Merge pull request #5452 from inspec/nm/shell-inputs

Added ability to pass inputs to InSpec shell using input file and cli
This commit is contained in:
Clinton Wolfe 2021-04-13 20:39:12 -04:00 committed by GitHub
commit c57ef924fc
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 81 additions and 0 deletions

View file

@ -230,3 +230,49 @@ $ inspec shell --format json -c 'describe file("/Users/test") do it { should exi
}
}
```
## Running Chef InSpec Shell With Inputs
With InSpec [profiles that support inputs](inspec/inputs/#which-profiles-support-inputs),
you can set inputs using the InSpec `shell` command. This allows you to work more consistently with
InSpec profiles when switching between the `shell` and `exec` commands.
For more details on inputs, see the [inputs reference](/inspec/inputs/).
### Set Inputs with Command-line Options
The `shell` command accepts one or more inputs in the command line as single-quoted YAML or JSON structures.
```bash
$ inspec shell --input=input_name=input_value
Welcome to the interactive InSpec Shell
To find out how to use it, type: help
inspec> control 'my_control' do
inspec> describe input('input_name') do
inspec> it { should cmp 'input_value' }
inspec> end
inspec> end
Profile: inspec-shell
✔ my_control: input_value
✔ input_value is expected to cmp == "input_value"
Profile Summary: 1 successful control, 0 control failures, 0 controls skipped
Test Summary: 1 successful, 0 failures, 0 skipped
inspec> exit
```
### Set Inputs with YAML File
You can also save inputs and values to one or more YAML files and pass them to `shell` in the command line.
For example:
```yaml
input_name: input_value
another_input: another_value
```
```bash
inspec shell --input-file=<path>
```

View file

@ -325,6 +325,10 @@ class Inspec::InspecCLI < Inspec::BaseCLI
desc: "Maximum seconds to allow a command to run. Default 3600.",
long_desc: "Maximum seconds to allow commands to run. Default 3600. A timed out command is considered an error."
option :inspect, type: :boolean, default: false, desc: "Use verbose/debugging output for resources."
option :input_file, type: :array,
desc: "Load one or more input files, a YAML file with values for the shell to use"
option :input, type: :array, banner: "name1=value1 name2=value2",
desc: "Specify one or more inputs directly on the command line to the shell, as --input NAME=VALUE. Accepts single-quoted YAML and JSON structures."
def shell_func
o = config
diagnose(o)

View file

@ -2,6 +2,7 @@ require "functional/helper"
describe "inspec shell tests" do
include FunctionalHelper
let(:input_file_from_basic_input_profile) { File.join(profile_path, "inputs", "basic", "files", "flat.yaml") }
parallelize_me!
@ -22,6 +23,22 @@ describe "inspec shell tests" do
out
end
def assert_shell_c_with_inputs(code, input_cmd, input, exit_status, json = false, stderr = "")
json_suffix = " --reporter 'json'" if json
command = "shell -c '#{code.tr("'", '\\\'')}'#{input_cmd} #{input}#{json_suffix}"
# On darwin this value is:
# shell -c 'describe file(\"/Users/nickschwaderer/Documents/inspec/inspec/test/functional/inspec_shell_test.rb\") do it { should exist } end' --reporter 'json'"
# appears to break in windows.
out = inspec(command)
actual = out.stderr.gsub(/\e\[(\d+)(;\d+)*m/, "") # strip ANSI color codes
_(actual).must_equal stderr
assert_exit_code exit_status, out
out
end
it "loads a dependency" do
res = inspec("shell -c 'example_config' --depends #{example_profile}")
@ -178,6 +195,20 @@ describe "inspec shell tests" do
_(out.stdout).must_include "0 successful"
_(out.stdout).must_include "1 failure"
end
it "loads input from external input file" do
skip_windows! # Breakage confirmed
out = assert_shell_c_with_inputs("describe input(\"a_quoted_string\") do it { should cmp \"Should not have quotes\" } end", " --input-file", input_file_from_basic_input_profile, 0)
_(out.stdout).must_include "1 successful"
_(out.stdout).must_include "0 failures"
end
it "loads input from input cli" do
skip_windows! # Breakage confirmed
out = assert_shell_c_with_inputs("describe input(\"test_input_01\") do it { should cmp \"value_from_cli_01\" } end", " --input", "test_input_01='value_from_cli_01'", 0)
_(out.stdout).must_include "1 successful"
_(out.stdout).must_include "0 failures"
end
end
# Pry does not support STDIN from windows currently. Skipping these for now.