mirror of https://github.com/containers/podman.git
Kube Play - Support multi-doc YAML files for configmap argument
Read the entire YAML file in case of a multi-doc file Adjust the unit test Add a system test Add comment in the man page Signed-off-by: Ygal Blum <ygal.blum@gmail.com>
This commit is contained in:
parent
d7f9ef253a
commit
26f1e95ab4
|
@ -174,6 +174,7 @@ Build images even if they are found in the local storage. Use `--build=false` to
|
||||||
Use Kubernetes configmap YAML at path to provide a source for environment variable values within the containers of the pod. (This option is not available with the remote Podman client)
|
Use Kubernetes configmap YAML at path to provide a source for environment variable values within the containers of the pod. (This option is not available with the remote Podman client)
|
||||||
|
|
||||||
Note: The *--configmap* option can be used multiple times or a comma-separated list of paths can be used to pass multiple Kubernetes configmap YAMLs.
|
Note: The *--configmap* option can be used multiple times or a comma-separated list of paths can be used to pass multiple Kubernetes configmap YAMLs.
|
||||||
|
The YAML file may be in a multi-doc YAML format. But, it must container only configmaps
|
||||||
|
|
||||||
#### **--context-dir**=*path*
|
#### **--context-dir**=*path*
|
||||||
|
|
||||||
|
|
|
@ -524,16 +524,18 @@ func (ic *ContainerEngine) playKubePod(ctx context.Context, podName string, podY
|
||||||
}
|
}
|
||||||
defer f.Close()
|
defer f.Close()
|
||||||
|
|
||||||
cm, err := readConfigMapFromFile(f)
|
cms, err := readConfigMapFromFile(f)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, fmt.Errorf("%q: %w", p, err)
|
return nil, nil, fmt.Errorf("%q: %w", p, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, present := configMapIndex[cm.Name]; present {
|
for _, cm := range cms {
|
||||||
return nil, nil, fmt.Errorf("ambiguous configuration: the same config map %s is present in YAML and in --configmaps %s file", cm.Name, p)
|
if _, present := configMapIndex[cm.Name]; present {
|
||||||
}
|
return nil, nil, fmt.Errorf("ambiguous configuration: the same config map %s is present in YAML and in --configmaps %s file", cm.Name, p)
|
||||||
|
}
|
||||||
|
|
||||||
configMaps = append(configMaps, cm)
|
configMaps = append(configMaps, cm)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mountLabel, err := getMountLabel(podYAML.Spec.SecurityContext)
|
mountLabel, err := getMountLabel(podYAML.Spec.SecurityContext)
|
||||||
|
@ -1152,23 +1154,38 @@ func (ic *ContainerEngine) importVolume(ctx context.Context, vol *libpod.Volume,
|
||||||
}
|
}
|
||||||
|
|
||||||
// readConfigMapFromFile returns a kubernetes configMap obtained from --configmap flag
|
// readConfigMapFromFile returns a kubernetes configMap obtained from --configmap flag
|
||||||
func readConfigMapFromFile(r io.Reader) (v1.ConfigMap, error) {
|
func readConfigMapFromFile(r io.Reader) ([]v1.ConfigMap, error) {
|
||||||
var cm v1.ConfigMap
|
configMaps := make([]v1.ConfigMap, 0)
|
||||||
|
|
||||||
content, err := io.ReadAll(r)
|
content, err := io.ReadAll(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return cm, fmt.Errorf("unable to read ConfigMap YAML content: %w", err)
|
return nil, fmt.Errorf("unable to read ConfigMap YAML content: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := yaml.Unmarshal(content, &cm); err != nil {
|
// split yaml document
|
||||||
return cm, fmt.Errorf("unable to read YAML as Kube ConfigMap: %w", err)
|
documentList, err := splitMultiDocYAML(content)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("unable to read as kube YAML: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if cm.Kind != "ConfigMap" {
|
for _, document := range documentList {
|
||||||
return cm, fmt.Errorf("invalid YAML kind: %q. [ConfigMap] is the only supported by --configmap", cm.Kind)
|
kind, err := getKubeKind(document)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("unable to read as kube YAML: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if kind != "ConfigMap" {
|
||||||
|
return nil, fmt.Errorf("invalid YAML kind: %q. [ConfigMap] is the only supported by --configmap", kind)
|
||||||
|
}
|
||||||
|
|
||||||
|
var configMap v1.ConfigMap
|
||||||
|
if err := yaml.Unmarshal(document, &configMap); err != nil {
|
||||||
|
return nil, fmt.Errorf("unable to read YAML as Kube ConfigMap: %w", err)
|
||||||
|
}
|
||||||
|
configMaps = append(configMaps, configMap)
|
||||||
}
|
}
|
||||||
|
|
||||||
return cm, nil
|
return configMaps, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// splitMultiDocYAML reads multiple documents in a YAML file and
|
// splitMultiDocYAML reads multiple documents in a YAML file and
|
||||||
|
|
|
@ -15,7 +15,7 @@ func TestReadConfigMapFromFile(t *testing.T) {
|
||||||
configMapContent string
|
configMapContent string
|
||||||
expectError bool
|
expectError bool
|
||||||
expectedErrorMsg string
|
expectedErrorMsg string
|
||||||
expected v1.ConfigMap
|
expected []v1.ConfigMap
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
"ValidConfigMap",
|
"ValidConfigMap",
|
||||||
|
@ -29,16 +29,18 @@ data:
|
||||||
`,
|
`,
|
||||||
false,
|
false,
|
||||||
"",
|
"",
|
||||||
v1.ConfigMap{
|
[]v1.ConfigMap{
|
||||||
TypeMeta: v12.TypeMeta{
|
{
|
||||||
Kind: "ConfigMap",
|
TypeMeta: v12.TypeMeta{
|
||||||
APIVersion: "v1",
|
Kind: "ConfigMap",
|
||||||
},
|
APIVersion: "v1",
|
||||||
ObjectMeta: v12.ObjectMeta{
|
},
|
||||||
Name: "foo",
|
ObjectMeta: v12.ObjectMeta{
|
||||||
},
|
Name: "foo",
|
||||||
Data: map[string]string{
|
},
|
||||||
"myvar": "foo",
|
Data: map[string]string{
|
||||||
|
"myvar": "foo",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -54,8 +56,8 @@ data:
|
||||||
myvar: foo
|
myvar: foo
|
||||||
`,
|
`,
|
||||||
true,
|
true,
|
||||||
"unable to read YAML as Kube ConfigMap",
|
"unable to read as kube YAML",
|
||||||
v1.ConfigMap{},
|
[]v1.ConfigMap{},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"InvalidKind",
|
"InvalidKind",
|
||||||
|
@ -69,7 +71,7 @@ data:
|
||||||
`,
|
`,
|
||||||
true,
|
true,
|
||||||
"invalid YAML kind",
|
"invalid YAML kind",
|
||||||
v1.ConfigMap{},
|
[]v1.ConfigMap{},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ValidBinaryDataConfigMap",
|
"ValidBinaryDataConfigMap",
|
||||||
|
@ -83,15 +85,64 @@ binaryData:
|
||||||
`,
|
`,
|
||||||
false,
|
false,
|
||||||
"",
|
"",
|
||||||
v1.ConfigMap{
|
[]v1.ConfigMap{
|
||||||
TypeMeta: v12.TypeMeta{
|
{
|
||||||
Kind: "ConfigMap",
|
TypeMeta: v12.TypeMeta{
|
||||||
APIVersion: "v1",
|
Kind: "ConfigMap",
|
||||||
|
APIVersion: "v1",
|
||||||
|
},
|
||||||
|
ObjectMeta: v12.ObjectMeta{
|
||||||
|
Name: "foo",
|
||||||
|
},
|
||||||
|
BinaryData: map[string][]byte{"data.zip": {0x50, 0x4b, 0x03, 0x04, 0x14, 0x00, 0x08, 0x00, 0x08, 0x00, 0xc9, 0xbb, 0x4a, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x08, 0x00, 0x20, 0x00, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x74, 0x78, 0x74, 0x55, 0x54, 0x0d, 0x00, 0x07, 0xea, 0x8e, 0x44, 0x63, 0x3b, 0x8f, 0x44, 0x63, 0xea, 0x8e, 0x44, 0x63, 0x75, 0x78, 0x0b, 0x00, 0x01, 0x04, 0xe8, 0x03, 0x00, 0x00, 0x04, 0xe8, 0x03, 0x00, 0x00, 0x4b, 0xca, 0xcc, 0x4b, 0x2c, 0xaa, 0x54, 0x48, 0x49, 0x2c, 0x49, 0xe4, 0x02, 0x00, 0x50, 0x4b, 0x07, 0x08, 0xdd, 0x09, 0xd9, 0xa0, 0x0e, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x50, 0x4b, 0x01, 0x02, 0x14, 0x03, 0x14, 0x00, 0x08, 0x00, 0x08, 0x00, 0xc9, 0xbb, 0x4a, 0x55, 0xdd, 0x09, 0xd9, 0xa0, 0x0e, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x08, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa4, 0x81, 0x00, 0x00, 0x00, 0x00, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x74, 0x78, 0x74, 0x55, 0x54, 0x0d, 0x00, 0x07, 0xea, 0x8e, 0x44, 0x63, 0x3b, 0x8f, 0x44, 0x63, 0xea, 0x8e, 0x44, 0x63, 0x75, 0x78, 0x0b, 0x00, 0x01, 0x04, 0xe8, 0x03, 0x00, 0x00, 0x04, 0xe8, 0x03, 0x00, 0x00, 0x50, 0x4b, 0x05, 0x06, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x56, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00}},
|
||||||
},
|
},
|
||||||
ObjectMeta: v12.ObjectMeta{
|
},
|
||||||
Name: "foo",
|
},
|
||||||
|
{
|
||||||
|
"MultiDocConfigMapFile",
|
||||||
|
`
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: ConfigMap
|
||||||
|
metadata:
|
||||||
|
name: foo
|
||||||
|
data:
|
||||||
|
myvar: foo
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: ConfigMap
|
||||||
|
metadata:
|
||||||
|
name: bar
|
||||||
|
data:
|
||||||
|
myvar: bar
|
||||||
|
`,
|
||||||
|
false,
|
||||||
|
"",
|
||||||
|
[]v1.ConfigMap{
|
||||||
|
{
|
||||||
|
TypeMeta: v12.TypeMeta{
|
||||||
|
Kind: "ConfigMap",
|
||||||
|
APIVersion: "v1",
|
||||||
|
},
|
||||||
|
ObjectMeta: v12.ObjectMeta{
|
||||||
|
Name: "foo",
|
||||||
|
},
|
||||||
|
Data: map[string]string{
|
||||||
|
"myvar": "foo",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
TypeMeta: v12.TypeMeta{
|
||||||
|
Kind: "ConfigMap",
|
||||||
|
APIVersion: "v1",
|
||||||
|
},
|
||||||
|
ObjectMeta: v12.ObjectMeta{
|
||||||
|
Name: "bar",
|
||||||
|
},
|
||||||
|
Data: map[string]string{
|
||||||
|
"myvar": "bar",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
BinaryData: map[string][]byte{"data.zip": {0x50, 0x4b, 0x03, 0x04, 0x14, 0x00, 0x08, 0x00, 0x08, 0x00, 0xc9, 0xbb, 0x4a, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x08, 0x00, 0x20, 0x00, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x74, 0x78, 0x74, 0x55, 0x54, 0x0d, 0x00, 0x07, 0xea, 0x8e, 0x44, 0x63, 0x3b, 0x8f, 0x44, 0x63, 0xea, 0x8e, 0x44, 0x63, 0x75, 0x78, 0x0b, 0x00, 0x01, 0x04, 0xe8, 0x03, 0x00, 0x00, 0x04, 0xe8, 0x03, 0x00, 0x00, 0x4b, 0xca, 0xcc, 0x4b, 0x2c, 0xaa, 0x54, 0x48, 0x49, 0x2c, 0x49, 0xe4, 0x02, 0x00, 0x50, 0x4b, 0x07, 0x08, 0xdd, 0x09, 0xd9, 0xa0, 0x0e, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x50, 0x4b, 0x01, 0x02, 0x14, 0x03, 0x14, 0x00, 0x08, 0x00, 0x08, 0x00, 0xc9, 0xbb, 0x4a, 0x55, 0xdd, 0x09, 0xd9, 0xa0, 0x0e, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x08, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa4, 0x81, 0x00, 0x00, 0x00, 0x00, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x74, 0x78, 0x74, 0x55, 0x54, 0x0d, 0x00, 0x07, 0xea, 0x8e, 0x44, 0x63, 0x3b, 0x8f, 0x44, 0x63, 0xea, 0x8e, 0x44, 0x63, 0x75, 0x78, 0x0b, 0x00, 0x01, 0x04, 0xe8, 0x03, 0x00, 0x00, 0x04, 0xe8, 0x03, 0x00, 0x00, 0x50, 0x4b, 0x05, 0x06, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x56, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00}},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -107,7 +158,9 @@ binaryData:
|
||||||
assert.Contains(t, err.Error(), test.expectedErrorMsg)
|
assert.Contains(t, err.Error(), test.expectedErrorMsg)
|
||||||
} else {
|
} else {
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equal(t, test.expected, cm)
|
for _, expected := range test.expected {
|
||||||
|
assert.Contains(t, cm, expected)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -651,3 +651,63 @@ spec:
|
||||||
run_podman pod ps
|
run_podman pod ps
|
||||||
run_podman rmi $(pause_image)
|
run_podman rmi $(pause_image)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@test "podman kube play with configmaps" {
|
||||||
|
skip_if_remote "the configmap argument is supported only locally"
|
||||||
|
|
||||||
|
configmap_file=${PODMAN_TMPDIR}/play_kube_configmap_configmaps$(random_string 6).yaml
|
||||||
|
echo "
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: ConfigMap
|
||||||
|
metadata:
|
||||||
|
name: foo
|
||||||
|
data:
|
||||||
|
value: foo
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: ConfigMap
|
||||||
|
metadata:
|
||||||
|
name: bar
|
||||||
|
data:
|
||||||
|
value: bar
|
||||||
|
" > $configmap_file
|
||||||
|
|
||||||
|
pod_file=${PODMAN_TMPDIR}/play_kube_configmap_pod$(random_string 6).yaml
|
||||||
|
echo "
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: test
|
||||||
|
name: test_pod
|
||||||
|
spec:
|
||||||
|
restartPolicy: Never
|
||||||
|
containers:
|
||||||
|
- name: server
|
||||||
|
image: $IMAGE
|
||||||
|
env:
|
||||||
|
- name: FOO
|
||||||
|
valueFrom:
|
||||||
|
configMapKeyRef:
|
||||||
|
name: foo
|
||||||
|
key: value
|
||||||
|
- name: BAR
|
||||||
|
valueFrom:
|
||||||
|
configMapKeyRef:
|
||||||
|
name: bar
|
||||||
|
key: value
|
||||||
|
command:
|
||||||
|
- /bin/sh
|
||||||
|
args:
|
||||||
|
- -c
|
||||||
|
- "echo \$FOO:\$BAR"
|
||||||
|
" > $pod_file
|
||||||
|
|
||||||
|
run_podman kube play --configmap=$configmap_file $pod_file
|
||||||
|
run_podman wait test_pod-server
|
||||||
|
run_podman logs test_pod-server
|
||||||
|
is $output "foo:bar"
|
||||||
|
|
||||||
|
run_podman kube down $pod_file
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue