puppet 6.25.0-x86-mingw32 → 6.27.0-x86-mingw32

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

Potentially problematic release.


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

Files changed (106) hide show
  1. checksums.yaml +4 -4
  2. data/CODEOWNERS +1 -1
  3. data/Gemfile +2 -2
  4. data/Gemfile.lock +39 -32
  5. data/lib/puppet/application/lookup.rb +74 -24
  6. data/lib/puppet/concurrent/thread_local_singleton.rb +5 -3
  7. data/lib/puppet/configurer.rb +65 -11
  8. data/lib/puppet/defaults.rb +19 -3
  9. data/lib/puppet/face/generate.rb +2 -0
  10. data/lib/puppet/file_serving/metadata.rb +3 -0
  11. data/lib/puppet/file_system/file_impl.rb +7 -7
  12. data/lib/puppet/file_system/jruby.rb +1 -1
  13. data/lib/puppet/file_system/windows.rb +4 -4
  14. data/lib/puppet/file_system.rb +1 -1
  15. data/lib/puppet/functions/next.rb +18 -1
  16. data/lib/puppet/functions/tree_each.rb +0 -1
  17. data/lib/puppet/functions/versioncmp.rb +6 -2
  18. data/lib/puppet/generate/type.rb +9 -0
  19. data/lib/puppet/http/client.rb +1 -1
  20. data/lib/puppet/http/redirector.rb +5 -0
  21. data/lib/puppet/node.rb +1 -1
  22. data/lib/puppet/parser/resource.rb +1 -1
  23. data/lib/puppet/pops/evaluator/closure.rb +7 -5
  24. data/lib/puppet/pops/evaluator/runtime3_resource_support.rb +1 -0
  25. data/lib/puppet/pops/parser/code_merger.rb +4 -4
  26. data/lib/puppet/pops/parser/egrammar.ra +2 -0
  27. data/lib/puppet/pops/parser/eparser.rb +813 -794
  28. data/lib/puppet/pops/serialization/to_data_converter.rb +6 -18
  29. data/lib/puppet/provider/service/init.rb +5 -4
  30. data/lib/puppet/resource/catalog.rb +1 -1
  31. data/lib/puppet/resource.rb +38 -5
  32. data/lib/puppet/ssl/ssl_provider.rb +10 -7
  33. data/lib/puppet/ssl/verifier.rb +6 -0
  34. data/lib/puppet/transaction/persistence.rb +22 -12
  35. data/lib/puppet/type/exec.rb +1 -1
  36. data/lib/puppet/type/file/data_sync.rb +1 -1
  37. data/lib/puppet/type/user.rb +40 -38
  38. data/lib/puppet/util/json.rb +17 -0
  39. data/lib/puppet/util/log.rb +7 -2
  40. data/lib/puppet/util/monkey_patches.rb +6 -2
  41. data/lib/puppet/util/package.rb +25 -16
  42. data/lib/puppet/util/windows/service.rb +0 -5
  43. data/lib/puppet/util/windows.rb +3 -0
  44. data/lib/puppet/util/yaml.rb +21 -2
  45. data/lib/puppet/util.rb +1 -2
  46. data/lib/puppet/version.rb +1 -1
  47. data/lib/puppet.rb +1 -0
  48. data/locales/puppet.pot +5 -10454
  49. data/man/man5/puppet.conf.5 +21 -2
  50. data/man/man8/puppet-agent.8 +1 -1
  51. data/man/man8/puppet-apply.8 +1 -1
  52. data/man/man8/puppet-catalog.8 +1 -1
  53. data/man/man8/puppet-config.8 +1 -1
  54. data/man/man8/puppet-describe.8 +1 -1
  55. data/man/man8/puppet-device.8 +1 -1
  56. data/man/man8/puppet-doc.8 +1 -1
  57. data/man/man8/puppet-epp.8 +1 -1
  58. data/man/man8/puppet-facts.8 +1 -1
  59. data/man/man8/puppet-filebucket.8 +1 -1
  60. data/man/man8/puppet-generate.8 +1 -1
  61. data/man/man8/puppet-help.8 +1 -1
  62. data/man/man8/puppet-key.8 +1 -1
  63. data/man/man8/puppet-lookup.8 +9 -6
  64. data/man/man8/puppet-man.8 +1 -1
  65. data/man/man8/puppet-module.8 +1 -1
  66. data/man/man8/puppet-node.8 +1 -1
  67. data/man/man8/puppet-parser.8 +1 -1
  68. data/man/man8/puppet-plugin.8 +1 -1
  69. data/man/man8/puppet-report.8 +1 -1
  70. data/man/man8/puppet-resource.8 +1 -1
  71. data/man/man8/puppet-script.8 +1 -1
  72. data/man/man8/puppet-ssl.8 +1 -1
  73. data/man/man8/puppet-status.8 +1 -1
  74. data/man/man8/puppet.8 +2 -2
  75. data/spec/fixtures/integration/application/agent/cached_deferred_catalog.json +2 -1
  76. data/spec/fixtures/unit/forge/bacula.json +1 -1
  77. data/spec/integration/application/agent_spec.rb +28 -0
  78. data/spec/integration/application/lookup_spec.rb +81 -50
  79. data/spec/integration/application/resource_spec.rb +6 -2
  80. data/spec/integration/http/client_spec.rb +30 -0
  81. data/spec/integration/parser/pcore_resource_spec.rb +10 -0
  82. data/spec/shared_contexts/l10n.rb +5 -0
  83. data/spec/unit/application/lookup_spec.rb +131 -10
  84. data/spec/unit/concurrent/thread_local_singleton_spec.rb +39 -0
  85. data/spec/unit/configurer_spec.rb +197 -73
  86. data/spec/unit/face/generate_spec.rb +64 -0
  87. data/spec/unit/file_system_spec.rb +34 -4
  88. data/spec/unit/forge/module_release_spec.rb +3 -3
  89. data/spec/unit/functions/versioncmp_spec.rb +40 -4
  90. data/spec/unit/http/client_spec.rb +58 -1
  91. data/spec/unit/node_spec.rb +6 -0
  92. data/spec/unit/pops/parser/parse_containers_spec.rb +2 -2
  93. data/spec/unit/pops/serialization/to_from_hr_spec.rb +0 -58
  94. data/spec/unit/pops/validator/validator_spec.rb +5 -0
  95. data/spec/unit/provider/service/gentoo_spec.rb +6 -5
  96. data/spec/unit/provider/service/init_spec.rb +15 -9
  97. data/spec/unit/provider/service/openwrt_spec.rb +21 -29
  98. data/spec/unit/provider/service/redhat_spec.rb +3 -2
  99. data/spec/unit/resource/catalog_spec.rb +14 -1
  100. data/spec/unit/resource_spec.rb +58 -2
  101. data/spec/unit/transaction/persistence_spec.rb +51 -0
  102. data/spec/unit/type/user_spec.rb +0 -45
  103. data/spec/unit/util/json_spec.rb +126 -0
  104. data/spec/unit/util/windows_spec.rb +23 -0
  105. data/spec/unit/util/yaml_spec.rb +54 -29
  106. metadata +9 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5ecc17db745494f717c3fb39a2361293d3667eca0938ac781c2e77d70d9314fe
