Example #1
0
def deploy_compressed_csar(
        csar_name: str,
        inputs: typing.Optional[dict],
        storage: Storage,
        verbose_mode: bool,
        num_workers: int,
        delete_existing_state: bool
):
    if delete_existing_state:
        storage.remove("instances")

    if inputs is None:
        inputs = {}
    storage.write_json(inputs, "inputs")

    csars_dir = Path(storage.path) / "csars"
    csars_dir.mkdir(exist_ok=True)

    csar = CloudServiceArchive.create(PurePath(csar_name))
    csar.validate_csar()
    tosca_service_template = csar.get_entrypoint()

    # unzip csar, save the path to storage and set workdir
    csar_dir = csars_dir / Path("csar")
    ZipFile(csar_name, "r").extractall(csar_dir)
    csar_tosca_service_template_path = csar_dir / tosca_service_template
    storage.write(str(csar_tosca_service_template_path), "root_file")
    workdir = str(csar_dir)

    # initialize service template from CSAR and deploy
    ast = tosca.load(Path(csar_dir), Path(tosca_service_template))
    template = ast.get_template(inputs)
    topology = template.instantiate(storage)
    topology.deploy(verbose_mode, workdir, num_workers)
Example #2
0
    def _update(service_template: str, inputs: typing.Optional[dict],
                num_workers: int):
        original_storage = Storage.create()

        new_storage = Storage.create(instance_path=".opera-api-update")
        new_storage.write_json(inputs, "inputs")
        new_storage.write(service_template, "root_file")

        instance_diff = opera_diff_instances(original_storage, ".",
                                             new_storage, ".",
                                             TemplateComparer(),
                                             InstanceComparer(), True)

        opera_update(original_storage,
                     ".",
                     new_storage,
                     ".",
                     InstanceComparer(),
                     instance_diff,
                     True,
                     num_workers,
                     overwrite=True)
Example #3
0
def outputs():
    logger.debug("Entry: outputs")

    try:
        opera_storage = Storage.create()
        result = opera_outputs(opera_storage)
    except Exception as e:
        logger.error("Error getting outputs.", e)
        return {"message": str(e)}, 500

    if not result:
        return {"message": "No outputs exist for this deployment."}, 404
    return result, 200
Example #4
0
def diff(body: dict = None):
    logger.debug("Entry: diff")
    diff_request = DiffRequest.from_dict(body)

    try:
        original_storage = Storage.create()
        original_service_template = original_storage.read("root_file")
        original_inputs = original_storage.read_json("inputs")

        with tempfile.TemporaryDirectory(prefix=".opera-api-diff",
                                         dir=".") as new_storage_root:
            new_storage = Storage.create(instance_path=new_storage_root)
            with tempfile.NamedTemporaryFile(prefix="diff-service-template",
                                             dir=".") as new_service_template:
                new_service_template.write(
                    diff_request.new_service_template_contents)
                new_service_template.flush()

                if diff_request.template_only:
                    diff_result = opera_diff_templates(
                        original_service_template, ".", original_inputs,
                        new_service_template.name, ".", diff_request.inputs,
                        TemplateComparer(), True)
                else:
                    diff_result = opera_diff_instances(original_storage, ".",
                                                       new_storage, ".",
                                                       TemplateComparer(),
                                                       InstanceComparer(),
                                                       True)

        result = Diff(added=diff_result.added,
                      changed=diff_result.changed,
                      deleted=diff_result.deleted)
    except Exception as e:
        logger.error("Error performing diff.", e)
        return {"message": str(e)}, 500

    return result, 200
Example #5
0
def _parser_callback(args):
    if args.instance_path and not path.isdir(args.instance_path):
        raise argparse.ArgumentTypeError(
            "Directory {} is not a valid path!".format(args.instance_path))

    if args.workers < 1:
        print("{} is not a positive number!".format(args.workers))
        return 1

    storage = Storage.create(args.instance_path)
    status = info(None, storage)["status"]

    if storage.exists("instances"):
        if args.resume and status == "error":
            if not args.force:
                print(
                    "The resume undeploy option might have unexpected consequences on the already "
                    "undeployed blueprint.")
                question = prompt_yes_no_question()
                if not question:
                    return 0
        elif status == "initialized":
            print(
                "The project is initialized. You have to deploy it first to be able to run undeploy."
            )
            return 0
        elif status == "deploying":
            print(
                "The project is currently deploying. Please try again after the deployment."
            )
            return 0
        elif status == "undeployed":
            print("All instances have already been undeployed.")
            return 0
        elif status == "error":
            print(
                "The instance model already exists. Use --resume/-r option to continue current undeployment process."
            )
            return 0

    try:
        undeploy(storage, args.verbose, args.workers)
    except ParseError as e:
        print("{}: {}".format(e.loc, e))
        return 1
    except DataError as e:
        print(str(e))
        return 1

    return 0
