puppet 7.12.0 → 7.12.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: feb741bb77ed2e7f043a4879e1ff6c5b6ae03a4467b497d0895ed8071ef607d7
4
- data.tar.gz: 4359d0d4a714a2e6cec8a85b0d469462784f738167fe88209e9644fb5ecd2362
3
+ metadata.gz: 9c9a5ad10d1fe29d4c28a410c34cc28236cc3a678444e72cdbcbd824ead10f99
4
+ data.tar.gz: 104352f3f069d1f9043dc386f035f0c18da3bbc09f1715092b682a6508b97842
5
5
  SHA512:
6
- metadata.gz: 410a0b4bf4b835b884e60235a6b7d902147655142dd4d11eaea7983b3a7bc42960e89a9132cd4db4e79ad485f61b88b5e6508db09f4ed806f78908f451f952e0
7
- data.tar.gz: 474c5e4a49a949e28438576047cbf17fc1dc5e30e2d4c04bf96fd6faefe8acbc77aea9e243381d33cf1202b65436b7f7f288e915442c555cad43731ffd23f568
6
+ metadata.gz: 45dcb3ec19cc2b62b3a642a3adbe3697a08eee3f6f79158b30e4b32dfecc4eb908f4d0c7a22958606b2cf3ba4cfefc93f17108b1ec159e49bdb4ed18540538aa
7
+ data.tar.gz: d5efd563f4a3bd518883d6ed8b8721cff49b81b9f0ccc0a382bb3e96ac4262ebbfe6535a12451f6d6a4ff61399cc5e79aeb64e13832443998dba2fa0fb2702ba
data/Gemfile.lock CHANGED
@@ -1,9 +1,9 @@
1
1
  GIT
2
2
  remote: git://github.com/puppetlabs/packaging
3
- revision: 03722ea5c9106c1b31a58b22cc41bacade8c8fa8
3
+ revision: 4c5359786cad0d12877e10e98948065bfeb3e304
4
4
  branch: 1.0.x
5
5
  specs:
6
- packaging (0.101.0)
6
+ packaging (0.103.0)
7
7
  artifactory (~> 2)
8
8
  csv (= 3.1.5)
9
9
  rake (>= 12.3)
@@ -12,7 +12,7 @@ GIT
12
12
  PATH
13
13
  remote: .
14
14
  specs:
15
- puppet (7.12.0)
15
+ puppet (7.12.1)
16
16
  CFPropertyList (~> 2.2)
17
17
  concurrent-ruby (~> 1.0)
18
18
  deep_merge (~> 1.0)
@@ -390,9 +390,16 @@ class Puppet::Configurer
390
390
  # We only need to find out the environment to run in if we don't already have a catalog
391
391
  unless (cached_catalog || options[:catalog] || Puppet.settings.set_by_cli?(:environment) || Puppet[:strict_environment_mode])
392
392
  Puppet.debug(_("Environment not passed via CLI and no catalog was given, attempting to find out the last server-specified environment"))
393
- if last_server_specified_environment
394
- @environment = last_server_specified_environment
395
- report.environment = last_server_specified_environment
393
+ initial_environment, loaded_last_environment = last_server_specified_environment
394
+
395
+ unless loaded_last_environment
396
+ Puppet.debug(_("Requesting environment from the server"))
397
+ initial_environment = current_server_specified_environment(@environment, configured_environment, options)
398
+ end
399
+
400
+ if initial_environment
401
+ @environment = initial_environment
402
+ report.environment = initial_environment
396
403
 
397
404
  push_current_environment_and_loaders
398
405
  else
@@ -551,24 +558,77 @@ class Puppet::Configurer
551
558
  end
552
559
  private :find_functional_server
553
560
 
561
+ #
562
+ # @api private
563
+ #
564
+ # Read the last server-specified environment from the lastrunfile. The
565
+ # environment is considered to be server-specified if the values of
566
+ # `initial_environment` and `converged_environment` are different.
567
+ #
568
+ # @return [String, Boolean] An array containing a string with the environment
569
+ # read from the lastrunfile in case the server is authoritative, and a
570
+ # boolean marking whether the last environment was correctly loaded.
554
571
  def last_server_specified_environment
555
- return @last_server_specified_environment if @last_server_specified_environment
572
+ return @last_server_specified_environment, @loaded_last_environment if @last_server_specified_environment
573
+
556
574
  if Puppet::FileSystem.exist?(Puppet[:lastrunfile])
557
575
  summary = Puppet::Util::Yaml.safe_load_file(Puppet[:lastrunfile])
558
- return unless summary.dig('application', 'run_mode') == 'agent'
559
- initial_environment = summary.dig('application', 'initial_environment')
560
- converged_environment = summary.dig('application', 'converged_environment')
576
+ return [nil, nil] unless summary['application']['run_mode'] == 'agent'
577
+ initial_environment = summary['application']['initial_environment']
578
+ converged_environment = summary['application']['converged_environment']
561
579
  @last_server_specified_environment = converged_environment if initial_environment != converged_environment
