inspec-core 3.7.1 → 3.7.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/inspec/config.rb +12 -0
- data/lib/inspec/shell.rb +2 -15
- data/lib/inspec/version.rb +1 -1
- data/lib/plugins/inspec-habitat/Berksfile +5 -0
- data/lib/plugins/inspec-habitat/README.md +150 -0
- data/lib/plugins/inspec-habitat/kitchen.yml +28 -0
- data/lib/plugins/inspec-habitat/lib/inspec-habitat/cli.rb +9 -9
- data/lib/plugins/inspec-habitat/lib/inspec-habitat/profile.rb +164 -280
- data/lib/plugins/inspec-habitat/templates/habitat/config/inspec_exec_config.json.erb +25 -0
- data/lib/plugins/inspec-habitat/templates/habitat/default.toml.erb +9 -0
- data/lib/plugins/inspec-habitat/templates/habitat/hooks/run.erb +32 -0
- data/lib/plugins/inspec-habitat/templates/habitat/plan.sh.erb +85 -0
- data/lib/plugins/inspec-habitat/test/cookbooks/inspec_habitat_fixture/Berksfile +2 -0
- data/lib/plugins/inspec-habitat/test/cookbooks/inspec_habitat_fixture/README.md +3 -0
- data/lib/plugins/inspec-habitat/test/cookbooks/inspec_habitat_fixture/files/hab_setup.exp +28 -0
- data/lib/plugins/inspec-habitat/test/cookbooks/inspec_habitat_fixture/metadata.rb +9 -0
- data/lib/plugins/inspec-habitat/test/cookbooks/inspec_habitat_fixture/recipes/default.rb +61 -0
- data/lib/plugins/inspec-habitat/test/functional/inspec_habitat_test.rb +38 -0
- data/lib/plugins/inspec-habitat/test/integration/default/inspec_habitat/README.md +3 -0
- data/lib/plugins/inspec-habitat/test/integration/default/inspec_habitat/controls/inspec_habitat.rb +40 -0
- data/lib/plugins/inspec-habitat/test/integration/default/inspec_habitat/inspec.yml +10 -0
- data/lib/plugins/inspec-habitat/test/support/example_profile/README.md +3 -0
- data/lib/plugins/inspec-habitat/test/support/example_profile/controls/example.rb +7 -0
- data/lib/plugins/inspec-habitat/test/support/example_profile/inspec.yml +10 -0
- data/lib/plugins/inspec-habitat/test/unit/profile_test.rb +188 -132
- data/lib/plugins/inspec-init/test/functional/inspec_init_profile_test.rb +12 -0
- data/lib/resources/aide_conf.rb +2 -2
- data/lib/resources/apache.rb +2 -2
- data/lib/resources/apache_conf.rb +2 -2
- data/lib/resources/apt.rb +2 -2
- data/lib/resources/audit_policy.rb +2 -2
- data/lib/resources/auditd.rb +2 -2
- data/lib/resources/auditd_conf.rb +2 -2
- data/lib/resources/bash.rb +2 -2
- data/lib/resources/bond.rb +2 -2
- data/lib/resources/bridge.rb +2 -2
- data/lib/resources/chocolatey_package.rb +2 -2
- data/lib/resources/command.rb +2 -2
- data/lib/resources/cpan.rb +2 -2
- data/lib/resources/cran.rb +2 -2
- data/lib/resources/crontab.rb +2 -2
- data/lib/resources/csv.rb +2 -2
- data/lib/resources/dh_params.rb +2 -2
- data/lib/resources/directory.rb +2 -2
- data/lib/resources/docker.rb +2 -2
- data/lib/resources/docker_container.rb +2 -2
- data/lib/resources/docker_image.rb +2 -2
- data/lib/resources/docker_plugin.rb +2 -2
- data/lib/resources/docker_service.rb +2 -2
- data/lib/resources/elasticsearch.rb +2 -2
- data/lib/resources/etc_fstab.rb +2 -2
- data/lib/resources/etc_group.rb +2 -2
- data/lib/resources/etc_hosts.rb +2 -2
- data/lib/resources/etc_hosts_allow_deny.rb +4 -4
- data/lib/resources/file.rb +2 -2
- data/lib/resources/filesystem.rb +2 -2
- data/lib/resources/firewalld.rb +2 -2
- data/lib/resources/gem.rb +2 -2
- data/lib/resources/groups.rb +4 -4
- data/lib/resources/grub_conf.rb +2 -2
- data/lib/resources/host.rb +2 -2
- data/lib/resources/http.rb +25 -5
- data/lib/resources/iis_app.rb +2 -2
- data/lib/resources/iis_app_pool.rb +6 -3
- data/lib/resources/iis_site.rb +4 -4
- data/lib/resources/inetd_conf.rb +2 -2
- data/lib/resources/ini.rb +2 -2
- data/lib/resources/interface.rb +2 -2
- data/lib/resources/iptables.rb +2 -2
- data/lib/resources/json.rb +2 -3
- data/lib/resources/kernel_module.rb +17 -18
- data/lib/resources/kernel_parameter.rb +2 -2
- data/lib/resources/key_rsa.rb +2 -2
- data/lib/resources/ksh.rb +2 -2
- data/lib/resources/limits_conf.rb +2 -2
- data/lib/resources/login_def.rb +2 -2
- data/lib/resources/mount.rb +2 -2
- data/lib/resources/mssql_session.rb +2 -2
- data/lib/resources/mysql_conf.rb +2 -2
- data/lib/resources/mysql_session.rb +2 -2
- data/lib/resources/nginx.rb +2 -2
- data/lib/resources/nginx_conf.rb +2 -2
- data/lib/resources/npm.rb +2 -2
- data/lib/resources/ntp_conf.rb +2 -2
- data/lib/resources/oneget.rb +2 -2
- data/lib/resources/oracledb_session.rb +2 -2
- data/lib/resources/os.rb +2 -2
- data/lib/resources/os_env.rb +2 -2
- data/lib/resources/package.rb +2 -2
- data/lib/resources/packages.rb +2 -2
- data/lib/resources/parse_config.rb +4 -4
- data/lib/resources/passwd.rb +2 -2
- data/lib/resources/pip.rb +2 -2
- data/lib/resources/platform.rb +2 -2
- data/lib/resources/port.rb +2 -2
- data/lib/resources/postgres_conf.rb +2 -2
- data/lib/resources/postgres_hba_conf.rb +2 -2
- data/lib/resources/postgres_ident_conf.rb +2 -2
- data/lib/resources/postgres_session.rb +2 -2
- data/lib/resources/powershell.rb +2 -2
- data/lib/resources/processes.rb +2 -2
- data/lib/resources/rabbitmq_conf.rb +2 -2
- data/lib/resources/registry_key.rb +2 -2
- data/lib/resources/security_identifier.rb +2 -2
- data/lib/resources/security_policy.rb +2 -2
- data/lib/resources/service.rb +14 -14
- data/lib/resources/shadow.rb +2 -2
- data/lib/resources/ssh_conf.rb +4 -4
- data/lib/resources/ssl.rb +2 -2
- data/lib/resources/sys_info.rb +2 -2
- data/lib/resources/toml.rb +2 -2
- data/lib/resources/users.rb +4 -4
- data/lib/resources/vbscript.rb +2 -2
- data/lib/resources/virtualization.rb +2 -2
- data/lib/resources/windows_feature.rb +2 -2
- data/lib/resources/windows_hotfix.rb +2 -2
- data/lib/resources/windows_task.rb +2 -2
- data/lib/resources/wmi.rb +2 -2
- data/lib/resources/x509_certificate.rb +2 -2
- data/lib/resources/xinetd.rb +2 -2
- data/lib/resources/xml.rb +2 -2
- data/lib/resources/yaml.rb +2 -2
- data/lib/resources/yum.rb +2 -2
- data/lib/resources/zfs_dataset.rb +2 -2
- data/lib/resources/zfs_pool.rb +2 -2
- metadata +36 -4
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"target_id": "{{ sys.member_id }}",
|
|
3
|
+
"reporter": {
|
|
4
|
+
"cli": {
|
|
5
|
+
"stdout": {{cfg.report_to_stdout}}
|
|
6
|
+
},
|
|
7
|
+
"json": {
|
|
8
|
+
"file": "{{pkg.svc_path}}/logs/inspec_last_run.json"
|
|
9
|
+
}{{#if cfg.automate.token ~}},
|
|
10
|
+
"automate" : {
|
|
11
|
+
"url": "{{cfg.automate.url}}/data-collector/v0/",
|
|
12
|
+
"token": "{{cfg.automate.token}}",
|
|
13
|
+
"node_name": "{{ sys.hostname }}",
|
|
14
|
+
"verify_ssl": false
|
|
15
|
+
}{{/if ~}}
|
|
16
|
+
}
|
|
17
|
+
{{#if cfg.automate.token }},
|
|
18
|
+
"compliance": {
|
|
19
|
+
"server" : "{{cfg.automate.url}}",
|
|
20
|
+
"token" : "{{cfg.automate.token}}",
|
|
21
|
+
"user" : "{{cfg.automate.user}}",
|
|
22
|
+
"insecure" : true,
|
|
23
|
+
"ent" : "automate"
|
|
24
|
+
}{{/if }}
|
|
25
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
#!/bin/sh
|
|
2
|
+
|
|
3
|
+
exec 2>&1
|
|
4
|
+
|
|
5
|
+
CONFIG="{{pkg.svc_config_path}}/inspec_exec_config.json"
|
|
6
|
+
INTERVAL="{{cfg.interval}}"
|
|
7
|
+
LOG_FILE="{{pkg.svc_path}}/logs/inspec_log.txt"
|
|
8
|
+
PROFILE_IDENT="{{pkg.origin}}/{{pkg.name}}"
|
|
9
|
+
PROFILE_PATH="{{pkg.path}}/{{pkg.name}}-{{pkg.version}}.tar.gz"
|
|
10
|
+
|
|
11
|
+
while true; do
|
|
12
|
+
echo "Executing ${PROFILE_IDENT}"
|
|
13
|
+
exec inspec exec ${PROFILE_PATH} --json-config ${CONFIG} 2>&1 | tee ${LOG_FILE}
|
|
14
|
+
|
|
15
|
+
exit_code=$?
|
|
16
|
+
if [ $exit_code -eq 1 ]; then
|
|
17
|
+
echo "InSpec run failed."
|
|
18
|
+
else
|
|
19
|
+
echo "InSpec run completed successfully."
|
|
20
|
+
if [ $exit_code -eq 0 ]; then
|
|
21
|
+
echo "No controls failed or were skipped."
|
|
22
|
+
elif [ $exit_code -eq 100 ]; then
|
|
23
|
+
echo "At least 1 control failed."
|
|
24
|
+
elif [ $exit_code -eq 101 ]; then
|
|
25
|
+
echo "No controls failed but at least 1 skipped."
|
|
26
|
+
fi
|
|
27
|
+
fi
|
|
28
|
+
echo "Results are logged here: ${LOG_FILE}"
|
|
29
|
+
|
|
30
|
+
echo "Sleeping for ${INTERVAL} seconds"
|
|
31
|
+
sleep ${INTERVAL}
|
|
32
|
+
done
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
pkg_name=<%= "inspec-profile-#{profile.name}" %>
|
|
2
|
+
pkg_version=<%= profile.version %>
|
|
3
|
+
pkg_origin=<%= habitat_origin %>
|
|
4
|
+
pkg_deps=(chef/inspec)
|
|
5
|
+
pkg_build_deps=(chef/inspec core/jq-static)
|
|
6
|
+
pkg_svc_user=root
|
|
7
|
+
<%= "pkg_license='#{profile.metadata.params[:license]}'" if profile.metadata.params[:license]%>
|
|
8
|
+
|
|
9
|
+
do_before() {
|
|
10
|
+
# Exit with error if not in the directory with 'inspec.yml'.
|
|
11
|
+
# This can happen if someone does 'hab studio enter' from within the
|
|
12
|
+
# 'habitat/' directory.
|
|
13
|
+
if [ ! -f "$PLAN_CONTEXT/../inspec.yml" ]; then
|
|
14
|
+
message="ERROR: Cannot find inspec.yml."
|
|
15
|
+
message="$message Please build from the profile root"
|
|
16
|
+
build_line "$message"
|
|
17
|
+
|
|
18
|
+
return 1
|
|
19
|
+
fi
|
|
20
|
+
|
|
21
|
+
# Execute an 'inspec compliance login' if a profile needs to be fetched from
|
|
22
|
+
# the Automate server
|
|
23
|
+
if [ "$(grep "compliance: " "$PLAN_CONTEXT/../inspec.yml")" ]; then
|
|
24
|
+
_do_compliance_login;
|
|
25
|
+
fi
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
do_setup_environment() {
|
|
29
|
+
set_buildtime_env PROFILE_CACHE_DIR "$HAB_CACHE_SRC_PATH/$pkg_dirname"
|
|
30
|
+
set_buildtime_env ARCHIVE_NAME "$pkg_name-$pkg_version.tar.gz"
|
|
31
|
+
|
|
32
|
+
# InSpec loads `pry` which tries to expand `~`. This fails if HOME isn't set.
|
|
33
|
+
set_runtime_env HOME "$pkg_svc_var_path"
|
|
34
|
+
|
|
35
|
+
# InSpec will create a `.inspec` directory in the user's home directory.
|
|
36
|
+
# This overrides that to write to a place within the running service's path.
|
|
37
|
+
# NOTE: Setting HOME does the same currently. This is here to be explicit.
|
|
38
|
+
set_runtime_env INSPEC_CONFIG_DIR "$pkg_svc_var_path"
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
do_unpack() {
|
|
42
|
+
# Change directory to where the profile files are
|
|
43
|
+
pushd "$PLAN_CONTEXT/../" > /dev/null
|
|
44
|
+
|
|
45
|
+
# Get a list of all files in the profile except those that are Habitat related
|
|
46
|
+
profile_files=($(ls -I habitat -I results -I "*.hart"))
|
|
47
|
+
|
|
48
|
+
mkdir -p "$PROFILE_CACHE_DIR" > /dev/null
|
|
49
|
+
|
|
50
|
+
# Copy just the profile files to the profile cache directory
|
|
51
|
+
cp -r ${profile_files[@]} "$PROFILE_CACHE_DIR"
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
do_build() {
|
|
55
|
+
inspec archive "$PROFILE_CACHE_DIR" \
|
|
56
|
+
--overwrite \
|
|
57
|
+
-o "$PROFILE_CACHE_DIR/$ARCHIVE_NAME"
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
do_install() {
|
|
61
|
+
cp "$PROFILE_CACHE_DIR/$ARCHIVE_NAME" "$pkg_prefix"
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
_do_compliance_login() {
|
|
65
|
+
if [ -z $COMPLIANCE_CREDS ]; then
|
|
66
|
+
message="ERROR: Please perform an 'inspec compliance login' and set"
|
|
67
|
+
message="$message \$HAB_STUDIO_SECRET_COMPLIANCE_CREDS to the contents of"
|
|
68
|
+
message="$message '~/.inspec/compliance/config.json'"
|
|
69
|
+
build_line "$message"
|
|
70
|
+
return 1
|
|
71
|
+
fi
|
|
72
|
+
|
|
73
|
+
user=$(echo $COMPLIANCE_CREDS | jq .user | sed 's/"//g')
|
|
74
|
+
token=$(echo $COMPLIANCE_CREDS | jq .token | sed 's/"//g')
|
|
75
|
+
automate_server=$(echo $COMPLIANCE_CREDS | \
|
|
76
|
+
jq .server | \
|
|
77
|
+
sed 's/\/api\/v0//' | \
|
|
78
|
+
sed 's/"//g'
|
|
79
|
+
)
|
|
80
|
+
insecure=$(echo $COMPLIANCE_CREDS | jq .insecure)
|
|
81
|
+
inspec compliance login --insecure $insecure \
|
|
82
|
+
--user $user \
|
|
83
|
+
--token $token \
|
|
84
|
+
$automate_server
|
|
85
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
#!/usr/bin/expect -f
|
|
2
|
+
|
|
3
|
+
set timeout -1
|
|
4
|
+
|
|
5
|
+
spawn hab setup
|
|
6
|
+
|
|
7
|
+
expect "Connect to an on-premises bldr instance?"
|
|
8
|
+
send -- "No\r"
|
|
9
|
+
|
|
10
|
+
expect "Set up a default origin?"
|
|
11
|
+
send -- "Yes\r"
|
|
12
|
+
|
|
13
|
+
expect "Default origin name"
|
|
14
|
+
send -- "vagrant\r"
|
|
15
|
+
|
|
16
|
+
expect "Create an origin key for `vagrant'?"
|
|
17
|
+
send -- "Yes\r"
|
|
18
|
+
|
|
19
|
+
expect "Set up a default Habitat personal access token?"
|
|
20
|
+
send -- "No\r"
|
|
21
|
+
|
|
22
|
+
expect "Set up a default Habitat Supervisor CtlGateway secret?"
|
|
23
|
+
send -- "No\r"
|
|
24
|
+
|
|
25
|
+
expect "Enable analytics?"
|
|
26
|
+
send -- "No\r"
|
|
27
|
+
|
|
28
|
+
expect eof
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Cookbook:: kitchen_setup_cookbook
|
|
3
|
+
# Recipe:: default
|
|
4
|
+
#
|
|
5
|
+
# Copyright:: 2019, The Authors, All Rights Reserved.
|
|
6
|
+
|
|
7
|
+
package %w(ruby ruby-dev gcc g++ make expect)
|
|
8
|
+
|
|
9
|
+
base_dir = '/home/vagrant'
|
|
10
|
+
|
|
11
|
+
cookbook_file "#{base_dir}/inspec-local.gem" do
|
|
12
|
+
source 'inspec-local.gem'
|
|
13
|
+
action :create
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
gem_package 'inspec' do
|
|
17
|
+
source "#{base_dir}/inspec-local.gem"
|
|
18
|
+
subscribes :install, "cookbook_file[#{base_dir}/inspec-local.gem]", :immediately
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
cookbook_file "#{base_dir}/hab_setup.exp" do
|
|
22
|
+
source 'hab_setup.exp'
|
|
23
|
+
mode '0755'
|
|
24
|
+
action :create
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
hab_install 'install habitat'
|
|
28
|
+
hab_sup 'setup hab supervisor'
|
|
29
|
+
|
|
30
|
+
execute 'setup hab cli' do
|
|
31
|
+
command "#{base_dir}/hab_setup.exp"
|
|
32
|
+
live_stream true
|
|
33
|
+
not_if { ::File.exist?('/hab/etc/cli.toml') }
|
|
34
|
+
not_if { ::File.exist?('~/.hab/etc/cli.toml') }
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
execute 'create inspec profile for testing' do
|
|
38
|
+
command "inspec init profile #{base_dir}/hab_test_profile"
|
|
39
|
+
live_stream true
|
|
40
|
+
creates "#{base_dir}/hab_test_profile"
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
directory "#{base_dir}/output"
|
|
44
|
+
|
|
45
|
+
execute 'create hart file from profile' do
|
|
46
|
+
command "inspec habitat profile create #{base_dir}/hab_test_profile --output_dir '#{base_dir}/output'"
|
|
47
|
+
live_stream true
|
|
48
|
+
not_if "find #{base_dir}/output | grep vagrant-inspec-profile-hab_test_profile-0.1.0-.*.hart"
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
execute 'install vagrant/inspec-profile-hab_test_profile' do
|
|
52
|
+
command "hab pkg install #{base_dir}/output/*.hart"
|
|
53
|
+
live_stream true
|
|
54
|
+
not_if 'hab pkg list --origin vagrant | grep inspec-profile'
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
execute 'load vagrant/inspec-profile-hab_test_profile into supervisor' do
|
|
58
|
+
command 'hab svc load vagrant/inspec-profile-hab_test_profile'
|
|
59
|
+
live_stream true
|
|
60
|
+
not_if 'sudo hab svc status | grep "vagrant/inspec-profile-hab_test_profile"'
|
|
61
|
+
end
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
require_relative '../../../shared/core_plugin_test_helper.rb'
|
|
2
|
+
require 'fileutils'
|
|
3
|
+
|
|
4
|
+
class ProfileCli < MiniTest::Test
|
|
5
|
+
include CorePluginFunctionalHelper
|
|
6
|
+
|
|
7
|
+
def setup
|
|
8
|
+
@tmpdir = Dir.mktmpdir
|
|
9
|
+
@habitat_profile = File.join(@tmpdir, 'habitat-profile')
|
|
10
|
+
run_inspec_process('init profile ' + @habitat_profile)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def teardown
|
|
14
|
+
FileUtils.remove_entry_secure(@tmpdir)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def test_setup_subcommand
|
|
18
|
+
result = run_inspec_process('habitat profile setup ' + @habitat_profile + ' --log-level debug')
|
|
19
|
+
|
|
20
|
+
# Command runs without error
|
|
21
|
+
assert_empty result.stderr
|
|
22
|
+
assert_equal 0, result.exit_status
|
|
23
|
+
|
|
24
|
+
# Command creates only expected files
|
|
25
|
+
base_dir = File.join(@tmpdir, 'habitat-profile', 'habitat')
|
|
26
|
+
files = %w{
|
|
27
|
+
default.toml
|
|
28
|
+
plan.sh
|
|
29
|
+
config
|
|
30
|
+
config/inspec_exec_config.json
|
|
31
|
+
hooks
|
|
32
|
+
hooks/run
|
|
33
|
+
}
|
|
34
|
+
actual_files = Dir.glob(File.join(base_dir, '**/*'))
|
|
35
|
+
expected_files = files.map { |x| File.join(base_dir, x) }
|
|
36
|
+
assert_equal actual_files.sort, expected_files.sort
|
|
37
|
+
end
|
|
38
|
+
end
|
data/lib/plugins/inspec-habitat/test/integration/default/inspec_habitat/controls/inspec_habitat.rb
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
control 'inspec-habitat-create' do
|
|
2
|
+
title 'Create command'
|
|
3
|
+
|
|
4
|
+
output_hart_dir = '/home/vagrant/output'
|
|
5
|
+
find_hart_output = command("find #{output_hart_dir} -name '*.hart'").stdout
|
|
6
|
+
hart_files = find_hart_output.split("\n")
|
|
7
|
+
|
|
8
|
+
hab_profile_path = '/home/vagrant/hab_test_profile'
|
|
9
|
+
find_profile_files_command = "find #{hab_profile_path} -type f -printf '%f\n'"
|
|
10
|
+
profile_files = command(find_profile_files_command).stdout.split("\n").sort
|
|
11
|
+
expected_files = %w{
|
|
12
|
+
.gitkeep
|
|
13
|
+
README.md
|
|
14
|
+
example.rb
|
|
15
|
+
inspec.yml
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
describe '`inspec habitat profile create`' do
|
|
19
|
+
it 'should create exactly 1 hart file' do
|
|
20
|
+
expect(hart_files.length).to eq(1)
|
|
21
|
+
end
|
|
22
|
+
it 'does not add any extra files to a default generated profile' do
|
|
23
|
+
expect(profile_files).to eq(expected_files)
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
control 'inspec-habitat-service' do
|
|
29
|
+
title 'inspec-profile-hab_test_profile service'
|
|
30
|
+
describe 'The running service' do
|
|
31
|
+
it 'should create a log file' do
|
|
32
|
+
log = '/hab/svc/inspec-profile-hab_test_profile/logs/inspec_log.txt'
|
|
33
|
+
expect(file(log).exist?).to be(true)
|
|
34
|
+
end
|
|
35
|
+
it 'should create a JSON file for the last run' do
|
|
36
|
+
log = '/hab/svc/inspec-profile-hab_test_profile/logs/inspec_last_run.json'
|
|
37
|
+
JSON.parse(file(log).content)
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
@@ -1,184 +1,240 @@
|
|
|
1
1
|
require 'mixlib/log'
|
|
2
|
-
require '
|
|
2
|
+
require 'fileutils'
|
|
3
3
|
require 'minitest/autorun'
|
|
4
|
-
require 'mocha/setup'
|
|
5
4
|
require_relative '../../lib/inspec-habitat/profile.rb'
|
|
6
5
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
6
|
+
class InspecPlugins::Habitat::ProfileTest < MiniTest::Unit::TestCase
|
|
7
|
+
def setup
|
|
8
|
+
@tmpdir = Dir.mktmpdir
|
|
9
|
+
|
|
10
|
+
@output_dir = File.join(@tmpdir, 'output')
|
|
11
|
+
FileUtils.mkdir(@output_dir)
|
|
12
|
+
|
|
13
|
+
@fake_hart_file = FileUtils.touch(File.join(@tmpdir, 'fake-hart.hart'))[0]
|
|
14
|
+
|
|
15
|
+
# Path from `__FILE__` needed to support running tests in `inspec/inspec`
|
|
16
|
+
@test_profile_path = File.join(
|
|
17
|
+
File.expand_path(File.dirname(__FILE__)),
|
|
18
|
+
'../',
|
|
19
|
+
'support',
|
|
20
|
+
'example_profile'
|
|
21
|
+
)
|
|
22
|
+
@test_profile = Inspec::Profile.for_target(
|
|
23
|
+
@test_profile_path,
|
|
24
|
+
backend: Inspec::Backend.create(Inspec::Config.mock),
|
|
13
25
|
)
|
|
14
|
-
end
|
|
15
26
|
|
|
16
|
-
|
|
27
|
+
@hab_profile = InspecPlugins::Habitat::Profile.new(
|
|
28
|
+
@test_profile_path,
|
|
29
|
+
{ output_dir: @output_dir },
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
@mock_hab_config = {
|
|
33
|
+
'auth_token' => 'FAKETOKEN',
|
|
34
|
+
'origin' => 'fake_origin',
|
|
35
|
+
}
|
|
17
36
|
|
|
18
|
-
before do
|
|
19
37
|
Inspec::Log.level(:fatal)
|
|
20
38
|
end
|
|
21
39
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
profile = mock
|
|
25
|
-
profile.stubs(:check).returns(summary: { valid: false })
|
|
26
|
-
subject.expects(:profile).returns(profile)
|
|
27
|
-
proc { subject.send(:verify_profile) }.must_raise SystemExit
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
it 'does not exist if the profile is valid' do
|
|
31
|
-
profile = mock
|
|
32
|
-
profile.stubs(:check).returns(summary: { valid: true })
|
|
33
|
-
subject.expects(:profile).returns(profile)
|
|
34
|
-
subject.send(:verify_profile)
|
|
35
|
-
end
|
|
40
|
+
def after_run
|
|
41
|
+
FileUtils.remove_entry_secure(@tmpdir)
|
|
36
42
|
end
|
|
37
43
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
let(:cache_path) { mock }
|
|
44
|
+
def test_create_raises_if_output_dir_does_not_exist
|
|
45
|
+
profile = InspecPlugins::Habitat::Profile.new(
|
|
46
|
+
@test_profile_path,
|
|
47
|
+
{
|
|
48
|
+
output_dir: '/not/a/real/path',
|
|
49
|
+
log_level: 'fatal',
|
|
50
|
+
},
|
|
51
|
+
)
|
|
47
52
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
53
|
+
assert_raises(SystemExit) { profile.create }
|
|
54
|
+
# TODO: Figure out how to capture and validate `Inspec::Log.error`
|
|
55
|
+
end
|
|
51
56
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
57
|
+
def test_create
|
|
58
|
+
file_count = Dir.glob(File.join(@test_profile_path, '**/*')).count
|
|
59
|
+
|
|
60
|
+
@hab_profile.stub :read_habitat_config, @mock_hab_config do
|
|
61
|
+
@hab_profile.stub :verify_habitat_setup, nil do
|
|
62
|
+
@hab_profile.stub :build_hart, @fake_hart_file do
|
|
63
|
+
@hab_profile.create
|
|
64
|
+
end
|
|
59
65
|
end
|
|
60
66
|
end
|
|
61
67
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
cache_path.expects(:exist?).returns(false)
|
|
66
|
-
profile_vendor.expects(:vendor!)
|
|
67
|
-
profile_vendor.expects(:make_readable)
|
|
68
|
-
subject.expects(:create_profile_object)
|
|
68
|
+
# It should not modify target profile
|
|
69
|
+
new_file_count = Dir.glob(File.join(@test_profile_path, '**/*')).count
|
|
70
|
+
assert_equal new_file_count, file_count
|
|
69
71
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
+
# It should create 1 Habitat artifact
|
|
73
|
+
output_files = Dir.glob(File.join(@output_dir, '**/*'))
|
|
74
|
+
assert_equal 1, output_files.count
|
|
75
|
+
assert_equal 'fake-hart.hart', File.basename(output_files.first)
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def test_create_rasies_if_habitat_is_not_installed
|
|
79
|
+
cmd = MiniTest::Mock.new
|
|
80
|
+
cmd.expect(:error?, true)
|
|
81
|
+
cmd.expect(:run_command, nil)
|
|
82
|
+
|
|
83
|
+
Mixlib::ShellOut.stub :new, cmd, 'hab --version' do
|
|
84
|
+
assert_raises(SystemExit) { @hab_profile.create }
|
|
85
|
+
# TODO: Figure out how to capture and validate `Inspec::Log.error`
|
|
72
86
|
end
|
|
73
87
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
lockfile.expects(:exist?).returns(false)
|
|
77
|
-
profile_vendor.expects(:vendor!)
|
|
78
|
-
profile_vendor.expects(:make_readable)
|
|
79
|
-
subject.expects(:create_profile_object)
|
|
88
|
+
cmd.verify
|
|
89
|
+
end
|
|
80
90
|
|
|
81
|
-
|
|
91
|
+
def test_upload
|
|
92
|
+
@hab_profile.stub :read_habitat_config, @mock_hab_config do
|
|
93
|
+
@hab_profile.stub :create, @fake_hart_file do
|
|
94
|
+
@hab_profile.stub :upload_hart, nil do
|
|
95
|
+
@hab_profile.upload
|
|
96
|
+
# TODO: Figure out how to capture and validate `Inspec::Log.error`
|
|
97
|
+
end
|
|
82
98
|
end
|
|
83
99
|
end
|
|
84
100
|
end
|
|
85
101
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
cmd.stubs(:run_command)
|
|
91
|
-
cmd.stubs(:stdout)
|
|
92
|
-
cmd.stubs(:stderr)
|
|
93
|
-
Mixlib::ShellOut.expects(:new).with('hab --version').returns(cmd)
|
|
94
|
-
proc { subject.send(:validate_habitat_installed) }.must_raise SystemExit
|
|
102
|
+
def test_upload_raises_if_no_habitat_auth_token_is_found
|
|
103
|
+
@hab_profile.stub :read_habitat_config, {} do
|
|
104
|
+
assert_raises(SystemExit) { @hab_profile.upload }
|
|
105
|
+
# TODO: Figure out how to capture and validate `Inspec::Log.error`
|
|
95
106
|
end
|
|
96
107
|
end
|
|
97
108
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
subject.send(:validate_habitat_origin)
|
|
109
|
+
def test_create_working_dir
|
|
110
|
+
Dir.stub :mktmpdir, '/tmp/fakedir' do
|
|
111
|
+
assert_equal '/tmp/fakedir', @hab_profile.send(:create_working_dir)
|
|
102
112
|
end
|
|
113
|
+
end
|
|
103
114
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
115
|
+
def test_duplicate_profile
|
|
116
|
+
current_profile = @test_profile
|
|
117
|
+
duplicated_profile = @hab_profile.send(:duplicate_profile,
|
|
118
|
+
@test_profile_path,
|
|
119
|
+
@tmpdir)
|
|
120
|
+
assert duplicated_profile.is_a?(Inspec::Profile)
|
|
121
|
+
assert duplicated_profile.sha256 == current_profile.sha256.to_s
|
|
122
|
+
refute_same duplicated_profile.root_path, current_profile.root_path
|
|
108
123
|
end
|
|
109
124
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
end
|
|
125
|
+
def test_profile_from_path
|
|
126
|
+
profile = @hab_profile.send(:profile_from_path, @test_profile_path)
|
|
127
|
+
assert profile.is_a?(Inspec::Profile)
|
|
128
|
+
end
|
|
115
129
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
130
|
+
def test_copy_profile_to_working_dir
|
|
131
|
+
duplicated_profile = @hab_profile.send(:duplicate_profile,
|
|
132
|
+
@test_profile_path,
|
|
133
|
+
@tmpdir)
|
|
134
|
+
|
|
135
|
+
dst = File.join(@tmpdir, 'working_dir')
|
|
136
|
+
FileUtils.mkdir_p(dst)
|
|
137
|
+
@hab_profile.send(:copy_profile_to_working_dir, duplicated_profile, dst)
|
|
138
|
+
|
|
139
|
+
expected_files = %w{
|
|
140
|
+
README.md
|
|
141
|
+
inspec.yml
|
|
142
|
+
example.rb
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
actual_files = Dir.glob(File.join(dst, '**/*')).map do |path|
|
|
146
|
+
next unless File.file?(path)
|
|
147
|
+
File.basename(path)
|
|
148
|
+
end.compact
|
|
149
|
+
|
|
150
|
+
assert(actual_files.sort == expected_files.sort)
|
|
120
151
|
end
|
|
121
152
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
153
|
+
def test_verify_profile_raises_if_profile_is_not_valid
|
|
154
|
+
bad_profile_path = File.join(@tmpdir, 'bad_profile')
|
|
155
|
+
FileUtils.mkdir_p(File.join(bad_profile_path))
|
|
156
|
+
FileUtils.touch(File.join(bad_profile_path, 'inspec.yml'))
|
|
157
|
+
bad_profile = Inspec::Profile.for_target(
|
|
158
|
+
bad_profile_path,
|
|
159
|
+
backend: Inspec::Backend.create(Inspec::Config.mock),
|
|
160
|
+
)
|
|
161
|
+
assert_raises(SystemExit) { @hab_profile.send(:verify_profile, bad_profile) }
|
|
162
|
+
# TODO: Figure out how to capture and validate `Inspec::Log.error`
|
|
163
|
+
end
|
|
126
164
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
165
|
+
def test_vendor_profile_dependencies_does_not_vendor_if_already_vendored
|
|
166
|
+
mock_lock_file = MiniTest::Mock.new
|
|
167
|
+
mock_lock_file.expect(:exist?, true)
|
|
168
|
+
mock_cache_path = MiniTest::Mock.new
|
|
169
|
+
mock_cache_path.expect(:exist?, true)
|
|
131
170
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
proc { subject.send(:build_hart) }.must_raise SystemExit
|
|
136
|
-
end
|
|
171
|
+
mock = MiniTest::Mock.new
|
|
172
|
+
mock.expect(:lockfile, mock_lock_file)
|
|
173
|
+
mock.expect(:cache_path, mock_cache_path)
|
|
137
174
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
175
|
+
Inspec::ProfileVendor.stub :new, mock do
|
|
176
|
+
new_profile = @hab_profile.send(:vendor_profile_dependencies!,
|
|
177
|
+
@test_profile)
|
|
178
|
+
assert new_profile.is_a?(Inspec::Profile)
|
|
142
179
|
end
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
def test_vendor_profile_dependencies
|
|
183
|
+
mock_lock_file = MiniTest::Mock.new
|
|
184
|
+
mock_lock_file.expect(:exist?, false)
|
|
185
|
+
|
|
186
|
+
mock = MiniTest::Mock.new
|
|
187
|
+
mock.expect(:lockfile, mock_lock_file)
|
|
188
|
+
mock.expect(:vendor!, nil)
|
|
189
|
+
mock.expect(:make_readable, nil)
|
|
143
190
|
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
191
|
+
Inspec::ProfileVendor.stub :new, mock do
|
|
192
|
+
new_profile = @hab_profile.send(:vendor_profile_dependencies!,
|
|
193
|
+
@test_profile)
|
|
194
|
+
assert new_profile.is_a?(Inspec::Profile)
|
|
148
195
|
end
|
|
196
|
+
mock.verify
|
|
149
197
|
end
|
|
150
198
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
'HAB_NONINTERACTIVE' => 'true',
|
|
157
|
-
}
|
|
199
|
+
def test_verify_habitat_setup_raises_if_hab_version_errors
|
|
200
|
+
mock = MiniTest::Mock.new
|
|
201
|
+
mock.expect(:run_command, nil)
|
|
202
|
+
mock.expect(:error?, true)
|
|
203
|
+
mock.expect(:stderr, 'This would be an error message')
|
|
158
204
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
cmd.stubs(:stdout)
|
|
163
|
-
cmd.stubs(:stderr)
|
|
164
|
-
|
|
165
|
-
subject.expects(:habitat_auth_token).returns('my_token')
|
|
166
|
-
Mixlib::ShellOut.expects(:new).with("hab pkg upload my_hart", env: env).returns(cmd)
|
|
167
|
-
proc { subject.send(:upload_hart, 'my_hart') }.must_raise SystemExit
|
|
205
|
+
Mixlib::ShellOut.stub(:new, mock) do
|
|
206
|
+
assert_raises(SystemExit) { @hab_profile.send(:verify_habitat_setup, {}) }
|
|
207
|
+
# TODO: Figure out how to capture and validate `Inspec::Log.error`
|
|
168
208
|
end
|
|
209
|
+
mock.verify
|
|
169
210
|
end
|
|
170
211
|
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
212
|
+
def test_verify_habitat_setup_raises_if_not_habitat_origin
|
|
213
|
+
mock = MiniTest::Mock.new
|
|
214
|
+
mock.expect(:run_command, nil)
|
|
215
|
+
mock.expect(:error?, false)
|
|
216
|
+
|
|
217
|
+
Mixlib::ShellOut.stub(:new, mock) do
|
|
218
|
+
assert_raises(SystemExit) { @hab_profile.send(:verify_habitat_setup, {}) }
|
|
219
|
+
# TODO: Figure out how to capture and validate `Inspec::Log.error`
|
|
175
220
|
end
|
|
221
|
+
mock.verify
|
|
222
|
+
end
|
|
223
|
+
|
|
224
|
+
# TODO: Figure out how to stub system()
|
|
225
|
+
# def test_build_hart
|
|
226
|
+
# end
|
|
227
|
+
|
|
228
|
+
def test_upload_hart_raises_if_hab_pkg_upload_fails
|
|
229
|
+
mock = MiniTest::Mock.new
|
|
230
|
+
mock.expect(:run_command, nil)
|
|
231
|
+
mock.expect(:error?, true)
|
|
232
|
+
mock.expect(:stdout, 'This would contain output from `hab`')
|
|
233
|
+
mock.expect(:stderr, 'This would be an error message')
|
|
176
234
|
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
Tomlrb.expects(:load_file).with(config_file).returns(foo: 1)
|
|
181
|
-
subject.send(:habitat_cli_config).must_equal(foo: 1)
|
|
235
|
+
Mixlib::ShellOut.stub(:new, mock) do
|
|
236
|
+
assert_raises(SystemExit) { @hab_profile.send(:upload_hart, @fake_hart_file, {}) }
|
|
237
|
+
# TODO: Figure out how to capture and validate `Inspec::Log.error`
|
|
182
238
|
end
|
|
183
239
|
end
|
|
184
240
|
end
|