diff --git a/source_control/githooks b/source_control/githooks new file mode 100644 index 00000000000..a05df9d8217 --- /dev/null +++ b/source_control/githooks @@ -0,0 +1,173 @@ +#!/usr/bin/python +import json +import urllib2 +import base64 + +""" +Ansible module to add authorized_keys for ssh logins. +(c) 2013, Phillip Gentry + +This file is part of Ansible + +Ansible is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +Ansible is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with Ansible. If not, see . +""" + +DOCUMENTATION = ''' +--- +module: githooks +short_description: Manages github service hooks. +description: + - Adds service hooks and removes service hooks that have an error status. +version_added: "1.3.4" +options: + user: + description: + - Github username. + required: true + oauthkey: + description: + - The oauth key provided by github. It can be found/generated on github under "Edit Your Profile" >> "Applications" >> "Personal Access Tokens" + required: true + repo: + description: + - This is the API url for the repository you want to manage hooks for. It should be in the form of: https://api.github.com/repos/user:/repo:. Note this is different than the normal repo url. + required: true + hookurl: + description: + - When creating a new hook, this is the url that you want github to post to. It is only required when creating a new hook. + required: false + action: + description: + - This tells the githooks module what you want it to do. + required: true + choices: [ "create", "cleanall" ] +author: Phillip Gentry, CX Inc +''' + +EXAMPLES = ''' +# Example creating a new service hook. It ignores duplicates. +- githooks: action=create hookurl=http://11.111.111.111:2222 user={{ gituser }} oauthkey={{ oauthkey }} repo=https://api.github.com/repos/pcgentry/Github-Auto-Deploy + +# Cleaning all hooks for this repo that had an error on the last update. Since this works for all hooks in a repo it is probably best that this would be called from a handler. +- local_action: githooks action=cleanall user={{ gituser }} oauthkey={{ oauthkey }} repo={{ repo }} +''' + + +def list(hookurl, oauthkey, repo, user): + url = "%s/hooks" % repo + auth = base64.encodestring('%s:%s' % (user, oauthkey)).replace('\n', '') + req = urllib2.Request(url) + req.add_header("Authorization", "Basic %s" % auth) + res = urllib2.urlopen(req) + out = res.read() + return False, out + +def clean504(hookurl, oauthkey, repo, user): + current_hooks = list(hookurl, oauthkey, repo, user)[1] + decoded = json.loads(current_hooks) + + for hook in decoded: + if hook['last_response']['code'] == 504: + # print "Last response was an ERROR for hook:" + # print hook['id'] + delete(hookurl, oauthkey, repo, user, hook['id']) + + return 0, current_hooks + +def cleanall(hookurl, oauthkey, repo, user): + current_hooks = list(hookurl, oauthkey, repo, user)[1] + decoded = json.loads(current_hooks) + + for hook in decoded: + if hook['last_response']['code'] != 200: + # print "Last response was an ERROR for hook:" + # print hook['id'] + delete(hookurl, oauthkey, repo, user, hook['id']) + + return 0, current_hooks + +def create(hookurl, oauthkey, repo, user): + url = "%s/hooks" % repo + values = { + "active": True, + "name": "web", + "config": { + "url": "%s" % hookurl, + "content_type": "json" + } + } + data = json.dumps(values) + auth = base64.encodestring('%s:%s' % (user, oauthkey)).replace('\n', '') + out='[]' + try : + req = urllib2.Request(url) + req.add_data(data) + req.add_header("Authorization", "Basic %s" % auth) + res = urllib2.urlopen(req) + out = res.read() + return 0, out + except urllib2.HTTPError, e : + if e.code == 422 : + return 0, out + +def delete(hookurl, oauthkey, repo, user, hookid): + url = "%s/hooks/%s" % (repo, hookid) + auth = base64.encodestring('%s:%s' % (user, oauthkey)).replace('\n', '') + req = urllib2.Request(url) + req.get_method = lambda: 'DELETE' + req.add_header("Authorization", "Basic %s" % auth) + # req.add_header('Content-Type', 'application/xml') + # req.add_header('Accept', 'application/xml') + res = urllib2.urlopen(req) + out = res.read() + return out + +def main(): + module = AnsibleModule( + argument_spec=dict( + action=dict(required=True), + hookurl=dict(required=False), + oauthkey=dict(required=True), + repo=dict(required=True), + user=dict(required=True), + ) + ) + + action = module.params['action'] + hookurl = module.params['hookurl'] + oauthkey = module.params['oauthkey'] + repo = module.params['repo'] + user = module.params['user'] + + if action == "list": + (rc, out) = list(hookurl, oauthkey, repo, user) + + if action == "clean504": + (rc, out) = clean504(hookurl, oauthkey, repo, user) + + if action == "cleanall": + (rc, out) = cleanall(hookurl, oauthkey, repo, user) + + if action == "create": + (rc, out) = create(hookurl, oauthkey, repo, user) + + if rc != 0: + module.fail_json(msg="failed", result=out) + + module.exit_json(msg="success", result=out) + + +# include magic from lib/ansible/module_common.py +#<> +main()