sigs.k8s.io/controller-runtime@v0.18.2/pkg/client/example_test.go (about) 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 }