Skip to content

Commit

Permalink
Add support for custom certificates to old PuppetDB
Browse files Browse the repository at this point in the history
This implementation is based on a suggestion from Josh Cooper:
```
Yeah can use
https://www.rubydoc.info/gems/puppet/Puppet/X509/CertProvider to load
x509 certificates and then create a custom ssl context using
https://www.rubydoc.info/gems/puppet/Puppet/SSL/SSLProvider, and pass it
into any of the http client methods, e.g.
x509 = Puppet::X509::CertProvider.new
cacerts = x509.load_cacerts_from_pem(File.read('...', encoding: Encoding::UTF_8))
prov = Puppet::SSL::Provider.new
ctx = prov.create_context(cacerts: cacerts, revocation: false, ...)
response = Puppet.runtime[:http].get(URI('https://...', options: { ssl_context: ctx })
```

Slack link:
https://puppetcommunity.slack.com/archives/C0W1X7ZAL/p1652464163822119?thread_ts=1652453262.819079&cid=C0W1X7ZAL
  • Loading branch information
bastelfreak committed Jun 9, 2022
1 parent 53c1d53 commit 3d31368
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 8 deletions.
14 changes: 10 additions & 4 deletions lib/puppet/catalog-diff/compilecatalog.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@ class CompileCatalog

attr_reader :node_name

def initialize(node_name, save_directory, server, certless, catalog_from_puppetdb, puppetdb)
def initialize(node_name, save_directory, server, certless, catalog_from_puppetdb, puppetdb, puppetdb_tls_cert, puppetdb_tls_key, puppetdb_tls_ca)
@node_name = node_name
catalog = if catalog_from_puppetdb
get_catalog_from_puppetdb(node_name, server, puppetdb)
get_catalog_from_puppetdb(node_name, server, puppetdb, puppetdb_tls_cert, puppetdb_tls_key, puppetdb_tls_ca)
else
catalog = compile_catalog(node_name, server, certless)
clean_sensitive_parameters!(catalog)
Expand Down Expand Up @@ -45,7 +45,7 @@ def lookup_environment(node_name)
node.environment
end

def get_catalog_from_puppetdb(node_name, server, puppetdb)
def get_catalog_from_puppetdb(node_name, server, puppetdb, puppetdb_tls_cert, puppetdb_tls_key, puppetdb_tls_ca)
Puppet.debug("Getting PuppetDB catalog for #{node_name} from #{puppetdb}")
query = ['and', ['=', 'certname', node_name.to_s]]
_server, environment = server.split('/')
Expand All @@ -54,7 +54,13 @@ def get_catalog_from_puppetdb(node_name, server, puppetdb)
json_query = URI.encode_www_form_component(query.to_json)
request_url = URI("#{puppetdb}/pdb/query/v4/catalogs?query=#{json_query}")
headers = { 'Accept-Content' => 'application/json'}
ret = Puppet.runtime[:http].get(request_url, headers: headers)
x509 = Puppet::X509::CertProvider.new
cacerts = x509.load_cacerts_from_pem(File.read(puppetdb_tls_ca, encoding: Encoding::UTF_8))
client_cert = x509.load_client_cert_from_pem(File.read(puppetdb_tls_cert, encoding: Encoding::UTF_8))
private_key = x509.load_private_key_from_pem(File.read(puppetdb_tls_key, encoding: Encoding::UTF_8))
prov = Puppet::SSL::SSLProvider.new
ssl_context = prov.create_context(revocation: false, cacerts: cacerts, private_key: private_key, client_cert: client_cert, include_system_store: true, crls: [])
ret = Puppet.runtime[:http].get(request_url, headers: headers, options: {ssl_context: ssl_context})
unless ret.success?
raise "HTTP request to PuppetDB failed with: HTTP #{ret.code} - #{ret.reason}"
end
Expand Down
16 changes: 16 additions & 0 deletions lib/puppet/face/catalog/diff.rb
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,19 @@
default_to { puppetdb_url }
end

option '--old_puppetdb_tls_cert=' do
summary 'Optional absolute path to a client certificate to authenticate against the old PuppetDB. If not provided, the Puppet Agent default certificate will be used.'
EOT
end

option '--old_puppetdb_tls_key=' do
summary 'Optional absolute path to a TLS private key in pem format. If not provided, the Puppet Agent default key will be used.'
end

option '--old_puppetdb_tls_ca=' do
summary 'Optional absolute path to a CA pem file. If not provided, the Puppet Agent CA will be used.'
end

option '--new_puppetdb=' do
description <<-'EOT'
Used to download new catalogs.
Expand Down Expand Up @@ -196,6 +209,9 @@
old_catalog_from_puppetdb: options[:old_catalog_from_puppetdb],
new_catalog_from_puppetdb: options[:new_catalog_from_puppetdb],
old_puppetdb: options[:old_puppetdb],
old_puppetdb_tls_cert: options[:old_puppetdb_tls_cert],
old_puppetdb_tls_key: options[:old_puppetdb_tls_key],
old_puppetdb_tls_ca: options[:old_puppetdb_tls_ca],
new_puppetdb: options[:new_puppetdb],
node_list: options[:node_list]
)
Expand Down
25 changes: 22 additions & 3 deletions lib/puppet/face/catalog/pull.rb
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,23 @@
description <<-'EOT'
URI to PuppetDB to find nodes if --node_list is not set.
Also used to download old catalogs.
Defaults to first server in puppetdb.conf
Defaults to first server in puppetdb.conf'
EOT
default_to { puppetdb_url }
end

option '--old_puppetdb_tls_cert=' do
summary 'Optional absolute path to a client certificate to authenticate against the old PuppetDB. If not provided, the Puppet Agent default certificate will be used.'
end

option '--old_puppetdb_tls_key=' do
summary 'Optional absolute path to a TLS private key in pem format. If not provided, the Puppet Agent default key will be used.'
end

option '--old_puppetdb_tls_ca=' do
summary 'Optional absolute path to a CA pem file. If not provided, the Puppet Agent CA will be used.'
end

option '--new_puppetdb=' do
description <<-'EOT'
Used to download new catalogs.
Expand Down Expand Up @@ -87,6 +99,7 @@
require File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'catalog-diff', 'searchfacts.rb'))
require File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'catalog-diff', 'compilecatalog.rb'))
options[:puppetdb] = options[:old_puppetdb]

nodes = if options[:node_list].nil?
Puppet::CatalogDiff::SearchFacts.new(args).find_nodes(options)
else
Expand All @@ -111,7 +124,10 @@
master_server: options[:old_server],
certless: options[:certless],
catalog_from_puppetdb: options[:old_catalog_from_puppetdb],
puppetdb: options[:old_puppetdb]
puppetdb: options[:old_puppetdb],
puppetdb_tls_cert: options[:old_puppetdb_tls_cert],
puppetdb_tls_key: options[:old_puppetdb_tls_key],
puppetdb_tls_ca: options[:old_puppetdb_tls_ca]
)
new_server = Puppet::Face[:catalog, '0.0.1'].seed(
catalog2, node_name,
Expand All @@ -133,7 +149,10 @@
master_server: options[:old_server],
certless: options[:certless],
catalog_from_puppetdb: options[:old_catalog_from_puppetdb],
puppetdb: options[:old_puppetdb]
puppetdb: options[:old_puppetdb],
puppetdb_tls_cert: options[:old_puppetdb_tls_cert],
puppetdb_tls_key: options[:old_puppetdb_tls_key],
puppetdb_tls_ca: options[:old_puppetdb_tls_ca]
)
end
mutex.synchronize { compiled_nodes + old_server[:compiled_nodes] }
Expand Down
18 changes: 17 additions & 1 deletion lib/puppet/face/catalog/seed.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,19 @@
default_to { puppetdb_url }
end

option '--puppetdb_tls_cert=' do
summary 'Optional absolute path to a client certificate to authenticate against the old PuppetDB. If not provided, the Puppet Agent default certificate will be used.'
end

option '--puppetdb_tls_key=' do
summary 'Optional absolute path to a TLS private key in pem format. If not provided, the Puppet Agent default key will be used.'
EOT
end

option '--puppetdb_tls_ca=' do
summary 'Optional absolute path to a CA pem file.If not provided, the Puppet Agent CA will be used.'
end

description <<-'EOT'
This action is used to seed a series of catalogs to then be compared with diff
EOT
Expand Down Expand Up @@ -72,7 +85,10 @@
options[:master_server],
options[:certless],
options[:catalog_from_puppetdb],
options[:puppetdb]
options[:puppetdb],
options[:puppetdb_tls_cert],
options[:puppetdb_tls_key],
options[:puppetdb_tls_ca]
)
mutex.synchronize { compiled_nodes << node_name }
rescue Exception => e
Expand Down

0 comments on commit 3d31368

Please sign in to comment.