/
unstructured.go
129 lines (110 loc) · 3.91 KB
/
unstructured.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
package client
import (
"context"
"encoding/json"
"github.com/uesyn/dotfiles/tools/devk/kubernetes/scheme"
"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"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/watch"
"k8s.io/client-go/discovery"
"k8s.io/client-go/discovery/cached/memory"
"k8s.io/client-go/dynamic"
"k8s.io/client-go/rest"
"k8s.io/client-go/restmapper"
)
type UnstructuredClient struct {
scheme *runtime.Scheme
restConfig *rest.Config
mapper *restmapper.DeferredDiscoveryRESTMapper
client dynamic.Interface
}
func NewUnstructuredClient(restConfig *rest.Config) *UnstructuredClient {
dc := discovery.NewDiscoveryClientForConfigOrDie(restConfig)
cached := memory.NewMemCacheClient(dc)
return &UnstructuredClient{
scheme: scheme.Scheme,
restConfig: restConfig,
mapper: restmapper.NewDeferredDiscoveryRESTMapper(cached),
client: dynamic.NewForConfigOrDie(restConfig),
}
}
func (u *UnstructuredClient) getNamespaceableResourceInterface(gvk schema.GroupVersionKind) (dynamic.NamespaceableResourceInterface, *meta.RESTMapping, error) {
mapping, err := u.mapper.RESTMapping(gvk.GroupKind(), gvk.Version)
if err != nil {
return nil, nil, err
}
return u.client.Resource(mapping.Resource), mapping, nil
}
func (u *UnstructuredClient) getResourceInterface(obj *unstructured.Unstructured) (dynamic.ResourceInterface, error) {
nr, mapping, err := u.getNamespaceableResourceInterface(obj.GroupVersionKind())
if err != nil {
return nil, err
}
if mapping.Scope.Name() == meta.RESTScopeNameNamespace {
return nr.Namespace(obj.GetNamespace()), nil
}
return nr, nil
}
type GetOptions = metav1.GetOptions
func (u *UnstructuredClient) Get(ctx context.Context, obj *unstructured.Unstructured, opts metav1.GetOptions) (*unstructured.Unstructured, error) {
dr, err := u.getResourceInterface(obj)
if err != nil {
return nil, err
}
return dr.Get(ctx, obj.GetName(), opts)
}
type CreateOptions = metav1.CreateOptions
func (u *UnstructuredClient) Create(ctx context.Context, obj *unstructured.Unstructured, opts metav1.CreateOptions) (*unstructured.Unstructured, error) {
dr, err := u.getResourceInterface(obj)
if err != nil {
return nil, err
}
return dr.Create(ctx, obj, opts)
}
type DeleteOptions = metav1.DeleteOptions
func (u *UnstructuredClient) Delete(ctx context.Context, obj *unstructured.Unstructured, opts metav1.DeleteOptions) error {
dr, err := u.getResourceInterface(obj)
if err != nil {
return err
}
return dr.Delete(ctx, obj.GetName(), opts)
}
type UpdateOptions = metav1.UpdateOptions
func (u *UnstructuredClient) Update(ctx context.Context, obj *unstructured.Unstructured, opts metav1.UpdateOptions) (*unstructured.Unstructured, error) {
dr, err := u.getResourceInterface(obj)
if err != nil {
return nil, err
}
return dr.Update(ctx, obj, opts)
}
type PatchOptions = metav1.PatchOptions
func (u *UnstructuredClient) Apply(ctx context.Context, obj *unstructured.Unstructured, opts PatchOptions) (*unstructured.Unstructured, error) {
dr, err := u.getResourceInterface(obj)
if err != nil {
return nil, err
}
data, err := json.Marshal(obj)
if err != nil {
return nil, err
}
return dr.Patch(ctx, obj.GetName(), types.ApplyPatchType, data, opts)
}
type ListOptions = metav1.ListOptions
func (u *UnstructuredClient) List(ctx context.Context, gvk schema.GroupVersionKind, opts metav1.ListOptions) (*unstructured.UnstructuredList, error) {
dr, _, err := u.getNamespaceableResourceInterface(gvk)
if err != nil {
return nil, err
}
return dr.List(ctx, opts)
}
func (u *UnstructuredClient) Watch(ctx context.Context, gvk schema.GroupVersionKind, opts ListOptions) (watch.Interface, error) {
dr, _, err := u.getNamespaceableResourceInterface(gvk)
if err != nil {
return nil, err
}
return dr.Watch(ctx, opts)
}