4
- data.tar.gz: 58f1cf1295996b99caeeebc6a5c235df85304a5aa473ba8361b84f8f3c43cb7a
3
+ metadata.gz: f5f0f081a7936b45170cd0228066956dabf9f226289f868f6ab5d212a643cf21
4
+ data.tar.gz: a41173a9cdee61c24c191c6a719ef33360b613d112a5e1da6e199c1bffe57bc9
5
5
  SHA512:
6
- metadata.gz: 6331d12d459eb1aefef844b8bb7c8637767c57bbdbbca6ee91c3aa87176f2367c806dc29703c38acd05ade0c70201a56f50ca4c22e0607b11ae2e2b288da649c
7
- data.tar.gz: 974a0df3f2663401d56031864e8ee696e462d8687a3369a3adf24acbf2501b1d3ab62390894c385b059e63c2eb2a51644c2e77f3ae03d1180ee848b7a3badef8
6
+ metadata.gz: ba51e906ce71f05f30c34f76b7b656a4e1f1707c29f5b18b96c4617f33485d1ccea56915e9b48cafa8f34f843ea911ddd37353cdda9d6d0490444325109c54ae
7
+ data.tar.gz: 967d852cbf0e1b8c8f2cc154ac7fa8316a8131044314a758295ca2f75a8cfa6537e4f69a3e99f88847b9df4cccc380e44b7b919c1e161954e484403d4b884504
data/CODEOWNERS CHANGED
@@ -1,5 +1,5 @@
1
1
  # defaults
2
- * @puppetlabs/platform-core @puppetlabs/puppetserver-maintainers @puppetlabs/night-s-watch
2
+ * @puppetlabs/phoenix @puppetlabs/puppetserver-maintainers
3
3
 
4
4
  # PAL
5
5
  /lib/puppet/pal @puppetlabs/bolt
data/Gemfile CHANGED
@@ -3,7 +3,7 @@ source ENV['GEM_SOURCE'] || "https://rubygems.org"
3
3
  gemspec
4
4
 
5
5
  def location_for(place, fake_version = nil)
6
- if place.is_a?(String) && place =~ /^(git[:@][^#]*)#(.*)/
6
+ if place.is_a?(String) && place =~ /^((?:git[:@]|https:)[^#]*)#(.*)/
7
7
  [fake_version, { git: $1, branch: $2, require: false }].compact
8
8
  elsif place.is_a?(String) && place =~ /^file:\/\/(.*)/
9
9
  ['>= 0', { path: File.expand_path($1), require: false }]
@@ -29,7 +29,7 @@ group(:features) do
29
29
  #gem 'ruby-shadow', '~> 2.5', require: false, platforms: [:ruby]
30
30
  gem 'minitar', '~> 0.9', require: false
31
31
  gem 'msgpack', '~> 1.2', require: false
32
- gem 'rdoc', '~> 6.0', require: false, platforms: [:ruby]
32
+ gem 'rdoc', ['~> 6.0', '< 6.4.0'], require: false, platforms: [:ruby]
33
33
  # requires native augeas headers/libs
34
34
  # gem 'ruby-augeas', require: false, platforms: [:ruby]
35
35
  # requires native ldap headers/libs
data/Gemfile.lock CHANGED
@@ -1,10 +1,11 @@
1
1
  GIT
2
- remote: git://github.com/puppetlabs/packaging
3
- revision: 48564f11abbc1f61a159d9caa44c8236d910575a
2
+ remote: https://github.com/puppetlabs/packaging
3
+ revision: 6f7b1ff00ab557f6a47f3f553cc87ec15d718470
4
4
  branch: 1.0.x
5
5
  specs:
6
- packaging (0.99.81)
7
- artifactory (~> 2)
6
+ packaging (0.106.0.27.g6f7b1ff)
7
+ apt_stage_artifacts
8
+ artifactory (~> 3)
8
9
  csv (= 3.1.5)
9
10
  rake (>= 12.3)
10
11
  release-metrics
@@ -12,7 +13,7 @@ GIT
12
13
  PATH
13
14
  remote: .
14
15
  specs:
15
- puppet (6.25.0)
16
+ puppet (6.27.0)
16
17
  CFPropertyList (~> 2.2)
17
18
  concurrent-ruby (~> 1.0)
18
19
  deep_merge (~> 1.0)
@@ -30,21 +31,23 @@ GEM
30
31
  CFPropertyList (2.3.6)
31
32
  addressable (2.8.0)
32
33
  public_suffix (>= 2.0.2, < 5.0)
33
- artifactory (2.8.2)
34
+ apt_stage_artifacts (0.10.1)
35
+ docopt
36
+ artifactory (3.0.15)
34
37
  ast (2.4.2)
35
38
  coderay (1.1.3)
36
- concurrent-ruby (1.1.9)
39
+ concurrent-ruby (1.1.10)
37
40
  crack (0.4.5)
38
41
  rexml
39
42
  csv (3.1.5)
40
- deep_merge (1.2.1)
41
- diff-lcs (1.4.4)
43
+ deep_merge (1.2.2)
44
+ diff-lcs (1.5.0)
42
45
  docopt (0.6.1)
43
- facter (4.2.5)
46
+ facter (4.2.9)
44
47
  hocon (~> 1.3)
45
48
  thor (>= 1.0.1, < 2.0)
46
49
  fast_gettext (1.1.2)
47
- ffi (1.15.4)
50
+ ffi (1.15.5)
48
51
  gettext (3.2.9)
49
52
  locale (>= 2.0.5)
50
53
  text (>= 1.3.0)
@@ -53,7 +56,7 @@ GEM
53
56
  gettext (>= 3.0.2, < 3.3.0)
54
57
  locale
55
58
  hashdiff (1.0.1)
56
- hiera (3.7.0)
59
+ hiera (3.8.0)
57
60
  hiera-eyaml (3.2.2)
58
61
  highline
59
62
  optimist
@@ -67,11 +70,11 @@ GEM
67
70
  memory_profiler (1.0.0)
68
71
  method_source (1.0.0)
69
72
  minitar (0.9)
70
- msgpack (1.4.2)
73
+ msgpack (1.5.0)
71
74
  multi_json (1.15.0)
72
75
  mustache (1.1.1)
73
76
  optimist (3.0.1)
74
- parallel (1.21.0)
77
+ parallel (1.22.1)
75
78
  parser (2.7.2.0)
76
79
  ast (~> 2.4.1)
77
80
  powerpack (0.1.3)
@@ -81,14 +84,14 @@ GEM
81
84
  public_suffix (4.0.6)
82
85
  puppet-resource_api (1.8.14)
83
86
  hocon (>= 1.0)
84
- puppetserver-ca (1.11.6)
87
+ puppetserver-ca (1.11.7)
85
88
  facter (>= 2.0.1, < 5)
86
89
  racc (1.5.2)
87
90
  rainbow (2.2.2)
88
91
  rake
89
92
  rake (12.3.3)
90
93
  rdiscount (2.2.0.2)
91
- rdoc (6.3.2)
94
+ rdoc (6.3.3)
92
95
  release-metrics (1.1.0)
93
96
  csv
94
97
  docopt
@@ -97,22 +100,22 @@ GEM
97
100
  hpricot (>= 0.8.2)
98
101
  mustache (>= 0.7.0)
99
102
  rdiscount (>= 1.5.8)
100
- rspec (3.10.0)
101
- rspec-core (~> 3.10.0)
102
- rspec-expectations (~> 3.10.0)
103
- rspec-mocks (~> 3.10.0)
104
- rspec-core (3.10.1)
105
- rspec-support (~> 3.10.0)
106
- rspec-expectations (3.10.1)
103
+ rspec (3.11.0)
104
+ rspec-core (~> 3.11.0)
105
+ rspec-expectations (~> 3.11.0)
106
+ rspec-mocks (~> 3.11.0)
107
+ rspec-core (3.11.0)
108
+ rspec-support (~> 3.11.0)
109
+ rspec-expectations (3.11.0)
107
110
  diff-lcs (>= 1.2.0, < 2.0)
108
- rspec-support (~> 3.10.0)
111
+ rspec-support (~> 3.11.0)
109
112
  rspec-its (1.3.0)
110
113
  rspec-core (>= 3.0.0)
111
114
  rspec-expectations (>= 3.0.0)
112
- rspec-mocks (3.10.2)
115
+ rspec-mocks (3.11.1)
113
116
  diff-lcs (>= 1.2.0, < 2.0)
114
- rspec-support (~> 3.10.0)
115
- rspec-support (3.10.2)
117
+ rspec-support (~> 3.11.0)
118
+ rspec-support (3.11.0)
116
119
  rubocop (0.49.1)
117
120
  parallel (~> 1.10)
118
121
  parser (>= 2.3.3.1, < 3.0)
@@ -124,19 +127,22 @@ GEM
124
127
  rubocop (~> 0.49.0)
125
128
  ruby-prof (1.4.3)
126
129
  ruby-progressbar (1.11.0)
130
+ scanf (1.0.0)
127
131
  semantic_puppet (1.0.4)
128
132
  text (1.3.1)
129
- thor (1.1.0)
133
+ thor (1.2.1)
130
134
  unicode-display_width (1.8.0)
131
135
  vcr (5.1.0)
132
136
  webmock (3.14.0)
133
137
  addressable (>= 2.8.0)
134
138
  crack (>= 0.3.2)
135
139
  hashdiff (>= 0.4.0, < 2.0.0)
136
- yard (0.9.26)
140
+ webrick (1.7.0)
141
+ yard (0.9.27)
142
+ webrick (~> 1.7.0)
137
143
 
138
144
  PLATFORMS
139
- ruby
145
+ x86_64-linux
140
146
 
141
147
  DEPENDENCIES
142
148
  diff-lcs (~> 1.3)
@@ -155,7 +161,7 @@ DEPENDENCIES
155
161
  puppetserver-ca (~> 1.1)
156
162
  racc (= 1.5.2)
157
163
  rake (~> 12.2)
158
- rdoc (~> 6.0)
164
+ rdoc (~> 6.0, < 6.4.0)
159
165
  ronn (~> 0.7.3)
160
166
  rspec (~> 3.1)
161
167
  rspec-expectations (~> 3.9, != 3.9.3)
@@ -163,10 +169,11 @@ DEPENDENCIES
163
169
  rubocop (~> 0.49)
164
170
  rubocop-i18n (~> 1.2.0)
165
171
  ruby-prof (>= 0.16.0)
172
+ scanf
166
173
  semantic_puppet (~> 1.0)
167
174
  vcr (~> 5.0)
168
175
  webmock (~> 3.0)
169
176
  yard
170
177
 
171
178
  BUNDLED WITH
172
- 1.17.3
179
+ 2.3.9
@@ -7,6 +7,7 @@ class Puppet::Application::Lookup < Puppet::Application
7
7
 
8
8
  RUN_HELP = _("Run 'puppet lookup --help' for more details").freeze
9
9
  DEEP_MERGE_OPTIONS = '--knock-out-prefix, --sort-merged-arrays, and --merge-hash-arrays'.freeze
10
+ TRUSTED_INFORMATION_FACTS = ["hostname", "domain", "fqdn", "clientcert"].freeze
10
11
 
11
12
  run_mode :server
12
13
 
@@ -54,11 +55,7 @@ class Puppet::Application::Lookup < Puppet::Application
54
55
  end
55
56
 
56
57
  option('--facts FACT_FILE') do |arg|
57
- if %w{.yaml .yml .json}.include?(arg.match(/\.[^.]*$/)[0])
58
- options[:fact_file] = arg
59
- else
60
- raise _("The --fact file only accepts yaml and json files.\n%{run_help}") % { run_help: RUN_HELP }
61
- end
58
+ options[:fact_file] = arg
62
59
  end
63
60
 
64
61
  def app_defaults
@@ -137,7 +134,9 @@ DESCRIPTION
137
134
  The lookup command is a CLI for Puppet's 'lookup()' function. It searches your
138
135
  Hiera data and returns a value for the requested lookup key, so you can test and
139
136
  explore your data. It is a modern replacement for the 'hiera' command.
140
-
137
+ Lookup uses the setting for global hiera.yaml from puppet's config,
138
+ and the environment to find the environment level hiera.yaml as well as the
139
+ resulting modulepath for the environment (for hiera.yaml files in modules).
141
140
  Hiera usually relies on a node's facts to locate the relevant data sources. By
142
141
  default, 'puppet lookup' uses facts from the node you run the command on, but
143
142
  you can get data for any other node with the '--node <NAME>' option. If
@@ -186,7 +185,8 @@ OPTIONS
186
185
  * --environment <ENV>
187
186
  Like with most Puppet commands, you can specify an environment on the command
188
187
  line. This is important for lookup because different environments can have
189
- different Hiera data.
188
+ different Hiera data. This environment will be always be the one used regardless
189
+ of any other factors.
190
190
 
191
191
  * --merge first|unique|hash|deep:
192
192
  Specify the merge behavior, overriding any merge behavior from the data's
@@ -237,6 +237,13 @@ EXAMPLE
237
237
  To look up 'key_name' using the Puppet Server node's facts:
238
238
  $ puppet lookup key_name
239
239
 
240
+ To look up 'key_name' using the Puppet Server node's arbitrary variables from a manifest, and
241
+ classify the node if applicable:
242
+ $ puppet lookup key_name --compile
243
+
244
+ To look up 'key_name' using the Puppet Server node's facts, overridden by facts given in a file:
245
+ $ puppet lookup key_name --facts fact_file.yaml
246
+
240
247
  To look up 'key_name' with agent.local's facts:
241
248
  $ puppet lookup --node agent.local key_name
242
249
 
@@ -341,31 +348,62 @@ Copyright (c) 2015 Puppet Inc., LLC Licensed under the Apache 2.0 License
341
348
  Puppet.settings[:facts_terminus] = 'facter'
342
349
  end
343
350
 
344
- unless node.is_a?(Puppet::Node) # to allow unit tests to pass a node instance
345
- ni = Puppet::Node.indirection
346
- tc = ni.terminus_class
347
- if tc == :plain || options[:compile]
348
- node = ni.find(node)
349
- else
350
- ni.terminus_class = :plain
351
- node = ni.find(node)
352
- ni.terminus_class = tc
353
- end
354
- end
355
-
356
351
  fact_file = options[:fact_file]
357
352
 
358
353
  if fact_file
359
- if fact_file.end_with?("json")
360
- given_facts = Puppet::Util::Json.load(Puppet::FileSystem.read(fact_file, :encoding => 'utf-8'))
361
- else
354
+ if fact_file.end_with?('.json')
355
+ given_facts = Puppet::Util::Json.load_file(fact_file)
356
+ elsif fact_file.end_with?('.yml', '.yaml')
362
357
  given_facts = Puppet::Util::Yaml.safe_load_file(fact_file)
358
+ else
359
+ given_facts = Puppet::Util::Json.load_file_if_valid(fact_file)
360
+ given_facts = Puppet::Util::Yaml.safe_load_file_if_valid(fact_file) unless given_facts
363
361
  end
364
362
 
365
363
  unless given_facts.instance_of?(Hash)
366
- raise _("Incorrect formatted data in %{fact_file} given via the --facts flag") % { fact_file: fact_file }
364
+ raise _("Incorrectly formatted data in %{fact_file} given via the --facts flag (only accepts yaml and json files)") % { fact_file: fact_file }
365
+ end
366
+
367
+ if TRUSTED_INFORMATION_FACTS.any? { |key| given_facts.key? key }
368
+ unless TRUSTED_INFORMATION_FACTS.all? { |key| given_facts.key? key }
369
+ raise _("When overriding any of the %{trusted_facts_list} facts with %{fact_file} "\
370
+ "given via the --facts flag, they must all be overridden.") % { fact_file: fact_file ,trusted_facts_list: TRUSTED_INFORMATION_FACTS.join(',')}
371
+ end
367
372
  end
368
- node.add_extra_facts(given_facts)
373
+ end
374
+
375
+ unless node.is_a?(Puppet::Node) # to allow unit tests to pass a node instance
376
+ facts = retrieve_node_facts(node, given_facts)
377
+ ni = Puppet::Node.indirection
378
+ tc = ni.terminus_class
379
+ if options[:compile] && !Puppet.settings.set_by_cli?('environment')
380
+ if tc == :plain
381
+ node = ni.find(node, facts: facts)
382
+ else
383
+ begin
384
+ service = Puppet.runtime[:http]
385
+ session = service.create_session
386
+ cert = session.route_to(:ca)
387
+
388
+ _, x509 = cert.get_certificate(node)
389
+ cert = OpenSSL::X509::Certificate.new(x509)
390
+ Puppet::SSL::Oids.register_puppet_oids
391
+ trusted = Puppet::Context::TrustedInformation.remote(true, facts.values['certname'] || node, Puppet::SSL::Certificate.from_instance(cert))
392
+ Puppet.override(trusted_information: trusted) do
393
+ node = ni.find(node, facts: facts)
394
+ end
395
+ rescue
396
+ Puppet.warning _("CA is not available, the operation will continue without using trusted facts.")
397
+ node = ni.find(node, facts: facts)
398
+ end
399
+ end
400
+ else
401
+ ni.terminus_class = :plain
402
+ node = ni.find(node, facts: facts, environment: Puppet[:environment])
403
+ ni.terminus_class = tc
404
+ end
405
+ else
406
+ node.add_extra_facts(given_facts) if given_facts
369
407
  end
370
408
 
371
409
  Puppet[:code] = 'undef' unless options[:compile]
@@ -378,4 +416,16 @@ Copyright (c) 2015 Puppet Inc., LLC Licensed under the Apache 2.0 License
378
416
  compiler.compile { |catalog| yield(compiler.topscope); catalog }
379
417
  end
380
418
  end
419
+
420
+ def retrieve_node_facts(node, given_facts)
421
+ facts = Puppet::Node::Facts.indirection.find(node, :environment => Puppet.lookup(:current_environment))
422
+
423
+ facts = Puppet::Node::Facts.new(node, {}) if facts.nil?
424
+ facts.add_extra_values(given_facts) if given_facts
425
+
426
+ if facts.values.empty?
427
+ raise _("No facts available for target node: %{node}") % { node: node}
428
+ end
429
+ facts
430
+ end
381
431
  end
@@ -5,10 +5,12 @@ module Puppet
5
5
  def singleton
6
6
  key = (name + ".singleton").intern
7
7
  thread = Thread.current
8
- unless thread.thread_variable?(key)
9
- thread.thread_variable_set(key, new)
8
+ value = thread.thread_variable_get(key)
9
+ if value.nil?
10
+ value = new
11
+ thread.thread_variable_set(key, value)
10
12
  end
11
- thread.thread_variable_get(key)
13
+ value
12
14
  end
13
15
  end
14
16
  end
@@ -302,9 +302,16 @@ class Puppet::Configurer
302
302
  # We only need to find out the environment to run in if we don't already have a catalog
303
303
  unless (cached_catalog || options[:catalog] || Puppet.settings.set_by_cli?(:environment) || Puppet[:strict_environment_mode])
304
304
  Puppet.debug(_("Environment not passed via CLI and no catalog was given, attempting to find out the last server-specified environment"))
305
- if last_server_specified_environment
306
- @environment = last_server_specified_environment
307
- report.environment = last_server_specified_environment
305
+ initial_environment, loaded_last_environment = last_server_specified_environment
306
+
307
+ unless Puppet[:use_last_environment] && loaded_last_environment
308
+ Puppet.debug(_("Requesting environment from the server"))
309
+ initial_environment = current_server_specified_environment(@environment, configured_environment, options)
310
+ end
311
+
312
+ if initial_environment
313
+ @environment = initial_environment
314
+ report.environment = initial_environment
308
315
 
309
316
  push_current_environment_and_loaders
310
317
  else
@@ -323,7 +330,7 @@ class Puppet::Configurer
323
330
  temp_value = options[:pluginsync]
324
331
 
325
332
  # only validate server environment if pluginsync is requested
326
- options[:pluginsync] = valid_server_environment? if options[:pluginsync] == true
333
+ options[:pluginsync] = valid_server_environment? if options[:pluginsync]
327
334
 
328
335
  query_options, facts = get_facts(options) unless query_options
329
336
  options[:pluginsync] = temp_value
@@ -436,7 +443,11 @@ class Puppet::Configurer
436
443
  true
437
444
  rescue Puppet::HTTP::ResponseError => detail
438
445
  if detail.response.code == 404
439
- Puppet.notice(_("Environment '%{environment}' not found on server, skipping initial pluginsync.") % { environment: @environment })
446
+ if Puppet[:strict_environment_mode]
447
+ raise Puppet::Error.new(_("Environment '%{environment}' not found on server, aborting run.") % { environment: @environment })
448
+ else
449
+ Puppet.notice(_("Environment '%{environment}' not found on server, skipping initial pluginsync.") % { environment: @environment })
450
+ end
440
451
  else
441
452
  Puppet.log_exception(detail, detail.message)
442
453
  end
@@ -463,24 +474,67 @@ class Puppet::Configurer
463
474
  end
464
475
  private :find_functional_server
465
476
 
477
+ #
478
+ # @api private
479
+ #
480
+ # Read the last server-specified environment from the lastrunfile. The
481
+ # environment is considered to be server-specified if the values of
482
+ # `initial_environment` and `converged_environment` are different.
483
+ #
484
+ # @return [String, Boolean] An array containing a string with the environment
485
+ # read from the lastrunfile in case the server is authoritative, and a
486
+ # boolean marking whether the last environment was correctly loaded.
466
487
  def last_server_specified_environment
467
- return @last_server_specified_environment if @last_server_specified_environment
488
+ return @last_server_specified_environment, @loaded_last_environment if @last_server_specified_environment
489
+
468
490
  if Puppet::FileSystem.exist?(Puppet[:lastrunfile])
469
491
  summary = Puppet::Util::Yaml.safe_load_file(Puppet[:lastrunfile])
470
- return unless summary.dig('application', 'run_mode') == 'agent'
471
- initial_environment = summary.dig('application', 'initial_environment')
472
- converged_environment = summary.dig('application', 'converged_environment')
492
+ return [nil, nil] unless summary['application']['run_mode'] == 'agent'
493
+ initial_environment = summary['application']['initial_environment']
494
+ converged_environment = summary['application']['converged_environment']
473
495
  @last_server_specified_environment = converged_environment if initial_environment != converged_environment
496
+ Puppet.debug(_("Successfully loaded last environment from the lastrunfile"))
497
+ @loaded_last_environment = true
474
498
  end
475
499
 
476
500
  Puppet.debug(_("Found last server-specified environment: %{environment}") % { environment: @last_server_specified_environment }) if @last_server_specified_environment
477
- @last_server_specified_environment
501
+ [@last_server_specified_environment, @loaded_last_environment]
478
502
  rescue => detail
479
503
  Puppet.debug(_("Could not find last server-specified environment: %{detail}") % { detail: detail })
480
- nil
504
+ [nil, nil]
481
505
  end
482
506
  private :last_server_specified_environment
483
507
 
508
+ def current_server_specified_environment(current_environment, configured_environment, options)
509
+ return @server_specified_environment if @server_specified_environment
510
+
511
+ begin
512
+ node_retr_time = thinmark do
513
+ node = Puppet::Node.indirection.find(Puppet[:node_name_value],
514
+ :environment => Puppet::Node::Environment.remote(current_environment),
515
+ :configured_environment => configured_environment,
516
+ :ignore_cache => true,
517
+ :transaction_uuid => @transaction_uuid,
518
+ :fail_on_404 => true)
519
+
520
+ @server_specified_environment = node.environment_name.to_s
521
+
522
+ if @server_specified_environment != @environment
523
+ Puppet.notice _("Local environment: '%{local_env}' doesn't match server specified node environment '%{node_env}', switching agent to '%{node_env}'.") % { local_env: @environment, node_env: @server_specified_environment }
524
+ end
525
+ end
526
+
527
+ options[:report].add_times(:node_retrieval, node_retr_time)
528
+
529
+ @server_specified_environment
530
+ rescue => detail
531
+ Puppet.warning(_("Unable to fetch my node definition, but the agent run will continue:"))
532
+ Puppet.warning(detail)
533
+ nil
534
+ end
535
+ end
536
+ private :current_server_specified_environment
537
+
484
538
  def send_report(report)
485
539
  puts report.summary if Puppet[:summarize]
486
540
  save_last_run_summary(report)
@@ -442,6 +442,17 @@ module Puppet
442
442
  <https://puppet.com/docs/puppet/latest/environments_about.html>",
443
443
  :type => :path,
444
444
  },
445
+ :use_last_environment => {
446
+ :type => :boolean,
447
+ :default => true,
448
+ :desc => <<-'EOT'
449
+ Puppet saves both the initial and converged environment in the last_run_summary file.
450
+ If they differ, and this setting is set to true, we will use the last converged
451
+ environment and skip the node request.
452
+
453
+ When set to false, we will do the node request and ignore the environment data from the last_run_summary file.
454
+ EOT
455
+ },
445
456
  :always_retry_plugins => {
446
457
  :type => :boolean,
447
458
  :default => true,
@@ -800,6 +811,12 @@ Valid values are 0 (never cache) and 15 (15 second minimum wait time).
800
811
  :owner => "service",
801
812
  :group => "service",
802
813
  :desc => "The directory where catalog previews per node are generated."
814
+ },
815
+ :location_trusted => {
816
+ :default => false,
817
+ :type => :boolean,
818
+ :desc => "This will allow sending the name + password and the cookie header to all hosts that puppet may redirect to.
819
+ This may or may not introduce a security breach if puppet redirects you to a site to which you'll send your authentication info and cookies."
803
820
  }
804
821
  )
805
822
 
@@ -2050,7 +2067,8 @@ EOT
2050
2067
  :call_hook => :on_initialize_and_write, # Call our hook with the default value, so we always get the value added to facter.
2051
2068
  :hook => proc do |value|
2052
2069
  paths = value.split(File::PATH_SEPARATOR)
2053
- Puppet.runtime[:facter].search(*paths)
2070
+ facter = Puppet.runtime[:facter]
2071
+ facter.search(*paths)
2054
2072
  end
2055
2073
  }
2056
2074
  )
@@ -2191,8 +2209,6 @@ EOT
2191
2209
  # Call our hook with the default value, so we always get the libdir set.
2192
2210
  :call_hook => :on_initialize_and_write,
2193
2211
  :hook => proc do |value|
2194
- require 'puppet/node'
2195
- require 'puppet/node/facts'
2196
2212
  if value
2197
2213
  Puppet::Resource::Catalog.indirection.set_global_setting(:cache_class, :store_configs)
2198
2214
  settings.override_default(:catalog_cache_terminus, :store_configs)
@@ -58,6 +58,8 @@ Puppet::Face.define(:generate, '0.1.0') do
58
58
  Puppet::FileSystem::mkpath(outputdir)
59
59
 
60
60
  generator.generate(inputs, outputdir, options[:force])
61
+
62
+ exit(1) if generator.bad_input?
61
63
  nil
62
64
  end
63
65
  end
@@ -118,6 +118,9 @@ class Puppet::FileServing::Metadata < Puppet::FileServing::Base
118
118
  when "link"
119
119
  @destination = Puppet::FileSystem.readlink(real_path)
120
120
  @checksum = ("{#{@checksum_type}}") + send("#{@checksum_type}_file", real_path).to_s rescue nil
121
+ when "fifo", "socket"
122
+ @checksum_type = "none"
123
+ @checksum = ("{#{@checksum_type}}") + send("#{@checksum_type}_file", real_path).to_s
121
124
  else
