inspec-core 4.56.19 → 5.12.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (77) hide show
  1. checksums.yaml +4 -4
  2. data/etc/deprecations.json +12 -16
  3. data/inspec-core.gemspec +1 -1
  4. data/lib/inspec/base_cli.rb +14 -2
  5. data/lib/inspec/cli.rb +15 -0
  6. data/lib/inspec/dependency_installer.rb +74 -0
  7. data/lib/inspec/dependency_loader.rb +97 -0
  8. data/lib/inspec/dsl.rb +11 -2
  9. data/lib/inspec/errors.rb +7 -0
  10. data/lib/inspec/formatters/base.rb +23 -0
  11. data/lib/inspec/metadata.rb +36 -0
  12. data/lib/inspec/plugin/v2/installer.rb +9 -2
  13. data/lib/inspec/plugin/v2/loader.rb +13 -0
  14. data/lib/inspec/plugin/v2/plugin_types/streaming_reporter.rb +44 -1
  15. data/lib/inspec/plugin/v2/status.rb +2 -1
  16. data/lib/inspec/profile.rb +63 -0
  17. data/lib/inspec/reporters/automate.rb +1 -1
  18. data/lib/inspec/reporters/cli.rb +1 -1
  19. data/lib/inspec/reporters/json.rb +31 -11
  20. data/lib/inspec/resource.rb +6 -0
  21. data/lib/inspec/resources/apt.rb +12 -6
  22. data/lib/inspec/resources/cgroup.rb +101 -0
  23. data/lib/inspec/resources/cron.rb +49 -0
  24. data/lib/inspec/resources/docker_container.rb +21 -0
  25. data/lib/inspec/resources/docker_image.rb +53 -0
  26. data/lib/inspec/resources/ipfilter.rb +59 -0
  27. data/lib/inspec/resources/ipnat.rb +58 -0
  28. data/lib/inspec/resources/lxc.rb +57 -0
  29. data/lib/inspec/resources/mail_alias.rb +46 -0
  30. data/lib/inspec/resources/routing_table.rb +137 -0
  31. data/lib/inspec/resources/service.rb +14 -1
  32. data/lib/inspec/resources/user.rb +12 -0
  33. data/lib/inspec/resources/users.rb +79 -14
  34. data/lib/inspec/resources/virtualization.rb +9 -3
  35. data/lib/inspec/resources.rb +3 -16
  36. data/lib/inspec/runner.rb +18 -1
  37. data/lib/inspec/runner_rspec.rb +15 -0
  38. data/lib/inspec/schema/exec_json.rb +59 -58
  39. data/lib/inspec/schema/exec_json_min.rb +16 -16
  40. data/lib/inspec/schema/primitives.rb +68 -51
  41. data/lib/inspec/schema/profile_json.rb +27 -27
  42. data/lib/inspec/schema.rb +1 -0
  43. data/lib/inspec/ui.rb +10 -0
  44. data/lib/inspec/utils/deprecated_cloud_resources_list.rb +54 -0
  45. data/lib/inspec/version.rb +1 -1
  46. data/lib/inspec.rb +3 -0
  47. data/lib/plugins/inspec-artifact/inspec-artifact.gemspec +9 -0
  48. data/lib/plugins/inspec-compliance/inspec-compliance.gemspec +9 -0
  49. data/lib/plugins/inspec-habitat/inspec-habitat.gemspec +9 -0
  50. data/lib/plugins/inspec-init/inspec-init.gemspec +9 -0
  51. data/lib/plugins/inspec-init/lib/inspec-init/cli.rb +1 -0
  52. data/lib/plugins/inspec-init/lib/inspec-init/cli_plugin.rb +9 -0
  53. data/lib/plugins/inspec-init/lib/inspec-init/cli_resource.rb +126 -0
  54. data/lib/plugins/inspec-init/lib/inspec-init/renderer.rb +9 -8
  55. data/lib/plugins/inspec-init/templates/plugins/inspec-plugin-template/lib/inspec-plugin-template/plugin.erb +16 -0
  56. data/lib/plugins/inspec-init/templates/plugins/inspec-plugin-template/lib/inspec-plugin-template/streaming_reporter.erb +31 -0
  57. data/lib/plugins/inspec-init/templates/profiles/aws/inspec.yml +1 -1
  58. data/lib/plugins/inspec-init/templates/resources/basic/docs/resource-doc.erb +77 -0
  59. data/lib/plugins/inspec-init/templates/resources/basic/libraries/inspec-resource-template.erb +94 -0
  60. data/lib/plugins/inspec-init/templates/resources/plural/docs/resource-doc.erb +62 -0
  61. data/lib/plugins/inspec-init/templates/resources/plural/libraries/inspec-resource-template.erb +73 -0
  62. data/lib/plugins/inspec-plugin-manager-cli/inspec-plugin-manager-cli.gemspec +10 -0
  63. data/lib/plugins/inspec-plugin-manager-cli/lib/inspec-plugin-manager-cli/cli_command.rb +15 -11
  64. data/lib/plugins/inspec-reporter-html2/inspec-reporter-html2.gemspec +9 -0
  65. data/lib/plugins/inspec-reporter-html2/templates/body.html.erb +2 -0
  66. data/lib/plugins/inspec-reporter-html2/templates/control.html.erb +3 -0
  67. data/lib/plugins/inspec-reporter-html2/templates/profile.html.erb +1 -0
  68. data/lib/plugins/inspec-reporter-html2/templates/result.html.erb +1 -0
  69. data/lib/plugins/inspec-reporter-json-min/inspec-reporter-json-min.gemspec +9 -0
  70. data/lib/plugins/inspec-reporter-junit/inspec-reporter-junit.gemspec +9 -0
  71. data/lib/plugins/inspec-streaming-reporter-progress-bar/README.md +5 -0
  72. data/lib/plugins/inspec-streaming-reporter-progress-bar/inspec-streaming-reporter-progress-bar.gemspec +9 -0
  73. data/lib/plugins/inspec-streaming-reporter-progress-bar/lib/inspec-streaming-reporter-progress-bar/plugin.rb +13 -0
  74. data/lib/plugins/inspec-streaming-reporter-progress-bar/lib/inspec-streaming-reporter-progress-bar/streaming_reporter.rb +123 -0
  75. data/lib/plugins/inspec-streaming-reporter-progress-bar/lib/inspec-streaming-reporter-progress-bar/version.rb +8 -0
  76. data/lib/plugins/inspec-streaming-reporter-progress-bar/lib/inspec-streaming-reporter-progress-bar.rb +15 -0
  77. metadata +33 -3
