kafo 6.5.0 → 7.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,110 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>
7
+ Top Level Namespace
8
+
9
+ &mdash; Documentation by YARD 0.9.34
10
+
11
+ </title>
12
+
13
+ <link rel="stylesheet" href="css/style.css" type="text/css" />
14
+
15
+ <link rel="stylesheet" href="css/common.css" type="text/css" />
16
+
17
+ <script type="text/javascript">
18
+ pathId = "";
19
+ relpath = '';
20
+ </script>
21
+
22
+
23
+ <script type="text/javascript" charset="utf-8" src="js/jquery.js"></script>
24
+
25
+ <script type="text/javascript" charset="utf-8" src="js/app.js"></script>
26
+
27
+
28
+ </head>
29
+ <body>
30
+ <div class="nav_wrap">
31
+ <iframe id="nav" src="class_list.html?1"></iframe>
32
+ <div id="resizer"></div>
33
+ </div>
34
+
35
+ <div id="main" tabindex="-1">
36
+ <div id="header">
37
+ <div id="menu">
38
+
39
+ <a href="_index.html">Index</a> &raquo;
40
+
41
+
42
+ <span class="title">Top Level Namespace</span>
43
+
44
+ </div>
45
+
46
+ <div id="search">
47
+
48
+ <a class="full_list_link" id="class_list_link"
49
+ href="class_list.html">
50
+
51
+ <svg width="24" height="24">
52
+ <rect x="0" y="4" width="24" height="4" rx="1" ry="1"></rect>
53
+ <rect x="0" y="12" width="24" height="4" rx="1" ry="1"></rect>
54
+ <rect x="0" y="20" width="24" height="4" rx="1" ry="1"></rect>
55
+ </svg>
56
+ </a>
57
+
58
+ </div>
59
+ <div class="clear"></div>
60
+ </div>
61
+
62
+ <div id="content"><h1>Top Level Namespace
63
+
64
+
65
+
66
+ </h1>
67
+ <div class="box_info">
68
+
69
+
70
+
71
+
72
+
73
+
74
+
75
+
76
+
77
+
78
+
79
+ </div>
80
+
81
+ <h2>Defined Under Namespace</h2>
82
+ <p class="children">
83
+
84
+
85
+ <strong class="modules">Modules:</strong> <span class='object_link'><a href="Kafo.html" title="Kafo (module)">Kafo</a></span>
86
+
87
+
88
+
89
+
90
+ </p>
91
+
92
+
93
+
94
+
95
+
96
+
97
+
98
+
99
+
100
+ </div>
101
+
102
+ <div id="footer">
103
+ Generated on Fri Jul 14 17:35:54 2023 by
104
+ <a href="https://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
105
+ 0.9.34 (ruby-3.2.2).
106
+ </div>
107
+
108
+ </div>
109
+ </body>
110
+ </html>
@@ -8,4 +8,7 @@ module Kafo
8
8
 
9
9
  class ParserError < StandardError
10
10
  end
11
+
12
+ class PuppetReportError < StandardError
13
+ end
11
14
  end
@@ -19,6 +19,15 @@ module Kafo
19
19
  end
20
20
  end
21
21
 
22
+ def reportdir
23
+ @reportdir ||= File.join(directory, 'reports')
24
+ end
25
+
26
+ def reports
27
+ # Reports are stored in $reportdir/$certname/$report
28
+ Dir.glob(File.join(reportdir, '*', '*.*')).sort_by { |path| File.mtime(path) }
29
+ end
30
+
22
31
  def store_answers
23
32
  answer_data = HieraConfigurer.generate_data(@config.modules, @config.app[:order])
24
33
  @logger.debug("Writing temporary answers to #{answer_file}")
@@ -37,6 +46,8 @@ module Kafo
37
46
  'environmentpath' => environmentpath,
38
47
  'factpath' => factpath,
39
48
  'hiera_config' => hiera_config,
49
+ 'reports' => 'store',
50
+ 'reportdir' => reportdir,
40
51
  }.merge(settings)
41
52
 
42
53
  PuppetConfigurer.new(puppet_conf, settings)
