$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
#  and https://github.com/goss-org/goss/blob/master/README.md
# It was tested in intellij against https://github.com/goss-org/goss/blob/master/docs/goss.yaml
# both for completion and code analysis use-cases.
# Limitations / missing support
# - patterns
# - advanced matchers
# - templates
$schema: http://json-schema.org/draft-07/schema#
title: "Goss-file-schema"
definitions:
  title:
    type: string
    default: "UID must be between 50-100, GID doesn't matter. home is flexible"
    description: title attribute is persisted when adding other resources with goss add
  meta:
    description: meta (arbitrary data) attributes are persisted when adding other resources with goss add
    type: object
  addrTest:
    required:
      - reachable
      - timeout
    properties:
      title: { "$ref":"#/definitions/title" }
      meta: { "$ref":"#/definitions/meta" }
      reachable:
        type: boolean
        default: true
      timeout:
        type: integer
        default: 500
        examples:
          - 500
          # optional attributes
      local-address:
        type: string
        default: 127.0.0.1
  commandTest:
    type: object
    properties:
      title: { "$ref":"#/definitions/title" }
      meta: { "$ref":"#/definitions/meta" }
      exit-status:
        type: integer
        description: "Validates the exit-status and output of a command"
      exec:
        description: "command to execute, defaults to the hash key"
        type: string
      stdout:
        type: array
        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://goss.rocks/gossfile#patterns"
        items:
          type: string
      timeout:
        type: integer
        description: "in milliseconds"
      skip:
        type: boolean
        default: false
    required:
      - exit-status
  dnsTest:
    required:
      - resolvable
    properties:
      title: { "$ref":"#/definitions/title" }
      meta: { "$ref":"#/definitions/meta" }
      resolvable:
        type: boolean
        default: true
      # optional attributes
      addrs:
        description: |
          list of addresses e.g. ["127.0.0.1", "::1"]
        type: array
        items:
          type: string
        default: ["127.0.0.1", "::1"]
      server:
        description: "Eg 8.8.8.8. Also supports server:port "
        type: string
        default: 8.8.8.8
      timeout:
        type: integer
        default: 500
        description: in milliseconds (Only used when server attribute is provided)
  fileTest:
    required:
      - exists
    properties:
      title: { "$ref":"#/definitions/title" }
      meta: { "$ref":"#/definitions/meta" }
      exists:
        type: boolean
        default: true
      mode:
        type: string
        default: "0644"
      size:
        type: integer
        default: 2118
        description: in bytes
      owner:
        type: string
        default: root
      uid:
        type: integer
      group:
        type: string
        default: root
      gid:
        type: integer
      filetype:
        type: string
        default: file
        enum:
          - file
          - symlink
          - directory
      contains:
        type: array
        description: Check file content for these patterns. can be a string or a pattern
        items:
          type: string
          description: string or patterns
      md5:
        type: string
        default: 7c9bb14b3bf178e82c00c2a4398c93cd
        description: md5 checksum of file

      sha256:
        type: string
        default: 7f78ce27859049f725936f7b52c6e25d774012947d915e7b394402cfceb70c4c
        description: "A stronger checksum alternatives to md5 (recommended)"
      sha512:
        type: string
        default: cb71b1940dc879a3688bd502846bff6316dd537bbe917484964fe0f098e9245d80958258dc3bd6297bf42d5bd978cbe2c03d077d4ed45b2b1ed9cd831ceb1bd0
        description: "A stronger checksum alternatives to md5 (recommended)"
      linked-to:
        type: string
        default: /usr/sbin/sendmail.sendmail
      skip:
        type: boolean
        default: false
  gossfileTest:
    properties:
      title: { "$ref":"#/definitions/title" }
      meta: { "$ref":"#/definitions/meta" }
      file:
        type: string
        default: myapp_gossfile.yaml
      skip:
        type: boolean
        default: false
  groupTest:
    required:
      - exists
    properties:
      title: { "$ref":"#/definitions/title" }
      meta: { "$ref":"#/definitions/meta" }
      exists:
        type: boolean
        default: true
      uid:
        type: integer
        default: 65534
      gid:
        type: integer
        default: 65534
      groups:
        type: object
      skip:
        type: boolean
        default: false
  httpTest:
    required:
      - status
    properties:
      title: { "$ref":"#/definitions/title" }
      meta: { "$ref":"#/definitions/meta" }
      status:
        type: integer
        default: 200
      allow-insecure:
        type: boolean
        default: false
      no-follow-redirects:
        type: boolean
        default: false
        description: Setting this to true will NOT follow redirects
      timeout:
        type: integer
        default: 1000
      request-headers:
        description: |
          Set request header values, e.g. [ "Content-Type: text/html" ]
        type: array
        items:
          type: string
        default: [ "Content-Type: text/html" ]
      headers:
        type: array
        description: |
          Check http response headers for these patterns (e.g. "Content-Type: text/html")
          NOTE: only the first Host header will be used to set the Request.Host value if multiple are provided.
        items:
          type: string
        default: [ ]
      request-body:
        type: object
        default: '{"key": "value"}'
        description: request body
      body:
        type: array
        description: Check http response content for these patterns
      username:
        type: string
        description: username for basic auth
        default: ""
      password:
        type: string
        description: password for basic auth
        default: ""
      ca-file:
        type: string
        default: ""
        description: |
          CA root certs pem file, ex: /etc/ssl/cert.pem
      cert-file:
        type: string
        default: ""
        description: |
         certificate file to use for authentication (used with key-file)
      key-file:
        type: string
        default: ""
        description:  |
          private-key file to use for authentication (used with cert-file)
      proxy:
        type: string
        default: ""
        description:  |
          proxy server to proxy traffic through. Proxy can also be set with environment variables http_proxy.
      skip:
        type: boolean
        default: false
      method:
        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
          - GET
          - PUT
          - HEAD
          - POST
          - DELETE
          - PATCH
          - CONNECT
          - OPTIONS
          - TRACE
  interfaceTest:
    required:
      - exists
    properties:
      title: { "$ref":"#/definitions/title" }
      meta: { "$ref":"#/definitions/meta" }
      exists:
        type: boolean
        default: true
      addrs:
        type: array
        items:
          type: string
        default:
        - 172.17.0.2/16
        - fe80::42:acff:fe11:2/64
      mtu:
        type: integer
        default: 1500
  kernelParamTest:
    description: |
      To see the full list of current values, run sysctl -a.
    required:
      - value
    properties:
      title: { "$ref":"#/definitions/title" }
      meta: { "$ref":"#/definitions/meta" }
      value:
        type: string
        default: Linux
  matchingTest:
    properties:
      title: { "$ref":"#/definitions/title" }
      meta: { "$ref":"#/definitions/meta" }
      content:
        anyOf:
        - type: string
          default: "some string"
        - type: array
          default:
            - 2
        - type: object
          default:
            foo: bar
            baz: ring
      matches:
        anyOf:
          - type: integer
          - type: object
          - type: array
  mountTest:
    required:
      - exists
    properties:
      timeout:
        type: integer
      title: { "$ref":"#/definitions/title" }
      meta: { "$ref":"#/definitions/meta" }
      exists:
        type: boolean
        default: true
      opts:
        type: array
        items:
          type: string
        default:
        - rw
        - relatime
      source:
        type: string
        default: /dev/mapper/fedora-home
      filesystem:
        type: string
        default: xfs
      usage:
        description: |
          % of blocks used in this mountpoint
        type: object
        properties:
          lt:
            type: integer
            default: 95
  packageTest:
    required:
      - installed
    properties:
      title: { "$ref":"#/definitions/title" }
      meta: { "$ref":"#/definitions/meta" }
      installed:
        type: boolean
        default: true
      versions:
        oneOf:
          - type: object # matcher
          - type: array
            items:
              type: string
            default:
            - 2.2.15
      skip:
        type: boolean
        default: false
  portTest:
    required:
      - listening
    properties:
      title: { "$ref":"#/definitions/title" }
      meta: { "$ref":"#/definitions/meta" }
      listening:
        type: boolean
        default: true
      ip:
        description: what IP(s) is it listening on
        type: array
        items:
          type: string
        default:
        - 0.0.0.0
      skip:
        type: boolean
        default: false
  processTest:
    required:
      - running
    properties:
      title: { "$ref":"#/definitions/title" }
      meta: { "$ref":"#/definitions/meta" }
      running:
        type: boolean
        default: true
  serviceTest:
    required:
      - enabled
      - running
      - skip
    properties:
      title: { "$ref":"#/definitions/title" }
      meta: { "$ref":"#/definitions/meta" }
      enabled:
        type: boolean
        default: true
      running:
        type: boolean
        default: true
      skip:
        type: boolean
        default: false
  userTest:
    required:
      - exists
    properties:
      title: { "$ref": "#/definitions/title" }
      meta:  { "$ref": "#/definitions/meta" }
      exists:
        type: boolean
        default: true
      # optional attributes
      uid:
        anyOf:
          - { "$ref": "#/definitions/matchingTest" }
          - type: integer
            default: 65534

      gid:
        anyOf:
          - { "$ref": "#/definitions/matchingTest" }
          - type: integer
            default: 65534
      groups:
        anyOf:
          - { "$ref": "#/definitions/matchingTest" }
          - type: array
            items:
              type: string
            default:
            - nfsnobody
      home:
        anyOf:
          - { "$ref": "#/definitions/matchingTest" }
          - type: string
            default: /var/lib/nfs
      shell:
        type: string
        default: /sbin/nologin
      skip:
        type: boolean
        default: false

