puppet-debugger 0.19.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (82) hide show
  1. checksums.yaml +4 -4
  2. data/.gitlab-ci.yml +10 -27
  3. data/.rubocop.yml +64 -232
  4. data/.rubocop_todo.yml +89 -147
  5. data/CHANGELOG.md +12 -1
  6. data/Gemfile +7 -5
  7. data/README.md +4 -5
  8. data/Rakefile +11 -12
  9. data/bin/pdb +1 -1
  10. data/lib/awesome_print/ext/awesome_puppet.rb +10 -8
  11. data/lib/plugins/puppet-debugger/input_responders/benchmark.rb +5 -4
  12. data/lib/plugins/puppet-debugger/input_responders/classes.rb +4 -1
  13. data/lib/plugins/puppet-debugger/input_responders/classification.rb +4 -2
  14. data/lib/plugins/puppet-debugger/input_responders/commands.rb +18 -18
  15. data/lib/plugins/puppet-debugger/input_responders/datatypes.rb +11 -5
  16. data/lib/plugins/puppet-debugger/input_responders/environment.rb +4 -2
  17. data/lib/plugins/puppet-debugger/input_responders/exit.rb +4 -2
  18. data/lib/plugins/puppet-debugger/input_responders/facterdb_filter.rb +4 -2
  19. data/lib/plugins/puppet-debugger/input_responders/facts.rb +4 -2
  20. data/lib/plugins/puppet-debugger/input_responders/functions.rb +34 -32
  21. data/lib/plugins/puppet-debugger/input_responders/help.rb +4 -2
  22. data/lib/plugins/puppet-debugger/input_responders/krt.rb +4 -2
  23. data/lib/plugins/puppet-debugger/input_responders/play.rb +22 -24
  24. data/lib/plugins/puppet-debugger/input_responders/reset.rb +5 -3
  25. data/lib/plugins/puppet-debugger/input_responders/resources.rb +5 -2
  26. data/lib/plugins/puppet-debugger/input_responders/set.rb +34 -32
  27. data/lib/plugins/puppet-debugger/input_responders/stacktrace.rb +23 -0
  28. data/lib/plugins/puppet-debugger/input_responders/types.rb +6 -2
  29. data/lib/plugins/puppet-debugger/input_responders/vars.rb +6 -5
  30. data/lib/plugins/puppet-debugger/input_responders/whereami.rb +5 -3
  31. data/lib/puppet-debugger/cli.rb +118 -91
  32. data/lib/puppet-debugger/code/code_file.rb +13 -14
  33. data/lib/puppet-debugger/code/code_range.rb +5 -3
  34. data/lib/puppet-debugger/code/loc.rb +1 -1
  35. data/lib/puppet-debugger/debugger_code.rb +2 -0
  36. data/lib/puppet-debugger/hooks.rb +15 -16
  37. data/lib/puppet-debugger/input_responder_plugin.rb +54 -52
  38. data/lib/puppet-debugger/monkey_patches.rb +4 -1
  39. data/lib/puppet-debugger/plugin_test_helper.rb +9 -8
  40. data/lib/puppet-debugger/support.rb +27 -17
  41. data/lib/puppet-debugger/support/environment.rb +4 -4
  42. data/lib/puppet-debugger/support/errors.rb +25 -27
  43. data/lib/puppet-debugger/support/facts.rb +5 -5
  44. data/lib/puppet-debugger/support/node.rb +4 -5
  45. data/lib/puppet-debugger/support/scope.rb +19 -17
  46. data/lib/puppet-debugger/trollop.rb +38 -31
  47. data/lib/puppet-debugger/version.rb +1 -1
  48. data/lib/puppet/application/debugger.rb +141 -135
  49. data/output.json +1 -0
  50. data/puppet-debugger.gemspec +17 -16
  51. data/spec/awesome_print/ext/awesome_puppet_spec.rb +30 -30
  52. data/spec/fixtures/sample_start_debugger.pp +3 -2
  53. data/spec/hooks_spec.rb +33 -35
  54. data/spec/input_responder_plugin_spec.rb +7 -6
  55. data/spec/input_responders/benchmark_spec.rb +3 -1
  56. data/spec/input_responders/classes_spec.rb +12 -10
  57. data/spec/input_responders/classification_spec.rb +4 -2
  58. data/spec/input_responders/commands_spec.rb +2 -0
  59. data/spec/input_responders/datatypes_spec.rb +4 -3
  60. data/spec/input_responders/environment_spec.rb +2 -0
  61. data/spec/input_responders/exit_spec.rb +9 -11
  62. data/spec/input_responders/facterdb_filter_spec.rb +2 -0
  63. data/spec/input_responders/facts_spec.rb +2 -0
  64. data/spec/input_responders/functions_spec.rb +30 -28
  65. data/spec/input_responders/help_spec.rb +4 -2
  66. data/spec/input_responders/krt_spec.rb +3 -1
  67. data/spec/input_responders/play_spec.rb +10 -20
  68. data/spec/input_responders/reset_spec.rb +2 -0
  69. data/spec/input_responders/resources_spec.rb +3 -1
  70. data/spec/input_responders/set_spec.rb +3 -1
  71. data/spec/input_responders/stacktrace_spec.rb +15 -0
  72. data/spec/input_responders/types_spec.rb +2 -0
  73. data/spec/input_responders/vars_spec.rb +4 -4
  74. data/spec/input_responders/whereami_spec.rb +2 -0
  75. data/spec/pdb_spec.rb +0 -9
  76. data/spec/puppet/application/debugger_spec.rb +18 -19
  77. data/spec/puppet_debugger_spec.rb +81 -84
  78. data/spec/remote_node_spec.rb +1 -5
  79. data/spec/spec_helper.rb +22 -18
  80. data/spec/support_spec.rb +3 -5
  81. data/test_matrix.rb +1 -1
  82. metadata +48 -31
