Code refactoring for bpa operator
[icn.git] / cmd / bpa-operator / vendor / sigs.k8s.io / controller-runtime / pkg / client / unstructured_client.go
1 /*
2 Copyright 2018 The Kubernetes Authors.
3
4 Licensed under the Apache License, Version 2.0 (the "License");
5 you may not use this file except in compliance with the License.
6 You may obtain a copy of the License at
7
8     http://www.apache.org/licenses/LICENSE-2.0
9
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
15 */
16
17 package client
18
19 import (
20         "context"
21         "fmt"
22         "strings"
23
24         "k8s.io/apimachinery/pkg/api/meta"
25         metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
26         "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
27         "k8s.io/apimachinery/pkg/runtime"
28         "k8s.io/apimachinery/pkg/runtime/schema"
29         "k8s.io/client-go/dynamic"
30 )
31
32 // client is a client.Client that reads and writes directly from/to an API server.  It lazily initializes
33 // new clients at the time they are used, and caches the client.
34 type unstructuredClient struct {
35         client     dynamic.Interface
36         restMapper meta.RESTMapper
37 }
38
39 // Create implements client.Client
40 func (uc *unstructuredClient) Create(_ context.Context, obj runtime.Object) error {
41         u, ok := obj.(*unstructured.Unstructured)
42         if !ok {
43                 return fmt.Errorf("unstructured client did not understand object: %T", obj)
44         }
45         r, err := uc.getResourceInterface(u.GroupVersionKind(), u.GetNamespace())
46         if err != nil {
47                 return err
48         }
49         i, err := r.Create(u, metav1.CreateOptions{})
50         if err != nil {
51                 return err
52         }
53         u.Object = i.Object
54         return nil
55 }
56
57 // Update implements client.Client
58 func (uc *unstructuredClient) Update(_ context.Context, obj runtime.Object) error {
59         u, ok := obj.(*unstructured.Unstructured)
60         if !ok {
61                 return fmt.Errorf("unstructured client did not understand object: %T", obj)
62         }
63         r, err := uc.getResourceInterface(u.GroupVersionKind(), u.GetNamespace())
64         if err != nil {
65                 return err
66         }
67         i, err := r.Update(u, metav1.UpdateOptions{})
68         if err != nil {
69                 return err
70         }
71         u.Object = i.Object
72         return nil
73 }
74
75 // Delete implements client.Client
76 func (uc *unstructuredClient) Delete(_ context.Context, obj runtime.Object, opts ...DeleteOptionFunc) error {
77         u, ok := obj.(*unstructured.Unstructured)
78         if !ok {
79                 return fmt.Errorf("unstructured client did not understand object: %T", obj)
80         }
81         r, err := uc.getResourceInterface(u.GroupVersionKind(), u.GetNamespace())
82         if err != nil {
83                 return err
84         }
85         deleteOpts := DeleteOptions{}
86         err = r.Delete(u.GetName(), deleteOpts.ApplyOptions(opts).AsDeleteOptions())
87         return err
88 }
89
90 // Get implements client.Client
91 func (uc *unstructuredClient) Get(_ context.Context, key ObjectKey, obj runtime.Object) error {
92         u, ok := obj.(*unstructured.Unstructured)
93         if !ok {
94                 return fmt.Errorf("unstructured client did not understand object: %T", obj)
95         }
96         r, err := uc.getResourceInterface(u.GroupVersionKind(), key.Namespace)
97         if err != nil {
98                 return err
99         }
100         i, err := r.Get(key.Name, metav1.GetOptions{})
101         if err != nil {
102                 return err
103         }
104         u.Object = i.Object
105         return nil
106 }
107
108 // List implements client.Client
109 func (uc *unstructuredClient) List(_ context.Context, opts *ListOptions, obj runtime.Object) error {
110         u, ok := obj.(*unstructured.UnstructuredList)
111         if !ok {
112                 return fmt.Errorf("unstructured client did not understand object: %T", obj)
113         }
114         gvk := u.GroupVersionKind()
115         if strings.HasSuffix(gvk.Kind, "List") {
116                 gvk.Kind = gvk.Kind[:len(gvk.Kind)-4]
117         }
118         namespace := ""
119         if opts != nil {
120                 namespace = opts.Namespace
121         }
122         r, err := uc.getResourceInterface(gvk, namespace)
123         if err != nil {
124                 return err
125         }
126
127         i, err := r.List(*opts.AsListOptions())
128         if err != nil {
129                 return err
130         }
131         u.Items = i.Items
132         u.Object = i.Object
133         return nil
134 }
135
136 func (uc *unstructuredClient) UpdateStatus(_ context.Context, obj runtime.Object) error {
137         u, ok := obj.(*unstructured.Unstructured)
138         if !ok {
139                 return fmt.Errorf("unstructured client did not understand object: %T", obj)
140         }
141         r, err := uc.getResourceInterface(u.GroupVersionKind(), u.GetNamespace())
142         if err != nil {
143                 return err
144         }
145         i, err := r.UpdateStatus(u, metav1.UpdateOptions{})
146         if err != nil {
147                 return err
148         }
149         u.Object = i.Object
150         return nil
151 }
152
153 func (uc *unstructuredClient) getResourceInterface(gvk schema.GroupVersionKind, ns string) (dynamic.ResourceInterface, error) {
154         mapping, err := uc.restMapper.RESTMapping(gvk.GroupKind(), gvk.Version)
155         if err != nil {
156                 return nil, err
157         }
158         if mapping.Scope.Name() == meta.RESTScopeNameRoot {
159                 return uc.client.Resource(mapping.Resource), nil
160         }
161         return uc.client.Resource(mapping.Resource).Namespace(ns), nil
162 }