diff --git a/deployments/kubernetes/chart/reloader/templates/deployment.yaml b/deployments/kubernetes/chart/reloader/templates/deployment.yaml index 53b999c..fb40b3f 100644 --- a/deployments/kubernetes/chart/reloader/templates/deployment.yaml +++ b/deployments/kubernetes/chart/reloader/templates/deployment.yaml @@ -1,4 +1,4 @@ -apiVersion: extensions/v1beta1 +apiVersion: apps/v1 kind: Deployment metadata: {{- if .Values.reloader.deployment.annotations }} diff --git a/internal/pkg/handler/upgrade_test.go b/internal/pkg/handler/upgrade_test.go index 38d5a85..9b40806 100644 --- a/internal/pkg/handler/upgrade_test.go +++ b/internal/pkg/handler/upgrade_test.go @@ -20,6 +20,8 @@ var ( secretName = "testsecret-handler-" + testutil.RandSeq(5) configmapWithInitContainer = "testconfigmapInitContainerhandler-" + testutil.RandSeq(3) secretWithInitContainer = "testsecretWithInitContainer-handler-" + testutil.RandSeq(3) + configmapWithInitEnv = "configmapWithInitEnv-" + testutil.RandSeq(3) + secretWithInitEnv = "secretWithInitEnv-handler-" + testutil.RandSeq(3) configmapWithEnvName = "testconfigmapWithEnv-handler-" + testutil.RandSeq(3) configmapWithEnvFromName = "testconfigmapWithEnvFrom-handler-" + testutil.RandSeq(3) secretWithEnvName = "testsecretWithEnv-handler-" + testutil.RandSeq(5) @@ -73,6 +75,17 @@ func setup() { logrus.Errorf("Error in configmap creation: %v", err) } + // Creating secret + _, err = testutil.CreateSecret(client, namespace, secretWithInitEnv, data) + if err != nil { + logrus.Errorf("Error in secret creation: %v", err) + } + + _, err = testutil.CreateConfigMap(client, namespace, configmapWithInitContainer, "www.google.com") + if err != nil { + logrus.Errorf("Error in configmap creation: %v", err) + } + // Creating secret _, err = testutil.CreateSecret(client, namespace, secretWithEnvFromName, data) if err != nil { @@ -97,13 +110,25 @@ func setup() { } // Creating Deployment with configmap mounted in init container - _, err = testutil.CreateDeploymentWithInitContainer(client, configmapWithInitContainer, namespace) + _, err = testutil.CreateDeploymentWithInitContainer(client, configmapWithInitContainer, namespace, true) if err != nil { logrus.Errorf("Error in Deployment with configmap creation: %v", err) } // Creating Deployment with secret mounted in init container - _, err = testutil.CreateDeploymentWithInitContainer(client, secretWithInitContainer, namespace) + _, err = testutil.CreateDeploymentWithInitContainer(client, secretWithInitContainer, namespace, true) + if err != nil { + logrus.Errorf("Error in Deployment with secret creation: %v", err) + } + + // Creating Deployment with configmap mounted as Env in init container + _, err = testutil.CreateDeploymentWithInitContainer(client, configmapWithInitEnv, namespace, false) + if err != nil { + logrus.Errorf("Error in Deployment with configmap creation: %v", err) + } + + // Creating Deployment with secret mounted as Env in init container + _, err = testutil.CreateDeploymentWithInitContainer(client, secretWithInitEnv, namespace, false) if err != nil { logrus.Errorf("Error in Deployment with secret creation: %v", err) } @@ -225,6 +250,18 @@ func teardown() { logrus.Errorf("Error while deleting deployment with secret mounted in init container %v", deploymentError) } + // Deleting Deployment with configmap mounted as env in init container + deploymentError = testutil.DeleteDeployment(client, namespace, configmapWithInitEnv) + if deploymentError != nil { + logrus.Errorf("Error while deleting deployment with configmap mounted as env in init container %v", deploymentError) + } + + // Deleting Deployment with secret mounted as env in init container + deploymentError = testutil.DeleteDeployment(client, namespace, secretWithInitEnv) + if deploymentError != nil { + logrus.Errorf("Error while deleting deployment with secret mounted as env in init container %v", deploymentError) + } + // Deleting Deployment with configmap as envFrom source deploymentError = testutil.DeleteDeployment(client, namespace, configmapWithEnvFromName) if deploymentError != nil { @@ -333,6 +370,18 @@ func teardown() { logrus.Errorf("Error while deleting the secret used as env var source %v", err) } + // Deleting Configmap used as env var source + err = testutil.DeleteConfigMap(client, namespace, configmapWithInitEnv) + if err != nil { + logrus.Errorf("Error while deleting the configmap used as env var source in init container %v", err) + } + + // Deleting Secret used as env var source + err = testutil.DeleteSecret(client, namespace, secretWithInitEnv) + if err != nil { + logrus.Errorf("Error while deleting the secret used as env var source in init container %v", err) + } + // Deleting namespace testutil.DeleteNamespace(namespace, client) @@ -402,6 +451,24 @@ func TestRollingUpgradeForDeploymentWithConfigmapAsEnvVar(t *testing.T) { } } +func TestRollingUpgradeForDeploymentWithConfigmapAsEnvVarInInitContainer(t *testing.T) { + shaData := testutil.ConvertResourceToSHA(testutil.ConfigmapResourceType, namespace, configmapWithInitEnv, "www.stakater.com") + config := getConfigWithAnnotations(constants.ConfigmapEnvVarPostfix, configmapWithInitEnv, shaData, options.ReloaderAutoAnnotation) + deploymentFuncs := GetDeploymentRollingUpgradeFuncs() + + err := PerformRollingUpgrade(client, config, deploymentFuncs) + time.Sleep(5 * time.Second) + if err != nil { + t.Errorf("Rolling upgrade failed for Deployment with Configmap used as env var") + } + + logrus.Infof("Verifying deployment update") + updated := testutil.VerifyResourceUpdate(client, config, constants.ConfigmapEnvVarPostfix, deploymentFuncs) + if !updated { + t.Errorf("Deployment was not updated") + } +} + func TestRollingUpgradeForDeploymentWithConfigmapAsEnvVarFrom(t *testing.T) { shaData := testutil.ConvertResourceToSHA(testutil.ConfigmapResourceType, namespace, configmapWithEnvFromName, "www.stakater.com") config := getConfigWithAnnotations(constants.ConfigmapEnvVarPostfix, configmapWithEnvFromName, shaData, options.ReloaderAutoAnnotation) @@ -492,6 +559,24 @@ func TestRollingUpgradeForDeploymentWithSecretAsEnvVarFrom(t *testing.T) { } } +func TestRollingUpgradeForDeploymentWithSecretAsEnvVarInInitContainer(t *testing.T) { + shaData := testutil.ConvertResourceToSHA(testutil.SecretResourceType, namespace, secretWithInitEnv, "dGVzdFVwZGF0ZWRTZWNyZXRFbmNvZGluZ0ZvclJlbG9hZGVy") + config := getConfigWithAnnotations(constants.SecretEnvVarPostfix, secretWithInitEnv, shaData, options.ReloaderAutoAnnotation) + deploymentFuncs := GetDeploymentRollingUpgradeFuncs() + + err := PerformRollingUpgrade(client, config, deploymentFuncs) + time.Sleep(5 * time.Second) + if err != nil { + t.Errorf("Rolling upgrade failed for Deployment with Secret") + } + + logrus.Infof("Verifying deployment update") + updated := testutil.VerifyResourceUpdate(client, config, constants.SecretEnvVarPostfix, deploymentFuncs) + if !updated { + t.Errorf("Deployment was not updated") + } +} + func TestRollingUpgradeForDaemonSetWithConfigmap(t *testing.T) { shaData := testutil.ConvertResourceToSHA(testutil.ConfigmapResourceType, namespace, configmapName, "www.facebook.com") config := getConfigWithAnnotations(constants.ConfigmapEnvVarPostfix, configmapName, shaData, options.ConfigmapUpdateOnChangeAnnotation) diff --git a/internal/pkg/testutil/kube.go b/internal/pkg/testutil/kube.go index 296eec0..feaec28 100644 --- a/internal/pkg/testutil/kube.go +++ b/internal/pkg/testutil/kube.go @@ -78,6 +78,61 @@ func getAnnotations(name string, autoReload bool) map[string]string { options.SecretUpdateOnChangeAnnotation: name} } +func getEnvVarSources(name string) []v1.EnvFromSource { + return []v1.EnvFromSource{ + { + ConfigMapRef: &v1.ConfigMapEnvSource{ + LocalObjectReference: v1.LocalObjectReference{ + Name: name, + }, + }, + }, + { + SecretRef: &v1.SecretEnvSource{ + LocalObjectReference: v1.LocalObjectReference{ + Name: name, + }, + }, + }, + } +} + +func getVolumes(name string) []v1.Volume { + return []v1.Volume{ + { + Name: "configmap", + VolumeSource: v1.VolumeSource{ + ConfigMap: &v1.ConfigMapVolumeSource{ + LocalObjectReference: v1.LocalObjectReference{ + Name: name, + }, + }, + }, + }, + { + Name: "secret", + VolumeSource: v1.VolumeSource{ + Secret: &v1.SecretVolumeSource{ + SecretName: name, + }, + }, + }, + } +} + +func getVolumeMounts(name string) []v1.VolumeMount { + return []v1.VolumeMount{ + { + MountPath: "etc/config", + Name: "configmap", + }, + { + MountPath: "etc/sec", + Name: "secret", + }, + } +} + func getPodTemplateSpecWithEnvVars(name string) v1.PodTemplateSpec { return v1.PodTemplateSpec{ ObjectMeta: metav1.ObjectMeta{ @@ -132,22 +187,7 @@ func getPodTemplateSpecWithEnvVarSources(name string) v1.PodTemplateSpec { { Image: "tutum/hello-world", Name: name, - EnvFrom: []v1.EnvFromSource{ - { - ConfigMapRef: &v1.ConfigMapEnvSource{ - LocalObjectReference: v1.LocalObjectReference{ - Name: name, - }, - }, - }, - { - SecretRef: &v1.SecretEnvSource{ - LocalObjectReference: v1.LocalObjectReference{ - Name: name, - }, - }, - }, - }, + EnvFrom: getEnvVarSources(name), }, }, }, @@ -170,38 +210,10 @@ func getPodTemplateSpecWithVolumes(name string) v1.PodTemplateSpec { Value: "test", }, }, - VolumeMounts: []v1.VolumeMount{ - { - MountPath: "etc/config", - Name: "configmap", - }, - { - MountPath: "etc/sec", - Name: "secret", - }, - }, - }, - }, - Volumes: []v1.Volume{ - { - Name: "configmap", - VolumeSource: v1.VolumeSource{ - ConfigMap: &v1.ConfigMapVolumeSource{ - LocalObjectReference: v1.LocalObjectReference{ - Name: name, - }, - }, - }, - }, - { - Name: "secret", - VolumeSource: v1.VolumeSource{ - Secret: &v1.SecretVolumeSource{ - SecretName: name, - }, - }, + VolumeMounts: getVolumeMounts(name), }, }, + Volumes: getVolumes(name), }, } } @@ -216,16 +228,7 @@ func getPodTemplateSpecWithInitContainer(name string) v1.PodTemplateSpec { { Image: "busybox", Name: "busyBox", - VolumeMounts: []v1.VolumeMount{ - { - MountPath: "etc/config", - Name: "configmap", - }, - { - MountPath: "etc/sec", - Name: "secret", - }, - }, + VolumeMounts: getVolumeMounts(name), }, }, Containers: []v1.Container{ @@ -240,22 +243,32 @@ func getPodTemplateSpecWithInitContainer(name string) v1.PodTemplateSpec { }, }, }, - Volumes: []v1.Volume{ + Volumes: getVolumes(name), + }, + } +} + +func getPodTemplateSpecWithInitContainerAndEnv(name string) v1.PodTemplateSpec { + return v1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{"secondLabel": "temp"}, + }, + Spec: v1.PodSpec{ + InitContainers: []v1.Container{ { - Name: "configmap", - VolumeSource: v1.VolumeSource{ - ConfigMap: &v1.ConfigMapVolumeSource{ - LocalObjectReference: v1.LocalObjectReference{ - Name: name, - }, - }, - }, + Image: "busybox", + Name: "busyBox", + EnvFrom: getEnvVarSources(name), }, + }, + Containers: []v1.Container{ { - Name: "secret", - VolumeSource: v1.VolumeSource{ - Secret: &v1.SecretVolumeSource{ - SecretName: name, + Image: "tutum/hello-world", + Name: name, + Env: []v1.EnvVar{ + { + Name: "BUCKET_NAME", + Value: "test", }, }, }, @@ -279,7 +292,7 @@ func GetDeployment(namespace string, deploymentName string) *v1beta1.Deployment } } -// GetDeploymentWithInitContainer provides deployment with init container +// GetDeploymentWithInitContainer provides deployment with init container and volumeMounts func GetDeploymentWithInitContainer(namespace string, deploymentName string) *v1beta1.Deployment { replicaset := int32(1) return &v1beta1.Deployment{ @@ -294,6 +307,21 @@ func GetDeploymentWithInitContainer(namespace string, deploymentName string) *v1 } } +// GetDeploymentWithInitContainerAndEnv provides deployment with init container and EnvSource +func GetDeploymentWithInitContainerAndEnv(namespace string, deploymentName string) *v1beta1.Deployment { + replicaset := int32(1) + return &v1beta1.Deployment{ + ObjectMeta: getObjectMeta(namespace, deploymentName, true), + Spec: v1beta1.DeploymentSpec{ + Replicas: &replicaset, + Strategy: v1beta1.DeploymentStrategy{ + Type: v1beta1.RollingUpdateDeploymentStrategyType, + }, + Template: getPodTemplateSpecWithInitContainerAndEnv(deploymentName), + }, + } +} + func GetDeploymentWithEnvVars(namespace string, deploymentName string) *v1beta1.Deployment { replicaset := int32(1) return &v1beta1.Deployment{ @@ -486,10 +514,15 @@ func CreateDeployment(client kubernetes.Interface, deploymentName string, namesp } // CreateDeploymentWithInitContainer creates a deployment in given namespace with init container and returns the Deployment -func CreateDeploymentWithInitContainer(client kubernetes.Interface, deploymentName string, namespace string) (*v1beta1.Deployment, error) { +func CreateDeploymentWithInitContainer(client kubernetes.Interface, deploymentName string, namespace string, volumeMount bool) (*v1beta1.Deployment, error) { logrus.Infof("Creating Deployment") deploymentClient := client.ExtensionsV1beta1().Deployments(namespace) - deploymentObj := GetDeploymentWithInitContainer(namespace, deploymentName) + var deploymentObj *v1beta1.Deployment + if volumeMount { + deploymentObj = GetDeploymentWithInitContainer(namespace, deploymentName) + } else { + deploymentObj = GetDeploymentWithInitContainerAndEnv(namespace, deploymentName) + } deployment, err := deploymentClient.Create(deploymentObj) time.Sleep(10 * time.Second) return deployment, err