Example #6
0
def init(csar_initialization_input: CsarInitializationInput):
    logger.debug("Entry: init")

    try:
        opera_storage = Storage.create()
        opera_init_compressed_csar(".", csar_initialization_input.inputs,
                                   opera_storage,
                                   csar_initialization_input.clean)
        return {"success": True, "message": ""}, 200
    except Exception as e:
        return {
            "success": False,
            "message": "General error: {}".format(str(e))
        }, 500
Example #7
0
def initialize_compressed_csar(csar_name: str, inputs: typing.Optional[dict],
                               storage: Storage):
    if inputs is None:
        inputs = {}
    storage.write_json(inputs, "inputs")

    csars_dir = Path(storage.path) / "csars"
    csars_dir.mkdir(exist_ok=True)

    # validate csar
    csar = CloudServiceArchive(csar_name, csars_dir)
    tosca_service_template = csar.validate_csar()

    # unzip csar and save the path to storage
    csar_dir = csars_dir / Path("csar")
    ZipFile(csar_name, 'r').extractall(csar_dir)
    csar_tosca_service_template_path = csar_dir / tosca_service_template
    storage.write(str(csar_tosca_service_template_path), "root_file")

    # try to initiate service template from csar
    ast = tosca.load(Path(csar_dir), Path(tosca_service_template))
    template = ast.get_template(inputs)
    template.instantiate(storage)
Example #8
0
 def test_undefined_required_properties1(self, tmp_path, yaml_text):
     name = pathlib.PurePath("template.yaml")
     (tmp_path / name).write_text(
         yaml_text(
             # language=yaml
             """
         tosca_definitions_version: tosca_simple_yaml_1_3
         node_types:
           my_node_type:
             derived_from: tosca.nodes.Root
             attributes:
               test_attribute:
                 type: boolean
             properties:
               test_property1:
                 type: integer
                 default: 42
                 required: false
               test_property2:
                 type: float
                 default: 42.0
                 required: true
               test_property3:
                 type: string
                 required: true
         topology_template:
           node_templates:
             my_node_template:
               type: my_node_type
         """))
     storage = Storage(tmp_path / pathlib.Path(".opera"))
     storage.write("template.yaml", "root_file")
     ast = tosca.load(tmp_path, name)
     with pytest.raises(
             ParseError,
             match="Missing a required property: test_property3"):
         ast.get_template({})
Example #9
0
def notify(storage: Storage, verbose_mode: bool, trigger_name_or_event: str,
           notification_file_contents: typing.Optional[str]):
    if storage.exists("inputs"):
        inputs = yaml.safe_load(storage.read("inputs"))
    else:
        inputs = {}

    if storage.exists("root_file"):
        service_template_path = PurePath(storage.read("root_file"))

        workdir = Path(service_template_path.parent)
        if storage.exists("csars"):
            csar_dir = Path(storage.path) / "csars" / "csar"
            workdir = csar_dir
            ast = tosca.load(workdir, service_template_path.relative_to(csar_dir))
        else:
            ast = tosca.load(workdir, PurePath(service_template_path.name))

        template = ast.get_template(inputs)

        # check if specified trigger or event name exists in template
        if trigger_name_or_event:
            trigger_name_or_event_exists = False
            for policy in template.policies:
                for trigger in policy.triggers.values():
                    if trigger_name_or_event in (trigger.name, trigger.event.data):
                        trigger_name_or_event_exists = True
                        break

            if not trigger_name_or_event_exists:
                raise DataError(f"The provided trigger or event name does not exist: {trigger_name_or_event}.")

        topology = template.instantiate(storage)
        topology.notify(verbose_mode, workdir, trigger_name_or_event, notification_file_contents)
    else:
        print("There is no root_file in storage.")
