mirror of
https://github.com/inspec/inspec
synced 2024-11-22 04:33:09 +00:00
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:
parent
bf9a3c7e38
commit
7e4ef2fddf
29 changed files with 4 additions and 2424 deletions
|
@ -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" >}}
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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 }
|
|
@ -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"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
4
test/fixtures/cmd/docker-images
vendored
4
test/fixtures/cmd/docker-images
vendored
|
@ -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" }
|
10
test/fixtures/cmd/docker-info
vendored
10
test/fixtures/cmd/docker-info
vendored
|
@ -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"]
|
||||
}
|
7
test/fixtures/cmd/docker-inspec
vendored
7
test/fixtures/cmd/docker-inspec
vendored
|
@ -1,7 +0,0 @@
|
|||
[
|
||||
{
|
||||
"Id": "71b5df59442be8215902ce7804bfbb0ab5d8b8ddab7cef6e00224a8c1f476e38",
|
||||
"Created": "2017-04-22T15:08:47.082154846Z",
|
||||
"Path": "nginx"
|
||||
}
|
||||
]
|
243
test/fixtures/cmd/docker-inspect
vendored
243
test/fixtures/cmd/docker-inspect
vendored
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
196
test/fixtures/cmd/docker-inspect-e
vendored
196
test/fixtures/cmd/docker-inspect-e
vendored
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
88
test/fixtures/cmd/docker-inspect-image
vendored
88
test/fixtures/cmd/docker-inspect-image
vendored
|
@ -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"
|
||||
}
|
||||
}
|
||||
]
|
2
test/fixtures/cmd/docker-plugin-ls
vendored
2
test/fixtures/cmd/docker-plugin-ls
vendored
|
@ -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 }
|
4
test/fixtures/cmd/docker-ps-a
vendored
4
test/fixtures/cmd/docker-ps-a
vendored
|
@ -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"}
|
4
test/fixtures/cmd/docker-service-ls
vendored
4
test/fixtures/cmd/docker-service-ls
vendored
|
@ -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": ""}
|
1
test/fixtures/cmd/docker-version
vendored
1
test/fixtures/cmd/docker-version
vendored
|
@ -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"}}
|
|
@ -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
|
||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
Loading…
Reference in a new issue