Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Template Support #200

Merged
merged 10 commits into from Mar 6, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
22 changes: 19 additions & 3 deletions README.md
Expand Up @@ -104,6 +104,11 @@ Total Duration: 0.021s # <- yeah, it's that fast..
Count: 15, Failed: 0

```
* Edit it to use [templates](https://github.com/aelsabbahy/goss/blob/master/docs/manual.md#templates), and run with a vars file
```
goss --vars vars.yaml validate
```

* keep running it until the system enters a valid state or we timeout
```
goss validate --retry-timeout 30s --sleep 1s
Expand All @@ -118,10 +123,11 @@ goss serve --format json &
curl localhost:8080/healthz
```

### Patterns, matchers and metadata
Goss files can be manually edited to match:
### Manually editing Goss files
Goss files can be manually edited to use:
* [Patterns](https://github.com/aelsabbahy/goss/blob/master/docs/manual.md#patterns)
* [Advanced Matchers](https://github.com/aelsabbahy/goss/blob/master/docs/manual.md#advanced-matchers).
* [Advanced Matchers](https://github.com/aelsabbahy/goss/blob/master/docs/manual.md#advanced-matchers)
* [Templates](https://github.com/aelsabbahy/goss/blob/master/docs/manual.md#templates)
* `title` and `meta` (arbitrary data) attributes are persisted when adding other resources with `goss add`

Some examples:
Expand Down Expand Up @@ -153,6 +159,16 @@ package:
- have-len: 3
- not:
contain-element: 4.4.0

# Loaded from --vars YAML/JSON file
{{.Vars.package}}:
installed: true

{{if eq .Env.OS "centos"}}
# This test is only when $OS environment variable is set to "centos"
libselinux:
installed: true
{{end}}
```

