Kube - support List documents

Flatten List into documents
Add List type to meta/v1
Add unittest
Add e2e test

Signed-off-by: Ygal Blum <ygal.blum@gmail.com>
This commit is contained in:
Ygal Blum
2023-08-27 15:52:32 +03:00
parent f521fd2843
commit 7ef97fa49e
4 changed files with 103 additions and 6 deletions

View File

@ -24,6 +24,7 @@ import (
"github.com/containers/podman/v4/pkg/domain/entities"
v1apps "github.com/containers/podman/v4/pkg/k8s.io/api/apps/v1"
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/containers/podman/v4/pkg/specgen"
"github.com/containers/podman/v4/pkg/specgen/generate"
"github.com/containers/podman/v4/pkg/specgen/generate/kube"
@ -1261,13 +1262,37 @@ func splitMultiDocYAML(yamlContent []byte) ([][]byte, error) {
return nil, fmt.Errorf("multi doc yaml could not be split: %w", err)
}
if o != nil {
// back to bytes
document, err := yamlv3.Marshal(o)
if err != nil {
return nil, fmt.Errorf("individual doc yaml could not be marshalled: %w", err)
}
if o == nil {
continue
}
// back to bytes
document, err := yamlv3.Marshal(o)
if err != nil {
return nil, fmt.Errorf("individual doc yaml could not be marshalled: %w", err)
}
kind, err := getKubeKind(document)
if err != nil {
return nil, fmt.Errorf("couldn't get object kind: %w", err)
}
// The items in a document of kind "List" are fully qualified resources
// So, they can be treated as separate documents
if kind == "List" {
var kubeList metav1.List
if err := yaml.Unmarshal(document, &kubeList); err != nil {
return nil, err
}
for _, item := range kubeList.Items {
itemDocument, err := yamlv3.Marshal(item)
if err != nil {
return nil, fmt.Errorf("individual doc yaml could not be marshalled: %w", err)
}
documentList = append(documentList, itemDocument)
}
} else {
documentList = append(documentList, document)
}
}

View File

@ -246,6 +246,23 @@ kind: Pod
"multi doc yaml could not be split",
0,
},
{
"DocWithList",
`
apiVersion: v1
kind: List
items:
- apiVersion: v1
kind: Pod
- apiVersion: v1
kind: Pod
- apiVersion: v1
kind: Pod
`,
false,
"",
3,
},
}
for _, test := range tests {

View File

@ -929,6 +929,18 @@ const (
CauseTypeResourceVersionTooLarge CauseType = "ResourceVersionTooLarge"
)
// List holds a list of objects, which may not be known by the server.
type List struct {
TypeMeta `json:",inline"`
// Standard list metadata.
// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
// +optional
ListMeta `json:"metadata,omitempty"`
// List of objects
Items []interface{} `json:"items"`
}
// APIVersions lists the versions that are available, to allow clients to
// discover the API at /api, which is the root path of the legacy v1 API.
//

View File

@ -1190,6 +1190,34 @@ spec:
- "sysctl kernel.msgmax"
`
var listPodAndConfigMap = `
apiVersion: v1
kind: List
items:
- apiVersion: v1
kind: ConfigMap
metadata:
name: test-list-configmap
data:
foo: bar
- apiVersion: v1
kind: Pod
metadata:
name: test-list-pod
spec:
containers:
- name: container
image: quay.io/libpod/alpine:latest
command: [ "/bin/sh", "-c", "env" ]
env:
- name: FOO
valueFrom:
configMapKeyRef:
name: test-list-configmap
key: foo
restartPolicy: Never
`
var (
defaultCtrName = "testCtr"
defaultCtrCmd = []string{"top"}
@ -5955,4 +5983,19 @@ EXPOSE 2004-2005/tcp`, ALPINE)
Expect(ps).Should(Exit(0))
Expect(ps.OutputToString()).To(ContainSubstring(podID[:12] + "-infra"))
})
It("podman play kube support List kind", func() {
listYamlPathname := filepath.Join(podmanTest.TempDir, "list.yaml")
err = writeYaml(listPodAndConfigMap, listYamlPathname)
Expect(err).ToNot(HaveOccurred())
kube := podmanTest.Podman([]string{"play", "kube", listYamlPathname})
kube.WaitWithDefaultTimeout()
Expect(kube).Should(Exit(0))
inspect := podmanTest.Podman([]string{"inspect", "test-list-pod-container", "--format", "'{{ .Config.Env }}'"})
inspect.WaitWithDefaultTimeout()
Expect(inspect).Should(Exit(0))
Expect(inspect.OutputToString()).To(ContainSubstring(`FOO=bar`))
})
})