Class: Puppet::CatalogDiff::CompileCatalog
- Inherits:
-
Object
- Object
- Puppet::CatalogDiff::CompileCatalog
- Includes:
- Preprocessor
- Defined in:
- lib/puppet/catalog-diff/compilecatalog.rb
Overview
Puppet::CatalogDiff::CompileCatalog allows to retrieve a catalog, using v3/catalog, v4/catalog or PuppetDB
Instance Attribute Summary collapse
-
#node_name ⇒ Object
readonly
Returns the value of attribute node_name.
Instance Method Summary collapse
- #clean_nested_sensitive_parameters!(catalog) ⇒ Object
- #clean_sensitive_parameters!(catalog) ⇒ Object
- #compile_catalog(node_name, server, certless, tls_cert, tls_key, tls_ca) ⇒ Object
- #get_catalog_from_puppetdb(node_name, server, puppetdb, puppetdb_tls_cert, puppetdb_tls_key, puppetdb_tls_ca) ⇒ Object
-
#initialize(node_name, save_directory, server, certless, catalog_from_puppetdb, puppetdb, puppetdb_tls_cert, puppetdb_tls_key, puppetdb_tls_ca, puppetserver_tls_cert, puppetserver_tls_key, puppetserver_tls_ca) ⇒ CompileCatalog
constructor
A new instance of CompileCatalog.
- #lookup_environment(node_name) ⇒ Object
- #redact_sensitive(data) ⇒ Object
- #render_pson(catalog) ⇒ Object
- #save_catalog_to_disk(save_directory, node_name, catalog, extention) ⇒ Object
Constructor Details
#initialize(node_name, save_directory, server, certless, catalog_from_puppetdb, puppetdb, puppetdb_tls_cert, puppetdb_tls_key, puppetdb_tls_ca, puppetserver_tls_cert, puppetserver_tls_key, puppetserver_tls_ca) ⇒ CompileCatalog
Returns a new instance of CompileCatalog.
15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
# File 'lib/puppet/catalog-diff/compilecatalog.rb', line 15 def initialize(node_name, save_directory, server, certless, catalog_from_puppetdb, puppetdb, puppetdb_tls_cert, puppetdb_tls_key, puppetdb_tls_ca, puppetserver_tls_cert, puppetserver_tls_key, puppetserver_tls_ca) @node_name = node_name catalog = if catalog_from_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, puppetserver_tls_cert, puppetserver_tls_key, puppetserver_tls_ca) clean_sensitive_parameters!(catalog) clean_nested_sensitive_parameters!(catalog) catalog end catalog = render_pson(catalog) begin save_catalog_to_disk(save_directory, node_name, catalog, 'pson') rescue Exception => e Puppet.err("Server returned invalid catalog for #{node_name}") save_catalog_to_disk(save_directory, node_name, catalog, 'error') raise e. if catalog =~ %r{.document_type.:.Catalog.} raise catalog end end |
Instance Attribute Details
#node_name ⇒ Object (readonly)
Returns the value of attribute node_name.
13 14 15 |
# File 'lib/puppet/catalog-diff/compilecatalog.rb', line 13 def node_name @node_name end |
Instance Method Details
#clean_nested_sensitive_parameters!(catalog) ⇒ Object
143 144 145 146 147 148 |
# File 'lib/puppet/catalog-diff/compilecatalog.rb', line 143 def clean_nested_sensitive_parameters!(catalog) # Resources can also contain sensitive data nested deep in hashes/arrays catalog['resources'].each do |resource| redact_sensitive(resource['parameters']) if resource.key? 'parameters' end end |
#clean_sensitive_parameters!(catalog) ⇒ Object
130 131 132 133 134 135 136 137 138 139 140 141 |
# File 'lib/puppet/catalog-diff/compilecatalog.rb', line 130 def clean_sensitive_parameters!(catalog) catalog['resources'].map! do |resource| if resource.key? 'sensitive_parameters' resource['sensitive_parameters'].each do |p| hash = Digest::SHA256.hexdigest Marshal.dump(resource['parameters'][p]) resource['parameters'][p] = "Sensitive [hash #{hash}]" end resource.delete('sensitive_parameters') end resource end end |
#compile_catalog(node_name, server, certless, tls_cert, tls_key, tls_ca) ⇒ Object
71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 |
# File 'lib/puppet/catalog-diff/compilecatalog.rb', line 71 def compile_catalog(node_name, server, certless, tls_cert, tls_key, tls_ca) Puppet.debug("Compiling catalog for #{node_name}") server, environment = server.split('/') environment ||= lookup_environment(node_name) server, port = server.split(':') port ||= '8140' headers = { 'Accept' => 'pson', } if certless endpoint = '/puppet/v4/catalog' headers['Content-Type'] = 'text/json' body = { certname: node_name, environment: environment, persistence: { facts: false, catalog: false, }, options: { prefer_requested_environment: true, }, } else endpoint = "/puppet/v3/catalog/#{node_name}?environment=#{environment}" end uri = URI("https://#{server}:#{port}#{endpoint}") ssl_context = Puppet::CatalogDiff::Tlsfactory.ssl_context(tls_cert, tls_key, tls_ca) begin ret = if certless Puppet.runtime[:http].post(uri, body.to_json, headers: headers, options: { ssl_context: ssl_context }) else Puppet.runtime[:http].get(uri, headers: headers, options: { ssl_context: ssl_context }) end raise "HTTP request to Puppetserver #{server} failed with: HTTP #{ret.code} - #{ret.reason}" unless ret.success? rescue Exception => e raise "Failed to retrieve catalog for #{node_name} from #{server} in environment #{environment}: #{e.}" end begin catalog = PSON.parse(ret.body) rescue PSON::ParserError => e raise "Error parsing json output of puppet catalog query for #{node_name}: #{e.}. Content: #{ret.body}" end raise catalog['message'] if catalog.key?('issue_kind') catalog = catalog['catalog'] if certless catalog end |
#get_catalog_from_puppetdb(node_name, server, puppetdb, puppetdb_tls_cert, puppetdb_tls_key, puppetdb_tls_ca) ⇒ Object
49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
# File 'lib/puppet/catalog-diff/compilecatalog.rb', line 49 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('/') environment ||= lookup_environment(node_name) query.concat([['=', 'environment', environment]]) 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' } ssl_context = Puppet::CatalogDiff::Tlsfactory.ssl_context(puppetdb_tls_cert, puppetdb_tls_key, puppetdb_tls_ca) ret = Puppet.runtime[:http].get(request_url, headers: headers, options: { ssl_context: ssl_context }) raise "HTTP request to PuppetDB failed with: HTTP #{ret.code} - #{ret.reason}" unless ret.success? begin catalog = PSON.parse(ret.body) rescue PSON::ParserError => e raise "Error parsing json output of puppetdb catalog query for #{node_name}: #{e.}\ncontent: #{ret.body}" end convert_pdb(catalog) end |
#lookup_environment(node_name) ⇒ Object
37 38 39 40 41 42 43 44 45 46 47 |
# File 'lib/puppet/catalog-diff/compilecatalog.rb', line 37 def lookup_environment(node_name) # Compile the catalog with the last environment used according to the yaml terminus # The following is a hack as I can't pass :mode => master in the 2.7 series node = Puppet::Face[:node, '0.0.1'].find(node_name, terminus: 'yaml') raise "Error retrieving node object from yaml terminus #{node_name}" unless node Puppet.debug("Found environment #{node.environment} for node #{node_name}") raise "The node retrieved from yaml terminus is a mismatch node returned was (#{node.parameters['clientcert']})" if node.parameters['clientcert'] != node_name node.environment end |
#redact_sensitive(data) ⇒ Object
150 151 152 153 154 155 156 157 158 159 160 161 162 163 |
# File 'lib/puppet/catalog-diff/compilecatalog.rb', line 150 def redact_sensitive(data) if data.is_a?(Hash) && data.key?('__ptype') data[:catalog_diff_hash] = Digest::SHA256.hexdigest Marshal.dump(data['__pvalue']) data.reject! { |k| %w[__ptype __pvalue].include?(k) } elsif data.is_a? Hash data.each do |_k, v| redact_sensitive(v) if v.is_a?(Hash) || v.is_a?(Array) end elsif data.is_a? Array data.each do |v| redact_sensitive(v) if v.is_a?(Hash) || v.is_a?(Array) end end end |
#render_pson(catalog) ⇒ Object
123 124 125 126 127 128 |
# File 'lib/puppet/catalog-diff/compilecatalog.rb', line 123 def render_pson(catalog) pson = PSON.pretty_generate(catalog, allow_nan: true, max_nesting: false) raise "Could not render catalog as pson, #{catalog}" unless pson pson end |
#save_catalog_to_disk(save_directory, node_name, catalog, extention) ⇒ Object
165 166 167 168 169 170 171 |
# File 'lib/puppet/catalog-diff/compilecatalog.rb', line 165 def save_catalog_to_disk(save_directory, node_name, catalog, extention) File.open("#{save_directory}/#{node_name}.#{extention}", 'w') do |f| f.write(catalog) end rescue Exception => e raise "Failed to save catalog for #{node_name} in #{save_directory}: #{e.}" end |