1/* 2Copyright 2018 The Kubernetes Authors. 3 4Licensed under the Apache License, Version 2.0 (the "License"); 5you may not use this file except in compliance with the License. 6You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10Unless required by applicable law or agreed to in writing, software 11distributed under the License is distributed on an "AS IS" BASIS, 12WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13See the License for the specific language governing permissions and 14limitations under the License. 15*/ 16 17package client 18 19import ( 20 "context" 21 22 apierrors "k8s.io/apimachinery/pkg/api/errors" 23 24 "k8s.io/apimachinery/pkg/api/meta" 25 "k8s.io/apimachinery/pkg/runtime" 26 "k8s.io/apimachinery/pkg/types" 27) 28 29// ObjectKey identifies a Kubernetes Object. 30type ObjectKey = types.NamespacedName 31 32// ObjectKeyFromObject returns the ObjectKey given a runtime.Object 33func ObjectKeyFromObject(obj runtime.Object) (ObjectKey, error) { 34 accessor, err := meta.Accessor(obj) 35 if err != nil { 36 return ObjectKey{}, err 37 } 38 return ObjectKey{Namespace: accessor.GetNamespace(), Name: accessor.GetName()}, nil 39} 40 41// Patch is a patch that can be applied to a Kubernetes object. 42type Patch interface { 43 // Type is the PatchType of the patch. 44 Type() types.PatchType 45 // Data is the raw data representing the patch. 46 Data(obj runtime.Object) ([]byte, error) 47} 48 49// TODO(directxman12): is there a sane way to deal with get/delete options? 50 51// Reader knows how to read and list Kubernetes objects. 52type Reader interface { 53 // Get retrieves an obj for the given object key from the Kubernetes Cluster. 54 // obj must be a struct pointer so that obj can be updated with the response 55 // returned by the Server. 56 Get(ctx context.Context, key ObjectKey, obj runtime.Object) error 57 58 // List retrieves list of objects for a given namespace and list options. On a 59 // successful call, Items field in the list will be populated with the 60 // result returned from the server. 61 List(ctx context.Context, list runtime.Object, opts ...ListOption) error 62} 63 64// Writer knows how to create, delete, and update Kubernetes objects. 65type Writer interface { 66 // Create saves the object obj in the Kubernetes cluster. 67 Create(ctx context.Context, obj runtime.Object, opts ...CreateOption) error 68 69 // Delete deletes the given obj from Kubernetes cluster. 70 Delete(ctx context.Context, obj runtime.Object, opts ...DeleteOption) error 71 72 // Update updates the given obj in the Kubernetes cluster. obj must be a 73 // struct pointer so that obj can be updated with the content returned by the Server. 74 Update(ctx context.Context, obj runtime.Object, opts ...UpdateOption) error 75 76 // Patch patches the given obj in the Kubernetes cluster. obj must be a 77 // struct pointer so that obj can be updated with the content returned by the Server. 78 Patch(ctx context.Context, obj runtime.Object, patch Patch, opts ...PatchOption) error 79 80 // DeleteAllOf deletes all objects of the given type matching the given options. 81 DeleteAllOf(ctx context.Context, obj runtime.Object, opts ...DeleteAllOfOption) error 82} 83 84// StatusClient knows how to create a client which can update status subresource 85// for kubernetes objects. 86type StatusClient interface { 87 Status() StatusWriter 88} 89 90// StatusWriter knows how to update status subresource of a Kubernetes object. 91type StatusWriter interface { 92 // Update updates the fields corresponding to the status subresource for the 93 // given obj. obj must be a struct pointer so that obj can be updated 94 // with the content returned by the Server. 95 Update(ctx context.Context, obj runtime.Object, opts ...UpdateOption) error 96 97 // Patch patches the given object's subresource. obj must be a struct 98 // pointer so that obj can be updated with the content returned by the 99 // Server. 100 Patch(ctx context.Context, obj runtime.Object, patch Patch, opts ...PatchOption) error 101} 102 103// Client knows how to perform CRUD operations on Kubernetes objects. 104type Client interface { 105 Reader 106 Writer 107 StatusClient 108} 109 110// IndexerFunc knows how to take an object and turn it into a series 111// of non-namespaced keys. Namespaced objects are automatically given 112// namespaced and non-spaced variants, so keys do not need to include namespace. 113type IndexerFunc func(runtime.Object) []string 114 115// FieldIndexer knows how to index over a particular "field" such that it 116// can later be used by a field selector. 117type FieldIndexer interface { 118 // IndexFields adds an index with the given field name on the given object type 119 // by using the given function to extract the value for that field. If you want 120 // compatibility with the Kubernetes API server, only return one key, and only use 121 // fields that the API server supports. Otherwise, you can return multiple keys, 122 // and "equality" in the field selector means that at least one key matches the value. 123 // The FieldIndexer will automatically take care of indexing over namespace 124 // and supporting efficient all-namespace queries. 125 IndexField(ctx context.Context, obj runtime.Object, field string, extractValue IndexerFunc) error 126} 127 128// IgnoreNotFound returns nil on NotFound errors. 129// All other values that are not NotFound errors or nil are returned unmodified. 130func IgnoreNotFound(err error) error { 131 if apierrors.IsNotFound(err) { 132 return nil 133 } 134 return err 135} 136