Example #10
0
def build_image(inv: Invocation):
    with tempfile.TemporaryDirectory() as workdir:
        dir_util.copy_tree(Settings.TOSCA_path, workdir)
        with image_builder_util.cwd(workdir):
            opera_storage = Storage.create(".opera")
            service_template = "docker_image_definition.yaml"
            build_params = transform_build_params(inv.build_params)
            logger.info(json.dumps(build_params))
            opera_deploy(service_template,
                         build_params,
                         opera_storage,
                         verbose_mode=False,
                         num_workers=1,
                         delete_existing_state=True)
            return opera_outputs(opera_storage)
Example #11
0
def _parser_callback(args):
    if args.instance_path and not path.isdir(args.instance_path):
        raise argparse.ArgumentTypeError(
            "Directory {0} is not a valid path!".format(args.instance_path))

    storage = Storage.create(args.instance_path)
    try:
        outs = info(storage)
        print(format_outputs(outs, args.format))
    except ParseError as e:
        print("{}: {}".format(e.loc, e))
        return 1
    except DataError as e:
        print(str(e))
        return 1
    return 0
Example #12
0
def prepare_csar(path, yaml_text, template):
    # language=yaml
    tosca_meta = \
        """
        TOSCA-Meta-File-Version: 1.1
        CSAR-Version: 1.1
        Created-By: xOpera TOSCA orchestrator
        Entry-Definitions: service.yaml
        """
    Path.mkdir(path / "TOSCA-Metadata")
    (path / "TOSCA-Metadata" / "TOSCA.meta").write_text(yaml_text(tosca_meta))
    name = PurePath("service.yaml")
    (path / name).write_text(yaml_text(template))
    shutil.make_archive(path / "compressed" / "test", "zip", path)
    storage = Storage(path / Path(".opera"))
    return path, storage
Example #13
0
def _parser_callback(args):
    if args.instance_path and not path.isdir(args.instance_path):
        raise argparse.ArgumentTypeError(f"Directory {args.instance_path} is not a valid path!")

    storage = Storage.create(args.instance_path)
    status = info(None, storage)["status"]

    if not args.force and storage.exists("instances"):
        if status == "initialized":
            print("Running notify without previously running deploy might have unexpected consequences.")
            question = prompt_yes_no_question()
            if not question:
                return 0
        elif status in ("deploying", "undeploying"):
            print("The project is in the middle of some other operation. Please try again after some time.")
            return 0
        elif status == "undeployed":
            print("Running notify in an undeployed project might have unexpected consequences.")
            question = prompt_yes_no_question()
            if not question:
                return 0
        elif status == "error":
            print("Running notify after a deployment with an error might have unexpected consequences.")
            question = prompt_yes_no_question()
            if not question:
                return 0

    if not args.force and not args.trigger:
        print("You have not specified which policy trigger to use (with --trigger/-t or --event/-e) "
              "and in this case all the triggers will be invoked which might not be what you want.")
        question = prompt_yes_no_question()
        if not question:
            return 0

    # read the notification file and the pass its contents to the library function
    notification_file_contents = Path(args.notification.name).read_text(encoding="utf-8") if args.notification else None

    try:
        notify(storage, args.verbose, args.trigger, notification_file_contents)
    except ParseError as e:
        print(f"{e.loc}: {e}")
        return 1
    except DataError as e:
        print(str(e))
        return 1

    return 0
Example #14
0
def run_test(registry_ip: str, test_name: str):
    """
    Runs yaml test and returns exit_code
    """
    test_path = test_build_params / f'{test_name}.json'

    inputs = json_to_yaml(test_path, registry_ip)
    with cwd(tosca_path):
        opera_storage = Storage.create('.opera')
        try:
            opera_deploy('docker_image_definition.yaml', inputs, opera_storage,
                         verbose_mode=False, num_workers=1, delete_existing_state=True)
        except OperationError:
            return 1
        finally:
            shutil.rmtree((tosca_path / ".opera"), ignore_errors=True)
    return 0
