forked from bsteciuk/kismatic
-
Notifications
You must be signed in to change notification settings - Fork 0
/
kubernetes.go
219 lines (196 loc) · 7.49 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
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
package data
import (
"encoding/json"
"fmt"
"strings"
"github.com/apprenda/kismatic/pkg/ssh"
)
// PodLister lists pods on a Kubernetes cluster
type PodLister interface {
ListPods() (*PodList, error)
}
// PVLister lists persistent volumes that exist on a Kubernetes cluster
type PVLister interface {
ListPersistentVolumes() (*PersistentVolumeList, error)
}
// PersistentVolumeGetter gets a persistent volume
type PersistentVolumeGetter interface {
GetPersistentVolume(name string) (*PersistentVolume, error)
}
// PersistentVolumeClaimGetter gets a persistent volume claim
type PersistentVolumeClaimGetter interface {
GetPersistentVolumeClaim(namespace, name string) (*PersistentVolumeClaim, error)
}
// DaemonSetGetter gets a given daemonset
type DaemonSetGetter interface {
GetDaemonSet(namespace, name string) (*DaemonSet, error)
}
// ReplicationControllerGetter gets a replication controller
type ReplicationControllerGetter interface {
GetReplicationController(namespace, name string) (*ReplicationController, error)
}
// ReplicaSetGetter gets a replica set
type ReplicaSetGetter interface {
GetReplicaSet(namespace, name string) (*ReplicaSet, error)
}
// StatefulSetGetter gets a stateful set
type StatefulSetGetter interface {
GetStatefulSet(namespace, name string) (*StatefulSet, error)
}
type KubernetesClient interface {
PodLister
PVLister
}
// RemoteKubectl is a kubectl client that uses an underlying SSH connection
// to connect to a node that has the kubectl binary. It is expected that this
// node has access to a kubernetes cluster via kubectl.
type RemoteKubectl struct {
SSHClient ssh.Client
}
// ListPersistentVolumes returns PersistentVolume data
func (k RemoteKubectl) ListPersistentVolumes() (*PersistentVolumeList, error) {
pvRaw, err := k.SSHClient.Output(true, "sudo kubectl --kubeconfig /root/.kube/config get pv -o json")
if err != nil {
return nil, fmt.Errorf("error getting persistent volume data: %v", err)
}
return UnmarshalPVs(pvRaw)
}
func UnmarshalPVs(raw string) (*PersistentVolumeList, error) {
if isNoResourcesResponse(raw) {
return nil, nil
}
var pvs PersistentVolumeList
err := json.Unmarshal([]byte(raw), &pvs)
if err != nil {
return nil, fmt.Errorf("error unmarshalling persistent volume data: %v", err)
}
return &pvs, nil
}
// ListPods returns Pods data with --all-namespaces=true flag
func (k RemoteKubectl) ListPods() (*PodList, error) {
podsRaw, err := k.SSHClient.Output(true, "sudo kubectl --kubeconfig /root/.kube/config get pods --all-namespaces=true -o json")
if err != nil {
return nil, fmt.Errorf("error getting pod data: %v", err)
}
return UnmarshalPods(podsRaw)
}
func UnmarshalPods(raw string) (*PodList, error) {
if isNoResourcesResponse(raw) {
return nil, nil
}
var pods PodList
err := json.Unmarshal([]byte(raw), &pods)
if err != nil {
return nil, fmt.Errorf("error unmarshalling pod data: %v", err)
}
return &pods, nil
}
// GetDaemonSet returns the DaemonSet with the given namespace and name. If not found,
// returns an error.
func (k RemoteKubectl) GetDaemonSet(namespace, name string) (*DaemonSet, error) {
cmd := fmt.Sprintf("sudo kubectl --kubeconfig /root/.kube/config get ds --namespace=%s -o json %s", namespace, name)
dsRaw, err := k.SSHClient.Output(true, cmd)
if err != nil {
return nil, fmt.Errorf("error getting daemon sets: %v", err)
}
if isNoResourcesResponse(dsRaw) {
return nil, fmt.Errorf("DaemonSet %s/%s was not found", namespace, name)
}
var d DaemonSet
if err := json.Unmarshal([]byte(dsRaw), &d); err != nil {
return nil, fmt.Errorf("error unmarshalling daemonset: %v", err)
}
return &d, nil
}
// GetReplicationController returns the ReplicationController with the given name in the given namespace.
// If not found, returns an error.
func (k RemoteKubectl) GetReplicationController(namespace, name string) (*ReplicationController, error) {
cmd := fmt.Sprintf("sudo kubectl --kubeconfig /root/.kube/config get replicationcontroller --namespace=%s -o json %s", namespace, name)
rcRaw, err := k.SSHClient.Output(true, cmd)
if err != nil {
return nil, fmt.Errorf("error getting replication controller: %v", err)
}
if isNoResourcesResponse(rcRaw) {
return nil, fmt.Errorf("ReplicationController %s/%s was not found", namespace, name)
}
var r ReplicationController
if err := json.Unmarshal([]byte(rcRaw), &r); err != nil {
return nil, fmt.Errorf("error unmarshalling replication controller: %v", err)
}
return &r, nil
}
// GetReplicaSet returns the ReplicaSet with the given name in the given namespace.
// If not found, returns an error.
func (k RemoteKubectl) GetReplicaSet(namespace, name string) (*ReplicaSet, error) {
cmd := fmt.Sprintf("sudo kubectl --kubeconfig /root/.kube/config get replicaset --namespace=%s -o json %s", namespace, name)
raw, err := k.SSHClient.Output(true, cmd)
if err != nil {
return nil, fmt.Errorf("error getting ReplicaSet: %v", err)
}
if isNoResourcesResponse(raw) {
return nil, fmt.Errorf("ReplicaSet %s/%s was not found", namespace, name)
}
var r ReplicaSet
if err := json.Unmarshal([]byte(raw), &r); err != nil {
return nil, fmt.Errorf("error unmarshalling ReplicaSet: %v", err)
}
return &r, nil
}
// GetPersistentVolume returns the persistent volume with the given name.
// If not found, returns an error.
func (k RemoteKubectl) GetPersistentVolume(name string) (*PersistentVolume, error) {
cmd := fmt.Sprintf("sudo kubectl --kubeconfig /root/.kube/config get pv -o json %s", name)
raw, err := k.SSHClient.Output(true, cmd)
if err != nil {
return nil, fmt.Errorf("error getting PersistentVolume: %v", err)
}
if isNoResourcesResponse(raw) {
return nil, fmt.Errorf("PersistentVolume %s was not found", name)
}
var p PersistentVolume
if err := json.Unmarshal([]byte(raw), &p); err != nil {
return nil, fmt.Errorf("error unmarshalling PersistentVolume: %v", err)
}
return &p, nil
}
// GetPersistentVolumeClaim returns the persistent volume claim with the given name and namespace.
// If not found, returns an error.
func (k RemoteKubectl) GetPersistentVolumeClaim(namespace, name string) (*PersistentVolumeClaim, error) {
cmd := fmt.Sprintf("sudo kubectl --kubeconfig /root/.kube/config get pvc --namespace %s -o json %s", namespace, name)
raw, err := k.SSHClient.Output(true, cmd)
if err != nil {
return nil, fmt.Errorf("error getting PersistentVolumeClaim: %v", err)
}
if isNoResourcesResponse(raw) {
return nil, fmt.Errorf("PersistentVolumeClaim %s was not found", name)
}
var p PersistentVolumeClaim
if err := json.Unmarshal([]byte(raw), &p); err != nil {
return nil, fmt.Errorf("error unmarshalling PersistentVolumeClaim: %v", err)
}
return &p, nil
}
// GetStatefulSet returns the stateful set with the given name in the given namespace.
// If not found, returns an error.
func (k RemoteKubectl) GetStatefulSet(namespace, name string) (*StatefulSet, error) {
cmd := fmt.Sprintf("sudo kubectl --kubeconfig /root/.kube/config get statefulset --namespace %s -o json %s", namespace, name)
raw, err := k.SSHClient.Output(true, cmd)
if err != nil {
return nil, fmt.Errorf("error getting StatefulSet: %v", err)
}
if isNoResourcesResponse(raw) {
return nil, fmt.Errorf("StatefulSet %s/%s was not found", namespace, name)
}
var s StatefulSet
if err := json.Unmarshal([]byte(raw), &s); err != nil {
return nil, fmt.Errorf("error unmarshalling StatefulSet: %v", err)
}
return &s, nil
}
// kubectl will print this message when no resources are returned
func isNoResourcesResponse(s string) bool {
if strings.Contains(strings.TrimSpace(s), "No resources found") {
return true
}
return false
}