Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions cmd/crossplane/render/xr/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import (
"github.com/spf13/afero"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
kruntime "k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/serializer/json"
"k8s.io/kube-openapi/pkg/spec3"

Expand Down Expand Up @@ -166,6 +167,7 @@ func (c *Cmd) Run(k *kong.Context, log logging.Logger, sp terminal.SpinnerPrinte
return errors.Wrap(err, "cannot apply function annotation overrides")
}

var xrdUnstructured *unstructured.Unstructured
if c.XRD != "" {
xrd, err := render.LoadXRD(c.fs, c.XRD)
if err != nil {
Expand All @@ -175,6 +177,12 @@ func (c *Cmd) Run(k *kong.Context, log logging.Logger, sp terminal.SpinnerPrinte
if err := xrpkg.ApplyXRDDefaults(xr.GetUnstructured(), xrd); err != nil {
return errors.Wrapf(err, "cannot apply XRD defaults to XR %q", xr.GetName())
}

obj, err := kruntime.DefaultUnstructuredConverter.ToUnstructured(xrd)
if err != nil {
return errors.Wrapf(err, "cannot convert XRD %q to unstructured", xrd.GetName())
}
xrdUnstructured = &unstructured.Unstructured{Object: obj}
}

fcreds := []corev1.Secret{}
Expand Down Expand Up @@ -283,6 +291,7 @@ func (c *Cmd) Run(k *kong.Context, log logging.Logger, sp terminal.SpinnerPrinte
RequiredResources: rrs,
RequiredSchemas: rsc,
FunctionCredentials: fcreds,
XRD: xrdUnstructured,
}
req, err := render.BuildCompositeRequest(in)
if err != nil {
Expand Down
46 changes: 46 additions & 0 deletions cmd/crossplane/render/xr/cmd_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,9 @@ var includeFunctionResultsOutput string
//go:embed testdata/cmd/output/include-full-xr.yaml
var includeFullXROutput string

//go:embed testdata/cmd/xrd.yaml
var xrdYAML string

func newEngineFunc(engine render.Engine) func(*render.EngineFlags, logging.Logger) render.Engine {
return func(*render.EngineFlags, logging.Logger) render.Engine {
return engine
Expand Down Expand Up @@ -470,6 +473,49 @@ func TestCmdRun(t *testing.T) {
},
want: want{err: cmpopts.AnyError},
},
"XRDPassedToEngine": {
reason: "When --xrd is set, the XRD should be forwarded to the render engine so it can determine the composite schema (Legacy vs Modern).",
args: args{
cmd: Cmd{
CompositeResource: "xr.yaml",
Composition: "composition.yaml",
Functions: "functions.yaml",
XRD: "xrd.yaml",
Timeout: time.Minute,
fs: newTestFS(map[string]string{"xrd.yaml": xrdYAML}),
newEngine: newEngineFunc(&render.MockEngine{
MockRender: func(_ context.Context, req *renderv1alpha1.RenderRequest) (*renderv1alpha1.RenderResponse, error) {
if req.GetComposite().GetCompositeResourceDefinition() == nil {
t.Error("expected render request to contain the XRD, got nil")
}
return &renderv1alpha1.RenderResponse{
Output: &renderv1alpha1.RenderResponse_Composite{
Composite: &renderv1alpha1.CompositeOutput{
CompositeResource: fillResourceRefs(t, req.GetComposite().GetCompositeResource()),
ComposedResources: []*structpb.Struct{
mustNewStruct(t, map[string]any{
"apiVersion": "example.org/v1alpha1",
"kind": "ComposedResource",
"metadata": map[string]any{
"name": "composed-foo",
"annotations": map[string]any{
"crossplane.io/composition-resource-name": "composed-foo",
},
},
"spec": map[string]any{"coolField": "composed!"},
}),
},
},
},
}, nil
},
}),
},
},
want: want{
stdout: successOutput,
},
},
"IncludeFullXR": {
reason: "With --include-full-xr, the rendered XR is merged into the input XR so the input's spec.fromXR survives alongside any updated fields.",
args: args{
Expand Down
22 changes: 22 additions & 0 deletions cmd/crossplane/render/xr/testdata/cmd/xrd.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
apiVersion: apiextensions.crossplane.io/v1
kind: CompositeResourceDefinition
metadata:
name: xnopresources.nop.example.org
spec:
group: nop.example.org
names:
kind: XNopResource
plural: xnopresources
versions:
- name: v1alpha1
served: true
referenceable: true
schema:
openAPIV3Schema:
type: object
properties:
spec:
type: object
properties:
coolField:
type: string