github.com/juju/juju@v0.0.0-20240430160146-1752b71fcf00/caas/kubernetes/provider/daemonset.go (about)

     1  // Copyright 2020 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package provider
     5  
     6  import (
     7  	"context"
     8  
     9  	"github.com/juju/errors"
    10  	apps "k8s.io/api/apps/v1"
    11  	k8serrors "k8s.io/apimachinery/pkg/api/errors"
    12  	v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    13  	"k8s.io/apimachinery/pkg/types"
    14  
    15  	"github.com/juju/juju/caas/kubernetes/provider/constants"
    16  	"github.com/juju/juju/caas/kubernetes/provider/utils"
    17  )
    18  
    19  func (k *kubernetesClient) ensureDaemonSet(spec *apps.DaemonSet) (func(), error) {
    20  	cleanUp := func() {}
    21  	out, err := k.createDaemonSet(spec)
    22  	if err == nil {
    23  		logger.Debugf("daemon set %q created", out.GetName())
    24  		cleanUp = func() { _ = k.deleteDaemonSet(out.GetName(), out.GetUID()) }
    25  		return cleanUp, nil
    26  	}
    27  	if !errors.IsAlreadyExists(err) {
    28  		return cleanUp, errors.Trace(err)
    29  	}
    30  	_, err = k.listDaemonSets(spec.GetLabels())
    31  	if err != nil {
    32  		if errors.IsNotFound(err) {
    33  			// spec.Name is already used for an existing daemon set.
    34  			return cleanUp, errors.AlreadyExistsf("daemon set %q", spec.GetName())
    35  		}
    36  		return cleanUp, errors.Trace(err)
    37  	}
    38  	_, err = k.updateDaemonSet(spec)
    39  	logger.Debugf("updating daemon set %q", spec.GetName())
    40  	return cleanUp, errors.Trace(err)
    41  }
    42  
    43  func (k *kubernetesClient) createDaemonSet(spec *apps.DaemonSet) (*apps.DaemonSet, error) {
    44  	if k.namespace == "" {
    45  		return nil, errNoNamespace
    46  	}
    47  	utils.PurifyResource(spec)
    48  	out, err := k.client().AppsV1().DaemonSets(k.namespace).Create(context.TODO(), spec, v1.CreateOptions{})
    49  	if k8serrors.IsAlreadyExists(err) {
    50  		return nil, errors.AlreadyExistsf("daemon set %q", spec.GetName())
    51  	}
    52  	return out, errors.Trace(err)
    53  }
    54  
    55  func (k *kubernetesClient) getDaemonSet(name string) (*apps.DaemonSet, error) {
    56  	if k.namespace == "" {
    57  		return nil, errNoNamespace
    58  	}
    59  	out, err := k.client().AppsV1().DaemonSets(k.namespace).Get(context.TODO(), name, v1.GetOptions{})
    60  	if k8serrors.IsNotFound(err) {
    61  		return nil, errors.NotFoundf("daemon set %q", name)
    62  	}
    63  	return out, errors.Trace(err)
    64  }
    65  
    66  func (k *kubernetesClient) updateDaemonSet(spec *apps.DaemonSet) (*apps.DaemonSet, error) {
    67  	if k.namespace == "" {
    68  		return nil, errNoNamespace
    69  	}
    70  	out, err := k.client().AppsV1().DaemonSets(k.namespace).Update(context.TODO(), spec, v1.UpdateOptions{})
    71  	if k8serrors.IsNotFound(err) {
    72  		return nil, errors.NotFoundf("daemon set %q", spec.GetName())
    73  	}
    74  	return out, errors.Trace(err)
    75  }
    76  
    77  func (k *kubernetesClient) deleteDaemonSet(name string, uid types.UID) error {
    78  	if k.namespace == "" {
    79  		return errNoNamespace
    80  	}
    81  	err := k.client().AppsV1().DaemonSets(k.namespace).Delete(context.TODO(), name, utils.NewPreconditionDeleteOptions(uid))
    82  	if k8serrors.IsNotFound(err) {
    83  		return nil
    84  	}
    85  	return errors.Trace(err)
    86  }
    87  
    88  func (k *kubernetesClient) listDaemonSets(labels map[string]string) ([]apps.DaemonSet, error) {
    89  	if k.namespace == "" {
    90  		return nil, errNoNamespace
    91  	}
    92  	listOps := v1.ListOptions{
    93  		LabelSelector: utils.LabelsToSelector(labels).String(),
    94  	}
    95  	out, err := k.client().AppsV1().DaemonSets(k.namespace).List(context.TODO(), listOps)
    96  	if err != nil {
    97  		return nil, errors.Trace(err)
    98  	}
    99  	if len(out.Items) == 0 {
   100  		return nil, errors.NotFoundf("daemon set with labels %v", labels)
   101  	}
   102  	return out.Items, nil
   103  }
   104  
   105  func (k *kubernetesClient) deleteDaemonSets(appName string) error {
   106  	if k.namespace == "" {
   107  		return errNoNamespace
   108  	}
   109  	labels := utils.LabelsForApp(appName, k.IsLegacyLabels())
   110  	err := k.client().AppsV1().DaemonSets(k.namespace).DeleteCollection(context.TODO(), v1.DeleteOptions{
   111  		PropagationPolicy: constants.DefaultPropagationPolicy(),
   112  	}, v1.ListOptions{
   113  		LabelSelector: utils.LabelsToSelector(labels).String(),
   114  	})
   115  	if k8serrors.IsNotFound(err) {
   116  		return nil
   117  	}
   118  	return errors.Trace(err)
   119  }