Пример #1
0
    def deploy(self, verbose, workdir):
        thread_utils.print_thread("  Deploying {}".format(self.tosca_id))

        self.set_state(NodeState.CREATING)
        self.run_operation(OperationHost.HOST, StandardInterfaceOperation.shorthand_name(),
                           StandardInterfaceOperation.CREATE, verbose, workdir)
        self.set_state(NodeState.CREATED)
        self.set_state(NodeState.CONFIGURING)

        self._configure_requirements(ConfigureInterfaceOperation.PRE_CONFIGURE_SOURCE,
                                     ConfigureInterfaceOperation.PRE_CONFIGURE_TARGET,
                                     verbose, workdir)

        self.run_operation(OperationHost.HOST,
                           StandardInterfaceOperation.shorthand_name(),
                           StandardInterfaceOperation.CONFIGURE,
                           verbose, workdir)

        self._configure_requirements(ConfigureInterfaceOperation.POST_CONFIGURE_SOURCE,
                                     ConfigureInterfaceOperation.POST_CONFIGURE_TARGET,
                                     verbose, workdir)

        self.set_state(NodeState.CONFIGURED)
        self.set_state(NodeState.STARTING)
        self.run_operation(OperationHost.HOST, StandardInterfaceOperation.shorthand_name(),
                           StandardInterfaceOperation.START, verbose, workdir)
        self.set_state(NodeState.STARTED)

        # TODO(@tadeboro): Execute various add hooks
        thread_utils.print_thread("  Deployment of {} complete".format(self.tosca_id))
Пример #2
0
    def run(self, host: OperationHost, instance, verbose, workdir, validate):
        thread_utils.print_thread(
            f"    Executing {self.name} on {instance.tosca_id}")

        # TODO(@tadeboro): Respect the timeout option.
        # TODO(@tadeboro): Add host validation.
        # TODO(@tadeboro): Properly handle SELF - not even sure what this
        # proper way would be at this time.
        host = self.host or host
        if host in (OperationHost.SELF, OperationHost.HOST):
            actual_host = instance.get_host()
        elif host == OperationHost.SOURCE:
            actual_host = instance.source.get_host()
        elif host == OperationHost.TARGET:
            actual_host = instance.target.get_host()
        else:  # ORCHESTRATOR
            actual_host = "localhost"

        operation_inputs = {
            k: v.eval(instance, k)
            for k, v in self.inputs.items()
        }

        # TODO: Currently when primary is None we skip running the operation. Fix this if needed.
        if not self.primary:
            return True, {}, {}

        # TODO(@tadeboro): Generalize executors.
        success, ansible_outputs = ansible.run(
            actual_host, str(self.primary),
            tuple(str(i) for i in self.dependencies),
            tuple(str(i) for i in self.artifacts), operation_inputs, verbose,
            workdir, validate)
        if not success:
            return False, {}, {}

        outputs = []
        unresolved_outputs = []

        for output, attribute_mapping in self.outputs.items():
            if output in ansible_outputs:
                outputs.append((attribute_mapping, ansible_outputs[output]))
                ansible_outputs.pop(output)
            else:
                unresolved_outputs.append(output)

        if len(unresolved_outputs) > 0:
            raise DataError(
                f"Operation did not return the following outputs: {', '.join(unresolved_outputs)}"
            )

        return success, outputs, ansible_outputs
Пример #3
0
    def notify(self, verbose: bool, workdir: str,
               trigger_name_or_event: Optional[str],
               notification_file_contents: Optional[str]):
        thread_utils.print_thread(f"  Notifying {self.tosca_id}")

        for policy in self.template.policies:
            for trigger_name, trigger in policy.triggers.items():
                # break here if trigger is not targeting this node
                if trigger.target_filter and trigger.target_filter[
                        0] != self.template.name:
                    break

                invoke_trigger = True
                if trigger_name_or_event is not None and trigger_name_or_event not in (
                        trigger_name, trigger.event.data):
                    invoke_trigger = False

                # invoke the chosen trigger only if it contains any actions
                if invoke_trigger and trigger.action:
                    thread_utils.print_thread(
                        f"   Calling trigger {trigger_name} with event {trigger.event}"
                    )
                    self.invoke_trigger(verbose, workdir, trigger,
                                        notification_file_contents)
                    thread_utils.print_thread(
                        f"   Calling trigger actions with event {trigger.event} complete"
                    )

        self.notified = True
        thread_utils.print_thread(
            f"  Notification on {self.tosca_id} complete")
