diff --git a/docs/getting_started.rst b/docs/getting_started.rst index 629ae7d..d15a171 100644 --- a/docs/getting_started.rst +++ b/docs/getting_started.rst @@ -15,6 +15,11 @@ Lavatory looks for several environment variables in order to authenticate: These will be loaded in at the beginning of a run and raise an exception if these environment variables are missing. +In addition, Lavatory supports the ability to send Slack notifications with optional environment variables (both of which must be set): + +``SLACK_API_TOKEN`` - Slack API Token + +``SLACK_CHANNEL`` - Slack Channel to Post Notification to Purging Artifacts ----------------- diff --git a/requirements.txt b/requirements.txt index 64c60e6..32b8c5b 100644 --- a/requirements.txt +++ b/requirements.txt @@ -6,3 +6,4 @@ requests humanfriendly party pluginbase +slacker \ No newline at end of file diff --git a/src/lavatory/credentials.py b/src/lavatory/credentials.py index dcfd345..bc14df6 100644 --- a/src/lavatory/credentials.py +++ b/src/lavatory/credentials.py @@ -15,3 +15,20 @@ def load_credentials(): raise MissingEnvironmentVariable(key.upper()) return credentials + +def load_slack_credentials(): + """Get slack credentials from environment variables + + Returns False if no credentials set. + + """ + + slack_credentials = { + "api_token": os.getenv('SLACK_API_TOKEN', False), + "slack_channel": os.getenv('SLACK_CHANNEL', False) + } + + if not slack_credentials['api_token'] and not slack_credentials['slack_channel']: + slack_credentials = False + + return slack_credentials \ No newline at end of file diff --git a/src/lavatory/utils/artifactory.py b/src/lavatory/utils/artifactory.py index b9f0642..a8b6c4f 100644 --- a/src/lavatory/utils/artifactory.py +++ b/src/lavatory/utils/artifactory.py @@ -9,7 +9,8 @@ # pylint: disable=redefined-builtin from requests.exceptions import (BaseHTTPError, ConnectionError, HTTPError, InvalidURL, RequestException) -from ..credentials import load_credentials +from ..credentials import load_credentials, load_slack_credentials +from .slack import post_slack_message LOG = logging.getLogger(__name__) @@ -84,6 +85,10 @@ def purge(self, dry_run, artifacts): purged += 1 except (BaseHTTPError, HTTPError, InvalidURL, RequestException, ConnectionError) as error: LOG.error(str(error)) + + if load_slack_credentials(): + slack_message = "Purged Artifact: {}".format(full_artifact_url) + post_slack_message(message=slack_message, username="lavatory", icon_emoji=":name_badge:") return purged diff --git a/src/lavatory/utils/slack.py b/src/lavatory/utils/slack.py new file mode 100644 index 0000000..5dab117 --- /dev/null +++ b/src/lavatory/utils/slack.py @@ -0,0 +1,30 @@ +"""Post a message to slack.""" +import logging + +import slacker + +from ..credentials import load_slack_credentials + +LOG = logging.getLogger(__name__) + + +def post_slack_message(message=None, username=None, icon_emoji=None): + """Format the message and post to the appropriate slack channel. + + Args: + message (str): Message to post to slack + channel (str): Desired channel. Must start with # + + """ + LOG.debug('Loading Slack Credentials') + slack_credentials = load_slack_credentials() + + channel = slack_credentials['slack_channel'] + LOG.debug('Slack Channel: %s\nSlack Message: %s', channel, message) + + slack = slacker.Slacker(slack_credentials['api_token']) + try: + slack.chat.post_message(channel=channel, text=message, username=username, icon_emoji=icon_emoji) + LOG.info('Message posted to %s', channel) + except slacker.Error: + LOG.info("error posted message to %s", channel) \ No newline at end of file