inspec-core 5.18.14 → 5.21.29

Sign up to get free protection for your applications and to get access to all the features.
Files changed (58) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +19 -16
  3. data/inspec-core.gemspec +22 -22
  4. data/lib/inspec/base_cli.rb +2 -0
  5. data/lib/inspec/cli.rb +6 -2
  6. data/lib/inspec/dsl.rb +10 -4
  7. data/lib/inspec/enhanced_outcomes.rb +19 -0
  8. data/lib/inspec/env_printer.rb +1 -1
  9. data/lib/inspec/exceptions.rb +2 -0
  10. data/lib/inspec/formatters/base.rb +69 -16
  11. data/lib/inspec/plugin/v2/loader.rb +19 -8
  12. data/lib/inspec/plugin/v2/plugin_types/reporter.rb +1 -0
  13. data/lib/inspec/plugin/v2/plugin_types/streaming_reporter.rb +54 -0
  14. data/lib/inspec/reporters/base.rb +1 -0
  15. data/lib/inspec/reporters/cli.rb +94 -3
  16. data/lib/inspec/reporters/json.rb +3 -1
  17. data/lib/inspec/reporters/yaml.rb +3 -1
  18. data/lib/inspec/reporters.rb +2 -1
  19. data/lib/inspec/resources/file.rb +1 -1
  20. data/lib/inspec/resources/http.rb +2 -2
  21. data/lib/inspec/resources/lxc.rb +65 -9
  22. data/lib/inspec/resources/oracledb_session.rb +13 -4
  23. data/lib/inspec/resources/podman.rb +353 -0
  24. data/lib/inspec/resources/podman_container.rb +84 -0
  25. data/lib/inspec/resources/podman_image.rb +108 -0
  26. data/lib/inspec/resources/podman_network.rb +81 -0
  27. data/lib/inspec/resources/podman_pod.rb +101 -0
  28. data/lib/inspec/resources/podman_volume.rb +87 -0
  29. data/lib/inspec/resources/service.rb +1 -1
  30. data/lib/inspec/rule.rb +54 -17
  31. data/lib/inspec/run_data/control.rb +6 -0
  32. data/lib/inspec/run_data/statistics.rb +8 -2
  33. data/lib/inspec/runner.rb +18 -8
  34. data/lib/inspec/runner_rspec.rb +3 -2
  35. data/lib/inspec/schema/exec_json.rb +78 -2
  36. data/lib/inspec/schema/output_schema.rb +4 -1
  37. data/lib/inspec/schema/profile_json.rb +46 -0
  38. data/lib/inspec/schema.rb +91 -0
  39. data/lib/inspec/utils/convert.rb +8 -0
  40. data/lib/inspec/utils/podman.rb +24 -0
  41. data/lib/inspec/utils/waivers/csv_file_reader.rb +34 -0
  42. data/lib/inspec/utils/waivers/excel_file_reader.rb +39 -0
  43. data/lib/inspec/utils/waivers/json_file_reader.rb +15 -0
  44. data/lib/inspec/version.rb +1 -1
  45. data/lib/inspec/waiver_file_reader.rb +61 -0
  46. data/lib/matchers/matchers.rb +7 -1
  47. data/lib/plugins/inspec-init/templates/profiles/alicloud/README.md +27 -0
  48. data/lib/plugins/inspec-init/templates/profiles/alicloud/controls/example.rb +10 -0
  49. data/lib/plugins/inspec-init/templates/profiles/alicloud/inputs.yml +1 -0
  50. data/lib/plugins/inspec-init/templates/profiles/alicloud/inspec.yml +14 -0
  51. data/lib/plugins/inspec-reporter-html2/README.md +1 -1
  52. data/lib/plugins/inspec-reporter-html2/templates/body.html.erb +7 -1
  53. data/lib/plugins/inspec-reporter-html2/templates/control.html.erb +10 -6
  54. data/lib/plugins/inspec-reporter-html2/templates/default.css +12 -0
  55. data/lib/plugins/inspec-reporter-html2/templates/selector.html.erb +7 -1
  56. data/lib/plugins/inspec-sign/lib/inspec-sign/base.rb +5 -2
  57. data/lib/plugins/inspec-streaming-reporter-progress-bar/lib/inspec-streaming-reporter-progress-bar/streaming_reporter.rb +39 -13
  58. metadata +25 -9
@@ -0,0 +1,353 @@
1
+ require "inspec/resources/command"
2
+ require "inspec/utils/filter"
3
+ require "hashie/mash"
4
+
5
+ module Inspec::Resources
6
+ class Podman < Inspec.resource(1)
7
+ # Resource requires an internal name.
8
+ name "podman"
9
+
10
+ # Restrict to only run on the below platforms (if none were given,
11
+ # all OS's and cloud API's supported)
12
+ supports platform: "unix"
13
+
14
+ desc "A resource to retrieve information about podman"
15
+
16
+ example <<~EXAMPLE
17
+ describe podman.containers do
18
+ its('images') { should include "docker.io/library/ubuntu:latest" }
19
+ end
20
+
21
+ describe podman.images do
22
+ its('names') { should_not include "docker.io/library/ubuntu:latest" }
23
+ end
24
+
25
+ describe podman.pods do
26
+ its("ids") { should include "95cadbb84df71e6374fceb3fd89ee3b8f2c7e1a831062cd9cea7d0e3e4b1dbcc" }
27
+ end
28
+
29
+ describe podman.info.host do
30
+ its("os") { should eq "linux"}
31
+ end
32
+
33
+ describe podman.version do
34
+ its("Client.Version") { should eq "4.1.0"}
35
+ end
36
+
37
+ podman.containers.ids.each do |id|
38
+ # call podman inspect for a specific container id
39
+ describe podman.object(id) do
40
+ its("State.OciVersion") { should eq "1.0.2-dev" }
41
+ its("State.Running") { should eq true}
42
+ end
43
+ end
44
+ EXAMPLE
45
+
46
+ def containers
47
+ PodmanContainerFilter.new(parse_containers)
48
+ end
49
+
50
+ def images
51
+ PodmanImageFilter.new(parse_images)
52
+ end
53
+
54
+ def networks
55
+ PodmanNetworkFilter.new(parse_networks)
56
+ end
57
+
58
+ def pods
59
+ PodmanPodFilter.new(parse_pods)
60
+ end
61
+
62
+ def volumes
63
+ PodmanVolumeFilter.new(parse_volumes)
64
+ end
65
+
66
+ def version
67
+ return @version if defined?(@version)
68
+
69
+ sub_cmd = "version --format json"
70
+ output = run_command(sub_cmd)
71
+ @version = Hashie::Mash.new(JSON.parse(output))
72
+ rescue JSON::ParserError => _e
73
+ Hashie::Mash.new({})
74
+ end
75
+
76
+ def info
77
+ return @info if defined?(@info)
78
+
79
+ sub_cmd = "info --format json"
80
+ output = run_command(sub_cmd)
81
+ @info = Hashie::Mash.new(JSON.parse(output))
82
+ rescue JSON::ParserError => _e
83
+ Hashie::Mash.new({})
84
+ end
85
+
86
+ # returns information about podman objects
87
+ def object(id)
88
+ return @inspect if defined?(@inspect)
89
+
90
+ output = run_command("inspect #{id} --format json")
91
+ data = JSON.parse(output)
92
+ data = data[0] if data.is_a?(Array)
93
+ @inspect = Hashie::Mash.new(data)
94
+ rescue JSON::ParserError => _e
95
+ Hashie::Mash.new({})
96
+ end
97
+
98
+ def to_s
99
+ "Podman"
100
+ end
101
+
102
+ private
103
+
104
+ # Calls the run_command method to get all podman containers and parse the command output.
105
+ # Returns the parsed command output.
106
+ def parse_containers
107
+ labels = %w{ID Image ImageID Command CreatedAt RunningFor Status Pod Ports Size Names Networks Labels Mounts}
108
+ parse_json_command(labels, "ps -a --no-trunc --size")
109
+ end
110
+
111
+ # Calls the run_command method to get all podman images and parse the command output.
112
+ # Returns the parsed command output.
113
+ def parse_images
114
+ labels = %w{ID Repository Tag Size Digest CreatedAt CreatedSince History}
115
+ parse_json_command(labels, "images -a --no-trunc")
116
+ end
117
+
118
+ # Calls the run_command method to get all podman network list and parse the command output.
119
+ # Returns the parsed command output.
120
+ def parse_networks
121
+ labels = %w{ID Name Driver Labels Options IPAMOptions Created Internal IPv6Enabled DNSEnabled NetworkInterface Subnets}
122
+ parse_json_command(labels, "network ls --no-trunc")
123
+ end
124
+
125
+ # Calls the run_command method to get all podman pod list and parse the command output.
126
+ # Returns the parsed command output.
127
+ def parse_pods
128
+ sub_cmd = "pod ps --no-trunc --format json"
129
+ output = run_command(sub_cmd)
130
+ parse(output)
131
+ end
132
+
133
+ # Calls the run_command method to get all podman volume list and parse the command output.
134
+ # Returns the parsed command output.
135
+ def parse_volumes
136
+ sub_cmd = "volume ls --format json"
137
+ output = run_command(sub_cmd)
138
+ parse(output)
139
+ end
140
+
141
+ # Runs the given podman command on the host machine on which podman is installed
142
+ # Returns the command output or raises the command execution error.
143
+ def run_command(subcommand)
144
+ result = inspec.command("podman #{subcommand}")
145
+ if result.stderr.empty?
146
+ result.stdout
147
+ else
148
+ raise "Error while running command \'podman #{subcommand}\' : #{result.stderr}"
149
+ end
150
+ end
151
+
152
+ def parse_json_command(labels, subcommand)
153
+ # build command
154
+ format = labels.map { |label| "\"#{label}\": {{json .#{label}}}" }
155
+ raw = inspec.command("podman #{subcommand} --format '{#{format.join(", ")}}'").stdout
156
+ output = []
157
+
158
+ raw.each_line do |entry|
159
+ # convert all keys to lower_case to work well with ruby and filter table
160
+ row = JSON.parse(entry).map do |key, value|
161
+ [key.downcase, value]
162
+ end.to_h
163
+
164
+ # ensure all keys are there
165
+ row = ensure_keys(row, labels)
166
+ output.push(row)
167
+ end
168
+
169
+ output
170
+ rescue JSON::ParserError => _e
171
+ warn "Could not parse `podman #{subcommand}` output"
172
+ []
173
+ end
174
+
175
+ def ensure_keys(entry, labels)
176
+ labels.each do |key|
177
+ entry[key.downcase] = nil unless entry.key?(key.downcase)
178
+ end
179
+ entry
180
+ end
181
+
182
+ # Method to parse JDON content.
183
+ # Returns: Parsed data.
184
+ def parse(content)
185
+ require "json" unless defined?(JSON)
186
+ output = JSON.parse(content)
187
+ parsed_output = []
188
+ output.each do |entry|
189
+ entry = entry.map do |k, v|
190
+ [k.downcase, v]
191
+ end.to_h
192
+ parsed_output << entry
193
+ end
194
+ parsed_output
195
+ rescue => e
196
+ raise Inspec::Exceptions::ResourceFailed, "Unable to parse command JSON output: #{e.message}"
197
+ end
198
+ end
199
+
200
+ # class for podman.containers plural resource
201
+ class PodmanContainerFilter
202
+ filter = FilterTable.create
203
+ filter.register_custom_matcher(:exists?) { |x| !x.entries.empty? }
204
+ filter.register_column(:commands, field: "command")
205
+ .register_column(:ids, field: "id")
206
+ .register_column(:created_at, field: "createdat")
207
+ .register_column(:images, field: "image")
208
+ .register_column(:names, field: "names")
209
+ .register_column(:status, field: "status")
210
+ .register_column(:image_ids, field: "image_id")
211
+ .register_column(:labels, field: "labels", style: :simple)
212
+ .register_column(:mounts, field: "mounts")
213
+ .register_column(:networks, field: "networks")
214
+ .register_column(:pods, field: "pod")
215
+ .register_column(:ports, field: "ports")
216
+ .register_column(:sizes, field: "size")
217
+ .register_column(:running_for, field: "running_for")
218
+ .register_custom_matcher(:running?) do |x|
219
+ x.where { status.downcase.start_with?("up") }
220
+ end
221
+ filter.install_filter_methods_on_resource(self, :containers)
222
+
223
+ attr_reader :containers
224
+ def initialize(containers)
225
+ @containers = containers
226
+ end
227
+
228
+ def to_s
229
+ "Podman Containers"
230
+ end
231
+
232
+ def resource_id
233
+ "Podman Containers"
234
+ end
235
+ end
236
+
237
+ # class for podman.images plural resource
238
+ class PodmanImageFilter
239
+ filter = FilterTable.create
240
+ filter.register_custom_matcher(:exists?) { |x| !x.entries.empty? }
241
+ filter.register_column(:ids, field: "id")
242
+ .register_column(:repositories, field: "repository")
243
+ .register_column(:tags, field: "tag")
244
+ .register_column(:sizes, field: "size")
245
+ .register_column(:digests, field: "digest")
246
+ .register_column(:created_at, field: "createdat")
247
+ .register_column(:created_since, field: "createdsince")
248
+ .register_column(:history, field: "history")
249
+ filter.install_filter_methods_on_resource(self, :images)
250
+
251
+ attr_reader :images
252
+ def initialize(images)
253
+ @images = images
254
+ end
255
+
256
+ def to_s
257
+ "Podman Images"
258
+ end
259
+
260
+ def resource_id
261
+ "Podman Images"
262
+ end
263
+ end
264
+
265
+ class PodmanNetworkFilter
266
+ filter = FilterTable.create
267
+ filter.register_custom_matcher(:exists?) { |x| !x.entries.empty? }
268
+ .register_column(:ids, field: "id")
269
+ .register_column(:names, field: "name")
270
+ .register_column(:drivers, field: "driver")
271
+ .register_column(:network_interfaces, field: "networkinterface")
272
+ .register_column(:created, field: "created")
273
+ .register_column(:subnets, field: "subnets")
274
+ .register_column(:ipv6_enabled, field: "ipv6enabled")
275
+ .register_column(:internal, field: "internal")
276
+ .register_column(:dns_enabled, field: "dnsenabled")
277
+ .register_column(:ipam_options, field: "ipamoptions")
278
+ .register_column(:options, field: "options")
279
+ .register_column(:labels, field: "labels")
280
+ filter.install_filter_methods_on_resource(self, :networks)
281
+
282
+ attr_reader :networks
283
+ def initialize(networks)
284
+ @networks = networks
285
+ end
286
+
287
+ def to_s
288
+ "Podman Networks"
289
+ end
290
+
291
+ def resource_id
292
+ "Podman Networks"
293
+ end
294
+ end
295
+
296
+ class PodmanPodFilter
297
+ filter = FilterTable.create
298
+ filter.register_custom_matcher(:exists?) { |x| !x.entries.empty? }
299
+ .register_column(:ids, field: "id")
300
+ .register_column(:cgroups, field: "cgroup")
301
+ .register_column(:containers, field: "containers")
302
+ .register_column(:created, field: "created")
303
+ .register_column(:infraids, field: "infraid")
304
+ .register_column(:names, field: "name")
305
+ .register_column(:namespaces, field: "namespace")
306
+ .register_column(:networks, field: "networks")
307
+ .register_column(:status, field: "status")
308
+ .register_column(:labels, field: "labels")
309
+ filter.install_filter_methods_on_resource(self, :pods)
310
+
311
+ attr_reader :pods
312
+ def initialize(pods)
313
+ @pods = pods
314
+ end
315
+
316
+ def to_s
317
+ "Podman Pods"
318
+ end
319
+
320
+ def resource_id
321
+ "Podman Pods"
322
+ end
323
+ end
324
+
325
+ class PodmanVolumeFilter
326
+ filter = FilterTable.create
327
+ filter.register_custom_matcher(:exists?) { |x| !x.entries.empty? }
328
+ .register_column(:names, field: "name")
329
+ .register_column(:drivers, field: "driver")
330
+ .register_column(:mountpoints, field: "mountpoint")
331
+ .register_column(:createdat, field: "createdat")
332
+ .register_column(:labels, field: "labels")
333
+ .register_column(:scopes, field: "scope")
334
+ .register_column(:options, field: "options")
335
+ .register_column(:mountcount, field: "mountcount")
336
+ .register_column(:needscopyup, field: "needscopyup")
337
+ .register_column(:needschown, field: "needschown")
338
+ filter.install_filter_methods_on_resource(self, :volumes)
339
+
340
+ attr_reader :volumes
341
+ def initialize(volumes)
342
+ @volumes = volumes
343
+ end
344
+
345
+ def to_s
346
+ "Podman Volumes"
347
+ end
348
+
349
+ def resource_id
350
+ "Podman Volumes"
351
+ end
352
+ end
353
+ end
@@ -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