bolt 0.16.0 → 0.16.1

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 (91) hide show
  1. checksums.yaml +4 -4
  2. data/lib/bolt/cli.rb +32 -17
  3. data/lib/bolt/config.rb +12 -31
  4. data/lib/bolt/error.rb +18 -7
  5. data/lib/bolt/executor.rb +3 -3
  6. data/lib/bolt/inventory.rb +101 -0
  7. data/lib/bolt/inventory/group.rb +127 -0
  8. data/lib/bolt/node.rb +10 -9
  9. data/lib/bolt/node/ssh.rb +86 -69
  10. data/lib/bolt/node/winrm.rb +3 -3
  11. data/lib/bolt/outputter/human.rb +1 -1
  12. data/lib/bolt/pal.rb +17 -11
  13. data/lib/bolt/result.rb +9 -4
  14. data/lib/bolt/target.rb +26 -11
  15. data/lib/bolt/util.rb +54 -0
  16. data/lib/bolt/version.rb +1 -1
  17. data/modules/boltlib/lib/puppet/functions/fail_plan.rb +27 -0
  18. data/modules/boltlib/lib/puppet/functions/file_upload.rb +4 -4
  19. data/modules/boltlib/lib/puppet/functions/run_command.rb +3 -3
  20. data/modules/boltlib/lib/puppet/functions/run_plan.rb +18 -4
  21. data/modules/boltlib/lib/puppet/functions/run_script.rb +5 -2
  22. data/modules/boltlib/lib/puppet/functions/run_task.rb +3 -3
  23. data/vendored/puppet/lib/puppet/datatypes/error.rb +5 -3
  24. data/vendored/puppet/lib/puppet/datatypes/impl/error.rb +10 -12
  25. data/vendored/puppet/lib/puppet/defaults.rb +33 -25
  26. data/vendored/puppet/lib/puppet/etc.rb +2 -2
  27. data/vendored/puppet/lib/puppet/external/pson/pure/generator.rb +1 -1
  28. data/vendored/puppet/lib/puppet/external/pson/pure/parser.rb +1 -1
  29. data/vendored/puppet/lib/puppet/face/config.rb +45 -0
  30. data/vendored/puppet/lib/puppet/face/module/generate.rb +5 -0
  31. data/vendored/puppet/lib/puppet/functions/annotate.rb +1 -1
  32. data/vendored/puppet/lib/puppet/functions/any.rb +1 -1
  33. data/vendored/puppet/lib/puppet/generate/type.rb +1 -1
  34. data/vendored/puppet/lib/puppet/gettext/config.rb +2 -2
  35. data/vendored/puppet/lib/puppet/gettext/stubs.rb +1 -1
  36. data/vendored/puppet/lib/puppet/interface/action.rb +11 -0
  37. data/vendored/puppet/lib/puppet/interface/action_builder.rb +8 -0
  38. data/vendored/puppet/lib/puppet/network/authstore.rb +1 -1
  39. data/vendored/puppet/lib/puppet/network/http/connection.rb +1 -1
  40. data/vendored/puppet/lib/puppet/parameter/boolean.rb +1 -1
  41. data/vendored/puppet/lib/puppet/parser/ast/branch.rb +1 -1
  42. data/vendored/puppet/lib/puppet/parser/functions/new.rb +1 -1
  43. data/vendored/puppet/lib/puppet/parser/functions/reverse_each.rb +1 -1
  44. data/vendored/puppet/lib/puppet/pops/evaluator/compare_operator.rb +1 -1
  45. data/vendored/puppet/lib/puppet/pops/evaluator/evaluator_impl.rb +3 -3
  46. data/vendored/puppet/lib/puppet/pops/evaluator/literal_evaluator.rb +1 -1
  47. data/vendored/puppet/lib/puppet/pops/evaluator/runtime3_converter.rb +1 -1
  48. data/vendored/puppet/lib/puppet/pops/evaluator/runtime3_support.rb +1 -1
  49. data/vendored/puppet/lib/puppet/pops/issues.rb +1 -1
  50. data/vendored/puppet/lib/puppet/pops/loader/loader.rb +1 -1
  51. data/vendored/puppet/lib/puppet/pops/loader/loader_paths.rb +1 -1
  52. data/vendored/puppet/lib/puppet/pops/loader/module_loaders.rb +3 -5
  53. data/vendored/puppet/lib/puppet/pops/loader/puppet_resource_type_impl_instantiator.rb +1 -1
  54. data/vendored/puppet/lib/puppet/pops/loader/runtime3_type_loader.rb +1 -1
  55. data/vendored/puppet/lib/puppet/pops/loaders.rb +40 -1
  56. data/vendored/puppet/lib/puppet/pops/lookup/interpolation.rb +1 -1
  57. data/vendored/puppet/lib/puppet/pops/model/tree_dumper.rb +1 -1
  58. data/vendored/puppet/lib/puppet/pops/parser/epp_support.rb +1 -1
  59. data/vendored/puppet/lib/puppet/pops/parser/interpolation_support.rb +1 -1
  60. data/vendored/puppet/lib/puppet/pops/parser/lexer2.rb +1 -1
  61. data/vendored/puppet/lib/puppet/pops/parser/lexer_support.rb +2 -2
  62. data/vendored/puppet/lib/puppet/pops/parser/locatable.rb +1 -1
  63. data/vendored/puppet/lib/puppet/pops/parser/locator.rb +2 -6
  64. data/vendored/puppet/lib/puppet/pops/resource/param.rb +1 -1
  65. data/vendored/puppet/lib/puppet/pops/resource/resource_type_impl.rb +1 -1
  66. data/vendored/puppet/lib/puppet/pops/types/iterable.rb +1 -1
  67. data/vendored/puppet/lib/puppet/pops/types/tree_iterators.rb +5 -1
  68. data/vendored/puppet/lib/puppet/pops/types/type_acceptor.rb +1 -1
  69. data/vendored/puppet/lib/puppet/pops/types/type_calculator.rb +1 -1
  70. data/vendored/puppet/lib/puppet/pops/types/type_with_members.rb +1 -1
  71. data/vendored/puppet/lib/puppet/pops/types/types.rb +1 -1
  72. data/vendored/puppet/lib/puppet/provider/package/yum.rb +1 -1
  73. data/vendored/puppet/lib/puppet/provider/service/redhat.rb +3 -2
  74. data/vendored/puppet/lib/puppet/provider/service/systemd.rb +1 -1
  75. data/vendored/puppet/lib/puppet/provider/ssh_authorized_key/parsed.rb +1 -1
  76. data/vendored/puppet/lib/puppet/resource/type.rb +1 -1
  77. data/vendored/puppet/lib/puppet/settings/base_setting.rb +1 -1
  78. data/vendored/puppet/lib/puppet/settings/ini_file.rb +33 -12
  79. data/vendored/puppet/lib/puppet/ssl/certificate_request.rb +2 -2
  80. data/vendored/puppet/lib/puppet/transaction.rb +37 -14
  81. data/vendored/puppet/lib/puppet/type/cron.rb +1 -1
  82. data/vendored/puppet/lib/puppet/type/file/checksum.rb +6 -0
  83. data/vendored/puppet/lib/puppet/type/mount.rb +0 -9
  84. data/vendored/puppet/lib/puppet/util/character_encoding.rb +2 -2
  85. data/vendored/puppet/lib/puppet/util/network_device/cisco/device.rb +5 -5
  86. data/vendored/puppet/lib/puppet/util/rdoc/generators/puppet_generator.rb +1 -1
  87. data/vendored/puppet/lib/puppet/util/windows/process.rb +1 -1
  88. data/vendored/puppet/lib/puppet/vendor/pathspec/lib/pathspec/gitignorespec.rb +18 -18
  89. data/vendored/puppet/lib/puppet/vendor/semantic_puppet/lib/semantic_puppet/version.rb +2 -2
  90. data/vendored/puppet/lib/puppet/vendor/semantic_puppet/lib/semantic_puppet/version_range.rb +5 -5
  91. metadata +20 -2
