Example #1
0
def update_cache(entity_type):
    """Update the data for dynamic entities stored in the cache"""

    LOG.debug("Updating cache")
    # Update api cache
    Cache.sync(entity_type)
    # Update version cache
    Version.sync()
    LOG.debug("Success")
    show_cache()
    LOG.info(highlight_text("Cache updated at {}".format(datetime.datetime.now())))
Example #2
0
    def invoke(self, ctx):

        if not ctx.protected_args:
            return super(FeatureFlagMixin, self).invoke(ctx)

        cmd_name = ctx.protected_args[0]

        feature_min_version = self.feature_version_map.get(cmd_name, "")
        if feature_min_version:
            calm_version = Version.get_version("Calm")
            if not calm_version:
                LOG.error("Calm version not found. Please update cache")
                sys.exit(-1)

            if LV(calm_version) >= LV(feature_min_version):
                return super().invoke(ctx)

            else:
                LOG.warning(
                    "Please update Calm (v{} -> >=v{}) to use this command.".
                    format(calm_version, feature_min_version))
                return None

        else:
            return super().invoke(ctx)
Example #3
0
def get_validators_with_defaults(schema_props):

    validators = {}
    defaults = {}
    display_map = bidict()
    for name, props in schema_props.items():
        calm_version = Version.get_version("Calm")

        # dev machines do not follow standard version protocols. Avoid matching there
        attribute_min_version = str(props.get("x-calm-dsl-min-version", ""))
        if not calm_version:
            # Raise warning and set default to 2.9.0
            calm_version = "2.9.0"

        # If attribute version is less than calm version, ignore it
        if attribute_min_version and LV(attribute_min_version) > LV(calm_version):
            continue

        ValidatorType, is_array, default = get_validator_details(schema_props, name)
        attr_name = props.get("x-calm-dsl-display-name", name)
        validators[attr_name] = (ValidatorType, is_array)
        defaults[attr_name] = default
        display_map[attr_name] = name

    return validators, defaults, display_map
Example #4
0
    def compile(cls):
        cdict = super().compile()
        if (cdict.get("provider_type", "")) == "":
            cdict.pop("provider_type", "")
        if (cdict.get("value_type", "")) == "":
            cdict.pop("value_type", "")

        CALM_VERSION = Version.get_version("Calm")
        if LV(CALM_VERSION) < LV("3.2.0"):
            value_type = cdict.pop("value_type")
            cdict["attrs"]["value_type"] = value_type

        else:
            value_type = cdict.get("value_type", "IP")
            if value_type == "VM":
                account = cdict["attrs"]["account_reference"]
                account_name = account["name"]
                account_data = Cache.get_entity_data(
                    entity_type=CACHE.ENTITY.ACCOUNT, name=account_name)
                if not account_data:
                    LOG.error("Account {} not found".format(account_name))
                    sys.exit(-1)

                provider_type = account_data["provider_type"]
                if provider_type not in ["nutanix_pc", "vmware"]:
                    LOG.error("Provider {} not supported for endpoints".format(
                        provider_type))
                    sys.exit(-1)

                cdict["provider_type"] = provider_type.upper()

        return cdict
Example #5
0
    def compile(cls):
        cdict = super().compile()

        cdict["account_reference_list"] = []
        cdict["subnet_reference_list"] = []
        cdict["external_network_list"] = []
        cdict["default_subnet_reference"] = {}

        CALM_VERSION = Version.get_version("Calm")
        default_subnet_reference = None

        # Populate accounts
        provider_list = cdict.pop("provider_list", [])
        for provider_obj in provider_list:
            provider_data = provider_obj.get_dict()

            if provider_obj.type == "nutanix_pc":
                if "subnet_reference_list" in provider_data:
                    cdict["subnet_reference_list"].extend(
                        provider_data["subnet_reference_list"])

                if "external_network_list" in provider_data:
                    for _network in provider_data["external_network_list"]:
                        _network.pop("kind", None)
                        cdict["external_network_list"].append(_network)

                if "default_subnet_reference" in provider_data:
                    # From 3.2, only subnets from local account can be marked as default
                    if provider_data.get("subnet_reference_list"
                                         ) or LV(CALM_VERSION) < LV("3.2.0"):
                        cdict["default_subnet_reference"] = provider_data[
                            "default_subnet_reference"]

            if "account_reference" in provider_data:
                cdict["account_reference_list"].append(
                    provider_data["account_reference"])

        quotas = cdict.pop("quotas", None)
        if quotas:
            project_resources = []
            for qk, qv in quotas.items():
                if qk != "VCPUS":
                    qv *= 1073741824

                project_resources.append({"limit": qv, "resource_type": qk})

            cdict["resource_domain"] = {"resources": project_resources}

        # pop out unnecessary attibutes
        cdict.pop("environment_definition_list", None)
        # empty dict is not accepted for default_environment_reference
        default_env = cdict.get("default_environment_reference")
        if not default_env:
            cdict.pop("default_environment_reference", None)

        if not cdict.get("default_subnet_reference"):
            cdict.pop("default_subnet_reference", None)
        return cdict
