From d45722e82055c07679ab4f4f6535fb7bef127378 Mon Sep 17 00:00:00 2001 From: dklimpel <5740567+dklimpel@users.noreply.github.com> Date: Sat, 13 Jul 2024 23:05:55 +0200 Subject: [PATCH 1/4] ci: add validation with yamllint --- .github/workflows/docker-goss.yaml | 196 ++--- .github/workflows/yamllint.yaml | 17 + .yamllint | 20 +- docs/goss.yaml | 12 +- docs/myapp_gossfile.yaml | 2 +- docs/schema.yaml | 689 +++++++++--------- docs/vars.yaml | 2 +- examples/goss_awesome_gomega.yaml | 10 +- extras/dcgoss/docker-compose.yml | 46 +- integration-tests/goss/alpine3/goss.yaml | 1 - integration-tests/goss/arch/goss.yaml | 1 - integration-tests/goss/goss-dummy.yaml | 1 - integration-tests/goss/goss-shared.yaml | 1 - integration-tests/goss/trusty/goss.yaml | 1 - integration-tests/goss/wheezy/goss.yaml | 1 - .../goss/windows/commands/add.goss.yaml | 1 - mkdocs.yml | 4 +- testdata/matching_basic.yaml | 12 +- testdata/matching_basic_failing.yaml | 20 +- testdata/matching_transformers.yaml | 12 +- testdata/matching_transformers_failing.yaml | 12 +- 21 files changed, 541 insertions(+), 520 deletions(-) create mode 100644 .github/workflows/yamllint.yaml diff --git a/.github/workflows/docker-goss.yaml b/.github/workflows/docker-goss.yaml index 78e07bdcd..3b0287106 100644 --- a/.github/workflows/docker-goss.yaml +++ b/.github/workflows/docker-goss.yaml @@ -1,98 +1,98 @@ -name: Docker image for Goss - -on: - push: - branches: - - master - tags: - - "v*" - workflow_dispatch: - -env: - PLATFORMS: "linux/amd64,linux/arm64" - -jobs: - goss: - name: Build and push Docker image - runs-on: ubuntu-latest - permissions: - packages: write - contents: read - security-events: write # To upload Trivy sarif files - - steps: - - name: Checkout - uses: actions/checkout@v4 - - - name: Set up QEMU - uses: docker/setup-qemu-action@v3 - - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 - - - name: Login to GHCR - uses: docker/login-action@v3 - with: - registry: ghcr.io - username: ${{ github.repository_owner }} - password: ${{ secrets.GITHUB_TOKEN }} - - - name: Extract metadata (tags, labels) for Docker - id: meta - uses: docker/metadata-action@v5 - with: - images: | - ghcr.io/${{ github.repository_owner }}/goss - - - name: Get latest git tag - uses: actions-ecosystem/action-get-latest-tag@v1 - id: get-latest-tag - - - name: Set short git commit SHA - run: | - calculatedSha=$(git rev-parse --short ${{ github.sha }}) - echo "COMMIT_SHORT_SHA=$calculatedSha" >> $GITHUB_ENV - - - name: Get the current version of Go from project. - run: echo "GO_VERSION_FROM_PROJECT=$(go mod edit -json | jq -r .Go)" >> $GITHUB_ENV - - - name: Build master goss image - if: github.ref_name == 'master' - uses: docker/build-push-action@v5 - with: - build-args: | - GO_VERSION=${{ env.GO_VERSION_FROM_PROJECT }} - GOSS_VERSION=${{ steps.get-latest-tag.outputs.tag }}-${{ github.ref_name }}+${{ env.COMMIT_SHORT_SHA }} - context: . - push: true - tags: | - ghcr.io/${{ github.repository_owner }}/goss:master - labels: ${{ steps.meta.outputs.labels }} - platforms: ${{ env.PLATFORMS }} - - - name: Build release goss image - if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/') - uses: docker/build-push-action@v5 - with: - build-args: | - GO_VERSION=${{ env.GO_VERSION_FROM_PROJECT }} - GOSS_VERSION=${{ github.ref_name }} - context: . - push: true - tags: | - ghcr.io/${{ github.repository_owner }}/goss:latest - ghcr.io/${{ github.repository_owner }}/goss:${{ github.ref_name }} - labels: ${{ steps.meta.outputs.labels }} - platforms: ${{ env.PLATFORMS }} - - - name: Run Trivy vulnerability scanner - uses: aquasecurity/trivy-action@master - with: - image-ref: ghcr.io/${{ github.repository_owner }}/goss:master - format: "sarif" - output: "trivy-results.sarif" - - - name: Upload Trivy scan results to GitHub Security tab - uses: github/codeql-action/upload-sarif@v3 - with: - sarif_file: "trivy-results.sarif" +name: Docker image for Goss + +on: + push: + branches: + - master + tags: + - "v*" + workflow_dispatch: + +env: + PLATFORMS: "linux/amd64,linux/arm64" + +jobs: + goss: + name: Build and push Docker image + runs-on: ubuntu-latest + permissions: + packages: write + contents: read + security-events: write # To upload Trivy sarif files + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Login to GHCR + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.repository_owner }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Extract metadata (tags, labels) for Docker + id: meta + uses: docker/metadata-action@v5 + with: + images: | + ghcr.io/${{ github.repository_owner }}/goss + + - name: Get latest git tag + uses: actions-ecosystem/action-get-latest-tag@v1 + id: get-latest-tag + + - name: Set short git commit SHA + run: | + calculatedSha=$(git rev-parse --short ${{ github.sha }}) + echo "COMMIT_SHORT_SHA=$calculatedSha" >> $GITHUB_ENV + + - name: Get the current version of Go from project. + run: echo "GO_VERSION_FROM_PROJECT=$(go mod edit -json | jq -r .Go)" >> $GITHUB_ENV + + - name: Build master goss image + if: github.ref_name == 'master' + uses: docker/build-push-action@v5 + with: + build-args: | + GO_VERSION=${{ env.GO_VERSION_FROM_PROJECT }} + GOSS_VERSION=${{ steps.get-latest-tag.outputs.tag }}-${{ github.ref_name }}+${{ env.COMMIT_SHORT_SHA }} + context: . + push: true + tags: | + ghcr.io/${{ github.repository_owner }}/goss:master + labels: ${{ steps.meta.outputs.labels }} + platforms: ${{ env.PLATFORMS }} + + - name: Build release goss image + if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/') + uses: docker/build-push-action@v5 + with: + build-args: | + GO_VERSION=${{ env.GO_VERSION_FROM_PROJECT }} + GOSS_VERSION=${{ github.ref_name }} + context: . + push: true + tags: | + ghcr.io/${{ github.repository_owner }}/goss:latest + ghcr.io/${{ github.repository_owner }}/goss:${{ github.ref_name }} + labels: ${{ steps.meta.outputs.labels }} + platforms: ${{ env.PLATFORMS }} + + - name: Run Trivy vulnerability scanner + uses: aquasecurity/trivy-action@master + with: + image-ref: ghcr.io/${{ github.repository_owner }}/goss:master + format: "sarif" + output: "trivy-results.sarif" + + - name: Upload Trivy scan results to GitHub Security tab + uses: github/codeql-action/upload-sarif@v3 + with: + sarif_file: "trivy-results.sarif" diff --git a/.github/workflows/yamllint.yaml b/.github/workflows/yamllint.yaml new file mode 100644 index 000000000..0c887c2c2 --- /dev/null +++ b/.github/workflows/yamllint.yaml @@ -0,0 +1,17 @@ +name: Validate YAML + +on: + push: + branches: + - master + pull_request: + paths: + - "**/*.ya?ml" + +jobs: + validate-yaml: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Validate YAML file + run: yamllint -c .yamllint . diff --git a/.yamllint b/.yamllint index 8aeea49b0..b25fd9b88 100644 --- a/.yamllint +++ b/.yamllint @@ -1,8 +1,26 @@ --- extends: default +ignore: + # uses go templates (these are invalid yaml files) + - integration-tests/goss/goss-service.yaml + - integration-tests/goss/goss-shared.yaml + - docs/goss.yaml + rules: + braces: + min-spaces-inside: 0 + max-spaces-inside: 1 # required for schema.yaml + brackets: + min-spaces-inside: 0 + max-spaces-inside: 1 # required for schema.yaml + indentation: + spaces: consistent + indent-sequences: consistent line-length: disable + document-start: disable truthy: allowed-values: - - on + - "on" # required for github workflows + - "false" + - "true" diff --git a/docs/goss.yaml b/docs/goss.yaml index 61b47f508..a155c67dd 100644 --- a/docs/goss.yaml +++ b/docs/goss.yaml @@ -16,7 +16,7 @@ command: stdout: - go version go1.6 linux/amd64 stderr: [] - timeout: 10000 # in milliseconds + timeout: 10000 # in milliseconds skip: false dns: @@ -64,7 +64,7 @@ group: gid: 65534 nobody: exists: true - + http: https://www.google.com: @@ -190,14 +190,14 @@ user: home: /var/lib/nfs shell: /sbin/nologin skip: false - + nobody: exists: true uid: lt: 500 groups: consist-of: [nobody] - + sshd: title: UID must be between 50-100, GID doesn't matter. home is flexible meta: @@ -216,7 +216,3 @@ user: - /var/run/sshd # https://github.com/goss-org/goss/blob/master/README.md#manually-editing-goss-files - - - - diff --git a/docs/myapp_gossfile.yaml b/docs/myapp_gossfile.yaml index c5d79f5d9..74e42d2f1 100644 --- a/docs/myapp_gossfile.yaml +++ b/docs/myapp_gossfile.yaml @@ -1,2 +1,2 @@ # This is a sample file referenced by goss.yaml -# Used for render test and Json schema validation. \ No newline at end of file +# Used for render test and Json schema validation. diff --git a/docs/schema.yaml b/docs/schema.yaml index 4a5ac7310..661ae527d 100644 --- a/docs/schema.yaml +++ b/docs/schema.yaml @@ -242,12 +242,12 @@ definitions: key-file: type: string default: "" - description: | + description: | private-key file to use for authentication (used with cert-file) proxy: type: string default: "" - description: | + description: | proxy server to proxy traffic through. Proxy can also be set with environment variables http_proxy. skip: type: boolean @@ -256,8 +256,8 @@ definitions: type: string default: PUT description: http method - enum: # See https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Request_methods - # Note: not yet clear whether goss supports all methods + enum: # See https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Request_methods + # Note: not yet clear whether goss supports all methods - GET - PUT - HEAD @@ -281,8 +281,8 @@ definitions: items: type: string default: - - 172.17.0.2/16 - - fe80::42:acff:fe11:2/64 + - 172.17.0.2/16 + - fe80::42:acff:fe11:2/64 mtu: type: integer default: 1500 @@ -303,15 +303,15 @@ definitions: meta: { "$ref":"#/definitions/meta" } content: anyOf: - - type: string - default: "some string" - - type: array - default: - - 2 - - type: object - default: - foo: bar - baz: ring + - type: string + default: "some string" + - type: array + default: + - 2 + - type: object + default: + foo: bar + baz: ring matches: anyOf: - type: integer @@ -333,8 +333,8 @@ definitions: items: type: string default: - - rw - - relatime + - rw + - relatime source: type: string default: /dev/mapper/fedora-home @@ -360,12 +360,12 @@ definitions: default: true versions: oneOf: - - type: object # matcher + - type: object # matcher - type: array items: type: string default: - - 2.2.15 + - 2.2.15 skip: type: boolean default: false @@ -384,7 +384,7 @@ definitions: items: type: string default: - - 0.0.0.0 + - 0.0.0.0 skip: type: boolean default: false @@ -419,7 +419,7 @@ definitions: - exists properties: title: { "$ref": "#/definitions/title" } - meta: { "$ref": "#/definitions/meta" } + meta: { "$ref": "#/definitions/meta" } exists: type: boolean default: true @@ -442,7 +442,7 @@ definitions: items: type: string default: - - nfsnobody + - nfsnobody home: anyOf: - { "$ref": "#/definitions/matchingTest" } @@ -460,15 +460,15 @@ type: "object" properties: addr: - type: object - description: "Validates if a remote address:port are accessible." - examples: - - tcp://ip-address-or-domain-name:80: - reachable: true - timeout: 500 - local-address: 127.0.0.1 - additionalProperties: - $ref: "#/definitions/addrTest" + type: object + description: "Validates if a remote address:port are accessible." + examples: + - tcp://ip-address-or-domain-name:80: + reachable: true + timeout: 500 + local-address: 127.0.0.1 + additionalProperties: + $ref: "#/definitions/addrTest" command: type: object @@ -477,348 +477,345 @@ properties: $ref: "#/definitions/commandTest" dns: - type: object - description: "Validates that the provided address is resolvable and the addrs it resolves to." - x-intellij-html-description: | -

