kafo 6.5.0 → 7.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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