@@ -0,0 +1,53 @@
1
+ module Kafo
2
+ class PuppetFailedResource
3
+ # @param [Hash] status
4
+ # The status hash from the report
5
+ # @param [Array[Hash]] logs
6
+ # Relevant log lines for this resoure
7
+ def initialize(status, logs)
8
+ @status = status
9
+ @logs = logs
10
+ end
11
+
12
+ # @example
13
+ # puppet_failed_resource.resource == 'Exec[/bin/true]'
14
+ # @return [String] A resource
15
+ def resource
16
+ @status['resource']
17
+ end
18
+
19
+ # @example
20
+ # puppet_failed_resource.type == 'Exec'
21
+ # @return [String] A resource type
22
+ def type
23
+ @status['resource_type']
24
+ end
25
+
26
+ # @example
27
+ # puppet_failed_resource.title == '/bin/true'
28
+ # @return [String] A resource title
29
+ def title
30
+ @status['title']
31
+ end
32
+
33
+ def to_s
34
+ "Puppet #{type} resource '#{title}'"
35
+ end
36
+
37
+ # @return [Array[String]] The event messages
38
+ def event_messages
39
+ @status['events'].map { |event| event['message'] }
40
+ end
41
+
42
+ # A collection of Puppet log messages
43
+ #
44
+ # The log messages include detailed information of what failed. Some debug
45
+ # information, such as timing but crucially the command output, both stdout
46
+ # and stderr.
47
+ #
48
+ # @return [Array[String]] The Puppet log messages for this resource
49
+ def log_messages
50
+ @logs.map { |log| log['message'] }
51
+ end
52
+ end
53
+ end
@@ -6,7 +6,7 @@ module Kafo
6
6
  def add_module(name, items)
7
7
  data = by_parameter_groups(items)
8
8
  if data.keys.size > 1
9
- puts module_header(name + ':')
9
+ line module_header(name + ':')
10
10
  data.keys.each do |group|
11
11
  add_list(header(2, group), data[group])
12
12
  end
@@ -17,7 +17,7 @@ module Kafo
17
17
  def add_list(heading, items)
18
18
  return if items.empty?
19
19
  if heading == 'Options'
20
- puts "\n#{heading}:"
20
+ line "\n#{heading}:"
21
21
 
22
22
  data = by_module(items)
23
23
 
@@ -196,5 +196,13 @@ module Kafo
196
196
  def exit_code
197
197
  self.kafo.exit_code
198
198
  end
199
+
200
+ # Return the Puppet report, if any.
201
+ # Only available after Puppet actual ran.
202
+ #
203
+ # @return [Optional[Kafo::PuppetReport]]
204
+ def puppet_report
205
+ self.kafo.puppet_report
206
+ end
199
207
  end
200
208
  end
@@ -20,8 +20,10 @@ require 'kafo/string_helper'
20
20
  require 'kafo/help_builder'
21
21
  require 'kafo/wizard'
22
22
  require 'kafo/system_checker'
23
+ require 'kafo/failed_puppet_resource'
23
24
  require 'kafo/puppet_command'
24
25
  require 'kafo/puppet_log_parser'
26
+ require 'kafo/puppet_report'
25
27
  require 'kafo/progress_bar'
26
28
  require 'kafo/hooking'
27
29
  require 'kafo/exit_handler'
@@ -34,6 +36,8 @@ module Kafo
34
36
  class KafoConfigure < Clamp::Command
35
37
  include StringHelper
36
38
 
39
+ attr_accessor :puppet_report
40
+
37
41
  class << self
38
42
  include AppOption::Declaration
39
43
 
@@ -304,7 +308,7 @@ module Kafo
304
308
  store = Store.new()
305
309
  store_path = self.class.config.app[:store_dir]
306
310
  store_path = File.expand_path(File.join(CONFIG_DIR, '../store.d')) if store_path.empty? && defined?(CONFIG_DIR)
307
- store.add_dir(store_path) if File.exists?(store_path)
311
+ store.add_dir(store_path) if File.exist?(store_path)
308
312
  store
309
313
  end
310
314
 
@@ -542,6 +546,12 @@ module Kafo
542
546
  @progress_bar.close if @progress_bar
543
547
  logger.notice "System configuration has finished."
544
548
 
549
+ if (last_report = execution_env.reports.last)
550
+ # For debugging: you can easily copy the last report to fixtures
551
+ # FileUtils.cp(last_report, File.join(__dir__, '..', '..', 'test', 'fixtures', 'reports', File.basename(last_report)))
552
+ self.puppet_report = PuppetReport.load_report_file(last_report)
553
+ end
554
+
545
555
  self.class.hooking.execute(:post)
546
556
  self.class.exit(exit_code)
547
557
  end
@@ -556,10 +566,10 @@ module Kafo
556
566
  end
557
567
 
558
568
  def config_file
559
- return CONFIG_FILE if defined?(CONFIG_FILE) && File.exists?(CONFIG_FILE)
569
+ return CONFIG_FILE if defined?(CONFIG_FILE) && File.exist?(CONFIG_FILE)
560
570
  return self.class.scenario_manager.select_scenario if self.class.scenario_manager.configured?
