...

Source file src/sigs.k8s.io/controller-runtime/pkg/client/interfaces.go

Documentation: sigs.k8s.io/controller-runtime/pkg/client

     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  
    22  	apierrors "k8s.io/apimachinery/pkg/api/errors"
    23  	"k8s.io/apimachinery/pkg/runtime/schema"
    24  
    25  	"k8s.io/apimachinery/pkg/api/meta"
    26  	"k8s.io/apimachinery/pkg/runtime"
    27  	"k8s.io/apimachinery/pkg/types"
    28  	"k8s.io/apimachinery/pkg/watch"
    29  )
    30  
    31  // ObjectKey identifies a Kubernetes Object.
    32  type ObjectKey = types.NamespacedName
    33  
    34  // ObjectKeyFromObject returns the ObjectKey given a runtime.Object.
    35  func ObjectKeyFromObject(obj Object) ObjectKey {
    36  	return ObjectKey{Namespace: obj.GetNamespace(), Name: obj.GetName()}
    37  }
    38  
    39  // Patch is a patch that can be applied to a Kubernetes object.
    40  type Patch interface {
    41  	// Type is the PatchType of the patch.
    42  	Type() types.PatchType
    43  	// Data is the raw data representing the patch.
    44  	Data(obj Object) ([]byte, error)
    45  }
    46  
    47  // TODO(directxman12): is there a sane way to deal with get/delete options?
    48  
    49  // Reader knows how to read and list Kubernetes objects.
    50  type Reader interface {
    51  	// Get retrieves an obj for the given object key from the Kubernetes Cluster.
    52  	// obj must be a struct pointer so that obj can be updated with the response
    53  	// returned by the Server.
    54  	Get(ctx context.Context, key ObjectKey, obj Object, opts ...GetOption) error
    55  
    56  	// List retrieves list of objects for a given namespace and list options. On a
    57  	// successful call, Items field in the list will be populated with the
    58  	// result returned from the server.
    59  	List(ctx context.Context, list ObjectList, opts ...ListOption) error
    60  }
    61  
    62  // Writer knows how to create, delete, and update Kubernetes objects.
    63  type Writer interface {
    64  	// Create saves the object obj in the Kubernetes cluster. obj must be a
    65  	// struct pointer so that obj can be updated with the content returned by the Server.
    66  	Create(ctx context.Context, obj Object, opts ...CreateOption) error
    67  
    68  	// Delete deletes the given obj from Kubernetes cluster.
    69  	Delete(ctx context.Context, obj Object, opts ...DeleteOption) error
    70  
    71  	// Update updates the given obj in the Kubernetes cluster. obj must be a
    72  	// struct pointer so that obj can be updated with the content returned by the Server.
    73  	Update(ctx context.Context, obj Object, opts ...UpdateOption) error
    74  
    75  	// Patch patches the given obj in the Kubernetes cluster. obj must be a
    76  	// struct pointer so that obj can be updated with the content returned by the Server.
    77  	Patch(ctx context.Context, obj Object, patch Patch, opts ...PatchOption) error
    78  
    79  	// DeleteAllOf deletes all objects of the given type matching the given options.
    80  	DeleteAllOf(ctx context.Context, obj Object, opts ...DeleteAllOfOption) error
    81  }
    82  
    83  // StatusClient knows how to create a client which can update status subresource
    84  // for kubernetes objects.
    85  type StatusClient interface {
    86  	Status() SubResourceWriter
    87  }
    88  
    89  // SubResourceClientConstructor knows how to create a client which can update subresource
    90  // for kubernetes objects.
    91  type SubResourceClientConstructor interface {
    92  	// SubResourceClientConstructor returns a subresource client for the named subResource. Known
    93  	// upstream subResources usages are:
    94  	// - ServiceAccount token creation:
    95  	//     sa := &corev1.ServiceAccount{ObjectMeta: metav1.ObjectMeta{Namespace: "foo", Name: "bar"}}
    96  	//     token := &authenticationv1.TokenRequest{}
    97  	//     c.SubResourceClient("token").Create(ctx, sa, token)
    98  	//
    99  	// - Pod eviction creation:
   100  	//     pod := &corev1.Pod{ObjectMeta: metav1.ObjectMeta{Namespace: "foo", Name: "bar"}}
   101  	//     c.SubResourceClient("eviction").Create(ctx, pod, &policyv1.Eviction{})
   102  	//
   103  	// - Pod binding creation:
   104  	//     pod := &corev1.Pod{ObjectMeta: metav1.ObjectMeta{Namespace: "foo", Name: "bar"}}
   105  	//     binding := &corev1.Binding{Target: corev1.ObjectReference{Name: "my-node"}}
   106  	//     c.SubResourceClient("binding").Create(ctx, pod, binding)
   107  	//
   108  	// - CertificateSigningRequest approval:
   109  	//     csr := &certificatesv1.CertificateSigningRequest{
   110  	//	     ObjectMeta: metav1.ObjectMeta{Namespace: "foo", Name: "bar"},
   111  	//       Status: certificatesv1.CertificateSigningRequestStatus{
   112  	//         Conditions: []certificatesv1.[]CertificateSigningRequestCondition{{
   113  	//           Type: certificatesv1.CertificateApproved,
   114  	//           Status: corev1.ConditionTrue,
   115  	//         }},
   116  	//       },
   117  	//     }
   118  	//     c.SubResourceClient("approval").Update(ctx, csr)
   119  	//
   120  	// - Scale retrieval:
   121  	//     dep := &appsv1.Deployment{ObjectMeta: metav1.ObjectMeta{Namespace: "foo", Name: "bar"}}
   122  	//     scale := &autoscalingv1.Scale{}
   123  	//     c.SubResourceClient("scale").Get(ctx, dep, scale)
   124  	//
   125  	// - Scale update:
   126  	//     dep := &appsv1.Deployment{ObjectMeta: metav1.ObjectMeta{Namespace: "foo", Name: "bar"}}
   127  	//     scale := &autoscalingv1.Scale{Spec: autoscalingv1.ScaleSpec{Replicas: 2}}
   128  	//     c.SubResourceClient("scale").Update(ctx, dep, client.WithSubResourceBody(scale))
   129  	SubResource(subResource string) SubResourceClient
   130  }
   131  
   132  // StatusWriter is kept for backward compatibility.
   133  type StatusWriter = SubResourceWriter
   134  
   135  // SubResourceReader knows how to read SubResources
   136  type SubResourceReader interface {
   137  	Get(ctx context.Context, obj Object, subResource Object, opts ...SubResourceGetOption) error
   138  }
   139  
   140  // SubResourceWriter knows how to update subresource of a Kubernetes object.
   141  type SubResourceWriter interface {
   142  	// Create saves the subResource object in the Kubernetes cluster. obj must be a
   143  	// struct pointer so that obj can be updated with the content returned by the Server.
   144  	Create(ctx context.Context, obj Object, subResource Object, opts ...SubResourceCreateOption) error
   145  
   146  	// Update updates the fields corresponding to the status subresource for the
   147  	// given obj. obj must be a struct pointer so that obj can be updated
   148  	// with the content returned by the Server.
   149  	Update(ctx context.Context, obj Object, opts ...SubResourceUpdateOption) error
   150  
   151  	// Patch patches the given object's subresource. obj must be a struct
   152  	// pointer so that obj can be updated with the content returned by the
   153  	// Server.
   154  	Patch(ctx context.Context, obj Object, patch Patch, opts ...SubResourcePatchOption) error
   155  }
   156  
   157  // SubResourceClient knows how to perform CRU operations on Kubernetes objects.
   158  type SubResourceClient interface {
   159  	SubResourceReader
   160  	SubResourceWriter
   161  }
   162  
   163  // Client knows how to perform CRUD operations on Kubernetes objects.
   164  type Client interface {
   165  	Reader
   166  	Writer
   167  	StatusClient
   168  	SubResourceClientConstructor
   169  
   170  	// Scheme returns the scheme this client is using.
   171  	Scheme() *runtime.Scheme
   172  	// RESTMapper returns the rest this client is using.
   173  	RESTMapper() meta.RESTMapper
   174  	// GroupVersionKindFor returns the GroupVersionKind for the given object.
   175  	GroupVersionKindFor(obj runtime.Object) (schema.GroupVersionKind, error)
   176  	// IsObjectNamespaced returns true if the GroupVersionKind of the object is namespaced.
   177  	IsObjectNamespaced(obj runtime.Object) (bool, error)
   178  }
   179  
   180  // WithWatch supports Watch on top of the CRUD operations supported by
   181  // the normal Client. Its intended use-case are CLI apps that need to wait for
   182  // events.
   183  type WithWatch interface {
   184  	Client
   185  	Watch(ctx context.Context, obj ObjectList, opts ...ListOption) (watch.Interface, error)
   186  }
   187  
   188  // IndexerFunc knows how to take an object and turn it into a series
   189  // of non-namespaced keys. Namespaced objects are automatically given
   190  // namespaced and non-spaced variants, so keys do not need to include namespace.
   191  type IndexerFunc func(Object) []string
   192  
   193  // FieldIndexer knows how to index over a particular "field" such that it
   194  // can later be used by a field selector.
   195  type FieldIndexer interface {
   196  	// IndexFields adds an index with the given field name on the given object type
   197  	// by using the given function to extract the value for that field.  If you want
   198  	// compatibility with the Kubernetes API server, only return one key, and only use
   199  	// fields that the API server supports.  Otherwise, you can return multiple keys,
   200  	// and "equality" in the field selector means that at least one key matches the value.
   201  	// The FieldIndexer will automatically take care of indexing over namespace
   202  	// and supporting efficient all-namespace queries.
   203  	IndexField(ctx context.Context, obj Object, field string, extractValue IndexerFunc) error
   204  }
   205  
   206  // IgnoreNotFound returns nil on NotFound errors.
   207  // All other values that are not NotFound errors or nil are returned unmodified.
   208  func IgnoreNotFound(err error) error {
   209  	if apierrors.IsNotFound(err) {
   210  		return nil
   211  	}
   212  	return err
   213  }
   214  
   215  // IgnoreAlreadyExists returns nil on AlreadyExists errors.
   216  // All other values that are not AlreadyExists errors or nil are returned unmodified.
   217  func IgnoreAlreadyExists(err error) error {
   218  	if apierrors.IsAlreadyExists(err) {
   219  		return nil
   220  	}
   221  
   222  	return err
   223  }
   224  

View as plain text