def create_environment_payload(UserEnvironment, metadata=dict()):
    """
    Creates environment payload
    Args:
        UserEnvironment(object): Environment object
        metadata (dict) : Metadata for environment
    Returns:
        response(tuple): tuple consisting of environment payload object and error
    """

    err = {"error": "", "code": -1}

    if UserEnvironment is None:
        err["error"] = "Given environment is empty."
        return None, err

    if not isinstance(UserEnvironment, EnvironmentType):
        err["error"] = "Given environment is not of type Environment"
        return None, err

    spec = {
        "name": UserEnvironment.__name__,
        "description": UserEnvironment.__doc__ or "",
        "resources": UserEnvironment,
    }

    env_project = metadata.get("project_reference", {}).get("name", "")
    if not env_project:
        ContextObj = get_context()
        project_config = ContextObj.get_project_config()
        env_project = project_config["name"]

    project_cache_data = Cache.get_entity_data(
        entity_type=CACHE.ENTITY.PROJECT, name=env_project)
    if not project_cache_data:
        LOG.error("Project {} not found.".format(env_project))
        sys.exit("Project {} not found.".format(env_project))

    metadata_payload = {
        "spec_version": 1,
        "kind": "environment",
        "name": UserEnvironment.__name__,
        "uuid": str(uuid.uuid4()),
    }

    calm_version = Version.get_version("Calm")
    if LV(calm_version) >= LV("3.2.0"):
        metadata_payload["project_reference"] = {
            "kind": "project",
            "name": project_cache_data["name"],
            "uuid": project_cache_data["uuid"],
        }

    UserEnvironmentPayload = _environment_payload()
    UserEnvironmentPayload.metadata = metadata_payload
    UserEnvironmentPayload.spec = spec

    return UserEnvironmentPayload, None
def validate_version():

    # At initializing dsl, version might not found in cache
    calm_version = Version.get_version("Calm")
    if calm_version:
        if LV(calm_version) < LV(LATEST_VERIFIED_VERSION):
            LOG.warning(
                "Calm server version ({}) is less than verified version. ({})."
                .format(calm_version, LATEST_VERIFIED_VERSION))
Example #8
0
    def test_endpoint_validation_and_type_update2(self, EndpointPayload):
        """
        test_endpoint_name_validations
        """

        client = get_api_client()
        endpoint = copy.deepcopy(change_uuids(EndpointPayload, {}))

        # set values and credentials to empty
        CALM_VERSION = Version.get_version("Calm")
        if LV(CALM_VERSION) < LV("3.3.0"):
            message = (
                "Name can contain only alphanumeric, underscores, hyphens and spaces"
            )
        else:
            message = "Name can contain only unicode characters, underscores, hyphens and spaces"

        endpoint["spec"]["name"] = "ep-$.-name1" + str(uuid.uuid4())[-10:]
        # Endpoint Create
        res, err = client.endpoint.create(endpoint)
        if not err:
            pytest.fail(
                "Endpoint created successfully with unsupported name formats")
        assert err.get("code", 0) == 422
        assert message in res.text

        endpoint["spec"]["name"] = "endpoint_" + str(uuid.uuid4())[-10:]
        res, err = client.endpoint.create(endpoint)
        if err:
            pytest.fail("[{}] - {}".format(err["code"], err["error"]))
        ep = res.json()
        ep_uuid = ep["metadata"]["uuid"]
        ep_name = ep["spec"]["name"]
        print(">> Endpoint created: {}".format(ep_name))

        del ep["status"]
        ep["spec"]["name"] = "-test_ep_name_" + str(uuid.uuid4())[-10:]

        if LV(CALM_VERSION) < LV("3.3.0"):
            message = (
                "Names can only start with alphanumeric characters or underscore (_)"
            )
        else:
            message = "Names can only start with unicode characters or underscore (_)"
        res, err = client.endpoint.update(ep_uuid, ep)
        if not err:
            pytest.fail(
                "Endpoint updated successfully with unsupported name formats")
        assert err.get("code", 0) == 422
        assert message in res.text

        # delete the endpoint
        _, err = client.endpoint.delete(ep_uuid)
        if err:
            pytest.fail("[{}] - {}".format(err["code"], err["error"]))
        else:
            print("endpoint {} deleted".format(ep_name))
