From dd1b7753a7269b39cfe81b5daa92d9e9c473a327 Mon Sep 17 00:00:00 2001 From: Adam Wolfe Gordon Date: Fri, 5 Jun 2026 16:03:58 -0600 Subject: [PATCH 1/2] render: Use crossplane.io/composition-resource-name constant from xcrd As noted by the coderabbit bot on #82, this const is duplicated in the CLI. Use the version from crossplane-runtime, since it's what Crossplane uses. Signed-off-by: Adam Wolfe Gordon --- cmd/crossplane/render/xr/cmd.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/crossplane/render/xr/cmd.go b/cmd/crossplane/render/xr/cmd.go index 5f4a317..ece36cb 100644 --- a/cmd/crossplane/render/xr/cmd.go +++ b/cmd/crossplane/render/xr/cmd.go @@ -337,7 +337,7 @@ func (c *Cmd) Run(k *kong.Context, log logging.Logger, sp terminal.SpinnerPrinte for i := range out.ComposedResources { _, _ = fmt.Fprintln(k.Stdout, "---") if err := s.Encode(&out.ComposedResources[i], k.Stdout); err != nil { - return errors.Wrapf(err, "cannot marshal composed resource %q to YAML", out.ComposedResources[i].GetAnnotations()[render.AnnotationKeyCompositionResourceName]) + return errors.Wrapf(err, "cannot marshal composed resource %q to YAML", out.ComposedResources[i].GetAnnotations()[xcrd.AnnotationKeyCompositionResourceName]) } } From b665f70d232aa38ba30bb55e3b961aaf72d205f5 Mon Sep 17 00:00:00 2001 From: Adam Wolfe Gordon Date: Fri, 5 Jun 2026 16:04:49 -0600 Subject: [PATCH 2/2] render: Remove unused code When we switched render to use the high-fidelity engine (`crossplane internal render`), we left behind some helper functions that are exported but no longer used. These functions just duplicate functionality from the real composite controller, so they shouldn't be necessary for any external consumers of the render code. Signed-off-by: Adam Wolfe Gordon --- cmd/crossplane/render/render.go | 58 ------- cmd/crossplane/render/render_test.go | 241 --------------------------- 2 files changed, 299 deletions(-) delete mode 100644 cmd/crossplane/render/render_test.go diff --git a/cmd/crossplane/render/render.go b/cmd/crossplane/render/render.go index 2090300..2e8a084 100644 --- a/cmd/crossplane/render/render.go +++ b/cmd/crossplane/render/render.go @@ -30,8 +30,6 @@ import ( "github.com/crossplane/crossplane-runtime/v2/pkg/errors" "github.com/crossplane/crossplane-runtime/v2/pkg/logging" - "github.com/crossplane/crossplane-runtime/v2/pkg/meta" - "github.com/crossplane/crossplane-runtime/v2/pkg/resource" "github.com/crossplane/crossplane-runtime/v2/pkg/resource/unstructured/composed" ucomposite "github.com/crossplane/crossplane-runtime/v2/pkg/resource/unstructured/composite" @@ -42,14 +40,6 @@ import ( renderv1alpha1 "github.com/crossplane/cli/v2/proto/render/v1alpha1" ) -// Annotations added to composed resources. -const ( - AnnotationKeyCompositionResourceName = "crossplane.io/composition-resource-name" - AnnotationKeyCompositeName = "crossplane.io/composite" - AnnotationKeyClaimNamespace = "crossplane.io/claim-namespace" - AnnotationKeyClaimName = "crossplane.io/claim-name" -) - // CompositionInputs contains all inputs to the render process. type CompositionInputs struct { CompositeResource *ucomposite.Unstructured @@ -154,54 +144,6 @@ func RewriteAddressesForDocker(fns []*renderv1alpha1.FunctionInput) []*renderv1a return fns } -// GetSecret retrieves the secret with the specified name and namespace from the provided list of secrets. -func GetSecret(name string, nameSpace string, secrets []corev1.Secret) (*corev1.Secret, error) { - for _, s := range secrets { - if s.GetName() == name && s.GetNamespace() == nameSpace { - return &s, nil - } - } - - return nil, errors.Errorf("secret %q not found", name) -} - -// SetComposedResourceMetadata sets standard, required composed resource -// metadata. It mirrors the behavior of RenderComposedResourceMetadata in -// Crossplane's composition controller. -func SetComposedResourceMetadata(cd resource.Object, xr resource.LegacyComposite, name string) error { - namePrefix := xr.GetLabels()[AnnotationKeyCompositeName] - if namePrefix == "" { - namePrefix = xr.GetName() - } - - if cd.GetName() == "" && cd.GetGenerateName() == "" { - cd.SetGenerateName(namePrefix + "-") - } - - if xr.GetNamespace() != "" { - cd.SetNamespace(xr.GetNamespace()) - } - - meta.AddAnnotations(cd, map[string]string{AnnotationKeyCompositionResourceName: name}) - meta.AddLabels(cd, map[string]string{AnnotationKeyCompositeName: namePrefix}) - - if xr.GetLabels()[AnnotationKeyClaimName] != "" && xr.GetLabels()[AnnotationKeyClaimNamespace] != "" { - meta.AddLabels(cd, map[string]string{ - AnnotationKeyClaimNamespace: xr.GetLabels()[AnnotationKeyClaimNamespace], - AnnotationKeyClaimName: xr.GetLabels()[AnnotationKeyClaimName], - }) - } else if ref := xr.GetClaimReference(); ref != nil { - meta.AddLabels(cd, map[string]string{ - AnnotationKeyClaimNamespace: ref.Namespace, - AnnotationKeyClaimName: ref.Name, - }) - } - - or := meta.AsController(meta.TypedReferenceTo(xr, xr.GetObjectKind().GroupVersionKind())) - - return errors.Wrapf(meta.AddControllerReference(cd, or), "cannot set composite resource %q as controller ref of composed resource", xr.GetName()) -} - // injectNetworkAnnotation sets the Docker network annotation on all functions // so their containers join the specified network. func injectNetworkAnnotation(fns []pkgv1.Function, networkName string) { diff --git a/cmd/crossplane/render/render_test.go b/cmd/crossplane/render/render_test.go deleted file mode 100644 index fd7e47c..0000000 --- a/cmd/crossplane/render/render_test.go +++ /dev/null @@ -1,241 +0,0 @@ -/* -Copyright 2023 The Crossplane Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package render - -import ( - "testing" - - "github.com/google/go-cmp/cmp" - "google.golang.org/protobuf/encoding/protojson" - "google.golang.org/protobuf/types/known/structpb" - corev1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - - "github.com/crossplane/crossplane-runtime/v2/pkg/resource/unstructured/composed" - ucomposite "github.com/crossplane/crossplane-runtime/v2/pkg/resource/unstructured/composite" - "github.com/crossplane/crossplane-runtime/v2/pkg/resource/unstructured/reference" -) - -func TestGetSecret(t *testing.T) { - secrets := []corev1.Secret{ - { - ObjectMeta: metav1.ObjectMeta{ - Name: "secret1", - Namespace: "namespace1", - }, - }, - { - ObjectMeta: metav1.ObjectMeta{ - Name: "secret2", - Namespace: "namespace2", - }, - }, - } - - tests := map[string]struct { - name string - namespace string - secrets []corev1.Secret - wantErr bool - }{ - "SecretFound": { - name: "secret1", - namespace: "namespace1", - secrets: secrets, - wantErr: false, - }, - "SecretNotFound": { - name: "secret3", - namespace: "namespace3", - secrets: secrets, - wantErr: true, - }, - "SecretWrongNamespace": { - name: "secret1", - namespace: "namespace2", - secrets: secrets, - wantErr: true, - }, - } - - for name, tc := range tests { - t.Run(name, func(t *testing.T) { - _, err := GetSecret(tc.name, tc.namespace, tc.secrets) - if (err != nil) != tc.wantErr { - t.Errorf("GetSecret() error = %v, wantErr %v", err, tc.wantErr) - } - }) - } -} - -func TestSetComposedResourceMetadata(t *testing.T) { - type args struct { - cd *composed.Unstructured - xr *ucomposite.Unstructured - name string - } - type want struct { - generateName string - compositeLabel string - claimName string - claimNamespace string - } - - tests := map[string]struct { - reason string - args args - want want - }{ - "RootXRUsesOwnName": { - reason: "A root XR without composite label should use its own name", - args: args{ - cd: composed.New(), - xr: func() *ucomposite.Unstructured { - xr := ucomposite.New(ucomposite.WithSchema(ucomposite.SchemaLegacy)) - xr.SetName("root-xr") - return xr - }(), - name: "resource-a", - }, - want: want{ - generateName: "root-xr-", - compositeLabel: "root-xr", - }, - }, - "NestedXRPropagatesRootLabel": { - reason: "A nested XR with composite label should propagate the root's name", - args: args{ - cd: composed.New(), - xr: func() *ucomposite.Unstructured { - xr := ucomposite.New(ucomposite.WithSchema(ucomposite.SchemaLegacy)) - xr.SetName("root-xr-child") - xr.SetLabels(map[string]string{ - AnnotationKeyCompositeName: "root-xr", - }) - return xr - }(), - name: "resource-a", - }, - want: want{ - generateName: "root-xr-", - compositeLabel: "root-xr", - }, - }, - "NestedXRPropagatesClaimLabels": { - reason: "A nested XR with claim labels should propagate them to composed resources", - args: args{ - cd: composed.New(), - xr: func() *ucomposite.Unstructured { - xr := ucomposite.New(ucomposite.WithSchema(ucomposite.SchemaLegacy)) - xr.SetName("root-xr-child") - xr.SetLabels(map[string]string{ - AnnotationKeyCompositeName: "root-xr", - AnnotationKeyClaimName: "my-claim", - AnnotationKeyClaimNamespace: "claim-ns", - }) - return xr - }(), - name: "resource-a", - }, - want: want{ - generateName: "root-xr-", - compositeLabel: "root-xr", - claimName: "my-claim", - claimNamespace: "claim-ns", - }, - }, - "RootXRWithClaimReference": { - reason: "A root XR with ClaimReference but no claim labels should use ClaimReference for claim labels", - args: args{ - cd: composed.New(), - xr: func() *ucomposite.Unstructured { - xr := ucomposite.New(ucomposite.WithSchema(ucomposite.SchemaLegacy)) - xr.SetName("root-xr") - xr.SetClaimReference(&reference.Claim{ - Name: "my-claim", - Namespace: "claim-ns", - }) - return xr - }(), - name: "resource-a", - }, - want: want{ - generateName: "root-xr-", - compositeLabel: "root-xr", - claimName: "my-claim", - claimNamespace: "claim-ns", - }, - }, - "XRWithClaimLabelsButNoCompositeLabel": { - reason: "An XR with claim labels but no composite label should fall back to XR name and still propagate claim labels", - args: args{ - cd: composed.New(), - xr: func() *ucomposite.Unstructured { - xr := ucomposite.New(ucomposite.WithSchema(ucomposite.SchemaLegacy)) - xr.SetName("root-xr") - xr.SetLabels(map[string]string{ - AnnotationKeyClaimName: "my-claim", - AnnotationKeyClaimNamespace: "claim-ns", - }) - return xr - }(), - name: "resource-a", - }, - want: want{ - generateName: "root-xr-", - compositeLabel: "root-xr", - claimName: "my-claim", - claimNamespace: "claim-ns", - }, - }, - } - - for name, tc := range tests { - t.Run(name, func(t *testing.T) { - err := SetComposedResourceMetadata(tc.args.cd, tc.args.xr, tc.args.name) - if err != nil { - t.Fatalf("SetComposedResourceMetadata() error = %v", err) - } - - if diff := cmp.Diff(tc.want.generateName, tc.args.cd.GetGenerateName()); diff != "" { - t.Errorf("%s\nSetComposedResourceMetadata() generateName: -want, +got:\n%s", tc.reason, diff) - } - if diff := cmp.Diff(tc.want.compositeLabel, tc.args.cd.GetLabels()[AnnotationKeyCompositeName]); diff != "" { - t.Errorf("%s\nSetComposedResourceMetadata() compositeLabel: -want, +got:\n%s", tc.reason, diff) - } - if tc.want.claimName != "" { - if diff := cmp.Diff(tc.want.claimName, tc.args.cd.GetLabels()[AnnotationKeyClaimName]); diff != "" { - t.Errorf("%s\nSetComposedResourceMetadata() claimName: -want, +got:\n%s", tc.reason, diff) - } - } - if tc.want.claimNamespace != "" { - if diff := cmp.Diff(tc.want.claimNamespace, tc.args.cd.GetLabels()[AnnotationKeyClaimNamespace]); diff != "" { - t.Errorf("%s\nSetComposedResourceMetadata() claimNamespace: -want, +got:\n%s", tc.reason, diff) - } - } - }) - } -} - -func MustStructJSON(j string) *structpb.Struct { - s := &structpb.Struct{} - if err := protojson.Unmarshal([]byte(j), s); err != nil { - panic(err) - } - - return s -}