github.com/argoproj/argo-cd/v2@v2.10.5/util/kube/util.go (about) 1 package kube 2 3 import ( 4 "context" 5 6 apiv1 "k8s.io/api/core/v1" 7 "k8s.io/apimachinery/pkg/api/errors" 8 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 9 "k8s.io/client-go/kubernetes" 10 ) 11 12 type kubeUtil struct { 13 client kubernetes.Interface 14 ctx context.Context 15 labels map[string]string 16 annotations map[string]string 17 } 18 19 // updateFn will be called to set data for secret s. new will be true if the 20 // secret was created by the caller, or false if it has existed before. 21 type updateFn func(s *apiv1.Secret, new bool) error 22 23 // NewKubeUtil NewUtil returns a new kubeUtil receiver 24 func NewKubeUtil(client kubernetes.Interface, ctx context.Context) *kubeUtil { 25 return &kubeUtil{client: client, ctx: ctx} 26 } 27 28 // CreateOrUpdateSecret creates or updates a secret, using the update function. 29 // If the secret is created, its labels and annotations are set if non-empty in 30 // the receiver. If the secret is updated, labels and annotations will not be 31 // touched. 32 func (ku *kubeUtil) CreateOrUpdateSecret(ns string, name string, update updateFn) error { 33 var s *apiv1.Secret 34 var err error 35 var new bool 36 37 s, err = ku.client.CoreV1().Secrets(ns).Get(ku.ctx, name, metav1.GetOptions{}) 38 if err != nil { 39 if !errors.IsNotFound(err) { 40 return err 41 } 42 new = true 43 } 44 45 if new { 46 s = &apiv1.Secret{ 47 ObjectMeta: metav1.ObjectMeta{ 48 Name: name, 49 Namespace: ns, 50 Labels: ku.labels, 51 Annotations: ku.annotations, 52 }, 53 } 54 s.Data = make(map[string][]byte) 55 } 56 57 err = update(s, new) 58 if err != nil { 59 return err 60 } 61 62 if new { 63 _, err = ku.client.CoreV1().Secrets(ns).Create(ku.ctx, s, metav1.CreateOptions{}) 64 } else { 65 _, err = ku.client.CoreV1().Secrets(ns).Update(ku.ctx, s, metav1.UpdateOptions{}) 66 } 67 68 return err 69 70 } 71 72 // CreateOrUpdateSecretField creates or updates a secret name in namespace ns, with given value for given field 73 func (ku *kubeUtil) CreateOrUpdateSecretField(ns string, name string, field string, value string) error { 74 err := ku.CreateOrUpdateSecret(ns, name, func(s *apiv1.Secret, new bool) error { 75 s.Data[field] = []byte(value) 76 return nil 77 }) 78 return err 79 } 80 81 // CreateOrUpdateSecretData creates or updates a secret name in namespace ns, with given data. 82 // If merge is true, merges data with the existing data, otherwise overwrites it. 83 func (ku *kubeUtil) CreateOrUpdateSecretData(ns string, name string, data map[string][]byte, merge bool) error { 84 err := ku.CreateOrUpdateSecret(ns, name, func(s *apiv1.Secret, new bool) error { 85 if !merge || new { 86 s.Data = data 87 } else { 88 for key, val := range data { 89 s.Data[key] = val 90 } 91 } 92 return nil 93 }) 94 return err 95 } 96 97 // DeepCopy returns a copy of ku 98 func (ku *kubeUtil) DeepCopy() *kubeUtil { 99 kun := &kubeUtil{ 100 client: ku.client, 101 ctx: ku.ctx, 102 labels: ku.labels, 103 annotations: ku.annotations, 104 } 105 return kun 106 } 107 108 // WithLabels returns a copy of ku with labels attached 109 func (ku *kubeUtil) WithLabels(labels map[string]string) *kubeUtil { 110 kun := ku.DeepCopy() 111 kun.labels = labels 112 return kun 113 } 114 115 // WithAnnotations returns a copy of ku with annotations attached 116 func (ku *kubeUtil) WithAnnotations(annotations map[string]string) *kubeUtil { 117 kun := ku.DeepCopy() 118 kun.annotations = annotations 119 return kun 120 }