inspec-core 3.5.0 → 3.6.2
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.
- checksums.yaml +4 -4
- data/etc/deprecations.json +9 -0
- data/lib/bundles/inspec-supermarket/cli.rb +1 -1
- data/lib/inspec/backend.rb +9 -8
- data/lib/inspec/base_cli.rb +12 -170
- data/lib/inspec/cli.rb +17 -16
- data/lib/inspec/config.rb +391 -0
- data/lib/inspec/control_eval_context.rb +2 -1
- data/lib/inspec/dsl.rb +2 -2
- data/lib/inspec/errors.rb +5 -0
- data/lib/inspec/plugin/v1/plugin_types/resource.rb +1 -1
- data/lib/inspec/plugin/v2/activator.rb +24 -3
- data/lib/inspec/plugin/v2/loader.rb +1 -1
- data/lib/inspec/plugin/v2/registry.rb +8 -12
- data/lib/inspec/profile.rb +3 -2
- data/lib/inspec/profile_vendor.rb +2 -1
- data/lib/inspec/rspec_extensions.rb +2 -2
- data/lib/inspec/runner.rb +5 -5
- data/lib/inspec/shell.rb +1 -1
- data/lib/inspec/ui.rb +2 -2
- data/lib/inspec/version.rb +1 -1
- data/lib/plugins/inspec-habitat/lib/inspec-habitat/profile.rb +1 -1
- data/lib/plugins/inspec-init/lib/inspec-init/cli.rb +3 -28
- data/lib/plugins/inspec-init/lib/inspec-init/cli_plugin.rb +245 -0
- data/lib/plugins/inspec-init/lib/inspec-init/cli_profile.rb +49 -0
- data/lib/plugins/inspec-init/lib/inspec-init/renderer.rb +43 -31
- data/lib/plugins/inspec-init/templates/plugins/inspec-plugin-template/Gemfile +12 -0
- data/lib/plugins/inspec-init/templates/plugins/inspec-plugin-template/LICENSE +2 -0
- data/lib/plugins/inspec-init/templates/plugins/inspec-plugin-template/README.md +28 -0
- data/lib/plugins/inspec-init/templates/plugins/inspec-plugin-template/Rakefile +40 -0
- data/lib/plugins/inspec-init/templates/plugins/inspec-plugin-template/inspec-plugin-template.gemspec +45 -0
- data/lib/plugins/inspec-init/templates/plugins/inspec-plugin-template/lib/inspec-plugin-template.rb +16 -0
- data/lib/plugins/inspec-init/templates/plugins/inspec-plugin-template/lib/inspec-plugin-template/cli_command.rb +64 -0
- data/lib/plugins/inspec-init/templates/plugins/inspec-plugin-template/lib/inspec-plugin-template/plugin.rb +55 -0
- data/lib/plugins/inspec-init/templates/plugins/inspec-plugin-template/lib/inspec-plugin-template/version.rb +10 -0
- data/lib/plugins/inspec-init/templates/plugins/inspec-plugin-template/test/fixtures/README.md +24 -0
- data/lib/plugins/inspec-init/templates/plugins/inspec-plugin-template/test/functional/README.md +12 -0
- data/lib/plugins/inspec-init/templates/plugins/inspec-plugin-template/test/functional/inspec_plugin_template_test.rb +110 -0
- data/lib/plugins/inspec-init/templates/plugins/inspec-plugin-template/test/helper.rb +26 -0
- data/lib/plugins/inspec-init/templates/plugins/inspec-plugin-template/test/unit/README.md +17 -0
- data/lib/plugins/inspec-init/templates/plugins/inspec-plugin-template/test/unit/cli_args_test.rb +67 -0
- data/lib/plugins/inspec-init/templates/plugins/inspec-plugin-template/test/unit/plugin_def_test.rb +51 -0
- data/lib/plugins/inspec-init/{lib/inspec-init/templates → templates}/profiles/os/README.md +0 -0
- data/lib/plugins/inspec-init/{lib/inspec-init/templates → templates}/profiles/os/controls/example.rb +0 -0
- data/lib/plugins/inspec-init/{lib/inspec-init/templates → templates}/profiles/os/inspec.yml +0 -0
- data/lib/plugins/inspec-init/{lib/inspec-init/templates → templates}/profiles/os/libraries/.gitkeep +0 -0
- data/lib/plugins/inspec-init/test/functional/inspec_init_plugin_test.rb +173 -0
- data/lib/plugins/inspec-init/test/functional/{inspec_init_test.rb → inspec_init_profile_test.rb} +7 -7
- data/lib/resources/filesystem.rb +40 -12
- metadata +31 -11
@@ -0,0 +1,49 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'pathname'
|
4
|
+
require_relative 'renderer'
|
5
|
+
|
6
|
+
module InspecPlugins
|
7
|
+
module Init
|
8
|
+
class CLI < Inspec.plugin(2, :cli_command)
|
9
|
+
#-------------------------------------------------------------------#
|
10
|
+
# inspec init profile
|
11
|
+
#-------------------------------------------------------------------#
|
12
|
+
def self.valid_profile_platforms
|
13
|
+
# Look in the 'template/profiles' directory and detect which platforms are available.
|
14
|
+
profile_templates_dir = File.join(TEMPLATES_PATH, 'profiles')
|
15
|
+
Dir.glob(File.join(profile_templates_dir, '*')).select { |p| File.directory?(p) }.map { |d| File.basename(d) }
|
16
|
+
end
|
17
|
+
|
18
|
+
no_commands do
|
19
|
+
def valid_profile_platforms
|
20
|
+
self.class.valid_profile_platforms
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
desc 'profile [OPTIONS] NAME', 'Generate a new profile'
|
25
|
+
option :platform, default: 'os', type: :string, aliases: [:p],
|
26
|
+
desc: "Which platform to generate a profile for: choose from #{valid_profile_platforms.join(', ')}"
|
27
|
+
option :overwrite, type: :boolean, default: false,
|
28
|
+
desc: 'Overwrites existing directory'
|
29
|
+
def profile(new_profile_name)
|
30
|
+
unless valid_profile_platforms.include?(options[:platform])
|
31
|
+
ui.error "Unable to generate profile: No template available for platform '#{options[:platform]}' (expected one of: #{valid_profile_platforms.join(', ')})"
|
32
|
+
ui.exit(:usage_error)
|
33
|
+
end
|
34
|
+
template_path = File.join('profiles', options[:platform])
|
35
|
+
|
36
|
+
render_opts = {
|
37
|
+
templates_path: TEMPLATES_PATH,
|
38
|
+
overwrite: options[:overwrite],
|
39
|
+
}
|
40
|
+
renderer = InspecPlugins::Init::Renderer.new(ui, render_opts)
|
41
|
+
|
42
|
+
vars = {
|
43
|
+
name: new_profile_name,
|
44
|
+
}
|
45
|
+
renderer.render_with_values(template_path, 'profile', vars)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -7,58 +7,70 @@ module InspecPlugins
|
|
7
7
|
# Creates a renderer able to render the given template type
|
8
8
|
# 1. iterate over all files
|
9
9
|
# 2. read content in erb
|
10
|
-
# 3. write to
|
10
|
+
# 3. write to destination path
|
11
11
|
|
12
|
-
attr_reader :overwrite_mode, :ui
|
13
|
-
def initialize(cli_ui,
|
12
|
+
attr_reader :file_rename_map, :overwrite_mode, :skip_files, :templates_path, :ui
|
13
|
+
def initialize(cli_ui, options = {})
|
14
14
|
@ui = cli_ui
|
15
|
-
@overwrite_mode =
|
15
|
+
@overwrite_mode = options[:overwrite]
|
16
|
+
@templates_path ||= options[:templates_path]
|
17
|
+
@file_rename_map = options[:file_rename_map] || {}
|
18
|
+
@skip_files = options[:skip_files] || []
|
16
19
|
end
|
17
20
|
|
18
21
|
# rubocop: disable Metrics/AbcSize
|
19
|
-
def render_with_values(template_subdir_path, template_values = {})
|
22
|
+
def render_with_values(template_subdir_path, template_type, template_values = {})
|
20
23
|
# look for template directory
|
21
|
-
|
24
|
+
source_dir = File.join(templates_path, template_subdir_path)
|
25
|
+
|
22
26
|
# prepare glob for all subdirectories and files
|
23
|
-
template_glob = File.join(
|
24
|
-
|
25
|
-
|
26
|
-
#
|
27
|
-
|
28
|
-
|
29
|
-
#
|
30
|
-
|
27
|
+
template_glob = File.join(source_dir, '**', '{*,.*}')
|
28
|
+
|
29
|
+
# Use the name attribute to define the path to the new thing.
|
30
|
+
# May contain slashes.
|
31
|
+
relative_destination_path = template_values[:name]
|
32
|
+
|
33
|
+
# Now reset the :name variable to be the basename.
|
34
|
+
# This is important in profiles, for example.
|
35
|
+
template_values[:name] = File.basename(template_values[:name])
|
31
36
|
|
32
|
-
#
|
33
|
-
|
34
|
-
ui.plain_text "Create new #{generator_type} at #{ui.mark_text(full_destination_root_path)}"
|
37
|
+
# Generate the full full_destination_path path on disk
|
38
|
+
full_destination_path = Pathname.new(Dir.pwd).join(relative_destination_path)
|
35
39
|
|
36
40
|
# check that the directory does not exist
|
37
|
-
if File.exist?(
|
38
|
-
ui.
|
39
|
-
ui.exit(
|
41
|
+
if File.exist?(full_destination_path) && !overwrite_mode
|
42
|
+
ui.plain_line "#{ui.emphasis(full_destination_path)} exists already, use --overwrite"
|
43
|
+
ui.exit(:usage_error)
|
40
44
|
end
|
41
45
|
|
46
|
+
ui.headline('InSpec Code Generator')
|
47
|
+
|
48
|
+
ui.plain_line "Creating new #{template_type} at #{ui.emphasis(full_destination_path)}"
|
49
|
+
|
42
50
|
# ensure that full_destination_root_path directory is available
|
43
|
-
FileUtils.mkdir_p(
|
51
|
+
FileUtils.mkdir_p(full_destination_path)
|
44
52
|
|
45
|
-
# iterate over files and write to
|
46
|
-
Dir.glob(template_glob) do |
|
47
|
-
relative_destination_item_path = Pathname.new(
|
48
|
-
|
49
|
-
|
50
|
-
|
53
|
+
# iterate over files and write to full_destination_path
|
54
|
+
Dir.glob(template_glob) do |source_file|
|
55
|
+
relative_destination_item_path = Pathname.new(source_file).relative_path_from(Pathname.new(source_dir)).to_s
|
56
|
+
next if skip_files.include? relative_destination_item_path
|
57
|
+
relative_destination_item_path = file_rename_map[relative_destination_item_path] || relative_destination_item_path
|
58
|
+
full_destination_item_path = Pathname.new(full_destination_path).join(relative_destination_item_path)
|
59
|
+
if File.directory?(source_file)
|
60
|
+
ui.list_item "Creating directory #{ui.emphasis(relative_destination_item_path)}"
|
51
61
|
FileUtils.mkdir_p(full_destination_item_path)
|
52
|
-
elsif File.file?(
|
53
|
-
ui.
|
62
|
+
elsif File.file?(source_file)
|
63
|
+
ui.list_item "Creating file #{ui.emphasis(relative_destination_item_path)}"
|
54
64
|
# read & render content
|
55
|
-
content = render(File.read(
|
65
|
+
content = render(File.read(source_file), template_values)
|
56
66
|
# write file content
|
57
67
|
File.write(full_destination_item_path, content)
|
58
68
|
else
|
59
|
-
ui.
|
69
|
+
ui.warning "Ignoring #{ui.emphasis(source_file)}, because its not an file or directoy"
|
60
70
|
end
|
61
71
|
end
|
72
|
+
|
73
|
+
ui.plain_line
|
62
74
|
end
|
63
75
|
# rubocop: enable Metrics/AbcSize
|
64
76
|
|
@@ -0,0 +1,12 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
source 'https://rubygems.org'
|
3
|
+
|
4
|
+
gemspec
|
5
|
+
|
6
|
+
group :development do
|
7
|
+
gem 'bundler'
|
8
|
+
gem 'byebug'
|
9
|
+
gem 'minitest'
|
10
|
+
gem 'rake'
|
11
|
+
gem 'rubocop', '= 0.49.1' # Need to keep in sync with main InSpec project, so config files will work
|
12
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# <%= module_name %> Plugin
|
2
|
+
|
3
|
+
This plugin was generated by `inspec init plugin`, and apparently the author, '<%= author_name %>', did not update the README.
|
4
|
+
|
5
|
+
## To Install This Plugin
|
6
|
+
|
7
|
+
Assuming it has been published to RubyGems, you can install this gem using:
|
8
|
+
|
9
|
+
```
|
10
|
+
you@machine $ inspec plugin install <%= plugin_name %>
|
11
|
+
```
|
12
|
+
|
13
|
+
## What This Plugin Does
|
14
|
+
|
15
|
+
No idea.
|
16
|
+
|
17
|
+
## Developing This Plugin
|
18
|
+
|
19
|
+
The generated plugin contains everything a real-world, industrial grade plugin would have, including:
|
20
|
+
|
21
|
+
* an (possibly incomplete) implementation of one or more InSpec Plugin Types
|
22
|
+
* documentation (you are reading it now)
|
23
|
+
* tests, at the unit and functional level
|
24
|
+
* a .gemspec, for packaging and publishing it as a gem
|
25
|
+
* a Gemfile, for managing its dependencies
|
26
|
+
* a Rakefile, for running development tasks
|
27
|
+
* Rubocop linting support for using the base InSpec project rubocop.yml (See Rakefile)
|
28
|
+
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# A Rakefile defines tasks to help maintain your project.
|
2
|
+
# Rake provides several task templates that are useful.
|
3
|
+
|
4
|
+
#------------------------------------------------------------------#
|
5
|
+
# Test Runner Tasks
|
6
|
+
#------------------------------------------------------------------#
|
7
|
+
|
8
|
+
# This task template will make a task named 'test', and run
|
9
|
+
# the tests that it finds.
|
10
|
+
require 'rake/testtask'
|
11
|
+
|
12
|
+
Rake::TestTask.new do |t|
|
13
|
+
t.libs.push 'lib'
|
14
|
+
t.test_files = FileList[
|
15
|
+
'test/unit/*_test.rb',
|
16
|
+
'test/functional/*_test.rb',
|
17
|
+
]
|
18
|
+
t.verbose = true
|
19
|
+
# Ideally, we'd run tests with warnings enabled,
|
20
|
+
# but the dependent gems have many warnings. As this
|
21
|
+
# is an example, let's disable them so the testing
|
22
|
+
# experience is cleaner.
|
23
|
+
t.warning = false
|
24
|
+
end
|
25
|
+
|
26
|
+
#------------------------------------------------------------------#
|
27
|
+
# Code Style Tasks
|
28
|
+
#------------------------------------------------------------------#
|
29
|
+
require 'rubocop/rake_task'
|
30
|
+
|
31
|
+
RuboCop::RakeTask.new(:lint) do |t|
|
32
|
+
# Choices of RuboCop rules to enforce are deeply personal.
|
33
|
+
# Here, we set things up so that your plugin will use the Bundler-installed
|
34
|
+
# inspec gem's copy of the InSpec project's rubocop.yml file (which
|
35
|
+
# is indeed packaged with the inspec gem).
|
36
|
+
require 'inspec/globals'
|
37
|
+
inspec_rubocop_yml = File.join(Inspec.src_root, '.rubocop.yml')
|
38
|
+
|
39
|
+
t.options = ['--display-cop-names', '--config', inspec_rubocop_yml]
|
40
|
+
end
|
data/lib/plugins/inspec-init/templates/plugins/inspec-plugin-template/inspec-plugin-template.gemspec
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
# As plugins are usually packaged and distributed as a RubyGem,
|
4
|
+
# we have to provide a .gemspec file, which controls the gembuild
|
5
|
+
# and publish process. This is a fairly generic gemspec.
|
6
|
+
|
7
|
+
# It is traditional in a gemspec to dynamically load the current version
|
8
|
+
# from a file in the source tree. The next three lines make that happen.
|
9
|
+
lib = File.expand_path('../lib', __FILE__)
|
10
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
11
|
+
require '<%= plugin_name %>/version'
|
12
|
+
|
13
|
+
Gem::Specification.new do |spec|
|
14
|
+
# Importantly, all InSpec plugins must be prefixed with `inspec-` (most
|
15
|
+
# plugins) or `train-` (plugins which add new connectivity features).
|
16
|
+
spec.name = '<%= plugin_name %>'
|
17
|
+
|
18
|
+
# It is polite to namespace your plugin under InspecPlugins::YourPluginInCamelCase
|
19
|
+
spec.version = InspecPlugins::<%= module_name %>::VERSION
|
20
|
+
spec.authors = ['<%= author_name %>']
|
21
|
+
spec.email = ['<%= author_email %>']
|
22
|
+
spec.summary = '<%= summary %>'
|
23
|
+
spec.description = '<%= description %>'
|
24
|
+
spec.homepage = '<%= homepage %>'
|
25
|
+
spec.license = '<%= license_name %>'
|
26
|
+
|
27
|
+
# Though complicated-looking, this is pretty standard for a gemspec.
|
28
|
+
# It just filters what will actually be packaged in the gem (leaving
|
29
|
+
# out tests, etc)
|
30
|
+
spec.files = %w{
|
31
|
+
README.md <%= snake_case %>.gemspec Gemfile
|
32
|
+
} + Dir.glob(
|
33
|
+
'lib/**/*', File::FNM_DOTMATCH
|
34
|
+
).reject { |f| File.directory?(f) }
|
35
|
+
spec.require_paths = ['lib']
|
36
|
+
|
37
|
+
# If you rely on any other gems, list them here with any constraints.
|
38
|
+
# This is how `inspec plugin install` is able to manage your dependencies.
|
39
|
+
# For example, perhaps you are writing a thing that talks to AWS, and you
|
40
|
+
# want to ensure you have `aws-sdk` in a certain version.
|
41
|
+
|
42
|
+
# All plugins should mention inspec, > 2.2.78
|
43
|
+
# 2.2.78 included the v2 Plugin API
|
44
|
+
spec.add_dependency 'inspec', '>=2.2.78', '<4.0.0'
|
45
|
+
end
|
data/lib/plugins/inspec-init/templates/plugins/inspec-plugin-template/lib/inspec-plugin-template.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
# This file is known as the "entry point."
|
4
|
+
# This is the file InSpec will try to load if it
|
5
|
+
# thinks your plugin is installed.
|
6
|
+
|
7
|
+
# The *only* thing this file should do is setup the
|
8
|
+
# load path, then load the plugin definition file.
|
9
|
+
|
10
|
+
# Next two lines simply add the path of the gem to the load path.
|
11
|
+
# This is not needed when being loaded as a gem; but when doing
|
12
|
+
# plugin development, you may need it. Either way, it's harmless.
|
13
|
+
libdir = File.dirname(__FILE__)
|
14
|
+
$LOAD_PATH.unshift(libdir) unless $LOAD_PATH.include?(libdir)
|
15
|
+
|
16
|
+
require '<%= plugin_name %>/plugin'
|
@@ -0,0 +1,64 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'inspec/resource'
|
4
|
+
|
5
|
+
module InspecPlugins::<%= module_name %>
|
6
|
+
# This class will provide the actual CLI implementation.
|
7
|
+
# Its superclass is provided by another call to Inspec.plugin,
|
8
|
+
# this time with two args. The first arg specifies we are requesting
|
9
|
+
# version 2 of the Plugins API. The second says we are making a CLI
|
10
|
+
# Command plugin component, so please make available any DSL needed
|
11
|
+
# for that.
|
12
|
+
# In fact, aside from a some housekeeping DSL methods, most of the
|
13
|
+
# DSL provided is that of Thor. Inspec.plugin(2, :cli_command)
|
14
|
+
# promises to return a class that is a subclass of Thor. So, to add
|
15
|
+
# commands, usage information, and options, use the Thor documentation.
|
16
|
+
class CliCommand < Inspec.plugin(2, :cli_command)
|
17
|
+
# This isn't provided by Thor, but is needed by InSpec so that it can
|
18
|
+
# register the top-level subcommand. That is to say, subcommand_desc
|
19
|
+
# makes `inspec <%= command_name_dashes %> ...` work. Args to sub_command_desc are
|
20
|
+
# a usage message, and a short decription.
|
21
|
+
# These will appear when someone has installed the plugin, and then they
|
22
|
+
# run `inspec help`.
|
23
|
+
# Note: if you want your command (or subcommand) to have dashes in it,
|
24
|
+
# use underscores where you want a dash, and Thor will convert them.
|
25
|
+
# Thor will fail to find a command that is directly named with dashes.
|
26
|
+
subcommand_desc '<%= command_name_snake %> [COMMAND]', 'Your Usage Message Here'
|
27
|
+
|
28
|
+
# The usual rhythm for a Thor CLI file is description, options, command method.
|
29
|
+
# Thor just has you call DSL methods in sequence prior to each command.
|
30
|
+
|
31
|
+
# Let's make a command, 'do_something'. This will then be available
|
32
|
+
# as `inspec <%= command_name_dashes %> do-something
|
33
|
+
# (Change this method name to be something sensible for your plugin.)
|
34
|
+
|
35
|
+
# First, provide a usage / description. This will appear
|
36
|
+
# in `inspec help <%= command_name_dashes %>`.
|
37
|
+
# As this is a usage message, you should write the command as it should appear
|
38
|
+
# to the user (if you want it to have dashes, use dashes)
|
39
|
+
desc 'do-something WHAT [OPTIONS]', 'Does something'
|
40
|
+
|
41
|
+
# Let's include an option, -s, to summarize
|
42
|
+
# Refer to the Thors docs; there is a lot you can do here.
|
43
|
+
option :summary, desc: 'Include a total at the bottom', \
|
44
|
+
type: :boolean, default: true, aliases: [:s]
|
45
|
+
|
46
|
+
# OK, now the actual method itself. If you provide params, you're telling Thor that
|
47
|
+
# you accept CLI arguments after all options have been consumed.
|
48
|
+
# Note again that the method name has an underscore, but when invoked
|
49
|
+
# on the CLI, use a dash.
|
50
|
+
def do_something(what = 'nothing')
|
51
|
+
# The code here will *only* be executed if someone actually
|
52
|
+
# runs `inspec <%= command_name_dashes %> do-something`.
|
53
|
+
|
54
|
+
# `what` will be the command line arg
|
55
|
+
# `options` will be a hash of CLI option values
|
56
|
+
|
57
|
+
# Talk to the user using the `ui` object (see Inspec::UI)
|
58
|
+
# ui.error('Whoops!')
|
59
|
+
|
60
|
+
ui.warning('This is a generated plugin with a default implementation. Edit lib/<%= plugin_name %>/cli_command.rb to make it do what you want.')
|
61
|
+
ui.exit(:success) # or :usage_error
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
# Plugin Definition file
|
4
|
+
# The purpose of this file is to declare to InSpec what plugin_types (capabilities)
|
5
|
+
# are included in this plugin, and provide hooks that will load them as needed.
|
6
|
+
|
7
|
+
# It is important that this file load successfully and *quickly*.
|
8
|
+
# Your plugin's functionality may never be used on this InSpec run; so we keep things
|
9
|
+
# fast and light by only loading heavy things when they are needed.
|
10
|
+
|
11
|
+
# Presumably this is light
|
12
|
+
require '<%= plugin_name %>/version'
|
13
|
+
|
14
|
+
# The InspecPlugins namespace is where all plugins should declare themselves.
|
15
|
+
# The 'Inspec' capitalization is used throughout the InSpec source code; yes, it's
|
16
|
+
# strange.
|
17
|
+
module InspecPlugins
|
18
|
+
# Pick a reasonable namespace here for your plugin. A reasonable choice
|
19
|
+
# would be the CamelCase version of your plugin gem name.
|
20
|
+
# <%= plugin_name %> => <%= module_name %>
|
21
|
+
module <%= module_name %>
|
22
|
+
# This simple class handles the plugin definition, so calling it simply Plugin is OK.
|
23
|
+
# Inspec.plugin returns various Classes, intended to be superclasses for various
|
24
|
+
# plugin components. Here, the one-arg form gives you the Plugin Definition superclass,
|
25
|
+
# which mainly gives you access to the hook / plugin_type DSL.
|
26
|
+
# The number '2' says you are asking for version 2 of the plugin API. If there are
|
27
|
+
# future versions, InSpec promises plugin API v2 will work for at least two more InSpec
|
28
|
+
# major versions.
|
29
|
+
class Plugin < ::Inspec.plugin(2)
|
30
|
+
# Internal machine name of the plugin. InSpec will use this in errors, etc.
|
31
|
+
plugin_name :'<%= plugin_name %>'
|
32
|
+
|
33
|
+
# Define a new CLI subcommand.
|
34
|
+
# The argument here will be used to match against the command line args,
|
35
|
+
# and if the user said `inspec list-resources`, this hook will get called.
|
36
|
+
# Notice that you can define multiple hooks with different names, and they
|
37
|
+
# don't have to match the plugin name.
|
38
|
+
|
39
|
+
# We'd like this to be list-resources, but Thor does not support hyphens
|
40
|
+
# see https://github.com/erikhuda/thor/pull/613
|
41
|
+
cli_command :<%= command_name_snake %> do
|
42
|
+
# Calling this hook doesn't mean the subcommand is being executed - just
|
43
|
+
# that we should be ready to do so. So, load the file that defines the
|
44
|
+
# functionality.
|
45
|
+
# For example, InSpec will activate this hook when `inspec help` is
|
46
|
+
# executed, so that this plugin's usage message will be included in the help.
|
47
|
+
require '<%= plugin_name %>/cli_command'
|
48
|
+
|
49
|
+
# Having loaded our functionality, return a class that will let the
|
50
|
+
# CLI engine tap into it.
|
51
|
+
InspecPlugins::<%= module_name %>::CliCommand
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
# This file simply makes it easier for CI engines to update
|
4
|
+
# the version stamp, and provide a clean way for the gemspec
|
5
|
+
# to learn the current version.
|
6
|
+
module InspecPlugins
|
7
|
+
module <%= module_name %>
|
8
|
+
VERSION = '0.1.0'.freeze
|
9
|
+
end
|
10
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# Test Fixtures Area
|
2
|
+
|
3
|
+
In this directory, you would place things that you need during testing. For example, if you were making a plugin that counts the number of controls in a profile, you might have a directory tree like this:
|
4
|
+
|
5
|
+
```
|
6
|
+
fixtures/
|
7
|
+
profiles/
|
8
|
+
zero-controls/
|
9
|
+
inspec.yml
|
10
|
+
controls/
|
11
|
+
twelve-controls/
|
12
|
+
inspec.yml
|
13
|
+
controls/
|
14
|
+
nine.rb
|
15
|
+
three.rb
|
16
|
+
```
|
17
|
+
|
18
|
+
When writing your functional tests, you can point InSpec at the various test fixture profiles, and know that when it points at the zero-controls profile, it should find no controls; and when pointed at the twelve-controls profile, it should find 12.
|
19
|
+
|
20
|
+
## Using test fixtures provided with the `inspec` source code
|
21
|
+
|
22
|
+
InSpec itself ships with many test fixtures - not just profiles, but attribute files, configuration directories, and more. Examine them at [the fixtures directory](https://github.com/inspec/inspec/tree/master/test/unit/mock)
|
23
|
+
|
24
|
+
To use them, see the helper.rb file included in the example at test/helper.rb .
|