diff --git a/docs-chef-io/content/inspec/resources/lxc.md b/docs-chef-io/content/inspec/resources/lxc.md new file mode 100644 index 000000000..d419e1fc7 --- /dev/null +++ b/docs-chef-io/content/inspec/resources/lxc.md @@ -0,0 +1,67 @@ ++++ +title = "lxc resource" +draft = false +gh_repo = "inspec" +platform = "linux" + +[menu] + [menu.inspec] + title = "lxc" + identifier = "inspec/resources/os/lxc.md lxc resource" + parent = "inspec/resources/os" ++++ + +Use the `lxc` Chef InSpec audit resource to test the information about Linux containers. LXC is a command-line client for LXD that manages your LXD instances (containers and virtual machines). The tests are against the container's information obtained on `lxc info [container-name]`. `lxc` resource allows the testing if the container exists or is in running status. + +## Availability + +### Installation + +This resource is distributed with Chef InSpec. + +## Syntax + +An `lxc` Chef InSpec audit resource allows testing if the container exists or is in running status. + + describe lxc("linux-container-name") do + it { should exist } + it { should be_running } + end + +## Matchers + +For a full list of available matchers, please visit our [matchers page](https://docs.chef.io/inspec/matchers/). + +The specific matchers of this resource are: `exist`, `be_running`. + +### exist + +The `exist` matcher is used to specify if the container exists: + + it { should exist } + +### be_running + +The `be_running` matcher is used to check if the container is running: + + it { should be_running } + +## Examples + +The following examples show how to use this Chef InSpec audit resource. + +### Ensures container exists + +The below test passes if the container `immense-phoenix` exists as part of the LXD instances. + + describe lxc("immense-phoenix") do + it { should exist } + end + +### Ensures container is in running status + +The below test passes if the container `delicate-sloth` exists as part of the LXD instances and the status is running. + + describe lxc("delicate-sloth") do + it { should be_running } + end diff --git a/lib/inspec/resources/lxc.rb b/lib/inspec/resources/lxc.rb new file mode 100644 index 000000000..f9c0e87ae --- /dev/null +++ b/lib/inspec/resources/lxc.rb @@ -0,0 +1,57 @@ +require "inspec/resources/command" +module Inspec::Resources + class Lxc < Inspec.resource(1) + name "lxc" + # Restrict to only run on the below platforms + supports platform: "linux" + desc "Use the lxc InSpec audit resource to test if container exists and/or is running for linux container" + example <<~EXAMPLE + describe lxc("ubuntu-container") do + it { should exist } + it { should be_running } + end + EXAMPLE + + # Resource initialization. + def initialize(container_name) + @container_name = container_name + + raise Inspec::Exceptions::ResourceSkipped, "The `lxc` resource is not supported on your OS yet." unless inspec.os.linux? + end + + def resource_id + @container_name + end + + def to_s + "lxc #{resource_id}" + end + + def exists? + lxc_info_cmd.exit_status.to_i == 0 + end + + def running? + container_info = lxc_info_cmd.stdout.split(":").map(&:strip) + container_info[0] == "Status" && container_info[1] == "Running" + end + + private + + # Method to find lxc + def find_lxc_or_error + %w{/usr/sbin/lxc /sbin/lxc lxc}.each do |cmd| + return cmd if inspec.command(cmd).exist? + end + + raise Inspec::Exceptions::ResourceFailed, "Could not find `lxc`" + end + + def lxc_info_cmd + bin = find_lxc_or_error + info_cmd = "info #{@container_name} | grep -i Status" + lxc_cmd = format("%s %s", bin, info_cmd).strip + inspec.command(lxc_cmd) + end + end +end diff --git a/test/fixtures/cmd/lxcinfo b/test/fixtures/cmd/lxcinfo new file mode 100644 index 000000000..374b6dadc --- /dev/null +++ b/test/fixtures/cmd/lxcinfo @@ -0,0 +1 @@ +Status: Running \ No newline at end of file diff --git a/test/helpers/mock_loader.rb b/test/helpers/mock_loader.rb index 636d59e2c..515820b25 100644 --- a/test/helpers/mock_loader.rb +++ b/test/helpers/mock_loader.rb @@ -375,6 +375,9 @@ class MockLoader # ipfilter "/usr/sbin/ipfstat -io" => cmd.call("ipfstat-io"), %{type "/usr/sbin/ipfstat"} => empty.call, + # lxc + "/usr/sbin/lxc info my-ubuntu-container | grep -i Status" => cmd.call("lxcinfo"), + %{sh -c 'type "/usr/sbin/lxc"'} => empty.call, # apache_conf "sh -c 'find /etc/apache2/ports.conf -type f -maxdepth 1'" => cmd.call("find-apache2-ports-conf"), "sh -c 'find /etc/httpd/conf.d/*.conf -type f -maxdepth 1'" => cmd.call("find-httpd-ssl-conf"), diff --git a/test/unit/resources/lxc_test.rb b/test/unit/resources/lxc_test.rb new file mode 100644 index 000000000..11830c3e7 --- /dev/null +++ b/test/unit/resources/lxc_test.rb @@ -0,0 +1,38 @@ +# Load (require) the InSpec globals definition file. +require "inspec/globals" +# Load (require) the core test unit helper file +require "#{Inspec.src_root}/test/helper" +# Load (require) the resource library file +require_relative "../../../lib/inspec/resources/lxc" + +describe "Inspec::Resources::Lxc" do + # ubuntu + it "verify lxc resource on ubuntu" do + resource = MockLoader.new(:ubuntu).load_resource("lxc", "my-ubuntu-container") + _(resource.exists?).must_equal true + _(resource.running?).must_equal true + _(resource.resource_skipped?).must_equal false + end + + # # ubuntu + it "verify lxc resource on ubuntu for non exisiting container" do + resource = MockLoader.new(:ubuntu).load_resource("lxc", "my-ubuntu-container-1") + _(resource.exists?).must_equal false + _(resource.running?).must_equal false + _(resource.resource_skipped?).must_equal false + end + + # windows + it "verify lxc resource on windows" do + resource = MockLoader.new(:windows).load_resource("lxc", "my-ubuntu-container") + _(resource.resource_skipped?).must_equal true + _(resource.resource_exception_message).must_equal "The `lxc` resource is not supported on your OS yet." + end + + # undefined + it "verify lxc resource on unsupported os" do + resource = MockLoader.new(:undefined).load_resource("lxc", "my-ubuntu-container") + _(resource.resource_skipped?).must_equal true + _(resource.resource_exception_message).must_equal "The `lxc` resource is not supported on your OS yet." + end +end \ No newline at end of file