From 7d9176bd0d2579a95bf9f3e79760c2bd2f389f56 Mon Sep 17 00:00:00 2001 From: Ludovic Fernandez Date: Sun, 13 Feb 2022 12:28:51 +0100 Subject: [PATCH] chore: migrate to github.com/urfave/cli/v2 (#1590) --- cmd/accounts_storage.go | 8 +-- cmd/certs_storage.go | 14 ++--- cmd/cmd.go | 6 +- cmd/cmd_before.go | 8 +-- cmd/cmd_dnshelp.go | 13 ++-- cmd/cmd_list.go | 22 +++---- cmd/cmd_renew.go | 30 +++++----- cmd/cmd_revoke.go | 17 +++--- cmd/cmd_run.go | 32 +++++----- cmd/flags.go | 100 ++++++++++++++++--------------- cmd/lego/main.go | 2 +- cmd/setup.go | 16 ++--- cmd/setup_challenges.go | 46 +++++++------- docs/content/usage/cli/_index.md | 20 +++---- go.mod | 2 +- go.sum | 3 +- internal/release.go | 13 ++-- 17 files changed, 181 insertions(+), 171 deletions(-) diff --git a/cmd/accounts_storage.go b/cmd/accounts_storage.go index abe08445..8be48e25 100644 --- a/cmd/accounts_storage.go +++ b/cmd/accounts_storage.go @@ -16,7 +16,7 @@ import ( "github.com/go-acme/lego/v4/lego" "github.com/go-acme/lego/v4/log" "github.com/go-acme/lego/v4/registration" - "github.com/urfave/cli" + "github.com/urfave/cli/v2" ) const ( @@ -73,12 +73,12 @@ func NewAccountsStorage(ctx *cli.Context) *AccountsStorage { // TODO: move to account struct? Currently MUST pass email. email := getEmail(ctx) - serverURL, err := url.Parse(ctx.GlobalString("server")) + serverURL, err := url.Parse(ctx.String("server")) if err != nil { log.Fatal(err) } - rootPath := filepath.Join(ctx.GlobalString("path"), baseAccountsRootFolderName) + rootPath := filepath.Join(ctx.String("path"), baseAccountsRootFolderName) serverPath := strings.NewReplacer(":", "_", "/", string(os.PathSeparator)).Replace(serverURL.Host) accountsPath := filepath.Join(rootPath, serverPath) rootUserPath := filepath.Join(accountsPath, email) @@ -226,7 +226,7 @@ func loadPrivateKey(file string) (crypto.PrivateKey, error) { func tryRecoverRegistration(ctx *cli.Context, privateKey crypto.PrivateKey) (*registration.Resource, error) { // couldn't load account but got a key. Try to look the account up. config := lego.NewConfig(&Account{key: privateKey}) - config.CADirURL = ctx.GlobalString("server") + config.CADirURL = ctx.String("server") config.UserAgent = fmt.Sprintf("lego-cli/%s", ctx.App.Version) client, err := lego.NewClient(config) diff --git a/cmd/certs_storage.go b/cmd/certs_storage.go index bb62cb46..3d7e46f4 100644 --- a/cmd/certs_storage.go +++ b/cmd/certs_storage.go @@ -17,7 +17,7 @@ import ( "github.com/go-acme/lego/v4/certcrypto" "github.com/go-acme/lego/v4/certificate" "github.com/go-acme/lego/v4/log" - "github.com/urfave/cli" + "github.com/urfave/cli/v2" "golang.org/x/net/idna" "software.sslmate.com/src/go-pkcs12" ) @@ -53,12 +53,12 @@ type CertificatesStorage struct { // NewCertificatesStorage create a new certificates storage. func NewCertificatesStorage(ctx *cli.Context) *CertificatesStorage { return &CertificatesStorage{ - rootPath: filepath.Join(ctx.GlobalString("path"), baseCertificatesFolderName), - archivePath: filepath.Join(ctx.GlobalString("path"), baseArchivesFolderName), - pem: ctx.GlobalBool("pem"), - pfx: ctx.GlobalBool("pfx"), - pfxPassword: ctx.GlobalString("pfx.pass"), - filename: ctx.GlobalString("filename"), + rootPath: filepath.Join(ctx.String("path"), baseCertificatesFolderName), + archivePath: filepath.Join(ctx.String("path"), baseArchivesFolderName), + pem: ctx.Bool("pem"), + pfx: ctx.Bool("pfx"), + pfxPassword: ctx.String("pfx.pass"), + filename: ctx.String("filename"), } } diff --git a/cmd/cmd.go b/cmd/cmd.go index 05b135f5..4d4dd3af 100644 --- a/cmd/cmd.go +++ b/cmd/cmd.go @@ -1,10 +1,10 @@ package cmd -import "github.com/urfave/cli" +import "github.com/urfave/cli/v2" // CreateCommands Creates all CLI commands. -func CreateCommands() []cli.Command { - return []cli.Command{ +func CreateCommands() []*cli.Command { + return []*cli.Command{ createRun(), createRevoke(), createRenew(), diff --git a/cmd/cmd_before.go b/cmd/cmd_before.go index 2d7dd465..61ffcb97 100644 --- a/cmd/cmd_before.go +++ b/cmd/cmd_before.go @@ -2,20 +2,20 @@ package cmd import ( "github.com/go-acme/lego/v4/log" - "github.com/urfave/cli" + "github.com/urfave/cli/v2" ) func Before(ctx *cli.Context) error { - if ctx.GlobalString("path") == "" { + if ctx.String("path") == "" { log.Fatal("Could not determine current working directory. Please pass --path.") } - err := createNonExistingFolder(ctx.GlobalString("path")) + err := createNonExistingFolder(ctx.String("path")) if err != nil { log.Fatalf("Could not check/create path: %v", err) } - if ctx.GlobalString("server") == "" { + if ctx.String("server") == "" { log.Fatal("Could not determine current working server. Please pass --server.") } diff --git a/cmd/cmd_dnshelp.go b/cmd/cmd_dnshelp.go index 33592112..4210e23a 100644 --- a/cmd/cmd_dnshelp.go +++ b/cmd/cmd_dnshelp.go @@ -7,18 +7,19 @@ import ( "strings" "text/tabwriter" - "github.com/urfave/cli" + "github.com/urfave/cli/v2" ) -func createDNSHelp() cli.Command { - return cli.Command{ +func createDNSHelp() *cli.Command { + return &cli.Command{ Name: "dnshelp", Usage: "Shows additional help for the '--dns' global option", Action: dnsHelp, Flags: []cli.Flag{ - cli.StringFlag{ - Name: "code, c", - Usage: fmt.Sprintf("DNS code: %s", allDNSCodes()), + &cli.StringFlag{ + Name: "code", + Aliases: []string{"c"}, + Usage: fmt.Sprintf("DNS code: %s", allDNSCodes()), }, }, } diff --git a/cmd/cmd_list.go b/cmd/cmd_list.go index 100c2a0b..90a15077 100644 --- a/cmd/cmd_list.go +++ b/cmd/cmd_list.go @@ -9,22 +9,24 @@ import ( "strings" "github.com/go-acme/lego/v4/certcrypto" - "github.com/urfave/cli" + "github.com/urfave/cli/v2" ) -func createList() cli.Command { - return cli.Command{ +func createList() *cli.Command { + return &cli.Command{ Name: "list", Usage: "Display certificates and accounts information.", Action: list, Flags: []cli.Flag{ - cli.BoolFlag{ - Name: "accounts, a", - Usage: "Display accounts.", + &cli.BoolFlag{ + Name: "accounts", + Aliases: []string{"a"}, + Usage: "Display accounts.", }, - cli.BoolFlag{ - Name: "names, n", - Usage: "Display certificate common names only.", + &cli.BoolFlag{ + Name: "names", + Aliases: []string{"n"}, + Usage: "Display certificate common names only.", }, }, } @@ -92,7 +94,7 @@ func listCertificates(ctx *cli.Context) error { func listAccount(ctx *cli.Context) error { // fake email, needed by NewAccountsStorage - if err := ctx.GlobalSet("email", "unknown"); err != nil { + if err := ctx.Set("email", "unknown"); err != nil { return err } diff --git a/cmd/cmd_renew.go b/cmd/cmd_renew.go index ac7897ff..ba93403f 100644 --- a/cmd/cmd_renew.go +++ b/cmd/cmd_renew.go @@ -9,7 +9,7 @@ import ( "github.com/go-acme/lego/v4/certificate" "github.com/go-acme/lego/v4/lego" "github.com/go-acme/lego/v4/log" - "github.com/urfave/cli" + "github.com/urfave/cli/v2" ) const ( @@ -19,15 +19,15 @@ const ( renewEnvCertKeyPath = "LEGO_CERT_KEY_PATH" ) -func createRenew() cli.Command { - return cli.Command{ +func createRenew() *cli.Command { + return &cli.Command{ Name: "renew", Usage: "Renew a certificate", Action: renew, Before: func(ctx *cli.Context) error { // we require either domains or csr, but not both - hasDomains := len(ctx.GlobalStringSlice("domains")) > 0 - hasCsr := len(ctx.GlobalString("csr")) > 0 + hasDomains := len(ctx.StringSlice("domains")) > 0 + hasCsr := len(ctx.String("csr")) > 0 if hasDomains && hasCsr { log.Fatal("Please specify either --domains/-d or --csr/-c, but not both") } @@ -37,32 +37,32 @@ func createRenew() cli.Command { return nil }, Flags: []cli.Flag{ - cli.IntFlag{ + &cli.IntFlag{ Name: "days", Value: 30, Usage: "The number of days left on a certificate to renew it.", }, - cli.BoolFlag{ + &cli.BoolFlag{ Name: "reuse-key", Usage: "Used to indicate you want to reuse your current private key for the new certificate.", }, - cli.BoolFlag{ + &cli.BoolFlag{ Name: "no-bundle", Usage: "Do not create a certificate bundle by adding the issuers certificate to the new certificate.", }, - cli.BoolFlag{ + &cli.BoolFlag{ Name: "must-staple", Usage: "Include the OCSP must staple TLS extension in the CSR and generated certificate. Only works if the CSR is generated by lego.", }, - cli.StringFlag{ + &cli.StringFlag{ Name: "renew-hook", Usage: "Define a hook. The hook is executed only when the certificates are effectively renewed.", }, - cli.StringFlag{ + &cli.StringFlag{ Name: "preferred-chain", Usage: "If the CA offers multiple certificate chains, prefer the chain with an issuer matching this Subject Common Name. If no match, the default offered chain will be used.", }, - cli.StringFlag{ + &cli.StringFlag{ Name: "always-deactivate-authorizations", Usage: "Force the authorizations to be relinquished even if the certificate request was successful.", }, @@ -85,7 +85,7 @@ func renew(ctx *cli.Context) error { meta := map[string]string{renewEnvAccountEmail: account.Email} // CSR - if ctx.GlobalIsSet("csr") { + if ctx.IsSet("csr") { return renewForCSR(ctx, client, certsStorage, bundle, meta) } @@ -94,7 +94,7 @@ func renew(ctx *cli.Context) error { } func renewForDomains(ctx *cli.Context, client *lego.Client, certsStorage *CertificatesStorage, bundle bool, meta map[string]string) error { - domains := ctx.GlobalStringSlice("domains") + domains := ctx.StringSlice("domains") domain := domains[0] // load the cert resource from files. @@ -153,7 +153,7 @@ func renewForDomains(ctx *cli.Context, client *lego.Client, certsStorage *Certif } func renewForCSR(ctx *cli.Context, client *lego.Client, certsStorage *CertificatesStorage, bundle bool, meta map[string]string) error { - csr, err := readCSRFile(ctx.GlobalString("csr")) + csr, err := readCSRFile(ctx.String("csr")) if err != nil { log.Fatal(err) } diff --git a/cmd/cmd_revoke.go b/cmd/cmd_revoke.go index 90390fe4..f735893e 100644 --- a/cmd/cmd_revoke.go +++ b/cmd/cmd_revoke.go @@ -3,20 +3,21 @@ package cmd import ( "github.com/go-acme/lego/v4/acme" "github.com/go-acme/lego/v4/log" - "github.com/urfave/cli" + "github.com/urfave/cli/v2" ) -func createRevoke() cli.Command { - return cli.Command{ +func createRevoke() *cli.Command { + return &cli.Command{ Name: "revoke", Usage: "Revoke a certificate", Action: revoke, Flags: []cli.Flag{ - cli.BoolFlag{ - Name: "keep, k", - Usage: "Keep the certificates after the revocation instead of archiving them.", + &cli.BoolFlag{ + Name: "keep", + Aliases: []string{"k"}, + Usage: "Keep the certificates after the revocation instead of archiving them.", }, - cli.UintFlag{ + &cli.UintFlag{ Name: "reason", Usage: "Identifies the reason for the certificate revocation. See https://www.rfc-editor.org/rfc/rfc5280.html#section-5.3.1. 0(unspecified),1(keyCompromise),2(cACompromise),3(affiliationChanged),4(superseded),5(cessationOfOperation),6(certificateHold),8(removeFromCRL),9(privilegeWithdrawn),10(aACompromise)", Value: acme.CRLReasonUnspecified, @@ -35,7 +36,7 @@ func revoke(ctx *cli.Context) error { certsStorage := NewCertificatesStorage(ctx) certsStorage.CreateRootFolder() - for _, domain := range ctx.GlobalStringSlice("domains") { + for _, domain := range ctx.StringSlice("domains") { log.Printf("Trying to revoke certificate for domain %s", domain) certBytes, err := certsStorage.ReadFile(domain, ".crt") diff --git a/cmd/cmd_run.go b/cmd/cmd_run.go index db368cdf..00259043 100644 --- a/cmd/cmd_run.go +++ b/cmd/cmd_run.go @@ -10,17 +10,17 @@ import ( "github.com/go-acme/lego/v4/lego" "github.com/go-acme/lego/v4/log" "github.com/go-acme/lego/v4/registration" - "github.com/urfave/cli" + "github.com/urfave/cli/v2" ) -func createRun() cli.Command { - return cli.Command{ +func createRun() *cli.Command { + return &cli.Command{ Name: "run", Usage: "Register an account, then create and install a certificate", Before: func(ctx *cli.Context) error { // we require either domains or csr, but not both - hasDomains := len(ctx.GlobalStringSlice("domains")) > 0 - hasCsr := len(ctx.GlobalString("csr")) > 0 + hasDomains := len(ctx.StringSlice("domains")) > 0 + hasCsr := len(ctx.String("csr")) > 0 if hasDomains && hasCsr { log.Fatal("Please specify either --domains/-d or --csr/-c, but not both") } @@ -31,23 +31,23 @@ func createRun() cli.Command { }, Action: run, Flags: []cli.Flag{ - cli.BoolFlag{ + &cli.BoolFlag{ Name: "no-bundle", Usage: "Do not create a certificate bundle by adding the issuers certificate to the new certificate.", }, - cli.BoolFlag{ + &cli.BoolFlag{ Name: "must-staple", Usage: "Include the OCSP must staple TLS extension in the CSR and generated certificate. Only works if the CSR is generated by lego.", }, - cli.StringFlag{ + &cli.StringFlag{ Name: "run-hook", Usage: "Define a hook. The hook is executed when the certificates are effectively created.", }, - cli.StringFlag{ + &cli.StringFlag{ Name: "preferred-chain", Usage: "If the CA offers multiple certificate chains, prefer the chain with an issuer matching this Subject Common Name. If no match, the default offered chain will be used.", }, - cli.StringFlag{ + &cli.StringFlag{ Name: "always-deactivate-authorizations", Usage: "Force the authorizations to be relinquished even if the certificate request was successful.", }, @@ -110,7 +110,7 @@ func run(ctx *cli.Context) error { func handleTOS(ctx *cli.Context, client *lego.Client) bool { // Check for a global accept override - if ctx.GlobalBool("accept-tos") { + if ctx.Bool("accept-tos") { return true } @@ -142,9 +142,9 @@ func register(ctx *cli.Context, client *lego.Client) (*registration.Resource, er log.Fatal("You did not accept the TOS. Unable to proceed.") } - if ctx.GlobalBool("eab") { - kid := ctx.GlobalString("kid") - hmacEncoded := ctx.GlobalString("hmac") + if ctx.Bool("eab") { + kid := ctx.String("kid") + hmacEncoded := ctx.String("hmac") if kid == "" || hmacEncoded == "" { log.Fatalf("Requires arguments --kid and --hmac.") @@ -163,7 +163,7 @@ func register(ctx *cli.Context, client *lego.Client) (*registration.Resource, er func obtainCertificate(ctx *cli.Context, client *lego.Client) (*certificate.Resource, error) { bundle := !ctx.Bool("no-bundle") - domains := ctx.GlobalStringSlice("domains") + domains := ctx.StringSlice("domains") if len(domains) > 0 { // obtain a certificate, generating a new private key request := certificate.ObtainRequest{ @@ -177,7 +177,7 @@ func obtainCertificate(ctx *cli.Context, client *lego.Client) (*certificate.Reso } // read the CSR - csr, err := readCSRFile(ctx.GlobalString("csr")) + csr, err := readCSRFile(ctx.String("csr")) if err != nil { return nil, err } diff --git a/cmd/flags.go b/cmd/flags.go index dcc90018..88e5c610 100644 --- a/cmd/flags.go +++ b/cmd/flags.go @@ -2,126 +2,132 @@ package cmd import ( "github.com/go-acme/lego/v4/lego" - "github.com/urfave/cli" - pkcs12 "software.sslmate.com/src/go-pkcs12" + "github.com/urfave/cli/v2" + "software.sslmate.com/src/go-pkcs12" ) func CreateFlags(defaultPath string) []cli.Flag { return []cli.Flag{ - cli.StringSliceFlag{ - Name: "domains, d", - Usage: "Add a domain to the process. Can be specified multiple times.", + &cli.StringSliceFlag{ + Name: "domains", + Aliases: []string{"d"}, + Usage: "Add a domain to the process. Can be specified multiple times.", }, - cli.StringFlag{ - Name: "server, s", - Usage: "CA hostname (and optionally :port). The server certificate must be trusted in order to avoid further modifications to the client.", - Value: lego.LEDirectoryProduction, + &cli.StringFlag{ + Name: "server", + Aliases: []string{"s"}, + Usage: "CA hostname (and optionally :port). The server certificate must be trusted in order to avoid further modifications to the client.", + Value: lego.LEDirectoryProduction, }, - cli.BoolFlag{ - Name: "accept-tos, a", - Usage: "By setting this flag to true you indicate that you accept the current Let's Encrypt terms of service.", + &cli.BoolFlag{ + Name: "accept-tos", + Aliases: []string{"a"}, + Usage: "By setting this flag to true you indicate that you accept the current Let's Encrypt terms of service.", }, - cli.StringFlag{ - Name: "email, m", - Usage: "Email used for registration and recovery contact.", + &cli.StringFlag{ + Name: "email", + Aliases: []string{"m"}, + Usage: "Email used for registration and recovery contact.", }, - cli.StringFlag{ - Name: "csr, c", - Usage: "Certificate signing request filename, if an external CSR is to be used.", + &cli.StringFlag{ + Name: "csr", + Aliases: []string{"c"}, + Usage: "Certificate signing request filename, if an external CSR is to be used.", }, - cli.BoolFlag{ + &cli.BoolFlag{ Name: "eab", Usage: "Use External Account Binding for account registration. Requires --kid and --hmac.", }, - cli.StringFlag{ + &cli.StringFlag{ Name: "kid", Usage: "Key identifier from External CA. Used for External Account Binding.", }, - cli.StringFlag{ + &cli.StringFlag{ Name: "hmac", Usage: "MAC key from External CA. Should be in Base64 URL Encoding without padding format. Used for External Account Binding.", }, - cli.StringFlag{ - Name: "key-type, k", - Value: "ec256", - Usage: "Key type to use for private keys. Supported: rsa2048, rsa4096, rsa8192, ec256, ec384.", + &cli.StringFlag{ + Name: "key-type", + Aliases: []string{"k"}, + Value: "ec256", + Usage: "Key type to use for private keys. Supported: rsa2048, rsa4096, rsa8192, ec256, ec384.", }, - cli.StringFlag{ + &cli.StringFlag{ Name: "filename", Usage: "(deprecated) Filename of the generated certificate.", }, - cli.StringFlag{ - Name: "path", - EnvVar: "LEGO_PATH", - Usage: "Directory to use for storing the data.", - Value: defaultPath, + &cli.StringFlag{ + Name: "path", + EnvVars: []string{"LEGO_PATH"}, + Usage: "Directory to use for storing the data.", + Value: defaultPath, }, - cli.BoolFlag{ + &cli.BoolFlag{ Name: "http", Usage: "Use the HTTP challenge to solve challenges. Can be mixed with other types of challenges.", }, - cli.StringFlag{ + &cli.StringFlag{ Name: "http.port", Usage: "Set the port and interface to use for HTTP based challenges to listen on.Supported: interface:port or :port.", Value: ":80", }, - cli.StringFlag{ + &cli.StringFlag{ Name: "http.proxy-header", Usage: "Validate against this HTTP header when solving HTTP based challenges behind a reverse proxy.", Value: "Host", }, - cli.StringFlag{ + &cli.StringFlag{ Name: "http.webroot", Usage: "Set the webroot folder to use for HTTP based challenges to write directly in a file in .well-known/acme-challenge. This disables the built-in server and expects the given directory to be publicly served with access to .well-known/acme-challenge", }, - cli.StringSliceFlag{ + &cli.StringSliceFlag{ Name: "http.memcached-host", Usage: "Set the memcached host(s) to use for HTTP based challenges. Challenges will be written to all specified hosts.", }, - cli.BoolFlag{ + &cli.BoolFlag{ Name: "tls", Usage: "Use the TLS challenge to solve challenges. Can be mixed with other types of challenges.", }, - cli.StringFlag{ + &cli.StringFlag{ Name: "tls.port", Usage: "Set the port and interface to use for TLS based challenges to listen on. Supported: interface:port or :port.", Value: ":443", }, - cli.StringFlag{ + &cli.StringFlag{ Name: "dns", Usage: "Solve a DNS challenge using the specified provider. Can be mixed with other types of challenges. Run 'lego dnshelp' for help on usage.", }, - cli.BoolFlag{ + &cli.BoolFlag{ Name: "dns.disable-cp", Usage: "By setting this flag to true, disables the need to wait the propagation of the TXT record to all authoritative name servers.", }, - cli.StringSliceFlag{ + &cli.StringSliceFlag{ Name: "dns.resolvers", Usage: "Set the resolvers to use for performing recursive DNS queries. Supported: host:port. The default is to use the system resolvers, or Google's DNS resolvers if the system's cannot be determined.", }, - cli.IntFlag{ + &cli.IntFlag{ Name: "http-timeout", Usage: "Set the HTTP timeout value to a specific value in seconds.", }, - cli.IntFlag{ + &cli.IntFlag{ Name: "dns-timeout", Usage: "Set the DNS timeout value to a specific value in seconds. Used only when performing authoritative name servers queries.", Value: 10, }, - cli.BoolFlag{ + &cli.BoolFlag{ Name: "pem", Usage: "Generate a .pem file by concatenating the .key and .crt files together.", }, - cli.BoolFlag{ + &cli.BoolFlag{ Name: "pfx", Usage: "Generate a .pfx (PKCS#12) file by with the .key and .crt and issuer .crt files together.", }, - cli.StringFlag{ + &cli.StringFlag{ Name: "pfx.pass", Usage: "The password used to encrypt the .pfx (PCKS#12) file.", Value: pkcs12.DefaultPassword, }, - cli.IntFlag{ + &cli.IntFlag{ Name: "cert.timeout", Usage: "Set the certificate timeout value to a specific value in seconds. Only used when obtaining certificates.", Value: 30, diff --git a/cmd/lego/main.go b/cmd/lego/main.go index 2467272e..de498699 100644 --- a/cmd/lego/main.go +++ b/cmd/lego/main.go @@ -10,7 +10,7 @@ import ( "github.com/go-acme/lego/v4/cmd" "github.com/go-acme/lego/v4/log" - "github.com/urfave/cli" + "github.com/urfave/cli/v2" ) var version = "dev" diff --git a/cmd/setup.go b/cmd/setup.go index 063c740a..94e3345f 100644 --- a/cmd/setup.go +++ b/cmd/setup.go @@ -12,7 +12,7 @@ import ( "github.com/go-acme/lego/v4/lego" "github.com/go-acme/lego/v4/log" "github.com/go-acme/lego/v4/registration" - "github.com/urfave/cli" + "github.com/urfave/cli/v2" ) const filePerm os.FileMode = 0o600 @@ -35,16 +35,16 @@ func setup(ctx *cli.Context, accountsStorage *AccountsStorage) (*Account, *lego. func newClient(ctx *cli.Context, acc registration.User, keyType certcrypto.KeyType) *lego.Client { config := lego.NewConfig(acc) - config.CADirURL = ctx.GlobalString("server") + config.CADirURL = ctx.String("server") config.Certificate = lego.CertificateConfig{ KeyType: keyType, - Timeout: time.Duration(ctx.GlobalInt("cert.timeout")) * time.Second, + Timeout: time.Duration(ctx.Int("cert.timeout")) * time.Second, } config.UserAgent = fmt.Sprintf("lego-cli/%s", ctx.App.Version) - if ctx.GlobalIsSet("http-timeout") { - config.HTTPClient.Timeout = time.Duration(ctx.GlobalInt("http-timeout")) * time.Second + if ctx.IsSet("http-timeout") { + config.HTTPClient.Timeout = time.Duration(ctx.Int("http-timeout")) * time.Second } client, err := lego.NewClient(config) @@ -52,7 +52,7 @@ func newClient(ctx *cli.Context, acc registration.User, keyType certcrypto.KeyTy log.Fatalf("Could not create client: %v", err) } - if client.GetExternalAccountRequired() && !ctx.GlobalIsSet("eab") { + if client.GetExternalAccountRequired() && !ctx.IsSet("eab") { log.Fatal("Server requires External Account Binding. Use --eab with --kid and --hmac.") } @@ -61,7 +61,7 @@ func newClient(ctx *cli.Context, acc registration.User, keyType certcrypto.KeyTy // getKeyType the type from which private keys should be generated. func getKeyType(ctx *cli.Context) certcrypto.KeyType { - keyType := ctx.GlobalString("key-type") + keyType := ctx.String("key-type") switch strings.ToUpper(keyType) { case "RSA2048": return certcrypto.RSA2048 @@ -80,7 +80,7 @@ func getKeyType(ctx *cli.Context) certcrypto.KeyType { } func getEmail(ctx *cli.Context) string { - email := ctx.GlobalString("email") + email := ctx.String("email") if email == "" { log.Fatal("You have to pass an account (email address) to the program using --email or -m") } diff --git a/cmd/setup_challenges.go b/cmd/setup_challenges.go index 95aee069..938ee745 100644 --- a/cmd/setup_challenges.go +++ b/cmd/setup_challenges.go @@ -14,49 +14,49 @@ import ( "github.com/go-acme/lego/v4/providers/dns" "github.com/go-acme/lego/v4/providers/http/memcached" "github.com/go-acme/lego/v4/providers/http/webroot" - "github.com/urfave/cli" + "github.com/urfave/cli/v2" ) func setupChallenges(ctx *cli.Context, client *lego.Client) { - if !ctx.GlobalBool("http") && !ctx.GlobalBool("tls") && !ctx.GlobalIsSet("dns") { + if !ctx.Bool("http") && !ctx.Bool("tls") && !ctx.IsSet("dns") { log.Fatal("No challenge selected. You must specify at least one challenge: `--http`, `--tls`, `--dns`.") } - if ctx.GlobalBool("http") { + if ctx.Bool("http") { err := client.Challenge.SetHTTP01Provider(setupHTTPProvider(ctx)) if err != nil { log.Fatal(err) } } - if ctx.GlobalBool("tls") { + if ctx.Bool("tls") { err := client.Challenge.SetTLSALPN01Provider(setupTLSProvider(ctx)) if err != nil { log.Fatal(err) } } - if ctx.GlobalIsSet("dns") { + if ctx.IsSet("dns") { setupDNS(ctx, client) } } func setupHTTPProvider(ctx *cli.Context) challenge.Provider { switch { - case ctx.GlobalIsSet("http.webroot"): - ps, err := webroot.NewHTTPProvider(ctx.GlobalString("http.webroot")) + case ctx.IsSet("http.webroot"): + ps, err := webroot.NewHTTPProvider(ctx.String("http.webroot")) if err != nil { log.Fatal(err) } return ps - case ctx.GlobalIsSet("http.memcached-host"): - ps, err := memcached.NewMemcachedProvider(ctx.GlobalStringSlice("http.memcached-host")) + case ctx.IsSet("http.memcached-host"): + ps, err := memcached.NewMemcachedProvider(ctx.StringSlice("http.memcached-host")) if err != nil { log.Fatal(err) } return ps - case ctx.GlobalIsSet("http.port"): - iface := ctx.GlobalString("http.port") + case ctx.IsSet("http.port"): + iface := ctx.String("http.port") if !strings.Contains(iface, ":") { log.Fatalf("The --http switch only accepts interface:port or :port for its argument.") } @@ -67,13 +67,13 @@ func setupHTTPProvider(ctx *cli.Context) challenge.Provider { } srv := http01.NewProviderServer(host, port) - if header := ctx.GlobalString("http.proxy-header"); header != "" { + if header := ctx.String("http.proxy-header"); header != "" { srv.SetProxyHeader(header) } return srv - case ctx.GlobalBool("http"): + case ctx.Bool("http"): srv := http01.NewProviderServer("", "") - if header := ctx.GlobalString("http.proxy-header"); header != "" { + if header := ctx.String("http.proxy-header"); header != "" { srv.SetProxyHeader(header) } return srv @@ -85,8 +85,8 @@ func setupHTTPProvider(ctx *cli.Context) challenge.Provider { func setupTLSProvider(ctx *cli.Context) challenge.Provider { switch { - case ctx.GlobalIsSet("tls.port"): - iface := ctx.GlobalString("tls.port") + case ctx.IsSet("tls.port"): + iface := ctx.String("tls.port") if !strings.Contains(iface, ":") { log.Fatalf("The --tls switch only accepts interface:port or :port for its argument.") } @@ -97,7 +97,7 @@ func setupTLSProvider(ctx *cli.Context) challenge.Provider { } return tlsalpn01.NewProviderServer(host, port) - case ctx.GlobalBool("tls"): + case ctx.Bool("tls"): return tlsalpn01.NewProviderServer("", "") default: log.Fatal("Invalid HTTP challenge options.") @@ -106,19 +106,19 @@ func setupTLSProvider(ctx *cli.Context) challenge.Provider { } func setupDNS(ctx *cli.Context, client *lego.Client) { - provider, err := dns.NewDNSChallengeProviderByName(ctx.GlobalString("dns")) + provider, err := dns.NewDNSChallengeProviderByName(ctx.String("dns")) if err != nil { log.Fatal(err) } - servers := ctx.GlobalStringSlice("dns.resolvers") + servers := ctx.StringSlice("dns.resolvers") err = client.Challenge.SetDNS01Provider(provider, dns01.CondOption(len(servers) > 0, - dns01.AddRecursiveNameservers(dns01.ParseNameservers(ctx.GlobalStringSlice("dns.resolvers")))), - dns01.CondOption(ctx.GlobalBool("dns.disable-cp"), + dns01.AddRecursiveNameservers(dns01.ParseNameservers(ctx.StringSlice("dns.resolvers")))), + dns01.CondOption(ctx.Bool("dns.disable-cp"), dns01.DisableCompletePropagationRequirement()), - dns01.CondOption(ctx.GlobalIsSet("dns-timeout"), - dns01.AddDNSTimeout(time.Duration(ctx.GlobalInt("dns-timeout"))*time.Second)), + dns01.CondOption(ctx.IsSet("dns-timeout"), + dns01.AddDNSTimeout(time.Duration(ctx.Int("dns-timeout"))*time.Second)), ) if err != nil { log.Fatal(err) diff --git a/docs/content/usage/cli/_index.md b/docs/content/usage/cli/_index.md index c32d0755..155e7400 100644 --- a/docs/content/usage/cli/_index.md +++ b/docs/content/usage/cli/_index.md @@ -28,33 +28,33 @@ COMMANDS: GLOBAL OPTIONS: --domains value, -d value Add a domain to the process. Can be specified multiple times. --server value, -s value CA hostname (and optionally :port). The server certificate must be trusted in order to avoid further modifications to the client. (default: "https://acme-v02.api.letsencrypt.org/directory") - --accept-tos, -a By setting this flag to true you indicate that you accept the current Let's Encrypt terms of service. + --accept-tos, -a By setting this flag to true you indicate that you accept the current Let's Encrypt terms of service. (default: false) --email value, -m value Email used for registration and recovery contact. --csr value, -c value Certificate signing request filename, if an external CSR is to be used. - --eab Use External Account Binding for account registration. Requires --kid and --hmac. + --eab Use External Account Binding for account registration. Requires --kid and --hmac. (default: false) --kid value Key identifier from External CA. Used for External Account Binding. --hmac value MAC key from External CA. Should be in Base64 URL Encoding without padding format. Used for External Account Binding. --key-type value, -k value Key type to use for private keys. Supported: rsa2048, rsa4096, rsa8192, ec256, ec384. (default: "ec256") --filename value (deprecated) Filename of the generated certificate. --path value Directory to use for storing the data. (default: "./.lego") [$LEGO_PATH] - --http Use the HTTP challenge to solve challenges. Can be mixed with other types of challenges. + --http Use the HTTP challenge to solve challenges. Can be mixed with other types of challenges. (default: false) --http.port value Set the port and interface to use for HTTP based challenges to listen on.Supported: interface:port or :port. (default: ":80") --http.proxy-header value Validate against this HTTP header when solving HTTP based challenges behind a reverse proxy. (default: "Host") --http.webroot value Set the webroot folder to use for HTTP based challenges to write directly in a file in .well-known/acme-challenge. This disables the built-in server and expects the given directory to be publicly served with access to .well-known/acme-challenge --http.memcached-host value Set the memcached host(s) to use for HTTP based challenges. Challenges will be written to all specified hosts. - --tls Use the TLS challenge to solve challenges. Can be mixed with other types of challenges. + --tls Use the TLS challenge to solve challenges. Can be mixed with other types of challenges. (default: false) --tls.port value Set the port and interface to use for TLS based challenges to listen on. Supported: interface:port or :port. (default: ":443") --dns value Solve a DNS challenge using the specified provider. Can be mixed with other types of challenges. Run 'lego dnshelp' for help on usage. - --dns.disable-cp By setting this flag to true, disables the need to wait the propagation of the TXT record to all authoritative name servers. + --dns.disable-cp By setting this flag to true, disables the need to wait the propagation of the TXT record to all authoritative name servers. (default: false) --dns.resolvers value Set the resolvers to use for performing recursive DNS queries. Supported: host:port. The default is to use the system resolvers, or Google's DNS resolvers if the system's cannot be determined. --http-timeout value Set the HTTP timeout value to a specific value in seconds. (default: 0) --dns-timeout value Set the DNS timeout value to a specific value in seconds. Used only when performing authoritative name servers queries. (default: 10) - --pem Generate a .pem file by concatenating the .key and .crt files together. - --pfx Generate a .pfx (PKCS#12) file by with the .key and .crt and issuer .crt files together. - --pfx.pass The password used to encrypt the .pfx (PCKS#12) file (default: changeit). + --pem Generate a .pem file by concatenating the .key and .crt files together. (default: false) + --pfx Generate a .pfx (PKCS#12) file by with the .key and .crt and issuer .crt files together. (default: false) + --pfx.pass value The password used to encrypt the .pfx (PCKS#12) file. (default: "changeit") --cert.timeout value Set the certificate timeout value to a specific value in seconds. Only used when obtaining certificates. (default: 30) - --help, -h show help - --version, -v print the version + --help, -h show help (default: false) + --version, -v print the version (default: false) ``` When using the standard `--path` option, all certificates and account configurations are saved to a folder `.lego` in the current working directory. diff --git a/go.mod b/go.mod index 334ac1bd..a4a19dd7 100644 --- a/go.mod +++ b/go.mod @@ -52,7 +52,7 @@ require ( github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.287 github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dnspod v1.0.287 github.com/transip/gotransip/v6 v6.6.1 - github.com/urfave/cli v1.22.5 + github.com/urfave/cli/v2 v2.3.0 github.com/vinyldns/go-vinyldns v0.9.16 github.com/vultr/govultr/v2 v2.7.1 golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e diff --git a/go.sum b/go.sum index 3d15eb93..55756062 100644 --- a/go.sum +++ b/go.sum @@ -474,8 +474,7 @@ github.com/transip/gotransip/v6 v6.6.1 h1:nsCU1ErZS5G0FeOpgGXc4FsWvBff9GPswSMggs github.com/transip/gotransip/v6 v6.6.1/go.mod h1:pQZ36hWWRahCUXkFWlx9Hs711gLd8J4qdgLdRzmtY+g= github.com/uber-go/atomic v1.3.2 h1:Azu9lPBWRNKzYXSIwRfgRuDuS0YKsK4NFhiQv98gkxo= github.com/uber-go/atomic v1.3.2/go.mod h1:/Ct5t2lcmbJ4OSe/waGBoaVvVqtO0bmtfVNex1PFV8g= -github.com/urfave/cli v1.22.5 h1:lNq9sAHXK2qfdI8W+GRItjCEkI+2oR4d+MEHy1CKXoU= -github.com/urfave/cli v1.22.5/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= +github.com/urfave/cli/v2 v2.3.0 h1:qph92Y649prgesehzOrQjdWyxFOp/QVM+6imKHad91M= github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8= diff --git a/internal/release.go b/internal/release.go index f3330270..b03e62b2 100644 --- a/internal/release.go +++ b/internal/release.go @@ -14,7 +14,7 @@ import ( "strings" "text/template" - "github.com/urfave/cli" + "github.com/urfave/cli/v2" ) const sourceFile = "./acme/api/internal/sender/useragent.go" @@ -41,7 +41,7 @@ func main() { app.Name = "lego-releaser" app.Usage = "Lego releaser" app.HelpName = "releaser" - app.Commands = []cli.Command{ + app.Commands = []*cli.Command{ { Name: "release", Usage: "Update file for a release", @@ -56,10 +56,11 @@ func main() { } }, Flags: []cli.Flag{ - cli.StringFlag{ - Name: "mode, m", - Value: "patch", - Usage: "The release mode: patch|minor|major", + &cli.StringFlag{ + Name: "mode", + Aliases: []string{"m"}, + Value: "patch", + Usage: "The release mode: patch|minor|major", }, }, },