puppet 5.5.3 → 5.5.6

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 (71) hide show
  1. checksums.yaml +5 -5
  2. data/CONTRIBUTING.md +1 -4
  3. data/Gemfile +5 -1
  4. data/Gemfile.lock +167 -0
  5. data/Rakefile +4 -34
  6. data/ext/build_defaults.yaml +0 -2
  7. data/lib/puppet/application/cert.rb +3 -1
  8. data/lib/puppet/defaults.rb +55 -26
  9. data/lib/puppet/face/certificate.rb +2 -0
  10. data/lib/puppet/indirector/ldap.rb +6 -0
  11. data/lib/puppet/node/environment.rb +4 -2
  12. data/lib/puppet/parser/functions/tagged.rb +1 -4
  13. data/lib/puppet/pops/issues.rb +4 -0
  14. data/lib/puppet/pops/validation/checker4_0.rb +100 -0
  15. data/lib/puppet/pops/validation/validator_factory_4_0.rb +4 -3
  16. data/lib/puppet/provider/augeas/augeas.rb +198 -4
  17. data/lib/puppet/provider/service/smf.rb +2 -3
  18. data/lib/puppet/provider/service/upstart.rb +10 -2
  19. data/lib/puppet/test/test_helper.rb +0 -3
  20. data/lib/puppet/type/file/source.rb +10 -1
  21. data/lib/puppet/version.rb +1 -1
  22. data/locales/puppet.pot +132 -118
  23. data/man/man5/puppet.conf.5 +23 -23
  24. data/man/man8/puppet-agent.8 +1 -1
  25. data/man/man8/puppet-apply.8 +1 -1
  26. data/man/man8/puppet-ca.8 +3 -3
  27. data/man/man8/puppet-catalog.8 +1 -1
  28. data/man/man8/puppet-cert.8 +2 -2
  29. data/man/man8/puppet-certificate.8 +3 -3
  30. data/man/man8/puppet-certificate_request.8 +1 -1
  31. data/man/man8/puppet-certificate_revocation_list.8 +1 -1
  32. data/man/man8/puppet-config.8 +1 -1
  33. data/man/man8/puppet-describe.8 +1 -1
  34. data/man/man8/puppet-device.8 +1 -1
  35. data/man/man8/puppet-doc.8 +1 -1
  36. data/man/man8/puppet-epp.8 +1 -1
  37. data/man/man8/puppet-facts.8 +1 -1
  38. data/man/man8/puppet-filebucket.8 +1 -1
  39. data/man/man8/puppet-generate.8 +1 -1
  40. data/man/man8/puppet-help.8 +1 -1
  41. data/man/man8/puppet-key.8 +1 -1
  42. data/man/man8/puppet-lookup.8 +1 -1
  43. data/man/man8/puppet-man.8 +1 -1
  44. data/man/man8/puppet-master.8 +1 -1
  45. data/man/man8/puppet-module.8 +1 -1
  46. data/man/man8/puppet-node.8 +1 -1
  47. data/man/man8/puppet-parser.8 +1 -1
  48. data/man/man8/puppet-plugin.8 +1 -1
  49. data/man/man8/puppet-report.8 +1 -1
  50. data/man/man8/puppet-resource.8 +1 -1
  51. data/man/man8/puppet-script.8 +1 -1
  52. data/man/man8/puppet-status.8 +1 -1
  53. data/man/man8/puppet.8 +3 -3
  54. data/spec/integration/type/file_spec.rb +18 -3
  55. data/spec/integration/util/settings_spec.rb +1 -0
  56. data/spec/integration/util/windows/security_spec.rb +78 -1
  57. data/spec/unit/application/master_spec.rb +2 -0
  58. data/spec/unit/configurer/downloader_spec.rb +5 -0
  59. data/spec/unit/defaults_spec.rb +13 -0
  60. data/spec/unit/face/help_spec.rb +2 -1
  61. data/spec/unit/indirector/ldap_spec.rb +22 -1
  62. data/spec/unit/node/environment_spec.rb +14 -0
  63. data/spec/unit/parser/functions/tagged_spec.rb +16 -0
  64. data/spec/unit/pops/validator/validator_spec.rb +139 -4
  65. data/spec/unit/provider/augeas/augeas_spec.rb +66 -1
  66. data/spec/unit/provider/service/smf_spec.rb +2 -6
  67. data/spec/unit/provider/service/upstart_spec.rb +37 -0
  68. data/spec/unit/settings/autosign_setting_spec.rb +2 -2
  69. data/spec/unit/settings/file_setting_spec.rb +6 -0
  70. data/spec/unit/ssl/certificate_authority_spec.rb +1 -0
  71. metadata +4 -3
