-
Notifications
You must be signed in to change notification settings - Fork 203
/
kubernetes.go
122 lines (106 loc) · 2.89 KB
/
kubernetes.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
//go:generate packr2
package kubernetes
import (
"bufio"
"fmt"
"io"
"io/ioutil"
"strings"
"github.com/deislabs/porter/pkg/context"
"github.com/ghodss/yaml"
"github.com/gobuffalo/packr/v2"
"github.com/pkg/errors"
"github.com/xeipuuv/gojsonschema"
)
type Mixin struct {
*context.Context
schemas *packr.Box
}
func New() *Mixin {
return &Mixin{
Context: context.New(),
schemas: NewSchemaBox(),
}
}
func NewSchemaBox() *packr.Box {
return packr.New("github.com/deislabs/porter/pkg/kubernetes/schema", "./schema")
}
func (m *Mixin) getCommandFile(commandFile string, w io.Writer) ([]byte, error) {
if commandFile == "" {
reader := bufio.NewReader(m.In)
return ioutil.ReadAll(reader)
}
return ioutil.ReadFile(commandFile)
}
func (m *Mixin) getPayloadData() ([]byte, error) {
reader := bufio.NewReader(m.In)
data, err := ioutil.ReadAll(reader)
if err != nil {
errors.Wrap(err, "could not read payload from STDIN")
}
err = m.ValidatePayload(data)
return data, errors.Wrap(err, "could not validate payload")
}
func (m *Mixin) ValidatePayload(b []byte) error {
// Load the step as a go dump
s := make(map[string]interface{})
err := yaml.Unmarshal(b, &s)
if err != nil {
return errors.Wrap(err, "could not marshal payload as yaml")
}
manifestLoader := gojsonschema.NewGoLoader(s)
// Load the step schema
schema, err := m.GetSchema()
if err != nil {
return err
}
schemaLoader := gojsonschema.NewStringLoader(schema)
validator, err := gojsonschema.NewSchema(schemaLoader)
if err != nil {
return errors.Wrap(err, "unable to compile the mixin step schema")
}
// Validate the manifest against the schema
result, err := validator.Validate(manifestLoader)
if err != nil {
return errors.Wrap(err, "unable to validate the mixin step schema")
}
if !result.Valid() {
errs := make([]string, 0, len(result.Errors()))
for _, err := range result.Errors() {
errs = append(errs, err.String())
}
return errors.New(strings.Join(errs, "\n\t* "))
}
return nil
}
func (m *Mixin) getOutput(resourceType, resourceName, namespace, jsonPath string) ([]byte, error) {
args := []string{"get", resourceType, resourceName}
args = append(args, fmt.Sprintf("-o=jsonpath='%s'", jsonPath))
if namespace != "" {
args = append(args, fmt.Sprintf("--namespace=%s", namespace))
}
cmd := m.NewCommand("kubectl", args...)
cmd.Stderr = m.Err
out, err := cmd.Output()
if err != nil {
prettyCmd := fmt.Sprintf("%s %s", cmd.Path, strings.Join(cmd.Args, " "))
return nil, errors.Wrap(err, fmt.Sprintf("couldn't run command %s", prettyCmd))
}
return out, nil
}
func (m *Mixin) handleOutputs(outputs []KubernetesOutput) error {
//Now get the outputs
for _, output := range outputs {
bytes, err := m.getOutput(
output.ResourceType,
output.ResourceName,
output.Namespace,
output.JSONPath,
)
if err != nil {
return err
}
m.Context.WriteMixinOutputToFile(output.Name, bytes)
}
return nil
}