data/lib/bolt/util.rb ADDED
@@ -0,0 +1,54 @@
1
+ module Bolt
2
+ module Util
3
+ # CODEREVIEW I hate mixing in random modules
4
+ class << self
5
+ def read_config_file(path, default_paths = nil, file_name = 'file')
6
+ logger = Logging.logger[self]
7
+ path_passed = path
8
+ if path.nil? && default_paths
9
+ found_default = default_paths.select { |p| File.exist?(p) }
10
+ if found_default.size > 1
11
+ logger.warn "Found #{file_name}s at #{found_default.join(', ')}, using the first"
12
+ end
13
+ # Use first found, fall back to first default and try to load even if it didn't exist
14
+ path = found_default.first || default_paths.first
15
+ end
16
+
17
+ path = File.expand_path(path)
18
+ # safe_load doesn't work with psych in ruby 2.0
19
+ # The user controls the configfile so this isn't a problem
20
+ # rubocop:disable YAMLLoad
21
+ File.open(path, "r:UTF-8") { |f| YAML.load(f.read) }
22
+ rescue Errno::ENOENT
23
+ if path_passed
24
+ raise Bolt::CLIError, "Could not read #{file_name} file: #{path}"
25
+ end
26
+ # In older releases of psych SyntaxError is not a subclass of Exception
27
+ rescue Psych::SyntaxError
28
+ raise Bolt::CLIError, "Could not parse #{file_name} file: #{path}"
29
+ rescue Psych::Exception
30
+ raise Bolt::CLIError, "Could not parse #{file_name} file: #{path}"
31
+ rescue IOError, SystemCallError
32
+ raise Bolt::CLIError, "Could not read #{file_name} file: #{path}"
33
+ end
34
+
35
+ def deep_merge(hash1, hash2)
36
+ recursive_merge = proc do |_key, h1, h2|
37
+ if h1.is_a?(Hash) && h2.is_a?(Hash)
38
+ h1.merge(h2, &recursive_merge)
39
+ else
40
+ h2
41
+ end
42
+ end
43
+ hash1.merge(hash2, &recursive_merge)
44
+ end
45
+
46
+ def symbolize_keys(hash)
47
+ hash.each_with_object({}) do |(k, v), acc|
48
+ k = k.to_sym
49
+ acc[k] = v.is_a?(Hash) ? symbolize_keys(v) : v
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
data/lib/bolt/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Bolt
2
- VERSION = '0.16.0'.freeze
2
+ VERSION = '0.16.1'.freeze
3
3
  end