@@ -162,4 +162,6 @@ Puppet::Indirector::Face.define(:certificate, '0.0.1') do
162
162
 
163
163
  deactivate_action(:search)
164
164
  deactivate_action(:save)
165
+
166
+ deprecate
165
167
  end
@@ -2,6 +2,12 @@ require 'puppet/indirector/terminus'
2
2
  require 'puppet/util/ldap/connection'
3
3
 
4
4
  class Puppet::Indirector::Ldap < Puppet::Indirector::Terminus
5
+ def initialize
6
+ #TRANSLATORS 'Puppet::Indirector::Ldap' is a class and should not be translated
7
+ Puppet.deprecation_warning(_("Puppet::Indirector::Ldap is deprecated and will be removed in a future release of Puppet."));
8
+ super
9
+ end
10
+
5
11
  # Perform our ldap search and process the result.
6
12
  def find(request)
7
13
  ldapsearch(search_filter(request.key)) { |entry| return process(entry) } || nil
@@ -434,9 +434,10 @@ class Puppet::Node::Environment
434
434
  end
435
435
 
436
436
  # Loads module translations for the current environment once for
437
- # the lifetime of the environment.
437
+ # the lifetime of the environment. Execute a block in the context
438
+ # of that translation domain.
438
439
  def with_text_domain
439
- return if Puppet[:disable_i18n]
440
+ return yield if Puppet[:disable_i18n]
440
441
 
441
442
  if @text_domain.nil?
442
443
  @text_domain = @name
@@ -448,6 +449,7 @@ class Puppet::Node::Environment
448
449
 
449
450
  yield
450
451
  ensure
452
+ # Is a noop if disable_i18n is true
451
453
  Puppet::GettextConfig.clear_text_domain
452
454
  end
453
455
 
@@ -9,12 +9,9 @@ Puppet::Parser::Functions::newfunction(:tagged, :type => :rvalue, :arity => -2,
9
9
  {:operation => 'tagged'})
10
10
  end
11
11
 
12
- configtags = compiler.catalog.tags
13
- resourcetags = resource.tags
14
-
15
12
  retval = true
16
13
  vals.each do |val|
17
- unless configtags.include?(val) or resourcetags.include?(val)
14
+ unless compiler.catalog.tagged?(val) or resource.tagged?(val)
18
15
  retval = false
19
16
  break
20
17
  end
@@ -486,6 +486,10 @@ module Issues
486
486
  _("Unacceptable name. The name '%{name}' is unacceptable as the name of %{value}") % { name: name, value: label.a_an(semantic) }
487
487
  end
488
488
 
489
+ ILLEGAL_DEFINITION_LOCATION = issue :ILLEGAL_DEFINITION_LOCATION, :name, :file do
490
+ _("Unacceptable location. The name '%{name}' is unacceptable in file '%{file}'") % { name: name, file: file }
491
+ end
492
+
489
493
  CAPTURES_REST_NOT_LAST = hard_issue :CAPTURES_REST_NOT_LAST, :param_name do
490
494
  _("Parameter $%{param} is not last, and has 'captures rest'") % { param: param_name }
491
495
  end
@@ -395,6 +395,8 @@ class Checker4_0 < Evaluator::LiteralEvaluator
395
395
  if o.name !~ Patterns::CLASSREF_DECL
