Skip to content

Commit

Permalink
Kube - support List documents
Browse files Browse the repository at this point in the history
Flatten List into documents
Add List type to meta/v1
Add unittest
Add e2e test

Signed-off-by: Ygal Blum <ygal.blum@gmail.com>
  • Loading branch information
ygalblum committed Aug 28, 2023
1 parent f521fd2 commit 7ef97fa
Show file tree
Hide file tree
Showing 4 changed files with 102 additions and 5 deletions.
35 changes: 30 additions & 5 deletions pkg/domain/infra/abi/play.go
Expand Up @@ -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"
Expand Down Expand Up @@ -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)
}
}
Expand Down
17 changes: 17 additions & 0 deletions pkg/domain/infra/abi/play_test.go
Expand Up @@ -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 {
Expand Down
12 changes: 12 additions & 0 deletions pkg/k8s.io/apimachinery/pkg/apis/meta/v1/types.go
Expand Up @@ -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.
//
Expand Down
43 changes: 43 additions & 0 deletions test/e2e/play_kube_test.go
Expand Up @@ -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"}
Expand Down Expand Up @@ -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`))
})
})

0 comments on commit 7ef97fa

Please sign in to comment.