github.com/argoproj/argo-cd/v3@v3.2.1/cmd/argocd/commands/admin/redis_initial_password.go (about) 1 package admin 2 3 import ( 4 "context" 5 "crypto/rand" 6 "fmt" 7 "math/big" 8 9 "github.com/spf13/cobra" 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/client-go/kubernetes" 14 "k8s.io/client-go/tools/clientcmd" 15 16 "github.com/argoproj/argo-cd/v3/common" 17 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1" 18 "github.com/argoproj/argo-cd/v3/util/cli" 19 "github.com/argoproj/argo-cd/v3/util/errors" 20 ) 21 22 func generateRandomPassword() (string, error) { 23 const initialPasswordLength = 16 24 const letters = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-" 25 randBytes := make([]byte, initialPasswordLength) 26 for i := 0; i < initialPasswordLength; i++ { 27 num, err := rand.Int(rand.Reader, big.NewInt(int64(len(letters)))) 28 if err != nil { 29 return "", err 30 } 31 randBytes[i] = letters[num.Int64()] 32 } 33 initialPassword := string(randBytes) 34 return initialPassword, nil 35 } 36 37 // NewRedisInitialPasswordCommand defines a new command to ensure Argo CD Redis password secret exists. 38 func NewRedisInitialPasswordCommand() *cobra.Command { 39 var clientConfig clientcmd.ClientConfig 40 command := cobra.Command{ 41 Use: "redis-initial-password", 42 Short: "Ensure the Redis password exists, creating a new one if necessary.", 43 Run: func(_ *cobra.Command, _ []string) { 44 namespace, _, err := clientConfig.Namespace() 45 errors.CheckError(err) 46 47 // redisInitialCredentials is the kubernetes secret containing 48 // the redis password 49 redisInitialCredentials := common.RedisInitialCredentials 50 51 // redisInitialCredentialsKey is the key in the redisInitialCredentials 52 // secret which maps to the redis password 53 redisInitialCredentialsKey := common.RedisInitialCredentialsKey 54 fmt.Printf("Checking for initial Redis password in secret %s/%s at key %s. \n", namespace, redisInitialCredentials, redisInitialCredentialsKey) 55 56 config, err := clientConfig.ClientConfig() 57 errors.CheckError(err) 58 errors.CheckError(v1alpha1.SetK8SConfigDefaults(config)) 59 60 kubeClientset := kubernetes.NewForConfigOrDie(config) 61 62 randomPassword, err := generateRandomPassword() 63 errors.CheckError(err) 64 65 data := map[string][]byte{ 66 redisInitialCredentialsKey: []byte(randomPassword), 67 } 68 secret := &corev1.Secret{ 69 ObjectMeta: metav1.ObjectMeta{ 70 Name: redisInitialCredentials, 71 Namespace: namespace, 72 }, 73 Data: data, 74 Type: corev1.SecretTypeOpaque, 75 } 76 _, err = kubeClientset.CoreV1().Secrets(namespace).Create(context.Background(), secret, metav1.CreateOptions{}) 77 if err != nil && !apierrors.IsAlreadyExists(err) { 78 errors.CheckError(err) 79 } 80 81 fmt.Printf("Argo CD Redis secret state confirmed: secret name %s.\n", redisInitialCredentials) 82 secret, err = kubeClientset.CoreV1().Secrets(namespace).Get(context.Background(), redisInitialCredentials, metav1.GetOptions{}) 83 errors.CheckError(err) 84 85 if _, ok := secret.Data[redisInitialCredentialsKey]; ok { 86 fmt.Println("Password secret is configured properly.") 87 } else { 88 errors.Fatal(errors.ErrorGeneric, fmt.Sprintf("key %s doesn't exist in secret %s. \n", redisInitialCredentialsKey, redisInitialCredentials)) 89 } 90 }, 91 } 92 93 clientConfig = cli.AddKubectlFlagsToCmd(&command) 94 95 return &command 96 }