@@ -0,0 +1,126 @@
1
+ require_relative "renderer"
2
+
3
+ module InspecPlugins
4
+ module Init
5
+ class CLI < Inspec.plugin(2, :cli_command)
6
+ #-------------------------------------------------------------------#
7
+ # inspec init resource
8
+ #-------------------------------------------------------------------#
9
+ desc "resource RESOURCE_NAME [options]", "Generates an InSpec resource, which can extend the scope of InSpec resources support"
10
+ # General options
11
+ option :prompt, type: :boolean, default: true, desc: "Interactively prompt for information to put in your generated resource."
12
+ option :overwrite, type: :boolean, default: false, desc: "Overwrite existing files"
13
+ option :layout, type: :string, default: "resource-pack", desc: "File layout, either 'resource-pack' or 'core'"
14
+ option :template, type: :string, default: "basic", desc: "Which type of resource template to use"
15
+
16
+ # Templating vars
17
+ option :supports_platform, type: :string, default: "linux", desc: "the platform supported by this resource"
18
+ option :description, type: :string, default: "Resource description ...", desc: "the description of this resource"
19
+ option :class_name, type: :string, default: "MyCustomResource", desc: "Class Name for your resource."
20
+ option :path, type: :string, default: ".", desc: "Subdirectory under which to create files"
21
+
22
+ # Wishlist:
23
+ # Make make_rename_map_resource dynamic:
24
+ # + Add a --path option which defaults to ., which will create the tree under that path
25
+ # + Add a --layout option which changes all the tree to act as placing the files in core inspec (lib/inspec/resources, docs-chef-io/)
26
+ # - Add a --template=plural option which changes the templates to use a set of Filtertable based templates
27
+ # - Add a --template=inherit option which provides a template for inheriting from the core resources
28
+ # - Add a template=aws
29
+ # + Generate properties and matchers:
30
+ # + generate a has_bells? matcher => it { should have_bells }
31
+ # + generate a is_purple? matcher => it { should be_purple }
32
+ # + generate a shoe_size => its('shoe_size') { should cmp 10 }
33
+ # + Generate unit tests for above properties and matchers
34
+ # + Generate docs for properties and matchers
35
+ # + Add --overwrite option
36
+
37
+ def resource(resource_name)
38
+ resource_vars_from_opts_resource
39
+ template_vars = {
40
+ name: options[:path], # This is used for the path prefix
41
+ resource_name: resource_name,
42
+ }
43
+ template_vars.merge!(options)
44
+ template_path = File.join("resources", template_vars["template"])
45
+
46
+ render_opts = {
47
+ templates_path: TEMPLATES_PATH,
48
+ overwrite: options[:overwrite],
49
+ file_rename_map: make_rename_map_resource(template_vars),
50
+ }
51
+ renderer = InspecPlugins::Init::Renderer.new(ui, render_opts)
52
+ renderer.render_with_values(template_path, "resource", template_vars)
53
+ end
54
+
55
+ private
56
+
57
+ def make_rename_map_resource(vars)
58
+ if vars["layout"] == "resource-pack"
59
+ {
60
+ File.join("libraries", "inspec-resource-template.erb") => File.join("libraries", vars[:resource_name] + ".rb"),
61
+ File.join("docs", "resource-doc.erb") => File.join("docs", vars[:resource_name] + ".md"),
62
+ File.join("test", "unit", "inspec-resource-test-template.erb") => File.join("test", "unit", vars[:resource_name] + "_test.rb"),
63
+ }
64
+ elsif vars["layout"] == "core"
65
+ {
66
+ File.join("libraries", "inspec-resource-template.erb") => File.join("lib", "inspec", "resources", vars[:resource_name] + ".rb"),
67
+ File.join("docs", "resource-doc.erb") => File.join("docs-chef-io", "content", "inspec", "resources", vars[:resource_name] + ".md"),
68
+ File.join("test", "unit", "inspec-resource-test-template.erb") => File.join("test", "unit", "resources", vars[:resource_name] + "_test.rb"),
69
+ }
70
+ else
71
+ ui.error("Unrecognized value for 'layout' - please enter either 'resource-pack' or 'core'")
72
+ ui.exit(:usage_error)
73
+ end
74
+ end
75
+
76
+ def resource_vars_from_opts_resource
77
+ if options[:prompt] && ui.interactive?
78
+ options.dup.merge(prompt_for_options_resource)
79
+ elsif !options[:prompt]
80
+ # Nothing to do - unless we need to calculate dynamic defaults in the future
81
+ else
82
+ ui.error("You requested interactive prompting for the template variables, but this does not seem to be an interactive terminal.")
83
+ ui.exit(:usage_error)
84
+ end
85
+ end
86
+
87
+ def prompt_for_options_resource # rubocop: disable Metrics/AbcSize
88
+ option_defs = self.class.all_commands["resource"].options
89
+ options_order = {
90
+ path: {},
91
+ layout: {
92
+ mode: :select,
93
+ choices: [
94
+ { name: "Resource Pack", value: "resource-pack", default: true },
95
+ { name: "InSpec Core", value: "core" },
96
+ ],
97
+ },
98
+ template: {
99
+ mode: :select,
100
+ choices: [
101
+ { name: "Basic", value: "basic", default: true },
102
+ { name: "Plural", value: "plural" },
103
+ ],
104
+ },
105
+ supports_platform: {},
106
+ description: {},
107
+ class_name: {},
108
+ }
109
+
110
+ options_order.each do |opt_name, prompt_options|
111
+ opt_def = option_defs[opt_name]
112
+
113
+ case prompt_options[:mode]
114
+ when :select
115
+ options[opt_name] = ui.prompt.select("Choose " + opt_def.description + ":", prompt_options[:choices])
116
+ when :multiline
117
+ options[opt_name] = ui.prompt.multiline("Enter " + opt_def.description + ". Press Control-D to end.", default: options[opt_name])
118
+ else
119
+ # Assume plain ask
120
+ options[opt_name] = ui.prompt.ask("Enter " + opt_def.description + ":", default: options[opt_name])
121
+ end
122
+ end
123
+ end
124
+ end
125
+ end
126
+ end
@@ -38,8 +38,8 @@ module InspecPlugins
38
38
  full_destination_path = Pathname.new(Dir.pwd).join(relative_destination_path)