Example #15
0
 def validate(blueprint_id: str, version_tag: str, inputs: dict):
     with tempfile.TemporaryDirectory() as location:
         CSAR_db.get_revision(blueprint_id, location, version_tag)
         try:
             with xopera_util.cwd(location):
                 opera_storage = Storage.create(".opera")
                 service_template = Path(location) / entry_definitions(
                     location)
                 opera_validate(service_template,
                                inputs,
                                opera_storage,
                                verbose=False,
                                executors=False)
             return None
         except Exception as e:
             return "{}: {}".format(
                 e.__class__.__name__,
                 xopera_util.mask_workdir(location, str(e)))
 def load_invocation(cls, job_id: uuid) -> Optional[Invocation]:
     # TODO database
     # try:
     #     inv = SQL_database.get_deployment_status(deployment_id)
     #     # if inv.state == InvocationState.IN_PROGRESS:
     #     #     inv.stdout = InvocationWorkerProcess.read_file(cls.stdout_file(inv.deployment_id))
     #     #     inv.stderr = InvocationWorkerProcess.read_file(cls.stderr_file(inv.deployment_id))
     #     return inv
     #
     # except Exception in (FileNotFoundError, AttributeError):
     #     return None
     storage = Storage.create(".opera-api")
     filename = "invocation-{}.json".format(job_id)
     try:
         dump = storage.read_json(filename)
     except FileNotFoundError:
         return None
     return Invocation.from_dict(dump)
Example #17
0
def init_service_template(service_template: str, inputs: typing.Optional[dict],
                          storage: Storage, clean_storage: bool):
    if storage.exists("root_file"):
        if clean_storage:
            storage.remove_all()
        else:
            print("Looks like service template or CSAR has already been initialized. "
                  "Use --clean/-c flag to clear the storage.")
            return

    if inputs is None:
        inputs = {}
    storage.write_json(inputs, "inputs")
    storage.write(service_template, "root_file")

    ast = tosca.load(Path.cwd(), PurePath(service_template))
    template = ast.get_template(inputs)
    template.instantiate(storage)
Example #18
0
def _parser_callback(args):
    if args.instance_path and not path.isdir(args.instance_path):
        raise argparse.ArgumentTypeError(
            f"Directory {args.instance_path} is not a valid path!")

    storage = Storage.create(args.instance_path)

    try:
        outs = outputs(storage)
        if args.output:
            save_outputs(outs, args.format, args.output)
        else:
            print(format_outputs(outs, args.format).strip())
    except ParseError as e:
        print(f"{e.loc}: {e}")
        return 1
    except DataError as e:
        print(str(e))
        return 1
    return 0
Example #19
0
def _parser_callback(args):
    if args.instance_path and not path.isdir(args.instance_path):
        raise argparse.ArgumentTypeError(
            "Directory {0} is not a valid path!".format(args.instance_path))

    if args.workers < 1:
        print("{0} is not a positive number!".format(args.workers))
        return 1

    storage = Storage.create(args.instance_path)
    try:
        undeploy(storage, args.verbose, args.workers)
    except ParseError as e:
        print("{}: {}".format(e.loc, e))
        return 1
    except DataError as e:
        print(str(e))
        return 1

    return 0
Example #20
0
def info(csar_or_rootdir: Optional[PurePath], storage: Storage) -> dict:
    info_dict: Dict[str, Optional[str]] = dict(service_template=None,
                                               content_root=None,
                                               inputs=None,
                                               status=None)

    # stateless autodetect first if possible,
    # which can then be overwritten via state
    if csar_or_rootdir is not None:
        csar = CloudServiceArchive.create(csar_or_rootdir)
        try:
            csar.validate_csar()
            info_dict["content_root"] = str(csar_or_rootdir)

            meta = csar.parse_csar_meta()
            if meta is not None:
                info_dict["service_template"] = meta.entry_definitions
        except OperaError:
            pass

    if storage.exists("root_file"):
        service_template = storage.read("root_file")
        info_dict["service_template"] = service_template

        if storage.exists("inputs"):
            info_dict["inputs"] = str(storage.path / "inputs")
            inputs = yaml.safe_load(storage.read("inputs"))
        else:
            inputs = {}

        if storage.exists("csars/csar"):
            csar_dir = Path(storage.path) / "csars" / "csar"
            info_dict["content_root"] = str(csar_dir)
            ast = tosca.load(Path(csar_dir),
                             PurePath(service_template).relative_to(csar_dir))
        else:
            ast = tosca.load(Path.cwd(), PurePath(service_template))

        if storage.exists("instances"):
            template = ast.get_template(inputs)
            # We need to instantiate the template in order
            # to get access to the instance state.
            topology = template.instantiate(storage)
            info_dict["status"] = topology.get_info()
        else:
            info_dict["status"] = "initialized"

    return info_dict