Validates that the provided address is resolvable and the addrs it resolves to.

-
dns:
-          localhost:
-            # required attributes
-            resolvable: true
-            # optional attributes
-            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)
- Validates that the provided address is resolvable and the addrs it resolves to.

+
dns:
+        localhost:
+          # required attributes
+          resolvable: true
+          # optional attributes
+          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:

-
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

-
dns:
-          localhost:
-            resolvable: true
-            addrs:
-              consist-of: [127.0.0.1]
-            timeout: 500 # in milliseconds
-      additionalProperties:
-        $ref: "#/definitions/dnsTest"
+          server: 8.8.8.8 # Also supports server:port
+          timeout: 500 # in milliseconds (Only used when server attribute is provided)" tabindex="0" role="button" style="display: none;">
+            
+            
+          
+        
+

It is possible to validate the following types of DNS records, but requires the server attribute be set:

+ +

To validate specific DNS address types, prepend the hostname with the type and a colon, a few examples:

+
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

+
dns:
+        localhost:
+          resolvable: true
+          addrs:
+            consist-of: [127.0.0.1]
+          timeout: 500 # in milliseconds
+    additionalProperties:
+      $ref: "#/definitions/dnsTest"
 
   file:
-      type: object
-      description: "Validates the state of a file, directory, or symbolic link"
-      additionalProperties:
-        $ref: "#/definitions/fileTest"
+    type: object
+    description: "Validates the state of a file, directory, or symbolic link"
+    additionalProperties:
+      $ref: "#/definitions/fileTest"
 
   gossfile:
