github.com/juju/juju@v0.0.0-20240430160146-1752b71fcf00/caas/kubernetes/provider/resources/secret.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 corev1 "k8s.io/api/core/v1" 12 k8serrors "k8s.io/apimachinery/pkg/api/errors" 13 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 14 "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" 15 "k8s.io/apimachinery/pkg/runtime" 16 types "k8s.io/apimachinery/pkg/types" 17 "k8s.io/client-go/kubernetes" 18 19 k8sconstants "github.com/juju/juju/caas/kubernetes/provider/constants" 20 "github.com/juju/juju/core/status" 21 ) 22 23 // Secret extends the k8s secret. 24 type Secret struct { 25 corev1.Secret 26 } 27 28 // NewSecret creates a new secret resource. 29 func NewSecret(name string, namespace string, in *corev1.Secret) *Secret { 30 if in == nil { 31 in = &corev1.Secret{} 32 } 33 in.SetName(name) 34 in.SetNamespace(namespace) 35 return &Secret{*in} 36 } 37 38 // ListSecrets returns a list of Secrets. 39 func ListSecrets(ctx context.Context, client kubernetes.Interface, namespace string, opts metav1.ListOptions) ([]Secret, error) { 40 api := client.CoreV1().Secrets(namespace) 41 var items []Secret 42 for { 43 res, err := api.List(ctx, opts) 44 if err != nil { 45 return nil, errors.Trace(err) 46 } 47 for _, v := range res.Items { 48 items = append(items, Secret{Secret: v}) 49 } 50 if res.RemainingItemCount == nil || *res.RemainingItemCount == 0 { 51 break 52 } 53 opts.Continue = res.Continue 54 } 55 return items, nil 56 } 57 58 // Clone returns a copy of the resource. 59 func (s *Secret) Clone() Resource { 60 clone := *s 61 return &clone 62 } 63 64 // ID returns a comparable ID for the Resource 65 func (s *Secret) ID() ID { 66 return ID{"Secret", s.Name, s.Namespace} 67 } 68 69 // Apply patches the resource change. 70 func (s *Secret) Apply(ctx context.Context, client kubernetes.Interface) error { 71 api := client.CoreV1().Secrets(s.Namespace) 72 data, err := runtime.Encode(unstructured.UnstructuredJSONScheme, &s.Secret) 73 if err != nil { 74 return errors.Trace(err) 75 } 76 res, err := api.Patch(ctx, s.Name, types.StrategicMergePatchType, data, metav1.PatchOptions{ 77 FieldManager: JujuFieldManager, 78 }) 79 if k8serrors.IsNotFound(err) { 80 res, err = api.Create(ctx, &s.Secret, metav1.CreateOptions{ 81 FieldManager: JujuFieldManager, 82 }) 83 } 84 if k8serrors.IsConflict(err) { 85 return errors.Annotatef(errConflict, "secret %q", s.Name) 86 } 87 if err != nil { 88 return errors.Trace(err) 89 } 90 s.Secret = *res 91 return nil 92 } 93 94 // Get refreshes the resource. 95 func (s *Secret) Get(ctx context.Context, client kubernetes.Interface) error { 96 api := client.CoreV1().Secrets(s.Namespace) 97 res, err := api.Get(ctx, s.Name, metav1.GetOptions{}) 98 if k8serrors.IsNotFound(err) { 99 return errors.NewNotFound(err, "k8s") 100 } else if err != nil { 101 return errors.Trace(err) 102 } 103 s.Secret = *res 104 return nil 105 } 106 107 // Delete removes the resource. 108 func (s *Secret) Delete(ctx context.Context, client kubernetes.Interface) error { 109 api := client.CoreV1().Secrets(s.Namespace) 110 err := api.Delete(ctx, s.Name, metav1.DeleteOptions{ 111 PropagationPolicy: k8sconstants.DefaultPropagationPolicy(), 112 }) 113 if k8serrors.IsNotFound(err) { 114 return nil 115 } else if err != nil { 116 return errors.Trace(err) 117 } 118 return nil 119 } 120 121 // Events emitted by the resource. 122 func (s *Secret) Events(ctx context.Context, client kubernetes.Interface) ([]corev1.Event, error) { 123 return ListEventsForObject(ctx, client, s.Namespace, s.Name, "Secret") 124 } 125 126 // ComputeStatus returns a juju status for the resource. 127 func (s *Secret) ComputeStatus(ctx context.Context, client kubernetes.Interface, now time.Time) (string, status.Status, time.Time, error) { 128 if s.DeletionTimestamp != nil { 129 return "", status.Terminated, s.DeletionTimestamp.Time, nil 130 } 131 return "", status.Active, s.CreationTimestamp.Time, nil 132 }