优化结构
This commit is contained in:
@@ -13,18 +13,16 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"kra/internal/conf"
|
||||
"kra/internal/config"
|
||||
)
|
||||
|
||||
type emailRepo struct {
|
||||
runtime *conf.Runtime
|
||||
}
|
||||
type emailRepo struct{ runtime *config.Store }
|
||||
|
||||
func NewEmailRepo(runtime *conf.Runtime) system.EmailRepo {
|
||||
func NewEmailRepo(runtime *config.Store) system.EmailRepo {
|
||||
return &emailRepo{runtime: runtime}
|
||||
}
|
||||
|
||||
func (r *emailRepo) email() *conf.AdminBackend_Email {
|
||||
func (r *emailRepo) email() *config.Email {
|
||||
if r.runtime == nil {
|
||||
return nil
|
||||
}
|
||||
@@ -47,7 +45,7 @@ func (r *emailRepo) DefaultRecipients() []string {
|
||||
return []string{strings.TrimSpace(config.To)}
|
||||
}
|
||||
|
||||
func emailEnabled(config *conf.AdminBackend_Email) bool {
|
||||
func emailEnabled(config *config.Email) bool {
|
||||
return config != nil && strings.TrimSpace(config.Host) != "" &&
|
||||
strings.TrimSpace(config.From) != "" && strings.TrimSpace(config.Secret) != "" && config.Port > 0
|
||||
}
|
||||
@@ -82,7 +80,7 @@ func (r *emailRepo) Send(ctx context.Context, to []string, subject, body string)
|
||||
dialer := &net.Dialer{Timeout: 10 * time.Second}
|
||||
var conn net.Conn
|
||||
var err error
|
||||
if config.IsSsl {
|
||||
if config.IsSSL {
|
||||
conn, err = (&tls.Dialer{NetDialer: dialer, Config: &tls.Config{ServerName: config.Host, MinVersion: tls.VersionTLS12}}).DialContext(ctx, "tcp", address)
|
||||
} else {
|
||||
conn, err = dialer.DialContext(ctx, "tcp", address)
|
||||
|
||||
@@ -4,11 +4,11 @@ import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"kra/internal/conf"
|
||||
"kra/internal/config"
|
||||
)
|
||||
|
||||
func TestDefaultRecipientsIgnoreEmptyConfiguration(t *testing.T) {
|
||||
runtime := conf.NewRuntime(&conf.Data{}, &conf.AdminBackend{Email: &conf.AdminBackend_Email{To: " "}})
|
||||
runtime := config.NewStore(&config.Config{Data: &config.Data{}, Admin: &config.Admin{Email: &config.Email{To: " "}}})
|
||||
repo := &emailRepo{runtime: runtime}
|
||||
if got := repo.DefaultRecipients(); len(got) != 0 {
|
||||
t.Fatalf("DefaultRecipients() = %#v, want empty", got)
|
||||
@@ -16,7 +16,7 @@ func TestDefaultRecipientsIgnoreEmptyConfiguration(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestSendRejectsEmptyRecipientsBeforeNetworkDial(t *testing.T) {
|
||||
runtime := conf.NewRuntime(&conf.Data{}, &conf.AdminBackend{Email: &conf.AdminBackend_Email{Host: "smtp.example.com", From: "from@example.com", Secret: "secret", Port: 25}})
|
||||
runtime := config.NewStore(&config.Config{Data: &config.Data{}, Admin: &config.Admin{Email: &config.Email{Host: "smtp.example.com", From: "from@example.com", Secret: "secret", Port: 25}}})
|
||||
repo := &emailRepo{runtime: runtime}
|
||||
if err := repo.Send(context.Background(), []string{" ", ""}, "subject", "body"); err == nil {
|
||||
t.Fatal("Send() accepted empty recipients")
|
||||
|
||||
@@ -8,7 +8,7 @@ import (
|
||||
"path"
|
||||
"strings"
|
||||
|
||||
"kra/internal/conf"
|
||||
"kra/internal/config"
|
||||
|
||||
"github.com/aliyun/aliyun-oss-go-sdk/oss"
|
||||
)
|
||||
@@ -18,7 +18,7 @@ type aliyunStorage struct {
|
||||
baseURL, prefix string
|
||||
}
|
||||
|
||||
func newAliyunStorage(config *conf.AdminBackend_ObjectStore) (system.FileStorage, error) {
|
||||
func newAliyunStorage(config *config.ObjectStore) (system.FileStorage, error) {
|
||||
if config == nil || config.Endpoint == "" || config.Bucket == "" || config.AccessKey == "" || config.SecretKey == "" {
|
||||
return nil, fmt.Errorf("aliyun-oss storage configuration is incomplete")
|
||||
}
|
||||
@@ -30,7 +30,7 @@ func newAliyunStorage(config *conf.AdminBackend_ObjectStore) (system.FileStorage
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &aliyunStorage{bucket: bucket, baseURL: strings.TrimSuffix(config.BaseUrl, "/"), prefix: strings.Trim(config.PathPrefix, "/")}, nil
|
||||
return &aliyunStorage{bucket: bucket, baseURL: strings.TrimSuffix(config.BaseURL, "/"), prefix: strings.Trim(config.PathPrefix, "/")}, nil
|
||||
}
|
||||
func (s *aliyunStorage) key(name string) string {
|
||||
if s.prefix == "" {
|
||||
|
||||
@@ -8,7 +8,7 @@ import (
|
||||
"path"
|
||||
"strings"
|
||||
|
||||
"kra/internal/conf"
|
||||
"kra/internal/config"
|
||||
|
||||
"github.com/aws/aws-sdk-go-v2/aws"
|
||||
awsconfig "github.com/aws/aws-sdk-go-v2/config"
|
||||
@@ -22,7 +22,7 @@ type awsStorage struct {
|
||||
bucket, baseURL, prefix string
|
||||
}
|
||||
|
||||
func newAWSStorage(provider string, config *conf.AdminBackend_ObjectStore) (system.FileStorage, error) {
|
||||
func newAWSStorage(provider string, config *config.ObjectStore) (system.FileStorage, error) {
|
||||
if config == nil || config.Bucket == "" || config.AccessKey == "" || config.SecretKey == "" {
|
||||
return nil, fmt.Errorf("%s storage configuration is incomplete", provider)
|
||||
}
|
||||
@@ -31,10 +31,10 @@ func newAWSStorage(provider string, config *conf.AdminBackend_ObjectStore) (syst
|
||||
if provider == "cloudflare-r2" {
|
||||
region = "auto"
|
||||
if endpoint == "" {
|
||||
if config.AccountId == "" {
|
||||
if config.AccountID == "" {
|
||||
return nil, fmt.Errorf("cloudflare-r2 account id is required")
|
||||
}
|
||||
endpoint = fmt.Sprintf("https://%s.r2.cloudflarestorage.com", config.AccountId)
|
||||
endpoint = fmt.Sprintf("https://%s.r2.cloudflarestorage.com", config.AccountID)
|
||||
}
|
||||
}
|
||||
if region == "" {
|
||||
@@ -47,7 +47,7 @@ func newAWSStorage(provider string, config *conf.AdminBackend_ObjectStore) (syst
|
||||
client := s3.NewFromConfig(loaded, func(options *s3.Options) {
|
||||
if endpoint != "" {
|
||||
if !strings.HasPrefix(endpoint, "http://") && !strings.HasPrefix(endpoint, "https://") {
|
||||
if config.UseSsl {
|
||||
if config.UseSSL {
|
||||
endpoint = "https://" + endpoint
|
||||
} else {
|
||||
endpoint = "http://" + endpoint
|
||||
@@ -57,7 +57,7 @@ func newAWSStorage(provider string, config *conf.AdminBackend_ObjectStore) (syst
|
||||
}
|
||||
options.UsePathStyle = config.ForcePathStyle
|
||||
})
|
||||
return &awsStorage{client: client, bucket: config.Bucket, baseURL: strings.TrimSuffix(config.BaseUrl, "/"), prefix: strings.Trim(config.PathPrefix, "/")}, nil
|
||||
return &awsStorage{client: client, bucket: config.Bucket, baseURL: strings.TrimSuffix(config.BaseURL, "/"), prefix: strings.Trim(config.PathPrefix, "/")}, nil
|
||||
}
|
||||
|
||||
func (s *awsStorage) key(name string) string {
|
||||
|
||||
@@ -8,7 +8,7 @@ import (
|
||||
"path"
|
||||
"strings"
|
||||
|
||||
"kra/internal/conf"
|
||||
"kra/internal/config"
|
||||
|
||||
"github.com/huaweicloud/huaweicloud-sdk-go-obs/obs"
|
||||
)
|
||||
@@ -18,7 +18,7 @@ type huaweiStorage struct {
|
||||
bucket, baseURL, prefix string
|
||||
}
|
||||
|
||||
func newHuaweiStorage(config *conf.AdminBackend_ObjectStore) (system.FileStorage, error) {
|
||||
func newHuaweiStorage(config *config.ObjectStore) (system.FileStorage, error) {
|
||||
if config == nil || config.Endpoint == "" || config.Bucket == "" || config.AccessKey == "" || config.SecretKey == "" {
|
||||
return nil, fmt.Errorf("huawei-obs storage configuration is incomplete")
|
||||
}
|
||||
@@ -26,7 +26,7 @@ func newHuaweiStorage(config *conf.AdminBackend_ObjectStore) (system.FileStorage
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &huaweiStorage{client: client, bucket: config.Bucket, baseURL: strings.TrimSuffix(config.BaseUrl, "/"), prefix: strings.Trim(config.PathPrefix, "/")}, nil
|
||||
return &huaweiStorage{client: client, bucket: config.Bucket, baseURL: strings.TrimSuffix(config.BaseURL, "/"), prefix: strings.Trim(config.PathPrefix, "/")}, nil
|
||||
}
|
||||
func (s *huaweiStorage) key(name string) string {
|
||||
if s.prefix == "" {
|
||||
|
||||
@@ -11,7 +11,7 @@ import (
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"kra/internal/conf"
|
||||
"kra/internal/config"
|
||||
)
|
||||
|
||||
type fileStorage struct {
|
||||
@@ -19,41 +19,41 @@ type fileStorage struct {
|
||||
urlPrefix string
|
||||
}
|
||||
|
||||
func New(config *conf.AdminBackend) (system.FileStorage, error) {
|
||||
func New(admin *config.Admin) (system.FileStorage, error) {
|
||||
storageType := "local"
|
||||
if config != nil && config.Storage != nil && config.Storage.Type != "" {
|
||||
storageType = strings.ToLower(config.Storage.Type)
|
||||
if admin != nil && admin.Storage != nil && admin.Storage.Type != "" {
|
||||
storageType = strings.ToLower(admin.Storage.Type)
|
||||
}
|
||||
if storageType == "qiniu" {
|
||||
return newQiniuStorage(config.Storage.Qiniu)
|
||||
return newQiniuStorage(admin.Storage.Qiniu)
|
||||
}
|
||||
if storageType != "local" {
|
||||
var object *conf.AdminBackend_ObjectStore
|
||||
var object *config.ObjectStore
|
||||
switch storageType {
|
||||
case "aliyun-oss":
|
||||
return newAliyunStorage(config.Storage.AliyunOss)
|
||||
return newAliyunStorage(admin.Storage.AliyunOSS)
|
||||
case "huawei-obs":
|
||||
return newHuaweiStorage(config.Storage.HuaweiObs)
|
||||
return newHuaweiStorage(admin.Storage.HuaweiOBS)
|
||||
case "tencent-cos":
|
||||
return newTencentStorage(config.Storage.TencentCos)
|
||||
return newTencentStorage(admin.Storage.TencentCOS)
|
||||
case "aws-s3":
|
||||
return newAWSStorage(storageType, config.Storage.AwsS3)
|
||||
return newAWSStorage(storageType, admin.Storage.AWSS3)
|
||||
case "cloudflare-r2":
|
||||
return newAWSStorage(storageType, config.Storage.CloudflareR2)
|
||||
return newAWSStorage(storageType, admin.Storage.CloudflareR2)
|
||||
case "minio":
|
||||
object = config.Storage.Minio
|
||||
object = admin.Storage.Minio
|
||||
default:
|
||||
return nil, fmt.Errorf("unsupported storage type %q", storageType)
|
||||
}
|
||||
return newS3Storage(storageType, object)
|
||||
}
|
||||
root, prefix := "uploads/file", "uploads/file"
|
||||
if config != nil && config.Local != nil {
|
||||
if config.Local.StorePath != "" {
|
||||
root = config.Local.StorePath
|
||||
if admin != nil && admin.Local != nil {
|
||||
if admin.Local.StorePath != "" {
|
||||
root = admin.Local.StorePath
|
||||
}
|
||||
if config.Local.PathPrefix != "" {
|
||||
prefix = config.Local.PathPrefix
|
||||
if admin.Local.PathPrefix != "" {
|
||||
prefix = admin.Local.PathPrefix
|
||||
}
|
||||
}
|
||||
root = filepath.Clean(root)
|
||||
|
||||
@@ -11,24 +11,24 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"kra/internal/conf"
|
||||
"kra/internal/config"
|
||||
|
||||
"github.com/qiniu/go-sdk/v7/auth/qbox"
|
||||
qstorage "github.com/qiniu/go-sdk/v7/storage"
|
||||
)
|
||||
|
||||
type qiniuStorage struct {
|
||||
config *conf.AdminBackend_Qiniu
|
||||
config *config.Qiniu
|
||||
upload *qstorage.FormUploader
|
||||
manager *qstorage.BucketManager
|
||||
mac *qbox.Mac
|
||||
}
|
||||
|
||||
func newQiniuStorage(config *conf.AdminBackend_Qiniu) (system.FileStorage, error) {
|
||||
func newQiniuStorage(config *config.Qiniu) (system.FileStorage, error) {
|
||||
if config == nil || config.Bucket == "" || config.AccessKey == "" || config.SecretKey == "" {
|
||||
return nil, fmt.Errorf("qiniu storage configuration is incomplete")
|
||||
}
|
||||
cfg := qstorage.Config{UseHTTPS: config.UseHttps, UseCdnDomains: config.UseCdnDomains}
|
||||
cfg := qstorage.Config{UseHTTPS: config.UseHTTPS, UseCdnDomains: config.UseCDNDomains}
|
||||
switch config.Zone {
|
||||
case "ZoneHuadong":
|
||||
cfg.Zone = &qstorage.ZoneHuadong
|
||||
@@ -51,7 +51,7 @@ func (s *qiniuStorage) uploadToken() string {
|
||||
}
|
||||
|
||||
func (s *qiniuStorage) file(key string, size int64) *system.StoredFile {
|
||||
return &system.StoredFile{Name: path.Base(key), Path: key, URL: strings.TrimSuffix(s.config.BaseUrl, "/") + "/" + key, Size: size}
|
||||
return &system.StoredFile{Name: path.Base(key), Path: key, URL: strings.TrimSuffix(s.config.BaseURL, "/") + "/" + key, Size: size}
|
||||
}
|
||||
func (s *qiniuStorage) Put(ctx context.Context, name string, reader io.Reader) (*system.StoredFile, error) {
|
||||
temporary, err := os.CreateTemp("", "kra-qiniu-upload-*")
|
||||
@@ -77,7 +77,7 @@ func (s *qiniuStorage) Put(ctx context.Context, name string, reader io.Reader) (
|
||||
return s.file(ret.Key, size), nil
|
||||
}
|
||||
func (s *qiniuStorage) Open(ctx context.Context, name string) (io.ReadCloser, error) {
|
||||
downloadURL := qstorage.MakePrivateURL(s.mac, strings.TrimSuffix(s.config.BaseUrl, "/"), strings.TrimPrefix(name, "/"), time.Now().Add(time.Hour).Unix())
|
||||
downloadURL := qstorage.MakePrivateURL(s.mac, strings.TrimSuffix(s.config.BaseURL, "/"), strings.TrimPrefix(name, "/"), time.Now().Add(time.Hour).Unix())
|
||||
req, err := http.NewRequestWithContext(ctx, http.MethodGet, downloadURL, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -7,7 +7,7 @@ import (
|
||||
"kra/internal/biz/system"
|
||||
"sync"
|
||||
|
||||
"kra/internal/conf"
|
||||
"kra/internal/config"
|
||||
)
|
||||
|
||||
type Reloadable struct {
|
||||
@@ -15,15 +15,15 @@ type Reloadable struct {
|
||||
current system.FileStorage
|
||||
}
|
||||
|
||||
func NewFileStorage(runtime *conf.Runtime) (*Reloadable, error) {
|
||||
var config *conf.AdminBackend
|
||||
func NewFileStorage(runtime *config.Store) (*Reloadable, error) {
|
||||
var config *config.Admin
|
||||
if runtime != nil {
|
||||
config = runtime.Admin()
|
||||
}
|
||||
return NewReloadable(config)
|
||||
}
|
||||
|
||||
func NewReloadable(config *conf.AdminBackend) (*Reloadable, error) {
|
||||
func NewReloadable(config *config.Admin) (*Reloadable, error) {
|
||||
current, err := New(config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -9,7 +9,7 @@ import (
|
||||
"path"
|
||||
"strings"
|
||||
|
||||
"kra/internal/conf"
|
||||
"kra/internal/config"
|
||||
|
||||
"github.com/minio/minio-go/v7"
|
||||
"github.com/minio/minio-go/v7/pkg/credentials"
|
||||
@@ -20,7 +20,7 @@ type s3Storage struct {
|
||||
bucket, baseURL, prefix string
|
||||
}
|
||||
|
||||
func newS3Storage(provider string, config *conf.AdminBackend_ObjectStore) (system.FileStorage, error) {
|
||||
func newS3Storage(provider string, config *config.ObjectStore) (system.FileStorage, error) {
|
||||
if config == nil || config.Bucket == "" || config.AccessKey == "" || config.SecretKey == "" {
|
||||
return nil, fmt.Errorf("%s storage configuration is incomplete", provider)
|
||||
}
|
||||
@@ -30,7 +30,7 @@ func newS3Storage(provider string, config *conf.AdminBackend_ObjectStore) (syste
|
||||
case "aws-s3":
|
||||
endpoint = "s3." + config.Region + ".amazonaws.com"
|
||||
case "cloudflare-r2":
|
||||
endpoint = config.AccountId + ".r2.cloudflarestorage.com"
|
||||
endpoint = config.AccountID + ".r2.cloudflarestorage.com"
|
||||
case "aliyun-oss":
|
||||
endpoint = "oss-" + config.Region + ".aliyuncs.com"
|
||||
case "huawei-obs":
|
||||
@@ -39,7 +39,7 @@ func newS3Storage(provider string, config *conf.AdminBackend_ObjectStore) (syste
|
||||
endpoint = "cos." + config.Region + ".myqcloud.com"
|
||||
}
|
||||
}
|
||||
secure := config.UseSsl
|
||||
secure := config.UseSSL
|
||||
if parsed, err := url.Parse(endpoint); err == nil && parsed.Host != "" {
|
||||
secure = parsed.Scheme == "https"
|
||||
endpoint = parsed.Host
|
||||
@@ -56,7 +56,7 @@ func newS3Storage(provider string, config *conf.AdminBackend_ObjectStore) (syste
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &s3Storage{client: client, bucket: config.Bucket, baseURL: strings.TrimSuffix(config.BaseUrl, "/"), prefix: strings.Trim(config.PathPrefix, "/")}, nil
|
||||
return &s3Storage{client: client, bucket: config.Bucket, baseURL: strings.TrimSuffix(config.BaseURL, "/"), prefix: strings.Trim(config.PathPrefix, "/")}, nil
|
||||
}
|
||||
func (s *s3Storage) key(name string) string {
|
||||
if s.prefix == "" {
|
||||
|
||||
@@ -11,7 +11,7 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"kra/internal/conf"
|
||||
"kra/internal/config"
|
||||
|
||||
cos "github.com/tencentyun/cos-go-sdk-v5"
|
||||
)
|
||||
@@ -21,7 +21,7 @@ type tencentStorage struct {
|
||||
baseURL, prefix string
|
||||
}
|
||||
|
||||
func newTencentStorage(config *conf.AdminBackend_ObjectStore) (system.FileStorage, error) {
|
||||
func newTencentStorage(config *config.ObjectStore) (system.FileStorage, error) {
|
||||
if config == nil || config.Bucket == "" || config.Region == "" || config.AccessKey == "" || config.SecretKey == "" {
|
||||
return nil, fmt.Errorf("tencent-cos storage configuration is incomplete")
|
||||
}
|
||||
@@ -29,7 +29,7 @@ func newTencentStorage(config *conf.AdminBackend_ObjectStore) (system.FileStorag
|
||||
if endpoint == "" {
|
||||
endpoint = fmt.Sprintf("https://%s.cos.%s.myqcloud.com", config.Bucket, config.Region)
|
||||
} else if !strings.HasPrefix(endpoint, "http://") && !strings.HasPrefix(endpoint, "https://") {
|
||||
if config.UseSsl {
|
||||
if config.UseSSL {
|
||||
endpoint = "https://" + endpoint
|
||||
} else {
|
||||
endpoint = "http://" + endpoint
|
||||
@@ -40,7 +40,7 @@ func newTencentStorage(config *conf.AdminBackend_ObjectStore) (system.FileStorag
|
||||
return nil, err
|
||||
}
|
||||
client := cos.NewClient(&cos.BaseURL{BucketURL: bucketURL}, &http.Client{Transport: &cos.AuthorizationTransport{SecretID: config.AccessKey, SecretKey: config.SecretKey}})
|
||||
return &tencentStorage{client: client, baseURL: strings.TrimSuffix(config.BaseUrl, "/"), prefix: strings.Trim(config.PathPrefix, "/")}, nil
|
||||
return &tencentStorage{client: client, baseURL: strings.TrimSuffix(config.BaseURL, "/"), prefix: strings.Trim(config.PathPrefix, "/")}, nil
|
||||
}
|
||||
func (s *tencentStorage) key(name string) string {
|
||||
if s.prefix == "" {
|
||||
|
||||
Reference in New Issue
Block a user