-      type: object
-      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.
-        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.
-      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.

-
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.

- additionalProperties: - $ref: "#/definitions/gossfileTest" + type: object + 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. + 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. + 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.

+
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.

+ additionalProperties: + $ref: "#/definitions/gossfileTest" group: - type: object - description: "Validates the state of a group" - additionalProperties: - $ref: "#/definitions/groupTest" + type: object + description: "Validates the state of a group" + additionalProperties: + $ref: "#/definitions/groupTest" http: - type: object - description: "description: Validates network interface values" - additionalProperties: - $ref: "#/definitions/httpTest" + type: object + description: "description: Validates network interface values" + additionalProperties: + $ref: "#/definitions/httpTest" interface: - type: object - description: "test " - additionalProperties: - $ref: "#/definitions/interfaceTest" + type: object + description: "test " + additionalProperties: + $ref: "#/definitions/interfaceTest" kernel-param: - type: object - description: "test " - additionalProperties: - $ref: "#/definitions/kernelParamTest" + type: object + description: "test " + additionalProperties: + $ref: "#/definitions/kernelParamTest" matching: - 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:

-

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

-
{
-          "instance_count": 14,
-          "failures": 3,
-          "status": "FAIL"
-        }
- - - - -
-

This could then be passed into goss: goss --vars data.json validate

