CHEF-15119 - Removes docker resources from core (#7170)

* Removes the docker resources from core as they will be distributed through gem as seprate resoource pack from InSpec 7 and onwards.

Signed-off-by: Vasu1105 <vjagdale@progress.com>

* Adds deprecation for docker resources

Signed-off-by: Vasu1105 <vjagdale@progress.com>

* Removed Documentation for docker resources from core

Signed-off-by: Vasu1105 <vjagdale@progress.com>

---------

Signed-off-by: Vasu1105 <vjagdale@progress.com>
This commit is contained in:
Vasundhara Jagdale 2024-11-12 10:11:47 +00:00 committed by GitHub
parent bf9a3c7e38
commit 7e4ef2fddf
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
29 changed files with 4 additions and 2424 deletions

View file

@ -1,234 +0,0 @@
+++
title = "docker resource"
draft = false
gh_repo = "inspec"
platform = "linux"
[menu]
[menu.inspec]
title = "docker"
identifier = "inspec/resources/os/docker.md docker resource"
parent = "inspec/resources/os"
+++
Use the `docker` Chef InSpec audit resource to test configuration data for the Docker daemon. It is a very comprehensive resource. See also: [docker_container](/inspec/resources/docker_container/) and [docker_image](/inspec/resources/docker_image/), too.
## Availability
### Install
{{< readfile file="content/inspec/reusable/md/inspec_installation.md" >}}
### Version
This resource first became available in v1.21.0 of InSpec.
## Syntax
A `docker` resource block allows you to write tests for many containers:
describe docker.containers do
its('images') { should_not include 'u12:latest' }
end
or:
describe docker.containers.where { names == 'flamboyant_allen' } do
it { should be_running }
end
where
- `.where()` may specify a specific item and value, to which the resource parameters are compared
- `commands`, `ids`, `images`, `labels`, `local_volumes`, `mounts`, `names`, `networks`, `ports`, `sizes` and `status` are valid parameters for `containers`
The `docker` resource block also declares allows you to write test for many images:
describe docker.images do
its('repositories') { should_not include 'insecure_image' }
end
or if you want to query specific images:
describe docker.images.where { repository == 'ubuntu' && tag == '12.04' } do
it { should_not exist }
end
where
- `.where()` may specify a specific filter and expected value, against which parameters are compared
## Examples
The following examples show how to use this Chef InSpec audit resource.
### Return all running containers
docker.containers.running?.ids.each do |id|
describe docker.object(id) do
its('State.Health.Status') { should eq 'healthy' }
end
end
### Verify a Docker Server and Client version
describe docker.version do
its('Server.Version') { should cmp >= '1.12'}
its('Client.Version') { should cmp >= '1.12'}
end
### Iterate over all containers to verify host configuration
docker.containers.ids.each do |id|
# call Docker inspect for a specific container id
describe docker.object(id) do
its(%w(HostConfig Privileged)) { should cmp false }
its(%w(HostConfig Privileged)) { should_not cmp true }
end
end
### Iterate over all images to verify the container was built without ADD instruction
docker.images.ids.each do |id|
describe command("docker history #{id}| grep 'ADD'") do
its('stdout') { should eq '' }
end
end
### Verify that health-checks are enabled for a container
describe docker.object('71b5df59442b') do
its(%w(Config Healthcheck)) { should_not eq nil }
end
## How to run the DevSec Docker baseline profile
There are two ways to run the `docker-baseline` profile to test Docker via the `docker` resource.
Clone the profile:
git clone https://github.com/dev-sec/cis-docker-benchmark.git
and then run:
inspec exec cis-docker-benchmark
Or execute the profile directly via URL:
inspec exec https://github.com/dev-sec/cis-docker-benchmark
## Resource Parameters
- `commands`, `ids`, `images`, `labels`, `local_volumes`, `mounts`, `names`, `networks`, `ports`, `sizes` and `status` are valid parameters for `containers`
## Resource Parameter Examples
### containers
`containers` returns information about containers as returned by [docker ps -a](https://docs.docker.com/engine/reference/commandline/ps/).
describe docker.containers do
its('ids') { should include 'sha:71b5df59...442b' }
its('commands') { should_not include '/bin/sh' }
its('images') { should_not include 'u12:latest' }
its('ports') { should include '0.0.0.0:1234->1234/tcp' }
its('labels') { should include 'License=GPLv2' }
end
### object('id')
`object` returns low-level information about Docker objects. It is calling [docker inspect](https://docs.docker.com/engine/reference/commandline/info/) under the hood.
describe docker.object(id) do
its('Configuration.Path') { should eq 'value' }
end
### images
`images` returns information about a Docker image as returned by [docker images](https://docs.docker.com/engine/reference/commandline/images/).
describe docker.images do
its('ids') { should include 'sha:12b5df59...442b' }
its('repositories') { should_not include 'my_image' }
its('tags') { should_not include 'unwanted_tag' }
its('sizes') { should_not include '1.41 GB' }
end
### plugins
`plugins` returns information about Docker plugins as returned by [docker plugin ls](https://docs.docker.com/engine/reference/commandline/plugin/).
describe docker.plugins do
its('names') { should include ['store/weaveworks/net-plugin', 'docker4x/cloudstor'] }
its('ids') { should cmp ['6ea8176de74b', '771d3ee7c7ea'] }
its('versions') { should cmp ['2.3.0', '18.03.1-ce-aws1'] }
its('enabled') { should cmp [true, false] }
end
### info
`info` returns the parsed result of [docker info](https://docs.docker.com/engine/reference/commandline/info/)
describe docker.info do
its('Configuration.Path') { should eq 'value' }
end
### version
`info` returns the parsed result of [docker version](https://docs.docker.com/engine/reference/commandline/version/)
describe docker.version do
its('Server.Version') { should cmp >= '1.12'}
its('Client.Version') { should cmp >= '1.12'}
end
## Properties
- `id`
- `image`
- `repo`
- `tag`
- `ports`
- `command`
## Property Examples
### id
describe docker_container(name: 'an-echo-server') do
its('id') { should_not eq '' }
end
### image
describe docker_container(name: 'an-echo-server') do
its('image') { should eq 'busybox:latest' }
end
### repo
describe docker_container(name: 'an-echo-server') do
its('repo') { should eq 'busybox' }
end
### tag
describe docker_container(name: 'an-echo-server') do
its('tag') { should eq 'latest' }
end
### ports
describe docker_container(name: 'an-echo-server') do
its('ports') { should eq '0.0.0.0:1234->1234/tcp' }
end
### command
describe docker_container(name: 'an-echo-server') do
its('command') { should eq 'nc -ll -p 1234 -e /bin/cat' }
end
## Matchers
{{< readfile file="content/inspec/reusable/md/inspec_matchers_link.md" >}}

View file

@ -1,157 +0,0 @@
+++
title = "docker_container resource"
draft = false
gh_repo = "inspec"
platform = "linux"
[menu]
[menu.inspec]
title = "docker_container"
identifier = "inspec/resources/os/docker_container.md docker_container resource"
parent = "inspec/resources/os"
+++
Use the `docker_container` Chef InSpec audit resource to test a Docker container.
## Availability
### Install
This resource is distributed with Chef InSpec.
### Version
This resource is available from the InSpec version 1.21.0.
## Syntax
A `docker_container` resource block declares the configuration data to be tested:
describe docker_container('container') do
it { should exist }
it { should be_running }
its('id') { should_not eq '' }
its('image') { should eq 'busybox:latest' }
its('repo') { should eq 'busybox' }
its('tag') { should eq 'latest' }
its('ports') { should eq [] }
its('command') { should eq 'nc -ll -p 1234 -e /bin/cat' }
end
## Resource Parameter Examples
### name
The container name can be provided with the `name` resource parameter.
describe docker_container(name: 'an-echo-server') do
it { should exist }
it { should be_running }
end
### container id
Alternatively, you can pass in the container id.
describe docker_container(id: '71b5df59442b') do
it { should exist }
it { should be_running }
end
## Property Examples
The following examples show how to use this Chef InSpec resource.
### id
The `id` property tests the container ID.
its('id') { should eq 'sha:71b5df59...442b' }
### Repo
The `repo` property tests the value of the image repository.
its('repo') { should eq 'REPO' }
### tag
The `tag` property tests the value of the image tag.
its('tag') { should eq 'LATEST' }
### ports
The `ports` property tests the value of the Docker ports.
its('ports') { should eq '0.0.0.0:1234->1234/tcp' }
### command
The `command` property tests the value of the container run command.
its('command') { should eq 'nc -ll -p 1234 -e /bin/cat' }
### Verify a running container
describe docker_container('an-echo-server') do
it { should exist }
it { should be_running }
its('id') { should_not eq '' }
its('image') { should eq 'busybox:latest' }
its('repo') { should eq 'busybox' }
its('tag') { should eq 'latest' }
its('ports') { should eq [] }
its('command') { should eq 'nc -ll -p 1234 -e /bin/cat' }
end
## Matchers
{{< readfile file="content/inspec/reusable/md/inspec_matchers_link.md" >}}
The specific matchers of this resource are: `exist`, `be_running`, `have_volume?`.
### exist
The `exist` matcher specifies if the container exists.
it { should exist }
### be_running
The `be_running` matcher checks if the container is running.
it { should be_running }
### have_volume?
The `have_volume?` matcher checks if the container has mounted volumes.
it { should have_volume?(destination_path_in_container, source_path_in_source) }
## Examples
The following examples show how to use this Chef InSpec audit resource.
### Ensures container exists
The below test passes if the container `wonderful_wozniak` exists as part of the Docker instances.
describe docker_container('wonderful_wozniak') do
it { should exist }
end
### Ensures container is in running status
The below test passes if the container `trusting_williams` exists as part of the Docker instances and the status is running.
describe docker_container('trusting_williams') do
it { should be_running }
end
### Ensures container has mounted volumes
The below test passes if the container `quizzical_williamson` exists as part of the Docker instances, the status is running, and has mounted volume on `/app` in the container from the source path of `/var/lib/docker/volumes/myvol2/_data`
describe docker_container('quizzical_williamson') do
it { should have_volume('/app', '/var/lib/docker/volumes/myvol2/_data') }
end

View file

@ -1,156 +0,0 @@
+++
title = "docker_image resource"
draft = false
gh_repo = "inspec"
platform = "linux"
[menu]
[menu.inspec]
title = "docker_image"
identifier = "inspec/resources/os/docker_image.md docker_image resource"
parent = "inspec/resources/os"
+++
Use the `docker_image` Chef InSpec audit resource to verify a Docker image. A Docker Image is a template that contains the application and all the dependencies required to run an application on Docker.
## Availability
### Install
This resource is distributed with Chef InSpec.
### Version
This resource is available from the InSpec version, 1.21.0.
## Syntax
A `docker_image` resource block declares the image.
describe docker_image('ALPINE:LATEST') do
it { should exist }
its('id') { should eq 'sha256:4a415e...a526' }
its('repo') { should eq 'ALPINE' }
its('tag') { should eq 'LATEST' }
end
### Resource Parameter Examples
The resource allows you to pass with an image ID.
describe docker_image(id: ID) do
...
end
If the tag is missing for an image, `LATEST` is assumed as default.
describe docker_image('ALPINE') do
...
end
You can also pass the repository and tag values as separate values.
describe docker_image(repo: 'ALPINE', tag: 'LATEST') do
...
end
## Properties
### id
The `id` property returns the full image ID.
its('id') { should eq 'sha256:4a415e3663882fbc554ee830889c68a33b3585503892cc718a4698e91ef2a526' }
### image
The `image` property tests the value of the image. It is a combination of `repository/tag`.
its('image') { should eq 'ALPINE:LATEST' }
### repo
The `repo` property tests the value of the repository name.
its('repo') { should eq 'ALPINE' }
### tag
The `tag` property tests the value of the image tag.
its('tag') { should eq 'LATEST' }
### Low-level information of docker image as docker_image's property
#### inspection
The property allows testing the low-level information of docker image returned by `docker inspect [docker_image]`. Use hash format `'key' => 'value` for testing the information.
its(:inspection) { should include "Key" => "Value" }
its(:inspection) { should include "Key" =>
{
"SubKey" => "Value1",
"SubKey" => "Value2"
}
}
Additionally, all keys of the low-level information are valid properties and can be passed in three ways when writing the test.
- Serverspec's syntax
its(['key']) { should eq some_value }
its(['key1.key2.key3']) { should include some_value }
- InSpec's syntax
its(['key']) { should eq some_value }
its(['key1', 'key2', 'key3']) { should include some_value }
- Combination of Serverspec and InSpec
its(['key1.key2', 'key3']) { should include some_value }
## Matchers
{{< readfile file="content/inspec/reusable/md/inspec_matchers_link.md" >}}
This resource has the following special matchers.
### exist
The `exist` matcher tests if the image is available on the node.
it { should exist }
## Examples
### Test if a docker image exists and verifies the image properties: ID, image, repo, and tag
describe docker_image('ALPINE:LATEST') do
it { should exist }
its('id') { should eq 'sha256:4a415e...a526' }
its('image') { should eq 'ALPINE:LATEST' }
its('repo') { should eq 'ALPINE' }
its('tag') { should eq 'LATEST' }
end
### Test if a docker image exists and verifies the low-level information: Architecture, Config.Cmd, and GraphDriver
describe docker_image('ubuntu:latest') do
it { should exist }
its(['Architecture']) { should eq 'ARM64' }
its(['Config.Cmd']) { should include 'BASH' }
its(['GraphDriver.Data.MergedDir']) { should include "/var/lib/docker/overlay2/4336ba2a87c8d82abaa9ee5afd3ac20ea275bf05502d74d8d8396f8f51a4736c/merged" }
its(:inspection) { should include 'Architecture' => 'ARM64' }
its(:inspection) { should_not include 'Architecture' => 'i386' }
its(:inspection) { should include "GraphDriver" =>
{
"Data" => {
"MergedDir" => "/var/lib/docker/overlay2/4336ba2a87c8d82abaa9ee5afd3ac20ea275bf05502d74d8d8396f8f51a4736c/merged",
"UpperDir" => "/var/lib/docker/overlay2/4336ba2a87c8d82abaa9ee5afd3ac20ea275bf05502d74d8d8396f8f51a4736c/diff",
"WorkDir"=> "/var/lib/docker/overlay2/4336ba2a87c8d82abaa9ee5afd3ac20ea275bf05502d74d8d8396f8f51a4736c/work"
},
"Name" => "overlay2"
}
}
end

View file

@ -1,74 +0,0 @@
+++
title = "docker_plugin resource"
draft = false
gh_repo = "inspec"
platform = "linux"
[menu]
[menu.inspec]
title = "docker_plugin"
identifier = "inspec/resources/os/docker_plugin.md docker_plugin resource"
parent = "inspec/resources/os"
+++
Use the `docker_plugin` Chef InSpec audit resource to verify a Docker plugin.
## Syntax
A `docker_plugin` resource block declares the plugin:
describe docker_plugin('rexray/ebs') do
it { should exist }
its('id') { should_not eq '0ac30b93ad40' }
its('version') { should eq '0.11.1' }
it { should be_enabled }
end
## Resource Parameter Examples
The resource allows you to pass in an plugin id:
describe docker_plugin(id: plugin_id) do
it { should be_enabled }
end
## Properties
### id
The `id` property returns the full plugin id:
its('id') { should eq '0ac30b93ad40' }
### version
The `version` property tests the value of plugin version:
its('version') { should eq '0.11.0' }
## Examples
### Test a Docker plugin
describe docker_plugin('rexray/ebs') do
it { should exist }
its('id') { should_not eq '0ac30b93ad40' }
its('version') { should eq '0.11.1' }
it { should be_enabled }
end
## Matchers
For a full list of available matchers, please visit our [Universal Matchers](/inspec/matchers/).
### exist
The `exist` matcher tests if the plugin is available on the node:
describe docker_plugin('rexray/ebs') do
it { should exist }
end
### enabled
The `be_enabled` matches tests if the plugin is enabled

View file

@ -1,122 +0,0 @@
+++
title = "docker_service resource"
draft = false
gh_repo = "inspec"
platform = "linux"
[menu]
[menu.inspec]
title = "docker_service"
identifier = "inspec/resources/os/docker_service.md docker_service resource"
parent = "inspec/resources/os"
+++
Use the `docker_service` Chef InSpec audit resource to verify a docker swarm service.
## Availability
### Install
{{< readfile file="content/inspec/reusable/md/inspec_installation.md" >}}
### Version
This resource first became available in v1.51.0 of InSpec.
## Syntax
A `docker_service` resource block declares the service by name:
describe docker_service('foo') do
it { should exist }
its('id') { should eq 'docker-service-id' }
its('repo') { should eq 'alpine' }
its('tag') { should eq 'latest' }
end
## Resource Parameter Examples
The resource allows you to pass in a service id:
describe docker_service(id: 'docker-service-id') do
...
end
You can also pass in the fully-qualified image:
describe docker_service(image: 'localhost:5000/alpine:latest') do
...
end
## Property Examples
The following examples show how to use Chef InSpec `docker_service` resource.
### id
The `id` property returns the service id:
its('id') { should eq 'docker-service-id' }
### image
The `image` property is a combination of `repository:tag` it tests the value of the image:
its('image') { should eq 'alpine:latest' }
### mode
The `mode` property tests the value of the service mode:
its('mode') { should eq 'replicated' }
### name
The `name` property tests the value of the service name:
its('name') { should eq 'foo' }
### ports
The `ports` property tests the value of the service's published ports:
its('ports') { should include '*:8000->8000/tcp' }
### repo
The `repo` property tests the value of the repository name:
its('repo') { should eq 'alpine' }
### replicas
The `replicas` property tests the value of the service's replica count:
its('replicas') { should eq '3/3' }
### tag
The `tag` property tests the value of image tag:
its('tag') { should eq 'latest' }
### Test a docker service
describe docker_service('foo') do
it { should exist }
its('id') { should eq 'docker-service-id' }
its('repo') { should eq 'alpine' }
its('tag') { should eq 'latest' }
end
## Matchers
{{< readfile file="content/inspec/reusable/md/inspec_matchers_link.md" >}}
This resource has the following special matchers.
### exist
The `exist` matcher tests if the image is available on the node:
it { should exist }

View file

@ -131,6 +131,10 @@
"internal_fallback_test.+":{
"gem":"inspec-test-resources",
"message":"The internal_fallback_test resource is a test resource used to exercise InSpec's ability to fallback on gem resource packs."
},
"docker.+":{
"gem": "inspec-docker-resources",
"message": "The Inspec docker resources are moved out of InSpec core and will be installed as gem"
}
}
}

View file

@ -30,11 +30,6 @@ require "inspec/resources/cron"
require "inspec/resources/timezone"
require "inspec/resources/dh_params"
require "inspec/resources/directory"
require "inspec/resources/docker"
require "inspec/resources/docker_container"
require "inspec/resources/docker_image"
require "inspec/resources/docker_plugin"
require "inspec/resources/docker_service"
require "inspec/resources/elasticsearch"
require "inspec/resources/etc_fstab"
require "inspec/resources/etc_group"

View file

@ -1,274 +0,0 @@
#
# Copyright 2017, Christoph Hartmann
#
require "inspec/resources/command"
require "inspec/utils/filter"
require "hashie/mash"
module Inspec::Resources
class DockerContainerFilter
# use filtertable for containers
filter = FilterTable.create
filter.register_custom_matcher(:exists?) { |x| !x.entries.empty? }
filter.register_column(:commands, field: "command")
.register_column(:ids, field: "id")
.register_column(:images, field: "image")
.register_column(:labels, field: "labels", style: :simple)
.register_column(:local_volumes, field: "localvolumes")
.register_column(:mounts, field: "mounts")
.register_column(:names, field: "names")
.register_column(:networks, field: "networks")
.register_column(:ports, field: "ports")
.register_column(:running_for, field: "runningfor")
.register_column(:sizes, field: "size")
.register_column(:status, field: "status")
.register_custom_matcher(:running?) do |x|
x.where { status.downcase.start_with?("up") }
end
filter.install_filter_methods_on_resource(self, :containers)
attr_reader :containers
def initialize(containers)
@containers = containers
end
end
class DockerImageFilter
filter = FilterTable.create
filter.register_custom_matcher(:exists?) { |x| !x.entries.empty? }
filter.register_column(:ids, field: "id")
.register_column(:repositories, field: "repository")
.register_column(:tags, field: "tag")
.register_column(:sizes, field: "size")
.register_column(:digests, field: "digest")
.register_column(:created, field: "createdat")
.register_column(:created_since, field: "createdsize")
filter.install_filter_methods_on_resource(self, :images)
attr_reader :images
def initialize(images)
@images = images
end
end
class DockerPluginFilter
filter = FilterTable.create
filter.add(:ids, field: "id")
.add(:names, field: "name")
.add(:versions, field: "version")
.add(:enabled, field: "enabled")
filter.connect(self, :plugins)
attr_reader :plugins
def initialize(plugins)
@plugins = plugins
end
end
class DockerServiceFilter
filter = FilterTable.create
filter.register_custom_matcher(:exists?) { |x| !x.entries.empty? }
filter.register_column(:ids, field: "id")
.register_column(:names, field: "name")
.register_column(:modes, field: "mode")
.register_column(:replicas, field: "replicas")
.register_column(:images, field: "image")
.register_column(:ports, field: "ports")
filter.install_filter_methods_on_resource(self, :services)
attr_reader :services
def initialize(services)
@services = services
end
end
# This resource helps to parse information from the docker host
# For compatability with Serverspec we also offer the following resouses:
# - docker_container
# - docker_image
class Docker < Inspec.resource(1)
name "docker"
supports platform: "unix"
desc "
A resource to retrieve information about docker
"
example <<~EXAMPLE
describe docker.containers do
its('images') { should_not include 'u12:latest' }
end
describe docker.images do
its('repositories') { should_not include 'inssecure_image' }
end
describe docker.plugins.where { name == 'rexray/ebs' } do
it { should exist }
end
describe docker.services do
its('images') { should_not include 'inssecure_image' }
end
describe docker.version do
its('Server.Version') { should cmp >= '1.12'}
its('Client.Version') { should cmp >= '1.12'}
end
describe docker.object(id) do
its('Configuration.Path') { should eq 'value' }
end
docker.containers.ids.each do |id|
# call docker inspect for a specific container id
describe docker.object(id) do
its(%w(HostConfig Privileged)) { should cmp false }
its(%w(HostConfig Privileged)) { should_not cmp true }
end
end
EXAMPLE
def containers
DockerContainerFilter.new(parse_containers)
end
def images
DockerImageFilter.new(parse_images)
end
def plugins
DockerPluginFilter.new(parse_plugins)
end
def services
DockerServiceFilter.new(parse_services)
end
def version
return @version if defined?(@version)
data = {}
cmd = inspec.command("docker version --format '{{ json . }}'")
data = JSON.parse(cmd.stdout) if cmd.exit_status == 0
@version = Hashie::Mash.new(data)
rescue JSON::ParserError => _e
Hashie::Mash.new({})
end
def info
return @info if defined?(@info)
data = {}
# docke info format is only supported for Docker 17.03+
cmd = inspec.command("docker info --format '{{ json . }}'")
data = JSON.parse(cmd.stdout) if cmd.exit_status == 0
@info = Hashie::Mash.new(data)
rescue JSON::ParserError => _e
Hashie::Mash.new({})
end
# returns information about docker objects
def object(id)
return @inspect if defined?(@inspect)
data = JSON.parse(inspec.command("docker inspect #{id}").stdout)
data = data[0] if data.is_a?(Array)
@inspect = Hashie::Mash.new(data)
rescue JSON::ParserError => _e
Hashie::Mash.new({})
end
def to_s
"Docker Host"
end
private
def parse_json_command(labels, subcommand)
# build command
format = labels.map { |label| "\"#{label}\": {{json .#{label}}}" }
raw = inspec.command("docker #{subcommand} --format '{#{format.join(", ")}}'").stdout
output = []
# since docker is not outputting valid json, we need to parse each row
raw.each_line do |entry|
# convert all keys to lower_case to work well with ruby and filter table
row = JSON.parse(entry).map do |key, value|
[key.downcase, value]
end.to_h
# ensure all keys are there
row = ensure_keys(row, labels)
# strip off any linked container names
# Depending on how it was linked, the actual container name may come before
# or after the link information, so we'll just look for the first name that
# does not include a slash since that is not a valid character in a container name
if row["names"]
row["names"] = row["names"].split(",").find { |c| !c.include?("/") }
end
# Split labels on ',' or set to empty array
# Allows for `docker.containers.where { labels.include?('app=redis') }`
row["labels"] = row.key?("labels") ? row["labels"].split(",") : []
output.push(row)
end
output
rescue JSON::ParserError => _e
warn "Could not parse `docker #{subcommand}` output"
[]
end
def parse_containers
# @see https://github.com/moby/moby/issues/20625, works for docker 1.13+
# raw_containers = inspec.command('docker ps -a --no-trunc --format \'{{ json . }}\'').stdout
# therefore we stick with older approach
labels = %w{Command CreatedAt ID Image Labels Mounts Names Ports RunningFor Size Status}
# Networks LocalVolumes work with 1.13+ only
if !version.empty? && Gem::Version.new(version["Client"]["Version"]) >= Gem::Version.new("1.13")
labels.push("Networks")
labels.push("LocalVolumes")
end
parse_json_command(labels, "ps -a --no-trunc")
end
def parse_services
parse_json_command(%w{ID Name Mode Replicas Image Ports}, "service ls")
end
def ensure_keys(entry, labels)
labels.each do |key|
entry[key.downcase] = nil unless entry.key?(key.downcase)
end
entry
end
def parse_images
# docker does not support the `json .` function here, therefore we need to emulate that behavior.
raw_images = inspec.command('docker images -a --no-trunc --format \'{ "id": {{json .ID}}, "repository": {{json .Repository}}, "tag": {{json .Tag}}, "size": {{json .Size}}, "digest": {{json .Digest}}, "createdat": {{json .CreatedAt}}, "createdsize": {{json .CreatedSince}} }\'').stdout
c_images = []
raw_images.each_line do |entry|
c_images.push(JSON.parse(entry))
end
c_images
rescue JSON::ParserError => _e
warn "Could not parse `docker images` output"
[]
end
def parse_plugins
plugins = inspec.command('docker plugin ls --format \'{"id": {{json .ID}}, "name": "{{ with split .Name ":"}}{{index . 0}}{{end}}", "version": "{{ with split .Name ":"}}{{index . 1}}{{end}}", "enabled": {{json .Enabled}} }\'').stdout
c_plugins = []
plugins.each_line do |entry|
c_plugins.push(JSON.parse(entry))
end
c_plugins
rescue JSON::ParserError => _e
warn "Could not parse `docker plugin ls` output"
[]
end
end
end

View file

@ -1,116 +0,0 @@
#
# Copyright 2017, Christoph Hartmann
require "inspec/resources/docker"
require_relative "docker_object"
module Inspec::Resources
class DockerContainer < Inspec.resource(1)
include Inspec::Resources::DockerObject
name "docker_container"
supports platform: "unix"
desc ""
example <<~EXAMPLE
describe docker_container('an-echo-server') do
it { should exist }
it { should be_running }
its('id') { should_not eq '' }
its('image') { should eq 'busybox:latest' }
its('repo') { should eq 'busybox' }
its('tag') { should eq 'latest' }
its('ports') { should eq [] }
its('command') { should eq 'nc -ll -p 1234 -e /bin/cat' }
its('labels') { should include 'app=example' }
end
describe docker_container(id: 'e2c52a183358') do
it { should exist }
it { should be_running }
end
EXAMPLE
def initialize(opts = {})
# if a string is provided, we expect it is the name
if opts.is_a?(String)
@opts = { name: opts }
else
@opts = opts
end
end
def running?
status.downcase.start_with?("up") if object_info.entries.length == 1
end
# has_volume? matcher checks if the volume specified in source path of host is mounted in destination path of docker
def has_volume?(destination, source)
# volume_info is the hash which contains the low-level information about the container
# if Mounts key is not present or is nil; raise exception
raise Inspec::Exceptions::ResourceFailed, "Could not find any mounted volumes for your container" unless volume_info.Mounts[0]
# Iterate through the list of mounted volumes and check if it matches with the given destination and source
# is_mounted flag is used to handle to return explict boolean values of true or false
is_mounted = false
volume_info.Mounts.detect { |mount| is_mounted = mount.Destination == destination && mount.Source == source }
is_mounted
end
def status
object_info.status[0] if object_info.entries.length == 1
end
def labels
object_info.labels
end
def ports
object_info.ports[0] if object_info.entries.length == 1
end
def command
return unless object_info.entries.length == 1
cmd = object_info.commands[0]
cmd.slice(1, cmd.length - 2)
end
def image
object_info.images[0] if object_info.entries.length == 1
end
def repo
parse_components_from_image(image)[:repo] if object_info.entries.size == 1
end
def tag
parse_components_from_image(image)[:tag] if object_info.entries.size == 1
end
def to_s
name = @opts[:name] || @opts[:id]
"Docker Container #{name}"
end
def resource_id
object_info.ids[0] || @opts[:id] || @opts[:name] || ""
end
private
def object_info
return @info if defined?(@info)
opts = @opts
@info = inspec.docker.containers.where { names == opts[:name] || (!id.nil? && !opts[:id].nil? && (id == opts[:id] || id.start_with?(opts[:id]))) }
end
# volume_info returns the low-level information obtained on docker inspect [container_name/id]
def volume_info
return @mount_info if defined?(@mount_info)
# Check for either docker inspect [container_name] or docker inspect [container_id]
@mount_info = inspec.docker.object(@opts[:name] || @opts[:id])
end
end
end

View file

@ -1,141 +0,0 @@
#
# Copyright 2017, Christoph Hartmann
require "inspec/resources/docker"
require_relative "docker_object"
module Inspec::Resources
class DockerImage < Inspec.resource(1)
include Inspec::Resources::DockerObject
name "docker_image"
supports platform: "unix"
desc ""
example <<~EXAMPLE
describe docker_image('alpine:latest') do
it { should exist }
its('id') { should_not eq '' }
its('image') { should eq 'alpine:latest' }
its('repo') { should eq 'alpine' }
its('tag') { should eq 'latest' }
end
describe docker_image('alpine:latest') do
it { should exist }
end
describe docker_image(id: '4a415e366388') do
it { should exist }
end
EXAMPLE
def initialize(opts = {})
# do sanitizion of input values
o = opts.dup
o = { image: opts } if opts.is_a?(String)
@opts = sanitize_options(o)
end
def image
"#{repo}:#{tag}" if object_info.entries.size == 1
end
def repo
object_info.repositories[0] if object_info.entries.size == 1
end
def tag
object_info.tags[0] if object_info.entries.size == 1
end
# method_missing handles when hash_keys are invoked to check information obtained on docker inspect [image_name]
def method_missing(*hash_keys)
# User can test the low-level inspect information in three ways:
# Way 1: Serverspec style: its(['Config.Cmd']) { should include some_value }
# here, the value for hash_keys recieved is [:[], "Config.Cmd"]
# Way 2: InSpec style: its(['Config','Cmd']) { should include some_value }
# here, the value for hash_keys recieved is [:[], "Config", "Cmd"]
# Way 3: Mix of both: its(['GraphDriver.Data','MergedDir']) { should include some_value }
# here, the value for hash_keys recieved is [:[], "GraphDriver.Data", "MergedDir"]
# hash_keys are passed to this method to evaluate the value
image_hash_inspection(hash_keys)
end
# inspection property allows to test any of the hash key-value pairs as part of the image_inspect_info
def inspection
image_inspect_info
end
def to_s
img = @opts[:image] || @opts[:id]
"Docker Image #{img}"
end
def resource_id
object_info.ids[0] || @opts[:id] || @opts[:image] || ""
end
private
def sanitize_options(opts)
opts.merge!(parse_components_from_image(opts[:image]))
# assume a "latest" tag if we don't have one
opts[:tag] ||= "latest"
# if the ID isn't nil and doesn't contain a hash indicator (indicated by the presence
# of a colon, which separates the indicator from the actual hash), we assume it's sha256.
opts[:id] = "sha256:" + opts[:id] unless opts[:id].nil? || opts[:id].include?(":")
# Assemble/reassemble the image from the repo and tag
opts[:image] = "#{opts[:repo]}:#{opts[:tag]}" unless opts[:repo].nil?
# return the santized opts back to the caller
opts
end
def object_info
return @info if defined?(@info)
opts = @opts
@info = inspec.docker.images.where do
(repository == opts[:repo] && tag == opts[:tag]) || (!id.nil? && !opts[:id].nil? && (id == opts[:id] || id.start_with?(opts[:id])))
end
end
# image_inspect_info returns the complete inspect hash_values of the image
def image_inspect_info
return @inspect_info if defined?(@inspect_info)
@inspect_info = inspec.docker.object(@opts[:image] || (!@opts[:id].nil? && @opts[:id]))
end
# image_hash_inspection formats the input hash_keys and checks if any value exists for such keys in @inspect_info(image_inspect_info)
def image_hash_inspection(hash_keys)
# The hash_keys recieved are in three formats as mentioned in method_missing
# The hash_keys recieved must be in array format [] and the zeroth index must be :[]
# Check for the conditions and remove the zeroth element from the hash_keys
hash_keys.shift if hash_keys.is_a?(Array) && hash_keys[0] == :[]
# When received hash_keys in Serverspec style or mix of both
# The hash_keys are to be splitted at '.' (dot) and flatten it so that it doesn't become array of arrays
# After splitting and flattening is done, hash_keys is now an array with individual keys
hash_keys = hash_keys.map { |key| key.split(".") }.flatten
# image_inspect_info returns the complete inspect hash_values of the image
# dig() finds the nested value specified by the sequence of the key object by calling dig at each step.
# hash_keys is the key object. If one of the key is bad, value will be nil.
hash_value = image_inspect_info.dig(*hash_keys)
# If one of the key is bad, hash_value will be nil, so raise exception which throws it in rescue block
# else return hash_value
raise Inspec::Exceptions::ResourceFailed if hash_value.nil?
hash_value
rescue
raise Inspec::Exceptions::ResourceFailed, "#{hash_keys.join(".")} is not a valid key for your image or has nil value."
end
end
end

View file

@ -1,52 +0,0 @@
#
# Copyright 2017, Christoph Hartmann
#
module Inspec::Resources::DockerObject
def exist?
object_info.exists?
end
def id
object_info.ids[0] if object_info.entries.size == 1
end
private
def parse_components_from_image(image_string)
# if the user did not supply an image string, they likely supplied individual
# option parameters, such as repo and tag. Return empty data back to the caller.
return {} if image_string.nil?
first_colon = image_string.index(":") || -1
first_slash = image_string.index("/") || -1
if image_string.count(":") == 2
# If there are two colons in the image string, it contains a repo-with-port and a tag.
# example: localhost:5000/chef/inspec:1.46.3
partitioned_string = image_string.rpartition(":")
repo = partitioned_string.first
tag = partitioned_string.last
image_name = repo.split("/")[1..-1].join
elsif image_string.count(":") == 1 && first_colon < first_slash
# If there's one colon in the image string, and it comes before a forward-slash,
# it contains a repo-with-port but no tag.
# example: localhost:5000/ubuntu
repo = image_string
tag = nil
image_name = repo.split("/")[1..-1].join
else
# If there's one colon in the image string and it doesn't preceed a slash, or if
# there is no colon at all, then it separates the repo from the tag, if there is a tag.
# example: chef/inspec:1.46.3
# example: chef/inspec
# example: ubuntu:14.04
repo, tag = image_string.split(":")
image_name = repo
end
# return the repo, image_name and tag parsed from the string, which can be merged into
# the rest of the user-supplied options
{ repo: repo, image_name: image_name, tag: tag }
end
end

View file

@ -1,68 +0,0 @@
require "inspec/resources/docker"
module Inspec::Resources
class DockerPlugin < Inspec.resource(1)
name "docker_plugin"
supports platform: "unix"
desc "Retrieves info about docker plugins"
example <<~EXAMPLE
describe docker_plugin('rexray/ebs') do
it { should exist }
its('id') { should_not eq '0ac30b93ad40' }
its('version') { should eq '0.11.1' }
it { should be_enabled }
end
describe docker_plugin('alpine:latest') do
it { should exist }
end
describe docker_plugin(id: '4a415e366388') do
it { should exist }
end
EXAMPLE
def initialize(opts = {})
# do sanitizion of input values
o = opts.dup
o = { name: opts } if opts.is_a?(String)
@opts = o
end
def exist?
object_info.entries.size == 1
end
def enabled?
object_info.enabled[0]
end
def id
object_info.ids[0] if object_info.entries.size == 1
end
def version
object_info.versions[0] if object_info.entries.size == 1
end
def to_s
plugin = @opts[:name] || @opts[:id]
"Docker plugin #{plugin}"
end
def resource_id
id || @opts[:id] || @opts[:name] || ""
end
private
def object_info
return @info if defined?(@info)
opts = @opts
@info = inspec.docker.plugins.where do
(name == opts[:name]) || (!id.nil? && !opts[:id].nil? && (id == opts[:id]))
end
end
end
end

View file

@ -1,95 +0,0 @@
#
# Copyright 2017, Christoph Hartmann
require "inspec/resources/docker"
require_relative "docker_object"
module Inspec::Resources
class DockerService < Inspec.resource(1)
include Inspec::Resources::DockerObject
name "docker_service"
supports platform: "unix"
desc "Swarm-mode service"
example <<~EXAMPLE
describe docker_service('service1') do
it { should exist }
its('id') { should_not eq '' }
its('image') { should eq 'alpine:latest' }
its('repo') { should eq 'alpine' }
its('tag') { should eq 'latest' }
end
describe docker_service(id: '4a415e366388') do
it { should exist }
end
describe docker_service(image: 'alpine:latest') do
it { should exist }
end
EXAMPLE
def initialize(opts = {})
# do sanitizion of input values
o = opts.dup
o = { name: opts } if opts.is_a?(String)
@opts = sanitize_options(o)
end
def name
object_info.names[0] if object_info.entries.size == 1
end
def image
object_info.images[0] if object_info.entries.size == 1
end
def image_name
parse_components_from_image(image)[:image_name] if object_info.entries.size == 1
end
def repo
parse_components_from_image(image)[:repo] if object_info.entries.size == 1
end
def tag
parse_components_from_image(image)[:tag] if object_info.entries.size == 1
end
def mode
object_info.modes[0] if object_info.entries.size == 1
end
def replicas
object_info.replicas[0] if object_info.entries.size == 1
end
def ports
object_info.ports[0] if object_info.entries.size == 1
end
def to_s
service = @opts[:name] || @opts[:id]
"Docker Service #{service}"
end
def resource_id
object_info.ids[0] || @opts[:id] || @opts[:name] || ""
end
private
def sanitize_options(opts)
opts.merge(parse_components_from_image(opts[:image]))
end
def object_info
return @info if defined?(@info)
opts = @opts
@info = inspec.docker.services.where do
name == opts[:name] || image == opts[:image] || (!id.nil? && !opts[:id].nil? && (id == opts[:id] || id.start_with?(opts[:id])))
end
end
end
end

View file

@ -1,4 +0,0 @@
{ "id": "sha256:4a415e3663882fbc554ee830889c68a33b3585503892cc718a4698e91ef2a526", "repository": "alpine", "tag": "latest", "size": "3.99 MB", "digest": "\u003cnone\u003e", "createdat": "2017-03-03 21:32:37 +0100 CET", "createdsize": "7 weeks" }
{ "id": "sha256:978d85d02b87aea199e4ae8664f6abf32fdea331884818e46b8a01106b114cee", "repository": "debian", "tag": "8", "size": "123 MB", "digest": "\u003cnone\u003e", "createdat": "2017-02-27 21:34:37 +0100 CET", "createdsize": "7 weeks" }
{ "id": "sha256:0ef2e08ed3fabfc44002ccb846c4f2416a2135affc3ce39538834059606f32dd", "repository": "ubuntu", "tag": "16.04", "size": "130 MB", "digest": "\u003cnone\u003e", "createdat": "2017-02-27 20:42:10 +0100 CET", "createdsize": "7 weeks" }
{ "id": "sha256:c4e5744dbe11a4f1970ba36d0aa3944c347ab232bb58fb86b240f1bb18a360c2", "repository": "repo.example.com:5000/ubuntu", "tag": "14.04", "size": "125 MB", "digest": "\u003cnone\u003e", "createdat": "2017-02-27 20:42:10 +0100 CET", "createdsize": "7 weeks" }

View file

@ -1,10 +0,0 @@
{
"ID": "HMKB:SOFR:Z3DM:J6ZY:WE6K:47EW:WVGV:C5C3:WNJC:TSG6:43YV:IOGU",
"Containers": 93,
"Runtimes": {
"runc": {
"path": "docker-runc"
}
},
"SecurityOptions": ["name=seccomp,profile=default"]
}

View file

@ -1,7 +0,0 @@
[
{
"Id": "71b5df59442be8215902ce7804bfbb0ab5d8b8ddab7cef6e00224a8c1f476e38",
"Created": "2017-04-22T15:08:47.082154846Z",
"Path": "nginx"
}
]

View file

@ -1,243 +0,0 @@
[
{
"Id": "36a981f1ec0d3d1c7f7779671dc79e011f2bb691b6eeb2c43b05edee02b79539",
"Created": "2022-03-21T05:23:13.178761971Z",
"Path": "/docker-entrypoint.sh",
"Args": [
"nginx",
"-g",
"daemon off;"
],
"State": {
"Status": "running",
"Running": true,
"Paused": false,
"Restarting": false,
"OOMKilled": false,
"Dead": false,
"Pid": 2424,
"ExitCode": 0,
"Error": "",
"StartedAt": "2022-03-21T05:23:13.435779679Z",
"FinishedAt": "0001-01-01T00:00:00Z"
},
"Image": "sha256:4f6e44d5fceb133ca9d0e4baccaa2dfd721f2c5f951d1a28ca7fd4cf5f2b04a1",
"ResolvConfPath": "/var/lib/docker/containers/36a981f1ec0d3d1c7f7779671dc79e011f2bb691b6eeb2c43b05edee02b79539/resolv.conf",
"HostnamePath": "/var/lib/docker/containers/36a981f1ec0d3d1c7f7779671dc79e011f2bb691b6eeb2c43b05edee02b79539/hostname",
"HostsPath": "/var/lib/docker/containers/36a981f1ec0d3d1c7f7779671dc79e011f2bb691b6eeb2c43b05edee02b79539/hosts",
"LogPath": "/var/lib/docker/containers/36a981f1ec0d3d1c7f7779671dc79e011f2bb691b6eeb2c43b05edee02b79539/36a981f1ec0d3d1c7f7779671dc79e011f2bb691b6eeb2c43b05edee02b79539-json.log",
"Name": "/trusting_williams",
"RestartCount": 0,
"Driver": "overlay2",
"Platform": "linux",
"MountLabel": "",
"ProcessLabel": "",
"AppArmorProfile": "",
"ExecIDs": null,
"HostConfig": {
"Binds": null,
"ContainerIDFile": "",
"LogConfig": {
"Type": "json-file",
"Config": {}
},
"NetworkMode": "default",
"PortBindings": {},
"RestartPolicy": {
"Name": "no",
"MaximumRetryCount": 0
},
"AutoRemove": false,
"VolumeDriver": "",
"VolumesFrom": null,
"CapAdd": null,
"CapDrop": null,
"CgroupnsMode": "private",
"Dns": [],
"DnsOptions": [],
"DnsSearch": [],
"ExtraHosts": null,
"GroupAdd": null,
"IpcMode": "private",
"Cgroup": "",
"Links": null,
"OomScoreAdj": 0,
"PidMode": "",
"Privileged": false,
"PublishAllPorts": false,
"ReadonlyRootfs": false,
"SecurityOpt": null,
"UTSMode": "",
"UsernsMode": "",
"ShmSize": 67108864,
"Runtime": "runc",
"ConsoleSize": [
0,
0
],
"Isolation": "",
"CpuShares": 0,
"Memory": 0,
"NanoCpus": 0,
"CgroupParent": "",
"BlkioWeight": 0,
"BlkioWeightDevice": [],
"BlkioDeviceReadBps": null,
"BlkioDeviceWriteBps": null,
"BlkioDeviceReadIOps": null,
"BlkioDeviceWriteIOps": null,
"CpuPeriod": 0,
"CpuQuota": 0,
"CpuRealtimePeriod": 0,
"CpuRealtimeRuntime": 0,
"CpusetCpus": "",
"CpusetMems": "",
"Devices": [],
"DeviceCgroupRules": null,
"DeviceRequests": null,
"KernelMemory": 0,
"KernelMemoryTCP": 0,
"MemoryReservation": 0,
"MemorySwap": 0,
"MemorySwappiness": null,
"OomKillDisable": null,
"PidsLimit": null,
"Ulimits": null,
"CpuCount": 0,
"CpuPercent": 0,
"IOMaximumIOps": 0,
"IOMaximumBandwidth": 0,
"Mounts": [
{
"Type": "volume",
"Source": "myvol2",
"Target": "/app"
}
],
"MaskedPaths": [
"/proc/asound",
"/proc/acpi",
"/proc/kcore",
"/proc/keys",
"/proc/latency_stats",
"/proc/timer_list",
"/proc/timer_stats",
"/proc/sched_debug",
"/proc/scsi",
"/sys/firmware"
],
"ReadonlyPaths": [
"/proc/bus",
"/proc/fs",
"/proc/irq",
"/proc/sys",
"/proc/sysrq-trigger"
]
},
"GraphDriver": {
"Data": {
"LowerDir": "/var/lib/docker/overlay2/1424effcec0fdc7234402663637c2cbd466d84f30a2838b6be2c3f074d9ce2a9-init/diff:/var/lib/docker/overlay2/409f4ed0129c77297201c41fe3ededa514f4b7ee3a01324917cf81cdb227f8f4/diff:/var/lib/docker/overlay2/81db7ba78e6a85e259f501b6ef0199e1c2566bf0db45a159e8d94f7beb994ccf/diff:/var/lib/docker/overlay2/b1ba5f1241fa00ba1d93e8818109633c047b80388d9cea734ea360c4b06fd832/diff:/var/lib/docker/overlay2/c965bed4b998eba7c9a2ce1aef1592d5f290eccfe648e18ecb22ce259689b464/diff:/var/lib/docker/overlay2/873a23b96e84ccc65851bc82d541da545eded80455518069944b28828663845c/diff:/var/lib/docker/overlay2/e4b850cefce408a53da3a08276983ff227c2e020883ad41d6f363dfa96853893/diff",
"MergedDir": "/var/lib/docker/overlay2/1424effcec0fdc7234402663637c2cbd466d84f30a2838b6be2c3f074d9ce2a9/merged",
"UpperDir": "/var/lib/docker/overlay2/1424effcec0fdc7234402663637c2cbd466d84f30a2838b6be2c3f074d9ce2a9/diff",
"WorkDir": "/var/lib/docker/overlay2/1424effcec0fdc7234402663637c2cbd466d84f30a2838b6be2c3f074d9ce2a9/work"
},
"Name": "overlay2"
},
"Mounts": [
{
"Type": "volume",
"Name": "myvol2",
"Source": "/var/lib/docker/volumes/myvol2/_data",
"Destination": "/app",
"Driver": "local",
"Mode": "z",
"RW": true,
"Propagation": ""
},
{
"Type": "volume",
"Name": "myvol3",
"Source": "/var/lib/docker/volumes/myvol3/_data",
"Destination": "/app2",
"Driver": "local",
"Mode": "z",
"RW": true,
"Propagation": ""
}
],
"Config": {
"Hostname": "36a981f1ec0d",
"Domainname": "",
"User": "",
"AttachStdin": false,
"AttachStdout": false,
"AttachStderr": false,
"ExposedPorts": {
"80/tcp": {}
},
"Tty": false,
"OpenStdin": false,
"StdinOnce": false,
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
"NGINX_VERSION=1.21.6",
"NJS_VERSION=0.7.2",
"PKG_RELEASE=1~bullseye"
],
"Cmd": [
"nginx",
"-g",
"daemon off;"
],
"Image": "nginx:latest",
"Volumes": null,
"WorkingDir": "",
"Entrypoint": [
"/docker-entrypoint.sh"
],
"OnBuild": null,
"Labels": {
"maintainer": "NGINX Docker Maintainers \u003cdocker-maint@nginx.com\u003e"
},
"StopSignal": "SIGQUIT"
},
"NetworkSettings": {
"Bridge": "",
"SandboxID": "cd498ab32e4f029504a92da8a44822188857f98da6f0f54ea7dc087733b88f01",
"HairpinMode": false,
"LinkLocalIPv6Address": "",
"LinkLocalIPv6PrefixLen": 0,
"Ports": {
"80/tcp": null
},
"SandboxKey": "/var/run/docker/netns/cd498ab32e4f",
"SecondaryIPAddresses": null,
"SecondaryIPv6Addresses": null,
"EndpointID": "5b76a7779528d8ac8e222da8298e82136ca6928a5af1b5b1e731b7d01486fb3e",
"Gateway": "172.17.0.1",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"IPAddress": "172.17.0.4",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"MacAddress": "02:42:ac:11:00:04",
"Networks": {
"bridge": {
"IPAMConfig": null,
"Links": null,
"Aliases": null,
"NetworkID": "7507315d62a18bb05ad4e14dd6ecb5341d23884aa8cf919ad821ad1068d2ac8f",
"EndpointID": "5b76a7779528d8ac8e222da8298e82136ca6928a5af1b5b1e731b7d01486fb3e",
"Gateway": "172.17.0.1",
"IPAddress": "172.17.0.4",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"MacAddress": "02:42:ac:11:00:04",
"DriverOpts": null
}
}
}
}
]

View file

@ -1,196 +0,0 @@
[
{
"Id": "1870886821c3ccd63500f3437582021c6c97e427ca0d0fc4aa40d1d1f5936b22",
"Created": "2022-03-18T11:09:14.841566375Z",
"Path": "bash",
"Args": [],
"State": {
"Status": "running",
"Running": true,
"Paused": false,
"Restarting": false,
"OOMKilled": false,
"Dead": false,
"Pid": 2070,
"ExitCode": 0,
"Error": "",
"StartedAt": "2022-03-18T11:09:15.091396417Z",
"FinishedAt": "0001-01-01T00:00:00Z"
},
"Image": "sha256:a457a74c9aaabc62ddc119d2fb03ba6f58fa299bf766bd2411c159142b972c1d",
"ResolvConfPath": "/var/lib/docker/containers/1870886821c3ccd63500f3437582021c6c97e427ca0d0fc4aa40d1d1f5936b22/resolv.conf",
"HostnamePath": "/var/lib/docker/containers/1870886821c3ccd63500f3437582021c6c97e427ca0d0fc4aa40d1d1f5936b22/hostname",
"HostsPath": "/var/lib/docker/containers/1870886821c3ccd63500f3437582021c6c97e427ca0d0fc4aa40d1d1f5936b22/hosts",
"LogPath": "/var/lib/docker/containers/1870886821c3ccd63500f3437582021c6c97e427ca0d0fc4aa40d1d1f5936b22/1870886821c3ccd63500f3437582021c6c97e427ca0d0fc4aa40d1d1f5936b22-json.log",
"Name": "/fried_water",
"RestartCount": 0,
"Driver": "overlay2",
"Platform": "linux",
"MountLabel": "",
"ProcessLabel": "",
"AppArmorProfile": "",
"ExecIDs": null,
"HostConfig": {
"Binds": [],
"ContainerIDFile": "",
"LogConfig": {
"Type": "json-file",
"Config": {}
},
"NetworkMode": "default",
"PortBindings": {},
"RestartPolicy": {
"Name": "",
"MaximumRetryCount": 0
},
"AutoRemove": false,
"VolumeDriver": "",
"VolumesFrom": null,
"CapAdd": null,
"CapDrop": null,
"CgroupnsMode": "private",
"Dns": null,
"DnsOptions": null,
"DnsSearch": null,
"ExtraHosts": null,
"GroupAdd": null,
"IpcMode": "private",
"Cgroup": "",
"Links": null,
"OomScoreAdj": 0,
"PidMode": "",
"Privileged": false,
"PublishAllPorts": false,
"ReadonlyRootfs": false,
"SecurityOpt": null,
"UTSMode": "",
"UsernsMode": "",
"ShmSize": 67108864,
"Runtime": "runc",
"ConsoleSize": [
0,
0
],
"Isolation": "",
"CpuShares": 0,
"Memory": 0,
"NanoCpus": 0,
"CgroupParent": "",
"BlkioWeight": 0,
"BlkioWeightDevice": null,
"BlkioDeviceReadBps": null,
"BlkioDeviceWriteBps": null,
"BlkioDeviceReadIOps": null,
"BlkioDeviceWriteIOps": null,
"CpuPeriod": 0,
"CpuQuota": 0,
"CpuRealtimePeriod": 0,
"CpuRealtimeRuntime": 0,
"CpusetCpus": "",
"CpusetMems": "",
"Devices": null,
"DeviceCgroupRules": null,
"DeviceRequests": null,
"KernelMemory": 0,
"KernelMemoryTCP": 0,
"MemoryReservation": 0,
"MemorySwap": 0,
"MemorySwappiness": null,
"OomKillDisable": null,
"PidsLimit": null,
"Ulimits": null,
"CpuCount": 0,
"CpuPercent": 0,
"IOMaximumIOps": 0,
"IOMaximumBandwidth": 0,
"MaskedPaths": [
"/proc/asound",
"/proc/acpi",
"/proc/kcore",
"/proc/keys",
"/proc/latency_stats",
"/proc/timer_list",
"/proc/timer_stats",
"/proc/sched_debug",
"/proc/scsi",
"/sys/firmware"
],
"ReadonlyPaths": [
"/proc/bus",
"/proc/fs",
"/proc/irq",
"/proc/sys",
"/proc/sysrq-trigger"
]
},
"GraphDriver": {
"Data": {
"LowerDir": "/var/lib/docker/overlay2/97e77c7aa67c1cc7034d661e3c198f1c9c79b47cd56affa95172c7398f6b4aba-init/diff:/var/lib/docker/overlay2/4336ba2a87c8d82abaa9ee5afd3ac20ea275bf05502d74d8d8396f8f51a4736c/diff",
"MergedDir": "/var/lib/docker/overlay2/97e77c7aa67c1cc7034d661e3c198f1c9c79b47cd56affa95172c7398f6b4aba/merged",
"UpperDir": "/var/lib/docker/overlay2/97e77c7aa67c1cc7034d661e3c198f1c9c79b47cd56affa95172c7398f6b4aba/diff",
"WorkDir": "/var/lib/docker/overlay2/97e77c7aa67c1cc7034d661e3c198f1c9c79b47cd56affa95172c7398f6b4aba/work"
},
"Name": "overlay2"
},
"Mounts": [],
"Config": {
"Hostname": "1870886821c3",
"Domainname": "",
"User": "",
"AttachStdin": false,
"AttachStdout": true,
"AttachStderr": true,
"Tty": true,
"OpenStdin": false,
"StdinOnce": false,
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
],
"Cmd": [
"bash"
],
"Image": "ubuntu:latest",
"Volumes": null,
"WorkingDir": "",
"Entrypoint": null,
"OnBuild": null,
"Labels": {}
},
"NetworkSettings": {
"Bridge": "",
"SandboxID": "a5437c8af3fa5f6e70d58f5a054f5ebeeb882a251654647668fdd0f49336873d",
"HairpinMode": false,
"LinkLocalIPv6Address": "",
"LinkLocalIPv6PrefixLen": 0,
"Ports": {},
"SandboxKey": "/var/run/docker/netns/a5437c8af3fa",
"SecondaryIPAddresses": null,
"SecondaryIPv6Addresses": null,
"EndpointID": "95d81c097b766930c1b8d15b8cd661f281a422f4670c085d33ea0c6654a653b0",
"Gateway": "172.17.0.1",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"IPAddress": "172.17.0.3",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"MacAddress": "02:42:ac:11:00:03",
"Networks": {
"bridge": {
"IPAMConfig": null,
"Links": null,
"Aliases": null,
"NetworkID": "7507315d62a18bb05ad4e14dd6ecb5341d23884aa8cf919ad821ad1068d2ac8f",
"EndpointID": "95d81c097b766930c1b8d15b8cd661f281a422f4670c085d33ea0c6654a653b0",
"Gateway": "172.17.0.1",
"IPAddress": "172.17.0.3",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"MacAddress": "02:42:ac:11:00:03",
"DriverOpts": null
}
}
}
}
]

View file

@ -1,88 +0,0 @@
[
{
"Id": "sha256:a457a74c9aaabc62ddc119d2fb03ba6f58fa299bf766bd2411c159142b972c1d",
"RepoTags": [
"ubuntu:latest"
],
"RepoDigests": [
"ubuntu@sha256:669e010b58baf5beb2836b253c1fd5768333f0d1dbcb834f7c07a4dc93f474be"
],
"Parent": "",
"Comment": "",
"Created": "2022-02-02T03:19:27.692029463Z",
"Container": "396e646862a702db784450345079c41dc9da7103da54ca3d777394b06aba775e",
"ContainerConfig": {
"Hostname": "396e646862a7",
"Domainname": "",
"User": "",
"AttachStdin": false,
"AttachStdout": false,
"AttachStderr": false,
"Tty": false,
"OpenStdin": false,
"StdinOnce": false,
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
],
"Cmd": [
"/bin/sh",
"-c",
"#(nop) ",
"CMD [\"bash\"]"
],
"Image": "sha256:90d6079446c1908361700f819e620a87b923908fe4a1c5bfb12ae45b36358547",
"Volumes": null,
"WorkingDir": "",
"Entrypoint": null,
"OnBuild": null,
"Labels": {}
},
"DockerVersion": "20.10.7",
"Author": "",
"Config": {
"Hostname": "",
"Domainname": "",
"User": "",
"AttachStdin": false,
"AttachStdout": false,
"AttachStderr": false,
"Tty": false,
"OpenStdin": false,
"StdinOnce": false,
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
],
"Cmd": [
"bash"
],
"Image": "sha256:90d6079446c1908361700f819e620a87b923908fe4a1c5bfb12ae45b36358547",
"Volumes": null,
"WorkingDir": "",
"Entrypoint": null,
"OnBuild": null,
"Labels": null
},
"Architecture": "arm64",
"Variant": "v8",
"Os": "linux",
"Size": 65592278,
"VirtualSize": 65592278,
"GraphDriver": {
"Data": {
"MergedDir": "/var/lib/docker/overlay2/4336ba2a87c8d82abaa9ee5afd3ac20ea275bf05502d74d8d8396f8f51a4736c/merged",
"UpperDir": "/var/lib/docker/overlay2/4336ba2a87c8d82abaa9ee5afd3ac20ea275bf05502d74d8d8396f8f51a4736c/diff",
"WorkDir": "/var/lib/docker/overlay2/4336ba2a87c8d82abaa9ee5afd3ac20ea275bf05502d74d8d8396f8f51a4736c/work"
},
"Name": "overlay2"
},
"RootFS": {
"Type": "layers",
"Layers": [
"sha256:0c20a4bc193b305ce66d3bde10d177631646a8844804953c320f1f5b68655213"
]
},
"Metadata": {
"LastTagTime": "0001-01-01T00:00:00Z"
}
}
]

View file

@ -1,2 +0,0 @@
{"id": "6ea8176de74b", "name": "store/weaveworks/net-plugin", "version": "2.3.0", "enabled": true }
{"id": "771d3ee7c7ea", "name": "docker4x/cloudstor", "version": "18.03.1-ce-aws1", "enabled": false }

View file

@ -1,4 +0,0 @@
{"Command":"\"/bin/bash\"","CreatedAt":"2017-04-24 10:29:12 +0200 CEST","ID":"3def9aa450f8bd772c3d5b07e27ec934e5f58575e955367a0aca2d93e0687536","Image":"ubuntu:12.04","Labels":"app=example,version=1.5.4","LocalVolumes":"0","Mounts":"","Names":"sleepy_khorana","Networks":"bridge","Ports":"","RunningFor":"29 minutes","Size":"0 B","Status":"Exited (127) 2 seconds ago"}
{"Command":"\"/bin/sh\"","CreatedAt":"2017-04-22 22:44:42 +0200 CEST","ID":"d94f854370d2b02912e8fc636502bc72b74fbd567a7eba3fc6a52045bb28904e","Image":"alpine","Labels":"","LocalVolumes":"0","Mounts":"","Names":"laughing_austin,sleepy_khorana/container1","Networks":"bridge","Ports":"","RunningFor":"36 hours","Size":"0 B","Status":"Exited (0) 35 hours ago"}
{"Command":"\"/bin/sh\"","CreatedAt":"2017-08-03 12:56:03 +0200 CEST","ID":"5a83c301f30ccd48579a74a84af6fdd0c0e0d66aacc7bb52abfa2ba2544c6c0c","Image":"repo.example.com:5000/ubuntu:14.04","Labels":"","LocalVolumes":"0","Mounts":"","Names":"heuristic_almeida","Networks":"bridge","Ports":"","RunningFor":"5 hours","Size":"0 B","Status":"Exited (0) 24 hours ago"}
{"Command":"\"/bin/sh\"","CreatedAt":"2017-08-03 12:56:03 +0200 CEST","ID":"5a83c301f30ccd48579a74a84af6fdd0c0e0d66aacc7bb52abfa2ba2544c6c0c","Image":"repo.example.com:5000/ubuntu","Labels":"","LocalVolumes":"0","Mounts":"","Names":"sleepy_khorana/container1,laughing_austin/container2,laughing_lamport","Networks":"bridge","Ports":"","RunningFor":"5 hours","Size":"0 B","Status":"Exited (0) 24 hours ago"}

View file

@ -1,4 +0,0 @@
{"ID": "2ghswegspre1", "Name": "service1", "Mode": "replicated", "Replicas": "3/3", "Image": "foo/image:1.0", "Ports": "*:1234->1234/tcp"}
{"ID": "huhcawfiyddo", "Name": "service2", "Mode": "replicated", "Replicas": "3/3", "Image": "foo/image:1.1", "Ports": "*:1234->1234/tcp"}
{"ID": "msar8lb56wq2", "Name": "service3", "Mode": "replicated", "Replicas": "3/3", "Image": "bar:latest", "Ports": "*:8000->8000/tcp,*:8001->8001/tcp"}
{"ID": "mdrfkxckau6c", "Name": "service4", "Mode": "global", "Replicas": "3/3", "Image": "bar:latest", "Ports": ""}

View file

@ -1 +0,0 @@
{"Client":{"Version":"17.03.0-ce","ApiVersion":"1.26","GitCommit":"60ccb22","GoVersion":"go1.7.5","Os":"darwin","Arch":"amd64","BuildTime":"Thu Feb 23 10:40:59 2017"},"Server":{"Version":"17.03.0-ce","ApiVersion":"1.26","MinAPIVersion":"1.12","GitCommit":"3a232c8","GoVersion":"go1.7.5","Os":"linux","Arch":"amd64","KernelVersion":"4.9.12-moby","Experimental":true,"BuildTime":"Tue Feb 28 07:52:04 2017"}}

View file

@ -531,21 +531,6 @@ class MockLoader
"which zfs" => cmd.call("zfs-which"),
# which zpool
"which zpool" => cmd.call("zpool-which"),
# docker
"4f8e24022ea8b7d3b117041ec32e55d9bf08f11f4065c700e7c1dc606c84fd17" => cmd.call("docker-ps-a"),
"b40ed61c006b54f155b28a85dc944dc0352b30222087b47c6279568ec0e59d05" => cmd.call("df-PT"),
"docker version --format '{{ json . }}'" => cmd.call("docker-version"),
"docker info --format '{{ json . }}'" => cmd.call("docker-info"),
"docker inspect 71b5df59442b" => cmd.call("docker-inspec"),
"docker inspect trusting_williams" => cmd.call("docker-inspect"), # inspect container to check for mounted volumes
"docker inspect fried_water" => cmd.call("docker-inspect-e"), # inspect container to check for mounted volumes
# docker images
"83c36bfade9375ae1feb91023cd1f7409b786fd992ad4013bf0f2259d33d6406" => cmd.call("docker-images"),
"docker inspect ubuntu:latest" => cmd.call("docker-inspect-image"),
# docker services
%{docker service ls --format '{"ID": {{json .ID}}, "Name": {{json .Name}}, "Mode": {{json .Mode}}, "Replicas": {{json .Replicas}}, "Image": {{json .Image}}, "Ports": {{json .Ports}}}'} => cmd.call("docker-service-ls"),
# docker plugins
%{docker plugin ls --format '{"id": {{json .ID}}, "name": "{{ with split .Name ":"}}{{index . 0}}{{end}}", "version": "{{ with split .Name ":"}}{{index . 1}}{{end}}", "enabled": {{json .Enabled}} }'} => cmd.call("docker-plugin-ls"),
# modprobe for kernel_module
"modprobe --showconfig" => cmd.call("modprobe-config"),
# get-process cmdlet for processes resource

View file

@ -1,75 +0,0 @@
require "helper"
require "inspec/resource"
require "inspec/resources/docker_container"
describe "Inspec::Resources::DockerContainer" do
describe "docker_container" do
it "check container parsing for alpine" do
resource = load_resource("docker_container", "laughing_austin")
_(resource.id).must_equal "d94f854370d2b02912e8fc636502bc72b74fbd567a7eba3fc6a52045bb28904e"
_(resource.image).must_equal "alpine"
_(resource.repo).must_equal "alpine"
_(resource.tag).must_be_nil
_(resource.command).must_equal "/bin/sh"
_(resource.ports).must_equal ""
_(resource.resource_id).must_equal "d94f854370d2b02912e8fc636502bc72b74fbd567a7eba3fc6a52045bb28904e"
end
it "check container parsing for alpine" do
resource = load_resource("docker_container", "sleepy_khorana")
_(resource.id).must_equal "3def9aa450f8bd772c3d5b07e27ec934e5f58575e955367a0aca2d93e0687536"
_(resource.image).must_equal "ubuntu:12.04"
_(resource.repo).must_equal "ubuntu"
_(resource.tag).must_equal "12.04"
_(resource.command).must_equal "/bin/bash"
_(resource.ports).must_equal ""
_(resource.labels).must_equal ["app=example", "version=1.5.4"]
_(resource.resource_id).must_equal "3def9aa450f8bd772c3d5b07e27ec934e5f58575e955367a0aca2d93e0687536"
end
it "returns an empty array when parsing a container with no labels specified" do
resource = load_resource("docker_container", "heuristic_almeida")
_(resource.labels).must_equal []
end
it "check image containing repo with port and tag gives correct repo, image, and tag" do
resource = load_resource("docker_container", "heuristic_almeida")
_(resource.repo).must_equal "repo.example.com:5000/ubuntu"
_(resource.image).must_equal "repo.example.com:5000/ubuntu:14.04"
_(resource.tag).must_equal "14.04"
end
it "check image containing repo with port and no tag gives correct repo, image, and tag" do
resource = load_resource("docker_container", "laughing_lamport")
_(resource.repo).must_equal "repo.example.com:5000/ubuntu"
_(resource.image).must_equal "repo.example.com:5000/ubuntu"
_(resource.tag).must_be_nil
end
it "prints as a docker resource" do
resource = load_resource("docker_container", "laughing_austin")
_(resource.to_s).must_equal "Docker Container laughing_austin"
end
# Test case for has_volume? matcher - Case 1: Volumes are mounted on the container
it "checks if a volume has been mounted for the docker resource" do
resource = load_resource("docker_container", "trusting_williams")
_(resource.has_volume?("/app", "/var/lib/docker/volumes/myvol2/_data")).must_equal true
_(resource.has_volume?("/app2", "/var/lib/docker/volumes/myvol3/_data")).must_equal true
end
# Test case for has_volume? matcher - Case 2: Volumes are not mounted on the container
it "checks exception when no volume has been mounted for the docker resource" do
resource = load_resource("docker_container", "fried_water")
ex = _ { resource.has_volume?("/app", "/var/lib/docker/volumes/myvol2/_data") }.must_raise(Inspec::Exceptions::ResourceFailed)
_(ex.message).must_include "Could not find any mounted volumes for your container"
end
# Test case for has_volume? matcher - Case 3: The container doesn't exist
it "checks exception when no volume has been mounted for the docker resource and the container doesnt'e exist" do
resource = load_resource("docker_container", "non_existing_container")
ex = _ { resource.has_volume?("/app", "/var/lib/docker/volumes/myvol2/_data") }.must_raise(NoMethodError)
_(ex.message).must_include "undefined method `[]' for nil:NilClass"
end
end
end

View file

@ -1,87 +0,0 @@
require "helper"
require "inspec/resource"
require "inspec/resources/docker_image"
describe "Inspec::Resources::DockerImage" do
describe "docker_image" do
it "check docker image parsing" do
resource = load_resource("docker_image", "alpine")
_(resource.id).must_equal "sha256:4a415e3663882fbc554ee830889c68a33b3585503892cc718a4698e91ef2a526"
_(resource.tag).must_equal "latest"
_(resource.image).must_equal "alpine:latest"
_(resource.repo).must_equal "alpine"
_(resource.resource_id).must_equal "sha256:4a415e3663882fbc554ee830889c68a33b3585503892cc718a4698e91ef2a526"
end
# Test case for inspect image information handled by inspection and method_missing
it "check attributes returned by docker inspect [docker_image]" do
resource = load_resource("docker_image", "ubuntu:latest")
_(resource["Architecture"]).must_equal "arm64"
_(resource["Config.Cmd"]).must_include "bash"
_(resource.inspection).must_include "Architecture"
_(resource.inspection.Architecture).must_equal "arm64"
_(resource.resource_id).must_equal "ubuntu:latest"
end
# Test case for inspect image information with invalid keys
it "checks exception when key is invalid or doesn't exist as part of the inspect information" do
resource = load_resource("docker_image", "ubuntu:latest")
ex = _ { resource["Garbage.Key"] }.must_raise(Inspec::Exceptions::ResourceFailed)
_(ex.message).must_include "Garbage.Key is not a valid key for your image or has nil value."
end
it "prints as a docker_image resource" do
resource = load_resource("docker_image", "alpine")
_(resource.to_s).must_equal "Docker Image alpine:latest"
end
end
describe "#parse_components_from_image" do
let(:resource) { load_resource("docker_image", "alpine") }
let(:parsed) { resource.send(:parse_components_from_image, image_string) }
describe "a nil image string" do
let(:image_string) { nil }
it "returns an empty hash" do
_(parsed).must_equal({})
end
end
describe "an image string containing a simple repo" do
let(:image_string) { "chef/inspec" }
it "returns correct data" do
_(parsed[:repo]).must_equal "chef/inspec"
_(parsed[:tag]).must_be_nil
end
end
describe "parses an image string containing a repo with a port number" do
let(:image_string) { "localhost:5000/chef/inspec" }
it "returns correct data" do
_(parsed[:repo]).must_equal "localhost:5000/chef/inspec"
_(parsed[:tag]).must_be_nil
end
end
describe "parses an image string containing a repo with a tag" do
let(:image_string) { "chef/inspec:1.46.3" }
it "returns correct data" do
_(parsed[:repo]).must_equal "chef/inspec"
_(parsed[:tag]).must_equal "1.46.3"
end
end
describe "parses an image string containing a repo with a port number and a tag" do
let(:image_string) { "localhost:5000/chef/inspec:1.46.3" }
it "returns correct data" do
_(parsed[:repo]).must_equal "localhost:5000/chef/inspec"
_(parsed[:tag]).must_equal "1.46.3"
end
end
end
end

View file

@ -1,40 +0,0 @@
require "helper"
require "inspec/resource"
require "inspec/resources/docker_plugin"
describe "Inspec::Resources::DockerContainer" do
describe "docker_plugin" do
it "check plugin parsing for docker4x/cloudstor" do
resource = load_resource("docker_plugin", "docker4x/cloudstor")
_(resource.id).must_equal "771d3ee7c7ea"
_(resource.version).must_equal "18.03.1-ce-aws1"
_(resource.enabled?).must_equal false
_(resource.exist?).must_equal true
_(resource.resource_id).must_equal "771d3ee7c7ea"
end
it "check plugin parsing for store/weaveworks/net-plugin" do
resource = load_resource("docker_plugin", "store/weaveworks/net-plugin")
_(resource.id).must_equal "6ea8176de74b"
_(resource.version).must_equal "2.3.0"
_(resource.enabled?).must_equal true
_(resource.exist?).must_equal true
_(resource.resource_id).must_equal "6ea8176de74b"
end
it "check plugin parsing when there are no plugins" do
resource = load_resource("docker_plugin")
assert_nil resource.id
assert_nil resource.version
assert_nil resource.id
assert_nil resource.enabled?
_(resource.resource_id).must_equal ""
_(resource.exist?).must_equal false
end
it "prints as a docker resource" do
resource = load_resource("docker_plugin", "store/weaveworks/net-plugin")
_(resource.to_s).must_equal "Docker plugin store/weaveworks/net-plugin"
end
end
end

View file

@ -1,100 +0,0 @@
require "helper"
require "inspec/resource"
require "inspec/resources/docker_service"
describe "Inspec::Resources::DockerService" do
describe "docker_service" do
it "check docker service parsing" do
resource = load_resource("docker_service", "service1")
_(resource.id).must_equal "2ghswegspre1"
_(resource.tag).must_equal "1.0"
_(resource.image).must_equal "foo/image:1.0"
_(resource.repo).must_equal "foo/image"
_(resource.image_name).must_equal "foo/image"
_(resource.replicas).must_equal "3/3"
_(resource.mode).must_equal "replicated"
_(resource.ports).must_equal "*:1234->1234/tcp"
_(resource.resource_id).must_equal "2ghswegspre1"
end
it "check docker service from id" do
resource = load_resource("docker_service", id: "2ghswegspre1")
_(resource.id).must_equal "2ghswegspre1"
_(resource.tag).must_equal "1.0"
_(resource.image).must_equal "foo/image:1.0"
_(resource.repo).must_equal "foo/image"
_(resource.image_name).must_equal "foo/image"
_(resource.replicas).must_equal "3/3"
_(resource.mode).must_equal "replicated"
_(resource.ports).must_equal "*:1234->1234/tcp"
_(resource.resource_id).must_equal "2ghswegspre1"
end
it "check docker service from image" do
resource = load_resource("docker_service", image: "foo/image:1.0")
_(resource.id).must_equal "2ghswegspre1"
_(resource.tag).must_equal "1.0"
_(resource.image).must_equal "foo/image:1.0"
_(resource.repo).must_equal "foo/image"
_(resource.image_name).must_equal "foo/image"
_(resource.replicas).must_equal "3/3"
_(resource.mode).must_equal "replicated"
_(resource.ports).must_equal "*:1234->1234/tcp"
_(resource.resource_id).must_equal "2ghswegspre1"
end
it "prints as a docker_image resource" do
resource = load_resource("docker_service", "service1")
_(resource.to_s).must_equal "Docker Service service1"
end
end
describe "#parse_components_from_image" do
let(:resource) { load_resource("docker_service", "service1") }
let(:parsed) { resource.send(:parse_components_from_image, image_string) }
describe "a nil image string" do
let(:image_string) { nil }
it "returns an empty hash" do
_(parsed).must_equal({})
end
end
describe "an image string containing a simple repo" do
let(:image_string) { "chef/inspec" }
it "returns correct data" do
_(parsed[:repo]).must_equal "chef/inspec"
_(parsed[:tag]).must_be_nil
end
end
describe "parses an image string containing a repo with a port number" do
let(:image_string) { "localhost:5000/chef/inspec" }
it "returns correct data" do
_(parsed[:repo]).must_equal "localhost:5000/chef/inspec"
_(parsed[:tag]).must_be_nil
end
end
describe "parses an image string containing a repo with a tag" do
let(:image_string) { "chef/inspec:1.46.3" }
it "returns correct data" do
_(parsed[:repo]).must_equal "chef/inspec"
_(parsed[:tag]).must_equal "1.46.3"
end
end
describe "parses an image string containing a repo with a port number and a tag" do
let(:image_string) { "localhost:5000/chef/inspec:1.46.3" }
it "returns correct data" do
_(parsed[:repo]).must_equal "localhost:5000/chef/inspec"
_(parsed[:tag]).must_equal "1.46.3"
end
end
end
end

View file

@ -1,54 +0,0 @@
require "helper"
require "inspec/resource"
require "inspec/resources/docker"
describe "Inspec::Resources::Docker" do
describe "docker" do
let(:resource) { load_resource("docker") }
it "check docker container parsing" do
_(resource.containers.ids).must_equal %w{3def9aa450f8bd772c3d5b07e27ec934e5f58575e955367a0aca2d93e0687536 d94f854370d2b02912e8fc636502bc72b74fbd567a7eba3fc6a52045bb28904e 5a83c301f30ccd48579a74a84af6fdd0c0e0d66aacc7bb52abfa2ba2544c6c0c 5a83c301f30ccd48579a74a84af6fdd0c0e0d66aacc7bb52abfa2ba2544c6c0c}
_(resource.containers.names).must_equal %w{sleepy_khorana laughing_austin heuristic_almeida laughing_lamport}
_(resource.containers.labels).must_equal ["app=example", "version=1.5.4"]
end
it "check docker image parsing" do
_(resource.images.ids).must_equal ["sha256:4a415e3663882fbc554ee830889c68a33b3585503892cc718a4698e91ef2a526", "sha256:978d85d02b87aea199e4ae8664f6abf32fdea331884818e46b8a01106b114cee", "sha256:0ef2e08ed3fabfc44002ccb846c4f2416a2135affc3ce39538834059606f32dd", "sha256:c4e5744dbe11a4f1970ba36d0aa3944c347ab232bb58fb86b240f1bb18a360c2"]
_(resource.images.repositories).must_equal ["alpine", "debian", "ubuntu", "repo.example.com:5000/ubuntu"]
end
it "check docker service parsing" do
_(resource.services.ids).must_equal %w{2ghswegspre1 huhcawfiyddo msar8lb56wq2 mdrfkxckau6c}
_(resource.services.names).must_equal %w{service1 service2 service3 service4}
_(resource.services.images).must_equal ["foo/image:1.0", "foo/image:1.1", "bar:latest", "bar:latest"]
end
it "check docker plugins parsing" do
_(resource.plugins.ids).must_equal %w{6ea8176de74b 771d3ee7c7ea}
_(resource.plugins.names).must_equal ["store/weaveworks/net-plugin", "docker4x/cloudstor"]
_(resource.plugins.versions).must_equal ["2.3.0", "18.03.1-ce-aws1"]
_(resource.plugins.enabled).must_equal [true, false]
end
it "check docker version parsing" do
_(resource.version.Server.Version).must_equal "17.03.0-ce"
_(resource.version.Client.Version).must_equal "17.03.0-ce"
end
it "check docker info parsing" do
_(resource.info.ID).must_equal "HMKB:SOFR:Z3DM:J6ZY:WE6K:47EW:WVGV:C5C3:WNJC:TSG6:43YV:IOGU"
_(resource.info.Containers).must_equal 93
_(resource.info.Runtimes.runc.path).must_equal "docker-runc"
_(resource.info.SecurityOptions).must_equal ["name=seccomp,profile=default"]
end
it "check docker object parsing" do
_(resource.object("71b5df59442b").Id).must_equal "71b5df59442be8215902ce7804bfbb0ab5d8b8ddab7cef6e00224a8c1f476e38"
_(resource.object("71b5df59442b").Path).must_equal "nginx"
end
it "prints as a docker resource" do
_(resource.to_s).must_equal "Docker Host"
end
end
end