@@ -0,0 +1,27 @@
1
+ # Raises a Bolt::PlanFailure exception to signal to callers that the plan failed
2
+ #
3
+ # Plan authors should call this function when their plan is not successful. The
4
+ # error may then be caught by another plans run_plan function or in bolt itself
5
+
6
+ require 'bolt/error'
7
+
8
+ Puppet::Functions.create_function(:fail_plan, Puppet::Functions::InternalFunction) do
9
+ dispatch :from_args do
10
+ param 'String[1]', :msg
11
+ optional_param 'String[1]', :kind
12
+ optional_param 'Hash[String[1], Any]', :details
13
+ optional_param 'String[1]', :issue_code
14
+ end
15
+
16
+ dispatch :from_error do
17
+ param 'Error', :error
18
+ end
19
+
20
+ def from_args(msg, kind = nil, details = nil, issue_code = nil)
21
+ raise Bolt::PlanFailure.new(msg, kind || 'bolt/plan-failure', details, issue_code)
22
+ end
23
+
24
+ def from_error(e)
25
+ from_args(e.message, e.kind, e.details, e.issue_code)
26
+ end
27
+ end
@@ -30,7 +30,8 @@ Puppet::Functions.create_function(:file_upload, Puppet::Functions::InternalFunct
30
30
  end
31
31
 
32
32
  executor = Puppet.lookup(:bolt_executor) { nil }
33
- unless executor && Puppet.features.bolt?
33
+ inventory = Puppet.lookup(:bolt_inventory) { nil }
34
+ unless executor && inventory && Puppet.features.bolt?
34
35
  raise Puppet::ParseErrorWithIssue.from_issue_and_stack(
35
36
  Puppet::Pops::Issues::TASK_MISSING_BOLT, action: _('do file uploads')
36
37
  )
@@ -44,13 +45,12 @@ Puppet::Functions.create_function(:file_upload, Puppet::Functions::InternalFunct
44
45
  end
45
46
 
46
47
  # Ensure that that given targets are all Target instances
47
- targets = [targets] unless targets.is_a?(Array)
48
- targets = targets.flatten.map { |t| t.is_a?(String) ? Bolt::Target.from_uri(t) : t }
48
+ targets = inventory.get_targets(targets)
49
49
  if targets.empty?
50
50
  call_function('debug', "Simulating file upload of '#{found}' - no targets given - no action taken")
51
51
  r = Bolt::ResultSet.new([])
52
52
  else
53
- r = executor.file_upload(targets, found, destination)
53
+ r = executor.file_upload(targets, found, destination, options.select { |k, _| k == '_run_as' })
54
54
  end
55
55
 
56
56
  if !r.ok && !options['_catch_errors']
@@ -28,15 +28,15 @@ Puppet::Functions.create_function(:run_command) do
28
28
  end
29
29
 
30
30
  executor = Puppet.lookup(:bolt_executor) { nil }
31
- unless executor && Puppet.features.bolt?
31
+ inventory = Puppet.lookup(:bolt_inventory) { nil }
32
+ unless executor && inventory && Puppet.features.bolt?
32
33
  raise Puppet::ParseErrorWithIssue.from_issue_and_stack(
33
34
  Puppet::Pops::Issues::TASK_MISSING_BOLT, action: _('run a command')
34
35
  )
35
36
  end
36
37
 
37
38
  # Ensure that that given targets are all Target instances
38
- targets = [targets] unless targets.is_a?(Array)
39
- targets = targets.flatten.map { |t| t.is_a?(String) ? Bolt::Target.from_uri(t) : t }
39
+ targets = inventory.get_targets(targets)
40
40
 
41
41
  if targets.empty?
42
42
  call_function('debug', "Simulating run_command('#{command}') - no targets given - no action taken")
@@ -8,6 +8,8 @@
8
8
  # }
9
9
  # run_plan('myplan', { x => 'testing' })
10
10
  #
11
+ require 'bolt/error'
12
+
11
13
  Puppet::Functions.create_function(:run_plan, Puppet::Functions::InternalFunction) do
12
14
  dispatch :run_plan do
13
15
  scope_param
@@ -29,7 +31,7 @@ Puppet::Functions.create_function(:run_plan, Puppet::Functions::InternalFunction
29
31
  )
30
32
  end
31
33
 
32
- use_args = named_args.reject { |k, _| k.start_with?('_') }
34
+ params = named_args.reject { |k, _| k.start_with?('_') }
33
35
 
34
36
  loaders = closure_scope.compiler.loaders
35
37
  # The perspective of the environment is wanted here (for now) to not have to
@@ -41,10 +43,22 @@ Puppet::Functions.create_function(:run_plan, Puppet::Functions::InternalFunction
41
43
  old_run_as = executor.run_as
42
44
  executor.run_as = run_as
43
45
  end
44
- result = func.class.dispatcher.dispatchers[0].call_by_name_with_scope(scope, use_args, true)
45
- if run_as
46
- executor.run_as = old_run_as
46
+
47
+ begin
48
+ result = func.class.dispatcher.dispatchers[0].call_by_name_with_scope(scope, params, true)
49
+ rescue Puppet::PreformattedError => err
50
+ if named_args['_catch_errors'] &&
51
+ err.respond_to?(:cause) && err.cause && err.cause.is_a?(Bolt::Error)
52
+ result = err.cause.to_puppet_error
53
+ else
54
+ raise err
55
+ end
56
+ ensure
57
+ if run_as
58
+ executor.run_as = old_run_as
59
+ end
47
60
  end
61
+
48
62
  return result
49
63
  end
50
64
  # Could not find plan
@@ -27,7 +27,8 @@ Puppet::Functions.create_function(:run_script, Puppet::Functions::InternalFuncti
27
27
  end
28
28
 
29
29
  executor = Puppet.lookup(:bolt_executor) { nil }
30
- unless executor && Puppet.features.bolt?
30
+ inventory = Puppet.lookup(:bolt_inventory) { nil }
31
+ unless executor && inventory && Puppet.features.bolt?
31
32
  raise Puppet::ParseErrorWithIssue.from_issue_and_stack(
32
33
  Puppet::Pops::Issues::TASK_MISSING_BOLT, action: _('run a script')
33
34
  )
@@ -46,7 +47,9 @@ Puppet::Functions.create_function(:run_script, Puppet::Functions::InternalFuncti
46
47
  end
47
48
 
48
49
  # Ensure that that given targets are all Target instances)
49
- targets = [targets].flatten.map { |t| t.is_a?(String) ? Bolt::Target.from_uri(t) : t }
50
+ targets = inventory.get_targets(targets)
51
+
52
+ #
50
53
  r = if targets.empty?
51
54
  Bolt::ResultSet.new([])
52
55
  else
@@ -54,7 +54,8 @@ Puppet::Functions.create_function(:run_task) do
54
54
  end
55
55
 
56
56
  executor = Puppet.lookup(:bolt_executor) { nil }
57
- unless executor && Puppet.features.bolt?
57
+ inventory = Puppet.lookup(:bolt_inventory) { nil }
58
+ unless executor && inventory && Puppet.features.bolt?
58
59
  raise Puppet::ParseErrorWithIssue.from_issue_and_stack(
59
60
  Puppet::Pops::Issues::TASK_MISSING_BOLT, action: _('run a task')
60
61
  )
@@ -81,8 +82,7 @@ Puppet::Functions.create_function(:run_task) do
81
82
  end
82
83
 
83
84
  # Ensure that that given targets are all Target instances
84
- targets = [targets] unless targets.is_a?(Array)
85
- targets = targets.flatten.map { |t| t.is_a?(String) ? Bolt::Target.from_uri(t) : t }
85
+ targets = inventory.get_targets(targets)
86
86
  if targets.empty?
87
87
  Bolt::ResultSet.new([])
88
88
  else
@@ -5,11 +5,13 @@ Puppet::DataTypes.create_type('Error') do
5
5
  issue_code => Optional[Variant[String,Regexp,Type[Enum],Type[Pattern],Type[NotUndef],Type[Undef]]]
6
6
  },
7
7
  attributes => {
8
- message => String[1],
8
+ msg => String[1],
9
9
  kind => { type => Optional[String[1]], value => undef },
10
- issue_code => { type => Optional[String[1]], value => undef },
11
- partial_result => { type => Data, value => undef },
12
10
  details => { type => Optional[Hash[String[1],Data]], value => undef },
11
+ issue_code => { type => Optional[String[1]], value => undef },
12
+ },
13
+ functions => {
14
+ message => Callable[[], String[1]]
13
15
  }
14
16
  PUPPET
15
17
 
@@ -1,39 +1,37 @@
1
1
  class Puppet::DataTypes::Error
2
- attr_reader :message, :kind, :issue_code, :partial_result, :details
2
+ attr_reader :msg, :kind, :issue_code, :details
3
+ alias message msg
3
4
 
4
5
  def self.from_asserted_hash(hash)
5
- new(hash['message'], hash['kind'], hash['issue_code'], hash['partial_result'], hash['details'])
6
+ new(hash['msg'], hash['kind'], hash['details'], hash['issue_code'])
6
7
  end
7
8
 
8
9
  def _pcore_init_hash
9
- result = { 'message' => @message }
10
+ result = { 'msg' => @msg }
10
11
  result['kind'] = @kind unless @kind.nil?
11
- result['issue_code'] = @issue_code unless @issue_code.nil?
12
- result['partial_result'] = @partial_result unless @partial_result.nil?
13
12
  result['details'] = @details unless @details.nil?
13
+ result['issue_code'] = @issue_code unless @issue_code.nil?
14
14
  result
15
15
  end
16
16
 
17
- def initialize(message, kind = nil, issue_code = nil, partial_result = nil, details = nil)
18
- @message = message
17
+ def initialize(msg, kind = nil, details = nil, issue_code = nil)
18
+ @msg = msg
19
19
  @kind = kind
20
- @issue_code = issue_code
21
- @partial_result = partial_result
22
20
  @details = details
21
+ @issue_code = issue_code
23
22
  end
24
23
 
25
24
  def eql?(o)
26
25
  self.class.equal?(o.class) &&
27
- @message == o.message &&
26
+ @msg == o.msg &&
28
27
  @kind == o.kind &&
29
28
  @issue_code == o.issue_code &&
30
- @partial_result == o.partial_result &&
31
29
  @details == o.details
32
30
  end
33
31
  alias == eql?
34
32
 
35
33
  def hash
36
- @message.hash ^ @kind.hash ^ @issue_code.hash
34
+ @msg.hash ^ @kind.hash ^ @issue_code.hash
37
35
  end
38
36
 
39
37
  def to_s
@@ -10,20 +10,26 @@ module Puppet
10
10
  end
11
11
  end
12
12
 
13
- def self.default_digest_alg
14
- if Puppet::Util::Platform.fips_enabled?
15
- "sha256"
16
- else
17
- "md5"
18
- end
13
+ def self.default_digest_algorithm
14
+ Puppet::Util::Platform.fips_enabled? ? 'sha256' : 'md5'
19
15
  end
20
16
 
21
- def self.default_checksum_types
22
- if Puppet::Util::Platform.fips_enabled?
23
- ['sha256', 'sha384', 'sha512', 'sha224']
24
- else
25
- ['md5', 'sha256', 'sha384', 'sha512', 'sha224']
26
- end
17
+ def self.valid_digest_algorithms
18
+ Puppet::Util::Platform.fips_enabled? ?
19
+ %w[sha256 sha384 sha512 sha224] :
20
+ %w[md5 sha256 sha384 sha512 sha224]
21
+ end
22
+
23
+ def self.default_file_checksum_types
24
+ Puppet::Util::Platform.fips_enabled? ?
25
+ %w[sha256 sha384 sha512 sha224] :
26
+ %w[md5 sha256 sha384 sha512 sha224]
27
+ end
28
+
29
+ def self.valid_file_checksum_types
30
+ Puppet::Util::Platform.fips_enabled? ?
31
+ %w[sha256 sha256lite sha384 sha512 sha224 sha1 sha1lite mtime ctime] :
32
+ %w[md5 md5lite sha256 sha256lite sha384 sha512 sha224 sha1 sha1lite mtime ctime]
27
33
  end
28
34
 
29
35
  ############################################################################################
@@ -939,26 +945,28 @@ attempt to download the CRL.
939
945
  EOT
940
946
  },
941
947
  :digest_algorithm => {
942
- :default => lambda { default_digest_alg },
948
+ :default => lambda { default_digest_algorithm },
943
949
  :type => :enum,
944
- :values => ["md5", "sha256", "sha384", "sha512", "sha224"],
945
- :desc => 'Which digest algorithm to use for file resources and the filebucket.
946
- Valid values are md5, sha256, sha384, sha512, sha224. Default is md5.',
950
+ :values => valid_digest_algorithms,
951
+ :desc => "Which digest algorithm to use for file resources and the filebucket.
952
+ Valid values are #{valid_digest_algorithms.join(', ')}. Default is
953
+ #{default_digest_algorithm}.",
947
954
  },
948
955
  :supported_checksum_types => {
949
- :default => lambda { default_checksum_types },
956
+ :default => lambda { default_file_checksum_types },
950
957
  :type => :array,
951
- :desc => 'Checksum types supported by this agent for use in file resources of a
952
- static catalog. Values must be comma-separated. Valid types are md5,
953
- md5lite, sha256, sha256lite, sha384, sha512,
954
- sha1, sha1lite, sha224, mtime, ctime.',
958
+ :desc => "Checksum types supported by this agent for use in file resources of a
959
+ static catalog. Values must be comma-separated. Valid types are
960
+ #{valid_file_checksum_types.join(', ')}. Default is
961
+ #{default_file_checksum_types.join(', ')}.",
955
962
  :hook => proc do |value|
956
963
  values = munge(value)
957
- valid = ['md5', 'md5lite', 'sha256', 'sha256lite', 'sha384', 'sha512', 'sha224', 'sha1', 'sha1lite', 'mtime', 'ctime']
958
- invalid = values.reject {|alg| valid.include?(alg)}
964
+
965
+ invalid = values - Puppet.valid_file_checksum_types
959
966
  if not invalid.empty?
960
- raise ArgumentError, _("Unrecognized checksum types %{invalid} are not supported.") % { invalid: invalid } +
961
- ' ' + _("Valid values are %{values}.") % { values: valid }
967
+ raise ArgumentError, _("Invalid value '%{value}' for parameter %{name}. Allowed values are '%{allowed_values}'") % {
968
+ value: invalid.first, name: @name, allowed_values: Puppet.valid_file_checksum_types.join("', '")
969
+ }
962
970
  end
963
971
  end
964
972
  }
@@ -109,7 +109,7 @@ module Puppet::Etc
109
109
  # Defines Puppet::Etc::Passwd struct class. Contains all of the original
110
110
  # member fields of Etc::Passwd, and additional "canonical_" versions of
111
111
  # these fields as well. API compatible with Etc::Passwd. Because Struct.new
112
- # defines a new Class object, we memozie to avoid superfluous extra Class
112
+ # defines a new Class object, we memoize to avoid superfluous extra Class
113
113
  # instantiations.
114
114
  def puppet_etc_passwd_class
115
115
  @password_class ||= Struct.new(*Etc::Passwd.members, *Etc::Passwd.members.map { |member| "canonical_#{member}".to_sym })
@@ -133,7 +133,7 @@ module Puppet::Etc
133
133
  # @api private
134
134
  # @param [Etc::Passwd or Etc::Group struct]
135
135
  # @return [Puppet::Etc::Passwd or Puppet::Etc::Group struct] a new struct
136
- # object with the original struct values overidden to UTF-8, if valid. For
136
+ # object with the original struct values overridden to UTF-8, if valid. For
137
137
  # invalid values originating in UTF-8, invalid characters are replaced with
138
138
  # '?'. For each member the struct also contains a corresponding
139
139
  # :canonical_<member name> struct member.
@@ -341,7 +341,7 @@ module PSON
341
341
  '"' << PSON.utf8_to_pson(self) << '"'
342
342
  end
343
343
 
344
- # Module that holds the extinding methods if, the String module is
344
+ # Module that holds the extending methods if, the String module is
345
345
  # included.
346
346
  module Extend
347
347
  # Raw Strings are PSON Objects (the raw bytes are stored in an array for the
@@ -44,7 +44,7 @@ module PSON
44
44
  /(?=\*/) # single slash before this comment's end
45
45
  )*
46
46
  \*/ # the End of this comment
47
- |[ \t\r\n]+ # whitespaces: space, horicontal tab, lf, cr
47
+ |[ \t\r\n]+ # whitespaces: space, horizontal tab, lf, cr
48
48
  )+
49
49
  )mx
