Merge pull request #456 from fudiwei/feat/providers

feat: more providers
This commit is contained in:
Yoan.liu 2025-02-22 14:47:22 +08:00 committed by GitHub
commit 569f94e885
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
357 changed files with 12978 additions and 2054 deletions

View File

@ -90,17 +90,23 @@ make local.run
| :----------------------------------------------------------------- | :-------------------------------------- | | :----------------------------------------------------------------- | :-------------------------------------- |
| [阿里云](https://www.aliyun.com/) | | | [阿里云](https://www.aliyun.com/) | |
| [腾讯云](https://cloud.tencent.com/) | | | [腾讯云](https://cloud.tencent.com/) | |
| [百度智能云](https://cloud.baidu.com/) | |
| [华为云](https://www.huaweicloud.com/) | | | [华为云](https://www.huaweicloud.com/) | |
| [火山引擎](https://www.volcengine.com/) | | | [火山引擎](https://www.volcengine.com/) | |
| [京东云](https://www.jdcloud.com/) | |
| [AWS Route53](https://aws.amazon.com/route53/) | | | [AWS Route53](https://aws.amazon.com/route53/) | |
| [Azure](https://azure.microsoft.com/) | | | [Azure](https://azure.microsoft.com/) | |
| [CloudFlare](https://www.cloudflare.com/) | | | [CloudFlare](https://www.cloudflare.com/) | |
| [ClouDNS](https://www.cloudns.net//) | | | [ClouDNS](https://www.cloudns.net/) | |
| [DNS.LA](https://www.dns.la/) | |
| [Gcore](https://gcore.com/) | |
| [GNAME](https://www.gname.com/) | | | [GNAME](https://www.gname.com/) | |
| [GoDaddy](https://www.godaddy.com/) | | | [GoDaddy](https://www.godaddy.com/) | |
| [Name.com](https://www.name.com/) | | | [Name.com](https://www.name.com/) | |
| [Namecheap](https://www.namecheap.com/) | |
| [NameSilo](https://www.namesilo.com/) | | | [NameSilo](https://www.namesilo.com/) | |
| [IBM NS1 Connect](https://www.ibm.com/cn-zh/products/ns1-connect/) | | | [IBM NS1 Connect](https://www.ibm.com/cn-zh/products/ns1-connect/) | |
| [移动云](https://ecloud.10086.cn/) | |
| [雨云](https://www.rainyun.com/) | | | [雨云](https://www.rainyun.com/) | |
| [西部数码](https://www.west.cn/) | | | [西部数码](https://www.west.cn/) | |
| [PowerDNS](https://www.powerdns.com/) | | | [PowerDNS](https://www.powerdns.com/) | |
@ -117,23 +123,29 @@ make local.run
<summary>[展开查看]</summary> <summary>[展开查看]</summary>
| 提供商 | 备注 | | 提供商 | 备注 |
| :-------------------------------------- | :----------------------------------------------------------------------- | | :-------------------------------------- | :---------------------------------------------------------------------------- |
| 本地部署 | 可部署到本地服务器 | | 本地部署 | 可部署到本地服务器 |
| SSH 部署 | 可部署到远程服务器(通过 SSH+SFTP/SCP | | SSH 部署 | 可部署到远程服务器(通过 SSH+SFTP/SCP |
| Webhook 回调 | 可部署到 Webhook | | Webhook 回调 | 可部署到 Webhook |
| [Kubernetes](https://kubernetes.io/) | 可部署到 Kubernetes Secret | | [Kubernetes](https://kubernetes.io/) | 可部署到 Kubernetes Secret |
| [阿里云](https://www.aliyun.com/) | 可部署到阿里云 OSS、CDN、DCDN、ESA、SLBCLB/ALB/NLB、WAF、Live 等服务 | | [阿里云](https://www.aliyun.com/) | 可部署到阿里云 OSS、CDN、DCDN、ESA、SLBCLB/ALB/NLB、WAF、Live、VOD 等服务 |
| [腾讯云](https://cloud.tencent.com/) | 可部署到腾讯云 COS、CDN、ECDN、EdgeOne、CLB、CSS 等服务 | | [腾讯云](https://cloud.tencent.com/) | 可部署到腾讯云 COS、CDN、ECDN、EdgeOne、CLB、WAF、CSS、VOD 等服务 |
| [百度智能云](https://cloud.baidu.com/) | 可部署到百度智能云 CDN 等服务 | | [百度智能云](https://cloud.baidu.com/) | 可部署到百度智能云 CDN 等服务 |
| [华为云](https://www.huaweicloud.com/) | 可部署到华为云 CDN、ELB 等服务 | | [华为云](https://www.huaweicloud.com/) | 可部署到华为云 CDN、ELB、WAF 等服务 |
| [火山引擎](https://www.volcengine.com/) | 可部署到火山引擎 TOS、CDN、DCDN、CLB、Live 等服务 | | [火山引擎](https://www.volcengine.com/) | 可部署到火山引擎 TOS、CDN、DCDN、CLB、ImageX、Live 等服务 |
| [京东云](https://www.jdcloud.com/) | 可部署到京东云 CDN、ALB、视频直播、视频点播等服务 |
| [七牛云](https://www.qiniu.com/) | 可部署到七牛云 CDN、直播云等服务 | | [七牛云](https://www.qiniu.com/) | 可部署到七牛云 CDN、直播云等服务 |
| [白山云](https://www.baishan.com/) | 可部署到白山云 CDN |
| [多吉云](https://www.dogecloud.com/) | 可部署到多吉云 CDN | | [多吉云](https://www.dogecloud.com/) | 可部署到多吉云 CDN |
| [优刻得](https://www.ucloud.cn/) | 可部署到优刻得 US3、UCDN 等服务 | | [优刻得](https://www.ucloud.cn/) | 可部署到优刻得 US3、UCDN 等服务 |
| [雷池](https://waf-ce.chaitin.cn/) | 可部署到雷池 WAF |
| [宝塔面板](https://www.bt.cn/) | 可部署到宝塔面板 | | [宝塔面板](https://www.bt.cn/) | 可部署到宝塔面板 |
| [AWS](https://aws.amazon.com/) | 可部署到 AWS CloudFront 等服务 | | [AWS](https://aws.amazon.com/) | 可部署到 AWS CloudFront |
| [BytePlus](https://www.byteplus.com/) | 可部署到 BytePlus CDN 等服务 | | [BytePlus](https://www.byteplus.com/) | 可部署到 BytePlus CDN |
| [Edgio](https://edg.io/) | 可部署到 Edgio Applications 等服务 | | [CacheFly](https://www.cachefly.com/) | 可部署到 CacheFly CDN |
| [Cdnfly](https://www.cdnfly.cn/) | 可部署到 Cdnfly CDN |
| [Edgio](https://edg.io/) | 可部署到 Edgio Applications |
| [Gcore](https://gcore.com/) | 可部署到 Gcore CDN |
</details> </details>

View File

@ -89,17 +89,23 @@ The following DNS providers are supported:
| :----------------------------------------------------------- | :------------------------------------ | | :----------------------------------------------------------- | :------------------------------------ |
| [Alibaba Cloud](https://www.alibabacloud.com/) | | | [Alibaba Cloud](https://www.alibabacloud.com/) | |
| [Tencent Cloud](https://www.tencentcloud.com/) | | | [Tencent Cloud](https://www.tencentcloud.com/) | |
| [Baidu AI Cloud](https://intl.cloud.baidu.com/) | |
| [Huawei Cloud](https://www.huaweicloud.com/) | | | [Huawei Cloud](https://www.huaweicloud.com/) | |
| [Volcengine](https://www.volcengine.com/) | | | [Volcengine](https://www.volcengine.com/) | |
| [JD Cloud](https://www.jdcloud.com/) | |
| [AWS Route53](https://aws.amazon.com/route53/) | | | [AWS Route53](https://aws.amazon.com/route53/) | |
| [Azure DNS](https://azure.microsoft.com/) | | | [Azure DNS](https://azure.microsoft.com/) | |
| [CloudFlare](https://www.cloudflare.com/) | | | [CloudFlare](https://www.cloudflare.com/) | |
| [ClouDNS](https://www.cloudns.net//) | | | [ClouDNS](https://www.cloudns.net/) | |
| [DNS.LA](https://www.dns.la/) | |
| [Gcore](https://gcore.com/) | |
| [GNAME](https://www.gname.com/) | | | [GNAME](https://www.gname.com/) | |
| [GoDaddy](https://www.godaddy.com/) | | | [GoDaddy](https://www.godaddy.com/) | |
| [Name.com](https://www.name.com/) | | | [Name.com](https://www.name.com/) | |
| [Namecheap](https://www.namecheap.com/) | |
| [NameSilo](https://www.namesilo.com/) | | | [NameSilo](https://www.namesilo.com/) | |
| [IBM NS1 Connect](https://www.ibm.com/products/ns1-connect/) | | | [IBM NS1 Connect](https://www.ibm.com/products/ns1-connect/) | |
| [CMCC Cloud](https://ecloud.10086.cn/) | |
| [Rain Yun](https://www.rainyun.com/) | | | [Rain Yun](https://www.rainyun.com/) | |
| [West.cn](https://www.west.cn/) | | | [West.cn](https://www.west.cn/) | |
| [PowerDNS](https://www.powerdns.com/) | | | [PowerDNS](https://www.powerdns.com/) | |
@ -116,23 +122,29 @@ The following hosting providers are supported:
<summary>[Fold/Unfold to view ...]</summary> <summary>[Fold/Unfold to view ...]</summary>
| Provider | Remarks | | Provider | Remarks |
| :---------------------------------------------- | :------------------------------------------------------------------------------- | | :---------------------------------------------- | :------------------------------------------------------------------------------------ |
| Local | Supports deployment to local servers | | Local | Supports deployment to local servers |
| SSH | Supports deployment to remote servers (via SSH+SFTP/SCP) | | SSH | Supports deployment to remote servers (via SSH+SFTP/SCP) |
| Webhook | Supports deployment to Webhook | | Webhook | Supports deployment to Webhook |
| [Kubernetes](https://kubernetes.io/) | Supports deployment to Kubernetes Secret | | [Kubernetes](https://kubernetes.io/) | Supports deployment to Kubernetes Secret |
| [Alibaba Cloud](https://www.alibabacloud.com/) | Supports deployment to Alibaba Cloud OSS, CDN, DCDN, SLB(CLB/ALB/NLB), WAF, Live | | [Alibaba Cloud](https://www.alibabacloud.com/) | Supports deployment to Alibaba Cloud OSS, CDN, DCDN, SLB(CLB/ALB/NLB), WAF, Live, VOD |
| [Tencent Cloud](https://www.tencentcloud.com/) | Supports deployment to Tencent Cloud COS, CDN, ECDN, EdgeOne, CLB, CSS | | [Tencent Cloud](https://www.tencentcloud.com/) | Supports deployment to Tencent Cloud COS, CDN, ECDN, EdgeOne, CLB, WAF, CSS, VOD |
| [Baidu AI Cloud](https://intl.cloud.baidu.com/) | Supports deployment to Baidu AI CLoud CDN | | [Baidu AI Cloud](https://intl.cloud.baidu.com/) | Supports deployment to Baidu AI CLoud CDN |
| [Huawei Cloud](https://www.huaweicloud.com/) | Supports deployment to Huawei Cloud CDN, ELB | | [Huawei Cloud](https://www.huaweicloud.com/) | Supports deployment to Huawei Cloud CDN, ELB, WAF |
| [Volcengine](https://www.volcengine.com/) | Supports deployment to Volcengine TOS, CDN, DCDN, CLB, Live | | [Volcengine](https://www.volcengine.com/) | Supports deployment to Volcengine TOS, CDN, DCDN, CLB, ImageX, Live |
| [JD Cloud](https://www.jdcloud.com/) | Supports deployment to JD Cloud CDN, ALB, Live Video, VOD |
| [Qiniu Cloud](https://www.qiniu.com/) | Supports deployment to Qiniu Cloud CDN, Pili | | [Qiniu Cloud](https://www.qiniu.com/) | Supports deployment to Qiniu Cloud CDN, Pili |
| [Baishan Cloud](https://intl.baishancloud.com/) | Supports deployment to Baishan Cloud CDN |
| [Doge Cloud](https://www.dogecloud.com/) | Supports deployment to Doge Cloud CDN | | [Doge Cloud](https://www.dogecloud.com/) | Supports deployment to Doge Cloud CDN |
| [BaoTa Panel](https://www.bt.cn/) | Supports deployment to BaoTa Panel sites |
| [UCloud](https://www.ucloud-global.com/) | Supports deployment to UCloud US3, UCDN | | [UCloud](https://www.ucloud-global.com/) | Supports deployment to UCloud US3, UCDN |
| [SafeLine](https://waf.chaitin.com/) | Supports deployment to SafeLine WAF |
| [BaoTa Panel](https://www.bt.cn/) | Supports deployment to BaoTa Panel sites |
| [AWS](https://aws.amazon.com/) | Supports deployment to AWS CloudFront | | [AWS](https://aws.amazon.com/) | Supports deployment to AWS CloudFront |
| [BytePlus](https://www.byteplus.com/) | Supports deployment to BytePlus CDN | | [BytePlus](https://www.byteplus.com/) | Supports deployment to BytePlus CDN |
| [CacheFly](https://www.cachefly.com/) | Supports deployment to CacheFly CDN |
| [Cdnfly](https://www.cdnfly.cn/) | Supports deployment to Cdnfly CDN |
| [Edgio](https://edg.io/) | Supports deployment to Edgio Applications | | [Edgio](https://edg.io/) | Supports deployment to Edgio Applications |
| [Gcore](https://gcore.com/) | Supports deployment to Gcore CDN |
</details> </details>

26
go.mod
View File

@ -19,12 +19,12 @@ require (
github.com/aliyun/aliyun-oss-go-sdk v3.0.2+incompatible github.com/aliyun/aliyun-oss-go-sdk v3.0.2+incompatible
github.com/aws/aws-sdk-go-v2/service/acm v1.30.18 github.com/aws/aws-sdk-go-v2/service/acm v1.30.18
github.com/aws/aws-sdk-go-v2/service/cloudfront v1.44.10 github.com/aws/aws-sdk-go-v2/service/cloudfront v1.44.10
github.com/baidubce/bce-sdk-go v0.9.216 github.com/baidubce/bce-sdk-go v0.9.217
github.com/byteplus-sdk/byteplus-sdk-golang v1.0.41 github.com/byteplus-sdk/byteplus-sdk-golang v1.0.41
github.com/go-acme/lego/v4 v4.21.0 github.com/go-acme/lego/v4 v4.22.2
github.com/go-resty/resty/v2 v2.16.5 github.com/go-resty/resty/v2 v2.16.5
github.com/go-viper/mapstructure/v2 v2.2.1 github.com/go-viper/mapstructure/v2 v2.2.1
github.com/huaweicloud/huaweicloud-sdk-go-v3 v0.1.135 github.com/huaweicloud/huaweicloud-sdk-go-v3 v0.1.136
github.com/nikoksr/notify v1.3.0 github.com/nikoksr/notify v1.3.0
github.com/pavlo-v-chernykh/keystore-go/v4 v4.5.0 github.com/pavlo-v-chernykh/keystore-go/v4 v4.5.0
github.com/pkg/sftp v1.13.7 github.com/pkg/sftp v1.13.7
@ -34,13 +34,13 @@ require (
github.com/qiniu/go-sdk/v7 v7.25.2 github.com/qiniu/go-sdk/v7 v7.25.2
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cdn v1.0.1096 github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cdn v1.0.1096
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/clb v1.0.1096 github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/clb v1.0.1096
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1096 github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1102
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/live v1.0.1096 github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/live v1.0.1096
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/ssl v1.0.1096 github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/ssl v1.0.1096
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/teo v1.0.1096 github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/teo v1.0.1096
github.com/ucloud/ucloud-sdk-go v0.22.31 github.com/ucloud/ucloud-sdk-go v0.22.31
github.com/volcengine/ve-tos-golang-sdk/v2 v2.7.9 github.com/volcengine/ve-tos-golang-sdk/v2 v2.7.9
github.com/volcengine/volc-sdk-golang v1.0.194 github.com/volcengine/volc-sdk-golang v1.0.195
github.com/volcengine/volcengine-go-sdk v1.0.180 github.com/volcengine/volcengine-go-sdk v1.0.180
golang.org/x/crypto v0.33.0 golang.org/x/crypto v0.33.0
golang.org/x/exp v0.0.0-20250210185358-939b2ce775ac golang.org/x/exp v0.0.0-20250210185358-939b2ce775ac
@ -57,11 +57,17 @@ require (
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/privatedns/armprivatedns v1.3.0 // indirect github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/privatedns/armprivatedns v1.3.0 // indirect
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resourcegraph/armresourcegraph v0.9.0 // indirect github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resourcegraph/armresourcegraph v0.9.0 // indirect
github.com/AzureAD/microsoft-authentication-library-for-go v1.3.2 // indirect github.com/AzureAD/microsoft-authentication-library-for-go v1.3.2 // indirect
github.com/G-Core/gcorelabscdn-go v1.0.26 // indirect
github.com/alibabacloud-go/openplatform-20191219/v2 v2.0.1 // indirect github.com/alibabacloud-go/openplatform-20191219/v2 v2.0.1 // indirect
github.com/alibabacloud-go/tea-fileform v1.1.1 // indirect github.com/alibabacloud-go/tea-fileform v1.1.1 // indirect
github.com/alibabacloud-go/tea-oss-sdk v1.1.3 // indirect github.com/alibabacloud-go/tea-oss-sdk v1.1.3 // indirect
github.com/alibabacloud-go/tea-oss-utils v1.1.0 // indirect github.com/alibabacloud-go/tea-oss-utils v1.1.0 // indirect
github.com/alibabacloud-go/tea-rpc v1.1.3 // indirect
github.com/alibabacloud-go/tea-rpc-utils v1.1.0 // indirect
github.com/alibabacloud-go/tea-utils/v2 v2.0.7 // indirect github.com/alibabacloud-go/tea-utils/v2 v2.0.7 // indirect
github.com/alibabacloud-go/vod-20170321 v1.0.1 // indirect
github.com/alibabacloud-go/vod-20170321/v4 v4.6.1 // indirect
github.com/avast/retry-go v3.0.0+incompatible // indirect
github.com/aws/aws-sdk-go-v2/service/route53 v1.48.1 // indirect github.com/aws/aws-sdk-go-v2/service/route53 v1.48.1 // indirect
github.com/blinkbean/dingtalk v1.1.3 // indirect github.com/blinkbean/dingtalk v1.1.3 // indirect
github.com/emicklei/go-restful/v3 v3.12.1 // indirect github.com/emicklei/go-restful/v3 v3.12.1 // indirect
@ -75,12 +81,14 @@ require (
github.com/go-playground/universal-translator v0.18.1 // indirect github.com/go-playground/universal-translator v0.18.1 // indirect
github.com/go-playground/validator/v10 v10.16.0 // indirect github.com/go-playground/validator/v10 v10.16.0 // indirect
github.com/go-telegram-bot-api/telegram-bot-api v4.6.4+incompatible // indirect github.com/go-telegram-bot-api/telegram-bot-api v4.6.4+incompatible // indirect
github.com/gofrs/uuid v4.4.0+incompatible // indirect
github.com/gogo/protobuf v1.3.2 // indirect github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang-jwt/jwt/v5 v5.2.1 // indirect github.com/golang-jwt/jwt/v5 v5.2.1 // indirect
github.com/golang/protobuf v1.5.4 // indirect github.com/golang/protobuf v1.5.4 // indirect
github.com/google/gnostic-models v0.6.9 // indirect github.com/google/gnostic-models v0.6.9 // indirect
github.com/google/go-cmp v0.6.0 // indirect github.com/google/go-cmp v0.6.0 // indirect
github.com/google/gofuzz v1.2.0 // indirect github.com/google/gofuzz v1.2.0 // indirect
github.com/jdcloud-api/jdcloud-sdk-go v1.62.0 // indirect
github.com/josharian/intern v1.0.0 // indirect github.com/josharian/intern v1.0.0 // indirect
github.com/kylelemons/godebug v1.1.0 // indirect github.com/kylelemons/godebug v1.1.0 // indirect
github.com/leodido/go-urn v1.4.0 // indirect github.com/leodido/go-urn v1.4.0 // indirect
@ -94,7 +102,11 @@ require (
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
github.com/sirupsen/logrus v1.9.3 // indirect github.com/sirupsen/logrus v1.9.3 // indirect
github.com/technoweenie/multipartstreamer v1.0.1 // indirect github.com/technoweenie/multipartstreamer v1.0.1 // indirect
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/vod v1.0.1102 // indirect
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/waf v1.0.1099 // indirect
github.com/x448/float16 v0.8.4 // indirect github.com/x448/float16 v0.8.4 // indirect
gitlab.ecloud.com/ecloud/ecloudsdkclouddns v1.0.1 // indirect
gitlab.ecloud.com/ecloud/ecloudsdkcore v1.0.0 // indirect
go.mongodb.org/mongo-driver v1.17.2 // indirect go.mongodb.org/mongo-driver v1.17.2 // indirect
gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/inf.v0 v0.9.1 // indirect
@ -201,3 +213,7 @@ require (
modernc.org/memory v1.8.2 // indirect modernc.org/memory v1.8.2 // indirect
modernc.org/sqlite v1.34.5 // indirect modernc.org/sqlite v1.34.5 // indirect
) )
replace gitlab.ecloud.com/ecloud/ecloudsdkcore v1.0.0 => ./internal/pkg/vendors/cmcc-sdk/ecloudsdkcore@v1.0.0
replace gitlab.ecloud.com/ecloud/ecloudsdkclouddns v1.0.1 => ./internal/pkg/vendors/cmcc-sdk/ecloudsdkclouddns@v1.0.1

33
go.sum
View File

@ -79,6 +79,8 @@ github.com/BurntSushi/toml v1.4.0 h1:kuoIxZQy2WRRk1pttg9asf+WVv6tWQuBNVmK8+nqPr0
github.com/BurntSushi/toml v1.4.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho= github.com/BurntSushi/toml v1.4.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ=
github.com/G-Core/gcorelabscdn-go v1.0.26 h1:22SqETUw64s+It/op1T7y3ukEOU62CJOsUcsfSkhvZs=
github.com/G-Core/gcorelabscdn-go v1.0.26/go.mod h1:iSGXaTvZBzDHQW+rKFS918BgFVpONcyLEijwh8WsXpE=
github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.25.0 h1:3c8yed4lgqTt+oTQ+JNMDo+F4xprBf+O/il4ZC0nRLw= github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.25.0 h1:3c8yed4lgqTt+oTQ+JNMDo+F4xprBf+O/il4ZC0nRLw=
github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.25.0/go.mod h1:obipzmGjfSjam60XLwGfqUkJsfiheAl+TUjG+4yzyPM= github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.25.0/go.mod h1:obipzmGjfSjam60XLwGfqUkJsfiheAl+TUjG+4yzyPM=
github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.49.0 h1:o90wcURuxekmXrtxmYWTyNla0+ZEHhud6DI1ZTxd1vI= github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.49.0 h1:o90wcURuxekmXrtxmYWTyNla0+ZEHhud6DI1ZTxd1vI=
@ -169,6 +171,11 @@ github.com/alibabacloud-go/tea-oss-sdk v1.1.3 h1:EhAHI6edMeqgkZEqP7r4nc9iMWAUBKG
github.com/alibabacloud-go/tea-oss-sdk v1.1.3/go.mod h1:yUnodpR3Bf2rudLE7V/Gft5txjJF30Pk+hH77K/Eab0= github.com/alibabacloud-go/tea-oss-sdk v1.1.3/go.mod h1:yUnodpR3Bf2rudLE7V/Gft5txjJF30Pk+hH77K/Eab0=
github.com/alibabacloud-go/tea-oss-utils v1.1.0 h1:y65crjjcZ2Pbb6UZtC2deuIZHDVTS3IaDWE7M9nVLRc= github.com/alibabacloud-go/tea-oss-utils v1.1.0 h1:y65crjjcZ2Pbb6UZtC2deuIZHDVTS3IaDWE7M9nVLRc=
github.com/alibabacloud-go/tea-oss-utils v1.1.0/go.mod h1:PFCF12e9yEKyBUIn7X1IrF/pNjvxgkHy0CgxX4+xRuY= github.com/alibabacloud-go/tea-oss-utils v1.1.0/go.mod h1:PFCF12e9yEKyBUIn7X1IrF/pNjvxgkHy0CgxX4+xRuY=
github.com/alibabacloud-go/tea-rpc v1.1.3 h1:uuxAIT9PB6MMABQfV/EMSnREZjh629WXu+hmPNF1IAs=
github.com/alibabacloud-go/tea-rpc v1.1.3/go.mod h1:uwhvnxPK69jcAYkVyP1WCFhTh1oVLiibUseSUpC7L8g=
github.com/alibabacloud-go/tea-rpc-utils v1.1.0 h1:kIG7+9sMRaDzvCbXfowycEwFRdnLAglRFQ/dnc0/JNE=
github.com/alibabacloud-go/tea-rpc-utils v1.1.0/go.mod h1:rxGY+fLbm3Fj3oJpeU0hBTmz52Ux50nm7JL01tyPv9c=
github.com/alibabacloud-go/tea-utils v1.3.0/go.mod h1:EI/o33aBfj3hETm4RLiAxF/ThQdSngxrpF8rKUDJjPE=
github.com/alibabacloud-go/tea-utils v1.3.1/go.mod h1:EI/o33aBfj3hETm4RLiAxF/ThQdSngxrpF8rKUDJjPE= github.com/alibabacloud-go/tea-utils v1.3.1/go.mod h1:EI/o33aBfj3hETm4RLiAxF/ThQdSngxrpF8rKUDJjPE=
github.com/alibabacloud-go/tea-utils v1.3.6/go.mod h1:EI/o33aBfj3hETm4RLiAxF/ThQdSngxrpF8rKUDJjPE= github.com/alibabacloud-go/tea-utils v1.3.6/go.mod h1:EI/o33aBfj3hETm4RLiAxF/ThQdSngxrpF8rKUDJjPE=
github.com/alibabacloud-go/tea-utils v1.4.5 h1:h0/6Xd2f3bPE4XHTvkpjwxowIwRCJAJOqY6Eq8f3zfA= github.com/alibabacloud-go/tea-utils v1.4.5 h1:h0/6Xd2f3bPE4XHTvkpjwxowIwRCJAJOqY6Eq8f3zfA=
@ -184,12 +191,17 @@ github.com/alibabacloud-go/tea-xml v1.1.1/go.mod h1:Rq08vgCcCAjHyRi/M7xlHKUykZCE
github.com/alibabacloud-go/tea-xml v1.1.2/go.mod h1:Rq08vgCcCAjHyRi/M7xlHKUykZCEtyBy9+DPF6GgEu8= github.com/alibabacloud-go/tea-xml v1.1.2/go.mod h1:Rq08vgCcCAjHyRi/M7xlHKUykZCEtyBy9+DPF6GgEu8=
github.com/alibabacloud-go/tea-xml v1.1.3 h1:7LYnm+JbOq2B+T/B0fHC4Ies4/FofC4zHzYtqw7dgt0= github.com/alibabacloud-go/tea-xml v1.1.3 h1:7LYnm+JbOq2B+T/B0fHC4Ies4/FofC4zHzYtqw7dgt0=
github.com/alibabacloud-go/tea-xml v1.1.3/go.mod h1:Rq08vgCcCAjHyRi/M7xlHKUykZCEtyBy9+DPF6GgEu8= github.com/alibabacloud-go/tea-xml v1.1.3/go.mod h1:Rq08vgCcCAjHyRi/M7xlHKUykZCEtyBy9+DPF6GgEu8=
github.com/alibabacloud-go/vod-20170321 v1.0.1 h1:ZiBggVoJegu0Q3iarHZyveTOJJE0kUym6RCSLM9epoc=
github.com/alibabacloud-go/vod-20170321 v1.0.1/go.mod h1:eKaYMCAd22pgBFMz0Ci/o2l+UJSrq24LLSF/XyaTiac=
github.com/alibabacloud-go/vod-20170321/v4 v4.6.1 h1:6JTNq23lMo3wOui5qjpUJu2VKBgSHR4ArMgbKDOej7Q=
github.com/alibabacloud-go/vod-20170321/v4 v4.6.1/go.mod h1:TkgLKMSLu0qZN8Qdcu8svfHREyI64kjFvrp/GhrD4VQ=
github.com/alibabacloud-go/waf-openapi-20211001/v5 v5.0.4 h1:Od0KgA73DyG9X2XFwuZZTkDv2pzA6B5mhYapyyca6QE= github.com/alibabacloud-go/waf-openapi-20211001/v5 v5.0.4 h1:Od0KgA73DyG9X2XFwuZZTkDv2pzA6B5mhYapyyca6QE=
github.com/alibabacloud-go/waf-openapi-20211001/v5 v5.0.4/go.mod h1:DohGoS8BnMxHXghHebtjPP7+GMdxPsRN19T3nn2HcCU= github.com/alibabacloud-go/waf-openapi-20211001/v5 v5.0.4/go.mod h1:DohGoS8BnMxHXghHebtjPP7+GMdxPsRN19T3nn2HcCU=
github.com/aliyun/alibaba-cloud-sdk-go v1.63.83 h1:YBkf7H5CSgrlb3C1aWcpDt7Vk8UEGFPeD2OOirtt6IM= github.com/aliyun/alibaba-cloud-sdk-go v1.63.83 h1:YBkf7H5CSgrlb3C1aWcpDt7Vk8UEGFPeD2OOirtt6IM=
github.com/aliyun/alibaba-cloud-sdk-go v1.63.83/go.mod h1:SOSDHfe1kX91v3W5QiBsWSLqeLxImobbMX1mxrFHsVQ= github.com/aliyun/alibaba-cloud-sdk-go v1.63.83/go.mod h1:SOSDHfe1kX91v3W5QiBsWSLqeLxImobbMX1mxrFHsVQ=
github.com/aliyun/aliyun-oss-go-sdk v3.0.2+incompatible h1:8psS8a+wKfiLt1iVDX79F7Y6wUM49Lcha2FMXt4UM8g= github.com/aliyun/aliyun-oss-go-sdk v3.0.2+incompatible h1:8psS8a+wKfiLt1iVDX79F7Y6wUM49Lcha2FMXt4UM8g=
github.com/aliyun/aliyun-oss-go-sdk v3.0.2+incompatible/go.mod h1:T/Aws4fEfogEE9v+HPhhw+CntffsBHJ8nXQCwKr0/g8= github.com/aliyun/aliyun-oss-go-sdk v3.0.2+incompatible/go.mod h1:T/Aws4fEfogEE9v+HPhhw+CntffsBHJ8nXQCwKr0/g8=
github.com/aliyun/credentials-go v1.1.0/go.mod h1:ZXrrxv386Mj6z8NpihLKpexQE550m7j3LlyCvYub9aE=
github.com/aliyun/credentials-go v1.1.2/go.mod h1:ozcZaMR5kLM7pwtCMEpVmQ242suV6qTJya2bDq4X1Tw= github.com/aliyun/credentials-go v1.1.2/go.mod h1:ozcZaMR5kLM7pwtCMEpVmQ242suV6qTJya2bDq4X1Tw=
github.com/aliyun/credentials-go v1.3.1/go.mod h1:8jKYhQuDawt8x2+fusqa1Y6mPxemTsBEN04dgcAcYz0= github.com/aliyun/credentials-go v1.3.1/go.mod h1:8jKYhQuDawt8x2+fusqa1Y6mPxemTsBEN04dgcAcYz0=
github.com/aliyun/credentials-go v1.3.6/go.mod h1:1LxUuX7L5YrZUWzBrRyk0SwSdH4OmPrib8NVePL3fxM= github.com/aliyun/credentials-go v1.3.6/go.mod h1:1LxUuX7L5YrZUWzBrRyk0SwSdH4OmPrib8NVePL3fxM=
@ -205,6 +217,7 @@ github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgI
github.com/asaskevich/govalidator v0.0.0-20200108200545-475eaeb16496/go.mod h1:oGkLhpf+kjZl6xBf758TQhh5XrAeiJv/7FRz/2spLIg= github.com/asaskevich/govalidator v0.0.0-20200108200545-475eaeb16496/go.mod h1:oGkLhpf+kjZl6xBf758TQhh5XrAeiJv/7FRz/2spLIg=
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3dyBCFEj5IhUbnKptjxatkF07cF2ak3yi77so= github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3dyBCFEj5IhUbnKptjxatkF07cF2ak3yi77so=
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw=
github.com/avast/retry-go v3.0.0+incompatible h1:4SOWQ7Qs+oroOTQOYnAHqelpCO0biHSxpiH9JdtuBj0=
github.com/avast/retry-go v3.0.0+incompatible/go.mod h1:XtSnn+n/sHqQIpZ10K1qAevBhOOCWBLXXy3hyiqqBrY= github.com/avast/retry-go v3.0.0+incompatible/go.mod h1:XtSnn+n/sHqQIpZ10K1qAevBhOOCWBLXXy3hyiqqBrY=
github.com/aws/aws-sdk-go v1.40.45/go.mod h1:585smgzpB/KqRA+K3y/NL/oYRqQvpNJYvLm+LY1U59Q= github.com/aws/aws-sdk-go v1.40.45/go.mod h1:585smgzpB/KqRA+K3y/NL/oYRqQvpNJYvLm+LY1U59Q=
github.com/aws/aws-sdk-go v1.55.5 h1:KKUZBfBoyqy5d3swXyiC7Q76ic40rYcbqH7qjh59kzU= github.com/aws/aws-sdk-go v1.55.5 h1:KKUZBfBoyqy5d3swXyiC7Q76ic40rYcbqH7qjh59kzU=
@ -258,6 +271,8 @@ github.com/aws/smithy-go v1.22.2 h1:6D9hW43xKFrRx/tXXfAlIZc4JI+yQe6snnWcQyxSyLQ=
github.com/aws/smithy-go v1.22.2/go.mod h1:irrKGvNn1InZwb2d7fkIRNucdfwR8R+Ts3wxYa/cJHg= github.com/aws/smithy-go v1.22.2/go.mod h1:irrKGvNn1InZwb2d7fkIRNucdfwR8R+Ts3wxYa/cJHg=
github.com/baidubce/bce-sdk-go v0.9.216 h1:jRq4C1UGYcvHo6Gst2kuUzhWwJM6EqXCmhIsTKQvf4k= github.com/baidubce/bce-sdk-go v0.9.216 h1:jRq4C1UGYcvHo6Gst2kuUzhWwJM6EqXCmhIsTKQvf4k=
github.com/baidubce/bce-sdk-go v0.9.216/go.mod h1:zbYJMQwE4IZuyrJiFO8tO8NbtYiKTFTbwh4eIsqjVdg= github.com/baidubce/bce-sdk-go v0.9.216/go.mod h1:zbYJMQwE4IZuyrJiFO8tO8NbtYiKTFTbwh4eIsqjVdg=
github.com/baidubce/bce-sdk-go v0.9.217 h1:dbMeVzpr9BGItTFHB1s2KSrpz0ayJC1y366VUMmaF0k=
github.com/baidubce/bce-sdk-go v0.9.217/go.mod h1:zbYJMQwE4IZuyrJiFO8tO8NbtYiKTFTbwh4eIsqjVdg=
github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
@ -361,6 +376,8 @@ github.com/ganigeorgiev/fexpr v0.4.1/go.mod h1:RyGiGqmeXhEQ6+mlGdnUleLHgtzzu/VGO
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/go-acme/lego/v4 v4.21.0 h1:arEW+8o5p7VI8Bk1kr/PDlgD1DrxtTH1gJ4b7mehL8o= github.com/go-acme/lego/v4 v4.21.0 h1:arEW+8o5p7VI8Bk1kr/PDlgD1DrxtTH1gJ4b7mehL8o=
github.com/go-acme/lego/v4 v4.21.0/go.mod h1:HrSWzm3Ckj45Ie3i+p1zKVobbQoMOaGu9m4up0dUeDI= github.com/go-acme/lego/v4 v4.21.0/go.mod h1:HrSWzm3Ckj45Ie3i+p1zKVobbQoMOaGu9m4up0dUeDI=
github.com/go-acme/lego/v4 v4.22.2 h1:ck+HllWrV/rZGeYohsKQ5iKNnU/WAZxwOdiu6cxky+0=
github.com/go-acme/lego/v4 v4.22.2/go.mod h1:E2FndyI3Ekv0usNJt46mFb9LVpV/XBYT+4E3tz02Tzo=
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= 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-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-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
@ -422,6 +439,8 @@ github.com/goccy/go-json v0.10.4 h1:JSwxQzIqKfmFX1swYPpUThQZp/Ka4wzJdK0LWVytLPM=
github.com/goccy/go-json v0.10.4/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M= github.com/goccy/go-json v0.10.4/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M=
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU=
github.com/gofrs/uuid v4.4.0+incompatible h1:3qXRTX8/NbyulANqlc0lchS1gqAVxRgsuW1YrTJupqA=
github.com/gofrs/uuid v4.4.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
@ -557,6 +576,8 @@ github.com/hashicorp/serf v0.9.5/go.mod h1:UWDWwZeL5cuWDJdl0C6wrvrUwEqtQ4ZKBKKEN
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/huaweicloud/huaweicloud-sdk-go-v3 v0.1.135 h1:UbNMlPfh0GhRY3iVkvv4fXFJ+bLqXoVCwjqe6geFdPs= github.com/huaweicloud/huaweicloud-sdk-go-v3 v0.1.135 h1:UbNMlPfh0GhRY3iVkvv4fXFJ+bLqXoVCwjqe6geFdPs=
github.com/huaweicloud/huaweicloud-sdk-go-v3 v0.1.135/go.mod h1:Y/+YLCFCJtS29i2MbYPTUlNNfwXvkzEsZKR0imY/2aY= github.com/huaweicloud/huaweicloud-sdk-go-v3 v0.1.135/go.mod h1:Y/+YLCFCJtS29i2MbYPTUlNNfwXvkzEsZKR0imY/2aY=
github.com/huaweicloud/huaweicloud-sdk-go-v3 v0.1.136 h1:T785NUg5245nWpPVHLVR8lBd+zGQYR14Vi/TCX1iu3A=
github.com/huaweicloud/huaweicloud-sdk-go-v3 v0.1.136/go.mod h1:Y/+YLCFCJtS29i2MbYPTUlNNfwXvkzEsZKR0imY/2aY=
github.com/hudl/fargo v1.4.0/go.mod h1:9Ai6uvFy5fQNq6VPKtg+Ceq1+eTY4nKUlR2JElEOcDo= github.com/hudl/fargo v1.4.0/go.mod h1:9Ai6uvFy5fQNq6VPKtg+Ceq1+eTY4nKUlR2JElEOcDo=
github.com/iancoleman/strcase v0.3.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho= github.com/iancoleman/strcase v0.3.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho=
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
@ -569,6 +590,8 @@ github.com/jcmturner/gofork v1.0.0/go.mod h1:MK8+TM0La+2rjBD4jE12Kj1pCCxK7d2LK/U
github.com/jcmturner/goidentity/v6 v6.0.1/go.mod h1:X1YW3bgtvwAXju7V3LCIMpY0Gbxyjn/mY9zx4tFonSg= 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.2/go.mod h1:sb+Xq/fTY5yktf/VxLsE3wlfPqQjp0aWNYyvBVK62bc=
github.com/jcmturner/rpc/v2 v2.0.3/go.mod h1:VUJYCIDm3PVOEHw8sgt091/20OJjskO/YJki3ELg/Hc= github.com/jcmturner/rpc/v2 v2.0.3/go.mod h1:VUJYCIDm3PVOEHw8sgt091/20OJjskO/YJki3ELg/Hc=
github.com/jdcloud-api/jdcloud-sdk-go v1.62.0 h1:uPfyOSY16mBrhggriDNeySFB4ZkzMMXpNac2P0fbDRw=
github.com/jdcloud-api/jdcloud-sdk-go v1.62.0/go.mod h1:UrKjuULIWLjHFlG6aSPunArE5QX57LftMmStAZJBEX8=
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg=
github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo=
@ -826,6 +849,10 @@ github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/clb v1.0.1096/go.mod h1
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1084/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1084/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1096 h1:DMokC7T0UF8wMfT1kD+mX3M+hc2C06gmFvQ9gsfRPmI= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1096 h1:DMokC7T0UF8wMfT1kD+mX3M+hc2C06gmFvQ9gsfRPmI=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1096/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1096/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1099 h1:4fQ53ORk6Eayw1H2kg43PoBnUuhGR6WRG6rtec/i3oI=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1099/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1102 h1:DxsNhw67OHyQME20IULmi8lgNY9MHuQ+qS1XH1/yTvM=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1102/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dnspod v1.0.1084 h1:kwctN0WQYt8/iKP+iRCTCwdzEMIXsXklbRIib5rjeQ8= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dnspod v1.0.1084 h1:kwctN0WQYt8/iKP+iRCTCwdzEMIXsXklbRIib5rjeQ8=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dnspod v1.0.1084/go.mod h1:qE67ApiBzeRvzeDsV+GxyIDbVIDemsKpHXllQATz/Vw= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dnspod v1.0.1084/go.mod h1:qE67ApiBzeRvzeDsV+GxyIDbVIDemsKpHXllQATz/Vw=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/live v1.0.1096 h1:h9FP40Ycg45egJlZcjbLyc4IUeFoq+wSpR43sHMALtM= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/live v1.0.1096 h1:h9FP40Ycg45egJlZcjbLyc4IUeFoq+wSpR43sHMALtM=
@ -834,6 +861,10 @@ github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/ssl v1.0.1096 h1:7ZmPus
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/ssl v1.0.1096/go.mod h1:aMpGcDskqqhXtfMaeo2egO61tgh/zt07L1ohSPwmjWk= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/ssl v1.0.1096/go.mod h1:aMpGcDskqqhXtfMaeo2egO61tgh/zt07L1ohSPwmjWk=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/teo v1.0.1096 h1:N62IFKL1ZRNQ7WPLNn8x9eYnwM4lOUIVY3buW6kbGtg= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/teo v1.0.1096 h1:N62IFKL1ZRNQ7WPLNn8x9eYnwM4lOUIVY3buW6kbGtg=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/teo v1.0.1096/go.mod h1:4PZRRpZp+jvYBUbUajsoZREnk7sJXMnPAiGB4IX8IkM= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/teo v1.0.1096/go.mod h1:4PZRRpZp+jvYBUbUajsoZREnk7sJXMnPAiGB4IX8IkM=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/vod v1.0.1102 h1:B0mJk0ojVOFCMLrBoxLNVgrGih11EezTekRffkACCAY=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/vod v1.0.1102/go.mod h1:0yyQ1r35jteb5DV4mcJZ5uh9NStWzjMYz9iSMnDMdJA=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/waf v1.0.1099 h1:kD+8RKF0uJCr7VaurAUA11NNAoln0HaagMCgQV6EnUw=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/waf v1.0.1099/go.mod h1:ellbjD8eHKHS4ixscLdiPJI8QoFIk0YNEgaDjxXMECM=
github.com/tjfoc/gmsm v1.3.2/go.mod h1:HaUcFuY0auTiaHB9MHFGCPx5IaLhTUd2atbCFBQXn9w= 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 h1:aMe1GlZb+0bLjn+cKTPEvvn9oUEBlJitaZiiBwsbgho=
github.com/tjfoc/gmsm v1.4.1/go.mod h1:j4INPkHWMrhJb38G+J6W4Tw0AbuN8Thu3PbdVYhVcTE= github.com/tjfoc/gmsm v1.4.1/go.mod h1:j4INPkHWMrhJb38G+J6W4Tw0AbuN8Thu3PbdVYhVcTE=
@ -850,6 +881,8 @@ github.com/volcengine/ve-tos-golang-sdk/v2 v2.7.9/go.mod h1:IrjK84IJJTuOZOTMv/P1
github.com/volcengine/volc-sdk-golang v1.0.23/go.mod h1:AfG/PZRUkHJ9inETvbjNifTDgut25Wbkm2QoYBTbvyU= github.com/volcengine/volc-sdk-golang v1.0.23/go.mod h1:AfG/PZRUkHJ9inETvbjNifTDgut25Wbkm2QoYBTbvyU=
github.com/volcengine/volc-sdk-golang v1.0.194 h1:3o0INQzdtYJWvdGrtX02booCqPL5TsWSq2W1Ur7Bzlo= github.com/volcengine/volc-sdk-golang v1.0.194 h1:3o0INQzdtYJWvdGrtX02booCqPL5TsWSq2W1Ur7Bzlo=
github.com/volcengine/volc-sdk-golang v1.0.194/go.mod h1:u0VtPvlXWpXDTmc9IHkaW1q+5Jjwus4oAqRhNMDRInE= github.com/volcengine/volc-sdk-golang v1.0.194/go.mod h1:u0VtPvlXWpXDTmc9IHkaW1q+5Jjwus4oAqRhNMDRInE=
github.com/volcengine/volc-sdk-golang v1.0.195 h1:hKX4pBhmKcB3652BTdcAmtgizEPBnoQUpTM+j5blMA4=
github.com/volcengine/volc-sdk-golang v1.0.195/go.mod h1:stZX+EPgv1vF4nZwOlEe8iGcriUPRBKX8zA19gXycOQ=
github.com/volcengine/volcengine-go-sdk v1.0.180 h1:lzcNlaxeGIUdXgDuVH7KJwZYZjIZzaCAYPDh91htU6U= github.com/volcengine/volcengine-go-sdk v1.0.180 h1:lzcNlaxeGIUdXgDuVH7KJwZYZjIZzaCAYPDh91htU6U=
github.com/volcengine/volcengine-go-sdk v1.0.180/go.mod h1:gfEDc1s7SYaGoY+WH2dRrS3qiuDJMkwqyfXWCa7+7oA= github.com/volcengine/volcengine-go-sdk v1.0.180/go.mod h1:gfEDc1s7SYaGoY+WH2dRrS3qiuDJMkwqyfXWCa7+7oA=
github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=

View File

@ -6,23 +6,29 @@ import (
"github.com/go-acme/lego/v4/challenge" "github.com/go-acme/lego/v4/challenge"
"github.com/usual2970/certimate/internal/domain" "github.com/usual2970/certimate/internal/domain"
providerACMEHttpReq "github.com/usual2970/certimate/internal/pkg/core/applicant/acme-dns-01/lego-providers/acmehttpreq" pACMEHttpReq "github.com/usual2970/certimate/internal/pkg/core/applicant/acme-dns-01/lego-providers/acmehttpreq"
providerAliyun "github.com/usual2970/certimate/internal/pkg/core/applicant/acme-dns-01/lego-providers/aliyun" pAliyun "github.com/usual2970/certimate/internal/pkg/core/applicant/acme-dns-01/lego-providers/aliyun"
providerAWSRoute53 "github.com/usual2970/certimate/internal/pkg/core/applicant/acme-dns-01/lego-providers/aws-route53" pAWSRoute53 "github.com/usual2970/certimate/internal/pkg/core/applicant/acme-dns-01/lego-providers/aws-route53"
providerAzureDNS "github.com/usual2970/certimate/internal/pkg/core/applicant/acme-dns-01/lego-providers/azure-dns" pAzureDNS "github.com/usual2970/certimate/internal/pkg/core/applicant/acme-dns-01/lego-providers/azure-dns"
providerCloudflare "github.com/usual2970/certimate/internal/pkg/core/applicant/acme-dns-01/lego-providers/cloudflare" pBaiduCloud "github.com/usual2970/certimate/internal/pkg/core/applicant/acme-dns-01/lego-providers/baiducloud"
providerClouDNS "github.com/usual2970/certimate/internal/pkg/core/applicant/acme-dns-01/lego-providers/cloudns" pCloudflare "github.com/usual2970/certimate/internal/pkg/core/applicant/acme-dns-01/lego-providers/cloudflare"
providerGname "github.com/usual2970/certimate/internal/pkg/core/applicant/acme-dns-01/lego-providers/gname" pClouDNS "github.com/usual2970/certimate/internal/pkg/core/applicant/acme-dns-01/lego-providers/cloudns"
providerGoDaddy "github.com/usual2970/certimate/internal/pkg/core/applicant/acme-dns-01/lego-providers/godaddy" pCMCCCloud "github.com/usual2970/certimate/internal/pkg/core/applicant/acme-dns-01/lego-providers/cmcccloud"
providerHuaweiCloud "github.com/usual2970/certimate/internal/pkg/core/applicant/acme-dns-01/lego-providers/huaweicloud" pDNSLA "github.com/usual2970/certimate/internal/pkg/core/applicant/acme-dns-01/lego-providers/dnsla"
providerNameDotCom "github.com/usual2970/certimate/internal/pkg/core/applicant/acme-dns-01/lego-providers/namedotcom" pGcore "github.com/usual2970/certimate/internal/pkg/core/applicant/acme-dns-01/lego-providers/gcore"
providerNameSilo "github.com/usual2970/certimate/internal/pkg/core/applicant/acme-dns-01/lego-providers/namesilo" pGname "github.com/usual2970/certimate/internal/pkg/core/applicant/acme-dns-01/lego-providers/gname"
providerNS1 "github.com/usual2970/certimate/internal/pkg/core/applicant/acme-dns-01/lego-providers/ns1" pGoDaddy "github.com/usual2970/certimate/internal/pkg/core/applicant/acme-dns-01/lego-providers/godaddy"
providerPowerDNS "github.com/usual2970/certimate/internal/pkg/core/applicant/acme-dns-01/lego-providers/powerdns" pHuaweiCloud "github.com/usual2970/certimate/internal/pkg/core/applicant/acme-dns-01/lego-providers/huaweicloud"
providerRainYun "github.com/usual2970/certimate/internal/pkg/core/applicant/acme-dns-01/lego-providers/rainyun" pJDCloud "github.com/usual2970/certimate/internal/pkg/core/applicant/acme-dns-01/lego-providers/jdcloud"
providerTencentCloud "github.com/usual2970/certimate/internal/pkg/core/applicant/acme-dns-01/lego-providers/tencentcloud" pNamecheap "github.com/usual2970/certimate/internal/pkg/core/applicant/acme-dns-01/lego-providers/namecheap"
providerVolcEngine "github.com/usual2970/certimate/internal/pkg/core/applicant/acme-dns-01/lego-providers/volcengine" pNameDotCom "github.com/usual2970/certimate/internal/pkg/core/applicant/acme-dns-01/lego-providers/namedotcom"
providerWestcn "github.com/usual2970/certimate/internal/pkg/core/applicant/acme-dns-01/lego-providers/westcn" pNameSilo "github.com/usual2970/certimate/internal/pkg/core/applicant/acme-dns-01/lego-providers/namesilo"
pNS1 "github.com/usual2970/certimate/internal/pkg/core/applicant/acme-dns-01/lego-providers/ns1"
pPowerDNS "github.com/usual2970/certimate/internal/pkg/core/applicant/acme-dns-01/lego-providers/powerdns"
pRainYun "github.com/usual2970/certimate/internal/pkg/core/applicant/acme-dns-01/lego-providers/rainyun"
pTencentCloud "github.com/usual2970/certimate/internal/pkg/core/applicant/acme-dns-01/lego-providers/tencentcloud"
pVolcEngine "github.com/usual2970/certimate/internal/pkg/core/applicant/acme-dns-01/lego-providers/volcengine"
pWestcn "github.com/usual2970/certimate/internal/pkg/core/applicant/acme-dns-01/lego-providers/westcn"
"github.com/usual2970/certimate/internal/pkg/utils/maps" "github.com/usual2970/certimate/internal/pkg/utils/maps"
) )
@ -39,7 +45,7 @@ func createApplicant(options *applicantOptions) (challenge.Provider, error) {
return nil, fmt.Errorf("failed to populate provider access config: %w", err) return nil, fmt.Errorf("failed to populate provider access config: %w", err)
} }
applicant, err := providerACMEHttpReq.NewChallengeProvider(&providerACMEHttpReq.ACMEHttpReqApplicantConfig{ applicant, err := pACMEHttpReq.NewChallengeProvider(&pACMEHttpReq.ChallengeProviderConfig{
Endpoint: access.Endpoint, Endpoint: access.Endpoint,
Mode: access.Mode, Mode: access.Mode,
Username: access.Username, Username: access.Username,
@ -56,7 +62,7 @@ func createApplicant(options *applicantOptions) (challenge.Provider, error) {
return nil, fmt.Errorf("failed to populate provider access config: %w", err) return nil, fmt.Errorf("failed to populate provider access config: %w", err)
} }
applicant, err := providerAliyun.NewChallengeProvider(&providerAliyun.AliyunApplicantConfig{ applicant, err := pAliyun.NewChallengeProvider(&pAliyun.ChallengeProviderConfig{
AccessKeyId: access.AccessKeyId, AccessKeyId: access.AccessKeyId,
AccessKeySecret: access.AccessKeySecret, AccessKeySecret: access.AccessKeySecret,
DnsPropagationTimeout: options.DnsPropagationTimeout, DnsPropagationTimeout: options.DnsPropagationTimeout,
@ -72,7 +78,7 @@ func createApplicant(options *applicantOptions) (challenge.Provider, error) {
return nil, fmt.Errorf("failed to populate provider access config: %w", err) return nil, fmt.Errorf("failed to populate provider access config: %w", err)
} }
applicant, err := providerAWSRoute53.NewChallengeProvider(&providerAWSRoute53.AWSRoute53ApplicantConfig{ applicant, err := pAWSRoute53.NewChallengeProvider(&pAWSRoute53.ChallengeProviderConfig{
AccessKeyId: access.AccessKeyId, AccessKeyId: access.AccessKeyId,
SecretAccessKey: access.SecretAccessKey, SecretAccessKey: access.SecretAccessKey,
Region: maps.GetValueAsString(options.ProviderApplyConfig, "region"), Region: maps.GetValueAsString(options.ProviderApplyConfig, "region"),
@ -83,14 +89,14 @@ func createApplicant(options *applicantOptions) (challenge.Provider, error) {
return applicant, err return applicant, err
} }
case domain.ApplyDNSProviderTypeAzureDNS: case domain.ApplyDNSProviderTypeAzure, domain.ApplyDNSProviderTypeAzureDNS:
{ {
access := domain.AccessConfigForAzure{} access := domain.AccessConfigForAzure{}
if err := maps.Populate(options.ProviderAccessConfig, &access); err != nil { if err := maps.Populate(options.ProviderAccessConfig, &access); err != nil {
return nil, fmt.Errorf("failed to populate provider access config: %w", err) return nil, fmt.Errorf("failed to populate provider access config: %w", err)
} }
applicant, err := providerAzureDNS.NewChallengeProvider(&providerAzureDNS.AzureDNSApplicantConfig{ applicant, err := pAzureDNS.NewChallengeProvider(&pAzureDNS.ChallengeProviderConfig{
TenantId: access.TenantId, TenantId: access.TenantId,
ClientId: access.ClientId, ClientId: access.ClientId,
ClientSecret: access.ClientSecret, ClientSecret: access.ClientSecret,
@ -101,6 +107,22 @@ func createApplicant(options *applicantOptions) (challenge.Provider, error) {
return applicant, err return applicant, err
} }
case domain.ApplyDNSProviderTypeBaiduCloud, domain.ApplyDNSProviderTypeBaiduCloudDNS:
{
access := domain.AccessConfigForBaiduCloud{}
if err := maps.Populate(options.ProviderAccessConfig, &access); err != nil {
return nil, fmt.Errorf("failed to populate provider access config: %w", err)
}
applicant, err := pBaiduCloud.NewChallengeProvider(&pBaiduCloud.ChallengeProviderConfig{
AccessKeyId: access.AccessKeyId,
SecretAccessKey: access.SecretAccessKey,
DnsPropagationTimeout: options.DnsPropagationTimeout,
DnsTTL: options.DnsTTL,
})
return applicant, err
}
case domain.ApplyDNSProviderTypeCloudflare: case domain.ApplyDNSProviderTypeCloudflare:
{ {
access := domain.AccessConfigForCloudflare{} access := domain.AccessConfigForCloudflare{}
@ -108,7 +130,7 @@ func createApplicant(options *applicantOptions) (challenge.Provider, error) {
return nil, fmt.Errorf("failed to populate provider access config: %w", err) return nil, fmt.Errorf("failed to populate provider access config: %w", err)
} }
applicant, err := providerCloudflare.NewChallengeProvider(&providerCloudflare.CloudflareApplicantConfig{ applicant, err := pCloudflare.NewChallengeProvider(&pCloudflare.ChallengeProviderConfig{
DnsApiToken: access.DnsApiToken, DnsApiToken: access.DnsApiToken,
DnsPropagationTimeout: options.DnsPropagationTimeout, DnsPropagationTimeout: options.DnsPropagationTimeout,
DnsTTL: options.DnsTTL, DnsTTL: options.DnsTTL,
@ -123,7 +145,7 @@ func createApplicant(options *applicantOptions) (challenge.Provider, error) {
return nil, fmt.Errorf("failed to populate provider access config: %w", err) return nil, fmt.Errorf("failed to populate provider access config: %w", err)
} }
applicant, err := providerClouDNS.NewChallengeProvider(&providerClouDNS.ClouDNSApplicantConfig{ applicant, err := pClouDNS.NewChallengeProvider(&pClouDNS.ChallengeProviderConfig{
AuthId: access.AuthId, AuthId: access.AuthId,
AuthPassword: access.AuthPassword, AuthPassword: access.AuthPassword,
DnsPropagationTimeout: options.DnsPropagationTimeout, DnsPropagationTimeout: options.DnsPropagationTimeout,
@ -132,6 +154,53 @@ func createApplicant(options *applicantOptions) (challenge.Provider, error) {
return applicant, err return applicant, err
} }
case domain.ApplyDNSProviderTypeCMCCCloud:
{
access := domain.AccessConfigForCMCCCloud{}
if err := maps.Populate(options.ProviderAccessConfig, &access); err != nil {
return nil, fmt.Errorf("failed to populate provider access config: %w", err)
}
applicant, err := pCMCCCloud.NewChallengeProvider(&pCMCCCloud.ChallengeProviderConfig{
AccessKeyId: access.AccessKeyId,
AccessKeySecret: access.AccessKeySecret,
DnsPropagationTimeout: options.DnsPropagationTimeout,
DnsTTL: options.DnsTTL,
})
return applicant, err
}
case domain.ApplyDNSProviderTypeDNSLA:
{
access := domain.AccessConfigForDNSLA{}
if err := maps.Populate(options.ProviderAccessConfig, &access); err != nil {
return nil, fmt.Errorf("failed to populate provider access config: %w", err)
}
applicant, err := pDNSLA.NewChallengeProvider(&pDNSLA.ChallengeProviderConfig{
ApiId: access.ApiId,
ApiSecret: access.ApiSecret,
DnsPropagationTimeout: options.DnsPropagationTimeout,
DnsTTL: options.DnsTTL,
})
return applicant, err
}
case domain.ApplyDNSProviderTypeGcore:
{
access := domain.AccessConfigForGcore{}
if err := maps.Populate(options.ProviderAccessConfig, &access); err != nil {
return nil, fmt.Errorf("failed to populate provider access config: %w", err)
}
applicant, err := pGcore.NewChallengeProvider(&pGcore.ChallengeProviderConfig{
ApiToken: access.ApiToken,
DnsPropagationTimeout: options.DnsPropagationTimeout,
DnsTTL: options.DnsTTL,
})
return applicant, err
}
case domain.ApplyDNSProviderTypeGname: case domain.ApplyDNSProviderTypeGname:
{ {
access := domain.AccessConfigForGname{} access := domain.AccessConfigForGname{}
@ -139,7 +208,7 @@ func createApplicant(options *applicantOptions) (challenge.Provider, error) {
return nil, fmt.Errorf("failed to populate provider access config: %w", err) return nil, fmt.Errorf("failed to populate provider access config: %w", err)
} }
applicant, err := providerGname.NewChallengeProvider(&providerGname.GnameApplicantConfig{ applicant, err := pGname.NewChallengeProvider(&pGname.ChallengeProviderConfig{
AppId: access.AppId, AppId: access.AppId,
AppKey: access.AppKey, AppKey: access.AppKey,
DnsPropagationTimeout: options.DnsPropagationTimeout, DnsPropagationTimeout: options.DnsPropagationTimeout,
@ -155,7 +224,7 @@ func createApplicant(options *applicantOptions) (challenge.Provider, error) {
return nil, fmt.Errorf("failed to populate provider access config: %w", err) return nil, fmt.Errorf("failed to populate provider access config: %w", err)
} }
applicant, err := providerGoDaddy.NewChallengeProvider(&providerGoDaddy.GoDaddyApplicantConfig{ applicant, err := pGoDaddy.NewChallengeProvider(&pGoDaddy.ChallengeProviderConfig{
ApiKey: access.ApiKey, ApiKey: access.ApiKey,
ApiSecret: access.ApiSecret, ApiSecret: access.ApiSecret,
DnsPropagationTimeout: options.DnsPropagationTimeout, DnsPropagationTimeout: options.DnsPropagationTimeout,
@ -171,7 +240,7 @@ func createApplicant(options *applicantOptions) (challenge.Provider, error) {
return nil, fmt.Errorf("failed to populate provider access config: %w", err) return nil, fmt.Errorf("failed to populate provider access config: %w", err)
} }
applicant, err := providerHuaweiCloud.NewChallengeProvider(&providerHuaweiCloud.HuaweiCloudApplicantConfig{ applicant, err := pHuaweiCloud.NewChallengeProvider(&pHuaweiCloud.ChallengeProviderConfig{
AccessKeyId: access.AccessKeyId, AccessKeyId: access.AccessKeyId,
SecretAccessKey: access.SecretAccessKey, SecretAccessKey: access.SecretAccessKey,
Region: maps.GetValueAsString(options.ProviderApplyConfig, "region"), Region: maps.GetValueAsString(options.ProviderApplyConfig, "region"),
@ -181,6 +250,39 @@ func createApplicant(options *applicantOptions) (challenge.Provider, error) {
return applicant, err return applicant, err
} }
case domain.ApplyDNSProviderTypeJDCloud, domain.ApplyDNSProviderTypeJDCloudDNS:
{
access := domain.AccessConfigForJDCloud{}
if err := maps.Populate(options.ProviderAccessConfig, &access); err != nil {
return nil, fmt.Errorf("failed to populate provider access config: %w", err)
}
applicant, err := pJDCloud.NewChallengeProvider(&pJDCloud.ChallengeProviderConfig{
AccessKeyId: access.AccessKeyId,
AccessKeySecret: access.AccessKeySecret,
RegionId: maps.GetValueAsString(options.ProviderApplyConfig, "region_id"),
DnsPropagationTimeout: options.DnsPropagationTimeout,
DnsTTL: options.DnsTTL,
})
return applicant, err
}
case domain.ApplyDNSProviderTypeNamecheap:
{
access := domain.AccessConfigForNamecheap{}
if err := maps.Populate(options.ProviderAccessConfig, &access); err != nil {
return nil, fmt.Errorf("failed to populate provider access config: %w", err)
}
applicant, err := pNamecheap.NewChallengeProvider(&pNamecheap.ChallengeProviderConfig{
Username: access.Username,
ApiKey: access.ApiKey,
DnsPropagationTimeout: options.DnsPropagationTimeout,
DnsTTL: options.DnsTTL,
})
return applicant, err
}
case domain.ApplyDNSProviderTypeNameDotCom: case domain.ApplyDNSProviderTypeNameDotCom:
{ {
access := domain.AccessConfigForNameDotCom{} access := domain.AccessConfigForNameDotCom{}
@ -188,7 +290,7 @@ func createApplicant(options *applicantOptions) (challenge.Provider, error) {
return nil, fmt.Errorf("failed to populate provider access config: %w", err) return nil, fmt.Errorf("failed to populate provider access config: %w", err)
} }
applicant, err := providerNameDotCom.NewChallengeProvider(&providerNameDotCom.NameDotComApplicantConfig{ applicant, err := pNameDotCom.NewChallengeProvider(&pNameDotCom.ChallengeProviderConfig{
Username: access.Username, Username: access.Username,
ApiToken: access.ApiToken, ApiToken: access.ApiToken,
DnsPropagationTimeout: options.DnsPropagationTimeout, DnsPropagationTimeout: options.DnsPropagationTimeout,
@ -204,7 +306,7 @@ func createApplicant(options *applicantOptions) (challenge.Provider, error) {
return nil, fmt.Errorf("failed to populate provider access config: %w", err) return nil, fmt.Errorf("failed to populate provider access config: %w", err)
} }
applicant, err := providerNameSilo.NewChallengeProvider(&providerNameSilo.NameSiloApplicantConfig{ applicant, err := pNameSilo.NewChallengeProvider(&pNameSilo.ChallengeProviderConfig{
ApiKey: access.ApiKey, ApiKey: access.ApiKey,
DnsPropagationTimeout: options.DnsPropagationTimeout, DnsPropagationTimeout: options.DnsPropagationTimeout,
DnsTTL: options.DnsTTL, DnsTTL: options.DnsTTL,
@ -219,7 +321,7 @@ func createApplicant(options *applicantOptions) (challenge.Provider, error) {
return nil, fmt.Errorf("failed to populate provider access config: %w", err) return nil, fmt.Errorf("failed to populate provider access config: %w", err)
} }
applicant, err := providerNS1.NewChallengeProvider(&providerNS1.NS1ApplicantConfig{ applicant, err := pNS1.NewChallengeProvider(&pNS1.ChallengeProviderConfig{
ApiKey: access.ApiKey, ApiKey: access.ApiKey,
DnsPropagationTimeout: options.DnsPropagationTimeout, DnsPropagationTimeout: options.DnsPropagationTimeout,
DnsTTL: options.DnsTTL, DnsTTL: options.DnsTTL,
@ -234,7 +336,7 @@ func createApplicant(options *applicantOptions) (challenge.Provider, error) {
return nil, fmt.Errorf("failed to populate provider access config: %w", err) return nil, fmt.Errorf("failed to populate provider access config: %w", err)
} }
applicant, err := providerPowerDNS.NewChallengeProvider(&providerPowerDNS.PowerDNSApplicantConfig{ applicant, err := pPowerDNS.NewChallengeProvider(&pPowerDNS.ChallengeProviderConfig{
ApiUrl: access.ApiUrl, ApiUrl: access.ApiUrl,
ApiKey: access.ApiKey, ApiKey: access.ApiKey,
DnsPropagationTimeout: options.DnsPropagationTimeout, DnsPropagationTimeout: options.DnsPropagationTimeout,
@ -250,7 +352,7 @@ func createApplicant(options *applicantOptions) (challenge.Provider, error) {
return nil, fmt.Errorf("failed to populate provider access config: %w", err) return nil, fmt.Errorf("failed to populate provider access config: %w", err)
} }
applicant, err := providerRainYun.NewChallengeProvider(&providerRainYun.RainYunApplicantConfig{ applicant, err := pRainYun.NewChallengeProvider(&pRainYun.ChallengeProviderConfig{
ApiKey: access.ApiKey, ApiKey: access.ApiKey,
DnsPropagationTimeout: options.DnsPropagationTimeout, DnsPropagationTimeout: options.DnsPropagationTimeout,
DnsTTL: options.DnsTTL, DnsTTL: options.DnsTTL,
@ -265,7 +367,7 @@ func createApplicant(options *applicantOptions) (challenge.Provider, error) {
return nil, fmt.Errorf("failed to populate provider access config: %w", err) return nil, fmt.Errorf("failed to populate provider access config: %w", err)
} }
applicant, err := providerTencentCloud.NewChallengeProvider(&providerTencentCloud.TencentCloudApplicantConfig{ applicant, err := pTencentCloud.NewChallengeProvider(&pTencentCloud.ChallengeProviderConfig{
SecretId: access.SecretId, SecretId: access.SecretId,
SecretKey: access.SecretKey, SecretKey: access.SecretKey,
DnsPropagationTimeout: options.DnsPropagationTimeout, DnsPropagationTimeout: options.DnsPropagationTimeout,
@ -281,7 +383,7 @@ func createApplicant(options *applicantOptions) (challenge.Provider, error) {
return nil, fmt.Errorf("failed to populate provider access config: %w", err) return nil, fmt.Errorf("failed to populate provider access config: %w", err)
} }
applicant, err := providerVolcEngine.NewChallengeProvider(&providerVolcEngine.VolcEngineApplicantConfig{ applicant, err := pVolcEngine.NewChallengeProvider(&pVolcEngine.ChallengeProviderConfig{
AccessKeyId: access.AccessKeyId, AccessKeyId: access.AccessKeyId,
SecretAccessKey: access.SecretAccessKey, SecretAccessKey: access.SecretAccessKey,
DnsPropagationTimeout: options.DnsPropagationTimeout, DnsPropagationTimeout: options.DnsPropagationTimeout,
@ -297,7 +399,7 @@ func createApplicant(options *applicantOptions) (challenge.Provider, error) {
return nil, fmt.Errorf("failed to populate provider access config: %w", err) return nil, fmt.Errorf("failed to populate provider access config: %w", err)
} }
applicant, err := providerWestcn.NewChallengeProvider(&providerWestcn.WestcnApplicantConfig{ applicant, err := pWestcn.NewChallengeProvider(&pWestcn.ChallengeProviderConfig{
Username: access.Username, Username: access.Username,
ApiPassword: access.ApiPassword, ApiPassword: access.ApiPassword,
DnsPropagationTimeout: options.DnsPropagationTimeout, DnsPropagationTimeout: options.DnsPropagationTimeout,

View File

@ -42,7 +42,7 @@ func NewWithDeployNode(node *domain.WorkflowNode, certdata struct {
return nil, fmt.Errorf("failed to unmarshal access config: %w", err) return nil, fmt.Errorf("failed to unmarshal access config: %w", err)
} }
deployer, logger, err := createDeployer(&deployerOptions{ deployer, err := createDeployer(&deployerOptions{
Provider: domain.DeployProviderType(nodeConfig.Provider), Provider: domain.DeployProviderType(nodeConfig.Provider),
ProviderAccessConfig: accessConfig, ProviderAccessConfig: accessConfig,
ProviderDeployConfig: nodeConfig.ProviderConfig, ProviderDeployConfig: nodeConfig.ProviderConfig,
@ -52,7 +52,7 @@ func NewWithDeployNode(node *domain.WorkflowNode, certdata struct {
} }
return &proxyDeployer{ return &proxyDeployer{
logger: logger, logger: logger.NewNilLogger(),
deployer: deployer, deployer: deployer,
deployCertificate: certdata.Certificate, deployCertificate: certdata.Certificate,
deployPrivateKey: certdata.PrivateKey, deployPrivateKey: certdata.PrivateKey,

View File

@ -6,162 +6,183 @@ import (
"github.com/usual2970/certimate/internal/domain" "github.com/usual2970/certimate/internal/domain"
"github.com/usual2970/certimate/internal/pkg/core/deployer" "github.com/usual2970/certimate/internal/pkg/core/deployer"
providerAliyunALB "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/aliyun-alb" pAliyunALB "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/aliyun-alb"
providerAliyunCASDeploy "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/aliyun-cas-deploy" pAliyunCASDeploy "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/aliyun-cas-deploy"
providerAliyunCDN "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/aliyun-cdn" pAliyunCDN "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/aliyun-cdn"
providerAliyunCLB "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/aliyun-clb" pAliyunCLB "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/aliyun-clb"
providerAliyunDCDN "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/aliyun-dcdn" pAliyunDCDN "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/aliyun-dcdn"
providerAliyunESA "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/aliyun-esa" pAliyunESA "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/aliyun-esa"
providerAliyunLive "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/aliyun-live" pAliyunLive "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/aliyun-live"
providerAliyunNLB "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/aliyun-nlb" pAliyunNLB "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/aliyun-nlb"
providerAliyunOSS "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/aliyun-oss" pAliyunOSS "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/aliyun-oss"
providerAliyunWAF "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/aliyun-waf" pAliyunVOD "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/aliyun-vod"
providerAWSCloudFront "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/aws-cloudfront" pAliyunWAF "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/aliyun-waf"
providerBaiduCloudCDN "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/baiducloud-cdn" pAWSCloudFront "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/aws-cloudfront"
providerBaotaPanelSite "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/baotapanel-site" pBaiduCloudCDN "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/baiducloud-cdn"
providerBytePlusCDN "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/byteplus-cdn" pBaishanCDN "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/baishan-cdn"
providerDogeCDN "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/dogecloud-cdn" pBaotaPanelConsole "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/baotapanel-console"
providerEdgioApplications "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/edgio-applications" pBaotaPanelSite "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/baotapanel-site"
providerHuaweiCloudCDN "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/huaweicloud-cdn" pBytePlusCDN "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/byteplus-cdn"
providerHuaweiCloudELB "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/huaweicloud-elb" pCacheFly "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/cachefly"
providerK8sSecret "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/k8s-secret" pCdnfly "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/cdnfly"
providerLocal "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/local" pDogeCDN "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/dogecloud-cdn"
providerQiniuCDN "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/qiniu-cdn" pEdgioApplications "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/edgio-applications"
providerQiniuPili "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/qiniu-pili" pGcoreCDN "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/gcore-cdn"
providerSSH "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/ssh" pHuaweiCloudCDN "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/huaweicloud-cdn"
providerTencentCloudCDN "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/tencentcloud-cdn" pHuaweiCloudELB "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/huaweicloud-elb"
providerTencentCloudCLB "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/tencentcloud-clb" pHuaweiCloudWAF "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/huaweicloud-waf"
providerTencentCloudCOS "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/tencentcloud-cos" pJDCloudALB "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/jdcloud-alb"
providerTencentCloudCSS "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/tencentcloud-css" pJDCloudCDN "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/jdcloud-cdn"
providerTencentCloudECDN "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/tencentcloud-ecdn" pJDCloudLive "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/jdcloud-live"
providerTencentCloudEO "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/tencentcloud-eo" pJDCloudVOD "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/jdcloud-vod"
providerTencentCloudSSLDeploy "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/tencentcloud-ssl-deploy" pK8sSecret "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/k8s-secret"
providerUCloudUCDN "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/ucloud-ucdn" pLocal "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/local"
providerUCloudUS3 "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/ucloud-us3" pQiniuCDN "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/qiniu-cdn"
providerVolcEngineCDN "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/volcengine-cdn" pQiniuPili "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/qiniu-pili"
providerVolcEngineCLB "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/volcengine-clb" pSafeLine "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/safeline"
providerVolcEngineDCDN "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/volcengine-dcdn" pSSH "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/ssh"
providerVolcEngineLive "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/volcengine-live" pTencentCloudCDN "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/tencentcloud-cdn"
providerVolcEngineTOS "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/volcengine-tos" pTencentCloudCLB "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/tencentcloud-clb"
providerWebhook "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/webhook" pTencentCloudCOS "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/tencentcloud-cos"
"github.com/usual2970/certimate/internal/pkg/core/logger" pTencentCloudCSS "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/tencentcloud-css"
pTencentCloudECDN "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/tencentcloud-ecdn"
pTencentCloudEO "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/tencentcloud-eo"
pTencentCloudSSLDeploy "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/tencentcloud-ssl-deploy"
pTencentCloudVOD "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/tencentcloud-vod"
pTencentCloudWAF "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/tencentcloud-waf"
pUCloudUCDN "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/ucloud-ucdn"
pUCloudUS3 "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/ucloud-us3"
pVolcEngineCDN "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/volcengine-cdn"
pVolcEngineCLB "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/volcengine-clb"
pVolcEngineDCDN "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/volcengine-dcdn"
pVolcEngineImageX "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/volcengine-imagex"
pVolcEngineLive "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/volcengine-live"
pVolcEngineTOS "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/volcengine-tos"
pWebhook "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/webhook"
"github.com/usual2970/certimate/internal/pkg/utils/maps" "github.com/usual2970/certimate/internal/pkg/utils/maps"
"github.com/usual2970/certimate/internal/pkg/utils/slices" "github.com/usual2970/certimate/internal/pkg/utils/slices"
) )
func createDeployer(options *deployerOptions) (deployer.Deployer, logger.Logger, error) { func createDeployer(options *deployerOptions) (deployer.Deployer, error) {
logger := logger.NewDefaultLogger()
/* /*
注意如果追加新的常量值请保持以 ASCII 排序 注意如果追加新的常量值请保持以 ASCII 排序
NOTICE: If you add new constant, please keep ASCII order. NOTICE: If you add new constant, please keep ASCII order.
*/ */
switch options.Provider { switch options.Provider {
case domain.DeployProviderTypeAliyunALB, domain.DeployProviderTypeAliyunCASDeploy, domain.DeployProviderTypeAliyunCDN, domain.DeployProviderTypeAliyunCLB, domain.DeployProviderTypeAliyunDCDN, domain.DeployProviderTypeAliyunESA, domain.DeployProviderTypeAliyunLive, domain.DeployProviderTypeAliyunNLB, domain.DeployProviderTypeAliyunOSS, domain.DeployProviderTypeAliyunWAF: case domain.DeployProviderTypeAliyunALB, domain.DeployProviderTypeAliyunCASDeploy, domain.DeployProviderTypeAliyunCDN, domain.DeployProviderTypeAliyunCLB, domain.DeployProviderTypeAliyunDCDN, domain.DeployProviderTypeAliyunESA, domain.DeployProviderTypeAliyunLive, domain.DeployProviderTypeAliyunNLB, domain.DeployProviderTypeAliyunOSS, domain.DeployProviderTypeAliyunVOD, domain.DeployProviderTypeAliyunWAF:
{ {
access := domain.AccessConfigForAliyun{} access := domain.AccessConfigForAliyun{}
if err := maps.Populate(options.ProviderAccessConfig, &access); err != nil { if err := maps.Populate(options.ProviderAccessConfig, &access); err != nil {
return nil, nil, fmt.Errorf("failed to populate provider access config: %w", err) return nil, fmt.Errorf("failed to populate provider access config: %w", err)
} }
switch options.Provider { switch options.Provider {
case domain.DeployProviderTypeAliyunALB: case domain.DeployProviderTypeAliyunALB:
deployer, err := providerAliyunALB.NewWithLogger(&providerAliyunALB.AliyunALBDeployerConfig{ deployer, err := pAliyunALB.NewDeployer(&pAliyunALB.DeployerConfig{
AccessKeyId: access.AccessKeyId, AccessKeyId: access.AccessKeyId,
AccessKeySecret: access.AccessKeySecret, AccessKeySecret: access.AccessKeySecret,
Region: maps.GetValueAsString(options.ProviderDeployConfig, "region"), Region: maps.GetValueAsString(options.ProviderDeployConfig, "region"),
ResourceType: providerAliyunALB.DeployResourceType(maps.GetValueAsString(options.ProviderDeployConfig, "resourceType")), ResourceType: pAliyunALB.ResourceType(maps.GetValueAsString(options.ProviderDeployConfig, "resourceType")),
LoadbalancerId: maps.GetValueAsString(options.ProviderDeployConfig, "loadbalancerId"), LoadbalancerId: maps.GetValueAsString(options.ProviderDeployConfig, "loadbalancerId"),
ListenerId: maps.GetValueAsString(options.ProviderDeployConfig, "listenerId"), ListenerId: maps.GetValueAsString(options.ProviderDeployConfig, "listenerId"),
Domain: maps.GetValueAsString(options.ProviderDeployConfig, "domain"), Domain: maps.GetValueAsString(options.ProviderDeployConfig, "domain"),
}, logger) })
return deployer, logger, err return deployer, err
case domain.DeployProviderTypeAliyunCASDeploy: case domain.DeployProviderTypeAliyunCASDeploy:
deployer, err := providerAliyunCASDeploy.NewWithLogger(&providerAliyunCASDeploy.AliyunCASDeployDeployerConfig{ deployer, err := pAliyunCASDeploy.NewDeployer(&pAliyunCASDeploy.DeployerConfig{
AccessKeyId: access.AccessKeyId, AccessKeyId: access.AccessKeyId,
AccessKeySecret: access.AccessKeySecret, AccessKeySecret: access.AccessKeySecret,
Region: maps.GetValueAsString(options.ProviderDeployConfig, "region"), Region: maps.GetValueAsString(options.ProviderDeployConfig, "region"),
ResourceIds: slices.Filter(strings.Split(maps.GetValueAsString(options.ProviderDeployConfig, "resourceIds"), ";"), func(s string) bool { return s != "" }), ResourceIds: slices.Filter(strings.Split(maps.GetValueAsString(options.ProviderDeployConfig, "resourceIds"), ";"), func(s string) bool { return s != "" }),
ContactIds: slices.Filter(strings.Split(maps.GetValueAsString(options.ProviderDeployConfig, "contactIds"), ";"), func(s string) bool { return s != "" }), ContactIds: slices.Filter(strings.Split(maps.GetValueAsString(options.ProviderDeployConfig, "contactIds"), ";"), func(s string) bool { return s != "" }),
}, logger) })
return deployer, logger, err return deployer, err
case domain.DeployProviderTypeAliyunCDN: case domain.DeployProviderTypeAliyunCDN:
deployer, err := providerAliyunCDN.NewWithLogger(&providerAliyunCDN.AliyunCDNDeployerConfig{ deployer, err := pAliyunCDN.NewDeployer(&pAliyunCDN.DeployerConfig{
AccessKeyId: access.AccessKeyId, AccessKeyId: access.AccessKeyId,
AccessKeySecret: access.AccessKeySecret, AccessKeySecret: access.AccessKeySecret,
Domain: maps.GetValueAsString(options.ProviderDeployConfig, "domain"), Domain: maps.GetValueAsString(options.ProviderDeployConfig, "domain"),
}, logger) })
return deployer, logger, err return deployer, err
case domain.DeployProviderTypeAliyunCLB: case domain.DeployProviderTypeAliyunCLB:
deployer, err := providerAliyunCLB.NewWithLogger(&providerAliyunCLB.AliyunCLBDeployerConfig{ deployer, err := pAliyunCLB.NewDeployer(&pAliyunCLB.DeployerConfig{
AccessKeyId: access.AccessKeyId, AccessKeyId: access.AccessKeyId,
AccessKeySecret: access.AccessKeySecret, AccessKeySecret: access.AccessKeySecret,
Region: maps.GetValueAsString(options.ProviderDeployConfig, "region"), Region: maps.GetValueAsString(options.ProviderDeployConfig, "region"),
ResourceType: providerAliyunCLB.DeployResourceType(maps.GetValueAsString(options.ProviderDeployConfig, "resourceType")), ResourceType: pAliyunCLB.ResourceType(maps.GetValueAsString(options.ProviderDeployConfig, "resourceType")),
LoadbalancerId: maps.GetValueAsString(options.ProviderDeployConfig, "loadbalancerId"), LoadbalancerId: maps.GetValueAsString(options.ProviderDeployConfig, "loadbalancerId"),
ListenerPort: maps.GetValueOrDefaultAsInt32(options.ProviderDeployConfig, "listenerPort", 443), ListenerPort: maps.GetValueOrDefaultAsInt32(options.ProviderDeployConfig, "listenerPort", 443),
Domain: maps.GetValueAsString(options.ProviderDeployConfig, "domain"), Domain: maps.GetValueAsString(options.ProviderDeployConfig, "domain"),
}, logger) })
return deployer, logger, err return deployer, err
case domain.DeployProviderTypeAliyunDCDN: case domain.DeployProviderTypeAliyunDCDN:
deployer, err := providerAliyunDCDN.NewWithLogger(&providerAliyunDCDN.AliyunDCDNDeployerConfig{ deployer, err := pAliyunDCDN.NewDeployer(&pAliyunDCDN.DeployerConfig{
AccessKeyId: access.AccessKeyId, AccessKeyId: access.AccessKeyId,
AccessKeySecret: access.AccessKeySecret, AccessKeySecret: access.AccessKeySecret,
Domain: maps.GetValueAsString(options.ProviderDeployConfig, "domain"), Domain: maps.GetValueAsString(options.ProviderDeployConfig, "domain"),
}, logger) })
return deployer, logger, err return deployer, err
case domain.DeployProviderTypeAliyunESA: case domain.DeployProviderTypeAliyunESA:
deployer, err := providerAliyunESA.NewWithLogger(&providerAliyunESA.AliyunESADeployerConfig{ deployer, err := pAliyunESA.NewDeployer(&pAliyunESA.DeployerConfig{
AccessKeyId: access.AccessKeyId, AccessKeyId: access.AccessKeyId,
AccessKeySecret: access.AccessKeySecret, AccessKeySecret: access.AccessKeySecret,
Region: maps.GetValueAsString(options.ProviderDeployConfig, "region"), Region: maps.GetValueAsString(options.ProviderDeployConfig, "region"),
SiteId: maps.GetValueAsInt64(options.ProviderDeployConfig, "siteId"), SiteId: maps.GetValueAsInt64(options.ProviderDeployConfig, "siteId"),
}, logger) })
return deployer, logger, err return deployer, err
case domain.DeployProviderTypeAliyunLive: case domain.DeployProviderTypeAliyunLive:
deployer, err := providerAliyunLive.NewWithLogger(&providerAliyunLive.AliyunLiveDeployerConfig{ deployer, err := pAliyunLive.NewDeployer(&pAliyunLive.DeployerConfig{
AccessKeyId: access.AccessKeyId, AccessKeyId: access.AccessKeyId,
AccessKeySecret: access.AccessKeySecret, AccessKeySecret: access.AccessKeySecret,
Region: maps.GetValueAsString(options.ProviderDeployConfig, "region"), Region: maps.GetValueAsString(options.ProviderDeployConfig, "region"),
Domain: maps.GetValueAsString(options.ProviderDeployConfig, "domain"), Domain: maps.GetValueAsString(options.ProviderDeployConfig, "domain"),
}, logger) })
return deployer, logger, err return deployer, err
case domain.DeployProviderTypeAliyunNLB: case domain.DeployProviderTypeAliyunNLB:
deployer, err := providerAliyunNLB.NewWithLogger(&providerAliyunNLB.AliyunNLBDeployerConfig{ deployer, err := pAliyunNLB.NewDeployer(&pAliyunNLB.DeployerConfig{
AccessKeyId: access.AccessKeyId, AccessKeyId: access.AccessKeyId,
AccessKeySecret: access.AccessKeySecret, AccessKeySecret: access.AccessKeySecret,
Region: maps.GetValueAsString(options.ProviderDeployConfig, "region"), Region: maps.GetValueAsString(options.ProviderDeployConfig, "region"),
ResourceType: providerAliyunNLB.DeployResourceType(maps.GetValueAsString(options.ProviderDeployConfig, "resourceType")), ResourceType: pAliyunNLB.ResourceType(maps.GetValueAsString(options.ProviderDeployConfig, "resourceType")),
LoadbalancerId: maps.GetValueAsString(options.ProviderDeployConfig, "loadbalancerId"), LoadbalancerId: maps.GetValueAsString(options.ProviderDeployConfig, "loadbalancerId"),
ListenerId: maps.GetValueAsString(options.ProviderDeployConfig, "listenerId"), ListenerId: maps.GetValueAsString(options.ProviderDeployConfig, "listenerId"),
}, logger) })
return deployer, logger, err return deployer, err
case domain.DeployProviderTypeAliyunOSS: case domain.DeployProviderTypeAliyunOSS:
deployer, err := providerAliyunOSS.NewWithLogger(&providerAliyunOSS.AliyunOSSDeployerConfig{ deployer, err := pAliyunOSS.NewDeployer(&pAliyunOSS.DeployerConfig{
AccessKeyId: access.AccessKeyId, AccessKeyId: access.AccessKeyId,
AccessKeySecret: access.AccessKeySecret, AccessKeySecret: access.AccessKeySecret,
Region: maps.GetValueAsString(options.ProviderDeployConfig, "region"), Region: maps.GetValueAsString(options.ProviderDeployConfig, "region"),
Bucket: maps.GetValueAsString(options.ProviderDeployConfig, "bucket"), Bucket: maps.GetValueAsString(options.ProviderDeployConfig, "bucket"),
Domain: maps.GetValueAsString(options.ProviderDeployConfig, "domain"), Domain: maps.GetValueAsString(options.ProviderDeployConfig, "domain"),
}, logger) })
return deployer, logger, err return deployer, err
case domain.DeployProviderTypeAliyunVOD:
deployer, err := pAliyunVOD.NewDeployer(&pAliyunVOD.DeployerConfig{
AccessKeyId: access.AccessKeyId,
AccessKeySecret: access.AccessKeySecret,
Region: maps.GetValueAsString(options.ProviderDeployConfig, "region"),
Domain: maps.GetValueAsString(options.ProviderDeployConfig, "domain"),
})
return deployer, err
case domain.DeployProviderTypeAliyunWAF: case domain.DeployProviderTypeAliyunWAF:
deployer, err := providerAliyunWAF.NewWithLogger(&providerAliyunWAF.AliyunWAFDeployerConfig{ deployer, err := pAliyunWAF.NewDeployer(&pAliyunWAF.DeployerConfig{
AccessKeyId: access.AccessKeyId, AccessKeyId: access.AccessKeyId,
AccessKeySecret: access.AccessKeySecret, AccessKeySecret: access.AccessKeySecret,
Region: maps.GetValueAsString(options.ProviderDeployConfig, "region"), Region: maps.GetValueAsString(options.ProviderDeployConfig, "region"),
InstanceId: maps.GetValueAsString(options.ProviderDeployConfig, "instanceId"), InstanceId: maps.GetValueAsString(options.ProviderDeployConfig, "instanceId"),
}, logger) })
return deployer, logger, err return deployer, err
default: default:
break break
@ -172,18 +193,18 @@ func createDeployer(options *deployerOptions) (deployer.Deployer, logger.Logger,
{ {
access := domain.AccessConfigForAWS{} access := domain.AccessConfigForAWS{}
if err := maps.Populate(options.ProviderAccessConfig, &access); err != nil { if err := maps.Populate(options.ProviderAccessConfig, &access); err != nil {
return nil, nil, fmt.Errorf("failed to populate provider access config: %w", err) return nil, fmt.Errorf("failed to populate provider access config: %w", err)
} }
switch options.Provider { switch options.Provider {
case domain.DeployProviderTypeAWSCloudFront: case domain.DeployProviderTypeAWSCloudFront:
deployer, err := providerAWSCloudFront.NewWithLogger(&providerAWSCloudFront.AWSCloudFrontDeployerConfig{ deployer, err := pAWSCloudFront.NewDeployer(&pAWSCloudFront.DeployerConfig{
AccessKeyId: access.AccessKeyId, AccessKeyId: access.AccessKeyId,
SecretAccessKey: access.SecretAccessKey, SecretAccessKey: access.SecretAccessKey,
Region: maps.GetValueAsString(options.ProviderDeployConfig, "region"), Region: maps.GetValueAsString(options.ProviderDeployConfig, "region"),
DistributionId: maps.GetValueAsString(options.ProviderDeployConfig, "distributionId"), DistributionId: maps.GetValueAsString(options.ProviderDeployConfig, "distributionId"),
}, logger) })
return deployer, logger, err return deployer, err
default: default:
break break
@ -194,117 +215,263 @@ func createDeployer(options *deployerOptions) (deployer.Deployer, logger.Logger,
{ {
access := domain.AccessConfigForBaiduCloud{} access := domain.AccessConfigForBaiduCloud{}
if err := maps.Populate(options.ProviderAccessConfig, &access); err != nil { if err := maps.Populate(options.ProviderAccessConfig, &access); err != nil {
return nil, nil, fmt.Errorf("failed to populate provider access config: %w", err) return nil, fmt.Errorf("failed to populate provider access config: %w", err)
} }
switch options.Provider { switch options.Provider {
case domain.DeployProviderTypeBaiduCloudCDN: case domain.DeployProviderTypeBaiduCloudCDN:
deployer, err := providerBaiduCloudCDN.NewWithLogger(&providerBaiduCloudCDN.BaiduCloudCDNDeployerConfig{ deployer, err := pBaiduCloudCDN.NewDeployer(&pBaiduCloudCDN.DeployerConfig{
AccessKeyId: access.AccessKeyId, AccessKeyId: access.AccessKeyId,
SecretAccessKey: access.SecretAccessKey, SecretAccessKey: access.SecretAccessKey,
Domain: maps.GetValueAsString(options.ProviderDeployConfig, "domain"), Domain: maps.GetValueAsString(options.ProviderDeployConfig, "domain"),
}, logger) })
return deployer, logger, err return deployer, err
default: default:
break break
} }
} }
case domain.DeployProviderTypeBaotaPanelSite: case domain.DeployProviderTypeBaishanCDN:
{
access := domain.AccessConfigForBaishan{}
if err := maps.Populate(options.ProviderAccessConfig, &access); err != nil {
return nil, fmt.Errorf("failed to populate provider access config: %w", err)
}
switch options.Provider {
case domain.DeployProviderTypeBaishanCDN:
deployer, err := pBaishanCDN.NewDeployer(&pBaishanCDN.DeployerConfig{
ApiToken: access.ApiToken,
Domain: maps.GetValueAsString(options.ProviderDeployConfig, "domain"),
})
return deployer, err
default:
break
}
}
case domain.DeployProviderTypeBaotaPanelConsole, domain.DeployProviderTypeBaotaPanelSite:
{ {
access := domain.AccessConfigForBaotaPanel{} access := domain.AccessConfigForBaotaPanel{}
if err := maps.Populate(options.ProviderAccessConfig, &access); err != nil { if err := maps.Populate(options.ProviderAccessConfig, &access); err != nil {
return nil, nil, fmt.Errorf("failed to populate provider access config: %w", err) return nil, fmt.Errorf("failed to populate provider access config: %w", err)
} }
deployer, err := providerBaotaPanelSite.NewWithLogger(&providerBaotaPanelSite.BaotaPanelSiteDeployerConfig{ switch options.Provider {
case domain.DeployProviderTypeBaotaPanelConsole:
deployer, err := pBaotaPanelConsole.NewDeployer(&pBaotaPanelConsole.DeployerConfig{
ApiUrl: access.ApiUrl, ApiUrl: access.ApiUrl,
ApiKey: access.ApiKey, ApiKey: access.ApiKey,
AutoRestart: maps.GetValueAsBool(options.ProviderDeployConfig, "autoRestart"),
})
return deployer, err
case domain.DeployProviderTypeBaotaPanelSite:
deployer, err := pBaotaPanelSite.NewDeployer(&pBaotaPanelSite.DeployerConfig{
ApiUrl: access.ApiUrl,
ApiKey: access.ApiKey,
SiteType: maps.GetValueOrDefaultAsString(options.ProviderDeployConfig, "siteType", "other"),
SiteName: maps.GetValueAsString(options.ProviderDeployConfig, "siteName"), SiteName: maps.GetValueAsString(options.ProviderDeployConfig, "siteName"),
}, logger) SiteNames: slices.Filter(strings.Split(maps.GetValueAsString(options.ProviderDeployConfig, "siteNames"), ";"), func(s string) bool { return s != "" }),
return deployer, logger, err })
return deployer, err
default:
break
}
} }
case domain.DeployProviderTypeBytePlusCDN: case domain.DeployProviderTypeBytePlusCDN:
{ {
access := domain.AccessConfigForBytePlus{} access := domain.AccessConfigForBytePlus{}
if err := maps.Populate(options.ProviderAccessConfig, &access); err != nil { if err := maps.Populate(options.ProviderAccessConfig, &access); err != nil {
return nil, nil, fmt.Errorf("failed to populate provider access config: %w", err) return nil, fmt.Errorf("failed to populate provider access config: %w", err)
} }
switch options.Provider { switch options.Provider {
case domain.DeployProviderTypeBytePlusCDN: case domain.DeployProviderTypeBytePlusCDN:
deployer, err := providerBytePlusCDN.NewWithLogger(&providerBytePlusCDN.BytePlusCDNDeployerConfig{ deployer, err := pBytePlusCDN.NewDeployer(&pBytePlusCDN.DeployerConfig{
AccessKey: access.AccessKey, AccessKey: access.AccessKey,
SecretKey: access.SecretKey, SecretKey: access.SecretKey,
Domain: maps.GetValueAsString(options.ProviderDeployConfig, "domain"), Domain: maps.GetValueAsString(options.ProviderDeployConfig, "domain"),
}, logger) })
return deployer, logger, err return deployer, err
default: default:
break break
} }
} }
case domain.DeployProviderTypeCacheFly:
{
access := domain.AccessConfigForCacheFly{}
if err := maps.Populate(options.ProviderAccessConfig, &access); err != nil {
return nil, fmt.Errorf("failed to populate provider access config: %w", err)
}
deployer, err := pCacheFly.NewDeployer(&pCacheFly.DeployerConfig{
ApiToken: access.ApiToken,
})
return deployer, err
}
case domain.DeployProviderTypeCdnfly:
{
access := domain.AccessConfigForCdnfly{}
if err := maps.Populate(options.ProviderAccessConfig, &access); err != nil {
return nil, fmt.Errorf("failed to populate provider access config: %w", err)
}
deployer, err := pCdnfly.NewDeployer(&pCdnfly.DeployerConfig{
ApiUrl: access.ApiUrl,
ApiKey: access.ApiKey,
ApiSecret: access.ApiSecret,
ResourceType: pCdnfly.ResourceType(maps.GetValueAsString(options.ProviderDeployConfig, "resourceType")),
SiteId: maps.GetValueAsString(options.ProviderDeployConfig, "siteId"),
CertificateId: maps.GetValueAsString(options.ProviderDeployConfig, "certificateId"),
})
return deployer, err
}
case domain.DeployProviderTypeDogeCloudCDN: case domain.DeployProviderTypeDogeCloudCDN:
{ {
access := domain.AccessConfigForDogeCloud{} access := domain.AccessConfigForDogeCloud{}
if err := maps.Populate(options.ProviderAccessConfig, &access); err != nil { if err := maps.Populate(options.ProviderAccessConfig, &access); err != nil {
return nil, nil, fmt.Errorf("failed to populate provider access config: %w", err) return nil, fmt.Errorf("failed to populate provider access config: %w", err)
} }
deployer, err := providerDogeCDN.NewWithLogger(&providerDogeCDN.DogeCloudCDNDeployerConfig{ deployer, err := pDogeCDN.NewDeployer(&pDogeCDN.DeployerConfig{
AccessKey: access.AccessKey, AccessKey: access.AccessKey,
SecretKey: access.SecretKey, SecretKey: access.SecretKey,
Domain: maps.GetValueAsString(options.ProviderDeployConfig, "domain"), Domain: maps.GetValueAsString(options.ProviderDeployConfig, "domain"),
}, logger) })
return deployer, logger, err return deployer, err
} }
case domain.DeployProviderTypeEdgioApplications: case domain.DeployProviderTypeEdgioApplications:
{ {
access := domain.AccessConfigForEdgio{} access := domain.AccessConfigForEdgio{}
if err := maps.Populate(options.ProviderAccessConfig, &access); err != nil { if err := maps.Populate(options.ProviderAccessConfig, &access); err != nil {
return nil, nil, fmt.Errorf("failed to populate provider access config: %w", err) return nil, fmt.Errorf("failed to populate provider access config: %w", err)
} }
deployer, err := providerEdgioApplications.NewWithLogger(&providerEdgioApplications.EdgioApplicationsDeployerConfig{ deployer, err := pEdgioApplications.NewDeployer(&pEdgioApplications.DeployerConfig{
ClientId: access.ClientId, ClientId: access.ClientId,
ClientSecret: access.ClientSecret, ClientSecret: access.ClientSecret,
EnvironmentId: maps.GetValueAsString(options.ProviderDeployConfig, "environmentId"), EnvironmentId: maps.GetValueAsString(options.ProviderDeployConfig, "environmentId"),
}, logger) })
return deployer, logger, err return deployer, err
} }
case domain.DeployProviderTypeHuaweiCloudCDN, domain.DeployProviderTypeHuaweiCloudELB: case domain.DeployProviderTypeGcoreCDN:
{
access := domain.AccessConfigForGcore{}
if err := maps.Populate(options.ProviderAccessConfig, &access); err != nil {
return nil, fmt.Errorf("failed to populate provider access config: %w", err)
}
switch options.Provider {
case domain.DeployProviderTypeGcoreCDN:
deployer, err := pGcoreCDN.NewDeployer(&pGcoreCDN.DeployerConfig{
ApiToken: access.ApiToken,
ResourceId: maps.GetValueAsInt64(options.ProviderDeployConfig, "resourceId"),
})
return deployer, err
default:
break
}
}
case domain.DeployProviderTypeHuaweiCloudCDN, domain.DeployProviderTypeHuaweiCloudELB, domain.DeployProviderTypeHuaweiCloudWAF:
{ {
access := domain.AccessConfigForHuaweiCloud{} access := domain.AccessConfigForHuaweiCloud{}
if err := maps.Populate(options.ProviderAccessConfig, &access); err != nil { if err := maps.Populate(options.ProviderAccessConfig, &access); err != nil {
return nil, nil, fmt.Errorf("failed to populate provider access config: %w", err) return nil, fmt.Errorf("failed to populate provider access config: %w", err)
} }
switch options.Provider { switch options.Provider {
case domain.DeployProviderTypeHuaweiCloudCDN: case domain.DeployProviderTypeHuaweiCloudCDN:
deployer, err := providerHuaweiCloudCDN.NewWithLogger(&providerHuaweiCloudCDN.HuaweiCloudCDNDeployerConfig{ deployer, err := pHuaweiCloudCDN.NewDeployer(&pHuaweiCloudCDN.DeployerConfig{
AccessKeyId: access.AccessKeyId, AccessKeyId: access.AccessKeyId,
SecretAccessKey: access.SecretAccessKey, SecretAccessKey: access.SecretAccessKey,
Region: maps.GetValueAsString(options.ProviderDeployConfig, "region"), Region: maps.GetValueAsString(options.ProviderDeployConfig, "region"),
Domain: maps.GetValueAsString(options.ProviderDeployConfig, "domain"), Domain: maps.GetValueAsString(options.ProviderDeployConfig, "domain"),
}, logger) })
return deployer, logger, err return deployer, err
case domain.DeployProviderTypeHuaweiCloudELB: case domain.DeployProviderTypeHuaweiCloudELB:
deployer, err := providerHuaweiCloudELB.NewWithLogger(&providerHuaweiCloudELB.HuaweiCloudELBDeployerConfig{ deployer, err := pHuaweiCloudELB.NewDeployer(&pHuaweiCloudELB.DeployerConfig{
AccessKeyId: access.AccessKeyId, AccessKeyId: access.AccessKeyId,
SecretAccessKey: access.SecretAccessKey, SecretAccessKey: access.SecretAccessKey,
Region: maps.GetValueAsString(options.ProviderDeployConfig, "region"), Region: maps.GetValueAsString(options.ProviderDeployConfig, "region"),
ResourceType: providerHuaweiCloudELB.DeployResourceType(maps.GetValueAsString(options.ProviderDeployConfig, "resourceType")), ResourceType: pHuaweiCloudELB.ResourceType(maps.GetValueAsString(options.ProviderDeployConfig, "resourceType")),
CertificateId: maps.GetValueAsString(options.ProviderDeployConfig, "certificateId"), CertificateId: maps.GetValueAsString(options.ProviderDeployConfig, "certificateId"),
LoadbalancerId: maps.GetValueAsString(options.ProviderDeployConfig, "loadbalancerId"), LoadbalancerId: maps.GetValueAsString(options.ProviderDeployConfig, "loadbalancerId"),
ListenerId: maps.GetValueAsString(options.ProviderDeployConfig, "listenerId"), ListenerId: maps.GetValueAsString(options.ProviderDeployConfig, "listenerId"),
}, logger) })
return deployer, logger, err return deployer, err
case domain.DeployProviderTypeHuaweiCloudWAF:
deployer, err := pHuaweiCloudWAF.NewDeployer(&pHuaweiCloudWAF.DeployerConfig{
AccessKeyId: access.AccessKeyId,
SecretAccessKey: access.SecretAccessKey,
Region: maps.GetValueAsString(options.ProviderDeployConfig, "region"),
ResourceType: pHuaweiCloudWAF.ResourceType(maps.GetValueAsString(options.ProviderDeployConfig, "resourceType")),
CertificateId: maps.GetValueAsString(options.ProviderDeployConfig, "certificateId"),
Domain: maps.GetValueAsString(options.ProviderDeployConfig, "domain"),
})
return deployer, err
default:
break
}
}
case domain.DeployProviderTypeJDCloudALB, domain.DeployProviderTypeJDCloudCDN, domain.DeployProviderTypeJDCloudLive, domain.DeployProviderTypeJDCloudVOD:
{
access := domain.AccessConfigForJDCloud{}
if err := maps.Populate(options.ProviderAccessConfig, &access); err != nil {
return nil, fmt.Errorf("failed to populate provider access config: %w", err)
}
switch options.Provider {
case domain.DeployProviderTypeJDCloudALB:
deployer, err := pJDCloudALB.NewDeployer(&pJDCloudALB.DeployerConfig{
AccessKeyId: access.AccessKeyId,
AccessKeySecret: access.AccessKeySecret,
RegionId: maps.GetValueAsString(options.ProviderDeployConfig, "regionId"),
ResourceType: pJDCloudALB.ResourceType(maps.GetValueAsString(options.ProviderDeployConfig, "resourceType")),
LoadbalancerId: maps.GetValueAsString(options.ProviderDeployConfig, "loadbalancerId"),
ListenerId: maps.GetValueAsString(options.ProviderDeployConfig, "listenerId"),
})
return deployer, err
case domain.DeployProviderTypeJDCloudCDN:
deployer, err := pJDCloudCDN.NewDeployer(&pJDCloudCDN.DeployerConfig{
AccessKeyId: access.AccessKeyId,
AccessKeySecret: access.AccessKeySecret,
Domain: maps.GetValueAsString(options.ProviderDeployConfig, "domain"),
})
return deployer, err
case domain.DeployProviderTypeJDCloudLive:
deployer, err := pJDCloudLive.NewDeployer(&pJDCloudLive.DeployerConfig{
AccessKeyId: access.AccessKeyId,
AccessKeySecret: access.AccessKeySecret,
Domain: maps.GetValueAsString(options.ProviderDeployConfig, "domain"),
})
return deployer, err
case domain.DeployProviderTypeJDCloudVOD:
deployer, err := pJDCloudVOD.NewDeployer(&pJDCloudVOD.DeployerConfig{
AccessKeyId: access.AccessKeyId,
AccessKeySecret: access.AccessKeySecret,
Domain: maps.GetValueAsString(options.ProviderDeployConfig, "domain"),
})
return deployer, err
default: default:
break break
@ -313,77 +480,93 @@ func createDeployer(options *deployerOptions) (deployer.Deployer, logger.Logger,
case domain.DeployProviderTypeLocal: case domain.DeployProviderTypeLocal:
{ {
deployer, err := providerLocal.NewWithLogger(&providerLocal.LocalDeployerConfig{ deployer, err := pLocal.NewDeployer(&pLocal.DeployerConfig{
ShellEnv: providerLocal.ShellEnvType(maps.GetValueAsString(options.ProviderDeployConfig, "shellEnv")), ShellEnv: pLocal.ShellEnvType(maps.GetValueAsString(options.ProviderDeployConfig, "shellEnv")),
PreCommand: maps.GetValueAsString(options.ProviderDeployConfig, "preCommand"), PreCommand: maps.GetValueAsString(options.ProviderDeployConfig, "preCommand"),
PostCommand: maps.GetValueAsString(options.ProviderDeployConfig, "postCommand"), PostCommand: maps.GetValueAsString(options.ProviderDeployConfig, "postCommand"),
OutputFormat: providerLocal.OutputFormatType(maps.GetValueOrDefaultAsString(options.ProviderDeployConfig, "format", string(providerLocal.OUTPUT_FORMAT_PEM))), OutputFormat: pLocal.OutputFormatType(maps.GetValueOrDefaultAsString(options.ProviderDeployConfig, "format", string(pLocal.OUTPUT_FORMAT_PEM))),
OutputCertPath: maps.GetValueAsString(options.ProviderDeployConfig, "certPath"), OutputCertPath: maps.GetValueAsString(options.ProviderDeployConfig, "certPath"),
OutputKeyPath: maps.GetValueAsString(options.ProviderDeployConfig, "keyPath"), OutputKeyPath: maps.GetValueAsString(options.ProviderDeployConfig, "keyPath"),
PfxPassword: maps.GetValueAsString(options.ProviderDeployConfig, "pfxPassword"), PfxPassword: maps.GetValueAsString(options.ProviderDeployConfig, "pfxPassword"),
JksAlias: maps.GetValueAsString(options.ProviderDeployConfig, "jksAlias"), JksAlias: maps.GetValueAsString(options.ProviderDeployConfig, "jksAlias"),
JksKeypass: maps.GetValueAsString(options.ProviderDeployConfig, "jksKeypass"), JksKeypass: maps.GetValueAsString(options.ProviderDeployConfig, "jksKeypass"),
JksStorepass: maps.GetValueAsString(options.ProviderDeployConfig, "jksStorepass"), JksStorepass: maps.GetValueAsString(options.ProviderDeployConfig, "jksStorepass"),
}, logger) })
return deployer, logger, err return deployer, err
} }
case domain.DeployProviderTypeKubernetesSecret: case domain.DeployProviderTypeKubernetesSecret:
{ {
access := domain.AccessConfigForKubernetes{} access := domain.AccessConfigForKubernetes{}
if err := maps.Populate(options.ProviderAccessConfig, &access); err != nil { if err := maps.Populate(options.ProviderAccessConfig, &access); err != nil {
return nil, nil, fmt.Errorf("failed to populate provider access config: %w", err) return nil, fmt.Errorf("failed to populate provider access config: %w", err)
} }
deployer, err := providerK8sSecret.NewWithLogger(&providerK8sSecret.K8sSecretDeployerConfig{ deployer, err := pK8sSecret.NewDeployer(&pK8sSecret.DeployerConfig{
KubeConfig: access.KubeConfig, KubeConfig: access.KubeConfig,
Namespace: maps.GetValueOrDefaultAsString(options.ProviderDeployConfig, "namespace", "default"), Namespace: maps.GetValueOrDefaultAsString(options.ProviderDeployConfig, "namespace", "default"),
SecretName: maps.GetValueAsString(options.ProviderDeployConfig, "secretName"), SecretName: maps.GetValueAsString(options.ProviderDeployConfig, "secretName"),
SecretType: maps.GetValueOrDefaultAsString(options.ProviderDeployConfig, "secretType", "kubernetes.io/tls"), SecretType: maps.GetValueOrDefaultAsString(options.ProviderDeployConfig, "secretType", "kubernetes.io/tls"),
SecretDataKeyForCrt: maps.GetValueOrDefaultAsString(options.ProviderDeployConfig, "secretDataKeyForCrt", "tls.crt"), SecretDataKeyForCrt: maps.GetValueOrDefaultAsString(options.ProviderDeployConfig, "secretDataKeyForCrt", "tls.crt"),
SecretDataKeyForKey: maps.GetValueOrDefaultAsString(options.ProviderDeployConfig, "secretDataKeyForKey", "tls.key"), SecretDataKeyForKey: maps.GetValueOrDefaultAsString(options.ProviderDeployConfig, "secretDataKeyForKey", "tls.key"),
}, logger) })
return deployer, logger, err return deployer, err
} }
case domain.DeployProviderTypeQiniuCDN, domain.DeployProviderTypeQiniuPili: case domain.DeployProviderTypeQiniuCDN, domain.DeployProviderTypeQiniuPili:
{ {
access := domain.AccessConfigForQiniu{} access := domain.AccessConfigForQiniu{}
if err := maps.Populate(options.ProviderAccessConfig, &access); err != nil { if err := maps.Populate(options.ProviderAccessConfig, &access); err != nil {
return nil, nil, fmt.Errorf("failed to populate provider access config: %w", err) return nil, fmt.Errorf("failed to populate provider access config: %w", err)
} }
switch options.Provider { switch options.Provider {
case domain.DeployProviderTypeQiniuCDN: case domain.DeployProviderTypeQiniuCDN:
deployer, err := providerQiniuCDN.NewWithLogger(&providerQiniuCDN.QiniuCDNDeployerConfig{ deployer, err := pQiniuCDN.NewDeployer(&pQiniuCDN.DeployerConfig{
AccessKey: access.AccessKey, AccessKey: access.AccessKey,
SecretKey: access.SecretKey, SecretKey: access.SecretKey,
Domain: maps.GetValueAsString(options.ProviderDeployConfig, "domain"), Domain: maps.GetValueAsString(options.ProviderDeployConfig, "domain"),
}, logger) })
return deployer, logger, err return deployer, err
case domain.DeployProviderTypeQiniuPili: case domain.DeployProviderTypeQiniuPili:
deployer, err := providerQiniuPili.NewWithLogger(&providerQiniuPili.QiniuPiliDeployerConfig{ deployer, err := pQiniuPili.NewDeployer(&pQiniuPili.DeployerConfig{
AccessKey: access.AccessKey, AccessKey: access.AccessKey,
SecretKey: access.SecretKey, SecretKey: access.SecretKey,
Hub: maps.GetValueAsString(options.ProviderDeployConfig, "hub"), Hub: maps.GetValueAsString(options.ProviderDeployConfig, "hub"),
Domain: maps.GetValueAsString(options.ProviderDeployConfig, "domain"), Domain: maps.GetValueAsString(options.ProviderDeployConfig, "domain"),
}, logger) })
return deployer, logger, err return deployer, err
default: default:
break break
} }
} }
case domain.DeployProviderTypeSafeLine:
{
access := domain.AccessConfigForSafeLine{}
if err := maps.Populate(options.ProviderAccessConfig, &access); err != nil {
return nil, fmt.Errorf("failed to populate provider access config: %w", err)
}
deployer, err := pSafeLine.NewDeployer(&pSafeLine.DeployerConfig{
ApiUrl: access.ApiUrl,
ApiToken: access.ApiToken,
ResourceType: pSafeLine.ResourceType(maps.GetValueAsString(options.ProviderDeployConfig, "resourceType")),
CertificateId: maps.GetValueAsInt32(options.ProviderDeployConfig, "certificateId"),
})
return deployer, err
}
case domain.DeployProviderTypeSSH: case domain.DeployProviderTypeSSH:
{ {
access := domain.AccessConfigForSSH{} access := domain.AccessConfigForSSH{}
if err := maps.Populate(options.ProviderAccessConfig, &access); err != nil { if err := maps.Populate(options.ProviderAccessConfig, &access); err != nil {
return nil, nil, fmt.Errorf("failed to populate provider access config: %w", err) return nil, fmt.Errorf("failed to populate provider access config: %w", err)
} }
deployer, err := providerSSH.NewWithLogger(&providerSSH.SshDeployerConfig{ deployer, err := pSSH.NewDeployer(&pSSH.DeployerConfig{
SshHost: access.Host, SshHost: access.Host,
SshPort: access.Port, SshPort: access.Port,
SshUsername: access.Username, SshUsername: access.Username,
@ -393,89 +576,108 @@ func createDeployer(options *deployerOptions) (deployer.Deployer, logger.Logger,
UseSCP: maps.GetValueAsBool(options.ProviderDeployConfig, "useSCP"), UseSCP: maps.GetValueAsBool(options.ProviderDeployConfig, "useSCP"),
PreCommand: maps.GetValueAsString(options.ProviderDeployConfig, "preCommand"), PreCommand: maps.GetValueAsString(options.ProviderDeployConfig, "preCommand"),
PostCommand: maps.GetValueAsString(options.ProviderDeployConfig, "postCommand"), PostCommand: maps.GetValueAsString(options.ProviderDeployConfig, "postCommand"),
OutputFormat: providerSSH.OutputFormatType(maps.GetValueOrDefaultAsString(options.ProviderDeployConfig, "format", string(providerSSH.OUTPUT_FORMAT_PEM))), OutputFormat: pSSH.OutputFormatType(maps.GetValueOrDefaultAsString(options.ProviderDeployConfig, "format", string(pSSH.OUTPUT_FORMAT_PEM))),
OutputCertPath: maps.GetValueAsString(options.ProviderDeployConfig, "certPath"), OutputCertPath: maps.GetValueAsString(options.ProviderDeployConfig, "certPath"),
OutputKeyPath: maps.GetValueAsString(options.ProviderDeployConfig, "keyPath"), OutputKeyPath: maps.GetValueAsString(options.ProviderDeployConfig, "keyPath"),
PfxPassword: maps.GetValueAsString(options.ProviderDeployConfig, "pfxPassword"), PfxPassword: maps.GetValueAsString(options.ProviderDeployConfig, "pfxPassword"),
JksAlias: maps.GetValueAsString(options.ProviderDeployConfig, "jksAlias"), JksAlias: maps.GetValueAsString(options.ProviderDeployConfig, "jksAlias"),
JksKeypass: maps.GetValueAsString(options.ProviderDeployConfig, "jksKeypass"), JksKeypass: maps.GetValueAsString(options.ProviderDeployConfig, "jksKeypass"),
JksStorepass: maps.GetValueAsString(options.ProviderDeployConfig, "jksStorepass"), JksStorepass: maps.GetValueAsString(options.ProviderDeployConfig, "jksStorepass"),
}, logger) })
return deployer, logger, err return deployer, err
} }
case domain.DeployProviderTypeTencentCloudCDN, domain.DeployProviderTypeTencentCloudCLB, domain.DeployProviderTypeTencentCloudCOS, domain.DeployProviderTypeTencentCloudCSS, domain.DeployProviderTypeTencentCloudECDN, domain.DeployProviderTypeTencentCloudEO, domain.DeployProviderTypeTencentCloudSSLDeploy: case domain.DeployProviderTypeTencentCloudCDN, domain.DeployProviderTypeTencentCloudCLB, domain.DeployProviderTypeTencentCloudCOS, domain.DeployProviderTypeTencentCloudCSS, domain.DeployProviderTypeTencentCloudECDN, domain.DeployProviderTypeTencentCloudEO, domain.DeployProviderTypeTencentCloudSSLDeploy, domain.DeployProviderTypeTencentCloudVOD, domain.DeployProviderTypeTencentCloudWAF:
{ {
access := domain.AccessConfigForTencentCloud{} access := domain.AccessConfigForTencentCloud{}
if err := maps.Populate(options.ProviderAccessConfig, &access); err != nil { if err := maps.Populate(options.ProviderAccessConfig, &access); err != nil {
return nil, nil, fmt.Errorf("failed to populate provider access config: %w", err) return nil, fmt.Errorf("failed to populate provider access config: %w", err)
} }
switch options.Provider { switch options.Provider {
case domain.DeployProviderTypeTencentCloudCDN: case domain.DeployProviderTypeTencentCloudCDN:
deployer, err := providerTencentCloudCDN.NewWithLogger(&providerTencentCloudCDN.TencentCloudCDNDeployerConfig{ deployer, err := pTencentCloudCDN.NewDeployer(&pTencentCloudCDN.DeployerConfig{
SecretId: access.SecretId, SecretId: access.SecretId,
SecretKey: access.SecretKey, SecretKey: access.SecretKey,
Domain: maps.GetValueAsString(options.ProviderDeployConfig, "domain"), Domain: maps.GetValueAsString(options.ProviderDeployConfig, "domain"),
}, logger) })
return deployer, logger, err return deployer, err
case domain.DeployProviderTypeTencentCloudCLB: case domain.DeployProviderTypeTencentCloudCLB:
deployer, err := providerTencentCloudCLB.NewWithLogger(&providerTencentCloudCLB.TencentCloudCLBDeployerConfig{ deployer, err := pTencentCloudCLB.NewDeployer(&pTencentCloudCLB.DeployerConfig{
SecretId: access.SecretId, SecretId: access.SecretId,
SecretKey: access.SecretKey, SecretKey: access.SecretKey,
Region: maps.GetValueAsString(options.ProviderDeployConfig, "region"), Region: maps.GetValueAsString(options.ProviderDeployConfig, "region"),
ResourceType: providerTencentCloudCLB.DeployResourceType(maps.GetValueAsString(options.ProviderDeployConfig, "resourceType")), ResourceType: pTencentCloudCLB.ResourceType(maps.GetValueAsString(options.ProviderDeployConfig, "resourceType")),
LoadbalancerId: maps.GetValueAsString(options.ProviderDeployConfig, "loadbalancerId"), LoadbalancerId: maps.GetValueAsString(options.ProviderDeployConfig, "loadbalancerId"),
ListenerId: maps.GetValueAsString(options.ProviderDeployConfig, "listenerId"), ListenerId: maps.GetValueAsString(options.ProviderDeployConfig, "listenerId"),
Domain: maps.GetValueAsString(options.ProviderDeployConfig, "domain"), Domain: maps.GetValueAsString(options.ProviderDeployConfig, "domain"),
}, logger) })
return deployer, logger, err return deployer, err
case domain.DeployProviderTypeTencentCloudCOS: case domain.DeployProviderTypeTencentCloudCOS:
deployer, err := providerTencentCloudCOS.NewWithLogger(&providerTencentCloudCOS.TencentCloudCOSDeployerConfig{ deployer, err := pTencentCloudCOS.NewDeployer(&pTencentCloudCOS.DeployerConfig{
SecretId: access.SecretId, SecretId: access.SecretId,
SecretKey: access.SecretKey, SecretKey: access.SecretKey,
Region: maps.GetValueAsString(options.ProviderDeployConfig, "region"), Region: maps.GetValueAsString(options.ProviderDeployConfig, "region"),
Bucket: maps.GetValueAsString(options.ProviderDeployConfig, "bucket"), Bucket: maps.GetValueAsString(options.ProviderDeployConfig, "bucket"),
Domain: maps.GetValueAsString(options.ProviderDeployConfig, "domain"), Domain: maps.GetValueAsString(options.ProviderDeployConfig, "domain"),
}, logger) })
return deployer, logger, err return deployer, err
case domain.DeployProviderTypeTencentCloudCSS: case domain.DeployProviderTypeTencentCloudCSS:
deployer, err := providerTencentCloudCSS.NewWithLogger(&providerTencentCloudCSS.TencentCloudCSSDeployerConfig{ deployer, err := pTencentCloudCSS.NewDeployer(&pTencentCloudCSS.DeployerConfig{
SecretId: access.SecretId, SecretId: access.SecretId,
SecretKey: access.SecretKey, SecretKey: access.SecretKey,
Domain: maps.GetValueAsString(options.ProviderDeployConfig, "domain"), Domain: maps.GetValueAsString(options.ProviderDeployConfig, "domain"),
}, logger) })
return deployer, logger, err return deployer, err
case domain.DeployProviderTypeTencentCloudECDN: case domain.DeployProviderTypeTencentCloudECDN:
deployer, err := providerTencentCloudECDN.NewWithLogger(&providerTencentCloudECDN.TencentCloudECDNDeployerConfig{ deployer, err := pTencentCloudECDN.NewDeployer(&pTencentCloudECDN.DeployerConfig{
SecretId: access.SecretId, SecretId: access.SecretId,
SecretKey: access.SecretKey, SecretKey: access.SecretKey,
Domain: maps.GetValueAsString(options.ProviderDeployConfig, "domain"), Domain: maps.GetValueAsString(options.ProviderDeployConfig, "domain"),
}, logger) })
return deployer, logger, err return deployer, err
case domain.DeployProviderTypeTencentCloudEO: case domain.DeployProviderTypeTencentCloudEO:
deployer, err := providerTencentCloudEO.NewWithLogger(&providerTencentCloudEO.TencentCloudEODeployerConfig{ deployer, err := pTencentCloudEO.NewDeployer(&pTencentCloudEO.DeployerConfig{
SecretId: access.SecretId, SecretId: access.SecretId,
SecretKey: access.SecretKey, SecretKey: access.SecretKey,
ZoneId: maps.GetValueAsString(options.ProviderDeployConfig, "zoneId"), ZoneId: maps.GetValueAsString(options.ProviderDeployConfig, "zoneId"),
Domain: maps.GetValueAsString(options.ProviderDeployConfig, "domain"), Domain: maps.GetValueAsString(options.ProviderDeployConfig, "domain"),
}, logger) })
return deployer, logger, err return deployer, err
case domain.DeployProviderTypeTencentCloudSSLDeploy: case domain.DeployProviderTypeTencentCloudSSLDeploy:
deployer, err := providerTencentCloudSSLDeploy.NewWithLogger(&providerTencentCloudSSLDeploy.TencentCloudSSLDeployDeployerConfig{ deployer, err := pTencentCloudSSLDeploy.NewDeployer(&pTencentCloudSSLDeploy.DeployerConfig{
SecretId: access.SecretId, SecretId: access.SecretId,
SecretKey: access.SecretKey, SecretKey: access.SecretKey,
Region: maps.GetValueAsString(options.ProviderDeployConfig, "region"), Region: maps.GetValueAsString(options.ProviderDeployConfig, "region"),
ResourceType: maps.GetValueAsString(options.ProviderDeployConfig, "resourceType"), ResourceType: maps.GetValueAsString(options.ProviderDeployConfig, "resourceType"),
ResourceIds: slices.Filter(strings.Split(maps.GetValueAsString(options.ProviderDeployConfig, "resourceIds"), ";"), func(s string) bool { return s != "" }), ResourceIds: slices.Filter(strings.Split(maps.GetValueAsString(options.ProviderDeployConfig, "resourceIds"), ";"), func(s string) bool { return s != "" }),
}, logger) })
return deployer, logger, err return deployer, err
case domain.DeployProviderTypeTencentCloudVOD:
deployer, err := pTencentCloudVOD.NewDeployer(&pTencentCloudVOD.DeployerConfig{
SecretId: access.SecretId,
SecretKey: access.SecretKey,
SubAppId: maps.GetValueAsInt64(options.ProviderDeployConfig, "subAppId"),
Domain: maps.GetValueAsString(options.ProviderDeployConfig, "domain"),
})
return deployer, err
case domain.DeployProviderTypeTencentCloudWAF:
deployer, err := pTencentCloudWAF.NewDeployer(&pTencentCloudWAF.DeployerConfig{
SecretId: access.SecretId,
SecretKey: access.SecretKey,
Domain: maps.GetValueAsString(options.ProviderDeployConfig, "domain"),
DomainId: maps.GetValueAsString(options.ProviderDeployConfig, "domainId"),
InstanceId: maps.GetValueAsString(options.ProviderDeployConfig, "instanceId"),
})
return deployer, err
default: default:
break break
@ -486,86 +688,96 @@ func createDeployer(options *deployerOptions) (deployer.Deployer, logger.Logger,
{ {
access := domain.AccessConfigForUCloud{} access := domain.AccessConfigForUCloud{}
if err := maps.Populate(options.ProviderAccessConfig, &access); err != nil { if err := maps.Populate(options.ProviderAccessConfig, &access); err != nil {
return nil, nil, fmt.Errorf("failed to populate provider access config: %w", err) return nil, fmt.Errorf("failed to populate provider access config: %w", err)
} }
switch options.Provider { switch options.Provider {
case domain.DeployProviderTypeUCloudUCDN: case domain.DeployProviderTypeUCloudUCDN:
deployer, err := providerUCloudUCDN.NewWithLogger(&providerUCloudUCDN.UCloudUCDNDeployerConfig{ deployer, err := pUCloudUCDN.NewDeployer(&pUCloudUCDN.DeployerConfig{
PrivateKey: access.PrivateKey, PrivateKey: access.PrivateKey,
PublicKey: access.PublicKey, PublicKey: access.PublicKey,
ProjectId: access.ProjectId, ProjectId: access.ProjectId,
DomainId: maps.GetValueAsString(options.ProviderDeployConfig, "domainId"), DomainId: maps.GetValueAsString(options.ProviderDeployConfig, "domainId"),
}, logger) })
return deployer, logger, err return deployer, err
case domain.DeployProviderTypeUCloudUS3: case domain.DeployProviderTypeUCloudUS3:
deployer, err := providerUCloudUS3.NewWithLogger(&providerUCloudUS3.UCloudUS3DeployerConfig{ deployer, err := pUCloudUS3.NewDeployer(&pUCloudUS3.DeployerConfig{
PrivateKey: access.PrivateKey, PrivateKey: access.PrivateKey,
PublicKey: access.PublicKey, PublicKey: access.PublicKey,
ProjectId: access.ProjectId, ProjectId: access.ProjectId,
Region: maps.GetValueAsString(options.ProviderDeployConfig, "region"), Region: maps.GetValueAsString(options.ProviderDeployConfig, "region"),
Bucket: maps.GetValueAsString(options.ProviderDeployConfig, "bucket"), Bucket: maps.GetValueAsString(options.ProviderDeployConfig, "bucket"),
Domain: maps.GetValueAsString(options.ProviderDeployConfig, "domain"), Domain: maps.GetValueAsString(options.ProviderDeployConfig, "domain"),
}, logger) })
return deployer, logger, err return deployer, err
default: default:
break break
} }
} }
case domain.DeployProviderTypeVolcEngineCDN, domain.DeployProviderTypeVolcEngineCLB, domain.DeployProviderTypeVolcEngineDCDN, domain.DeployProviderTypeVolcEngineLive, domain.DeployProviderTypeVolcEngineTOS: case domain.DeployProviderTypeVolcEngineCDN, domain.DeployProviderTypeVolcEngineCLB, domain.DeployProviderTypeVolcEngineDCDN, domain.DeployProviderTypeVolcEngineImageX, domain.DeployProviderTypeVolcEngineLive, domain.DeployProviderTypeVolcEngineTOS:
{ {
access := domain.AccessConfigForVolcEngine{} access := domain.AccessConfigForVolcEngine{}
if err := maps.Populate(options.ProviderAccessConfig, &access); err != nil { if err := maps.Populate(options.ProviderAccessConfig, &access); err != nil {
return nil, nil, fmt.Errorf("failed to populate provider access config: %w", err) return nil, fmt.Errorf("failed to populate provider access config: %w", err)
} }
switch options.Provider { switch options.Provider {
case domain.DeployProviderTypeVolcEngineCDN: case domain.DeployProviderTypeVolcEngineCDN:
deployer, err := providerVolcEngineCDN.NewWithLogger(&providerVolcEngineCDN.VolcEngineCDNDeployerConfig{ deployer, err := pVolcEngineCDN.NewDeployer(&pVolcEngineCDN.DeployerConfig{
AccessKeyId: access.AccessKeyId, AccessKeyId: access.AccessKeyId,
AccessKeySecret: access.SecretAccessKey, AccessKeySecret: access.SecretAccessKey,
Domain: maps.GetValueAsString(options.ProviderDeployConfig, "domain"), Domain: maps.GetValueAsString(options.ProviderDeployConfig, "domain"),
}, logger) })
return deployer, logger, err return deployer, err
case domain.DeployProviderTypeVolcEngineCLB: case domain.DeployProviderTypeVolcEngineCLB:
deployer, err := providerVolcEngineCLB.NewWithLogger(&providerVolcEngineCLB.VolcEngineCLBDeployerConfig{ deployer, err := pVolcEngineCLB.NewDeployer(&pVolcEngineCLB.DeployerConfig{
AccessKeyId: access.AccessKeyId, AccessKeyId: access.AccessKeyId,
AccessKeySecret: access.SecretAccessKey, AccessKeySecret: access.SecretAccessKey,
Region: maps.GetValueAsString(options.ProviderDeployConfig, "region"), Region: maps.GetValueAsString(options.ProviderDeployConfig, "region"),
ResourceType: providerVolcEngineCLB.DeployResourceType(maps.GetValueAsString(options.ProviderDeployConfig, "resourceType")), ResourceType: pVolcEngineCLB.ResourceType(maps.GetValueAsString(options.ProviderDeployConfig, "resourceType")),
ListenerId: maps.GetValueAsString(options.ProviderDeployConfig, "listenerId"), ListenerId: maps.GetValueAsString(options.ProviderDeployConfig, "listenerId"),
}, logger) })
return deployer, logger, err return deployer, err
case domain.DeployProviderTypeVolcEngineDCDN: case domain.DeployProviderTypeVolcEngineDCDN:
deployer, err := providerVolcEngineDCDN.NewWithLogger(&providerVolcEngineDCDN.VolcEngineDCDNDeployerConfig{ deployer, err := pVolcEngineDCDN.NewDeployer(&pVolcEngineDCDN.DeployerConfig{
AccessKeyId: access.AccessKeyId, AccessKeyId: access.AccessKeyId,
AccessKeySecret: access.SecretAccessKey, AccessKeySecret: access.SecretAccessKey,
Domain: maps.GetValueAsString(options.ProviderDeployConfig, "domain"), Domain: maps.GetValueAsString(options.ProviderDeployConfig, "domain"),
}, logger) })
return deployer, logger, err return deployer, err
case domain.DeployProviderTypeVolcEngineImageX:
deployer, err := pVolcEngineImageX.NewDeployer(&pVolcEngineImageX.DeployerConfig{
AccessKeyId: access.AccessKeyId,
AccessKeySecret: access.SecretAccessKey,
Region: maps.GetValueAsString(options.ProviderDeployConfig, "region"),
ServiceId: maps.GetValueAsString(options.ProviderDeployConfig, "serviceId"),
Domain: maps.GetValueAsString(options.ProviderDeployConfig, "domain"),
})
return deployer, err
case domain.DeployProviderTypeVolcEngineLive: case domain.DeployProviderTypeVolcEngineLive:
deployer, err := providerVolcEngineLive.NewWithLogger(&providerVolcEngineLive.VolcEngineLiveDeployerConfig{ deployer, err := pVolcEngineLive.NewDeployer(&pVolcEngineLive.DeployerConfig{
AccessKeyId: access.AccessKeyId, AccessKeyId: access.AccessKeyId,
AccessKeySecret: access.SecretAccessKey, AccessKeySecret: access.SecretAccessKey,
Domain: maps.GetValueAsString(options.ProviderDeployConfig, "domain"), Domain: maps.GetValueAsString(options.ProviderDeployConfig, "domain"),
}, logger) })
return deployer, logger, err return deployer, err
case domain.DeployProviderTypeVolcEngineTOS: case domain.DeployProviderTypeVolcEngineTOS:
deployer, err := providerVolcEngineTOS.NewWithLogger(&providerVolcEngineTOS.VolcEngineTOSDeployerConfig{ deployer, err := pVolcEngineTOS.NewDeployer(&pVolcEngineTOS.DeployerConfig{
AccessKeyId: access.AccessKeyId, AccessKeyId: access.AccessKeyId,
AccessKeySecret: access.SecretAccessKey, AccessKeySecret: access.SecretAccessKey,
Region: maps.GetValueAsString(options.ProviderDeployConfig, "region"), Region: maps.GetValueAsString(options.ProviderDeployConfig, "region"),
Bucket: maps.GetValueAsString(options.ProviderDeployConfig, "bucket"), Bucket: maps.GetValueAsString(options.ProviderDeployConfig, "bucket"),
Domain: maps.GetValueAsString(options.ProviderDeployConfig, "domain"), Domain: maps.GetValueAsString(options.ProviderDeployConfig, "domain"),
}, logger) })
return deployer, logger, err return deployer, err
default: default:
break break
@ -576,16 +788,16 @@ func createDeployer(options *deployerOptions) (deployer.Deployer, logger.Logger,
{ {
access := domain.AccessConfigForWebhook{} access := domain.AccessConfigForWebhook{}
if err := maps.Populate(options.ProviderAccessConfig, &access); err != nil { if err := maps.Populate(options.ProviderAccessConfig, &access); err != nil {
return nil, nil, fmt.Errorf("failed to populate provider access config: %w", err) return nil, fmt.Errorf("failed to populate provider access config: %w", err)
} }
deployer, err := providerWebhook.NewWithLogger(&providerWebhook.WebhookDeployerConfig{ deployer, err := pWebhook.NewDeployer(&pWebhook.DeployerConfig{
WebhookUrl: access.Url, WebhookUrl: access.Url,
WebhookData: maps.GetValueAsString(options.ProviderDeployConfig, "webhookData"), WebhookData: maps.GetValueAsString(options.ProviderDeployConfig, "webhookData"),
}, logger) })
return deployer, logger, err return deployer, err
} }
} }
return nil, nil, fmt.Errorf("unsupported deployer provider: %s", string(options.Provider)) return nil, fmt.Errorf("unsupported deployer provider: %s", string(options.Provider))
} }

View File

@ -53,6 +53,10 @@ type AccessConfigForBaiduCloud struct {
SecretAccessKey string `json:"secretAccessKey"` SecretAccessKey string `json:"secretAccessKey"`
} }
type AccessConfigForBaishan struct {
ApiToken string `json:"apiToken"`
}
type AccessConfigForBaotaPanel struct { type AccessConfigForBaotaPanel struct {
ApiUrl string `json:"apiUrl"` ApiUrl string `json:"apiUrl"`
ApiKey string `json:"apiKey"` ApiKey string `json:"apiKey"`
@ -63,6 +67,16 @@ type AccessConfigForBytePlus struct {
SecretKey string `json:"secretKey"` SecretKey string `json:"secretKey"`
} }
type AccessConfigForCacheFly struct {
ApiToken string `json:"apiToken"`
}
type AccessConfigForCdnfly struct {
ApiUrl string `json:"apiUrl"`
ApiKey string `json:"apiKey"`
ApiSecret string `json:"apiSecret"`
}
type AccessConfigForCloudflare struct { type AccessConfigForCloudflare struct {
DnsApiToken string `json:"dnsApiToken"` DnsApiToken string `json:"dnsApiToken"`
} }
@ -72,6 +86,16 @@ type AccessConfigForClouDNS struct {
AuthPassword string `json:"authPassword"` AuthPassword string `json:"authPassword"`
} }
type AccessConfigForCMCCCloud struct {
AccessKeyId string `json:"accessKeyId"`
AccessKeySecret string `json:"accessKeySecret"`
}
type AccessConfigForDNSLA struct {
ApiId string `json:"apiId"`
ApiSecret string `json:"apiSecret"`
}
type AccessConfigForDogeCloud struct { type AccessConfigForDogeCloud struct {
AccessKey string `json:"accessKey"` AccessKey string `json:"accessKey"`
SecretKey string `json:"secretKey"` SecretKey string `json:"secretKey"`
@ -82,6 +106,10 @@ type AccessConfigForEdgio struct {
ClientSecret string `json:"clientSecret"` ClientSecret string `json:"clientSecret"`
} }
type AccessConfigForGcore struct {
ApiToken string `json:"apiToken"`
}
type AccessConfigForGname struct { type AccessConfigForGname struct {
AppId string `json:"appId"` AppId string `json:"appId"`
AppKey string `json:"appKey"` AppKey string `json:"appKey"`
@ -97,12 +125,22 @@ type AccessConfigForHuaweiCloud struct {
SecretAccessKey string `json:"secretAccessKey"` SecretAccessKey string `json:"secretAccessKey"`
} }
type AccessConfigForLocal struct{} type AccessConfigForJDCloud struct {
AccessKeyId string `json:"accessKeyId"`
AccessKeySecret string `json:"accessKeySecret"`
}
type AccessConfigForKubernetes struct { type AccessConfigForKubernetes struct {
KubeConfig string `json:"kubeConfig,omitempty"` KubeConfig string `json:"kubeConfig,omitempty"`
} }
type AccessConfigForLocal struct{}
type AccessConfigForNamecheap struct {
Username string `json:"username"`
ApiKey string `json:"apiKey"`
}
type AccessConfigForNameDotCom struct { type AccessConfigForNameDotCom struct {
Username string `json:"username"` Username string `json:"username"`
ApiToken string `json:"apiToken"` ApiToken string `json:"apiToken"`
@ -130,6 +168,11 @@ type AccessConfigForRainYun struct {
ApiKey string `json:"apiKey"` ApiKey string `json:"apiKey"`
} }
type AccessConfigForSafeLine struct {
ApiUrl string `json:"apiUrl"`
ApiToken string `json:"apiToken"`
}
type AccessConfigForSSH struct { type AccessConfigForSSH struct {
Host string `json:"host"` Host string `json:"host"`
Port int32 `json:"port"` Port int32 `json:"port"`

View File

@ -16,33 +16,37 @@ const (
AccessProviderTypeAWS = AccessProviderType("aws") AccessProviderTypeAWS = AccessProviderType("aws")
AccessProviderTypeAzure = AccessProviderType("azure") AccessProviderTypeAzure = AccessProviderType("azure")
AccessProviderTypeBaiduCloud = AccessProviderType("baiducloud") AccessProviderTypeBaiduCloud = AccessProviderType("baiducloud")
AccessProviderTypeBaishan = AccessProviderType("baishan") // 白山云(预留) AccessProviderTypeBaishan = AccessProviderType("baishan")
AccessProviderTypeBaotaPanel = AccessProviderType("baotapanel") AccessProviderTypeBaotaPanel = AccessProviderType("baotapanel")
AccessProviderTypeBytePlus = AccessProviderType("byteplus") AccessProviderTypeBytePlus = AccessProviderType("byteplus")
AccessProviderTypeCacheFly = AccessProviderType("cachefly") // CacheFly预留 AccessProviderTypeCacheFly = AccessProviderType("cachefly")
AccessProviderTypeCdnfly = AccessProviderType("cdnfly") // Cdnly预留 AccessProviderTypeCdnfly = AccessProviderType("cdnfly")
AccessProviderTypeCloudflare = AccessProviderType("cloudflare") AccessProviderTypeCloudflare = AccessProviderType("cloudflare")
AccessProviderTypeClouDNS = AccessProviderType("cloudns") AccessProviderTypeClouDNS = AccessProviderType("cloudns")
AccessProviderTypeCMCCCloud = AccessProviderType("cmcccloud") // 移动云(预留) AccessProviderTypeCMCCCloud = AccessProviderType("cmcccloud")
AccessProviderTypeCTCCCloud = AccessProviderType("ctcccloud") // 联通云(预留) AccessProviderTypeCTCCCloud = AccessProviderType("ctcccloud") // 联通云(预留)
AccessProviderTypeCUCCCloud = AccessProviderType("cucccloud") // 天翼云(预留) AccessProviderTypeCUCCCloud = AccessProviderType("cucccloud") // 天翼云(预留)
AccessProviderTypeDNSLA = AccessProviderType("dnsla")
AccessProviderTypeDogeCloud = AccessProviderType("dogecloud") AccessProviderTypeDogeCloud = AccessProviderType("dogecloud")
AccessProviderTypeEdgio = AccessProviderType("edgio") AccessProviderTypeEdgio = AccessProviderType("edgio")
AccessProviderTypeFastly = AccessProviderType("fastly") // Fastly预留 AccessProviderTypeFastly = AccessProviderType("fastly") // Fastly预留
AccessProviderTypeGname = AccessProviderType("gname") AccessProviderTypeGname = AccessProviderType("gname")
AccessProviderTypeGcore = AccessProviderType("gcore") // Gcore预留 AccessProviderTypeGcore = AccessProviderType("gcore")
AccessProviderTypeGoDaddy = AccessProviderType("godaddy") AccessProviderTypeGoDaddy = AccessProviderType("godaddy")
AccessProviderTypeGoEdge = AccessProviderType("goedge") // GoEdge预留 AccessProviderTypeGoEdge = AccessProviderType("goedge") // GoEdge预留
AccessProviderTypeHuaweiCloud = AccessProviderType("huaweicloud") AccessProviderTypeHuaweiCloud = AccessProviderType("huaweicloud")
AccessProviderTypeJDCloud = AccessProviderType("jdcloud")
AccessProviderTypeKubernetes = AccessProviderType("k8s") AccessProviderTypeKubernetes = AccessProviderType("k8s")
AccessProviderTypeLocal = AccessProviderType("local") AccessProviderTypeLocal = AccessProviderType("local")
AccessProviderTypeNamecheap = AccessProviderType("namecheap")
AccessProviderTypeNameDotCom = AccessProviderType("namedotcom") AccessProviderTypeNameDotCom = AccessProviderType("namedotcom")
AccessProviderTypeNameSilo = AccessProviderType("namesilo") AccessProviderTypeNameSilo = AccessProviderType("namesilo")
AccessProviderTypeNS1 = AccessProviderType("ns1") AccessProviderTypeNS1 = AccessProviderType("ns1")
AccessProviderTypePowerDNS = AccessProviderType("powerdns") AccessProviderTypePowerDNS = AccessProviderType("powerdns")
AccessProviderTypeQiniu = AccessProviderType("qiniu") AccessProviderTypeQiniu = AccessProviderType("qiniu")
AccessProviderTypeQingCloud = AccessProviderType("qingcloud") // 青云(预留)
AccessProviderTypeRainYun = AccessProviderType("rainyun") AccessProviderTypeRainYun = AccessProviderType("rainyun")
AccessProviderTypeSafeLine = AccessProviderType("safeline") // 雷池(预留) AccessProviderTypeSafeLine = AccessProviderType("safeline")
AccessProviderTypeSSH = AccessProviderType("ssh") AccessProviderTypeSSH = AccessProviderType("ssh")
AccessProviderTypeTencentCloud = AccessProviderType("tencentcloud") AccessProviderTypeTencentCloud = AccessProviderType("tencentcloud")
AccessProviderTypeUCloud = AccessProviderType("ucloud") AccessProviderTypeUCloud = AccessProviderType("ucloud")
@ -66,13 +70,22 @@ const (
ApplyDNSProviderTypeAliyunDNS = ApplyDNSProviderType("aliyun-dns") ApplyDNSProviderTypeAliyunDNS = ApplyDNSProviderType("aliyun-dns")
ApplyDNSProviderTypeAWS = ApplyDNSProviderType("aws") // 兼容旧值,等同于 [ApplyDNSProviderTypeAWSRoute53] ApplyDNSProviderTypeAWS = ApplyDNSProviderType("aws") // 兼容旧值,等同于 [ApplyDNSProviderTypeAWSRoute53]
ApplyDNSProviderTypeAWSRoute53 = ApplyDNSProviderType("aws-route53") ApplyDNSProviderTypeAWSRoute53 = ApplyDNSProviderType("aws-route53")
ApplyDNSProviderTypeAzure = ApplyDNSProviderType("azure") // 兼容旧值,等同于 [ApplyDNSProviderTypeAzure]
ApplyDNSProviderTypeAzureDNS = ApplyDNSProviderType("azure-dns") ApplyDNSProviderTypeAzureDNS = ApplyDNSProviderType("azure-dns")
ApplyDNSProviderTypeBaiduCloud = ApplyDNSProviderType("baiducloud") // 兼容旧值,等同于 [ApplyDNSProviderTypeBaiduCloudDNS]
ApplyDNSProviderTypeBaiduCloudDNS = ApplyDNSProviderType("baiducloud-dns")
ApplyDNSProviderTypeCloudflare = ApplyDNSProviderType("cloudflare") ApplyDNSProviderTypeCloudflare = ApplyDNSProviderType("cloudflare")
ApplyDNSProviderTypeClouDNS = ApplyDNSProviderType("cloudns") ApplyDNSProviderTypeClouDNS = ApplyDNSProviderType("cloudns")
ApplyDNSProviderTypeCMCCCloud = ApplyDNSProviderType("cmcccloud")
ApplyDNSProviderTypeDNSLA = ApplyDNSProviderType("dnsla")
ApplyDNSProviderTypeGcore = ApplyDNSProviderType("gcore")
ApplyDNSProviderTypeGname = ApplyDNSProviderType("gname") ApplyDNSProviderTypeGname = ApplyDNSProviderType("gname")
ApplyDNSProviderTypeGoDaddy = ApplyDNSProviderType("godaddy") ApplyDNSProviderTypeGoDaddy = ApplyDNSProviderType("godaddy")
ApplyDNSProviderTypeHuaweiCloud = ApplyDNSProviderType("huaweicloud") // 兼容旧值,等同于 [ApplyDNSProviderTypeHuaweiCloudDNS] ApplyDNSProviderTypeHuaweiCloud = ApplyDNSProviderType("huaweicloud") // 兼容旧值,等同于 [ApplyDNSProviderTypeHuaweiCloudDNS]
ApplyDNSProviderTypeHuaweiCloudDNS = ApplyDNSProviderType("huaweicloud-dns") ApplyDNSProviderTypeHuaweiCloudDNS = ApplyDNSProviderType("huaweicloud-dns")
ApplyDNSProviderTypeJDCloud = ApplyDNSProviderType("jdcloud") // 兼容旧值,等同于 [ApplyDNSProviderTypeJDCloudDNS]
ApplyDNSProviderTypeJDCloudDNS = ApplyDNSProviderType("jdcloud-dns")
ApplyDNSProviderTypeNamecheap = ApplyDNSProviderType("namecheap")
ApplyDNSProviderTypeNameDotCom = ApplyDNSProviderType("namedotcom") ApplyDNSProviderTypeNameDotCom = ApplyDNSProviderType("namedotcom")
ApplyDNSProviderTypeNameSilo = ApplyDNSProviderType("namesilo") ApplyDNSProviderTypeNameSilo = ApplyDNSProviderType("namesilo")
ApplyDNSProviderTypeNS1 = ApplyDNSProviderType("ns1") ApplyDNSProviderTypeNS1 = ApplyDNSProviderType("ns1")
@ -104,19 +117,31 @@ const (
DeployProviderTypeAliyunLive = DeployProviderType("aliyun-live") DeployProviderTypeAliyunLive = DeployProviderType("aliyun-live")
DeployProviderTypeAliyunNLB = DeployProviderType("aliyun-nlb") DeployProviderTypeAliyunNLB = DeployProviderType("aliyun-nlb")
DeployProviderTypeAliyunOSS = DeployProviderType("aliyun-oss") DeployProviderTypeAliyunOSS = DeployProviderType("aliyun-oss")
DeployProviderTypeAliyunVOD = DeployProviderType("aliyun-vod")
DeployProviderTypeAliyunWAF = DeployProviderType("aliyun-waf") DeployProviderTypeAliyunWAF = DeployProviderType("aliyun-waf")
DeployProviderTypeAWSCloudFront = DeployProviderType("aws-cloudfront") DeployProviderTypeAWSCloudFront = DeployProviderType("aws-cloudfront")
DeployProviderTypeBaiduCloudCDN = DeployProviderType("baiducloud-cdn") DeployProviderTypeBaiduCloudCDN = DeployProviderType("baiducloud-cdn")
DeployProviderTypeBaishanCDN = DeployProviderType("baishan-cdn")
DeployProviderTypeBaotaPanelConsole = DeployProviderType("baotapanel-console")
DeployProviderTypeBaotaPanelSite = DeployProviderType("baotapanel-site") DeployProviderTypeBaotaPanelSite = DeployProviderType("baotapanel-site")
DeployProviderTypeBytePlusCDN = DeployProviderType("byteplus-cdn") DeployProviderTypeBytePlusCDN = DeployProviderType("byteplus-cdn")
DeployProviderTypeCacheFly = DeployProviderType("cachefly")
DeployProviderTypeCdnfly = DeployProviderType("cdnfly")
DeployProviderTypeDogeCloudCDN = DeployProviderType("dogecloud-cdn") DeployProviderTypeDogeCloudCDN = DeployProviderType("dogecloud-cdn")
DeployProviderTypeEdgioApplications = DeployProviderType("edgio-applications") DeployProviderTypeEdgioApplications = DeployProviderType("edgio-applications")
DeployProviderTypeGcoreCDN = DeployProviderType("gcore-cdn")
DeployProviderTypeHuaweiCloudCDN = DeployProviderType("huaweicloud-cdn") DeployProviderTypeHuaweiCloudCDN = DeployProviderType("huaweicloud-cdn")
DeployProviderTypeHuaweiCloudELB = DeployProviderType("huaweicloud-elb") DeployProviderTypeHuaweiCloudELB = DeployProviderType("huaweicloud-elb")
DeployProviderTypeHuaweiCloudWAF = DeployProviderType("huaweicloud-waf")
DeployProviderTypeJDCloudALB = DeployProviderType("jdcloud-alb")
DeployProviderTypeJDCloudCDN = DeployProviderType("jdcloud-cdn")
DeployProviderTypeJDCloudLive = DeployProviderType("jdcloud-live")
DeployProviderTypeJDCloudVOD = DeployProviderType("jdcloud-vod")
DeployProviderTypeKubernetesSecret = DeployProviderType("k8s-secret") DeployProviderTypeKubernetesSecret = DeployProviderType("k8s-secret")
DeployProviderTypeLocal = DeployProviderType("local") DeployProviderTypeLocal = DeployProviderType("local")
DeployProviderTypeQiniuCDN = DeployProviderType("qiniu-cdn") DeployProviderTypeQiniuCDN = DeployProviderType("qiniu-cdn")
DeployProviderTypeQiniuPili = DeployProviderType("qiniu-pili") DeployProviderTypeQiniuPili = DeployProviderType("qiniu-pili")
DeployProviderTypeSafeLine = DeployProviderType("safeline")
DeployProviderTypeSSH = DeployProviderType("ssh") DeployProviderTypeSSH = DeployProviderType("ssh")
DeployProviderTypeTencentCloudCDN = DeployProviderType("tencentcloud-cdn") DeployProviderTypeTencentCloudCDN = DeployProviderType("tencentcloud-cdn")
DeployProviderTypeTencentCloudCLB = DeployProviderType("tencentcloud-clb") DeployProviderTypeTencentCloudCLB = DeployProviderType("tencentcloud-clb")
@ -125,11 +150,14 @@ const (
DeployProviderTypeTencentCloudECDN = DeployProviderType("tencentcloud-ecdn") DeployProviderTypeTencentCloudECDN = DeployProviderType("tencentcloud-ecdn")
DeployProviderTypeTencentCloudEO = DeployProviderType("tencentcloud-eo") DeployProviderTypeTencentCloudEO = DeployProviderType("tencentcloud-eo")
DeployProviderTypeTencentCloudSSLDeploy = DeployProviderType("tencentcloud-ssldeploy") DeployProviderTypeTencentCloudSSLDeploy = DeployProviderType("tencentcloud-ssldeploy")
DeployProviderTypeTencentCloudVOD = DeployProviderType("tencentcloud-vod")
DeployProviderTypeTencentCloudWAF = DeployProviderType("tencentcloud-waf")
DeployProviderTypeUCloudUCDN = DeployProviderType("ucloud-ucdn") DeployProviderTypeUCloudUCDN = DeployProviderType("ucloud-ucdn")
DeployProviderTypeUCloudUS3 = DeployProviderType("ucloud-us3") DeployProviderTypeUCloudUS3 = DeployProviderType("ucloud-us3")
DeployProviderTypeVolcEngineCDN = DeployProviderType("volcengine-cdn") DeployProviderTypeVolcEngineCDN = DeployProviderType("volcengine-cdn")
DeployProviderTypeVolcEngineCLB = DeployProviderType("volcengine-clb") DeployProviderTypeVolcEngineCLB = DeployProviderType("volcengine-clb")
DeployProviderTypeVolcEngineDCDN = DeployProviderType("volcengine-dcdn") DeployProviderTypeVolcEngineDCDN = DeployProviderType("volcengine-dcdn")
DeployProviderTypeVolcEngineImageX = DeployProviderType("volcengine-imagex")
DeployProviderTypeVolcEngineLive = DeployProviderType("volcengine-live") DeployProviderTypeVolcEngineLive = DeployProviderType("volcengine-live")
DeployProviderTypeVolcEngineTOS = DeployProviderType("volcengine-tos") DeployProviderTypeVolcEngineTOS = DeployProviderType("volcengine-tos")
DeployProviderTypeWebhook = DeployProviderType("webhook") DeployProviderTypeWebhook = DeployProviderType("webhook")

View File

@ -5,14 +5,14 @@ import (
"github.com/usual2970/certimate/internal/domain" "github.com/usual2970/certimate/internal/domain"
"github.com/usual2970/certimate/internal/pkg/core/notifier" "github.com/usual2970/certimate/internal/pkg/core/notifier"
providerBark "github.com/usual2970/certimate/internal/pkg/core/notifier/providers/bark" pBark "github.com/usual2970/certimate/internal/pkg/core/notifier/providers/bark"
providerDingTalk "github.com/usual2970/certimate/internal/pkg/core/notifier/providers/dingtalk" pDingTalk "github.com/usual2970/certimate/internal/pkg/core/notifier/providers/dingtalk"
providerEmail "github.com/usual2970/certimate/internal/pkg/core/notifier/providers/email" pEmail "github.com/usual2970/certimate/internal/pkg/core/notifier/providers/email"
providerLark "github.com/usual2970/certimate/internal/pkg/core/notifier/providers/lark" pLark "github.com/usual2970/certimate/internal/pkg/core/notifier/providers/lark"
providerServerChan "github.com/usual2970/certimate/internal/pkg/core/notifier/providers/serverchan" pServerChan "github.com/usual2970/certimate/internal/pkg/core/notifier/providers/serverchan"
providerTelegram "github.com/usual2970/certimate/internal/pkg/core/notifier/providers/telegram" pTelegram "github.com/usual2970/certimate/internal/pkg/core/notifier/providers/telegram"
providerWebhook "github.com/usual2970/certimate/internal/pkg/core/notifier/providers/webhook" pWebhook "github.com/usual2970/certimate/internal/pkg/core/notifier/providers/webhook"
providerWeCom "github.com/usual2970/certimate/internal/pkg/core/notifier/providers/wecom" pWeCom "github.com/usual2970/certimate/internal/pkg/core/notifier/providers/wecom"
"github.com/usual2970/certimate/internal/pkg/utils/maps" "github.com/usual2970/certimate/internal/pkg/utils/maps"
) )
@ -23,19 +23,19 @@ func createNotifier(channel domain.NotifyChannelType, channelConfig map[string]a
*/ */
switch channel { switch channel {
case domain.NotifyChannelTypeBark: case domain.NotifyChannelTypeBark:
return providerBark.New(&providerBark.BarkNotifierConfig{ return pBark.NewNotifier(&pBark.NotifierConfig{
DeviceKey: maps.GetValueAsString(channelConfig, "deviceKey"), DeviceKey: maps.GetValueAsString(channelConfig, "deviceKey"),
ServerUrl: maps.GetValueAsString(channelConfig, "serverUrl"), ServerUrl: maps.GetValueAsString(channelConfig, "serverUrl"),
}) })
case domain.NotifyChannelTypeDingTalk: case domain.NotifyChannelTypeDingTalk:
return providerDingTalk.New(&providerDingTalk.DingTalkNotifierConfig{ return pDingTalk.NewNotifier(&pDingTalk.NotifierConfig{
AccessToken: maps.GetValueAsString(channelConfig, "accessToken"), AccessToken: maps.GetValueAsString(channelConfig, "accessToken"),
Secret: maps.GetValueAsString(channelConfig, "secret"), Secret: maps.GetValueAsString(channelConfig, "secret"),
}) })
case domain.NotifyChannelTypeEmail: case domain.NotifyChannelTypeEmail:
return providerEmail.New(&providerEmail.EmailNotifierConfig{ return pEmail.NewNotifier(&pEmail.NotifierConfig{
SmtpHost: maps.GetValueAsString(channelConfig, "smtpHost"), SmtpHost: maps.GetValueAsString(channelConfig, "smtpHost"),
SmtpPort: maps.GetValueAsInt32(channelConfig, "smtpPort"), SmtpPort: maps.GetValueAsInt32(channelConfig, "smtpPort"),
SmtpTLS: maps.GetValueOrDefaultAsBool(channelConfig, "smtpTLS", true), SmtpTLS: maps.GetValueOrDefaultAsBool(channelConfig, "smtpTLS", true),
@ -46,28 +46,28 @@ func createNotifier(channel domain.NotifyChannelType, channelConfig map[string]a
}) })
case domain.NotifyChannelTypeLark: case domain.NotifyChannelTypeLark:
return providerLark.New(&providerLark.LarkNotifierConfig{ return pLark.NewNotifier(&pLark.NotifierConfig{
WebhookUrl: maps.GetValueAsString(channelConfig, "webhookUrl"), WebhookUrl: maps.GetValueAsString(channelConfig, "webhookUrl"),
}) })
case domain.NotifyChannelTypeServerChan: case domain.NotifyChannelTypeServerChan:
return providerServerChan.New(&providerServerChan.ServerChanNotifierConfig{ return pServerChan.NewNotifier(&pServerChan.NotifierConfig{
Url: maps.GetValueAsString(channelConfig, "url"), Url: maps.GetValueAsString(channelConfig, "url"),
}) })
case domain.NotifyChannelTypeTelegram: case domain.NotifyChannelTypeTelegram:
return providerTelegram.New(&providerTelegram.TelegramNotifierConfig{ return pTelegram.NewNotifier(&pTelegram.NotifierConfig{
ApiToken: maps.GetValueAsString(channelConfig, "apiToken"), ApiToken: maps.GetValueAsString(channelConfig, "apiToken"),
ChatId: maps.GetValueAsInt64(channelConfig, "chatId"), ChatId: maps.GetValueAsInt64(channelConfig, "chatId"),
}) })
case domain.NotifyChannelTypeWebhook: case domain.NotifyChannelTypeWebhook:
return providerWebhook.New(&providerWebhook.WebhookNotifierConfig{ return pWebhook.NewNotifier(&pWebhook.NotifierConfig{
Url: maps.GetValueAsString(channelConfig, "url"), Url: maps.GetValueAsString(channelConfig, "url"),
}) })
case domain.NotifyChannelTypeWeCom: case domain.NotifyChannelTypeWeCom:
return providerWeCom.New(&providerWeCom.WeComNotifierConfig{ return pWeCom.NewNotifier(&pWeCom.NotifierConfig{
WebhookUrl: maps.GetValueAsString(channelConfig, "webhookUrl"), WebhookUrl: maps.GetValueAsString(channelConfig, "webhookUrl"),
}) })
} }

View File

@ -1,7 +1,6 @@
package acmehttpreq package acmehttpreq
import ( import (
"errors"
"net/url" "net/url"
"time" "time"
@ -9,7 +8,7 @@ import (
"github.com/go-acme/lego/v4/providers/dns/httpreq" "github.com/go-acme/lego/v4/providers/dns/httpreq"
) )
type ACMEHttpReqApplicantConfig struct { type ChallengeProviderConfig struct {
Endpoint string `json:"endpoint"` Endpoint string `json:"endpoint"`
Mode string `json:"mode"` Mode string `json:"mode"`
Username string `json:"username"` Username string `json:"username"`
@ -17,9 +16,9 @@ type ACMEHttpReqApplicantConfig struct {
DnsPropagationTimeout int32 `json:"dnsPropagationTimeout,omitempty"` DnsPropagationTimeout int32 `json:"dnsPropagationTimeout,omitempty"`
} }
func NewChallengeProvider(config *ACMEHttpReqApplicantConfig) (challenge.Provider, error) { func NewChallengeProvider(config *ChallengeProviderConfig) (challenge.Provider, error) {
if config == nil { if config == nil {
return nil, errors.New("config is nil") panic("config is nil")
} }
endpoint, _ := url.Parse(config.Endpoint) endpoint, _ := url.Parse(config.Endpoint)

View File

@ -1,23 +1,22 @@
package aliyun package aliyun
import ( import (
"errors"
"time" "time"
"github.com/go-acme/lego/v4/challenge" "github.com/go-acme/lego/v4/challenge"
"github.com/go-acme/lego/v4/providers/dns/alidns" "github.com/go-acme/lego/v4/providers/dns/alidns"
) )
type AliyunApplicantConfig struct { type ChallengeProviderConfig struct {
AccessKeyId string `json:"accessKeyId"` AccessKeyId string `json:"accessKeyId"`
AccessKeySecret string `json:"accessKeySecret"` AccessKeySecret string `json:"accessKeySecret"`
DnsPropagationTimeout int32 `json:"dnsPropagationTimeout,omitempty"` DnsPropagationTimeout int32 `json:"dnsPropagationTimeout,omitempty"`
DnsTTL int32 `json:"dnsTTL,omitempty"` DnsTTL int32 `json:"dnsTTL,omitempty"`
} }
func NewChallengeProvider(config *AliyunApplicantConfig) (challenge.Provider, error) { func NewChallengeProvider(config *ChallengeProviderConfig) (challenge.Provider, error) {
if config == nil { if config == nil {
return nil, errors.New("config is nil") panic("config is nil")
} }
providerConfig := alidns.NewDefaultConfig() providerConfig := alidns.NewDefaultConfig()

View File

@ -1,14 +1,13 @@
package awsroute53 package awsroute53
import ( import (
"errors"
"time" "time"
"github.com/go-acme/lego/v4/challenge" "github.com/go-acme/lego/v4/challenge"
"github.com/go-acme/lego/v4/providers/dns/route53" "github.com/go-acme/lego/v4/providers/dns/route53"
) )
type AWSRoute53ApplicantConfig struct { type ChallengeProviderConfig struct {
AccessKeyId string `json:"accessKeyId"` AccessKeyId string `json:"accessKeyId"`
SecretAccessKey string `json:"secretAccessKey"` SecretAccessKey string `json:"secretAccessKey"`
Region string `json:"region"` Region string `json:"region"`
@ -17,9 +16,9 @@ type AWSRoute53ApplicantConfig struct {
DnsTTL int32 `json:"dnsTTL,omitempty"` DnsTTL int32 `json:"dnsTTL,omitempty"`
} }
func NewChallengeProvider(config *AWSRoute53ApplicantConfig) (challenge.Provider, error) { func NewChallengeProvider(config *ChallengeProviderConfig) (challenge.Provider, error) {
if config == nil { if config == nil {
return nil, errors.New("config is nil") panic("config is nil")
} }
providerConfig := route53.NewDefaultConfig() providerConfig := route53.NewDefaultConfig()

View File

@ -1,7 +1,6 @@
package azuredns package azuredns
import ( import (
"errors"
"fmt" "fmt"
"strings" "strings"
"time" "time"
@ -11,7 +10,7 @@ import (
"github.com/go-acme/lego/v4/providers/dns/azuredns" "github.com/go-acme/lego/v4/providers/dns/azuredns"
) )
type AzureDNSApplicantConfig struct { type ChallengeProviderConfig struct {
TenantId string `json:"tenantId"` TenantId string `json:"tenantId"`
ClientId string `json:"clientId"` ClientId string `json:"clientId"`
ClientSecret string `json:"clientSecret"` ClientSecret string `json:"clientSecret"`
@ -20,9 +19,9 @@ type AzureDNSApplicantConfig struct {
DnsTTL int32 `json:"dnsTTL,omitempty"` DnsTTL int32 `json:"dnsTTL,omitempty"`
} }
func NewChallengeProvider(config *AzureDNSApplicantConfig) (challenge.Provider, error) { func NewChallengeProvider(config *ChallengeProviderConfig) (challenge.Provider, error) {
if config == nil { if config == nil {
return nil, errors.New("config is nil") panic("config is nil")
} }
providerConfig := azuredns.NewDefaultConfig() providerConfig := azuredns.NewDefaultConfig()

View File

@ -0,0 +1,39 @@
package baiducloud
import (
"time"
"github.com/go-acme/lego/v4/challenge"
internal "github.com/usual2970/certimate/internal/pkg/core/applicant/acme-dns-01/lego-providers/baiducloud/internal"
)
type ChallengeProviderConfig struct {
AccessKeyId string `json:"accessKeyId"`
SecretAccessKey string `json:"secretAccessKey"`
DnsPropagationTimeout int32 `json:"dnsPropagationTimeout,omitempty"`
DnsTTL int32 `json:"dnsTTL,omitempty"`
}
func NewChallengeProvider(config *ChallengeProviderConfig) (challenge.Provider, error) {
if config == nil {
panic("config is nil")
}
providerConfig := internal.NewDefaultConfig()
providerConfig.AccessKeyID = config.AccessKeyId
providerConfig.SecretAccessKey = config.SecretAccessKey
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 {
return nil, err
}
return provider, nil
}

View File

@ -0,0 +1,204 @@
package lego_baiducloud
import (
"errors"
"fmt"
"strings"
"time"
bceDns "github.com/baidubce/bce-sdk-go/services/dns"
"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/google/uuid"
)
const (
envNamespace = "BAIDUCLOUD_"
EnvAccessKeyID = envNamespace + "ACCESS_KEY_ID"
EnvSecretAccessKey = envNamespace + "SECRET_ACCESS_KEY"
EnvTTL = envNamespace + "TTL"
EnvPropagationTimeout = envNamespace + "PROPAGATION_TIMEOUT"
EnvPollingInterval = envNamespace + "POLLING_INTERVAL"
EnvHTTPTimeout = envNamespace + "HTTP_TIMEOUT"
)
var _ challenge.ProviderTimeout = (*DNSProvider)(nil)
type Config struct {
AccessKeyID string
SecretAccessKey string
PropagationTimeout time.Duration
PollingInterval time.Duration
TTL int32
HTTPTimeout time.Duration
}
type DNSProvider struct {
client *bceDns.Client
config *Config
}
func NewDefaultConfig() *Config {
return &Config{
TTL: int32(env.GetOrDefaultInt(EnvTTL, 300)),
PropagationTimeout: env.GetOrDefaultSecond(EnvPropagationTimeout, 2*time.Minute),
PollingInterval: env.GetOrDefaultSecond(EnvPollingInterval, dns01.DefaultPollingInterval),
HTTPTimeout: env.GetOrDefaultSecond(EnvHTTPTimeout, 30*time.Second),
}
}
func NewDNSProvider() (*DNSProvider, error) {
values, err := env.Get(EnvAccessKeyID, EnvSecretAccessKey)
if err != nil {
return nil, fmt.Errorf("baiducloud: %w", err)
}
config := NewDefaultConfig()
config.AccessKeyID = values[EnvAccessKeyID]
config.SecretAccessKey = values[EnvSecretAccessKey]
return NewDNSProviderConfig(config)
}
func NewDNSProviderConfig(config *Config) (*DNSProvider, error) {
if config == nil {
return nil, errors.New("baiducloud: the configuration of the DNS provider is nil")
}
client, err := bceDns.NewClient(config.AccessKeyID, config.SecretAccessKey, "")
if err != nil {
return nil, err
} else {
if client.Config != nil {
client.Config.ConnectionTimeoutInMillis = int(config.HTTPTimeout.Milliseconds())
}
}
return &DNSProvider{
client: client,
config: config,
}, nil
}
func (d *DNSProvider) Present(domain, token, keyAuth string) error {
info := dns01.GetChallengeInfo(domain, keyAuth)
authZone, err := dns01.FindZoneByFqdn(info.EffectiveFQDN)
if err != nil {
return fmt.Errorf("baiducloud: %w", err)
}
subDomain, err := dns01.ExtractSubDomain(info.EffectiveFQDN, authZone)
if err != nil {
return fmt.Errorf("baiducloud: %w", err)
}
if err := d.addOrUpdateDNSRecord(dns01.UnFqdn(authZone), subDomain, info.Value); err != nil {
return fmt.Errorf("baiducloud: %w", err)
}
return nil
}
func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error {
info := dns01.GetChallengeInfo(domain, keyAuth)
authZone, err := dns01.FindZoneByFqdn(info.EffectiveFQDN)
if err != nil {
return fmt.Errorf("baiducloud: %w", err)
}
subDomain, err := dns01.ExtractSubDomain(info.EffectiveFQDN, authZone)
if err != nil {
return fmt.Errorf("baiducloud: %w", err)
}
if err := d.removeDNSRecord(dns01.UnFqdn(authZone), subDomain); err != nil {
return fmt.Errorf("baiducloud: %w", err)
}
return nil
}
func (d *DNSProvider) Timeout() (timeout, interval time.Duration) {
return d.config.PropagationTimeout, d.config.PollingInterval
}
func (d *DNSProvider) getDNSRecord(zoneName, subDomain string) (*bceDns.Record, error) {
pageMarker := ""
pageSize := 1000
for {
request := &bceDns.ListRecordRequest{}
request.Rr = subDomain
request.Marker = pageMarker
request.MaxKeys = pageSize
response, err := d.client.ListRecord(zoneName, request)
if err != nil {
return nil, err
}
for _, record := range response.Records {
if record.Type == "TXT" && record.Rr == subDomain {
return &record, nil
}
}
if len(response.Records) < pageSize {
break
}
pageMarker = response.NextMarker
}
return nil, nil
}
func (d *DNSProvider) addOrUpdateDNSRecord(zoneName, subDomain, value string) error {
record, err := d.getDNSRecord(zoneName, subDomain)
if err != nil {
return err
}
if record == nil {
request := &bceDns.CreateRecordRequest{
Type: "TXT",
Rr: subDomain,
Value: value,
Ttl: &d.config.TTL,
}
err := d.client.CreateRecord(zoneName, request, d.generateClientToken())
return err
} else {
request := &bceDns.UpdateRecordRequest{
Type: "TXT",
Rr: subDomain,
Value: value,
Ttl: &d.config.TTL,
}
err := d.client.UpdateRecord(zoneName, record.Id, request, d.generateClientToken())
return err
}
}
func (d *DNSProvider) removeDNSRecord(zoneName, subDomain string) error {
record, err := d.getDNSRecord(zoneName, subDomain)
if err != nil {
return err
}
if record == nil {
return nil
} else {
err = d.client.DeleteRecord(zoneName, record.Id, d.generateClientToken())
return err
}
}
func (d *DNSProvider) generateClientToken() string {
return strings.ReplaceAll(uuid.New().String(), "-", "")
}

View File

@ -1,22 +1,21 @@
package cloudflare package cloudflare
import ( import (
"errors"
"time" "time"
"github.com/go-acme/lego/v4/challenge" "github.com/go-acme/lego/v4/challenge"
"github.com/go-acme/lego/v4/providers/dns/cloudflare" "github.com/go-acme/lego/v4/providers/dns/cloudflare"
) )
type CloudflareApplicantConfig struct { type ChallengeProviderConfig struct {
DnsApiToken string `json:"dnsApiToken"` DnsApiToken string `json:"dnsApiToken"`
DnsPropagationTimeout int32 `json:"dnsPropagationTimeout,omitempty"` DnsPropagationTimeout int32 `json:"dnsPropagationTimeout,omitempty"`
DnsTTL int32 `json:"dnsTTL,omitempty"` DnsTTL int32 `json:"dnsTTL,omitempty"`
} }
func NewChallengeProvider(config *CloudflareApplicantConfig) (challenge.Provider, error) { func NewChallengeProvider(config *ChallengeProviderConfig) (challenge.Provider, error) {
if config == nil { if config == nil {
return nil, errors.New("config is nil") panic("config is nil")
} }
providerConfig := cloudflare.NewDefaultConfig() providerConfig := cloudflare.NewDefaultConfig()

View File

@ -1,23 +1,22 @@
package cloudns package cloudns
import ( import (
"errors"
"time" "time"
"github.com/go-acme/lego/v4/challenge" "github.com/go-acme/lego/v4/challenge"
"github.com/go-acme/lego/v4/providers/dns/cloudns" "github.com/go-acme/lego/v4/providers/dns/cloudns"
) )
type ClouDNSApplicantConfig struct { type ChallengeProviderConfig struct {
AuthId string `json:"authId"` AuthId string `json:"authId"`
AuthPassword string `json:"authPassword"` AuthPassword string `json:"authPassword"`
DnsPropagationTimeout int32 `json:"dnsPropagationTimeout,omitempty"` DnsPropagationTimeout int32 `json:"dnsPropagationTimeout,omitempty"`
DnsTTL int32 `json:"dnsTTL,omitempty"` DnsTTL int32 `json:"dnsTTL,omitempty"`
} }
func NewChallengeProvider(config *ClouDNSApplicantConfig) (challenge.Provider, error) { func NewChallengeProvider(config *ChallengeProviderConfig) (challenge.Provider, error) {
if config == nil { if config == nil {
return nil, errors.New("config is nil") panic("config is nil")
} }
providerConfig := cloudns.NewDefaultConfig() providerConfig := cloudns.NewDefaultConfig()

View File

@ -0,0 +1,40 @@
package cmcccloud
import (
"errors"
"time"
"github.com/go-acme/lego/v4/challenge"
"github.com/usual2970/certimate/internal/pkg/core/applicant/acme-dns-01/lego-providers/cmcccloud/internal"
)
type ChallengeProviderConfig struct {
AccessKeyId string `json:"accessKeyId"`
AccessKeySecret string `json:"accessKeySecret"`
DnsPropagationTimeout int32 `json:"dnsPropagationTimeout,omitempty"`
DnsTTL int32 `json:"dnsTTL,omitempty"`
}
func NewChallengeProvider(config *ChallengeProviderConfig) (challenge.Provider, error) {
if config == nil {
return nil, errors.New("config is nil")
}
providerConfig := internal.NewDefaultConfig()
providerConfig.AccessKey = config.AccessKeyId
providerConfig.SecretKey = config.AccessKeySecret
if config.DnsTTL != 0 {
providerConfig.TTL = config.DnsTTL
}
if config.DnsPropagationTimeout != 0 {
providerConfig.PropagationTimeout = time.Duration(config.DnsPropagationTimeout) * time.Second
}
provider, err := internal.NewDNSProviderConfig(providerConfig)
if err != nil {
return nil, err
}
return provider, nil
}

View File

@ -0,0 +1,221 @@
package internal
import (
"encoding/json"
"errors"
"fmt"
"strings"
"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"
"gitlab.ecloud.com/ecloud/ecloudsdkclouddns"
"gitlab.ecloud.com/ecloud/ecloudsdkclouddns/model"
"gitlab.ecloud.com/ecloud/ecloudsdkcore/config"
)
const (
envNamespace = "CMCCCLOUD_"
EnvAccessKey = envNamespace + "ACCESS_KEY"
EnvSecretKey = envNamespace + "SECRET_KEY"
EnvTTL = envNamespace + "TTL"
EnvPropagationTimeout = envNamespace + "PROPAGATION_TIMEOUT"
EnvPollingInterval = envNamespace + "POLLING_INTERVAL"
EnvReadTimeOut = envNamespace + "READ_TIMEOUT"
EnvConnectTimeout = envNamespace + "CONNECT_TIMEOUT"
)
var _ challenge.ProviderTimeout = (*DNSProvider)(nil)
type Config struct {
AccessKey string
SecretKey string
ReadTimeOut int
ConnectTimeout int
PropagationTimeout time.Duration
PollingInterval time.Duration
TTL int32
}
type DNSProvider struct {
client *ecloudsdkclouddns.Client
config *Config
}
func NewDefaultConfig() *Config {
return &Config{
ReadTimeOut: env.GetOrDefaultInt(EnvReadTimeOut, 30),
ConnectTimeout: env.GetOrDefaultInt(EnvConnectTimeout, 30),
TTL: int32(env.GetOrDefaultInt(EnvTTL, 600)),
PropagationTimeout: env.GetOrDefaultSecond(EnvPropagationTimeout, 2*time.Minute),
PollingInterval: env.GetOrDefaultSecond(EnvPollingInterval, dns01.DefaultPollingInterval),
}
}
func NewDNSProvider() (*DNSProvider, error) {
values, err := env.Get(EnvAccessKey, EnvSecretKey)
if err != nil {
return nil, fmt.Errorf("cmccecloud: %w", err)
}
cfg := NewDefaultConfig()
cfg.AccessKey = values[EnvAccessKey]
cfg.SecretKey = values[EnvSecretKey]
return NewDNSProviderConfig(cfg)
}
func NewDNSProviderConfig(cfg *Config) (*DNSProvider, error) {
if cfg == nil {
return nil, errors.New("cmccecloud: the configuration of the DNS provider is nil")
}
client := ecloudsdkclouddns.NewClient(&config.Config{
AccessKey: cfg.AccessKey,
SecretKey: cfg.SecretKey,
// 资源池常量见: https://ecloud.10086.cn/op-help-center/doc/article/54462
// 默认全局
PoolId: "CIDC-CORE-00",
ReadTimeOut: cfg.ReadTimeOut,
ConnectTimeout: cfg.ConnectTimeout,
})
return &DNSProvider{
client: client,
config: cfg,
}, nil
}
func (d *DNSProvider) Present(domain, token, keyAuth string) error {
info := dns01.GetChallengeInfo(domain, keyAuth)
zoneName, err := dns01.FindZoneByFqdn(info.EffectiveFQDN)
if err != nil {
return fmt.Errorf("cmccecloud: %w", err)
}
subDomain, err := dns01.ExtractSubDomain(info.EffectiveFQDN, zoneName)
if err != nil {
return fmt.Errorf("cmccecloud: %w", err)
}
readDomain := strings.Trim(zoneName, ".")
record, err := d.getDomainRecord(readDomain, subDomain)
if err != nil {
return err
}
if record == nil {
// add new record
resp, err := d.client.CreateRecordOpenapi(&model.CreateRecordOpenapiRequest{
CreateRecordOpenapiBody: &model.CreateRecordOpenapiBody{
LineId: "0", // 默认线路
Rr: subDomain,
DomainName: readDomain,
Description: "from certimate",
Type: model.CreateRecordOpenapiBodyTypeEnumTxt,
Value: info.Value,
Ttl: &d.config.TTL,
},
})
if err != nil {
return fmt.Errorf("lego: %w", err)
}
if resp.State != model.CreateRecordOpenapiResponseStateEnumOk {
return fmt.Errorf("lego: create record failed, response state: %s, message: %s, code: %s", resp.State, resp.ErrorMessage, resp.ErrorCode)
}
return nil
} else {
// update record
resp, err := d.client.ModifyRecordOpenapi(&model.ModifyRecordOpenapiRequest{
ModifyRecordOpenapiBody: &model.ModifyRecordOpenapiBody{
RecordId: record.RecordId,
Rr: subDomain,
DomainName: readDomain,
Description: "from certmate",
LineId: "0",
Type: model.ModifyRecordOpenapiBodyTypeEnumTxt,
Value: info.Value,
Ttl: &d.config.TTL,
},
})
if err != nil {
return fmt.Errorf("lego: %w", err)
}
if resp.State != model.ModifyRecordOpenapiResponseStateEnumOk {
return fmt.Errorf("lego: create record failed, response state: %s", resp.State)
}
return nil
}
}
func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error {
challengeInfo := dns01.GetChallengeInfo(domain, keyAuth)
zoneName, err := dns01.FindZoneByFqdn(challengeInfo.FQDN)
if err != nil {
return fmt.Errorf("cmccecloud: %w", err)
}
subDomain, err := dns01.ExtractSubDomain(challengeInfo.FQDN, zoneName)
if err != nil {
return fmt.Errorf("cmccecloud: %w", err)
}
readDomain := strings.Trim(zoneName, ".")
record, err := d.getDomainRecord(readDomain, subDomain)
if err != nil {
return err
}
if record == nil {
return nil
}
resp, err := d.client.DeleteRecordOpenapi(&model.DeleteRecordOpenapiRequest{
DeleteRecordOpenapiBody: &model.DeleteRecordOpenapiBody{
RecordIdList: []string{record.RecordId},
},
})
if err != nil {
return fmt.Errorf("lego: %w", err)
}
if resp.State != model.DeleteRecordOpenapiResponseStateEnumOk {
return fmt.Errorf("lego: delete record failed, response state: %s", resp.State)
}
return nil
}
func (d *DNSProvider) Timeout() (timeout, interval time.Duration) {
return d.config.PropagationTimeout, d.config.PollingInterval
}
func (d *DNSProvider) getDomainRecord(domain string, rr string) (*model.ListRecordOpenapiResponseData, error) {
pageSize := int32(50)
page := int32(1)
for {
resp, err := d.client.ListRecordOpenapi(&model.ListRecordOpenapiRequest{
ListRecordOpenapiBody: &model.ListRecordOpenapiBody{
DomainName: domain,
},
ListRecordOpenapiQuery: &model.ListRecordOpenapiQuery{
PageSize: &pageSize,
Page: &page,
},
})
if err != nil {
return nil, err
}
if resp.State != model.ListRecordOpenapiResponseStateEnumOk {
respStr, _ := json.Marshal(resp)
return nil, fmt.Errorf("request error. %s", string(respStr))
}
if resp.Body.Data != nil {
for _, item := range *resp.Body.Data {
if item.Rr == rr {
return &item, nil
}
}
}
if resp.Body.TotalPages == nil || page >= *resp.Body.TotalPages {
return nil, nil
}
page++
}
}

View File

@ -0,0 +1,39 @@
package dnsla
import (
"time"
"github.com/go-acme/lego/v4/challenge"
internal "github.com/usual2970/certimate/internal/pkg/core/applicant/acme-dns-01/lego-providers/dnsla/internal"
)
type ChallengeProviderConfig struct {
ApiId string `json:"apiId"`
ApiSecret string `json:"apiSecret"`
DnsPropagationTimeout int32 `json:"dnsPropagationTimeout,omitempty"`
DnsTTL int32 `json:"dnsTTL,omitempty"`
}
func NewChallengeProvider(config *ChallengeProviderConfig) (challenge.Provider, error) {
if config == nil {
panic("config is nil")
}
providerConfig := internal.NewDefaultConfig()
providerConfig.APIId = config.ApiId
providerConfig.APISecret = config.ApiSecret
if config.DnsPropagationTimeout != 0 {
providerConfig.PropagationTimeout = time.Duration(config.DnsPropagationTimeout) * time.Second
}
if config.DnsTTL != 0 {
providerConfig.TTL = int(config.DnsTTL)
}
provider, err := internal.NewDNSProviderConfig(providerConfig)
if err != nil {
return nil, err
}
return provider, nil
}

View File

@ -0,0 +1,240 @@
package lego_dnsla
import (
"errors"
"fmt"
"strings"
"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"
dnslasdk "github.com/usual2970/certimate/internal/pkg/vendors/dnsla-sdk"
)
const (
envNamespace = "DNSLA_"
EnvAPIId = envNamespace + "API_ID"
EnvAPISecret = envNamespace + "API_KEY"
EnvTTL = envNamespace + "TTL"
EnvPropagationTimeout = envNamespace + "PROPAGATION_TIMEOUT"
EnvPollingInterval = envNamespace + "POLLING_INTERVAL"
EnvHTTPTimeout = envNamespace + "HTTP_TIMEOUT"
)
var _ challenge.ProviderTimeout = (*DNSProvider)(nil)
type Config struct {
APIId string
APISecret string
PropagationTimeout time.Duration
PollingInterval time.Duration
TTL int
HTTPTimeout time.Duration
}
type DNSProvider struct {
client *dnslasdk.Client
config *Config
}
func NewDefaultConfig() *Config {
return &Config{
TTL: env.GetOrDefaultInt(EnvTTL, 300),
PropagationTimeout: env.GetOrDefaultSecond(EnvPropagationTimeout, 2*time.Minute),
PollingInterval: env.GetOrDefaultSecond(EnvPollingInterval, dns01.DefaultPollingInterval),
HTTPTimeout: env.GetOrDefaultSecond(EnvHTTPTimeout, 30*time.Second),
}
}
func NewDNSProvider() (*DNSProvider, error) {
values, err := env.Get(EnvAPIId, EnvAPISecret)
if err != nil {
return nil, fmt.Errorf("dnsla: %w", err)
}
config := NewDefaultConfig()
config.APIId = values[EnvAPIId]
config.APISecret = values[EnvAPISecret]
return NewDNSProviderConfig(config)
}
func NewDNSProviderConfig(config *Config) (*DNSProvider, error) {
if config == nil {
return nil, errors.New("dnsla: the configuration of the DNS provider is nil")
}
client := dnslasdk.NewClient(config.APIId, config.APISecret).
WithTimeout(config.HTTPTimeout)
return &DNSProvider{
client: client,
config: config,
}, nil
}
func (d *DNSProvider) Present(domain, token, keyAuth string) error {
info := dns01.GetChallengeInfo(domain, keyAuth)
authZone, err := dns01.FindZoneByFqdn(info.EffectiveFQDN)
if err != nil {
return fmt.Errorf("dnsla: %w", err)
}
subDomain, err := dns01.ExtractSubDomain(info.EffectiveFQDN, authZone)
if err != nil {
return fmt.Errorf("dnsla: %w", err)
}
if err := d.addOrUpdateDNSRecord(dns01.UnFqdn(authZone), subDomain, info.Value); err != nil {
return fmt.Errorf("dnsla: %w", err)
}
return nil
}
func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error {
info := dns01.GetChallengeInfo(domain, keyAuth)
authZone, err := dns01.FindZoneByFqdn(info.EffectiveFQDN)
if err != nil {
return fmt.Errorf("dnsla: %w", err)
}
subDomain, err := dns01.ExtractSubDomain(info.EffectiveFQDN, authZone)
if err != nil {
return fmt.Errorf("dnsla: %w", err)
}
if err := d.removeDNSRecord(dns01.UnFqdn(authZone), subDomain); err != nil {
return fmt.Errorf("dnsla: %w", err)
}
return nil
}
func (d *DNSProvider) Timeout() (timeout, interval time.Duration) {
return d.config.PropagationTimeout, d.config.PollingInterval
}
func (d *DNSProvider) getDNSZone(zoneName string) (*dnslasdk.DomainInfo, error) {
pageIndex := 1
pageSize := 100
for {
request := &dnslasdk.ListDomainsRequest{
PageIndex: int32(pageIndex),
PageSize: int32(pageSize),
}
response, err := d.client.ListDomains(request)
if err != nil {
return nil, err
}
if response.Data != nil {
for _, item := range response.Data.Results {
if strings.TrimRight(item.Domain, ".") == zoneName || strings.TrimRight(item.DisplayDomain, ".") == zoneName {
return item, nil
}
}
}
if response.Data == nil || len(response.Data.Results) < pageSize {
break
}
pageIndex++
}
return nil, fmt.Errorf("dnsla: zone %s not found", zoneName)
}
func (d *DNSProvider) getDNSZoneAndRecord(zoneName, subDomain string) (*dnslasdk.DomainInfo, *dnslasdk.RecordInfo, error) {
zone, err := d.getDNSZone(zoneName)
if err != nil {
return nil, nil, err
}
pageIndex := 1
pageSize := 100
for {
request := &dnslasdk.ListRecordsRequest{
DomainId: zone.Id,
Host: &subDomain,
PageIndex: int32(pageIndex),
PageSize: int32(pageSize),
}
response, err := d.client.ListRecords(request)
if err != nil {
return zone, nil, err
}
if response.Data != nil {
for _, record := range response.Data.Results {
if record.Type == 16 && (record.Host == subDomain || record.DisplayHost == subDomain) {
return zone, record, nil
}
}
}
if response.Data == nil || len(response.Data.Results) < pageSize {
break
}
pageIndex++
}
return zone, nil, nil
}
func (d *DNSProvider) addOrUpdateDNSRecord(zoneName, subDomain, value string) error {
zone, record, err := d.getDNSZoneAndRecord(zoneName, subDomain)
if err != nil {
return err
}
if record == nil {
request := &dnslasdk.CreateRecordRequest{
DomainId: zone.Id,
Type: 16,
Host: subDomain,
Data: value,
Ttl: int32(d.config.TTL),
}
_, err := d.client.CreateRecord(request)
return err
} else {
reqType := int32(16)
reqTtl := int32(d.config.TTL)
request := &dnslasdk.UpdateRecordRequest{
Id: record.Id,
Type: &reqType,
Host: &subDomain,
Data: &value,
Ttl: &reqTtl,
}
_, err := d.client.UpdateRecord(request)
return err
}
}
func (d *DNSProvider) removeDNSRecord(zoneName, subDomain string) error {
_, record, err := d.getDNSZoneAndRecord(zoneName, subDomain)
if err != nil {
return err
}
if record == nil {
return nil
} else {
request := &dnslasdk.DeleteRecordRequest{
Id: record.Id,
}
_, err = d.client.DeleteRecord(request)
return err
}
}

View File

@ -0,0 +1,36 @@
package gcore
import (
"time"
"github.com/go-acme/lego/v4/challenge"
"github.com/go-acme/lego/v4/providers/dns/gcore"
)
type ChallengeProviderConfig struct {
ApiToken string `json:"apiToken"`
DnsPropagationTimeout int32 `json:"dnsPropagationTimeout,omitempty"`
DnsTTL int32 `json:"dnsTTL,omitempty"`
}
func NewChallengeProvider(config *ChallengeProviderConfig) (challenge.Provider, error) {
if config == nil {
panic("config is nil")
}
providerConfig := gcore.NewDefaultConfig()
providerConfig.APIToken = config.ApiToken
if config.DnsPropagationTimeout != 0 {
providerConfig.PropagationTimeout = time.Duration(config.DnsPropagationTimeout) * time.Second
}
if config.DnsTTL != 0 {
providerConfig.TTL = int(config.DnsTTL)
}
provider, err := gcore.NewDNSProviderConfig(providerConfig)
if err != nil {
return nil, err
}
return provider, nil
}

View File

@ -1,7 +1,6 @@
package gname package gname
import ( import (
"errors"
"time" "time"
"github.com/go-acme/lego/v4/challenge" "github.com/go-acme/lego/v4/challenge"
@ -9,16 +8,16 @@ import (
internal "github.com/usual2970/certimate/internal/pkg/core/applicant/acme-dns-01/lego-providers/gname/internal" internal "github.com/usual2970/certimate/internal/pkg/core/applicant/acme-dns-01/lego-providers/gname/internal"
) )
type GnameApplicantConfig struct { type ChallengeProviderConfig struct {
AppId string `json:"appId"` AppId string `json:"appId"`
AppKey string `json:"appKey"` AppKey string `json:"appKey"`
DnsPropagationTimeout int32 `json:"dnsPropagationTimeout,omitempty"` DnsPropagationTimeout int32 `json:"dnsPropagationTimeout,omitempty"`
DnsTTL int32 `json:"dnsTTL,omitempty"` DnsTTL int32 `json:"dnsTTL,omitempty"`
} }
func NewChallengeProvider(config *GnameApplicantConfig) (challenge.Provider, error) { func NewChallengeProvider(config *ChallengeProviderConfig) (challenge.Provider, error) {
if config == nil { if config == nil {
return nil, errors.New("config is nil") panic("config is nil")
} }
providerConfig := internal.NewDefaultConfig() providerConfig := internal.NewDefaultConfig()

View File

@ -37,13 +37,13 @@ type Config struct {
} }
type DNSProvider struct { type DNSProvider struct {
client *gnamesdk.GnameClient client *gnamesdk.Client
config *Config config *Config
} }
func NewDefaultConfig() *Config { func NewDefaultConfig() *Config {
return &Config{ return &Config{
TTL: env.GetOrDefaultInt(EnvTTL, dns01.DefaultTTL), TTL: env.GetOrDefaultInt(EnvTTL, 300),
PropagationTimeout: env.GetOrDefaultSecond(EnvPropagationTimeout, 2*time.Minute), PropagationTimeout: env.GetOrDefaultSecond(EnvPropagationTimeout, 2*time.Minute),
PollingInterval: env.GetOrDefaultSecond(EnvPollingInterval, dns01.DefaultPollingInterval), PollingInterval: env.GetOrDefaultSecond(EnvPollingInterval, dns01.DefaultPollingInterval),
HTTPTimeout: env.GetOrDefaultSecond(EnvHTTPTimeout, 30*time.Second), HTTPTimeout: env.GetOrDefaultSecond(EnvHTTPTimeout, 30*time.Second),
@ -68,7 +68,7 @@ func NewDNSProviderConfig(config *Config) (*DNSProvider, error) {
return nil, errors.New("gname: the configuration of the DNS provider is nil") return nil, errors.New("gname: the configuration of the DNS provider is nil")
} }
client := gnamesdk.NewGnameClient(config.AppID, config.AppKey). client := gnamesdk.NewClient(config.AppID, config.AppKey).
WithTimeout(config.HTTPTimeout) WithTimeout(config.HTTPTimeout)
return &DNSProvider{ return &DNSProvider{
@ -80,17 +80,17 @@ func NewDNSProviderConfig(config *Config) (*DNSProvider, error) {
func (d *DNSProvider) Present(domain, token, keyAuth string) error { func (d *DNSProvider) Present(domain, token, keyAuth string) error {
info := dns01.GetChallengeInfo(domain, keyAuth) info := dns01.GetChallengeInfo(domain, keyAuth)
zoneName, err := dns01.FindZoneByFqdn(info.EffectiveFQDN) authZone, err := dns01.FindZoneByFqdn(info.EffectiveFQDN)
if err != nil { if err != nil {
return fmt.Errorf("gname: %w", err) return fmt.Errorf("gname: %w", err)
} }
subDomain, err := dns01.ExtractSubDomain(info.EffectiveFQDN, zoneName) subDomain, err := dns01.ExtractSubDomain(info.EffectiveFQDN, authZone)
if err != nil { if err != nil {
return fmt.Errorf("gname: %w", err) return fmt.Errorf("gname: %w", err)
} }
if err := d.addOrUpdateDNSRecord(domain, subDomain, info.Value); err != nil { if err := d.addOrUpdateDNSRecord(dns01.UnFqdn(authZone), subDomain, info.Value); err != nil {
return fmt.Errorf("gname: %w", err) return fmt.Errorf("gname: %w", err)
} }
@ -98,10 +98,19 @@ func (d *DNSProvider) Present(domain, token, keyAuth string) error {
} }
func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error { func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error {
fqdn, value := dns01.GetRecord(domain, keyAuth) info := dns01.GetChallengeInfo(domain, keyAuth)
subDomain := dns01.UnFqdn(fqdn)
if err := d.removeDNSRecord(domain, subDomain, value); err != nil { authZone, err := dns01.FindZoneByFqdn(info.EffectiveFQDN)
if err != nil {
return fmt.Errorf("gname: %w", err)
}
subDomain, err := dns01.ExtractSubDomain(info.EffectiveFQDN, authZone)
if err != nil {
return fmt.Errorf("gname: %w", err)
}
if err := d.removeDNSRecord(dns01.UnFqdn(authZone), subDomain); err != nil {
return fmt.Errorf("gname: %w", err) return fmt.Errorf("gname: %w", err)
} }
@ -112,12 +121,12 @@ func (d *DNSProvider) Timeout() (timeout, interval time.Duration) {
return d.config.PropagationTimeout, d.config.PollingInterval return d.config.PropagationTimeout, d.config.PollingInterval
} }
func (d *DNSProvider) getDNSRecord(domain, subDomain string) (*gnamesdk.ResolutionRecord, error) { func (d *DNSProvider) getDNSRecord(zoneName, subDomain string) (*gnamesdk.ResolutionRecord, error) {
page := 1 page := 1
pageSize := 20 pageSize := 20
for { for {
request := &gnamesdk.ListDomainResolutionRequest{} request := &gnamesdk.ListDomainResolutionRequest{}
request.ZoneName = domain request.ZoneName = zoneName
request.Page = &page request.Page = &page
request.PageSize = &pageSize request.PageSize = &pageSize
@ -145,15 +154,15 @@ func (d *DNSProvider) getDNSRecord(domain, subDomain string) (*gnamesdk.Resoluti
return nil, nil return nil, nil
} }
func (d *DNSProvider) addOrUpdateDNSRecord(domain, subDomain, value string) error { func (d *DNSProvider) addOrUpdateDNSRecord(zoneName, subDomain, value string) error {
record, err := d.getDNSRecord(domain, subDomain) record, err := d.getDNSRecord(zoneName, subDomain)
if err != nil { if err != nil {
return err return err
} }
if record == nil { if record == nil {
request := &gnamesdk.AddDomainResolutionRequest{ request := &gnamesdk.AddDomainResolutionRequest{
ZoneName: domain, ZoneName: zoneName,
RecordType: "TXT", RecordType: "TXT",
RecordName: subDomain, RecordName: subDomain,
RecordValue: value, RecordValue: value,
@ -164,7 +173,7 @@ func (d *DNSProvider) addOrUpdateDNSRecord(domain, subDomain, value string) erro
} else { } else {
request := &gnamesdk.ModifyDomainResolutionRequest{ request := &gnamesdk.ModifyDomainResolutionRequest{
ID: record.ID, ID: record.ID,
ZoneName: domain, ZoneName: zoneName,
RecordType: "TXT", RecordType: "TXT",
RecordName: subDomain, RecordName: subDomain,
RecordValue: value, RecordValue: value,
@ -175,8 +184,8 @@ func (d *DNSProvider) addOrUpdateDNSRecord(domain, subDomain, value string) erro
} }
} }
func (d *DNSProvider) removeDNSRecord(domain, subDomain, value string) error { func (d *DNSProvider) removeDNSRecord(zoneName, subDomain string) error {
record, err := d.getDNSRecord(domain, subDomain) record, err := d.getDNSRecord(zoneName, subDomain)
if err != nil { if err != nil {
return err return err
} }
@ -186,7 +195,7 @@ func (d *DNSProvider) removeDNSRecord(domain, subDomain, value string) error {
} }
request := &gnamesdk.DeleteDomainResolutionRequest{ request := &gnamesdk.DeleteDomainResolutionRequest{
ZoneName: domain, ZoneName: zoneName,
RecordID: record.ID, RecordID: record.ID,
} }
_, err = d.client.DeleteDomainResolution(request) _, err = d.client.DeleteDomainResolution(request)

View File

@ -1,23 +1,22 @@
package godaddy package godaddy
import ( import (
"errors"
"time" "time"
"github.com/go-acme/lego/v4/challenge" "github.com/go-acme/lego/v4/challenge"
"github.com/go-acme/lego/v4/providers/dns/godaddy" "github.com/go-acme/lego/v4/providers/dns/godaddy"
) )
type GoDaddyApplicantConfig struct { type ChallengeProviderConfig struct {
ApiKey string `json:"apiKey"` ApiKey string `json:"apiKey"`
ApiSecret string `json:"apiSecret"` ApiSecret string `json:"apiSecret"`
DnsPropagationTimeout int32 `json:"dnsPropagationTimeout,omitempty"` DnsPropagationTimeout int32 `json:"dnsPropagationTimeout,omitempty"`
DnsTTL int32 `json:"dnsTTL,omitempty"` DnsTTL int32 `json:"dnsTTL,omitempty"`
} }
func NewChallengeProvider(config *GoDaddyApplicantConfig) (challenge.Provider, error) { func NewChallengeProvider(config *ChallengeProviderConfig) (challenge.Provider, error) {
if config == nil { if config == nil {
return nil, errors.New("config is nil") panic("config is nil")
} }
providerConfig := godaddy.NewDefaultConfig() providerConfig := godaddy.NewDefaultConfig()

View File

@ -1,14 +1,13 @@
package huaweicloud package huaweicloud
import ( import (
"errors"
"time" "time"
"github.com/go-acme/lego/v4/challenge" "github.com/go-acme/lego/v4/challenge"
hwc "github.com/go-acme/lego/v4/providers/dns/huaweicloud" hwc "github.com/go-acme/lego/v4/providers/dns/huaweicloud"
) )
type HuaweiCloudApplicantConfig struct { type ChallengeProviderConfig struct {
AccessKeyId string `json:"accessKeyId"` AccessKeyId string `json:"accessKeyId"`
SecretAccessKey string `json:"secretAccessKey"` SecretAccessKey string `json:"secretAccessKey"`
Region string `json:"region"` Region string `json:"region"`
@ -16,9 +15,9 @@ type HuaweiCloudApplicantConfig struct {
DnsTTL int32 `json:"dnsTTL,omitempty"` DnsTTL int32 `json:"dnsTTL,omitempty"`
} }
func NewChallengeProvider(config *HuaweiCloudApplicantConfig) (challenge.Provider, error) { func NewChallengeProvider(config *ChallengeProviderConfig) (challenge.Provider, error) {
if config == nil { if config == nil {
return nil, errors.New("config is nil") panic("config is nil")
} }
region := config.Region region := config.Region

View File

@ -0,0 +1,238 @@
package lego_jdcloud
import (
"errors"
"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"
jdCore "github.com/jdcloud-api/jdcloud-sdk-go/core"
jdDnsApi "github.com/jdcloud-api/jdcloud-sdk-go/services/domainservice/apis"
jdDnsClient "github.com/jdcloud-api/jdcloud-sdk-go/services/domainservice/client"
jdDnsModel "github.com/jdcloud-api/jdcloud-sdk-go/services/domainservice/models"
)
const (
envNamespace = "JDCLOUD_"
EnvAccessKeyID = envNamespace + "ACCESS_KEY_ID"
EnvAccessKeySecret = envNamespace + "ACCESS_KEY_SECRET"
EnvRegionId = envNamespace + "REGION_ID"
EnvTTL = envNamespace + "TTL"
EnvPropagationTimeout = envNamespace + "PROPAGATION_TIMEOUT"
EnvPollingInterval = envNamespace + "POLLING_INTERVAL"
EnvHTTPTimeout = envNamespace + "HTTP_TIMEOUT"
)
var _ challenge.ProviderTimeout = (*DNSProvider)(nil)
type Config struct {
AccessKeyID string
AccessKeySecret string
RegionId string
PropagationTimeout time.Duration
PollingInterval time.Duration
TTL int32
HTTPTimeout time.Duration
}
type DNSProvider struct {
client *jdDnsClient.DomainserviceClient
config *Config
}
func NewDefaultConfig() *Config {
return &Config{
TTL: int32(env.GetOrDefaultInt(EnvTTL, 300)),
PropagationTimeout: env.GetOrDefaultSecond(EnvPropagationTimeout, 2*time.Minute),
PollingInterval: env.GetOrDefaultSecond(EnvPollingInterval, dns01.DefaultPollingInterval),
HTTPTimeout: env.GetOrDefaultSecond(EnvHTTPTimeout, 30*time.Second),
}
}
func NewDNSProvider() (*DNSProvider, error) {
values, err := env.Get(EnvAccessKeyID, EnvAccessKeySecret)
if err != nil {
return nil, fmt.Errorf("jdcloud: %w", err)
}
config := NewDefaultConfig()
config.AccessKeyID = values[EnvAccessKeyID]
config.AccessKeySecret = values[EnvAccessKeySecret]
config.RegionId = values[EnvRegionId]
return NewDNSProviderConfig(config)
}
func NewDNSProviderConfig(config *Config) (*DNSProvider, error) {
if config == nil {
return nil, errors.New("jdcloud: the configuration of the DNS provider is nil")
}
clientCredentials := jdCore.NewCredentials(config.AccessKeyID, config.AccessKeySecret)
client := jdDnsClient.NewDomainserviceClient(clientCredentials)
clientConfig := &client.Config
clientConfig.SetTimeout(config.HTTPTimeout)
client.SetConfig(clientConfig)
client.SetLogger(jdCore.NewDefaultLogger(jdCore.LogWarn))
return &DNSProvider{
client: client,
config: config,
}, nil
}
func (d *DNSProvider) Present(domain, token, keyAuth string) error {
info := dns01.GetChallengeInfo(domain, keyAuth)
authZone, err := dns01.FindZoneByFqdn(info.EffectiveFQDN)
if err != nil {
return fmt.Errorf("jdcloud: %w", err)
}
subDomain, err := dns01.ExtractSubDomain(info.EffectiveFQDN, authZone)
if err != nil {
return fmt.Errorf("jdcloud: %w", err)
}
if err := d.addOrUpdateDNSRecord(dns01.UnFqdn(authZone), subDomain, info.Value); err != nil {
return fmt.Errorf("jdcloud: %w", err)
}
return nil
}
func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error {
info := dns01.GetChallengeInfo(domain, keyAuth)
authZone, err := dns01.FindZoneByFqdn(info.EffectiveFQDN)
if err != nil {
return fmt.Errorf("jdcloud: %w", err)
}
subDomain, err := dns01.ExtractSubDomain(info.EffectiveFQDN, authZone)
if err != nil {
return fmt.Errorf("jdcloud: %w", err)
}
if err := d.removeDNSRecord(dns01.UnFqdn(authZone), subDomain); err != nil {
return fmt.Errorf("jdcloud: %w", err)
}
return nil
}
func (d *DNSProvider) Timeout() (timeout, interval time.Duration) {
return d.config.PropagationTimeout, d.config.PollingInterval
}
func (d *DNSProvider) getDNSZone(zoneName string) (*jdDnsModel.DomainInfo, error) {
pageNumber := 1
pageSize := 10
for {
request := jdDnsApi.NewDescribeDomainsRequest(d.config.RegionId, pageNumber, pageSize)
request.SetDomainName(zoneName)
response, err := d.client.DescribeDomains(request)
if err != nil {
return nil, err
}
for _, item := range response.Result.DataList {
if item.DomainName == zoneName {
return &item, nil
}
}
if len(response.Result.DataList) < pageSize {
break
}
pageNumber++
}
return nil, fmt.Errorf("jdcloud: zone %s not found", zoneName)
}
func (d *DNSProvider) getDNSZoneAndRecord(zoneName, subDomain string) (*jdDnsModel.DomainInfo, *jdDnsModel.RRInfo, error) {
zone, err := d.getDNSZone(zoneName)
if err != nil {
return nil, nil, err
}
pageNumber := 1
pageSize := 10
for {
request := jdDnsApi.NewDescribeResourceRecordRequest(d.config.RegionId, fmt.Sprintf("%d", zone.Id))
request.SetSearch(subDomain)
request.SetPageNumber(pageNumber)
request.SetPageSize(pageSize)
response, err := d.client.DescribeResourceRecord(request)
if err != nil {
return zone, nil, err
}
for _, record := range response.Result.DataList {
if record.Type == "TXT" && record.HostRecord == subDomain {
return zone, &record, nil
}
}
if len(response.Result.DataList) < pageSize {
break
}
pageNumber++
}
return zone, nil, nil
}
func (d *DNSProvider) addOrUpdateDNSRecord(zoneName, subDomain, value string) error {
zone, record, err := d.getDNSZoneAndRecord(zoneName, subDomain)
if err != nil {
return err
}
if record == nil {
request := jdDnsApi.NewCreateResourceRecordRequest(d.config.RegionId, fmt.Sprintf("%d", zone.Id), &jdDnsModel.AddRR{
Type: "TXT",
HostRecord: subDomain,
HostValue: value,
Ttl: int(d.config.TTL),
ViewValue: -1,
})
_, err := d.client.CreateResourceRecord(request)
return err
} else {
request := jdDnsApi.NewModifyResourceRecordRequest(d.config.RegionId, fmt.Sprintf("%d", zone.Id), fmt.Sprintf("%d", record.Id), &jdDnsModel.UpdateRR{
Type: "TXT",
HostRecord: subDomain,
HostValue: value,
Ttl: int(d.config.TTL),
ViewValue: -1,
})
_, err := d.client.ModifyResourceRecord(request)
return err
}
}
func (d *DNSProvider) removeDNSRecord(zoneName, subDomain string) error {
zone, record, err := d.getDNSZoneAndRecord(zoneName, subDomain)
if err != nil {
return err
}
if record == nil {
return nil
} else {
request := jdDnsApi.NewDeleteResourceRecordRequest(d.config.RegionId, fmt.Sprintf("%d", zone.Id), fmt.Sprintf("%d", record.Id))
_, err = d.client.DeleteResourceRecord(request)
return err
}
}

View File

@ -0,0 +1,47 @@
package jdcloud
import (
"time"
"github.com/go-acme/lego/v4/challenge"
internal "github.com/usual2970/certimate/internal/pkg/core/applicant/acme-dns-01/lego-providers/jdcloud/internal"
)
type ChallengeProviderConfig struct {
AccessKeyId string `json:"accessKeyId"`
AccessKeySecret string `json:"accessKeySecret"`
RegionId string `json:"regionId"`
DnsPropagationTimeout int32 `json:"dnsPropagationTimeout,omitempty"`
DnsTTL int32 `json:"dnsTTL,omitempty"`
}
func NewChallengeProvider(config *ChallengeProviderConfig) (challenge.Provider, error) {
if config == nil {
panic("config is nil")
}
regionId := config.RegionId
if regionId == "" {
// 京东云的 SDK 要求必须传一个区域,实际上 DNS-01 流程里用不到,但不传会报错
regionId = "cn-north-1"
}
providerConfig := internal.NewDefaultConfig()
providerConfig.AccessKeyID = config.AccessKeyId
providerConfig.AccessKeySecret = config.AccessKeySecret
providerConfig.RegionId = regionId
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 {
return nil, err
}
return provider, nil
}

View File

@ -0,0 +1,38 @@
package namedotcom
import (
"time"
"github.com/go-acme/lego/v4/challenge"
"github.com/go-acme/lego/v4/providers/dns/namecheap"
)
type ChallengeProviderConfig struct {
Username string `json:"username"`
ApiKey string `json:"apiKey"`
DnsPropagationTimeout int32 `json:"dnsPropagationTimeout,omitempty"`
DnsTTL int32 `json:"dnsTTL,omitempty"`
}
func NewChallengeProvider(config *ChallengeProviderConfig) (challenge.Provider, error) {
if config == nil {
panic("config is nil")
}
providerConfig := namecheap.NewDefaultConfig()
providerConfig.APIUser = config.Username
providerConfig.APIKey = config.ApiKey
if config.DnsPropagationTimeout != 0 {
providerConfig.PropagationTimeout = time.Duration(config.DnsPropagationTimeout) * time.Second
}
if config.DnsTTL != 0 {
providerConfig.TTL = int(config.DnsTTL)
}
provider, err := namecheap.NewDNSProviderConfig(providerConfig)
if err != nil {
return nil, err
}
return provider, nil
}

View File

@ -1,23 +1,22 @@
package namedotcom package namedotcom
import ( import (
"errors"
"time" "time"
"github.com/go-acme/lego/v4/challenge" "github.com/go-acme/lego/v4/challenge"
"github.com/go-acme/lego/v4/providers/dns/namedotcom" "github.com/go-acme/lego/v4/providers/dns/namedotcom"
) )
type NameDotComApplicantConfig struct { type ChallengeProviderConfig struct {
Username string `json:"username"` Username string `json:"username"`
ApiToken string `json:"apiToken"` ApiToken string `json:"apiToken"`
DnsPropagationTimeout int32 `json:"dnsPropagationTimeout,omitempty"` DnsPropagationTimeout int32 `json:"dnsPropagationTimeout,omitempty"`
DnsTTL int32 `json:"dnsTTL,omitempty"` DnsTTL int32 `json:"dnsTTL,omitempty"`
} }
func NewChallengeProvider(config *NameDotComApplicantConfig) (challenge.Provider, error) { func NewChallengeProvider(config *ChallengeProviderConfig) (challenge.Provider, error) {
if config == nil { if config == nil {
return nil, errors.New("config is nil") panic("config is nil")
} }
providerConfig := namedotcom.NewDefaultConfig() providerConfig := namedotcom.NewDefaultConfig()

View File

@ -1,22 +1,21 @@
package namesilo package namesilo
import ( import (
"errors"
"time" "time"
"github.com/go-acme/lego/v4/challenge" "github.com/go-acme/lego/v4/challenge"
"github.com/go-acme/lego/v4/providers/dns/namesilo" "github.com/go-acme/lego/v4/providers/dns/namesilo"
) )
type NameSiloApplicantConfig struct { type ChallengeProviderConfig struct {
ApiKey string `json:"apiKey"` ApiKey string `json:"apiKey"`
DnsPropagationTimeout int32 `json:"dnsPropagationTimeout,omitempty"` DnsPropagationTimeout int32 `json:"dnsPropagationTimeout,omitempty"`
DnsTTL int32 `json:"dnsTTL,omitempty"` DnsTTL int32 `json:"dnsTTL,omitempty"`
} }
func NewChallengeProvider(config *NameSiloApplicantConfig) (challenge.Provider, error) { func NewChallengeProvider(config *ChallengeProviderConfig) (challenge.Provider, error) {
if config == nil { if config == nil {
return nil, errors.New("config is nil") panic("config is nil")
} }
providerConfig := namesilo.NewDefaultConfig() providerConfig := namesilo.NewDefaultConfig()

View File

@ -1,22 +1,21 @@
package ns1 package ns1
import ( import (
"errors"
"time" "time"
"github.com/go-acme/lego/v4/challenge" "github.com/go-acme/lego/v4/challenge"
"github.com/go-acme/lego/v4/providers/dns/ns1" "github.com/go-acme/lego/v4/providers/dns/ns1"
) )
type NS1ApplicantConfig struct { type ChallengeProviderConfig struct {
ApiKey string `json:"apiKey"` ApiKey string `json:"apiKey"`
DnsPropagationTimeout int32 `json:"dnsPropagationTimeout,omitempty"` DnsPropagationTimeout int32 `json:"dnsPropagationTimeout,omitempty"`
DnsTTL int32 `json:"dnsTTL,omitempty"` DnsTTL int32 `json:"dnsTTL,omitempty"`
} }
func NewChallengeProvider(config *NS1ApplicantConfig) (challenge.Provider, error) { func NewChallengeProvider(config *ChallengeProviderConfig) (challenge.Provider, error) {
if config == nil { if config == nil {
return nil, errors.New("config is nil") panic("config is nil")
} }
providerConfig := ns1.NewDefaultConfig() providerConfig := ns1.NewDefaultConfig()

View File

@ -1,7 +1,6 @@
package namesilo package namesilo
import ( import (
"errors"
"net/url" "net/url"
"time" "time"
@ -9,16 +8,16 @@ import (
"github.com/go-acme/lego/v4/providers/dns/pdns" "github.com/go-acme/lego/v4/providers/dns/pdns"
) )
type PowerDNSApplicantConfig struct { type ChallengeProviderConfig struct {
ApiUrl string `json:"apiUrl"` ApiUrl string `json:"apiUrl"`
ApiKey string `json:"apiKey"` ApiKey string `json:"apiKey"`
DnsPropagationTimeout int32 `json:"dnsPropagationTimeout,omitempty"` DnsPropagationTimeout int32 `json:"dnsPropagationTimeout,omitempty"`
DnsTTL int32 `json:"dnsTTL,omitempty"` DnsTTL int32 `json:"dnsTTL,omitempty"`
} }
func NewChallengeProvider(config *PowerDNSApplicantConfig) (challenge.Provider, error) { func NewChallengeProvider(config *ChallengeProviderConfig) (challenge.Provider, error) {
if config == nil { if config == nil {
return nil, errors.New("config is nil") panic("config is nil")
} }
host, _ := url.Parse(config.ApiUrl) host, _ := url.Parse(config.ApiUrl)

View File

@ -1,22 +1,21 @@
package rainyun package rainyun
import ( import (
"errors"
"time" "time"
"github.com/go-acme/lego/v4/challenge" "github.com/go-acme/lego/v4/challenge"
"github.com/go-acme/lego/v4/providers/dns/rainyun" "github.com/go-acme/lego/v4/providers/dns/rainyun"
) )
type RainYunApplicantConfig struct { type ChallengeProviderConfig struct {
ApiKey string `json:"apiKey"` ApiKey string `json:"apiKey"`
DnsPropagationTimeout int32 `json:"dnsPropagationTimeout,omitempty"` DnsPropagationTimeout int32 `json:"dnsPropagationTimeout,omitempty"`
DnsTTL int32 `json:"dnsTTL,omitempty"` DnsTTL int32 `json:"dnsTTL,omitempty"`
} }
func NewChallengeProvider(config *RainYunApplicantConfig) (challenge.Provider, error) { func NewChallengeProvider(config *ChallengeProviderConfig) (challenge.Provider, error) {
if config == nil { if config == nil {
return nil, errors.New("config is nil") panic("config is nil")
} }
providerConfig := rainyun.NewDefaultConfig() providerConfig := rainyun.NewDefaultConfig()

View File

@ -1,23 +1,22 @@
package tencentcloud package tencentcloud
import ( import (
"errors"
"time" "time"
"github.com/go-acme/lego/v4/challenge" "github.com/go-acme/lego/v4/challenge"
"github.com/go-acme/lego/v4/providers/dns/tencentcloud" "github.com/go-acme/lego/v4/providers/dns/tencentcloud"
) )
type TencentCloudApplicantConfig struct { type ChallengeProviderConfig struct {
SecretId string `json:"secretId"` SecretId string `json:"secretId"`
SecretKey string `json:"secretKey"` SecretKey string `json:"secretKey"`
DnsPropagationTimeout int32 `json:"dnsPropagationTimeout,omitempty"` DnsPropagationTimeout int32 `json:"dnsPropagationTimeout,omitempty"`
DnsTTL int32 `json:"dnsTTL,omitempty"` DnsTTL int32 `json:"dnsTTL,omitempty"`
} }
func NewChallengeProvider(config *TencentCloudApplicantConfig) (challenge.Provider, error) { func NewChallengeProvider(config *ChallengeProviderConfig) (challenge.Provider, error) {
if config == nil { if config == nil {
return nil, errors.New("config is nil") panic("config is nil")
} }
providerConfig := tencentcloud.NewDefaultConfig() providerConfig := tencentcloud.NewDefaultConfig()

View File

@ -1,23 +1,22 @@
package volcengine package volcengine
import ( import (
"errors"
"time" "time"
"github.com/go-acme/lego/v4/challenge" "github.com/go-acme/lego/v4/challenge"
"github.com/go-acme/lego/v4/providers/dns/volcengine" "github.com/go-acme/lego/v4/providers/dns/volcengine"
) )
type VolcEngineApplicantConfig struct { type ChallengeProviderConfig struct {
AccessKeyId string `json:"accessKeyId"` AccessKeyId string `json:"accessKeyId"`
SecretAccessKey string `json:"secretAccessKey"` SecretAccessKey string `json:"secretAccessKey"`
DnsPropagationTimeout int32 `json:"dnsPropagationTimeout,omitempty"` DnsPropagationTimeout int32 `json:"dnsPropagationTimeout,omitempty"`
DnsTTL int32 `json:"dnsTTL,omitempty"` DnsTTL int32 `json:"dnsTTL,omitempty"`
} }
func NewChallengeProvider(config *VolcEngineApplicantConfig) (challenge.Provider, error) { func NewChallengeProvider(config *ChallengeProviderConfig) (challenge.Provider, error) {
if config == nil { if config == nil {
return nil, errors.New("config is nil") panic("config is nil")
} }
providerConfig := volcengine.NewDefaultConfig() providerConfig := volcengine.NewDefaultConfig()

View File

@ -1,23 +1,22 @@
package westcn package westcn
import ( import (
"errors"
"time" "time"
"github.com/go-acme/lego/v4/challenge" "github.com/go-acme/lego/v4/challenge"
"github.com/go-acme/lego/v4/providers/dns/westcn" "github.com/go-acme/lego/v4/providers/dns/westcn"
) )
type WestcnApplicantConfig struct { type ChallengeProviderConfig struct {
Username string `json:"username"` Username string `json:"username"`
ApiPassword string `json:"apiPassword"` ApiPassword string `json:"apiPassword"`
DnsPropagationTimeout int32 `json:"dnsPropagationTimeout,omitempty"` DnsPropagationTimeout int32 `json:"dnsPropagationTimeout,omitempty"`
DnsTTL int32 `json:"dnsTTL,omitempty"` DnsTTL int32 `json:"dnsTTL,omitempty"`
} }
func NewChallengeProvider(config *WestcnApplicantConfig) (challenge.Provider, error) { func NewChallengeProvider(config *ChallengeProviderConfig) (challenge.Provider, error) {
if config == nil { if config == nil {
return nil, errors.New("config is nil") panic("config is nil")
} }
providerConfig := westcn.NewDefaultConfig() providerConfig := westcn.NewDefaultConfig()

View File

@ -18,10 +18,10 @@ import (
"github.com/usual2970/certimate/internal/pkg/core/deployer" "github.com/usual2970/certimate/internal/pkg/core/deployer"
"github.com/usual2970/certimate/internal/pkg/core/logger" "github.com/usual2970/certimate/internal/pkg/core/logger"
"github.com/usual2970/certimate/internal/pkg/core/uploader" "github.com/usual2970/certimate/internal/pkg/core/uploader"
uploaderp "github.com/usual2970/certimate/internal/pkg/core/uploader/providers/aliyun-cas" uploadersp "github.com/usual2970/certimate/internal/pkg/core/uploader/providers/aliyun-cas"
) )
type AliyunALBDeployerConfig struct { type DeployerConfig struct {
// 阿里云 AccessKeyId。 // 阿里云 AccessKeyId。
AccessKeyId string `json:"accessKeyId"` AccessKeyId string `json:"accessKeyId"`
// 阿里云 AccessKeySecret。 // 阿里云 AccessKeySecret。
@ -29,43 +29,35 @@ type AliyunALBDeployerConfig struct {
// 阿里云地域。 // 阿里云地域。
Region string `json:"region"` Region string `json:"region"`
// 部署资源类型。 // 部署资源类型。
ResourceType DeployResourceType `json:"resourceType"` ResourceType ResourceType `json:"resourceType"`
// 负载均衡实例 ID。 // 负载均衡实例 ID。
// 部署资源类型为 [DEPLOY_RESOURCE_LOADBALANCER] 时必填。 // 部署资源类型为 [RESOURCE_TYPE_LOADBALANCER] 时必填。
LoadbalancerId string `json:"loadbalancerId,omitempty"` LoadbalancerId string `json:"loadbalancerId,omitempty"`
// 负载均衡监听 ID。 // 负载均衡监听 ID。
// 部署资源类型为 [DEPLOY_RESOURCE_LISTENER] 时必填。 // 部署资源类型为 [RESOURCE_TYPE_LISTENER] 时必填。
ListenerId string `json:"listenerId,omitempty"` ListenerId string `json:"listenerId,omitempty"`
// SNI 域名(支持泛域名)。 // SNI 域名(支持泛域名)。
// 部署资源类型为 [DEPLOY_RESOURCE_LOADBALANCER]、[DEPLOY_RESOURCE_LISTENER] 时选填。 // 部署资源类型为 [RESOURCE_TYPE_LOADBALANCER]、[RESOURCE_TYPE_LISTENER] 时选填。
Domain string `json:"domain,omitempty"` Domain string `json:"domain,omitempty"`
} }
type AliyunALBDeployer struct { type DeployerProvider struct {
config *AliyunALBDeployerConfig config *DeployerConfig
logger logger.Logger logger logger.Logger
sdkClients *wSdkClients sdkClients *wSdkClients
sslUploader uploader.Uploader sslUploader uploader.Uploader
} }
var _ deployer.Deployer = (*AliyunALBDeployer)(nil) var _ deployer.Deployer = (*DeployerProvider)(nil)
type wSdkClients struct { type wSdkClients struct {
alb *aliyunAlb.Client alb *aliyunAlb.Client
cas *aliyunCas.Client cas *aliyunCas.Client
} }
func New(config *AliyunALBDeployerConfig) (*AliyunALBDeployer, error) { func NewDeployer(config *DeployerConfig) (*DeployerProvider, error) {
return NewWithLogger(config, logger.NewNilLogger())
}
func NewWithLogger(config *AliyunALBDeployerConfig, logger logger.Logger) (*AliyunALBDeployer, error) {
if config == nil { if config == nil {
return nil, errors.New("config is nil") panic("config is nil")
}
if logger == nil {
return nil, errors.New("logger is nil")
} }
clients, err := createSdkClients(config.AccessKeyId, config.AccessKeySecret, config.Region) clients, err := createSdkClients(config.AccessKeyId, config.AccessKeySecret, config.Region)
@ -78,15 +70,20 @@ func NewWithLogger(config *AliyunALBDeployerConfig, logger logger.Logger) (*Aliy
return nil, xerrors.Wrap(err, "failed to create ssl uploader") return nil, xerrors.Wrap(err, "failed to create ssl uploader")
} }
return &AliyunALBDeployer{ return &DeployerProvider{
logger: logger,
config: config, config: config,
logger: logger.NewNilLogger(),
sdkClients: clients, sdkClients: clients,
sslUploader: uploader, sslUploader: uploader,
}, nil }, nil
} }
func (d *AliyunALBDeployer) Deploy(ctx context.Context, certPem string, privkeyPem string) (*deployer.DeployResult, error) { func (d *DeployerProvider) WithLogger(logger logger.Logger) *DeployerProvider {
d.logger = logger
return d
}
func (d *DeployerProvider) Deploy(ctx context.Context, certPem string, privkeyPem string) (*deployer.DeployResult, error) {
// 上传证书到 CAS // 上传证书到 CAS
upres, err := d.sslUploader.Upload(ctx, certPem, privkeyPem) upres, err := d.sslUploader.Upload(ctx, certPem, privkeyPem)
if err != nil { if err != nil {
@ -97,12 +94,12 @@ func (d *AliyunALBDeployer) Deploy(ctx context.Context, certPem string, privkeyP
// 根据部署资源类型决定部署方式 // 根据部署资源类型决定部署方式
switch d.config.ResourceType { switch d.config.ResourceType {
case DEPLOY_RESOURCE_LOADBALANCER: case RESOURCE_TYPE_LOADBALANCER:
if err := d.deployToLoadbalancer(ctx, upres.CertId); err != nil { if err := d.deployToLoadbalancer(ctx, upres.CertId); err != nil {
return nil, err return nil, err
} }
case DEPLOY_RESOURCE_LISTENER: case RESOURCE_TYPE_LISTENER:
if err := d.deployToListener(ctx, upres.CertId); err != nil { if err := d.deployToListener(ctx, upres.CertId); err != nil {
return nil, err return nil, err
} }
@ -114,7 +111,7 @@ func (d *AliyunALBDeployer) Deploy(ctx context.Context, certPem string, privkeyP
return &deployer.DeployResult{}, nil return &deployer.DeployResult{}, nil
} }
func (d *AliyunALBDeployer) deployToLoadbalancer(ctx context.Context, cloudCertId string) error { func (d *DeployerProvider) deployToLoadbalancer(ctx context.Context, cloudCertId string) error {
if d.config.LoadbalancerId == "" { if d.config.LoadbalancerId == "" {
return errors.New("config `loadbalancerId` is required") return errors.New("config `loadbalancerId` is required")
} }
@ -213,7 +210,7 @@ func (d *AliyunALBDeployer) deployToLoadbalancer(ctx context.Context, cloudCertI
return nil return nil
} }
func (d *AliyunALBDeployer) deployToListener(ctx context.Context, cloudCertId string) error { func (d *DeployerProvider) deployToListener(ctx context.Context, cloudCertId string) error {
if d.config.ListenerId == "" { if d.config.ListenerId == "" {
return errors.New("config `listenerId` is required") return errors.New("config `listenerId` is required")
} }
@ -226,7 +223,7 @@ func (d *AliyunALBDeployer) deployToListener(ctx context.Context, cloudCertId st
return nil return nil
} }
func (d *AliyunALBDeployer) updateListenerCertificate(ctx context.Context, cloudListenerId string, cloudCertId string) error { func (d *DeployerProvider) updateListenerCertificate(ctx context.Context, cloudListenerId string, cloudCertId string) error {
// 查询监听的属性 // 查询监听的属性
// REF: https://help.aliyun.com/zh/slb/application-load-balancer/developer-reference/api-alb-2020-06-16-getlistenerattribute // REF: https://help.aliyun.com/zh/slb/application-load-balancer/developer-reference/api-alb-2020-06-16-getlistenerattribute
getListenerAttributeReq := &aliyunAlb.GetListenerAttributeRequest{ getListenerAttributeReq := &aliyunAlb.GetListenerAttributeRequest{
@ -257,7 +254,7 @@ func (d *AliyunALBDeployer) updateListenerCertificate(ctx context.Context, cloud
d.logger.Logt("已更新 ALB 监听配置", updateListenerAttributeResp) d.logger.Logt("已更新 ALB 监听配置", updateListenerAttributeResp)
} else { } else {
// 指定 SNI需部署到扩展域名(支持泛域名) // 指定 SNI需部署到扩展域名
// 查询监听证书列表 // 查询监听证书列表
// REF: https://help.aliyun.com/zh/slb/application-load-balancer/developer-reference/api-alb-2020-06-16-listlistenercertificates // REF: https://help.aliyun.com/zh/slb/application-load-balancer/developer-reference/api-alb-2020-06-16-listlistenercertificates
@ -445,7 +442,7 @@ func createSslUploader(accessKeyId, accessKeySecret, region string) (uploader.Up
} }
} }
uploader, err := uploaderp.New(&uploaderp.AliyunCASUploaderConfig{ uploader, err := uploadersp.NewUploader(&uploadersp.UploaderConfig{
AccessKeyId: accessKeyId, AccessKeyId: accessKeyId,
AccessKeySecret: accessKeySecret, AccessKeySecret: accessKeySecret,
Region: casRegion, Region: casRegion,

View File

@ -63,11 +63,11 @@ func TestDeploy(t *testing.T) {
fmt.Sprintf("DOMAIN: %v", fDomain), fmt.Sprintf("DOMAIN: %v", fDomain),
}, "\n")) }, "\n"))
deployer, err := provider.New(&provider.AliyunALBDeployerConfig{ deployer, err := provider.NewDeployer(&provider.DeployerConfig{
AccessKeyId: fAccessKeyId, AccessKeyId: fAccessKeyId,
AccessKeySecret: fAccessKeySecret, AccessKeySecret: fAccessKeySecret,
Region: fRegion, Region: fRegion,
ResourceType: provider.DEPLOY_RESOURCE_LOADBALANCER, ResourceType: provider.RESOURCE_TYPE_LOADBALANCER,
LoadbalancerId: fLoadbalancerId, LoadbalancerId: fLoadbalancerId,
Domain: fDomain, Domain: fDomain,
}) })
@ -98,11 +98,11 @@ func TestDeploy(t *testing.T) {
fmt.Sprintf("LISTENERID: %v", fListenerId), fmt.Sprintf("LISTENERID: %v", fListenerId),
}, "\n")) }, "\n"))
deployer, err := provider.New(&provider.AliyunALBDeployerConfig{ deployer, err := provider.NewDeployer(&provider.DeployerConfig{
AccessKeyId: fAccessKeyId, AccessKeyId: fAccessKeyId,
AccessKeySecret: fAccessKeySecret, AccessKeySecret: fAccessKeySecret,
Region: fRegion, Region: fRegion,
ResourceType: provider.DEPLOY_RESOURCE_LISTENER, ResourceType: provider.RESOURCE_TYPE_LISTENER,
ListenerId: fListenerId, ListenerId: fListenerId,
Domain: fDomain, Domain: fDomain,
}) })

View File

@ -0,0 +1,10 @@
package aliyunalb
type ResourceType string
const (
// 资源类型:部署到指定负载均衡器。
RESOURCE_TYPE_LOADBALANCER = ResourceType("loadbalancer")
// 资源类型:部署到指定监听器。
RESOURCE_TYPE_LISTENER = ResourceType("listener")
)

View File

@ -1,10 +0,0 @@
package aliyunalb
type DeployResourceType string
const (
// 资源类型:部署到指定负载均衡器。
DEPLOY_RESOURCE_LOADBALANCER = DeployResourceType("loadbalancer")
// 资源类型:部署到指定监听器。
DEPLOY_RESOURCE_LISTENER = DeployResourceType("listener")
)

View File

@ -15,10 +15,10 @@ import (
"github.com/usual2970/certimate/internal/pkg/core/deployer" "github.com/usual2970/certimate/internal/pkg/core/deployer"
"github.com/usual2970/certimate/internal/pkg/core/logger" "github.com/usual2970/certimate/internal/pkg/core/logger"
"github.com/usual2970/certimate/internal/pkg/core/uploader" "github.com/usual2970/certimate/internal/pkg/core/uploader"
uploaderp "github.com/usual2970/certimate/internal/pkg/core/uploader/providers/aliyun-cas" uploadersp "github.com/usual2970/certimate/internal/pkg/core/uploader/providers/aliyun-cas"
) )
type AliyunCASDeployDeployerConfig struct { type DeployerConfig struct {
// 阿里云 AccessKeyId。 // 阿里云 AccessKeyId。
AccessKeyId string `json:"accessKeyId"` AccessKeyId string `json:"accessKeyId"`
// 阿里云 AccessKeySecret。 // 阿里云 AccessKeySecret。
@ -32,26 +32,18 @@ type AliyunCASDeployDeployerConfig struct {
ContactIds []string `json:"contactIds"` ContactIds []string `json:"contactIds"`
} }
type AliyunCASDeployDeployer struct { type DeployerProvider struct {
config *AliyunCASDeployDeployerConfig config *DeployerConfig
logger logger.Logger logger logger.Logger
sdkClient *aliyunCas.Client sdkClient *aliyunCas.Client
sslUploader uploader.Uploader sslUploader uploader.Uploader
} }
var _ deployer.Deployer = (*AliyunCASDeployDeployer)(nil) var _ deployer.Deployer = (*DeployerProvider)(nil)
func New(config *AliyunCASDeployDeployerConfig) (*AliyunCASDeployDeployer, error) { func NewDeployer(config *DeployerConfig) (*DeployerProvider, error) {
return NewWithLogger(config, logger.NewNilLogger())
}
func NewWithLogger(config *AliyunCASDeployDeployerConfig, logger logger.Logger) (*AliyunCASDeployDeployer, error) {
if config == nil { if config == nil {
return nil, errors.New("config is nil") panic("config is nil")
}
if logger == nil {
return nil, errors.New("logger is nil")
} }
client, err := createSdkClient(config.AccessKeyId, config.AccessKeySecret, config.Region) client, err := createSdkClient(config.AccessKeyId, config.AccessKeySecret, config.Region)
@ -64,15 +56,20 @@ func NewWithLogger(config *AliyunCASDeployDeployerConfig, logger logger.Logger)
return nil, xerrors.Wrap(err, "failed to create ssl uploader") return nil, xerrors.Wrap(err, "failed to create ssl uploader")
} }
return &AliyunCASDeployDeployer{ return &DeployerProvider{
logger: logger,
config: config, config: config,
logger: logger.NewNilLogger(),
sdkClient: client, sdkClient: client,
sslUploader: uploader, sslUploader: uploader,
}, nil }, nil
} }
func (d *AliyunCASDeployDeployer) Deploy(ctx context.Context, certPem string, privkeyPem string) (*deployer.DeployResult, error) { func (d *DeployerProvider) WithLogger(logger logger.Logger) *DeployerProvider {
d.logger = logger
return d
}
func (d *DeployerProvider) Deploy(ctx context.Context, certPem string, privkeyPem string) (*deployer.DeployResult, error) {
if len(d.config.ResourceIds) == 0 { if len(d.config.ResourceIds) == 0 {
return nil, errors.New("config `resourceIds` is required") return nil, errors.New("config `resourceIds` is required")
} }
@ -178,7 +175,7 @@ func createSdkClient(accessKeyId, accessKeySecret, region string) (*aliyunCas.Cl
} }
func createSslUploader(accessKeyId, accessKeySecret, region string) (uploader.Uploader, error) { func createSslUploader(accessKeyId, accessKeySecret, region string) (uploader.Uploader, error) {
uploader, err := uploaderp.New(&uploaderp.AliyunCASUploaderConfig{ uploader, err := uploadersp.NewUploader(&uploadersp.UploaderConfig{
AccessKeyId: accessKeyId, AccessKeyId: accessKeyId,
AccessKeySecret: accessKeySecret, AccessKeySecret: accessKeySecret,
Region: region, Region: region,

View File

@ -2,7 +2,6 @@
import ( import (
"context" "context"
"errors"
"fmt" "fmt"
"strings" "strings"
"time" "time"
@ -16,7 +15,7 @@ import (
"github.com/usual2970/certimate/internal/pkg/core/logger" "github.com/usual2970/certimate/internal/pkg/core/logger"
) )
type AliyunCDNDeployerConfig struct { type DeployerConfig struct {
// 阿里云 AccessKeyId。 // 阿里云 AccessKeyId。
AccessKeyId string `json:"accessKeyId"` AccessKeyId string `json:"accessKeyId"`
// 阿里云 AccessKeySecret。 // 阿里云 AccessKeySecret。
@ -25,25 +24,17 @@ type AliyunCDNDeployerConfig struct {
Domain string `json:"domain"` Domain string `json:"domain"`
} }
type AliyunCDNDeployer struct { type DeployerProvider struct {
config *AliyunCDNDeployerConfig config *DeployerConfig
logger logger.Logger logger logger.Logger
sdkClient *aliyunCdn.Client sdkClient *aliyunCdn.Client
} }
var _ deployer.Deployer = (*AliyunCDNDeployer)(nil) var _ deployer.Deployer = (*DeployerProvider)(nil)
func New(config *AliyunCDNDeployerConfig) (*AliyunCDNDeployer, error) { func NewDeployer(config *DeployerConfig) (*DeployerProvider, error) {
return NewWithLogger(config, logger.NewNilLogger())
}
func NewWithLogger(config *AliyunCDNDeployerConfig, logger logger.Logger) (*AliyunCDNDeployer, error) {
if config == nil { if config == nil {
return nil, errors.New("config is nil") panic("config is nil")
}
if logger == nil {
return nil, errors.New("logger is nil")
} }
client, err := createSdkClient(config.AccessKeyId, config.AccessKeySecret) client, err := createSdkClient(config.AccessKeyId, config.AccessKeySecret)
@ -51,14 +42,19 @@ func NewWithLogger(config *AliyunCDNDeployerConfig, logger logger.Logger) (*Aliy
return nil, xerrors.Wrap(err, "failed to create sdk client") return nil, xerrors.Wrap(err, "failed to create sdk client")
} }
return &AliyunCDNDeployer{ return &DeployerProvider{
logger: logger,
config: config, config: config,
logger: logger.NewNilLogger(),
sdkClient: client, sdkClient: client,
}, nil }, nil
} }
func (d *AliyunCDNDeployer) Deploy(ctx context.Context, certPem string, privkeyPem string) (*deployer.DeployResult, error) { func (d *DeployerProvider) WithLogger(logger logger.Logger) *DeployerProvider {
d.logger = logger
return d
}
func (d *DeployerProvider) Deploy(ctx context.Context, certPem string, privkeyPem string) (*deployer.DeployResult, error) {
// "*.example.com" → ".example.com",适配阿里云 CDN 要求的泛域名格式 // "*.example.com" → ".example.com",适配阿里云 CDN 要求的泛域名格式
domain := strings.TrimPrefix(d.config.Domain, "*") domain := strings.TrimPrefix(d.config.Domain, "*")

View File

@ -52,7 +52,7 @@ func TestDeploy(t *testing.T) {
fmt.Sprintf("DOMAIN: %v", fDomain), fmt.Sprintf("DOMAIN: %v", fDomain),
}, "\n")) }, "\n"))
deployer, err := provider.New(&provider.AliyunCDNDeployerConfig{ deployer, err := provider.NewDeployer(&provider.DeployerConfig{
AccessKeyId: fAccessKeyId, AccessKeyId: fAccessKeyId,
AccessKeySecret: fAccessKeySecret, AccessKeySecret: fAccessKeySecret,
Domain: fDomain, Domain: fDomain,

View File

@ -13,10 +13,10 @@ import (
"github.com/usual2970/certimate/internal/pkg/core/deployer" "github.com/usual2970/certimate/internal/pkg/core/deployer"
"github.com/usual2970/certimate/internal/pkg/core/logger" "github.com/usual2970/certimate/internal/pkg/core/logger"
"github.com/usual2970/certimate/internal/pkg/core/uploader" "github.com/usual2970/certimate/internal/pkg/core/uploader"
uploaderp "github.com/usual2970/certimate/internal/pkg/core/uploader/providers/aliyun-slb" uploadersp "github.com/usual2970/certimate/internal/pkg/core/uploader/providers/aliyun-slb"
) )
type AliyunCLBDeployerConfig struct { type DeployerConfig struct {
// 阿里云 AccessKeyId。 // 阿里云 AccessKeyId。
AccessKeyId string `json:"accessKeyId"` AccessKeyId string `json:"accessKeyId"`
// 阿里云 AccessKeySecret。 // 阿里云 AccessKeySecret。
@ -24,38 +24,30 @@ type AliyunCLBDeployerConfig struct {
// 阿里云地域。 // 阿里云地域。
Region string `json:"region"` Region string `json:"region"`
// 部署资源类型。 // 部署资源类型。
ResourceType DeployResourceType `json:"resourceType"` ResourceType ResourceType `json:"resourceType"`
// 负载均衡实例 ID。 // 负载均衡实例 ID。
// 部署资源类型为 [DEPLOY_RESOURCE_LOADBALANCER]、[DEPLOY_RESOURCE_LISTENER] 时必填。 // 部署资源类型为 [RESOURCE_TYPE_LOADBALANCER]、[RESOURCE_TYPE_LISTENER] 时必填。
LoadbalancerId string `json:"loadbalancerId,omitempty"` LoadbalancerId string `json:"loadbalancerId,omitempty"`
// 负载均衡监听端口。 // 负载均衡监听端口。
// 部署资源类型为 [DEPLOY_RESOURCE_LISTENER] 时必填。 // 部署资源类型为 [RESOURCE_TYPE_LISTENER] 时必填。
ListenerPort int32 `json:"listenerPort,omitempty"` ListenerPort int32 `json:"listenerPort,omitempty"`
// SNI 域名(支持泛域名)。 // SNI 域名(支持泛域名)。
// 部署资源类型为 [DEPLOY_RESOURCE_LOADBALANCER]、[DEPLOY_RESOURCE_LISTENER] 时选填。 // 部署资源类型为 [RESOURCE_TYPE_LOADBALANCER]、[RESOURCE_TYPE_LISTENER] 时选填。
Domain string `json:"domain,omitempty"` Domain string `json:"domain,omitempty"`
} }
type AliyunCLBDeployer struct { type DeployerProvider struct {
config *AliyunCLBDeployerConfig config *DeployerConfig
logger logger.Logger logger logger.Logger
sdkClient *aliyunSlb.Client sdkClient *aliyunSlb.Client
sslUploader uploader.Uploader sslUploader uploader.Uploader
} }
var _ deployer.Deployer = (*AliyunCLBDeployer)(nil) var _ deployer.Deployer = (*DeployerProvider)(nil)
func New(config *AliyunCLBDeployerConfig) (*AliyunCLBDeployer, error) { func NewDeployer(config *DeployerConfig) (*DeployerProvider, error) {
return NewWithLogger(config, logger.NewNilLogger())
}
func NewWithLogger(config *AliyunCLBDeployerConfig, logger logger.Logger) (*AliyunCLBDeployer, error) {
if config == nil { if config == nil {
return nil, errors.New("config is nil") panic("config is nil")
}
if logger == nil {
return nil, errors.New("logger is nil")
} }
client, err := createSdkClient(config.AccessKeyId, config.AccessKeySecret, config.Region) client, err := createSdkClient(config.AccessKeyId, config.AccessKeySecret, config.Region)
@ -63,7 +55,7 @@ func NewWithLogger(config *AliyunCLBDeployerConfig, logger logger.Logger) (*Aliy
return nil, xerrors.Wrap(err, "failed to create sdk client") return nil, xerrors.Wrap(err, "failed to create sdk client")
} }
uploader, err := uploaderp.New(&uploaderp.AliyunSLBUploaderConfig{ uploader, err := uploadersp.NewUploader(&uploadersp.UploaderConfig{
AccessKeyId: config.AccessKeyId, AccessKeyId: config.AccessKeyId,
AccessKeySecret: config.AccessKeySecret, AccessKeySecret: config.AccessKeySecret,
Region: config.Region, Region: config.Region,
@ -72,15 +64,20 @@ func NewWithLogger(config *AliyunCLBDeployerConfig, logger logger.Logger) (*Aliy
return nil, xerrors.Wrap(err, "failed to create ssl uploader") return nil, xerrors.Wrap(err, "failed to create ssl uploader")
} }
return &AliyunCLBDeployer{ return &DeployerProvider{
logger: logger,
config: config, config: config,
logger: logger.NewNilLogger(),
sdkClient: client, sdkClient: client,
sslUploader: uploader, sslUploader: uploader,
}, nil }, nil
} }
func (d *AliyunCLBDeployer) Deploy(ctx context.Context, certPem string, privkeyPem string) (*deployer.DeployResult, error) { func (d *DeployerProvider) WithLogger(logger logger.Logger) *DeployerProvider {
d.logger = logger
return d
}
func (d *DeployerProvider) Deploy(ctx context.Context, certPem string, privkeyPem string) (*deployer.DeployResult, error) {
// 上传证书到 SLB // 上传证书到 SLB
upres, err := d.sslUploader.Upload(ctx, certPem, privkeyPem) upres, err := d.sslUploader.Upload(ctx, certPem, privkeyPem)
if err != nil { if err != nil {
@ -91,12 +88,12 @@ func (d *AliyunCLBDeployer) Deploy(ctx context.Context, certPem string, privkeyP
// 根据部署资源类型决定部署方式 // 根据部署资源类型决定部署方式
switch d.config.ResourceType { switch d.config.ResourceType {
case DEPLOY_RESOURCE_LOADBALANCER: case RESOURCE_TYPE_LOADBALANCER:
if err := d.deployToLoadbalancer(ctx, upres.CertId); err != nil { if err := d.deployToLoadbalancer(ctx, upres.CertId); err != nil {
return nil, err return nil, err
} }
case DEPLOY_RESOURCE_LISTENER: case RESOURCE_TYPE_LISTENER:
if err := d.deployToListener(ctx, upres.CertId); err != nil { if err := d.deployToListener(ctx, upres.CertId); err != nil {
return nil, err return nil, err
} }
@ -108,7 +105,7 @@ func (d *AliyunCLBDeployer) Deploy(ctx context.Context, certPem string, privkeyP
return &deployer.DeployResult{}, nil return &deployer.DeployResult{}, nil
} }
func (d *AliyunCLBDeployer) deployToLoadbalancer(ctx context.Context, cloudCertId string) error { func (d *DeployerProvider) deployToLoadbalancer(ctx context.Context, cloudCertId string) error {
if d.config.LoadbalancerId == "" { if d.config.LoadbalancerId == "" {
return errors.New("config `loadbalancerId` is required") return errors.New("config `loadbalancerId` is required")
} }
@ -179,7 +176,7 @@ func (d *AliyunCLBDeployer) deployToLoadbalancer(ctx context.Context, cloudCertI
return nil return nil
} }
func (d *AliyunCLBDeployer) deployToListener(ctx context.Context, cloudCertId string) error { func (d *DeployerProvider) deployToListener(ctx context.Context, cloudCertId string) error {
if d.config.LoadbalancerId == "" { if d.config.LoadbalancerId == "" {
return errors.New("config `loadbalancerId` is required") return errors.New("config `loadbalancerId` is required")
} }
@ -195,7 +192,7 @@ func (d *AliyunCLBDeployer) deployToListener(ctx context.Context, cloudCertId st
return nil return nil
} }
func (d *AliyunCLBDeployer) updateListenerCertificate(ctx context.Context, cloudLoadbalancerId string, cloudListenerPort int32, cloudCertId string) error { func (d *DeployerProvider) updateListenerCertificate(ctx context.Context, cloudLoadbalancerId string, cloudListenerPort int32, cloudCertId string) error {
// 查询监听配置 // 查询监听配置
// REF: https://help.aliyun.com/zh/slb/classic-load-balancer/developer-reference/api-slb-2014-05-15-describeloadbalancerhttpslistenerattribute // REF: https://help.aliyun.com/zh/slb/classic-load-balancer/developer-reference/api-slb-2014-05-15-describeloadbalancerhttpslistenerattribute
describeLoadBalancerHTTPSListenerAttributeReq := &aliyunSlb.DescribeLoadBalancerHTTPSListenerAttributeRequest{ describeLoadBalancerHTTPSListenerAttributeReq := &aliyunSlb.DescribeLoadBalancerHTTPSListenerAttributeRequest{
@ -214,8 +211,6 @@ func (d *AliyunCLBDeployer) updateListenerCertificate(ctx context.Context, cloud
// 修改监听配置 // 修改监听配置
// REF: https://help.aliyun.com/zh/slb/classic-load-balancer/developer-reference/api-slb-2014-05-15-setloadbalancerhttpslistenerattribute // REF: https://help.aliyun.com/zh/slb/classic-load-balancer/developer-reference/api-slb-2014-05-15-setloadbalancerhttpslistenerattribute
//
// 注意修改监听配置要放在修改扩展域名之后
setLoadBalancerHTTPSListenerAttributeReq := &aliyunSlb.SetLoadBalancerHTTPSListenerAttributeRequest{ setLoadBalancerHTTPSListenerAttributeReq := &aliyunSlb.SetLoadBalancerHTTPSListenerAttributeRequest{
RegionId: tea.String(d.config.Region), RegionId: tea.String(d.config.Region),
LoadBalancerId: tea.String(cloudLoadbalancerId), LoadBalancerId: tea.String(cloudLoadbalancerId),
@ -229,7 +224,7 @@ func (d *AliyunCLBDeployer) updateListenerCertificate(ctx context.Context, cloud
d.logger.Logt("已更新 CLB HTTPS 监听配置", setLoadBalancerHTTPSListenerAttributeResp) d.logger.Logt("已更新 CLB HTTPS 监听配置", setLoadBalancerHTTPSListenerAttributeResp)
} else { } else {
// 指定 SNI需部署到扩展域名(支持泛域名) // 指定 SNI需部署到扩展域名
// 查询扩展域名 // 查询扩展域名
// REF: https://help.aliyun.com/zh/slb/classic-load-balancer/developer-reference/api-slb-2014-05-15-describedomainextensions // REF: https://help.aliyun.com/zh/slb/classic-load-balancer/developer-reference/api-slb-2014-05-15-describedomainextensions

View File

@ -63,11 +63,11 @@ func TestDeploy(t *testing.T) {
fmt.Sprintf("DOMAIN: %v", fDomain), fmt.Sprintf("DOMAIN: %v", fDomain),
}, "\n")) }, "\n"))
deployer, err := provider.New(&provider.AliyunCLBDeployerConfig{ deployer, err := provider.NewDeployer(&provider.DeployerConfig{
AccessKeyId: fAccessKeyId, AccessKeyId: fAccessKeyId,
AccessKeySecret: fAccessKeySecret, AccessKeySecret: fAccessKeySecret,
Region: fRegion, Region: fRegion,
ResourceType: provider.DEPLOY_RESOURCE_LOADBALANCER, ResourceType: provider.RESOURCE_TYPE_LOADBALANCER,
LoadbalancerId: fLoadbalancerId, LoadbalancerId: fLoadbalancerId,
Domain: fDomain, Domain: fDomain,
}) })
@ -99,11 +99,11 @@ func TestDeploy(t *testing.T) {
fmt.Sprintf("LISTENERPORT: %v", fListenerPort), fmt.Sprintf("LISTENERPORT: %v", fListenerPort),
}, "\n")) }, "\n"))
deployer, err := provider.New(&provider.AliyunCLBDeployerConfig{ deployer, err := provider.NewDeployer(&provider.DeployerConfig{
AccessKeyId: fAccessKeyId, AccessKeyId: fAccessKeyId,
AccessKeySecret: fAccessKeySecret, AccessKeySecret: fAccessKeySecret,
Region: fRegion, Region: fRegion,
ResourceType: provider.DEPLOY_RESOURCE_LISTENER, ResourceType: provider.RESOURCE_TYPE_LISTENER,
LoadbalancerId: fLoadbalancerId, LoadbalancerId: fLoadbalancerId,
ListenerPort: int32(fListenerPort), ListenerPort: int32(fListenerPort),
Domain: fDomain, Domain: fDomain,

View File

@ -0,0 +1,10 @@
package aliyunclb
type ResourceType string
const (
// 资源类型:部署到指定负载均衡器。
RESOURCE_TYPE_LOADBALANCER = ResourceType("loadbalancer")
// 资源类型:部署到指定监听器。
RESOURCE_TYPE_LISTENER = ResourceType("listener")
)

View File

@ -1,10 +0,0 @@
package aliyunclb
type DeployResourceType string
const (
// 资源类型:部署到指定负载均衡器。
DEPLOY_RESOURCE_LOADBALANCER = DeployResourceType("loadbalancer")
// 资源类型:部署到指定监听器。
DEPLOY_RESOURCE_LISTENER = DeployResourceType("listener")
)

View File

@ -2,7 +2,6 @@
import ( import (
"context" "context"
"errors"
"fmt" "fmt"
"strings" "strings"
"time" "time"
@ -16,7 +15,7 @@ import (
"github.com/usual2970/certimate/internal/pkg/core/logger" "github.com/usual2970/certimate/internal/pkg/core/logger"
) )
type AliyunDCDNDeployerConfig struct { type DeployerConfig struct {
// 阿里云 AccessKeyId。 // 阿里云 AccessKeyId。
AccessKeyId string `json:"accessKeyId"` AccessKeyId string `json:"accessKeyId"`
// 阿里云 AccessKeySecret。 // 阿里云 AccessKeySecret。
@ -25,25 +24,17 @@ type AliyunDCDNDeployerConfig struct {
Domain string `json:"domain"` Domain string `json:"domain"`
} }
type AliyunDCDNDeployer struct { type DeployerProvider struct {
config *AliyunDCDNDeployerConfig config *DeployerConfig
logger logger.Logger logger logger.Logger
sdkClient *aliyunDcdn.Client sdkClient *aliyunDcdn.Client
} }
var _ deployer.Deployer = (*AliyunDCDNDeployer)(nil) var _ deployer.Deployer = (*DeployerProvider)(nil)
func New(config *AliyunDCDNDeployerConfig) (*AliyunDCDNDeployer, error) { func NewDeployer(config *DeployerConfig) (*DeployerProvider, error) {
return NewWithLogger(config, logger.NewNilLogger())
}
func NewWithLogger(config *AliyunDCDNDeployerConfig, logger logger.Logger) (*AliyunDCDNDeployer, error) {
if config == nil { if config == nil {
return nil, errors.New("config is nil") panic("config is nil")
}
if logger == nil {
return nil, errors.New("logger is nil")
} }
client, err := createSdkClient(config.AccessKeyId, config.AccessKeySecret) client, err := createSdkClient(config.AccessKeyId, config.AccessKeySecret)
@ -51,14 +42,19 @@ func NewWithLogger(config *AliyunDCDNDeployerConfig, logger logger.Logger) (*Ali
return nil, xerrors.Wrap(err, "failed to create sdk client") return nil, xerrors.Wrap(err, "failed to create sdk client")
} }
return &AliyunDCDNDeployer{ return &DeployerProvider{
logger: logger,
config: config, config: config,
logger: logger.NewNilLogger(),
sdkClient: client, sdkClient: client,
}, nil }, nil
} }
func (d *AliyunDCDNDeployer) Deploy(ctx context.Context, certPem string, privkeyPem string) (*deployer.DeployResult, error) { func (d *DeployerProvider) WithLogger(logger logger.Logger) *DeployerProvider {
d.logger = logger
return d
}
func (d *DeployerProvider) Deploy(ctx context.Context, certPem string, privkeyPem string) (*deployer.DeployResult, error) {
// "*.example.com" → ".example.com",适配阿里云 DCDN 要求的泛域名格式 // "*.example.com" → ".example.com",适配阿里云 DCDN 要求的泛域名格式
domain := strings.TrimPrefix(d.config.Domain, "*") domain := strings.TrimPrefix(d.config.Domain, "*")

View File

@ -52,7 +52,7 @@ func TestDeploy(t *testing.T) {
fmt.Sprintf("DOMAIN: %v", fDomain), fmt.Sprintf("DOMAIN: %v", fDomain),
}, "\n")) }, "\n"))
deployer, err := provider.New(&provider.AliyunDCDNDeployerConfig{ deployer, err := provider.NewDeployer(&provider.DeployerConfig{
AccessKeyId: fAccessKeyId, AccessKeyId: fAccessKeyId,
AccessKeySecret: fAccessKeySecret, AccessKeySecret: fAccessKeySecret,
Domain: fDomain, Domain: fDomain,

View File

@ -15,10 +15,10 @@ import (
"github.com/usual2970/certimate/internal/pkg/core/deployer" "github.com/usual2970/certimate/internal/pkg/core/deployer"
"github.com/usual2970/certimate/internal/pkg/core/logger" "github.com/usual2970/certimate/internal/pkg/core/logger"
"github.com/usual2970/certimate/internal/pkg/core/uploader" "github.com/usual2970/certimate/internal/pkg/core/uploader"
uploaderp "github.com/usual2970/certimate/internal/pkg/core/uploader/providers/aliyun-cas" uploadersp "github.com/usual2970/certimate/internal/pkg/core/uploader/providers/aliyun-cas"
) )
type AliyunESADeployerConfig struct { type DeployerConfig struct {
// 阿里云 AccessKeyId。 // 阿里云 AccessKeyId。
AccessKeyId string `json:"accessKeyId"` AccessKeyId string `json:"accessKeyId"`
// 阿里云 AccessKeySecret。 // 阿里云 AccessKeySecret。
@ -29,26 +29,18 @@ type AliyunESADeployerConfig struct {
SiteId int64 `json:"siteId"` SiteId int64 `json:"siteId"`
} }
type AliyunESADeployer struct { type DeployerProvider struct {
config *AliyunESADeployerConfig config *DeployerConfig
logger logger.Logger logger logger.Logger
sdkClient *aliyunEsa.Client sdkClient *aliyunEsa.Client
sslUploader uploader.Uploader sslUploader uploader.Uploader
} }
var _ deployer.Deployer = (*AliyunESADeployer)(nil) var _ deployer.Deployer = (*DeployerProvider)(nil)
func New(config *AliyunESADeployerConfig) (*AliyunESADeployer, error) { func NewDeployer(config *DeployerConfig) (*DeployerProvider, error) {
return NewWithLogger(config, logger.NewNilLogger())
}
func NewWithLogger(config *AliyunESADeployerConfig, logger logger.Logger) (*AliyunESADeployer, error) {
if config == nil { if config == nil {
return nil, errors.New("config is nil") panic("config is nil")
}
if logger == nil {
return nil, errors.New("logger is nil")
} }
client, err := createSdkClient(config.AccessKeyId, config.AccessKeySecret, config.Region) client, err := createSdkClient(config.AccessKeyId, config.AccessKeySecret, config.Region)
@ -61,15 +53,20 @@ func NewWithLogger(config *AliyunESADeployerConfig, logger logger.Logger) (*Aliy
return nil, xerrors.Wrap(err, "failed to create ssl uploader") return nil, xerrors.Wrap(err, "failed to create ssl uploader")
} }
return &AliyunESADeployer{ return &DeployerProvider{
logger: logger,
config: config, config: config,
logger: logger.NewNilLogger(),
sdkClient: client, sdkClient: client,
sslUploader: uploader, sslUploader: uploader,
}, nil }, nil
} }
func (d *AliyunESADeployer) Deploy(ctx context.Context, certPem string, privkeyPem string) (*deployer.DeployResult, error) { func (d *DeployerProvider) WithLogger(logger logger.Logger) *DeployerProvider {
d.logger = logger
return d
}
func (d *DeployerProvider) Deploy(ctx context.Context, certPem string, privkeyPem string) (*deployer.DeployResult, error) {
if d.config.SiteId == 0 { if d.config.SiteId == 0 {
return nil, errors.New("config `siteId` is required") return nil, errors.New("config `siteId` is required")
} }
@ -129,7 +126,7 @@ func createSslUploader(accessKeyId, accessKeySecret, region string) (uploader.Up
} }
} }
uploader, err := uploaderp.New(&uploaderp.AliyunCASUploaderConfig{ uploader, err := uploadersp.NewUploader(&uploadersp.UploaderConfig{
AccessKeyId: accessKeyId, AccessKeyId: accessKeyId,
AccessKeySecret: accessKeySecret, AccessKeySecret: accessKeySecret,
Region: casRegion, Region: casRegion,

View File

@ -56,7 +56,7 @@ func TestDeploy(t *testing.T) {
fmt.Sprintf("SITEID: %v", fSiteId), fmt.Sprintf("SITEID: %v", fSiteId),
}, "\n")) }, "\n"))
deployer, err := provider.New(&provider.AliyunESADeployerConfig{ deployer, err := provider.NewDeployer(&provider.DeployerConfig{
AccessKeyId: fAccessKeyId, AccessKeyId: fAccessKeyId,
AccessKeySecret: fAccessKeySecret, AccessKeySecret: fAccessKeySecret,
Region: fRegion, Region: fRegion,

View File

@ -2,7 +2,6 @@
import ( import (
"context" "context"
"errors"
"fmt" "fmt"
"strings" "strings"
"time" "time"
@ -16,7 +15,7 @@ import (
"github.com/usual2970/certimate/internal/pkg/core/logger" "github.com/usual2970/certimate/internal/pkg/core/logger"
) )
type AliyunLiveDeployerConfig struct { type DeployerConfig struct {
// 阿里云 AccessKeyId。 // 阿里云 AccessKeyId。
AccessKeyId string `json:"accessKeyId"` AccessKeyId string `json:"accessKeyId"`
// 阿里云 AccessKeySecret。 // 阿里云 AccessKeySecret。
@ -27,25 +26,17 @@ type AliyunLiveDeployerConfig struct {
Domain string `json:"domain"` Domain string `json:"domain"`
} }
type AliyunLiveDeployer struct { type DeployerProvider struct {
config *AliyunLiveDeployerConfig config *DeployerConfig
logger logger.Logger logger logger.Logger
sdkClient *aliyunLive.Client sdkClient *aliyunLive.Client
} }
var _ deployer.Deployer = (*AliyunLiveDeployer)(nil) var _ deployer.Deployer = (*DeployerProvider)(nil)
func New(config *AliyunLiveDeployerConfig) (*AliyunLiveDeployer, error) { func NewDeployer(config *DeployerConfig) (*DeployerProvider, error) {
return NewWithLogger(config, logger.NewNilLogger())
}
func NewWithLogger(config *AliyunLiveDeployerConfig, logger logger.Logger) (*AliyunLiveDeployer, error) {
if config == nil { if config == nil {
return nil, errors.New("config is nil") panic("config is nil")
}
if logger == nil {
return nil, errors.New("logger is nil")
} }
client, err := createSdkClient(config.AccessKeyId, config.AccessKeySecret, config.Region) client, err := createSdkClient(config.AccessKeyId, config.AccessKeySecret, config.Region)
@ -53,14 +44,19 @@ func NewWithLogger(config *AliyunLiveDeployerConfig, logger logger.Logger) (*Ali
return nil, xerrors.Wrap(err, "failed to create sdk client") return nil, xerrors.Wrap(err, "failed to create sdk client")
} }
return &AliyunLiveDeployer{ return &DeployerProvider{
logger: logger,
config: config, config: config,
logger: logger.NewNilLogger(),
sdkClient: client, sdkClient: client,
}, nil }, nil
} }
func (d *AliyunLiveDeployer) Deploy(ctx context.Context, certPem string, privkeyPem string) (*deployer.DeployResult, error) { func (d *DeployerProvider) WithLogger(logger logger.Logger) *DeployerProvider {
d.logger = logger
return d
}
func (d *DeployerProvider) Deploy(ctx context.Context, certPem string, privkeyPem string) (*deployer.DeployResult, error) {
// "*.example.com" → ".example.com",适配阿里云 Live 要求的泛域名格式 // "*.example.com" → ".example.com",适配阿里云 Live 要求的泛域名格式
domain := strings.TrimPrefix(d.config.Domain, "*") domain := strings.TrimPrefix(d.config.Domain, "*")

View File

@ -16,6 +16,7 @@ var (
fInputKeyPath string fInputKeyPath string
fAccessKeyId string fAccessKeyId string
fAccessKeySecret string fAccessKeySecret string
fRegion string
fDomain string fDomain string
) )
@ -26,6 +27,7 @@ func init() {
flag.StringVar(&fInputKeyPath, argsPrefix+"INPUTKEYPATH", "", "") flag.StringVar(&fInputKeyPath, argsPrefix+"INPUTKEYPATH", "", "")
flag.StringVar(&fAccessKeyId, argsPrefix+"ACCESSKEYID", "", "") flag.StringVar(&fAccessKeyId, argsPrefix+"ACCESSKEYID", "", "")
flag.StringVar(&fAccessKeySecret, argsPrefix+"ACCESSKEYSECRET", "", "") flag.StringVar(&fAccessKeySecret, argsPrefix+"ACCESSKEYSECRET", "", "")
flag.StringVar(&fRegion, argsPrefix+"REGION", "", "")
flag.StringVar(&fDomain, argsPrefix+"DOMAIN", "", "") flag.StringVar(&fDomain, argsPrefix+"DOMAIN", "", "")
} }
@ -37,6 +39,7 @@ Shell command to run this test:
--CERTIMATE_DEPLOYER_ALIYUNLIVE_INPUTKEYPATH="/path/to/your-input-key.pem" \ --CERTIMATE_DEPLOYER_ALIYUNLIVE_INPUTKEYPATH="/path/to/your-input-key.pem" \
--CERTIMATE_DEPLOYER_ALIYUNLIVE_ACCESSKEYID="your-access-key-id" \ --CERTIMATE_DEPLOYER_ALIYUNLIVE_ACCESSKEYID="your-access-key-id" \
--CERTIMATE_DEPLOYER_ALIYUNLIVE_ACCESSKEYSECRET="your-access-key-secret" \ --CERTIMATE_DEPLOYER_ALIYUNLIVE_ACCESSKEYSECRET="your-access-key-secret" \
--CERTIMATE_DEPLOYER_ALIYUNLIVE_REGION="cn-hangzhou" \
--CERTIMATE_DEPLOYER_ALIYUNLIVE_DOMAIN="example.com" --CERTIMATE_DEPLOYER_ALIYUNLIVE_DOMAIN="example.com"
*/ */
func TestDeploy(t *testing.T) { func TestDeploy(t *testing.T) {
@ -49,12 +52,14 @@ func TestDeploy(t *testing.T) {
fmt.Sprintf("INPUTKEYPATH: %v", fInputKeyPath), fmt.Sprintf("INPUTKEYPATH: %v", fInputKeyPath),
fmt.Sprintf("ACCESSKEYID: %v", fAccessKeyId), fmt.Sprintf("ACCESSKEYID: %v", fAccessKeyId),
fmt.Sprintf("ACCESSKEYSECRET: %v", fAccessKeySecret), fmt.Sprintf("ACCESSKEYSECRET: %v", fAccessKeySecret),
fmt.Sprintf("REGION: %v", fRegion),
fmt.Sprintf("DOMAIN: %v", fDomain), fmt.Sprintf("DOMAIN: %v", fDomain),
}, "\n")) }, "\n"))
deployer, err := provider.New(&provider.AliyunLiveDeployerConfig{ deployer, err := provider.NewDeployer(&provider.DeployerConfig{
AccessKeyId: fAccessKeyId, AccessKeyId: fAccessKeyId,
AccessKeySecret: fAccessKeySecret, AccessKeySecret: fAccessKeySecret,
Region: fRegion,
Domain: fDomain, Domain: fDomain,
}) })
if err != nil { if err != nil {

View File

@ -14,10 +14,10 @@ import (
"github.com/usual2970/certimate/internal/pkg/core/deployer" "github.com/usual2970/certimate/internal/pkg/core/deployer"
"github.com/usual2970/certimate/internal/pkg/core/logger" "github.com/usual2970/certimate/internal/pkg/core/logger"
"github.com/usual2970/certimate/internal/pkg/core/uploader" "github.com/usual2970/certimate/internal/pkg/core/uploader"
uploaderp "github.com/usual2970/certimate/internal/pkg/core/uploader/providers/aliyun-cas" uploadersp "github.com/usual2970/certimate/internal/pkg/core/uploader/providers/aliyun-cas"
) )
type AliyunNLBDeployerConfig struct { type DeployerConfig struct {
// 阿里云 AccessKeyId。 // 阿里云 AccessKeyId。
AccessKeyId string `json:"accessKeyId"` AccessKeyId string `json:"accessKeyId"`
// 阿里云 AccessKeySecret。 // 阿里云 AccessKeySecret。
@ -25,35 +25,27 @@ type AliyunNLBDeployerConfig struct {
// 阿里云地域。 // 阿里云地域。
Region string `json:"region"` Region string `json:"region"`
// 部署资源类型。 // 部署资源类型。
ResourceType DeployResourceType `json:"resourceType"` ResourceType ResourceType `json:"resourceType"`
// 负载均衡实例 ID。 // 负载均衡实例 ID。
// 部署资源类型为 [DEPLOY_RESOURCE_LOADBALANCER] 时必填。 // 部署资源类型为 [RESOURCE_TYPE_LOADBALANCER] 时必填。
LoadbalancerId string `json:"loadbalancerId,omitempty"` LoadbalancerId string `json:"loadbalancerId,omitempty"`
// 负载均衡监听 ID。 // 负载均衡监听 ID。
// 部署资源类型为 [DEPLOY_RESOURCE_LISTENER] 时必填。 // 部署资源类型为 [RESOURCE_TYPE_LISTENER] 时必填。
ListenerId string `json:"listenerId,omitempty"` ListenerId string `json:"listenerId,omitempty"`
} }
type AliyunNLBDeployer struct { type DeployerProvider struct {
config *AliyunNLBDeployerConfig config *DeployerConfig
logger logger.Logger logger logger.Logger
sdkClient *aliyunNlb.Client sdkClient *aliyunNlb.Client
sslUploader uploader.Uploader sslUploader uploader.Uploader
} }
var _ deployer.Deployer = (*AliyunNLBDeployer)(nil) var _ deployer.Deployer = (*DeployerProvider)(nil)
func New(config *AliyunNLBDeployerConfig) (*AliyunNLBDeployer, error) { func NewDeployer(config *DeployerConfig) (*DeployerProvider, error) {
return NewWithLogger(config, logger.NewNilLogger())
}
func NewWithLogger(config *AliyunNLBDeployerConfig, logger logger.Logger) (*AliyunNLBDeployer, error) {
if config == nil { if config == nil {
return nil, errors.New("config is nil") panic("config is nil")
}
if logger == nil {
return nil, errors.New("logger is nil")
} }
client, err := createSdkClient(config.AccessKeyId, config.AccessKeySecret, config.Region) client, err := createSdkClient(config.AccessKeyId, config.AccessKeySecret, config.Region)
@ -66,15 +58,20 @@ func NewWithLogger(config *AliyunNLBDeployerConfig, logger logger.Logger) (*Aliy
return nil, xerrors.Wrap(err, "failed to create ssl uploader") return nil, xerrors.Wrap(err, "failed to create ssl uploader")
} }
return &AliyunNLBDeployer{ return &DeployerProvider{
logger: logger,
config: config, config: config,
logger: logger.NewNilLogger(),
sdkClient: client, sdkClient: client,
sslUploader: uploader, sslUploader: uploader,
}, nil }, nil
} }
func (d *AliyunNLBDeployer) Deploy(ctx context.Context, certPem string, privkeyPem string) (*deployer.DeployResult, error) { func (d *DeployerProvider) WithLogger(logger logger.Logger) *DeployerProvider {
d.logger = logger
return d
}
func (d *DeployerProvider) Deploy(ctx context.Context, certPem string, privkeyPem string) (*deployer.DeployResult, error) {
// 上传证书到 CAS // 上传证书到 CAS
upres, err := d.sslUploader.Upload(ctx, certPem, privkeyPem) upres, err := d.sslUploader.Upload(ctx, certPem, privkeyPem)
if err != nil { if err != nil {
@ -85,12 +82,12 @@ func (d *AliyunNLBDeployer) Deploy(ctx context.Context, certPem string, privkeyP
// 根据部署资源类型决定部署方式 // 根据部署资源类型决定部署方式
switch d.config.ResourceType { switch d.config.ResourceType {
case DEPLOY_RESOURCE_LOADBALANCER: case RESOURCE_TYPE_LOADBALANCER:
if err := d.deployToLoadbalancer(ctx, upres.CertId); err != nil { if err := d.deployToLoadbalancer(ctx, upres.CertId); err != nil {
return nil, err return nil, err
} }
case DEPLOY_RESOURCE_LISTENER: case RESOURCE_TYPE_LISTENER:
if err := d.deployToListener(ctx, upres.CertId); err != nil { if err := d.deployToListener(ctx, upres.CertId); err != nil {
return nil, err return nil, err
} }
@ -102,7 +99,7 @@ func (d *AliyunNLBDeployer) Deploy(ctx context.Context, certPem string, privkeyP
return &deployer.DeployResult{}, nil return &deployer.DeployResult{}, nil
} }
func (d *AliyunNLBDeployer) deployToLoadbalancer(ctx context.Context, cloudCertId string) error { func (d *DeployerProvider) deployToLoadbalancer(ctx context.Context, cloudCertId string) error {
if d.config.LoadbalancerId == "" { if d.config.LoadbalancerId == "" {
return errors.New("config `loadbalancerId` is required") return errors.New("config `loadbalancerId` is required")
} }
@ -171,7 +168,7 @@ func (d *AliyunNLBDeployer) deployToLoadbalancer(ctx context.Context, cloudCertI
return nil return nil
} }
func (d *AliyunNLBDeployer) deployToListener(ctx context.Context, cloudCertId string) error { func (d *DeployerProvider) deployToListener(ctx context.Context, cloudCertId string) error {
if d.config.ListenerId == "" { if d.config.ListenerId == "" {
return errors.New("config `listenerId` is required") return errors.New("config `listenerId` is required")
} }
@ -184,7 +181,7 @@ func (d *AliyunNLBDeployer) deployToListener(ctx context.Context, cloudCertId st
return nil return nil
} }
func (d *AliyunNLBDeployer) updateListenerCertificate(ctx context.Context, cloudListenerId string, cloudCertId string) error { func (d *DeployerProvider) updateListenerCertificate(ctx context.Context, cloudListenerId string, cloudCertId string) error {
// 查询监听的属性 // 查询监听的属性
// REF: https://help.aliyun.com/zh/slb/network-load-balancer/developer-reference/api-nlb-2022-04-30-getlistenerattribute // REF: https://help.aliyun.com/zh/slb/network-load-balancer/developer-reference/api-nlb-2022-04-30-getlistenerattribute
getListenerAttributeReq := &aliyunNlb.GetListenerAttributeRequest{ getListenerAttributeReq := &aliyunNlb.GetListenerAttributeRequest{
@ -248,7 +245,7 @@ func createSslUploader(accessKeyId, accessKeySecret, region string) (uploader.Up
} }
} }
uploader, err := uploaderp.New(&uploaderp.AliyunCASUploaderConfig{ uploader, err := uploadersp.NewUploader(&uploadersp.UploaderConfig{
AccessKeyId: accessKeyId, AccessKeyId: accessKeyId,
AccessKeySecret: accessKeySecret, AccessKeySecret: accessKeySecret,
Region: casRegion, Region: casRegion,

View File

@ -59,11 +59,11 @@ func TestDeploy(t *testing.T) {
fmt.Sprintf("LOADBALANCERID: %v", fLoadbalancerId), fmt.Sprintf("LOADBALANCERID: %v", fLoadbalancerId),
}, "\n")) }, "\n"))
deployer, err := provider.New(&provider.AliyunNLBDeployerConfig{ deployer, err := provider.NewDeployer(&provider.DeployerConfig{
AccessKeyId: fAccessKeyId, AccessKeyId: fAccessKeyId,
AccessKeySecret: fAccessKeySecret, AccessKeySecret: fAccessKeySecret,
Region: fRegion, Region: fRegion,
ResourceType: provider.DEPLOY_RESOURCE_LOADBALANCER, ResourceType: provider.RESOURCE_TYPE_LOADBALANCER,
LoadbalancerId: fLoadbalancerId, LoadbalancerId: fLoadbalancerId,
}) })
if err != nil { if err != nil {
@ -94,11 +94,11 @@ func TestDeploy(t *testing.T) {
fmt.Sprintf("LISTENERID: %v", fListenerId), fmt.Sprintf("LISTENERID: %v", fListenerId),
}, "\n")) }, "\n"))
deployer, err := provider.New(&provider.AliyunNLBDeployerConfig{ deployer, err := provider.NewDeployer(&provider.DeployerConfig{
AccessKeyId: fAccessKeyId, AccessKeyId: fAccessKeyId,
AccessKeySecret: fAccessKeySecret, AccessKeySecret: fAccessKeySecret,
Region: fRegion, Region: fRegion,
ResourceType: provider.DEPLOY_RESOURCE_LISTENER, ResourceType: provider.RESOURCE_TYPE_LISTENER,
ListenerId: fListenerId, ListenerId: fListenerId,
}) })
if err != nil { if err != nil {

View File

@ -0,0 +1,10 @@
package aliyunnlb
type ResourceType string
const (
// 资源类型:部署到指定负载均衡器。
RESOURCE_TYPE_LOADBALANCER = ResourceType("loadbalancer")
// 资源类型:部署到指定监听器。
RESOURCE_TYPE_LISTENER = ResourceType("listener")
)

View File

@ -1,10 +0,0 @@
package aliyunnlb
type DeployResourceType string
const (
// 资源类型:部署到指定负载均衡器。
DEPLOY_RESOURCE_LOADBALANCER = DeployResourceType("loadbalancer")
// 资源类型:部署到指定监听器。
DEPLOY_RESOURCE_LISTENER = DeployResourceType("listener")
)

View File

@ -12,7 +12,7 @@ import (
"github.com/usual2970/certimate/internal/pkg/core/logger" "github.com/usual2970/certimate/internal/pkg/core/logger"
) )
type AliyunOSSDeployerConfig struct { type DeployerConfig struct {
// 阿里云 AccessKeyId。 // 阿里云 AccessKeyId。
AccessKeyId string `json:"accessKeyId"` AccessKeyId string `json:"accessKeyId"`
// 阿里云 AccessKeySecret。 // 阿里云 AccessKeySecret。
@ -25,25 +25,17 @@ type AliyunOSSDeployerConfig struct {
Domain string `json:"domain"` Domain string `json:"domain"`
} }
type AliyunOSSDeployer struct { type DeployerProvider struct {
config *AliyunOSSDeployerConfig config *DeployerConfig
logger logger.Logger logger logger.Logger
sdkClient *oss.Client sdkClient *oss.Client
} }
var _ deployer.Deployer = (*AliyunOSSDeployer)(nil) var _ deployer.Deployer = (*DeployerProvider)(nil)
func New(config *AliyunOSSDeployerConfig) (*AliyunOSSDeployer, error) { func NewDeployer(config *DeployerConfig) (*DeployerProvider, error) {
return NewWithLogger(config, logger.NewNilLogger())
}
func NewWithLogger(config *AliyunOSSDeployerConfig, logger logger.Logger) (*AliyunOSSDeployer, error) {
if config == nil { if config == nil {
return nil, errors.New("config is nil") panic("config is nil")
}
if logger == nil {
return nil, errors.New("logger is nil")
} }
client, err := createSdkClient(config.AccessKeyId, config.AccessKeySecret, config.Region) client, err := createSdkClient(config.AccessKeyId, config.AccessKeySecret, config.Region)
@ -51,14 +43,19 @@ func NewWithLogger(config *AliyunOSSDeployerConfig, logger logger.Logger) (*Aliy
return nil, xerrors.Wrap(err, "failed to create sdk client") return nil, xerrors.Wrap(err, "failed to create sdk client")
} }
return &AliyunOSSDeployer{ return &DeployerProvider{
logger: logger,
config: config, config: config,
logger: logger.NewNilLogger(),
sdkClient: client, sdkClient: client,
}, nil }, nil
} }
func (d *AliyunOSSDeployer) Deploy(ctx context.Context, certPem string, privkeyPem string) (*deployer.DeployResult, error) { func (d *DeployerProvider) WithLogger(logger logger.Logger) *DeployerProvider {
d.logger = logger
return d
}
func (d *DeployerProvider) Deploy(ctx context.Context, certPem string, privkeyPem string) (*deployer.DeployResult, error) {
if d.config.Bucket == "" { if d.config.Bucket == "" {
return nil, errors.New("config `bucket` is required") return nil, errors.New("config `bucket` is required")
} }

View File

@ -60,7 +60,7 @@ func TestDeploy(t *testing.T) {
fmt.Sprintf("DOMAIN: %v", fDomain), fmt.Sprintf("DOMAIN: %v", fDomain),
}, "\n")) }, "\n"))
deployer, err := provider.New(&provider.AliyunOSSDeployerConfig{ deployer, err := provider.NewDeployer(&provider.DeployerConfig{
AccessKeyId: fAccessKeyId, AccessKeyId: fAccessKeyId,
AccessKeySecret: fAccessKeySecret, AccessKeySecret: fAccessKeySecret,
Region: fRegion, Region: fRegion,

View File

@ -0,0 +1,95 @@
package aliyunvod
import (
"context"
"fmt"
"time"
aliyunOpen "github.com/alibabacloud-go/darabonba-openapi/v2/client"
"github.com/alibabacloud-go/tea/tea"
aliyunVod "github.com/alibabacloud-go/vod-20170321/v4/client"
xerrors "github.com/pkg/errors"
"github.com/usual2970/certimate/internal/pkg/core/deployer"
"github.com/usual2970/certimate/internal/pkg/core/logger"
)
type DeployerConfig struct {
// 阿里云 AccessKeyId。
AccessKeyId string `json:"accessKeyId"`
// 阿里云 AccessKeySecret。
AccessKeySecret string `json:"accessKeySecret"`
// 阿里云地域。
Region string `json:"region"`
// 点播加速域名(不支持泛域名)。
Domain string `json:"domain"`
}
type DeployerProvider struct {
config *DeployerConfig
logger logger.Logger
sdkClient *aliyunVod.Client
}
var _ deployer.Deployer = (*DeployerProvider)(nil)
func NewDeployer(config *DeployerConfig) (*DeployerProvider, error) {
if config == nil {
panic("config is nil")
}
client, err := createSdkClient(config.AccessKeyId, config.AccessKeySecret, config.Region)
if err != nil {
return nil, xerrors.Wrap(err, "failed to create sdk client")
}
return &DeployerProvider{
config: config,
logger: logger.NewNilLogger(),
sdkClient: client,
}, nil
}
func (d *DeployerProvider) WithLogger(logger logger.Logger) *DeployerProvider {
d.logger = logger
return d
}
func (d *DeployerProvider) Deploy(ctx context.Context, certPem string, privkeyPem string) (*deployer.DeployResult, error) {
// 设置域名证书
// REF: https://help.aliyun.com/zh/vod/developer-reference/api-vod-2017-03-21-setvoddomainsslcertificate
setVodDomainSSLCertificateReq := &aliyunVod.SetVodDomainSSLCertificateRequest{
DomainName: tea.String(d.config.Domain),
CertName: tea.String(fmt.Sprintf("certimate-%d", time.Now().UnixMilli())),
CertType: tea.String("upload"),
SSLProtocol: tea.String("on"),
SSLPub: tea.String(certPem),
SSLPri: tea.String(privkeyPem),
}
setVodDomainSSLCertificateResp, err := d.sdkClient.SetVodDomainSSLCertificate(setVodDomainSSLCertificateReq)
if err != nil {
return nil, xerrors.Wrap(err, "failed to execute sdk request 'live.SetVodDomainSSLCertificate'")
} else {
d.logger.Logt("已设置域名证书", setVodDomainSSLCertificateResp)
}
return &deployer.DeployResult{}, nil
}
func createSdkClient(accessKeyId, accessKeySecret, region string) (*aliyunVod.Client, error) {
// 接入点一览 https://help.aliyun.com/zh/vod/developer-reference/api-vod-2017-03-21-endpoint
endpoint := fmt.Sprintf("vod.%s.aliyuncs.com", region)
config := &aliyunOpen.Config{
AccessKeyId: tea.String(accessKeyId),
AccessKeySecret: tea.String(accessKeySecret),
Endpoint: tea.String(endpoint),
}
client, err := aliyunVod.NewClient(config)
if err != nil {
return nil, err
}
return client, nil
}

View File

@ -0,0 +1,80 @@
package aliyunvod_test
import (
"context"
"flag"
"fmt"
"os"
"strings"
"testing"
provider "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/aliyun-vod"
)
var (
fInputCertPath string
fInputKeyPath string
fAccessKeyId string
fAccessKeySecret string
fRegion string
fDomain string
)
func init() {
argsPrefix := "CERTIMATE_DEPLOYER_ALIYUNVOD_"
flag.StringVar(&fInputCertPath, argsPrefix+"INPUTCERTPATH", "", "")
flag.StringVar(&fInputKeyPath, argsPrefix+"INPUTKEYPATH", "", "")
flag.StringVar(&fAccessKeyId, argsPrefix+"ACCESSKEYID", "", "")
flag.StringVar(&fAccessKeySecret, argsPrefix+"ACCESSKEYSECRET", "", "")
flag.StringVar(&fRegion, argsPrefix+"REGION", "", "")
flag.StringVar(&fDomain, argsPrefix+"DOMAIN", "", "")
}
/*
Shell command to run this test:
go test -v ./aliyun_vod_test.go -args \
--CERTIMATE_DEPLOYER_ALIYUNVOD_INPUTCERTPATH="/path/to/your-input-cert.pem" \
--CERTIMATE_DEPLOYER_ALIYUNVOD_INPUTKEYPATH="/path/to/your-input-key.pem" \
--CERTIMATE_DEPLOYER_ALIYUNVOD_ACCESSKEYID="your-access-key-id" \
--CERTIMATE_DEPLOYER_ALIYUNVOD_ACCESSKEYSECRET="your-access-key-secret" \
--CERTIMATE_DEPLOYER_ALIYUNVOD_REGION="cn-hangzhou" \
--CERTIMATE_DEPLOYER_ALIYUNVOD_DOMAIN="example.com"
*/
func TestDeploy(t *testing.T) {
flag.Parse()
t.Run("Deploy", func(t *testing.T) {
t.Log(strings.Join([]string{
"args:",
fmt.Sprintf("INPUTCERTPATH: %v", fInputCertPath),
fmt.Sprintf("INPUTKEYPATH: %v", fInputKeyPath),
fmt.Sprintf("ACCESSKEYID: %v", fAccessKeyId),
fmt.Sprintf("ACCESSKEYSECRET: %v", fAccessKeySecret),
fmt.Sprintf("REGION: %v", fRegion),
fmt.Sprintf("DOMAIN: %v", fDomain),
}, "\n"))
deployer, err := provider.NewDeployer(&provider.DeployerConfig{
AccessKeyId: fAccessKeyId,
AccessKeySecret: fAccessKeySecret,
Region: fRegion,
Domain: fDomain,
})
if err != nil {
t.Errorf("err: %+v", err)
return
}
fInputCertData, _ := os.ReadFile(fInputCertPath)
fInputKeyData, _ := os.ReadFile(fInputKeyPath)
res, err := deployer.Deploy(context.Background(), string(fInputCertData), string(fInputKeyData))
if err != nil {
t.Errorf("err: %+v", err)
return
}
t.Logf("ok: %v", res)
})
}

View File

@ -14,10 +14,10 @@ import (
"github.com/usual2970/certimate/internal/pkg/core/deployer" "github.com/usual2970/certimate/internal/pkg/core/deployer"
"github.com/usual2970/certimate/internal/pkg/core/logger" "github.com/usual2970/certimate/internal/pkg/core/logger"
"github.com/usual2970/certimate/internal/pkg/core/uploader" "github.com/usual2970/certimate/internal/pkg/core/uploader"
uploaderp "github.com/usual2970/certimate/internal/pkg/core/uploader/providers/aliyun-cas" uploadersp "github.com/usual2970/certimate/internal/pkg/core/uploader/providers/aliyun-cas"
) )
type AliyunWAFDeployerConfig struct { type DeployerConfig struct {
// 阿里云 AccessKeyId。 // 阿里云 AccessKeyId。
AccessKeyId string `json:"accessKeyId"` AccessKeyId string `json:"accessKeyId"`
// 阿里云 AccessKeySecret。 // 阿里云 AccessKeySecret。
@ -28,26 +28,18 @@ type AliyunWAFDeployerConfig struct {
InstanceId string `json:"instanceId"` InstanceId string `json:"instanceId"`
} }
type AliyunWAFDeployer struct { type DeployerProvider struct {
config *AliyunWAFDeployerConfig config *DeployerConfig
logger logger.Logger logger logger.Logger
sdkClient *aliyunWaf.Client sdkClient *aliyunWaf.Client
sslUploader uploader.Uploader sslUploader uploader.Uploader
} }
var _ deployer.Deployer = (*AliyunWAFDeployer)(nil) var _ deployer.Deployer = (*DeployerProvider)(nil)
func New(config *AliyunWAFDeployerConfig) (*AliyunWAFDeployer, error) { func NewDeployer(config *DeployerConfig) (*DeployerProvider, error) {
return NewWithLogger(config, logger.NewNilLogger())
}
func NewWithLogger(config *AliyunWAFDeployerConfig, logger logger.Logger) (*AliyunWAFDeployer, error) {
if config == nil { if config == nil {
return nil, errors.New("config is nil") panic("config is nil")
}
if logger == nil {
return nil, errors.New("logger is nil")
} }
client, err := createSdkClient(config.AccessKeyId, config.AccessKeySecret, config.Region) client, err := createSdkClient(config.AccessKeyId, config.AccessKeySecret, config.Region)
@ -60,15 +52,20 @@ func NewWithLogger(config *AliyunWAFDeployerConfig, logger logger.Logger) (*Aliy
return nil, xerrors.Wrap(err, "failed to create ssl uploader") return nil, xerrors.Wrap(err, "failed to create ssl uploader")
} }
return &AliyunWAFDeployer{ return &DeployerProvider{
logger: logger,
config: config, config: config,
logger: logger.NewNilLogger(),
sdkClient: client, sdkClient: client,
sslUploader: uploader, sslUploader: uploader,
}, nil }, nil
} }
func (d *AliyunWAFDeployer) Deploy(ctx context.Context, certPem string, privkeyPem string) (*deployer.DeployResult, error) { func (d *DeployerProvider) WithLogger(logger logger.Logger) *DeployerProvider {
d.logger = logger
return d
}
func (d *DeployerProvider) Deploy(ctx context.Context, certPem string, privkeyPem string) (*deployer.DeployResult, error) {
if d.config.InstanceId == "" { if d.config.InstanceId == "" {
return nil, errors.New("config `instanceId` is required") return nil, errors.New("config `instanceId` is required")
} }
@ -142,7 +139,7 @@ func createSslUploader(accessKeyId, accessKeySecret, region string) (uploader.Up
} }
} }
uploader, err := uploaderp.New(&uploaderp.AliyunCASUploaderConfig{ uploader, err := uploadersp.NewUploader(&uploadersp.UploaderConfig{
AccessKeyId: accessKeyId, AccessKeyId: accessKeyId,
AccessKeySecret: accessKeySecret, AccessKeySecret: accessKeySecret,
Region: casRegion, Region: casRegion,

View File

@ -56,7 +56,7 @@ func TestDeploy(t *testing.T) {
fmt.Sprintf("INSTANCEID: %v", fInstanceId), fmt.Sprintf("INSTANCEID: %v", fInstanceId),
}, "\n")) }, "\n"))
deployer, err := provider.New(&provider.AliyunWAFDeployerConfig{ deployer, err := provider.NewDeployer(&provider.DeployerConfig{
AccessKeyId: fAccessKeyId, AccessKeyId: fAccessKeyId,
AccessKeySecret: fAccessKeySecret, AccessKeySecret: fAccessKeySecret,
Region: fRegion, Region: fRegion,

View File

@ -14,10 +14,10 @@ import (
"github.com/usual2970/certimate/internal/pkg/core/deployer" "github.com/usual2970/certimate/internal/pkg/core/deployer"
"github.com/usual2970/certimate/internal/pkg/core/logger" "github.com/usual2970/certimate/internal/pkg/core/logger"
"github.com/usual2970/certimate/internal/pkg/core/uploader" "github.com/usual2970/certimate/internal/pkg/core/uploader"
uploaderp "github.com/usual2970/certimate/internal/pkg/core/uploader/providers/aws-acm" uploadersp "github.com/usual2970/certimate/internal/pkg/core/uploader/providers/aws-acm"
) )
type AWSCloudFrontDeployerConfig struct { type DeployerConfig struct {
// AWS AccessKeyId。 // AWS AccessKeyId。
AccessKeyId string `json:"accessKeyId"` AccessKeyId string `json:"accessKeyId"`
// AWS SecretAccessKey。 // AWS SecretAccessKey。
@ -28,26 +28,18 @@ type AWSCloudFrontDeployerConfig struct {
DistributionId string `json:"distributionId"` DistributionId string `json:"distributionId"`
} }
type AWSCloudFrontDeployer struct { type DeployerProvider struct {
config *AWSCloudFrontDeployerConfig config *DeployerConfig
logger logger.Logger logger logger.Logger
sdkClient *awsCf.Client sdkClient *awsCf.Client
sslUploader uploader.Uploader sslUploader uploader.Uploader
} }
var _ deployer.Deployer = (*AWSCloudFrontDeployer)(nil) var _ deployer.Deployer = (*DeployerProvider)(nil)
func New(config *AWSCloudFrontDeployerConfig) (*AWSCloudFrontDeployer, error) { func NewDeployer(config *DeployerConfig) (*DeployerProvider, error) {
return NewWithLogger(config, logger.NewNilLogger())
}
func NewWithLogger(config *AWSCloudFrontDeployerConfig, logger logger.Logger) (*AWSCloudFrontDeployer, error) {
if config == nil { if config == nil {
return nil, errors.New("config is nil") panic("config is nil")
}
if logger == nil {
return nil, errors.New("logger is nil")
} }
client, err := createSdkClient(config.AccessKeyId, config.SecretAccessKey, config.Region) client, err := createSdkClient(config.AccessKeyId, config.SecretAccessKey, config.Region)
@ -55,7 +47,7 @@ func NewWithLogger(config *AWSCloudFrontDeployerConfig, logger logger.Logger) (*
return nil, xerrors.Wrap(err, "failed to create sdk client") return nil, xerrors.Wrap(err, "failed to create sdk client")
} }
uploader, err := uploaderp.New(&uploaderp.AWSCertificateManagerUploaderConfig{ uploader, err := uploadersp.NewUploader(&uploadersp.UploaderConfig{
AccessKeyId: config.AccessKeyId, AccessKeyId: config.AccessKeyId,
SecretAccessKey: config.SecretAccessKey, SecretAccessKey: config.SecretAccessKey,
Region: config.Region, Region: config.Region,
@ -64,15 +56,20 @@ func NewWithLogger(config *AWSCloudFrontDeployerConfig, logger logger.Logger) (*
return nil, xerrors.Wrap(err, "failed to create ssl uploader") return nil, xerrors.Wrap(err, "failed to create ssl uploader")
} }
return &AWSCloudFrontDeployer{ return &DeployerProvider{
logger: logger,
config: config, config: config,
logger: logger.NewNilLogger(),
sdkClient: client, sdkClient: client,
sslUploader: uploader, sslUploader: uploader,
}, nil }, nil
} }
func (d *AWSCloudFrontDeployer) Deploy(ctx context.Context, certPem string, privkeyPem string) (*deployer.DeployResult, error) { func (d *DeployerProvider) WithLogger(logger logger.Logger) *DeployerProvider {
d.logger = logger
return d
}
func (d *DeployerProvider) Deploy(ctx context.Context, certPem string, privkeyPem string) (*deployer.DeployResult, error) {
if d.config.DistributionId == "" { if d.config.DistributionId == "" {
return nil, errors.New("config `distribuitionId` is required") return nil, errors.New("config `distribuitionId` is required")
} }

View File

@ -56,11 +56,11 @@ func TestDeploy(t *testing.T) {
fmt.Sprintf("DISTRIBUTIONID: %v", fDistribuitionId), fmt.Sprintf("DISTRIBUTIONID: %v", fDistribuitionId),
}, "\n")) }, "\n"))
deployer, err := provider.New(&provider.AWSCloudFrontDeployerConfig{ deployer, err := provider.NewDeployer(&provider.DeployerConfig{
AccessKeyId: fAccessKeyId, AccessKeyId: fAccessKeyId,
SecretAccessKey: fSecretAccessKey, SecretAccessKey: fSecretAccessKey,
Region: fRegion, Region: fRegion,
DistribuitionId: fDistribuitionId, DistributionId: fDistribuitionId,
}) })
if err != nil { if err != nil {
t.Errorf("err: %+v", err) t.Errorf("err: %+v", err)

View File

@ -2,7 +2,6 @@
import ( import (
"context" "context"
"errors"
"fmt" "fmt"
"time" "time"
@ -14,7 +13,7 @@ import (
"github.com/usual2970/certimate/internal/pkg/core/logger" "github.com/usual2970/certimate/internal/pkg/core/logger"
) )
type BaiduCloudCDNDeployerConfig struct { type DeployerConfig struct {
// 百度智能云 AccessKeyId。 // 百度智能云 AccessKeyId。
AccessKeyId string `json:"accessKeyId"` AccessKeyId string `json:"accessKeyId"`
// 百度智能云 SecretAccessKey。 // 百度智能云 SecretAccessKey。
@ -23,25 +22,17 @@ type BaiduCloudCDNDeployerConfig struct {
Domain string `json:"domain"` Domain string `json:"domain"`
} }
type BaiduCloudCDNDeployer struct { type DeployerProvider struct {
config *BaiduCloudCDNDeployerConfig config *DeployerConfig
logger logger.Logger logger logger.Logger
sdkClient *bceCdn.Client sdkClient *bceCdn.Client
} }
var _ deployer.Deployer = (*BaiduCloudCDNDeployer)(nil) var _ deployer.Deployer = (*DeployerProvider)(nil)
func New(config *BaiduCloudCDNDeployerConfig) (*BaiduCloudCDNDeployer, error) { func NewDeployer(config *DeployerConfig) (*DeployerProvider, error) {
return NewWithLogger(config, logger.NewNilLogger())
}
func NewWithLogger(config *BaiduCloudCDNDeployerConfig, logger logger.Logger) (*BaiduCloudCDNDeployer, error) {
if config == nil { if config == nil {
return nil, errors.New("config is nil") panic("config is nil")
}
if logger == nil {
return nil, errors.New("logger is nil")
} }
client, err := createSdkClient(config.AccessKeyId, config.SecretAccessKey) client, err := createSdkClient(config.AccessKeyId, config.SecretAccessKey)
@ -49,14 +40,19 @@ func NewWithLogger(config *BaiduCloudCDNDeployerConfig, logger logger.Logger) (*
return nil, xerrors.Wrap(err, "failed to create sdk client") return nil, xerrors.Wrap(err, "failed to create sdk client")
} }
return &BaiduCloudCDNDeployer{ return &DeployerProvider{
logger: logger,
config: config, config: config,
logger: logger.NewNilLogger(),
sdkClient: client, sdkClient: client,
}, nil }, nil
} }
func (d *BaiduCloudCDNDeployer) Deploy(ctx context.Context, certPem string, privkeyPem string) (*deployer.DeployResult, error) { func (d *DeployerProvider) WithLogger(logger logger.Logger) *DeployerProvider {
d.logger = logger
return d
}
func (d *DeployerProvider) Deploy(ctx context.Context, certPem string, privkeyPem string) (*deployer.DeployResult, error) {
// 修改域名证书 // 修改域名证书
// REF: https://cloud.baidu.com/doc/CDN/s/qjzuz2hp8 // REF: https://cloud.baidu.com/doc/CDN/s/qjzuz2hp8
putCertResp, err := d.sdkClient.PutCert( putCertResp, err := d.sdkClient.PutCert(

View File

@ -52,7 +52,7 @@ func TestDeploy(t *testing.T) {
fmt.Sprintf("DOMAIN: %v", fDomain), fmt.Sprintf("DOMAIN: %v", fDomain),
}, "\n")) }, "\n"))
deployer, err := provider.New(&provider.BaiduCloudCDNDeployerConfig{ deployer, err := provider.NewDeployer(&provider.DeployerConfig{
AccessKeyId: fAccessKeyId, AccessKeyId: fAccessKeyId,
SecretAccessKey: fSecretAccessKey, SecretAccessKey: fSecretAccessKey,
Domain: fDomain, Domain: fDomain,

View File

@ -0,0 +1,117 @@
package baishancdn
import (
"context"
"errors"
"fmt"
"time"
xerrors "github.com/pkg/errors"
"github.com/usual2970/certimate/internal/pkg/core/deployer"
"github.com/usual2970/certimate/internal/pkg/core/logger"
bssdk "github.com/usual2970/certimate/internal/pkg/vendors/baishan-sdk"
)
type DeployerConfig struct {
// 白山云 API Token。
ApiToken string `json:"apiToken"`
// 加速域名(支持泛域名)。
Domain string `json:"domain"`
}
type DeployerProvider struct {
config *DeployerConfig
logger logger.Logger
sdkClient *bssdk.Client
}
var _ deployer.Deployer = (*DeployerProvider)(nil)
func NewDeployer(config *DeployerConfig) (*DeployerProvider, error) {
if config == nil {
panic("config is nil")
}
client, err := createSdkClient(config.ApiToken)
if err != nil {
return nil, xerrors.Wrap(err, "failed to create sdk client")
}
return &DeployerProvider{
config: config,
logger: logger.NewNilLogger(),
sdkClient: client,
}, nil
}
func (d *DeployerProvider) WithLogger(logger logger.Logger) *DeployerProvider {
d.logger = logger
return d
}
func (d *DeployerProvider) Deploy(ctx context.Context, certPem string, privkeyPem string) (*deployer.DeployResult, error) {
if d.config.Domain == "" {
return nil, errors.New("config `domain` is required")
}
// 查询域名配置
// REF: https://portal.baishancloud.com/track/document/api/1/1065
getDomainConfigReq := &bssdk.GetDomainConfigRequest{
Domains: d.config.Domain,
Config: "https",
}
getDomainConfigResp, err := d.sdkClient.GetDomainConfig(getDomainConfigReq)
if err != nil {
return nil, xerrors.Wrap(err, "failed to execute sdk request 'baishan.GetDomainConfig'")
} else if len(getDomainConfigResp.Data) == 0 {
return nil, errors.New("domain config not found")
} else {
d.logger.Logt("已查询到域名配置", getDomainConfigResp)
}
// 新增证书
// REF: https://portal.baishancloud.com/track/document/downloadPdf/1441
createCertificateReq := &bssdk.CreateCertificateRequest{
Certificate: certPem,
Key: privkeyPem,
Name: fmt.Sprintf("certimate_%d", time.Now().UnixMilli()),
}
createCertificateResp, err := d.sdkClient.CreateCertificate(createCertificateReq)
if err != nil {
return nil, xerrors.Wrap(err, "failed to execute sdk request 'baishan.CreateCertificate'")
} else {
d.logger.Logt("已新增证书", createCertificateResp)
}
// 设置域名配置
// REF: https://portal.baishancloud.com/track/document/api/1/1045
setDomainConfigReq := &bssdk.SetDomainConfigRequest{
Domains: d.config.Domain,
Config: &bssdk.DomainConfig{
Https: &bssdk.DomainConfigHttps{
CertId: createCertificateResp.Data.CertId,
ForceHttps: getDomainConfigResp.Data[0].Config.Https.ForceHttps,
EnableHttp2: getDomainConfigResp.Data[0].Config.Https.EnableHttp2,
EnableOcsp: getDomainConfigResp.Data[0].Config.Https.EnableOcsp,
},
},
}
setDomainConfigResp, err := d.sdkClient.SetDomainConfig(setDomainConfigReq)
if err != nil {
return nil, xerrors.Wrap(err, "failed to execute sdk request 'baishan.SetDomainConfig'")
} else {
d.logger.Logt("已设置域名配置", setDomainConfigResp)
}
return &deployer.DeployResult{}, nil
}
func createSdkClient(apiToken string) (*bssdk.Client, error) {
if apiToken == "" {
return nil, errors.New("invalid baishan api token")
}
client := bssdk.NewClient(apiToken)
return client, nil
}

View File

@ -0,0 +1,70 @@
package baishancdn_test
import (
"context"
"flag"
"fmt"
"os"
"strings"
"testing"
provider "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/baishan-cdn"
)
var (
fInputCertPath string
fInputKeyPath string
fApiToken string
fDomain string
)
func init() {
argsPrefix := "CERTIMATE_DEPLOYER_BAISHANCDN_"
flag.StringVar(&fInputCertPath, argsPrefix+"INPUTCERTPATH", "", "")
flag.StringVar(&fInputKeyPath, argsPrefix+"INPUTKEYPATH", "", "")
flag.StringVar(&fApiToken, argsPrefix+"APITOKEN", "", "")
flag.StringVar(&fDomain, argsPrefix+"DOMAIN", "", "")
}
/*
Shell command to run this test:
go test -v ./baishan_cdn_test.go -args \
--CERTIMATE_DEPLOYER_BAISHANCDN_INPUTCERTPATH="/path/to/your-input-cert.pem" \
--CERTIMATE_DEPLOYER_BAISHANCDN_INPUTKEYPATH="/path/to/your-input-key.pem" \
--CERTIMATE_DEPLOYER_BAISHANCDN_APITOKEN="your-api-token" \
--CERTIMATE_DEPLOYER_BAISHANCDN_DOMAIN="example.com"
*/
func TestDeploy(t *testing.T) {
flag.Parse()
t.Run("Deploy", func(t *testing.T) {
t.Log(strings.Join([]string{
"args:",
fmt.Sprintf("INPUTCERTPATH: %v", fInputCertPath),
fmt.Sprintf("INPUTKEYPATH: %v", fInputKeyPath),
fmt.Sprintf("APITOKEN: %v", fApiToken),
fmt.Sprintf("DOMAIN: %v", fDomain),
}, "\n"))
deployer, err := provider.NewDeployer(&provider.DeployerConfig{
ApiToken: fApiToken,
Domain: fDomain,
})
if err != nil {
t.Errorf("err: %+v", err)
return
}
fInputCertData, _ := os.ReadFile(fInputCertPath)
fInputKeyData, _ := os.ReadFile(fInputKeyPath)
res, err := deployer.Deploy(context.Background(), string(fInputCertData), string(fInputKeyData))
if err != nil {
t.Errorf("err: %+v", err)
return
}
t.Logf("ok: %v", res)
})
}

View File

@ -0,0 +1,93 @@
package baotapanelconsole
import (
"context"
"errors"
"net/url"
xerrors "github.com/pkg/errors"
"github.com/usual2970/certimate/internal/pkg/core/deployer"
"github.com/usual2970/certimate/internal/pkg/core/logger"
btsdk "github.com/usual2970/certimate/internal/pkg/vendors/btpanel-sdk"
)
type DeployerConfig struct {
// 宝塔面板地址。
ApiUrl string `json:"apiUrl"`
// 宝塔面板接口密钥。
ApiKey string `json:"apiKey"`
// 是否自动重启。
AutoRestart bool `json:"autoRestart"`
}
type DeployerProvider struct {
config *DeployerConfig
logger logger.Logger
sdkClient *btsdk.Client
}
var _ deployer.Deployer = (*DeployerProvider)(nil)
func NewDeployer(config *DeployerConfig) (*DeployerProvider, error) {
if config == nil {
panic("config is nil")
}
client, err := createSdkClient(config.ApiUrl, config.ApiKey)
if err != nil {
return nil, xerrors.Wrap(err, "failed to create sdk client")
}
return &DeployerProvider{
config: config,
logger: logger.NewNilLogger(),
sdkClient: client,
}, nil
}
func (d *DeployerProvider) WithLogger(logger logger.Logger) *DeployerProvider {
d.logger = logger
return d
}
func (d *DeployerProvider) Deploy(ctx context.Context, certPem string, privkeyPem string) (*deployer.DeployResult, error) {
// 设置面板 SSL 证书
configSavePanelSSLReq := &btsdk.ConfigSavePanelSSLRequest{
PrivateKey: privkeyPem,
Certificate: certPem,
}
configSavePanelSSLResp, err := d.sdkClient.ConfigSavePanelSSL(configSavePanelSSLReq)
if err != nil {
return nil, xerrors.Wrap(err, "failed to execute sdk request 'bt.ConfigSavePanelSSL'")
} else {
d.logger.Logt("已设置面板 SSL 证书", configSavePanelSSLResp)
}
if d.config.AutoRestart {
// 重启面板
systemServiceAdminReq := &btsdk.SystemServiceAdminRequest{
Name: "nginx",
Type: "restart",
}
_, err := d.sdkClient.SystemServiceAdmin(systemServiceAdminReq)
if err != nil {
return nil, xerrors.Wrap(err, "failed to execute sdk request 'bt.SystemServiceAdmin'")
}
}
return &deployer.DeployResult{}, nil
}
func createSdkClient(apiUrl, apiKey string) (*btsdk.Client, error) {
if _, err := url.Parse(apiUrl); err != nil {
return nil, errors.New("invalid baota api url")
}
if apiKey == "" {
return nil, errors.New("invalid baota api key")
}
client := btsdk.NewClient(apiUrl, apiKey)
return client, nil
}

View File

@ -0,0 +1,70 @@
package baotapanelconsole_test
import (
"context"
"flag"
"fmt"
"os"
"strings"
"testing"
provider "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/baotapanel-console"
)
var (
fInputCertPath string
fInputKeyPath string
fApiUrl string
fApiKey string
)
func init() {
argsPrefix := "CERTIMATE_DEPLOYER_BAOTAPANELCONSOLE_"
flag.StringVar(&fInputCertPath, argsPrefix+"INPUTCERTPATH", "", "")
flag.StringVar(&fInputKeyPath, argsPrefix+"INPUTKEYPATH", "", "")
flag.StringVar(&fApiUrl, argsPrefix+"APIURL", "", "")
flag.StringVar(&fApiKey, argsPrefix+"APIKEY", "", "")
}
/*
Shell command to run this test:
go test -v ./baotapanel_console_test.go -args \
--CERTIMATE_DEPLOYER_BAOTAPANELCONSOLE_INPUTCERTPATH="/path/to/your-input-cert.pem" \
--CERTIMATE_DEPLOYER_BAOTAPANELCONSOLE_INPUTKEYPATH="/path/to/your-input-key.pem" \
--CERTIMATE_DEPLOYER_BAOTAPANELCONSOLE_APIURL="http://127.0.0.1:8888" \
--CERTIMATE_DEPLOYER_BAOTAPANELCONSOLE_APIKEY="your-api-key"
*/
func TestDeploy(t *testing.T) {
flag.Parse()
t.Run("Deploy", func(t *testing.T) {
t.Log(strings.Join([]string{
"args:",
fmt.Sprintf("INPUTCERTPATH: %v", fInputCertPath),
fmt.Sprintf("INPUTKEYPATH: %v", fInputKeyPath),
fmt.Sprintf("APIURL: %v", fApiUrl),
fmt.Sprintf("APIKEY: %v", fApiKey),
}, "\n"))
deployer, err := provider.NewDeployer(&provider.DeployerConfig{
ApiUrl: fApiUrl,
ApiKey: fApiKey,
})
if err != nil {
t.Errorf("err: %+v", err)
return
}
fInputCertData, _ := os.ReadFile(fInputCertPath)
fInputKeyData, _ := os.ReadFile(fInputKeyPath)
res, err := deployer.Deploy(context.Background(), string(fInputCertData), string(fInputKeyData))
if err != nil {
t.Errorf("err: %+v", err)
return
}
t.Logf("ok: %v", res)
})
}

View File

@ -3,42 +3,41 @@
import ( import (
"context" "context"
"errors" "errors"
"fmt"
"net/url"
xerrors "github.com/pkg/errors" xerrors "github.com/pkg/errors"
"github.com/usual2970/certimate/internal/pkg/core/deployer" "github.com/usual2970/certimate/internal/pkg/core/deployer"
"github.com/usual2970/certimate/internal/pkg/core/logger" "github.com/usual2970/certimate/internal/pkg/core/logger"
"github.com/usual2970/certimate/internal/pkg/utils/slices"
btsdk "github.com/usual2970/certimate/internal/pkg/vendors/btpanel-sdk" btsdk "github.com/usual2970/certimate/internal/pkg/vendors/btpanel-sdk"
) )
type BaotaPanelSiteDeployerConfig struct { type DeployerConfig struct {
// 宝塔面板地址。 // 宝塔面板地址。
ApiUrl string `json:"apiUrl"` ApiUrl string `json:"apiUrl"`
// 宝塔面板接口密钥。 // 宝塔面板接口密钥。
ApiKey string `json:"apiKey"` ApiKey string `json:"apiKey"`
// 站点名称 // 站点类型。
SiteName string `json:"siteName"` SiteType string `json:"siteType"`
// 站点名称(单个)。
SiteName string `json:"siteName,omitempty"`
// 站点名称(多个)。
SiteNames []string `json:"siteNames,omitempty"`
} }
type BaotaPanelSiteDeployer struct { type DeployerProvider struct {
config *BaotaPanelSiteDeployerConfig config *DeployerConfig
logger logger.Logger logger logger.Logger
sdkClient *btsdk.BaoTaPanelClient sdkClient *btsdk.Client
} }
var _ deployer.Deployer = (*BaotaPanelSiteDeployer)(nil) var _ deployer.Deployer = (*DeployerProvider)(nil)
func New(config *BaotaPanelSiteDeployerConfig) (*BaotaPanelSiteDeployer, error) { func NewDeployer(config *DeployerConfig) (*DeployerProvider, error) {
return NewWithLogger(config, logger.NewNilLogger())
}
func NewWithLogger(config *BaotaPanelSiteDeployerConfig, logger logger.Logger) (*BaotaPanelSiteDeployer, error) {
if config == nil { if config == nil {
return nil, errors.New("config is nil") panic("config is nil")
}
if logger == nil {
return nil, errors.New("logger is nil")
} }
client, err := createSdkClient(config.ApiUrl, config.ApiKey) client, err := createSdkClient(config.ApiUrl, config.ApiKey)
@ -46,36 +45,92 @@ func NewWithLogger(config *BaotaPanelSiteDeployerConfig, logger logger.Logger) (
return nil, xerrors.Wrap(err, "failed to create sdk client") return nil, xerrors.Wrap(err, "failed to create sdk client")
} }
return &BaotaPanelSiteDeployer{ return &DeployerProvider{
logger: logger,
config: config, config: config,
logger: logger.NewNilLogger(),
sdkClient: client, sdkClient: client,
}, nil }, nil
} }
func (d *BaotaPanelSiteDeployer) Deploy(ctx context.Context, certPem string, privkeyPem string) (*deployer.DeployResult, error) { func (d *DeployerProvider) WithLogger(logger logger.Logger) *DeployerProvider {
d.logger = logger
return d
}
func (d *DeployerProvider) Deploy(ctx context.Context, certPem string, privkeyPem string) (*deployer.DeployResult, error) {
switch d.config.SiteType {
case "php":
{
if d.config.SiteName == "" { if d.config.SiteName == "" {
return nil, errors.New("config `siteName` is required") return nil, errors.New("config `siteName` is required")
} }
// 设置站点 SSL 证书 // 设置站点 SSL 证书
setSiteSSLReq := &btsdk.SetSiteSSLRequest{ siteSetSSLReq := &btsdk.SiteSetSSLRequest{
SiteName: d.config.SiteName, SiteName: d.config.SiteName,
Type: "1", Type: "0",
Key: privkeyPem, Certificate: certPem,
Csr: certPem, PrivateKey: privkeyPem,
} }
setSiteSSLResp, err := d.sdkClient.SetSiteSSL(setSiteSSLReq) siteSetSSLResp, err := d.sdkClient.SiteSetSSL(siteSetSSLReq)
if err != nil { if err != nil {
return nil, xerrors.Wrap(err, "failed to execute sdk request 'bt.SetSiteSSL'") return nil, xerrors.Wrap(err, "failed to execute sdk request 'bt.SiteSetSSL'")
} else {
d.logger.Logt("已设置站点证书", siteSetSSLResp)
}
} }
d.logger.Logt("已设置站点 SSL 证书", setSiteSSLResp) case "other":
{
if len(d.config.SiteNames) == 0 {
return nil, errors.New("config `siteNames` is required")
}
// 上传证书
sslCertSaveCertReq := &btsdk.SSLCertSaveCertRequest{
Certificate: certPem,
PrivateKey: privkeyPem,
}
sslCertSaveCertResp, err := d.sdkClient.SSLCertSaveCert(sslCertSaveCertReq)
if err != nil {
return nil, xerrors.Wrap(err, "failed to execute sdk request 'bt.SSLCertSaveCert'")
} else {
d.logger.Logt("已上传证书", sslCertSaveCertResp)
}
// 设置站点证书
sslSetBatchCertToSiteReq := &btsdk.SSLSetBatchCertToSiteRequest{
BatchInfo: slices.Map(d.config.SiteNames, func(siteName string) *btsdk.SSLSetBatchCertToSiteRequestBatchInfo {
return &btsdk.SSLSetBatchCertToSiteRequestBatchInfo{
SiteName: siteName,
SSLHash: sslCertSaveCertResp.SSLHash,
}
}),
}
sslSetBatchCertToSiteResp, err := d.sdkClient.SSLSetBatchCertToSite(sslSetBatchCertToSiteReq)
if err != nil {
return nil, xerrors.Wrap(err, "failed to execute sdk request 'bt.SSLSetBatchCertToSite'")
} else {
d.logger.Logt("已设置站点证书", sslSetBatchCertToSiteResp)
}
}
default:
return nil, fmt.Errorf("unsupported site type: %s", d.config.SiteType)
}
return &deployer.DeployResult{}, nil return &deployer.DeployResult{}, nil
} }
func createSdkClient(apiUrl, apiKey string) (*btsdk.BaoTaPanelClient, error) { func createSdkClient(apiUrl, apiKey string) (*btsdk.Client, error) {
client := btsdk.NewBaoTaPanelClient(apiUrl, apiKey) if _, err := url.Parse(apiUrl); err != nil {
return nil, errors.New("invalid baota api url")
}
if apiKey == "" {
return nil, errors.New("invalid baota api key")
}
client := btsdk.NewClient(apiUrl, apiKey)
return client, nil return client, nil
} }

View File

@ -16,6 +16,7 @@ var (
fInputKeyPath string fInputKeyPath string
fApiUrl string fApiUrl string
fApiKey string fApiKey string
fSiteType string
fSiteName string fSiteName string
) )
@ -26,6 +27,7 @@ func init() {
flag.StringVar(&fInputKeyPath, argsPrefix+"INPUTKEYPATH", "", "") flag.StringVar(&fInputKeyPath, argsPrefix+"INPUTKEYPATH", "", "")
flag.StringVar(&fApiUrl, argsPrefix+"APIURL", "", "") flag.StringVar(&fApiUrl, argsPrefix+"APIURL", "", "")
flag.StringVar(&fApiKey, argsPrefix+"APIKEY", "", "") flag.StringVar(&fApiKey, argsPrefix+"APIKEY", "", "")
flag.StringVar(&fSiteType, argsPrefix+"SITETYPE", "", "")
flag.StringVar(&fSiteName, argsPrefix+"SITENAME", "", "") flag.StringVar(&fSiteName, argsPrefix+"SITENAME", "", "")
} }
@ -35,9 +37,10 @@ Shell command to run this test:
go test -v ./baotapanel_site_test.go -args \ go test -v ./baotapanel_site_test.go -args \
--CERTIMATE_DEPLOYER_BAOTAPANELSITE_INPUTCERTPATH="/path/to/your-input-cert.pem" \ --CERTIMATE_DEPLOYER_BAOTAPANELSITE_INPUTCERTPATH="/path/to/your-input-cert.pem" \
--CERTIMATE_DEPLOYER_BAOTAPANELSITE_INPUTKEYPATH="/path/to/your-input-key.pem" \ --CERTIMATE_DEPLOYER_BAOTAPANELSITE_INPUTKEYPATH="/path/to/your-input-key.pem" \
--CERTIMATE_DEPLOYER_BAOTAPANELSITE_APIURL="your-baota-panel-url" \ --CERTIMATE_DEPLOYER_BAOTAPANELSITE_APIURL="http://127.0.0.1:8888" \
--CERTIMATE_DEPLOYER_BAOTAPANELSITE_APIKEY="your-baota-panel-key" \ --CERTIMATE_DEPLOYER_BAOTAPANELSITE_APIKEY="your-api-key" \
--CERTIMATE_DEPLOYER_BAOTAPANELSITE_SITENAME="your-baota-site-name" --CERTIMATE_DEPLOYER_BAOTAPANELSITE_SITETYPE="php" \
--CERTIMATE_DEPLOYER_BAOTAPANELSITE_SITENAME="your-site-name"
*/ */
func TestDeploy(t *testing.T) { func TestDeploy(t *testing.T) {
flag.Parse() flag.Parse()
@ -49,13 +52,16 @@ func TestDeploy(t *testing.T) {
fmt.Sprintf("INPUTKEYPATH: %v", fInputKeyPath), fmt.Sprintf("INPUTKEYPATH: %v", fInputKeyPath),
fmt.Sprintf("APIURL: %v", fApiUrl), fmt.Sprintf("APIURL: %v", fApiUrl),
fmt.Sprintf("APIKEY: %v", fApiKey), fmt.Sprintf("APIKEY: %v", fApiKey),
fmt.Sprintf("SITETYPE: %v", fSiteType),
fmt.Sprintf("SITENAME: %v", fSiteName), fmt.Sprintf("SITENAME: %v", fSiteName),
}, "\n")) }, "\n"))
deployer, err := provider.New(&provider.BaotaPanelSiteDeployerConfig{ deployer, err := provider.NewDeployer(&provider.DeployerConfig{
ApiUrl: fApiUrl, ApiUrl: fApiUrl,
ApiKey: fApiKey, ApiKey: fApiKey,
SiteType: fSiteType,
SiteName: fSiteName, SiteName: fSiteName,
SiteNames: []string{fSiteName},
}) })
if err != nil { if err != nil {
t.Errorf("err: %+v", err) t.Errorf("err: %+v", err)

View File

@ -12,10 +12,10 @@ import (
"github.com/usual2970/certimate/internal/pkg/core/deployer" "github.com/usual2970/certimate/internal/pkg/core/deployer"
"github.com/usual2970/certimate/internal/pkg/core/logger" "github.com/usual2970/certimate/internal/pkg/core/logger"
"github.com/usual2970/certimate/internal/pkg/core/uploader" "github.com/usual2970/certimate/internal/pkg/core/uploader"
uploaderp "github.com/usual2970/certimate/internal/pkg/core/uploader/providers/byteplus-cdn" uploadersp "github.com/usual2970/certimate/internal/pkg/core/uploader/providers/byteplus-cdn"
) )
type BytePlusCDNDeployerConfig struct { type DeployerConfig struct {
// BytePlus AccessKey。 // BytePlus AccessKey。
AccessKey string `json:"accessKey"` AccessKey string `json:"accessKey"`
// BytePlus SecretKey。 // BytePlus SecretKey。
@ -24,33 +24,25 @@ type BytePlusCDNDeployerConfig struct {
Domain string `json:"domain"` Domain string `json:"domain"`
} }
type BytePlusCDNDeployer struct { type DeployerProvider struct {
config *BytePlusCDNDeployerConfig config *DeployerConfig
logger logger.Logger logger logger.Logger
sdkClient *bpCdn.CDN sdkClient *bpCdn.CDN
sslUploader uploader.Uploader sslUploader uploader.Uploader
} }
var _ deployer.Deployer = (*BytePlusCDNDeployer)(nil) var _ deployer.Deployer = (*DeployerProvider)(nil)
func New(config *BytePlusCDNDeployerConfig) (*BytePlusCDNDeployer, error) { func NewDeployer(config *DeployerConfig) (*DeployerProvider, error) {
return NewWithLogger(config, logger.NewNilLogger())
}
func NewWithLogger(config *BytePlusCDNDeployerConfig, logger logger.Logger) (*BytePlusCDNDeployer, error) {
if config == nil { if config == nil {
return nil, errors.New("config is nil") panic("config is nil")
}
if logger == nil {
return nil, errors.New("logger is nil")
} }
client := bpCdn.NewInstance() client := bpCdn.NewInstance()
client.Client.SetAccessKey(config.AccessKey) client.Client.SetAccessKey(config.AccessKey)
client.Client.SetSecretKey(config.SecretKey) client.Client.SetSecretKey(config.SecretKey)
uploader, err := uploaderp.New(&uploaderp.ByteplusCDNUploaderConfig{ uploader, err := uploadersp.NewUploader(&uploadersp.UploaderConfig{
AccessKey: config.AccessKey, AccessKey: config.AccessKey,
SecretKey: config.SecretKey, SecretKey: config.SecretKey,
}) })
@ -58,15 +50,20 @@ func NewWithLogger(config *BytePlusCDNDeployerConfig, logger logger.Logger) (*By
return nil, xerrors.Wrap(err, "failed to create ssl uploader") return nil, xerrors.Wrap(err, "failed to create ssl uploader")
} }
return &BytePlusCDNDeployer{ return &DeployerProvider{
logger: logger,
config: config, config: config,
logger: logger.NewNilLogger(),
sdkClient: client, sdkClient: client,
sslUploader: uploader, sslUploader: uploader,
}, nil }, nil
} }
func (d *BytePlusCDNDeployer) Deploy(ctx context.Context, certPem string, privkeyPem string) (*deployer.DeployResult, error) { func (d *DeployerProvider) WithLogger(logger logger.Logger) *DeployerProvider {
d.logger = logger
return d
}
func (d *DeployerProvider) Deploy(ctx context.Context, certPem string, privkeyPem string) (*deployer.DeployResult, error) {
// 上传证书到 CDN // 上传证书到 CDN
upres, err := d.sslUploader.Upload(ctx, certPem, privkeyPem) upres, err := d.sslUploader.Upload(ctx, certPem, privkeyPem)
if err != nil { if err != nil {

View File

@ -52,7 +52,7 @@ func TestDeploy(t *testing.T) {
fmt.Sprintf("DOMAIN: %v", fDomain), fmt.Sprintf("DOMAIN: %v", fDomain),
}, "\n")) }, "\n"))
deployer, err := provider.New(&provider.BytePlusCDNDeployerConfig{ deployer, err := provider.NewDeployer(&provider.DeployerConfig{
AccessKey: fAccessKey, AccessKey: fAccessKey,
SecretKey: fSecretKey, SecretKey: fSecretKey,
Domain: fDomain, Domain: fDomain,

View File

@ -0,0 +1,72 @@
package cachefly
import (
"context"
"errors"
xerrors "github.com/pkg/errors"
"github.com/usual2970/certimate/internal/pkg/core/deployer"
"github.com/usual2970/certimate/internal/pkg/core/logger"
cfsdk "github.com/usual2970/certimate/internal/pkg/vendors/cachefly-sdk"
)
type DeployerConfig struct {
// CacheFly API Token。
ApiToken string `json:"apiToken"`
}
type DeployerProvider struct {
config *DeployerConfig
logger logger.Logger
sdkClient *cfsdk.Client
}
var _ deployer.Deployer = (*DeployerProvider)(nil)
func NewDeployer(config *DeployerConfig) (*DeployerProvider, error) {
if config == nil {
panic("config is nil")
}
client, err := createSdkClient(config.ApiToken)
if err != nil {
return nil, xerrors.Wrap(err, "failed to create sdk client")
}
return &DeployerProvider{
config: config,
logger: logger.NewNilLogger(),
sdkClient: client,
}, nil
}
func (d *DeployerProvider) WithLogger(logger logger.Logger) *DeployerProvider {
d.logger = logger
return d
}
func (d *DeployerProvider) Deploy(ctx context.Context, certPem string, privkeyPem string) (*deployer.DeployResult, error) {
// 上传证书
createCertificateReq := &cfsdk.CreateCertificateRequest{
Certificate: certPem,
CertificateKey: privkeyPem,
}
createCertificateResp, err := d.sdkClient.CreateCertificate(createCertificateReq)
if err != nil {
return nil, xerrors.Wrap(err, "failed to execute sdk request 'cachefly.CreateCertificate'")
} else {
d.logger.Logt("已上传证书", createCertificateResp)
}
return &deployer.DeployResult{}, nil
}
func createSdkClient(apiToken string) (*cfsdk.Client, error) {
if apiToken == "" {
return nil, errors.New("invalid cachefly api token")
}
client := cfsdk.NewClient(apiToken)
return client, nil
}

View File

@ -0,0 +1,65 @@
package cachefly_test
import (
"context"
"flag"
"fmt"
"os"
"strings"
"testing"
provider "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/cachefly"
)
var (
fInputCertPath string
fInputKeyPath string
fApiToken string
)
func init() {
argsPrefix := "CERTIMATE_DEPLOYER_CACHEFLY_"
flag.StringVar(&fInputCertPath, argsPrefix+"INPUTCERTPATH", "", "")
flag.StringVar(&fInputKeyPath, argsPrefix+"INPUTKEYPATH", "", "")
flag.StringVar(&fApiToken, argsPrefix+"APITOKEN", "", "")
}
/*
Shell command to run this test:
go test -v ./cachefly_test.go -args \
--CERTIMATE_DEPLOYER_CACHEFLY_INPUTCERTPATH="/path/to/your-input-cert.pem" \
--CERTIMATE_DEPLOYER_CACHEFLY_INPUTKEYPATH="/path/to/your-input-key.pem" \
--CERTIMATE_DEPLOYER_CACHEFLY_APITOKEN="your-api-token"
*/
func TestDeploy(t *testing.T) {
flag.Parse()
t.Run("Deploy", func(t *testing.T) {
t.Log(strings.Join([]string{
"args:",
fmt.Sprintf("INPUTCERTPATH: %v", fInputCertPath),
fmt.Sprintf("INPUTKEYPATH: %v", fInputKeyPath),
fmt.Sprintf("APITOKEN: %v", fApiToken),
}, "\n"))
deployer, err := provider.NewDeployer(&provider.DeployerConfig{
ApiToken: fApiToken,
})
if err != nil {
t.Errorf("err: %+v", err)
return
}
fInputCertData, _ := os.ReadFile(fInputCertPath)
fInputKeyData, _ := os.ReadFile(fInputKeyPath)
res, err := deployer.Deploy(context.Background(), string(fInputCertData), string(fInputKeyData))
if err != nil {
t.Errorf("err: %+v", err)
return
}
t.Logf("ok: %v", res)
})
}

View File

@ -0,0 +1,177 @@
package cdnfly
import (
"context"
"encoding/json"
"errors"
"fmt"
"net/url"
"time"
xerrors "github.com/pkg/errors"
"github.com/usual2970/certimate/internal/pkg/core/deployer"
"github.com/usual2970/certimate/internal/pkg/core/logger"
cfsdk "github.com/usual2970/certimate/internal/pkg/vendors/cdnfly-sdk"
)
type DeployerConfig struct {
// Cdnfly 地址。
ApiUrl string `json:"apiUrl"`
// Cdnfly 用户端 API Key。
ApiKey string `json:"apiKey"`
// Cdnfly 用户端 API Secret。
ApiSecret string `json:"apiSecret"`
// 部署资源类型。
ResourceType ResourceType `json:"resourceType"`
// 网站 ID。
// 部署资源类型为 [RESOURCE_TYPE_SITE] 时必填。
SiteId string `json:"siteId,omitempty"`
// 证书 ID。
// 部署资源类型为 [RESOURCE_TYPE_CERTIFICATE] 时必填。
CertificateId string `json:"certificateId,omitempty"`
}
type DeployerProvider struct {
config *DeployerConfig
logger logger.Logger
sdkClient *cfsdk.Client
}
var _ deployer.Deployer = (*DeployerProvider)(nil)
func NewDeployer(config *DeployerConfig) (*DeployerProvider, error) {
if config == nil {
panic("config is nil")
}
client, err := createSdkClient(config.ApiUrl, config.ApiKey, config.ApiSecret)
if err != nil {
return nil, xerrors.Wrap(err, "failed to create sdk client")
}
return &DeployerProvider{
config: config,
logger: logger.NewNilLogger(),
sdkClient: client,
}, nil
}
func (d *DeployerProvider) WithLogger(logger logger.Logger) *DeployerProvider {
d.logger = logger
return d
}
func (d *DeployerProvider) Deploy(ctx context.Context, certPem string, privkeyPem string) (*deployer.DeployResult, error) {
// 根据部署资源类型决定部署方式
switch d.config.ResourceType {
case RESOURCE_TYPE_SITE:
if err := d.deployToSite(ctx, certPem, privkeyPem); err != nil {
return nil, err
}
case RESOURCE_TYPE_CERTIFICATE:
if err := d.deployToCertificate(ctx, certPem, privkeyPem); err != nil {
return nil, err
}
default:
return nil, fmt.Errorf("unsupported resource type: %s", d.config.ResourceType)
}
return &deployer.DeployResult{}, nil
}
func (d *DeployerProvider) deployToSite(ctx context.Context, certPem string, privkeyPem string) error {
if d.config.SiteId == "" {
return errors.New("config `siteId` is required")
}
// 获取单个网站详情
// REF: https://doc.cdnfly.cn/wangzhanguanli-v1-sites.html#%E8%8E%B7%E5%8F%96%E5%8D%95%E4%B8%AA%E7%BD%91%E7%AB%99%E8%AF%A6%E6%83%85
getSiteReq := &cfsdk.GetSiteRequest{
Id: d.config.SiteId,
}
getSiteResp, err := d.sdkClient.GetSite(getSiteReq)
if err != nil {
return xerrors.Wrap(err, "failed to execute sdk request 'cdnfly.GetSite'")
} else {
d.logger.Logt("已获取网站详情", getSiteResp)
}
// 添加单个证书
// REF: https://doc.cdnfly.cn/wangzhanzhengshu-v1-certs.html#%E6%B7%BB%E5%8A%A0%E5%8D%95%E4%B8%AA%E6%88%96%E5%A4%9A%E4%B8%AA%E8%AF%81%E4%B9%A6-%E5%A4%9A%E4%B8%AA%E8%AF%81%E4%B9%A6%E6%97%B6%E6%95%B0%E6%8D%AE%E6%A0%BC%E5%BC%8F%E4%B8%BA%E6%95%B0%E7%BB%84
createCertificateReq := &cfsdk.CreateCertificateRequest{
Name: fmt.Sprintf("certimate-%d", time.Now().UnixMilli()),
Type: "custom",
Cert: certPem,
Key: privkeyPem,
}
createCertificateResp, err := d.sdkClient.CreateCertificate(createCertificateReq)
if err != nil {
return xerrors.Wrap(err, "failed to execute sdk request 'cdnfly.CreateCertificate'")
} else {
d.logger.Logt("已添加证书", createCertificateResp)
}
// 修改单个网站
// REF: https://doc.cdnfly.cn/wangzhanguanli-v1-sites.html#%E4%BF%AE%E6%94%B9%E5%8D%95%E4%B8%AA%E7%BD%91%E7%AB%99
updateSiteHttpsListenMap := make(map[string]any)
_ = json.Unmarshal([]byte(getSiteResp.Data.HttpsListen), &updateSiteHttpsListenMap)
updateSiteHttpsListenMap["cert"] = createCertificateResp.Data
updateSiteHttpsListenData, _ := json.Marshal(updateSiteHttpsListenMap)
updateSiteHttpsListen := string(updateSiteHttpsListenData)
updateSiteReq := &cfsdk.UpdateSiteRequest{
Id: d.config.SiteId,
HttpsListen: &updateSiteHttpsListen,
}
updateSiteResp, err := d.sdkClient.UpdateSite(updateSiteReq)
if err != nil {
return xerrors.Wrap(err, "failed to execute sdk request 'cdnfly.UpdateSite'")
} else {
d.logger.Logt("已修改网站", updateSiteResp)
}
return nil
}
func (d *DeployerProvider) deployToCertificate(ctx context.Context, certPem string, privkeyPem string) error {
if d.config.CertificateId == "" {
return errors.New("config `certificateId` is required")
}
// 修改单个证书
// REF: https://doc.cdnfly.cn/wangzhanzhengshu-v1-certs.html#%E4%BF%AE%E6%94%B9%E5%8D%95%E4%B8%AA%E8%AF%81%E4%B9%A6
updateCertificateType := "custom"
updateCertificateReq := &cfsdk.UpdateCertificateRequest{
Id: d.config.CertificateId,
Type: &updateCertificateType,
Cert: &certPem,
Key: &privkeyPem,
}
updateCertificateResp, err := d.sdkClient.UpdateCertificate(updateCertificateReq)
if err != nil {
return xerrors.Wrap(err, "failed to execute sdk request 'cdnfly.UpdateCertificate'")
} else {
d.logger.Logt("已修改证书", updateCertificateResp)
}
return nil
}
func createSdkClient(apiUrl, apiKey, apiSecret string) (*cfsdk.Client, error) {
if _, err := url.Parse(apiUrl); err != nil {
return nil, errors.New("invalid cachefly api url")
}
if apiKey == "" {
return nil, errors.New("invalid cachefly api key")
}
if apiSecret == "" {
return nil, errors.New("invalid cachefly api secret")
}
client := cfsdk.NewClient(apiUrl, apiKey, apiSecret)
return client, nil
}

View File

@ -0,0 +1,81 @@
package cdnfly_test
import (
"context"
"flag"
"fmt"
"os"
"strings"
"testing"
provider "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/cdnfly"
)
var (
fInputCertPath string
fInputKeyPath string
fApiUrl string
fApiKey string
fApiSecret string
fCertificateId string
)
func init() {
argsPrefix := "CERTIMATE_DEPLOYER_CDNFLY_"
flag.StringVar(&fInputCertPath, argsPrefix+"INPUTCERTPATH", "", "")
flag.StringVar(&fInputKeyPath, argsPrefix+"INPUTKEYPATH", "", "")
flag.StringVar(&fApiUrl, argsPrefix+"APIURL", "", "")
flag.StringVar(&fApiKey, argsPrefix+"APIKEY", "", "")
flag.StringVar(&fApiSecret, argsPrefix+"APISECRET", "", "")
flag.StringVar(&fCertificateId, argsPrefix+"CERTIFICATEID", "", "")
}
/*
Shell command to run this test:
go test -v ./cdnfly_test.go -args \
--CERTIMATE_DEPLOYER_CDNFLY_INPUTCERTPATH="/path/to/your-input-cert.pem" \
--CERTIMATE_DEPLOYER_CDNFLY_INPUTKEYPATH="/path/to/your-input-key.pem" \
--CERTIMATE_DEPLOYER_CDNFLY_APIURL="http://127.0.0.1:88" \
--CERTIMATE_DEPLOYER_CDNFLY_APIKEY="your-api-key" \
--CERTIMATE_DEPLOYER_CDNFLY_APISECRET="your-api-secret" \
--CERTIMATE_DEPLOYER_CDNFLY_CERTIFICATEID="your-cert-id"
*/
func TestDeploy(t *testing.T) {
flag.Parse()
t.Run("Deploy", func(t *testing.T) {
t.Log(strings.Join([]string{
"args:",
fmt.Sprintf("INPUTCERTPATH: %v", fInputCertPath),
fmt.Sprintf("INPUTKEYPATH: %v", fInputKeyPath),
fmt.Sprintf("APIURL: %v", fApiUrl),
fmt.Sprintf("APIKEY: %v", fApiKey),
fmt.Sprintf("APISECRET: %v", fApiSecret),
fmt.Sprintf("CERTIFICATEID: %v", fCertificateId),
}, "\n"))
deployer, err := provider.NewDeployer(&provider.DeployerConfig{
ApiUrl: fApiUrl,
ApiKey: fApiKey,
ApiSecret: fApiSecret,
ResourceType: provider.RESOURCE_TYPE_CERTIFICATE,
CertificateId: fCertificateId,
})
if err != nil {
t.Errorf("err: %+v", err)
return
}
fInputCertData, _ := os.ReadFile(fInputCertPath)
fInputKeyData, _ := os.ReadFile(fInputKeyPath)
res, err := deployer.Deploy(context.Background(), string(fInputCertData), string(fInputKeyData))
if err != nil {
t.Errorf("err: %+v", err)
return
}
t.Logf("ok: %v", res)
})
}

View File

@ -0,0 +1,10 @@
package cdnfly
type ResourceType string
const (
// 资源类型:替换指定网站的证书。
RESOURCE_TYPE_SITE = ResourceType("site")
// 资源类型:替换指定证书。
RESOURCE_TYPE_CERTIFICATE = ResourceType("certificate")
)

View File

@ -2,7 +2,6 @@
import ( import (
"context" "context"
"errors"
"strconv" "strconv"
xerrors "github.com/pkg/errors" xerrors "github.com/pkg/errors"
@ -10,11 +9,11 @@ import (
"github.com/usual2970/certimate/internal/pkg/core/deployer" "github.com/usual2970/certimate/internal/pkg/core/deployer"
"github.com/usual2970/certimate/internal/pkg/core/logger" "github.com/usual2970/certimate/internal/pkg/core/logger"
"github.com/usual2970/certimate/internal/pkg/core/uploader" "github.com/usual2970/certimate/internal/pkg/core/uploader"
uploaderp "github.com/usual2970/certimate/internal/pkg/core/uploader/providers/dogecloud" uploadersp "github.com/usual2970/certimate/internal/pkg/core/uploader/providers/dogecloud"
dogesdk "github.com/usual2970/certimate/internal/pkg/vendors/dogecloud-sdk" dogesdk "github.com/usual2970/certimate/internal/pkg/vendors/dogecloud-sdk"
) )
type DogeCloudCDNDeployerConfig struct { type DeployerConfig struct {
// 多吉云 AccessKey。 // 多吉云 AccessKey。
AccessKey string `json:"accessKey"` AccessKey string `json:"accessKey"`
// 多吉云 SecretKey。 // 多吉云 SecretKey。
@ -23,31 +22,23 @@ type DogeCloudCDNDeployerConfig struct {
Domain string `json:"domain"` Domain string `json:"domain"`
} }
type DogeCloudCDNDeployer struct { type DeployerProvider struct {
config *DogeCloudCDNDeployerConfig config *DeployerConfig
logger logger.Logger logger logger.Logger
sdkClient *dogesdk.Client sdkClient *dogesdk.Client
sslUploader uploader.Uploader sslUploader uploader.Uploader
} }
var _ deployer.Deployer = (*DogeCloudCDNDeployer)(nil) var _ deployer.Deployer = (*DeployerProvider)(nil)
func New(config *DogeCloudCDNDeployerConfig) (*DogeCloudCDNDeployer, error) { func NewDeployer(config *DeployerConfig) (*DeployerProvider, error) {
return NewWithLogger(config, logger.NewNilLogger())
}
func NewWithLogger(config *DogeCloudCDNDeployerConfig, logger logger.Logger) (*DogeCloudCDNDeployer, error) {
if config == nil { if config == nil {
return nil, errors.New("config is nil") panic("config is nil")
}
if logger == nil {
return nil, errors.New("logger is nil")
} }
client := dogesdk.NewClient(config.AccessKey, config.SecretKey) client := dogesdk.NewClient(config.AccessKey, config.SecretKey)
uploader, err := uploaderp.New(&uploaderp.DogeCloudUploaderConfig{ uploader, err := uploadersp.NewUploader(&uploadersp.UploaderConfig{
AccessKey: config.AccessKey, AccessKey: config.AccessKey,
SecretKey: config.SecretKey, SecretKey: config.SecretKey,
}) })
@ -55,15 +46,19 @@ func NewWithLogger(config *DogeCloudCDNDeployerConfig, logger logger.Logger) (*D
return nil, xerrors.Wrap(err, "failed to create ssl uploader") return nil, xerrors.Wrap(err, "failed to create ssl uploader")
} }
return &DogeCloudCDNDeployer{ return &DeployerProvider{
logger: logger, logger: logger.NewNilLogger(),
config: config,
sdkClient: client, sdkClient: client,
sslUploader: uploader, sslUploader: uploader,
}, nil }, nil
} }
func (d *DogeCloudCDNDeployer) Deploy(ctx context.Context, certPem string, privkeyPem string) (*deployer.DeployResult, error) { func (d *DeployerProvider) WithLogger(logger logger.Logger) *DeployerProvider {
d.logger = logger
return d
}
func (d *DeployerProvider) Deploy(ctx context.Context, certPem string, privkeyPem string) (*deployer.DeployResult, error) {
// 上传证书到 CDN // 上传证书到 CDN
upres, err := d.sslUploader.Upload(ctx, certPem, privkeyPem) upres, err := d.sslUploader.Upload(ctx, certPem, privkeyPem)
if err != nil { if err != nil {

View File

@ -52,7 +52,7 @@ func TestDeploy(t *testing.T) {
fmt.Sprintf("DOMAIN: %v", fDomain), fmt.Sprintf("DOMAIN: %v", fDomain),
}, "\n")) }, "\n"))
deployer, err := provider.New(&provider.DogeCloudCDNDeployerConfig{ deployer, err := provider.NewDeployer(&provider.DeployerConfig{
AccessKey: fAccessKey, AccessKey: fAccessKey,
SecretKey: fSecretKey, SecretKey: fSecretKey,
Domain: fDomain, Domain: fDomain,

View File

@ -2,7 +2,6 @@
import ( import (
"context" "context"
"errors"
xerrors "github.com/pkg/errors" xerrors "github.com/pkg/errors"
@ -13,7 +12,7 @@ import (
edgsdkDtos "github.com/usual2970/certimate/internal/pkg/vendors/edgio-sdk/applications/v7/dtos" edgsdkDtos "github.com/usual2970/certimate/internal/pkg/vendors/edgio-sdk/applications/v7/dtos"
) )
type EdgioApplicationsDeployerConfig struct { type DeployerConfig struct {
// Edgio ClientId。 // Edgio ClientId。
ClientId string `json:"clientId"` ClientId string `json:"clientId"`
// Edgio ClientSecret。 // Edgio ClientSecret。
@ -22,25 +21,17 @@ type EdgioApplicationsDeployerConfig struct {
EnvironmentId string `json:"environmentId"` EnvironmentId string `json:"environmentId"`
} }
type EdgioApplicationsDeployer struct { type DeployerProvider struct {
config *EdgioApplicationsDeployerConfig config *DeployerConfig
logger logger.Logger logger logger.Logger
sdkClient *edgsdk.EdgioClient sdkClient *edgsdk.EdgioClient
} }
var _ deployer.Deployer = (*EdgioApplicationsDeployer)(nil) var _ deployer.Deployer = (*DeployerProvider)(nil)
func New(config *EdgioApplicationsDeployerConfig) (*EdgioApplicationsDeployer, error) { func NewDeployer(config *DeployerConfig) (*DeployerProvider, error) {
return NewWithLogger(config, logger.NewNilLogger())
}
func NewWithLogger(config *EdgioApplicationsDeployerConfig, logger logger.Logger) (*EdgioApplicationsDeployer, error) {
if config == nil { if config == nil {
return nil, errors.New("config is nil") panic("config is nil")
}
if logger == nil {
return nil, errors.New("logger is nil")
} }
client, err := createSdkClient(config.ClientId, config.ClientSecret) client, err := createSdkClient(config.ClientId, config.ClientSecret)
@ -48,14 +39,19 @@ func NewWithLogger(config *EdgioApplicationsDeployerConfig, logger logger.Logger
return nil, xerrors.Wrap(err, "failed to create sdk client") return nil, xerrors.Wrap(err, "failed to create sdk client")
} }
return &EdgioApplicationsDeployer{ return &DeployerProvider{
logger: logger,
config: config, config: config,
logger: logger.NewNilLogger(),
sdkClient: client, sdkClient: client,
}, nil }, nil
} }
func (d *EdgioApplicationsDeployer) Deploy(ctx context.Context, certPem string, privkeyPem string) (*deployer.DeployResult, error) { func (d *DeployerProvider) WithLogger(logger logger.Logger) *DeployerProvider {
d.logger = logger
return d
}
func (d *DeployerProvider) Deploy(ctx context.Context, certPem string, privkeyPem string) (*deployer.DeployResult, error) {
// 提取 Edgio 所需的服务端证书和中间证书内容 // 提取 Edgio 所需的服务端证书和中间证书内容
privateCertPem, intermediateCertPem, err := certs.ExtractCertificatesFromPEM(certPem) privateCertPem, intermediateCertPem, err := certs.ExtractCertificatesFromPEM(certPem)
if err != nil { if err != nil {

View File

@ -52,7 +52,7 @@ func TestDeploy(t *testing.T) {
fmt.Sprintf("ENVIRONMENTID: %v", fEnvironmentId), fmt.Sprintf("ENVIRONMENTID: %v", fEnvironmentId),
}, "\n")) }, "\n"))
deployer, err := provider.New(&provider.EdgioApplicationsDeployerConfig{ deployer, err := provider.NewDeployer(&provider.DeployerConfig{
ClientId: fClientId, ClientId: fClientId,
ClientSecret: fClientSecret, ClientSecret: fClientSecret,
EnvironmentId: fEnvironmentId, EnvironmentId: fEnvironmentId,

View File

@ -0,0 +1,124 @@
package gcorecdn
import (
"context"
"errors"
"strconv"
gprovider "github.com/G-Core/gcorelabscdn-go/gcore/provider"
gresources "github.com/G-Core/gcorelabscdn-go/resources"
xerrors "github.com/pkg/errors"
"github.com/usual2970/certimate/internal/pkg/core/deployer"
"github.com/usual2970/certimate/internal/pkg/core/logger"
"github.com/usual2970/certimate/internal/pkg/core/uploader"
uploadersp "github.com/usual2970/certimate/internal/pkg/core/uploader/providers/gcore-cdn"
gcoresdk "github.com/usual2970/certimate/internal/pkg/vendors/gcore-sdk/common"
)
type DeployerConfig struct {
// Gcore API Token。
ApiToken string `json:"apiToken"`
// CDN 资源 ID。
ResourceId int64 `json:"resourceId"`
}
type DeployerProvider struct {
config *DeployerConfig
logger logger.Logger
sdkClient *gresources.Service
sslUploader uploader.Uploader
}
var _ deployer.Deployer = (*DeployerProvider)(nil)
func NewDeployer(config *DeployerConfig) (*DeployerProvider, error) {
if config == nil {
panic("config is nil")
}
client, err := createSdkClient(config.ApiToken)
if err != nil {
return nil, xerrors.Wrap(err, "failed to create sdk client")
}
uploader, err := uploadersp.NewUploader(&uploadersp.UploaderConfig{
ApiToken: config.ApiToken,
})
if err != nil {
return nil, xerrors.Wrap(err, "failed to create ssl uploader")
}
return &DeployerProvider{
config: config,
logger: logger.NewNilLogger(),
sdkClient: client,
sslUploader: uploader,
}, nil
}
func (d *DeployerProvider) WithLogger(logger logger.Logger) *DeployerProvider {
d.logger = logger
return d
}
func (d *DeployerProvider) Deploy(ctx context.Context, certPem string, privkeyPem string) (*deployer.DeployResult, error) {
if d.config.ResourceId == 0 {
return nil, errors.New("config `resourceId` is required")
}
// 上传证书到 CDN
upres, err := d.sslUploader.Upload(ctx, certPem, privkeyPem)
if err != nil {
return nil, xerrors.Wrap(err, "failed to upload certificate file")
} else {
d.logger.Logt("certificate file uploaded", upres)
}
// 获取 CDN 资源详情
// REF: https://api.gcore.com/docs/cdn#tag/CDN-resources/paths/~1cdn~1resources~1%7Bresource_id%7D/get
getResourceResp, err := d.sdkClient.Get(context.TODO(), d.config.ResourceId)
if err != nil {
return nil, xerrors.Wrap(err, "failed to execute sdk request 'resources.Get'")
} else {
d.logger.Logt("已获取 CDN 资源详情", getResourceResp)
}
// 更新 CDN 资源详情
// REF: https://api.gcore.com/docs/cdn#tag/CDN-resources/operation/change_cdn_resource
updateResourceCertId, _ := strconv.ParseInt(upres.CertId, 10, 64)
updateResourceReq := &gresources.UpdateRequest{
Description: getResourceResp.Description,
Active: getResourceResp.Active,
OriginGroup: int(getResourceResp.OriginGroup),
OriginProtocol: getResourceResp.OriginProtocol,
SecondaryHostnames: getResourceResp.SecondaryHostnames,
SSlEnabled: true,
SSLData: int(updateResourceCertId),
ProxySSLEnabled: getResourceResp.ProxySSLEnabled,
ProxySSLCA: &getResourceResp.ProxySSLCA,
ProxySSLData: &getResourceResp.ProxySSLData,
Options: getResourceResp.Options,
}
updateResourceResp, err := d.sdkClient.Update(context.TODO(), d.config.ResourceId, updateResourceReq)
if err != nil {
return nil, xerrors.Wrap(err, "failed to execute sdk request 'resources.Update'")
} else {
d.logger.Logt("已更新 CDN 资源详情", updateResourceResp)
}
return &deployer.DeployResult{}, nil
}
func createSdkClient(apiToken string) (*gresources.Service, error) {
if apiToken == "" {
return nil, errors.New("invalid gcore api token")
}
requester := gprovider.NewClient(
gcoresdk.BASE_URL,
gprovider.WithSigner(gcoresdk.NewAuthRequestSigner(apiToken)),
)
service := gresources.NewService(requester)
return service, nil
}

View File

@ -0,0 +1,70 @@
package gcorecdn_test
import (
"context"
"flag"
"fmt"
"os"
"strings"
"testing"
provider "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/gcore-cdn"
)
var (
fInputCertPath string
fInputKeyPath string
fApiToken string
fResourceId int64
)
func init() {
argsPrefix := "CERTIMATE_DEPLOYER_GCORECDN_"
flag.StringVar(&fInputCertPath, argsPrefix+"INPUTCERTPATH", "", "")
flag.StringVar(&fInputKeyPath, argsPrefix+"INPUTKEYPATH", "", "")
flag.StringVar(&fApiToken, argsPrefix+"APITOKEN", "", "")
flag.Int64Var(&fResourceId, argsPrefix+"RESOURCEID", 0, "")
}
/*
Shell command to run this test:
go test -v ./gcore_cdn_test.go -args \
--CERTIMATE_DEPLOYER_GCORECDN_INPUTCERTPATH="/path/to/your-input-cert.pem" \
--CERTIMATE_DEPLOYER_GCORECDN_INPUTKEYPATH="/path/to/your-input-key.pem" \
--CERTIMATE_DEPLOYER_GCORECDN_APITOKEN="your-api-token" \
--CERTIMATE_DEPLOYER_GCORECDN_RESOURCEID="your-cdn-resource-id"
*/
func TestDeploy(t *testing.T) {
flag.Parse()
t.Run("Deploy", func(t *testing.T) {
t.Log(strings.Join([]string{
"args:",
fmt.Sprintf("INPUTCERTPATH: %v", fInputCertPath),
fmt.Sprintf("INPUTKEYPATH: %v", fInputKeyPath),
fmt.Sprintf("APITOKEN: %v", fApiToken),
fmt.Sprintf("RESOURCEID: %v", fResourceId),
}, "\n"))
deployer, err := provider.NewDeployer(&provider.DeployerConfig{
ApiToken: fApiToken,
ResourceId: fResourceId,
})
if err != nil {
t.Errorf("err: %+v", err)
return
}
fInputCertData, _ := os.ReadFile(fInputCertPath)
fInputKeyData, _ := os.ReadFile(fInputKeyPath)
res, err := deployer.Deploy(context.Background(), string(fInputCertData), string(fInputKeyData))
if err != nil {
t.Errorf("err: %+v", err)
return
}
t.Logf("ok: %v", res)
})
}

View File

@ -2,7 +2,6 @@
import ( import (
"context" "context"
"errors"
"github.com/huaweicloud/huaweicloud-sdk-go-v3/core/auth/global" "github.com/huaweicloud/huaweicloud-sdk-go-v3/core/auth/global"
hcCdn "github.com/huaweicloud/huaweicloud-sdk-go-v3/services/cdn/v2" hcCdn "github.com/huaweicloud/huaweicloud-sdk-go-v3/services/cdn/v2"
@ -13,11 +12,11 @@ import (
"github.com/usual2970/certimate/internal/pkg/core/deployer" "github.com/usual2970/certimate/internal/pkg/core/deployer"
"github.com/usual2970/certimate/internal/pkg/core/logger" "github.com/usual2970/certimate/internal/pkg/core/logger"
"github.com/usual2970/certimate/internal/pkg/core/uploader" "github.com/usual2970/certimate/internal/pkg/core/uploader"
uploaderp "github.com/usual2970/certimate/internal/pkg/core/uploader/providers/huaweicloud-scm" uploadersp "github.com/usual2970/certimate/internal/pkg/core/uploader/providers/huaweicloud-scm"
hwsdk "github.com/usual2970/certimate/internal/pkg/vendors/huaweicloud-sdk" hwsdk "github.com/usual2970/certimate/internal/pkg/vendors/huaweicloud-sdk"
) )
type HuaweiCloudCDNDeployerConfig struct { type DeployerConfig struct {
// 华为云 AccessKeyId。 // 华为云 AccessKeyId。
AccessKeyId string `json:"accessKeyId"` AccessKeyId string `json:"accessKeyId"`
// 华为云 SecretAccessKey。 // 华为云 SecretAccessKey。
@ -28,26 +27,18 @@ type HuaweiCloudCDNDeployerConfig struct {
Domain string `json:"domain"` Domain string `json:"domain"`
} }
type HuaweiCloudCDNDeployer struct { type DeployerProvider struct {
config *HuaweiCloudCDNDeployerConfig config *DeployerConfig
logger logger.Logger logger logger.Logger
sdkClient *hcCdn.CdnClient sdkClient *hcCdn.CdnClient
sslUploader uploader.Uploader sslUploader uploader.Uploader
} }
var _ deployer.Deployer = (*HuaweiCloudCDNDeployer)(nil) var _ deployer.Deployer = (*DeployerProvider)(nil)
func New(config *HuaweiCloudCDNDeployerConfig) (*HuaweiCloudCDNDeployer, error) { func NewDeployer(config *DeployerConfig) (*DeployerProvider, error) {
return NewWithLogger(config, logger.NewNilLogger())
}
func NewWithLogger(config *HuaweiCloudCDNDeployerConfig, logger logger.Logger) (*HuaweiCloudCDNDeployer, error) {
if config == nil { if config == nil {
return nil, errors.New("config is nil") panic("config is nil")
}
if logger == nil {
return nil, errors.New("logger is nil")
} }
client, err := createSdkClient( client, err := createSdkClient(
@ -59,7 +50,7 @@ func NewWithLogger(config *HuaweiCloudCDNDeployerConfig, logger logger.Logger) (
return nil, xerrors.Wrap(err, "failed to create sdk client") return nil, xerrors.Wrap(err, "failed to create sdk client")
} }
uploader, err := uploaderp.New(&uploaderp.HuaweiCloudSCMUploaderConfig{ uploader, err := uploadersp.NewUploader(&uploadersp.UploaderConfig{
AccessKeyId: config.AccessKeyId, AccessKeyId: config.AccessKeyId,
SecretAccessKey: config.SecretAccessKey, SecretAccessKey: config.SecretAccessKey,
}) })
@ -67,15 +58,20 @@ func NewWithLogger(config *HuaweiCloudCDNDeployerConfig, logger logger.Logger) (
return nil, xerrors.Wrap(err, "failed to create ssl uploader") return nil, xerrors.Wrap(err, "failed to create ssl uploader")
} }
return &HuaweiCloudCDNDeployer{ return &DeployerProvider{
logger: logger,
config: config, config: config,
logger: logger.NewNilLogger(),
sdkClient: client, sdkClient: client,
sslUploader: uploader, sslUploader: uploader,
}, nil }, nil
} }
func (d *HuaweiCloudCDNDeployer) Deploy(ctx context.Context, certPem string, privkeyPem string) (*deployer.DeployResult, error) { func (d *DeployerProvider) WithLogger(logger logger.Logger) *DeployerProvider {
d.logger = logger
return d
}
func (d *DeployerProvider) Deploy(ctx context.Context, certPem string, privkeyPem string) (*deployer.DeployResult, error) {
// 上传证书到 SCM // 上传证书到 SCM
upres, err := d.sslUploader.Upload(ctx, certPem, privkeyPem) upres, err := d.sslUploader.Upload(ctx, certPem, privkeyPem)
if err != nil { if err != nil {

View File

@ -56,7 +56,7 @@ func TestDeploy(t *testing.T) {
fmt.Sprintf("DOMAIN: %v", fDomain), fmt.Sprintf("DOMAIN: %v", fDomain),
}, "\n")) }, "\n"))
deployer, err := provider.New(&provider.HuaweiCloudCDNDeployerConfig{ deployer, err := provider.NewDeployer(&provider.DeployerConfig{
AccessKeyId: fAccessKeyId, AccessKeyId: fAccessKeyId,
SecretAccessKey: fSecretAccessKey, SecretAccessKey: fSecretAccessKey,
Region: fRegion, Region: fRegion,

View File

@ -0,0 +1,12 @@
package huaweicloudelb
type ResourceType string
const (
// 资源类型:替换指定证书。
RESOURCE_TYPE_CERTIFICATE = ResourceType("certificate")
// 资源类型:部署到指定负载均衡器。
RESOURCE_TYPE_LOADBALANCER = ResourceType("loadbalancer")
// 资源类型:部署到指定监听器。
RESOURCE_TYPE_LISTENER = ResourceType("listener")
)

View File

@ -1,12 +0,0 @@
package huaweicloudelb
type DeployResourceType string
const (
// 资源类型:替换指定证书。
DEPLOY_RESOURCE_CERTIFICATE = DeployResourceType("certificate")
// 资源类型:部署到指定负载均衡器。
DEPLOY_RESOURCE_LOADBALANCER = DeployResourceType("loadbalancer")
// 资源类型:部署到指定监听器。
DEPLOY_RESOURCE_LISTENER = DeployResourceType("listener")
)

View File

@ -19,11 +19,11 @@ import (
"github.com/usual2970/certimate/internal/pkg/core/deployer" "github.com/usual2970/certimate/internal/pkg/core/deployer"
"github.com/usual2970/certimate/internal/pkg/core/logger" "github.com/usual2970/certimate/internal/pkg/core/logger"
"github.com/usual2970/certimate/internal/pkg/core/uploader" "github.com/usual2970/certimate/internal/pkg/core/uploader"
uploaderp "github.com/usual2970/certimate/internal/pkg/core/uploader/providers/huaweicloud-elb" uploadersp "github.com/usual2970/certimate/internal/pkg/core/uploader/providers/huaweicloud-elb"
hwsdk "github.com/usual2970/certimate/internal/pkg/vendors/huaweicloud-sdk" hwsdk "github.com/usual2970/certimate/internal/pkg/vendors/huaweicloud-sdk"
) )
type HuaweiCloudELBDeployerConfig struct { type DeployerConfig struct {
// 华为云 AccessKeyId。 // 华为云 AccessKeyId。
AccessKeyId string `json:"accessKeyId"` AccessKeyId string `json:"accessKeyId"`
// 华为云 SecretAccessKey。 // 华为云 SecretAccessKey。
@ -31,38 +31,30 @@ type HuaweiCloudELBDeployerConfig struct {
// 华为云区域。 // 华为云区域。
Region string `json:"region"` Region string `json:"region"`
// 部署资源类型。 // 部署资源类型。
ResourceType DeployResourceType `json:"resourceType"` ResourceType ResourceType `json:"resourceType"`
// 证书 ID。 // 证书 ID。
// 部署资源类型为 [DEPLOY_RESOURCE_CERTIFICATE] 时必填。 // 部署资源类型为 [RESOURCE_TYPE_CERTIFICATE] 时必填。
CertificateId string `json:"certificateId,omitempty"` CertificateId string `json:"certificateId,omitempty"`
// 负载均衡器 ID。 // 负载均衡器 ID。
// 部署资源类型为 [DEPLOY_RESOURCE_LOADBALANCER] 时必填。 // 部署资源类型为 [RESOURCE_TYPE_LOADBALANCER] 时必填。
LoadbalancerId string `json:"loadbalancerId,omitempty"` LoadbalancerId string `json:"loadbalancerId,omitempty"`
// 负载均衡监听 ID。 // 负载均衡监听 ID。
// 部署资源类型为 [DEPLOY_RESOURCE_LISTENER] 时必填。 // 部署资源类型为 [RESOURCE_TYPE_LISTENER] 时必填。
ListenerId string `json:"listenerId,omitempty"` ListenerId string `json:"listenerId,omitempty"`
} }
type HuaweiCloudELBDeployer struct { type DeployerProvider struct {
config *HuaweiCloudELBDeployerConfig config *DeployerConfig
logger logger.Logger logger logger.Logger
sdkClient *hcElb.ElbClient sdkClient *hcElb.ElbClient
sslUploader uploader.Uploader sslUploader uploader.Uploader
} }
var _ deployer.Deployer = (*HuaweiCloudELBDeployer)(nil) var _ deployer.Deployer = (*DeployerProvider)(nil)
func New(config *HuaweiCloudELBDeployerConfig) (*HuaweiCloudELBDeployer, error) { func NewDeployer(config *DeployerConfig) (*DeployerProvider, error) {
return NewWithLogger(config, logger.NewNilLogger())
}
func NewWithLogger(config *HuaweiCloudELBDeployerConfig, logger logger.Logger) (*HuaweiCloudELBDeployer, error) {
if config == nil { if config == nil {
return nil, errors.New("config is nil") panic("config is nil")
}
if logger == nil {
return nil, errors.New("logger is nil")
} }
client, err := createSdkClient(config.AccessKeyId, config.SecretAccessKey, config.Region) client, err := createSdkClient(config.AccessKeyId, config.SecretAccessKey, config.Region)
@ -70,7 +62,7 @@ func NewWithLogger(config *HuaweiCloudELBDeployerConfig, logger logger.Logger) (
return nil, xerrors.Wrap(err, "failed to create sdk client") return nil, xerrors.Wrap(err, "failed to create sdk client")
} }
uploader, err := uploaderp.New(&uploaderp.HuaweiCloudELBUploaderConfig{ uploader, err := uploadersp.NewUploader(&uploadersp.UploaderConfig{
AccessKeyId: config.AccessKeyId, AccessKeyId: config.AccessKeyId,
SecretAccessKey: config.SecretAccessKey, SecretAccessKey: config.SecretAccessKey,
Region: config.Region, Region: config.Region,
@ -79,15 +71,20 @@ func NewWithLogger(config *HuaweiCloudELBDeployerConfig, logger logger.Logger) (
return nil, xerrors.Wrap(err, "failed to create ssl uploader") return nil, xerrors.Wrap(err, "failed to create ssl uploader")
} }
return &HuaweiCloudELBDeployer{ return &DeployerProvider{
logger: logger,
config: config, config: config,
logger: logger.NewNilLogger(),
sdkClient: client, sdkClient: client,
sslUploader: uploader, sslUploader: uploader,
}, nil }, nil
} }
func (d *HuaweiCloudELBDeployer) Deploy(ctx context.Context, certPem string, privkeyPem string) (*deployer.DeployResult, error) { func (d *DeployerProvider) WithLogger(logger logger.Logger) *DeployerProvider {
d.logger = logger
return d
}
func (d *DeployerProvider) Deploy(ctx context.Context, certPem string, privkeyPem string) (*deployer.DeployResult, error) {
// 上传证书到 SCM // 上传证书到 SCM
upres, err := d.sslUploader.Upload(ctx, certPem, privkeyPem) upres, err := d.sslUploader.Upload(ctx, certPem, privkeyPem)
if err != nil { if err != nil {
@ -98,17 +95,17 @@ func (d *HuaweiCloudELBDeployer) Deploy(ctx context.Context, certPem string, pri
// 根据部署资源类型决定部署方式 // 根据部署资源类型决定部署方式
switch d.config.ResourceType { switch d.config.ResourceType {
case DEPLOY_RESOURCE_CERTIFICATE: case RESOURCE_TYPE_CERTIFICATE:
if err := d.deployToCertificate(ctx, certPem, privkeyPem); err != nil { if err := d.deployToCertificate(ctx, certPem, privkeyPem); err != nil {
return nil, err return nil, err
} }
case DEPLOY_RESOURCE_LOADBALANCER: case RESOURCE_TYPE_LOADBALANCER:
if err := d.deployToLoadbalancer(ctx, certPem, privkeyPem); err != nil { if err := d.deployToLoadbalancer(ctx, certPem, privkeyPem); err != nil {
return nil, err return nil, err
} }
case DEPLOY_RESOURCE_LISTENER: case RESOURCE_TYPE_LISTENER:
if err := d.deployToListener(ctx, certPem, privkeyPem); err != nil { if err := d.deployToListener(ctx, certPem, privkeyPem); err != nil {
return nil, err return nil, err
} }
@ -120,7 +117,7 @@ func (d *HuaweiCloudELBDeployer) Deploy(ctx context.Context, certPem string, pri
return &deployer.DeployResult{}, nil return &deployer.DeployResult{}, nil
} }
func (d *HuaweiCloudELBDeployer) deployToCertificate(ctx context.Context, certPem string, privkeyPem string) error { func (d *DeployerProvider) deployToCertificate(ctx context.Context, certPem string, privkeyPem string) error {
if d.config.CertificateId == "" { if d.config.CertificateId == "" {
return errors.New("config `certificateId` is required") return errors.New("config `certificateId` is required")
} }
@ -146,7 +143,7 @@ func (d *HuaweiCloudELBDeployer) deployToCertificate(ctx context.Context, certPe
return nil return nil
} }
func (d *HuaweiCloudELBDeployer) deployToLoadbalancer(ctx context.Context, certPem string, privkeyPem string) error { func (d *DeployerProvider) deployToLoadbalancer(ctx context.Context, certPem string, privkeyPem string) error {
if d.config.LoadbalancerId == "" { if d.config.LoadbalancerId == "" {
return errors.New("config `loadbalancerId` is required") return errors.New("config `loadbalancerId` is required")
} }
@ -223,7 +220,7 @@ func (d *HuaweiCloudELBDeployer) deployToLoadbalancer(ctx context.Context, certP
return nil return nil
} }
func (d *HuaweiCloudELBDeployer) deployToListener(ctx context.Context, certPem string, privkeyPem string) error { func (d *DeployerProvider) deployToListener(ctx context.Context, certPem string, privkeyPem string) error {
if d.config.ListenerId == "" { if d.config.ListenerId == "" {
return errors.New("config `listenerId` is required") return errors.New("config `listenerId` is required")
} }
@ -244,7 +241,7 @@ func (d *HuaweiCloudELBDeployer) deployToListener(ctx context.Context, certPem s
return nil return nil
} }
func (d *HuaweiCloudELBDeployer) modifyListenerCertificate(ctx context.Context, cloudListenerId string, cloudCertId string) error { func (d *DeployerProvider) modifyListenerCertificate(ctx context.Context, cloudListenerId string, cloudCertId string) error {
// 查询监听器详情 // 查询监听器详情
// REF: https://support.huaweicloud.com/api-elb/ShowListener.html // REF: https://support.huaweicloud.com/api-elb/ShowListener.html
showListenerReq := &hcElbModel.ShowListenerRequest{ showListenerReq := &hcElbModel.ShowListenerRequest{

View File

@ -62,11 +62,11 @@ func TestDeploy(t *testing.T) {
fmt.Sprintf("CERTIFICATEID: %v", fCertificateId), fmt.Sprintf("CERTIFICATEID: %v", fCertificateId),
}, "\n")) }, "\n"))
deployer, err := provider.New(&provider.HuaweiCloudELBDeployerConfig{ deployer, err := provider.NewDeployer(&provider.DeployerConfig{
AccessKeyId: fAccessKeyId, AccessKeyId: fAccessKeyId,
SecretAccessKey: fSecretAccessKey, SecretAccessKey: fSecretAccessKey,
Region: fRegion, Region: fRegion,
ResourceType: provider.DEPLOY_RESOURCE_CERTIFICATE, ResourceType: provider.RESOURCE_TYPE_CERTIFICATE,
CertificateId: fCertificateId, CertificateId: fCertificateId,
}) })
if err != nil { if err != nil {
@ -96,11 +96,11 @@ func TestDeploy(t *testing.T) {
fmt.Sprintf("LOADBALANCERID: %v", fLoadbalancerId), fmt.Sprintf("LOADBALANCERID: %v", fLoadbalancerId),
}, "\n")) }, "\n"))
deployer, err := provider.New(&provider.HuaweiCloudELBDeployerConfig{ deployer, err := provider.NewDeployer(&provider.DeployerConfig{
AccessKeyId: fAccessKeyId, AccessKeyId: fAccessKeyId,
SecretAccessKey: fSecretAccessKey, SecretAccessKey: fSecretAccessKey,
Region: fRegion, Region: fRegion,
ResourceType: provider.DEPLOY_RESOURCE_LOADBALANCER, ResourceType: provider.RESOURCE_TYPE_LOADBALANCER,
LoadbalancerId: fLoadbalancerId, LoadbalancerId: fLoadbalancerId,
}) })
if err != nil { if err != nil {
@ -130,11 +130,11 @@ func TestDeploy(t *testing.T) {
fmt.Sprintf("LISTENERID: %v", fListenerId), fmt.Sprintf("LISTENERID: %v", fListenerId),
}, "\n")) }, "\n"))
deployer, err := provider.New(&provider.HuaweiCloudELBDeployerConfig{ deployer, err := provider.NewDeployer(&provider.DeployerConfig{
AccessKeyId: fAccessKeyId, AccessKeyId: fAccessKeyId,
SecretAccessKey: fSecretAccessKey, SecretAccessKey: fSecretAccessKey,
Region: fRegion, Region: fRegion,
ResourceType: provider.DEPLOY_RESOURCE_LISTENER, ResourceType: provider.RESOURCE_TYPE_LISTENER,
ListenerId: fListenerId, ListenerId: fListenerId,
}) })
if err != nil { if err != nil {

View File

@ -0,0 +1,12 @@
package huaweicloudwaf
type ResourceType string
const (
// 资源类型:替换指定证书。
RESOURCE_TYPE_CERTIFICATE = ResourceType("certificate")
// 资源类型:部署到云模式防护网站。
RESOURCE_TYPE_CLOUDSERVER = ResourceType("cloudserver")
// 资源类型:部署到独享模式防护网站。
RESOURCE_TYPE_PREMIUMHOST = ResourceType("premiumhost")
)

View File

@ -0,0 +1,355 @@
package huaweicloudwaf
import (
"context"
"errors"
"fmt"
"strings"
"github.com/huaweicloud/huaweicloud-sdk-go-v3/core/auth/basic"
"github.com/huaweicloud/huaweicloud-sdk-go-v3/core/auth/global"
hcIam "github.com/huaweicloud/huaweicloud-sdk-go-v3/services/iam/v3"
hcIamModel "github.com/huaweicloud/huaweicloud-sdk-go-v3/services/iam/v3/model"
hcIamRegion "github.com/huaweicloud/huaweicloud-sdk-go-v3/services/iam/v3/region"
hcWaf "github.com/huaweicloud/huaweicloud-sdk-go-v3/services/waf/v1"
hcWafModel "github.com/huaweicloud/huaweicloud-sdk-go-v3/services/waf/v1/model"
hcWafRegion "github.com/huaweicloud/huaweicloud-sdk-go-v3/services/waf/v1/region"
xerrors "github.com/pkg/errors"
"github.com/usual2970/certimate/internal/pkg/core/deployer"
"github.com/usual2970/certimate/internal/pkg/core/logger"
"github.com/usual2970/certimate/internal/pkg/core/uploader"
uploadersp "github.com/usual2970/certimate/internal/pkg/core/uploader/providers/huaweicloud-waf"
hwsdk "github.com/usual2970/certimate/internal/pkg/vendors/huaweicloud-sdk"
)
type DeployerConfig struct {
// 华为云 AccessKeyId。
AccessKeyId string `json:"accessKeyId"`
// 华为云 SecretAccessKey。
SecretAccessKey string `json:"secretAccessKey"`
// 华为云区域。
Region string `json:"region"`
// 部署资源类型。
ResourceType ResourceType `json:"resourceType"`
// 证书 ID。
// 部署资源类型为 [RESOURCE_TYPE_CERTIFICATE] 时必填。
CertificateId string `json:"certificateId,omitempty"`
// 防护域名(支持泛域名)。
// 部署资源类型为 [RESOURCE_TYPE_CLOUDSERVER]、[RESOURCE_TYPE_PREMIUMHOST] 时必填。
Domain string `json:"domain,omitempty"`
}
type DeployerProvider struct {
config *DeployerConfig
logger logger.Logger
sdkClient *hcWaf.WafClient
sslUploader uploader.Uploader
}
var _ deployer.Deployer = (*DeployerProvider)(nil)
func NewDeployer(config *DeployerConfig) (*DeployerProvider, error) {
if config == nil {
panic("config is nil")
}
client, err := createSdkClient(config.AccessKeyId, config.SecretAccessKey, config.Region)
if err != nil {
return nil, xerrors.Wrap(err, "failed to create sdk client")
}
uploader, err := uploadersp.NewUploader(&uploadersp.UploaderConfig{
AccessKeyId: config.AccessKeyId,
SecretAccessKey: config.SecretAccessKey,
Region: config.Region,
})
if err != nil {
return nil, xerrors.Wrap(err, "failed to create ssl uploader")
}
return &DeployerProvider{
config: config,
logger: logger.NewNilLogger(),
sdkClient: client,
sslUploader: uploader,
}, nil
}
func (d *DeployerProvider) WithLogger(logger logger.Logger) *DeployerProvider {
d.logger = logger
return d
}
func (d *DeployerProvider) Deploy(ctx context.Context, certPem string, privkeyPem string) (*deployer.DeployResult, error) {
// 上传证书到 WAF
upres, err := d.sslUploader.Upload(ctx, certPem, privkeyPem)
if err != nil {
return nil, xerrors.Wrap(err, "failed to upload certificate file")
} else {
d.logger.Logt("certificate file uploaded", upres)
}
// 根据部署资源类型决定部署方式
switch d.config.ResourceType {
case RESOURCE_TYPE_CERTIFICATE:
if err := d.deployToCertificate(ctx, certPem, privkeyPem); err != nil {
return nil, err
}
case RESOURCE_TYPE_CLOUDSERVER:
if err := d.deployToCloudServer(ctx, certPem, privkeyPem); err != nil {
return nil, err
}
case RESOURCE_TYPE_PREMIUMHOST:
if err := d.deployToPremiumHost(ctx, certPem, privkeyPem); err != nil {
return nil, err
}
default:
return nil, fmt.Errorf("unsupported resource type: %s", d.config.ResourceType)
}
return &deployer.DeployResult{}, nil
}
func (d *DeployerProvider) deployToCertificate(ctx context.Context, certPem string, privkeyPem string) error {
if d.config.CertificateId == "" {
return errors.New("config `certificateId` is required")
}
// 查询证书
// REF: https://support.huaweicloud.com/api-waf/ShowCertificate.html
showCertificateReq := &hcWafModel.ShowCertificateRequest{
CertificateId: d.config.CertificateId,
}
showCertificateResp, err := d.sdkClient.ShowCertificate(showCertificateReq)
if err != nil {
return xerrors.Wrap(err, "failed to execute sdk request 'waf.ShowCertificate'")
} else {
d.logger.Logt("已获取 WAF 证书", showCertificateResp)
}
// 更新证书
// REF: https://support.huaweicloud.com/api-waf/UpdateCertificate.html
updateCertificateReq := &hcWafModel.UpdateCertificateRequest{
CertificateId: d.config.CertificateId,
Body: &hcWafModel.UpdateCertificateRequestBody{
Name: *showCertificateResp.Name,
Content: hwsdk.StringPtr(certPem),
Key: hwsdk.StringPtr(privkeyPem),
},
}
updateCertificateResp, err := d.sdkClient.UpdateCertificate(updateCertificateReq)
if err != nil {
return xerrors.Wrap(err, "failed to execute sdk request 'waf.UpdateCertificate'")
} else {
d.logger.Logt("已更新 WAF 证书", updateCertificateResp)
}
return nil
}
func (d *DeployerProvider) deployToCloudServer(ctx context.Context, certPem string, privkeyPem string) error {
if d.config.Domain == "" {
return errors.New("config `domain` is required")
}
// 上传证书到 WAF
upres, err := d.sslUploader.Upload(ctx, certPem, privkeyPem)
if err != nil {
return xerrors.Wrap(err, "failed to upload certificate file")
} else {
d.logger.Logt("certificate file uploaded", upres)
}
// 遍历查询云模式防护域名列表,获取防护域名 ID
// REF: https://support.huaweicloud.com/api-waf/ListHost.html
hostId := ""
listHostPage := int32(1)
listHostPageSize := int32(100)
for {
listHostReq := &hcWafModel.ListHostRequest{
Hostname: hwsdk.StringPtr(strings.TrimPrefix(d.config.Domain, "*")),
Page: hwsdk.Int32Ptr(listHostPage),
Pagesize: hwsdk.Int32Ptr(listHostPageSize),
}
listHostResp, err := d.sdkClient.ListHost(listHostReq)
if err != nil {
return xerrors.Wrap(err, "failed to execute sdk request 'waf.ListHost'")
}
if listHostResp.Items != nil {
for _, hostItem := range *listHostResp.Items {
if strings.TrimPrefix(d.config.Domain, "*") == *hostItem.Hostname {
hostId = *hostItem.Id
break
}
}
}
if listHostResp.Items == nil || len(*listHostResp.Items) < int(listHostPageSize) {
break
} else {
listHostPage++
}
}
if hostId == "" {
return errors.New("host not found")
}
// 更新云模式防护域名的配置
// REF: https://support.huaweicloud.com/api-waf/UpdateHost.html
updateHostReq := &hcWafModel.UpdateHostRequest{
InstanceId: hostId,
Body: &hcWafModel.UpdateHostRequestBody{
Certificateid: hwsdk.StringPtr(upres.CertId),
Certificatename: hwsdk.StringPtr(upres.CertName),
},
}
updateHostResp, err := d.sdkClient.UpdateHost(updateHostReq)
if err != nil {
return xerrors.Wrap(err, "failed to execute sdk request 'waf.UpdateHost'")
} else {
d.logger.Logt("已更新云模式防护域名的配置", updateHostResp)
}
return nil
}
func (d *DeployerProvider) deployToPremiumHost(ctx context.Context, certPem string, privkeyPem string) error {
if d.config.Domain == "" {
return errors.New("config `domain` is required")
}
// 上传证书到 WAF
upres, err := d.sslUploader.Upload(ctx, certPem, privkeyPem)
if err != nil {
return xerrors.Wrap(err, "failed to upload certificate file")
} else {
d.logger.Logt("certificate file uploaded", upres)
}
// 遍历查询独享模式域名列表,获取防护域名 ID
// REF: https://support.huaweicloud.com/api-waf/ListPremiumHost.html
hostId := ""
listPremiumHostPage := int32(1)
listPremiumHostPageSize := int32(100)
for {
listPremiumHostReq := &hcWafModel.ListPremiumHostRequest{
Hostname: hwsdk.StringPtr(strings.TrimPrefix(d.config.Domain, "*")),
Page: hwsdk.StringPtr(fmt.Sprintf("%d", listPremiumHostPage)),
Pagesize: hwsdk.StringPtr(fmt.Sprintf("%d", listPremiumHostPageSize)),
}
listPremiumHostResp, err := d.sdkClient.ListPremiumHost(listPremiumHostReq)
if err != nil {
return xerrors.Wrap(err, "failed to execute sdk request 'waf.ListPremiumHost'")
}
if listPremiumHostResp.Items != nil {
for _, hostItem := range *listPremiumHostResp.Items {
if strings.TrimPrefix(d.config.Domain, "*") == *hostItem.Hostname {
hostId = *hostItem.Id
break
}
}
}
if listPremiumHostResp.Items == nil || len(*listPremiumHostResp.Items) < int(listPremiumHostPageSize) {
break
} else {
listPremiumHostPage++
}
}
if hostId == "" {
return errors.New("host not found")
}
// 修改独享模式域名配置
// REF: https://support.huaweicloud.com/api-waf/UpdatePremiumHost.html
updatePremiumHostReq := &hcWafModel.UpdatePremiumHostRequest{
HostId: hostId,
Body: &hcWafModel.UpdatePremiumHostRequestBody{
Certificateid: hwsdk.StringPtr(upres.CertId),
Certificatename: hwsdk.StringPtr(upres.CertName),
},
}
updatePremiumHostResp, err := d.sdkClient.UpdatePremiumHost(updatePremiumHostReq)
if err != nil {
return xerrors.Wrap(err, "failed to execute sdk request 'waf.UpdatePremiumHost'")
} else {
d.logger.Logt("已修改独享模式域名配置", updatePremiumHostResp)
}
return nil
}
func createSdkClient(accessKeyId, secretAccessKey, region string) (*hcWaf.WafClient, error) {
projectId, err := getSdkProjectId(accessKeyId, secretAccessKey, region)
if err != nil {
return nil, err
}
auth, err := basic.NewCredentialsBuilder().
WithAk(accessKeyId).
WithSk(secretAccessKey).
WithProjectId(projectId).
SafeBuild()
if err != nil {
return nil, err
}
hcRegion, err := hcWafRegion.SafeValueOf(region)
if err != nil {
return nil, err
}
hcClient, err := hcWaf.WafClientBuilder().
WithRegion(hcRegion).
WithCredential(auth).
SafeBuild()
if err != nil {
return nil, err
}
client := hcWaf.NewWafClient(hcClient)
return client, nil
}
func getSdkProjectId(accessKeyId, secretAccessKey, region string) (string, error) {
auth, err := global.NewCredentialsBuilder().
WithAk(accessKeyId).
WithSk(secretAccessKey).
SafeBuild()
if err != nil {
return "", err
}
hcRegion, err := hcIamRegion.SafeValueOf(region)
if err != nil {
return "", err
}
hcClient, err := hcIam.IamClientBuilder().
WithRegion(hcRegion).
WithCredential(auth).
SafeBuild()
if err != nil {
return "", err
}
client := hcIam.NewIamClient(hcClient)
request := &hcIamModel.KeystoneListProjectsRequest{
Name: &region,
}
response, err := client.KeystoneListProjects(request)
if err != nil {
return "", err
} else if response.Projects == nil || len(*response.Projects) == 0 {
return "", errors.New("no project found")
}
return (*response.Projects)[0].Id, nil
}

View File

@ -0,0 +1,84 @@
package huaweicloudwaf_test
import (
"context"
"flag"
"fmt"
"os"
"strings"
"testing"
provider "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/huaweicloud-waf"
)
var (
fInputCertPath string
fInputKeyPath string
fAccessKeyId string
fSecretAccessKey string
fRegion string
fResourceType string
fDomain string
)
func init() {
argsPrefix := "CERTIMATE_DEPLOYER_HUAWEICLOUDWAF_"
flag.StringVar(&fInputCertPath, argsPrefix+"INPUTCERTPATH", "", "")
flag.StringVar(&fInputKeyPath, argsPrefix+"INPUTKEYPATH", "", "")
flag.StringVar(&fAccessKeyId, argsPrefix+"ACCESSKEYID", "", "")
flag.StringVar(&fSecretAccessKey, argsPrefix+"SECRETACCESSKEY", "", "")
flag.StringVar(&fRegion, argsPrefix+"REGION", "", "")
flag.StringVar(&fResourceType, argsPrefix+"RESOURCETYPE", "", "")
flag.StringVar(&fDomain, argsPrefix+"DOMAIN", "", "")
}
/*
Shell command to run this test:
go test -v ./huaweicloud_waf_test.go -args \
--CERTIMATE_DEPLOYER_HUAWEICLOUDWAF_INPUTCERTPATH="/path/to/your-input-cert.pem" \
--CERTIMATE_DEPLOYER_HUAWEICLOUDWAF_INPUTKEYPATH="/path/to/your-input-key.pem" \
--CERTIMATE_DEPLOYER_HUAWEICLOUDWAF_ACCESSKEYID="your-access-key-id" \
--CERTIMATE_DEPLOYER_HUAWEICLOUDWAF_SECRETACCESSKEY="your-secret-access-key" \
--CERTIMATE_DEPLOYER_HUAWEICLOUDWAF_REGION="cn-north-1" \
--CERTIMATE_DEPLOYER_HUAWEICLOUDWAF_RESOURCETYPE="premium" \
--CERTIMATE_DEPLOYER_HUAWEICLOUDWAF_DOMAIN="example.com"
*/
func TestDeploy(t *testing.T) {
flag.Parse()
t.Run("Deploy", func(t *testing.T) {
t.Log(strings.Join([]string{
"args:",
fmt.Sprintf("INPUTCERTPATH: %v", fInputCertPath),
fmt.Sprintf("INPUTKEYPATH: %v", fInputKeyPath),
fmt.Sprintf("ACCESSKEYID: %v", fAccessKeyId),
fmt.Sprintf("SECRETACCESSKEY: %v", fSecretAccessKey),
fmt.Sprintf("REGION: %v", fRegion),
fmt.Sprintf("RESOURCETYPE: %v", fResourceType),
}, "\n"))
deployer, err := provider.NewDeployer(&provider.DeployerConfig{
AccessKeyId: fAccessKeyId,
SecretAccessKey: fSecretAccessKey,
Region: fRegion,
ResourceType: provider.ResourceType(fResourceType),
Domain: fDomain,
})
if err != nil {
t.Errorf("err: %+v", err)
return
}
fInputCertData, _ := os.ReadFile(fInputCertPath)
fInputKeyData, _ := os.ReadFile(fInputKeyPath)
res, err := deployer.Deploy(context.Background(), string(fInputCertData), string(fInputKeyData))
if err != nil {
t.Errorf("err: %+v", err)
return
}
t.Logf("ok: %v", res)
})
}

View File

@ -0,0 +1,10 @@
package jdcloudalb
type ResourceType string
const (
// 资源类型:部署到指定负载均衡器。
RESOURCE_TYPE_LOADBALANCER = ResourceType("loadbalancer")
// 资源类型:部署到指定监听器。
RESOURCE_TYPE_LISTENER = ResourceType("listener")
)

View File

@ -0,0 +1,252 @@
package jdcloudalb
import (
"context"
"errors"
"fmt"
"strings"
jdCore "github.com/jdcloud-api/jdcloud-sdk-go/core"
jdCommon "github.com/jdcloud-api/jdcloud-sdk-go/services/common/models"
jdLbApi "github.com/jdcloud-api/jdcloud-sdk-go/services/lb/apis"
jdLbClient "github.com/jdcloud-api/jdcloud-sdk-go/services/lb/client"
jdLbModel "github.com/jdcloud-api/jdcloud-sdk-go/services/lb/models"
xerrors "github.com/pkg/errors"
"github.com/usual2970/certimate/internal/pkg/core/deployer"
"github.com/usual2970/certimate/internal/pkg/core/logger"
"github.com/usual2970/certimate/internal/pkg/core/uploader"
uploadersp "github.com/usual2970/certimate/internal/pkg/core/uploader/providers/jdcloud-ssl"
"github.com/usual2970/certimate/internal/pkg/utils/slices"
)
type DeployerConfig struct {
// 京东云 AccessKeyId。
AccessKeyId string `json:"accessKeyId"`
// 京东云 AccessKeySecret。
AccessKeySecret string `json:"accessKeySecret"`
// 京东云地域 ID。
RegionId string `json:"regionId"`
// 部署资源类型。
ResourceType ResourceType `json:"resourceType"`
// 负载均衡器 ID。
// 部署资源类型为 [RESOURCE_TYPE_LOADBALANCER] 时必填。
LoadbalancerId string `json:"loadbalancerId,omitempty"`
// 监听器 ID。
// 部署资源类型为 [RESOURCE_TYPE_LISTENER] 时必填。
ListenerId string `json:"listenerId,omitempty"`
// SNI 域名(支持泛域名)。
// 部署资源类型为 [RESOURCE_TYPE_LOADBALANCER]、[RESOURCE_TYPE_LISTENER] 时选填。
Domain string `json:"domain,omitempty"`
}
type DeployerProvider struct {
config *DeployerConfig
logger logger.Logger
sdkClient *jdLbClient.LbClient
sslUploader uploader.Uploader
}
var _ deployer.Deployer = (*DeployerProvider)(nil)
func NewDeployer(config *DeployerConfig) (*DeployerProvider, error) {
if config == nil {
panic("config is nil")
}
client, err := createSdkClient(config.AccessKeyId, config.AccessKeySecret)
if err != nil {
return nil, xerrors.Wrap(err, "failed to create sdk client")
}
uploader, err := uploadersp.NewUploader(&uploadersp.UploaderConfig{
AccessKeyId: config.AccessKeyId,
AccessKeySecret: config.AccessKeySecret,
})
if err != nil {
return nil, xerrors.Wrap(err, "failed to create ssl uploader")
}
return &DeployerProvider{
config: config,
logger: logger.NewNilLogger(),
sdkClient: client,
sslUploader: uploader,
}, nil
}
func (d *DeployerProvider) WithLogger(logger logger.Logger) *DeployerProvider {
d.logger = logger
return d
}
func (d *DeployerProvider) Deploy(ctx context.Context, certPem string, privkeyPem string) (*deployer.DeployResult, error) {
// 上传证书到 SSL
upres, err := d.sslUploader.Upload(ctx, certPem, privkeyPem)
if err != nil {
return nil, xerrors.Wrap(err, "failed to upload certificate file")
} else {
d.logger.Logt("certificate file uploaded", upres)
}
// 根据部署资源类型决定部署方式
switch d.config.ResourceType {
case RESOURCE_TYPE_LOADBALANCER:
if err := d.deployToLoadbalancer(ctx, upres.CertId); err != nil {
return nil, err
}
case RESOURCE_TYPE_LISTENER:
if err := d.deployToListener(ctx, upres.CertId); err != nil {
return nil, err
}
default:
return nil, fmt.Errorf("unsupported resource type: %s", d.config.ResourceType)
}
return &deployer.DeployResult{}, nil
}
func (d *DeployerProvider) deployToLoadbalancer(ctx context.Context, cloudCertId string) error {
if d.config.LoadbalancerId == "" {
return errors.New("config `loadbalancerId` is required")
}
// 查询负载均衡器详情
// REF: https://docs.jdcloud.com/cn/load-balancer/api/describeloadbalancer
describeLoadBalancerReq := jdLbApi.NewDescribeLoadBalancerRequest(d.config.RegionId, d.config.LoadbalancerId)
describeLoadBalancerResp, err := d.sdkClient.DescribeLoadBalancer(describeLoadBalancerReq)
if err != nil {
return xerrors.Wrap(err, "failed to execute sdk request 'lb.DescribeLoadBalancer'")
} else {
d.logger.Logt("已查询到负载均衡器详情", describeLoadBalancerResp)
}
// 查询监听器列表
// REF: https://docs.jdcloud.com/cn/load-balancer/api/describelisteners
listenerIds := make([]string, 0)
describeListenersPageNumber := 1
describeListenersPageSize := 100
for {
describeListenersReq := jdLbApi.NewDescribeListenersRequest(d.config.RegionId)
describeListenersReq.SetFilters([]jdCommon.Filter{{Name: "loadBalancerId", Values: []string{d.config.LoadbalancerId}}})
describeListenersReq.SetPageSize(describeListenersPageNumber)
describeListenersReq.SetPageSize(describeListenersPageSize)
describeListenersResp, err := d.sdkClient.DescribeListeners(describeListenersReq)
if err != nil {
return xerrors.Wrap(err, "failed to execute sdk request 'lb.DescribeListeners'")
}
for _, listener := range describeListenersResp.Result.Listeners {
if strings.EqualFold(listener.Protocol, "https") || strings.EqualFold(listener.Protocol, "tls") {
listenerIds = append(listenerIds, listener.ListenerId)
}
}
if len(describeListenersResp.Result.Listeners) < int(describeListenersPageSize) {
break
} else {
describeListenersPageNumber++
}
}
// 遍历更新监听器证书
if len(listenerIds) == 0 {
return errors.New("listener not found")
} else {
d.logger.Logt("已查询到负载均衡器下的全部 HTTPS/TLS 监听器", listenerIds)
var errs []error
for _, listenerId := range listenerIds {
if err := d.updateListenerCertificate(ctx, listenerId, cloudCertId); err != nil {
errs = append(errs, err)
}
}
if len(errs) > 0 {
return errors.Join(errs...)
}
}
return nil
}
func (d *DeployerProvider) deployToListener(ctx context.Context, cloudCertId string) error {
if d.config.ListenerId == "" {
return errors.New("config `listenerId` is required")
}
// 更新监听器证书
if err := d.updateListenerCertificate(ctx, d.config.ListenerId, cloudCertId); err != nil {
return err
}
return nil
}
func (d *DeployerProvider) updateListenerCertificate(ctx context.Context, cloudListenerId string, cloudCertId string) error {
// 查询监听器详情
// REF: https://docs.jdcloud.com/cn/load-balancer/api/describelistener
describeListenerReq := jdLbApi.NewDescribeListenerRequest(d.config.RegionId, cloudListenerId)
describeListenerResp, err := d.sdkClient.DescribeListener(describeListenerReq)
if err != nil {
return xerrors.Wrap(err, "failed to execute sdk request 'lb.DescribeListener'")
} else {
d.logger.Logt("已查询到监听器详情", describeListenerResp)
}
if d.config.Domain == "" {
// 未指定 SNI只需部署到监听器
// 修改监听器信息
// REF: https://docs.jdcloud.com/cn/load-balancer/api/updatelistener
updateListenerReq := jdLbApi.NewUpdateListenerRequest(d.config.RegionId, cloudListenerId)
updateListenerReq.SetCertificateSpecs([]jdLbModel.CertificateSpec{{CertificateId: cloudCertId}})
updateListenerResp, err := d.sdkClient.UpdateListener(updateListenerReq)
if err != nil {
return xerrors.Wrap(err, "failed to execute sdk request 'lb.UpdateListener'")
} else {
d.logger.Logt("已修改监听器信息", updateListenerResp)
}
} else {
// 指定 SNI需部署到扩展证书
extCertSpecs := slices.Filter(describeListenerResp.Result.Listener.ExtensionCertificateSpecs, func(extCertSpec jdLbModel.ExtensionCertificateSpec) bool {
return extCertSpec.Domain == d.config.Domain
})
if len(extCertSpecs) == 0 {
return errors.New("extension certificate spec not found")
}
// 批量修改扩展证书
// REF: https://docs.jdcloud.com/cn/load-balancer/api/updatelistenercertificates
updateListenerCertificatesReq := jdLbApi.NewUpdateListenerCertificatesRequest(
d.config.RegionId,
cloudListenerId,
slices.Map(extCertSpecs, func(extCertSpec jdLbModel.ExtensionCertificateSpec) jdLbModel.ExtCertificateUpdateSpec {
return jdLbModel.ExtCertificateUpdateSpec{
CertificateBindId: extCertSpec.CertificateBindId,
CertificateId: &cloudCertId,
Domain: &extCertSpec.Domain,
}
}),
)
updateListenerCertificatesResp, err := d.sdkClient.UpdateListenerCertificates(updateListenerCertificatesReq)
if err != nil {
return xerrors.Wrap(err, "failed to execute sdk request 'lb.UpdateListenerCertificates'")
} else {
d.logger.Logt("已批量修改扩展证书", updateListenerCertificatesResp)
}
}
return nil
}
func createSdkClient(accessKeyId, accessKeySecret string) (*jdLbClient.LbClient, error) {
clientCredentials := jdCore.NewCredentials(accessKeyId, accessKeySecret)
client := jdLbClient.NewLbClient(clientCredentials)
client.SetLogger(jdCore.NewDefaultLogger(jdCore.LogWarn))
return client, nil
}

View File

@ -0,0 +1,118 @@
package jdcloudalb_test
import (
"context"
"flag"
"fmt"
"os"
"strings"
"testing"
provider "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/jdcloud-alb"
)
var (
fInputCertPath string
fInputKeyPath string
fAccessKeyId string
fAccessKeySecret string
fRegionId string
fLoadbalancerId string
fListenerId string
)
func init() {
argsPrefix := "CERTIMATE_DEPLOYER_JDCLOUDALB_"
flag.StringVar(&fInputCertPath, argsPrefix+"INPUTCERTPATH", "", "")
flag.StringVar(&fInputKeyPath, argsPrefix+"INPUTKEYPATH", "", "")
flag.StringVar(&fAccessKeyId, argsPrefix+"ACCESSKEYID", "", "")
flag.StringVar(&fAccessKeySecret, argsPrefix+"ACCESSKEYSECRET", "", "")
flag.StringVar(&fRegionId, argsPrefix+"REGIONID", "", "")
flag.StringVar(&fLoadbalancerId, argsPrefix+"LOADBALANCERID", "", "")
flag.StringVar(&fListenerId, argsPrefix+"LISTENERID", "", "")
}
/*
Shell command to run this test:
go test -v ./jdcloud_alb_test.go -args \
--CERTIMATE_DEPLOYER_JDCLOUDALB_INPUTCERTPATH="/path/to/your-input-cert.pem" \
--CERTIMATE_DEPLOYER_JDCLOUDALB_INPUTKEYPATH="/path/to/your-input-key.pem" \
--CERTIMATE_DEPLOYER_JDCLOUDALB_ACCESSKEYID="your-access-key-id" \
--CERTIMATE_DEPLOYER_JDCLOUDALB_ACCESSKEYSECRET="your-secret-access-key" \
--CERTIMATE_DEPLOYER_JDCLOUDALB_REGION_ID="cn-north-1" \
--CERTIMATE_DEPLOYER_JDCLOUDALB_LOADBALANCERID="your-alb-loadbalancer-id" \
--CERTIMATE_DEPLOYER_JDCLOUDALB_LISTENERID="your-alb-listener-id"
*/
func TestDeploy(t *testing.T) {
flag.Parse()
t.Run("Deploy_ToLoadbalancer", func(t *testing.T) {
t.Log(strings.Join([]string{
"args:",
fmt.Sprintf("INPUTCERTPATH: %v", fInputCertPath),
fmt.Sprintf("INPUTKEYPATH: %v", fInputKeyPath),
fmt.Sprintf("ACCESSKEYID: %v", fAccessKeyId),
fmt.Sprintf("ACCESSKEYSECRET: %v", fAccessKeySecret),
fmt.Sprintf("REGIONID: %v", fRegionId),
fmt.Sprintf("LOADBALANCERID: %v", fLoadbalancerId),
}, "\n"))
deployer, err := provider.NewDeployer(&provider.DeployerConfig{
AccessKeyId: fAccessKeyId,
AccessKeySecret: fAccessKeySecret,
RegionId: fRegionId,
ResourceType: provider.RESOURCE_TYPE_LOADBALANCER,
LoadbalancerId: fLoadbalancerId,
})
if err != nil {
t.Errorf("err: %+v", err)
return
}
fInputCertData, _ := os.ReadFile(fInputCertPath)
fInputKeyData, _ := os.ReadFile(fInputKeyPath)
res, err := deployer.Deploy(context.Background(), string(fInputCertData), string(fInputKeyData))
if err != nil {
t.Errorf("err: %+v", err)
return
}
t.Logf("ok: %v", res)
})
t.Run("Deploy_ToListener", func(t *testing.T) {
t.Log(strings.Join([]string{
"args:",
fmt.Sprintf("INPUTCERTPATH: %v", fInputCertPath),
fmt.Sprintf("INPUTKEYPATH: %v", fInputKeyPath),
fmt.Sprintf("ACCESSKEYID: %v", fAccessKeyId),
fmt.Sprintf("ACCESSKEYSECRET: %v", fAccessKeySecret),
fmt.Sprintf("REGIONID: %v", fRegionId),
fmt.Sprintf("LISTENERID: %v", fListenerId),
}, "\n"))
deployer, err := provider.NewDeployer(&provider.DeployerConfig{
AccessKeyId: fAccessKeyId,
AccessKeySecret: fAccessKeySecret,
RegionId: fRegionId,
ResourceType: provider.RESOURCE_TYPE_LISTENER,
ListenerId: fListenerId,
})
if err != nil {
t.Errorf("err: %+v", err)
return
}
fInputCertData, _ := os.ReadFile(fInputCertPath)
fInputKeyData, _ := os.ReadFile(fInputKeyPath)
res, err := deployer.Deploy(context.Background(), string(fInputCertData), string(fInputKeyData))
if err != nil {
t.Errorf("err: %+v", err)
return
}
t.Logf("ok: %v", res)
})
}

Some files were not shown because too many files have changed in this diff Show More