class Inspec::Resources::Docker
This resource helps to parse information from the docker host For compatability with Serverspec we also offer the following resouses:
-
docker_container
-
docker_image
Public Instance Methods
containers()
click to toggle source
# File lib/inspec/resources/docker.rb, line 132 def containers DockerContainerFilter.new(parse_containers) end
images()
click to toggle source
# File lib/inspec/resources/docker.rb, line 136 def images DockerImageFilter.new(parse_images) end
info()
click to toggle source
# File lib/inspec/resources/docker.rb, line 159 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
object(id)
click to toggle source
returns information about docker objects
# File lib/inspec/resources/docker.rb, line 172 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
plugins()
click to toggle source
# File lib/inspec/resources/docker.rb, line 140 def plugins DockerPluginFilter.new(parse_plugins) end
services()
click to toggle source
# File lib/inspec/resources/docker.rb, line 144 def services DockerServiceFilter.new(parse_services) end
to_s()
click to toggle source
# File lib/inspec/resources/docker.rb, line 182 def to_s "Docker Host" end
version()
click to toggle source
# File lib/inspec/resources/docker.rb, line 148 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
Private Instance Methods
ensure_keys(entry, labels)
click to toggle source
# File lib/inspec/resources/docker.rb, line 242 def ensure_keys(entry, labels) labels.each do |key| entry[key.downcase] = nil unless entry.key?(key.downcase) end entry end
parse_containers()
click to toggle source
# File lib/inspec/resources/docker.rb, line 224 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
parse_images()
click to toggle source
# File lib/inspec/resources/docker.rb, line 249 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
parse_json_command(labels, subcommand)
click to toggle source
# File lib/inspec/resources/docker.rb, line 188 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
parse_plugins()
click to toggle source
# File lib/inspec/resources/docker.rb, line 262 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
parse_services()
click to toggle source
# File lib/inspec/resources/docker.rb, line 238 def parse_services parse_json_command(%w{ID Name Mode Replicas Image Ports}, "service ls") end