122
125
  raise ArgumentError, _("Cannot manage files of type %{file_type}") % { file_type: stat.ftype }
123
126
  end
@@ -130,23 +130,23 @@ class Puppet::FileSystem::FileImpl
130
130
  end
131
131
 
132
132
  def symlink?(path)
133
- File.symlink?(path)
133
+ ::File.symlink?(path)
134
134
  end
135
135
 
136
136
  def readlink(path)
137
- File.readlink(path)
137
+ ::File.readlink(path)
138
138
  end
139
139
 
140
140
  def unlink(*paths)
141
- File.unlink(*paths)
141
+ ::File.unlink(*paths)
142
142
  end
143
143
 
144
144
  def stat(path)
145
- File.stat(path)
145
+ ::File.stat(path)
146
146
  end
147
147
 
148
148
  def lstat(path)
149
- File.lstat(path)
149
+ ::File.lstat(path)
150
150
  end
151
151
 
152
152
  def compare_stream(path, stream)
@@ -159,7 +159,7 @@ class Puppet::FileSystem::FileImpl
159
159
 
160
160
  def replace_file(path, mode = nil)
161
161
  begin
162
- stat = Puppet::FileSystem.lstat(path)
162
+ stat = lstat(path)
163
163
  gid = stat.gid
164
164
  uid = stat.uid
