inspec-core 3.5.0 → 3.6.2
Sign up to get free protection for your applications and to get access to all the features.
- 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 .
|