github.com/Racer159/jackal@v0.32.7-0.20240401174413-0bd2339e4f2e/src/pkg/k8s/secrets.go (about) 1 // SPDX-License-Identifier: Apache-2.0 2 // SPDX-FileCopyrightText: 2021-Present The Jackal Authors 3 4 // Package k8s provides a client for interacting with a Kubernetes cluster. 5 package k8s 6 7 import ( 8 "context" 9 "crypto/tls" 10 "fmt" 11 12 "github.com/defenseunicorns/pkg/helpers" 13 corev1 "k8s.io/api/core/v1" 14 "k8s.io/apimachinery/pkg/api/errors" 15 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 16 ) 17 18 // GetSecret returns a Kubernetes secret. 19 func (k *K8s) GetSecret(namespace, name string) (*corev1.Secret, error) { 20 return k.Clientset.CoreV1().Secrets(namespace).Get(context.TODO(), name, metav1.GetOptions{}) 21 } 22 23 // GetSecretsWithLabel returns a list of Kubernetes secrets with the given label. 24 func (k *K8s) GetSecretsWithLabel(namespace, labelSelector string) (*corev1.SecretList, error) { 25 listOptions := metav1.ListOptions{LabelSelector: labelSelector} 26 return k.Clientset.CoreV1().Secrets(namespace).List(context.TODO(), listOptions) 27 } 28 29 // GenerateSecret returns a Kubernetes secret object without applying it to the cluster. 30 func (k *K8s) GenerateSecret(namespace, name string, secretType corev1.SecretType) *corev1.Secret { 31 secret := &corev1.Secret{ 32 TypeMeta: metav1.TypeMeta{ 33 APIVersion: corev1.SchemeGroupVersion.String(), 34 Kind: "Secret", 35 }, 36 ObjectMeta: metav1.ObjectMeta{ 37 Name: name, 38 Namespace: namespace, 39 }, 40 Type: secretType, 41 Data: map[string][]byte{}, 42 } 43 44 // Merge in common labels so that later modifications to the secret can't mutate them 45 secret.ObjectMeta.Labels = helpers.MergeMap[string](k.Labels, secret.ObjectMeta.Labels) 46 47 return secret 48 } 49 50 // GenerateTLSSecret returns a Kubernetes secret object without applying it to the cluster. 51 func (k *K8s) GenerateTLSSecret(namespace, name string, conf GeneratedPKI) (*corev1.Secret, error) { 52 if _, err := tls.X509KeyPair(conf.Cert, conf.Key); err != nil { 53 return nil, err 54 } 55 56 secretTLS := k.GenerateSecret(namespace, name, corev1.SecretTypeTLS) 57 secretTLS.Data[corev1.TLSCertKey] = conf.Cert 58 secretTLS.Data[corev1.TLSPrivateKeyKey] = conf.Key 59 60 return secretTLS, nil 61 } 62 63 // CreateOrUpdateTLSSecret creates or updates a Kubernetes secret with a new TLS secret. 64 func (k *K8s) CreateOrUpdateTLSSecret(namespace, name string, conf GeneratedPKI) (*corev1.Secret, error) { 65 secret, err := k.GenerateTLSSecret(namespace, name, conf) 66 if err != nil { 67 return secret, err 68 } 69 70 return k.CreateOrUpdateSecret(secret) 71 } 72 73 // DeleteSecret deletes a Kubernetes secret. 74 func (k *K8s) DeleteSecret(secret *corev1.Secret) error { 75 namespaceSecrets := k.Clientset.CoreV1().Secrets(secret.Namespace) 76 77 err := namespaceSecrets.Delete(context.TODO(), secret.Name, metav1.DeleteOptions{}) 78 if err != nil && !errors.IsNotFound(err) { 79 return fmt.Errorf("error deleting the secret: %w", err) 80 } 81 82 return nil 83 } 84 85 // CreateOrUpdateSecret creates or updates a Kubernetes secret. 86 func (k *K8s) CreateOrUpdateSecret(secret *corev1.Secret) (createdSecret *corev1.Secret, err error) { 87 88 namespaceSecrets := k.Clientset.CoreV1().Secrets(secret.Namespace) 89 90 if _, err = k.GetSecret(secret.Namespace, secret.Name); err != nil { 91 // create the given secret 92 if createdSecret, err = namespaceSecrets.Create(context.TODO(), secret, metav1.CreateOptions{}); err != nil { 93 return createdSecret, fmt.Errorf("unable to create the secret: %w", err) 94 } 95 } else { 96 // update the given secret 97 if createdSecret, err = namespaceSecrets.Update(context.TODO(), secret, metav1.UpdateOptions{}); err != nil { 98 return createdSecret, fmt.Errorf("unable to update the secret: %w", err) 99 } 100 } 101 102 return createdSecret, nil 103 }