Implement GetExternalTags to return Crossplane tags for managed resource controllers to tag their external resources

Signed-off-by: Muvaffak Onus <onus.muvaffak@gmail.com>
This commit is contained in:
Muvaffak Onus 2020-02-27 17:17:36 +03:00
parent c7524ab860
commit 34f8959f86
No known key found for this signature in database
GPG Key ID: 86E282DC72236827
5 changed files with 83 additions and 10 deletions

View File

@ -810,15 +810,13 @@ func TestWasCreated(t *testing.T) {
}
func TestGetExternalName(t *testing.T) {
testName := "my-external-name"
cases := map[string]struct {
o metav1.Object
want string
}{
"ExternalNameExists": {
o: &corev1.Pod{ObjectMeta: metav1.ObjectMeta{Annotations: map[string]string{ExternalNameAnnotationKey: testName}}},
want: testName,
o: &corev1.Pod{ObjectMeta: metav1.ObjectMeta{Annotations: map[string]string{ExternalNameAnnotationKey: name}}},
want: name,
},
"NoExternalName": {
o: &corev1.Pod{},
@ -830,15 +828,13 @@ func TestGetExternalName(t *testing.T) {
t.Run(name, func(t *testing.T) {
got := GetExternalName(tc.o)
if diff := cmp.Diff(tc.want, got); diff != "" {
t.Errorf("WasCreated(...): -want, +got:\n%s", diff)
t.Errorf("GetExternalName(...): -want, +got:\n%s", diff)
}
})
}
}
func TestSetExternalName(t *testing.T) {
testName := "my-external-name"
cases := map[string]struct {
o metav1.Object
name string
@ -846,8 +842,8 @@ func TestSetExternalName(t *testing.T) {
}{
"SetsTheCorrectKey": {
o: &corev1.Pod{},
name: testName,
want: &corev1.Pod{ObjectMeta: metav1.ObjectMeta{Annotations: map[string]string{ExternalNameAnnotationKey: testName}}},
name: name,
want: &corev1.Pod{ObjectMeta: metav1.ObjectMeta{Annotations: map[string]string{ExternalNameAnnotationKey: name}}},
},
}
@ -855,7 +851,7 @@ func TestSetExternalName(t *testing.T) {
t.Run(name, func(t *testing.T) {
SetExternalName(tc.o, tc.name)
if diff := cmp.Diff(tc.want, tc.o); diff != "" {
t.Errorf("WasCreated(...): -want, +got:\n%s", diff)
t.Errorf("SetExternalName(...): -want, +got:\n%s", diff)
}
})
}

View File

@ -95,6 +95,15 @@ func (m *ManagedResourceReferencer) SetResourceReference(r *corev1.ObjectReferen
// GetResourceReference gets the ResourceReference.
func (m *ManagedResourceReferencer) GetResourceReference() *corev1.ObjectReference { return m.Ref }
// ProviderReferencer is a mock that implements ProviderReferencer interface.
type ProviderReferencer struct{ Ref *corev1.ObjectReference }
// SetProviderReference sets the ProviderReference.
func (m *ProviderReferencer) SetProviderReference(p *corev1.ObjectReference) { m.Ref = p }
// GetProviderReference gets the ProviderReference.
func (m *ProviderReferencer) GetProviderReference() *corev1.ObjectReference { return m.Ref }
// LocalConnectionSecretWriterTo is a mock that implements LocalConnectionSecretWriterTo interface.
type LocalConnectionSecretWriterTo struct {
Ref *v1alpha1.LocalSecretReference
@ -200,6 +209,7 @@ type Managed struct {
metav1.ObjectMeta
ClassReferencer
ClaimReferencer
ProviderReferencer
ConnectionSecretWriterTo
Reclaimer
v1alpha1.ConditionedStatus

View File

@ -89,6 +89,12 @@ type CredentialsSecretReferencer interface {
SetCredentialsSecretReference(r v1alpha1.SecretKeySelector)
}
// A ProviderReferencer may reference a provider resource.
type ProviderReferencer interface {
GetProviderReference() *corev1.ObjectReference
SetProviderReference(p *corev1.ObjectReference)
}
// A Claim is a Kubernetes object representing an abstract resource claim (e.g.
// an SQL database) that may be bound to a concrete managed resource (e.g. a
// CloudSQL instance).
@ -122,6 +128,7 @@ type Managed interface {
ClassReferencer
ClaimReferencer
ProviderReferencer
ConnectionSecretWriterTo
Reclaimer

View File

@ -19,6 +19,7 @@ package resource
import (
"context"
"encoding/json"
"strings"
"github.com/pkg/errors"
corev1 "k8s.io/api/core/v1"
@ -46,6 +47,15 @@ const (
AnnotationDelimiter = "/"
)
// External resources are tagged/labelled with the following keys in the cloud
// provider API if the type supports.
const (
ExternalResourceTagKeyKind = "crossplane-kind"
ExternalResourceTagKeyName = "crossplane-name"
ExternalResourceTagKeyClass = "crossplane-class"
ExternalResourceTagKeyProvider = "crossplane-provider"
)
// A ClaimKind contains the type metadata for a kind of resource claim.
type ClaimKind schema.GroupVersionKind
@ -298,3 +308,19 @@ type patch struct{ from runtime.Object }
func (p *patch) Type() types.PatchType { return types.MergePatchType }
func (p *patch) Data(_ runtime.Object) ([]byte, error) { return json.Marshal(p.from) }
// GetExternalTags returns the identifying tags to be used to tag the external
// resource in provider API.
func GetExternalTags(mg Managed) map[string]string {
tags := map[string]string{
ExternalResourceTagKeyKind: strings.ToLower(mg.GetObjectKind().GroupVersionKind().GroupKind().String()),
ExternalResourceTagKeyName: mg.GetName(),
}
if mg.GetClassReference() != nil {
tags[ExternalResourceTagKeyClass] = mg.GetClassReference().Name
}
if mg.GetProviderReference() != nil {
tags[ExternalResourceTagKeyProvider] = mg.GetProviderReference().Name
}
return tags
}

View File

@ -18,6 +18,7 @@ package resource
import (
"context"
"strings"
"testing"
"github.com/google/go-cmp/cmp"
@ -601,3 +602,36 @@ func TestApply(t *testing.T) {
})
}
}
func TestGetExternalTags(t *testing.T) {
provName := "prov"
className := "classy"
cases := map[string]struct {
o Managed
want map[string]string
}{
"Successful": {
o: &fake.Managed{ObjectMeta: metav1.ObjectMeta{
Name: name,
},
ProviderReferencer: fake.ProviderReferencer{Ref: &corev1.ObjectReference{Name: provName}},
ClassReferencer: fake.ClassReferencer{Ref: &corev1.ObjectReference{Name: className}},
},
want: map[string]string{
ExternalResourceTagKeyKind: strings.ToLower((&fake.Managed{}).GetObjectKind().GroupVersionKind().GroupKind().String()),
ExternalResourceTagKeyName: name,
ExternalResourceTagKeyProvider: provName,
ExternalResourceTagKeyClass: className,
},
},
}
for name, tc := range cases {
t.Run(name, func(t *testing.T) {
got := GetExternalTags(tc.o)
if diff := cmp.Diff(tc.want, got); diff != "" {
t.Errorf("GetExternalTags(...): -want, +got:\n%s", diff)
}
})
}
}