"""Jira utility functions.""" import datetime from jira import JIRA from jira import JIRAError from lambdacommon.common_config import logger import config def comment_on_jira_issue(jira_issue, user, account_id): """ Comment on Jira issue. Args: jira_issue (str): Name of Jira issue to look up, e.g. DEVEX-123 user (str): Name of user that is running this tool account_id (str): ID of the AWS account Returns: str: Timestamp that comment was created """ try: jira = JIRA(config.JIRA_BASE_URL, basic_auth=( config.JIRA_EMAIL_ADDRESS, config.JIRA_API_TOKEN)) now = datetime.datetime.now() now_formatted = now.strftime('%Y-%m-%d-%H:%M:%S') comment = f'{user} has run the AWS break-glass tool '\ f'for account {account_id} ' \ f'at {now_formatted} UTC' response = jira.add_comment(jira_issue, comment) return response.created except JIRAError as error: # Jira throws an exception when the issue does not exist if error.status_code == 404: logger.exception(f'Issue not found: {error.text}') else: logger.exception(f'Issue error: {error.text}') raise def verify_jira_issue(jira_issue): """ Look up Jira issue and verify it exists. Args: jira_issue (str): Name of Jira issue to look up, e.g. DEVEX-123 Returns: JIRA: Jira issue object """ try: jira = JIRA(config.JIRA_BASE_URL, basic_auth=( config.JIRA_EMAIL_ADDRESS, config.JIRA_API_TOKEN)) # Look up jira issue issue = jira.issue(jira_issue) issue_created = datetime.datetime.strptime( issue.fields.created, '%Y-%m-%dT%H:%M:%S.%f%z') issue_created_utc = datetime.datetime.utcfromtimestamp( issue_created.timestamp()) now = datetime.datetime.utcnow() diff = now - issue_created_utc diff_seconds = int(diff.total_seconds()) valid_hours = config.JIRA_ISSUE_VALIDITY_PERIOD_HOURS if (diff_seconds / 3600) > valid_hours: logger.exception(f'Jira issue more than {valid_hours} hours old') raise ValueError('Jira issue greater than validity period.') # Returned from https://theorchard.atlassian.net/rest/api/3/statuscategory # noqa if issue.fields.status.statusCategory.name == 'Done': logger.exception('Jira issue should not be closed. Status category' f' is {issue.fields.status.statusCategory.name}') raise ValueError('Jira issue status category is not valid.') return issue.permalink() except JIRAError as error: # Jira throws an exception when the issue does not exist if error.status_code == 404: logger.exception(f'Issue not found: {error.text}') else: logger.exception(f'Error looking up issue: {error.text}') raise