561
- return '/etc/kafo/kafo.yaml' if File.exists?('/etc/kafo/kafo.yaml')
562
- return "#{::RbConfig::CONFIG['sysconfdir']}/kafo/kafo.yaml" if File.exists?("#{::RbConfig::CONFIG['sysconfdir']}/kafo/kafo.yaml")
571
+ return '/etc/kafo/kafo.yaml' if File.exist?('/etc/kafo/kafo.yaml')
572
+ return "#{::RbConfig::CONFIG['sysconfdir']}/kafo/kafo.yaml" if File.exist?("#{::RbConfig::CONFIG['sysconfdir']}/kafo/kafo.yaml")
563
573
  File.join(Dir.pwd, 'config', 'kafo.yaml')
564
574
  end
565
575
 
@@ -73,16 +73,11 @@ module Kafo
73
73
  def manifest
74
74
  %{echo '
75
75
  $kafo_config_file="#{@configuration.config_file}"
76
- #{add_progress}
77
76
  #{generate_version_checks.join("\n") if @puppet_version_check}
78
77
  #{@command}
79
78
  '}
80
79
  end
81
80
 
82
- def add_progress
83
- %{$kafo_add_progress=#{!KafoConfigure.verbose}}
84
- end
85
-
86
81
  def generate_version_checks
87
82
  checks = []
88
83
  modules_path.each do |modulepath|
@@ -36,7 +36,7 @@ module Kafo
36
36
  if @configuration.module_dirs.count == 1
37
37
  module_dir = @configuration.module_dirs.first
38
38
  else
39
- module_dir = @configuration.module_dirs.find { |dir| File.exists?(File.join(dir, module_manifest_path)) } ||
39
+ module_dir = @configuration.module_dirs.find { |dir| File.exist?(File.join(dir, module_manifest_path)) } ||
40
40
  warn("Manifest #{module_manifest_path} was not found in #{@configuration.module_dirs.join(', ')}")
41
41
  end
42
42
  @manifest_path = File.join(module_dir, module_manifest_path)
@@ -0,0 +1,64 @@
1
+ module Kafo
2
+ # An abstraction over the Puppet report format
3
+ #
4
+ # @see https://puppet.com/docs/puppet/8/format_report.html
5
+ class PuppetReport
6
+ # Load a Puppet report from a path
7
+ #
8
+ # Both YAML and JSON are supported.
9
+ #
10
+ # @param [String] path
11
+ # The path to Puppet report
12
+ #
13
+ # @return [PuppetReport] The report from the path
14
+ def self.load_report_file(path)
15
+ raise ArgumentError, 'No path given' unless path || path.empty?
16
+ raise ArgumentError, "#{path} is not a readable file" unless File.file?(path) && File.readable?(path)
17
+
18
+ data = case File.extname(path)
19
+ when '.yaml'
20
+ require 'yaml'
21
+ content = File.read(path).gsub(/\!ruby\/object.*$/, '')
22
+ YAML.safe_load(content, permitted_classes: [Time, Symbol])
23
+ when '.json'
24
+ require 'json'
25
+ JSON.parse(File.read(path))
26
+ else
27
+ raise ArgumentError, "Unsupported file extension for #{path}"
28
+ end
29
+
30
+ PuppetReport.new(data)
31
+ end
32
+
33
+ # @param [Hash] report
34
+ # The Puppet report
35
+ def initialize(report)
36
+ @report = report
37
+ end
38
+
39
+ # @return [Integer] The report format
40
+ def report_format
41
+ @report['report_format']
42
+ end
43
+
44
+ # @return [Array[Hash]] The Puppet logs
45
+ def logs
46
+ @report['logs']
47
+ end
48
+
49
+ # @return [Array[PuppetFailedResource]] The failed resources and their status
50
+ def failed_resources
51
+ statuses = @report['resource_statuses']
52
+
53
+ raise PuppetReportError, "No resource statuses found in report" unless statuses
54
+
55
+ statuses.select { |_title, status| status['failed'] }.map do |title, status|
56
+ # TODO: There's also a message with source Puppet
57
+ # Executing with uid=USER: '/tmp/failing-command'
58
+ # This shows up after Executing '/tmp/failing-command'
59
+ related_logs = logs.select { |log| log['source'].include?(title) }
60
+ PuppetFailedResource.new(status, related_logs)
61
+ end
62
+ end
63
+ end
64
+ end
data/lib/kafo/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # encoding: UTF-8
2
2
  module Kafo
3
3
  PARSER_CACHE_VERSION = 1
4
- VERSION = "6.5.0"
4
+ VERSION = "7.1.0"
5
5
  end
@@ -3,15 +3,6 @@
3
3
  # optional $answers class parameter
4
4
  # $modulepath/config/answers.yaml
5
5
  # /etc/kafo-configure/answers.yaml
6
- #
7
- # @param add_progress
8
- # Whether to add a progress bar. Only works on Puppet < 6.
9
- class kafo_configure(
10
- Boolean $add_progress = $::kafo_add_progress,
11
- ) {
12
- if $add_progress and SemVer($facts['puppetversion']) =~ SemVerRange('< 6.0.0') {
13
- add_progress()
14
- }
15
-
6
+ class kafo_configure {
16
7
  lookup('classes', {merge => unique}).include
17
8
  }
@@ -2,16 +2,9 @@ require 'spec_helper'
2
2
 
3
3
  describe 'kafo_configure' do
4
4
  let(:hiera_config) { 'spec/fixtures/hiera/hiera.yaml' }
5
- let(:facts) { { puppetversion: Puppet.version } }
6
5
 
7
6
  context 'without parameters' do
8
- let(:params) { {add_progress: false} }
9
7
  it { is_expected.to compile.with_all_deps }
10
8
  it { is_expected.to contain_class('dummy') }
11
9
  end
12
-
13
- context 'with progress' do
14
- let(:params) { {add_progress: true} }
15
- it { is_expected.to compile.with_all_deps }
16
- end
17
10
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kafo
3
3
  version: !ruby/object:Gem::Version
4
- version: 6.5.0
4
+ version: 7.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Marek Hulan
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-05-31 00:00:00.000000000 Z
11
+ date: 2023-08-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -31,7 +31,7 @@ dependencies:
31
31
  - !ruby/object:Gem::Version
32
32
  version: '3'
33
33
  - !ruby/object:Gem::Dependency
34
- name: rake
34
+ name: minitest
35
35
  requirement: !ruby/object:Gem::Requirement
36
36
  requirements:
37
37
  - - ">="
@@ -45,7 +45,7 @@ dependencies:
45
45
  - !ruby/object:Gem::Version
46
46
  version: '0'
47
47
  - !ruby/object:Gem::Dependency
48
- name: minitest
48
+ name: minitest-reporters
49
49
  requirement: !ruby/object:Gem::Requirement
50
50
  requirements:
51
51
  - - ">="
@@ -59,7 +59,7 @@ dependencies:
59
59
  - !ruby/object:Gem::Version
60
60
  version: '0'
61
61
  - !ruby/object:Gem::Dependency
62
- name: minitest-reporters
62
+ name: rake
63
63
  requirement: !ruby/object:Gem::Requirement
64
64
  requirements:
65
65
  - - ">="
@@ -87,7 +87,7 @@ dependencies:
87
87
  - !ruby/object:Gem::Version
88
88
  version: '0'
89
89
  - !ruby/object:Gem::Dependency
90
- name: kafo_wizards
90
+ name: ansi
91
91
  requirement: !ruby/object:Gem::Requirement
92
92
  requirements:
93
93
  - - ">="
@@ -101,7 +101,7 @@ dependencies:
101
101
  - !ruby/object:Gem::Version
102
102
  version: '0'
103
103
  - !ruby/object:Gem::Dependency
104
- name: ansi
104
+ name: kafo_wizards
105
105
  requirement: !ruby/object:Gem::Requirement
106
106
  requirements:
107
107
  - - ">="
@@ -148,20 +148,20 @@ dependencies:
148
148
  requirements:
149
149
  - - ">="
150
150
  - !ruby/object:Gem::Version
151
- version: 0.6.2
151
+ version: 1.3.1
152
152
  - - "<"
153
153
  - !ruby/object:Gem::Version
154
- version: 1.3.1
154
+ version: '2'
155
155
  type: :runtime
156
156
  prerelease: false
157
157
  version_requirements: !ruby/object:Gem::Requirement
158
158
  requirements:
159
159
  - - ">="
160
160
  - !ruby/object:Gem::Version
161
- version: 0.6.2
161
+ version: 1.3.1
162
162
  - - "<"
163
163
  - !ruby/object:Gem::Version
164
- version: 1.3.1
164
+ version: '2'
165
165
  - !ruby/object:Gem::Dependency
166
166
  name: highline
167
167
  requirement: !ruby/object:Gem::Requirement
@@ -215,8 +215,17 @@ files:
215
215
  - bin/kafofy
216
216
  - config/config_header.txt
217
217
  - config/kafo.yaml.example
218
+ - doc/Kafo.html
219
+ - doc/_index.html
220
+ - doc/class_list.html
221
+ - doc/file.README.html
222
+ - doc/file_list.html
223
+ - doc/frames.html
224
+ - doc/index.html
218
225
  - doc/kafo_run.png
219
226
  - doc/kafo_run.uml
227
+ - doc/method_list.html
228
+ - doc/top-level-namespace.html
220
229
  - lib/kafo.rb
221
230
  - lib/kafo/app_option/declaration.rb
222
231
  - lib/kafo/app_option/definition.rb
@@ -250,6 +259,7 @@ files:
250
259
  - lib/kafo/execution_environment.rb
251
260
  - lib/kafo/exit_handler.rb
252
261
  - lib/kafo/fact_writer.rb
262
+ - lib/kafo/failed_puppet_resource.rb
253
263
  - lib/kafo/help_builder.rb
254
264
  - lib/kafo/help_builders/advanced.rb
255
265
  - lib/kafo/help_builders/base.rb
@@ -275,6 +285,7 @@ files:
275
285
  - lib/kafo/puppet_configurer.rb
276
286
  - lib/kafo/puppet_log_parser.rb
277
287
  - lib/kafo/puppet_module.rb
288
+ - lib/kafo/puppet_report.rb
278
289
  - lib/kafo/scenario_manager.rb
279
290
  - lib/kafo/scenario_option.rb
280
291
  - lib/kafo/store.rb
@@ -286,7 +297,6 @@ files:
286
297
  - modules/kafo_configure/lib/puppet/functions/kafo_configure/dump_lookups.rb
287
298
  - modules/kafo_configure/lib/puppet/functions/kafo_configure/dump_variables.rb
288
299
  - modules/kafo_configure/lib/puppet/functions/kafo_configure/to_yaml.rb
289
- - modules/kafo_configure/lib/puppet/parser/functions/add_progress.rb
290
300
  - modules/kafo_configure/manifests/dump_values.pp
291
301
  - modules/kafo_configure/manifests/init.pp
292
302
  - modules/kafo_configure/manifests/puppet_version_semver.pp
@@ -313,14 +323,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
313
323
  requirements:
314
324
  - - ">="
315
325
  - !ruby/object:Gem::Version
316
- version: 2.4.0
326
+ version: '2.7'
317
327
  required_rubygems_version: !ruby/object:Gem::Requirement
318
328
  requirements:
319
329
  - - ">="
320
330
  - !ruby/object:Gem::Version
321
331
  version: '0'
322
332
  requirements: []
323
- rubygems_version: 3.2.22
333
+ rubygems_version: 3.4.10
324
334
  signing_key:
325
335
  specification_version: 4
326
336
  summary: A gem for making installations based on puppet user friendly
@@ -1,43 +0,0 @@
1
- module Puppet::Parser::Functions
2
- newfunction(:add_progress) do |args|
3
- loaded = false
4
- begin
5
- require 'puppet/transaction'
6
- loaded = true
7
- rescue LoadError
8
- ::Puppet.warning 'Unable to load puppet/transaction for progress bar support, this version may not be supported'
9
- end
10
-
11
- if loaded
12
- # Monkey patch the transaction to put our wrapper around the report object
13
- class Puppet::Transaction
14
- attr_accessor :in_main_catalog
15
-
16
- def is_interesting?(resource)
17
- return false if resource.class.name == :component # ignore defined types
18
- ![:schedule, :class, :stage, :filebucket, :anchor, :concat_fragment].include?(resource.to_s.split('[')[0].downcase.to_sym)
19
- end
20
-
21
- def tracked_resources
22
- @tracked_resources ||= catalog.vertices.select { |resource| is_interesting?(resource) }.map(&:to_s)
23
- end
24
-
25
- def evaluate_with_trigger(*args, &block)
26
- if catalog.version
27
- self.in_main_catalog = true
28
- tracked_resources.each { |r| ::Puppet.info "MONITOR_RESOURCE #{r}" }
29
- end
30
- evaluate_without_trigger(*args, &block)
31
- self.in_main_catalog = false if catalog.version
32
- end
33
-
34
- if method_defined?(:evaluate) && method_defined?(:report)
35
- alias_method :evaluate_without_trigger, :evaluate
36
- alias_method :evaluate, :evaluate_with_trigger
37
- else
38
- ::Puppet.warning 'Unable to patch Puppet transactions for progress bar support, this version may not be supported'
39
- end
40
- end
41
- end
42
- end
43
- end