@@ -9,8 +9,6 @@ module PuppetDebugger
9
9
  end
10
10
  end
11
11
 
12
-
13
-
14
12
  class FatalError < Error
15
13
  end
16
14
 
@@ -22,9 +20,9 @@ module PuppetDebugger
22
20
 
23
21
  class ConnectError < Error
24
22
  def message
25
- out = <<-EOF
26
- #{data[:message]}
27
- EOF
23
+ <<~OUT
24
+ #{data[:message]}
25
+ OUT
28
26
  end
29
27
  end
30
28
 
@@ -36,9 +34,9 @@ EOF
36
34
 
37
35
  class UndefinedNode < FatalError
38
36
  def message
39
- out = <<-EOF
40
- Cannot find node with name: #{data[:name]} on remote server
41
- EOF
37
+ <<~OUT
38
+ Cannot find node with name: #{data[:name]} on remote server
39
+ OUT
42
40
  end
43
41
  end
44
42
 
@@ -48,36 +46,36 @@ Cannot find node with name: #{data[:name]} on remote server
48
46
 
49
47
  class NoClassError < FatalError
50
48
  def message
51
- out = <<-EOF
52
- #{data[:message]}
53
- You are missing puppet classes that are required for compilation.
54
- Please ensure these classes are installed on this machine in any of the following paths:
55
- #{data[:default_modules_paths]}
56
- EOF
49
+ <<~OUT
50
+ #{data[:message]}
51
+ You are missing puppet classes that are required for compilation.
52
+ Please ensure these classes are installed on this machine in any of the following paths:
53
+ #{data[:default_modules_paths]}
54
+ OUT
57
55
  end
58
56
  end
59
57
 
60
58
  class NodeDefinitionError < FatalError
61
59
  def message
62
- out = <<-EOF
63
- You are missing a default node definition in your site.pp that is required for compilation.
64
- Please ensure you have at least the following default node definition
65
- node default {
66
- # include classes here
67
- }
68
- in your #{data[:default_site_manifest]} file.
69
- EOF
60
+ out = <<~OUT
61
+ You are missing a default node definition in your site.pp that is required for compilation.
62
+ Please ensure you have at least the following default node definition
63
+ node default {
64
+ # include classes here
65
+ }
66
+ in your #{data[:default_site_manifest]} file.
67
+ OUT
70
68
  out.fatal
71
69
  end
72
70
  end
73
71
 
74
72
  class AuthError < FatalError
75
73
  def message
76
- out = <<-EOF
77
- #{data[:message]}
78
- You will need to edit your auth.conf or conf.d/auth.conf (puppetserver) to allow node calls.
79
- EOF
80
- end
74
+ <<~OUT
75
+ #{data[:message]}
76
+ You will need to edit your auth.conf or conf.d/auth.conf (puppetserver) to allow node calls.
77
+ OUT
78
+ end
81
79
  end
82
80
  end
83
81
  end
@@ -46,11 +46,11 @@ module PuppetDebugger
46
46
  def node_facts
47
47
  node_facts = FacterDB.get_facts(dynamic_facterdb_filter).first
48
48
  if node_facts.nil?
49
- message = <<-EOS
50
- Using filter: #{dynamic_facterdb_filter}
51
- Bad FacterDB filter, please change the filter so it returns a result set.
52
- See https://github.com/camptocamp/facterdb/#with-a-string-filter
53
- EOS
49
+ message = <<~OUT
50
+ Using filter: #{dynamic_facterdb_filter}
51
+ Bad FacterDB filter, please change the filter so it returns a result set.
52
+ See https://github.com/camptocamp/facterdb/#with-a-string-filter
53
+ OUT
54
54
  raise PuppetDebugger::Exception::BadFilter, message: message
55
55
  end
56
56
  # fix for when --show-legacy facts are not part of the facter 3 fact set
@@ -32,6 +32,7 @@ module PuppetDebugger
32
32
  # Collect our facts.
33
33
  facts = Puppet::Node::Facts.indirection.find(Puppet[:node_name_value])
34
34
  raise "Could not find facts for #{Puppet[:node_name_value]}" unless facts
35
+
35
36
  Puppet[:node_name_value] = facts.values[Puppet[:node_name_fact]]
36
37
  facts.name = Puppet[:node_name_value]
37
38
  end
@@ -39,6 +40,7 @@ module PuppetDebugger
39
40
  # Find our Node
40
41
  node = Puppet::Node.indirection.find(Puppet[:node_name_value])
41
42
  raise "Could not find node #{Puppet[:node_name_value]}" unless node
43
+
42
44
  # Merge in the facts.
43
45
  node.merge(facts.values) if facts
44
46
  end
@@ -91,11 +93,8 @@ module PuppetDebugger
91
93
  def set_node_from_name(name)
92
94
  out_buffer.puts "Fetching node #{name}"
93
95
  remote_node = get_remote_node(name)
94
- if remote_node && remote_node.parameters.empty?
95
- remote_node_name = nil # clear out the remote name
96
- raise PuppetDebugger::Exception::UndefinedNode, name: remote_node.name
97
- end
98
- remote_node_name = remote_node.name
96
+ raise PuppetDebugger::Exception::UndefinedNode, name: remote_node.name if remote_node&.parameters&.empty?
97
+
99
98
  node_object = convert_remote_node(remote_node)