Example #21
0
    def _deploy_fresh(location: Path, inv: ExtendedInvocation):
        CSAR_db.get_revision(inv.blueprint_id, location, inv.version_id)

        with xopera_util.cwd(location):
            try:
                if inv.user_id and Settings.secure_workdir:
                    xopera_util.setup_user([location], inv.user_id,
                                           inv.access_token)
                opera_storage = Storage.create(".opera")
                service_template = entry_definitions(location)
                opera_deploy(service_template,
                             inv.inputs,
                             opera_storage,
                             verbose_mode=False,
                             num_workers=inv.workers,
                             delete_existing_state=True)

                outputs = opera_outputs(opera_storage)
                return outputs
            finally:
                if inv.user_id and Settings.secure_workdir:
                    xopera_util.cleanup_user()
Example #22
0
    def validate_new(CSAR: FileStorage, inputs: dict):
        try:
            with tempfile.TemporaryDirectory() as location:
                with tempfile.TemporaryDirectory() as csar_workdir:
                    csar_path = Path(csar_workdir) / Path(CSAR.filename)
                    CSAR.save(Path(csar_path).open('wb'))
                    csar_to_blueprint(csar=csar_path, dst=location)

                with xopera_util.cwd(location):
                    opera_storage = Storage.create(".opera")
                    service_template = Path(location) / entry_definitions(
                        location)
                    opera_validate(service_template,
                                   inputs,
                                   opera_storage,
                                   verbose=False,
                                   executors=False)
                return None
        except Exception as e:
            return "{}: {}".format(
                e.__class__.__name__,
                xopera_util.mask_workdirs([location, csar_workdir], str(e)),
            )
Example #23
0
def _parser_callback(args):
    if args.instance_path and not path.isdir(args.instance_path):
        raise argparse.ArgumentTypeError(
            "Directory {0} is not a valid path!".format(args.instance_path))

    storage = Storage.create(args.instance_path)
    try:
        if args.csar_or_rootdir is None:
            csar_path = "."
        else:
            csar_path = args.csar_or_rootdir

        outs = info(PurePath(csar_path), storage)
        if args.output:
            save_outputs(outs, args.format, args.output)
        else:
            print(format_outputs(outs, args.format))
    except ParseError as e:
        print("{}: {}".format(e.loc, e))
        return 1
    except DataError as e:
        print(str(e))
        return 1
    return 0
Example #24
0
def info(storage: Storage) -> dict:
    """
    :raises ParseError:
    :raises DataError:
    """
    info_dict = dict(service_template=None,
                     content_root=None,
                     inputs=None,
                     status=None)

    if storage.exists("root_file"):
        service_template = storage.read("root_file")
        info_dict["service_template"] = service_template

        if storage.exists("inputs"):
            info_dict["inputs"] = str(storage.path / "inputs")
            inputs = yaml.safe_load(storage.read("inputs"))
        else:
            inputs = {}

        if storage.exists("csars/csar"):
            csar_dir = Path(storage.path) / "csars" / "csar"
            info_dict["content_root"] = str(csar_dir)
            ast = tosca.load(Path(csar_dir),
                             PurePath(service_template).relative_to(csar_dir))
        else:
            ast = tosca.load(Path.cwd(), PurePath(service_template))

        if storage.exists("instances"):
            template = ast.get_template(inputs)
            # We need to instantiate the template in order
            # to get access to the instance state.
            topology = template.instantiate(storage)
            info_dict["status"] = topology.get_info()
        else:
            info_dict["status"] = "initialized"

    return info_dict
