From c8cc06c5fb53d9ce1e181f8a7313f74b04689e02 Mon Sep 17 00:00:00 2001 From: Hasan Turken Date: Sat, 5 Mar 2022 01:47:16 +0300 Subject: [PATCH] Implement ConnectionPropagator in connection.DetailsManager Signed-off-by: Hasan Turken --- pkg/connection/manager.go | 46 ++++++++++++++++++++++++++++++++++++++ pkg/resource/fake/mocks.go | 11 +++++++++ pkg/resource/resource.go | 1 + 3 files changed, 58 insertions(+) diff --git a/pkg/connection/manager.go b/pkg/connection/manager.go index db5dfcd..7b14307 100644 --- a/pkg/connection/manager.go +++ b/pkg/connection/manager.go @@ -160,6 +160,52 @@ func (m *DetailsManager) FetchConnection(ctx context.Context, so resource.Connec return kv, errors.Wrap(err, errReadStore) } +// PropagateConnection propagate connection details from one resource to the other. +func (m *DetailsManager) PropagateConnection(ctx context.Context, to resource.LocalConnectionSecretOwner, from resource.ConnectionSecretOwner) (propagated bool, err error) { + // Either from does not expose a connection secret, or to does not want one. + if from.GetPublishConnectionDetailsTo() == nil || to.GetPublishConnectionDetailsTo() == nil { + return false, nil + } + + ssFrom, err := m.connectStore(ctx, from.GetPublishConnectionDetailsTo()) + if err != nil { + return false, errors.Wrap(err, errConnectStore) + } + + // TODO(turkenh): Figure out how to check the following case with + // SecretStore: errSecretConflict + + kv, err := ssFrom.ReadKeyValues(ctx, store.Secret{ + Name: from.GetPublishConnectionDetailsTo().Name, + Scope: from.GetNamespace(), + Metadata: from.GetPublishConnectionDetailsTo().Metadata, + }) + if err != nil { + return false, errors.Wrap(err, "errGetSecret") + } + + // TODO(turkenh): Implement an equivalent functionality to + // "resource.ConnectionSecretMustBeControllableBy" + + ssTo, err := m.connectStore(ctx, to.GetPublishConnectionDetailsTo()) + if err != nil { + return false, errors.Wrap(err, errConnectStore) + } + + if err = ssTo.WriteKeyValues(ctx, store.Secret{ + Name: to.GetPublishConnectionDetailsTo().Name, + Scope: to.GetNamespace(), + Metadata: to.GetPublishConnectionDetailsTo().Metadata, + }, kv); err != nil { + return false, errors.Wrap(err, errWriteStore) + } + + // TODO(turkenh): Figure out how can we set published to false + // (and why do we need to?) in case of no-op. + + return true, nil +} + func (m *DetailsManager) connectStore(ctx context.Context, p *v1.PublishConnectionDetailsTo) (Store, error) { sc := m.newConfig() if err := m.client.Get(ctx, types.NamespacedName{Name: p.SecretStoreConfigRef.Name}, sc); err != nil { diff --git a/pkg/resource/fake/mocks.go b/pkg/resource/fake/mocks.go index c7c858c..5cbe1d2 100644 --- a/pkg/resource/fake/mocks.go +++ b/pkg/resource/fake/mocks.go @@ -483,6 +483,7 @@ type MockLocalConnectionSecretOwner struct { metav1.ObjectMeta Ref *xpv1.LocalSecretReference + To *xpv1.PublishConnectionDetailsTo } // GetWriteConnectionSecretToReference returns the connection secret reference. @@ -495,6 +496,16 @@ func (m *MockLocalConnectionSecretOwner) SetWriteConnectionSecretToReference(r * m.Ref = r } +// SetPublishConnectionDetailsTo sets the publish connectionDetails to +func (m *MockLocalConnectionSecretOwner) SetPublishConnectionDetailsTo(r *xpv1.PublishConnectionDetailsTo) { + m.To = r +} + +// GetPublishConnectionDetailsTo returns the publish connectionDetails to. +func (m *MockLocalConnectionSecretOwner) GetPublishConnectionDetailsTo() *xpv1.PublishConnectionDetailsTo { + return m.To +} + // GetObjectKind returns schema.ObjectKind. func (m *MockLocalConnectionSecretOwner) GetObjectKind() schema.ObjectKind { return schema.EmptyObjectKind diff --git a/pkg/resource/resource.go b/pkg/resource/resource.go index 2c85fb6..206dc1d 100644 --- a/pkg/resource/resource.go +++ b/pkg/resource/resource.go @@ -78,6 +78,7 @@ type LocalConnectionSecretOwner interface { metav1.Object LocalConnectionSecretWriterTo + ConnectionDetailsPublisherTo } // A ConnectionPropagator is responsible for propagating information required to