description: "A file describing a series of tests"
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"

  command:
    type: object
    description: "test executing a command"
    additionalProperties:
      $ref: "#/definitions/commandTest"

  dns:
      type: object
      description: "Validates that the provided address is resolvable and the addrs it resolves to."
      x-intellij-html-description: |
        <p dir="auto">Validates that the provided address is resolvable and the addrs it resolves to.</p>
        <div class="highlight highlight-source-yaml notranslate position-relative overflow-auto" dir="auto"><pre><span class="pl-ent">dns</span>:
          <span class="pl-ent">localhost</span>:
            <span class="pl-c"><span class="pl-c">#</span> required attributes</span>
            <span class="pl-ent">resolvable</span>: <span class="pl-c1">true</span>
            <span class="pl-c"><span class="pl-c">#</span> optional attributes</span>
            <span class="pl-ent">addrs</span>:
            - <span class="pl-s">127.0.0.1</span>
            - <span class="pl-s">::1</span>
            <span class="pl-ent">server</span>: <span class="pl-s">8.8.8.8 </span><span class="pl-c"><span class="pl-c">#</span> Also supports server:port</span>
            <span class="pl-ent">timeout</span>: <span class="pl-c1">500</span> <span class="pl-c"><span class="pl-c">#</span> in milliseconds (Only used when server attribute is provided)</span></pre><div class="zeroclipboard-container position-absolute right-0 top-0">
            <clipboard-copy aria-label="Copy" class="ClipboardButton btn js-clipboard-copy m-2 p-0 tooltipped-no-delay" data-copy-feedback="Copied!" data-tooltip-direction="w" value="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)" tabindex="0" role="button" style="display: none;">
              <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-copy js-clipboard-copy-icon m-2">
            <path fill-rule="evenodd" d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 010 1.5h-1.5a.25.25 0 00-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 00.25-.25v-1.5a.75.75 0 011.5 0v1.5A1.75 1.75 0 019.25 16h-7.5A1.75 1.75 0 010 14.25v-7.5z"></path><path fill-rule="evenodd" d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0114.25 11h-7.5A1.75 1.75 0 015 9.25v-7.5zm1.75-.25a.25.25 0 00-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 00.25-.25v-7.5a.25.25 0 00-.25-.25h-7.5z"></path>
        </svg>
              <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-check js-clipboard-check-icon color-fg-success d-none m-2">
            <path fill-rule="evenodd" d="M13.78 4.22a.75.75 0 010 1.06l-7.25 7.25a.75.75 0 01-1.06 0L2.22 9.28a.75.75 0 011.06-1.06L6 10.94l6.72-6.72a.75.75 0 011.06 0z"></path>
        </svg>
            </clipboard-copy>
          </div></div>
        <p dir="auto">It is possible to validate the following types of DNS records, but requires the <code>server</code> attribute be set:</p>
        <ul dir="auto">
        <li>A</li>
        <li>AAAA</li>
        <li>CAA</li>
        <li>CNAME</li>
        <li>MX</li>
        <li>NS</li>
        <li>PTR</li>
        <li>SRV</li>
        <li>TXT</li>
        </ul>
        <p dir="auto">To validate specific DNS address types, prepend the hostname with the type and a colon, a few examples:</p>
        <div class="highlight highlight-source-yaml notranslate position-relative overflow-auto" dir="auto"><pre><span class="pl-ent">dns</span>:
          <span class="pl-c"><span class="pl-c">#</span> Validate a CNAME record</span>
          <span class="pl-ent">CNAME:c.dnstest.io</span>:
            <span class="pl-ent">resolvable</span>: <span class="pl-c1">true</span>
            <span class="pl-ent">server</span>: <span class="pl-s">208.67.222.222</span>
            <span class="pl-ent">addrs</span>:
            - <span class="pl-s"><span class="pl-pds">"</span>a.dnstest.io.<span class="pl-pds">"</span></span>

          <span class="pl-c"><span class="pl-c">#</span> Validate a PTR record</span>
          <span class="pl-ent">PTR:8.8.8.8</span>:
            <span class="pl-ent">resolvable</span>: <span class="pl-c1">true</span>
            <span class="pl-ent">server</span>: <span class="pl-s">8.8.8.8</span>
            <span class="pl-ent">addrs</span>:
            - <span class="pl-s"><span class="pl-pds">"</span>dns.google.<span class="pl-pds">"</span></span>

          <span class="pl-c"><span class="pl-c">#</span> Validate and SRV record</span>
          <span class="pl-ent">SRV:_https._tcp.dnstest.io</span>:
            <span class="pl-ent">resolvable</span>: <span class="pl-c1">true</span>
            <span class="pl-ent">server</span>: <span class="pl-s">208.67.222.222</span>
            <span class="pl-ent">addrs</span>:
            - <span class="pl-s"><span class="pl-pds">"</span>0 5 443 a.dnstest.io.<span class="pl-pds">"</span></span>
            - <span class="pl-s"><span class="pl-pds">"</span>10 10 443 b.dnstest.io.<span class="pl-pds">"</span></span></pre><div class="zeroclipboard-container position-absolute right-0 top-0">
            <clipboard-copy aria-label="Copy" class="ClipboardButton btn js-clipboard-copy m-2 p-0 tooltipped-no-delay" data-copy-feedback="Copied!" data-tooltip-direction="w" value="dns:
          # Validate a CNAME record
          CNAME:c.dnstest.io:
            resolvable: true
            server: 208.67.222.222
            addrs:
            - &quot;a.dnstest.io.&quot;

          # Validate a PTR record
          PTR:8.8.8.8:
            resolvable: true
            server: 8.8.8.8
            addrs:
            - &quot;dns.google.&quot;

          # Validate and SRV record
          SRV:_https._tcp.dnstest.io:
            resolvable: true
            server: 208.67.222.222
            addrs:
            - &quot;0 5 443 a.dnstest.io.&quot;
            - &quot;10 10 443 b.dnstest.io.&quot;" tabindex="0" role="button">
              <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-copy js-clipboard-copy-icon m-2">
            <path fill-rule="evenodd" d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 010 1.5h-1.5a.25.25 0 00-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 00.25-.25v-1.5a.75.75 0 011.5 0v1.5A1.75 1.75 0 019.25 16h-7.5A1.75 1.75 0 010 14.25v-7.5z"></path><path fill-rule="evenodd" d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0114.25 11h-7.5A1.75 1.75 0 015 9.25v-7.5zm1.75-.25a.25.25 0 00-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 00.25-.25v-7.5a.25.25 0 00-.25-.25h-7.5z"></path>
        </svg>
              <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-check js-clipboard-check-icon color-fg-success d-none m-2">
            <path fill-rule="evenodd" d="M13.78 4.22a.75.75 0 010 1.06l-7.25 7.25a.75.75 0 01-1.06 0L2.22 9.28a.75.75 0 011.06-1.06L6 10.94l6.72-6.72a.75.75 0 011.06 0z"></path>
        </svg>
            </clipboard-copy>
          </div></div>
        <p dir="auto">Please note that if you want <code>localhost</code> to <strong>only</strong> resolve <code>127.0.0.1</code> you'll need to use <a href="https://goss.rocks/gossfile/#advanced-matchers">Advanced Matchers</a></p>
        <div class="highlight highlight-source-yaml notranslate position-relative overflow-auto" dir="auto"><pre><span class="pl-ent">dns</span>:
          <span class="pl-ent">localhost</span>:
            <span class="pl-ent">resolvable</span>: <span class="pl-c1">true</span>
            <span class="pl-ent">addrs</span>:
              <span class="pl-ent">consist-of</span>: <span class="pl-s">[127.0.0.1]</span>
            <span class="pl-ent">timeout</span>: <span class="pl-c1">500</span> <span class="pl-c"><span class="pl-c">#</span> in milliseconds</span>
      additionalProperties:
        $ref: "#/definitions/dnsTest"

  file:
      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 <a href="https://goss.rocks/cli/#render">render</a> for more examples. Glob patterns can be also be used to specify matching gossfiles.</p>
        <div class="highlight highlight-source-yaml notranslate position-relative overflow-auto" dir="auto"><pre><span class="pl-ent">gossfile</span>:
          <span class="pl-ent">myapplication</span>:
            <span class="pl-ent">file</span>: <span class="pl-s">myapp_gossfile.yaml</span>
            <span class="pl-ent">skip</span>: <span class="pl-c1">false</span>
          <span class="pl-s">*.yaml:</span>
            <span class="pl-ent">skip</span>: <span class="pl-c1">true</span>
          <span class="pl-ent">goss_httpd.yaml</span>: <span class="pl-s">{}</span>
          <span class="pl-ent">/etc/goss.d/*.yaml</span>: <span class="pl-s">{}</span></pre><div class="zeroclipboard-container position-absolute right-0 top-0">
            <clipboard-copy aria-label="Copy" class="ClipboardButton btn js-clipboard-copy m-2 p-0 tooltipped-no-delay" data-copy-feedback="Copied!" data-tooltip-direction="w" value="gossfile:
          myapplication:
            file: myapp_gossfile.yaml
            skip: false
          *.yaml:
            skip: true
          goss_httpd.yaml: {}
          /etc/goss.d/*.yaml: {}" tabindex="0" role="button" style="display: none;">
              <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-copy js-clipboard-copy-icon m-2">
            <path fill-rule="evenodd" d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 010 1.5h-1.5a.25.25 0 00-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 00.25-.25v-1.5a.75.75 0 011.5 0v1.5A1.75 1.75 0 019.25 16h-7.5A1.75 1.75 0 010 14.25v-7.5z"></path><path fill-rule="evenodd" d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0114.25 11h-7.5A1.75 1.75 0 015 9.25v-7.5zm1.75-.25a.25.25 0 00-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 00.25-.25v-7.5a.25.25 0 00-.25-.25h-7.5z"></path>
        </svg>
              <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-check js-clipboard-check-icon color-fg-success d-none m-2">
            <path fill-rule="evenodd" d="M13.78 4.22a.75.75 0 010 1.06l-7.25 7.25a.75.75 0 01-1.06 0L2.22 9.28a.75.75 0 011.06-1.06L6 10.94l6.72-6.72a.75.75 0 011.06 0z"></path>
        </svg>
            </clipboard-copy>
          </div></div>
        <p dir="auto">You can specify the gossfile(s) either as the resource key, or using the 'file' attribute.</p>
        <p dir="auto">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.</p>
      additionalProperties:
        $ref: "#/definitions/gossfileTest"

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

  interface:
      type: object
      description: "test "
      additionalProperties:
        $ref: "#/definitions/interfaceTest"

  kernel-param:
      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: |
        <p dir="auto">Validates specified content against a matcher. Best used with <a href="https://goss.rocks/gossfile/#templates">Templates</a>.</p>
        <h4 dir="auto"><a id="user-content-with-templates" class="anchor" aria-hidden="true" href="https://goss.rocks/gossfile/#with-templates"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a>With <a href="https://goss.rocks/gossfile/#templates">Templates</a>:</h4>
        <p dir="auto">Let's say we have a <code>data.json</code> file that gets generated as part of some testing pipeline:</p>
        <div class="highlight highlight-source-json notranslate position-relative overflow-auto" dir="auto"><pre>{
          <span class="pl-ent">"instance_count"</span>: <span class="pl-c1">14</span>,
          <span class="pl-ent">"failures"</span>: <span class="pl-c1">3</span>,
          <span class="pl-ent">"status"</span>: <span class="pl-s"><span class="pl-pds">"</span>FAIL<span class="pl-pds">"</span></span>
        }</pre><div class="zeroclipboard-container position-absolute right-0 top-0">
            <clipboard-copy aria-label="Copy" class="ClipboardButton btn js-clipboard-copy m-2 p-0 tooltipped-no-delay" data-copy-feedback="Copied!" data-tooltip-direction="w" value="{
          &quot;instance_count&quot;: 14,
          &quot;failures&quot;: 3,
          &quot;status&quot;: &quot;FAIL&quot;
        }" tabindex="0" role="button">
              <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-copy js-clipboard-copy-icon m-2">
            <path fill-rule="evenodd" d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 010 1.5h-1.5a.25.25 0 00-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 00.25-.25v-1.5a.75.75 0 011.5 0v1.5A1.75 1.75 0 019.25 16h-7.5A1.75 1.75 0 010 14.25v-7.5z"></path><path fill-rule="evenodd" d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0114.25 11h-7.5A1.75 1.75 0 015 9.25v-7.5zm1.75-.25a.25.25 0 00-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 00.25-.25v-7.5a.25.25 0 00-.25-.25h-7.5z"></path>
        </svg>
              <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-check js-clipboard-check-icon color-fg-success d-none m-2">
            <path fill-rule="evenodd" d="M13.78 4.22a.75.75 0 010 1.06l-7.25 7.25a.75.75 0 01-1.06 0L2.22 9.28a.75.75 0 011.06-1.06L6 10.94l6.72-6.72a.75.75 0 011.06 0z"></path>
        </svg>
            </clipboard-copy>
          </div></div>
        <p dir="auto">This could then be passed into goss: <code>goss --vars data.json validate</code></p>
        <p dir="auto">And then validated against:</p>
        <div class="highlight highlight-source-yaml notranslate position-relative overflow-auto" dir="auto"><pre><span class="pl-ent">matching</span>:
          <span class="pl-ent">check_instance_count</span>: <span class="pl-c"><span class="pl-c">#</span> Make sure there is at least one instance</span>
            <span class="pl-ent">content</span>: <span class="pl-s">{{ .Vars.instance_count }}</span>
            <span class="pl-ent">matches</span>:
              <span class="pl-ent">gt</span>: <span class="pl-c1">0</span>

          <span class="pl-ent">check_failure_count_from_all_instance</span>: <span class="pl-c"><span class="pl-c">#</span> expect no failures</span>
            <span class="pl-ent">content</span>: <span class="pl-s">{{ .Vars.failures }}</span>
            <span class="pl-ent">matches</span>: <span class="pl-c1">0</span>

          <span class="pl-ent">check_status</span>:
            <span class="pl-ent">content</span>: <span class="pl-s">{{ .Vars.status }}</span>
            <span class="pl-ent">matches</span>:
              - <span class="pl-ent">not</span>: <span class="pl-s">FAIL</span></pre><div class="zeroclipboard-container position-absolute right-0 top-0">
            <clipboard-copy aria-label="Copy" class="ClipboardButton btn js-clipboard-copy m-2 p-0 tooltipped-no-delay" data-copy-feedback="Copied!" data-tooltip-direction="w" value="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" tabindex="0" role="button" style="display: none;">
              <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-copy js-clipboard-copy-icon m-2">
            <path fill-rule="evenodd" d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 010 1.5h-1.5a.25.25 0 00-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 00.25-.25v-1.5a.75.75 0 011.5 0v1.5A1.75 1.75 0 019.25 16h-7.5A1.75 1.75 0 010 14.25v-7.5z"></path><path fill-rule="evenodd" d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0114.25 11h-7.5A1.75 1.75 0 015 9.25v-7.5zm1.75-.25a.25.25 0 00-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 00.25-.25v-7.5a.25.25 0 00-.25-.25h-7.5z"></path>
        </svg>
              <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-check js-clipboard-check-icon color-fg-success d-none m-2">
            <path fill-rule="evenodd" d="M13.78 4.22a.75.75 0 010 1.06l-7.25 7.25a.75.75 0 01-1.06 0L2.22 9.28a.75.75 0 011.06-1.06L6 10.94l6.72-6.72a.75.75 0 011.06 0z"></path>
        </svg>
            </clipboard-copy>
          </div></div>
        <h4 dir="auto"><a id="user-content-without-templates" class="anchor" aria-hidden="true" href="https://goss.rocks/gossfile/#without-templates"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a>Without <a href="https://goss.rocks/gossfile/#templates">Templates</a>:</h4>
        <div class="highlight highlight-source-yaml notranslate position-relative overflow-auto" dir="auto"><pre><span class="pl-ent">matching</span>:
          <span class="pl-ent">has_substr</span>: <span class="pl-c"><span class="pl-c">#</span> friendly test name</span>
            <span class="pl-ent">content</span>: <span class="pl-s">some string</span>
            <span class="pl-ent">matches</span>:
              <span class="pl-ent">match-regexp</span>: <span class="pl-s">some str</span>
          <span class="pl-ent">has_2</span>:
            <span class="pl-ent">content</span>:
              - <span class="pl-c1">2</span>
            <span class="pl-ent">matches</span>:
              <span class="pl-ent">contain-element</span>: <span class="pl-c1">2</span>
          <span class="pl-ent">has_foo_bar_and_baz</span>:
            <span class="pl-ent">content</span>:
              <span class="pl-ent">foo</span>: <span class="pl-s">bar</span>
              <span class="pl-ent">baz</span>: <span class="pl-s">bing</span>
            <span class="pl-ent">matches</span>:
              <span class="pl-ent">and</span>:
                - <span class="pl-ent">have-key-with-value</span>:
                    <span class="pl-ent">foo</span>: <span class="pl-s">bar</span>
                - <span class="pl-ent">have-key</span>: <span class="pl-s">baz</span></pre><div class="zeroclipboard-container position-absolute right-0 top-0">
            <clipboard-copy aria-label="Copy" class="ClipboardButton btn js-clipboard-copy m-2 p-0 tooltipped-no-delay" data-copy-feedback="Copied!" data-tooltip-direction="w" value="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" tabindex="0" role="button" style="display: none;">
              <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-copy js-clipboard-copy-icon m-2">
            <path fill-rule="evenodd" d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 010 1.5h-1.5a.25.25 0 00-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 00.25-.25v-1.5a.75.75 0 011.5 0v1.5A1.75 1.75 0 019.25 16h-7.5A1.75 1.75 0 010 14.25v-7.5z"></path><path fill-rule="evenodd" d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0114.25 11h-7.5A1.75 1.75 0 015 9.25v-7.5zm1.75-.25a.25.25 0 00-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 00.25-.25v-7.5a.25.25 0 00-.25-.25h-7.5z"></path>
        </svg>
              <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-check js-clipboard-check-icon color-fg-success d-none m-2">
            <path fill-rule="evenodd" d="M13.78 4.22a.75.75 0 010 1.06l-7.25 7.25a.75.75 0 01-1.06 0L2.22 9.28a.75.75 0 011.06-1.06L6 10.94l6.72-6.72a.75.75 0 011.06 0z"></path>
        </svg>
            </clipboard-copy>
          </div></div>

        additionalProperties:
        $ref: "#/definitions/matchTest"

  mount:
      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 <format> 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: |
        <p dir="auto">Validates the state of a local port.</p>
        <p dir="auto"><strong>Note:</strong> Goss might consider your port to be listening on <code>tcp6</code> rather than <code>tcp</code>, try running <code>goss add port ..</code> to see how goss detects it. (<a href="https://github.com/goss-org/goss/issues/149" data-hovercard-type="issue" data-hovercard-url="/goss-org/goss/issues/149/hovercard">explanation</a>)</p>
        <div class="highlight highlight-source-yaml notranslate position-relative overflow-auto" dir="auto"><pre><span class="pl-ent">port</span>:
          <span class="pl-c"><span class="pl-c">#</span> {tcp,tcp6,udp,udp6}:port_num</span>
          <span class="pl-ent">tcp:22</span>:
            <span class="pl-c"><span class="pl-c">#</span> required attributes</span>
            <span class="pl-ent">listening</span>: <span class="pl-c1">true</span>
            <span class="pl-c"><span class="pl-c">#</span> optional attributes</span>
            <span class="pl-ent">ip</span>: <span class="pl-c"><span class="pl-c">#</span> what IP(s) is it listening on</span>
            - <span class="pl-s">0.0.0.0</span>
            <span class="pl-ent">skip</span>: <span class="pl-c1">false</span>
      additionalProperties:
        $ref: "#/definitions/portTest"

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

  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"


