github.com/verrazzano/verrazzano@v1.7.1/tests/e2e/pkg/secrets.go (about)

     1  // Copyright (c) 2021, 2023, Oracle and/or its affiliates.
     2  // Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl.
     3  
     4  package pkg
     5  
     6  import (
     7  	"context"
     8  	"encoding/base64"
     9  	"fmt"
    10  	"strings"
    11  
    12  	"github.com/verrazzano/verrazzano/pkg/k8sutil"
    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  // ListSecrets returns the list of secrets in a given namespace for the cluster
    19  func ListSecrets(namespace string) (*corev1.SecretList, error) {
    20  	// Get the kubernetes clientset
    21  	clientset, err := k8sutil.GetKubernetesClientset()
    22  	if err != nil {
    23  		Log(Error, fmt.Sprintf("Failed to get clientset with error: %v", err))
    24  		return nil, err
    25  	}
    26  
    27  	secrets, err := clientset.CoreV1().Secrets(namespace).List(context.TODO(), metav1.ListOptions{})
    28  	if err != nil {
    29  		Log(Error, fmt.Sprintf("Failed to list secrets in namespace %s with error: %v", namespace, err))
    30  		return nil, err
    31  	}
    32  	return secrets, nil
    33  }
    34  
    35  // GetSecret returns the secret in a given namespace for the cluster specified in the environment
    36  func GetSecret(namespace string, name string) (*corev1.Secret, error) {
    37  	kubeconfigPath, err := k8sutil.GetKubeConfigLocation()
    38  	if err != nil {
    39  		Log(Error, fmt.Sprintf("Error getting kubeconfig, error: %v", err))
    40  		return nil, err
    41  	}
    42  	return GetSecretInCluster(namespace, name, kubeconfigPath)
    43  }
    44  
    45  // GetSecretInCluster returns the secret in a given namespace for the given cluster
    46  func GetSecretInCluster(namespace string, name string, kubeconfigPath string) (*corev1.Secret, error) {
    47  	// Get the kubernetes clientset for the given cluster
    48  	clientset, err := GetKubernetesClientsetForCluster(kubeconfigPath)
    49  	if err != nil {
    50  		return nil, err
    51  	}
    52  	secret, err := clientset.CoreV1().Secrets(namespace).Get(context.TODO(), name, metav1.GetOptions{})
    53  	if err != nil {
    54  		Log(Info, fmt.Sprintf("GetSecretInCluster error: %s", err))
    55  	}
    56  	return secret, err
    57  }
    58  
    59  // CreateCredentialsSecret creates opaque secret
    60  func CreateCredentialsSecret(namespace string, name string, username string, pw string, labels map[string]string) (*corev1.Secret, error) {
    61  	return CreateCredentialsSecretFromMap(namespace, name, map[string]string{
    62  		"password": pw,
    63  		"username": username,
    64  	}, labels)
    65  }
    66  
    67  // CreateCredentialsSecretInCluster creates opaque secret
    68  func CreateCredentialsSecretInCluster(namespace string, name string, username string, pw string, labels map[string]string, kubeconfigPath string) (*corev1.Secret, error) {
    69  	return CreateCredentialsSecretFromMapInCluster(namespace, name, map[string]string{
    70  		"password": pw,
    71  		"username": username,
    72  	}, labels, kubeconfigPath)
    73  }
    74  
    75  // CreateCredentialsSecretFromMap creates opaque secret from the given map of values
    76  func CreateCredentialsSecretFromMap(namespace string, name string, values, labels map[string]string) (*corev1.Secret, error) {
    77  	Log(Info, fmt.Sprintf("CreateCredentialsSecret %s in %s", name, namespace))
    78  	// Get the kubernetes clientset
    79  	clientset, err := k8sutil.GetKubernetesClientset()
    80  	if err != nil {
    81  		Log(Error, fmt.Sprintf("Failed to get clientset with error: %v", err))
    82  		return nil, err
    83  	}
    84  
    85  	secret := &corev1.Secret{
    86  		ObjectMeta: metav1.ObjectMeta{
    87  			Name:      name,
    88  			Namespace: namespace,
    89  			Labels:    labels,
    90  		},
    91  		Type:       corev1.SecretTypeOpaque,
    92  		StringData: values,
    93  	}
    94  	scr, err := clientset.CoreV1().Secrets(namespace).Create(context.TODO(), secret, metav1.CreateOptions{})
    95  	if err != nil {
    96  		Log(Error, fmt.Sprintf("CreateSecretOfOpaque %v error: %v", name, err))
    97  	}
    98  	return scr, err
    99  }
   100  
   101  // CreateCredentialsSecretFromMapInCluster creates opaque secret from the given map of values
   102  func CreateCredentialsSecretFromMapInCluster(namespace string, name string, values, labels map[string]string, kubeconfigPath string) (*corev1.Secret, error) {
   103  	Log(Info, fmt.Sprintf("CreateCredentialsSecret %s in %s", name, namespace))
   104  	// Get the kubernetes clientset
   105  	clientset, err := GetKubernetesClientsetForCluster(kubeconfigPath)
   106  	if err != nil {
   107  		Log(Error, fmt.Sprintf("Failed to get clientset with error: %v", err))
   108  		return nil, err
   109  	}
   110  
   111  	secret := &corev1.Secret{
   112  		ObjectMeta: metav1.ObjectMeta{
   113  			Name:      name,
   114  			Namespace: namespace,
   115  			Labels:    labels,
   116  		},
   117  		Type:       corev1.SecretTypeOpaque,
   118  		StringData: values,
   119  	}
   120  	scr, err := clientset.CoreV1().Secrets(namespace).Create(context.TODO(), secret, metav1.CreateOptions{})
   121  	if err != nil {
   122  		Log(Error, fmt.Sprintf("CreateSecretOfOpaque %v error: %v", name, err))
   123  	}
   124  	return scr, err
   125  }
   126  
   127  // CreatePasswordSecret creates opaque secret
   128  func CreatePasswordSecret(namespace string, name string, pw string, labels map[string]string) (*corev1.Secret, error) {
   129  	Log(Info, fmt.Sprintf("CreatePasswordSecret %s in %s", name, namespace))
   130  	// Get the kubernetes clientset
   131  	clientset, err := k8sutil.GetKubernetesClientset()
   132  	if err != nil {
   133  		Log(Error, fmt.Sprintf("Failed to get clientset with error: %v", err))
   134  		return nil, err
   135  	}
   136  
   137  	secret := &corev1.Secret{
   138  		ObjectMeta: metav1.ObjectMeta{
   139  			Name:      name,
   140  			Namespace: namespace,
   141  			Labels:    labels,
   142  		},
   143  		Type: corev1.SecretTypeOpaque,
   144  		StringData: map[string]string{
   145  			"password": pw,
   146  		},
   147  	}
   148  	scr, err := clientset.CoreV1().Secrets(namespace).Create(context.TODO(), secret, metav1.CreateOptions{})
   149  	if err != nil {
   150  		Log(Error, fmt.Sprintf("CreatePasswordSecret %v error: %v", name, err))
   151  	}
   152  	return scr, err
   153  }
   154  
   155  // CreateDockerSecret creates docker secret
   156  func CreateDockerSecret(namespace string, name string, server string, username string, password string) (*corev1.Secret, error) {
   157  	Log(Info, fmt.Sprintf("CreateDockerSecret %s in %s", name, namespace))
   158  	// Get the kubernetes clientset
   159  	clientset, err := k8sutil.GetKubernetesClientset()
   160  	if err != nil {
   161  		Log(Error, fmt.Sprintf("Failed to get clientset with error: %v", err))
   162  		return nil, err
   163  	}
   164  
   165  	auth := base64.StdEncoding.EncodeToString([]byte(fmt.Sprintf("%v:%v", username, password)))
   166  	secret := &corev1.Secret{
   167  		ObjectMeta: metav1.ObjectMeta{
   168  			Name:      name,
   169  			Namespace: namespace,
   170  		},
   171  		Type: corev1.SecretTypeDockerConfigJson,
   172  		StringData: map[string]string{
   173  			".dockerconfigjson": fmt.Sprintf(dockerconfigjsonTemplate, server, username, password, auth),
   174  		},
   175  	}
   176  	scr, err := clientset.CoreV1().Secrets(namespace).Create(context.TODO(), secret, metav1.CreateOptions{})
   177  	if err != nil {
   178  		if !errors.IsAlreadyExists(err) {
   179  			Log(Error, fmt.Sprintf("CreateDockerSecret %v error: %v", name, err))
   180  			return nil, err
   181  		}
   182  		Log(Info, fmt.Sprintf("Secret %s/%s already exists, updating", namespace, name))
   183  		return clientset.CoreV1().Secrets(namespace).Update(context.TODO(), secret, metav1.UpdateOptions{})
   184  	}
   185  	return scr, err
   186  }
   187  
   188  // CreateDockerSecretInCluster creates docker secret
   189  func CreateDockerSecretInCluster(namespace string, name string, server string, username string, password string, kubeconfigPath string) (*corev1.Secret, error) {
   190  	Log(Info, fmt.Sprintf("CreateDockerSecret %s in %s", name, namespace))
   191  	// Get the kubernetes clientset
   192  	clientset, err := GetKubernetesClientsetForCluster(kubeconfigPath)
   193  	if err != nil {
   194  		Log(Error, fmt.Sprintf("Failed to get clientset with error: %v", err))
   195  		return nil, err
   196  	}
   197  
   198  	auth := base64.StdEncoding.EncodeToString([]byte(fmt.Sprintf("%v:%v", username, password)))
   199  	secret := &corev1.Secret{
   200  		ObjectMeta: metav1.ObjectMeta{
   201  			Name:      name,
   202  			Namespace: namespace,
   203  		},
   204  		Type: corev1.SecretTypeDockerConfigJson,
   205  		StringData: map[string]string{
   206  			".dockerconfigjson": fmt.Sprintf(dockerconfigjsonTemplate, server, username, password, auth),
   207  		},
   208  	}
   209  	scr, err := clientset.CoreV1().Secrets(namespace).Create(context.TODO(), secret, metav1.CreateOptions{})
   210  	if err != nil {
   211  		if !errors.IsAlreadyExists(err) {
   212  			Log(Error, fmt.Sprintf("CreateDockerSecretInCluster %v error: %v", name, err))
   213  			return nil, err
   214  		}
   215  		Log(Info, fmt.Sprintf("CreateDockerSecretInCluster secret %s/%s already exists, updating", namespace, name))
   216  		return clientset.CoreV1().Secrets(namespace).Update(context.TODO(), secret, metav1.UpdateOptions{})
   217  	}
   218  	return scr, err
   219  }
   220  
   221  // DeleteSecret deletes the specified secret in the specified namespace
   222  func DeleteSecret(namespace string, name string) error {
   223  	// Get the kubernetes clientset
   224  	clientset, err := k8sutil.GetKubernetesClientset()
   225  	if err != nil {
   226  		return nil
   227  	}
   228  	return clientset.CoreV1().Secrets(namespace).Delete(context.TODO(), name, metav1.DeleteOptions{})
   229  }
   230  
   231  // SecretsCreated checks if all the secrets identified by names are created
   232  func SecretsCreated(namespace string, names ...string) bool {
   233  	secrets, err := ListSecrets(namespace)
   234  	if err != nil {
   235  		return false
   236  	}
   237  	missing := missingSecrets(secrets.Items, names...)
   238  	Log(Info, fmt.Sprintf("Secrets %v were NOT created in %v", missing, namespace))
   239  	return len(missing) == 0
   240  }
   241  
   242  func missingSecrets(secrets []corev1.Secret, namePrefixes ...string) []string {
   243  	var missing []string
   244  	for _, name := range namePrefixes {
   245  		if !secretExists(secrets, name) {
   246  			missing = append(missing, name)
   247  		}
   248  	}
   249  	return missing
   250  }
   251  
   252  func secretExists(secrets []corev1.Secret, namePrefix string) bool {
   253  	for i := range secrets {
   254  		if strings.HasPrefix(secrets[i].Name, namePrefix) {
   255  			return true
   256  		}
   257  	}
   258  	return false
   259  }
   260  
   261  // CreateSecret creates the given secret
   262  func CreateSecret(secret *corev1.Secret) error {
   263  	clientset, err := k8sutil.GetKubernetesClientset()
   264  	if err != nil {
   265  		return err
   266  	}
   267  	_, err = clientset.CoreV1().Secrets(secret.Namespace).Create(context.TODO(), secret, metav1.CreateOptions{})
   268  	return err
   269  }
   270  
   271  // UpdateSecret updates the given secret
   272  func UpdateSecret(secret *corev1.Secret) error {
   273  	clientset, err := k8sutil.GetKubernetesClientset()
   274  	if err != nil {
   275  		return err
   276  	}
   277  	_, err = clientset.CoreV1().Secrets(secret.Namespace).Update(context.TODO(), secret, metav1.UpdateOptions{})
   278  	return err
   279  }