diff --git a/go.mod b/go.mod index 0b8596bd..8e21cd36 100644 --- a/go.mod +++ b/go.mod @@ -52,6 +52,7 @@ require ( github.com/libdns/dynv6 v1.1.1 github.com/libdns/libdns v1.1.1 github.com/luthermonson/go-proxmox v0.2.4 + github.com/minio/minio-go/v7 v7.0.97 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/sftp v1.13.10 @@ -205,22 +206,31 @@ require ( github.com/ganigeorgiev/fexpr v0.5.0 // indirect github.com/go-acme/esa-20240910/v2 v2.40.3 // indirect github.com/go-acme/tencentedgdeone v1.1.48 // indirect + github.com/go-ini/ini v1.67.0 // indirect github.com/go-jose/go-jose/v4 v4.1.3 // indirect github.com/go-ozzo/ozzo-validation/v4 v4.3.0 // indirect github.com/google/uuid v1.6.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/json-iterator/go v1.1.13-0.20220915233716-71ac16282d12 // indirect + github.com/klauspost/compress v1.18.0 // indirect + github.com/klauspost/cpuid/v2 v2.2.11 // indirect + github.com/klauspost/crc32 v1.3.0 // indirect github.com/kr/fs v0.1.0 // indirect github.com/mattn/go-colorable v0.1.14 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/miekg/dns v1.1.69 // indirect + github.com/minio/crc64nvme v1.1.0 // indirect + github.com/minio/md5-simd v1.1.2 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect github.com/ncruces/go-strftime v1.0.0 // indirect github.com/nrdcg/namesilo v0.5.0 // 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/cast v1.10.0 // indirect + github.com/tinylib/msgp v1.3.0 // indirect github.com/tjfoc/gmsm v1.4.1 // indirect golang.org/x/image v0.34.0 // indirect golang.org/x/mod v0.31.0 // indirect diff --git a/go.sum b/go.sum index 25c96e4e..9c30dc1e 100644 --- a/go.sum +++ b/go.sum @@ -144,8 +144,6 @@ github.com/alibabacloud-go/fc-open-20210406/v2 v2.0.12 h1:A3D8Mp6qf8DfR6Dt5MpS8a github.com/alibabacloud-go/fc-open-20210406/v2 v2.0.12/go.mod h1:F5c0E5UB3k8v6neTtw3FBcJ1YCNFzVoL1JPRHTe33u4= github.com/alibabacloud-go/ga-20191120/v3 v3.1.8 h1:5GF0PXijDhxRQ3gTg9Ee/CVPtglkxuVdz4yIQgYLPgw= github.com/alibabacloud-go/ga-20191120/v3 v3.1.8/go.mod h1:RVpR9VL4YECKoZCQijTYfPk8k52O61v6hSRekjxF0kw= -github.com/alibabacloud-go/live-20161101/v2 v2.4.0 h1:TLNjd3HkUyCji4LjXMtse3lKPKBPNCSvll9rAWHOJ7Q= -github.com/alibabacloud-go/live-20161101/v2 v2.4.0/go.mod h1:1BN//Z4vOkdEplf0pWcpF1GuIqaPJOwYuPCShljY+nI= github.com/alibabacloud-go/live-20161101/v2 v2.5.0 h1:DxALW3BqBGDrgMu7OHLT5nHVeil440DGKUlPiVN/zbE= github.com/alibabacloud-go/live-20161101/v2 v2.5.0/go.mod h1:1BN//Z4vOkdEplf0pWcpF1GuIqaPJOwYuPCShljY+nI= github.com/alibabacloud-go/nlb-20220430/v4 v4.1.0 h1:iuoiJUMz0SUWbLxZdyp/IdbtGKuniftnV776FUwMEyU= @@ -153,8 +151,6 @@ github.com/alibabacloud-go/nlb-20220430/v4 v4.1.0/go.mod h1:OxNPeLl4eV3s2ZoMcuUo github.com/alibabacloud-go/openapi-util v0.1.0/go.mod h1:sQuElr4ywwFRlCCberQwKRFhRzIyG4QTP/P4y1CJ6Ws= github.com/alibabacloud-go/openapi-util v0.1.1 h1:ujGErJjG8ncRW6XtBBMphzHTvCxn4DjrVw4m04HsS28= github.com/alibabacloud-go/openapi-util v0.1.1/go.mod h1:/UehBSE2cf1gYT43GV4E+RxTdLRzURImCYY0aRmlXpw= -github.com/alibabacloud-go/slb-20140515/v4 v4.0.12 h1:J/mnt9MJC5HIzXsWuNnSzp3YgLohkUg3cgrckMJgii0= -github.com/alibabacloud-go/slb-20140515/v4 v4.0.12/go.mod h1:gWZrz3AD+izASfHjpxTOIJ8N0KMRjbIRzRZr1koy7tA= github.com/alibabacloud-go/slb-20140515/v4 v4.0.13 h1:MtQUoGTgFqGTebY4lzFTFVsIV7QXeVN13oMzJYqvtYQ= github.com/alibabacloud-go/slb-20140515/v4 v4.0.13/go.mod h1:gWZrz3AD+izASfHjpxTOIJ8N0KMRjbIRzRZr1koy7tA= github.com/alibabacloud-go/tea v1.1.0/go.mod h1:IkGyUSX4Ba1V+k4pCtJUc6jDpZLFph9QMy2VUPTwukg= @@ -246,8 +242,6 @@ github.com/aws/aws-sdk-go-v2/service/sts v1.41.5/go.mod h1:iW40X4QBmUxdP+fZNOpfm github.com/aws/smithy-go v1.8.0/go.mod h1:SObp3lf9smib00L/v3U2eAKG8FyQ7iLrJnQiAmR5n+E= github.com/aws/smithy-go v1.24.0 h1:LpilSUItNPFr1eY85RYgTIg5eIEPtvFbskaFcmmIUnk= github.com/aws/smithy-go v1.24.0/go.mod h1:LEj2LM3rBRQJxPZTB4KuzZkaZYnZPnvgIhb4pu07mx0= -github.com/baidubce/bce-sdk-go v0.9.254 h1:A7GtBOt7z2lnV7fqlZPZefhcBFg7z6iliUAhEOiIhoE= -github.com/baidubce/bce-sdk-go v0.9.254/go.mod h1:zbYJMQwE4IZuyrJiFO8tO8NbtYiKTFTbwh4eIsqjVdg= github.com/baidubce/bce-sdk-go v0.9.256 h1:/6UwBzDp+dRFpKRIb5WsvxfSiG4SLOIOghvagOK/q4Y= github.com/baidubce/bce-sdk-go v0.9.256/go.mod h1:zbYJMQwE4IZuyrJiFO8tO8NbtYiKTFTbwh4eIsqjVdg= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= @@ -360,6 +354,8 @@ github.com/go-cmd/cmd v1.4.3/go.mod h1:u3hxg/ry+D5kwh8WvUkHLAMe2zQCaXd00t35WfQaO github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-ini/ini v1.67.0 h1:z6ZrTEZqSWOTyH2FlglNbNgARyHG8oLW9gMELqKr06A= +github.com/go-ini/ini v1.67.0/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8= github.com/go-jose/go-jose/v4 v4.1.3 h1:CVLmWDhDVRa6Mi/IgCgaopNosCaHz7zrMeF9MlZRkrs= github.com/go-jose/go-jose/v4 v4.1.3/go.mod h1:x4oUasVrzR7071A4TnHLGSPpNOm2a21K9Kf04k1rs08= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= @@ -596,8 +592,13 @@ github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/compress v1.13.4/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= -github.com/klauspost/compress v1.17.4 h1:Ej5ixsIri7BrIjBkRZLTo6ghwrEtHFk7ijlczPW4fZ4= -github.com/klauspost/compress v1.17.4/go.mod h1:/dCuZOvVtNoHsyb+cuJD3itjs3NbnF6KH9zAO4BDxPM= +github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo= +github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ= +github.com/klauspost/cpuid/v2 v2.0.1/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= +github.com/klauspost/cpuid/v2 v2.2.11 h1:0OwqZRYI2rFrjS4kvkDnqJkKHdHaRnCm68/DY4OxRzU= +github.com/klauspost/cpuid/v2 v2.2.11/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0= +github.com/klauspost/crc32 v1.3.0 h1:sSmTt3gUt81RP655XGZPElI0PelVTZ6YwCRnPSupoFM= +github.com/klauspost/crc32 v1.3.0/go.mod h1:D7kQaZhnkX/Y0tstFGf8VUzv2UofNGqCjnC3zdHB0Hw= github.com/kong/go-kong v0.71.0 h1:unPik6osV1DD3DF+jLs9oMedxWQsnepPYTm1dRQSIa4= github.com/kong/go-kong v0.71.0/go.mod h1:J0vGB3wsZ2i99zly1zTRe3v7rOKpkhQZRwbcTFP76qM= github.com/kong/semver/v4 v4.0.1 h1:DIcNR8W3gfx0KabFBADPalxxsp+q/5COwIFkkhrFQ2Y= @@ -657,8 +658,14 @@ github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKju github.com/miekg/dns v1.1.43/go.mod h1:+evo5L0630/F6ca/Z9+GAqzhjGyn8/c+TBaOyfEl0V4= github.com/miekg/dns v1.1.69 h1:Kb7Y/1Jo+SG+a2GtfoFUfDkG//csdRPwRLkCsxDG9Sc= github.com/miekg/dns v1.1.69/go.mod h1:7OyjD9nEba5OkqQ/hB4fy3PIoxafSZJtducccIelz3g= +github.com/minio/crc64nvme v1.1.0 h1:e/tAguZ+4cw32D+IO/8GSf5UVr9y+3eJcxZI2WOO/7Q= +github.com/minio/crc64nvme v1.1.0/go.mod h1:eVfm2fAzLlxMdUGc0EEBGSMmPwmXD5XiNRpnu9J3bvg= github.com/minio/highwayhash v1.0.1/go.mod h1:BQskDq+xkJ12lmlUUi7U0M5Swg3EWR+dLTk+kldvVxY= github.com/minio/highwayhash v1.0.2/go.mod h1:BQskDq+xkJ12lmlUUi7U0M5Swg3EWR+dLTk+kldvVxY= +github.com/minio/md5-simd v1.1.2 h1:Gdi1DZK69+ZVMoNHRXJyNcxrMA4dSxoYHZSQbirFg34= +github.com/minio/md5-simd v1.1.2/go.mod h1:MzdKDxYpY2BT9XQFocsiZf/NKVtR7nkE4RoEpN+20RM= +github.com/minio/minio-go/v7 v7.0.97 h1:lqhREPyfgHTB/ciX8k2r8k0D93WaFqxbJX36UZq5occ= +github.com/minio/minio-go/v7 v7.0.97/go.mod h1:re5VXuo0pwEtoNLsNuSr0RrLfT/MBtohwdaSmPPSRSk= github.com/mitchellh/cli v1.1.0/go.mod h1:xcISNoH86gajksDmfB23e/pu+B+GeFRMYmoHXxx3xhI= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= @@ -732,6 +739,8 @@ github.com/pavlo-v-chernykh/keystore-go/v4 v4.5.0/go.mod h1:lAVhWwbNaveeJmxrxuST github.com/performancecopilot/speed/v4 v4.0.0/go.mod h1:qxrSyuDGrTOWfV+uKRFhfxw6h/4HXRGUiZiufxo49BM= github.com/peterhellberg/link v1.2.0 h1:UA5pg3Gp/E0F2WdX7GERiNrPQrM1K6CVJUUWfHa4t6c= github.com/peterhellberg/link v1.2.0/go.mod h1:gYfAh+oJgQu2SrZHg5hROVRQe1ICoK0/HHJTcE0edxc= +github.com/philhofer/fwd v1.2.0 h1:e6DnBTl7vGY+Gz322/ASL4Gyp1FspeMvx1RNDoToZuM= +github.com/philhofer/fwd v1.2.0/go.mod h1:RqIHx9QI14HlwKwm98g9Re5prTQ6LdeRQn+gXJFxsJM= github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc= github.com/pierrec/lz4 v2.6.1+incompatible h1:9UY3+iC23yxF0UfGaYrGplQ+79Rg+h/q9FV9ix19jjM= github.com/pierrec/lz4 v2.6.1+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= @@ -796,6 +805,8 @@ github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTE github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE= github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= +github.com/rs/xid v1.6.0 h1:fV591PaemRlL6JfRxGDEPl69wICngIQ3shQtzfy2gxU= +github.com/rs/xid v1.6.0/go.mod h1:7XoLgs4eV+QndskICGsho+ADou8ySMSjJKDIan90Nz0= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= @@ -845,8 +856,6 @@ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= -github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cdn v1.3.17 h1:daYB3/mHBoYRAUWTkU2PrKSijNOqmPGwyCjSbhpsPfk= -github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cdn v1.3.17/go.mod h1:zJGNIT9EJUEGNYwIsB96L9JagH65lhxRriTPmHTjWJk= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cdn v1.3.20 h1:2YLbDjm8I7TRurRJZO7pCsUs6J8uNSGVaP9DWZQPc6U= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cdn v1.3.20/go.mod h1:elKRHSEOQbiRov7N1xEoy0E8KPwAyc/VMJOVI5G5zEM= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/clb v1.3.13 h1:UtduU6ahUDJeZlmoUbyoz8Vguipiqk7tHQR4uXW0boA= @@ -854,38 +863,23 @@ github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/clb v1.3.13/go.mod h1:f github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.1.25/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.1.45/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.1.48/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0= -github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.2.2/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.3.4/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0= -github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.3.11/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.3.13/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0= -github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.3.16/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0= -github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.3.17 h1:pjL2v80TdxvF08WzSO2Tr2TTEOH1O7FQR176uLO+4O0= -github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.3.17/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.3.18/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.3.20 h1:RRq1WvPfe5jy5ImFiFo5HU+tPiCt+qdnwO+T7vVN6dU= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.3.20/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/gaap v1.1.45 h1:xqKjGMJw7CICjs+xAIDWK7l52QQ1rUUlajTfksYkH50= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/gaap v1.1.45/go.mod h1:2KEYKinKeqfdcetd0nLrS3pllb1SJ27ygmiyJ570iH8= -github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/live v1.3.16 h1:ukU4KPGFYgCuTyflIPnXlMQcoW7AoSLtDfQ541gpHXU= -github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/live v1.3.16/go.mod h1:Hpn3mSxaMoQE2/SJf64FgEcK7ypAeSrO1uUwTPadCrw= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/live v1.3.20 h1:/147pDQzIVqOgt4CGtjRyuWvDvaWXrjmRwvcKbWugXk= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/live v1.3.20/go.mod h1:YXRHnmmu42wyXIGvVxffVOZtCK0G5xJ23eQzcon1f+w= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/scf v1.3.4 h1:CkRXWD7DeoUosSQ6tMdoktw2IODUlbrd4KQpaiUDZg0= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/scf v1.3.4/go.mod h1:/Z0n3bA2SQaHclfeTUNtnIfK61ADe/Zk4Auuequgze0= -github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/ssl v1.2.2 h1:VkeBp3dOfCm0INU4oi3Djg4Terms8xrlcbHWI6AQ1so= -github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/ssl v1.2.2/go.mod h1:uJfDgCw3jYjEPJ/mZ9sMahPt8pd57rct6yGLNiPDKvw= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/ssl v1.3.20 h1:VPfMa3hsxMxquv06Bat6wv9tLv3ZjCjgz0/dndwMloQ= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/ssl v1.3.20/go.mod h1:rDr8tuOVK5CPXe2wiq3Q8RCEVzCE2yKckQgdr1Bvar8= -github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/teo v1.3.17 h1:QdoR+rCiHBZuuoivdWaVOIHzvMUPIiSTmUe7OFnUAo8= -github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/teo v1.3.17/go.mod h1:EJ82JP35f7Pkh2dm+OvDDQ6/9kViBb0M/WGhiOHmQ10= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/teo v1.3.18 h1:XFsg8l4rGDkG2HT7xIJsfWvBSe62GQV/MxSh2EBAosU= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/teo v1.3.18/go.mod h1:ttUXlKbDD+f6BOAG1rTiKG0TNNh6/4V7TEEE/0HL/oQ= -github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/vod v1.3.17 h1:fL6OrLmOt+cx8ydlqkUngq7M/b8vrxQezINaeKHTZ3Q= -github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/vod v1.3.17/go.mod h1:iVBFznh44P2Bq42W0Mxvb6QKA8rne1nyp11O1Wpmwbc= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/vod v1.3.20 h1:kV0p6/rO4seCojF4hsPBTQq6dMGVJsUB6/5u3Y16YRQ= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/vod v1.3.20/go.mod h1:2HdphlkKmQc5TIiaZnUPxB4s1wbriExDS0TSZwkvp+s= -github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/waf v1.3.11 h1:+ymQSl/hQaE0quLmGoCTjqwRbXSDebkSPYnC3AigQqA= -github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/waf v1.3.11/go.mod h1:3z7CWaLikx7voRr1MVaa785f+y9evC0UzyLWSSwuvgY= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/waf v1.3.20 h1:xrX2I30YY2hLsm302jATQsnq860gBNFSLbGlNgXANug= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/waf v1.3.20/go.mod h1:NMaQNYoBdz4fUR9fi6/jMTe7xdsJLYnlBxDAu+y5+nw= github.com/tidwall/gjson v1.18.0 h1:FIDeeyB800efLX89e5a8Y0BNH+LOngJyGrIWxG2FKQY= @@ -894,6 +888,8 @@ github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs= github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= +github.com/tinylib/msgp v1.3.0 h1:ULuf7GPooDaIlbyvgAxBV/FI7ynli6LZ1/nVUNu+0ww= +github.com/tinylib/msgp v1.3.0/go.mod h1:ykjzy2wzgrlvpDCRc4LA8UXy6D8bzMSuAF3WD57Gok0= github.com/tjfoc/gmsm v1.3.2/go.mod h1:HaUcFuY0auTiaHB9MHFGCPx5IaLhTUd2atbCFBQXn9w= github.com/tjfoc/gmsm v1.4.1 h1:aMe1GlZb+0bLjn+cKTPEvvn9oUEBlJitaZiiBwsbgho= github.com/tjfoc/gmsm v1.4.1/go.mod h1:j4INPkHWMrhJb38G+J6W4Tw0AbuN8Thu3PbdVYhVcTE= diff --git a/internal/certacme/certifiers/sp_s3.go b/internal/certacme/certifiers/sp_s3.go new file mode 100644 index 00000000..f5883e8f --- /dev/null +++ b/internal/certacme/certifiers/sp_s3.go @@ -0,0 +1,32 @@ +package certifiers + +import ( + "fmt" + + "github.com/go-acme/lego/v4/challenge" + + "github.com/certimate-go/certimate/internal/domain" + "github.com/certimate-go/certimate/pkg/core/certifier/challengers/http01/s3" + xmaps "github.com/certimate-go/certimate/pkg/utils/maps" +) + +func init() { + ACMEHttp01Registries.MustRegister(domain.ACMEHttp01ProviderTypeS3, func(options *ProviderFactoryOptions) (challenge.Provider, error) { + credentials := domain.AccessConfigForS3{} + if err := xmaps.Populate(options.ProviderAccessConfig, &credentials); err != nil { + return nil, fmt.Errorf("failed to populate provider access config: %w", err) + } + + provider, err := s3.NewChallenger(&s3.ChallengerConfig{ + Endpoint: credentials.Endpoint, + AccessKey: credentials.AccessKey, + SecretKey: credentials.SecretKey, + SignatureVersion: credentials.SignatureVersion, + UsePathStyle: credentials.UsePathStyle, + AllowInsecureConnections: credentials.AllowInsecureConnections, + Region: xmaps.GetString(options.ProviderExtendedConfig, "region"), + Bucket: xmaps.GetString(options.ProviderExtendedConfig, "bucket"), + }) + return provider, err + }) +} diff --git a/internal/domain/access.go b/internal/domain/access.go index e7fb438e..05931768 100644 --- a/internal/domain/access.go +++ b/internal/domain/access.go @@ -363,6 +363,11 @@ type AccessConfigForMattermost struct { ChannelId string `json:"channelId,omitempty"` } +type AccessConfigForMohua struct { + Username string `json:"username"` + ApiPassword string `json:"apiPassword"` +} + type AccessConfigForNamecheap struct { Username string `json:"username"` ApiKey string `json:"apiKey"` @@ -429,11 +434,6 @@ type AccessConfigForQiniu struct { SecretKey string `json:"secretKey"` } -type AccessConfigForMohua struct { - Username string `json:"username"` - ApiPassword string `json:"apiPassword"` -} - type AccessConfigForRainYun struct { ApiKey string `json:"apiKey"` } @@ -453,6 +453,15 @@ type AccessConfigForRFC2136 struct { TsigSecret string `json:"tsigSecret,omitempty"` } +type AccessConfigForS3 struct { + Endpoint string `json:"endpoint"` + AccessKey string `json:"accessKey"` + SecretKey string `json:"secretKey"` + SignatureVersion string `json:"signatureVersion,omitempty"` + UsePathStyle bool `json:"usePathStyle,omitempty"` + AllowInsecureConnections bool `json:"allowInsecureConnections,omitempty"` +} + type AccessConfigForSafeLine struct { ServerUrl string `json:"serverUrl"` ApiToken string `json:"apiToken"` diff --git a/internal/domain/provider.go b/internal/domain/provider.go index 94583f07..2d493d97 100644 --- a/internal/domain/provider.go +++ b/internal/domain/provider.go @@ -94,6 +94,7 @@ const ( AccessProviderTypeRainYun = AccessProviderType("rainyun") AccessProviderTypeRatPanel = AccessProviderType("ratpanel") AccessProviderTypeRFC2136 = AccessProviderType("rfc2136") + AccessProviderTypeS3 = AccessProviderType("s3") AccessProviderTypeSafeLine = AccessProviderType("safeline") AccessProviderTypeSectigo = AccessProviderType("sectigo") AccessProviderTypeSlackBot = AccessProviderType("slackbot") @@ -236,6 +237,7 @@ NOTICE: If you add new constant, please keep ASCII order. */ const ( ACMEHttp01ProviderTypeLocal = ACMEHttp01ProviderType(AccessProviderTypeLocal) + ACMEHttp01ProviderTypeS3 = ACMEHttp01ProviderType(AccessProviderTypeS3) ACMEHttp01ProviderTypeSSH = ACMEHttp01ProviderType(AccessProviderTypeSSH) ) diff --git a/pkg/core/certifier/challengers/http01/s3/s3.go b/pkg/core/certifier/challengers/http01/s3/s3.go new file mode 100644 index 00000000..0ee9d6c4 --- /dev/null +++ b/pkg/core/certifier/challengers/http01/s3/s3.go @@ -0,0 +1,121 @@ +package s3 + +import ( + "context" + "errors" + "fmt" + "regexp" + "strings" + + "github.com/go-acme/lego/v4/challenge/http01" + "github.com/minio/minio-go/v7" + "github.com/minio/minio-go/v7/pkg/credentials" + "github.com/samber/lo" + + "github.com/certimate-go/certimate/pkg/core/certifier" + xhttp "github.com/certimate-go/certimate/pkg/utils/http" + xtls "github.com/certimate-go/certimate/pkg/utils/tls" +) + +type ChallengerConfig struct { + // S3 Endpoint。 + Endpoint string `json:"endpoint"` + // S3 AccessKey。 + AccessKey string `json:"accessKey"` + // S3 SecretKey。 + SecretKey string `json:"secretKey"` + // S3 签名版本。 + // 可取值 "v2"、"v4"。 + // 零值时默认值 "v4"。 + SignatureVersion string `json:"signatureVersion,omitempty"` + // 是否使用路径风格。 + UsePathStyle bool `json:"usePathStyle,omitempty"` + // 存储区域。 + Region string `json:"region"` + // 存储桶名。 + Bucket string `json:"bucket"` + // 是否允许不安全的连接。 + AllowInsecureConnections bool `json:"allowInsecureConnections,omitempty"` +} + +func NewChallenger(config *ChallengerConfig) (certifier.ACMEChallenger, error) { + if config == nil { + return nil, errors.New("the configuration of the acme challenge provider is nil") + } + + var clientCred *credentials.Credentials + switch config.SignatureVersion { + case "", "v4": + clientCred = credentials.NewStaticV4(config.AccessKey, config.SecretKey, "") + case "v2": + 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.AllowInsecureConnections { + transport := xhttp.NewDefaultTransport() + transport.DisableKeepAlives = true + transport.TLSClientConfig = xtls.NewInsecureConfig() + clientOpts.Transport = transport + } + + client, err := minio.New(endpoint, clientOpts) + if err != nil { + return nil, err + } + + provider := &provider{client: client, bucket: config.Bucket} + return provider, nil +} + +type provider struct { + client *minio.Client + bucket string +} + +func (p *provider) Present(domain, token, keyAuth string) error { + objectKey := strings.Trim(http01.ChallengePath(token), "/") + putOpts := minio.PutObjectOptions{ + DisableMultipart: true, + } + reader := strings.NewReader(keyAuth) + _, err := p.client.PutObject(context.Background(), p.bucket, objectKey, reader, reader.Size(), putOpts) + if err != nil { + return fmt.Errorf("s3: failed to upload token to s3: %w", err) + } + + return nil +} + +func (p *provider) CleanUp(domain, token, keyAuth string) error { + objectKey := strings.Trim(http01.ChallengePath(token), "/") + removeOpts := minio.RemoveObjectOptions{} + err := p.client.RemoveObject(context.Background(), p.bucket, objectKey, removeOpts) + if err != nil { + return fmt.Errorf("s3: could not remove file in s3 bucket after HTTP challenge: %w", err) + } + + return nil +} diff --git a/ui/public/imgs/providers/s3.svg b/ui/public/imgs/providers/s3.svg new file mode 100644 index 00000000..76a77a38 --- /dev/null +++ b/ui/public/imgs/providers/s3.svg @@ -0,0 +1 @@ + diff --git a/ui/src/components/access/forms/AccessConfigFieldsProvider.tsx b/ui/src/components/access/forms/AccessConfigFieldsProvider.tsx index cea12f8b..68832c13 100644 --- a/ui/src/components/access/forms/AccessConfigFieldsProvider.tsx +++ b/ui/src/components/access/forms/AccessConfigFieldsProvider.tsx @@ -82,6 +82,7 @@ import AccessConfigFieldsProviderQiniu from "./AccessConfigFieldsProviderQiniu"; import AccessConfigFieldsProviderRainYun from "./AccessConfigFieldsProviderRainYun"; import AccessConfigFieldsProviderRatPanel from "./AccessConfigFieldsProviderRatPanel"; import AccessConfigFieldsProviderRFC2136 from "./AccessConfigFieldsProviderRFC2136"; +import AccessConfigFieldsProviderS3 from "./AccessConfigFieldsProviderS3"; import AccessConfigFieldsProviderSafeLine from "./AccessConfigFieldsProviderSafeLine"; import AccessConfigFieldsProviderSectigo from "./AccessConfigFieldsProviderSectigo"; import AccessConfigFieldsProviderSlackBot from "./AccessConfigFieldsProviderSlackBot"; @@ -189,6 +190,7 @@ const providerComponentMap: Partial { + const { i18n, t } = useTranslation(); + + const { parentNamePath } = useFormNestedFieldsContext(); + const formSchema = z.object({ + [parentNamePath]: getSchema({ i18n }), + }); + const formRule = createSchemaFieldRule(formSchema); + const initialValues = getInitialValues(); + + return ( + <> + } + rules={[formRule]} + > + + + + + + + + + + + + + + + + + + + + ); +}; + +const getInitialValues = (): Nullish>> => { + return { + region: "", + bucket: "", + }; +}; + +const getSchema = ({ i18n = getI18n() }: { i18n?: ReturnType }) => { + const { t } = i18n; + + return z.object({ + region: z.string().nonempty(t("workflow_node.apply.form.s3_region.placeholder")), + bucket: z.string().nonempty(t("workflow_node.apply.form.s3_bucket.placeholder")), + }); +}; + +const _default = Object.assign(BizApplyNodeConfigFieldsProviderS3, { + getInitialValues, + getSchema, +}); + +export default _default; diff --git a/ui/src/domain/provider.ts b/ui/src/domain/provider.ts index b338e5e0..9bf7a43f 100644 --- a/ui/src/domain/provider.ts +++ b/ui/src/domain/provider.ts @@ -98,6 +98,7 @@ export const ACCESS_PROVIDERS = Object.freeze({ RAINYUN: "rainyun", RATPANEL: "ratpanel", RFC2136: "rfc2136", + S3: "s3", SAFELINE: "safeline", SECTIGO: "sectigo", SLACKBOT: "slackbot", @@ -147,6 +148,7 @@ export const accessProvidersMap: Map ).map(([type, name, builtin]) => [ type, diff --git a/ui/src/i18n/locales/en/nls.access.json b/ui/src/i18n/locales/en/nls.access.json index 87d48ea8..318f558b 100644 --- a/ui/src/i18n/locales/en/nls.access.json +++ b/ui/src/i18n/locales/en/nls.access.json @@ -534,6 +534,17 @@ "access.form.rfc2136_tsig_key.placeholder": "Please enter TSIG authentication key", "access.form.rfc2136_tsig_secret.label": "TSIG authentication secret (Optional)", "access.form.rfc2136_tsig_secret.placeholder": "Please enter TSIG authentication secret", + "access.form.s3_endpoint.label": "Endpoint", + "access.form.s3_endpoint.placeholder": "Please enter endpoint", + "access.form.s3_endpoint.help": "Note: If the protocol is not specified, https:// is used by default.", + "access.form.s3_access_key.label": "Access key", + "access.form.s3_access_key.placeholder": "Please enter access key", + "access.form.s3_secret_key.label": "Secret key", + "access.form.s3_secret_key.placeholder": "Please enter secret key", + "access.form.s3_signature_version.label": "Signature version", + "access.form.s3_signature_version.placeholder": "Please select signature version", + "access.form.s3_use_path_style.label": "Use path style addressing", + "access.form.s3_use_path_style.tooltip": "
  1. Virtual-hosted style (default): https://<BUCKET>.<ENDPOINT>/<KEY>
  2. Path style: https://<ENDPOINT>/<BUCKET>/<KEY>
", "access.form.safeline_server_url.label": "SafeLine server URL", "access.form.safeline_server_url.placeholder": "Please enter SafeLine server URL", "access.form.safeline_api_token.label": "SafeLine API token", diff --git a/ui/src/i18n/locales/en/nls.provider.json b/ui/src/i18n/locales/en/nls.provider.json index 2931a250..78fa3f6e 100644 --- a/ui/src/i18n/locales/en/nls.provider.json +++ b/ui/src/i18n/locales/en/nls.provider.json @@ -159,6 +159,7 @@ "provider.ratpanel_console": "AcePanel - Console itself", "provider.ratpanel_site": "AcePanel - Website", "provider.rfc2136": "RFC 2136: Dynamic DNS Updates", + "provider.s3": "Object storage (S3-compatible)", "provider.safeline": "SafeLine", "provider.safeline_site": "SafeLine - Website", "provider.sectigo": "Sectigo", diff --git a/ui/src/i18n/locales/en/nls.workflow.nodes.json b/ui/src/i18n/locales/en/nls.workflow.nodes.json index 83cbfe94..d7d3cab1 100644 --- a/ui/src/i18n/locales/en/nls.workflow.nodes.json +++ b/ui/src/i18n/locales/en/nls.workflow.nodes.json @@ -83,6 +83,10 @@ "workflow_node.apply.form.jdcloud_dns_region_id.label": "JD Cloud region ID", "workflow_node.apply.form.jdcloud_dns_region_id.placeholder": "Please enter JD Cloud DNS region ID (e.g. cn-north-1)", "workflow_node.apply.form.jdcloud_dns_region_id.tooltip": "For more information, see https://docs.jdcloud.com/en/common-declaration/api/introduction", + "workflow_node.apply.form.s3_region.label": "Object storage (S3-compatible) region", + "workflow_node.apply.form.s3_region.placeholder": "Please enter region", + "workflow_node.apply.form.s3_bucket.label": "Object storage (S3-compatible) bucket", + "workflow_node.apply.form.s3_bucket.placeholder": "Please enter bucket name", "workflow_node.apply.form.local_webroot_path.label": "Web root path", "workflow_node.apply.form.local_webroot_path.placeholder": "Please enter web root path", "workflow_node.apply.form.local_webroot_path.tooltip": "It's the main directory where the website's files are stored on the server.", diff --git a/ui/src/i18n/locales/zh/nls.access.json b/ui/src/i18n/locales/zh/nls.access.json index 98264f4f..5e3063bf 100644 --- a/ui/src/i18n/locales/zh/nls.access.json +++ b/ui/src/i18n/locales/zh/nls.access.json @@ -534,6 +534,17 @@ "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.help": "注意:如果不指定协议,则默认使用 https://。", + "access.form.s3_access_key.label": "AccessKey", + "access.form.s3_access_key.placeholder": "请输入 AccessKey", + "access.form.s3_secret_key.label": "SecretKey", + "access.form.s3_secret_key.placeholder": "请输入 SecretKey", + "access.form.s3_signature_version.label": "签名版本", + "access.form.s3_signature_version.placeholder": "请选择签名版本", + "access.form.s3_use_path_style.label": "使用路径风格地址", + "access.form.s3_use_path_style.tooltip": "
  1. 虚拟托管风格(默认):
    https://<BUCKET>.<ENDPOINT>/<KEY>
  2. 路径风格:
    https://<ENDPOINT>/<BUCKET>/<KEY>
", "access.form.safeline_server_url.label": "雷池服务地址", "access.form.safeline_server_url.placeholder": "请输入雷池服务地址", "access.form.safeline_api_token.label": "雷池 API Token", diff --git a/ui/src/i18n/locales/zh/nls.provider.json b/ui/src/i18n/locales/zh/nls.provider.json index 1b22d9b0..933e7690 100644 --- a/ui/src/i18n/locales/zh/nls.provider.json +++ b/ui/src/i18n/locales/zh/nls.provider.json @@ -159,6 +159,7 @@ "provider.ratpanel_console": "耗子面板 - 面板自身", "provider.ratpanel_site": "耗子面板 - 网站", "provider.rfc2136": "RFC 2136: Dynamic DNS Updates", + "provider.s3": "对象存储(S3 兼容)", "provider.safeline": "雷池", "provider.safeline_site": "雷池 - 网站", "provider.sectigo": "Sectigo", diff --git a/ui/src/i18n/locales/zh/nls.workflow.nodes.json b/ui/src/i18n/locales/zh/nls.workflow.nodes.json index 3b2017d1..a25b0a7f 100644 --- a/ui/src/i18n/locales/zh/nls.workflow.nodes.json +++ b/ui/src/i18n/locales/zh/nls.workflow.nodes.json @@ -83,6 +83,10 @@ "workflow_node.apply.form.jdcloud_dns_region_id.label": "京东云服务地域 ID", "workflow_node.apply.form.jdcloud_dns_region_id.placeholder": "请输入京东云 DNS 服务地域 ID(例如:cn-north-1)", "workflow_node.apply.form.jdcloud_dns_region_id.tooltip": "这是什么?请参阅 https://docs.jdcloud.com/cn/common-declaration/api/introduction", + "workflow_node.apply.form.s3_region.label": "对象存储区域", + "workflow_node.apply.form.s3_region.placeholder": "请输入对象存储区域", + "workflow_node.apply.form.s3_bucket.label": "对象存储桶名", + "workflow_node.apply.form.s3_bucket.placeholder": "请输入对象存储桶名", "workflow_node.apply.form.local_webroot_path.label": "网站根目录", "workflow_node.apply.form.local_webroot_path.placeholder": "请输入网站根目录", "workflow_node.apply.form.local_webroot_path.tooltip": "即服务器上存储网站文件的主文件夹。",