39
39
 
40
40
  # check that the directory does not exist
41
- if File.exist?(full_destination_path) && !overwrite_mode
42
- ui.plain_line "#{ui.emphasis(full_destination_path)} exists already, use --overwrite"
41
+ if File.exist?(full_destination_path) && !overwrite_mode && template_values[:name] != "."
42
+ ui.plain_line "#{ui.emphasis(full_destination_path)} exists already, use --overwrite or move to #{ui.emphasis(full_destination_path)} to create the resource"
43
43
  ui.exit(:usage_error)
44
44
  end
45
45
 
@@ -57,18 +57,19 @@ module InspecPlugins
57
57
 
58
58
  relative_destination_item_path = file_rename_map[relative_destination_item_path] || relative_destination_item_path
59
59
  full_destination_item_path = Pathname.new(full_destination_path).join(relative_destination_item_path)
60
- if File.directory?(source_file)
61
- ui.list_item "Creating directory #{ui.emphasis(relative_destination_item_path)}"
62
- FileUtils.mkdir_p(full_destination_item_path)
63
- elsif File.file?(source_file)
60
+ if File.file?(source_file)
61
+ # Be git-like and only create directories if they contain a file
62
+ containing_directory = full_destination_item_path.dirname
63
+ unless File.exist?(containing_directory)
64
+ ui.list_item "Creating directory #{ui.emphasis(containing_directory)}"
65
+ FileUtils.mkdir_p(containing_directory)
66
+ end
64
67
  ui.list_item "Creating file #{ui.emphasis(relative_destination_item_path)}"
