Skip to content
Permalink
Browse files

Add new options to Command resource (#434)

* Add optional exec attribute to command definitions
Allow skip attribute in command definitions

Documentation changes for new command exec attribute, and skip attribute

Update CI tests to match changes to the command exec attribute

* Disable dnstest (#440)

* Disable dnstest.io tests, seems to be down

* Update md5 for latest docker images

* Add tests for command and skip
Fix problem with skipping first test
Fix where commands add exec attribute automatically

* gofmt loves tabs and vertical space
  • Loading branch information...
sshipway authored and aelsabbahy committed May 12, 2019
1 parent 9c0d41f commit e5701164dbcb2ddf25cfbf13523ad13b03bda5ee
@@ -432,18 +432,23 @@ Validates the exit-status and output of a command
```yaml
command:
go version:
version:
# required attributes
exit-status: 0
# defaults to hash key
exec: "go version"
# optional attributes
stdout:
- go version go1.6 linux/amd64
stderr: []
timeout: 10000 # in milliseconds
skip: false
```
`stdout` and `stderr` can be a string or [pattern](#patterns)
The `exec` attribute is the command to run; this defaults to the name of
the hash for backwards compatibility
### dns
Validates that the provided address is resolvable and the addrs it resolves to.
@@ -535,6 +540,7 @@ file:
# optional attributes
filetype: symlink # file, symlink, directory
linked-to: /usr/sbin/sendmail.sendmail
skip: false
```
`contains` can be a string or a [pattern](#patterns)
@@ -560,6 +566,7 @@ group:
exists: true
# optional attributes
gid: 65534
skip: false
```
@@ -578,6 +585,7 @@ http:
body: [] # Check http response content for these patterns
username: "" # username for basic auth
password: "" # password for basic auth
skip: false
```
@@ -695,6 +703,7 @@ package:
# optional attributes
versions:
- 2.2.15
skip: false
```
**NOTE:** this check uses the `--package <format>` parameter passed on the command line.
@@ -714,6 +723,7 @@ port:
# optional attributes
ip: # what IP(s) is it listening on
- 0.0.0.0
skip: false
```
@@ -725,6 +735,7 @@ process:
chrome:
# required attributes
running: true
skip: false
```
@@ -737,6 +748,7 @@ service:
# required attributes
enabled: true
running: true
skip: false
```
**NOTE:** this will **not** automatically check if the process is alive, it will check the status from `systemd`/`upstart`/`init`.
@@ -757,6 +769,7 @@ user:
- nfsnobody
home: /var/lib/nfs
shell: /sbin/nologin
skip: false
```
@@ -14,3 +14,7 @@ service:
enabled: true
{{end}}
running: true
skippable:
enabled: true
running: true
skip: true
@@ -10,6 +10,13 @@ command:
stdout: []
stderr:
- not found
command-override:
exec: true
exit-status: 0
commandskip:
exec: false
exit-status: 0
skip: true
file:
{{range mkSlice "/etc/passwd" "/etc/group"}}
{{.}}:
@@ -40,6 +47,11 @@ file:
"/pipe":
exists: true
filetype: pipe
"/does/not/exist":
exists: true
contains:
- skip-this-test
skip: true
package:
foobar:
installed: false
@@ -32,7 +32,7 @@ docker_exec() {
if docker ps -a | grep "$container_name";then
docker rm -vf "$container_name"
fi
opts=(--env OS=$os --cap-add SYS_ADMIN -v "$PWD/goss:/goss" -d --name "$container_name" $(seccomp_opts))
opts=(--env OS=$os --cap-add SYS_ADMIN -v "$PWD/goss:/goss" -d --name "$container_name" $(seccomp_opts))
id=$(docker run "${opts[@]}" "aelsabbahy/goss_$os" /sbin/init)
ip=$(docker inspect --format '{{ .NetworkSettings.IPAddress }}' "$id")
trap "rv=\$?; docker rm -vf $id; exit \$rv" INT TERM EXIT
@@ -44,9 +44,9 @@ out=$(docker_exec "/goss/$os/goss-linux-$arch" --vars "/goss/vars.yaml" -g "/gos
echo "$out"

if [[ $os == "arch" ]]; then
egrep -q 'Count: 55, Failed: 0' <<<"$out"
egrep -q 'Count: 59, Failed: 0, Skipped: 3' <<<"$out"
else
egrep -q 'Count: 69, Failed: 0' <<<"$out"
egrep -q 'Count: 75, Failed: 0, Skipped: 5' <<<"$out"
fi

if [[ ! $os == "arch" ]]; then
@@ -14,26 +14,43 @@ type Command struct {
Title string `json:"title,omitempty" yaml:"title,omitempty"`
Meta meta `json:"meta,omitempty" yaml:"meta,omitempty"`
Command string `json:"-" yaml:"-"`
Exec string `json:"exec,omitempty" yaml:"exec,omitempty"`
ExitStatus matcher `json:"exit-status" yaml:"exit-status"`
Stdout []string `json:"stdout" yaml:"stdout"`
Stderr []string `json:"stderr" yaml:"stderr"`
Timeout int `json:"timeout" yaml:"timeout"`
Skip bool `json:"skip,omitempty" yaml:"skip,omitempty"`
}

func (c *Command) ID() string { return c.Command }
func (c *Command) ID() string {
if c.Exec != "" && c.Exec != c.Command {
return fmt.Sprintf("%s: %s", c.Command, c.Exec)
}
return c.Command
}
func (c *Command) SetID(id string) { c.Command = id }

func (c *Command) GetTitle() string { return c.Title }
func (c *Command) GetMeta() meta { return c.Meta }
func (c *Command) GetExec() string {
if c.Exec != "" {
return c.Exec
}
return c.Command
}

func (c *Command) Validate(sys *system.System) []TestResult {
skip := false
if c.Timeout == 0 {
c.Timeout = 10000
}
sysCommand := sys.NewCommand(c.Command, sys, util.Config{Timeout: c.Timeout})
if c.Skip {
skip = true
}

var results []TestResult
sysCommand := sys.NewCommand(c.GetExec(), sys, util.Config{Timeout: c.Timeout})

cExitStatus := deprecateAtoI(c.ExitStatus, fmt.Sprintf("%s: command.exit-status", c.Command))
results = append(results, ValidateValue(c, "exit-status", cExitStatus, sysCommand.ExitStatus, skip))
if len(c.Stdout) > 0 {
@@ -16,6 +16,7 @@ type DNS struct {
Addrs matcher `json:"addrs,omitempty" yaml:"addrs,omitempty"`
Timeout int `json:"timeout" yaml:"timeout"`
Server string `json:"server,omitempty" yaml:"server,omitempty"`
Skip bool `json:"skip,omitempty" yaml:"skip,omitempty"`
}

func (d *DNS) ID() string { return d.Host }
@@ -29,6 +30,9 @@ func (d *DNS) Validate(sys *system.System) []TestResult {
if d.Timeout == 0 {
d.Timeout = 500
}
if d.Skip {
skip = true
}

sysDNS := sys.NewDNS(d.Host, sys, util.Config{Timeout: d.Timeout, Server: d.Server})

@@ -19,6 +19,7 @@ type File struct {
Contains []string `json:"contains" yaml:"contains"`
Md5 matcher `json:"md5,omitempty" yaml:"md5,omitempty"`
Sha256 matcher `json:"sha256,omitempty" yaml:"sha256,omitempty"`
Skip bool `json:"skip,omitempty" yaml:"skip,omitempty"`
}

func (f *File) ID() string { return f.Path }
@@ -31,6 +32,10 @@ func (f *File) Validate(sys *system.System) []TestResult {
skip := false
sysFile := sys.NewFile(f.Path, sys, util.Config{})

if f.Skip {
skip = true
}

var results []TestResult
results = append(results, ValidateValue(f, "exists", f.Exists, sysFile.Exists, skip))
if shouldSkip(results) {
@@ -13,6 +13,7 @@ type Group struct {
Groupname string `json:"-" yaml:"-"`
Exists matcher `json:"exists" yaml:"exists"`
GID matcher `json:"gid,omitempty" yaml:"gid,omitempty"`
Skip bool `json:"skip,omitempty" yaml:"skip,omitempty"`
}

func (g *Group) ID() string { return g.Groupname }
@@ -25,6 +26,10 @@ func (g *Group) Validate(sys *system.System) []TestResult {
skip := false
sysgroup := sys.NewGroup(g.Groupname, sys, util.Config{})

if g.Skip {
skip = true
}

var results []TestResult
results = append(results, ValidateValue(g, "exists", g.Exists, sysgroup.Exists, skip))
if shouldSkip(results) {
@@ -16,6 +16,7 @@ type HTTP struct {
Body []string `json:"body" yaml:"body"`
Username string `json:"username,omitempty" yaml:"username,omitempty"`
Password string `json:"password,omitempty" yaml:"password,omitempty"`
Skip bool `json:"skip,omitempty" yaml:"skip,omitempty"`
}

func (u *HTTP) ID() string { return u.HTTP }
@@ -36,6 +37,10 @@ func (u *HTTP) Validate(sys *system.System) []TestResult {
sysHTTP.SetAllowInsecure(u.AllowInsecure)
sysHTTP.SetNoFollowRedirects(u.NoFollowRedirects)

if u.Skip {
skip = true
}

var results []TestResult
results = append(results, ValidateValue(u, "status", u.Status, sysHTTP.Status, skip))
if shouldSkip(results) {
@@ -58,7 +63,7 @@ func NewHTTP(sysHTTP system.HTTP, config util.Config) (*HTTP, error) {
AllowInsecure: config.AllowInsecure,
NoFollowRedirects: config.NoFollowRedirects,
Timeout: config.Timeout,
Username: config.Username,
Username: config.Username,
Password: config.Password,
}
return u, err
@@ -12,6 +12,7 @@ type Interface struct {
Exists matcher `json:"exists" yaml:"exists"`
Addrs matcher `json:"addrs,omitempty" yaml:"addrs,omitempty"`
MTU matcher `json:"mtu,omitempty" yaml:"mtu,omitempty"`
Skip bool `json:"skip,omitempty" yaml:"skip,omitempty"`
}

func (i *Interface) ID() string { return i.Name }
@@ -25,6 +26,10 @@ func (i *Interface) Validate(sys *system.System) []TestResult {
skip := false
sysInterface := sys.NewInterface(i.Name, sys, util.Config{})

if i.Skip {
skip = true
}

var results []TestResult
results = append(results, ValidateValue(i, "exists", i.Exists, sysInterface.Exists, skip))
if shouldSkip(results) {
@@ -13,6 +13,7 @@ type Mount struct {
Opts matcher `json:"opts,omitempty" yaml:"opts,omitempty"`
Source matcher `json:"source,omitempty" yaml:"source,omitempty"`
Filesystem matcher `json:"filesystem,omitempty" yaml:"filesystem,omitempty"`
Skip bool `json:"skip,omitempty" yaml:"skip,omitempty"`
}

func (m *Mount) ID() string { return m.MountPoint }
@@ -26,6 +27,10 @@ func (m *Mount) Validate(sys *system.System) []TestResult {
skip := false
sysMount := sys.NewMount(m.MountPoint, sys, util.Config{})

if m.Skip {
skip = true
}

var results []TestResult
results = append(results, ValidateValue(m, "exists", m.Exists, sysMount.Exists, skip))
if shouldSkip(results) {
@@ -11,6 +11,7 @@ type Package struct {
Name string `json:"-" yaml:"-"`
Installed matcher `json:"installed" yaml:"installed"`
Versions matcher `json:"versions,omitempty" yaml:"versions,omitempty"`
Skip bool `json:"skip,omitempty" yaml:"skip,omitempty"`
}

func (p *Package) ID() string { return p.Name }
@@ -23,6 +24,10 @@ func (p *Package) Validate(sys *system.System) []TestResult {
skip := false
sysPkg := sys.NewPackage(p.Name, sys, util.Config{})

if p.Skip {
skip = true
}

var results []TestResult
results = append(results, ValidateValue(p, "installed", p.Installed, sysPkg.Installed, skip))
if shouldSkip(results) {
@@ -11,6 +11,7 @@ type Port struct {
Port string `json:"-" yaml:"-"`
Listening matcher `json:"listening" yaml:"listening"`
IP matcher `json:"ip,omitempty" yaml:"ip,omitempty"`
Skip bool `json:"skip,omitempty" yaml:"skip,omitempty"`
}

func (p *Port) ID() string { return p.Port }
@@ -23,6 +24,10 @@ func (p *Port) Validate(sys *system.System) []TestResult {
skip := false
sysPort := sys.NewPort(p.Port, sys, util.Config{})

if p.Skip {
skip = true
}

var results []TestResult
results = append(results, ValidateValue(p, "listening", p.Listening, sysPort.Listening, skip))
if shouldSkip(results) {
@@ -10,6 +10,7 @@ type Process struct {
Meta meta `json:"meta,omitempty" yaml:"meta,omitempty"`
Executable string `json:"-" yaml:"-"`
Running matcher `json:"running" yaml:"running"`
Skip bool `json:"skip,omitempty" yaml:"skip,omitempty"`
}

func (p *Process) ID() string { return p.Executable }
@@ -22,6 +23,10 @@ func (p *Process) Validate(sys *system.System) []TestResult {
skip := false
sysProcess := sys.NewProcess(p.Executable, sys, util.Config{})

if p.Skip {
skip = true
}

var results []TestResult
results = append(results, ValidateValue(p, "running", p.Running, sysProcess.Running, skip))
return results
@@ -59,7 +59,16 @@ func validAttrs(i interface{}, t string) (map[string]bool, error) {
}

func shouldSkip(results []TestResult) bool {
if results[0].Err != nil || results[0].Found[0] == "false" {
if len(results) < 1 {
return false
}
if results[0].Err != nil {
return true
}
if len(results[0].Found) < 1 {
return false
}
if results[0].Found[0] == "false" {
return true
}
return false
Oops, something went wrong.

0 comments on commit e570116

Please sign in to comment.
You can’t perform that action at this time.