Ejemplo n.º 1
0
def verify_issue_status(jira, current_environment):
    if current_environment.status:
        issues_to_verify = []
        # If they have a single issue listed, add it to be verified
        if current_environment.issue:
            issue = retrieve_jira_issue(jira, current_environment.issue)
            issues_to_verify.append(issue)
        # If they have a jql query specified, retrieve the list of issues to be verified
        if current_environment.jql_query:
            issues_to_verify.extend(jql_query(jira, current_environment))

        print("\nVerify issue transition status")
        print("Desired Status: " + str(current_environment.status))
        for current_issue in issues_to_verify:
            if str(current_issue.fields.status) == current_environment.status:
                print(str(current_issue) + ": " + str(current_issue.fields.status))
            else:
                StepUtility.printFail("Exiting Step - Jira Issue "
                    + str(current_issue)
                    + "\n Current Status: "
                    + str(current_issue.fields.status)
                    + "\n Desired status: "
                    + str(current_environment.status))
                sys.exit(1)
        print("Successfully verified status")
    else:
        StepUtility.printFail("Exiting Step - Please specify a valid status name")
        sys.exit(1)
Ejemplo n.º 2
0
def retrieve_jira_issue(jira, current_issue):
    try:
        issue = jira.issue(current_issue)
        return issue
    except Exception as exc:
        StepUtility.printCleanException(exc)
        StepUtility.printFail("Exiting Step - Failed to retrieve issue")
        sys.exit(1)
Ejemplo n.º 3
0
def update_comment(jira, current_environment):
    print("\nUpdate comment")
    try:
        comment = jira.comment(current_environment.issue, current_environment.existing_comment_id)
        comment.update(body = current_environment.comment_body)
    except Exception as exc:
        StepUtility.printCleanException(exc)
        StepUtility.printFail("Exiting Step - Failed to update comment")
        sys.exit(1)
Ejemplo n.º 4
0
def vault_authentication(current_environment):
    # Authenticate the client - exit program if authentication fails
    print("\nAuthentication")
    client = hvac.Client(url=current_environment.vault_addr)

    # Check for client certs and apply them
    if current_environment.vault_client_cert_base64 != "" and current_environment.vault_client_key_base64 != "":
        try:
            client_certs = (base64.b64decode(
                current_environment.vault_client_cert_base64),
                            base64.b64decode(
                                current_environment.vault_client_key_base64))
            client = hvac.Client(url=current_environment.vault_addr,
                                 cert=client_certs)
        except Exception as exc:
            StepUtility.printCleanException(exc)
            StepUtility.printFail(
                "Exiting Step - Failed to authenticate with certificates to Vault instance"
            )
            sys.exit(1)

    if current_environment.vault_auth_method.upper() == "TOKEN":
        print("Mode: TOKEN")
        client.token = current_environment.vault_token
    elif current_environment.vault_auth_method.upper() == "APPROLE":
        print("Mode: APPROLE")
        try:
            client.auth_approle(current_environment.approle_role_id,
                                current_environment.approle_secret_id)
        except Exception as exc:
            StepUtility.printCleanException(exc)
            StepUtility.printFail(
                "Exiting Step - Failed to authenticate with Approle to Vault instance"
            )
            sys.exit(1)
    else:
        print("Authentication Mode not passed, defaulting to Token auth")
        client.token = current_environment.vault_token

    # Verify that we connected successfully to Vault, otherwise exit the step
    if not client.is_authenticated():
        StepUtility.printFail(
            "Exiting Step - Failed to authenticate with Vault instance")
        sys.exit(1)
    else:
        print("Successfully authenticated with Vault instance")
    return client
Ejemplo n.º 5
0
def perform_jira_update(jira, current_environment, issue):
    print("Updating issue: " + str(issue))
    update_issue_dict = {}
    if current_environment.issue_summary:
        update_issue_dict.update(summary = current_environment.issue_summary)
    if current_environment.issue_description:
        update_issue_dict.update(description = current_environment.issue_description)
    if current_environment.issue_type:
        update_issue_dict.update(issuetype = ast.literal_eval(current_environment.issue_type))
    if current_environment.issue_components:
        update_issue_dict.update(components = current_environment.issue_components)
    try:
        issue.update(update_issue_dict)
    except Exception as exc:
        StepUtility.printCleanException(exc)
        StepUtility.printFail("Exiting Step - Failed to update issue: " + str(issue))
        sys.exit(1)
