maidn-cli/cmd/vault.go

187 lines
5.4 KiB
Go

package cmd
import (
"fmt"
"os"
"strings"
"time"
"github.com/Pingu-Studio/MaidnCLI/internal/k8s"
"github.com/Pingu-Studio/MaidnCLI/internal/ui"
"github.com/Pingu-Studio/MaidnCLI/internal/utils"
"github.com/Pingu-Studio/MaidnCLI/internal/vault"
"github.com/spf13/cobra"
)
var vaultCmd = &cobra.Command{
Use: "vault",
Short: "Manage Vault secrets for CI/CD.",
}
func init() {
rootCmd.AddCommand(vaultCmd)
vaultCmd.AddCommand(createDockerSecretCmd)
vaultCmd.AddCommand(createGhcrSecretCmd)
vaultCmd.AddCommand(createGithubSecretCmd)
}
var createDockerSecretCmd = &cobra.Command{
Use: "create-docker-secret",
Short: "Creates a secret in Vault for Docker Hub and applies it to Kubernetes.",
Run: runCreateDockerSecret,
}
var createGhcrSecretCmd = &cobra.Command{
Use: "create-ghcr-secret",
Short: "Creates secrets in Vault for GHCR and applies it to Kubernetes.",
Run: runCreateGhcrSecret,
}
var createGithubSecretCmd = &cobra.Command{
Use: "create-github-secret",
Short: "Creates a GitHub authentication secret in Vault.",
Run: runCreateGithubSecret,
}
func runCreateDockerSecret(cmd *cobra.Command, args []string) {
if err := k8s.CheckExternalSecretCRD(); err != nil {
fmt.Printf("[ERROR] Prerequisite check failed: %v\n", err)
os.Exit(1)
}
vm, err := vault.NewVaultManager()
if err != nil {
fmt.Printf("[ERROR] Failed to initialize Vault manager: %v\n", err)
os.Exit(1)
}
username, password, err := ui.GetUserInputForDockerHub()
if err != nil {
fmt.Printf("[ERROR] %v\n", err)
os.Exit(1)
}
dockerConfigJSON, err := vault.CreateDockerConfig(vault.DockerHubRegistry, username, password)
if err != nil {
fmt.Printf("[ERROR] Failed to create Docker config: %v\n", err)
os.Exit(1)
}
secretData := map[string]string{vault.DockerConfigJSONKey: dockerConfigJSON}
if err := vm.StoreSecret(vault.DockerHubSecretPath, secretData); err != nil {
fmt.Printf("[ERROR] Failed to store Docker Hub secret in Vault: %v\n", err)
os.Exit(1)
}
// First attempt to create the secret
err = k8s.CreateDockerHubExternalSecret()
if err == nil {
// Success on the first try
return
}
// If it failed, check for the specific cache error
if strings.Contains(err.Error(), "no matches for kind") {
// Handle the cache error interactively
cacheCleared := utils.HandleKubectlCacheError(err)
// If the user agreed and the cache was cleared, retry the operation
if cacheCleared {
fmt.Println("\n[INFO] Retrying to apply the ExternalSecret after clearing cache...")
time.Sleep(1 * time.Second) // Give the system a moment to breathe
err = k8s.CreateDockerHubExternalSecret()
if err == nil {
fmt.Println("[SUCCESS] ExternalSecret applied successfully on the second attempt.")
return
}
}
}
// If we reach here, either the error was not the cache issue, or the retry failed.
fmt.Printf("\n[ERROR] Operation failed. The secret is saved in Vault, but the ExternalSecret could not be applied to Kubernetes.\n")
fmt.Printf("Final error: %v\n", err)
os.Exit(1)
}
func runCreateGhcrSecret(cmd *cobra.Command, args []string) {
if err := k8s.CheckExternalSecretCRD(); err != nil {
fmt.Printf("[ERROR] Prerequisite check failed: %v\n", err)
os.Exit(1)
}
vm, err := vault.NewVaultManager()
if err != nil {
fmt.Printf("[ERROR] Failed to initialize Vault manager: %v\n", err)
os.Exit(1)
}
username, registryToken, orgToken, err := ui.GetUserInputForGhcr()
if err != nil {
fmt.Printf("[ERROR] %v\n", err)
os.Exit(1)
}
dockerConfigJSON, err := vault.CreateDockerConfig(vault.GhcrRegistry, username, registryToken)
if err != nil {
fmt.Printf("[ERROR] Failed to create Docker config for GHCR: %v\n", err)
os.Exit(1)
}
dockerSecretData := map[string]string{vault.DockerConfigJSONKey: dockerConfigJSON}
if err := vm.StoreSecret(vault.GhcrSecretPath, dockerSecretData); err != nil {
fmt.Printf("[ERROR] Failed to store GHCR secret in Vault: %v\n", err)
os.Exit(1)
}
orgSecretData := map[string]string{vault.OrgManagementPATKey: orgToken}
if err := vm.StoreSecret(vault.OrgManagementSecretPath, orgSecretData); err != nil {
fmt.Printf("[ERROR] Failed to store organization management PAT in Vault: %v\n", err)
os.Exit(1)
}
err = k8s.CreateGhcrExternalSecret()
if err == nil {
return
}
if strings.Contains(err.Error(), "no matches for kind") {
cacheCleared := utils.HandleKubectlCacheError(err)
if cacheCleared {
fmt.Println("\n[INFO] Retrying to apply the ExternalSecret after clearing cache...")
time.Sleep(1 * time.Second)
err = k8s.CreateGhcrExternalSecret()
if err == nil {
fmt.Println("[SUCCESS] ExternalSecret applied successfully on the second attempt.")
return
}
}
}
fmt.Printf("\n[ERROR] Operation failed. The secrets are saved in Vault, but the ExternalSecret for GHCR could not be applied to Kubernetes.\n")
fmt.Printf("Final error: %v\n", err)
os.Exit(1)
}
func runCreateGithubSecret(cmd *cobra.Command, args []string) {
vm, err := vault.NewVaultManager()
if err != nil {
fmt.Printf("[ERROR] Failed to initialize Vault manager: %v\n", err)
os.Exit(1)
}
username, token, err := ui.GetUserInputForGithubAuth()
if err != nil {
fmt.Printf("[ERROR] %v\n", err)
os.Exit(1)
}
secretData := map[string]string{"username": username, "password": token}
if err := vm.StoreSecret(vault.GithubAuthSecretPath, secretData); err != nil {
fmt.Printf("[ERROR] Failed to store GitHub auth secret in Vault: %v\n", err)
os.Exit(1)
}
}