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)
Example #5
0
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)