50
50
 
@@ -129,4 +129,49 @@ https://puppet.com/docs/puppet/latest/configuration.html#environment
129
129
  nil
130
130
  end
131
131
  end
132
+
133
+ action(:delete) do
134
+ summary _("Delete a Puppet setting.")
135
+ arguments _("(<setting>")
136
+ #TRANSLATORS 'main' is a specific section name and should not be translated
137
+ description "Deletes a setting from the specified section. (The default is the section 'main')."
138
+ notes <<-'EOT'
139
+ By default, this action deletes the configuration setting from the 'main'
140
+ configuration domain. Use the '--section' flags to delete settings from other
141
+ configuration domains.
142
+ EOT
143
+ examples <<-'EOT'
144
+ Delete the setting 'setting_name' from the 'main' configuration domain:
145
+
146
+ $ puppet config delete setting_name
147
+
148
+ Delete the setting 'setting_name' from the 'master' configuration domain:
149
+
150
+ $ puppet config delete setting_name --section master
151
+ EOT
152
+
153
+ when_invoked do |name, options|
154
+ options[:section] = options[:section].to_s # If value was left as default - set to default string
155
+
156
+ path = Puppet::FileSystem.pathname(Puppet.settings.which_configuration_file)
157
+ if Puppet::FileSystem.exist?(path)
158
+ Puppet::FileSystem.open(path, nil, 'r+:UTF-8') do |file|
159
+ Puppet::Settings::IniFile.update(file) do |config|
160
+ setting_string = config.delete(options[:section], name)
161
+ if setting_string
162
+ puts(_("Deleted setting from '%{section_name}': '%{setting_string}'") %
163
+ { section_name: options[:section], name: name, setting_string: setting_string.strip })
164
+ else
165
+ Puppet.warning(_("No setting found in configuration file for section '%{section_name}' setting name '%{name}'") %
166
+ { section_name: options[:section], name: name })
167
+ end
168
+ end
169
+ end
170
+ else
171
+ #TRANSLATORS the 'puppet.conf' is a specific file and should not be translated
172
+ Puppet.warning(_("The puppet.conf file does not exist %{puppet_conf}") % { puppet_conf: path })
173
+ end
174
+ nil
175
+ end
176
+ end
132
177
  end