396
396
  acceptor.accept(Issues::ILLEGAL_DEFINITION_NAME, o, {:name=>o.name})
397
397
  end
398
+
399
+ internal_check_file_namespace(o, o.name, o.locator.file)
398
400
  internal_check_reserved_type_name(o, o.name)
399
401
  internal_check_future_reserved_word(o, o.name)
400
402
  end
@@ -530,6 +532,104 @@ class Checker4_0 < Evaluator::LiteralEvaluator
530
532
  end
531
533
  end
532
534
 
535
+ NO_NAMESPACE = :no_namespace
536
+ NO_PATH = :no_path
537
+ BAD_MODULE_FILE = :bad_module_file
538
+ def internal_check_file_namespace(o, name, file)
539
+ return if file.nil? || file == '' #e.g. puppet apply -e '...'
540
+
541
+ file_namespace = namespace_for_file(file)
542
+ return if file_namespace == NO_NAMESPACE
543
+
544
+ # Downcasing here because check is case-insensitive
545
+ if file_namespace == BAD_MODULE_FILE || !name.downcase.start_with?(file_namespace)
546
+ acceptor.accept(Issues::ILLEGAL_DEFINITION_LOCATION, o, {:name => name, :file => file})
547
+ end
548
+ end
549
+
550
+ # @api private
551
+ class Puppet::Util::FileNamespaceAdapter < Puppet::Pops::Adaptable::Adapter
552
+ attr_accessor :file_to_namespace
553
+ end
554
+
555
+ def namespace_for_file(file)
556
+ env = Puppet.lookup(:current_environment)
557
+ return NO_NAMESPACE if env.nil?
558
+
559
+ Puppet::Util::FileNamespaceAdapter.adapt(env) do |adapter|
560
+ adapter.file_to_namespace ||= {}
561
+
562
+ file_namespace = adapter.file_to_namespace[file]
563
+ return file_namespace unless file_namespace.nil? # No cache entry, so we do the calculation
564
+
565
+ path = Pathname.new(file)
566
+
567
+ return adapter.file_to_namespace[file] = NO_NAMESPACE if path.extname != ".pp"
568
+
569
+ path = path.expand_path
570
+
571
+ return adapter.file_to_namespace[file] = NO_NAMESPACE if initial_manifest?(path, env.manifest)
572
+
573
+ #All auto-loaded files from modules come from a module search path dir
574
+ relative_path = get_module_relative_path(path, env.full_modulepath)
575
+
576
+ return adapter.file_to_namespace[file] = NO_NAMESPACE if relative_path == NO_PATH
577
+
578
+ #If a file comes from a module, but isn't in the right place, always error
579
+ names = dir_to_names(relative_path)
580
+
581
+ return adapter.file_to_namespace[file] = (names == BAD_MODULE_FILE ? BAD_MODULE_FILE : names.join("::").freeze)
582
+ end
583
+ end
584
+
585
+ def initial_manifest?(path, manifest_setting)
586
+ return false if manifest_setting.nil? || manifest_setting == :no_manifest
587
+
588
+ string_path = path.to_s
589
+
590
+ string_path == manifest_setting || string_path.start_with?(manifest_setting)
591
+ end
592
+
593
+ def get_module_relative_path(file_path, modulepath_directories)
594
+ clean_file = file_path.cleanpath
595
+ parent_path = modulepath_directories.find { |path_dir| is_parent_dir_of(path_dir, clean_file) }
596
+ return NO_PATH if parent_path.nil?
597
+
598
+ file_path.relative_path_from(Pathname.new(parent_path))
599
+ end
600
+
601
+ def is_parent_dir_of(parent_dir, child_dir)
602
+ parent_dir_path = Pathname.new(parent_dir)
603
+ clean_parent = parent_dir_path.cleanpath
604
+
605
+ return child_dir.to_s.start_with?(clean_parent.to_s)
606
+ end
607
+
608
+ def dir_to_names(relative_path)
609
+ # Downcasing here because check is case-insensitive
610
+ path_components = relative_path.to_s.downcase.split(File::SEPARATOR)
611
+
612
+ # Example definition dir: manifests in this path:
613
+ # <module name>/manifests/<module subdir>/<classfile>.pp
614
+ dir = path_components[1]
615
+
616
+ # How can we get this result?
617
+ # If it is not an initial manifest, it must come from a module,
618
+ # and from the manifests dir there. This may never get used...
619
+ return BAD_MODULE_FILE unless dir == 'manifests' || dir == 'functions' || dir == 'types' || dir == 'plans'
620
+
621
+ names = path_components[2 .. -2] # Directories inside module
622
+ names.unshift(path_components[0]) # Name of the module itself
623
+
624
+ # Do not include name of module init file at top level of module
625
+ # e.g. <module name>/manifests/init.pp
626
+ filename = path_components[-1]
627
+ if !(path_components.length == 3 && filename == 'init.pp')
628
+ names.push(filename[0 .. -4]) # Remove .pp from filename
629
+ end
630
+
631
+ names
632
+ end
533
633
 
