Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement GetExternalTags #123

Merged
merged 1 commit into from
Mar 4, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 6 additions & 10 deletions pkg/meta/meta_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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{},
Expand All @@ -830,32 +828,30 @@ 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
want metav1.Object
}{
"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}}},
},
}

for name, tc := range cases {
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)
}
})
}
Expand Down
10 changes: 10 additions & 0 deletions pkg/resource/fake/mocks.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -200,6 +209,7 @@ type Managed struct {
metav1.ObjectMeta
ClassReferencer
ClaimReferencer
ProviderReferencer
ConnectionSecretWriterTo
Reclaimer
v1alpha1.ConditionedStatus
Expand Down
7 changes: 7 additions & 0 deletions pkg/resource/interfaces.go
Original file line number Diff line number Diff line change
Expand Up @@ -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).
Expand Down Expand Up @@ -122,6 +128,7 @@ type Managed interface {

ClassReferencer
ClaimReferencer
ProviderReferencer
ConnectionSecretWriterTo
Reclaimer

Expand Down
26 changes: 26 additions & 0 deletions pkg/resource/resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ package resource
import (
"context"
"encoding/json"
"strings"

"github.com/pkg/errors"
corev1 "k8s.io/api/core/v1"
Expand Down Expand Up @@ -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

Expand Down Expand Up @@ -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
}
34 changes: 34 additions & 0 deletions pkg/resource/resource_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ package resource

import (
"context"
"strings"
"testing"

"github.com/google/go-cmp/cmp"
Expand Down Expand Up @@ -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)
}
})
}
}