-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdelete.go
104 lines (87 loc) · 2.74 KB
/
delete.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
package k8t
import (
"context"
"io/ioutil"
"k8s.io/apimachinery/pkg/api/meta"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime/serializer/yaml"
"k8s.io/client-go/discovery"
memory "k8s.io/client-go/discovery/cached"
"k8s.io/client-go/dynamic"
"k8s.io/client-go/restmapper"
)
// options for DeleteWithOpts function
type DeleteOpts struct {
// here you can pass your context. It it's not set, the default
// context.Background() will be used
Context context.Context
// namespace where delete resource. If it's not set, the cluster's
// test namespace will be used. This is ignored for cluster-wide resources
Namespace string
}
// Delete resource in given file
func (c *Cluster) DeleteFile(path string) error {
data, err := ioutil.ReadFile(path)
if err != nil {
return err
}
return c.Delete(string(data))
}
// Delete resource of given YAML. The resource must be located in
// cluster's default test namespace or it must be cluster-wide resource. If
// you want to delete resource in another namespace, you should use more
// verbose DeleteWithOpts.
func (c *Cluster) Delete(yml string) error {
return c.DeleteWithOpts(yml, DeleteOpts{})
}
// More verbose version of Delete() function that allow you pass the context
// or change the namespace etc.
func (c *Cluster) DeleteWithOpts(yml string, opts DeleteOpts) error {
ctx := opts.Context
if ctx == nil {
ctx = context.Background()
}
namespace := opts.Namespace
if namespace == "" {
namespace = c.testNamespace
}
// Decode YAML manifest into unstructured.Unstructured
decUnstructured := yaml.NewDecodingSerializer(unstructured.UnstructuredJSONScheme)
obj := &unstructured.Unstructured{}
_, gvk, err := decUnstructured.Decode([]byte(yml), nil, obj)
if err != nil {
return err
}
// Prepare a RESTMapper and find GVR
dc, err := discovery.NewDiscoveryClientForConfig(c.restConfig)
if err != nil {
return err
}
mapper := restmapper.NewDeferredDiscoveryRESTMapper(memory.NewMemCacheClient(dc))
mapping, err := mapper.RESTMapping(gvk.GroupKind(), gvk.Version)
if err != nil {
return err
}
// Prepare the dynamic client
dyn, err := dynamic.NewForConfig(c.restConfig)
if err != nil {
return err
}
// Obtain REST interface for the GVR
var dr dynamic.ResourceInterface
if mapping.Scope.Name() == meta.RESTScopeNameNamespace {
// namespaced resources are placed into test Namespace
dr = dyn.Resource(mapping.Resource).Namespace(c.testNamespace)
} else {
// for cluster-wide resources
dr = dyn.Resource(mapping.Resource)
}
// Create or Update the object with server-side-apply
err = dr.Delete(ctx, obj.GetName(), metav1.DeleteOptions{})
if err != nil {
return err
} else {
return nil
}
}