/
resourceclient.go
83 lines (67 loc) · 2.6 KB
/
resourceclient.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
/*
Copyright 2020 The Custom Pod Autoscaler Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package resourceclient
import (
"fmt"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/client-go/dynamic"
"k8s.io/client-go/kubernetes/scheme"
"strings"
)
// Client provides methods for retrieving arbitrary Kubernetes resources, returned as generalised metav1.Object, which can be converted
// to concrete types, and allows for retrieving common and shared data (namespaces, names etc.)
type Client interface {
Get(apiVersion string, kind string, name string, namespace string) (metav1.Object, error)
}
// UnstructuredClient is an implementation of the arbitrary resource client that uses a dynamic Kubernetes interface, retrieving
// unstructured k8s objects and converting them to metav1.Object
type UnstructuredClient struct {
Dynamic dynamic.Interface
UnstructuredConverter runtime.UnstructuredConverter
}
// Get takes descriptors of a Kubernetes object (api version, kind, name, namespace) and fetches the matching object, returning it
// as a metav1.Object
func (u *UnstructuredClient) Get(apiVersion string, kind string, name string, namespace string) (metav1.Object, error) {
// TODO: update this to be less hacky
// Convert to plural and lowercase
kindPlural := fmt.Sprintf("%ss", strings.ToLower(kind))
// Parse group version
resourceGV, err := schema.ParseGroupVersion(apiVersion)
if err != nil {
return nil, err
}
// Build GVK
resourceGVK := schema.FromAPIVersionAndKind(apiVersion, kind)
// Build GVR
resourceGVR := schema.GroupVersionResource{
Group: resourceGV.Group,
Version: resourceGV.Version,
Resource: kindPlural,
}
// Get resource
resource, err := u.Dynamic.Resource(resourceGVR).Namespace(namespace).Get(name, metav1.GetOptions{})
if err != nil {
return nil, err
}
resourceMeta, err := scheme.Scheme.New(resourceGVK)
if err != nil {
return nil, err
}
err = u.UnstructuredConverter.FromUnstructured(resource.Object, resourceMeta)
if err != nil {
return nil, err
}
return resourceMeta.(metav1.Object), nil
}