From 35c1c2e97aec14c9c09b3bac272f42a76552358a Mon Sep 17 00:00:00 2001 From: Fu Diwei Date: Thu, 22 Jan 2026 21:21:16 +0800 Subject: [PATCH] refactor: clean code --- internal/tools/s3/client.go | 122 +++++++++--------- internal/tools/s3/config.go | 26 ++++ .../certifier/challengers/http01/s3/s3.go | 30 +++-- pkg/core/deployer/providers/s3/s3.go | 30 +++-- ui/src/i18n/locales/zh/nls.access.json | 4 +- 5 files changed, 127 insertions(+), 85 deletions(-) create mode 100644 internal/tools/s3/config.go diff --git a/internal/tools/s3/client.go b/internal/tools/s3/client.go index 25e06dc2e..3a6d2f4bc 100644 --- a/internal/tools/s3/client.go +++ b/internal/tools/s3/client.go @@ -3,7 +3,6 @@ import ( "bytes" "context" - "errors" "fmt" "io" "regexp" @@ -17,84 +16,30 @@ import ( xtls "github.com/certimate-go/certimate/pkg/utils/tls" ) -const ( - SignatureV2 = "v2" - SignatureV4 = "v4" -) - -type Config struct { - Endpoint string - AccessKey string - SecretKey string - SignatureVersion string // 默认值 "v4" - UsePathStyle bool - Region string - SkipTlsVerify bool -} - type Client struct { - client *minio.Client + cli *minio.Client } func NewClient(config *Config) (*Client, error) { if config == nil { - return nil, errors.New("the configuration of S3 client is nil") + return nil, fmt.Errorf("the configuration of S3 client is nil") } - var clientCred *credentials.Credentials - switch config.SignatureVersion { - case "", SignatureV4: - clientCred = credentials.NewStaticV4(config.AccessKey, config.SecretKey, "") - case SignatureV2: - clientCred = credentials.NewStaticV2(config.AccessKey, config.SecretKey, "") - default: - return nil, fmt.Errorf("unsupported S3 signature version: '%s'", config.SignatureVersion) - } - - var clientOpts *minio.Options - clientOpts = &minio.Options{ - Creds: clientCred, - Region: config.Region, - BucketLookup: lo.If(config.UsePathStyle, minio.BucketLookupPath).Else(minio.BucketLookupDNS), - } - - var endpoint string - if config.Endpoint != "" { - reScheme := regexp.MustCompile("^([^:]+)://") - if reScheme.MatchString(config.Endpoint) { - temp := strings.Split(config.Endpoint, "://") - scheme := temp[0] - endpoint = temp[1] - clientOpts.Secure = strings.EqualFold(scheme, "https") - } else { - endpoint = config.Endpoint - clientOpts.Secure = true - } - } - - if clientOpts.Secure && config.SkipTlsVerify { - transport := xhttp.NewDefaultTransport() - transport.TLSClientConfig = xtls.NewInsecureConfig() - clientOpts.Transport = transport - } - - client, err := minio.New(endpoint, clientOpts) + client, err := createS3Client(config) if err != nil { return nil, err } - return &Client{ - client: client, - }, nil + return &Client{cli: client}, nil } func (c *Client) PutObject(ctx context.Context, bucket, key string, reader io.Reader, size int64) error { putOpts := minio.PutObjectOptions{ DisableMultipart: true, } - _, err := c.client.PutObject(ctx, bucket, key, reader, size, putOpts) + _, err := c.cli.PutObject(ctx, bucket, key, reader, size, putOpts) if err != nil { - return err + return fmt.Errorf("s3: failed to put object: %w", err) } return nil @@ -112,10 +57,61 @@ func (c *Client) PutObjectBytes(ctx context.Context, bucket, key string, data [] func (c *Client) RemoveObject(ctx context.Context, bucket, key string) error { removeOpts := minio.RemoveObjectOptions{} - err := c.client.RemoveObject(ctx, bucket, key, removeOpts) + err := c.cli.RemoveObject(ctx, bucket, key, removeOpts) if err != nil { - return err + return fmt.Errorf("s3: failed to remove object: %w", err) } return nil } + +func createS3Client(config *Config) (*minio.Client, error) { + var clientCred *credentials.Credentials + switch config.SignatureVersion { + case "", SignatureV4: + clientCred = credentials.NewStaticV4(config.AccessKey, config.SecretKey, "") + case SignatureV2: + clientCred = credentials.NewStaticV2(config.AccessKey, config.SecretKey, "") + default: + return nil, fmt.Errorf("s3: unsupported signature version: '%s'", config.SignatureVersion) + } + + endpoint, secure := resolveEndpoint(config.Endpoint) + clientOpts := &minio.Options{ + Creds: clientCred, + Region: config.Region, + BucketLookup: lo.If(config.UsePathStyle, minio.BucketLookupPath).Else(minio.BucketLookupDNS), + Secure: secure, + } + + if secure && config.SkipTlsVerify { + transport := xhttp.NewDefaultTransport() + transport.TLSClientConfig = xtls.NewInsecureConfig() + clientOpts.Transport = transport + } + + client, err := minio.New(endpoint, clientOpts) + if err != nil { + return nil, fmt.Errorf("s3: %w", err) + } + + return client, nil +} + +func resolveEndpoint(endpoint string) (string, bool) { + var secure bool + var result string + + reScheme := regexp.MustCompile("^([^:]+)://") + if reScheme.MatchString(endpoint) { + temp := strings.Split(endpoint, "://") + scheme := temp[0] + result = temp[1] + secure = strings.EqualFold(scheme, "https") + } else { + result = endpoint + secure = true + } + + return result, secure +} diff --git a/internal/tools/s3/config.go b/internal/tools/s3/config.go new file mode 100644 index 000000000..9a26743c2 --- /dev/null +++ b/internal/tools/s3/config.go @@ -0,0 +1,26 @@ +package s3 + +const ( + SignatureV2 = "v2" + SignatureV4 = "v4" +) + +const ( + defaultSignatureVersion = SignatureV4 +) + +type Config struct { + Endpoint string + AccessKey string + SecretKey string + SignatureVersion string + UsePathStyle bool + Region string + SkipTlsVerify bool +} + +func NewDefaultConfig() *Config { + return &Config{ + SignatureVersion: defaultSignatureVersion, + } +} diff --git a/pkg/core/certifier/challengers/http01/s3/s3.go b/pkg/core/certifier/challengers/http01/s3/s3.go index 79abd2fd1..f3dc9f83e 100644 --- a/pkg/core/certifier/challengers/http01/s3/s3.go +++ b/pkg/core/certifier/challengers/http01/s3/s3.go @@ -38,17 +38,9 @@ func NewChallenger(config *ChallengerConfig) (certifier.ACMEChallenger, error) { return nil, errors.New("the configuration of the acme challenge provider is nil") } - client, err := s3.NewClient(&s3.Config{ - Endpoint: config.Endpoint, - AccessKey: config.AccessKey, - SecretKey: config.SecretKey, - SignatureVersion: config.SignatureVersion, - UsePathStyle: config.UsePathStyle, - Region: config.Region, - SkipTlsVerify: config.AllowInsecureConnections, - }) + client, err := createS3Client(*config) if err != nil { - return nil, fmt.Errorf("s3: failed to create s3 client: %w", err) + return nil, fmt.Errorf("s3: failed to create S3 client: %w", err) } provider := &provider{client: client, bucket: config.Bucket} @@ -77,3 +69,21 @@ func (p *provider) CleanUp(domain, token, keyAuth string) error { return nil } + +func createS3Client(config ChallengerConfig) (*s3.Client, error) { + clientCfg := s3.NewDefaultConfig() + clientCfg.Endpoint = config.Endpoint + clientCfg.AccessKey = config.AccessKey + clientCfg.SecretKey = config.SecretKey + clientCfg.SignatureVersion = config.SignatureVersion + clientCfg.UsePathStyle = config.UsePathStyle + clientCfg.Region = config.Region + clientCfg.SkipTlsVerify = config.AllowInsecureConnections + + client, err := s3.NewClient(clientCfg) + if err != nil { + return nil, err + } + + return client, err +} diff --git a/pkg/core/deployer/providers/s3/s3.go b/pkg/core/deployer/providers/s3/s3.go index 1760f8ce3..03a940e97 100644 --- a/pkg/core/deployer/providers/s3/s3.go +++ b/pkg/core/deployer/providers/s3/s3.go @@ -69,17 +69,9 @@ func NewDeployer(config *DeployerConfig) (*Deployer, error) { return nil, errors.New("the configuration of the deployer provider is nil") } - client, err := s3.NewClient(&s3.Config{ - Endpoint: config.Endpoint, - AccessKey: config.AccessKey, - SecretKey: config.SecretKey, - SignatureVersion: config.SignatureVersion, - UsePathStyle: config.UsePathStyle, - Region: config.Region, - SkipTlsVerify: config.AllowInsecureConnections, - }) + client, err := createS3Client(*config) if err != nil { - return nil, fmt.Errorf("s3: failed to create s3 client: %w", err) + return nil, fmt.Errorf("s3: failed to create S3 client: %w", err) } return &Deployer{ @@ -167,3 +159,21 @@ func (d *Deployer) Deploy(ctx context.Context, certPEM, privkeyPEM string) (*dep return &deployer.DeployResult{}, nil } + +func createS3Client(config DeployerConfig) (*s3.Client, error) { + clientCfg := s3.NewDefaultConfig() + clientCfg.Endpoint = config.Endpoint + clientCfg.AccessKey = config.AccessKey + clientCfg.SecretKey = config.SecretKey + clientCfg.SignatureVersion = config.SignatureVersion + clientCfg.UsePathStyle = config.UsePathStyle + clientCfg.Region = config.Region + clientCfg.SkipTlsVerify = config.AllowInsecureConnections + + client, err := s3.NewClient(clientCfg) + if err != nil { + return nil, err + } + + return client, err +} diff --git a/ui/src/i18n/locales/zh/nls.access.json b/ui/src/i18n/locales/zh/nls.access.json index 5595b8317..19c0021bb 100644 --- a/ui/src/i18n/locales/zh/nls.access.json +++ b/ui/src/i18n/locales/zh/nls.access.json @@ -556,8 +556,8 @@ "access.form.rfc2136_tsig_key.placeholder": "请输入 TSIG 认证密钥 Key", "access.form.rfc2136_tsig_secret.label": "TSIG 认证密钥 Secret(可选)", "access.form.rfc2136_tsig_secret.placeholder": "请输入 TSIG 认证密钥 Secret", - "access.form.s3_endpoint.label": "服务端点", - "access.form.s3_endpoint.placeholder": "请输入服务端点", + "access.form.s3_endpoint.label": "终端节点", + "access.form.s3_endpoint.placeholder": "请输入终端节点", "access.form.s3_endpoint.help": "注意:如果不指定协议,则默认使用 https://。", "access.form.s3_access_key.label": "AccessKey", "access.form.s3_access_key.placeholder": "请输入 AccessKey",