Compare commits

...

77 Commits

Author SHA1 Message Date
RHQYZ
c3e7590f53 bump version to v0.3.16 2025-06-03 23:50:48 +08:00
RHQYZ
65cd1dc850 Merge pull request #761 from fudiwei/feat/providers
new providers
2025-06-03 23:48:27 +08:00
RHQYZ
2203bb5268 Merge pull request #760 from fudiwei/bugfix
bugfix: could not add branches in workflows
2025-06-03 23:48:13 +08:00
Fu Diwei
8e5c36968a chore: improve error 2025-06-03 23:45:00 +08:00
Fu Diwei
9ad0e6fb57 feat: support ssh challenge-response 2025-06-03 23:39:48 +08:00
Fu Diwei
7d55383cf7 feat: new deployment provider: aws iam 2025-06-03 23:39:48 +08:00
Fu Diwei
6dc65eea2f feat: new acme dns-01 provider: ucloud udnr 2025-06-03 23:39:48 +08:00
Fu Diwei
7210f63884 feat: new acme dns-01 provider: constellix 2025-06-03 23:39:42 +08:00
Fu Diwei
f94db675fb fix: could not add branches in workflows 2025-06-03 22:37:03 +08:00
RHQYZ
e6cf4d3e07 bump version to v0.3.15 2025-06-02 23:10:34 +08:00
RHQYZ
cc5098c4bc Merge pull request #755 from fudiwei/main
Support duplicating workflow nodes or branches
2025-06-02 23:09:14 +08:00
Fu Diwei
025e606db4 feat(ui): duplicate workflow node 2025-06-02 23:06:18 +08:00
RHQYZ
d3e8bacd58 Merge pull request #742 from tailorvii/wangsu
fix: wangsu get certificate list api error #741
2025-06-01 23:05:10 +08:00
RHQYZ
308b21bb33 Merge pull request #734 from fudiwei/bugfix
bugfix
2025-06-01 23:04:53 +08:00
RHQYZ
262c1d7fcb Merge pull request #735 from fudiwei/feat/providers
enhance providers
2025-06-01 23:04:42 +08:00
RHQYZ
722c3a0e83 Merge pull request #712 from usual2970/feat/condition
workflow conditional branch & monitoring node
2025-06-01 23:04:31 +08:00
Fu Diwei
f885b49daf feat: add certtest workflow template 2025-06-01 22:59:24 +08:00
Fu Diwei
6731c465e7 refactor: workflow condition node
refactor: workflow condition node
2025-05-31 17:30:37 +08:00
Fu Diwei
28811c46d8 fix: #746 2025-05-31 16:29:17 +08:00
tailor
599cf17c9e fix: wangsu get certificate list api error 2025-05-29 11:24:30 +08:00
Fu Diwei
f0af36b59e refactor: clean code 2025-05-28 22:43:18 +08:00
Fu Diwei
e73e2739c1 feat: use discard handler as default providers logger 2025-05-28 22:21:41 +08:00
Fu Diwei
efdeacf01a feat: add preset webhook template for serverchan3 2025-05-28 21:39:02 +08:00
Fu Diwei
3a829ad53b refactor: workflow monitor(aka inspect) node 2025-05-28 21:05:56 +08:00
Yoan.liu
605de595b1 remove upx compression 2025-05-28 20:34:18 +08:00
Fu Diwei
daf22b7f15 feat: initialize aliyun fc ssl protocol 2025-05-28 16:44:11 +08:00
Fu Diwei
0e8ebaa885 fix: #732 2025-05-28 14:51:18 +08:00
Fu Diwei
829fa29cf1 feat: add user-agent http header for thirdparty sdks 2025-05-28 10:46:02 +08:00
Fu Diwei
ddb46f9dda refactor: clean code 2025-05-28 10:17:33 +08:00
Fu Diwei
df1f216b5b feat: support configuring aliyun resource group id 2025-05-27 21:19:06 +08:00
Fu Diwei
b8b94dfd77 feat: support configuring huaweicloud enterprise project id 2025-05-27 21:19:02 +08:00
Fu Diwei
4489096e57 Merge branch 'main' into feat/condition 2025-05-27 05:36:42 +08:00
Fu Diwei
a4f736e0f3 build: fix goreleaser.yml 2025-05-27 05:04:35 +08:00
Fu Diwei
d8935337d6 build: fix goreleaser.yml 2025-05-27 04:59:38 +08:00
Fu Diwei
211f66dc0a fix: tsc build error 2025-05-27 04:43:44 +08:00
RHQYZ
d964b129b0 bump version to v0.3.14 2025-05-27 04:35:10 +08:00
RHQYZ
a758b1d6d4 Merge pull request #727 from fudiwei/feat/providers
new providers
2025-05-27 04:34:07 +08:00
Fu Diwei
037305d8cd update README 2025-05-27 04:31:26 +08:00
Fu Diwei
cfdd3c621f feat: new deployment provider: unicloud webhost 2025-05-27 04:29:51 +08:00
Fu Diwei
5339963524 feat(ui): improve i18n 2025-05-26 23:02:57 +08:00
RHQYZ
af7d05e669 Merge pull request #726 from fudiwei/feat/providers
new providers
2025-05-26 21:52:02 +08:00
Fu Diwei
bf1d03a30e feat(migration): tracer 2025-05-26 21:49:37 +08:00
Fu Diwei
3bb88d9f93 chore(deps): upgrade npm dependencies 2025-05-26 17:04:40 +08:00
Fu Diwei
b0eb71421f chore(deps): upgrade go mod dependencies 2025-05-26 16:55:15 +08:00
Fu Diwei
e82a59289b feat: new notification provider: slack bot 2025-05-26 16:41:44 +08:00
Fu Diwei
8e23b14bf3 feat: new notification provider: discord bot 2025-05-26 16:41:38 +08:00
Fu Diwei
cd9dac7765 feat: new acme dns-01 provider: duckdns 2025-05-26 13:59:22 +08:00
Fu Diwei
40f4488009 feat: new acme dns-01 provider: digitalocean 2025-05-26 13:59:22 +08:00
Fu Diwei
4c13a3e86a feat: new acme dns-01 provider: hetzner 2025-05-26 13:59:16 +08:00
Fu Diwei
b139139f50 Merge branch 'main' into feat/providers 2025-05-26 11:37:01 +08:00
RHQYZ
55e16f4b17 Merge pull request #725 from fudiwei/bugfix
bugfix
2025-05-26 11:30:31 +08:00
Fu Diwei
46b4ff73c9 fix: ari double renewal error 2025-05-26 11:29:04 +08:00
Fu Diwei
970a1f0f79 fix: i18n error in AccessEditModal 2025-05-26 10:17:25 +08:00
Fu Diwei
11ff80ab28 fix: #723 2025-05-26 09:27:33 +08:00
Fu Diwei
7cd036f41e fix: #724 2025-05-26 09:26:11 +08:00
Fu Diwei
0909671be6 refactor: clean code 2025-05-25 23:32:41 +08:00
Fu Diwei
b798b824db refactor(ui): MultipleSplitValueInput 2025-05-25 23:05:08 +08:00
Fu Diwei
71c093c042 refactor: clean code 2025-05-25 21:54:39 +08:00
Yoan.liu
9878c12512 Merge pull request #722 from KukiSa/main
Fix Netlify Site Inversion of ca_certificates and key
2025-05-25 08:30:14 +08:00
Signaliks
b43797a0fb Update models.go 2025-05-24 21:32:34 +08:00
Yoan.liu
312589ab1c reduce the binary size 2025-05-23 17:23:36 +08:00
Yoan.liu
bff8add010 Merge branch 'main' of github.com:usual2970/certimate 2025-05-23 16:48:54 +08:00
Yoan.liu
6b9f295167 update Dockerfile 2025-05-23 16:48:41 +08:00
Yoan.liu
9cdc59b272 refactor code 2025-05-22 17:09:14 +08:00
RHQYZ
0e8b271e8d Merge pull request #716 from fudiwei/bugfix
bugfix
2025-05-21 20:31:09 +08:00
Fu Diwei
87aae4087c fix: #706 2025-05-21 20:28:21 +08:00
Yoan.liu
75326b1ddd refactor code 2025-05-21 15:59:02 +08:00
Yoan.liu
7d8dd523a2 Merge branch 'main' into feat/condition 2025-05-21 13:51:23 +08:00
Yoan.liu
993ca36755 add certificate mornitoring node 2025-05-21 13:48:54 +08:00
Yoan.liu
faad7cb6d7 improve condition evaluate 2025-05-20 22:54:41 +08:00
Yoan.liu
97d692910b expression evaluate 2025-05-20 18:09:42 +08:00
Yoan.liu
b546cf3ad0 multi language support 2025-05-20 14:55:48 +08:00
Yoan.liu
6353f0139b improve variable types 2025-05-20 11:01:04 +08:00
Yoan.liu
1e67e9333e condition render 2025-05-19 21:59:37 +08:00
Yoan.liu
6f054ee594 update readme 2025-05-19 18:16:21 +08:00
Yoan.liu
05d43f38ce improve previous variables 2025-05-19 18:15:04 +08:00
Yoan.liu
b8ab077b57 improve ui 2025-05-19 17:41:39 +08:00
349 changed files with 8277 additions and 2561 deletions

View File

@@ -24,6 +24,11 @@ jobs:
with:
go-version-file: "go.mod"
# - name: Install upx (optional)
# run: |
# sudo apt-get update
# sudo apt-get install -y upx
- name: Build WebUI
run: |
npm --prefix=./ui ci
@@ -44,3 +49,4 @@ jobs:
args: release --clean
env:
GITHUB_TOKEN: ${{ secrets.RELEASE_TOKEN }}

View File

@@ -30,6 +30,9 @@ builds:
- goos: darwin
goarch: arm
# upx:
# - enabled: true
release:
draft: true

View File

@@ -13,7 +13,8 @@ WORKDIR /app
COPY ../. /app/
RUN rm -rf /app/ui/dist
COPY --from=webui-builder /app/ui/dist /app/ui/dist
RUN go build -o certimate
ENV CGO_ENABLED=0
RUN go build -ldflags="-s -w" -o certimate

View File

@@ -21,7 +21,8 @@ $(OS_ARCH):
@mkdir -p $(BUILD_DIR)
GOOS=$(word 1,$(subst /, ,$@)) \
GOARCH=$(word 2,$(subst /, ,$@)) \
go build -o $(BUILD_DIR)/$(BINARY_NAME)_$(word 1,$(subst /, ,$@))_$(word 2,$(subst /, ,$@)) -ldflags="-X main.version=$(VERSION)" .
CGO_ENABLED=0 \
go build -o $(BUILD_DIR)/$(BINARY_NAME)_$(word 1,$(subst /, ,$@))_$(word 2,$(subst /, ,$@)) -ldflags="-X main.version=$(VERSION) -s -w" .
# 清理构建文件
clean:

View File

