Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Add "structured data" resource #981

Closed
sed-i opened this issue Sep 24, 2024 · 4 comments
Closed

Add "structured data" resource #981

sed-i opened this issue Sep 24, 2024 · 4 comments

Comments

@sed-i
Copy link

sed-i commented Sep 24, 2024

Describe the feature:
Server validation often involves structured data, such as json/yaml/toml. Being able to assert against objects inside some structured data could obviate the need for bespoke goss resources.

Describe the solution you'd like
A general purpose resource for poking into structured data and making exact/contains assertions. For example:

structured-data:
  format: json  # another option: yaml
  source:
    command: "juju status --format=json"
    # mutually exclusive option: url
  mode: contains  # another option: exact-match
  assertions:
    ".applications | keys":  # this is a standard jq-style query
      - prom
      - alertmanager
    ".applications.prom.relations | keys":
      - alertmanager
      - prometheus-peers

Describe alternatives you've considered
While we can certainly use the command resource for those checks, on a larger scale it may result in checks that are not maintainable.

@aelsabbahy
Copy link
Member

Can you provide an example json and checks you're making?

Goss has a gjson matcher, which may meet your needs.

You can use it against the stdout of a command.

@sed-i
Copy link
Author

sed-i commented Sep 25, 2024

I was not aware of gjson, looks incredible @aelsabbahy.
A trimmed down json sample is below.

json sample
{
  "model": {
    "name": "welcome-k8s"
  },
  "applications": {
    "am": {
      "charm": "alertmanager-k8s",
      "base": {
        "name": "ubuntu",
        "channel": "20.04"
      },
      "relations": {
        "alerting": [
          {
            "related-application": "prom",
            "interface": "alertmanager_dispatch",
            "scope": "global"
          }
        ],
        "replicas": [
          {
            "related-application": "am",
            "interface": "alertmanager_replica",
            "scope": "global"
          }
        ]
      },
      "version": "0.27.0"
    },
    "prom": {
      "charm": "prometheus-k8s",
      "base": {
        "name": "ubuntu",
        "channel": "20.04"
      },
      "relations": {
        "alertmanager": [
          {
            "related-application": "am",
            "interface": "alertmanager_dispatch",
            "scope": "global"
          }
        ],
        "prometheus-peers": [
          {
            "related-application": "prom",
            "interface": "prometheus_peers",
            "scope": "global"
          }
        ]
      },
      "version": "2.52.0"
      }
    }
  }
}

I tried to run the following:

command:
  app-names:
    exec: juju status --format=json
    exit-status: 0
    stdout:
      gjson:
        applications:
          and:
            - {have-key: "prom"}
            - {have-key: "am"}
        application.prom.relations:
          and:
            - {have-key: "alertmanager"}

But got a nil pointer deref.

goss -g check2.yaml validate
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x20 pc=0x84e53b]

goroutine 7 [running]:
github.com/goss-org/goss/matchers.(*AndMatcher).FailureResult(0x4119db?, {0x0?, 0x0?})
	/home/travis/gopath/src/github.com/goss-org/goss/matchers/and.go:32 +0x5b
github.com/goss-org/goss/matchers.(*WithSafeTransformMatcher).FailureResult(0xb567f8?, {0xa676c0, 0xc000382110})
	/home/travis/gopath/src/github.com/goss-org/goss/matchers/with_safe_transform.go:45 +0x1bc
github.com/goss-org/goss/matchers.(*AndMatcher).FailureResult(0x0?, {0xa676c0?, 0xc000382110?})
	/home/travis/gopath/src/github.com/goss-org/goss/matchers/and.go:32 +0x62
github.com/goss-org/goss/resource.ValidateGomegaValue({_, _}, {_, _}, {_, _}, {_, _}, _)
	/home/travis/gopath/src/github.com/goss-org/goss/resource/validate.go:199 +0x788
github.com/goss-org/goss/resource.ValidateValue({_, _}, {_, _}, {_, _}, {_, _}, _)
	/home/travis/gopath/src/github.com/goss-org/goss/resource/validate.go:126 +0x174
github.com/goss-org/goss/resource.(*Command).Validate(0xc0000bc380, 0xc0000be0b0)
	/home/travis/gopath/src/github.com/goss-org/goss/resource/command.go:65 +0x3bd
github.com/goss-org/goss.validate.func2()
	/home/travis/gopath/src/github.com/goss-org/goss/validate.go:184 +0x86
created by github.com/goss-org/goss.validate in goroutine 1
	/home/travis/gopath/src/github.com/goss-org/goss/validate.go:181 +0x187

Likely I got the syntax wrong?

@sed-i
Copy link
Author

sed-i commented Sep 25, 2024

Oops, a typo on my part

-application.prom.relations:
+applications.prom.relations:

This works fine:

command:
  app-names:
    exec: juju status --format=json
    exit-status: 0
    stdout:
      gjson:
        applications:
          and:
            - {have-key: "prom"}
            - {have-key: "am"}
        applications.prom.relations:
          and:
            - {have-key: "alertmanager"}

@sed-i
Copy link
Author

sed-i commented Sep 25, 2024

Filed #982 with a minimal repro.
Closing this issue, as the requested feature already exists.

@sed-i sed-i closed this as completed Sep 25, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants