bolt 0.23.0 → 0.24.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of bolt might be problematic. Click here for more details.

Files changed (192) hide show
  1. checksums.yaml +4 -4
  2. data/bolt-modules/boltlib/lib/puppet/functions/apply_prep.rb +5 -2
  3. data/bolt-modules/boltlib/lib/puppet/functions/puppetdb_query.rb +5 -1
  4. data/bolt-modules/boltlib/lib/puppet/functions/run_task.rb +5 -8
  5. data/lib/bolt/applicator.rb +11 -8
  6. data/lib/bolt/boltdir.rb +13 -5
  7. data/lib/bolt/catalog.rb +22 -47
  8. data/lib/bolt/config.rb +1 -26
  9. data/lib/bolt/executor.rb +1 -1
  10. data/lib/bolt/outputter.rb +0 -9
  11. data/lib/bolt/outputter/human.rb +29 -14
  12. data/lib/bolt/outputter/json.rb +12 -1
  13. data/lib/bolt/pal.rb +12 -10
  14. data/lib/bolt/target.rb +0 -6
  15. data/lib/bolt/task.rb +53 -10
  16. data/lib/bolt/transport/base.rb +1 -6
  17. data/lib/bolt/transport/local.rb +11 -13
  18. data/lib/bolt/transport/local/shell.rb +2 -2
  19. data/lib/bolt/transport/ssh.rb +16 -11
  20. data/lib/bolt/transport/winrm.rb +8 -11
  21. data/lib/bolt/version.rb +1 -1
  22. data/lib/bolt_ext/schemas/task.json +12 -5
  23. data/libexec/apply_catalog.rb +3 -1
  24. data/libexec/bolt_catalog +4 -0
  25. data/vendored/puppet/lib/puppet.rb +2 -1
  26. data/vendored/puppet/lib/puppet/application/agent.rb +2 -6
  27. data/vendored/puppet/lib/puppet/application/apply.rb +100 -60
  28. data/vendored/puppet/lib/puppet/application/cert.rb +26 -291
  29. data/vendored/puppet/lib/puppet/application/device.rb +0 -5
  30. data/vendored/puppet/lib/puppet/application/lookup.rb +1 -1
  31. data/vendored/puppet/lib/puppet/application/ssl.rb +133 -0
  32. data/vendored/puppet/lib/puppet/application_support.rb +1 -2
  33. data/vendored/puppet/lib/puppet/configurer.rb +34 -50
  34. data/vendored/puppet/lib/puppet/configurer/downloader.rb +1 -1
  35. data/vendored/puppet/lib/puppet/configurer/plugin_handler.rb +1 -1
  36. data/vendored/puppet/lib/puppet/daemon.rb +1 -1
  37. data/vendored/puppet/lib/puppet/defaults.rb +40 -117
  38. data/vendored/puppet/lib/puppet/face/epp.rb +2 -2
  39. data/vendored/puppet/lib/puppet/face/help.rb +21 -7
  40. data/vendored/puppet/lib/puppet/face/node/clean.rb +14 -10
  41. data/vendored/puppet/lib/puppet/feature/base.rb +7 -23
  42. data/vendored/puppet/lib/puppet/feature/eventlog.rb +1 -1
  43. data/vendored/puppet/lib/puppet/file_serving/base.rb +2 -2
  44. data/vendored/puppet/lib/puppet/file_serving/fileset.rb +1 -1
  45. data/vendored/puppet/lib/puppet/file_serving/metadata.rb +2 -2
  46. data/vendored/puppet/lib/puppet/functions.rb +133 -0
  47. data/vendored/puppet/lib/puppet/functions/eyaml_lookup_key.rb +4 -5
  48. data/vendored/puppet/lib/puppet/functions/filter.rb +7 -6
  49. data/vendored/puppet/lib/puppet/functions/new.rb +37 -53
  50. data/vendored/puppet/lib/puppet/functions/warning.rb +1 -1
  51. data/vendored/puppet/lib/puppet/functions/yaml_data.rb +4 -5
  52. data/vendored/puppet/lib/puppet/gettext/config.rb +1 -1
  53. data/vendored/puppet/lib/puppet/graph.rb +0 -2
  54. data/vendored/puppet/lib/puppet/indirector/catalog/json.rb +14 -3
  55. data/vendored/puppet/lib/puppet/indirector/catalog/yaml.rb +0 -16
  56. data/vendored/puppet/lib/puppet/indirector/certificate/file.rb +0 -1
  57. data/vendored/puppet/lib/puppet/indirector/facts/yaml.rb +4 -2
  58. data/vendored/puppet/lib/puppet/indirector/key/file.rb +1 -6
  59. data/vendored/puppet/lib/puppet/indirector/node/exec.rb +1 -3
  60. data/vendored/puppet/lib/puppet/indirector/node/yaml.rb +0 -6
  61. data/vendored/puppet/lib/puppet/indirector/request.rb +1 -1
  62. data/vendored/puppet/lib/puppet/indirector/ssl_file.rb +3 -44
  63. data/vendored/puppet/lib/puppet/indirector/yaml.rb +4 -4
  64. data/vendored/puppet/lib/puppet/info_service/task_information_service.rb +7 -3
  65. data/vendored/puppet/lib/puppet/loaders.rb +1 -0
  66. data/vendored/puppet/lib/puppet/module/task.rb +198 -29
  67. data/vendored/puppet/lib/puppet/module_tool/applications/unpacker.rb +1 -1
  68. data/vendored/puppet/lib/puppet/network/format_support.rb +13 -8
  69. data/vendored/puppet/lib/puppet/network/formats.rb +93 -2
  70. data/vendored/puppet/lib/puppet/network/http/api/indirected_routes.rb +10 -3
  71. data/vendored/puppet/lib/puppet/node/facts.rb +11 -1
  72. data/vendored/puppet/lib/puppet/parser/catalog_compiler.rb +56 -0
  73. data/vendored/puppet/lib/puppet/parser/compiler.rb +3 -1
  74. data/vendored/puppet/lib/puppet/parser/functions.rb +3 -1
  75. data/vendored/puppet/lib/puppet/parser/functions/filter.rb +1 -1
  76. data/vendored/puppet/lib/puppet/parser/functions/generate.rb +1 -1
  77. data/vendored/puppet/lib/puppet/parser/functions/sprintf.rb +12 -1
  78. data/vendored/puppet/lib/puppet/parser/functions/tagged.rb +1 -4
  79. data/vendored/puppet/lib/puppet/parser/scope.rb +1 -1
  80. data/vendored/puppet/lib/puppet/parser/script_compiler.rb +7 -2
  81. data/vendored/puppet/lib/puppet/pops/evaluator/deferred_resolver.rb +5 -3
  82. data/vendored/puppet/lib/puppet/pops/evaluator/runtime3_converter.rb +23 -4
  83. data/vendored/puppet/lib/puppet/pops/evaluator/runtime3_support.rb +3 -4
  84. data/vendored/puppet/lib/puppet/pops/functions/dispatch.rb +4 -0
  85. data/vendored/puppet/lib/puppet/pops/issues.rb +8 -0
  86. data/vendored/puppet/lib/puppet/pops/loader/loader.rb +2 -2
  87. data/vendored/puppet/lib/puppet/pops/loader/loader_paths.rb +3 -1
  88. data/vendored/puppet/lib/puppet/pops/loader/module_loaders.rb +30 -9
  89. data/vendored/puppet/lib/puppet/pops/loader/ruby_legacy_function_instantiator.rb +62 -0
  90. data/vendored/puppet/lib/puppet/pops/loader/static_loader.rb +0 -1
  91. data/vendored/puppet/lib/puppet/pops/loader/task_instantiator.rb +13 -70
  92. data/vendored/puppet/lib/puppet/pops/loaders.rb +19 -29
  93. data/vendored/puppet/lib/puppet/pops/lookup/hiera_config.rb +1 -1
  94. data/vendored/puppet/lib/puppet/pops/model/model_label_provider.rb +4 -1
  95. data/vendored/puppet/lib/puppet/pops/pcore.rb +10 -33
  96. data/vendored/puppet/lib/puppet/pops/serialization.rb +2 -0
  97. data/vendored/puppet/lib/puppet/pops/serialization/from_data_converter.rb +2 -1
  98. data/vendored/puppet/lib/puppet/pops/serialization/to_data_converter.rb +11 -3
  99. data/vendored/puppet/lib/puppet/pops/serialization/to_stringified_converter.rb +226 -0
  100. data/vendored/puppet/lib/puppet/pops/types/p_object_type.rb +3 -0
  101. data/vendored/puppet/lib/puppet/pops/validation/checker4_0.rb +97 -47
  102. data/vendored/puppet/lib/puppet/pops/validation/validator_factory_4_0.rb +7 -8
  103. data/vendored/puppet/lib/puppet/property/keyvalue.rb +70 -8
  104. data/vendored/puppet/lib/puppet/provider/aix_object.rb +483 -0
  105. data/vendored/puppet/lib/puppet/provider/file/windows.rb +1 -1
  106. data/vendored/puppet/lib/puppet/provider/group/aix.rb +51 -112
  107. data/vendored/puppet/lib/puppet/provider/package/gem.rb +1 -1
  108. data/vendored/puppet/lib/puppet/provider/package/pip.rb +1 -1
  109. data/vendored/puppet/lib/puppet/provider/package/puppet_gem.rb +1 -1
  110. data/vendored/puppet/lib/puppet/provider/package/rpm.rb +1 -1
  111. data/vendored/puppet/lib/puppet/provider/package/windows/package.rb +1 -1
  112. data/vendored/puppet/lib/puppet/provider/package/zypper.rb +1 -1
  113. data/vendored/puppet/lib/puppet/provider/service/systemd.rb +1 -1
  114. data/vendored/puppet/lib/puppet/provider/service/windows.rb +37 -40
  115. data/vendored/puppet/lib/puppet/provider/user/aix.rb +142 -254
  116. data/vendored/puppet/lib/puppet/resource.rb +20 -3
  117. data/vendored/puppet/lib/puppet/resource/catalog.rb +2 -12
  118. data/vendored/puppet/lib/puppet/rest/routes.rb +97 -34
  119. data/vendored/puppet/lib/puppet/settings.rb +1 -1
  120. data/vendored/puppet/lib/puppet/settings/file_setting.rb +1 -1
  121. data/vendored/puppet/lib/puppet/ssl/base.rb +1 -9
  122. data/vendored/puppet/lib/puppet/ssl/certificate_request.rb +1 -13
  123. data/vendored/puppet/lib/puppet/ssl/certificate_request_attributes.rb +1 -1
  124. data/vendored/puppet/lib/puppet/ssl/host.rb +114 -232
  125. data/vendored/puppet/lib/puppet/ssl/key.rb +1 -5
  126. data/vendored/puppet/lib/puppet/ssl/oids.rb +1 -1
  127. data/vendored/puppet/lib/puppet/test/test_helper.rb +0 -4
  128. data/vendored/puppet/lib/puppet/transaction/event.rb +3 -7
  129. data/vendored/puppet/lib/puppet/transaction/persistence.rb +1 -1
  130. data/vendored/puppet/lib/puppet/type/exec.rb +18 -16
  131. data/vendored/puppet/lib/puppet/type/file.rb +3 -3
  132. data/vendored/puppet/lib/puppet/type/file/source.rb +20 -7
  133. data/vendored/puppet/lib/puppet/type/group.rb +3 -5
  134. data/vendored/puppet/lib/puppet/type/notify.rb +1 -1
  135. data/vendored/puppet/lib/puppet/type/package.rb +2 -5
  136. data/vendored/puppet/lib/puppet/type/schedule.rb +1 -1
  137. data/vendored/puppet/lib/puppet/type/service.rb +3 -6
  138. data/vendored/puppet/lib/puppet/type/tidy.rb +1 -1
  139. data/vendored/puppet/lib/puppet/type/user.rb +13 -20
  140. data/vendored/puppet/lib/puppet/util.rb +8 -9
  141. data/vendored/puppet/lib/puppet/util/execution.rb +3 -3
  142. data/vendored/puppet/lib/puppet/util/feature.rb +61 -39
  143. data/vendored/puppet/lib/puppet/util/log/destinations.rb +1 -1
  144. data/vendored/puppet/lib/puppet/util/rdoc.rb +1 -1
  145. data/vendored/puppet/lib/puppet/util/run_mode.rb +1 -1
  146. data/vendored/puppet/lib/puppet/util/storage.rb +1 -1
  147. data/vendored/puppet/lib/puppet/util/suidmanager.rb +7 -5
  148. data/vendored/puppet/lib/puppet/util/tag_set.rb +1 -1
  149. data/vendored/puppet/lib/puppet/util/tagging.rb +1 -1
  150. data/vendored/puppet/lib/puppet/util/windows.rb +18 -2
  151. data/vendored/puppet/lib/puppet/util/windows/adsi.rb +154 -205
  152. data/vendored/puppet/lib/puppet/util/windows/service.rb +770 -0
  153. data/vendored/puppet/lib/puppet/util/yaml.rb +41 -5
  154. data/vendored/puppet/lib/puppet/version.rb +1 -1
  155. data/vendored/puppet/lib/puppet_pal.rb +280 -24
  156. metadata +8 -38
  157. data/lib/bolt/catalog/compiler.rb +0 -48
  158. data/lib/bolt/catalog/loaders.rb +0 -19
  159. data/vendored/puppet/lib/puppet/application/ca.rb +0 -11
  160. data/vendored/puppet/lib/puppet/application/certificate.rb +0 -17
  161. data/vendored/puppet/lib/puppet/application/certificate_request.rb +0 -7
  162. data/vendored/puppet/lib/puppet/application/certificate_revocation_list.rb +0 -7
  163. data/vendored/puppet/lib/puppet/face/ca.rb +0 -266
  164. data/vendored/puppet/lib/puppet/face/certificate.rb +0 -167
  165. data/vendored/puppet/lib/puppet/face/certificate_request.rb +0 -56
  166. data/vendored/puppet/lib/puppet/face/certificate_revocation_list.rb +0 -56
  167. data/vendored/puppet/lib/puppet/graph/random_prioritizer.rb +0 -16
  168. data/vendored/puppet/lib/puppet/graph/title_hash_prioritizer.rb +0 -16
  169. data/vendored/puppet/lib/puppet/indirector/certificate/ca.rb +0 -9
  170. data/vendored/puppet/lib/puppet/indirector/certificate/disabled_ca.rb +0 -22
  171. data/vendored/puppet/lib/puppet/indirector/certificate_request/ca.rb +0 -22
  172. data/vendored/puppet/lib/puppet/indirector/certificate_request/disabled_ca.rb +0 -22
  173. data/vendored/puppet/lib/puppet/indirector/certificate_revocation_list/ca.rb +0 -8
  174. data/vendored/puppet/lib/puppet/indirector/certificate_revocation_list/disabled_ca.rb +0 -22
  175. data/vendored/puppet/lib/puppet/indirector/certificate_revocation_list/file.rb +0 -8
  176. data/vendored/puppet/lib/puppet/indirector/certificate_revocation_list/rest.rb +0 -11
  177. data/vendored/puppet/lib/puppet/indirector/certificate_status.rb +0 -4
  178. data/vendored/puppet/lib/puppet/indirector/certificate_status/file.rb +0 -91
  179. data/vendored/puppet/lib/puppet/indirector/certificate_status/rest.rb +0 -11
  180. data/vendored/puppet/lib/puppet/indirector/key/ca.rb +0 -16
  181. data/vendored/puppet/lib/puppet/indirector/key/disabled_ca.rb +0 -22
  182. data/vendored/puppet/lib/puppet/indirector/ldap.rb +0 -86
  183. data/vendored/puppet/lib/puppet/indirector/node/ldap.rb +0 -275
  184. data/vendored/puppet/lib/puppet/provider/aixobject.rb +0 -392
  185. data/vendored/puppet/lib/puppet/provider/cron/crontab.rb +0 -297
  186. data/vendored/puppet/lib/puppet/ssl/certificate_authority.rb +0 -475
  187. data/vendored/puppet/lib/puppet/ssl/certificate_authority/autosign_command.rb +0 -45
  188. data/vendored/puppet/lib/puppet/ssl/certificate_authority/interface.rb +0 -324
  189. data/vendored/puppet/lib/puppet/ssl/certificate_factory.rb +0 -219
  190. data/vendored/puppet/lib/puppet/ssl/certificate_revocation_list.rb +0 -111
  191. data/vendored/puppet/lib/puppet/ssl/inventory.rb +0 -55
  192. data/vendored/puppet/lib/puppet/type/cron.rb +0 -480
