-
Notifications
You must be signed in to change notification settings - Fork 10
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
4 changed files
with
215 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
ansible-tower-bridges/github-webhook | ||
==================================== | ||
|
||
This implementation is used to bridge GitHub webhooks to Ansible Tower. Ansible Tower expects any payload/input parameters to be passed in the `extra_vars` dictionary. Of course GitHub does not do this, and hence this "bridge" to provide that mapping for webhooks request configured on github to be sent to/through this bridge. | ||
|
||
Requirements | ||
------------ | ||
|
||
Although this can be run as a regular/standalone `node.js` app, it is recommended that this gets deployed on an OpenShift Container Platform for ease of maintaining it. | ||
|
||
|
||
Running in OpenShift | ||
-------------------- | ||
|
||
For example, use `oc new-app` to deploy the application: | ||
|
||
``` | ||
> oc new-app openshift/nodejs:8~https://github.com/tool-integrations.git --context-dir=ansible-tower-bridges/github-webhook | ||
``` | ||
|
||
|
||
Configuration | ||
------------- | ||
|
||
| Variable | Description | Required | Defaults | | ||
|:---------|:------------|:---------|:---------| | ||
| ANSIBLE_TOWER_URL | The fqdn portion of Ansible Tower (or IP) - do not include 'http://' or 'https://' | yes | | | ||
| ANSIBLE_TOWER_TEMPLATE_ID | The numeric template id for the job template to run | yes | | | ||
| ANSIBLE_TOWER_USERNAME | An Ansible Tower username with the correct permissions to run the above template | yes | | | ||
| ANSIBLE_TOWER_PASSWORD | Password for the above Ansible Tower username | yes | | | ||
| HTTP_PORT | The http port for the application to listen on | no | 8080 | | ||
| HTTPS_PORT | The httpd (SSL) port for the application listen on (choose this or HTTP_PORT above) | no | 8443 | | ||
| HTTPS_SSL_CERTIFICATE | When HTTPS_PORT above is used, specify the certificate here | no | | | ||
| HTTPS_SSL_KEY | When the HTTPS_PORT above is used, specify the certificate key here | no | | | ||
|
||
|
||
License | ||
------- | ||
|
||
Apache License 2.0 | ||
|
||
|
||
Author Information | ||
------------------ | ||
|
||
Red Hat Community of Practice & staff of the Red Hat Open Innovation Labs. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
|
||
const http = require('http'); | ||
const https = require('https'); | ||
const fs = require('fs'); | ||
|
||
const httpPort = process.env.HTTP_PORT || 8080; | ||
const httpsPort = process.env.HTTPS_PORT || 8443; | ||
const httpsSSLKey = process.env.HTTPS_SSL_KEY || ''; | ||
const httpsSSLCert = process.env.HTTPS_SSL_CERTIFICATE || ''; | ||
|
||
var express = require('express'); | ||
var cors = require('cors'); | ||
var app = express(); | ||
var bodyParser = require('body-parser'); | ||
var bridge = require('./lib/bridge'); | ||
|
||
app.use(cors()); | ||
app.use(bodyParser()); | ||
|
||
app.post('/', function (request, res) { | ||
bridge.processRequest(request.body, function(err, response) { | ||
if (err){ | ||
// TODO: make the return status code be more specific per the error | ||
// - i.e.: not use "400 Bad Request" for all of it | ||
res.status(400).send(err); | ||
} else { | ||
res.send(response); | ||
} | ||
}); | ||
}); | ||
|
||
if (httpsSSLCert.trim() && httpsSSLKey.trim()) { // Secure | ||
const options = { | ||
key: fs.readFileSync(httpsSSLKey), | ||
cert: fs.readFileSync(httpsSSLCert) | ||
}; | ||
|
||
https.createServer(options, app).listen(httpsPort, function () { | ||
console.log('Listening on https://localhost:' + httpsPort); | ||
}); | ||
} | ||
else { // non-Secure | ||
http.createServer(app).listen(httpPort, function() { | ||
console.log('Listening on UNSECURE http://localhost:' + httpPort); | ||
}); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
|
||
const request = require('request'); | ||
const urlModule = require('url'); | ||
|
||
const AnsibleTowerUrl = process.env['ANSIBLE_TOWER_URL']; | ||
const AnsibleTowerTemplateId = process.env['ANSIBLE_TOWER_TEMPLATE_ID']; | ||
const AnsibleTowerUsername = process.env['ANSIBLE_TOWER_USERNAME'] || ''; | ||
const AnsibleTowerPassword = process.env['ANSIBLE_TOWER_PASSWORD'] || ''; | ||
|
||
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0" | ||
|
||
|
||
function getTemplateLaunchUri(){ | ||
return '/api/v1/job_templates/' + AnsibleTowerTemplateId + '/launch/'; | ||
} | ||
|
||
function getRequestUrl(server, uri){ | ||
return 'https://' + server + uri; | ||
} | ||
|
||
function getAuth(){ | ||
return 'Basic ' + new Buffer(AnsibleTowerUsername + ':' + AnsibleTowerPassword).toString('base64'); | ||
} | ||
|
||
|
||
function generateReturnJson(message, url) { | ||
var returnjson = { | ||
message: message, | ||
url: '' | ||
}; | ||
|
||
if (url) { | ||
returnjson['url'] = url; | ||
} | ||
|
||
return returnjson; | ||
} | ||
|
||
|
||
function sendResponse(cb, successMessage, errorMessage, url) { | ||
if (errorMessage) { | ||
console.log('ERROR: ' + errorMessage); | ||
returnjson = generateReturnJson(errorMessage, url); | ||
cb(returnjson, null); | ||
} else if (successMessage) { | ||
console.log('SUCCESS: ' + successMessage); | ||
returnjson = generateReturnJson(successMessage, url); | ||
cb(null, returnjson); | ||
} else { | ||
returnjson = generateReturnJson('Unknown Error'); | ||
cb(returnjson, null); | ||
} | ||
} | ||
|
||
|
||
function processRequest(params, cb) { | ||
var uri = getTemplateLaunchUri(); | ||
var request_url = getRequestUrl(AnsibleTowerUrl, uri); | ||
var auth = getAuth(); | ||
|
||
var config_body = { | ||
"extra_vars" : {} | ||
}; | ||
|
||
// Wrap the params in the `extra_vars` dictionary | ||
config_body['extra_vars'] = params; | ||
|
||
var options = { | ||
url: request_url, | ||
method: 'POST', | ||
headers: { | ||
'Content-type': 'application/json', | ||
'Authorization': auth | ||
}, | ||
json: config_body | ||
}; | ||
|
||
// options_string = JSON.stringify(options, null, 4); | ||
// console.log('calling options: ' + options_string); | ||
|
||
request(options, function (error, response) { | ||
//console.log('*********RESPONSE**********************'); | ||
//console.log(response); | ||
//console.log('**********END RESPONSE*****************'); | ||
if (!error && response.statusCode >= 200 && response.statusCode < 300) { | ||
sendResponse( | ||
cb, | ||
'Successful Launch with Ansible Tower job ID: ' + response.body.job, | ||
null, | ||
'https://' + AnsibleTowerUrl + '/#/jobs/' + response.body.job); | ||
|
||
} | ||
else { | ||
var errorMsg = 'Failed to launch Ansible Tower job. Please check your input and try again.'; | ||
if (error) { | ||
errorMsg += ' (' + error + ')'; | ||
} | ||
|
||
sendResponse(cb, null, errorMsg, null); | ||
} | ||
}) | ||
} | ||
|
||
|
||
exports.processRequest = processRequest; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
{ | ||
"name": "github-webhook-bridge", | ||
"version": "0.1.0", | ||
"description": "GitHub Webhook Bridge for Ansible Tower", | ||
"main": "index.js", | ||
"scripts": { | ||
"start": "node index.js" | ||
}, | ||
"author": "Øystein Bedin", | ||
"license": "ISC", | ||
"dependencies": { | ||
"body-parser": "^1.15.2", | ||
"cors": "^2.7.1", | ||
"express": "^4.14.0", | ||
"request": "^2.85.0", | ||
"url": "^0.11.0" | ||
} | ||
} |