580
+ Puppet.debug(_("Successfully loaded last environment from the lastrunfile"))
581
+ @loaded_last_environment = true
562
582
  end
563
583
 
564
584
  Puppet.debug(_("Found last server-specified environment: %{environment}") % { environment: @last_server_specified_environment }) if @last_server_specified_environment
565
- @last_server_specified_environment
585
+ [@last_server_specified_environment, @loaded_last_environment]
566
586
  rescue => detail
567
587
  Puppet.debug(_("Could not find last server-specified environment: %{detail}") % { detail: detail })
568
- nil
588
+ [nil, nil]
569
589
  end
570
590
  private :last_server_specified_environment
571
591
 
592
+ def current_server_specified_environment(current_environment, configured_environment, options)
593
+ return @server_specified_environment if @server_specified_environment
594
+
595
+ begin
596
+ node_retr_time = thinmark do
597
+ node = Puppet::Node.indirection.find(Puppet[:node_name_value],
598
+ :environment => Puppet::Node::Environment.remote(current_environment),
599
+ :configured_environment => configured_environment,
600
+ :ignore_cache => true,
601
+ :transaction_uuid => @transaction_uuid,
602
+ :fail_on_404 => true)
603
+
604
+ # The :rest node terminus returns a node with an environment_name, but not an
605
+ # environment instance. Attempting to get the environment instance will load
606
+ # it from disk, which will likely fail. So create a remote environment.
607
+ #
608
+ # The :plain node terminus returns a node with an environment, but not an
609
+ # environment_name.
610
+ if !node.has_environment_instance? && node.environment_name
611
+ node.environment = Puppet::Node::Environment.remote(node.environment_name)
612
+ end
613
+
614
+ @server_specified_environment = node.environment.to_s
615
+
616
+ if @server_specified_environment != @environment
617
+ 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 }
618
+ end
619
+ end
620
+
621
+ options[:report].add_times(:node_retrieval, node_retr_time)
622
+
623
+ @server_specified_environment
624
+ rescue => detail
625
+ Puppet.warning(_("Unable to fetch my node definition, but the agent run will continue:"))
626
+ Puppet.warning(detail)
627
+ nil
628
+ end
629
+ end
630
+ private :current_server_specified_environment
631
+
572
632
  def send_report(report)
573
633
  puts report.summary if Puppet[:summarize]
574
634
  save_last_run_summary(report)
@@ -761,6 +761,12 @@ Valid values are 0 (never cache) and 15 (15 second minimum wait time).
761
761
  :owner => "service",
762
762
  :group => "service",
763
763
  :desc => "The directory where catalog previews per node are generated."
764
+ },
765
+ :location_trusted => {
766
+ :default => false,
767
+ :type => :boolean,
768
+ :desc => "This will allow sending the name + password and the cookie header to all hosts that puppet may redirect to.
769
+ 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."
764
770
  }
765
771
  )
766
772
 
@@ -346,7 +346,7 @@ class Puppet::HTTP::Client
346
346
 
347
347
  while !done do
348
348
  connect(request.uri, options: options) do |http|
349
- apply_auth(request, basic_auth)
349
+ apply_auth(request, basic_auth) if redirects.zero?
350
350
 
351
351
  # don't call return within the `request` block
352
352
  http.request(request) do |nethttp|
@@ -49,6 +49,11 @@ class Puppet::HTTP::Redirector
49
49
  new_request = request.class.new(url)
50
50
  new_request.body = request.body
51
51
  request.each do |header, value|
52
+ unless Puppet[:location_trusted]
53
+ # skip adding potentially sensitive header to other hosts
54
+ next if header.casecmp('Authorization').zero? && request.uri.host.casecmp(location.host) != 0
55
+ next if header.casecmp('Cookie').zero? && request.uri.host.casecmp(location.host) != 0
56
+ end
52
57
  new_request[header] = value
53
58
  end
54
59
 
@@ -13,7 +13,7 @@ class Puppet::Parser::Resource < Puppet::Resource
13
13
 
14
14
  attr_accessor :source, :scope, :collector_id
15
15
  attr_accessor :virtual, :override, :translated, :catalog, :evaluated
16
- attr_accessor :file, :line
16
+ attr_accessor :file, :line, :kind
17
17
 
18
18
  attr_reader :exported, :parameters
19
19
 
@@ -40,6 +40,7 @@ module Runtime3ResourceSupport
40
40
  :parameters => evaluated_parameters,
41
41
  :file => file,
42
42
  :line => line,
43
+ :kind => Puppet::Resource.to_kind(resolved_type),
43
44
  :exported => exported,
44
45
  :virtual => virtual,
45
46
  # WTF is this? Which source is this? The file? The name of the context ?
@@ -313,7 +313,7 @@ class Puppet::Resource::Catalog < Puppet::Graph::SimpleGraph
313
313
  super()
314
314
  @name = name
