
The following tests are not tagged because they are not really run in node e2e suites: * A subset of host path tests that required SSH access - should evaluate whether the tests should be moved to test/e2e_node * GCP volume tests - should evaluate whether these tests should be moved out of the common directly since they are not shared with the node e2e suite.
721 lines
22 KiB
Go
721 lines
22 KiB
Go
/*
|
|
Copyright 2016 The Kubernetes Authors.
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
*/
|
|
|
|
package common
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"path"
|
|
|
|
. "github.com/onsi/ginkgo"
|
|
. "github.com/onsi/gomega"
|
|
"k8s.io/api/core/v1"
|
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
|
"k8s.io/apimachinery/pkg/util/uuid"
|
|
"k8s.io/kubernetes/test/e2e/framework"
|
|
)
|
|
|
|
var _ = Describe("[sig-storage] ConfigMap", func() {
|
|
f := framework.NewDefaultFramework("configmap")
|
|
|
|
/*
|
|
Testname: configmap-nomap-simple
|
|
Description: Make sure config map without mappings works by mounting it
|
|
to a volume with a custom path (mapping) on the pod with no other settings.
|
|
*/
|
|
framework.ConformanceIt("should be consumable from pods in volume [NodeConformance]", func() {
|
|
doConfigMapE2EWithoutMappings(f, 0, 0, nil)
|
|
})
|
|
|
|
/*
|
|
Testname: configmap-nomap-default-mode
|
|
Description: Make sure config map without mappings works by mounting it
|
|
to a volume with a custom path (mapping) on the pod with defaultMode set
|
|
*/
|
|
framework.ConformanceIt("should be consumable from pods in volume with defaultMode set [NodeConformance]", func() {
|
|
defaultMode := int32(0400)
|
|
doConfigMapE2EWithoutMappings(f, 0, 0, &defaultMode)
|
|
})
|
|
|
|
It("should be consumable from pods in volume as non-root with defaultMode and fsGroup set [NodeFeature:FSGroup]", func() {
|
|
defaultMode := int32(0440) /* setting fsGroup sets mode to at least 440 */
|
|
doConfigMapE2EWithoutMappings(f, 1000, 1001, &defaultMode)
|
|
})
|
|
|
|
/*
|
|
Testname: configmap-nomap-user
|
|
Description: Make sure config map without mappings works by mounting it
|
|
to a volume with a custom path (mapping) on the pod as non-root.
|
|
*/
|
|
framework.ConformanceIt("should be consumable from pods in volume as non-root [NodeConformance]", func() {
|
|
doConfigMapE2EWithoutMappings(f, 1000, 0, nil)
|
|
})
|
|
|
|
It("should be consumable from pods in volume as non-root with FSGroup [NodeFeature:FSGroup]", func() {
|
|
doConfigMapE2EWithoutMappings(f, 1000, 1001, nil)
|
|
})
|
|
|
|
/*
|
|
Testname: configmap-simple-mapped
|
|
Description: Make sure config map works by mounting it to a volume with
|
|
a custom path (mapping) on the pod with no other settings and make sure
|
|
the pod actually consumes it.
|
|
*/
|
|
framework.ConformanceIt("should be consumable from pods in volume with mappings [NodeConformance]", func() {
|
|
doConfigMapE2EWithMappings(f, 0, 0, nil)
|
|
})
|
|
|
|
/*
|
|
Testname: configmap-with-item-mode-mapped
|
|
Description: Make sure config map works with an item mode (e.g. 0400)
|
|
for the config map item.
|
|
*/
|
|
framework.ConformanceIt("should be consumable from pods in volume with mappings and Item mode set [NodeConformance]", func() {
|
|
mode := int32(0400)
|
|
doConfigMapE2EWithMappings(f, 0, 0, &mode)
|
|
})
|
|
|
|
/*
|
|
Testname: configmap-simple-user-mapped
|
|
Description: Make sure config map works when it is mounted as non-root.
|
|
*/
|
|
framework.ConformanceIt("should be consumable from pods in volume with mappings as non-root [NodeConformance]", func() {
|
|
doConfigMapE2EWithMappings(f, 1000, 0, nil)
|
|
})
|
|
|
|
It("should be consumable from pods in volume with mappings as non-root with FSGroup [NodeFeature:FSGroup]", func() {
|
|
doConfigMapE2EWithMappings(f, 1000, 1001, nil)
|
|
})
|
|
|
|
/*
|
|
Testname: configmap-update-test
|
|
Description: Make sure update operation is working on config map and
|
|
the result is observed on volumes mounted in containers.
|
|
*/
|
|
framework.ConformanceIt("updates should be reflected in volume [NodeConformance]", func() {
|
|
podLogTimeout := framework.GetPodSecretUpdateTimeout(f.ClientSet)
|
|
containerTimeoutArg := fmt.Sprintf("--retry_time=%v", int(podLogTimeout.Seconds()))
|
|
|
|
name := "configmap-test-upd-" + string(uuid.NewUUID())
|
|
volumeName := "configmap-volume"
|
|
volumeMountPath := "/etc/configmap-volume"
|
|
containerName := "configmap-volume-test"
|
|
|
|
configMap := &v1.ConfigMap{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Namespace: f.Namespace.Name,
|
|
Name: name,
|
|
},
|
|
Data: map[string]string{
|
|
"data-1": "value-1",
|
|
},
|
|
}
|
|
|
|
By(fmt.Sprintf("Creating configMap with name %s", configMap.Name))
|
|
var err error
|
|
if configMap, err = f.ClientSet.CoreV1().ConfigMaps(f.Namespace.Name).Create(configMap); err != nil {
|
|
framework.Failf("unable to create test configMap %s: %v", configMap.Name, err)
|
|
}
|
|
|
|
pod := &v1.Pod{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: "pod-configmaps-" + string(uuid.NewUUID()),
|
|
},
|
|
Spec: v1.PodSpec{
|
|
Volumes: []v1.Volume{
|
|
{
|
|
Name: volumeName,
|
|
VolumeSource: v1.VolumeSource{
|
|
ConfigMap: &v1.ConfigMapVolumeSource{
|
|
LocalObjectReference: v1.LocalObjectReference{
|
|
Name: name,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
Containers: []v1.Container{
|
|
{
|
|
Name: containerName,
|
|
Image: mountImage,
|
|
Command: []string{"/mounttest", "--break_on_expected_content=false", containerTimeoutArg, "--file_content_in_loop=/etc/configmap-volume/data-1"},
|
|
VolumeMounts: []v1.VolumeMount{
|
|
{
|
|
Name: volumeName,
|
|
MountPath: volumeMountPath,
|
|
ReadOnly: true,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
RestartPolicy: v1.RestartPolicyNever,
|
|
},
|
|
}
|
|
By("Creating the pod")
|
|
f.PodClient().CreateSync(pod)
|
|
|
|
pollLogs := func() (string, error) {
|
|
return framework.GetPodLogs(f.ClientSet, f.Namespace.Name, pod.Name, containerName)
|
|
}
|
|
|
|
Eventually(pollLogs, podLogTimeout, framework.Poll).Should(ContainSubstring("value-1"))
|
|
|
|
By(fmt.Sprintf("Updating configmap %v", configMap.Name))
|
|
configMap.ResourceVersion = "" // to force update
|
|
configMap.Data["data-1"] = "value-2"
|
|
_, err = f.ClientSet.CoreV1().ConfigMaps(f.Namespace.Name).Update(configMap)
|
|
Expect(err).NotTo(HaveOccurred(), "Failed to update configmap %q in namespace %q", configMap.Name, f.Namespace.Name)
|
|
|
|
By("waiting to observe update in volume")
|
|
Eventually(pollLogs, podLogTimeout, framework.Poll).Should(ContainSubstring("value-2"))
|
|
})
|
|
|
|
It("binary data should be reflected in volume [NodeConformance]", func() {
|
|
podLogTimeout := framework.GetPodSecretUpdateTimeout(f.ClientSet)
|
|
containerTimeoutArg := fmt.Sprintf("--retry_time=%v", int(podLogTimeout.Seconds()))
|
|
|
|
name := "configmap-test-upd-" + string(uuid.NewUUID())
|
|
volumeName := "configmap-volume"
|
|
volumeMountPath := "/etc/configmap-volume"
|
|
containerName1 := "configmap-volume-data-test"
|
|
containerName2 := "configmap-volume-binary-test"
|
|
|
|
configMap := &v1.ConfigMap{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Namespace: f.Namespace.Name,
|
|
Name: name,
|
|
},
|
|
Data: map[string]string{
|
|
"data-1": "value-1",
|
|
},
|
|
BinaryData: map[string][]byte{
|
|
"dump.bin": {0xde, 0xca, 0xfe, 0xba, 0xd0, 0xfe, 0xff},
|
|
},
|
|
}
|
|
|
|
By(fmt.Sprintf("Creating configMap with name %s", configMap.Name))
|
|
var err error
|
|
if configMap, err = f.ClientSet.CoreV1().ConfigMaps(f.Namespace.Name).Create(configMap); err != nil {
|
|
framework.Failf("unable to create test configMap %s: %v", configMap.Name, err)
|
|
}
|
|
|
|
pod := &v1.Pod{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: "pod-configmaps-" + string(uuid.NewUUID()),
|
|
},
|
|
Spec: v1.PodSpec{
|
|
Volumes: []v1.Volume{
|
|
{
|
|
Name: volumeName,
|
|
VolumeSource: v1.VolumeSource{
|
|
ConfigMap: &v1.ConfigMapVolumeSource{
|
|
LocalObjectReference: v1.LocalObjectReference{
|
|
Name: name,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
Containers: []v1.Container{
|
|
{
|
|
Name: containerName1,
|
|
Image: mountImage,
|
|
Command: []string{"/mounttest", "--break_on_expected_content=false", containerTimeoutArg, "--file_content_in_loop=/etc/configmap-volume/data-1"},
|
|
VolumeMounts: []v1.VolumeMount{
|
|
{
|
|
Name: volumeName,
|
|
MountPath: volumeMountPath,
|
|
ReadOnly: true,
|
|
},
|
|
},
|
|
},
|
|
{
|
|
Name: containerName2,
|
|
Image: "busybox",
|
|
Command: []string{"hexdump", "-C", "/etc/configmap-volume/dump.bin"},
|
|
VolumeMounts: []v1.VolumeMount{
|
|
{
|
|
Name: volumeName,
|
|
MountPath: volumeMountPath,
|
|
ReadOnly: true,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
RestartPolicy: v1.RestartPolicyNever,
|
|
},
|
|
}
|
|
By("Creating the pod")
|
|
f.PodClient().CreateSync(pod)
|
|
|
|
pollLogs1 := func() (string, error) {
|
|
return framework.GetPodLogs(f.ClientSet, f.Namespace.Name, pod.Name, containerName1)
|
|
}
|
|
pollLogs2 := func() (string, error) {
|
|
return framework.GetPodLogs(f.ClientSet, f.Namespace.Name, pod.Name, containerName2)
|
|
}
|
|
|
|
By("Waiting for pod with text data")
|
|
Eventually(pollLogs1, podLogTimeout, framework.Poll).Should(ContainSubstring("value-1"))
|
|
By("Waiting for pod with binary data")
|
|
Eventually(pollLogs2, podLogTimeout, framework.Poll).Should(ContainSubstring("de ca fe ba d0 fe ff"))
|
|
})
|
|
|
|
/*
|
|
Testname: configmap-CUD-test
|
|
Description: Make sure Create, Update, Delete operations are all working
|
|
on config map and the result is observed on volumes mounted in containers.
|
|
*/
|
|
framework.ConformanceIt("optional updates should be reflected in volume [NodeConformance]", func() {
|
|
podLogTimeout := framework.GetPodSecretUpdateTimeout(f.ClientSet)
|
|
containerTimeoutArg := fmt.Sprintf("--retry_time=%v", int(podLogTimeout.Seconds()))
|
|
trueVal := true
|
|
volumeMountPath := "/etc/configmap-volumes"
|
|
|
|
deleteName := "cm-test-opt-del-" + string(uuid.NewUUID())
|
|
deleteContainerName := "delcm-volume-test"
|
|
deleteVolumeName := "deletecm-volume"
|
|
deleteConfigMap := &v1.ConfigMap{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Namespace: f.Namespace.Name,
|
|
Name: deleteName,
|
|
},
|
|
Data: map[string]string{
|
|
"data-1": "value-1",
|
|
},
|
|
}
|
|
|
|
updateName := "cm-test-opt-upd-" + string(uuid.NewUUID())
|
|
updateContainerName := "updcm-volume-test"
|
|
updateVolumeName := "updatecm-volume"
|
|
updateConfigMap := &v1.ConfigMap{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Namespace: f.Namespace.Name,
|
|
Name: updateName,
|
|
},
|
|
Data: map[string]string{
|
|
"data-1": "value-1",
|
|
},
|
|
}
|
|
|
|
createName := "cm-test-opt-create-" + string(uuid.NewUUID())
|
|
createContainerName := "createcm-volume-test"
|
|
createVolumeName := "createcm-volume"
|
|
createConfigMap := &v1.ConfigMap{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Namespace: f.Namespace.Name,
|
|
Name: createName,
|
|
},
|
|
Data: map[string]string{
|
|
"data-1": "value-1",
|
|
},
|
|
}
|
|
|
|
By(fmt.Sprintf("Creating configMap with name %s", deleteConfigMap.Name))
|
|
var err error
|
|
if deleteConfigMap, err = f.ClientSet.CoreV1().ConfigMaps(f.Namespace.Name).Create(deleteConfigMap); err != nil {
|
|
framework.Failf("unable to create test configMap %s: %v", deleteConfigMap.Name, err)
|
|
}
|
|
|
|
By(fmt.Sprintf("Creating configMap with name %s", updateConfigMap.Name))
|
|
if updateConfigMap, err = f.ClientSet.CoreV1().ConfigMaps(f.Namespace.Name).Create(updateConfigMap); err != nil {
|
|
framework.Failf("unable to create test configMap %s: %v", updateConfigMap.Name, err)
|
|
}
|
|
|
|
pod := &v1.Pod{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: "pod-configmaps-" + string(uuid.NewUUID()),
|
|
},
|
|
Spec: v1.PodSpec{
|
|
Volumes: []v1.Volume{
|
|
{
|
|
Name: deleteVolumeName,
|
|
VolumeSource: v1.VolumeSource{
|
|
ConfigMap: &v1.ConfigMapVolumeSource{
|
|
LocalObjectReference: v1.LocalObjectReference{
|
|
Name: deleteName,
|
|
},
|
|
Optional: &trueVal,
|
|
},
|
|
},
|
|
},
|
|
{
|
|
Name: updateVolumeName,
|
|
VolumeSource: v1.VolumeSource{
|
|
ConfigMap: &v1.ConfigMapVolumeSource{
|
|
LocalObjectReference: v1.LocalObjectReference{
|
|
Name: updateName,
|
|
},
|
|
Optional: &trueVal,
|
|
},
|
|
},
|
|
},
|
|
{
|
|
Name: createVolumeName,
|
|
VolumeSource: v1.VolumeSource{
|
|
ConfigMap: &v1.ConfigMapVolumeSource{
|
|
LocalObjectReference: v1.LocalObjectReference{
|
|
Name: createName,
|
|
},
|
|
Optional: &trueVal,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
Containers: []v1.Container{
|
|
{
|
|
Name: deleteContainerName,
|
|
Image: mountImage,
|
|
Command: []string{"/mounttest", "--break_on_expected_content=false", containerTimeoutArg, "--file_content_in_loop=/etc/configmap-volumes/delete/data-1"},
|
|
VolumeMounts: []v1.VolumeMount{
|
|
{
|
|
Name: deleteVolumeName,
|
|
MountPath: path.Join(volumeMountPath, "delete"),
|
|
ReadOnly: true,
|
|
},
|
|
},
|
|
},
|
|
{
|
|
Name: updateContainerName,
|
|
Image: mountImage,
|
|
Command: []string{"/mounttest", "--break_on_expected_content=false", containerTimeoutArg, "--file_content_in_loop=/etc/configmap-volumes/update/data-3"},
|
|
VolumeMounts: []v1.VolumeMount{
|
|
{
|
|
Name: updateVolumeName,
|
|
MountPath: path.Join(volumeMountPath, "update"),
|
|
ReadOnly: true,
|
|
},
|
|
},
|
|
},
|
|
{
|
|
Name: createContainerName,
|
|
Image: mountImage,
|
|
Command: []string{"/mounttest", "--break_on_expected_content=false", containerTimeoutArg, "--file_content_in_loop=/etc/configmap-volumes/create/data-1"},
|
|
VolumeMounts: []v1.VolumeMount{
|
|
{
|
|
Name: createVolumeName,
|
|
MountPath: path.Join(volumeMountPath, "create"),
|
|
ReadOnly: true,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
RestartPolicy: v1.RestartPolicyNever,
|
|
},
|
|
}
|
|
By("Creating the pod")
|
|
f.PodClient().CreateSync(pod)
|
|
|
|
pollCreateLogs := func() (string, error) {
|
|
return framework.GetPodLogs(f.ClientSet, f.Namespace.Name, pod.Name, createContainerName)
|
|
}
|
|
Eventually(pollCreateLogs, podLogTimeout, framework.Poll).Should(ContainSubstring("Error reading file /etc/configmap-volumes/create/data-1"))
|
|
|
|
pollUpdateLogs := func() (string, error) {
|
|
return framework.GetPodLogs(f.ClientSet, f.Namespace.Name, pod.Name, updateContainerName)
|
|
}
|
|
Eventually(pollUpdateLogs, podLogTimeout, framework.Poll).Should(ContainSubstring("Error reading file /etc/configmap-volumes/update/data-3"))
|
|
|
|
pollDeleteLogs := func() (string, error) {
|
|
return framework.GetPodLogs(f.ClientSet, f.Namespace.Name, pod.Name, deleteContainerName)
|
|
}
|
|
Eventually(pollDeleteLogs, podLogTimeout, framework.Poll).Should(ContainSubstring("value-1"))
|
|
|
|
By(fmt.Sprintf("Deleting configmap %v", deleteConfigMap.Name))
|
|
err = f.ClientSet.CoreV1().ConfigMaps(f.Namespace.Name).Delete(deleteConfigMap.Name, &metav1.DeleteOptions{})
|
|
Expect(err).NotTo(HaveOccurred(), "Failed to delete configmap %q in namespace %q", deleteConfigMap.Name, f.Namespace.Name)
|
|
|
|
By(fmt.Sprintf("Updating configmap %v", updateConfigMap.Name))
|
|
updateConfigMap.ResourceVersion = "" // to force update
|
|
delete(updateConfigMap.Data, "data-1")
|
|
updateConfigMap.Data["data-3"] = "value-3"
|
|
_, err = f.ClientSet.CoreV1().ConfigMaps(f.Namespace.Name).Update(updateConfigMap)
|
|
Expect(err).NotTo(HaveOccurred(), "Failed to update configmap %q in namespace %q", updateConfigMap.Name, f.Namespace.Name)
|
|
|
|
By(fmt.Sprintf("Creating configMap with name %s", createConfigMap.Name))
|
|
if createConfigMap, err = f.ClientSet.CoreV1().ConfigMaps(f.Namespace.Name).Create(createConfigMap); err != nil {
|
|
framework.Failf("unable to create test configMap %s: %v", createConfigMap.Name, err)
|
|
}
|
|
|
|
By("waiting to observe update in volume")
|
|
|
|
Eventually(pollCreateLogs, podLogTimeout, framework.Poll).Should(ContainSubstring("value-1"))
|
|
Eventually(pollUpdateLogs, podLogTimeout, framework.Poll).Should(ContainSubstring("value-3"))
|
|
Eventually(pollDeleteLogs, podLogTimeout, framework.Poll).Should(ContainSubstring("Error reading file /etc/configmap-volumes/delete/data-1"))
|
|
})
|
|
|
|
/*
|
|
Testname: configmap-multiple-volumes
|
|
Description: Make sure config map works when it mounted as two different
|
|
volumes on the same node.
|
|
*/
|
|
framework.ConformanceIt("should be consumable in multiple volumes in the same pod [NodeConformance]", func() {
|
|
var (
|
|
name = "configmap-test-volume-" + string(uuid.NewUUID())
|
|
volumeName = "configmap-volume"
|
|
volumeMountPath = "/etc/configmap-volume"
|
|
volumeName2 = "configmap-volume-2"
|
|
volumeMountPath2 = "/etc/configmap-volume-2"
|
|
configMap = newConfigMap(f, name)
|
|
)
|
|
|
|
By(fmt.Sprintf("Creating configMap with name %s", configMap.Name))
|
|
var err error
|
|
if configMap, err = f.ClientSet.CoreV1().ConfigMaps(f.Namespace.Name).Create(configMap); err != nil {
|
|
framework.Failf("unable to create test configMap %s: %v", configMap.Name, err)
|
|
}
|
|
|
|
pod := &v1.Pod{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: "pod-configmaps-" + string(uuid.NewUUID()),
|
|
},
|
|
Spec: v1.PodSpec{
|
|
Volumes: []v1.Volume{
|
|
{
|
|
Name: volumeName,
|
|
VolumeSource: v1.VolumeSource{
|
|
ConfigMap: &v1.ConfigMapVolumeSource{
|
|
LocalObjectReference: v1.LocalObjectReference{
|
|
Name: name,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
Name: volumeName2,
|
|
VolumeSource: v1.VolumeSource{
|
|
ConfigMap: &v1.ConfigMapVolumeSource{
|
|
LocalObjectReference: v1.LocalObjectReference{
|
|
Name: name,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
Containers: []v1.Container{
|
|
{
|
|
Name: "configmap-volume-test",
|
|
Image: mountImage,
|
|
Args: []string{"--file_content=/etc/configmap-volume/data-1"},
|
|
VolumeMounts: []v1.VolumeMount{
|
|
{
|
|
Name: volumeName,
|
|
MountPath: volumeMountPath,
|
|
ReadOnly: true,
|
|
},
|
|
{
|
|
Name: volumeName2,
|
|
MountPath: volumeMountPath2,
|
|
ReadOnly: true,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
RestartPolicy: v1.RestartPolicyNever,
|
|
},
|
|
}
|
|
|
|
f.TestContainerOutput("consume configMaps", pod, 0, []string{
|
|
"content of file \"/etc/configmap-volume/data-1\": value-1",
|
|
})
|
|
|
|
})
|
|
})
|
|
|
|
func newConfigMap(f *framework.Framework, name string) *v1.ConfigMap {
|
|
return &v1.ConfigMap{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Namespace: f.Namespace.Name,
|
|
Name: name,
|
|
},
|
|
Data: map[string]string{
|
|
"data-1": "value-1",
|
|
"data-2": "value-2",
|
|
"data-3": "value-3",
|
|
},
|
|
}
|
|
}
|
|
|
|
func doConfigMapE2EWithoutMappings(f *framework.Framework, uid, fsGroup int64, defaultMode *int32) {
|
|
userID := int64(uid)
|
|
groupID := int64(fsGroup)
|
|
|
|
var (
|
|
name = "configmap-test-volume-" + string(uuid.NewUUID())
|
|
volumeName = "configmap-volume"
|
|
volumeMountPath = "/etc/configmap-volume"
|
|
configMap = newConfigMap(f, name)
|
|
)
|
|
|
|
By(fmt.Sprintf("Creating configMap with name %s", configMap.Name))
|
|
var err error
|
|
if configMap, err = f.ClientSet.CoreV1().ConfigMaps(f.Namespace.Name).Create(configMap); err != nil {
|
|
framework.Failf("unable to create test configMap %s: %v", configMap.Name, err)
|
|
}
|
|
|
|
one := int64(1)
|
|
pod := &v1.Pod{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: "pod-configmaps-" + string(uuid.NewUUID()),
|
|
},
|
|
Spec: v1.PodSpec{
|
|
SecurityContext: &v1.PodSecurityContext{},
|
|
Volumes: []v1.Volume{
|
|
{
|
|
Name: volumeName,
|
|
VolumeSource: v1.VolumeSource{
|
|
ConfigMap: &v1.ConfigMapVolumeSource{
|
|
LocalObjectReference: v1.LocalObjectReference{
|
|
Name: name,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
Containers: []v1.Container{
|
|
{
|
|
Name: "configmap-volume-test",
|
|
Image: mountImage,
|
|
Args: []string{
|
|
"--file_content=/etc/configmap-volume/data-1",
|
|
"--file_mode=/etc/configmap-volume/data-1"},
|
|
VolumeMounts: []v1.VolumeMount{
|
|
{
|
|
Name: volumeName,
|
|
MountPath: volumeMountPath,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
RestartPolicy: v1.RestartPolicyNever,
|
|
TerminationGracePeriodSeconds: &one,
|
|
},
|
|
}
|
|
|
|
if userID != 0 {
|
|
pod.Spec.SecurityContext.RunAsUser = &userID
|
|
}
|
|
|
|
if groupID != 0 {
|
|
pod.Spec.SecurityContext.FSGroup = &groupID
|
|
}
|
|
|
|
if defaultMode != nil {
|
|
pod.Spec.Volumes[0].VolumeSource.ConfigMap.DefaultMode = defaultMode
|
|
} else {
|
|
mode := int32(0644)
|
|
defaultMode = &mode
|
|
}
|
|
|
|
modeString := fmt.Sprintf("%v", os.FileMode(*defaultMode))
|
|
output := []string{
|
|
"content of file \"/etc/configmap-volume/data-1\": value-1",
|
|
"mode of file \"/etc/configmap-volume/data-1\": " + modeString,
|
|
}
|
|
f.TestContainerOutput("consume configMaps", pod, 0, output)
|
|
}
|
|
|
|
func doConfigMapE2EWithMappings(f *framework.Framework, uid, fsGroup int64, itemMode *int32) {
|
|
userID := int64(uid)
|
|
groupID := int64(fsGroup)
|
|
|
|
var (
|
|
name = "configmap-test-volume-map-" + string(uuid.NewUUID())
|
|
volumeName = "configmap-volume"
|
|
volumeMountPath = "/etc/configmap-volume"
|
|
configMap = newConfigMap(f, name)
|
|
)
|
|
|
|
By(fmt.Sprintf("Creating configMap with name %s", configMap.Name))
|
|
|
|
var err error
|
|
if configMap, err = f.ClientSet.CoreV1().ConfigMaps(f.Namespace.Name).Create(configMap); err != nil {
|
|
framework.Failf("unable to create test configMap %s: %v", configMap.Name, err)
|
|
}
|
|
|
|
one := int64(1)
|
|
pod := &v1.Pod{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: "pod-configmaps-" + string(uuid.NewUUID()),
|
|
},
|
|
Spec: v1.PodSpec{
|
|
SecurityContext: &v1.PodSecurityContext{},
|
|
Volumes: []v1.Volume{
|
|
{
|
|
Name: volumeName,
|
|
VolumeSource: v1.VolumeSource{
|
|
ConfigMap: &v1.ConfigMapVolumeSource{
|
|
LocalObjectReference: v1.LocalObjectReference{
|
|
Name: name,
|
|
},
|
|
Items: []v1.KeyToPath{
|
|
{
|
|
Key: "data-2",
|
|
Path: "path/to/data-2",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
Containers: []v1.Container{
|
|
{
|
|
Name: "configmap-volume-test",
|
|
Image: mountImage,
|
|
Args: []string{"--file_content=/etc/configmap-volume/path/to/data-2",
|
|
"--file_mode=/etc/configmap-volume/path/to/data-2"},
|
|
VolumeMounts: []v1.VolumeMount{
|
|
{
|
|
Name: volumeName,
|
|
MountPath: volumeMountPath,
|
|
ReadOnly: true,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
RestartPolicy: v1.RestartPolicyNever,
|
|
TerminationGracePeriodSeconds: &one,
|
|
},
|
|
}
|
|
|
|
if userID != 0 {
|
|
pod.Spec.SecurityContext.RunAsUser = &userID
|
|
}
|
|
|
|
if groupID != 0 {
|
|
pod.Spec.SecurityContext.FSGroup = &groupID
|
|
}
|
|
|
|
if itemMode != nil {
|
|
pod.Spec.Volumes[0].VolumeSource.ConfigMap.Items[0].Mode = itemMode
|
|
} else {
|
|
mode := int32(0644)
|
|
itemMode = &mode
|
|
}
|
|
|
|
// Just check file mode if fsGroup is not set. If fsGroup is set, the
|
|
// final mode is adjusted and we are not testing that case.
|
|
output := []string{
|
|
"content of file \"/etc/configmap-volume/path/to/data-2\": value-2",
|
|
}
|
|
if fsGroup == 0 {
|
|
modeString := fmt.Sprintf("%v", os.FileMode(*itemMode))
|
|
output = append(output, "mode of file \"/etc/configmap-volume/path/to/data-2\": "+modeString)
|
|
}
|
|
f.TestContainerOutput("consume configMaps", pod, 0, output)
|
|
}
|