mirror of
https://github.com/inspec/inspec
synced 2024-11-25 22:20:27 +00:00
Plugins: Support for Train Plugins in InSpec (#3444)
* Unit tests passing for loading Train plugins * detect works with a train test fixture * Update fixture install of train-fixture-plugin * Add functional tests for detect and shell when talking to a train plugin backend * Update docs to reflect availability of Train plugins * Functional test for install train plugin from path * Working install train plugin from path, more tests for installing from odd locations * PR Feedback Signed-off-by: Clinton Wolfe <clintoncwolfe@gmail.com>
This commit is contained in:
parent
5693d16f7e
commit
857b9bb11c
42 changed files with 1305 additions and 33 deletions
|
@ -1,22 +1,26 @@
|
|||
---
|
||||
title: About InSpec Plugins
|
||||
title: About InSpec and Train Plugins
|
||||
---
|
||||
|
||||
# InSpec Plugins
|
||||
# InSpec and Train Plugins
|
||||
|
||||
## What are InSpec Plugins?
|
||||
|
||||
Plugins are optional software components that extend the capabilities of InSpec. For example, `inspec-iggy` is a plugin project that aims to generate InSpec controls from infrastructure-as-code. Plugins are distributed as RubyGems, and InSpec manages their installation.
|
||||
InSpec Plugins are optional software components that extend the capabilities of InSpec. For example, [`inspec-iggy`](https://github.com/inspec/inspec-iggy) is a Plugin project that aims to generate InSpec controls from infrastructure-as-code files. Plugins are distributed as RubyGems, and InSpec manages their installation. InSpec Plugins always begin with the prefix 'inspec-'.
|
||||
|
||||
## What are Train Plugins?
|
||||
|
||||
Train Plugins allow InSpec to speak to new kinds of targets (typically new remote targets or APIs, but you could treat the local system in a new way if you wished to). For example, if you wanted to audit a Kubernetes cluster, you might want a transport that can talk to the supervisor API. You'd develop a Train Plugin for that, and install it using the InSpec command line. Train Plugins always begin with the prefix 'train-'.
|
||||
|
||||
## What can plugins do?
|
||||
|
||||
Currently, each plugin can offer one or more of these capabilities:
|
||||
|
||||
* define a new command-line-interface (CLI) command suite
|
||||
* connectivity to new types of hosts or cloud providers (`train` plugins)
|
||||
|
||||
Future work might include new capability types, such as:
|
||||
|
||||
* connectivity to new types of hosts or cloud providers (`train` transports)
|
||||
* reporters (output generators)
|
||||
* DSL extensions at the file, control, or test level
|
||||
* attribute fetchers to allow reading InSpec attributes from new sources (for example, a remote, encrypted key-value store)
|
||||
|
@ -37,10 +41,17 @@ You can install a plugin by running:
|
|||
|
||||
```bash
|
||||
$ inspec plugin install inspec-some-plugin
|
||||
$ inspec plugin install train-some-plugin
|
||||
```
|
||||
|
||||
For more details on what the `plugin` command can do, see the [online help](https://www.inspec.io/docs/reference/cli/#plugin), or run `inspec plugin help`.
|
||||
|
||||
## How do I write a plugin?
|
||||
|
||||
For details on how to author a Plugin, see the [developer documentation](https://github.com/inspec/inspec/blob/master/docs/dev/plugins.md)
|
||||
### InSpec Plugins
|
||||
|
||||
For details on how to author an InSpec Plugin, see the [developer documentation](https://github.com/inspec/inspec/blob/master/docs/dev/plugins.md)
|
||||
|
||||
### Train Plugins
|
||||
|
||||
For details on how to author a Train Plugin, see the [developer documentation](https://github.com/inspec/train/blob/master/docs/dev/plugins.md)
|
|
@ -22,7 +22,7 @@ Gem::Specification.new do |spec|
|
|||
|
||||
spec.required_ruby_version = '>= 2.3'
|
||||
|
||||
spec.add_dependency 'train-core', '~> 1.4', '>= 1.4.37'
|
||||
spec.add_dependency 'train-core', '~> 1.5'
|
||||
spec.add_dependency 'thor', '~> 0.20'
|
||||
spec.add_dependency 'json', '>= 1.8', '< 3.0'
|
||||
spec.add_dependency 'method_source', '~> 0.8'
|
||||
|
|
|
@ -26,7 +26,7 @@ Gem::Specification.new do |spec|
|
|||
|
||||
spec.required_ruby_version = '>= 2.3'
|
||||
|
||||
spec.add_dependency 'train', '~> 1.4', '>= 1.4.37'
|
||||
spec.add_dependency 'train', '~> 1.5'
|
||||
spec.add_dependency 'thor', '~> 0.20'
|
||||
spec.add_dependency 'json', '>= 1.8', '< 3.0'
|
||||
spec.add_dependency 'method_source', '~> 0.8'
|
||||
|
|
|
@ -24,6 +24,10 @@ module Inspec::Plugin::V2
|
|||
# New-style (v2) co-distributed plugins are in lib/plugins,
|
||||
# and may be safely loaded
|
||||
detect_core_plugins unless options[:omit_core_plugins]
|
||||
|
||||
# Train plugins aren't InSpec plugins (they don't use our API)
|
||||
# but InSpec CLI manages them. So, we have to wrap them a bit.
|
||||
accommodate_train_plugins
|
||||
end
|
||||
|
||||
def load_all
|
||||
|
@ -195,6 +199,7 @@ module Inspec::Plugin::V2
|
|||
def annotate_status_after_loading(plugin_name)
|
||||
status = registry[plugin_name]
|
||||
return if status.api_generation == 2 # Gen2 have self-annotating superclasses
|
||||
return if status.api_generation == :'train-1' # Train plugins are here as a courtesy, don't poke them
|
||||
case status.installation_type
|
||||
when :bundle
|
||||
annotate_bundle_plugin_status_after_load(plugin_name)
|
||||
|
@ -250,6 +255,18 @@ module Inspec::Plugin::V2
|
|||
end
|
||||
end
|
||||
|
||||
def accommodate_train_plugins
|
||||
registry.plugin_names.map(&:to_s).grep(/^train-/).each do |train_plugin_name|
|
||||
status = registry[train_plugin_name.to_sym]
|
||||
status.api_generation = :'train-1'
|
||||
|
||||
if status.installation_type == :gem
|
||||
# Activate the gem. This allows train to 'require' the gem later.
|
||||
activate_managed_gems_for_plugin(train_plugin_name)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# TODO: DRY up re: Installer read_or_init_config_file
|
||||
# TODO: refactor the plugin.json file to have its own class, which Loader consumes
|
||||
def read_conf_file
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
require 'forwardable'
|
||||
require 'singleton'
|
||||
require 'train'
|
||||
|
||||
require_relative 'status'
|
||||
require_relative 'activator'
|
||||
|
||||
|
@ -25,11 +27,14 @@ module Inspec::Plugin::V2
|
|||
end
|
||||
|
||||
def loaded_plugin?(name)
|
||||
registry.dig(name.to_sym, :loaded)
|
||||
# HACK: Status is normally the source of truth for loadedness, unless it is a train plugin; then the Train::Registry is the source of truth.
|
||||
# Also, InSpec registry is keyed on Symbols; Train is keyed on Strings.
|
||||
return registry.dig(name.to_sym, :loaded) unless name.to_s.start_with?('train-')
|
||||
Train::Plugins.registry.key?(name.to_s.sub(/^train-/, ''))
|
||||
end
|
||||
|
||||
def loaded_count
|
||||
registry.values.select(&:loaded).count
|
||||
loaded_plugin_names.count
|
||||
end
|
||||
|
||||
def known_count
|
||||
|
@ -37,7 +42,7 @@ module Inspec::Plugin::V2
|
|||
end
|
||||
|
||||
def loaded_plugin_names
|
||||
registry.values.select(&:loaded).map(&:name)
|
||||
registry.keys.select { |name| loaded_plugin?(name) }
|
||||
end
|
||||
|
||||
def path_based_plugin?(name)
|
||||
|
|
|
@ -7,7 +7,7 @@ module InspecPlugins
|
|||
class CliCommand < Inspec.plugin(2, :cli_command)
|
||||
include Term::ANSIColor
|
||||
|
||||
subcommand_desc 'plugin SUBCOMMAND', 'Manage InSpec plugins'
|
||||
subcommand_desc 'plugin SUBCOMMAND', 'Manage InSpec and Train plugins'
|
||||
|
||||
#==================================================================#
|
||||
# inspec plugin list
|
||||
|
@ -207,10 +207,11 @@ module InspecPlugins
|
|||
# Rationale for rubocop variances: It's a heuristics method, and will be full of
|
||||
# conditionals. The code is well-commented; refactoring into sub-methods would
|
||||
# reduce clarity.
|
||||
def install_from_path__apply_entry_point_heuristics(path) # rubocop: disable Metrics/AbcSize, Metrics/CyclomaticComplexity
|
||||
def install_from_path__apply_entry_point_heuristics(path) # rubocop: disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
||||
given = Pathname.new(path)
|
||||
given = given.expand_path # Resolve any relative paths
|
||||
name_regex = /^(inspec|train)-/
|
||||
versioned_regex = /^(inspec|train)-[a-z0-9\-\_]+-\d+\.\d+\.\d+$/
|
||||
|
||||
# What are the last four things like?
|
||||
parts = [
|
||||
|
@ -220,14 +221,14 @@ module InspecPlugins
|
|||
given.extname,
|
||||
].map(&:to_s)
|
||||
|
||||
# Simplest case: it was a full entry point, as presented.
|
||||
# Case 1: Simplest case: it was a full entry point, as presented.
|
||||
# /home/you/projects/inspec-something/lib/inspec-something.rb
|
||||
# parts index: ^0^ ^1^ ^2^ ^3^
|
||||
if parts[0] =~ name_regex && parts[1] == 'lib' && parts[2] == parts[0] && parts[3] == '.rb'
|
||||
return given.to_s
|
||||
end
|
||||
|
||||
# Also easy: they either referred to the internal library directory,
|
||||
# Case 2: Also easy: they either referred to the internal library directory,
|
||||
# or left the extansion off. Those are the same to us.
|
||||
# /home/you/projects/inspec-something/lib/inspec-something
|
||||
# parts index: ^0^ ^1^ ^2^ (3 is empty)
|
||||
|
@ -235,7 +236,22 @@ module InspecPlugins
|
|||
return given.to_s + '.rb'
|
||||
end
|
||||
|
||||
# Easy to recognize, but harder to handle: they referred to the project root.
|
||||
# Case 3: Maybe they were refering to a path that is inside a gem installation, or an exploded gem?
|
||||
# In that case, we'll have a version on the plugin name in part 0
|
||||
# /home/you/.gems/2.4.0/gems/inspec-something-3.45.1/lib/inspec-something.rb
|
||||
# parts index: ^0^ ^1^ ^2^ ^3^
|
||||
if parts[0] =~ versioned_regex && parts[1] == 'lib' && parts[0].start_with?(parts[2]) && parts[3] == '.rb'
|
||||
return given.to_s
|
||||
end
|
||||
|
||||
# Case 4: Like case 3, but missing the .rb
|
||||
# /home/you/.gems/2.4.0/gems/inspec-something-3.45.1/lib/inspec-something
|
||||
# parts index: ^0^ ^1^ ^2^ ^3^ (empty)
|
||||
if parts[0] =~ versioned_regex && parts[1] == 'lib' && parts[0].start_with?(parts[2]) && parts[3].empty?
|
||||
return given.to_s + '.rb'
|
||||
end
|
||||
|
||||
# Case 5: Easy to recognize, but harder to handle: they referred to the project root.
|
||||
# /home/you/projects/inspec-something
|
||||
# parts index: ^0^ ^1^ ^2^ (3 is empty)
|
||||
# 0 and 1 are not meaningful to us, but we hope to find a parts[2]/lib/inspec-something.rb.
|
||||
|
@ -261,9 +277,19 @@ module InspecPlugins
|
|||
end
|
||||
|
||||
# OK, the wheels didn't fall off. But is it a plugin?
|
||||
unless Inspec::Plugin::V2::Registry.instance.known_plugin?(plugin_name.to_sym)
|
||||
puts(red { 'Does not appear to be a plugin' } + " - #{plugin_name} - After probe-loading the supposed plugin, it did not register itself. Ensure something inherits from 'Inspec.plugin(2)' - installation failed.")
|
||||
exit 1
|
||||
if plugin_name.to_s.start_with?('train')
|
||||
# Train internal names do not include the prix in their registry entries
|
||||
# And the registry is keyed on Strings
|
||||
registry_key = plugin_name.to_s.sub(/^train-/, '')
|
||||
unless Train::Plugins.registry.key?(registry_key)
|
||||
puts(red { 'Does not appear to be a plugin' } + " - #{plugin_name} - After probe-loading the supposed plugin, it did not register itself to Train. Ensure something inherits from 'Train.plugin(1)' - installation failed.")
|
||||
exit 1
|
||||
end
|
||||
else
|
||||
unless registry.known_plugin?(plugin_name.to_sym)
|
||||
puts(red { 'Does not appear to be a plugin' } + " - #{plugin_name} - After probe-loading the supposed plugin, it did not register itself to InSpec. Ensure something inherits from 'Inspec.plugin(2)' - installation failed.")
|
||||
exit 1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -112,6 +112,28 @@ class PluginManagerCliList < MiniTest::Test
|
|||
path_line = result.stdout.split("\n").grep(/path/).first
|
||||
assert_match(/\s*inspec-\S+\s+src\s+path\s+2/, path_line)
|
||||
end
|
||||
|
||||
def test_list_when_a_train_plugin_is_installed
|
||||
pre_block = Proc.new do |plugin_statefile_data, tmp_dir|
|
||||
plugin_statefile_data.clear # Signal not to write a file, we'll provide one.
|
||||
copy_in_core_config_dir('train-test-fixture', tmp_dir)
|
||||
end
|
||||
|
||||
result = run_inspec_process_with_this_plugin('plugin list', pre_run: pre_block)
|
||||
assert_equal 0, result.exit_status, 'exist status must be 0'
|
||||
assert_includes result.stdout, '1 plugin(s) total', 'list train should show one plugins'
|
||||
|
||||
# Plugin Name Version Via ApiVer
|
||||
# -------------------------------------------------------
|
||||
# train-test-fixture 0.1.0 gem train-1
|
||||
# -------------------------------------------------------
|
||||
# 1 plugin(s) total
|
||||
train_line = result.stdout.split("\n").grep(/train/).first
|
||||
assert_includes(train_line, 'train-test-fixture')
|
||||
assert_includes(train_line, '0.1.0')
|
||||
assert_includes(train_line, 'gem')
|
||||
assert_includes(train_line, 'train-1')
|
||||
end
|
||||
end
|
||||
|
||||
#-----------------------------------------------------------------------------------------#
|
||||
|
@ -184,6 +206,15 @@ class PluginManagerCliSearch < MiniTest::Test
|
|||
assert_includes result.stdout, '0 plugin(s) found', 'Search result should find 0 plugins'
|
||||
end
|
||||
|
||||
def test_search_for_a_real_gem_with_full_name_no_options_and_train_name
|
||||
result = run_inspec_process('plugin search train-test-fixture')
|
||||
assert_equal 0, result.exit_status, 'Search should exit 0 on a hit'
|
||||
assert_includes result.stdout, 'train-test-fixture', 'Search result should contain the gem name'
|
||||
assert_includes result.stdout, '1 plugin(s) found', 'Search result should find 1 plugin'
|
||||
line = result.stdout.split("\n").grep(/train-test-fixture/).first
|
||||
assert_match(/\s*train-test-fixture\s+\((\d+\.\d+\.\d+){1}\)/,line,'Plugin line should include name and exactly one version')
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
#-----------------------------------------------------------------------------------------#
|
||||
|
@ -194,17 +225,43 @@ class PluginManagerCliInstall < MiniTest::Test
|
|||
extend CorePluginFunctionalHelper # gives us class methods, like `let` aliases out here outside test methods
|
||||
|
||||
include PluginManagerHelpers
|
||||
|
||||
ruby_abi_version = (Gem.ruby_version.segments[0, 2] << 0).join('.')
|
||||
# Test multiple hueristics of the path-mode install.
|
||||
# These are all positive tests; they should resolve the entry point to the same path in each case.
|
||||
{
|
||||
'is_perfect' => File.join(core_fixture_plugins_path, 'inspec-test-fixture', 'lib', 'inspec-test-fixture.rb'),
|
||||
'refers_to_the_entry_point_with_no_extension' => File.join(core_fixture_plugins_path, 'inspec-test-fixture', 'lib', 'inspec-test-fixture'),
|
||||
'refers_to_the_src_root_of_a_plugin' => File.join(core_fixture_plugins_path, 'inspec-test-fixture'),
|
||||
'refers_to_a_relative_path' => File.join('test', 'unit', 'mock', 'plugins', 'inspec-test-fixture', 'lib', 'inspec-test-fixture.rb'),
|
||||
}.each do |test_name, fixture_plugin_path|
|
||||
'is_perfect' => {
|
||||
given: File.join(core_fixture_plugins_path, 'inspec-test-fixture', 'lib', 'inspec-test-fixture.rb'),
|
||||
},
|
||||
'refers_to_the_entry_point_with_no_extension' => {
|
||||
given: File.join(core_fixture_plugins_path, 'inspec-test-fixture', 'lib', 'inspec-test-fixture'),
|
||||
},
|
||||
'refers_to_the_src_root_of_a_plugin' => {
|
||||
given: File.join(core_fixture_plugins_path, 'inspec-test-fixture'),
|
||||
},
|
||||
'refers_to_a_versioned_gem_install' => {
|
||||
given: File.join(core_config_dir_path, 'test-fixture-1-float', 'gems', ruby_abi_version, 'gems', 'inspec-test-fixture-0.1.0', 'lib', 'inspec-test-fixture.rb'),
|
||||
resolved_path: File.join(core_config_dir_path, 'test-fixture-1-float', 'gems', ruby_abi_version, 'gems', 'inspec-test-fixture-0.1.0', 'lib', 'inspec-test-fixture.rb'),
|
||||
},
|
||||
'refers_to_a_versioned_gem_install_missing_extension' => {
|
||||
given: File.join(core_config_dir_path, 'test-fixture-1-float', 'gems', ruby_abi_version, 'gems', 'inspec-test-fixture-0.1.0', 'lib', 'inspec-test-fixture'),
|
||||
resolved_path: File.join(core_config_dir_path, 'test-fixture-1-float', 'gems', ruby_abi_version, 'gems', 'inspec-test-fixture-0.1.0', 'lib', 'inspec-test-fixture.rb'),
|
||||
},
|
||||
'refers_to_a_relative_path' => {
|
||||
given: File.join('test', 'unit', 'mock', 'plugins', 'inspec-test-fixture', 'lib', 'inspec-test-fixture.rb'),
|
||||
},
|
||||
'refers_to_a_train_plugin' => {
|
||||
given: File.join(core_config_dir_path, 'train-test-fixture', 'gems', ruby_abi_version, 'gems', 'train-test-fixture-0.1.0', 'lib', 'train-test-fixture.rb'),
|
||||
plugin_name: 'train-test-fixture',
|
||||
resolved_path: File.join(core_config_dir_path, 'train-test-fixture', 'gems', ruby_abi_version, 'gems', 'train-test-fixture-0.1.0', 'lib', 'train-test-fixture.rb'),
|
||||
},
|
||||
}.each do |test_name, fixture_info|
|
||||
define_method(('test_install_from_path_when_path_' + test_name).to_sym) do
|
||||
install_result = run_inspec_process_with_this_plugin("plugin install #{fixture_plugin_path}", post_run: list_after_run)
|
||||
fixture_info = {
|
||||
plugin_name: 'inspec-test-fixture',
|
||||
resolved_path: File.join(core_fixture_plugins_path, 'inspec-test-fixture', 'lib', 'inspec-test-fixture.rb')
|
||||
}.merge(fixture_info)
|
||||
|
||||
install_result = run_inspec_process_with_this_plugin("plugin install #{fixture_info[:given]}", post_run: list_after_run)
|
||||
|
||||
assert_empty install_result.stderr
|
||||
assert_equal 0, install_result.exit_status, 'Exit status should be 0'
|
||||
|
@ -212,20 +269,19 @@ class PluginManagerCliInstall < MiniTest::Test
|
|||
# Check UX messaging
|
||||
success_message = install_result.stdout.split("\n").grep(/installed/).last
|
||||
refute_nil success_message, 'Should find a success message at the end'
|
||||
assert_includes success_message, 'inspec-test-fixture'
|
||||
assert_includes success_message, fixture_info[:plugin_name]
|
||||
assert_includes success_message, 'plugin installed via source path reference'
|
||||
|
||||
# Check round-trip UX via list
|
||||
list_result = install_result.payload.list_result
|
||||
itf_line = list_result.stdout.split("\n").grep(/inspec-test-fixture/).first
|
||||
refute_nil itf_line, 'inspec-test-fixture should now appear in the output of inspec list'
|
||||
assert_match(/\s*inspec-test-fixture\s+src\s+path\s+/, itf_line, 'list output should show that it is a path installation')
|
||||
itf_line = list_result.stdout.split("\n").grep(Regexp.new(fixture_info[:plugin_name])).first
|
||||
refute_nil itf_line, 'plugin name should now appear in the output of inspec list'
|
||||
assert_match(/\s*(inspec|train)-test-fixture\s+src\s+path\s+/, itf_line, 'list output should show that it is a path installation')
|
||||
|
||||
# Check plugin statefile. Extra important in this case, since all should resolve to the same entry point.
|
||||
plugin_data = install_result.payload.plugin_data
|
||||
entry = plugin_data['plugins'].detect { |e| e['name'] == 'inspec-test-fixture' }
|
||||
expected = File.join(core_fixture_plugins_path, 'inspec-test-fixture', 'lib', 'inspec-test-fixture.rb')
|
||||
assert_equal expected, entry['installation_path'], 'Regardless of input, the entry point should be correct.'
|
||||
entry = plugin_data['plugins'].detect { |e| e['name'] == fixture_info[:plugin_name] }
|
||||
assert_equal fixture_info[:resolved_path], entry['installation_path'], 'Regardless of input, the entry point should be correct.'
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -439,6 +495,24 @@ class PluginManagerCliInstall < MiniTest::Test
|
|||
assert_includes refusal_message, 'Update required'
|
||||
assert_includes refusal_message, 'inspec plugin update'
|
||||
end
|
||||
|
||||
def test_install_from_rubygems_latest_with_train_plugin
|
||||
install_result = run_inspec_process_with_this_plugin('plugin install train-test-fixture', post_run: list_after_run)
|
||||
|
||||
assert_empty install_result.stderr
|
||||
assert_equal 0, install_result.exit_status, 'Exit status should be 0'
|
||||
|
||||
success_message = install_result.stdout.split("\n").grep(/installed/).last
|
||||
refute_nil success_message, 'Should find a success message at the end'
|
||||
assert_includes success_message, 'train-test-fixture'
|
||||
assert_includes success_message, '0.1.0'
|
||||
assert_includes success_message, 'installed from rubygems.org'
|
||||
|
||||
list_result = install_result.payload.list_result
|
||||
itf_line = list_result.stdout.split("\n").grep(/train-test-fixture/).first
|
||||
refute_nil itf_line, 'train-test-fixture should now appear in the output of inspec list'
|
||||
assert_match(/\s*train-test-fixture\s+0.1.0\s+gem\s+/, itf_line, 'list output should show that it is a gem installation with version')
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
|
14
lib/plugins/things-for-train-integration.rb
Normal file
14
lib/plugins/things-for-train-integration.rb
Normal file
|
@ -0,0 +1,14 @@
|
|||
# docs/plugins
|
||||
# Update that train plugins are now possible
|
||||
|
||||
# test/unit/plugin/v2/loader_test.rb
|
||||
# TODO: loading all plugins does not activate Train plugins
|
||||
|
||||
# lib/plugins/inspec-plugin-manager-cli/test/functional/inspec-plugin_test.rb
|
||||
# ~ Should be able to install a train plugin - in place, will fail until plugin published
|
||||
# ~ Should be able to search for a train plugin - in place, will fail until plugin published
|
||||
|
||||
# test/functional/plugins_test.rb
|
||||
# % Should be able to suggest a train transport plugin when an unsupported --target schema is used and a gem search is successful
|
||||
# % Should be able to suggest a train transport plugin when an unrecognized profile platform declaration is used and a gem search is successful
|
||||
# - Should be able to run inspec detect targeting a test target
|
|
@ -104,3 +104,59 @@ describe 'plugin cli usage message integration' do
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
#=========================================================================================#
|
||||
# Train Plugin Support
|
||||
#=========================================================================================#
|
||||
|
||||
describe 'train plugin support' do
|
||||
describe 'when a train plugin is installed' do
|
||||
include FunctionalHelper
|
||||
it 'can run inspec detect against a URL target' do
|
||||
outcome = inspec_with_env('detect -t test-fixture://', INSPEC_CONFIG_DIR: File.join(config_dir_path, 'train-test-fixture'))
|
||||
outcome.exit_status.must_equal(0)
|
||||
outcome.stderr.must_be_empty
|
||||
lines = outcome.stdout.split("\n")
|
||||
lines.grep(/Name/).first.must_include('test-fixture')
|
||||
lines.grep(/Name/).first.wont_include('train-test-fixture')
|
||||
lines.grep(/Release/).first.must_include('0.1.0')
|
||||
lines.grep(/Families/).first.must_include('os')
|
||||
lines.grep(/Families/).first.must_include('windows')
|
||||
lines.grep(/Families/).first.must_include('unix')
|
||||
lines.grep(/Arch/).first.must_include('mock')
|
||||
end
|
||||
|
||||
it 'can run inspec detect against a test-fixture backend' do
|
||||
outcome = inspec_with_env('detect -b test-fixture', INSPEC_CONFIG_DIR: File.join(config_dir_path, 'train-test-fixture'))
|
||||
outcome.exit_status.must_equal(0)
|
||||
outcome.stderr.must_be_empty
|
||||
lines = outcome.stdout.split("\n")
|
||||
lines.grep(/Name/).first.must_include('test-fixture')
|
||||
lines.grep(/Name/).first.wont_include('train-test-fixture')
|
||||
lines.grep(/Release/).first.must_include('0.1.0')
|
||||
lines.grep(/Families/).first.must_include('os')
|
||||
lines.grep(/Families/).first.must_include('windows')
|
||||
lines.grep(/Families/).first.must_include('unix')
|
||||
lines.grep(/Arch/).first.must_include('mock')
|
||||
end
|
||||
|
||||
it 'can run inspec shell and read a file' do
|
||||
outcome = inspec_with_env("shell -t test-fixture:// -c 'file(\"any-path\").content'", INSPEC_CONFIG_DIR: File.join(config_dir_path, 'train-test-fixture'))
|
||||
outcome.exit_status.must_equal(0)
|
||||
outcome.stderr.must_be_empty
|
||||
outcome.stdout.chomp.must_equal 'Lorem Ipsum'
|
||||
end
|
||||
|
||||
it 'can run inspec shell and run a command' do
|
||||
outcome = inspec_with_env("shell -t test-fixture:// -c 'command(\"echo hello\").exit_status'", INSPEC_CONFIG_DIR: File.join(config_dir_path, 'train-test-fixture'))
|
||||
outcome.exit_status.must_equal(0)
|
||||
outcome.stderr.must_be_empty
|
||||
outcome.stdout.chomp.must_equal "17"
|
||||
|
||||
outcome = inspec_with_env("shell -t test-fixture:// -c 'command(\"echo hello\").stdout'", INSPEC_CONFIG_DIR: File.join(config_dir_path, 'train-test-fixture'))
|
||||
outcome.exit_status.must_equal(0)
|
||||
outcome.stderr.must_be_empty
|
||||
outcome.stdout.chomp.must_equal "Mock Command Result stdout"
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,2 +1,5 @@
|
|||
lib = File.expand_path("../../lib", __FILE__)
|
||||
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
||||
|
||||
require 'inspec-test-fixture/version'
|
||||
require 'inspec-test-fixture/plugin'
|
||||
|
|
|
@ -1,2 +1,5 @@
|
|||
lib = File.expand_path("../../lib", __FILE__)
|
||||
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
||||
|
||||
require 'inspec-test-fixture/version'
|
||||
require 'inspec-test-fixture/plugin'
|
||||
|
|
|
@ -1,2 +1,5 @@
|
|||
lib = File.expand_path("../../lib", __FILE__)
|
||||
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
||||
|
||||
require 'inspec-test-fixture/version'
|
||||
require 'inspec-test-fixture/plugin'
|
||||
|
|
|
@ -0,0 +1,201 @@
|
|||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
|
@ -0,0 +1,5 @@
|
|||
This is a very simple train transport plugin. It provided fixed responses to file.content and command.stdout/stderr/exit_status.
|
||||
|
||||
It is not a good example to use for learning, nor a good base for starting your own plugin - it's intended for for use during the testing of Train.
|
||||
|
||||
For good examples of plugin development, see train/examples/plugin.
|
|
@ -0,0 +1,4 @@
|
|||
lib = File.expand_path("../../lib", __FILE__)
|
||||
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
||||
|
||||
require 'train-test-fixture/transport'
|
|
@ -0,0 +1,39 @@
|
|||
require 'train-test-fixture/platform'
|
||||
require 'train/transports/local'
|
||||
|
||||
module TrainPlugins
|
||||
module TestFixture
|
||||
class Connection < Train::Plugins::Transport::BaseConnection
|
||||
include TrainPlugins::TestFixture::Platform
|
||||
|
||||
def initialize(options)
|
||||
super(options)
|
||||
end
|
||||
|
||||
def local?
|
||||
true
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def run_command_via_connection(cmd)
|
||||
Train::Transports::Local::CommandResult.new(
|
||||
'Mock Command Result stdout',
|
||||
'Mock Command Result stderr',
|
||||
17
|
||||
)
|
||||
end
|
||||
|
||||
def file_via_connection(path, *args)
|
||||
MockFile.new(self, path)
|
||||
end
|
||||
|
||||
class MockFile < Train::File
|
||||
def content
|
||||
# Remarkably, the content is always the same.
|
||||
'Lorem Ipsum'
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,18 @@
|
|||
require 'train-test-fixture/version'
|
||||
|
||||
module TrainPlugins
|
||||
module TestFixture
|
||||
module Platform
|
||||
def platform
|
||||
# Build this platform's family declarations.
|
||||
# You'll need at least unix and windows to make the file() resource work.
|
||||
Train::Platforms.name('test-fixture').in_family('unix')
|
||||
Train::Platforms.name('test-fixture').in_family('windows')
|
||||
force_platform!('test-fixture',
|
||||
release: TrainPlugins::TestFixture::VERSION,
|
||||
arch: 'mock',
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,14 @@
|
|||
require 'train-test-fixture/connection'
|
||||
|
||||
module TrainPlugins
|
||||
module TestFixture
|
||||
class Transport < Train.plugin(1)
|
||||
name 'test-fixture'
|
||||
|
||||
def connection(_ = nil)
|
||||
@connection ||= TrainPlugins::TestFixture::Connection.new(@options)
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,5 @@
|
|||
module TrainPlugins
|
||||
module TestFixture
|
||||
VERSION = '0.1.0'
|
||||
end
|
||||
end
|
|
@ -0,0 +1,35 @@
|
|||
|
||||
lib = File.expand_path("../lib", __FILE__)
|
||||
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
||||
|
||||
Gem::Specification.new do |spec|
|
||||
spec.name = "train-test-fixture"
|
||||
spec.version = '0.1.0'
|
||||
spec.authors = ["Inspec core engineering team"]
|
||||
spec.email = ["hello@chef.io"]
|
||||
spec.license = 'Apache-2.0'
|
||||
|
||||
spec.summary = %q{Test train plugin. Not intended for use as an example.}
|
||||
spec.description = <<~EOD
|
||||
Train plugin used in testing Train's plugin loader and InSpec's plugin manager.
|
||||
This plugin does things that a normal plugin should not. Do not use it as an
|
||||
example or as a starting point for plugin of your own. For that, please see
|
||||
https://github.com/inspec/train/tree/master/examples/plugins
|
||||
EOD
|
||||
spec.homepage = "https://github.com/inspec/train"
|
||||
|
||||
spec.files = %w{
|
||||
README.md
|
||||
LICENSE
|
||||
lib/train-test-fixture.rb
|
||||
lib/train-test-fixture/version.rb
|
||||
lib/train-test-fixture/transport.rb
|
||||
lib/train-test-fixture/connection.rb
|
||||
lib/train-test-fixture/platform.rb
|
||||
train-test-fixture.gemspec
|
||||
}
|
||||
spec.executables = []
|
||||
spec.require_paths = ["lib"]
|
||||
|
||||
# No deps
|
||||
end
|
|
@ -0,0 +1,20 @@
|
|||
# -*- encoding: utf-8 -*-
|
||||
# stub: train-test-fixture 0.1.0 ruby lib
|
||||
|
||||
Gem::Specification.new do |s|
|
||||
s.name = "train-test-fixture".freeze
|
||||
s.version = "0.1.0"
|
||||
|
||||
s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
|
||||
s.require_paths = ["lib".freeze]
|
||||
s.authors = ["Inspec core engineering team".freeze]
|
||||
s.date = "2018-09-26"
|
||||
s.description = "Train plugin used in testing Train's plugin loader and InSpec's plugin manager.\nThis plugin does things that a normal plugin should not. Do not use it as an\nexample or as a starting point for plugin of your own. For that, please see\nhttps://github.com/inspec/train/tree/master/examples/plugins\n".freeze
|
||||
s.email = ["hello@chef.io".freeze]
|
||||
s.homepage = "https://github.com/inspec/train".freeze
|
||||
s.licenses = ["Apache-2.0".freeze]
|
||||
s.rubygems_version = "2.6.13".freeze
|
||||
s.summary = "Test train plugin. Not intended for use as an example.".freeze
|
||||
|
||||
s.installed_by_version = "2.6.13" if s.respond_to? :installed_by_version
|
||||
end
|
|
@ -0,0 +1,201 @@
|
|||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
|
@ -0,0 +1,5 @@
|
|||
This is a very simple train transport plugin. It provided fixed responses to file.content and command.stdout/stderr/exit_status.
|
||||
|
||||
It is not a good example to use for learning, nor a good base for starting your own plugin - it's intended for for use during the testing of Train.
|
||||
|
||||
For good examples of plugin development, see train/examples/plugin.
|
|
@ -0,0 +1,4 @@
|
|||
lib = File.expand_path("../../lib", __FILE__)
|
||||
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
||||
|
||||
require 'train-test-fixture/transport'
|
|
@ -0,0 +1,39 @@
|
|||
require 'train-test-fixture/platform'
|
||||
require 'train/transports/local'
|
||||
|
||||
module TrainPlugins
|
||||
module TestFixture
|
||||
class Connection < Train::Plugins::Transport::BaseConnection
|
||||
include TrainPlugins::TestFixture::Platform
|
||||
|
||||
def initialize(options)
|
||||
super(options)
|
||||
end
|
||||
|
||||
def local?
|
||||
true
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def run_command_via_connection(cmd)
|
||||
Train::Transports::Local::CommandResult.new(
|
||||
'Mock Command Result stdout',
|
||||
'Mock Command Result stderr',
|
||||
17
|
||||
)
|
||||
end
|
||||
|
||||
def file_via_connection(path, *args)
|
||||
MockFile.new(self, path)
|
||||
end
|
||||
|
||||
class MockFile < Train::File
|
||||
def content
|
||||
# Remarkably, the content is always the same.
|
||||
'Lorem Ipsum'
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,18 @@
|
|||
require 'train-test-fixture/version'
|
||||
|
||||
module TrainPlugins
|
||||
module TestFixture
|
||||
module Platform
|
||||
def platform
|
||||
# Build this platform's family declarations.
|
||||
# You'll need at least unix and windows to make the file() resource work.
|
||||
Train::Platforms.name('test-fixture').in_family('unix')
|
||||
Train::Platforms.name('test-fixture').in_family('windows')
|
||||
force_platform!('test-fixture',
|
||||
release: TrainPlugins::TestFixture::VERSION,
|
||||
arch: 'mock',
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,14 @@
|
|||
require 'train-test-fixture/connection'
|
||||
|
||||
module TrainPlugins
|
||||
module TestFixture
|
||||
class Transport < Train.plugin(1)
|
||||
name 'test-fixture'
|
||||
|
||||
def connection(_ = nil)
|
||||
@connection ||= TrainPlugins::TestFixture::Connection.new(@options)
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,5 @@
|
|||
module TrainPlugins
|
||||
module TestFixture
|
||||
VERSION = '0.1.0'
|
||||
end
|
||||
end
|
|
@ -0,0 +1,35 @@
|
|||
|
||||
lib = File.expand_path("../lib", __FILE__)
|
||||
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
||||
|
||||
Gem::Specification.new do |spec|
|
||||
spec.name = "train-test-fixture"
|
||||
spec.version = '0.1.0'
|
||||
spec.authors = ["Inspec core engineering team"]
|
||||
spec.email = ["hello@chef.io"]
|
||||
spec.license = 'Apache-2.0'
|
||||
|
||||
spec.summary = %q{Test train plugin. Not intended for use as an example.}
|
||||
spec.description = <<~EOD
|
||||
Train plugin used in testing Train's plugin loader and InSpec's plugin manager.
|
||||
This plugin does things that a normal plugin should not. Do not use it as an
|
||||
example or as a starting point for plugin of your own. For that, please see
|
||||
https://github.com/inspec/train/tree/master/examples/plugins
|
||||
EOD
|
||||
spec.homepage = "https://github.com/inspec/train"
|
||||
|
||||
spec.files = %w{
|
||||
README.md
|
||||
LICENSE
|
||||
lib/train-test-fixture.rb
|
||||
lib/train-test-fixture/version.rb
|
||||
lib/train-test-fixture/transport.rb
|
||||
lib/train-test-fixture/connection.rb
|
||||
lib/train-test-fixture/platform.rb
|
||||
train-test-fixture.gemspec
|
||||
}
|
||||
spec.executables = []
|
||||
spec.require_paths = ["lib"]
|
||||
|
||||
# No deps
|
||||
end
|
|
@ -0,0 +1,20 @@
|
|||
# -*- encoding: utf-8 -*-
|
||||
# stub: train-test-fixture 0.1.0 ruby lib
|
||||
|
||||
Gem::Specification.new do |s|
|
||||
s.name = "train-test-fixture".freeze
|
||||
s.version = "0.1.0"
|
||||
|
||||
s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
|
||||
s.require_paths = ["lib".freeze]
|
||||
s.authors = ["Inspec core engineering team".freeze]
|
||||
s.date = "2018-09-26"
|
||||
s.description = "Train plugin used in testing Train's plugin loader and InSpec's plugin manager.\nThis plugin does things that a normal plugin should not. Do not use it as an\nexample or as a starting point for plugin of your own. For that, please see\nhttps://github.com/inspec/train/tree/master/examples/plugins\n".freeze
|
||||
s.email = ["hello@chef.io".freeze]
|
||||
s.homepage = "https://github.com/inspec/train".freeze
|
||||
s.licenses = ["Apache-2.0".freeze]
|
||||
s.rubygems_version = "2.6.13".freeze
|
||||
s.summary = "Test train plugin. Not intended for use as an example.".freeze
|
||||
|
||||
s.installed_by_version = "2.6.13" if s.respond_to? :installed_by_version
|
||||
end
|
|
@ -0,0 +1,201 @@
|
|||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
|
@ -0,0 +1,5 @@
|
|||
This is a very simple train transport plugin. It provided fixed responses to file.content and command.stdout/stderr/exit_status.
|
||||
|
||||
It is not a good example to use for learning, nor a good base for starting your own plugin - it's intended for for use during the testing of Train.
|
||||
|
||||
For good examples of plugin development, see train/examples/plugin.
|
|
@ -0,0 +1,4 @@
|
|||
lib = File.expand_path("../../lib", __FILE__)
|
||||
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
||||
|
||||
require 'train-test-fixture/transport'
|
|
@ -0,0 +1,39 @@
|
|||
require 'train-test-fixture/platform'
|
||||
require 'train/transports/local'
|
||||
|
||||
module TrainPlugins
|
||||
module TestFixture
|
||||
class Connection < Train::Plugins::Transport::BaseConnection
|
||||
include TrainPlugins::TestFixture::Platform
|
||||
|
||||
def initialize(options)
|
||||
super(options)
|
||||
end
|
||||
|
||||
def local?
|
||||
true
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def run_command_via_connection(cmd)
|
||||
Train::Transports::Local::CommandResult.new(
|
||||
'Mock Command Result stdout',
|
||||
'Mock Command Result stderr',
|
||||
17
|
||||
)
|
||||
end
|
||||
|
||||
def file_via_connection(path, *args)
|
||||
MockFile.new(self, path)
|
||||
end
|
||||
|
||||
class MockFile < Train::File
|
||||
def content
|
||||
# Remarkably, the content is always the same.
|
||||
'Lorem Ipsum'
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,18 @@
|
|||
require 'train-test-fixture/version'
|
||||
|
||||
module TrainPlugins
|
||||
module TestFixture
|
||||
module Platform
|
||||
def platform
|
||||
# Build this platform's family declarations.
|
||||
# You'll need at least unix and windows to make the file() resource work.
|
||||
Train::Platforms.name('test-fixture').in_family('unix')
|
||||
Train::Platforms.name('test-fixture').in_family('windows')
|
||||
force_platform!('test-fixture',
|
||||
release: TrainPlugins::TestFixture::VERSION,
|
||||
arch: 'mock',
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,14 @@
|
|||
require 'train-test-fixture/connection'
|
||||
|
||||
module TrainPlugins
|
||||
module TestFixture
|
||||
class Transport < Train.plugin(1)
|
||||
name 'test-fixture'
|
||||
|
||||
def connection(_ = nil)
|
||||
@connection ||= TrainPlugins::TestFixture::Connection.new(@options)
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,5 @@
|
|||
module TrainPlugins
|
||||
module TestFixture
|
||||
VERSION = '0.1.0'
|
||||
end
|
||||
end
|
|
@ -0,0 +1,35 @@
|
|||
|
||||
lib = File.expand_path("../lib", __FILE__)
|
||||
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
||||
|
||||
Gem::Specification.new do |spec|
|
||||
spec.name = "train-test-fixture"
|
||||
spec.version = '0.1.0'
|
||||
spec.authors = ["Inspec core engineering team"]
|
||||
spec.email = ["hello@chef.io"]
|
||||
spec.license = 'Apache-2.0'
|
||||
|
||||
spec.summary = %q{Test train plugin. Not intended for use as an example.}
|
||||
spec.description = <<~EOD
|
||||
Train plugin used in testing Train's plugin loader and InSpec's plugin manager.
|
||||
This plugin does things that a normal plugin should not. Do not use it as an
|
||||
example or as a starting point for plugin of your own. For that, please see
|
||||
https://github.com/inspec/train/tree/master/examples/plugins
|
||||
EOD
|
||||
spec.homepage = "https://github.com/inspec/train"
|
||||
|
||||
spec.files = %w{
|
||||
README.md
|
||||
LICENSE
|
||||
lib/train-test-fixture.rb
|
||||
lib/train-test-fixture/version.rb
|
||||
lib/train-test-fixture/transport.rb
|
||||
lib/train-test-fixture/connection.rb
|
||||
lib/train-test-fixture/platform.rb
|
||||
train-test-fixture.gemspec
|
||||
}
|
||||
spec.executables = []
|
||||
spec.require_paths = ["lib"]
|
||||
|
||||
# No deps
|
||||
end
|
|
@ -0,0 +1,20 @@
|
|||
# -*- encoding: utf-8 -*-
|
||||
# stub: train-test-fixture 0.1.0 ruby lib
|
||||
|
||||
Gem::Specification.new do |s|
|
||||
s.name = "train-test-fixture".freeze
|
||||
s.version = "0.1.0"
|
||||
|
||||
s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
|
||||
s.require_paths = ["lib".freeze]
|
||||
s.authors = ["Inspec core engineering team".freeze]
|
||||
s.date = "2018-09-26"
|
||||
s.description = "Train plugin used in testing Train's plugin loader and InSpec's plugin manager.\nThis plugin does things that a normal plugin should not. Do not use it as an\nexample or as a starting point for plugin of your own. For that, please see\nhttps://github.com/inspec/train/tree/master/examples/plugins\n".freeze
|
||||
s.email = ["hello@chef.io".freeze]
|
||||
s.homepage = "https://github.com/inspec/train".freeze
|
||||
s.licenses = ["Apache-2.0".freeze]
|
||||
s.rubygems_version = "2.6.13".freeze
|
||||
s.summary = "Test train plugin. Not intended for use as an example.".freeze
|
||||
|
||||
s.installed_by_version = "2.6.13" if s.respond_to? :installed_by_version
|
||||
end
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"plugins_config_version" : "1.0.0",
|
||||
"plugins": [
|
||||
{
|
||||
"name": "train-test-fixture"
|
||||
}
|
||||
]
|
||||
}
|
|
@ -1,2 +1,5 @@
|
|||
lib = File.expand_path("../../lib", __FILE__)
|
||||
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
||||
|
||||
require_relative 'inspec-test-fixture/version'
|
||||
require_relative 'inspec-test-fixture/plugin'
|
||||
|
|
|
@ -4,6 +4,8 @@ require 'minitest/autorun'
|
|||
require 'minitest/test'
|
||||
require_relative '../../../../lib/inspec/plugin/v2'
|
||||
|
||||
require 'train' # Needed for Train plugin testing
|
||||
|
||||
class PluginLoaderTests < MiniTest::Test
|
||||
|
||||
@@orig_home = Dir.home
|
||||
|
@ -228,4 +230,28 @@ class PluginLoaderTests < MiniTest::Test
|
|||
assert InspecPlugins::MeaningOfLife.const_defined?(:MockPlugin), 'impl_class should now be defined'
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
#====================================================================#
|
||||
# Train Plugin Special Handling #
|
||||
#====================================================================#
|
||||
def test_when_a_train_plugin_is_installed_via_gem_and_required
|
||||
ENV['INSPEC_CONFIG_DIR'] = File.join(@config_dir_path, 'train-test-fixture')
|
||||
|
||||
reg = Inspec::Plugin::V2::Registry.instance
|
||||
loader = nil
|
||||
assert_silent { loader = Inspec::Plugin::V2::Loader.new }
|
||||
|
||||
plugin_name = :'train-test-fixture'
|
||||
assert(reg.known_plugin?(plugin_name), 'The train plugin should be known after loader init')
|
||||
|
||||
status = reg[plugin_name]
|
||||
assert_equal(:'train-1', status.api_generation, "It should have a special value for api gen (:'train-1')")
|
||||
refute(reg.loaded_plugin?(plugin_name), 'It should not be loaded until needed')
|
||||
|
||||
# 'Requiring' the gem name should succeed
|
||||
|
||||
require 'train-test-fixture'
|
||||
assert_includes(Train::Plugins.registry.keys, 'test-fixture', 'After requiring the gem, the Train Registry should know the plugin is loaded')
|
||||
assert(reg.loaded_plugin?(plugin_name), 'After requiring, InSpec Registry should know the the plugin is loaded')
|
||||
end
|
||||
end
|
Loading…
Reference in a new issue