-

And then validated against:

-
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:

-
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-with-value:
-                    foo: bar
-                - have-key: baz
- -
+ 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:

+

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

+
{
+        "instance_count": 14,
+        "failures": 3,
+        "status": "FAIL"
+      }
+ + + + +
+

This could then be passed into goss: goss --vars data.json validate

+

And then validated against:

+
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:

+
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-with-value:
+                  foo: bar
+              - have-key: baz
+ +
- additionalProperties: + additionalProperties: $ref: "#/definitions/matchTest" mount: - type: object - description: "Validates mount point attributes." - additionalProperties: - $ref: "#/definitions/mountTest" + type: object + description: "Validates mount point attributes." + additionalProperties: + $ref: "#/definitions/mountTest" package: - type: object - description: | - Validates the state of a package" - NOTE: this check uses the --package parameter passed on the command line. - additionalProperties: - $ref: "#/definitions/packageTest" + type: object + description: | + Validates the state of a package" + NOTE: this check uses the --package parameter passed on the command line. + additionalProperties: + $ref: "#/definitions/packageTest" port: - type: object - description: | - 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) - x-intellij-html-description: | -

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)

-
port:
-          # {tcp,tcp6,udp,udp6}:port_num
-          tcp:22:
-            # required attributes
-            listening: true
-            # optional attributes
-            ip: # what IP(s) is it listening on
-            - 0.0.0.0
-            skip: false
-      additionalProperties:
-        $ref: "#/definitions/portTest"
+    type: object
+    description: |
+      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)
+    x-intellij-html-description: |
+      

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)

