inspec-core 6.8.24 → 7.0.38.beta

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.
Files changed (69) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +6 -6
  3. data/etc/deprecations.json +15 -6
  4. data/lib/inspec/base_cli.rb +3 -0
  5. data/lib/inspec/cached_fetcher.rb +16 -1
  6. data/lib/inspec/dependencies/cache.rb +48 -4
  7. data/lib/inspec/dsl.rb +40 -11
  8. data/lib/inspec/exceptions.rb +1 -0
  9. data/lib/inspec/fetcher/gem.rb +99 -0
  10. data/lib/inspec/fetcher/local.rb +1 -1
  11. data/lib/inspec/fetcher.rb +1 -0
  12. data/lib/inspec/file_provider.rb +46 -1
  13. data/lib/inspec/input_registry.rb +1 -1
  14. data/lib/inspec/plugin/v2/concerns/gem_spec_helper.rb +30 -0
  15. data/lib/inspec/plugin/v2/gem_source_manager.rb +43 -0
  16. data/lib/inspec/plugin/v2/installer.rb +42 -16
  17. data/lib/inspec/plugin/v2/loader.rb +34 -5
  18. data/lib/inspec/plugin/v2/plugin_types/resource_pack.rb +8 -0
  19. data/lib/inspec/plugin/v2.rb +1 -0
  20. data/lib/inspec/profile.rb +10 -0
  21. data/lib/inspec/profile_context.rb +10 -0
  22. data/lib/inspec/reporters/automate.rb +2 -2
  23. data/lib/inspec/resources/auditd.rb +1 -1
  24. data/lib/inspec/resources/groups.rb +52 -0
  25. data/lib/inspec/resources/port.rb +2 -2
  26. data/lib/inspec/resources/postgres_session.rb +5 -9
  27. data/lib/inspec/resources/yum.rb +1 -1
  28. data/lib/inspec/resources.rb +0 -14
  29. data/lib/inspec/runner.rb +7 -15
  30. data/lib/inspec/source_reader.rb +2 -0
  31. data/lib/inspec/ui.rb +1 -0
  32. data/lib/inspec/utils/deprecation/config_file.rb +39 -3
  33. data/lib/inspec/utils/deprecation/deprecator.rb +10 -3
  34. data/lib/inspec/utils/licensing_config.rb +1 -15
  35. data/lib/inspec/utils/parser.rb +9 -19
  36. data/lib/inspec/utils/telemetry.rb +1 -3
  37. data/lib/inspec/version.rb +1 -1
  38. data/lib/plugins/inspec-plugin-manager-cli/lib/inspec-plugin-manager-cli/cli_command.rb +2 -4
  39. data/lib/source_readers/gem.rb +67 -0
  40. data/lib/source_readers/inspec.rb +1 -1
  41. metadata +9 -32
  42. data/lib/inspec/resources/docker.rb +0 -274
  43. data/lib/inspec/resources/docker_container.rb +0 -116
  44. data/lib/inspec/resources/docker_image.rb +0 -141
  45. data/lib/inspec/resources/docker_object.rb +0 -52
  46. data/lib/inspec/resources/docker_plugin.rb +0 -68
  47. data/lib/inspec/resources/docker_service.rb +0 -95
  48. data/lib/inspec/resources/elasticsearch.rb +0 -165
  49. data/lib/inspec/resources/ibmdb2_conf.rb +0 -65
  50. data/lib/inspec/resources/ibmdb2_session.rb +0 -78
  51. data/lib/inspec/resources/mongodb.rb +0 -69
  52. data/lib/inspec/resources/mongodb_conf.rb +0 -44
  53. data/lib/inspec/resources/mongodb_session.rb +0 -98
  54. data/lib/inspec/resources/podman.rb +0 -353
  55. data/lib/inspec/resources/podman_container.rb +0 -84
  56. data/lib/inspec/resources/podman_image.rb +0 -108
  57. data/lib/inspec/resources/podman_network.rb +0 -81
  58. data/lib/inspec/resources/podman_pod.rb +0 -101
  59. data/lib/inspec/resources/podman_volume.rb +0 -87
  60. data/lib/inspec/resources/rabbitmq_conf.rb +0 -2
  61. data/lib/inspec/resources/rabbitmq_config.rb +0 -56
  62. data/lib/inspec/resources/ssh_config.rb +0 -215
  63. data/lib/inspec/resources/ssh_key.rb +0 -124
  64. data/lib/inspec/resources/sshd_active_config.rb +0 -2
  65. data/lib/inspec/resources/sshd_config.rb +0 -2
  66. data/lib/inspec/resources/sybase_conf.rb +0 -41
  67. data/lib/inspec/resources/sybase_session.rb +0 -124
  68. data/lib/inspec/utils/deprecated_core_resources_list.rb +0 -25
  69. data/lib/inspec/utils/podman.rb +0 -24
