From 602553758e5d9a7348d687cbc6893b8f44e7b687 Mon Sep 17 00:00:00 2001 From: "Axel H." Date: Sun, 12 Nov 2023 15:12:57 +0100 Subject: [PATCH] Added: MkDocs documentation and readthedocs.io configuration Fixes #853 --- .editorconfig | 18 + .github/CONTRIBUTING.md | 62 +- .github/ISSUE_TEMPLATE/feature_request.md | 2 +- .github/workflows/docs.yaml | 47 + .github/workflows/preview-docs.yaml | 23 + .gitignore | 6 + .markdownlint.yaml | 41 + .readthedocs.yaml | 19 + LICENSE | 3 +- Makefile | 26 + README.md | 102 +- docs/.pages | 12 + docs/changelog.md | 4 + docs/cli.md | 375 ++++++ docs/containers/docker-compose.md | 1 + docs/containers/docker.md | 1 + docs/containers/kubernetes.md | 1 + docs/contributing.md | 1 + docs/gossfile.md | 1027 +++++++++++++++ docs/index.md | 4 + docs/installation.md | 3 + docs/license.md | 1 + docs/manual.md | 1260 ------------------- docs/{v4_migration.md => migrations.md} | 13 +- docs/platform-feature-parity.md | 164 --- docs/platforms.md | 174 +++ docs/quickstart.md | 3 + docs/requirements.pip | 6 + docs/{goss-json-schema.yaml => schema.yaml} | 26 +- docs/style.css | 15 + extras/dcgoss/README.md | 69 +- extras/dgoss/README.md | 56 +- extras/kgoss/README.md | 11 +- mkdocs.yml | 100 ++ 34 files changed, 2124 insertions(+), 1552 deletions(-) create mode 100644 .editorconfig create mode 100644 .github/workflows/docs.yaml create mode 100644 .github/workflows/preview-docs.yaml create mode 100644 .markdownlint.yaml create mode 100644 .readthedocs.yaml create mode 100644 docs/.pages create mode 100644 docs/changelog.md create mode 100644 docs/cli.md create mode 100644 docs/containers/docker-compose.md create mode 100644 docs/containers/docker.md create mode 100644 docs/containers/kubernetes.md create mode 100644 docs/contributing.md create mode 100644 docs/gossfile.md create mode 100644 docs/index.md create mode 100644 docs/installation.md create mode 100644 docs/license.md delete mode 100644 docs/manual.md rename docs/{v4_migration.md => migrations.md} (84%) delete mode 100644 docs/platform-feature-parity.md create mode 100644 docs/platforms.md create mode 100644 docs/quickstart.md create mode 100644 docs/requirements.pip rename docs/{goss-json-schema.yaml => schema.yaml} (95%) create mode 100644 docs/style.css create mode 100644 mkdocs.yml diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 000000000..3d0042b22 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,18 @@ +# EditorConfig is awesome: https://EditorConfig.org + +# top-most EditorConfig file +root = true + +[*] +indent_style = space +indent_size = 2 +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true + +[*.md] +indent_size = 4 + +[Makefile] +indent_style = tab diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index b677e273d..1dcea61e1 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -1,9 +1,11 @@ -Contributing to Goss -==================== +# Contributing to Goss -Thank you for your interest in contributing to Goss. Goss wouldn't be where it is today if it wasn't for people like you. Some ways you can contribute: +Thank you for your interest in contributing to Goss. Goss wouldn't be where it is today if it wasn't for people like you. +Some ways you can contribute: -* Improve the [README](https://github.com/goss-org/goss/blob/master/README.md) and/or [Docs](https://github.com/goss-org/goss/blob/master/docs/manual.md) - This makes it easier for new users to learn goss. +* Improve the [README](https://github.com/goss-org/goss/blob/master/README.md) + and/or [Docs](https://github.com/goss-org/goss/blob/master/docs/). + This makes it easier for new users to learn goss. * Vote on bugs and feature requests by adding a :+1: reaction to the inital post. * Create tutorials, blog posts and example use-cases on how to use Goss. * Help users with [questions](https://github.com/goss-org/goss/labels/question) tracker. @@ -11,40 +13,52 @@ Thank you for your interest in contributing to Goss. Goss wouldn't be where it i * Implement approved [feature requests](https://github.com/goss-org/goss/issues?q=is%3Aopen+is%3Aissue+label%3Aapproved+label%3Aenhancement+sort%3Areactions-%2B1-desc). * Spread the word. +## Features and bug reports and questions -Features and bug reports and questions --------------------------------------- +Please search the [issues](https://github.com/goss-org/goss/issues) page before opening a feature request or a bug report. +If a feature or a bug report already exists, +please thumbs up the initial post to indicate it's importance to you and raise it's priority. +Please comment and contribute to said issue if you feel it's deficient. -Please search the [issues](https://github.com/goss-org/goss/issues) page before opening a feature request or a bug report. If a feature or a bug report already exists, please thumbs up the initial post to indicate it's importance to you and raise it's priority. Please comment and contribute to said issue if you feel it's deficient. - -Bug reports ------------ +## Bug reports If you think you found a bug in Goss, please submit a [bug report](https://github.com/goss-org/goss/issues). -Feature requests ----------------- +## Feature requests If there's a feature you wish Goss would support, please open a feature request. Some things to note prior to opening a Goss feature request: -* Goss is intended to be quick and easy to learn. -* Goss is focused on the 20% of the 80/20 rule. In other words, Goss focuses on the 20% of features that cover the core aspects of OS testing and benefit 80% of users. -* Goss is intended to test the local machine it's running on. Tests aren't intended to be used to validate remote systems or endpoints. -* Goss provides a generic [command](https://github.com/goss-org/goss/blob/master/docs/manual.md#command) runner to allow users to cover more nuanced test cases. -If you believe your feature adheres to the goals of Goss, please open a [feature request](https://github.com/goss-org/goss/issues) on GitHub which describes the feature you would like to see, why it is useful, and how it should work. +* Goss is intended to be quick and easy to learn. +* Goss is focused on the 20% of the 80/20 rule. + In other words, Goss focuses on the 20% of features that cover the core aspects of OS testing and benefit 80% of users. +* Goss is intended to test the local machine it's running on. + Tests aren't intended to be used to validate remote systems or endpoints. +* Goss provides a generic [command](https://goss.rocks/gossfile/#command) runner + to allow users to cover more nuanced test cases. -Once a feature is submitted, it will be reviewed. Upon approval, the issue can be worked on and PRs can be submitted that implement this new feature. +If you believe your feature adheres to the goals of Goss, +please open a [feature request](https://github.com/goss-org/goss/issues) on GitHub +which describes the feature you would like to see, why it is useful, and how it should work. +Once a feature is submitted, it will be reviewed. +Upon approval, the issue can be worked on and PRs can be submitted that implement this new feature. -Contributing code and documentation changes -------------------------------------------- +## Contributing code and documentation changes -If you have a bugfix or new feature that you would like to contribute to Goss, please find or open an issue about it first. Talk about what you would like to do. It may be that somebody is already working on it, or that there are particular issues that you should know about before implementing the change. +If you have a bugfix or new feature that you would like to contribute to Goss, please find or open an issue about it first. +Talk about what you would like to do. It may be that somebody is already working on it, +or that there are particular issues that you should know about before implementing the change. -We enjoy working with contributors to get their code accepted. There are many approaches to fixing a problem and it is important to find the best approach before writing too much code. +We enjoy working with contributors to get their code accepted. +There are many approaches to fixing a problem and it is important to find the best approach before writing too much code. -Note that it is unlikely the project will merge refactors for the sake of refactoring or niche features that aren't common use-cases (see the feature request section above). These types of pull requests have a high cost to maintainers but provide little benefit to the community. +Note that it is unlikely the project will merge refactors for the sake of refactoring +or niche features that aren't common use-cases (see the feature request section above). +These types of pull requests have a high cost to maintainers but provide little benefit to the community. -Lastly, in order for a pull request to be merged, it must provide automated tests (unit and/or integration) proving the change works as intended, this also prevents future changes from introducing regressions. It would be quite odd for a testing tool to not have a healthy approach to test automation, after all. :-) +Lastly, in order for a pull request to be merged, +it must provide automated tests (unit and/or integration) proving the change works as intended, +this also prevents future changes from introducing regressions. +It would be quite odd for a testing tool to not have a healthy approach to test automation, after all. :smile: diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md index f6d0b5594..1705c2b05 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -11,7 +11,7 @@ assignees: '' Some things to note prior to opening a Goss feature request: * Goss is intended to be quick and easy to learn. * Goss is focused on the 20% of the 80/20 rule. In other words, Goss focuses on the 20% of features that cover the core aspects of OS testing and benefit 80% of users. -* Goss provides a generic [command](https://github.com/goss-org/goss/blob/master/docs/manual.md#command) runner to allow users to cover more nuanced test cases. +* Goss provides a generic [command](https://goss.rocks/gossfile/#command) runner to allow users to cover more nuanced test cases. If after reading the above, you believe your feature is valid within the project scope please submit this feature request. diff --git a/.github/workflows/docs.yaml b/.github/workflows/docs.yaml new file mode 100644 index 000000000..6a80c4abd --- /dev/null +++ b/.github/workflows/docs.yaml @@ -0,0 +1,47 @@ +name: Documentation + +on: + push: + branches: + - master + pull_request: + paths: + - mkdocs.yml + - docs/ + - README.md + - LICENSE + - extras/**/README.md + - .github/CONTRIBUTING.md + workflow_dispatch: + +jobs: + lint: + name: Lint Documentation + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: DavidAnson/markdownlint-cli2-action@v13 + with: + globs: | + docs/**/*.md + + build: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + - uses: actions/setup-python@v4 + with: + python-version: "3.11" + cache: 'pip' + - name: Install dependencies + run: | + pip install --upgrade pip + pip install --requirement docs/requirements.pip + - name: Build documentation + run: mkdocs build + # To remove if not using github pages + - name: Upload artifact + uses: actions/upload-pages-artifact@v2 + with: + path: site diff --git a/.github/workflows/preview-docs.yaml b/.github/workflows/preview-docs.yaml new file mode 100644 index 000000000..e2aebafa7 --- /dev/null +++ b/.github/workflows/preview-docs.yaml @@ -0,0 +1,23 @@ +name: Preview documentation +on: + pull_request_target: + types: + - opened + paths: + - mkdocs.yml + - docs/ + - README.md + - LICENSE + - extras/**/README.md + - .github/CONTRIBUTING.md + +jobs: + pull-request-links: + name: Add preview link to pull-request + runs-on: ubuntu-latest + permissions: + pull-requests: write + steps: + - uses: readthedocs/actions/preview@v1 + with: + project-slug: goss diff --git a/.gitignore b/.gitignore index 728c55667..b911396ac 100644 --- a/.gitignore +++ b/.gitignore @@ -17,3 +17,9 @@ tmp/ /c.out /c.out.tmp + +# Documentation +## Virtualenv +/.venv +## MkDocs rendered site +/site diff --git a/.markdownlint.yaml b/.markdownlint.yaml new file mode 100644 index 000000000..556e87def --- /dev/null +++ b/.markdownlint.yaml @@ -0,0 +1,41 @@ +--- +# Enable all rules +default: true + +# Enforce asterisk for unordered lists +# See: https://github.com/DavidAnson/markdownlint/blob/main/doc/md004.md +MD004: + style: asterisk + +# Set list indent level to 4 which Python-Markdown requires +# See: +# - https://github.com/DavidAnson/markdownlint/blob/main/doc/md007.md +# - https://python-markdown.github.io/#differences +MD007: + indent: 4 + +# Tune `line-length` +# See: https://github.com/DavidAnson/markdownlint/blob/main/doc/md013.md +MD013: + line_length: 120 + tables: false + code_blocks: false + +# Disable `blanks-around-list` (to stay close from GitHub-flavored markdown) +# See: +# - https://github.com/DavidAnson/markdownlint/blob/main/doc/md032.md +# - https://python-markdown.github.io/#differences +MD032: false + +# Disable `no-space-in-code` +# Generate lots of false positive with admonitions and code blocks +MD038: false + +# Disable `code-blocks-style` +# Use fenced code blocks everywhere but raise false positives with admonitions +MD046: false + +# Disable `link-fragments` +# Only works for github-rendered markdown (which does not have the same rules as MkDocs) +# See: https://github.com/DavidAnson/markdownlint/blob/main/doc/md051.md +MD051: false diff --git a/.readthedocs.yaml b/.readthedocs.yaml new file mode 100644 index 000000000..3166424d8 --- /dev/null +++ b/.readthedocs.yaml @@ -0,0 +1,19 @@ +# Read the Docs configuration file for MkDocs projects +# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details + +# Required +version: 2 + +# Set the version of Python and other tools you might need +build: + os: ubuntu-22.04 + tools: + python: "3.12" + +mkdocs: + configuration: mkdocs.yml + +# Optionally declare the Python requirements required to build your docs +python: + install: + - requirements: docs/requirements.pip diff --git a/LICENSE b/LICENSE index 8f71f43fe..c8c84af1d 100644 --- a/LICENSE +++ b/LICENSE @@ -186,7 +186,7 @@ same "printed page" as the copyright notice for easier identification within third-party archives. - Copyright {yyyy} {name of copyright owner} + Copyright 2015 Ahmed Elsabbahy Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -199,4 +199,3 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. - diff --git a/Makefile b/Makefile index 6aec096d1..dfbac4da0 100644 --- a/Makefile +++ b/Makefile @@ -5,6 +5,9 @@ pkgs = $(shell ./novendor.sh) cmd = goss GO111MODULE=on GO_FILES = $(shell git ls-files -- '*.go' ':!:*vendor*_test.go') +VENV := $(shell echo $${VIRTUAL_ENV-.venv}) +PYTHON := $(VENV)/bin/python +DOCS_DEPS := $(VENV)/.docs.dependencies .PHONY: all build install test release bench fmt lint vet test-int-all gen centos7 wheezy trusty alpine3 arch test-int32 centos7-32 wheezy-32 trusty-32 alpine3-32 arch-32 @@ -73,6 +76,8 @@ gen: clean: $(info INFO: Starting build $@) rm -rf ./release + rm -rf ./site + rm -rf ${VENV} build-images: $(info INFO: Starting build $@) @@ -130,3 +135,24 @@ arch: build dgoss-sha256: cd extras/dgoss/ && sha256sum dgoss > dgoss.sha256 + +$(PYTHON): + $(info Creating virtualenv in $(VENV)) + @python -m venv $(VENV) + +$(DOCS_DEPS): $(PYTHON) docs/requirements.pip + $(info Installing dependencies) + @pip install --upgrade pip + @pip install --requirement docs/requirements.pip + @touch $(DOCS_DEPS) + +docs/setup: $(DOCS_DEPS) + +docs/serve: docs/setup + $(info Running documentation live development server) + @mkdocs serve --strict + +.PHONY: docs +docs: docs/setup + $(info Building documentation) + @mkdocs build --strict diff --git a/README.md b/README.md index dc03e7508..3547ada28 100644 --- a/README.md +++ b/README.md @@ -2,14 +2,21 @@ [![Build Status](https://travis-ci.org/goss-org/goss.svg?branch=master)](https://travis-ci.org/goss-org/goss) [![Github All Releases](https://img.shields.io/github/downloads/goss-org/goss/total.svg?maxAge=604800)](https://github.com/goss-org/goss/releases) +[![Documentation Status](https://readthedocs.org/projects/goss/badge/)](https://goss.rocks/) ** [![Blog](https://img.shields.io/badge/follow-blog-brightgreen.svg)](https://medium.com/@aelsabbahy) + + ## Goss in 45 seconds + asciicast + -**Note:** For testing docker containers see the [dgoss](https://github.com/goss-org/goss/tree/master/extras/dgoss) wrapper. Also, user submitted wrapper scripts for Kubernetes [kgoss](https://github.com/goss-org/goss/tree/master/extras/kgoss) and Docker Compose [dcgoss](https://github.com/goss-org/goss/tree/master/extras/dcgoss). +**Note:** For testing docker containers see the [dgoss](https://github.com/goss-org/goss/tree/master/extras/dgoss) wrapper. +Also, user submitted wrapper scripts for Kubernetes [kgoss](https://github.com/goss-org/goss/tree/master/extras/kgoss) +and Docker Compose [dcgoss](https://github.com/goss-org/goss/tree/master/extras/dcgoss). **Note:** For some Docker/Kubernetes healthcheck, health endpoint, and container ordering examples, see my blog post @@ -19,7 +26,9 @@ container ordering examples, see my blog post ### What is Goss? -Goss is a YAML based [serverspec](http://serverspec.org/) alternative tool for validating a server’s configuration. It eases the process of writing tests by allowing the user to generate tests from the current system state. Once the test suite is written they can be executed, waited-on, or served as a health endpoint. +Goss is a YAML based [serverspec](http://serverspec.org/) alternative tool for validating a server's configuration. +It eases the process of writing tests by allowing the user to generate tests from the current system state. +Once the test suite is written they can be executed, waited-on, or served as a health endpoint. ### Why use Goss? @@ -43,6 +52,9 @@ curl -fsSL https://goss.rocks/install | sh curl -fsSL https://goss.rocks/install | GOSS_VER=v0.3.16 GOSS_DST=~/bin sh ``` + + + ### Manual installation #### Latest @@ -77,15 +89,20 @@ chmod +rx /usr/local/bin/dgoss make build ``` + + ## Full Documentation -Documentation is available here: [manual](https://github.com/goss-org/goss/blob/master/docs/manual.md) +Documentation is available at ## Quick start + + ### Writing a simple sshd test -An initial set of tests can be derived from the system state by using the [add](https://github.com/goss-org/goss/blob/master/docs/manual.md#add-a---add-system-resource-to-test-suite) or [autoadd](https://github.com/goss-org/goss/blob/master/docs/manual.md#autoadd-aa---auto-add-all-matching-resources-to-test-suite) commands. +An initial set of tests can be derived from the system state by using the [add](https://goss.rocks/cli/#add) +or [autoadd](https://goss.rocks/cli/#autoadd) commands. Let's write a simple sshd test using autoadd. @@ -97,7 +114,6 @@ $ sudo goss autoadd sshd Generated `goss.yaml`: ```yaml -$ cat goss.yaml port: tcp:22: listening: true @@ -133,59 +149,67 @@ Now that we have a test suite, we can: * Run it once -```txt -goss validate +```console +$ goss validate ............... Total Duration: 0.021s # <- yeah, it's that fast.. Count: 15, Failed: 0 ``` -* Edit it to use [templates](https://github.com/goss-org/goss/blob/master/docs/manual.md#templates), and run with a vars file +* Edit it to use [templates](https://goss.rocks/gossfile/#templates), and run with a vars file -```txt +```console goss --vars vars.yaml validate ``` * keep running it until the system enters a valid state or we timeout -```txt +```console goss validate --retry-timeout 30s --sleep 1s ``` * serve the tests as a health endpoint -```txt -goss serve & -curl localhost:8080/healthz +```console +$ goss serve & +$ curl localhost:8080/healthz # JSON endpoint -goss serve --format json & -curl localhost:8080/healthz +$ goss serve --format json & +$ curl localhost:8080/healthz # rspecish response via content negotiation -goss serve --format json & -curl -H "Accept: application/vnd.goss-rspecish" localhost:8080/healthz +$ goss serve --format json & +$ curl -H "Accept: application/vnd.goss-rspecish" localhost:8080/healthz ``` ### Manually editing Goss files Goss files can be manually edited to improve readability and expressiveness of tests. -A [Json draft 7 schema](https://github.com/json-schema-org/json-schema-spec/blob/draft-07/schema.json) available in [docs/goss-json-schema.yaml](./docs/goss-json-schema.yaml) makes it easier to edit simple goss.yaml files in IDEs, providing usual coding assistance such as inline documentation, completion and static analysis. See [PR 793](https://github.com/goss-org/goss/pull/793) for screenshots. +A [Json draft 7 schema](https://github.com/json-schema-org/json-schema-spec/blob/draft-07/schema.json) available +at makes it easier to edit simple goss.yaml files in IDEs, +providing usual coding assistance such as inline documentation, completion and static analysis. +See #793 for screenshots. -For example, to configure the Json schema in JetBrains intellij IDEA, follow [documented instructions](https://www.jetbrains.com/help/idea/json.html#ws_json_schema_add_custom), with arguments such as `schema url=https://raw.githubusercontent.com/goss-org/goss/master/docs/goss-json-schema.yaml`, `schema version=Json schema version 7`, `file path pattern=*/goss.yaml` +For example, to configure the Json schema in JetBrains intellij IDEA, +follow [documented instructions](https://www.jetbrains.com/help/idea/json.html#ws_json_schema_add_custom), +with arguments such as: +* `schema url=https://goss.rocks/schema.yaml` +* `schema version=Json schema version 7` +* `file path pattern=*/goss.yaml` In addition, Goss files can also be further manually edited (without yet full json support) to use: -* [Patterns](https://github.com/goss-org/goss/blob/master/docs/manual.md#patterns) -* [Advanced Matchers](https://github.com/goss-org/goss/blob/master/docs/manual.md#advanced-matchers) -* [Templates](https://github.com/goss-org/goss/blob/master/docs/manual.md#templates) +* [Patterns](https://goss.rocks/gossfile/#patterns) +* [Advanced Matchers](https://goss.rocks/gossfile/#advanced-matchers) +* [Templates](https://goss.rocks/gossfile/#templates) * `title` and `meta` (arbitrary data) attributes are persisted when adding other resources with `goss add` Some examples: -```yaml +```yaml+jinja user: sshd: title: UID must be between 50-100, GID doesn't matter. home is flexible @@ -225,19 +249,20 @@ package: {{end}} ``` -Goss.yaml files with templates can still be validated through the Json schema after being rendered using the `goss render` command. See example below +Goss.yaml files with templates can still be validated through the Json schema after being rendered +using the `goss render` command. See example below -```bash -cd docs -goss --vars ./vars.yaml render > rendered_goss.yaml -# proceed with json schema validation of rendered_goss.yaml in your favorite IDE +```console +$ cd docs +$ goss --vars ./vars.yaml render > rendered_goss.yaml +# proceed with json schema validation of rendered_goss.yaml in your favorite IDE # or in one of the Json schema validator listed in https://json-schema.org/implementations.html -# The following example is for a Linux AMD64 host -curl -LO https://github.com/neilpa/yajsv/releases/download/v1.4.1/yajsv.linux.amd64 -chmod a+x yajsv.linux.amd64 -sudo mv yajsv.linux.amd64 /usr/sbin/yajsv +# The following example is for a Linux AMD64 host +$ curl -LO https://github.com/neilpa/yajsv/releases/download/v1.4.1/yajsv.linux.amd64 +$ chmod a+x yajsv.linux.amd64 +$ sudo mv yajsv.linux.amd64 /usr/sbin/yajsv -yajsv -s goss-json-schema.yaml rendered_goss.yaml +$ yajsv -s goss-json-schema.yaml rendered_goss.yaml rendered_goss.yaml: fail: process.chrome: skip is required rendered_goss.yaml: fail: service.sshd: skip is required @@ -246,7 +271,10 @@ rendered_goss.yaml: fail: process.chrome: skip is required rendered_goss.yaml: fail: service.sshd: skip is required ``` -Full list of available Json schema validators can be found in https://json-schema.org/implementations.html#validator-command%20line +Full list of available Json schema validators can be found in + + + ## Supported resources @@ -280,6 +308,7 @@ Full list of available Json schema validators can be found in https://json-schem ## Community Contributions + * [goss-ansible](https://github.com/indusbox/goss-ansible) - Ansible module for Goss. * [degoss](https://github.com/naftulikay/ansible-role-degoss) - Ansible role for installing, running, and removing Goss in a single go. * [kitchen-goss](https://github.com/ahelal/kitchen-goss) - A test-kitchen verifier plugin for Goss. @@ -287,6 +316,7 @@ Full list of available Json schema validators can be found in https://json-schem * [molecule](https://github.com/metacloud/molecule) - Automated testing for Ansible roles, with native Goss support. * [packer-provisioner-goss](https://github.com/YaleUniversity/packer-provisioner-goss) - A packer plugin to run Goss as a provision step. * [gossboss](https://github.com/mdb/gossboss) - Collect and view aggregated Goss test results from multiple remote Goss servers. + ## Limitations @@ -309,4 +339,6 @@ Service: * Upstart [kubernetes-simplified-health-checks]: https://medium.com/@aelsabbahy/docker-1-12-kubernetes-simplified-health-checks-and-container-ordering-with-goss-fa8debbe676c -[platform-feature-parity]: docs/platform-feature-parity.md +[platform-feature-parity]: https://goss.rocks/platforms + + diff --git a/docs/.pages b/docs/.pages new file mode 100644 index 000000000..67373453b --- /dev/null +++ b/docs/.pages @@ -0,0 +1,12 @@ +nav: + - Home: index.md + - installation.md + - quickstart.md + - Command Reference: cli.md + - The gossfile: gossfile.md + - migrations.md + - platforms.md + - containers + - Contributing: contributing.md + - changelog.md + - license.md diff --git a/docs/changelog.md b/docs/changelog.md new file mode 100644 index 000000000..d2ae96ae2 --- /dev/null +++ b/docs/changelog.md @@ -0,0 +1,4 @@ +# Changelog + +`Goss` does not (yet?) maintain a changelog file. +However, you can consult [Goss releases](https://github.com/goss-org/goss/releases). diff --git a/docs/cli.md b/docs/cli.md new file mode 100644 index 000000000..d7b1bf62e --- /dev/null +++ b/docs/cli.md @@ -0,0 +1,375 @@ +# Command Line Interface + +## Usage + +```console +NAME: + goss - Quick and Easy server validation + +USAGE: + goss [global options] command [command options] [arguments...] + +VERSION: + 0.0.0 + +COMMANDS: + validate, v Validate system + serve, s Serve a health endpoint + render, r render gossfile after imports + autoadd, aa automatically add all matching resource to the test suite + add, a add a resource to the test suite + help, h Shows a list of commands or help for one command + +GLOBAL OPTIONS: + --gossfile value, -g value Goss file to read from / write to (default: "./goss.yaml") [$GOSS_FILE] + --vars value json/yaml file containing variables for template [$GOSS_VARS] + --vars-inline value json/yaml string containing variables for template (overwrites vars) [$GOSS_VARS_INLINE] + --package value Package type to use [rpm, deb, apk, pacman] + --help, -h show help + --version, -v print the version +``` + +!!! note + Most flags can be set by using environment variables, see `--help` for more info. + +## Global options + +`--gossfile/-g ` +: The file to use when reading/writing tests. Use `--gossfile -` or `-g -` to read from `STDIN`. + + Valid formats: + * `yaml` *(default)* + * `json` + +`--vars ` +: The file to read variables from when rendering gossfile [templates](gossfile.md#templates). + + Valid formats: + + * `yaml` *(default)* + * `json` + +`--package ` +: The package type to check for. + + Valid options are: + + * `apk` + * `deb` + * `pacman` + * `rpm` + +## Commands + +Commands are the actions goss can run. +- [add](#add): add a single test for a resource +- [autoadd](#autoadd): automatically add multiple tests for a resource +- [render](#render): renders and outputs the gossfile, importing all included gossfiles +- [serve](#serve): serves the gossfile validation as an HTTP endpoint on a specified address and port, + so you can use your gossfile as a health report for the host +- [validate](#validate): runs the goss test suite on your server + +### `add` + +!!! abstract "Add system resource to test suite" + ```console + goss add [--exclude-attr ] [] + goss a [--exclude-attr ] [] + ``` + +This will add a test for a resource. Non existent resources will add a test to ensure they do not exist on the system. +A sub-command *resource type* has to be provided when running `add`. + +`--exclude-attr` +: Ignore **non-required** attribute(s) matching the provided glob when adding a new resource, + may be specified multiple times. + +!!! example + ```console + goss add file /etc/passwd + goss a user nobody + goss add --exclude-attr home --exclude-attr shell user nobody + goss a --exclude-attr '*' user nobody + ``` + +#### Resources types + +| Type | Description | +|--------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------| +| [`addr`](gossfile.md#addr) | Verify if a remote `address:port` is reachable | +| [`command`](gossfile.md#command) | Run a [command](gossfile.md#command) and validate the exit status and/or output | +| [`dns`](gossfile.md#dns) | Resolves a [dns](gossfile.md#dns) name and validates the addresses | +| [`file`](gossfile.md#file) | Validate a [file](gossfile.md#file) existence, permissions, stats (size, etc) and contents | +| [`goss`](gossfile.md#gossfile) | Includes the contents of another [gossfile](gossfile.md) | +| [`group`](gossfile.md#group) | can validate the existence and values of a [group](gossfile.md#group) on the system | +| [`http`](gossfile.md#http) | Validate the HTTP response code, headers, and content of a URI | +| [`interface`](gossfile.md#interface) | Validate the existence and values (es. the addresses) of a network interface | +| [`kernel-param`](gossfile.md#kernel-param) | Validate kernel parameters (sysctl values) | +| [`mount`](gossfile.md#mount) | Validate the existence and options relative to a [mount](gossfile.md#mount) point | +| [`package`](gossfile.md#package) | Validate the status of a [package](gossfile.md#package) using the package manager specified on the commandline with `--package` | +| [`port`](gossfile.md#port) | Validate the status of a local [port](gossfile.md#port), for example `80` or `udp:123` | +| [`process`](gossfile.md#process) | Validate the status of a [process](gossfile.md#process) | +| [`service`](gossfile.md#service) | Validate if a [service](gossfile.md#service) is running and/or enabled at boot | +| [`user`](gossfile.md#user) | Validate the existence and values of a [user](gossfile.md#user) on the system | + +### `autoadd` + +!!! abstract "Auto add all matching resources to test suite" + ```console + goss autoadd [arguments...] + goss aa [arguments...] + ``` + +Automatically [adds](#add) all **existing** resources matching the provided argument. + +Will automatically add the following matching resources: +- `file` - only if argument contains `/` +- `group` +- `package` +- `port` +- `process` - Also adding any ports it's listening to (if run as root) +- `service` +- `user` + +Will **NOT** automatically add: +- `addr` +- `command` - for safety +- `dns` +- `http` +- `interface` +- `kernel-param` +- `mount` + +!!! example + ```console + goss autoadd sshd + ``` + + Generates the following `goss.yaml` + + ```yaml + port: + tcp:22: + listening: true + ip: + - 0.0.0.0 + tcp6:22: + listening: true + ip: + - '::' + service: + sshd: + enabled: true + running: true + user: + sshd: + exists: true + uid: 74 + gid: 74 + groups: + - sshd + home: /var/empty/sshd + shell: /sbin/nologin + group: + sshd: + exists: true + gid: 74 + process: + sshd: + running: true + ``` + +### `render` + +!!! abstract "Render gossfile after importing all referenced gossfiles" + ``` + goss render + goss r + ``` + +This command allows you to keep your tests separated and render a single, valid, gossfile, +by including them with the `gossfile` directive. + +`--debug` +: This prints the rendered golang template prior to printing the parsed JSON/YAML gossfile. + +!!! example + ```console + $ cat goss_httpd_package.yaml + package: + httpd: + installed: true + versions: + - 2.2.15 + + $ cat goss_httpd_service.yaml + service: + httpd: + enabled: true + running: true + + $ cat goss_nginx_service-NO.yaml + service: + nginx: + enabled: false + running: false + + $ cat goss.yaml + gossfile: + goss_httpd_package.yaml: {} + goss_httpd_service.yaml: {} + goss_nginx_service-NO.yaml: {} + + $ goss -g goss.yaml render + package: + httpd: + installed: true + versions: + - 2.2.15 + service: + httpd: + enabled: true + running: true + nginx: + enabled: false + running: false + ``` + +### `serve` + +!!! abstract "Serve a health endpoint" + ```console + goss serve [...] + goss s [...] + ``` + +`serve` exposes the goss test suite as a health endpoint on your server. +The end-point will return the stest results in the format requested and an http status of 200 or 503. + +`serve` will look for a test suite in the same order as [validate](#validate) + +`--cache `, `-c ` +: Time to cache the results (default: 5s) + +`--endpoint `, `-e ` +: Endpoint to expose (default: `/healthz`) + +`--format `, `-f ` +: Output format, same as [validate](#validate) + +`--listen-addr [ip]:port`, `-l [ip]:port` +: Address to listen on (default: `:8080`) + +`--loglevel `, `-L ` +: Goss logging verbosity level (default: `INFO`). + Lower levels of tracing include all upper levels traces also (ie. `INFO` include `WARN` and `ERROR`). + `level` can be one of: + - `ERROR` - Critical errors that halt goss or significantly affect its functionality, requiring immediate intervention. + - `WARN` - Non-critical issues that may require attention, such as overwritten keys or deprecated features. + - `INFO` - General operational messages, useful for tasks where a more structured output is needed (e.g. goss serve). + - `DEBUG` - Information useful for the goss user to debug. + - `TRACE` - Detailed internal system activities useful for goss developers to debug. + +`--max-concurrent ` +: Max number of tests to run concurrently + +!!! example + ```console + $ goss serve & + $ curl http://localhost:8080/healthz + # JSON endpoint + $ goss serve --format json & + $ curl localhost:8080/healthz + # rspecish output format in response via content negotiation + goss serve --format json & + curl -H "Accept: application/vnd.goss-rspecish" localhost:8080/healthz + ``` + +The `application/vnd.goss-{output format}` media type can be used in the `Accept` request header +to determine the response's content-type. +You can also `Accept: application/json` to get back `application/json`. + +### `validate` + +!!! abstract "Validate the system" + ```console + goss validate [...] + goss v [...] + ``` + +`validate` runs the goss test suite on your server. Prints an rspec-like (by default) output of test results. +Exits with status 0 on success, non-0 otherwise. + +`--format `, `-f ` +: Output format. Can be one of: + - `documentation` - Verbose test results + - `json` - Detailed test result on a single line (See `pretty` format option) + - `junit` + - `nagios` - Nagios/Sensu compatible output /w exit code 2 for failures + - `rspecish` **(default)** - Similar to rspec output + - `tap` + - `prometheus` - Prometheus compatible output. + - `silent` - No output. Avoids exposing system information (e.g. when serving tests as a healthcheck endpoint) + +`--format-options`, `-o` +: Output format option: + - `perfdata` - Outputs Nagios "performance data". Applies to `nagios` output + - `verbose` - Gives verbose output. Applies to `nagios` and `prometheus` output + - `pretty` - Pretty printing for the `json` output + - `sort` - Sorts the results + +`--loglevel `, `-L ` +: Goss logging verbosity level (default: `INFO`). + Lower levels of tracing include all upper levels traces also (ie. `INFO` includes `WARN`, `ERROR` and `FATAL` outputs). + `level` can be one of : + - `TRACE` - Print details for each check, successful or not and all incoming healthchecks + - `DEBUG` - Print details of summary response to healthchecks including remote IP address, return code and full body + - `INFO` - Print summary when all checks run OK + - `WARN` - Print summary and corresponding checks when encountering some failures + - `ERROR` - Not used for now (will not print anything) + - `FATAL` - Not used for now (will not print anything) + +`--max-concurrent ` +: Max number of tests to run concurrently + +`--color`/`--no-color` +: Force color or disable color + +`--retry-timeout `, `-r ` +: Retry on failure so long as elapsed + sleep time is less than this + + *default: `0`* + +`--sleep `, `-s ` +: Time to sleep between retries + + *default: `1s`* + +!!! example + + ```console + $ goss validate --format documentation + File: /etc/hosts: exists: matches expectation: [true] + DNS: localhost: resolvable: matches expectation: [true] + [...] + Total Duration: 0.002s + Count: 10, Failed: 2, Skipped: 0 + + $ curl -s https://static/or/dynamic/goss.json | goss validate + ...F.F + [...] + Total Duration: 0.002s + Count: 6, Failed: 2, Skipped: 0 + + $ goss render | ssh remote-host 'goss -g - validate' + ...... + + Total Duration: 0.002s + Count: 6, Failed: 0, Skipped: 0 + + $ goss validate --format nagios -o verbose -o perfdata + GOSS CRITICAL - Count: 76, Failed: 1, Skipped: 0, Duration: 1.009s|total=76 failed=1 skipped=0 duration=1.009s + Fail 1 - DNS: localhost: addrs: doesn't match, expect: [["127.0.0.1","::1"]] found: [["127.0.0.1"]] + $ echo $? + 2 + ``` diff --git a/docs/containers/docker-compose.md b/docs/containers/docker-compose.md new file mode 100644 index 000000000..9219adf97 --- /dev/null +++ b/docs/containers/docker-compose.md @@ -0,0 +1 @@ +--8<-- "extras/dcgoss/README.md" diff --git a/docs/containers/docker.md b/docs/containers/docker.md new file mode 100644 index 000000000..07daf5c87 --- /dev/null +++ b/docs/containers/docker.md @@ -0,0 +1 @@ +--8<-- "extras/dgoss/README.md" diff --git a/docs/containers/kubernetes.md b/docs/containers/kubernetes.md new file mode 100644 index 000000000..b696d2f54 --- /dev/null +++ b/docs/containers/kubernetes.md @@ -0,0 +1 @@ +--8<-- "extras/kgoss/README.md" diff --git a/docs/contributing.md b/docs/contributing.md new file mode 100644 index 000000000..0c7bc9cbf --- /dev/null +++ b/docs/contributing.md @@ -0,0 +1 @@ +--8<-- ".github/CONTRIBUTING.md" diff --git a/docs/gossfile.md b/docs/gossfile.md new file mode 100644 index 000000000..fc264c9c2 --- /dev/null +++ b/docs/gossfile.md @@ -0,0 +1,1027 @@ +# The `gossfile` configuration + +## Goss test creation + +Goss tests can be created by using either of following methods. + +1. `goss autoadd ` +2. `goss add ` +3. manually create YAML/JSON test file by hand. + +To customize the parameters generated by `goss add` and `goss autoadd` YAML file you need to manually edit it. + +`goss add package nginx` will generate below YAML + +```yaml +package: + nginx: + installed: true + versions: + - 1.17.8 +``` + +To test uninstall scenario you would need to manually edit it and set it as below. + +```yaml +package: + nginx: + installed: false +``` + +## Important note about goss file format + +It is important to note that both YAML and JSON are formats that describe a nested data structure. + +```yaml title="WRONG way to write a goss file" +file: + /etc/httpd/conf/httpd.conf: + exists: true + +service: + httpd: + enabled: true + running: true + +file: + /var/www/html: + filetype: directory + exists: true +``` + +If you try to validate this file, it will **only** run the second `file` test: + +```console +$ goss validate --format documentation +File: /var/www/html: exists: matches expectation: [true] +File: /var/www/html: filetype: matches expectation: ["directory"] +Service: httpd: enabled: matches expectation: [true] +Service: httpd: running: matches expectation: [true] + +Total Duration: 0.014s +Count: 8, Failed: 0, Skipped: 0 +``` + +As you can see, the first `file` check has not been run because the second `file` entry *overwrites* the previous one. + +You need to make sure all the entries of the same type are under the same declaration. + +```yaml title="This is the CORRECT way to write a goss file" +file: + /etc/httpd/conf/httpd.conf: + exists: true + /var/www/html: + filetype: directory + exists: true + +service: + httpd: + enabled: true + running: true +``` + +Running validate with this configuration will correctly check both files: + +```console +$ goss validate --format documentation +File: /var/www/html: exists: matches expectation: [true] +File: /var/www/html: filetype: matches expectation: ["directory"] +File: /etc/httpd/conf/httpd.conf: exists: matches expectation: [true] +Service: httpd: enabled: matches expectation: [true] +Service: httpd: running: matches expectation: [true] + +Total Duration: 0.014s +Count: 10, Failed: 0, Skipped: 0 +``` + +Please note that using the `goss add` and `goss autoadd` command will create a valid file, +but if you're writing your files by hand you'll save a lot of time by taking this in consideration. + +If you want to keep your tests in separate files, the best way to obtain a single, valid, +file is to create a main goss file that includes the others with the [gossfile](#gossfile) directive +and then [render](cli.md#render) it. + +### Schema + +A [Json draft 7 schema](https://github.com/json-schema-org/json-schema-spec/blob/draft-07/schema.json) +available at +makes it easier to edit simple goss.yaml files in IDEs, providing usual coding assistance +such as inline documentation, completion and static analysis. +See #793 for screenshots. + +For example, to configure the Json schema in JetBrains intellij IDEA, +follow [documented instructions](https://www.jetbrains.com/help/idea/json.html#ws_json_schema_add_custom), +with arguments such as: + +* `schema url=https://goss.rocks/schemas/gossfile.yaml` +* `schema version=Json schema version 7` +* `file path pattern=*/goss.yaml` + +## Available tests + +* [addr](#addr) +* [command](#command) +* [dns](#dns) +* [file](#file) +* [gossfile](#gossfile) +* [group](#group) +* [http](#http) +* [interface](#interface) +* [kernel-param](#kernel-param) +* [matching](#matching) +* [mount](#mount) +* [package](#package) +* [port](#port) +* [process](#process) +* [service](#service) +* [user](#user) + +### addr + +Validates if a remote `address:port` are accessible. + +```yaml +addr: + tcp://ip-address-or-domain-name:80: + # required attributes + reachable: true + # optional attributes + # defaults to hash key + address: "tcp://ip-address-or-domain-name:80" + timeout: 500 + local-address: 127.0.0.1 +``` + +### command + +Validates the exit-status and output of a command. +This can be used in combination with the [gjson](#gjson) matcher to create powerful goss custom tests. + +```yaml +command: + 'go version': + # required attributes + exit-status: 0 + # optional attributes + # defaults to hash key + exec: "go version" + 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. + +```yaml +dns: + localhost: + # required attributes + resolvable: true + # optional attributes + # defaults to hash key + resolve: localhost + addrs: + - 127.0.0.1 + - ::1 + server: 8.8.8.8 # Also supports server:port + timeout: 500 # in milliseconds (Only used when server attribute is provided) +``` + +It is possible to validate the following types of DNS records, but requires the ```server``` attribute be set: + +* `A` +* `AAAA` +* `CAA` +* `CNAME` +* `MX` +* `NS` +* `PTR` +* `SRV` +* `TXT` + +To validate specific DNS address types, prepend the hostname with the type and a colon, a few examples: + +```yaml +dns: + # Validate a CNAME record + CNAME:c.dnstest.io: + resolvable: true + server: 208.67.222.222 + addrs: + - "a.dnstest.io." + + # Validate a PTR record + PTR:8.8.8.8: + resolvable: true + server: 8.8.8.8 + addrs: + - "dns.google." + + # Validate and SRV record + SRV:_https._tcp.dnstest.io: + resolvable: true + server: 208.67.222.222 + addrs: + - "0 5 443 a.dnstest.io." + - "10 10 443 b.dnstest.io." +``` + +Please note that if you want `localhost` to **only** resolve `127.0.0.1` you'll need to use [Advanced Matchers](#advanced-matchers) + +```yaml +dns: + localhost: + resolvable: true + addrs: + consist-of: [127.0.0.1] + timeout: 500 # in milliseconds +``` + +### file + +Validates the state of a file, directory, socket, or symbolic link + +```yaml +file: + /etc/passwd: + # required attributes + exists: true + # optional attributes + # defaults to hash key + path: /etc/passwd + mode: "0644" + size: 2118 # in bytes + owner: root + group: root + filetype: file # file, symlink, directory, socket + contents: [] # Check file content for these patterns + md5: 7c9bb14b3bf178e82c00c2a4398c93cd # md5 checksum of file + # A stronger checksum alternatives to md5 (recommended) + sha256: 7f78ce27859049f725936f7b52c6e25d774012947d915e7b394402cfceb70c4c + sha512: cb71b1940dc879a3688bd502846bff6316dd537bbe917484964fe0f098e9245d80958258dc3bd6297bf42d5bd978cbe2c03d077d4ed45b2b1ed9cd831ceb1bd0 + /etc/alternatives/mta: + # required attributes + exists: true + # optional attributes + filetype: symlink # file, symlink, directory, socket + linked-to: /usr/sbin/sendmail.sendmail + skip: false +``` + +`contents` can be a string or a [pattern](#patterns) + +### gossfile + +Import other gossfiles from this one. This is the best way to maintain a large number of tests, and/or create profiles. +See [render](cli.md#render) for more examples. Glob patterns can be also be used to specify matching gossfiles. + +```yaml +gossfile: + myapplication: + file: myapp_gossfile.yaml + skip: false + *.yaml: + skip: true + goss_httpd.yaml: {} + /etc/goss.d/*.yaml: {} +``` + +You can specify the gossfile(s) either as the resource key, or using the 'file' attribute. + +If the 'skip' attribute is true, then the file is not processed. +If the filename is a glob pattern, then none of the matching files are processed. +Note that this is not the same as skipping the contained resources; +any overrides in the referenced gossfile will not be processed, and the resource count will not be incremented. +Skipping a gossfile include is the same as omitting the gossfile resource entirely. + +### group + +Validates the state of a group + +```yaml +group: + nfsnobody: + # required attributes + exists: true + # optional attributes + # defaults to hash key + groupname: /etc/passwd + gid: 65534 + skip: false +``` + +### http + +Validates HTTP response status code and content. + +```yaml +http: + https://www.google.com: + # required attributes + status: 200 + # optional attributes + # defaults to hash key + url: https://www.google.com + allow-insecure: false + no-follow-redirects: false # Setting this to true will NOT follow redirects + timeout: 1000 + request-headers: # Set request header values + - "Content-Type: text/html" + headers: [] # Check http response headers for these patterns (e.g. "Content-Type: text/html") + request-body: '{"key": "value"}' # request body + body: [] # Check http response content for these patterns + username: "" # username for basic auth + password: "" # password for basic auth + ca-file: "" # CA root certs pem file, ex: /etc/ssl/cert.pem + cert-file: "" # certificate file to use for authentication (used with key-file) + key-file: "" # private-key file to use for authentication (used with cert-file) + proxy: "" # proxy server to proxy traffic through. Proxy can also be set with environment variables http_proxy. + skip: false + method: PUT # http method +``` + +!!! note + only the first `Host` header will be used to set the `Request.Host` value if multiple are provided. + +### interface + +Validates network interface values + +```yaml +interface: + eth0: + # required attributes + exists: true + # optional attributes + # defaults to hash key + name: eth0 + addrs: + - 172.17.0.2/16 + - fe80::42:acff:fe11:2/64 + mtu: 1500 +``` + +### kernel-param + +Validates kernel param (sysctl) value. + +```yaml +kernel-param: + kernel.ostype: + # required attributes + value: Linux + # optional attributes + # defaults to hash key + name: kernel.ostype +``` + +To see the full list of current values, run `sysctl -a`. + +### mount + +Validates mount point attributes. + +```yaml +mount: + /home: + # required attributes + exists: true + # optional attributes + # defaults to hash key + mountpoint: /home + opts: + - rw + - relatime + # This maps to the per-superblock options, see: + # https://man7.org/linux/man-pages/man5/proc.5.html + # https://man7.org/linux/man-pages/man2/mount.2.html + vfs-opts: + - rw + source: /dev/mapper/fedora-home + filesystem: xfs + usage: #% of blocks used in this mountpoint + lt: 95 +``` + +### matching + +Validates specified content against a matcher. Best used with [Templates](#templates). + +#### With [Templates](#templates) + +Let's say we have a `data.json` file that gets generated as part of some testing pipeline: + +```json +{ + "instance_count": 14, + "failures": 3, + "status": "FAIL" +} +``` + +This could then be passed into goss: `goss --vars data.json validate` + +And then validated against: + +```yaml+jinja +matching: + check_instance_count: # Make sure there is at least one instance + content: {{ .Vars.instance_count }} + matches: + gt: 0 + + check_failure_count_from_all_instance: # expect no failures + content: {{ .Vars.failures }} + matches: 0 + + check_status: + content: {{ .Vars.status }} + matches: + - not: FAIL +``` + +#### Without [Templates](#templates) + +```yaml +matching: + has_substr: # friendly test name + content: some string + matches: + match-regexp: some str + has_2: + content: + - 2 + matches: + contain-element: 2 + has_foo_bar_and_baz: + content: + foo: bar + baz: bing + matches: + and: + - have-key: baz +``` + +### package + +Validates the state of a package + +```yaml +package: + httpd: + # required attributes + installed: true + # optional attributes + # defaults to hash key + name: httpd + versions: + - 2.2.15 + skip: false +``` + +!!! note + this check uses the `--package ` parameter passed on the command line. + +### port + +Validates the state of a local port. + +!!! note + Goss might consider your port to be listening on `tcp6` rather than `tcp`, + try running `goss add port ..` to see how goss detects it. + ([explanation](https://github.com/goss-org/goss/issues/149)) + +```yaml +port: + # {tcp,tcp6,udp,udp6}:port_num + tcp:22: + # required attributes + listening: true + # optional attributes + # defaults to hash key + port: 'tcp:22' + ip: # what IP(s) is it listening on + - 0.0.0.0 + skip: false +``` + +### process + +Validates if a process is running. + +```yaml +process: + chrome: + # required attributes + running: true + # optional attributes + # defaults to hash key + comm: chrome + skip: false +``` + +!!! note + This check is inspecting the name of the binary, not the name of the process. + + For example, a process with the name `nginx: master process /usr/sbin/nginx` would be checked with the process `nginx`. + To discover the binary of a pid run `cat -E /proc//comm`. + +### service + +Validates the state of a service. + +```yaml +service: + sshd: + # Optional attributes + # defaults to hash key + name: sshd + enabled: true + running: true + runlevels: ["3", "4", "5"] # Alpine example, runlevels: ["default"] + skip: false +``` + +`runlevels` is only supported on Alpine init, sysv init, and upstart + +!!! note + This will **not** automatically check if the process is alive, it will check the status from `systemd`/`upstart`/`init`. + +### user + +Validates the state of a user + +```yaml +user: + nfsnobody: + # required attributes + exists: true + # optional attributes + # defaults to hash key + username: nfsnobody + uid: 65534 + gid: 65534 + groups: + - nfsnobody + home: /var/lib/nfs + shell: /sbin/nologin + skip: false +``` + +!!! note + This check is inspecting the contents of local passwd file `/etc/passwd`, this does not validate remote users (e.g. LDAP). + +## Matchers + +### Default Matchers + +Default matchers are determined by the attribute value received from the system. + +#### Bool, Strings, Integers + +Bool, Strings and integers are compared using equality, for example: + +```yaml +matching: + basic_string: + content: 'foo' + matches: 'foo' + +user: + nfsnobody: + exists: true + uid: 65534 +``` + +#### Arrays + +Arrays are treated as a [contains-elements](#array-matchers) by default, +this validates that the expected test is a subset of the returned system state. + +```yaml +matching: + basic_array: + content: + - 'group1' + - 'group2' + - 'group3' + matches: + - 'group1' + - 'group2' + + # This fails, since the returned result and it's no longer a subset + basic_array_failing: + content: + - 'group1' + - 'group2' + - 'group3' + matches: + - 'group1' + - 'group2' + - 'group2' # this 2nd group2 is not in the returned content +``` + +#### io.Readers + +This is the most magical matcher for goss. It remains a default for historic and performance reasons. +Some attributes return an io.Reader that is read line by line (ex. file content, command, http body). +This allows goss to validate large files/content efficiently. + +Each pattern is checked against the attribute output, the type of patterns are: + +* `"foo"` - checks if any line contains `foo` +* `"!foo"` - inverse of above, checks that no line contains `foo` +* `"\\!foo"` - escape sequence, check if any line contains `!string` +* `"/[Rr]egex/"` - verifies that line matches regex +* `"!/[Rr]egex/"` - inverse of above, checks that no line matches regex + +!!! note + Regex support is based on Golang's regex engine documented [here](https://golang.org/pkg/regexp/syntax/) + +!!! warning + You will **need** the double backslash (`\\`) escape for Regex special entities, for example `\\s` for blank spaces. + +!!! example + ```yaml + file: + /tmp/test.txt: + exists: true + contents: + - "foo" + - "!bar" + - "/[Gg]oss/" + ``` + + The above can be expressed as: + + ```yaml + file: + /tmp/test.txt: + exists: true + contents: + and: + - contain-element: "foo" + - not: {contain-element: "bar"} + - contain-element: {match-regexp: "[Gg]oss"} + + ``` + +### Transforms + +If the system state type and the expected type don't match, +goss will attempt to transform the system state type before matching it. + +For example, kernel-param attribute returns a string, however, it can be tested using numeric comparisons: + +!!! example "kernel-param test" + ```yaml + kernel-param: + net.core.somaxconn: + value: "128" + ``` + +!!! example "(failing) kernel-param test with transform" + ```yaml + kernel-param: + net.core.somaxconn: + value: {gt: 200} + ``` + +When a transformed test fails, it will detail the transformers used, +the `-o exclude_raw` option can be used to exclude the raw, untransformed attribute value: + +```coonsole +$ goss v +F + +Failures/Skipped: + +KernelParam: net.core.somaxconn: value: +Expected + 128 +to be > + 200 +the transform chain was + [{"to-numeric":{}}] +the raw value was + "128" + +Total Duration: 0.001s +Count: 1, Failed: 1, Skipped: 0 + +$ goss v -o exclude_raw +F + +Failures/Skipped: + +KernelParam: net.core.somaxconn: value: +Expected + 128 +to be > + 200 +the transform chain was + [{"to-numeric":{}}] + +Total Duration: 0.001s +Count: 1, Failed: 1, Skipped: 0 + +``` + +### Advanced Matchers + +Goss supports advanced matchers by converting YAML input to [gomega](https://onsi.github.io/gomega/) matchers. + +#### String Matchers + +These will convert the system attribute to a string prior to matching. + +* `'55'` - Checks that the numeric is "55" when converted to string +* `have-prefix: pre` - Checks if string starts with "pre" +* `have-suffix: suf` - Checks if string ends with "suf" +* `match-regexp: '.*'` - Checks if string matches regexp +* `contain-substring: '2'` - Checks if string contains "2" + +* `'55'` - Checks that the numeric is "55" when converted to string +* `have-prefix: pre` - Checks if string starts with "pre" +* `have-suffix: suf` - Checks if string ends with "suf" +* `match-regexp: '.*'` - Checks if string matches regexp +* `contain-substring: '2'` - Checks if string contains "2" + +!!! example + ```yaml + matching: + example: + content: 42 + matches: + and: + - '42' + - have-prefix: '4' + - have-suffix: '2' + - match-regexp: '\d{2}' + - contain-substring: '2' + ``` + +#### Numeric matchers + +These will convert the system attribute to a numeric prior to matching. + +* `42` - If the expected type is a number +* `gt, ge, lt, le` - Greater than, greater than or equal, less than, etc.. + +!!! example + ```yaml + matching: + example: + content: "42" + matches: + and: + - 42 + - 42.0 + - gt: 40 + - lt: 45 + ``` + +#### Array matchers + +These will convert the system attribute to an array prior to matching. Strings are split on "\n" + +* `contain-element: matcher` - Checks if the array contains an element that passes the matcher +* `contain-elements: [matcher, ...]` - checks if the array is a superset of the provided matchers +* `[matcher, ...]` - same as above +* `equal: [value, ...]` - Checks if the array is exactly equal to provided array +* `consist-of: [matcher, ...]` - Checks if the array consists of the provided matchers (order does not matter) + +!!! example + ```yaml + matching: + example: + content: [foo, bar, moo] + matches: + and: + - contain-elements: [foo, bar] + - [foo, bar] # same as above + - equal: [foo, bar, moo] # order matters, exact match + - consist-of: [foo, have-prefix: m, bar] # order doesn't matter, can use matchers + - contain-element: + have-prefix: b + ``` + +#### Misc matchers + +These matchers don't really fall into any of the above categories, or span multiple categories. + +* `equal` - Useful when needing to override a default matcher +* `have-len: 3` - Checks if the array/string/map has length of 3 +* `have-key: "foo"` - Checks if key exists in map, useful with `gjson` +* `not: matcher` - Checks that a matcher does not match +* `and: [matcher, ..]` - Checks that all matchers match +* `or: [matcher, ..]` - Checks that any matchers match + +!!! note + When system returns a string it is converted into a one element array and matched + +See the following for examples: [link..]fixme + +##### semver-constraint + +Checks that all versions match semver constraint or range syntax. +This uses [semver](https://github.com/blang/semver) under the hood, however, wildcards +(e.g. `1.X` are not officially supported and may go away in a future release). + +!!! example + ```yaml + matching: + semver: + content: + - 1.0.1 + - 1.9.9 + matches: + semver-constraint: ">1.0.0 <2.0.0 !=1.5.0" + semver2: + content: + - 1.0.1 + - 1.5.0 + - 1.9.9 + matches: + not: + semver-constraint: ">1.0.0 <2.0.0 !=1.5.0" + semver3: + content: 1.0.1 + matches: + semver-constraint: ">5.0.0 || < 1.5.0" + ``` + +##### gjson + +Checks extracted [gjson](https://gjson.dev/) passes the matcher + +Example: + +```yaml +matching: + example: + content: '{"foo": "bar", "moo" {"nested": "cow"}, "count": "15"}' + matches: + gjson: + moo.nested: cow + foo: {have-prefix: b} + count: {le: 25} + '@this': {have-key: "foo"} + moo: + and: + - {have-key: "nested"} + - {not: {have-key: "nested2"}} +``` + +## 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: + +* [built-in text/template functions](https://golang.org/pkg/text/template/#hdr-Functions) +* [Sprig functions](https://masterminds.github.io/sprig/) +* Custom functions: + + `mkSlice "ARG1" "ARG2"` + : Returns a slice of all the arguments. See examples below for usage. + + `getEnv "var" ["default"]` + : A more forgiving env var lookup. If key is missing either "" or default (if provided) is returned. + + `readFile "fileName"` + : Reads file content into a string, trims whitespace. Useful when a file contains a token. + !!! note + Goss will error out during during the parsing phase if the file does not exist, no tests will be executed. + + `regexMatch "(some)?reg[eE]xp"` + : Tests the piped input against the regular expression argument. + + `toLower` + : Changes piped input to lowercase + + `toUpper` + : Changes piped input to UPPERCASE + +!!! warning + + 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. + +!!! note + + Some of Sprig functions have the same name as the older Custom Goss functions. + The Sprig functions are overwritten by the custom functions for backwards compatibility. + +### 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+jinja +file: +{{- range mkSlice "/etc/passwd" "/etc/group"}} + {{.}}: + exists: true + mode: "0644" + owner: root + group: root + filetype: file +{{end}} +``` + +Using `upper` function from Sprig. + +```yaml+jinja +matching: + sping_basic: + content: {{ "hello!" | upper | repeat 5 }} + matches: + match-regexp: "HELLO!HELLO!HELLO!HELLO!HELLO!" +``` + +Using Env variables and a vars file: + +```yaml title="vars.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 +``` + +```yaml+jinja title="goss.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 the OS environment variable matches the pattern +{{if .Env.OS | regexMatch "[Cc]ent(OS|os)"}} + libselinux: + installed: true +{{end}} + +# Loop over users +user: +{{range .Vars.users}} + {{.}}: + exists: true + groups: + - {{.}} + home: /home/{{.}} + shell: /bin/bash +{{end}} + + +package: +{{if eq .Env.OS "centos"}} + # This test is only when $OS environment variable is set to "centos" + libselinux: + installed: true +{{end}} +``` + +```console title="Rendered results" +# 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 +``` diff --git a/docs/index.md b/docs/index.md new file mode 100644 index 000000000..d5a3cc436 --- /dev/null +++ b/docs/index.md @@ -0,0 +1,4 @@ +# Goss - Quick and Easy server validation + +--8<-- "README.md:intro" +--8<-- "README.md:about" diff --git a/docs/installation.md b/docs/installation.md new file mode 100644 index 000000000..0ab4cc435 --- /dev/null +++ b/docs/installation.md @@ -0,0 +1,3 @@ +# Installation + +--8<-- "README.md:install" diff --git a/docs/license.md b/docs/license.md new file mode 100644 index 000000000..f409d4523 --- /dev/null +++ b/docs/license.md @@ -0,0 +1 @@ +--8<-- "LICENSE" diff --git a/docs/manual.md b/docs/manual.md deleted file mode 100644 index fd60b87d8..000000000 --- a/docs/manual.md +++ /dev/null @@ -1,1260 +0,0 @@ -# goss manual - -**Notes:** - -* For migration from v0.3.x to v0.4.x, see: [v4 migration](https://github.com/goss-org/goss/blob/master/docs/v4_migration.md) -* For macOS and Windows, see: [platform-feature-parity](https://github.com/goss-org/goss/blob/master/docs/platform-feature-parity.md) - -## Table of Contents - -## Usage - -``` -NAME: - goss - Quick and Easy server validation - -USAGE: - goss [global options] command [command options] [arguments...] - -VERSION: - 0.0.0 - -COMMANDS: - validate, v Validate system - serve, s Serve a health endpoint - render, r render gossfile after imports - autoadd, aa automatically add all matching resource to the test suite - add, a add a resource to the test suite - help, h Shows a list of commands or help for one command - -GLOBAL OPTIONS: - --gossfile value, -g value Goss file to read from / write to (default: "./goss.yaml") [$GOSS_FILE] - --vars value json/yaml file containing variables for template [$GOSS_VARS] - --vars-inline value json/yaml string containing variables for template (overwrites vars) [$GOSS_VARS_INLINE] - --package value Package type to use [rpm, deb, apk, pacman] - --help, -h show help - --version, -v print the version -``` -**Note:** *Most flags can be set by using environment variables, see `--help` for more info.* - - -## global options -### --gossfile gossfile or -g gossfile -The file to use when reading/writing tests. Use `--gossfile -` or `-g -` to read from `STDIN`. - -Valid formats: -* **YAML** (default) -* **JSON** - -### --vars -The file to read variables from when rendering gossfile [templates](#templates). - -Valid formats: -* **YAML** (default) -* **JSON** - -### --package -The package type to check for. - -Valid options are: -* `apk` -* `deb` -* `pacman` -* `rpm` - - -## commands -Commands are the actions goss can run. - -* [add](#add-a---add-system-resource-to-test-suite): add a single test for a resource -* [autoadd](#autoadd-aa---auto-add-all-matching-resources-to-test-suite): automatically add multiple tests for a resource -* [render](#render-r---render-gossfile-after-importing-all-referenced-gossfiles): renders and outputs the gossfile, importing all included gossfiles -* [serve](#serve-s---serve-a-health-endpoint): serves the gossfile validation as an HTTP endpoint on a specified address and port, so you can use your gossfile as a health report for the host -* [validate](#validate-v---validate-the-system): runs the goss test suite on your server - - -### add, a - Add system resource to test suite - -This will add a test for a resource. Non existent resources will add a test to ensure they do not exist on the system. A sub-command *resource type* has to be provided when running `add`. - -#### Resource types -* `addr` - can verify if a remote `address:port` is reachable, see [addr](#addr) -* `command` - can run a [command](#command) and validate the exit status and/or output -* `dns` - resolves a [dns](#dns) name and validates the addresses -* `file` - can validate a [file](#file) existence, permissions, stats (size, etc) and contents -* `goss` - allows you to include the contents of another [gossfile](#gossfile) -* `group` - can validate the existence and values of a [group](#group) on the system -* `http` - can validate the HTTP response code, headers, and content of a URI, see [http](#http) -* `interface` - can validate the existence and values (es. the addresses) of a network interface, see [interface](#interface) -* `kernel-param` - can validate kernel parameters (sysctl values), see [kernel-param](#kernel-param) -* `mount` - can validate the existence and options relative to a [mount](#mount) point -* `package` - can validate the status of a [package](#package) using the package manager specified on the commandline with `--package` -* `port` - can validate the status of a local [port](#port), for example `80` or `udp:123` -* `process` - can validate the status of a [process](#process) -* `service` - can validate if a [service](#service) is running and/or enabled at boot -* `user` - can validate the existence and values of a [user](#user) on the system - -#### Flags -##### --exclude-attr -Ignore **non-required** attribute(s) matching the provided glob when adding a new resource, may be specified multiple times. - -#### Example: -```bash -$ goss a file /etc/passwd -$ goss a user nobody -$ goss a --exclude-attr home --exclude-attr shell user nobody -$ goss a --exclude-attr '*' user nobody -``` - - -### autoadd, aa - Auto add all matching resources to test suite -Automatically [adds](#add-a---add-system-resource-to-test-suite) all **existing** resources matching the provided argument. - -Will automatically add the following matching resources: -* `file` - only if argument contains `/` -* `group` -* `package` -* `port` -* `process` - Also adding any ports it's listening to (if run as root) -* `service` -* `user` - -Will **NOT** automatically add: -* `addr` -* `command` - for safety -* `dns` -* `http` -* `interface` -* `kernel-param` -* `mount` - -#### Example: -```bash -$ goss autoadd sshd -``` - -Generates the following `goss.yaml` -```yaml -port: - tcp:22: - listening: true - ip: - - 0.0.0.0 - tcp6:22: - listening: true - ip: - - '::' -service: - sshd: - enabled: true - running: true -user: - sshd: - exists: true - uid: 74 - gid: 74 - groups: - - sshd - home: /var/empty/sshd - shell: /sbin/nologin -group: - sshd: - exists: true - gid: 74 -process: - sshd: - running: true -``` - - -### 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 - -$ cat goss_httpd_package.yaml -package: - httpd: - installed: true - versions: - - 2.2.15 - -$ cat goss_httpd_service.yaml -service: - httpd: - enabled: true - running: true - -$ cat goss_nginx_service-NO.yaml -service: - nginx: - enabled: false - running: false - -$ cat goss.yaml -gossfile: - goss_httpd_package.yaml: {} - goss_httpd_service.yaml: {} - goss_nginx_service-NO.yaml: {} - -$ goss -g goss.yaml render -package: - httpd: - installed: true - versions: - - 2.2.15 -service: - httpd: - enabled: true - running: true - nginx: - enabled: false - running: false -``` - -### serve, s - Serve a health endpoint - -`serve` exposes the goss test suite as a health endpoint on your server. The end-point will return the stest results in the format requested and an http status of 200 or 503. - -`serve` will look for a test suite in the same order as [validate](#validate-v---validate-the-system) - -#### Flags - -* `--cache `, `-c ` - Time to cache the results (default: 5s) -* `--endpoint `, `-e ` - Endpoint to expose (default: `/healthz`) -* `--format`, `-f` - output format, same as [validate](#validate-v---validate-the-system) -* `--listen-addr [ip]:port`, `-l [ip]:port` - Address to listen on (default: `:8080`) -* `--loglevel level`, `-L level` - Goss logging verbosity level (default: `INFO`). `level` can be one of `TRACE | DEBUG | INFO | WARN | ERROR`. Lower levels of tracing include all upper levels traces also (ie. INFO include WARN and ERROR). - * `ERROR` - Critical errors that halt goss or significantly affect its functionality, requiring immediate intervention. - * `WARN` - Non-critical issues that may require attention, such as overwritten keys or deprecated features. - * `INFO` - General operational messages, useful for tasks where a more structured output is needed (e.g. goss serve). - * `DEBUG` - Information useful for the goss user to debug. - * `TRACE` - Detailed internal system activities useful for goss developers to debug. -* `--max-concurrent` - Max number of tests to run concurrently - -#### Example: - -```bash -$ goss serve & -$ curl http://localhost:8080/healthz - -# JSON endpoint -$ goss serve --format json & -$ curl localhost:8080/healthz - -# rspecish output format in response via content negotiation -goss serve --format json & -curl -H "Accept: application/vnd.goss-rspecish" localhost:8080/healthz -``` - -The `application/vnd.goss-{output format}` media type can be used in the `Accept` request header to determine the response's content-type. You can also `Accept: application/json` to get back `application/json`. - -### validate, v - Validate the system - -`validate` runs the goss test suite on your server. Prints an rspec-like (by default) output of test results. Exits with status 0 on success, non-0 otherwise. - -#### Flags -* `--format`, `-f` (output format) - * `documentation` - Verbose test results - * `json` - Detailed test result on a single line (See `pretty` format option) - * `junit` - * `nagios` - Nagios/Sensu compatible output /w exit code 2 for failures - * `rspecish` **(default)** - Similar to rspec output - * `tap` - * `prometheus` - Prometheus compatible output. - * `silent` - No output. Avoids exposing system information (e.g. when serving tests as a healthcheck endpoint) -* `--format-options`, `-o` (output format option) - * `perfdata` - Outputs Nagios "performance data". Applies to `nagios` output - * `verbose` - Gives verbose output. Applies to `nagios` and `prometheus` output - * `pretty` - Pretty printing for the `json` output - * `sort` - Sorts the results -* `--loglevel level`, `-L level` - Goss logging verbosity level (default: `INFO`). `level` can be one of `TRACE | DEBUG | INFO | WARN | ERROR | FATAL`. Lower levels of tracing include all upper levels traces also (ie. INFO include WARN, ERROR and FATAL outputs). - * `TRACE` - Print details for each check, successful or not and all incoming healthchecks - * `DEBUG` - Print details of summary response to healthchecks including remote IP address, return code and full body - * `INFO` - Print summary when all checks run OK - * `WARN` - Print summary and corresponding checks when encountering some failures - * `ERROR` - Not used for now (will not print anything) - * `FATAL` - Not used for now (will not print anything) -* `--max-concurrent` - Max number of tests to run concurrently -* `--no-color` - Disable color -* `--color` - Force enable color -* `--retry-timeout`, `-r` - Retry on failure so long as elapsed + sleep time is less than this (default: 0) -* `--sleep`, `-s` - Time to sleep between retries (default: 1s) - -#### Examples: - -```bash -$ goss validate --format documentation -File: /etc/hosts: exists: matches expectation: [true] -DNS: localhost: resolvable: matches expectation: [true] -[...] -Total Duration: 0.002s -Count: 10, Failed: 2, Skipped: 0 - -$ curl -s https://static/or/dynamic/goss.json | goss validate -...F.F -[...] -Total Duration: 0.002s -Count: 6, Failed: 2, Skipped: 0 - -$ goss render | ssh remote-host 'goss -g - validate' -...... - -Total Duration: 0.002s -Count: 6, Failed: 0, Skipped: 0 - -$ goss validate --format nagios -o verbose -o perfdata -GOSS CRITICAL - Count: 76, Failed: 1, Skipped: 0, Duration: 1.009s|total=76 failed=1 skipped=0 duration=1.009s -Fail 1 - DNS: localhost: addrs: doesn't match, expect: [["127.0.0.1","::1"]] found: [["127.0.0.1"]] -$ echo $? -2 -``` - -## Goss test creation -Goss tests can be created by using either of following methods. -1. goss autoadd -2. goss add -3. manually create YAML/JSON test file by hand. - -To customize the parameters generated by `goss add` and `goss autoadd` YAML file you need to manually edit it. - -`goss add package nginx` will generate below YAML -``` -package: - nginx: - installed: true - versions: - - 1.17.8 -``` -To test uninstall scenario you would need to manually edit it and set it as below. -``` -package: - nginx: - installed: false -``` - -## Important note about goss file format -It is important to note that both YAML and JSON are formats that describe a nested data structure. - -**WRONG way to write a goss file** - -```yaml -file: - /etc/httpd/conf/httpd.conf: - exists: true - -service: - httpd: - enabled: true - running: true - -file: - /var/www/html: - filetype: directory - exists: true -``` - -If you try to validate this file, it will **only** run the second `file` test: - -```bash -# goss validate --format documentation -File: /var/www/html: exists: matches expectation: [true] -File: /var/www/html: filetype: matches expectation: ["directory"] -Service: httpd: enabled: matches expectation: [true] -Service: httpd: running: matches expectation: [true] - -Total Duration: 0.014s -Count: 8, Failed: 0, Skipped: 0 -``` - -As you can see, the first `file` check has not been run because the second `file` entry *overwrites* the previous one. - -You need to make sure all the entries of the same type are under the same declaration. - -**This is the CORRECT way to write a goss file** - -```yaml -file: - /etc/httpd/conf/httpd.conf: - exists: true - /var/www/html: - filetype: directory - exists: true - -service: - httpd: - enabled: true - running: true -``` - -Running validate with this configuration will correctly check both files: - -```bash -# goss validate --format documentation -File: /var/www/html: exists: matches expectation: [true] -File: /var/www/html: filetype: matches expectation: ["directory"] -File: /etc/httpd/conf/httpd.conf: exists: matches expectation: [true] -Service: httpd: enabled: matches expectation: [true] -Service: httpd: running: matches expectation: [true] - -Total Duration: 0.014s -Count: 10, Failed: 0, Skipped: 0 -``` - -Please note that using the `goss add` and `goss autoadd` command will create a valid file, but if you're writing your files by hand you'll save a lot of time by taking this in consideration. - -If you want to keep your tests in separate files, the best way to obtain a single, valid, file is to create a main goss file that includes the others with the [gossfile](#gossfile) directive and then [render](#render-r---render-gossfile-after-importing-all-referenced-gossfiles) it. - - - -## Available tests - -* [addr](#addr) -* [command](#command) -* [dns](#dns) -* [file](#file) -* [gossfile](#gossfile) -* [group](#group) -* [http](#http) -* [interface](#interface) -* [kernel-param](#kernel-param) -* [matching](#matching) -* [mount](#mount) -* [package](#package) -* [port](#port) -* [process](#process) -* [service](#service) -* [user](#user) - - -### addr -Validates if a remote `address:port` are accessible. - -```yaml -addr: - tcp://ip-address-or-domain-name:80: - # required attributes - reachable: true - # optional attributes - # defaults to hash key - address: "tcp://ip-address-or-domain-name:80" - timeout: 500 - local-address: 127.0.0.1 -``` - - -### command -Validates the exit-status and output of a command. This can be used in combination with the [gjson](#gjson) matcher to create powerful goss custom tests. - -```yaml -command: - 'go version': - # required attributes - exit-status: 0 - # optional attributes - # defaults to hash key - exec: "go version" - 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. - -```yaml -dns: - localhost: - # required attributes - resolvable: true - # optional attributes - # defaults to hash key - resolve: localhost - addrs: - - 127.0.0.1 - - ::1 - server: 8.8.8.8 # Also supports server:port - timeout: 500 # in milliseconds (Only used when server attribute is provided) -``` - -It is possible to validate the following types of DNS records, but requires the ```server``` attribute be set: - -- A -- AAAA -- CAA -- CNAME -- MX -- NS -- PTR -- SRV -- TXT - -To validate specific DNS address types, prepend the hostname with the type and a colon, a few examples: - -```yaml -dns: - # Validate a CNAME record - CNAME:c.dnstest.io: - resolvable: true - server: 208.67.222.222 - addrs: - - "a.dnstest.io." - - # Validate a PTR record - PTR:8.8.8.8: - resolvable: true - server: 8.8.8.8 - addrs: - - "dns.google." - - # Validate and SRV record - SRV:_https._tcp.dnstest.io: - resolvable: true - server: 208.67.222.222 - addrs: - - "0 5 443 a.dnstest.io." - - "10 10 443 b.dnstest.io." -``` - -Please note that if you want `localhost` to **only** resolve `127.0.0.1` you'll need to use [Advanced Matchers](#advanced-matchers) - -```yaml -dns: - localhost: - resolvable: true - addrs: - consist-of: [127.0.0.1] - timeout: 500 # in milliseconds -``` - -### file -Validates the state of a file, directory, socket, or symbolic link - -```yaml -file: - /etc/passwd: - # required attributes - exists: true - # optional attributes - # defaults to hash key - path: /etc/passwd - mode: "0644" - size: 2118 # in bytes - owner: root - group: root - filetype: file # file, symlink, directory, socket - contents: [] # Check file content for these patterns - md5: 7c9bb14b3bf178e82c00c2a4398c93cd # md5 checksum of file - # A stronger checksum alternatives to md5 (recommended) - sha256: 7f78ce27859049f725936f7b52c6e25d774012947d915e7b394402cfceb70c4c - sha512: cb71b1940dc879a3688bd502846bff6316dd537bbe917484964fe0f098e9245d80958258dc3bd6297bf42d5bd978cbe2c03d077d4ed45b2b1ed9cd831ceb1bd0 - /etc/alternatives/mta: - # required attributes - exists: true - # optional attributes - filetype: symlink # file, symlink, directory, socket - linked-to: /usr/sbin/sendmail.sendmail - skip: false -``` - -`contents` can be a string or a [pattern](#patterns) - - -### gossfile -Import other gossfiles from this one. This is the best way to maintain a large number of tests, and/or create profiles. See [render](#render-r---render-gossfile-after-importing-all-referenced-gossfiles) for more examples. Glob patterns can be also be used to specify matching gossfiles. - -```yaml -gossfile: - myapplication: - file: myapp_gossfile.yaml - skip: false - *.yaml: - skip: true - goss_httpd.yaml: {} - /etc/goss.d/*.yaml: {} -``` - -You can specify the gossfile(s) either as the resource key, or using the 'file' attribute. - -If the 'skip' attribute is true, then the file is not processed. If the filename is a glob pattern, then none of the matching files are processed. Note that this is not the same as skipping the contained resources; any overrides in the referenced gossfile will not be processed, and the resource count will not be incremented. Skipping a gossfile include is the same as omitting the gossfile resource entirely. - -### group -Validates the state of a group - -```yaml -group: - nfsnobody: - # required attributes - exists: true - # optional attributes - # defaults to hash key - groupname: /etc/passwd - gid: 65534 - skip: false -``` - - -### http -Validates HTTP response status code and content. - -```yaml -http: - https://www.google.com: - # required attributes - status: 200 - # optional attributes - # defaults to hash key - url: https://www.google.com - allow-insecure: false - no-follow-redirects: false # Setting this to true will NOT follow redirects - timeout: 1000 - request-headers: # Set request header values - - "Content-Type: text/html" - headers: [] # Check http response headers for these patterns (e.g. "Content-Type: text/html") - request-body: '{"key": "value"}' # request body - body: [] # Check http response content for these patterns - username: "" # username for basic auth - password: "" # password for basic auth - ca-file: "" # CA root certs pem file, ex: /etc/ssl/cert.pem - cert-file: "" # certificate file to use for authentication (used with key-file) - key-file: "" # private-key file to use for authentication (used with cert-file) - proxy: "" # proxy server to proxy traffic through. Proxy can also be set with environment variables http_proxy. - skip: false - method: PUT # http method -``` - -**NOTE:** only the first `Host` header will be used to set the `Request.Host` value if multiple are provided. - -### interface -Validates network interface values - -```yaml -interface: - eth0: - # required attributes - exists: true - # optional attributes - # defaults to hash key - name: eth0 - addrs: - - 172.17.0.2/16 - - fe80::42:acff:fe11:2/64 - mtu: 1500 -``` - - -### kernel-param -Validates kernel param (sysctl) value. - -```yaml -kernel-param: - kernel.ostype: - # required attributes - value: Linux - # optional attributes - # defaults to hash key - name: kernel.ostype -``` - -To see the full list of current values, run `sysctl -a`. - - -### mount -Validates mount point attributes. - -```yaml -mount: - /home: - # required attributes - exists: true - # optional attributes - # defaults to hash key - mountpoint: /home - opts: - - rw - - relatime - # This maps to the per-superblock options, see: - # https://man7.org/linux/man-pages/man5/proc.5.html - # https://man7.org/linux/man-pages/man2/mount.2.html - vfs-opts: - - rw - source: /dev/mapper/fedora-home - filesystem: xfs - usage: #% of blocks used in this mountpoint - lt: 95 -``` - -### matching -Validates specified content against a matcher. Best used with [Templates](#templates). - -#### With [Templates](#templates): -Let's say we have a `data.json` file that gets generated as part of some testing pipeline: - -```json -{ - "instance_count": 14, - "failures": 3, - "status": "FAIL" -} -``` - -This could then be passed into goss: `goss --vars data.json validate` - -And then validated against: - -```yaml -matching: - check_instance_count: # Make sure there is at least one instance - content: {{ .Vars.instance_count }} - matches: - gt: 0 - - check_failure_count_from_all_instance: # expect no failures - content: {{ .Vars.failures }} - matches: 0 - - check_status: - content: {{ .Vars.status }} - matches: - - not: FAIL -``` - -#### Without [Templates](#templates): -```yaml -matching: - has_substr: # friendly test name - content: some string - matches: - match-regexp: some str - has_2: - content: - - 2 - matches: - contain-element: 2 - has_foo_bar_and_baz: - content: - foo: bar - baz: bing - matches: - and: - - have-key: baz -``` - -### package -Validates the state of a package - -```yaml -package: - httpd: - # required attributes - installed: true - # optional attributes - # defaults to hash key - name: httpd - versions: - - 2.2.15 - skip: false -``` - -**NOTE:** this check uses the `--package ` parameter passed on the command line. - - -### port -Validates the state of a local port. - -**Note:** Goss might consider your port to be listening on `tcp6` rather than `tcp`, try running `goss add port ..` to see how goss detects it. ([explanation](https://github.com/goss-org/goss/issues/149)) - -```yaml -port: - # {tcp,tcp6,udp,udp6}:port_num - tcp:22: - # required attributes - listening: true - # optional attributes - # defaults to hash key - port: 'tcp:22' - ip: # what IP(s) is it listening on - - 0.0.0.0 - skip: false -``` - - -### process -Validates if a process is running. - -```yaml -process: - chrome: - # required attributes - running: true - # optional attributes - # defaults to hash key - comm: chrome - skip: false -``` - -**NOTE:** This check is inspecting the name of the binary, not the name of the process. For example, a process with the name `nginx: master process /usr/sbin/nginx` would be checked with the process `nginx`. To discover the binary of a pid run `cat -E /proc//comm`. - -### service -Validates the state of a service. - -```yaml -service: - sshd: - # Optional attributes - # defaults to hash key - name: sshd - enabled: true - running: true - runlevels: ["3", "4", "5"] # Alpine example, runlevels: ["default"] - skip: false -``` - -`runlevels` is only supported on Alpine init, sysv init, and upstart - -**NOTE:** this will **not** automatically check if the process is alive, it will check the status from `systemd`/`upstart`/`init`. - - -### user -Validates the state of a user - -```yaml -user: - nfsnobody: - # required attributes - exists: true - # optional attributes - # defaults to hash key - username: nfsnobody - uid: 65534 - gid: 65534 - groups: - - nfsnobody - home: /var/lib/nfs - shell: /sbin/nologin - skip: false -``` - -**NOTE:** This check is inspecting the contents of local passwd file `/etc/passwd`, this does not validate remote users (e.g. LDAP). - - -## Matchers - -### Default Matchers - -Default matchers are determined by the attribute value received from the system. - -#### Bool, Strings, Integers - -Bool, Strings and integers are compared using equality, for example: - -```yaml -matching: - basic_string: - content: 'foo' - matches: 'foo' - -user: - nfsnobody: - exists: true - uid: 65534 -``` - -#### Arrays - -Arrays are treated as a [contains-elements](#array-matchers) by default, this validates that the expected test is a subset of the returned system state. - -```yaml -matching: - basic_array: - content: - - 'group1' - - 'group2' - - 'group3' - matches: - - 'group1' - - 'group2' - - # This fails, since the returned result and it's no longer a subset - basic_array_failing: - content: - - 'group1' - - 'group2' - - 'group3' - matches: - - 'group1' - - 'group2' - - 'group2' # this 2nd group2 is not in the returned content -``` - -#### io.Readers - -This is the most magical matcher for goss. It remains a default for historic and performance reasons. Some attributes return an io.Reader that is read line by line (ex. file content, command, http body). This allows goss to validate large files/content efficiently. - - -Each pattern is checked against the attribute output, the type of patterns are: - -* `"foo"` - checks if any line contains `foo` -* `"!foo"` - inverse of above, checks that no line contains `foo` -* `"\\!foo"` - escape sequence, check if any line contains `!string` -* `"/[Rr]egex/"` - verifies that line matches regex -* `"!/[Rr]egex/"` - inverse of above, checks that no line matches regex - -**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. - -Example: - -```yaml -file: - /tmp/test.txt: - exists: true - contents: - - "foo" - - "!bar" - - "/[Gg]oss/" -``` - -The above can be expressed as: - -```yaml -file: - /tmp/test.txt: - exists: true - contents: - and: - - contain-element: "foo" - - not: {contain-element: "bar"} - - contain-element: {match-regexp: "[Gg]oss"} - -``` - -### Transforms - -If the system state type and the expected type don't match, goss will attempt to transform the system state type before matching it. - -For example, kernel-param attribute returns a string, however, it can be tested using numeric comparisons: - -Example kernel-param test: -```yaml -kernel-param: - net.core.somaxconn: - value: "128" -``` - -Example (failing) kernel-param test with transform: -```yaml -kernel-param: - net.core.somaxconn: - value: {gt: 200} -``` - -When a transformed test fails, it will detail the transformers used, the `-o exclude_raw` option can be used to exclude the raw, untransformed attribute value: -``` -$ goss v -F - -Failures/Skipped: - -KernelParam: net.core.somaxconn: value: -Expected - 128 -to be > - 200 -the transform chain was - [{"to-numeric":{}}] -the raw value was - "128" - -Total Duration: 0.001s -Count: 1, Failed: 1, Skipped: 0 - -$ goss v -o exclude_raw -F - -Failures/Skipped: - -KernelParam: net.core.somaxconn: value: -Expected - 128 -to be > - 200 -the transform chain was - [{"to-numeric":{}}] - -Total Duration: 0.001s -Count: 1, Failed: 1, Skipped: 0 - - -``` - -### Advanced Matchers - -Goss supports advanced matchers by converting YAML input to [gomega](https://onsi.github.io/gomega/) matchers. - -#### String Matchers - -These will convert the system attribute to a string prior to matching. - -* `'55'` - Checks that the numeric is "55" when converted to string -* `have-prefix: pre` - Checks if string starts with "pre" -* `have-suffix: suf` - Checks if string ends with "suf" -* `match-regexp: '.*'` - Checks if string matches regexp -* `contain-substring: '2'` - Checks if string contains "2" - -Example: -```yaml -matching: - example: - content: 42 - matches: - and: - - '42' - - have-prefix: '4' - - have-suffix: '2' - - match-regexp: '\d{2}' - - contain-substring: '2' -``` - -#### Numeric matchers - -These will convert the system attribute to a numeric prior to matching. - -* `42` - If the expected type is a number -* `gt, ge, lt, le` - Greater than, greater than or equal, less than, etc.. - -Example: -```yaml -matching: - example: - content: "42" - matches: - and: - - 42 - - 42.0 - - gt: 40 - - lt: 45 -``` - -#### Array matchers - -These will convert the system attribute to an array prior to matching. Strings are split on "\n" - - -* `contain-element: matcher` - Checks if the array contains an element that passes the matcher -* `contain-elements: [matcher, ...]` - checks if the array is a superset of the provided matchers -* `[matcher, ...]` - same as above -* `equal: [value, ...]` - Checks if the array is exactly equal to provided array -* `consist-of: [matcher, ...]` - Checks if the array consists of the provided matchers (order does not matter) - -Example: -```yaml -matching: - example: - content: [foo, bar, moo] - matches: - and: - - contain-elements: [foo, bar] - - [foo, bar] # same as above - - equal: [foo, bar, moo] # order matters, exact match - - consist-of: [foo, have-prefix: m, bar] # order doesn't matter, can use matchers - - contain-element: - have-prefix: b -``` - -#### Misc matchers - -These matchers don't really fall into any of the above categories, or span multiple categories. - -* `equal` - Useful when needing to override a default matcher -* `have-len: 3` - Checks if the array/string/map has length of 3 -* `have-key: "foo"` - Checks if key exists in map, useful with `gjson` -* `not: matcher` - Checks that a matcher does not match -* `and: [matcher, ..]` - Checks that all matchers match -* `or: [matcher, ..]` - Checks that any matchers match - * when system returns a string it is converted into a one element array and matched - -See the following for examples: [link..]fixme - -##### semver-constraint - -Checks that all versions match semver constraint or range syntax. This uses [semver](https://github.com/blang/semver) under the hood, however, wildcards (e.g. `1.X` are not officially supported and may go away in a future release. - -Example: -```yaml -matching: - semver: - content: - - 1.0.1 - - 1.9.9 - matches: - semver-constraint: ">1.0.0 <2.0.0 !=1.5.0" - semver2: - content: - - 1.0.1 - - 1.5.0 - - 1.9.9 - matches: - not: - semver-constraint: ">1.0.0 <2.0.0 !=1.5.0" - semver3: - content: 1.0.1 - matches: - semver-constraint: ">5.0.0 || < 1.5.0" -``` - - -##### gjson - -Checks extracted [gjson](https://gjson.dev/) passes the matcher - -Example: -```yaml -matching: - example: - content: '{"foo": "bar", "moo" {"nested": "cow"}, "count": "15"}' - matches: - gjson: - moo.nested: cow - foo: {have-prefix: b} - count: {le: 25} - '@this': {have-key: "foo"} - moo: - and: - - {have-key: "nested"} - - {not: {have-key: "nested2"}} -``` - -## 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: -* [built-in text/template functions](https://golang.org/pkg/text/template/#hdr-Functions) -* [Sprig functions](https://masterminds.github.io/sprig/) -* Custom functions: - * `mkSlice "ARG1" "ARG2"` - Returns a slice of all the arguments. See examples below for usage. - * `getEnv "var" ["default"]` - A more forgiving env var lookup. If key is missing either "" or default (if provided) is returned. - * `readFile "fileName"` - Reads file content into a string, trims whitespace. Useful when a file contains a token. - * **NOTE:** Goss will error out during during the parsing phase if the file does not exist, no tests will be executed. - * `regexMatch "(some)?reg[eE]xp"` - Tests the piped input against the regular expression argument. - * `toLower` - Changes piped input to lowercase - * `toUpper` - Changes piped input to UPPERCASE - -**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. -**NOTE:** Some of Sprig functions have the same name as the older Custom Goss functions. The Sprig functions are overwritten by the custom functions for backwards compatibility. - -### 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 `upper` function from Sprig. -```yaml -matching: - sping_basic: - content: {{ "hello!" | upper | repeat 5 }} - matches: - match-regexp: "HELLO!HELLO!HELLO!HELLO!HELLO!" -``` - -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 the OS environment variable matches the pattern -{{if .Env.OS | regexMatch "[Cc]ent(OS|os)"}} - libselinux: - installed: true -{{end}} - -# Loop over users -user: -{{range .Vars.users}} - {{.}}: - exists: true - groups: - - {{.}} - home: /home/{{.}} - shell: /bin/bash -{{end}} - - -package: -{{if eq .Env.OS "centos"}} - # This test is only when $OS environment variable is set to "centos" - libselinux: - installed: true -{{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 -``` diff --git a/docs/v4_migration.md b/docs/migrations.md similarity index 84% rename from docs/v4_migration.md rename to docs/migrations.md index 959e7412e..f6981f4c0 100644 --- a/docs/v4_migration.md +++ b/docs/migrations.md @@ -1,7 +1,8 @@ -# v4 migration +# Migration guide +## v4 migration -## Array matchers (e.g. user.groups) no longer allows duplicates +### Array matchers (e.g. user.groups) no longer allows duplicates Goss v0.3.X allowed: @@ -32,17 +33,17 @@ To enable the ability to compare RPM versions in the future, The version matchin from: -``` +```console rpm -q --nosignature --nohdrchk --nodigest --qf '%{VERSION}\n' package_name ``` to: -``` +```console rpm -q --nosignature --nohdrchk --nodigest --qf '%|EPOCH?{%{EPOCH}:}:{}|%{VERSION}-%{RELEASE}\n' package_name ``` -## file.contains -> file.contents +## `file.contains` -> `file.contents` File contains attribute has been renamed to file.contents @@ -57,7 +58,7 @@ file: to: -``` +```yaml file: /tmp/foo: exists: true diff --git a/docs/platform-feature-parity.md b/docs/platform-feature-parity.md deleted file mode 100644 index c5f388503..000000000 --- a/docs/platform-feature-parity.md +++ /dev/null @@ -1,164 +0,0 @@ -# Platform feature-parity - -macOS and Windows binaries are new and considered alpha-quality. Some functionality may be missing, some may be broken. (Enhancements and bug-reports welcome, please see [#551: Multi-OS support](https://github.com/goss-org/goss/issues/551)). - -To clearly signal that, goss emits a log message on every invocation saying so, linking here, then exits with a clear error. - -To try out the alpha functionality, you must do one of: - -* pass `--use-alpha=1` to the root command - e.g. `goss --use-alpha=1 validate`. -* set an environment variable `GOSS_USE_ALPHA=1`. - -The macOS and Windows support is community driven; there is no commitment to adding features / fixing bugs for those platforms. [See thread](https://github.com/goss-org/goss/pull/585#discussion_r429968540). - -This matrix attempts to track parity across platforms. - -## How to use this doc - -### Legend - -* `x` - full supported/tested -* `w` - full working/tested, community support -* `wp-pt` - works partially / partially tested - * this is ambiguous; where you see this, check into the test coverage within `integration-tests/goss/{darwin|windows}/{test}.goss.yaml` for more detail. It might be that not all features work as on `linux`, it might be that not all features are covered by automated tests. -* `w-nt` - works no automated tests -* `ni` - not implemented / needs implementation -* `n/a` - Not applicable for this platform -* `#585` - Link to bug(s) for implementation, fixing -* ` ` - (blank) - not yet tried, no data - -### Contributing - -The current integration test approach is only appropriate for validating `linux` binaries against `linux` OS/arch combinations. - -Validating `macOS` and `Windows` binaries requires adding coverage that runs on those platforms within Travis, but since Travis does not support containerised builds for either platform, assertions are limited to assert against the state of the CI hosts, where we're relying on that to predictable. - -You can find goss-files that are used to populate this matrix within `integration-tests/goss/{darwin|windows}/{test}.goss.yaml`. Where a feature does note work the same as linux, it is commented. The intent is to end up with a set of running-and-passing tests. - -## Matrix - tests/assertions - -| Test | `linux` | `macOS` | `Windows` | -|:--------------------|---------|---------|-----------| -| **addr** | x | wp-pt | wp-pt | -| reachable | x | wp-pt | wp-pt | -| local-address | x | | wp-pt | -| timeout | x | w-nt | w-nt | -| | x | | | -| **command** | x | wp-pt | wp-pt | -| exit-status | x | wp-pt | wp-pt | -| stdout | x | wp-pt | wp-pt | -| stderr | x | w-nt | w-nt | -| timeout | x | w-nt | w-nt | -| | x | | | -| **dns** | x | wp-pt | wp-pt | -| resolvable | x | wp-pt | wp-pt | -| addrs | x | wp-pt | wp-pt | -| server | x | | wp-pt | -| timeout | x | w-nt | wp-pt | -| | | | | -| **file** | x | wp-pt | wp-pt | -| exists | x | wp-pt | w | -| mode | x | wp-pt | n/a | -| size | x | wp-pt | wp-pt | -| owner | x | broken | n/a | -| group | x | broken | n/a | -| filetype | x | wp-pt | wp-pt | -| contains | x | wp-pt | wp-pt | -| md5 | x | wp-pt | wp-pt | -| sha256 | x | wp-pt | wp-pt | -| linked-to | x | | | -| | x | | | -| **gossfile** | x | wp-pt | wp-pt | -| | x | | | -| **group** | x | ni | ni | -| exists | x | ni | ni | -| gid | x | ni | n/a | -| | x | | | -| **http** | x | wp-pt | wp-pt | -| status | x | wp-pt | wp-pt | -| allow-insecure | x | wp-pt | wp-pt | -| no-follow-redirects | x | wp-pt | wp-pt | -| timeout | x | w-nt | wp-pt | -| request-headers | x | wp-pt | wp-pt | -| headers | x | wp-pt | wp-pt | -| body | x | wp-pt | wp-pt | -| username | x | w-nt | wp-pt | -| password | x | w-nt | wp-pt | -| | | | | -| **interface** | x | ni | ni | -| exists | x | ni | ni | -| addrs | x | ni | ni | -| mtu | x | ni | ni | -| | x | | | -| **kernel-param** | x | n/a | n/a | -| value | x | n/a | n/a | -| | x | | | -| **mount** | x | ni | ni | -| exists | x | ni | ni | -| opts | x | ni | n/a | -| source | x | ni | n/a | -| filesystem | x | ni | ni | -| usage | x | ni | ni | -| | x | | | -| **matching** | x | | | -| | x | | | -| **package** | x | ni | ni | -| installed | x | ni | ni | -| versions | x | ni | ni | -| | x | | | -| **port** | x | ni | ni | -| listening | x | ni | ni | -| ip | x | | | -| | x | | | -| **process** | x | wp-pt | wp-pt | -| running | x | wp-pt | wp-pt | -| | x | | | -| **service** | x | ni | ni | -| enabled | x | ni | ni | -| running | x | ni | ni | -| | x | | | -| **user** | x | ni | ni | -| exists | x | ni | ni | -| uid | x | ni | n/a | -| gid | x | ni | n/a | -| groups | x | ni | ni | -| home | x | ni | ni | -| shell | x | ni | ni | - -## Matrix - `command`s - -| Test | `linux` | `macOS` | `Windows` | -|:-----------|---------|---------|-----------| -| `add` | x | | wp-pt | -| `autoadd` | x | | | -| `help` | x | | wp-pt | -| `render` | x | | | -| `serve` | x | w-nt | | -| `validate` | x | w-nt | wp-pt | - -### `command` testing notes - -Run all of the `darwin`/`windows` integration tests: - -```bash -make test-int-validate-darwin-amd64 -make test-int-validate-windows-amd64 -``` - -The script finds all goss spec files within `integration-tests` then filters to just ones matching the passed OS-name, then runs `validate` against them. - -### Command: `serve` - -This is a special-case test since it requires a persistent process, then to make the http request, then to tear down the process. - -#### macOS `serve` - -```bash -make "test-int-serve-darwin-amd64" -``` - -#### Windows `serve` - -```bash -make "test-int-serve-windows-amd64" -``` diff --git a/docs/platforms.md b/docs/platforms.md new file mode 100644 index 000000000..340859d5c --- /dev/null +++ b/docs/platforms.md @@ -0,0 +1,174 @@ +--- +render_macros: true + +fully_supported: :fontawesome-solid-circle-check:{ .green title="Fully supported/tested" } +community_supported: :fontawesome-solid-circle-check:{ .blue title="Fully working/tested, community support" } +not_automated: :fontawesome-solid-circle-pause:{ .green title="Works but is not covered by automated tests" } +work_partially: :fontawesome-solid-circle-minus:{ .orange title="Works partially / partially tested" } +not_implemented: :fontawesome-solid-circle-xmark:{ .red title="Not implemented / needs implementation" } +broken: :material-image-broken-variant:{ .red title="Currently broken" } +n_a: :fontawesome-regular-circle:{ .grey title="Not applicable for this platform" } +no_data: :fontawesome-regular-circle-question:{ .grey title="Not yet tried, no data" } +--- +# Platform feature-parity + +macOS and Windows binaries are new and considered alpha-quality. +Some functionality may be missing, some may be broken. +(Enhancements and bug-reports welcome, please see #551) + +To clearly signal that, goss emits a log message on every invocation saying so, linking here, then exits with a clear error. + +To try out the alpha functionality, you must do one of: + +* pass `--use-alpha=1` to the root command (e.g. `goss --use-alpha=1 validate`). +* set an environment variable `GOSS_USE_ALPHA=1`. + +The macOS and Windows support is community driven; +there is no commitment to adding features / fixing bugs for those platforms. +[See thread](https://github.com/goss-org/goss/pull/585#discussion_r429968540). + +This matrix attempts to track parity across platforms. + +## Legend + +| Symbol | Meaning | +|:-----------------------:|----------------------------------------| +| {{ fully_supported }} | Fully supported/tested | +| {{community_supported}} | Full working/tested, community support | +| {{ not_automated }} | Works but without automated tests | +| {{ work_partially }} | Works partially / partially tested | +| {{ not_implemented }} | Not implemented / needs implementation | +| {{ n_a }} | Not applicable for this platform | +| {{ no_data }} | Not yet tried, no data | + +!!! note "About partial support" + + This is ambiguous. Where you see this, check into the test coverage within `integration-tests/goss/{darwin|windows}/{test}.goss.yaml` for more detail. + It might be that not all features work as on `linux`, it might be that not all features are covered by automated tests. + +## Tests/assertions support matrix + +| Test | Option | Linux | macOS | Windows | +|:--------------------|:--------------------|:-----------------------:|:----------------------:|:-----------------------:| +| **addr** | | {{ fully_supported }} | {{ work_partially }} | {{ work_partially }} | +| | reachable | {{ fully_supported }} | {{ work_partially }} | {{ work_partially }} | +| | local-address | {{ fully_supported }} | {{ no_data }} | {{ work_partially }} | +| | timeout | {{ fully_supported }} | {{ not_automated }} | {{ not_automated }} | +| **command** | | {{ fully_supported }} | {{ work_partially }} | {{ work_partially }} | +| | exit-status | {{ fully_supported }} | {{ work_partially }} | {{ work_partially }} | +| | stdout | {{ fully_supported }} | {{ work_partially }} | {{ work_partially }} | +| | stderr | {{ fully_supported }} | {{ not_automated }} | {{ not_automated }} | +| | timeout | {{ fully_supported }} | {{ not_automated }} | {{ not_automated }} | +| **dns** | | {{ fully_supported }} | {{ work_partially }} | {{ work_partially }} | +| | resolvable | {{ fully_supported }} | {{ work_partially }} | {{ work_partially }} | +| | addrs | {{ fully_supported }} | {{ work_partially }} | {{ work_partially }} | +| | server | {{ fully_supported }} | {{ no_data }} | {{ work_partially }} | +| | timeout | {{ fully_supported }} | {{ not_automated }} | {{ work_partially }} | +| **file** | | {{ fully_supported }} | {{ work_partially }} | {{ work_partially }} | +| | exists | {{ fully_supported }} | {{ work_partially }} | {{community_supported}} | +| | mode | {{ fully_supported }} | {{ work_partially }} | {{ n_a }} | +| | size | {{ fully_supported }} | {{ work_partially }} | {{ work_partially }} | +| | owner | {{ fully_supported }} | {{ broken }} | {{ n_a }} | +| | group | {{ fully_supported }} | {{ broken }} | {{ n_a }} | +| | filetype | {{ fully_supported }} | {{ work_partially }} | {{ work_partially }} | +| | contains | {{ fully_supported }} | {{ work_partially }} | {{ work_partially }} | +| | md5 | {{ fully_supported }} | {{ work_partially }} | {{ work_partially }} | +| | sha256 | {{ fully_supported }} | {{ work_partially }} | {{ work_partially }} | +| | linked-to | {{ fully_supported }} | {{ no_data }} | {{ no_data }} | +| **gossfile** | | {{ fully_supported }} | {{ work_partially }} | {{ work_partially }} | +| **group** | | {{ fully_supported }} | {{ not_implemented }} | {{ not_implemented }} | +| | exists | {{ fully_supported }} | {{ not_implemented }} | {{ not_implemented }} | +| | gid | {{ fully_supported }} | {{ not_implemented }} | {{ n_a }} | +| **http** | | {{ fully_supported }} | {{ work_partially }} | {{ work_partially }} | +| | status | {{ fully_supported }} | {{ work_partially }} | {{ work_partially }} | +| | allow-insecure | {{ fully_supported }} | {{ work_partially }} | {{ work_partially }} | +| | no-follow-redirects | {{ fully_supported }} | {{ work_partially }} | {{ work_partially }} | +| | timeout | {{ fully_supported }} | {{ not_automated }} | {{ work_partially }} | +| | request-headers | {{ fully_supported }} | {{ work_partially }} | {{ work_partially }} | +| | headers | {{ fully_supported }} | {{ work_partially }} | {{ work_partially }} | +| | body | {{ fully_supported }} | {{ work_partially }} | {{ work_partially }} | +| | username | {{ fully_supported }} | {{ not_automated }} | {{ work_partially }} | +| | password | {{ fully_supported }} | {{ not_automated }} | {{ work_partially }} | +| **interface** | | {{ fully_supported }} | {{ not_implemented }} | {{ not_implemented }} | +| | exists | {{ fully_supported }} | {{ not_implemented }} | {{ not_implemented }} | +| | addrs | {{ fully_supported }} | {{ not_implemented }} | {{ not_implemented }} | +| | mtu | {{ fully_supported }} | {{ not_implemented }} | {{ not_implemented }} | +| **kernel-param** | | {{ fully_supported }} | {{ n_a }} | {{ n_a }} | +| | value | {{ fully_supported }} | {{ n_a }} | {{ n_a }} | +| **mount** | | {{ fully_supported }} | {{ not_implemented }} | {{ not_implemented }} | +| | exists | {{ fully_supported }} | {{ not_implemented }} | {{ not_implemented }} | +| | opts | {{ fully_supported }} | {{ not_implemented }} | {{ n_a }} | +| | source | {{ fully_supported }} | {{ not_implemented }} | {{ n_a }} | +| | filesystem | {{ fully_supported }} | {{ not_implemented }} | {{ not_implemented }} | +| | usage | {{ fully_supported }} | {{ not_implemented }} | {{ not_implemented }} | +| **matching** | | {{ fully_supported }} | {{ no_data }} | {{ no_data }} | +| **package** | | {{ fully_supported }} | {{ not_implemented }} | {{ not_implemented }} | +| | installed | {{ fully_supported }} | {{ not_implemented }} | {{ not_implemented }} | +| | versions | {{ fully_supported }} | {{ not_implemented }} | {{ not_implemented }} | +| **port** | | {{ fully_supported }} | {{ not_implemented }} | {{ not_implemented }} | +| | listening | {{ fully_supported }} | {{ not_implemented }} | {{ not_implemented }} | +| | ip | {{ fully_supported }} | {{ no_data }} | {{ no_data }} | +| **process** | | {{ fully_supported }} | {{ work_partially }} | {{ work_partially }} | +| | running | {{ fully_supported }} | {{ work_partially }} | {{ work_partially }} | +| **service** | | {{ fully_supported }} | {{ not_implemented }} | {{ not_implemented }} | +| | enabled | {{ fully_supported }} | {{ not_implemented }} | {{ not_implemented }} | +| | running | {{ fully_supported }} | {{ not_implemented }} | {{ not_implemented }} | +| **user** | | {{ fully_supported }} | {{ not_implemented }} | {{ not_implemented }} | +| | exists | {{ fully_supported }} | {{ not_implemented }} | {{ not_implemented }} | +| | uid | {{ fully_supported }} | {{ not_implemented }} | {{ n_a }} | +| | gid | {{ fully_supported }} | {{ not_implemented }} | {{ n_a }} | +| | groups | {{ fully_supported }} | {{ not_implemented }} | {{ not_implemented }} | +| | home | {{ fully_supported }} | {{ not_implemented }} | {{ not_implemented }} | +| | shell | {{ fully_supported }} | {{ not_implemented }} | {{ not_implemented }} | + +## Commands support matrix + +| Test | Linux | macOS | Windows | +|:-----------|------------------------|---------------------|----------------------| +| `add` | {{ fully_supported }} | {{ no_data }} | {{ work_partially }} | +| `autoadd` | {{ fully_supported }} | {{ no_data }} | {{ no_data }} | +| `help` | {{ fully_supported }} | {{ no_data }} | {{ work_partially }} | +| `render` | {{ fully_supported }} | {{ no_data }} | {{ no_data }} | +| `serve` | {{ fully_supported }} | {{ not_automated }} | {{ no_data }} | +| `validate` | {{ fully_supported }} | {{ not_automated }} | {{ work_partially }} | + +### `command` testing notes + +Run all of the `darwin`/`windows` integration tests: + +```bash +make test-int-validate-darwin-amd64 +make test-int-validate-windows-amd64 +``` + +The script finds all goss spec files within `integration-tests` then filters to just ones matching the passed OS-name, +then runs `validate` against them. + +### Command: `serve` + +This is a special-case test since it requires a persistent process, +then to make the http request, then to tear down the process. + +#### macOS `serve` + +```bash +make "test-int-serve-darwin-amd64" +``` + +#### Windows `serve` + +```bash +make "test-int-serve-windows-amd64" +``` + +## Contributing + +The current integration test approach is only appropriate for validating `linux` binaries against `linux` OS/arch combinations. + +Validating `macOS` and `Windows` binaries requires adding coverage that runs on those platforms within Travis, +but since Travis does not support containerised builds for either platform, +assertions are limited to assert against the state of the CI hosts, where we're relying on that to predictable. + +You can find goss-files that are used to populate this matrix within `integration-tests/goss/{darwin|windows}/{test}.goss.yaml`. +Where a feature does note work the same as linux, it is commented. +The intent is to end up with a set of running-and-passing tests. diff --git a/docs/quickstart.md b/docs/quickstart.md new file mode 100644 index 000000000..4219a70a1 --- /dev/null +++ b/docs/quickstart.md @@ -0,0 +1,3 @@ +# Quick start + +--8<-- "README.md:quickstart" diff --git a/docs/requirements.pip b/docs/requirements.pip new file mode 100644 index 000000000..cfa4c09da --- /dev/null +++ b/docs/requirements.pip @@ -0,0 +1,6 @@ +mkdocs-material==9.5.3 +mkdocs-macros-plugin==1.0.5 +mkdocs-awesome-pages-plugin==2.9.2 +mdx-breakless-lists==1.0.1 +pygments==2.17.2 + diff --git a/docs/goss-json-schema.yaml b/docs/schema.yaml similarity index 95% rename from docs/goss-json-schema.yaml rename to docs/schema.yaml index f09acc1c4..730aebda7 100644 --- a/docs/goss-json-schema.yaml +++ b/docs/schema.yaml @@ -1,4 +1,4 @@ -$id: "https://github.com/goss-org/goss/master/docs/goss-json-schema.yaml" +$id: "https://goss.rocks/schema.yaml" # Note: this schema was authored using intellij support for Json schema version 7 # providing coding assistance # This schema is based on content from https://github.com/goss-org/goss/blob/master/docs/manual.md and @@ -51,12 +51,12 @@ definitions: type: string stdout: type: array - description: "can be a string or pattern, see https://github.com/goss-org/goss/blob/master/docs/manual.md#patterns" + description: "can be a string or pattern, see https://goss.rocks/gossfile#patterns" items: type: string stderr: type: array - description: "can be a string or pattern, see https://github.com/goss-org/goss/blob/master/docs/manual.md#patterns" + description: "can be a string or pattern, see https://goss.rocks/gossfile#patterns" items: type: string timeout: @@ -568,7 +568,7 @@ properties: -

