slack

slack

This function sends a message to a slack channel.

  1#!/usr/bin/env python3
  2"""
  3slack
  4
  5This function sends a message to a slack channel.
  6
  7"""
  8
  9
 10import json
 11import getopt
 12import sys
 13import logging
 14import os
 15# import datetime
 16# import boto3
 17from urllib.request import Request, urlopen
 18from urllib.error import URLError, HTTPError
 19# import base64
 20# import zlib
 21
 22SLACK_WEBHOOK_URL = os.environ.get('SLACK_WEBHOOK_URL', 'None')
 23
 24GO_SERVER_URL = os.environ.get('GO_SERVER_URL', 'None')
 25GO_PIPELINE_NAME = os.environ.get('GO_PIPELINE_NAME', 'None')
 26GO_PIPELINE_GROUP_NAME = os.environ.get('GO_PIPELINE_GROUP_NAME', 'None')
 27GO_PIPELINE_LABEL = os.environ.get('GO_PIPELINE_LABEL', 'None')
 28GO_PIPELINE_COUNTER = os.environ.get('GO_PIPELINE_COUNTER', 'None')
 29GO_TRIGGER_USER = os.environ.get('GO_TRIGGER_USER', 'None')
 30GO_STAGE_NAME = os.environ.get('GO_STAGE_NAME', 'None')
 31GO_STAGE_COUNTER = os.environ.get('GO_STAGE_COUNTER', 'None')
 32GO_JOB_NAME = os.environ.get('GO_JOB_NAME', 'None')
 33GO_ENVIRONMENT_NAME = os.environ.get('GO_ENVIRONMENT_NAME', 'None')
 34
 35#
 36# Need to iterate on this. Name is not always MYGITY
 37#
 38GO_REVISION_MYGITY = os.environ.get('GO_REVISION_MYGITY', 'None')
 39GO_MATERIAL_BRANCH_MYGITY = os.environ.get('GO_MATERIAL_BRANCH_MYGITY', 'None')
 40
 41#
 42# For testing
 43#
 44# export SLACK_WEBHOOK_URL=https://fake123454321.com/
 45# export GO_SERVER_URL=https://gocd.cloudops.rekor.io/go
 46# export GO_ENVIRONMENT_NAME=build-prod
 47# export GO_PIPELINE_GROUP_NAME=build-prod
 48# export GO_TO_REVISION_MYGITY=40c9a6ea1716e1a3f12db4314644f5f1829f995d
 49# export GO_FROM_REVISION_MYGITY=40c9a6ea1716e1a3f12db4314644f5f1829f995d
 50# export GO_TRIGGER_USER=changes
 51# export GO_REVISION_MYGITY=40c9a6ea1716e1a3f12db4314644f5f1829f995d
 52# export GO_PIPELINE_NAME=cdk
 53# export GO_MATERIAL_BRANCH_MYGITY=master
 54
 55# export GO_MATERIAL_URL_MYGITY=git@bitbucket.org:openalpr/rekor-ops-gocd.git
 56# export GO_JAVA_HOME=/gocd-jre
 57# export GO_PIPELINE_LABEL=37
 58# export GO_EA_MODE=prod
 59# export GO_STAGE_NAME=buildStg
 60# export GO_STAGE_COUNTER=1
 61# export GO_PIPELINE_COUNTER=37
 62# export GO_JOB_NAME=buildJob
 63
 64# ${GO_SERVER_URL}/tab/build/detail/${GO_PIPELINE_NAME}/${GO_PIPELINE_LABEL}/${GO_STAGE_NAME}/${GO_STAGE_COUNTER}/${GO_JOB_NAME}#tab-console
 65
 66
 67logger = logging.getLogger()
 68logger.setLevel(logging.INFO)
 69
 70message_parsed = False
 71
 72pretty_alarm_name = ""
 73alarm_name = ""
 74old_state = ""
 75new_state = ""
 76reason = ""
 77alarm_description = ""
 78
 79channel = "gocd"
 80msg = None
 81json_block = None
 82basic_msg = None
 83
 84
 85def parser(message):
 86    """
 87    parser takes a message and creates a formatted / prettified slack message
 88    """
 89    if type(message) == list:
 90        message = message[0]
 91
 92    global msg
 93    global channel
 94    global json_block
 95
 96    if json_block:
 97        message = json.loads(msg)
 98    else:
 99        if basic_msg:
100            message = {
101              "text": msg,
102              "channel": channel,
103              "username": "gocd-slack-bot",
104              "icon_emoji": ":gocd:"
105            }
106        else:
107            message = {
108                "username": "gocd-slack-bot",
109                "icon_emoji": ":gocd:",
110                "channel": channel,
111                "blocks": [
112                    {
113                        "type": "section",
114                        "text": {
115                            "type": "mrkdwn",
116                            "text": "*"+msg+"*"
117                        }
118                    },
119                    {
120                        "type": "section",
121                        "fields": [
122                            {
123                                "type": "mrkdwn",
124                                "text": "*Environment*\n"+GO_ENVIRONMENT_NAME
125                            },
126                            {
127                                "type": "mrkdwn",
128                                "text": "*Pipeline Group*\n"+GO_PIPELINE_GROUP_NAME
129                            },
130                            {
131                                "type": "mrkdwn",
132                                "text": "*Pipeline*\n"+GO_PIPELINE_NAME
133                            },
134                            {
135                                "type": "mrkdwn",
136                                "text": "*Pipeline Build #*\n"+GO_PIPELINE_LABEL
137                            },
138                            {
139                                "type": "mrkdwn",
140                                "text": "*Stage Name*\n"+GO_STAGE_NAME
141                            },
142                            {
143                                "type": "mrkdwn",
144                                "text": "*Stage Counter*\n"+GO_STAGE_COUNTER
145                            },
146                            {
147                                "type": "mrkdwn",
148                                "text": "*Job Name*\n"+GO_JOB_NAME
149                            },
150                            {
151                                "type": "mrkdwn",
152                                "text": "*Trigger User*\n"+GO_TRIGGER_USER
153                            },
154                            {
155                                "type": "mrkdwn",
156                                "text": "*Material Branch*\n"+GO_MATERIAL_BRANCH_MYGITY
157                            },
158                            {
159                                "type": "mrkdwn",
160                                "text": "*Material Revision*\n"+GO_REVISION_MYGITY
161                            }
162                        ]
163                    },
164                    {
165                        "type": "section",
166                        "text": {
167                            "type": "mrkdwn",
168                            "text": "*Console Logs:*\n<"+GO_SERVER_URL+"/pipelines/"+GO_PIPELINE_NAME+"/"+GO_PIPELINE_LABEL+"/"+GO_STAGE_NAME+"/"+GO_STAGE_COUNTER+"|GoCD Logs>"
169                        }
170                    }
171                ]
172            }
173
174    req = Request(SLACK_WEBHOOK_URL, json.dumps(message).encode('utf-8'))
175    try:
176        response = urlopen(req)
177        body = response.read()
178        print(body)
179        logger.info("Message posted")
180    except HTTPError as e:
181        logger.error("Request failed: %d %s", e.code, e.reason)
182    except URLError as e:
183        logger.error("Server connection failed: %s", e.reason)
184
185
186def usage():
187    print("Usage: slack -c channel_name -m message_to_send -j[message is a slack json block]")
188
189
190def main():
191    # logger.info("Event: " + str(event))
192
193    global channel
194    global msg
195    global json_block
196    global basic_msg
197
198    try:
199        opts, args = getopt.getopt(sys.argv[1:], "hjbc:m:", ["help", "basic", "channel=", "message=", "json"])
200    except getopt.GetoptError as err:
201        # print help information and exit:
202        print(err)  # will print something like "option -a not recognized"
203        usage()
204        sys.exit(2)
205    for o, a in opts:
206        if o in ("-h", "--help"):
207            usage()
208            sys.exit()
209        elif o in ["-j", "--json"]:
210            json_block = True
211        elif o in ["-b", "--basic"]:
212            basic_msg = True
213        elif o in ("-c", "--channel"):
214            channel = a
215        elif o in ("-m", "--message"):
216            msg = a
217        else:
218            assert False, "unhandled option"
219
220    if msg is None:
221        usage()
222        sys.exit(2)
223
224    print(msg)
225    parser(msg)
226
227
228# Using the special variable
229# __name__
230if __name__ == "__main__":
231    main()
def parser(message)
 86def parser(message):
 87    """
 88    parser takes a message and creates a formatted / prettified slack message
 89    """
 90    if type(message) == list:
 91        message = message[0]
 92
 93    global msg
 94    global channel
 95    global json_block
 96
 97    if json_block:
 98        message = json.loads(msg)
 99    else:
100        if basic_msg:
101            message = {
102              "text": msg,
103              "channel": channel,
104              "username": "gocd-slack-bot",
105              "icon_emoji": ":gocd:"
106            }
107        else:
108            message = {
109                "username": "gocd-slack-bot",
110                "icon_emoji": ":gocd:",
111                "channel": channel,
112                "blocks": [
113                    {
114                        "type": "section",
115                        "text": {
116                            "type": "mrkdwn",
117                            "text": "*"+msg+"*"
118                        }
119                    },
120                    {
121                        "type": "section",
122                        "fields": [
123                            {
124                                "type": "mrkdwn",
125                                "text": "*Environment*\n"+GO_ENVIRONMENT_NAME
126                            },
127                            {
128                                "type": "mrkdwn",
129                                "text": "*Pipeline Group*\n"+GO_PIPELINE_GROUP_NAME
130                            },
131                            {
132                                "type": "mrkdwn",
133                                "text": "*Pipeline*\n"+GO_PIPELINE_NAME
134                            },
135                            {
136                                "type": "mrkdwn",
137                                "text": "*Pipeline Build #*\n"+GO_PIPELINE_LABEL
138                            },
139                            {
140                                "type": "mrkdwn",
141                                "text": "*Stage Name*\n"+GO_STAGE_NAME
142                            },
143                            {
144                                "type": "mrkdwn",
145                                "text": "*Stage Counter*\n"+GO_STAGE_COUNTER
146                            },
147                            {
148                                "type": "mrkdwn",
149                                "text": "*Job Name*\n"+GO_JOB_NAME
150                            },
151                            {
152                                "type": "mrkdwn",
153                                "text": "*Trigger User*\n"+GO_TRIGGER_USER
154                            },
155                            {
156                                "type": "mrkdwn",
157                                "text": "*Material Branch*\n"+GO_MATERIAL_BRANCH_MYGITY
158                            },
159                            {
160                                "type": "mrkdwn",
161                                "text": "*Material Revision*\n"+GO_REVISION_MYGITY
162                            }
163                        ]
164                    },
165                    {
166                        "type": "section",
167                        "text": {
168                            "type": "mrkdwn",
169                            "text": "*Console Logs:*\n<"+GO_SERVER_URL+"/pipelines/"+GO_PIPELINE_NAME+"/"+GO_PIPELINE_LABEL+"/"+GO_STAGE_NAME+"/"+GO_STAGE_COUNTER+"|GoCD Logs>"
170                        }
171                    }
172                ]
173            }
174
175    req = Request(SLACK_WEBHOOK_URL, json.dumps(message).encode('utf-8'))
176    try:
177        response = urlopen(req)
178        body = response.read()
179        print(body)
180        logger.info("Message posted")
181    except HTTPError as e:
182        logger.error("Request failed: %d %s", e.code, e.reason)
183    except URLError as e:
184        logger.error("Server connection failed: %s", e.reason)

parser takes a message and creates a formatted / prettified slack message

def usage()
187def usage():
188    print("Usage: slack -c channel_name -m message_to_send -j[message is a slack json block]")
def main()
191def main():
192    # logger.info("Event: " + str(event))
193
194    global channel
195    global msg
196    global json_block
197    global basic_msg
198
199    try:
200        opts, args = getopt.getopt(sys.argv[1:], "hjbc:m:", ["help", "basic", "channel=", "message=", "json"])
201    except getopt.GetoptError as err:
202        # print help information and exit:
203        print(err)  # will print something like "option -a not recognized"
204        usage()
205        sys.exit(2)
206    for o, a in opts:
207        if o in ("-h", "--help"):
208            usage()
209            sys.exit()
210        elif o in ["-j", "--json"]:
211            json_block = True
212        elif o in ["-b", "--basic"]:
213            basic_msg = True
214        elif o in ("-c", "--channel"):
215            channel = a
216        elif o in ("-m", "--message"):
217            msg = a
218        else:
219            assert False, "unhandled option"
220
221    if msg is None:
222        usage()
223        sys.exit(2)
224
225    print(msg)
226    parser(msg)