github.com/oam-dev/cluster-gateway@v1.9.0/pkg/util/cert/secret.go (about) 1 package cert 2 3 import ( 4 "bytes" 5 "context" 6 7 "github.com/oam-dev/cluster-gateway/pkg/common" 8 9 "github.com/pkg/errors" 10 corev1 "k8s.io/api/core/v1" 11 apierrors "k8s.io/apimachinery/pkg/api/errors" 12 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 13 "k8s.io/apimachinery/pkg/labels" 14 "k8s.io/apimachinery/pkg/selection" 15 "k8s.io/client-go/kubernetes" 16 corev1lister "k8s.io/client-go/listers/core/v1" 17 ) 18 19 func CopySecret(kubeClient kubernetes.Interface, sourceNamespace string, sourceName string, targetNamespace, targetName string) error { 20 sourceSecret, err := kubeClient.CoreV1(). 21 Secrets(sourceNamespace). 22 Get(context.TODO(), sourceName, metav1.GetOptions{}) 23 if err != nil { 24 return errors.Wrapf(err, "failed getting source secret %v/%v: %v", sourceNamespace, sourceName, err) 25 } 26 shouldCreate := false 27 existingTargetSecret, err := kubeClient.CoreV1(). 28 Secrets(targetNamespace). 29 Get(context.TODO(), targetName, metav1.GetOptions{}) 30 if err != nil { 31 if !apierrors.IsNotFound(err) { 32 return errors.Wrapf(err, "failed getting target secret %v/%v: %v", targetNamespace, targetName, err) 33 } 34 shouldCreate = true 35 } 36 if shouldCreate { 37 existingTargetSecret = sourceSecret.DeepCopy() 38 existingTargetSecret.Namespace = targetNamespace 39 existingTargetSecret.Name = targetName 40 existingTargetSecret.UID = "" 41 existingTargetSecret.ResourceVersion = "" 42 if _, err := kubeClient.CoreV1().Secrets(targetNamespace). 43 Create(context.TODO(), existingTargetSecret, metav1.CreateOptions{}); err != nil { 44 if !apierrors.IsAlreadyExists(err) { 45 return errors.Wrapf(err, "failed creating CA secret") 46 } 47 } 48 return nil 49 } 50 51 if IsSubset(sourceSecret.Data, existingTargetSecret.Data) { 52 return nil 53 } 54 Merge(sourceSecret.Data, existingTargetSecret.Data) 55 _, err = kubeClient.CoreV1(). 56 Secrets(targetNamespace). 57 Update(context.TODO(), existingTargetSecret, metav1.UpdateOptions{}) 58 return err 59 } 60 61 func IsSubset(subset, superset map[string][]byte) bool { 62 for k, v := range subset { 63 if !bytes.Equal(v, superset[k]) { 64 return false 65 } 66 } 67 return true 68 } 69 70 func Merge(l, r map[string][]byte) { 71 for k, v := range l { 72 r[k] = v 73 } 74 } 75 76 type SecretControl interface { 77 Get(ctx context.Context, name string) (*corev1.Secret, error) 78 List(ctx context.Context) ([]*corev1.Secret, error) 79 } 80 81 var _ SecretControl = &directApiSecretControl{} 82 83 type directApiSecretControl struct { 84 secretNamespace string 85 kubeClient kubernetes.Interface 86 } 87 88 func (d *directApiSecretControl) Get(ctx context.Context, name string) (*corev1.Secret, error) { 89 return d.kubeClient.CoreV1().Secrets(d.secretNamespace).Get(ctx, name, metav1.GetOptions{}) 90 } 91 92 func (d *directApiSecretControl) List(ctx context.Context) ([]*corev1.Secret, error) { 93 requirement, err := labels.NewRequirement( 94 common.LabelKeyClusterCredentialType, 95 selection.Exists, 96 nil) 97 if err != nil { 98 return nil, err 99 } 100 secretList, err := d.kubeClient.CoreV1().Secrets(d.secretNamespace).List(ctx, metav1.ListOptions{ 101 LabelSelector: labels.NewSelector().Add(*requirement).String(), 102 }) 103 if err != nil { 104 return nil, err 105 } 106 secrets := make([]*corev1.Secret, len(secretList.Items)) 107 for i := range secretList.Items { 108 secrets[i] = &secretList.Items[i] 109 } 110 return secrets, nil 111 } 112 113 var _ SecretControl = &cachedSecretControl{} 114 115 type cachedSecretControl struct { 116 secretNamespace string 117 secretLister corev1lister.SecretLister 118 } 119 120 func (c *cachedSecretControl) Get(ctx context.Context, name string) (*corev1.Secret, error) { 121 return c.secretLister.Secrets(c.secretNamespace).Get(name) 122 } 123 124 func (c *cachedSecretControl) List(ctx context.Context) ([]*corev1.Secret, error) { 125 requirement, err := labels.NewRequirement( 126 common.LabelKeyClusterCredentialType, 127 selection.Exists, 128 nil) 129 if err != nil { 130 return nil, err 131 } 132 selector := labels.NewSelector().Add(*requirement) 133 return c.secretLister.Secrets(c.secretNamespace).List(selector) 134 } 135 136 func NewDirectApiSecretControl(secretNamespace string, kubeClient kubernetes.Interface) SecretControl { 137 return &directApiSecretControl{ 138 secretNamespace: secretNamespace, 139 kubeClient: kubeClient, 140 } 141 } 142 143 func NewCachedSecretControl(secretNamespace string, secretLister corev1lister.SecretLister) SecretControl { 144 return &cachedSecretControl{ 145 secretNamespace: secretNamespace, 146 secretLister: secretLister, 147 } 148 }