Please note that if you want localhost to only resolve 127.0.0.1 you'll need to use Advanced Matchers

+

Please note that if you want localhost to only resolve 127.0.0.1 you'll need to use Advanced Matchers

dns:
           localhost:
             resolvable: true
@@ -592,7 +592,7 @@ properties:
 
         If the 'skip' attribute is true, then the file is not processed. If the filename is a glob pattern, then none of the matching files are processed. Note that this is not the same as skipping the contained resources; any overrides in the referenced gossfile will not be processed, and the resource count will not be incremented. Skipping a gossfile include is the same as omitting the gossfile resource entirely.
       x-intellij-html-description: |
-        Import other gossfiles from this one. This is the best way to maintain a large number of tests, and/or create profiles. See render for more examples. Glob patterns can be also be used to specify matching gossfiles.

+ Import other gossfiles from this one. This is the best way to maintain a large number of tests, and/or create profiles. See render for more examples. Glob patterns can be also be used to specify matching gossfiles.

gossfile:
           myapplication:
             file: myapp_gossfile.yaml
@@ -650,8 +650,8 @@ properties:
       type: object
       description: "Validates specified content against a matcher. Best used with Templates."
       x-intellij-html-description: |
-        

Validates specified content against a matcher. Best used with Templates.

-

With Templates:

+

Validates specified content against a matcher. Best used with Templates.

+

With Templates:

Let's say we have a data.json file that gets generated as part of some testing pipeline:

{
           "instance_count": 14,
@@ -678,11 +678,11 @@ properties:
             content: {{ .Vars.instance_count }}
             matches:
               gt: 0
-        
+
           check_failure_count_from_all_instance: # expect no failures
             content: {{ .Vars.failures }}
             matches: 0
-        
+
           check_status:
             content: {{ .Vars.status }}
             matches:
@@ -692,11 +692,11 @@ properties:
             content: {{ .Vars.instance_count }}
             matches:
               gt: 0
-        
+
           check_failure_count_from_all_instance: # expect no failures
             content: {{ .Vars.failures }}
             matches: 0
-        
+
           check_status:
             content: {{ .Vars.status }}
             matches:
@@ -709,7 +709,7 @@ properties:
         
             
           
-

Without Templates:

+

Without Templates:

matching:
           has_substr: # friendly test name
             content: some string
@@ -756,7 +756,7 @@ properties:
         
             
           
- + additionalProperties: $ref: "#/definitions/matchTest" diff --git a/docs/style.css b/docs/style.css new file mode 100644 index 000000000..910f88111 --- /dev/null +++ b/docs/style.css @@ -0,0 +1,15 @@ +.green { + color: green; +} + +.blue { + color: cyan; +} + +.orange { + color: orange; +} + +.red { + color: red; +} diff --git a/extras/dcgoss/README.md b/extras/dcgoss/README.md index 74248d675..06d64498a 100644 --- a/extras/dcgoss/README.md +++ b/extras/dcgoss/README.md @@ -6,7 +6,6 @@ dcgoss is a convenience wrapper around goss that aims to bring the simplicity of `dcgoss [run|edit] ` - ### Run Run is used to validate a docker container defined in `docker-compose.yml`. It expects both a `docker-compose.yml` and `goss.yaml` file to exist in the directory it was invoked from. Container configuration is used from the compose file, for example: @@ -20,70 +19,98 @@ Run is used to validate a docker container defined in `docker-compose.yml`. It e `dcgoss run db` `dcgoss run` will do the following: + * Start the container as defined in `docker-compose.yml` * Stream the containers log output into the container as `/goss/docker_output.log` - * This allows writing tests or waits against the docker output + * This allows writing tests or waits against the docker output * (optional) Run `goss` with `$GOSS_WAIT_OPTS` if `./goss_wait.yaml` file exists in the current dir * Run `goss` with `$GOSS_OPTS` using `./goss.yaml` - ### Edit -Edit will launch a docker container, install goss, and drop the user into an interactive shell. Once the user quits the interactive shell, any `goss.yaml` or `goss_wait.yaml` are copied out into the current directory. This allows the user to leverage the `goss add|autoadd` commands to write tests as they would on a regular machine. +Edit will launch a docker container, install goss, and drop the user into an interactive shell. +Once the user quits the interactive shell, any `goss.yaml` or `goss_wait.yaml` are copied out into the current directory. +This allows the user to leverage the `goss add|autoadd` commands to write tests as they would on a regular machine. **Example:** `dcgoss edit db` ### Environment vars and defaults + The following environment variables can be set to change the behavior of dcgoss. -##### DEBUG -Enables debug output of `dcgoss`. (Default: empty) +#### DEBUG +Enables debug output of `dcgoss`. + When running in debug mode, the tmp dir with the container output will not be cleaned up. +**Default:** empty + **Example:** `DEBUG=true dcgoss edit db` -##### GOSS_PATH -Location of the goss binary to use. (Default: `$(which goss)`) +#### GOSS_PATH + +Location of the goss binary to use. + +**Default:** `$(which goss)` + +#### GOSS_OPTS + +Options to use for the goss test run. + +**Default:** `--color --format documentation` -##### GOSS_OPTS -Options to use for the goss test run. (Default: `--color --format documentation`) +#### GOSS_WAIT_OPTS -##### GOSS_WAIT_OPTS Options to use for the goss wait run, when `./goss_wait.yaml` exists. (Default: `-r 30s -s 1s > /dev/null`) -##### GOSS_SLEEP -Time to sleep after running container (and optionally `goss_wait.yaml`) and before running tests. (Default: `0.2`) +#### GOSS_SLEEP -##### GOSS_FILES_PATH -Location of the goss yaml files. (Default: `.`) +Time to sleep after running container (and optionally `goss_wait.yaml`) and before running tests. + +**Default:** `0.2` + +#### GOSS_FILES_PATH + +Location of the goss yaml files. + +**Default:** `.` **Example:** `GOSS_FILES_PATH=db dcgoss edit db` -##### GOSS_FILE +#### GOSS_FILE + Allows to specify a differing name for `goss.yaml`. Useful when the same image is started for different configurations. **Example:** `GOSS_FILE=goss_config1.yaml dcgoss run db` -##### GOSS_VARS +#### GOSS_VARS + The name of the variables file relative to `GOSS_FILES_PATH` to copy into the docker container and use for valiation (i.e. `dcgoss run`) and copy out of the docker container when writing tests (i.e. `dcgoss edit`). If set, the `--vars` flag is passed to `goss validate` commands inside the container. If unset (or empty), the `--vars` flag is omitted, which is the normal behavior. -(Default: `''`). -##### GOSS_FILES_STRATEGY -Strategy used for copying goss files into the docker container. If set to `'mount'` a volume with goss files is mounted and log output is streamed into the container as `/goss/docker_output.log` file. Other strategy is `'cp'` which uses `'docker cp'` command to copy goss files into docker container. With the `'cp'` strategy you lose the ability to write tests or waits against the docker output. The `'cp'` strategy is required especially when docker daemon is not on the local machine. -(Default `'mount'`) +**Default:** `''` + +#### GOSS_FILES_STRATEGY + +Strategy used for copying goss files into the docker container. +If set to `'mount'` a volume with goss files is mounted and log output is streamed into the container as `/goss/docker_output.log` file. +Other strategy is `'cp'` which uses `'docker cp'` command to copy goss files into docker container. +With the `'cp'` strategy you lose the ability to write tests or waits against the docker output. +The `'cp'` strategy is required especially when docker daemon is not on the local machine. + +**Default:** `'mount'` ## Debugging test runs diff --git a/extras/dgoss/README.md b/extras/dgoss/README.md index e4a8941d5..beedc739e 100644 --- a/extras/dgoss/README.md +++ b/extras/dgoss/README.md @@ -3,19 +3,22 @@ dgoss is a convenience wrapper around goss that aims to bring the simplicity of goss to docker containers. ## Examples and Tutorials + * [blog tutorial](https://medium.com/@aelsabbahy/tutorial-how-to-test-your-docker-image-in-half-a-second-bbd13e06a4a9) - Introduction to dgoss tutorial * [video tutorial](https://youtu.be/PEHz5EnZ-FM) - Same as above, but in video format * [dgoss-examples](https://github.com/aelsabbahy/dgoss-examples) - Repo containing examples of using dgoss to validate docker images ## Installation -#### Linux: + +### Linux Follow the goss [installation instructions](https://github.com/goss-org/goss#installation) -#### Mac OSX +### Mac OSX Since goss runs on the target container, dgoss can be used on a Mac OSX system by doing the following: -``` + +```shell # Install dgoss curl -L https://raw.githubusercontent.com/goss-org/goss/master/extras/dgoss/dgoss -o /usr/local/bin/dgoss chmod +rx /usr/local/bin/dgoss @@ -31,15 +34,15 @@ dgoss edit ... dgoss run ... ``` - ## Usage `dgoss [run|edit] ` - ### Run -Run is used to validate a docker container. It expects a `./goss.yaml` file to exist in the directory it was invoked from. In most cases one can just substitute the docker command for the dgoss command, for example: +Run is used to validate a docker container. +It expects a `./goss.yaml` file to exist in the directory it was invoked from. +In most cases one can just substitute the docker command for the dgoss command, for example: **run:** @@ -49,15 +52,14 @@ Run is used to validate a docker container. It expects a `./goss.yaml` file to e `dgoss run -e JENKINS_OPTS="--httpPort=8080 --httpsPort=-1" -e JAVA_OPTS="-Xmx1048m" jenkins:alpine` - `dgoss run` will do the following: + * Run the container with the flags you specified. * Stream the containers log output into the container as `/goss/docker_output.log` - * This allows writing tests or waits against the docker output + * This allows writing tests or waits against the docker output * (optional) Run `goss` with `$GOSS_WAIT_OPTS` if `./goss_wait.yaml` file exists in the current dir * Run `goss` with `$GOSS_OPTS` using `./goss.yaml` - ### Edit Edit will launch a docker container, install goss, and drop the user into an interactive shell. Once the user quits the interactive shell, any `goss.yaml` or `goss_wait.yaml` are copied out into the current directory. This allows the user to leverage the `goss add|autoadd` commands to write tests as they would on a regular machine. @@ -67,27 +69,35 @@ Edit will launch a docker container, install goss, and drop the user into an int `dgoss edit -e JENKINS_OPTS="--httpPort=8080 --httpsPort=-1" -e JAVA_OPTS="-Xmx1048m" jenkins:alpine` ### Environment vars and defaults + The following environment variables can be set to change the behavior of dgoss. -##### GOSS_PATH +#### GOSS_PATH + Location of the goss binary to use. (Default: `$(which goss)`) -##### GOSS_FILE +#### GOSS_FILE + Name of the goss file to use. (Default: `goss.yaml`) -##### GOSS_OPTS +#### GOSS_OPTS + Options to use for the goss test run. (Default: `--color --format documentation`) -##### GOSS_WAIT_OPTS +#### GOSS_WAIT_OPTS + Options to use for the goss wait run, when `./goss_wait.yaml` exists. (Default: `-r 30s -s 1s > /dev/null`) -##### GOSS_SLEEP +#### GOSS_SLEEP + Time to sleep after running container (and optionally `goss_wait.yaml`) and before running tests. (Default: `0.2`) -##### GOSS_FILES_PATH +#### GOSS_FILES_PATH + Location of the goss yaml files. (Default: `.`) -##### GOSS_VARS +#### GOSS_VARS + The name of the variables file relative to `GOSS_FILES_PATH` to copy into the docker container and use for valiation (i.e. `dgoss run`) and copy out of the docker container when writing tests (i.e. `dgoss edit`). If set, the @@ -95,15 +105,19 @@ docker container when writing tests (i.e. `dgoss edit`). If set, the If unset (or empty), the `--vars` flag is omitted, which is the normal behavior. (Default: `''`). -##### GOSS_FILES_STRATEGY +#### GOSS_FILES_STRATEGY + Strategy used for copying goss files into the docker container. If set to `'mount'` a volume with goss files is mounted and log output is streamed into the container as `/goss/docker_output.log` file. Other strategy is `'cp'` which uses `'docker cp'` command to copy goss files into docker container. With the `'cp'` strategy you lose the ability to write tests or waits against the docker output. The `'cp'` strategy is required especially when docker daemon is not on the local machine. (Default `'mount'`) -##### CONTAINER_LOG_OUTPUT +#### CONTAINER_LOG_OUTPUT + Location of the file that contains tested container logs. Logs are retained only if the variable is set to a non-empty string. (Default `''`) -##### DGOSS_TEMP_DIR +#### DGOSS_TEMP_DIR + Location of the temporary directory used by dgoss. (Default `'$(mktemp -d /tmp/tmp.XXXXXXXXXX)'`) -##### CONTAINER_RUNTIME -Container runtime to use - `docker` or `podman`. Defaults to `docker`. Note that `podman` requires a run command to keep the container running. This defaults to `sleep infinity` in case only an image is passed to `dgoss` commands. \ No newline at end of file +#### CONTAINER_RUNTIME + +Container runtime to use - `docker` or `podman`. Defaults to `docker`. Note that `podman` requires a run command to keep the container running. This defaults to `sleep infinity` in case only an image is passed to `dgoss` commands. diff --git a/extras/kgoss/README.md b/extras/kgoss/README.md index e34196327..ae3cbb047 100644 --- a/extras/kgoss/README.md +++ b/extras/kgoss/README.md @@ -17,7 +17,7 @@ Installing kgoss requires copying the kgoss file to a directory in your PATH and copying the goss file to your home folder (or a path set as `GOSS_PATH`), as follows. -#### Manual / UI +### Manual / UI You can manually install kgoss and goss by going through the Web UI, getting the files and putting them in the right path. To get each of them: @@ -29,7 +29,7 @@ the files and putting them in the right path. To get each of them: in your HOME directory, e.g. C:\\Users\\ on Windows; or set the environment variable `GOSS_PATH` to its path. -#### Automatic / CLI +### Automatic / CLI To install from the command line or automatically, use the following commands. [jq][] is required to parse the API response and find the release asset's @@ -41,7 +41,7 @@ First get a GitHub personal access token for accessing the GitHub API from . Input it in the first line below. Set `dest_dir` to a directory in your `PATH` env var. -``` +```shell token= username=$(whoami) dest_dir=${HOME}/bin @@ -94,7 +94,7 @@ in the target container's `GOSS_CONTAINER_PATH`. To find `goss.yaml` in another directory specify that directory's path in `GOSS_FILES_PATH`. -#### Run +### Run The `run` command is used to validate a docker container. It expects a `./goss.yaml` file to exist in the directory it was invoked from. @@ -104,11 +104,12 @@ The `run` command is used to validate a docker container. It expects a `kgoss run -e JENKINS_OPTS="--httpPort=8080 --httpsPort=-1" -e JAVA_OPTS="-Xmx1048m" -i jenkins:alpine` `kgoss run` will do the following: + * Run the container with the start commands specified by `-c`, `-a`, or `-p`. * Run `goss` with `$GOSS_WAIT_OPTS` if `./goss_wait.yaml` file exists in the current dir. * Run `goss` with `$GOSS_OPTS` using `./goss.yaml` from `GOSS_FILES_PATH`. -#### Edit +### Edit Edit will launch a docker container, install goss, and drop the user into an interactive shell. Once the user quits the interactive shell, any `goss.yaml` diff --git a/mkdocs.yml b/mkdocs.yml new file mode 100644 index 000000000..547aaaa90 --- /dev/null +++ b/mkdocs.yml @@ -0,0 +1,100 @@ +site_name: Goss +site_description: Goss is a YAML based serverspec alternative tool for validating a server’s configuration. +site_author: Goss team +site_url: https://goss.readthedocs.io/ +repo_url: https://github.com/goss-org/goss +repo_name: goss-org/goss +edit_uri: edit/master/docs/ + + +theme: + name: material + palette: + - media: "(prefers-color-scheme: light)" + scheme: default + primary: black + accent: amber + toggle: + icon: material/weather-sunny + name: Switch to dark mode + - media: "(prefers-color-scheme: dark)" + scheme: slate + primary: black + accent: indigo + toggle: + icon: material/weather-night + name: Switch to light mode + features: + - content.action.edit + - content.code.copy + - navigation.footer + - navigation.instant + - navigation.instant.progress + - navigation.top + - navigation.tracking + - search.highlight + - search.share + - search.suggest + - toc.follow + + +extra_css: + - style.css + +plugins: + - search + - awesome-pages + - macros: + render_by_default: false + +markdown_extensions: + - abbr + - admonition + - attr_list + - def_list + - md_in_html + - mdx_breakless_lists + - tables + - pymdownx.details + - pymdownx.emoji: + emoji_index: !!python/name:material.extensions.emoji.twemoji + emoji_generator: !!python/name:material.extensions.emoji.to_svg + - pymdownx.highlight: + anchor_linenums: true + line_spans: __span + pygments_lang_class: true + - pymdownx.inlinehilite + - pymdownx.magiclink: + repo_url_shortener: true + social_url_shortener: true + repo_url_shorthand: true + social_url_shorthand: true + user: goss-org + repo: goss + - pymdownx.snippets: + base_path: + - . + - docs/snippets + check_paths: true + - pymdownx.superfences + +copyright: Copyright © 2015 - 2023 Ahmed Elsabbahy + +extra: + social: + - icon: fontawesome/brands/github + link: https://github.com/gooss-org/goss + - icon: simple/codeclimate + link: https://codeclimate.com/github/goss-org/goss + - icon: simple/travisci + link: https://travis-ci.org/goss-org/goss + - icon: fontawesome/brands/medium + link: https://medium.com/@aelsabbahy + +watch: + - README.md + - LICENSE + - .github/CONTRIBUTING.md + - extras/dcgoss/README.md + - extras/dgoss/README.md + - extras/kgoss/README.md