feat(913)!: object in status field#2008
Conversation
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughResourceSpec.AdditionalStatusFields changed from string values to JSON ( Changes
Sequence DiagramsequenceDiagram
participant Client as Client/User
participant Controller as ResourceController
participant CELEval as ComputeAdditionalStatusFields
participant CELEngine as CEL Engine
participant Converter as GoNativeType
participant Status as Resource.Status
Client->>Controller: Create/Update Resource with spec.additionalStatusFields
Controller->>CELEval: ComputeAdditionalStatusFields(ctx, res, resource, component)
CELEval->>CELEval: convert resource -> generic map
CELEval->>CELEval: iterate entries and dispatch per-field
alt field is CEL string
CELEval->>CELEngine: compile & evaluate expression
CELEngine->>Converter: return ref.Val
Converter-->>CELEval: native Go value
else field is nested object
CELEval->>CELEval: recurse into nested object, evaluate CEL strings
CELEval->>CELEngine: evaluate nested CEL expressions
CELEngine->>Converter: convert nested ref.Val
Converter-->>CELEval: native nested value
end
CELEval->>CELEval: marshal native values -> apiextensionsv1.JSON
CELEval-->>Controller: map[string]apiextensionsv1.JSON
Controller->>Status: assign Resource.Status.Additional
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (1 warning, 1 inconclusive)
✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
9548175 to
5d48ba3
Compare
b323799 to
620243b
Compare
1217524 to
a8678ca
Compare
0b5ec5b to
a2d5fb9
Compare
|
STOP FAILING GOD DAMNIT |
stupid me |
There was a problem hiding this comment.
Actionable comments posted: 5
🧹 Nitpick comments (2)
kubernetes/controller/internal/controller/resource/conversion/conversions_test.go (1)
1-213: LGTM! Comprehensive test coverage for CEL type conversions.The tests thoroughly cover scalar types, collections (lists, maps), nested structures, and special types (duration, timestamp, bytes). The deep-copy test properly validates mutation isolation.
Consider adding a test for the
ErrUnsupportedTypeerror path to ensure unsupported CEL types are handled gracefully.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@kubernetes/controller/internal/controller/resource/conversion/conversions_test.go` around lines 1 - 213, Add a new unit test in conversions_test.go that constructs a CEL value representing an unsupported type and calls GoNativeType, asserting it returns the package's ErrUnsupportedType (and non-nil error); specifically reference GoNativeType and ErrUnsupportedType in the test, create or mock a cel ref.Val that triggers the unsupported path (e.g., via types.NewEmptyRegistry().NativeToValue with a custom/unknown native type or a crafted cel.Value), and verify the error value equals ErrUnsupportedType and no nil result is returned.kubernetes/controller/examples/helm-simple-nested-status/rgd.yaml (1)
10-10: Prefer secure-by-default registry config in the example.Line 36 hardwires
insecure: true. Consider making this configurable and defaulting tofalseso copied manifests don’t inherit an insecure setting.Suggested refactor
spec: prefix: string | default="helm-simple-nested-status" + insecureRegistry: bool | default=false @@ - insecure: true + insecure: ${schema.spec.insecureRegistry}Also applies to: 36-36
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@kubernetes/controller/examples/helm-simple-nested-status/rgd.yaml` at line 10, The example hardcodes insecure: true which is unsafe; update the rgd.yaml example to make the registry insecure flag configurable (e.g., introduce a registry.insecure variable) and set its default to false, and update any references that currently set insecure: true to read that variable (look for the insecure field in the registry/remote/helm config and the prefix declaration) so that copied manifests default to secure behavior while still allowing opt-in insecure usage.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@kubernetes/controller/config/crd/bases/delivery.ocm.software_resources.yaml`:
- Around line 52-61: The Helm chart CRD for resources.delivery.ocm.software is
missing the additionalProperties block under additionalStatusFields that exists
in the base CRD (additionalStatusFields -> additionalProperties with
x-kubernetes-preserve-unknown-fields: true); fix by regenerating the Helm
templates from the base CRDs (run the provided sync task: task
helm/sync-manifests) so the
chart/templates/crd/resources.delivery.ocm.software.yaml includes the
additionalProperties stanza, or if you must patch manually, add the
additionalProperties block under additionalStatusFields with
x-kubernetes-preserve-unknown-fields: true to match
config/crd/bases/delivery.ocm.software_resources.yaml.
In `@kubernetes/controller/examples/helm-simple-nested-status/rgd.yaml`:
- Line 56: The example hardcodes chartRef.namespace to "default", which breaks
when instantiated in other namespaces; update the rgd.yaml example so
chartRef.namespace is not fixed to "default" — either remove the namespace key
so the reference resolves in the same namespace as the graph, or replace the
literal with a namespace variable that references the containing resource (e.g.,
use the graph's metadata.namespace or a templated/current-namespace
placeholder). Ensure the change targets the chartRef.namespace entry so the
reference is namespace-agnostic.
In
`@kubernetes/controller/internal/controller/resource/conversion/conversions.go`:
- Around line 83-87: In convertMap, the fallback call to
v.ConvertToNative(reflect.TypeOf(map[string]any{})) ignores the returned error;
modify convertMap (like convertList) to capture both return values from
ConvertToNative and if an error is returned propagate it (return nil, err) or
otherwise return the converted value and nil error, ensuring you reference the
convertMap function and the ConvertToNative(reflect.TypeOf(map[string]any{}))
call site when making the change.
- Around line 65-69: In convertList, handle the error returned by
v.ConvertToNative(reflect.TypeOf([]interface{}{})) when v does not implement
traits.Lister: call v.ConvertToNative(...), capture both (val, err), and if err
!= nil return nil, err (or wrap the error with context) otherwise return val,
nil; update function convertList to propagate that error instead of discarding
it.
In `@kubernetes/controller/test/e2e/hacks/setup.sh`:
- Line 119: The helm install line using "--version=0.8.5" may be pinning a chart
version that doesn't exist or doesn't bundle kro app v0.8.5; verify and fix by
pulling/inspecting the chart and then updating the helm invocation: run "helm
pull" or "helm show chart oci://registry.k8s.io/kro/charts/kro --version
<chart-ver>" and confirm Chart.yaml.appVersion matches 0.8.5, then update the
script's helm install command (the line starting with "helm install kro
oci://registry.k8s.io/kro/charts/kro --namespace kro --create-namespace
--version=0.8.5 || exit 1") to use the correct chart --version that contains
appVersion 0.8.5 (or remove the --version to use the repo latest) and fail the
script if the pulled Chart.yaml.appVersion does not equal 0.8.5.
---
Nitpick comments:
In `@kubernetes/controller/examples/helm-simple-nested-status/rgd.yaml`:
- Line 10: The example hardcodes insecure: true which is unsafe; update the
rgd.yaml example to make the registry insecure flag configurable (e.g.,
introduce a registry.insecure variable) and set its default to false, and update
any references that currently set insecure: true to read that variable (look for
the insecure field in the registry/remote/helm config and the prefix
declaration) so that copied manifests default to secure behavior while still
allowing opt-in insecure usage.
In
`@kubernetes/controller/internal/controller/resource/conversion/conversions_test.go`:
- Around line 1-213: Add a new unit test in conversions_test.go that constructs
a CEL value representing an unsupported type and calls GoNativeType, asserting
it returns the package's ErrUnsupportedType (and non-nil error); specifically
reference GoNativeType and ErrUnsupportedType in the test, create or mock a cel
ref.Val that triggers the unsupported path (e.g., via
types.NewEmptyRegistry().NativeToValue with a custom/unknown native type or a
crafted cel.Value), and verify the error value equals ErrUnsupportedType and no
nil result is returned.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 09753e80-a742-45c0-832a-9508e3919d22
📒 Files selected for processing (17)
kubernetes/controller/api/v1alpha1/resource_types.gokubernetes/controller/api/v1alpha1/zz_generated.deepcopy.gokubernetes/controller/chart/templates/crd/resources.delivery.ocm.software.yamlkubernetes/controller/config/crd/bases/delivery.ocm.software_resources.yamlkubernetes/controller/examples/helm-simple-nested-status/bootstrap.yamlkubernetes/controller/examples/helm-simple-nested-status/component-constructor.yamlkubernetes/controller/examples/helm-simple-nested-status/instance.yamlkubernetes/controller/examples/helm-simple-nested-status/rgd.yamlkubernetes/controller/internal/cel/functions/oci.gokubernetes/controller/internal/cel/functions/oci_test.gokubernetes/controller/internal/controller/resource/cel_eval.gokubernetes/controller/internal/controller/resource/cel_eval_test.gokubernetes/controller/internal/controller/resource/conversion/conversions.gokubernetes/controller/internal/controller/resource/conversion/conversions_test.gokubernetes/controller/internal/controller/resource/resource_controller.gokubernetes/controller/internal/controller/resource/resource_controller_test.gokubernetes/controller/test/e2e/hacks/setup.sh
151a210 to
ce7213c
Compare
There was a problem hiding this comment.
🧹 Nitpick comments (2)
kubernetes/controller/internal/controller/resource/resource_controller_test.go (2)
866-870: Expand nested-object test to cover mixed literal + CEL types.Line 866 currently builds the nested object as
map[string]string, so all nested values are CEL strings. Adding at least one literal (e.g., bool/number) would validate that mixed typed nested JSON is preserved and not only string-expression leaves.Also applies to: 886-890
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@kubernetes/controller/internal/controller/resource/resource_controller_test.go` around lines 866 - 870, The nested test JSON currently uses map[string]string so every nested value becomes a CEL-string; change the nested literal construction to use map[string]interface{} (or equivalent) and set at least one nested value to a non-string literal (e.g., boolean or number) so mixed literal + CEL-expression types are exercised; update both occurrences that build the "oci" Raw payload (the map passed into mustMarshalJSON in resource_controller_test.go) and keep keys like "registry"/"repository"/"reference" but make one key a literal (e.g., add "insecure": true or "port": 443) to validate mixed-typed nested JSON is preserved.
111-127: Consider a helper for CEL JSON string encoding to reduce repetition.Line 111–Line 127 repeats the same raw JSON-string wrapping pattern many times, which is easy to mistype and harder to maintain.
Refactor sketch
+func mustCELExprJSON(expr string) apiextensionsv1.JSON { + return mustToJSON(expr) +} ... - additionalStatusFields["registry"] = apiextensionsv1.JSON{Raw: []byte(`"resource.access.toOCI().registry"`)} + additionalStatusFields["registry"] = mustCELExprJSON("resource.access.toOCI().registry")🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@kubernetes/controller/internal/controller/resource/resource_controller_test.go` around lines 111 - 127, The test repeatedly constructs apiextensionsv1.JSON values using Raw: []byte(`"..."`) (e.g., lines setting additionalStatusFields["registry"], "repository", "reference", "helmChart", "gitRepoURL", "gitRepository"); create a small helper function (e.g., celStringJSON or mustCELJSON) that accepts the unquoted CEL expression string and returns apiextensionsv1.JSON with the correctly quoted Raw bytes, then replace each Raw: []byte(...) site in the resource_controller_test.go setup with calls to that helper to remove repetition and prevent quoting mistakes.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In
`@kubernetes/controller/internal/controller/resource/resource_controller_test.go`:
- Around line 866-870: The nested test JSON currently uses map[string]string so
every nested value becomes a CEL-string; change the nested literal construction
to use map[string]interface{} (or equivalent) and set at least one nested value
to a non-string literal (e.g., boolean or number) so mixed literal +
CEL-expression types are exercised; update both occurrences that build the "oci"
Raw payload (the map passed into mustMarshalJSON in resource_controller_test.go)
and keep keys like "registry"/"repository"/"reference" but make one key a
literal (e.g., add "insecure": true or "port": 443) to validate mixed-typed
nested JSON is preserved.
- Around line 111-127: The test repeatedly constructs apiextensionsv1.JSON
values using Raw: []byte(`"..."`) (e.g., lines setting
additionalStatusFields["registry"], "repository", "reference", "helmChart",
"gitRepoURL", "gitRepository"); create a small helper function (e.g.,
celStringJSON or mustCELJSON) that accepts the unquoted CEL expression string
and returns apiextensionsv1.JSON with the correctly quoted Raw bytes, then
replace each Raw: []byte(...) site in the resource_controller_test.go setup with
calls to that helper to remove repetition and prevent quoting mistakes.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 0d1aa48b-c2e6-45ae-8c3e-b9abba9361ce
📒 Files selected for processing (2)
kubernetes/controller/examples/helm-simple-nested-status/rgd.yamlkubernetes/controller/internal/controller/resource/resource_controller_test.go
✅ Files skipped from review due to trivial changes (1)
- kubernetes/controller/examples/helm-simple-nested-status/rgd.yaml
On-behalf-of: SAP <matthias.bruns@sap.com> Signed-off-by: Matthias Bruns <git@matthiasbruns.com> # Conflicts: # kubernetes/controller/internal/controller/resource/resource_controller_test.go
On-behalf-of: SAP <matthias.bruns@sap.com> Signed-off-by: Matthias Bruns <git@matthiasbruns.com>
On-behalf-of: SAP <matthias.bruns@sap.com> Signed-off-by: Matthias Bruns <git@matthiasbruns.com> # Conflicts: # kubernetes/controller/internal/controller/resource/resource_controller.go
On-behalf-of: SAP <matthias.bruns@sap.com> Signed-off-by: Matthias Bruns <git@matthiasbruns.com>
On-behalf-of: SAP <matthias.bruns@sap.com> Signed-off-by: Matthias Bruns <git@matthiasbruns.com>
On-behalf-of: SAP <matthias.bruns@sap.com> Signed-off-by: Matthias Bruns <git@matthiasbruns.com>
On-behalf-of: SAP <matthias.bruns@sap.com> Signed-off-by: Matthias Bruns <git@matthiasbruns.com>
On-behalf-of: SAP <matthias.bruns@sap.com> Signed-off-by: Matthias Bruns <git@matthiasbruns.com>
On-behalf-of: SAP <matthias.bruns@sap.com> Signed-off-by: Matthias Bruns <git@matthiasbruns.com>
On-behalf-of: SAP <matthias.bruns@sap.com> Signed-off-by: Matthias Bruns <git@matthiasbruns.com>
On-behalf-of: SAP <matthias.bruns@sap.com> Signed-off-by: Matthias Bruns <git@matthiasbruns.com>
On-behalf-of: SAP <matthias.bruns@sap.com> Signed-off-by: Matthias Bruns <git@matthiasbruns.com>
On-behalf-of: SAP <matthias.bruns@sap.com> Signed-off-by: Matthias Bruns <git@matthiasbruns.com>
On-behalf-of: SAP <matthias.bruns@sap.com> Signed-off-by: Matthias Bruns <git@matthiasbruns.com>
On-behalf-of: SAP <matthias.bruns@sap.com> Signed-off-by: Matthias Bruns <git@matthiasbruns.com>
69a8e0b to
41f96a5
Compare
There was a problem hiding this comment.
🧹 Nitpick comments (2)
kubernetes/controller/internal/controller/resource/conversion/conversions.go (2)
116-118: Consider adding context to value conversion error.Line 109 wraps key conversion errors with context, but value conversion errors at line 118 are returned without indicating which key caused the failure. This could make debugging harder.
♻️ Proposed fix
valNative, err := GoNativeType(val) if err != nil { - return nil, err + return nil, fmt.Errorf("failed to convert map value for key %q: %w", keyStr, err) }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@kubernetes/controller/internal/controller/resource/conversion/conversions.go` around lines 116 - 118, The value conversion error returned from GoNativeType (when assigning valNative) lacks context about which key failed; update the error handling around the GoNativeType call (where valNative, err := GoNativeType(val) is invoked) to wrap or format the error with the associated key (e.g., include the variable key) so the returned error reads like "failed converting value for key '<key>': <err>". Use the project's preferred error-wrapping pattern (fmt.Errorf or errors.Wrap) and keep the variable names (val, valNative, key, err) to locate the change.
102-104: Nil key handling is silent - consider logging or erroring.CEL maps shouldn't have nil keys. If
it.Next()returns nil, it may indicate an internal issue that would be silently masked here. Consider returning an error or adding a debug log for visibility.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@kubernetes/controller/internal/controller/resource/conversion/conversions.go` around lines 102 - 104, The nil-key branch silently skips an unexpected case from it.Next(), which masks internal errors; replace the silent continue in the key == nil check with visible handling: either return an error (e.g., fmt.Errorf) from the conversion function or emit a debug/error log via your project logger (klog/logr) including context (e.g., the iterator state and surrounding map name). Update the branch in the function where it.Next() is called so callers can detect and handle this abnormal nil-key instead of silently dropping it.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In
`@kubernetes/controller/internal/controller/resource/conversion/conversions.go`:
- Around line 116-118: The value conversion error returned from GoNativeType
(when assigning valNative) lacks context about which key failed; update the
error handling around the GoNativeType call (where valNative, err :=
GoNativeType(val) is invoked) to wrap or format the error with the associated
key (e.g., include the variable key) so the returned error reads like "failed
converting value for key '<key>': <err>". Use the project's preferred
error-wrapping pattern (fmt.Errorf or errors.Wrap) and keep the variable names
(val, valNative, key, err) to locate the change.
- Around line 102-104: The nil-key branch silently skips an unexpected case from
it.Next(), which masks internal errors; replace the silent continue in the key
== nil check with visible handling: either return an error (e.g., fmt.Errorf)
from the conversion function or emit a debug/error log via your project logger
(klog/logr) including context (e.g., the iterator state and surrounding map
name). Update the branch in the function where it.Next() is called so callers
can detect and handle this abnormal nil-key instead of silently dropping it.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: ff1b1a20-4ced-4811-ba44-0ff120900863
📒 Files selected for processing (20)
kubernetes/controller/api/v1alpha1/resource_types.gokubernetes/controller/api/v1alpha1/zz_generated.deepcopy.gokubernetes/controller/chart/templates/crd/components.delivery.ocm.software.yamlkubernetes/controller/chart/templates/crd/deployers.delivery.ocm.software.yamlkubernetes/controller/chart/templates/crd/repositories.delivery.ocm.software.yamlkubernetes/controller/chart/templates/crd/resources.delivery.ocm.software.yamlkubernetes/controller/config/crd/bases/delivery.ocm.software_resources.yamlkubernetes/controller/examples/helm-simple-nested-status/bootstrap.yamlkubernetes/controller/examples/helm-simple-nested-status/component-constructor.yamlkubernetes/controller/examples/helm-simple-nested-status/instance.yamlkubernetes/controller/examples/helm-simple-nested-status/rgd.yamlkubernetes/controller/internal/cel/functions/oci.gokubernetes/controller/internal/cel/functions/oci_test.gokubernetes/controller/internal/controller/resource/cel_eval.gokubernetes/controller/internal/controller/resource/cel_eval_test.gokubernetes/controller/internal/controller/resource/conversion/conversions.gokubernetes/controller/internal/controller/resource/conversion/conversions_test.gokubernetes/controller/internal/controller/resource/resource_controller.gokubernetes/controller/internal/controller/resource/resource_controller_test.gokubernetes/controller/test/e2e/hacks/setup.sh
✅ Files skipped from review due to trivial changes (12)
- kubernetes/controller/chart/templates/crd/deployers.delivery.ocm.software.yaml
- kubernetes/controller/test/e2e/hacks/setup.sh
- kubernetes/controller/chart/templates/crd/repositories.delivery.ocm.software.yaml
- kubernetes/controller/chart/templates/crd/components.delivery.ocm.software.yaml
- kubernetes/controller/api/v1alpha1/zz_generated.deepcopy.go
- kubernetes/controller/examples/helm-simple-nested-status/instance.yaml
- kubernetes/controller/internal/controller/resource/resource_controller.go
- kubernetes/controller/examples/helm-simple-nested-status/bootstrap.yaml
- kubernetes/controller/internal/controller/resource/conversion/conversions_test.go
- kubernetes/controller/examples/helm-simple-nested-status/component-constructor.yaml
- kubernetes/controller/examples/helm-simple-nested-status/rgd.yaml
- kubernetes/controller/internal/controller/resource/cel_eval_test.go
🚧 Files skipped from review as they are similar to previous changes (4)
- kubernetes/controller/chart/templates/crd/resources.delivery.ocm.software.yaml
- kubernetes/controller/config/crd/bases/delivery.ocm.software_resources.yaml
- kubernetes/controller/internal/controller/resource/cel_eval.go
- kubernetes/controller/internal/cel/functions/oci.go
- refactor: simplify `AdditionalStatusFields` handling for better clarity and extensibility. - fix: align CRD definitions with new `apiextensionsv1.JSON` structure. Signed-off-by: Jakob Möller <contact@jakob-moeller.com>

What this PR does / why we need it
Currently,
additionalStatusFieldsis amap[string]string.Kor supports objects in the statusFields, so we can e.g. change the
toOCIexpressions toWhich issue(s) this PR fixes
Fixes: open-component-model/ocm-project#913
Testing
How to test the changes
Verification
ocmSummary by CodeRabbit
New Features
Tests
Chores