mirror of
https://github.com/inspec/inspec
synced 2024-11-22 12:43:07 +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.+":{
|
"internal_fallback_test.+":{
|
||||||
"gem":"inspec-test-resources",
|
"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."
|
"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/timezone"
|
||||||
require "inspec/resources/dh_params"
|
require "inspec/resources/dh_params"
|
||||||
require "inspec/resources/directory"
|
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/elasticsearch"
|
||||||
require "inspec/resources/etc_fstab"
|
require "inspec/resources/etc_fstab"
|
||||||
require "inspec/resources/etc_group"
|
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 zfs" => cmd.call("zfs-which"),
|
||||||
# which zpool
|
# which zpool
|
||||||
"which zpool" => cmd.call("zpool-which"),
|
"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 for kernel_module
|
||||||
"modprobe --showconfig" => cmd.call("modprobe-config"),
|
"modprobe --showconfig" => cmd.call("modprobe-config"),
|
||||||
# get-process cmdlet for processes resource
|
# 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