+
port:
+        # {tcp,tcp6,udp,udp6}:port_num
+        tcp:22:
+          # required attributes
+          listening: true
+          # optional attributes
+          ip: # what IP(s) is it listening on
+          - 0.0.0.0
+          skip: false
+    additionalProperties:
+      $ref: "#/definitions/portTest"
 
   process:
-      type: object
-      description: "Validates if a process is running."
-      additionalProperties:
-        $ref: "#/definitions/processTest"
+    type: object
+    description: "Validates if a process is running."
+    additionalProperties:
+      $ref: "#/definitions/processTest"
 
   service:
-      type: object
-      description: "Validates the state of a service."
-      additionalProperties:
-        $ref: "#/definitions/serviceTest"
+    type: object
+    description: "Validates the state of a service."
+    additionalProperties:
+      $ref: "#/definitions/serviceTest"
 
   user:
-      type: object
-      description: |
-        Validates the state of a user"
-        NOTE: This check is inspecting the contents of local passwd file /etc/passwd, this does not validate remote users (e.g. LDAP).
-      additionalProperties:
-        $ref: "#/definitions/userTest"
-
-
+    type: object
+    description: |
+      Validates the state of a user"
+      NOTE: This check is inspecting the contents of local passwd file /etc/passwd, this does not validate remote users (e.g. LDAP).
+    additionalProperties:
+      $ref: "#/definitions/userTest"
diff --git a/docs/vars.yaml b/docs/vars.yaml
index 19e03b8aa..d8e6cdd6e 100644
--- a/docs/vars.yaml
+++ b/docs/vars.yaml
@@ -2,4 +2,4 @@
 # Used for render test and Json schema validation.
 instance_count: 1
 failures: 0
-status: "PASS"
\ No newline at end of file
+status: "PASS"
diff --git a/examples/goss_awesome_gomega.yaml b/examples/goss_awesome_gomega.yaml
index 1a9a54aa8..e59f4b0f8 100644
--- a/examples/goss_awesome_gomega.yaml
+++ b/examples/goss_awesome_gomega.yaml
@@ -95,9 +95,9 @@ matching:
         - contain-element:
             have-prefix: 'moo'
         - contain-elements:
-          - not: 'this_doesnt_exist'
-          - lt: 20
-          - have-prefix: 'moo'
+            - not: 'this_doesnt_exist'
+            - lt: 20
+            - have-prefix: 'moo'
 
 
   test_reader_as_single_string:
@@ -110,8 +110,8 @@ matching:
     as-reader: true
     matches:
       and:
-       - le: 250
-       - ge: 20
+        - le: 250
+        - ge: 20
 
 
   test_gjson_transform:
diff --git a/extras/dcgoss/docker-compose.yml b/extras/dcgoss/docker-compose.yml
index 90813cbdc..62aba21c8 100644
--- a/extras/dcgoss/docker-compose.yml
+++ b/extras/dcgoss/docker-compose.yml
@@ -1,28 +1,28 @@
 version: '3.3'
 
 services:
-   db:
-     image: mysql:5.7
-     volumes:
-       - db_data:/var/lib/mysql
-     restart: always
-     environment:
-       MYSQL_ROOT_PASSWORD: somewordpress
-       MYSQL_DATABASE: wordpress
-       MYSQL_USER: wordpress
-       MYSQL_PASSWORD: wordpress
+  db:
+    image: mysql:5.7
+    volumes:
+      - db_data:/var/lib/mysql
+    restart: always
+    environment:
+      MYSQL_ROOT_PASSWORD: somewordpress
+      MYSQL_DATABASE: wordpress
+      MYSQL_USER: wordpress
+      MYSQL_PASSWORD: wordpress
 