Пример #4
0
    def run(self, host, instance, verbose, workdir):
        thread_utils.print_thread(
            "    Executing {} on {}".format(self.name, instance.tosca_id)
        )

        # TODO(@tadeboro): Respect the timeout option.
        # TODO(@tadeboro): Add host validation.
        # TODO(@tadeboro): Properly handle SELF - not even sure what this
        # proper way would be at this time.
        host = self.host or host
        if host in ("SELF", "HOST"):
            actual_host = instance.get_host()
        elif host == "SOURCE":
            actual_host = instance.source.get_host()
        elif host == "TARGET":
            actual_host = instance.target.get_host()
        else:  # ORCHESTRATOR
            actual_host = "localhost"

        operation_inputs = {
            k: v.eval(instance, k) for k, v in self.inputs.items()
        }

        # TODO(@tadeboro): Generalize executors.
        success, ansible_outputs = ansible.run(
            actual_host, str(self.primary),
            tuple(str(i) for i in self.dependencies),
            tuple(str(i) for i in self.artifacts), operation_inputs, verbose,
            workdir
        )
        if not success:
            return False, {}, {}

        outputs = []
        unresolved_outputs = []

        for output, attribute_mapping in self.outputs.items():
            if output in ansible_outputs:
                outputs.append((attribute_mapping, ansible_outputs[output]))
                ansible_outputs.pop(output)
            else:
                unresolved_outputs.append(output)

        if len(unresolved_outputs) > 0:
            raise DataError(
                "Operation did not return the following outputs: {}".format(
                    ", ".join(unresolved_outputs)))

        return success, outputs, ansible_outputs
Пример #5
0
    def undeploy(self, verbose, workdir):
        thread_utils.print_thread("  Undeploying {}".format(self.tosca_id))

        self.set_state("stopping")
        self.run_operation("HOST", "Standard", "stop", verbose, workdir)
        self.set_state("configured")

        self.set_state("deleting")
        self.run_operation("HOST", "Standard", "delete", verbose, workdir)
        self.set_state("initial")

        # TODO(@tadeboro): Execute various remove hooks

        self.reset_attributes()
        self.write()

        thread_utils.print_thread("  Undeployment of {} complete".format(
            self.tosca_id))
Пример #6
0
    def undeploy(self, verbose, workdir):
        thread_utils.print_thread("  Undeploying {}".format(self.tosca_id))

        self.set_state(NodeState.STOPPING)
        self.run_operation(OperationHost.HOST, StandardInterfaceOperation.shorthand_name(),
                           StandardInterfaceOperation.STOP, verbose, workdir)
        self.set_state(NodeState.CONFIGURED)

        self.set_state(NodeState.DELETING)
        self.run_operation(OperationHost.HOST, StandardInterfaceOperation.shorthand_name(),
                           StandardInterfaceOperation.DELETE, verbose, workdir)
        self.set_state(NodeState.INITIAL)

        # TODO(@tadeboro): Execute various remove hooks

        self.reset_attributes()
        self.write()

        thread_utils.print_thread("  Undeployment of {} complete".format(self.tosca_id))
Пример #7
0
    def deploy(self, verbose, workdir):
        thread_utils.print_thread("  Deploying {}".format(self.tosca_id))

        self.set_state("creating")
        self.run_operation("HOST", "Standard", "create", verbose, workdir)
        self.set_state("created")

        self.set_state("configuring")
        for requirement in set([r.name for r in self.template.requirements]):
            for relationship in self.out_edges[requirement].values():
                relationship.run_operation(
                    "SOURCE", "Configure", "pre_configure_source", verbose,
                    workdir
                )
        for requirement_dependants in self.in_edges.values():
            for relationship in requirement_dependants.values():
                relationship.run_operation(
                    "TARGET", "Configure", "pre_configure_target", verbose,
                    workdir
                )
        self.run_operation("HOST", "Standard", "configure", verbose, workdir)
        for requirement in set([r.name for r in self.template.requirements]):
            for relationship in self.out_edges[requirement].values():
                relationship.run_operation(
                    "SOURCE", "Configure", "post_configure_source", verbose,
                    workdir
                )
        for requirement_dependants in self.in_edges.values():
            for relationship in requirement_dependants.values():
                relationship.run_operation(
                    "TARGET", "Configure", "post_configure_target", verbose,
                    workdir
                )
        self.set_state("configured")

        self.set_state("starting")
        self.run_operation("HOST", "Standard", "start", verbose, workdir)
        self.set_state("started")

        # TODO(@tadeboro): Execute various add hooks
        thread_utils.print_thread(
            "  Deployment of {} complete".format(self.tosca_id)
        )
