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)
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)
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)
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
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)
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)
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)
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)
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
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