65
68
  # read & render content
66
69
  content = render(File.read(source_file), template_values)
67
70
  # write file content
68
71
 
69
72
  File.write(full_destination_item_path, content)
70
- else
71
- ui.warning "Ignoring #{ui.emphasis(source_file)}, because its not an file or directoy"
72
73
  end
73
74
  end
74
75
 
@@ -66,6 +66,22 @@ module InspecPlugins
66
66
  InspecPlugins::<%= module_name %>::Reporter
67
67
  end
68
68
  <% end %>
69
+
70
+ <% if activators[:streaming_reporter] %>
71
+ # Define a new Streaming Reporter.
72
+ # The argument here will be used to match against the CLI --reporter option.
73
+ # `--reporter <%= streaming_reporter_name_snake %>` will load your streaming reporter and perform streaming real-time on each passing, failing or pending test.
74
+ streaming_reporter :<%= streaming_reporter_name_snake %> do
75
+ # Calling this activator doesn't mean the reporter is being executed - just
76
+ # that we should be ready to do so. So, load the file that defines the
77
+ # functionality.
78
+ require "<%= plugin_name %>/streaming_reporter"
79
+
80
+ # Having loaded our functionality, return a class that will let the
81
+ # reporting engine tap into it.
82
+ InspecPlugins::<%= module_name %>::StreamingReporter
83
+ end
84
+ <% end %>
69
85
  end
70
86
  end
71
87
  end
@@ -0,0 +1,31 @@
1
+ module InspecPlugins::<%= module_name %>
2
+ # This class will provide the actual Streaming Reporter implementation.
3
+ # Its superclass is provided by another call to Inspec.plugin,
4
+ # this time with two args. The first arg specifies we are requesting
5
+ # version 2 of the Plugins API. The second says we are making a
6
+ # Streaming Reporter plugin component, so please make available any DSL needed
7
+ # for that.
8
+
9
+ class StreamingReporter < Inspec.plugin(2, :streaming_reporter)
10
+
11
+ # Registering these methods with RSpec::Core::Formatters class is mandatory
12
+ RSpec::Core::Formatters.register self, :example_passed, :example_failed, :example_pending
13
+
14
+ def initialize(output)
15
+ @output = output
16
+ end
17
+
18
+ def example_passed(notification) # ExampleNotification
19
+ # some logic to run on passing test case
20
+ end
21
+
22
+ def example_failed(notification) # FailedExampleNotification
23
+ # some logic to run on failing test case
24
+ end
25
+
26
+ def example_pending(notification) # ExampleNotification
27
+ # some logic to run on pending test case
28
+ end
29
+
30
+ end
31
+ end
@@ -6,7 +6,7 @@ copyright_email: you@example.com
6
6
  license: Apache-2.0
7
7
  summary: An InSpec Compliance Profile For AWS
8
8
  version: 0.1.0
9
- inspec_version: '~> 4'
9
+ inspec_version: '~> 5'
10
10
  inputs:
11
11
  - name: aws_vpc_id
12
12
  required: false
