...

Source file src/sigs.k8s.io/controller-runtime/pkg/client/example_test.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_test
    18  
    19  import (
    20  	"context"
    21  	"fmt"
    22  	"os"
    23  	"time"
    24  
    25  	corev1 "k8s.io/api/core/v1"
    26  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    27  	"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
    28  	"k8s.io/apimachinery/pkg/runtime"
    29  	"k8s.io/apimachinery/pkg/runtime/schema"
    30  	"k8s.io/apimachinery/pkg/types"
    31  	corev1ac "k8s.io/client-go/applyconfigurations/core/v1"
    32  
    33  	"sigs.k8s.io/controller-runtime/pkg/client"
    34  	"sigs.k8s.io/controller-runtime/pkg/client/config"
    35  	"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
    36  )
    37  
    38  var (
    39  	c           client.Client
    40  	someIndexer client.FieldIndexer
    41  )
    42  
    43  func ExampleNew() {
    44  	cl, err := client.New(config.GetConfigOrDie(), client.Options{})
    45  	if err != nil {
    46  		fmt.Println("failed to create client")
    47  		os.Exit(1)
    48  	}
    49  
    50  	podList := &corev1.PodList{}
    51  
    52  	err = cl.List(context.Background(), podList, client.InNamespace("default"))
    53  	if err != nil {
    54  		fmt.Printf("failed to list pods in namespace default: %v\n", err)
    55  		os.Exit(1)
    56  	}
    57  }
    58  
    59  // This example shows how to use the client with typed and unstructured objects to retrieve an object.
    60  func ExampleClient_get() {
    61  	// Using a typed object.
    62  	pod := &corev1.Pod{}
    63  	// c is a created client.
    64  	_ = c.Get(context.Background(), client.ObjectKey{
    65  		Namespace: "namespace",
    66  		Name:      "name",
    67  	}, pod)
    68  
    69  	// Using a unstructured object.
    70  	u := &unstructured.Unstructured{}
    71  	u.SetGroupVersionKind(schema.GroupVersionKind{
    72  		Group:   "apps",
    73  		Kind:    "Deployment",
    74  		Version: "v1",
    75  	})
    76  	_ = c.Get(context.Background(), client.ObjectKey{
    77  		Namespace: "namespace",
    78  		Name:      "name",
    79  	}, u)
    80  }
    81  
    82  // This example shows how to use the client with typed and unstructured objects to create objects.
    83  func ExampleClient_create() {
    84  	// Using a typed object.
    85  	pod := &corev1.Pod{
    86  		ObjectMeta: metav1.ObjectMeta{
    87  			Namespace: "namespace",
    88  			Name:      "name",
    89  		},
    90  		Spec: corev1.PodSpec{
    91  			Containers: []corev1.Container{
    92  				{
    93  					Image: "nginx",
    94  					Name:  "nginx",
    95  				},
    96  			},
    97  		},
    98  	}
    99  	// c is a created client.
   100  	_ = c.Create(context.Background(), pod)
   101  
   102  	// Using a unstructured object.
   103  	u := &unstructured.Unstructured{}
   104  	u.Object = map[string]interface{}{
   105  		"metadata": map[string]interface{}{
   106  			"name":      "name",
   107  			"namespace": "namespace",
   108  		},
   109  		"spec": map[string]interface{}{
   110  			"replicas": 2,
   111  			"selector": map[string]interface{}{
   112  				"matchLabels": map[string]interface{}{
   113  					"foo": "bar",
   114  				},
   115  			},
   116  			"template": map[string]interface{}{
   117  				"labels": map[string]interface{}{
   118  					"foo": "bar",
   119  				},
   120  				"spec": map[string]interface{}{
   121  					"containers": []map[string]interface{}{
   122  						{
   123  							"name":  "nginx",
   124  							"image": "nginx",
   125  						},
   126  					},
   127  				},
   128  			},
   129  		},
   130  	}
   131  	u.SetGroupVersionKind(schema.GroupVersionKind{
   132  		Group:   "apps",
   133  		Kind:    "Deployment",
   134  		Version: "v1",
   135  	})
   136  	_ = c.Create(context.Background(), u)
   137  }
   138  
   139  // This example shows how to use the client with typed and unstructured objects to list objects.
   140  func ExampleClient_list() {
   141  	// Using a typed object.
   142  	pod := &corev1.PodList{}
   143  	// c is a created client.
   144  	_ = c.List(context.Background(), pod)
   145  
   146  	// Using a unstructured object.
   147  	u := &unstructured.UnstructuredList{}
   148  	u.SetGroupVersionKind(schema.GroupVersionKind{
   149  		Group:   "apps",
   150  		Kind:    "DeploymentList",
   151  		Version: "v1",
   152  	})
   153  	_ = c.List(context.Background(), u)
   154  }
   155  
   156  // This example shows how to use the client with typed and unstructured objects to update objects.
   157  func ExampleClient_update() {
   158  	// Using a typed object.
   159  	pod := &corev1.Pod{}
   160  	// c is a created client.
   161  	_ = c.Get(context.Background(), client.ObjectKey{
   162  		Namespace: "namespace",
   163  		Name:      "name",
   164  	}, pod)
   165  	controllerutil.AddFinalizer(pod, "new-finalizer")
   166  	_ = c.Update(context.Background(), pod)
   167  
   168  	// Using a unstructured object.
   169  	u := &unstructured.Unstructured{}
   170  	u.SetGroupVersionKind(schema.GroupVersionKind{
   171  		Group:   "apps",
   172  		Kind:    "Deployment",
   173  		Version: "v1",
   174  	})
   175  	_ = c.Get(context.Background(), client.ObjectKey{
   176  		Namespace: "namespace",
   177  		Name:      "name",
   178  	}, u)
   179  	controllerutil.AddFinalizer(u, "new-finalizer")
   180  	_ = c.Update(context.Background(), u)
   181  }
   182  
   183  // This example shows how to use the client with typed and unstructured objects to patch objects.
   184  func ExampleClient_patch() {
   185  	patch := []byte(`{"metadata":{"annotations":{"version": "v2"}}}`)
   186  	_ = c.Patch(context.Background(), &corev1.Pod{
   187  		ObjectMeta: metav1.ObjectMeta{
   188  			Namespace: "namespace",
   189  			Name:      "name",
   190  		},
   191  	}, client.RawPatch(types.StrategicMergePatchType, patch))
   192  }
   193  
   194  // This example shows how to use the client with unstructured objects to create/patch objects using Server Side Apply,
   195  // "k8s.io/apimachinery/pkg/runtime".DefaultUnstructuredConverter.ToUnstructured is used to convert an object into map[string]any representation,
   196  // which is then set as an "Object" field in *unstructured.Unstructured struct, which implements client.Object.
   197  func ExampleClient_apply() {
   198  	// Using a typed object.
   199  	configMap := corev1ac.ConfigMap("name", "namespace").WithData(map[string]string{"key": "value"})
   200  	// c is a created client.
   201  	u := &unstructured.Unstructured{}
   202  	u.Object, _ = runtime.DefaultUnstructuredConverter.ToUnstructured(configMap)
   203  	_ = c.Patch(context.Background(), u, client.Apply, client.ForceOwnership, client.FieldOwner("field-owner"))
   204  }
   205  
   206  // This example shows how to use the client with typed and unstructured objects to patch objects' status.
   207  func ExampleClient_patchStatus() {
   208  	u := &unstructured.Unstructured{}
   209  	u.Object = map[string]interface{}{
   210  		"metadata": map[string]interface{}{
   211  			"name":      "foo",
   212  			"namespace": "namespace",
   213  		},
   214  	}
   215  	u.SetGroupVersionKind(schema.GroupVersionKind{
   216  		Group:   "batch",
   217  		Version: "v1beta1",
   218  		Kind:    "CronJob",
   219  	})
   220  	patch := []byte(fmt.Sprintf(`{"status":{"lastScheduleTime":"%s"}}`, time.Now().Format(time.RFC3339)))
   221  	_ = c.Status().Patch(context.Background(), u, client.RawPatch(types.MergePatchType, patch))
   222  }
   223  
   224  // This example shows how to use the client with typed and unstructured objects to delete objects.
   225  func ExampleClient_delete() {
   226  	// Using a typed object.
   227  	pod := &corev1.Pod{
   228  		ObjectMeta: metav1.ObjectMeta{
   229  			Namespace: "namespace",
   230  			Name:      "name",
   231  		},
   232  	}
   233  	// c is a created client.
   234  	_ = c.Delete(context.Background(), pod)
   235  
   236  	// Using a unstructured object.
   237  	u := &unstructured.Unstructured{}
   238  	u.SetName("name")
   239  	u.SetNamespace("namespace")
   240  	u.SetGroupVersionKind(schema.GroupVersionKind{
   241  		Group:   "apps",
   242  		Kind:    "Deployment",
   243  		Version: "v1",
   244  	})
   245  	_ = c.Delete(context.Background(), u)
   246  }
   247  
   248  // This example shows how to use the client with typed and unstructured objects to delete collections of objects.
   249  func ExampleClient_deleteAllOf() {
   250  	// Using a typed object.
   251  	// c is a created client.
   252  	_ = c.DeleteAllOf(context.Background(), &corev1.Pod{}, client.InNamespace("foo"), client.MatchingLabels{"app": "foo"})
   253  
   254  	// Using an unstructured Object
   255  	u := &unstructured.Unstructured{}
   256  	u.SetGroupVersionKind(schema.GroupVersionKind{
   257  		Group:   "apps",
   258  		Kind:    "Deployment",
   259  		Version: "v1",
   260  	})
   261  	_ = c.DeleteAllOf(context.Background(), u, client.InNamespace("foo"), client.MatchingLabels{"app": "foo"})
   262  }
   263  
   264  // This example shows how to set up and consume a field selector over a pod's volumes' secretName field.
   265  func ExampleFieldIndexer_secretNameNode() {
   266  	// someIndexer is a FieldIndexer over a Cache
   267  	_ = someIndexer.IndexField(context.TODO(), &corev1.Pod{}, "spec.volumes.secret.secretName", func(o client.Object) []string {
   268  		var res []string
   269  		for _, vol := range o.(*corev1.Pod).Spec.Volumes {
   270  			if vol.Secret == nil {
   271  				continue
   272  			}
   273  			// just return the raw field value -- the indexer will take care of dealing with namespaces for us
   274  			res = append(res, vol.Secret.SecretName)
   275  		}
   276  		return res
   277  	})
   278  
   279  	_ = someIndexer.IndexField(context.TODO(), &corev1.Pod{}, "spec.NodeName", func(o client.Object) []string {
   280  		nodeName := o.(*corev1.Pod).Spec.NodeName
   281  		if nodeName != "" {
   282  			return []string{nodeName}
   283  		}
   284  		return nil
   285  	})
   286  
   287  	// elsewhere (e.g. in your reconciler)
   288  	mySecretName := "someSecret" // derived from the reconcile.Request, for instance
   289  	myNode := "master-0"
   290  	var podsWithSecrets corev1.PodList
   291  	_ = c.List(context.Background(), &podsWithSecrets, client.MatchingFields{
   292  		"spec.volumes.secret.secretName": mySecretName,
   293  		"spec.NodeName":                  myNode,
   294  	})
   295  }
   296  

View as plain text