@@ -22,7 +22,7 @@
做个人产品或者在中小企业里负责运维的同学,会遇到要管理多个域名的情况,需要给域名申请证书。但是手动申请证书有以下缺点:
- 😱 麻烦:申请证书并部署到服务的流程虽不复杂,但也挺麻烦的,其是你有多个域名需要维护的时候。
- 😱 麻烦:申请证书并部署到服务的流程虽不复杂,但也挺麻烦的,其是你有多个域名需要维护的时候。
- 😭 易忘:另外当前免费证书的有效期只有 90 天,这就要求你定期的操作,增加了工作量的同时,你也很容易忘掉续期,从而导致网站访问不了。
Certimate 就是为了解决上述问题而产生的,它具有以下优势:
@@ -39,7 +39,7 @@ Certimate 旨在为用户提供一个安全、简便的 SSL 证书管理解决
- 支持单域名、多域名、泛域名证书,可选 RSA、ECC 签名算法;
- 支持 PEM、PFX、JKS 等多种格式输出证书;
- 支持 30+ 域名托管商如阿里云、腾讯云、Cloudflare 等,[点此查看完整清单](https://docs.certimate.me/docs/reference/providers#supported-dns-providers)
- 支持 80+ 部署目标(如 Kubernetes、CDN、WAF、负载均衡等[点此查看完整清单](https://docs.certimate.me/docs/reference/providers#supported-hosting-providers)
- 支持 90+ 部署目标(如 Kubernetes、CDN、WAF、负载均衡等[点此查看完整清单](https://docs.certimate.me/docs/reference/providers#supported-hosting-providers)
- 支持邮件、钉钉、飞书、企业微信、Webhook 等多种通知渠道;
- 支持 Let's Encrypt、Buypass、Google Trust Services、SSL.com、ZeroSSL 等多种 ACME 证书颁发机构;
- 更多特性等待探索。

View File

@@ -39,7 +39,7 @@ Certimate aims to provide users with a secure and user-friendly SSL certificate
- Supports single-domain, multi-domain, wildcard certificates, with options for RSA or ECC.
- Supports various certificate formats such as PEM, PFX, JKS.
- Supports more than 30+ domain registrars (e.g., Alibaba Cloud, Tencent Cloud, Cloudflare, etc. [Check out this link](https://docs.certimate.me/en/docs/reference/providers#supported-dns-providers));
- Supports more than 80+ deployment targets (e.g., Kubernetes, CDN, WAF, load balancers, etc. [Check out this link](https://docs.certimate.me/en/docs/reference/providers#supported-hosting-providers));
- Supports more than 90+ deployment targets (e.g., Kubernetes, CDN, WAF, load balancers, etc. [Check out this link](https://docs.certimate.me/en/docs/reference/providers#supported-hosting-providers));
- Supports multiple notification channels including email, DingTalk, Feishu, WeCom, Webhook, and more;
- Supports multiple ACME CAs including Let's Encrypt, Buypass, Google Trust ServicesSSL.com, ZeroSSL, and more;
- More features waiting to be discovered.

47
go.mod
View File

@@ -6,7 +6,7 @@ toolchain go1.24.3
require (
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.18.0
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.9.0
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.10.0
github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azcertificates v1.3.1
github.com/Edgio/edgio-api v0.0.0-workspace
github.com/G-Core/gcorelabscdn-go v1.0.31
@@ -14,10 +14,10 @@ require (
github.com/alibabacloud-go/apig-20240327/v3 v3.2.2
github.com/alibabacloud-go/cas-20200407/v3 v3.0.4
github.com/alibabacloud-go/cdn-20180510/v5 v5.2.2
github.com/alibabacloud-go/cloudapi-20160714/v5 v5.7.3
github.com/alibabacloud-go/cloudapi-20160714/v5 v5.7.4
github.com/alibabacloud-go/darabonba-openapi/v2 v2.1.7
github.com/alibabacloud-go/ddoscoo-20200101/v4 v4.0.0
github.com/alibabacloud-go/esa-20240910/v2 v2.32.0
github.com/alibabacloud-go/esa-20240910/v2 v2.33.0
github.com/alibabacloud-go/fc-20230330/v4 v4.3.5
github.com/alibabacloud-go/fc-open-20210406/v2 v2.0.12
github.com/alibabacloud-go/ga-20191120/v3 v3.1.8
@@ -26,18 +26,18 @@ require (
github.com/alibabacloud-go/slb-20140515/v4 v4.0.10
github.com/alibabacloud-go/tea v1.3.9
github.com/alibabacloud-go/vod-20170321/v4 v4.8.4
github.com/alibabacloud-go/waf-openapi-20211001/v5 v5.1.2
github.com/alibabacloud-go/waf-openapi-20211001/v5 v5.1.3
github.com/aliyun/aliyun-oss-go-sdk v3.0.2+incompatible
github.com/aws/aws-sdk-go-v2/service/acm v1.32.0
github.com/aws/aws-sdk-go-v2/service/cloudfront v1.46.1
github.com/baidubce/bce-sdk-go v0.9.226
github.com/baidubce/bce-sdk-go v0.9.228
github.com/blinkbean/dingtalk v1.1.3
github.com/byteplus-sdk/byteplus-sdk-golang v1.0.46
github.com/go-acme/lego/v4 v4.23.1
github.com/go-lark/lark v1.16.0
github.com/go-resty/resty/v2 v2.16.5
github.com/go-viper/mapstructure/v2 v2.2.1
github.com/huaweicloud/huaweicloud-sdk-go-v3 v0.1.148
github.com/huaweicloud/huaweicloud-sdk-go-v3 v0.1.150
github.com/jdcloud-api/jdcloud-sdk-go v1.64.0
github.com/libdns/dynv6 v1.0.0
github.com/libdns/libdns v0.2.3
@@ -45,29 +45,29 @@ require (
github.com/pavlo-v-chernykh/keystore-go/v4 v4.5.0
github.com/pkg/sftp v1.13.9
github.com/pocketbase/dbx v1.11.0
github.com/pocketbase/pocketbase v0.28.0
github.com/pocketbase/pocketbase v0.28.2
github.com/povsister/scp v0.0.0-20250504051308-e467f71ea63c
github.com/qiniu/go-sdk/v7 v7.25.3
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cdn v1.0.1155
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/clb v1.0.1161
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1162
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/clb v1.0.1166
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1173
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/live v1.0.1150
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/scf v1.0.1120
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/ssl v1.0.1124
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/teo v1.0.1162
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/vod v1.0.1160
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/waf v1.0.1162
github.com/ucloud/ucloud-sdk-go v0.22.35
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/scf v1.0.1172
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/ssl v1.0.1169
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/teo v1.0.1166
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/vod v1.0.1164
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/waf v1.0.1170
github.com/ucloud/ucloud-sdk-go v0.22.41
github.com/volcengine/ve-tos-golang-sdk/v2 v2.7.12
github.com/volcengine/volc-sdk-golang v1.0.207
github.com/volcengine/volcengine-go-sdk v1.1.7
github.com/volcengine/volc-sdk-golang v1.0.208
github.com/volcengine/volcengine-go-sdk v1.1.8
gitlab.ecloud.com/ecloud/ecloudsdkclouddns v1.0.1
gitlab.ecloud.com/ecloud/ecloudsdkcore v1.0.0
golang.org/x/crypto v0.38.0
golang.org/x/exp v0.0.0-20250506013437-ce4c2cf36ca6
k8s.io/api v0.33.0
k8s.io/apimachinery v0.33.0
k8s.io/client-go v0.33.0
k8s.io/api v0.33.1
k8s.io/apimachinery v0.33.1
k8s.io/client-go v0.33.1
software.sslmate.com/src/go-pkcs12 v0.5.0
)
@@ -85,6 +85,7 @@ require (
github.com/alibabacloud-go/tea-oss-utils v1.1.0 // indirect
github.com/alibabacloud-go/tea-utils/v2 v2.0.7 // indirect
github.com/avast/retry-go v3.0.0+incompatible // indirect
github.com/aws/aws-sdk-go-v2/service/iam v1.42.0 // indirect
github.com/aws/aws-sdk-go-v2/service/route53 v1.50.0 // indirect
github.com/buger/goterm v1.0.4 // indirect
github.com/diskfs/go-diskfs v1.5.0 // indirect
@@ -211,10 +212,10 @@ require (
google.golang.org/protobuf v1.36.5 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
modernc.org/libc v1.62.1 // indirect
modernc.org/libc v1.65.7 // indirect
modernc.org/mathutil v1.7.1 // indirect
modernc.org/memory v1.9.1 // indirect
modernc.org/sqlite v1.37.0 // indirect
modernc.org/memory v1.11.0 // indirect
modernc.org/sqlite v1.37.1 // indirect
)
replace github.com/Edgio/edgio-api v0.0.0-workspace => ./internal/pkg/sdk3rd/edgio/edgio-api@v0.0.0-workspace

119
go.sum
View File

@@ -36,8 +36,8 @@ filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4
github.com/Azure/azure-sdk-for-go v68.0.0+incompatible h1:fcYLmCpyNYRnvJbPerq7U0hS+6+I79yEDJBqVNcqUzU=
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.18.0 h1:Gt0j3wceWMwPmiazCa8MzMA0MfhmPIz0Qp0FJ6qcM0U=
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.18.0/go.mod h1:Ot/6aikWnKWi4l9QB7qVSwa8iMphQNqkWALMoNT3rzM=
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.9.0 h1:OVoM452qUFBrX+URdH3VpR299ma4kfom0yB0URYky9g=
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.9.0/go.mod h1:kUjrAo8bgEwLeZ/CmHqNl3Z/kPm7y6FKfxxK0izYUg4=
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.10.0 h1:j8BorDEigD8UFOSZQiSqAMOOleyQOOQPnUAwV+Ls1gA=
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.10.0/go.mod h1:JdM5psgjfBf5fo2uWOZhflPWyDBZ/O/CNAH9CtsuZE4=
github.com/Azure/azure-sdk-for-go/sdk/azidentity/cache v0.3.2 h1:yz1bePFlP5Vws5+8ez6T3HWXPmwOK7Yvq8QxDBD3SKY=
github.com/Azure/azure-sdk-for-go/sdk/azidentity/cache v0.3.2/go.mod h1:Pa9ZNPuoNu/GztvBSKk9J1cDJW6vk/n0zLtV4mgd8N8=
github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.1 h1:FPKJS1T+clwv+OLGt13a8UjqeRuh0O4SJ3lUriThc+4=
@@ -101,8 +101,8 @@ github.com/alibabacloud-go/cas-20200407/v3 v3.0.4 h1:ngRlctbt135zoujwX0lXSv9m4h1
github.com/alibabacloud-go/cas-20200407/v3 v3.0.4/go.mod h1:6n9MZ9SH3HlSzfe2oKwjOqhJx3dxvW2gMDO+lq8t9U4=
github.com/alibabacloud-go/cdn-20180510/v5 v5.2.2 h1:+KJOPukTM+xMyiLOW5qBwYKG2df3Ar7coRsqc1juKO8=
github.com/alibabacloud-go/cdn-20180510/v5 v5.2.2/go.mod h1:GnPiPL3HlzCi8SGiLiVgKrAFkP1vTtcF4yGtjsl4wfo=
github.com/alibabacloud-go/cloudapi-20160714/v5 v5.7.3 h1:OTLn0ShbE0jJj+5Z+P76zeHsZYxZjO7YVThQoeaBM9M=
github.com/alibabacloud-go/cloudapi-20160714/v5 v5.7.3/go.mod h1:eUmD1G4BjEBOAHIeJrHJL7pyLGgXSRTPLjBmYY7uPEg=
github.com/alibabacloud-go/cloudapi-20160714/v5 v5.7.4 h1:SsyAoXM1R4J3I4xQdPW/rRW8cTo2KN440/4h/pGiwRQ=
github.com/alibabacloud-go/cloudapi-20160714/v5 v5.7.4/go.mod h1:eUmD1G4BjEBOAHIeJrHJL7pyLGgXSRTPLjBmYY7uPEg=
github.com/alibabacloud-go/darabonba-array v0.1.0 h1:vR8s7b1fWAQIjEjWnuF0JiKsCvclSRTfDzZHTYqfufY=
github.com/alibabacloud-go/darabonba-array v0.1.0/go.mod h1:BLKxr0brnggqOJPqT09DFJ8g3fsDshapUD3C3aOEFaI=
github.com/alibabacloud-go/darabonba-encode-util v0.0.2 h1:1uJGrbsGEVqWcWxrS9MyC2NG0Ax+GpOM5gtupki31XE=
@@ -132,8 +132,8 @@ github.com/alibabacloud-go/debug v1.0.1/go.mod h1:8gfgZCCAC3+SCzjWtY053FrOcd4/ql
github.com/alibabacloud-go/endpoint-util v1.1.0/go.mod h1:O5FuCALmCKs2Ff7JFJMudHs0I5EBgecXXxZRyswlEjE=
github.com/alibabacloud-go/endpoint-util v1.1.1 h1:ZkBv2/jnghxtU0p+upSU0GGzW1VL9GQdZO3mcSUTUy8=
github.com/alibabacloud-go/endpoint-util v1.1.1/go.mod h1:O5FuCALmCKs2Ff7JFJMudHs0I5EBgecXXxZRyswlEjE=
github.com/alibabacloud-go/esa-20240910/v2 v2.32.0 h1:eudSgNIkCg6huIu3HuF16BJG6+CA6bIuIddxpuPydpg=
github.com/alibabacloud-go/esa-20240910/v2 v2.32.0/go.mod h1:HZS5PmYJvcmH4vrJYuCvK3AnYzD9hLlO8CT0hgRyDXo=
github.com/alibabacloud-go/esa-20240910/v2 v2.33.0 h1:10IWxrMcF1W6/7BUJIJifrofduSG0wRFqDbRfIsR3Zw=
github.com/alibabacloud-go/esa-20240910/v2 v2.33.0/go.mod h1:HZS5PmYJvcmH4vrJYuCvK3AnYzD9hLlO8CT0hgRyDXo=
github.com/alibabacloud-go/fc-20230330/v4 v4.3.5 h1:nDNjVzGwkQPbQnAuxAmxvS9x8QGLph8j0ptEdZDPGBA=
github.com/alibabacloud-go/fc-20230330/v4 v4.3.5/go.mod h1:vEJimQ6E/e+m2z0/oXdeQWlFw/Pi/Ar6NKcMrSvcILE=
github.com/alibabacloud-go/fc-open-20210406/v2 v2.0.12 h1:A3D8Mp6qf8DfR6Dt5MpS8aDVaWfS4N85T5CvGUvgrjM=
@@ -190,8 +190,8 @@ github.com/alibabacloud-go/tea-xml v1.1.3 h1:7LYnm+JbOq2B+T/B0fHC4Ies4/FofC4zHzY
github.com/alibabacloud-go/tea-xml v1.1.3/go.mod h1:Rq08vgCcCAjHyRi/M7xlHKUykZCEtyBy9+DPF6GgEu8=
github.com/alibabacloud-go/vod-20170321/v4 v4.8.4 h1:MYP2xfrcud8vlWljQ4lhemNgAgi9/AUAa450n8TUXZo=
github.com/alibabacloud-go/vod-20170321/v4 v4.8.4/go.mod h1:5ocQ6hIc9tpGixD2iy099aOGwIgpzjT2le4Krd4aLn8=
github.com/alibabacloud-go/waf-openapi-20211001/v5 v5.1.2 h1:CmhJzCZ5RiSiWU6BV2XJUtIMD2LDo9FFfqlYGtx1aAw=
github.com/alibabacloud-go/waf-openapi-20211001/v5 v5.1.2/go.mod h1:9itYSTzipL3NlvhvNYfTjFaapoZzG68nlu/KUdh9SpA=
github.com/alibabacloud-go/waf-openapi-20211001/v5 v5.1.3 h1:25tmcJxIitrk55crBGssPlqRzmFcpGVW5TEFxdUvfg0=
github.com/alibabacloud-go/waf-openapi-20211001/v5 v5.1.3/go.mod h1:9itYSTzipL3NlvhvNYfTjFaapoZzG68nlu/KUdh9SpA=
github.com/aliyun/alibaba-cloud-sdk-go v1.63.100 h1:yUkCbrSM1cWtgBfRVKMQtdt22KhDvKY7g4V+92eG9wA=
github.com/aliyun/alibaba-cloud-sdk-go v1.63.100/go.mod h1:SOSDHfe1kX91v3W5QiBsWSLqeLxImobbMX1mxrFHsVQ=
github.com/aliyun/aliyun-oss-go-sdk v3.0.2+incompatible h1:8psS8a+wKfiLt1iVDX79F7Y6wUM49Lcha2FMXt4UM8g=
@@ -235,6 +235,8 @@ github.com/aws/aws-sdk-go-v2/service/acm v1.32.0/go.mod h1:3sKYAgRbuBa2QMYGh/WEc
github.com/aws/aws-sdk-go-v2/service/cloudfront v1.46.1 h1:6xZNYtuVwzBs8k+TmraERt0vL68Ppg9aUi+aTQmPaVM=
github.com/aws/aws-sdk-go-v2/service/cloudfront v1.46.1/go.mod h1:FIBJ48TS+qJb+Ne4qJ+0NeIhtPTVXItXooTeNeVI4Po=
github.com/aws/aws-sdk-go-v2/service/cloudwatch v1.8.1/go.mod h1:CM+19rL1+4dFWnOQKwDc7H1KwXTz+h61oUSHyhV0b3o=
github.com/aws/aws-sdk-go-v2/service/iam v1.42.0 h1:G6+UzGvubaet9QOh0664E9JeT+b6Zvop3AChozRqkrA=
github.com/aws/aws-sdk-go-v2/service/iam v1.42.0/go.mod h1:mPJkGQzeCoPs82ElNILor2JzZgYENr4UaSKUT8K27+c=
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.3 h1:eAh2A4b5IzM/lum78bZ590jy36+d/aFLgKF/4Vd1xPE=
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.3/go.mod h1:0yKJC/kb8sAnmlYa6Zs3QVYqaC8ug2AbnNChv5Ox3uA=
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.15 h1:dM9/92u2F1JbDaGooxTq18wmmFzbJRfXfVfy96/1CXM=
@@ -250,8 +252,8 @@ github.com/aws/aws-sdk-go-v2/service/sts v1.33.17/go.mod h1:cQnB8CUnxbMU82JvlqjK
github.com/aws/smithy-go v1.8.0/go.mod h1:SObp3lf9smib00L/v3U2eAKG8FyQ7iLrJnQiAmR5n+E=
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/baidubce/bce-sdk-go v0.9.226 h1:VKEKcJC9P33yIfYJZr12Q/4Bvj18RFbgO8w8XOfU8AI=
github.com/baidubce/bce-sdk-go v0.9.226/go.mod h1:zbYJMQwE4IZuyrJiFO8tO8NbtYiKTFTbwh4eIsqjVdg=
github.com/baidubce/bce-sdk-go v0.9.228 h1:XEY3/oAxXcsi7+3atib9fMI6YNE9sL5qo+WMZ+iqmNE=
github.com/baidubce/bce-sdk-go v0.9.228/go.mod h1:zbYJMQwE4IZuyrJiFO8tO8NbtYiKTFTbwh4eIsqjVdg=
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 v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
@@ -545,8 +547,8 @@ github.com/hashicorp/mdns v1.0.1/go.mod h1:4gW7WsVCke5TE7EPeYliwHlRUyBtfCwuFwuMg
github.com/hashicorp/memberlist v0.2.2/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE=
github.com/hashicorp/serf v0.9.5/go.mod h1:UWDWwZeL5cuWDJdl0C6wrvrUwEqtQ4ZKBKKENpqIUyk=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/huaweicloud/huaweicloud-sdk-go-v3 v0.1.148 h1:PdWSbniKnPhKe1B19KUHW/9ahYbFH2EY6Iq6sxOnomo=
github.com/huaweicloud/huaweicloud-sdk-go-v3 v0.1.148/go.mod h1:Y/+YLCFCJtS29i2MbYPTUlNNfwXvkzEsZKR0imY/2aY=
github.com/huaweicloud/huaweicloud-sdk-go-v3 v0.1.150 h1:Ih+z79Ko1ClH4dlv7O1lyHRiVCjkb2NZYYk+1cSZbU8=
github.com/huaweicloud/huaweicloud-sdk-go-v3 v0.1.150/go.mod h1:Y/+YLCFCJtS29i2MbYPTUlNNfwXvkzEsZKR0imY/2aY=
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/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
@@ -737,8 +739,8 @@ github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRI
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/pocketbase/dbx v1.11.0 h1:LpZezioMfT3K4tLrqA55wWFw1EtH1pM4tzSVa7kgszU=
github.com/pocketbase/dbx v1.11.0/go.mod h1:xXRCIAKTHMgUCyCKZm55pUOdvFziJjQfXaWKhu2vhMs=
github.com/pocketbase/pocketbase v0.28.0 h1:dnMHSO0wuYpKs6oP3X5buw1lY9ptd8zy1fTjN+Ae+mA=
github.com/pocketbase/pocketbase v0.28.0/go.mod h1:WE6xMM4+pxKIVNl4B1mcOEZXlDvPGl7cZ64TW2iXHdI=
github.com/pocketbase/pocketbase v0.28.2 h1:b6cfUfr5d4whvUFGFhI8oHRzx/eB76GCUQGftqgv9lM=
github.com/pocketbase/pocketbase v0.28.2/go.mod h1:ElwIYS1b5xS9w0U7AK7tsm6FuC0lzw57H8p/118Cu7g=
github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s=
github.com/povsister/scp v0.0.0-20250504051308-e467f71ea63c h1:1+j5JHz9mUzYSp0scuF6hzvJP28EDBFe5eBJb0xnGk4=
@@ -771,8 +773,8 @@ github.com/qiniu/x v1.10.5 h1:7V/CYWEmo9axJULvrJN6sMYh2FdY+esN5h8jwDkA4b0=
github.com/qiniu/x v1.10.5/go.mod h1:03Ni9tj+N2h2aKnAz+6N0Xfl8FwMEDRC2PAlxekASDs=
github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
github.com/redis/go-redis/v9 v9.7.3 h1:YpPyAayJV+XErNsatSElgRZZVCwXX9QzkKYNvO7x0wM=
github.com/redis/go-redis/v9 v9.7.3/go.mod h1:bGUrSggJ9X9GUmZpZNEOQKaANxSGgOEBRltRTZHSvrA=
github.com/redis/go-redis/v9 v9.8.0 h1:q3nRvjrlge/6UD7eTu/DSg2uYiU2mCL0G/uzBWqhicI=
github.com/redis/go-redis/v9 v9.8.0/go.mod h1:huWgSWd8mW6+m0VPhJjSSQ+d6Nh1VICQ6Q5lHuCH/Iw=
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE=
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
@@ -829,31 +831,32 @@ github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOf
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cdn v1.0.1155 h1:ildxJtjnqiKZxWDVKHT/ncIknGDijtg60MuFELON8bY=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cdn v1.0.1155/go.mod h1:iLASpooTdyXtx642E5Ws7cfWENsp4/uZ/78TFoln7OI=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/clb v1.0.1161 h1:yGFg9/6j3NP10r9PfSWHfekuq4SwPyqblWnfISfKANo=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/clb v1.0.1161/go.mod h1:9MzQSEULYm5wHAKz8R3oQ8ovg4vWeLFzn0DmRWTc6zg=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1120/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1124/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/clb v1.0.1166 h1:cEoDsBt7vGh7YtfVHVmgXKQURZANBE8UKK/So84QUdU=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/clb v1.0.1166/go.mod h1:0o5Cfgdh+bAx7kpQ5a5wce/ZUiDvy4Md8NcbrLtk6i8=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1128/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1150/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1155/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1160/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1161/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1162 h1:bscCBygP9JRl6iNabF+vmBOhY+xayFFGYV5Wa0NzH0A=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1162/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1164/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1166/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1169/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1170/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1172/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1173 h1:W5bzEWiJwiwRZR0/P1l78OYWUXYsXLjhBaQ64c+9+fk=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1173/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dnspod v1.0.1128 h1:mrJ5Fbkd7sZIJ5F6oRfh5zebPQaudPH9Y0+GUmFytYU=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dnspod v1.0.1128/go.mod h1:zbsYIBT+VTX4z4ocjTAdLBIWyNYj3z0BRqd0iPdnjsk=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/live v1.0.1150 h1:RQQYfZOFYlkxKR2+xp8el3+8xs9DhxBy+ajlHtapqtQ=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/live v1.0.1150/go.mod h1:zpfr6EBWy7ClASTGUgIy01Gn4R79UXf+2QGQeyR124A=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/scf v1.0.1120 h1:z0t0lb5h1mZirXftO8MRg25COYZHx0ubQjSPhZT/LY0=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/scf v1.0.1120/go.mod h1:IFZL44Keyl+MHrhpFwUaQmJvMDwGr+t+cUfFAC+74lU=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/ssl v1.0.1124 h1:LQKAlxFb0sYiE8ojK5h9+seuFzogoJtYnXmiRF+4F4Q=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/ssl v1.0.1124/go.mod h1:tYbK0FbHVG+78od7eZpzczE8qk0JWKO/osTQWuiJ3Fo=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/teo v1.0.1162 h1:z/JF+JGi6bGf8vnK9ZeVXz+1Q3ih8nF6KjThxhtIrNc=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/teo v1.0.1162/go.mod h1:rsO8JCP+WQeLQ32wAB4oRRjsEz0O+kvCGDqc7Ze1jc4=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/vod v1.0.1160 h1:aNVEDS1yQ7sLfXOOQ/bF3eljFjyvHoJ/J8qSC9mC9gw=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/vod v1.0.1160/go.mod h1:kf6NQmKK6sh1ACwh8iliBy7I/burd+AWusNz6zbDvLM=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/waf v1.0.1162 h1:gnmuUaoFAShc9FKj3Omswu3n08bHM/sGsl8xjFAkFNs=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/waf v1.0.1162/go.mod h1:bu3KAFeoJ1xDGQp72h9Le3FqbOcCcdomOUig3OqgcE4=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/scf v1.0.1172 h1:6SUO0hTie3zxnUEMxmhnS1iRIXpAukSZV27Nrx4NwIk=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/scf v1.0.1172/go.mod h1:tmN4zfu70SD0iee3qfpc09NRLel30zGoAuzIs4X0Kfs=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/ssl v1.0.1169 h1:oBymtJEmKDnS2NIR0PDLd+xCGQ+7uMoEt7zEB5Q3x8U=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/ssl v1.0.1169/go.mod h1:K27PNEgRJ602ESXUNnlRnCkf1+XYHI6RVP/ylIe/Aro=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/teo v1.0.1166 h1:+kIsoG2If/0y15PpZsXfT0QqTuwec9nMgo1JP8KQMkw=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/teo v1.0.1166/go.mod h1:lGmBMXqe3vBg6Bi9h4mVpWLKd7jQIMRbndr8KNHBqSw=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/vod v1.0.1164 h1:caaIGWOs/JtWOK5ptVMEiiGgzU7Jf6UpMv+9IbIa4vs=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/vod v1.0.1164/go.mod h1:SJI2mc77gDC7Tw1QoF/4d5SwLvz8HQFUecWtIXb+r/Q=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/waf v1.0.1170 h1:kcQCWuI9zOkZgL5CK66HNAJmSWCSJxRrDxXT+j02CeE=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/waf v1.0.1170/go.mod h1:vTukVfThbBIc4lOf4eq/q51eEk78oZUJd2lAoJBOJwI=
github.com/tjfoc/gmsm v1.3.2/go.mod h1:HaUcFuY0auTiaHB9MHFGCPx5IaLhTUd2atbCFBQXn9w=
github.com/tjfoc/gmsm v1.4.1 h1:aMe1GlZb+0bLjn+cKTPEvvn9oUEBlJitaZiiBwsbgho=
github.com/tjfoc/gmsm v1.4.1/go.mod h1:j4INPkHWMrhJb38G+J6W4Tw0AbuN8Thu3PbdVYhVcTE=
@@ -862,18 +865,18 @@ github.com/uber/jaeger-client-go v2.30.0+incompatible h1:D6wyKGCecFaSRUpo8lCVbaO
github.com/uber/jaeger-client-go v2.30.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk=
github.com/uber/jaeger-lib v2.4.1+incompatible h1:td4jdvLcExb4cBISKIpHuGoVXh+dVKhn2Um6rjCsSsg=
github.com/uber/jaeger-lib v2.4.1+incompatible/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U=
github.com/ucloud/ucloud-sdk-go v0.22.35 h1:Q4CY3Ae5813jmNUrGdCjc8tlyleL5Lyl0APnpK5L4sk=
github.com/ucloud/ucloud-sdk-go v0.22.35/go.mod h1:dyLmFHmUfgb4RZKYQP9IArlvQ2pxzFthfhwxRzOEPIw=
github.com/ucloud/ucloud-sdk-go v0.22.41 h1:JndTJhCx7A1wggZfVb4KMm7D0Wfvd/HkmQVfSNjClQA=
github.com/ucloud/ucloud-sdk-go v0.22.41/go.mod h1:dyLmFHmUfgb4RZKYQP9IArlvQ2pxzFthfhwxRzOEPIw=
github.com/ulikunitz/xz v0.5.11 h1:kpFauv27b6ynzBNT/Xy+1k+fK4WswhN/6PN5WhFAGw8=
github.com/ulikunitz/xz v0.5.11/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=
github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI=
github.com/volcengine/ve-tos-golang-sdk/v2 v2.7.12 h1:u9+32DXQIOFPG8oQ3xrjSAUSyAcaq5bqO4cEBom/6lA=
github.com/volcengine/ve-tos-golang-sdk/v2 v2.7.12/go.mod h1:IrjK84IJJTuOZOTMv/P18Ydjy/x+ow7fF7q11jAxXLM=
github.com/volcengine/volc-sdk-golang v1.0.23/go.mod h1:AfG/PZRUkHJ9inETvbjNifTDgut25Wbkm2QoYBTbvyU=
github.com/volcengine/volc-sdk-golang v1.0.207 h1:1OJ/nC92dF1URRoyO1AHSghCob12NT1PAA/GoK8uU18=
github.com/volcengine/volc-sdk-golang v1.0.207/go.mod h1:stZX+EPgv1vF4nZwOlEe8iGcriUPRBKX8zA19gXycOQ=
github.com/volcengine/volcengine-go-sdk v1.1.7 h1:5ElF1inqX1QUKX8/XGk+HGpG+F01W+m73cLQH+0x50s=
github.com/volcengine/volcengine-go-sdk v1.1.7/go.mod h1:EyKoi6t6eZxoPNGr2GdFCZti2Skd7MO3eUzx7TtSvNo=
github.com/volcengine/volc-sdk-golang v1.0.208 h1:DyGUPjEKhWS08BkptfqenXTuUq+LKb7+gX/RBAtNl8w=
github.com/volcengine/volc-sdk-golang v1.0.208/go.mod h1:stZX+EPgv1vF4nZwOlEe8iGcriUPRBKX8zA19gXycOQ=
github.com/volcengine/volcengine-go-sdk v1.1.8 h1:/T2p7qeeLWWhGrhtB00b8VNlE32S266LcO+jqFUYwzY=
github.com/volcengine/volcengine-go-sdk v1.1.8/go.mod h1:EyKoi6t6eZxoPNGr2GdFCZti2Skd7MO3eUzx7TtSvNo=
github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=
github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg=
github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI=
@@ -1394,39 +1397,39 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
k8s.io/api v0.33.0 h1:yTgZVn1XEe6opVpP1FylmNrIFWuDqe2H0V8CT5gxfIU=
k8s.io/api v0.33.0/go.mod h1:CTO61ECK/KU7haa3qq8sarQ0biLq2ju405IZAd9zsiM=
k8s.io/apimachinery v0.33.0 h1:1a6kHrJxb2hs4t8EE5wuR/WxKDwGN1FKH3JvDtA0CIQ=
k8s.io/apimachinery v0.33.0/go.mod h1:BHW0YOu7n22fFv/JkYOEfkUYNRN0fj0BlvMFWA7b+SM=
k8s.io/client-go v0.33.0 h1:UASR0sAYVUzs2kYuKn/ZakZlcs2bEHaizrrHUZg0G98=
k8s.io/client-go v0.33.0/go.mod h1:kGkd+l/gNGg8GYWAPr0xF1rRKvVWvzh9vmZAMXtaKOg=
k8s.io/api v0.33.1 h1:tA6Cf3bHnLIrUK4IqEgb2v++/GYUtqiu9sRVk3iBXyw=
k8s.io/api v0.33.1/go.mod h1:87esjTn9DRSRTD4fWMXamiXxJhpOIREjWOSjsW1kEHw=
k8s.io/apimachinery v0.33.1 h1:mzqXWV8tW9Rw4VeW9rEkqvnxj59k1ezDUl20tFK/oM4=
k8s.io/apimachinery v0.33.1/go.mod h1:BHW0YOu7n22fFv/JkYOEfkUYNRN0fj0BlvMFWA7b+SM=
k8s.io/client-go v0.33.1 h1:ZZV/Ks2g92cyxWkRRnfUDsnhNn28eFpt26aGc8KbXF4=
k8s.io/client-go v0.33.1/go.mod h1:JAsUrl1ArO7uRVFWfcj6kOomSlCv+JpvIsp6usAGefA=
k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk=
k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE=
k8s.io/kube-openapi v0.0.0-20250318190949-c8a335a9a2ff h1:/usPimJzUKKu+m+TE36gUyGcf03XZEP0ZIKgKj35LS4=
k8s.io/kube-openapi v0.0.0-20250318190949-c8a335a9a2ff/go.mod h1:5jIi+8yX4RIb8wk3XwBo5Pq2ccx4FP10ohkbSKCZoK8=
k8s.io/utils v0.0.0-20241210054802-24370beab758 h1:sdbE21q2nlQtFh65saZY+rRM6x6aJJI8IUa1AmH/qa0=
k8s.io/utils v0.0.0-20241210054802-24370beab758/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
modernc.org/cc/v4 v4.25.2 h1:T2oH7sZdGvTaie0BRNFbIYsabzCxUQg8nLqCdQ2i0ic=
modernc.org/cc/v4 v4.25.2/go.mod h1:uVtb5OGqUKpoLWhqwNQo/8LwvoiEBLvZXIQ/SmO6mL0=
modernc.org/ccgo/v4 v4.25.1 h1:TFSzPrAGmDsdnhT9X2UrcPMI3N/mJ9/X9ykKXwLhDsU=
modernc.org/ccgo/v4 v4.25.1/go.mod h1:njjuAYiPflywOOrm3B7kCB444ONP5pAVr8PIEoE0uDw=
modernc.org/cc/v4 v4.26.1 h1:+X5NtzVBn0KgsBCBe+xkDC7twLb/jNVj9FPgiwSQO3s=
modernc.org/cc/v4 v4.26.1/go.mod h1:uVtb5OGqUKpoLWhqwNQo/8LwvoiEBLvZXIQ/SmO6mL0=
modernc.org/ccgo/v4 v4.28.0 h1:rjznn6WWehKq7dG4JtLRKxb52Ecv8OUGah8+Z/SfpNU=
modernc.org/ccgo/v4 v4.28.0/go.mod h1:JygV3+9AV6SmPhDasu4JgquwU81XAKLd3OKTUDNOiKE=
modernc.org/fileutil v1.0.0/go.mod h1:JHsWpkrk/CnVV1H/eGlFf85BEpfkrp56ro8nojIq9Q8=
modernc.org/fileutil v1.3.0 h1:gQ5SIzK3H9kdfai/5x41oQiKValumqNTDXMvKo62HvE=
modernc.org/fileutil v1.3.0/go.mod h1:XatxS8fZi3pS8/hKG2GH/ArUogfxjpEKs3Ku3aK4JyQ=
modernc.org/fileutil v1.3.1 h1:8vq5fe7jdtEvoCf3Zf9Nm0Q05sH6kGx0Op2CPx1wTC8=
modernc.org/fileutil v1.3.1/go.mod h1:HxmghZSZVAz/LXcMNwZPA/DRrQZEVP9VX0V4LQGQFOc=
modernc.org/gc/v2 v2.6.5 h1:nyqdV8q46KvTpZlsw66kWqwXRHdjIlJOhG6kxiV/9xI=
modernc.org/gc/v2 v2.6.5/go.mod h1:YgIahr1ypgfe7chRuJi2gD7DBQiKSLMPgBQe9oIiito=
modernc.org/libc v1.62.1 h1:s0+fv5E3FymN8eJVmnk0llBe6rOxCu/DEU+XygRbS8s=
modernc.org/libc v1.62.1/go.mod h1:iXhATfJQLjG3NWy56a6WVU73lWOcdYVxsvwCgoPljuo=
modernc.org/libc v1.65.7 h1:Ia9Z4yzZtWNtUIuiPuQ7Qf7kxYrxP1/jeHZzG8bFu00=
modernc.org/libc v1.65.7/go.mod h1:011EQibzzio/VX3ygj1qGFt5kMjP0lHb0qCW5/D/pQU=
modernc.org/mathutil v1.7.1 h1:GCZVGXdaN8gTqB1Mf/usp1Y/hSqgI2vAGGP4jZMCxOU=
modernc.org/mathutil v1.7.1/go.mod h1:4p5IwJITfppl0G4sUEDtCr4DthTaT47/N3aT6MhfgJg=
modernc.org/memory v1.9.1 h1:V/Z1solwAVmMW1yttq3nDdZPJqV1rM05Ccq6KMSZ34g=
modernc.org/memory v1.9.1/go.mod h1:/JP4VbVC+K5sU2wZi9bHoq2MAkCnrt2r98UGeSK7Mjw=
modernc.org/memory v1.11.0 h1:o4QC8aMQzmcwCK3t3Ux/ZHmwFPzE6hf2Y5LbkRs+hbI=
modernc.org/memory v1.11.0/go.mod h1:/JP4VbVC+K5sU2wZi9bHoq2MAkCnrt2r98UGeSK7Mjw=
modernc.org/opt v0.1.4 h1:2kNGMRiUjrp4LcaPuLY2PzUfqM/w9N23quVwhKt5Qm8=
modernc.org/opt v0.1.4/go.mod h1:03fq9lsNfvkYSfxrfUhZCWPk1lm4cq4N+Bh//bEtgns=
modernc.org/sortutil v1.2.1 h1:+xyoGf15mM3NMlPDnFqrteY07klSFxLElE2PVuWIJ7w=
modernc.org/sortutil v1.2.1/go.mod h1:7ZI3a3REbai7gzCLcotuw9AC4VZVpYMjDzETGsSMqJE=
modernc.org/sqlite v1.37.0 h1:s1TMe7T3Q3ovQiK2Ouz4Jwh7dw4ZDqbebSDTlSJdfjI=
modernc.org/sqlite v1.37.0/go.mod h1:5YiWv+YviqGMuGw4V+PNplcyaJ5v+vQd7TQOgkACoJM=
modernc.org/sqlite v1.37.1 h1:EgHJK/FPoqC+q2YBXg7fUmES37pCHFc97sI7zSayBEs=
modernc.org/sqlite v1.37.1/go.mod h1:XwdRtsE1MpiBcL54+MbKcaDvcuej+IYSMfLN6gSKV8g=
modernc.org/strutil v1.2.1 h1:UneZBkQA+DX2Rp35KcM69cSsNES9ly8mQWD71HKlOA0=
modernc.org/strutil v1.2.1/go.mod h1:EHkiggD70koQxjVdSBM3JKM7k6L0FbGE5eymy9i3B9A=
modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y=

View File

@@ -26,13 +26,14 @@ import (
)
type ApplyResult struct {
CSR string
FullChainCertificate string
IssuerCertificate string
PrivateKey string
ACMEAccountUrl string
ACMECertUrl string
ACMECertStableUrl string
CSR string
ARIReplaced bool
}
type Applicant interface {
@@ -52,35 +53,35 @@ func NewWithWorkflowNode(config ApplicantWithWorkflowNodeConfig) (Applicant, err
return nil, fmt.Errorf("node type is not '%s'", string(domain.WorkflowNodeTypeApply))
}
nodeConfig := config.Node.GetConfigForApply()
nodeCfg := config.Node.GetConfigForApply()
options := &applicantProviderOptions{
Domains: sliceutil.Filter(strings.Split(nodeConfig.Domains, ";"), func(s string) bool { return s != "" }),
ContactEmail: nodeConfig.ContactEmail,
Provider: domain.ACMEDns01ProviderType(nodeConfig.Provider),
Domains: sliceutil.Filter(strings.Split(nodeCfg.Domains, ";"), func(s string) bool { return s != "" }),
ContactEmail: nodeCfg.ContactEmail,
Provider: domain.ACMEDns01ProviderType(nodeCfg.Provider),
ProviderAccessConfig: make(map[string]any),
ProviderServiceConfig: nodeConfig.ProviderConfig,
CAProvider: domain.CAProviderType(nodeConfig.CAProvider),
ProviderServiceConfig: nodeCfg.ProviderConfig,
CAProvider: domain.CAProviderType(nodeCfg.CAProvider),
CAProviderAccessConfig: make(map[string]any),
CAProviderServiceConfig: nodeConfig.CAProviderConfig,
KeyAlgorithm: nodeConfig.KeyAlgorithm,
Nameservers: sliceutil.Filter(strings.Split(nodeConfig.Nameservers, ";"), func(s string) bool { return s != "" }),
DnsPropagationWait: nodeConfig.DnsPropagationWait,
DnsPropagationTimeout: nodeConfig.DnsPropagationTimeout,
DnsTTL: nodeConfig.DnsTTL,
DisableFollowCNAME: nodeConfig.DisableFollowCNAME,
CAProviderServiceConfig: nodeCfg.CAProviderConfig,
KeyAlgorithm: nodeCfg.KeyAlgorithm,
Nameservers: sliceutil.Filter(strings.Split(nodeCfg.Nameservers, ";"), func(s string) bool { return s != "" }),
DnsPropagationWait: nodeCfg.DnsPropagationWait,
DnsPropagationTimeout: nodeCfg.DnsPropagationTimeout,
DnsTTL: nodeCfg.DnsTTL,
DisableFollowCNAME: nodeCfg.DisableFollowCNAME,
}
accessRepo := repository.NewAccessRepository()
if nodeConfig.ProviderAccessId != "" {
if access, err := accessRepo.GetById(context.Background(), nodeConfig.ProviderAccessId); err != nil {
return nil, fmt.Errorf("failed to get access #%s record: %w", nodeConfig.ProviderAccessId, err)
if nodeCfg.ProviderAccessId != "" {
if access, err := accessRepo.GetById(context.Background(), nodeCfg.ProviderAccessId); err != nil {
return nil, fmt.Errorf("failed to get access #%s record: %w", nodeCfg.ProviderAccessId, err)
} else {
options.ProviderAccessConfig = access.Config
}
}
if nodeConfig.CAProviderAccessId != "" {
if access, err := accessRepo.GetById(context.Background(), nodeConfig.CAProviderAccessId); err != nil {
return nil, fmt.Errorf("failed to get access #%s record: %w", nodeConfig.CAProviderAccessId, err)
if nodeCfg.CAProviderAccessId != "" {
if access, err := accessRepo.GetById(context.Background(), nodeCfg.CAProviderAccessId); err != nil {
return nil, fmt.Errorf("failed to get access #%s record: %w", nodeCfg.CAProviderAccessId, err)
} else {
options.CAProviderAccessId = access.Id
options.CAProviderAccessConfig = access.Config
@@ -109,7 +110,7 @@ func NewWithWorkflowNode(config ApplicantWithWorkflowNodeConfig) (Applicant, err
certRepo := repository.NewCertificateRepository()
lastCertificate, _ := certRepo.GetByWorkflowNodeId(context.Background(), config.Node.Id)
if lastCertificate != nil {
if lastCertificate != nil && !lastCertificate.ACMERenewed {
newCertSan := slices.Clone(options.Domains)
oldCertSan := strings.Split(lastCertificate.SubjectAltNames, ";")
slices.Sort(newCertSan)
@@ -119,8 +120,8 @@ func NewWithWorkflowNode(config ApplicantWithWorkflowNodeConfig) (Applicant, err
lastCertX509, _ := certcrypto.ParsePEMCertificate([]byte(lastCertificate.Certificate))
if lastCertX509 != nil {
replacedARICertId, _ := certificate.MakeARICertID(lastCertX509)
options.ReplacedARIAcct = lastCertificate.ACMEAccountUrl
options.ReplacedARICert = replacedARICertId
options.ARIReplaceAcct = lastCertificate.ACMEAccountUrl
options.ARIReplaceCert = replacedARICertId
}
}
}
@@ -235,22 +236,24 @@ func applyUseLego(legoProvider challenge.Provider, options *applicantProviderOpt
Domains: options.Domains,
Bundle: true,
}
if options.ReplacedARIAcct == user.Registration.URI {
certRequest.ReplacesCertID = options.ReplacedARICert
if options.ARIReplaceAcct == user.Registration.URI {
certRequest.ReplacesCertID = options.ARIReplaceCert
}
certResource, err := client.Certificate.Obtain(certRequest)
if err != nil {
return nil, err
}
return &ApplyResult{
CSR: strings.TrimSpace(string(certResource.CSR)),
FullChainCertificate: strings.TrimSpace(string(certResource.Certificate)),
IssuerCertificate: strings.TrimSpace(string(certResource.IssuerCertificate)),
PrivateKey: strings.TrimSpace(string(certResource.PrivateKey)),
ACMEAccountUrl: user.Registration.URI,
ACMECertUrl: certResource.CertURL,
ACMECertStableUrl: certResource.CertStableURL,
CSR: strings.TrimSpace(string(certResource.CSR)),
ARIReplaced: certRequest.ReplacesCertID != "",
}, nil
}

View File

@@ -16,12 +16,16 @@ import (
pCloudflare "github.com/usual2970/certimate/internal/pkg/core/applicant/acme-dns-01/lego-providers/cloudflare"
pClouDNS "github.com/usual2970/certimate/internal/pkg/core/applicant/acme-dns-01/lego-providers/cloudns"
pCMCCCloud "github.com/usual2970/certimate/internal/pkg/core/applicant/acme-dns-01/lego-providers/cmcccloud"
pConstellix "github.com/usual2970/certimate/internal/pkg/core/applicant/acme-dns-01/lego-providers/constellix"
pDeSEC "github.com/usual2970/certimate/internal/pkg/core/applicant/acme-dns-01/lego-providers/desec"
pDigitalOcean "github.com/usual2970/certimate/internal/pkg/core/applicant/acme-dns-01/lego-providers/digitalocean"
pDNSLA "github.com/usual2970/certimate/internal/pkg/core/applicant/acme-dns-01/lego-providers/dnsla"
pDuckDNS "github.com/usual2970/certimate/internal/pkg/core/applicant/acme-dns-01/lego-providers/duckdns"
pDynv6 "github.com/usual2970/certimate/internal/pkg/core/applicant/acme-dns-01/lego-providers/dynv6"
pGcore "github.com/usual2970/certimate/internal/pkg/core/applicant/acme-dns-01/lego-providers/gcore"
pGname "github.com/usual2970/certimate/internal/pkg/core/applicant/acme-dns-01/lego-providers/gname"
pGoDaddy "github.com/usual2970/certimate/internal/pkg/core/applicant/acme-dns-01/lego-providers/godaddy"
pHetzner "github.com/usual2970/certimate/internal/pkg/core/applicant/acme-dns-01/lego-providers/hetzner"
pHuaweiCloud "github.com/usual2970/certimate/internal/pkg/core/applicant/acme-dns-01/lego-providers/huaweicloud"
pJDCloud "github.com/usual2970/certimate/internal/pkg/core/applicant/acme-dns-01/lego-providers/jdcloud"
pNamecheap "github.com/usual2970/certimate/internal/pkg/core/applicant/acme-dns-01/lego-providers/namecheap"
@@ -35,6 +39,7 @@ import (
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"
pTencentCloudEO "github.com/usual2970/certimate/internal/pkg/core/applicant/acme-dns-01/lego-providers/tencentcloud-eo"
pUCloudUDNR "github.com/usual2970/certimate/internal/pkg/core/applicant/acme-dns-01/lego-providers/ucloud-udnr"
pVercel "github.com/usual2970/certimate/internal/pkg/core/applicant/acme-dns-01/lego-providers/vercel"
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"
@@ -57,8 +62,8 @@ type applicantProviderOptions struct {
DnsPropagationTimeout int32
DnsTTL int32
DisableFollowCNAME bool
ReplacedARIAcct string
ReplacedARICert string
ARIReplaceAcct string
ARIReplaceCert string
}
func createApplicantProvider(options *applicantProviderOptions) (challenge.Provider, error) {
@@ -231,6 +236,22 @@ func createApplicantProvider(options *applicantProviderOptions) (challenge.Provi
return applicant, err
}
case domain.ACMEDns01ProviderTypeConstellix:
{
access := domain.AccessConfigForConstellix{}
if err := maputil.Populate(options.ProviderAccessConfig, &access); err != nil {
return nil, fmt.Errorf("failed to populate provider access config: %w", err)
}
applicant, err := pConstellix.NewChallengeProvider(&pConstellix.ChallengeProviderConfig{
ApiKey: access.ApiKey,
SecretKey: access.SecretKey,
DnsPropagationTimeout: options.DnsPropagationTimeout,
DnsTTL: options.DnsTTL,
})
return applicant, err
}
case domain.ACMEDns01ProviderTypeDeSEC:
{
access := domain.AccessConfigForDeSEC{}
@@ -246,6 +267,21 @@ func createApplicantProvider(options *applicantProviderOptions) (challenge.Provi
return applicant, err
}
case domain.ACMEDns01ProviderTypeDigitalOcean:
{
access := domain.AccessConfigForDigitalOcean{}
if err := maputil.Populate(options.ProviderAccessConfig, &access); err != nil {
return nil, fmt.Errorf("failed to populate provider access config: %w", err)
}
applicant, err := pDigitalOcean.NewChallengeProvider(&pDigitalOcean.ChallengeProviderConfig{
AccessToken: access.AccessToken,
DnsPropagationTimeout: options.DnsPropagationTimeout,
DnsTTL: options.DnsTTL,
})
return applicant, err
}
case domain.ACMEDns01ProviderTypeDNSLA:
{
access := domain.AccessConfigForDNSLA{}
@@ -262,6 +298,20 @@ func createApplicantProvider(options *applicantProviderOptions) (challenge.Provi
return applicant, err
}
case domain.ACMEDns01ProviderTypeDuckDNS:
{
access := domain.AccessConfigForDuckDNS{}
if err := maputil.Populate(options.ProviderAccessConfig, &access); err != nil {
return nil, fmt.Errorf("failed to populate provider access config: %w", err)
}
applicant, err := pDuckDNS.NewChallengeProvider(&pDuckDNS.ChallengeProviderConfig{
Token: access.Token,
DnsPropagationTimeout: options.DnsPropagationTimeout,
})
return applicant, err
}
case domain.ACMEDns01ProviderTypeDynv6:
{
access := domain.AccessConfigForDynv6{}
@@ -324,6 +374,21 @@ func createApplicantProvider(options *applicantProviderOptions) (challenge.Provi
return applicant, err
}
case domain.ACMEDns01ProviderTypeHetzner:
{
access := domain.AccessConfigForHetzner{}
if err := maputil.Populate(options.ProviderAccessConfig, &access); err != nil {
return nil, fmt.Errorf("failed to populate provider access config: %w", err)
}
applicant, err := pHetzner.NewChallengeProvider(&pHetzner.ChallengeProviderConfig{
ApiToken: access.ApiToken,
DnsPropagationTimeout: options.DnsPropagationTimeout,
DnsTTL: options.DnsTTL,
})
return applicant, err
}
case domain.ACMEDns01ProviderTypeHuaweiCloud, domain.ACMEDns01ProviderTypeHuaweiCloudDNS:
{
access := domain.AccessConfigForHuaweiCloud{}
@@ -476,7 +541,7 @@ func createApplicantProvider(options *applicantProviderOptions) (challenge.Provi
}
applicant, err := pPowerDNS.NewChallengeProvider(&pPowerDNS.ChallengeProviderConfig{
ApiUrl: access.ApiUrl,
ServerUrl: access.ServerUrl,
ApiKey: access.ApiKey,
AllowInsecureConnections: access.AllowInsecureConnections,
DnsPropagationTimeout: options.DnsPropagationTimeout,
@@ -532,6 +597,22 @@ func createApplicantProvider(options *applicantProviderOptions) (challenge.Provi
}
}
case domain.ACMEDns01ProviderTypeUCloudUDNR:
{
access := domain.AccessConfigForUCloud{}
if err := maputil.Populate(options.ProviderAccessConfig, &access); err != nil {
return nil, fmt.Errorf("failed to populate provider access config: %w", err)
}
applicant, err := pUCloudUDNR.NewChallengeProvider(&pUCloudUDNR.ChallengeProviderConfig{
PrivateKey: access.PrivateKey,
PublicKey: access.PublicKey,
DnsPropagationTimeout: options.DnsPropagationTimeout,
DnsTTL: options.DnsTTL,
})
return applicant, err
}
case domain.ACMEDns01ProviderTypeVercel:
{
access := domain.AccessConfigForVercel{}

View File

@@ -29,18 +29,18 @@ func NewWithWorkflowNode(config DeployerWithWorkflowNodeConfig) (Deployer, error
return nil, fmt.Errorf("node type is not '%s'", string(domain.WorkflowNodeTypeDeploy))
}
nodeConfig := config.Node.GetConfigForDeploy()
nodeCfg := config.Node.GetConfigForDeploy()
options := &deployerProviderOptions{
Provider: domain.DeploymentProviderType(nodeConfig.Provider),
Provider: domain.DeploymentProviderType(nodeCfg.Provider),
ProviderAccessConfig: make(map[string]any),
ProviderServiceConfig: nodeConfig.ProviderConfig,
ProviderServiceConfig: nodeCfg.ProviderConfig,
}
accessRepo := repository.NewAccessRepository()
if nodeConfig.ProviderAccessId != "" {
access, err := accessRepo.GetById(context.Background(), nodeConfig.ProviderAccessId)
if nodeCfg.ProviderAccessId != "" {
access, err := accessRepo.GetById(context.Background(), nodeCfg.ProviderAccessId)
if err != nil {
return nil, fmt.Errorf("failed to get access #%s record: %w", nodeConfig.ProviderAccessId, err)
return nil, fmt.Errorf("failed to get access #%s record: %w", nodeCfg.ProviderAccessId, err)
} else {
options.ProviderAccessConfig = access.Config
}

View File

@@ -27,6 +27,7 @@ import (
pAliyunWAF "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/aliyun-waf"
pAWSACM "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/aws-acm"
pAWSCloudFront "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/aws-cloudfront"
pAWSIAM "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/aws-iam"
pAzureKeyVault "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/azure-keyvault"
pBaiduCloudAppBLB "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/baiducloud-appblb"
pBaiduCloudBLB "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/baiducloud-blb"
@@ -79,6 +80,7 @@ import (
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"
pUniCloudWebHost "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/unicloud-webhost"
pUpyunCDN "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/upyun-cdn"
pVolcEngineALB "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/volcengine-alb"
pVolcEngineCDN "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/volcengine-cdn"
@@ -119,7 +121,7 @@ func createDeployerProvider(options *deployerProviderOptions) (deployer.Deployer
switch options.Provider {
case domain.DeploymentProviderType1PanelConsole:
deployer, err := p1PanelConsole.NewDeployer(&p1PanelConsole.DeployerConfig{
ApiUrl: access.ApiUrl,
ServerUrl: access.ServerUrl,
ApiVersion: access.ApiVersion,
ApiKey: access.ApiKey,
AllowInsecureConnections: access.AllowInsecureConnections,
@@ -129,7 +131,7 @@ func createDeployerProvider(options *deployerProviderOptions) (deployer.Deployer
case domain.DeploymentProviderType1PanelSite:
deployer, err := p1PanelSite.NewDeployer(&p1PanelSite.DeployerConfig{
ApiUrl: access.ApiUrl,
ServerUrl: access.ServerUrl,
ApiVersion: access.ApiVersion,
ApiKey: access.ApiKey,
AllowInsecureConnections: access.AllowInsecureConnections,
@@ -156,6 +158,7 @@ func createDeployerProvider(options *deployerProviderOptions) (deployer.Deployer
deployer, err := pAliyunALB.NewDeployer(&pAliyunALB.DeployerConfig{
AccessKeyId: access.AccessKeyId,
AccessKeySecret: access.AccessKeySecret,
ResourceGroupId: access.ResourceGroupId,
Region: maputil.GetString(options.ProviderServiceConfig, "region"),
ResourceType: pAliyunALB.ResourceType(maputil.GetString(options.ProviderServiceConfig, "resourceType")),
LoadbalancerId: maputil.GetString(options.ProviderServiceConfig, "loadbalancerId"),
@@ -168,6 +171,7 @@ func createDeployerProvider(options *deployerProviderOptions) (deployer.Deployer
deployer, err := pAliyunAPIGW.NewDeployer(&pAliyunAPIGW.DeployerConfig{
AccessKeyId: access.AccessKeyId,
AccessKeySecret: access.AccessKeySecret,
ResourceGroupId: access.ResourceGroupId,
Region: maputil.GetString(options.ProviderServiceConfig, "region"),
ServiceType: pAliyunAPIGW.ServiceType(maputil.GetString(options.ProviderServiceConfig, "serviceType")),
GatewayId: maputil.GetString(options.ProviderServiceConfig, "gatewayId"),
@@ -180,6 +184,7 @@ func createDeployerProvider(options *deployerProviderOptions) (deployer.Deployer
deployer, err := pAliyunCAS.NewDeployer(&pAliyunCAS.DeployerConfig{
AccessKeyId: access.AccessKeyId,
AccessKeySecret: access.AccessKeySecret,
ResourceGroupId: access.ResourceGroupId,
Region: maputil.GetString(options.ProviderServiceConfig, "region"),
})
return deployer, err
@@ -188,6 +193,7 @@ func createDeployerProvider(options *deployerProviderOptions) (deployer.Deployer
deployer, err := pAliyunCASDeploy.NewDeployer(&pAliyunCASDeploy.DeployerConfig{
AccessKeyId: access.AccessKeyId,
AccessKeySecret: access.AccessKeySecret,
ResourceGroupId: access.ResourceGroupId,
Region: maputil.GetString(options.ProviderServiceConfig, "region"),
ResourceIds: sliceutil.Filter(strings.Split(maputil.GetString(options.ProviderServiceConfig, "resourceIds"), ";"), func(s string) bool { return s != "" }),
ContactIds: sliceutil.Filter(strings.Split(maputil.GetString(options.ProviderServiceConfig, "contactIds"), ";"), func(s string) bool { return s != "" }),
@@ -198,6 +204,7 @@ func createDeployerProvider(options *deployerProviderOptions) (deployer.Deployer
deployer, err := pAliyunCDN.NewDeployer(&pAliyunCDN.DeployerConfig{
AccessKeyId: access.AccessKeyId,
AccessKeySecret: access.AccessKeySecret,
ResourceGroupId: access.ResourceGroupId,
Domain: maputil.GetString(options.ProviderServiceConfig, "domain"),
})
return deployer, err
@@ -206,6 +213,7 @@ func createDeployerProvider(options *deployerProviderOptions) (deployer.Deployer
deployer, err := pAliyunCLB.NewDeployer(&pAliyunCLB.DeployerConfig{
AccessKeyId: access.AccessKeyId,
AccessKeySecret: access.AccessKeySecret,
ResourceGroupId: access.ResourceGroupId,
Region: maputil.GetString(options.ProviderServiceConfig, "region"),
ResourceType: pAliyunCLB.ResourceType(maputil.GetString(options.ProviderServiceConfig, "resourceType")),
LoadbalancerId: maputil.GetString(options.ProviderServiceConfig, "loadbalancerId"),
@@ -218,6 +226,7 @@ func createDeployerProvider(options *deployerProviderOptions) (deployer.Deployer
deployer, err := pAliyunDCDN.NewDeployer(&pAliyunDCDN.DeployerConfig{
AccessKeyId: access.AccessKeyId,
AccessKeySecret: access.AccessKeySecret,
ResourceGroupId: access.ResourceGroupId,
Domain: maputil.GetString(options.ProviderServiceConfig, "domain"),
})
return deployer, err
@@ -226,6 +235,7 @@ func createDeployerProvider(options *deployerProviderOptions) (deployer.Deployer
deployer, err := pAliyunDDoS.NewDeployer(&pAliyunDDoS.DeployerConfig{
AccessKeyId: access.AccessKeyId,
AccessKeySecret: access.AccessKeySecret,
ResourceGroupId: access.ResourceGroupId,
Region: maputil.GetString(options.ProviderServiceConfig, "region"),
Domain: maputil.GetString(options.ProviderServiceConfig, "domain"),
})
@@ -244,6 +254,7 @@ func createDeployerProvider(options *deployerProviderOptions) (deployer.Deployer
deployer, err := pAliyunFC.NewDeployer(&pAliyunFC.DeployerConfig{
AccessKeyId: access.AccessKeyId,
AccessKeySecret: access.AccessKeySecret,
ResourceGroupId: access.ResourceGroupId,
Region: maputil.GetString(options.ProviderServiceConfig, "region"),
ServiceVersion: maputil.GetOrDefaultString(options.ProviderServiceConfig, "serviceVersion", "3.0"),
Domain: maputil.GetString(options.ProviderServiceConfig, "domain"),
@@ -254,6 +265,7 @@ func createDeployerProvider(options *deployerProviderOptions) (deployer.Deployer
deployer, err := pAliyunGA.NewDeployer(&pAliyunGA.DeployerConfig{
AccessKeyId: access.AccessKeyId,
AccessKeySecret: access.AccessKeySecret,
ResourceGroupId: access.ResourceGroupId,
ResourceType: pAliyunGA.ResourceType(maputil.GetString(options.ProviderServiceConfig, "resourceType")),
AcceleratorId: maputil.GetString(options.ProviderServiceConfig, "acceleratorId"),
ListenerId: maputil.GetString(options.ProviderServiceConfig, "listenerId"),
@@ -274,6 +286,7 @@ func createDeployerProvider(options *deployerProviderOptions) (deployer.Deployer
deployer, err := pAliyunNLB.NewDeployer(&pAliyunNLB.DeployerConfig{
AccessKeyId: access.AccessKeyId,
AccessKeySecret: access.AccessKeySecret,
ResourceGroupId: access.ResourceGroupId,
Region: maputil.GetString(options.ProviderServiceConfig, "region"),
ResourceType: pAliyunNLB.ResourceType(maputil.GetString(options.ProviderServiceConfig, "resourceType")),
LoadbalancerId: maputil.GetString(options.ProviderServiceConfig, "loadbalancerId"),
@@ -285,6 +298,7 @@ func createDeployerProvider(options *deployerProviderOptions) (deployer.Deployer
deployer, err := pAliyunOSS.NewDeployer(&pAliyunOSS.DeployerConfig{
AccessKeyId: access.AccessKeyId,
AccessKeySecret: access.AccessKeySecret,
ResourceGroupId: access.ResourceGroupId,
Region: maputil.GetString(options.ProviderServiceConfig, "region"),
Bucket: maputil.GetString(options.ProviderServiceConfig, "bucket"),
Domain: maputil.GetString(options.ProviderServiceConfig, "domain"),
@@ -295,6 +309,7 @@ func createDeployerProvider(options *deployerProviderOptions) (deployer.Deployer
deployer, err := pAliyunVOD.NewDeployer(&pAliyunVOD.DeployerConfig{
AccessKeyId: access.AccessKeyId,
AccessKeySecret: access.AccessKeySecret,
ResourceGroupId: access.ResourceGroupId,
Region: maputil.GetString(options.ProviderServiceConfig, "region"),
Domain: maputil.GetString(options.ProviderServiceConfig, "domain"),
})
@@ -304,6 +319,7 @@ func createDeployerProvider(options *deployerProviderOptions) (deployer.Deployer
deployer, err := pAliyunWAF.NewDeployer(&pAliyunWAF.DeployerConfig{
AccessKeyId: access.AccessKeyId,
AccessKeySecret: access.AccessKeySecret,
ResourceGroupId: access.ResourceGroupId,
Region: maputil.GetString(options.ProviderServiceConfig, "region"),
ServiceVersion: maputil.GetOrDefaultString(options.ProviderServiceConfig, "serviceVersion", "3.0"),
InstanceId: maputil.GetString(options.ProviderServiceConfig, "instanceId"),
@@ -316,7 +332,7 @@ func createDeployerProvider(options *deployerProviderOptions) (deployer.Deployer
}
}
case domain.DeploymentProviderTypeAWSACM, domain.DeploymentProviderTypeAWSCloudFront:
case domain.DeploymentProviderTypeAWSACM, domain.DeploymentProviderTypeAWSCloudFront, domain.DeploymentProviderTypeAWSIAM:
{
access := domain.AccessConfigForAWS{}
if err := maputil.Populate(options.ProviderAccessConfig, &access); err != nil {
@@ -335,10 +351,20 @@ func createDeployerProvider(options *deployerProviderOptions) (deployer.Deployer
case domain.DeploymentProviderTypeAWSCloudFront:
deployer, err := pAWSCloudFront.NewDeployer(&pAWSCloudFront.DeployerConfig{
AccessKeyId: access.AccessKeyId,
SecretAccessKey: access.SecretAccessKey,
Region: maputil.GetString(options.ProviderServiceConfig, "region"),
DistributionId: maputil.GetString(options.ProviderServiceConfig, "distributionId"),
CertificateSource: maputil.GetOrDefaultString(options.ProviderServiceConfig, "certificateSource", "ACM"),
})
return deployer, err
case domain.DeploymentProviderTypeAWSIAM:
deployer, err := pAWSIAM.NewDeployer(&pAWSIAM.DeployerConfig{
AccessKeyId: access.AccessKeyId,
SecretAccessKey: access.SecretAccessKey,
Region: maputil.GetString(options.ProviderServiceConfig, "region"),
DistributionId: maputil.GetString(options.ProviderServiceConfig, "distributionId"),
CertificatePath: maputil.GetOrDefaultString(options.ProviderServiceConfig, "certificatePath", "/"),
})
return deployer, err
@@ -454,7 +480,7 @@ func createDeployerProvider(options *deployerProviderOptions) (deployer.Deployer
switch options.Provider {
case domain.DeploymentProviderTypeBaotaPanelConsole:
deployer, err := pBaotaPanelConsole.NewDeployer(&pBaotaPanelConsole.DeployerConfig{
ApiUrl: access.ApiUrl,
ServerUrl: access.ServerUrl,
ApiKey: access.ApiKey,
AllowInsecureConnections: access.AllowInsecureConnections,
AutoRestart: maputil.GetBool(options.ProviderServiceConfig, "autoRestart"),
@@ -463,7 +489,7 @@ func createDeployerProvider(options *deployerProviderOptions) (deployer.Deployer
case domain.DeploymentProviderTypeBaotaPanelSite:
deployer, err := pBaotaPanelSite.NewDeployer(&pBaotaPanelSite.DeployerConfig{
ApiUrl: access.ApiUrl,
ServerUrl: access.ServerUrl,
ApiKey: access.ApiKey,
AllowInsecureConnections: access.AllowInsecureConnections,
SiteType: maputil.GetOrDefaultString(options.ProviderServiceConfig, "siteType", "other"),
@@ -487,7 +513,7 @@ func createDeployerProvider(options *deployerProviderOptions) (deployer.Deployer
switch options.Provider {
case domain.DeploymentProviderTypeBaotaWAFConsole:
deployer, err := pBaotaWAFConsole.NewDeployer(&pBaotaWAFConsole.DeployerConfig{
ApiUrl: access.ApiUrl,
ServerUrl: access.ServerUrl,
ApiKey: access.ApiKey,
AllowInsecureConnections: access.AllowInsecureConnections,
})
@@ -495,7 +521,7 @@ func createDeployerProvider(options *deployerProviderOptions) (deployer.Deployer
case domain.DeploymentProviderTypeBaotaWAFSite:
deployer, err := pBaotaWAFSite.NewDeployer(&pBaotaWAFSite.DeployerConfig{
ApiUrl: access.ApiUrl,
ServerUrl: access.ServerUrl,
ApiKey: access.ApiKey,
AllowInsecureConnections: access.AllowInsecureConnections,
SiteName: maputil.GetString(options.ProviderServiceConfig, "siteName"),
@@ -565,7 +591,7 @@ func createDeployerProvider(options *deployerProviderOptions) (deployer.Deployer
}
deployer, err := pCdnfly.NewDeployer(&pCdnfly.DeployerConfig{
ApiUrl: access.ApiUrl,
ServerUrl: access.ServerUrl,
ApiKey: access.ApiKey,
ApiSecret: access.ApiSecret,
AllowInsecureConnections: access.AllowInsecureConnections,
@@ -614,7 +640,7 @@ func createDeployerProvider(options *deployerProviderOptions) (deployer.Deployer
}
deployer, err := pFlexCDN.NewDeployer(&pFlexCDN.DeployerConfig{
ApiUrl: access.ApiUrl,
ServerUrl: access.ServerUrl,
ApiRole: access.ApiRole,
AccessKeyId: access.AccessKeyId,
AccessKey: access.AccessKey,
@@ -654,7 +680,7 @@ func createDeployerProvider(options *deployerProviderOptions) (deployer.Deployer
}
deployer, err := pGoEdge.NewDeployer(&pGoEdge.DeployerConfig{
ApiUrl: access.ApiUrl,
ServerUrl: access.ServerUrl,
ApiRole: access.ApiRole,
AccessKeyId: access.AccessKeyId,
AccessKey: access.AccessKey,
@@ -675,40 +701,44 @@ func createDeployerProvider(options *deployerProviderOptions) (deployer.Deployer
switch options.Provider {
case domain.DeploymentProviderTypeHuaweiCloudCDN:
deployer, err := pHuaweiCloudCDN.NewDeployer(&pHuaweiCloudCDN.DeployerConfig{
AccessKeyId: access.AccessKeyId,
SecretAccessKey: access.SecretAccessKey,
Region: maputil.GetString(options.ProviderServiceConfig, "region"),
Domain: maputil.GetString(options.ProviderServiceConfig, "domain"),
AccessKeyId: access.AccessKeyId,
SecretAccessKey: access.SecretAccessKey,
EnterpriseProjectId: access.EnterpriseProjectId,
Region: maputil.GetString(options.ProviderServiceConfig, "region"),
Domain: maputil.GetString(options.ProviderServiceConfig, "domain"),
})
return deployer, err
case domain.DeploymentProviderTypeHuaweiCloudELB:
deployer, err := pHuaweiCloudELB.NewDeployer(&pHuaweiCloudELB.DeployerConfig{
AccessKeyId: access.AccessKeyId,
SecretAccessKey: access.SecretAccessKey,
Region: maputil.GetString(options.ProviderServiceConfig, "region"),
ResourceType: pHuaweiCloudELB.ResourceType(maputil.GetString(options.ProviderServiceConfig, "resourceType")),
CertificateId: maputil.GetString(options.ProviderServiceConfig, "certificateId"),
LoadbalancerId: maputil.GetString(options.ProviderServiceConfig, "loadbalancerId"),
ListenerId: maputil.GetString(options.ProviderServiceConfig, "listenerId"),
AccessKeyId: access.AccessKeyId,
SecretAccessKey: access.SecretAccessKey,
EnterpriseProjectId: access.EnterpriseProjectId,
Region: maputil.GetString(options.ProviderServiceConfig, "region"),
ResourceType: pHuaweiCloudELB.ResourceType(maputil.GetString(options.ProviderServiceConfig, "resourceType")),
CertificateId: maputil.GetString(options.ProviderServiceConfig, "certificateId"),
LoadbalancerId: maputil.GetString(options.ProviderServiceConfig, "loadbalancerId"),
ListenerId: maputil.GetString(options.ProviderServiceConfig, "listenerId"),
})
return deployer, err
case domain.DeploymentProviderTypeHuaweiCloudSCM:
deployer, err := pHuaweiCloudSCM.NewDeployer(&pHuaweiCloudSCM.DeployerConfig{
AccessKeyId: access.AccessKeyId,
SecretAccessKey: access.SecretAccessKey,
AccessKeyId: access.AccessKeyId,
SecretAccessKey: access.SecretAccessKey,
EnterpriseProjectId: access.EnterpriseProjectId,
})
return deployer, err
case domain.DeploymentProviderTypeHuaweiCloudWAF:
deployer, err := pHuaweiCloudWAF.NewDeployer(&pHuaweiCloudWAF.DeployerConfig{
AccessKeyId: access.AccessKeyId,
SecretAccessKey: access.SecretAccessKey,
Region: maputil.GetString(options.ProviderServiceConfig, "region"),
ResourceType: pHuaweiCloudWAF.ResourceType(maputil.GetString(options.ProviderServiceConfig, "resourceType")),
CertificateId: maputil.GetString(options.ProviderServiceConfig, "certificateId"),
Domain: maputil.GetString(options.ProviderServiceConfig, "domain"),
AccessKeyId: access.AccessKeyId,
SecretAccessKey: access.SecretAccessKey,
EnterpriseProjectId: access.EnterpriseProjectId,
Region: maputil.GetString(options.ProviderServiceConfig, "region"),
ResourceType: pHuaweiCloudWAF.ResourceType(maputil.GetString(options.ProviderServiceConfig, "resourceType")),
CertificateId: maputil.GetString(options.ProviderServiceConfig, "certificateId"),
Domain: maputil.GetString(options.ProviderServiceConfig, "domain"),
})
return deployer, err
@@ -773,7 +803,7 @@ func createDeployerProvider(options *deployerProviderOptions) (deployer.Deployer
}
deployer, err := pLeCDN.NewDeployer(&pLeCDN.DeployerConfig{
ApiUrl: access.ApiUrl,
ServerUrl: access.ServerUrl,
ApiVersion: access.ApiVersion,
ApiRole: access.ApiRole,
Username: access.Username,
@@ -845,7 +875,7 @@ func createDeployerProvider(options *deployerProviderOptions) (deployer.Deployer
}
deployer, err := pProxmoxVE.NewDeployer(&pProxmoxVE.DeployerConfig{
ApiUrl: access.ApiUrl,
ServerUrl: access.ServerUrl,
ApiToken: access.ApiToken,
ApiTokenSecret: access.ApiTokenSecret,
AllowInsecureConnections: access.AllowInsecureConnections,
@@ -916,7 +946,7 @@ func createDeployerProvider(options *deployerProviderOptions) (deployer.Deployer
switch options.Provider {
case domain.DeploymentProviderTypeRatPanelConsole:
deployer, err := pRatPanelConsole.NewDeployer(&pRatPanelConsole.DeployerConfig{
ApiUrl: access.ApiUrl,
ServerUrl: access.ServerUrl,
AccessTokenId: access.AccessTokenId,
AccessToken: access.AccessToken,
AllowInsecureConnections: access.AllowInsecureConnections,
@@ -925,7 +955,7 @@ func createDeployerProvider(options *deployerProviderOptions) (deployer.Deployer
case domain.DeploymentProviderTypeRatPanelSite:
deployer, err := pRatPanelSite.NewDeployer(&pRatPanelSite.DeployerConfig{
ApiUrl: access.ApiUrl,
ServerUrl: access.ServerUrl,
AccessTokenId: access.AccessTokenId,
AccessToken: access.AccessToken,
AllowInsecureConnections: access.AllowInsecureConnections,
@@ -946,7 +976,7 @@ func createDeployerProvider(options *deployerProviderOptions) (deployer.Deployer
}
deployer, err := pSafeLine.NewDeployer(&pSafeLine.DeployerConfig{
ApiUrl: access.ApiUrl,
ServerUrl: access.ServerUrl,
ApiToken: access.ApiToken,
AllowInsecureConnections: access.AllowInsecureConnections,
ResourceType: pSafeLine.ResourceType(maputil.GetString(options.ProviderServiceConfig, "resourceType")),
@@ -967,6 +997,7 @@ func createDeployerProvider(options *deployerProviderOptions) (deployer.Deployer
jumpServers[i] = pSSH.JumpServerConfig{
SshHost: jumpServer.Host,
SshPort: jumpServer.Port,
SshAuthMethod: jumpServer.AuthMethod,
SshUsername: jumpServer.Username,
SshPassword: jumpServer.Password,
SshKey: jumpServer.Key,
@@ -977,6 +1008,7 @@ func createDeployerProvider(options *deployerProviderOptions) (deployer.Deployer
deployer, err := pSSH.NewDeployer(&pSSH.DeployerConfig{
SshHost: access.Host,
SshPort: access.Port,
SshAuthMethod: access.AuthMethod,
SshUsername: access.Username,
SshPassword: access.Password,
SshKey: access.Key,
@@ -1144,6 +1176,23 @@ func createDeployerProvider(options *deployerProviderOptions) (deployer.Deployer
}
}
case domain.DeploymentProviderTypeUniCloudWebHost:
{
access := domain.AccessConfigForUniCloud{}
if err := maputil.Populate(options.ProviderAccessConfig, &access); err != nil {
return nil, fmt.Errorf("failed to populate provider access config: %w", err)
}
deployer, err := pUniCloudWebHost.NewDeployer(&pUniCloudWebHost.DeployerConfig{
Username: access.Username,
Password: access.Password,
SpaceProvider: maputil.GetString(options.ProviderServiceConfig, "spaceProvider"),
SpaceId: maputil.GetString(options.ProviderServiceConfig, "spaceId"),
Domain: maputil.GetString(options.ProviderServiceConfig, "domain"),
})
return deployer, err
}
case domain.DeploymentProviderTypeUpyunCDN, domain.DeploymentProviderTypeUpyunFile:
{
access := domain.AccessConfigForUpyun{}

View File

@@ -16,7 +16,7 @@ type Access struct {
}
type AccessConfigFor1Panel struct {
ApiUrl string `json:"apiUrl"`
ServerUrl string `json:"serverUrl"`
ApiVersion string `json:"apiVersion"`
ApiKey string `json:"apiKey"`
AllowInsecureConnections bool `json:"allowInsecureConnections,omitempty"`
@@ -38,6 +38,7 @@ type AccessConfigForACMEHttpReq struct {
type AccessConfigForAliyun struct {
AccessKeyId string `json:"accessKeyId"`
AccessKeySecret string `json:"accessKeySecret"`
ResourceGroupId string `json:"resourceGroupId,omitempty"`
}
type AccessConfigForAWS struct {
@@ -62,13 +63,13 @@ type AccessConfigForBaishan struct {
}
type AccessConfigForBaotaPanel struct {
ApiUrl string `json:"apiUrl"`
ServerUrl string `json:"serverUrl"`
ApiKey string `json:"apiKey"`
AllowInsecureConnections bool `json:"allowInsecureConnections,omitempty"`
}
type AccessConfigForBaotaWAF struct {
ApiUrl string `json:"apiUrl"`
ServerUrl string `json:"serverUrl"`
ApiKey string `json:"apiKey"`
AllowInsecureConnections bool `json:"allowInsecureConnections,omitempty"`
}
@@ -87,7 +88,7 @@ type AccessConfigForCacheFly struct {
}
type AccessConfigForCdnfly struct {
ApiUrl string `json:"apiUrl"`
ServerUrl string `json:"serverUrl"`
ApiKey string `json:"apiKey"`
ApiSecret string `json:"apiSecret"`
AllowInsecureConnections bool `json:"allowInsecureConnections,omitempty"`
@@ -108,15 +109,29 @@ type AccessConfigForCMCCCloud struct {
AccessKeySecret string `json:"accessKeySecret"`
}
type AccessConfigForConstellix struct {
ApiKey string `json:"apiKey"`
SecretKey string `json:"secretKey"`
}
type AccessConfigForDeSEC struct {
Token string `json:"token"`
}
type AccessConfigForDigitalOcean struct {
AccessToken string `json:"accessToken"`
}
type AccessConfigForDingTalkBot struct {
WebhookUrl string `json:"webhookUrl"`
Secret string `json:"secret"`
}
type AccessConfigForDiscordBot struct {
BotToken string `json:"botToken"`
DefaultChannelId string `json:"defaultChannelId,omitempty"`
}
type AccessConfigForDNSLA struct {
ApiId string `json:"apiId"`
ApiSecret string `json:"apiSecret"`
@@ -127,6 +142,10 @@ type AccessConfigForDogeCloud struct {
SecretKey string `json:"secretKey"`
}
type AccessConfigForDuckDNS struct {
Token string `json:"token"`
}
type AccessConfigForDynv6 struct {
HttpToken string `json:"httpToken"`
}
@@ -147,7 +166,7 @@ type AccessConfigForEmail struct {
}
type AccessConfigForFlexCDN struct {
ApiUrl string `json:"apiUrl"`
ServerUrl string `json:"serverUrl"`
ApiRole string `json:"apiRole"`
AccessKeyId string `json:"accessKeyId"`
AccessKey string `json:"accessKey"`
@@ -169,7 +188,7 @@ type AccessConfigForGoDaddy struct {
}
type AccessConfigForGoEdge struct {
ApiUrl string `json:"apiUrl"`
ServerUrl string `json:"serverUrl"`
ApiRole string `json:"apiRole"`
AccessKeyId string `json:"accessKeyId"`
AccessKey string `json:"accessKey"`
@@ -181,9 +200,14 @@ type AccessConfigForGoogleTrustServices struct {
EabHmacKey string `json:"eabHmacKey"`
}
type AccessConfigForHetzner struct {
ApiToken string `json:"apiToken"`
}
type AccessConfigForHuaweiCloud struct {
AccessKeyId string `json:"accessKeyId"`
SecretAccessKey string `json:"secretAccessKey"`
AccessKeyId string `json:"accessKeyId"`
SecretAccessKey string `json:"secretAccessKey"`
EnterpriseProjectId string `json:"enterpriseProjectId,omitempty"`
}
type AccessConfigForJDCloud struct {
@@ -200,7 +224,7 @@ type AccessConfigForLarkBot struct {
}
type AccessConfigForLeCDN struct {
ApiUrl string `json:"apiUrl"`
ServerUrl string `json:"serverUrl"`
ApiVersion string `json:"apiVersion"`
ApiRole string `json:"apiRole"`
Username string `json:"username"`
@@ -249,13 +273,13 @@ type AccessConfigForPorkbun struct {
}
type AccessConfigForPowerDNS struct {
ApiUrl string `json:"apiUrl"`
ServerUrl string `json:"serverUrl"`
ApiKey string `json:"apiKey"`
AllowInsecureConnections bool `json:"allowInsecureConnections,omitempty"`
}
type AccessConfigForProxmoxVE struct {
ApiUrl string `json:"apiUrl"`
ServerUrl string `json:"serverUrl"`
ApiToken string `json:"apiToken"`
ApiTokenSecret string `json:"apiTokenSecret,omitempty"`
AllowInsecureConnections bool `json:"allowInsecureConnections,omitempty"`
@@ -271,29 +295,36 @@ type AccessConfigForRainYun struct {
}
type AccessConfigForRatPanel struct {
ApiUrl string `json:"apiUrl"`
ServerUrl string `json:"serverUrl"`
AccessTokenId int32 `json:"accessTokenId"`
AccessToken string `json:"accessToken"`
AllowInsecureConnections bool `json:"allowInsecureConnections,omitempty"`
}
type AccessConfigForSafeLine struct {
ApiUrl string `json:"apiUrl"`
ServerUrl string `json:"serverUrl"`
ApiToken string `json:"apiToken"`
AllowInsecureConnections bool `json:"allowInsecureConnections,omitempty"`
}
type AccessConfigForSlackBot struct {
BotToken string `json:"botToken"`
DefaultChannelId string `json:"defaultChannelId,omitempty"`
}
type AccessConfigForSSH struct {
Host string `json:"host"`
Port int32 `json:"port"`
Username string `json:"username"`
AuthMethod string `json:"authMethod,omitempty"`
Username string `json:"username,omitempty"`
Password string `json:"password,omitempty"`
Key string `json:"key,omitempty"`
KeyPassphrase string `json:"keyPassphrase,omitempty"`
JumpServers []struct {
Host string `json:"host"`
Port int32 `json:"port"`
Username string `json:"username"`
AuthMethod string `json:"authMethod,omitempty"`
Username string `json:"username,omitempty"`
Password string `json:"password,omitempty"`
Key string `json:"key,omitempty"`
KeyPassphrase string `json:"keyPassphrase,omitempty"`
@@ -321,6 +352,11 @@ type AccessConfigForUCloud struct {
ProjectId string `json:"projectId,omitempty"`
}
type AccessConfigForUniCloud struct {
Username string `json:"username"`
Password string `json:"password"`
}
type AccessConfigForUpyun struct {
Username string `json:"username"`
Password string `json:"password"`
@@ -357,7 +393,7 @@ type AccessConfigForWeComBot struct {
type AccessConfigForWestcn struct {
Username string `json:"username"`
ApiPassword string `json:"password"`
ApiPassword string `json:"apiPassword"`
}
type AccessConfigForZeroSSL struct {

View File

@@ -28,6 +28,7 @@ type Certificate struct {
ACMEAccountUrl string `json:"acmeAccountUrl" db:"acmeAccountUrl"`
ACMECertUrl string `json:"acmeCertUrl" db:"acmeCertUrl"`
ACMECertStableUrl string `json:"acmeCertStableUrl" db:"acmeCertStableUrl"`
ACMERenewed bool `json:"acmeRenewed" db:"acmeRenewed"`
WorkflowId string `json:"workflowId" db:"workflowId"`
WorkflowNodeId string `json:"workflowNodeId" db:"workflowNodeId"`
WorkflowRunId string `json:"workflowRunId" db:"workflowRunId"`

View File

@@ -0,0 +1,630 @@
package expr
import (
"encoding/json"
"fmt"
"strconv"
)
type (
ExprType string
ExprComparisonOperator string
ExprLogicalOperator string
ExprValueType string
)
const (
GreaterThan ExprComparisonOperator = "gt"
GreaterOrEqual ExprComparisonOperator = "gte"
LessThan ExprComparisonOperator = "lt"
LessOrEqual ExprComparisonOperator = "lte"
Equal ExprComparisonOperator = "eq"
NotEqual ExprComparisonOperator = "neq"
And ExprLogicalOperator = "and"
Or ExprLogicalOperator = "or"
Not ExprLogicalOperator = "not"
Number ExprValueType = "number"
String ExprValueType = "string"
Boolean ExprValueType = "boolean"
ConstantExprType ExprType = "const"
VariantExprType ExprType = "var"
ComparisonExprType ExprType = "comparison"
LogicalExprType ExprType = "logical"
NotExprType ExprType = "not"
)
type EvalResult struct {
Type ExprValueType
Value any
}
func (e *EvalResult) GetFloat64() (float64, error) {
if e.Type != Number {
return 0, fmt.Errorf("type mismatch: %s", e.Type)
}
stringValue, ok := e.Value.(string)
if !ok {
return 0, fmt.Errorf("value is not a string: %v", e.Value)
}
floatValue, err := strconv.ParseFloat(stringValue, 64)
if err != nil {
return 0, fmt.Errorf("failed to parse float64: %v", err)
}
return floatValue, nil
}
func (e *EvalResult) GetBool() (bool, error) {
if e.Type != Boolean {
return false, fmt.Errorf("type mismatch: %s", e.Type)
}
strValue, ok := e.Value.(string)
if ok {
if strValue == "true" {
return true, nil
} else if strValue == "false" {
return false, nil
}
return false, fmt.Errorf("value is not a boolean: %v", e.Value)
}
boolValue, ok := e.Value.(bool)
if !ok {
return false, fmt.Errorf("value is not a boolean: %v", e.Value)
}
return boolValue, nil
}
func (e *EvalResult) GreaterThan(other *EvalResult) (*EvalResult, error) {
if e.Type != other.Type {
return nil, fmt.Errorf("type mismatch: %s vs %s", e.Type, other.Type)
}
switch e.Type {
case String:
return &EvalResult{
Type: Boolean,
Value: e.Value.(string) > other.Value.(string),
}, nil
case Number:
left, err := e.GetFloat64()
if err != nil {
return nil, err
}
right, err := other.GetFloat64()
if err != nil {
return nil, err
}
return &EvalResult{
Type: Boolean,
Value: left > right,
}, nil
default:
return nil, fmt.Errorf("unsupported value type: %s", e.Type)
}
}
func (e *EvalResult) GreaterOrEqual(other *EvalResult) (*EvalResult, error) {
if e.Type != other.Type {
return nil, fmt.Errorf("type mismatch: %s vs %s", e.Type, other.Type)
}
switch e.Type {
case String:
return &EvalResult{
Type: Boolean,
Value: e.Value.(string) >= other.Value.(string),
}, nil
case Number:
left, err := e.GetFloat64()
if err != nil {
return nil, err
}
right, err := other.GetFloat64()
if err != nil {
return nil, err
}
return &EvalResult{
Type: Boolean,
Value: left >= right,
}, nil
default:
return nil, fmt.Errorf("unsupported value type: %s", e.Type)
}
}
func (e *EvalResult) LessThan(other *EvalResult) (*EvalResult, error) {
if e.Type != other.Type {
return nil, fmt.Errorf("type mismatch: %s vs %s", e.Type, other.Type)
}
switch e.Type {
case String:
return &EvalResult{
Type: Boolean,
Value: e.Value.(string) < other.Value.(string),
}, nil
case Number:
left, err := e.GetFloat64()
if err != nil {
return nil, err
}
right, err := other.GetFloat64()
if err != nil {
return nil, err
}
return &EvalResult{
Type: Boolean,
Value: left < right,
}, nil
default:
return nil, fmt.Errorf("unsupported value type: %s", e.Type)
}
}
func (e *EvalResult) LessOrEqual(other *EvalResult) (*EvalResult, error) {
if e.Type != other.Type {
return nil, fmt.Errorf("type mismatch: %s vs %s", e.Type, other.Type)
}
switch e.Type {
case String:
return &EvalResult{
Type: Boolean,
Value: e.Value.(string) <= other.Value.(string),
}, nil
case Number:
left, err := e.GetFloat64()
if err != nil {
return nil, err
}
right, err := other.GetFloat64()
if err != nil {
return nil, err
}
return &EvalResult{
Type: Boolean,
Value: left <= right,
}, nil
default:
return nil, fmt.Errorf("unsupported value type: %s", e.Type)
}
}
func (e *EvalResult) Equal(other *EvalResult) (*EvalResult, error) {
if e.Type != other.Type {
return nil, fmt.Errorf("type mismatch: %s vs %s", e.Type, other.Type)
}
switch e.Type {
case String:
return &EvalResult{
Type: Boolean,
Value: e.Value.(string) == other.Value.(string),
}, nil
case Number:
left, err := e.GetFloat64()
if err != nil {
return nil, err
}
right, err := other.GetFloat64()
if err != nil {
return nil, err
}
return &EvalResult{
Type: Boolean,
Value: left == right,
}, nil
case Boolean:
left, err := e.GetBool()
if err != nil {
return nil, err
}
right, err := other.GetBool()
if err != nil {
return nil, err
}
return &EvalResult{
Type: Boolean,
Value: left == right,
}, nil
default:
return nil, fmt.Errorf("unsupported value type: %s", e.Type)
}
}
func (e *EvalResult) NotEqual(other *EvalResult) (*EvalResult, error) {
if e.Type != other.Type {
return nil, fmt.Errorf("type mismatch: %s vs %s", e.Type, other.Type)
}
switch e.Type {
case String:
return &EvalResult{
Type: Boolean,
Value: e.Value.(string) != other.Value.(string),
}, nil
case Number:
left, err := e.GetFloat64()
if err != nil {
return nil, err
}
right, err := other.GetFloat64()
if err != nil {
return nil, err
}
return &EvalResult{
Type: Boolean,
Value: left != right,
}, nil
case Boolean:
left, err := e.GetBool()
if err != nil {
return nil, err
}
right, err := other.GetBool()
if err != nil {
return nil, err
}
return &EvalResult{
Type: Boolean,
Value: left != right,
}, nil
default:
return nil, fmt.Errorf("unsupported value type: %s", e.Type)
}
}
func (e *EvalResult) And(other *EvalResult) (*EvalResult, error) {
if e.Type != other.Type {
return nil, fmt.Errorf("type mismatch: %s vs %s", e.Type, other.Type)
}
switch e.Type {
case Boolean:
left, err := e.GetBool()
if err != nil {
return nil, err
}
right, err := other.GetBool()
if err != nil {
return nil, err
}
return &EvalResult{
Type: Boolean,
Value: left && right,
}, nil
default:
return nil, fmt.Errorf("unsupported value type: %s", e.Type)
}
}
func (e *EvalResult) Or(other *EvalResult) (*EvalResult, error) {
if e.Type != other.Type {
return nil, fmt.Errorf("type mismatch: %s vs %s", e.Type, other.Type)
}
switch e.Type {
case Boolean:
left, err := e.GetBool()
if err != nil {
return nil, err
}
right, err := other.GetBool()
if err != nil {
return nil, err
}
return &EvalResult{
Type: Boolean,
Value: left || right,
}, nil
default:
return nil, fmt.Errorf("unsupported value type: %s", e.Type)
}
}
func (e *EvalResult) Not() (*EvalResult, error) {
if e.Type != Boolean {
return nil, fmt.Errorf("type mismatch: %s", e.Type)
}
boolValue, err := e.GetBool()
if err != nil {
return nil, err
}
return &EvalResult{
Type: Boolean,
Value: !boolValue,
}, nil
}
type Expr interface {
GetType() ExprType
Eval(variables map[string]map[string]any) (*EvalResult, error)
}
type ExprValueSelector struct {
Id string `json:"id"`
Name string `json:"name"`
Type ExprValueType `json:"type"`
}
type ConstantExpr struct {
Type ExprType `json:"type"`
Value string `json:"value"`
ValueType ExprValueType `json:"valueType"`
}
func (c ConstantExpr) GetType() ExprType { return c.Type }
func (c ConstantExpr) Eval(variables map[string]map[string]any) (*EvalResult, error) {
return &EvalResult{
Type: c.ValueType,
Value: c.Value,
}, nil
}
type VariantExpr struct {
Type ExprType `json:"type"`
Selector ExprValueSelector `json:"selector"`
}
func (v VariantExpr) GetType() ExprType { return v.Type }
func (v VariantExpr) Eval(variables map[string]map[string]any) (*EvalResult, error) {
if v.Selector.Id == "" {
return nil, fmt.Errorf("node id is empty")
}
if v.Selector.Name == "" {
return nil, fmt.Errorf("name is empty")
}
if _, ok := variables[v.Selector.Id]; !ok {
return nil, fmt.Errorf("node %s not found", v.Selector.Id)
}
if _, ok := variables[v.Selector.Id][v.Selector.Name]; !ok {
return nil, fmt.Errorf("variable %s not found in node %s", v.Selector.Name, v.Selector.Id)
}
return &EvalResult{
Type: v.Selector.Type,
Value: variables[v.Selector.Id][v.Selector.Name],
}, nil
}
type ComparisonExpr struct {
Type ExprType `json:"type"` // compare
Operator ExprComparisonOperator `json:"operator"`
Left Expr `json:"left"`
Right Expr `json:"right"`
}
func (c ComparisonExpr) GetType() ExprType { return c.Type }
func (c ComparisonExpr) Eval(variables map[string]map[string]any) (*EvalResult, error) {
left, err := c.Left.Eval(variables)
if err != nil {
return nil, err
}
right, err := c.Right.Eval(variables)
if err != nil {
return nil, err
}
switch c.Operator {
case GreaterThan:
return left.GreaterThan(right)
case LessThan:
return left.LessThan(right)
case GreaterOrEqual:
return left.GreaterOrEqual(right)
case LessOrEqual:
return left.LessOrEqual(right)
case Equal:
return left.Equal(right)
case NotEqual:
return left.NotEqual(right)
default:
return nil, fmt.Errorf("unknown expression operator: %s", c.Operator)
}
}
type LogicalExpr struct {
Type ExprType `json:"type"` // logical
Operator ExprLogicalOperator `json:"operator"`
Left Expr `json:"left"`
Right Expr `json:"right"`
}
func (l LogicalExpr) GetType() ExprType { return l.Type }
func (l LogicalExpr) Eval(variables map[string]map[string]any) (*EvalResult, error) {
left, err := l.Left.Eval(variables)
if err != nil {
return nil, err
}
right, err := l.Right.Eval(variables)
if err != nil {
return nil, err
}
switch l.Operator {
case And:
return left.And(right)
case Or:
return left.Or(right)
default:
return nil, fmt.Errorf("unknown expression operator: %s", l.Operator)
}
}
type NotExpr struct {
Type ExprType `json:"type"` // not
Expr Expr `json:"expr"`
}
func (n NotExpr) GetType() ExprType { return n.Type }
func (n NotExpr) Eval(variables map[string]map[string]any) (*EvalResult, error) {
inner, err := n.Expr.Eval(variables)
if err != nil {
return nil, err
}
return inner.Not()
}
type rawExpr struct {
Type ExprType `json:"type"`
}
func MarshalExpr(e Expr) ([]byte, error) {
return json.Marshal(e)
}
func UnmarshalExpr(data []byte) (Expr, error) {
var typ rawExpr
if err := json.Unmarshal(data, &typ); err != nil {
return nil, err
}
switch typ.Type {
case ConstantExprType:
var e ConstantExpr
if err := json.Unmarshal(data, &e); err != nil {
return nil, err
}
return e, nil
case VariantExprType:
var e VariantExpr
if err := json.Unmarshal(data, &e); err != nil {
return nil, err
}
return e, nil
case ComparisonExprType:
var e ComparisonExprRaw
if err := json.Unmarshal(data, &e); err != nil {
return nil, err
}
return e.ToComparisonExpr()
case LogicalExprType:
var e LogicalExprRaw
if err := json.Unmarshal(data, &e); err != nil {
return nil, err
}
return e.ToLogicalExpr()
case NotExprType:
var e NotExprRaw
if err := json.Unmarshal(data, &e); err != nil {
return nil, err
}
return e.ToNotExpr()
default:
return nil, fmt.Errorf("unknown expression type: %s", typ.Type)
}
}
type ComparisonExprRaw struct {
Type ExprType `json:"type"`
Operator ExprComparisonOperator `json:"operator"`
Left json.RawMessage `json:"left"`
Right json.RawMessage `json:"right"`
}
func (r ComparisonExprRaw) ToComparisonExpr() (ComparisonExpr, error) {
leftExpr, err := UnmarshalExpr(r.Left)
if err != nil {
return ComparisonExpr{}, err
}
rightExpr, err := UnmarshalExpr(r.Right)
if err != nil {
return ComparisonExpr{}, err
}
return ComparisonExpr{
Type: r.Type,
Operator: r.Operator,
Left: leftExpr,
Right: rightExpr,
}, nil
}
type LogicalExprRaw struct {
Type ExprType `json:"type"`
Operator ExprLogicalOperator `json:"operator"`
Left json.RawMessage `json:"left"`
Right json.RawMessage `json:"right"`
}
func (r LogicalExprRaw) ToLogicalExpr() (LogicalExpr, error) {
left, err := UnmarshalExpr(r.Left)
if err != nil {
return LogicalExpr{}, err
}
right, err := UnmarshalExpr(r.Right)
if err != nil {
return LogicalExpr{}, err
}
return LogicalExpr{
Type: r.Type,
Operator: r.Operator,
Left: left,
Right: right,
}, nil
}
type NotExprRaw struct {
Type ExprType `json:"type"`
Expr json.RawMessage `json:"expr"`
}
func (r NotExprRaw) ToNotExpr() (NotExpr, error) {
inner, err := UnmarshalExpr(r.Expr)
if err != nil {
return NotExpr{}, err
}
return NotExpr{
Type: r.Type,
Expr: inner,
}, nil
}

View File

@@ -0,0 +1,127 @@
package expr
import (
"testing"
)
func TestLogicalEval(t *testing.T) {
// 测试逻辑表达式 and
logicalExpr := LogicalExpr{
Left: ConstantExpr{
Type: "const",
Value: "true",
ValueType: "boolean",
},
Operator: And,
Right: ConstantExpr{
Type: "const",
Value: "true",
ValueType: "boolean",
},
}
result, err := logicalExpr.Eval(nil)
if err != nil {
t.Errorf("failed to evaluate logical expression: %v", err)
}
if result.Value != true {
t.Errorf("expected true, got %v", result)
}
// 测试逻辑表达式 or
orExpr := LogicalExpr{
Left: ConstantExpr{
Type: "const",
Value: "true",
ValueType: "boolean",
},
Operator: Or,
Right: ConstantExpr{
Type: "const",
Value: "true",
ValueType: "boolean",
},
}
result, err = orExpr.Eval(nil)
if err != nil {
t.Errorf("failed to evaluate logical expression: %v", err)
}
if result.Value != true {
t.Errorf("expected true, got %v", result)
}
}
func TestUnmarshalExpr(t *testing.T) {
type args struct {
data []byte
}
tests := []struct {
name string
args args
want Expr
wantErr bool
}{
{
name: "test1",
args: args{
data: []byte(`{"left":{"left":{"selector":{"id":"ODnYSOXB6HQP2_vz6JcZE","name":"certificate.validity","type":"boolean"},"type":"var"},"operator":"is","right":{"type":"const","value":true,"valueType":"boolean"},"type":"comparison"},"operator":"and","right":{"left":{"selector":{"id":"ODnYSOXB6HQP2_vz6JcZE","name":"certificate.daysLeft","type":"number"},"type":"var"},"operator":"eq","right":{"type":"const","value":2,"valueType":"number"},"type":"comparison"},"type":"logical"}`),
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := UnmarshalExpr(tt.args.data)
if (err != nil) != tt.wantErr {
t.Errorf("UnmarshalExpr() error = %v, wantErr %v", err, tt.wantErr)
return
}
if got == nil {
t.Errorf("UnmarshalExpr() got = nil, want %v", tt.want)
return
}
})
}
}
func TestExpr_Eval(t *testing.T) {
type args struct {
variables map[string]map[string]any
data []byte
}
tests := []struct {
name string
args args
want *EvalResult
wantErr bool
}{
{
name: "test1",
args: args{
variables: map[string]map[string]any{
"ODnYSOXB6HQP2_vz6JcZE": {
"certificate.validity": true,
"certificate.daysLeft": 2,
},
},
data: []byte(`{"left":{"left":{"selector":{"id":"ODnYSOXB6HQP2_vz6JcZE","name":"certificate.validity","type":"boolean"},"type":"var"},"operator":"is","right":{"type":"const","value":true,"valueType":"boolean"},"type":"comparison"},"operator":"and","right":{"left":{"selector":{"id":"ODnYSOXB6HQP2_vz6JcZE","name":"certificate.daysLeft","type":"number"},"type":"var"},"operator":"eq","right":{"type":"const","value":2,"valueType":"number"},"type":"comparison"},"type":"logical"}`),
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
c, err := UnmarshalExpr(tt.args.data)
if err != nil {
t.Errorf("UnmarshalExpr() error = %v", err)
return
}
got, err := c.Eval(tt.args.variables)
t.Log("got:", got)
if (err != nil) != tt.wantErr {
t.Errorf("ConstExpr.Eval() error = %v, wantErr %v", err, tt.wantErr)
return
}
if got.Value != true {
t.Errorf("ConstExpr.Eval() got = %v, want %v", got.Value, true)
}
})
}
}

View File

@@ -28,12 +28,16 @@ const (
AccessProviderTypeCloudflare = AccessProviderType("cloudflare")
AccessProviderTypeClouDNS = AccessProviderType("cloudns")
AccessProviderTypeCMCCCloud = AccessProviderType("cmcccloud")
AccessProviderTypeConstellix = AccessProviderType("constellix")
AccessProviderTypeCTCCCloud = AccessProviderType("ctcccloud") // 天翼云(预留)
AccessProviderTypeCUCCCloud = AccessProviderType("cucccloud") // 联通云(预留)
AccessProviderTypeDeSEC = AccessProviderType("desec")
AccessProviderTypeDigitalOcean = AccessProviderType("digitalocean")
AccessProviderTypeDingTalkBot = AccessProviderType("dingtalkbot")
AccessProviderTypeDiscordBot = AccessProviderType("discordbot")
AccessProviderTypeDNSLA = AccessProviderType("dnsla")
AccessProviderTypeDogeCloud = AccessProviderType("dogecloud")
AccessProviderTypeDuckDNS = AccessProviderType("duckdns")
AccessProviderTypeDynv6 = AccessProviderType("dynv6")
AccessProviderTypeEdgio = AccessProviderType("edgio")
AccessProviderTypeEmail = AccessProviderType("email")
@@ -44,6 +48,7 @@ const (
AccessProviderTypeGoDaddy = AccessProviderType("godaddy")
AccessProviderTypeGoEdge = AccessProviderType("goedge")
AccessProviderTypeGoogleTrustServices = AccessProviderType("googletrustservices")
AccessProviderTypeHetzner = AccessProviderType("hetzner")
AccessProviderTypeHuaweiCloud = AccessProviderType("huaweicloud")
AccessProviderTypeJDCloud = AccessProviderType("jdcloud")
AccessProviderTypeKubernetes = AccessProviderType("k8s")
@@ -67,11 +72,13 @@ const (
AccessProviderTypeRainYun = AccessProviderType("rainyun")
AccessProviderTypeRatPanel = AccessProviderType("ratpanel")
AccessProviderTypeSafeLine = AccessProviderType("safeline")
AccessProviderTypeSlackBot = AccessProviderType("slackbot")
AccessProviderTypeSSH = AccessProviderType("ssh")
AccessProviderTypeSSLCOM = AccessProviderType("sslcom")
AccessProviderTypeTelegramBot = AccessProviderType("telegrambot")
AccessProviderTypeTencentCloud = AccessProviderType("tencentcloud")
AccessProviderTypeUCloud = AccessProviderType("ucloud")
AccessProviderTypeUniCloud = AccessProviderType("unicloud")
AccessProviderTypeUpyun = AccessProviderType("upyun")
AccessProviderTypeVercel = AccessProviderType("vercel")
AccessProviderTypeVolcEngine = AccessProviderType("volcengine")
@@ -125,12 +132,16 @@ const (
ACMEDns01ProviderTypeCloudflare = ACMEDns01ProviderType(AccessProviderTypeCloudflare)
ACMEDns01ProviderTypeClouDNS = ACMEDns01ProviderType(AccessProviderTypeClouDNS)
ACMEDns01ProviderTypeCMCCCloud = ACMEDns01ProviderType(AccessProviderTypeCMCCCloud)
ACMEDns01ProviderTypeConstellix = ACMEDns01ProviderType(AccessProviderTypeConstellix)
ACMEDns01ProviderTypeDeSEC = ACMEDns01ProviderType(AccessProviderTypeDeSEC)
ACMEDns01ProviderTypeDigitalOcean = ACMEDns01ProviderType(AccessProviderTypeDigitalOcean)
ACMEDns01ProviderTypeDNSLA = ACMEDns01ProviderType(AccessProviderTypeDNSLA)
ACMEDns01ProviderTypeDuckDNS = ACMEDns01ProviderType(AccessProviderTypeDuckDNS)
ACMEDns01ProviderTypeDynv6 = ACMEDns01ProviderType(AccessProviderTypeDynv6)
ACMEDns01ProviderTypeGcore = ACMEDns01ProviderType(AccessProviderTypeGcore)
ACMEDns01ProviderTypeGname = ACMEDns01ProviderType(AccessProviderTypeGname)
ACMEDns01ProviderTypeGoDaddy = ACMEDns01ProviderType(AccessProviderTypeGoDaddy)
ACMEDns01ProviderTypeHetzner = ACMEDns01ProviderType(AccessProviderTypeHetzner)
ACMEDns01ProviderTypeHuaweiCloud = ACMEDns01ProviderType(AccessProviderTypeHuaweiCloud) // 兼容旧值,等同于 [ACMEDns01ProviderTypeHuaweiCloudDNS]
ACMEDns01ProviderTypeHuaweiCloudDNS = ACMEDns01ProviderType(AccessProviderTypeHuaweiCloud + "-dns")
ACMEDns01ProviderTypeJDCloud = ACMEDns01ProviderType(AccessProviderTypeJDCloud) // 兼容旧值,等同于 [ACMEDns01ProviderTypeJDCloudDNS]
@@ -147,6 +158,7 @@ const (
ACMEDns01ProviderTypeTencentCloud = ACMEDns01ProviderType(AccessProviderTypeTencentCloud) // 兼容旧值,等同于 [ACMEDns01ProviderTypeTencentCloudDNS]
ACMEDns01ProviderTypeTencentCloudDNS = ACMEDns01ProviderType(AccessProviderTypeTencentCloud + "-dns")
ACMEDns01ProviderTypeTencentCloudEO = ACMEDns01ProviderType(AccessProviderTypeTencentCloud + "-eo")
ACMEDns01ProviderTypeUCloudUDNR = ACMEDns01ProviderType(AccessProviderTypeUCloud + "-udnr")
ACMEDns01ProviderTypeVercel = ACMEDns01ProviderType(AccessProviderTypeVercel)
ACMEDns01ProviderTypeVolcEngine = ACMEDns01ProviderType(AccessProviderTypeVolcEngine) // 兼容旧值,等同于 [ACMEDns01ProviderTypeVolcEngineDNS]
ACMEDns01ProviderTypeVolcEngineDNS = ACMEDns01ProviderType(AccessProviderTypeVolcEngine + "-dns")
@@ -183,6 +195,7 @@ const (
DeploymentProviderTypeAliyunWAF = DeploymentProviderType(AccessProviderTypeAliyun + "-waf")
DeploymentProviderTypeAWSACM = DeploymentProviderType(AccessProviderTypeAWS + "-acm")
DeploymentProviderTypeAWSCloudFront = DeploymentProviderType(AccessProviderTypeAWS + "-cloudfront")
DeploymentProviderTypeAWSIAM = DeploymentProviderType(AccessProviderTypeAWS + "-iam")
DeploymentProviderTypeAzureKeyVault = DeploymentProviderType(AccessProviderTypeAzure + "-keyvault")
DeploymentProviderTypeBaiduCloudAppBLB = DeploymentProviderType(AccessProviderTypeBaiduCloud + "-appblb")
DeploymentProviderTypeBaiduCloudBLB = DeploymentProviderType(AccessProviderTypeBaiduCloud + "-blb")
@@ -236,6 +249,7 @@ const (
DeploymentProviderTypeTencentCloudWAF = DeploymentProviderType(AccessProviderTypeTencentCloud + "-waf")
DeploymentProviderTypeUCloudUCDN = DeploymentProviderType(AccessProviderTypeUCloud + "-ucdn")
DeploymentProviderTypeUCloudUS3 = DeploymentProviderType(AccessProviderTypeUCloud + "-us3")
DeploymentProviderTypeUniCloudWebHost = DeploymentProviderType(AccessProviderTypeUniCloud + "-webhost")
DeploymentProviderTypeUpyunCDN = DeploymentProviderType(AccessProviderTypeUpyun + "-cdn")
DeploymentProviderTypeUpyunFile = DeploymentProviderType(AccessProviderTypeUpyun + "-file")
DeploymentProviderTypeVolcEngineALB = DeploymentProviderType(AccessProviderTypeVolcEngine + "-alb")
@@ -263,9 +277,11 @@ type NotificationProviderType string
*/
const (
NotificationProviderTypeDingTalkBot = NotificationProviderType(AccessProviderTypeDingTalkBot)
NotificationProviderTypeDiscordBot = NotificationProviderType(AccessProviderTypeDiscordBot)
NotificationProviderTypeEmail = NotificationProviderType(AccessProviderTypeEmail)
NotificationProviderTypeLarkBot = NotificationProviderType(AccessProviderTypeLarkBot)
NotificationProviderTypeMattermost = NotificationProviderType(AccessProviderTypeMattermost)
NotificationProviderTypeSlackBot = NotificationProviderType(AccessProviderTypeSlackBot)
NotificationProviderTypeTelegramBot = NotificationProviderType(AccessProviderTypeTelegramBot)
NotificationProviderTypeWebhook = NotificationProviderType(AccessProviderTypeWebhook)
NotificationProviderTypeWeComBot = NotificationProviderType(AccessProviderTypeWeComBot)

View File

@@ -1,8 +1,10 @@
package domain
import (
"encoding/json"
"time"
"github.com/usual2970/certimate/internal/domain/expr"
maputil "github.com/usual2970/certimate/internal/pkg/utils/map"
)
@@ -30,6 +32,7 @@ const (
WorkflowNodeTypeEnd = WorkflowNodeType("end")
WorkflowNodeTypeApply = WorkflowNodeType("apply")
WorkflowNodeTypeUpload = WorkflowNodeType("upload")
WorkflowNodeTypeMonitor = WorkflowNodeType("monitor")
WorkflowNodeTypeDeploy = WorkflowNodeType("deploy")
WorkflowNodeTypeNotify = WorkflowNodeType("notify")
WorkflowNodeTypeBranch = WorkflowNodeType("branch")
@@ -68,23 +71,30 @@ type WorkflowNodeConfigForApply struct {
Provider string `json:"provider"` // DNS 提供商
ProviderAccessId string `json:"providerAccessId"` // DNS 提供商授权记录 ID
ProviderConfig map[string]any `json:"providerConfig"` // DNS 提供商额外配置
CAProvider string `json:"caProvider,omitempty"` // CA 提供商(零值使用全局配置)
CAProvider string `json:"caProvider,omitempty"` // CA 提供商(零值使用全局配置)
CAProviderAccessId string `json:"caProviderAccessId,omitempty"` // CA 提供商授权记录 ID
CAProviderConfig map[string]any `json:"caProviderConfig,omitempty"` // CA 提供商额外配置
KeyAlgorithm string `json:"keyAlgorithm"` // 证书算法
Nameservers string `json:"nameservers,omitempty"` // DNS 服务器列表,以半角分号分隔
DnsPropagationWait int32 `json:"dnsPropagationWait,omitempty"` // DNS 传播等待时间,等同于 lego 的 `--dns-propagation-wait` 参数
DnsPropagationTimeout int32 `json:"dnsPropagationTimeout,omitempty"` // DNS 传播检查超时时间(零值取决于提供商的默认值)
DnsTTL int32 `json:"dnsTTL,omitempty"` // DNS 解析记录 TTL零值取决于提供商的默认值)
DnsPropagationTimeout int32 `json:"dnsPropagationTimeout,omitempty"` // DNS 传播检查超时时间(零值时使用提供商的默认值)
DnsTTL int32 `json:"dnsTTL,omitempty"` // DNS 解析记录 TTL零值时使用提供商的默认值)
DisableFollowCNAME bool `json:"disableFollowCNAME,omitempty"` // 是否关闭 CNAME 跟随
DisableARI bool `json:"disableARI,omitempty"` // 是否关闭 ARI
SkipBeforeExpiryDays int32 `json:"skipBeforeExpiryDays,omitempty"` // 证书到期前多少天前跳过续期(零值将使用默认值 30
SkipBeforeExpiryDays int32 `json:"skipBeforeExpiryDays,omitempty"` // 证书到期前多少天前跳过续期(零值默认值 30
}
type WorkflowNodeConfigForUpload struct {
Certificate string `json:"certificate"`
PrivateKey string `json:"privateKey"`
Domains string `json:"domains"`
Certificate string `json:"certificate"` // 证书 PEM 内容
PrivateKey string `json:"privateKey"` // 私钥 PEM 内容
Domains string `json:"domains,omitempty"`
}
type WorkflowNodeConfigForMonitor struct {
Host string `json:"host"` // 主机地址
Port int32 `json:"port,omitempty"` // 端口(零值时默认值 443
Domain string `json:"domain,omitempty"` // 域名(零值时默认值 [Host]
RequestPath string `json:"requestPath,omitempty"` // 请求路径
}
type WorkflowNodeConfigForDeploy struct {
@@ -104,6 +114,10 @@ type WorkflowNodeConfigForNotify struct {
Message string `json:"message"` // 通知内容
}
type WorkflowNodeConfigForCondition struct {
Expression expr.Expr `json:"expression"` // 条件表达式
}
func (n *WorkflowNode) GetConfigForApply() WorkflowNodeConfigForApply {
return WorkflowNodeConfigForApply{
Domains: maputil.GetString(n.Config, "domains"),
@@ -133,6 +147,16 @@ func (n *WorkflowNode) GetConfigForUpload() WorkflowNodeConfigForUpload {
}
}
func (n *WorkflowNode) GetConfigForMonitor() WorkflowNodeConfigForMonitor {
host := maputil.GetString(n.Config, "host")
return WorkflowNodeConfigForMonitor{
Host: host,
Port: maputil.GetOrDefaultInt32(n.Config, "port", 443),
Domain: maputil.GetOrDefaultString(n.Config, "domain", host),
RequestPath: maputil.GetString(n.Config, "path"),
}
}
func (n *WorkflowNode) GetConfigForDeploy() WorkflowNodeConfigForDeploy {
return WorkflowNodeConfigForDeploy{
Certificate: maputil.GetString(n.Config, "certificate"),
@@ -154,6 +178,23 @@ func (n *WorkflowNode) GetConfigForNotify() WorkflowNodeConfigForNotify {
}
}
func (n *WorkflowNode) GetConfigForCondition() WorkflowNodeConfigForCondition {
expression := n.Config["expression"]
if expression == nil {
return WorkflowNodeConfigForCondition{}
}
exprRaw, _ := json.Marshal(expression)
expr, err := expr.UnmarshalExpr([]byte(exprRaw))
if err != nil {
return WorkflowNodeConfigForCondition{}
}
return WorkflowNodeConfigForCondition{
Expression: expr,
}
}
type WorkflowNodeIO struct {
Label string `json:"label"`
Name string `json:"name"`
@@ -163,9 +204,6 @@ type WorkflowNodeIO struct {
ValueSelector WorkflowNodeIOValueSelector `json:"valueSelector"`
}
type WorkflowNodeIOValueSelector struct {
Id string `json:"id"`
Name string `json:"name"`
}
type WorkflowNodeIOValueSelector = expr.ExprValueSelector
const WorkflowNodeIONameCertificate string = "certificate"

View File

@@ -29,18 +29,18 @@ func NewWithWorkflowNode(config NotifierWithWorkflowNodeConfig) (Notifier, error
return nil, fmt.Errorf("node type is not '%s'", string(domain.WorkflowNodeTypeNotify))
}
nodeConfig := config.Node.GetConfigForNotify()
nodeCfg := config.Node.GetConfigForNotify()
options := &notifierProviderOptions{
Provider: domain.NotificationProviderType(nodeConfig.Provider),
Provider: domain.NotificationProviderType(nodeCfg.Provider),
ProviderAccessConfig: make(map[string]any),
ProviderServiceConfig: nodeConfig.ProviderConfig,
ProviderServiceConfig: nodeCfg.ProviderConfig,
}
accessRepo := repository.NewAccessRepository()
if nodeConfig.ProviderAccessId != "" {
access, err := accessRepo.GetById(context.Background(), nodeConfig.ProviderAccessId)
if nodeCfg.ProviderAccessId != "" {
access, err := accessRepo.GetById(context.Background(), nodeCfg.ProviderAccessId)
if err != nil {
return nil, fmt.Errorf("failed to get access #%s record: %w", nodeConfig.ProviderAccessId, err)
return nil, fmt.Errorf("failed to get access #%s record: %w", nodeCfg.ProviderAccessId, err)
} else {
options.ProviderAccessConfig = access.Config
}

View File

@@ -7,9 +7,11 @@ import (
"github.com/usual2970/certimate/internal/domain"
"github.com/usual2970/certimate/internal/pkg/core/notifier"
pDingTalkBot "github.com/usual2970/certimate/internal/pkg/core/notifier/providers/dingtalkbot"
pDiscordBot "github.com/usual2970/certimate/internal/pkg/core/notifier/providers/discordbot"
pEmail "github.com/usual2970/certimate/internal/pkg/core/notifier/providers/email"
pLarkBot "github.com/usual2970/certimate/internal/pkg/core/notifier/providers/larkbot"
pMattermost "github.com/usual2970/certimate/internal/pkg/core/notifier/providers/mattermost"
pSlackBot "github.com/usual2970/certimate/internal/pkg/core/notifier/providers/slackbot"
pTelegramBot "github.com/usual2970/certimate/internal/pkg/core/notifier/providers/telegrambot"
pWebhook "github.com/usual2970/certimate/internal/pkg/core/notifier/providers/webhook"
pWeComBot "github.com/usual2970/certimate/internal/pkg/core/notifier/providers/wecombot"
@@ -42,6 +44,19 @@ func createNotifierProvider(options *notifierProviderOptions) (notifier.Notifier
})
}
case domain.NotificationProviderTypeDiscordBot:
{
access := domain.AccessConfigForDiscordBot{}
if err := maputil.Populate(options.ProviderAccessConfig, &access); err != nil {
return nil, fmt.Errorf("failed to populate provider access config: %w", err)
}
return pDiscordBot.NewNotifier(&pDiscordBot.NotifierConfig{
BotToken: access.BotToken,
ChannelId: maputil.GetOrDefaultString(options.ProviderServiceConfig, "channelId", access.DefaultChannelId),
})
}
case domain.NotificationProviderTypeEmail:
{
access := domain.AccessConfigForEmail{}
@@ -87,6 +102,19 @@ func createNotifierProvider(options *notifierProviderOptions) (notifier.Notifier
})
}
case domain.NotificationProviderTypeSlackBot:
{
access := domain.AccessConfigForSlackBot{}
if err := maputil.Populate(options.ProviderAccessConfig, &access); err != nil {
return nil, fmt.Errorf("failed to populate provider access config: %w", err)
}
return pSlackBot.NewNotifier(&pSlackBot.NotifierConfig{
BotToken: access.BotToken,
ChannelId: maputil.GetOrDefaultString(options.ProviderServiceConfig, "channelId", access.DefaultChannelId),
})
}
case domain.NotificationProviderTypeTelegramBot:
{
access := domain.AccessConfigForTelegramBot{}

View File

@@ -1,9 +1,8 @@
package lego_aliyunesa
package internal
import (
"errors"
"fmt"
"strings"
"sync"
"time"
@@ -89,6 +88,8 @@ func NewDNSProviderConfig(config *Config) (*DNSProvider, error) {
return &DNSProvider{
client: client,
config: config,
siteIDs: make(map[string]int64),
}, nil
}
@@ -100,12 +101,13 @@ func (d *DNSProvider) Present(domain, token, keyAuth string) error {
return fmt.Errorf("alicloud-esa: could not find zone for domain %q: %w", domain, err)
}
siteId, err := d.getSiteId(authZone)
siteName := dns01.UnFqdn(authZone)
siteId, err := d.getSiteId(siteName)
if err != nil {
return fmt.Errorf("alicloud-esa: could not find site for zone %q: %w", authZone, err)
return fmt.Errorf("alicloud-esa: could not find site for zone %q: %w", siteName, err)
}
if err := d.addOrUpdateDNSRecord(siteId, strings.TrimRight(info.EffectiveFQDN, "."), info.Value); err != nil {
if err := d.addOrUpdateDNSRecord(siteId, dns01.UnFqdn(info.EffectiveFQDN), info.Value); err != nil {
return fmt.Errorf("alicloud-esa: %w", err)
}
@@ -120,12 +122,13 @@ func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error {
return fmt.Errorf("alicloud-esa: could not find zone for domain %q: %w", domain, err)
}
siteId, err := d.getSiteId(authZone)
siteName := dns01.UnFqdn(authZone)
siteId, err := d.getSiteId(siteName)
if err != nil {
return fmt.Errorf("alicloud-esa: could not find site for zone %q: %w", authZone, err)
return fmt.Errorf("alicloud-esa: could not find site for zone %q: %w", siteName, err)
}
if err := d.removeDNSRecord(siteId, strings.TrimRight(info.EffectiveFQDN, ".")); err != nil {
if err := d.removeDNSRecord(siteId, dns01.UnFqdn(info.EffectiveFQDN)); err != nil {
return fmt.Errorf("alicloud-esa: %w", err)
}
@@ -148,10 +151,11 @@ func (d *DNSProvider) getSiteId(siteName string) (int64, error) {
pageSize := 500
for {
request := &aliesa.ListSitesRequest{
SiteName: tea.String(siteName),
PageNumber: tea.Int32(int32(pageNumber)),
PageSize: tea.Int32(int32(pageNumber)),
AccessType: tea.String("NS"),
SiteName: tea.String(siteName),
SiteSearchType: tea.String("exact"),
PageNumber: tea.Int32(int32(pageNumber)),
PageSize: tea.Int32(int32(pageSize)),
AccessType: tea.String("NS"),
}
response, err := d.client.ListSites(request)
if err != nil {
@@ -178,7 +182,7 @@ func (d *DNSProvider) getSiteId(siteName string) (int64, error) {
}
}
return 0, errors.New("failed to get site id")
return 0, errors.New("site not found")
}
func (d *DNSProvider) findDNSRecord(siteId int64, effectiveFQDN string) (*aliesa.ListRecordsResponseBodyRecords, error) {
@@ -186,11 +190,12 @@ func (d *DNSProvider) findDNSRecord(siteId int64, effectiveFQDN string) (*aliesa
pageSize := 500
for {
request := &aliesa.ListRecordsRequest{
SiteId: tea.Int64(siteId),
Type: tea.String("TXT"),
RecordName: tea.String(effectiveFQDN),
PageNumber: tea.Int32(int32(pageNumber)),
PageSize: tea.Int32(int32(pageNumber)),
SiteId: tea.Int64(siteId),
Type: tea.String("TXT"),
RecordName: tea.String(effectiveFQDN),
RecordMatchType: tea.String("exact"),
PageNumber: tea.Int32(int32(pageNumber)),
PageSize: tea.Int32(int32(pageSize)),
}
response, err := d.client.ListRecords(request)
if err != nil {

View File

@@ -1,4 +1,4 @@
package lego_baiducloud
package internal
import (
"errors"

View File

@@ -0,0 +1,38 @@
package cloudns
import (
"time"
"github.com/go-acme/lego/v4/challenge"
"github.com/go-acme/lego/v4/providers/dns/constellix"
)
type ChallengeProviderConfig struct {
ApiKey string `json:"apiKey"`
SecretKey string `json:"secretKey"`
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 := constellix.NewDefaultConfig()
providerConfig.APIKey = config.ApiKey
providerConfig.SecretKey = config.SecretKey
if config.DnsPropagationTimeout != 0 {
providerConfig.PropagationTimeout = time.Duration(config.DnsPropagationTimeout) * time.Second
}
if config.DnsTTL != 0 {
providerConfig.TTL = int(config.DnsTTL)
}
provider, err := constellix.NewDNSProviderConfig(providerConfig)
if err != nil {
return nil, err
}
return provider, nil
}

View File

@@ -0,0 +1,36 @@
package namedotcom
import (
"time"
"github.com/go-acme/lego/v4/challenge"
"github.com/go-acme/lego/v4/providers/dns/digitalocean"
)
type ChallengeProviderConfig struct {
AccessToken string `json:"accessToken"`
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 := digitalocean.NewDefaultConfig()
providerConfig.AuthToken = config.AccessToken
if config.DnsPropagationTimeout != 0 {
providerConfig.PropagationTimeout = time.Duration(config.DnsPropagationTimeout) * time.Second
}
if config.DnsTTL != 0 {
providerConfig.TTL = int(config.DnsTTL)
}
provider, err := digitalocean.NewDNSProviderConfig(providerConfig)
if err != nil {
return nil, err
}
return provider, nil
}

View File

@@ -1,4 +1,4 @@
package lego_dnsla
package internal
import (
"errors"

View File

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

View File

@@ -1,4 +1,4 @@
package lego_dynv6
package internal
import (
"context"

View File

@@ -1,4 +1,4 @@
package lego_gname
package internal
import (
"errors"

View File

@@ -0,0 +1,36 @@
package namedotcom
import (
"time"
"github.com/go-acme/lego/v4/challenge"
"github.com/go-acme/lego/v4/providers/dns/hetzner"
)
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 := hetzner.NewDefaultConfig()
providerConfig.APIKey = 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 := hetzner.NewDNSProviderConfig(providerConfig)
if err != nil {
return nil, err
}
return provider, nil
}

View File

@@ -1,4 +1,4 @@
package lego_jdcloud
package internal
import (
"errors"

View File

@@ -11,7 +11,7 @@ import (
)
type ChallengeProviderConfig struct {
ApiUrl string `json:"apiUrl"`
ServerUrl string `json:"serverUrl"`
ApiKey string `json:"apiKey"`
AllowInsecureConnections bool `json:"allowInsecureConnections,omitempty"`
DnsPropagationTimeout int32 `json:"dnsPropagationTimeout,omitempty"`
@@ -23,12 +23,13 @@ func NewChallengeProvider(config *ChallengeProviderConfig) (challenge.Provider,
panic("config is nil")
}
host, _ := url.Parse(config.ApiUrl)
serverUrl, _ := url.Parse(config.ServerUrl)
providerConfig := pdns.NewDefaultConfig()
providerConfig.Host = host
providerConfig.Host = serverUrl
providerConfig.APIKey = config.ApiKey
if config.AllowInsecureConnections {
providerConfig.HTTPClient.Transport = &http.Transport{
Proxy: http.ProxyFromEnvironment,
TLSClientConfig: &tls.Config{
InsecureSkipVerify: true,
},

View File

@@ -1,10 +1,9 @@
package lego_tencentcloudeo
package internal
import (
"errors"
"fmt"
"math"
"strings"
"time"
"github.com/go-acme/lego/v4/challenge"
@@ -91,7 +90,7 @@ func NewDNSProviderConfig(config *Config) (*DNSProvider, error) {
func (d *DNSProvider) Present(domain, token, keyAuth string) error {
info := dns01.GetChallengeInfo(domain, keyAuth)
if err := d.addOrUpdateDNSRecord(strings.TrimRight(info.EffectiveFQDN, "."), info.Value); err != nil {
if err := d.addOrUpdateDNSRecord(dns01.UnFqdn(info.EffectiveFQDN), info.Value); err != nil {
return fmt.Errorf("tencentcloud-eo: %w", err)
}
@@ -101,7 +100,7 @@ func (d *DNSProvider) Present(domain, token, keyAuth string) error {
func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error {
info := dns01.GetChallengeInfo(domain, keyAuth)
if err := d.removeDNSRecord(strings.TrimRight(info.EffectiveFQDN, ".")); err != nil {
if err := d.removeDNSRecord(dns01.UnFqdn(info.EffectiveFQDN)); err != nil {
return fmt.Errorf("tencentcloud-eo: %w", err)
}

View File

@@ -0,0 +1,165 @@
package internal
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"
"github.com/ucloud/ucloud-sdk-go/ucloud"
"github.com/ucloud/ucloud-sdk-go/ucloud/auth"
"github.com/usual2970/certimate/internal/pkg/sdk3rd/ucloud/udnr"
)
const (
envNamespace = "UCLOUDUDNR_"
EnvPublicKey = envNamespace + "PUBLIC_KEY"
EnvPrivateKey = envNamespace + "PRIVATE_KEY"
EnvTTL = envNamespace + "TTL"
EnvPropagationTimeout = envNamespace + "PROPAGATION_TIMEOUT"
EnvPollingInterval = envNamespace + "POLLING_INTERVAL"
EnvHTTPTimeout = envNamespace + "HTTP_TIMEOUT"
)
var _ challenge.ProviderTimeout = (*DNSProvider)(nil)
type Config struct {
PrivateKey string
PublicKey string
PropagationTimeout time.Duration
PollingInterval time.Duration
TTL int32
HTTPTimeout time.Duration
}
type DNSProvider struct {
client *udnr.UDNRClient
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(EnvPrivateKey, EnvPublicKey)
if err != nil {
return nil, fmt.Errorf("ucloud-udnr: %w", err)
}
config := NewDefaultConfig()
config.PrivateKey = values[EnvPrivateKey]
config.PublicKey = values[EnvPublicKey]
return NewDNSProviderConfig(config)
}
func NewDNSProviderConfig(config *Config) (*DNSProvider, error) {
if config == nil {
return nil, errors.New("ucloud-udnr: the configuration of the DNS provider is nil")
}
cfg := ucloud.NewConfig()
credential := auth.NewCredential()
credential.PrivateKey = config.PrivateKey
credential.PublicKey = config.PublicKey
client := udnr.NewClient(&cfg, &credential)
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("ucloud-udnr: could not find zone for domain %q: %w", domain, err)
}
subDomain, err := dns01.ExtractSubDomain(info.EffectiveFQDN, authZone)
if err != nil {
return fmt.Errorf("ucloud-udnr: %w", err)
}
udnrDomainDNSQueryReq := d.client.NewQueryDomainDNSRequest()
udnrDomainDNSQueryReq.Dn = ucloud.String(authZone)
if udnrDomainDNSQueryResp, err := d.client.QueryDomainDNS(udnrDomainDNSQueryReq); err != nil {
return fmt.Errorf("ucloud-udnr: %w", err)
} else {
for _, record := range udnrDomainDNSQueryResp.Data {
if record.DnsType == "TXT" && record.RecordName == subDomain {
udnrDomainDNSDeleteReq := d.client.NewDeleteDomainDNSRequest()
udnrDomainDNSDeleteReq.Dn = ucloud.String(authZone)
udnrDomainDNSDeleteReq.DnsType = ucloud.String(record.DnsType)
udnrDomainDNSDeleteReq.RecordName = ucloud.String(record.RecordName)
udnrDomainDNSDeleteReq.Content = ucloud.String(record.Content)
d.client.DeleteDomainDNS(udnrDomainDNSDeleteReq)
break
}
}
}
udnrDomainDNSAddReq := d.client.NewAddDomainDNSRequest()
udnrDomainDNSAddReq.Dn = ucloud.String(authZone)
udnrDomainDNSAddReq.DnsType = ucloud.String("TXT")
udnrDomainDNSAddReq.RecordName = ucloud.String(subDomain)
udnrDomainDNSAddReq.Content = ucloud.String(info.Value)
udnrDomainDNSAddReq.TTL = ucloud.Int(int(d.config.TTL))
if _, err := d.client.AddDomainDNS(udnrDomainDNSAddReq); err != nil {
return fmt.Errorf("ucloud-udnr: %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("ucloud-udnr: could not find zone for domain %q: %w", domain, err)
}
subDomain, err := dns01.ExtractSubDomain(info.EffectiveFQDN, authZone)
if err != nil {
return fmt.Errorf("ucloud-udnr: %w", err)
}
udnrDomainDNSQueryReq := d.client.NewQueryDomainDNSRequest()
udnrDomainDNSQueryReq.Dn = ucloud.String(authZone)
if udnrDomainDNSQueryResp, err := d.client.QueryDomainDNS(udnrDomainDNSQueryReq); err != nil {
return fmt.Errorf("ucloud-udnr: %w", err)
} else {
for _, record := range udnrDomainDNSQueryResp.Data {
if record.DnsType == "TXT" && record.RecordName == subDomain {
udnrDomainDNSDeleteReq := d.client.NewDeleteDomainDNSRequest()
udnrDomainDNSDeleteReq.Dn = ucloud.String(authZone)
udnrDomainDNSDeleteReq.DnsType = ucloud.String(record.DnsType)
udnrDomainDNSDeleteReq.RecordName = ucloud.String(record.RecordName)
udnrDomainDNSDeleteReq.Content = ucloud.String(record.Content)
d.client.DeleteDomainDNS(udnrDomainDNSDeleteReq)
break
}
}
}
return nil
}
func (d *DNSProvider) Timeout() (timeout, interval time.Duration) {
return d.config.PropagationTimeout, d.config.PollingInterval
}

View File

@@ -0,0 +1,40 @@
package ucloududnr
import (
"errors"
"time"
"github.com/go-acme/lego/v4/challenge"
"github.com/usual2970/certimate/internal/pkg/core/applicant/acme-dns-01/lego-providers/ucloud-udnr/internal"
)
type ChallengeProviderConfig struct {
PrivateKey string `json:"privateKey"`
PublicKey string `json:"publicKey"`
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.PrivateKey = config.PrivateKey
providerConfig.PublicKey = config.PublicKey
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

@@ -20,7 +20,7 @@ type Deployer interface {
// 出参:
// - res部署结果。
// - err: 错误。
Deploy(ctx context.Context, certPEM string, privkeyPEM string) (res *DeployResult, err error)
Deploy(ctx context.Context, certPEM string, privkeyPEM string) (_res *DeployResult, _err error)
}
// 表示证书部署结果的数据结构。

View File

@@ -13,8 +13,8 @@ import (
)
type DeployerConfig struct {
// 1Panel 地址。
ApiUrl string `json:"apiUrl"`
// 1Panel 服务地址。
ServerUrl string `json:"serverUrl"`
// 1Panel 版本。
// 可取值 "v1"、"v2"。
ApiVersion string `json:"apiVersion"`
@@ -39,7 +39,7 @@ func NewDeployer(config *DeployerConfig) (*DeployerProvider, error) {
panic("config is nil")
}
client, err := createSdkClient(config.ApiUrl, config.ApiVersion, config.ApiKey, config.AllowInsecureConnections)
client, err := createSdkClient(config.ServerUrl, config.ApiVersion, config.ApiKey, config.AllowInsecureConnections)
if err != nil {
return nil, fmt.Errorf("failed to create sdk client: %w", err)
}
@@ -53,7 +53,7 @@ func NewDeployer(config *DeployerConfig) (*DeployerProvider, error) {
func (d *DeployerProvider) WithLogger(logger *slog.Logger) deployer.Deployer {
if logger == nil {
d.logger = slog.Default()
d.logger = slog.New(slog.DiscardHandler)
} else {
d.logger = logger
}
@@ -82,9 +82,9 @@ func (d *DeployerProvider) Deploy(ctx context.Context, certPEM string, privkeyPE
return &deployer.DeployResult{}, nil
}
func createSdkClient(apiUrl, apiVersion, apiKey string, skipTlsVerify bool) (*onepanelsdk.Client, error) {
if _, err := url.Parse(apiUrl); err != nil {
return nil, errors.New("invalid 1panel api url")
func createSdkClient(serverUrl, apiVersion, apiKey string, skipTlsVerify bool) (*onepanelsdk.Client, error) {
if _, err := url.Parse(serverUrl); err != nil {
return nil, errors.New("invalid 1panel server url")
}
if apiVersion == "" {
@@ -95,7 +95,7 @@ func createSdkClient(apiUrl, apiVersion, apiKey string, skipTlsVerify bool) (*on
return nil, errors.New("invalid 1panel api key")
}
client := onepanelsdk.NewClient(apiUrl, apiVersion, apiKey)
client := onepanelsdk.NewClient(serverUrl, apiVersion, apiKey)
if skipTlsVerify {
client.WithTLSConfig(&tls.Config{InsecureSkipVerify: true})
}

View File

@@ -14,7 +14,7 @@ import (
var (
fInputCertPath string
fInputKeyPath string
fApiUrl string
fServerUrl string
fApiVersion string
fApiKey string
)
@@ -24,7 +24,7 @@ func init() {
flag.StringVar(&fInputCertPath, argsPrefix+"INPUTCERTPATH", "", "")
flag.StringVar(&fInputKeyPath, argsPrefix+"INPUTKEYPATH", "", "")
flag.StringVar(&fApiUrl, argsPrefix+"APIURL", "", "")
flag.StringVar(&fServerUrl, argsPrefix+"SERVERURL", "", "")
flag.StringVar(&fApiVersion, argsPrefix+"APIVERSION", "v1", "")
flag.StringVar(&fApiKey, argsPrefix+"APIKEY", "", "")
}
@@ -35,7 +35,7 @@ Shell command to run this test:
go test -v ./1panel_console_test.go -args \
--CERTIMATE_DEPLOYER_1PANELCONSOLE_INPUTCERTPATH="/path/to/your-input-cert.pem" \
--CERTIMATE_DEPLOYER_1PANELCONSOLE_INPUTKEYPATH="/path/to/your-input-key.pem" \
--CERTIMATE_DEPLOYER_1PANELCONSOLE_APIURL="http://127.0.0.1:20410" \
--CERTIMATE_DEPLOYER_1PANELCONSOLE_SERVERURL="http://127.0.0.1:20410" \
--CERTIMATE_DEPLOYER_1PANELCONSOLE_APIVERSION="v1" \
--CERTIMATE_DEPLOYER_1PANELCONSOLE_APIKEY="your-api-key"
*/
@@ -47,13 +47,13 @@ func TestDeploy(t *testing.T) {
"args:",
fmt.Sprintf("INPUTCERTPATH: %v", fInputCertPath),
fmt.Sprintf("INPUTKEYPATH: %v", fInputKeyPath),
fmt.Sprintf("APIURL: %v", fApiUrl),
fmt.Sprintf("SERVERURL: %v", fServerUrl),
fmt.Sprintf("APIVERSION: %v", fApiVersion),
fmt.Sprintf("APIKEY: %v", fApiKey),
}, "\n"))
deployer, err := provider.NewDeployer(&provider.DeployerConfig{
ApiUrl: fApiUrl,
ServerUrl: fServerUrl,
ApiVersion: fApiVersion,
ApiKey: fApiKey,
AllowInsecureConnections: true,

View File

@@ -16,8 +16,8 @@ import (
)
type DeployerConfig struct {
// 1Panel 地址。
ApiUrl string `json:"apiUrl"`
// 1Panel 服务地址。
ServerUrl string `json:"serverUrl"`
// 1Panel 版本。
// 可取值 "v1"、"v2"。
ApiVersion string `json:"apiVersion"`
@@ -49,15 +49,16 @@ func NewDeployer(config *DeployerConfig) (*DeployerProvider, error) {
panic("config is nil")
}
client, err := createSdkClient(config.ApiUrl, config.ApiVersion, config.ApiKey, config.AllowInsecureConnections)
client, err := createSdkClient(config.ServerUrl, config.ApiVersion, config.ApiKey, config.AllowInsecureConnections)
if err != nil {
return nil, fmt.Errorf("failed to create sdk client: %w", err)
}
uploader, err := uploadersp.NewUploader(&uploadersp.UploaderConfig{
ApiUrl: config.ApiUrl,
ApiVersion: config.ApiVersion,
ApiKey: config.ApiKey,
ServerUrl: config.ServerUrl,
ApiVersion: config.ApiVersion,
ApiKey: config.ApiKey,
AllowInsecureConnections: config.AllowInsecureConnections,
})
if err != nil {
return nil, fmt.Errorf("failed to create ssl uploader: %w", err)
@@ -73,7 +74,7 @@ func NewDeployer(config *DeployerConfig) (*DeployerProvider, error) {
func (d *DeployerProvider) WithLogger(logger *slog.Logger) deployer.Deployer {
if logger == nil {
d.logger = slog.Default()
d.logger = slog.New(slog.DiscardHandler)
} else {
d.logger = logger
}
@@ -177,9 +178,9 @@ func (d *DeployerProvider) deployToCertificate(ctx context.Context, certPEM stri
return nil
}
func createSdkClient(apiUrl, apiVersion, apiKey string, skipTlsVerify bool) (*onepanelsdk.Client, error) {
if _, err := url.Parse(apiUrl); err != nil {
return nil, errors.New("invalid 1panel api url")
func createSdkClient(serverUrl, apiVersion, apiKey string, skipTlsVerify bool) (*onepanelsdk.Client, error) {
if _, err := url.Parse(serverUrl); err != nil {
return nil, errors.New("invalid 1panel server url")
}
if apiVersion == "" {
@@ -190,7 +191,7 @@ func createSdkClient(apiUrl, apiVersion, apiKey string, skipTlsVerify bool) (*on
return nil, errors.New("invalid 1panel api key")
}
client := onepanelsdk.NewClient(apiUrl, apiVersion, apiKey)
client := onepanelsdk.NewClient(serverUrl, apiVersion, apiKey)
if skipTlsVerify {
client.WithTLSConfig(&tls.Config{InsecureSkipVerify: true})
}

View File

@@ -14,7 +14,7 @@ import (
var (
fInputCertPath string
fInputKeyPath string
fApiUrl string
fServerUrl string
fApiVersion string
fApiKey string
fWebsiteId int64
@@ -25,7 +25,7 @@ func init() {
flag.StringVar(&fInputCertPath, argsPrefix+"INPUTCERTPATH", "", "")
flag.StringVar(&fInputKeyPath, argsPrefix+"INPUTKEYPATH", "", "")
flag.StringVar(&fApiUrl, argsPrefix+"APIURL", "", "")
flag.StringVar(&fServerUrl, argsPrefix+"SERVERURL", "", "")
flag.StringVar(&fApiVersion, argsPrefix+"APIVERSION", "v1", "")
flag.StringVar(&fApiKey, argsPrefix+"APIKEY", "", "")
flag.Int64Var(&fWebsiteId, argsPrefix+"WEBSITEID", 0, "")
@@ -37,7 +37,7 @@ Shell command to run this test:
go test -v ./1panel_site_test.go -args \
--CERTIMATE_DEPLOYER_1PANELSITE_INPUTCERTPATH="/path/to/your-input-cert.pem" \
--CERTIMATE_DEPLOYER_1PANELSITE_INPUTKEYPATH="/path/to/your-input-key.pem" \
--CERTIMATE_DEPLOYER_1PANELSITE_APIURL="http://127.0.0.1:20410" \
--CERTIMATE_DEPLOYER_1PANELSITE_SERVERURL="http://127.0.0.1:20410" \
--CERTIMATE_DEPLOYER_1PANELSITE_APIVERSION="v1" \
--CERTIMATE_DEPLOYER_1PANELSITE_APIKEY="your-api-key" \
--CERTIMATE_DEPLOYER_1PANELSITE_WEBSITEID="your-website-id"
@@ -50,14 +50,14 @@ func TestDeploy(t *testing.T) {
"args:",
fmt.Sprintf("INPUTCERTPATH: %v", fInputCertPath),
fmt.Sprintf("INPUTKEYPATH: %v", fInputKeyPath),
fmt.Sprintf("APIURL: %v", fApiUrl),
fmt.Sprintf("SERVERURL: %v", fServerUrl),
fmt.Sprintf("APIVERSION: %v", fApiVersion),
fmt.Sprintf("APIKEY: %v", fApiKey),
fmt.Sprintf("WEBSITEID: %v", fWebsiteId),
}, "\n"))
deployer, err := provider.NewDeployer(&provider.DeployerConfig{
ApiUrl: fApiUrl,
ServerUrl: fServerUrl,
ApiVersion: fApiVersion,
ApiKey: fApiKey,
AllowInsecureConnections: true,

View File

@@ -25,6 +25,8 @@ type DeployerConfig struct {
AccessKeyId string `json:"accessKeyId"`
// 阿里云 AccessKeySecret。
AccessKeySecret string `json:"accessKeySecret"`
// 阿里云资源组 ID。
ResourceGroupId string `json:"resourceGroupId,omitempty"`
// 阿里云地域。
Region string `json:"region"`
// 部署资源类型。
@@ -64,7 +66,7 @@ func NewDeployer(config *DeployerConfig) (*DeployerProvider, error) {
return nil, fmt.Errorf("failed to create sdk clients: %w", err)
}
uploader, err := createSslUploader(config.AccessKeyId, config.AccessKeySecret, config.Region)
uploader, err := createSslUploader(config.AccessKeyId, config.AccessKeySecret, config.ResourceGroupId, config.Region)
if err != nil {
return nil, fmt.Errorf("failed to create ssl uploader: %w", err)
}
@@ -79,7 +81,7 @@ func NewDeployer(config *DeployerConfig) (*DeployerProvider, error) {
func (d *DeployerProvider) WithLogger(logger *slog.Logger) deployer.Deployer {
if logger == nil {
d.logger = slog.Default()
d.logger = slog.New(slog.DiscardHandler)
} else {
d.logger = logger
}
@@ -423,7 +425,7 @@ func createSdkClients(accessKeyId, accessKeySecret, region string) (*wSdkClients
// 接入点一览 https://api.aliyun.com/product/Alb
var albEndpoint string
switch region {
case "cn-hangzhou-finance":
case "", "cn-hangzhou-finance":
albEndpoint = "alb.cn-hangzhou.aliyuncs.com"
default:
albEndpoint = fmt.Sprintf("alb.%s.aliyuncs.com", region)
@@ -463,7 +465,7 @@ func createSdkClients(accessKeyId, accessKeySecret, region string) (*wSdkClients
}, nil
}
func createSslUploader(accessKeyId, accessKeySecret, region string) (uploader.Uploader, error) {
func createSslUploader(accessKeyId, accessKeySecret, resourceGroupId, region string) (uploader.Uploader, error) {
casRegion := region
if casRegion != "" {
// 阿里云 CAS 服务接入点是独立于 ALB 服务的
@@ -479,6 +481,7 @@ func createSslUploader(accessKeyId, accessKeySecret, region string) (uploader.Up
uploader, err := uploadersp.NewUploader(&uploadersp.UploaderConfig{
AccessKeyId: accessKeyId,
AccessKeySecret: accessKeySecret,
ResourceGroupId: resourceGroupId,
Region: casRegion,
})
return uploader, err

View File

@@ -16,6 +16,7 @@ import (
"github.com/usual2970/certimate/internal/pkg/core/deployer"
"github.com/usual2970/certimate/internal/pkg/core/uploader"
uploadersp "github.com/usual2970/certimate/internal/pkg/core/uploader/providers/aliyun-cas"
typeutil "github.com/usual2970/certimate/internal/pkg/utils/type"
)
type DeployerConfig struct {
@@ -23,6 +24,8 @@ type DeployerConfig struct {
AccessKeyId string `json:"accessKeyId"`
// 阿里云 AccessKeySecret。
AccessKeySecret string `json:"accessKeySecret"`
// 阿里云资源组 ID。
ResourceGroupId string `json:"resourceGroupId,omitempty"`
// 阿里云地域。
Region string `json:"region"`
// 服务类型。
@@ -61,7 +64,7 @@ func NewDeployer(config *DeployerConfig) (*DeployerProvider, error) {
return nil, fmt.Errorf("failed to create sdk clients: %w", err)
}
uploader, err := createSslUploader(config.AccessKeyId, config.AccessKeySecret, config.Region)
uploader, err := createSslUploader(config.AccessKeyId, config.AccessKeySecret, config.ResourceGroupId, config.Region)
if err != nil {
return nil, fmt.Errorf("failed to create ssl uploader: %w", err)
}
@@ -76,7 +79,7 @@ func NewDeployer(config *DeployerConfig) (*DeployerProvider, error) {
func (d *DeployerProvider) WithLogger(logger *slog.Logger) deployer.Deployer {
if logger == nil {
d.logger = slog.Default()
d.logger = slog.New(slog.DiscardHandler)
} else {
d.logger = logger
}
@@ -149,10 +152,11 @@ func (d *DeployerProvider) deployToCloudNative(ctx context.Context, certPEM stri
}
listDomainsReq := &aliapig.ListDomainsRequest{
GatewayId: tea.String(d.config.GatewayId),
NameLike: tea.String(d.config.Domain),
PageNumber: tea.Int32(listDomainsPageNumber),
PageSize: tea.Int32(listDomainsPageSize),
ResourceGroupId: typeutil.ToPtrOrZeroNil(d.config.ResourceGroupId),
GatewayId: tea.String(d.config.GatewayId),
NameLike: tea.String(d.config.Domain),
PageNumber: tea.Int32(listDomainsPageNumber),
PageSize: tea.Int32(listDomainsPageSize),
}
listDomainsResp, err := d.sdkClients.CloudNativeAPIGateway.ListDomains(listDomainsReq)
d.logger.Debug("sdk request 'apig.ListDomains'", slog.Any("request", listDomainsReq), slog.Any("response", listDomainsResp))
@@ -223,7 +227,7 @@ func (d *DeployerProvider) deployToCloudNative(ctx context.Context, certPEM stri
func createSdkClients(accessKeyId, accessKeySecret, region string) (*wSdkClients, error) {
// 接入点一览 https://api.aliyun.com/product/APIG
cloudNativeAPIGEndpoint := fmt.Sprintf("apig.%s.aliyuncs.com", region)
cloudNativeAPIGEndpoint := strings.ReplaceAll(fmt.Sprintf("apig.%s.aliyuncs.com", region), "..", ".")
cloudNativeAPIGConfig := &aliopen.Config{
AccessKeyId: tea.String(accessKeyId),
AccessKeySecret: tea.String(accessKeySecret),
@@ -235,7 +239,7 @@ func createSdkClients(accessKeyId, accessKeySecret, region string) (*wSdkClients
}
// 接入点一览 https://api.aliyun.com/product/CloudAPI
traditionalAPIGEndpoint := fmt.Sprintf("apigateway.%s.aliyuncs.com", region)
traditionalAPIGEndpoint := strings.ReplaceAll(fmt.Sprintf("apigateway.%s.aliyuncs.com", region), "..", ".")
traditionalAPIGConfig := &aliopen.Config{
AccessKeyId: tea.String(accessKeyId),
AccessKeySecret: tea.String(accessKeySecret),
@@ -252,7 +256,7 @@ func createSdkClients(accessKeyId, accessKeySecret, region string) (*wSdkClients
}, nil
}
func createSslUploader(accessKeyId, accessKeySecret, region string) (uploader.Uploader, error) {
func createSslUploader(accessKeyId, accessKeySecret, resourceGroupId, region string) (uploader.Uploader, error) {
casRegion := region
if casRegion != "" {
// 阿里云 CAS 服务接入点是独立于 APIGateway 服务的
@@ -268,6 +272,7 @@ func createSslUploader(accessKeyId, accessKeySecret, region string) (uploader.Up
uploader, err := uploadersp.NewUploader(&uploadersp.UploaderConfig{
AccessKeyId: accessKeyId,
AccessKeySecret: accessKeySecret,
ResourceGroupId: resourceGroupId,
Region: casRegion,
})
return uploader, err

View File

@@ -22,12 +22,14 @@ type DeployerConfig struct {
AccessKeyId string `json:"accessKeyId"`
// 阿里云 AccessKeySecret。
AccessKeySecret string `json:"accessKeySecret"`
// 阿里云资源组 ID。
ResourceGroupId string `json:"resourceGroupId,omitempty"`
// 阿里云地域。
Region string `json:"region"`
// 阿里云云产品资源 ID 数组。
ResourceIds []string `json:"resourceIds"`
// 阿里云云联系人 ID 数组。
// 零值时默认使用账号下第一个联系人。
// 零值时使用账号下第一个联系人。
ContactIds []string `json:"contactIds"`
}
@@ -50,11 +52,7 @@ func NewDeployer(config *DeployerConfig) (*DeployerProvider, error) {
return nil, fmt.Errorf("failed to create sdk client: %w", err)
}
uploader, err := uploadersp.NewUploader(&uploadersp.UploaderConfig{
AccessKeyId: config.AccessKeyId,
AccessKeySecret: config.AccessKeySecret,
Region: config.Region,
})
uploader, err := createSslUploader(config.AccessKeyId, config.AccessKeySecret, config.ResourceGroupId, config.Region)
if err != nil {
return nil, fmt.Errorf("failed to create ssl uploader: %w", err)
}
@@ -69,7 +67,7 @@ func NewDeployer(config *DeployerConfig) (*DeployerProvider, error) {
func (d *DeployerProvider) WithLogger(logger *slog.Logger) deployer.Deployer {
if logger == nil {
d.logger = slog.Default()
d.logger = slog.New(slog.DiscardHandler)
} else {
d.logger = logger
}
@@ -94,9 +92,10 @@ func (d *DeployerProvider) Deploy(ctx context.Context, certPEM string, privkeyPE
if len(contactIds) == 0 {
// 获取联系人列表
// REF: https://help.aliyun.com/zh/ssl-certificate/developer-reference/api-cas-2020-04-07-listcontact
listContactReq := &alicas.ListContactRequest{}
listContactReq.ShowSize = tea.Int32(1)
listContactReq.CurrentPage = tea.Int32(1)
listContactReq := &alicas.ListContactRequest{
ShowSize: tea.Int32(1),
CurrentPage: tea.Int32(1),
}
listContactResp, err := d.sdkClient.ListContact(listContactReq)
d.logger.Debug("sdk request 'cas.ListContact'", slog.Any("request", listContactReq), slog.Any("response", listContactResp))
if err != nil {
@@ -157,14 +156,10 @@ func (d *DeployerProvider) Deploy(ctx context.Context, certPEM string, privkeyPE
}
func createSdkClient(accessKeyId, accessKeySecret, region string) (*alicas.Client, error) {
if region == "" {
region = "cn-hangzhou" // CAS 服务默认区域:华东一杭州
}
// 接入点一览 https://api.aliyun.com/product/cas
var endpoint string
switch region {
case "cn-hangzhou":
case "", "cn-hangzhou":
endpoint = "cas.aliyuncs.com"
default:
endpoint = fmt.Sprintf("cas.%s.aliyuncs.com", region)
@@ -183,3 +178,25 @@ func createSdkClient(accessKeyId, accessKeySecret, region string) (*alicas.Clien
return client, nil
}
func createSslUploader(accessKeyId, accessKeySecret, resourceGroupId, region string) (uploader.Uploader, error) {
casRegion := region
if casRegion != "" {
// 阿里云 CAS 服务接入点是独立于其他服务的
// 国内版固定接入点:华东一杭州
// 国际版固定接入点:亚太东南一新加坡
if !strings.HasPrefix(casRegion, "cn-") {
casRegion = "ap-southeast-1"
} else {
casRegion = "cn-hangzhou"
}
}
uploader, err := uploadersp.NewUploader(&uploadersp.UploaderConfig{
AccessKeyId: accessKeyId,
AccessKeySecret: accessKeySecret,
ResourceGroupId: resourceGroupId,
Region: casRegion,
})
return uploader, err
}

View File

@@ -15,6 +15,8 @@ type DeployerConfig struct {
AccessKeyId string `json:"accessKeyId"`
// 阿里云 AccessKeySecret。
AccessKeySecret string `json:"accessKeySecret"`
// 阿里云资源组 ID。
ResourceGroupId string `json:"resourceGroupId,omitempty"`
// 阿里云地域。
Region string `json:"region"`
}
@@ -35,6 +37,7 @@ func NewDeployer(config *DeployerConfig) (*DeployerProvider, error) {
uploader, err := uploadersp.NewUploader(&uploadersp.UploaderConfig{
AccessKeyId: config.AccessKeyId,
AccessKeySecret: config.AccessKeySecret,
ResourceGroupId: config.ResourceGroupId,
Region: config.Region,
})
if err != nil {
@@ -50,7 +53,7 @@ func NewDeployer(config *DeployerConfig) (*DeployerProvider, error) {
func (d *DeployerProvider) WithLogger(logger *slog.Logger) deployer.Deployer {
if logger == nil {
d.logger = slog.Default()
d.logger = slog.New(slog.DiscardHandler)
} else {
d.logger = logger
}

View File

@@ -19,6 +19,8 @@ type DeployerConfig struct {
AccessKeyId string `json:"accessKeyId"`
// 阿里云 AccessKeySecret。
AccessKeySecret string `json:"accessKeySecret"`
// 阿里云资源组 ID。
ResourceGroupId string `json:"resourceGroupId,omitempty"`
// 加速域名(支持泛域名)。
Domain string `json:"domain"`
}
@@ -50,7 +52,7 @@ func NewDeployer(config *DeployerConfig) (*DeployerProvider, error) {
func (d *DeployerProvider) WithLogger(logger *slog.Logger) deployer.Deployer {
if logger == nil {
d.logger = slog.Default()
d.logger = slog.New(slog.DiscardHandler)
} else {
d.logger = logger
}

View File

@@ -20,6 +20,8 @@ type DeployerConfig struct {
AccessKeyId string `json:"accessKeyId"`
// 阿里云 AccessKeySecret。
AccessKeySecret string `json:"accessKeySecret"`
// 阿里云资源组 ID。
ResourceGroupId string `json:"resourceGroupId,omitempty"`
// 阿里云地域。
Region string `json:"region"`
// 部署资源类型。
@@ -54,7 +56,7 @@ func NewDeployer(config *DeployerConfig) (*DeployerProvider, error) {
return nil, fmt.Errorf("failed to create sdk client: %w", err)
}
uploader, err := createSslUploader(config.AccessKeyId, config.AccessKeySecret, config.Region)
uploader, err := createSslUploader(config.AccessKeyId, config.AccessKeySecret, config.ResourceGroupId, config.Region)
if err != nil {
return nil, fmt.Errorf("failed to create ssl uploader: %w", err)
}
@@ -69,7 +71,7 @@ func NewDeployer(config *DeployerConfig) (*DeployerProvider, error) {
func (d *DeployerProvider) WithLogger(logger *slog.Logger) deployer.Deployer {
if logger == nil {
d.logger = slog.Default()
d.logger = slog.New(slog.DiscardHandler)
} else {
d.logger = logger
}
@@ -283,7 +285,7 @@ func createSdkClient(accessKeyId, accessKeySecret, region string) (*alislb.Clien
// 接入点一览 https://api.aliyun.com/product/Slb
var endpoint string
switch region {
case
case "",
"cn-hangzhou",
"cn-hangzhou-finance",
"cn-shanghai-finance-1",
@@ -307,10 +309,11 @@ func createSdkClient(accessKeyId, accessKeySecret, region string) (*alislb.Clien
return client, nil
}
func createSslUploader(accessKeyId, accessKeySecret, region string) (uploader.Uploader, error) {
func createSslUploader(accessKeyId, accessKeySecret, resourceGroupId, region string) (uploader.Uploader, error) {
uploader, err := uploadersp.NewUploader(&uploadersp.UploaderConfig{
AccessKeyId: accessKeyId,
AccessKeySecret: accessKeySecret,
ResourceGroupId: resourceGroupId,
Region: region,
})
return uploader, err

View File

@@ -19,6 +19,8 @@ type DeployerConfig struct {
AccessKeyId string `json:"accessKeyId"`
// 阿里云 AccessKeySecret。
AccessKeySecret string `json:"accessKeySecret"`
// 阿里云资源组 ID。
ResourceGroupId string `json:"resourceGroupId,omitempty"`
// 加速域名(支持泛域名)。
Domain string `json:"domain"`
}
@@ -50,7 +52,7 @@ func NewDeployer(config *DeployerConfig) (*DeployerProvider, error) {
func (d *DeployerProvider) WithLogger(logger *slog.Logger) deployer.Deployer {
if logger == nil {
d.logger = slog.Default()
d.logger = slog.New(slog.DiscardHandler)
} else {
d.logger = logger
}

View File

@@ -22,6 +22,8 @@ type DeployerConfig struct {
AccessKeyId string `json:"accessKeyId"`
// 阿里云 AccessKeySecret。
AccessKeySecret string `json:"accessKeySecret"`
// 阿里云资源组 ID。
ResourceGroupId string `json:"resourceGroupId,omitempty"`
// 阿里云地域。
Region string `json:"region"`
// 网站域名(支持泛域名)。
@@ -47,7 +49,7 @@ func NewDeployer(config *DeployerConfig) (*DeployerProvider, error) {
return nil, fmt.Errorf("failed to create sdk client: %w", err)
}
uploader, err := createSslUploader(config.AccessKeyId, config.AccessKeySecret, config.Region)
uploader, err := createSslUploader(config.AccessKeyId, config.AccessKeySecret, config.ResourceGroupId, config.Region)
if err != nil {
return nil, fmt.Errorf("failed to create ssl uploader: %w", err)
}
@@ -62,7 +64,7 @@ func NewDeployer(config *DeployerConfig) (*DeployerProvider, error) {
func (d *DeployerProvider) WithLogger(logger *slog.Logger) deployer.Deployer {
if logger == nil {
d.logger = slog.Default()
d.logger = slog.New(slog.DiscardHandler)
} else {
d.logger = logger
}
@@ -104,7 +106,7 @@ func createSdkClient(accessKeyId, accessKeySecret, region string) (*aliddos.Clie
config := &aliopen.Config{
AccessKeyId: tea.String(accessKeyId),
AccessKeySecret: tea.String(accessKeySecret),
Endpoint: tea.String(fmt.Sprintf("ddoscoo.%s.aliyuncs.com", region)),
Endpoint: tea.String(strings.ReplaceAll(fmt.Sprintf("ddoscoo.%s.aliyuncs.com", region), "..", ".")),
}
client, err := aliddos.NewClient(config)
@@ -115,7 +117,7 @@ func createSdkClient(accessKeyId, accessKeySecret, region string) (*aliddos.Clie
return client, nil
}
func createSslUploader(accessKeyId, accessKeySecret, region string) (uploader.Uploader, error) {
func createSslUploader(accessKeyId, accessKeySecret, resourceGroupId, region string) (uploader.Uploader, error) {
casRegion := region
if casRegion != "" {
// 阿里云 CAS 服务接入点是独立于 Anti-DDoS 服务的
@@ -131,6 +133,7 @@ func createSslUploader(accessKeyId, accessKeySecret, region string) (uploader.Up
uploader, err := uploadersp.NewUploader(&uploadersp.UploaderConfig{
AccessKeyId: accessKeyId,
AccessKeySecret: accessKeySecret,
ResourceGroupId: resourceGroupId,
Region: casRegion,
})
return uploader, err

View File

@@ -22,6 +22,8 @@ type DeployerConfig struct {
AccessKeyId string `json:"accessKeyId"`
// 阿里云 AccessKeySecret。
AccessKeySecret string `json:"accessKeySecret"`
// 阿里云资源组 ID。
ResourceGroupId string `json:"resourceGroupId,omitempty"`
// 阿里云地域。
Region string `json:"region"`
// 阿里云 ESA 站点 ID。
@@ -47,7 +49,7 @@ func NewDeployer(config *DeployerConfig) (*DeployerProvider, error) {
return nil, fmt.Errorf("failed to create sdk client: %w", err)
}
uploader, err := createSslUploader(config.AccessKeyId, config.AccessKeySecret, config.Region)
uploader, err := createSslUploader(config.AccessKeyId, config.AccessKeySecret, config.ResourceGroupId, config.Region)
if err != nil {
return nil, fmt.Errorf("failed to create ssl uploader: %w", err)
}
@@ -62,7 +64,7 @@ func NewDeployer(config *DeployerConfig) (*DeployerProvider, error) {
func (d *DeployerProvider) WithLogger(logger *slog.Logger) deployer.Deployer {
if logger == nil {
d.logger = slog.Default()
d.logger = slog.New(slog.DiscardHandler)
} else {
d.logger = logger
}
@@ -105,7 +107,7 @@ func createSdkClient(accessKeyId, accessKeySecret, region string) (*aliesa.Clien
config := &aliopen.Config{
AccessKeyId: tea.String(accessKeyId),
AccessKeySecret: tea.String(accessKeySecret),
Endpoint: tea.String(fmt.Sprintf("esa.%s.aliyuncs.com", region)),
Endpoint: tea.String(strings.ReplaceAll(fmt.Sprintf("esa.%s.aliyuncs.com", region), "..", ".")),
}
client, err := aliesa.NewClient(config)
@@ -116,7 +118,7 @@ func createSdkClient(accessKeyId, accessKeySecret, region string) (*aliesa.Clien
return client, nil
}
func createSslUploader(accessKeyId, accessKeySecret, region string) (uploader.Uploader, error) {
func createSslUploader(accessKeyId, accessKeySecret, resourceGroupId, region string) (uploader.Uploader, error) {
casRegion := region
if casRegion != "" {
// 阿里云 CAS 服务接入点是独立于 ESA 服务的
@@ -132,6 +134,7 @@ func createSslUploader(accessKeyId, accessKeySecret, region string) (uploader.Up
uploader, err := uploadersp.NewUploader(&uploadersp.UploaderConfig{
AccessKeyId: accessKeyId,
AccessKeySecret: accessKeySecret,
ResourceGroupId: resourceGroupId,
Region: casRegion,
})
return uploader, err

View File

@@ -4,6 +4,7 @@ import (
"context"
"fmt"
"log/slog"
"strings"
"time"
aliopen "github.com/alibabacloud-go/darabonba-openapi/v2/client"
@@ -19,6 +20,8 @@ type DeployerConfig struct {
AccessKeyId string `json:"accessKeyId"`
// 阿里云 AccessKeySecret。
AccessKeySecret string `json:"accessKeySecret"`
// 阿里云资源组 ID。
ResourceGroupId string `json:"resourceGroupId,omitempty"`
// 阿里云地域。
Region string `json:"region"`
// 服务版本。
@@ -60,7 +63,7 @@ func NewDeployer(config *DeployerConfig) (*DeployerProvider, error) {
func (d *DeployerProvider) WithLogger(logger *slog.Logger) deployer.Deployer {
if logger == nil {
d.logger = slog.Default()
d.logger = slog.New(slog.DiscardHandler)
} else {
d.logger = logger
}
@@ -108,6 +111,9 @@ func (d *DeployerProvider) deployToFC3(ctx context.Context, certPEM string, priv
TlsConfig: getCustomDomainResp.Body.TlsConfig,
},
}
if tea.StringValue(updateCustomDomainReq.Body.Protocol) == "HTTP" {
updateCustomDomainReq.Body.Protocol = tea.String("HTTP,HTTPS")
}
updateCustomDomainResp, err := d.sdkClients.FC3.UpdateCustomDomain(tea.String(d.config.Domain), updateCustomDomainReq)
d.logger.Debug("sdk request 'fc.UpdateCustomDomain'", slog.Any("request", updateCustomDomainReq), slog.Any("response", updateCustomDomainResp))
if err != nil {
@@ -137,6 +143,9 @@ func (d *DeployerProvider) deployToFC2(ctx context.Context, certPEM string, priv
Protocol: getCustomDomainResp.Body.Protocol,
TlsConfig: getCustomDomainResp.Body.TlsConfig,
}
if tea.StringValue(updateCustomDomainReq.Protocol) == "HTTP" {
updateCustomDomainReq.Protocol = tea.String("HTTP,HTTPS")
}
updateCustomDomainResp, err := d.sdkClients.FC2.UpdateCustomDomain(tea.String(d.config.Domain), updateCustomDomainReq)
d.logger.Debug("sdk request 'fc.UpdateCustomDomain'", slog.Any("request", updateCustomDomainReq), slog.Any("response", updateCustomDomainResp))
if err != nil {
@@ -150,6 +159,8 @@ func createSdkClients(accessKeyId, accessKeySecret, region string) (*wSdkClients
// 接入点一览 https://api.aliyun.com/product/FC-Open
var fc2Endpoint string
switch region {
case "":
fc2Endpoint = "fc.aliyuncs.com"
case "cn-hangzhou-finance":
fc2Endpoint = fmt.Sprintf("%s.fc.aliyuncs.com", region)
default:
@@ -167,7 +178,7 @@ func createSdkClients(accessKeyId, accessKeySecret, region string) (*wSdkClients
}
// 接入点一览 https://api.aliyun.com/product/FC-Open
fc3Endpoint := fmt.Sprintf("fcv3.%s.aliyuncs.com", region)
fc3Endpoint := strings.ReplaceAll(fmt.Sprintf("fcv3.%s.aliyuncs.com", region), "..", ".")
fc3Config := &aliopen.Config{
AccessKeyId: tea.String(accessKeyId),
AccessKeySecret: tea.String(accessKeySecret),

View File

@@ -22,6 +22,8 @@ type DeployerConfig struct {
AccessKeyId string `json:"accessKeyId"`
// 阿里云 AccessKeySecret。
AccessKeySecret string `json:"accessKeySecret"`
// 阿里云资源组 ID。
ResourceGroupId string `json:"resourceGroupId,omitempty"`
// 部署资源类型。
ResourceType ResourceType `json:"resourceType"`
// 全球加速实例 ID。
@@ -53,7 +55,7 @@ func NewDeployer(config *DeployerConfig) (*DeployerProvider, error) {
return nil, fmt.Errorf("failed to create sdk client: %w", err)
}
uploader, err := createSslUploader(config.AccessKeyId, config.AccessKeySecret)
uploader, err := createSslUploader(config.AccessKeyId, config.AccessKeySecret, config.ResourceGroupId)
if err != nil {
return nil, fmt.Errorf("failed to create ssl uploader: %w", err)
}
@@ -68,7 +70,7 @@ func NewDeployer(config *DeployerConfig) (*DeployerProvider, error) {
func (d *DeployerProvider) WithLogger(logger *slog.Logger) deployer.Deployer {
if logger == nil {
d.logger = slog.Default()
d.logger = slog.New(slog.DiscardHandler)
} else {
d.logger = logger
}
@@ -312,10 +314,11 @@ func createSdkClient(accessKeyId, accessKeySecret string) (*aliga.Client, error)
return client, nil
}
func createSslUploader(accessKeyId, accessKeySecret string) (uploader.Uploader, error) {
func createSslUploader(accessKeyId, accessKeySecret, resourceGroupId string) (uploader.Uploader, error) {
uploader, err := uploadersp.NewUploader(&uploadersp.UploaderConfig{
AccessKeyId: accessKeyId,
AccessKeySecret: accessKeySecret,
ResourceGroupId: resourceGroupId,
Region: "cn-hangzhou",
})
return uploader, err

View File

@@ -19,6 +19,8 @@ type DeployerConfig struct {
AccessKeyId string `json:"accessKeyId"`
// 阿里云 AccessKeySecret。
AccessKeySecret string `json:"accessKeySecret"`
// 阿里云资源组 ID。
ResourceGroupId string `json:"resourceGroupId,omitempty"`
// 阿里云地域。
Region string `json:"region"`
// 直播流域名(支持泛域名)。
@@ -52,7 +54,7 @@ func NewDeployer(config *DeployerConfig) (*DeployerProvider, error) {
func (d *DeployerProvider) WithLogger(logger *slog.Logger) deployer.Deployer {
if logger == nil {
d.logger = slog.Default()
d.logger = slog.New(slog.DiscardHandler)
} else {
d.logger = logger
}
@@ -86,7 +88,7 @@ func createSdkClient(accessKeyId, accessKeySecret, region string) (*alilive.Clie
// 接入点一览 https://api.aliyun.com/product/live
var endpoint string
switch region {
case
case "",
"cn-qingdao",
"cn-beijing",
"cn-shanghai",

View File

@@ -21,6 +21,8 @@ type DeployerConfig struct {
AccessKeyId string `json:"accessKeyId"`
// 阿里云 AccessKeySecret。
AccessKeySecret string `json:"accessKeySecret"`
// 阿里云资源组 ID。
ResourceGroupId string `json:"resourceGroupId,omitempty"`
// 阿里云地域。
Region string `json:"region"`
// 部署资源类型。
@@ -52,7 +54,7 @@ func NewDeployer(config *DeployerConfig) (*DeployerProvider, error) {
return nil, fmt.Errorf("failed to create sdk client: %w", err)
}
uploader, err := createSslUploader(config.AccessKeyId, config.AccessKeySecret, config.Region)
uploader, err := createSslUploader(config.AccessKeyId, config.AccessKeySecret, config.ResourceGroupId, config.Region)
if err != nil {
return nil, fmt.Errorf("failed to create ssl uploader: %w", err)
}
@@ -67,7 +69,7 @@ func NewDeployer(config *DeployerConfig) (*DeployerProvider, error) {
func (d *DeployerProvider) WithLogger(logger *slog.Logger) deployer.Deployer {
if logger == nil {
d.logger = slog.Default()
d.logger = slog.New(slog.DiscardHandler)
} else {
d.logger = logger
}
@@ -224,12 +226,7 @@ func (d *DeployerProvider) updateListenerCertificate(ctx context.Context, cloudL
func createSdkClient(accessKeyId, accessKeySecret, region string) (*alinlb.Client, error) {
// 接入点一览 https://api.aliyun.com/product/Nlb
var endpoint string
switch region {
default:
endpoint = fmt.Sprintf("nlb.%s.aliyuncs.com", region)
}
endpoint := strings.ReplaceAll(fmt.Sprintf("nlb.%s.aliyuncs.com", region), "..", ".")
config := &aliopen.Config{
AccessKeyId: tea.String(accessKeyId),
AccessKeySecret: tea.String(accessKeySecret),
@@ -244,7 +241,7 @@ func createSdkClient(accessKeyId, accessKeySecret, region string) (*alinlb.Clien
return client, nil
}
func createSslUploader(accessKeyId, accessKeySecret, region string) (uploader.Uploader, error) {
func createSslUploader(accessKeyId, accessKeySecret, resourceGroupId, region string) (uploader.Uploader, error) {
casRegion := region
if casRegion != "" {
// 阿里云 CAS 服务接入点是独立于 NLB 服务的
@@ -260,6 +257,7 @@ func createSslUploader(accessKeyId, accessKeySecret, region string) (uploader.Up
uploader, err := uploadersp.NewUploader(&uploadersp.UploaderConfig{
AccessKeyId: accessKeyId,
AccessKeySecret: accessKeySecret,
ResourceGroupId: resourceGroupId,
Region: casRegion,
})
return uploader, err

View File

@@ -16,6 +16,8 @@ type DeployerConfig struct {
AccessKeyId string `json:"accessKeyId"`
// 阿里云 AccessKeySecret。
AccessKeySecret string `json:"accessKeySecret"`
// 阿里云资源组 ID。
ResourceGroupId string `json:"resourceGroupId,omitempty"`
// 阿里云地域。
Region string `json:"region"`
// 存储桶名。
@@ -51,7 +53,7 @@ func NewDeployer(config *DeployerConfig) (*DeployerProvider, error) {
func (d *DeployerProvider) WithLogger(logger *slog.Logger) deployer.Deployer {
if logger == nil {
d.logger = slog.Default()
d.logger = slog.New(slog.DiscardHandler)
} else {
d.logger = logger
}

View File

@@ -4,6 +4,7 @@ import (
"context"
"fmt"
"log/slog"
"strings"
"time"
aliopen "github.com/alibabacloud-go/darabonba-openapi/v2/client"
@@ -18,6 +19,8 @@ type DeployerConfig struct {
AccessKeyId string `json:"accessKeyId"`
// 阿里云 AccessKeySecret。
AccessKeySecret string `json:"accessKeySecret"`
// 阿里云资源组 ID。
ResourceGroupId string `json:"resourceGroupId,omitempty"`
// 阿里云地域。
Region string `json:"region"`
// 点播加速域名(不支持泛域名)。
@@ -51,7 +54,7 @@ func NewDeployer(config *DeployerConfig) (*DeployerProvider, error) {
func (d *DeployerProvider) WithLogger(logger *slog.Logger) deployer.Deployer {
if logger == nil {
d.logger = slog.Default()
d.logger = slog.New(slog.DiscardHandler)
} else {
d.logger = logger
}
@@ -80,8 +83,7 @@ func (d *DeployerProvider) Deploy(ctx context.Context, certPEM string, privkeyPE
func createSdkClient(accessKeyId, accessKeySecret, region string) (*alivod.Client, error) {
// 接入点一览 https://api.aliyun.com/product/vod
endpoint := fmt.Sprintf("vod.%s.aliyuncs.com", region)
endpoint := strings.ReplaceAll(fmt.Sprintf("vod.%s.aliyuncs.com", region), "..", ".")
config := &aliopen.Config{
AccessKeyId: tea.String(accessKeyId),
AccessKeySecret: tea.String(accessKeySecret),

View File

@@ -15,6 +15,7 @@ import (
"github.com/usual2970/certimate/internal/pkg/core/uploader"
uploadersp "github.com/usual2970/certimate/internal/pkg/core/uploader/providers/aliyun-cas"
sliceutil "github.com/usual2970/certimate/internal/pkg/utils/slice"
typeutil "github.com/usual2970/certimate/internal/pkg/utils/type"
)
type DeployerConfig struct {
@@ -22,6 +23,8 @@ type DeployerConfig struct {
AccessKeyId string `json:"accessKeyId"`
// 阿里云 AccessKeySecret。
AccessKeySecret string `json:"accessKeySecret"`
// 阿里云资源组 ID。
ResourceGroupId string `json:"resourceGroupId,omitempty"`
// 阿里云地域。
Region string `json:"region"`
// 服务版本。
@@ -51,7 +54,7 @@ func NewDeployer(config *DeployerConfig) (*DeployerProvider, error) {
return nil, fmt.Errorf("failed to create sdk client: %w", err)
}
uploader, err := createSslUploader(config.AccessKeyId, config.AccessKeySecret, config.Region)
uploader, err := createSslUploader(config.AccessKeyId, config.AccessKeySecret, config.ResourceGroupId, config.Region)
if err != nil {
return nil, fmt.Errorf("failed to create ssl uploader: %w", err)
}
@@ -66,7 +69,7 @@ func NewDeployer(config *DeployerConfig) (*DeployerProvider, error) {
func (d *DeployerProvider) WithLogger(logger *slog.Logger) deployer.Deployer {
if logger == nil {
d.logger = slog.Default()
d.logger = slog.New(slog.DiscardHandler)
} else {
d.logger = logger
}
@@ -107,8 +110,9 @@ func (d *DeployerProvider) deployToWAF3(ctx context.Context, certPEM string, pri
// 查询默认 SSL/TLS 设置
// REF: https://help.aliyun.com/zh/waf/web-application-firewall-3-0/developer-reference/api-waf-openapi-2021-10-01-describedefaulthttps
describeDefaultHttpsReq := &aliwaf.DescribeDefaultHttpsRequest{
InstanceId: tea.String(d.config.InstanceId),
RegionId: tea.String(d.config.Region),
ResourceManagerResourceGroupId: typeutil.ToPtrOrZeroNil(d.config.ResourceGroupId),
InstanceId: tea.String(d.config.InstanceId),
RegionId: tea.String(d.config.Region),
}
describeDefaultHttpsResp, err := d.sdkClient.DescribeDefaultHttps(describeDefaultHttpsReq)
d.logger.Debug("sdk request 'waf.DescribeDefaultHttps'", slog.Any("request", describeDefaultHttpsReq), slog.Any("response", describeDefaultHttpsResp))
@@ -119,11 +123,12 @@ func (d *DeployerProvider) deployToWAF3(ctx context.Context, certPEM string, pri
// 修改默认 SSL/TLS 设置
// REF: https://help.aliyun.com/zh/waf/web-application-firewall-3-0/developer-reference/api-waf-openapi-2021-10-01-modifydefaulthttps
modifyDefaultHttpsReq := &aliwaf.ModifyDefaultHttpsRequest{
InstanceId: tea.String(d.config.InstanceId),
RegionId: tea.String(d.config.Region),
CertId: tea.String(upres.CertId),
TLSVersion: tea.String("tlsv1"),
EnableTLSv3: tea.Bool(false),
ResourceManagerResourceGroupId: typeutil.ToPtrOrZeroNil(d.config.ResourceGroupId),
InstanceId: tea.String(d.config.InstanceId),
RegionId: tea.String(d.config.Region),
CertId: tea.String(upres.CertId),
TLSVersion: tea.String("tlsv1"),
EnableTLSv3: tea.Bool(false),
}
if describeDefaultHttpsResp.Body != nil && describeDefaultHttpsResp.Body.DefaultHttps != nil {
modifyDefaultHttpsReq.TLSVersion = describeDefaultHttpsResp.Body.DefaultHttps.TLSVersion
@@ -172,10 +177,11 @@ func (d *DeployerProvider) deployToWAF3(ctx context.Context, certPEM string, pri
func createSdkClient(accessKeyId, accessKeySecret, region string) (*aliwaf.Client, error) {
// 接入点一览https://api.aliyun.com/product/waf-openapi
endpoint := strings.ReplaceAll(fmt.Sprintf("wafopenapi.%s.aliyuncs.com", region), "..", ".")
config := &aliopen.Config{
AccessKeyId: tea.String(accessKeyId),
AccessKeySecret: tea.String(accessKeySecret),
Endpoint: tea.String(fmt.Sprintf("wafopenapi.%s.aliyuncs.com", region)),
Endpoint: tea.String(endpoint),
}
client, err := aliwaf.NewClient(config)
@@ -186,7 +192,7 @@ func createSdkClient(accessKeyId, accessKeySecret, region string) (*aliwaf.Clien
return client, nil
}
func createSslUploader(accessKeyId, accessKeySecret, region string) (uploader.Uploader, error) {
func createSslUploader(accessKeyId, accessKeySecret, resourceGroupId, region string) (uploader.Uploader, error) {
casRegion := region
if casRegion != "" {
// 阿里云 CAS 服务接入点是独立于 WAF 服务的
@@ -202,6 +208,7 @@ func createSslUploader(accessKeyId, accessKeySecret, region string) (uploader.Up
uploader, err := uploadersp.NewUploader(&uploadersp.UploaderConfig{
AccessKeyId: accessKeyId,
AccessKeySecret: accessKeySecret,
ResourceGroupId: resourceGroupId,
Region: casRegion,
})
return uploader, err

View File

@@ -66,7 +66,7 @@ func NewDeployer(config *DeployerConfig) (*DeployerProvider, error) {
func (d *DeployerProvider) WithLogger(logger *slog.Logger) deployer.Deployer {
if logger == nil {
d.logger = slog.Default()
d.logger = slog.New(slog.DiscardHandler)
} else {
d.logger = logger
}

View File

@@ -14,7 +14,8 @@ import (
"github.com/usual2970/certimate/internal/pkg/core/deployer"
"github.com/usual2970/certimate/internal/pkg/core/uploader"
uploadersp "github.com/usual2970/certimate/internal/pkg/core/uploader/providers/aws-acm"
uploaderspacm "github.com/usual2970/certimate/internal/pkg/core/uploader/providers/aws-acm"
uploaderspiam "github.com/usual2970/certimate/internal/pkg/core/uploader/providers/aws-iam"
)
type DeployerConfig struct {
@@ -26,6 +27,9 @@ type DeployerConfig struct {
Region string `json:"region"`
// AWS CloudFront 分配 ID。
DistributionId string `json:"distributionId"`
// AWS CloudFront 证书来源。
// 可取值 "ACM"、"IAM"。
CertificateSource string `json:"certificateSource"`
}
type DeployerProvider struct {
@@ -47,13 +51,28 @@ func NewDeployer(config *DeployerConfig) (*DeployerProvider, error) {
return nil, fmt.Errorf("failed to create sdk client: %w", err)
}
uploader, err := uploadersp.NewUploader(&uploadersp.UploaderConfig{
AccessKeyId: config.AccessKeyId,
SecretAccessKey: config.SecretAccessKey,
Region: config.Region,
})
if err != nil {
return nil, fmt.Errorf("failed to create ssl uploader: %w", err)
var uploader uploader.Uploader
if config.CertificateSource == "ACM" {
uploader, err = uploaderspacm.NewUploader(&uploaderspacm.UploaderConfig{
AccessKeyId: config.AccessKeyId,
SecretAccessKey: config.SecretAccessKey,
Region: config.Region,
})
if err != nil {
return nil, fmt.Errorf("failed to create ssl uploader: %w", err)
}
} else if config.CertificateSource == "IAM" {
uploader, err = uploaderspiam.NewUploader(&uploaderspiam.UploaderConfig{
AccessKeyId: config.AccessKeyId,
SecretAccessKey: config.SecretAccessKey,
Region: config.Region,
CertificatePath: "/cloudfront/",
})
if err != nil {
return nil, fmt.Errorf("failed to create ssl uploader: %w", err)
}
} else {
return nil, fmt.Errorf("unsupported certificate source: '%s'", config.CertificateSource)
}
return &DeployerProvider{
@@ -66,7 +85,7 @@ func NewDeployer(config *DeployerConfig) (*DeployerProvider, error) {
func (d *DeployerProvider) WithLogger(logger *slog.Logger) deployer.Deployer {
if logger == nil {
d.logger = slog.Default()
d.logger = slog.New(slog.DiscardHandler)
} else {
d.logger = logger
}
@@ -79,7 +98,7 @@ func (d *DeployerProvider) Deploy(ctx context.Context, certPEM string, privkeyPE
return nil, errors.New("config `distribuitionId` is required")
}
// 上传证书到 ACM
// 上传证书到 ACM/IAM
upres, err := d.sslUploader.Upload(ctx, certPEM, privkeyPEM)
if err != nil {
return nil, fmt.Errorf("failed to upload certificate file: %w", err)
@@ -109,7 +128,19 @@ func (d *DeployerProvider) Deploy(ctx context.Context, certPEM string, privkeyPE
updateDistributionReq.DistributionConfig.ViewerCertificate = &types.ViewerCertificate{}
}
updateDistributionReq.DistributionConfig.ViewerCertificate.CloudFrontDefaultCertificate = aws.Bool(false)
updateDistributionReq.DistributionConfig.ViewerCertificate.ACMCertificateArn = aws.String(upres.CertId)
if d.config.CertificateSource == "ACM" {
updateDistributionReq.DistributionConfig.ViewerCertificate.ACMCertificateArn = aws.String(upres.CertId)
updateDistributionReq.DistributionConfig.ViewerCertificate.IAMCertificateId = nil
} else if d.config.CertificateSource == "IAM" {
updateDistributionReq.DistributionConfig.ViewerCertificate.ACMCertificateArn = nil
updateDistributionReq.DistributionConfig.ViewerCertificate.IAMCertificateId = aws.String(upres.CertId)
if updateDistributionReq.DistributionConfig.ViewerCertificate.MinimumProtocolVersion == "" {
updateDistributionReq.DistributionConfig.ViewerCertificate.MinimumProtocolVersion = types.MinimumProtocolVersionTLSv1
}
if updateDistributionReq.DistributionConfig.ViewerCertificate.SSLSupportMethod == "" {
updateDistributionReq.DistributionConfig.ViewerCertificate.SSLSupportMethod = types.SSLSupportMethodSniOnly
}
}
updateDistributionResp, err := d.sdkClient.UpdateDistribution(context.TODO(), updateDistributionReq)
d.logger.Debug("sdk request 'cloudfront.UpdateDistribution'", slog.Any("request", updateDistributionReq), slog.Any("response", updateDistributionResp))
if err != nil {

View File

@@ -0,0 +1,75 @@
package awsiam
import (
"context"
"fmt"
"log/slog"
"github.com/usual2970/certimate/internal/pkg/core/deployer"
"github.com/usual2970/certimate/internal/pkg/core/uploader"
uploadersp "github.com/usual2970/certimate/internal/pkg/core/uploader/providers/aws-iam"
)
type DeployerConfig struct {
// AWS AccessKeyId。
AccessKeyId string `json:"accessKeyId"`
// AWS SecretAccessKey。
SecretAccessKey string `json:"secretAccessKey"`
// AWS 区域。
Region string `json:"region"`
// IAM 证书路径。
// 选填。
CertificatePath string `json:"certificatePath,omitempty"`
}
type DeployerProvider struct {
config *DeployerConfig
logger *slog.Logger
sslUploader uploader.Uploader
}
var _ deployer.Deployer = (*DeployerProvider)(nil)
func NewDeployer(config *DeployerConfig) (*DeployerProvider, error) {
if config == nil {
panic("config is nil")
}
uploader, err := uploadersp.NewUploader(&uploadersp.UploaderConfig{
AccessKeyId: config.AccessKeyId,
SecretAccessKey: config.SecretAccessKey,
Region: config.Region,
CertificatePath: config.CertificatePath,
})
if err != nil {
return nil, fmt.Errorf("failed to create ssl uploader: %w", err)
}
return &DeployerProvider{
config: config,
logger: slog.Default(),
sslUploader: uploader,
}, nil
}
func (d *DeployerProvider) WithLogger(logger *slog.Logger) deployer.Deployer {
if logger == nil {
d.logger = slog.New(slog.DiscardHandler)
} else {
d.logger = logger
}
d.sslUploader.WithLogger(logger)
return d
}
func (d *DeployerProvider) Deploy(ctx context.Context, certPEM string, privkeyPEM string) (*deployer.DeployResult, error) {
// 上传证书到 IAM
upres, err := d.sslUploader.Upload(ctx, certPEM, privkeyPEM)
if err != nil {
return nil, fmt.Errorf("failed to upload certificate file: %w", err)
} else {
d.logger.Info("ssl certificate uploaded", slog.Any("result", upres))
}
return &deployer.DeployResult{}, nil
}

View File

@@ -76,7 +76,7 @@ func NewDeployer(config *DeployerConfig) (*DeployerProvider, error) {
func (d *DeployerProvider) WithLogger(logger *slog.Logger) deployer.Deployer {
if logger == nil {
d.logger = slog.Default()
d.logger = slog.New(slog.DiscardHandler)
} else {
d.logger = logger
}

View File

@@ -74,7 +74,7 @@ func NewDeployer(config *DeployerConfig) (*DeployerProvider, error) {
func (d *DeployerProvider) WithLogger(logger *slog.Logger) deployer.Deployer {
if logger == nil {
d.logger = slog.Default()
d.logger = slog.New(slog.DiscardHandler)
} else {
d.logger = logger
}

View File

@@ -74,7 +74,7 @@ func NewDeployer(config *DeployerConfig) (*DeployerProvider, error) {
func (d *DeployerProvider) WithLogger(logger *slog.Logger) deployer.Deployer {
if logger == nil {
d.logger = slog.Default()
d.logger = slog.New(slog.DiscardHandler)
} else {
d.logger = logger
}

View File

@@ -48,7 +48,7 @@ func NewDeployer(config *DeployerConfig) (*DeployerProvider, error) {
func (d *DeployerProvider) WithLogger(logger *slog.Logger) deployer.Deployer {
if logger == nil {
d.logger = slog.Default()
d.logger = slog.New(slog.DiscardHandler)
} else {
d.logger = logger
}

View File

@@ -47,7 +47,7 @@ func NewDeployer(config *DeployerConfig) (*DeployerProvider, error) {
func (d *DeployerProvider) WithLogger(logger *slog.Logger) deployer.Deployer {
if logger == nil {
d.logger = slog.Default()
d.logger = slog.New(slog.DiscardHandler)
} else {
d.logger = logger
}

View File

@@ -51,7 +51,7 @@ func NewDeployer(config *DeployerConfig) (*DeployerProvider, error) {
func (d *DeployerProvider) WithLogger(logger *slog.Logger) deployer.Deployer {
if logger == nil {
d.logger = slog.Default()
d.logger = slog.New(slog.DiscardHandler)
} else {
d.logger = logger
}

View File

@@ -13,8 +13,8 @@ import (
)
type DeployerConfig struct {
// 宝塔面板地址。
ApiUrl string `json:"apiUrl"`
// 宝塔面板服务地址。
ServerUrl string `json:"serverUrl"`
// 宝塔面板接口密钥。
ApiKey string `json:"apiKey"`
// 是否允许不安全的连接。
@@ -36,7 +36,7 @@ func NewDeployer(config *DeployerConfig) (*DeployerProvider, error) {
panic("config is nil")
}
client, err := createSdkClient(config.ApiUrl, config.ApiKey, config.AllowInsecureConnections)
client, err := createSdkClient(config.ServerUrl, config.ApiKey, config.AllowInsecureConnections)
if err != nil {
return nil, fmt.Errorf("failed to create sdk client: %w", err)
}
@@ -50,7 +50,7 @@ func NewDeployer(config *DeployerConfig) (*DeployerProvider, error) {
func (d *DeployerProvider) WithLogger(logger *slog.Logger) deployer.Deployer {
if logger == nil {
d.logger = slog.Default()
d.logger = slog.New(slog.DiscardHandler)
} else {
d.logger = logger
}
@@ -82,16 +82,16 @@ func (d *DeployerProvider) Deploy(ctx context.Context, certPEM string, privkeyPE
return &deployer.DeployResult{}, nil
}
func createSdkClient(apiUrl, apiKey string, skipTlsVerify bool) (*btsdk.Client, error) {
if _, err := url.Parse(apiUrl); err != nil {
return nil, errors.New("invalid baota api url")
func createSdkClient(serverUrl, apiKey string, skipTlsVerify bool) (*btsdk.Client, error) {
if _, err := url.Parse(serverUrl); err != nil {
return nil, errors.New("invalid baota server url")
}
if apiKey == "" {
return nil, errors.New("invalid baota api key")
}
client := btsdk.NewClient(apiUrl, apiKey)
client := btsdk.NewClient(serverUrl, apiKey)
if skipTlsVerify {
client.WithTLSConfig(&tls.Config{InsecureSkipVerify: true})
}

View File

@@ -14,7 +14,7 @@ import (
var (
fInputCertPath string
fInputKeyPath string
fApiUrl string
fServerUrl string
fApiKey string
)
@@ -23,7 +23,7 @@ func init() {
flag.StringVar(&fInputCertPath, argsPrefix+"INPUTCERTPATH", "", "")
flag.StringVar(&fInputKeyPath, argsPrefix+"INPUTKEYPATH", "", "")
flag.StringVar(&fApiUrl, argsPrefix+"APIURL", "", "")
flag.StringVar(&fServerUrl, argsPrefix+"SERVERURL", "", "")
flag.StringVar(&fApiKey, argsPrefix+"APIKEY", "", "")
}
@@ -33,7 +33,7 @@ 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_SERVERURL="http://127.0.0.1:8888" \
--CERTIMATE_DEPLOYER_BAOTAPANELCONSOLE_APIKEY="your-api-key"
*/
func TestDeploy(t *testing.T) {
@@ -44,12 +44,12 @@ func TestDeploy(t *testing.T) {
"args:",
fmt.Sprintf("INPUTCERTPATH: %v", fInputCertPath),
fmt.Sprintf("INPUTKEYPATH: %v", fInputKeyPath),
fmt.Sprintf("APIURL: %v", fApiUrl),
fmt.Sprintf("SERVERURL: %v", fServerUrl),
fmt.Sprintf("APIKEY: %v", fApiKey),
}, "\n"))
deployer, err := provider.NewDeployer(&provider.DeployerConfig{
ApiUrl: fApiUrl,
ServerUrl: fServerUrl,
ApiKey: fApiKey,
AllowInsecureConnections: true,
AutoRestart: true,

View File

@@ -14,8 +14,8 @@ import (
)
type DeployerConfig struct {
// 宝塔面板地址。
ApiUrl string `json:"apiUrl"`
// 宝塔面板服务地址。
ServerUrl string `json:"serverUrl"`
// 宝塔面板接口密钥。
ApiKey string `json:"apiKey"`
// 是否允许不安全的连接。
@@ -41,7 +41,7 @@ func NewDeployer(config *DeployerConfig) (*DeployerProvider, error) {
panic("config is nil")
}
client, err := createSdkClient(config.ApiUrl, config.ApiKey, config.AllowInsecureConnections)
client, err := createSdkClient(config.ServerUrl, config.ApiKey, config.AllowInsecureConnections)
if err != nil {
return nil, fmt.Errorf("failed to create sdk client: %w", err)
}
@@ -55,7 +55,7 @@ func NewDeployer(config *DeployerConfig) (*DeployerProvider, error) {
func (d *DeployerProvider) WithLogger(logger *slog.Logger) deployer.Deployer {
if logger == nil {
d.logger = slog.Default()
d.logger = slog.New(slog.DiscardHandler)
} else {
d.logger = logger
}
@@ -124,16 +124,16 @@ func (d *DeployerProvider) Deploy(ctx context.Context, certPEM string, privkeyPE
return &deployer.DeployResult{}, nil
}
func createSdkClient(apiUrl, apiKey string, skipTlsVerify bool) (*btsdk.Client, error) {
if _, err := url.Parse(apiUrl); err != nil {
return nil, errors.New("invalid baota api url")
func createSdkClient(serverUrl, apiKey string, skipTlsVerify bool) (*btsdk.Client, error) {
if _, err := url.Parse(serverUrl); err != nil {
return nil, errors.New("invalid baota server url")
}
if apiKey == "" {
return nil, errors.New("invalid baota api key")
}
client := btsdk.NewClient(apiUrl, apiKey)
client := btsdk.NewClient(serverUrl, apiKey)
if skipTlsVerify {
client.WithTLSConfig(&tls.Config{InsecureSkipVerify: true})
}

View File

@@ -14,7 +14,7 @@ import (
var (
fInputCertPath string
fInputKeyPath string
fApiUrl string
fServerUrl string
fApiKey string
fSiteType string
fSiteName string
@@ -25,7 +25,7 @@ func init() {
flag.StringVar(&fInputCertPath, argsPrefix+"INPUTCERTPATH", "", "")
flag.StringVar(&fInputKeyPath, argsPrefix+"INPUTKEYPATH", "", "")
flag.StringVar(&fApiUrl, argsPrefix+"APIURL", "", "")
flag.StringVar(&fServerUrl, argsPrefix+"SERVERURL", "", "")
flag.StringVar(&fApiKey, argsPrefix+"APIKEY", "", "")
flag.StringVar(&fSiteType, argsPrefix+"SITETYPE", "", "")
flag.StringVar(&fSiteName, argsPrefix+"SITENAME", "", "")
@@ -37,7 +37,7 @@ Shell command to run this test:
go test -v ./baotapanel_site_test.go -args \
--CERTIMATE_DEPLOYER_BAOTAPANELSITE_INPUTCERTPATH="/path/to/your-input-cert.pem" \
--CERTIMATE_DEPLOYER_BAOTAPANELSITE_INPUTKEYPATH="/path/to/your-input-key.pem" \
--CERTIMATE_DEPLOYER_BAOTAPANELSITE_APIURL="http://127.0.0.1:8888" \
--CERTIMATE_DEPLOYER_BAOTAPANELSITE_SERVERURL="http://127.0.0.1:8888" \
--CERTIMATE_DEPLOYER_BAOTAPANELSITE_APIKEY="your-api-key" \
--CERTIMATE_DEPLOYER_BAOTAPANELSITE_SITETYPE="php" \
--CERTIMATE_DEPLOYER_BAOTAPANELSITE_SITENAME="your-site-name"
@@ -50,14 +50,14 @@ func TestDeploy(t *testing.T) {
"args:",
fmt.Sprintf("INPUTCERTPATH: %v", fInputCertPath),
fmt.Sprintf("INPUTKEYPATH: %v", fInputKeyPath),
fmt.Sprintf("APIURL: %v", fApiUrl),
fmt.Sprintf("SERVERURL: %v", fServerUrl),
fmt.Sprintf("APIKEY: %v", fApiKey),
fmt.Sprintf("SITETYPE: %v", fSiteType),
fmt.Sprintf("SITENAME: %v", fSiteName),
}, "\n"))
deployer, err := provider.NewDeployer(&provider.DeployerConfig{
ApiUrl: fApiUrl,
ServerUrl: fServerUrl,
ApiKey: fApiKey,
AllowInsecureConnections: true,
SiteType: fSiteType,

View File

@@ -13,8 +13,8 @@ import (
)
type DeployerConfig struct {
// 堡塔云 WAF 地址。
ApiUrl string `json:"apiUrl"`
// 堡塔云 WAF 服务地址。
ServerUrl string `json:"serverUrl"`
// 堡塔云 WAF 接口密钥。
ApiKey string `json:"apiKey"`
// 是否允许不安全的连接。
@@ -34,7 +34,7 @@ func NewDeployer(config *DeployerConfig) (*DeployerProvider, error) {
panic("config is nil")
}
client, err := createSdkClient(config.ApiUrl, config.ApiKey, config.AllowInsecureConnections)
client, err := createSdkClient(config.ServerUrl, config.ApiKey, config.AllowInsecureConnections)
if err != nil {
return nil, fmt.Errorf("failed to create sdk client: %w", err)
}
@@ -48,7 +48,7 @@ func NewDeployer(config *DeployerConfig) (*DeployerProvider, error) {
func (d *DeployerProvider) WithLogger(logger *slog.Logger) deployer.Deployer {
if logger == nil {
d.logger = slog.Default()
d.logger = slog.New(slog.DiscardHandler)
} else {
d.logger = logger
}
@@ -70,16 +70,16 @@ func (d *DeployerProvider) Deploy(ctx context.Context, certPEM string, privkeyPE
return &deployer.DeployResult{}, nil
}
func createSdkClient(apiUrl, apiKey string, skipTlsVerify bool) (*btsdk.Client, error) {
if _, err := url.Parse(apiUrl); err != nil {
return nil, errors.New("invalid baota api url")
func createSdkClient(serverUrl, apiKey string, skipTlsVerify bool) (*btsdk.Client, error) {
if _, err := url.Parse(serverUrl); err != nil {
return nil, errors.New("invalid baota server url")
}
if apiKey == "" {
return nil, errors.New("invalid baota api key")
}
client := btsdk.NewClient(apiUrl, apiKey)
client := btsdk.NewClient(serverUrl, apiKey)
if skipTlsVerify {
client.WithTLSConfig(&tls.Config{InsecureSkipVerify: true})
}

View File

@@ -14,7 +14,7 @@ import (
var (
fInputCertPath string
fInputKeyPath string
fApiUrl string
fServerUrl string
fApiKey string
fSiteName string
fSitePort int64
@@ -25,7 +25,7 @@ func init() {
flag.StringVar(&fInputCertPath, argsPrefix+"INPUTCERTPATH", "", "")
flag.StringVar(&fInputKeyPath, argsPrefix+"INPUTKEYPATH", "", "")
flag.StringVar(&fApiUrl, argsPrefix+"APIURL", "", "")
flag.StringVar(&fServerUrl, argsPrefix+"SERVERURL", "", "")
flag.StringVar(&fApiKey, argsPrefix+"APIKEY", "", "")
}
@@ -35,7 +35,7 @@ Shell command to run this test:
go test -v ./baotawaf_console_test.go -args \
--CERTIMATE_DEPLOYER_BAOTAWAFCONSOLE_INPUTCERTPATH="/path/to/your-input-cert.pem" \
--CERTIMATE_DEPLOYER_BAOTAWAFCONSOLE_INPUTKEYPATH="/path/to/your-input-key.pem" \
--CERTIMATE_DEPLOYER_BAOTAWAFCONSOLE_APIURL="http://127.0.0.1:8888" \
--CERTIMATE_DEPLOYER_BAOTAWAFCONSOLE_SERVERURL="http://127.0.0.1:8888" \
--CERTIMATE_DEPLOYER_BAOTAWAFCONSOLE_APIKEY="your-api-key"
*/
func TestDeploy(t *testing.T) {
@@ -46,12 +46,12 @@ func TestDeploy(t *testing.T) {
"args:",
fmt.Sprintf("INPUTCERTPATH: %v", fInputCertPath),
fmt.Sprintf("INPUTKEYPATH: %v", fInputKeyPath),
fmt.Sprintf("APIURL: %v", fApiUrl),
fmt.Sprintf("SERVERURL: %v", fServerUrl),
fmt.Sprintf("APIKEY: %v", fApiKey),
}, "\n"))
deployer, err := provider.NewDeployer(&provider.DeployerConfig{
ApiUrl: fApiUrl,
ServerUrl: fServerUrl,
ApiKey: fApiKey,
AllowInsecureConnections: true,
})

View File

@@ -14,8 +14,8 @@ import (
)
type DeployerConfig struct {
// 堡塔云 WAF 地址。
ApiUrl string `json:"apiUrl"`
// 堡塔云 WAF 服务地址。
ServerUrl string `json:"serverUrl"`
// 堡塔云 WAF 接口密钥。
ApiKey string `json:"apiKey"`
// 是否允许不安全的连接。
@@ -23,7 +23,7 @@ type DeployerConfig struct {
// 网站名称。
SiteName string `json:"siteName"`
// 网站 SSL 端口。
// 零值时默认 443。
// 零值时默认 443。
SitePort int32 `json:"sitePort,omitempty"`
}
@@ -40,7 +40,7 @@ func NewDeployer(config *DeployerConfig) (*DeployerProvider, error) {
panic("config is nil")
}
client, err := createSdkClient(config.ApiUrl, config.ApiKey, config.AllowInsecureConnections)
client, err := createSdkClient(config.ServerUrl, config.ApiKey, config.AllowInsecureConnections)
if err != nil {
return nil, fmt.Errorf("failed to create sdk client: %w", err)
}
@@ -54,7 +54,7 @@ func NewDeployer(config *DeployerConfig) (*DeployerProvider, error) {
func (d *DeployerProvider) WithLogger(logger *slog.Logger) deployer.Deployer {
if logger == nil {
d.logger = slog.Default()
d.logger = slog.New(slog.DiscardHandler)
} else {
d.logger = logger
}
@@ -116,7 +116,7 @@ func (d *DeployerProvider) Deploy(ctx context.Context, certPEM string, privkeyPE
SiteId: siteId,
Type: typeutil.ToPtr("openCert"),
Server: &btsdk.SiteServerInfo{
ListenSSLPort: typeutil.ToPtr(d.config.SitePort),
ListenSSLPorts: typeutil.ToPtr([]int32{d.config.SitePort}),
SSL: &btsdk.SiteServerSSLInfo{
IsSSL: typeutil.ToPtr(int32(1)),
FullChain: typeutil.ToPtr(certPEM),
@@ -133,16 +133,16 @@ func (d *DeployerProvider) Deploy(ctx context.Context, certPEM string, privkeyPE
return &deployer.DeployResult{}, nil
}
func createSdkClient(apiUrl, apiKey string, skipTlsVerify bool) (*btsdk.Client, error) {
if _, err := url.Parse(apiUrl); err != nil {
return nil, errors.New("invalid baota api url")
func createSdkClient(serverUrl, apiKey string, skipTlsVerify bool) (*btsdk.Client, error) {
if _, err := url.Parse(serverUrl); err != nil {
return nil, errors.New("invalid baota server url")
}
if apiKey == "" {
return nil, errors.New("invalid baota api key")
}
client := btsdk.NewClient(apiUrl, apiKey)
client := btsdk.NewClient(serverUrl, apiKey)
if skipTlsVerify {
client.WithTLSConfig(&tls.Config{InsecureSkipVerify: true})
}

View File

@@ -14,7 +14,7 @@ import (
var (
fInputCertPath string
fInputKeyPath string
fApiUrl string
fServerUrl string
fApiKey string
fSiteName string
fSitePort int64
@@ -25,7 +25,7 @@ func init() {
flag.StringVar(&fInputCertPath, argsPrefix+"INPUTCERTPATH", "", "")
flag.StringVar(&fInputKeyPath, argsPrefix+"INPUTKEYPATH", "", "")
flag.StringVar(&fApiUrl, argsPrefix+"APIURL", "", "")
flag.StringVar(&fServerUrl, argsPrefix+"SERVERURL", "", "")
flag.StringVar(&fApiKey, argsPrefix+"APIKEY", "", "")
flag.StringVar(&fSiteName, argsPrefix+"SITENAME", "", "")
flag.Int64Var(&fSitePort, argsPrefix+"SITEPORT", 0, "")
@@ -37,9 +37,9 @@ Shell command to run this test:
go test -v ./baotawaf_site_test.go -args \
--CERTIMATE_DEPLOYER_BAOTAWAFSITE_INPUTCERTPATH="/path/to/your-input-cert.pem" \
--CERTIMATE_DEPLOYER_BAOTAWAFSITE_INPUTKEYPATH="/path/to/your-input-key.pem" \
--CERTIMATE_DEPLOYER_BAOTAWAFSITE_APIURL="http://127.0.0.1:8888" \
--CERTIMATE_DEPLOYER_BAOTAWAFSITE_SERVERURL="http://127.0.0.1:8888" \
--CERTIMATE_DEPLOYER_BAOTAWAFSITE_APIKEY="your-api-key" \
--CERTIMATE_DEPLOYER_BAOTAWAFSITE_SITENAME="your-site-name"\
--CERTIMATE_DEPLOYER_BAOTAWAFSITE_SITENAME="your-site-name" \
--CERTIMATE_DEPLOYER_BAOTAWAFSITE_SITEPORT=443
*/
func TestDeploy(t *testing.T) {
@@ -50,14 +50,14 @@ func TestDeploy(t *testing.T) {
"args:",
fmt.Sprintf("INPUTCERTPATH: %v", fInputCertPath),
fmt.Sprintf("INPUTKEYPATH: %v", fInputKeyPath),
fmt.Sprintf("APIURL: %v", fApiUrl),
fmt.Sprintf("SERVERURL: %v", fServerUrl),
fmt.Sprintf("APIKEY: %v", fApiKey),
fmt.Sprintf("SITENAME: %v", fSiteName),
fmt.Sprintf("SITEPORT: %v", fSitePort),
}, "\n"))
deployer, err := provider.NewDeployer(&provider.DeployerConfig{
ApiUrl: fApiUrl,
ServerUrl: fServerUrl,
ApiKey: fApiKey,
AllowInsecureConnections: true,
SiteName: fSiteName,

View File

@@ -41,7 +41,7 @@ func NewDeployer(config *DeployerConfig) (*DeployerProvider, error) {
func (d *DeployerProvider) WithLogger(logger *slog.Logger) deployer.Deployer {
if logger == nil {
d.logger = slog.Default()
d.logger = slog.New(slog.DiscardHandler)
} else {
d.logger = logger
}

View File

@@ -59,7 +59,7 @@ func NewDeployer(config *DeployerConfig) (*DeployerProvider, error) {
func (d *DeployerProvider) WithLogger(logger *slog.Logger) deployer.Deployer {
if logger == nil {
d.logger = slog.Default()
d.logger = slog.New(slog.DiscardHandler)
} else {
d.logger = logger
}

View File

@@ -42,7 +42,7 @@ func NewDeployer(config *DeployerConfig) (*DeployerProvider, error) {
func (d *DeployerProvider) WithLogger(logger *slog.Logger) deployer.Deployer {
if logger == nil {
d.logger = slog.Default()
d.logger = slog.New(slog.DiscardHandler)
} else {
d.logger = logger
}

View File

@@ -15,8 +15,8 @@ import (
)
type DeployerConfig struct {
// Cdnfly 地址。
ApiUrl string `json:"apiUrl"`
// Cdnfly 服务地址。
ServerUrl string `json:"serverUrl"`
// Cdnfly 用户端 API Key。
ApiKey string `json:"apiKey"`
// Cdnfly 用户端 API Secret。
@@ -46,7 +46,7 @@ func NewDeployer(config *DeployerConfig) (*DeployerProvider, error) {
panic("config is nil")
}
client, err := createSdkClient(config.ApiUrl, config.ApiKey, config.ApiSecret, config.AllowInsecureConnections)
client, err := createSdkClient(config.ServerUrl, config.ApiKey, config.ApiSecret, config.AllowInsecureConnections)
if err != nil {
return nil, fmt.Errorf("failed to create sdk client: %w", err)
}
@@ -60,7 +60,7 @@ func NewDeployer(config *DeployerConfig) (*DeployerProvider, error) {
func (d *DeployerProvider) WithLogger(logger *slog.Logger) deployer.Deployer {
if logger == nil {
d.logger = slog.Default()
d.logger = slog.New(slog.DiscardHandler)
} else {
d.logger = logger
}
@@ -160,9 +160,9 @@ func (d *DeployerProvider) deployToCertificate(ctx context.Context, certPEM stri
return nil
}
func createSdkClient(apiUrl, apiKey, apiSecret string, skipTlsVerify bool) (*cfsdk.Client, error) {
if _, err := url.Parse(apiUrl); err != nil {
return nil, errors.New("invalid cachefly api url")
func createSdkClient(serverUrl, apiKey, apiSecret string, skipTlsVerify bool) (*cfsdk.Client, error) {
if _, err := url.Parse(serverUrl); err != nil {
return nil, errors.New("invalid cachefly server url")
}
if apiKey == "" {
@@ -173,7 +173,7 @@ func createSdkClient(apiUrl, apiKey, apiSecret string, skipTlsVerify bool) (*cfs
return nil, errors.New("invalid cachefly api secret")
}
client := cfsdk.NewClient(apiUrl, apiKey, apiSecret)
client := cfsdk.NewClient(serverUrl, apiKey, apiSecret)
if skipTlsVerify {
client.WithTLSConfig(&tls.Config{InsecureSkipVerify: true})
}

View File

@@ -14,7 +14,7 @@ import (
var (
fInputCertPath string
fInputKeyPath string
fApiUrl string
fServerUrl string
fApiKey string
fApiSecret string
fCertificateId string
@@ -25,7 +25,7 @@ func init() {
flag.StringVar(&fInputCertPath, argsPrefix+"INPUTCERTPATH", "", "")
flag.StringVar(&fInputKeyPath, argsPrefix+"INPUTKEYPATH", "", "")
flag.StringVar(&fApiUrl, argsPrefix+"APIURL", "", "")
flag.StringVar(&fServerUrl, argsPrefix+"SERVERURL", "", "")
flag.StringVar(&fApiKey, argsPrefix+"APIKEY", "", "")
flag.StringVar(&fApiSecret, argsPrefix+"APISECRET", "", "")
flag.StringVar(&fCertificateId, argsPrefix+"CERTIFICATEID", "", "")
@@ -37,7 +37,7 @@ 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_SERVERURL="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"
@@ -50,14 +50,14 @@ func TestDeploy(t *testing.T) {
"args:",
fmt.Sprintf("INPUTCERTPATH: %v", fInputCertPath),
fmt.Sprintf("INPUTKEYPATH: %v", fInputKeyPath),
fmt.Sprintf("APIURL: %v", fApiUrl),
fmt.Sprintf("SERVERURL: %v", fServerUrl),
fmt.Sprintf("APIKEY: %v", fApiKey),
fmt.Sprintf("APISECRET: %v", fApiSecret),
fmt.Sprintf("CERTIFICATEID: %v", fCertificateId),
}, "\n"))
deployer, err := provider.NewDeployer(&provider.DeployerConfig{
ApiUrl: fApiUrl,
ServerUrl: fServerUrl,
ApiKey: fApiKey,
ApiSecret: fApiSecret,
AllowInsecureConnections: true,

View File

@@ -55,7 +55,7 @@ func NewDeployer(config *DeployerConfig) (*DeployerProvider, error) {
func (d *DeployerProvider) WithLogger(logger *slog.Logger) deployer.Deployer {
if logger == nil {
d.logger = slog.Default()
d.logger = slog.New(slog.DiscardHandler)
} else {
d.logger = logger
}

View File

@@ -48,7 +48,7 @@ func NewDeployer(config *DeployerConfig) (*DeployerProvider, error) {
func (d *DeployerProvider) WithLogger(logger *slog.Logger) deployer.Deployer {
if logger == nil {
d.logger = slog.Default()
d.logger = slog.New(slog.DiscardHandler)
} else {
d.logger = logger
}

View File

@@ -16,8 +16,8 @@ import (
)
type DeployerConfig struct {
// FlexCDN URL
ApiUrl string `json:"apiUrl"`
// FlexCDN 服务地址
ServerUrl string `json:"serverUrl"`
// FlexCDN 用户角色。
// 可取值 "user"、"admin"。
ApiRole string `json:"apiRole"`
@@ -47,7 +47,7 @@ func NewDeployer(config *DeployerConfig) (*DeployerProvider, error) {
panic("config is nil")
}
client, err := createSdkClient(config.ApiUrl, config.ApiRole, config.AccessKeyId, config.AccessKey, config.AllowInsecureConnections)
client, err := createSdkClient(config.ServerUrl, config.ApiRole, config.AccessKeyId, config.AccessKey, config.AllowInsecureConnections)
if err != nil {
return nil, fmt.Errorf("failed to create sdk client: %w", err)
}
@@ -61,7 +61,7 @@ func NewDeployer(config *DeployerConfig) (*DeployerProvider, error) {
func (d *DeployerProvider) WithLogger(logger *slog.Logger) deployer.Deployer {
if logger == nil {
d.logger = slog.Default()
d.logger = slog.New(slog.DiscardHandler)
} else {
d.logger = logger
}
@@ -119,9 +119,9 @@ func (d *DeployerProvider) deployToCertificate(ctx context.Context, certPEM stri
return nil
}
func createSdkClient(apiUrl, apiRole, accessKeyId, accessKey string, skipTlsVerify bool) (*flexcdnsdk.Client, error) {
if _, err := url.Parse(apiUrl); err != nil {
return nil, errors.New("invalid flexcdn api url")
func createSdkClient(serverUrl, apiRole, accessKeyId, accessKey string, skipTlsVerify bool) (*flexcdnsdk.Client, error) {
if _, err := url.Parse(serverUrl); err != nil {
return nil, errors.New("invalid flexcdn server url")
}
if apiRole != "user" && apiRole != "admin" {
@@ -136,7 +136,7 @@ func createSdkClient(apiUrl, apiRole, accessKeyId, accessKey string, skipTlsVeri
return nil, errors.New("invalid flexcdn access key")
}
client := flexcdnsdk.NewClient(apiUrl, apiRole, accessKeyId, accessKey)
client := flexcdnsdk.NewClient(serverUrl, apiRole, accessKeyId, accessKey)
if skipTlsVerify {
client.WithTLSConfig(&tls.Config{InsecureSkipVerify: true})
}

View File

@@ -14,7 +14,7 @@ import (
var (
fInputCertPath string
fInputKeyPath string
fApiUrl string
fServerUrl string
fAccessKeyId string
fAccessKey string
fCertificateId int64
@@ -25,7 +25,7 @@ func init() {
flag.StringVar(&fInputCertPath, argsPrefix+"INPUTCERTPATH", "", "")
flag.StringVar(&fInputKeyPath, argsPrefix+"INPUTKEYPATH", "", "")
flag.StringVar(&fApiUrl, argsPrefix+"APIURL", "", "")
flag.StringVar(&fServerUrl, argsPrefix+"SERVERURL", "", "")
flag.StringVar(&fAccessKeyId, argsPrefix+"ACCESSKEYID", "", "")
flag.StringVar(&fAccessKey, argsPrefix+"ACCESSKEY", "", "")
flag.Int64Var(&fCertificateId, argsPrefix+"CERTIFICATEID", 0, "")
@@ -37,7 +37,7 @@ Shell command to run this test:
go test -v ./flexcdn_test.go -args \
--CERTIMATE_DEPLOYER_FLEXCDN_INPUTCERTPATH="/path/to/your-input-cert.pem" \
--CERTIMATE_DEPLOYER_FLEXCDN_INPUTKEYPATH="/path/to/your-input-key.pem" \
--CERTIMATE_DEPLOYER_FLEXCDN_APIURL="http://127.0.0.1:7788" \
--CERTIMATE_DEPLOYER_FLEXCDN_SERVERURL="http://127.0.0.1:7788" \
--CERTIMATE_DEPLOYER_FLEXCDN_ACCESSKEYID="your-access-key-id" \
--CERTIMATE_DEPLOYER_FLEXCDN_ACCESSKEY="your-access-key" \
--CERTIMATE_DEPLOYER_FLEXCDN_CERTIFICATEID="your-cerficiate-id"
@@ -50,14 +50,14 @@ func TestDeploy(t *testing.T) {
"args:",
fmt.Sprintf("INPUTCERTPATH: %v", fInputCertPath),
fmt.Sprintf("INPUTKEYPATH: %v", fInputKeyPath),
fmt.Sprintf("APIURL: %v", fApiUrl),
fmt.Sprintf("SERVERURL: %v", fServerUrl),
fmt.Sprintf("ACCESSKEYID: %v", fAccessKeyId),
fmt.Sprintf("ACCESSKEY: %v", fAccessKey),
fmt.Sprintf("CERTIFICATEID: %v", fCertificateId),
}, "\n"))
deployer, err := provider.NewDeployer(&provider.DeployerConfig{
ApiUrl: fApiUrl,
ServerUrl: fServerUrl,
ApiRole: "user",
AccessKeyId: fAccessKeyId,
AccessKey: fAccessKey,

View File

@@ -69,7 +69,7 @@ func NewDeployer(config *DeployerConfig) (*DeployerProvider, error) {
func (d *DeployerProvider) WithLogger(logger *slog.Logger) deployer.Deployer {
if logger == nil {
d.logger = slog.Default()
d.logger = slog.New(slog.DiscardHandler)
} else {
d.logger = logger
}

View File

@@ -16,8 +16,8 @@ import (
)
type DeployerConfig struct {
// GoEdge URL
ApiUrl string `json:"apiUrl"`
// GoEdge 服务地址
ServerUrl string `json:"serverUrl"`
// GoEdge 用户角色。
// 可取值 "user"、"admin"。
ApiRole string `json:"apiRole"`
@@ -47,7 +47,7 @@ func NewDeployer(config *DeployerConfig) (*DeployerProvider, error) {
panic("config is nil")
}
client, err := createSdkClient(config.ApiUrl, config.ApiRole, config.AccessKeyId, config.AccessKey, config.AllowInsecureConnections)
client, err := createSdkClient(config.ServerUrl, config.ApiRole, config.AccessKeyId, config.AccessKey, config.AllowInsecureConnections)
if err != nil {
return nil, fmt.Errorf("failed to create sdk client: %w", err)
}
@@ -61,7 +61,7 @@ func NewDeployer(config *DeployerConfig) (*DeployerProvider, error) {
func (d *DeployerProvider) WithLogger(logger *slog.Logger) deployer.Deployer {
if logger == nil {
d.logger = slog.Default()
d.logger = slog.New(slog.DiscardHandler)
} else {
d.logger = logger
}
@@ -119,9 +119,9 @@ func (d *DeployerProvider) deployToCertificate(ctx context.Context, certPEM stri
return nil
}
func createSdkClient(apiUrl, apiRole, accessKeyId, accessKey string, skipTlsVerify bool) (*goedgesdk.Client, error) {
if _, err := url.Parse(apiUrl); err != nil {
return nil, errors.New("invalid goedge api url")
func createSdkClient(serverUrl, apiRole, accessKeyId, accessKey string, skipTlsVerify bool) (*goedgesdk.Client, error) {
if _, err := url.Parse(serverUrl); err != nil {
return nil, errors.New("invalid goedge server url")
}
if apiRole != "user" && apiRole != "admin" {
@@ -136,7 +136,7 @@ func createSdkClient(apiUrl, apiRole, accessKeyId, accessKey string, skipTlsVeri
return nil, errors.New("invalid goedge access key")
}
client := goedgesdk.NewClient(apiUrl, apiRole, accessKeyId, accessKey)
client := goedgesdk.NewClient(serverUrl, apiRole, accessKeyId, accessKey)
if skipTlsVerify {
client.WithTLSConfig(&tls.Config{InsecureSkipVerify: true})
}

View File

@@ -14,7 +14,7 @@ import (
var (
fInputCertPath string
fInputKeyPath string
fApiUrl string
fServerUrl string
fAccessKeyId string
fAccessKey string
fCertificateId int64
@@ -25,7 +25,7 @@ func init() {
flag.StringVar(&fInputCertPath, argsPrefix+"INPUTCERTPATH", "", "")
flag.StringVar(&fInputKeyPath, argsPrefix+"INPUTKEYPATH", "", "")
flag.StringVar(&fApiUrl, argsPrefix+"APIURL", "", "")
flag.StringVar(&fServerUrl, argsPrefix+"SERVERURL", "", "")
flag.StringVar(&fAccessKeyId, argsPrefix+"ACCESSKEYID", "", "")
flag.StringVar(&fAccessKey, argsPrefix+"ACCESSKEY", "", "")
flag.Int64Var(&fCertificateId, argsPrefix+"CERTIFICATEID", 0, "")
@@ -37,7 +37,7 @@ Shell command to run this test:
go test -v ./goedge_test.go -args \
--CERTIMATE_DEPLOYER_GOEDGE_INPUTCERTPATH="/path/to/your-input-cert.pem" \
--CERTIMATE_DEPLOYER_GOEDGE_INPUTKEYPATH="/path/to/your-input-key.pem" \
--CERTIMATE_DEPLOYER_GOEDGE_APIURL="http://127.0.0.1:7788" \
--CERTIMATE_DEPLOYER_GOEDGE_SERVERURL="http://127.0.0.1:7788" \
--CERTIMATE_DEPLOYER_GOEDGE_ACCESSKEYID="your-access-key-id" \
--CERTIMATE_DEPLOYER_GOEDGE_ACCESSKEY="your-access-key" \
--CERTIMATE_DEPLOYER_GOEDGE_CERTIFICATEID="your-cerficiate-id"
@@ -50,14 +50,14 @@ func TestDeploy(t *testing.T) {
"args:",
fmt.Sprintf("INPUTCERTPATH: %v", fInputCertPath),
fmt.Sprintf("INPUTKEYPATH: %v", fInputKeyPath),
fmt.Sprintf("APIURL: %v", fApiUrl),
fmt.Sprintf("SERVERURL: %v", fServerUrl),
fmt.Sprintf("ACCESSKEYID: %v", fAccessKeyId),
fmt.Sprintf("ACCESSKEY: %v", fAccessKey),
fmt.Sprintf("CERTIFICATEID: %v", fCertificateId),
}, "\n"))
deployer, err := provider.NewDeployer(&provider.DeployerConfig{
ApiUrl: fApiUrl,
ServerUrl: fServerUrl,
ApiRole: "user",
AccessKeyId: fAccessKeyId,
AccessKey: fAccessKey,

View File

@@ -21,6 +21,8 @@ type DeployerConfig struct {
AccessKeyId string `json:"accessKeyId"`
// 华为云 SecretAccessKey。
SecretAccessKey string `json:"secretAccessKey"`
// 华为云企业项目 ID。
EnterpriseProjectId string `json:"enterpriseProjectId,omitempty"`
// 华为云区域。
Region string `json:"region"`
// 加速域名(不支持泛域名)。
@@ -51,8 +53,9 @@ func NewDeployer(config *DeployerConfig) (*DeployerProvider, error) {
}
uploader, err := uploadersp.NewUploader(&uploadersp.UploaderConfig{
AccessKeyId: config.AccessKeyId,
SecretAccessKey: config.SecretAccessKey,
AccessKeyId: config.AccessKeyId,
SecretAccessKey: config.SecretAccessKey,
EnterpriseProjectId: config.EnterpriseProjectId,
})
if err != nil {
return nil, fmt.Errorf("failed to create ssl uploader: %w", err)
@@ -68,7 +71,7 @@ func NewDeployer(config *DeployerConfig) (*DeployerProvider, error) {
func (d *DeployerProvider) WithLogger(logger *slog.Logger) deployer.Deployer {
if logger == nil {
d.logger = slog.Default()
d.logger = slog.New(slog.DiscardHandler)
} else {
d.logger = logger
}
@@ -88,7 +91,8 @@ func (d *DeployerProvider) Deploy(ctx context.Context, certPEM string, privkeyPE
// 查询加速域名配置
// REF: https://support.huaweicloud.com/api-cdn/ShowDomainFullConfig.html
showDomainFullConfigReq := &hccdnmodel.ShowDomainFullConfigRequest{
DomainName: d.config.Domain,
EnterpriseProjectId: typeutil.ToPtrOrZeroNil(d.config.EnterpriseProjectId),
DomainName: d.config.Domain,
}
showDomainFullConfigResp, err := d.sdkClient.ShowDomainFullConfig(showDomainFullConfigReq)
d.logger.Debug("sdk request 'cdn.ShowDomainFullConfig'", slog.Any("request", showDomainFullConfigReq), slog.Any("response", showDomainFullConfigResp))
@@ -107,6 +111,7 @@ func (d *DeployerProvider) Deploy(ctx context.Context, certPEM string, privkeyPE
updateDomainMultiCertificatesReqBodyContent.CertName = typeutil.ToPtr(upres.CertName)
updateDomainMultiCertificatesReqBodyContent = assign(updateDomainMultiCertificatesReqBodyContent, showDomainFullConfigResp.Configs)
updateDomainMultiCertificatesReq := &hccdnmodel.UpdateDomainMultiCertificatesRequest{
EnterpriseProjectId: typeutil.ToPtrOrZeroNil(d.config.EnterpriseProjectId),
Body: &hccdnmodel.UpdateDomainMultiCertificatesRequestBody{
Https: updateDomainMultiCertificatesReqBodyContent,
},

View File

@@ -27,6 +27,8 @@ type DeployerConfig struct {
AccessKeyId string `json:"accessKeyId"`
// 华为云 SecretAccessKey。
SecretAccessKey string `json:"secretAccessKey"`
// 华为云企业项目 ID。
EnterpriseProjectId string `json:"enterpriseProjectId,omitempty"`
// 华为云区域。
Region string `json:"region"`
// 部署资源类型。
@@ -62,9 +64,10 @@ func NewDeployer(config *DeployerConfig) (*DeployerProvider, error) {
}
uploader, err := uploadersp.NewUploader(&uploadersp.UploaderConfig{
AccessKeyId: config.AccessKeyId,
SecretAccessKey: config.SecretAccessKey,
Region: config.Region,
AccessKeyId: config.AccessKeyId,
SecretAccessKey: config.SecretAccessKey,
EnterpriseProjectId: config.EnterpriseProjectId,
Region: config.Region,
})
if err != nil {
return nil, fmt.Errorf("failed to create ssl uploader: %w", err)
@@ -80,7 +83,7 @@ func NewDeployer(config *DeployerConfig) (*DeployerProvider, error) {
func (d *DeployerProvider) WithLogger(logger *slog.Logger) deployer.Deployer {
if logger == nil {
d.logger = slog.Default()
d.logger = slog.New(slog.DiscardHandler)
} else {
d.logger = logger
}
@@ -172,6 +175,9 @@ func (d *DeployerProvider) deployToLoadbalancer(ctx context.Context, certPEM str
Protocol: &[]string{"HTTPS", "TERMINATED_HTTPS"},
LoadbalancerId: &[]string{showLoadBalancerResp.Loadbalancer.Id},
}
if d.config.EnterpriseProjectId != "" {
listListenersReq.EnterpriseProjectId = typeutil.ToPtr([]string{d.config.EnterpriseProjectId})
}
listListenersResp, err := d.sdkClient.ListListeners(listListenersReq)
d.logger.Debug("sdk request 'elb.ListListeners'", slog.Any("request", listListenersReq), slog.Any("response", listListenersResp))
if err != nil {

View File

@@ -15,6 +15,8 @@ type DeployerConfig struct {
AccessKeyId string `json:"accessKeyId"`
// 华为云 SecretAccessKey。
SecretAccessKey string `json:"secretAccessKey"`
// 华为云企业项目 ID。
EnterpriseProjectId string `json:"enterpriseProjectId,omitempty"`
}
type DeployerProvider struct {
@@ -31,8 +33,9 @@ func NewDeployer(config *DeployerConfig) (*DeployerProvider, error) {
}
uploader, err := uploadersp.NewUploader(&uploadersp.UploaderConfig{
AccessKeyId: config.AccessKeyId,
SecretAccessKey: config.SecretAccessKey,
AccessKeyId: config.AccessKeyId,
SecretAccessKey: config.SecretAccessKey,
EnterpriseProjectId: config.EnterpriseProjectId,
})
if err != nil {
return nil, fmt.Errorf("failed to create ssl uploader: %w", err)
@@ -47,7 +50,7 @@ func NewDeployer(config *DeployerConfig) (*DeployerProvider, error) {
func (d *DeployerProvider) WithLogger(logger *slog.Logger) deployer.Deployer {
if logger == nil {
d.logger = slog.Default()
d.logger = slog.New(slog.DiscardHandler)
} else {
d.logger = logger
}

View File

@@ -27,6 +27,8 @@ type DeployerConfig struct {
AccessKeyId string `json:"accessKeyId"`
// 华为云 SecretAccessKey。
SecretAccessKey string `json:"secretAccessKey"`
// 华为云企业项目 ID。
EnterpriseProjectId string `json:"enterpriseProjectId,omitempty"`
// 华为云区域。
Region string `json:"region"`
// 部署资源类型。
@@ -59,9 +61,10 @@ func NewDeployer(config *DeployerConfig) (*DeployerProvider, error) {
}
uploader, err := uploadersp.NewUploader(&uploadersp.UploaderConfig{
AccessKeyId: config.AccessKeyId,
SecretAccessKey: config.SecretAccessKey,
Region: config.Region,
AccessKeyId: config.AccessKeyId,
SecretAccessKey: config.SecretAccessKey,
EnterpriseProjectId: config.EnterpriseProjectId,
Region: config.Region,
})
if err != nil {
return nil, fmt.Errorf("failed to create ssl uploader: %w", err)
@@ -77,7 +80,7 @@ func NewDeployer(config *DeployerConfig) (*DeployerProvider, error) {
func (d *DeployerProvider) WithLogger(logger *slog.Logger) deployer.Deployer {
if logger == nil {
d.logger = slog.Default()
d.logger = slog.New(slog.DiscardHandler)
} else {
d.logger = logger
}
@@ -126,7 +129,8 @@ func (d *DeployerProvider) deployToCertificate(ctx context.Context, certPEM stri
// 查询证书
// REF: https://support.huaweicloud.com/api-waf/ShowCertificate.html
showCertificateReq := &hcwafmodel.ShowCertificateRequest{
CertificateId: d.config.CertificateId,
EnterpriseProjectId: typeutil.ToPtrOrZeroNil(d.config.EnterpriseProjectId),
CertificateId: d.config.CertificateId,
}
showCertificateResp, err := d.sdkClient.ShowCertificate(showCertificateReq)
d.logger.Debug("sdk request 'waf.ShowCertificate'", slog.Any("request", showCertificateReq), slog.Any("response", showCertificateResp))
@@ -137,7 +141,8 @@ func (d *DeployerProvider) deployToCertificate(ctx context.Context, certPEM stri
// 更新证书
// REF: https://support.huaweicloud.com/api-waf/UpdateCertificate.html
updateCertificateReq := &hcwafmodel.UpdateCertificateRequest{
CertificateId: d.config.CertificateId,
EnterpriseProjectId: typeutil.ToPtrOrZeroNil(d.config.EnterpriseProjectId),
CertificateId: d.config.CertificateId,
Body: &hcwafmodel.UpdateCertificateRequestBody{
Name: *showCertificateResp.Name,
Content: typeutil.ToPtr(certPEM),
@@ -179,9 +184,10 @@ func (d *DeployerProvider) deployToCloudServer(ctx context.Context, certPEM stri
}
listHostReq := &hcwafmodel.ListHostRequest{
Hostname: typeutil.ToPtr(strings.TrimPrefix(d.config.Domain, "*")),
Page: typeutil.ToPtr(listHostPage),
Pagesize: typeutil.ToPtr(listHostPageSize),
EnterpriseProjectId: typeutil.ToPtrOrZeroNil(d.config.EnterpriseProjectId),
Hostname: typeutil.ToPtr(strings.TrimPrefix(d.config.Domain, "*")),
Page: typeutil.ToPtr(listHostPage),
Pagesize: typeutil.ToPtr(listHostPageSize),
}
listHostResp, err := d.sdkClient.ListHost(listHostReq)
d.logger.Debug("sdk request 'waf.ListHost'", slog.Any("request", listHostReq), slog.Any("response", listHostResp))
@@ -211,7 +217,8 @@ func (d *DeployerProvider) deployToCloudServer(ctx context.Context, certPEM stri
// 更新云模式防护域名的配置
// REF: https://support.huaweicloud.com/api-waf/UpdateHost.html
updateHostReq := &hcwafmodel.UpdateHostRequest{
InstanceId: hostId,
EnterpriseProjectId: typeutil.ToPtrOrZeroNil(d.config.EnterpriseProjectId),
InstanceId: hostId,
Body: &hcwafmodel.UpdateHostRequestBody{
Certificateid: typeutil.ToPtr(upres.CertId),
Certificatename: typeutil.ToPtr(upres.CertName),
@@ -252,9 +259,10 @@ func (d *DeployerProvider) deployToPremiumHost(ctx context.Context, certPEM stri
}
listPremiumHostReq := &hcwafmodel.ListPremiumHostRequest{
Hostname: typeutil.ToPtr(strings.TrimPrefix(d.config.Domain, "*")),
Page: typeutil.ToPtr(fmt.Sprintf("%d", listPremiumHostPage)),
Pagesize: typeutil.ToPtr(fmt.Sprintf("%d", listPremiumHostPageSize)),
EnterpriseProjectId: typeutil.ToPtrOrZeroNil(d.config.EnterpriseProjectId),
Hostname: typeutil.ToPtr(strings.TrimPrefix(d.config.Domain, "*")),
Page: typeutil.ToPtr(fmt.Sprintf("%d", listPremiumHostPage)),
Pagesize: typeutil.ToPtr(fmt.Sprintf("%d", listPremiumHostPageSize)),
}
listPremiumHostResp, err := d.sdkClient.ListPremiumHost(listPremiumHostReq)
d.logger.Debug("sdk request 'waf.ListPremiumHost'", slog.Any("request", listPremiumHostReq), slog.Any("response", listPremiumHostResp))
@@ -284,7 +292,8 @@ func (d *DeployerProvider) deployToPremiumHost(ctx context.Context, certPEM stri
// 修改独享模式域名配置
// REF: https://support.huaweicloud.com/api-waf/UpdatePremiumHost.html
updatePremiumHostReq := &hcwafmodel.UpdatePremiumHostRequest{
HostId: hostId,
EnterpriseProjectId: typeutil.ToPtrOrZeroNil(d.config.EnterpriseProjectId),
HostId: hostId,
Body: &hcwafmodel.UpdatePremiumHostRequestBody{
Certificateid: typeutil.ToPtr(upres.CertId),
Certificatename: typeutil.ToPtr(upres.CertName),

View File

@@ -76,7 +76,7 @@ func NewDeployer(config *DeployerConfig) (*DeployerProvider, error) {
func (d *DeployerProvider) WithLogger(logger *slog.Logger) deployer.Deployer {
if logger == nil {
d.logger = slog.Default()
d.logger = slog.New(slog.DiscardHandler)
} else {
d.logger = logger
}

View File

@@ -60,7 +60,7 @@ func NewDeployer(config *DeployerConfig) (*DeployerProvider, error) {
func (d *DeployerProvider) WithLogger(logger *slog.Logger) deployer.Deployer {
if logger == nil {
d.logger = slog.Default()
d.logger = slog.New(slog.DiscardHandler)
} else {
d.logger = logger
}

View File

@@ -48,7 +48,7 @@ func NewDeployer(config *DeployerConfig) (*DeployerProvider, error) {
func (d *DeployerProvider) WithLogger(logger *slog.Logger) deployer.Deployer {
if logger == nil {
d.logger = slog.Default()
d.logger = slog.New(slog.DiscardHandler)
} else {
d.logger = logger
}

View File

@@ -51,7 +51,7 @@ func NewDeployer(config *DeployerConfig) (*DeployerProvider, error) {
func (d *DeployerProvider) WithLogger(logger *slog.Logger) deployer.Deployer {
if logger == nil {
d.logger = slog.Default()
d.logger = slog.New(slog.DiscardHandler)
} else {
d.logger = logger
}

View File

@@ -52,7 +52,7 @@ func NewDeployer(config *DeployerConfig) (*DeployerProvider, error) {
func (d *DeployerProvider) WithLogger(logger *slog.Logger) deployer.Deployer {
if logger == nil {
d.logger = slog.Default()
d.logger = slog.New(slog.DiscardHandler)
} else {
d.logger = logger
}

View File

@@ -15,8 +15,8 @@ import (
)
type DeployerConfig struct {
// LeCDN URL
ApiUrl string `json:"apiUrl"`
// LeCDN 服务地址
ServerUrl string `json:"serverUrl"`
// LeCDN 版本。
// 可取值 "v3"。
ApiVersion string `json:"apiVersion"`
@@ -59,7 +59,7 @@ func NewDeployer(config *DeployerConfig) (*DeployerProvider, error) {
panic("config is nil")
}
client, err := createSdkClient(config.ApiUrl, config.ApiVersion, config.ApiRole, config.Username, config.Password, config.AllowInsecureConnections)
client, err := createSdkClient(config.ServerUrl, config.ApiVersion, config.ApiRole, config.Username, config.Password, config.AllowInsecureConnections)
if err != nil {
return nil, fmt.Errorf("failed to create sdk client: %w", err)
}
@@ -73,7 +73,7 @@ func NewDeployer(config *DeployerConfig) (*DeployerProvider, error) {
func (d *DeployerProvider) WithLogger(logger *slog.Logger) deployer.Deployer {
if logger == nil {
d.logger = slog.Default()
d.logger = slog.New(slog.DiscardHandler)
} else {
d.logger = logger
}
@@ -141,9 +141,9 @@ func (d *DeployerProvider) deployToCertificate(ctx context.Context, certPEM stri
return nil
}
func createSdkClient(apiUrl, apiVersion, apiRole, username, password string, skipTlsVerify bool) (interface{}, error) {
if _, err := url.Parse(apiUrl); err != nil {
return nil, errors.New("invalid lecdn api url")
func createSdkClient(serverUrl, apiVersion, apiRole, username, password string, skipTlsVerify bool) (interface{}, error) {
if _, err := url.Parse(serverUrl); err != nil {
return nil, errors.New("invalid lecdn server url")
}
if username == "" {
@@ -156,7 +156,7 @@ func createSdkClient(apiUrl, apiVersion, apiRole, username, password string, ski
if apiVersion == apiVersionV3 && apiRole == apiRoleClient {
// v3 版客户端
client := leclientsdkv3.NewClient(apiUrl, username, password)
client := leclientsdkv3.NewClient(serverUrl, username, password)
if skipTlsVerify {
client.WithTLSConfig(&tls.Config{InsecureSkipVerify: true})
}
@@ -164,7 +164,7 @@ func createSdkClient(apiUrl, apiVersion, apiRole, username, password string, ski
return client, nil
} else if apiVersion == apiVersionV3 && apiRole == apiRoleMaster {
// v3 版主控端
client := lemastersdkv3.NewClient(apiUrl, username, password)
client := lemastersdkv3.NewClient(serverUrl, username, password)
if skipTlsVerify {
client.WithTLSConfig(&tls.Config{InsecureSkipVerify: true})
}

View File

@@ -14,7 +14,7 @@ import (
var (
fInputCertPath string
fInputKeyPath string
fApiUrl string
fServerUrl string
fApiVersion string
fUsername string
fPassword string
@@ -26,7 +26,7 @@ func init() {
flag.StringVar(&fInputCertPath, argsPrefix+"INPUTCERTPATH", "", "")
flag.StringVar(&fInputKeyPath, argsPrefix+"INPUTKEYPATH", "", "")
flag.StringVar(&fApiUrl, argsPrefix+"APIURL", "", "")
flag.StringVar(&fServerUrl, argsPrefix+"SERVERURL", "", "")
flag.StringVar(&fApiVersion, argsPrefix+"APIVERSION", "v3", "")
flag.StringVar(&fUsername, argsPrefix+"USERNAME", "", "")
flag.StringVar(&fPassword, argsPrefix+"PASSWORD", "", "")
@@ -39,7 +39,7 @@ Shell command to run this test:
go test -v ./lecdn_test.go -args \
--CERTIMATE_DEPLOYER_LECDN_INPUTCERTPATH="/path/to/your-input-cert.pem" \
--CERTIMATE_DEPLOYER_LECDN_INPUTKEYPATH="/path/to/your-input-key.pem" \
--CERTIMATE_DEPLOYER_LECDN_APIURL="http://127.0.0.1:5090" \
--CERTIMATE_DEPLOYER_LECDN_SERVERURL="http://127.0.0.1:5090" \
--CERTIMATE_DEPLOYER_LECDN_USERNAME="your-username" \
--CERTIMATE_DEPLOYER_LECDN_PASSWORD="your-password" \
--CERTIMATE_DEPLOYER_LECDN_CERTIFICATEID="your-cerficiate-id"
@@ -52,7 +52,7 @@ func TestDeploy(t *testing.T) {
"args:",
fmt.Sprintf("INPUTCERTPATH: %v", fInputCertPath),
fmt.Sprintf("INPUTKEYPATH: %v", fInputKeyPath),
fmt.Sprintf("APIURL: %v", fApiUrl),
fmt.Sprintf("SERVERURL: %v", fServerUrl),
fmt.Sprintf("APIVERSION: %v", fApiVersion),
fmt.Sprintf("USERNAME: %v", fUsername),
fmt.Sprintf("PASSWORD: %v", fPassword),
@@ -60,7 +60,7 @@ func TestDeploy(t *testing.T) {
}, "\n"))
deployer, err := provider.NewDeployer(&provider.DeployerConfig{
ApiUrl: fApiUrl,
ServerUrl: fServerUrl,
ApiVersion: fApiVersion,
ApiRole: "user",
Username: fUsername,

View File

@@ -15,7 +15,7 @@ import (
type DeployerConfig struct {
// Shell 执行环境。
// 零值时默认根据操作系统决定。
// 零值时根据操作系统决定。
ShellEnv ShellEnvType `json:"shellEnv,omitempty"`
// 前置命令。
PreCommand string `json:"preCommand,omitempty"`
@@ -67,7 +67,7 @@ func NewDeployer(config *DeployerConfig) (*DeployerProvider, error) {
func (d *DeployerProvider) WithLogger(logger *slog.Logger) deployer.Deployer {
if logger == nil {
d.logger = slog.Default()
d.logger = slog.New(slog.DiscardHandler)
} else {
d.logger = logger
}

View File

@@ -45,7 +45,7 @@ func NewDeployer(config *DeployerConfig) (*DeployerProvider, error) {
func (d *DeployerProvider) WithLogger(logger *slog.Logger) deployer.Deployer {
if logger == nil {
d.logger = slog.Default()
d.logger = slog.New(slog.DiscardHandler)
} else {
d.logger = logger
}

View File

@@ -13,11 +13,12 @@ import (
"github.com/luthermonson/go-proxmox"
"github.com/usual2970/certimate/internal/pkg/core/deployer"
httputil "github.com/usual2970/certimate/internal/pkg/utils/http"
)
type DeployerConfig struct {
// Proxmox VE 地址。
ApiUrl string `json:"apiUrl"`
// Proxmox VE 服务地址。
ServerUrl string `json:"serverUrl"`
// Proxmox VE API Token。
ApiToken string `json:"apiToken"`
// Proxmox VE API Token Secret。
@@ -43,7 +44,7 @@ func NewDeployer(config *DeployerConfig) (*DeployerProvider, error) {
panic("config is nil")
}
client, err := createSdkClient(config.ApiUrl, config.ApiToken, config.ApiTokenSecret, config.AllowInsecureConnections)
client, err := createSdkClient(config.ServerUrl, config.ApiToken, config.ApiTokenSecret, config.AllowInsecureConnections)
if err != nil {
return nil, fmt.Errorf("failed to create sdk client: %w", err)
}
@@ -57,7 +58,7 @@ func NewDeployer(config *DeployerConfig) (*DeployerProvider, error) {
func (d *DeployerProvider) WithLogger(logger *slog.Logger) deployer.Deployer {
if logger == nil {
d.logger = slog.Default()
d.logger = slog.New(slog.DiscardHandler)
} else {
d.logger = logger
}
@@ -91,9 +92,9 @@ func (d *DeployerProvider) Deploy(ctx context.Context, certPEM string, privkeyPE
return &deployer.DeployResult{}, nil
}
func createSdkClient(apiUrl, apiToken, apiTokenSecret string, skipTlsVerify bool) (*proxmox.Client, error) {
if _, err := url.Parse(apiUrl); err != nil {
return nil, errors.New("invalid pve api url")
func createSdkClient(serverUrl, apiToken, apiTokenSecret string, skipTlsVerify bool) (*proxmox.Client, error) {
if _, err := url.Parse(serverUrl); err != nil {
return nil, errors.New("invalid pve server url")
}
if apiToken == "" {
@@ -101,18 +102,19 @@ func createSdkClient(apiUrl, apiToken, apiTokenSecret string, skipTlsVerify bool
}
httpClient := &http.Client{
Transport: http.DefaultTransport,
Transport: httputil.NewDefaultTransport(),
Timeout: http.DefaultClient.Timeout,
}
if skipTlsVerify {
httpClient.Transport = &http.Transport{
TLSClientConfig: &tls.Config{
InsecureSkipVerify: true,
},
transport := httputil.NewDefaultTransport()
if transport.TLSClientConfig == nil {
transport.TLSClientConfig = &tls.Config{}
}
transport.TLSClientConfig.InsecureSkipVerify = true
httpClient.Transport = transport
}
client := proxmox.NewClient(
strings.TrimRight(apiUrl, "/")+"/api2/json",
strings.TrimRight(serverUrl, "/")+"/api2/json",
proxmox.WithHTTPClient(httpClient),
proxmox.WithAPIToken(apiToken, apiTokenSecret),
)

View File

@@ -14,7 +14,7 @@ import (
var (
fInputCertPath string
fInputKeyPath string
fApiUrl string
fServerUrl string
fApiToken string
fApiTokenSecret string
fNodeName string
@@ -25,7 +25,7 @@ func init() {
flag.StringVar(&fInputCertPath, argsPrefix+"INPUTCERTPATH", "", "")
flag.StringVar(&fInputKeyPath, argsPrefix+"INPUTKEYPATH", "", "")
flag.StringVar(&fApiUrl, argsPrefix+"APIURL", "", "")
flag.StringVar(&fServerUrl, argsPrefix+"SERVERURL", "", "")
flag.StringVar(&fApiToken, argsPrefix+"APITOKEN", "", "")
flag.StringVar(&fApiTokenSecret, argsPrefix+"APITOKENSECRET", "", "")
flag.StringVar(&fNodeName, argsPrefix+"NODENAME", "", "")
@@ -37,7 +37,7 @@ Shell command to run this test:
go test -v ./proxmoxve_test.go -args \
--CERTIMATE_DEPLOYER_PROXMOXVE_INPUTCERTPATH="/path/to/your-input-cert.pem" \
--CERTIMATE_DEPLOYER_PROXMOXVE_INPUTKEYPATH="/path/to/your-input-key.pem" \
--CERTIMATE_DEPLOYER_PROXMOXVE_APIURL="http://127.0.0.1:8006" \
--CERTIMATE_DEPLOYER_PROXMOXVE_SERVERURL="http://127.0.0.1:8006" \
--CERTIMATE_DEPLOYER_PROXMOXVE_APITOKEN="your-api-token" \
--CERTIMATE_DEPLOYER_PROXMOXVE_APITOKENSECRET="your-api-token-secret" \
--CERTIMATE_DEPLOYER_PROXMOXVE_NODENAME="your-cluster-node-name"
@@ -50,14 +50,14 @@ func TestDeploy(t *testing.T) {
"args:",
fmt.Sprintf("INPUTCERTPATH: %v", fInputCertPath),
fmt.Sprintf("INPUTKEYPATH: %v", fInputKeyPath),
fmt.Sprintf("APIURL: %v", fApiUrl),
fmt.Sprintf("SERVERURL: %v", fServerUrl),
fmt.Sprintf("APITOKEN: %v", fApiToken),
fmt.Sprintf("APITOKENSECRET: %v", fApiTokenSecret),
fmt.Sprintf("NODENAME: %v", fNodeName),
}, "\n"))
deployer, err := provider.NewDeployer(&provider.DeployerConfig{
ApiUrl: fApiUrl,
ServerUrl: fServerUrl,
ApiToken: fApiToken,
ApiTokenSecret: fApiTokenSecret,
AllowInsecureConnections: true,

View File

@@ -57,7 +57,7 @@ func NewDeployer(config *DeployerConfig) (*DeployerProvider, error) {
func (d *DeployerProvider) WithLogger(logger *slog.Logger) deployer.Deployer {
if logger == nil {
d.logger = slog.Default()
d.logger = slog.New(slog.DiscardHandler)
} else {
d.logger = logger
}

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