100
99
  set_node(node_object)
101
100
  end
@@ -12,27 +12,29 @@ module PuppetDebugger
12
12
  @catalog || scope.compiler.catalog
13
13
  end
14
14
 
15
- def get_catalog_text(c)
16
- return nil unless c
17
- Puppet::FileSystem.read(c, :encoding => 'utf-8')
15
+ def get_catalog_text(catalog)
16
+ return nil unless catalog
17
+
18
+ Puppet::FileSystem.read(catalog, encoding: 'utf-8')
18
19
  end
19
20
 
20
21
  def set_catalog(catalog_file)
21
- return unless catalog_file
22
- catalog_text = get_catalog_text(catalog_file)
23
- scope # required
24
- Puppet.override({:current_environment => environment}, _("For puppet debugger")) do
25
- format = Puppet::Resource::Catalog.default_format
26
- begin
27
- c = Puppet::Resource::Catalog.convert_from(format, catalog_text)
28
- rescue => detail
29
- raise Puppet::Error, _("Could not deserialize catalog from %{format}: %{detail}") % { format: format, detail: detail }, detail.backtrace
30
- end
31
- # Resolve all deferred values and replace them / mutate the catalog
32
- # Puppet 6 only
33
- Puppet::Pops::Evaluator::DeferredResolver.resolve_and_replace(node.facts, c) if Gem::Version.new(Puppet.version) >= Gem::Version.new('6.0.0')
34
- @catalog = c
22
+ return unless catalog_file
23
+
24
+ catalog_text = get_catalog_text(catalog_file)
25
+ scope # required
26
+ Puppet.override({ current_environment: environment }, _('For puppet debugger')) do
27
+ format = Puppet::Resource::Catalog.default_format
28
+ begin
29
+ c = Puppet::Resource::Catalog.convert_from(format, catalog_text)
30
+ rescue StandardError => e
31
+ raise Puppet::Error, format(_('Could not deserialize catalog from %{format}: %{detail}'), format: format, detail: e), e.backtrace
35
32
  end
33
+ # Resolve all deferred values and replace them / mutate the catalog
34
+ # Puppet 6 only
35
+ Puppet::Pops::Evaluator::DeferredResolver.resolve_and_replace(node.facts, c) if Gem::Version.new(Puppet.version) >= Gem::Version.new('6.0.0')
36
+ @catalog = c
37
+ end
36
38
  end
37
39
 
38
40
  # @return [Puppet::Pops::Scope] - returns a puppet scope object
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  # lib/trollop.rb -- trollop command-line processing library
3
4
  # Copyright (c) 2008-2014 William Morgan.
4
5
  # Copyright (c) 2014 Red Hat, Inc.
@@ -33,10 +34,10 @@ module Trollop
33
34
  end
34
35
 
35
36
  ## Regex for floating point numbers
36
- FLOAT_RE = /^-?((\d+(\.\d+)?)|(\.\d+))([eE][-+]?[\d]+)?$/
37
+ FLOAT_RE = /^-?((\d+(\.\d+)?)|(\.\d+))([eE][-+]?[\d]+)?$/.freeze
37
38
 
38
39
  ## Regex for parameters
39
- PARAM_RE = /^-(-|\.$|[^\d\.])/
40
+ PARAM_RE = /^-(-|\.$|[^\d\.])/.freeze
40
41
 
41
42
  ## The commandline parser. In typical usage, the methods in this class
42
43
  ## will be handled internally by Trollop::options. In this case, only the
@@ -50,24 +51,24 @@ module Trollop
50
51
  class Parser
51
52
  ## The set of values that indicate a flag option when passed as the
52
53
  ## +:type+ parameter of #opt.
53
- FLAG_TYPES = [:flag, :bool, :boolean].freeze
54
+ FLAG_TYPES = %i[flag bool boolean].freeze
54
55
 
55
56
  ## The set of values that indicate a single-parameter (normal) option when
56
57
  ## passed as the +:type+ parameter of #opt.
57
58
  ##
58
59
  ## A value of +io+ corresponds to a readable IO resource, including
59
60
  ## a filename, URI, or the strings 'stdin' or '-'.
60
- SINGLE_ARG_TYPES = [:int, :integer, :string, :double, :float, :io, :date].freeze
61
+ SINGLE_ARG_TYPES = %i[int integer string double float io date].freeze
61
62
 
62
63
  ## The set of values that indicate a multiple-parameter option (i.e., that
63
64
  ## takes multiple space-separated values on the commandline) when passed as
64
65
  ## the +:type+ parameter of #opt.
65
- MULTI_ARG_TYPES = [:ints, :integers, :strings, :doubles, :floats, :ios, :dates].freeze
66
+ MULTI_ARG_TYPES = %i[ints integers strings doubles floats ios dates].freeze
66
67
 
67
68
  ## The complete set of legal values for the +:type+ parameter of #opt.
68
69
  TYPES = FLAG_TYPES + SINGLE_ARG_TYPES + MULTI_ARG_TYPES
69
70
 
70
- INVALID_SHORT_ARG_REGEX = /[\d-]/ #:nodoc:
71
+ INVALID_SHORT_ARG_REGEX = /[\d-]/.freeze #:nodoc:
71
72
 
72
73
  ## The values from the commandline that were not interpreted by #parse.
73
74
  attr_reader :leftovers
@@ -151,8 +152,7 @@ module Trollop
151
152
  when :doubles then :floats
152
153
  when Class
153
154
  case opts[:type].name