315
315
  @catalog_uuid = SecureRandom.uuid
316
- @catalog_format = 1
316
+ @catalog_format = 2
317
317
  @metadata = {}
318
318
  @recursive_metadata = {}
319
319
  @classes = []
@@ -11,7 +11,7 @@ class Puppet::Resource
11
11
  include Puppet::Util::PsychSupport
12
12
 
13
13
  include Enumerable
14
- attr_accessor :file, :line, :catalog, :exported, :virtual, :strict
14
+ attr_accessor :file, :line, :catalog, :exported, :virtual, :strict, :kind
15
15
  attr_reader :type, :title, :parameters
16
16
 
17
17
  # @!attribute [rw] sensitive_parameters
@@ -29,10 +29,15 @@ class Puppet::Resource
29
29
  EMPTY_ARRAY = [].freeze
30
30
  EMPTY_HASH = {}.freeze
31
31
 
32
- ATTRIBUTES = [:file, :line, :exported].freeze
32
+ ATTRIBUTES = [:file, :line, :exported, :kind].freeze
33
33
  TYPE_CLASS = 'Class'.freeze
34
34
  TYPE_NODE = 'Node'.freeze
35
35
 
36
+ CLASS_STRING = 'class'.freeze
37
+ DEFINED_TYPE_STRING = 'defined_type'.freeze
38
+ COMPILABLE_TYPE_STRING = 'compilable_type'.freeze
39
+ UNKNOWN_TYPE_STRING = 'unknown'.freeze
40
+
36
41
  PCORE_TYPE_KEY = '__ptype'.freeze
37
42
  VALUE_KEY = 'value'.freeze
38
43
 
@@ -193,6 +198,18 @@ class Puppet::Resource
193
198
  resource_type.is_a?(Puppet::CompilableResourceType)
194
199
  end
195
200
 
201
+ def self.to_kind(resource_type)
202
+ if resource_type == CLASS_STRING
203
+ CLASS_STRING
204
+ elsif resource_type.is_a?(Puppet::Resource::Type) && resource_type.type == :definition
205
+ DEFINED_TYPE_STRING
206
+ elsif resource_type.is_a?(Puppet::CompilableResourceType)
207
+ COMPILABLE_TYPE_STRING
208
+ else
209
+ UNKNOWN_TYPE_STRING
210
+ end
211
+ end
212
+
196
213
  # Iterate over each param/value pair, as required for Enumerable.
197
214
  def each
198
215
  parameters.each { |p,v| yield p, v }
@@ -247,6 +264,7 @@ class Puppet::Resource
247
264
  src = type
248
265
  self.file = src.file
249
266
  self.line = src.line
267
+ self.kind = src.kind
250
268
  self.exported = src.exported
251
269
  self.virtual = src.virtual
252
270
  self.set_tags(src)
@@ -309,6 +327,7 @@ class Puppet::Resource
309
327
 
310
328
  rt = resource_type
311
329
 
330
+ self.kind = self.class.to_kind(rt) unless kind
312
331
  if strict? && rt.nil?
313
332
  if self.class?
314
333
  raise ArgumentError, _("Could not find declared class %{title}") % { title: title }
@@ -468,10 +487,24 @@ class Puppet::Resource
468
487
  ref
469
488
  end
470
489
 
471
- # Convert our resource to a RAL resource instance. Creates component
472
- # instances for resource types that don't exist.
490
+ # Convert our resource to a RAL resource instance. Creates component
491
+ # instances for resource types that are not of a compilable_type kind. In case
492
+ # the resource doesn’t exist and it’s compilable_type kind, raise an error.
493
+ # There are certain cases where a resource won't be in a catalog, such as
494
+ # when we create a resource directly by using Puppet::Resource.new(...), so we
495
+ # must check its kind before deciding whether the catalog format is of an older
496
+ # version or not.
473
497
  def to_ral
474
- typeklass = Puppet::Type.type(self.type) || Puppet::Type.type(:component)
498
+ if self.kind == COMPILABLE_TYPE_STRING
499
+ typeklass = Puppet::Type.type(self.type)
500
+ elsif self.catalog && self.catalog.catalog_format >= 2
501
+ typeklass = Puppet::Type.type(:component)
502
+ else
503
+ typeklass = Puppet::Type.type(self.type) || Puppet::Type.type(:component)
504
+ end
505
+
506
+ raise(Puppet::Error, "Resource type '#{self.type}' was not found") unless typeklass
507
+
475
508
  typeklass.new(self)
476
509
  end
477
510
 
@@ -18,11 +18,6 @@ module Puppet::Util::Windows
18
18
  include Puppet::FFI::Windows::Functions
19
19
  extend Puppet::FFI::Windows::Functions
20
20
 
21
- # integer value of the floor for timeouts when waiting for service pending states.
22
- # puppet will wait the length of dwWaitHint if it is longer than this value, but
23
- # no shorter
24
- DEFAULT_TIMEOUT = 30
25
-
26
21
  # Returns true if the service exists, false otherwise.
