Skip to content

Instantly share code, notes, and snippets.

@richardradics
Last active January 25, 2017 23:09
Show Gist options
  • Save richardradics/5331e90d2dddb46da51c69011a4e462d to your computer and use it in GitHub Desktop.
Save richardradics/5331e90d2dddb46da51c69011a4e462d to your computer and use it in GitHub Desktop.
An example for creating a plugin for the limbo slack chat bot which trigger a remote jenkins job
"""!apk <parameters> trigger a remote jenkins which returns an android apk"""
import re
try:
from urllib import quote
except ImportError:
from urllib.request import quote
import requests
import os
help = ':book: *APK USAGE*\n' \
'\n\n' \
'*BRANCH* (branches (sprint-x or development) or tags (eg.: SIT2_5599) `MANDATORY`\n' \
'*FLAVOR* (Dev1,Dev2,Sit2,Uat,Perf,Prod) default Sit2\n' \
'*TYPE* (debug,beta,release) default beta\n' \
'*URL* - overrides APK url e.g: 192.168.1.113:8080\n' \
'\n' \
'Example latest development Sit2 beta version:\n' \
'*!apk BRANCH=development*\n' \
'\n' \
'Example for an unpinned pentest sprint-5 version:\n' \
'*!apk BRANCH=sprint-5 FLAVOR=Perf TYPE=Beta UNPINNED*\n' \
'\n' \
'Example local developer sprint-5 version:\n' \
'*!apk BRANCH=sprint-5 URL=192.168.1.113:8080*'
errorIcon = ":exclamation:"
infoIcon = ":book:"
defaultCheckForUsage = "\n" + infoIcon + " Check `!apk help` for usage"
errorWrongFormat = errorIcon + "Wrong parameter format!" + defaultCheckForUsage
errorWrongIpFormat = errorIcon + "Wrong server ip format: `{0}`" + defaultCheckForUsage
errorWrongParameter = errorIcon + "Wrong parameter: `{0}`" + defaultCheckForUsage
errorBranchMandatory = errorIcon + "*BRANCH* parameter is mandatory!" + defaultCheckForUsage
errorUnknownFlavor = errorIcon + "Unknown *FLAVOR*: `{0}`\n" + infoIcon + " Available flavors: Dev1,Dev2,Sit2,Uat,Perf,Prod"
errorUnknownBuildType = errorIcon + "Unknown build *TYPE*: `{0}`\n" + infoIcon + " Available build types: Debug,Beta,Release"
errorMissingSpaceBetweenParameters = errorIcon + "Add space between parameters: `{0}`" + defaultCheckForUsage
buildToken = os.environ.get("APK_BUILD_TOKEN")
botJobName = os.environ.get("APK_JOB_NAME")
temporaryCrendential = os.environ.get("JENKINS_CREDENTIAL")
host = os.environ.get("JENKINS_HOST")
baseReleaseUrl = 'http://' + temporaryCrendential + host + '/buildByToken/buildWithParameters?job='\
+ botJobName + '&token=' + buildToken + '{0}'
usersInfoUrl = 'https://slack.com/api/users.info?token={0}&user={1}&pretty=1'
flavors = ["Dev1", "Dev2", "Sit2", "Uat", "Perf", "Prod", "Demo"]
buildTypes = ["Debug", "Beta", "Release"]
def jenkins(searchterm, user_id, channel_id):
if "=" not in searchterm:
return errorWrongFormat
if "=" == searchterm:
return errorWrongFormat
parameters = searchterm.split(' ')
url_data = ''
arg_exists_flavor = False
arg_exists_build_type = False
arg_exists_branch = False
arg_exists_url = False
error_value_missing_space_parameter = ''
error_value_unknown_flavor_type = ''
error_value_unknown_build_type = ''
error_value_wrong_parameter = ''
branch = ''
server_ip = ''
for x in parameters:
parameter = x.split('=')
if "UNPINNED" == parameter[0].upper():
arg_exists_unpinned = True
continue
if len(parameter) == 1:
error_value_wrong_parameter = x
break
if len(parameter) > 2:
error_value_missing_space_parameter = x
break
key = parameter[0].upper()
value = parameter[1]
if len(key) == 0 or len(value) == 0:
error_value_wrong_parameter = x
break
if "BRANCH" == key:
branch = value
arg_exists_branch = True
if "FLAVOR" == key:
arg_exists_flavor = True
value = value.title()
if value not in flavors:
error_value_unknown_flavor_type = value
break
if "TYPE" == key:
arg_exists_build_type = True
value = value.title()
if value not in buildTypes:
error_value_unknown_build_type = value
break
if "URL" == key:
arg_exists_url = True
server_ip = value
url_data += '&' + key + '=' + value
if len(error_value_wrong_parameter) > 0:
return errorWrongParameter.format(error_value_wrong_parameter)
if len(error_value_missing_space_parameter) > 0:
return errorMissingSpaceBetweenParameters.format(error_value_missing_space_parameter)
if len(error_value_unknown_flavor_type) > 0:
return errorUnknownFlavor.format(error_value_unknown_flavor_type)
if len(error_value_unknown_build_type) > 0:
return errorUnknownBuildType.format(error_value_unknown_build_type)
if arg_exists_branch is False:
return errorBranchMandatory
if arg_exists_flavor is False:
url_data += '&FLAVOR=Sit2'
if arg_exists_build_type is False:
url_data += '&TYPE=Beta'
if arg_exists_url is True:
if not re.findall(r'[0-9]+(?:\.[0-9]+){3}(:[0-9]+)?', server_ip):
return errorWrongIpFormat.format(server_ip)
url_data += '&URL=' + server_ip
slack_token = os.environ.get("SLACK_TOKEN")
user_info = requests.post(usersInfoUrl.format(slack_token, user_id)).json().get("user", "")
nickname = user_info.get("name", "")
real_name = user_info.get("real_name", "")
full_url_data = url_data + "&USER=" + nickname + "&CHANNEL=" + channel_id
requests.post(baseReleaseUrl.format(full_url_data))
return print_result(url_data, real_name)
def print_result(url_data, real_name):
res = ':airplane: *Build scheduled* with parameters:\n{0}'
splitted = url_data[1:].split('&')
params = '\t\t*User*: '+real_name + "\n"
for x in splitted:
tmp = x.split('=')
params += "\t\t*" + tmp[0].title() + "*: " + tmp[1].title() + "\n"
return res.format(params)
def on_message(msg, server):
text = msg.get("text", "")
match = re.findall(r"!apk (.*)", text)
if not match:
return
searchterm = match[0].encode("utf8")
user_id = msg.get("user", "").encode("utf8")
channel_id = msg.get("channel", "").encode("utf8")
if "help" == searchterm:
return help
else:
return jenkins(searchterm, user_id, channel_id)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment