Skip to content

Add task and update configure plan to allow for ldap configuration on… #253

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
May 13, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 13 additions & 1 deletion documentation/install.md
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,19 @@ Example params.json Bolt parameters file (shown: Extra Large with DR):
}
```

Review the [peadm::install plan](../plans/install.pp) to learn about more advanced installation options. It is possible to supply an ssh private key and git clone URL for a control-repo as part of installation, for example.
Example params.json Bolt parameters file (shown: Standard):

```json
{
"primary_host": "pe-xl-core-0.lab1.puppet.vm",

"console_password": "puppetlabs",
"dns_alt_names": [ "puppet", "puppet.lab1.puppet.vm" ],
"version": "2021.5.0",
}
```

Review the [peadm::install plan](../plans/install.pp) to learn about more advanced installation options. For example, it is possible to: supply an ssh private key and git clone URL for a control-repo as part of installation; supply the LDAP configuration data for PE; and similar complete automation tie-ins.

## Offline usage

Expand Down
7 changes: 7 additions & 0 deletions plans/install.pp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@
# specified, PEAdm will attempt to download PE installation media from its
# standard public source. When specified, PEAdm will download directly from the
# URL given.
# @param ldap_config
# If specified, configures PE RBAC DS with the supplied configuration hash.
# The parameter should be set to a valid set of connection settings as
# documented for the PE RBAC /ds endpoint. See:
# https://puppet.com/docs/pe/latest/rbac_api_v1_directory.html#put_ds-request_format
#
plan peadm::install (
# Standard
Expand All @@ -38,6 +43,7 @@
Optional[String] $internal_compiler_a_pool_address = undef,
Optional[String] $internal_compiler_b_pool_address = undef,
Optional[Hash] $pe_conf_data = { },
Optional[Peadm::Ldap_config] $ldap_config = undef,

# Code Manager
Optional[String] $r10k_remote = undef,
Expand Down Expand Up @@ -109,6 +115,7 @@
internal_compiler_a_pool_address => $internal_compiler_a_pool_address,
internal_compiler_b_pool_address => $internal_compiler_b_pool_address,
deploy_environment => $deploy_environment,
ldap_config => $ldap_config,

# Other
stagingdir => $stagingdir,
Expand Down
29 changes: 24 additions & 5 deletions plans/subplans/configure.pp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@
# A load balancer address directing traffic to any of the "B" pool
# compilers. This is used for DR configuration in large and extra large
# architectures.
# @param ldap_config
# This hash contains the options necessary for configuring the LDAP
# connection on the main server.
#
plan peadm::subplans::configure (
# Standard
Expand All @@ -27,11 +30,12 @@
Optional[Peadm::SingleTargetSpec] $replica_postgresql_host = undef,

# Common Configuration
String $compiler_pool_address = $primary_host.peadm::certname(),
Optional[String] $internal_compiler_a_pool_address = undef,
Optional[String] $internal_compiler_b_pool_address = undef,
Optional[String] $token_file = undef,
Optional[String] $deploy_environment = undef,
String $compiler_pool_address = $primary_host.peadm::certname(),
Optional[String] $internal_compiler_a_pool_address = undef,
Optional[String] $internal_compiler_b_pool_address = undef,
Optional[String] $token_file = undef,
Optional[String] $deploy_environment = undef,
Optional[Peadm::Ldap_config] $ldap_config = undef,

# Other
String $stagingdir = '/tmp',
Expand Down Expand Up @@ -105,6 +109,21 @@
)
}

if $ldap_config {
# Run the task to configure ldap
$ldap_result = run_task('peadm::pe_ldap_config', $primary_target,
pe_main => $primary_target.peadm::certname(),
ldap_config => $ldap_config,
'_catch_errors' => true,
)

# If there was an LDAP failure, note it and continue.
if $ldap_result[0].error {
out::message('There was a problem with the LDAP configuration, configuration must be completed manually.')
out::message($ldap_result.to_data)
}
}

# Run Puppet everywhere to pick up last remaining config tweaks
run_task('peadm::puppet_runonce', peadm::flatten_compact([
$primary_target,
Expand Down
17 changes: 17 additions & 0 deletions tasks/pe_ldap_config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"description": "Set the ldap config in the PE console",
"parameters": {
"ldap_config": {
"type": "Peadm::Ldap_config",
"description": "The hash of options for ldap."
},
"pe_main": {
"type": "String",
"description": "The PE Main server"
}
},
"input_method": "stdin",
"implementations": [
{"name": "pe_ldap_config.rb"}
]
}
63 changes: 63 additions & 0 deletions tasks/pe_ldap_config.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
#!/opt/puppetlabs/puppet/bin/ruby
# Puppet Task Name: pe_ldap_config
#
# Update the LDAP configuration
#

require 'json'
require 'net/http'
require 'open3'

def main
params = JSON.parse(STDIN.read)
data = params['ldap_config']
pe_main = params['pe_main']

caf = ['/opt/puppetlabs/bin/puppet', 'config', 'print', 'localcacert']
cafout, cafstatus = Open3.capture2(*caf)
unless cafstatus.success?
raise 'Could not get the CA file path.'
end

cert = ['/opt/puppetlabs/bin/puppet', 'config', 'print', 'hostcert']
certout, certstatus = Open3.capture2(*cert)
unless certstatus.success?
raise 'Could not get the Cert file path.'
end

key = ['/opt/puppetlabs/bin/puppet', 'config', 'print', 'hostprivkey']
keyout, keystatus = Open3.capture2(*key)
unless keystatus.success?
raise 'Could not get the Key file path.'
end

uri = URI("https://#{pe_main}:4433/rbac-api/v1/ds")
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
http.ca_file = cafout.strip
http.cert = OpenSSL::X509::Certificate.new(File.read(certout.strip))
http.key = OpenSSL::PKey::RSA.new(File.read(keyout.strip))

req = Net::HTTP::Put.new(uri, 'Content-type' => 'application/json')
req.body = data.to_json

resp = http.request(req)

puts resp.body
raise "API response code #{resp.code}" unless resp.code == '200'
end

begin
main
rescue => e
result = {
'_error' => {
'msg' => e.message,
'kind' => 'RuntimeError',
'details' => e.message,
}
}
puts result.to_json
exit(1)
end
25 changes: 25 additions & 0 deletions types/ldap_config.pp
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
type Peadm::Ldap_config = Struct[{
base_dn => String,
connect_timeout => Integer,
disable_ldap_matching_rule_in_chain => Boolean,
display_name => String,
group_lookup_attr => String,
group_member_attr => String,
group_name_attr => String,
group_object_class => String,
Optional[group_rdn] => Optional[String],
Optional[help_link] => Optional[String],
hostname => String,
Optional[login] => Optional[String],
Optional[password] => Optional[String],
port => Integer,
search_nested_groups => Boolean,
ssl => Boolean,
ssl_hostname_validation => Boolean,
ssl_wildcard_validation => Boolean,
start_tls => Boolean,
user_display_name_attr => String,
user_email_attr => String,
user_lookup_attr => String,
Optional[user_rdn] => Optional[String],
}]