Skip to content

Instantly share code, notes, and snippets.

@JvGinkel
Created April 1, 2018 18:44
Show Gist options
  • Save JvGinkel/0930f860ab623cae5b7bf9d3d2b801f4 to your computer and use it in GitHub Desktop.
Save JvGinkel/0930f860ab623cae5b7bf9d3d2b801f4 to your computer and use it in GitHub Desktop.
Github webhook to trigger R10K runs on the puppet master
<?php
$config = yaml_parse_file('config.yaml');
$repo_full_name = $config['repo_full_name'];
$hookSecret = $config['hookSecret'];
set_error_handler(function($severity, $message, $file, $line) {
throw new \ErrorException($message, 0, $severity, $file, $line);
});
set_exception_handler(function($e) {
header('HTTP/1.1 500 Internal Server Error');
echo "Error on line {$e->getLine()}: " . htmlSpecialChars($e->getMessage());
die();
});
$rawPost = NULL;
if ($hookSecret !== NULL) {
if (!isset($_SERVER['HTTP_X_HUB_SIGNATURE'])) {
throw new \Exception("HTTP header 'X-Hub-Signature' is missing.");
} elseif (!extension_loaded('hash')) {
throw new \Exception("Missing 'hash' extension to check the secret code validity.");
}
list($algo, $hash) = explode('=', $_SERVER['HTTP_X_HUB_SIGNATURE'], 2) + array('', '');
if (!in_array($algo, hash_algos(), TRUE)) {
throw new \Exception("Hash algorithm '$algo' is not supported.");
}
$rawPost = file_get_contents('php://input');
if ($hash !== hash_hmac($algo, $rawPost, $hookSecret)) {
throw new \Exception('Hook secret does not match.');
}
};
if (!isset($_SERVER['HTTP_CONTENT_TYPE'])) {
throw new \Exception("Missing HTTP 'Content-Type' header.");
} elseif (!isset($_SERVER['HTTP_X_GITHUB_EVENT'])) {
throw new \Exception("Missing HTTP 'X-Github-Event' header.");
}
switch ($_SERVER['HTTP_CONTENT_TYPE']) {
case 'application/json':
$json = $rawPost ?: file_get_contents('php://input');
break;
case 'application/x-www-form-urlencoded':
$json = $_POST['payload'];
break;
default:
throw new \Exception("Unsupported content type: $_SERVER[HTTP_CONTENT_TYPE]");
}
# Payload structure depends on triggered event
# https://developer.github.com/v3/activity/events/types/
$payload = json_decode($json, true);
switch (strtolower($_SERVER['HTTP_X_GITHUB_EVENT'])) {
case 'ping':
echo 'pong';
break;
case 'push':
// error_log(json_encode($payload, JSON_PRETTY_PRINT));
if (! $repo_full_name === $payload['repository']['full_name']) {
header('HTTP/1.0 404 Not Found');
echo "repo_full_name does not match with [repository][full_name]\n";
break;
}
// Search in commits if Puppetfile is changed
$Puppetfile = '';
foreach ($payload['commits'] as $commit) {
foreach($commit['modified'] as $file) {
if ($file === 'Puppetfile') {
$Puppetfile = '-p';
break;
}
}
}
// Search for Branch name so we only update this branch
preg_match('/(\w+)$/', $payload['ref'], $matches);
$branch = $matches[0];
$command = "/opt/puppetlabs/puppet/bin/r10k deploy environment ${branch} -v ${Puppetfile} &";
exec($command);
echo "Executed command: ${command}";
break;
default:
header('HTTP/1.0 404 Not Found');
echo "Event:$_SERVER[HTTP_X_GITHUB_EVENT] Payload:\n";
print_r($payload); # For debug only. Can be found in GitHub hook log.
die();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment