diff --git a/pkg/domain/infra/abi/play.go b/pkg/domain/infra/abi/play.go index e73bf6614d60..b561f7b62d29 100644 --- a/pkg/domain/infra/abi/play.go +++ b/pkg/domain/infra/abi/play.go @@ -3,6 +3,7 @@ package abi import ( "bytes" "context" + "encoding/json" "errors" "fmt" "io" @@ -1213,7 +1214,15 @@ func (ic *ContainerEngine) playKubeSecret(secret *v1.Secret) (*entities.SecretCr return nil, err } - data, err := yaml.Marshal(secret) + if len(secret.StringData) > 0 { + if secret.Data == nil { + secret.Data = make(map[string][]byte) + } + for key, val := range secret.StringData { + secret.Data[key] = []byte(val) + } + } + data, err := json.Marshal(secret.Data) if err != nil { return nil, err } diff --git a/pkg/specgen/generate/kube/play_test.go b/pkg/specgen/generate/kube/play_test.go index 3ad80f8b1eb1..0f3abe46ff88 100644 --- a/pkg/specgen/generate/kube/play_test.go +++ b/pkg/specgen/generate/kube/play_test.go @@ -34,6 +34,14 @@ func createSecrets(t *testing.T, d string) *secrets.SecretsManager { } for _, s := range k8sSecrets { + if len(s.StringData) > 0 { + if s.Data == nil { + s.Data = make(map[string][]byte) + } + for key, val := range s.StringData { + s.Data[key] = []byte(val) + } + } data, err := json.Marshal(s.Data) assert.NoError(t, err) @@ -345,6 +353,42 @@ func TestEnvVarsFrom(t *testing.T) { "myvar": "foo", }, }, + { + "SecretExistsMultipleDataEntries", + v1.EnvFromSource{ + SecretRef: &v1.SecretEnvSource{ + LocalObjectReference: v1.LocalObjectReference{ + Name: "multi-data", + }, + }, + }, + CtrSpecGenOptions{ + SecretsManager: secretsManager, + }, + true, + map[string]string{ + "myvar": "foo", + "myvar1": "foo1", + }, + }, + { + "SecretExistsMultipleStringDataEntries", + v1.EnvFromSource{ + SecretRef: &v1.SecretEnvSource{ + LocalObjectReference: v1.LocalObjectReference{ + Name: "multi-stringdata", + }, + }, + }, + CtrSpecGenOptions{ + SecretsManager: secretsManager, + }, + true, + map[string]string{ + "myvar": "foo", + "myvar1": "foo1", + }, + }, { "SecretDoesNotExist", v1.EnvFromSource{ @@ -1087,6 +1131,30 @@ var ( "myvar": []byte("foo"), }, }, + { + TypeMeta: v12.TypeMeta{ + Kind: "Secret", + }, + ObjectMeta: v12.ObjectMeta{ + Name: "multi-data", + }, + Data: map[string][]byte{ + "myvar": []byte("foo"), + "myvar1": []byte("foo1"), + }, + }, + { + TypeMeta: v12.TypeMeta{ + Kind: "Secret", + }, + ObjectMeta: v12.ObjectMeta{ + Name: "multi-stringdata", + }, + StringData: map[string]string{ + "myvar": string("foo"), + "myvar1": string("foo1"), + }, + }, } cpuInt = 4 diff --git a/pkg/specgen/generate/kube/volume.go b/pkg/specgen/generate/kube/volume.go index 4e98305c5d32..2e9f3705c0a0 100644 --- a/pkg/specgen/generate/kube/volume.go +++ b/pkg/specgen/generate/kube/volume.go @@ -1,6 +1,7 @@ package kube import ( + "encoding/json" "errors" "fmt" "os" @@ -9,10 +10,8 @@ import ( "github.com/containers/common/pkg/secrets" "github.com/containers/podman/v4/libpod" v1 "github.com/containers/podman/v4/pkg/k8s.io/api/core/v1" - metav1 "github.com/containers/podman/v4/pkg/k8s.io/apimachinery/pkg/apis/meta/v1" "github.com/sirupsen/logrus" - "gopkg.in/yaml.v3" ) const ( @@ -137,24 +136,8 @@ func VolumeFromSecret(secretSource *v1.SecretVolumeSource, secretsManager *secre return nil, err } - // unmarshaling directly into a v1.secret creates type mismatch errors - // use a more friendly, string only secret struct. - type KubeSecret struct { - metav1.TypeMeta `json:",inline"` - // +optional - metav1.ObjectMeta `json:"metadata,omitempty"` - // +optional - Immutable *bool `json:"immutable,omitempty"` - Data map[string]string `json:"data,omitempty"` - // +optional - StringData map[string]string `json:"stringData,omitempty"` - // +optional - Type string `json:"type,omitempty"` - } - - data := &KubeSecret{} - - err = yaml.Unmarshal(secretByte, data) + data := make(map[string][]byte) + err = json.Unmarshal(secretByte, &data) if err != nil { return nil, err } @@ -166,8 +149,8 @@ func VolumeFromSecret(secretSource *v1.SecretVolumeSource, secretsManager *secre kv.Items = make(map[string][]byte) // add key: value pairs to the items array - for key, entry := range data.Data { - kv.Items[key] = []byte(entry) + for key, entry := range data { + kv.Items[key] = entry } return kv, nil } diff --git a/test/e2e/play_kube_test.go b/test/e2e/play_kube_test.go index 7fbc9305fcbe..c07ee00234c9 100644 --- a/test/e2e/play_kube_test.go +++ b/test/e2e/play_kube_test.go @@ -3,6 +3,7 @@ package integration import ( "bytes" "context" + "encoding/base64" "encoding/json" "fmt" "net" @@ -48,9 +49,11 @@ metadata: name: newsecrettwo type: Opaque data: - username: Y2RvZXJuCg== + username: Y2RvZXJu password: dGVzdGluZ3Rlc3RpbmcK note: a3ViZSBzZWNyZXRzIGFyZSBjb29sIQo= +stringData: + plain_note: This is a test ` var secretPodYaml = ` @@ -89,6 +92,9 @@ spec: - name: bar mountPath: /etc/bar readOnly: true + - name: baz + mountPath: /etc/baz + readOnly: true volumes: - name: foo secret: @@ -98,6 +104,10 @@ spec: secret: secretName: newsecrettwo optional: false + - name: baz + secret: + secretName: newsecrettwo + optional: false ` var unknownKindYaml = ` @@ -4220,7 +4230,8 @@ ENV OPENJ9_JAVA_OPTIONS=%q exec := podmanTest.Podman([]string{"exec", "-it", "mypod-myctr", "cat", "/etc/foo/username"}) exec.WaitWithDefaultTimeout() Expect(exec).Should(Exit(0)) - Expect(exec.OutputToString()).Should(ContainSubstring("dXNlcg==")) + username, _ := base64.StdEncoding.DecodeString("dXNlcg==") + Expect(exec.OutputToString()).Should(ContainSubstring(string(username))) secretRm := podmanTest.Podman([]string{"secret", "rm", "newsecret"}) secretRm.WaitWithDefaultTimeout() @@ -4258,12 +4269,19 @@ ENV OPENJ9_JAVA_OPTIONS=%q exec = podmanTest.Podman([]string{"exec", "-it", "mypod2-myctr", "cat", "/etc/foo/username"}) exec.WaitWithDefaultTimeout() Expect(exec).Should(Exit(0)) - Expect(exec.OutputToString()).Should(ContainSubstring("dXNlcg==")) + username, _ = base64.StdEncoding.DecodeString("dXNlcg==") + Expect(exec.OutputToString()).Should(ContainSubstring(string(username))) exec = podmanTest.Podman([]string{"exec", "-it", "mypod2-myctr", "cat", "/etc/bar/username"}) exec.WaitWithDefaultTimeout() Expect(exec).Should(Exit(0)) - Expect(exec.OutputToString()).Should(ContainSubstring("Y2RvZXJuCg==")) + username, _ = base64.StdEncoding.DecodeString("Y2RvZXJu") + Expect(exec.OutputToString()).Should(ContainSubstring(string(username))) + + exec = podmanTest.Podman([]string{"exec", "-it", "mypod2-myctr", "cat", "/etc/baz/plain_note"}) + exec.WaitWithDefaultTimeout() + Expect(exec).Should(Exit(0)) + Expect(exec.OutputToString()).Should(ContainSubstring("This is a test")) })