187 lines
5.4 KiB
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.",
|
|
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)
|
|
}
|
|
}
|