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())))
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)
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
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
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))
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))
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
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, )
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)
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()
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]")
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)))
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"]