Example #25
0
def info(csar_or_rootdir: Optional[PurePath], storage: Storage) -> dict:  # pylint: disable=too-many-statements
    info_dict: Dict[str, Optional[Union[str, dict, bool]]] = dict(
        service_template=None,
        content_root=None,
        inputs=None,
        status=None,
        csar_metadata=None,
        service_template_metadata=None,
        csar_valid=None)

    # stateless autodetect first if possible,
    # which can then be overwritten via state
    if csar_or_rootdir is not None:
        csar = CloudServiceArchive.create(csar_or_rootdir)
        try:
            # this validates CSAR and the entrypoint's (if it exists) metadata
            # failure to validate here means no static information will be available at all
            csar.validate_csar()
            info_dict["csar_valid"] = True

            info_dict["content_root"] = str(csar_or_rootdir)
            if csar.get_entrypoint() is not None:
                info_dict["service_template"] = str(csar.get_entrypoint())

                try:
                    service_template_meta = csar.parse_service_template_meta(
                        csar.get_entrypoint())
                    if service_template_meta:
                        info_dict[
                            "service_template_metadata"] = service_template_meta.to_dict(
                            )
                except OperaError:
                    pass

            try:
                csar_meta = csar.parse_csar_meta()
                if csar_meta:
                    info_dict["csar_metadata"] = csar_meta.to_dict()
            except OperaError:
                pass
        except OperaError:
            # anything that fails because of validation can be ignored, we can use state
            # we mark the CSAR as invalid because it's useful to know
            info_dict["csar_valid"] = False

    # detection from state, overrides stateless
    if storage.exists("root_file"):
        service_template_path = PurePath(storage.read("root_file"))
        info_dict["service_template"] = str(service_template_path)

        if storage.exists("inputs"):
            inputs = yaml.safe_load(storage.read("inputs"))
        else:
            inputs = {}
        info_dict["inputs"] = inputs

        if storage.exists("csars/csar"):
            csar_dir = Path(storage.path) / "csars" / "csar"
            info_dict["content_root"] = str(csar_dir)
            ast = tosca.load(Path(csar_dir),
                             service_template_path.relative_to(csar_dir))

            try:
                csar = CloudServiceArchive.create(csar_dir)
                csar.validate_csar()
                info_dict["csar_valid"] = True

                try:
                    service_template_meta = csar.parse_service_template_meta(
                        csar.get_entrypoint())
                    if service_template_meta:
                        info_dict[
                            "service_template_metadata"] = service_template_meta.to_dict(
                            )
                except OperaError:
                    pass

                try:
                    csar_meta = csar.parse_csar_meta()
                    if csar_meta:
                        info_dict["csar_metadata"] = csar_meta.to_dict()
                except OperaError:
                    pass

            except OperaError:
                info_dict["csar_valid"] = False
        else:
            ast = tosca.load(Path(service_template_path.parent),
                             PurePath(service_template_path.name))

        if storage.exists("instances"):
            template = ast.get_template(inputs)
            # We need to instantiate the template in order
            # to get access to the instance state.
            topology = template.instantiate(storage)
            info_dict["status"] = topology.status()
        else:
            info_dict["status"] = "initialized"

    return info_dict
Example #26
0
def _parser_callback(args):
    if args.instance_path and not path.isdir(args.instance_path):
        raise argparse.ArgumentTypeError(
            f"Directory {args.instance_path} is not a valid path!")

    storage_old = Storage.create(args.instance_path)
    comparer = TemplateComparer()

    if args.template:
        service_template_new_path = Path(args.template.name)
    else:
        print("Template file for comparison was not supplied.")
        return 1

    if storage_old.exists("root_file"):
        service_template_old_path = Path(storage_old.read("root_file"))
    else:
        print("There is no root_file in storage.")
        return 1

    if storage_old.exists("inputs"):
        inputs_old = storage_old.read_json("inputs")
    else:
        inputs_old = {}

    try:
        if args.inputs:
            inputs_new = yaml.safe_load(args.inputs)
        else:
            inputs_new = {}
    except yaml.YAMLError as e:
        print(f"Invalid inputs: {e}")
        return 1

    workdir_old = get_workdir(storage_old)
    workdir_new = Path(service_template_new_path.parent)

    try:
        if args.template_only:
            template_diff = diff_templates(service_template_old_path,
                                           workdir_old, inputs_old,
                                           service_template_new_path,
                                           workdir_new, inputs_new, comparer,
                                           args.verbose)
        else:
            instance_comparer = InstanceComparer()
            with tempfile.TemporaryDirectory() as temp_path:
                storage_new = Storage.create(temp_path)
                storage_new.write_json(inputs_new, "inputs")
                storage_new.write(str(service_template_new_path), "root_file")
                template_diff = diff_instances(storage_old, workdir_old,
                                               storage_new, workdir_new,
                                               comparer, instance_comparer,
                                               args.verbose)
        outputs = template_diff.outputs()
        if args.output:
            save_outputs(outputs, args.format, args.output)
        else:
            print(format_outputs(outputs, args.format))
    except ParseError as e:
        print(f"{e.loc}: {e}")
        return 1
    except DataError as e:
        print(str(e))
        return 1

    return 0
