k8s.io/kubernetes@v1.29.3/test/e2e/kubectl/rollout.go (about) 1 /* 2 Copyright 2023 The Kubernetes Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 // OWNER = sig/cli 18 19 package kubectl 20 21 import ( 22 "context" 23 24 "github.com/google/go-cmp/cmp" 25 "github.com/google/go-cmp/cmp/cmpopts" 26 "github.com/onsi/ginkgo/v2" 27 28 appsv1 "k8s.io/api/apps/v1" 29 v1 "k8s.io/api/core/v1" 30 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 31 clientset "k8s.io/client-go/kubernetes" 32 commonutils "k8s.io/kubernetes/test/e2e/common" 33 "k8s.io/kubernetes/test/e2e/framework" 34 e2edeployment "k8s.io/kubernetes/test/e2e/framework/deployment" 35 e2ekubectl "k8s.io/kubernetes/test/e2e/framework/kubectl" 36 imageutils "k8s.io/kubernetes/test/utils/image" 37 admissionapi "k8s.io/pod-security-admission/api" 38 ) 39 40 var _ = SIGDescribe("Kubectl rollout", func() { 41 defer ginkgo.GinkgoRecover() 42 var deploymentYaml string 43 f := framework.NewDefaultFramework("kubectl-rollout") 44 f.NamespacePodSecurityLevel = admissionapi.LevelBaseline 45 46 var c clientset.Interface 47 var ns string 48 ginkgo.BeforeEach(func() { 49 c = f.ClientSet 50 ns = f.Namespace.Name 51 deploymentYaml = commonutils.SubstituteImageName(string(readTestFileOrDie(httpdDeployment1Filename))) 52 }) 53 54 ginkgo.Describe("undo", func() { 55 ginkgo.AfterEach(func() { 56 cleanupKubectlInputs(deploymentYaml, ns, "app=httpd") 57 }) 58 ginkgo.It("undo should rollback and update deployment env", func(ctx context.Context) { 59 var err error 60 // create deployment 61 e2ekubectl.RunKubectlOrDieInput(ns, deploymentYaml, "apply", "-f", "-") 62 63 if err = e2edeployment.WaitForDeploymentRevisionAndImage(c, ns, "httpd-deployment", "1", imageutils.GetE2EImage(imageutils.HttpdNew)); err != nil { 64 framework.Failf("created deployment not ready") 65 } 66 67 var d *appsv1.Deployment 68 if d, err = c.AppsV1().Deployments(ns).Get(ctx, "httpd-deployment", metav1.GetOptions{}); err != nil { 69 framework.Failf("get deployment failed") 70 } 71 72 origEnv := d.Spec.Template.Spec.Containers[0].Env 73 for _, env := range origEnv { 74 if env.Name == "foo" && env.Value == "bar" { 75 framework.Failf("labeled deployment should not have an env named foo and valued bar at the beginning") 76 } 77 } 78 79 origLabels := d.Spec.Template.Labels 80 if len(origLabels) == 0 { 81 framework.Failf("original labels should not be empty in kubectl rollout test") 82 } 83 84 origAnnotations := d.Spec.Template.Annotations 85 if len(origAnnotations) == 0 { 86 framework.Failf("original annotations should not be empty in kubectl rollout test") 87 } 88 89 // do a small update 90 if _, err = e2ekubectl.RunKubectl(ns, "set", "env", "deployment/httpd-deployment", "foo=bar"); err != nil { 91 framework.Failf("kubectl failed set env for deployment") 92 } 93 // wait for env to be set 94 if err = e2edeployment.WaitForDeploymentComplete(c, d); err != nil { 95 framework.Failf("update deployment failed") 96 } 97 if d, err = c.AppsV1().Deployments(ns).Get(ctx, "httpd-deployment", metav1.GetOptions{}); err != nil { 98 framework.Failf("get deployment failed") 99 } 100 envs := d.Spec.Template.Spec.Containers[0].Env 101 102 envUpdated := false 103 for _, env := range envs { 104 if env.Name == "foo" && env.Value == "bar" { 105 envUpdated = true 106 break 107 } 108 } 109 if !envUpdated { 110 framework.Failf("update deployment's env failed") 111 } 112 113 // rollback 114 if _, err = e2ekubectl.RunKubectl(ns, "rollout", "undo", "deployment/httpd-deployment"); err != nil { 115 framework.Failf("kubectl failed to rollback deployment") 116 } 117 // wait for rollback finished 118 if err = e2edeployment.WaitForDeploymentComplete(c, d); err != nil { 119 framework.Failf("rollback deployment failed") 120 } 121 if d, err = c.AppsV1().Deployments(ns).Get(ctx, "httpd-deployment", metav1.GetOptions{}); err != nil { 122 framework.Failf("get deployment failed") 123 } 124 125 rollbackedEnv := d.Spec.Template.Spec.Containers[0].Env 126 rollbackedLabels := d.Spec.Template.Labels 127 rollbackedAnnotations := d.Spec.Template.Annotations 128 129 if diff := cmp.Diff(origEnv, rollbackedEnv, cmpopts.SortSlices(func(a, b v1.EnvVar) bool { 130 return a.Name < b.Name 131 })); diff != "" { 132 framework.Failf("inconsistent env after rolled back: %s", diff) 133 } 134 if diff := cmp.Diff(origLabels, rollbackedLabels); diff != "" { 135 framework.Failf("inconsistent labels after rolled back: %s", diff) 136 } 137 if diff := cmp.Diff(origAnnotations, rollbackedAnnotations); diff != "" { 138 framework.Failf("inconsistent annotations after rolled back: %s", diff) 139 } 140 }) 141 }) 142 })