/* * Copyright 2022 Oleg Borodin */ package main import ( "context" "errors" "flag" "fmt" "os" "os/user" "path/filepath" "time" "certmanager/pkg/client" cmapi "certmanager/pkg/cmctl" "sigs.k8s.io/yaml" ) const ( defaultHostname = "localhost" rcFilename = ".certmanager.yaml" defaultPort int = client.DefaultGrpcPort getStatusCmd = "getStatus" helpCmd = "help" createIssuerPairCmd = "createIssuerPair" importIssuerPairCmd = "importIssuerPair" revokeIssuerPairCmd = "revokeIssuerPair" unrevokeIssuerPairCmd = "unrevokeIssuerPair" listIssuerPairsCmd = "listIssuerPairs" getIssuerCertificateCmd = "getIssuerCertificate" createServicePairCmd = "createServicePair" revokeServicePairCmd = "revokeServicePair" unrevokeServicePairCmd = "unrevokeServicePair" listServicePairsCmd = "listServicePairs" getServicePairCmd = "getServicePair" createAccountCmd = "createAccount" updateAccountCmd = "updateAccount" deleteAccountCmd = "revokeAccount" listAccountsCmd = "listAccounts" ) func main() { var err error util := NewUtil() err = util.Exec() if err != nil { os.Exit(1) } os.Exit(0) } type Util struct { subCmd string cmdTimeout int64 access client.Access cont *cmapi.ControlClient caFilenamesList string certFilename string hostnameList string ipAdressesList string issuerCommonName string issuerID int64 issuerName string keyFilename string signerID int64 signerName string serviceCommonName string serviceID int64 serviceName string accountID int64 username string password string disable bool newUsername string newPassword string } func NewUtil() *Util { var util Util util.cmdTimeout = 120 util.access = client.Access{ Hostname: defaultHostname, Port: defaultPort, Username: "certmanager", Password: "certmanager", } return &util } func (util *Util) GetOpt() error { var err error homeDir := os.Getenv("HOME") if homeDir == "" { currUsr, err := user.Current() if err == nil { homeDir = currUsr.HomeDir } } if homeDir != "" { confPath := filepath.Join(homeDir, rcFilename) confData, err := os.ReadFile(confPath) if err == nil && len(confData) > 0 { yaml.Unmarshal(confData, &util.access) } } exeName := filepath.Base(os.Args[0]) flag.Int64Var(&util.cmdTimeout, "timeout", util.cmdTimeout, "command execution timeout") flag.StringVar(&util.access.Hostname, "host", util.access.Hostname, "service hostname") flag.IntVar(&util.access.Port, "port", util.access.Port, "service port") flag.StringVar(&util.access.Username, "user", util.access.Username, "access login") flag.StringVar(&util.access.Password, "pass", util.access.Password, "access password") help := func() { fmt.Println("") fmt.Printf("Usage: %s [option] command [command option]\n", exeName) fmt.Printf("\n") fmt.Printf("Command list: help, %s\n", getStatusCmd) fmt.Printf("Command list: %s, %s, %s, %s, %s, %s\n", createIssuerPairCmd, importIssuerPairCmd, revokeIssuerPairCmd, unrevokeIssuerPairCmd, listIssuerPairsCmd, getIssuerCertificateCmd) fmt.Printf("Command list: %s, %s, %s, %s\n", createServicePairCmd, revokeServicePairCmd, listServicePairsCmd, getServicePairCmd) fmt.Printf("Command list: %s, %s, %s, %s\n", createAccountCmd, deleteAccountCmd, listAccountsCmd, updateAccountCmd) fmt.Printf("\n") fmt.Printf("Global options:\n") flag.PrintDefaults() fmt.Printf("\n") } flag.Usage = help flag.Parse() args := flag.Args() var subCmd string var subArgs []string if len(args) > 0 { subCmd = args[0] subArgs = args[1:] } switch subCmd { case helpCmd: help() return errors.New("Unknown command") case getStatusCmd: flagSet := flag.NewFlagSet(getStatusCmd, flag.ExitOnError) flagSet.Usage = func() { fmt.Printf("\n") fmt.Printf("Usage: %s [global options] %s [command options]\n", exeName, subCmd) fmt.Printf("\n") fmt.Printf("The command options: none\n") flagSet.PrintDefaults() fmt.Printf("\n") } flagSet.Parse(subArgs) util.subCmd = subCmd case createIssuerPairCmd: flagSet := flag.NewFlagSet(createIssuerPairCmd, flag.ExitOnError) flagSet.StringVar(&util.issuerCommonName, "cn", util.issuerCommonName, "new issuer canonic name") flagSet.Int64Var(&util.signerID, "signerID", util.signerID, "optional issuer ID for sign") flagSet.StringVar(&util.signerName, "signerName", util.signerName, "optional issuer name for sign") flagSet.Usage = func() { fmt.Printf("\n") fmt.Printf("Usage: %s [global options] %s [command options]\n", exeName, subCmd) fmt.Printf("\n") fmt.Printf("The command options: none\n") flagSet.PrintDefaults() fmt.Printf("\n") } flagSet.Parse(subArgs) util.subCmd = subCmd case getIssuerCertificateCmd: flagSet := flag.NewFlagSet(getIssuerCertificateCmd, flag.ExitOnError) flagSet.StringVar(&util.issuerName, "issuerName", util.issuerName, "issuer name") flagSet.Int64Var(&util.issuerID, "issuerID", util.issuerID, "issuer ID") flagSet.Usage = func() { fmt.Printf("\n") fmt.Printf("Usage: %s [global options] %s [command options]\n", exeName, subCmd) fmt.Printf("\n") fmt.Printf("The command options: none\n") flagSet.PrintDefaults() fmt.Printf("\n") } flagSet.Parse(subArgs) util.subCmd = subCmd case listIssuerPairsCmd: flagSet := flag.NewFlagSet(listIssuerPairsCmd, flag.ExitOnError) flagSet.Usage = func() { fmt.Printf("\n") fmt.Printf("Usage: %s [global options] %s [command options]\n", exeName, subCmd) fmt.Printf("\n") fmt.Printf("The command options: none\n") flagSet.PrintDefaults() fmt.Printf("\n") } flagSet.Parse(subArgs) util.subCmd = subCmd case importIssuerPairCmd: flagSet := flag.NewFlagSet(importIssuerPairCmd, flag.ExitOnError) flagSet.Usage = func() { fmt.Printf("\n") fmt.Printf("Usage: %s [global options] %s [command options]\n", exeName, subCmd) fmt.Printf("\n") fmt.Printf("The command options: none\n") flagSet.PrintDefaults() fmt.Printf("\n") } flagSet.Parse(subArgs) util.subCmd = subCmd case revokeIssuerPairCmd: flagSet := flag.NewFlagSet(revokeIssuerPairCmd, flag.ExitOnError) flagSet.StringVar(&util.issuerName, "issuerName", util.issuerName, "issuer name") flagSet.Int64Var(&util.issuerID, "issuerID", util.issuerID, "issuer ID") flagSet.Usage = func() { fmt.Printf("\n") fmt.Printf("Usage: %s [global options] %s [command options]\n", exeName, subCmd) fmt.Printf("\n") fmt.Printf("The command options: none\n") flagSet.PrintDefaults() fmt.Printf("\n") } flagSet.Parse(subArgs) util.subCmd = subCmd case unrevokeIssuerPairCmd: flagSet := flag.NewFlagSet(unrevokeIssuerPairCmd, flag.ExitOnError) flagSet.StringVar(&util.issuerName, "issuerName", util.issuerName, "issuer name") flagSet.Int64Var(&util.issuerID, "issuerID", util.issuerID, "issuer ID") flagSet.Usage = func() { fmt.Printf("\n") fmt.Printf("Usage: %s [global options] %s [command options]\n", exeName, subCmd) fmt.Printf("\n") fmt.Printf("The command options: none\n") flagSet.PrintDefaults() fmt.Printf("\n") } flagSet.Parse(subArgs) util.subCmd = subCmd case createServicePairCmd: flagSet := flag.NewFlagSet(createServicePairCmd, flag.ExitOnError) flagSet.StringVar(&util.issuerCommonName, "cn", util.issuerCommonName, "new service canonic name") flagSet.StringVar(&util.issuerName, "issuerName", util.issuerName, "issuer name") flagSet.Int64Var(&util.issuerID, "issuerID", util.issuerID, "issuer ID") flagSet.StringVar(&util.ipAdressesList, "addresses", util.ipAdressesList, "comma separated IP address list") flagSet.StringVar(&util.hostnameList, "hostnames", util.hostnameList, "comma separated hostname list") flagSet.Usage = func() { fmt.Printf("\n") fmt.Printf("Usage: %s [global options] %s [command options]\n", exeName, subCmd) fmt.Printf("\n") fmt.Printf("The command options: none\n") flagSet.PrintDefaults() fmt.Printf("\n") } flagSet.Parse(subArgs) util.subCmd = subCmd case revokeServicePairCmd: flagSet := flag.NewFlagSet(revokeServicePairCmd, flag.ExitOnError) flagSet.StringVar(&util.serviceName, "serviceName", util.serviceName, "service name") flagSet.Int64Var(&util.serviceID, "serviceID", util.serviceID, "service ID") flagSet.Usage = func() { fmt.Printf("\n") fmt.Printf("Usage: %s [global options] %s [command options]\n", exeName, subCmd) fmt.Printf("\n") fmt.Printf("The command options: none\n") flagSet.PrintDefaults() fmt.Printf("\n") } flagSet.Parse(subArgs) util.subCmd = subCmd case unrevokeServicePairCmd: flagSet := flag.NewFlagSet(unrevokeServicePairCmd, flag.ExitOnError) flagSet.StringVar(&util.serviceName, "serviceName", util.serviceName, "service name") flagSet.Int64Var(&util.serviceID, "serviceID", util.serviceID, "service ID") flagSet.Usage = func() { fmt.Printf("\n") fmt.Printf("Usage: %s [global options] %s [command options]\n", exeName, subCmd) fmt.Printf("\n") fmt.Printf("The command options: none\n") flagSet.PrintDefaults() fmt.Printf("\n") } flagSet.Parse(subArgs) util.subCmd = subCmd case listServicePairsCmd: flagSet := flag.NewFlagSet(listServicePairsCmd, flag.ExitOnError) flagSet.Usage = func() { fmt.Printf("\n") fmt.Printf("Usage: %s [global options] %s [command options]\n", exeName, subCmd) fmt.Printf("\n") fmt.Printf("The command options: none\n") flagSet.PrintDefaults() fmt.Printf("\n") } flagSet.Parse(subArgs) util.subCmd = subCmd case getServicePairCmd: flagSet := flag.NewFlagSet(getServicePairCmd, flag.ExitOnError) flagSet.StringVar(&util.serviceName, "serviceName", util.serviceName, "service name") flagSet.Int64Var(&util.serviceID, "serviceID", util.serviceID, "service ID") flagSet.Usage = func() { fmt.Printf("\n") fmt.Printf("Usage: %s [global options] %s [command options]\n", exeName, subCmd) fmt.Printf("\n") fmt.Printf("The command options: none\n") flagSet.PrintDefaults() fmt.Printf("\n") } flagSet.Parse(subArgs) util.subCmd = subCmd case createAccountCmd: flagSet := flag.NewFlagSet(createAccountCmd, flag.ExitOnError) flagSet.StringVar(&util.username, "username", util.username, "user name") flagSet.StringVar(&util.password, "password", util.password, "user password") flagSet.Usage = func() { fmt.Printf("\n") fmt.Printf("Usage: %s [global options] %s [command options]\n", exeName, subCmd) fmt.Printf("\n") fmt.Printf("The command options: none\n") flagSet.PrintDefaults() fmt.Printf("\n") } flagSet.Parse(subArgs) util.subCmd = subCmd case deleteAccountCmd: flagSet := flag.NewFlagSet(deleteAccountCmd, flag.ExitOnError) flagSet.StringVar(&util.username, "username", util.username, "user name") flagSet.Int64Var(&util.accountID, "accountId", util.accountID, "account ID") flagSet.Usage = func() { fmt.Printf("\n") fmt.Printf("Usage: %s [global options] %s [command options]\n", exeName, subCmd) fmt.Printf("\n") fmt.Printf("The command options: none\n") flagSet.PrintDefaults() fmt.Printf("\n") } flagSet.Parse(subArgs) util.subCmd = subCmd case listAccountsCmd: flagSet := flag.NewFlagSet(listAccountsCmd, flag.ExitOnError) flagSet.Usage = func() { fmt.Printf("\n") fmt.Printf("Usage: %s [global options] %s [command options]\n", exeName, subCmd) fmt.Printf("\n") fmt.Printf("The command options: none\n") flagSet.PrintDefaults() fmt.Printf("\n") } flagSet.Parse(subArgs) util.subCmd = subCmd case updateAccountCmd: flagSet := flag.NewFlagSet(updateAccountCmd, flag.ExitOnError) flagSet.StringVar(&util.username, "username", util.username, "user name") flagSet.Int64Var(&util.accountID, "accountId", util.accountID, "account ID") flagSet.StringVar(&util.newUsername, "username", util.newUsername, "new user name") flagSet.StringVar(&util.newPassword, "password", util.newPassword, "new user password") flagSet.BoolVar(&util.disable, "disable", util.disable, "disable account") flagSet.Usage = func() { fmt.Printf("\n") fmt.Printf("Usage: %s [global options] %s [command options]\n", exeName, subCmd) fmt.Printf("\n") fmt.Printf("The command options: none\n") flagSet.PrintDefaults() fmt.Printf("\n") } flagSet.Parse(subArgs) util.subCmd = subCmd default: help() return errors.New("Unknown command") } return err } type Response struct { Error bool `json:"error" yaml:"error"` Message string `json:"message,omitempty" yaml:"message,omitempty"` Result any `json:"result,omitempty" yaml:"result,omitempty"` } func (util *Util) Exec() error { var err error err = util.GetOpt() if err != nil { return err } var timeout = time.Duration(util.cmdTimeout) * time.Second ctx, close := context.WithTimeout(context.Background(), timeout) defer close() var res any switch util.subCmd { case getStatusCmd: res, err = util.GetStatus(ctx) case createIssuerPairCmd: res, err = util.CreateIssuerPair(ctx) case importIssuerPairCmd: res, err = util.ImportIssuerPair(ctx) case revokeIssuerPairCmd: res, err = util.RevokeIssuerPair(ctx) case unrevokeIssuerPairCmd: res, err = util.UnrevokeIssuerPair(ctx) case listIssuerPairsCmd: res, err = util.ListIssuerPairs(ctx) case getIssuerCertificateCmd: res, err = util.GetIssuerCertificate(ctx) case createServicePairCmd: res, err = util.CreateServicePair(ctx) case revokeServicePairCmd: res, err = util.RevokeServicePair(ctx) case unrevokeServicePairCmd: res, err = util.UnrevokeServicePair(ctx) case listServicePairsCmd: res, err = util.ListServicePairs(ctx) case getServicePairCmd: res, err = util.GetServicePair(ctx) case createAccountCmd: res, err = util.CreateAccount(ctx) case updateAccountCmd: res, err = util.UpdateAccount(ctx) case listAccountsCmd: res, err = util.ListAccounts(ctx) case deleteAccountCmd: res, err = util.DeleteAccount(ctx) default: err = errors.New("Unknown cli command") } var resp Response if err != nil { resp.Error = true resp.Message = fmt.Sprintf("%v", err) } else { resp.Result = res } respBytes, _ := yaml.Marshal(resp) fmt.Println(string(respBytes)) return err } func (util *Util) GetStatus(ctx context.Context) (*cmapi.GetStatusResult, error) { var err error res := &cmapi.GetStatusResult{} cont, err := client.NewClient(&util.access) if err != nil { return res, err } params := &cmapi.GetStatusParams{} res, err = cont.GetStatus(ctx, params) if err != nil { return res, err } return res, err }