154
- when 'TrueClass',
155
- 'FalseClass' then :flag
155
+ when 'TrueClass', 'FalseClass' then :flag
156
156
  when 'String' then :string
157
157
  when 'Integer' then :int
158
158
  when 'Float' then :float
@@ -164,6 +164,7 @@ module Trollop
164
164
  when nil then nil
165
165
  else
166
166
  raise ArgumentError, "unsupported argument type '#{opts[:type]}'" unless TYPES.include?(opts[:type])
167
+
167
168
  opts[:type]
168
169
  end
169
170
 
@@ -175,14 +176,13 @@ module Trollop
175
176
  opts[:default].first
176
177
  else
177
178
  opts[:default]
178
- end
179
+ end
179
180
 
180
181
  type_from_default =
181
182
  case disambiguated_default
182
183
  when Integer then :int
183
184
  when Numeric then :float
184
- when TrueClass,
185
- FalseClass then :flag
185
+ when TrueClass, FalseClass then :flag
186
186
  when String then :string
187
187
  when IO then :io
188
188
  when Date then :date
@@ -190,6 +190,7 @@ module Trollop
190
190
  if opts[:default].empty?
191
191
  if opts[:type]
192
192
  raise ArgumentError, 'multiple argument type must be plural' unless MULTI_ARG_TYPES.include?(opts[:type])
193
+
193
194
  nil
194
195
  else
195
196
  raise ArgumentError, "multiple argument type cannot be deduced from an empty array for '#{opts[:default][0].class.name}'"
@@ -220,7 +221,7 @@ module Trollop
220
221
  when /^--([^-].*)$/ then Regexp.last_match(1)
221
222
  when /^[^-]/ then opts[:long]
222
223
  else raise ArgumentError, "invalid long option name #{opts[:long].inspect}"
223
- end
224
+ end
224
225
  raise ArgumentError, "long option name #{opts[:long].inspect} is already taken; please specify a (different) :long" if @long[opts[:long]]
225
226
 
226
227
  ## fill in :short
@@ -229,7 +230,7 @@ module Trollop
229
230
  when /^-(.)$/ then Regexp.last_match(1)
230
231
  when nil, :none, /^.$/ then opts[:short]
231
232
  else raise ArgumentError, "invalid short option name '#{opts[:short].inspect}'"
232
- end
233
+ end
233
234
 
234
235
  if opts[:short]
235
236
  raise ArgumentError, "short option name #{opts[:short].inspect} is already taken; please specify a (different) :short" if @short[opts[:short]]
@@ -255,21 +256,21 @@ module Trollop
255
256
  ## Sets the version string. If set, the user can request the version
256
257
  ## on the commandline. Should probably be of the form "<program name>
257
258
  ## <version number>".
258
- def version(s = nil)
259
- s ? @version = s : @version
259
+ def version(value = nil)
260
+ value ? @version = value : @version
260
261
  end
261
262
 
262
263
  ## Sets the usage string. If set the message will be printed as the
263
264
  ## first line in the help (educate) output and ending in two new
264
265
  ## lines.
265
- def usage(s = nil)
266
- s ? @usage = s : @usage
266
+ def usage(value = nil)
267
+ value ? @usage = value : @usage
267
268
  end
268
269
 
269
270
  ## Adds a synopsis (command summary description) right below the
270
271
  ## usage line, or as the first line if usage isn't specified.
271
- def synopsis(s = nil)
272
- s ? @synopsis = s : @synopsis
272
+ def synopsis(value = nil)
273
+ value ? @synopsis = value : @synopsis
273
274
  end
274
275
 
275
276
  ## Adds text to the help display. Can be interspersed with calls to
@@ -347,22 +348,20 @@ module Trollop
347
348
  ["--#{Regexp.last_match(1)}", true]
348
349
  else
349
350
  [arg, false]
350
- end
351
+ end
351
352
 
352
353
  sym = case arg
353
354
  when /^-([^-])$/ then @short[Regexp.last_match(1)]
354
355
  when /^--([^-]\S*)$/ then @long[Regexp.last_match(1)] || @long["no-#{Regexp.last_match(1)}"]
355
356
  else raise CommandlineError, "invalid argument syntax: '#{arg}'"
356
- end
357
+ end
357
358
 
358
359
  sym = nil if arg =~ /--no-/ # explicitly invalidate --no-no- arguments
359
360
 
360
361
  next 0 if ignore_invalid_options && !sym
361
362
  raise CommandlineError, "unknown argument '#{arg}'" unless sym
362
363
 
363
- if given_args.include?(sym) && !@specs[sym][:multi]
364
- raise CommandlineError, "option '#{arg}' specified multiple times"
365
- end
364
+ raise CommandlineError, "option '#{arg}' specified multiple times" if given_args.include?(sym) && !@specs[sym][:multi]
366
365
 
367
366
  given_args[sym] ||= {}
368
367
  given_args[sym][:arg] = arg
@@ -396,9 +395,13 @@ module Trollop
396
395
 
397
396
  case type
398
397
  when :depends
399
- syms.each { |sym| raise CommandlineError, "--#{@specs[constraint_sym][:long]} requires --#{@specs[sym][:long]}" unless given_args.include? sym }
398
+ syms.each do |sym|
399
+ raise CommandlineError, "--#{@specs[constraint_sym][:long]} requires --#{@specs[sym][:long]}" unless given_args.include? sym
400
+ end
400
401
  when :conflicts