27
22
  #
28
23
  # @param [String] service_name name of the service
@@ -10,6 +10,9 @@ module Puppet::Util::Windows
10
10
  module File; end
11
11
  module Registry
12
12
  end
13
+ module Service
14
+ DEFAULT_TIMEOUT = 30
15
+ end
13
16
  module SID
14
17
  class Principal; end
15
18
  end
@@ -6,7 +6,7 @@
6
6
  # Raketasks and such to set the version based on the output of `git describe`
7
7
 
8
8
  module Puppet
9
- PUPPETVERSION = '7.12.0'
9
+ PUPPETVERSION = '7.12.1'
10
10
 
11
11
  ##
12
12
  # version is a public API method intended to always provide a fast and
@@ -929,7 +929,7 @@ The time to wait for data to be read from an HTTP connection\. If nothing is rea
929
929
  The HTTP User\-Agent string to send when making network requests\.
930
930
  .
931
931
  .IP "\(bu" 4
932
- \fIDefault\fR: \fBPuppet/7\.12\.0 Ruby/2\.5\.1\-p57 (x86_64\-linux)\fR
932
+ \fIDefault\fR: \fBPuppet/7\.12\.1 Ruby/2\.5\.1\-p57 (x86_64\-linux)\fR
933
933
  .
934
934
  .IP "" 0
935
935
  .
data/man/man8/puppet.8 CHANGED
@@ -25,4 +25,4 @@ Specialized:
25
25
  catalog Compile, save, view, and convert catalogs\. describe Display help about resource types device Manage remote network devices doc Generate Puppet references epp Interact directly with the EPP template parser/renderer\. facts Retrieve and store facts\. filebucket Store and retrieve files in a filebucket generate Generates Puppet code from Ruby definitions\. node View and manage node definitions\. parser Interact directly with the parser\. plugin Interact with the Puppet plugin system\. script Run a puppet manifests as a script without compiling a catalog ssl Manage SSL keys and certificates for puppet SSL clients
26
26
  .
27
27
  .P
28
- See \'puppet help \fIsubcommand\fR \fIaction\fR\' for help on a specific subcommand action\. See \'puppet help \fIsubcommand\fR\' for help on a specific subcommand\. Puppet v7\.12\.0
28
+ See \'puppet help \fIsubcommand\fR \fIaction\fR\' for help on a specific subcommand action\. See \'puppet help \fIsubcommand\fR\' for help on a specific subcommand\. Puppet v7\.12\.1
@@ -6,7 +6,7 @@
6
6
  "version": 1607629733,
7
7
  "code_id": null,
8
8
  "catalog_uuid": "afc8472a-306b-4b24-b060-e956dffb79b8",
9
- "catalog_format": 1,
9
+ "catalog_format": 2,
10
10
  "environment": "production",
