inspec-resource-pack 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 526cf6f51d3c1b1e7f940524e97ad3290c145cbf96e1a6a97f54836acfef07f1
4
+ data.tar.gz: 1ebb3618679cf8b8120e48b6d343db68030f38cb5c841c1c1f4ff5330add82b8
5
+ SHA512:
6
+ metadata.gz: 8d9b8f1ad84c4d0d86f0809848a5dcdcc0bb207af641716031068b695229567be3d7ed2a58b9b065124691ec3dd0f60e0c309b18da7235149293f4ed7455de71
7
+ data.tar.gz: 45362a4ae99b34e6dd6c927aba57e4829366077a5387a0c5815216f75d67a55ee073e371e666b81135c2ae007e8d771bf29fd1a5f07dd2c8a9c431202e670f43
data/Gemfile ADDED
@@ -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
data/README.md ADDED
@@ -0,0 +1,28 @@
1
+ # ResourcePack Plugin
2
+
3
+ This plugin was generated by `inspec init plugin`, and apparently the author, 'Lynn Frank', 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 inspec-resource-pack
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,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 'inspec-resource-pack/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 = 'inspec-resource-pack'
17
+
18
+ # It is polite to namespace your plugin under InspecPlugins::YourPluginInCamelCase
19
+ spec.version = InspecPlugins::ResourcePack::VERSION
20
+ spec.authors = ['Lynn Frank']
21
+ spec.email = ['franklin.webber@gmail.com']
22
+ spec.summary = 'Test resources defined in a profile'
23
+ spec.description = '["Adds some testing helper files to be able to unit test"]'
24
+ spec.homepage = 'https://github.com/burtlo/inspec-resource-pack'
25
+ spec.license = 'Apache-2.0'
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 inspec-resource-pack.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
@@ -0,0 +1,46 @@
1
+ # encoding: utf-8
2
+
3
+ require 'inspec/resource'
4
+ require 'plugins/inspec-init/lib/inspec-init/renderer'
5
+
6
+ module InspecPlugins
7
+ module ResourcePack
8
+ class GenerateCLI < Inspec.plugin(2, :cli_command)
9
+ subcommand_desc 'generate resource_pack', 'Create an InSpec profile that is resource pack'
10
+
11
+ # The usual rhythm for a Thor CLI file is description, options, command method.
12
+ # Thor just has you call DSL methods in sequence prior to each command.
13
+
14
+ # Let's make a command, 'do_something'. This will then be available
15
+ # as `inspec my-command do-something
16
+ # (Change this method name to be something sensible for your plugin.)
17
+
18
+ # First, provide a usage / description. This will appear
19
+ # in `inspec help my-command`.
20
+ # As this is a usage message, you should write the command as it should appear
21
+ # to the user (if you want it to have dashes, use dashes)
22
+ desc 'resource_pack NAME', 'Create a custom resource pack'
23
+
24
+ option :overwrite, type: :boolean, default: false,
25
+ desc: 'Overwrites existing directory'
26
+
27
+ def resource_pack(new_resource_pack_name)
28
+ base_templates_path = File.absolute_path(File.join(__FILE__,'..','..','templates'))
29
+ resource_pack_template = 'resource_pack'
30
+
31
+ render_opts = {
32
+ templates_path: base_templates_path,
33
+ overwrite: options[:overwrite]
34
+ }
35
+ renderer = InspecPlugins::Init::Renderer.new(ui, render_opts)
36
+
37
+ vars = { name: new_resource_pack_name }
38
+
39
+ renderer.render_with_values(resource_pack_template, 'resource pack', vars)
40
+
41
+ # ui.exit(:success) # or :usage_error
42
+ ui.exit
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,38 @@
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 'inspec-resource-pack/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
+ # inspec-resource-pack => ResourcePack
21
+ module ResourcePack
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
+ plugin_name :'inspec-resource-pack'
31
+
32
+ cli_command :generate do
33
+ require 'inspec-resource-pack/cli_command'
34
+ InspecPlugins::ResourcePack::GenerateCLI
35
+ end
36
+ end
37
+ end
38
+ 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 ResourcePack
8
+ VERSION = '0.1.0'.freeze
9
+ end
10
+ end
@@ -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 'inspec-resource-pack/plugin'
@@ -0,0 +1,10 @@
1
+ name: <%= name %>
2
+ title: InSpec Resource Pack
3
+ maintainer: The Authors
4
+ copyright: The Authors
5
+ copyright_email: you@example.com
6
+ license: Apache-2.0
7
+ summary: An InSpec Resource Pack
8
+ version: 0.1.0
9
+ supports:
10
+ platform: os
@@ -0,0 +1,22 @@
1
+ class ExampleResource < Inspec.resource(1)
2
+ name 'example'
3
+
4
+ def initialize(alternate_path = nil)
5
+ @path = alternate_path || default_path
6
+ end
7
+
8
+ def default_path
9
+ if inspec.os.windows?
10
+ 'C:\example\bin\example.bat'
11
+ else
12
+ '/usr/bin/example'
13
+ end
14
+ end
15
+
16
+ attr_reader :path
17
+
18
+ def version
19
+ raw_result = inspec.command("#{path} --version").stdout
20
+ raw_result.split.first
21
+ end
22
+ end
@@ -0,0 +1,27 @@
1
+ require 'spec_helper'
2
+ require 'libraries/example'
3
+
4
+ describe_inspec_resource 'example' do
5
+ context 'on windows' do
6
+ # This helper method here is the equivalent to the first line within the environment
7
+ # that defines an os that returns a true when the names align.
8
+ # let(:platform) { 'windows' }
9
+
10
+ environment do
11
+ os.returns(windows?: true, linux?: false)
12
+ command('C:\example\bin\example.bat --version').returns(stdout: '0.1.0 (windows-build)')
13
+ end
14
+
15
+ its(:version) { should eq('0.1.0') }
16
+ end
17
+
18
+ context 'on linux' do
19
+ let(:platform) { 'linux' }
20
+
21
+ environment do
22
+ command('/usr/bin/example --version').returns(stdout: '0.1.0 (GNULinux-build)')
23
+ end
24
+
25
+ its(:version) { should eq('0.1.0') }
26
+ end
27
+ end
@@ -0,0 +1,173 @@
1
+ require 'inspec'
2
+ require 'rspec/its'
3
+
4
+ # To test each of your resources, they will need to be required
5
+ # to have the InSpec registry know about it.
6
+ #
7
+ # require './libraries/ohai.rb'
8
+
9
+ RSpec.configure do |config|
10
+ #
11
+ # Add a convienent name for the example group to the RSpec
12
+ # lexicon. This enables a user to write:
13
+ # describe_inspec_resource 'ohai'
14
+ #
15
+ # As opposed to appending a type to the declaration of the spec:
16
+ # describe 'ohai', type: :inspec_resource'
17
+ #
18
+ config.alias_example_group_to :describe_inspec_resource, type: :inspec_resource
19
+ end
20
+
21
+ shared_context 'InSpec Resource', type: :inspec_resource do
22
+ # The name of the resource which is the string in the
23
+ # top-level description should be the name field of
24
+ # the InSpec resource as it would appears in the registry.
25
+ let(:resource_name) { self.class.top_level_description }
26
+
27
+ # Find the resource in the registry based on the resource_name.
28
+ # The resource classes stored here are not exactly instances
29
+ # of the Resource class (e.g. OhaiResource). They are
30
+ # instead wrapped with the backend transport mechanism which
31
+ # they will be executed against.
32
+ let(:resource_class) { Inspec::Resource.registry[resource_name] }
33
+
34
+ #
35
+ def self.environment_builder(builder = nil)
36
+ if builder
37
+ @environment_builder = builder
38
+ else
39
+ @environment_builder
40
+ end
41
+ end
42
+
43
+ def self.environment(&block)
44
+ environment_builder(DoubleBuilder.new(&block))
45
+
46
+ # Create a backend helper which will generate a backend double
47
+ # based on the definitions that have been building up in
48
+ # all the environment builders in th current context and their
49
+ # parent contexts.
50
+ let(:backend) do
51
+ # For all the possible platforms assign a false result unless the platform name matches
52
+ possible_platforms = %w{aix redhat debian suse bsd solaris linux unix windows hpux darwin}
53
+ os_platform_mock_results = possible_platforms.inject({}) { |acc, elem| acc["#{elem}?"] = (elem == platform.to_s) ; acc }
54
+ platform_builder = DoubleBuilder.new { os.returns(os_platform_mock_results) }
55
+
56
+ env_builders = [ platform_builder ] + self.class.parent_groups.map(&:environment_builder).compact
57
+ starting_double = RSpec::Mocks::Double.new('backend')
58
+ env_builders.inject(starting_double) { |acc, elem| elem.evaluate(self, acc) }
59
+ end
60
+ end
61
+
62
+ # Create an instance of the resource with the mock backend and the resource name
63
+ def resource(*args)
64
+ resource_class.new(backend, resource_name, *args)
65
+ end
66
+
67
+ # Provide an alias of the resource to subject. By setting the subject
68
+ # creates an implicit subject to work with the `rspec-its`.
69
+ let(:subject) { resource }
70
+
71
+ # Provide a helper to help define the environment where the plugin is run in the unit tests
72
+ let(:platform) do
73
+ "spec"
74
+ end
75
+
76
+ # This is a no-op backend that should be overridden.
77
+ # Below is a helper method #environment which provides some
78
+ # shortcuts for hiding some of the RSpec mocking/stubbing double language.
79
+ def backend
80
+ double(
81
+ <<~BACKEND
82
+ A mocked underlying backend has not been defined. This can be done through the environment
83
+ helper method. Which enables you to specify how the mock envrionment will behave to all requests.
84
+
85
+ environment do
86
+ command('which ohai').returns(stdout: '/path/to/ohai')
87
+ command('/path/to/ohai').returns(stdout: '{ "os": "mac_os_x" }')
88
+ end
89
+ BACKEND
90
+ )
91
+ end
92
+ end
93
+
94
+ # This class serves only to create a context to enable a new domain-specific-language (DSL)
95
+ # for defining a backend in a simple way. The DoubleBuilder is constructed with the current
96
+ # test context which it later defines the #backend method that returns the test double that
97
+ # is built with this DSL.
98
+ class DoubleBuilder
99
+ def initialize(&block)
100
+ @content_block = block
101
+ end
102
+
103
+ def evaluate(test_context, backend)
104
+ # Evaluate the block provided to queue up a bunch of backend double definitions.
105
+ instance_exec(&@content_block)
106
+
107
+ backend_doubles = self.backend_doubles
108
+ test_context.instance_exec do
109
+ # With all the backend double definitions defined,
110
+ # create a backend to append all these doubles
111
+ backend_doubles.each do |backend_double|
112
+ if backend_double.has_inputs?
113
+ allow(backend).to receive(backend_double.name).with(*backend_double.inputs).and_return(backend_double.outputs)
114
+ else
115
+ allow(backend).to receive(backend_double.name).with(no_args).and_return(backend_double.outputs)
116
+ end
117
+ end
118
+ end
119
+
120
+ backend
121
+ end
122
+
123
+ # Store all the doubling specified in the initial part of #evaluate
124
+ def backend_doubles
125
+ @backend_doubles ||= []
126
+ end
127
+
128
+ def method_missing(backend_method_name, *args, &_block)
129
+ backend_double = BackendDouble.new(backend_method_name)
130
+ backend_double.inputs = args unless args.empty?
131
+ backend_doubles.push backend_double
132
+ # NOTE: The block is ignored.
133
+ self
134
+ end
135
+
136
+ class InSpecResouceMash < Hashie::Mash
137
+ disable_warnings
138
+ end
139
+
140
+ # When defining a new aspect of the environment (e.g. command, file)
141
+ # you will often want a result from that detail. Because of the fluent
142
+ # interface this double builder provides this is a way to grab the last
143
+ # build double and append a mock of a return object.
144
+ #
145
+ # @TODO this shouldn't be used without a double being created, an
146
+ # error will be generated with that last_double coming back as a nil.
147
+ # There may be some interesting behavior that could be undertaken
148
+ # here when no aspect is provided. It may also be better to throw a
149
+ # useful exception that describes use.
150
+ def returns(method_signature_as_hash)
151
+ return_result = InSpecResouceMash.new(method_signature_as_hash)
152
+ last_double = backend_doubles.last
153
+ results_double_name = "#{last_double.name}_#{last_double.inputs}_RESULTS"
154
+ last_double.outputs = RSpec::Mocks::Double.new(results_double_name, return_result)
155
+ self
156
+ end
157
+
158
+ # Create a object to hold the backend doubling information
159
+ class BackendDouble
160
+ class NoInputsSpecifed; end
161
+
162
+ def initialize(name)
163
+ @name = name
164
+ @inputs = NoInputsSpecifed
165
+ end
166
+
167
+ def has_inputs?
168
+ inputs != NoInputsSpecifed
169
+ end
170
+
171
+ attr_accessor :name, :inputs, :outputs
172
+ end
173
+ end
metadata ADDED
@@ -0,0 +1,74 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: inspec-resource-pack
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Lynn Frank
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2019-05-31 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: inspec
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: 2.2.78
20
+ - - "<"
21
+ - !ruby/object:Gem::Version
22
+ version: 4.0.0
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ version: 2.2.78
30
+ - - "<"
31
+ - !ruby/object:Gem::Version
32
+ version: 4.0.0
33
+ description: '["Adds some testing helper files to be able to unit test"]'
34
+ email:
35
+ - franklin.webber@gmail.com
36
+ executables: []
37
+ extensions: []
38
+ extra_rdoc_files: []
39
+ files:
40
+ - Gemfile
41
+ - README.md
42
+ - inspec-resource-pack.gemspec
43
+ - lib/inspec-resource-pack.rb
44
+ - lib/inspec-resource-pack/cli_command.rb
45
+ - lib/inspec-resource-pack/plugin.rb
46
+ - lib/inspec-resource-pack/version.rb
47
+ - lib/templates/resource_pack/inspec.yml
48
+ - lib/templates/resource_pack/libraries/example.rb
49
+ - lib/templates/resource_pack/spec/example_spec.rb
50
+ - lib/templates/resource_pack/spec/spec_helper.rb
51
+ homepage: https://github.com/burtlo/inspec-resource-pack
52
+ licenses:
53
+ - Apache-2.0
54
+ metadata: {}
55
+ post_install_message:
56
+ rdoc_options: []
57
+ require_paths:
58
+ - lib
59
+ required_ruby_version: !ruby/object:Gem::Requirement
60
+ requirements:
61
+ - - ">="
62
+ - !ruby/object:Gem::Version
63
+ version: '0'
64
+ required_rubygems_version: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ requirements: []
70
+ rubygems_version: 3.0.3
71
+ signing_key:
72
+ specification_version: 4
73
+ summary: Test resources defined in a profile
74
+ test_files: []