@@ -1,141 +0,0 @@
1
- #
2
- # Copyright 2017, Christoph Hartmann
3
-
4
- require "inspec/resources/docker"
5
- require_relative "docker_object"
6
-
7
- module Inspec::Resources
8
- class DockerImage < Inspec.resource(1)
9
- include Inspec::Resources::DockerObject
10
-
11
- name "docker_image"
12
- supports platform: "unix"
13
- desc ""
14
- example <<~EXAMPLE
15
- describe docker_image('alpine:latest') do
16
- it { should exist }
17
- its('id') { should_not eq '' }
18
- its('image') { should eq 'alpine:latest' }
19
- its('repo') { should eq 'alpine' }
20
- its('tag') { should eq 'latest' }
21
- end
22
-
23
- describe docker_image('alpine:latest') do
24
- it { should exist }
25
- end
26
-
27
- describe docker_image(id: '4a415e366388') do
28
- it { should exist }
29
- end
30
- EXAMPLE
31
-
32
- def initialize(opts = {})
33
- # do sanitizion of input values
34
- o = opts.dup
35
- o = { image: opts } if opts.is_a?(String)
36
- @opts = sanitize_options(o)
37
- end
38
-
39
- def image
40
- "#{repo}:#{tag}" if object_info.entries.size == 1
41
- end
42
-
43
- def repo
44
- object_info.repositories[0] if object_info.entries.size == 1
45
- end
46
-
47
- def tag
48
- object_info.tags[0] if object_info.entries.size == 1
49
- end
50
-
51
- # method_missing handles when hash_keys are invoked to check information obtained on docker inspect [image_name]
52
- def method_missing(*hash_keys)
53
- # User can test the low-level inspect information in three ways:
54
- # Way 1: Serverspec style: its(['Config.Cmd']) { should include some_value }
55
- # here, the value for hash_keys recieved is [:[], "Config.Cmd"]
56
- # Way 2: InSpec style: its(['Config','Cmd']) { should include some_value }
57
- # here, the value for hash_keys recieved is [:[], "Config", "Cmd"]
58
- # Way 3: Mix of both: its(['GraphDriver.Data','MergedDir']) { should include some_value }
59
- # here, the value for hash_keys recieved is [:[], "GraphDriver.Data", "MergedDir"]
60
-
61
- # hash_keys are passed to this method to evaluate the value
62
- image_hash_inspection(hash_keys)
63
- end
64
-
65
- # inspection property allows to test any of the hash key-value pairs as part of the image_inspect_info
66
- def inspection
67
- image_inspect_info
68
- end
69
-
70
- def to_s
71
- img = @opts[:image] || @opts[:id]
72
- "Docker Image #{img}"
73
- end
74
-
75
- def resource_id
76
- object_info.ids[0] || @opts[:id] || @opts[:image] || ""
77
- end
78
-
79
- private
80
-
81
- def sanitize_options(opts)
82
- opts.merge!(parse_components_from_image(opts[:image]))
83
-
84
- # assume a "latest" tag if we don't have one
85
- opts[:tag] ||= "latest"
86
-
87
- # if the ID isn't nil and doesn't contain a hash indicator (indicated by the presence
88
- # of a colon, which separates the indicator from the actual hash), we assume it's sha256.
89
- opts[:id] = "sha256:" + opts[:id] unless opts[:id].nil? || opts[:id].include?(":")
90
-
91
- # Assemble/reassemble the image from the repo and tag
92
- opts[:image] = "#{opts[:repo]}:#{opts[:tag]}" unless opts[:repo].nil?
93
-
94
- # return the santized opts back to the caller
95
- opts
96
- end
97
-
98
- def object_info
99
- return @info if defined?(@info)
100
-
101
- opts = @opts
102
- @info = inspec.docker.images.where do
103
- (repository == opts[:repo] && tag == opts[:tag]) || (!id.nil? && !opts[:id].nil? && (id == opts[:id] || id.start_with?(opts[:id])))
104
- end
105
- end
106
-
107
- # image_inspect_info returns the complete inspect hash_values of the image
108
- def image_inspect_info
109
- return @inspect_info if defined?(@inspect_info)
110
-
111
- @inspect_info = inspec.docker.object(@opts[:image] || (!@opts[:id].nil? && @opts[:id]))
112
- end
113
-
114
- # image_hash_inspection formats the input hash_keys and checks if any value exists for such keys in @inspect_info(image_inspect_info)
115
- def image_hash_inspection(hash_keys)
116
- # The hash_keys recieved are in three formats as mentioned in method_missing
117
- # The hash_keys recieved must be in array format [] and the zeroth index must be :[]
118
- # Check for the conditions and remove the zeroth element from the hash_keys
119
-
120
- hash_keys.shift if hash_keys.is_a?(Array) && hash_keys[0] == :[]
121
-
122
- # When received hash_keys in Serverspec style or mix of both
123
- # The hash_keys are to be splitted at '.' (dot) and flatten it so that it doesn't become array of arrays
124
- # After splitting and flattening is done, hash_keys is now an array with individual keys
125
- hash_keys = hash_keys.map { |key| key.split(".") }.flatten
126
-
127
- # image_inspect_info returns the complete inspect hash_values of the image
128
- # dig() finds the nested value specified by the sequence of the key object by calling dig at each step.
129
- # hash_keys is the key object. If one of the key is bad, value will be nil.
130
- hash_value = image_inspect_info.dig(*hash_keys)
131
-
132
- # If one of the key is bad, hash_value will be nil, so raise exception which throws it in rescue block
133
- # else return hash_value
134
- raise Inspec::Exceptions::ResourceFailed if hash_value.nil?
135
-
136
- hash_value
137
- rescue
138
- raise Inspec::Exceptions::ResourceFailed, "#{hash_keys.join(".")} is not a valid key for your image or has nil value."
139
- end
140
- end
141
- end
@@ -1,52 +0,0 @@
1
- #
2
- # Copyright 2017, Christoph Hartmann
3
- #
4
-
5
- module Inspec::Resources::DockerObject
6
- def exist?
7
- object_info.exists?
8
- end
9
-
10
- def id
11
- object_info.ids[0] if object_info.entries.size == 1
12
- end
13
-
14
- private
15
-
16
- def parse_components_from_image(image_string)
17
- # if the user did not supply an image string, they likely supplied individual
18
- # option parameters, such as repo and tag. Return empty data back to the caller.
19
- return {} if image_string.nil?
20
-
21
- first_colon = image_string.index(":") || -1
22
- first_slash = image_string.index("/") || -1
23
-
24
- if image_string.count(":") == 2
25
- # If there are two colons in the image string, it contains a repo-with-port and a tag.
26
- # example: localhost:5000/chef/inspec:1.46.3
27
- partitioned_string = image_string.rpartition(":")
28
- repo = partitioned_string.first
29
- tag = partitioned_string.last
30
- image_name = repo.split("/")[1..-1].join
31
- elsif image_string.count(":") == 1 && first_colon < first_slash
32
- # If there's one colon in the image string, and it comes before a forward-slash,
33
- # it contains a repo-with-port but no tag.
34
- # example: localhost:5000/ubuntu
35
- repo = image_string
36
- tag = nil
37
- image_name = repo.split("/")[1..-1].join
38
- else
39
- # If there's one colon in the image string and it doesn't preceed a slash, or if
40
- # there is no colon at all, then it separates the repo from the tag, if there is a tag.
41
- # example: chef/inspec:1.46.3
42
- # example: chef/inspec
43
- # example: ubuntu:14.04
44
- repo, tag = image_string.split(":")
45
- image_name = repo
46
- end
47
-
48
- # return the repo, image_name and tag parsed from the string, which can be merged into
49
- # the rest of the user-supplied options
50
- { repo: repo, image_name: image_name, tag: tag }
51
- end
52
- end
@@ -1,68 +0,0 @@
1
- require "inspec/resources/docker"
2
-
3
- module Inspec::Resources
4
- class DockerPlugin < Inspec.resource(1)
5
- name "docker_plugin"
6
- supports platform: "unix"
7
- desc "Retrieves info about docker plugins"
8
- example <<~EXAMPLE
9
- describe docker_plugin('rexray/ebs') do
10
- it { should exist }
11
- its('id') { should_not eq '0ac30b93ad40' }
12
- its('version') { should eq '0.11.1' }
13
- it { should be_enabled }
14
- end
15
-
16
- describe docker_plugin('alpine:latest') do
17
- it { should exist }
18
- end
19
-
20
- describe docker_plugin(id: '4a415e366388') do
21
- it { should exist }
22
- end
23
- EXAMPLE
24
-
25
- def initialize(opts = {})
26
- # do sanitizion of input values
27
- o = opts.dup
28
- o = { name: opts } if opts.is_a?(String)
29
- @opts = o
30
- end
31
-
32
- def exist?
33
- object_info.entries.size == 1
34
- end
35
-
36
- def enabled?
37
- object_info.enabled[0]
38
- end
39
-
40
- def id
41
- object_info.ids[0] if object_info.entries.size == 1
42
- end
43
-
44
- def version
45
- object_info.versions[0] if object_info.entries.size == 1
46
- end
47
-
48
- def to_s
49
- plugin = @opts[:name] || @opts[:id]
50
- "Docker plugin #{plugin}"
51
- end
52
-
53
- def resource_id
54
- id || @opts[:id] || @opts[:name] || ""
55
- end
56
-
57
- private
58
-
59
- def object_info
60
- return @info if defined?(@info)
61
-
62
- opts = @opts
63
- @info = inspec.docker.plugins.where do
64
- (name == opts[:name]) || (!id.nil? && !opts[:id].nil? && (id == opts[:id]))
65
- end
66
- end
67
- end
68
- end
@@ -1,95 +0,0 @@
1
- #
2
- # Copyright 2017, Christoph Hartmann
3
-
4
- require "inspec/resources/docker"
5
- require_relative "docker_object"
6
-
7
- module Inspec::Resources
8
- class DockerService < Inspec.resource(1)
9
- include Inspec::Resources::DockerObject
10
-
11
- name "docker_service"
12
- supports platform: "unix"
13
- desc "Swarm-mode service"
14
- example <<~EXAMPLE
15
- describe docker_service('service1') do
16
- it { should exist }
17
- its('id') { should_not eq '' }
18
- its('image') { should eq 'alpine:latest' }
19
- its('repo') { should eq 'alpine' }
20
- its('tag') { should eq 'latest' }
21
- end
22
-
23
- describe docker_service(id: '4a415e366388') do
24
- it { should exist }
25
- end
26
-
27
- describe docker_service(image: 'alpine:latest') do
28
- it { should exist }
29
- end
30
- EXAMPLE
31
-
32
- def initialize(opts = {})
33
- # do sanitizion of input values
34
- o = opts.dup
35
- o = { name: opts } if opts.is_a?(String)
36
- @opts = sanitize_options(o)
37
- end
38
-
39
- def name
40
- object_info.names[0] if object_info.entries.size == 1
41
- end
42
-
43
- def image
44
- object_info.images[0] if object_info.entries.size == 1
45
- end
46
-
47
- def image_name
48
- parse_components_from_image(image)[:image_name] if object_info.entries.size == 1
49
- end
50
-
51
- def repo
52
- parse_components_from_image(image)[:repo] if object_info.entries.size == 1
53
- end
54
-
55
- def tag
56
- parse_components_from_image(image)[:tag] if object_info.entries.size == 1
57
- end
58
-
59
- def mode
60
- object_info.modes[0] if object_info.entries.size == 1
61
- end
62
-
63
- def replicas
64
- object_info.replicas[0] if object_info.entries.size == 1
65
- end
66
-
67
- def ports
68
- object_info.ports[0] if object_info.entries.size == 1
69
- end
70
-
71
- def to_s
72
- service = @opts[:name] || @opts[:id]
73
- "Docker Service #{service}"
74
- end
75
-
76
- def resource_id
77
- object_info.ids[0] || @opts[:id] || @opts[:name] || ""
78
- end
79
-
80
- private
81
-
82
- def sanitize_options(opts)
83
- opts.merge(parse_components_from_image(opts[:image]))
84
- end
85
-
86
- def object_info
87
- return @info if defined?(@info)
88
-
89
- opts = @opts
90
- @info = inspec.docker.services.where do
91
- name == opts[:name] || image == opts[:image] || (!id.nil? && !opts[:id].nil? && (id == opts[:id] || id.start_with?(opts[:id])))
92
- end
93
- end
94
- end
95
- end
@@ -1,165 +0,0 @@
1
- require "inspec/utils/filter"
2
- require "hashie/mash"
3
- require "inspec/resources/package"
4
-
5
- module Inspec::Resources
6
- class Elasticsearch < Inspec.resource(1)
7
- name "elasticsearch"
8
- supports platform: "unix"
9
- desc "Use the Elasticsearch InSpec audit resource to test the status of nodes in
10
- an Elasticsearch cluster."
11
-
12
- example <<~EXAMPLE
13
- describe elasticsearch('http://eshost.mycompany.biz:9200/', username: 'elastic', password: 'changeme', ssl_verify: false) do
14
- its('node_count') { should >= 3 }
15
- end
16
-
17
- describe elasticsearch do
18
- its('node_name') { should include 'node1' }
19
- its('os') { should_not include 'MacOS' }
20
- its('version') { should cmp > 1.2.0 }
21
- end
22
- EXAMPLE
23
-
24
- filter = FilterTable.create
25
- filter.register_custom_matcher(:exists?) { |x| !x.entries.empty? }
26
- filter.register_column(:cluster_name, field: "cluster_name")
27
- .register_column(:node_name, field: "name")
28
- .register_column(:transport_address, field: "transport_address")
29
- .register_column(:host, field: "host")
30
- .register_column(:ip, field: "ip")
31
- .register_column(:version, field: "version")
32
- .register_column(:build_hash, field: "build_hash")
33
- .register_column(:total_indexing_buffer, field: "total_indexing_buffer")
34
- .register_column(:roles, field: "roles")
35
- .register_column(:settings, field: "settings")
36
- .register_column(:os, field: "os")
37
- .register_column(:process, field: "process")
38
- .register_column(:jvm, field: "jvm")
39
- .register_column(:transport, field: "transport")
40
- .register_column(:http, field: "http")
41
- .register_column(:plugins, field: "plugins")
42
- .register_column(:plugin_list, field: "plugin_list")
43
- .register_column(:modules, field: "modules")
44
- .register_column(:module_list, field: "module_list")
45
- .register_column(:node_id, field: "node_id")
46
- .register_column(:ingest, field: "ingest")
47
- .register_custom_property(:node_count) do |t, _|
48
- t.entries.length
49
- end
50
-
51
- filter.install_filter_methods_on_resource(self, :nodes)
52
-
53
- attr_reader :nodes, :url
54
-
55
- def initialize(opts = {})
56
- return skip_resource "Package `curl` not avaiable on the host" unless inspec.command("curl").exist?
57
-
58
- @url = opts.fetch(:url, "http://localhost:9200")
59
-
60
- username = opts.fetch(:username, nil)
61
- password = opts.fetch(:password, nil)
62
- ssl_verify = opts.fetch(:ssl_verify, true)
63
-
64
- cmd = inspec.command(curl_command_string(username, password, ssl_verify))
65
-
66
- # after implementation of PR #2235, this begin..rescue won't be necessary.
67
- # The checks in verify_curl_success! can raise their own skip message exception.
68
- begin
69
- verify_curl_success!(cmd)
70
- rescue => e
71
- return skip_resource e.message
72
- end
73
-
74
- begin
75
- content = JSON.parse(cmd.stdout)
76
- # after implementation of PR #2235, this can be broken out of the begin..rescue
77
- # clause. The checks in verify_json_payload! can raise their own skip message exception.
78
- verify_json_payload!(content)
79
- rescue JSON::ParserError => e
80
- return skip_resource "Couldn't parse the Elasticsearch response: #{e.message}"
81
- rescue => e
82
- return skip_resource e.message
83
- end
84
-
85
- @nodes = parse_cluster(content)
86
- end
87
-
88
- def to_s
89
- "Elasticsearch Cluster #{url}"
90
- end
91
-
92
- private
93
-
94
- def parse_cluster(content)
95
- return [] unless content["nodes"]
96
-
97
- nodes = []
98
-
99
- content["nodes"].each do |node_id, node_data|
100
- node_data = fix_mash_key_collision(node_data)
101
-
102
- node = Hashie::Mash.new(node_data)
103
- node.node_id = node_id
104
- node.plugin_list = node.plugins.map(&:name)
105
- node.module_list = node.modules.map(&:name)
106
- node.cluster_name = node.settings.cluster.name
107
- nodes << node
108
- end
109
-
110
- nodes
111
- end
112
-
113
- #
114
- # Hashie::Mash will throw warnings if the Mash contains a key that is the same as a built-in
115
- # method on a Hashie::Mash instance. This is a crude way of avoiding those warnings without
116
- # hard-coding a bunch of key renames.
117
- #
118
- # Any key that is in conflict will be renamed "es_ORIGINALKEY"
119
- #
120
- def fix_mash_key_collision(data)
121
- test_mash = Hashie::Mash.new
122
-
123
- new_data = {}
124
- data.each do |key, value|
125
- new_key = test_mash.respond_to?(key.to_sym) ? "es_#{key}" : key
126
- new_value = value.is_a?(Hash) ? fix_mash_key_collision(value) : value
127
-
128
- new_data[new_key] = new_value
129
- end
130
-
131
- new_data
132
- end
133
-
134
- def curl_command_string(username, password, ssl_verify)
135
- cmd_string = ["curl"]
136
- cmd_string << "-k" unless ssl_verify
137
- cmd_string << "-H 'Content-Type: application/json'"
138
- cmd_string << " -u #{username}:#{password}" unless username.nil? || password.nil?
139
- cmd_string << URI.join(url, "_nodes")
140
-
141
- cmd_string.join(" ")
142
- end
143
-
144
- def verify_curl_success!(cmd)
145
- # the following lines captures known possible curl command errors and provides compact skip resource messeges
146
- if cmd.stderr =~ /Failed to connect/
147
- raise "Connection refused - please check the URL #{url} for accuracy"
148
- end
149
-
150
- if cmd.stderr =~ /Peer's Certificate issuer is not recognized/
151
- raise "Connection refused - peer certificate issuer is not recognized"
152
- end
153
-
154
- raise "Error fetching Elastcsearch data from curl #{url}: #{cmd.stderr}" unless cmd.exit_status == 0
155
- end
156
-
157
- def verify_json_payload!(content)
158
- unless content["error"].nil?
159
- raise "#{content["error"]["type"]}: #{content["error"]["reason"]}"
160
- end
161
-
162
- raise "No successful nodes available in cluster" if content["_nodes"]["successful"] == 0
163
- end
164
- end
165
- end
@@ -1,65 +0,0 @@
1
- module Inspec::Resources
2
- class Ibmdb2Conf < Inspec.resource(1)
3
- name "ibmdb2_conf"
4
-
5
- supports platform: "unix"
6
- supports platform: "windows"
7
-
8
- desc "Use the ibmdb2_conf InSpec audit resource to test the configuration values of IBM Db2 database."
9
- example <<~EXAMPLE
10
- describe ibmdb2_conf(db2_executable_file_path: "path_to_db2_binary", db_instance: "db2inst1") do
11
- its("output") { should_not be_empty }
12
- its("output") { should include("Audit buffer size (4KB) (AUDIT_BUF_SZ) = 0")}
13
- end
14
- EXAMPLE
15
-
16
- attr_reader :output
17
-
18
- def initialize(opts = {})
19
- if inspec.os.platform?("unix")
20
- @db2_executable_file_path = opts[:db2_executable_file_path]
21
- @db_instance = opts[:db_instance]
22
- raise Inspec::Exceptions::ResourceFailed, "Can't connect to IBM DB2 without db2_executable_file_path, db_instance options provided." if @db2_executable_file_path.nil? || @db_instance.nil?
23
- end
24
- @output = run_command
25
- end
26
-
27
- def resource_id
28
- if inspec.os.platform?("windows")
29
- "ibmdb2_conf"
30
- else
31
- "ibmdb2_conf:DatabaseInstance:#{@db_instance}"
32
- end
33
- end
34
-
35
- def to_s
36
- "IBM Db2 Conf"
37
- end
38
-
39
- private
40
-
41
- def run_command
42
- # attach to the db2 instance and get the configuration
43
- if inspec.os.platform?("unix")
44
- cmd = inspec.command("#{@db2_executable_file_path} attach to #{@db_instance}\; #{@db2_executable_file_path} get database manager configuration")
45
- out = cmd.stdout + "\n" + cmd.stderr
46
-
47
- # check if following specific error is there. Sourcing the db2profile to resolve the error.
48
- if cmd.exit_status != 0 && out =~ /SQL10007N Message "-1390" could not be retrieved. Reason code: "3"/
49
- cmd = inspec.command(". ~/sqllib/db2profile\; #{@db2_executable_file_path} attach to #{@db_instance}\; #{@db2_executable_file_path} get database manager configuration")
50
- out = cmd.stdout + "\n" + cmd.stderr
51
- end
52
- elsif inspec.os.platform?("windows")
53
- # set-item command set the powershell to run the db2 commands.
54
- cmd = inspec.command("set-item -path env:DB2CLP -value \"**$$**\"\; db2 get database manager configuration")
55
- out = cmd.stdout + "\n" + cmd.stderr
56
- end
57
-
58
- if cmd.exit_status != 0 || out =~ /Can't connect to IBM Db2 server/ || out.downcase =~ /^error:.*/
59
- raise Inspec::Exceptions::ResourceFailed, "IBM Db2 query with error: #{out}"
60
- else
61
- cmd.stdout.gsub(/\n|\r/, ",").split(",").reject { |n| n.nil? || n.empty? }.map { |n| n.strip.gsub!(/\s+/, " ") }
62
- end
63
- end
64
- end
65
- end
@@ -1,78 +0,0 @@
1
- module Inspec::Resources
2
- class Lines
3
- attr_reader :output, :exit_status
4
-
5
- def initialize(raw, desc, exit_status)
6
- @output = raw
7
- @desc = desc
8
- @exit_status = exit_status
9
- end
10
-
11
- def to_s
12
- @desc
13
- end
14
- end
15
-
16
- class Ibmdb2Session < Inspec.resource(1)
17
- name "ibmdb2_session"
18
-
19
- supports platform: "unix"
20
- supports platform: "windows"
21
-
22
- desc "Use the ibmdb2_session InSpec audit resource to test SQL commands run against a IBM Db2 database."
23
- example <<~EXAMPLE
24
- describe ibmdb2_session(db2_executable_file_path: "path_to_db2_binary", db_instance: "db2inst1", db_name: "sample").query('list database directory') do
25
- its('output') { should_not match(/sample/) }
26
- end
27
- EXAMPLE
28
-
29
- def initialize(opts = {})
30
- @db_name = opts[:db_name]
31
- if inspec.os.platform?("unix")
32
- @db2_executable_file_path = opts[:db2_executable_file_path]
33
- @db_instance = opts[:db_instance]
34
- raise Inspec::Exceptions::ResourceFailed, "Can't run IBM DB2 queries without db2_executable_file_path, db_instance, db_name options provided." if @db2_executable_file_path.nil? || @db_instance.nil? || @db_name.nil?
35
- elsif inspec.os.platform?("windows")
36
- raise Inspec::Exceptions::ResourceFailed, "Can't run IBM DB2 queries without db_name option provided." if @db_name.nil?
37
- end
38
- end
39
-
40
- def query(q)
41
- raise Inspec::Exceptions::ResourceFailed, "#{resource_exception_message}" if resource_failed?
42
-
43
- if inspec.os.platform?("unix")
44
- # connect to the db and query on the database
45
- cmd = inspec.command("#{@db2_executable_file_path} attach to #{@db_instance}\; #{@db2_executable_file_path} connect to #{@db_name}\; #{@db2_executable_file_path} #{q}\;")
46
- out = cmd.stdout + "\n" + cmd.stderr
47
-
48
- # check if following specific error is there. Sourcing the db2profile to resolve the error.
49
- if cmd.exit_status != 0 && out =~ /SQL10007N Message "-1390" could not be retrieved. Reason code: "3"/
50
- cmd = inspec.command(". ~/sqllib/db2profile\; #{@db2_executable_file_path} attach to #{@db_instance}\; #{@db2_executable_file_path} connect to #{@db_name}\; #{@db2_executable_file_path} \"#{q}\"\;")
51
- out = cmd.stdout + "\n" + cmd.stderr
52
- end
53
- elsif inspec.os.platform?("windows")
54
- # set-item command set the powershell to run the db2 commands.
55
- cmd = inspec.command("set-item -path env:DB2CLP -value \"**$$**\"\; db2 connect to #{@db_name}\; db2 \"#{q}\"\;")
56
- out = cmd.stdout + "\n" + cmd.stderr
57
- end
58
-
59
- if cmd.exit_status != 0 || out =~ /Can't connect to IBM Db2 / || out.downcase =~ /^error:.*/
60
- raise Inspec::Exceptions::ResourceFailed, "IBM Db2 connection error: #{out}"
61
- else
62
- Lines.new(cmd.stdout.strip, "IBM Db2 Query: #{q}", cmd.exit_status)
63
- end
64
- end
65
-
66
- def resource_id
67
- if inspec.os.platform?("windows")
68
- "ibmdb2_session:DatabaseName#{@db_name}"
69
- else
70
- "ibmdb2_session:DatabaseInstance:#{@db_instance}:DatabaseName#{@db_name}"
71
- end
72
- end
73
-
74
- def to_s
75
- "IBM Db2 Session"
76
- end
77
- end
78
- end