Example #9
0
def create_environment_payload(UserEnvironment):

    err = {"error": "", "code": -1}

    if UserEnvironment is None:
        err["error"] = "Given environment is empty."
        return None, err

    if not isinstance(UserEnvironment, EnvironmentType):
        err["error"] = "Given environment is not of type Environment"
        return None, err

    spec = {
        "name": UserEnvironment.__name__,
        "description": UserEnvironment.__doc__ or "",
        "resources": UserEnvironment,
    }

    ContextObj = get_context()
    project_config = ContextObj.get_project_config()
    project_cache_data = Cache.get_entity_data(
        entity_type=CACHE.ENTITY.PROJECT, name=project_config["name"])
    if not project_cache_data:
        LOG.error("Project {} not found.".format(project_config["name"]))
        sys.exit(-1)

    metadata = {
        "spec_version": 1,
        "kind": "environment",
        "name": UserEnvironment.__name__,
    }

    calm_version = Version.get_version("Calm")
    if LV(calm_version) >= LV("3.2.0"):
        metadata["project_reference"] = {
            "kind": "project",
            "name": project_cache_data["name"],
            "uuid": project_cache_data["uuid"],
        }

    UserEnvironmentPayload = _environment_payload()
    UserEnvironmentPayload.metadata = metadata
    UserEnvironmentPayload.spec = spec

    return UserEnvironmentPayload, None
Example #10
0
    def convert(self, value, param, ctx):

        if self.feature_min_version:
            calm_version = Version.get_version("Calm")
            if not calm_version:
                LOG.error("Calm version not found. Please update cache")
                sys.exit(-1)

            # TODO add the pc version to warning also
            if LV(calm_version) < LV(self.feature_min_version):
                LOG.error(
                    "Calm {} does not support '{}' option. Please upgrade server to Calm {}"
                    .format(calm_version, param.name,
                            self.feature_min_version))
                sys.exit(-1)

        # Add validation for file types etc.
        return value
def get_vmware_vm_data_with_version_filtering(vm_data):
    """returns instance_data_according_to_version_filter"""

    CALM_VERSION = Version.get_version("Calm")

    instance_id = vm_data["instance_id"]
    instance_name = vm_data["instance_name"]

    if LV(CALM_VERSION) >= LV("3.3.0"):
        hostname = vm_data["guest_hostname"]
        address = ",".join(vm_data["guest_ipaddress"])
        vcpus = vm_data["cpu"]
        sockets = vm_data["num_vcpus_per_socket"]
        memory = int(vm_data["memory"]) // 1024
        guest_family = vm_data.get("guest_family", "")
        template = vm_data.get("is_template", False)

    else:
        hostname = vm_data["guest.hostName"]
        address = ",".join(vm_data["guest.ipAddress"])
        vcpus = vm_data["config.hardware.numCPU"]
        sockets = vm_data["config.hardware.numCoresPerSocket"]
        memory = int(vm_data["config.hardware.memoryMB"]) // 1024
        guest_family = vm_data.get("guest.guestFamily", "")
        template = vm_data.get("config.template", False)

    return (
        instance_id,
        instance_name,
        hostname,
        address,
        vcpus,
        sockets,
        memory,
        guest_family,
        template,
    )
