Merge pull request from umohnani8/secrets

Use secret.items to create volume mounts if present
This commit is contained in:
OpenShift Merge Robot
2023-03-31 13:42:14 -04:00
committed by GitHub
2 changed files with 155 additions and 8 deletions
pkg/specgen/generate/kube
test/e2e

@ -147,20 +147,31 @@ func VolumeFromSecret(secretSource *v1.SecretVolumeSource, secretsManager *secre
return nil, err
}
data := &v1.Secret{}
secret := &v1.Secret{}
err = yaml.Unmarshal(secretByte, data)
err = yaml.Unmarshal(secretByte, secret)
if err != nil {
return nil, err
}
// add key: value pairs to the items array
for key, entry := range data.Data {
kv.Items[key] = entry
}
// If there are Items specified in the volumeSource, that overwrites the Data from the Secret
if len(secretSource.Items) > 0 {
for _, item := range secretSource.Items {
if val, ok := secret.Data[item.Key]; ok {
kv.Items[item.Path] = val
} else if val, ok := secret.StringData[item.Key]; ok {
kv.Items[item.Path] = []byte(val)
}
}
} else {
// add key: value pairs to the items array
for key, entry := range secret.Data {
kv.Items[key] = entry
}
for key, entry := range data.StringData {
kv.Items[key] = []byte(entry)
for key, entry := range secret.StringData {
kv.Items[key] = []byte(entry)
}
}
return kv, nil

@ -492,6 +492,19 @@ data:
{{ end }}
`
var secretYamlTemplate = `
apiVersion: v1
kind: Secret
metadata:
name: {{ .Name }}
data:
{{ with .Data }}
{{ range $key, $value := . }}
{{ $key }}: {{ $value }}
{{ end }}
{{ end }}
`
var persistentVolumeClaimYamlTemplate = `
apiVersion: v1
kind: PersistentVolumeClaim
@ -692,6 +705,18 @@ spec:
path: {{ .path }}
{{- end }}
{{- end }}
{{- end }}
{{- if (eq .VolumeType "Secret") }}
secret:
secretName: {{ .SecretVol.SecretName }}
optional: {{ .SecretVol.Optional }}
{{- with .SecretVol.Items }}
items:
{{- range . }}
- key: {{ .key }}
path: {{ .path }}
{{- end }}
{{- end }}
{{- end }}
{{ end }}
{{ end }}
@ -1019,6 +1044,7 @@ var (
defaultVolName = "testVol"
defaultDeploymentName = "testDeployment"
defaultConfigMapName = "testConfigMap"
defaultSecretName = "testSecret"
defaultPVCName = "testPVC"
seccompPwdEPERM = []byte(`{"defaultAction":"SCMP_ACT_ALLOW","syscalls":[{"name":"getcwd","action":"SCMP_ACT_ERRNO"}]}`)
// CPU Period in ms
@ -1041,6 +1067,8 @@ func getKubeYaml(kind string, object interface{}) (string, error) {
yamlTemplate = deploymentYamlTemplate
case "persistentVolumeClaim":
yamlTemplate = persistentVolumeClaimYamlTemplate
case "secret":
yamlTemplate = secretYamlTemplate
default:
return "", fmt.Errorf("unsupported kubernetes kind")
}
@ -1089,6 +1117,39 @@ func createSecret(podmanTest *PodmanTestIntegration, name string, value []byte)
Expect(secret).Should(Exit(0))
}
// Secret describes the options a kube yaml can be configured at secret level
type Secret struct {
Name string
Data map[string]string
}
func getSecret(options ...secretOption) *Secret {
secret := Secret{
Name: defaultSecretName,
Data: map[string]string{},
}
for _, option := range options {
option(&secret)
}
return &secret
}
type secretOption func(*Secret)
func withSecretName(name string) secretOption {
return func(secret *Secret) {
secret.Name = name
}
}
func withSecretData(k, v string) secretOption {
return func(secret *Secret) {
secret.Data[k] = base64.StdEncoding.EncodeToString([]byte(v))
}
}
// CM describes the options a kube yaml can be configured at configmap level
type CM struct {
Name string
@ -1568,6 +1629,12 @@ type ConfigMap struct {
Optional bool
}
type SecretVol struct {
SecretName string
Items []map[string]string
Optional bool
}
type EmptyDir struct{}
type Volume struct {
@ -1577,6 +1644,7 @@ type Volume struct {
PersistentVolumeClaim
ConfigMap
EmptyDir
SecretVol
}
// getHostPathVolume takes a type and a location for a HostPath
@ -1618,6 +1686,18 @@ func getConfigMapVolume(vName string, items []map[string]string, optional bool)
}
}
func getSecretVolume(vName string, items []map[string]string, optional bool) *Volume {
return &Volume{
VolumeType: "Secret",
Name: defaultVolName,
SecretVol: SecretVol{
SecretName: vName,
Items: items,
Optional: optional,
},
}
}
func getEmptyDirVolume() *Volume {
return &Volume{
VolumeType: "EmptyDir",
@ -4730,6 +4810,62 @@ ENV OPENJ9_JAVA_OPTIONS=%q
deleteAndTestSecret(podmanTest, "newsecret")
})
It("podman play kube secret as volume with no items", func() {
volumeName := "secretVol"
secret := getSecret(withSecretName(volumeName), withSecretData("FOO", "testuser"))
secretYaml, err := getKubeYaml("secret", secret)
Expect(err).ToNot(HaveOccurred())
ctr := getCtr(withVolumeMount("/test", "", false), withImage(BB))
pod := getPod(withVolume(getSecretVolume(volumeName, []map[string]string{}, false)), withCtr(ctr))
podYaml, err := getKubeYaml("pod", pod)
Expect(err).ToNot(HaveOccurred())
yamls := []string{secretYaml, podYaml}
err = generateMultiDocKubeYaml(yamls, kubeYaml)
Expect(err).ToNot(HaveOccurred())
kube := podmanTest.Podman([]string{"kube", "play", kubeYaml})
kube.WaitWithDefaultTimeout()
Expect(kube).Should(Exit(0))
secretData := podmanTest.Podman([]string{"exec", getCtrNameInPod(pod), "cat", "/test/FOO"})
secretData.WaitWithDefaultTimeout()
Expect(secretData).Should(Exit(0))
Expect(secretData.OutputToString()).To(Equal("testuser"))
})
It("podman play kube secret as volume with items", func() {
volumeName := "secretVol"
secret := getSecret(withSecretName(volumeName), withSecretData("FOO", "foobar"))
secretYaml, err := getKubeYaml("secret", secret)
Expect(err).ToNot(HaveOccurred())
volumeContents := []map[string]string{{
"key": "FOO",
"path": "BAR",
}}
ctr := getCtr(withVolumeMount("/test", "", false), withImage(BB))
pod := getPod(withVolume(getSecretVolume(volumeName, volumeContents, false)), withCtr(ctr))
podYaml, err := getKubeYaml("pod", pod)
Expect(err).ToNot(HaveOccurred())
yamls := []string{secretYaml, podYaml}
err = generateMultiDocKubeYaml(yamls, kubeYaml)
Expect(err).ToNot(HaveOccurred())
kube := podmanTest.Podman([]string{"kube", "play", kubeYaml})
kube.WaitWithDefaultTimeout()
Expect(kube).Should(Exit(0))
secretData := podmanTest.Podman([]string{"exec", getCtrNameInPod(pod), "cat", "/test/BAR"})
secretData.WaitWithDefaultTimeout()
Expect(secretData).Should(Exit(0))
Expect(secretData.OutputToString()).To(Equal("foobar"))
secretData = podmanTest.Podman([]string{"exec", getCtrNameInPod(pod), "cat", "/test/FOO"})
secretData.WaitWithDefaultTimeout()
Expect(secretData).Should(Not(Exit(0)))
})
It("podman play kube with disabled cgroup", func() {
SkipIfRunc(podmanTest, "Test not supported with runc, see issue #17436")
conffile := filepath.Join(podmanTest.TempDir, "container.conf")