401
- syms.each { |sym| raise CommandlineError, "--#{@specs[constraint_sym][:long]} conflicts with --#{@specs[sym][:long]}" if given_args.include?(sym) && (sym != constraint_sym) }
402
+ syms.each do |sym|
403
+ raise CommandlineError, "--#{@specs[constraint_sym][:long]} conflicts with --#{@specs[sym][:long]}" if given_args.include?(sym) && (sym != constraint_sym)
404
+ end
402
405
  end
403
406
  end
404
407
 
@@ -413,6 +416,7 @@ module Trollop
413
416
  opts = @specs[sym]
414
417
  if params.empty? && opts[:type] != :flag
415
418
  raise CommandlineError, "option '#{arg}' needs a parameter" unless opts[:default]
419
+
416
420
  params << (opts[:default].is_a?(Array) ? opts[:default].clone : [opts[:default]])
417
421
  end
418
422
 
@@ -527,7 +531,7 @@ module Trollop
527
531
  spec[:default].join(', ')
528
532
  else
529
533
  spec[:default].to_s
530
- end
534
+ end
531
535
 
532
536
  if spec[:default]
533
537
  if spec[:desc] =~ /\.$/
@@ -553,7 +557,7 @@ module Trollop
553
557
  end
554
558
  else
555
559
  80
556
- end
560
+ end
557
561
  end
558
562
 
559
563
  def legacy_width
@@ -580,15 +584,15 @@ module Trollop
580
584
  ## The per-parser version of Trollop::die (see that for documentation).
581
585
  def die(arg, msg = nil, error_code = nil)
582
586
  if msg
583
- $stderr.puts "Error: argument --#{@specs[arg][:long]} #{msg}."
587
+ warn "Error: argument --#{@specs[arg][:long]} #{msg}."
584
588
  else
585
- $stderr.puts "Error: #{arg}."
589
+ warn "Error: #{arg}."
586
590
  end
587
591
  if @educate_on_error
588
592
  $stderr.puts
589
593
  educate $stderr
590
594
  else
591
- $stderr.puts 'Try --help for help.'
595
+ warn 'Try --help for help.'
592
596
  end
593
597
  exit(error_code || -1)
594
598
  end
@@ -602,6 +606,7 @@ module Trollop
602
606
 
603
607
  until i >= args.length
604
608
  return remains += args[i..-1] if @stop_words.member? args[i]
609
+
605
610
  case args[i]
606
611
  when /^--$/ # arg terminator
607
612
  return remains += args[(i + 1)..-1]
@@ -662,11 +667,13 @@ module Trollop
662
667
 
663
668
  def parse_integer_parameter(param, arg)
664
669
  raise CommandlineError, "option '#{arg}' needs an integer" unless param =~ /^-?[\d_]+$/
670
+
665
671
  param.to_i
666
672
  end
667
673
 
668
674
  def parse_float_parameter(param, arg)
669
675
  raise CommandlineError, "option '#{arg}' needs a floating-point number" unless param =~ FLOAT_RE
676
+
670
677
  param.to_f
671
678
  end
672
679
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module PuppetDebugger
4
- VERSION = "0.19.0"
4
+ VERSION = '1.0.0'
5
5
  end
@@ -1,185 +1,185 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "puppet/application"
4
- require "optparse"
5
- require "puppet/util/command_line"
3
+ require 'puppet/application'
4
+ require 'optparse'
5
+ require 'puppet/util/command_line'
6
6
 
7
7
  class Puppet::Application::Debugger < Puppet::Application
8
8
  attr_reader :use_stdin
9
9
 
10
- option("--execute EXECUTE", "-e") do |arg|
10
+ option('--execute EXECUTE', '-e') do |arg|
11
11
  options[:code] = arg
12
12
  end
13
13
 
14
- option("--facterdb-filter FILTER") do |arg|
14
+ option('--facterdb-filter FILTER') do |arg|
15
15
  options[:use_facterdb] = true unless options[:node_name]
16
- ENV["DEBUGGER_FACTERDB_FILTER"] = arg if arg
16
+ ENV['DEBUGGER_FACTERDB_FILTER'] = arg if arg
17
17
  end
18
18
 
19
- option("--test") do |_arg|
19
+ option('--test') do |_arg|
20
20
  options[:quiet] = true
21
21
  options[:run_once] = true
22
22
  @use_stdin = true
23
23
  end
24
24
 
25
- option("--no-facterdb") { |_arg| options[:use_facterdb] = false }
25
+ option('--no-facterdb') { |_arg| options[:use_facterdb] = false }
26
26
 
27
- option("--log-level LEVEL", "-l") do |arg|
27
+ option('--log-level LEVEL', '-l') do |arg|
28
28
  Puppet::Util::Log.level = arg.to_sym
29
29
  end
30
30
 
31
- option("--catalog catalog", "-c catalog") do |arg|
31
+ option('--catalog catalog', '-c catalog') do |arg|
32
32
  options[:catalog] = arg
33
33
  end
34
34
 
35
- option("--quiet", "-q") { |_arg| options[:quiet] = true }
35
+ option('--quiet', '-q') { |_arg| options[:quiet] = true }
36
36
 
37
- option("--play URL", "-p") do |arg|
37
+ option('--play URL', '-p') do |arg|
38
38
  options[:play] = arg
39
39
  end
40
40
 
41
- option("--stdin", "-s") { |_arg| @use_stdin = true }
41
+ option('--stdin', '-s') { |_arg| @use_stdin = true }
42
42
 
43
- option("--run-once", "-r") { |_arg| options[:run_once] = true }
43
+ option('--run-once', '-r') { |_arg| options[:run_once] = true }
44
44
 
45
- option("--node-name CERTNAME", "-n") do |arg|
45
+ option('--node-name CERTNAME', '-n') do |arg|
46
46
  options[:use_facterdb] = false
