Skip to content

Commit

Permalink
Merge pull request #227 from negz/intermediary
Browse files Browse the repository at this point in the history
Allow XRs and XRCs to record when they last published connection details
  • Loading branch information
negz committed Nov 5, 2020
2 parents dd9eadb + 3058c2f commit 31eef9b
Show file tree
Hide file tree
Showing 9 changed files with 136 additions and 0 deletions.
2 changes: 2 additions & 0 deletions pkg/meta/meta.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
)
Expand Down Expand Up @@ -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(),
Expand Down
3 changes: 3 additions & 0 deletions pkg/resource/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Expand All @@ -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)},
Expand Down
18 changes: 18 additions & 0 deletions pkg/resource/fake/mocks.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 }
Expand Down Expand Up @@ -251,7 +265,9 @@ type Composite struct {
ComposedResourcesReferencer
ClaimReferencer
ConnectionSecretWriterTo

v1alpha1.ConditionedStatus
ConnectionDetailsLastPublishedTimer
}

// GetObjectKind returns schema.ObjectKind.
Expand Down Expand Up @@ -300,7 +316,9 @@ type CompositeClaim struct {
CompositionReferencer
CompositeResourceReferencer
LocalConnectionSecretWriterTo

v1alpha1.ConditionedStatus
ConnectionDetailsLastPublishedTimer
}

// GetObjectKind returns schema.ObjectKind.
Expand Down
9 changes: 9 additions & 0 deletions pkg/resource/interfaces.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -188,6 +195,7 @@ type Composite interface {
ConnectionSecretWriterTo

Conditioned
ConnectionDetailsPublishedTimer
}

// Composed resources can be a composed into a Composite resource.
Expand All @@ -208,4 +216,5 @@ type CompositeClaim interface {
LocalConnectionSecretWriterTo

Conditioned
ConnectionDetailsPublishedTimer
}
2 changes: 2 additions & 0 deletions pkg/resource/resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Expand All @@ -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
}
Expand Down
14 changes: 14 additions & 0 deletions pkg/resource/unstructured/claim/claim.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
37 changes: 37 additions & 0 deletions pkg/resource/unstructured/claim/claim_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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)
}
})
}
}
14 changes: 14 additions & 0 deletions pkg/resource/unstructured/composite/composite.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
37 changes: 37 additions & 0 deletions pkg/resource/unstructured/composite/composite_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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)
}
})
}
}

0 comments on commit 31eef9b

Please sign in to comment.