Example #12
0
def get_accounts(name, filter_by, limit, offset, quiet, all_items,
                 account_type):
    """Get the accounts, optionally filtered by a string"""

    client = get_api_client()
    calm_version = Version.get_version("Calm")

    params = {"length": limit, "offset": offset}
    filter_query = ""
    if name:
        filter_query = get_name_query([name])
    if filter_by:
        filter_query = filter_query + ";(" + filter_by + ")"
    if account_type:
        filter_query += ";(type=={})".format(",type==".join(account_type))
    if all_items:
        filter_query += get_states_filter(ACCOUNT.STATES)

    # Remove PE accounts for versions >= 2.9.0 (TODO move to constants)
    if LV(calm_version) >= LV("2.9.0"):
        filter_query += ";type!=nutanix"

    if filter_query.startswith(";"):
        filter_query = filter_query[1:]

    if filter_query:
        params["filter"] = filter_query

    res, err = client.account.list(params)

    if err:
        ContextObj = get_context()
        server_config = ContextObj.get_server_config()
        pc_ip = server_config["pc_ip"]

        LOG.warning("Cannot fetch accounts from {}".format(pc_ip))
        return

    res = res.json()
    total_matches = res["metadata"]["total_matches"]
    if total_matches > limit:
        LOG.warning(
            "Displaying {} out of {} entities. Please use --limit and --offset option for more results."
            .format(limit, total_matches))

    json_rows = res["entities"]
    if not json_rows:
        click.echo(highlight_text("No account found !!!\n"))
        return

    if quiet:
        for _row in json_rows:
            row = _row["status"]
            click.echo(highlight_text(row["name"]))
        return

    table = PrettyTable()
    table.field_names = [
        "NAME",
        "ACCOUNT TYPE",
        "STATE",
        "OWNER",
        "CREATED ON",
        "LAST UPDATED",
        "UUID",
    ]

    for _row in json_rows:
        row = _row["status"]
        metadata = _row["metadata"]

        creation_time = int(metadata["creation_time"]) // 1000000
        last_update_time = int(metadata["last_update_time"]) // 1000000
        if "owner_reference" in metadata:
            owner_reference_name = metadata["owner_reference"]["name"]
        else:
            owner_reference_name = "-"

        table.add_row([
            highlight_text(row["name"]),
            highlight_text(row["resources"]["type"]),
            highlight_text(row["resources"]["state"]),
            highlight_text(owner_reference_name),
            highlight_text(time.ctime(creation_time)),
            "{}".format(arrow.get(last_update_time).humanize()),
            highlight_text(metadata["uuid"]),
        ])
    click.echo(table)
Example #13
0
from calm.dsl.builtins import read_local_file
from calm.dsl.config import get_context
from calm.dsl.store import Version
from calm.dsl.log import get_logging_handle

LOG = get_logging_handle(__name__)

DSL_PROJECT_PATH = "tests/project/test_project_in_pc.py"
DSL_PROJECT_WITH_ENV_PATH = "tests/project/test_project_with_env.py"

DSL_CONFIG = json.loads(read_local_file(".tests/config.json"))
USER = DSL_CONFIG["USERS"][0]
USER_NAME = USER["NAME"]

# calm_version
CALM_VERSION = Version.get_version("Calm")


class TestProjectCommands:
    def setup_method(self):
        """"Reset the context changes"""
        ContextObj = get_context()
        ContextObj.reset_configuration()

    def teardown_method(self):
        """"Reset the context changes"""
        ContextObj = get_context()
        ContextObj.reset_configuration()

    def test_projects_list(self):
        runner = CliRunner()
Example #14
0
def create_project_from_dsl(project_file, project_name, description=""):
    """Steps:
    1. Creation of project without env
    2. Creation of env
    3. Updation of project for adding env details
    """

    client = get_api_client()

    user_project_module = get_project_module_from_file(project_file)
    UserProject = get_project_class_from_module(user_project_module)
    if UserProject is None:
        LOG.error("User project not found in {}".format(project_file))
        return

    envs = []
    if hasattr(UserProject, "envs"):
        envs = getattr(UserProject, "envs", [])

    default_environment_name = ""
    if (hasattr(UserProject, "default_environment")
            and UserProject.default_environment is not None):
        default_environment = getattr(UserProject, "default_environment", None)
        UserProject.default_environment = {}
        default_environment_name = default_environment.__name__

    if envs and not default_environment_name:
        default_environment_name = envs[0].__name__

    calm_version = Version.get_version("Calm")
    if LV(calm_version) < LV("3.2.0"):
        for _env in envs:
            env_name = _env.__name__
            LOG.info(
                "Searching for existing environments with name '{}'".format(
                    env_name))
            res, err = client.environment.list(
                {"filter": "name=={}".format(env_name)})
            if err:
                LOG.error(err)
                sys.exit(-1)

            res = res.json()
            if res["metadata"]["total_matches"]:
                LOG.error("Environment with name '{}' already exists".format(
                    env_name))

            LOG.info("No existing environment found with name '{}'".format(
                env_name))

    # Creation of project
    project_payload = compile_project_dsl_class(UserProject)
    project_data = create_project(project_payload,
                                  name=project_name,
                                  description=description)
    project_name = project_data["name"]
    project_uuid = project_data["uuid"]

    if envs:
        # Update project in cache
        LOG.info("Updating projects cache")
        Cache.sync_table("project")
        LOG.info("[Done]")

        # As ahv helpers in environment should use account from project accounts
        # updating the context
        ContextObj = get_context()
        ContextObj.update_project_context(project_name=project_name)

        default_environment_ref = {}

        # Create environment
        env_ref_list = []
        for env_obj in envs:
            env_res_data = create_environment_from_dsl_class(env_obj)
            env_ref = {"kind": "environment", "uuid": env_res_data["uuid"]}
            env_ref_list.append(env_ref)
            if (default_environment_name
                    and env_res_data["name"] == default_environment_name):
                default_environment_ref = env_ref

        LOG.info("Updating project '{}' for adding environment".format(
            project_name))
        project_payload = get_project(project_uuid=project_uuid)

        project_payload.pop("status", None)
        project_payload["spec"]["resources"][
            "environment_reference_list"] = env_ref_list

        default_environment_ref = default_environment_ref or {
            "kind": "environment",
            "uuid": env_ref_list[0]["uuid"],
        }

        # default_environment_reference added in 3.2
        calm_version = Version.get_version("Calm")
        if LV(calm_version) >= LV("3.2.0"):
            project_payload["spec"]["resources"][
                "default_environment_reference"] = default_environment_ref

        update_project(project_uuid=project_uuid,
                       project_payload=project_payload)

        # Reset the context changes
        ContextObj.reset_configuration()

    # Update projects in cache
    LOG.info("Updating projects cache ...")
    Cache.sync_table(cache_type=CACHE.ENTITY.PROJECT)
    LOG.info("[Done]")
