def main(): # Get and log the config from the Env variable config = json.loads(os.environ["CUSTOM_SCRIPT_CONFIG"]) INFO(config) # Get PC info from the config dict pc_info = config.get("tdaas_pc") pc_external_ip = pc_info.get("ips")[0][0] pc_internal_ip = pc_info.get("ips")[0][1] pc_password = pc_info.get("prism_password") try: # Get a list of apps apps = body_via_v3_post(pc_external_ip, "apps", pc_password, None).json # Loop through our apps for app in apps["entities"]: # Print out status INFO(f'{app["status"]["name"]} App State: {app["status"]["state"]}') # Fail out if app is not in running state if app["status"]["state"].lower() != "running": raise Exception(f"{app['status']['name']} app in a non-running state.") except Exception as ex: ERROR(traceback.format_exc()) # NX-on-GCP does not support erroring out based on return codes, # so sleeping to time the deployment out time.sleep(18000)
def main(): # Get and log the config from the Env variable config = json.loads(os.environ["CUSTOM_SCRIPT_CONFIG"]) INFO(config) # Get PC info from the config dict pc_info = config.get("tdaas_pc") pc_external_ip = pc_info.get("ips")[0][0] pc_internal_ip = pc_info.get("ips")[0][1] pc_password = pc_info.get("prism_password") try: # Read in our spec file autodc_spec = file_to_dict("specs/pc_autodc.json") INFO(f"autodc_spec: {autodc_spec}") # Make API call to configure the authconfig resp = create_via_v1_post(pc_external_ip, "authconfig/directories", pc_password, autodc_spec) # Log appropriately based on response if resp.code == 200 or resp.code == 202: INFO("Authconfig configured successfully.") else: raise Exception(f"Authconfig failed with:\n" + f"Resp: {resp}\n" + f"Error Code: {resp.code}\n" + f"Error Message: {resp.message}") except Exception as ex: ERROR(traceback.format_exc())
def main(): # Get and log the config from the Env variable config = json.loads(os.environ["CUSTOM_SCRIPT_CONFIG"]) INFO(config) # Get PC info from the config dict pc_info = config.get("tdaas_pc") pc_external_ip = pc_info.get("ips")[0][0] pc_internal_ip = pc_info.get("ips")[0][1] pc_password = pc_info.get("prism_password") try: # Create the API call body body = {"enable_nutanix_apps": True} # Make API call to enable marketplace resp = create_via_v3_post(pc_external_ip, "marketplace_items/config", pc_password, body) # Log appropriately based on response if resp.code == 200 or resp.code == 202: INFO("Marketplace enabled successfully.") else: raise Exception(f"Marketplace enable failed with:\n" + f"Resp: {resp}\n" + f"Error Code: {resp.code}\n" + f"Error Message: {resp.message}") except Exception as ex: ERROR(traceback.format_exc())
def main(): # Get and log the config from the Env variable config = json.loads(os.environ["CUSTOM_SCRIPT_CONFIG"]) INFO(config) # Get PC info from the config dict pc_info = config.get("tdaas_pc") pc_external_ip = pc_info.get("ips")[0][0] pc_internal_ip = pc_info.get("ips")[0][1] pc_password = pc_info.get("prism_password") try: # Get marketplace items mp_items = body_via_v3_post(pc_external_ip, "calm_marketplace_items", pc_password, None).json # Loop through our items for item in mp_items["entities"]: # We only care about those PENDING if item["status"]["app_state"] == "PENDING": # Get and modify the body body = body_via_v3_get( pc_external_ip, "calm_marketplace_items", pc_password, item["metadata"]["uuid"], ).json del body["status"] body["spec"]["resources"]["app_state"] = "ACCEPTED" # Update the item resp = update_via_v3_put( pc_external_ip, "calm_marketplace_items", pc_password, item["metadata"]["uuid"], body, ) # Log appropriately based on response if resp.code == 200 or resp.code == 202: INFO(f"{item['status']['name']} bp approved successfully.") else: raise Exception( f"{item['status']['name']} bp approved failed with:\n" + f"Resp: {resp}\n" + f"Error Code: {resp.code}\n" + f"Error Message: {resp.message}") except Exception as ex: ERROR(traceback.format_exc())
def main(): # Get and log the config from the Env variable config = json.loads(os.environ["CUSTOM_SCRIPT_CONFIG"]) INFO(config) # Get PC info from the config dict pc_info = config.get("tdaas_pc") pc_external_ip = pc_info.get("ips")[0][0] pc_internal_ip = pc_info.get("ips")[0][1] pc_password = pc_info.get("prism_password") try: # Read in the delete spec file delete_spec = file_to_dict("specs/calm_app_delete.json") # Loop through the apps to delete for app in delete_spec["entities"]: # Get the app uuid app_uuid = uuid_via_v3_post(pc_external_ip, "apps", pc_password, app["app_name"]) # Handle soft_delete if app["soft_delete"]: app_uuid = app_uuid + "?type=soft" # Delete the app resp = del_via_v3_delete(pc_external_ip, "apps", pc_password, app_uuid) # Log appropriately based on response if resp.code == 200 or resp.code == 202: INFO(f'{app["app_name"]} app deleted successfully.') else: raise Exception( 'f{app["app_name"]} app delete failed with:\n' + f"Resp: {resp}\n" + f"Error Code: {resp.code}\n" + f"Error Message: {resp.message}") except Exception as ex: ERROR(traceback.format_exc())
def main(): # Get and log the config from the Env variable config = json.loads(os.environ["CUSTOM_SCRIPT_CONFIG"]) INFO(config) # Get PC info from the config dict pc_info = config.get("tdaas_pc") pc_external_ip = pc_info.get("ips")[0][0] pc_internal_ip = pc_info.get("ips")[0][1] pc_password = pc_info.get("prism_password") try: # Read in the spec files and conver to dicts bp_spec = file_to_dict("specs/calm_bp_upload.json") INFO(f"bp_spec: {bp_spec}") # Loop through the blueprints to upload for bp in bp_spec["entities"]: # Get our project uuid and create our payload project_uuid = uuid_via_v3_post(pc_external_ip, "projects", pc_password, bp["bp_project"]) payload = {"name": bp["bp_name"], "project_uuid": project_uuid} # Upload our blueprint resp = upload_bp_via_v3_post(pc_external_ip, pc_password, payload, bp["bp_file"]) # Log appropriately based on response if resp.code == 200 or resp.code == 202: INFO(f"{bp['bp_name']} blueprint created successfully.") else: raise Exception( f"{bp['bp_name']} blueprint create failed with:\n" + f"Resp: {resp}\n" + f"Error Code: {resp.code}\n" + f"Error Message: {resp.message}") except Exception as ex: ERROR(traceback.format_exc())
def main(): # Get and log the config from the Env variable config = json.loads(os.environ["CUSTOM_SCRIPT_CONFIG"]) INFO(config) # Get PC info from the config dict pc_info = config.get("tdaas_pc") pc_external_ip = pc_info.get("ips")[0][0] pc_internal_ip = pc_info.get("ips")[0][1] pc_password = pc_info.get("prism_password") try: # Read in our public key and create our payload public_key = file_to_string("/root/.ssh/id_rsa.pub") INFO(f"public_key: {public_key}") payload = {"name": "plugin-runner", "key": public_key} # Make API call to configure the authconfig resp = create_via_v1_post( pc_external_ip, "cluster/public_keys", pc_password, payload, ) # Log appropriately based on response if resp.code == 200 or resp.code == 202: INFO("SSH Key added to PC successfully.") else: raise Exception(f"SSH Key failed to add to PC with:\n" + f"Resp: {resp}\n" + f"Error Code: {resp.code}\n" + f"Error Message: {resp.message}") except Exception as ex: ERROR(traceback.format_exc())
def main(): # Get and log the config from the Env variable config = json.loads(os.environ["CUSTOM_SCRIPT_CONFIG"]) INFO(config) # Get PC info from the config dict pc_info = config.get("tdaas_pc") pc_external_ip = pc_info.get("ips")[0][0] pc_internal_ip = pc_info.get("ips")[0][1] pc_password = pc_info.get("prism_password") try: # Read in the spec file and conver to dict image_spec = file_to_dict("specs/pc_image.json") INFO(f"image_spec: {image_spec}") # Loop through each image for image in image_spec["entities"]: # Make API call to create image resp = create_via_v3_post(pc_external_ip, "images", pc_password, image) # Log appropriately based on response if resp.code == 200 or resp.code == 202: INFO(f"image['spec']['name'] Image created successfully.") else: raise Exception( f"image['spec']['name'] Image create failed with:\n" + f"Resp: {resp}\n" + f"Error Code: {resp.code}\n" + f"Error Message: {resp.message}") except Exception as ex: ERROR(traceback.format_exc())
def main(): # Get and log the config from the Env variable config = json.loads(os.environ["CUSTOM_SCRIPT_CONFIG"]) INFO(config) # Get PC info from the config dict pc_info = config.get("tdaas_pc") pc_external_ip = pc_info.get("ips")[0][0] pc_internal_ip = pc_info.get("ips")[0][1] pc_password = pc_info.get("prism_password") try: # Convert our spec to dict apps_spec = file_to_dict("specs/calm_bp_publish.json") # Get our non-default projects before the loop projects_payload = {"filter": "name!=default"} projects_resp = body_via_v3_post(pc_external_ip, "projects", pc_password, projects_payload) # Loop through our to-be-published apps for app in apps_spec["entities"]: # Construct payload and make call mp_payload = {"filter": f"name=={app['mp_name']}"} mp_post = body_via_v3_post(pc_external_ip, "calm_marketplace_items", pc_password, mp_payload) # Loop through our response to find matching version for mp_item in mp_post.json["entities"]: if (mp_item["status"]["app_state"] == "ACCEPTED" and mp_item["status"]["version"] == app["bp_version"] and mp_item["status"]["app_source"] == app["app_source"]): # Make a GET with our UUID mp_get = body_via_v3_get( pc_external_ip, "calm_marketplace_items", pc_password, mp_item["metadata"]["uuid"], ) # Modify the response body mp_body = mp_get.json del mp_body["status"] mp_body["spec"]["resources"]["app_state"] = "PUBLISHED" for project in projects_resp.json["entities"]: mp_body["spec"]["resources"][ "project_reference_list"].append( project["metadata"]["project_reference"]) # Publish the blueprint pub_resp = update_via_v3_put( pc_external_ip, "calm_marketplace_items", pc_password, mp_body["metadata"]["uuid"], mp_body, ) # Log appropriately based on response if pub_resp.code == 200 or pub_resp.code == 202: INFO( f"{mp_body['spec']['name']} MP item published successfully." ) else: raise Exception( f"{mp_body['spec']['name']} MP App Publish failed with:\n" + f"Resp: {resp}\n" + f"Error Code: {pub_resp.code}\n" + f"Error Message: {pub_resp.message}") except Exception as ex: ERROR(traceback.format_exc())
def main(): # Get and log the config from the Env variable config = json.loads(os.environ["CUSTOM_SCRIPT_CONFIG"]) INFO(config) # Get PC info from the config dict pc_info = config.get("tdaas_pc") pc_external_ip = pc_info.get("ips")[0][0] pc_internal_ip = pc_info.get("ips")[0][1] pc_password = pc_info.get("prism_password") try: # Read in the spec files and convert to dicts env_spec = file_to_dict("specs/calm_environment.json") image_spec = file_to_dict("specs/pc_image.json") subnet_spec = file_to_dict("specs/calm_subnet.json") secret_spec = file_to_dict("specs/calm_secrets.json") # Get our subnet info from the infra subnet_info = get_subnet_info(pc_external_ip, pc_password, subnet_spec["entities"][0]["vlan"]) INFO(f"subnet_uuid: {subnet_info['uuid']}") # Get our image info from the infra cent_image_name = image_spec["entities"][0]["metadata"]["name"] cent_image_uuid = uuid_via_v3_post(pc_external_ip, "images", pc_password, cent_image_name) INFO(f"cent_image_uuid: {cent_image_uuid}") # win_image_name = image_spec["entities"][1]["metadata"]["name"] # win_image_uuid = uuid_via_v3_post(pc_external_ip, "images", # pc_password, win_image_name) # INFO(f"win_image_uuid: {win_image_uuid}") # Generate UUIDs for new components env_name = str(uuid.uuid4()) env_uuid = str(uuid.uuid4()) cent_substrate_uuid = str(uuid.uuid4()) # win_substrate_uuid = str(uuid.uuid4()) cent_key_uuid = str(uuid.uuid4()) cent_pass_uuid = str(uuid.uuid4()) # win_pass_uuid = str(uuid.uuid4()) # Sub in our UUIDs and names: # env env_spec["spec"]["name"] = env_name env_spec["metadata"]["name"] = env_name env_spec["metadata"]["uuid"] = env_uuid # substrate env_spec["spec"]["resources"]["substrate_definition_list"][0][ "uuid"] = cent_substrate_uuid # env_spec["spec"]["resources"]["substrate_definition_list"][1]\ # ["uuid"] = win_substrate_uuid # account env_spec["spec"]["resources"]["substrate_definition_list"][0][ "readiness_probe"]["login_credential_local_reference"][ "uuid"] = cent_key_uuid # env_spec["spec"]["resources"]["substrate_definition_list"][1]\ # ["readiness_probe"]["login_credential_local_reference"]\ # ["uuid"] = win_pass_uuid # subnet env_spec["spec"]["resources"]["substrate_definition_list"][0][ "create_spec"]["resources"]["nic_list"][0]["subnet_reference"][ "uuid"] = subnet_info["uuid"] # env_spec["spec"]["resources"]["substrate_definition_list"][1]\ # ["create_spec"]["resources"]["nic_list"][0]\ # ["subnet_reference"]["uuid"] = subnet_info["uuid"] # image env_spec["spec"]["resources"]["substrate_definition_list"][0][ "create_spec"]["resources"]["disk_list"][0][ "data_source_reference"]["name"] = cent_image_name env_spec["spec"]["resources"]["substrate_definition_list"][0][ "create_spec"]["resources"]["disk_list"][0][ "data_source_reference"]["uuid"] = cent_image_uuid # env_spec["spec"]["resources"]["substrate_definition_list"][1]\ # ["create_spec"]["resources"]["disk_list"][0]\ # ["data_source_reference"]["name"] = win_image_name # env_spec["spec"]["resources"]["substrate_definition_list"][1]\ # ["create_spec"]["resources"]["disk_list"][0]\ # ["data_source_reference"]["uuid"] = win_image_uuid # secrets for secret in secret_spec["entities"]: if secret["name"] == "CENTOS_KEY": suuid = cent_key_uuid elif secret["name"] == "CENTOS_PASS": suuid = cent_pass_uuid else: continue env_spec["spec"]["resources"]["credential_definition_list"].append( { "name": secret["name"], "type": secret["type"], "username": secret["username"], "secret": { "attrs": { "is_secret_modified": True }, "value": secret["secret"], }, "uuid": suuid, }) # Make the API call to create the environment INFO(f"env_spec: {env_spec}") resp = create_via_v3_post(pc_external_ip, "environments", pc_password, env_spec) # Log appropriately based on response if resp.code == 200 or resp.code == 202: INFO(f"{env_spec['spec']['name']} Env created successfully.") else: raise Exception( f"{env_spec['spec']['name']} Env create failed with:\n" + f"Resp: {resp}\n" + f"Error Code: {resp.code}\n" + f"Error Message: {resp.message}") except Exception as ex: ERROR(traceback.format_exc())
def main(): # Get and log the config from the Env variable config = json.loads(os.environ["CUSTOM_SCRIPT_CONFIG"]) INFO(config) # Get PC info from the config dict pc_info = config.get("tdaas_pc") pc_external_ip = pc_info.get("ips")[0][0] pc_internal_ip = pc_info.get("ips")[0][1] pc_password = pc_info.get("prism_password") try: # Convert our spec to dict subnet_spec = file_to_dict("specs/calm_subnet.json") # Get our info from the infra subnet_info = get_subnet_info( pc_external_ip, pc_password, subnet_spec["entities"][0]["vlan"] ) if "proxy_vm" in config: public_subnet_info = get_subnet_info( pc_external_ip, pc_password, subnet_spec["entities"][1]["vlan"] ) account_info = body_via_v3_post(pc_external_ip, "accounts", pc_password, None) env_uuid = uuid_via_v3_post(pc_external_ip, "environments", pc_password, "") # Get the pojects body project_resp = body_via_v3_post(pc_external_ip, "projects", pc_password, None) # Loop through each project to add the env for project in project_resp.json["entities"]: # Delete the unneeded "status" del project["status"] # If default project, add subnet_ref_list if project["spec"]["name"] == "default": # add subnet if not present if len(project["spec"]["resources"]["subnet_reference_list"]) == 0: project["spec"]["resources"]["subnet_reference_list"].append( { "kind": "subnet", "name": subnet_info["name"], "uuid": subnet_info["uuid"], } ) if "proxy_vm" in config: project["spec"]["resources"]["subnet_reference_list"].append( { "kind": "subnet", "name": public_subnet_info["name"], "uuid": public_subnet_info["uuid"], } ) # Add account if not present if len(project["spec"]["resources"]["account_reference_list"]) == 0: for account in account_info.json["entities"]: if account["status"]["resources"]["type"] == "nutanix_pc": project["spec"]["resources"][ "account_reference_list" ].append( { "kind": "account", "name": account["metadata"]["name"], "uuid": account["metadata"]["uuid"], } ) # Add env if not present if len(project["spec"]["resources"]["environment_reference_list"]) == 0: project["spec"]["resources"]["environment_reference_list"].append( {"kind": "environment", "uuid": env_uuid} ) # Make the API call to update the Project INFO(f"project: {project}") resp = update_via_v3_put( pc_external_ip, "projects", pc_password, project["metadata"]["uuid"], project, ) # Log appropriately based on response if resp.code == 202 or resp.code == 200: INFO(f"{project['spec']['name']} Project updated successfully.") else: raise Exception( f"{project['spec']['name']} Project update failed with:\n" + f"Resp: {resp}\n" + f"Error Code: {resp.code}\n" + f"Error Message: {resp.message}" ) except Exception as ex: ERROR(traceback.format_exc())
def main(): # Get and log the config from the Env variable config = json.loads(os.environ["CUSTOM_SCRIPT_CONFIG"]) INFO(config) # Get PC info from the config dict pc_info = config.get("tdaas_pc") pc_external_ip = pc_info.get("ips")[0][0] pc_internal_ip = pc_info.get("ips")[0][1] pc_password = pc_info.get("prism_password") try: # Read in the spec files and conver to dicts publish_spec = file_to_dict("specs/calm_bp_publish.json") INFO(f"publish_spec: {publish_spec}") # Get user and icon info user_info = body_via_v3_get(pc_external_ip, "users", pc_password, "me").json icon_info = body_via_v3_post(pc_external_ip, "app_icons", pc_password, None).json # Loop through the blueprints to upload for publish in publish_spec["entities"]: # Create our payload and get bp uuid payload = {"filter": f"name=={publish['bp_name']}"} bp_info = body_via_v3_post(pc_external_ip, "blueprints", pc_password, payload).json bp_uuid = bp_info["entities"][0]["metadata"]["uuid"] # Get bp spec with uuid bp = body_via_v3_get( pc_external_ip, "blueprints", pc_password, f"{bp_uuid}/export_json?keep_secrets=true", ).json # Modify our body bp["spec"]["name"] = publish["mp_name"] bp["spec"]["description"] = publish["mp_description"] bp["status"]["name"] = publish["mp_name"] bp["status"]["description"] = publish["mp_description"] spec = copy.deepcopy(bp["spec"]) status = copy.deepcopy(bp["status"]) del bp["spec"]["resources"] del bp["status"] bp["metadata"]["kind"] = "marketplace_item" bp["spec"]["resources"] = {"app_attribute_list": ["FEATURED"]} bp["spec"]["resources"]["app_state"] = "PENDING" bp["spec"]["resources"]["project_reference_list"] = [] bp["spec"]["resources"]["change_log"] = "" bp["spec"]["resources"]["app_source"] = "LOCAL" bp["spec"]["resources"]["app_group_uuid"] = str(uuid.uuid4()) bp["spec"]["resources"]["author"] = user_info["status"]["name"] for icon in icon_info["entities"]: if icon["status"]["name"] == publish["icon_name"]: bp["spec"]["resources"]["icon_reference_list"] = [{ "icon_reference": { "kind": "file_item", "uuid": icon["metadata"]["uuid"], }, "icon_type": "ICON", }] bp["spec"]["resources"]["version"] = publish["bp_version"] bp["spec"]["resources"]["app_blueprint_template"] = {"spec": spec} bp["spec"]["resources"]["app_blueprint_template"][ "status"] = status # Upload our marketplace item resp = create_via_v3_post(pc_external_ip, "calm_marketplace_items", pc_password, bp) # Log appropriately based on response if resp.code == 200 or resp.code == 202: INFO(f"{publish['mp_name']} bp published successfully.") else: raise Exception( f"{publish['mp_name']} bp publish failed with:\n" + f"Resp: {resp}\n" + f"Error Code: {resp.code}\n" + f"Error Message: {resp.message}") except Exception as ex: ERROR(traceback.format_exc())
def main(launch): # Get and log the config from the Env variable config = json.loads(os.environ["CUSTOM_SCRIPT_CONFIG"]) INFO(config) # Get PC info from the config dict pc_info = config.get("tdaas_pc") pc_external_ip = pc_info.get("ips")[0][0] pc_internal_ip = pc_info.get("ips")[0][1] pc_password = pc_info.get("prism_password") try: # Read in the spec files and convert to dicts launch_spec = file_to_dict(f"specs/{launch}") INFO(f"launch_spec: {launch_spec}") # Loop through the blueprints to launch for launch in launch_spec["entities"]: # Get our blueprint uuid payload = {"filter": f"name=={launch['bp_name']}"} bp = body_via_v3_post( pc_external_ip, "blueprints", pc_password, payload ).json if bp["metadata"]["total_matches"] != 1: raise Exception( str(bp["metadata"]["total_matches"]) + " blueprints found, when 1 should" + " have been found." ) else: bp_uuid = bp["entities"][0]["metadata"]["uuid"] # Get our runtime editables editables = body_via_v3_get( pc_external_ip, "blueprints", pc_password, bp_uuid + "/runtime_editables", ).json for profile in editables["resources"]: if profile["app_profile_reference"]["name"] == launch["profile_name"]: profile_ref = profile["app_profile_reference"] run_editables = profile["runtime_editables"] INFO(f"{launch['bp_name']} profile_ref: {profile_ref}") INFO(f"{launch['bp_name']} run_editables: {run_editables}") # Determine if this blueprint has an app dependency if "dependencies" in launch and len(launch["dependencies"]) > 0: # Get a list of running apps apps = body_via_v3_post(pc_external_ip, "apps", pc_password, None).json # Cycle through the apps for app in apps["entities"]: # Cycle through our launch dependencies for depend in launch["dependencies"]: # Find the matching app name if app["status"]["name"] == depend["app_name"]: # Get app body app_body = body_via_v3_get( pc_external_ip, "apps", pc_password, app["metadata"]["uuid"], ).json # Loop through our dependency values for value in depend["values"]: # Get value from our body+key combo app_val = recursive_dict_lookup(app_body, value["keys"]) # Set our app_val to the appropriate variable value for launch_var in launch["variables"]: if value["name"] == launch_var["name"]: launch_var["value"] = app_val INFO(f'{launch["bp_name"]} vars after depend: {launch["variables"]}') # Set our runtime variables if "variable_list" in run_editables: for run_edit_var in run_editables["variable_list"]: for launch_var in launch["variables"]: if run_edit_var["name"] == launch_var["name"]: run_edit_var["value"]["value"] = launch_var["value"] INFO(f"{launch['bp_name']} run_editables: {run_editables}") # Create our payload and launch our app payload = { "spec": { "app_name": launch["app_name"], "app_description": launch["app_description"], "app_profile_reference": profile_ref, "runtime_editables": run_editables, } } resp = create_via_v3_post( pc_external_ip, "blueprints/" + bp_uuid + "/simple_launch", pc_password, payload, ) # Log appropriately based on response if resp.code == 200 or resp.code == 202: INFO(f"{launch['app_name']} app launched successfully.") else: raise Exception( f"{launch['app_name']} app launch failed with:\n" + f"Resp: {resp}\n" + f"Error Code: {resp.code}\n" + f"Error Message: {resp.message}" ) time.sleep(2) except Exception as ex: ERROR(traceback.format_exc())
def main(): # Get and log the config from the Env variable config = json.loads(os.environ["CUSTOM_SCRIPT_CONFIG"]) INFO(config) # Get PC info from the config dict pc_info = config.get("tdaas_pc") pc_external_ip = pc_info.get("ips")[0][0] pc_internal_ip = pc_info.get("ips")[0][1] pc_password = pc_info.get("prism_password") # Get PE info from the config dict pe_info = config.get("tdaas_cluster") pe_external_ip = pe_info.get("ips")[0][0] pe_internal_ip = pe_info.get("ips")[0][1] pe_password = pe_info.get("prism_password") try: # Read in the spec files and conver to dicts subnet_spec = file_to_dict("specs/calm_subnet.json") INFO(f"subnet_spec: {subnet_spec}") secret_spec = file_to_dict("specs/calm_secrets.json") INFO(f"secret_spec: {secret_spec}") # Get our subnet and image info from the infra subnet_info = get_subnet_info(pc_external_ip, pc_password, subnet_spec["entities"][0]["vlan"]) infra_subnet_info = get_subnet_info(pc_external_ip, pc_password, subnet_spec["entities"][1]["vlan"]) image_info = body_via_v3_post(pc_external_ip, "images", pc_password, None).json # If we have Public UVMs / Proxy IPs, then get our array proxy_array = [] if "proxy_vm" in config: proxy_array = create_proxy_array(config["proxy_vm"]) # Get a list of DRAFT blueprints payload = {"filter": "state==DRAFT"} draft_resp = body_via_v3_post(pc_external_ip, "blueprints", pc_password, payload).json # Loop through the blueprints to modify for bp in draft_resp["entities"]: # Get the body of our blueprint bp_body = body_via_v3_get(pc_external_ip, "blueprints", pc_password, bp["metadata"]["uuid"]).json # Remove unneeded status del bp_body["status"] # Configure secrets for secret in bp_body["spec"]["resources"][ "credential_definition_list"]: secret["secret"]["attrs"]["is_secret_modified"] = True # Handle PE and PC Creds which are unique if secret["name"].lower() == "pc_creds": secret["secret"]["username"] = "******" secret["secret"]["value"] = pc_password elif secret["name"].lower() == "pe_creds": secret["secret"]["username"] = "******" secret["secret"]["value"] = pe_password # Find a matching type/username from our secret_spec else: for ss in secret_spec["entities"]: if (secret["type"] == ss["type"] and secret["username"] == ss["username"]): secret["secret"]["value"] = ss["secret"] INFO(f"secret: {secret}") # Configure NICs and Images for substrate in bp_body["spec"]["resources"][ "substrate_definition_list"]: if substrate["type"] == "AHV_VM": # For NICs, determine if it's an infra or user VM based blueprint for nic in substrate["create_spec"]["resources"][ "nic_list"]: if "infra" in bp_body["metadata"]["name"].lower(): # Ensure we have a proxy_vm config if len(proxy_array) > 0: nic["subnet_reference"][ "uuid"] = infra_subnet_info["uuid"] nic["subnet_reference"][ "name"] = infra_subnet_info["name"] proxy_ips = proxy_array.pop() nic["ip_endpoint_list"][0]["ip"] = proxy_ips[1] else: ERROR( f'Blueprint "{bp_body["metadata"]["name"]}" has ' + f'"infra" in the name, but there were not enough ' + f" proxy IPs configured: {config}. If" + f" this application needs external access, " + f"please ensure enough proxy IPs are in your GCP " + f'cluster. Otherwise, remove "infra" from the ' + f"blueprint name.") else: nic["subnet_reference"]["uuid"] = subnet_info[ "uuid"] nic["subnet_reference"]["name"] = subnet_info[ "name"] print(json.dumps(nic, sort_keys=True, indent=4)) for disk in substrate["create_spec"]["resources"][ "disk_list"]: if (disk["data_source_reference"] is not None and disk["data_source_reference"]["kind"] == "image"): for image in image_info["entities"]: if (image["status"]["name"] == disk["data_source_reference"]["name"]): disk["data_source_reference"][ "uuid"] = image["metadata"]["uuid"] print( json.dumps(disk, sort_keys=True, indent=4)) # Update our blueprint resp = update_via_v3_put( pc_external_ip, "blueprints", pc_password, bp["metadata"]["uuid"], bp_body, ) # Log appropriately based on response if resp.code == 200 or resp.code == 202: INFO( f"{bp['metadata']['name']} blueprint updated successfully." ) else: raise Exception( f"{bp['metadata']['name']} blueprint update failed with:\n" + f"Resp: {resp}\n" + f"Error Code: {resp.code}\n" + f"Error Message: {resp.message}") except Exception as ex: ERROR(traceback.format_exc())
def main(project_name): # Get and log the config from the Env variable config = json.loads(os.environ["CUSTOM_SCRIPT_CONFIG"]) INFO(config) # Get PC info from the config dict pc_info = config.get("tdaas_pc") pc_external_ip = pc_info.get("ips")[0][0] pc_internal_ip = pc_info.get("ips")[0][1] pc_password = pc_info.get("prism_password") try: # Read in the spec files and conver to dicts project_spec = file_to_dict("specs/calm_project.json") INFO(f"project_spec pre-update: {project_spec}") subnet_spec = file_to_dict("specs/calm_subnet.json") INFO(f"subnet_spec pre-update: {subnet_spec}") # Get our info from the infra subnet_info = get_subnet_info( pc_external_ip, pc_password, subnet_spec["entities"][0]["vlan"] ) account_info = body_via_v3_post(pc_external_ip, "accounts", pc_password, None) # Cycle through our accounts to find the right one for account in account_info.json["entities"]: if account["status"]["resources"]["type"] == "nutanix_pc": # Update our project_spec project_spec["spec"]["name"] = project_name project_spec["spec"]["resources"]["subnet_reference_list"][0][ "name" ] = subnet_info["name"] project_spec["spec"]["resources"]["subnet_reference_list"][0][ "uuid" ] = subnet_info["uuid"] project_spec["spec"]["resources"]["account_reference_list"][0][ "name" ] = account["metadata"]["name"] project_spec["spec"]["resources"]["account_reference_list"][0][ "uuid" ] = account["metadata"]["uuid"] INFO(f"project_spec post-update: {project_spec}") # Make API call to create project resp = create_via_v3_post( pc_external_ip, "projects", pc_password, project_spec ) # Log appropriately based on response if resp.code == 200 or resp.code == 202: INFO( f"{project_spec['spec']['name']} Project created successfully." ) else: raise Exception( f"{project_spec['spec']['name']} Project create failed with:\n" + f"Resp: {resp}\n" + f"Error Code: {resp.code}\n" + f"Error Message: {resp.message}" ) except Exception as ex: ERROR(traceback.format_exc())