-
Notifications
You must be signed in to change notification settings - Fork 444
/
kubernetes.go
135 lines (109 loc) · 3.45 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
123
124
125
126
127
128
129
130
131
132
133
134
135
package install
import (
"bytes"
"fmt"
"io"
"os"
"os/exec"
"strings"
. "github.com/onsi/gomega"
"github.com/solo-io/gloo/pkg/cliutil"
)
func KubectlApply(manifest []byte, extraArgs ...string) error {
return Kubectl(bytes.NewBuffer(manifest), append([]string{"apply", "-f", "-"}, extraArgs...)...)
}
func KubectlApplyOut(manifest []byte, extraArgs ...string) ([]byte, error) {
return KubectlOut(bytes.NewBuffer(manifest), append([]string{"apply", "-f", "-"}, extraArgs...)...)
}
func KubectlDelete(manifest []byte, extraArgs ...string) error {
return Kubectl(bytes.NewBuffer(manifest), append([]string{"delete", "-f", "-"}, extraArgs...)...)
}
type KubeCli interface {
Kubectl(stdin io.Reader, args ...string) error
KubectlOut(stdin io.Reader, args ...string) ([]byte, error)
}
type CmdKubectl struct{}
var _ KubeCli = &CmdKubectl{}
func (k *CmdKubectl) Kubectl(stdin io.Reader, args ...string) error {
return Kubectl(stdin, args...)
}
func (k *CmdKubectl) KubectlOut(stdin io.Reader, args ...string) ([]byte, error) {
return KubectlOut(stdin, args...)
}
type MockKubectl struct {
Expected []string
Next int
StdoutLines []string
StdoutLineIndex int
}
var _ KubeCli = &MockKubectl{}
func NewMockKubectl(cmds []string, stdoutLines []string) *MockKubectl {
return &MockKubectl{
Expected: cmds,
Next: 0,
StdoutLines: stdoutLines,
}
}
func (k *MockKubectl) Kubectl(stdin io.Reader, args ...string) error {
// If this fails then the CLI tried to run commands we didn't account for in the mock
Expect(k.Next < len(k.Expected)).To(BeTrue())
Expect(stdin).To(BeNil())
cmd := strings.Join(args, " ")
Expect(cmd).To(BeEquivalentTo(k.Expected[k.Next]))
k.Next = k.Next + 1
return nil
}
func (k *MockKubectl) KubectlOut(stdin io.Reader, args ...string) ([]byte, error) {
Expect(k.Next < len(k.Expected)).To(BeTrue(), "MockKubectl did not have a next command for KubectlOut")
Expect(stdin).To(BeNil(), "Should have passed nil to MockKubectl.KubectlOut")
cmd := strings.Join(args, " ")
Expect(cmd).To(BeEquivalentTo(k.Expected[k.Next]), "Wrong next command for MockKubectl.KubectlOut")
k.Next = k.Next + 1
Expect(k.StdoutLineIndex < len(k.StdoutLines)).To(BeTrue(), "Mock kubectl has run out of stdout lines on command "+cmd)
stdOutLine := k.StdoutLines[k.StdoutLineIndex]
k.StdoutLineIndex = k.StdoutLineIndex + 1
return []byte(stdOutLine), nil
}
var verbose bool
func SetVerbose(b bool) {
verbose = b
}
func Kubectl(stdin io.Reader, args ...string) error {
kubectl := exec.Command("kubectl", args...)
if stdin != nil {
kubectl.Stdin = stdin
}
if verbose {
fmt.Fprintf(os.Stderr, "running kubectl command: %v\n", kubectl.Args)
kubectl.Stdout = os.Stdout
kubectl.Stderr = os.Stderr
} else {
// use logfile
cliutil.Initialize()
kubectl.Stdout = cliutil.GetLogger()
kubectl.Stderr = cliutil.GetLogger()
}
return kubectl.Run()
}
func KubectlOut(stdin io.Reader, args ...string) ([]byte, error) {
kubectl := exec.Command("kubectl", args...)
if stdin != nil {
kubectl.Stdin = stdin
}
var stdout, stderr io.Writer
if verbose {
fmt.Fprintf(os.Stderr, "running kubectl command: %v\n", kubectl.Args)
stdout = os.Stdout
stderr = os.Stderr
} else {
// use logfile
cliutil.Initialize()
stdout = cliutil.GetLogger()
stderr = cliutil.GetLogger()
}
buf := &bytes.Buffer{}
kubectl.Stdout = io.MultiWriter(stdout, buf)
kubectl.Stderr = io.MultiWriter(stderr, buf)
err := kubectl.Run()
return buf.Bytes(), err
}