bolt 0.20.3 → 0.20.5

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 (256) hide show
  1. checksums.yaml +4 -4
  2. data/bolt-modules/boltlib/lib/puppet/functions/run_task.rb +3 -3
  3. data/bolt-modules/boltlib/lib/puppet/functions/set_feature.rb +33 -0
  4. data/lib/bolt/inventory.rb +19 -1
  5. data/lib/bolt/target.rb +15 -0
  6. data/lib/bolt/transport/local.rb +6 -1
  7. data/lib/bolt/transport/orch.rb +2 -0
  8. data/lib/bolt/transport/ssh.rb +7 -2
  9. data/lib/bolt/transport/winrm.rb +6 -1
  10. data/lib/bolt/version.rb +1 -1
  11. data/modules/facts/plans/retrieve.pp +2 -26
  12. data/modules/facts/tasks/init.json +9 -0
  13. data/vendored/puppet/lib/hiera/puppet_function.rb +1 -1
  14. data/vendored/puppet/lib/hiera/scope.rb +24 -2
  15. data/vendored/puppet/lib/puppet.rb +4 -13
  16. data/vendored/puppet/lib/puppet/application.rb +2 -2
  17. data/vendored/puppet/lib/puppet/application/agent.rb +1 -1
  18. data/vendored/puppet/lib/puppet/application/apply.rb +1 -1
  19. data/vendored/puppet/lib/puppet/application/cert.rb +1 -1
  20. data/vendored/puppet/lib/puppet/application/device.rb +8 -8
  21. data/vendored/puppet/lib/puppet/application/face_base.rb +1 -1
  22. data/vendored/puppet/lib/puppet/application/lookup.rb +2 -2
  23. data/vendored/puppet/lib/puppet/application/resource.rb +2 -2
  24. data/vendored/puppet/lib/puppet/application/script.rb +1 -1
  25. data/vendored/puppet/lib/puppet/configurer.rb +47 -24
  26. data/vendored/puppet/lib/puppet/confine.rb +4 -1
  27. data/vendored/puppet/lib/puppet/context.rb +1 -1
  28. data/vendored/puppet/lib/puppet/defaults.rb +32 -44
  29. data/vendored/puppet/lib/puppet/error.rb +14 -7
  30. data/vendored/puppet/lib/puppet/external/dot.rb +23 -17
  31. data/vendored/puppet/lib/puppet/face/config.rb +58 -3
  32. data/vendored/puppet/lib/puppet/face/epp.rb +1 -1
  33. data/vendored/puppet/lib/puppet/face/module/build.rb +3 -3
  34. data/vendored/puppet/lib/puppet/face/module/install.rb +0 -4
  35. data/vendored/puppet/lib/puppet/face/module/list.rb +0 -5
  36. data/vendored/puppet/lib/puppet/face/module/search.rb +1 -1
  37. data/vendored/puppet/lib/puppet/face/module/uninstall.rb +0 -4
  38. data/vendored/puppet/lib/puppet/face/module/upgrade.rb +0 -4
  39. data/vendored/puppet/lib/puppet/face/status.rb +2 -2
  40. data/vendored/puppet/lib/puppet/file_serving/base.rb +5 -5
  41. data/vendored/puppet/lib/puppet/file_serving/metadata.rb +2 -1
  42. data/vendored/puppet/lib/puppet/forge.rb +7 -8
  43. data/vendored/puppet/lib/puppet/forge/errors.rb +3 -3
  44. data/vendored/puppet/lib/puppet/functions/abs.rb +61 -0
  45. data/vendored/puppet/lib/puppet/functions/all.rb +2 -2
  46. data/vendored/puppet/lib/puppet/functions/any.rb +2 -2
  47. data/vendored/puppet/lib/puppet/functions/assert_type.rb +3 -3
  48. data/vendored/puppet/lib/puppet/functions/break.rb +3 -7
  49. data/vendored/puppet/lib/puppet/functions/camelcase.rb +62 -0
  50. data/vendored/puppet/lib/puppet/functions/capitalize.rb +61 -0
  51. data/vendored/puppet/lib/puppet/functions/ceiling.rb +37 -0
  52. data/vendored/puppet/lib/puppet/functions/chomp.rb +57 -0
  53. data/vendored/puppet/lib/puppet/functions/chop.rb +67 -0
  54. data/vendored/puppet/lib/puppet/functions/compare.rb +125 -0
  55. data/vendored/puppet/lib/puppet/functions/convert_to.rb +3 -2
  56. data/vendored/puppet/lib/puppet/functions/dig.rb +21 -1
  57. data/vendored/puppet/lib/puppet/functions/downcase.rb +89 -0
  58. data/vendored/puppet/lib/puppet/functions/each.rb +2 -2
  59. data/vendored/puppet/lib/puppet/functions/empty.rb +1 -3
  60. data/vendored/puppet/lib/puppet/functions/eyaml_lookup_key.rb +4 -2
  61. data/vendored/puppet/lib/puppet/functions/filter.rb +2 -2
  62. data/vendored/puppet/lib/puppet/functions/floor.rb +37 -0
  63. data/vendored/puppet/lib/puppet/functions/get.rb +150 -0
  64. data/vendored/puppet/lib/puppet/functions/getvar.rb +87 -0
  65. data/vendored/puppet/lib/puppet/functions/hiera.rb +5 -5
  66. data/vendored/puppet/lib/puppet/functions/hiera_array.rb +5 -5
  67. data/vendored/puppet/lib/puppet/functions/hiera_hash.rb +6 -6
  68. data/vendored/puppet/lib/puppet/functions/hiera_include.rb +7 -7
  69. data/vendored/puppet/lib/puppet/functions/hocon_data.rb +1 -1
  70. data/vendored/puppet/lib/puppet/functions/json_data.rb +3 -3
  71. data/vendored/puppet/lib/puppet/functions/lest.rb +1 -1
  72. data/vendored/puppet/lib/puppet/functions/lookup.rb +3 -2
  73. data/vendored/puppet/lib/puppet/functions/lstrip.rb +58 -0
  74. data/vendored/puppet/lib/puppet/functions/map.rb +1 -1
  75. data/vendored/puppet/lib/puppet/functions/match.rb +11 -0
  76. data/vendored/puppet/lib/puppet/functions/max.rb +183 -0
  77. data/vendored/puppet/lib/puppet/functions/min.rb +182 -0
  78. data/vendored/puppet/lib/puppet/functions/next.rb +1 -8
  79. data/vendored/puppet/lib/puppet/functions/reduce.rb +1 -1
  80. data/vendored/puppet/lib/puppet/functions/return.rb +1 -8
  81. data/vendored/puppet/lib/puppet/functions/reverse_each.rb +1 -1
  82. data/vendored/puppet/lib/puppet/functions/round.rb +24 -0
  83. data/vendored/puppet/lib/puppet/functions/rstrip.rb +58 -0
  84. data/vendored/puppet/lib/puppet/functions/size.rb +15 -0
  85. data/vendored/puppet/lib/puppet/functions/sort.rb +74 -0
  86. data/vendored/puppet/lib/puppet/functions/step.rb +1 -1
  87. data/vendored/puppet/lib/puppet/functions/strftime.rb +1 -7
  88. data/vendored/puppet/lib/puppet/functions/strip.rb +58 -0
  89. data/vendored/puppet/lib/puppet/functions/then.rb +1 -1
  90. data/vendored/puppet/lib/puppet/functions/tree_each.rb +7 -7
  91. data/vendored/puppet/lib/puppet/functions/upcase.rb +89 -0
  92. data/vendored/puppet/lib/puppet/functions/with.rb +4 -4
  93. data/vendored/puppet/lib/puppet/functions/yaml_data.rb +4 -2
  94. data/vendored/puppet/lib/puppet/graph/simple_graph.rb +9 -5
  95. data/vendored/puppet/lib/puppet/indirector/certificate_revocation_list/rest.rb +0 -11
  96. data/vendored/puppet/lib/puppet/indirector/indirection.rb +8 -12
  97. data/vendored/puppet/lib/puppet/indirector/node/exec.rb +1 -1
  98. data/vendored/puppet/lib/puppet/indirector/node/ldap.rb +1 -1
  99. data/vendored/puppet/lib/puppet/indirector/request.rb +11 -11
  100. data/vendored/puppet/lib/puppet/indirector/rest.rb +11 -11
  101. data/vendored/puppet/lib/puppet/interface/action.rb +2 -5
  102. data/vendored/puppet/lib/puppet/metatype/manager.rb +0 -2
  103. data/vendored/puppet/lib/puppet/module.rb +7 -33
  104. data/vendored/puppet/lib/puppet/module/task.rb +0 -1
  105. data/vendored/puppet/lib/puppet/module_tool.rb +2 -5
  106. data/vendored/puppet/lib/puppet/module_tool/applications/application.rb +5 -5
  107. data/vendored/puppet/lib/puppet/module_tool/applications/builder.rb +2 -2
  108. data/vendored/puppet/lib/puppet/module_tool/applications/checksummer.rb +3 -3
  109. data/vendored/puppet/lib/puppet/module_tool/applications/installer.rb +6 -7
  110. data/vendored/puppet/lib/puppet/module_tool/applications/uninstaller.rb +1 -2
  111. data/vendored/puppet/lib/puppet/module_tool/applications/unpacker.rb +2 -2
  112. data/vendored/puppet/lib/puppet/module_tool/applications/upgrader.rb +5 -6
  113. data/vendored/puppet/lib/puppet/module_tool/dependency.rb +1 -1
  114. data/vendored/puppet/lib/puppet/module_tool/installed_modules.rb +2 -2
  115. data/vendored/puppet/lib/puppet/module_tool/local_tarball.rb +3 -3
  116. data/vendored/puppet/lib/puppet/module_tool/metadata.rb +3 -4
  117. data/vendored/puppet/lib/puppet/module_tool/shared_behaviors.rb +2 -2
  118. data/vendored/puppet/lib/puppet/network/authconfig.rb +0 -13
  119. data/vendored/puppet/lib/puppet/network/format_support.rb +1 -1
  120. data/vendored/puppet/lib/puppet/network/formats.rb +5 -7
  121. data/vendored/puppet/lib/puppet/network/http.rb +0 -2
  122. data/vendored/puppet/lib/puppet/network/http/api.rb +1 -10
  123. data/vendored/puppet/lib/puppet/network/http/api/master/v3/environment.rb +2 -2
  124. data/vendored/puppet/lib/puppet/network/http/api/master/v3/environments.rb +2 -2
  125. data/vendored/puppet/lib/puppet/network/http/compression.rb +1 -1
  126. data/vendored/puppet/lib/puppet/network/http/connection.rb +11 -3
  127. data/vendored/puppet/lib/puppet/network/http/error.rb +3 -3
  128. data/vendored/puppet/lib/puppet/network/http/factory.rb +3 -0
  129. data/vendored/puppet/lib/puppet/network/http/handler.rb +59 -27
  130. data/vendored/puppet/lib/puppet/network/resolver.rb +140 -67
  131. data/vendored/puppet/lib/puppet/node/environment.rb +2 -19
  132. data/vendored/puppet/lib/puppet/parameter.rb +12 -7
  133. data/vendored/puppet/lib/puppet/parser/ast.rb +4 -8
  134. data/vendored/puppet/lib/puppet/parser/ast/branch.rb +3 -3
  135. data/vendored/puppet/lib/puppet/parser/ast/leaf.rb +5 -0
  136. data/vendored/puppet/lib/puppet/parser/ast/pops_bridge.rb +18 -0
  137. data/vendored/puppet/lib/puppet/parser/compiler.rb +3 -4
  138. data/vendored/puppet/lib/puppet/parser/compiler/catalog_validator/relationship_validator.rb +9 -2
  139. data/vendored/puppet/lib/puppet/parser/functions.rb +1 -1
  140. data/vendored/puppet/lib/puppet/parser/functions/assert_type.rb +3 -3
  141. data/vendored/puppet/lib/puppet/parser/functions/create_resources.rb +1 -7
  142. data/vendored/puppet/lib/puppet/parser/functions/each.rb +2 -2
  143. data/vendored/puppet/lib/puppet/parser/functions/filter.rb +1 -1
  144. data/vendored/puppet/lib/puppet/parser/functions/hiera.rb +4 -4
  145. data/vendored/puppet/lib/puppet/parser/functions/hiera_array.rb +5 -5
  146. data/vendored/puppet/lib/puppet/parser/functions/hiera_hash.rb +6 -6
  147. data/vendored/puppet/lib/puppet/parser/functions/hiera_include.rb +10 -11
  148. data/vendored/puppet/lib/puppet/parser/functions/inline_template.rb +1 -1
  149. data/vendored/puppet/lib/puppet/parser/functions/lest.rb +1 -1
  150. data/vendored/puppet/lib/puppet/parser/functions/lookup.rb +1 -1
  151. data/vendored/puppet/lib/puppet/parser/functions/map.rb +1 -1
  152. data/vendored/puppet/lib/puppet/parser/functions/reduce.rb +1 -1
  153. data/vendored/puppet/lib/puppet/parser/functions/return.rb +22 -1
  154. data/vendored/puppet/lib/puppet/parser/functions/reverse_each.rb +1 -1
  155. data/vendored/puppet/lib/puppet/parser/functions/step.rb +1 -1
  156. data/vendored/puppet/lib/puppet/parser/functions/then.rb +1 -1
  157. data/vendored/puppet/lib/puppet/parser/functions/with.rb +4 -4
  158. data/vendored/puppet/lib/puppet/parser/resource.rb +0 -1
  159. data/vendored/puppet/lib/puppet/parser/resource/param.rb +12 -5
  160. data/vendored/puppet/lib/puppet/parser/scope.rb +5 -7
  161. data/vendored/puppet/lib/puppet/pops/evaluator/compare_operator.rb +3 -1
  162. data/vendored/puppet/lib/puppet/pops/evaluator/runtime3_support.rb +2 -7
  163. data/vendored/puppet/lib/puppet/pops/issues.rb +4 -0
  164. data/vendored/puppet/lib/puppet/pops/loader/loader_paths.rb +2 -2
  165. data/vendored/puppet/lib/puppet/pops/loader/module_loaders.rb +17 -12
  166. data/vendored/puppet/lib/puppet/pops/loader/task_instantiator.rb +73 -45
  167. data/vendored/puppet/lib/puppet/pops/lookup/lookup_adapter.rb +55 -6
  168. data/vendored/puppet/lib/puppet/pops/model/model_label_provider.rb +2 -0
  169. data/vendored/puppet/lib/puppet/pops/parser/epp_parser.rb +1 -1
  170. data/vendored/puppet/lib/puppet/pops/parser/epp_support.rb +6 -2
  171. data/vendored/puppet/lib/puppet/pops/parser/lexer2.rb +1 -1
  172. data/vendored/puppet/lib/puppet/pops/pcore.rb +7 -7
  173. data/vendored/puppet/lib/puppet/pops/puppet_stack.rb +15 -1
  174. data/vendored/puppet/lib/puppet/pops/serialization.rb +2 -2
  175. data/vendored/puppet/lib/puppet/pops/serialization/from_data_converter.rb +2 -2
  176. data/vendored/puppet/lib/puppet/pops/serialization/json.rb +7 -7
  177. data/vendored/puppet/lib/puppet/pops/serialization/to_data_converter.rb +5 -5
  178. data/vendored/puppet/lib/puppet/pops/types/types.rb +8 -4
  179. data/vendored/puppet/lib/puppet/pops/validation/checker4_0.rb +73 -0
  180. data/vendored/puppet/lib/puppet/pops/validation/validator_factory_4_0.rb +4 -3
  181. data/vendored/puppet/lib/puppet/provider/augeas/augeas.rb +7 -0
  182. data/vendored/puppet/lib/puppet/provider/service/systemd.rb +1 -1
  183. data/vendored/puppet/lib/puppet/provider/user/aix.rb +2 -2
  184. data/vendored/puppet/lib/puppet/provider/yumrepo/inifile.rb +21 -9
  185. data/vendored/puppet/lib/puppet/reference/providers.rb +1 -1
  186. data/vendored/puppet/lib/puppet/reference/report.rb +1 -1
  187. data/vendored/puppet/lib/puppet/resource.rb +1 -1
  188. data/vendored/puppet/lib/puppet/resource/capability_finder.rb +4 -4
  189. data/vendored/puppet/lib/puppet/resource/catalog.rb +6 -3
  190. data/vendored/puppet/lib/puppet/resource/type.rb +6 -2
  191. data/vendored/puppet/lib/puppet/rest/client.rb +79 -0
  192. data/vendored/puppet/lib/puppet/rest/errors.rb +14 -0
  193. data/vendored/puppet/lib/puppet/rest/response.rb +29 -0
  194. data/vendored/puppet/lib/puppet/rest/route.rb +102 -0
  195. data/vendored/puppet/lib/puppet/rest/routes.rb +31 -0
  196. data/vendored/puppet/lib/puppet/settings.rb +9 -5
  197. data/vendored/puppet/lib/puppet/settings/config_file.rb +1 -1
  198. data/vendored/puppet/lib/puppet/settings/environment_conf.rb +10 -1
  199. data/vendored/puppet/lib/puppet/ssl.rb +0 -1
  200. data/vendored/puppet/lib/puppet/ssl/certificate.rb +6 -2
  201. data/vendored/puppet/lib/puppet/ssl/certificate_authority.rb +3 -3
  202. data/vendored/puppet/lib/puppet/ssl/host.rb +258 -19
  203. data/vendored/puppet/lib/puppet/ssl/validator/default_validator.rb +33 -19
  204. data/vendored/puppet/lib/puppet/syntax_checkers/json.rb +1 -1
  205. data/vendored/puppet/lib/puppet/transaction/event.rb +34 -7
  206. data/vendored/puppet/lib/puppet/transaction/report.rb +17 -14
  207. data/vendored/puppet/lib/puppet/type.rb +20 -12
  208. data/vendored/puppet/lib/puppet/type/file.rb +1 -1
  209. data/vendored/puppet/lib/puppet/type/file/content.rb +15 -2
  210. data/vendored/puppet/lib/puppet/type/file/ensure.rb +1 -1
  211. data/vendored/puppet/lib/puppet/type/schedule.rb +1 -1
  212. data/vendored/puppet/lib/puppet/type/stage.rb +1 -1
  213. data/vendored/puppet/lib/puppet/type/tidy.rb +5 -1
  214. data/vendored/puppet/lib/puppet/type/user.rb +35 -18
  215. data/vendored/puppet/lib/puppet/type/yumrepo.rb +8 -17
  216. data/vendored/puppet/lib/puppet/util.rb +0 -1
  217. data/vendored/puppet/lib/puppet/util/autoload.rb +1 -6
  218. data/vendored/puppet/lib/puppet/util/checksums.rb +0 -2
  219. data/vendored/puppet/lib/puppet/util/classgen.rb +0 -6
  220. data/vendored/puppet/lib/puppet/util/fileparsing.rb +27 -5
  221. data/vendored/puppet/lib/puppet/util/instance_loader.rb +3 -3
  222. data/vendored/puppet/lib/puppet/util/json.rb +77 -0
  223. data/vendored/puppet/lib/puppet/util/json_lockfile.rb +3 -3
  224. data/vendored/puppet/lib/puppet/util/ldap/connection.rb +7 -7
  225. data/vendored/puppet/lib/puppet/util/log/destinations.rb +2 -2
  226. data/vendored/puppet/lib/puppet/util/logging.rb +1 -1
  227. data/vendored/puppet/lib/puppet/util/plist.rb +1 -1
  228. data/vendored/puppet/lib/puppet/util/provider_features.rb +2 -5
  229. data/vendored/puppet/lib/puppet/util/reference.rb +5 -4
  230. data/vendored/puppet/lib/puppet/util/tagging.rb +16 -3
  231. data/vendored/puppet/lib/puppet/version.rb +1 -1
  232. metadata +44 -26
  233. data/vendored/puppet/lib/puppet/application/master.rb +0 -317
  234. data/vendored/puppet/lib/puppet/feature/rack.rb +0 -19
  235. data/vendored/puppet/lib/puppet/network/http/api/ca.rb +0 -2
  236. data/vendored/puppet/lib/puppet/network/http/api/ca/v1.rb +0 -11
  237. data/vendored/puppet/lib/puppet/network/http/rack.rb +0 -33
  238. data/vendored/puppet/lib/puppet/network/http/rack/rest.rb +0 -162
  239. data/vendored/puppet/lib/puppet/network/http/webrick.rb +0 -124
  240. data/vendored/puppet/lib/puppet/network/http/webrick/rest.rb +0 -114
  241. data/vendored/puppet/lib/puppet/network/server.rb +0 -39
  242. data/vendored/puppet/lib/puppet/ssl/configuration.rb +0 -61
  243. data/vendored/puppet/lib/puppet/util/methodhelper.rb +0 -32
  244. data/vendored/puppet/lib/puppet/vendor/load_semantic.rb +0 -1
  245. data/vendored/puppet/lib/puppet/vendor/load_semantic_puppet.rb +0 -1
  246. data/vendored/puppet/lib/puppet/vendor/semantic/lib/semantic.rb +0 -5
  247. data/vendored/puppet/lib/puppet/vendor/semantic_puppet/lib/semantic_puppet.rb +0 -11
  248. data/vendored/puppet/lib/puppet/vendor/semantic_puppet/lib/semantic_puppet/dependency.rb +0 -181
  249. data/vendored/puppet/lib/puppet/vendor/semantic_puppet/lib/semantic_puppet/dependency/graph.rb +0 -60
  250. data/vendored/puppet/lib/puppet/vendor/semantic_puppet/lib/semantic_puppet/dependency/graph_node.rb +0 -117
  251. data/vendored/puppet/lib/puppet/vendor/semantic_puppet/lib/semantic_puppet/dependency/module_release.rb +0 -58
  252. data/vendored/puppet/lib/puppet/vendor/semantic_puppet/lib/semantic_puppet/dependency/source.rb +0 -25
  253. data/vendored/puppet/lib/puppet/vendor/semantic_puppet/lib/semantic_puppet/dependency/unsatisfiable_graph.rb +0 -31
  254. data/vendored/puppet/lib/puppet/vendor/semantic_puppet/lib/semantic_puppet/gem_version.rb +0 -3
  255. data/vendored/puppet/lib/puppet/vendor/semantic_puppet/lib/semantic_puppet/version.rb +0 -203
  256. data/vendored/puppet/lib/puppet/vendor/semantic_puppet/lib/semantic_puppet/version_range.rb +0 -758