@@ -12,7 +12,7 @@ class Puppet::Resource
12
12
 
13
13
  include Enumerable
14
14
  attr_accessor :file, :line, :catalog, :exported, :virtual, :strict
15
- attr_reader :type, :title, :parameters, :rich_data_enabled
15
+ attr_reader :type, :title, :parameters
16
16
 
17
17
  # @!attribute [rw] sensitive_parameters
18
18
  # @api private
@@ -76,6 +76,13 @@ class Puppet::Resource
76
76
  "#{@type}[#{@title}]#{to_hash.inspect}"
77
77
  end
78
78
 
79
+ # Produces a Data compliant hash of the resource.
80
+ # The result depends on the --rich_data setting, and the context value
81
+ # for Puppet.lookup(:stringify_rich), that if it is `true` will use the
82
+ # ToStringifiedConverter to produce the value per parameter.
83
+ # (Note that the ToStringifiedConverter output is lossy and should not
84
+ # be used when producing a catalog serialization).
85
+ #
79
86
  def to_data_hash
80
87
  data = {
81
88
  'type' => type,
@@ -89,17 +96,27 @@ class Puppet::Resource
89
96
 
90
97
  data['exported'] ||= false
91
98
 
99
+ # To get stringified parameter values the flag :stringify_rich can be set
100
+ # in the puppet context.
101
+ #
102
+ stringify = Puppet.lookup(:stringify_rich) { false }
103
+ converter = stringify ? Puppet::Pops::Serialization::ToStringifiedConverter.new : nil
104
+
92
105
  params = {}
93
106
  self.to_hash.each_pair do |param, value|
94
107
  # Don't duplicate the title as the namevar
95
108
  unless param == namevar && value == title
96
- params[param.to_s] = Puppet::Resource.value_to_json_data(value)
109
+ if stringify
110
+ params[param.to_s] = converter.convert(value)
111
+ else
112
+ params[param.to_s] = Puppet::Resource.value_to_json_data(value)
113
+ end
97
114
  end
98
115
  end
99
116
 
100
117
  unless params.empty?
101
118
  data['parameters'] = Puppet::Pops::Serialization::ToDataConverter.convert(params, {
102
- :rich_data => environment.rich_data?,
119
+ :rich_data => Puppet.lookup(:rich_data),
103
120
  :symbol_as_string => true,
104
121
  :local_reference => false,
105
122
  :type_by_reference => true,
@@ -377,8 +377,7 @@ class Puppet::Resource::Catalog < Puppet::Graph::SimpleGraph
377
377
  result = @resource_table[title_key]
378
378
  if result.nil?
379
379
  # an instance has to be created in order to construct the unique key used when
380
- # searching for aliases, or when app_management is active and nothing is found in
381
- # which case it is needed by the CapabilityFinder.
380
+ # searching for aliases, or nothing is found as it is needed by the CapabilityFinder.
382
381
  res = Puppet::Resource.new(type, title, { :environment => @environment_instance })
383
382
 
384
383
  # Must check with uniqueness key because of aliases or if resource transforms title in title
@@ -582,16 +581,7 @@ class Puppet::Resource::Catalog < Puppet::Graph::SimpleGraph
582
581
  private
583
582
 
584
583
  def prioritizer
585
- @prioritizer ||= case Puppet[:ordering]
586
- when "title-hash"
587
- Puppet::Graph::TitleHashPrioritizer.new
588
- when "manifest"
589
- Puppet::Graph::SequentialPrioritizer.new
590
- when "random"
591
- Puppet::Graph::RandomPrioritizer.new
592
- else
593
- raise Puppet::DevError, _("Unknown ordering type %{ordering}") % { ordering: Puppet[:ordering] }
594
- end
584
+ @prioritizer = Puppet::Graph::SequentialPrioritizer.new
595
585
  end
596
586
 
597
587
  def create_transaction(options)
@@ -1,8 +1,12 @@
1
1
  require 'puppet/rest/route'
2
+ require 'puppet/network/http_pool'
3
+ require 'puppet/network/http/compression'
2
4
 
3
5
  module Puppet::Rest
4
6
  module Routes
5
7
 
8
+ extend Puppet::Network::HTTP::Compression.module
9
+
6
10
  ACCEPT_ENCODING = 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3'
7
11
 
8
12
  def self.ca
@@ -12,79 +16,138 @@ module Puppet::Rest
12
16
  srv_service: :ca)
13
17
  end
14
18
 
15
- # Make an HTTP request to fetch the named certificate, using the given
16
- # HTTP client.
17
- # @param [Puppet::Rest::Client] client the HTTP client to use to make the request
19
+ # Make an HTTP request to fetch the named certificate
18
20
  # @param [String] name the name of the certificate to fetch
21
+ # @param [Puppet::Rest::SSLContext] ssl_context the ssl content to use when making the request
19
22
  # @raise [Puppet::Rest::ResponseError] if the response status is not OK
20
23
  # @return [String] the PEM-encoded certificate or certificate bundle
21
- def self.get_certificate(client, name)
22
- ca.with_base_url(client.dns_resolver) do |url|
24
+ def self.get_certificate(name, ssl_context)
25
+ ca.with_base_url(Puppet::Network::Resolver.new) do |url|
23
26
  header = { 'Accept' => 'text/plain', 'Accept-Encoding' => ACCEPT_ENCODING }
24
- body = ''
25
27
  url.path += "certificate/#{name}"
26
- client.get(url, header: header) do |chunk|
27
- body << chunk
28
+
29
+ use_ssl = url.is_a? URI::HTTPS
30
+
31
+ # Deeper levels of the code assume that if we have any number of
32
+ # certificate related files, we have all of the certificate related
33
+ # files. This assumption caused us to download the certificate twice.
34
+ # We have to hard code `verify_mode=false` so we don't attempt to
35
+ # download the certificate so that we can download the certificate.
36
+ #
37
+ # This is related to PUP-9094. We won't have so many issues with this
38
+ # once we are using the httpclient gem to handle this work. We were
39
+ # unable to get this work completed in time for Puppet 6.0.0, so we had
40
+ # to switch back to using Puppet::Network::HttpPool, which has
41
+ # unfortunate limitations (i.e., an all or nothing approach to cert
42
+ # verification).
43
+ verify_mode = false
44
+
45
+ client = Puppet::Network::HttpPool.http_instance(url.host, url.port, use_ssl, verify_mode)
46
+
47
+ response = client.get(url.request_uri, header)
48
+ unless response.code.to_i == 200
49
+ raise Puppet::Rest::ResponseError.new(response.message, response)
28
50
  end
51
+
29
52
  Puppet.info _("Downloaded certificate for %{name} from %{server}") % { name: name, server: ca.server }
30
- body
53
+
54
+ uncompress_body(response)
31
55
  end
32
56
  end
33
57
 
34
- # Make an HTTP request to fetch the named crl, using the given
35
- # HTTP client. Accepts a block to stream responses to disk.
36
- # @param [Puppet::Rest::Client] client the HTTP client to use to make the request
58
+ # Make an HTTP request to fetch the named crl
37
59
  # @param [String] name the crl to fetch
60
+ # @param [Puppet::Rest::SSLContext] ssl_context the ssl content to use when making the request
38
61
  # @raise [Puppet::Rest::ResponseError] if the response status is not OK
39
- # @return nil
40
- def self.get_crls(client, name, &block)
41
- ca.with_base_url(client.dns_resolver) do |url|
62
+ # @return [String] the PEM-encoded crl
63
+ def self.get_crls(name, ssl_context)
64
+ ca.with_base_url(Puppet::Network::Resolver.new) do |url|
42
65
  header = { 'Accept' => 'text/plain', 'Accept-Encoding' => ACCEPT_ENCODING }
43
66
  url.path += "certificate_revocation_list/#{name}"
44
- client.get(url, header: header) do |chunk|
45
- block.call(chunk)
67
+
68
+ use_ssl = url.is_a? URI::HTTPS
69
+
70
+ # Deeper levels of the code assume that if we have any number of
71
+ # certificate related files, we have all of the certificate related
72
+ # files. Unfortunately, this causes us to get stuck in an infinite loop,
73
+ # so we have to hard code `verify_mode=false` so we don't attempt to use
74
+ # files that do not exist yet in order to download those files.
75
+ #
76
+ # This is related to PUP-9094. We won't have so many issues with this
77
+ # once we are using the httpclient gem to handle this work. We were
78
+ # unable to get this work completed in time for Puppet 6.0.0, so we had
79
+ # to switch back to using Puppet::Network::HttpPool, which has
80
+ # unfortunate limitations (i.e., an all or nothing approach to cert
81
+ # verification).
82
+ verify_mode = false
83
+
84
+ client = Puppet::Network::HttpPool.http_instance(url.host, url.port, use_ssl, verify_mode)
85
+
86
+ response = client.get(url.request_uri, header)
87
+ unless response.code.to_i == 200
88
+ raise Puppet::Rest::ResponseError.new(response.message, response)
46
89
  end
90
+
47
91
  Puppet.debug _("Downloaded certificate revocation list for %{name} from %{server}") % { name: name, server: ca.server }
92
+
93
+ uncompress_body(response)
48
94
  end
49
95
  end
50
96
 
51
- # Make an HTTP request to send the named CSR, using the given
52
- # HTTP client.
53
- # @param [Puppet::Rest::Client] client the HTTP client to use to make the request
97
+ # Make an HTTP request to send the named CSR
54
98
  # @param [String] csr_pem the contents of the CSR to sent to the CA
55
99
  # @param [String] name the name of the host whose CSR is being submitted
100
+ # @param [Puppet::Rest::SSLContext] ssl_context the ssl content to use when making the request
56
101
  # @rasies [Puppet::Rest::ResponseError] if the response status is not OK
57
- def self.put_certificate_request(client, csr_pem, name)
58
- ca.with_base_url(client.dns_resolver) do |url|
102
+ def self.put_certificate_request(csr_pem, name, ssl_context)
103
+ ca.with_base_url(Puppet::Network::Resolver.new) do |url|
59
104
  header = { 'Accept' => 'text/plain',
60
105
  'Accept-Encoding' => ACCEPT_ENCODING,
61
106
  'Content-Type' => 'text/plain' }
62
107
  url.path += "certificate_request/#{name}"
63
- response = client.put(url, body: csr_pem, header: header)
64
- if response.ok?
108
+
109
+ use_ssl = url.is_a? URI::HTTPS
110
+
111
+ # See notes above as to why verify_mode is hardcoded to false
112
+ verify_mode = false
113
+
114
+ client = Puppet::Network::HttpPool.http_instance(url.host, url.port, use_ssl, verify_mode)
115
+
116
+ response = client.put(url.request_uri, csr_pem, header)
117
+ if response.code.to_i == 200
65
118
  Puppet.debug "Submitted certificate request to server."
66
119
  else
67
- raise response.to_exception
120
+ raise Puppet::Rest::ResponseError.new(response.message, response)
68
121
  end
69
122
  end
70
123
  end
71
124
 
72
- # Make an HTTP request to get the named CSR, using the given
73
- # HTTP client.
74
- # @param [Puppet::Rest::Client] client the HTTP client to use to make the request
125
+ # Make an HTTP request to get the named CSR
75
126
  # @param [String] name the name of the host whose CSR is being queried
127
+ # @param [Puppet::Rest::SSLContext] ssl_context the ssl content to use when making the request
76
128
  # @rasies [Puppet::Rest::ResponseError] if the response status is not OK
77
129
  # @return [String] the PEM encoded certificate request
78
- def self.get_certificate_request(client, name)
79
- ca.with_base_url(client.dns_resolver) do |url|
130
+ def self.get_certificate_request(name, ssl_context)
131
+ ca.with_base_url(Puppet::Network::Resolver.new) do |url|
80
132
  header = { 'Accept' => 'text/plain', 'Accept-Encoding' => ACCEPT_ENCODING }
81
- body = ''
82
133
  url.path += "certificate_request/#{name}"
83
- client.get(url, header: header) do |chunk|
84
- body << chunk
134
+
135
+ use_ssl = url.is_a? URI::HTTPS
136
+
137
+ # See notes above as to why verify_mode is hardcoded to false
138
+ verify_mode = false
139
+
140
+ client = Puppet::Network::HttpPool.http_instance(url.host, url.port, use_ssl, verify_mode)
141
+
142
+
143
+ response = client.get(url.request_uri, header)
144
+ unless response.code.to_i == 200
145
+ raise Puppet::Rest::ResponseError.new(response.message, response)
85
146
  end
147
+
86
148
  Puppet.debug _("Downloaded existing certificate request for %{name} from %{server}") % { name: name, server: ca.server }
87
- body
149
+
150
+ uncompress_body(response)
88
151
  end
89
152
  end
90
153
  end
@@ -1197,7 +1197,7 @@ Generated on #{Time.now}.
1197
1197
 
1198
1198
  def add_user_resources(catalog, sections)
1199
1199
  return unless Puppet.features.root?
1200
- return if Puppet.features.microsoft_windows?
1200
+ return if Puppet::Util::Platform.windows?
1201
1201
  return unless self[:mkusers]
1202
1202
 
1203
1203
  @config.each do |name, setting|
@@ -156,7 +156,7 @@ class Puppet::Settings::FileSetting < Puppet::Settings::StringSetting
156
156
  end
157
157
 
158
158
  # REMIND fails on Windows because chown/chgrp functionality not supported yet
159
- if Puppet.features.root? and !Puppet.features.microsoft_windows?
159
+ if Puppet.features.root? and !Puppet::Util::Platform.windows?
160
160
  resource[:owner] = self.owner if self.owner
161
161
  resource[:group] = self.group if self.group
162
162
  end
@@ -34,11 +34,6 @@ class Puppet::SSL::Base
34
34
 
35
35
  attr_accessor :name, :content
36
36
 
37
- # Is this file for the CA?
38
- def ca?
39
- name == Puppet::SSL::Host.ca_name
40
- end
41
-
42
37
  def generate
43
38
  raise Puppet::DevError, _("%{class_name} did not override 'generate'") % { class_name: self.class }
44
39
  end
@@ -86,18 +81,15 @@ class Puppet::SSL::Base
86
81
 
87
82
  # Read content from disk appropriately.
88
83
  def read(path)
89
- # applies to Puppet::SSL::Certificate, Puppet::SSL::CertificateRequest, Puppet::SSL::CertificateRevocationList
84
+ # applies to Puppet::SSL::Certificate, Puppet::SSL::CertificateRequest
90
85
  # Puppet::SSL::Key uses this, but also provides its own override
91
86
  # nothing derives from Puppet::SSL::Certificate, but it is called by a number of other SSL Indirectors:
92
- # Puppet::SSL::Certificate::DisabledCa (:find, :save, :destroy)
93
87
  # Puppet::Indirector::CertificateStatus::File (.indirection.find)
94
88
  # Puppet::Network::HTTP::WEBrick (.indirection.find)
95
89
  # Puppet::Network::HTTP::RackREST (.from_instance)
96
90
  # Puppet::Network::HTTP::WEBrickREST (.from_instance)
97
- # Puppet::SSL::CertificateAuthority (.new, .indirection.find, .indirection.save)
98
91
  # Puppet::SSL::Host (.indirection.find)
99
92
  # Puppet::SSL::Inventory (.indirection.search, implements its own add / rebuild / serials with encoding UTF8)
100
- # Puppet::SSL::CertificateAuthority::Interface (.indirection.find)
101
93
  # Puppet::SSL::Validator::DefaultValidator (.from_instance) / Puppet::SSL::Validator::NoValidator does nothing
102
94
  @content = wrapped_class.new(Puppet::FileSystem.read(path, :encoding => Encoding::ASCII))
103
95
  end
@@ -30,19 +30,7 @@ class Puppet::SSL::CertificateRequest < Puppet::SSL::Base
30
30
 
31
31
  extend Puppet::Indirector
32
32
 
33
- # If auto-signing is on, sign any certificate requests as they are saved.
34
- module AutoSigner
35
- def save(instance, key = nil)
36
- super
37
-
38
- # Try to autosign the CSR.
39
- if ca = Puppet::SSL::CertificateAuthority.instance
40
- ca.autosign(instance)
41
- end
42
- end
43
- end
44
-
45
- indirects :certificate_request, :terminus_class => :file, :extend => AutoSigner, :doc => <<DOC
33
+ indirects :certificate_request, :terminus_class => :file, :doc => <<DOC
46
34
  This indirection wraps an `OpenSSL::X509::Request` object, representing a certificate signing request (CSR).
47
35
  The indirection key is the certificate CN (generally a hostname).
48
36
  DOC
@@ -21,7 +21,7 @@ class Puppet::SSL::CertificateRequestAttributes
21
21
  def load
22
22
  Puppet.info(_("csr_attributes file loading from %{path}") % { path: path })
23
23
  if Puppet::FileSystem.exist?(path)
24
- hash = Puppet::Util::Yaml.load_file(path, {})
24
+ hash = Puppet::Util::Yaml.safe_load_file(path, [Symbol]) || {}
25
25
  if ! hash.is_a?(Hash)
26
26
  raise Puppet::Error, _("invalid CSR attributes, expected instance of Hash, received instance of %{klass}") % { klass: hash.class }
27
27
  end
@@ -1,9 +1,7 @@
1
- require 'puppet/indirector'
2
1
  require 'puppet/ssl'
3
2
  require 'puppet/ssl/key'
4
3
  require 'puppet/ssl/certificate'
5
4
  require 'puppet/ssl/certificate_request'
6
- require 'puppet/ssl/certificate_revocation_list'
7
5
  require 'puppet/ssl/certificate_request_attributes'
8
6
  require 'puppet/rest/errors'
9
7
  require 'puppet/rest/routes'
@@ -24,22 +22,11 @@ class Puppet::SSL::Host
24
22
  CA_NAME = Puppet::SSL::CA_NAME
25
23
  Certificate = Puppet::SSL::Certificate
26
24
  CertificateRequest = Puppet::SSL::CertificateRequest
27
- CertificateRevocationList = Puppet::SSL::CertificateRevocationList
28
-
29
- extend Puppet::Indirector
30
- indirects :certificate_status, :terminus_class => :file, :doc => <<DOC
31
- This indirection represents the host that ties a key, certificate, and certificate request together.
32
- The indirection key is the certificate CN (generally a hostname).
33
- DOC
34
25
 
35
26
  attr_reader :name, :crl_path
36
- attr_accessor :ca
37
27
 
38
28
  attr_writer :key, :certificate, :certificate_request, :crl_usage
39
29
 
40
- # This accessor is used in instances for indirector requests to hold desired state
41
- attr_accessor :desired_state
42
-
43
30
  def self.localhost
44
31
  return @localhost if @localhost
45
32
  @localhost = new
@@ -52,28 +39,10 @@ DOC
52
39
  @localhost = nil
53
40
  end
54
41
 
55
- # This is the constant that people will use to mark that a given host is
56
- # a certificate authority.
57
- def self.ca_name
58
- CA_NAME
59
- end
60
-
61
- class << self
62
- attr_reader :ca_location
63
- end
64
-
65
42
  # Configure how our various classes interact with their various terminuses.
66
43
  def self.configure_indirection(terminus, cache = nil)
67
44
  Certificate.indirection.terminus_class = terminus
68
45
  CertificateRequest.indirection.terminus_class = terminus
69
- CertificateRevocationList.indirection.terminus_class = terminus
70
-
71
- host_map = {:ca => :file, :disabled_ca => nil, :file => nil, :rest => :rest}
72
- if term = host_map[terminus]
73
- self.indirection.terminus_class = term
74
- else
75
- self.indirection.reset_terminus_class
76
- end
77
46
 
78
47
  if cache
79
48
  # This is weird; we don't actually cache our keys, we
@@ -87,7 +56,6 @@ DOC
87
56
  if cache
88
57
  Certificate.indirection.cache_class = cache
89
58
  CertificateRequest.indirection.cache_class = cache
90
- CertificateRevocationList.indirection.cache_class = cache
91
59
  else
92
60
  # Make sure we have no cache configured. puppet master
93
61
  # switches the configurations around a bit, so it's important
@@ -95,39 +63,9 @@ DOC
95
63
  # time.
96
64
  Certificate.indirection.cache_class = nil
97
65
  CertificateRequest.indirection.cache_class = nil
98
- CertificateRevocationList.indirection.cache_class = nil
99
66
  end
100
67
  end
101
68
 
102
- CA_MODES = {
103
- # Our ca is local, so we use it as the ultimate source of information
104
- # And we cache files locally.
105
- :local => [:ca, :file],
106
- # We're a remote CA client.
107
- :remote => [:rest, :file],
108
- # We are the CA, so we don't have read/write access to the normal certificates.
109
- :only => [:ca],
110
- # We have no CA, so we just look in the local file store.
111
- :none => [:disabled_ca]
112
- }
113
-
114
- # Specify how we expect to interact with our certificate authority.
115
- def self.ca_location=(mode)
116
- modes = CA_MODES.collect { |m, vals| m.to_s }.join(", ")
117
- raise ArgumentError, _("CA Mode can only be one of: %{modes}") % { modes: modes } unless CA_MODES.include?(mode)
118
-
119
- @ca_location = mode
120
-
121
- configure_indirection(*CA_MODES[@ca_location])
122
- end
123
-
124
- # Puppet::SSL::Host is actually indirected now so the original implementation
125
- # has been moved into the certificate_status indirector. This method is in-use
126
- # in `puppet cert -c <certname>`.
127
- def self.destroy(name)
128
- indirection.destroy(name)
129
- end
130
-
131
69
  def self.from_data_hash(data)
132
70
  instance = new(data["name"])
133
71
  if data["desired_state"]
@@ -136,18 +74,6 @@ DOC
136
74
  instance
137
75
  end
138
76
 
139
- # Puppet::SSL::Host is actually indirected now so the original implementation
140
- # has been moved into the certificate_status indirector. This method does not
141
- # appear to be in use in `puppet cert -l`.
142
- def self.search(options = {})
143
- indirection.search("*", options)
144
- end
145
-
146
- # Is this a ca host, meaning that all of its files go in the CA location?
147
- def ca?
148
- ca
149
- end
150
-
151
77
  def key
152
78
  @key ||= Key.indirection.find(name)
153
79
  end
@@ -175,8 +101,6 @@ DOC
175
101
  # ...add our configured dns_alt_names
176
102
  if Puppet[:dns_alt_names] and Puppet[:dns_alt_names] != ''
177
103
  options[:dns_alt_names] ||= Puppet[:dns_alt_names]
178
- elsif Puppet::SSL::CertificateAuthority.ca? and fqdn = Facter.value(:fqdn) and domain = Facter.value(:domain)
179
- options[:dns_alt_names] = "puppet, #{fqdn}, puppet.#{domain}"
180
104
  end
181
105
  end
182
106
 
@@ -190,6 +114,7 @@ DOC
190
114
  @certificate_request.generate(key.content, options)
191
115
  begin
192
116
  submit_certificate_request(@certificate_request)
117
+ save_certificate_request(@certificate_request)
193
118
  rescue
194
119
  @certificate_request = nil
195
120
  raise
@@ -208,23 +133,28 @@ DOC
208
133
 
209
134
  # get the CA cert first, since it's required for the normal cert
210
135
  # to be of any use. If we can't get it, quit.
211
- if !ca? && !ensure_ca_certificate
136
+ if !ensure_ca_certificate
212
137
  return nil
213
138
  end
214
139
 
215
- @certificate = get_host_certificate
216
- return nil unless @certificate
140
+ cert = get_host_certificate
141
+ return nil unless cert
217
142
 
218
- validate_certificate_with_key
143
+ validate_certificate_with_key(cert)
144
+ @certificate = cert
219
145
  end
220
146
  @certificate
221
147
  end
222
148
 
223
- def validate_certificate_with_key
224
- raise Puppet::Error, _("No certificate to validate.") unless certificate
225
- raise Puppet::Error, _("No private key with which to validate certificate with fingerprint: %{fingerprint}") % { fingerprint: certificate.fingerprint } unless key
226
- unless certificate.content.check_private_key(key.content)
227
- raise Puppet::Error, _(<<ERROR_STRING) % { fingerprint: certificate.fingerprint, cert_name: Puppet[:certname], ssl_dir: Puppet[:ssldir], cert_dir: Puppet[:certdir].gsub('/', '\\') }
149
+ # Validate that our private key matches the specified certificate.
150
+ #
151
+ # @param [Puppet::SSL::Certificate] cert the certificate to check
152
+ # @raises [Puppet::Error] if the private key does not match
153
+ def validate_certificate_with_key(cert)
154
+ raise Puppet::Error, _("No certificate to validate.") unless cert
155
+ raise Puppet::Error, _("No private key with which to validate certificate with fingerprint: %{fingerprint}") % { fingerprint: cert.fingerprint } unless key
156
+ unless cert.content.check_private_key(key.content)
157
+ raise Puppet::Error, _(<<ERROR_STRING) % { fingerprint: cert.fingerprint, cert_name: Puppet[:certname], ssl_dir: Puppet[:ssldir], cert_dir: Puppet[:certdir].gsub('/', '\\') }
228
158
  The certificate retrieved from the master does not match the agent's private key. Did you forget to run as root?
229
159
  Certificate fingerprint: %{fingerprint}
230
160
  To fix this, remove the certificate from both the master and the agent and then start a puppet run, which will automatically regenerate a certificate.
@@ -238,6 +168,15 @@ ERROR_STRING
238
168
  end
239
169
  end
240
170
 
171
+ def download_host_certificate
172
+ cert = download_certificate_from_ca(name)
173
+ return nil unless cert
174
+
175
+ validate_certificate_with_key(cert)
176
+ save_host_certificate(cert)
177
+ cert
178
+ end
179
+
241
180
  # Search for an existing CSR for this host either cached on
242
181
  # disk or stored by the CA. Returns nil if no request exists.
243
182
  # @return [Puppet::SSL::CertificateRequest, nil]
@@ -245,10 +184,8 @@ ERROR_STRING
245
184
  unless @certificate_request
246
185
  if csr = load_certificate_request_from_file
247
186
  @certificate_request = csr
248
- elsif Puppet::SSL::Host.ca_location == :remote
249
- if csr = download_csr_from_ca
250
- @certificate_request = csr
251
- end
187
+ elsif csr = download_csr_from_ca
188
+ @certificate_request = csr
252
189
  end
253
190
  end
254
191
  @certificate_request
@@ -262,10 +199,62 @@ ERROR_STRING
262
199
 
263
200
  # if CSR downloaded from master, but the local keypair was just generated and
264
201
  # does not match the public key in the CSR, fail hard
265
- if !existing_request.nil? &&
266
- (key.content.public_key.to_s != existing_request.content.public_key.to_s)
202
+ validate_csr_with_key(existing_request, key) if existing_request
203
+
204
+ generate_certificate_request unless existing_request
205
+ end
267
206
 
268
- raise Puppet::Error, _(<<ERROR_STRING) % { fingerprint: existing_request.fingerprint, csr_public_key: existing_request.content.public_key.to_text, agent_public_key: key.content.public_key.to_text, cert_name: Puppet[:certname], ssl_dir: Puppet[:ssldir], cert_dir: Puppet[:certdir].gsub('/', '\\') }
207
+ # Generate a keypair, generate a CSR, and submit it. If a local key pair
208
+ # already exists it will be used to generate the CSR. If a local CSR already
209
+ # exists and matches the key then the existing CSR will be submitted. If the
210
+ # CSR and key do not match an exception will be raised.
211
+ #
212
+ # @return [Puppet::SSL::CertificateRequest, nil]
213
+ def submit_request
214
+ generate_key unless key
215
+
216
+ csr = load_certificate_request_from_file
217
+ if csr
218
+ if key.content.public_key.to_s != csr.content.public_key.to_s
219
+ Puppet.warning("The local CSR does not match the agent's public key. Generating a new CSR.")
220
+
221
+ request_path = certificate_request_location(name)
222
+ Puppet::FileSystem.unlink(request_path)
223
+ csr = nil
224
+ end
225
+ end
226
+
227
+ if csr
228
+ validate_csr_with_key(csr, key)
229
+ submit_certificate_request(csr)
230
+ @certificate_request = csr
231
+ else
232
+ generate_certificate_request
233
+ end
234
+
235
+ @certificate_request
236
+ end
237
+
238
+ def validate_local_csr_with_key(csr, key)
239
+ if key.content.public_key.to_s != csr.content.public_key.to_s
240
+ raise Puppet::Error, _(<<ERROR_STRING) % { fingerprint: csr.fingerprint, csr_public_key: csr.content.public_key.to_text, agent_public_key: key.content.public_key.to_text, cert_name: Puppet[:certname], ssl_dir: Puppet[:ssldir], cert_dir: Puppet[:certdir].gsub('/', '\\') }
241
+ The local CSR does not match the agent's public key.
242
+ CSR fingerprint: %{fingerprint}
243
+ CSR public key: %{csr_public_key}
244
+ Agent public key: %{agent_public_key}
245
+ To fix this, remove the CSR from the agent and then start a puppet run, which will automatically regenerate a CSR.
246
+ On the agent:
247
+ 1a. On most platforms: find %{ssl_dir} -name %{cert_name}.pem -delete
248
+ 1b. On Windows: del "%{cert_dir}\\%{cert_name}.pem" /f
249
+ 2. puppet agent -t
250
+ ERROR_STRING
251
+ end
252
+ end
253
+ private :validate_local_csr_with_key
254
+
255
+ def validate_csr_with_key(csr, key)
256
+ if key.content.public_key.to_s != csr.content.public_key.to_s
257
+ raise Puppet::Error, _(<<ERROR_STRING) % { fingerprint: csr.fingerprint, csr_public_key: csr.content.public_key.to_text, agent_public_key: key.content.public_key.to_text, cert_name: Puppet[:certname], ssl_dir: Puppet[:ssldir], cert_dir: Puppet[:certdir].gsub('/', '\\') }
269
258
  The CSR retrieved from the master does not match the agent's public key.
270
259
  CSR fingerprint: %{fingerprint}
271
260
  CSR public key: %{csr_public_key}
@@ -279,21 +268,13 @@ On the agent:
279
268
  2. puppet agent -t
280
269
  ERROR_STRING
281
270
  end
282
- generate_certificate_request unless existing_request
283
-
284
- # If we can get a CA instance, then we're a valid CA, and we
285
- # should use it to sign our request; else, just try to read
286
- # the cert.
287
- if ! certificate and ca = Puppet::SSL::CertificateAuthority.instance
288
- ca.sign(self.name, {allow_dns_alt_names: true})
289
- end
290
271
  end
272
+ private :validate_csr_with_key
291
273
 
292
274
  def initialize(name = nil)
293
275
  @name = (name || Puppet[:certname]).downcase
294
276
  Puppet::SSL::Base.validate_certname(@name)
295
277
  @key = @certificate = @certificate_request = nil
296
- @ca = (name == self.class.ca_name)
297
278
  @crl_usage = Puppet.settings[:certificate_revocation]
298
279
  @crl_path = Puppet.settings[:hostcrl]
299
280
  end
@@ -320,49 +301,6 @@ ERROR_STRING
320
301
  @ssl_store
321
302
  end
322
303
 
323
- def to_data_hash
324
- my_cert = Puppet::SSL::Certificate.indirection.find(name)
325
- result = { 'name' => name }
326
-
327
- my_state = state
328
-
329
- result['state'] = my_state
330
- result['desired_state'] = desired_state if desired_state
331
-
332
- thing_to_use = (my_state == 'requested') ? certificate_request : my_cert
333
-
334
- # this is for backwards-compatibility
335
- # we should deprecate it and transition people to using
336
- # json[:fingerprints][:default]
337
- # It appears that we have no internal consumers of this api
338
- # --jeffweiss 30 aug 2012
339
- result['fingerprint'] = thing_to_use.fingerprint
340
-
341
- # The above fingerprint doesn't tell us what message digest algorithm was used
342
- # No problem, except that the default is changing between 2.7 and 3.0. Also, as
343
- # we move to FIPS 140-2 compliance, MD5 is no longer allowed (and, gasp, will
344
- # segfault in rubies older than 1.9.3)
345
- # So, when we add the newer fingerprints, we're explicit about the hashing
346
- # algorithm used.
347
- # --jeffweiss 31 july 2012
348
- result['fingerprints'] = {}
349
- result['fingerprints']['default'] = thing_to_use.fingerprint
350
-
351
- suitable_message_digest_algorithms.each do |md|
352
- result['fingerprints'][md.to_s] = thing_to_use.fingerprint md
353
- end
354
- result['dns_alt_names'] = thing_to_use.subject_alt_names
355
-
356
- result
357
- end
358
-
359
- # eventually we'll probably want to move this somewhere else or make it
360
- # configurable
361
- # --jeffweiss 29 aug 2012
362
- def suitable_message_digest_algorithms
363
- [:SHA1, :SHA224, :SHA256, :SHA384, :SHA512]
364
- end
365
-
366
304
  # Attempt to retrieve a cert, if we don't already have one.
367
305
  def wait_for_cert(time)
368
306
  begin
@@ -396,28 +334,21 @@ ERROR_STRING
396
334
  end
397
335
  end
398
336
 
399
- def state
400
- if certificate_request
401
- return 'requested'
402
- end
403
-
404
- begin
405
- Puppet::SSL::CertificateAuthority.new.verify(name)
406
- return 'signed'
407
- rescue Puppet::SSL::CertificateAuthority::CertificateVerificationError
408
- return 'revoked'
337
+ # Saves the given certificate to disc, at a location determined by this
338
+ # host's configuration.
339
+ # @param [Puppet::SSL::Certificate] cert the cert to save
340
+ def save_host_certificate(cert)
341
+ file_path = certificate_location(name)
342
+ Puppet::Util.replace_file(file_path, 0644) do |f|
343
+ f.write(cert.to_s)
409
344
  end
410
345
  end
411
346
 
412
347
  private
413
348
 
414
- # Load a previously generated CSR either from memory or from disk
349
+ # Load a previously generated CSR from disk
415
350
  # @return [Puppet::SSL::CertificateRequest, nil]
416
351
  def load_certificate_request_from_file
417
- if Puppet::SSL::CertificateRequest.indirection.terminus_class == :memory
418
- return Puppet::SSL::CertificateRequest.indirection.find(cert_name)
419
- end
420
-
421
352
  request_path = certificate_request_location(name)
422
353
  if Puppet::FileSystem.exist?(request_path)
423
354
  Puppet::SSL::CertificateRequest.from_s(Puppet::FileSystem.read(request_path))
@@ -432,38 +363,28 @@ ERROR_STRING
432
363
  def download_csr_from_ca
433
364
  begin
434
365
  body = Puppet::Rest::Routes.get_certificate_request(
435
- http_client(Puppet::Rest::SSLContext.new(OpenSSL::SSL::VERIFY_PEER, ssl_store)),
436
- name)
366
+ name, Puppet::Rest::SSLContext.new(OpenSSL::SSL::VERIFY_PEER, ssl_store))
437
367
  begin
438
368
  Puppet::SSL::CertificateRequest.from_s(body)
439
369
  rescue OpenSSL::X509::RequestError => e
440
370
  raise Puppet::Error, _("Response from the CA did not contain a valid certificate request: %{message}") % { message: e.message }
441
371
  end
442
372
  rescue Puppet::Rest::ResponseError => e
443
- if e.response.status_code == 404
373
+ if e.response.code.to_i == 404
444
374
  nil
445
375
  else
446
376
  raise Puppet::Error, _('Could not download certificate request: %{message}') % { message: e.message }
447
377
  end
448
378
  end
449
379
  end
450
- # Submit the CSR to the CA, either via an HTTP PUT request, or when testing,
451
- # via the indirector (needed for both memory and CA terminii). This also
452
- # caches a copy of the CSR on disk.
380
+ # Submit the CSR to the CA via an HTTP PUT request.
453
381
  # @param [Puppet::SSL::CertificateRequest] csr the request to submit
454
382
  def submit_certificate_request(csr)
455
- if Puppet::SSL::CertificateRequest.indirection.terminus_class == :memory ||
456
- Puppet::SSL::CertificateRequest.indirection.terminus_class == :ca
457
- Puppet::SSL::CertificateRequest.indirection.save(csr)
458
- return
459
- end
460
-
461
- if Puppet::SSL::Host.ca_location == :remote
462
- Puppet::Rest::Routes.put_certificate_request(
463
- http_client(Puppet::Rest::SSLContext.new(OpenSSL::SSL::VERIFY_PEER, ssl_store)),
464
- csr.render, name)
465
- end
383
+ Puppet::Rest::Routes.put_certificate_request(
384
+ csr.render, name, Puppet::Rest::SSLContext.new(OpenSSL::SSL::VERIFY_PEER, ssl_store))
385
+ end
466
386
 
387
+ def save_certificate_request(csr)
467
388
  Puppet::Util.replace_file(certificate_request_location(name), 0644) do |file|
468
389
  file.write(csr.render)
469
390
  end
@@ -495,16 +416,13 @@ ERROR_STRING
495
416
 
496
417
  # Ensures that the CA certificate is available for either generating or
497
418
  # validating the host's cert.
498
- # It will first check if the cert is present in memory (used for testing),
499
- # then check on disk, and finally try to download it.
419
+ # It will first check on disk, then try to download it.
500
420
  # @raise [Puppet::Error] if text form of found certificate bundle is invalid
501
421
  # and cannot be loaded into cert objects
502
422
  # @return [Boolean] true if the CA certificate was found, false otherwise
503
423
  def ensure_ca_certificate
504
424
  file_path = certificate_location(CA_NAME)
505
- if check_for_certificate_in_memory(CA_NAME)
506
- true
507
- elsif Puppet::FileSystem.exist?(file_path)
425
+ if Puppet::FileSystem.exist?(file_path)
508
426
  begin
509
427
  # This load ensures that the file contents is a valid cert bundle.
510
428
  # If the text is malformed, load_certificate_bundle will raise.
@@ -522,6 +440,7 @@ ERROR_STRING
522
440
  end
523
441
  end
524
442
  end
443
+ public :ensure_ca_certificate
525
444
 
526
445
  # Creates an arry of SSL Certificate objects from a PEM-encoding string
527
446
  # of one or more certs.
@@ -556,13 +475,11 @@ ERROR_STRING
556
475
  # @return nil
557
476
  def download_and_save_crl_bundle(store=nil)
558
477
  begin
559
- # If no SSL store was suppoed, use this host's SSL store
478
+ # If no SSL store was supplied, use this host's SSL store
560
479
  store ||= ssl_store
561
- client = http_client(Puppet::Rest::SSLContext.new(OpenSSL::SSL::VERIFY_PEER, store))
562
480
  Puppet::Util.replace_file(crl_path, 0644) do |file|
563
- Puppet::Rest::Routes.get_crls(client, CA_NAME) do |chunk|
564
- file.write(chunk)
565
- end
481
+ result = Puppet::Rest::Routes.get_crls(CA_NAME, Puppet::Rest::SSLContext.new(OpenSSL::SSL::VERIFY_PEER, store))
482
+ file.write(result)
566
483
  end
567
484
  rescue Puppet::Rest::ResponseError => e
568
485
  raise Puppet::Error, _('Could not download CRLs: %{message}') % { message: e.message }
@@ -574,12 +491,11 @@ ERROR_STRING
574
491
  # bundle
575
492
  # @return [[OpenSSL::X509::Certificate]] the certs loaded from the response
576
493
  def download_ca_certificate_bundle
577
- return nil if Puppet::SSL::Host.ca_location != :remote
578
-
579
494
  begin
580
495
  cert_bundle = Puppet::Rest::Routes.get_certificate(
581
- http_client(Puppet::Rest::SSLContext.new(OpenSSL::SSL::VERIFY_NONE)),
582
- CA_NAME)
496
+ CA_NAME,
497
+ Puppet::Rest::SSLContext.new(OpenSSL::SSL::VERIFY_NONE)
498
+ )
583
499
  # This load ensures that the response body is a valid cert bundle.
