mirror of
https://github.com/inspec/inspec
synced 2024-11-10 07:04:15 +00:00
Enhance lxc
resource to test properties (#6243)
* ENHANCE: Extend lxc resource to test the properties Signed-off-by: Sonu Saha <sonu.saha@progress.com> * TEST: Extend test for introduced properties Signed-off-by: Sonu Saha <sonu.saha@progress.com> * DOCS: Extend test for introduced properties Signed-off-by: Sonu Saha <sonu.saha@progress.com> * FIX: Correct exception class to handle bad yaml Signed-off-by: Sonu Saha <sonu.saha@progress.com> * Doc Review Signed-off-by: Deepa Kumaraswamy <dkumaras@progress.com> * FIX: Handle specific exception to handle bad yaml Signed-off-by: Sonu Saha <sonu.saha@progress.com> Signed-off-by: Sonu Saha <sonu.saha@progress.com> Signed-off-by: Deepa Kumaraswamy <dkumaras@progress.com> Co-authored-by: Deepa Kumaraswamy <dkumaras@progress.com>
This commit is contained in:
parent
93f24cabbe
commit
3bcf4e6544
6 changed files with 231 additions and 30 deletions
|
@ -11,40 +11,112 @@ platform = "linux"
|
|||
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.
|
||||
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.
|
||||
This resource is distributed with Chef InSpec and is automatically available for use.
|
||||
|
||||
## Syntax
|
||||
|
||||
An `lxc` Chef InSpec audit resource allows testing if the container exists or is in running status.
|
||||
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
|
||||
```ruby
|
||||
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`.
|
||||
The specific matchers of this resource are: `exist` and `be_running`.
|
||||
|
||||
### exist
|
||||
|
||||
The `exist` matcher is used to specify if the container exists:
|
||||
|
||||
it { should exist }
|
||||
```ruby
|
||||
it { should exist }
|
||||
```
|
||||
|
||||
### be_running
|
||||
|
||||
The `be_running` matcher is used to check if the container is running:
|
||||
|
||||
it { should be_running }
|
||||
```ruby
|
||||
it { should be_running }
|
||||
```
|
||||
|
||||
## Properties
|
||||
|
||||
### name
|
||||
|
||||
Returns the instance name.
|
||||
|
||||
```ruby
|
||||
its("name") { should eq "ubuntu-container" }
|
||||
```
|
||||
|
||||
### status
|
||||
|
||||
Returns the instance status.
|
||||
|
||||
```ruby
|
||||
its("status") { should cmp "Running" }
|
||||
```
|
||||
|
||||
### type
|
||||
|
||||
Returns the instance type (for example, container).
|
||||
|
||||
```ruby
|
||||
its("type") { should eq "container" }
|
||||
```
|
||||
|
||||
### architecture
|
||||
|
||||
Returns the architecture of the instance.
|
||||
|
||||
```ruby
|
||||
its("architecture") { should eq "x86_64" }
|
||||
```
|
||||
|
||||
### pid
|
||||
|
||||
Returns the pid of the instance.
|
||||
|
||||
```ruby
|
||||
its("pid") { should eq 1378 }
|
||||
```
|
||||
|
||||
### created_at
|
||||
|
||||
Returns the creation date of the instance.
|
||||
|
||||
```ruby
|
||||
its("created_at") { should eq "2022/08/16 12:07 UTC" }
|
||||
```
|
||||
|
||||
### last_used_at
|
||||
|
||||
Returns the last used date of the instance.
|
||||
|
||||
```ruby
|
||||
its("last_used_at") { should eq "2022/08/17 05:06 UTC" }
|
||||
```
|
||||
|
||||
### resources
|
||||
|
||||
Returns the resource information of the instance.
|
||||
|
||||
```ruby
|
||||
its("resources") { should include "Disk usage" }
|
||||
```
|
||||
|
||||
## Examples
|
||||
|
||||
|
@ -54,14 +126,37 @@ The following examples show how to use this Chef InSpec audit resource.
|
|||
|
||||
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
|
||||
```ruby
|
||||
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
|
||||
```ruby
|
||||
describe lxc("delicate-sloth") do
|
||||
it { should be_running }
|
||||
end
|
||||
```
|
||||
|
||||
### Ensures container exists, is in running status, and verifies the different container properties
|
||||
|
||||
The below test passes if the container `ubuntu-container` exists, is running, and the properties value matches against the desired value.
|
||||
|
||||
```ruby
|
||||
describe lxc("ubuntu-container") do
|
||||
it { should exist }
|
||||
it { should be_running }
|
||||
its("name") { should eq "ubuntu-container" }
|
||||
its("status") { should cmp "Running" }
|
||||
its("type") { should eq "container" }
|
||||
its("architecture") { should eq "x86_64" }
|
||||
its("pid") { should eq 1378 }
|
||||
its("created_at") { should eq "2022/08/16 12:07 UTC" }
|
||||
its("last_used_at") { should eq "2022/08/17 05:06 UTC" }
|
||||
its("resources") { should include "Disk usage" }
|
||||
end
|
||||
```
|
||||
|
|
|
@ -9,14 +9,26 @@ module Inspec::Resources
|
|||
describe lxc("ubuntu-container") do
|
||||
it { should exist }
|
||||
it { should be_running }
|
||||
its("name") { should eq "ubuntu-container" }
|
||||
its("status") { should cmp "Running" }
|
||||
its("type") { should eq "container" }
|
||||
its("architecture") { should eq "x86_64" }
|
||||
its("pid") { should eq 1378 }
|
||||
its("created_at") { should eq "2022/08/16 12:07 UTC" }
|
||||
its("last_used_at") { should eq "2022/08/17 05:06 UTC" }
|
||||
its("resources") { should include "Disk usage" }
|
||||
end
|
||||
EXAMPLE
|
||||
|
||||
attr_reader :container_info, :container_name
|
||||
|
||||
# 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?
|
||||
|
||||
@container_info = populate_container_info
|
||||
end
|
||||
|
||||
def resource_id
|
||||
|
@ -28,17 +40,60 @@ module Inspec::Resources
|
|||
end
|
||||
|
||||
def exists?
|
||||
lxc_info_cmd.exit_status.to_i == 0
|
||||
!@container_info.empty?
|
||||
end
|
||||
|
||||
def running?
|
||||
container_info = lxc_info_cmd.stdout.split(":").map(&:strip)
|
||||
container_info[0] == "Status" && container_info[1] == "Running"
|
||||
@container_info.key?("Status") && @container_info["Status"].casecmp("Running") == 0
|
||||
end
|
||||
|
||||
def name
|
||||
@container_info["Name"]
|
||||
end
|
||||
|
||||
def status
|
||||
@container_info["Status"]
|
||||
end
|
||||
|
||||
def type
|
||||
@container_info["Type"]
|
||||
end
|
||||
|
||||
def architecture
|
||||
@container_info["Architecture"]
|
||||
end
|
||||
|
||||
def pid
|
||||
@container_info["PID"]
|
||||
end
|
||||
|
||||
def created_at
|
||||
@container_info["Created"]
|
||||
end
|
||||
|
||||
def last_used_at
|
||||
@container_info["Last Used"]
|
||||
end
|
||||
|
||||
def resources
|
||||
@container_info["Resources"]
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# Method to find lxc
|
||||
def populate_container_info
|
||||
lxc_util = find_lxc_or_error
|
||||
lxc_info_cmd = inspec.command("#{lxc_util} info #{@container_name}")
|
||||
|
||||
if lxc_info_cmd.exit_status.to_i == 0
|
||||
parse_command_output(lxc_info_cmd.stdout)
|
||||
elsif lxc_info_cmd.stderr =~ /Error: Instance not found/
|
||||
{}
|
||||
else
|
||||
raise Inspec::Exceptions::ResourceFailed, "Unable to retrieve information for #{container_name}.\n#{lxc_info_cmd.stderr}"
|
||||
end
|
||||
end
|
||||
|
||||
def find_lxc_or_error
|
||||
%w{/usr/sbin/lxc /sbin/lxc lxc}.each do |cmd|
|
||||
return cmd if inspec.command(cmd).exist?
|
||||
|
@ -47,11 +102,12 @@ module Inspec::Resources
|
|||
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)
|
||||
def parse_command_output(output)
|
||||
require "yaml" unless defined?(YAML)
|
||||
YAML.load(output)
|
||||
rescue Psych::SyntaxError => e
|
||||
warn "Could not parse the command output.\n#{e.message}"
|
||||
{}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
1
test/fixtures/cmd/lxcerror
vendored
Normal file
1
test/fixtures/cmd/lxcerror
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
Error: Instance not found
|
43
test/fixtures/cmd/lxcinfo
vendored
43
test/fixtures/cmd/lxcinfo
vendored
|
@ -1 +1,42 @@
|
|||
Status: Running
|
||||
Name: ubuntu-container
|
||||
Status: RUNNING
|
||||
Type: container
|
||||
Architecture: x86_64
|
||||
PID: 1378
|
||||
Created: 2022/08/16 12:07 UTC
|
||||
Last Used: 2022/08/17 05:06 UTC
|
||||
|
||||
Resources:
|
||||
Processes: 13
|
||||
Disk usage:
|
||||
root: 53.97MiB
|
||||
CPU usage:
|
||||
CPU usage (in seconds): 2
|
||||
Memory usage:
|
||||
Memory (current): 32.30MiB
|
||||
Network usage:
|
||||
eth0:
|
||||
Type: broadcast
|
||||
State: UP
|
||||
Host interface: vethc32daefe
|
||||
MAC address: 00:16:3e:0e:be:4b
|
||||
MTU: 1500
|
||||
Bytes received: 18.12kB
|
||||
Bytes sent: 18.82kB
|
||||
Packets received: 130
|
||||
Packets sent: 183
|
||||
IP addresses:
|
||||
inet: 10.199.12.205/24 (global)
|
||||
inet6: fd42:574e:edd0:2d9f:216:3eff:fe0e:be4b/64 (global)
|
||||
inet6: fe80::216:3eff:fe0e:be4b/64 (link)
|
||||
lo:
|
||||
Type: loopback
|
||||
State: UP
|
||||
MTU: 65536
|
||||
Bytes received: 0B
|
||||
Bytes sent: 0B
|
||||
Packets received: 0
|
||||
Packets sent: 0
|
||||
IP addresses:
|
||||
inet: 127.0.0.1/8 (local)
|
||||
inet6: ::1/128 (local)
|
|
@ -392,7 +392,8 @@ class MockLoader
|
|||
"/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"),
|
||||
"/usr/sbin/lxc info ubuntu-container" => cmd.call("lxcinfo"),
|
||||
"/usr/sbin/lxc info my-ubuntu-container-1" => cmd_stderr.call("lxcerror"),
|
||||
%{sh -c 'type "/usr/sbin/lxc"'} => empty.call,
|
||||
# cgroup
|
||||
"cgget -n -a carrotking" => cmd.call("cgget-n-a"),
|
||||
|
|
|
@ -8,14 +8,21 @@ 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 = MockLoader.new(:ubuntu).load_resource("lxc", "ubuntu-container")
|
||||
_(resource.exists?).must_equal true
|
||||
_(resource.running?).must_equal true
|
||||
_(resource.resource_skipped?).must_equal false
|
||||
_(resource.resource_id).must_equal "my-ubuntu-container"
|
||||
_(resource.name).must_equal "ubuntu-container"
|
||||
_(resource.status).must_equal "RUNNING"
|
||||
_(resource.type).must_equal "container"
|
||||
_(resource.architecture).must_equal "x86_64"
|
||||
_(resource.pid).must_equal 1378
|
||||
_(resource.created_at).must_equal "2022/08/16 12:07 UTC"
|
||||
_(resource.last_used_at).must_equal "2022/08/17 05:06 UTC"
|
||||
_(resource.resource_id).must_equal "ubuntu-container"
|
||||
end
|
||||
|
||||
# # ubuntu
|
||||
# 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
|
||||
|
|
Loading…
Reference in a new issue