@@ -1176,11 +1176,15 @@ Generated on #{Time.now}.
1176
1176
  if configured_environment == "production" && envdir && Puppet::FileSystem.exist?(envdir)
1177
1177
  configured_environment_path = File.join(envdir, configured_environment)
1178
1178
  if !Puppet::FileSystem.symlink?(configured_environment_path)
1179
- catalog.add_resource(
1180
- Puppet::Resource.new(:file,
1181
- configured_environment_path,
1182
- :parameters => { :ensure => 'directory' })
1183
- )
1179
+ parameters = { :ensure => 'directory' }
1180
+ unless Puppet::FileSystem.exist?(configured_environment_path)
1181
+ parameters.merge!(:mode => '0750')
1182
+ if Puppet.features.root?
1183
+ parameters.merge!(:owner => Puppet[:user]) if service_user_available?
1184
+ parameters.merge!(:group => Puppet[:group]) if service_group_available?
1185
+ end
1186
+ end
1187
+ catalog.add_resource(Puppet::Resource.new(:file, configured_environment_path, :parameters => parameters))
1184
1188
  end
1185
1189
  end
1186
1190
  end
@@ -90,7 +90,7 @@ private
90
90
  message += ' ' + _("The only valid puppet.conf sections are: [%{allowed_sections_list}].") %
