chef 16.7.61-universal-mingw32 → 16.9.20-universal-mingw32
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/Gemfile +3 -5
- data/README.md +2 -2
- data/chef.gemspec +12 -2
- data/distro/ruby_bin_folder/AMD64/Chef.PowerShell.Wrapper.dll +0 -0
- data/distro/ruby_bin_folder/AMD64/Chef.PowerShell.dll +0 -0
- data/distro/ruby_bin_folder/AMD64/shared/Microsoft.NETCore.App/5.0.0/Chef.PowerShell.Wrapper.Core.dll +0 -0
- data/distro/ruby_bin_folder/AMD64/shared/Microsoft.NETCore.App/5.0.0/Chef.Powershell.Core.dll +0 -0
- data/distro/ruby_bin_folder/AMD64/shared/Microsoft.NETCore.App/5.0.0/Chef.Powershell.Core.pdb +0 -0
- data/distro/ruby_bin_folder/x86/Chef.PowerShell.dll +0 -0
- data/distro/ruby_bin_folder/x86/Chef.Powershell.Wrapper.dll +0 -0
- data/distro/ruby_bin_folder/x86/shared/Microsoft.NETCore.App/5.0.0/Chef.PowerShell.Wrapper.Core.dll +0 -0
- data/distro/ruby_bin_folder/x86/shared/Microsoft.NETCore.App/5.0.0/Chef.Powershell.Core.dll +0 -0
- data/distro/ruby_bin_folder/x86/shared/Microsoft.NETCore.App/5.0.0/Chef.Powershell.Core.pdb +0 -0
- data/lib/chef/application/base.rb +1 -1
- data/lib/chef/client.rb +3 -0
- data/lib/chef/compliance/default_attributes.rb +93 -0
- data/lib/chef/compliance/fetcher/automate.rb +69 -0
- data/lib/chef/compliance/fetcher/chef_server.rb +134 -0
- data/lib/chef/compliance/reporter/automate.rb +201 -0
- data/lib/chef/compliance/reporter/chef_server_automate.rb +94 -0
- data/lib/chef/compliance/reporter/compliance_enforcer.rb +20 -0
- data/lib/chef/compliance/reporter/json_file.rb +19 -0
- data/lib/chef/compliance/runner.rb +262 -0
- data/lib/chef/cookbook_manifest.rb +1 -0
- data/lib/chef/encrypted_data_bag_item/assertions.rb +1 -1
- data/lib/chef/exceptions.rb +4 -0
- data/lib/chef/http/ssl_policies.rb +33 -14
- data/lib/chef/knife/bootstrap/train_connector.rb +1 -1
- data/lib/chef/knife/core/formatting_options.rb +49 -0
- data/lib/chef/knife/core/node_presenter.rb +0 -25
- data/lib/chef/knife/core/status_presenter.rb +1 -26
- data/lib/chef/knife/core/ui.rb +4 -1
- data/lib/chef/knife/core/windows_bootstrap_context.rb +1 -1
- data/lib/chef/knife/node_show.rb +2 -1
- data/lib/chef/knife/search.rb +2 -1
- data/lib/chef/knife/ssh.rb +3 -1
- data/lib/chef/knife/status.rb +8 -11
- data/lib/chef/mixin/powershell_exec.rb +3 -1
- data/lib/chef/platform/query_helpers.rb +4 -4
- data/lib/chef/policy_builder/policyfile.rb +1 -1
- data/lib/chef/powershell.rb +2 -0
- data/lib/chef/provider/dsc_resource.rb +12 -24
- data/lib/chef/provider/dsc_script.rb +16 -20
- data/lib/chef/provider/git.rb +5 -5
- data/lib/chef/provider/package.rb +53 -19
- data/lib/chef/provider/package/dnf.rb +39 -12
- data/lib/chef/provider/package/dnf/dnf_helper.py +18 -5
- data/lib/chef/provider/package/dnf/python_helper.rb +6 -6
- data/lib/chef/provider/package/freebsd/pkgng.rb +3 -1
- data/lib/chef/provider/yum_repository.rb +2 -2
- data/lib/chef/resource/chef_client_config.rb +1 -1
- data/lib/chef/resource/chef_gem.rb +2 -2
- data/lib/chef/resource/cron/cron_d.rb +1 -0
- data/lib/chef/resource/dsc_script.rb +8 -1
- data/lib/chef/resource/file.rb +1 -1
- data/lib/chef/resource/gem_package.rb +2 -2
- data/lib/chef/resource/homebrew_cask.rb +3 -3
- data/lib/chef/resource/hostname.rb +3 -3
- data/lib/chef/resource/http_request.rb +1 -1
- data/lib/chef/resource/locale.rb +1 -1
- data/lib/chef/resource/mdadm.rb +2 -2
- data/lib/chef/resource/osx_profile.rb +7 -7
- data/lib/chef/resource/remote_directory.rb +1 -1
- data/lib/chef/resource/ruby.rb +1 -5
- data/lib/chef/resource/ruby_block.rb +1 -1
- data/lib/chef/resource/template.rb +2 -2
- data/lib/chef/resource/user/windows_user.rb +5 -0
- data/lib/chef/resource/windows_certificate.rb +9 -13
- data/lib/chef/resource/yum_repository.rb +5 -0
- data/lib/chef/resource_collection/resource_set.rb +1 -1
- data/lib/chef/util/dsc/configuration_generator.rb +52 -11
- data/lib/chef/util/dsc/lcm_output_parser.rb +3 -4
- data/lib/chef/util/dsc/local_configuration_manager.rb +17 -14
- data/lib/chef/util/dsc/resource_store.rb +5 -11
- data/lib/chef/version.rb +1 -1
- data/lib/chef/win32/api/file.rb +4 -0
- data/spec/data/rubygems.org/latest_specs.4.8.gz +0 -0
- data/spec/data/rubygems.org/nonexistent_gem +0 -0
- data/spec/data/rubygems.org/sexp_processor +0 -0
- data/spec/data/rubygems.org/sexp_processor-4.15.1.gemspec.rz +0 -0
- data/spec/data/ssl/binary/chef-rspec-der.cert +0 -0
- data/spec/data/ssl/binary/chef-rspec-der.key +0 -0
- data/spec/functional/resource/dnf_package_spec.rb +319 -16
- data/spec/functional/resource/dsc_script_spec.rb +3 -6
- data/spec/functional/resource/windows_certificate_spec.rb +204 -384
- data/spec/integration/client/client_spec.rb +2 -1
- data/spec/integration/compliance/compliance_spec.rb +81 -0
- data/spec/integration/recipes/recipe_dsl_spec.rb +1 -0
- data/spec/spec_helper.rb +1 -1
- data/spec/unit/client_spec.rb +1 -0
- data/spec/unit/compliance/fetcher/automate_spec.rb +134 -0
- data/spec/unit/compliance/fetcher/chef_server_spec.rb +93 -0
- data/spec/unit/compliance/reporter/automate_spec.rb +427 -0
- data/spec/unit/compliance/reporter/chef_server_automate_spec.rb +177 -0
- data/spec/unit/compliance/reporter/compliance_enforcer_spec.rb +48 -0
- data/spec/unit/compliance/runner_spec.rb +167 -0
- data/spec/unit/http/ssl_policies_spec.rb +107 -68
- data/spec/unit/knife/bootstrap_spec.rb +5 -17
- data/spec/unit/knife/core/node_editor_spec.rb +1 -1
- data/spec/unit/knife/core/status_presenter_spec.rb +54 -0
- data/spec/unit/mixin/openssl_helper_spec.rb +0 -7
- data/spec/unit/mixin/powershell_exec_spec.rb +1 -1
- data/spec/unit/platform/query_helpers_spec.rb +11 -12
- data/spec/unit/provider/dsc_resource_spec.rb +10 -27
- data/spec/unit/provider/dsc_script_spec.rb +1 -1
- data/spec/unit/provider/mount/windows_spec.rb +1 -0
- data/spec/unit/provider/package/freebsd/pkgng_spec.rb +1 -1
- data/spec/unit/provider/package/rubygems_spec.rb +39 -7
- data/spec/unit/provider/systemd_unit_spec.rb +1 -1
- data/spec/unit/resource/user/windows_user_spec.rb +36 -0
- data/spec/unit/resource/windows_certificate_spec.rb +12 -0
- data/spec/unit/util/dsc/configuration_generator_spec.rb +79 -0
- data/spec/unit/util/dsc/local_configuration_manager_spec.rb +27 -35
- metadata +55 -18
- data/lib/chef/util/powershell/cmdlet.rb +0 -169
- data/lib/chef/util/powershell/cmdlet_result.rb +0 -61
- data/spec/data/trusted_certs_empty/.gitkeep +0 -0
- data/spec/data/trusted_certs_empty/README.md +0 -1
- data/spec/functional/util/powershell/cmdlet_spec.rb +0 -111
- data/spec/scripts/ssl-serve.rb +0 -47
- data/spec/unit/util/powershell/cmdlet_spec.rb +0 -106
@@ -97,7 +97,8 @@ describe "chef-client" do
|
|
97
97
|
before { file ".chef/knife.rb", "xxx.xxx" }
|
98
98
|
|
99
99
|
it "should load .chef/knife.rb when -z is specified" do
|
100
|
-
|
100
|
+
# On Solaris shell_out will invoke /bin/sh which doesn't understand how to correctly update ENV['PWD']
|
101
|
+
result = shell_out("#{chef_client} -z -o 'x::default'", cwd: path_to(""), env: { "PWD" => nil })
|
101
102
|
# FATAL: Configuration error NoMethodError: undefined method `xxx' for nil:NilClass
|
102
103
|
expect(result.stdout).to include("xxx")
|
103
104
|
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
require "support/shared/integration/integration_helper"
|
4
|
+
require "chef/mixin/shell_out"
|
5
|
+
require "chef-utils/dist"
|
6
|
+
|
7
|
+
describe "chef-client with audit mode" do
|
8
|
+
|
9
|
+
include IntegrationSupport
|
10
|
+
include Chef::Mixin::ShellOut
|
11
|
+
|
12
|
+
let(:chef_dir) { File.join(__dir__, "..", "..", "..", "bin") }
|
13
|
+
|
14
|
+
# Invoke `chef-client` as `ruby PATH/TO/chef-client`. This ensures the
|
15
|
+
# following constraints are satisfied:
|
16
|
+
# * Windows: windows can only run batch scripts as bare executables. Rubygems
|
17
|
+
# creates batch wrappers for installed gems, but we don't have batch wrappers
|
18
|
+
# in the source tree.
|
19
|
+
# * Other `chef-client` in PATH: A common case is running the tests on a
|
20
|
+
# machine that has omnibus chef installed. In that case we need to ensure
|
21
|
+
# we're running `chef-client` from the source tree and not the external one.
|
22
|
+
# cf. CHEF-4914
|
23
|
+
let(:chef_client) { "bundle exec #{ChefUtils::Dist::Infra::CLIENT} --minimal-ohai" }
|
24
|
+
|
25
|
+
when_the_repository "has a custom profile" do
|
26
|
+
let(:report_file) { path_to("report_file.json") }
|
27
|
+
|
28
|
+
before do
|
29
|
+
directory "profiles/my-profile" do
|
30
|
+
file "inspec.yml", <<~FILE
|
31
|
+
---
|
32
|
+
name: my-profile
|
33
|
+
FILE
|
34
|
+
|
35
|
+
directory "controls" do
|
36
|
+
file "my_control.rb", <<~FILE
|
37
|
+
control "my control" do
|
38
|
+
describe Dir.home do
|
39
|
+
it { should be_kind_of String }
|
40
|
+
end
|
41
|
+
end
|
42
|
+
FILE
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
file "attributes.json", <<~FILE
|
47
|
+
{
|
48
|
+
"audit": {
|
49
|
+
"json_file": {
|
50
|
+
"location": "#{report_file}"
|
51
|
+
},
|
52
|
+
"profiles": {
|
53
|
+
"my-profile": {
|
54
|
+
"path": "#{path_to("profiles/my-profile")}"
|
55
|
+
}
|
56
|
+
}
|
57
|
+
}
|
58
|
+
}
|
59
|
+
FILE
|
60
|
+
end
|
61
|
+
|
62
|
+
it "should complete with success" do
|
63
|
+
result = shell_out!("#{chef_client} --local-mode --json-attributes #{path_to("attributes.json")}", cwd: chef_dir)
|
64
|
+
result.error!
|
65
|
+
|
66
|
+
inspec_report = JSON.parse(File.read(report_file))
|
67
|
+
expect(inspec_report["profiles"].length).to eq(1)
|
68
|
+
|
69
|
+
profile = inspec_report["profiles"].first
|
70
|
+
expect(profile["name"]).to eq("my-profile")
|
71
|
+
expect(profile["controls"].length).to eq(1)
|
72
|
+
|
73
|
+
control = profile["controls"].first
|
74
|
+
expect(control["id"]).to eq("my control")
|
75
|
+
expect(control["results"].length).to eq(1)
|
76
|
+
|
77
|
+
result = control["results"].first
|
78
|
+
expect(result["status"]).to eq("passed")
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
data/spec/spec_helper.rb
CHANGED
data/spec/unit/client_spec.rb
CHANGED
@@ -129,6 +129,7 @@ shared_context "a client run" do
|
|
129
129
|
expect(client.events).to receive(:register).with(instance_of(Chef::DataCollector::Reporter))
|
130
130
|
expect(client.events).to receive(:register).with(instance_of(Chef::ResourceReporter))
|
131
131
|
expect(client.events).to receive(:register).with(instance_of(Chef::ActionCollection))
|
132
|
+
expect(client.events).to receive(:register).with(instance_of(Chef::Compliance::Runner))
|
132
133
|
end
|
133
134
|
|
134
135
|
def stub_for_node_load
|
@@ -0,0 +1,134 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
require "chef/compliance/fetcher/automate"
|
3
|
+
|
4
|
+
describe Chef::Compliance::Fetcher::Automate do
|
5
|
+
describe ".resolve" do
|
6
|
+
before do
|
7
|
+
Chef::Config[:data_collector] = {
|
8
|
+
server_url: "https://automate.test/data_collector",
|
9
|
+
token: token,
|
10
|
+
}
|
11
|
+
end
|
12
|
+
|
13
|
+
let(:token) { "fake_token" }
|
14
|
+
|
15
|
+
context "when target is a string" do
|
16
|
+
it "should resolve a compliance URL" do
|
17
|
+
res = Chef::Compliance::Fetcher::Automate.resolve("compliance://namespace/profile_name")
|
18
|
+
|
19
|
+
expect(res).to be_kind_of(Chef::Compliance::Fetcher::Automate)
|
20
|
+
expected = "https://automate.test/compliance/profiles/namespace/profile_name/tar"
|
21
|
+
expect(res.target).to eq(expected)
|
22
|
+
end
|
23
|
+
|
24
|
+
it "raises an exception with no data collector token" do
|
25
|
+
Chef::Config[:data_collector].delete(:token)
|
26
|
+
|
27
|
+
expect {
|
28
|
+
Chef::Compliance::Fetcher::Automate.resolve("compliance://namespace/profile_name")
|
29
|
+
}.to raise_error(/No data-collector token set/)
|
30
|
+
end
|
31
|
+
|
32
|
+
it "includes the data collector token" do
|
33
|
+
expect(Chef::Compliance::Fetcher::Automate).to receive(:new).with(
|
34
|
+
"https://automate.test/compliance/profiles/namespace/profile_name/tar",
|
35
|
+
hash_including("token" => token)
|
36
|
+
).and_call_original
|
37
|
+
|
38
|
+
res = Chef::Compliance::Fetcher::Automate.resolve("compliance://namespace/profile_name")
|
39
|
+
|
40
|
+
expect(res).to be_kind_of(Chef::Compliance::Fetcher::Automate)
|
41
|
+
expected = "https://automate.test/compliance/profiles/namespace/profile_name/tar"
|
42
|
+
expect(res.target).to eq(expected)
|
43
|
+
end
|
44
|
+
|
45
|
+
it "returns nil with a non-compliance URL" do
|
46
|
+
res = Chef::Compliance::Fetcher::Automate.resolve("http://github.com/chef-cookbooks/audit")
|
47
|
+
|
48
|
+
expect(res).to eq(nil)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
context "when target is a hash" do
|
53
|
+
it "should resolve a target with a version" do
|
54
|
+
res = Chef::Compliance::Fetcher::Automate.resolve(
|
55
|
+
compliance: "namespace/profile_name",
|
56
|
+
version: "1.2.3"
|
57
|
+
)
|
58
|
+
|
59
|
+
expect(res).to be_kind_of(Chef::Compliance::Fetcher::Automate)
|
60
|
+
expected = "https://automate.test/compliance/profiles/namespace/profile_name/version/1.2.3/tar"
|
61
|
+
expect(res.target).to eq(expected)
|
62
|
+
end
|
63
|
+
|
64
|
+
it "should resolve a target without a version" do
|
65
|
+
res = Chef::Compliance::Fetcher::Automate.resolve(
|
66
|
+
compliance: "namespace/profile_name"
|
67
|
+
)
|
68
|
+
|
69
|
+
expect(res).to be_kind_of(Chef::Compliance::Fetcher::Automate)
|
70
|
+
expected = "https://automate.test/compliance/profiles/namespace/profile_name/tar"
|
71
|
+
expect(res.target).to eq(expected)
|
72
|
+
end
|
73
|
+
|
74
|
+
it "uses url key when present" do
|
75
|
+
res = Chef::Compliance::Fetcher::Automate.resolve(
|
76
|
+
compliance: "namespace/profile_name",
|
77
|
+
version: "1.2.3",
|
78
|
+
url: "https://profile.server.test/profiles/profile_name/1.2.3"
|
79
|
+
)
|
80
|
+
|
81
|
+
expect(res).to be_kind_of(Chef::Compliance::Fetcher::Automate)
|
82
|
+
expected = "https://profile.server.test/profiles/profile_name/1.2.3"
|
83
|
+
expect(res.target).to eq(expected)
|
84
|
+
end
|
85
|
+
|
86
|
+
it "does not include token in the config when url key is present" do
|
87
|
+
expect(Chef::Compliance::Fetcher::Automate).to receive(:new).with(
|
88
|
+
"https://profile.server.test/profiles/profile_name/1.2.3",
|
89
|
+
hash_including("token" => nil)
|
90
|
+
).and_call_original
|
91
|
+
|
92
|
+
res = Chef::Compliance::Fetcher::Automate.resolve(
|
93
|
+
compliance: "namespace/profile_name",
|
94
|
+
version: "1.2.3",
|
95
|
+
url: "https://profile.server.test/profiles/profile_name/1.2.3"
|
96
|
+
)
|
97
|
+
|
98
|
+
expect(res).to be_kind_of(Chef::Compliance::Fetcher::Automate)
|
99
|
+
expected = "https://profile.server.test/profiles/profile_name/1.2.3"
|
100
|
+
expect(res.target).to eq(expected)
|
101
|
+
end
|
102
|
+
|
103
|
+
it "raises an exception with no data collector token" do
|
104
|
+
Chef::Config[:data_collector].delete(:token)
|
105
|
+
|
106
|
+
expect {
|
107
|
+
Chef::Compliance::Fetcher::Automate.resolve(compliance: "namespace/profile_name")
|
108
|
+
}.to raise_error(Inspec::FetcherFailure, /No data-collector token set/)
|
109
|
+
end
|
110
|
+
|
111
|
+
it "includes the data collector token" do
|
112
|
+
expect(Chef::Compliance::Fetcher::Automate).to receive(:new).with(
|
113
|
+
"https://automate.test/compliance/profiles/namespace/profile_name/tar",
|
114
|
+
hash_including("token" => token)
|
115
|
+
).and_call_original
|
116
|
+
|
117
|
+
res = Chef::Compliance::Fetcher::Automate.resolve(compliance: "namespace/profile_name")
|
118
|
+
|
119
|
+
expect(res).to be_kind_of(Chef::Compliance::Fetcher::Automate)
|
120
|
+
expected = "https://automate.test/compliance/profiles/namespace/profile_name/tar"
|
121
|
+
expect(res.target).to eq(expected)
|
122
|
+
end
|
123
|
+
|
124
|
+
it "returns nil with a non-profile Hash" do
|
125
|
+
res = Chef::Compliance::Fetcher::Automate.resolve(
|
126
|
+
profile: "namespace/profile_name",
|
127
|
+
version: "1.2.3"
|
128
|
+
)
|
129
|
+
|
130
|
+
expect(res).to eq(nil)
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
@@ -0,0 +1,93 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
require "chef/compliance/fetcher/chef_server"
|
3
|
+
|
4
|
+
describe Chef::Compliance::Fetcher::ChefServer do
|
5
|
+
let(:node) do
|
6
|
+
Chef::Node.new.tap do |n|
|
7
|
+
n.default["audit"] = {}
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
before :each do
|
12
|
+
allow(Chef).to receive(:node).and_return(node)
|
13
|
+
|
14
|
+
Chef::Config[:chef_server_url] = "http://127.0.0.1:8889/organizations/my_org"
|
15
|
+
end
|
16
|
+
|
17
|
+
describe ".resolve" do
|
18
|
+
context "when target is a string" do
|
19
|
+
it "should resolve a compliance URL" do
|
20
|
+
res = Chef::Compliance::Fetcher::ChefServer.resolve("compliance://namespace/profile_name")
|
21
|
+
|
22
|
+
expect(res).to be_kind_of(Chef::Compliance::Fetcher::ChefServer)
|
23
|
+
expected = "http://127.0.0.1:8889/organizations/my_org/owners/namespace/compliance/profile_name/tar"
|
24
|
+
expect(res.target).to eq(expected)
|
25
|
+
end
|
26
|
+
|
27
|
+
it "should add /compliance URL prefix if needed" do
|
28
|
+
node.default["audit"]["fetcher"] = "chef-server"
|
29
|
+
res = Chef::Compliance::Fetcher::ChefServer.resolve("compliance://namespace/profile_name")
|
30
|
+
|
31
|
+
expect(res).to be_kind_of(Chef::Compliance::Fetcher::ChefServer)
|
32
|
+
expected = "http://127.0.0.1:8889/compliance/organizations/my_org/owners/namespace/compliance/profile_name/tar"
|
33
|
+
expect(res.target).to eq(expected)
|
34
|
+
end
|
35
|
+
|
36
|
+
it "includes user in the URL if present" do
|
37
|
+
res = Chef::Compliance::Fetcher::ChefServer.resolve("compliance://username@namespace/profile_name")
|
38
|
+
|
39
|
+
expect(res).to be_kind_of(Chef::Compliance::Fetcher::ChefServer)
|
40
|
+
expected = "http://127.0.0.1:8889/organizations/my_org/owners/username@namespace/compliance/profile_name/tar"
|
41
|
+
expect(res.target).to eq(expected)
|
42
|
+
end
|
43
|
+
|
44
|
+
it "returns nil with a non-compliance URL" do
|
45
|
+
res = Chef::Compliance::Fetcher::ChefServer.resolve("http://github.com/chef-cookbooks/audit")
|
46
|
+
|
47
|
+
expect(res).to eq(nil)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
context "when target is a hash" do
|
52
|
+
it "should resolve a target with a version" do
|
53
|
+
res = Chef::Compliance::Fetcher::ChefServer.resolve(
|
54
|
+
compliance: "namespace/profile_name",
|
55
|
+
version: "1.2.3"
|
56
|
+
)
|
57
|
+
|
58
|
+
expect(res).to be_kind_of(Chef::Compliance::Fetcher::ChefServer)
|
59
|
+
expected = "http://127.0.0.1:8889/organizations/my_org/owners/namespace/compliance/profile_name/version/1.2.3/tar"
|
60
|
+
expect(res.target).to eq(expected)
|
61
|
+
end
|
62
|
+
|
63
|
+
it "should resolve a target without a version" do
|
64
|
+
res = Chef::Compliance::Fetcher::ChefServer.resolve(
|
65
|
+
compliance: "namespace/profile_name"
|
66
|
+
)
|
67
|
+
|
68
|
+
expect(res).to be_kind_of(Chef::Compliance::Fetcher::ChefServer)
|
69
|
+
expected = "http://127.0.0.1:8889/organizations/my_org/owners/namespace/compliance/profile_name/tar"
|
70
|
+
expect(res.target).to eq(expected)
|
71
|
+
end
|
72
|
+
|
73
|
+
it "includes user in the URL if present" do
|
74
|
+
res = Chef::Compliance::Fetcher::ChefServer.resolve(
|
75
|
+
compliance: "username@namespace/profile_name"
|
76
|
+
)
|
77
|
+
|
78
|
+
expect(res).to be_kind_of(Chef::Compliance::Fetcher::ChefServer)
|
79
|
+
expected = "http://127.0.0.1:8889/organizations/my_org/owners/username@namespace/compliance/profile_name/tar"
|
80
|
+
expect(res.target).to eq(expected)
|
81
|
+
end
|
82
|
+
|
83
|
+
it "returns nil with a non-profile Hash" do
|
84
|
+
res = Chef::Compliance::Fetcher::ChefServer.resolve(
|
85
|
+
profile: "namespace/profile_name",
|
86
|
+
version: "1.2.3"
|
87
|
+
)
|
88
|
+
|
89
|
+
expect(res).to eq(nil)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
@@ -0,0 +1,427 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
require "json" # For .to_json
|
3
|
+
|
4
|
+
describe Chef::Compliance::Reporter::Automate do
|
5
|
+
let(:reporter) { Chef::Compliance::Reporter::Automate.new(opts) }
|
6
|
+
|
7
|
+
let(:opts) do
|
8
|
+
{
|
9
|
+
entity_uuid: "aaaaaaaa-709a-475d-bef5-zzzzzzzzzzzz",
|
10
|
+
run_id: "3f0536f7-3361-4bca-ae53-b45118dceb5d",
|
11
|
+
node_info: {
|
12
|
+
node: "chef-client.solo",
|
13
|
+
environment: "My Prod Env",
|
14
|
+
roles: %w{base_linux apache_linux},
|
15
|
+
recipes: ["some_cookbook::some_recipe", "some_cookbook"],
|
16
|
+
policy_name: "test_policy_name",
|
17
|
+
policy_group: "test_policy_group",
|
18
|
+
chef_tags: ["mylinux", "my.tag", "some=tag"],
|
19
|
+
organization_name: "test_org",
|
20
|
+
source_fqdn: "api.chef.io",
|
21
|
+
ipaddress: "192.168.56.33",
|
22
|
+
fqdn: "lb1.prod.example.com",
|
23
|
+
},
|
24
|
+
run_time_limit: 1.1,
|
25
|
+
control_results_limit: 2,
|
26
|
+
timestamp: Time.parse("2016-07-19T19:19:19+01:00"),
|
27
|
+
}
|
28
|
+
end
|
29
|
+
|
30
|
+
let(:inspec_report) do
|
31
|
+
{
|
32
|
+
"version": "1.2.1",
|
33
|
+
"profiles":
|
34
|
+
[{ "name": "tmp_compliance_profile",
|
35
|
+
"title": "/tmp Compliance Profile",
|
36
|
+
"summary": "An Example Compliance Profile",
|
37
|
+
"sha256": "7bd598e369970002fc6f2d16d5b988027d58b044ac3fa30ae5fc1b8492e215cd",
|
38
|
+
"version": "0.1.1",
|
39
|
+
"maintainer": "Nathen Harvey <nharvey@chef.io>",
|
40
|
+
"license": "Apache 2.0 License",
|
41
|
+
"copyright": "Nathen Harvey <nharvey@chef.io>",
|
42
|
+
"supports": [],
|
43
|
+
"controls":
|
44
|
+
[{ "title": "A /tmp directory must exist",
|
45
|
+
"desc": "A /tmp directory must exist",
|
46
|
+
"impact": 0.3,
|
47
|
+
"refs": [],
|
48
|
+
"tags": {},
|
49
|
+
"code": "control 'tmp-1.0' do\n impact 0.3\n title 'A /tmp directory must exist'\n desc 'A /tmp directory must exist'\n describe file '/tmp' do\n it { should be_directory }\n end\nend\n",
|
50
|
+
"source_location": { "ref": "/Users/vjeffrey/code/delivery/insights/data_generator/chef-client/cache/cookbooks/test-cookbook/recipes/../files/default/compliance_profiles/tmp_compliance_profile/controls/tmp.rb", "line": 3 },
|
51
|
+
"id": "tmp-1.0",
|
52
|
+
"results": [
|
53
|
+
{ "status": "passed", "code_desc": "File /tmp should be directory", "run_time": 0.002312, "start_time": "2016-10-19 11:09:43 -0400" },
|
54
|
+
],
|
55
|
+
},
|
56
|
+
{ "title": "/tmp directory is owned by the root user",
|
57
|
+
"desc": "The /tmp directory must be owned by the root user",
|
58
|
+
"impact": 0.3,
|
59
|
+
"refs": [{ "url": "https://pages.chef.io/rs/255-VFB-268/images/compliance-at-velocity2015.pdf", "ref": "Compliance Whitepaper" }],
|
60
|
+
"tags": { "production": nil, "development": nil, "identifier": "value", "remediation": "https://github.com/chef-cookbooks/audit" },
|
61
|
+
"code": "control 'tmp-1.1' do\n impact 0.3\n title '/tmp directory is owned by the root user'\n desc 'The /tmp directory must be owned by the root user'\n tag 'production','development'\n tag identifier: 'value'\n tag remediation: 'https://github.com/chef-cookbooks/audit'\n ref 'Compliance Whitepaper', url: 'https://pages.chef.io/rs/255-VFB-268/images/compliance-at-velocity2015.pdf'\n describe file '/tmp' do\n it { should be_owned_by 'root' }\n end\nend\n",
|
62
|
+
"source_location": { "ref": "/Users/vjeffrey/code/delivery/insights/data_generator/chef-client/cache/cookbooks/test-cookbook/recipes/../files/default/compliance_profiles/tmp_compliance_profile/controls/tmp.rb", "line": 12 },
|
63
|
+
"id": "tmp-1.1",
|
64
|
+
"results": [
|
65
|
+
{ "status": "passed", "code_desc": 'File /tmp should be owned by "root"', "run_time": 1.228845, "start_time": "2016-10-19 11:09:43 -0400" },
|
66
|
+
{ "status": "skipped", "code_desc": 'File /tmp should be owned by "root"', "run_time": 1.228845, "start_time": "2016-10-19 11:09:43 -0400" },
|
67
|
+
{ "status": "failed", "code_desc": "File /etc/hosts is expected to be directory", "run_time": 1.228845, "start_time": "2016-10-19 11:09:43 -0400", "message": "expected `File /etc/hosts.directory?` to return true, got false" },
|
68
|
+
],
|
69
|
+
},
|
70
|
+
],
|
71
|
+
"groups": [{ "title": "/tmp Compliance Profile", "controls": ["tmp-1.0", "tmp-1.1"], "id": "controls/tmp.rb" }],
|
72
|
+
"attributes": [{ "name": "syslog_pkg", "options": { "default": "rsyslog", "description": "syslog package..." } }] }],
|
73
|
+
"other_checks": [],
|
74
|
+
"statistics": { "duration": 0.032332 },
|
75
|
+
}
|
76
|
+
end
|
77
|
+
|
78
|
+
describe "#send_report" do
|
79
|
+
before :each do
|
80
|
+
WebMock.disable_net_connect!
|
81
|
+
|
82
|
+
Chef::Config[:data_collector] = { token: token, server_url: "https://automate.test/data_collector" }
|
83
|
+
end
|
84
|
+
|
85
|
+
let(:token) { "fake_token" }
|
86
|
+
|
87
|
+
it "sends report successfully to ChefAutomate with missing profiles" do
|
88
|
+
metasearch_stub = stub_request(:post, "https://automate.test/compliance/profiles/metasearch")
|
89
|
+
.with(
|
90
|
+
body: '{"sha256": ["7bd598e369970002fc6f2d16d5b988027d58b044ac3fa30ae5fc1b8492e215cd"]}',
|
91
|
+
headers: {
|
92
|
+
"Accept-Encoding" => "identity",
|
93
|
+
"X-Chef-Version" => Chef::VERSION,
|
94
|
+
"X-Data-Collector-Auth" => "version=1.0",
|
95
|
+
"X-Data-Collector-Token" => token,
|
96
|
+
}
|
97
|
+
).to_return(
|
98
|
+
status: 200,
|
99
|
+
body: '{"missing_sha256": ["7bd598e369970002fc6f2d16d5b988027d58b044ac3fa30ae5fc1b8492e215cd"]}'
|
100
|
+
)
|
101
|
+
|
102
|
+
report_stub = stub_request(:post, "https://automate.test/data_collector")
|
103
|
+
.with(
|
104
|
+
body: {
|
105
|
+
"version": "1.2.1",
|
106
|
+
"profiles": [
|
107
|
+
{
|
108
|
+
"name": "tmp_compliance_profile",
|
109
|
+
"title": "/tmp Compliance Profile",
|
110
|
+
"summary": "An Example Compliance Profile",
|
111
|
+
"sha256": "7bd598e369970002fc6f2d16d5b988027d58b044ac3fa30ae5fc1b8492e215cd",
|
112
|
+
"version": "0.1.1",
|
113
|
+
"maintainer": "Nathen Harvey <nharvey@chef.io>",
|
114
|
+
"license": "Apache 2.0 License",
|
115
|
+
"copyright": "Nathen Harvey <nharvey@chef.io>",
|
116
|
+
"supports": [],
|
117
|
+
"controls": [
|
118
|
+
{
|
119
|
+
"title": "A /tmp directory must exist",
|
120
|
+
"desc": "A /tmp directory must exist",
|
121
|
+
"impact": 0.3,
|
122
|
+
"refs": [],
|
123
|
+
"tags": {},
|
124
|
+
"code": "control 'tmp-1.0' do\n impact 0.3\n title 'A /tmp directory must exist'\n desc 'A /tmp directory must exist'\n describe file '/tmp' do\n it { should be_directory }\n end\nend\n",
|
125
|
+
"source_location": { "ref": "/Users/vjeffrey/code/delivery/insights/data_generator/chef-client/cache/cookbooks/test-cookbook/recipes/../files/default/compliance_profiles/tmp_compliance_profile/controls/tmp.rb", "line": 3 },
|
126
|
+
"id": "tmp-1.0",
|
127
|
+
"results": [
|
128
|
+
{ "status": "passed", "code_desc": "File /tmp should be directory", "run_time": 0.002312, "start_time": "2016-10-19 11:09:43 -0400" },
|
129
|
+
],
|
130
|
+
},
|
131
|
+
{
|
132
|
+
"title": "/tmp directory is owned by the root user",
|
133
|
+
"desc": "The /tmp directory must be owned by the root user",
|
134
|
+
"impact": 0.3,
|
135
|
+
"refs": [
|
136
|
+
{ "url": "https://pages.chef.io/rs/255-VFB-268/images/compliance-at-velocity2015.pdf", "ref": "Compliance Whitepaper" },
|
137
|
+
],
|
138
|
+
"tags": { "production": nil, "development": nil, "identifier": "value", "remediation": "https://github.com/chef-cookbooks/audit" },
|
139
|
+
"code": "control 'tmp-1.1' do\n impact 0.3\n title '/tmp directory is owned by the root user'\n desc 'The /tmp directory must be owned by the root user'\n tag 'production','development'\n tag identifier: 'value'\n tag remediation: 'https://github.com/chef-cookbooks/audit'\n ref 'Compliance Whitepaper', url: 'https://pages.chef.io/rs/255-VFB-268/images/compliance-at-velocity2015.pdf'\n describe file '/tmp' do\n it { should be_owned_by 'root' }\n end\nend\n",
|
140
|
+
"source_location": { "ref": "/Users/vjeffrey/code/delivery/insights/data_generator/chef-client/cache/cookbooks/test-cookbook/recipes/../files/default/compliance_profiles/tmp_compliance_profile/controls/tmp.rb", "line": 12 },
|
141
|
+
"id": "tmp-1.1",
|
142
|
+
"results": [
|
143
|
+
{ "status": "failed", "code_desc": "File /etc/hosts is expected to be directory", "run_time": 1.228845, "start_time": "2016-10-19 11:09:43 -0400", "message": "expected `File /etc/hosts.directory?` to return true, got false" },
|
144
|
+
{ "status": "skipped", "code_desc": 'File /tmp should be owned by "root"', "run_time": 1.228845, "start_time": "2016-10-19 11:09:43 -0400" },
|
145
|
+
],
|
146
|
+
"removed_results_counts": { "failed": 0, "skipped": 0, "passed": 1 },
|
147
|
+
},
|
148
|
+
],
|
149
|
+
"groups": [
|
150
|
+
{ "title": "/tmp Compliance Profile", "controls": ["tmp-1.0", "tmp-1.1"], "id": "controls/tmp.rb" },
|
151
|
+
],
|
152
|
+
"attributes": [
|
153
|
+
{ "name": "syslog_pkg", "options": { "default": "rsyslog", "description": "syslog package..." } },
|
154
|
+
],
|
155
|
+
},
|
156
|
+
],
|
157
|
+
"other_checks": [],
|
158
|
+
"statistics": { "duration": 0.032332 },
|
159
|
+
"type": "inspec_report",
|
160
|
+
"node_name": "chef-client.solo",
|
161
|
+
"end_time": "2016-07-19T18:19:19Z",
|
162
|
+
"node_uuid": "aaaaaaaa-709a-475d-bef5-zzzzzzzzzzzz",
|
163
|
+
"environment": "My Prod Env",
|
164
|
+
"roles": %w{base_linux apache_linux},
|
165
|
+
"recipes": ["some_cookbook::some_recipe", "some_cookbook"],
|
166
|
+
"report_uuid": "3f0536f7-3361-4bca-ae53-b45118dceb5d",
|
167
|
+
"source_fqdn": "api.chef.io",
|
168
|
+
"organization_name": "test_org",
|
169
|
+
"policy_group": "test_policy_group",
|
170
|
+
"policy_name": "test_policy_name",
|
171
|
+
"chef_tags": ["mylinux", "my.tag", "some=tag"],
|
172
|
+
"ipaddress": "192.168.56.33",
|
173
|
+
"fqdn": "lb1.prod.example.com",
|
174
|
+
"run_time_limit": 1.1,
|
175
|
+
},
|
176
|
+
headers: {
|
177
|
+
"Accept-Encoding" => "identity",
|
178
|
+
"X-Chef-Version" => Chef::VERSION,
|
179
|
+
"X-Data-Collector-Auth" => "version=1.0",
|
180
|
+
"X-Data-Collector-Token" => token,
|
181
|
+
}
|
182
|
+
).to_return(status: 200)
|
183
|
+
|
184
|
+
expect(reporter.send_report(inspec_report)).to eq(true)
|
185
|
+
|
186
|
+
expect(metasearch_stub).to have_been_requested
|
187
|
+
expect(report_stub).to have_been_requested
|
188
|
+
end
|
189
|
+
|
190
|
+
it "sends report successfully to ChefAutomate with seen profiles" do
|
191
|
+
metasearch_stub = stub_request(:post, "https://automate.test/compliance/profiles/metasearch")
|
192
|
+
.with(
|
193
|
+
body: '{"sha256": ["7bd598e369970002fc6f2d16d5b988027d58b044ac3fa30ae5fc1b8492e215cd"]}',
|
194
|
+
headers: {
|
195
|
+
"Accept-Encoding" => "identity",
|
196
|
+
"X-Chef-Version" => Chef::VERSION,
|
197
|
+
"X-Data-Collector-Auth" => "version=1.0",
|
198
|
+
"X-Data-Collector-Token" => token,
|
199
|
+
}
|
200
|
+
).to_return(
|
201
|
+
status: 200,
|
202
|
+
body: '{"missing_sha256": []}'
|
203
|
+
)
|
204
|
+
|
205
|
+
report_stub = stub_request(:post, "https://automate.test/data_collector")
|
206
|
+
.with(
|
207
|
+
body: {
|
208
|
+
"version": "1.2.1",
|
209
|
+
"profiles": [
|
210
|
+
{
|
211
|
+
"title": "/tmp Compliance Profile",
|
212
|
+
"sha256": "7bd598e369970002fc6f2d16d5b988027d58b044ac3fa30ae5fc1b8492e215cd",
|
213
|
+
"version": "0.1.1",
|
214
|
+
"controls": [
|
215
|
+
{
|
216
|
+
"id": "tmp-1.0",
|
217
|
+
"results": [
|
218
|
+
{ "status": "passed", "code_desc": "File /tmp should be directory" },
|
219
|
+
],
|
220
|
+
},
|
221
|
+
{
|
222
|
+
"id": "tmp-1.1",
|
223
|
+
"results": [
|
224
|
+
{ "status": "failed", "code_desc": "File /etc/hosts is expected to be directory", "run_time": 1.228845, "start_time": "2016-10-19 11:09:43 -0400", "message": "expected `File /etc/hosts.directory?` to return true, got false" },
|
225
|
+
{ "status": "skipped", "code_desc": 'File /tmp should be owned by "root"', "run_time": 1.228845, "start_time": "2016-10-19 11:09:43 -0400" },
|
226
|
+
],
|
227
|
+
"removed_results_counts": { "failed": 0, "skipped": 0, "passed": 1 },
|
228
|
+
},
|
229
|
+
],
|
230
|
+
"attributes": [
|
231
|
+
{ "name": "syslog_pkg", "options": { "default": "rsyslog", "description": "syslog package..." } },
|
232
|
+
],
|
233
|
+
},
|
234
|
+
],
|
235
|
+
"other_checks": [],
|
236
|
+
"statistics": { "duration": 0.032332 },
|
237
|
+
"type": "inspec_report",
|
238
|
+
"node_name": "chef-client.solo",
|
239
|
+
"end_time": "2016-07-19T18:19:19Z",
|
240
|
+
"node_uuid": "aaaaaaaa-709a-475d-bef5-zzzzzzzzzzzz",
|
241
|
+
"environment": "My Prod Env",
|
242
|
+
"roles": %w{base_linux apache_linux},
|
243
|
+
"recipes": ["some_cookbook::some_recipe", "some_cookbook"],
|
244
|
+
"report_uuid": "3f0536f7-3361-4bca-ae53-b45118dceb5d",
|
245
|
+
"source_fqdn": "api.chef.io",
|
246
|
+
"organization_name": "test_org",
|
247
|
+
"policy_group": "test_policy_group",
|
248
|
+
"policy_name": "test_policy_name",
|
249
|
+
"chef_tags": ["mylinux", "my.tag", "some=tag"],
|
250
|
+
"ipaddress": "192.168.56.33",
|
251
|
+
"fqdn": "lb1.prod.example.com",
|
252
|
+
"run_time_limit": 1.1,
|
253
|
+
},
|
254
|
+
headers: {
|
255
|
+
"Accept-Encoding" => "identity",
|
256
|
+
"X-Chef-Version" => Chef::VERSION,
|
257
|
+
"X-Data-Collector-Auth" => "version=1.0",
|
258
|
+
"X-Data-Collector-Token" => token,
|
259
|
+
}
|
260
|
+
).to_return(status: 200)
|
261
|
+
|
262
|
+
expect(reporter.send_report(inspec_report)).to eq(true)
|
263
|
+
|
264
|
+
expect(metasearch_stub).to have_been_requested
|
265
|
+
expect(report_stub).to have_been_requested
|
266
|
+
end
|
267
|
+
|
268
|
+
it "does not send report when entity_uuid is missing" do
|
269
|
+
opts.delete(:entity_uuid)
|
270
|
+
reporter = Chef::Compliance::Reporter::Automate.new(opts)
|
271
|
+
expect(reporter.send_report(inspec_report)).to eq(false)
|
272
|
+
end
|
273
|
+
end
|
274
|
+
|
275
|
+
describe "#truncate_controls_results" do
|
276
|
+
let(:report) do
|
277
|
+
{
|
278
|
+
"version": "1.2.1",
|
279
|
+
"profiles":
|
280
|
+
[{ "name": "tmp_compliance_profile",
|
281
|
+
"title": "/tmp Compliance Profile",
|
282
|
+
"summary": "An Example Compliance Profile",
|
283
|
+
"sha256": "7bd598e369970002fc6f2d16d5b988027d58b044ac3fa30ae5fc1b8492e215ff",
|
284
|
+
"version": "0.1.1",
|
285
|
+
"maintainer": "Nathen Harvey <nharvey@chef.io>",
|
286
|
+
"license": "Apache 2.0 License",
|
287
|
+
"copyright": "Nathen Harvey <nharvey@chef.io>",
|
288
|
+
"supports": [],
|
289
|
+
"controls":
|
290
|
+
[{ "id": "tmp-2.0",
|
291
|
+
"title": "A bunch of directories must exist",
|
292
|
+
"desc": "A bunch of directories must exist for testing",
|
293
|
+
"impact": 0.3,
|
294
|
+
"refs": [],
|
295
|
+
"tags": {},
|
296
|
+
"code": "control 'tmp-2.0' do\n impact 0.3\n title 'A bunch of directories must exist'\n desc 'A bunch of directories must exist for testing'\n describe file '/tmp' do\n it { should be_directory }\n end\nend\n",
|
297
|
+
"source_location": { "ref": "/Users/vjeffrey/code/delivery/insights/data_generator/chef-client/cache/cookbooks/test-cookbook/recipes/../files/default/compliance_profiles/tmp_compliance_profile/controls/tmp.rb", "line": 3 },
|
298
|
+
"results": [
|
299
|
+
{ "status": "passed", "code_desc": "File /tmp should be directory", "run_time": 0.002312, "start_time": "2016-10-19 11:09:43 -0400" },
|
300
|
+
{ "status": "passed", "code_desc": "File /etc should be directory", "run_time": 0.002314, "start_time": "2016-10-19 11:09:45 -0400" },
|
301
|
+
{ "status": "passed", "code_desc": "File /opt should be directory", "run_time": 0.002315, "start_time": "2016-10-19 11:09:46 -0400" },
|
302
|
+
{ "status": "skipped", "code_desc": "No-op", "run_time": 0.002316, "start_time": "2016-10-19 11:09:44 -0400", "skip_message": "4 testing" },
|
303
|
+
{ "status": "skipped", "code_desc": "No-op", "run_time": 0.002317, "start_time": "2016-10-19 11:09:44 -0400", "skip_message": "4 testing" },
|
304
|
+
{ "status": "skipped", "code_desc": "No-op", "run_time": 0.002318, "start_time": "2016-10-19 11:09:44 -0400", "skip_message": "4 testing" },
|
305
|
+
{ "status": "failed", "code_desc": "File /etc/passwd should be directory", "run_time": 0.002313, "start_time": "2016-10-19 11:09:44 -0400" },
|
306
|
+
{ "status": "failed", "code_desc": "File /etc/passwd should be directory", "run_time": 0.002313, "start_time": "2016-10-19 11:09:44 -0400" },
|
307
|
+
{ "status": "failed", "code_desc": "File /etc/passwd should be directory", "run_time": 0.002313, "start_time": "2016-10-19 11:09:44 -0400" },
|
308
|
+
],
|
309
|
+
},
|
310
|
+
{ "id": "tmp-2.1",
|
311
|
+
"title": "/tmp directory is owned by the root user",
|
312
|
+
"desc": "The /tmp directory must be owned by the root user",
|
313
|
+
"impact": 0.3,
|
314
|
+
"refs": [{ "url": "https://pages.chef.io/rs/255-VFB-268/images/compliance-at-velocity2015.pdf", "ref": "Compliance Whitepaper" }],
|
315
|
+
"tags": { "production": nil, "development": nil, "identifier": "value", "remediation": "https://github.com/chef-cookbooks/audit" },
|
316
|
+
"code": "control 'tmp-2.1' do\n impact 0.3\n title '/tmp directory is owned by the root user'\n desc 'The /tmp directory must be owned by the root user'\n tag 'production','development'\n tag identifier: 'value'\n tag remediation: 'https://github.com/chef-cookbooks/audit'\n ref 'Compliance Whitepaper', url: 'https://pages.chef.io/rs/255-VFB-268/images/compliance-at-velocity2015.pdf'\n describe file '/tmp' do\n it { should be_owned_by 'root' }\n end\nend\n",
|
317
|
+
"source_location": { "ref": "/Users/vjeffrey/code/delivery/insights/data_generator/chef-client/cache/cookbooks/test-cookbook/recipes/../files/default/compliance_profiles/tmp_compliance_profile/controls/tmp.rb", "line": 12 },
|
318
|
+
"results": [
|
319
|
+
{ "status": "passed", "code_desc": 'File /tmp should be owned by "root"', "run_time": 1.228845, "start_time": "2016-10-19 11:09:43 -0400" },
|
320
|
+
{ "status": "passed", "code_desc": 'File /etc should be owned by "root"', "run_time": 1.238845, "start_time": "2016-10-19 11:09:43 -0400" },
|
321
|
+
],
|
322
|
+
},
|
323
|
+
],
|
324
|
+
"groups": [{ "title": "/tmp Compliance Profile", "controls": ["tmp-1.0", "tmp-1.1"], "id": "controls/tmp.rb" }],
|
325
|
+
"attributes": [{ "name": "syslog_pkg", "options": { "default": "rsyslog", "description": "syslog package..." } }] }],
|
326
|
+
"other_checks": [],
|
327
|
+
"statistics": { "duration": 0.032332 },
|
328
|
+
}
|
329
|
+
end
|
330
|
+
|
331
|
+
it "truncates controls results 1" do
|
332
|
+
truncated_report = reporter.truncate_controls_results(report, 5)
|
333
|
+
expect(truncated_report[:profiles][0][:controls][0][:results].length).to eq(5)
|
334
|
+
statuses = truncated_report[:profiles][0][:controls][0][:results].map { |r| r[:status] }
|
335
|
+
expect(statuses).to eq(%w{failed failed failed skipped skipped})
|
336
|
+
expect(truncated_report[:profiles][0][:controls][0][:removed_results_counts]).to eq(failed: 0, skipped: 1, passed: 3)
|
337
|
+
end
|
338
|
+
|
339
|
+
it "truncates controls results 2" do
|
340
|
+
truncated_report = reporter.truncate_controls_results(report, 5)
|
341
|
+
expect(truncated_report[:profiles][0][:controls][1][:results].length).to eq(2)
|
342
|
+
statuses = truncated_report[:profiles][0][:controls][1][:results].map { |r| r[:status] }
|
343
|
+
expect(statuses).to eq(%w{passed passed})
|
344
|
+
expect(truncated_report[:profiles][0][:controls][1][:removed_results_counts]).to eq(nil)
|
345
|
+
end
|
346
|
+
|
347
|
+
it "truncates controls results 3" do
|
348
|
+
truncated_report = reporter.truncate_controls_results(report, 0)
|
349
|
+
expect(truncated_report[:profiles][0][:controls][0][:results].length).to eq(9)
|
350
|
+
end
|
351
|
+
|
352
|
+
it "truncates controls results 4" do
|
353
|
+
truncated_report = reporter.truncate_controls_results(report, 1)
|
354
|
+
expect(truncated_report[:profiles][0][:controls][0][:results].length).to eq(1)
|
355
|
+
end
|
356
|
+
end
|
357
|
+
|
358
|
+
describe "#strip_profiles_meta" do
|
359
|
+
it "removes the metadata from seen profiles" do
|
360
|
+
expected = {
|
361
|
+
other_checks: [],
|
362
|
+
profiles: [
|
363
|
+
{
|
364
|
+
attributes: [
|
365
|
+
{
|
366
|
+
name: "syslog_pkg",
|
367
|
+
options: {
|
368
|
+
default: "rsyslog",
|
369
|
+
description: "syslog package...",
|
370
|
+
},
|
371
|
+
},
|
372
|
+
],
|
373
|
+
controls: [
|
374
|
+
{
|
375
|
+
id: "tmp-1.0",
|
376
|
+
results: [
|
377
|
+
{
|
378
|
+
code_desc: "File /tmp should be directory",
|
379
|
+
status: "passed",
|
380
|
+
},
|
381
|
+
],
|
382
|
+
},
|
383
|
+
{
|
384
|
+
id: "tmp-1.1",
|
385
|
+
results: [
|
386
|
+
{
|
387
|
+
code_desc: 'File /tmp should be owned by "root"',
|
388
|
+
run_time: 1.228845,
|
389
|
+
start_time: "2016-10-19 11:09:43 -0400",
|
390
|
+
status: "passed",
|
391
|
+
},
|
392
|
+
{
|
393
|
+
code_desc: 'File /tmp should be owned by "root"',
|
394
|
+
run_time: 1.228845,
|
395
|
+
start_time: "2016-10-19 11:09:43 -0400",
|
396
|
+
status: "skipped",
|
397
|
+
},
|
398
|
+
{
|
399
|
+
code_desc: "File /etc/hosts is expected to be directory",
|
400
|
+
message: "expected `File /etc/hosts.directory?` to return true, got false",
|
401
|
+
run_time: 1.228845,
|
402
|
+
start_time: "2016-10-19 11:09:43 -0400",
|
403
|
+
status: "failed",
|
404
|
+
},
|
405
|
+
],
|
406
|
+
},
|
407
|
+
],
|
408
|
+
sha256: "7bd598e369970002fc6f2d16d5b988027d58b044ac3fa30ae5fc1b8492e215cd",
|
409
|
+
title: "/tmp Compliance Profile",
|
410
|
+
version: "0.1.1",
|
411
|
+
},
|
412
|
+
],
|
413
|
+
run_time_limit: 1.1,
|
414
|
+
statistics: {
|
415
|
+
duration: 0.032332,
|
416
|
+
},
|
417
|
+
version: "1.2.1",
|
418
|
+
}
|
419
|
+
expect(reporter.strip_profiles_meta(inspec_report, [], 1.1)).to eq(expected)
|
420
|
+
end
|
421
|
+
|
422
|
+
it "does not remove the metadata from missing profiles" do
|
423
|
+
expected = inspec_report.merge(run_time_limit: 1.1)
|
424
|
+
expect(reporter.strip_profiles_meta(inspec_report, ["7bd598e369970002fc6f2d16d5b988027d58b044ac3fa30ae5fc1b8492e215cd"], 1.1)).to eq(expected)
|
425
|
+
end
|
426
|
+
end
|
427
|
+
end
|