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 }