-
Notifications
You must be signed in to change notification settings - Fork 258
Create setters KRM function incorrectly matches setter values in internal.config.kubernetes.io annotations #4462
Description
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
- Use the
examples/create-setters-simplepackage from the krm-functions-catalog:
cp -r examples/create-setters-simple /tmp/test-create-setters44
cd /tmp/test-create-setters44- Verify the fn-config uses
nginx-replicassetter with value4:
cat setters.yaml
# nginx-replicas: "4"- Run
kpt fn render:
kpt fn render- Inspect the Kptfile, the
renderStatuswill contain spurious results forinternal.config.kubernetes.io/package-path:
cat KptfileOutput 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-pathRoot 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.