/* * Copyright 2022 Oleg Borodin */ package main import ( "context" "errors" "flag" "fmt" "os" "os/user" "path/filepath" "time" cmapi "certmanager/pkg/cmctl" "certmanager/pkg/client" "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" ) 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 } 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, %s, %s, %s, %s\n", createIssuerPairCmd, importIssuerPairCmd, revokeIssuerPairCmd, unrevokeIssuerPairCmd, listIssuerPairsCmd, getIssuerCertificateCmd, createServicePairCmd, revokeServicePairCmd, listServicePairsCmd, getServicePairCmd) 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 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) 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 }