584
500
  # If the text is malformed, load_certificate_bundle will raise.
585
501
  begin
@@ -606,9 +522,7 @@ ERROR_STRING
606
522
  # no certificate could be found.
607
523
  # @return [Puppet::SSL::Certificate, nil]
608
524
  def get_host_certificate
609
- if cert = check_for_certificate_in_memory(name)
610
- return cert
611
- elsif cert = check_for_certificate_on_disk(name)
525
+ if cert = check_for_certificate_on_disk(name)
612
526
  return cert
613
527
  elsif cert = download_certificate_from_ca(name)
614
528
  save_host_certificate(cert)
@@ -618,17 +532,6 @@ ERROR_STRING
618
532
  end
619
533
  end
620
534
 
621
- # Checks the certificate indirection for a cert stored in memory.
622
- # Only relevant if the memory terminus is in use, and currently
623
- # only used in testing.
624
- # @param [String] name the name of the cert to look for
625
- # @return [Puppet::SSL::Certificate, nil]
626
- def check_for_certificate_in_memory(cert_name)
627
- if Puppet::SSL::Certificate.indirection.terminus_class == :memory
628
- return Puppet::SSL::Certificate.indirection.find(cert_name)
629
- end
630
- end
631
-
632
535
  # Checks for the requested certificate on disc, at a location
