Skip to content

Commit

Permalink
feat(operator): add version conversion rule for KeptnEvaluationProvider
Browse files Browse the repository at this point in the history
Signed-off-by: Giovanni Liva <[email protected]>
  • Loading branch information
thisthat committed Dec 15, 2022
1 parent deb1027 commit e48fbd2
Show file tree
Hide file tree
Showing 3 changed files with 245 additions and 0 deletions.
52 changes: 52 additions & 0 deletions operator/api/v1alpha1/keptnevaluationprovider_conversion.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package v1alpha1

import (
"fmt"
corev1 "k8s.io/api/core/v1"

"github.com/keptn/lifecycle-toolkit/operator/api/v1alpha2"
"sigs.k8s.io/controller-runtime/pkg/conversion"
)

// ConvertTo converts the src v1alpha1.KeptnApp to the hub version (v1alpha2.KeptnApp)
func (src *KeptnEvaluationProvider) ConvertTo(dstRaw conversion.Hub) error {
dst, ok := dstRaw.(*v1alpha2.KeptnEvaluationProvider)

if !ok {
return fmt.Errorf("cannot cast KeptnEvaluationProvider to v1alpha2. Got type %T", dstRaw)
}

// Copy equal stuff to new object
// DO NOT COPY TypeMeta
dst.ObjectMeta = src.ObjectMeta

dst.Spec.TargetServer = src.Spec.TargetServer

// Set sensible defaults for new fields
dst.Spec.SecretKeyRef = corev1.SecretKeySelector{
LocalObjectReference: corev1.LocalObjectReference{
Name: src.Spec.SecretName,
},
Key: "apiToken",
}

return nil
}

// ConvertFrom converts from the hub version (v1alpha2.KeptnApp) to this version (v1alpha1.KeptnApp)
func (dst *KeptnEvaluationProvider) ConvertFrom(srcRaw conversion.Hub) error {
src, ok := srcRaw.(*v1alpha2.KeptnEvaluationProvider)

if !ok {
return fmt.Errorf("cannot cast KeptnEvaluationProvider to v1alpha1. Got type %T", srcRaw)
}

// Copy equal stuff to new object
// DO NOT COPY TypeMeta
dst.ObjectMeta = src.ObjectMeta

dst.Spec.TargetServer = src.Spec.TargetServer
dst.Spec.SecretName = src.Spec.SecretKeyRef.Name

return nil
}
187 changes: 187 additions & 0 deletions operator/api/v1alpha1/keptnevaluationprovider_conversion_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,187 @@
package v1alpha1

import (
corev1 "k8s.io/api/core/v1"
v2 "sigs.k8s.io/controller-runtime/pkg/webhook/conversion/testdata/api/v2"
"testing"

"github.com/keptn/lifecycle-toolkit/operator/api/v1alpha2"
"github.com/stretchr/testify/require"
"k8s.io/apimachinery/pkg/apis/meta/v1"
)

func TestKeptnEvalProvider_ConvertFrom(t *testing.T) {
tests := []struct {
name string
srcObj *v1alpha2.KeptnEvaluationProvider
wantErr bool
wantObj *KeptnEvaluationProvider
}{
{
name: "Test that conversion from v1alpha2 to v1alpha1 works",
srcObj: &v1alpha2.KeptnEvaluationProvider{
TypeMeta: v1.TypeMeta{
Kind: "KeptnEvaluationProvider",
APIVersion: "lifecycle.keptn.sh/v1alpha2",
},
ObjectMeta: v1.ObjectMeta{
Name: "some-keptn-app-name",
Namespace: "",
Labels: map[string]string{
"some-label": "some-label-value",
},
Annotations: map[string]string{
"some-annotation": "some-annotation-value",
},
},
Spec: v1alpha2.KeptnEvaluationProviderSpec{
TargetServer: "my-server",
SecretKeyRef: corev1.SecretKeySelector{
LocalObjectReference: corev1.LocalObjectReference{
Name: "my-secret-name",
},
Key: "my-secret-key",
},
},
Status: v1alpha2.KeptnEvaluationProviderStatus{},
},
wantErr: false,
wantObj: &KeptnEvaluationProvider{
ObjectMeta: v1.ObjectMeta{
Name: "some-keptn-app-name",
Namespace: "",
Labels: map[string]string{
"some-label": "some-label-value",
},
Annotations: map[string]string{
"some-annotation": "some-annotation-value",
},
},
Spec: KeptnEvaluationProviderSpec{
TargetServer: "my-server",
SecretName: "my-secret-name",
},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
dst := &KeptnEvaluationProvider{
TypeMeta: v1.TypeMeta{},
ObjectMeta: v1.ObjectMeta{},
Spec: KeptnEvaluationProviderSpec{},
Status: KeptnEvaluationProviderStatus{},
}
if err := dst.ConvertFrom(tt.srcObj); (err != nil) != tt.wantErr {
t.Errorf("ConvertFrom() error = %v, wantErr %v", err, tt.wantErr)
}
if tt.wantObj != nil {
require.Equal(t, tt.wantObj, dst, "Object was not converted correctly")
}
})
}
}

