1
0
mirror of https://github.com/go-acme/lego.git synced 2024-11-28 09:33:13 +02:00

chore: migrate to github.com/urfave/cli/v2 (#1590)

This commit is contained in:
Ludovic Fernandez 2022-02-13 12:28:51 +01:00 committed by GitHub
parent 6d474ebb65
commit 7d9176bd0d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 181 additions and 171 deletions

View File

@ -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)

View File

@ -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"),
}
}

View File

@ -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(),

View File

@ -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.")
}

View File

@ -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()),
},
},
}

View File

@ -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
}

View File

@ -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)
}

View File

@ -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")

View File

@ -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
}

View File

@ -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,

View File

@ -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"

View File

@ -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")
}

View File

@ -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)

View File

@ -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.

2
go.mod
View File

@ -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

3
go.sum
View File

@ -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=

View File

@ -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",
},
},
},