47
47
  options[:node_name] = arg
48
48
  end
49
49
 
50
50
  def help
51
- <<-HELP
51
+ <<~HELP
52
52
 
53
- puppet-debugger(8) -- Starts a debugger session using the puppet-debugger tool
54
- ========
53
+ puppet-debugger(8) -- Starts a debugger session using the puppet-debugger tool
54
+ ========
55
55
 
56
- SYNOPSIS
57
- --------
58
- A interactive command line tool for evaluating the puppet language and debugging
59
- puppet code.
56
+ SYNOPSIS
57
+ --------
58
+ A interactive command line tool for evaluating the puppet language and debugging
59
+ puppet code.
60
60
 
61
- USAGE
62
- -----
63
- puppet debugger [--help] [--version] [-e|--execute CODE] [--facterdb-filter FILTER]
64
- [--test] [--no-facterdb] [-q|--quiet] [-p|--play URL] [-s|--stdin]
65
- [-r|--run-once] [-n|--node-name CERTNAME]
61
+ USAGE
62
+ -----
63
+ puppet debugger [--help] [--version] [-e|--execute CODE] [--facterdb-filter FILTER]
64
+ [--test] [--no-facterdb] [-q|--quiet] [-p|--play URL] [-s|--stdin]
65
+ [-r|--run-once] [-n|--node-name CERTNAME]
66
66
 
67
67
 
68
- DESCRIPTION
69
- -----------
70
- A interactive command line tool for evaluating the puppet language and debugging
71
- puppet code.
72
-
73
- USAGE WITH DEBUG MODULE
74
- -----------------------
75
- Use the puppet debugger in conjunction with the debug::break() puppet function
76
- to pry into your code during compilation. Get immediate insight in how the puppet4
77
- languge works during the execution of your code.
68
+ DESCRIPTION
69
+ -----------
70
+ A interactive command line tool for evaluating the puppet language and debugging
71
+ puppet code.
72
+
73
+ USAGE WITH DEBUG MODULE
74
+ -----------------------
75
+ Use the puppet debugger in conjunction with the debug::break() puppet function
76
+ to pry into your code during compilation. Get immediate insight in how the puppet4
77
+ languge works during the execution of your code.
78
78
 
79
- To use the break function install the module via: puppet module install nwops/debug
79
+ To use the break function install the module via: puppet module install nwops/debug
80
80
 
81
- Now place the debug::break() function anywhere in your code to
81
+ Now place the debug::break() function anywhere in your code to
82
82
 
83
- Example:
84
- puppet debugger -e '$abs_vars = [-11,-22,-33].map | Integer $num | { debug::break() ; notice($num) }'
83
+ Example:
84
+ puppet debugger -e '$abs_vars = [-11,-22,-33].map | Integer $num | { debug::break() ; notice($num) }'
85
85
 
86
- See: https://github.com/nwops/puppet-debug
87
- OPTIONS
88
- -------
89
- Note that any setting that's valid in the configuration
90
- file is also a valid long argument. For example, 'server' is a valid
91
- setting, so you can specify '--server <servername>' as
92
- an argument.
86
+ See: https://github.com/nwops/puppet-debug
87
+ OPTIONS
88
+ -------
89
+ Note that any setting that's valid in the configuration
90
+ file is also a valid long argument. For example, 'server' is a valid
91
+ setting, so you can specify '--server <servername>' as
92
+ an argument.
93
93
 
94
- See the configuration file documentation at
95
- http://docs.puppetlabs.com/references/stable/configuration.html for the
96
- full list of acceptable parameters. A commented list of all
97
- configuration options can also be generated by running puppet debugger with
98
- '--genconfig'.
94
+ See the configuration file documentation at
95
+ http://docs.puppetlabs.com/references/stable/configuration.html for the
96
+ full list of acceptable parameters. A commented list of all
97
+ configuration options can also be generated by running puppet debugger with
98
+ '--genconfig'.
99
99
 
100
- * --help:
101
- Print this help message
100
+ * --help:
101
+ Print this help message
102
102
 
103
- * --version:
104
- Print the puppet version number and exit.
103
+ * --version:
104
+ Print the puppet version number and exit.
105
105
 
106
- * --execute:
107
- Execute a specific piece of Puppet code
106
+ * --execute:
107
+ Execute a specific piece of Puppet code
108
108
 
109
- * --facterdb-filter
110
- Disables the usage of the current node level facts and uses cached facts
111
- from facterdb. Specifying a filter will override the default facterdb filter.
112
- Not specifiying a filter will use the default CentOS based filter.
113
- This will greatly speed up the start time of the debugger since
114
- you are using cached facts. Additionally, using facterdb also allows you
115
- to play with many other operating system facts that you might not have access
116
- to. For example filters please see the facterdb docs.
109
+ * --facterdb-filter
110
+ Disables the usage of the current node level facts and uses cached facts
111
+ from facterdb. Specifying a filter will override the default facterdb filter.
112
+ Not specifiying a filter will use the default CentOS based filter.
113
+ This will greatly speed up the start time of the debugger since
114
+ you are using cached facts. Additionally, using facterdb also allows you
115
+ to play with many other operating system facts that you might not have access
116
+ to. For example filters please see the facterdb docs.
117
117
 
118
- See https://github.com/camptocamp/facterdb for more info
118
+ See https://github.com/camptocamp/facterdb for more info
119
119
 
120
- * --no-facterdb
121
- Use the facts found on this node instead of cached facts from facterdb.
120
+ * --no-facterdb
121
+ Use the facts found on this node instead of cached facts from facterdb.
122
122
 
