inspec-core 4.56.58 → 5.7.9
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +24 -9
- data/etc/deprecations.json +12 -11
- data/inspec-core.gemspec +3 -5
- data/lib/inspec/base_cli.rb +14 -2
- data/lib/inspec/cli.rb +16 -7
- data/lib/inspec/dependencies/dependency_set.rb +2 -6
- data/lib/inspec/dependency_installer.rb +74 -0
- data/lib/inspec/dependency_loader.rb +97 -0
- data/lib/inspec/dsl.rb +16 -23
- data/lib/inspec/env_printer.rb +1 -1
- data/lib/inspec/errors.rb +7 -0
- data/lib/inspec/fetcher/git.rb +28 -43
- data/lib/inspec/fetcher/url.rb +1 -1
- data/lib/inspec/formatters/base.rb +22 -0
- data/lib/inspec/metadata.rb +36 -0
- data/lib/inspec/plugin/v2/plugin_types/streaming_reporter.rb +44 -1
- data/lib/inspec/profile.rb +81 -29
- data/lib/inspec/reporters/automate.rb +1 -1
- data/lib/inspec/reporters/cli.rb +1 -1
- data/lib/inspec/reporters/json.rb +31 -11
- data/lib/inspec/resource.rb +6 -0
- data/lib/inspec/resources/cassandradb_session.rb +3 -4
- data/lib/inspec/resources/cron.rb +49 -0
- data/lib/inspec/resources/file.rb +1 -1
- data/lib/inspec/resources/ibmdb2_session.rb +3 -4
- data/lib/inspec/resources/ipfilter.rb +59 -0
- data/lib/inspec/resources/ipnat.rb +58 -0
- data/lib/inspec/resources/mongodb_session.rb +1 -7
- data/lib/inspec/resources/oracledb_session.rb +7 -20
- data/lib/inspec/resources/postgres_session.rb +5 -7
- data/lib/inspec/resources/processes.rb +4 -6
- data/lib/inspec/resources/service.rb +2 -4
- data/lib/inspec/resources.rb +3 -16
- data/lib/inspec/rule.rb +1 -1
- data/lib/inspec/runner.rb +18 -1
- data/lib/inspec/runner_rspec.rb +15 -0
- data/lib/inspec/schema/exec_json.rb +59 -58
- data/lib/inspec/schema/exec_json_min.rb +16 -16
- data/lib/inspec/schema/primitives.rb +68 -51
- data/lib/inspec/schema/profile_json.rb +27 -27
- data/lib/inspec/schema.rb +1 -0
- data/lib/inspec/secrets/yaml.rb +1 -7
- data/lib/inspec/ui.rb +1 -0
- data/lib/inspec/utils/deprecated_cloud_resources_list.rb +54 -0
- data/lib/inspec/version.rb +1 -1
- data/lib/inspec.rb +3 -0
- data/lib/matchers/matchers.rb +1 -7
- data/lib/plugins/inspec-init/lib/inspec-init/cli.rb +1 -0
- data/lib/plugins/inspec-init/lib/inspec-init/cli_plugin.rb +9 -0
- data/lib/plugins/inspec-init/lib/inspec-init/cli_resource.rb +126 -0
- data/lib/plugins/inspec-init/lib/inspec-init/renderer.rb +9 -8
- data/lib/plugins/inspec-init/templates/plugins/inspec-plugin-template/lib/inspec-plugin-template/plugin.erb +16 -0
- data/lib/plugins/inspec-init/templates/plugins/inspec-plugin-template/lib/inspec-plugin-template/streaming_reporter.erb +31 -0
- data/lib/plugins/inspec-init/templates/profiles/aws/inspec.yml +1 -1
- data/lib/plugins/inspec-init/templates/resources/basic/docs/resource-doc.erb +77 -0
- data/lib/plugins/inspec-init/templates/resources/basic/libraries/inspec-resource-template.erb +94 -0
- data/lib/plugins/inspec-init/templates/resources/plural/docs/resource-doc.erb +62 -0
- data/lib/plugins/inspec-init/templates/resources/plural/libraries/inspec-resource-template.erb +73 -0
- data/lib/plugins/inspec-reporter-html2/templates/body.html.erb +6 -4
- data/lib/plugins/inspec-reporter-html2/templates/control.html.erb +4 -1
- data/lib/plugins/inspec-reporter-html2/templates/profile.html.erb +2 -1
- data/lib/plugins/inspec-reporter-html2/templates/result.html.erb +1 -0
- data/lib/plugins/inspec-streaming-reporter-progress-bar/README.md +5 -0
- data/lib/plugins/inspec-streaming-reporter-progress-bar/lib/inspec-streaming-reporter-progress-bar/plugin.rb +13 -0
- data/lib/plugins/inspec-streaming-reporter-progress-bar/lib/inspec-streaming-reporter-progress-bar/streaming_reporter.rb +112 -0
- data/lib/plugins/inspec-streaming-reporter-progress-bar/lib/inspec-streaming-reporter-progress-bar/version.rb +8 -0
- data/lib/plugins/inspec-streaming-reporter-progress-bar/lib/inspec-streaming-reporter-progress-bar.rb +15 -0
- metadata +24 -7
@@ -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.
|
61
|
-
|
62
|
-
|
63
|
-
|
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
|
@@ -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
|
data/lib/plugins/inspec-init/templates/resources/plural/libraries/inspec-resource-template.erb
ADDED
@@ -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
|
@@ -7,31 +7,33 @@
|
|
7
7
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
8
8
|
<style type="text/css">
|
9
9
|
/* Must inline all CSS files, this is a single-file output that may be airgapped */
|
10
|
-
<%= ERB.new(File.read(css_path),
|
10
|
+
<%= ERB.new(File.read(css_path), nil, nil, "_css").result(binding) %>
|
11
11
|
</style>
|
12
12
|
<script type="text/javascript">
|
13
13
|
// <![CDATA[
|
14
14
|
/* Must inline all JavaScript files, this is a single-file output that may be airgapped */
|
15
|
-
<%= ERB.new(File.read(js_path),
|
15
|
+
<%= ERB.new(File.read(js_path), nil, nil, "_js").result(binding) %>
|
16
16
|
// ]]>
|
17
17
|
</script>
|
18
18
|
</head>
|
19
19
|
<body onload="pageLoaded()">
|
20
|
-
<%= ERB.new(File.read(template_path + "/selector.html.erb"),
|
20
|
+
<%= ERB.new(File.read(template_path + "/selector.html.erb"), nil, nil, "_select").result(binding) %>
|
21
21
|
<div class="inspec-report">
|
22
22
|
<h1><%= Inspec::Dist::PRODUCT_NAME %> Report</h1>
|
23
23
|
<% run_data.profiles.each do |profile| %>
|
24
|
-
<%= ERB.new(File.read(template_path + "/profile.html.erb"),
|
24
|
+
<%= ERB.new(File.read(template_path + "/profile.html.erb"), nil, nil, "_prof").result(binding) %>
|
25
25
|
<% end %>
|
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 %>
|
@@ -71,7 +74,7 @@
|
|
71
74
|
</table>
|
72
75
|
|
73
76
|
<% control.results.each do |result| %>
|
74
|
-
<%= ERB.new(File.read(template_path + "/result.html.erb"),
|
77
|
+
<%= ERB.new(File.read(template_path + "/result.html.erb"), nil, nil, "_rslt").result(binding) %>
|
75
78
|
<% end %>
|
76
79
|
|
77
80
|
</div>
|
@@ -3,6 +3,7 @@
|
|
3
3
|
<h2 class="profile_title">Profile <%= display_name %> (<%= profile.name %>)</h2>
|
4
4
|
|
5
5
|
<table class="profile-metadata info" id="profile-metadata-<%= profile.name %>">
|
6
|
+
<caption>Profile Information Table</caption>
|
6
7
|
<tr class="profile-version"><th>Version:</th><td><%= profile.version %></td></tr>
|
7
8
|
<% if profile.summary %>
|
8
9
|
<tr class="profile-summary"><th>Summary:</th><td><%= profile.summary %></td></tr>
|
@@ -17,7 +18,7 @@
|
|
17
18
|
|
18
19
|
<% if profile.status == "loaded" %>
|
19
20
|
<% profile.controls.each do |control| %>
|
20
|
-
<%= ERB.new(File.read(template_path + "/control.html.erb"),
|
21
|
+
<%= ERB.new(File.read(template_path + "/control.html.erb"), nil, nil, "_ctl").result(binding) %>
|
21
22
|
<% end %>
|
22
23
|
<% end %>
|
23
24
|
</div>
|
@@ -2,6 +2,7 @@
|
|
2
2
|
<div class="result" id="result-<%= slugged_id %>">
|
3
3
|
<h4 class="resource-title">Resource <code><%= result.resource_title.to_s %></code></h4>
|
4
4
|
<table class="result-metadata info">
|
5
|
+
<caption>Result Information Table</caption>
|
5
6
|
<tr class="expectation_message"><th>Test:</th><td><code><%= result.expectation_message %></code></td></tr>
|
6
7
|
<tr class="status status-<%= result.status %>"><th>Status:</th><td><div><%= result.status.capitalize %></div></td></tr>
|
7
8
|
<% if result.status == "failed" %>
|
@@ -0,0 +1,5 @@
|
|
1
|
+
# StreamingReporterProgressBar Plugin
|
2
|
+
|
3
|
+
## What This Plugin Does
|
4
|
+
|
5
|
+
This plugin is a streaming reporter plugin which shows the real-time progress of a running InSpec profile using a progress bar. It also outputs the ID of a running control with an indicator showing if the control has passed, failed or skipped.
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require "inspec-streaming-reporter-progress-bar/version"
|
2
|
+
|
3
|
+
module InspecPlugins
|
4
|
+
module StreamingReporterProgressBar
|
5
|
+
class Plugin < ::Inspec.plugin(2)
|
6
|
+
plugin_name :"inspec-streaming-reporter-progress-bar"
|
7
|
+
streaming_reporter :"progress-bar" do
|
8
|
+
require "inspec-streaming-reporter-progress-bar/streaming_reporter"
|
9
|
+
InspecPlugins::StreamingReporterProgressBar::StreamingReporter
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|