Skip to content

Create setters KRM function incorrectly matches setter values in internal.config.kubernetes.io annotations #4462

@aravindtga

Description

@aravindtga

Description

The create-setters function incorrectly adds setter comments to internal kpt annotations that are not part of the user-authored resource content.

When running kpt fn render on a package that uses create-setters, the function scans all fields in a resource, including internal.config.kubernetes.io/package-path, which is an annotation automatically injected by kpt containing the filesystem path. If a setter value (e.g. 4 from nginx-replicas: 4) happens to appear as a digit in the filesystem path, the function treats it as a match and produces an incorrect result:

"kpt-set: 
/tmp/kpt-pipeline-e2e-10${nginx-replicas}7697916/create-setters-simple"
 for field with value 
"/tmp/kpt-pipeline-e2e-1047697916/create-setters-simple"

Steps to reproduce

  1. Use the examples/create-setters-simple package from the krm-functions-catalog:
cp -r examples/create-setters-simple /tmp/test-create-setters44
cd /tmp/test-create-setters44
  1. Verify the fn-config uses nginx-replicas setter with value 4:
cat setters.yaml
# nginx-replicas: "4"
  1. Run kpt fn render:
kpt fn render
  1. Inspect the Kptfile, the renderStatus will contain spurious results for internal.config.kubernetes.io/package-path:
cat Kptfile

Output includes:

- message: 'Added line comment "kpt-set: /tmp/test-create-setters-${nginx-replicas}..." for field with value "/tmp/test-create-setters-4..."'
 field:
   path: metadata.annotations.internal.config.kubernetes.io/package-path

Root cause

In createsetters/create_setters.go, visitScalar() processes every scalar node without checking if the field path belongs to an internal annotation:

func (cs CreateSetters) visitScalar(object yaml.RNode, path string) error {
   if object.YNode().Kind != yaml.ScalarNode {
       return nil
   }
   if hasMultipleLines(object.YNode().Value) {
       return nil
   }
   linecomment, valueMatch := getLineComment(object.YNode().Value, cs.replacer)
   // No check for internal annotations — matches against all fields
   ...
}

Why this is visible now

This bug has existed since the create-setters function was written, but was previously invisible because the spurious result messages were only printed to stdout during kpt fn render and never persisted. With the introduction of renderStatus in the Kptfile (kptdev/kpt#4437), per-function structured results are now written to the Kptfile and included in diff comparisons, making the non-deterministic output visible in E2E tests.

Expected behaviour

Fields under internal.config.kubernetes.io/* and config.kubernetes.io/* annotations should be excluded from setter matching, as they are kpt runtime metadata and not user-authored resource content.

Metadata

Metadata

Assignees

No one assigned

    Labels

    area/fn-catalogFunctions CatalogbugSomething isn't workinggoPull requests that update Go code

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions