github.com/Racer159/jackal@v0.32.7-0.20240401174413-0bd2339e4f2e/src/pkg/k8s/dynamic.go (about)

     1  // SPDX-License-Identifier: Apache-2.0
     2  // SPDX-FileCopyrightText: 2021-Present The Jackal Authors
     3  
     4  // Package k8s provides a client for interacting with a Kubernetes cluster.
     5  package k8s
     6  
     7  import (
     8  	"context"
     9  
    10  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    11  	"k8s.io/apimachinery/pkg/runtime/schema"
    12  	"k8s.io/client-go/discovery"
    13  	"k8s.io/client-go/dynamic"
    14  	"k8s.io/client-go/restmapper"
    15  )
    16  
    17  // AddLabelsAndAnnotations adds the provided labels and annotations to the specified K8s resource
    18  func (k *K8s) AddLabelsAndAnnotations(resourceNamespace string, resourceName string, groupKind schema.GroupKind, labels map[string]string, annotations map[string]string) error {
    19  	return k.updateLabelsAndAnnotations(resourceNamespace, resourceName, groupKind, labels, annotations, false)
    20  }
    21  
    22  // RemoveLabelsAndAnnotations removes the provided labels and annotations to the specified K8s resource
    23  func (k *K8s) RemoveLabelsAndAnnotations(resourceNamespace string, resourceName string, groupKind schema.GroupKind, labels map[string]string, annotations map[string]string) error {
    24  	return k.updateLabelsAndAnnotations(resourceNamespace, resourceName, groupKind, labels, annotations, true)
    25  }
    26  
    27  // updateLabelsAndAnnotations updates the provided labels and annotations to the specified K8s resource
    28  func (k *K8s) updateLabelsAndAnnotations(resourceNamespace string, resourceName string, groupKind schema.GroupKind, labels map[string]string, annotations map[string]string, isRemove bool) error {
    29  	dynamicClient := dynamic.NewForConfigOrDie(k.RestConfig)
    30  
    31  	discoveryClient := discovery.NewDiscoveryClientForConfigOrDie(k.RestConfig)
    32  
    33  	groupResources, err := restmapper.GetAPIGroupResources(discoveryClient)
    34  	if err != nil {
    35  		return err
    36  	}
    37  	mapper := restmapper.NewDiscoveryRESTMapper(groupResources)
    38  
    39  	mapping, err := mapper.RESTMapping(groupKind)
    40  	if err != nil {
    41  		return err
    42  	}
    43  
    44  	deployedResource, err := dynamicClient.Resource(mapping.Resource).Namespace(resourceNamespace).Get(context.TODO(), resourceName, metav1.GetOptions{})
    45  	if err != nil {
    46  		return err
    47  	}
    48  
    49  	// Pull the existing labels from the rendered resource
    50  	deployedLabels := deployedResource.GetLabels()
    51  	if deployedLabels == nil {
    52  		// Ensure label map exists to avoid nil panic
    53  		deployedLabels = make(map[string]string)
    54  	}
    55  	for key, value := range labels {
    56  		if isRemove {
    57  			delete(deployedLabels, key)
    58  		} else {
    59  			deployedLabels[key] = value
    60  		}
    61  	}
    62  
    63  	deployedResource.SetLabels(deployedLabels)
    64  
    65  	// Pull the existing annotations from the rendered resource
    66  	deployedAnnotations := deployedResource.GetAnnotations()
    67  	if deployedAnnotations == nil {
    68  		// Ensure label map exists to avoid nil panic
    69  		deployedAnnotations = make(map[string]string)
    70  	}
    71  	for key, value := range annotations {
    72  		if isRemove {
    73  			delete(deployedAnnotations, key)
    74  		} else {
    75  			deployedAnnotations[key] = value
    76  		}
    77  	}
    78  
    79  	deployedResource.SetAnnotations(deployedAnnotations)
    80  
    81  	_, err = dynamicClient.Resource(mapping.Resource).Namespace(resourceNamespace).Update(context.TODO(), deployedResource, metav1.UpdateOptions{})
    82  	return err
    83  }