Example #27
0
def _parser_callback(args):
    if args.instance_path and not path.isdir(args.instance_path):
        raise argparse.ArgumentTypeError(
            "Directory {0} is not a valid path!".format(args.instance_path))

    storage = Storage.create(args.instance_path)

    if args.workers < 1:
        print("{0} is not a positive number!".format(args.workers))
        return 1

    delete_existing_state = False
    if storage.exists("instances"):
        if args.resume:
            if not args.force:
                print("The resume deploy option might have unexpected "
                      "consequences on the already deployed blueprint.")
                question = prompt_yes_no_question()
                if not question:
                    return 0
        elif args.clean_state:
            if args.force:
                delete_existing_state = True
            else:
                print("The clean state deploy option might have unexpected "
                      "consequences on the already deployed blueprint.")
                question = prompt_yes_no_question()
                if question:
                    delete_existing_state = True
                else:
                    return 0
        else:
            print("The instance model already exists. Use --resume to "
                  "continue or --clean-state to delete current deployment "
                  "state and start over the deployment.")
            return 0

    if args.template:
        service_template = args.template.name
    else:
        if storage.exists("root_file"):
            service_template = storage.read("root_file")
        else:
            print("CSAR or template root file does not exist. "
                  "Maybe you have forgotten to initialize it.")
            return 1

    try:
        if args.inputs:
            inputs = yaml.safe_load(args.inputs)
        else:
            inputs = None
    except Exception as e:
        print("Invalid inputs: {}".format(e))
        return 1

    try:
        deploy(service_template, inputs, storage, args.verbose, args.workers,
               delete_existing_state)
    except ParseError as e:
        print("{}: {}".format(e.loc, e))
        return 1
    except DataError as e:
        print(str(e))
        return 1

    return 0
Example #28
0
 def write_invocation(cls, inv: Invocation):
     storage = Storage.create(".opera-api")
     filename = "invocation-{}.json".format(inv.id)
     dump = json.dumps(inv.to_dict())
     storage.write(dump, filename)
Example #29
0
def _parser_callback(args):  # pylint: disable=too-many-statements
    if args.instance_path and not path.isdir(args.instance_path):
        raise argparse.ArgumentTypeError(
            f"Directory {args.instance_path} is not a valid path!")

    if args.workers < 1:
        print(f"{args.workers} is not a positive number!")
        return 1

    storage = Storage.create(args.instance_path)
    status = info(None, storage)["status"]
    delete_existing_state = False

    if storage.exists("instances"):
        if args.resume and status == "error":
            if not args.force:
                print(
                    "The resume deploy option might have unexpected consequences on the already deployed blueprint."
                )
                question = prompt_yes_no_question()
                if not question:
                    return 0
        elif args.clean_state:
            if args.force:
                delete_existing_state = True
            else:
                print("The clean state deploy option might have unexpected "
                      "consequences on the already deployed blueprint.")
                question = prompt_yes_no_question()
                if question:
                    delete_existing_state = True
                else:
                    return 0
        elif status == "initialized":
            print(
                "The project is initialized. You have to deploy it first to be able to run undeploy."
            )
            return 0
        elif status == "undeploying":
            print(
                "The project is currently undeploying. Please try again after the undeployment."
            )
            return 0
        elif status == "deployed":
            print("All instances have already been deployed.")
            return 0
        elif status == "error":
            print(
                "The instance model already exists. Use --resume/-r to continue or --clean-state/-c to delete "
                "current deployment state and start over the deployment.")
            return 0

    if args.template:
        csar_or_st_path = PurePath(args.template.name)
    else:
        if storage.exists("root_file"):
            csar_or_st_path = PurePath(storage.read("root_file"))
        else:
            print(
                "CSAR or template root file does not exist. Maybe you have forgotten to initialize it."
            )
            return 1

    try:
        if args.inputs:
            inputs = yaml.safe_load(args.inputs)
        else:
            inputs = None
    except yaml.YAMLError as e:
        print(f"Invalid inputs: {e}")
        return 1

    try:
        if is_zipfile(csar_or_st_path):
            deploy_compressed_csar(csar_or_st_path, inputs, storage,
                                   args.verbose, args.workers,
                                   delete_existing_state)
        else:
            deploy_service_template(csar_or_st_path, inputs, storage,
                                    args.verbose, args.workers,
                                    delete_existing_state)
    except ParseError as e:
        print(f"{e.loc}: {e}")
        return 1
    except DataError as e:
        print(str(e))
        return 1

    return 0
Example #30
0
def prepare_template(path, yaml_text, template):
    name = PurePath("service.yaml")
    (path / name).write_text(yaml_text(template))
    storage = Storage(path / Path(".opera"))
    return template, path, storage