Move profile::git_webhook into seperate module pe_code_manager_webhook

Prior to this commit the functionality to setup the either code
manager or zack/r10k was tightly coupled to this control-repo. In
an effort to make that functionality useful to more people we're
splitting it into a dedicated module.

After this commit, the pe_code_manager_webhook module will contain all logic
around setting up the webhook while this control-repo will still
gloss over the details needed to get everything in PE setup correctly
to use that module.

This commit removes the files associated with the profile including
some custom functions that were only there to make it work.

This commit removes the all_in_one_pe_2015_2 role as it was exactly
the same as the all_in_one_pe role.

This commit modifies all_in_one_pe to use the pe_code_manager_webhook module
instead of the profile.
This commit is contained in:
Nick Walker 2016-02-25 15:23:12 -08:00
parent d250d971b9
commit 00d3aa1f4f
9 changed files with 5 additions and 282 deletions

View File

@ -28,6 +28,10 @@ mod 'r10k',
:git => 'https://github.com/acidprime/r10k',
:tag => 'v3.1.1'
mod 'pe_code_manager_webhook',
:git => 'https://github.com/npwalker/pe_code_manager_webhook',
:ref => '20d9f2e274325edaa10d8ec3b4f98a62ad726335'
mod 'gms',
:git => 'https://github.com/npwalker/abrader-gms',
:branch => 'gitlab_disable_ssl_verify_support'

View File

@ -1,36 +0,0 @@
require 'puppet/file_system'
Puppet::Parser::Functions::newfunction(
:no_fail_file, :arity => -2, :type => :rvalue,
:doc => "Loads a file from a module and returns its contents as a string.
This is a replacement to the file function that returns nothing
if the file specified cannot be found instead of erroring out.
The argument to this function should be a `<MODULE NAME>/<FILE>`
reference, which will load `<FILE>` from a module's `files`
directory. (For example, the reference `mysql/mysqltuner.pl` will load the
file `<MODULES DIRECTORY>/mysql/files/mysqltuner.pl`.)
This function can also accept:
* An absolute path, which can load a file from anywhere on disk.
* Multiple arguments, which will return the contents of the **first** file
found, skipping any files that don't exist.
"
) do |vals|
path = nil
vals.each do |file|
found = Puppet::Parser::Files.find_file(file, compiler.environment)
if found && Puppet::FileSystem.exist?(found)
path = found
break
end
end
if path
Puppet::FileSystem.read_preserve_line_endings(path)
else
nil
end
end

View File

@ -1,12 +0,0 @@
class profile::git_webhook (
$force_zack_r10k_webhook = false
) {
if versioncmp( $::pe_server_version, '2015.2.99' ) <= 0 or $force_zack_r10k_webhook {
include profile::git_webhook::zack_r10k_webhook
} else {
include profile::git_webhook::code_manager
include profile::git_webhook::zack_r10k_webhook_disable
}
}

View File

