def main(artifact_dir: str, lt_http_proto: str, lt_url: str, lt_api_endpoint: str, lt_api_version: int, lt_token: str, source_env: str, dest_env: str, apps: list, dep_manifest: list, dep_note: str, osp_tool_path: str, credentials: str, cicd_http_proto: str, cicd_url: str, cicd_api_endpoint: str, cicd_version: str): app_data_list = [ ] # will contain the applications to deploy details from LT if lt_api_version == 1: # LT for OS version < 11 raise InvalidParametersError( "Air Gap deployments are not supported for Deployment API v1") # Builds the LifeTime endpoint lt_endpoint = build_lt_endpoint(lt_http_proto, lt_url, lt_api_endpoint, lt_api_version) # Builds the Probe endpoint probe_endpoint = build_probe_endpoint(cicd_http_proto, cicd_url, cicd_api_endpoint, cicd_version) # Gets the environment key for the source environment src_env_key = get_environment_key(artifact_dir, lt_endpoint, lt_token, source_env) # If the manifest file is being used, the app versions MUST come from that file # Or else you might not be deploying the same app versions that were deployed in # previous pipeline steps if dep_manifest: app_data_list = generate_deployment_based_on_manifest( artifact_dir, lt_endpoint, lt_token, src_env_key, source_env, apps, dep_manifest) else: app_data_list = generate_regular_deployment(artifact_dir, lt_endpoint, lt_token, src_env_key, apps) # Export binary files app_oap_list = generate_oap_list(app_data_list) export_apps_oap(artifact_dir, lt_endpoint, lt_token, src_env_key, app_oap_list) # Generate deployment order sorted_oap_list = generate_deployment_order(artifact_dir, probe_endpoint, app_oap_list) print("\nDeployment Order:\n", flush=True) for oap in sorted_oap_list: print(" " + str(sorted_oap_list.index(oap) + 1) + ". " + oap["app_name"] + " (" + oap["version_key"] + ")\n", flush=True) # Deploy binary files to target environment deploy_apps_oap(artifact_dir, dest_env, osp_tool_path, credentials, sorted_oap_list)
def _create_deployment_plan(artifact_dir: str, endpoint: str, lt_api_version: int, auth_token: str, app_keys: str, dep_note: str, source_env: str, dest_env: str): if lt_api_version == 1: api_var_name = DEPLOYMENT_PLAN_V1_API_OPS elif lt_api_version == 2: api_var_name = DEPLOYMENT_PLAN_V2_API_OPS else: raise NotImplementedError( "Unsupported API version for LifeTime: used {}".format( lt_api_version)) source_env_key = get_environment_key(artifact_dir, endpoint, auth_token, source_env) dest_env_key = get_environment_key(artifact_dir, endpoint, auth_token, dest_env) deployment_request = { api_var_name: app_keys, "Notes": dep_note, "SourceEnvironmentKey": source_env_key, "TargetEnvironmentKey": dest_env_key } return json.dumps(deployment_request)
def main(artifact_dir: str, lt_http_proto: str, lt_url: str, lt_api_endpoint: str, lt_api_version: int, lt_token: str, dest_env: str, app_list: list, dep_manifest: list): # Builds the LifeTime endpoint lt_endpoint = build_lt_endpoint(lt_http_proto, lt_url, lt_api_endpoint, lt_api_version) # Get the environment keys dest_env_key = get_environment_key(artifact_dir, lt_endpoint, lt_token, dest_env) for deployed_app in dep_manifest: if deployed_app["ApplicationName"] in app_list: set_application_version(lt_endpoint, lt_token, dest_env_key, deployed_app["ApplicationKey"], deployed_app["ChangeLog"], deployed_app["Version"]) print("{} application successuflly tagged as {} on {}".format( deployed_app["ApplicationName"], deployed_app["Version"], dest_env), flush=True)
def main(artifact_dir: str, lt_http_proto: str, lt_url: str, lt_api_endpoint: str, lt_api_version: int, lt_token: str, source_env: str, dest_env: str, apps: list, dep_note: str): # use the script variables global app_data_list, app_keys, to_deploy_app_keys # Builds the LifeTime endpoint lt_endpoint = build_lt_endpoint(lt_http_proto, lt_url, lt_api_endpoint, lt_api_version) # Gets the environment key for the source environment src_env_key = get_environment_key(artifact_dir, lt_endpoint, lt_token, source_env) # Gets the environment key for the destination environment dest_env_key = get_environment_key(artifact_dir, lt_endpoint, lt_token, dest_env) # Creates a list with the details for the apps you want to deploy for app_name in apps: # Removes whitespaces in the beginning and end of the string app_name = app_name.strip() # Get the app running version on the source environment. It will only retrieve tagged applications deployed = get_running_app_version(artifact_dir, lt_endpoint, lt_token, src_env_key, app_name=app_name) # Grab the App key app_key = deployed["ApplicationKey"] # Grab the Version ID from the latest version of the app app_version = deployed["Version"] # Grab the Version Key from the latest version of the app app_version_key = deployed["VersionKey"] if lt_api_version == 1: # LT for OS version < 11 app_keys.append(app_version_key) elif lt_api_version == 2: # LT for OS v11 app_keys.append({ "ApplicationVersionKey": app_version_key, "DeploymentZoneKey": "" }) else: raise NotImplementedError( "Please make sure the API version is compatible with the module." ) # Add it to the app data listapp_version app_data_list.append({ 'Name': app_name, 'Key': app_key, 'Version': app_version, 'VersionKey': app_version_key }) # Check if target environment already has the application versions to be deployed for app in app_data_list: # get the status of the app in the target env, to check if they were deployed try: app_status = get_environment_app_version(artifact_dir, lt_endpoint, lt_token, True, env_name=dest_env, app_key=app["Key"]) # Check if the app version is already deployed in the target environment if app_status["AppStatusInEnvs"][0][ "BaseApplicationVersionKey"] != app["VersionKey"]: # If it's not, save the key of the tagged app, to deploy later to_deploy_app_keys.append(app["VersionKey"]) print( "App {} with version {} does not exist in {} environment. Ignoring check and deploy it." .format(app["Name"], app["Version"], dest_env)) else: print( "Skipping app {} with version {}, since it's already deployed in {} environment." .format(app["Name"], app["Version"], dest_env)) except AppDoesNotExistError: to_deploy_app_keys.append(app["VersionKey"]) print( "App {} with version {} does not exist in {} environment. Ignoring check and deploy it." .format(app["Name"], app["Version"], dest_env)) # Check if there are apps to be deployed if len(to_deploy_app_keys) == 0: print( "Deployment skipped because {} environment already has the target application deployed with the same tags." .format(dest_env)) sys.exit(0) # Write the names and keys of the application versions to be deployed print( "Creating deployment plan from {} to {} including applications: {} ({})." .format(source_env, dest_env, apps, app_data_list)) wait_counter = 0 deployments = get_running_deployment(artifact_dir, lt_endpoint, lt_token, dest_env_key) while len(deployments) > 0: if wait_counter >= QUEUE_TIMEOUT_IN_SECS: print( "Timeout occurred while waiting for LT to be free, to create the new deployment plan." ) sys.exit(1) sleep(SLEEP_PERIOD_IN_SECS) wait_counter += SLEEP_PERIOD_IN_SECS deployments = get_running_deployment(artifact_dir, lt_endpoint, lt_token, dest_env_key) # LT is free to deploy # Send the deployment plan and grab the key dep_plan_key = send_deployment(artifact_dir, lt_endpoint, lt_token, lt_api_version, app_keys, dep_note, source_env, dest_env) print("Deployment plan {} created successfully.".format(dep_plan_key)) # Check if created deployment plan has conflicts dep_details = get_deployment_info(artifact_dir, lt_endpoint, lt_token, dep_plan_key) if len(dep_details["ApplicationConflicts"]) > 0: store_data(artifact_dir, CONFLICTS_FILE, dep_details["ApplicationConflicts"]) print( "Deployment plan {} has conflicts and will be aborted. Check {} artifact for more details." .format(dep_plan_key, CONFLICTS_FILE)) # Abort previously created deployment plan to target environment delete_deployment(lt_endpoint, lt_token, dep_plan_key) print("Deployment plan {} was deleted successfully.".format( dep_plan_key)) sys.exit(1) # The plan has no conflits. Save it to the artifacts storage filename = "{}{}".format(dep_plan_key, DEPLOYMENT_PLAN_FILE) store_data(artifact_dir, filename, dep_details) # Check if outdated consumer applications (outside of deployment plan) should be redeployed and start the deployment plan execution if lt_api_version == 1: # LT for OS version < 11 start_deployment(lt_endpoint, lt_token, dep_plan_key) elif lt_api_version == 2: # LT for OS v11 start_deployment(lt_endpoint, lt_token, dep_plan_key, redeploy_outdated=REDEPLOY_OUTDATED_APPS) else: raise NotImplementedError( "Please make sure the API version is compatible with the module.") print("Deployment plan {} started being executed.".format(dep_plan_key)) # Sleep thread until deployment has finished wait_counter = 0 while wait_counter < DEPLOYMENT_TIMEOUT_IN_SECS: # Check Deployment Plan status. dep_status = get_deployment_status(artifact_dir, lt_endpoint, lt_token, dep_plan_key) if dep_status["DeploymentStatus"] != DEPLOYMENT_RUNNING_STATUS: # Check deployment status is pending approval. Force it to continue (if 2-Step deployment is enabled) if dep_status["DeploymentStatus"] == DEPLOYMENT_WAITING_STATUS: continue_deployment(lt_endpoint, lt_token, dep_plan_key) print("Deployment plan {} resumed execution.".format( dep_plan_key)) elif dep_status[ "DeploymentStatus"] in DEPLOYMENT_ERROR_STATUS_LIST: print("Deployment plan finished with status {}.".format( dep_status["DeploymentStatus"])) store_data(artifact_dir, DEPLOY_ERROR_FILE, dep_status) sys.exit(1) else: # If it reaches here, it means the deployment was successful print("Deployment plan finished with status {}.".format( dep_status["DeploymentStatus"])) # Exit the script to continue with the pipeline sys.exit(0) # Deployment status is still running. Go back to sleep. sleep(SLEEP_PERIOD_IN_SECS) wait_counter += SLEEP_PERIOD_IN_SECS print("{} secs have passed since the deployment started...".format( wait_counter)) # Deployment timeout reached. Exit script with error print( "Timeout occurred while deployment plan is still in {} status.".format( DEPLOYMENT_RUNNING_STATUS)) sys.exit(1)
def main(artifact_dir: str, lt_http_proto: str, lt_url: str, lt_api_endpoint: str, lt_api_version: int, lt_token: str, source_env: str, dest_env: str, apps: list, dep_manifest: list, dep_note: str): app_data_list = [ ] # will contain the applications to deploy details from LT to_deploy_app_keys = [] # will contain the app keys for the apps tagged # Builds the LifeTime endpoint lt_endpoint = build_lt_endpoint(lt_http_proto, lt_url, lt_api_endpoint, lt_api_version) # Gets the environment key for the source environment src_env_key = get_environment_key(artifact_dir, lt_endpoint, lt_token, source_env) # Gets the environment key for the destination environment dest_env_key = get_environment_key(artifact_dir, lt_endpoint, lt_token, dest_env) # If the manifest file is being used, the app versions MUST come from that file # Or else you might not be deploying the same app versions that were deployed in # previous pipeline steps if dep_manifest: app_data_list = generate_deployment_based_on_manifest( artifact_dir, lt_endpoint, lt_token, src_env_key, source_env, apps, dep_manifest) else: app_data_list = generate_regular_deployment(artifact_dir, lt_endpoint, lt_token, src_env_key, apps) to_deploy_app_keys = check_if_can_deploy(artifact_dir, lt_endpoint, lt_api_version, lt_token, dest_env_key, dest_env, app_data_list) # Check if there are apps to be deployed if len(to_deploy_app_keys) == 0: print( "Deployment skipped because {} environment already has the target application deployed with the same tags." .format(dest_env), flush=True) sys.exit(0) # Write the names and keys of the application versions to be deployed to_deploy_app_names = [] to_deploy_app_info = [] for app in app_data_list: for deploying_apps in to_deploy_app_keys: if lt_api_version == 1: # LT for OS version < 11 if deploying_apps == app["VersionKey"]: to_deploy_app_names.append(app["Name"]) to_deploy_app_info.append(app) elif lt_api_version == 2: # LT for OS v11 if deploying_apps["ApplicationVersionKey"] == app[ "VersionKey"]: to_deploy_app_names.append(app["Name"]) to_deploy_app_info.append(app) else: raise NotImplementedError( "Please make sure the API version is compatible with the module." ) print( "Creating deployment plan from {} to {} including applications: {} ({})." .format(source_env, dest_env, to_deploy_app_names, to_deploy_app_info), flush=True) wait_counter = 0 deployments = get_running_deployment(artifact_dir, lt_endpoint, lt_token, dest_env_key) while len(deployments) > 0: if wait_counter >= QUEUE_TIMEOUT_IN_SECS: print( "Timeout occurred while waiting for LifeTime to be free, to create the new deployment plan.", flush=True) sys.exit(1) sleep(SLEEP_PERIOD_IN_SECS) wait_counter += SLEEP_PERIOD_IN_SECS print("Waiting for LifeTime to be free. Elapsed time: {} seconds...". format(wait_counter), flush=True) deployments = get_running_deployment(artifact_dir, lt_endpoint, lt_token, dest_env_key) # LT is free to deploy # Send the deployment plan and grab the key dep_plan_key = send_deployment(artifact_dir, lt_endpoint, lt_token, lt_api_version, to_deploy_app_keys, dep_note, source_env, dest_env) print("Deployment plan {} created successfully.".format(dep_plan_key), flush=True) # Check if created deployment plan has conflicts dep_details = get_deployment_info(artifact_dir, lt_endpoint, lt_token, dep_plan_key) if len(dep_details["ApplicationConflicts"]) > 0: store_data(artifact_dir, CONFLICTS_FILE, dep_details["ApplicationConflicts"]) print( "Deployment plan {} has conflicts and will be aborted. Check {} artifact for more details." .format(dep_plan_key, CONFLICTS_FILE), flush=True) # Abort previously created deployment plan to target environment delete_deployment(lt_endpoint, lt_token, dep_plan_key) print("Deployment plan {} was deleted successfully.".format( dep_plan_key), flush=True) sys.exit(1) # Check if outdated consumer applications (outside of deployment plan) should be redeployed and start the deployment plan execution if lt_api_version == 1: # LT for OS version < 11 start_deployment(lt_endpoint, lt_token, dep_plan_key) elif lt_api_version == 2: # LT for OS v11 start_deployment(lt_endpoint, lt_token, dep_plan_key, redeploy_outdated=REDEPLOY_OUTDATED_APPS) else: raise NotImplementedError( "Please make sure the API version is compatible with the module.") print("Deployment plan {} started being executed.".format(dep_plan_key), flush=True) # Sleep thread until deployment has finished wait_counter = 0 while wait_counter < DEPLOYMENT_TIMEOUT_IN_SECS: # Check Deployment Plan status. dep_status = get_deployment_status(artifact_dir, lt_endpoint, lt_token, dep_plan_key) if dep_status["DeploymentStatus"] != DEPLOYMENT_RUNNING_STATUS: # Check deployment status is pending approval. Force it to continue (if 2-Step deployment is enabled) if dep_status["DeploymentStatus"] == DEPLOYMENT_WAITING_STATUS: continue_deployment(lt_endpoint, lt_token, dep_plan_key) print("Deployment plan {} resumed execution.".format( dep_plan_key), flush=True) elif dep_status[ "DeploymentStatus"] in DEPLOYMENT_ERROR_STATUS_LIST: print("Deployment plan finished with status {}.".format( dep_status["DeploymentStatus"]), flush=True) store_data(artifact_dir, DEPLOY_ERROR_FILE, dep_status) sys.exit(1) else: # If it reaches here, it means the deployment was successful print("Deployment plan finished with status {}.".format( dep_status["DeploymentStatus"]), flush=True) # Exit the script to continue with the pipeline sys.exit(0) # Deployment status is still running. Go back to sleep. sleep(SLEEP_PERIOD_IN_SECS) wait_counter += SLEEP_PERIOD_IN_SECS print("{} secs have passed since the deployment started...".format( wait_counter), flush=True) # Deployment timeout reached. Exit script with error print( "Timeout occurred while deployment plan is still in {} status.".format( DEPLOYMENT_RUNNING_STATUS), flush=True) sys.exit(1)