def polish_blueprint(self, names, polishers): """ Walks a named blueprint for this facility and polish related resources :param names: the name(s) of the blueprint(s) to polish :type names: ``str`` or ``list`` of ``str`` :param polishers: polishers to be applied :type polishers: list of :class:`plumbery.PlumberyPolisher` """ if isinstance(polishers, str): polishers = PlumberyPolisher.filter(self.plumbery.polishers, polishers) self.power_on() infrastructure = PlumberyInfrastructure(self) nodes = PlumberyNodes(self) for name in self.expand_blueprint(names): blueprint = self.get_blueprint(name) container = infrastructure.get_container(blueprint) for polisher in polishers: polisher.shine_container(container) nodes.polish_blueprint(blueprint, polishers, container)
def polish_blueprint(self, names, polishers): """ Walks a named blueprint for this facility and polish related resources :param names: the name(s) of the blueprint(s) to polish :type names: ``str`` or ``list`` of ``str`` :param polishers: polishers to be applied :type polishers: list of :class:`plumbery.PlumberyPolisher` """ self.power_on() infrastructure = PlumberyInfrastructure(self) nodes = PlumberyNodes(self) if isinstance(names, str): names = names.split(' ') for name in names: blueprint = self.get_blueprint(name) if blueprint is None: continue container = infrastructure.get_container(blueprint) for polisher in polishers: polisher.shine_container(container) nodes.polish_blueprint(blueprint, polishers, container)
def build_all_blueprints(self): """ Builds all blueprints defined for this facility This function builds all network domains across all blueprints, then it builds all nodes across all blueprints. If the keyword ``basement`` mentions one or several blueprints, then these are built before the other blueprints. """ self.power_on() infrastructure = PlumberyInfrastructure(self) nodes = PlumberyNodes(self) basement = self.list_basement() for name in basement: logging.debug("Building infrastructure of blueprint '{}'" .format(name)) blueprint = self.get_blueprint(name) infrastructure.build(blueprint) blueprints = self.list_blueprints() for name in blueprints: if name not in basement: logging.debug("Building infrastructure of blueprint '{}'" .format(name)) blueprint = self.get_blueprint(name) infrastructure.build(blueprint) for name in basement: logging.debug("Building nodes of blueprint '{}'" .format(name)) blueprint = self.get_blueprint(name) container = infrastructure.get_container(blueprint) nodes.build_blueprint(blueprint, container) for name in blueprints: if name not in basement: logging.debug("Building nodes of blueprint '{}'" .format(name)) blueprint = self.get_blueprint(name) container = infrastructure.get_container(blueprint) nodes.build_blueprint(blueprint, container)
def build_blueprint(self, names): """ Builds a named blueprint for this facility :param names: the name(s) of the blueprint(s) to build :type names: ``str`` or ``list`` of ``str`` This function builds the named blueprint in two steps: the infrastructure comes first, and then the nodes themselves. >>>facility.build_blueprint('sql') If the keyword ``basement`` mentions one or several blueprints, then network domains of these special blueprints are built before the actual target blueprint. Example ``fittings.yaml``:: --- basement: admin blueprints: - admin: ethernet: control - sql: ethernet: data nodes: - server1: glue: control In this example, the node ``server1``has two network interfaces. The main network interface is connected to the network ``data``, and the secondary network interface is connected to the network ``control``. """ self.power_on() infrastructure = PlumberyInfrastructure(self) nodes = PlumberyNodes(self) basement = self.list_basement() for name in basement: blueprint = self.get_blueprint(name) infrastructure.build(blueprint) for name in self.expand_blueprint(names): blueprint = self.get_blueprint(name) if name not in basement: infrastructure.build(blueprint) nodes.build_blueprint( blueprint, infrastructure.get_container(blueprint))
def build_all_blueprints(self): """ Builds all blueprints defined for this facility This function builds all network domains across all blueprints, then it builds all nodes across all blueprints. If the keyword ``basement`` mentions one or several blueprints, then these are built before the other blueprints. """ self.power_on() infrastructure = PlumberyInfrastructure(self) nodes = PlumberyNodes(self) for name in self.list_basement(): blueprint = self.get_blueprint(name) if blueprint is not None: infrastructure.build(blueprint) for name in self.list_blueprints(): if name not in self.list_basement(): blueprint = self.get_blueprint(name) if blueprint is not None: infrastructure.build(blueprint) for name in self.list_basement(): blueprint = self.get_blueprint(name) if blueprint is not None: container = infrastructure.get_container(blueprint) nodes.build_blueprint(blueprint, container) for name in self.list_blueprints(): if name not in self.list_basement(): blueprint = self.get_blueprint(name) if blueprint is not None: container = infrastructure.get_container(blueprint) nodes.build_blueprint(blueprint, container)
def destroy_blueprint(self, blueprint): """ Destroys nodes of a given blueprint :param blueprint: the blueprint to build :type blueprint: ``dict`` """ self.facility.power_on() infrastructure = PlumberyInfrastructure(self.facility) container = infrastructure.get_container(blueprint) if "nodes" not in blueprint or not isinstance(blueprint["nodes"], list): return # destroy in reverse order for item in reversed(blueprint["nodes"]): if type(item) is dict: label = item.keys()[0] settings = item[label] else: label = str(item) settings = {} for label in self.expand_labels(label): node = self.get_node(label) if node is None: logging.info("Destroying node '{}'".format(label)) logging.info("- not found") continue if "destroy" in settings and settings["destroy"] == "never": logging.info("Destroying node '{}'".format(label)) logging.info("- this node can never be destroyed") return False timeout = 300 tick = 6 while node.extra["status"].action == "SHUTDOWN_SERVER": time.sleep(tick) node = self.get_node(label) timeout -= tick if timeout < 0: break if node.state == NodeState.RUNNING: logging.info("Destroying node '{}'".format(label)) logging.info("- skipped - node is up and running") continue if self.plumbery.safeMode: logging.info("Destroying node '{}'".format(label)) logging.info("- not in safe mode") continue self._stop_monitoring(node, settings) self._detach_node(node, settings) container._detach_node_from_internet(node) container._remove_from_pool(node) logging.info("Destroying node '{}'".format(label)) while True: try: self.region.destroy_node(node) logging.info("- in progress") except Exception as feedback: if "RESOURCE_BUSY" in str(feedback): time.sleep(10) continue elif "RESOURCE_NOT_FOUND" in str(feedback): logging.info("- not found") elif "SERVER_STARTED" in str(feedback): logging.info("- skipped - node is up and running") elif "RESOURCE_LOCKED" in str(feedback): logging.info("- not now - locked") return False else: logging.info("- unable to destroy node") logging.error(str(feedback)) break
def destroy_blueprint(self, blueprint): """ Destroys nodes of a given blueprint :param blueprint: the blueprint to build :type blueprint: ``dict`` """ self.facility.power_on() infrastructure = PlumberyInfrastructure(self.facility) container = infrastructure.get_container(blueprint) if 'nodes' not in blueprint or not isinstance(blueprint['nodes'], list): return # destroy in reverse order for item in reversed(blueprint['nodes']): if type(item) is dict: label = item.keys()[0] settings = item[label] else: label = str(item) settings = {} for label in self.expand_labels(label): node = self.get_node(label) if node is None: logging.info("Destroying node '{}'".format(label)) logging.info("- not found") continue if 'destroy' in settings and settings['destroy'] == 'never': logging.info("Destroying node '{}'".format(label)) logging.info("- this node can never be destroyed") return False if node.state == NodeState.RUNNING: logging.info("Destroying node '{}'".format(label)) logging.info("- skipped - node is up and running") continue if self.plumbery.safeMode: logging.info("Destroying node '{}'".format(label)) logging.info("- not in safe mode") continue self._stop_monitoring(node, settings) self._detach_node(node, settings) container._detach_node_from_internet(node) container._remove_from_pool(node) logging.info("Destroying node '{}'".format(label)) while True: try: self.region.destroy_node(node) logging.info("- in progress") except Exception as feedback: if 'RESOURCE_BUSY' in str(feedback): time.sleep(10) continue elif 'RESOURCE_NOT_FOUND' in str(feedback): logging.info("- not found") elif 'SERVER_STARTED' in str(feedback): logging.info("- skipped - node is up and running") elif 'RESOURCE_LOCKED' in str(feedback): logging.info("- not now - locked") return False else: logging.info("- unable to destroy node") logging.error(str(feedback)) break