func TestKeptnEvalProvider_ConvertTo(t *testing.T) {
tests := []struct {
name string
src *KeptnEvaluationProvider
wantErr bool
wantObj *v1alpha2.KeptnEvaluationProvider
}{
{
name: "Test that conversion from v1alpha1 to v1alpha2 works",
src: &KeptnEvaluationProvider{
TypeMeta: v1.TypeMeta{
Kind: "KeptnEvaluationProvider",
APIVersion: "lifecycle.keptn.sh/v1alpha1",
},
ObjectMeta: v1.ObjectMeta{
Name: "some-keptn-app-name",
Namespace: "",
Labels: map[string]string{
"some-label": "some-label-value",
},
Annotations: map[string]string{
"some-annotation": "some-annotation-value",
},
},
Spec: KeptnEvaluationProviderSpec{
TargetServer: "my-server",
SecretName: "my-secret-name",
},
Status: KeptnEvaluationProviderStatus{},
},
wantErr: false,
wantObj: &v1alpha2.KeptnEvaluationProvider{
ObjectMeta: v1.ObjectMeta{
Name: "some-keptn-app-name",
Namespace: "",
Labels: map[string]string{
"some-label": "some-label-value",
},
Annotations: map[string]string{
"some-annotation": "some-annotation-value",
},
},
Spec: v1alpha2.KeptnEvaluationProviderSpec{
TargetServer: "my-server",
SecretKeyRef: corev1.SecretKeySelector{
LocalObjectReference: corev1.LocalObjectReference{
Name: "my-secret-name",
},
Key: "apiToken",
},
},
Status: v1alpha2.KeptnEvaluationProviderStatus{},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
dst := v1alpha2.KeptnEvaluationProvider{
TypeMeta: v1.TypeMeta{},
ObjectMeta: v1.ObjectMeta{},
Spec: v1alpha2.KeptnEvaluationProviderSpec{},
Status: v1alpha2.KeptnEvaluationProviderStatus{},
}
if err := tt.src.ConvertTo(&dst); (err != nil) != tt.wantErr {
t.Errorf("ConvertTo() error = %v, wantErr %v", err, tt.wantErr)
}
if tt.wantObj != nil {
require.Equal(t, tt.wantObj, &dst, "Object was not converted correctly")
}
})
}
}

func TestKeptnEvalProvider_ConvertFrom_Errorcase(t *testing.T) {
// A random different object is used here to simulate a different API version
testObj := v2.ExternalJob{}

dst := &KeptnEvaluationProvider{
TypeMeta: v1.TypeMeta{},
ObjectMeta: v1.ObjectMeta{},
Spec: KeptnEvaluationProviderSpec{},
Status: KeptnEvaluationProviderStatus{},
}

if err := dst.ConvertFrom(&testObj); err == nil {
t.Errorf("ConvertFrom() error = %v", err)
} else {
require.Contains(t, err.Error(), "cannot cast KeptnEvaluationProvider to v1alpha1")
}
}

func TestKeptnEvalProvider_ConvertTo_Errorcase(t *testing.T) {
testObj := KeptnEvaluationProvider{}

// A random different object is used here to simulate a different API version
dst := v2.ExternalJob{}

if err := testObj.ConvertTo(&dst); err == nil {
t.Errorf("ConvertTo() error = %v", err)
} else {
require.Contains(t, err.Error(), "cannot cast KeptnEvaluationProvider to v1alpha2")
}
}
6 changes: 6 additions & 0 deletions operator/api/v1alpha2/keptnevaluationprovider_conversion.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package v1alpha2

// Hub is the stub function to make the API conversion pattern with hub and spokes complete
func (*KeptnEvaluationProvider) Hub() {
// Hub() needed to implement interface
}

0 comments on commit e48fbd2

Please sign in to comment.