633
536
  # determined by this host's configuration.
634
537
  # @name [String] name the name of the cert to look for
@@ -645,6 +548,7 @@ ERROR_STRING
645
548
  end
646
549
  end
647
550
  end
551
+ public :check_for_certificate_on_disk
648
552
 
649
553
  # Attempts to download this host's certificate from the CA server.
650
554
  # Returns nil if the CA does not yet have a signed cert for this host.
@@ -653,19 +557,18 @@ ERROR_STRING
653
557
  # certificate
654
558
  # @return [Puppet::SSL::Certificate, nil]
655
559
  def download_certificate_from_ca(cert_name)
656
- return nil if Puppet::SSL::Host.ca_location != :remote
657
-
658
560
  begin
659
561
  cert = Puppet::Rest::Routes.get_certificate(
660
- http_client(Puppet::Rest::SSLContext.new(OpenSSL::SSL::VERIFY_PEER, ssl_store)),
661
- cert_name)
562
+ cert_name,
563
+ Puppet::Rest::SSLContext.new(OpenSSL::SSL::VERIFY_PEER, ssl_store)
564
+ )
662
565
  begin
663
566
  Puppet::SSL::Certificate.from_s(cert)
664
567
  rescue OpenSSL::X509::CertificateError
665
568
  raise Puppet::Error, _("Response from the CA did not contain a valid certificate for %{cert_name}.") % { cert_name: cert_name }
