/* * Copyright 2024 Oleg Borodin */ package main import ( "context" "errors" "flag" "fmt" "os" "os/user" "path/filepath" "time" "certmanager/pkg/client" "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 = "deleteAccount" listAccountsCmd = "listAccounts" setGrantCmd = "setGrant" deleteGrantCmd = "deleteGrant" ) 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 *cmctl.ControlClient caFilenamesList string certFilename string keyFilename string issuerOrganizationName string issuerOrganizationalUnitName string issuerCommonName string issuerID int64 issuerName string signerID int64 signerName string serviceOrganizationName string serviceOrganizationalUnitName string serviceCommonName string hostnameList string ipAdressesList string serviceID int64 serviceName string accountID int64 username string password string disable bool newUsername string newPassword string operation 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(" %s, %s, %s, %s,\n", createServicePairCmd, revokeServicePairCmd, listServicePairsCmd, getServicePairCmd) fmt.Printf(" %s, %s, %s, %s,\n", createAccountCmd, deleteAccountCmd, listAccountsCmd, updateAccountCmd) fmt.Printf(" %s, %s\n", setGrantCmd, deleteGrantCmd) 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.issuerOrganizationName, "org", util.issuerOrganizationName, "new issuer organization name") flagSet.StringVar(&util.issuerOrganizationalUnitName, "unit", util.issuerOrganizationalUnitName, "new issuer organizational unit name") 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.serviceOrganizationName, "org", util.serviceOrganizationName, "new service organization name") flagSet.StringVar(&util.serviceOrganizationalUnitName, "unit", util.serviceOrganizationalUnitName, "new service organizational unit name") flagSet.StringVar(&util.serviceCommonName, "cn", util.serviceCommonName, "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, "newUsername", util.newUsername, "new user name") flagSet.StringVar(&util.newPassword, "newPassword", 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 case setGrantCmd: flagSet := flag.NewFlagSet(setGrantCmd, flag.ExitOnError) flagSet.StringVar(&util.username, "username", util.username, "user name") flagSet.Int64Var(&util.accountID, "accountId", util.accountID, "account ID") flagSet.StringVar(&util.operation, "operation", util.operation, "grant type") 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 deleteGrantCmd: flagSet := flag.NewFlagSet(deleteGrantCmd, flag.ExitOnError) flagSet.StringVar(&util.username, "username", util.username, "user name") flagSet.Int64Var(&util.accountID, "accountId", util.accountID, "account ID") flagSet.StringVar(&util.operation, "operation", util.operation, "grant type") 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) case setGrantCmd: res, err = util.SetGrant(ctx) case deleteGrantCmd: res, err = util.DeleteGrant(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) (*cmctl.GetStatusResult, error) { var err error res := &cmctl.GetStatusResult{} cont, err := client.NewClient(&util.access) if err != nil { return res, err } params := &cmctl.GetStatusParams{} res, err = cont.GetStatus(ctx, params) if err != nil { return res, err } return res, err }