@ -1,150 +0,0 @@
class profile::git_webhook::code_manager {
$authenticate_webhook = hiera('puppet_enterprise::master::code_manager::authenticate_webhook', true)
$code_manager_service_user = 'code_manager_service_user'
$code_manager_service_user_password = fqdn_rand_string(40, '', "${code_manager_service_user}_password")
#puppet_master_classifier_settings is a custom function
$classifier_settings = puppet_master_classifer_settings()
$classifier_hostname = $classifier_settings['server']
$classifier_port = $classifier_settings['port']
$token_directory = '/etc/puppetlabs/puppetserver/.puppetlabs'
$token_filename = "${token_directory}/${code_manager_service_user}_token"
$gms_api_token = hiera('gms_api_token', undef)
$git_management_system = hiera('git_management_system', undef)
$code_manager_ssh_key_file = '/etc/puppetlabs/puppetserver/code_manager.key'
exec { 'create code manager ssh key' :
command => "/usr/bin/ssh-keygen -t rsa -b 2048 -C 'code_manager' -f ${code_manager_ssh_key_file} -q -N ''",
creates => $code_manager_ssh_key_file,
}
file { $code_manager_ssh_key_file :
ensure => file,
owner => 'pe-puppet',
group => 'pe-puppet',
require => Exec['create code manager ssh key'],
}
#If files exist in the codedir code manager can't manage them unless pe-puppet can read them
exec { 'chown all environments to pe-puppet' :
command => "/bin/chown -R pe-puppet:pe-puppet ${::settings::codedir}",
unless => "/usr/bin/test \$(stat -c %U ${::settings::codedir}/environments/production) = 'pe-puppet'",
}
$code_manager_role_name = 'Deploy Environments'
$create_role_creates_file = '/etc/puppetlabs/puppetserver/.puppetlabs/deploy_environments_created'
$create_role_curl = @(EOT)
/opt/puppetlabs/puppet/bin/curl -k -X POST -H 'Content-Type: application/json' \
https://<%= $classifier_hostname %>:4433/rbac-api/v1/roles \
-d '{"permissions": [{"object_type": "environment", "action": "deploy_code", "instance": "*"},
{"object_type": "tokens", "action": "override_lifetime", "instance": "*"}],"user_ids": [], "group_ids": [], "display_name": "<%= $code_manager_role_name %>", "description": ""}' \
--cert <%= $::settings::certdir %>/<%= $::trusted['certname'] %>.pem \
--key <%= $::settings::privatekeydir %>/<%= $::trusted['certname'] %>.pem \
--cacert <%= $::settings::certdir %>/ca.pem;
touch <%= $create_role_creates_file %>
| EOT
exec { 'create deploy environments role' :
command => inline_epp( $create_role_curl ),
creates => $create_role_creates_file,
logoutput => true,
path => $::path,
require => File[$token_directory],
}
rbac_user { $code_manager_service_user :
ensure => 'present',
name => $code_manager_service_user,
email => "${code_manager_service_user}@example.com",
display_name => 'Code Manager Service Account',
password => $code_manager_service_user_password,
roles => [ $code_manager_role_name ],
require => Exec['create deploy environments role'],
}
file { $token_directory :
ensure => directory,
owner => 'pe-puppet',
group => 'pe-puppet',
}
exec { "Generate Token for ${code_manager_service_user}" :
command => epp('profile/git_webhook/code_manager/create_rbac_token.epp',
{ 'code_manager_service_user' => $code_manager_service_user,
'code_manager_service_user_password' => $code_manager_service_user_password,
'classifier_hostname' => $classifier_hostname,
'classifier_port' => $classifier_port,
'token_filename' => $token_filename
}),
creates => $token_filename,
require => [ Rbac_user[$code_manager_service_user], File[$token_directory] ],
}
#this file cannont be read until the next run after the above exec
#because the file function runs on the master not on the agent
#so the file doesn't exist at the time the function is run
$rbac_token_file_contents = no_fail_file($token_filename)
#Only mv code if this is at least the 2nd run of puppet
#Code manager needs to be enabled and puppet server restarted
#before this exec can complete. Gating on the token file
#ensures at least one run has completed
if $::code_manager_mv_old_code and !empty($rbac_token_file_contents) {
$timestamp = chomp(generate('/bin/date', '+%Y%d%m_%H:%M:%S'))
exec { 'mv files out of $environmentpath' :
command => "mkdir /etc/puppetlabs/env_back_${timestamp};
mv ${::settings::codedir}/environments/* /etc/puppetlabs/env_back_${timestamp}/;
rm /opt/puppetlabs/facter/facts.d/code_manager_mv_old_code.txt;
TOKEN=`/opt/puppetlabs/puppet/bin/ruby -e \"require 'json'; puts JSON.parse(File.read('${token_filename}'))['token']\"`;
/opt/puppetlabs/puppet/bin/curl -k -X POST -H 'Content-Type: application/json' \"https://${::trusted['certname']}:8170/code-manager/v1/deploys?token=\$TOKEN\" -d '{\"environments\": [\"${::environment}\"], \"wait\": true}';
/opt/puppetlabs/puppet/bin/curl -k -X POST -H 'Content-Type: application/json' \"https://${::trusted['certname']}:8170/code-manager/v1/deploys?token=\$TOKEN\" -d '{\"deploy-all\": true, \"wait\": true}';
sleep 15",
path => $::path,
logoutput => true,
require => Exec["Generate Token for ${code_manager_service_user}"],
}
}
if !empty($gms_api_token) {
if $authenticate_webhook and !empty($rbac_token_file_contents) {
$rbac_token = parsejson($rbac_token_file_contents)['token']
$token_info = "&token=${rbac_token}"
}
else {
$token_info = ''
}
$code_manager_webhook_type = $git_management_system ? {
'gitlab' => 'github',
default => $git_management_system,
}
git_deploy_key { "add_deploy_key_to_puppet_control-${::fqdn}":
ensure => present,
name => $::fqdn,
path => "${code_manager_ssh_key_file}.pub",
token => $gms_api_token,
project_name => 'puppet/control-repo',
server_url => hiera('gms_server_url'),
provider => $git_management_system,
}
git_webhook { "code_manager_post_receive_webhook-${::fqdn}" :
ensure => present,
webhook_url => "https://${::fqdn}:8170/code-manager/v1/webhook?type=${code_manager_webhook_type}${token_info}",
token => $gms_api_token,
project_name => 'puppet/control-repo',
server_url => hiera('gms_server_url'),
provider => $git_management_system,
disable_ssl_verify => true,
}
}
}

View File

@ -1,58 +0,0 @@
class profile::git_webhook::zack_r10k_webhook (
$use_mcollective = false,
) {
$username = hiera('webhook_username', fqdn_rand_string(10, '', 'username'))
$password = hiera('webhook_password', fqdn_rand_string(20, '', 'password'))
$gms_api_token = hiera('gms_api_token', undef)
$git_management_system = hiera('git_management_system', undef)
if $use_mcollective {
class { 'r10k::mcollective':
notify => Service['mcollective'],
}
}
class {'r10k::webhook::config':
enable_ssl => true,
protected => true,
user => $username,
pass => $password,
use_mcollective => $use_mcollective,
}
class {'r10k::webhook':
user => 'root',
group => '0',
require => Class['r10k::webhook::config'],
}
$r10k_ssh_key_file = '/root/.ssh/r10k_rsa'
exec { 'create r10k ssh key' :
command => "/usr/bin/ssh-keygen -t rsa -b 2048 -C 'r10k' -f ${r10k_ssh_key_file} -q -N ''",
creates => $r10k_ssh_key_file,
}
if !empty($gms_api_token) {
git_deploy_key { "add_deploy_key_to_puppet_control-${::fqdn}":
ensure => present,
name => $::fqdn,
path => "${r10k_ssh_key_file}.pub",
token => $gms_api_token,
project_name => 'puppet/control-repo',
server_url => hiera('gms_server_url'),
provider => $git_management_system,
}
git_webhook { "web_post_receive_webhook-${::fqdn}" :
ensure => present,
webhook_url => "https://${username}:${password}@${::fqdn}:8088/payload",
token => $gms_api_token,
project_name => 'puppet/control-repo',
server_url => hiera('gms_server_url'),
provider => $git_management_system,
disable_ssl_verify => true,
}
}
}

View File

@ -1,14 +0,0 @@
class profile::git_webhook::zack_r10k_webhook_disable {
file { '/etc/webhook.yaml' :
ensure => absent,
notify => Exec['stop and disable webhook service'],
}
exec { 'stop and disable webhook service' :
command => '/opt/puppetlabs/puppet/bin/puppet resource service webhook ensure=stopped enable=false',
logoutput => true,
refreshonly => true,
}
}

View File

@ -1,5 +0,0 @@
module Puppet::Parser::Functions
newfunction(:puppet_master_classifer_settings, :type => :rvalue) do |args|
function_parseyaml([function_file([File.join(lookupvar('settings::confdir').to_s, 'classifier.yaml')])])
end
end

View File

@ -1,6 +1,6 @@
class role::all_in_one_pe {
include profile::puppetmaster
include profile::git_webhook
include pe_code_manager_webhook
}

View File

@ -1,6 +0,0 @@
class role::all_in_one_pe_2015_2 {
include profile::puppetmaster
include profile::git_webhook
}