Ejemplo n.º 6
0
def step_action(action, authenticated_jira, current_environment):
    print("Step Action: " + action)
    actions = {
        'issue_create': create_issue,
        'issue_update': update_issue,
        'issue_transition': transition_issue,
        'issue_transition_and_update': transition_issue,
        'comment_create': create_comment,
        'comment_update': update_comment,
        'verify_status': verify_issue_status,
        'update_all_from_jql_query': update_multiple_issues,
    }
    action_func = actions.get(action, action_required)
    if action_func:
        action_func(authenticated_jira, current_environment)
    else:
        StepUtility.printFail("Exiting Step - invalid ACTION environment variable")
        sys.exit(1)
Ejemplo n.º 7
0
def create_issue(jira, current_environment):
    print("\nCreate issue")

    new_issue_dict = {}
    new_issue_dict.update(
        project=ast.literal_eval(current_environment.issue_project))
    new_issue_dict.update(summary=current_environment.issue_summary)
    new_issue_dict.update(description=current_environment.issue_description)
    new_issue_dict.update(
        issuetype=ast.literal_eval(current_environment.issue_type))
    new_issue_dict.update(components=current_environment.issue_components)

    try:
        created_issue = jira.create_issue(new_issue_dict)
        print("Jira issue " + str(created_issue) + " created")
    except Exception as exc:
        StepUtility.printCleanException(exc)
        StepUtility.printFail("Exiting Step - Failed to create issue")
        sys.exit(1)
Ejemplo n.º 8
0
def create_comment(jira, current_environment):
    print("\nCreate comment")
    try:
        comment_id = jira.add_comment(current_environment.issue, current_environment.comment_body)
        print("Comment id: " + str(comment_id))
        StepUtility.export_variable("JIRA_COMMENT_ID", comment_id)
    except Exception as exc:
        StepUtility.printCleanException(exc)
        StepUtility.printFail("Exiting Step - Failed to insert a comment")
        sys.exit(1)
Ejemplo n.º 9
0
def create_issue(jira, current_environment):
    print("\nCreate issue")

    new_issue_dict = {}
    new_issue_dict.update(project = ast.literal_eval(current_environment.issue_project))
    new_issue_dict.update(summary = current_environment.issue_summary)
    new_issue_dict.update(description = current_environment.issue_description)
    new_issue_dict.update(issuetype = ast.literal_eval(current_environment.issue_type))
    if (current_environment.issue_components):
        new_issue_dict.update(components = current_environment.issue_components)

    # print(current_environment.issue_customfields)
    # sys.exit(1)

    if current_environment.issue_customfields:

        url = '{}/rest/api/3/field'.format(current_environment.jira_base_url)

        response = requests.request('GET', url, auth=HTTPBasicAuth(current_environment.jira_username, current_environment.jira_api_key))

        data = response.json()

        customfields = current_environment.issue_customfields.lstrip('[').rstrip(']')

        kv_pairs = re.findall(r'(\w+.*?)\s*=\s*(.*?)(?=(?:\s[^\s=]+|$))', customfields)

        for k, v in kv_pairs:

            if 'customfield' not in k:
                for item in data:
                    if k in item['name']:
                        customfield_id = item['id']
                new_issue_dict[customfield_id] = v
            else:
                new_issue_dict[k] = v

    try:
        created_issue = jira.create_issue(new_issue_dict)
        print("Jira issue " + str(created_issue) + " created")
        StepUtility.export_variable("JIRA_ISSUE_ID", created_issue)
        StepUtility.export_variable("main_CF_OUTPUT_URL", str(current_environment.jira_base_url) + "/browse/" + str(created_issue))
    except Exception as exc:
        StepUtility.printCleanException(exc)
        StepUtility.printFail("Exiting Step - Failed to create issue")
        sys.exit(1)
Ejemplo n.º 10
0
def transition_issue(jira, current_environment):
    print("\nTransition issue status")
    issue = retrieve_jira_issue(jira, current_environment.issue)
    print("Current issue status: " + str(issue.fields.status))
    print("Desired issue status: " + current_environment.status)

    if str(issue.fields.status) == current_environment.status:
        print("Skipping transition as desired state is already met")
    else:
        # Verbose: Print the list of viable transitions before the transition takes place
        if current_environment.verbose == "true":
            transition_list = jira.transitions(current_environment.issue)
            print("Viable transition statuses before:")
            for transition in transition_list:
                print("\t" + transition['id'], transition['name'])
            print()

        transition_id = jira.find_transitionid_by_name(
            current_environment.issue, current_environment.status)
        if transition_id:
            try:
                jira.transition_issue(issue, transition_id)
            except Exception as exc:
                StepUtility.printCleanException(exc)
                StepUtility.printFail(
                    "Exiting Step - Failed to transition issue")
                sys.exit(1)
        else:
            StepUtility.printFail(
                "Exiting Step - Failed to find transition id for transition name: "
                + current_environment.status)
            sys.exit(1)

        # Verbose: Print the list of viable transitions after the transition takes place
        if current_environment.verbose == "true":
            print()
            transition_list = jira.transitions(current_environment.issue)
            print("Viable transition statuses after:")
            for transition in transition_list:
                print("\t" + transition['id'], transition['name'])

    print("Successfully transitioned issue")
    # Issue was successfully transitioned - attempt to update the issue now if required
    if current_environment.action == "issue_transition_and_update":
        update_issue(jira, current_environment)
Ejemplo n.º 11
0
def environment_setup():
    # Grab all of the environment variables
    env = os.environ
    jira_base_url = StepUtility.getEnvironmentVariable('JIRA_BASE_URL', env)
    jira_username = StepUtility.getEnvironmentVariable('JIRA_USERNAME', env)
    jira_api_key = StepUtility.getEnvironmentVariable('JIRA_API_KEY', env)
    action = StepUtility.getEnvironmentVariable('ACTION', env)

    # Logic here to use the regex to grab the jira issue key and assign it to issue
    jira_issue_source_field = StepUtility.getEnvironmentVariable('JIRA_ISSUE_SOURCE_FIELD', env)
    jira_issue_source_field_regex = StepUtility.getEnvironmentVariable('JIRA_ISSUE_SOURCE_FIELD_REGEX', env)
    ## TODO - Brandon - need to do regex work here
    issue = jira_issue_source_field

    # Issue fields below
    # Retrieve the project environment variable and add the project to a dict representation
    issue_project_env = StepUtility.getEnvironmentVariable('ISSUE_PROJECT', env)
    issue_project = None
    if issue_project_env:
        issue_project = "{'key': '" + issue_project_env + "'}"

    issue_summary = StepUtility.getEnvironmentVariable('ISSUE_SUMMARY', env)
    issue_description = StepUtility.getEnvironmentVariable('ISSUE_DESCRIPTION', env)

    # Retrieve the type environment variable and add the type to a dict representation
    issue_type_env = StepUtility.getEnvironmentVariable('ISSUE_TYPE', env)
    issue_type = None
    if issue_type_env:
        issue_type = "{'name': '" + issue_type_env + "'}"

    # Retrieve the components, split the list, and create an array of dicts with each component
    issue_components_env = StepUtility.getEnvironmentVariable('ISSUE_COMPONENTS', env)
    issue_components = None
    if issue_components_env:
        issue_components = []
        split_components = issue_components_env.split(",")
        for component in split_components:
            component_string = "{'name': '" + component + "'}"
            issue_components.append(ast.literal_eval(component_string))

    # Retrieve customfields
    issue_customfields = StepUtility.getEnvironmentVariable('ISSUE_CUSTOMFIELDS', env)

    # Retrieve the comment information
    existing_comment_id = StepUtility.getEnvironmentVariable('JIRA_COMMENT_ID', env)
    comment_body = StepUtility.getEnvironmentVariable('COMMENT_BODY', env)

    # Desired Jira status information
    status = StepUtility.getEnvironmentVariable('DESIRED_ISSUE_STATUS', env)
    jql_query = StepUtility.getEnvironmentVariable('JQL_QUERY', env)
    jql_query_max_results = 50
    jql_query_max_results_env = StepUtility.getEnvironmentVariable('JQL_QUERY_MAX_RESULTS', env)
    if jql_query_max_results_env:
        jql_query_max_results = jql_query_max_results_env

    verbose = StepUtility.getEnvironmentVariable('VERBOSE', env)

    current_environment = Environment(
        jira_base_url,
        jira_username,
        jira_api_key,
        action,
        issue,
        issue_project,
        issue_summary,
        issue_description,
        issue_type,
        issue_components,
        issue_customfields,
        existing_comment_id,
        comment_body,
        status,
        jql_query,
        jql_query_max_results,
        verbose)
    return current_environment
