-
Notifications
You must be signed in to change notification settings - Fork 106
/
cluster_resource.go
126 lines (107 loc) · 3.67 KB
/
cluster_resource.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
// Copyright 2024 The Carvel Authors.
// SPDX-License-Identifier: Apache-2.0
package e2e
import (
"fmt"
"strings"
"sync"
"testing"
ctlres "carvel.dev/kapp/pkg/kapp/resources"
"github.com/stretchr/testify/require"
)
var (
hasShowManagedFieldsFlag bool
determineShowManagedFieldsFlag sync.Once
)
type ClusterResource struct {
res ctlres.Resource
}
func NewPresentClusterResource(kind, name, ns string, kubectl Kubectl) ClusterResource {
// Since -oyaml output is different between different kubectl versions
// due to inclusion/exclusion of managed fields, lets try to
// always include it via a flag. Older versions did not have it.
determineShowManagedFieldsFlag.Do(func() {
_, err := kubectl.RunWithOpts([]string{"get", "node", "--show-managed-fields"}, RunOpts{AllowError: true})
hasShowManagedFieldsFlag = (err == nil)
})
args := []string{"get", kind, name, "-n", ns, "-o", "yaml"}
if hasShowManagedFieldsFlag {
args = append(args, "--show-managed-fields")
}
out, _ := kubectl.RunWithOpts(args, RunOpts{NoNamespace: true})
return ClusterResource{ctlres.MustNewResourceFromBytes([]byte(out))}
}
func NewMissingClusterResource(t *testing.T, kind, name, ns string, kubectl Kubectl) {
_, err := kubectl.RunWithOpts([]string{"get", kind, name, "-n", ns, "-o", "yaml"}, RunOpts{AllowError: true})
require.Condition(t, func() bool {
return err != nil && strings.Contains(err.Error(), "Error from server (NotFound)")
}, "Expected resource to not exist")
}
func NewClusterResource(t *testing.T, kind, name, ns string, kubectl Kubectl) {
_, err := kubectl.RunWithOpts([]string{"create", kind, name, "-n", ns}, RunOpts{AllowError: true, NoNamespace: true})
require.NoErrorf(t, err, "Failed to deploy resource %s/%s: %s", kind, name, err)
}
func RemoveClusterResource(t *testing.T, kind, name, ns string, kubectl Kubectl) {
_, err := kubectl.RunWithOpts([]string{"delete", kind, name, "-n", ns}, RunOpts{AllowError: true, NoNamespace: true})
if err != nil {
require.Contains(t, err.Error(), "Error from server (NotFound)", "Failed to delete resource %s/%s: %s")
}
}
func PatchClusterResource(kind, name, ns, patch string, kubectl Kubectl) {
kubectl.RunWithOpts([]string{"patch", kind, name, "--type=json", "--patch", patch, "-n", ns}, RunOpts{NoNamespace: true})
}
func ClusterResourceExists(kind, name string, kubectl Kubectl) (bool, error) {
_, err := kubectl.RunWithOpts([]string{"get", kind, name}, RunOpts{AllowError: true})
if err != nil {
if strings.Contains(err.Error(), "Error from server (NotFound)") {
return false, nil
}
return false, err
}
return true, nil
}
func (r ClusterResource) UID() string {
uid := r.res.UID()
if len(uid) == 0 {
panic("Expected UID to be non-empty")
}
return uid
}
func (r ClusterResource) Labels() map[string]string {
return r.res.Labels()
}
func (r ClusterResource) Raw() map[string]interface{} {
return r.res.DeepCopyRaw()
}
func (r ClusterResource) RawPath(path ctlres.Path) interface{} {
var result interface{} = r.Raw()
for _, part := range path {
switch {
case part.MapKey != nil:
typedResult, ok := result.(map[string]interface{})
if !ok {
panic("Expected to find map")
}
result, ok = typedResult[*part.MapKey]
if !ok {
panic(fmt.Sprintf("Expected to find key %s", *part.MapKey))
}
case part.ArrayIndex != nil:
typedResult, ok := result.([]interface{})
if !ok {
panic("Expected to find array")
}
switch {
case part.ArrayIndex.Index != nil:
result = typedResult[*part.ArrayIndex.Index]
case part.ArrayIndex.All != nil:
panic("Unsupported array index all")
default:
panic("Unknown array index")
}
default:
panic("Unknown path part")
}
}
return result
}