Merge pull request #849 from negz/x-treme

Backport c/c internal/xresource
This commit is contained in:
Nic Cope 2025-06-20 11:57:48 -07:00 committed by GitHub
commit 0d81d3f7c2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 212 additions and 131 deletions

View File

@ -234,7 +234,7 @@ type ProviderConfigUsageList interface {
GetItems() []ProviderConfigUsage
}
// A Composite resource composes one or more Composed resources.
// A Composite resource (or XR) is composed of other resources.
type Composite interface { //nolint:interfacebloat // This interface has to be big.
Object
@ -244,27 +244,29 @@ type Composite interface { //nolint:interfacebloat // This interface has to be b
CompositionRevisionReferencer
CompositionRevisionSelector
ComposedResourcesReferencer
EnvironmentConfigReferencer
ClaimReferencer
ConnectionSecretWriterTo
ConnectionDetailsPublisherTo
Conditioned
ConnectionDetailsPublishedTimer
ReconciliationObserver
}
// A LegacyComposite is a Crossplane v1 style legacy XR.
type LegacyComposite interface {
Composite
ClaimReferencer
ConnectionSecretWriterTo
ConnectionDetailsPublishedTimer
}
// Composed resources can be a composed into a Composite resource.
type Composed interface {
Object
Conditioned
ConnectionSecretWriterTo
ConnectionDetailsPublisherTo
ReconciliationObserver
}
// A CompositeClaim for a Composite resource.
// A CompositeClaim of a composite resource (XR).
type CompositeClaim interface { //nolint:interfacebloat // This interface has to be big.
Object
@ -276,9 +278,11 @@ type CompositeClaim interface { //nolint:interfacebloat // This interface has to
CompositeResourceDeleter
CompositeResourceReferencer
LocalConnectionSecretWriterTo
ConnectionDetailsPublisherTo
Conditioned
ConnectionDetailsPublishedTimer
ReconciliationObserver
}
// A Claim of a composite resource (XR).
type Claim = CompositeClaim

View File

@ -193,20 +193,6 @@ func (c *Unstructured) SetWriteConnectionSecretToReference(ref *xpv1.LocalSecret
_ = fieldpath.Pave(c.Object).SetValue("spec.writeConnectionSecretToRef", ref)
}
// GetPublishConnectionDetailsTo of this composite resource claim.
func (c *Unstructured) GetPublishConnectionDetailsTo() *xpv1.PublishConnectionDetailsTo {
out := &xpv1.PublishConnectionDetailsTo{}
if err := fieldpath.Pave(c.Object).GetValueInto("spec.publishConnectionDetailsTo", out); err != nil {
return nil
}
return out
}
// SetPublishConnectionDetailsTo of this composite resource claim.
func (c *Unstructured) SetPublishConnectionDetailsTo(ref *xpv1.PublishConnectionDetailsTo) {
_ = fieldpath.Pave(c.Object).SetValue("spec.publishConnectionDetailsTo", ref)
}
// GetCondition of this composite resource claim.
func (c *Unstructured) GetCondition(ct xpv1.ConditionType) xpv1.Condition {
conditioned := xpv1.ConditionedStatus{}

View File

@ -103,20 +103,6 @@ func (cr *Unstructured) SetWriteConnectionSecretToReference(r *xpv1.SecretRefere
_ = fieldpath.Pave(cr.Object).SetValue("spec.writeConnectionSecretToRef", r)
}
// GetPublishConnectionDetailsTo of this Composed resource.
func (cr *Unstructured) GetPublishConnectionDetailsTo() *xpv1.PublishConnectionDetailsTo {
out := &xpv1.PublishConnectionDetailsTo{}
if err := fieldpath.Pave(cr.Object).GetValueInto("spec.publishConnectionDetailsTo", out); err != nil {
return nil
}
return out
}
// SetPublishConnectionDetailsTo of this Composed resource.
func (cr *Unstructured) SetPublishConnectionDetailsTo(ref *xpv1.PublishConnectionDetailsTo) {
_ = fieldpath.Pave(cr.Object).SetValue("spec.publishConnectionDetailsTo", ref)
}
// OwnedBy returns true if the supplied UID is an owner of the composed.
func (cr *Unstructured) OwnedBy(u types.UID) bool {
for _, owner := range cr.GetOwnerReferences() {

View File

@ -22,6 +22,7 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/utils/ptr"
xpv1 "github.com/crossplane/crossplane-runtime/apis/common/v1"
"github.com/crossplane/crossplane-runtime/pkg/errors"
@ -29,28 +30,49 @@ import (
"github.com/crossplane/crossplane-runtime/pkg/resource/unstructured/reference"
)
// Schema specifies the schema version of a composite resource's Crossplane
// machinery fields.
type Schema int
const (
// SchemaModern indicates a modern Namespaced or Cluster scope composite
// resource. Modern composite resources nest all Crossplane machinery fields
// under spec.crossplane and status.crossplane, and can't be claimed.
SchemaModern Schema = iota
// SchemaLegacy indicates a LegacyCluster scope composite resource. Legacy
// composite resources don't nest Crossplane machinery fields - they're set
// directly under spec and status. Legacy composite resources can be claimed.
SchemaLegacy
)
// An Option modifies an unstructured composite resource.
type Option func(*Unstructured)
// WithGroupVersionKind sets the GroupVersionKind of the unstructured composite
// resource.
// WithGroupVersionKind sets the GroupVersionKind of the composite resource.
func WithGroupVersionKind(gvk schema.GroupVersionKind) Option {
return func(c *Unstructured) {
c.SetGroupVersionKind(gvk)
}
}
// WithConditions returns an Option that sets the supplied conditions on an
// unstructured composite resource.
// WithConditions sets the supplied conditions on the composite resource.
func WithConditions(c ...xpv1.Condition) Option {
return func(cr *Unstructured) {
cr.SetConditions(c...)
}
}
// New returns a new unstructured composed resource.
// WithSchema sets the schema of the composite resource.
func WithSchema(s Schema) Option {
return func(c *Unstructured) {
c.Schema = s
}
}
// New returns a new unstructured composite resource.
func New(opts ...Option) *Unstructured {
c := &Unstructured{unstructured.Unstructured{Object: make(map[string]any)}}
c := &Unstructured{Unstructured: unstructured.Unstructured{Object: make(map[string]any)}}
for _, f := range opts {
f(c)
}
@ -60,9 +82,11 @@ func New(opts ...Option) *Unstructured {
// +k8s:deepcopy-gen=true
// +kubebuilder:object:root=true
// An Unstructured composed resource.
// An Unstructured composite resource.
type Unstructured struct {
unstructured.Unstructured
Schema Schema
}
// GetUnstructured returns the underlying *unstructured.Unstructured.
@ -70,52 +94,87 @@ func (c *Unstructured) GetUnstructured() *unstructured.Unstructured {
return &c.Unstructured
}
// GetCompositionSelector of this Composite resource.
// GetCompositionSelector of this composite resource.
func (c *Unstructured) GetCompositionSelector() *metav1.LabelSelector {
path := "spec.crossplane.compositionSelector"
if c.Schema == SchemaLegacy {
path = "spec.compositionSelector"
}
out := &metav1.LabelSelector{}
if err := fieldpath.Pave(c.Object).GetValueInto("spec.compositionSelector", out); err != nil {
if err := fieldpath.Pave(c.Object).GetValueInto(path, out); err != nil {
return nil
}
return out
}
// SetCompositionSelector of this Composite resource.
// SetCompositionSelector of this composite resource.
func (c *Unstructured) SetCompositionSelector(sel *metav1.LabelSelector) {
_ = fieldpath.Pave(c.Object).SetValue("spec.compositionSelector", sel)
path := "spec.crossplane.compositionSelector"
if c.Schema == SchemaLegacy {
path = "spec.compositionSelector"
}
_ = fieldpath.Pave(c.Object).SetValue(path, sel)
}
// GetCompositionReference of this Composite resource.
// GetCompositionReference of this composite resource.
func (c *Unstructured) GetCompositionReference() *corev1.ObjectReference {
path := "spec.crossplane.compositionRef"
if c.Schema == SchemaLegacy {
path = "spec.compositionRef"
}
out := &corev1.ObjectReference{}
if err := fieldpath.Pave(c.Object).GetValueInto("spec.compositionRef", out); err != nil {
if err := fieldpath.Pave(c.Object).GetValueInto(path, out); err != nil {
return nil
}
return out
}
// SetCompositionReference of this Composite resource.
// SetCompositionReference of this composite resource.
func (c *Unstructured) SetCompositionReference(ref *corev1.ObjectReference) {
_ = fieldpath.Pave(c.Object).SetValue("spec.compositionRef", ref)
path := "spec.crossplane.compositionRef"
if c.Schema == SchemaLegacy {
path = "spec.compositionRef"
}
_ = fieldpath.Pave(c.Object).SetValue(path, ref)
}
// GetCompositionRevisionReference of this Composite resource.
// GetCompositionRevisionReference of this composite resource.
func (c *Unstructured) GetCompositionRevisionReference() *corev1.LocalObjectReference {
path := "spec.crossplane.compositionRevisionRef"
if c.Schema == SchemaLegacy {
path = "spec.compositionRevisionRef"
}
out := &corev1.LocalObjectReference{}
if err := fieldpath.Pave(c.Object).GetValueInto("spec.compositionRevisionRef", out); err != nil {
if err := fieldpath.Pave(c.Object).GetValueInto(path, out); err != nil {
return nil
}
return out
}
// SetCompositionRevisionReference of this Composite resource.
// SetCompositionRevisionReference of this composite resource.
func (c *Unstructured) SetCompositionRevisionReference(ref *corev1.LocalObjectReference) {
_ = fieldpath.Pave(c.Object).SetValue("spec.compositionRevisionRef", ref)
path := "spec.crossplane.compositionRevisionRef"
if c.Schema == SchemaLegacy {
path = "spec.compositionRevisionRef"
}
_ = fieldpath.Pave(c.Object).SetValue(path, ref)
}
// GetCompositionRevisionSelector of this resource claim.
func (c *Unstructured) GetCompositionRevisionSelector() *metav1.LabelSelector {
path := "spec.crossplane.compositionRevisionSelector"
if c.Schema == SchemaLegacy {
path = "spec.compositionRevisionSelector"
}
out := &metav1.LabelSelector{}
if err := fieldpath.Pave(c.Object).GetValueInto("spec.compositionRevisionSelector", out); err != nil {
if err := fieldpath.Pave(c.Object).GetValueInto(path, out); err != nil {
return nil
}
return out
@ -123,17 +182,32 @@ func (c *Unstructured) GetCompositionRevisionSelector() *metav1.LabelSelector {
// SetCompositionRevisionSelector of this resource claim.
func (c *Unstructured) SetCompositionRevisionSelector(sel *metav1.LabelSelector) {
_ = fieldpath.Pave(c.Object).SetValue("spec.compositionRevisionSelector", sel)
path := "spec.crossplane.compositionRevisionSelector"
if c.Schema == SchemaLegacy {
path = "spec.compositionRevisionSelector"
}
_ = fieldpath.Pave(c.Object).SetValue(path, sel)
}
// SetCompositionUpdatePolicy of this Composite resource.
// SetCompositionUpdatePolicy of this composite resource.
func (c *Unstructured) SetCompositionUpdatePolicy(p *xpv1.UpdatePolicy) {
_ = fieldpath.Pave(c.Object).SetValue("spec.compositionUpdatePolicy", p)
path := "spec.crossplane.compositionUpdatePolicy"
if c.Schema == SchemaLegacy {
path = "spec.compositionUpdatePolicy"
}
_ = fieldpath.Pave(c.Object).SetValue(path, p)
}
// GetCompositionUpdatePolicy of this Composite resource.
// GetCompositionUpdatePolicy of this composite resource.
func (c *Unstructured) GetCompositionUpdatePolicy() *xpv1.UpdatePolicy {
p, err := fieldpath.Pave(c.Object).GetString("spec.compositionUpdatePolicy")
path := "spec.crossplane.compositionUpdatePolicy"
if c.Schema == SchemaLegacy {
path = "spec.compositionUpdatePolicy"
}
p, err := fieldpath.Pave(c.Object).GetString(path)
if err != nil {
return nil
}
@ -141,8 +215,13 @@ func (c *Unstructured) GetCompositionUpdatePolicy() *xpv1.UpdatePolicy {
return &out
}
// GetClaimReference of this Composite resource.
// GetClaimReference of this composite resource.
func (c *Unstructured) GetClaimReference() *reference.Claim {
// Only legacy XRs support claims.
if c.Schema != SchemaLegacy {
return nil
}
out := &reference.Claim{}
if err := fieldpath.Pave(c.Object).GetValueInto("spec.claimRef", out); err != nil {
return nil
@ -150,20 +229,35 @@ func (c *Unstructured) GetClaimReference() *reference.Claim {
return out
}
// SetClaimReference of this Composite resource.
// SetClaimReference of this composite resource.
func (c *Unstructured) SetClaimReference(ref *reference.Claim) {
// Only legacy XRs support claims.
if c.Schema != SchemaLegacy {
return
}
_ = fieldpath.Pave(c.Object).SetValue("spec.claimRef", ref)
}
// GetResourceReferences of this Composite resource.
// GetResourceReferences of this composite resource.
func (c *Unstructured) GetResourceReferences() []corev1.ObjectReference {
path := "spec.crossplane.resourceRefs"
if c.Schema == SchemaLegacy {
path = "spec.resourceRefs"
}
out := &[]corev1.ObjectReference{}
_ = fieldpath.Pave(c.Object).GetValueInto("spec.resourceRefs", out)
_ = fieldpath.Pave(c.Object).GetValueInto(path, out)
return *out
}
// SetResourceReferences of this Composite resource.
// SetResourceReferences of this composite resource.
func (c *Unstructured) SetResourceReferences(refs []corev1.ObjectReference) {
path := "spec.crossplane.resourceRefs"
if c.Schema == SchemaLegacy {
path = "spec.resourceRefs"
}
empty := corev1.ObjectReference{}
filtered := make([]corev1.ObjectReference, 0, len(refs))
for _, ref := range refs {
@ -174,20 +268,35 @@ func (c *Unstructured) SetResourceReferences(refs []corev1.ObjectReference) {
}
filtered = append(filtered, ref)
}
_ = fieldpath.Pave(c.Object).SetValue("spec.resourceRefs", filtered)
_ = fieldpath.Pave(c.Object).SetValue(path, filtered)
}
// GetReference returns reference to this composite.
func (c *Unstructured) GetReference() *reference.Composite {
return &reference.Composite{
ref := &reference.Composite{
APIVersion: c.GetAPIVersion(),
Kind: c.GetKind(),
Name: c.GetName(),
}
if c.GetNamespace() != "" {
ref.Namespace = ptr.To(c.GetNamespace())
}
return ref
}
// GetWriteConnectionSecretToReference of this Composite resource.
// TODO(negz): Ideally we'd use LocalSecretReference for namespaced XRs. As is
// we'll return a SecretReference with an empty namespace if the XR doesn't
// actually have a spec.crossplane.writeConnectionSecretToRef.namespace field.
// GetWriteConnectionSecretToReference of this composite resource.
func (c *Unstructured) GetWriteConnectionSecretToReference() *xpv1.SecretReference {
// Only legacy XRs support connection secrets.
if c.Schema != SchemaLegacy {
return nil
}
out := &xpv1.SecretReference{}
if err := fieldpath.Pave(c.Object).GetValueInto("spec.writeConnectionSecretToRef", out); err != nil {
return nil
@ -195,26 +304,17 @@ func (c *Unstructured) GetWriteConnectionSecretToReference() *xpv1.SecretReferen
return out
}
// SetWriteConnectionSecretToReference of this Composite resource.
// SetWriteConnectionSecretToReference of this composite resource.
func (c *Unstructured) SetWriteConnectionSecretToReference(ref *xpv1.SecretReference) {
// Only legacy XRs support connection secrets.
if c.Schema != SchemaLegacy {
return
}
_ = fieldpath.Pave(c.Object).SetValue("spec.writeConnectionSecretToRef", ref)
}
// GetPublishConnectionDetailsTo of this Composite resource.
func (c *Unstructured) GetPublishConnectionDetailsTo() *xpv1.PublishConnectionDetailsTo {
out := &xpv1.PublishConnectionDetailsTo{}
if err := fieldpath.Pave(c.Object).GetValueInto("spec.publishConnectionDetailsTo", out); err != nil {
return nil
}
return out
}
// SetPublishConnectionDetailsTo of this Composite resource.
func (c *Unstructured) SetPublishConnectionDetailsTo(ref *xpv1.PublishConnectionDetailsTo) {
_ = fieldpath.Pave(c.Object).SetValue("spec.publishConnectionDetailsTo", ref)
}
// GetCondition of this Composite resource.
// GetCondition of this composite resource.
func (c *Unstructured) GetCondition(ct xpv1.ConditionType) xpv1.Condition {
conditioned := xpv1.ConditionedStatus{}
// The path is directly `status` because conditions are inline.
@ -224,7 +324,7 @@ func (c *Unstructured) GetCondition(ct xpv1.ConditionType) xpv1.Condition {
return conditioned.GetCondition(ct)
}
// SetConditions of this Composite resource.
// SetConditions of this composite resource.
func (c *Unstructured) SetConditions(conditions ...xpv1.Condition) {
conditioned := xpv1.ConditionedStatus{}
// The path is directly `status` because conditions are inline.
@ -233,7 +333,7 @@ func (c *Unstructured) SetConditions(conditions ...xpv1.Condition) {
_ = fieldpath.Pave(c.Object).SetValue("status.conditions", conditioned.Conditions)
}
// GetConditions of this Composite resource.
// GetConditions of this composite resource.
func (c *Unstructured) GetConditions() []xpv1.Condition {
conditioned := xpv1.ConditionedStatus{}
// The path is directly `status` because conditions are inline.
@ -241,40 +341,28 @@ func (c *Unstructured) GetConditions() []xpv1.Condition {
return conditioned.Conditions
}
// GetConnectionDetailsLastPublishedTime of this Composite resource.
// GetConnectionDetailsLastPublishedTime of this composite resource.
func (c *Unstructured) GetConnectionDetailsLastPublishedTime() *metav1.Time {
path := "status.crossplane.connectionDetails.lastPublishedTime"
if c.Schema == SchemaLegacy {
path = "status.connectionDetails.lastPublishedTime"
}
out := &metav1.Time{}
if err := fieldpath.Pave(c.Object).GetValueInto("status.connectionDetails.lastPublishedTime", out); err != nil {
if err := fieldpath.Pave(c.Object).GetValueInto(path, out); err != nil {
return nil
}
return out
}
// SetConnectionDetailsLastPublishedTime of this Composite resource.
// SetConnectionDetailsLastPublishedTime of this composite resource.
func (c *Unstructured) SetConnectionDetailsLastPublishedTime(t *metav1.Time) {
_ = fieldpath.Pave(c.Object).SetValue("status.connectionDetails.lastPublishedTime", t)
}
// GetEnvironmentConfigReferences of this Composite resource.
func (c *Unstructured) GetEnvironmentConfigReferences() []corev1.ObjectReference {
out := &[]corev1.ObjectReference{}
_ = fieldpath.Pave(c.Object).GetValueInto("spec.environmentConfigRefs", out)
return *out
}
// SetEnvironmentConfigReferences of this Composite resource.
func (c *Unstructured) SetEnvironmentConfigReferences(refs []corev1.ObjectReference) {
empty := corev1.ObjectReference{}
filtered := make([]corev1.ObjectReference, 0, len(refs))
for _, ref := range refs {
// TODO(negz): Ask muvaf to explain what this is working around. :)
// TODO(muvaf): temporary workaround.
if ref.String() == empty.String() {
continue
}
filtered = append(filtered, ref)
path := "status.crossplane.connectionDetails.lastPublishedTime"
if c.Schema == SchemaLegacy {
path = "status.connectionDetails.lastPublishedTime"
}
_ = fieldpath.Pave(c.Object).SetValue("spec.environmentConfigRefs", filtered)
_ = fieldpath.Pave(c.Object).SetValue(path, t)
}
// SetObservedGeneration of this composite resource claim.
@ -292,9 +380,13 @@ func (c *Unstructured) GetObservedGeneration() int64 {
return status.GetObservedGeneration()
}
// SetClaimConditionTypes of this Composite resource. You cannot set system
// SetClaimConditionTypes of this composite resource. You cannot set system
// condition types such as Ready, Synced or Healthy as claim conditions.
func (c *Unstructured) SetClaimConditionTypes(in ...xpv1.ConditionType) error {
// Only legacy XRs support claims.
if c.Schema != SchemaLegacy {
return nil
}
ts := c.GetClaimConditionTypes()
m := make(map[xpv1.ConditionType]bool, len(ts))
for _, t := range ts {
@ -315,8 +407,12 @@ func (c *Unstructured) SetClaimConditionTypes(in ...xpv1.ConditionType) error {
return nil
}
// GetClaimConditionTypes of this Composite resource.
// GetClaimConditionTypes of this composite resource.
func (c *Unstructured) GetClaimConditionTypes() []xpv1.ConditionType {
// Only legacy XRs support claims.
if c.Schema != SchemaLegacy {
return nil
}
cs := []xpv1.ConditionType{}
_ = fieldpath.Pave(c.Object).GetValueInto("status.claimConditionTypes", &cs)
return cs

View File

@ -96,7 +96,7 @@ func TestConditions(t *testing.T) {
},
"WeirdStatus": {
reason: "It should not be possible to set a condition when status is not an object.",
u: &Unstructured{unstructured.Unstructured{Object: map[string]any{
u: &Unstructured{Unstructured: unstructured.Unstructured{Object: map[string]any{
"status": "wat",
}}},
set: []xpv1.Condition{xpv1.Available()},
@ -106,7 +106,7 @@ func TestConditions(t *testing.T) {
},
"WeirdStatusConditions": {
reason: "Conditions should be overwritten if they are not an object.",
u: &Unstructured{unstructured.Unstructured{Object: map[string]any{
u: &Unstructured{Unstructured: unstructured.Unstructured{Object: map[string]any{
"status": map[string]any{
"conditions": "wat",
},
@ -145,7 +145,7 @@ func TestClaimConditionTypes(t *testing.T) {
}{
"CannotSetSystemConditionTypes": {
reason: "Claim conditions API should fail to set conditions if a system condition is detected.",
u: New(),
u: New(WithSchema(SchemaLegacy)),
set: []xpv1.ConditionType{
xpv1.ConditionType("DatabaseReady"),
xpv1.ConditionType("NetworkReady"),
@ -157,37 +157,43 @@ func TestClaimConditionTypes(t *testing.T) {
},
"SetSingleCustomConditionType": {
reason: "Claim condition API should work with a single custom condition type.",
u: New(),
u: New(WithSchema(SchemaLegacy)),
set: []xpv1.ConditionType{xpv1.ConditionType("DatabaseReady")},
want: []xpv1.ConditionType{xpv1.ConditionType("DatabaseReady")},
},
"SetMultipleCustomConditionTypes": {
reason: "Claim condition API should work with multiple custom condition types.",
u: New(),
u: New(WithSchema(SchemaLegacy)),
set: []xpv1.ConditionType{xpv1.ConditionType("DatabaseReady"), xpv1.ConditionType("NetworkReady")},
want: []xpv1.ConditionType{xpv1.ConditionType("DatabaseReady"), xpv1.ConditionType("NetworkReady")},
},
"SetMultipleOfTheSameCustomConditionTypes": {
reason: "Claim condition API not add more than one of the same condition.",
u: New(),
u: New(WithSchema(SchemaLegacy)),
set: []xpv1.ConditionType{xpv1.ConditionType("DatabaseReady"), xpv1.ConditionType("DatabaseReady")},
want: []xpv1.ConditionType{xpv1.ConditionType("DatabaseReady")},
},
"WeirdStatus": {
reason: "It should not be possible to set a condition when status is not an object.",
u: &Unstructured{unstructured.Unstructured{Object: map[string]any{
"status": "wat",
}}},
u: &Unstructured{
Unstructured: unstructured.Unstructured{Object: map[string]any{
"status": "wat",
}},
Schema: SchemaLegacy,
},
set: []xpv1.ConditionType{xpv1.ConditionType("DatabaseReady")},
want: []xpv1.ConditionType{},
},
"WeirdStatusClaimConditionTypes": {
reason: "Claim conditions should be overwritten if they are not an object.",
u: &Unstructured{unstructured.Unstructured{Object: map[string]any{
"status": map[string]any{
"claimConditionTypes": "wat",
},
}}},
u: &Unstructured{
Unstructured: unstructured.Unstructured{Object: map[string]any{
"status": map[string]any{
"claimConditionTypes": "wat",
},
}},
Schema: SchemaLegacy,
},
set: []xpv1.ConditionType{xpv1.ConditionType("DatabaseReady")},
want: []xpv1.ConditionType{xpv1.ConditionType("DatabaseReady")},
},
@ -341,7 +347,7 @@ func TestClaimReference(t *testing.T) {
want *reference.Claim
}{
"NewRef": {
u: New(),
u: New(WithSchema(SchemaLegacy)),
set: ref,
want: ref,
},
@ -391,7 +397,7 @@ func TestWriteConnectionSecretToReference(t *testing.T) {
want *xpv1.SecretReference
}{
"NewRef": {
u: New(),
u: New(WithSchema(SchemaLegacy)),
set: ref,
want: ref,
},

View File

@ -46,6 +46,9 @@ type Composite struct {
// Name of the referenced composite.
Name string `json:"name"`
// Namespace of the referenced composite.
Namespace *string `json:"namespace,omitempty"`
}
// GroupVersionKind returns the GroupVersionKind of the claim reference.