From 4824a23492b1091af3b374eb4df27c82880e3d47 Mon Sep 17 00:00:00 2001 From: Fu Diwei Date: Wed, 27 May 2026 23:47:13 +0800 Subject: [PATCH] chore(deps): migrate to lego v5 --- cmd/intercmd.go | 57 ++++++-- go.mod | 38 +++--- go.sum | 76 +++++------ internal/certacme/account.go | 35 +++-- internal/certacme/ca.go | 70 ++++++++++ internal/certacme/client.go | 22 +--- internal/certacme/client_obtain.go | 80 +++++------- internal/certacme/client_revoke.go | 23 +--- internal/certacme/config.go | 123 +++++------------- internal/certacme/logging.go | 61 --------- internal/certificate/service.go | 4 +- internal/certmgmt/client_deploy.go | 10 +- internal/domain/acme_account.go | 19 ++- internal/domain/certificate.go | 34 ++--- internal/domain/provider.go | 14 +- internal/notify/client_notifier.go | 4 +- internal/notify/service.go | 2 +- internal/repository/acme_account.go | 10 +- internal/tools/mproc/sender.go | 47 ++++--- internal/tools/mproc/stdlog.go | 54 ++++++++ internal/workflow/engine/engine.go | 2 +- internal/workflow/engine/executor_bizapply.go | 116 +++++++++-------- .../workflow/engine/executor_bizdeploy.go | 6 +- .../workflow/engine/executor_biznotify.go | 7 +- pkg/core/certifier.go | 2 +- .../certifier/challengers/dns01/35cn/35cn.go | 2 +- .../dns01/51dnscom/internal/lego.go | 27 ++-- .../challengers/dns01/acmedns/acmedns.go | 2 +- .../dns01/acmehttpreq/acmehttpreq.go | 2 +- .../dns01/akamai-edgedns/akamai_edgedns.go | 4 +- .../dns01/aliyun-esa/aliyun_esa.go | 2 +- .../challengers/dns01/aliyun/aliyun.go | 2 +- .../dns01/arvancloud/arvancloud.go | 2 +- .../dns01/aws-lightsail/aws_lightsail.go | 6 +- .../dns01/aws-lightsail/internal/lego.go | 22 ++-- .../dns01/aws-route53/aws_route53.go | 2 +- .../challengers/dns01/azure-dns/azure_dns.go | 2 +- .../dns01/baiducloud/baiducloud.go | 2 +- .../dns01/bookmyname/bookmyname.go | 2 +- .../challengers/dns01/bunny/bunny.go | 2 +- .../dns01/cloudflare/cloudflare.go | 2 +- .../challengers/dns01/cloudns/cloudns.go | 2 +- .../dns01/cmcccloud/internal/lego.go | 17 +-- .../dns01/constellix/constellix.go | 2 +- .../challengers/dns01/cpanel/cpanel.go | 2 +- .../dns01/ctcccloud/internal/lego.go | 21 +-- .../challengers/dns01/desec/desec.go | 2 +- .../dns01/digitalocean/digitalocean.go | 2 +- .../challengers/dns01/dnsexit/dnsexit.go | 2 +- .../challengers/dns01/dnsla/internal/lego.go | 27 ++-- .../dns01/dnsmadeeasy/dnsmadeeasy.go | 2 +- .../challengers/dns01/duckdns/duckdns.go | 2 +- .../dns01/dynadot/internal/lego.go | 23 ++-- .../certifier/challengers/dns01/dynu/dynu.go | 2 +- .../challengers/dns01/dynv6/internal/lego.go | 27 ++-- .../challengers/dns01/gandinet/gandinet.go | 2 +- .../challengers/dns01/gcore/gcore.go | 2 +- .../challengers/dns01/gname/internal/lego.go | 23 ++-- .../challengers/dns01/godaddy/godaddy.go | 2 +- .../challengers/dns01/hetzner/hetzner.go | 2 +- .../challengers/dns01/hostingde/hostingde.go | 2 +- .../challengers/dns01/hostinger/hostinger.go | 2 +- .../dns01/huaweicloud/huaweicloud.go | 2 +- .../dns01/infomaniak/infomaniak.go | 2 +- .../challengers/dns01/ionos/ionos.go | 2 +- .../challengers/dns01/jdcloud/jdcloud.go | 2 +- .../challengers/dns01/linode/linode.go | 2 +- .../challengers/dns01/namecheap/namecheap.go | 2 +- .../dns01/namedotcom/namedotcom.go | 2 +- .../challengers/dns01/namesilo/namesilo.go | 2 +- .../challengers/dns01/netcup/netcup.go | 5 +- .../challengers/dns01/netlify/netlify.go | 2 +- .../certifier/challengers/dns01/ns1/ns1.go | 2 +- .../challengers/dns01/ovhcloud/ovhcloud.go | 2 +- .../challengers/dns01/porkbun/porkbun.go | 2 +- .../challengers/dns01/powerdns/powerdns.go | 2 +- .../dns01/qingcloud/internal/lego.go | 21 +-- .../challengers/dns01/rainyun/rainyun.go | 2 +- .../challengers/dns01/rfc2136/rfc2136.go | 6 +- .../challengers/dns01/spaceship/spaceship.go | 2 +- .../dns01/technitiumdns/technitiumdns.go | 2 +- .../dns01/tencentcloud-eo/tencentcloud_eo.go | 2 +- .../dns01/tencentcloud/tencentcloud.go | 2 +- .../challengers/dns01/todaynic/todaynic.go | 2 +- .../challengers/dns01/ucloud/ucloud.go | 2 +- .../challengers/dns01/vercel/vercel.go | 2 +- .../dns01/volcengine/volcengine.go | 2 +- .../challengers/dns01/vultr/vultr.go | 2 +- .../challengers/dns01/westcn/westcn.go | 2 +- .../challengers/dns01/xinnet/internal/lego.go | 23 ++-- .../certifier/challengers/http01/ftp/ftp.go | 10 +- .../challengers/http01/local/local.go | 2 +- .../certifier/challengers/http01/s3/s3.go | 10 +- .../certifier/challengers/http01/ssh/ssh.go | 7 +- pkg/logging/{handler.go => handler_hook.go} | 8 +- pkg/logging/handler_named.go | 47 +++++++ pkg/utils/cert/parser.go | 2 +- 97 files changed, 693 insertions(+), 663 deletions(-) create mode 100644 internal/certacme/ca.go delete mode 100644 internal/certacme/logging.go create mode 100644 internal/tools/mproc/stdlog.go rename pkg/logging/{handler.go => handler_hook.go} (92%) create mode 100644 pkg/logging/handler_named.go diff --git a/cmd/intercmd.go b/cmd/intercmd.go index 863e4536a..900038a4d 100644 --- a/cmd/intercmd.go +++ b/cmd/intercmd.go @@ -3,17 +3,18 @@ package cmd import ( "context" "fmt" - "log" + "log/slog" "os" + "time" - "github.com/go-acme/lego/v4/lego" - legolog "github.com/go-acme/lego/v4/log" + "github.com/go-acme/lego/v5/lego" + "github.com/go-acme/lego/v5/log" "github.com/pocketbase/pocketbase/core" "github.com/spf13/cobra" - "github.com/certimate-go/certimate/internal/app" "github.com/certimate-go/certimate/internal/certacme" "github.com/certimate-go/certimate/internal/tools/mproc" + "github.com/certimate-go/certimate/pkg/logging" ) func NewInternalCommand(app core.App) *cobra.Command { @@ -33,14 +34,43 @@ func internalCertApplyCommand(_ core.App) *cobra.Command { var flagError string var flagEncryptionKey string + hookStdLog := func(namespace string) *slog.Logger { + jHdr := slog.NewJSONHandler(os.Stdout, nil) + nHdr := logging.NewNamedHandler(jHdr, namespace) + hHdr := logging.NewHookHandler(nil, &logging.HookHandlerOptions{ + WriteFunc: func(ctx context.Context, record logging.Record) error { + copy := slog.NewRecord(record.Time, record.Level, record.Message, record.PC) + + record.Attrs(func(a slog.Attr) bool { + if a.Value.Kind() == slog.KindDuration { + a = log.DurationAttr(a.Key, a.Value.Duration()) + } else if a.Value.Kind() == slog.KindAny && a.Value.Any() != nil { + if d, ok := a.Value.Any().(time.Duration); ok { + a = log.DurationAttr(a.Key, d) + } + } + + copy.AddAttrs(a) + return true + }) + + nHdr.Handle(ctx, copy) + return nil + }, + }) + return slog.New(hHdr) + } + command := &cobra.Command{ Use: "certapply", Example: "internal certapply --mprocIn ./in.file --mprocOut ./out.file --mprocSecret aeskey", SilenceUsage: true, Run: func(cmd *cobra.Command, args []string) { type InData struct { - Account *certacme.ACMEAccount `json:"account,omitempty"` Request *certacme.ObtainCertificateRequest `json:"request,omitempty"` + + LegoAccount *certacme.ACMEAccount `json:"legoAccount,omitempty"` + LegoCertifierConfig *lego.CertificateConfig `json:"legoCertifierConfig,omitempty"` } type OutData struct { @@ -48,22 +78,23 @@ func internalCertApplyCommand(_ core.App) *cobra.Command { } mreceiver := mproc.NewReceiver(func(ctx context.Context, params *InData) (*OutData, error) { - if params.Account == nil { + if params.LegoAccount == nil { return nil, fmt.Errorf("illegal params") } if params.Request == nil { return nil, fmt.Errorf("illegal params") } - // redirect to stdout, remove datetime prefix - // so that the logger can split logs correctly + // set lego logger to a wrapped JSON handler, + // so that the logger can parse logs correctly. // see: /internal/tools/mproc/sender.go - legolog.Logger = log.New(os.Stdout, "", 0) + log.SetDefault(hookStdLog("go-acme/lego")) + + client, err := certacme.NewACMEClientWithAccount(params.LegoAccount, func(legoCfg *lego.Config) error { + if params.LegoCertifierConfig != nil { + legoCfg.Certificate = *params.LegoCertifierConfig + } - client, err := certacme.NewACMEClientWithAccount(params.Account, func(c *lego.Config) error { - c.UserAgent = app.AppUserAgent - c.Certificate.KeyType = params.Request.PrivateKeyType - c.Certificate.DisableCommonName = params.Request.NoCommonName return nil }) if err != nil { diff --git a/go.mod b/go.mod index 74241b74b..fb2855e40 100644 --- a/go.mod +++ b/go.mod @@ -39,12 +39,12 @@ require ( github.com/aws/aws-sdk-go-v2/service/lightsail v1.54.0 github.com/baidubce/bce-sdk-go v0.9.266 github.com/byteplus-sdk/byteplus-sdk-golang v1.0.65 - github.com/go-acme/lego/v4 v4.34.0 + github.com/go-acme/lego/v5 v5.1.0 github.com/go-cmd/cmd v1.4.3 github.com/go-resty/resty/v2 v2.17.2 github.com/go-viper/mapstructure/v2 v2.5.0 github.com/google/go-querystring v1.2.0 - github.com/huaweicloud/huaweicloud-sdk-go-v3 v0.1.195 + github.com/huaweicloud/huaweicloud-sdk-go-v3 v0.1.197 github.com/jdcloud-api/jdcloud-sdk-go v1.64.0 github.com/jlaffaye/ftp v0.2.0 github.com/kong/go-kong v0.75.1 @@ -53,6 +53,7 @@ require ( github.com/minio/minio-go/v7 v7.1.0 github.com/mohuatech/mohuacloud-go-sdk v0.0.0-20251115182757-6fba4d0a4c47 github.com/pavlo-v-chernykh/keystore-go/v4 v4.5.0 + github.com/pkg/errors v0.9.1 github.com/pkg/sftp v1.13.10 github.com/pocketbase/dbx v1.12.0 github.com/pocketbase/pocketbase v0.38.1 @@ -64,7 +65,7 @@ require ( github.com/spf13/pflag v1.0.10 github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cdn v1.3.90 github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/clb v1.3.83 - github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.3.97 + github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.3.102 github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/gaap v1.3.34 github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/live v1.3.95 github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/scf v1.3.29 @@ -72,17 +73,19 @@ require ( github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/teo v1.3.93 github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/vod v1.3.96 github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/waf v1.3.95 - github.com/ucloud/ucloud-sdk-go v0.22.70 + github.com/ucloud/ucloud-sdk-go v0.22.73 github.com/volcengine/ve-tos-golang-sdk/v2 v2.9.4 - github.com/volcengine/volc-sdk-golang v1.0.246 + github.com/volcengine/volc-sdk-golang v1.0.248 github.com/volcengine/volcengine-go-sdk v1.2.27 github.com/wneessen/go-mail v0.7.3 github.com/xhit/go-str2duration/v2 v2.1.0 + github.com/zenlayer/zenlayercloud-sdk-go v0.2.33 gitlab.ecloud.com/ecloud/ecloudsdkclouddns v1.0.1 gitlab.ecloud.com/ecloud/ecloudsdkcore v1.0.0 - golang.org/x/crypto v0.51.0 + golang.org/x/crypto v0.52.0 golang.org/x/sync v0.20.0 - golang.org/x/sys v0.44.0 + golang.org/x/sys v0.45.0 + google.golang.org/protobuf v1.36.11 k8s.io/api v0.35.3 k8s.io/apimachinery v0.35.3 k8s.io/client-go v0.35.3 @@ -99,7 +102,7 @@ require ( github.com/alibabacloud-go/alibabacloud-gateway-fc-util v0.0.7 // indirect github.com/avast/retry-go v3.0.0+incompatible // indirect github.com/aws/aws-sdk-go v1.55.8 // indirect - github.com/aws/aws-sdk-go-v2/service/route53 v1.62.5 // indirect + github.com/aws/aws-sdk-go-v2/service/route53 v1.62.7 // indirect github.com/benbjohnson/clock v1.3.5 // indirect github.com/buger/goterm v1.0.4 // indirect github.com/cenkalti/backoff/v5 v5.0.3 // indirect @@ -129,7 +132,7 @@ require ( github.com/kong/semver/v4 v4.0.1 // indirect github.com/kylelemons/godebug v1.1.0 // indirect github.com/leodido/go-urn v1.4.0 // indirect - github.com/linode/linodego v1.67.0 // indirect + github.com/linode/linodego v1.69.1 // indirect github.com/magefile/mage v1.17.2 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect @@ -152,7 +155,7 @@ require ( github.com/tidwall/gjson v1.18.0 // indirect github.com/tidwall/match v1.2.0 // indirect github.com/tidwall/pretty v1.2.1 // indirect - github.com/vultr/govultr/v3 v3.30.0 // indirect + github.com/vultr/govultr/v3 v3.31.2 // indirect github.com/x448/float16 v0.8.4 // indirect go.mongodb.org/mongo-driver v1.17.9 // indirect go.uber.org/ratelimit v0.3.1 // indirect @@ -173,7 +176,7 @@ require ( require ( github.com/BurntSushi/toml v1.6.0 // indirect - github.com/alexbrainman/sspi v0.0.0-20180613141037-e580b900e9f5 // indirect + github.com/alexbrainman/sspi v0.0.0-20250919150558-7d374ff0d59e // indirect github.com/alibabacloud-go/alibabacloud-gateway-spi v0.0.5 // indirect github.com/alibabacloud-go/debug v1.0.1 // indirect github.com/alibabacloud-go/endpoint-util v1.1.1 // indirect @@ -191,7 +194,8 @@ require ( github.com/aws/aws-sdk-go-v2/service/sts v1.42.1 // indirect github.com/aws/smithy-go v1.25.1 // indirect github.com/aymerick/douceur v0.2.0 // indirect - github.com/bodgit/tsig v1.2.2 // indirect + github.com/bodgit/gssapi v0.0.3 // indirect + github.com/bodgit/tsig v1.3.1 // indirect github.com/boombuler/barcode v1.1.0 // indirect github.com/cenkalti/backoff/v4 v4.3.0 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect @@ -250,23 +254,21 @@ require ( github.com/nrdcg/namesilo v0.5.0 // indirect github.com/openshift/gssapi v0.0.0-20161010215902-5fb4217df13b // indirect github.com/philhofer/fwd v1.2.0 // indirect - github.com/pkg/errors v0.9.1 // indirect github.com/rs/xid v1.6.0 // indirect + github.com/spf13/afero v1.15.0 // indirect github.com/spf13/cast v1.10.0 // indirect github.com/tinylib/msgp v1.6.4 // indirect github.com/tjfoc/gmsm v1.4.1 // indirect github.com/zeebo/xxh3 v1.1.0 // indirect - github.com/zenlayer/zenlayercloud-sdk-go v0.2.33 // indirect golang.org/x/image v0.40.0 // indirect - golang.org/x/mod v0.35.0 // indirect - golang.org/x/net v0.54.0 // indirect + golang.org/x/mod v0.36.0 // indirect + golang.org/x/net v0.55.0 // indirect golang.org/x/oauth2 v0.36.0 // indirect golang.org/x/term v0.43.0 // indirect golang.org/x/text v0.37.0 // indirect golang.org/x/time v0.15.0 // indirect golang.org/x/tools v0.44.0 // indirect - google.golang.org/protobuf v1.36.11 // indirect - gopkg.in/ini.v1 v1.67.1 // indirect + gopkg.in/ini.v1 v1.67.2 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect modernc.org/libc v1.72.3 // indirect modernc.org/mathutil v1.7.1 // indirect diff --git a/go.sum b/go.sum index 69581bd21..79e924963 100644 --- a/go.sum +++ b/go.sum @@ -33,7 +33,6 @@ cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9 dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= -github.com/Azure/azure-sdk-for-go v68.0.0+incompatible h1:fcYLmCpyNYRnvJbPerq7U0hS+6+I79yEDJBqVNcqUzU= github.com/Azure/azure-sdk-for-go/sdk/azcore v1.21.1 h1:jHb/wfvRikGdxMXYV3QG/SzUOPYN9KEUUuC0Yd0/vC0= github.com/Azure/azure-sdk-for-go/sdk/azcore v1.21.1/go.mod h1:pzBXCYn05zvYIrwLgtK8Ap8QcjRg+0i76tMQdWN6wOk= github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.13.1 h1:Hk5QBxZQC1jb2Fwj6mpzme37xbCDdNTxU7O9eb5+LB4= @@ -87,8 +86,8 @@ github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuy github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= -github.com/alexbrainman/sspi v0.0.0-20180613141037-e580b900e9f5 h1:P5U+E4x5OkVEKQDklVPmzs71WM56RTTRqV4OrDC//Y4= -github.com/alexbrainman/sspi v0.0.0-20180613141037-e580b900e9f5/go.mod h1:976q2ETgjT2snVCf2ZaBnyBbVoPERGjUz+0sofzEfro= +github.com/alexbrainman/sspi v0.0.0-20250919150558-7d374ff0d59e h1:4dAU9FXIyQktpoUAgOJK3OTFc/xug0PCXYCqU0FgDKI= +github.com/alexbrainman/sspi v0.0.0-20250919150558-7d374ff0d59e/go.mod h1:cEWa1LVoE5KvSD9ONXsZrj0z6KqySlCCNKHlLzbqAt4= github.com/alibabacloud-go/alb-20200616/v2 v2.3.1 h1:IYWpYnBpRUY35vA0/Qxedqwkl2oMlwFf7UhibbUXkEE= github.com/alibabacloud-go/alb-20200616/v2 v2.3.1/go.mod h1:pUTnSOSknoHg5YtAmGrXuO+JcPlb+EYRNutf5VbW/F0= github.com/alibabacloud-go/alibabacloud-gateway-fc-util v0.0.7 h1:RDatRb9RG39HjkevgzTeiVoDDaamoB+12GHNairp3Ag= @@ -225,8 +224,8 @@ github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.23 h1:pbrxO/ku github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.23/go.mod h1:/CMNUqoj46HpS3MNRDEDIwcgEnrtZlKRaHNaHxIFpNA= github.com/aws/aws-sdk-go-v2/service/lightsail v1.54.0 h1:07DKnL5eKSel3XEM2UxlD/z9zUZZ6XMHLGDXkAdY4u8= github.com/aws/aws-sdk-go-v2/service/lightsail v1.54.0/go.mod h1:Etcg8xorq1b0g0V2KMNgFjubYITZseJv08qtX/3szko= -github.com/aws/aws-sdk-go-v2/service/route53 v1.62.5 h1:Z+/OLsb85Kpq7TVLCspskqePaf68Tdv6GfmJP4kH6i0= -github.com/aws/aws-sdk-go-v2/service/route53 v1.62.5/go.mod h1:TmxGowuBYwjmHFOsEDxaZdsQE62JJzOmtiWafTi/czg= +github.com/aws/aws-sdk-go-v2/service/route53 v1.62.7 h1:twRRMmtSITnt/rrp+D7UDLzE5pKMZe759aalkUdN+OY= +github.com/aws/aws-sdk-go-v2/service/route53 v1.62.7/go.mod h1:ztM1lr+sRoCAI8336ZUvlRPbToue0d3gE/wd6jomSJ8= github.com/aws/aws-sdk-go-v2/service/signin v1.0.11 h1:TdJ+HdzOBhU8+iVAOGUTU63VXopcumCOF1paFulHWZc= github.com/aws/aws-sdk-go-v2/service/signin v1.0.11/go.mod h1:R82ZRExE/nheo0N+T8zHPcLRTcH8MGsnR3BiVGX0TwI= github.com/aws/aws-sdk-go-v2/service/sso v1.30.17 h1:7byT8HUWrgoRp6sXjxtZwgOKfhss5fW6SkLBtqzgRoE= @@ -249,8 +248,10 @@ github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24 github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= -github.com/bodgit/tsig v1.2.2 h1:RgxTCr8UFUHyU4D8Ygb2UtXtS4niw4B6XYYBpgCjl0k= -github.com/bodgit/tsig v1.2.2/go.mod h1:rIGNOLZOV/UA03fmCUtEFbpWOrIoaOuETkpaeTvnLF4= +github.com/bodgit/gssapi v0.0.3 h1:CtNl14kFo6aQE4tld//yBZ4xgJIPW32YxlOob0TG1y8= +github.com/bodgit/gssapi v0.0.3/go.mod h1:DXyzvSyncJX6mT8WYYWYGzO/SrT+ijMi1ebfQHsWMNo= +github.com/bodgit/tsig v1.3.1 h1:wvyR60AWCH0wdJiloB9dPfg8M3NV42HGW8dce3Z0GDE= +github.com/bodgit/tsig v1.3.1/go.mod h1:Ez+xu0W5Ew/D28XqthucLOX8k9A0UGVPETvagYxbIHU= github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8= github.com/boombuler/barcode v1.1.0 h1:ChaYjBR63fr4LFyGn8E8nt7dBSt3MiU3zMOZqFvVkHo= github.com/boombuler/barcode v1.1.0/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8= @@ -313,7 +314,6 @@ github.com/elliotwutingfeng/asciiset v0.0.0-20260129054604-cfde2086bc57 h1:x5yxN github.com/elliotwutingfeng/asciiset v0.0.0-20260129054604-cfde2086bc57/go.mod h1:GLo/8fDswSAniFG+BFIaiSPcK610jyzgEhWYPQwuQdw= github.com/emicklei/go-restful/v3 v3.13.0 h1:C4Bl2xDndpU6nJ4bc1jXd+uTmYPVUwkD6bFY/oTyCes= github.com/emicklei/go-restful/v3 v3.13.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= -github.com/enceve/crypto v0.0.0-20160707101852-34d48bb93815/go.mod h1:wYFFK4LYXbX7j+76mOq7aiC/EAw2S22CrzPHqgsisPw= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= @@ -351,8 +351,8 @@ github.com/go-acme/esa-20240910/v2 v2.48.0 h1:muSDyhjDTejxUGe3FTthCPCqRaEdYY9cG3 github.com/go-acme/esa-20240910/v2 v2.48.0/go.mod h1:shPb6hzc1rJL15IJBY8HQ4GZk4E8RC52+52twutEwIg= github.com/go-acme/jdcloud-sdk-go v1.64.0 h1:AW9j5khk8tRYbpBJPxKmqdwIqgLs2Fz3HUK3hn2YXjs= github.com/go-acme/jdcloud-sdk-go v1.64.0/go.mod h1:qc/m8HNX1Zgd7GAv2DSEinup8fwy3Ted3/VVx7LB5bU= -github.com/go-acme/lego/v4 v4.34.0 h1:oRsIuPJ4ORX7ufviXvelUpBSez2XxeKGwo5pNG9BVeY= -github.com/go-acme/lego/v4 v4.34.0/go.mod h1:gsmdlx/ZS6OUeXbOj0U+VnCLLfEFj4WCYRkcGpZw+pc= +github.com/go-acme/lego/v5 v5.1.0 h1:8JvnoRgH6uyFENTKS+3+JXdobpo4jYGfj4Bs4izVwmk= +github.com/go-acme/lego/v5 v5.1.0/go.mod h1:oCmaeLjpcqHmB1JGqGzsAjCMXXCPbDpNCckYv6J47m4= github.com/go-acme/tencentclouddnspod v1.3.24 h1:uCSiOW1EJttcnOON+MVVyVDJguFL/Q4NIGkq1CrT9p8= github.com/go-acme/tencentclouddnspod v1.3.24/go.mod h1:RKcB2wSoZncjBA0OEFj59s1ko1XDy+ZsAtk+9uMxUF0= github.com/go-acme/tencentedgdeone v1.3.38 h1:5YsVl0H4A+cwtiUqR1eZbKFdr4OWfYp2KYJopifzKyQ= @@ -375,7 +375,6 @@ github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9 github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= -github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-openapi/jsonpointer v0.22.5 h1:8on/0Yp4uTb9f4XvTrM2+1CPrV05QPZXu+rvu2o9jcA= @@ -584,8 +583,8 @@ github.com/hashicorp/mdns v1.0.1/go.mod h1:4gW7WsVCke5TE7EPeYliwHlRUyBtfCwuFwuMg github.com/hashicorp/memberlist v0.2.2/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE= github.com/hashicorp/serf v0.9.5/go.mod h1:UWDWwZeL5cuWDJdl0C6wrvrUwEqtQ4ZKBKKENpqIUyk= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= -github.com/huaweicloud/huaweicloud-sdk-go-v3 v0.1.195 h1:DFdcGWtp9htuXqVjhogF/twgrzJ5qbvzAONXzN+lkMw= -github.com/huaweicloud/huaweicloud-sdk-go-v3 v0.1.195/go.mod h1:M+yna96Fx9o5GbIUnF3OvVvQGjgfVSyeJbV9Yb1z/wI= +github.com/huaweicloud/huaweicloud-sdk-go-v3 v0.1.197 h1:3UKTBHggGG3nDQXbUjFdwOy7LGGz+liuxp4aXBxWSRU= +github.com/huaweicloud/huaweicloud-sdk-go-v3 v0.1.197/go.mod h1:M+yna96Fx9o5GbIUnF3OvVvQGjgfVSyeJbV9Yb1z/wI= github.com/hudl/fargo v1.4.0/go.mod h1:9Ai6uvFy5fQNq6VPKtg+Ceq1+eTY4nKUlR2JElEOcDo= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4= @@ -605,14 +604,12 @@ github.com/jcmturner/gofork v1.7.6/go.mod h1:1622LH6i/EZqLloHfE7IeZ0uEJwMSUyQ/nD github.com/jcmturner/goidentity/v6 v6.0.1 h1:VKnZd2oEIMorCTsFBnJWbExfNN7yZr3EhJAxwOkZg6o= github.com/jcmturner/goidentity/v6 v6.0.1/go.mod h1:X1YW3bgtvwAXju7V3LCIMpY0Gbxyjn/mY9zx4tFonSg= github.com/jcmturner/gokrb5/v8 v8.4.2/go.mod h1:sb+Xq/fTY5yktf/VxLsE3wlfPqQjp0aWNYyvBVK62bc= -github.com/jcmturner/gokrb5/v8 v8.4.3/go.mod h1:dqRwJGXznQrzw6cWmyo6kH+E7jksEQG/CyVWsJEsJO0= github.com/jcmturner/gokrb5/v8 v8.4.4 h1:x1Sv4HaTpepFkXbt2IkL29DXRf8sOfZXo8eRKh687T8= github.com/jcmturner/gokrb5/v8 v8.4.4/go.mod h1:1btQEpgT6k+unzCwX1KdWMEwPPkkgBtP+F6aCACiMrs= github.com/jcmturner/rpc/v2 v2.0.3 h1:7FXXj8Ti1IaVFpSAziCZWNzbNuZmnvw/i6CqLNdWfZY= github.com/jcmturner/rpc/v2 v2.0.3/go.mod h1:VUJYCIDm3PVOEHw8sgt091/20OJjskO/YJki3ELg/Hc= github.com/jdcloud-api/jdcloud-sdk-go v1.64.0 h1:xZc/ZRcrOhDx9Ra9htu6ui2gUUttmLsXIqH61LcvY4U= github.com/jdcloud-api/jdcloud-sdk-go v1.64.0/go.mod h1:UrKjuULIWLjHFlG6aSPunArE5QX57LftMmStAZJBEX8= -github.com/jinzhu/copier v0.3.5/go.mod h1:DfbEm0FYsaqBcKcFuvmOZb218JkPGtvSHsKg8S8hyyg= github.com/jinzhu/copier v0.4.0 h1:w3ciUoD19shMCRargcpm0cm91ytaBhDvuRpz1ODO/U8= github.com/jinzhu/copier v0.4.0/go.mod h1:DfbEm0FYsaqBcKcFuvmOZb218JkPGtvSHsKg8S8hyyg= github.com/jlaffaye/ftp v0.2.0 h1:lXNvW7cBu7R/68bknOX3MrRIIqZ61zELs1P2RAiA3lg= @@ -672,8 +669,8 @@ github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+ github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= -github.com/linode/linodego v1.67.0 h1:pomhFuuCCJI4N6emtB9027h1yXHY2/MIT0hwHEFwvq4= -github.com/linode/linodego v1.67.0/go.mod h1:+9mbdu0P3WMRCl0QbVfiFavR+Iel7TCRDJk3nInyx14= +github.com/linode/linodego v1.69.1 h1:f45N2MHR/oece2/ktTTCYmrlfse4//k3NgwcF5zbGZ0= +github.com/linode/linodego v1.69.1/go.mod h1:Fha0NYsQSx5VZK1HQNJY/z/dIxxkFp+vb5veawbmAUw= github.com/luthermonson/go-proxmox v0.5.0 h1:15/ZaoNXeBtpE31ZZ5kSY5XnlMNcCJmbTteEXxPLS4o= github.com/luthermonson/go-proxmox v0.5.0/go.mod h1:/mrMokmcU1lcWiWJFCPDO5nzcxpo8h0PEfcmY/ERZmA= github.com/magefile/mage v1.17.2 h1:fyXVu1eadI8Ap1HCCNgEhJ5McIWiYhLR8uol64ZZc40= @@ -700,7 +697,6 @@ github.com/microcosm-cc/bluemonday v1.0.27/go.mod h1:jFi9vgW+H7c3V0lb6nR74Ib/DIB github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso= github.com/miekg/dns v1.1.43/go.mod h1:+evo5L0630/F6ca/Z9+GAqzhjGyn8/c+TBaOyfEl0V4= -github.com/miekg/dns v1.1.50/go.mod h1:e3IlAVfNqAllflbibAZEWOXOQ+Ynzk/dDozDxY7XnME= github.com/miekg/dns v1.1.72 h1:vhmr+TF2A3tuoGNkLDFK9zi36F2LS+hKTRW0Uf8kbzI= github.com/miekg/dns v1.1.72/go.mod h1:+EuEPhdHOsfk6Wk5TT2CzssZdqkmFhf8r+aVyDEToIs= github.com/minio/crc64nvme v1.1.1 h1:8dwx/Pz49suywbO+auHCBpCtlW1OfpcLN7wYgVR6wAI= @@ -804,8 +800,6 @@ github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRI github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pocketbase/dbx v1.12.0 h1:/oLErM+A0b4xI0PWTGPqSDVjzix48PqI/bng2l0PzoA= github.com/pocketbase/dbx v1.12.0/go.mod h1:xXRCIAKTHMgUCyCKZm55pUOdvFziJjQfXaWKhu2vhMs= -github.com/pocketbase/pocketbase v0.38.0 h1:EwZiOpu2RwJ7O0d0+W+rUAGeXvBhH6zpZOX37wFB830= -github.com/pocketbase/pocketbase v0.38.0/go.mod h1:gxdfarbZ4gT/ivRNiIa7uJ1a64eY8yncW+NyvA31aLk= github.com/pocketbase/pocketbase v0.38.1 h1:wNFm9Nw18D/6hZP5Q+Biz1LSz3bkcFmfb318GoJ/UXo= github.com/pocketbase/pocketbase v0.38.1/go.mod h1:j2+DlxYqUanERfruYvkBDMKOASfRJUrQKMJdscmookA= github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= @@ -872,6 +866,8 @@ github.com/smartystreets/assertions v1.1.0/go.mod h1:tcbTF8ujkAEcZ8TElKY+i30BzYl github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +github.com/spf13/afero v1.15.0 h1:b/YBCLWAJdFWJTN9cLhiXXcD7mzKn9Dm86dNnfyQw1I= +github.com/spf13/afero v1.15.0/go.mod h1:NC2ByUVxtQs4b3sIUphxK0NioZnmxgyCrfzeuq8lxMg= github.com/spf13/cast v1.10.0 h1:h2x0u2shc1QuLHfxi+cTJvs30+ZAHOGRic8uyGTDWxY= github.com/spf13/cast v1.10.0/go.mod h1:jNfB8QC9IA6ZuY2ZjDp0KtFO2LZZlg4S/7bzP6qqeHo= github.com/spf13/cobra v1.10.2 h1:DMTTonx5m65Ic0GOoRY2c16WCbHxOOw6xxezuLaBpcU= @@ -917,8 +913,8 @@ github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.3.93/go.mod h github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.3.94/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.3.95/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.3.96/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0= -github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.3.97 h1:pohADysUIGHOMXymXnMNyyfJKy0iHjnBHoSQ3GO0UAM= -github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.3.97/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0= +github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.3.102 h1:3n7BpLOPnE9Rv3Y9Jxgl/XaQX3GzktO+dEaAbtVbjSk= +github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.3.102/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/gaap v1.3.34 h1:/QJeztyMC2tYPJceIoObx7LZqqgFcdDM0SQ/Wd0RtEI= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/gaap v1.3.34/go.mod h1:LiTqyLKs+CUdXeiTezJrsMcgi1RhVQ2gFuCcDxQBK9U= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/live v1.3.95 h1:rWiKud64WUq65AenAxjNtXjaf9wbbpitT1xUfnE9kZ4= @@ -947,20 +943,20 @@ github.com/tjfoc/gmsm v1.3.2/go.mod h1:HaUcFuY0auTiaHB9MHFGCPx5IaLhTUd2atbCFBQXn github.com/tjfoc/gmsm v1.4.1 h1:aMe1GlZb+0bLjn+cKTPEvvn9oUEBlJitaZiiBwsbgho= github.com/tjfoc/gmsm v1.4.1/go.mod h1:j4INPkHWMrhJb38G+J6W4Tw0AbuN8Thu3PbdVYhVcTE= github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= -github.com/ucloud/ucloud-sdk-go v0.22.70 h1:EFXJmdWjq38u2k9E8FqLZ3d9EGYwP/wh+YWYHsIsaIQ= -github.com/ucloud/ucloud-sdk-go v0.22.70/go.mod h1:dyLmFHmUfgb4RZKYQP9IArlvQ2pxzFthfhwxRzOEPIw= +github.com/ucloud/ucloud-sdk-go v0.22.73 h1:7PLPhbK0SWdZHy+ohJxsfX+UEtoAO4a+YlL2Es7yB/o= +github.com/ucloud/ucloud-sdk-go v0.22.73/go.mod h1:dyLmFHmUfgb4RZKYQP9IArlvQ2pxzFthfhwxRzOEPIw= github.com/ulikunitz/xz v0.5.15 h1:9DNdB5s+SgV3bQ2ApL10xRc35ck0DuIX/isZvIk+ubY= github.com/ulikunitz/xz v0.5.15/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI= github.com/volcengine/ve-tos-golang-sdk/v2 v2.9.4 h1:PBa2DI7SQT1ur1zXqldbaIgybHid4fx2yjO/l4GyUsg= github.com/volcengine/ve-tos-golang-sdk/v2 v2.9.4/go.mod h1:IrjK84IJJTuOZOTMv/P18Ydjy/x+ow7fF7q11jAxXLM= github.com/volcengine/volc-sdk-golang v1.0.23/go.mod h1:AfG/PZRUkHJ9inETvbjNifTDgut25Wbkm2QoYBTbvyU= -github.com/volcengine/volc-sdk-golang v1.0.246 h1:5paLSGGy4eB31tdgFA0XfPgZNCicoxnm2VaWIqF3YQY= -github.com/volcengine/volc-sdk-golang v1.0.246/go.mod h1:zHJlaqiMbIB+0mcrsZPTwOb3FB7S/0MCfqlnO8R7hlM= +github.com/volcengine/volc-sdk-golang v1.0.248 h1:2XxvADkC9Q3UNxE1/X/QhRB45Ic2z7dbH33jZurwB8I= +github.com/volcengine/volc-sdk-golang v1.0.248/go.mod h1:zHJlaqiMbIB+0mcrsZPTwOb3FB7S/0MCfqlnO8R7hlM= github.com/volcengine/volcengine-go-sdk v1.2.27 h1:azBueeKhhGQukss+ob6m3oJ5K8GGYbfDNj8RKAEXVTE= github.com/volcengine/volcengine-go-sdk v1.2.27/go.mod h1:oxoVo+A17kvkwPkIeIHPVLjSw7EQAm+l/Vau1YGHN+A= -github.com/vultr/govultr/v3 v3.30.0 h1:kTeDJ+5or6g4CQJmD6Kmz4R63B18poNZ8RP87r9LZdg= -github.com/vultr/govultr/v3 v3.30.0/go.mod h1:2zyUw9yADQaGwKnwDesmIOlBNLrm7edsCfWHFJpWKf8= +github.com/vultr/govultr/v3 v3.31.2 h1:2l3/KDvfemG+4azw4LLquJoh9mFOAVEdBXtPPzix3ac= +github.com/vultr/govultr/v3 v3.31.2/go.mod h1:2zyUw9yADQaGwKnwDesmIOlBNLrm7edsCfWHFJpWKf8= github.com/wneessen/go-mail v0.7.3 h1:g3DravXC5SMlVdboFrQA8Jx95A8sOzoBeS5F+vzNRK0= github.com/wneessen/go-mail v0.7.3/go.mod h1:QGhBX0yNbc1J+Mkjcu7z2rpj4B4l+BmDY8gYznPC9sk= github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= @@ -1034,7 +1030,6 @@ golang.org/x/crypto v0.0.0-20210915214749-c084706c2272/go.mod h1:GvvjBRRGRdwPK5y golang.org/x/crypto v0.0.0-20210920023735-84f357641f63/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58= golang.org/x/crypto v0.10.0/go.mod h1:o4eNf7Ede1fv+hwOwZsTHl9EsPFO6q6ZvYR8vYfY45I= golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio= @@ -1045,8 +1040,8 @@ golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDf golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM= -golang.org/x/crypto v0.51.0 h1:IBPXwPfKxY7cWQZ38ZCIRPI50YLeevDLlLnyC5wRGTI= -golang.org/x/crypto v0.51.0/go.mod h1:8AdwkbraGNABw2kOX6YFPs3WM22XqI4EXEd8g+x7Oc8= +golang.org/x/crypto v0.52.0 h1:RMs7fP2rXdep0CftQlK8Uf+kibLm7qkCcradZWYz988= +golang.org/x/crypto v0.52.0/go.mod h1:1QgfPxDqh0T2M/elOJtp9RvuR95kVjir0e6/BvEmGbc= golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -1091,8 +1086,8 @@ golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= -golang.org/x/mod v0.35.0 h1:Ww1D637e6Pg+Zb2KrWfHQUnH2dQRLBQyAtpr/haaJeM= -golang.org/x/mod v0.35.0/go.mod h1:+GwiRhIInF8wPm+4AoT6L0FA1QWAad3OMdTRx4tFYlU= +golang.org/x/mod v0.36.0 h1:JJjpVx6myfUsUdAzZuOSTTmRE0PfZeNWzzvKrP7amb4= +golang.org/x/mod v0.36.0/go.mod h1:moc6ELqsWcOw5Ef3xVprK5ul/MvtVvkIXLziUOICjUQ= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1133,11 +1128,9 @@ golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96b golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210614182718-04defd469f4e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210917221730-978cfadd31cf/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.0.0-20220725212005-46097bf591d3/go.mod h1:AaygXjzTFtRAg2ttMY5RMuhpJ3cNnI0XpyFJD1iQRSM= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= @@ -1150,8 +1143,8 @@ golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE= -golang.org/x/net v0.54.0 h1:2zJIZAxAHV/OHCDTCOHAYehQzLfSXuf/5SoL/Dv6w/w= -golang.org/x/net v0.54.0/go.mod h1:Sj4oj8jK6XmHpBZU/zWHw3BV3abl4Kvi+Ut7cQcY+cQ= +golang.org/x/net v0.55.0 h1:bcvxaJn3e1U6InsFWt1JUq1aSjnRxLzT2rtD2KfkDF8= +golang.org/x/net v0.55.0/go.mod h1:L5U2KuzuOe1lY7Z+aWVIKK6qEeJXnXV9yzGA+WCHJww= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -1255,8 +1248,8 @@ golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.44.0 h1:ildZl3J4uzeKP07r2F++Op7E9B29JRUy+a27EibtBTQ= -golang.org/x/sys v0.44.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= +golang.org/x/sys v0.45.0 h1:dO4czNzziLiiXplLQgBCEpCvXQ3dnkn0SdaZSYdQ+FY= +golang.org/x/sys v0.45.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= @@ -1349,7 +1342,6 @@ golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= @@ -1469,8 +1461,8 @@ gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/ini.v1 v1.56.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/ini.v1 v1.67.1 h1:tVBILHy0R6e4wkYOn3XmiITt/hEVH4TFMYvAX2Ytz6k= -gopkg.in/ini.v1 v1.67.1/go.mod h1:x/cyOwCgZqOkJoDIJ3c1KNHMo10+nLGAhh+kn3Zizss= +gopkg.in/ini.v1 v1.67.2 h1:JtOSMb9OuaCZKr7h5D/h6iii14sK0hLbplTc6frx4Ss= +gopkg.in/ini.v1 v1.67.2/go.mod h1:x/cyOwCgZqOkJoDIJ3c1KNHMo10+nLGAhh+kn3Zizss= gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k= gopkg.in/ns1/ns1-go.v2 v2.17.2 h1:x8YKHqCJWkC/hddfUhw7FRqTG0x3fr/0ZnWYN+i4THs= gopkg.in/ns1/ns1-go.v2 v2.17.2/go.mod h1:pfaU0vECVP7DIOr453z03HXS6dFJpXdNRwOyRzwmPSc= diff --git a/internal/certacme/account.go b/internal/certacme/account.go index 1932b6f2a..cb03b1d85 100644 --- a/internal/certacme/account.go +++ b/internal/certacme/account.go @@ -8,10 +8,12 @@ import ( "fmt" "strings" - "github.com/go-acme/lego/v4/lego" - "github.com/go-acme/lego/v4/registration" + "github.com/go-acme/lego/v5/acme" + "github.com/go-acme/lego/v5/lego" + "github.com/go-acme/lego/v5/registration" "golang.org/x/sync/singleflight" + "github.com/certimate-go/certimate/internal/app" "github.com/certimate-go/certimate/internal/domain" "github.com/certimate-go/certimate/internal/repository" xcert "github.com/certimate-go/certimate/pkg/utils/cert" @@ -21,7 +23,7 @@ var registrationSg singleflight.Group type ACMEAccount = domain.ACMEAccount -func NewACMEAccount(config *ACMEConfig, email string, register bool) (*ACMEAccount, error) { +func CreateACMEAccount(ctx context.Context, config *ACMEConfig, email string) (*ACMEAccount, error) { if config == nil { return nil, fmt.Errorf("the acme config is nil") } @@ -29,7 +31,6 @@ func NewACMEAccount(config *ACMEConfig, email string, register bool) (*ACMEAccou return nil, fmt.Errorf("the email is empty") } - ctx := context.Background() accountRepo := repository.NewACMEAccountRepository() account, err := accountRepo.GetByCAAndEmail(ctx, config.CAProvider.String(), config.CADirUrl, email) if err != nil { @@ -38,12 +39,7 @@ func NewACMEAccount(config *ACMEConfig, email string, register bool) (*ACMEAccou } } - // register new acme account if not exists if account == nil { - if !register { - return nil, fmt.Errorf("the acme account does not exist") - } - key, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) if err != nil { return nil, err @@ -60,16 +56,18 @@ func NewACMEAccount(config *ACMEConfig, email string, register bool) (*ACMEAccou PrivateKey: keyPEM, ACMEDirUrl: config.CADirUrl, } + legoCfg := lego.NewConfig(account) + legoCfg.UserAgent = app.AppUserAgent legoCfg.CADirURL = config.CADirUrl legoClient, err := lego.NewClient(legoCfg) if err != nil { return nil, err } - var regres *registration.Resource + var regres *acme.ExtendedAccount var regerr error - if legoClient.GetExternalAccountRequired() { + if legoClient.GetServerMetadata().ExternalAccountRequired { if config.EABKid == "" { return nil, fmt.Errorf("missing or invalid eab kid") } @@ -83,13 +81,13 @@ func NewACMEAccount(config *ACMEConfig, email string, register bool) (*ACMEAccou keyEncoded = strings.ReplaceAll(strings.ReplaceAll(keyEncoded, "+", "-"), "/", "_") keyEncoded = strings.TrimSuffix(keyEncoded, "=") - regres, regerr = legoClient.Registration.RegisterWithExternalAccountBinding(registration.RegisterEABOptions{ + regres, regerr = legoClient.Registration.RegisterWithExternalAccountBinding(ctx, registration.RegisterEABOptions{ TermsOfServiceAgreed: true, Kid: keyId, HmacEncoded: keyEncoded, }) } else { - regres, regerr = legoClient.Registration.Register(registration.RegisterOptions{ + regres, regerr = legoClient.Registration.Register(ctx, registration.RegisterOptions{ TermsOfServiceAgreed: true, }) } @@ -97,8 +95,8 @@ func NewACMEAccount(config *ACMEConfig, email string, register bool) (*ACMEAccou return nil, fmt.Errorf("failed to register acme account: %w", regerr) } - account.ACMEAccount = ®res.Body - account.ACMEAcctUrl = regres.URI + account.ACMEAcctUrl = regres.Location + account.ACMEAccount = ®res.Account if _, err := accountRepo.Save(ctx, account); err != nil { return nil, fmt.Errorf("failed to save acme account record: %w", err) @@ -108,7 +106,7 @@ func NewACMEAccount(config *ACMEConfig, email string, register bool) (*ACMEAccou return account, nil } -func NewACMEAccountWithSingleFlight(config *ACMEConfig, email string) (*ACMEAccount, error) { +func CreateACMEAccountWithSingleFlight(ctx context.Context, config *ACMEConfig, email string) (*ACMEAccount, error) { if config == nil { return nil, fmt.Errorf("the acme config is nil") } @@ -116,8 +114,9 @@ func NewACMEAccountWithSingleFlight(config *ACMEConfig, email string) (*ACMEAcco return nil, fmt.Errorf("the email is empty") } - resp, err, _ := registrationSg.Do(fmt.Sprintf("%s|%s|%s", config.CAProvider, config.CADirUrl, email), func() (any, error) { - return NewACMEAccount(config, email, true) + key := fmt.Sprintf("%s|%s|%s", config.CAProvider, config.CADirUrl, email) + resp, err, _ := registrationSg.Do(key, func() (any, error) { + return CreateACMEAccount(ctx, config, email) }) if err != nil { return nil, err diff --git a/internal/certacme/ca.go b/internal/certacme/ca.go new file mode 100644 index 000000000..59069decb --- /dev/null +++ b/internal/certacme/ca.go @@ -0,0 +1,70 @@ +package certacme + +import ( + "fmt" + "strings" + + "github.com/certimate-go/certimate/internal/domain" + xmaps "github.com/certimate-go/certimate/pkg/utils/maps" +) + +var caDirUrls = map[string]string{ + domain.CAProviderTypeLetsEncrypt.String(): "https://acme-v02.api.letsencrypt.org/directory", + domain.CAProviderTypeLetsEncryptStaging.String(): "https://acme-staging-v02.api.letsencrypt.org/directory", + domain.CAProviderTypeActalisSSL.String(): "https://acme-api.actalis.com/acme/directory", + domain.CAProviderTypeDigiCert.String(): "https://acme.digicert.com/v2/acme/directory", + domain.CAProviderTypeGlobalSignAtlas.String(): "https://emea.acme.atlas.globalsign.com/directory", + domain.CAProviderTypeGoogleTrustServices.String(): "https://dv.acme-v02.api.pki.goog/directory", + domain.CAProviderTypeLiteSSL.String(): "https://acme.litessl.com/acme/v2/directory", + domain.CAProviderTypeSSLCom.String(): "https://acme.ssl.com/sslcom-dv-rsa", + domain.CAProviderTypeSSLCom.String() + "RSA": "https://acme.ssl.com/sslcom-dv-rsa", + domain.CAProviderTypeSSLCom.String() + "ECC": "https://acme.ssl.com/sslcom-dv-ecc", + domain.CAProviderTypeSectigo.String(): "https://acme.sectigo.com/v2/DV", + domain.CAProviderTypeSectigo.String() + "DV": "https://acme.sectigo.com/v2/DV", + domain.CAProviderTypeSectigo.String() + "OV": "https://acme.sectigo.com/v2/OV", + domain.CAProviderTypeSectigo.String() + "EV": "https://acme.sectigo.com/v2/EV", + domain.CAProviderTypeZeroSSL.String(): "https://acme.zerossl.com/v2/DV90", +} + +func getCADirUrl(providerType domain.CAProviderType, providerAccessConfig map[string]any, keyAlgorithm domain.CertificateKeyAlgorithmType) (string, error) { + switch providerType { + case domain.CAProviderTypeSectigo: + credentials := &domain.AccessConfigForGlobalSectigo{} + if err := xmaps.Populate(providerAccessConfig, &credentials); err != nil { + return "", err + } else if strings.EqualFold(credentials.ValidationType, "DV") { + return caDirUrls[domain.CAProviderTypeSectigo.String()+"DV"], nil + } else if strings.EqualFold(credentials.ValidationType, "OV") { + return caDirUrls[domain.CAProviderTypeSectigo.String()+"OV"], nil + } else if strings.EqualFold(credentials.ValidationType, "EV") { + return caDirUrls[domain.CAProviderTypeSectigo.String()+"EV"], nil + } else { + return caDirUrls[domain.CAProviderTypeSectigo.String()], nil + } + + case domain.CAProviderTypeSSLCom: + if strings.HasPrefix(keyAlgorithm.String(), "RSA") { + return caDirUrls[domain.CAProviderTypeSSLCom.String()+"RSA"], nil + } else if strings.HasPrefix(keyAlgorithm.String(), "EC") { + return caDirUrls[domain.CAProviderTypeSSLCom.String()+"ECC"], nil + } else { + return caDirUrls[domain.CAProviderTypeSSLCom.String()], nil + } + + case domain.CAProviderTypeACMECA: + credentials := &domain.AccessConfigForACMECA{} + if err := xmaps.Populate(providerAccessConfig, &credentials); err != nil { + return "", err + } else if credentials.Endpoint == "" { + return "", fmt.Errorf("the endpoint of custom ACME CA is empty") + } + return credentials.Endpoint, nil + + default: + endpoint := caDirUrls[providerType.String()] + if endpoint == "" { + return "", fmt.Errorf("the endpoint of the ACME CA provider is empty") + } + return endpoint, nil + } +} diff --git a/internal/certacme/client.go b/internal/certacme/client.go index d8fa38163..ff4055eaf 100644 --- a/internal/certacme/client.go +++ b/internal/certacme/client.go @@ -4,11 +4,10 @@ import ( "context" "errors" "fmt" - "time" - "github.com/certimate-go/certimate/internal/domain" - "github.com/certimate-go/certimate/internal/repository" - "github.com/go-acme/lego/v4/lego" + "github.com/go-acme/lego/v5/lego" + + "github.com/certimate-go/certimate/internal/app" ) type ACMEClient struct { @@ -16,8 +15,9 @@ type ACMEClient struct { account *ACMEAccount } +// Deprecated: use [NewACMEClientWithAccount] instead. func NewACMEClient(config *ACMEConfig, email string, configures ...func(*lego.Config) error) (*ACMEClient, error) { - account, err := NewACMEAccountWithSingleFlight(config, email) + account, err := CreateACMEAccountWithSingleFlight(context.Background(), config, email) if err != nil { return nil, err } @@ -25,7 +25,6 @@ func NewACMEClient(config *ACMEConfig, email string, configures ...func(*lego.Co mergedConfigures := []func(*lego.Config) error{ func(legoCfg *lego.Config) error { legoCfg.CADirURL = config.CADirUrl - legoCfg.Certificate.KeyType = config.CertifierKeyType return nil }, } @@ -43,18 +42,9 @@ func newACMEClientWithAccount(account *ACMEAccount, configures ...func(*lego.Con } legoCfg := lego.NewConfig(account) + legoCfg.UserAgent = app.AppUserAgent legoCfg.CADirURL = account.ACMEDirUrl - // TODO: fix this after migrate lego to v5 - settingsRepo := repository.NewSettingsRepository() - settings, _ := settingsRepo.GetByName(context.Background(), domain.SettingsNameSSLProvider) - if settings != nil { - sslProviderSettings := settings.Content.AsSSLProvider() - if sslProviderSettings.Timeout > 0 { - legoCfg.Certificate.Timeout = time.Duration(sslProviderSettings.Timeout) * time.Second - } - } - errs := make([]error, 0) for _, configure := range configures { if err := configure(legoCfg); err != nil { diff --git a/internal/certacme/client_obtain.go b/internal/certacme/client_obtain.go index 3f46f8eab..3a75831d8 100644 --- a/internal/certacme/client_obtain.go +++ b/internal/certacme/client_obtain.go @@ -10,12 +10,12 @@ import ( "strings" "time" - "github.com/go-acme/lego/v4/acme" - "github.com/go-acme/lego/v4/certcrypto" - "github.com/go-acme/lego/v4/certificate" - "github.com/go-acme/lego/v4/challenge/dns01" - "github.com/go-acme/lego/v4/challenge/http01" - "github.com/go-acme/lego/v4/log" + "github.com/go-acme/lego/v5/acme" + "github.com/go-acme/lego/v5/certcrypto" + "github.com/go-acme/lego/v5/certificate" + "github.com/go-acme/lego/v5/challenge/dns01" + "github.com/go-acme/lego/v5/challenge/http01" + "github.com/go-acme/lego/v5/log" "github.com/samber/lo" "github.com/certimate-go/certimate/internal/certacme/certifiers" @@ -32,7 +32,7 @@ type ObtainCertificateRequest struct { // 提供商相关 ChallengeType string - Provider string + Provider domain.ACMEChallengeProviderType ProviderAccessConfig map[string]any ProviderExtendedConfig map[string]any @@ -68,35 +68,16 @@ type ObtainCertificateResponse struct { } func (c *ACMEClient) ObtainCertificate(ctx context.Context, request *ObtainCertificateRequest) (*ObtainCertificateResponse, error) { - type result struct { - res *ObtainCertificateResponse - err error - } - - done := make(chan result, 1) - - go func() { - res, err := c.sendObtainCertificateRequest(request) - done <- result{res, err} - }() - - select { - case <-ctx.Done(): - return nil, ctx.Err() - case r := <-done: - return r.res, r.err - } -} - -func (c *ACMEClient) sendObtainCertificateRequest(request *ObtainCertificateRequest) (*ObtainCertificateResponse, error) { if request == nil { return nil, fmt.Errorf("the request is nil") } os.Setenv("LEGO_DISABLE_CNAME_SUPPORT", strconv.FormatBool(request.DisableFollowCNAME)) - switch request.ChallengeType { - case "dns-01": + const CHALLENGE_TYPE_DNS01 = "dns-01" + const CHALLENGE_TYPE_HTTP01 = "http-01" + switch strings.ToLower(request.ChallengeType) { + case CHALLENGE_TYPE_DNS01: { providerFactory, err := certifiers.ACMEDns01Registries.Get(domain.ACMEDns01ProviderType(request.Provider)) if err != nil { @@ -113,23 +94,22 @@ func (c *ACMEClient) sendObtainCertificateRequest(request *ObtainCertificateRequ return nil, fmt.Errorf("failed to initialize dns-01 provider '%s': %w", request.Provider, err) } + opts := &dns01.Options{} + opts.RecursiveNameservers = request.Nameservers + dns01.SetDefaultClient(dns01.NewClient(opts)) c.client.Challenge.SetDNS01Provider(provider, - dns01.CondOption( - len(request.Nameservers) > 0, - dns01.AddRecursiveNameservers(dns01.ParseNameservers(request.Nameservers)), - ), - dns01.CondOption( + dns01.CondOptions( request.DnsPropagationWait > 0, dns01.PropagationWait(time.Duration(request.DnsPropagationWait)*time.Second, true), ), - dns01.CondOption( + dns01.CondOptions( len(request.Nameservers) > 0 || request.DnsPropagationWait > 0, dns01.DisableAuthoritativeNssPropagationRequirement(), ), ) } - case "http-01": + case CHALLENGE_TYPE_HTTP01: { providerFactory, err := certifiers.ACMEHttp01Registries.Get(domain.ACMEHttp01ProviderType(request.Provider)) if err != nil { @@ -153,7 +133,7 @@ func (c *ACMEClient) sendObtainCertificateRequest(request *ObtainCertificateRequ return nil, fmt.Errorf("unsupported challenge type: '%s'", request.ChallengeType) } - var privkey crypto.PrivateKey + var privkey crypto.Signer if request.PrivateKeyPEM != "" { pk, err := certcrypto.ParsePEMPrivateKey([]byte(request.PrivateKeyPEM)) if err != nil { @@ -164,27 +144,29 @@ func (c *ACMEClient) sendObtainCertificateRequest(request *ObtainCertificateRequ } req := certificate.ObtainRequest{ - Domains: request.DomainOrIPs, - PrivateKey: privkey, - Bundle: true, - PreferredChain: request.PreferredChain, - Profile: request.ACMEProfile, - NotBefore: request.ValidityNotBefore, - NotAfter: request.ValidityNotAfter, - ReplacesCertID: lo.If(request.ARIReplacesAcctUrl == c.account.ACMEAcctUrl, request.ARIReplacesCertId).Else(""), + Domains: request.DomainOrIPs, + KeyType: request.PrivateKeyType, + PrivateKey: privkey, + Bundle: true, + EnableCommonName: !request.NoCommonName, + PreferredChain: request.PreferredChain, + Profile: request.ACMEProfile, + NotBefore: request.ValidityNotBefore, + NotAfter: request.ValidityNotAfter, + ReplacesCertID: lo.If(request.ARIReplacesAcctUrl == c.account.ACMEAcctUrl, request.ARIReplacesCertId).Else(""), } - resp, err := c.client.Certificate.Obtain(req) + resp, err := c.client.Certificate.Obtain(ctx, req) if err != nil { ariErr := &acme.AlreadyReplacedError{} if !errors.As(err, &ariErr) { return nil, err } - log.Warnf("the certificate has already been replaced, try to obtain again without ARI ...") + log.Warn("the certificate has already been replaced, try to obtain again without ARI ...") // reset ARI and retry if failure req.ReplacesCertID = "" - resp, err = c.client.Certificate.Obtain(req) + resp, err = c.client.Certificate.Obtain(ctx, req) if err != nil { return nil, err } diff --git a/internal/certacme/client_revoke.go b/internal/certacme/client_revoke.go index 380392610..543c683f0 100644 --- a/internal/certacme/client_revoke.go +++ b/internal/certacme/client_revoke.go @@ -12,32 +12,11 @@ type RevokeCertificateRequest struct { type RevokeCertificateResponse struct{} func (c *ACMEClient) RevokeCertificate(ctx context.Context, request *RevokeCertificateRequest) (*RevokeCertificateResponse, error) { - type result struct { - res *RevokeCertificateResponse - err error - } - - done := make(chan result, 1) - - go func() { - res, err := c.sendRevokeCertificateRequest(request) - done <- result{res, err} - }() - - select { - case <-ctx.Done(): - return nil, ctx.Err() - case r := <-done: - return r.res, r.err - } -} - -func (c *ACMEClient) sendRevokeCertificateRequest(request *RevokeCertificateRequest) (*RevokeCertificateResponse, error) { if request == nil { return nil, fmt.Errorf("the request is nil") } - err := c.client.Certificate.Revoke([]byte(request.Certificate)) + err := c.client.Certificate.Revoke(ctx, []byte(request.Certificate)) if err != nil { return nil, err } diff --git a/internal/certacme/config.go b/internal/certacme/config.go index f72f2a8c5..03e8a2afc 100644 --- a/internal/certacme/config.go +++ b/internal/certacme/config.go @@ -3,124 +3,65 @@ package certacme import ( "context" "fmt" - "strings" - - "github.com/go-acme/lego/v4/certcrypto" "github.com/certimate-go/certimate/internal/domain" "github.com/certimate-go/certimate/internal/repository" xmaps "github.com/certimate-go/certimate/pkg/utils/maps" ) -var acmeDirUrls = map[string]string{ - string(domain.CAProviderTypeLetsEncrypt): "https://acme-v02.api.letsencrypt.org/directory", - string(domain.CAProviderTypeLetsEncryptStaging): "https://acme-staging-v02.api.letsencrypt.org/directory", - string(domain.CAProviderTypeActalisSSL): "https://acme-api.actalis.com/acme/directory", - string(domain.CAProviderTypeDigiCert): "https://acme.digicert.com/v2/acme/directory", - string(domain.CAProviderTypeGlobalSignAtlas): "https://emea.acme.atlas.globalsign.com/directory", - string(domain.CAProviderTypeGoogleTrustServices): "https://dv.acme-v02.api.pki.goog/directory", - string(domain.CAProviderTypeLiteSSL): "https://acme.litessl.com/acme/v2/directory", - string(domain.CAProviderTypeSSLCom): "https://acme.ssl.com/sslcom-dv-rsa", - string(domain.CAProviderTypeSSLCom) + "RSA": "https://acme.ssl.com/sslcom-dv-rsa", - string(domain.CAProviderTypeSSLCom) + "ECC": "https://acme.ssl.com/sslcom-dv-ecc", - string(domain.CAProviderTypeSectigo): "https://acme.sectigo.com/v2/DV", - string(domain.CAProviderTypeSectigo) + "DV": "https://acme.sectigo.com/v2/DV", - string(domain.CAProviderTypeSectigo) + "OV": "https://acme.sectigo.com/v2/OV", - string(domain.CAProviderTypeSectigo) + "EV": "https://acme.sectigo.com/v2/EV", - string(domain.CAProviderTypeZeroSSL): "https://acme.zerossl.com/v2/DV90", -} - type ACMEConfigOptions struct { - CAProvider string - CAAccessConfig map[string]any - CAProviderConfig map[string]any - CertifierKeyType certcrypto.KeyType + CAProvider domain.CAProviderType + CAProviderAccessConfig map[string]any + CAProviderExtendedConfig map[string]any + CertifierKeyAlgorithm domain.CertificateKeyAlgorithmType } type ACMEConfig struct { - CAProvider domain.CAProviderType - CADirUrl string - EABKid string - EABHmacKey string - CertifierKeyType certcrypto.KeyType + CAProvider domain.CAProviderType + CADirUrl string + EABKid string + EABHmacKey string } -func NewACMEConfig(options *ACMEConfigOptions) (*ACMEConfig, error) { +func CreateACMEConfig(ctx context.Context, options *ACMEConfigOptions) (*ACMEConfig, error) { if options == nil { return nil, fmt.Errorf("the options is nil") } - caProvider := options.CAProvider - caAccessConfig := options.CAAccessConfig + provider := options.CAProvider + providerAccessCfg := options.CAProviderAccessConfig - if options.CAProvider == "" { + if provider.String() == "" { + // follow global settings + // TODO: decoupling from the repository layer settingsRepo := repository.NewSettingsRepository() - settings, _ := settingsRepo.GetByName(context.Background(), domain.SettingsNameSSLProvider) + settings, _ := settingsRepo.GetByName(ctx, domain.SettingsNameSSLProvider) if settings != nil { sslProviderSettings := settings.Content.AsSSLProvider() - caProvider = sslProviderSettings.Provider.String() - caAccessConfig = sslProviderSettings.Configs[sslProviderSettings.Provider] + provider = sslProviderSettings.Provider + providerAccessCfg = sslProviderSettings.Configs[sslProviderSettings.Provider] } } - if caProvider == "" { + if provider.String() == "" { // default CA: Let's Encrypt - caProvider = domain.AccessProviderTypeLetsEncrypt.String() + provider = domain.CAProviderTypeLetsEncrypt } - if caAccessConfig == nil { - caAccessConfig = make(map[string]any) - } - - ca := &ACMEConfig{CAProvider: domain.CAProviderType(caProvider), CertifierKeyType: options.CertifierKeyType} - switch ca.CAProvider { - case domain.CAProviderTypeSectigo: - credentials := &domain.AccessConfigForGlobalSectigo{} - if err := xmaps.Populate(caAccessConfig, &credentials); err != nil { - return nil, err - } else if strings.EqualFold(credentials.ValidationType, "DV") { - ca.CADirUrl = acmeDirUrls[domain.CAProviderTypeSectigo.String()+"DV"] - } else if strings.EqualFold(credentials.ValidationType, "OV") { - ca.CADirUrl = acmeDirUrls[domain.CAProviderTypeSectigo.String()+"OV"] - } else if strings.EqualFold(credentials.ValidationType, "EV") { - ca.CADirUrl = acmeDirUrls[domain.CAProviderTypeSectigo.String()+"EV"] - } else { - ca.CADirUrl = acmeDirUrls[domain.CAProviderTypeSectigo.String()] - } - - case domain.CAProviderTypeSSLCom: - // TODO: fix this after migrate lego to v5 - if strings.HasPrefix(string(options.CertifierKeyType), "RSA") { - ca.CADirUrl = acmeDirUrls[domain.CAProviderTypeSSLCom.String()+"RSA"] - } else if strings.HasPrefix(string(options.CertifierKeyType), "EC") { - ca.CADirUrl = acmeDirUrls[domain.CAProviderTypeSSLCom.String()+"ECC"] - } else { - ca.CADirUrl = acmeDirUrls[domain.CAProviderTypeSSLCom.String()] - } - - case domain.CAProviderTypeACMECA: - credentials := &domain.AccessConfigForACMECA{} - if err := xmaps.Populate(caAccessConfig, &credentials); err != nil { - return nil, err - } else if credentials.Endpoint == "" { - return nil, fmt.Errorf("the endpoint of custom ACME CA is empty") - } - ca.CADirUrl = credentials.Endpoint - - default: - endpoint := acmeDirUrls[ca.CAProvider.String()] - if endpoint == "" { - return nil, fmt.Errorf("the endpoint of the ACME CA provider is empty") - } - ca.CADirUrl = endpoint - } - - eab := domain.AccessConfigForACMEExternalAccountBinding{} - if err := xmaps.Populate(caAccessConfig, &eab); err != nil { + acmeDirUrl, err := getCADirUrl(provider, providerAccessCfg, options.CertifierKeyAlgorithm) + if err != nil { return nil, err } - ca.EABKid = eab.EabKid - ca.EABHmacKey = eab.EabHmacKey - return ca, nil + acmeEab := domain.AccessConfigForACMEExternalAccountBinding{} + if err := xmaps.Populate(providerAccessCfg, &acmeEab); err != nil { + return nil, err + } + + return &ACMEConfig{ + CAProvider: provider, + CADirUrl: acmeDirUrl, + EABKid: acmeEab.EabKid, + EABHmacKey: acmeEab.EabHmacKey, + }, nil } diff --git a/internal/certacme/logging.go b/internal/certacme/logging.go deleted file mode 100644 index abe50bdaa..000000000 --- a/internal/certacme/logging.go +++ /dev/null @@ -1,61 +0,0 @@ -package certacme - -import ( - "fmt" - "log" - "log/slog" - "os" - "strings" - - legolog "github.com/go-acme/lego/v4/log" -) - -type legoLogger struct { - callLogger *slog.Logger - legoLogger legolog.StdLogger -} - -func (l *legoLogger) Fatal(args ...any) { - l.callLogger.Error("go-acme/lego: " + fmt.Sprint(args...)) - l.legoLogger.Fatal(args...) -} - -func (l *legoLogger) Fatalln(args ...any) { - l.Fatal(fmt.Sprintln(args...)) -} - -func (l *legoLogger) Fatalf(format string, args ...any) { - l.Fatal(fmt.Sprintf(format, args...)) -} - -func (l *legoLogger) Print(args ...any) { - message := fmt.Sprint(args...) - print := l.callLogger.Debug - if strings.HasPrefix(message, "[WARN] ") { - message = strings.TrimPrefix(message, "[WARN] ") - print = l.callLogger.Warn - } else if strings.HasPrefix(message, "[INFO] ") { - message = strings.TrimPrefix(message, "[INFO] ") - print = l.callLogger.Info - } - - print("go-acme/lego: " + message) - l.legoLogger.Print(message) -} - -func (l *legoLogger) Println(args ...any) { - l.Print(fmt.Sprintln(args...)) -} - -func (l *legoLogger) Printf(format string, args ...any) { - l.Print(fmt.Sprintf(format, args...)) -} - -func NewLegoLogger(logger *slog.Logger) legolog.StdLogger { - return &legoLogger{ - callLogger: logger, - - // https://github.com/go-acme/lego/blob/master/log/logger.go - legoLogger: log.New(os.Stderr, "", log.LstdFlags), - } -} diff --git a/internal/certificate/service.go b/internal/certificate/service.go index 28d0cd044..7403e0e3e 100644 --- a/internal/certificate/service.go +++ b/internal/certificate/service.go @@ -240,7 +240,7 @@ func (s *CertificateService) RevokeCertificate(ctx context.Context, req *dtos.Ce return nil, fmt.Errorf("failed to revoke certificate: could not find acme account: %w", err) } - legoClient, err := certacme.NewACMEClientWithAccount(acmeAccount) + acmeClient, err := certacme.NewACMEClientWithAccount(acmeAccount) if err != nil { return nil, fmt.Errorf("failed to revoke certificate: could not initialize acme config: %w", err) } @@ -248,7 +248,7 @@ func (s *CertificateService) RevokeCertificate(ctx context.Context, req *dtos.Ce revokeReq := &certacme.RevokeCertificateRequest{ Certificate: certificate.Certificate, } - _, err = legoClient.RevokeCertificate(ctx, revokeReq) + _, err = acmeClient.RevokeCertificate(ctx, revokeReq) if err != nil { return nil, fmt.Errorf("failed to revoke certificate: %w", err) } diff --git a/internal/certmgmt/client_deploy.go b/internal/certmgmt/client_deploy.go index 8e9bc8dfe..b28c04ef1 100644 --- a/internal/certmgmt/client_deploy.go +++ b/internal/certmgmt/client_deploy.go @@ -10,13 +10,13 @@ import ( type DeployCertificateRequest struct { // 提供商相关 - Provider string + Provider domain.DeploymentProviderType ProviderAccessConfig map[string]any ProviderExtendedConfig map[string]any // 证书相关 - Certificate string - PrivateKey string + CertificatePEM string + PrivateKeyPEM string } type DeployCertificateResponse struct{} @@ -26,7 +26,7 @@ func (c *Client) DeployCertificate(ctx context.Context, request *DeployCertifica return nil, fmt.Errorf("the request is nil") } - providerFactory, err := deployers.Registries.Get(domain.DeploymentProviderType(request.Provider)) + providerFactory, err := deployers.Registries.Get(request.Provider) if err != nil { return nil, err } @@ -40,7 +40,7 @@ func (c *Client) DeployCertificate(ctx context.Context, request *DeployCertifica } provider.SetLogger(c.logger) - if _, err := provider.Deploy(ctx, request.Certificate, request.PrivateKey); err != nil { + if _, err := provider.Deploy(ctx, request.CertificatePEM, request.PrivateKeyPEM); err != nil { return nil, err } diff --git a/internal/domain/acme_account.go b/internal/domain/acme_account.go index 58e25b12e..1a8a402e6 100644 --- a/internal/domain/acme_account.go +++ b/internal/domain/acme_account.go @@ -3,8 +3,7 @@ package domain import ( "crypto" - "github.com/go-acme/lego/v4/acme" - "github.com/go-acme/lego/v4/registration" + "github.com/go-acme/lego/v5/acme" xcert "github.com/certimate-go/certimate/pkg/utils/cert" ) @@ -16,31 +15,31 @@ type ACMEAccount struct { CA string `db:"ca" json:"ca"` Email string `db:"email" json:"email"` PrivateKey string `db:"privateKey" json:"privateKey"` - ACMEAccount *acme.Account `db:"acmeAccount" json:"acmeAccount"` - ACMEAcctUrl string `db:"acmeAcctUrl" json:"acmeAcctUrl"` ACMEDirUrl string `db:"acmeDirUrl" json:"acmeDirUrl"` + ACMEAcctUrl string `db:"acmeAcctUrl" json:"acmeAcctUrl"` + ACMEAccount *acme.Account `db:"acmeAccount" json:"acmeAccount"` } func (a *ACMEAccount) GetEmail() string { return a.Email } -func (a *ACMEAccount) GetRegistration() *registration.Resource { +func (a *ACMEAccount) GetRegistration() *acme.ExtendedAccount { if a.ACMEAccount == nil { return nil } - return ®istration.Resource{ - Body: *a.ACMEAccount, - URI: a.ACMEAcctUrl, + return &acme.ExtendedAccount{ + Account: *a.ACMEAccount, + Location: a.ACMEAcctUrl, } } -func (a *ACMEAccount) GetPrivateKey() crypto.PrivateKey { +func (a *ACMEAccount) GetPrivateKey() crypto.Signer { if a.PrivateKey == "" { return nil } rs, _ := xcert.ParsePrivateKeyFromPEM(a.PrivateKey) - return rs + return rs.(crypto.Signer) } diff --git a/internal/domain/certificate.go b/internal/domain/certificate.go index f4fddb9cb..97a45972a 100644 --- a/internal/domain/certificate.go +++ b/internal/domain/certificate.go @@ -6,7 +6,7 @@ import ( "strings" "time" - "github.com/go-acme/lego/v4/certcrypto" + "github.com/go-acme/lego/v5/certcrypto" xcert "github.com/certimate-go/certimate/pkg/utils/cert" xcertkey "github.com/certimate-go/certimate/pkg/utils/cert/key" @@ -87,37 +87,23 @@ const ( CertificateSourceTypeUpload = CertificateSourceType("upload") ) -type CertificateKeyAlgorithmType string +type CertificateKeyAlgorithmType certcrypto.KeyType func (t CertificateKeyAlgorithmType) String() string { return string(t) } -func (t CertificateKeyAlgorithmType) ToLegoKeyType() (certcrypto.KeyType, error) { - keyTypeMap := map[CertificateKeyAlgorithmType]certcrypto.KeyType{ - CertificateKeyAlgorithmTypeRSA2048: certcrypto.RSA2048, - CertificateKeyAlgorithmTypeRSA3072: certcrypto.RSA3072, - CertificateKeyAlgorithmTypeRSA4096: certcrypto.RSA4096, - CertificateKeyAlgorithmTypeRSA8192: certcrypto.RSA8192, - CertificateKeyAlgorithmTypeEC256: certcrypto.EC256, - CertificateKeyAlgorithmTypeEC384: certcrypto.EC384, - } - - if keyType, ok := keyTypeMap[t]; ok { - return keyType, nil - } - - return certcrypto.RSA2048, fmt.Errorf("unsupported key algorithm type: '%s'", t) +func (t CertificateKeyAlgorithmType) LegoKeyType() certcrypto.KeyType { + return certcrypto.KeyType(t) } const ( - CertificateKeyAlgorithmTypeRSA2048 = CertificateKeyAlgorithmType("RSA2048") - CertificateKeyAlgorithmTypeRSA3072 = CertificateKeyAlgorithmType("RSA3072") - CertificateKeyAlgorithmTypeRSA4096 = CertificateKeyAlgorithmType("RSA4096") - CertificateKeyAlgorithmTypeRSA8192 = CertificateKeyAlgorithmType("RSA8192") - CertificateKeyAlgorithmTypeEC256 = CertificateKeyAlgorithmType("EC256") - CertificateKeyAlgorithmTypeEC384 = CertificateKeyAlgorithmType("EC384") - CertificateKeyAlgorithmTypeEC512 = CertificateKeyAlgorithmType("EC512") + CertificateKeyAlgorithmTypeRSA2048 = CertificateKeyAlgorithmType(certcrypto.RSA2048) + CertificateKeyAlgorithmTypeRSA3072 = CertificateKeyAlgorithmType(certcrypto.RSA3072) + CertificateKeyAlgorithmTypeRSA4096 = CertificateKeyAlgorithmType(certcrypto.RSA4096) + CertificateKeyAlgorithmTypeRSA8192 = CertificateKeyAlgorithmType(certcrypto.RSA8192) + CertificateKeyAlgorithmTypeEC256 = CertificateKeyAlgorithmType(certcrypto.EC256) + CertificateKeyAlgorithmTypeEC384 = CertificateKeyAlgorithmType(certcrypto.EC384) ) type CertificateFormatType string diff --git a/internal/domain/provider.go b/internal/domain/provider.go index 3ce327022..328a5feed 100644 --- a/internal/domain/provider.go +++ b/internal/domain/provider.go @@ -159,10 +159,16 @@ const ( CAProviderTypeZeroSSL = CAProviderType(AccessProviderTypeZeroSSL) ) -type ACMEDns01ProviderType string +type ACMEChallengeProviderType string + +func (t ACMEChallengeProviderType) String() string { + return string(t) +} + +type ACMEDns01ProviderType ACMEChallengeProviderType func (t ACMEDns01ProviderType) String() string { - return string(t) + return t.String() } /* @@ -252,10 +258,10 @@ const ( ACMEDns01ProviderTypeXinnet = ACMEDns01ProviderType(AccessProviderTypeXinnet) ) -type ACMEHttp01ProviderType string +type ACMEHttp01ProviderType ACMEChallengeProviderType func (t ACMEHttp01ProviderType) String() string { - return string(t) + return t.String() } /* diff --git a/internal/notify/client_notifier.go b/internal/notify/client_notifier.go index 55fe9d584..46af2fe99 100644 --- a/internal/notify/client_notifier.go +++ b/internal/notify/client_notifier.go @@ -10,7 +10,7 @@ import ( type SendNotificationRequest struct { // 提供商相关 - Provider string + Provider domain.NotificationProviderType ProviderAccessConfig map[string]any ProviderExtendedConfig map[string]any @@ -26,7 +26,7 @@ func (c *Client) SendNotification(ctx context.Context, request *SendNotification return nil, fmt.Errorf("the request is nil") } - providerFactory, err := notifiers.Registries.Get(domain.NotificationProviderType(request.Provider)) + providerFactory, err := notifiers.Registries.Get(request.Provider) if err != nil { return nil, err } diff --git a/internal/notify/service.go b/internal/notify/service.go index fd56efdde..59d182d83 100644 --- a/internal/notify/service.go +++ b/internal/notify/service.go @@ -36,7 +36,7 @@ func (n *NotifyService) TestPush(ctx context.Context, req *dtos.NotifyTestPushRe notifier := NewClient() notifyReq := &SendNotificationRequest{ - Provider: req.Provider.String(), + Provider: req.Provider, ProviderAccessConfig: accessConfig, ProviderExtendedConfig: make(map[string]any), Subject: testSubject, diff --git a/internal/repository/acme_account.go b/internal/repository/acme_account.go index 4a265b906..8e0f94445 100644 --- a/internal/repository/acme_account.go +++ b/internal/repository/acme_account.go @@ -6,7 +6,7 @@ import ( "errors" "fmt" - "github.com/go-acme/lego/v4/acme" + "github.com/go-acme/lego/v5/acme" "github.com/pocketbase/dbx" "github.com/pocketbase/pocketbase/core" @@ -74,9 +74,9 @@ func (r *ACMEAccountRepository) Save(ctx context.Context, acmeAccount *domain.AC record.Set("ca", acmeAccount.CA) record.Set("email", acmeAccount.Email) record.Set("privateKey", acmeAccount.PrivateKey) - record.Set("acmeAccount", acmeAccount.ACMEAccount) - record.Set("acmeAcctUrl", acmeAccount.ACMEAcctUrl) record.Set("acmeDirUrl", acmeAccount.ACMEDirUrl) + record.Set("acmeAcctUrl", acmeAccount.ACMEAcctUrl) + record.Set("acmeAccount", acmeAccount.ACMEAccount) if err := app.GetApp().Save(record); err != nil { return acmeAccount, err } @@ -106,9 +106,9 @@ func (r *ACMEAccountRepository) castRecordToModel(record *core.Record) (*domain. CA: record.GetString("ca"), Email: record.GetString("email"), PrivateKey: record.GetString("privateKey"), - ACMEAccount: account, - ACMEAcctUrl: record.GetString("acmeAcctUrl"), ACMEDirUrl: record.GetString("acmeDirUrl"), + ACMEAcctUrl: record.GetString("acmeAcctUrl"), + ACMEAccount: account, } return acmeAccount, nil } diff --git a/internal/tools/mproc/sender.go b/internal/tools/mproc/sender.go index ab7566762..fb9b99373 100644 --- a/internal/tools/mproc/sender.go +++ b/internal/tools/mproc/sender.go @@ -8,7 +8,6 @@ import ( "fmt" "log/slog" "os" - "strings" "github.com/go-cmd/cmd" @@ -106,19 +105,33 @@ func (s *sender[TIn, TOut]) SendWithContext(ctx context.Context, params *TIn) (* } if s.logger != nil { - print := s.logger.Info + logFn := s.logger.Info - // split log level prefix for those vendor packages: - // - github.com/go-acme/lego: INFO, WARN - if strings.HasPrefix(line, "[INFO] ") { - line = strings.TrimPrefix(line, "[INFO] ") - print = s.logger.Info - } else if strings.HasPrefix(line, "[WARN] ") { - line = strings.TrimPrefix(line, "[WARN] ") - print = s.logger.Warn + logRec, err := stdLogUnmarshal([]byte(line)) + logAttrs := make([]any, 0) + if err == nil { + switch logRec.Level { + case slog.LevelDebug: + logFn = s.logger.Debug + line = logRec.Message + case slog.LevelWarn: + logFn = s.logger.Warn + line = logRec.Message + case slog.LevelError: + logFn = s.logger.Error + line = logRec.Message + default: + logFn = s.logger.Info + line = logRec.Message + } + + logRec.Attrs(func(a slog.Attr) bool { + logAttrs = append(logAttrs, a) + return true + }) } - print(line) + logFn(line, logAttrs...) } } @@ -130,16 +143,8 @@ func (s *sender[TIn, TOut]) SendWithContext(ctx context.Context, params *TIn) (* } if s.logger != nil { - print := s.logger.Error - - // split log level prefix for those vendor packages: - // - github.com/nrdcg/desec: DEBUG - if strings.Contains(line, "[DEBUG] ") { - line = strings.SplitN(line, "[DEBUG] ", 2)[1] - print = s.logger.Debug - } - - print(line) + logFn := s.logger.Error + logFn(line) } } } diff --git a/internal/tools/mproc/stdlog.go b/internal/tools/mproc/stdlog.go new file mode 100644 index 000000000..080e9c1d5 --- /dev/null +++ b/internal/tools/mproc/stdlog.go @@ -0,0 +1,54 @@ +package mproc + +import ( + "encoding/json" + "log/slog" + "time" +) + +type stdLogEntry struct { + Time time.Time `json:"time"` + Level string `json:"level"` + Msg string `json:"msg"` +} + +func stdLogUnmarshal(data []byte) (slog.Record, error) { + var entry stdLogEntry + if err := json.Unmarshal(data, &entry); err != nil { + return slog.Record{}, err + } + + var attrsMap map[string]any + if err := json.Unmarshal(data, &attrsMap); err != nil { + return slog.Record{}, err + } + + level := slog.LevelInfo + switch entry.Level { + case "DEBUG": + level = slog.LevelDebug + case "INFO": + level = slog.LevelInfo + case "WARN": + level = slog.LevelWarn + case "ERROR": + level = slog.LevelError + default: + level = slog.LevelInfo + } + + record := slog.Record{ + Time: entry.Time, + Level: level, + Message: entry.Msg, + } + + delete(attrsMap, "time") + delete(attrsMap, "level") + delete(attrsMap, "msg") + for k, v := range attrsMap { + record.AddAttrs(slog.Any(k, v)) + } + + return record, nil +} diff --git a/internal/workflow/engine/engine.go b/internal/workflow/engine/engine.go index 178eb42df..4e2b936a8 100644 --- a/internal/workflow/engine/engine.go +++ b/internal/workflow/engine/engine.go @@ -147,7 +147,7 @@ func (we *workflowEngine) executeNode(wfCtx *WorkflowContext, node *Node) error err := fmt.Errorf("workflow engine: no executor registered for node type: '%s'", node.Type) return err } else { - logger := slog.New(logging.NewHookHandler(&logging.HookHandlerOptions{ + logger := slog.New(logging.NewHookHandler(nil, &logging.HookHandlerOptions{ Level: slog.LevelDebug, WriteFunc: func(ctx context.Context, record logging.Record) error { we.fireOnNodeLoggingHooks(ctx, node, record) diff --git a/internal/workflow/engine/executor_bizapply.go b/internal/workflow/engine/executor_bizapply.go index 2f0b9e252..ca314941b 100644 --- a/internal/workflow/engine/executor_bizapply.go +++ b/internal/workflow/engine/executor_bizapply.go @@ -10,13 +10,11 @@ import ( "strings" "time" - legocertifier "github.com/go-acme/lego/v4/certificate" - "github.com/go-acme/lego/v4/lego" - legolog "github.com/go-acme/lego/v4/log" + "github.com/go-acme/lego/v5/acme/api" + "github.com/go-acme/lego/v5/lego" "github.com/samber/lo" "github.com/xhit/go-str2duration/v2" - "github.com/certimate-go/certimate/internal/app" "github.com/certimate-go/certimate/internal/certacme" "github.com/certimate-go/certimate/internal/domain" "github.com/certimate-go/certimate/internal/repository" @@ -55,6 +53,7 @@ const ( type bizApplyNodeExecutor struct { nodeExecutor + settingsRepo settingsRepository accessRepo accessRepository certificateRepo certificateRepository wfoutputRepo workflowOutputRepository @@ -232,35 +231,31 @@ func (ne *bizApplyNodeExecutor) checkCanSkip(execCtx *NodeExecutionContext, last func (ne *bizApplyNodeExecutor) executeObtain(execCtx *NodeExecutionContext, nodeCfg *domain.WorkflowNodeConfigForBizApply, lastCertificate *domain.Certificate) (*certacme.ObtainCertificateResponse, error) { // 读取私钥算法 // 如果复用私钥,则保持算法一致 - legoKeyType, err := domain.CertificateKeyAlgorithmType(nodeCfg.KeyAlgorithm).ToLegoKeyType() - if err != nil { - return nil, err - } else { - switch nodeCfg.KeySource { - case BizApplyKeySourceAuto: - break - case BizApplyKeySourceReuse: - if lastCertificate != nil { - legoKeyType, _ = lastCertificate.KeyAlgorithm.ToLegoKeyType() - } - case BizApplyKeySourceCustom: - privkey, err := xcert.ParsePrivateKeyFromPEM(nodeCfg.KeyContent) - if err != nil { - return nil, fmt.Errorf("could not parse custom private key: %w", err) - } else { - privkeyAlg, privkeySize, _ := xcertkey.DetectPrivateKeyAlgorithm(privkey) - switch privkeyAlg { - case x509.RSA: - if nodeCfg.KeyAlgorithm != fmt.Sprintf("RSA%d", privkeySize) { - return nil, fmt.Errorf("could not parse custom private key: unsupported algorithm or key size") - } - case x509.ECDSA: - if nodeCfg.KeyAlgorithm != fmt.Sprintf("EC%d", privkeySize) { - return nil, fmt.Errorf("could not parse custom private key: unsupported algorithm or key size") - } - default: - return nil, fmt.Errorf("could not parse custom private key: unsupported algorithm") + keyAlgorithm := domain.CertificateKeyAlgorithmType(nodeCfg.KeyAlgorithm) + switch nodeCfg.KeySource { + case BizApplyKeySourceAuto: + break + case BizApplyKeySourceReuse: + if lastCertificate != nil { + keyAlgorithm = lastCertificate.KeyAlgorithm + } + case BizApplyKeySourceCustom: + privkey, err := xcert.ParsePrivateKeyFromPEM(nodeCfg.KeyContent) + if err != nil { + return nil, fmt.Errorf("could not parse custom private key: %w", err) + } else { + privkeyAlg, privkeySize, _ := xcertkey.DetectPrivateKeyAlgorithm(privkey) + switch privkeyAlg { + case x509.RSA: + if nodeCfg.KeyAlgorithm != fmt.Sprintf("RSA%d", privkeySize) { + return nil, fmt.Errorf("could not parse custom private key: unsupported algorithm or key size") } + case x509.ECDSA: + if nodeCfg.KeyAlgorithm != fmt.Sprintf("EC%d", privkeySize) { + return nil, fmt.Errorf("could not parse custom private key: unsupported algorithm or key size") + } + default: + return nil, fmt.Errorf("could not parse custom private key: unsupported algorithm") } } } @@ -286,37 +281,34 @@ func (ne *bizApplyNodeExecutor) executeObtain(execCtx *NodeExecutionContext, nod } // 初始化 ACME 配置项 - legoOptions := &certacme.ACMEConfigOptions{ - CAProvider: nodeCfg.CAProvider, - CAAccessConfig: caAccessConfig, - CAProviderConfig: nodeCfg.CAProviderConfig, - CertifierKeyType: legoKeyType, + acmeOpts := &certacme.ACMEConfigOptions{ + CAProvider: domain.CAProviderType(nodeCfg.CAProvider), + CAProviderAccessConfig: caAccessConfig, + CAProviderExtendedConfig: nodeCfg.CAProviderConfig, + CertifierKeyAlgorithm: keyAlgorithm, } - legoConfig, err := certacme.NewACMEConfig(legoOptions) + acmeCfg, err := certacme.CreateACMEConfig(execCtx.Context(), acmeOpts) if err != nil { ne.logger.Warn("could not initialize acme config") return nil, err } else { - ne.logger.Info("acme config initialized", slog.String("acmeDirUrl", legoConfig.CADirUrl)) + ne.logger.Info("acme config initialized", slog.String("acmeDirUrl", acmeCfg.CADirUrl)) } // 初始化 ACME 账户 // 注意此步骤仍需在主进程中进行,以保证并发安全 - legoUser, err := certacme.NewACMEAccountWithSingleFlight(legoConfig, nodeCfg.ContactEmail) + acmeAcct, err := certacme.CreateACMEAccountWithSingleFlight(execCtx.Context(), acmeCfg, nodeCfg.ContactEmail) if err != nil { ne.logger.Warn("could not initialize acme account") return nil, err } else { - ne.logger.Info("acme account initialized", slog.String("acmeAcctUrl", legoUser.ACMEAcctUrl)) + ne.logger.Info("acme account initialized", slog.String("acmeAcctUrl", acmeAcct.ACMEAcctUrl)) } // 构造证书申请请求 - legoDomains := make([]string, 0) - legoDomains = append(legoDomains, nodeCfg.Domains...) - legoDomains = append(legoDomains, nodeCfg.IPAddrs...) obtainReq := &certacme.ObtainCertificateRequest{ - DomainOrIPs: legoDomains, - PrivateKeyType: legoKeyType, + DomainOrIPs: lo.Concat(nodeCfg.Domains, nodeCfg.IPAddrs), + PrivateKeyType: keyAlgorithm.LegoKeyType(), PrivateKeyPEM: lo. If(nodeCfg.KeySource == BizApplyKeySourceAuto, ""). ElseF(func() string { @@ -341,7 +333,7 @@ func (ne *bizApplyNodeExecutor) executeObtain(execCtx *NodeExecutionContext, nod }), NoCommonName: nodeCfg.DisableCommonName, ChallengeType: nodeCfg.ChallengeType, - Provider: nodeCfg.Provider, + Provider: domain.ACMEChallengeProviderType(nodeCfg.Provider), ProviderAccessConfig: providerAccessConfig, ProviderExtendedConfig: nodeCfg.ProviderConfig, DisableFollowCNAME: nodeCfg.DisableFollowCNAME, @@ -380,16 +372,28 @@ func (ne *bizApplyNodeExecutor) executeObtain(execCtx *NodeExecutionContext, nod return "" } - oldARICertId, _ := legocertifier.MakeARICertID(oldCertX509) + oldARICertId, _ := api.MakeARICertID(oldCertX509) return oldARICertId }), } + // 构造证书申请时所需的 lego 配置项 + legoCertifierCfg := &lego.NewConfig(nil).Certificate + settings, _ := ne.settingsRepo.GetByName(execCtx.Context(), domain.SettingsNameSSLProvider) + if settings != nil { + sslProviderSettings := settings.Content.AsSSLProvider() + if sslProviderSettings.Timeout > 0 { + legoCertifierCfg.Timeout = time.Duration(sslProviderSettings.Timeout) * time.Second + } + } + // 如果启用多进程模式,发送指令 if envMultiProc { type InData struct { - Account *certacme.ACMEAccount `json:"account,omitempty"` Request *certacme.ObtainCertificateRequest `json:"request,omitempty"` + + LegoAccount *certacme.ACMEAccount `json:"legoAccount,omitempty"` + LegoCertifierConfig *lego.CertificateConfig `json:"legoCertifierConfig,omitempty"` } type OutData struct { @@ -398,8 +402,10 @@ func (ne *bizApplyNodeExecutor) executeObtain(execCtx *NodeExecutionContext, nod msender := mproc.NewSender[InData, OutData]("certapply", ne.logger) moutput, err := msender.SendWithContext(execCtx.Context(), &InData{ - Account: legoUser, Request: obtainReq, + + LegoAccount: acmeAcct, + LegoCertifierConfig: legoCertifierCfg, }) if err != nil { ne.logger.Warn("could not obtain certificate") @@ -414,11 +420,8 @@ func (ne *bizApplyNodeExecutor) executeObtain(execCtx *NodeExecutionContext, nod } // 初始化 ACME 客户端 - legolog.Logger = certacme.NewLegoLogger(app.GetLogger()) - legoClient, err := certacme.NewACMEClientWithAccount(legoUser, func(c *lego.Config) error { - c.UserAgent = app.AppUserAgent - c.Certificate.KeyType = legoKeyType - c.Certificate.DisableCommonName = obtainReq.NoCommonName + acmeClient, err := certacme.NewACMEClientWithAccount(acmeAcct, func(legoCfg *lego.Config) error { + legoCfg.Certificate = *legoCertifierCfg return nil }) if err != nil { @@ -427,7 +430,7 @@ func (ne *bizApplyNodeExecutor) executeObtain(execCtx *NodeExecutionContext, nod } // 执行申请证书请求 - obtainResp, err := legoClient.ObtainCertificate(execCtx.Context(), obtainReq) + obtainResp, err := acmeClient.ObtainCertificate(execCtx.Context(), obtainReq) if err != nil { ne.logger.Warn("could not obtain certificate") return nil, err @@ -490,6 +493,7 @@ func (ne *bizApplyNodeExecutor) setVariablesOfResult(execCtx *NodeExecutionConte func newBizApplyNodeExecutor() NodeExecutor { return &bizApplyNodeExecutor{ nodeExecutor: nodeExecutor{logger: slog.Default()}, + settingsRepo: repository.NewSettingsRepository(), accessRepo: repository.NewAccessRepository(), certificateRepo: repository.NewCertificateRepository(), wfoutputRepo: repository.NewWorkflowOutputRepository(), diff --git a/internal/workflow/engine/executor_bizdeploy.go b/internal/workflow/engine/executor_bizdeploy.go index 921750664..c519430bb 100644 --- a/internal/workflow/engine/executor_bizdeploy.go +++ b/internal/workflow/engine/executor_bizdeploy.go @@ -91,11 +91,11 @@ func (ne *bizDeployNodeExecutor) Execute(execCtx *NodeExecutionContext) (*NodeEx // 部署证书 deployer := certmgmt.NewClient(certmgmt.WithLogger(ne.logger)) deployReq := &certmgmt.DeployCertificateRequest{ - Provider: nodeCfg.Provider, + Provider: domain.DeploymentProviderType(nodeCfg.Provider), ProviderAccessConfig: providerAccessConfig, ProviderExtendedConfig: nodeCfg.ProviderConfig, - Certificate: inputCertificate.Certificate, - PrivateKey: inputCertificate.PrivateKey, + CertificatePEM: inputCertificate.Certificate, + PrivateKeyPEM: inputCertificate.PrivateKey, } if _, err := deployer.DeployCertificate(execCtx.Context(), deployReq); err != nil { ne.logger.Warn("could not deploy certificate") diff --git a/internal/workflow/engine/executor_biznotify.go b/internal/workflow/engine/executor_biznotify.go index 0b73c3af2..bd0a2851e 100644 --- a/internal/workflow/engine/executor_biznotify.go +++ b/internal/workflow/engine/executor_biznotify.go @@ -7,6 +7,7 @@ import ( "strings" "time" + "github.com/certimate-go/certimate/internal/domain" "github.com/certimate-go/certimate/internal/notify" "github.com/certimate-go/certimate/internal/repository" ) @@ -14,8 +15,7 @@ import ( type bizNotifyNodeExecutor struct { nodeExecutor - settingsRepo settingsRepository - accessRepo accessRepository + accessRepo accessRepository } func (ne *bizNotifyNodeExecutor) Execute(execCtx *NodeExecutionContext) (*NodeExecutionResult, error) { @@ -68,7 +68,7 @@ func (ne *bizNotifyNodeExecutor) Execute(execCtx *NodeExecutionContext) (*NodeEx // 推送通知 notifier := notify.NewClient(notify.WithLogger(ne.logger)) notifyReq := ¬ify.SendNotificationRequest{ - Provider: nodeCfg.Provider, + Provider: domain.NotificationProviderType(nodeCfg.Provider), ProviderAccessConfig: providerAccessConfig, ProviderExtendedConfig: nodeCfg.ProviderConfig, Subject: subject, @@ -108,7 +108,6 @@ func (ne *bizNotifyNodeExecutor) checkCanSkip(execCtx *NodeExecutionContext) (_s func newBizNotifyNodeExecutor() NodeExecutor { return &bizNotifyNodeExecutor{ nodeExecutor: nodeExecutor{logger: slog.Default()}, - settingsRepo: repository.NewSettingsRepository(), accessRepo: repository.NewAccessRepository(), } } diff --git a/pkg/core/certifier.go b/pkg/core/certifier.go index 082167a4e..1a16ae522 100644 --- a/pkg/core/certifier.go +++ b/pkg/core/certifier.go @@ -1,7 +1,7 @@ package core import ( - "github.com/go-acme/lego/v4/challenge" + "github.com/go-acme/lego/v5/challenge" ) type ACMEChallenger = challenge.Provider diff --git a/pkg/core/certifier/challengers/dns01/35cn/35cn.go b/pkg/core/certifier/challengers/dns01/35cn/35cn.go index 2e78b1de8..c7fa9d996 100644 --- a/pkg/core/certifier/challengers/dns01/35cn/35cn.go +++ b/pkg/core/certifier/challengers/dns01/35cn/35cn.go @@ -4,7 +4,7 @@ import ( "fmt" "time" - "github.com/go-acme/lego/v4/providers/dns/com35" + "github.com/go-acme/lego/v5/providers/dns/com35" "github.com/certimate-go/certimate/pkg/core/certifier" ) diff --git a/pkg/core/certifier/challengers/dns01/51dnscom/internal/lego.go b/pkg/core/certifier/challengers/dns01/51dnscom/internal/lego.go index 2fc3f7aaf..8ff0dbe86 100644 --- a/pkg/core/certifier/challengers/dns01/51dnscom/internal/lego.go +++ b/pkg/core/certifier/challengers/dns01/51dnscom/internal/lego.go @@ -1,13 +1,14 @@ package internal import ( + "context" "fmt" "sync" "time" - "github.com/go-acme/lego/v4/challenge" - "github.com/go-acme/lego/v4/challenge/dns01" - "github.com/go-acme/lego/v4/platform/config/env" + "github.com/go-acme/lego/v5/challenge" + "github.com/go-acme/lego/v5/challenge/dns01" + "github.com/go-acme/lego/v5/platform/env" "github.com/samber/lo" dnscomsdk "github.com/certimate-go/certimate/pkg/sdk3rd/51dnscom" @@ -86,10 +87,10 @@ func NewDNSProviderConfig(config *Config) (*DNSProvider, error) { }, nil } -func (d *DNSProvider) Present(domain, token, keyAuth string) error { - info := dns01.GetChallengeInfo(domain, keyAuth) +func (d *DNSProvider) Present(ctx context.Context, domain, token, keyAuth string) error { + info := dns01.GetChallengeInfo(ctx, domain, keyAuth) - authZone, err := dns01.FindZoneByFqdn(info.EffectiveFQDN) + authZone, err := dns01.DefaultClient().FindZoneByFqdn(ctx, info.EffectiveFQDN) if err != nil { return fmt.Errorf("51dnscom: could not find zone for domain %q: %w", domain, err) } @@ -99,7 +100,7 @@ func (d *DNSProvider) Present(domain, token, keyAuth string) error { return fmt.Errorf("51dnscom: %w", err) } - zone, err := d.findZone(dns01.UnFqdn(authZone)) + zone, err := d.findZone(ctx, dns01.UnFqdn(authZone)) if err != nil { return fmt.Errorf("51dnscom: error when list zones: %w", err) } @@ -112,7 +113,7 @@ func (d *DNSProvider) Present(domain, token, keyAuth string) error { Value: lo.ToPtr(info.Value), TTL: lo.ToPtr(int32(d.config.TTL)), } - response, err := d.client.RecordCreate(request) + response, err := d.client.RecordCreateWithContext(ctx, request) if err != nil { return fmt.Errorf("51dnscom: error when create record: %w", err) } @@ -124,8 +125,8 @@ func (d *DNSProvider) Present(domain, token, keyAuth string) error { return nil } -func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error { - info := dns01.GetChallengeInfo(domain, keyAuth) +func (d *DNSProvider) CleanUp(ctx context.Context, domain, token, keyAuth string) error { + info := dns01.GetChallengeInfo(ctx, domain, keyAuth) d.recordCacheMu.Lock() record, ok := d.recordCache[token] @@ -139,7 +140,7 @@ func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error { DomainID: lo.ToPtr(record.DomainID), RecordID: lo.ToPtr(record.RecordID), } - if _, err := d.client.RecordRemove(request); err != nil { + if _, err := d.client.RecordRemoveWithContext(ctx, request); err != nil { return fmt.Errorf("51dnscom: error when delete record: %w", err) } @@ -155,7 +156,7 @@ type dnsRecordCacheEntry struct { RecordID string } -func (d *DNSProvider) findZone(zoneName string) (*dnscomsdk.DomainRecord, error) { +func (d *DNSProvider) findZone(ctx context.Context, zoneName string) (*dnscomsdk.DomainRecord, error) { page := 1 pageSize := 10 for { @@ -164,7 +165,7 @@ func (d *DNSProvider) findZone(zoneName string) (*dnscomsdk.DomainRecord, error) Page: lo.ToPtr(int32(page)), PageSize: lo.ToPtr(int32(pageSize)), } - response, err := d.client.DomainList(request) + response, err := d.client.DomainListWithContext(ctx, request) if err != nil { return nil, err } diff --git a/pkg/core/certifier/challengers/dns01/acmedns/acmedns.go b/pkg/core/certifier/challengers/dns01/acmedns/acmedns.go index 82fe4438b..de91437db 100644 --- a/pkg/core/certifier/challengers/dns01/acmedns/acmedns.go +++ b/pkg/core/certifier/challengers/dns01/acmedns/acmedns.go @@ -4,7 +4,7 @@ import ( "fmt" "os" - "github.com/go-acme/lego/v4/providers/dns/acmedns" + "github.com/go-acme/lego/v5/providers/dns/acmedns" "github.com/certimate-go/certimate/pkg/core/certifier" ) diff --git a/pkg/core/certifier/challengers/dns01/acmehttpreq/acmehttpreq.go b/pkg/core/certifier/challengers/dns01/acmehttpreq/acmehttpreq.go index 4a10901cf..49d7cbdae 100644 --- a/pkg/core/certifier/challengers/dns01/acmehttpreq/acmehttpreq.go +++ b/pkg/core/certifier/challengers/dns01/acmehttpreq/acmehttpreq.go @@ -5,7 +5,7 @@ import ( "net/url" "time" - "github.com/go-acme/lego/v4/providers/dns/httpreq" + "github.com/go-acme/lego/v5/providers/dns/httpreq" "github.com/certimate-go/certimate/pkg/core/certifier" ) diff --git a/pkg/core/certifier/challengers/dns01/akamai-edgedns/akamai_edgedns.go b/pkg/core/certifier/challengers/dns01/akamai-edgedns/akamai_edgedns.go index 183c74163..c4c1d711b 100644 --- a/pkg/core/certifier/challengers/dns01/akamai-edgedns/akamai_edgedns.go +++ b/pkg/core/certifier/challengers/dns01/akamai-edgedns/akamai_edgedns.go @@ -4,8 +4,8 @@ import ( "time" "github.com/akamai/AkamaiOPEN-edgegrid-golang/v13/pkg/edgegrid" - "github.com/go-acme/lego/v4/challenge" - "github.com/go-acme/lego/v4/providers/dns/edgedns" + "github.com/go-acme/lego/v5/challenge" + "github.com/go-acme/lego/v5/providers/dns/edgedns" ) type ChallengerConfig struct { diff --git a/pkg/core/certifier/challengers/dns01/aliyun-esa/aliyun_esa.go b/pkg/core/certifier/challengers/dns01/aliyun-esa/aliyun_esa.go index 80bdbf7dd..cfc24f0d6 100644 --- a/pkg/core/certifier/challengers/dns01/aliyun-esa/aliyun_esa.go +++ b/pkg/core/certifier/challengers/dns01/aliyun-esa/aliyun_esa.go @@ -4,7 +4,7 @@ import ( "fmt" "time" - "github.com/go-acme/lego/v4/providers/dns/aliesa" + "github.com/go-acme/lego/v5/providers/dns/aliesa" "github.com/certimate-go/certimate/pkg/core/certifier" ) diff --git a/pkg/core/certifier/challengers/dns01/aliyun/aliyun.go b/pkg/core/certifier/challengers/dns01/aliyun/aliyun.go index d4759c3af..6c68ca0a8 100644 --- a/pkg/core/certifier/challengers/dns01/aliyun/aliyun.go +++ b/pkg/core/certifier/challengers/dns01/aliyun/aliyun.go @@ -4,7 +4,7 @@ import ( "fmt" "time" - "github.com/go-acme/lego/v4/providers/dns/alidns" + "github.com/go-acme/lego/v5/providers/dns/alidns" "github.com/certimate-go/certimate/pkg/core/certifier" ) diff --git a/pkg/core/certifier/challengers/dns01/arvancloud/arvancloud.go b/pkg/core/certifier/challengers/dns01/arvancloud/arvancloud.go index fb27506fb..e27104dd5 100644 --- a/pkg/core/certifier/challengers/dns01/arvancloud/arvancloud.go +++ b/pkg/core/certifier/challengers/dns01/arvancloud/arvancloud.go @@ -4,7 +4,7 @@ import ( "fmt" "time" - "github.com/go-acme/lego/v4/providers/dns/arvancloud" + "github.com/go-acme/lego/v5/providers/dns/arvancloud" "github.com/certimate-go/certimate/pkg/core/certifier" ) diff --git a/pkg/core/certifier/challengers/dns01/aws-lightsail/aws_lightsail.go b/pkg/core/certifier/challengers/dns01/aws-lightsail/aws_lightsail.go index b66eabd03..2ffd47837 100644 --- a/pkg/core/certifier/challengers/dns01/aws-lightsail/aws_lightsail.go +++ b/pkg/core/certifier/challengers/dns01/aws-lightsail/aws_lightsail.go @@ -4,9 +4,8 @@ import ( "fmt" "time" - internal "github.com/go-acme/lego/v4/providers/dns/route53" - "github.com/certimate-go/certimate/pkg/core/certifier" + "github.com/certimate-go/certimate/pkg/core/certifier/challengers/dns01/aws-lightsail/internal" ) type ChallengerConfig struct { @@ -29,9 +28,6 @@ func NewChallenger(config *ChallengerConfig) (certifier.ACMEChallenger, error) { if config.DnsPropagationTimeout != 0 { providerConfig.PropagationTimeout = time.Duration(config.DnsPropagationTimeout) * time.Second } - if config.DnsTTL != 0 { - providerConfig.TTL = config.DnsTTL - } provider, err := internal.NewDNSProviderConfig(providerConfig) if err != nil { diff --git a/pkg/core/certifier/challengers/dns01/aws-lightsail/internal/lego.go b/pkg/core/certifier/challengers/dns01/aws-lightsail/internal/lego.go index 550c5a22c..8a0f449e7 100644 --- a/pkg/core/certifier/challengers/dns01/aws-lightsail/internal/lego.go +++ b/pkg/core/certifier/challengers/dns01/aws-lightsail/internal/lego.go @@ -13,9 +13,9 @@ import ( "github.com/aws/aws-sdk-go-v2/credentials" "github.com/aws/aws-sdk-go-v2/service/lightsail" awstypes "github.com/aws/aws-sdk-go-v2/service/lightsail/types" - "github.com/go-acme/lego/v4/challenge" - "github.com/go-acme/lego/v4/challenge/dns01" - "github.com/go-acme/lego/v4/platform/config/env" + "github.com/go-acme/lego/v5/challenge" + "github.com/go-acme/lego/v5/challenge/dns01" + "github.com/go-acme/lego/v5/platform/env" ) const ( @@ -90,10 +90,10 @@ func NewDNSProviderConfig(config *Config) (*DNSProvider, error) { }, nil } -func (d *DNSProvider) Present(domain, _, keyAuth string) error { - info := dns01.GetChallengeInfo(domain, keyAuth) +func (d *DNSProvider) Present(ctx context.Context, domain, _, keyAuth string) error { + info := dns01.GetChallengeInfo(ctx, domain, keyAuth) - authZone, err := dns01.FindZoneByFqdn(info.EffectiveFQDN) + authZone, err := dns01.DefaultClient().FindZoneByFqdn(ctx, info.EffectiveFQDN) if err != nil { return fmt.Errorf("lightsail: could not find zone for domain %q: %w", domain, err) } @@ -103,7 +103,7 @@ func (d *DNSProvider) Present(domain, _, keyAuth string) error { return fmt.Errorf("lightsail: %w", err) } - if _, err := d.client.CreateDomainEntry(context.Background(), &lightsail.CreateDomainEntryInput{ + if _, err := d.client.CreateDomainEntry(ctx, &lightsail.CreateDomainEntryInput{ DomainName: aws.String(dns01.UnFqdn(authZone)), DomainEntry: &awstypes.DomainEntry{ Type: aws.String("TXT"), @@ -117,10 +117,10 @@ func (d *DNSProvider) Present(domain, _, keyAuth string) error { return nil } -func (d *DNSProvider) CleanUp(domain, _, keyAuth string) error { - info := dns01.GetChallengeInfo(domain, keyAuth) +func (d *DNSProvider) CleanUp(ctx context.Context, domain, _, keyAuth string) error { + info := dns01.GetChallengeInfo(ctx, domain, keyAuth) - authZone, err := dns01.FindZoneByFqdn(info.EffectiveFQDN) + authZone, err := dns01.DefaultClient().FindZoneByFqdn(ctx, info.EffectiveFQDN) if err != nil { return fmt.Errorf("lightsail: could not find zone for domain %q: %w", domain, err) } @@ -130,7 +130,7 @@ func (d *DNSProvider) CleanUp(domain, _, keyAuth string) error { return fmt.Errorf("lightsail: %w", err) } - if _, err := d.client.DeleteDomainEntry(context.Background(), &lightsail.DeleteDomainEntryInput{ + if _, err := d.client.DeleteDomainEntry(ctx, &lightsail.DeleteDomainEntryInput{ DomainName: aws.String(dns01.UnFqdn(authZone)), DomainEntry: &awstypes.DomainEntry{ Type: aws.String("TXT"), diff --git a/pkg/core/certifier/challengers/dns01/aws-route53/aws_route53.go b/pkg/core/certifier/challengers/dns01/aws-route53/aws_route53.go index dac85019a..df74d15eb 100644 --- a/pkg/core/certifier/challengers/dns01/aws-route53/aws_route53.go +++ b/pkg/core/certifier/challengers/dns01/aws-route53/aws_route53.go @@ -4,7 +4,7 @@ import ( "fmt" "time" - "github.com/go-acme/lego/v4/providers/dns/route53" + "github.com/go-acme/lego/v5/providers/dns/route53" "github.com/certimate-go/certimate/pkg/core/certifier" ) diff --git a/pkg/core/certifier/challengers/dns01/azure-dns/azure_dns.go b/pkg/core/certifier/challengers/dns01/azure-dns/azure_dns.go index 1603590cb..84b3ecd36 100644 --- a/pkg/core/certifier/challengers/dns01/azure-dns/azure_dns.go +++ b/pkg/core/certifier/challengers/dns01/azure-dns/azure_dns.go @@ -4,7 +4,7 @@ import ( "fmt" "time" - "github.com/go-acme/lego/v4/providers/dns/azuredns" + "github.com/go-acme/lego/v5/providers/dns/azuredns" "github.com/certimate-go/certimate/pkg/core/certifier" azenv "github.com/certimate-go/certimate/pkg/sdk3rd/azure/env" diff --git a/pkg/core/certifier/challengers/dns01/baiducloud/baiducloud.go b/pkg/core/certifier/challengers/dns01/baiducloud/baiducloud.go index 7406c96f6..2223e900d 100644 --- a/pkg/core/certifier/challengers/dns01/baiducloud/baiducloud.go +++ b/pkg/core/certifier/challengers/dns01/baiducloud/baiducloud.go @@ -4,7 +4,7 @@ import ( "fmt" "time" - "github.com/go-acme/lego/v4/providers/dns/baiducloud" + "github.com/go-acme/lego/v5/providers/dns/baiducloud" "github.com/certimate-go/certimate/pkg/core/certifier" ) diff --git a/pkg/core/certifier/challengers/dns01/bookmyname/bookmyname.go b/pkg/core/certifier/challengers/dns01/bookmyname/bookmyname.go index c883873bf..d20d4afe0 100644 --- a/pkg/core/certifier/challengers/dns01/bookmyname/bookmyname.go +++ b/pkg/core/certifier/challengers/dns01/bookmyname/bookmyname.go @@ -4,7 +4,7 @@ import ( "fmt" "time" - "github.com/go-acme/lego/v4/providers/dns/bookmyname" + "github.com/go-acme/lego/v5/providers/dns/bookmyname" "github.com/certimate-go/certimate/pkg/core/certifier" ) diff --git a/pkg/core/certifier/challengers/dns01/bunny/bunny.go b/pkg/core/certifier/challengers/dns01/bunny/bunny.go index 62f7ad43a..058690f5d 100644 --- a/pkg/core/certifier/challengers/dns01/bunny/bunny.go +++ b/pkg/core/certifier/challengers/dns01/bunny/bunny.go @@ -4,7 +4,7 @@ import ( "fmt" "time" - "github.com/go-acme/lego/v4/providers/dns/bunny" + "github.com/go-acme/lego/v5/providers/dns/bunny" "github.com/certimate-go/certimate/pkg/core/certifier" ) diff --git a/pkg/core/certifier/challengers/dns01/cloudflare/cloudflare.go b/pkg/core/certifier/challengers/dns01/cloudflare/cloudflare.go index 46f1f451d..14044087e 100644 --- a/pkg/core/certifier/challengers/dns01/cloudflare/cloudflare.go +++ b/pkg/core/certifier/challengers/dns01/cloudflare/cloudflare.go @@ -4,7 +4,7 @@ import ( "fmt" "time" - "github.com/go-acme/lego/v4/providers/dns/cloudflare" + "github.com/go-acme/lego/v5/providers/dns/cloudflare" "github.com/certimate-go/certimate/pkg/core/certifier" ) diff --git a/pkg/core/certifier/challengers/dns01/cloudns/cloudns.go b/pkg/core/certifier/challengers/dns01/cloudns/cloudns.go index e300d7019..96edb8cf9 100644 --- a/pkg/core/certifier/challengers/dns01/cloudns/cloudns.go +++ b/pkg/core/certifier/challengers/dns01/cloudns/cloudns.go @@ -4,7 +4,7 @@ import ( "fmt" "time" - "github.com/go-acme/lego/v4/providers/dns/cloudns" + "github.com/go-acme/lego/v5/providers/dns/cloudns" "github.com/certimate-go/certimate/pkg/core/certifier" ) diff --git a/pkg/core/certifier/challengers/dns01/cmcccloud/internal/lego.go b/pkg/core/certifier/challengers/dns01/cmcccloud/internal/lego.go index fba7ba31d..2892c5377 100644 --- a/pkg/core/certifier/challengers/dns01/cmcccloud/internal/lego.go +++ b/pkg/core/certifier/challengers/dns01/cmcccloud/internal/lego.go @@ -1,13 +1,14 @@ package internal import ( + "context" "fmt" "sync" "time" - "github.com/go-acme/lego/v4/challenge" - "github.com/go-acme/lego/v4/challenge/dns01" - "github.com/go-acme/lego/v4/platform/config/env" + "github.com/go-acme/lego/v5/challenge" + "github.com/go-acme/lego/v5/challenge/dns01" + "github.com/go-acme/lego/v5/platform/env" "github.com/samber/lo" "gitlab.ecloud.com/ecloud/ecloudsdkclouddns" "gitlab.ecloud.com/ecloud/ecloudsdkclouddns/model" @@ -94,10 +95,10 @@ func NewDNSProviderConfig(cfg *Config) (*DNSProvider, error) { }, nil } -func (d *DNSProvider) Present(domain, token, keyAuth string) error { - info := dns01.GetChallengeInfo(domain, keyAuth) +func (d *DNSProvider) Present(ctx context.Context, domain, token, keyAuth string) error { + info := dns01.GetChallengeInfo(ctx, domain, keyAuth) - zoneName, err := dns01.FindZoneByFqdn(info.EffectiveFQDN) + zoneName, err := dns01.DefaultClient().FindZoneByFqdn(ctx, info.EffectiveFQDN) if err != nil { return fmt.Errorf("cmccecloud: could not find zone for domain %q: %w", domain, err) } @@ -132,8 +133,8 @@ func (d *DNSProvider) Present(domain, token, keyAuth string) error { return nil } -func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error { - info := dns01.GetChallengeInfo(domain, keyAuth) +func (d *DNSProvider) CleanUp(ctx context.Context, domain, token, keyAuth string) error { + info := dns01.GetChallengeInfo(ctx, domain, keyAuth) d.recordIDsMu.Lock() recordID, ok := d.recordIDs[token] diff --git a/pkg/core/certifier/challengers/dns01/constellix/constellix.go b/pkg/core/certifier/challengers/dns01/constellix/constellix.go index 40b493eac..03f9434d1 100644 --- a/pkg/core/certifier/challengers/dns01/constellix/constellix.go +++ b/pkg/core/certifier/challengers/dns01/constellix/constellix.go @@ -4,7 +4,7 @@ import ( "fmt" "time" - "github.com/go-acme/lego/v4/providers/dns/constellix" + "github.com/go-acme/lego/v5/providers/dns/constellix" "github.com/certimate-go/certimate/pkg/core/certifier" ) diff --git a/pkg/core/certifier/challengers/dns01/cpanel/cpanel.go b/pkg/core/certifier/challengers/dns01/cpanel/cpanel.go index 368c937f7..233fc6155 100644 --- a/pkg/core/certifier/challengers/dns01/cpanel/cpanel.go +++ b/pkg/core/certifier/challengers/dns01/cpanel/cpanel.go @@ -5,7 +5,7 @@ import ( "fmt" "time" - "github.com/go-acme/lego/v4/providers/dns/cpanel" + "github.com/go-acme/lego/v5/providers/dns/cpanel" "github.com/certimate-go/certimate/pkg/core/certifier" xhttp "github.com/certimate-go/certimate/pkg/utils/http" diff --git a/pkg/core/certifier/challengers/dns01/ctcccloud/internal/lego.go b/pkg/core/certifier/challengers/dns01/ctcccloud/internal/lego.go index 29398e447..e6b5a99e9 100644 --- a/pkg/core/certifier/challengers/dns01/ctcccloud/internal/lego.go +++ b/pkg/core/certifier/challengers/dns01/ctcccloud/internal/lego.go @@ -1,13 +1,14 @@ package internal import ( + "context" "fmt" "sync" "time" - "github.com/go-acme/lego/v4/challenge" - "github.com/go-acme/lego/v4/challenge/dns01" - "github.com/go-acme/lego/v4/platform/config/env" + "github.com/go-acme/lego/v5/challenge" + "github.com/go-acme/lego/v5/challenge/dns01" + "github.com/go-acme/lego/v5/platform/env" "github.com/samber/lo" ctyundns "github.com/certimate-go/certimate/pkg/sdk3rd/ctyun/dns" @@ -86,10 +87,10 @@ func NewDNSProviderConfig(config *Config) (*DNSProvider, error) { }, nil } -func (d *DNSProvider) Present(domain, token, keyAuth string) error { - info := dns01.GetChallengeInfo(domain, keyAuth) +func (d *DNSProvider) Present(ctx context.Context, domain, token, keyAuth string) error { + info := dns01.GetChallengeInfo(ctx, domain, keyAuth) - authZone, err := dns01.FindZoneByFqdn(info.EffectiveFQDN) + authZone, err := dns01.DefaultClient().FindZoneByFqdn(ctx, info.EffectiveFQDN) if err != nil { return fmt.Errorf("ctyun: could not find zone for domain %q: %w", domain, err) } @@ -109,7 +110,7 @@ func (d *DNSProvider) Present(domain, token, keyAuth string) error { State: lo.ToPtr(int32(1)), TTL: lo.ToPtr(int32(d.config.TTL)), } - response, err := d.client.AddRecord(request) + response, err := d.client.AddRecordWithContext(ctx, request) if err != nil { return fmt.Errorf("ctyun: error when create record: %w", err) } @@ -121,8 +122,8 @@ func (d *DNSProvider) Present(domain, token, keyAuth string) error { return nil } -func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error { - info := dns01.GetChallengeInfo(domain, keyAuth) +func (d *DNSProvider) CleanUp(ctx context.Context, domain, token, keyAuth string) error { + info := dns01.GetChallengeInfo(ctx, domain, keyAuth) d.recordIDsMu.Lock() recordID, ok := d.recordIDs[token] @@ -135,7 +136,7 @@ func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error { request := &ctyundns.DeleteRecordRequest{ RecordId: lo.ToPtr(recordID), } - if _, err := d.client.DeleteRecord(request); err != nil { + if _, err := d.client.DeleteRecordWithContext(ctx, request); err != nil { return fmt.Errorf("ctyun: error when delete record: %w", err) } diff --git a/pkg/core/certifier/challengers/dns01/desec/desec.go b/pkg/core/certifier/challengers/dns01/desec/desec.go index d9c8330ca..5913aa3d0 100644 --- a/pkg/core/certifier/challengers/dns01/desec/desec.go +++ b/pkg/core/certifier/challengers/dns01/desec/desec.go @@ -4,7 +4,7 @@ import ( "fmt" "time" - "github.com/go-acme/lego/v4/providers/dns/desec" + "github.com/go-acme/lego/v5/providers/dns/desec" "github.com/certimate-go/certimate/pkg/core/certifier" ) diff --git a/pkg/core/certifier/challengers/dns01/digitalocean/digitalocean.go b/pkg/core/certifier/challengers/dns01/digitalocean/digitalocean.go index 234c1cad4..f6ff6dbc8 100644 --- a/pkg/core/certifier/challengers/dns01/digitalocean/digitalocean.go +++ b/pkg/core/certifier/challengers/dns01/digitalocean/digitalocean.go @@ -4,7 +4,7 @@ import ( "fmt" "time" - "github.com/go-acme/lego/v4/providers/dns/digitalocean" + "github.com/go-acme/lego/v5/providers/dns/digitalocean" "github.com/certimate-go/certimate/pkg/core/certifier" ) diff --git a/pkg/core/certifier/challengers/dns01/dnsexit/dnsexit.go b/pkg/core/certifier/challengers/dns01/dnsexit/dnsexit.go index c14564ae5..10adb3f1b 100644 --- a/pkg/core/certifier/challengers/dns01/dnsexit/dnsexit.go +++ b/pkg/core/certifier/challengers/dns01/dnsexit/dnsexit.go @@ -4,7 +4,7 @@ import ( "fmt" "time" - "github.com/go-acme/lego/v4/providers/dns/dnsexit" + "github.com/go-acme/lego/v5/providers/dns/dnsexit" "github.com/certimate-go/certimate/pkg/core/certifier" ) diff --git a/pkg/core/certifier/challengers/dns01/dnsla/internal/lego.go b/pkg/core/certifier/challengers/dns01/dnsla/internal/lego.go index b515257b4..0e6247a0d 100644 --- a/pkg/core/certifier/challengers/dns01/dnsla/internal/lego.go +++ b/pkg/core/certifier/challengers/dns01/dnsla/internal/lego.go @@ -1,14 +1,15 @@ package internal import ( + "context" "fmt" "strings" "sync" "time" - "github.com/go-acme/lego/v4/challenge" - "github.com/go-acme/lego/v4/challenge/dns01" - "github.com/go-acme/lego/v4/platform/config/env" + "github.com/go-acme/lego/v5/challenge" + "github.com/go-acme/lego/v5/challenge/dns01" + "github.com/go-acme/lego/v5/platform/env" "github.com/samber/lo" dnslasdk "github.com/certimate-go/certimate/pkg/sdk3rd/dnsla" @@ -88,10 +89,10 @@ func NewDNSProviderConfig(config *Config) (*DNSProvider, error) { }, nil } -func (d *DNSProvider) Present(domain, token, keyAuth string) error { - info := dns01.GetChallengeInfo(domain, keyAuth) +func (d *DNSProvider) Present(ctx context.Context, domain, token, keyAuth string) error { + info := dns01.GetChallengeInfo(ctx, domain, keyAuth) - authZone, err := dns01.FindZoneByFqdn(info.EffectiveFQDN) + authZone, err := dns01.DefaultClient().FindZoneByFqdn(ctx, info.EffectiveFQDN) if err != nil { return fmt.Errorf("dnsla: could not find zone for domain %q: %w", domain, err) } @@ -101,7 +102,7 @@ func (d *DNSProvider) Present(domain, token, keyAuth string) error { return fmt.Errorf("dnsla: %w", err) } - zone, err := d.findZone(dns01.UnFqdn(authZone)) + zone, err := d.findZone(ctx, dns01.UnFqdn(authZone)) if err != nil { return fmt.Errorf("dnsla: error when list zones: %w", err) } @@ -114,7 +115,7 @@ func (d *DNSProvider) Present(domain, token, keyAuth string) error { Data: lo.ToPtr(info.Value), Ttl: lo.ToPtr(int32(d.config.TTL)), } - response, err := d.client.CreateRecord(request) + response, err := d.client.CreateRecordWithContext(ctx, request) if err != nil { return fmt.Errorf("dnsla: error when create record: %w", err) } @@ -126,8 +127,8 @@ func (d *DNSProvider) Present(domain, token, keyAuth string) error { return nil } -func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error { - info := dns01.GetChallengeInfo(domain, keyAuth) +func (d *DNSProvider) CleanUp(ctx context.Context, domain, token, keyAuth string) error { + info := dns01.GetChallengeInfo(ctx, domain, keyAuth) d.recordIDsMu.Lock() recordID, ok := d.recordIDs[token] @@ -137,7 +138,7 @@ func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error { } // REF: https://www.dnsla.cn/docs/ApiDoc - if _, err := d.client.DeleteRecord(recordID); err != nil { + if _, err := d.client.DeleteRecordWithContext(ctx, recordID); err != nil { return fmt.Errorf("dnsla: error when delete record: %w", err) } @@ -148,7 +149,7 @@ func (d *DNSProvider) Timeout() (timeout, interval time.Duration) { return d.config.PropagationTimeout, d.config.PollingInterval } -func (d *DNSProvider) findZone(zoneName string) (*dnslasdk.DomainRecord, error) { +func (d *DNSProvider) findZone(ctx context.Context, zoneName string) (*dnslasdk.DomainRecord, error) { pageIndex := 1 pageSize := 100 for { @@ -157,7 +158,7 @@ func (d *DNSProvider) findZone(zoneName string) (*dnslasdk.DomainRecord, error) PageIndex: lo.ToPtr(int32(pageIndex)), PageSize: lo.ToPtr(int32(pageSize)), } - response, err := d.client.ListDomains(request) + response, err := d.client.ListDomainsWithContext(ctx, request) if err != nil { return nil, err } diff --git a/pkg/core/certifier/challengers/dns01/dnsmadeeasy/dnsmadeeasy.go b/pkg/core/certifier/challengers/dns01/dnsmadeeasy/dnsmadeeasy.go index 535c9785a..b1247caae 100644 --- a/pkg/core/certifier/challengers/dns01/dnsmadeeasy/dnsmadeeasy.go +++ b/pkg/core/certifier/challengers/dns01/dnsmadeeasy/dnsmadeeasy.go @@ -4,7 +4,7 @@ import ( "fmt" "time" - "github.com/go-acme/lego/v4/providers/dns/dnsmadeeasy" + "github.com/go-acme/lego/v5/providers/dns/dnsmadeeasy" "github.com/certimate-go/certimate/pkg/core/certifier" ) diff --git a/pkg/core/certifier/challengers/dns01/duckdns/duckdns.go b/pkg/core/certifier/challengers/dns01/duckdns/duckdns.go index 2ea0fa7af..aa9426aba 100644 --- a/pkg/core/certifier/challengers/dns01/duckdns/duckdns.go +++ b/pkg/core/certifier/challengers/dns01/duckdns/duckdns.go @@ -4,7 +4,7 @@ import ( "fmt" "time" - "github.com/go-acme/lego/v4/providers/dns/duckdns" + "github.com/go-acme/lego/v5/providers/dns/duckdns" "github.com/certimate-go/certimate/pkg/core/certifier" ) diff --git a/pkg/core/certifier/challengers/dns01/dynadot/internal/lego.go b/pkg/core/certifier/challengers/dns01/dynadot/internal/lego.go index e70734428..7066147cc 100644 --- a/pkg/core/certifier/challengers/dns01/dynadot/internal/lego.go +++ b/pkg/core/certifier/challengers/dns01/dynadot/internal/lego.go @@ -1,12 +1,13 @@ package internal import ( + "context" "fmt" "time" - "github.com/go-acme/lego/v4/challenge" - "github.com/go-acme/lego/v4/challenge/dns01" - "github.com/go-acme/lego/v4/platform/config/env" + "github.com/go-acme/lego/v5/challenge" + "github.com/go-acme/lego/v5/challenge/dns01" + "github.com/go-acme/lego/v5/platform/env" "github.com/samber/lo" dynadotsdk "github.com/certimate-go/certimate/pkg/sdk3rd/dynadot" @@ -87,10 +88,10 @@ func NewDNSProviderConfig(config *Config) (*DNSProvider, error) { }, nil } -func (d *DNSProvider) Present(domain, token, keyAuth string) error { - info := dns01.GetChallengeInfo(domain, keyAuth) +func (d *DNSProvider) Present(ctx context.Context, domain, token, keyAuth string) error { + info := dns01.GetChallengeInfo(ctx, domain, keyAuth) - authZone, err := dns01.FindZoneByFqdn(info.EffectiveFQDN) + authZone, err := dns01.DefaultClient().FindZoneByFqdn(ctx, info.EffectiveFQDN) if err != nil { return fmt.Errorf("dynadot: could not find zone for domain %q: %w", domain, err) } @@ -112,17 +113,17 @@ func (d *DNSProvider) Present(domain, token, keyAuth string) error { TTL: lo.ToPtr(int64(d.config.TTL)), AddDnsToCurrentSetting: lo.ToPtr(true), } - if _, err := d.client.SetDns(dns01.UnFqdn(authZone), request); err != nil { + if _, err := d.client.SetDnsWithContext(ctx, dns01.UnFqdn(authZone), request); err != nil { return fmt.Errorf("dynadot: error when create record: %w", err) } return nil } -func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error { - info := dns01.GetChallengeInfo(domain, keyAuth) +func (d *DNSProvider) CleanUp(ctx context.Context, domain, token, keyAuth string) error { + info := dns01.GetChallengeInfo(ctx, domain, keyAuth) - authZone, err := dns01.FindZoneByFqdn(info.EffectiveFQDN) + authZone, err := dns01.DefaultClient().FindZoneByFqdn(ctx, info.EffectiveFQDN) if err != nil { return fmt.Errorf("dynadot: could not find zone for domain %q: %w", domain, err) } @@ -142,7 +143,7 @@ func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error { }, }, } - if _, err := d.client.RemoveDns(dns01.UnFqdn(authZone), request); err != nil { + if _, err := d.client.RemoveDnsWithContext(ctx, dns01.UnFqdn(authZone), request); err != nil { return fmt.Errorf("dynadot: error when delete record: %w", err) } diff --git a/pkg/core/certifier/challengers/dns01/dynu/dynu.go b/pkg/core/certifier/challengers/dns01/dynu/dynu.go index 09e54c2a5..feaedeae3 100644 --- a/pkg/core/certifier/challengers/dns01/dynu/dynu.go +++ b/pkg/core/certifier/challengers/dns01/dynu/dynu.go @@ -4,7 +4,7 @@ import ( "fmt" "time" - "github.com/go-acme/lego/v4/providers/dns/dynu" + "github.com/go-acme/lego/v5/providers/dns/dynu" "github.com/certimate-go/certimate/pkg/core/certifier" ) diff --git a/pkg/core/certifier/challengers/dns01/dynv6/internal/lego.go b/pkg/core/certifier/challengers/dns01/dynv6/internal/lego.go index bb3aff4c1..f9ce5555d 100644 --- a/pkg/core/certifier/challengers/dns01/dynv6/internal/lego.go +++ b/pkg/core/certifier/challengers/dns01/dynv6/internal/lego.go @@ -1,13 +1,14 @@ package internal import ( + "context" "fmt" "sync" "time" - "github.com/go-acme/lego/v4/challenge" - "github.com/go-acme/lego/v4/challenge/dns01" - "github.com/go-acme/lego/v4/platform/config/env" + "github.com/go-acme/lego/v5/challenge" + "github.com/go-acme/lego/v5/challenge/dns01" + "github.com/go-acme/lego/v5/platform/env" "github.com/samber/lo" dynv6sdk "github.com/certimate-go/certimate/pkg/sdk3rd/dynv6" @@ -88,10 +89,10 @@ func NewDNSProviderConfig(config *Config) (*DNSProvider, error) { }, nil } -func (d *DNSProvider) Present(domain, token, keyAuth string) error { - info := dns01.GetChallengeInfo(domain, keyAuth) +func (d *DNSProvider) Present(ctx context.Context, domain, token, keyAuth string) error { + info := dns01.GetChallengeInfo(ctx, domain, keyAuth) - authZone, err := dns01.FindZoneByFqdn(info.EffectiveFQDN) + authZone, err := dns01.DefaultClient().FindZoneByFqdn(ctx, info.EffectiveFQDN) if err != nil { return fmt.Errorf("dynv6: could not find zone for domain %q: %w", domain, err) } @@ -101,13 +102,13 @@ func (d *DNSProvider) Present(domain, token, keyAuth string) error { return fmt.Errorf("dynv6: %w", err) } - zone, err := d.findZone(dns01.UnFqdn(authZone)) + zone, err := d.findZone(ctx, dns01.UnFqdn(authZone)) if err != nil { return fmt.Errorf("dynv6: error when list zones: %w", err) } // REF: https://dynv6.github.io/api-spec/#tag/records/operation/addRecord - response, err := d.client.AddRecord(zone.ID, &dynv6sdk.AddRecordRequest{ + response, err := d.client.AddRecordWithContext(ctx, zone.ID, &dynv6sdk.AddRecordRequest{ Type: lo.ToPtr("TXT"), Name: lo.ToPtr(subDomain), Data: lo.ToPtr(info.Value), @@ -127,10 +128,10 @@ func (d *DNSProvider) Present(domain, token, keyAuth string) error { return nil } -func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error { - info := dns01.GetChallengeInfo(domain, keyAuth) +func (d *DNSProvider) CleanUp(ctx context.Context, domain, token, keyAuth string) error { + info := dns01.GetChallengeInfo(ctx, domain, keyAuth) - authZone, err := dns01.FindZoneByFqdn(info.EffectiveFQDN) + authZone, err := dns01.DefaultClient().FindZoneByFqdn(ctx, info.EffectiveFQDN) if err != nil { return fmt.Errorf("dynv6: could not find zone for domain %q: %w", domain, err) } @@ -160,9 +161,9 @@ func (d *DNSProvider) Timeout() (timeout, interval time.Duration) { return d.config.PropagationTimeout, d.config.PollingInterval } -func (d *DNSProvider) findZone(zoneName string) (*dynv6sdk.ZoneRecord, error) { +func (d *DNSProvider) findZone(ctx context.Context, zoneName string) (*dynv6sdk.ZoneRecord, error) { // REF: https://dynv6.github.io/api-spec/#tag/zones/operation/findZones - zones, err := d.client.ListZones() + zones, err := d.client.ListZonesWithContext(ctx) if err != nil { return nil, err } diff --git a/pkg/core/certifier/challengers/dns01/gandinet/gandinet.go b/pkg/core/certifier/challengers/dns01/gandinet/gandinet.go index 5ed3b5c09..3d2ccccc0 100644 --- a/pkg/core/certifier/challengers/dns01/gandinet/gandinet.go +++ b/pkg/core/certifier/challengers/dns01/gandinet/gandinet.go @@ -4,7 +4,7 @@ import ( "fmt" "time" - "github.com/go-acme/lego/v4/providers/dns/gandiv5" + "github.com/go-acme/lego/v5/providers/dns/gandiv5" "github.com/certimate-go/certimate/pkg/core/certifier" ) diff --git a/pkg/core/certifier/challengers/dns01/gcore/gcore.go b/pkg/core/certifier/challengers/dns01/gcore/gcore.go index 081ff85a2..ff9eec4af 100644 --- a/pkg/core/certifier/challengers/dns01/gcore/gcore.go +++ b/pkg/core/certifier/challengers/dns01/gcore/gcore.go @@ -4,7 +4,7 @@ import ( "fmt" "time" - "github.com/go-acme/lego/v4/providers/dns/gcore" + "github.com/go-acme/lego/v5/providers/dns/gcore" "github.com/certimate-go/certimate/pkg/core/certifier" ) diff --git a/pkg/core/certifier/challengers/dns01/gname/internal/lego.go b/pkg/core/certifier/challengers/dns01/gname/internal/lego.go index 60cd8750c..b82793c0b 100644 --- a/pkg/core/certifier/challengers/dns01/gname/internal/lego.go +++ b/pkg/core/certifier/challengers/dns01/gname/internal/lego.go @@ -1,13 +1,14 @@ package internal import ( + "context" "fmt" "sync" "time" - "github.com/go-acme/lego/v4/challenge" - "github.com/go-acme/lego/v4/challenge/dns01" - "github.com/go-acme/lego/v4/platform/config/env" + "github.com/go-acme/lego/v5/challenge" + "github.com/go-acme/lego/v5/challenge/dns01" + "github.com/go-acme/lego/v5/platform/env" "github.com/samber/lo" gnamesdk "github.com/certimate-go/certimate/pkg/sdk3rd/gname" @@ -87,10 +88,10 @@ func NewDNSProviderConfig(config *Config) (*DNSProvider, error) { }, nil } -func (d *DNSProvider) Present(domain, token, keyAuth string) error { - info := dns01.GetChallengeInfo(domain, keyAuth) +func (d *DNSProvider) Present(ctx context.Context, domain, token, keyAuth string) error { + info := dns01.GetChallengeInfo(ctx, domain, keyAuth) - authZone, err := dns01.FindZoneByFqdn(info.EffectiveFQDN) + authZone, err := dns01.DefaultClient().FindZoneByFqdn(ctx, info.EffectiveFQDN) if err != nil { return fmt.Errorf("gname: could not find zone for domain %q: %w", domain, err) } @@ -108,7 +109,7 @@ func (d *DNSProvider) Present(domain, token, keyAuth string) error { RecordValue: lo.ToPtr(info.Value), TTL: lo.ToPtr(int32(d.config.TTL)), } - response, err := d.client.AddDomainResolution(request) + response, err := d.client.AddDomainResolutionWithContext(ctx, request) if err != nil { return fmt.Errorf("gname: error when create record: %w", err) } @@ -120,10 +121,10 @@ func (d *DNSProvider) Present(domain, token, keyAuth string) error { return nil } -func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error { - info := dns01.GetChallengeInfo(domain, keyAuth) +func (d *DNSProvider) CleanUp(ctx context.Context, domain, token, keyAuth string) error { + info := dns01.GetChallengeInfo(ctx, domain, keyAuth) - authZone, err := dns01.FindZoneByFqdn(info.EffectiveFQDN) + authZone, err := dns01.DefaultClient().FindZoneByFqdn(ctx, info.EffectiveFQDN) if err != nil { return fmt.Errorf("gname: could not find zone for domain %q: %w", domain, err) } @@ -140,7 +141,7 @@ func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error { ZoneName: lo.ToPtr(dns01.UnFqdn(authZone)), RecordID: lo.ToPtr(recordID), } - _, err = d.client.DeleteDomainResolution(request) + _, err = d.client.DeleteDomainResolutionWithContext(ctx, request) if err != nil { return fmt.Errorf("gname: error when delete record: %w", err) } diff --git a/pkg/core/certifier/challengers/dns01/godaddy/godaddy.go b/pkg/core/certifier/challengers/dns01/godaddy/godaddy.go index c80cbbd2b..2e3e046ec 100644 --- a/pkg/core/certifier/challengers/dns01/godaddy/godaddy.go +++ b/pkg/core/certifier/challengers/dns01/godaddy/godaddy.go @@ -4,7 +4,7 @@ import ( "fmt" "time" - "github.com/go-acme/lego/v4/providers/dns/godaddy" + "github.com/go-acme/lego/v5/providers/dns/godaddy" "github.com/certimate-go/certimate/pkg/core/certifier" ) diff --git a/pkg/core/certifier/challengers/dns01/hetzner/hetzner.go b/pkg/core/certifier/challengers/dns01/hetzner/hetzner.go index da942a27b..e00c9bb73 100644 --- a/pkg/core/certifier/challengers/dns01/hetzner/hetzner.go +++ b/pkg/core/certifier/challengers/dns01/hetzner/hetzner.go @@ -4,7 +4,7 @@ import ( "fmt" "time" - "github.com/go-acme/lego/v4/providers/dns/hetzner" + "github.com/go-acme/lego/v5/providers/dns/hetzner" "github.com/certimate-go/certimate/pkg/core/certifier" ) diff --git a/pkg/core/certifier/challengers/dns01/hostingde/hostingde.go b/pkg/core/certifier/challengers/dns01/hostingde/hostingde.go index b1b31d466..7bf667dd4 100644 --- a/pkg/core/certifier/challengers/dns01/hostingde/hostingde.go +++ b/pkg/core/certifier/challengers/dns01/hostingde/hostingde.go @@ -4,7 +4,7 @@ import ( "fmt" "time" - "github.com/go-acme/lego/v4/providers/dns/hostingde" + "github.com/go-acme/lego/v5/providers/dns/hostingde" "github.com/certimate-go/certimate/pkg/core/certifier" ) diff --git a/pkg/core/certifier/challengers/dns01/hostinger/hostinger.go b/pkg/core/certifier/challengers/dns01/hostinger/hostinger.go index 866f49638..895a544a0 100644 --- a/pkg/core/certifier/challengers/dns01/hostinger/hostinger.go +++ b/pkg/core/certifier/challengers/dns01/hostinger/hostinger.go @@ -4,7 +4,7 @@ import ( "fmt" "time" - "github.com/go-acme/lego/v4/providers/dns/hostinger" + "github.com/go-acme/lego/v5/providers/dns/hostinger" "github.com/certimate-go/certimate/pkg/core/certifier" ) diff --git a/pkg/core/certifier/challengers/dns01/huaweicloud/huaweicloud.go b/pkg/core/certifier/challengers/dns01/huaweicloud/huaweicloud.go index de40caaa8..91b2644a6 100644 --- a/pkg/core/certifier/challengers/dns01/huaweicloud/huaweicloud.go +++ b/pkg/core/certifier/challengers/dns01/huaweicloud/huaweicloud.go @@ -5,7 +5,7 @@ import ( "time" "github.com/certimate-go/certimate/pkg/core/certifier" - hwc "github.com/go-acme/lego/v4/providers/dns/huaweicloud" + hwc "github.com/go-acme/lego/v5/providers/dns/huaweicloud" ) type ChallengerConfig struct { diff --git a/pkg/core/certifier/challengers/dns01/infomaniak/infomaniak.go b/pkg/core/certifier/challengers/dns01/infomaniak/infomaniak.go index b90c72890..e78cdcdf9 100644 --- a/pkg/core/certifier/challengers/dns01/infomaniak/infomaniak.go +++ b/pkg/core/certifier/challengers/dns01/infomaniak/infomaniak.go @@ -4,7 +4,7 @@ import ( "fmt" "time" - "github.com/go-acme/lego/v4/providers/dns/infomaniak" + "github.com/go-acme/lego/v5/providers/dns/infomaniak" "github.com/certimate-go/certimate/pkg/core/certifier" ) diff --git a/pkg/core/certifier/challengers/dns01/ionos/ionos.go b/pkg/core/certifier/challengers/dns01/ionos/ionos.go index 5e4618400..ddc7201e2 100644 --- a/pkg/core/certifier/challengers/dns01/ionos/ionos.go +++ b/pkg/core/certifier/challengers/dns01/ionos/ionos.go @@ -4,7 +4,7 @@ import ( "fmt" "time" - "github.com/go-acme/lego/v4/providers/dns/ionos" + "github.com/go-acme/lego/v5/providers/dns/ionos" "github.com/certimate-go/certimate/pkg/core/certifier" ) diff --git a/pkg/core/certifier/challengers/dns01/jdcloud/jdcloud.go b/pkg/core/certifier/challengers/dns01/jdcloud/jdcloud.go index f737a4857..10a12637b 100644 --- a/pkg/core/certifier/challengers/dns01/jdcloud/jdcloud.go +++ b/pkg/core/certifier/challengers/dns01/jdcloud/jdcloud.go @@ -4,7 +4,7 @@ import ( "fmt" "time" - "github.com/go-acme/lego/v4/providers/dns/jdcloud" + "github.com/go-acme/lego/v5/providers/dns/jdcloud" "github.com/certimate-go/certimate/pkg/core/certifier" ) diff --git a/pkg/core/certifier/challengers/dns01/linode/linode.go b/pkg/core/certifier/challengers/dns01/linode/linode.go index a52abe3ed..4642b38b3 100644 --- a/pkg/core/certifier/challengers/dns01/linode/linode.go +++ b/pkg/core/certifier/challengers/dns01/linode/linode.go @@ -4,7 +4,7 @@ import ( "fmt" "time" - "github.com/go-acme/lego/v4/providers/dns/linode" + "github.com/go-acme/lego/v5/providers/dns/linode" "github.com/certimate-go/certimate/pkg/core/certifier" ) diff --git a/pkg/core/certifier/challengers/dns01/namecheap/namecheap.go b/pkg/core/certifier/challengers/dns01/namecheap/namecheap.go index 42faa2643..31e6c6562 100644 --- a/pkg/core/certifier/challengers/dns01/namecheap/namecheap.go +++ b/pkg/core/certifier/challengers/dns01/namecheap/namecheap.go @@ -4,7 +4,7 @@ import ( "fmt" "time" - "github.com/go-acme/lego/v4/providers/dns/namecheap" + "github.com/go-acme/lego/v5/providers/dns/namecheap" "github.com/certimate-go/certimate/pkg/core/certifier" ) diff --git a/pkg/core/certifier/challengers/dns01/namedotcom/namedotcom.go b/pkg/core/certifier/challengers/dns01/namedotcom/namedotcom.go index 3aa99c668..2d5d7825c 100644 --- a/pkg/core/certifier/challengers/dns01/namedotcom/namedotcom.go +++ b/pkg/core/certifier/challengers/dns01/namedotcom/namedotcom.go @@ -4,7 +4,7 @@ import ( "fmt" "time" - "github.com/go-acme/lego/v4/providers/dns/namedotcom" + "github.com/go-acme/lego/v5/providers/dns/namedotcom" "github.com/certimate-go/certimate/pkg/core/certifier" ) diff --git a/pkg/core/certifier/challengers/dns01/namesilo/namesilo.go b/pkg/core/certifier/challengers/dns01/namesilo/namesilo.go index 99284ea6a..e31781ba9 100644 --- a/pkg/core/certifier/challengers/dns01/namesilo/namesilo.go +++ b/pkg/core/certifier/challengers/dns01/namesilo/namesilo.go @@ -4,7 +4,7 @@ import ( "fmt" "time" - "github.com/go-acme/lego/v4/providers/dns/namesilo" + "github.com/go-acme/lego/v5/providers/dns/namesilo" "github.com/certimate-go/certimate/pkg/core/certifier" ) diff --git a/pkg/core/certifier/challengers/dns01/netcup/netcup.go b/pkg/core/certifier/challengers/dns01/netcup/netcup.go index 3ccf2c19b..c1e06043e 100644 --- a/pkg/core/certifier/challengers/dns01/netcup/netcup.go +++ b/pkg/core/certifier/challengers/dns01/netcup/netcup.go @@ -4,7 +4,7 @@ import ( "fmt" "time" - "github.com/go-acme/lego/v4/providers/dns/netcup" + "github.com/go-acme/lego/v5/providers/dns/netcup" "github.com/certimate-go/certimate/pkg/core/certifier" ) @@ -29,9 +29,6 @@ func NewChallenger(config *ChallengerConfig) (certifier.ACMEChallenger, error) { if config.DnsPropagationTimeout != 0 { providerConfig.PropagationTimeout = time.Duration(config.DnsPropagationTimeout) * time.Second } - if config.DnsTTL != 0 { - providerConfig.TTL = config.DnsTTL - } provider, err := netcup.NewDNSProviderConfig(providerConfig) if err != nil { diff --git a/pkg/core/certifier/challengers/dns01/netlify/netlify.go b/pkg/core/certifier/challengers/dns01/netlify/netlify.go index 09565af20..7926a0624 100644 --- a/pkg/core/certifier/challengers/dns01/netlify/netlify.go +++ b/pkg/core/certifier/challengers/dns01/netlify/netlify.go @@ -4,7 +4,7 @@ import ( "fmt" "time" - "github.com/go-acme/lego/v4/providers/dns/netlify" + "github.com/go-acme/lego/v5/providers/dns/netlify" "github.com/certimate-go/certimate/pkg/core/certifier" ) diff --git a/pkg/core/certifier/challengers/dns01/ns1/ns1.go b/pkg/core/certifier/challengers/dns01/ns1/ns1.go index 2e6cfd06d..e5dfb622d 100644 --- a/pkg/core/certifier/challengers/dns01/ns1/ns1.go +++ b/pkg/core/certifier/challengers/dns01/ns1/ns1.go @@ -4,7 +4,7 @@ import ( "fmt" "time" - "github.com/go-acme/lego/v4/providers/dns/ns1" + "github.com/go-acme/lego/v5/providers/dns/ns1" "github.com/certimate-go/certimate/pkg/core/certifier" ) diff --git a/pkg/core/certifier/challengers/dns01/ovhcloud/ovhcloud.go b/pkg/core/certifier/challengers/dns01/ovhcloud/ovhcloud.go index bd7e04885..cb3f9feda 100644 --- a/pkg/core/certifier/challengers/dns01/ovhcloud/ovhcloud.go +++ b/pkg/core/certifier/challengers/dns01/ovhcloud/ovhcloud.go @@ -4,7 +4,7 @@ import ( "fmt" "time" - "github.com/go-acme/lego/v4/providers/dns/ovh" + "github.com/go-acme/lego/v5/providers/dns/ovh" "github.com/certimate-go/certimate/pkg/core/certifier" ) diff --git a/pkg/core/certifier/challengers/dns01/porkbun/porkbun.go b/pkg/core/certifier/challengers/dns01/porkbun/porkbun.go index a21a06c24..ab96b7fee 100644 --- a/pkg/core/certifier/challengers/dns01/porkbun/porkbun.go +++ b/pkg/core/certifier/challengers/dns01/porkbun/porkbun.go @@ -4,7 +4,7 @@ import ( "fmt" "time" - "github.com/go-acme/lego/v4/providers/dns/porkbun" + "github.com/go-acme/lego/v5/providers/dns/porkbun" "github.com/certimate-go/certimate/pkg/core/certifier" ) diff --git a/pkg/core/certifier/challengers/dns01/powerdns/powerdns.go b/pkg/core/certifier/challengers/dns01/powerdns/powerdns.go index 9303172f9..6e3a72ae5 100644 --- a/pkg/core/certifier/challengers/dns01/powerdns/powerdns.go +++ b/pkg/core/certifier/challengers/dns01/powerdns/powerdns.go @@ -6,7 +6,7 @@ import ( "net/url" "time" - "github.com/go-acme/lego/v4/providers/dns/pdns" + "github.com/go-acme/lego/v5/providers/dns/pdns" "github.com/certimate-go/certimate/pkg/core/certifier" xhttp "github.com/certimate-go/certimate/pkg/utils/http" diff --git a/pkg/core/certifier/challengers/dns01/qingcloud/internal/lego.go b/pkg/core/certifier/challengers/dns01/qingcloud/internal/lego.go index bcb5121cd..5f83b0ecc 100644 --- a/pkg/core/certifier/challengers/dns01/qingcloud/internal/lego.go +++ b/pkg/core/certifier/challengers/dns01/qingcloud/internal/lego.go @@ -1,13 +1,14 @@ package internal import ( + "context" "fmt" "sync" "time" - "github.com/go-acme/lego/v4/challenge" - "github.com/go-acme/lego/v4/challenge/dns01" - "github.com/go-acme/lego/v4/platform/config/env" + "github.com/go-acme/lego/v5/challenge" + "github.com/go-acme/lego/v5/challenge/dns01" + "github.com/go-acme/lego/v5/platform/env" "github.com/samber/lo" qingcloudsdk "github.com/certimate-go/certimate/pkg/sdk3rd/qingcloud/dns" @@ -87,10 +88,10 @@ func NewDNSProviderConfig(config *Config) (*DNSProvider, error) { }, nil } -func (d *DNSProvider) Present(domain, token, keyAuth string) error { - info := dns01.GetChallengeInfo(domain, keyAuth) +func (d *DNSProvider) Present(ctx context.Context, domain, token, keyAuth string) error { + info := dns01.GetChallengeInfo(ctx, domain, keyAuth) - authZone, err := dns01.FindZoneByFqdn(info.EffectiveFQDN) + authZone, err := dns01.DefaultClient().FindZoneByFqdn(ctx, info.EffectiveFQDN) if err != nil { return fmt.Errorf("qingcloud: could not find zone for domain %q: %w", domain, err) } @@ -116,7 +117,7 @@ func (d *DNSProvider) Present(domain, token, keyAuth string) error { Mode: lo.ToPtr(int32(1)), AutoMerge: lo.ToPtr(int32(1)), } - response, err := d.client.CreateRecord(request) + response, err := d.client.CreateRecordWithContext(ctx, request) if err != nil { return fmt.Errorf("qingcloud: error when create record: %w", err) } @@ -128,8 +129,8 @@ func (d *DNSProvider) Present(domain, token, keyAuth string) error { return nil } -func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error { - info := dns01.GetChallengeInfo(domain, keyAuth) +func (d *DNSProvider) CleanUp(ctx context.Context, domain, token, keyAuth string) error { + info := dns01.GetChallengeInfo(ctx, domain, keyAuth) d.recordIDsMu.Lock() recordID, ok := d.recordIDs[token] @@ -139,7 +140,7 @@ func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error { } // REF: https://docsv4.qingcloud.com/user_guide/development_docs/api/api_list/dns/record/#_deleterecord - if _, err := d.client.DeleteRecord([]*int64{recordID}); err != nil { + if _, err := d.client.DeleteRecordWithContext(ctx, []*int64{recordID}); err != nil { return fmt.Errorf("qingcloud: error when delete record: %w", err) } diff --git a/pkg/core/certifier/challengers/dns01/rainyun/rainyun.go b/pkg/core/certifier/challengers/dns01/rainyun/rainyun.go index 2d8c57a14..962b38f31 100644 --- a/pkg/core/certifier/challengers/dns01/rainyun/rainyun.go +++ b/pkg/core/certifier/challengers/dns01/rainyun/rainyun.go @@ -4,7 +4,7 @@ import ( "fmt" "time" - "github.com/go-acme/lego/v4/providers/dns/rainyun" + "github.com/go-acme/lego/v5/providers/dns/rainyun" "github.com/certimate-go/certimate/pkg/core/certifier" ) diff --git a/pkg/core/certifier/challengers/dns01/rfc2136/rfc2136.go b/pkg/core/certifier/challengers/dns01/rfc2136/rfc2136.go index 3f4393464..709754c7f 100644 --- a/pkg/core/certifier/challengers/dns01/rfc2136/rfc2136.go +++ b/pkg/core/certifier/challengers/dns01/rfc2136/rfc2136.go @@ -6,7 +6,7 @@ import ( "strconv" "time" - "github.com/go-acme/lego/v4/providers/dns/rfc2136" + "github.com/go-acme/lego/v5/providers/dns/dnsupdate" "github.com/certimate-go/certimate/pkg/core/certifier" ) @@ -34,7 +34,7 @@ func NewChallenger(config *ChallengerConfig) (certifier.ACMEChallenger, error) { config.TsigAlgorithm = "hmac-sha1." } - providerConfig := rfc2136.NewDefaultConfig() + providerConfig := dnsupdate.NewDefaultConfig() providerConfig.Nameserver = net.JoinHostPort(config.Host, strconv.Itoa(int(config.Port))) providerConfig.TSIGAlgorithm = config.TsigAlgorithm providerConfig.TSIGKey = config.TsigKey @@ -46,7 +46,7 @@ func NewChallenger(config *ChallengerConfig) (certifier.ACMEChallenger, error) { providerConfig.TTL = config.DnsTTL } - provider, err := rfc2136.NewDNSProviderConfig(providerConfig) + provider, err := dnsupdate.NewDNSProviderConfig(providerConfig) if err != nil { return nil, err } diff --git a/pkg/core/certifier/challengers/dns01/spaceship/spaceship.go b/pkg/core/certifier/challengers/dns01/spaceship/spaceship.go index 4a059cbbf..b42fa569a 100644 --- a/pkg/core/certifier/challengers/dns01/spaceship/spaceship.go +++ b/pkg/core/certifier/challengers/dns01/spaceship/spaceship.go @@ -4,7 +4,7 @@ import ( "fmt" "time" - "github.com/go-acme/lego/v4/providers/dns/spaceship" + "github.com/go-acme/lego/v5/providers/dns/spaceship" "github.com/certimate-go/certimate/pkg/core/certifier" ) diff --git a/pkg/core/certifier/challengers/dns01/technitiumdns/technitiumdns.go b/pkg/core/certifier/challengers/dns01/technitiumdns/technitiumdns.go index 936295d19..1a957e536 100644 --- a/pkg/core/certifier/challengers/dns01/technitiumdns/technitiumdns.go +++ b/pkg/core/certifier/challengers/dns01/technitiumdns/technitiumdns.go @@ -5,7 +5,7 @@ import ( "fmt" "time" - "github.com/go-acme/lego/v4/providers/dns/technitium" + "github.com/go-acme/lego/v5/providers/dns/technitium" "github.com/certimate-go/certimate/pkg/core/certifier" xhttp "github.com/certimate-go/certimate/pkg/utils/http" diff --git a/pkg/core/certifier/challengers/dns01/tencentcloud-eo/tencentcloud_eo.go b/pkg/core/certifier/challengers/dns01/tencentcloud-eo/tencentcloud_eo.go index 636078d1d..ef1c4996c 100644 --- a/pkg/core/certifier/challengers/dns01/tencentcloud-eo/tencentcloud_eo.go +++ b/pkg/core/certifier/challengers/dns01/tencentcloud-eo/tencentcloud_eo.go @@ -4,7 +4,7 @@ import ( "fmt" "time" - "github.com/go-acme/lego/v4/providers/dns/edgeone" + "github.com/go-acme/lego/v5/providers/dns/edgeone" "github.com/certimate-go/certimate/pkg/core/certifier" ) diff --git a/pkg/core/certifier/challengers/dns01/tencentcloud/tencentcloud.go b/pkg/core/certifier/challengers/dns01/tencentcloud/tencentcloud.go index 4f299ab5c..3f57bcb32 100644 --- a/pkg/core/certifier/challengers/dns01/tencentcloud/tencentcloud.go +++ b/pkg/core/certifier/challengers/dns01/tencentcloud/tencentcloud.go @@ -4,7 +4,7 @@ import ( "fmt" "time" - "github.com/go-acme/lego/v4/providers/dns/tencentcloud" + "github.com/go-acme/lego/v5/providers/dns/tencentcloud" "github.com/certimate-go/certimate/pkg/core/certifier" ) diff --git a/pkg/core/certifier/challengers/dns01/todaynic/todaynic.go b/pkg/core/certifier/challengers/dns01/todaynic/todaynic.go index a34082119..7b3e3aee9 100644 --- a/pkg/core/certifier/challengers/dns01/todaynic/todaynic.go +++ b/pkg/core/certifier/challengers/dns01/todaynic/todaynic.go @@ -4,7 +4,7 @@ import ( "fmt" "time" - "github.com/go-acme/lego/v4/providers/dns/todaynic" + "github.com/go-acme/lego/v5/providers/dns/todaynic" "github.com/certimate-go/certimate/pkg/core/certifier" ) diff --git a/pkg/core/certifier/challengers/dns01/ucloud/ucloud.go b/pkg/core/certifier/challengers/dns01/ucloud/ucloud.go index 3eca9fc47..c94c0df11 100644 --- a/pkg/core/certifier/challengers/dns01/ucloud/ucloud.go +++ b/pkg/core/certifier/challengers/dns01/ucloud/ucloud.go @@ -4,7 +4,7 @@ import ( "fmt" "time" - "github.com/go-acme/lego/v4/providers/dns/ucloud" + "github.com/go-acme/lego/v5/providers/dns/ucloud" "github.com/certimate-go/certimate/pkg/core/certifier" ) diff --git a/pkg/core/certifier/challengers/dns01/vercel/vercel.go b/pkg/core/certifier/challengers/dns01/vercel/vercel.go index 3a7ac812a..938f249c9 100644 --- a/pkg/core/certifier/challengers/dns01/vercel/vercel.go +++ b/pkg/core/certifier/challengers/dns01/vercel/vercel.go @@ -4,7 +4,7 @@ import ( "fmt" "time" - "github.com/go-acme/lego/v4/providers/dns/vercel" + "github.com/go-acme/lego/v5/providers/dns/vercel" "github.com/certimate-go/certimate/pkg/core/certifier" ) diff --git a/pkg/core/certifier/challengers/dns01/volcengine/volcengine.go b/pkg/core/certifier/challengers/dns01/volcengine/volcengine.go index b697ee2a9..021486ea3 100644 --- a/pkg/core/certifier/challengers/dns01/volcengine/volcengine.go +++ b/pkg/core/certifier/challengers/dns01/volcengine/volcengine.go @@ -4,7 +4,7 @@ import ( "fmt" "time" - "github.com/go-acme/lego/v4/providers/dns/volcengine" + "github.com/go-acme/lego/v5/providers/dns/volcengine" "github.com/certimate-go/certimate/pkg/core/certifier" ) diff --git a/pkg/core/certifier/challengers/dns01/vultr/vultr.go b/pkg/core/certifier/challengers/dns01/vultr/vultr.go index b28856c7e..7bd4f2462 100644 --- a/pkg/core/certifier/challengers/dns01/vultr/vultr.go +++ b/pkg/core/certifier/challengers/dns01/vultr/vultr.go @@ -4,7 +4,7 @@ import ( "fmt" "time" - "github.com/go-acme/lego/v4/providers/dns/vultr" + "github.com/go-acme/lego/v5/providers/dns/vultr" "github.com/certimate-go/certimate/pkg/core/certifier" ) diff --git a/pkg/core/certifier/challengers/dns01/westcn/westcn.go b/pkg/core/certifier/challengers/dns01/westcn/westcn.go index cebf1a014..a2c64bb22 100644 --- a/pkg/core/certifier/challengers/dns01/westcn/westcn.go +++ b/pkg/core/certifier/challengers/dns01/westcn/westcn.go @@ -4,7 +4,7 @@ import ( "fmt" "time" - "github.com/go-acme/lego/v4/providers/dns/westcn" + "github.com/go-acme/lego/v5/providers/dns/westcn" "github.com/certimate-go/certimate/pkg/core/certifier" ) diff --git a/pkg/core/certifier/challengers/dns01/xinnet/internal/lego.go b/pkg/core/certifier/challengers/dns01/xinnet/internal/lego.go index a5b836ab2..bc90e47d0 100644 --- a/pkg/core/certifier/challengers/dns01/xinnet/internal/lego.go +++ b/pkg/core/certifier/challengers/dns01/xinnet/internal/lego.go @@ -1,13 +1,14 @@ package internal import ( + "context" "fmt" "sync" "time" - "github.com/go-acme/lego/v4/challenge" - "github.com/go-acme/lego/v4/challenge/dns01" - "github.com/go-acme/lego/v4/platform/config/env" + "github.com/go-acme/lego/v5/challenge" + "github.com/go-acme/lego/v5/challenge/dns01" + "github.com/go-acme/lego/v5/platform/env" "github.com/samber/lo" xinnetsdk "github.com/certimate-go/certimate/pkg/sdk3rd/xinnet" @@ -87,10 +88,10 @@ func NewDNSProviderConfig(config *Config) (*DNSProvider, error) { }, nil } -func (d *DNSProvider) Present(domain, token, keyAuth string) error { - info := dns01.GetChallengeInfo(domain, keyAuth) +func (d *DNSProvider) Present(ctx context.Context, domain, token, keyAuth string) error { + info := dns01.GetChallengeInfo(ctx, domain, keyAuth) - authZone, err := dns01.FindZoneByFqdn(info.EffectiveFQDN) + authZone, err := dns01.DefaultClient().FindZoneByFqdn(ctx, info.EffectiveFQDN) if err != nil { return fmt.Errorf("xinnet: could not find zone for domain %q: %w", domain, err) } @@ -104,7 +105,7 @@ func (d *DNSProvider) Present(domain, token, keyAuth string) error { Line: lo.ToPtr("默认"), Ttl: lo.ToPtr(int32(d.config.TTL)), } - response, err := d.client.DnsCreate(request) + response, err := d.client.DnsCreateWithContext(ctx, request) if err != nil { return fmt.Errorf("xinnet: error when create record: %w", err) } @@ -116,10 +117,10 @@ func (d *DNSProvider) Present(domain, token, keyAuth string) error { return nil } -func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error { - info := dns01.GetChallengeInfo(domain, keyAuth) +func (d *DNSProvider) CleanUp(ctx context.Context, domain, token, keyAuth string) error { + info := dns01.GetChallengeInfo(ctx, domain, keyAuth) - authZone, err := dns01.FindZoneByFqdn(info.EffectiveFQDN) + authZone, err := dns01.DefaultClient().FindZoneByFqdn(ctx, info.EffectiveFQDN) if err != nil { return fmt.Errorf("xinnet: could not find zone for domain %q: %w", domain, err) } @@ -136,7 +137,7 @@ func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error { DomainName: lo.ToPtr(dns01.UnFqdn(authZone)), RecordId: recordID, } - if _, err := d.client.DnsDelete(request); err != nil { + if _, err := d.client.DnsDeleteWithContext(ctx, request); err != nil { return fmt.Errorf("xinnet: error when delete record: %w", err) } diff --git a/pkg/core/certifier/challengers/http01/ftp/ftp.go b/pkg/core/certifier/challengers/http01/ftp/ftp.go index b1f743722..40ce2d2cc 100644 --- a/pkg/core/certifier/challengers/http01/ftp/ftp.go +++ b/pkg/core/certifier/challengers/http01/ftp/ftp.go @@ -5,7 +5,7 @@ import ( "fmt" "path/filepath" - "github.com/go-acme/lego/v4/challenge/http01" + "github.com/go-acme/lego/v5/challenge/http01" "github.com/certimate-go/certimate/internal/tools/ftp" "github.com/certimate-go/certimate/pkg/core/certifier" @@ -38,9 +38,7 @@ type provider struct { config *ChallengerConfig } -func (p *provider) Present(domain, token, keyAuth string) error { - ctx := context.Background() - +func (p *provider) Present(ctx context.Context, domain, token, keyAuth string) error { client, err := createFtpClient(*p.config) if err != nil { return fmt.Errorf("ftp: failed to create FTP client: %w", err) @@ -64,9 +62,7 @@ func (p *provider) Present(domain, token, keyAuth string) error { return nil } -func (p *provider) CleanUp(domain, token, keyAuth string) error { - ctx := context.Background() - +func (p *provider) CleanUp(ctx context.Context, domain, token, keyAuth string) error { client, err := createFtpClient(*p.config) if err != nil { return fmt.Errorf("ftp: failed to create FTP client: %w", err) diff --git a/pkg/core/certifier/challengers/http01/local/local.go b/pkg/core/certifier/challengers/http01/local/local.go index d2827e1cb..7b8a0ea7c 100644 --- a/pkg/core/certifier/challengers/http01/local/local.go +++ b/pkg/core/certifier/challengers/http01/local/local.go @@ -3,7 +3,7 @@ package local import ( "fmt" - "github.com/go-acme/lego/v4/providers/http/webroot" + "github.com/go-acme/lego/v5/providers/http/webroot" "github.com/certimate-go/certimate/pkg/core/certifier" ) diff --git a/pkg/core/certifier/challengers/http01/s3/s3.go b/pkg/core/certifier/challengers/http01/s3/s3.go index 9b78526ea..c39263b00 100644 --- a/pkg/core/certifier/challengers/http01/s3/s3.go +++ b/pkg/core/certifier/challengers/http01/s3/s3.go @@ -5,7 +5,7 @@ import ( "fmt" "strings" - "github.com/go-acme/lego/v4/challenge/http01" + "github.com/go-acme/lego/v5/challenge/http01" "github.com/certimate-go/certimate/internal/tools/s3" "github.com/certimate-go/certimate/pkg/core/certifier" @@ -51,18 +51,18 @@ type provider struct { bucket string } -func (p *provider) Present(domain, token, keyAuth string) error { +func (p *provider) Present(ctx context.Context, domain, token, keyAuth string) error { objectKey := strings.Trim(http01.ChallengePath(token), "/") - if err := p.client.PutObjectString(context.Background(), p.bucket, objectKey, keyAuth); err != nil { + if err := p.client.PutObjectString(ctx, p.bucket, objectKey, keyAuth); err != nil { return fmt.Errorf("s3: failed to upload file for HTTP challenge: %w", err) } return nil } -func (p *provider) CleanUp(domain, token, keyAuth string) error { +func (p *provider) CleanUp(ctx context.Context, domain, token, keyAuth string) error { objectKey := strings.Trim(http01.ChallengePath(token), "/") - if err := p.client.RemoveObject(context.Background(), p.bucket, objectKey); err != nil { + if err := p.client.RemoveObject(ctx, p.bucket, objectKey); err != nil { return fmt.Errorf("s3: failed to remove file after HTTP challenge: %w", err) } diff --git a/pkg/core/certifier/challengers/http01/ssh/ssh.go b/pkg/core/certifier/challengers/http01/ssh/ssh.go index 27da88d20..355253c15 100644 --- a/pkg/core/certifier/challengers/http01/ssh/ssh.go +++ b/pkg/core/certifier/challengers/http01/ssh/ssh.go @@ -1,10 +1,11 @@ package ssh import ( + "context" "fmt" "path/filepath" - "github.com/go-acme/lego/v4/challenge/http01" + "github.com/go-acme/lego/v5/challenge/http01" "github.com/certimate-go/certimate/internal/tools/ssh" "github.com/certimate-go/certimate/pkg/core/certifier" @@ -56,7 +57,7 @@ type provider struct { config *ChallengerConfig } -func (p *provider) Present(domain, token, keyAuth string) error { +func (p *provider) Present(ctx context.Context, domain, token, keyAuth string) error { client, err := createSshClient(*p.config) if err != nil { return fmt.Errorf("ssh: failed to create SSH client: %w", err) @@ -72,7 +73,7 @@ func (p *provider) Present(domain, token, keyAuth string) error { return nil } -func (p *provider) CleanUp(domain, token, keyAuth string) error { +func (p *provider) CleanUp(ctx context.Context, domain, token, keyAuth string) error { client, err := createSshClient(*p.config) if err != nil { return fmt.Errorf("ssh: failed to create SSH client: %w", err) diff --git a/pkg/logging/handler.go b/pkg/logging/handler_hook.go similarity index 92% rename from pkg/logging/handler.go rename to pkg/logging/handler_hook.go index e3c8bc306..8734f3671 100644 --- a/pkg/logging/handler.go +++ b/pkg/logging/handler_hook.go @@ -15,19 +15,21 @@ var _ slog.Handler = (*HookHandler)(nil) type HookHandler struct { mutex *sync.Mutex + base slog.Handler parent *HookHandler options *HookHandlerOptions group string attrs []slog.Attr } -func NewHookHandler(opts *HookHandlerOptions) *HookHandler { +func NewHookHandler(handler slog.Handler, opts *HookHandlerOptions) *HookHandler { if opts == nil { opts = &HookHandlerOptions{} } h := &HookHandler{ mutex: &sync.Mutex{}, + base: handler, options: opts, } @@ -100,6 +102,10 @@ func (h *HookHandler) Handle(ctx context.Context, r slog.Record) error { return h.parent.Handle(ctx, r) } + if h.base != nil { + h.base.Handle(ctx, r) + } + if err := h.writeRecord(ctx, Record{Record: r}); err != nil { return err } diff --git a/pkg/logging/handler_named.go b/pkg/logging/handler_named.go new file mode 100644 index 000000000..e1a8fc40f --- /dev/null +++ b/pkg/logging/handler_named.go @@ -0,0 +1,47 @@ +package logging + +import ( + "context" + "log/slog" +) + +var _ slog.Handler = (*NamedHandler)(nil) + +type NamedHandler struct { + handler slog.Handler + namespace string +} + +func NewNamedHandler(handler slog.Handler, namespace string) *NamedHandler { + h := &NamedHandler{ + handler: handler, + namespace: namespace, + } + + return h +} + +func (h *NamedHandler) Enabled(ctx context.Context, level slog.Level) bool { + return h.handler.Enabled(ctx, level) +} + +func (h *NamedHandler) WithAttrs(attrs []slog.Attr) slog.Handler { + return &NamedHandler{ + namespace: h.namespace, + handler: h.handler.WithAttrs(attrs), + } +} + +func (h *NamedHandler) WithGroup(name string) slog.Handler { + return &NamedHandler{ + namespace: h.namespace, + handler: h.handler.WithGroup(name), + } +} + +func (h *NamedHandler) Handle(ctx context.Context, r slog.Record) error { + if h.namespace != "" { + r.Message = h.namespace + ": " + r.Message + } + return h.handler.Handle(ctx, r) +} diff --git a/pkg/utils/cert/parser.go b/pkg/utils/cert/parser.go index 1202db39a..90217472d 100644 --- a/pkg/utils/cert/parser.go +++ b/pkg/utils/cert/parser.go @@ -4,7 +4,7 @@ import ( "crypto" "crypto/x509" - "github.com/go-acme/lego/v4/certcrypto" + "github.com/go-acme/lego/v5/certcrypto" ) // 从 PEM 编码的证书字符串解析并返回一个 x509.Certificate 对象。