165
165
  mode ||= stat.mode & 07777
@@ -180,7 +180,7 @@ class Puppet::FileSystem::FileImpl
180
180
  tempfile_path = tempfile.path
181
181
  FileUtils.chown(uid, gid, tempfile_path) if uid && gid
182
182
  chmod(mode, tempfile_path)
183
- File.rename(tempfile_path, Puppet::FileSystem.path_string(path))
183
+ ::File.rename(tempfile_path, path_string(path))
184
184
  ensure
185
185
  tempfile.close!
186
186
  end
@@ -14,7 +14,7 @@ class Puppet::FileSystem::JRuby < Puppet::FileSystem::Posix
14
14
  def replace_file(path, mode = nil, &block)
15
15
  # MRI Ruby rename checks if destination is a directory and raises, while
16
16
  # JRuby removes the directory and replaces the file.
17
- if Puppet::FileSystem.directory?(path)
17
+ if directory?(path)
18
18
  raise Errno::EISDIR, _("Is a directory: %{directory}") % { directory: path }
19
19
  end
20
20
 
@@ -123,7 +123,7 @@ class Puppet::FileSystem::Windows < Puppet::FileSystem::Posix
123
123
  LOCK_VIOLATION = 33
124
124
 
125
125
  def replace_file(path, mode = nil)