Пример #8
0
    def validate(self, verbose, workdir):
        thread_utils.print_thread(f"  Validating {self.tosca_id}")

        # validate node's deployment
        self.run_operation(OperationHost.HOST,
                           StandardInterfaceOperation.shorthand_name(),
                           StandardInterfaceOperation.CREATE, verbose, workdir,
                           True)
        self._configure_requirements(
            ConfigureInterfaceOperation.PRE_CONFIGURE_SOURCE,
            ConfigureInterfaceOperation.PRE_CONFIGURE_TARGET, verbose, workdir,
            True)
        self.run_operation(OperationHost.HOST,
                           StandardInterfaceOperation.shorthand_name(),
                           StandardInterfaceOperation.CONFIGURE, verbose,
                           workdir, True)
        self._configure_requirements(
            ConfigureInterfaceOperation.POST_CONFIGURE_SOURCE,
            ConfigureInterfaceOperation.POST_CONFIGURE_TARGET, verbose,
            workdir, True)
        self.run_operation(OperationHost.HOST,
                           StandardInterfaceOperation.shorthand_name(),
                           StandardInterfaceOperation.START, verbose, workdir,
                           True)

        # validate node's undeployment
        self.run_operation(OperationHost.HOST,
                           StandardInterfaceOperation.shorthand_name(),
                           StandardInterfaceOperation.STOP, verbose, workdir,
                           True)
        self.run_operation(OperationHost.HOST,
                           StandardInterfaceOperation.shorthand_name(),
                           StandardInterfaceOperation.DELETE, verbose, workdir,
                           True)
        self.reset_attributes()
        self.write()

        self.validated = True
        thread_utils.print_thread(f"  Validation of {self.tosca_id} complete")
Пример #9
0
def run(host, primary, dependencies, artifacts, variables, verbose, workdir):  # pylint: disable=too-many-locals
    with tempfile.TemporaryDirectory() as dir_path:
        playbook = os.path.join(dir_path, os.path.basename(primary))
        utils.copy(os.path.join(workdir, primary), playbook)

        for d in dependencies:
            utils.copy(os.path.join(workdir, d),
                       os.path.join(dir_path, os.path.basename(d)))
        for a in artifacts:
            utils.copy(os.path.join(workdir, a),
                       os.path.join(dir_path, os.path.basename(a)))

        inventory = utils.write(dir_path, _get_inventory(host), suffix=".yaml")
        vars_file = utils.write(dir_path,
                                yaml.safe_dump(variables),
                                suffix=".yaml")

        with open("{}/ansible.cfg".format(dir_path), "w") as fd:
            fd.write("[defaults]\n")
            fd.write("retry_files_enabled = False\n")

            opera_ssh_host_key_checking = os.environ.get(
                "OPERA_SSH_HOST_KEY_CHECKING")
            if opera_ssh_host_key_checking is not None:
                check = str(opera_ssh_host_key_checking).lower().strip()
                if check[:1] == "f" or check[:1] == "false":
                    fd.write("host_key_checking = False\n")

        if verbose:
            print("***inputs***")
            print(["{}: {}".format(key, variables[key]) for key in variables])
            print("***inputs***")

        cmd = [
            "ansible-playbook", "-i", inventory, "-e", "@" + vars_file,
            playbook
        ]
        env = dict(
            ANSIBLE_SHOW_CUSTOM_STATS="1",
            ANSIBLE_STDOUT_CALLBACK="json",
        )
        code, out, err = utils.run_in_directory(dir_path, cmd, env)
        if code != 0 or verbose:
            thread_utils.print_thread("------------")
            with open(out) as fd:
                for line in fd:
                    print(line.rstrip())
            thread_utils.print_thread("------------")
            with open(err) as fd:
                for line in fd:
                    print(line.rstrip())
            thread_utils.print_thread("============")

        if code != 0:
            return False, {}

        with open(out) as fd:
            outputs = json.load(fd)["global_custom_stats"]
        return code == 0, outputs