-   wordpress:
-     depends_on:
-       - db
-     image: wordpress:latest
-     ports:
-       - "8000:80"
-     restart: always
-     environment:
-       WORDPRESS_DB_HOST: db:3306
-       WORDPRESS_DB_USER: wordpress
-       WORDPRESS_DB_PASSWORD: wordpress
-       WORDPRESS_DB_NAME: wordpress
+  wordpress:
+    depends_on:
+      - db
+    image: wordpress:latest
+    ports:
+      - "8000:80"
+    restart: always
+    environment:
+      WORDPRESS_DB_HOST: db:3306
+      WORDPRESS_DB_USER: wordpress
+      WORDPRESS_DB_PASSWORD: wordpress
+      WORDPRESS_DB_NAME: wordpress
 volumes:
-    db_data: {}
+  db_data: {}
diff --git a/integration-tests/goss/alpine3/goss.yaml b/integration-tests/goss/alpine3/goss.yaml
index 2a19e2e45..57b689bb1 100644
--- a/integration-tests/goss/alpine3/goss.yaml
+++ b/integration-tests/goss/alpine3/goss.yaml
@@ -32,4 +32,3 @@ gossfile:
   "../goss-s*.yaml": {}
   bypath:
     file: "../goss-dummy.yaml"
-
diff --git a/integration-tests/goss/arch/goss.yaml b/integration-tests/goss/arch/goss.yaml
index 50fad0d0c..c03c07bc8 100644
--- a/integration-tests/goss/arch/goss.yaml
+++ b/integration-tests/goss/arch/goss.yaml
@@ -20,4 +20,3 @@ gossfile:
   "../goss-shared.yaml": {}
   bypath:
     file: "../goss-dummy.yaml"
-
diff --git a/integration-tests/goss/goss-dummy.yaml b/integration-tests/goss/goss-dummy.yaml
index 241f9ef5e..339d255b2 100644
--- a/integration-tests/goss/goss-dummy.yaml
+++ b/integration-tests/goss/goss-dummy.yaml
@@ -1,4 +1,3 @@
-
 ---
 command:
   includetest:
diff --git a/integration-tests/goss/goss-shared.yaml b/integration-tests/goss/goss-shared.yaml
index 220ec4e8c..cdf81b185 100644
--- a/integration-tests/goss/goss-shared.yaml
+++ b/integration-tests/goss/goss-shared.yaml
@@ -293,4 +293,3 @@ gossfile:
     skip: true
   bypath:
     file: "goss-dummy.yaml"
-
diff --git a/integration-tests/goss/trusty/goss.yaml b/integration-tests/goss/trusty/goss.yaml
index ef6931160..97738c926 100644
--- a/integration-tests/goss/trusty/goss.yaml
+++ b/integration-tests/goss/trusty/goss.yaml
@@ -32,4 +32,3 @@ gossfile:
   "../goss-s*.yaml": {}
   bypath:
     file: "../goss-dummy.yaml"
-
diff --git a/integration-tests/goss/wheezy/goss.yaml b/integration-tests/goss/wheezy/goss.yaml
index c83ed1d0e..23cad4045 100644
--- a/integration-tests/goss/wheezy/goss.yaml
+++ b/integration-tests/goss/wheezy/goss.yaml
@@ -32,4 +32,3 @@ gossfile:
   "../goss-s*.yaml": {}
   bypath:
     file: "../goss-dummy.yaml"
-
diff --git a/integration-tests/goss/windows/commands/add.goss.yaml b/integration-tests/goss/windows/commands/add.goss.yaml
index d65d1899f..3df6e627c 100644
--- a/integration-tests/goss/windows/commands/add.goss.yaml
+++ b/integration-tests/goss/windows/commands/add.goss.yaml
@@ -8,4 +8,3 @@ command:
     - "timeout: 500"
     stderr: []
     timeout: 5000
-
diff --git a/mkdocs.yml b/mkdocs.yml
index 7156db5e6..3110deda9 100644
--- a/mkdocs.yml
+++ b/mkdocs.yml
@@ -47,8 +47,8 @@ plugins:
   - macros:
       render_by_default: false
   - exclude:
-       glob:
-         - requirements.txt
+      glob:
+        - requirements.txt
 
 markdown_extensions:
   - abbr
diff --git a/testdata/matching_basic.yaml b/testdata/matching_basic.yaml
index 67af512ad..b58f93be5 100644
--- a/testdata/matching_basic.yaml
+++ b/testdata/matching_basic.yaml
@@ -53,9 +53,9 @@ matching:
     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
+        - [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
         - contain-element:
@@ -107,11 +107,11 @@ matching:
       and:
         - not:
             contain-elements: [fox, box]
-        - not: [fox, bax] # same as above
+        - not: [fox, bax]  # same as above
         - not:
-            equal: [fox, bax, mox] # order matters, exact match
+            equal: [fox, bax, mox]  # order matters, exact match
         - not:
-            consist-of: [have-suffix: x, have-prefix: t, box] # order doesn't matter, can use matchers
+            consist-of: [have-suffix: x, have-prefix: t, box]  # order doesn't matter, can use matchers
         - not:
             contain-element:
               have-prefix: x
diff --git a/testdata/matching_basic_failing.yaml b/testdata/matching_basic_failing.yaml
index 1d2351149..d201fbe8c 100644
--- a/testdata/matching_basic_failing.yaml
+++ b/testdata/matching_basic_failing.yaml
@@ -44,13 +44,13 @@ matching:
     content: '1.2.3'
     matches:
       or:
-       - semver-constraint: '>=9.9.0'
+        - semver-constraint: '>=9.9.0'
 
   basic_len:
     content: "123"
     matches:
       or:
-       - have-len: 2
+        - have-len: 2
 
   basic_int:
     content: 42
@@ -72,9 +72,9 @@ matching:
     matches:
       or:
         - contain-elements: [fox, box]
-        - [fox, bax] # same as above
-        - equal: [fox, bax, mox] # order matters, exact match
-        - consist-of: [fox, have-prefix: t, box] # order doesn't matter, can use matchers
+        - [fox, bax]  # same as above
+        - equal: [fox, bax, mox]  # order matters, exact match
+        - consist-of: [fox, have-prefix: t, box]  # order doesn't matter, can use matchers
         - contain-element:
             have-prefix: x
         - contain-element:
@@ -83,7 +83,7 @@ matching:
   basic_array_consists_of:
     content: [foo, bar, moo]
     matches:
-      consist-of: [fox, have-prefix: t, box] # order doesn't matter, can use matchers
+      consist-of: [fox, have-prefix: t, box]  # order doesn't matter, can use matchers
 
   basic_reader:
     as-reader: true
@@ -163,11 +163,11 @@ matching:
         - not:
             contain-elements: [foo, bar]
         - not:
-            [foo, bar] # same as above
+            [foo, bar]  # same as above
         - not:
-            equal: [foo, bar, moo] # order matters, exact match
+            equal: [foo, bar, moo]  # order matters, exact match
         - not:
-            consist-of: [foo, have-prefix: m, bar] # order doesn't matter, can use matchers
+            consist-of: [foo, have-prefix: m, bar]  # order doesn't matter, can use matchers
         - not:
             contain-element:
               have-prefix: b
@@ -182,7 +182,7 @@ matching:
     content: [foo, bar, moo]
     matches:
       not:
-        consist-of: [foo, have-prefix: m, bar] # order doesn't matter, can use matchers
+        consist-of: [foo, have-prefix: m, bar]  # order doesn't matter, can use matchers
 
   negated_basic_reader:
     as-reader: true
diff --git a/testdata/matching_transformers.yaml b/testdata/matching_transformers.yaml
index e30100714..56a4fe08a 100644
--- a/testdata/matching_transformers.yaml
+++ b/testdata/matching_transformers.yaml
@@ -65,9 +65,9 @@ matching:
         - contain-element:
             have-prefix: 'moo'
         - contain-elements:
-          - not: 'this_doesnt_exist'
-          - lt: 20
-          - have-prefix: 'moo'
+            - not: 'this_doesnt_exist'
+            - lt: 20
+            - have-prefix: 'moo'
 
   test_reader_using_array:
     content: |
@@ -91,8 +91,8 @@ matching:
     as-reader: true
     matches:
       and:
-       - le: 250
-       - ge: 20
+        - le: 250
+        - ge: 20
 
 
   test_gjson_transform:
@@ -126,4 +126,4 @@ matching:
           # or tests MarshalJSON
           or:
             - contain-elements:
-              - have-key: 'nested'
+                - have-key: 'nested'
diff --git a/testdata/matching_transformers_failing.yaml b/testdata/matching_transformers_failing.yaml
index f49482ba0..1e216b5d8 100644
--- a/testdata/matching_transformers_failing.yaml
+++ b/testdata/matching_transformers_failing.yaml
@@ -65,9 +65,9 @@ matching:
         - contain-element:
             have-prefix: 'too'
         - contain-elements:
-          - not: 'moo cow'
-          - lt: 10
-          - have-prefix: 'tow'
+            - not: 'moo cow'
+            - lt: 10
+            - have-prefix: 'tow'
 
 
   test_reader_as_single_string:
@@ -80,8 +80,8 @@ matching:
     as-reader: true
     matches:
       and:
-       - le: 20
-       - ge: 50
+        - le: 20
+        - ge: 50
 
 
   test_gjson_transform_simple:
@@ -159,4 +159,4 @@ matching:
     matches:
       gjson:
         '@this':
-            - have-key: "arr"
+          - have-key: "arr"

From b8968fa2817e9272400e2cfe99594722c2f595f8 Mon Sep 17 00:00:00 2001
From: dklimpel <5740567+dklimpel@users.noreply.github.com>
Date: Sat, 13 Jul 2024 23:23:41 +0200
Subject: [PATCH 2/4] use makefile

---
 .github/workflows/yamllint.yaml | 2 +-
 Makefile                        | 5 +++++
 2 files changed, 6 insertions(+), 1 deletion(-)

diff --git a/.github/workflows/yamllint.yaml b/.github/workflows/yamllint.yaml
index 0c887c2c2..802c0eeef 100644
--- a/.github/workflows/yamllint.yaml
+++ b/.github/workflows/yamllint.yaml
@@ -14,4 +14,4 @@ jobs:
     steps:
       - uses: actions/checkout@v4
       - name: Validate YAML file
-        run: yamllint -c .yamllint .
+        run: make lint-yaml
diff --git a/Makefile b/Makefile
index b5148e82f..77c606951 100644
--- a/Makefile
+++ b/Makefile
@@ -144,6 +144,11 @@ arch: build
 dgoss-sha256:
 	cd extras/dgoss/ && sha256sum dgoss > dgoss.sha256
 
+.PHONY: lint-yaml
+lint-yaml:
+	$(info INFO: Starting $@)
+	yamllint -c .yamllint .
+
 $(PYTHON):
 	$(info Creating virtualenv in $(VENV))
 	@python -m venv $(VENV)

From ff38cb59b08b2778567865d7601aead597cf4258 Mon Sep 17 00:00:00 2001
From: dklimpel <5740567+dklimpel@users.noreply.github.com>
Date: Fri, 30 Aug 2024 08:05:42 +0200
Subject: [PATCH 3/4] disable warnings for comments-indentation

---
 .yamllint | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/.yamllint b/.yamllint
index b25fd9b88..675218737 100644
--- a/.yamllint
+++ b/.yamllint
@@ -14,6 +14,8 @@ rules:
   brackets:
     min-spaces-inside: 0
     max-spaces-inside: 1  # required for schema.yaml
+  comments-indentation:
+    level: disable
   indentation:
     spaces: consistent
     indent-sequences: consistent

From ed544e481d9333ceac1357f0388af1e9607a04bd Mon Sep 17 00:00:00 2001
From: dklimpel <5740567+dklimpel@users.noreply.github.com>
Date: Fri, 30 Aug 2024 08:09:11 +0200
Subject: [PATCH 4/4] fix configuration for comments-indentation

---
 .yamllint | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/.yamllint b/.yamllint
index 675218737..d575ab3fb 100644
--- a/.yamllint
+++ b/.yamllint
@@ -14,8 +14,7 @@ rules:
   brackets:
     min-spaces-inside: 0
     max-spaces-inside: 1  # required for schema.yaml
-  comments-indentation:
-    level: disable
+  comments-indentation: disable
   indentation:
     spaces: consistent
     indent-sequences: consistent