2 Copyright 2018 The Kubernetes Authors.
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
8 http://www.apache.org/licenses/LICENSE-2.0
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.
24 "k8s.io/apimachinery/pkg/api/meta"
25 "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
26 "k8s.io/apimachinery/pkg/runtime"
27 "k8s.io/apimachinery/pkg/runtime/serializer"
28 "k8s.io/client-go/dynamic"
29 "k8s.io/client-go/kubernetes/scheme"
30 "k8s.io/client-go/rest"
31 "sigs.k8s.io/controller-runtime/pkg/client/apiutil"
34 // Options are creation options for a Client
36 // Scheme, if provided, will be used to map go structs to GroupVersionKinds
37 Scheme *runtime.Scheme
39 // Mapper, if provided, will be used to map GroupVersionKinds to Resources
40 Mapper meta.RESTMapper
43 // New returns a new Client using the provided config and Options.
44 func New(config *rest.Config, options Options) (Client, error) {
46 return nil, fmt.Errorf("must provide non-nil rest.Config to client.New")
49 // Init a scheme if none provided
50 if options.Scheme == nil {
51 options.Scheme = scheme.Scheme
54 // Init a Mapper if none provided
55 if options.Mapper == nil {
57 options.Mapper, err = apiutil.NewDiscoveryRESTMapper(config)
63 dynamicClient, err := dynamic.NewForConfig(config)
69 typedClient: typedClient{
72 scheme: options.Scheme,
73 mapper: options.Mapper,
74 codecs: serializer.NewCodecFactory(options.Scheme),
75 resourceByType: make(map[reflect.Type]*resourceMeta),
77 paramCodec: runtime.NewParameterCodec(options.Scheme),
79 unstructuredClient: unstructuredClient{
80 client: dynamicClient,
81 restMapper: options.Mapper,
88 var _ Client = &client{}
90 // client is a client.Client that reads and writes directly from/to an API server. It lazily initializes
91 // new clients at the time they are used, and caches the client.
93 typedClient typedClient
94 unstructuredClient unstructuredClient
97 // Create implements client.Client
98 func (c *client) Create(ctx context.Context, obj runtime.Object) error {
99 _, ok := obj.(*unstructured.Unstructured)
101 return c.unstructuredClient.Create(ctx, obj)
103 return c.typedClient.Create(ctx, obj)
106 // Update implements client.Client
107 func (c *client) Update(ctx context.Context, obj runtime.Object) error {
108 _, ok := obj.(*unstructured.Unstructured)
110 return c.unstructuredClient.Update(ctx, obj)
112 return c.typedClient.Update(ctx, obj)
115 // Delete implements client.Client
116 func (c *client) Delete(ctx context.Context, obj runtime.Object, opts ...DeleteOptionFunc) error {
117 _, ok := obj.(*unstructured.Unstructured)
119 return c.unstructuredClient.Delete(ctx, obj, opts...)
121 return c.typedClient.Delete(ctx, obj, opts...)
124 // Get implements client.Client
125 func (c *client) Get(ctx context.Context, key ObjectKey, obj runtime.Object) error {
126 _, ok := obj.(*unstructured.Unstructured)
128 return c.unstructuredClient.Get(ctx, key, obj)
130 return c.typedClient.Get(ctx, key, obj)
133 // List implements client.Client
134 func (c *client) List(ctx context.Context, opts *ListOptions, obj runtime.Object) error {
135 _, ok := obj.(*unstructured.UnstructuredList)
137 return c.unstructuredClient.List(ctx, opts, obj)
139 return c.typedClient.List(ctx, opts, obj)
142 // Status implements client.StatusClient
143 func (c *client) Status() StatusWriter {
144 return &statusWriter{client: c}
147 // statusWriter is client.StatusWriter that writes status subresource
148 type statusWriter struct {
152 // ensure statusWriter implements client.StatusWriter
153 var _ StatusWriter = &statusWriter{}
155 // Update implements client.StatusWriter
156 func (sw *statusWriter) Update(ctx context.Context, obj runtime.Object) error {
157 _, ok := obj.(*unstructured.Unstructured)
159 return sw.client.unstructuredClient.UpdateStatus(ctx, obj)
161 return sw.client.typedClient.UpdateStatus(ctx, obj)