mirror of
https://github.com/containers/podman.git
synced 2025-07-23 06:13:25 +08:00
Merge pull request #17995 from umohnani8/secrets
Use secret.items to create volume mounts if present
This commit is contained in:
@ -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")
|
||||
|
Reference in New Issue
Block a user