123
- * --log-level
124
- Set the Puppet log level which can be very useful with using the debugger.
123
+ * --log-level
124
+ Set the Puppet log level which can be very useful with using the debugger.
125
125
 
126
- * --quiet
127
- Do not display the debugger help script upon startup.
126
+ * --quiet
127
+ Do not display the debugger help script upon startup.
128
128
 
129
- * --play
130
- Plays back the code file supplied into the debugger. Can also supply
131
- any http based url.
129
+ * --play
130
+ Plays back the code file supplied into the debugger. Can also supply
131
+ any http based url.
132
132
 
133
- * --run-once
134
- Return the result from the debugger and exit
133
+ * --run-once
134
+ Return the result from the debugger and exit
135
135
 
136
- * --stdin
137
- Read from stdin instead of starting the debugger right away. Useful when piping code into the debugger.
136
+ * --stdin
137
+ Read from stdin instead of starting the debugger right away. Useful when piping code into the debugger.
138
138
 
139
- * --catalog:
140
- Import a JSON catalog (such as one generated with 'puppet master --compile'). You need to
141
- specify a valid JSON encoded catalog file. Gives you the ability
142
- to inspect the catalog and all the parameter values that make up the resources. Can
143
- specify a file or pipe to stdin with '-'.
139
+ * --catalog:
140
+ Import a JSON catalog (such as one generated with 'puppet master --compile'). You need to
141
+ specify a valid JSON encoded catalog file. Gives you the ability
142
+ to inspect the catalog and all the parameter values that make up the resources. Can
143
+ specify a file or pipe to stdin with '-'.
144
144
 
145
- * --node-name
146
- Retrieves the node information remotely via the puppet server given the node name.
147
- This is extremely useful when trying to debug classification issues, as this can show
148
- classes and parameters retrieved from the ENC. You can also play around with the real facts
149
- of the remote node as well.
145
+ * --node-name
146
+ Retrieves the node information remotely via the puppet server given the node name.
147
+ This is extremely useful when trying to debug classification issues, as this can show
148
+ classes and parameters retrieved from the ENC. You can also play around with the real facts
149
+ of the remote node as well.
150
150
 
151
- Note: this requires special permission in your puppet server's auth.conf file to allow
152
- access to make remote calls from this node: #{Puppet[:certname]}. If you are running
153
- the debugger from the puppet server as root you do not need any special setup.
151
+ Note: this requires special permission in your puppet server's auth.conf file to allow
152
+ access to make remote calls from this node: #{Puppet[:certname]}. If you are running
153
+ the debugger from the puppet server as root you do not need any special setup.
154
154
 
155
- You must also have a signed cert and be able to connect to the server from this system.
155
+ You must also have a signed cert and be able to connect to the server from this system.
156
156
 
157
- Mutually exclusive with --facterdb-filter
157
+ Mutually exclusive with --facterdb-filter
158
158
 
159
- * --test
160
- Runs the code in the debugger and exit without showing the help screen ( --quiet --run-once, --stdin)
159
+ * --test
160
+ Runs the code in the debugger and exit without showing the help screen ( --quiet --run-once, --stdin)
161
161
 
162
- EXAMPLE
163
- -------
164
- $ puppet debugger
165
- $ echo "notice('hello, can you hear me?')" | puppet debugger --test
166
- $ echo "notice('hello, can you hear me?')" | puppet debugger --stdin
167
- $ puppet debugger --execute "notice('hello')"
168
- $ puppet debugger --facterdb-filter 'facterversion=/^2.4\./ and operatingsystem=Debian'
169
- $ puppet debugger --play https://gist.github.com/logicminds/4f6bcfd723c92aad1f01f6a800319fa4
170
- $ puppet debugger --facterdb-filter 'facterversion=/^2.4\./ and operatingsystem=Debian' \\
171
- --play https://gist.github.com/logicminds/4f6bcfd723c92aad1f01f6a800319fa4
172
- $ puppet debugger --node-name
162
+ EXAMPLE
163
+ -------
164
+ $ puppet debugger
165
+ $ echo "notice('hello, can you hear me?')" | puppet debugger --test
166
+ $ echo "notice('hello, can you hear me?')" | puppet debugger --stdin
167
+ $ puppet debugger --execute "notice('hello')"
168
+ $ puppet debugger --facterdb-filter 'facterversion=/^2.4\./ and operatingsystem=Debian'
169
+ $ puppet debugger --play https://gist.github.com/logicminds/4f6bcfd723c92aad1f01f6a800319fa4
170
+ $ puppet debugger --facterdb-filter 'facterversion=/^2.4\./ and operatingsystem=Debian' \\
171
+ --play https://gist.github.com/logicminds/4f6bcfd723c92aad1f01f6a800319fa4
172
+ $ puppet debugger --node-name
173
173
 
174
174
 
175
- AUTHOR
176
- ------
177
- Corey Osman <corey@nwops.io>
175
+ AUTHOR
176
+ ------
177
+ Corey Osman <corey@nwops.io>
178
178
 
179
179
 
180
- COPYRIGHT
181
- ---------
182
- Copyright (c) 2019 NWOps
180
+ COPYRIGHT
181
+ ---------
182
+ Copyright (c) 2019 NWOps
183
183
 
184
184
  HELP
185
185
  end
@@ -187,13 +187,13 @@ Copyright (c) 2019 NWOps
187
187
  def initialize(command_line = Puppet::Util::CommandLine.new)
188
188
  @command_line = CommandLineArgs.new(command_line.subcommand_name, command_line.args.dup)
