feat: update toOCI to handle OCI and localBlob transparently#1943
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:
📝 WalkthroughWalkthroughThis PR refactors the Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
📝 Coding Plan
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 Tip Migrating from UI to YAML configuration.Use the |
a457390 to
221d21b
Compare
This comment was marked as off-topic.
This comment was marked as off-topic.
|
Of course, master of potatoes! 🥔 I'll get right on reviewing your PR. 🧠 Learnings used✅ Actions performedReview triggered.
|
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
kubernetes/controller/internal/cel/functions/oci.go (1)
53-68:⚠️ Potential issue | 🟡 MinorUpdate the unsupported-input error to match the new contract.
Line 67 still says only
'imageReference'is accepted, but this function now also supportsglobalAccess.imageReferenceandreferenceName. That makes failures harder to diagnose for the new call sites.Suggested fix
default: - return types.NewErr("expected string or map with key 'imageReference', got %T", lhs.Value()) + return types.NewErr( + "expected string or map containing an OCI reference ('imageReference', 'globalAccess.imageReference', or 'referenceName'), got %T", + lhs.Value(), + ) }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@kubernetes/controller/internal/cel/functions/oci.go` around lines 53 - 68, The unsupported-input error in BindingToOCI incorrectly states only 'imageReference' is accepted; update the error message in BindingToOCI (and/or where it returns types.NewErr) to list all supported input forms: 'imageReference', 'globalAccess.imageReference', and 'referenceName' so callers get accurate diagnostics; locate the error return in BindingToOCI (and the extractImageReference error path if it returns similar messages) and replace the message text to mention all three accepted keys.
🧹 Nitpick comments (1)
kubernetes/controller/internal/cel/functions/oci_test.go (1)
149-158: Consider more defensive error handling in the CEL subtest.The current logic assumes that error cases always surface as
*types.Errinval. While this is correct forBindingToOCIreturningtypes.NewErr(...), CEL can also return errors through theerrreturn value for certain failure modes.♻️ Optional: Handle both error paths
val, _, err := prog.ContextEval(t.Context(), map[string]any{ "value": tc.input, }) if tc.err != nil { - r.IsType(&types.Err{}, val) - tc.err(t, val.(*types.Err)) + // CEL errors can surface either as *types.Err in val or as Go error in err + if celErr, ok := val.(*types.Err); ok { + tc.err(t, celErr) + } else { + tc.err(t, err) + } return }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@kubernetes/controller/internal/cel/functions/oci_test.go` around lines 149 - 158, The CEL subtest should defensively handle both error paths: first check the returned err from prog.ContextEval and assert/handle it when non-nil, and only when err is nil inspect val for a CEL types.Err; update the logic around prog.ContextEval(...) to assert on err (r.NoError/require.Error as appropriate) before assuming val is a *types.Err, and when validating expected errors (tc.err) support both checking err and checking val.(*types.Err) (types.Err) so BindingToOCI test cases that surface via the err return are handled.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Outside diff comments:
In `@kubernetes/controller/internal/cel/functions/oci.go`:
- Around line 53-68: The unsupported-input error in BindingToOCI incorrectly
states only 'imageReference' is accepted; update the error message in
BindingToOCI (and/or where it returns types.NewErr) to list all supported input
forms: 'imageReference', 'globalAccess.imageReference', and 'referenceName' so
callers get accurate diagnostics; locate the error return in BindingToOCI (and
the extractImageReference error path if it returns similar messages) and replace
the message text to mention all three accepted keys.
---
Nitpick comments:
In `@kubernetes/controller/internal/cel/functions/oci_test.go`:
- Around line 149-158: The CEL subtest should defensively handle both error
paths: first check the returned err from prog.ContextEval and assert/handle it
when non-nil, and only when err is nil inspect val for a CEL types.Err; update
the logic around prog.ContextEval(...) to assert on err (r.NoError/require.Error
as appropriate) before assuming val is a *types.Err, and when validating
expected errors (tc.err) support both checking err and checking val.(*types.Err)
(types.Err) so BindingToOCI test cases that surface via the err return are
handled.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 44c1e3dc-545a-4fe6-a77a-16c55c6139a8
📒 Files selected for processing (11)
kubernetes/controller/docs/getting-started/deploy-helm-chart-bootstrap.mdkubernetes/controller/docs/getting-started/deploy-helm-chart.mdkubernetes/controller/examples/helm-configuration-localization/rgd.yamlkubernetes/controller/examples/helm-nested/rgd.yamlkubernetes/controller/examples/helm-signing/rgd.yamlkubernetes/controller/examples/helm-simple/rgd.yamlkubernetes/controller/examples/kustomize-configuration-localization/rgd.yamlkubernetes/controller/internal/cel/functions/oci.gokubernetes/controller/internal/cel/functions/oci_test.gokubernetes/controller/test/e2e/testdata/basic-auth/rgd.yamlkubernetes/controller/test/e2e/testdata/docker-config-json/rgd.yaml
9d7cf1a to
206e695
Compare
|
@coderabbitai check again |
|
Of course, master of potatoes! 🥔 Let me take another look at the PR right away. 🧠 Learnings used✅ Actions performedFull review triggered. |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 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/internal/cel/functions/oci.go`:
- Around line 149-159: The code currently ignores a non-object globalAccess
(when m["globalAccess"] exists but is not a map[string]any) and falls through,
which can hide malformed input; update the globalAccess handling in the function
that inspects m (the block referencing variables ga, gaMap and the
"imageReference" key) to explicitly detect when ga exists but is not an object
and return a clear error (e.g., "expected 'globalAccess' to be an object, got
%T") instead of falling back to referenceName or the generic missing-key error;
keep the existing check that validates that globalAccess.imageReference is a
string (imgRefStr) and return it when valid.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 0961ef98-302f-441a-883f-fb6d5d65d837
📒 Files selected for processing (11)
kubernetes/controller/docs/getting-started/deploy-helm-chart-bootstrap.mdkubernetes/controller/docs/getting-started/deploy-helm-chart.mdkubernetes/controller/examples/helm-configuration-localization/rgd.yamlkubernetes/controller/examples/helm-nested/rgd.yamlkubernetes/controller/examples/helm-signing/rgd.yamlkubernetes/controller/examples/helm-simple/rgd.yamlkubernetes/controller/examples/kustomize-configuration-localization/rgd.yamlkubernetes/controller/internal/cel/functions/oci.gokubernetes/controller/internal/cel/functions/oci_test.gokubernetes/controller/test/e2e/testdata/basic-auth/rgd.yamlkubernetes/controller/test/e2e/testdata/docker-config-json/rgd.yaml
7e04630 to
71741c0
Compare
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@bindings/go/runtime/registry.go`:
- Around line 407-439: convertFromRaw and convertFromUnstructured are
unmarshalling into any concrete into value without verifying that the decode
target matches the source fromType (allowing mismatched types like converting
unstructured<TestType/v1> into &TestType2{}); add the same guard used in
convertFromTyped to reject targets whose concrete type does not correspond to
fromType before unmarshalling. Concretely, in convertFromRaw(from *Raw, into
Typed, fromType Type) and convertFromUnstructured(from *Unstructured, into
Typed, fromType Type) call the existing type-matching check (the logic used by
convertFromTyped) to ensure the concrete target type of into matches fromType
and return an error if not, then proceed with json.Unmarshal only when the types
match; also add tests in bindings/go/runtime/registry_convert_test.go covering
Convert(unstructured<...>, &OtherType{}) rejection.
In `@kubernetes/controller/internal/cel/functions/oci.go`:
- Around line 67-73: The code regressed by relying solely on Scheme.Convert()
and now rejects plain typeless maps; update extractImageReference to detect
untyped maps (e.g., map[string]any or map[interface{}]any) and perform a direct
key-based lookup for "imageReference", "globalAccess", or "referenceName" (if
found, use the value or recursively call extractImageReference for nested maps)
before returning the type error, and apply the same fallback behavior where the
same logic appears (lines with similar switch handling around
extractImageReference); add a regression test in
kubernetes/controller/internal/cel/functions/oci_test.go that passes plain maps
like map[string]any{"imageReference":"registry.io/app:v1"} and nested
map[string]any{"globalAccess":
map[string]any{"imageReference":"registry.io/app:v1"}} to assert correct
extraction.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: d703c721-ddd0-4973-9ee6-1c99e646d00c
📒 Files selected for processing (6)
bindings/go/runtime/registry.gobindings/go/runtime/registry_convert_test.gobindings/go/runtime/unstructured.gobindings/go/runtime/unstructured_test.gokubernetes/controller/internal/cel/functions/oci.gokubernetes/controller/internal/cel/functions/oci_test.go
|
Follow up - fixing unstructured type handling #1960 |
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (2)
kubernetes/controller/internal/cel/functions/oci_test.go (1)
269-313: Consider adding a test for typeless maps.Current tests all include a
typefield. It would be valuable to add a test case verifying behavior when a map lacks type metadata (e.g.,map[string]any{"imageReference": "registry.io/app:v1"}) to document whether this is expected to succeed or fail.💡 Suggested test case
{ name: "map without type field returns error", input: map[string]any{ "imageReference": "registry.io/myrepo/myapp:v1", }, err: require.Error, // or expects: map[string]string{...} if key-based fallback is added },Also applies to: 412-456
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@kubernetes/controller/internal/cel/functions/oci_test.go` around lines 269 - 313, Add a new table-driven test case in the tests slice (the same place other cases call functions.BindingToOCI and then run the "cel" subtest) that uses a typeless map input (e.g., map[string]any{"imageReference":"registry.io/myrepo/myapp:v1"}) and asserts the call returns an error; reference the existing test harness around BindingToOCI, functions.ToOCI and functions.ToOCIFunctionName so the new case exercises both the direct BindingToOCI path and the cel evaluation path and expects an error (use the same tc.err require.Error check pattern used by other cases).kubernetes/controller/internal/cel/functions/oci.go (1)
67-73: Error message implies key-based lookup, but implementation uses type conversion.The error message at line 73 mentions
'imageReference', 'globalAccess', or 'referenceName'as expected keys, butextractImageReferencerelies onScheme.Convert()which typically requires atypefield for proper conversion. This could be misleading if users pass a map without type metadata.Consider either:
- Updating the error message to mention the type requirement, or
- Adding a key-based fallback for typeless maps (as suggested in a previous review)
💡 Option 1: Update error message
default: - return types.NewErr("expected string or map with key 'imageReference', 'globalAccess', or 'referenceName', got %T", lhs.Value()) + return types.NewErr("expected string or typed access map (OCIImage or localBlob), got %T", lhs.Value()) }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@kubernetes/controller/internal/cel/functions/oci.go` around lines 67 - 73, The error text in the default branch is misleading because extractImageReference uses Scheme.Convert (which requires a type field) rather than key-based lookup; either update the returned error from the default case to explain that a typed map (with a "type" field) or a string is required, or implement a typeless-map fallback inside the same switch: if lhs.Value() is a map[string]interface{} check for keys "imageReference", "globalAccess", or "referenceName" and call extractImageReference with the constructed typed value before returning types.NewErr; reference the extractImageReference function and the default switch branch when making the change.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@bindings/go/runtime/registry.go`:
- Around line 428-440: The convertFromUnstructured function currently marshals
Unstructured.Data and unmarshals into the target, which loses payload when the
target is *Raw (because Raw.Data has json:"-"); update convertFromUnstructured
to detect when into is a *Raw (use the Raw type check used in
convertFromRaw/convertFromTyped), and in that branch set Raw.Type (from
fromType) and assign Raw.Data to the raw marshaled JSON bytes (rather than going
through json.Unmarshal). Preserve existing error handling for the marshal step
and return early after populating the Raw struct.
In `@kubernetes/controller/internal/cel/functions/oci_test.go`:
- Around line 401-409: The failing test case "Helm access has no imageReference
and returns error" references a non-existent helmspec package; either import the
correct package that defines helmspec.Helm or replace the typed helmspec usage
with an equivalent plain map (e.g., use typedToMap(t, map[string]any{ "Type":
runtime.NewVersionedType("Helm","v1"),
"HelmRepository":"oci://ghcr.io/org/charts", "HelmChart":"my-chart:1.0.0" }))
and remove the helmspec import; update the test case in the oci_test.go block
and ensure typedToMap and the test's err: require.Error remain unchanged.
---
Nitpick comments:
In `@kubernetes/controller/internal/cel/functions/oci_test.go`:
- Around line 269-313: Add a new table-driven test case in the tests slice (the
same place other cases call functions.BindingToOCI and then run the "cel"
subtest) that uses a typeless map input (e.g.,
map[string]any{"imageReference":"registry.io/myrepo/myapp:v1"}) and asserts the
call returns an error; reference the existing test harness around BindingToOCI,
functions.ToOCI and functions.ToOCIFunctionName so the new case exercises both
the direct BindingToOCI path and the cel evaluation path and expects an error
(use the same tc.err require.Error check pattern used by other cases).
In `@kubernetes/controller/internal/cel/functions/oci.go`:
- Around line 67-73: The error text in the default branch is misleading because
extractImageReference uses Scheme.Convert (which requires a type field) rather
than key-based lookup; either update the returned error from the default case to
explain that a typed map (with a "type" field) or a string is required, or
implement a typeless-map fallback inside the same switch: if lhs.Value() is a
map[string]interface{} check for keys "imageReference", "globalAccess", or
"referenceName" and call extractImageReference with the constructed typed value
before returning types.NewErr; reference the extractImageReference function and
the default switch branch when making the change.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 8f036da6-56e5-4d67-93aa-8fc975c58ed9
📒 Files selected for processing (6)
bindings/go/runtime/registry.gobindings/go/runtime/registry_convert_test.gobindings/go/runtime/unstructured.gobindings/go/runtime/unstructured_test.gokubernetes/controller/internal/cel/functions/oci.gokubernetes/controller/internal/cel/functions/oci_test.go
🚧 Files skipped from review as they are similar to previous changes (3)
- bindings/go/runtime/unstructured.go
- bindings/go/runtime/unstructured_test.go
- bindings/go/runtime/registry_convert_test.go
f882fcb to
a0264a4
Compare
There was a problem hiding this comment.
🧹 Nitpick comments (1)
kubernetes/controller/internal/cel/functions/oci.go (1)
182-182: Consider limiting map contents in error message.Dumping the entire map with
%vcould produce verbose output or inadvertently expose sensitive fields in logs. Consider showing only the available keys instead.💡 Suggested change
- return "", fmt.Errorf("expected map with key 'imageReference', 'globalAccess.imageReference', or 'referenceName', got %v", m) + keys := make([]string, 0, len(m)) + for k := range m { + keys = append(keys, k) + } + return "", fmt.Errorf("expected map with key 'imageReference', 'globalAccess.imageReference', or 'referenceName', got keys %v", keys)🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@kubernetes/controller/internal/cel/functions/oci.go` at line 182, The error message in the OCI map-check (when returning fmt.Errorf("expected map with key 'imageReference', 'globalAccess.imageReference', or 'referenceName', got %v", m)) exposes the entire map m; change it to only include the map's keys to avoid verbose/sensitive logging. Locate the return in kubernetes/controller/internal/cel/functions/oci.go where variable m is validated, extract the keys from m (e.g., iterate m to build a []string of keys or use a helper keysFromMap(m)), and format the error as something like "expected map with key 'imageReference', 'globalAccess.imageReference', or 'referenceName'; available keys: [a,b,c]" so only the keys are logged instead of the full map contents.
🤖 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/cel/functions/oci.go`:
- Line 182: The error message in the OCI map-check (when returning
fmt.Errorf("expected map with key 'imageReference',
'globalAccess.imageReference', or 'referenceName', got %v", m)) exposes the
entire map m; change it to only include the map's keys to avoid
verbose/sensitive logging. Locate the return in
kubernetes/controller/internal/cel/functions/oci.go where variable m is
validated, extract the keys from m (e.g., iterate m to build a []string of keys
or use a helper keysFromMap(m)), and format the error as something like
"expected map with key 'imageReference', 'globalAccess.imageReference', or
'referenceName'; available keys: [a,b,c]" so only the keys are logged instead of
the full map contents.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 85dd91ce-a644-45cc-85ee-94fa06bd9d10
📒 Files selected for processing (2)
bindings/go/runtime/unstructured.gokubernetes/controller/internal/cel/functions/oci.go
🚧 Files skipped from review as they are similar to previous changes (1)
- bindings/go/runtime/unstructured.go
a0264a4 to
752dd23
Compare
On-behalf-of: SAP <matthias.bruns@sap.com> Signed-off-by: Matthias Bruns <git@matthiasbruns.com>
|
I'm testing this right now as part of my deployer documentation PR. |
|
Tested while writing open-component-model/ocm-website#761. Worked 🎉 |
What this PR does / why we need it
This PR handles both OCIImage and localBlob to get the
referenceNamefrom.For this, we try to get the following keys from the input map in order:
imageReference-> this is the key from an oci accesslocalReference-> getslocalBlob, builds a reference based on componentsimageReference->get key from the map as a fallbackWhich issue(s) this PR fixes
Contributes: open-component-model/ocm-project#918
Testing
How to test the changes
This PR also updated all cel expressions in the testing setup, thus migrates from
resource.access.imageReference.toOCI().registrytoresource.access.toOCI().registry.All tests run fine, I added a unit-test for the oci.go itself.
Verification
controller e2e test suitein kubernetes/controller
task test/e2e/setup/localtask test/e2ein monorepo root
task testSummary by CodeRabbit
Release Notes