Esempio n. 1
0
def _decompile_bp(bp_payload, with_secrets=False, prefix="", bp_dir=None):
    """decompiles the blueprint from payload"""

    blueprint = bp_payload["spec"]["resources"]
    blueprint_name = bp_payload["spec"].get("name", "DslBlueprint")
    blueprint_description = bp_payload["spec"].get("description", "")

    blueprint_metadata = bp_payload["metadata"]

    # POP unnecessary keys
    blueprint_metadata.pop("creation_time", None)
    blueprint_metadata.pop("last_update_time", None)

    metadata_obj = MetadataType.decompile(blueprint_metadata)

    # Copying dsl_name_map to global client_attrs
    if bp_payload["spec"]["resources"]["client_attrs"].get("None", {}):
        init_dsl_metadata_map(bp_payload["spec"]["resources"]["client_attrs"]["None"])

    LOG.info("Decompiling blueprint {}".format(blueprint_name))

    for sub_obj in blueprint.get("substrate_definition_list"):
        sub_type = sub_obj.get("type", "") or "AHV_VM"
        if sub_type == "K8S_POD":
            raise NotImplementedError(
                "Decompilation for k8s pod is not supported right now"
            )
        elif sub_type != "AHV_VM":
            LOG.warning(
                "Decompilation support for providers other than AHV is experimental."
            )
            break

    prefix = get_valid_identifier(prefix)
    bp_cls = BlueprintType.decompile(blueprint, prefix=prefix)
    bp_cls.__name__ = get_valid_identifier(blueprint_name)
    bp_cls.__doc__ = blueprint_description

    create_bp_dir(
        bp_cls=bp_cls,
        with_secrets=with_secrets,
        metadata_obj=metadata_obj,
        bp_dir=bp_dir,
    )
    click.echo(
        "\nSuccessfully decompiled. Directory location: {}. Blueprint location: {}".format(
            get_bp_dir(), os.path.join(get_bp_dir(), "blueprint.py")
        )
    )
Esempio n. 2
0
def _decompile_bp(bp_payload, with_secrets=False):
    """decompiles the blueprint from payload"""

    blueprint = bp_payload["spec"]["resources"]
    blueprint_name = bp_payload["spec"].get("name", "DslBlueprint")
    blueprint_description = bp_payload["spec"].get("description", "")

    # Copying dsl_name_map to global client_attrs
    if bp_payload["spec"]["resources"]["client_attrs"].get("None", {}):
        init_dsl_metadata_map(bp_payload["spec"]["resources"]["client_attrs"]["None"])

    LOG.info("Decompiling blueprint {}".format(blueprint_name))

    for sub_obj in blueprint.get("substrate_definition_list"):
        sub_type = sub_obj.get("type", "") or "AHV_VM"
        if sub_type == "K8S_POD":
            raise NotImplementedError(
                "Decompilation for k8s pod is not supported right now"
            )
        elif sub_type != "AHV_VM":
            LOG.warning(
                "Decompilation support for providers other than AHV is experimental/best effort"
            )
            break

    bp_cls = BlueprintType.decompile(blueprint)
    bp_cls.__name__ = get_valid_identifier(blueprint_name)
    bp_cls.__doc__ = blueprint_description

    create_bp_dir(bp_cls=bp_cls, with_secrets=with_secrets)
    click.echo("\nSuccessfully decompiled. Directory location: {}".format(get_bp_dir()))
Esempio n. 3
0
def render_credential_template(cls):

    global CRED_VAR_NAME_MAP, CRED_FILES
    LOG.debug("Rendering {} credential template".format(cls.__name__))
    if not isinstance(cls, CredentialType):
        raise TypeError("{} is not of type {}".format(cls, CredentialType))

    user_attrs = cls.get_user_attrs()
    user_attrs["description"] = cls.__doc__

    var_name = "BP_CRED_{}".format(get_valid_identifier(cls.__name__))
    file_name = "{}_{}".format(var_name, user_attrs["type"])
    file_loc = os.path.join(get_local_dir(), file_name)

    # Storing empty value in the file
    with open(file_loc, "w+") as fd:
        fd.write("")

    user_attrs["var_name"] = var_name
    user_attrs["value"] = file_name

    if user_attrs.get("editables", {}):
        user_attrs["editables"] = user_attrs["editables"].get_dict()

    # update the map
    CRED_VAR_NAME_MAP[user_attrs["name"]] = var_name
    CRED_FILES.append(file_name)

    text = render_template("credential.py.jinja2", obj=user_attrs)
    return text.strip()
Esempio n. 4
0
def get_provider_spec_string(spec, filename, provider_type, vm_images):

    # TODO add switch to use YAML_file/Helper_class for ahv provider
    dsl_file_location_alias = "os.path.join('{}', '{}')".format(
        get_specs_dir_key(), filename)
    if provider_type == "AHV_VM":
        disk_list = spec["resources"]["disk_list"]

        disk_ind_img_map = {}
        for ind, disk in enumerate(disk_list):
            data_source_ref = disk.get("data_source_reference", {})
            if data_source_ref:
                if data_source_ref.get("kind") == "app_package":
                    disk_ind_img_map[ind + 1] = get_valid_identifier(
                        data_source_ref.get("name"))
                    data_source_ref.pop("uuid", None)

        disk_pkg_string = ""
        for k, v in disk_ind_img_map.items():
            disk_pkg_string += ",{}: {}".format(k, v)
        if disk_pkg_string.startswith(","):
            disk_pkg_string = disk_pkg_string[1:]
        disk_pkg_string = "{" + disk_pkg_string + "}"

        res = "read_ahv_spec({}, disk_packages = {})".format(
            dsl_file_location_alias, disk_pkg_string)

    elif provider_type == "VMWARE_VM":
        spec_template = get_valid_identifier(spec["template"])

        if spec_template in vm_images:
            spec["template"] = ""
            res = "read_vmw_spec({}, vm_template={})".format(
                dsl_file_location_alias, spec_template)

        else:
            res = "read_vmw_spec({})".format(dsl_file_location_alias)

    else:
        res = "read_provider_spec({})".format(dsl_file_location_alias)

    return res
Esempio n. 5
0
def decompile_marketplace_bp(name, version, app_source, bp_name, project,
                             with_secrets, bp_dir):
    """decompiles marketplace blueprint"""

    if not version:
        LOG.info("Fetching latest version of Marketplace Blueprint {} ".format(
            name))
        version = get_mpi_latest_version(name=name, app_source=app_source)
        LOG.info(version)

    LOG.info("Converting MPI into blueprint")
    bp_payload = convert_mpi_into_blueprint(name=name,
                                            version=version,
                                            project_name=project,
                                            app_source=app_source)
    del bp_payload["status"]

    client = get_api_client()
    blueprint_uuid = bp_payload["metadata"]["uuid"]
    res, err = client.blueprint.export_file(blueprint_uuid)
    if err:
        LOG.error("[{}] - {}".format(err["code"], err["error"]))
        sys.exit(-1)

    bp_payload = res.json()
    blueprint = bp_payload["spec"]["resources"]
    blueprint_name = get_valid_identifier(bp_name or name)

    if not bp_dir:
        bp_dir_suffix = bp_name or "mpi_bp_{}_v{}".format(
            blueprint_name, version)
        bp_dir = os.path.join(os.getcwd(), bp_dir_suffix)

    blueprint_description = bp_payload["spec"].get("description", "")
    LOG.info("Decompiling marketplace blueprint {}".format(name))
    for sub_obj in blueprint.get("substrate_definition_list"):
        sub_type = sub_obj.get("type", "") or "AHV_VM"
        if sub_type == "K8S_POD":
            raise NotImplementedError(
                "Decompilation for k8s pod is not supported right now")
        elif sub_type != "AHV_VM":
            LOG.warning(
                "Decompilation support for providers other than AHV is experimental."
            )
            break

    bp_cls = BlueprintType.decompile(blueprint)
    bp_cls.__name__ = blueprint_name
    bp_cls.__doc__ = blueprint_description

    create_bp_dir(bp_cls=bp_cls, bp_dir=bp_dir, with_secrets=with_secrets)
    click.echo(
        "\nSuccessfully decompiled. Directory location: {}. Blueprint location: {}"
        .format(get_bp_dir(), os.path.join(get_bp_dir(), "blueprint.py")))
Esempio n. 6
0
def render_restore_config_template(cls, entity_context):
    LOG.debug("Rendering {} restore config template".format(cls.__name__))
    if not isinstance(cls, ConfigSpecType):
        raise TypeError("{} is not of type {}".format(cls, ConfigSpecType))

    _user_attrs = cls.get_user_attrs()
    user_attrs = dict()
    user_attrs["name"] = _user_attrs["name"] or cls.__name__
    attrs = _user_attrs["attrs_list"][0]
    user_attrs["target"] = get_valid_identifier(
        attrs["target_any_local_reference"]["name"]
    )
    user_attrs["delete_vm_post_restore"] = attrs["delete_vm_post_restore"]
    text = render_template(schema_file="restore_config.py.jinja2", obj=user_attrs)
    return text.strip()
Esempio n. 7
0
def render_snapshot_config_template(cls, entity_context, CONFIG_SPEC_MAP):
    LOG.debug("Rendering {} snapshot config template".format(cls.__name__))
    if not isinstance(cls, ConfigSpecType):
        raise TypeError("{} is not of type {}".format(cls, ConfigSpecType))

    _user_attrs = cls.get_user_attrs()
    user_attrs = dict()
    user_attrs["name"] = _user_attrs["name"] or cls.__name__
    user_attrs["restore_config"] = CONFIG_SPEC_MAP[
        _user_attrs["config_references"][0].name
    ]["local_name"]
    attrs = _user_attrs["attrs_list"][0]
    user_attrs["target"] = get_valid_identifier(
        attrs["target_any_local_reference"]["name"]
    )
    user_attrs["num_of_replicas"] = attrs["num_of_replicas"]
    if attrs.get("app_protection_policy_reference", None):
        user_attrs["policy"] = attrs["app_protection_policy_reference"]["name"]
    if attrs.get("app_protection_rule_reference", None):
        user_attrs["rule"] = attrs["app_protection_rule_reference"]["name"]
    text = render_template(schema_file="snapshot_config.py.jinja2", obj=user_attrs)
    return text.strip()
    def _test_decompile_with_prefix(self, bp_name):

        runner = CliRunner()

        # Decompiling the created bp and storing secrets in file with prefix
        prefix = get_valid_identifier("_{}".format(str(uuid.uuid4())[:10]))
        LOG.info(
            "Decompiling Blueprint {} with prefix flag set to '{}'".format(
                bp_name, prefix))

        cli_inputs = [CRED_PASSWORD, CRED_PASSWORD, CRED_PASSWORD]
        result = runner.invoke(
            cli,
            ["decompile", "bp", bp_name, "--with_secrets", "-p", prefix],
            input="\n".join(cli_inputs),
        )

        if result.exit_code:
            cli_res_dict = {
                "Output": result.output,
                "Exception": str(result.exception)
            }
            LOG.debug("Cli Response: {}".format(
                json.dumps(cli_res_dict, indent=4, separators=(",", ": "))))
            LOG.debug("Traceback: \n{}".format("".join(
                traceback.format_tb(result.exc_info[2]))))

        self.bp_dir_list.append(get_bp_dir())
        decompiled_bp_file_location = os.path.join(get_bp_dir(),
                                                   "blueprint.py")

        user_bp_module = get_blueprint_module_from_file(
            decompiled_bp_file_location)
        UserBlueprint = get_blueprint_class_from_module(user_bp_module)

        LOG.info("Asserting prefix in the entity names")
        for svc in UserBlueprint.services:
            assert svc.__name__.startswith(prefix)

        for pkg in UserBlueprint.packages:
            assert pkg.__name__.startswith(prefix)

        for sub in UserBlueprint.substrates:
            assert sub.__name__.startswith(prefix)
            assert sub.provider_spec.__name__.startswith(prefix)
            assert sub.provider_spec.resources.__name__.startswith(prefix)

        for pfl in UserBlueprint.profiles:
            assert pfl.__name__.startswith(prefix)

            for dep in pfl.deployments:
                assert dep.__name__.startswith(prefix)

        LOG.info("Success")

        # Resetting context for decompiling
        init_decompile_context

        # On applying prefix, name of dsl classes will be changed but UI name will be preserved
        # So compiled payload should be same

        bp_file_location = os.path.join(os.getcwd(), BP_FILE)
        LOG.info(
            "Compiling original blueprint file at {}".format(bp_file_location))
        result = runner.invoke(
            cli, ["-vv", "compile", "bp", "-f", bp_file_location])
        if result.exit_code:
            cli_res_dict = {
                "Output": result.output,
                "Exception": str(result.exception)
            }
            LOG.debug("Cli Response: {}".format(
                json.dumps(cli_res_dict, indent=4, separators=(",", ": "))))
            LOG.debug("Traceback: \n{}".format("".join(
                traceback.format_tb(result.exc_info[2]))))
        bp_json = json.loads(result.output)

        LOG.info(
            "Compiling decompiled blueprint file having entity names with prefix at {}"
            .format(decompiled_bp_file_location))
        result = runner.invoke(
            cli, ["-vv", "compile", "bp", "-f", decompiled_bp_file_location])
        if result.exit_code:
            cli_res_dict = {
                "Output": result.output,
                "Exception": str(result.exception)
            }
            LOG.debug("Cli Response: {}".format(
                json.dumps(cli_res_dict, indent=4, separators=(",", ": "))))
            LOG.debug("Traceback: \n{}".format("".join(
                traceback.format_tb(result.exc_info[2]))))

        decompiled_bp_json = json.loads(result.output)
        # We don't have paramter to pass name of blueprint during compile right now
        # So compare everythin else other than blueprint name
        decompiled_bp_json["metadata"]["name"] = bp_json["metadata"]["name"]
        decompiled_bp_json["spec"]["name"] = bp_json["spec"]["name"]

        # POP out the client attrs, as they will be changed due to prefix
        bp_json["spec"]["resources"].pop("client_attrs", {})
        decompiled_bp_json["spec"]["resources"].pop("client_attrs", {})

        LOG.info("Comparing original and decompiled blueprint json")
        assert bp_json == decompiled_bp_json
        LOG.info("Success")

        # Reseting context
        ContextObj = get_context()
        ContextObj.reset_configuration()