666
569
  end
667
570
  rescue Puppet::Rest::ResponseError => e
668
- if e.response.status_code == 404
571
+ if e.response.code.to_i == 404
669
572
  Puppet.debug _("No certificate for %{cert_name} on CA") % { cert_name: cert_name }
670
573
  nil
671
574
  else
@@ -674,38 +577,19 @@ ERROR_STRING
674
577
  end
675
578
  end
676
579
 
677
- # Saves the given certificate to disc, at a location determined by this
678
- # host's configuration.
679
- # @param [Puppet::SSL::Certificate] cert the cert to save
680
- def save_host_certificate(cert)
681
- file_path = certificate_location(name)
682
- Puppet::Util.replace_file(file_path, 0644) do |f|
683
- f.write(cert.to_s)
684
- end
685
- end
686
-
687
580
  # Returns the file path for the named certificate, based on this host's
688
581
  # configuration.
689
582
  # @param [String] name the name of the cert to find
690
583
  # @return [String] file path to the cert's location
691
584
  def certificate_location(cert_name)
692
- if Puppet::SSL::Host.ca_location == :only
693
- cert_name == CA_NAME ? Puppet[:cacert] : File.join(Puppet[:signeddir], "#{cert_name}.pem")
694
- else
695
- cert_name == CA_NAME ? Puppet[:localcacert] : File.join(Puppet[:certdir], "#{cert_name}.pem")
696
- end
585
+ cert_name == CA_NAME ? Puppet[:localcacert] : File.join(Puppet[:certdir], "#{cert_name}.pem")
697
586
  end
698
587
 
699
588
  # Returns the file path for the named CSR, based on this host's configuration.
700
589
  # @param [String] name the name of the CSR to find
701
590
  # @return [String] file path to the CSR's location
702
591
  def certificate_request_location(cert_name)
703
- if Puppet::SSL::Host.ca_location == :only ||
704
- Puppet::SSL::Host.ca_location == :local
705
- File.join(Puppet[:csrdir], "#{cert_name}.pem")
706
- else
707
- File.join(Puppet[:requestdir], "#{cert_name}.pem")
708
- end
592
+ File.join(Puppet[:requestdir], "#{cert_name}.pem")
709
593
  end
710
594
 
711
595
  # @param [OpenSSL::X509::PURPOSE_*] constant defining the kinds of certs
@@ -740,5 +624,3 @@ ERROR_STRING
740
624
  store
741
625
  end
742
626
  end
743
-
744
- require 'puppet/ssl/certificate_authority'