## Supported resources
Expand Down
4 changes: 2 additions & 2 deletions add.go
Expand Up @@ -14,7 +14,7 @@ import (

// Simple wrapper to add multiple resources
func AddResources(fileName, resourceName string, keys []string, c *cli.Context) error {
setStoreFormatFromFileName(fileName)
OutStoreFormat = getStoreFormatFromFileName(fileName)
config := util.Config{
IgnoreList: c.GlobalStringSlice("exclude-attr"),
Timeout: int(c.Duration("timeout") / time.Millisecond),
Expand Down Expand Up @@ -159,7 +159,7 @@ func AddResource(fileName string, gossConfig GossConfig, resourceName, key strin

// Simple wrapper to add multiple resources
func AutoAddResources(fileName string, keys []string, c *cli.Context) error {
setStoreFormatFromFileName(fileName)
OutStoreFormat = getStoreFormatFromFileName(fileName)
config := util.Config{
IgnoreList: c.GlobalStringSlice("exclude-attr"),
Timeout: int(c.Duration("timeout") / time.Millisecond),
Expand Down
13 changes: 12 additions & 1 deletion cmd/goss/goss.go
Expand Up @@ -27,6 +27,11 @@ func main() {
Usage: "Goss file to read from / write to",
EnvVar: "GOSS_FILE",
},
cli.StringFlag{
Name: "vars",
Usage: "json/yaml file containing variables for template",
EnvVar: "GOSS_VARS",
},
cli.StringFlag{
Name: "package",
Usage: "Package type to use [rpm, deb, apk, pacman]",
Expand Down Expand Up @@ -118,8 +123,14 @@ func main() {
Name: "render",
Aliases: []string{"r"},
Usage: "render gossfile after imports",
Flags: []cli.Flag{
cli.BoolFlag{
Name: "debug, d",
Usage: fmt.Sprintf("Print debugging info when rendering"),
},
},
Action: func(c *cli.Context) error {
fmt.Print(goss.RenderJSON(c.GlobalString("gossfile")))
fmt.Print(goss.RenderJSON(c))
return nil
},
},
Expand Down
1 change: 1 addition & 0 deletions development/build_images.sh
Expand Up @@ -7,6 +7,7 @@ INTEGRATION_TEST_DIR="$SCRIPT_DIR/../integration-tests/"


for docker_file in $INTEGRATION_TEST_DIR/Dockerfile_*; do
[[ $docker_file == *.md5 ]] && continue
os=$(cut -d '_' -f2 <<<"$docker_file")
docker build -t "aelsabbahy/goss_${os}:latest" - < "$docker_file"
done
1 change: 0 additions & 1 deletion development/push_images.sh
Expand Up @@ -16,4 +16,3 @@ popd
for image in $images; do
docker push "${image}:latest"
done

111 changes: 109 additions & 2 deletions docs/manual.md
Expand Up @@ -14,6 +14,7 @@
* [validate, v \- Validate the system](#validate-v---validate-the-system)
* [Important note about goss file format](#important-note-about-goss-file-format)
* [Available tests](#available-tests)
* [addr](#addr)
* [command](#command)
* [dns](#dns)
* [file](#file)
Expand All @@ -30,7 +31,7 @@
* [user](#user)
* [Patterns](#patterns)
* [Advanced Matchers](#advanced-matchers)

* [Templates](#templates)

## Usage

Expand All @@ -54,6 +55,7 @@ COMMANDS:

GLOBAL OPTIONS:
--gossfile, -g "./goss.yaml" Goss file to read from / write to [$GOSS_FILE]
--vars value json/yaml file containing variables for template [$GOSS_VARS]
--package Package type to use [rpm, deb, apk, pacman]
--help, -h show help
--generate-bash-completion
Expand All @@ -71,6 +73,13 @@ Valid formats:
* **YAML** (default)
* **JSON**

### --vars
The file to read variables from when rendering gossfile [templates](#templates).

Valid formats:
* **YAML** (default)
* **JSON**

### --package <type>
The package type to check for.

Expand Down Expand Up @@ -188,6 +197,10 @@ process:
### render, r - Render gossfile after importing all referenced gossfiles
This command allows you to keep your tests separated and render a single, valid, gossfile, by including them with the `gossfile` directive.

#### Flags
##### --debug
This prints the rendered golang template prior to printing the parsed JSON/YAML gossfile.

#### Example:
```bash

Expand Down Expand Up @@ -676,7 +689,7 @@ For the attributes that use patterns (ex. `file`, `command` `output`), each patt

**NOTE:** Pattern attributes do not support [Advanced Matchers](#advanced-matchers)

**NOTE:** Regex support is based on golangs regex engine documented [here](https://golang.org/pkg/regexp/syntax/)
**NOTE:** Regex support is based on golang's regex engine documented [here](https://golang.org/pkg/regexp/syntax/)

**NOTE:** You will **need** the double backslash (`\\`) escape for Regex special entities, for example `\\s` for blank spaces.

Expand Down Expand Up @@ -738,3 +751,97 @@ package:
For more information see:
* [gomega_test.go](https://github.com/aelsabbahy/goss/blob/master/resource/gomega_test.go) - For a complete set of supported json -> Gomega mapping
* [gomega](https://onsi.github.io/gomega/) - Gomega matchers reference

## Templates

Goss test files can leverage golang's [text/template](https://golang.org/pkg/text/template/) to allow for dynamic or conditional tests.

Available variables:
* `{{.Env}}` - Containing environment variables
* `{{.Vars}}` - Containing the values defined in [--vars](#global-options) file

Available functions beyond text/template [built-in functions](https://golang.org/pkg/text/template/#hdr-Functions):
* `mkSlice` - Retuns a slice of all the arguments. See examples below for usage.

**NOTE:** gossfiles containing text/template `{{}}` controls will no longer work with `goss add/autoadd`. One way to get around this is to split your template and static goss files and use [gossfile](#gossfile) to import.

### Examples

Using [puppetlabs/facter](https://github.com/puppetlabs/facter) or [chef/ohai](https://github.com/chef/ohai) as external tools to provide vars.
```bash
$ goss --vars <(ohai) validate
$ goss --vars <(facter -j) validate
```

Using `mkSlice` to define a loop locally.
```yaml
file:
{{- range mkSlice "/etc/passwd" "/etc/group"}}
{{.}}:
exists: true
mode: "0644"
owner: root
group: root
filetype: file
{{end}}
```

Using Env variables and a vars file:

**vars.yaml:**
```yaml
centos:
packages:
kernel:
- "4.9.11-centos"
- "4.9.11-centos2"
debian:
packages:
kernel:
- "4.9.11-debian"
- "4.9.11-debian2"
users:
- user1
- user2
```

**goss.yaml:**
```yaml
package:
# Looping over a variables defined in a vars.yaml using $OS environment variable as a lookup key
{{range $name, $vers := index .Vars .Env.OS "packages"}}
{{$name}}:
installed: true
versions:
{{range $vers}}
- {{.}}
{{end}}
{{end}}

# This test is only when OS=centos variable is defined
{{if eq .Env.OS "centos"}}
libselinux:
installed: true
{{end}}

# Loop over users
user:
{{range .Vars.users}}
{{.}}:
exists: true
groups:
- {{.}}
home: /home/{{.}}
shell: /bin/bash
{{end}}
```

Rendered results:
```bash
# To validate:
$ OS=centos goss --vars vars.yaml validate
# To render:
$ OS=centos goss --vars vars.yaml render
# To render with debugging enabled:
$ OS=centos goss --vars vars.yaml render --debug
```
2 changes: 1 addition & 1 deletion integration-tests/Dockerfile_arch.md5
@@ -1 +1 @@
b430b4a6a2ea84679f9ae705a65b2c25 Dockerfile_arch
f73a8fa9e9c0940ce2bfc09c13c3aaf5 Dockerfile_arch
8 changes: 0 additions & 8 deletions integration-tests/goss/alpine3/goss.yaml
@@ -1,13 +1,5 @@
---
package:
apache2:
installed: true
versions:
- 2.4.23-r1
service:
apache2:
enabled: true
running: true
autofs:
enabled: false
running: false
Expand Down
8 changes: 0 additions & 8 deletions integration-tests/goss/centos7/goss.yaml
@@ -1,13 +1,5 @@
---
package:
httpd:
installed: true
versions:
- 2.4.6
service:
httpd:
enabled: true
running: true
autofs:
enabled: false
running: false
Expand Down
7 changes: 7 additions & 0 deletions integration-tests/goss/goss-service.yaml
Expand Up @@ -3,3 +3,10 @@ service:
foobar:
enabled: false
running: false
{{if eq .Env.OS "centos7"}}
httpd:
{{else}}
apache2:
{{end}}
enabled: true
running: true
10 changes: 9 additions & 1 deletion integration-tests/goss/goss-shared.yaml
Expand Up @@ -11,14 +11,16 @@ command:
stderr:
- not found
file:
"/etc/passwd":
{{range mkSlice "/etc/passwd" "/etc/group"}}
{{.}}:
exists: true
mode: '0644'
owner: root
group: root
filetype: file
contains:
- root
{{end}}
"/goss/hellogoss.txt":
exists: true
md5: 7c9bb14b3bf178e82c00c2a4398c93cd
Expand All @@ -34,6 +36,12 @@ file:
package:
foobar:
installed: false
{{- range $name, $ver := index .Vars .Env.OS "packages"}}
{{$name}}:
installed: true
versions:
- {{$ver}}
{{end}}
addr:
tcp://google.com:22:
reachable: false
Expand Down
8 changes: 0 additions & 8 deletions integration-tests/goss/precise/goss.yaml
@@ -1,13 +1,5 @@
---
package:
apache2:
installed: true
versions:
- 2.2.22-1ubuntu1.11
service:
apache2:
enabled: true
running: true
autofs:
enabled: true
running: true
Expand Down
15 changes: 15 additions & 0 deletions integration-tests/goss/vars.yaml
@@ -0,0 +1,15 @@
---
alpine3:
packages:
apache2: "2.4.23-r1"
arch:
packages:
centos7:
packages:
httpd: "2.4.6"
precise:
packages:
apache2: "2.2.22-1ubuntu1.11"
wheezy:
packages:
apache2: "2.2.22-13+deb7u7"
8 changes: 0 additions & 8 deletions integration-tests/goss/wheezy/goss.yaml
@@ -1,13 +1,5 @@
---
package:
apache2:
installed: true
versions:
- 2.2.22-13+deb7u7
service:
apache2:
enabled: true
running: true
autofs:
enabled: false
running: false
Expand Down