152 lines
3.9 KiB
Go
152 lines
3.9 KiB
Go
package cmd
|
|
|
|
import (
|
|
"bufio"
|
|
"fmt"
|
|
"os"
|
|
"strings"
|
|
|
|
"kmanage/pkg/git"
|
|
"kmanage/pkg/komodo"
|
|
"kmanage/pkg/secret"
|
|
|
|
"github.com/spf13/viper"
|
|
)
|
|
|
|
// getKomodoClient initializes the Komodo client, resolving credentials from the keyring, environment, or config file.
|
|
func getKomodoClient() (*komodo.Client, error) {
|
|
cfg, err := LoadAppConfig()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
url := cfg.KomodoURL
|
|
if url == "" {
|
|
url = viper.GetString("komodo_url")
|
|
}
|
|
if url == "" {
|
|
return nil, fmt.Errorf("Komodo URL not configured. Run 'kmanage kmd configure'")
|
|
}
|
|
|
|
key, _ := secret.GetSecret("komodo:key")
|
|
if key == "" {
|
|
key = cfg.KomodoKey
|
|
}
|
|
if key == "" {
|
|
key = viper.GetString("komodo_key")
|
|
}
|
|
|
|
sec, _ := secret.GetSecret("komodo:secret")
|
|
if sec == "" {
|
|
sec = cfg.KomodoSecret
|
|
}
|
|
if sec == "" {
|
|
sec = viper.GetString("komodo_secret")
|
|
}
|
|
|
|
if key == "" || sec == "" {
|
|
return nil, fmt.Errorf("incomplete Komodo credentials. Run 'kmanage kmd configure'")
|
|
}
|
|
|
|
return komodo.NewClient(url, key, sec), nil
|
|
}
|
|
|
|
// getGitClientForAccount initializes a Git client for a specific account name or the configured default account.
|
|
func getGitClientForAccount(accountName string) (*git.Client, error) {
|
|
cfg, err := LoadAppConfig()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if len(cfg.GitAccounts) == 0 {
|
|
return nil, fmt.Errorf("no Git account configured. Run 'kmanage git configure --url <url> --token <token>'")
|
|
}
|
|
|
|
target := accountName
|
|
if target == "" {
|
|
target = cfg.DefaultGitAccount
|
|
}
|
|
if target == "" {
|
|
for k := range cfg.GitAccounts {
|
|
target = k
|
|
break
|
|
}
|
|
}
|
|
|
|
acc, exists := cfg.GitAccounts[target]
|
|
if !exists {
|
|
return nil, fmt.Errorf("Git account '%s' not found. View configured accounts with 'kmanage git accounts'", target)
|
|
}
|
|
|
|
token, _ := secret.GetSecret("git:" + target + ":token")
|
|
if token == "" {
|
|
token = acc.Token
|
|
}
|
|
|
|
if token == "" {
|
|
return nil, fmt.Errorf("token for Git account '%s' not found. Reconfigure using 'kmanage git configure --name %s --token <token>'", target, target)
|
|
}
|
|
|
|
return git.NewClient(target, acc.URL, token, git.ProviderType(acc.Type)), nil
|
|
}
|
|
|
|
// getSelectedGitClients returns relevant clients based on --account or --all-accounts flags.
|
|
func getSelectedGitClients(accountFlag string, allAccountsFlag bool) ([]*git.Client, error) {
|
|
cfg, err := LoadAppConfig()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if len(cfg.GitAccounts) == 0 {
|
|
return nil, fmt.Errorf("no Git account configured. Run 'kmanage git configure --url <url> --token <token>'")
|
|
}
|
|
|
|
if allAccountsFlag {
|
|
var clients []*git.Client
|
|
for name := range cfg.GitAccounts {
|
|
c, err := getGitClientForAccount(name)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
clients = append(clients, c)
|
|
}
|
|
return clients, nil
|
|
}
|
|
|
|
client, err := getGitClientForAccount(accountFlag)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return []*git.Client{client}, nil
|
|
}
|
|
|
|
// parseRepoArg splits repository arguments (e.g. 'Docker/authentik' or 'https://git.hnrx.net/Docker/authentik.git') into owner and repo name.
|
|
func parseRepoArg(repoArg string) (string, string, error) {
|
|
repoArg = strings.TrimSpace(repoArg)
|
|
repoArg = strings.TrimPrefix(repoArg, "https://")
|
|
repoArg = strings.TrimPrefix(repoArg, "http://")
|
|
if strings.Contains(repoArg, "/") {
|
|
parts := strings.Split(repoArg, "/")
|
|
if len(parts) >= 2 {
|
|
owner := parts[len(parts)-2]
|
|
repo := strings.TrimSuffix(parts[len(parts)-1], ".git")
|
|
if owner != "" && repo != "" {
|
|
return owner, repo, nil
|
|
}
|
|
}
|
|
}
|
|
return "", "", fmt.Errorf("invalid repository format '%s'. Please specify 'owner/repo' (e.g. 'Docker/authentik')", repoArg)
|
|
}
|
|
|
|
// confirmAction prompts the user for yes/no confirmation on stdin.
|
|
func confirmAction(prompt string) bool {
|
|
fmt.Printf("%s [y/N]: ", prompt)
|
|
reader := bufio.NewReader(os.Stdin)
|
|
response, err := reader.ReadString('\n')
|
|
if err != nil {
|
|
return false
|
|
}
|
|
response = strings.ToLower(strings.TrimSpace(response))
|
|
return response == "y" || response == "yes" || response == "j" || response == "ja"
|
|
}
|