summaryrefslogtreecommitdiff
path: root/pkg/domain/infra/abi/play.go
diff options
context:
space:
mode:
Diffstat (limited to 'pkg/domain/infra/abi/play.go')
-rw-r--r--pkg/domain/infra/abi/play.go152
1 files changed, 118 insertions, 34 deletions
diff --git a/pkg/domain/infra/abi/play.go b/pkg/domain/infra/abi/play.go
index efc7c86e3..3b5c141d7 100644
--- a/pkg/domain/infra/abi/play.go
+++ b/pkg/domain/infra/abi/play.go
@@ -1,6 +1,7 @@
package abi
import (
+ "bytes"
"context"
"fmt"
"io"
@@ -8,6 +9,7 @@ import (
"os"
"strings"
+ "github.com/containers/common/pkg/secrets"
"github.com/containers/image/v5/types"
"github.com/containers/podman/v3/libpod"
"github.com/containers/podman/v3/libpod/define"
@@ -20,46 +22,79 @@ import (
"github.com/ghodss/yaml"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
+ yamlv3 "gopkg.in/yaml.v3"
v1apps "k8s.io/api/apps/v1"
v1 "k8s.io/api/core/v1"
)
func (ic *ContainerEngine) PlayKube(ctx context.Context, path string, options entities.PlayKubeOptions) (*entities.PlayKubeReport, error) {
- var (
- kubeObject v1.ObjectReference
- )
+ report := &entities.PlayKubeReport{}
+ validKinds := 0
+ // read yaml document
content, err := ioutil.ReadFile(path)
if err != nil {
return nil, err
}
- if err := yaml.Unmarshal(content, &kubeObject); err != nil {
- return nil, errors.Wrapf(err, "unable to read %q as YAML", path)
+ // split yaml document
+ documentList, err := splitMultiDocYAML(content)
+ if err != nil {
+ return nil, err
}
- // NOTE: pkg/bindings/play is also parsing the file.
- // A pkg/kube would be nice to refactor and abstract
- // parts of the K8s-related code.
- switch kubeObject.Kind {
- case "Pod":
- var podYAML v1.Pod
- var podTemplateSpec v1.PodTemplateSpec
- if err := yaml.Unmarshal(content, &podYAML); err != nil {
- return nil, errors.Wrapf(err, "unable to read YAML %q as Kube Pod", path)
+ // create pod on each document if it is a pod or deployment
+ // any other kube kind will be skipped
+ for _, document := range documentList {
+ kind, err := getKubeKind(document)
+ if err != nil {
+ return nil, errors.Wrapf(err, "unable to read %q as kube YAML", path)
}
- podTemplateSpec.ObjectMeta = podYAML.ObjectMeta
- podTemplateSpec.Spec = podYAML.Spec
- return ic.playKubePod(ctx, podTemplateSpec.ObjectMeta.Name, &podTemplateSpec, options)
- case "Deployment":
- var deploymentYAML v1apps.Deployment
- if err := yaml.Unmarshal(content, &deploymentYAML); err != nil {
- return nil, errors.Wrapf(err, "unable to read YAML %q as Kube Deployment", path)
+
+ switch kind {
+ case "Pod":
+ var podYAML v1.Pod
+ var podTemplateSpec v1.PodTemplateSpec
+
+ if err := yaml.Unmarshal(document, &podYAML); err != nil {
+ return nil, errors.Wrapf(err, "unable to read YAML %q as Kube Pod", path)
+ }
+
+ podTemplateSpec.ObjectMeta = podYAML.ObjectMeta
+ podTemplateSpec.Spec = podYAML.Spec
+
+ r, err := ic.playKubePod(ctx, podTemplateSpec.ObjectMeta.Name, &podTemplateSpec, options)
+ if err != nil {
+ return nil, err
+ }
+
+ report.Pods = append(report.Pods, r.Pods...)
+ validKinds++
+ case "Deployment":
+ var deploymentYAML v1apps.Deployment
+
+ if err := yaml.Unmarshal(document, &deploymentYAML); err != nil {
+ return nil, errors.Wrapf(err, "unable to read YAML %q as Kube Deployment", path)
+ }
+
+ r, err := ic.playKubeDeployment(ctx, &deploymentYAML, options)
+ if err != nil {
+ return nil, err
+ }
+
+ report.Pods = append(report.Pods, r.Pods...)
+ validKinds++
+ default:
+ logrus.Infof("kube kind %s not supported", kind)
+ continue
}
- return ic.playKubeDeployment(ctx, &deploymentYAML, options)
- default:
- return nil, errors.Errorf("invalid YAML kind: %q. [Pod|Deployment] are the only supported Kubernetes Kinds", kubeObject.Kind)
}
+
+ if validKinds == 0 {
+ return nil, fmt.Errorf("YAML document does not contain any supported kube kind")
+ }
+
+ return report, nil
}
func (ic *ContainerEngine) playKubeDeployment(ctx context.Context, deploymentYAML *v1apps.Deployment, options entities.PlayKubeOptions) (*entities.PlayKubeReport, error) {
@@ -101,6 +136,12 @@ func (ic *ContainerEngine) playKubePod(ctx context.Context, podName string, podY
report entities.PlayKubeReport
)
+ // Create the secret manager before hand
+ secretsManager, err := secrets.NewManager(ic.Libpod.GetSecretsStorageDir())
+ if err != nil {
+ return nil, err
+ }
+
// check for name collision between pod and container
if podName == "" {
return nil, errors.Errorf("pod does not have a name")
@@ -227,16 +268,17 @@ func (ic *ContainerEngine) playKubePod(ctx context.Context, podName string, podY
}
specgenOpts := kube.CtrSpecGenOptions{
- Container: container,
- Image: newImage,
- Volumes: volumes,
- PodID: pod.ID(),
- PodName: podName,
- PodInfraID: podInfraID,
- ConfigMaps: configMaps,
- SeccompPaths: seccompPaths,
- RestartPolicy: ctrRestartPolicy,
- NetNSIsHost: p.NetNS.IsHost(),
+ Container: container,
+ Image: newImage,
+ Volumes: volumes,
+ PodID: pod.ID(),
+ PodName: podName,
+ PodInfraID: podInfraID,
+ ConfigMaps: configMaps,
+ SeccompPaths: seccompPaths,
+ RestartPolicy: ctrRestartPolicy,
+ NetNSIsHost: p.NetNS.IsHost(),
+ SecretsManager: secretsManager,
}
specGen, err := kube.ToSpecGen(ctx, &specgenOpts)
if err != nil {
@@ -290,3 +332,45 @@ func readConfigMapFromFile(r io.Reader) (v1.ConfigMap, error) {
return cm, nil
}
+
+// splitMultiDocYAML reads mutiple documents in a YAML file and
+// returns them as a list.
+func splitMultiDocYAML(yamlContent []byte) ([][]byte, error) {
+ var documentList [][]byte
+
+ d := yamlv3.NewDecoder(bytes.NewReader(yamlContent))
+ for {
+ var o interface{}
+ // read individual document
+ err := d.Decode(&o)
+ if err == io.EOF {
+ break
+ }
+ if err != nil {
+ return nil, errors.Wrapf(err, "multi doc yaml could not be split")
+ }
+
+ if o != nil {
+ // back to bytes
+ document, err := yamlv3.Marshal(o)
+ if err != nil {
+ return nil, errors.Wrapf(err, "individual doc yaml could not be marshalled")
+ }
+
+ documentList = append(documentList, document)
+ }
+ }
+
+ return documentList, nil
+}
+
+// getKubeKind unmarshals a kube YAML document and returns its kind.
+func getKubeKind(obj []byte) (string, error) {
+ var kubeObject v1.ObjectReference
+
+ if err := yaml.Unmarshal(obj, &kubeObject); err != nil {
+ return "", err
+ }
+
+ return kubeObject.Kind, nil
+}