inspec-core 5.18.14 → 5.22.3
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 +19 -17
- data/inspec-core.gemspec +22 -22
- data/lib/inspec/base_cli.rb +19 -17
- data/lib/inspec/cli.rb +27 -25
- data/lib/inspec/dependencies/dependency_set.rb +2 -2
- data/lib/inspec/dsl.rb +9 -5
- data/lib/inspec/enhanced_outcomes.rb +19 -0
- data/lib/inspec/env_printer.rb +1 -1
- data/lib/inspec/exceptions.rb +2 -0
- data/lib/inspec/formatters/base.rb +69 -16
- data/lib/inspec/plugin/v2/loader.rb +19 -8
- data/lib/inspec/plugin/v2/plugin_types/reporter.rb +1 -0
- data/lib/inspec/plugin/v2/plugin_types/streaming_reporter.rb +54 -0
- data/lib/inspec/profile.rb +9 -8
- data/lib/inspec/reporters/base.rb +1 -0
- data/lib/inspec/reporters/cli.rb +94 -3
- data/lib/inspec/reporters/json.rb +3 -1
- data/lib/inspec/reporters/yaml.rb +3 -1
- data/lib/inspec/reporters.rb +2 -1
- data/lib/inspec/resources/file.rb +1 -1
- data/lib/inspec/resources/http.rb +5 -5
- data/lib/inspec/resources/lxc.rb +65 -9
- data/lib/inspec/resources/mongodb_session.rb +5 -0
- data/lib/inspec/resources/nftables.rb +251 -0
- data/lib/inspec/resources/oracledb_session.rb +13 -4
- data/lib/inspec/resources/podman.rb +353 -0
- data/lib/inspec/resources/podman_container.rb +84 -0
- data/lib/inspec/resources/podman_image.rb +108 -0
- data/lib/inspec/resources/podman_network.rb +81 -0
- data/lib/inspec/resources/podman_pod.rb +101 -0
- data/lib/inspec/resources/podman_volume.rb +87 -0
- data/lib/inspec/resources/postgres_session.rb +2 -1
- data/lib/inspec/resources/service.rb +1 -1
- data/lib/inspec/resources.rb +1 -0
- data/lib/inspec/rule.rb +54 -17
- data/lib/inspec/run_data/control.rb +6 -0
- data/lib/inspec/run_data/statistics.rb +8 -2
- data/lib/inspec/runner.rb +18 -8
- data/lib/inspec/runner_rspec.rb +3 -2
- data/lib/inspec/schema/exec_json.rb +78 -2
- data/lib/inspec/schema/output_schema.rb +4 -1
- data/lib/inspec/schema/profile_json.rb +46 -0
- data/lib/inspec/schema.rb +91 -0
- data/lib/inspec/utils/convert.rb +8 -0
- data/lib/inspec/utils/podman.rb +24 -0
- data/lib/inspec/utils/simpleconfig.rb +10 -2
- data/lib/inspec/utils/waivers/csv_file_reader.rb +34 -0
- data/lib/inspec/utils/waivers/excel_file_reader.rb +39 -0
- data/lib/inspec/utils/waivers/json_file_reader.rb +15 -0
- data/lib/inspec/version.rb +1 -1
- data/lib/inspec/waiver_file_reader.rb +61 -0
- data/lib/matchers/matchers.rb +15 -2
- data/lib/plugins/inspec-init/templates/profiles/alicloud/README.md +27 -0
- data/lib/plugins/inspec-init/templates/profiles/alicloud/controls/example.rb +10 -0
- data/lib/plugins/inspec-init/templates/profiles/alicloud/inputs.yml +1 -0
- data/lib/plugins/inspec-init/templates/profiles/alicloud/inspec.yml +14 -0
- data/lib/plugins/inspec-reporter-html2/README.md +1 -1
- data/lib/plugins/inspec-reporter-html2/templates/body.html.erb +7 -1
- data/lib/plugins/inspec-reporter-html2/templates/control.html.erb +10 -6
- data/lib/plugins/inspec-reporter-html2/templates/default.css +12 -0
- data/lib/plugins/inspec-reporter-html2/templates/selector.html.erb +7 -1
- data/lib/plugins/inspec-sign/lib/inspec-sign/base.rb +5 -2
- data/lib/plugins/inspec-streaming-reporter-progress-bar/lib/inspec-streaming-reporter-progress-bar/streaming_reporter.rb +39 -13
- metadata +26 -9
@@ -0,0 +1,84 @@
|
|
1
|
+
require "inspec/resources/podman"
|
2
|
+
require_relative "docker_object"
|
3
|
+
|
4
|
+
# Change module if required
|
5
|
+
module Inspec::Resources
|
6
|
+
class PodmanContainer < Inspec.resource(1)
|
7
|
+
include Inspec::Resources::DockerObject
|
8
|
+
name "podman_container"
|
9
|
+
supports platform: "unix"
|
10
|
+
|
11
|
+
desc "Inspec core resource to retrieve information about podman container"
|
12
|
+
|
13
|
+
example <<~EXAMPLE
|
14
|
+
describe podman_container("sweet_mendeleev") do
|
15
|
+
it { should exist }
|
16
|
+
it { should be_running }
|
17
|
+
its("id") { should eq "591270d8d80d26671fd6ed622f367fbe19004d16e3b519c292313feb5f22e7f7" }
|
18
|
+
its("image") { should eq "docker.io/library/nginx:latest" }
|
19
|
+
its("labels") { should include "maintainer"=>"NGINX Docker Maintainers <docker-maint@nginx.com>" }
|
20
|
+
its("ports") { should eq nil }
|
21
|
+
end
|
22
|
+
|
23
|
+
describe podman_container(id: "591270d8d80d2667") do
|
24
|
+
it { should exist }
|
25
|
+
it { should be_running }
|
26
|
+
end
|
27
|
+
EXAMPLE
|
28
|
+
|
29
|
+
def initialize(opts = {})
|
30
|
+
skip_resource "The `podman_container` resource is not yet available on your OS." unless inspec.os.unix?
|
31
|
+
|
32
|
+
# if a string is provided, we expect it is the name
|
33
|
+
if opts.is_a?(String)
|
34
|
+
@opts = { name: opts }
|
35
|
+
else
|
36
|
+
@opts = opts
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def running?
|
41
|
+
status.downcase.start_with?("up") if object_info.entries.length == 1
|
42
|
+
end
|
43
|
+
|
44
|
+
def status
|
45
|
+
object_info.status[0] if object_info.entries.length == 1
|
46
|
+
end
|
47
|
+
|
48
|
+
def labels
|
49
|
+
object_info.labels
|
50
|
+
end
|
51
|
+
|
52
|
+
def ports
|
53
|
+
object_info.ports[0] if object_info.entries.length == 1
|
54
|
+
end
|
55
|
+
|
56
|
+
def command
|
57
|
+
return unless object_info.entries.length == 1
|
58
|
+
|
59
|
+
object_info.commands[0]
|
60
|
+
end
|
61
|
+
|
62
|
+
def image
|
63
|
+
object_info.images[0] if object_info.entries.length == 1
|
64
|
+
end
|
65
|
+
|
66
|
+
def resource_id
|
67
|
+
object_info.ids[0] || @opts[:id] || @opts[:name] || ""
|
68
|
+
end
|
69
|
+
|
70
|
+
def to_s
|
71
|
+
name = @opts[:name] || @opts[:id]
|
72
|
+
"Podman Container #{name}"
|
73
|
+
end
|
74
|
+
|
75
|
+
private
|
76
|
+
|
77
|
+
def object_info
|
78
|
+
return @info if defined?(@info)
|
79
|
+
|
80
|
+
opts = @opts
|
81
|
+
@info = inspec.podman.containers.where { names == opts[:name] || (!id.nil? && !opts[:id].nil? && (id == opts[:id] || id.start_with?(opts[:id]))) }
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
@@ -0,0 +1,108 @@
|
|
1
|
+
require "inspec/resources/command"
|
2
|
+
require_relative "docker_object"
|
3
|
+
require "inspec/utils/podman"
|
4
|
+
|
5
|
+
module Inspec::Resources
|
6
|
+
class PodmanImage < Inspec.resource(1)
|
7
|
+
include Inspec::Resources::DockerObject
|
8
|
+
include Inspec::Utils::Podman
|
9
|
+
|
10
|
+
name "podman_image"
|
11
|
+
supports platform: "unix"
|
12
|
+
|
13
|
+
desc "InSpec core resource to retrieve information about podman image"
|
14
|
+
|
15
|
+
example <<~EXAMPLE
|
16
|
+
describe podman_image("docker.io/library/busybox") do
|
17
|
+
it { should exist }
|
18
|
+
its("repo_tags") { should include "docker.io/library/busybox:latest" }
|
19
|
+
its("size") { should eq 1636053 }
|
20
|
+
its("resource_id") { should eq "docker.io/library/busybox:latest" }
|
21
|
+
end
|
22
|
+
|
23
|
+
describe podman_image("docker.io/library/busybox:latest") do
|
24
|
+
it { should exist }
|
25
|
+
end
|
26
|
+
|
27
|
+
describe podman_image(repo: "docker.io/library/busybox", tag: "latest") do
|
28
|
+
it { should exist }
|
29
|
+
end
|
30
|
+
|
31
|
+
describe podman_image(id: "3c19bafed223") do
|
32
|
+
it { should exist }
|
33
|
+
end
|
34
|
+
EXAMPLE
|
35
|
+
|
36
|
+
attr_reader :opts, :image_info
|
37
|
+
|
38
|
+
def initialize(opts)
|
39
|
+
skip_resource "The `podman_image` resource is not yet available on your OS." unless inspec.os.unix?
|
40
|
+
opts = { image: opts } if opts.is_a?(String)
|
41
|
+
@opts = sanitize_options(opts)
|
42
|
+
raise Inspec::Exceptions::ResourceFailed, "Podman is not running. Please make sure it is installed and running." unless podman_running?
|
43
|
+
|
44
|
+
@image_info = get_image_info
|
45
|
+
end
|
46
|
+
|
47
|
+
LABELS = {
|
48
|
+
"id" => "ID",
|
49
|
+
"repo_tags" => "RepoTags",
|
50
|
+
"size" => "Size",
|
51
|
+
"digest" => "Digest",
|
52
|
+
"created_at" => "Created",
|
53
|
+
"version" => "Version",
|
54
|
+
"names_history" => "NamesHistory",
|
55
|
+
"repo_digests" => "RepoDigests",
|
56
|
+
"architecture" => "Architecture",
|
57
|
+
"os" => "Os",
|
58
|
+
"virtual_size" => "VirtualSize",
|
59
|
+
}.freeze
|
60
|
+
|
61
|
+
## This creates all the required properties methods dynamically.
|
62
|
+
LABELS.each do |k, v|
|
63
|
+
define_method(k) do
|
64
|
+
image_info[k.to_s]
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def exist?
|
69
|
+
! image_info.empty?
|
70
|
+
end
|
71
|
+
|
72
|
+
def resource_id
|
73
|
+
opts[:id] || opts[:image] || ""
|
74
|
+
end
|
75
|
+
|
76
|
+
def to_s
|
77
|
+
"podman_image #{resource_id}"
|
78
|
+
end
|
79
|
+
|
80
|
+
private
|
81
|
+
|
82
|
+
def sanitize_options(opts)
|
83
|
+
opts.merge!(parse_components_from_image(opts[:image]))
|
84
|
+
|
85
|
+
# assume a "latest" tag if we don't have one
|
86
|
+
opts[:tag] ||= "latest"
|
87
|
+
|
88
|
+
# Assemble/reassemble the image from the repo and tag
|
89
|
+
opts[:image] = "#{opts[:repo]}:#{opts[:tag]}" unless opts[:repo].nil?
|
90
|
+
|
91
|
+
opts
|
92
|
+
end
|
93
|
+
|
94
|
+
def get_image_info
|
95
|
+
current_image = opts[:id] || opts[:image] || opts[:repo] + ":" + opts[:tag]
|
96
|
+
json_key_label = generate_go_template(LABELS)
|
97
|
+
podman_inspect_cmd = inspec.command("podman image inspect #{current_image} --format '{#{json_key_label}}'")
|
98
|
+
|
99
|
+
if podman_inspect_cmd.exit_status == 0
|
100
|
+
parse_command_output(podman_inspect_cmd.stdout)
|
101
|
+
elsif podman_inspect_cmd.stderr =~ /failed to find image/
|
102
|
+
{}
|
103
|
+
else
|
104
|
+
raise Inspec::Exceptions::ResourceFailed, "Unable to retrieve podman image information for #{current_image}.\nError message: #{podman_inspect_cmd.stderr}"
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
require "inspec/resources/command"
|
2
|
+
require "inspec/utils/podman"
|
3
|
+
module Inspec::Resources
|
4
|
+
class PodmanNetwork < Inspec.resource(1)
|
5
|
+
include Inspec::Utils::Podman
|
6
|
+
|
7
|
+
name "podman_network"
|
8
|
+
|
9
|
+
supports platform: "unix"
|
10
|
+
|
11
|
+
desc "InSpec core resource to retrive information about the given Podman network"
|
12
|
+
|
13
|
+
example <<~EXAMPLE
|
14
|
+
describe podman_network("podman") do
|
15
|
+
it { should exist }
|
16
|
+
end
|
17
|
+
describe podman_network("3a7c94d937d5f3a0f1a9b1610589945aedfbe56207fd5d32fc8154aa1a8b007f") do
|
18
|
+
its("driver") { should eq bridge }
|
19
|
+
end
|
20
|
+
EXAMPLE
|
21
|
+
|
22
|
+
LABELS = {
|
23
|
+
id: "ID",
|
24
|
+
name: "Name",
|
25
|
+
driver: "Driver",
|
26
|
+
labels: "Labels",
|
27
|
+
options: "Options",
|
28
|
+
ipam_options: "IPAMOptions",
|
29
|
+
internal: "Internal",
|
30
|
+
created: "Created",
|
31
|
+
ipv6_enabled: "IPv6Enabled",
|
32
|
+
dns_enabled: "DNSEnabled",
|
33
|
+
network_interface: "NetworkInterface",
|
34
|
+
subnets: "Subnets",
|
35
|
+
}.freeze
|
36
|
+
|
37
|
+
attr_reader :param, :network_info
|
38
|
+
def initialize(param)
|
39
|
+
skip_resource "The `podman_network` resource is not yet available on your OS." unless inspec.os.unix?
|
40
|
+
|
41
|
+
@param = param
|
42
|
+
raise Inspec::Exceptions::ResourceFailed, "Podman is not running. Please make sure it is installed and running." unless podman_running?
|
43
|
+
|
44
|
+
@network_info = get_network_info
|
45
|
+
end
|
46
|
+
|
47
|
+
## This creates all the required properties methods dynamically.
|
48
|
+
LABELS.each do |k, v|
|
49
|
+
define_method(k) do
|
50
|
+
network_info[k.to_s]
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def exist?
|
55
|
+
!network_info.empty?
|
56
|
+
end
|
57
|
+
|
58
|
+
def resource_id
|
59
|
+
id || param || ""
|
60
|
+
end
|
61
|
+
|
62
|
+
def to_s
|
63
|
+
"podman_network #{resource_id}"
|
64
|
+
end
|
65
|
+
|
66
|
+
private
|
67
|
+
|
68
|
+
def get_network_info
|
69
|
+
go_template_format = generate_go_template(LABELS)
|
70
|
+
result = inspec.command("podman network inspect #{param} --format '{#{go_template_format}}'")
|
71
|
+
|
72
|
+
if result.exit_status == 0
|
73
|
+
parse_command_output(result.stdout)
|
74
|
+
elsif result.stderr =~ /network not found/
|
75
|
+
{}
|
76
|
+
else
|
77
|
+
raise Inspec::Exceptions::ResourceFailed, "Unable to retrieve podman network information for #{param}.\nError message: #{result.stderr}"
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
@@ -0,0 +1,101 @@
|
|
1
|
+
require "inspec/resources/command"
|
2
|
+
require "inspec/utils/podman"
|
3
|
+
|
4
|
+
module Inspec::Resources
|
5
|
+
class PodmanPod < Inspec.resource(1)
|
6
|
+
include Inspec::Utils::Podman
|
7
|
+
|
8
|
+
name "podman_pod"
|
9
|
+
supports platform: "unix"
|
10
|
+
|
11
|
+
desc "InSpec core resource to retrieve information about podman pod"
|
12
|
+
|
13
|
+
example <<~EXAMPLE
|
14
|
+
describe podman_pod("nginx-frontend") do
|
15
|
+
it { should exist }
|
16
|
+
its("id") { should eq "fcfe4d471cfface0d1b39bce23af7d31ab8736cd68c0360ade0b4afe364f79d4" }
|
17
|
+
its("name") { should eq "nginx-frontend" }
|
18
|
+
its("created_at") { should eq "2022-07-14T15:47:47.978078124+05:30" }
|
19
|
+
its("create_command") { should include "new:nginx-frontend" }
|
20
|
+
its("state") { should eq "Running" }
|
21
|
+
its("hostname") { should eq "" }
|
22
|
+
its("create_cgroup") { should eq true }
|
23
|
+
its("cgroup_parent") { should eq "user.slice" }
|
24
|
+
its("cgroup_path") { should eq "user.slice/user-libpod_pod_fcfe4d471cfface0d1b39bce23af7d31ab8736cd68c0360ade0b4afe364f79d4.slice" }
|
25
|
+
its("create_infra") { should eq true }
|
26
|
+
its("infra_container_id") { should eq "727538044b32a165934729dc2d47d9d5e981b6496aebfad7de470f7e76ea4251" }
|
27
|
+
its("infra_config") { should include "DNSOption" }
|
28
|
+
its("shared_namespaces") { should include "ipc" }
|
29
|
+
its("num_containers") { should eq 2 }
|
30
|
+
its("containers") { should_not be nil }
|
31
|
+
end
|
32
|
+
|
33
|
+
describe podman_pod("non-existing-pod") do
|
34
|
+
it { should_not exist }
|
35
|
+
end
|
36
|
+
EXAMPLE
|
37
|
+
|
38
|
+
attr_reader :pod_info, :pod_id
|
39
|
+
|
40
|
+
def initialize(pod_id)
|
41
|
+
skip_resource "The `podman_pod` resource is not yet available on your OS." unless inspec.os.unix?
|
42
|
+
raise Inspec::Exceptions::ResourceFailed, "Podman is not running. Please make sure it is installed and running." unless podman_running?
|
43
|
+
|
44
|
+
@pod_id = pod_id
|
45
|
+
@pod_info = get_pod_info
|
46
|
+
end
|
47
|
+
|
48
|
+
LABELS = {
|
49
|
+
"id" => "ID",
|
50
|
+
"name" => "Name",
|
51
|
+
"created_at" => "Created",
|
52
|
+
"create_command" => "CreateCommand",
|
53
|
+
"state" => "State",
|
54
|
+
"hostname" => "Hostname",
|
55
|
+
"create_cgroup" => "CreateCgroup",
|
56
|
+
"cgroup_parent" => "CgroupParent",
|
57
|
+
"cgroup_path" => "CgroupPath",
|
58
|
+
"create_infra" => "CreateInfra",
|
59
|
+
"infra_container_id" => "InfraContainerID",
|
60
|
+
"infra_config" => "InfraConfig",
|
61
|
+
"shared_namespaces" => "SharedNamespaces",
|
62
|
+
"num_containers" => "NumContainers",
|
63
|
+
"containers" => "Containers",
|
64
|
+
}.freeze
|
65
|
+
|
66
|
+
# This creates all the required properties methods dynamically.
|
67
|
+
LABELS.each do |k, _|
|
68
|
+
define_method(k) do
|
69
|
+
pod_info[k.to_s]
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def exist?
|
74
|
+
!pod_info.empty?
|
75
|
+
end
|
76
|
+
|
77
|
+
def resource_id
|
78
|
+
pod_id
|
79
|
+
end
|
80
|
+
|
81
|
+
def to_s
|
82
|
+
"Podman Pod #{resource_id}"
|
83
|
+
end
|
84
|
+
|
85
|
+
private
|
86
|
+
|
87
|
+
def get_pod_info
|
88
|
+
json_key_label = generate_go_template(LABELS)
|
89
|
+
|
90
|
+
inspect_pod_cmd = inspec.command("podman pod inspect #{pod_id} --format '{#{json_key_label}}'")
|
91
|
+
|
92
|
+
if inspect_pod_cmd.exit_status == 0
|
93
|
+
parse_command_output(inspect_pod_cmd.stdout)
|
94
|
+
elsif inspect_pod_cmd.stderr =~ /no pod with name or ID/
|
95
|
+
{}
|
96
|
+
else
|
97
|
+
raise Inspec::Exceptions::ResourceFailed, "Unable to retrieve podman pod information for #{pod_id}.\nError message: #{inspect_pod_cmd.stderr}"
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
require "inspec/resources/command"
|
2
|
+
require "inspec/utils/podman"
|
3
|
+
|
4
|
+
module Inspec::Resources
|
5
|
+
class PodmanVolume < Inspec.resource(1)
|
6
|
+
include Inspec::Utils::Podman
|
7
|
+
|
8
|
+
name "podman_volume"
|
9
|
+
supports platform: "unix"
|
10
|
+
|
11
|
+
desc "InSpec core resource to retrieve information about podman volume"
|
12
|
+
|
13
|
+
example <<~EXAMPLE
|
14
|
+
describe podman_volume("my_volume") do
|
15
|
+
it { should exist }
|
16
|
+
its("name") { should eq "my_volume" }
|
17
|
+
its("driver") { should eq "local" }
|
18
|
+
its("mountpoint") { should eq "/var/home/core/.local/share/containers/storage/volumes/my_volume/_data" }
|
19
|
+
its("created_at") { should eq "2022-07-14T13:21:19.965421792+05:30" }
|
20
|
+
its("labels") { should eq({}) }
|
21
|
+
its("scope") { should eq "local" }
|
22
|
+
its("options") { should eq({}) }
|
23
|
+
its("mount_count") { should eq 0 }
|
24
|
+
its("needs_copy_up") { should eq true }
|
25
|
+
its("needs_chown") { should eq true }
|
26
|
+
end
|
27
|
+
EXAMPLE
|
28
|
+
|
29
|
+
attr_reader :volume_info, :volume_name
|
30
|
+
|
31
|
+
def initialize(volume_name)
|
32
|
+
skip_resource "The `podman_volume` resource is not yet available on your OS." unless inspec.os.unix?
|
33
|
+
raise Inspec::Exceptions::ResourceFailed, "Podman is not running. Please make sure it is installed and running." unless podman_running?
|
34
|
+
|
35
|
+
@volume_name = volume_name
|
36
|
+
@volume_info = get_volume_info
|
37
|
+
end
|
38
|
+
|
39
|
+
LABELS = {
|
40
|
+
"name" => "Name",
|
41
|
+
"driver" => "Driver",
|
42
|
+
"mountpoint" => "Mountpoint",
|
43
|
+
"created_at" => "CreatedAt",
|
44
|
+
"labels" => "Labels",
|
45
|
+
"scope" => "Scope",
|
46
|
+
"options" => "Options",
|
47
|
+
"mount_count" => "MountCount",
|
48
|
+
"needs_copy_up" => "NeedsCopyUp",
|
49
|
+
"needs_chown" => "NeedsChown",
|
50
|
+
}.freeze
|
51
|
+
|
52
|
+
# This creates all the required properties methods dynamically.
|
53
|
+
LABELS.each do |k, _|
|
54
|
+
define_method(k) do
|
55
|
+
volume_info[k.to_s]
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def exist?
|
60
|
+
!volume_info.empty?
|
61
|
+
end
|
62
|
+
|
63
|
+
def resource_id
|
64
|
+
volume_name
|
65
|
+
end
|
66
|
+
|
67
|
+
def to_s
|
68
|
+
"podman_volume #{resource_id}"
|
69
|
+
end
|
70
|
+
|
71
|
+
private
|
72
|
+
|
73
|
+
def get_volume_info
|
74
|
+
json_key_label = generate_go_template(LABELS)
|
75
|
+
|
76
|
+
inspect_volume_cmd = inspec.command("podman volume inspect #{volume_name} --format '{#{json_key_label}}'")
|
77
|
+
|
78
|
+
if inspect_volume_cmd.exit_status == 0
|
79
|
+
parse_command_output(inspect_volume_cmd.stdout)
|
80
|
+
elsif inspect_volume_cmd.stderr =~ /inspecting object: no such/
|
81
|
+
{}
|
82
|
+
else
|
83
|
+
raise Inspec::Exceptions::ResourceFailed, "Unable to retrieve podman volume information for #{volume_name}.\nError message: #{inspect_volume_cmd.stderr}"
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
@@ -81,7 +81,8 @@ module Inspec::Resources
|
|
81
81
|
# Socket path and empty host in the connection string establishes socket connection
|
82
82
|
# Socket connection only enabled for non-windows platforms
|
83
83
|
# Windows does not support unix domain sockets
|
84
|
-
|
84
|
+
option_port = @port.nil? ? "" : "-p #{@port}" # add explicit port if specified
|
85
|
+
"psql -d postgresql://#{@user}:#{@pass}@/#{dbs}?host=#{@socket_path} #{option_port} -A -t -w -c #{escaped_query(query)}"
|
85
86
|
else
|
86
87
|
# Host in connection string establishes tcp/ip connection
|
87
88
|
if inspec.os.windows?
|
@@ -646,7 +646,7 @@ module Inspec::Resources
|
|
646
646
|
return nil if srv.nil? || srv[0].nil?
|
647
647
|
|
648
648
|
# extract values from service
|
649
|
-
parsed_srv = /^(?<pid>[0-9-]+)\t(?<exit>[0-9]+)\t(?<name>\S*)$/.match(srv[0])
|
649
|
+
parsed_srv = /^(?<pid>[0-9-]+)\t(?<exit>[\-0-9]+)\t(?<name>\S*)$/.match(srv[0])
|
650
650
|
enabled = !parsed_srv["name"].nil? # it's in the list
|
651
651
|
|
652
652
|
# check if the service is running
|
data/lib/inspec/resources.rb
CHANGED
@@ -73,6 +73,7 @@ require "inspec/resources/mssql_sys_conf"
|
|
73
73
|
require "inspec/resources/mysql"
|
74
74
|
require "inspec/resources/mysql_conf"
|
75
75
|
require "inspec/resources/mysql_session"
|
76
|
+
require "inspec/resources/nftables"
|
76
77
|
require "inspec/resources/nginx"
|
77
78
|
require "inspec/resources/nginx_conf"
|
78
79
|
require "inspec/resources/npm"
|
data/lib/inspec/rule.rb
CHANGED
@@ -8,13 +8,15 @@ require "inspec/impact"
|
|
8
8
|
require "inspec/resource"
|
9
9
|
require "inspec/resources/os"
|
10
10
|
require "inspec/input_registry"
|
11
|
+
require "inspec/waiver_file_reader"
|
12
|
+
require "inspec/utils/convert"
|
11
13
|
|
12
14
|
module Inspec
|
13
15
|
class Rule
|
14
16
|
include ::RSpec::Matchers
|
15
17
|
|
16
18
|
attr_reader :__waiver_data
|
17
|
-
attr_accessor :resource_dsl
|
19
|
+
attr_accessor :resource_dsl, :na_impact_freeze
|
18
20
|
attr_reader :__profile_id
|
19
21
|
|
20
22
|
def initialize(id, profile_id, resource_dsl, opts, &block)
|
@@ -38,6 +40,7 @@ module Inspec
|
|
38
40
|
@__merge_count = 0
|
39
41
|
@__merge_changes = []
|
40
42
|
@__skip_only_if_eval = opts[:skip_only_if_eval]
|
43
|
+
@__na_rule = {}
|
41
44
|
|
42
45
|
# evaluate the given definition
|
43
46
|
return unless block_given?
|
@@ -73,10 +76,13 @@ module Inspec
|
|
73
76
|
end
|
74
77
|
|
75
78
|
def impact(v = nil)
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
79
|
+
# N/A impact freeze is required when only_applicable_if block has reset impact value to zero"
|
80
|
+
unless na_impact_freeze
|
81
|
+
if v.is_a?(String)
|
82
|
+
@impact = Inspec::Impact.impact_from_string(v)
|
83
|
+
elsif !v.nil?
|
84
|
+
@impact = v
|
85
|
+
end
|
80
86
|
end
|
81
87
|
|
82
88
|
@impact
|
@@ -133,15 +139,28 @@ module Inspec
|
|
133
139
|
#
|
134
140
|
# @param [Type] &block returns true if tests are added, false otherwise
|
135
141
|
# @return [nil]
|
136
|
-
def only_if(message = nil)
|
142
|
+
def only_if(message = nil, impact: nil)
|
137
143
|
return unless block_given?
|
138
144
|
return if @__skip_only_if_eval == true
|
139
145
|
|
146
|
+
self.impact(impact) if impact && !yield
|
140
147
|
@__skip_rule[:result] ||= !yield
|
141
148
|
@__skip_rule[:type] = :only_if
|
142
149
|
@__skip_rule[:message] = message
|
143
150
|
end
|
144
151
|
|
152
|
+
def only_applicable_if(message = nil)
|
153
|
+
return unless block_given?
|
154
|
+
return if yield
|
155
|
+
|
156
|
+
impact(0.0)
|
157
|
+
self.na_impact_freeze = true # this flag prevents impact value to reset to any other value
|
158
|
+
|
159
|
+
@__na_rule[:result] ||= !yield
|
160
|
+
@__na_rule[:type] = :only_applicable_if
|
161
|
+
@__na_rule[:message] = message
|
162
|
+
end
|
163
|
+
|
145
164
|
# Describe will add one or more tests to this control. There is 2 ways
|
146
165
|
# of calling it:
|
147
166
|
#
|
@@ -252,6 +271,10 @@ module Inspec
|
|
252
271
|
rule.instance_variable_get(:@__skip_rule)
|
253
272
|
end
|
254
273
|
|
274
|
+
def self.na_status(rule)
|
275
|
+
rule.instance_variable_get(:@__na_rule)
|
276
|
+
end
|
277
|
+
|
255
278
|
def self.set_skip_rule(rule, value, message = nil, type = :only_if)
|
256
279
|
rule.instance_variable_set(:@__skip_rule,
|
257
280
|
{
|
@@ -273,16 +296,26 @@ module Inspec
|
|
273
296
|
# creates a dummay array of "checks" with a skip outcome
|
274
297
|
def self.prepare_checks(rule)
|
275
298
|
skip_check = skip_status(rule)
|
276
|
-
|
299
|
+
na_check = na_status(rule)
|
300
|
+
return checks(rule) unless skip_check[:result].eql?(true) || na_check[:result].eql?(true)
|
277
301
|
|
278
|
-
|
279
|
-
|
302
|
+
resource = rule.noop
|
303
|
+
if skip_check[:result].eql?(true)
|
304
|
+
if skip_check[:message]
|
305
|
+
msg = "Skipped control due to #{skip_check[:type]} condition: #{skip_check[:message]}"
|
306
|
+
else
|
307
|
+
msg = "Skipped control due to #{skip_check[:type]} condition."
|
308
|
+
end
|
309
|
+
resource.skip_resource(msg)
|
280
310
|
else
|
281
|
-
|
311
|
+
if na_check[:message]
|
312
|
+
msg = "N/A control due to #{na_check[:type]} condition: #{na_check[:message]}"
|
313
|
+
else
|
314
|
+
msg = "N/A control due to #{na_check[:type]} condition."
|
315
|
+
end
|
316
|
+
resource.fail_resource(msg)
|
282
317
|
end
|
283
318
|
|
284
|
-
resource = rule.noop
|
285
|
-
resource.skip_resource(msg)
|
286
319
|
[["describe", [resource], nil]]
|
287
320
|
end
|
288
321
|
|
@@ -337,17 +370,20 @@ module Inspec
|
|
337
370
|
# only_if mechanism)
|
338
371
|
# Double underscore: not intended to be called as part of the DSL
|
339
372
|
def __apply_waivers
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
373
|
+
control_id = @__rule_id # TODO: control ID slugging
|
374
|
+
waiver_files = Inspec::Config.cached.final_options["waiver_file"] if Inspec::Config.cached.respond_to?(:final_options)
|
375
|
+
|
376
|
+
waiver_data_by_profile = Inspec::WaiverFileReader.fetch_waivers_by_profile(__profile_id, waiver_files) unless waiver_files.nil?
|
377
|
+
|
378
|
+
return unless waiver_data_by_profile && waiver_data_by_profile[control_id] && waiver_data_by_profile[control_id].is_a?(Hash)
|
344
379
|
|
345
380
|
# An InSpec Input is a datastructure that tracks a profile parameter
|
346
381
|
# over time. Its value can be set by many sources, and it keeps a
|
347
382
|
# log of each "set" event so that when it is collapsed to a value,
|
348
383
|
# it can determine the correct (highest priority) value.
|
349
384
|
# Store in an instance variable for.. later reading???
|
350
|
-
@__waiver_data =
|
385
|
+
@__waiver_data = waiver_data_by_profile[control_id]
|
386
|
+
|
351
387
|
__waiver_data["skipped_due_to_waiver"] = false
|
352
388
|
__waiver_data["message"] = ""
|
353
389
|
|
@@ -376,6 +412,7 @@ module Inspec
|
|
376
412
|
# expiration_date. We only care here if it has a "run" key and it
|
377
413
|
# is false-like, since all non-skipped waiver operations are handled
|
378
414
|
# during reporting phase.
|
415
|
+
__waiver_data["run"] = Converter.to_boolean(__waiver_data["run"]) if __waiver_data.key?("run")
|
379
416
|
return unless __waiver_data.key?("run") && !__waiver_data["run"]
|
380
417
|
|
381
418
|
# OK, apply a skip.
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require "inspec/enhanced_outcomes"
|
2
|
+
|
1
3
|
module Inspec
|
2
4
|
class RunData
|
3
5
|
Control = Struct.new(
|
@@ -31,6 +33,10 @@ module Inspec
|
|
31
33
|
].each do |field|
|
32
34
|
self[field] = raw_ctl_data[field]
|
33
35
|
end
|
36
|
+
|
37
|
+
def status
|
38
|
+
Inspec::EnhancedOutcomes.determine_status(results, impact)
|
39
|
+
end
|
34
40
|
end
|
35
41
|
end
|
36
42
|
|
@@ -16,14 +16,20 @@ module Inspec
|
|
16
16
|
:total,
|
17
17
|
:passed,
|
18
18
|
:skipped,
|
19
|
-
:failed
|
19
|
+
:failed,
|
20
|
+
:not_reviewed,
|
21
|
+
:not_applicable,
|
22
|
+
:error
|
20
23
|
) do
|
21
24
|
include HashLikeStruct
|
22
25
|
def initialize(raw_stat_ctl_data)
|
23
26
|
self.total = raw_stat_ctl_data[:total]
|
24
27
|
self.passed = Inspec::RunData::Statistics::Controls::Total.new(raw_stat_ctl_data[:passed][:total])
|
25
|
-
self.skipped = Inspec::RunData::Statistics::Controls::Total.new(raw_stat_ctl_data[:skipped][:total])
|
26
28
|
self.failed = Inspec::RunData::Statistics::Controls::Total.new(raw_stat_ctl_data[:failed][:total])
|
29
|
+
self.skipped = Inspec::RunData::Statistics::Controls::Total.new(raw_stat_ctl_data[:skipped][:total]) if raw_stat_ctl_data[:skipped]
|
30
|
+
self.not_reviewed = Inspec::RunData::Statistics::Controls::Total.new(raw_stat_ctl_data[:not_reviewed][:total]) if raw_stat_ctl_data[:not_reviewed]
|
31
|
+
self.not_applicable = Inspec::RunData::Statistics::Controls::Total.new(raw_stat_ctl_data[:not_applicable][:total]) if raw_stat_ctl_data[:not_applicable]
|
32
|
+
self.error = Inspec::RunData::Statistics::Controls::Total.new(raw_stat_ctl_data[:error][:total]) if raw_stat_ctl_data[:error]
|
27
33
|
end
|
28
34
|
end
|
29
35
|
class Controls
|