11
11
  "resources": [
12
12
  {
@@ -50,6 +50,7 @@
50
50
  ],
51
51
  "file": "",
52
52
  "line": 1,
53
+ "kind": "compilable_type",
53
54
  "exported": false,
54
55
  "parameters": {
55
56
  "message": {
@@ -645,6 +645,34 @@ describe "puppet agent", unless: Puppet::Util::Platform.jruby? do
645
645
  end
646
646
 
647
647
  context "environment convergence" do
648
+ it "falls back to making a node request if the last server-specified environment cannot be loaded" do
649
+ mounts = {}
650
+ mounts[:node] = -> (req, res) {
651
+ node = Puppet::Node.new('test', environment: Puppet::Node::Environment.remote('doesnotexistonagent'))
652
+ res.body = formatter.render(node)
653
+ res['Content-Type'] = formatter.mime
654
+ }
655
+
656
+ server.start_server(mounts: mounts) do |port|
657
+ Puppet[:serverport] = port
658
+ Puppet[:log_level] = 'debug'
659
+
660
+ expect {
661
+ agent.command_line.args << '--test'
662
+ agent.run
663
+ }.to exit_with(0)
664
+ .and output(a_string_matching(%r{Debug: Requesting environment from the server})).to_stdout
665
+
666
+ Puppet::Application.clear!
667
+
668
+ expect {
669
+ agent.command_line.args << '--test'
670
+ agent.run
671
+ }.to exit_with(0)
672
+ .and output(a_string_matching(%r{Debug: Successfully loaded last environment from the lastrunfile})).to_stdout
673
+ end
674
+ end
675
+
648
676
  it "switches to 'newenv' environment and retries the run" do
649
677
  first_run = true
650
678
  libdir = File.join(my_fixture_dir, 'lib')
@@ -122,6 +122,16 @@ describe 'when pcore described resources types are in use' do
122
122
  expect(catalog.resource(:test3, "x/y")['message']).to eq('x/y works')
123
123
  end
124
124
 
125
+ it 'considers Pcore types to be builtin ' do
126
+ genface.types
127
+ catalog = compile_to_catalog(<<-MANIFEST)
128
+ test1 { 'a':
129
+ message => 'a works'
130
+ }
131
+ MANIFEST
132
+ expect(catalog.resource(:test1, "a").kind).to eq('compilable_type')
133
+ end
134
+
125
135
  it 'the validity of attribute names are checked' do
126
136
  genface.types
127
137
  expect do
@@ -2,6 +2,8 @@ require 'spec_helper'
2
2
  require 'puppet/configurer'
3
3
 
4
4
  describe Puppet::Configurer do
5
+ include PuppetSpec::Files
6
+
5
7
  before do
6
8
  Puppet[:server] = "puppetmaster"
7
9
  Puppet[:report] = true
@@ -10,6 +12,17 @@ describe Puppet::Configurer do
10
12
  allow_any_instance_of(described_class).to(
11
13
  receive(:valid_server_environment?).and_return(true)
12
14
  )
15
+
16
+ Puppet[:lastrunfile] = file_containing('last_run_summary.yaml', <<~SUMMARY)
17
+ ---
18
+ version:
19
+ config: 1624882680
20
+ puppet: #{Puppet.version}
21
+ application:
22
+ initial_environment: #{Puppet[:environment]}
23
+ converged_environment: #{Puppet[:environment]}
24
+ run_mode: agent
25
+ SUMMARY
13
26
  end
14
27
 
15
28
  let(:node_name) { Puppet[:node_name_value] }
@@ -866,7 +879,7 @@ describe Puppet::Configurer do
866
879
  expect(configurer.run).to be_nil
867
880
  end
868
881
 
869
- it "should proceed with the cached catalog if its environment matchs the local environment" do
882
+ it "should proceed with the cached catalog if its environment matches the local environment" do
870
883
  expects_cached_catalog_only(catalog)
871
884
 
872
885
  expect(configurer.run).to eq(0)
@@ -1222,7 +1235,6 @@ describe Puppet::Configurer do
1222
1235
  end
1223
1236
 
1224
1237
  describe "when selecting an environment" do
1225
- include PuppetSpec::Files
1226
1238
  include PuppetSpec::Settings
1227
1239
 
1228
1240
  describe "when the last used environment is available" do
@@ -1239,6 +1251,9 @@ describe Puppet::Configurer do
1239
1251
  converged_environment: #{last_server_specified_environment}
1240
1252
  run_mode: agent
1241
1253
  SUMMARY
1254
+
1255
+ expect(Puppet::Node.indirection).not_to receive(:find)
1256
+ .with(anything, hash_including(:ignore_cache => true, :fail_on_404 => true))
1242
1257
  end
1243
1258
 
1244
1259
  it "prefers the environment set via cli" do
@@ -1248,26 +1263,27 @@ describe Puppet::Configurer do
1248
1263
  expect(configurer.environment).to eq('usethis')
1249
1264
  end
1250
1265
 
1251
- it "prefers the environment set via config" do
1266
+ it "prefers the environment set via lastrunfile over config" do
1252
1267
  FileUtils.mkdir_p(Puppet[:confdir])
1253
1268
  set_puppet_conf(Puppet[:confdir], <<~CONF)
1254
1269
  [main]
1255
1270
  environment = usethis
1271
+ lastrunfile = #{Puppet[:lastrunfile]}
1256
1272
  CONF
1257
1273
 
1258
1274
  Puppet.initialize_settings
1259
1275
  configurer.run
1260
1276
 
1261
- expect(configurer.environment).to eq('usethis')
1277
+ expect(configurer.environment).to eq(last_server_specified_environment)
1262
1278
  end
1263
1279
 
1264
- it "uses environment from Puppet[:environment] if given a catalog" do
1280
+ it "uses the environment from Puppet[:environment] if given a catalog" do
1265
1281
  configurer.run(catalog: catalog)
1266
1282
 
1267
1283
  expect(configurer.environment).to eq(Puppet[:environment])
1268
1284
  end
1269
1285
 
1270
- it "uses environment from Puppet[:environment] if use_cached_catalog = true" do
1286
+ it "uses the environment from Puppet[:environment] if use_cached_catalog = true" do
1271
1287
  Puppet[:use_cached_catalog] = true
1272
1288
  expects_cached_catalog_only(catalog)
1273
1289
  configurer.run
@@ -1296,14 +1312,14 @@ describe Puppet::Configurer do
1296
1312
  configurer.run
1297
1313
  end
1298
1314
 
1299
- it "uses environment from Puppet[:environment] if strict_environment_mode is set" do
1315
+ it "uses the environment from Puppet[:environment] if strict_environment_mode is set" do
1300
1316
  Puppet[:strict_environment_mode] = true
1301
1317
  configurer.run
1302
1318
 
1303
1319
  expect(configurer.environment).to eq(Puppet[:environment])
1304
1320
  end
1305
1321
 
1306
- it "uses environment from Puppet[:environment] if initial_environment is the same as converged_environment" do
1322
+ it "uses the environment from Puppet[:environment] if initial_environment is the same as converged_environment" do
1307
1323
  Puppet[:lastrunfile] = file_containing('last_run_summary.yaml', <<~SUMMARY)
1308
1324
  ---
1309
1325
  version:
@@ -1318,41 +1334,86 @@ describe Puppet::Configurer do
1318
1334
 
1319
1335
  expect(configurer.environment).to eq(Puppet[:environment])
1320
1336
  end
1337
+ end
1338
+ end
1339
+
1340
+ describe "when the last used environment is not available" do
1341
+ describe "when the node request succeeds" do
1342
+ let(:node_environment) { Puppet::Node::Environment.remote(:salam) }
1343
+ let(:node) { Puppet::Node.new(Puppet[:node_name_value]) }
1344
+ let(:last_server_specified_environment) { 'development' }
1345
+
1346
+ before do
1347
+ node.environment = node_environment
1348
+
1349
+ allow(Puppet::Node.indirection).to receive(:find)
1350
+ allow(Puppet::Node.indirection).to receive(:find)
1351
+ .with(anything, hash_including(:ignore_cache => true, :fail_on_404 => true))
1352
+ .and_return(node)
1353
+ end
1321
1354
 
1322
- it "uses environment from Puppet[:environment] if the run mode doesn't match" do
1355
+ it "uses the environment from the node request if the run mode doesn't match" do
1323
1356
  Puppet[:lastrunfile] = file_containing('last_run_summary.yaml', <<~SUMMARY)
1324
- ---
1325
- version:
1326
- config: 1624882680
1327
- puppet: 6.24.0
1328
- application:
1329
- initial_environment: #{Puppet[:environment]}
1330
- converged_environment: #{last_server_specified_environment}
1331
- run_mode: user
1357
+ ---
1358
+ version:
1359
+ config: 1624882680
1360
+ puppet: 6.24.0
1361
+ application:
1362
+ initial_environment: #{Puppet[:environment]}
1363
+ converged_environment: #{last_server_specified_environment}
1364
+ run_mode: user
1332
1365
  SUMMARY
1333
1366
  configurer.run
1334
1367
 
1335
- expect(configurer.environment).to eq(Puppet[:environment])
1368
+ expect(configurer.environment).to eq(node_environment.name.to_s)
1336
1369
  end
1337
1370
 
1338
- it "uses environment from Puppet[:environment] if lastrunfile is invalid YAML" do
1371
+ it "uses the environment from the node request if lastrunfile does not contain the expected keys" do
1339
1372
  Puppet[:lastrunfile] = file_containing('last_run_summary.yaml', <<~SUMMARY)
1340
- Key: 'this is my very very very ' +
1341
- 'long string'
1373
+ ---
1374
+ version:
1375
+ config: 1624882680
1376
+ puppet: 6.24.0
1342
1377
  SUMMARY
1343
1378
  configurer.run
1344
1379
 
1345
- expect(configurer.environment).to eq(Puppet[:environment])
1380
+ expect(configurer.environment).to eq(node_environment.name.to_s)
1346
1381
  end
1347
1382
 
1348
- it "uses environment from Puppet[:environment] if lastrunfile exists but is empty" do
1383
+ it "uses the environment from the node request if lastrunfile is invalid YAML" do
1384
+ Puppet[:lastrunfile] = file_containing('last_run_summary.yaml', <<~SUMMARY)
1385
+ Key: 'this is my very very very ' +
1386
+ 'long string'
1387
+ SUMMARY
1388
+ configurer.run
1389
+
1390
+ expect(configurer.environment).to eq(node_environment.name.to_s)
1391
+ end
1392
+
1393
+ it "uses the environment from the node request if lastrunfile exists but is empty" do
1349
1394
  Puppet[:lastrunfile] = file_containing('last_run_summary.yaml', '')
1350
1395
  configurer.run
1351
1396
 
1352
- expect(configurer.environment).to eq(Puppet[:environment])
1397
+ expect(configurer.environment).to eq(node_environment.name.to_s)
1398
+ end
1399
+
1400
+ it "uses the environment from the node request if the last used one cannot be found" do
1401
+ Puppet[:lastrunfile] = tmpfile('last_run_summary.yaml')
1402
+ configurer.run
1403
+
1404
+ expect(configurer.environment).to eq(node_environment.name.to_s)
1405
+ end
1406
+ end
1407
+
1408
+ describe "when the node request fails" do
1409
+ before do
1410
+ allow(Puppet::Node.indirection).to receive(:find).and_call_original
1411
+ allow(Puppet::Node.indirection).to receive(:find)
1412
+ .with(anything, hash_including(:ignore_cache => true, :fail_on_404 => true))
1413
+ .and_raise(Puppet::Error)
1353
1414
  end
1354
1415
 
1355
- it "uses environment from Puppet[:environment] if the last used one cannot be found" do
1416
+ it "uses the environment from Puppet[:environment] if the last used one cannot be found" do
1356
1417
  Puppet[:lastrunfile] = tmpfile('last_run_summary.yaml')
1357
1418
  configurer.run
1358
1419
 
@@ -597,11 +597,68 @@ describe Puppet::HTTP::Client do
597
597
  expect(response).to be_success
598
598
  end
599
599
 
600
- it "preserves basic authorization" do
600
+ it "does not preserve basic authorization when redirecting to different hosts" do
601
+ stub_request(:get, start_url).with(basic_auth: credentials).to_return(redirect_to(url: other_host))
602
+ stub_request(:get, other_host).to_return(status: 200)
603
+
604
+ client.get(start_url, options: {basic_auth: {user: 'user', password: 'pass'}})
605
+ expect(a_request(:get, other_host).
606
+ with{ |req| !req.headers.key?('Authorization')}).to have_been_made
607
+ end
608
+
609
+ it "does preserve basic authorization when redirecting to the same hosts" do
610
+ stub_request(:get, start_url).with(basic_auth: credentials).to_return(redirect_to(url: bar_url))
611
+ stub_request(:get, bar_url).with(basic_auth: credentials).to_return(status: 200)
612
+
613
+ client.get(start_url, options: {basic_auth: {user: 'user', password: 'pass'}})
614
+ expect(a_request(:get, bar_url).
615
+ with{ |req| req.headers.key?('Authorization')}).to have_been_made
616
+ end
617
+
618
+ it "does not preserve cookie header when redirecting to different hosts" do
619
+ headers = { 'Cookie' => 'TEST_COOKIE'}
620
+
621
+ stub_request(:get, start_url).with(headers: headers).to_return(redirect_to(url: other_host))
622
+ stub_request(:get, other_host).to_return(status: 200)
623
+
624
+ client.get(start_url, headers: headers)
625
+ expect(a_request(:get, other_host).
626
+ with{ |req| !req.headers.key?('Cookie')}).to have_been_made
627
+ end
628
+
629
+ it "does preserve cookie header when redirecting to the same hosts" do
630
+ headers = { 'Cookie' => 'TEST_COOKIE'}
631
+
632
+ stub_request(:get, start_url).with(headers: headers).to_return(redirect_to(url: bar_url))
633
+ stub_request(:get, bar_url).with(headers: headers).to_return(status: 200)
634
+
635
+ client.get(start_url, headers: headers)
636
+ expect(a_request(:get, bar_url).
637
+ with{ |req| req.headers.key?('Cookie')}).to have_been_made
638
+ end
639
+
640
+ it "does preserves cookie header and basic authentication when Puppet[:location_trusted] is true redirecting to different hosts" do
641
+ headers = { 'cookie' => 'TEST_COOKIE'}
642
+ Puppet[:location_trusted] = true
643
+
644
+ stub_request(:get, start_url).with(headers: headers, basic_auth: credentials).to_return(redirect_to(url: other_host))
645
+ stub_request(:get, other_host).with(headers: headers, basic_auth: credentials).to_return(status: 200)
646
+
647
+ client.get(start_url, headers: headers, options: {basic_auth: {user: 'user', password: 'pass'}})
648
+ expect(a_request(:get, other_host).
649
+ with{ |req| req.headers.key?('Authorization') && req.headers.key?('Cookie')}).to have_been_made
650
+ end
651
+
652
+ it "treats hosts as case-insensitive" do
653
+ start_url = URI("https://www.EXAmple.com:8140/Start")
654
+ bar_url = "https://www.example.com:8140/bar"
655
+
601
656
  stub_request(:get, start_url).with(basic_auth: credentials).to_return(redirect_to(url: bar_url))
602
657
  stub_request(:get, bar_url).with(basic_auth: credentials).to_return(status: 200)
603
658
 
604
659
  client.get(start_url, options: {basic_auth: {user: 'user', password: 'pass'}})
660
+ expect(a_request(:get, bar_url).
661
+ with{ |req| req.headers.key?('Authorization')}).to have_been_made
605
662
  end
606
663
 
607
664
  it "redirects given a relative location" do
@@ -104,7 +104,7 @@ describe Puppet::Resource::Catalog, "when compiling" do
104
104
 
105
105
  it "should include the current catalog_format" do
106
106
  catalog = Puppet::Resource::Catalog.new("host")
107
- expect(catalog.catalog_format).to eq(1)
107
+ expect(catalog.catalog_format).to eq(2)
108
108
  end
109
109
 
110
110
  describe "when compiling" do
@@ -178,6 +178,7 @@ describe Puppet::Resource::Catalog, "when compiling" do
178
178
  @original.add_edge(@middle, @bottom)
179
179
  @original.add_edge(@bottom, @bottomobject)
180
180
 
181
+ @original.catalog_format = 1
181
182
  @catalog = @original.to_ral
182
183
  end
183
184
 
@@ -190,6 +191,18 @@ describe Puppet::Resource::Catalog, "when compiling" do
190
191
  end
191
192
  end
192
193
 
194
+ it "should raise if an unknown resource is being converted" do
195
+ @new_res = Puppet::Resource.new "Unknown", "type", :kind => 'compilable_type'
196
+ @resource_array = [@new_res]
197
+
198
+ @original.add_resource(*@resource_array)
199
+ @original.add_edge(@bottomobject, @new_res)
200
+
201
+ @original.catalog_format = 2
202
+
203
+ expect { @original.to_ral }.to raise_error(Puppet::Error, "Resource type 'Unknown' was not found")
204
+ end
205
+
193
206
  it "should copy the tag list to the new catalog" do
194
207
  expect(@catalog.tags.sort).to eq(@original.tags.sort)
195
208
  end
@@ -638,19 +638,68 @@ describe Puppet::Resource do
638
638
  it "should use the resource type's :new method to create the resource if the resource is of a builtin type" do
639
639
  resource = Puppet::Resource.new("file", basepath+"/my/file")
640
640
  result = resource.to_ral
641
+
641
642
  expect(result).to be_instance_of(Puppet::Type.type(:file))
642
643
  expect(result[:path]).to eq(basepath+"/my/file")
643
644
  end
644
645
 
645
- it "should convert to a component instance if the resource type is not of a builtin type" do
646
+ it "should convert to a component instance if the resource is not a compilable_type" do
646
647
  resource = Puppet::Resource.new("foobar", "somename")
647
648
  result = resource.to_ral
648
649
 
649
650
  expect(result).to be_instance_of(Puppet::Type.type(:component))
650
651
  expect(result.title).to eq("Foobar[somename]")
651
652
  end
652
- end
653
653
 
654
+ it "should convert to a component instance if the resource is a class" do
655
+ resource = Puppet::Resource.new("Class", "somename")
656
+ result = resource.to_ral
657
+
658
+ expect(result).to be_instance_of(Puppet::Type.type(:component))
659
+ expect(result.title).to eq("Class[Somename]")
660
+ end
661
+
662
+ it "should convert to component when the resource is a defined_type" do
663
+ resource = Puppet::Resource.new("Unknown", "type", :kind => 'defined_type')
664
+
665
+ result = resource.to_ral
666
+ expect(result).to be_instance_of(Puppet::Type.type(:component))
667
+ end
668
+
669
+ it "should raise if a resource type is a compilable_type and it wasn't found" do
670
+ resource = Puppet::Resource.new("Unknown", "type", :kind => 'compilable_type')
671
+
672
+ expect { resource.to_ral }.to raise_error(Puppet::Error, "Resource type 'Unknown' was not found")
673
+ end
674
+
675
+ it "should use the old behaviour when the catalog_format is equal to 1" do
676
+ resource = Puppet::Resource.new("Unknown", "type")
677
+ catalog = Puppet::Resource::Catalog.new("mynode")
678
+
679
+ resource.catalog = catalog
680
+ resource.catalog.catalog_format = 1
681
+
682
+ result = resource.to_ral
683
+ expect(result).to be_instance_of(Puppet::Type.type(:component))
684
+ end
685
+
686
+ it "should use the new behaviour and fail when the catalog_format is greater than 1" do
687
+ resource = Puppet::Resource.new("Unknown", "type", :kind => 'compilable_type')
688
+ catalog = Puppet::Resource::Catalog.new("mynode")
689
+
690
+ resource.catalog = catalog
691
+ resource.catalog.catalog_format = 2
692
+
693
+ expect { resource.to_ral }.to raise_error(Puppet::Error, "Resource type 'Unknown' was not found")
694
+ end
695
+
696
+ it "should use the resource type when the resource doesn't respond to kind and the resource type can be found" do
697
+ resource = Puppet::Resource.new("file", basepath+"/my/file")
698
+
699
+ result = resource.to_ral
700
+ expect(result).to be_instance_of(Puppet::Type.type(:file))
701
+ end
702
+ end
654
703
  describe "when converting to puppet code" do
655
704
  before do
656
705
  @resource = Puppet::Resource.new("one::two", "/my/file",
@@ -766,6 +815,13 @@ describe Puppet::Resource do
766
815
  expect(Puppet::Resource.from_data_hash(JSON.parse(resource.to_json)).line).to eq(50)
767
816
  end
768
817
 
818
+ it "should include the kind if one is set" do
819
+ resource = Puppet::Resource.new("File", "/foo")
820
+ resource.kind = 'im_a_file'
821
+
822
+ expect(Puppet::Resource.from_data_hash(JSON.parse(resource.to_json)).kind).to eq('im_a_file')
823
+ end
824
+
769
825
  it "should include the 'exported' value if one is set" do
770
826
  resource = Puppet::Resource.new("File", "/foo")
771
827
  resource.exported = true
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: puppet
3
3
  version: !ruby/object:Gem::Version
4
- version: 7.12.0
4
+ version: 7.12.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Puppet Labs
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-10-11 00:00:00.000000000 Z
11
+ date: 2021-10-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: facter