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

     1  // Copyright 2020 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package resources
     5  
     6  import (
     7  	"context"
     8  	"time"
     9  
    10  	"github.com/juju/errors"
    11  	appsv1 "k8s.io/api/apps/v1"
    12  	corev1 "k8s.io/api/core/v1"
    13  	k8serrors "k8s.io/apimachinery/pkg/api/errors"
    14  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    15  	"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
    16  	"k8s.io/apimachinery/pkg/runtime"
    17  	types "k8s.io/apimachinery/pkg/types"
    18  	"k8s.io/client-go/kubernetes"
    19  
    20  	k8sconstants "github.com/juju/juju/caas/kubernetes/provider/constants"
    21  	"github.com/juju/juju/core/status"
    22  )
    23  
    24  // DaemonSet extends the k8s daemonset.
    25  type DaemonSet struct {
    26  	appsv1.DaemonSet
    27  }
    28  
    29  // NewDaemonSet creates a new daemonSet resource.
    30  func NewDaemonSet(name string, namespace string, in *appsv1.DaemonSet) *DaemonSet {
    31  	if in == nil {
    32  		in = &appsv1.DaemonSet{}
    33  	}
    34  	in.SetName(name)
    35  	in.SetNamespace(namespace)
    36  	return &DaemonSet{*in}
    37  }
    38  
    39  // Clone returns a copy of the resource.
    40  func (ds *DaemonSet) Clone() Resource {
    41  	clone := *ds
    42  	return &clone
    43  }
    44  
    45  // ID returns a comparable ID for the Resource
    46  func (ds *DaemonSet) ID() ID {
    47  	return ID{"DaemonSet", ds.Name, ds.Namespace}
    48  }
    49  
    50  // Apply patches the resource change.
    51  func (ds *DaemonSet) Apply(ctx context.Context, client kubernetes.Interface) error {
    52  	api := client.AppsV1().DaemonSets(ds.Namespace)
    53  	data, err := runtime.Encode(unstructured.UnstructuredJSONScheme, &ds.DaemonSet)
    54  	if err != nil {
    55  		return errors.Trace(err)
    56  	}
    57  	res, err := api.Patch(ctx, ds.Name, types.StrategicMergePatchType, data, metav1.PatchOptions{
    58  		FieldManager: JujuFieldManager,
    59  	})
    60  	if k8serrors.IsNotFound(err) {
    61  		res, err = api.Create(ctx, &ds.DaemonSet, metav1.CreateOptions{
    62  			FieldManager: JujuFieldManager,
    63  		})
    64  	}
    65  	if k8serrors.IsConflict(err) {
    66  		return errors.Annotatef(errConflict, "daemon set %q", ds.Name)
    67  	}
    68  	if err != nil {
    69  		return errors.Trace(err)
    70  	}
    71  	ds.DaemonSet = *res
    72  	return nil
    73  }
    74  
    75  // Get refreshes the resource.
    76  func (ds *DaemonSet) Get(ctx context.Context, client kubernetes.Interface) error {
    77  	api := client.AppsV1().DaemonSets(ds.Namespace)
    78  	res, err := api.Get(ctx, ds.Name, metav1.GetOptions{})
    79  	if k8serrors.IsNotFound(err) {
    80  		return errors.NewNotFound(err, "k8s")
    81  	} else if err != nil {
    82  		return errors.Trace(err)
    83  	}
    84  	ds.DaemonSet = *res
    85  	return nil
    86  }
    87  
    88  // Delete removes the resource.
    89  func (ds *DaemonSet) Delete(ctx context.Context, client kubernetes.Interface) error {
    90  	api := client.AppsV1().DaemonSets(ds.Namespace)
    91  	err := api.Delete(ctx, ds.Name, metav1.DeleteOptions{
    92  		PropagationPolicy: k8sconstants.DefaultPropagationPolicy(),
    93  	})
    94  	if k8serrors.IsNotFound(err) {
    95  		return nil
    96  	} else if err != nil {
    97  		return errors.Trace(err)
    98  	}
    99  	return nil
   100  }
   101  
   102  // Events emitted by the resource.
   103  func (ds *DaemonSet) Events(ctx context.Context, client kubernetes.Interface) ([]corev1.Event, error) {
   104  	return ListEventsForObject(ctx, client, ds.Namespace, ds.Name, "DaemonSet")
   105  }
   106  
   107  // ComputeStatus returns a juju status for the resource.
   108  func (ds *DaemonSet) ComputeStatus(ctx context.Context, client kubernetes.Interface, now time.Time) (string, status.Status, time.Time, error) {
   109  	if ds.DeletionTimestamp != nil {
   110  		return "", status.Terminated, ds.DeletionTimestamp.Time, nil
   111  	}
   112  	if ds.Status.NumberReady == ds.Status.DesiredNumberScheduled {
   113  		return "", status.Active, now, nil
   114  	}
   115  	return "", status.Waiting, now, nil
   116  }