kyverno / chainsaw

Declarative K8s e2e testing
https://kyverno.github.io/chainsaw/
Apache License 2.0
269 stars 40 forks source link

[Feature] Allow to use binding/functions in `use.template` in test step #1846

Open jingav opened 1 month ago

jingav commented 1 month ago

Describe your question

Hi there,

I'm trying to create reusable (StepTemplate) building blocks and have the following:

apiVersion: chainsaw.kyverno.io/v1alpha1
kind: Test
metadata:
  name: basic-test
spec:
  bindings:
  - name: rootPath
    value: ../..
  - name: templatesPath
    value: (join('/', [$rootPath, 'templates']))
  steps:
  - name:  Print path # Works fine
    try:
    - script:
        env:
        - name: TEMPLATES_PATH
          value: (join('/', [$templatesPath, 'example/custom_bindings.yaml']))
        content: |
          echo $TEMPLATES_PATH
  - name: Test custom bindings
    bindings:
    - name: filePath
      value: (join('/', [$templatesPath, 'example/custom_bindings.yaml']))
    use: 
      # template: ../../templates/example/custom_bindings.yaml
      template: $filePath # does NOT work
      # template: (join('/', [$templatesPath, 'example/custom_bindings.yaml'])) # does NOT work
Version: 0.2.8
No configuration provided but found default file: .chainsaw.yaml
Loading config (.chainsaw.yaml)...
Loading tests...
Running tests...
=== RUN   chainsaw
=== PAUSE chainsaw
=== CONT  chainsaw
=== RUN   chainsaw/my-test
    | 18:46:04 | basic-test | Paths                            | TRY       | RUN   |
    | 18:46:04 | basic-test | Paths                            | SCRIPT    | RUN   |
        === COMMAND
        /usr/bin/sh -c echo $TEMPLATES_PATH
    | 18:46:04 | basic-test | Paths                            | SCRIPT    | LOG   |
        === STDOUT
        ../../templates/example/custom_bindings.yaml

Version: 0.2.8
No configuration provided but found default file: .chainsaw.yaml
Loading config (.chainsaw.yaml)...
Loading tests...
Error: open tests/basic-test/$filePath: no such file or directory

It seems it's not currently supported or did I miss anything?

Would it be possible to add support for this? There are more use cases for this, the above is just a quick example.

chainsaw version Version

v0.2.8

Additional context

No response

jingav commented 1 month ago

Similarly for apply.file

apiVersion: chainsaw.kyverno.io/v1alpha1
kind: StepTemplate
metadata:
  name: generic-step-apply-claim
spec:
  bindings:
    # e.g. "../.."
  - name: rootPath
    value: ($rootPath)
    # e.g. "../../common/claims"
  - name: claimsPath
    value: (join('/', [$rootPath, 'common/claims']))
    # e.g. "azure-subscription.yaml"
  - name: claimFileName
    value: ($claimFileName)
    # e.g. "../../common/claims/azure-subscription.yaml"
  - name: claimFileNamePath
    value: (join('/', [$claimsPath, $claimFileName]))
    # e.g. "my-azure-subscription-claim"
  - name: claimName
    value: (to_string($claimName))
  try:
  - apply:
      # file: ../../common/claims/azure-subscription.yaml
      file: ($claimFileNamePath)
   catch:
     .....
   finally:
     .....

So, it looks like no interpolation for any paths anywhere?

eddycharly commented 1 month ago

@jingav it will be supported in file in the next version (v0.2.9).

There's no plan to support it in template at this point. Step templates are resolved at discovery time and no binding are evaluated at that time, only when the test executes. We could delay the step template loading until execution but again, there's no plan for that yet.

jingav commented 1 month ago

@eddycharly , ok thanks for sharing the details.

Shall I then change this issue to Enhancement type for the template part?

eddycharly commented 4 weeks ago

Yes you can change it to a feature request.

jingav commented 4 weeks ago

I'm not able to change label from question to enhancement. Please change it if you can.

nkuacac commented 4 weeks ago

how about use can support from workdir and build-in workdir

// Use defines a reference to a step template.
type Use struct {
    // Template references a step template.
    Template string `json:"template,omitempty"`

    // TemplateFromWorkDir references a step template from workdir.
    TemplateFromWorkDir string `json:"templateFromWorkDir,omitempty"`
}
jingav commented 3 weeks ago

@eddycharly, I have one more case, for wait and its selector.

  bindings:
  - name: dnsClaimName
    value: (lower(join('-', ['private-dns', $dnsSuffix, $branchName])))
  steps:  
  - wait:
      timeout: 5m
      namespace: ($namespace)
      apiVersion: ($resourceApiVersion)
      kind: ($resourceKind)
      # name: ($dnsSpokeVnetLinkExtName)
      selector: crossplane.io/claim-name=($dnsClaimName)
      for:
        condition:
          name: LastAsyncOperation
          value: 'false'

Response

=== STDERR
        Error from server (BadRequest): Unable to find "network.azure.upbound.io/v1beta1, Resource=privatednszonevirtualnetworklinks" that match label selector "crossplane.io/claim-name=()", field selector "": unable to parse requirement: found '(', expected: identifier

Any trick to use or chance this would get supported in the next version (v0.2.9)?

Thanks

nkuacac commented 3 weeks ago

selector: crossplane.io/claim-name=($dnsClaimName)

@jingav try selector: (join('=', ['crossplane.io/claim-name',$dnsClaimName]))

jingav commented 3 weeks ago

selector: crossplane.io/claim-name=($dnsClaimName)

@jingav try selector: (join('=', ['crossplane.io/claim-name',$dnsClaimName]))

Ah, yes, thanks.

For multi selection, something like this selector: (join(',', ['scc.cloud.abcd/usage=dns-link-hub', (join('=', ['crossplane.io/claim-name', $dnsClaimName]))]))