forked from vmware-tanzu/sonobuoy
-
Notifications
You must be signed in to change notification settings - Fork 0
/
client.go
119 lines (106 loc) · 3.66 KB
/
client.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
package dynamic
import (
"github.com/pkg/errors"
"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/client-go/discovery"
"k8s.io/client-go/dynamic"
"k8s.io/client-go/rest"
"k8s.io/client-go/restmapper"
)
// A scoped down meta.MetadataAccessor
type MetadataAccessor interface {
Namespace(runtime.Object) (string, error)
Name(runtime.Object) (string, error)
ResourceVersion(runtime.Object) (string, error)
}
// A scoped down meta.RESTMapper
type mapper interface {
RESTMapping(gk schema.GroupKind, versions ...string) (*meta.RESTMapping, error)
}
// APIHelper wraps the client-go dynamic client and exposes a simple interface.
type APIHelper struct {
Client dynamic.Interface
DiscoveryClient discovery.DiscoveryInterface
Mapper mapper
Accessor MetadataAccessor
}
// NewAPIHelperFromRESTConfig creates a new APIHelper with default objects
// from client-go.
func NewAPIHelperFromRESTConfig(cfg *rest.Config) (*APIHelper, error) {
dynClient, err := dynamic.NewForConfig(cfg)
if err != nil {
return nil, errors.Wrap(err, "could not create dynamic client")
}
discover, err := discovery.NewDiscoveryClientForConfig(cfg)
if err != nil {
return nil, errors.Wrap(err, "could not create discovery client")
}
groupResources, err := restmapper.GetAPIGroupResources(discover)
if err != nil {
return nil, errors.Wrap(err, "could not get api group resources")
}
mapper := restmapper.NewDiscoveryRESTMapper(groupResources)
return &APIHelper{
Client: dynClient,
Mapper: mapper,
Accessor: meta.NewAccessor(),
DiscoveryClient: discover,
}, nil
}
// NewAPIHelper returns an APIHelper with the internals instantiated.
func NewAPIHelper(dyn dynamic.Interface, mapper mapper, accessor MetadataAccessor) (*APIHelper, error) {
return &APIHelper{
Client: dyn,
Mapper: mapper,
Accessor: accessor,
}, nil
}
// CreateObject attempts to create any kubernetes object.
func (a *APIHelper) CreateObject(obj *unstructured.Unstructured) (*unstructured.Unstructured, error) {
restMapping, err := a.Mapper.RESTMapping(obj.GroupVersionKind().GroupKind(), obj.GroupVersionKind().Version)
if err != nil {
return nil, errors.Wrap(err, "could not get restMapping")
}
name, err := a.Accessor.Name(obj)
if err != nil {
return nil, errors.Wrap(err, "could not get name for object")
}
namespace, err := a.Accessor.Namespace(obj)
if err != nil {
return nil, errors.Wrapf(err, "couldn't get namespace for object %s", name)
}
rsc := a.Client.Resource(restMapping.Resource)
if rsc == nil {
return nil, errors.New("failed to get a resource interface")
}
ri := rsc.Namespace(namespace)
return ri.Create(obj, metav1.CreateOptions{})
}
func sliceContains(set []string, val string) bool {
for _, v := range set {
if v == val {
return true
}
}
return false
}
// Name returns the name of the kubernetes object.
func (a *APIHelper) Name(obj *unstructured.Unstructured) (string, error) {
return a.Accessor.Name(obj)
}
// Namespace returns the namespace of the kubernetes object.
func (a *APIHelper) Namespace(obj *unstructured.Unstructured) (string, error) {
return a.Accessor.Namespace(obj)
}
// ResourceVersion returns the resource version of a kubernetes object.
func (a *APIHelper) ResourceVersion(obj *unstructured.Unstructured) (string, error) {
restMapping, err := a.Mapper.RESTMapping(obj.GroupVersionKind().GroupKind(), obj.GroupVersionKind().Version)
if err != nil {
return "", errors.Wrap(err, "could not get restMapping")
}
return restMapping.Resource.GroupResource().Resource, nil
}