Example #15
0
def create_spec(client):

    CALM_VERSION = Version.get_version("Calm")
    spec = {}
    Obj = Azure(client.connection)

    account_id = ""
    resource_group = ""
    location = ""
    vm_os = ""

    # VM Configuration

    projects = client.project.get_name_uuid_map()
    project_list = list(projects.keys())

    if not project_list:
        click.echo(highlight_text("No projects found!!!"))
        click.echo(highlight_text("Please add first"))
        return

    click.echo("\nChoose from given projects:")
    for ind, name in enumerate(project_list):
        click.echo("\t {}. {}".format(str(ind + 1), highlight_text(name)))

    project_id = ""
    while True:
        ind = click.prompt("\nEnter the index of project", default=1)
        if (ind > len(project_list)) or (ind <= 0):
            click.echo("Invalid index !!! ")

        else:
            project_id = projects[project_list[ind - 1]]
            click.echo("{} selected".format(
                highlight_text(project_list[ind - 1])))
            break

    res, err = client.project.read(project_id)
    if err:
        raise Exception("[{}] - {}".format(err["code"], err["error"]))

    project = res.json()
    accounts = project["status"]["resources"]["account_reference_list"]

    reg_accounts = []
    for account in accounts:
        reg_accounts.append(account["uuid"])

    payload = {"filter": "type==azure"}
    res, err = client.account.list(payload)
    if err:
        raise Exception("[{}] - {}".format(err["code"], err["error"]))

    res = res.json()
    azure_accounts = {}

    for entity in res["entities"]:
        entity_name = entity["metadata"]["name"]
        entity_id = entity["metadata"]["uuid"]
        if entity_id in reg_accounts:
            azure_accounts[entity_name] = entity_id

    accounts = list(azure_accounts.keys())
    spec["resources"] = {}

    click.echo("\nChoose from given AZURE accounts")
    for ind, name in enumerate(accounts):
        click.echo("\t {}. {}".format(str(ind + 1), highlight_text(name)))

    while True:
        res = click.prompt("\nEnter the index of account to be used",
                           default=1)
        if (res > len(accounts)) or (res <= 0):
            click.echo("Invalid index !!! ")

        else:
            account_name = accounts[res - 1]
            account_id = azure_accounts[account_name]  # TO BE USED

            spec["resources"]["account_uuid"] = account_id
            click.echo("{} selected".format(highlight_text(account_name)))
            break

    if not account_id:
        click.echo(
            highlight_text(
                "No azure account found registered in this project !!!"))
        click.echo("Please add one !!!")
        return

    click.echo("\nChoose from given Operating System types:")
    os_types = azure.OPERATING_SYSTEMS

    for ind, name in enumerate(os_types):
        click.echo("\t {}. {}".format(str(ind + 1), highlight_text(name)))

    while True:
        ind = click.prompt("\nEnter the index of operating system", default=1)
        if (ind > len(os_types)) or (ind <= 0):
            click.echo("Invalid index !!! ")

        else:
            vm_os = os_types[ind - 1]
            click.echo("{} selected".format(highlight_text(vm_os)))
            break

    click.echo("\n\t\t", nl=False)
    click.secho("VM Configuration", bold=True, underline=True)

    vm_name = "vm-@@{calm_unique_hash}@@-@@{calm_array_index}@@"
    spec["resources"]["vm_name"] = click.prompt("\nEnter instance name",
                                                default=vm_name)

    # Add resource group
    resource_groups = Obj.resource_groups(account_id)
    if not resource_groups:
        click.echo("\n{}".format(highlight_text("No resource group present")))

    else:
        click.echo("\nChoose from given resource groups")
        for ind, name in enumerate(resource_groups):
            click.echo("\t {}. {}".format(str(ind + 1), highlight_text(name)))

        while True:
            res = click.prompt("\nEnter the index of resource group",
                               default=1)
            if (res > len(resource_groups)) or (res <= 0):
                click.echo("Invalid index !!! ")

            else:
                resource_group = resource_groups[res - 1]  # TO BE USED
                spec["resources"]["resource_group"] = resource_group
                click.echo("{} selected".format(
                    highlight_text(resource_group)))
                break

    # Add location
    locations = Obj.locations(account_id)
    if not locations:
        click.echo("\n{}".format(highlight_text("No location group present")))

    else:
        click.echo("\nChoose from given locations")
        location_names = list(locations.keys())
        for ind, name in enumerate(location_names):
            click.echo("\t {}. {}".format(str(ind + 1), highlight_text(name)))

        while True:
            res = click.prompt("\nEnter the index of resource group",
                               default=1)
            if (res > len(location_names)) or (res <= 0):
                click.echo("Invalid index !!! ")

            else:
                location = location_names[res - 1]
                click.echo("{} selected".format(highlight_text(location)))
                location = locations[location]
                spec["resources"]["location"] = location
                break

    if LV(CALM_VERSION) < LV("3.2.0"):
        # Add availabililty set
        choice = click.prompt(
            "\n{}(y/n)".format(
                highlight_text("Want to add a availabilty set")),
            default="n",
        )
        if choice[0] == "y":
            availability_sets = Obj.availability_sets(account_id,
                                                      resource_group)
            avl_set_list = list(availability_sets.keys())

            if not avl_set_list:
                click.echo("\n{}".format(
                    highlight_text("No availability_set present")))

            else:
                click.echo("\nChoose from given availabilty set")
                for ind, name in enumerate(avl_set_list):
                    click.echo("\t {}. {}".format(str(ind + 1),
                                                  highlight_text(name)))

                while True:
                    res = click.prompt("\nEnter the index of availabilty set",
                                       default=1)
                    if (res > len(avl_set_list)) or (res <= 0):
                        click.echo("Invalid index !!! ")

                    else:
                        avl_set = avl_set_list[res - 1]
                        spec["resources"][
                            "availability_set_id"] = availability_sets[avl_set]
                        click.echo("{} selected".format(
                            highlight_text(avl_set)))
                        break

    else:
        # Add availability option
        choice = click.prompt(
            "\n{}(y/n)".format(
                highlight_text("Want to select availability options")),
            default="n",
        )
        if choice[0] == "y":
            availability_options = ["Availability Sets", "Availability Zones"]
            click.echo("\nChoose from given availability options")
            for ind, name in enumerate(availability_options):
                click.echo("\t {}. {}".format(str(ind + 1),
                                              highlight_text(name)))

            while True:
                res = click.prompt("\nEnter the index of option", default=1)
                if (res > len(availability_options)) or (res <= 0):
                    click.echo("Invalid index !!! ")

                else:
                    spec["resources"][
                        "availability_option"] = availability_options[
                            res - 1].replace(" ", "")
                    click.echo("{} selected".format(
                        highlight_text(availability_options[res - 1])))
                    if res == 1:
                        availability_sets = Obj.availability_sets(
                            account_id, spec["resources"]["resource_group"])
                        avl_set_list = list(availability_sets.keys())

                        if not avl_set_list:
                            click.echo("\n{}".format(
                                highlight_text("No availability_set present")))

                        else:
                            click.echo("\nChoose from given availabilty set")
                            for ind, name in enumerate(avl_set_list):
                                click.echo("\t {}. {}".format(
                                    str(ind + 1), highlight_text(name)))

                            while True:
                                res = click.prompt(
                                    "\nEnter the index of availabilty set",
                                    default=1)
                                if (res > len(avl_set_list)) or (res <= 0):
                                    click.echo("Invalid index !!! ")

                                else:
                                    avl_set = avl_set_list[res - 1]
                                    spec["resources"][
                                        "availability_set_id"] = availability_sets[
                                            avl_set]
                                    click.echo("{} selected".format(
                                        highlight_text(avl_set)))
                                    break

                    else:
                        availability_zones = Obj.availability_zones(
                            account_id,
                            spec["resources"]["resource_group"],
                            spec["resources"]["location"],
                        )
                        if not availability_zones:
                            click.echo("\n{}".format(
                                highlight_text(
                                    "Selected location does not support Availability Zones"
                                )))
                        else:
                            click.echo("\nChoose from the given zones")
                            zones = list(availability_zones.keys())
                            for ind, name in enumerate(zones):
                                click.echo("\t {}. {}".format(
                                    str(ind + 1), highlight_text(name)))

                            while True:
                                res = click.prompt("\nEnter the index of zone",
                                                   default=1)
                                if (res > len(availability_zones)) or (res <=
                                                                       0):
                                    click.echo("Invalid index !!! ")
                                else:
                                    click.echo("{} selected".format(
                                        highlight_text(zones[res - 1])))
                                    spec["resources"][
                                        "availability_zone"] = availability_zones[
                                            zones[res - 1]]
                                    break
                    break

    hardware_profiles = Obj.hardware_profiles(account_id, location)
    if not hardware_profiles:
        click.echo("\n{}".format(
            highlight_text("No hardware profile present")))

    else:
        click.echo("\nChoose from given Hardware Profiles")
        hw_profile_names = list(hardware_profiles.keys())

        for ind, name in enumerate(hw_profile_names):
            click.echo("\t {}. {}".format(str(ind + 1), highlight_text(name)))

        while True:
            res = click.prompt("\nEnter the index of Hardware Profile",
                               default=1)
            if (res > len(hw_profile_names)) or (res <= 0):
                click.echo("Invalid index !!! ")

            else:
                hw_profile = hw_profile_names[res - 1]
                click.echo("{} selected".format(highlight_text(hw_profile)))
                spec["resources"]["hw_profile"] = {
                    "vm_size": hw_profile,
                    "max_data_disk_count": hardware_profiles[hw_profile],
                }
                break

    # OS Profile
    spec["resources"]["os_profile"] = get_os_profile(vm_os)

    # Storage Profile
    spec["resources"]["storage_profile"] = get_storage_profile(
        Obj, account_id, location)

    # Network Profile
    spec["resources"]["nw_profile"] = {}
    spec["resources"]["nw_profile"]["nic_list"] = get_nw_profile(
        Obj, account_id, resource_group, location)

    # Add tags
    choice = click.prompt("\n{}(y/n)".format(
        highlight_text("Want to add any tags")),
                          default="n")
    if choice[0] == "y":
        tags = []
        while True:
            key = click.prompt("\n\tKey")
            value = click.prompt("\tValue")

            tag = {"key": key, "value": value}
            tags.append(tag)
            choice = click.prompt("\n{}(y/n)".format(
                highlight_text("Want to add more tags")),
                                  default="n")
            if choice[0] == "n":
                spec["resources"]["tag_list"] = tags
                break

    AzureVmProvider.validate_spec(spec)
    click.secho("\nCreate spec for your AZURE VM:\n", underline=True)
    click.echo(highlight_text(yaml.dump(spec, default_flow_style=False)))