Ejemplo n.º 12
0
def action_required(jira, current_environment):
    StepUtility.printFail("Exiting Step - Please specify a valid action type")
    sys.exit(1)
Ejemplo n.º 13
0
def environment_setup():
    # Grab all of the environment variables
    env = os.environ
    vault_addr = StepUtility.getEnvironmentVariable('VAULT_ADDR', env)
    vault_auth_method = StepUtility.getEnvironmentVariable(
        'VAULT_AUTH_METHOD', env)
    vault_token = StepUtility.getEnvironmentVariable('VAULT_TOKEN', env)
    approle_role_id = StepUtility.getEnvironmentVariable(
        'APPROLE_ROLE_ID', env)
    approle_secret_id = StepUtility.getEnvironmentVariable(
        'APPROLE_SECRET_ID', env)
    vault_client_cert_base64 = StepUtility.getEnvironmentVariable(
        'VAULT_CLIENT_CERT_BASE64', env)
    vault_client_key_base64 = StepUtility.getEnvironmentVariable(
        'VAULT_CLIENT_KEY_BASE64', env)
    mount_point = StepUtility.getEnvironmentVariable('MOUNT_POINT', env)
    vault_kv_version = StepUtility.getEnvironmentVariable(
        'VAULT_KV_VERSION', env)
    new_line_replacement_string = StepUtility.getEnvironmentVariable(
        'NEW_LINE_REPLACEMENT_STRING', env)
    verbose = StepUtility.getEnvironmentVariable('VERBOSE', env)
    current_environment = Environment(
        vault_addr, vault_auth_method, vault_token, approle_role_id,
        approle_secret_id, vault_client_cert_base64, vault_client_key_base64,
        mount_point, vault_kv_version, new_line_replacement_string, verbose)
    return env, current_environment