534
634
  RESERVED_PARAMETERS = {
535
635
  'name' => true,
@@ -27,15 +27,16 @@ class ValidatorFactory_4_0 < Factory
27
27
  # Configure each issue that should **not** be an error
28
28
  #
29
29
  # Validate as per the current runtime configuration
30
- p[Issues::RT_NO_STORECONFIGS_EXPORT] = Puppet[:storeconfigs] ? :ignore : :warning
31
- p[Issues::RT_NO_STORECONFIGS] = Puppet[:storeconfigs] ? :ignore : :warning
30
+ p[Issues::RT_NO_STORECONFIGS_EXPORT] = Puppet[:storeconfigs] ? :ignore : :warning
31
+ p[Issues::RT_NO_STORECONFIGS] = Puppet[:storeconfigs] ? :ignore : :warning
32
32
 
33
33
  p[Issues::FUTURE_RESERVED_WORD] = :deprecation
34
34
 
35
35
  p[Issues::DUPLICATE_KEY] = Puppet[:strict] == :off ? :ignore : Puppet[:strict]
36
36
  p[Issues::NAME_WITH_HYPHEN] = :error
37
37
  p[Issues::EMPTY_RESOURCE_SPECIALIZATION] = :ignore
38
- p[Issues::CLASS_NOT_VIRTUALIZABLE] = Puppet[:strict] == :off ? :warning : Puppet[:strict]
38
+ p[Issues::CLASS_NOT_VIRTUALIZABLE] = Puppet[:strict] == :off ? :warning : Puppet[:strict]
39
+ p[Issues::ILLEGAL_DEFINITION_LOCATION] = :deprecation
39
40
  p
40
41
  end
41
42
  end
@@ -281,7 +281,7 @@ Puppet::Type.type(:augeas).provide(:augeas) do
281
281
  when "=="
282
282
  begin
283
283
  arg = clause_array.shift
284
- new_array = eval arg
284
+ new_array = to_array(arg)
285
285
  return_value = (values == new_array)
286
286
  rescue
287
287
  fail(_("Invalid array in command: %{cmd}") % { cmd: cmd_array.join(" ") })
@@ -289,7 +289,7 @@ Puppet::Type.type(:augeas).provide(:augeas) do
289
289
  when "!="
290
290
  begin
291
291
  arg = clause_array.shift
292
- new_array = eval arg
292
+ new_array = to_array(arg)
293
293
  return_value = (values != new_array)
294
294
  rescue
295
295
  fail(_("Invalid array in command: %{cmd}") % { cmd: cmd_array.join(" ") })
@@ -337,7 +337,7 @@ Puppet::Type.type(:augeas).provide(:augeas) do
337
337
  when "=="
338
338
  begin
339
339
  arg = clause_array.shift
340
- new_array = eval arg
340
+ new_array = to_array(arg)
341
341
  return_value = (result == new_array)
342
342
  rescue
343
343
  fail(_("Invalid array in command: %{cmd}") % { cmd: cmd_array.join(" ") })
@@ -345,7 +345,7 @@ Puppet::Type.type(:augeas).provide(:augeas) do
345
345
  when "!="
346
346
  begin
347
347
  arg = clause_array.shift
348
- new_array = eval arg
348
+ new_array = to_array(arg)
349
349
  return_value = (result != new_array)
350
350
  rescue
351
351
  fail(_("Invalid array in command: %{cmd}") % { cmd: cmd_array.join(" ") })
@@ -570,4 +570,198 @@ Puppet::Type.type(:augeas).provide(:augeas) do
570
570
  end
571
571
  end
572
572
  end
573
+
574
+ def to_array(string)
575
+ s = StringScanner.new(string)
576
+ match = array_open(s)
577
+ raise "Unable to parse array. Unexpected character at: #{s.rest}" if match.nil?
578
+
579
+ array_content = array_values(s)
580
+
581
+ match = array_close(s)
582
+ raise "Unable to parse array. Unexpected character at: #{s.rest}" if match.nil?
583
+
584
+ array_content
585
+ end
586
+ private :to_array
587
+
588
+ def array_open(scanner)
589
+ scanner.scan(/\s*\[\s*/)
590
+ end
591
+ private :array_open
592
+
593
+ def array_close(scanner)
594
+ scanner.scan(/\s*\]\s*/)
595
+ end
596
+ private :array_close
597
+
598
+ def array_separator(scanner)
599
+ scanner.scan(/\s*,\s*/)
600
+ end
601
+ private :array_separator
602
+
603
+ def single_quote_unescaped_char(scanner)
604
+ scanner.scan(/[^'\\]/)
605
+ end
606
+ private :single_quote_unescaped_char
607
+
608
+ def single_quote_escaped_char(scanner)
609
+ scanner.scan(/\\(['\\])/) && scanner[1]
610
+ end
611
+ private :single_quote_escaped_char
612
+
613
+ def single_quote_char(scanner)
614
+ single_quote_escaped_char(scanner) || single_quote_unescaped_char(scanner)
615
+ end
616
+ private :single_quote_char
617
+
618
+ def double_quote_unescaped_char(scanner)
619
+ scanner.scan(/[^"\\]/)
620
+ end
621
+ private :double_quote_unescaped_char
622
+
623
+ # This handles the possible Ruby escape sequences in double-quoted strings,
624
+ # except for \M-x, \M-\C-x, \M-\cx, \c\M-x, \c?, and \C-?. The full list of
625
+ # escape sequences, and their meanings is taken from:
626
+ # https://github.com/ruby/ruby/blob/90fdfec11a4a42653722e2ce2a672d6e87a57b8e/doc/syntax/literals.rdoc#strings
627
+ def double_quote_escaped_char(scanner)
628
+ match = scanner.scan(/\\(["\\abtnvfres0-7xu])/)
629
+ return nil if match.nil?
630
+
631
+ case scanner[1]
632
+ when '\\' then return '\\'
633
+ when '"' then return '"'
634
+ when 'a' then return "\a"
635
+ when 'b' then return "\b"
636
+ when 't' then return "\t"
637
+ when 'n' then return "\n"
638
+ when 'v' then return "\v"
639
+ when 'f' then return "\f"
640
+ when 'r' then return "\r"
641
+ when 'e' then return "\e"
642
+ when 's' then return "\s"
643
+ when /[0-7]/
644
+ octal_character = scanner[1]
645
+ other_digits = scanner.scan(/[0-7]{1,2}/)
646
+ octal_character << other_digits unless other_digits.nil?
647
+
648
+ return octal_character.to_i(8).chr
649
+ when 'x'
650
+ hex_character = scanner.scan(/[0-9a-fA-F]{1,2}/)
651
+ if hex_character.nil?
652
+ return nil
653
+ else
654
+ return hex_character.to_i(16).chr
655
+ end
656
+ when 'u'
657
+ return unicode_short_hex_character(scanner) || unicode_long_hex_characters(scanner)
658
+ else
659
+ # Not a valid escape sequence as far as we're concerned.
660
+ return nil
661
+ end
662
+ end
663
+ private :double_quote_escaped_char
664
+
665
+ def unicode_short_hex_character(scanner)
666
+ unicode_character = scanner.scan(/[0-9a-fA-F]{4}/)
667
+ if unicode_character.nil?
668
+ return nil
669
+ else
670
+ return [unicode_character.hex].pack 'U'
671
+ end
672
+ end
673
+ private :unicode_short_hex_character
674
+
675
+ def unicode_long_hex_characters(scanner)
676
+ unicode_string = ''
677
+ return nil unless scanner.scan(/{/)
678
+
679
+ loop do
680
+ char = scanner.scan(/[0-9a-fA-F]{1,6}/)
681
+ break if char.nil?
682
+ unicode_string << [char.hex].pack('U')
683
+
684
+ separator = scanner.scan(/\s/)
685
+ break if separator.nil?
686
+ end
687
+
688
+ return nil unless scanner.scan(/}/)
689
+
690
+ if unicode_string.empty?
691
+ return nil
692
+ else
693
+ return unicode_string
694
+ end
695
+ end
696
+ private :unicode_long_hex_characters
697
+
698
+ def single_quoted_string(scanner)
699
+ quoted_string = ''
700
+
701
+ match = scanner.scan(/'/)
702
+ return nil if match.nil?
703
+
704
+ loop do
705
+ match = single_quote_char(scanner)
706
+ break if match.nil?
707
+
708
+ quoted_string << match
709
+ end
710
+
711
+ match = scanner.scan(/'/)
712
+ if match
713
+ return quoted_string
714
+ else
715
+ return nil
716
+ end
717
+ end
718
+ private :single_quoted_string
719
+
720
+ def double_quote_char(scanner)
721
+ double_quote_escaped_char(scanner) || double_quote_unescaped_char(scanner)
722
+ end
723
+ private :double_quote_char
724
+
725
+ def double_quoted_string(scanner)
726
+ quoted_string = ''
727
+
728
+ match = scanner.scan(/"/)
729
+ return nil if match.nil?
730
+
731
+ loop do
732
+ match = double_quote_char(scanner)
733
+ break if match.nil?
734
+
735
+ quoted_string << match
736
+ end
737
+
738
+ match = scanner.scan(/"/)
739
+ if match
740
+ return quoted_string
741
+ else
742
+ return nil
743
+ end
744
+ end
745
+ private :double_quoted_string
746
+
747
+ def quoted_string(scanner)
748
+ single_quoted_string(scanner) || double_quoted_string(scanner)
749
+ end
750
+ private :quoted_string
751
+
752
+ def array_values(scanner)
753
+ values = []
754
+
755
+ loop do
756
+ match = quoted_string(scanner)
757
+ break if match.nil?
758
+ values << match
759
+
760
+ match = array_separator(scanner)
761
+ break if match.nil?
762
+ end
763
+
764
+ values
765
+ end
766
+ private :array_values
573
767
  end
@@ -108,8 +108,6 @@ Puppet::Type.type(:service).provide :smf, :parent => :base do
108
108
  end
109
109
 
110
110
  def stop
111
- # Don't try to stop non-existing services (PUP-8167)
112
- return if self.status == :absent
113
111
  # Wait for the service to actually stop before returning.
114
112
  super
115
113
  self.wait('offline', 'disabled', 'uninitialized')
@@ -138,8 +136,9 @@ Puppet::Type.type(:service).provide :smf, :parent => :base do
138
136
  states = service_states
139
137
  state = states[1] == "-" ? states[0] : states[1]
140
138
  rescue Puppet::ExecutionFailure
139
+ # TODO (PUP-8957): Should this be set back to INFO ?
141
140
  debug "Could not get status on service #{self.name} #{$!}"
142
- return :absent
141
+ return :stopped
143
142
  end
144
143
 
145
144
  case state