Skip to content

Commit 7cc3971

Browse files
committed
Immutable secrets/configmaps tests
1 parent 9174905 commit 7cc3971

File tree

2 files changed

+108
-14
lines changed

2 files changed

+108
-14
lines changed

test/e2e/common/configmap_volume.go

Lines changed: 54 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import (
2323
"github.com/onsi/ginkgo"
2424
"github.com/onsi/gomega"
2525
"k8s.io/api/core/v1"
26+
apierrors "k8s.io/apimachinery/pkg/api/errors"
2627
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2728
"k8s.io/apimachinery/pkg/util/uuid"
2829
"k8s.io/kubernetes/test/e2e/framework"
@@ -549,19 +550,65 @@ var _ = ginkgo.Describe("[sig-storage] ConfigMap", func() {
549550

550551
})
551552

552-
//The pod is in pending during volume creation until the configMap objects are available
553-
//or until mount the configMap volume times out. There is no configMap object defined for the pod, so it should return timout exception unless it is marked optional.
554-
//Slow (~5 mins)
553+
// It should be forbidden to change data for configmaps marked as immutable, but
554+
// allowed to modify its metadata independently of its state.
555+
ginkgo.It("should be immutable if `immutable` field is set [Feature:ImmutableEphemeralVolume]", func() {
556+
name := "immutable"
557+
configMap := newConfigMap(f, name)
558+
559+
currentConfigMap, err := f.ClientSet.CoreV1().ConfigMaps(f.Namespace.Name).Create(configMap)
560+
framework.ExpectNoError(err, "Failed to create config map %q in namespace %q", configMap.Name, configMap.Namespace)
561+
562+
currentConfigMap.Data["data-4"] = "value-4"
563+
currentConfigMap, err = f.ClientSet.CoreV1().ConfigMaps(f.Namespace.Name).Update(currentConfigMap)
564+
framework.ExpectNoError(err, "Failed to update config map %q in namespace %q", configMap.Name, configMap.Namespace)
565+
566+
// Mark config map as immutable.
567+
trueVal := true
568+
currentConfigMap.Immutable = &trueVal
569+
currentConfigMap, err = f.ClientSet.CoreV1().ConfigMaps(f.Namespace.Name).Update(currentConfigMap)
570+
framework.ExpectNoError(err, "Failed to mark config map %q in namespace %q as immutable", configMap.Name, configMap.Namespace)
571+
572+
// Ensure data can't be changed now.
573+
currentConfigMap.Data["data-5"] = "value-5"
574+
_, err = f.ClientSet.CoreV1().ConfigMaps(f.Namespace.Name).Update(currentConfigMap)
575+
framework.ExpectEqual(apierrors.IsInvalid(err), true)
576+
577+
// Ensure config map can't be switched from immutable to mutable.
578+
currentConfigMap, err = f.ClientSet.CoreV1().ConfigMaps(f.Namespace.Name).Get(name, metav1.GetOptions{})
579+
framework.ExpectNoError(err, "Failed to get config map %q in namespace %q", configMap.Name, configMap.Namespace)
580+
framework.ExpectEqual(*currentConfigMap.Immutable, true)
581+
582+
falseVal := false
583+
currentConfigMap.Immutable = &falseVal
584+
_, err = f.ClientSet.CoreV1().ConfigMaps(f.Namespace.Name).Update(currentConfigMap)
585+
framework.ExpectEqual(apierrors.IsInvalid(err), true)
586+
587+
// Ensure that metadata can be changed.
588+
currentConfigMap, err = f.ClientSet.CoreV1().ConfigMaps(f.Namespace.Name).Get(name, metav1.GetOptions{})
589+
framework.ExpectNoError(err, "Failed to get config map %q in namespace %q", configMap.Name, configMap.Namespace)
590+
currentConfigMap.Labels = map[string]string{"label1": "value1"}
591+
_, err = f.ClientSet.CoreV1().ConfigMaps(f.Namespace.Name).Update(currentConfigMap)
592+
framework.ExpectNoError(err, "Failed to update config map %q in namespace %q", configMap.Name, configMap.Namespace)
593+
594+
// Ensure that immutable config map can be deleted.
595+
err = f.ClientSet.CoreV1().ConfigMaps(f.Namespace.Name).Delete(name, &metav1.DeleteOptions{})
596+
framework.ExpectNoError(err, "Failed to delete config map %q in namespace %q", configMap.Name, configMap.Namespace)
597+
})
598+
599+
// The pod is in pending during volume creation until the configMap objects are available
600+
// or until mount the configMap volume times out. There is no configMap object defined for the pod, so it should return timout exception unless it is marked optional.
601+
// Slow (~5 mins)
555602
ginkgo.It("Should fail non-optional pod creation due to configMap object does not exist [Slow]", func() {
556603
volumeMountPath := "/etc/configmap-volumes"
557604
podName := "pod-configmaps-" + string(uuid.NewUUID())
558605
err := createNonOptionalConfigMapPod(f, volumeMountPath, podName)
559606
framework.ExpectError(err, "created pod %q with non-optional configMap in namespace %q", podName, f.Namespace.Name)
560607
})
561608

562-
//ConfigMap object defined for the pod, If a key is specified which is not present in the ConfigMap,
609+
// ConfigMap object defined for the pod, If a key is specified which is not present in the ConfigMap,
563610
// the volume setup will error unless it is marked optional, during the pod creation.
564-
//Slow (~5 mins)
611+
// Slow (~5 mins)
565612
ginkgo.It("Should fail non-optional pod creation due to the key in the configMap object does not exist [Slow]", func() {
566613
volumeMountPath := "/etc/configmap-volumes"
567614
podName := "pod-configmaps-" + string(uuid.NewUUID())
@@ -754,7 +801,7 @@ func createNonOptionalConfigMapPod(f *framework.Framework, volumeMountPath, podN
754801
createContainerName := "createcm-volume-test"
755802
createVolumeName := "createcm-volume"
756803

757-
//creating a pod without configMap object created, by mentioning the configMap volume source's local reference name
804+
// creating a pod without configMap object created, by mentioning the configMap volume source's local reference name
758805
pod := &v1.Pod{
759806
ObjectMeta: metav1.ObjectMeta{
760807
Name: podName,
@@ -810,7 +857,7 @@ func createNonOptionalConfigMapPodWithConfig(f *framework.Framework, volumeMount
810857
if configMap, err = f.ClientSet.CoreV1().ConfigMaps(f.Namespace.Name).Create(configMap); err != nil {
811858
framework.Failf("unable to create test configMap %s: %v", configMap.Name, err)
812859
}
813-
//creating a pod with configMap object, but with different key which is not present in configMap object.
860+
// creating a pod with configMap object, but with different key which is not present in configMap object.
814861
pod := &v1.Pod{
815862
ObjectMeta: metav1.ObjectMeta{
816863
Name: podName,

test/e2e/common/secrets_volume.go

Lines changed: 54 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import (
2121
"path"
2222

2323
"k8s.io/api/core/v1"
24+
apierrors "k8s.io/apimachinery/pkg/api/errors"
2425
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2526
"k8s.io/apimachinery/pkg/util/uuid"
2627
"k8s.io/kubernetes/test/e2e/framework"
@@ -368,19 +369,65 @@ var _ = ginkgo.Describe("[sig-storage] Secrets", func() {
368369
gomega.Eventually(pollDeleteLogs, podLogTimeout, framework.Poll).Should(gomega.ContainSubstring("Error reading file /etc/secret-volumes/delete/data-1"))
369370
})
370371

371-
//The secret is in pending during volume creation until the secret objects are available
372-
//or until mount the secret volume times out. There is no secret object defined for the pod, so it should return timout exception unless it is marked optional.
373-
//Slow (~5 mins)
372+
// It should be forbidden to change data for secrets marked as immutable, but
373+
// allowed to modify its metadata independently of its state.
374+
ginkgo.It("should be immutable if `immutable` field is set [Feature:ImmutableEphemeralVolume]", func() {
375+
name := "immutable"
376+
secret := secretForTest(f.Namespace.Name, name)
377+
378+
currentSecret, err := f.ClientSet.CoreV1().Secrets(f.Namespace.Name).Create(secret)
379+
framework.ExpectNoError(err, "Failed to create secret %q in namespace %q", secret.Name, secret.Namespace)
380+
381+
currentSecret.Data["data-4"] = []byte("value-4\n")
382+
currentSecret, err = f.ClientSet.CoreV1().Secrets(f.Namespace.Name).Update(currentSecret)
383+
framework.ExpectNoError(err, "Failed to update secret %q in namespace %q", secret.Name, secret.Namespace)
384+
385+
// Mark secret as immutable.
386+
trueVal := true
387+
currentSecret.Immutable = &trueVal
388+
currentSecret, err = f.ClientSet.CoreV1().Secrets(f.Namespace.Name).Update(currentSecret)
389+
framework.ExpectNoError(err, "Failed to mark secret %q in namespace %q as immutable", secret.Name, secret.Namespace)
390+
391+
// Ensure data can't be changed now.
392+
currentSecret.Data["data-5"] = []byte("value-5\n")
393+
_, err = f.ClientSet.CoreV1().Secrets(f.Namespace.Name).Update(currentSecret)
394+
framework.ExpectEqual(apierrors.IsInvalid(err), true)
395+
396+
// Ensure secret can't be switched from immutable to mutable.
397+
currentSecret, err = f.ClientSet.CoreV1().Secrets(f.Namespace.Name).Get(name, metav1.GetOptions{})
398+
framework.ExpectNoError(err, "Failed to get secret %q in namespace %q", secret.Name, secret.Namespace)
399+
framework.ExpectEqual(*currentSecret.Immutable, true)
400+
401+
falseVal := false
402+
currentSecret.Immutable = &falseVal
403+
_, err = f.ClientSet.CoreV1().Secrets(f.Namespace.Name).Update(currentSecret)
404+
framework.ExpectEqual(apierrors.IsInvalid(err), true)
405+
406+
// Ensure that metadata can be changed.
407+
currentSecret, err = f.ClientSet.CoreV1().Secrets(f.Namespace.Name).Get(name, metav1.GetOptions{})
408+
framework.ExpectNoError(err, "Failed to get secret %q in namespace %q", secret.Name, secret.Namespace)
409+
currentSecret.Labels = map[string]string{"label1": "value1"}
410+
_, err = f.ClientSet.CoreV1().Secrets(f.Namespace.Name).Update(currentSecret)
411+
framework.ExpectNoError(err, "Failed to update secret %q in namespace %q", secret.Name, secret.Namespace)
412+
413+
// Ensure that immutable secret can be deleted.
414+
err = f.ClientSet.CoreV1().Secrets(f.Namespace.Name).Delete(name, &metav1.DeleteOptions{})
415+
framework.ExpectNoError(err, "Failed to delete secret %q in namespace %q", secret.Name, secret.Namespace)
416+
})
417+
418+
// The secret is in pending during volume creation until the secret objects are available
419+
// or until mount the secret volume times out. There is no secret object defined for the pod, so it should return timout exception unless it is marked optional.
420+
// Slow (~5 mins)
374421
ginkgo.It("Should fail non-optional pod creation due to secret object does not exist [Slow]", func() {
375422
volumeMountPath := "/etc/secret-volumes"
376423
podName := "pod-secrets-" + string(uuid.NewUUID())
377424
err := createNonOptionalSecretPod(f, volumeMountPath, podName)
378425
framework.ExpectError(err, "created pod %q with non-optional secret in namespace %q", podName, f.Namespace.Name)
379426
})
380427

381-
//Secret object defined for the pod, If a key is specified which is not present in the secret,
428+
// Secret object defined for the pod, If a key is specified which is not present in the secret,
382429
// the volume setup will error unless it is marked optional, during the pod creation.
383-
//Slow (~5 mins)
430+
// Slow (~5 mins)
384431
ginkgo.It("Should fail non-optional pod creation due to the key in the secret object does not exist [Slow]", func() {
385432
volumeMountPath := "/etc/secret-volumes"
386433
podName := "pod-secrets-" + string(uuid.NewUUID())
@@ -548,7 +595,7 @@ func createNonOptionalSecretPod(f *framework.Framework, volumeMountPath, podName
548595
createContainerName := "creates-volume-test"
549596
createVolumeName := "creates-volume"
550597

551-
//creating a pod without secret object created, by mentioning the secret volume source reference name
598+
// creating a pod without secret object created, by mentioning the secret volume source reference name
552599
pod := &v1.Pod{
553600
ObjectMeta: metav1.ObjectMeta{
554601
Name: podName,
@@ -603,7 +650,7 @@ func createNonOptionalSecretPodWithSecret(f *framework.Framework, volumeMountPat
603650
if secret, err = f.ClientSet.CoreV1().Secrets(f.Namespace.Name).Create(secret); err != nil {
604651
framework.Failf("unable to create test secret %s: %v", secret.Name, err)
605652
}
606-
//creating a pod with secret object, with the key which is not present in secret object.
653+
// creating a pod with secret object, with the key which is not present in secret object.
607654
pod := &v1.Pod{
608655
ObjectMeta: metav1.ObjectMeta{
609656
Name: podName,

0 commit comments

Comments
 (0)