From 02f32b99b4ed07f6a34f3e575b22012aa134cd3d Mon Sep 17 00:00:00 2001 From: Karolis Rusenas Date: Wed, 18 Apr 2018 23:04:50 +0100 Subject: [PATCH] test updates --- provider/kubernetes/approvals_test.go | 84 ++- provider/kubernetes/force_update_test.go | 7 +- provider/kubernetes/implementer.go | 31 +- provider/kubernetes/kubernetes.go | 80 +-- provider/kubernetes/kubernetes_test.go | 678 +++++++++--------- .../kubernetes/unversioned_updates_test.go | 125 ++-- util/version/version.go | 4 +- util/version/version_test.go | 7 + 8 files changed, 504 insertions(+), 512 deletions(-) diff --git a/provider/kubernetes/approvals_test.go b/provider/kubernetes/approvals_test.go index 2c2aed17..806a2fcb 100644 --- a/provider/kubernetes/approvals_test.go +++ b/provider/kubernetes/approvals_test.go @@ -4,10 +4,11 @@ import ( "testing" "time" + "github.com/keel-hq/keel/internal/k8s" "github.com/keel-hq/keel/types" + apps_v1 "k8s.io/api/apps/v1" "k8s.io/api/core/v1" - "k8s.io/api/extensions/v1beta1" meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) @@ -23,33 +24,36 @@ func TestCheckRequestedApproval(t *testing.T) { }, }, } - fp.deploymentList = &v1beta1.DeploymentList{ - Items: []v1beta1.Deployment{ - v1beta1.Deployment{ - meta_v1.TypeMeta{}, - meta_v1.ObjectMeta{ - Name: "dep-1", - Namespace: "xxxx", - Labels: map[string]string{types.KeelPolicyLabel: "all", types.KeelMinimumApprovalsLabel: "1"}, - Annotations: map[string]string{}, - }, - v1beta1.DeploymentSpec{ - Template: v1.PodTemplateSpec{ - Spec: v1.PodSpec{ - Containers: []v1.Container{ - v1.Container{ - Image: "gcr.io/v2-namespace/hello-world:1.1.1", - }, + deployments := []apps_v1.Deployment{ + apps_v1.Deployment{ + meta_v1.TypeMeta{}, + meta_v1.ObjectMeta{ + Name: "dep-1", + Namespace: "xxxx", + Labels: map[string]string{types.KeelPolicyLabel: "all", types.KeelMinimumApprovalsLabel: "1"}, + Annotations: map[string]string{}, + }, + apps_v1.DeploymentSpec{ + Template: v1.PodTemplateSpec{ + Spec: v1.PodSpec{ + Containers: []v1.Container{ + v1.Container{ + Image: "gcr.io/v2-namespace/hello-world:1.1.1", }, }, }, }, - v1beta1.DeploymentStatus{}, }, + apps_v1.DeploymentStatus{}, }, } + + grs := MustParseGRS(deployments) + grc := &k8s.GenericResourceCache{} + grc.Add(grs...) + approver := approver() - provider, err := NewProvider(fp, &fakeSender{}, approver) + provider, err := NewProvider(fp, &fakeSender{}, approver, grc) if err != nil { t.Fatalf("failed to get provider: %s", err) } @@ -91,33 +95,35 @@ func TestApprovedCheck(t *testing.T) { }, }, } - fp.deploymentList = &v1beta1.DeploymentList{ - Items: []v1beta1.Deployment{ - v1beta1.Deployment{ - meta_v1.TypeMeta{}, - meta_v1.ObjectMeta{ - Name: "dep-1", - Namespace: "xxxx", - Labels: map[string]string{types.KeelPolicyLabel: "all", types.KeelMinimumApprovalsLabel: "1"}, - Annotations: map[string]string{}, - }, - v1beta1.DeploymentSpec{ - Template: v1.PodTemplateSpec{ - Spec: v1.PodSpec{ - Containers: []v1.Container{ - v1.Container{ - Image: "gcr.io/v2-namespace/hello-world:1.1.1", - }, + deployments := []apps_v1.Deployment{ + apps_v1.Deployment{ + meta_v1.TypeMeta{}, + meta_v1.ObjectMeta{ + Name: "dep-1", + Namespace: "xxxx", + Labels: map[string]string{types.KeelPolicyLabel: "all", types.KeelMinimumApprovalsLabel: "1"}, + Annotations: map[string]string{}, + }, + apps_v1.DeploymentSpec{ + Template: v1.PodTemplateSpec{ + Spec: v1.PodSpec{ + Containers: []v1.Container{ + v1.Container{ + Image: "gcr.io/v2-namespace/hello-world:1.1.1", }, }, }, }, - v1beta1.DeploymentStatus{}, }, + apps_v1.DeploymentStatus{}, }, } + grs := MustParseGRS(deployments) + grc := &k8s.GenericResourceCache{} + grc.Add(grs...) + approver := approver() - provider, err := NewProvider(fp, &fakeSender{}, approver) + provider, err := NewProvider(fp, &fakeSender{}, approver, grc) if err != nil { t.Fatalf("failed to get provider: %s", err) } diff --git a/provider/kubernetes/force_update_test.go b/provider/kubernetes/force_update_test.go index f0f2b3f6..3d005525 100644 --- a/provider/kubernetes/force_update_test.go +++ b/provider/kubernetes/force_update_test.go @@ -4,6 +4,7 @@ import ( "testing" "time" + "github.com/keel-hq/keel/internal/k8s" "github.com/keel-hq/keel/types" "k8s.io/api/core/v1" "k8s.io/api/extensions/v1beta1" @@ -25,6 +26,7 @@ func TestForceUpdate(t *testing.T) { v1beta1.DeploymentStatus{}, } + grc := &k8s.GenericResourceCache{} fp.podList = &v1.PodList{ Items: []v1.Pod{ v1.Pod{ @@ -42,7 +44,7 @@ func TestForceUpdate(t *testing.T) { }, } - provider, err := NewProvider(fp, &fakeSender{}, approver()) + provider, err := NewProvider(fp, &fakeSender{}, approver(), grc) if err != nil { t.Fatalf("failed to get provider: %s", err) } @@ -104,7 +106,8 @@ func TestForceUpdateDelay(t *testing.T) { }, } - provider, err := NewProvider(fp, &fakeSender{}, approver()) + grc := &k8s.GenericResourceCache{} + provider, err := NewProvider(fp, &fakeSender{}, approver(), grc) if err != nil { t.Fatalf("failed to get provider: %s", err) } diff --git a/provider/kubernetes/implementer.go b/provider/kubernetes/implementer.go index 384f84f9..11b68416 100644 --- a/provider/kubernetes/implementer.go +++ b/provider/kubernetes/implementer.go @@ -14,7 +14,6 @@ import ( "k8s.io/api/core/v1" - "k8s.io/api/extensions/v1beta1" "k8s.io/client-go/rest" "k8s.io/client-go/tools/clientcmd" @@ -26,7 +25,7 @@ type Implementer interface { Namespaces() (*v1.NamespaceList, error) // Deployment(namespace, name string) (*v1beta1.Deployment, error) - Deployments(namespace string) (*v1beta1.DeploymentList, error) + Deployments(namespace string) (*apps_v1.DeploymentList, error) // Update(deployment *v1beta1.Deployment) error Update(obj *k8s.GenericResource) error @@ -103,32 +102,18 @@ func (i *KubernetesImplementer) Namespaces() (*v1.NamespaceList, error) { } // Deployment - get specific deployment for namespace/name -func (i *KubernetesImplementer) Deployment(namespace, name string) (*v1beta1.Deployment, error) { - dep := i.client.Extensions().Deployments(namespace) +func (i *KubernetesImplementer) Deployment(namespace, name string) (*apps_v1.Deployment, error) { + dep := i.client.Apps().Deployments(namespace) return dep.Get(name, meta_v1.GetOptions{}) } // Deployments - get all deployments for namespace -func (i *KubernetesImplementer) Deployments(namespace string) (*v1beta1.DeploymentList, error) { - dep := i.client.Extensions().Deployments(namespace) +func (i *KubernetesImplementer) Deployments(namespace string) (*apps_v1.DeploymentList, error) { + dep := i.client.Apps().Deployments(namespace) l, err := dep.List(meta_v1.ListOptions{}) return l, err } -// Update - update deployment -// func (i *KubernetesImplementer) Update(deployment *v1beta1.Deployment) error { -// // retryErr := retry.RetryOnConflict(retry.DefaultRetry, func() error { -// // // Retrieve the latest version of Deployment before attempting update -// // // RetryOnConflict uses exponential backoff to avoid exhausting the apiserver -// // _, updateErr := i.client.Extensions().Deployments(deployment.Namespace).Update(deployment) -// // return updateErr -// // }) -// // return retryErr - -// _, err := i.client.Extensions().Deployments(deployment.Namespace).Update(deployment) -// return err -// } - // Update converts generic resource into specific kubernetes type and updates it func (i *KubernetesImplementer) Update(obj *k8s.GenericResource) error { // retryErr := retry.RetryOnConflict(retry.DefaultRetry, func() error { @@ -155,10 +140,10 @@ func (i *KubernetesImplementer) Update(obj *k8s.GenericResource) error { if err != nil { return err } + default: + return fmt.Errorf("unsupported object type") } - - // _, err := i.client.Extensions().Deployments(deployment.Namespace).Update(deployment) - return fmt.Errorf("unsupported object type") + return nil } // Secret - get secret diff --git a/provider/kubernetes/kubernetes.go b/provider/kubernetes/kubernetes.go index 4f0d7e5d..5a59a9e6 100644 --- a/provider/kubernetes/kubernetes.go +++ b/provider/kubernetes/kubernetes.go @@ -9,7 +9,6 @@ import ( "github.com/rusenask/cron" "k8s.io/api/core/v1" - "k8s.io/api/extensions/v1beta1" "github.com/prometheus/client_golang/prometheus" @@ -374,22 +373,22 @@ func (p *Provider) updateDeployments(plans []*UpdatePlan) (updated []*k8s.Generi return } -func getImages(deployment *v1beta1.Deployment) []string { - var images []string - for _, c := range deployment.Spec.Template.Spec.Containers { - images = append(images, c.Image) - } +// func getImages(deployment *v1beta1.Deployment) []string { +// var images []string +// for _, c := range deployment.Spec.Template.Spec.Containers { +// images = append(images, c.Image) +// } - return images -} +// return images +// } -func getImagePullSecrets(deployment *v1beta1.Deployment) []string { - var secrets []string - for _, s := range deployment.Spec.Template.Spec.ImagePullSecrets { - secrets = append(secrets, s.Name) - } - return secrets -} +// func getImagePullSecrets(deployment *v1beta1.Deployment) []string { +// var secrets []string +// for _, s := range deployment.Spec.Template.Spec.ImagePullSecrets { +// secrets = append(secrets, s.Name) +// } +// return secrets +// } func getDesiredImage(delta map[string]string, currentImage string) (string, error) { currentRef, err := image.Parse(currentImage) @@ -413,37 +412,10 @@ func getDesiredImage(delta map[string]string, currentImage string) (string, erro return "", fmt.Errorf("image %s not found in deltas", currentImage) } -// checkForReset returns delta to apply after setting image -func checkForReset(deployment v1beta1.Deployment) bool { - reset := false - annotations := deployment.GetAnnotations() - for _, c := range deployment.Spec.Template.Spec.Containers { - if shouldPullImage(annotations, c.Image) { - reset = true - } - } - return reset -} - -// getDeployment - helper function to get specific deployment -// func (p *Provider) getDeployment(namespace, name string) (*v1beta1.Deployment, error) { -// return p.implementer.Deployment(namespace, name) -// } - // createUpdatePlans - impacted deployments by changed repository func (p *Provider) createUpdatePlans(repo *types.Repository) ([]*UpdatePlan, error) { - - // deploymentLists, err := p.deployments() - // if err != nil { - // log.WithFields(log.Fields{ - // "error": err, - // }).Error("provider.kubernetes: failed to get deployment lists") - // return nil, err - // } - impacted := []*UpdatePlan{} - // for _, deploymentList := range deploymentLists { for _, resource := range p.cache.Values() { labels := resource.GetLabels() @@ -516,27 +488,3 @@ func (p *Provider) createUpdatePlans(repo *types.Repository) ([]*UpdatePlan, err func (p *Provider) namespaces() (*v1.NamespaceList, error) { return p.implementer.Namespaces() } - -// deployments - gets all deployments -// func (p *Provider) deployments() ([]*v1beta1.DeploymentList, error) { -// deployments := []*v1beta1.DeploymentList{} - -// n, err := p.namespaces() -// if err != nil { -// return nil, err -// } - -// for _, n := range n.Items { -// l, err := p.implementer.Deployments(n.GetName()) -// if err != nil { -// log.WithFields(log.Fields{ -// "error": err, -// "namespace": n.GetName(), -// }).Error("provider.kubernetes: failed to list deployments") -// continue -// } -// deployments = append(deployments, l) -// } - -// return deployments, nil -// } diff --git a/provider/kubernetes/kubernetes_test.go b/provider/kubernetes/kubernetes_test.go index bf6e2e35..1182912b 100644 --- a/provider/kubernetes/kubernetes_test.go +++ b/provider/kubernetes/kubernetes_test.go @@ -7,11 +7,13 @@ import ( "github.com/keel-hq/keel/approvals" "github.com/keel-hq/keel/cache/memory" "github.com/keel-hq/keel/extension/notification" + "github.com/keel-hq/keel/internal/k8s" "github.com/keel-hq/keel/types" "github.com/keel-hq/keel/util/codecs" + apps_v1 "k8s.io/api/apps/v1" "k8s.io/api/core/v1" - "k8s.io/api/extensions/v1beta1" + // "k8s.io/api/extensions/apps_v1" meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1" core_v1 "k8s.io/client-go/kubernetes/typed/core/v1" ) @@ -41,14 +43,14 @@ func (p *fakeProvider) GetName() string { type fakeImplementer struct { namespaces *v1.NamespaceList - deployment *v1beta1.Deployment - deploymentList *v1beta1.DeploymentList + deployment *apps_v1.Deployment + deploymentList *apps_v1.DeploymentList podList *v1.PodList deletedPods []*v1.Pod // stores value of an updated deployment - updated *v1beta1.Deployment + updated *k8s.GenericResource availableSecret *v1.Secret } @@ -57,16 +59,16 @@ func (i *fakeImplementer) Namespaces() (*v1.NamespaceList, error) { return i.namespaces, nil } -func (i *fakeImplementer) Deployment(namespace, name string) (*v1beta1.Deployment, error) { +func (i *fakeImplementer) Deployment(namespace, name string) (*apps_v1.Deployment, error) { return i.deployment, nil } -func (i *fakeImplementer) Deployments(namespace string) (*v1beta1.DeploymentList, error) { +func (i *fakeImplementer) Deployments(namespace string) (*apps_v1.DeploymentList, error) { return i.deploymentList, nil } -func (i *fakeImplementer) Update(deployment *v1beta1.Deployment) error { - i.updated = deployment +func (i *fakeImplementer) Update(obj *k8s.GenericResource) error { + i.updated = obj return nil } @@ -128,7 +130,9 @@ func TestGetNamespaces(t *testing.T) { }, } - provider, err := NewProvider(fi, &fakeSender{}, approver()) + grc := &k8s.GenericResourceCache{} + + provider, err := NewProvider(fi, &fakeSender{}, approver(), grc) if err != nil { t.Fatalf("failed to get provider: %s", err) } @@ -150,59 +154,79 @@ func TestGetImageName(t *testing.T) { } } -func TestGetDeployments(t *testing.T) { - fp := &fakeImplementer{} - fp.namespaces = &v1.NamespaceList{ - Items: []v1.Namespace{ - v1.Namespace{ - meta_v1.TypeMeta{}, - meta_v1.ObjectMeta{Name: "xxxx"}, - v1.NamespaceSpec{}, - v1.NamespaceStatus{}, - }, - }, - } - fp.deploymentList = &v1beta1.DeploymentList{ - Items: []v1beta1.Deployment{ - v1beta1.Deployment{ - meta_v1.TypeMeta{}, - meta_v1.ObjectMeta{ - Name: "dep-1", - Namespace: "xxxx", - Labels: map[string]string{types.KeelPolicyLabel: "all"}, - }, - v1beta1.DeploymentSpec{ - Template: v1.PodTemplateSpec{ - Spec: v1.PodSpec{ - Containers: []v1.Container{ - v1.Container{ - Image: "gcr.io/v2-namespace/hello-world:1.1", - }, - }, - }, - }, - }, - v1beta1.DeploymentStatus{}, - }, - }, - } +// func TestGetDeployments(t *testing.T) { +// fp := &fakeImplementer{} +// fp.namespaces = &v1.NamespaceList{ +// Items: []v1.Namespace{ +// v1.Namespace{ +// meta_v1.TypeMeta{}, +// meta_v1.ObjectMeta{Name: "xxxx"}, +// v1.NamespaceSpec{}, +// v1.NamespaceStatus{}, +// }, +// }, +// } +// fp.deploymentList = &apps_v1.DeploymentList{ +// Items: []apps_v1.Deployment{ +// apps_v1.Deployment{ +// meta_v1.TypeMeta{}, +// meta_v1.ObjectMeta{ +// Name: "dep-1", +// Namespace: "xxxx", +// Labels: map[string]string{types.KeelPolicyLabel: "all"}, +// }, +// apps_v1.DeploymentSpec{ +// Template: v1.PodTemplateSpec{ +// Spec: v1.PodSpec{ +// Containers: []v1.Container{ +// v1.Container{ +// Image: "gcr.io/v2-namespace/hello-world:1.1", +// }, +// }, +// }, +// }, +// }, +// apps_v1.DeploymentStatus{}, +// }, +// }, +// } +// grc := &k8s.GenericResourceCache{} +// provider, err := NewProvider(fp, &fakeSender{}, approver(), grc) +// if err != nil { +// t.Fatalf("failed to get provider: %s", err) +// } - provider, err := NewProvider(fp, &fakeSender{}, approver()) +// deps, err := provider.deployments() +// if err != nil { +// t.Errorf("failed to get deployments: %s", err) +// } +// if len(deps) != 1 { +// t.Errorf("expected to find 1 deployment, got: %d", len(deps)) +// } + +// if deps[0].Items[0].GetName() != "dep-1" { +// t.Errorf("expected name %s, got %s", "dep-1", deps[0].Items[0].GetName()) +// } +// } + +func MustParseGR(obj interface{}) *k8s.GenericResource { + gr, err := k8s.NewGenericResource(obj) if err != nil { - t.Fatalf("failed to get provider: %s", err) + panic(err) } + return gr +} - deps, err := provider.deployments() - if err != nil { - t.Errorf("failed to get deployments: %s", err) - } - if len(deps) != 1 { - t.Errorf("expected to find 1 deployment, got: %d", len(deps)) - } - - if deps[0].Items[0].GetName() != "dep-1" { - t.Errorf("expected name %s, got %s", "dep-1", deps[0].Items[0].GetName()) +func MustParseGRS(objs ...interface{}) []*k8s.GenericResource { + grs := []*k8s.GenericResource{} + for obj := range objs { + gr, err := k8s.NewGenericResource(obj) + if err != nil { + panic(err) + } + grs = append(grs, gr) } + return grs } func TestGetImpacted(t *testing.T) { @@ -217,52 +241,55 @@ func TestGetImpacted(t *testing.T) { }, }, } - fp.deploymentList = &v1beta1.DeploymentList{ - Items: []v1beta1.Deployment{ - v1beta1.Deployment{ - meta_v1.TypeMeta{}, - meta_v1.ObjectMeta{ - Name: "dep-1", - Namespace: "xxxx", - Labels: map[string]string{types.KeelPolicyLabel: "all"}, - }, - v1beta1.DeploymentSpec{ - Template: v1.PodTemplateSpec{ - Spec: v1.PodSpec{ - Containers: []v1.Container{ - v1.Container{ - Image: "gcr.io/v2-namespace/hello-world:1.1.1", - }, + + deps := []apps_v1.Deployment{ + apps_v1.Deployment{ + meta_v1.TypeMeta{}, + meta_v1.ObjectMeta{ + Name: "dep-1", + Namespace: "xxxx", + Labels: map[string]string{types.KeelPolicyLabel: "all"}, + }, + apps_v1.DeploymentSpec{ + Template: v1.PodTemplateSpec{ + Spec: v1.PodSpec{ + Containers: []v1.Container{ + v1.Container{ + Image: "gcr.io/v2-namespace/hello-world:1.1.1", }, }, }, }, - v1beta1.DeploymentStatus{}, }, - v1beta1.Deployment{ - meta_v1.TypeMeta{}, - meta_v1.ObjectMeta{ - Name: "dep-2", - Namespace: "xxxx", - Labels: map[string]string{"whatever": "all"}, - }, - v1beta1.DeploymentSpec{ - Template: v1.PodTemplateSpec{ - Spec: v1.PodSpec{ - Containers: []v1.Container{ - v1.Container{ - Image: "gcr.io/v2-namespace/hello-world:1.1.1", - }, + apps_v1.DeploymentStatus{}, + }, + apps_v1.Deployment{ + meta_v1.TypeMeta{}, + meta_v1.ObjectMeta{ + Name: "dep-2", + Namespace: "xxxx", + Labels: map[string]string{"whatever": "all"}, + }, + apps_v1.DeploymentSpec{ + Template: v1.PodTemplateSpec{ + Spec: v1.PodSpec{ + Containers: []v1.Container{ + v1.Container{ + Image: "gcr.io/v2-namespace/hello-world:1.1.1", }, }, }, }, - v1beta1.DeploymentStatus{}, }, + apps_v1.DeploymentStatus{}, }, } - provider, err := NewProvider(fp, &fakeSender{}, approver()) + grs := MustParseGRS(deps) + grc := &k8s.GenericResourceCache{} + grc.Add(grs...) + + provider, err := NewProvider(fp, &fakeSender{}, approver(), grc) if err != nil { t.Fatalf("failed to get provider: %s", err) } @@ -283,7 +310,7 @@ func TestGetImpacted(t *testing.T) { } found := false - for _, c := range plans[0].Deployment.Spec.Template.Spec.Containers { + for _, c := range plans[0].Resource.Containers() { containerImageName := versionreg.ReplaceAllString(c.Image, "") @@ -310,54 +337,56 @@ func TestProcessEvent(t *testing.T) { }, }, } - fp.deploymentList = &v1beta1.DeploymentList{ - Items: []v1beta1.Deployment{ - v1beta1.Deployment{ - meta_v1.TypeMeta{}, - meta_v1.ObjectMeta{ - Name: "deployment-1", - Namespace: "xxxx", - Labels: map[string]string{types.KeelPolicyLabel: "all"}, - Annotations: map[string]string{}, - }, - v1beta1.DeploymentSpec{ - Template: v1.PodTemplateSpec{ - Spec: v1.PodSpec{ - Containers: []v1.Container{ - v1.Container{ - Image: "gcr.io/v2-namespace/hello-world:1.1.1", - }, + deps := []apps_v1.Deployment{ + apps_v1.Deployment{ + meta_v1.TypeMeta{}, + meta_v1.ObjectMeta{ + Name: "deployment-1", + Namespace: "xxxx", + Labels: map[string]string{types.KeelPolicyLabel: "all"}, + Annotations: map[string]string{}, + }, + apps_v1.DeploymentSpec{ + Template: v1.PodTemplateSpec{ + Spec: v1.PodSpec{ + Containers: []v1.Container{ + v1.Container{ + Image: "gcr.io/v2-namespace/hello-world:1.1.1", }, }, }, }, - v1beta1.DeploymentStatus{}, }, - v1beta1.Deployment{ - meta_v1.TypeMeta{}, - meta_v1.ObjectMeta{ - Name: "deployment-2", - Namespace: "xxxx", - Labels: map[string]string{"whatever": "all"}, - Annotations: map[string]string{}, - }, - v1beta1.DeploymentSpec{ - Template: v1.PodTemplateSpec{ - Spec: v1.PodSpec{ - Containers: []v1.Container{ - v1.Container{ - Image: "gcr.io/v2-namespace/bye-world:1.1.1", - }, + apps_v1.DeploymentStatus{}, + }, + apps_v1.Deployment{ + meta_v1.TypeMeta{}, + meta_v1.ObjectMeta{ + Name: "deployment-2", + Namespace: "xxxx", + Labels: map[string]string{"whatever": "all"}, + Annotations: map[string]string{}, + }, + apps_v1.DeploymentSpec{ + Template: v1.PodTemplateSpec{ + Spec: v1.PodSpec{ + Containers: []v1.Container{ + v1.Container{ + Image: "gcr.io/v2-namespace/bye-world:1.1.1", }, }, }, }, - v1beta1.DeploymentStatus{}, }, + apps_v1.DeploymentStatus{}, }, } - provider, err := NewProvider(fp, &fakeSender{}, approver()) + grs := MustParseGRS(deps) + grc := &k8s.GenericResourceCache{} + grc.Add(grs...) + + provider, err := NewProvider(fp, &fakeSender{}, approver(), grc) if err != nil { t.Fatalf("failed to get provider: %s", err) } @@ -373,8 +402,8 @@ func TestProcessEvent(t *testing.T) { t.Errorf("got error while processing event: %s", err) } - if fp.updated.Spec.Template.Spec.Containers[0].Image != repo.Name+":"+repo.Tag { - t.Errorf("expected to find a deployment with updated image but found: %s", fp.updated.Spec.Template.Spec.Containers[0].Image) + if fp.updated.Containers()[0].Image != repo.Name+":"+repo.Tag { + t.Errorf("expected to find a deployment with updated image but found: %s", fp.updated.Containers()[0].Image) } } @@ -390,33 +419,35 @@ func TestProcessEventBuildNumber(t *testing.T) { }, }, } - fp.deploymentList = &v1beta1.DeploymentList{ - Items: []v1beta1.Deployment{ - v1beta1.Deployment{ - meta_v1.TypeMeta{}, - meta_v1.ObjectMeta{ - Name: "deployment-1", - Namespace: "xxxx", - Labels: map[string]string{types.KeelPolicyLabel: "all"}, - Annotations: map[string]string{}, - }, - v1beta1.DeploymentSpec{ - Template: v1.PodTemplateSpec{ - Spec: v1.PodSpec{ - Containers: []v1.Container{ - v1.Container{ - Image: "gcr.io/v2-namespace/hello-world:10", - }, + deps := []apps_v1.Deployment{ + apps_v1.Deployment{ + meta_v1.TypeMeta{}, + meta_v1.ObjectMeta{ + Name: "deployment-1", + Namespace: "xxxx", + Labels: map[string]string{types.KeelPolicyLabel: "all"}, + Annotations: map[string]string{}, + }, + apps_v1.DeploymentSpec{ + Template: v1.PodTemplateSpec{ + Spec: v1.PodSpec{ + Containers: []v1.Container{ + v1.Container{ + Image: "gcr.io/v2-namespace/hello-world:10", }, }, }, }, - v1beta1.DeploymentStatus{}, }, + apps_v1.DeploymentStatus{}, }, } - provider, err := NewProvider(fp, &fakeSender{}, approver()) + grs := MustParseGRS(deps) + grc := &k8s.GenericResourceCache{} + grc.Add(grs...) + + provider, err := NewProvider(fp, &fakeSender{}, approver(), grc) if err != nil { t.Fatalf("failed to get provider: %s", err) } @@ -432,8 +463,8 @@ func TestProcessEventBuildNumber(t *testing.T) { t.Errorf("got error while processing event: %s", err) } - if fp.updated.Spec.Template.Spec.Containers[0].Image != repo.Name+":"+repo.Tag { - t.Errorf("expected to find a deployment with updated image but found: %s", fp.updated.Spec.Template.Spec.Containers[0].Image) + if fp.updated.Containers()[0].Image != repo.Name+":"+repo.Tag { + t.Errorf("expected to find a deployment with updated image but found: %s", fp.updated.Containers()[0].Image) } } @@ -450,56 +481,57 @@ func TestGetImpactedTwoContainersInSameDeployment(t *testing.T) { }, }, } - fp.deploymentList = &v1beta1.DeploymentList{ - Items: []v1beta1.Deployment{ - v1beta1.Deployment{ - meta_v1.TypeMeta{}, - meta_v1.ObjectMeta{ - Name: "dep-1", - Namespace: "xxxx", - Labels: map[string]string{types.KeelPolicyLabel: "all"}, - Annotations: map[string]string{}, - }, - v1beta1.DeploymentSpec{ - Template: v1.PodTemplateSpec{ - Spec: v1.PodSpec{ - Containers: []v1.Container{ - v1.Container{ - Image: "gcr.io/v2-namespace/hello-world:1.1.1", - }, - v1.Container{ - Image: "gcr.io/v2-namespace/greetings-world:1.1.1", - }, + deps := []apps_v1.Deployment{ + apps_v1.Deployment{ + meta_v1.TypeMeta{}, + meta_v1.ObjectMeta{ + Name: "dep-1", + Namespace: "xxxx", + Labels: map[string]string{types.KeelPolicyLabel: "all"}, + Annotations: map[string]string{}, + }, + apps_v1.DeploymentSpec{ + Template: v1.PodTemplateSpec{ + Spec: v1.PodSpec{ + Containers: []v1.Container{ + v1.Container{ + Image: "gcr.io/v2-namespace/hello-world:1.1.1", + }, + v1.Container{ + Image: "gcr.io/v2-namespace/greetings-world:1.1.1", }, }, }, }, - v1beta1.DeploymentStatus{}, }, - v1beta1.Deployment{ - meta_v1.TypeMeta{}, - meta_v1.ObjectMeta{ - Name: "dep-2", - Namespace: "xxxx", - Labels: map[string]string{"whatever": "all"}, - }, - v1beta1.DeploymentSpec{ - Template: v1.PodTemplateSpec{ - Spec: v1.PodSpec{ - Containers: []v1.Container{ - v1.Container{ - Image: "gcr.io/v2-namespace/hello-world:1.1.1", - }, + apps_v1.DeploymentStatus{}, + }, + apps_v1.Deployment{ + meta_v1.TypeMeta{}, + meta_v1.ObjectMeta{ + Name: "dep-2", + Namespace: "xxxx", + Labels: map[string]string{"whatever": "all"}, + }, + apps_v1.DeploymentSpec{ + Template: v1.PodTemplateSpec{ + Spec: v1.PodSpec{ + Containers: []v1.Container{ + v1.Container{ + Image: "gcr.io/v2-namespace/hello-world:1.1.1", }, }, }, }, - v1beta1.DeploymentStatus{}, }, + apps_v1.DeploymentStatus{}, }, } + grs := MustParseGRS(deps) + grc := &k8s.GenericResourceCache{} + grc.Add(grs...) - provider, err := NewProvider(fp, &fakeSender{}, approver()) + provider, err := NewProvider(fp, &fakeSender{}, approver(), grc) if err != nil { t.Fatalf("failed to get provider: %s", err) } @@ -520,7 +552,7 @@ func TestGetImpactedTwoContainersInSameDeployment(t *testing.T) { } found := false - for _, c := range plans[0].Deployment.Spec.Template.Spec.Containers { + for _, c := range plans[0].Resource.Containers() { containerImageName := versionreg.ReplaceAllString(c.Image, "") @@ -548,57 +580,59 @@ func TestGetImpactedTwoSameContainersInSameDeployment(t *testing.T) { }, }, } - fp.deploymentList = &v1beta1.DeploymentList{ - Items: []v1beta1.Deployment{ - v1beta1.Deployment{ - meta_v1.TypeMeta{}, - meta_v1.ObjectMeta{ - Name: "dep-1", - Namespace: "xxxx", - Labels: map[string]string{types.KeelPolicyLabel: "all"}, - Annotations: map[string]string{}, - }, - v1beta1.DeploymentSpec{ - Template: v1.PodTemplateSpec{ - Spec: v1.PodSpec{ - Containers: []v1.Container{ - v1.Container{ - Image: "gcr.io/v2-namespace/hello-world:1.1.1", - }, - v1.Container{ - Image: "gcr.io/v2-namespace/hello-world:1.1.1", - }, + deps := []apps_v1.Deployment{ + apps_v1.Deployment{ + meta_v1.TypeMeta{}, + meta_v1.ObjectMeta{ + Name: "dep-1", + Namespace: "xxxx", + Labels: map[string]string{types.KeelPolicyLabel: "all"}, + Annotations: map[string]string{}, + }, + apps_v1.DeploymentSpec{ + Template: v1.PodTemplateSpec{ + Spec: v1.PodSpec{ + Containers: []v1.Container{ + v1.Container{ + Image: "gcr.io/v2-namespace/hello-world:1.1.1", + }, + v1.Container{ + Image: "gcr.io/v2-namespace/hello-world:1.1.1", }, }, }, }, - v1beta1.DeploymentStatus{}, }, - v1beta1.Deployment{ - meta_v1.TypeMeta{}, - meta_v1.ObjectMeta{ - Name: "dep-2", - Namespace: "xxxx", - Labels: map[string]string{"whatever": "all"}, - Annotations: map[string]string{}, - }, - v1beta1.DeploymentSpec{ - Template: v1.PodTemplateSpec{ - Spec: v1.PodSpec{ - Containers: []v1.Container{ - v1.Container{ - Image: "gcr.io/v2-namespace/hello-world:1.1.1", - }, + apps_v1.DeploymentStatus{}, + }, + apps_v1.Deployment{ + meta_v1.TypeMeta{}, + meta_v1.ObjectMeta{ + Name: "dep-2", + Namespace: "xxxx", + Labels: map[string]string{"whatever": "all"}, + Annotations: map[string]string{}, + }, + apps_v1.DeploymentSpec{ + Template: v1.PodTemplateSpec{ + Spec: v1.PodSpec{ + Containers: []v1.Container{ + v1.Container{ + Image: "gcr.io/v2-namespace/hello-world:1.1.1", }, }, }, }, - v1beta1.DeploymentStatus{}, }, + apps_v1.DeploymentStatus{}, }, } - provider, err := NewProvider(fp, &fakeSender{}, approver()) + grs := MustParseGRS(deps) + grc := &k8s.GenericResourceCache{} + grc.Add(grs...) + + provider, err := NewProvider(fp, &fakeSender{}, approver(), grc) if err != nil { t.Fatalf("failed to get provider: %s", err) } @@ -619,7 +653,7 @@ func TestGetImpactedTwoSameContainersInSameDeployment(t *testing.T) { } found := false - for _, c := range plans[0].Deployment.Spec.Template.Spec.Containers { + for _, c := range plans[0].Resource.Containers() { containerImageName := versionreg.ReplaceAllString(c.Image, "") @@ -646,54 +680,55 @@ func TestGetImpactedUntaggedImage(t *testing.T) { }, }, } - fp.deploymentList = &v1beta1.DeploymentList{ - Items: []v1beta1.Deployment{ - v1beta1.Deployment{ - meta_v1.TypeMeta{}, - meta_v1.ObjectMeta{ - Name: "dep-1", - Namespace: "xxxx", - Labels: map[string]string{types.KeelPolicyLabel: "all"}, - Annotations: map[string]string{}, - }, - v1beta1.DeploymentSpec{ - Template: v1.PodTemplateSpec{ - Spec: v1.PodSpec{ - Containers: []v1.Container{ - v1.Container{ - Image: "gcr.io/v2-namespace/foo-world", - }, + deps := []apps_v1.Deployment{ + apps_v1.Deployment{ + meta_v1.TypeMeta{}, + meta_v1.ObjectMeta{ + Name: "dep-1", + Namespace: "xxxx", + Labels: map[string]string{types.KeelPolicyLabel: "all"}, + Annotations: map[string]string{}, + }, + apps_v1.DeploymentSpec{ + Template: v1.PodTemplateSpec{ + Spec: v1.PodSpec{ + Containers: []v1.Container{ + v1.Container{ + Image: "gcr.io/v2-namespace/foo-world", }, }, }, }, - v1beta1.DeploymentStatus{}, }, - v1beta1.Deployment{ - meta_v1.TypeMeta{}, - meta_v1.ObjectMeta{ - Name: "dep-2", - Namespace: "xxxx", - Annotations: map[string]string{}, - Labels: map[string]string{types.KeelPolicyLabel: "all"}, - }, - v1beta1.DeploymentSpec{ - Template: v1.PodTemplateSpec{ - Spec: v1.PodSpec{ - Containers: []v1.Container{ - v1.Container{ - Image: "gcr.io/v2-namespace/hello-world:1.1.1", - }, + apps_v1.DeploymentStatus{}, + }, + apps_v1.Deployment{ + meta_v1.TypeMeta{}, + meta_v1.ObjectMeta{ + Name: "dep-2", + Namespace: "xxxx", + Annotations: map[string]string{}, + Labels: map[string]string{types.KeelPolicyLabel: "all"}, + }, + apps_v1.DeploymentSpec{ + Template: v1.PodTemplateSpec{ + Spec: v1.PodSpec{ + Containers: []v1.Container{ + v1.Container{ + Image: "gcr.io/v2-namespace/hello-world:1.1.1", }, }, }, }, - v1beta1.DeploymentStatus{}, }, + apps_v1.DeploymentStatus{}, }, } + grs := MustParseGRS(deps) + grc := &k8s.GenericResourceCache{} + grc.Add(grs...) - provider, err := NewProvider(fp, &fakeSender{}, approver()) + provider, err := NewProvider(fp, &fakeSender{}, approver(), grc) if err != nil { t.Fatalf("failed to get provider: %s", err) } @@ -714,7 +749,7 @@ func TestGetImpactedUntaggedImage(t *testing.T) { } found := false - for _, c := range plans[0].Deployment.Spec.Template.Spec.Containers { + for _, c := range plans[0].Resource.Containers() { containerImageName := versionreg.ReplaceAllString(c.Image, "") @@ -742,54 +777,55 @@ func TestGetImpactedUntaggedOneImage(t *testing.T) { }, }, } - fp.deploymentList = &v1beta1.DeploymentList{ - Items: []v1beta1.Deployment{ - v1beta1.Deployment{ - meta_v1.TypeMeta{}, - meta_v1.ObjectMeta{ - Name: "dep-1", - Namespace: "xxxx", - Labels: map[string]string{types.KeelPolicyLabel: "all"}, - Annotations: map[string]string{}, - }, - v1beta1.DeploymentSpec{ - Template: v1.PodTemplateSpec{ - Spec: v1.PodSpec{ - Containers: []v1.Container{ - v1.Container{ - Image: "gcr.io/v2-namespace/hello-world", - }, + deps := []apps_v1.Deployment{ + apps_v1.Deployment{ + meta_v1.TypeMeta{}, + meta_v1.ObjectMeta{ + Name: "dep-1", + Namespace: "xxxx", + Labels: map[string]string{types.KeelPolicyLabel: "all"}, + Annotations: map[string]string{}, + }, + apps_v1.DeploymentSpec{ + Template: v1.PodTemplateSpec{ + Spec: v1.PodSpec{ + Containers: []v1.Container{ + v1.Container{ + Image: "gcr.io/v2-namespace/hello-world", }, }, }, }, - v1beta1.DeploymentStatus{}, }, - v1beta1.Deployment{ - meta_v1.TypeMeta{}, - meta_v1.ObjectMeta{ - Name: "dep-2", - Namespace: "xxxx", - Annotations: map[string]string{}, - Labels: map[string]string{types.KeelPolicyLabel: "all"}, - }, - v1beta1.DeploymentSpec{ - Template: v1.PodTemplateSpec{ - Spec: v1.PodSpec{ - Containers: []v1.Container{ - v1.Container{ - Image: "gcr.io/v2-namespace/hello-world:1.1.1", - }, + apps_v1.DeploymentStatus{}, + }, + apps_v1.Deployment{ + meta_v1.TypeMeta{}, + meta_v1.ObjectMeta{ + Name: "dep-2", + Namespace: "xxxx", + Annotations: map[string]string{}, + Labels: map[string]string{types.KeelPolicyLabel: "all"}, + }, + apps_v1.DeploymentSpec{ + Template: v1.PodTemplateSpec{ + Spec: v1.PodSpec{ + Containers: []v1.Container{ + v1.Container{ + Image: "gcr.io/v2-namespace/hello-world:1.1.1", }, }, }, }, - v1beta1.DeploymentStatus{}, }, + apps_v1.DeploymentStatus{}, }, } + grs := MustParseGRS(deps) + grc := &k8s.GenericResourceCache{} + grc.Add(grs...) - provider, err := NewProvider(fp, &fakeSender{}, approver()) + provider, err := NewProvider(fp, &fakeSender{}, approver(), grc) if err != nil { t.Fatalf("failed to get provider: %s", err) } @@ -811,7 +847,7 @@ func TestGetImpactedUntaggedOneImage(t *testing.T) { found := false for _, plan := range plans { - for _, c := range plan.Deployment.Spec.Template.Spec.Containers { + for _, c := range plan.Resource.Containers() { containerImageName := versionreg.ReplaceAllString(c.Image, "") @@ -839,37 +875,39 @@ func TestTrackedImages(t *testing.T) { }, }, } - fp.deploymentList = &v1beta1.DeploymentList{ - Items: []v1beta1.Deployment{ - v1beta1.Deployment{ - meta_v1.TypeMeta{}, - meta_v1.ObjectMeta{ - Name: "dep-1", - Namespace: "xxxx", - Labels: map[string]string{types.KeelPolicyLabel: "all"}, - }, - v1beta1.DeploymentSpec{ - Template: v1.PodTemplateSpec{ - Spec: v1.PodSpec{ - Containers: []v1.Container{ - v1.Container{ - Image: "gcr.io/v2-namespace/hello-world:1.1", - }, + deps := []apps_v1.Deployment{ + apps_v1.Deployment{ + meta_v1.TypeMeta{}, + meta_v1.ObjectMeta{ + Name: "dep-1", + Namespace: "xxxx", + Labels: map[string]string{types.KeelPolicyLabel: "all"}, + }, + apps_v1.DeploymentSpec{ + Template: v1.PodTemplateSpec{ + Spec: v1.PodSpec{ + Containers: []v1.Container{ + v1.Container{ + Image: "gcr.io/v2-namespace/hello-world:1.1", }, - ImagePullSecrets: []v1.LocalObjectReference{ - v1.LocalObjectReference{ - Name: "very-secret", - }, + }, + ImagePullSecrets: []v1.LocalObjectReference{ + v1.LocalObjectReference{ + Name: "very-secret", }, }, }, }, - v1beta1.DeploymentStatus{}, }, + apps_v1.DeploymentStatus{}, }, } - provider, err := NewProvider(fp, &fakeSender{}, approver()) + grs := MustParseGRS(deps) + grc := &k8s.GenericResourceCache{} + grc.Add(grs...) + + provider, err := NewProvider(fp, &fakeSender{}, approver(), grc) if err != nil { t.Fatalf("failed to get provider: %s", err) } diff --git a/provider/kubernetes/unversioned_updates_test.go b/provider/kubernetes/unversioned_updates_test.go index 782c2c1e..392619c6 100644 --- a/provider/kubernetes/unversioned_updates_test.go +++ b/provider/kubernetes/unversioned_updates_test.go @@ -7,10 +7,13 @@ import ( "github.com/keel-hq/keel/approvals" "github.com/keel-hq/keel/extension/notification" + "github.com/keel-hq/keel/internal/k8s" "github.com/keel-hq/keel/types" "github.com/keel-hq/keel/util/timeutil" + "k8s.io/api/core/v1" - "k8s.io/api/extensions/v1beta1" + // "k8s.io/api/extensions/apps_v1" + apps_v1 "k8s.io/api/apps/v1" meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) @@ -29,9 +32,9 @@ func TestProvider_checkUnversionedDeployment(t *testing.T) { stop chan struct{} } type args struct { - policy types.PolicyType - repo *types.Repository - deployment v1beta1.Deployment + policy types.PolicyType + repo *types.Repository + resource *k8s.GenericResource } tests := []struct { name string @@ -46,7 +49,7 @@ func TestProvider_checkUnversionedDeployment(t *testing.T) { args: args{ policy: types.PolicyTypeForce, repo: &types.Repository{Name: "gcr.io/v2-namespace/hello-world", Tag: "latest"}, - deployment: v1beta1.Deployment{ + resource: MustParseGR(&apps_v1.Deployment{ meta_v1.TypeMeta{}, meta_v1.ObjectMeta{ Name: "dep-1", @@ -54,7 +57,7 @@ func TestProvider_checkUnversionedDeployment(t *testing.T) { Annotations: map[string]string{}, Labels: map[string]string{types.KeelPolicyLabel: "all"}, }, - v1beta1.DeploymentSpec{ + apps_v1.DeploymentSpec{ Template: v1.PodTemplateSpec{ Spec: v1.PodSpec{ Containers: []v1.Container{ @@ -65,11 +68,11 @@ func TestProvider_checkUnversionedDeployment(t *testing.T) { }, }, }, - v1beta1.DeploymentStatus{}, - }, + apps_v1.DeploymentStatus{}, + }), }, wantUpdatePlan: &UpdatePlan{ - Deployment: v1beta1.Deployment{ + Resource: MustParseGR(&apps_v1.Deployment{ meta_v1.TypeMeta{}, meta_v1.ObjectMeta{ Name: "dep-1", @@ -77,7 +80,7 @@ func TestProvider_checkUnversionedDeployment(t *testing.T) { Annotations: map[string]string{forceUpdateImageAnnotation: "gcr.io/v2-namespace/hello-world:latest"}, Labels: map[string]string{types.KeelPolicyLabel: "all"}, }, - v1beta1.DeploymentSpec{ + apps_v1.DeploymentSpec{ Template: v1.PodTemplateSpec{ Spec: v1.PodSpec{ Containers: []v1.Container{ @@ -88,8 +91,8 @@ func TestProvider_checkUnversionedDeployment(t *testing.T) { }, }, }, - v1beta1.DeploymentStatus{}, - }, + apps_v1.DeploymentStatus{}, + }), NewVersion: "latest", CurrentVersion: "latest", }, @@ -101,7 +104,7 @@ func TestProvider_checkUnversionedDeployment(t *testing.T) { args: args{ policy: types.PolicyTypeForce, repo: &types.Repository{Name: "gcr.io/v2-namespace/hello-world", Tag: "latest"}, - deployment: v1beta1.Deployment{ + resource: MustParseGR(&apps_v1.Deployment{ meta_v1.TypeMeta{}, meta_v1.ObjectMeta{ Name: "dep-1", @@ -109,7 +112,7 @@ func TestProvider_checkUnversionedDeployment(t *testing.T) { Annotations: map[string]string{}, Labels: map[string]string{types.KeelPolicyLabel: "all"}, }, - v1beta1.DeploymentSpec{ + apps_v1.DeploymentSpec{ Template: v1.PodTemplateSpec{ Spec: v1.PodSpec{ Containers: []v1.Container{ @@ -120,11 +123,12 @@ func TestProvider_checkUnversionedDeployment(t *testing.T) { }, }, }, - v1beta1.DeploymentStatus{}, - }, + apps_v1.DeploymentStatus{}, + }), }, wantUpdatePlan: &UpdatePlan{ - Deployment: v1beta1.Deployment{}, + // Resource: &k8s.GenericResource{}, + Resource: nil, }, wantShouldUpdateDeployment: false, wantErr: false, @@ -134,7 +138,7 @@ func TestProvider_checkUnversionedDeployment(t *testing.T) { args: args{ policy: types.PolicyTypeForce, repo: &types.Repository{Name: "gcr.io/v2-namespace/hello-world", Tag: "master"}, - deployment: v1beta1.Deployment{ + resource: MustParseGR(&apps_v1.Deployment{ meta_v1.TypeMeta{}, meta_v1.ObjectMeta{ Name: "dep-1", @@ -146,7 +150,7 @@ func TestProvider_checkUnversionedDeployment(t *testing.T) { types.KeelPolicyLabel: "all", }, }, - v1beta1.DeploymentSpec{ + apps_v1.DeploymentSpec{ Template: v1.PodTemplateSpec{ Spec: v1.PodSpec{ Containers: []v1.Container{ @@ -157,11 +161,11 @@ func TestProvider_checkUnversionedDeployment(t *testing.T) { }, }, }, - v1beta1.DeploymentStatus{}, - }, + apps_v1.DeploymentStatus{}, + }), }, wantUpdatePlan: &UpdatePlan{ - Deployment: v1beta1.Deployment{}, + Resource: nil, }, wantShouldUpdateDeployment: false, wantErr: false, @@ -171,7 +175,7 @@ func TestProvider_checkUnversionedDeployment(t *testing.T) { args: args{ policy: types.PolicyTypeForce, repo: &types.Repository{Name: "karolisr/keel", Tag: "0.2.0"}, - deployment: v1beta1.Deployment{ + resource: MustParseGR(&apps_v1.Deployment{ meta_v1.TypeMeta{}, meta_v1.ObjectMeta{ Name: "dep-1", @@ -179,7 +183,7 @@ func TestProvider_checkUnversionedDeployment(t *testing.T) { Annotations: map[string]string{}, Labels: map[string]string{types.KeelPolicyLabel: "force"}, }, - v1beta1.DeploymentSpec{ + apps_v1.DeploymentSpec{ Template: v1.PodTemplateSpec{ Spec: v1.PodSpec{ Containers: []v1.Container{ @@ -190,11 +194,11 @@ func TestProvider_checkUnversionedDeployment(t *testing.T) { }, }, }, - v1beta1.DeploymentStatus{}, - }, + apps_v1.DeploymentStatus{}, + }), }, wantUpdatePlan: &UpdatePlan{ - Deployment: v1beta1.Deployment{ + Resource: MustParseGR(&apps_v1.Deployment{ meta_v1.TypeMeta{}, meta_v1.ObjectMeta{ Name: "dep-1", @@ -202,7 +206,7 @@ func TestProvider_checkUnversionedDeployment(t *testing.T) { Annotations: map[string]string{forceUpdateImageAnnotation: "karolisr/keel:0.2.0"}, Labels: map[string]string{types.KeelPolicyLabel: "force"}, }, - v1beta1.DeploymentSpec{ + apps_v1.DeploymentSpec{ Template: v1.PodTemplateSpec{ Spec: v1.PodSpec{ Containers: []v1.Container{ @@ -213,8 +217,8 @@ func TestProvider_checkUnversionedDeployment(t *testing.T) { }, }, }, - v1beta1.DeploymentStatus{}, - }, + apps_v1.DeploymentStatus{}, + }), NewVersion: "0.2.0", CurrentVersion: "latest", }, @@ -226,7 +230,7 @@ func TestProvider_checkUnversionedDeployment(t *testing.T) { args: args{ policy: types.PolicyTypeForce, repo: &types.Repository{Name: "karolisr/keel", Tag: "master"}, - deployment: v1beta1.Deployment{ + resource: MustParseGR(&apps_v1.Deployment{ meta_v1.TypeMeta{}, meta_v1.ObjectMeta{ Name: "dep-1", @@ -234,7 +238,7 @@ func TestProvider_checkUnversionedDeployment(t *testing.T) { Annotations: map[string]string{types.KeelPollScheduleAnnotation: types.KeelPollDefaultSchedule}, Labels: map[string]string{types.KeelPolicyLabel: "force"}, }, - v1beta1.DeploymentSpec{ + apps_v1.DeploymentSpec{ Template: v1.PodTemplateSpec{ Spec: v1.PodSpec{ Containers: []v1.Container{ @@ -245,11 +249,11 @@ func TestProvider_checkUnversionedDeployment(t *testing.T) { }, }, }, - v1beta1.DeploymentStatus{}, - }, + apps_v1.DeploymentStatus{}, + }), }, wantUpdatePlan: &UpdatePlan{ - Deployment: v1beta1.Deployment{ + Resource: MustParseGR(&apps_v1.Deployment{ meta_v1.TypeMeta{}, meta_v1.ObjectMeta{ Name: "dep-1", @@ -260,7 +264,7 @@ func TestProvider_checkUnversionedDeployment(t *testing.T) { }, Labels: map[string]string{types.KeelPolicyLabel: "force"}, }, - v1beta1.DeploymentSpec{ + apps_v1.DeploymentSpec{ Template: v1.PodTemplateSpec{ Spec: v1.PodSpec{ Containers: []v1.Container{ @@ -271,8 +275,8 @@ func TestProvider_checkUnversionedDeployment(t *testing.T) { }, }, }, - v1beta1.DeploymentStatus{}, - }, + apps_v1.DeploymentStatus{}, + }), NewVersion: "master", CurrentVersion: "master", }, @@ -285,7 +289,7 @@ func TestProvider_checkUnversionedDeployment(t *testing.T) { args: args{ policy: types.PolicyTypeForce, repo: &types.Repository{Name: "karolisr/keel", Tag: "latest-staging"}, - deployment: v1beta1.Deployment{ + resource: MustParseGR(&apps_v1.Deployment{ meta_v1.TypeMeta{}, meta_v1.ObjectMeta{ Name: "dep-1", @@ -296,7 +300,7 @@ func TestProvider_checkUnversionedDeployment(t *testing.T) { types.KeelForceTagMatchLabel: "yup", }, }, - v1beta1.DeploymentSpec{ + apps_v1.DeploymentSpec{ Template: v1.PodTemplateSpec{ Spec: v1.PodSpec{ Containers: []v1.Container{ @@ -307,11 +311,11 @@ func TestProvider_checkUnversionedDeployment(t *testing.T) { }, }, }, - v1beta1.DeploymentStatus{}, - }, + apps_v1.DeploymentStatus{}, + }), }, wantUpdatePlan: &UpdatePlan{ - Deployment: v1beta1.Deployment{ + Resource: MustParseGR(&apps_v1.Deployment{ meta_v1.TypeMeta{}, meta_v1.ObjectMeta{ Name: "dep-1", @@ -323,7 +327,7 @@ func TestProvider_checkUnversionedDeployment(t *testing.T) { }, Labels: map[string]string{types.KeelPolicyLabel: "force"}, }, - v1beta1.DeploymentSpec{ + apps_v1.DeploymentSpec{ Template: v1.PodTemplateSpec{ ObjectMeta: meta_v1.ObjectMeta{ Annotations: map[string]string{ @@ -339,8 +343,8 @@ func TestProvider_checkUnversionedDeployment(t *testing.T) { }, }, }, - v1beta1.DeploymentStatus{}, - }, + apps_v1.DeploymentStatus{}, + }), NewVersion: "latest-staging", CurrentVersion: "latest-staging", }, @@ -353,7 +357,7 @@ func TestProvider_checkUnversionedDeployment(t *testing.T) { args: args{ policy: types.PolicyTypeForce, repo: &types.Repository{Host: "eu.gcr.io", Name: "karolisr/keel", Tag: "latest-staging"}, - deployment: v1beta1.Deployment{ + resource: MustParseGR(&apps_v1.Deployment{ meta_v1.TypeMeta{}, meta_v1.ObjectMeta{ Name: "dep-1", @@ -364,7 +368,7 @@ func TestProvider_checkUnversionedDeployment(t *testing.T) { types.KeelForceTagMatchLabel: "yup", }, }, - v1beta1.DeploymentSpec{ + apps_v1.DeploymentSpec{ Template: v1.PodTemplateSpec{ ObjectMeta: meta_v1.ObjectMeta{ Annotations: map[string]string{ @@ -380,11 +384,11 @@ func TestProvider_checkUnversionedDeployment(t *testing.T) { }, }, }, - v1beta1.DeploymentStatus{}, - }, + apps_v1.DeploymentStatus{}, + }), }, wantUpdatePlan: &UpdatePlan{ - Deployment: v1beta1.Deployment{ + Resource: MustParseGR(&apps_v1.Deployment{ meta_v1.TypeMeta{}, meta_v1.ObjectMeta{ Name: "dep-1", @@ -396,7 +400,7 @@ func TestProvider_checkUnversionedDeployment(t *testing.T) { }, Labels: map[string]string{types.KeelPolicyLabel: "force"}, }, - v1beta1.DeploymentSpec{ + apps_v1.DeploymentSpec{ Template: v1.PodTemplateSpec{ ObjectMeta: meta_v1.ObjectMeta{ Annotations: map[string]string{ @@ -413,21 +417,20 @@ func TestProvider_checkUnversionedDeployment(t *testing.T) { }, }, }, - v1beta1.DeploymentStatus{}, - }, + apps_v1.DeploymentStatus{}, + }), NewVersion: "latest-staging", CurrentVersion: "latest-staging", }, wantShouldUpdateDeployment: true, wantErr: false, }, - { name: "poll trigger, force-match, different tag", args: args{ policy: types.PolicyTypeForce, repo: &types.Repository{Name: "karolisr/keel", Tag: "latest-staging"}, - deployment: v1beta1.Deployment{ + resource: MustParseGR(&apps_v1.Deployment{ meta_v1.TypeMeta{}, meta_v1.ObjectMeta{ Name: "dep-1", @@ -435,7 +438,7 @@ func TestProvider_checkUnversionedDeployment(t *testing.T) { Annotations: map[string]string{types.KeelPollScheduleAnnotation: types.KeelPollDefaultSchedule}, Labels: map[string]string{types.KeelPolicyLabel: "force"}, }, - v1beta1.DeploymentSpec{ + apps_v1.DeploymentSpec{ Template: v1.PodTemplateSpec{ Spec: v1.PodSpec{ Containers: []v1.Container{ @@ -446,11 +449,11 @@ func TestProvider_checkUnversionedDeployment(t *testing.T) { }, }, }, - v1beta1.DeploymentStatus{}, - }, + apps_v1.DeploymentStatus{}, + }), }, wantUpdatePlan: &UpdatePlan{ - Deployment: v1beta1.Deployment{}, + Resource: nil, }, wantShouldUpdateDeployment: false, wantErr: false, @@ -465,7 +468,7 @@ func TestProvider_checkUnversionedDeployment(t *testing.T) { events: tt.fields.events, stop: tt.fields.stop, } - gotUpdatePlan, gotShouldUpdateDeployment, err := p.checkUnversionedDeployment(tt.args.policy, tt.args.repo, tt.args.deployment) + gotUpdatePlan, gotShouldUpdateDeployment, err := p.checkUnversionedDeployment(tt.args.policy, tt.args.repo, tt.args.resource) if (err != nil) != tt.wantErr { t.Errorf("Provider.checkUnversionedDeployment() error = %#v, wantErr %#v", err, tt.wantErr) return diff --git a/util/version/version.go b/util/version/version.go index 940ed162..f0558d34 100644 --- a/util/version/version.go +++ b/util/version/version.go @@ -99,7 +99,9 @@ func NewAvailable(current string, tags []string) (newVersion string, newAvailabl } - vs = append(vs, v) + if currentVersion.Prerelease() == v.Prerelease() { + vs = append(vs, v) + } } if len(vs) == 0 { diff --git a/util/version/version_test.go b/util/version/version_test.go index c91cc317..d038f745 100644 --- a/util/version/version_test.go +++ b/util/version/version_test.go @@ -340,6 +340,13 @@ func TestNewAvailable(t *testing.T) { wantNewAvailable: true, wantErr: false, }, + { + name: "new non pre-release available", + args: args{current: "8.1.1", tags: []string{"8.2.0", "8.3.0-staging", "8.4.0-develop"}}, + wantNewVersion: "8.2.0", + wantNewAvailable: true, + wantErr: false, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) {