diff --git a/pkg/meta/meta.go b/pkg/meta/meta.go index de183a6b9..d77fa6c8d 100644 --- a/pkg/meta/meta.go +++ b/pkg/meta/meta.go @@ -41,6 +41,7 @@ const AnnotationKeyExternalName = "crossplane.io/external-name" const ( AnnotationKeyPropagateToPrefix = "to.propagate.crossplane.io/" + // Deprecated: This functionality will be removed soon. AnnotationKeyPropagateFromNamespace = "from.propagate.crossplane.io/namespace" AnnotationKeyPropagateFromName = "from.propagate.crossplane.io/name" ) @@ -246,6 +247,7 @@ func SetExternalName(o metav1.Object, name string) { // AllowPropagation from one object to another by adding consenting annotations // to both. +// Deprecated: This functionality will be removed soon. func AllowPropagation(from, to metav1.Object) { AddAnnotations(to, map[string]string{ AnnotationKeyPropagateFromNamespace: from.GetNamespace(), diff --git a/pkg/resource/api.go b/pkg/resource/api.go index 102731a45..b5a5309d6 100644 --- a/pkg/resource/api.go +++ b/pkg/resource/api.go @@ -43,6 +43,7 @@ const ( // An APIManagedConnectionPropagator propagates connection details by reading // them from and writing them to a Kubernetes API server. +// Deprecated: This functionality will be removed soon. type APIManagedConnectionPropagator struct { Propagator ConnectionPropagator } @@ -54,12 +55,14 @@ func (a *APIManagedConnectionPropagator) PropagateConnection(ctx context.Context // An APIConnectionPropagator propagates connection details by reading // them from and writing them to a Kubernetes API server. +// Deprecated: This functionality will be removed soon. type APIConnectionPropagator struct { client ClientApplicator typer runtime.ObjectTyper } // NewAPIConnectionPropagator returns a new APIConnectionPropagator. +// Deprecated: This functionality will be removed soon. func NewAPIConnectionPropagator(c client.Client, t runtime.ObjectTyper) *APIConnectionPropagator { return &APIConnectionPropagator{ client: ClientApplicator{Client: c, Applicator: NewAPIUpdatingApplicator(c)}, diff --git a/pkg/resource/fake/mocks.go b/pkg/resource/fake/mocks.go index e853fb007..da84cb904 100644 --- a/pkg/resource/fake/mocks.go +++ b/pkg/resource/fake/mocks.go @@ -181,6 +181,20 @@ func (m *ComposedResourcesReferencer) SetResourceReferences(r []corev1.ObjectRef // GetResourceReferences gets the composed references. func (m *ComposedResourcesReferencer) GetResourceReferences() []corev1.ObjectReference { return m.Refs } +// ConnectionDetailsLastPublishedTimer is a mock that implements the +// ConnectionDetailsLastPublishedTimer interface. +type ConnectionDetailsLastPublishedTimer struct{ Time *metav1.Time } + +// SetConnectionDetailsLastPublishedTime sets the published time. +func (c *ConnectionDetailsLastPublishedTimer) SetConnectionDetailsLastPublishedTime(t *metav1.Time) { + c.Time = t +} + +// GetConnectionDetailsLastPublishedTime gets the published time. +func (c *ConnectionDetailsLastPublishedTimer) GetConnectionDetailsLastPublishedTime() *metav1.Time { + return c.Time +} + // UserCounter is a mock that satisfies UserCounter // interface. type UserCounter struct{ Users int64 } @@ -251,7 +265,9 @@ type Composite struct { ComposedResourcesReferencer ClaimReferencer ConnectionSecretWriterTo + v1alpha1.ConditionedStatus + ConnectionDetailsLastPublishedTimer } // GetObjectKind returns schema.ObjectKind. @@ -300,7 +316,9 @@ type CompositeClaim struct { CompositionReferencer CompositeResourceReferencer LocalConnectionSecretWriterTo + v1alpha1.ConditionedStatus + ConnectionDetailsLastPublishedTimer } // GetObjectKind returns schema.ObjectKind. diff --git a/pkg/resource/interfaces.go b/pkg/resource/interfaces.go index 71846ad54..169d33d93 100644 --- a/pkg/resource/interfaces.go +++ b/pkg/resource/interfaces.go @@ -126,6 +126,13 @@ type UserCounter interface { GetUsers() int64 } +// A ConnectionDetailsPublishedTimer can record the last time its connection +// details were published. +type ConnectionDetailsPublishedTimer interface { + SetConnectionDetailsLastPublishedTime(t *metav1.Time) + GetConnectionDetailsLastPublishedTime() *metav1.Time +} + // An Object is a Kubernetes object. type Object interface { metav1.Object @@ -188,6 +195,7 @@ type Composite interface { ConnectionSecretWriterTo Conditioned + ConnectionDetailsPublishedTimer } // Composed resources can be a composed into a Composite resource. @@ -208,4 +216,5 @@ type CompositeClaim interface { LocalConnectionSecretWriterTo Conditioned + ConnectionDetailsPublishedTimer } diff --git a/pkg/resource/resource.go b/pkg/resource/resource.go index 5c9e86821..0fdfdbf4e 100644 --- a/pkg/resource/resource.go +++ b/pkg/resource/resource.go @@ -72,6 +72,7 @@ type LocalConnectionSecretOwner interface { // A ConnectionPropagator is responsible for propagating information required to // connect to a resource. +// Deprecated: This functionality will be removed soon. type ConnectionPropagator interface { PropagateConnection(ctx context.Context, to LocalConnectionSecretOwner, from ConnectionSecretOwner) error } @@ -83,6 +84,7 @@ type ConnectionPropagatorFn func(ctx context.Context, to LocalConnectionSecretOw // A ManagedConnectionPropagator is responsible for propagating information // required to connect to a managed resource (for example the connection secret) // from the managed resource to a target. +// Deprecated: This functionality will be removed soon. type ManagedConnectionPropagator interface { PropagateConnection(ctx context.Context, o LocalConnectionSecretOwner, mg Managed) error } diff --git a/pkg/resource/unstructured/claim/claim.go b/pkg/resource/unstructured/claim/claim.go index 80fa74078..8fc8df983 100644 --- a/pkg/resource/unstructured/claim/claim.go +++ b/pkg/resource/unstructured/claim/claim.go @@ -139,3 +139,17 @@ func (c *Unstructured) SetConditions(conditions ...v1alpha1.Condition) { conditioned.SetConditions(conditions...) _ = fieldpath.Pave(c.Object).SetValue("status.conditions", conditioned.Conditions) } + +// GetConnectionDetailsLastPublishedTime of this composite resource claim. +func (c *Unstructured) GetConnectionDetailsLastPublishedTime() *metav1.Time { + out := &metav1.Time{} + if err := fieldpath.Pave(c.Object).GetValueInto("status.connectionDetails.lastPublishedTime", out); err != nil { + return nil + } + return out +} + +// SetConnectionDetailsLastPublishedTime of this composite resource claim. +func (c *Unstructured) SetConnectionDetailsLastPublishedTime(t *metav1.Time) { + _ = fieldpath.Pave(c.Object).SetValue("status.connectionDetails.lastPublishedTime", t) +} diff --git a/pkg/resource/unstructured/claim/claim_test.go b/pkg/resource/unstructured/claim/claim_test.go index d80138102..2db0a56fc 100644 --- a/pkg/resource/unstructured/claim/claim_test.go +++ b/pkg/resource/unstructured/claim/claim_test.go @@ -17,7 +17,9 @@ limitations under the License. package claim import ( + "encoding/json" "testing" + "time" "github.com/google/go-cmp/cmp" corev1 "k8s.io/api/core/v1" @@ -213,3 +215,38 @@ func TestWriteConnectionSecretToReference(t *testing.T) { }) } } + +func TestConnectionDetailsLastPublishedTime(t *testing.T) { + now := &metav1.Time{Time: time.Now()} + + // The timestamp loses a little resolution when round-tripped through JSON + // encoding. + lores := func(t *metav1.Time) *metav1.Time { + out := &metav1.Time{} + j, _ := json.Marshal(t) + _ = json.Unmarshal(j, out) + return out + } + + cases := map[string]struct { + u *Unstructured + set *metav1.Time + want *metav1.Time + }{ + "NewTime": { + u: New(), + set: now, + want: lores(now), + }, + } + + for name, tc := range cases { + t.Run(name, func(t *testing.T) { + tc.u.SetConnectionDetailsLastPublishedTime(tc.set) + got := tc.u.GetConnectionDetailsLastPublishedTime() + if diff := cmp.Diff(tc.want, got); diff != "" { + t.Errorf("\nu.GetConnectionDetailsLastPublishedTime(): -want, +got:\n%s", diff) + } + }) + } +} diff --git a/pkg/resource/unstructured/composite/composite.go b/pkg/resource/unstructured/composite/composite.go index 3172fd6b7..bb1b0e0a1 100644 --- a/pkg/resource/unstructured/composite/composite.go +++ b/pkg/resource/unstructured/composite/composite.go @@ -161,3 +161,17 @@ func (c *Unstructured) SetConditions(conditions ...v1alpha1.Condition) { conditioned.SetConditions(conditions...) _ = fieldpath.Pave(c.Object).SetValue("status.conditions", conditioned.Conditions) } + +// GetConnectionDetailsLastPublishedTime of this Composite resource. +func (c *Unstructured) GetConnectionDetailsLastPublishedTime() *metav1.Time { + out := &metav1.Time{} + if err := fieldpath.Pave(c.Object).GetValueInto("status.connectionDetails.lastPublishedTime", out); err != nil { + return nil + } + return out +} + +// SetConnectionDetailsLastPublishedTime of this Composite resource. +func (c *Unstructured) SetConnectionDetailsLastPublishedTime(t *metav1.Time) { + _ = fieldpath.Pave(c.Object).SetValue("status.connectionDetails.lastPublishedTime", t) +} diff --git a/pkg/resource/unstructured/composite/composite_test.go b/pkg/resource/unstructured/composite/composite_test.go index 7771da4e7..cec197dc0 100644 --- a/pkg/resource/unstructured/composite/composite_test.go +++ b/pkg/resource/unstructured/composite/composite_test.go @@ -17,7 +17,9 @@ limitations under the License. package composite import ( + "encoding/json" "testing" + "time" "github.com/google/go-cmp/cmp" corev1 "k8s.io/api/core/v1" @@ -238,3 +240,38 @@ func TestWriteConnectionSecretToReference(t *testing.T) { }) } } + +func TestConnectionDetailsLastPublishedTime(t *testing.T) { + now := &metav1.Time{Time: time.Now()} + + // The timestamp loses a little resolution when round-tripped through JSON + // encoding. + lores := func(t *metav1.Time) *metav1.Time { + out := &metav1.Time{} + j, _ := json.Marshal(t) + _ = json.Unmarshal(j, out) + return out + } + + cases := map[string]struct { + u *Unstructured + set *metav1.Time + want *metav1.Time + }{ + "NewTime": { + u: New(), + set: now, + want: lores(now), + }, + } + + for name, tc := range cases { + t.Run(name, func(t *testing.T) { + tc.u.SetConnectionDetailsLastPublishedTime(tc.set) + got := tc.u.GetConnectionDetailsLastPublishedTime() + if diff := cmp.Diff(tc.want, got); diff != "" { + t.Errorf("\nu.GetConnectionDetailsLastPublishedTime(): -want, +got:\n%s", diff) + } + }) + } +}