Example #16
0
    def get_referenced_account_uuid(cls):
        """
            SUBSTRATE GIVEN UNDER BLUEPRINT
        If calm-version < v3.2.0:
            1. account_reference is not available at substrate-level, So need to read from project only
        If calm-version >= 3.2.0:
            1. account_reference is available at substrate-level
                1.a: If env is given at profile-level, then account must be whitelisted in environment
                1.b: If env is not given at profile-level, then account must be whitelisted in project
            2. If account_reference is not available at substrate-level
                2.a: If env is given at profile-level, return provider account in env
                2.b: If env is not given at profile-level, return provider account in project

            SUBSTRATE GIVEN UNDER ENVIRONMENT
        If calm-version < v3.2.0:
            1. account_reference is not available at substrate-level, So need to read from project only
        If calm-version >= 3.2.0:
            1. account_reference is available at substrate-level
                1. account must be filtered at environment
            2. If account_reference is not available at substrate-level
                2.a: return provider account whitelisted in environment

        """

        provider_account = getattr(cls, "account", {})
        calm_version = Version.get_version("Calm")
        provider_type = getattr(cls, "provider_type")
        provider_account_type = PROVIDER_ACCOUNT_TYPE_MAP.get(provider_type, "")
        if not provider_account_type:
            return ""

        # Fetching project data
        project_cache_data = common_helper.get_cur_context_project()
        project_name = project_cache_data.get("name")
        project_accounts = project_cache_data.get("accounts_data", {}).get(
            provider_account_type, []
        )
        if not project_accounts:
            LOG.error(
                "No '{}' account registered to project '{}'".format(
                    provider_account_type, project_name
                )
            )
            sys.exit(-1)

        # If substrate is defined in blueprint file
        cls_bp = common_helper._walk_to_parent_with_given_type(cls, "BlueprintType")
        if cls_bp:
            environment = {}
            for cls_profile in cls_bp.profiles:
                for cls_deployment in cls_profile.deployments:
                    if cls_deployment.substrate.name != str(cls):
                        continue

                    environment = getattr(cls_profile, "environment", {})
                    if environment:
                        LOG.debug(
                            "Found environment {} associated to app-profile {}".format(
                                environment.get("name"), cls_profile
                            )
                        )
                    break

            # If environment is given at profile level
            if environment:
                environment_cache_data = Cache.get_entity_data_using_uuid(
                    entity_type=CACHE.ENTITY.ENVIRONMENT, uuid=environment["uuid"]
                )
                if not environment_cache_data:
                    LOG.error(
                        "Environment {} not found. Please run: calm update cache".format(
                            environment["name"]
                        )
                    )
                    sys.exit(-1)

                accounts = environment_cache_data.get("accounts_data", {}).get(
                    provider_account_type, []
                )
                if not accounts:
                    LOG.error(
                        "Environment '{}' has no '{}' account.".format(
                            environment_cache_data.get("name", ""),
                            provider_account_type,
                        )
                    )
                    sys.exit(-1)

                # If account given at substrate, it should be whitelisted in environment
                if provider_account and provider_account["uuid"] != accounts[0]["uuid"]:
                    LOG.error(
                        "Account '{}' not filtered in environment '{}'".format(
                            provider_account["name"],
                            environment_cache_data.get("name", ""),
                        )
                    )
                    sys.exit(-1)

                # If provider_account is not given, then fetch from env
                elif not provider_account:
                    provider_account = {
                        "name": accounts[0]["name"],
                        "uuid": accounts[0]["uuid"],
                    }

            # If environment is not given at profile level
            else:
                # if provider_account is given, it should be part of project
                if not project_accounts:
                    LOG.error(
                        "No '{}' account registered to project '{}'".format(
                            provider_account_type, project_name
                        )
                    )
                    sys.exit(-1)

                if (
                    provider_account
                    and provider_account["uuid"] not in project_accounts
                ):
                    LOG.error(
                        "Account '{}' not filtered in project '{}'".format(
                            provider_account["name"], project_name
                        )
                    )
                    sys.exit(-1)

                # Else take first account in project
                elif not provider_account:
                    provider_account = {"uuid": project_accounts[0], "kind": "account"}

        # If substrate defined inside environment
        cls_env = common_helper._walk_to_parent_with_given_type(cls, "EnvironmentType")
        if cls_env:
            infra = getattr(cls_env, "providers", [])
            whitelisted_account = {}
            for _pdr in infra:
                if _pdr.type == PROVIDER_ACCOUNT_TYPE_MAP[provider_type]:
                    whitelisted_account = _pdr.account_reference.get_dict()
                    break

            if LV(calm_version) >= LV("3.2.0"):
                if provider_account and provider_account[
                    "uuid"
                ] != whitelisted_account.get("uuid", ""):
                    LOG.error(
                        "Account '{}' not filtered in environment '{}'".format(
                            provider_account["name"], str(cls_env)
                        )
                    )
                    sys.exit(-1)

                elif not whitelisted_account:
                    LOG.error(
                        "No account is filtered in environment '{}'".format(
                            str(cls_env)
                        )
                    )
                    sys.exit(-1)

                elif not provider_account:
                    provider_account = whitelisted_account

        # If version is less than 3.2.0, then it should use account from poroject only, OR
        # If no account is supplied, will take 0th account in project (in both case of blueprint/environment)
        if not provider_account:
            provider_account = {"uuid": project_accounts[0], "kind": "account"}

        return provider_account["uuid"]