Ejemplo n.º 14
0
def get_secrets(client, current_environment, secrets, path_set):
    if current_environment.verbose == "true":
        # Test printing of desired secret information when debug is enabled
        print("\n---- VERBOSE ---- Unique Paths")
        print(path_set)
        print("\n---- VERBOSE ---- Requested Secrets")
        for current_secret in secrets:
            print(json.dumps(current_secret.__dict__))
        print()

    # This will store all the key/values retrieved from the paths
    vault_retrieved_values = dict()
    # Iterate over each unique path passed in through the environment variables
    print("\nSecret Retrieval")
    for current_path in path_set:
        print("Retrieving secrets from path: " + current_path)
        if current_environment.vault_kv_version == "1":
            try:
                secret_response = client.secrets.kv.v1.read_secret(
                    mount_point=current_environment.mount_point,
                    path=current_path)
                vault_retrieved_values = secret_response['data']
            except Exception as exc:
                StepUtility.printCleanException(exc)
                StepUtility.printFail(
                    "Exiting Step - Failed to retrieve secrets from v1 path: "
                    + current_path)
                StepUtility.printFail(
                    "Please verify mount point, path, and kv version")
                sys.exit(1)
        else:
            try:
                secret_version_response = client.secrets.kv.v2.read_secret_version(
                    mount_point=current_environment.mount_point,
                    path=current_path)
                vault_retrieved_values = secret_version_response['data'][
                    'data']
            except Exception as exc:
                StepUtility.printCleanException(exc)
                StepUtility.printFail(
                    "Exiting Step - Failed to retrieve secrets from v2 path: "
                    + current_path)
                StepUtility.printFail(
                    "Please verify mount point, path, and kv version")
                sys.exit(1)

        # Loop through the list of secret requests and find keys that match
        for current_secret in secrets:
            for key, value in vault_retrieved_values.items():
                if current_secret.path == current_path and current_secret.secret_name == key:
                    print("Successful retrieval for \n\tpath: " +
                          current_secret.path + "\n\tsecret: " +
                          current_secret.secret_name)
                    current_secret.secret_value = value

    # Secrets should be retrieved now, check to make sure they all have a value
    for retrieved_secret in secrets:
        if retrieved_secret.secret_value == "":
            StepUtility.printFail(
                "Exiting Step - Failed retrieval for \n\tpath: " +
                retrieved_secret.path + "\n\tsecret: " +
                retrieved_secret.secret_name)
            sys.exit(1)

    return secrets
Ejemplo n.º 15
0
def vault_authentication(current_environment):
    # Authenticate the client - exit program if authentication fails
    print("\nAuthentication")
    client = hvac.Client(url=current_environment.vault_addr)

    # Check for client certs and apply them
    if current_environment.vault_client_cert_base64 != "" and current_environment.vault_client_key_base64 != "":
        try:
            client_certs = (base64.b64decode(
                current_environment.vault_client_cert_base64),
                            base64.b64decode(
                                current_environment.vault_client_key_base64))
            client = hvac.Client(url=current_environment.vault_addr,
                                 cert=client_certs)
        except Exception as exc:
            StepUtility.printCleanException(exc)
            StepUtility.printFail(
                "Exiting Step - Failed to authenticate with certificates to Vault instance"
            )
            sys.exit(1)

    if current_environment.vault_auth_method.upper() == "TOKEN":
        print("Mode: TOKEN")
        client.token = current_environment.vault_token
    elif current_environment.vault_auth_method.upper() == "APPROLE":
        print("Mode: APPROLE")
        try:
            client.auth_approle(current_environment.approle_role_id,
                                current_environment.approle_secret_id)
        except Exception as exc:
            StepUtility.printCleanException(exc)
            StepUtility.printFail(
                "Exiting Step - Failed to authenticate with Approle to Vault instance"
            )
            sys.exit(1)
    elif current_environment.vault_auth_method.upper() == "GCP":
        with open(current_environment.vault_auth_creds_path, 'r') as f:
            creds = json.load(f)
            project = creds['project_id']
            service_account = creds['client_email']

        now = int(time.time())
        expires = now + 900  # 15 mins in seconds
        payload = {
            'iat': now,
            'exp': expires,
            'sub': service_account,
            'aud': f"vault/{current_environment.vault_role}"
        }

        credentials = google_service_account.Credentials \
            .from_service_account_file(current_environment.vault_auth_creds_path)
        iam = googleapiclient.discovery.build('iam',
                                              'v1',
                                              credentials=credentials,
                                              cache_discovery=False)
        name = f'projects/{project}/serviceAccounts/{service_account}'
        body = {'payload': json.dumps(payload)}
        resp = iam.projects().serviceAccounts().signJwt(name=name,
                                                        body=body).execute()
        login = client.auth.gcp.login(current_environment.vault_role,
                                      resp['signedJwt'])
        client.token = login['auth']['client_token']
    else:
        print("Authentication Mode not passed, defaulting to Token auth")
        client.token = current_environment.vault_token

    # Verify that we connected successfully to Vault, otherwise exit the step
    if not client.is_authenticated():
        StepUtility.printFail(
            "Exiting Step - Failed to authenticate with Vault instance")
        sys.exit(1)
    else:
        print("Successfully authenticated with Vault instance")
    return client