189
189
  @options = { use_facterdb: true, play: nil, run_once: false,
190
- node_name: nil, quiet: false, help: false, scope: nil,
191
- catalog: nil }
190
+ node_name: nil, quiet: false, help: false, scope: nil,
191
+ catalog: nil }
192
192
  @use_stdin = false
193
193
  begin
194
- require "puppet-debugger"
195
- rescue LoadError => e
196
- Puppet.err("You must install the puppet-debugger: gem install puppet-debugger")
194
+ require 'puppet-debugger'
195
+ rescue LoadError
196
+ Puppet.err('You must install the puppet-debugger: gem install puppet-debugger')
197
197
  end
198
198
  end
199
199
 
@@ -201,26 +201,26 @@ Copyright (c) 2019 NWOps
201
201
  # if this is a file we don't play back since its part of the environment
202
202
  # if just the code we put in a file and use the play feature of the debugger
203
203
  # we could do the same thing with the passed in manifest file but that might be too much code to show
204
-
205
204
  if options[:code]
206
205
  code_input = options.delete(:code)
207
- file = Tempfile.new(["puppet_debugger_input", ".pp"])
208
- File.open(file, "w") do |f|
206
+ file = Tempfile.new(['puppet_debugger_input', '.pp'])
207
+ File.open(file, 'w') do |f|
209
208
  f.write(code_input)
210
209
  end
211
210
  options[:play] = file
212
211
  elsif command_line.args.empty? && use_stdin
213
212
  code_input = STDIN.read
214
- file = Tempfile.new(["puppet_debugger_input", ".pp"])
215
- File.open(file, "w") do |f|
213
+ file = Tempfile.new(['puppet_debugger_input', '.pp'])
214
+ File.open(file, 'w') do |f|
216
215
  f.write(code_input)
217
216
  end
218
217
  options[:play] = file
219
218
  elsif !command_line.args.empty?
220
219
  manifest = command_line.args.shift
221
220
  raise "Could not find file #{manifest}" unless Puppet::FileSystem.exist?(manifest)
222
- Puppet.warning("Only one file can be used per run. Skipping #{command_line.args.join(", ")}") unless command_line.args.empty?
223
- options[:play] = file
221
+
222
+ Puppet.warning("Only one file can be used per run. Skipping #{command_line.args.join(', ')}") unless command_line.args.empty?
223
+ options[:play] = manifest
224
224
  end
225
225
  begin
226
226
  if !options[:use_facterdb] && options[:node_name].nil?
@@ -235,20 +235,21 @@ Copyright (c) 2019 NWOps
235
235
  rescue Exception => e
236
236
  case e.class.to_s
237
237
  when 'SystemExit'
238
- return
238
+ nil
239
239
  else
240
240
  puts e.message
241
241
  puts e.backtrace
242
- exit 1
243
242
  end
244
243
  end
245
244
  end
246
245
 
247
246
  def create_environment(manifest)
248
247
  configured_environment = Puppet.lookup(:current_environment)
249
- manifest ?
250
- configured_environment.override_with(manifest: manifest) :
248
+ if manifest
249
+ configured_environment.override_with(manifest: manifest)
250
+ else
251
251
  configured_environment
252
+ end
252
253
  end
253
254
 
254
255
  def create_node(environment)
@@ -258,14 +259,16 @@ Copyright (c) 2019 NWOps
258
259
  unless facts = Puppet::Node::Facts.indirection.find(Puppet[:node_name_value])
259
260
  raise "Could not find facts for #{Puppet[:node_name_value]}"
260
261
  end
262
+
261
263
  Puppet[:node_name_value] = facts.values[Puppet[:node_name_fact]]
262
264
  facts.name = Puppet[:node_name_value]
263
265
  end
264
- Puppet.override({ current_environment: environment }, "For puppet debugger") do
266
+ Puppet.override({ current_environment: environment }, 'For puppet debugger') do
265
267
  # Find our Node
266
268
  unless node = Puppet::Node.indirection.find(Puppet[:node_name_value])
267
269
  raise "Could not find node #{Puppet[:node_name_value]}"
268
270
  end
271
+
269
272
  # Merge in the facts.
270
273
  node.merge(facts.values) if facts
271
274
  end
@@ -288,11 +291,14 @@ Copyright (c) 2019 NWOps
288
291
  if $stdout.isatty
289
292
  options = options.merge(scope: scope)
290
293
  # required in order to use convert puppet hash into ruby hash with symbols
291
- options = options.each_with_object({}) { |(k, v), data| data[k.to_sym] = v; data }
294
+ options = options.each_with_object({}) do |(k, v), data|
295
+ data[k.to_sym] = v
296
+ data
297
+ end
292
298
  # options[:source_file], options[:source_line] = stacktrace.last
293
299
  ::PuppetRepl::Cli.start(options)
294
300
  else
295
- Puppet.info "puppet debug: refusing to start the debugger without a tty"
301
+ Puppet.info 'puppet debug: refusing to start the debugger without a tty'
296
302
  end
297
303
  end
298
304
 
@@ -303,7 +309,7 @@ Copyright (c) 2019 NWOps
303
309
  # for compatibility with older puppet versions
304
310
  # The basics behind this are to find the `.pp` file in the list of loaded code
305
311
  def stacktrace
306
- result = caller.each_with_object([]) do |loc, memo|
312
+ caller.each_with_object([]) do |loc, memo|
307
313
  if loc =~ /\A(.*\.pp)?:([0-9]+):in\s(.*)/
308
314
  # if the file is not found we set to code
309
315
  # and read from Puppet[:code]