@@ -0,0 +1,77 @@
1
+ +++
2
+ title = "<%= resource_name %> resource"
3
+ draft = false
4
+ gh_repo = "inspec"
5
+ platform = "<%= supports_platform %>"
6
+
7
+ [menu]
8
+ [menu.inspec]
9
+ title = "<%= resource_name %>"
10
+ identifier = "inspec/resources/os/<%= resource_name %>.md <%= resource_name %> resource"
11
+ parent = "inspec/resources/os"
12
+ +++
13
+
14
+ Use the `<%= resource_name %>` Chef InSpec audit resource to test the ...
15
+
16
+
17
+ ## Availability
18
+
19
+ ### Installation
20
+
21
+ This resource is distributed along with Chef InSpec itself. You can use it automatically.
22
+
23
+ ## Syntax
24
+
25
+ A `<%= resource_name %>` Chef InSpec audit resource ...
26
+
27
+ describe <%= resource_name %> do
28
+ its('shoe_size') { should cmp 42 }
29
+ it { should be_purple }
30
+ it { should have_bells }
31
+ end
32
+ where
33
+
34
+ - `'shoe_size'` is some property of this resource
35
+ - `42` is the value to test for shoe size
36
+ - `be_purple` is a matcher of this resource
37
+ - `have_bells` is a matcher of this resource
38
+
39
+ ## Properties
40
+
41
+ - Properties of the resources: `shoe_size`
42
+
43
+ ### shoe_size
44
+
45
+ The shoe_size property tests ....
46
+
47
+ ## Matchers
48
+
49
+ For a full list of available matchers, please visit our [matchers page](https://docs.chef.io/inspec/matchers/).
50
+
51
+ The specific matchers of this resource are: `be_purple`, `have_bells`
52
+
53
+ ### be_purple
54
+
55
+ The `be_purple` matcher tests the ...:
56
+
57
+ it { should be_purple }
58
+
59
+ ## Examples
60
+ The following examples show how to use this Chef InSpec audit resource.
61
+
62
+ ### Example 1
63
+
64
+ `shoe_size` returns ...
65
+
66
+ describe <%= resource_name %> do
67
+ its("shoe_size") { should eq 42 }
68
+ end
69
+
70
+ ### Example 2
71
+
72
+ `be_purple` checks for ...
73
+
74
+ describe <%= resource_name %> do
75
+ it { should be_purple }
76
+ end
77
+
@@ -0,0 +1,94 @@
1
+ # Uncomment the below lines to add gems and files required by the resource
2
+ # require ""
3
+ # require_relative ""
4
+
5
+ # Change module if required
6
+ module Inspec::Resources
7
+ # Most custom InSpec resource inherit from a dynamic class, InSpec.resource(1).
8
+ # If you wish to inherit from a core resource, you need to follow special instructions -
9
+ # see https://www.chef.io/blog/extending-inspec-resources-core-resource-inheritance
10
+ class <%= class_name %> < Inspec.resource(1)
11
+ # Every resource requires an internal name.
12
+ name "<%= resource_name %>"
13
+
14
+ # Restrict to only run on the below platforms (if none were given,
15
+ # all OS's and cloud API's supported)
16
+ supports platform: "<%= supports_platform %>"
17
+
18
+ desc "<%= description %>"
19
+
20
+ example <<~EXAMPLE
21
+ describe "<%= resource_name %>" do
22
+ its("shoe_size") { should cmp 10 }
23
+ end
24
+ describe "<%= resource_name %>" do
25
+ it { should be_purple }
26
+ end
27
+ EXAMPLE
28
+
29
+ # Resource initialization. Add any arguments you want to pass to the contructor here.
30
+ # Anything you pass here will be passed to the "describe" call:
31
+ # describe <%= resource_name %>(YOUR_PARAMETERS_HERE) do
32
+ # its("shoe_size") { should cmp 10 }
33
+ # end
34
+ def initialize
35
+ skip_resource "The `<%= resource_name %>` resource is not yet available on your OS." unless inspec.os.<%= supports_platform %>?
36
+ # Initialize required path/params/configs
37
+ end
38
+
39
+ # Define a resource ID. This is used in reporting engines to uniquely identify the individual resource.
40
+ # This might be a file path, or a process ID, or a cloud instance ID. Only meaningful to the implementation.
41
+ # Must be a string. Defaults to the empty string if not implemented.
42
+ def resource_id
43
+ # replace value specific unique to this individual resource instance
44
+ "something special"
45
+ end
46
+
47
+ # Define how you want your resource to appear in test reports. Commonly, this is just the resource name and the resource ID.
48
+ def to_s
49
+ "<%= resource_name %> #{resource_id}"
50
+ end
51
+
52
+ # Define matchers. Matchers are predicates - they return true or false.
53
+ # Matchers also have their names transformed: the question mark is dropped, and
54
+ # the "is_" prefix becomes "be_". A similar transformation happens for "has_" (see below)
55
+ # So this will be called as:
56
+ # describe "<%= resource_name %>" do
57
+ # it { should be_purple }
58
+ # end
59
+ def is_purple?
60
+ # positive or negative expectations specific to this resource instance
61
+ true # Purple is the best color
62
+ end
63
+
64
+ # Define matchers. Matchers are predicates - they return true or false.
65
+ # Matchers also have their names transformed: the question mark is dropped, and
66
+ # the "has_" prefix becomes "have_".
67
+ # So this will be called as:
68
+ # describe "<%= resource_name %>" do
69
+ # it { should have_bells }
70
+ # end
71
+ def has_bells?
72
+ # positive or negative expectations specific to this resource instance
73
+ true # Jingle all the way
74
+ end
75
+
76
+ # Define properties. Properties return values for evaluation against operators.
77
+ # No name transformation occurs. This is called using the "its" facility.
78
+ # So this will be called as:
79
+ # describe "<%= resource_name %>" do
80
+ # its('shoe_size') { should cmp 42 }
81
+ # end
82
+ def shoe_size
83
+ # Implementation of a property specific to this resource
84
+ 42
85
+ end
86
+
87
+ private
88
+
89
+ # Methods to help the resource's public methods
90
+ def helper_method
91
+ # Add anything you need here
92
+ end
93
+ end
94
+ end
@@ -0,0 +1,62 @@
1
+ +++
2
+ title = "<%= resource_name %> resource"
3
+ draft = false
4
+ gh_repo = "inspec"
5
+ platform = "<%= supports_platform %>"
6
+
7
+ [menu]
8
+ [menu.inspec]
9
+ title = "<%= resource_name %>"
10
+ identifier = "inspec/resources/os/<%= resource_name %>.md <%= resource_name %> resource"
11
+ parent = "inspec/resources/os"
12
+ +++
13
+
14
+ Use the `<%= resource_name %>` Chef InSpec audit resource to test multiple ...
15
+
16
+
17
+ ## Availability
18
+
19
+ ### Installation
20
+
21
+ This resource is distributed along with Chef InSpec itself. You can use it automatically.
22
+
23
+ ## Syntax
24
+
25
+ A `<%= resource_name %>` Chef InSpec audit resource tests multiple ...
26
+
27
+ describe <%= resource_name %>.where { shoe_size > 10 } do
28
+ its('count') { should cmp 10 }
29
+ end
30
+
31
+ where
32
+
33
+ - `'shoe_size'` is a filter criteria of this resource
34
+ - `10` is the value to test for shoe size
35
+ - `count` is the count of matched records
36
+
37
+ ## Filter Criteria
38
+
39
+ ### shoe_size
40
+
41
+ The shoe_size filter criteria tests ....
42
+
43
+ ## Properties
44
+
45
+ ### count
46
+
47
+ Returns the number of records matched by the filter criteria.
48
+
49
+ describe <%= resource_name %>.where { shoe_size > 10 } do
50
+ its('count') { should cmp 10 }
51
+ end
52
+
53
+ ## Matchers
54
+
55
+ ### exist
56
+
57
+ The control will pass if the filter returns at least one result. Use
58
+ `should_not` if you expect zero matches.
59
+
60
+ describe <%= resource_name %> do
61
+ it { should exist }
62
+ end
@@ -0,0 +1,73 @@
1
+ # This file was generated by `inspec init resource <%= resource_name %>`
2
+ # using the "--template plural" option. It represents a "plural" (FilterTable-based)
3
+ # InSpec resource.
4
+
5
+ # Plural resources query multiple resources of the same type in bulk. For details of the
6
+ # differences between singular and plural resources, please see:
7
+ # https://www.chef.io/blog/understanding-singular-and-plural-inspec-resources
8
+
9
+ # Plural resources rely on the FilterTable facility to handle data lookup and querying.
10
+ # For details on Filtertable and how to use it effectively within your resource, please see
11
+ # https://github.com/inspec/inspec/blob/main/dev-docs/filtertable-usage.md
12
+ # Consider that page required reading for authoring plural resources.
13
+
14
+ # Uncomment the below lines to add gems and files required by the resource
15
+ # require "inspec/utils/filter"
16
+ # require_relative ""
17
+
18
+ # Include FilterTable support
19
+ require "inspec/utils/filter"
20
+
21
+ module Inspec::Resources
22
+ # Most custom InSpec resource inherit from a dynamic class, InSpec.resource(1).
23
+ # If you wish to inherit from a core resource, you need to follow special instructions -
24
+ # see https://www.chef.io/blog/extending-inspec-resources-core-resource-inheritance
25
+ class <%= class_name %> < Inspec.resource(1)
26
+ # Every resource requires an internal name.
27
+ name "<%= resource_name %>"
28
+
29
+ # Restrict to only run on the below platforms (if none were given,
30
+ # all OS's and cloud API's supported)
31
+ supports platform: "<%= supports_platform %>"
32
+
33
+ desc "<%= description %>"
34
+
35
+ example <<~EXAMPLE
36
+ describe <%= resource_name %>.where{ shoe_size > 10 } do
37
+ its("count") { should cmp 0 }
38
+ end
39
+ EXAMPLE
40
+
41
+ # Resource initialization. Add any arguments you want to pass to the contructor here.
42
+ # Anything you pass here will be passed to the "describe" call:
43
+ # describe <%= resource_name %>(YOUR_PARAMETERS_HERE) do
44
+ # its("shoe_size") { should cmp 10 }
45
+ # end
46
+ def initialize
47
+ # Initialize required path/params/configs
48
+ end
49
+
50
+ # Define the FilterTable. This will define many extra methods on your resource, including
51
+ # where(), count(), and a property for every column.
52
+ table = FilterTable.create
53
+ table.register_column(:names, field: :name, style: :simple)
54
+ .register_column(:shoe_sizes, field: :shoe_size)
55
+ .install_filter_methods_on_resource(self, :fetch_data)
56
+
57
+ # Plural resources do not generally define a resource_id.
58
+
59
+ # Define how you want your resource to appear in test reports. Commonly, this is just the resource name for plural resources.
60
+ def to_s
61
+ "<%= resource_name %>"
62
+ end
63
+
64
+ # Do whatever you need to do to fetch the underlying data.
65
+ # Return it as an array of hashes.
66
+ def fetch_data
67
+ [
68
+ { name: "Bob", shoe_size: 9 },
69
+ { name: "Alice", shoe_size: 8 },
70
+ ]
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,10 @@
1
+ # .gemspec file is added to add plugin details
2
+ # These specs are used in plugin list and search command
3
+
4
+ Gem::Specification.new do |spec|
5
+ spec.name = "inspec-plugin-manager-cli"
6
+ spec.summary = "CLI plugin for InSpec"
7
+ spec.description = "This is a CLI plugin for InSpec. It uses the Plugins API v2 to create a
8
+ series of commands to manage plugins."
9
+ spec.license = "Apache-2.0"
10
+ end
@@ -41,13 +41,14 @@ module InspecPlugins
41
41
 
42
42
  unless plugin_statuses.empty?
43
43
  ui.table do |t|
44
- t.header = ["Plugin Name", "Version", "Via", "ApiVer"]
44
+ t.header = ["Plugin Name", "Version", "Via", "ApiVer", "Description"]
45
45
  plugin_statuses.sort_by { |s| s.name.to_s }.each do |status|
46
46
  t << [
47
47
  status.name,
48
48
  make_pretty_version(status),
49
49
  make_pretty_install_type(status),
50
50
  status.api_generation,
51
+ status.description,
51
52
  ]
52
53
  end
53
54
  end
@@ -83,14 +84,15 @@ module InspecPlugins
83
84
  end
84
85
 
85
86
  puts
86
- ui.bold(format(" %-30s%-50s\n", "Plugin Name", "Versions Available"))
87
- ui.line
87
+ ui.bold(format(" %-30s%-30s%-20s\n", "Plugin Name", "Versions Available", "Description"))
88
+ ui.line_with_width(100)
88
89
  search_results.keys.sort.each do |plugin_name|
89
- versions = options[:all] ? search_results[plugin_name] : [search_results[plugin_name].first]
90
+ versions = options[:all] ? search_results[plugin_name]["versions"] : [search_results[plugin_name]["versions"].first]
90
91
  versions = "(" + versions.join(", ") + ")"
91
- ui.plain_line(format(" %-30s%-50s", plugin_name, versions))
92
+ description = search_results[plugin_name]["description"]
93
+ ui.plain_line(format(" %-30s%-30s%-20s", plugin_name, versions, description))
92
94
  end
93
- ui.line
95
+ ui.line_with_width(100)
94
96
  ui.plain_line(" #{search_results.count} plugin(s) found")
95
97
  puts
96
98
 
@@ -381,9 +383,11 @@ module InspecPlugins
381
383
  # Do an expensive search to determine the latest version.
382
384
  unless requested_version
383
385
  latest_version = installer.search(plugin_name, exact: true, scope: :latest)
384
- latest_version = latest_version[plugin_name]&.last
385
- if latest_version && !requested_version
386
- requested_version = latest_version
386
+ if latest_version[plugin_name]
387
+ latest_version = latest_version[plugin_name]["versions"]&.last
388
+ if latest_version && !requested_version
389
+ requested_version = latest_version
390
+ end
387
391
  end
388
392
  end
389
393
 
@@ -429,7 +433,7 @@ module InspecPlugins
429
433
  if results.empty?
430
434
  ui.red("No such plugin gem #{plugin_name} could be found on " \
431
435
  "#{source_host} - installation failed.\n")
432
- elsif options[:version] && !results[plugin_name].include?(options[:version])
436
+ elsif options[:version] && results[plugin_name] && !results[plugin_name]["versions"].include?(options[:version])
433
437
  ui.red("No such version - #{plugin_name} exists, but no such " \
434
438
  "version #{options[:version]} found on #{source_host} - " \
435
439
  "installation failed.\n")
@@ -460,7 +464,7 @@ module InspecPlugins
460
464
 
461
465
  # Check for latest version (and implicitly, existence)
462
466
  latest_version = installer.search(plugin_name, exact: true, scope: :latest)
463
- latest_version = latest_version[plugin_name]&.last
467
+ latest_version = latest_version[plugin_name] ? latest_version[plugin_name]["versions"]&.last : nil
464
468
 
465
469
  if pre_update_versions.include?(latest_version)
466
470
  ui.plain_line("#{ui.bold("Already installed at latest version:", print: false)} " \
@@ -0,0 +1,9 @@
1
+ # .gemspec file is added to add plugin details
2
+ # These specs are used in plugin list and search command
3
+
4
+ Gem::Specification.new do |spec|
5
+ spec.name = "inspec-reporter-html2"
6
+ spec.summary = "Improved HTML reporter plugin"
7
+ spec.description = "An improved HTML output reporter specifically for Chef InSpec. Unlike the default html reporter, which is RSpec-based, this reporter knows about Chef InSpec structures like Controls and Profiles, and includes full metadata such as control tags, etc."
8
+ spec.license = "Apache-2.0"
9
+ end
@@ -26,12 +26,14 @@
26
26
 
27
27
  <div class="inspec-summary">
28
28
  <table id="platform" class="info">
29
+ <caption>Platform Information</caption>
29
30
  <tr><th colspan=2><h4 id="platform-label">Platform Information</h4></th></tr>
30
31
  <tr class= "name"><th>Name:</th><td><%= run_data.platform.name %></td></tr>
31
32
  <tr class= "release"><th>Release:</th><td><%= run_data.platform.release %></td></tr>
32
33
  <tr class= "target"><th>Target:</th><td><%= run_data.platform.target %></td></tr>
33
34
  </table>
34
35
  <table id="statistics" class="info">
36
+ <caption>Control Statistics</caption>
35
37
  <tr><th colspan="2"><h4 id="statistics-label">Control Statistics</h4></th></tr>
36
38
  <tr class= "passed"><th>Passed:</th><td><%= run_data.statistics.controls.passed.total %></td></tr>
37
39
  <tr class= "skipped"><th>Skipped:</th><td><%= run_data.statistics.controls.skipped.total %></td></tr>
@@ -26,6 +26,7 @@
26
26
 
27
27
  <h3 class="control-title">Control <code><%= control.id %></code></h3>
28
28
  <table class="control-metadata info" id="control-metadata-<%= slugged_id %>">
29
+ <caption>Control Table</caption>
29
30
  <tr class="status status-<%= status %>"><th>Status:</th><td><div><%= status.capitalize %></div></td></tr>
30
31
  <% if control.title %><tr class="title"><th>Title:</th><td><%= control.title %></td></tr> <% end %>
31
32
  <% if control.desc %><tr class="desc"><th>Description:</th><td><%= control.desc %></td></tr> <% end %>
@@ -35,6 +36,8 @@
35
36
  <th>Tags:</th>
36
37
  <td>
37
38
  <table class="tags">
39
+ <caption>Tag Table</caption>
40
+ <tr><th>Tag Name</th><th>Tag Text</th></tr>
38
41
  <% control.tags.each do |tag_name, tag_text| %>
39
42
  <tr><td><%= tag_name %></td><td><%= tag_text %></td></tr>
40
43
  <% end %>