126
- if Puppet::FileSystem.directory?(path)
126
+ if directory?(path)
127
127
  raise Errno::EISDIR, _("Is a directory: %{directory}") % { directory: path }
128
128
  end
129
129
 
@@ -159,14 +159,14 @@ class Puppet::FileSystem::Windows < Puppet::FileSystem::Posix
159
159
  end
160
160
 
161
161
  set_dacl(tempfile.path, dacl) if dacl
162
- File.rename(tempfile.path, Puppet::FileSystem.path_string(path))
162
+ ::File.rename(tempfile.path, path_string(path))
163
163
  ensure
164
164
  tempfile.close!
165
165
  end
166
166
  rescue Puppet::Util::Windows::Error => e
167
167
  case e.code
168
168
  when ACCESS_DENIED, SHARING_VIOLATION, LOCK_VIOLATION
169
- raise Errno::EACCES.new(Puppet::FileSystem.path_string(path), e)
169
+ raise Errno::EACCES.new(path_string(path), e)
170
170
  else
171
171
  raise SystemCallError.new(e.message)
172
172
  end
@@ -193,7 +193,7 @@ class Puppet::FileSystem::Windows < Puppet::FileSystem::Posix
193
193
  end
194
194
 
195
195
  def get_dacl_from_file(path)
196
- sd = Puppet::Util::Windows::Security.get_security_descriptor(Puppet::FileSystem.path_string(path))
196
+ sd = Puppet::Util::Windows::Security.get_security_descriptor(path_string(path))
197
197
  sd.dacl
198
198
  rescue Puppet::Util::Windows::Error => e
199
199
  raise e unless e.code == FILE_NOT_FOUND
@@ -396,7 +396,7 @@ module Puppet::FileSystem
396
396
  # @api public
397
397
  #
398
398
  def self.chmod(mode, path)
399
- @impl.chmod(mode, path)
399
+ @impl.chmod(mode, assert_path(path))
400
400
  end
401
401
 
402
402
  # Replace the contents of a file atomically, creating the file if necessary.