91
91
  { allowed_sections_list: allowed_section_names.join(", ") }
92
92
  message += ' ' + _("Please use the directory environments feature to specify environments.")
93
- message += ' ' + _("(See https://docs.puppet.com/puppet/latest/reference/environments.html)")
93
+ message += ' ' + _("(See https://puppet.com/docs/puppet/latest/environments_about.html)")
94
94
  raise(Puppet::Error, message)
95
95
  end
96
96
  section.name
@@ -101,7 +101,7 @@ class Puppet::Settings::EnvironmentConf
101
101
  path = modulepath.kind_of?(String) ?
102
102
  modulepath.split(File::PATH_SEPARATOR) :
103
103
  modulepath
104
- path.map { |p| absolute(p) }.join(File::PATH_SEPARATOR)
104
+ path.map { |p| expand_glob(absolute(p)) }.flatten.join(File::PATH_SEPARATOR)
105
105
  end
106
106
  end
107
107
 
@@ -166,6 +166,15 @@ class Puppet::Settings::EnvironmentConf
166
166
  yield value
167
167
  end
168
168
 
169
+ def expand_glob(path)
170
+ return nil if path.nil?
171
+ if path =~ /[*?\[\{]/
172
+ Dir.glob(path)
173
+ else
174
+ path
175
+ end
176
+ end
177
+
169
178
  def absolute(path)
170
179
  return nil if path.nil?
171
180
  if path =~ /^\$/
@@ -4,7 +4,6 @@ require 'openssl'
4
4
 
5
5
  module Puppet::SSL # :nodoc:
6
6
  CA_NAME = "ca"
7
- require 'puppet/ssl/configuration'
8
7
  require 'puppet/ssl/host'
9
8
  require 'puppet/ssl/oids'
10
9
  require 'puppet/ssl/validator'
@@ -21,12 +21,16 @@ DOC
21
21
  [:s]
22
22
  end
23
23
 
24
- def subject_alt_names
25
- alts = content.extensions.find{|ext| ext.oid == "subjectAltName"}
24
+ def self.subject_alt_names_for(cert)
25
+ alts = cert.extensions.find{|ext| ext.oid == "subjectAltName"}
26
26
  return [] unless alts
27
27
  alts.value.split(/\s*,\s*/)
28
28
  end
29
29
 
30
+ def subject_alt_names
31
+ self.class.subject_alt_names_for(content)
32
+ end
33
+
30
34
  def expiration
31
35
  return nil unless content
32
36
  content.not_after
@@ -209,7 +209,7 @@ class Puppet::SSL::CertificateAuthority
209
209
  #
210
210
  # @deprecated Use Puppet::SSL::CertificateAuthority#list or Puppet Server Certificate status API
211
211
  def list_certificates(name='*')
212
- Puppet.deprecation_warning(_("Puppet::SSL::CertificateAuthority#list_certificates is deprecated. Please use Puppet::SSL::CertificateAuthority#list or the certificate status API to query certificate information. See https://docs.puppet.com/puppet/latest/http_api/http_certificate_status.html"))
212
+ Puppet.deprecation_warning(_("Puppet::SSL::CertificateAuthority#list_certificates is deprecated. Please use Puppet::SSL::CertificateAuthority#list or the certificate status API to query certificate information. See https://puppet.com/docs/puppet/latest/http_api/http_certificate_status.html"))
213
213
  Puppet::SSL::Certificate.indirection.search(name)
214
214
  end
215
215
 
@@ -446,7 +446,7 @@ class Puppet::SSL::CertificateAuthority
446
446
  store.add_file(Puppet[:cacert])
447
447
  store.add_crl(crl.content) if self.crl
448
448
  store.purpose = OpenSSL::X509::PURPOSE_SSL_CLIENT
449
- if Puppet.lookup(:certificate_revocation)
449
+ if Puppet.settings[:certificate_revocation]
450
450
  store.flags = OpenSSL::X509::V_FLAG_CRL_CHECK_ALL | OpenSSL::X509::V_FLAG_CRL_CHECK
451
451
  end
452
452
  store
@@ -477,7 +477,7 @@ class Puppet::SSL::CertificateAuthority
477
477
  #
478
478
  # @deprecated use Puppet::SSL::CertificateAuthority#verify or Puppet Server certificate status API
479
479
  def certificate_is_alive?(cert)
480
- Puppet.deprecation_warning(_("Puppet::SSL::CertificateAuthority#certificate_is_alive? is deprecated. Please use Puppet::SSL::CertificateAuthority#verify or the certificate status API to query certificate information. See https://docs.puppet.com/puppet/latest/http_api/http_certificate_status.html"))
480
+ Puppet.deprecation_warning(_("Puppet::SSL::CertificateAuthority#certificate_is_alive? is deprecated. Please use Puppet::SSL::CertificateAuthority#verify or the certificate status API to query certificate information. See https://puppet.com/docs/puppet/latest/http_api/http_certificate_status.html"))
481
481
  x509_store(:cache => true).verify(cert.content)
482
482
  end
483
483
 
@@ -5,6 +5,8 @@ require 'puppet/ssl/certificate'
5
5
  require 'puppet/ssl/certificate_request'
6
6
  require 'puppet/ssl/certificate_revocation_list'
7
7
  require 'puppet/ssl/certificate_request_attributes'
8
+ require 'puppet/rest/errors'
9
+ require 'puppet/rest/routes'
8
10
 
9
11
  # The class that manages all aspects of our SSL certificates --
10
12
  # private keys, public keys, requests, etc.
@@ -22,10 +24,10 @@ class Puppet::SSL::Host
22
24
  The indirection key is the certificate CN (generally a hostname).
23
25
  DOC
24
26
 
25
- attr_reader :name
27
+ attr_reader :name, :crl_path
26
28
  attr_accessor :ca
27
29
 
28
- attr_writer :key, :certificate, :certificate_request
30
+ attr_writer :key, :certificate, :certificate_request, :crl_usage
29
31
 
30
32
  # This accessor is used in instances for indirector requests to hold desired state
31
33
  attr_accessor :desired_state
@@ -192,14 +194,25 @@ DOC
192
194
  true
193
195
  end
194
196
 
197
+ def http_client
198
+ # This can't be required top-level because Puppetserver uses the Host class too,
199
+ # and we don't ship the gem in that context.
200
+ require 'puppet/rest/client'
201
+ @http_client ||= Puppet::Rest::Client.new
202
+ end
203
+
195
204
  def certificate
196
205
  unless @certificate
197
206
  generate_key unless key
198
207
 
199
208
  # get the CA cert first, since it's required for the normal cert
200
- # to be of any use.
201
- return nil unless Certificate.indirection.find("ca", :fail_on_404 => true) unless ca?
202
- return nil unless @certificate = Certificate.indirection.find(name)
209
+ # to be of any use. If we can't get it, quit.
210
+ if !ca? && !ensure_ca_certificate
211
+ return nil
212
+ end
213
+
214
+ @certificate = get_host_certificate
215
+ return nil unless @certificate
203
216
 
204
217
  validate_certificate_with_key
205
218
  end
@@ -264,6 +277,8 @@ ERROR_STRING
264
277
  Puppet::SSL::Base.validate_certname(@name)
265
278
  @key = @certificate = @certificate_request = nil
266
279
  @ca = (name == self.class.ca_name)
280
+ @crl_usage = Puppet.settings[:certificate_revocation]
281
+ @crl_path = Puppet.settings[:hostcrl]
267
282
  end
268
283
 
269
284
  # Extract the public key from the private key.
@@ -271,10 +286,19 @@ ERROR_STRING
271
286
  key.content.public_key
272
287
  end
273
288
 
289
+ def use_crl?
290
+ !!@crl_usage
291
+ end
292
+
293
+ def use_crl_chain?
294
+ @crl_usage == true || @crl_usage == :chain
295
+ end
296
+
274
297
  # Create/return a store that uses our SSL info to validate
275
298
  # connections.
276
299
  def ssl_store(purpose = OpenSSL::X509::PURPOSE_ANY)
277
300
  if @ssl_store.nil?
301
+ ensure_crl_if_needed
278
302
  @ssl_store = build_ssl_store(purpose)
279
303
  end
280
304
  @ssl_store
@@ -371,27 +395,242 @@ ERROR_STRING
371
395
 
372
396
  private
373
397
 
398
+ # Ensures that CRL is either on disk, or that CRL checking has been disabled
399
+ def ensure_crl_if_needed
400
+ if use_crl? && !Puppet::FileSystem.exist?(crl_path)
401
+ # The CertificateRevocationList indirector will attempt to download the
402
+ # CRL from the CA if it does not exist on disk. It will ask host for
403
+ # its ssl_store again, but expect crl checking to be disabled for that
404
+ # store. This is not thread safe, and should be replaced as soon as we
405
+ # no longer need to use the indirector to download the CRL (PUP-8654).
406
+ old_crl_usage = @crl_usage
407
+ @crl_usage = false
408
+ Puppet.debug _("Disabling certificate revocation checking when fetching the CRL and no CRL is present")
409
+ if !CertificateRevocationList.indirection.find(CA_NAME)
410
+ raise Puppet::Error,
411
+ _("Certificate revocation checking is enabled but a CRL cannot be found; CRL checking will not be performed.")
412
+ end
413
+ @crl_usage = old_crl_usage
414
+ end
415
+ end
416
+
417
+ # @param path [String] Path to CRL Chain
418
+ # @return [Array<OpenSSL::X509::CRL>] CRLs from chain
419
+ # @raise [Errno::ENOENT] if file does not exist
420
+ # @raise [Puppet::Error<OpenSSL::X509::CRLError>] if the CRL chain is malformed
421
+ def load_crls(path)
422
+ delimiters = /-----BEGIN X509 CRL-----.*?-----END X509 CRL-----/m
423
+ crls_pems = Puppet::FileSystem.read(path, encoding: Encoding::UTF_8)
424
+ crls_pems.scan(delimiters).map do |crl|
425
+ begin
426
+ OpenSSL::X509::CRL.new(crl)
427
+ rescue OpenSSL::X509::CRLError => e
428
+ raise Puppet::Error.new(
429
+ _("Failed attempting to load CRL from %{crl_path}! The CRL below caused the error '%{error}':\n%{crl}" % {crl_path: crl_path, error: e.message, crl: crl}),
430
+ e)
431
+ end
432
+ end
433
+ end
434
+
435
+ # Ensures that the CA certificate is available for either generating or
436
+ # validating the host's cert.
437
+ # It will first check if the cert is present in memory (used for testing),
438
+ # then check on disk, and finally try to download it.
439
+ # @raise [Puppet::Error] if text form of found certificate bundle is invalid
440
+ # and cannot be loaded into cert objects
441
+ # @return [Boolean] true if the CA certificate was found, false otherwise
442
+ def ensure_ca_certificate
443
+ file_path = certificate_location(CA_NAME)
444
+ if check_for_certificate_in_memory(CA_NAME)
445
+ true
446
+ elsif Puppet::FileSystem.exist?(file_path)
447
+ begin
448
+ # This load ensures that the file contents is a valid cert bundle.
449
+ # If the text is malformed, load_certificate_bundle will raise.
450
+ load_certificate_bundle(Puppet::FileSystem.read(file_path))
451
+ rescue Puppet::Error => e
452
+ raise Puppet::Error, _("The CA certificate at %{file_path} is invalid: %{message}") % { file_path: file_path, message: e.message }
453
+ end
454
+ else
455
+ bundle = download_ca_certificate_bundle
456
+ if bundle
457
+ save_certificate_bundle(bundle)
458
+ true
459
+ else
460
+ false
461
+ end
462
+ end
463
+ end
464
+
465
+ # Creates an arry of SSL Certificate objects from a PEM-encoding string
466
+ # of one or more certs.
467
+ # @param [String] bundle_string PEM-encoded string of certs
468
+ # @return [[OpenSSL::X509::Certificate], nil] the certs loaded from the
469
+ # input string, or nil if none could be loaded
470
+ def load_certificate_bundle(bundle_string)
471
+ delimiters = /-----BEGIN CERTIFICATE-----.*?-----END CERTIFICATE-----/m
472
+ certs = bundle_string.scan(delimiters)
473
+
474
+ if certs.empty?
475
+ raise Puppet::Error, _("No valid PEM-encoded certificates.")
476
+ end
477
+
478
+ certs.map do |cert|
479
+ begin
480
+ OpenSSL::X509::Certificate.new(cert)
481
+ rescue OpenSSL::X509::CertificateError => e
482
+ raise Puppet::Error, _("Could not parse certificate: %{message}") % { message: e.message }
483
+ end
484
+ end
485
+ end
486
+
487
+ # Fetches the CA certificate bundle from the CA server
488
+ # @raise [Puppet::Error] if response from the server is not a valid certificate
489
+ # bundle
490
+ # @return [[OpenSSL::X509::Certificate]] the certs loaded from the response
491
+ def download_ca_certificate_bundle
492
+ return nil if Puppet::SSL::Host.ca_location != :remote
493
+
494
+ begin
495
+ cert_bundle = Puppet::Rest::Routes.get_certificate(http_client, CA_NAME)
496
+ # This load ensures that the response body is a valid cert bundle.
497
+ # If the text is malformed, load_certificate_bundle will raise.
498
+ begin
499
+ load_certificate_bundle(cert_bundle)
500
+ rescue Puppet::Error => e
501
+ raise Puppet::Error, _("Response from the CA did not contain a valid CA certificate: %{message}") % { message: e.message }
502
+ end
503
+ rescue Puppet::Rest::ResponseError => e
504
+ raise Puppet::Error, _('Could not download CA certificate: %{message}') % { message: e.message }
505
+ end
506
+ end
507
+
508
+ # Saves the given certs to disc, to a location determined based
509
+ # on this host's configuration.
510
+ # @param [[OpenSSL::X509::Certificate]] the certs to save
511
+ def save_certificate_bundle(cert_bundle)
512
+ Puppet::Util.replace_file(certificate_location(CA_NAME), 0644) do |f|
513
+ bundle_string = cert_bundle.map(&:to_pem).join("\n")
514
+ f.write(bundle_string)
515
+ end
516
+ end
517
+
518
+ # Attempts to load or fetch this host's certificate. Returns nil if
519
+ # no certificate could be found.
520
+ # @return [Puppet::SSL::Certificate, nil]
521
+ def get_host_certificate
522
+ if cert = check_for_certificate_in_memory(name)
523
+ return cert
524
+ elsif cert = check_for_certificate_on_disk(name)
525
+ return cert
526
+ elsif cert = download_certificate_from_ca(name)
527
+ save_host_certificate(cert)
528
+ return cert
529
+ else
530
+ return nil
531
+ end
532
+ end
533
+
534
+ # Checks the certificate indirection for a cert stored in memory.
535
+ # Only relevant if the memory terminus is in use, and currently
536
+ # only used in testing.
537
+ # @param [String] name the name of the cert to look for
538
+ # @return [Puppet::SSL::Certificate, nil]
539
+ def check_for_certificate_in_memory(cert_name)
540
+ if Puppet::SSL::Certificate.indirection.terminus_class == :memory
541
+ return Puppet::SSL::Certificate.indirection.find(cert_name)
542
+ end
543
+ end
544
+
545
+ # Checks for the requested certificate on disc, at a location
546
+ # determined by this host's configuration.
547
+ # @name [String] name the name of the cert to look for
548
+ # @raise [Puppet::Error] if contents of certificate file is invalid
549
+ # and could not be loaded
550
+ # @return [Puppet::SSL::Certificate, nil]
551
+ def check_for_certificate_on_disk(cert_name)
552
+ file_path = certificate_location(cert_name)
553
+ if Puppet::FileSystem.exist?(file_path)
554
+ begin
555
+ Puppet::SSL::Certificate.from_s(Puppet::FileSystem.read(file_path))
556
+ rescue OpenSSL::X509::CertificateError
557
+ raise Puppet::Error, _("The certificate at %{file_path} is invalid. Could not load.") % { file_path: file_path }
558
+ end
559
+ end
560
+ end
561
+
562
+ # Attempts to download this host's certificate from the CA server.
563
+ # Returns nil if the CA does not yet have a signed cert for this host.
564
+ # @param [String] name then name of the cert to fetch
565
+ # @raise [Puppet::Error] if response from the CA does not contain a valid
566
+ # certificate
567
+ # @return [Puppet::SSL::Certificate, nil]
568
+ def download_certificate_from_ca(cert_name)
569
+ return nil if Puppet::SSL::Host.ca_location != :remote
570
+
571
+ begin
572
+ cert = Puppet::Rest::Routes.get_certificate(http_client, cert_name)
573
+ begin
574
+ Puppet::SSL::Certificate.from_s(cert)
575
+ rescue OpenSSL::X509::CertificateError
576
+ raise Puppet::Error, _("Response from the CA did not contain a valid certificate for %{cert_name}.") % { cert_name: cert_name }
577
+ end
578
+ rescue Puppet::Rest::ResponseError => e
579
+ if e.response.status_code == 404
580
+ Puppet.debug _("No certificate for %{cert_name} on CA") % { cert_name: cert_name }
581
+ nil
582
+ else
583
+ raise Puppet::Rest::ResponseError, _("Could not download host certificate: %{message}") % { message: e.message }
584
+ end
585
+ end
586
+ end
587
+
588
+ # Saves the given certificate to disc, at a location determined by this
589
+ # host's configuration.
590
+ # @param [Puppet::SSL::Certificate] cert the cert to save
591
+ def save_host_certificate(cert)
592
+ file_path = certificate_location(name)
593
+ Puppet::Util.replace_file(file_path, 0644) do |f|
594
+ f.write(cert.to_s)
595
+ end
596
+ end
597
+
598
+ # Returns the file path for the named certificate, based on this host's
599
+ # configuration.
600
+ # @param [String] name the name of the cert to find
601
+ # @return [String] file path to the certs location
602
+ def certificate_location(cert_name)
603
+ if Puppet::SSL::Host.ca_location == :only
604
+ cert_name == CA_NAME ? Puppet[:cacert] : File.join(Puppet[:signeddir], "#{cert_name}.pem")
605
+ else
606
+ cert_name == CA_NAME ? Puppet[:localcacert] : File.join(Puppet[:certdir], "#{cert_name}.pem")
607
+ end
608
+ end
609
+
610
+ # @param [OpenSSL::X509::PURPOSE_*] constant defining the kinds of certs
611
+ # this store can verify
612
+ # @return [OpenSSL::X509::Store]
613
+ # @raise [OpenSSL::X509::StoreError] if localcacert is malformed or non-existant
614
+ # @raise [Puppet::Error] if the CRL chain is malformed
615
+ # @raise [Errno::ENOENT] if the CRL does not exist on disk but use_crl? is true
374
616
  def build_ssl_store(purpose)
375
617
  store = OpenSSL::X509::Store.new
376
618
  store.purpose = purpose
377
619
 
378
620
  # Use the file path here, because we don't want to cause
379
621
  # a lookup in the middle of setting our ssl connection.
380
- store.add_file(Puppet[:localcacert])
381
-
382
- # If we're doing revocation and there's a CRL, add it to our store.
383
- if Puppet.lookup(:certificate_revocation)
384
- if crl = Puppet::SSL::CertificateRevocationList.indirection.find(CA_NAME)
385
- flags = OpenSSL::X509::V_FLAG_CRL_CHECK
386
- if Puppet.lookup(:certificate_revocation) == :chain
387
- flags |= OpenSSL::X509::V_FLAG_CRL_CHECK_ALL
388
- end
389
-
390
- store.flags = flags
391
- store.add_crl(crl.content)
392
- else
393
- Puppet.debug _("Certificate revocation checking is enabled but a CRL cannot be found; CRL checking will not be performed.")
622
+ store.add_file(Puppet.settings[:localcacert])
623
+
624
+ if use_crl?
625
+ crls = load_crls(crl_path)
626
+
627
+ flags = OpenSSL::X509::V_FLAG_CRL_CHECK
628
+ if use_crl_chain?
629
+ flags |= OpenSSL::X509::V_FLAG_CRL_CHECK_ALL
394
630
  end
631
+
632
+ store.flags = flags
633
+ crls.each {|crl| store.add_crl(crl) }
395
634
  end
396
635
  store
397
636
  end
@@ -9,27 +9,20 @@ require 'puppet/ssl'
9
9
  class Puppet::SSL::Validator::DefaultValidator #< class Puppet::SSL::Validator
10
10
  attr_reader :peer_certs
11
11
  attr_reader :verify_errors
12
- attr_reader :ssl_configuration
13
12
 
14
13
  FIVE_MINUTES_AS_SECONDS = 5 * 60
15
14
 
16
15
  # Creates a new DefaultValidator, optionally with an SSL Configuration and SSL Host.
17
16
  #
18
- # @param ssl_configuration [Puppet::SSL::Configuration] (a default configuration) ssl_configuration the SSL configuration to use
19
- # @param ssl_host [Puppet::SSL::Host] The SSL host to use
17
+ # @param ca_path [String] Filepath for the cacert
20
18
  #
21
19
  # @api private
22
20
  #
23
21
  def initialize(
24
- ssl_configuration = Puppet::SSL::Configuration.new(
25
- Puppet[:localcacert], {
26
- :ca_auth_file => Puppet[:ssl_client_ca_auth]
27
- }),
28
- ssl_host = Puppet.lookup(:ssl_host))
22
+ ca_path = Puppet[:ssl_client_ca_auth] || Puppet[:localcacert])
29
23
 
30
24
  reset!
31
- @ssl_configuration = ssl_configuration
32
- @ssl_host = ssl_host
25
+ @ca_path = ca_path
33
26
  end
34
27
 
35
28
 
@@ -70,7 +63,7 @@ class Puppet::SSL::Validator::DefaultValidator #< class Puppet::SSL::Validator
70
63
  #
71
64
  def call(preverify_ok, store_context)
72
65
  current_cert = store_context.current_cert
73
- @peer_certs << Puppet::SSL::Certificate.from_instance(current_cert)
66
+ @peer_certs << current_cert
74
67
 
75
68
  # We must make a copy since the scope of the store_context will be lost
76
69
  # across invocations of this method.
@@ -113,16 +106,17 @@ class Puppet::SSL::Validator::DefaultValidator #< class Puppet::SSL::Validator
113
106
  #
114
107
  # @param [Net::HTTP] connection The connection to validate
115
108
  #
109
+ # @param [Puppet::SSL::Host] host The host object containing SSL data
116
110
  # @return [void]
117
111
  #
118
112
  # @api private
119
113
  #
120
- def setup_connection(connection)
114
+ def setup_connection(connection, ssl_host = Puppet.lookup(:ssl_host))
121
115
  if ssl_certificates_are_present?
122
- connection.cert_store = @ssl_host.ssl_store
123
- connection.ca_file = @ssl_configuration.ca_auth_file
124
- connection.cert = @ssl_host.certificate.content
125
- connection.key = @ssl_host.key.content
116
+ connection.cert_store = ssl_host.ssl_store
117
+ connection.ca_file = @ca_path
118
+ connection.cert = ssl_host.certificate.content
119
+ connection.key = ssl_host.key.content
126
120
  connection.verify_mode = OpenSSL::SSL::VERIFY_PEER
127
121
  connection.verify_callback = self
128
122
  else
@@ -130,13 +124,33 @@ class Puppet::SSL::Validator::DefaultValidator #< class Puppet::SSL::Validator
130
124
  end
131
125
  end
132
126
 
127
+ ##
128
+ # Decode a string of concatenated certificates
129
+ #
130
+ # @return [Array<OpenSSL::X509::Certificate>]
131
+ def decode_cert_bundle(bundle_str)
132
+ re = /-----BEGIN CERTIFICATE-----.*?-----END CERTIFICATE-----/m
133
+ pem_ary = bundle_str.scan(re)
134
+ pem_ary.map do |pem_str|
135
+ OpenSSL::X509::Certificate.new(pem_str)
136
+ end
137
+ end
138
+
139
+ # read_file makes testing easier.
140
+ def read_file(path)
141
+ # https://www.ietf.org/rfc/rfc2459.txt defines the x509 V3 certificate format
142
+ # CA bundles are concatenated X509 certificates, but may also include
143
+ # comments, which could have UTF-8 characters
144
+ Puppet::FileSystem.read(path, :encoding => Encoding::UTF_8)
145
+ end
146
+
133
147
  # Validates the peer certificates against the authorized certificates.
134
148
  #
135
149
  # @api private
136
150
  #
137
151
  def valid_peer?
138
- descending_cert_chain = @peer_certs.reverse.map {|c| c.content }
139
- authz_ca_certs = ssl_configuration.ca_auth_certificates
152
+ descending_cert_chain = @peer_certs.reverse
153
+ authz_ca_certs = decode_cert_bundle(read_file(@ca_path))
140
154
 
141
155
  if not has_authz_peer_cert(descending_cert_chain, authz_ca_certs)
142
156
  msg = "The server presented a SSL certificate chain which does not include a " <<
@@ -168,6 +182,6 @@ class Puppet::SSL::Validator::DefaultValidator #< class Puppet::SSL::Validator
168
182
  # @api private
169
183
  #
170
184
  def ssl_certificates_are_present?
171
- Puppet::FileSystem.exist?(Puppet[:hostcert]) && Puppet::FileSystem.exist?(@ssl_configuration.ca_auth_file)
185
+ Puppet::FileSystem.exist?(Puppet[:hostcert]) && Puppet::FileSystem.exist?(@ca_path)
172
186
  end
173
187
  end