Merge pull request #8 from woodchen-ink:usual2970-main

Usual2970-main
This commit is contained in:
wood chen 2025-03-27 13:56:58 +08:00 committed by GitHub
commit fdf87e8447
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
159 changed files with 5051 additions and 1005 deletions

77
.github/ISSUE_TEMPLATE/1-bug_report.yml vendored Normal file
View File

@ -0,0 +1,77 @@
name: "🐞 Bug Report"
description: "报告缺陷来帮助我们完善。 / Create a report to help us improve."
title: "[Bug] 简要描述你发现的缺陷"
labels:
- bug
body:
- type: markdown
attributes:
value: |
## Welcome!
**在提交 Issue 之前,请确认以下事项**
1. 我**确认**已尝试过使用当前最新版本,并能复现问题。
2. 我**确认**已搜索过[已有的 Issues](https://github.com/usual2970/certimate/issues)(包括已关闭的),没有类似的问题。
3. 我**确认**已阅读过[文档](https://docs.certimate.me/),没有类似的问题。
4. 请**务必**按照模板规范详细描述问题,否则 Issue 将会被直接关闭。
**Before you submit the issue, please make sure of the following checklist**:
1. Yes, I'm using the latest release and can reproduce the issue.
2. Yes, I've searched for [existing issues](https://github.com/usual2970/certimate/issues) (including closed ones) on GitHub and didn't find any similar.
3. Yes, I've read the [documentation](https://docs.certimate.me/en/) and didn't find any similar.
4. Please describe the problem in detail according to the template specification, otherwise the issue will be closed directly.
- type: input
attributes:
label: 软件版本 / Release Version
description: 请提供 Certimate 的具体版本。 / Please provide the specific version of Certimate.
placeholder: (e.g. v1.0.0)
validations:
required: true
- type: textarea
attributes:
label: 缺陷描述 / Description
description: 请详细清晰地描述你发现的缺陷或故障,如果可能请上传截图。 / Describe the bug you found in detail and clearly, and upload screenshots if possible.
validations:
required: true
- type: textarea
attributes:
label: 复现步骤 / Steps to reproduce
description: 请提供可复现的完整步骤。 / Please walk us through it step by step.
placeholder: |
1. ...
2. ...
3. ...
...
validations:
required: true
- type: textarea
attributes:
label: 日志 / Logs
description: 在此处添加日志信息(如果有的话)。 / Add logs here if available.
value: |-
<details>
```console
# 请在此粘贴日志 / Paste logs here
```
</details>
validations:
required: false
- type: textarea
attributes:
label: 其他 / Miscellaneous
description: 在此处添加关于该 Issue 的任何其他信息。 / Add any other context about the issue here.
validations:
required: false
- type: markdown
attributes:
value: |
请保持每个 Issue 只包含一个缺陷报告。
Please limit one report per issue.

View File

@ -0,0 +1,56 @@
name: "💡 Feature Request"
description: "提出新功能请求或改进意见。 / Suggest an idea for this project."
title: "[Feature] 简要描述你希望实现的功能"
labels:
- enhancement
body:
- type: markdown
attributes:
value: |
## Welcome!
**在提交 Issue 之前,请确认以下事项**
1. 我**确认**是基于当前最新大版本而提出的新功能请求或改进意见。
2. 我**确认**已搜索过[已有的 Issues](https://github.com/usual2970/certimate/issues)(包括已关闭的),没有类似的问题。
3. 我**确认**已阅读过[文档](https://docs.certimate.me/),没有类似的问题。
4. 请**务必**按照模板规范详细描述问题,否则 Issue 将会被直接关闭。
**Before you submit the issue, please make sure of the following checklist**:
1. Yes, I'm using the latest release.
2. Yes, I've searched for [existing issues](https://github.com/usual2970/certimate/issues) (including closed ones) on GitHub and didn't find any similar.
3. Yes, I've read the [documentation](https://docs.certimate.me/en/) and didn't find any similar.
4. Please describe the problem in detail according to the template specification, otherwise the issue will be closed directly.
- type: textarea
attributes:
label: 功能描述 / Description
description: 请详细清晰地描述你希望添加的功能,如果可能请上传截图。 / Describe the feature you'd like to add in detail and clearly, and upload screenshots if possible.
validations:
required: true
- type: textarea
attributes:
label: 请求动机 / Motivation
description: 为什么这个功能对项目有帮助? / Why is this feature helpful to the project?
validations:
required: true
- type: textarea
attributes:
label: 其他 / Miscellaneous
description: 在此处添加关于该 Issue 的任何其他信息。 / Add any other context about the problem here.
validations:
required: false
- type: checkboxes
attributes:
label: 贡献 / Contribution
options:
- label: 我乐意为此贡献代码! / I am interested in contributing to this feature!
required: false
- type: markdown
attributes:
value: |
请保持每个 Issue 只包含一个功能请求。
Please limit one request per issue.

40
.github/ISSUE_TEMPLATE/3-questions.yml vendored Normal file
View File

@ -0,0 +1,40 @@
name: "❓ Questions"
description: "遇到了困难需要求助? / Have problem in use and need help?"
title: "[Feature] 简要描述你遇到的问题"
body:
- type: markdown
attributes:
value: |
## Welcome!
**在提交 Issue 之前,请确认以下事项**
1. 我**确认**正在使用的是当前最新版本。
2. 我**确认**已搜索过[已有的 Issues](https://github.com/usual2970/certimate/issues)(包括已关闭的),没有类似的问题。
3. 我**确认**已阅读过[文档](https://docs.certimate.me/),没有类似的问题。
4. 请**务必**按照模板规范详细描述问题,否则 Issue 将会被直接关闭。
**Before you submit the issue, please make sure of the following checklist**:
1. Yes, I'm using the latest release.
2. Yes, I've searched for [existing issues](https://github.com/usual2970/certimate/issues) (including closed ones) on GitHub and didn't find any similar.
3. Yes, I've read the [documentation](https://docs.certimate.me/en/) and didn't find any similar.
4. Please describe the problem in detail according to the template specification, otherwise the issue will be closed directly.
- type: textarea
attributes:
label: 问题描述 / Description
description: 请详细清晰地描述你遇到的问题,如果可能请上传截图。 / Describe the problem you encountered in detail and clearly, and upload screenshots if possible.
validations:
required: true
- type: textarea
attributes:
label: 其他 / Miscellaneous
description: 在此处添加关于该问题的任何其他信息。 / Add any other context about the problem here.
validations:
required: false
- type: markdown
attributes:
value: |
请保持每个 Issue 只包含一个问题求助。
Please limit one question per issue.

View File

@ -1,38 +1,28 @@
FROM node:22-alpine3.19 AS front-builder FROM node:22-alpine3.19 AS webui-builder
WORKDIR /app WORKDIR /app
COPY . /app/ COPY . /app/
RUN \ RUN \
cd /app/ui && \ cd /app/ui && \
npm install && \ npm install && \
npm run build npm run build
FROM golang:1.23-alpine AS builder
FROM golang:1.23-alpine AS builder
WORKDIR /app WORKDIR /app
RUN apk add --no-cache tzdata RUN apk add --no-cache tzdata
COPY ../. /app/ COPY ../. /app/
RUN rm -rf /app/ui/dist RUN rm -rf /app/ui/dist
COPY --from=webui-builder /app/ui/dist /app/ui/dist
COPY --from=front-builder /app/ui/dist /app/ui/dist
RUN go build -o certimate RUN go build -o certimate
FROM alpine:latest FROM alpine:latest
WORKDIR /app WORKDIR /app
RUN apk add --no-cache tzdata RUN apk add --no-cache tzdata
COPY --from=builder /app/certimate . COPY --from=builder /app/certimate .
COPY --from=builder /usr/share/zoneinfo /usr/share/zoneinfo COPY --from=builder /usr/share/zoneinfo /usr/share/zoneinfo
ENTRYPOINT ["./certimate", "serve", "--http", "0.0.0.0:8090"] ENTRYPOINT ["./certimate", "serve", "--http", "0.0.0.0:8090"]

View File

@ -38,8 +38,8 @@ Certimate 旨在为用户提供一个安全、简便的 SSL 证书管理解决
- 灵活的工作流编排方式,证书从申请到部署完全自动化; - 灵活的工作流编排方式,证书从申请到部署完全自动化;
- 支持单域名、多域名、泛域名证书,可选 RSA、ECC 签名算法; - 支持单域名、多域名、泛域名证书,可选 RSA、ECC 签名算法;
- 支持 PEM、PFX、JKS 等多种格式输出证书; - 支持 PEM、PFX、JKS 等多种格式输出证书;
- 支持 20+ 域名托管商如阿里云、腾讯云、Cloudflare 等,[点此查看](https://docs.certimate.me/docs/reference/providers#supported-dns-providers)完整提供商清单 - 支持 20+ 域名托管商如阿里云、腾讯云、Cloudflare 等,[点此查看完整清单](https://docs.certimate.me/docs/reference/providers#supported-dns-providers)
- 支持 60+ 部署目标(如 Kubernetes、CDN、WAF、负载均衡等[点此查看](https://docs.certimate.me/docs/reference/providers#supported-host-providers)完整提供商清单 - 支持 70+ 部署目标(如 Kubernetes、CDN、WAF、负载均衡等[点此查看完整清单](https://docs.certimate.me/docs/reference/providers#supported-host-providers)
- 支持邮件、钉钉、飞书、企业微信、Webhook 等多种通知渠道; - 支持邮件、钉钉、飞书、企业微信、Webhook 等多种通知渠道;
- 支持 Let's Encrypt、ZeroSSL、Google Trust Services 等多种 ACME 证书颁发机构; - 支持 Let's Encrypt、ZeroSSL、Google Trust Services 等多种 ACME 证书颁发机构;
- 更多特性等待探索。 - 更多特性等待探索。
@ -71,7 +71,7 @@ Certimate 旨在为用户提供一个安全、简便的 SSL 证书管理解决
相关文章: 相关文章:
- [使用 CNAME 实现 DNS-01 challenge](https://docs.certimate.me/blog/cname) - [使用 CNAME 完成 ACME DNS-01 质询](https://docs.certimate.me/blog/cname)
- [v0.3.0:第二个不向后兼容的大版本](https://docs.certimate.me/blog/v0.3.0) - [v0.3.0:第二个不向后兼容的大版本](https://docs.certimate.me/blog/v0.3.0)
- [v0.2.0:第一个不向后兼容的大版本](https://docs.certimate.me/blog/v0.2.0) - [v0.2.0:第一个不向后兼容的大版本](https://docs.certimate.me/blog/v0.2.0)
- [Why Certimate?](https://docs.certimate.me/blog/why-certimate) - [Why Certimate?](https://docs.certimate.me/blog/why-certimate)

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 single-domain, multi-domain, wildcard certificates, with options for RSA or ECC.
- Supports various certificate formats such as PEM, PFX, JKS. - Supports various certificate formats such as PEM, PFX, JKS.
- Supports more than 20+ 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 20+ 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 60+ deployment targets (e.g., Kubernetes, CDN, WAF, load balancers, etc. [Check out this link](https://docs.certimate.me/en/docs/reference/providers#supported-host-providers)); - Supports more than 70+ deployment targets (e.g., Kubernetes, CDN, WAF, load balancers, etc. [Check out this link](https://docs.certimate.me/en/docs/reference/providers#supported-host-providers));
- Supports multiple notification channels including email, DingTalk, Feishu, WeCom, Webhook, and more; - Supports multiple notification channels including email, DingTalk, Feishu, WeCom, Webhook, and more;
- Supports multiple ACME CAs including Let's Encrypt, ZeroSSL, Google Trust Services, and more; - Supports multiple ACME CAs including Let's Encrypt, ZeroSSL, Google Trust Services, and more;
- More features waiting to be discovered. - More features waiting to be discovered.
@ -69,7 +69,7 @@ Please visit the documentation site [docs.certimate.me](https://docs.certimate.m
Related articles: Related articles:
- [使用 CNAME 实现 DNS-01 challenge](https://docs.certimate.me/blog/cname) - [使用 CNAME 完成 ACME DNS-01 质询](https://docs.certimate.me/blog/cname)
- [v0.3.0:第二个不向后兼容的大版本](https://docs.certimate.me/blog/v0.3.0) - [v0.3.0:第二个不向后兼容的大版本](https://docs.certimate.me/blog/v0.3.0)
- [v0.2.0:第一个不向后兼容的大版本](https://docs.certimate.me/blog/v0.2.0) - [v0.2.0:第一个不向后兼容的大版本](https://docs.certimate.me/blog/v0.2.0)
- [Why Certimate?](https://docs.certimate.me/blog/why-certimate) - [Why Certimate?](https://docs.certimate.me/blog/why-certimate)

5
go.mod
View File

@ -99,13 +99,18 @@ require (
github.com/google/gnostic-models v0.6.9 // indirect github.com/google/gnostic-models v0.6.9 // indirect
github.com/google/go-cmp v0.6.0 // indirect github.com/google/go-cmp v0.6.0 // indirect
github.com/google/gofuzz v1.2.0 // indirect github.com/google/gofuzz v1.2.0 // indirect
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
github.com/hashicorp/go-retryablehttp v0.7.7 // indirect
github.com/josharian/intern v1.0.0 // indirect github.com/josharian/intern v1.0.0 // indirect
github.com/kylelemons/godebug v1.1.0 // indirect github.com/kylelemons/godebug v1.1.0 // indirect
github.com/leodido/go-urn v1.4.0 // indirect github.com/leodido/go-urn v1.4.0 // indirect
github.com/mailru/easyjson v0.9.0 // indirect github.com/mailru/easyjson v0.9.0 // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/namedotcom/go v0.0.0-20180403034216-08470befbe04 // indirect github.com/namedotcom/go v0.0.0-20180403034216-08470befbe04 // indirect
github.com/nrdcg/desec v0.10.0 // indirect
github.com/nrdcg/mailinabox v0.2.0 // indirect github.com/nrdcg/mailinabox v0.2.0 // indirect
github.com/nrdcg/porkbun v0.4.0 // indirect
github.com/peterhellberg/link v1.2.0 // indirect
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c // indirect github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c // indirect
github.com/qiniu/dyn v1.3.0 // indirect github.com/qiniu/dyn v1.3.0 // indirect
github.com/qiniu/x v1.10.5 // indirect github.com/qiniu/x v1.10.5 // indirect

9
go.sum
View File

@ -494,6 +494,7 @@ github.com/hashicorp/consul/sdk v0.8.0/go.mod h1:GBvyrGALthsZObzUGsfgHZQDXjg4lOj
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ=
github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48=
github.com/hashicorp/go-hclog v0.12.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= github.com/hashicorp/go-hclog v0.12.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ=
github.com/hashicorp/go-hclog v0.16.2/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= github.com/hashicorp/go-hclog v0.16.2/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ=
@ -503,6 +504,8 @@ github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iP
github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
github.com/hashicorp/go-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+vmowP0z+KUhOZdA= github.com/hashicorp/go-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+vmowP0z+KUhOZdA=
github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs= github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs=
github.com/hashicorp/go-retryablehttp v0.7.7 h1:C8hUCYzor8PIfXHa4UrZkU4VvK8o9ISHxT2Q8+VepXU=
github.com/hashicorp/go-retryablehttp v0.7.7/go.mod h1:pkQpWZeYWskR+D1tR2O5OcBFOxfA7DoAO6xtkuQnHTk=
github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8= github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8=
github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU=
github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4=
@ -646,10 +649,14 @@ github.com/ncruces/go-strftime v0.1.9/go.mod h1:Fwc5htZGVVkseilnfgOVb9mKy6w1naJm
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
github.com/nikoksr/notify v1.3.0 h1:UxzfxzAYGQD9a5JYLBTVx0lFMxeHCke3rPCkfWdPgLs= github.com/nikoksr/notify v1.3.0 h1:UxzfxzAYGQD9a5JYLBTVx0lFMxeHCke3rPCkfWdPgLs=
github.com/nikoksr/notify v1.3.0/go.mod h1:Xor2hMmkvrCfkCKvXGbcrESez4brac2zQjhd6U2BbeM= github.com/nikoksr/notify v1.3.0/go.mod h1:Xor2hMmkvrCfkCKvXGbcrESez4brac2zQjhd6U2BbeM=
github.com/nrdcg/desec v0.10.0 h1:qrEDiqnsvNU9QE7lXIXi/tIHAfyaFXKxF2/8/52O8uM=
github.com/nrdcg/desec v0.10.0/go.mod h1:5+4vyhMRTs49V9CNoODF/HwT8Mwxv9DJ6j+7NekUnBs=
github.com/nrdcg/mailinabox v0.2.0 h1:IKq8mfKiVwNW2hQii/ng1dJ4yYMMv3HAP3fMFIq2CFk= github.com/nrdcg/mailinabox v0.2.0 h1:IKq8mfKiVwNW2hQii/ng1dJ4yYMMv3HAP3fMFIq2CFk=
github.com/nrdcg/mailinabox v0.2.0/go.mod h1:0yxqeYOiGyxAu7Sb94eMxHPIOsPYXAjTeA9ZhePhGnc= github.com/nrdcg/mailinabox v0.2.0/go.mod h1:0yxqeYOiGyxAu7Sb94eMxHPIOsPYXAjTeA9ZhePhGnc=
github.com/nrdcg/namesilo v0.2.1 h1:kLjCjsufdW/IlC+iSfAqj0iQGgKjlbUUeDJio5Y6eMg= github.com/nrdcg/namesilo v0.2.1 h1:kLjCjsufdW/IlC+iSfAqj0iQGgKjlbUUeDJio5Y6eMg=
github.com/nrdcg/namesilo v0.2.1/go.mod h1:lwMvfQTyYq+BbjJd30ylEG4GPSS6PII0Tia4rRpRiyw= github.com/nrdcg/namesilo v0.2.1/go.mod h1:lwMvfQTyYq+BbjJd30ylEG4GPSS6PII0Tia4rRpRiyw=
github.com/nrdcg/porkbun v0.4.0 h1:rWweKlwo1PToQ3H+tEO9gPRW0wzzgmI/Ob3n2Guticw=
github.com/nrdcg/porkbun v0.4.0/go.mod h1:/QMskrHEIM0IhC/wY7iTCUgINsxdT2WcOphktJ9+Q54=
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
@ -675,6 +682,8 @@ github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144T
github.com/pavlo-v-chernykh/keystore-go/v4 v4.5.0 h1:2nosf3P75OZv2/ZO/9Px5ZgZ5gbKrzA3joN1QMfOGMQ= github.com/pavlo-v-chernykh/keystore-go/v4 v4.5.0 h1:2nosf3P75OZv2/ZO/9Px5ZgZ5gbKrzA3joN1QMfOGMQ=
github.com/pavlo-v-chernykh/keystore-go/v4 v4.5.0/go.mod h1:lAVhWwbNaveeJmxrxuSTxMgKpF6DjnuVpn6T8WiBwYQ= github.com/pavlo-v-chernykh/keystore-go/v4 v4.5.0/go.mod h1:lAVhWwbNaveeJmxrxuSTxMgKpF6DjnuVpn6T8WiBwYQ=
github.com/performancecopilot/speed/v4 v4.0.0/go.mod h1:qxrSyuDGrTOWfV+uKRFhfxw6h/4HXRGUiZiufxo49BM= github.com/performancecopilot/speed/v4 v4.0.0/go.mod h1:qxrSyuDGrTOWfV+uKRFhfxw6h/4HXRGUiZiufxo49BM=
github.com/peterhellberg/link v1.2.0 h1:UA5pg3Gp/E0F2WdX7GERiNrPQrM1K6CVJUUWfHa4t6c=
github.com/peterhellberg/link v1.2.0/go.mod h1:gYfAh+oJgQu2SrZHg5hROVRQe1ICoK0/HHJTcE0edxc=
github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc= github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc=
github.com/pierrec/lz4 v2.6.1+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= github.com/pierrec/lz4 v2.6.1+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c h1:+mdjkGKdHQG3305AYmdv1U2eRNDiU2ErMBj1gwrq8eQ= github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c h1:+mdjkGKdHQG3305AYmdv1U2eRNDiU2ErMBj1gwrq8eQ=

View File

@ -73,12 +73,7 @@ func NewWithApplyNode(node *domain.WorkflowNode) (Applicant, error) {
if access, err := accessRepo.GetById(context.Background(), nodeConfig.ProviderAccessId); err != nil { 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) return nil, fmt.Errorf("failed to get access #%s record: %w", nodeConfig.ProviderAccessId, err)
} else { } else {
accessConfig, err := access.UnmarshalConfigToMap() options.ProviderAccessConfig = access.Config
if err != nil {
return nil, fmt.Errorf("failed to unmarshal access config: %w", err)
}
options.ProviderAccessConfig = accessConfig
} }
certRepo := repository.NewCertificateRepository() certRepo := repository.NewCertificateRepository()

View File

@ -14,6 +14,7 @@ import (
pCloudflare "github.com/usual2970/certimate/internal/pkg/core/applicant/acme-dns-01/lego-providers/cloudflare" 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" 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" pCMCCCloud "github.com/usual2970/certimate/internal/pkg/core/applicant/acme-dns-01/lego-providers/cmcccloud"
pDeSEC "github.com/usual2970/certimate/internal/pkg/core/applicant/acme-dns-01/lego-providers/desec"
pDNSLA "github.com/usual2970/certimate/internal/pkg/core/applicant/acme-dns-01/lego-providers/dnsla" pDNSLA "github.com/usual2970/certimate/internal/pkg/core/applicant/acme-dns-01/lego-providers/dnsla"
pDynv6 "github.com/usual2970/certimate/internal/pkg/core/applicant/acme-dns-01/lego-providers/dynv6" 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" pGcore "github.com/usual2970/certimate/internal/pkg/core/applicant/acme-dns-01/lego-providers/gcore"
@ -25,9 +26,12 @@ import (
pNameDotCom "github.com/usual2970/certimate/internal/pkg/core/applicant/acme-dns-01/lego-providers/namedotcom" pNameDotCom "github.com/usual2970/certimate/internal/pkg/core/applicant/acme-dns-01/lego-providers/namedotcom"
pNameSilo "github.com/usual2970/certimate/internal/pkg/core/applicant/acme-dns-01/lego-providers/namesilo" pNameSilo "github.com/usual2970/certimate/internal/pkg/core/applicant/acme-dns-01/lego-providers/namesilo"
pNS1 "github.com/usual2970/certimate/internal/pkg/core/applicant/acme-dns-01/lego-providers/ns1" pNS1 "github.com/usual2970/certimate/internal/pkg/core/applicant/acme-dns-01/lego-providers/ns1"
pPorkbun "github.com/usual2970/certimate/internal/pkg/core/applicant/acme-dns-01/lego-providers/porkbun"
pPowerDNS "github.com/usual2970/certimate/internal/pkg/core/applicant/acme-dns-01/lego-providers/powerdns" pPowerDNS "github.com/usual2970/certimate/internal/pkg/core/applicant/acme-dns-01/lego-providers/powerdns"
pRainYun "github.com/usual2970/certimate/internal/pkg/core/applicant/acme-dns-01/lego-providers/rainyun" 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" 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"
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" 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" pWestcn "github.com/usual2970/certimate/internal/pkg/core/applicant/acme-dns-01/lego-providers/westcn"
"github.com/usual2970/certimate/internal/pkg/utils/maputil" "github.com/usual2970/certimate/internal/pkg/utils/maputil"
@ -171,6 +175,21 @@ func createApplicant(options *applicantOptions) (challenge.Provider, error) {
return applicant, err return applicant, err
} }
case domain.ApplyDNSProviderTypeDeSEC:
{
access := domain.AccessConfigForDeSEC{}
if err := maputil.Populate(options.ProviderAccessConfig, &access); err != nil {
return nil, fmt.Errorf("failed to populate provider access config: %w", err)
}
applicant, err := pDeSEC.NewChallengeProvider(&pDeSEC.ChallengeProviderConfig{
Token: access.Token,
DnsPropagationTimeout: options.DnsPropagationTimeout,
DnsTTL: options.DnsTTL,
})
return applicant, err
}
case domain.ApplyDNSProviderTypeDNSLA: case domain.ApplyDNSProviderTypeDNSLA:
{ {
access := domain.AccessConfigForDNSLA{} access := domain.AccessConfigForDNSLA{}
@ -276,7 +295,7 @@ func createApplicant(options *applicantOptions) (challenge.Provider, error) {
applicant, err := pJDCloud.NewChallengeProvider(&pJDCloud.ChallengeProviderConfig{ applicant, err := pJDCloud.NewChallengeProvider(&pJDCloud.ChallengeProviderConfig{
AccessKeyId: access.AccessKeyId, AccessKeyId: access.AccessKeyId,
AccessKeySecret: access.AccessKeySecret, AccessKeySecret: access.AccessKeySecret,
RegionId: maputil.GetString(options.ProviderApplyConfig, "region_id"), RegionId: maputil.GetString(options.ProviderApplyConfig, "regionId"),
DnsPropagationTimeout: options.DnsPropagationTimeout, DnsPropagationTimeout: options.DnsPropagationTimeout,
DnsTTL: options.DnsTTL, DnsTTL: options.DnsTTL,
}) })
@ -345,6 +364,22 @@ func createApplicant(options *applicantOptions) (challenge.Provider, error) {
return applicant, err return applicant, err
} }
case domain.ApplyDNSProviderTypePorkbun:
{
access := domain.AccessConfigForPorkbun{}
if err := maputil.Populate(options.ProviderAccessConfig, &access); err != nil {
return nil, fmt.Errorf("failed to populate provider access config: %w", err)
}
applicant, err := pPorkbun.NewChallengeProvider(&pPorkbun.ChallengeProviderConfig{
ApiKey: access.ApiKey,
SecretApiKey: access.SecretApiKey,
DnsPropagationTimeout: options.DnsPropagationTimeout,
DnsTTL: options.DnsTTL,
})
return applicant, err
}
case domain.ApplyDNSProviderTypePowerDNS: case domain.ApplyDNSProviderTypePowerDNS:
{ {
access := domain.AccessConfigForPowerDNS{} access := domain.AccessConfigForPowerDNS{}
@ -376,13 +411,15 @@ func createApplicant(options *applicantOptions) (challenge.Provider, error) {
return applicant, err return applicant, err
} }
case domain.ApplyDNSProviderTypeTencentCloud, domain.ApplyDNSProviderTypeTencentCloudDNS: case domain.ApplyDNSProviderTypeTencentCloud, domain.ApplyDNSProviderTypeTencentCloudDNS, domain.ApplyDNSProviderTypeTencentCloudEO:
{ {
access := domain.AccessConfigForTencentCloud{} access := domain.AccessConfigForTencentCloud{}
if err := maputil.Populate(options.ProviderAccessConfig, &access); err != nil { if err := maputil.Populate(options.ProviderAccessConfig, &access); err != nil {
return nil, fmt.Errorf("failed to populate provider access config: %w", err) return nil, fmt.Errorf("failed to populate provider access config: %w", err)
} }
switch options.Provider {
case domain.ApplyDNSProviderTypeTencentCloud, domain.ApplyDNSProviderTypeTencentCloudDNS:
applicant, err := pTencentCloud.NewChallengeProvider(&pTencentCloud.ChallengeProviderConfig{ applicant, err := pTencentCloud.NewChallengeProvider(&pTencentCloud.ChallengeProviderConfig{
SecretId: access.SecretId, SecretId: access.SecretId,
SecretKey: access.SecretKey, SecretKey: access.SecretKey,
@ -390,6 +427,36 @@ func createApplicant(options *applicantOptions) (challenge.Provider, error) {
DnsTTL: options.DnsTTL, DnsTTL: options.DnsTTL,
}) })
return applicant, err return applicant, err
case domain.ApplyDNSProviderTypeTencentCloudEO:
applicant, err := pTencentCloudEO.NewChallengeProvider(&pTencentCloudEO.ChallengeProviderConfig{
SecretId: access.SecretId,
SecretKey: access.SecretKey,
ZoneId: maputil.GetString(options.ProviderApplyConfig, "zoneId"),
DnsPropagationTimeout: options.DnsPropagationTimeout,
DnsTTL: options.DnsTTL,
})
return applicant, err
default:
break
}
}
case domain.ApplyDNSProviderTypeVercel:
{
access := domain.AccessConfigForVercel{}
if err := maputil.Populate(options.ProviderAccessConfig, &access); err != nil {
return nil, fmt.Errorf("failed to populate provider access config: %w", err)
}
applicant, err := pVercel.NewChallengeProvider(&pVercel.ChallengeProviderConfig{
ApiAccessToken: access.ApiAccessToken,
TeamId: access.TeamId,
DnsPropagationTimeout: options.DnsPropagationTimeout,
DnsTTL: options.DnsTTL,
})
return applicant, err
} }
case domain.ApplyDNSProviderTypeVolcEngine, domain.ApplyDNSProviderTypeVolcEngineDNS: case domain.ApplyDNSProviderTypeVolcEngine, domain.ApplyDNSProviderTypeVolcEngineDNS:

View File

@ -39,14 +39,9 @@ func NewWithDeployNode(node *domain.WorkflowNode, certdata struct {
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", nodeConfig.ProviderAccessId, err)
} }
accessConfig, err := access.UnmarshalConfigToMap()
if err != nil {
return nil, fmt.Errorf("failed to unmarshal access config: %w", err)
}
deployer, err := createDeployer(&deployerOptions{ deployer, err := createDeployer(&deployerOptions{
Provider: domain.DeployProviderType(nodeConfig.Provider), Provider: domain.DeployProviderType(nodeConfig.Provider),
ProviderAccessConfig: accessConfig, ProviderAccessConfig: access.Config,
ProviderDeployConfig: nodeConfig.ProviderConfig, ProviderDeployConfig: nodeConfig.ProviderConfig,
}) })
if err != nil { if err != nil {

View File

@ -24,7 +24,10 @@ import (
pAWSACM "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/aws-acm" pAWSACM "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/aws-acm"
pAWSCloudFront "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/aws-cloudfront" pAWSCloudFront "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/aws-cloudfront"
pAzureKeyVault "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/azure-keyvault" 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"
pBaiduCloudCDN "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/baiducloud-cdn" pBaiduCloudCDN "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/baiducloud-cdn"
pBaiduCloudCert "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/baiducloud-cert"
pBaishanCDN "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/baishan-cdn" pBaishanCDN "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/baishan-cdn"
pBaotaPanelConsole "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/baotapanel-console" pBaotaPanelConsole "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/baotapanel-console"
pBaotaPanelSite "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/baotapanel-site" pBaotaPanelSite "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/baotapanel-site"
@ -36,6 +39,7 @@ import (
pGcoreCDN "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/gcore-cdn" pGcoreCDN "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/gcore-cdn"
pHuaweiCloudCDN "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/huaweicloud-cdn" pHuaweiCloudCDN "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/huaweicloud-cdn"
pHuaweiCloudELB "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/huaweicloud-elb" pHuaweiCloudELB "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/huaweicloud-elb"
pHuaweiCloudSCM "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/huaweicloud-scm"
pHuaweiCloudWAF "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/huaweicloud-waf" pHuaweiCloudWAF "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/huaweicloud-waf"
pJDCloudALB "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/jdcloud-alb" pJDCloudALB "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/jdcloud-alb"
pJDCloudCDN "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/jdcloud-cdn" pJDCloudCDN "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/jdcloud-cdn"
@ -61,7 +65,9 @@ import (
pUCloudUCDN "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/ucloud-ucdn" pUCloudUCDN "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/ucloud-ucdn"
pUCloudUS3 "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/ucloud-us3" pUCloudUS3 "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/ucloud-us3"
pUpyunCDN "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/upyun-cdn" 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" pVolcEngineCDN "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/volcengine-cdn"
pVolcEngineCertCenter "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/volcengine-certcenter"
pVolcEngineCLB "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/volcengine-clb" pVolcEngineCLB "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/volcengine-clb"
pVolcEngineDCDN "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/volcengine-dcdn" pVolcEngineDCDN "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/volcengine-dcdn"
pVolcEngineImageX "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/volcengine-imagex" pVolcEngineImageX "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/volcengine-imagex"
@ -302,7 +308,7 @@ func createDeployer(options *deployerOptions) (deployer.Deployer, error) {
} }
} }
case domain.DeployProviderTypeBaiduCloudCDN: case domain.DeployProviderTypeBaiduCloudAppBLB, domain.DeployProviderTypeBaiduCloudBLB, domain.DeployProviderTypeBaiduCloudCDN, domain.DeployProviderTypeBaiduCloudCert:
{ {
access := domain.AccessConfigForBaiduCloud{} access := domain.AccessConfigForBaiduCloud{}
if err := maputil.Populate(options.ProviderAccessConfig, &access); err != nil { if err := maputil.Populate(options.ProviderAccessConfig, &access); err != nil {
@ -310,6 +316,30 @@ func createDeployer(options *deployerOptions) (deployer.Deployer, error) {
} }
switch options.Provider { switch options.Provider {
case domain.DeployProviderTypeBaiduCloudAppBLB:
deployer, err := pBaiduCloudAppBLB.NewDeployer(&pBaiduCloudAppBLB.DeployerConfig{
AccessKeyId: access.AccessKeyId,
SecretAccessKey: access.SecretAccessKey,
Region: maputil.GetString(options.ProviderDeployConfig, "region"),
ResourceType: pBaiduCloudAppBLB.ResourceType(maputil.GetString(options.ProviderDeployConfig, "resourceType")),
LoadbalancerId: maputil.GetString(options.ProviderDeployConfig, "loadbalancerId"),
ListenerPort: maputil.GetInt32(options.ProviderDeployConfig, "listenerPort"),
Domain: maputil.GetString(options.ProviderDeployConfig, "domain"),
})
return deployer, err
case domain.DeployProviderTypeBaiduCloudBLB:
deployer, err := pBaiduCloudBLB.NewDeployer(&pBaiduCloudBLB.DeployerConfig{
AccessKeyId: access.AccessKeyId,
SecretAccessKey: access.SecretAccessKey,
Region: maputil.GetString(options.ProviderDeployConfig, "region"),
ResourceType: pBaiduCloudBLB.ResourceType(maputil.GetString(options.ProviderDeployConfig, "resourceType")),
LoadbalancerId: maputil.GetString(options.ProviderDeployConfig, "loadbalancerId"),
ListenerPort: maputil.GetInt32(options.ProviderDeployConfig, "listenerPort"),
Domain: maputil.GetString(options.ProviderDeployConfig, "domain"),
})
return deployer, err
case domain.DeployProviderTypeBaiduCloudCDN: case domain.DeployProviderTypeBaiduCloudCDN:
deployer, err := pBaiduCloudCDN.NewDeployer(&pBaiduCloudCDN.DeployerConfig{ deployer, err := pBaiduCloudCDN.NewDeployer(&pBaiduCloudCDN.DeployerConfig{
AccessKeyId: access.AccessKeyId, AccessKeyId: access.AccessKeyId,
@ -318,6 +348,13 @@ func createDeployer(options *deployerOptions) (deployer.Deployer, error) {
}) })
return deployer, err return deployer, err
case domain.DeployProviderTypeBaiduCloudCert:
deployer, err := pBaiduCloudCert.NewDeployer(&pBaiduCloudCert.DeployerConfig{
AccessKeyId: access.AccessKeyId,
SecretAccessKey: access.SecretAccessKey,
})
return deployer, err
default: default:
break break
} }
@ -478,7 +515,7 @@ func createDeployer(options *deployerOptions) (deployer.Deployer, error) {
} }
} }
case domain.DeployProviderTypeHuaweiCloudCDN, domain.DeployProviderTypeHuaweiCloudELB, domain.DeployProviderTypeHuaweiCloudWAF: case domain.DeployProviderTypeHuaweiCloudCDN, domain.DeployProviderTypeHuaweiCloudELB, domain.DeployProviderTypeHuaweiCloudSCM, domain.DeployProviderTypeHuaweiCloudWAF:
{ {
access := domain.AccessConfigForHuaweiCloud{} access := domain.AccessConfigForHuaweiCloud{}
if err := maputil.Populate(options.ProviderAccessConfig, &access); err != nil { if err := maputil.Populate(options.ProviderAccessConfig, &access); err != nil {
@ -507,6 +544,13 @@ func createDeployer(options *deployerOptions) (deployer.Deployer, error) {
}) })
return deployer, err return deployer, err
case domain.DeployProviderTypeHuaweiCloudSCM:
deployer, err := pHuaweiCloudSCM.NewDeployer(&pHuaweiCloudSCM.DeployerConfig{
AccessKeyId: access.AccessKeyId,
SecretAccessKey: access.SecretAccessKey,
})
return deployer, err
case domain.DeployProviderTypeHuaweiCloudWAF: case domain.DeployProviderTypeHuaweiCloudWAF:
deployer, err := pHuaweiCloudWAF.NewDeployer(&pHuaweiCloudWAF.DeployerConfig{ deployer, err := pHuaweiCloudWAF.NewDeployer(&pHuaweiCloudWAF.DeployerConfig{
AccessKeyId: access.AccessKeyId, AccessKeyId: access.AccessKeyId,
@ -848,7 +892,7 @@ func createDeployer(options *deployerOptions) (deployer.Deployer, error) {
} }
} }
case domain.DeployProviderTypeVolcEngineCDN, domain.DeployProviderTypeVolcEngineCLB, domain.DeployProviderTypeVolcEngineDCDN, domain.DeployProviderTypeVolcEngineImageX, domain.DeployProviderTypeVolcEngineLive, domain.DeployProviderTypeVolcEngineTOS: case domain.DeployProviderTypeVolcEngineALB, domain.DeployProviderTypeVolcEngineCDN, domain.DeployProviderTypeVolcEngineCertCenter, domain.DeployProviderTypeVolcEngineCLB, domain.DeployProviderTypeVolcEngineDCDN, domain.DeployProviderTypeVolcEngineImageX, domain.DeployProviderTypeVolcEngineLive, domain.DeployProviderTypeVolcEngineTOS:
{ {
access := domain.AccessConfigForVolcEngine{} access := domain.AccessConfigForVolcEngine{}
if err := maputil.Populate(options.ProviderAccessConfig, &access); err != nil { if err := maputil.Populate(options.ProviderAccessConfig, &access); err != nil {
@ -856,6 +900,18 @@ func createDeployer(options *deployerOptions) (deployer.Deployer, error) {
} }
switch options.Provider { switch options.Provider {
case domain.DeployProviderTypeVolcEngineALB:
deployer, err := pVolcEngineALB.NewDeployer(&pVolcEngineALB.DeployerConfig{
AccessKeyId: access.AccessKeyId,
AccessKeySecret: access.SecretAccessKey,
Region: maputil.GetString(options.ProviderDeployConfig, "region"),
ResourceType: pVolcEngineALB.ResourceType(maputil.GetString(options.ProviderDeployConfig, "resourceType")),
LoadbalancerId: maputil.GetString(options.ProviderDeployConfig, "loadbalancerId"),
ListenerId: maputil.GetString(options.ProviderDeployConfig, "listenerId"),
Domain: maputil.GetString(options.ProviderDeployConfig, "domain"),
})
return deployer, err
case domain.DeployProviderTypeVolcEngineCDN: case domain.DeployProviderTypeVolcEngineCDN:
deployer, err := pVolcEngineCDN.NewDeployer(&pVolcEngineCDN.DeployerConfig{ deployer, err := pVolcEngineCDN.NewDeployer(&pVolcEngineCDN.DeployerConfig{
AccessKeyId: access.AccessKeyId, AccessKeyId: access.AccessKeyId,
@ -864,12 +920,21 @@ func createDeployer(options *deployerOptions) (deployer.Deployer, error) {
}) })
return deployer, err return deployer, err
case domain.DeployProviderTypeVolcEngineCertCenter:
deployer, err := pVolcEngineCertCenter.NewDeployer(&pVolcEngineCertCenter.DeployerConfig{
AccessKeyId: access.AccessKeyId,
AccessKeySecret: access.SecretAccessKey,
Region: maputil.GetString(options.ProviderDeployConfig, "region"),
})
return deployer, err
case domain.DeployProviderTypeVolcEngineCLB: case domain.DeployProviderTypeVolcEngineCLB:
deployer, err := pVolcEngineCLB.NewDeployer(&pVolcEngineCLB.DeployerConfig{ deployer, err := pVolcEngineCLB.NewDeployer(&pVolcEngineCLB.DeployerConfig{
AccessKeyId: access.AccessKeyId, AccessKeyId: access.AccessKeyId,
AccessKeySecret: access.SecretAccessKey, AccessKeySecret: access.SecretAccessKey,
Region: maputil.GetString(options.ProviderDeployConfig, "region"), Region: maputil.GetString(options.ProviderDeployConfig, "region"),
ResourceType: pVolcEngineCLB.ResourceType(maputil.GetString(options.ProviderDeployConfig, "resourceType")), ResourceType: pVolcEngineCLB.ResourceType(maputil.GetString(options.ProviderDeployConfig, "resourceType")),
LoadbalancerId: maputil.GetString(options.ProviderDeployConfig, "loadbalancerId"),
ListenerId: maputil.GetString(options.ProviderDeployConfig, "listenerId"), ListenerId: maputil.GetString(options.ProviderDeployConfig, "listenerId"),
}) })
return deployer, err return deployer, err

View File

@ -1,7 +1,6 @@
package domain package domain
import ( import (
"encoding/json"
"time" "time"
) )
@ -11,19 +10,10 @@ type Access struct {
Meta Meta
Name string `json:"name" db:"name"` Name string `json:"name" db:"name"`
Provider string `json:"provider" db:"provider"` Provider string `json:"provider" db:"provider"`
Config string `json:"config" db:"config"` Config map[string]any `json:"config" db:"config"`
DeletedAt *time.Time `json:"deleted" db:"deleted"` DeletedAt *time.Time `json:"deleted" db:"deleted"`
} }
func (a *Access) UnmarshalConfigToMap() (map[string]any, error) {
config := make(map[string]any)
if err := json.Unmarshal([]byte(a.Config), &config); err != nil {
return nil, err
}
return config, nil
}
type AccessConfigFor1Panel struct { type AccessConfigFor1Panel struct {
ApiUrl string `json:"apiUrl"` ApiUrl string `json:"apiUrl"`
ApiKey string `json:"apiKey"` ApiKey string `json:"apiKey"`
@ -98,6 +88,10 @@ type AccessConfigForCMCCCloud struct {
AccessKeySecret string `json:"accessKeySecret"` AccessKeySecret string `json:"accessKeySecret"`
} }
type AccessConfigForDeSEC struct {
Token string `json:"token"`
}
type AccessConfigForDNSLA struct { type AccessConfigForDNSLA struct {
ApiId string `json:"apiId"` ApiId string `json:"apiId"`
ApiSecret string `json:"apiSecret"` ApiSecret string `json:"apiSecret"`
@ -165,6 +159,11 @@ type AccessConfigForNS1 struct {
ApiKey string `json:"apiKey"` ApiKey string `json:"apiKey"`
} }
type AccessConfigForPorkbun struct {
ApiKey string `json:"apiKey"`
SecretApiKey string `json:"secretApiKey"`
}
type AccessConfigForPowerDNS struct { type AccessConfigForPowerDNS struct {
ApiUrl string `json:"apiUrl"` ApiUrl string `json:"apiUrl"`
ApiKey string `json:"apiKey"` ApiKey string `json:"apiKey"`
@ -210,6 +209,11 @@ type AccessConfigForUpyun struct {
Password string `json:"password"` Password string `json:"password"`
} }
type AccessConfigForVercel struct {
ApiAccessToken string `json:"apiAccessToken"`
TeamId string `json:"teamId,omitempty"`
}
type AccessConfigForVolcEngine struct { type AccessConfigForVolcEngine struct {
AccessKeyId string `json:"accessKeyId"` AccessKeyId string `json:"accessKeyId"`
SecretAccessKey string `json:"secretAccessKey"` SecretAccessKey string `json:"secretAccessKey"`

View File

@ -26,6 +26,7 @@ const (
AccessProviderTypeCMCCCloud = AccessProviderType("cmcccloud") AccessProviderTypeCMCCCloud = AccessProviderType("cmcccloud")
AccessProviderTypeCTCCCloud = AccessProviderType("ctcccloud") // 联通云(预留) AccessProviderTypeCTCCCloud = AccessProviderType("ctcccloud") // 联通云(预留)
AccessProviderTypeCUCCCloud = AccessProviderType("cucccloud") // 天翼云(预留) AccessProviderTypeCUCCCloud = AccessProviderType("cucccloud") // 天翼云(预留)
AccessProviderTypeDeSEC = AccessProviderType("desec")
AccessProviderTypeDNSLA = AccessProviderType("dnsla") AccessProviderTypeDNSLA = AccessProviderType("dnsla")
AccessProviderTypeDogeCloud = AccessProviderType("dogecloud") AccessProviderTypeDogeCloud = AccessProviderType("dogecloud")
AccessProviderTypeDynv6 = AccessProviderType("dynv6") AccessProviderTypeDynv6 = AccessProviderType("dynv6")
@ -43,6 +44,7 @@ const (
AccessProviderTypeNameDotCom = AccessProviderType("namedotcom") AccessProviderTypeNameDotCom = AccessProviderType("namedotcom")
AccessProviderTypeNameSilo = AccessProviderType("namesilo") AccessProviderTypeNameSilo = AccessProviderType("namesilo")
AccessProviderTypeNS1 = AccessProviderType("ns1") AccessProviderTypeNS1 = AccessProviderType("ns1")
AccessProviderTypePorkbun = AccessProviderType("porkbun")
AccessProviderTypePowerDNS = AccessProviderType("powerdns") AccessProviderTypePowerDNS = AccessProviderType("powerdns")
AccessProviderTypeQiniu = AccessProviderType("qiniu") AccessProviderTypeQiniu = AccessProviderType("qiniu")
AccessProviderTypeQingCloud = AccessProviderType("qingcloud") // 青云(预留) AccessProviderTypeQingCloud = AccessProviderType("qingcloud") // 青云(预留)
@ -52,6 +54,7 @@ const (
AccessProviderTypeTencentCloud = AccessProviderType("tencentcloud") AccessProviderTypeTencentCloud = AccessProviderType("tencentcloud")
AccessProviderTypeUCloud = AccessProviderType("ucloud") AccessProviderTypeUCloud = AccessProviderType("ucloud")
AccessProviderTypeUpyun = AccessProviderType("upyun") AccessProviderTypeUpyun = AccessProviderType("upyun")
AccessProviderTypeVercel = AccessProviderType("vercel")
AccessProviderTypeVolcEngine = AccessProviderType("volcengine") AccessProviderTypeVolcEngine = AccessProviderType("volcengine")
AccessProviderTypeWebhook = AccessProviderType("webhook") AccessProviderTypeWebhook = AccessProviderType("webhook")
AccessProviderTypeWestcn = AccessProviderType("westcn") AccessProviderTypeWestcn = AccessProviderType("westcn")
@ -79,6 +82,7 @@ const (
ApplyDNSProviderTypeCloudflare = ApplyDNSProviderType("cloudflare") ApplyDNSProviderTypeCloudflare = ApplyDNSProviderType("cloudflare")
ApplyDNSProviderTypeClouDNS = ApplyDNSProviderType("cloudns") ApplyDNSProviderTypeClouDNS = ApplyDNSProviderType("cloudns")
ApplyDNSProviderTypeCMCCCloud = ApplyDNSProviderType("cmcccloud") ApplyDNSProviderTypeCMCCCloud = ApplyDNSProviderType("cmcccloud")
ApplyDNSProviderTypeDeSEC = ApplyDNSProviderType("desec")
ApplyDNSProviderTypeDNSLA = ApplyDNSProviderType("dnsla") ApplyDNSProviderTypeDNSLA = ApplyDNSProviderType("dnsla")
ApplyDNSProviderTypeDynv6 = ApplyDNSProviderType("dynv6") ApplyDNSProviderTypeDynv6 = ApplyDNSProviderType("dynv6")
ApplyDNSProviderTypeGcore = ApplyDNSProviderType("gcore") ApplyDNSProviderTypeGcore = ApplyDNSProviderType("gcore")
@ -92,10 +96,13 @@ const (
ApplyDNSProviderTypeNameDotCom = ApplyDNSProviderType("namedotcom") ApplyDNSProviderTypeNameDotCom = ApplyDNSProviderType("namedotcom")
ApplyDNSProviderTypeNameSilo = ApplyDNSProviderType("namesilo") ApplyDNSProviderTypeNameSilo = ApplyDNSProviderType("namesilo")
ApplyDNSProviderTypeNS1 = ApplyDNSProviderType("ns1") ApplyDNSProviderTypeNS1 = ApplyDNSProviderType("ns1")
ApplyDNSProviderTypePorkbun = ApplyDNSProviderType("porkbun")
ApplyDNSProviderTypePowerDNS = ApplyDNSProviderType("powerdns") ApplyDNSProviderTypePowerDNS = ApplyDNSProviderType("powerdns")
ApplyDNSProviderTypeRainYun = ApplyDNSProviderType("rainyun") ApplyDNSProviderTypeRainYun = ApplyDNSProviderType("rainyun")
ApplyDNSProviderTypeTencentCloud = ApplyDNSProviderType("tencentcloud") // 兼容旧值,等同于 [ApplyDNSProviderTypeTencentCloudDNS] ApplyDNSProviderTypeTencentCloud = ApplyDNSProviderType("tencentcloud") // 兼容旧值,等同于 [ApplyDNSProviderTypeTencentCloudDNS]
ApplyDNSProviderTypeTencentCloudDNS = ApplyDNSProviderType("tencentcloud-dns") ApplyDNSProviderTypeTencentCloudDNS = ApplyDNSProviderType("tencentcloud-dns")
ApplyDNSProviderTypeTencentCloudEO = ApplyDNSProviderType("tencentcloud-eo")
ApplyDNSProviderTypeVercel = ApplyDNSProviderType("vercel")
ApplyDNSProviderTypeVolcEngine = ApplyDNSProviderType("volcengine") // 兼容旧值,等同于 [ApplyDNSProviderTypeVolcEngineDNS] ApplyDNSProviderTypeVolcEngine = ApplyDNSProviderType("volcengine") // 兼容旧值,等同于 [ApplyDNSProviderTypeVolcEngineDNS]
ApplyDNSProviderTypeVolcEngineDNS = ApplyDNSProviderType("volcengine-dns") ApplyDNSProviderTypeVolcEngineDNS = ApplyDNSProviderType("volcengine-dns")
ApplyDNSProviderTypeWestcn = ApplyDNSProviderType("westcn") ApplyDNSProviderTypeWestcn = ApplyDNSProviderType("westcn")
@ -129,7 +136,10 @@ const (
DeployProviderTypeAWSACM = DeployProviderType("aws-acm") DeployProviderTypeAWSACM = DeployProviderType("aws-acm")
DeployProviderTypeAWSCloudFront = DeployProviderType("aws-cloudfront") DeployProviderTypeAWSCloudFront = DeployProviderType("aws-cloudfront")
DeployProviderTypeAzureKeyVault = DeployProviderType("azure-keyvault") DeployProviderTypeAzureKeyVault = DeployProviderType("azure-keyvault")
DeployProviderTypeBaiduCloudAppBLB = DeployProviderType("baiducloud-appblb")
DeployProviderTypeBaiduCloudBLB = DeployProviderType("baiducloud-blb")
DeployProviderTypeBaiduCloudCDN = DeployProviderType("baiducloud-cdn") DeployProviderTypeBaiduCloudCDN = DeployProviderType("baiducloud-cdn")
DeployProviderTypeBaiduCloudCert = DeployProviderType("baiducloud-cert")
DeployProviderTypeBaishanCDN = DeployProviderType("baishan-cdn") DeployProviderTypeBaishanCDN = DeployProviderType("baishan-cdn")
DeployProviderTypeBaotaPanelConsole = DeployProviderType("baotapanel-console") DeployProviderTypeBaotaPanelConsole = DeployProviderType("baotapanel-console")
DeployProviderTypeBaotaPanelSite = DeployProviderType("baotapanel-site") DeployProviderTypeBaotaPanelSite = DeployProviderType("baotapanel-site")
@ -141,6 +151,7 @@ const (
DeployProviderTypeGcoreCDN = DeployProviderType("gcore-cdn") DeployProviderTypeGcoreCDN = DeployProviderType("gcore-cdn")
DeployProviderTypeHuaweiCloudCDN = DeployProviderType("huaweicloud-cdn") DeployProviderTypeHuaweiCloudCDN = DeployProviderType("huaweicloud-cdn")
DeployProviderTypeHuaweiCloudELB = DeployProviderType("huaweicloud-elb") DeployProviderTypeHuaweiCloudELB = DeployProviderType("huaweicloud-elb")
DeployProviderTypeHuaweiCloudSCM = DeployProviderType("huaweicloud-scm")
DeployProviderTypeHuaweiCloudWAF = DeployProviderType("huaweicloud-waf") DeployProviderTypeHuaweiCloudWAF = DeployProviderType("huaweicloud-waf")
DeployProviderTypeJDCloudALB = DeployProviderType("jdcloud-alb") DeployProviderTypeJDCloudALB = DeployProviderType("jdcloud-alb")
DeployProviderTypeJDCloudCDN = DeployProviderType("jdcloud-cdn") DeployProviderTypeJDCloudCDN = DeployProviderType("jdcloud-cdn")
@ -168,7 +179,9 @@ const (
DeployProviderTypeUCloudUS3 = DeployProviderType("ucloud-us3") DeployProviderTypeUCloudUS3 = DeployProviderType("ucloud-us3")
DeployProviderTypeUpyunCDN = DeployProviderType("upyun-cdn") DeployProviderTypeUpyunCDN = DeployProviderType("upyun-cdn")
DeployProviderTypeUpyunFile = DeployProviderType("upyun-file") DeployProviderTypeUpyunFile = DeployProviderType("upyun-file")
DeployProviderTypeVolcEngineALB = DeployProviderType("volcengine-alb")
DeployProviderTypeVolcEngineCDN = DeployProviderType("volcengine-cdn") DeployProviderTypeVolcEngineCDN = DeployProviderType("volcengine-cdn")
DeployProviderTypeVolcEngineCertCenter = DeployProviderType("volcengine-certcenter")
DeployProviderTypeVolcEngineCLB = DeployProviderType("volcengine-clb") DeployProviderTypeVolcEngineCLB = DeployProviderType("volcengine-clb")
DeployProviderTypeVolcEngineDCDN = DeployProviderType("volcengine-dcdn") DeployProviderTypeVolcEngineDCDN = DeployProviderType("volcengine-dcdn")
DeployProviderTypeVolcEngineImageX = DeployProviderType("volcengine-imagex") DeployProviderTypeVolcEngineImageX = DeployProviderType("volcengine-imagex")

View File

@ -6,7 +6,7 @@ import (
"strings" "strings"
"time" "time"
bceDns "github.com/baidubce/bce-sdk-go/services/dns" bcedns "github.com/baidubce/bce-sdk-go/services/dns"
"github.com/go-acme/lego/v4/challenge" "github.com/go-acme/lego/v4/challenge"
"github.com/go-acme/lego/v4/challenge/dns01" "github.com/go-acme/lego/v4/challenge/dns01"
"github.com/go-acme/lego/v4/platform/config/env" "github.com/go-acme/lego/v4/platform/config/env"
@ -38,7 +38,7 @@ type Config struct {
} }
type DNSProvider struct { type DNSProvider struct {
client *bceDns.Client client *bcedns.Client
config *Config config *Config
} }
@ -69,7 +69,7 @@ func NewDNSProviderConfig(config *Config) (*DNSProvider, error) {
return nil, errors.New("baiducloud: the configuration of the DNS provider is nil") return nil, errors.New("baiducloud: the configuration of the DNS provider is nil")
} }
client, err := bceDns.NewClient(config.AccessKeyID, config.SecretAccessKey, "") client, err := bcedns.NewClient(config.AccessKeyID, config.SecretAccessKey, "")
if err != nil { if err != nil {
return nil, err return nil, err
} else { } else {
@ -128,11 +128,11 @@ func (d *DNSProvider) Timeout() (timeout, interval time.Duration) {
return d.config.PropagationTimeout, d.config.PollingInterval return d.config.PropagationTimeout, d.config.PollingInterval
} }
func (d *DNSProvider) getDNSRecord(zoneName, subDomain string) (*bceDns.Record, error) { func (d *DNSProvider) getDNSRecord(zoneName, subDomain string) (*bcedns.Record, error) {
pageMarker := "" pageMarker := ""
pageSize := 1000 pageSize := 1000
for { for {
request := &bceDns.ListRecordRequest{} request := &bcedns.ListRecordRequest{}
request.Rr = subDomain request.Rr = subDomain
request.Marker = pageMarker request.Marker = pageMarker
request.MaxKeys = pageSize request.MaxKeys = pageSize
@ -165,7 +165,7 @@ func (d *DNSProvider) addOrUpdateDNSRecord(zoneName, subDomain, value string) er
} }
if record == nil { if record == nil {
request := &bceDns.CreateRecordRequest{ request := &bcedns.CreateRecordRequest{
Type: "TXT", Type: "TXT",
Rr: subDomain, Rr: subDomain,
Value: value, Value: value,
@ -174,7 +174,7 @@ func (d *DNSProvider) addOrUpdateDNSRecord(zoneName, subDomain, value string) er
err := d.client.CreateRecord(zoneName, request, d.generateClientToken()) err := d.client.CreateRecord(zoneName, request, d.generateClientToken())
return err return err
} else { } else {
request := &bceDns.UpdateRecordRequest{ request := &bcedns.UpdateRecordRequest{
Type: "TXT", Type: "TXT",
Rr: subDomain, Rr: subDomain,
Value: value, Value: value,

View File

@ -106,6 +106,7 @@ func (d *DNSProvider) Present(domain, token, keyAuth string) error {
if err != nil { if err != nil {
return err return err
} }
if record == nil { if record == nil {
// add new record // add new record
resp, err := d.client.CreateRecordOpenapi(&model.CreateRecordOpenapiRequest{ resp, err := d.client.CreateRecordOpenapi(&model.CreateRecordOpenapiRequest{

View File

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

View File

@ -122,8 +122,8 @@ func (d *DNSProvider) Timeout() (timeout, interval time.Duration) {
} }
func (d *DNSProvider) getDNSRecord(zoneName, subDomain string) (*gnamesdk.ResolutionRecord, error) { func (d *DNSProvider) getDNSRecord(zoneName, subDomain string) (*gnamesdk.ResolutionRecord, error) {
page := 1 page := int32(1)
pageSize := 20 pageSize := int32(20)
for { for {
request := &gnamesdk.ListDomainResolutionRequest{} request := &gnamesdk.ListDomainResolutionRequest{}
request.ZoneName = zoneName request.ZoneName = zoneName
@ -166,18 +166,19 @@ func (d *DNSProvider) addOrUpdateDNSRecord(zoneName, subDomain, value string) er
RecordType: "TXT", RecordType: "TXT",
RecordName: subDomain, RecordName: subDomain,
RecordValue: value, RecordValue: value,
TTL: d.config.TTL, TTL: int32(d.config.TTL),
} }
_, err := d.client.AddDomainResolution(request) _, err := d.client.AddDomainResolution(request)
return err return err
} else { } else {
recordId, _ := record.ID.Int64()
request := &gnamesdk.ModifyDomainResolutionRequest{ request := &gnamesdk.ModifyDomainResolutionRequest{
ID: record.ID, ID: recordId,
ZoneName: zoneName, ZoneName: zoneName,
RecordType: "TXT", RecordType: "TXT",
RecordName: subDomain, RecordName: subDomain,
RecordValue: value, RecordValue: value,
TTL: d.config.TTL, TTL: int32(d.config.TTL),
} }
_, err := d.client.ModifyDomainResolution(request) _, err := d.client.ModifyDomainResolution(request)
return err return err
@ -194,9 +195,10 @@ func (d *DNSProvider) removeDNSRecord(zoneName, subDomain string) error {
return nil return nil
} }
recordId, _ := record.ID.Int64()
request := &gnamesdk.DeleteDomainResolutionRequest{ request := &gnamesdk.DeleteDomainResolutionRequest{
ZoneName: zoneName, ZoneName: zoneName,
RecordID: record.ID, RecordID: recordId,
} }
_, err = d.client.DeleteDomainResolution(request) _, err = d.client.DeleteDomainResolution(request)
return err return err

View File

@ -8,10 +8,10 @@ import (
"github.com/go-acme/lego/v4/challenge" "github.com/go-acme/lego/v4/challenge"
"github.com/go-acme/lego/v4/challenge/dns01" "github.com/go-acme/lego/v4/challenge/dns01"
"github.com/go-acme/lego/v4/platform/config/env" "github.com/go-acme/lego/v4/platform/config/env"
jdCore "github.com/jdcloud-api/jdcloud-sdk-go/core" jdcore "github.com/jdcloud-api/jdcloud-sdk-go/core"
jdDnsApi "github.com/jdcloud-api/jdcloud-sdk-go/services/domainservice/apis" jddnsapi "github.com/jdcloud-api/jdcloud-sdk-go/services/domainservice/apis"
jdDnsClient "github.com/jdcloud-api/jdcloud-sdk-go/services/domainservice/client" jddnsclient "github.com/jdcloud-api/jdcloud-sdk-go/services/domainservice/client"
jdDnsModel "github.com/jdcloud-api/jdcloud-sdk-go/services/domainservice/models" jddnsmodel "github.com/jdcloud-api/jdcloud-sdk-go/services/domainservice/models"
) )
const ( const (
@ -41,7 +41,7 @@ type Config struct {
} }
type DNSProvider struct { type DNSProvider struct {
client *jdDnsClient.DomainserviceClient client *jddnsclient.DomainserviceClient
config *Config config *Config
} }
@ -73,12 +73,12 @@ func NewDNSProviderConfig(config *Config) (*DNSProvider, error) {
return nil, errors.New("jdcloud: the configuration of the DNS provider is nil") return nil, errors.New("jdcloud: the configuration of the DNS provider is nil")
} }
clientCredentials := jdCore.NewCredentials(config.AccessKeyID, config.AccessKeySecret) clientCredentials := jdcore.NewCredentials(config.AccessKeyID, config.AccessKeySecret)
client := jdDnsClient.NewDomainserviceClient(clientCredentials) client := jddnsclient.NewDomainserviceClient(clientCredentials)
clientConfig := &client.Config clientConfig := &client.Config
clientConfig.SetTimeout(config.HTTPTimeout) clientConfig.SetTimeout(config.HTTPTimeout)
client.SetConfig(clientConfig) client.SetConfig(clientConfig)
client.SetLogger(jdCore.NewDefaultLogger(jdCore.LogWarn)) client.SetLogger(jdcore.NewDefaultLogger(jdcore.LogWarn))
return &DNSProvider{ return &DNSProvider{
client: client, client: client,
@ -130,11 +130,11 @@ func (d *DNSProvider) Timeout() (timeout, interval time.Duration) {
return d.config.PropagationTimeout, d.config.PollingInterval return d.config.PropagationTimeout, d.config.PollingInterval
} }
func (d *DNSProvider) getDNSZone(zoneName string) (*jdDnsModel.DomainInfo, error) { func (d *DNSProvider) getDNSZone(zoneName string) (*jddnsmodel.DomainInfo, error) {
pageNumber := 1 pageNumber := 1
pageSize := 10 pageSize := 10
for { for {
request := jdDnsApi.NewDescribeDomainsRequest(d.config.RegionId, pageNumber, pageSize) request := jddnsapi.NewDescribeDomainsRequest(d.config.RegionId, pageNumber, pageSize)
request.SetDomainName(zoneName) request.SetDomainName(zoneName)
response, err := d.client.DescribeDomains(request) response, err := d.client.DescribeDomains(request)
@ -158,7 +158,7 @@ func (d *DNSProvider) getDNSZone(zoneName string) (*jdDnsModel.DomainInfo, error
return nil, fmt.Errorf("jdcloud: zone %s not found", zoneName) return nil, fmt.Errorf("jdcloud: zone %s not found", zoneName)
} }
func (d *DNSProvider) getDNSZoneAndRecord(zoneName, subDomain string) (*jdDnsModel.DomainInfo, *jdDnsModel.RRInfo, error) { func (d *DNSProvider) getDNSZoneAndRecord(zoneName, subDomain string) (*jddnsmodel.DomainInfo, *jddnsmodel.RRInfo, error) {
zone, err := d.getDNSZone(zoneName) zone, err := d.getDNSZone(zoneName)
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err
@ -167,7 +167,7 @@ func (d *DNSProvider) getDNSZoneAndRecord(zoneName, subDomain string) (*jdDnsMod
pageNumber := 1 pageNumber := 1
pageSize := 10 pageSize := 10
for { for {
request := jdDnsApi.NewDescribeResourceRecordRequest(d.config.RegionId, fmt.Sprintf("%d", zone.Id)) request := jddnsapi.NewDescribeResourceRecordRequest(d.config.RegionId, fmt.Sprintf("%d", zone.Id))
request.SetSearch(subDomain) request.SetSearch(subDomain)
request.SetPageNumber(pageNumber) request.SetPageNumber(pageNumber)
request.SetPageSize(pageSize) request.SetPageSize(pageSize)
@ -200,7 +200,7 @@ func (d *DNSProvider) addOrUpdateDNSRecord(zoneName, subDomain, value string) er
} }
if record == nil { if record == nil {
request := jdDnsApi.NewCreateResourceRecordRequest(d.config.RegionId, fmt.Sprintf("%d", zone.Id), &jdDnsModel.AddRR{ request := jddnsapi.NewCreateResourceRecordRequest(d.config.RegionId, fmt.Sprintf("%d", zone.Id), &jddnsmodel.AddRR{
Type: "TXT", Type: "TXT",
HostRecord: subDomain, HostRecord: subDomain,
HostValue: value, HostValue: value,
@ -210,7 +210,7 @@ func (d *DNSProvider) addOrUpdateDNSRecord(zoneName, subDomain, value string) er
_, err := d.client.CreateResourceRecord(request) _, err := d.client.CreateResourceRecord(request)
return err return err
} else { } else {
request := jdDnsApi.NewModifyResourceRecordRequest(d.config.RegionId, fmt.Sprintf("%d", zone.Id), fmt.Sprintf("%d", record.Id), &jdDnsModel.UpdateRR{ request := jddnsapi.NewModifyResourceRecordRequest(d.config.RegionId, fmt.Sprintf("%d", zone.Id), fmt.Sprintf("%d", record.Id), &jddnsmodel.UpdateRR{
Type: "TXT", Type: "TXT",
HostRecord: subDomain, HostRecord: subDomain,
HostValue: value, HostValue: value,
@ -231,7 +231,7 @@ func (d *DNSProvider) removeDNSRecord(zoneName, subDomain string) error {
if record == nil { if record == nil {
return nil return nil
} else { } else {
request := jdDnsApi.NewDeleteResourceRecordRequest(d.config.RegionId, fmt.Sprintf("%d", zone.Id), fmt.Sprintf("%d", record.Id)) request := jddnsapi.NewDeleteResourceRecordRequest(d.config.RegionId, fmt.Sprintf("%d", zone.Id), fmt.Sprintf("%d", record.Id))
_, err = d.client.DeleteResourceRecord(request) _, err = d.client.DeleteResourceRecord(request)
return err return err
} }

View File

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

View File

@ -1,4 +1,4 @@
package namesilo package powerdns
import ( import (
"net/url" "net/url"

View File

@ -0,0 +1,207 @@
package lego_tencentcloudeo
import (
"errors"
"fmt"
"math"
"strings"
"time"
"github.com/go-acme/lego/v4/challenge"
"github.com/go-acme/lego/v4/challenge/dns01"
"github.com/go-acme/lego/v4/platform/config/env"
"github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common"
"github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/profile"
teo "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/teo/v20220901"
)
const (
envNamespace = "TENCENTCLOUDEO_"
EnvSecretID = envNamespace + "SECRET_ID"
EnvSecretKey = envNamespace + "SECRET_KEY"
EnvZoneId = envNamespace + "ZONE_ID"
EnvTTL = envNamespace + "TTL"
EnvPropagationTimeout = envNamespace + "PROPAGATION_TIMEOUT"
EnvPollingInterval = envNamespace + "POLLING_INTERVAL"
EnvHTTPTimeout = envNamespace + "HTTP_TIMEOUT"
)
var _ challenge.ProviderTimeout = (*DNSProvider)(nil)
type Config struct {
SecretID string
SecretKey string
ZoneId string
PropagationTimeout time.Duration
PollingInterval time.Duration
TTL int32
HTTPTimeout time.Duration
}
type DNSProvider struct {
client *teo.Client
config *Config
}
func NewDefaultConfig() *Config {
return &Config{
TTL: int32(env.GetOrDefaultInt(EnvTTL, 300)),
PropagationTimeout: env.GetOrDefaultSecond(EnvPropagationTimeout, 2*time.Minute),
PollingInterval: env.GetOrDefaultSecond(EnvPollingInterval, dns01.DefaultPollingInterval),
HTTPTimeout: env.GetOrDefaultSecond(EnvHTTPTimeout, 30*time.Second),
}
}
func NewDNSProvider() (*DNSProvider, error) {
values, err := env.Get(EnvSecretID, EnvSecretKey, EnvZoneId)
if err != nil {
return nil, fmt.Errorf("tencentcloud-eo: %w", err)
}
config := NewDefaultConfig()
config.SecretID = values[EnvSecretID]
config.SecretKey = values[EnvSecretKey]
config.ZoneId = values[EnvSecretKey]
return NewDNSProviderConfig(config)
}
func NewDNSProviderConfig(config *Config) (*DNSProvider, error) {
if config == nil {
return nil, errors.New("tencentcloud-eo: the configuration of the DNS provider is nil")
}
credential := common.NewCredential(config.SecretID, config.SecretKey)
cpf := profile.NewClientProfile()
cpf.HttpProfile.ReqTimeout = int(math.Round(config.HTTPTimeout.Seconds()))
client, err := teo.NewClient(credential, "", cpf)
if err != nil {
return nil, err
}
return &DNSProvider{
client: client,
config: config,
}, nil
}
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 {
return fmt.Errorf("tencentcloud-eo: %w", err)
}
return nil
}
func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error {
info := dns01.GetChallengeInfo(domain, keyAuth)
if err := d.removeDNSRecord(strings.TrimRight(info.EffectiveFQDN, ".")); err != nil {
return fmt.Errorf("tencentcloud-eo: %w", err)
}
return nil
}
func (d *DNSProvider) Timeout() (timeout, interval time.Duration) {
return d.config.PropagationTimeout, d.config.PollingInterval
}
func (d *DNSProvider) getDNSRecord(effectiveFQDN string) (*teo.DnsRecord, error) {
pageOffset := 0
pageLimit := 1000
for {
request := teo.NewDescribeDnsRecordsRequest()
request.ZoneId = common.StringPtr(d.config.ZoneId)
request.Offset = common.Int64Ptr(int64(pageOffset))
request.Limit = common.Int64Ptr(int64(pageLimit))
request.Filters = []*teo.AdvancedFilter{
{
Name: common.StringPtr("type"),
Values: []*string{common.StringPtr("TXT")},
},
}
response, err := d.client.DescribeDnsRecords(request)
if err != nil {
return nil, err
}
if response.Response == nil {
break
} else {
for _, record := range response.Response.DnsRecords {
if *record.Name == effectiveFQDN {
return record, nil
}
}
if len(response.Response.DnsRecords) < int(pageLimit) {
break
}
pageOffset += len(response.Response.DnsRecords)
}
}
return nil, nil
}
func (d *DNSProvider) addOrUpdateDNSRecord(effectiveFQDN, value string) error {
record, err := d.getDNSRecord(effectiveFQDN)
if err != nil {
return err
}
if record == nil {
request := teo.NewCreateDnsRecordRequest()
request.ZoneId = common.StringPtr(d.config.ZoneId)
request.Name = common.StringPtr(effectiveFQDN)
request.Type = common.StringPtr("TXT")
request.Content = common.StringPtr(value)
request.TTL = common.Int64Ptr(int64(d.config.TTL))
_, err := d.client.CreateDnsRecord(request)
return err
} else {
record.Content = common.StringPtr(value)
request := teo.NewModifyDnsRecordsRequest()
request.ZoneId = common.StringPtr(d.config.ZoneId)
request.DnsRecords = []*teo.DnsRecord{record}
if _, err := d.client.ModifyDnsRecords(request); err != nil {
return err
}
if *record.Status == "disable" {
request := teo.NewModifyDnsRecordsStatusRequest()
request.ZoneId = common.StringPtr(d.config.ZoneId)
request.RecordsToEnable = []*string{record.RecordId}
if _, err = d.client.ModifyDnsRecordsStatus(request); err != nil {
return err
}
}
return nil
}
}
func (d *DNSProvider) removeDNSRecord(effectiveFQDN string) error {
record, err := d.getDNSRecord(effectiveFQDN)
if err != nil {
return err
}
if record == nil {
return nil
} else {
request := teo.NewDeleteDnsRecordsRequest()
request.ZoneId = common.StringPtr(d.config.ZoneId)
request.RecordIds = []*string{record.RecordId}
_, err = d.client.DeleteDnsRecords(request)
return err
}
}

View File

@ -0,0 +1,41 @@
package tencentcloudeo
import (
"time"
"github.com/go-acme/lego/v4/challenge"
internal "github.com/usual2970/certimate/internal/pkg/core/applicant/acme-dns-01/lego-providers/tencentcloud-eo/internal"
)
type ChallengeProviderConfig struct {
SecretId string `json:"secretId"`
SecretKey string `json:"secretKey"`
ZoneId string `json:"zoneId"`
DnsPropagationTimeout int32 `json:"dnsPropagationTimeout,omitempty"`
DnsTTL int32 `json:"dnsTTL,omitempty"`
}
func NewChallengeProvider(config *ChallengeProviderConfig) (challenge.Provider, error) {
if config == nil {
panic("config is nil")
}
providerConfig := internal.NewDefaultConfig()
providerConfig.SecretID = config.SecretId
providerConfig.SecretKey = config.SecretKey
providerConfig.ZoneId = config.ZoneId
if config.DnsPropagationTimeout != 0 {
providerConfig.PropagationTimeout = time.Duration(config.DnsPropagationTimeout) * time.Second
}
if config.DnsTTL != 0 {
providerConfig.TTL = config.DnsTTL
}
provider, err := internal.NewDNSProviderConfig(providerConfig)
if err != nil {
return nil, err
}
return provider, nil
}

View File

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

View File

@ -9,9 +9,9 @@ import (
"strings" "strings"
"time" "time"
aliyunAlb "github.com/alibabacloud-go/alb-20200616/v2/client" alialb "github.com/alibabacloud-go/alb-20200616/v2/client"
aliyunCas "github.com/alibabacloud-go/cas-20200407/v3/client" alicas "github.com/alibabacloud-go/cas-20200407/v3/client"
aliyunOpen "github.com/alibabacloud-go/darabonba-openapi/v2/client" aliopen "github.com/alibabacloud-go/darabonba-openapi/v2/client"
"github.com/alibabacloud-go/tea/tea" "github.com/alibabacloud-go/tea/tea"
xerrors "github.com/pkg/errors" xerrors "github.com/pkg/errors"
"golang.org/x/exp/slices" "golang.org/x/exp/slices"
@ -51,8 +51,8 @@ type DeployerProvider struct {
var _ deployer.Deployer = (*DeployerProvider)(nil) var _ deployer.Deployer = (*DeployerProvider)(nil)
type wSdkClients struct { type wSdkClients struct {
alb *aliyunAlb.Client ALB *alialb.Client
cas *aliyunCas.Client CAS *alicas.Client
} }
func NewDeployer(config *DeployerConfig) (*DeployerProvider, error) { func NewDeployer(config *DeployerConfig) (*DeployerProvider, error) {
@ -123,10 +123,10 @@ func (d *DeployerProvider) deployToLoadbalancer(ctx context.Context, cloudCertId
// 查询负载均衡实例的详细信息 // 查询负载均衡实例的详细信息
// REF: https://help.aliyun.com/zh/slb/application-load-balancer/developer-reference/api-alb-2020-06-16-getloadbalancerattribute // REF: https://help.aliyun.com/zh/slb/application-load-balancer/developer-reference/api-alb-2020-06-16-getloadbalancerattribute
getLoadBalancerAttributeReq := &aliyunAlb.GetLoadBalancerAttributeRequest{ getLoadBalancerAttributeReq := &alialb.GetLoadBalancerAttributeRequest{
LoadBalancerId: tea.String(d.config.LoadbalancerId), LoadBalancerId: tea.String(d.config.LoadbalancerId),
} }
getLoadBalancerAttributeResp, err := d.sdkClients.alb.GetLoadBalancerAttribute(getLoadBalancerAttributeReq) getLoadBalancerAttributeResp, err := d.sdkClients.ALB.GetLoadBalancerAttribute(getLoadBalancerAttributeReq)
d.logger.Debug("sdk request 'alb.GetLoadBalancerAttribute'", slog.Any("request", getLoadBalancerAttributeReq), slog.Any("response", getLoadBalancerAttributeResp)) d.logger.Debug("sdk request 'alb.GetLoadBalancerAttribute'", slog.Any("request", getLoadBalancerAttributeReq), slog.Any("response", getLoadBalancerAttributeResp))
if err != nil { if err != nil {
return xerrors.Wrap(err, "failed to execute sdk request 'alb.GetLoadBalancerAttribute'") return xerrors.Wrap(err, "failed to execute sdk request 'alb.GetLoadBalancerAttribute'")
@ -138,13 +138,13 @@ func (d *DeployerProvider) deployToLoadbalancer(ctx context.Context, cloudCertId
listListenersLimit := int32(100) listListenersLimit := int32(100)
var listListenersToken *string = nil var listListenersToken *string = nil
for { for {
listListenersReq := &aliyunAlb.ListListenersRequest{ listListenersReq := &alialb.ListListenersRequest{
MaxResults: tea.Int32(listListenersLimit), MaxResults: tea.Int32(listListenersLimit),
NextToken: listListenersToken, NextToken: listListenersToken,
LoadBalancerIds: []*string{tea.String(d.config.LoadbalancerId)}, LoadBalancerIds: []*string{tea.String(d.config.LoadbalancerId)},
ListenerProtocol: tea.String("HTTPS"), ListenerProtocol: tea.String("HTTPS"),
} }
listListenersResp, err := d.sdkClients.alb.ListListeners(listListenersReq) listListenersResp, err := d.sdkClients.ALB.ListListeners(listListenersReq)
d.logger.Debug("sdk request 'alb.ListListeners'", slog.Any("request", listListenersReq), slog.Any("response", listListenersResp)) d.logger.Debug("sdk request 'alb.ListListeners'", slog.Any("request", listListenersReq), slog.Any("response", listListenersResp))
if err != nil { if err != nil {
return xerrors.Wrap(err, "failed to execute sdk request 'alb.ListListeners'") return xerrors.Wrap(err, "failed to execute sdk request 'alb.ListListeners'")
@ -167,13 +167,13 @@ func (d *DeployerProvider) deployToLoadbalancer(ctx context.Context, cloudCertId
// REF: https://help.aliyun.com/zh/slb/application-load-balancer/developer-reference/api-alb-2020-06-16-listlisteners // REF: https://help.aliyun.com/zh/slb/application-load-balancer/developer-reference/api-alb-2020-06-16-listlisteners
listListenersToken = nil listListenersToken = nil
for { for {
listListenersReq := &aliyunAlb.ListListenersRequest{ listListenersReq := &alialb.ListListenersRequest{
MaxResults: tea.Int32(listListenersLimit), MaxResults: tea.Int32(listListenersLimit),
NextToken: listListenersToken, NextToken: listListenersToken,
LoadBalancerIds: []*string{tea.String(d.config.LoadbalancerId)}, LoadBalancerIds: []*string{tea.String(d.config.LoadbalancerId)},
ListenerProtocol: tea.String("QUIC"), ListenerProtocol: tea.String("QUIC"),
} }
listListenersResp, err := d.sdkClients.alb.ListListeners(listListenersReq) listListenersResp, err := d.sdkClients.ALB.ListListeners(listListenersReq)
d.logger.Debug("sdk request 'alb.ListListeners'", slog.Any("request", listListenersReq), slog.Any("response", listListenersResp)) d.logger.Debug("sdk request 'alb.ListListeners'", slog.Any("request", listListenersReq), slog.Any("response", listListenersResp))
if err != nil { if err != nil {
return xerrors.Wrap(err, "failed to execute sdk request 'alb.ListListeners'") return xerrors.Wrap(err, "failed to execute sdk request 'alb.ListListeners'")
@ -229,10 +229,10 @@ func (d *DeployerProvider) deployToListener(ctx context.Context, cloudCertId str
func (d *DeployerProvider) updateListenerCertificate(ctx context.Context, cloudListenerId string, cloudCertId string) error { func (d *DeployerProvider) updateListenerCertificate(ctx context.Context, cloudListenerId string, cloudCertId string) error {
// 查询监听的属性 // 查询监听的属性
// REF: https://help.aliyun.com/zh/slb/application-load-balancer/developer-reference/api-alb-2020-06-16-getlistenerattribute // REF: https://help.aliyun.com/zh/slb/application-load-balancer/developer-reference/api-alb-2020-06-16-getlistenerattribute
getListenerAttributeReq := &aliyunAlb.GetListenerAttributeRequest{ getListenerAttributeReq := &alialb.GetListenerAttributeRequest{
ListenerId: tea.String(cloudListenerId), ListenerId: tea.String(cloudListenerId),
} }
getListenerAttributeResp, err := d.sdkClients.alb.GetListenerAttribute(getListenerAttributeReq) getListenerAttributeResp, err := d.sdkClients.ALB.GetListenerAttribute(getListenerAttributeReq)
d.logger.Debug("sdk request 'alb.GetListenerAttribute'", slog.Any("request", getListenerAttributeReq), slog.Any("response", getListenerAttributeResp)) d.logger.Debug("sdk request 'alb.GetListenerAttribute'", slog.Any("request", getListenerAttributeReq), slog.Any("response", getListenerAttributeResp))
if err != nil { if err != nil {
return xerrors.Wrap(err, "failed to execute sdk request 'alb.GetListenerAttribute'") return xerrors.Wrap(err, "failed to execute sdk request 'alb.GetListenerAttribute'")
@ -243,13 +243,13 @@ func (d *DeployerProvider) updateListenerCertificate(ctx context.Context, cloudL
// 修改监听的属性 // 修改监听的属性
// REF: https://help.aliyun.com/zh/slb/application-load-balancer/developer-reference/api-alb-2020-06-16-updatelistenerattribute // REF: https://help.aliyun.com/zh/slb/application-load-balancer/developer-reference/api-alb-2020-06-16-updatelistenerattribute
updateListenerAttributeReq := &aliyunAlb.UpdateListenerAttributeRequest{ updateListenerAttributeReq := &alialb.UpdateListenerAttributeRequest{
ListenerId: tea.String(cloudListenerId), ListenerId: tea.String(cloudListenerId),
Certificates: []*aliyunAlb.UpdateListenerAttributeRequestCertificates{{ Certificates: []*alialb.UpdateListenerAttributeRequestCertificates{{
CertificateId: tea.String(cloudCertId), CertificateId: tea.String(cloudCertId),
}}, }},
} }
updateListenerAttributeResp, err := d.sdkClients.alb.UpdateListenerAttribute(updateListenerAttributeReq) updateListenerAttributeResp, err := d.sdkClients.ALB.UpdateListenerAttribute(updateListenerAttributeReq)
d.logger.Debug("sdk request 'alb.UpdateListenerAttribute'", slog.Any("request", updateListenerAttributeReq), slog.Any("response", updateListenerAttributeResp)) d.logger.Debug("sdk request 'alb.UpdateListenerAttribute'", slog.Any("request", updateListenerAttributeReq), slog.Any("response", updateListenerAttributeResp))
if err != nil { if err != nil {
return xerrors.Wrap(err, "failed to execute sdk request 'alb.UpdateListenerAttribute'") return xerrors.Wrap(err, "failed to execute sdk request 'alb.UpdateListenerAttribute'")
@ -259,17 +259,17 @@ func (d *DeployerProvider) updateListenerCertificate(ctx context.Context, cloudL
// 查询监听证书列表 // 查询监听证书列表
// REF: https://help.aliyun.com/zh/slb/application-load-balancer/developer-reference/api-alb-2020-06-16-listlistenercertificates // REF: https://help.aliyun.com/zh/slb/application-load-balancer/developer-reference/api-alb-2020-06-16-listlistenercertificates
listenerCertificates := make([]aliyunAlb.ListListenerCertificatesResponseBodyCertificates, 0) listenerCertificates := make([]alialb.ListListenerCertificatesResponseBodyCertificates, 0)
listListenerCertificatesLimit := int32(100) listListenerCertificatesLimit := int32(100)
var listListenerCertificatesToken *string = nil var listListenerCertificatesToken *string = nil
for { for {
listListenerCertificatesReq := &aliyunAlb.ListListenerCertificatesRequest{ listListenerCertificatesReq := &alialb.ListListenerCertificatesRequest{
NextToken: listListenerCertificatesToken, NextToken: listListenerCertificatesToken,
MaxResults: tea.Int32(listListenerCertificatesLimit), MaxResults: tea.Int32(listListenerCertificatesLimit),
ListenerId: tea.String(cloudListenerId), ListenerId: tea.String(cloudListenerId),
CertificateType: tea.String("Server"), CertificateType: tea.String("Server"),
} }
listListenerCertificatesResp, err := d.sdkClients.alb.ListListenerCertificates(listListenerCertificatesReq) listListenerCertificatesResp, err := d.sdkClients.ALB.ListListenerCertificates(listListenerCertificatesReq)
d.logger.Debug("sdk request 'alb.ListListenerCertificates'", slog.Any("request", listListenerCertificatesReq), slog.Any("response", listListenerCertificatesResp)) d.logger.Debug("sdk request 'alb.ListListenerCertificates'", slog.Any("request", listListenerCertificatesReq), slog.Any("response", listListenerCertificatesResp))
if err != nil { if err != nil {
return xerrors.Wrap(err, "failed to execute sdk request 'alb.ListListenerCertificates'") return xerrors.Wrap(err, "failed to execute sdk request 'alb.ListListenerCertificates'")
@ -291,52 +291,62 @@ func (d *DeployerProvider) updateListenerCertificate(ctx context.Context, cloudL
// 遍历查询监听证书,并找出需要解除关联的证书 // 遍历查询监听证书,并找出需要解除关联的证书
// REF: https://help.aliyun.com/zh/slb/application-load-balancer/developer-reference/api-alb-2020-06-16-listlistenercertificates // REF: https://help.aliyun.com/zh/slb/application-load-balancer/developer-reference/api-alb-2020-06-16-listlistenercertificates
// REF: https://help.aliyun.com/zh/ssl-certificate/developer-reference/api-cas-2020-04-07-getusercertificatedetail // REF: https://help.aliyun.com/zh/ssl-certificate/developer-reference/api-cas-2020-04-07-getusercertificatedetail
certificateIsAssociated := false certificateIsAlreadyAssociated := false
certificateIdsExpired := make([]string, 0) certificateIdsToDissociate := make([]string, 0)
if len(listenerCertificates) > 0 { if len(listenerCertificates) > 0 {
d.logger.Info("found listener certificates to deploy", slog.Any("listenerCertificates", listenerCertificates)) d.logger.Info("found listener certificates to deploy", slog.Any("listenerCertificates", listenerCertificates))
var errs []error var errs []error
for _, listenerCertificate := range listenerCertificates { for _, listenerCertificate := range listenerCertificates {
// 监听证书 ID 格式:${证书 ID}-${地域} if tea.BoolValue(listenerCertificate.IsDefault) {
certificateId := strings.Split(*listenerCertificate.CertificateId, "-")[0]
if certificateId == cloudCertId {
certificateIsAssociated = true
continue continue
} }
if *listenerCertificate.IsDefault || !strings.EqualFold(*listenerCertificate.Status, "Associated") { if !strings.EqualFold(tea.StringValue(listenerCertificate.Status), "Associated") {
continue continue
} }
// 监听证书 ID 格式:${证书 ID}-${地域}
certificateId := strings.Split(tea.StringValue(listenerCertificate.CertificateId), "-")[0]
if certificateId == cloudCertId {
certificateIsAlreadyAssociated = true
break
}
certificateIdAsInt64, err := strconv.ParseInt(certificateId, 10, 64) certificateIdAsInt64, err := strconv.ParseInt(certificateId, 10, 64)
if err != nil { if err != nil {
errs = append(errs, err) errs = append(errs, err)
continue continue
} }
getUserCertificateDetailReq := &aliyunCas.GetUserCertificateDetailRequest{ getUserCertificateDetailReq := &alicas.GetUserCertificateDetailRequest{
CertId: tea.Int64(certificateIdAsInt64), CertId: tea.Int64(certificateIdAsInt64),
} }
getUserCertificateDetailResp, err := d.sdkClients.cas.GetUserCertificateDetail(getUserCertificateDetailReq) getUserCertificateDetailResp, err := d.sdkClients.CAS.GetUserCertificateDetail(getUserCertificateDetailReq)
d.logger.Debug("sdk request 'cas.GetUserCertificateDetail'", slog.Any("request", getUserCertificateDetailReq), slog.Any("response", getUserCertificateDetailResp)) d.logger.Debug("sdk request 'cas.GetUserCertificateDetail'", slog.Any("request", getUserCertificateDetailReq), slog.Any("response", getUserCertificateDetailResp))
if err != nil { if err != nil {
if sdkerr, ok := err.(*tea.SDKError); ok {
if tea.IntValue(sdkerr.StatusCode) == 400 && tea.StringValue(sdkerr.Code) == "NotFound" {
continue
}
}
errs = append(errs, xerrors.Wrap(err, "failed to execute sdk request 'cas.GetUserCertificateDetail'")) errs = append(errs, xerrors.Wrap(err, "failed to execute sdk request 'cas.GetUserCertificateDetail'"))
continue continue
} } else {
certCNMatched := tea.StringValue(getUserCertificateDetailResp.Body.Common) == d.config.Domain
certCnMatched := getUserCertificateDetailResp.Body.Common != nil && *getUserCertificateDetailResp.Body.Common == d.config.Domain certSANMatched := slices.Contains(strings.Split(tea.StringValue(getUserCertificateDetailResp.Body.Sans), ","), d.config.Domain)
certSanMatched := getUserCertificateDetailResp.Body.Sans != nil && slices.Contains(strings.Split(*getUserCertificateDetailResp.Body.Sans, ","), d.config.Domain) if !certCNMatched && !certSANMatched {
if !certCnMatched && !certSanMatched {
continue continue
} }
certEndDate, _ := time.Parse("2006-01-02", *getUserCertificateDetailResp.Body.EndDate) certEndDate, _ := time.Parse("2006-01-02", tea.StringValue(getUserCertificateDetailResp.Body.EndDate))
if time.Now().Before(certEndDate) { if time.Now().Before(certEndDate) {
continue continue
} }
certificateIdsExpired = append(certificateIdsExpired, certificateId) certificateIdsToDissociate = append(certificateIdsToDissociate, certificateId)
}
} }
if len(errs) > 0 { if len(errs) > 0 {
@ -346,16 +356,16 @@ func (d *DeployerProvider) updateListenerCertificate(ctx context.Context, cloudL
// 关联监听和扩展证书 // 关联监听和扩展证书
// REF: https://help.aliyun.com/zh/slb/application-load-balancer/developer-reference/api-alb-2020-06-16-associateadditionalcertificateswithlistener // REF: https://help.aliyun.com/zh/slb/application-load-balancer/developer-reference/api-alb-2020-06-16-associateadditionalcertificateswithlistener
if !certificateIsAssociated { if !certificateIsAlreadyAssociated {
associateAdditionalCertificatesFromListenerReq := &aliyunAlb.AssociateAdditionalCertificatesWithListenerRequest{ associateAdditionalCertificatesFromListenerReq := &alialb.AssociateAdditionalCertificatesWithListenerRequest{
ListenerId: tea.String(cloudListenerId), ListenerId: tea.String(cloudListenerId),
Certificates: []*aliyunAlb.AssociateAdditionalCertificatesWithListenerRequestCertificates{ Certificates: []*alialb.AssociateAdditionalCertificatesWithListenerRequestCertificates{
{ {
CertificateId: tea.String(cloudCertId), CertificateId: tea.String(cloudCertId),
}, },
}, },
} }
associateAdditionalCertificatesFromListenerResp, err := d.sdkClients.alb.AssociateAdditionalCertificatesWithListener(associateAdditionalCertificatesFromListenerReq) associateAdditionalCertificatesFromListenerResp, err := d.sdkClients.ALB.AssociateAdditionalCertificatesWithListener(associateAdditionalCertificatesFromListenerReq)
d.logger.Debug("sdk request 'alb.AssociateAdditionalCertificatesWithListener'", slog.Any("request", associateAdditionalCertificatesFromListenerReq), slog.Any("response", associateAdditionalCertificatesFromListenerResp)) d.logger.Debug("sdk request 'alb.AssociateAdditionalCertificatesWithListener'", slog.Any("request", associateAdditionalCertificatesFromListenerReq), slog.Any("response", associateAdditionalCertificatesFromListenerResp))
if err != nil { if err != nil {
return xerrors.Wrap(err, "failed to execute sdk request 'alb.AssociateAdditionalCertificatesWithListener'") return xerrors.Wrap(err, "failed to execute sdk request 'alb.AssociateAdditionalCertificatesWithListener'")
@ -364,19 +374,19 @@ func (d *DeployerProvider) updateListenerCertificate(ctx context.Context, cloudL
// 解除关联监听和扩展证书 // 解除关联监听和扩展证书
// REF: https://help.aliyun.com/zh/slb/application-load-balancer/developer-reference/api-alb-2020-06-16-dissociateadditionalcertificatesfromlistener // REF: https://help.aliyun.com/zh/slb/application-load-balancer/developer-reference/api-alb-2020-06-16-dissociateadditionalcertificatesfromlistener
if len(certificateIdsExpired) > 0 { if !certificateIsAlreadyAssociated && len(certificateIdsToDissociate) > 0 {
dissociateAdditionalCertificates := make([]*aliyunAlb.DissociateAdditionalCertificatesFromListenerRequestCertificates, 0) dissociateAdditionalCertificates := make([]*alialb.DissociateAdditionalCertificatesFromListenerRequestCertificates, 0)
for _, certificateId := range certificateIdsExpired { for _, certificateId := range certificateIdsToDissociate {
dissociateAdditionalCertificates = append(dissociateAdditionalCertificates, &aliyunAlb.DissociateAdditionalCertificatesFromListenerRequestCertificates{ dissociateAdditionalCertificates = append(dissociateAdditionalCertificates, &alialb.DissociateAdditionalCertificatesFromListenerRequestCertificates{
CertificateId: tea.String(certificateId), CertificateId: tea.String(certificateId),
}) })
} }
dissociateAdditionalCertificatesFromListenerReq := &aliyunAlb.DissociateAdditionalCertificatesFromListenerRequest{ dissociateAdditionalCertificatesFromListenerReq := &alialb.DissociateAdditionalCertificatesFromListenerRequest{
ListenerId: tea.String(cloudListenerId), ListenerId: tea.String(cloudListenerId),
Certificates: dissociateAdditionalCertificates, Certificates: dissociateAdditionalCertificates,
} }
dissociateAdditionalCertificatesFromListenerResp, err := d.sdkClients.alb.DissociateAdditionalCertificatesFromListener(dissociateAdditionalCertificatesFromListenerReq) dissociateAdditionalCertificatesFromListenerResp, err := d.sdkClients.ALB.DissociateAdditionalCertificatesFromListener(dissociateAdditionalCertificatesFromListenerReq)
d.logger.Debug("sdk request 'alb.DissociateAdditionalCertificatesFromListener'", slog.Any("request", dissociateAdditionalCertificatesFromListenerReq), slog.Any("response", dissociateAdditionalCertificatesFromListenerResp)) d.logger.Debug("sdk request 'alb.DissociateAdditionalCertificatesFromListener'", slog.Any("request", dissociateAdditionalCertificatesFromListenerReq), slog.Any("response", dissociateAdditionalCertificatesFromListenerResp))
if err != nil { if err != nil {
return xerrors.Wrap(err, "failed to execute sdk request 'alb.DissociateAdditionalCertificatesFromListener'") return xerrors.Wrap(err, "failed to execute sdk request 'alb.DissociateAdditionalCertificatesFromListener'")
@ -397,12 +407,12 @@ func createSdkClients(accessKeyId, accessKeySecret, region string) (*wSdkClients
albEndpoint = fmt.Sprintf("alb.%s.aliyuncs.com", region) albEndpoint = fmt.Sprintf("alb.%s.aliyuncs.com", region)
} }
albConfig := &aliyunOpen.Config{ albConfig := &aliopen.Config{
AccessKeyId: tea.String(accessKeyId), AccessKeyId: tea.String(accessKeyId),
AccessKeySecret: tea.String(accessKeySecret), AccessKeySecret: tea.String(accessKeySecret),
Endpoint: tea.String(albEndpoint), Endpoint: tea.String(albEndpoint),
} }
albClient, err := aliyunAlb.NewClient(albConfig) albClient, err := alialb.NewClient(albConfig)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -415,19 +425,19 @@ func createSdkClients(accessKeyId, accessKeySecret, region string) (*wSdkClients
casEndpoint = "cas.aliyuncs.com" casEndpoint = "cas.aliyuncs.com"
} }
casConfig := &aliyunOpen.Config{ casConfig := &aliopen.Config{
Endpoint: tea.String(casEndpoint), Endpoint: tea.String(casEndpoint),
AccessKeyId: tea.String(accessKeyId), AccessKeyId: tea.String(accessKeyId),
AccessKeySecret: tea.String(accessKeySecret), AccessKeySecret: tea.String(accessKeySecret),
} }
casClient, err := aliyunCas.NewClient(casConfig) casClient, err := alicas.NewClient(casConfig)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return &wSdkClients{ return &wSdkClients{
alb: albClient, ALB: albClient,
cas: casClient, CAS: casClient,
}, nil }, nil
} }

View File

@ -8,8 +8,8 @@ import (
"strings" "strings"
"time" "time"
aliyunCas "github.com/alibabacloud-go/cas-20200407/v3/client" alicas "github.com/alibabacloud-go/cas-20200407/v3/client"
aliyunOpen "github.com/alibabacloud-go/darabonba-openapi/v2/client" aliopen "github.com/alibabacloud-go/darabonba-openapi/v2/client"
"github.com/alibabacloud-go/tea/tea" "github.com/alibabacloud-go/tea/tea"
xerrors "github.com/pkg/errors" xerrors "github.com/pkg/errors"
@ -35,7 +35,7 @@ type DeployerConfig struct {
type DeployerProvider struct { type DeployerProvider struct {
config *DeployerConfig config *DeployerConfig
logger *slog.Logger logger *slog.Logger
sdkClient *aliyunCas.Client sdkClient *alicas.Client
sslUploader uploader.Uploader sslUploader uploader.Uploader
} }
@ -95,7 +95,7 @@ func (d *DeployerProvider) Deploy(ctx context.Context, certPem string, privkeyPe
if len(contactIds) == 0 { if len(contactIds) == 0 {
// 获取联系人列表 // 获取联系人列表
// REF: https://help.aliyun.com/zh/ssl-certificate/developer-reference/api-cas-2020-04-07-listcontact // REF: https://help.aliyun.com/zh/ssl-certificate/developer-reference/api-cas-2020-04-07-listcontact
listContactReq := &aliyunCas.ListContactRequest{} listContactReq := &alicas.ListContactRequest{}
listContactReq.ShowSize = tea.Int32(1) listContactReq.ShowSize = tea.Int32(1)
listContactReq.CurrentPage = tea.Int32(1) listContactReq.CurrentPage = tea.Int32(1)
listContactResp, err := d.sdkClient.ListContact(listContactReq) listContactResp, err := d.sdkClient.ListContact(listContactReq)
@ -111,7 +111,7 @@ func (d *DeployerProvider) Deploy(ctx context.Context, certPem string, privkeyPe
// 创建部署任务 // 创建部署任务
// REF: https://help.aliyun.com/zh/ssl-certificate/developer-reference/api-cas-2020-04-07-createdeploymentjob // REF: https://help.aliyun.com/zh/ssl-certificate/developer-reference/api-cas-2020-04-07-createdeploymentjob
createDeploymentJobReq := &aliyunCas.CreateDeploymentJobRequest{ createDeploymentJobReq := &alicas.CreateDeploymentJobRequest{
Name: tea.String(fmt.Sprintf("certimate-%d", time.Now().UnixMilli())), Name: tea.String(fmt.Sprintf("certimate-%d", time.Now().UnixMilli())),
JobType: tea.String("user"), JobType: tea.String("user"),
CertIds: tea.String(upres.CertId), CertIds: tea.String(upres.CertId),
@ -131,7 +131,7 @@ func (d *DeployerProvider) Deploy(ctx context.Context, certPem string, privkeyPe
return nil, ctx.Err() return nil, ctx.Err()
} }
describeDeploymentJobReq := &aliyunCas.DescribeDeploymentJobRequest{ describeDeploymentJobReq := &alicas.DescribeDeploymentJobRequest{
JobId: createDeploymentJobResp.Body.JobId, JobId: createDeploymentJobResp.Body.JobId,
} }
describeDeploymentJobResp, err := d.sdkClient.DescribeDeploymentJob(describeDeploymentJobReq) describeDeploymentJobResp, err := d.sdkClient.DescribeDeploymentJob(describeDeploymentJobReq)
@ -155,7 +155,7 @@ func (d *DeployerProvider) Deploy(ctx context.Context, certPem string, privkeyPe
return &deployer.DeployResult{}, nil return &deployer.DeployResult{}, nil
} }
func createSdkClient(accessKeyId, accessKeySecret, region string) (*aliyunCas.Client, error) { func createSdkClient(accessKeyId, accessKeySecret, region string) (*alicas.Client, error) {
if region == "" { if region == "" {
region = "cn-hangzhou" // CAS 服务默认区域:华东一杭州 region = "cn-hangzhou" // CAS 服务默认区域:华东一杭州
} }
@ -169,13 +169,13 @@ func createSdkClient(accessKeyId, accessKeySecret, region string) (*aliyunCas.Cl
endpoint = fmt.Sprintf("cas.%s.aliyuncs.com", region) endpoint = fmt.Sprintf("cas.%s.aliyuncs.com", region)
} }
config := &aliyunOpen.Config{ config := &aliopen.Config{
AccessKeyId: tea.String(accessKeyId), AccessKeyId: tea.String(accessKeyId),
AccessKeySecret: tea.String(accessKeySecret), AccessKeySecret: tea.String(accessKeySecret),
Endpoint: tea.String(endpoint), Endpoint: tea.String(endpoint),
} }
client, err := aliyunCas.NewClient(config) client, err := alicas.NewClient(config)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -7,8 +7,8 @@ import (
"strings" "strings"
"time" "time"
aliyunCdn "github.com/alibabacloud-go/cdn-20180510/v5/client" alicdn "github.com/alibabacloud-go/cdn-20180510/v5/client"
aliyunOpen "github.com/alibabacloud-go/darabonba-openapi/v2/client" aliopen "github.com/alibabacloud-go/darabonba-openapi/v2/client"
"github.com/alibabacloud-go/tea/tea" "github.com/alibabacloud-go/tea/tea"
xerrors "github.com/pkg/errors" xerrors "github.com/pkg/errors"
@ -27,7 +27,7 @@ type DeployerConfig struct {
type DeployerProvider struct { type DeployerProvider struct {
config *DeployerConfig config *DeployerConfig
logger *slog.Logger logger *slog.Logger
sdkClient *aliyunCdn.Client sdkClient *alicdn.Client
} }
var _ deployer.Deployer = (*DeployerProvider)(nil) var _ deployer.Deployer = (*DeployerProvider)(nil)
@ -64,7 +64,7 @@ func (d *DeployerProvider) Deploy(ctx context.Context, certPem string, privkeyPe
// 设置 CDN 域名域名证书 // 设置 CDN 域名域名证书
// REF: https://help.aliyun.com/zh/cdn/developer-reference/api-cdn-2018-05-10-setcdndomainsslcertificate // REF: https://help.aliyun.com/zh/cdn/developer-reference/api-cdn-2018-05-10-setcdndomainsslcertificate
setCdnDomainSSLCertificateReq := &aliyunCdn.SetCdnDomainSSLCertificateRequest{ setCdnDomainSSLCertificateReq := &alicdn.SetCdnDomainSSLCertificateRequest{
DomainName: tea.String(domain), DomainName: tea.String(domain),
CertName: tea.String(fmt.Sprintf("certimate-%d", time.Now().UnixMilli())), CertName: tea.String(fmt.Sprintf("certimate-%d", time.Now().UnixMilli())),
CertType: tea.String("upload"), CertType: tea.String("upload"),
@ -81,14 +81,14 @@ func (d *DeployerProvider) Deploy(ctx context.Context, certPem string, privkeyPe
return &deployer.DeployResult{}, nil return &deployer.DeployResult{}, nil
} }
func createSdkClient(accessKeyId, accessKeySecret string) (*aliyunCdn.Client, error) { func createSdkClient(accessKeyId, accessKeySecret string) (*alicdn.Client, error) {
config := &aliyunOpen.Config{ config := &aliopen.Config{
AccessKeyId: tea.String(accessKeyId), AccessKeyId: tea.String(accessKeyId),
AccessKeySecret: tea.String(accessKeySecret), AccessKeySecret: tea.String(accessKeySecret),
Endpoint: tea.String("cdn.aliyuncs.com"), Endpoint: tea.String("cdn.aliyuncs.com"),
} }
client, err := aliyunCdn.NewClient(config) client, err := alicdn.NewClient(config)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -6,8 +6,8 @@ import (
"fmt" "fmt"
"log/slog" "log/slog"
aliyunOpen "github.com/alibabacloud-go/darabonba-openapi/v2/client" aliopen "github.com/alibabacloud-go/darabonba-openapi/v2/client"
aliyunSlb "github.com/alibabacloud-go/slb-20140515/v4/client" alislb "github.com/alibabacloud-go/slb-20140515/v4/client"
"github.com/alibabacloud-go/tea/tea" "github.com/alibabacloud-go/tea/tea"
xerrors "github.com/pkg/errors" xerrors "github.com/pkg/errors"
@ -39,7 +39,7 @@ type DeployerConfig struct {
type DeployerProvider struct { type DeployerProvider struct {
config *DeployerConfig config *DeployerConfig
logger *slog.Logger logger *slog.Logger
sdkClient *aliyunSlb.Client sdkClient *alislb.Client
sslUploader uploader.Uploader sslUploader uploader.Uploader
} }
@ -117,7 +117,7 @@ func (d *DeployerProvider) deployToLoadbalancer(ctx context.Context, cloudCertId
// 查询负载均衡实例的详细信息 // 查询负载均衡实例的详细信息
// REF: https://help.aliyun.com/zh/slb/classic-load-balancer/developer-reference/api-slb-2014-05-15-describeloadbalancerattribute // REF: https://help.aliyun.com/zh/slb/classic-load-balancer/developer-reference/api-slb-2014-05-15-describeloadbalancerattribute
describeLoadBalancerAttributeReq := &aliyunSlb.DescribeLoadBalancerAttributeRequest{ describeLoadBalancerAttributeReq := &alislb.DescribeLoadBalancerAttributeRequest{
RegionId: tea.String(d.config.Region), RegionId: tea.String(d.config.Region),
LoadBalancerId: tea.String(d.config.LoadbalancerId), LoadBalancerId: tea.String(d.config.LoadbalancerId),
} }
@ -133,7 +133,7 @@ func (d *DeployerProvider) deployToLoadbalancer(ctx context.Context, cloudCertId
describeLoadBalancerListenersLimit := int32(100) describeLoadBalancerListenersLimit := int32(100)
var describeLoadBalancerListenersToken *string = nil var describeLoadBalancerListenersToken *string = nil
for { for {
describeLoadBalancerListenersReq := &aliyunSlb.DescribeLoadBalancerListenersRequest{ describeLoadBalancerListenersReq := &alislb.DescribeLoadBalancerListenersRequest{
RegionId: tea.String(d.config.Region), RegionId: tea.String(d.config.Region),
MaxResults: tea.Int32(describeLoadBalancerListenersLimit), MaxResults: tea.Int32(describeLoadBalancerListenersLimit),
NextToken: describeLoadBalancerListenersToken, NextToken: describeLoadBalancerListenersToken,
@ -199,7 +199,7 @@ func (d *DeployerProvider) deployToListener(ctx context.Context, cloudCertId str
func (d *DeployerProvider) updateListenerCertificate(ctx context.Context, cloudLoadbalancerId string, cloudListenerPort int32, cloudCertId string) error { func (d *DeployerProvider) updateListenerCertificate(ctx context.Context, cloudLoadbalancerId string, cloudListenerPort int32, cloudCertId string) error {
// 查询监听配置 // 查询监听配置
// REF: https://help.aliyun.com/zh/slb/classic-load-balancer/developer-reference/api-slb-2014-05-15-describeloadbalancerhttpslistenerattribute // REF: https://help.aliyun.com/zh/slb/classic-load-balancer/developer-reference/api-slb-2014-05-15-describeloadbalancerhttpslistenerattribute
describeLoadBalancerHTTPSListenerAttributeReq := &aliyunSlb.DescribeLoadBalancerHTTPSListenerAttributeRequest{ describeLoadBalancerHTTPSListenerAttributeReq := &alislb.DescribeLoadBalancerHTTPSListenerAttributeRequest{
LoadBalancerId: tea.String(cloudLoadbalancerId), LoadBalancerId: tea.String(cloudLoadbalancerId),
ListenerPort: tea.Int32(cloudListenerPort), ListenerPort: tea.Int32(cloudListenerPort),
} }
@ -214,7 +214,7 @@ func (d *DeployerProvider) updateListenerCertificate(ctx context.Context, cloudL
// 修改监听配置 // 修改监听配置
// REF: https://help.aliyun.com/zh/slb/classic-load-balancer/developer-reference/api-slb-2014-05-15-setloadbalancerhttpslistenerattribute // REF: https://help.aliyun.com/zh/slb/classic-load-balancer/developer-reference/api-slb-2014-05-15-setloadbalancerhttpslistenerattribute
setLoadBalancerHTTPSListenerAttributeReq := &aliyunSlb.SetLoadBalancerHTTPSListenerAttributeRequest{ setLoadBalancerHTTPSListenerAttributeReq := &alislb.SetLoadBalancerHTTPSListenerAttributeRequest{
RegionId: tea.String(d.config.Region), RegionId: tea.String(d.config.Region),
LoadBalancerId: tea.String(cloudLoadbalancerId), LoadBalancerId: tea.String(cloudLoadbalancerId),
ListenerPort: tea.Int32(cloudListenerPort), ListenerPort: tea.Int32(cloudListenerPort),
@ -230,7 +230,7 @@ func (d *DeployerProvider) updateListenerCertificate(ctx context.Context, cloudL
// 查询扩展域名 // 查询扩展域名
// REF: https://help.aliyun.com/zh/slb/classic-load-balancer/developer-reference/api-slb-2014-05-15-describedomainextensions // REF: https://help.aliyun.com/zh/slb/classic-load-balancer/developer-reference/api-slb-2014-05-15-describedomainextensions
describeDomainExtensionsReq := &aliyunSlb.DescribeDomainExtensionsRequest{ describeDomainExtensionsReq := &alislb.DescribeDomainExtensionsRequest{
RegionId: tea.String(d.config.Region), RegionId: tea.String(d.config.Region),
LoadBalancerId: tea.String(cloudLoadbalancerId), LoadBalancerId: tea.String(cloudLoadbalancerId),
ListenerPort: tea.Int32(cloudListenerPort), ListenerPort: tea.Int32(cloudListenerPort),
@ -251,7 +251,7 @@ func (d *DeployerProvider) updateListenerCertificate(ctx context.Context, cloudL
continue continue
} }
setDomainExtensionAttributeReq := &aliyunSlb.SetDomainExtensionAttributeRequest{ setDomainExtensionAttributeReq := &alislb.SetDomainExtensionAttributeRequest{
RegionId: tea.String(d.config.Region), RegionId: tea.String(d.config.Region),
DomainExtensionId: tea.String(*domainExtension.DomainExtensionId), DomainExtensionId: tea.String(*domainExtension.DomainExtensionId),
ServerCertificateId: tea.String(cloudCertId), ServerCertificateId: tea.String(cloudCertId),
@ -273,7 +273,7 @@ func (d *DeployerProvider) updateListenerCertificate(ctx context.Context, cloudL
return nil return nil
} }
func createSdkClient(accessKeyId, accessKeySecret, region string) (*aliyunSlb.Client, error) { func createSdkClient(accessKeyId, accessKeySecret, region string) (*alislb.Client, error) {
// 接入点一览 https://api.aliyun.com/product/Slb // 接入点一览 https://api.aliyun.com/product/Slb
var endpoint string var endpoint string
switch region { switch region {
@ -287,13 +287,13 @@ func createSdkClient(accessKeyId, accessKeySecret, region string) (*aliyunSlb.Cl
endpoint = fmt.Sprintf("slb.%s.aliyuncs.com", region) endpoint = fmt.Sprintf("slb.%s.aliyuncs.com", region)
} }
config := &aliyunOpen.Config{ config := &aliopen.Config{
AccessKeyId: tea.String(accessKeyId), AccessKeyId: tea.String(accessKeyId),
AccessKeySecret: tea.String(accessKeySecret), AccessKeySecret: tea.String(accessKeySecret),
Endpoint: tea.String(endpoint), Endpoint: tea.String(endpoint),
} }
client, err := aliyunSlb.NewClient(config) client, err := alislb.NewClient(config)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -46,7 +46,7 @@ Shell command to run this test:
--CERTIMATE_DEPLOYER_ALIYUNCLB_REGION="cn-hangzhou" \ --CERTIMATE_DEPLOYER_ALIYUNCLB_REGION="cn-hangzhou" \
--CERTIMATE_DEPLOYER_ALIYUNCLB_LOADBALANCERID="your-clb-instance-id" \ --CERTIMATE_DEPLOYER_ALIYUNCLB_LOADBALANCERID="your-clb-instance-id" \
--CERTIMATE_DEPLOYER_ALIYUNCLB_LISTENERPORT=443 \ --CERTIMATE_DEPLOYER_ALIYUNCLB_LISTENERPORT=443 \
--CERTIMATE_DEPLOYER_ALIYUNCLB_DOMAIN="your-alb-sni-domain" --CERTIMATE_DEPLOYER_ALIYUNCLB_DOMAIN="your-clb-sni-domain"
*/ */
func TestDeploy(t *testing.T) { func TestDeploy(t *testing.T) {
flag.Parse() flag.Parse()

View File

@ -7,8 +7,8 @@ import (
"strings" "strings"
"time" "time"
aliyunOpen "github.com/alibabacloud-go/darabonba-openapi/v2/client" aliopen "github.com/alibabacloud-go/darabonba-openapi/v2/client"
aliyunDcdn "github.com/alibabacloud-go/dcdn-20180115/v3/client" alidcdn "github.com/alibabacloud-go/dcdn-20180115/v3/client"
"github.com/alibabacloud-go/tea/tea" "github.com/alibabacloud-go/tea/tea"
xerrors "github.com/pkg/errors" xerrors "github.com/pkg/errors"
@ -27,7 +27,7 @@ type DeployerConfig struct {
type DeployerProvider struct { type DeployerProvider struct {
config *DeployerConfig config *DeployerConfig
logger *slog.Logger logger *slog.Logger
sdkClient *aliyunDcdn.Client sdkClient *alidcdn.Client
} }
var _ deployer.Deployer = (*DeployerProvider)(nil) var _ deployer.Deployer = (*DeployerProvider)(nil)
@ -64,7 +64,7 @@ func (d *DeployerProvider) Deploy(ctx context.Context, certPem string, privkeyPe
// 配置域名证书 // 配置域名证书
// REF: https://help.aliyun.com/zh/edge-security-acceleration/dcdn/developer-reference/api-dcdn-2018-01-15-setdcdndomainsslcertificate // REF: https://help.aliyun.com/zh/edge-security-acceleration/dcdn/developer-reference/api-dcdn-2018-01-15-setdcdndomainsslcertificate
setDcdnDomainSSLCertificateReq := &aliyunDcdn.SetDcdnDomainSSLCertificateRequest{ setDcdnDomainSSLCertificateReq := &alidcdn.SetDcdnDomainSSLCertificateRequest{
DomainName: tea.String(domain), DomainName: tea.String(domain),
CertName: tea.String(fmt.Sprintf("certimate-%d", time.Now().UnixMilli())), CertName: tea.String(fmt.Sprintf("certimate-%d", time.Now().UnixMilli())),
CertType: tea.String("upload"), CertType: tea.String("upload"),
@ -81,14 +81,14 @@ func (d *DeployerProvider) Deploy(ctx context.Context, certPem string, privkeyPe
return &deployer.DeployResult{}, nil return &deployer.DeployResult{}, nil
} }
func createSdkClient(accessKeyId, accessKeySecret string) (*aliyunDcdn.Client, error) { func createSdkClient(accessKeyId, accessKeySecret string) (*alidcdn.Client, error) {
config := &aliyunOpen.Config{ config := &aliopen.Config{
AccessKeyId: tea.String(accessKeyId), AccessKeyId: tea.String(accessKeyId),
AccessKeySecret: tea.String(accessKeySecret), AccessKeySecret: tea.String(accessKeySecret),
Endpoint: tea.String("dcdn.aliyuncs.com"), Endpoint: tea.String("dcdn.aliyuncs.com"),
} }
client, err := aliyunDcdn.NewClient(config) client, err := alidcdn.NewClient(config)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -8,8 +8,8 @@ import (
"strconv" "strconv"
"strings" "strings"
aliyunOpen "github.com/alibabacloud-go/darabonba-openapi/v2/client" aliopen "github.com/alibabacloud-go/darabonba-openapi/v2/client"
aliyunEsa "github.com/alibabacloud-go/esa-20240910/v2/client" aliesa "github.com/alibabacloud-go/esa-20240910/v2/client"
"github.com/alibabacloud-go/tea/tea" "github.com/alibabacloud-go/tea/tea"
xerrors "github.com/pkg/errors" xerrors "github.com/pkg/errors"
@ -32,7 +32,7 @@ type DeployerConfig struct {
type DeployerProvider struct { type DeployerProvider struct {
config *DeployerConfig config *DeployerConfig
logger *slog.Logger logger *slog.Logger
sdkClient *aliyunEsa.Client sdkClient *aliesa.Client
sslUploader uploader.Uploader sslUploader uploader.Uploader
} }
@ -87,7 +87,7 @@ func (d *DeployerProvider) Deploy(ctx context.Context, certPem string, privkeyPe
// 配置站点证书 // 配置站点证书
// REF: https://help.aliyun.com/zh/edge-security-acceleration/esa/api-esa-2024-09-10-setcertificate // REF: https://help.aliyun.com/zh/edge-security-acceleration/esa/api-esa-2024-09-10-setcertificate
certId, _ := strconv.ParseInt(upres.CertId, 10, 64) certId, _ := strconv.ParseInt(upres.CertId, 10, 64)
setCertificateReq := &aliyunEsa.SetCertificateRequest{ setCertificateReq := &aliesa.SetCertificateRequest{
SiteId: tea.Int64(d.config.SiteId), SiteId: tea.Int64(d.config.SiteId),
Type: tea.String("cas"), Type: tea.String("cas"),
CasId: tea.Int64(certId), CasId: tea.Int64(certId),
@ -101,15 +101,15 @@ func (d *DeployerProvider) Deploy(ctx context.Context, certPem string, privkeyPe
return &deployer.DeployResult{}, nil return &deployer.DeployResult{}, nil
} }
func createSdkClient(accessKeyId, accessKeySecret, region string) (*aliyunEsa.Client, error) { func createSdkClient(accessKeyId, accessKeySecret, region string) (*aliesa.Client, error) {
// 接入点一览 https://api.aliyun.com/product/ESA // 接入点一览 https://api.aliyun.com/product/ESA
config := &aliyunOpen.Config{ config := &aliopen.Config{
AccessKeyId: tea.String(accessKeyId), AccessKeyId: tea.String(accessKeyId),
AccessKeySecret: tea.String(accessKeySecret), AccessKeySecret: tea.String(accessKeySecret),
Endpoint: tea.String(fmt.Sprintf("esa.%s.aliyuncs.com", region)), Endpoint: tea.String(fmt.Sprintf("esa.%s.aliyuncs.com", region)),
} }
client, err := aliyunEsa.NewClient(config) client, err := aliesa.NewClient(config)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -6,9 +6,9 @@ import (
"log/slog" "log/slog"
"time" "time"
aliyunOpen "github.com/alibabacloud-go/darabonba-openapi/v2/client" aliopen "github.com/alibabacloud-go/darabonba-openapi/v2/client"
aliyunFc3 "github.com/alibabacloud-go/fc-20230330/v4/client" alifc3 "github.com/alibabacloud-go/fc-20230330/v4/client"
aliyunFc2 "github.com/alibabacloud-go/fc-open-20210406/v2/client" alifc2 "github.com/alibabacloud-go/fc-open-20210406/v2/client"
"github.com/alibabacloud-go/tea/tea" "github.com/alibabacloud-go/tea/tea"
xerrors "github.com/pkg/errors" xerrors "github.com/pkg/errors"
@ -24,7 +24,7 @@ type DeployerConfig struct {
Region string `json:"region"` Region string `json:"region"`
// 服务版本。 // 服务版本。
ServiceVersion string `json:"serviceVersion"` ServiceVersion string `json:"serviceVersion"`
// 自定义域名(支持泛域名)。 // 自定义域名(支持泛域名)。
Domain string `json:"domain"` Domain string `json:"domain"`
} }
@ -37,8 +37,8 @@ type DeployerProvider struct {
var _ deployer.Deployer = (*DeployerProvider)(nil) var _ deployer.Deployer = (*DeployerProvider)(nil)
type wSdkClients struct { type wSdkClients struct {
fc2 *aliyunFc2.Client FC2 *alifc2.Client
fc3 *aliyunFc3.Client FC3 *alifc3.Client
} }
func NewDeployer(config *DeployerConfig) (*DeployerProvider, error) { func NewDeployer(config *DeployerConfig) (*DeployerProvider, error) {
@ -89,7 +89,7 @@ func (d *DeployerProvider) Deploy(ctx context.Context, certPem string, privkeyPe
func (d *DeployerProvider) deployToFC3(ctx context.Context, certPem string, privkeyPem string) error { func (d *DeployerProvider) deployToFC3(ctx context.Context, certPem string, privkeyPem string) error {
// 获取自定义域名 // 获取自定义域名
// REF: https://help.aliyun.com/zh/functioncompute/fc-3-0/developer-reference/api-fc-2023-03-30-getcustomdomain // REF: https://help.aliyun.com/zh/functioncompute/fc-3-0/developer-reference/api-fc-2023-03-30-getcustomdomain
getCustomDomainResp, err := d.sdkClients.fc3.GetCustomDomain(tea.String(d.config.Domain)) getCustomDomainResp, err := d.sdkClients.FC3.GetCustomDomain(tea.String(d.config.Domain))
d.logger.Debug("sdk request 'fc.GetCustomDomain'", slog.Any("response", getCustomDomainResp)) d.logger.Debug("sdk request 'fc.GetCustomDomain'", slog.Any("response", getCustomDomainResp))
if err != nil { if err != nil {
return xerrors.Wrap(err, "failed to execute sdk request 'fc.GetCustomDomain'") return xerrors.Wrap(err, "failed to execute sdk request 'fc.GetCustomDomain'")
@ -97,9 +97,9 @@ func (d *DeployerProvider) deployToFC3(ctx context.Context, certPem string, priv
// 更新自定义域名 // 更新自定义域名
// REF: https://help.aliyun.com/zh/functioncompute/fc-3-0/developer-reference/api-fc-2023-03-30-updatecustomdomain // REF: https://help.aliyun.com/zh/functioncompute/fc-3-0/developer-reference/api-fc-2023-03-30-updatecustomdomain
updateCustomDomainReq := &aliyunFc3.UpdateCustomDomainRequest{ updateCustomDomainReq := &alifc3.UpdateCustomDomainRequest{
Body: &aliyunFc3.UpdateCustomDomainInput{ Body: &alifc3.UpdateCustomDomainInput{
CertConfig: &aliyunFc3.CertConfig{ CertConfig: &alifc3.CertConfig{
CertName: tea.String(fmt.Sprintf("certimate-%d", time.Now().UnixMilli())), CertName: tea.String(fmt.Sprintf("certimate-%d", time.Now().UnixMilli())),
Certificate: tea.String(certPem), Certificate: tea.String(certPem),
PrivateKey: tea.String(privkeyPem), PrivateKey: tea.String(privkeyPem),
@ -108,7 +108,7 @@ func (d *DeployerProvider) deployToFC3(ctx context.Context, certPem string, priv
TlsConfig: getCustomDomainResp.Body.TlsConfig, TlsConfig: getCustomDomainResp.Body.TlsConfig,
}, },
} }
updateCustomDomainResp, err := d.sdkClients.fc3.UpdateCustomDomain(tea.String(d.config.Domain), updateCustomDomainReq) 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)) d.logger.Debug("sdk request 'fc.UpdateCustomDomain'", slog.Any("request", updateCustomDomainReq), slog.Any("response", updateCustomDomainResp))
if err != nil { if err != nil {
return xerrors.Wrap(err, "failed to execute sdk request 'fc.UpdateCustomDomain'") return xerrors.Wrap(err, "failed to execute sdk request 'fc.UpdateCustomDomain'")
@ -120,7 +120,7 @@ func (d *DeployerProvider) deployToFC3(ctx context.Context, certPem string, priv
func (d *DeployerProvider) deployToFC2(ctx context.Context, certPem string, privkeyPem string) error { func (d *DeployerProvider) deployToFC2(ctx context.Context, certPem string, privkeyPem string) error {
// 获取自定义域名 // 获取自定义域名
// REF: https://help.aliyun.com/zh/functioncompute/fc-2-0/developer-reference/api-fc-open-2021-04-06-getcustomdomain // REF: https://help.aliyun.com/zh/functioncompute/fc-2-0/developer-reference/api-fc-open-2021-04-06-getcustomdomain
getCustomDomainResp, err := d.sdkClients.fc2.GetCustomDomain(tea.String(d.config.Domain)) getCustomDomainResp, err := d.sdkClients.FC2.GetCustomDomain(tea.String(d.config.Domain))
d.logger.Debug("sdk request 'fc.GetCustomDomain'", slog.Any("response", getCustomDomainResp)) d.logger.Debug("sdk request 'fc.GetCustomDomain'", slog.Any("response", getCustomDomainResp))
if err != nil { if err != nil {
return xerrors.Wrap(err, "failed to execute sdk request 'fc.GetCustomDomain'") return xerrors.Wrap(err, "failed to execute sdk request 'fc.GetCustomDomain'")
@ -128,8 +128,8 @@ func (d *DeployerProvider) deployToFC2(ctx context.Context, certPem string, priv
// 更新自定义域名 // 更新自定义域名
// REF: https://help.aliyun.com/zh/functioncompute/fc-2-0/developer-reference/api-fc-open-2021-04-06-updatecustomdomain // REF: https://help.aliyun.com/zh/functioncompute/fc-2-0/developer-reference/api-fc-open-2021-04-06-updatecustomdomain
updateCustomDomainReq := &aliyunFc2.UpdateCustomDomainRequest{ updateCustomDomainReq := &alifc2.UpdateCustomDomainRequest{
CertConfig: &aliyunFc2.CertConfig{ CertConfig: &alifc2.CertConfig{
CertName: tea.String(fmt.Sprintf("certimate-%d", time.Now().UnixMilli())), CertName: tea.String(fmt.Sprintf("certimate-%d", time.Now().UnixMilli())),
Certificate: tea.String(certPem), Certificate: tea.String(certPem),
PrivateKey: tea.String(privkeyPem), PrivateKey: tea.String(privkeyPem),
@ -137,7 +137,7 @@ func (d *DeployerProvider) deployToFC2(ctx context.Context, certPem string, priv
Protocol: getCustomDomainResp.Body.Protocol, Protocol: getCustomDomainResp.Body.Protocol,
TlsConfig: getCustomDomainResp.Body.TlsConfig, TlsConfig: getCustomDomainResp.Body.TlsConfig,
} }
updateCustomDomainResp, err := d.sdkClients.fc2.UpdateCustomDomain(tea.String(d.config.Domain), updateCustomDomainReq) 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)) d.logger.Debug("sdk request 'fc.UpdateCustomDomain'", slog.Any("request", updateCustomDomainReq), slog.Any("response", updateCustomDomainResp))
if err != nil { if err != nil {
return xerrors.Wrap(err, "failed to execute sdk request 'fc.UpdateCustomDomain'") return xerrors.Wrap(err, "failed to execute sdk request 'fc.UpdateCustomDomain'")
@ -156,30 +156,30 @@ func createSdkClients(accessKeyId, accessKeySecret, region string) (*wSdkClients
fc2Endpoint = fmt.Sprintf("fc.%s.aliyuncs.com", region) fc2Endpoint = fmt.Sprintf("fc.%s.aliyuncs.com", region)
} }
fc2Config := &aliyunOpen.Config{ fc2Config := &aliopen.Config{
AccessKeyId: tea.String(accessKeyId), AccessKeyId: tea.String(accessKeyId),
AccessKeySecret: tea.String(accessKeySecret), AccessKeySecret: tea.String(accessKeySecret),
Endpoint: tea.String(fc2Endpoint), Endpoint: tea.String(fc2Endpoint),
} }
fc2Client, err := aliyunFc2.NewClient(fc2Config) fc2Client, err := alifc2.NewClient(fc2Config)
if err != nil { if err != nil {
return nil, err return nil, err
} }
// 接入点一览 https://api.aliyun.com/product/FC-Open // 接入点一览 https://api.aliyun.com/product/FC-Open
fc3Endpoint := fmt.Sprintf("fcv3.%s.aliyuncs.com", region) fc3Endpoint := fmt.Sprintf("fcv3.%s.aliyuncs.com", region)
fc3Config := &aliyunOpen.Config{ fc3Config := &aliopen.Config{
AccessKeyId: tea.String(accessKeyId), AccessKeyId: tea.String(accessKeyId),
AccessKeySecret: tea.String(accessKeySecret), AccessKeySecret: tea.String(accessKeySecret),
Endpoint: tea.String(fc3Endpoint), Endpoint: tea.String(fc3Endpoint),
} }
fc3Client, err := aliyunFc3.NewClient(fc3Config) fc3Client, err := alifc3.NewClient(fc3Config)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return &wSdkClients{ return &wSdkClients{
fc2: fc2Client, FC2: fc2Client,
fc3: fc3Client, FC3: fc3Client,
}, nil }, nil
} }

View File

@ -7,8 +7,8 @@ import (
"strings" "strings"
"time" "time"
aliyunOpen "github.com/alibabacloud-go/darabonba-openapi/v2/client" aliopen "github.com/alibabacloud-go/darabonba-openapi/v2/client"
aliyunLive "github.com/alibabacloud-go/live-20161101/client" alilive "github.com/alibabacloud-go/live-20161101/client"
"github.com/alibabacloud-go/tea/tea" "github.com/alibabacloud-go/tea/tea"
xerrors "github.com/pkg/errors" xerrors "github.com/pkg/errors"
@ -29,7 +29,7 @@ type DeployerConfig struct {
type DeployerProvider struct { type DeployerProvider struct {
config *DeployerConfig config *DeployerConfig
logger *slog.Logger logger *slog.Logger
sdkClient *aliyunLive.Client sdkClient *alilive.Client
} }
var _ deployer.Deployer = (*DeployerProvider)(nil) var _ deployer.Deployer = (*DeployerProvider)(nil)
@ -66,7 +66,7 @@ func (d *DeployerProvider) Deploy(ctx context.Context, certPem string, privkeyPe
// 设置域名证书 // 设置域名证书
// REF: https://help.aliyun.com/zh/live/developer-reference/api-live-2016-11-01-setlivedomaincertificate // REF: https://help.aliyun.com/zh/live/developer-reference/api-live-2016-11-01-setlivedomaincertificate
setLiveDomainSSLCertificateReq := &aliyunLive.SetLiveDomainCertificateRequest{ setLiveDomainSSLCertificateReq := &alilive.SetLiveDomainCertificateRequest{
DomainName: tea.String(domain), DomainName: tea.String(domain),
CertName: tea.String(fmt.Sprintf("certimate-%d", time.Now().UnixMilli())), CertName: tea.String(fmt.Sprintf("certimate-%d", time.Now().UnixMilli())),
CertType: tea.String("upload"), CertType: tea.String("upload"),
@ -83,7 +83,7 @@ func (d *DeployerProvider) Deploy(ctx context.Context, certPem string, privkeyPe
return &deployer.DeployResult{}, nil return &deployer.DeployResult{}, nil
} }
func createSdkClient(accessKeyId, accessKeySecret, region string) (*aliyunLive.Client, error) { func createSdkClient(accessKeyId, accessKeySecret, region string) (*alilive.Client, error) {
// 接入点一览 https://api.aliyun.com/product/live // 接入点一览 https://api.aliyun.com/product/live
var endpoint string var endpoint string
switch region { switch region {
@ -100,13 +100,13 @@ func createSdkClient(accessKeyId, accessKeySecret, region string) (*aliyunLive.C
endpoint = fmt.Sprintf("live.%s.aliyuncs.com", region) endpoint = fmt.Sprintf("live.%s.aliyuncs.com", region)
} }
config := &aliyunOpen.Config{ config := &aliopen.Config{
AccessKeyId: tea.String(accessKeyId), AccessKeyId: tea.String(accessKeyId),
AccessKeySecret: tea.String(accessKeySecret), AccessKeySecret: tea.String(accessKeySecret),
Endpoint: tea.String(endpoint), Endpoint: tea.String(endpoint),
} }
client, err := aliyunLive.NewClient(config) client, err := alilive.NewClient(config)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -7,8 +7,8 @@ import (
"log/slog" "log/slog"
"strings" "strings"
aliyunOpen "github.com/alibabacloud-go/darabonba-openapi/v2/client" aliopen "github.com/alibabacloud-go/darabonba-openapi/v2/client"
aliyunNlb "github.com/alibabacloud-go/nlb-20220430/v2/client" alinlb "github.com/alibabacloud-go/nlb-20220430/v2/client"
"github.com/alibabacloud-go/tea/tea" "github.com/alibabacloud-go/tea/tea"
xerrors "github.com/pkg/errors" xerrors "github.com/pkg/errors"
@ -37,7 +37,7 @@ type DeployerConfig struct {
type DeployerProvider struct { type DeployerProvider struct {
config *DeployerConfig config *DeployerConfig
logger *slog.Logger logger *slog.Logger
sdkClient *aliyunNlb.Client sdkClient *alinlb.Client
sslUploader uploader.Uploader sslUploader uploader.Uploader
} }
@ -111,7 +111,7 @@ func (d *DeployerProvider) deployToLoadbalancer(ctx context.Context, cloudCertId
// 查询负载均衡实例的详细信息 // 查询负载均衡实例的详细信息
// REF: https://help.aliyun.com/zh/slb/network-load-balancer/developer-reference/api-nlb-2022-04-30-getloadbalancerattribute // REF: https://help.aliyun.com/zh/slb/network-load-balancer/developer-reference/api-nlb-2022-04-30-getloadbalancerattribute
getLoadBalancerAttributeReq := &aliyunNlb.GetLoadBalancerAttributeRequest{ getLoadBalancerAttributeReq := &alinlb.GetLoadBalancerAttributeRequest{
LoadBalancerId: tea.String(d.config.LoadbalancerId), LoadBalancerId: tea.String(d.config.LoadbalancerId),
} }
getLoadBalancerAttributeResp, err := d.sdkClient.GetLoadBalancerAttribute(getLoadBalancerAttributeReq) getLoadBalancerAttributeResp, err := d.sdkClient.GetLoadBalancerAttribute(getLoadBalancerAttributeReq)
@ -126,7 +126,7 @@ func (d *DeployerProvider) deployToLoadbalancer(ctx context.Context, cloudCertId
listListenersLimit := int32(100) listListenersLimit := int32(100)
var listListenersToken *string = nil var listListenersToken *string = nil
for { for {
listListenersReq := &aliyunNlb.ListListenersRequest{ listListenersReq := &alinlb.ListListenersRequest{
MaxResults: tea.Int32(listListenersLimit), MaxResults: tea.Int32(listListenersLimit),
NextToken: listListenersToken, NextToken: listListenersToken,
LoadBalancerIds: []*string{tea.String(d.config.LoadbalancerId)}, LoadBalancerIds: []*string{tea.String(d.config.LoadbalancerId)},
@ -188,7 +188,7 @@ func (d *DeployerProvider) deployToListener(ctx context.Context, cloudCertId str
func (d *DeployerProvider) updateListenerCertificate(ctx context.Context, cloudListenerId string, cloudCertId string) error { func (d *DeployerProvider) updateListenerCertificate(ctx context.Context, cloudListenerId string, cloudCertId string) error {
// 查询监听的属性 // 查询监听的属性
// REF: https://help.aliyun.com/zh/slb/network-load-balancer/developer-reference/api-nlb-2022-04-30-getlistenerattribute // REF: https://help.aliyun.com/zh/slb/network-load-balancer/developer-reference/api-nlb-2022-04-30-getlistenerattribute
getListenerAttributeReq := &aliyunNlb.GetListenerAttributeRequest{ getListenerAttributeReq := &alinlb.GetListenerAttributeRequest{
ListenerId: tea.String(cloudListenerId), ListenerId: tea.String(cloudListenerId),
} }
getListenerAttributeResp, err := d.sdkClient.GetListenerAttribute(getListenerAttributeReq) getListenerAttributeResp, err := d.sdkClient.GetListenerAttribute(getListenerAttributeReq)
@ -199,7 +199,7 @@ func (d *DeployerProvider) updateListenerCertificate(ctx context.Context, cloudL
// 修改监听的属性 // 修改监听的属性
// REF: https://help.aliyun.com/zh/slb/network-load-balancer/developer-reference/api-nlb-2022-04-30-updatelistenerattribute // REF: https://help.aliyun.com/zh/slb/network-load-balancer/developer-reference/api-nlb-2022-04-30-updatelistenerattribute
updateListenerAttributeReq := &aliyunNlb.UpdateListenerAttributeRequest{ updateListenerAttributeReq := &alinlb.UpdateListenerAttributeRequest{
ListenerId: tea.String(cloudListenerId), ListenerId: tea.String(cloudListenerId),
CertificateIds: []*string{tea.String(cloudCertId)}, CertificateIds: []*string{tea.String(cloudCertId)},
} }
@ -212,7 +212,7 @@ func (d *DeployerProvider) updateListenerCertificate(ctx context.Context, cloudL
return nil return nil
} }
func createSdkClient(accessKeyId, accessKeySecret, region string) (*aliyunNlb.Client, error) { func createSdkClient(accessKeyId, accessKeySecret, region string) (*alinlb.Client, error) {
// 接入点一览 https://api.aliyun.com/product/Nlb // 接入点一览 https://api.aliyun.com/product/Nlb
var endpoint string var endpoint string
switch region { switch region {
@ -220,13 +220,13 @@ func createSdkClient(accessKeyId, accessKeySecret, region string) (*aliyunNlb.Cl
endpoint = fmt.Sprintf("nlb.%s.aliyuncs.com", region) endpoint = fmt.Sprintf("nlb.%s.aliyuncs.com", region)
} }
config := &aliyunOpen.Config{ config := &aliopen.Config{
AccessKeyId: tea.String(accessKeyId), AccessKeyId: tea.String(accessKeyId),
AccessKeySecret: tea.String(accessKeySecret), AccessKeySecret: tea.String(accessKeySecret),
Endpoint: tea.String(endpoint), Endpoint: tea.String(endpoint),
} }
client, err := aliyunNlb.NewClient(config) client, err := alinlb.NewClient(config)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -6,9 +6,9 @@ import (
"log/slog" "log/slog"
"time" "time"
aliyunOpen "github.com/alibabacloud-go/darabonba-openapi/v2/client" aliopen "github.com/alibabacloud-go/darabonba-openapi/v2/client"
"github.com/alibabacloud-go/tea/tea" "github.com/alibabacloud-go/tea/tea"
aliyunVod "github.com/alibabacloud-go/vod-20170321/v4/client" alivod "github.com/alibabacloud-go/vod-20170321/v4/client"
xerrors "github.com/pkg/errors" xerrors "github.com/pkg/errors"
"github.com/usual2970/certimate/internal/pkg/core/deployer" "github.com/usual2970/certimate/internal/pkg/core/deployer"
@ -28,7 +28,7 @@ type DeployerConfig struct {
type DeployerProvider struct { type DeployerProvider struct {
config *DeployerConfig config *DeployerConfig
logger *slog.Logger logger *slog.Logger
sdkClient *aliyunVod.Client sdkClient *alivod.Client
} }
var _ deployer.Deployer = (*DeployerProvider)(nil) var _ deployer.Deployer = (*DeployerProvider)(nil)
@ -62,7 +62,7 @@ func (d *DeployerProvider) WithLogger(logger *slog.Logger) deployer.Deployer {
func (d *DeployerProvider) Deploy(ctx context.Context, certPem string, privkeyPem string) (*deployer.DeployResult, error) { func (d *DeployerProvider) Deploy(ctx context.Context, certPem string, privkeyPem string) (*deployer.DeployResult, error) {
// 设置域名证书 // 设置域名证书
// REF: https://help.aliyun.com/zh/vod/developer-reference/api-vod-2017-03-21-setvoddomainsslcertificate // REF: https://help.aliyun.com/zh/vod/developer-reference/api-vod-2017-03-21-setvoddomainsslcertificate
setVodDomainSSLCertificateReq := &aliyunVod.SetVodDomainSSLCertificateRequest{ setVodDomainSSLCertificateReq := &alivod.SetVodDomainSSLCertificateRequest{
DomainName: tea.String(d.config.Domain), DomainName: tea.String(d.config.Domain),
CertName: tea.String(fmt.Sprintf("certimate-%d", time.Now().UnixMilli())), CertName: tea.String(fmt.Sprintf("certimate-%d", time.Now().UnixMilli())),
CertType: tea.String("upload"), CertType: tea.String("upload"),
@ -79,17 +79,17 @@ func (d *DeployerProvider) Deploy(ctx context.Context, certPem string, privkeyPe
return &deployer.DeployResult{}, nil return &deployer.DeployResult{}, nil
} }
func createSdkClient(accessKeyId, accessKeySecret, region string) (*aliyunVod.Client, error) { func createSdkClient(accessKeyId, accessKeySecret, region string) (*alivod.Client, error) {
// 接入点一览 https://api.aliyun.com/product/vod // 接入点一览 https://api.aliyun.com/product/vod
endpoint := fmt.Sprintf("vod.%s.aliyuncs.com", region) endpoint := fmt.Sprintf("vod.%s.aliyuncs.com", region)
config := &aliyunOpen.Config{ config := &aliopen.Config{
AccessKeyId: tea.String(accessKeyId), AccessKeyId: tea.String(accessKeyId),
AccessKeySecret: tea.String(accessKeySecret), AccessKeySecret: tea.String(accessKeySecret),
Endpoint: tea.String(endpoint), Endpoint: tea.String(endpoint),
} }
client, err := aliyunVod.NewClient(config) client, err := alivod.NewClient(config)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -7,14 +7,15 @@ import (
"log/slog" "log/slog"
"strings" "strings"
aliyunOpen "github.com/alibabacloud-go/darabonba-openapi/v2/client" aliopen "github.com/alibabacloud-go/darabonba-openapi/v2/client"
"github.com/alibabacloud-go/tea/tea" "github.com/alibabacloud-go/tea/tea"
aliyunWaf "github.com/alibabacloud-go/waf-openapi-20211001/v5/client" aliwaf "github.com/alibabacloud-go/waf-openapi-20211001/v5/client"
xerrors "github.com/pkg/errors" xerrors "github.com/pkg/errors"
"github.com/usual2970/certimate/internal/pkg/core/deployer" "github.com/usual2970/certimate/internal/pkg/core/deployer"
"github.com/usual2970/certimate/internal/pkg/core/uploader" "github.com/usual2970/certimate/internal/pkg/core/uploader"
uploadersp "github.com/usual2970/certimate/internal/pkg/core/uploader/providers/aliyun-cas" uploadersp "github.com/usual2970/certimate/internal/pkg/core/uploader/providers/aliyun-cas"
"github.com/usual2970/certimate/internal/pkg/utils/sliceutil"
) )
type DeployerConfig struct { type DeployerConfig struct {
@ -35,7 +36,7 @@ type DeployerConfig struct {
type DeployerProvider struct { type DeployerProvider struct {
config *DeployerConfig config *DeployerConfig
logger *slog.Logger logger *slog.Logger
sdkClient *aliyunWaf.Client sdkClient *aliwaf.Client
sslUploader uploader.Uploader sslUploader uploader.Uploader
} }
@ -106,7 +107,7 @@ func (d *DeployerProvider) deployToWAF3(ctx context.Context, certPem string, pri
// 查询默认 SSL/TLS 设置 // 查询默认 SSL/TLS 设置
// REF: https://help.aliyun.com/zh/waf/web-application-firewall-3-0/developer-reference/api-waf-openapi-2021-10-01-describedefaulthttps // REF: https://help.aliyun.com/zh/waf/web-application-firewall-3-0/developer-reference/api-waf-openapi-2021-10-01-describedefaulthttps
describeDefaultHttpsReq := &aliyunWaf.DescribeDefaultHttpsRequest{ describeDefaultHttpsReq := &aliwaf.DescribeDefaultHttpsRequest{
InstanceId: tea.String(d.config.InstanceId), InstanceId: tea.String(d.config.InstanceId),
RegionId: tea.String(d.config.Region), RegionId: tea.String(d.config.Region),
} }
@ -118,7 +119,7 @@ func (d *DeployerProvider) deployToWAF3(ctx context.Context, certPem string, pri
// 修改默认 SSL/TLS 设置 // 修改默认 SSL/TLS 设置
// REF: https://help.aliyun.com/zh/waf/web-application-firewall-3-0/developer-reference/api-waf-openapi-2021-10-01-modifydefaulthttps // REF: https://help.aliyun.com/zh/waf/web-application-firewall-3-0/developer-reference/api-waf-openapi-2021-10-01-modifydefaulthttps
modifyDefaultHttpsReq := &aliyunWaf.ModifyDefaultHttpsRequest{ modifyDefaultHttpsReq := &aliwaf.ModifyDefaultHttpsRequest{
InstanceId: tea.String(d.config.InstanceId), InstanceId: tea.String(d.config.InstanceId),
RegionId: tea.String(d.config.Region), RegionId: tea.String(d.config.Region),
CertId: tea.String(upres.CertId), CertId: tea.String(upres.CertId),
@ -139,7 +140,7 @@ func (d *DeployerProvider) deployToWAF3(ctx context.Context, certPem string, pri
// 查询 CNAME 接入详情 // 查询 CNAME 接入详情
// REF: https://help.aliyun.com/zh/waf/web-application-firewall-3-0/developer-reference/api-waf-openapi-2021-10-01-describedomaindetail // REF: https://help.aliyun.com/zh/waf/web-application-firewall-3-0/developer-reference/api-waf-openapi-2021-10-01-describedomaindetail
describeDomainDetailReq := &aliyunWaf.DescribeDomainDetailRequest{ describeDomainDetailReq := &aliwaf.DescribeDomainDetailRequest{
InstanceId: tea.String(d.config.InstanceId), InstanceId: tea.String(d.config.InstanceId),
RegionId: tea.String(d.config.Region), RegionId: tea.String(d.config.Region),
Domain: tea.String(d.config.Domain), Domain: tea.String(d.config.Domain),
@ -152,30 +153,14 @@ func (d *DeployerProvider) deployToWAF3(ctx context.Context, certPem string, pri
// 修改 CNAME 接入资源 // 修改 CNAME 接入资源
// REF: https://help.aliyun.com/zh/waf/web-application-firewall-3-0/developer-reference/api-waf-openapi-2021-10-01-modifydomain // REF: https://help.aliyun.com/zh/waf/web-application-firewall-3-0/developer-reference/api-waf-openapi-2021-10-01-modifydomain
modifyDomainReq := &aliyunWaf.ModifyDomainRequest{ modifyDomainReq := &aliwaf.ModifyDomainRequest{
InstanceId: tea.String(d.config.InstanceId), InstanceId: tea.String(d.config.InstanceId),
RegionId: tea.String(d.config.Region), RegionId: tea.String(d.config.Region),
Domain: tea.String(d.config.Domain), Domain: tea.String(d.config.Domain),
Listen: &aliyunWaf.ModifyDomainRequestListen{ Listen: &aliwaf.ModifyDomainRequestListen{CertId: tea.String(upres.CertId)},
CertId: tea.String(upres.CertId), Redirect: &aliwaf.ModifyDomainRequestRedirect{Loadbalance: tea.String("iphash")},
TLSVersion: tea.String("tlsv1"),
EnableTLSv3: tea.Bool(false),
},
Redirect: &aliyunWaf.ModifyDomainRequestRedirect{
Loadbalance: tea.String("iphash"),
},
}
if describeDomainDetailResp.Body != nil && describeDomainDetailResp.Body.Listen != nil {
modifyDomainReq.Listen.TLSVersion = describeDomainDetailResp.Body.Listen.TLSVersion
modifyDomainReq.Listen.EnableTLSv3 = describeDomainDetailResp.Body.Listen.EnableTLSv3
modifyDomainReq.Listen.FocusHttps = describeDomainDetailResp.Body.Listen.FocusHttps
}
if describeDomainDetailResp.Body != nil && describeDomainDetailResp.Body.Redirect != nil {
modifyDomainReq.Redirect.Loadbalance = describeDomainDetailResp.Body.Redirect.Loadbalance
modifyDomainReq.Redirect.FocusHttpBackend = describeDomainDetailResp.Body.Redirect.FocusHttpBackend
modifyDomainReq.Redirect.SniEnabled = describeDomainDetailResp.Body.Redirect.SniEnabled
modifyDomainReq.Redirect.SniHost = describeDomainDetailResp.Body.Redirect.SniHost
} }
modifyDomainReq = assign(modifyDomainReq, describeDomainDetailResp.Body)
modifyDomainResp, err := d.sdkClient.ModifyDomain(modifyDomainReq) modifyDomainResp, err := d.sdkClient.ModifyDomain(modifyDomainReq)
d.logger.Debug("sdk request 'waf.ModifyDomain'", slog.Any("request", modifyDomainReq), slog.Any("response", modifyDomainResp)) d.logger.Debug("sdk request 'waf.ModifyDomain'", slog.Any("request", modifyDomainReq), slog.Any("response", modifyDomainResp))
if err != nil { if err != nil {
@ -186,15 +171,15 @@ func (d *DeployerProvider) deployToWAF3(ctx context.Context, certPem string, pri
return nil return nil
} }
func createSdkClient(accessKeyId, accessKeySecret, region string) (*aliyunWaf.Client, error) { func createSdkClient(accessKeyId, accessKeySecret, region string) (*aliwaf.Client, error) {
// 接入点一览https://api.aliyun.com/product/waf-openapi // 接入点一览https://api.aliyun.com/product/waf-openapi
config := &aliyunOpen.Config{ config := &aliopen.Config{
AccessKeyId: tea.String(accessKeyId), AccessKeyId: tea.String(accessKeyId),
AccessKeySecret: tea.String(accessKeySecret), AccessKeySecret: tea.String(accessKeySecret),
Endpoint: tea.String(fmt.Sprintf("wafopenapi.%s.aliyuncs.com", region)), Endpoint: tea.String(fmt.Sprintf("wafopenapi.%s.aliyuncs.com", region)),
} }
client, err := aliyunWaf.NewClient(config) client, err := aliwaf.NewClient(config)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -222,3 +207,166 @@ func createSslUploader(accessKeyId, accessKeySecret, region string) (uploader.Up
}) })
return uploader, err return uploader, err
} }
func assign(source *aliwaf.ModifyDomainRequest, target *aliwaf.DescribeDomainDetailResponseBody) *aliwaf.ModifyDomainRequest {
// `ModifyDomain` 中不传的字段表示使用默认值、而非保留原值,
// 因此这里需要把原配置中的参数重新赋值回去。
if target == nil {
return source
}
if target.Listen != nil {
if source.Listen == nil {
source.Listen = &aliwaf.ModifyDomainRequestListen{}
}
if target.Listen.CipherSuite != nil {
source.Listen.CipherSuite = tea.Int32(int32(*target.Listen.CipherSuite))
}
if target.Listen.CustomCiphers != nil {
source.Listen.CustomCiphers = target.Listen.CustomCiphers
}
if target.Listen.EnableTLSv3 != nil {
source.Listen.EnableTLSv3 = target.Listen.EnableTLSv3
}
if target.Listen.ExclusiveIp != nil {
source.Listen.ExclusiveIp = target.Listen.ExclusiveIp
}
if target.Listen.FocusHttps != nil {
source.Listen.FocusHttps = target.Listen.FocusHttps
}
if target.Listen.Http2Enabled != nil {
source.Listen.Http2Enabled = target.Listen.Http2Enabled
}
if target.Listen.HttpPorts != nil {
source.Listen.HttpPorts = sliceutil.Map(target.Listen.HttpPorts, func(v *int64) *int32 {
if v == nil {
return nil
}
return tea.Int32(int32(*v))
})
}
if target.Listen.HttpsPorts != nil {
source.Listen.HttpsPorts = sliceutil.Map(target.Listen.HttpsPorts, func(v *int64) *int32 {
if v == nil {
return nil
}
return tea.Int32(int32(*v))
})
}
if target.Listen.IPv6Enabled != nil {
source.Listen.IPv6Enabled = target.Listen.IPv6Enabled
}
if target.Listen.ProtectionResource != nil {
source.Listen.ProtectionResource = target.Listen.ProtectionResource
}
if target.Listen.TLSVersion != nil {
source.Listen.TLSVersion = target.Listen.TLSVersion
}
if target.Listen.XffHeaderMode != nil {
source.Listen.XffHeaderMode = tea.Int32(int32(*target.Listen.XffHeaderMode))
}
if target.Listen.XffHeaders != nil {
source.Listen.XffHeaders = target.Listen.XffHeaders
}
}
if target.Redirect != nil {
if source.Redirect == nil {
source.Redirect = &aliwaf.ModifyDomainRequestRedirect{}
}
if target.Redirect.Backends != nil {
source.Redirect.Backends = sliceutil.Map(target.Redirect.Backends, func(v *aliwaf.DescribeDomainDetailResponseBodyRedirectBackends) *string {
if v == nil {
return nil
}
return v.Backend
})
}
if target.Redirect.BackupBackends != nil {
source.Redirect.BackupBackends = sliceutil.Map(target.Redirect.BackupBackends, func(v *aliwaf.DescribeDomainDetailResponseBodyRedirectBackupBackends) *string {
if v == nil {
return nil
}
return v.Backend
})
}
if target.Redirect.ConnectTimeout != nil {
source.Redirect.ConnectTimeout = target.Redirect.ConnectTimeout
}
if target.Redirect.FocusHttpBackend != nil {
source.Redirect.FocusHttpBackend = target.Redirect.FocusHttpBackend
}
if target.Redirect.Keepalive != nil {
source.Redirect.Keepalive = target.Redirect.Keepalive
}
if target.Redirect.KeepaliveRequests != nil {
source.Redirect.KeepaliveRequests = target.Redirect.KeepaliveRequests
}
if target.Redirect.KeepaliveTimeout != nil {
source.Redirect.KeepaliveTimeout = target.Redirect.KeepaliveTimeout
}
if target.Redirect.Loadbalance != nil {
source.Redirect.Loadbalance = target.Redirect.Loadbalance
}
if target.Redirect.ReadTimeout != nil {
source.Redirect.ReadTimeout = target.Redirect.ReadTimeout
}
if target.Redirect.RequestHeaders != nil {
source.Redirect.RequestHeaders = sliceutil.Map(target.Redirect.RequestHeaders, func(v *aliwaf.DescribeDomainDetailResponseBodyRedirectRequestHeaders) *aliwaf.ModifyDomainRequestRedirectRequestHeaders {
if v == nil {
return nil
}
return &aliwaf.ModifyDomainRequestRedirectRequestHeaders{
Key: v.Key,
Value: v.Value,
}
})
}
if target.Redirect.Retry != nil {
source.Redirect.Retry = target.Redirect.Retry
}
if target.Redirect.SniEnabled != nil {
source.Redirect.SniEnabled = target.Redirect.SniEnabled
}
if target.Redirect.SniHost != nil {
source.Redirect.SniHost = target.Redirect.SniHost
}
if target.Redirect.WriteTimeout != nil {
source.Redirect.WriteTimeout = target.Redirect.WriteTimeout
}
if target.Redirect.XffProto != nil {
source.Redirect.XffProto = target.Redirect.XffProto
}
}
return source
}

View File

@ -6,10 +6,10 @@ import (
"log/slog" "log/slog"
aws "github.com/aws/aws-sdk-go-v2/aws" aws "github.com/aws/aws-sdk-go-v2/aws"
awsCfg "github.com/aws/aws-sdk-go-v2/config" awscfg "github.com/aws/aws-sdk-go-v2/config"
awsCred "github.com/aws/aws-sdk-go-v2/credentials" awscred "github.com/aws/aws-sdk-go-v2/credentials"
awsCf "github.com/aws/aws-sdk-go-v2/service/cloudfront" "github.com/aws/aws-sdk-go-v2/service/cloudfront"
awsCfTypes "github.com/aws/aws-sdk-go-v2/service/cloudfront/types" "github.com/aws/aws-sdk-go-v2/service/cloudfront/types"
xerrors "github.com/pkg/errors" xerrors "github.com/pkg/errors"
"github.com/usual2970/certimate/internal/pkg/core/deployer" "github.com/usual2970/certimate/internal/pkg/core/deployer"
@ -31,7 +31,7 @@ type DeployerConfig struct {
type DeployerProvider struct { type DeployerProvider struct {
config *DeployerConfig config *DeployerConfig
logger *slog.Logger logger *slog.Logger
sdkClient *awsCf.Client sdkClient *cloudfront.Client
sslUploader uploader.Uploader sslUploader uploader.Uploader
} }
@ -89,7 +89,7 @@ func (d *DeployerProvider) Deploy(ctx context.Context, certPem string, privkeyPe
// 获取分配配置 // 获取分配配置
// REF: https://docs.aws.amazon.com/en_us/cloudfront/latest/APIReference/API_GetDistributionConfig.html // REF: https://docs.aws.amazon.com/en_us/cloudfront/latest/APIReference/API_GetDistributionConfig.html
getDistributionConfigReq := &awsCf.GetDistributionConfigInput{ getDistributionConfigReq := &cloudfront.GetDistributionConfigInput{
Id: aws.String(d.config.DistributionId), Id: aws.String(d.config.DistributionId),
} }
getDistributionConfigResp, err := d.sdkClient.GetDistributionConfig(context.TODO(), getDistributionConfigReq) getDistributionConfigResp, err := d.sdkClient.GetDistributionConfig(context.TODO(), getDistributionConfigReq)
@ -100,13 +100,13 @@ func (d *DeployerProvider) Deploy(ctx context.Context, certPem string, privkeyPe
// 更新分配配置 // 更新分配配置
// REF: https://docs.aws.amazon.com/zh_cn/cloudfront/latest/APIReference/API_UpdateDistribution.html // REF: https://docs.aws.amazon.com/zh_cn/cloudfront/latest/APIReference/API_UpdateDistribution.html
updateDistributionReq := &awsCf.UpdateDistributionInput{ updateDistributionReq := &cloudfront.UpdateDistributionInput{
Id: aws.String(d.config.DistributionId), Id: aws.String(d.config.DistributionId),
DistributionConfig: getDistributionConfigResp.DistributionConfig, DistributionConfig: getDistributionConfigResp.DistributionConfig,
IfMatch: getDistributionConfigResp.ETag, IfMatch: getDistributionConfigResp.ETag,
} }
if updateDistributionReq.DistributionConfig.ViewerCertificate == nil { if updateDistributionReq.DistributionConfig.ViewerCertificate == nil {
updateDistributionReq.DistributionConfig.ViewerCertificate = &awsCfTypes.ViewerCertificate{} updateDistributionReq.DistributionConfig.ViewerCertificate = &types.ViewerCertificate{}
} }
updateDistributionReq.DistributionConfig.ViewerCertificate.CloudFrontDefaultCertificate = aws.Bool(false) updateDistributionReq.DistributionConfig.ViewerCertificate.CloudFrontDefaultCertificate = aws.Bool(false)
updateDistributionReq.DistributionConfig.ViewerCertificate.ACMCertificateArn = aws.String(upres.CertId) updateDistributionReq.DistributionConfig.ViewerCertificate.ACMCertificateArn = aws.String(upres.CertId)
@ -119,15 +119,15 @@ func (d *DeployerProvider) Deploy(ctx context.Context, certPem string, privkeyPe
return &deployer.DeployResult{}, nil return &deployer.DeployResult{}, nil
} }
func createSdkClient(accessKeyId, secretAccessKey, region string) (*awsCf.Client, error) { func createSdkClient(accessKeyId, secretAccessKey, region string) (*cloudfront.Client, error) {
cfg, err := awsCfg.LoadDefaultConfig(context.TODO()) cfg, err := awscfg.LoadDefaultConfig(context.TODO())
if err != nil { if err != nil {
return nil, err return nil, err
} }
client := awsCf.NewFromConfig(cfg, func(o *awsCf.Options) { client := cloudfront.NewFromConfig(cfg, func(o *cloudfront.Options) {
o.Region = region o.Region = region
o.Credentials = aws.NewCredentialsCache(awsCred.NewStaticCredentialsProvider(accessKeyId, secretAccessKey, "")) o.Credentials = aws.NewCredentialsCache(awscred.NewStaticCredentialsProvider(accessKeyId, secretAccessKey, ""))
}) })
return client, nil return client, nil
} }

View File

@ -0,0 +1,332 @@
package baiducloudappblb
import (
"context"
"errors"
"fmt"
"log/slog"
"strconv"
"strings"
bceappblb "github.com/baidubce/bce-sdk-go/services/appblb"
"github.com/google/uuid"
xerrors "github.com/pkg/errors"
"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/baiducloud-cert"
"github.com/usual2970/certimate/internal/pkg/utils/sliceutil"
)
type DeployerConfig struct {
// 百度智能云 AccessKeyId。
AccessKeyId string `json:"accessKeyId"`
// 百度智能云 SecretAccessKey。
SecretAccessKey string `json:"secretAccessKey"`
// 百度智能云区域。
Region string `json:"region"`
// 部署资源类型。
ResourceType ResourceType `json:"resourceType"`
// 负载均衡实例 ID。
// 部署资源类型为 [RESOURCE_TYPE_LOADBALANCER]、[RESOURCE_TYPE_LISTENER] 时必填。
LoadbalancerId string `json:"loadbalancerId,omitempty"`
// 负载均衡监听端口。
// 部署资源类型为 [RESOURCE_TYPE_LISTENER] 时必填。
ListenerPort int32 `json:"listenerPort,omitempty"`
// SNI 域名(支持泛域名)。
// 部署资源类型为 [RESOURCE_TYPE_LOADBALANCER]、[RESOURCE_TYPE_LISTENER] 时选填。
Domain string `json:"domain,omitempty"`
}
type DeployerProvider struct {
config *DeployerConfig
logger *slog.Logger
sdkClient *bceappblb.Client
sslUploader uploader.Uploader
}
var _ deployer.Deployer = (*DeployerProvider)(nil)
func NewDeployer(config *DeployerConfig) (*DeployerProvider, error) {
if config == nil {
panic("config is nil")
}
client, err := createSdkClient(config.AccessKeyId, config.SecretAccessKey, config.Region)
if err != nil {
return nil, xerrors.Wrap(err, "failed to create sdk client")
}
uploader, err := uploadersp.NewUploader(&uploadersp.UploaderConfig{
AccessKeyId: config.AccessKeyId,
SecretAccessKey: config.SecretAccessKey,
})
if err != nil {
return nil, xerrors.Wrap(err, "failed to create ssl uploader")
}
return &DeployerProvider{
config: config,
logger: slog.Default(),
sdkClient: client,
sslUploader: uploader,
}, nil
}
func (d *DeployerProvider) WithLogger(logger *slog.Logger) deployer.Deployer {
if logger == nil {
d.logger = slog.Default()
} else {
d.logger = logger
}
return d
}
func (d *DeployerProvider) Deploy(ctx context.Context, certPem string, privkeyPem string) (*deployer.DeployResult, error) {
// 上传证书到 CAS
upres, err := d.sslUploader.Upload(ctx, certPem, privkeyPem)
if err != nil {
return nil, xerrors.Wrap(err, "failed to upload certificate file")
} else {
d.logger.Info("ssl certificate uploaded", slog.Any("result", upres))
}
// 根据部署资源类型决定部署方式
switch d.config.ResourceType {
case RESOURCE_TYPE_LOADBALANCER:
if err := d.deployToLoadbalancer(ctx, upres.CertId); err != nil {
return nil, err
}
case RESOURCE_TYPE_LISTENER:
if err := d.deployToListener(ctx, upres.CertId); err != nil {
return nil, err
}
default:
return nil, fmt.Errorf("unsupported resource type: %s", d.config.ResourceType)
}
return &deployer.DeployResult{}, nil
}
func (d *DeployerProvider) deployToLoadbalancer(ctx context.Context, cloudCertId string) error {
if d.config.LoadbalancerId == "" {
return errors.New("config `loadbalancerId` is required")
}
// 查询 BLB 实例详情
// REF: https://cloud.baidu.com/doc/BLB/s/6jwvxnyhi#describeloadbalancerdetail%E6%9F%A5%E8%AF%A2blb%E5%AE%9E%E4%BE%8B%E8%AF%A6%E6%83%85
describeLoadBalancerDetailResp, err := d.sdkClient.DescribeLoadBalancerDetail(d.config.LoadbalancerId)
d.logger.Debug("sdk request 'appblb.DescribeLoadBalancerAttribute'", slog.String("blbId", d.config.LoadbalancerId), slog.Any("response", describeLoadBalancerDetailResp))
if err != nil {
return xerrors.Wrap(err, "failed to execute sdk request 'appblb.DescribeLoadBalancerDetail'")
}
// 获取全部 HTTPS/SSL 监听端口
listeners := make([]struct {
Type string
Port int32
}, 0)
for _, listener := range describeLoadBalancerDetailResp.Listener {
if listener.Type == "HTTPS" || listener.Type == "SSL" {
listenerPort, err := strconv.Atoi(listener.Port)
if err != nil {
continue
}
listeners = append(listeners, struct {
Type string
Port int32
}{
Type: listener.Type,
Port: int32(listenerPort),
})
}
}
// 遍历更新监听证书
if len(listeners) == 0 {
d.logger.Info("no blb listeners to deploy")
} else {
d.logger.Info("found https/ssl listeners to deploy", slog.Any("listeners", listeners))
var errs []error
for _, listener := range listeners {
if err := d.updateListenerCertificate(ctx, d.config.LoadbalancerId, listener.Type, listener.Port, cloudCertId); err != nil {
errs = append(errs, err)
}
}
if len(errs) > 0 {
return errors.Join(errs...)
}
}
return nil
}
func (d *DeployerProvider) deployToListener(ctx context.Context, cloudCertId string) error {
if d.config.LoadbalancerId == "" {
return errors.New("config `loadbalancerId` is required")
}
if d.config.ListenerPort == 0 {
return errors.New("config `listenerPort` is required")
}
// 查询监听
// REF: https://cloud.baidu.com/doc/BLB/s/ujwvxnyux#describeappalllisteners%E6%9F%A5%E8%AF%A2%E6%89%80%E6%9C%89%E7%9B%91%E5%90%AC
describeAppAllListenersRequest := &bceappblb.DescribeAppListenerArgs{
ListenerPort: uint16(d.config.ListenerPort),
}
describeAppAllListenersResp, err := d.sdkClient.DescribeAppAllListeners(d.config.LoadbalancerId, describeAppAllListenersRequest)
d.logger.Debug("sdk request 'appblb.DescribeAppAllListeners'", slog.String("blbId", d.config.LoadbalancerId), slog.Any("request", describeAppAllListenersRequest), slog.Any("response", describeAppAllListenersResp))
if err != nil {
return xerrors.Wrap(err, "failed to execute sdk request 'appblb.DescribeAppAllListeners'")
}
// 获取全部 HTTPS/SSL 监听端口
listeners := make([]struct {
Type string
Port int32
}, 0)
for _, listener := range describeAppAllListenersResp.ListenerList {
if listener.ListenerType == "HTTPS" || listener.ListenerType == "SSL" {
listeners = append(listeners, struct {
Type string
Port int32
}{
Type: listener.ListenerType,
Port: int32(listener.ListenerPort),
})
}
}
// 遍历更新监听证书
if len(listeners) == 0 {
d.logger.Info("no blb listeners to deploy")
} else {
d.logger.Info("found https/ssl listeners to deploy", slog.Any("listeners", listeners))
var errs []error
for _, listener := range listeners {
if err := d.updateListenerCertificate(ctx, d.config.LoadbalancerId, listener.Type, listener.Port, cloudCertId); err != nil {
errs = append(errs, err)
}
}
if len(errs) > 0 {
return errors.Join(errs...)
}
}
return nil
}
func (d *DeployerProvider) updateListenerCertificate(ctx context.Context, cloudLoadbalancerId string, cloudListenerType string, cloudListenerPort int32, cloudCertId string) error {
switch strings.ToUpper(cloudListenerType) {
case "HTTPS":
return d.updateHttpsListenerCertificate(ctx, cloudLoadbalancerId, cloudListenerPort, cloudCertId)
case "SSL":
return d.updateSslListenerCertificate(ctx, cloudLoadbalancerId, cloudListenerPort, cloudCertId)
default:
return fmt.Errorf("unsupported listener type: %s", cloudListenerType)
}
}
func (d *DeployerProvider) updateHttpsListenerCertificate(ctx context.Context, cloudLoadbalancerId string, cloudHttpsListenerPort int32, cloudCertId string) error {
// 查询 HTTPS 监听器
// REF: https://cloud.baidu.com/doc/BLB/s/ujwvxnyux#describeapphttpslisteners%E6%9F%A5%E8%AF%A2https%E7%9B%91%E5%90%AC%E5%99%A8
describeAppHTTPSListenersReq := &bceappblb.DescribeAppListenerArgs{
ListenerPort: uint16(cloudHttpsListenerPort),
MaxKeys: 1,
}
describeAppHTTPSListenersResp, err := d.sdkClient.DescribeAppHTTPSListeners(cloudLoadbalancerId, describeAppHTTPSListenersReq)
d.logger.Debug("sdk request 'appblb.DescribeAppHTTPSListeners'", slog.String("blbId", cloudLoadbalancerId), slog.Any("request", describeAppHTTPSListenersReq), slog.Any("response", describeAppHTTPSListenersResp))
if err != nil {
return xerrors.Wrap(err, "failed to execute sdk request 'appblb.DescribeAppHTTPSListeners'")
} else if len(describeAppHTTPSListenersResp.ListenerList) == 0 {
return fmt.Errorf("listener %s:%d not found", cloudLoadbalancerId, cloudHttpsListenerPort)
}
if d.config.Domain == "" {
// 未指定 SNI只需部署到监听器
// 更新 HTTPS 监听器
// REF: https://cloud.baidu.com/doc/BLB/s/ujwvxnyux#updateapphttpslistener%E6%9B%B4%E6%96%B0https%E7%9B%91%E5%90%AC%E5%99%A8
updateAppHTTPSListenerReq := &bceappblb.UpdateAppHTTPSListenerArgs{
ClientToken: generateClientToken(),
ListenerPort: uint16(cloudHttpsListenerPort),
CertIds: []string{cloudCertId},
}
err := d.sdkClient.UpdateAppHTTPSListener(cloudLoadbalancerId, updateAppHTTPSListenerReq)
d.logger.Debug("sdk request 'appblb.UpdateAppHTTPSListener'", slog.Any("request", updateAppHTTPSListenerReq))
if err != nil {
return xerrors.Wrap(err, "failed to execute sdk request 'appblb.UpdateAppHTTPSListener'")
}
} else {
// 指定 SNI需部署到扩展域名
// 更新 HTTPS 监听器
// REF: https://cloud.baidu.com/doc/BLB/s/yjwvxnvl6#updatehttpslistener%E6%9B%B4%E6%96%B0https%E7%9B%91%E5%90%AC%E5%99%A8
updateAppHTTPSListenerReq := &bceappblb.UpdateAppHTTPSListenerArgs{
ClientToken: generateClientToken(),
ListenerPort: uint16(cloudHttpsListenerPort),
AdditionalCertDomains: sliceutil.Map(describeAppHTTPSListenersResp.ListenerList[0].AdditionalCertDomains, func(domain bceappblb.AdditionalCertDomainsModel) bceappblb.AdditionalCertDomainsModel {
if domain.Host == d.config.Domain {
return bceappblb.AdditionalCertDomainsModel{
Host: domain.Host,
CertId: cloudCertId,
}
}
return bceappblb.AdditionalCertDomainsModel{
Host: domain.Host,
CertId: domain.CertId,
}
}),
}
err := d.sdkClient.UpdateAppHTTPSListener(cloudLoadbalancerId, updateAppHTTPSListenerReq)
d.logger.Debug("sdk request 'appblb.UpdateAppHTTPSListener'", slog.Any("request", updateAppHTTPSListenerReq))
if err != nil {
return xerrors.Wrap(err, "failed to execute sdk request 'appblb.UpdateAppHTTPSListener'")
}
}
return nil
}
func (d *DeployerProvider) updateSslListenerCertificate(ctx context.Context, cloudLoadbalancerId string, cloudHttpsListenerPort int32, cloudCertId string) error {
// 更新 SSL 监听器
// REF: https://cloud.baidu.com/doc/BLB/s/ujwvxnyux#updateappssllistener%E6%9B%B4%E6%96%B0ssl%E7%9B%91%E5%90%AC%E5%99%A8
updateAppSSLListenerReq := &bceappblb.UpdateAppSSLListenerArgs{
ClientToken: generateClientToken(),
ListenerPort: uint16(cloudHttpsListenerPort),
CertIds: []string{cloudCertId},
}
err := d.sdkClient.UpdateAppSSLListener(cloudLoadbalancerId, updateAppSSLListenerReq)
d.logger.Debug("sdk request 'appblb.UpdateAppSSLListener'", slog.Any("request", updateAppSSLListenerReq))
if err != nil {
return xerrors.Wrap(err, "failed to execute sdk request 'appblb.UpdateAppSSLListener'")
}
return nil
}
func createSdkClient(accessKeyId, secretAccessKey, region string) (*bceappblb.Client, error) {
endpoint := ""
if region != "" {
endpoint = fmt.Sprintf("blb.%s.baidubce.com", region)
}
client, err := bceappblb.NewClient(accessKeyId, secretAccessKey, endpoint)
if err != nil {
return nil, err
}
return client, nil
}
func generateClientToken() string {
return strings.ReplaceAll(uuid.New().String(), "-", "")
}

View File

@ -0,0 +1,86 @@
package baiducloudappblb_test
import (
"context"
"flag"
"fmt"
"os"
"strings"
"testing"
provider "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/baiducloud-appblb"
)
var (
fInputCertPath string
fInputKeyPath string
fAccessKeyId string
fSecretAccessKey string
fRegion string
fLoadbalancerId string
fDomain string
)
func init() {
argsPrefix := "CERTIMATE_DEPLOYER_BAIDUCLOUDAPPBLB_"
flag.StringVar(&fInputCertPath, argsPrefix+"INPUTCERTPATH", "", "")
flag.StringVar(&fInputKeyPath, argsPrefix+"INPUTKEYPATH", "", "")
flag.StringVar(&fAccessKeyId, argsPrefix+"ACCESSKEYID", "", "")
flag.StringVar(&fSecretAccessKey, argsPrefix+"SECRETACCESSKEY", "", "")
flag.StringVar(&fRegion, argsPrefix+"REGION", "", "")
flag.StringVar(&fLoadbalancerId, argsPrefix+"LOADBALANCERID", "", "")
flag.StringVar(&fDomain, argsPrefix+"DOMAIN", "", "")
}
/*
Shell command to run this test:
go test -v ./baiducloud_appblb_test.go -args \
--CERTIMATE_DEPLOYER_BAIDUCLOUDAPPBLB_INPUTCERTPATH="/path/to/your-input-cert.pem" \
--CERTIMATE_DEPLOYER_BAIDUCLOUDAPPBLB_INPUTKEYPATH="/path/to/your-input-key.pem" \
--CERTIMATE_DEPLOYER_BAIDUCLOUDAPPBLB_ACCESSKEYID="your-access-key-id" \
--CERTIMATE_DEPLOYER_BAIDUCLOUDAPPBLB_SECRETACCESSKEY="your-secret-access-key" \
--CERTIMATE_DEPLOYER_BAIDUCLOUDAPPBLB_REGION="bj" \
--CERTIMATE_DEPLOYER_BAIDUCLOUDAPPBLB_LOADBALANCERID="your-blb-loadbalancer-id" \
--CERTIMATE_DEPLOYER_BAIDUCLOUDAPPBLB_DOMAIN="your-blb-sni-domain"
*/
func TestDeploy(t *testing.T) {
flag.Parse()
t.Run("Deploy", func(t *testing.T) {
t.Log(strings.Join([]string{
"args:",
fmt.Sprintf("INPUTCERTPATH: %v", fInputCertPath),
fmt.Sprintf("INPUTKEYPATH: %v", fInputKeyPath),
fmt.Sprintf("ACCESSKEYID: %v", fAccessKeyId),
fmt.Sprintf("SECRETACCESSKEY: %v", fSecretAccessKey),
fmt.Sprintf("REGION: %v", fRegion),
fmt.Sprintf("LOADBALANCERID: %v", fLoadbalancerId),
fmt.Sprintf("DOMAIN: %v", fDomain),
}, "\n"))
deployer, err := provider.NewDeployer(&provider.DeployerConfig{
AccessKeyId: fAccessKeyId,
SecretAccessKey: fSecretAccessKey,
ResourceType: provider.RESOURCE_TYPE_LOADBALANCER,
Region: fRegion,
LoadbalancerId: fLoadbalancerId,
Domain: fDomain,
})
if err != nil {
t.Errorf("err: %+v", err)
return
}
fInputCertData, _ := os.ReadFile(fInputCertPath)
fInputKeyData, _ := os.ReadFile(fInputKeyPath)
res, err := deployer.Deploy(context.Background(), string(fInputCertData), string(fInputKeyData))
if err != nil {
t.Errorf("err: %+v", err)
return
}
t.Logf("ok: %v", res)
})
}

View File

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

View File

@ -0,0 +1,332 @@
package baiducloudblb
import (
"context"
"errors"
"fmt"
"log/slog"
"strconv"
"strings"
bceblb "github.com/baidubce/bce-sdk-go/services/blb"
"github.com/google/uuid"
xerrors "github.com/pkg/errors"
"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/baiducloud-cert"
"github.com/usual2970/certimate/internal/pkg/utils/sliceutil"
)
type DeployerConfig struct {
// 百度智能云 AccessKeyId。
AccessKeyId string `json:"accessKeyId"`
// 百度智能云 SecretAccessKey。
SecretAccessKey string `json:"secretAccessKey"`
// 百度智能云区域。
Region string `json:"region"`
// 部署资源类型。
ResourceType ResourceType `json:"resourceType"`
// 负载均衡实例 ID。
// 部署资源类型为 [RESOURCE_TYPE_LOADBALANCER]、[RESOURCE_TYPE_LISTENER] 时必填。
LoadbalancerId string `json:"loadbalancerId,omitempty"`
// 负载均衡监听端口。
// 部署资源类型为 [RESOURCE_TYPE_LISTENER] 时必填。
ListenerPort int32 `json:"listenerPort,omitempty"`
// SNI 域名(支持泛域名)。
// 部署资源类型为 [RESOURCE_TYPE_LOADBALANCER]、[RESOURCE_TYPE_LISTENER] 时选填。
Domain string `json:"domain,omitempty"`
}
type DeployerProvider struct {
config *DeployerConfig
logger *slog.Logger
sdkClient *bceblb.Client
sslUploader uploader.Uploader
}
var _ deployer.Deployer = (*DeployerProvider)(nil)
func NewDeployer(config *DeployerConfig) (*DeployerProvider, error) {
if config == nil {
panic("config is nil")
}
client, err := createSdkClient(config.AccessKeyId, config.SecretAccessKey, config.Region)
if err != nil {
return nil, xerrors.Wrap(err, "failed to create sdk client")
}
uploader, err := uploadersp.NewUploader(&uploadersp.UploaderConfig{
AccessKeyId: config.AccessKeyId,
SecretAccessKey: config.SecretAccessKey,
})
if err != nil {
return nil, xerrors.Wrap(err, "failed to create ssl uploader")
}
return &DeployerProvider{
config: config,
logger: slog.Default(),
sdkClient: client,
sslUploader: uploader,
}, nil
}
func (d *DeployerProvider) WithLogger(logger *slog.Logger) deployer.Deployer {
if logger == nil {
d.logger = slog.Default()
} else {
d.logger = logger
}
return d
}
func (d *DeployerProvider) Deploy(ctx context.Context, certPem string, privkeyPem string) (*deployer.DeployResult, error) {
// 上传证书到 CAS
upres, err := d.sslUploader.Upload(ctx, certPem, privkeyPem)
if err != nil {
return nil, xerrors.Wrap(err, "failed to upload certificate file")
} else {
d.logger.Info("ssl certificate uploaded", slog.Any("result", upres))
}
// 根据部署资源类型决定部署方式
switch d.config.ResourceType {
case RESOURCE_TYPE_LOADBALANCER:
if err := d.deployToLoadbalancer(ctx, upres.CertId); err != nil {
return nil, err
}
case RESOURCE_TYPE_LISTENER:
if err := d.deployToListener(ctx, upres.CertId); err != nil {
return nil, err
}
default:
return nil, fmt.Errorf("unsupported resource type: %s", d.config.ResourceType)
}
return &deployer.DeployResult{}, nil
}
func (d *DeployerProvider) deployToLoadbalancer(ctx context.Context, cloudCertId string) error {
if d.config.LoadbalancerId == "" {
return errors.New("config `loadbalancerId` is required")
}
// 查询 BLB 实例详情
// REF: https://cloud.baidu.com/doc/BLB/s/njwvxnv79#describeloadbalancerdetail%E6%9F%A5%E8%AF%A2blb%E5%AE%9E%E4%BE%8B%E8%AF%A6%E6%83%85
describeLoadBalancerDetailResp, err := d.sdkClient.DescribeLoadBalancerDetail(d.config.LoadbalancerId)
d.logger.Debug("sdk request 'blb.DescribeLoadBalancerAttribute'", slog.String("blbId", d.config.LoadbalancerId), slog.Any("response", describeLoadBalancerDetailResp))
if err != nil {
return xerrors.Wrap(err, "failed to execute sdk request 'blb.DescribeLoadBalancerDetail'")
}
// 获取全部 HTTPS/SSL 监听端口
listeners := make([]struct {
Type string
Port int32
}, 0)
for _, listener := range describeLoadBalancerDetailResp.Listener {
if listener.Type == "HTTPS" || listener.Type == "SSL" {
listenerPort, err := strconv.Atoi(listener.Port)
if err != nil {
continue
}
listeners = append(listeners, struct {
Type string
Port int32
}{
Type: listener.Type,
Port: int32(listenerPort),
})
}
}
// 遍历更新监听证书
if len(listeners) == 0 {
d.logger.Info("no blb listeners to deploy")
} else {
d.logger.Info("found https/ssl listeners to deploy", slog.Any("listeners", listeners))
var errs []error
for _, listener := range listeners {
if err := d.updateListenerCertificate(ctx, d.config.LoadbalancerId, listener.Type, listener.Port, cloudCertId); err != nil {
errs = append(errs, err)
}
}
if len(errs) > 0 {
return errors.Join(errs...)
}
}
return nil
}
func (d *DeployerProvider) deployToListener(ctx context.Context, cloudCertId string) error {
if d.config.LoadbalancerId == "" {
return errors.New("config `loadbalancerId` is required")
}
if d.config.ListenerPort == 0 {
return errors.New("config `listenerPort` is required")
}
// 查询监听
// REF: https://cloud.baidu.com/doc/BLB/s/yjwvxnvl6#describealllisteners%E6%9F%A5%E8%AF%A2%E6%89%80%E6%9C%89%E7%9B%91%E5%90%AC
describeAllListenersRequest := &bceblb.DescribeListenerArgs{
ListenerPort: uint16(d.config.ListenerPort),
}
describeAllListenersResp, err := d.sdkClient.DescribeAllListeners(d.config.LoadbalancerId, describeAllListenersRequest)
d.logger.Debug("sdk request 'blb.DescribeAllListeners'", slog.String("blbId", d.config.LoadbalancerId), slog.Any("request", describeAllListenersRequest), slog.Any("response", describeAllListenersResp))
if err != nil {
return xerrors.Wrap(err, "failed to execute sdk request 'blb.DescribeAllListeners'")
}
// 获取全部 HTTPS/SSL 监听端口
listeners := make([]struct {
Type string
Port int32
}, 0)
for _, listener := range describeAllListenersResp.AllListenerList {
if listener.ListenerType == "HTTPS" || listener.ListenerType == "SSL" {
listeners = append(listeners, struct {
Type string
Port int32
}{
Type: listener.ListenerType,
Port: int32(listener.ListenerPort),
})
}
}
// 遍历更新监听证书
if len(listeners) == 0 {
d.logger.Info("no blb listeners to deploy")
} else {
d.logger.Info("found https/ssl listeners to deploy", slog.Any("listeners", listeners))
var errs []error
for _, listener := range listeners {
if err := d.updateListenerCertificate(ctx, d.config.LoadbalancerId, listener.Type, listener.Port, cloudCertId); err != nil {
errs = append(errs, err)
}
}
if len(errs) > 0 {
return errors.Join(errs...)
}
}
return nil
}
func (d *DeployerProvider) updateListenerCertificate(ctx context.Context, cloudLoadbalancerId string, cloudListenerType string, cloudListenerPort int32, cloudCertId string) error {
switch strings.ToUpper(cloudListenerType) {
case "HTTPS":
return d.updateHttpsListenerCertificate(ctx, cloudLoadbalancerId, cloudListenerPort, cloudCertId)
case "SSL":
return d.updateSslListenerCertificate(ctx, cloudLoadbalancerId, cloudListenerPort, cloudCertId)
default:
return fmt.Errorf("unsupported listener type: %s", cloudListenerType)
}
}
func (d *DeployerProvider) updateHttpsListenerCertificate(ctx context.Context, cloudLoadbalancerId string, cloudHttpsListenerPort int32, cloudCertId string) error {
// 查询 HTTPS 监听器
// REF: https://cloud.baidu.com/doc/BLB/s/yjwvxnvl6#describehttpslisteners%E6%9F%A5%E8%AF%A2https%E7%9B%91%E5%90%AC%E5%99%A8
describeHTTPSListenersReq := &bceblb.DescribeListenerArgs{
ListenerPort: uint16(cloudHttpsListenerPort),
MaxKeys: 1,
}
describeHTTPSListenersResp, err := d.sdkClient.DescribeHTTPSListeners(cloudLoadbalancerId, describeHTTPSListenersReq)
d.logger.Debug("sdk request 'blb.DescribeHTTPSListeners'", slog.String("blbId", cloudLoadbalancerId), slog.Any("request", describeHTTPSListenersReq), slog.Any("response", describeHTTPSListenersResp))
if err != nil {
return xerrors.Wrap(err, "failed to execute sdk request 'blb.DescribeHTTPSListeners'")
} else if len(describeHTTPSListenersResp.ListenerList) == 0 {
return fmt.Errorf("listener %s:%d not found", cloudLoadbalancerId, cloudHttpsListenerPort)
}
if d.config.Domain == "" {
// 未指定 SNI只需部署到监听器
// 更新 HTTPS 监听器
// REF: https://cloud.baidu.com/doc/BLB/s/yjwvxnvl6#updatehttpslistener%E6%9B%B4%E6%96%B0https%E7%9B%91%E5%90%AC%E5%99%A8
updateHTTPSListenerReq := &bceblb.UpdateHTTPSListenerArgs{
ClientToken: generateClientToken(),
ListenerPort: uint16(cloudHttpsListenerPort),
CertIds: []string{cloudCertId},
}
err := d.sdkClient.UpdateHTTPSListener(cloudLoadbalancerId, updateHTTPSListenerReq)
d.logger.Debug("sdk request 'blb.UpdateHTTPSListener'", slog.Any("request", updateHTTPSListenerReq))
if err != nil {
return xerrors.Wrap(err, "failed to execute sdk request 'blb.UpdateHTTPSListener'")
}
} else {
// 指定 SNI需部署到扩展域名
// 更新 HTTPS 监听器
// REF: https://cloud.baidu.com/doc/BLB/s/yjwvxnvl6#updatehttpslistener%E6%9B%B4%E6%96%B0https%E7%9B%91%E5%90%AC%E5%99%A8
updateHTTPSListenerReq := &bceblb.UpdateHTTPSListenerArgs{
ClientToken: generateClientToken(),
ListenerPort: uint16(cloudHttpsListenerPort),
AdditionalCertDomains: sliceutil.Map(describeHTTPSListenersResp.ListenerList[0].AdditionalCertDomains, func(domain bceblb.AdditionalCertDomainsModel) bceblb.AdditionalCertDomainsModel {
if domain.Host == d.config.Domain {
return bceblb.AdditionalCertDomainsModel{
Host: domain.Host,
CertId: cloudCertId,
}
}
return bceblb.AdditionalCertDomainsModel{
Host: domain.Host,
CertId: domain.CertId,
}
}),
}
err := d.sdkClient.UpdateHTTPSListener(cloudLoadbalancerId, updateHTTPSListenerReq)
d.logger.Debug("sdk request 'blb.UpdateHTTPSListener'", slog.Any("request", updateHTTPSListenerReq))
if err != nil {
return xerrors.Wrap(err, "failed to execute sdk request 'blb.UpdateHTTPSListener'")
}
}
return nil
}
func (d *DeployerProvider) updateSslListenerCertificate(ctx context.Context, cloudLoadbalancerId string, cloudHttpsListenerPort int32, cloudCertId string) error {
// 更新 SSL 监听器
// REF: https://cloud.baidu.com/doc/BLB/s/yjwvxnvl6#updatessllistener%E6%9B%B4%E6%96%B0ssl%E7%9B%91%E5%90%AC%E5%99%A8
updateSSLListenerReq := &bceblb.UpdateSSLListenerArgs{
ClientToken: generateClientToken(),
ListenerPort: uint16(cloudHttpsListenerPort),
CertIds: []string{cloudCertId},
}
err := d.sdkClient.UpdateSSLListener(cloudLoadbalancerId, updateSSLListenerReq)
d.logger.Debug("sdk request 'blb.UpdateSSLListener'", slog.Any("request", updateSSLListenerReq))
if err != nil {
return xerrors.Wrap(err, "failed to execute sdk request 'blb.UpdateSSLListener'")
}
return nil
}
func createSdkClient(accessKeyId, secretAccessKey, region string) (*bceblb.Client, error) {
endpoint := ""
if region != "" {
endpoint = fmt.Sprintf("blb.%s.baidubce.com", region)
}
client, err := bceblb.NewClient(accessKeyId, secretAccessKey, endpoint)
if err != nil {
return nil, err
}
return client, nil
}
func generateClientToken() string {
return strings.ReplaceAll(uuid.New().String(), "-", "")
}

View File

@ -0,0 +1,86 @@
package baiducloudblb_test
import (
"context"
"flag"
"fmt"
"os"
"strings"
"testing"
provider "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/baiducloud-blb"
)
var (
fInputCertPath string
fInputKeyPath string
fAccessKeyId string
fSecretAccessKey string
fRegion string
fLoadbalancerId string
fDomain string
)
func init() {
argsPrefix := "CERTIMATE_DEPLOYER_BAIDUCLOUDBLB_"
flag.StringVar(&fInputCertPath, argsPrefix+"INPUTCERTPATH", "", "")
flag.StringVar(&fInputKeyPath, argsPrefix+"INPUTKEYPATH", "", "")
flag.StringVar(&fAccessKeyId, argsPrefix+"ACCESSKEYID", "", "")
flag.StringVar(&fSecretAccessKey, argsPrefix+"SECRETACCESSKEY", "", "")
flag.StringVar(&fRegion, argsPrefix+"REGION", "", "")
flag.StringVar(&fLoadbalancerId, argsPrefix+"LOADBALANCERID", "", "")
flag.StringVar(&fDomain, argsPrefix+"DOMAIN", "", "")
}
/*
Shell command to run this test:
go test -v ./baiducloud_blb_test.go -args \
--CERTIMATE_DEPLOYER_BAIDUCLOUDBLB_INPUTCERTPATH="/path/to/your-input-cert.pem" \
--CERTIMATE_DEPLOYER_BAIDUCLOUDBLB_INPUTKEYPATH="/path/to/your-input-key.pem" \
--CERTIMATE_DEPLOYER_BAIDUCLOUDBLB_ACCESSKEYID="your-access-key-id" \
--CERTIMATE_DEPLOYER_BAIDUCLOUDBLB_SECRETACCESSKEY="your-secret-access-key" \
--CERTIMATE_DEPLOYER_BAIDUCLOUDBLB_REGION="bj" \
--CERTIMATE_DEPLOYER_BAIDUCLOUDBLB_LOADBALANCERID="your-blb-loadbalancer-id" \
--CERTIMATE_DEPLOYER_BAIDUCLOUDBLB_DOMAIN="your-blb-sni-domain"
*/
func TestDeploy(t *testing.T) {
flag.Parse()
t.Run("Deploy", func(t *testing.T) {
t.Log(strings.Join([]string{
"args:",
fmt.Sprintf("INPUTCERTPATH: %v", fInputCertPath),
fmt.Sprintf("INPUTKEYPATH: %v", fInputKeyPath),
fmt.Sprintf("ACCESSKEYID: %v", fAccessKeyId),
fmt.Sprintf("SECRETACCESSKEY: %v", fSecretAccessKey),
fmt.Sprintf("REGION: %v", fRegion),
fmt.Sprintf("LOADBALANCERID: %v", fLoadbalancerId),
fmt.Sprintf("DOMAIN: %v", fDomain),
}, "\n"))
deployer, err := provider.NewDeployer(&provider.DeployerConfig{
AccessKeyId: fAccessKeyId,
SecretAccessKey: fSecretAccessKey,
ResourceType: provider.RESOURCE_TYPE_LOADBALANCER,
Region: fRegion,
LoadbalancerId: fLoadbalancerId,
Domain: fDomain,
})
if err != nil {
t.Errorf("err: %+v", err)
return
}
fInputCertData, _ := os.ReadFile(fInputCertPath)
fInputKeyData, _ := os.ReadFile(fInputKeyPath)
res, err := deployer.Deploy(context.Background(), string(fInputCertData), string(fInputKeyData))
if err != nil {
t.Errorf("err: %+v", err)
return
}
t.Logf("ok: %v", res)
})
}

View File

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

View File

@ -6,8 +6,8 @@ import (
"log/slog" "log/slog"
"time" "time"
bceCdn "github.com/baidubce/bce-sdk-go/services/cdn" bcecdn "github.com/baidubce/bce-sdk-go/services/cdn"
bceCdnApi "github.com/baidubce/bce-sdk-go/services/cdn/api" bcecdnapi "github.com/baidubce/bce-sdk-go/services/cdn/api"
xerrors "github.com/pkg/errors" xerrors "github.com/pkg/errors"
"github.com/usual2970/certimate/internal/pkg/core/deployer" "github.com/usual2970/certimate/internal/pkg/core/deployer"
@ -25,7 +25,7 @@ type DeployerConfig struct {
type DeployerProvider struct { type DeployerProvider struct {
config *DeployerConfig config *DeployerConfig
logger *slog.Logger logger *slog.Logger
sdkClient *bceCdn.Client sdkClient *bcecdn.Client
} }
var _ deployer.Deployer = (*DeployerProvider)(nil) var _ deployer.Deployer = (*DeployerProvider)(nil)
@ -61,7 +61,7 @@ func (d *DeployerProvider) Deploy(ctx context.Context, certPem string, privkeyPe
// REF: https://cloud.baidu.com/doc/CDN/s/qjzuz2hp8 // REF: https://cloud.baidu.com/doc/CDN/s/qjzuz2hp8
putCertResp, err := d.sdkClient.PutCert( putCertResp, err := d.sdkClient.PutCert(
d.config.Domain, d.config.Domain,
&bceCdnApi.UserCertificate{ &bcecdnapi.UserCertificate{
CertName: fmt.Sprintf("certimate-%d", time.Now().UnixMilli()), CertName: fmt.Sprintf("certimate-%d", time.Now().UnixMilli()),
ServerData: certPem, ServerData: certPem,
PrivateData: privkeyPem, PrivateData: privkeyPem,
@ -76,8 +76,8 @@ func (d *DeployerProvider) Deploy(ctx context.Context, certPem string, privkeyPe
return &deployer.DeployResult{}, nil return &deployer.DeployResult{}, nil
} }
func createSdkClient(accessKeyId, secretAccessKey string) (*bceCdn.Client, error) { func createSdkClient(accessKeyId, secretAccessKey string) (*bcecdn.Client, error) {
client, err := bceCdn.NewClient(accessKeyId, secretAccessKey, "") client, err := bcecdn.NewClient(accessKeyId, secretAccessKey, "")
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -0,0 +1,68 @@
package baiducloudcert
import (
"context"
"log/slog"
xerrors "github.com/pkg/errors"
"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/baiducloud-cert"
)
type DeployerConfig struct {
// 百度智能云 AccessKeyId。
AccessKeyId string `json:"accessKeyId"`
// 百度智能云 SecretAccessKey。
SecretAccessKey string `json:"secretAccessKey"`
}
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,
})
if err != nil {
return nil, xerrors.Wrap(err, "failed to create ssl uploader")
}
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.Default()
} else {
d.logger = logger
}
return d
}
func (d *DeployerProvider) Deploy(ctx context.Context, certPem string, privkeyPem string) (*deployer.DeployResult, error) {
// 上传证书到 CAS
upres, err := d.sslUploader.Upload(ctx, certPem, privkeyPem)
if err != nil {
return nil, xerrors.Wrap(err, "failed to upload certificate file")
} else {
d.logger.Info("ssl certificate uploaded", slog.Any("result", upres))
}
return &deployer.DeployResult{}, nil
}

View File

@ -2,9 +2,12 @@
import ( import (
"context" "context"
"encoding/json"
"errors" "errors"
"fmt" "fmt"
"log/slog" "log/slog"
"regexp"
"strings"
"time" "time"
xerrors "github.com/pkg/errors" xerrors "github.com/pkg/errors"
@ -75,6 +78,7 @@ func (d *DeployerProvider) Deploy(ctx context.Context, certPem string, privkeyPe
// 新增证书 // 新增证书
// REF: https://portal.baishancloud.com/track/document/downloadPdf/1441 // REF: https://portal.baishancloud.com/track/document/downloadPdf/1441
certificateId := ""
createCertificateReq := &bssdk.CreateCertificateRequest{ createCertificateReq := &bssdk.CreateCertificateRequest{
Certificate: certPem, Certificate: certPem,
Key: privkeyPem, Key: privkeyPem,
@ -83,8 +87,20 @@ func (d *DeployerProvider) Deploy(ctx context.Context, certPem string, privkeyPe
createCertificateResp, err := d.sdkClient.CreateCertificate(createCertificateReq) createCertificateResp, err := d.sdkClient.CreateCertificate(createCertificateReq)
d.logger.Debug("sdk request 'baishan.CreateCertificate'", slog.Any("request", createCertificateReq), slog.Any("response", createCertificateResp)) d.logger.Debug("sdk request 'baishan.CreateCertificate'", slog.Any("request", createCertificateReq), slog.Any("response", createCertificateResp))
if err != nil { if err != nil {
if createCertificateResp != nil {
if createCertificateResp.GetCode() == 400699 && strings.Contains(createCertificateResp.GetMessage(), "this certificate is exists") {
// 证书已存在,忽略新增证书接口错误
re := regexp.MustCompile(`\d+`)
certificateId = re.FindString(createCertificateResp.GetMessage())
}
}
if certificateId == "" {
return nil, xerrors.Wrap(err, "failed to execute sdk request 'baishan.CreateCertificate'") return nil, xerrors.Wrap(err, "failed to execute sdk request 'baishan.CreateCertificate'")
} }
} else {
certificateId = createCertificateResp.Data.CertId.String()
}
// 设置域名配置 // 设置域名配置
// REF: https://portal.baishancloud.com/track/document/api/1/1045 // REF: https://portal.baishancloud.com/track/document/api/1/1045
@ -92,7 +108,7 @@ func (d *DeployerProvider) Deploy(ctx context.Context, certPem string, privkeyPe
Domains: d.config.Domain, Domains: d.config.Domain,
Config: &bssdk.DomainConfig{ Config: &bssdk.DomainConfig{
Https: &bssdk.DomainConfigHttps{ Https: &bssdk.DomainConfigHttps{
CertId: createCertificateResp.Data.CertId, CertId: json.Number(certificateId),
ForceHttps: getDomainConfigResp.Data[0].Config.Https.ForceHttps, ForceHttps: getDomainConfigResp.Data[0].Config.Https.ForceHttps,
EnableHttp2: getDomainConfigResp.Data[0].Config.Https.EnableHttp2, EnableHttp2: getDomainConfigResp.Data[0].Config.Https.EnableHttp2,
EnableOcsp: getDomainConfigResp.Data[0].Config.Https.EnableOcsp, EnableOcsp: getDomainConfigResp.Data[0].Config.Https.EnableOcsp,

View File

@ -6,7 +6,7 @@ import (
"log/slog" "log/slog"
"strings" "strings"
bpCdn "github.com/byteplus-sdk/byteplus-sdk-golang/service/cdn" bpcdn "github.com/byteplus-sdk/byteplus-sdk-golang/service/cdn"
xerrors "github.com/pkg/errors" xerrors "github.com/pkg/errors"
"github.com/usual2970/certimate/internal/pkg/core/deployer" "github.com/usual2970/certimate/internal/pkg/core/deployer"
@ -26,7 +26,7 @@ type DeployerConfig struct {
type DeployerProvider struct { type DeployerProvider struct {
config *DeployerConfig config *DeployerConfig
logger *slog.Logger logger *slog.Logger
sdkClient *bpCdn.CDN sdkClient *bpcdn.CDN
sslUploader uploader.Uploader sslUploader uploader.Uploader
} }
@ -37,7 +37,7 @@ func NewDeployer(config *DeployerConfig) (*DeployerProvider, error) {
panic("config is nil") panic("config is nil")
} }
client := bpCdn.NewInstance() client := bpcdn.NewInstance()
client.Client.SetAccessKey(config.AccessKey) client.Client.SetAccessKey(config.AccessKey)
client.Client.SetSecretKey(config.SecretKey) client.Client.SetSecretKey(config.SecretKey)
@ -80,7 +80,7 @@ func (d *DeployerProvider) Deploy(ctx context.Context, certPem string, privkeyPe
if strings.HasPrefix(d.config.Domain, "*.") { if strings.HasPrefix(d.config.Domain, "*.") {
// 获取指定证书可关联的域名 // 获取指定证书可关联的域名
// REF: https://docs.byteplus.com/en/docs/byteplus-cdn/reference-describecertconfig-9ea17 // REF: https://docs.byteplus.com/en/docs/byteplus-cdn/reference-describecertconfig-9ea17
describeCertConfigReq := &bpCdn.DescribeCertConfigRequest{ describeCertConfigReq := &bpcdn.DescribeCertConfigRequest{
CertId: upres.CertId, CertId: upres.CertId,
} }
describeCertConfigResp, err := d.sdkClient.DescribeCertConfig(describeCertConfigReq) describeCertConfigResp, err := d.sdkClient.DescribeCertConfig(describeCertConfigReq)
@ -119,7 +119,7 @@ func (d *DeployerProvider) Deploy(ctx context.Context, certPem string, privkeyPe
for _, domain := range domains { for _, domain := range domains {
// 关联证书与加速域名 // 关联证书与加速域名
// REF: https://docs.byteplus.com/en/docs/byteplus-cdn/reference-batchdeploycert // REF: https://docs.byteplus.com/en/docs/byteplus-cdn/reference-batchdeploycert
batchDeployCertReq := &bpCdn.BatchDeployCertRequest{ batchDeployCertReq := &bpcdn.BatchDeployCertRequest{
CertId: upres.CertId, CertId: upres.CertId,
Domain: domain, Domain: domain,
} }

View File

@ -9,7 +9,7 @@ import (
"github.com/usual2970/certimate/internal/pkg/core/deployer" "github.com/usual2970/certimate/internal/pkg/core/deployer"
"github.com/usual2970/certimate/internal/pkg/utils/certutil" "github.com/usual2970/certimate/internal/pkg/utils/certutil"
edgsdk "github.com/usual2970/certimate/internal/pkg/vendors/edgio-sdk/applications/v7" edgsdk "github.com/usual2970/certimate/internal/pkg/vendors/edgio-sdk/applications/v7"
edgsdkDtos "github.com/usual2970/certimate/internal/pkg/vendors/edgio-sdk/applications/v7/dtos" edgsdkdtos "github.com/usual2970/certimate/internal/pkg/vendors/edgio-sdk/applications/v7/dtos"
) )
type DeployerConfig struct { type DeployerConfig struct {
@ -64,7 +64,7 @@ func (d *DeployerProvider) Deploy(ctx context.Context, certPem string, privkeyPe
// 上传 TLS 证书 // 上传 TLS 证书
// REF: https://docs.edg.io/rest_api/#tag/tls-certs/operation/postConfigV01TlsCerts // REF: https://docs.edg.io/rest_api/#tag/tls-certs/operation/postConfigV01TlsCerts
uploadTlsCertReq := edgsdkDtos.UploadTlsCertRequest{ uploadTlsCertReq := edgsdkdtos.UploadTlsCertRequest{
EnvironmentID: d.config.EnvironmentId, EnvironmentID: d.config.EnvironmentId,
PrimaryCert: privateCertPem, PrimaryCert: privateCertPem,
IntermediateCert: intermediateCertPem, IntermediateCert: intermediateCertPem,

View File

@ -5,9 +5,9 @@ import (
"log/slog" "log/slog"
"github.com/huaweicloud/huaweicloud-sdk-go-v3/core/auth/global" "github.com/huaweicloud/huaweicloud-sdk-go-v3/core/auth/global"
hcCdn "github.com/huaweicloud/huaweicloud-sdk-go-v3/services/cdn/v2" hccdn "github.com/huaweicloud/huaweicloud-sdk-go-v3/services/cdn/v2"
hcCdnModel "github.com/huaweicloud/huaweicloud-sdk-go-v3/services/cdn/v2/model" hccdnmodel "github.com/huaweicloud/huaweicloud-sdk-go-v3/services/cdn/v2/model"
hcCdnRegion "github.com/huaweicloud/huaweicloud-sdk-go-v3/services/cdn/v2/region" hccdnregion "github.com/huaweicloud/huaweicloud-sdk-go-v3/services/cdn/v2/region"
xerrors "github.com/pkg/errors" xerrors "github.com/pkg/errors"
"github.com/usual2970/certimate/internal/pkg/core/deployer" "github.com/usual2970/certimate/internal/pkg/core/deployer"
@ -30,7 +30,7 @@ type DeployerConfig struct {
type DeployerProvider struct { type DeployerProvider struct {
config *DeployerConfig config *DeployerConfig
logger *slog.Logger logger *slog.Logger
sdkClient *hcCdn.CdnClient sdkClient *hccdn.CdnClient
sslUploader uploader.Uploader sslUploader uploader.Uploader
} }
@ -87,7 +87,7 @@ func (d *DeployerProvider) Deploy(ctx context.Context, certPem string, privkeyPe
// 查询加速域名配置 // 查询加速域名配置
// REF: https://support.huaweicloud.com/api-cdn/ShowDomainFullConfig.html // REF: https://support.huaweicloud.com/api-cdn/ShowDomainFullConfig.html
showDomainFullConfigReq := &hcCdnModel.ShowDomainFullConfigRequest{ showDomainFullConfigReq := &hccdnmodel.ShowDomainFullConfigRequest{
DomainName: d.config.Domain, DomainName: d.config.Domain,
} }
showDomainFullConfigResp, err := d.sdkClient.ShowDomainFullConfig(showDomainFullConfigReq) showDomainFullConfigResp, err := d.sdkClient.ShowDomainFullConfig(showDomainFullConfigReq)
@ -99,15 +99,15 @@ func (d *DeployerProvider) Deploy(ctx context.Context, certPem string, privkeyPe
// 更新加速域名配置 // 更新加速域名配置
// REF: https://support.huaweicloud.com/api-cdn/UpdateDomainMultiCertificates.html // REF: https://support.huaweicloud.com/api-cdn/UpdateDomainMultiCertificates.html
// REF: https://support.huaweicloud.com/usermanual-cdn/cdn_01_0306.html // REF: https://support.huaweicloud.com/usermanual-cdn/cdn_01_0306.html
updateDomainMultiCertificatesReqBodyContent := &hcCdnModel.UpdateDomainMultiCertificatesRequestBodyContent{} updateDomainMultiCertificatesReqBodyContent := &hccdnmodel.UpdateDomainMultiCertificatesRequestBodyContent{}
updateDomainMultiCertificatesReqBodyContent.DomainName = d.config.Domain updateDomainMultiCertificatesReqBodyContent.DomainName = d.config.Domain
updateDomainMultiCertificatesReqBodyContent.HttpsSwitch = 1 updateDomainMultiCertificatesReqBodyContent.HttpsSwitch = 1
updateDomainMultiCertificatesReqBodyContent.CertificateType = hwsdk.Int32Ptr(2) updateDomainMultiCertificatesReqBodyContent.CertificateType = hwsdk.Int32Ptr(2)
updateDomainMultiCertificatesReqBodyContent.ScmCertificateId = hwsdk.StringPtr(upres.CertId) updateDomainMultiCertificatesReqBodyContent.ScmCertificateId = hwsdk.StringPtr(upres.CertId)
updateDomainMultiCertificatesReqBodyContent.CertName = hwsdk.StringPtr(upres.CertName) updateDomainMultiCertificatesReqBodyContent.CertName = hwsdk.StringPtr(upres.CertName)
updateDomainMultiCertificatesReqBodyContent = assign(updateDomainMultiCertificatesReqBodyContent, showDomainFullConfigResp.Configs) updateDomainMultiCertificatesReqBodyContent = assign(updateDomainMultiCertificatesReqBodyContent, showDomainFullConfigResp.Configs)
updateDomainMultiCertificatesReq := &hcCdnModel.UpdateDomainMultiCertificatesRequest{ updateDomainMultiCertificatesReq := &hccdnmodel.UpdateDomainMultiCertificatesRequest{
Body: &hcCdnModel.UpdateDomainMultiCertificatesRequestBody{ Body: &hccdnmodel.UpdateDomainMultiCertificatesRequestBody{
Https: updateDomainMultiCertificatesReqBodyContent, Https: updateDomainMultiCertificatesReqBodyContent,
}, },
} }
@ -120,7 +120,7 @@ func (d *DeployerProvider) Deploy(ctx context.Context, certPem string, privkeyPe
return &deployer.DeployResult{}, nil return &deployer.DeployResult{}, nil
} }
func createSdkClient(accessKeyId, secretAccessKey, region string) (*hcCdn.CdnClient, error) { func createSdkClient(accessKeyId, secretAccessKey, region string) (*hccdn.CdnClient, error) {
if region == "" { if region == "" {
region = "cn-north-1" // CDN 服务默认区域:华北一北京 region = "cn-north-1" // CDN 服务默认区域:华北一北京
} }
@ -133,12 +133,12 @@ func createSdkClient(accessKeyId, secretAccessKey, region string) (*hcCdn.CdnCli
return nil, err return nil, err
} }
hcRegion, err := hcCdnRegion.SafeValueOf(region) hcRegion, err := hccdnregion.SafeValueOf(region)
if err != nil { if err != nil {
return nil, err return nil, err
} }
hcClient, err := hcCdn.CdnClientBuilder(). hcClient, err := hccdn.CdnClientBuilder().
WithRegion(hcRegion). WithRegion(hcRegion).
WithCredential(auth). WithCredential(auth).
SafeBuild() SafeBuild()
@ -146,42 +146,44 @@ func createSdkClient(accessKeyId, secretAccessKey, region string) (*hcCdn.CdnCli
return nil, err return nil, err
} }
client := hcCdn.NewCdnClient(hcClient) client := hccdn.NewCdnClient(hcClient)
return client, nil return client, nil
} }
func assign(reqContent *hcCdnModel.UpdateDomainMultiCertificatesRequestBodyContent, target *hcCdnModel.ConfigsGetBody) *hcCdnModel.UpdateDomainMultiCertificatesRequestBodyContent { func assign(source *hccdnmodel.UpdateDomainMultiCertificatesRequestBodyContent, target *hccdnmodel.ConfigsGetBody) *hccdnmodel.UpdateDomainMultiCertificatesRequestBodyContent {
// `UpdateDomainMultiCertificates` 中不传的字段表示使用默认值、而非保留原值,
// 因此这里需要把原配置中的参数重新赋值回去。
if target == nil { if target == nil {
return reqContent return source
} }
// 华为云 API 中不传的字段表示使用默认值、而非保留原值,因此这里需要把原配置中的参数重新赋值回去。
// 而且蛋疼的是查询接口返回的数据结构和更新接口传入的参数结构不一致,需要做很多转化。
if *target.OriginProtocol == "follow" { if *target.OriginProtocol == "follow" {
reqContent.AccessOriginWay = hwsdk.Int32Ptr(1) source.AccessOriginWay = hwsdk.Int32Ptr(1)
} else if *target.OriginProtocol == "http" { } else if *target.OriginProtocol == "http" {
reqContent.AccessOriginWay = hwsdk.Int32Ptr(2) source.AccessOriginWay = hwsdk.Int32Ptr(2)
} else if *target.OriginProtocol == "https" { } else if *target.OriginProtocol == "https" {
reqContent.AccessOriginWay = hwsdk.Int32Ptr(3) source.AccessOriginWay = hwsdk.Int32Ptr(3)
} }
if target.ForceRedirect != nil { if target.ForceRedirect != nil {
reqContent.ForceRedirectConfig = &hcCdnModel.ForceRedirect{} if source.ForceRedirectConfig == nil {
source.ForceRedirectConfig = &hccdnmodel.ForceRedirect{}
}
if target.ForceRedirect.Status == "on" { if target.ForceRedirect.Status == "on" {
reqContent.ForceRedirectConfig.Switch = 1 source.ForceRedirectConfig.Switch = 1
reqContent.ForceRedirectConfig.RedirectType = target.ForceRedirect.Type source.ForceRedirectConfig.RedirectType = target.ForceRedirect.Type
} else { } else {
reqContent.ForceRedirectConfig.Switch = 0 source.ForceRedirectConfig.Switch = 0
} }
} }
if target.Https != nil { if target.Https != nil {
if *target.Https.Http2Status == "on" { if *target.Https.Http2Status == "on" {
reqContent.Http2 = hwsdk.Int32Ptr(1) source.Http2 = hwsdk.Int32Ptr(1)
} }
} }
return reqContent return source
} }

View File

@ -8,12 +8,12 @@ import (
"github.com/huaweicloud/huaweicloud-sdk-go-v3/core/auth/basic" "github.com/huaweicloud/huaweicloud-sdk-go-v3/core/auth/basic"
"github.com/huaweicloud/huaweicloud-sdk-go-v3/core/auth/global" "github.com/huaweicloud/huaweicloud-sdk-go-v3/core/auth/global"
hcElb "github.com/huaweicloud/huaweicloud-sdk-go-v3/services/elb/v3" hcelb "github.com/huaweicloud/huaweicloud-sdk-go-v3/services/elb/v3"
hcElbModel "github.com/huaweicloud/huaweicloud-sdk-go-v3/services/elb/v3/model" hcelbmodel "github.com/huaweicloud/huaweicloud-sdk-go-v3/services/elb/v3/model"
hcElbRegion "github.com/huaweicloud/huaweicloud-sdk-go-v3/services/elb/v3/region" hcelbregion "github.com/huaweicloud/huaweicloud-sdk-go-v3/services/elb/v3/region"
hcIam "github.com/huaweicloud/huaweicloud-sdk-go-v3/services/iam/v3" hciam "github.com/huaweicloud/huaweicloud-sdk-go-v3/services/iam/v3"
hcIamModel "github.com/huaweicloud/huaweicloud-sdk-go-v3/services/iam/v3/model" hciammodel "github.com/huaweicloud/huaweicloud-sdk-go-v3/services/iam/v3/model"
hcIamRegion "github.com/huaweicloud/huaweicloud-sdk-go-v3/services/iam/v3/region" hciamregion "github.com/huaweicloud/huaweicloud-sdk-go-v3/services/iam/v3/region"
xerrors "github.com/pkg/errors" xerrors "github.com/pkg/errors"
"golang.org/x/exp/slices" "golang.org/x/exp/slices"
@ -46,7 +46,7 @@ type DeployerConfig struct {
type DeployerProvider struct { type DeployerProvider struct {
config *DeployerConfig config *DeployerConfig
logger *slog.Logger logger *slog.Logger
sdkClient *hcElb.ElbClient sdkClient *hcelb.ElbClient
sslUploader uploader.Uploader sslUploader uploader.Uploader
} }
@ -121,10 +121,10 @@ func (d *DeployerProvider) deployToCertificate(ctx context.Context, certPem stri
// 更新证书 // 更新证书
// REF: https://support.huaweicloud.com/api-elb/UpdateCertificate.html // REF: https://support.huaweicloud.com/api-elb/UpdateCertificate.html
updateCertificateReq := &hcElbModel.UpdateCertificateRequest{ updateCertificateReq := &hcelbmodel.UpdateCertificateRequest{
CertificateId: d.config.CertificateId, CertificateId: d.config.CertificateId,
Body: &hcElbModel.UpdateCertificateRequestBody{ Body: &hcelbmodel.UpdateCertificateRequestBody{
Certificate: &hcElbModel.UpdateCertificateOption{ Certificate: &hcelbmodel.UpdateCertificateOption{
Certificate: hwsdk.StringPtr(certPem), Certificate: hwsdk.StringPtr(certPem),
PrivateKey: hwsdk.StringPtr(privkeyPem), PrivateKey: hwsdk.StringPtr(privkeyPem),
}, },
@ -146,7 +146,7 @@ func (d *DeployerProvider) deployToLoadbalancer(ctx context.Context, certPem str
// 查询负载均衡器详情 // 查询负载均衡器详情
// REF: https://support.huaweicloud.com/api-elb/ShowLoadBalancer.html // REF: https://support.huaweicloud.com/api-elb/ShowLoadBalancer.html
showLoadBalancerReq := &hcElbModel.ShowLoadBalancerRequest{ showLoadBalancerReq := &hcelbmodel.ShowLoadBalancerRequest{
LoadbalancerId: d.config.LoadbalancerId, LoadbalancerId: d.config.LoadbalancerId,
} }
showLoadBalancerResp, err := d.sdkClient.ShowLoadBalancer(showLoadBalancerReq) showLoadBalancerResp, err := d.sdkClient.ShowLoadBalancer(showLoadBalancerReq)
@ -161,7 +161,7 @@ func (d *DeployerProvider) deployToLoadbalancer(ctx context.Context, certPem str
listListenersLimit := int32(2000) listListenersLimit := int32(2000)
var listListenersMarker *string = nil var listListenersMarker *string = nil
for { for {
listListenersReq := &hcElbModel.ListListenersRequest{ listListenersReq := &hcelbmodel.ListListenersRequest{
Limit: hwsdk.Int32Ptr(listListenersLimit), Limit: hwsdk.Int32Ptr(listListenersLimit),
Marker: listListenersMarker, Marker: listListenersMarker,
Protocol: &[]string{"HTTPS", "TERMINATED_HTTPS"}, Protocol: &[]string{"HTTPS", "TERMINATED_HTTPS"},
@ -239,7 +239,7 @@ func (d *DeployerProvider) deployToListener(ctx context.Context, certPem string,
func (d *DeployerProvider) modifyListenerCertificate(ctx context.Context, cloudListenerId string, cloudCertId string) error { func (d *DeployerProvider) modifyListenerCertificate(ctx context.Context, cloudListenerId string, cloudCertId string) error {
// 查询监听器详情 // 查询监听器详情
// REF: https://support.huaweicloud.com/api-elb/ShowListener.html // REF: https://support.huaweicloud.com/api-elb/ShowListener.html
showListenerReq := &hcElbModel.ShowListenerRequest{ showListenerReq := &hcelbmodel.ShowListenerRequest{
ListenerId: cloudListenerId, ListenerId: cloudListenerId,
} }
showListenerResp, err := d.sdkClient.ShowListener(showListenerReq) showListenerResp, err := d.sdkClient.ShowListener(showListenerReq)
@ -250,10 +250,10 @@ func (d *DeployerProvider) modifyListenerCertificate(ctx context.Context, cloudL
// 更新监听器 // 更新监听器
// REF: https://support.huaweicloud.com/api-elb/UpdateListener.html // REF: https://support.huaweicloud.com/api-elb/UpdateListener.html
updateListenerReq := &hcElbModel.UpdateListenerRequest{ updateListenerReq := &hcelbmodel.UpdateListenerRequest{
ListenerId: cloudListenerId, ListenerId: cloudListenerId,
Body: &hcElbModel.UpdateListenerRequestBody{ Body: &hcelbmodel.UpdateListenerRequestBody{
Listener: &hcElbModel.UpdateListenerOption{ Listener: &hcelbmodel.UpdateListenerOption{
DefaultTlsContainerRef: hwsdk.StringPtr(cloudCertId), DefaultTlsContainerRef: hwsdk.StringPtr(cloudCertId),
}, },
}, },
@ -264,7 +264,7 @@ func (d *DeployerProvider) modifyListenerCertificate(ctx context.Context, cloudL
sniCertIds := make([]string, 0) sniCertIds := make([]string, 0)
sniCertIds = append(sniCertIds, cloudCertId) sniCertIds = append(sniCertIds, cloudCertId)
listOldCertificateReq := &hcElbModel.ListCertificatesRequest{ listOldCertificateReq := &hcelbmodel.ListCertificatesRequest{
Id: &showListenerResp.Listener.SniContainerRefs, Id: &showListenerResp.Listener.SniContainerRefs,
} }
listOldCertificateResp, err := d.sdkClient.ListCertificates(listOldCertificateReq) listOldCertificateResp, err := d.sdkClient.ListCertificates(listOldCertificateReq)
@ -273,7 +273,7 @@ func (d *DeployerProvider) modifyListenerCertificate(ctx context.Context, cloudL
return xerrors.Wrap(err, "failed to execute sdk request 'elb.ListCertificates'") return xerrors.Wrap(err, "failed to execute sdk request 'elb.ListCertificates'")
} }
showNewCertificateReq := &hcElbModel.ShowCertificateRequest{ showNewCertificateReq := &hcelbmodel.ShowCertificateRequest{
CertificateId: cloudCertId, CertificateId: cloudCertId,
} }
showNewCertificateResp, err := d.sdkClient.ShowCertificate(showNewCertificateReq) showNewCertificateResp, err := d.sdkClient.ShowCertificate(showNewCertificateReq)
@ -315,7 +315,7 @@ func (d *DeployerProvider) modifyListenerCertificate(ctx context.Context, cloudL
return nil return nil
} }
func createSdkClient(accessKeyId, secretAccessKey, region string) (*hcElb.ElbClient, error) { func createSdkClient(accessKeyId, secretAccessKey, region string) (*hcelb.ElbClient, error) {
projectId, err := getSdkProjectId(accessKeyId, secretAccessKey, region) projectId, err := getSdkProjectId(accessKeyId, secretAccessKey, region)
if err != nil { if err != nil {
return nil, err return nil, err
@ -330,12 +330,12 @@ func createSdkClient(accessKeyId, secretAccessKey, region string) (*hcElb.ElbCli
return nil, err return nil, err
} }
hcRegion, err := hcElbRegion.SafeValueOf(region) hcRegion, err := hcelbregion.SafeValueOf(region)
if err != nil { if err != nil {
return nil, err return nil, err
} }
hcClient, err := hcElb.ElbClientBuilder(). hcClient, err := hcelb.ElbClientBuilder().
WithRegion(hcRegion). WithRegion(hcRegion).
WithCredential(auth). WithCredential(auth).
SafeBuild() SafeBuild()
@ -343,7 +343,7 @@ func createSdkClient(accessKeyId, secretAccessKey, region string) (*hcElb.ElbCli
return nil, err return nil, err
} }
client := hcElb.NewElbClient(hcClient) client := hcelb.NewElbClient(hcClient)
return client, nil return client, nil
} }
@ -360,12 +360,12 @@ func getSdkProjectId(accessKeyId, secretAccessKey, region string) (string, error
return "", err return "", err
} }
hcRegion, err := hcIamRegion.SafeValueOf(region) hcRegion, err := hciamregion.SafeValueOf(region)
if err != nil { if err != nil {
return "", err return "", err
} }
hcClient, err := hcIam.IamClientBuilder(). hcClient, err := hciam.IamClientBuilder().
WithRegion(hcRegion). WithRegion(hcRegion).
WithCredential(auth). WithCredential(auth).
SafeBuild() SafeBuild()
@ -373,9 +373,9 @@ func getSdkProjectId(accessKeyId, secretAccessKey, region string) (string, error
return "", err return "", err
} }
client := hcIam.NewIamClient(hcClient) client := hciam.NewIamClient(hcClient)
request := &hcIamModel.KeystoneListProjectsRequest{ request := &hciammodel.KeystoneListProjectsRequest{
Name: &region, Name: &region,
} }
response, err := client.KeystoneListProjects(request) response, err := client.KeystoneListProjects(request)

View File

@ -0,0 +1,69 @@
package huaweicloudscm
import (
"context"
"log/slog"
xerrors "github.com/pkg/errors"
"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/huaweicloud-scm"
)
type DeployerConfig struct {
// 华为云 AccessKeyId。
AccessKeyId string `json:"accessKeyId"`
// 华为云 SecretAccessKey。
SecretAccessKey string `json:"secretAccessKey"`
}
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,
})
if err != nil {
return nil, xerrors.Wrap(err, "failed to create ssl uploader")
}
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.Default()
} else {
d.logger = logger
}
d.sslUploader.WithLogger(logger)
return d
}
func (d *DeployerProvider) Deploy(ctx context.Context, certPem string, privkeyPem string) (*deployer.DeployResult, error) {
// 上传证书到 SCM
upres, err := d.sslUploader.Upload(ctx, certPem, privkeyPem)
if err != nil {
return nil, xerrors.Wrap(err, "failed to upload certificate file")
} else {
d.logger.Info("ssl certificate uploaded", slog.Any("result", upres))
}
return &deployer.DeployResult{}, nil
}

View File

@ -9,12 +9,12 @@ import (
"github.com/huaweicloud/huaweicloud-sdk-go-v3/core/auth/basic" "github.com/huaweicloud/huaweicloud-sdk-go-v3/core/auth/basic"
"github.com/huaweicloud/huaweicloud-sdk-go-v3/core/auth/global" "github.com/huaweicloud/huaweicloud-sdk-go-v3/core/auth/global"
hcIam "github.com/huaweicloud/huaweicloud-sdk-go-v3/services/iam/v3" hciam "github.com/huaweicloud/huaweicloud-sdk-go-v3/services/iam/v3"
hcIamModel "github.com/huaweicloud/huaweicloud-sdk-go-v3/services/iam/v3/model" hciamModel "github.com/huaweicloud/huaweicloud-sdk-go-v3/services/iam/v3/model"
hcIamRegion "github.com/huaweicloud/huaweicloud-sdk-go-v3/services/iam/v3/region" hciamregion "github.com/huaweicloud/huaweicloud-sdk-go-v3/services/iam/v3/region"
hcWaf "github.com/huaweicloud/huaweicloud-sdk-go-v3/services/waf/v1" hcwaf "github.com/huaweicloud/huaweicloud-sdk-go-v3/services/waf/v1"
hcWafModel "github.com/huaweicloud/huaweicloud-sdk-go-v3/services/waf/v1/model" hcwafmodel "github.com/huaweicloud/huaweicloud-sdk-go-v3/services/waf/v1/model"
hcWafRegion "github.com/huaweicloud/huaweicloud-sdk-go-v3/services/waf/v1/region" hcwafregion "github.com/huaweicloud/huaweicloud-sdk-go-v3/services/waf/v1/region"
xerrors "github.com/pkg/errors" xerrors "github.com/pkg/errors"
"github.com/usual2970/certimate/internal/pkg/core/deployer" "github.com/usual2970/certimate/internal/pkg/core/deployer"
@ -43,7 +43,7 @@ type DeployerConfig struct {
type DeployerProvider struct { type DeployerProvider struct {
config *DeployerConfig config *DeployerConfig
logger *slog.Logger logger *slog.Logger
sdkClient *hcWaf.WafClient sdkClient *hcwaf.WafClient
sslUploader uploader.Uploader sslUploader uploader.Uploader
} }
@ -126,7 +126,7 @@ func (d *DeployerProvider) deployToCertificate(ctx context.Context, certPem stri
// 查询证书 // 查询证书
// REF: https://support.huaweicloud.com/api-waf/ShowCertificate.html // REF: https://support.huaweicloud.com/api-waf/ShowCertificate.html
showCertificateReq := &hcWafModel.ShowCertificateRequest{ showCertificateReq := &hcwafmodel.ShowCertificateRequest{
CertificateId: d.config.CertificateId, CertificateId: d.config.CertificateId,
} }
showCertificateResp, err := d.sdkClient.ShowCertificate(showCertificateReq) showCertificateResp, err := d.sdkClient.ShowCertificate(showCertificateReq)
@ -137,9 +137,9 @@ func (d *DeployerProvider) deployToCertificate(ctx context.Context, certPem stri
// 更新证书 // 更新证书
// REF: https://support.huaweicloud.com/api-waf/UpdateCertificate.html // REF: https://support.huaweicloud.com/api-waf/UpdateCertificate.html
updateCertificateReq := &hcWafModel.UpdateCertificateRequest{ updateCertificateReq := &hcwafmodel.UpdateCertificateRequest{
CertificateId: d.config.CertificateId, CertificateId: d.config.CertificateId,
Body: &hcWafModel.UpdateCertificateRequestBody{ Body: &hcwafmodel.UpdateCertificateRequestBody{
Name: *showCertificateResp.Name, Name: *showCertificateResp.Name,
Content: hwsdk.StringPtr(certPem), Content: hwsdk.StringPtr(certPem),
Key: hwsdk.StringPtr(privkeyPem), Key: hwsdk.StringPtr(privkeyPem),
@ -173,7 +173,7 @@ func (d *DeployerProvider) deployToCloudServer(ctx context.Context, certPem stri
listHostPage := int32(1) listHostPage := int32(1)
listHostPageSize := int32(100) listHostPageSize := int32(100)
for { for {
listHostReq := &hcWafModel.ListHostRequest{ listHostReq := &hcwafmodel.ListHostRequest{
Hostname: hwsdk.StringPtr(strings.TrimPrefix(d.config.Domain, "*")), Hostname: hwsdk.StringPtr(strings.TrimPrefix(d.config.Domain, "*")),
Page: hwsdk.Int32Ptr(listHostPage), Page: hwsdk.Int32Ptr(listHostPage),
Pagesize: hwsdk.Int32Ptr(listHostPageSize), Pagesize: hwsdk.Int32Ptr(listHostPageSize),
@ -205,9 +205,9 @@ func (d *DeployerProvider) deployToCloudServer(ctx context.Context, certPem stri
// 更新云模式防护域名的配置 // 更新云模式防护域名的配置
// REF: https://support.huaweicloud.com/api-waf/UpdateHost.html // REF: https://support.huaweicloud.com/api-waf/UpdateHost.html
updateHostReq := &hcWafModel.UpdateHostRequest{ updateHostReq := &hcwafmodel.UpdateHostRequest{
InstanceId: hostId, InstanceId: hostId,
Body: &hcWafModel.UpdateHostRequestBody{ Body: &hcwafmodel.UpdateHostRequestBody{
Certificateid: hwsdk.StringPtr(upres.CertId), Certificateid: hwsdk.StringPtr(upres.CertId),
Certificatename: hwsdk.StringPtr(upres.CertName), Certificatename: hwsdk.StringPtr(upres.CertName),
}, },
@ -240,7 +240,7 @@ func (d *DeployerProvider) deployToPremiumHost(ctx context.Context, certPem stri
listPremiumHostPage := int32(1) listPremiumHostPage := int32(1)
listPremiumHostPageSize := int32(100) listPremiumHostPageSize := int32(100)
for { for {
listPremiumHostReq := &hcWafModel.ListPremiumHostRequest{ listPremiumHostReq := &hcwafmodel.ListPremiumHostRequest{
Hostname: hwsdk.StringPtr(strings.TrimPrefix(d.config.Domain, "*")), Hostname: hwsdk.StringPtr(strings.TrimPrefix(d.config.Domain, "*")),
Page: hwsdk.StringPtr(fmt.Sprintf("%d", listPremiumHostPage)), Page: hwsdk.StringPtr(fmt.Sprintf("%d", listPremiumHostPage)),
Pagesize: hwsdk.StringPtr(fmt.Sprintf("%d", listPremiumHostPageSize)), Pagesize: hwsdk.StringPtr(fmt.Sprintf("%d", listPremiumHostPageSize)),
@ -272,9 +272,9 @@ func (d *DeployerProvider) deployToPremiumHost(ctx context.Context, certPem stri
// 修改独享模式域名配置 // 修改独享模式域名配置
// REF: https://support.huaweicloud.com/api-waf/UpdatePremiumHost.html // REF: https://support.huaweicloud.com/api-waf/UpdatePremiumHost.html
updatePremiumHostReq := &hcWafModel.UpdatePremiumHostRequest{ updatePremiumHostReq := &hcwafmodel.UpdatePremiumHostRequest{
HostId: hostId, HostId: hostId,
Body: &hcWafModel.UpdatePremiumHostRequestBody{ Body: &hcwafmodel.UpdatePremiumHostRequestBody{
Certificateid: hwsdk.StringPtr(upres.CertId), Certificateid: hwsdk.StringPtr(upres.CertId),
Certificatename: hwsdk.StringPtr(upres.CertName), Certificatename: hwsdk.StringPtr(upres.CertName),
}, },
@ -288,7 +288,7 @@ func (d *DeployerProvider) deployToPremiumHost(ctx context.Context, certPem stri
return nil return nil
} }
func createSdkClient(accessKeyId, secretAccessKey, region string) (*hcWaf.WafClient, error) { func createSdkClient(accessKeyId, secretAccessKey, region string) (*hcwaf.WafClient, error) {
projectId, err := getSdkProjectId(accessKeyId, secretAccessKey, region) projectId, err := getSdkProjectId(accessKeyId, secretAccessKey, region)
if err != nil { if err != nil {
return nil, err return nil, err
@ -303,12 +303,12 @@ func createSdkClient(accessKeyId, secretAccessKey, region string) (*hcWaf.WafCli
return nil, err return nil, err
} }
hcRegion, err := hcWafRegion.SafeValueOf(region) hcRegion, err := hcwafregion.SafeValueOf(region)
if err != nil { if err != nil {
return nil, err return nil, err
} }
hcClient, err := hcWaf.WafClientBuilder(). hcClient, err := hcwaf.WafClientBuilder().
WithRegion(hcRegion). WithRegion(hcRegion).
WithCredential(auth). WithCredential(auth).
SafeBuild() SafeBuild()
@ -316,7 +316,7 @@ func createSdkClient(accessKeyId, secretAccessKey, region string) (*hcWaf.WafCli
return nil, err return nil, err
} }
client := hcWaf.NewWafClient(hcClient) client := hcwaf.NewWafClient(hcClient)
return client, nil return client, nil
} }
@ -329,12 +329,12 @@ func getSdkProjectId(accessKeyId, secretAccessKey, region string) (string, error
return "", err return "", err
} }
hcRegion, err := hcIamRegion.SafeValueOf(region) hcRegion, err := hciamregion.SafeValueOf(region)
if err != nil { if err != nil {
return "", err return "", err
} }
hcClient, err := hcIam.IamClientBuilder(). hcClient, err := hciam.IamClientBuilder().
WithRegion(hcRegion). WithRegion(hcRegion).
WithCredential(auth). WithCredential(auth).
SafeBuild() SafeBuild()
@ -342,9 +342,9 @@ func getSdkProjectId(accessKeyId, secretAccessKey, region string) (string, error
return "", err return "", err
} }
client := hcIam.NewIamClient(hcClient) client := hciam.NewIamClient(hcClient)
request := &hcIamModel.KeystoneListProjectsRequest{ request := &hciamModel.KeystoneListProjectsRequest{
Name: &region, Name: &region,
} }
response, err := client.KeystoneListProjects(request) response, err := client.KeystoneListProjects(request)

View File

@ -7,11 +7,11 @@ import (
"log/slog" "log/slog"
"strings" "strings"
jdCore "github.com/jdcloud-api/jdcloud-sdk-go/core" jdcore "github.com/jdcloud-api/jdcloud-sdk-go/core"
jdCommon "github.com/jdcloud-api/jdcloud-sdk-go/services/common/models" jdcommon "github.com/jdcloud-api/jdcloud-sdk-go/services/common/models"
jdLbApi "github.com/jdcloud-api/jdcloud-sdk-go/services/lb/apis" jdlbapi "github.com/jdcloud-api/jdcloud-sdk-go/services/lb/apis"
jdLbClient "github.com/jdcloud-api/jdcloud-sdk-go/services/lb/client" jdlbclient "github.com/jdcloud-api/jdcloud-sdk-go/services/lb/client"
jdLbModel "github.com/jdcloud-api/jdcloud-sdk-go/services/lb/models" jdlbmodel "github.com/jdcloud-api/jdcloud-sdk-go/services/lb/models"
xerrors "github.com/pkg/errors" xerrors "github.com/pkg/errors"
"github.com/usual2970/certimate/internal/pkg/core/deployer" "github.com/usual2970/certimate/internal/pkg/core/deployer"
@ -43,7 +43,7 @@ type DeployerConfig struct {
type DeployerProvider struct { type DeployerProvider struct {
config *DeployerConfig config *DeployerConfig
logger *slog.Logger logger *slog.Logger
sdkClient *jdLbClient.LbClient sdkClient *jdlbclient.LbClient
sslUploader uploader.Uploader sslUploader uploader.Uploader
} }
@ -120,7 +120,7 @@ func (d *DeployerProvider) deployToLoadbalancer(ctx context.Context, cloudCertId
// 查询负载均衡器详情 // 查询负载均衡器详情
// REF: https://docs.jdcloud.com/cn/load-balancer/api/describeloadbalancer // REF: https://docs.jdcloud.com/cn/load-balancer/api/describeloadbalancer
describeLoadBalancerReq := jdLbApi.NewDescribeLoadBalancerRequest(d.config.RegionId, d.config.LoadbalancerId) describeLoadBalancerReq := jdlbapi.NewDescribeLoadBalancerRequest(d.config.RegionId, d.config.LoadbalancerId)
describeLoadBalancerResp, err := d.sdkClient.DescribeLoadBalancer(describeLoadBalancerReq) describeLoadBalancerResp, err := d.sdkClient.DescribeLoadBalancer(describeLoadBalancerReq)
d.logger.Debug("sdk request 'lb.DescribeLoadBalancer'", slog.Any("request", describeLoadBalancerReq), slog.Any("response", describeLoadBalancerResp)) d.logger.Debug("sdk request 'lb.DescribeLoadBalancer'", slog.Any("request", describeLoadBalancerReq), slog.Any("response", describeLoadBalancerResp))
if err != nil { if err != nil {
@ -133,8 +133,8 @@ func (d *DeployerProvider) deployToLoadbalancer(ctx context.Context, cloudCertId
describeListenersPageNumber := 1 describeListenersPageNumber := 1
describeListenersPageSize := 100 describeListenersPageSize := 100
for { for {
describeListenersReq := jdLbApi.NewDescribeListenersRequest(d.config.RegionId) describeListenersReq := jdlbapi.NewDescribeListenersRequest(d.config.RegionId)
describeListenersReq.SetFilters([]jdCommon.Filter{{Name: "loadBalancerId", Values: []string{d.config.LoadbalancerId}}}) describeListenersReq.SetFilters([]jdcommon.Filter{{Name: "loadBalancerId", Values: []string{d.config.LoadbalancerId}}})
describeListenersReq.SetPageSize(describeListenersPageNumber) describeListenersReq.SetPageSize(describeListenersPageNumber)
describeListenersReq.SetPageSize(describeListenersPageSize) describeListenersReq.SetPageSize(describeListenersPageSize)
describeListenersResp, err := d.sdkClient.DescribeListeners(describeListenersReq) describeListenersResp, err := d.sdkClient.DescribeListeners(describeListenersReq)
@ -194,7 +194,7 @@ func (d *DeployerProvider) deployToListener(ctx context.Context, cloudCertId str
func (d *DeployerProvider) updateListenerCertificate(ctx context.Context, cloudListenerId string, cloudCertId string) error { func (d *DeployerProvider) updateListenerCertificate(ctx context.Context, cloudListenerId string, cloudCertId string) error {
// 查询监听器详情 // 查询监听器详情
// REF: https://docs.jdcloud.com/cn/load-balancer/api/describelistener // REF: https://docs.jdcloud.com/cn/load-balancer/api/describelistener
describeListenerReq := jdLbApi.NewDescribeListenerRequest(d.config.RegionId, cloudListenerId) describeListenerReq := jdlbapi.NewDescribeListenerRequest(d.config.RegionId, cloudListenerId)
describeListenerResp, err := d.sdkClient.DescribeListener(describeListenerReq) describeListenerResp, err := d.sdkClient.DescribeListener(describeListenerReq)
d.logger.Debug("sdk request 'lb.DescribeListener'", slog.Any("request", describeListenerReq), slog.Any("response", describeListenerResp)) d.logger.Debug("sdk request 'lb.DescribeListener'", slog.Any("request", describeListenerReq), slog.Any("response", describeListenerResp))
if err != nil { if err != nil {
@ -206,8 +206,8 @@ func (d *DeployerProvider) updateListenerCertificate(ctx context.Context, cloudL
// 修改监听器信息 // 修改监听器信息
// REF: https://docs.jdcloud.com/cn/load-balancer/api/updatelistener // REF: https://docs.jdcloud.com/cn/load-balancer/api/updatelistener
updateListenerReq := jdLbApi.NewUpdateListenerRequest(d.config.RegionId, cloudListenerId) updateListenerReq := jdlbapi.NewUpdateListenerRequest(d.config.RegionId, cloudListenerId)
updateListenerReq.SetCertificateSpecs([]jdLbModel.CertificateSpec{{CertificateId: cloudCertId}}) updateListenerReq.SetCertificateSpecs([]jdlbmodel.CertificateSpec{{CertificateId: cloudCertId}})
updateListenerResp, err := d.sdkClient.UpdateListener(updateListenerReq) updateListenerResp, err := d.sdkClient.UpdateListener(updateListenerReq)
d.logger.Debug("sdk request 'lb.UpdateListener'", slog.Any("request", updateListenerReq), slog.Any("response", updateListenerResp)) d.logger.Debug("sdk request 'lb.UpdateListener'", slog.Any("request", updateListenerReq), slog.Any("response", updateListenerResp))
if err != nil { if err != nil {
@ -216,7 +216,7 @@ func (d *DeployerProvider) updateListenerCertificate(ctx context.Context, cloudL
} else { } else {
// 指定 SNI需部署到扩展证书 // 指定 SNI需部署到扩展证书
extCertSpecs := sliceutil.Filter(describeListenerResp.Result.Listener.ExtensionCertificateSpecs, func(extCertSpec jdLbModel.ExtensionCertificateSpec) bool { extCertSpecs := sliceutil.Filter(describeListenerResp.Result.Listener.ExtensionCertificateSpecs, func(extCertSpec jdlbmodel.ExtensionCertificateSpec) bool {
return extCertSpec.Domain == d.config.Domain return extCertSpec.Domain == d.config.Domain
}) })
if len(extCertSpecs) == 0 { if len(extCertSpecs) == 0 {
@ -225,11 +225,11 @@ func (d *DeployerProvider) updateListenerCertificate(ctx context.Context, cloudL
// 批量修改扩展证书 // 批量修改扩展证书
// REF: https://docs.jdcloud.com/cn/load-balancer/api/updatelistenercertificates // REF: https://docs.jdcloud.com/cn/load-balancer/api/updatelistenercertificates
updateListenerCertificatesReq := jdLbApi.NewUpdateListenerCertificatesRequest( updateListenerCertificatesReq := jdlbapi.NewUpdateListenerCertificatesRequest(
d.config.RegionId, d.config.RegionId,
cloudListenerId, cloudListenerId,
sliceutil.Map(extCertSpecs, func(extCertSpec jdLbModel.ExtensionCertificateSpec) jdLbModel.ExtCertificateUpdateSpec { sliceutil.Map(extCertSpecs, func(extCertSpec jdlbmodel.ExtensionCertificateSpec) jdlbmodel.ExtCertificateUpdateSpec {
return jdLbModel.ExtCertificateUpdateSpec{ return jdlbmodel.ExtCertificateUpdateSpec{
CertificateBindId: extCertSpec.CertificateBindId, CertificateBindId: extCertSpec.CertificateBindId,
CertificateId: &cloudCertId, CertificateId: &cloudCertId,
Domain: &extCertSpec.Domain, Domain: &extCertSpec.Domain,
@ -246,9 +246,9 @@ func (d *DeployerProvider) updateListenerCertificate(ctx context.Context, cloudL
return nil return nil
} }
func createSdkClient(accessKeyId, accessKeySecret string) (*jdLbClient.LbClient, error) { func createSdkClient(accessKeyId, accessKeySecret string) (*jdlbclient.LbClient, error) {
clientCredentials := jdCore.NewCredentials(accessKeyId, accessKeySecret) clientCredentials := jdcore.NewCredentials(accessKeyId, accessKeySecret)
client := jdLbClient.NewLbClient(clientCredentials) client := jdlbclient.NewLbClient(clientCredentials)
client.SetLogger(jdCore.NewDefaultLogger(jdCore.LogWarn)) client.SetLogger(jdcore.NewDefaultLogger(jdcore.LogWarn))
return client, nil return client, nil
} }

View File

@ -4,9 +4,9 @@ import (
"context" "context"
"log/slog" "log/slog"
jdCore "github.com/jdcloud-api/jdcloud-sdk-go/core" jdcore "github.com/jdcloud-api/jdcloud-sdk-go/core"
jdCdnApi "github.com/jdcloud-api/jdcloud-sdk-go/services/cdn/apis" jdcdnapi "github.com/jdcloud-api/jdcloud-sdk-go/services/cdn/apis"
jdCdnClient "github.com/jdcloud-api/jdcloud-sdk-go/services/cdn/client" jdcdnclient "github.com/jdcloud-api/jdcloud-sdk-go/services/cdn/client"
xerrors "github.com/pkg/errors" xerrors "github.com/pkg/errors"
"github.com/usual2970/certimate/internal/pkg/core/deployer" "github.com/usual2970/certimate/internal/pkg/core/deployer"
@ -26,7 +26,7 @@ type DeployerConfig struct {
type DeployerProvider struct { type DeployerProvider struct {
config *DeployerConfig config *DeployerConfig
logger *slog.Logger logger *slog.Logger
sdkClient *jdCdnClient.CdnClient sdkClient *jdcdnclient.CdnClient
sslUploader uploader.Uploader sslUploader uploader.Uploader
} }
@ -71,7 +71,7 @@ func (d *DeployerProvider) WithLogger(logger *slog.Logger) deployer.Deployer {
func (d *DeployerProvider) Deploy(ctx context.Context, certPem string, privkeyPem string) (*deployer.DeployResult, error) { func (d *DeployerProvider) Deploy(ctx context.Context, certPem string, privkeyPem string) (*deployer.DeployResult, error) {
// 查询域名配置信息 // 查询域名配置信息
// REF: https://docs.jdcloud.com/cn/cdn/api/querydomainconfig // REF: https://docs.jdcloud.com/cn/cdn/api/querydomainconfig
queryDomainConfigReq := jdCdnApi.NewQueryDomainConfigRequest(d.config.Domain) queryDomainConfigReq := jdcdnapi.NewQueryDomainConfigRequest(d.config.Domain)
queryDomainConfigResp, err := d.sdkClient.QueryDomainConfig(queryDomainConfigReq) queryDomainConfigResp, err := d.sdkClient.QueryDomainConfig(queryDomainConfigReq)
d.logger.Debug("sdk request 'cdn.QueryDomainConfig'", slog.Any("request", queryDomainConfigReq), slog.Any("response", queryDomainConfigResp)) d.logger.Debug("sdk request 'cdn.QueryDomainConfig'", slog.Any("request", queryDomainConfigReq), slog.Any("response", queryDomainConfigResp))
if err != nil { if err != nil {
@ -88,7 +88,7 @@ func (d *DeployerProvider) Deploy(ctx context.Context, certPem string, privkeyPe
// 设置通讯协议 // 设置通讯协议
// REF: https://docs.jdcloud.com/cn/cdn/api/sethttptype // REF: https://docs.jdcloud.com/cn/cdn/api/sethttptype
setHttpTypeReq := jdCdnApi.NewSetHttpTypeRequest(d.config.Domain) setHttpTypeReq := jdcdnapi.NewSetHttpTypeRequest(d.config.Domain)
setHttpTypeReq.SetHttpType("https") setHttpTypeReq.SetHttpType("https")
setHttpTypeReq.SetCertificate(certPem) setHttpTypeReq.SetCertificate(certPem)
setHttpTypeReq.SetRsaKey(privkeyPem) setHttpTypeReq.SetRsaKey(privkeyPem)
@ -104,9 +104,9 @@ func (d *DeployerProvider) Deploy(ctx context.Context, certPem string, privkeyPe
return &deployer.DeployResult{}, nil return &deployer.DeployResult{}, nil
} }
func createSdkClient(accessKeyId, accessKeySecret string) (*jdCdnClient.CdnClient, error) { func createSdkClient(accessKeyId, accessKeySecret string) (*jdcdnclient.CdnClient, error) {
clientCredentials := jdCore.NewCredentials(accessKeyId, accessKeySecret) clientCredentials := jdcore.NewCredentials(accessKeyId, accessKeySecret)
client := jdCdnClient.NewCdnClient(clientCredentials) client := jdcdnclient.NewCdnClient(clientCredentials)
client.SetLogger(jdCore.NewDefaultLogger(jdCore.LogWarn)) client.SetLogger(jdcore.NewDefaultLogger(jdcore.LogWarn))
return client, nil return client, nil
} }

View File

@ -4,9 +4,9 @@ import (
"context" "context"
"log/slog" "log/slog"
jdCore "github.com/jdcloud-api/jdcloud-sdk-go/core" jdcore "github.com/jdcloud-api/jdcloud-sdk-go/core"
jdLiveApi "github.com/jdcloud-api/jdcloud-sdk-go/services/live/apis" jdliveapi "github.com/jdcloud-api/jdcloud-sdk-go/services/live/apis"
jdLiveClient "github.com/jdcloud-api/jdcloud-sdk-go/services/live/client" jdliveclient "github.com/jdcloud-api/jdcloud-sdk-go/services/live/client"
xerrors "github.com/pkg/errors" xerrors "github.com/pkg/errors"
"github.com/usual2970/certimate/internal/pkg/core/deployer" "github.com/usual2970/certimate/internal/pkg/core/deployer"
@ -24,7 +24,7 @@ type DeployerConfig struct {
type DeployerProvider struct { type DeployerProvider struct {
config *DeployerConfig config *DeployerConfig
logger *slog.Logger logger *slog.Logger
sdkClient *jdLiveClient.LiveClient sdkClient *jdliveclient.LiveClient
} }
var _ deployer.Deployer = (*DeployerProvider)(nil) var _ deployer.Deployer = (*DeployerProvider)(nil)
@ -58,7 +58,7 @@ func (d *DeployerProvider) WithLogger(logger *slog.Logger) deployer.Deployer {
func (d *DeployerProvider) Deploy(ctx context.Context, certPem string, privkeyPem string) (*deployer.DeployResult, error) { func (d *DeployerProvider) Deploy(ctx context.Context, certPem string, privkeyPem string) (*deployer.DeployResult, error) {
// 设置直播证书 // 设置直播证书
// REF: https://docs.jdcloud.com/cn/live-video/api/setlivedomaincertificate // REF: https://docs.jdcloud.com/cn/live-video/api/setlivedomaincertificate
setLiveDomainCertificateReq := jdLiveApi.NewSetLiveDomainCertificateRequest(d.config.Domain, "on") setLiveDomainCertificateReq := jdliveapi.NewSetLiveDomainCertificateRequest(d.config.Domain, "on")
setLiveDomainCertificateReq.SetCert(certPem) setLiveDomainCertificateReq.SetCert(certPem)
setLiveDomainCertificateReq.SetKey(privkeyPem) setLiveDomainCertificateReq.SetKey(privkeyPem)
setLiveDomainCertificateResp, err := d.sdkClient.SetLiveDomainCertificate(setLiveDomainCertificateReq) setLiveDomainCertificateResp, err := d.sdkClient.SetLiveDomainCertificate(setLiveDomainCertificateReq)
@ -70,9 +70,9 @@ func (d *DeployerProvider) Deploy(ctx context.Context, certPem string, privkeyPe
return &deployer.DeployResult{}, nil return &deployer.DeployResult{}, nil
} }
func createSdkClient(accessKeyId, accessKeySecret string) (*jdLiveClient.LiveClient, error) { func createSdkClient(accessKeyId, accessKeySecret string) (*jdliveclient.LiveClient, error) {
clientCredentials := jdCore.NewCredentials(accessKeyId, accessKeySecret) clientCredentials := jdcore.NewCredentials(accessKeyId, accessKeySecret)
client := jdLiveClient.NewLiveClient(clientCredentials) client := jdliveclient.NewLiveClient(clientCredentials)
client.SetLogger(jdCore.NewDefaultLogger(jdCore.LogWarn)) client.SetLogger(jdcore.NewDefaultLogger(jdcore.LogWarn))
return client, nil return client, nil
} }

View File

@ -7,9 +7,9 @@ import (
"strconv" "strconv"
"time" "time"
jdCore "github.com/jdcloud-api/jdcloud-sdk-go/core" jdcore "github.com/jdcloud-api/jdcloud-sdk-go/core"
jdVodApi "github.com/jdcloud-api/jdcloud-sdk-go/services/vod/apis" jdvodapi "github.com/jdcloud-api/jdcloud-sdk-go/services/vod/apis"
jdVodClient "github.com/jdcloud-api/jdcloud-sdk-go/services/vod/client" jdvodclient "github.com/jdcloud-api/jdcloud-sdk-go/services/vod/client"
xerrors "github.com/pkg/errors" xerrors "github.com/pkg/errors"
"github.com/usual2970/certimate/internal/pkg/core/deployer" "github.com/usual2970/certimate/internal/pkg/core/deployer"
@ -27,7 +27,7 @@ type DeployerConfig struct {
type DeployerProvider struct { type DeployerProvider struct {
config *DeployerConfig config *DeployerConfig
logger *slog.Logger logger *slog.Logger
sdkClient *jdVodClient.VodClient sdkClient *jdvodclient.VodClient
} }
var _ deployer.Deployer = (*DeployerProvider)(nil) var _ deployer.Deployer = (*DeployerProvider)(nil)
@ -65,7 +65,7 @@ func (d *DeployerProvider) Deploy(ctx context.Context, certPem string, privkeyPe
listDomainsPageNumber := 1 listDomainsPageNumber := 1
listDomainsPageSize := 100 listDomainsPageSize := 100
for { for {
listDomainsReq := jdVodApi.NewListDomainsRequest() listDomainsReq := jdvodapi.NewListDomainsRequest()
listDomainsReq.SetPageNumber(1) listDomainsReq.SetPageNumber(1)
listDomainsReq.SetPageSize(100) listDomainsReq.SetPageSize(100)
listDomainsResp, err := d.sdkClient.ListDomains(listDomainsReq) listDomainsResp, err := d.sdkClient.ListDomains(listDomainsReq)
@ -93,7 +93,7 @@ func (d *DeployerProvider) Deploy(ctx context.Context, certPem string, privkeyPe
// 查询域名 SSL 配置 // 查询域名 SSL 配置
// REF: https://docs.jdcloud.com/cn/video-on-demand/api/gethttpssl // REF: https://docs.jdcloud.com/cn/video-on-demand/api/gethttpssl
getHttpSslReq := jdVodApi.NewGetHttpSslRequest(domainId) getHttpSslReq := jdvodapi.NewGetHttpSslRequest(domainId)
getHttpSslResp, err := d.sdkClient.GetHttpSsl(getHttpSslReq) getHttpSslResp, err := d.sdkClient.GetHttpSsl(getHttpSslReq)
d.logger.Debug("sdk request 'vod.GetHttpSsl'", slog.Any("request", getHttpSslReq), slog.Any("response", getHttpSslResp)) d.logger.Debug("sdk request 'vod.GetHttpSsl'", slog.Any("request", getHttpSslReq), slog.Any("response", getHttpSslResp))
if err != nil { if err != nil {
@ -102,7 +102,7 @@ func (d *DeployerProvider) Deploy(ctx context.Context, certPem string, privkeyPe
// 设置域名 SSL 配置 // 设置域名 SSL 配置
// REF: https://docs.jdcloud.com/cn/video-on-demand/api/sethttpssl // REF: https://docs.jdcloud.com/cn/video-on-demand/api/sethttpssl
setHttpSslReq := jdVodApi.NewSetHttpSslRequest(domainId) setHttpSslReq := jdvodapi.NewSetHttpSslRequest(domainId)
setHttpSslReq.SetTitle(fmt.Sprintf("certimate-%d", time.Now().UnixMilli())) setHttpSslReq.SetTitle(fmt.Sprintf("certimate-%d", time.Now().UnixMilli()))
setHttpSslReq.SetSslCert(certPem) setHttpSslReq.SetSslCert(certPem)
setHttpSslReq.SetSslKey(privkeyPem) setHttpSslReq.SetSslKey(privkeyPem)
@ -118,9 +118,9 @@ func (d *DeployerProvider) Deploy(ctx context.Context, certPem string, privkeyPe
return &deployer.DeployResult{}, nil return &deployer.DeployResult{}, nil
} }
func createSdkClient(accessKeyId, accessKeySecret string) (*jdVodClient.VodClient, error) { func createSdkClient(accessKeyId, accessKeySecret string) (*jdvodclient.VodClient, error) {
clientCredentials := jdCore.NewCredentials(accessKeyId, accessKeySecret) clientCredentials := jdcore.NewCredentials(accessKeyId, accessKeySecret)
client := jdVodClient.NewVodClient(clientCredentials) client := jdvodclient.NewVodClient(clientCredentials)
client.SetLogger(jdCore.NewDefaultLogger(jdCore.LogWarn)) client.SetLogger(jdcore.NewDefaultLogger(jdcore.LogWarn))
return client, nil return client, nil
} }

View File

@ -7,8 +7,8 @@ import (
"strings" "strings"
xerrors "github.com/pkg/errors" xerrors "github.com/pkg/errors"
k8sCore "k8s.io/api/core/v1" k8score "k8s.io/api/core/v1"
k8sMeta "k8s.io/apimachinery/pkg/apis/meta/v1" k8smeta "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes" "k8s.io/client-go/kubernetes"
"k8s.io/client-go/rest" "k8s.io/client-go/rest"
"k8s.io/client-go/tools/clientcmd" "k8s.io/client-go/tools/clientcmd"
@ -87,7 +87,7 @@ func (d *DeployerProvider) Deploy(ctx context.Context, certPem string, privkeyPe
return nil, xerrors.Wrap(err, "failed to create k8s client") return nil, xerrors.Wrap(err, "failed to create k8s client")
} }
var secretPayload *k8sCore.Secret var secretPayload *k8score.Secret
secretAnnotations := map[string]string{ secretAnnotations := map[string]string{
"certimate/common-name": certX509.Subject.CommonName, "certimate/common-name": certX509.Subject.CommonName,
"certimate/subject-sn": certX509.Subject.SerialNumber, "certimate/subject-sn": certX509.Subject.SerialNumber,
@ -97,24 +97,24 @@ func (d *DeployerProvider) Deploy(ctx context.Context, certPem string, privkeyPe
} }
// 获取 Secret 实例,如果不存在则创建 // 获取 Secret 实例,如果不存在则创建
secretPayload, err = client.CoreV1().Secrets(d.config.Namespace).Get(context.TODO(), d.config.SecretName, k8sMeta.GetOptions{}) secretPayload, err = client.CoreV1().Secrets(d.config.Namespace).Get(context.TODO(), d.config.SecretName, k8smeta.GetOptions{})
if err != nil { if err != nil {
secretPayload = &k8sCore.Secret{ secretPayload = &k8score.Secret{
TypeMeta: k8sMeta.TypeMeta{ TypeMeta: k8smeta.TypeMeta{
Kind: "Secret", Kind: "Secret",
APIVersion: "v1", APIVersion: "v1",
}, },
ObjectMeta: k8sMeta.ObjectMeta{ ObjectMeta: k8smeta.ObjectMeta{
Name: d.config.SecretName, Name: d.config.SecretName,
Annotations: secretAnnotations, Annotations: secretAnnotations,
}, },
Type: k8sCore.SecretType(d.config.SecretType), Type: k8score.SecretType(d.config.SecretType),
} }
secretPayload.Data = make(map[string][]byte) secretPayload.Data = make(map[string][]byte)
secretPayload.Data[d.config.SecretDataKeyForCrt] = []byte(certPem) secretPayload.Data[d.config.SecretDataKeyForCrt] = []byte(certPem)
secretPayload.Data[d.config.SecretDataKeyForKey] = []byte(privkeyPem) secretPayload.Data[d.config.SecretDataKeyForKey] = []byte(privkeyPem)
secretPayload, err = client.CoreV1().Secrets(d.config.Namespace).Create(context.TODO(), secretPayload, k8sMeta.CreateOptions{}) secretPayload, err = client.CoreV1().Secrets(d.config.Namespace).Create(context.TODO(), secretPayload, k8smeta.CreateOptions{})
d.logger.Debug("k8s operate 'Secrets.Create'", slog.String("namespace", d.config.Namespace), slog.Any("secret", secretPayload)) d.logger.Debug("k8s operate 'Secrets.Create'", slog.String("namespace", d.config.Namespace), slog.Any("secret", secretPayload))
if err != nil { if err != nil {
return nil, xerrors.Wrap(err, "failed to create k8s secret") return nil, xerrors.Wrap(err, "failed to create k8s secret")
@ -124,7 +124,7 @@ func (d *DeployerProvider) Deploy(ctx context.Context, certPem string, privkeyPe
} }
// 更新 Secret 实例 // 更新 Secret 实例
secretPayload.Type = k8sCore.SecretType(d.config.SecretType) secretPayload.Type = k8score.SecretType(d.config.SecretType)
if secretPayload.ObjectMeta.Annotations == nil { if secretPayload.ObjectMeta.Annotations == nil {
secretPayload.ObjectMeta.Annotations = secretAnnotations secretPayload.ObjectMeta.Annotations = secretAnnotations
} else { } else {
@ -137,7 +137,7 @@ func (d *DeployerProvider) Deploy(ctx context.Context, certPem string, privkeyPe
} }
secretPayload.Data[d.config.SecretDataKeyForCrt] = []byte(certPem) secretPayload.Data[d.config.SecretDataKeyForCrt] = []byte(certPem)
secretPayload.Data[d.config.SecretDataKeyForKey] = []byte(privkeyPem) secretPayload.Data[d.config.SecretDataKeyForKey] = []byte(privkeyPem)
secretPayload, err = client.CoreV1().Secrets(d.config.Namespace).Update(context.TODO(), secretPayload, k8sMeta.UpdateOptions{}) secretPayload, err = client.CoreV1().Secrets(d.config.Namespace).Update(context.TODO(), secretPayload, k8smeta.UpdateOptions{})
d.logger.Debug("k8s operate 'Secrets.Update'", slog.String("namespace", d.config.Namespace), slog.Any("secret", secretPayload)) d.logger.Debug("k8s operate 'Secrets.Update'", slog.String("namespace", d.config.Namespace), slog.Any("secret", secretPayload))
if err != nil { if err != nil {
return nil, xerrors.Wrap(err, "failed to update k8s secret") return nil, xerrors.Wrap(err, "failed to update k8s secret")

View File

@ -37,7 +37,7 @@ Shell command to run this test:
--CERTIMATE_DEPLOYER_QINIUCDN_INPUTKEYPATH="/path/to/your-input-key.pem" \ --CERTIMATE_DEPLOYER_QINIUCDN_INPUTKEYPATH="/path/to/your-input-key.pem" \
--CERTIMATE_DEPLOYER_QINIUCDN_ACCESSKEY="your-access-key" \ --CERTIMATE_DEPLOYER_QINIUCDN_ACCESSKEY="your-access-key" \
--CERTIMATE_DEPLOYER_QINIUCDN_SECRETKEY="your-secret-key" \ --CERTIMATE_DEPLOYER_QINIUCDN_SECRETKEY="your-secret-key" \
--CERTIMATE_DEPLOYER_QINIUCDN_DOMAIN="example.com" \ --CERTIMATE_DEPLOYER_QINIUCDN_DOMAIN="example.com"
*/ */
func TestDeploy(t *testing.T) { func TestDeploy(t *testing.T) {
flag.Parse() flag.Parse()

View File

@ -40,7 +40,7 @@ Shell command to run this test:
--CERTIMATE_DEPLOYER_QINIUPILI_ACCESSKEY="your-access-key" \ --CERTIMATE_DEPLOYER_QINIUPILI_ACCESSKEY="your-access-key" \
--CERTIMATE_DEPLOYER_QINIUPILI_SECRETKEY="your-secret-key" \ --CERTIMATE_DEPLOYER_QINIUPILI_SECRETKEY="your-secret-key" \
--CERTIMATE_DEPLOYER_QINIUPILI_HUB="your-hub-name" \ --CERTIMATE_DEPLOYER_QINIUPILI_HUB="your-hub-name" \
--CERTIMATE_DEPLOYER_QINIUPILI_DOMAIN="example.com" \ --CERTIMATE_DEPLOYER_QINIUPILI_DOMAIN="example.com"
*/ */
func TestDeploy(t *testing.T) { func TestDeploy(t *testing.T) {
flag.Parse() flag.Parse()

View File

@ -6,10 +6,10 @@ import (
"strings" "strings"
xerrors "github.com/pkg/errors" xerrors "github.com/pkg/errors"
tcCdn "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cdn/v20180606" tccdn "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cdn/v20180606"
"github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common" "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common"
"github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/profile" "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/profile"
tcSsl "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/ssl/v20191205" tcssl "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/ssl/v20191205"
"golang.org/x/exp/slices" "golang.org/x/exp/slices"
"github.com/usual2970/certimate/internal/pkg/core/deployer" "github.com/usual2970/certimate/internal/pkg/core/deployer"
@ -36,8 +36,8 @@ type DeployerProvider struct {
var _ deployer.Deployer = (*DeployerProvider)(nil) var _ deployer.Deployer = (*DeployerProvider)(nil)
type wSdkClients struct { type wSdkClients struct {
ssl *tcSsl.Client SSL *tcssl.Client
cdn *tcCdn.Client CDN *tccdn.Client
} }
func NewDeployer(config *DeployerConfig) (*DeployerProvider, error) { func NewDeployer(config *DeployerConfig) (*DeployerProvider, error) {
@ -122,12 +122,12 @@ func (d *DeployerProvider) Deploy(ctx context.Context, certPem string, privkeyPe
// 证书部署到 CDN 实例 // 证书部署到 CDN 实例
// REF: https://cloud.tencent.com/document/product/400/91667 // REF: https://cloud.tencent.com/document/product/400/91667
deployCertificateInstanceReq := tcSsl.NewDeployCertificateInstanceRequest() deployCertificateInstanceReq := tcssl.NewDeployCertificateInstanceRequest()
deployCertificateInstanceReq.CertificateId = common.StringPtr(upres.CertId) deployCertificateInstanceReq.CertificateId = common.StringPtr(upres.CertId)
deployCertificateInstanceReq.ResourceType = common.StringPtr("cdn") deployCertificateInstanceReq.ResourceType = common.StringPtr("cdn")
deployCertificateInstanceReq.Status = common.Int64Ptr(1) deployCertificateInstanceReq.Status = common.Int64Ptr(1)
deployCertificateInstanceReq.InstanceIdList = common.StringPtrs(instanceIds) deployCertificateInstanceReq.InstanceIdList = common.StringPtrs(instanceIds)
deployCertificateInstanceResp, err := d.sdkClients.ssl.DeployCertificateInstance(deployCertificateInstanceReq) deployCertificateInstanceResp, err := d.sdkClients.SSL.DeployCertificateInstance(deployCertificateInstanceReq)
d.logger.Debug("sdk request 'ssl.DeployCertificateInstance'", slog.Any("request", deployCertificateInstanceReq), slog.Any("response", deployCertificateInstanceResp)) d.logger.Debug("sdk request 'ssl.DeployCertificateInstance'", slog.Any("request", deployCertificateInstanceReq), slog.Any("response", deployCertificateInstanceResp))
if err != nil { if err != nil {
return nil, xerrors.Wrap(err, "failed to execute sdk request 'ssl.DeployCertificateInstance'") return nil, xerrors.Wrap(err, "failed to execute sdk request 'ssl.DeployCertificateInstance'")
@ -140,10 +140,10 @@ func (d *DeployerProvider) Deploy(ctx context.Context, certPem string, privkeyPe
func (d *DeployerProvider) getDomainsByCertificateId(cloudCertId string) ([]string, error) { func (d *DeployerProvider) getDomainsByCertificateId(cloudCertId string) ([]string, error) {
// 获取证书中的可用域名 // 获取证书中的可用域名
// REF: https://cloud.tencent.com/document/product/228/42491 // REF: https://cloud.tencent.com/document/product/228/42491
describeCertDomainsReq := tcCdn.NewDescribeCertDomainsRequest() describeCertDomainsReq := tccdn.NewDescribeCertDomainsRequest()
describeCertDomainsReq.CertId = common.StringPtr(cloudCertId) describeCertDomainsReq.CertId = common.StringPtr(cloudCertId)
describeCertDomainsReq.Product = common.StringPtr("cdn") describeCertDomainsReq.Product = common.StringPtr("cdn")
describeCertDomainsResp, err := d.sdkClients.cdn.DescribeCertDomains(describeCertDomainsReq) describeCertDomainsResp, err := d.sdkClients.CDN.DescribeCertDomains(describeCertDomainsReq)
d.logger.Debug("sdk request 'cdn.DescribeCertDomains'", slog.Any("request", describeCertDomainsReq), slog.Any("response", describeCertDomainsResp)) d.logger.Debug("sdk request 'cdn.DescribeCertDomains'", slog.Any("request", describeCertDomainsReq), slog.Any("response", describeCertDomainsResp))
if err != nil { if err != nil {
return nil, xerrors.Wrap(err, "failed to execute sdk request 'cdn.DescribeCertDomains'") return nil, xerrors.Wrap(err, "failed to execute sdk request 'cdn.DescribeCertDomains'")
@ -162,10 +162,10 @@ func (d *DeployerProvider) getDomainsByCertificateId(cloudCertId string) ([]stri
func (d *DeployerProvider) getDeployedDomainsByCertificateId(cloudCertId string) ([]string, error) { func (d *DeployerProvider) getDeployedDomainsByCertificateId(cloudCertId string) ([]string, error) {
// 根据证书查询关联 CDN 域名 // 根据证书查询关联 CDN 域名
// REF: https://cloud.tencent.com/document/product/400/62674 // REF: https://cloud.tencent.com/document/product/400/62674
describeDeployedResourcesReq := tcSsl.NewDescribeDeployedResourcesRequest() describeDeployedResourcesReq := tcssl.NewDescribeDeployedResourcesRequest()
describeDeployedResourcesReq.CertificateIds = common.StringPtrs([]string{cloudCertId}) describeDeployedResourcesReq.CertificateIds = common.StringPtrs([]string{cloudCertId})
describeDeployedResourcesReq.ResourceType = common.StringPtr("cdn") describeDeployedResourcesReq.ResourceType = common.StringPtr("cdn")
describeDeployedResourcesResp, err := d.sdkClients.ssl.DescribeDeployedResources(describeDeployedResourcesReq) describeDeployedResourcesResp, err := d.sdkClients.SSL.DescribeDeployedResources(describeDeployedResourcesReq)
d.logger.Debug("sdk request 'cdn.DescribeDeployedResources'", slog.Any("request", describeDeployedResourcesReq), slog.Any("response", describeDeployedResourcesResp)) d.logger.Debug("sdk request 'cdn.DescribeDeployedResources'", slog.Any("request", describeDeployedResourcesReq), slog.Any("response", describeDeployedResourcesResp))
if err != nil { if err != nil {
return nil, xerrors.Wrap(err, "failed to execute sdk request 'cdn.DescribeDeployedResources'") return nil, xerrors.Wrap(err, "failed to execute sdk request 'cdn.DescribeDeployedResources'")
@ -186,18 +186,18 @@ func (d *DeployerProvider) getDeployedDomainsByCertificateId(cloudCertId string)
func createSdkClients(secretId, secretKey string) (*wSdkClients, error) { func createSdkClients(secretId, secretKey string) (*wSdkClients, error) {
credential := common.NewCredential(secretId, secretKey) credential := common.NewCredential(secretId, secretKey)
sslClient, err := tcSsl.NewClient(credential, "", profile.NewClientProfile()) sslClient, err := tcssl.NewClient(credential, "", profile.NewClientProfile())
if err != nil { if err != nil {
return nil, err return nil, err
} }
cdnClient, err := tcCdn.NewClient(credential, "", profile.NewClientProfile()) cdnClient, err := tccdn.NewClient(credential, "", profile.NewClientProfile())
if err != nil { if err != nil {
return nil, err return nil, err
} }
return &wSdkClients{ return &wSdkClients{
ssl: sslClient, SSL: sslClient,
cdn: cdnClient, CDN: cdnClient,
}, nil }, nil
} }

View File

@ -7,10 +7,10 @@ import (
"log/slog" "log/slog"
xerrors "github.com/pkg/errors" xerrors "github.com/pkg/errors"
tcClb "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/clb/v20180317" tcclb "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/clb/v20180317"
"github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common" "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common"
"github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/profile" "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/profile"
tcSsl "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/ssl/v20191205" tcssl "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/ssl/v20191205"
"github.com/usual2970/certimate/internal/pkg/core/deployer" "github.com/usual2970/certimate/internal/pkg/core/deployer"
"github.com/usual2970/certimate/internal/pkg/core/uploader" "github.com/usual2970/certimate/internal/pkg/core/uploader"
@ -47,8 +47,8 @@ type DeployerProvider struct {
var _ deployer.Deployer = (*DeployerProvider)(nil) var _ deployer.Deployer = (*DeployerProvider)(nil)
type wSdkClients struct { type wSdkClients struct {
ssl *tcSsl.Client SSL *tcssl.Client
clb *tcClb.Client CLB *tcclb.Client
} }
func NewDeployer(config *DeployerConfig) (*DeployerProvider, error) { func NewDeployer(config *DeployerConfig) (*DeployerProvider, error) {
@ -135,7 +135,7 @@ func (d *DeployerProvider) deployViaSslService(ctx context.Context, cloudCertId
// 证书部署到 CLB 实例 // 证书部署到 CLB 实例
// REF: https://cloud.tencent.com/document/product/400/91667 // REF: https://cloud.tencent.com/document/product/400/91667
deployCertificateInstanceReq := tcSsl.NewDeployCertificateInstanceRequest() deployCertificateInstanceReq := tcssl.NewDeployCertificateInstanceRequest()
deployCertificateInstanceReq.CertificateId = common.StringPtr(cloudCertId) deployCertificateInstanceReq.CertificateId = common.StringPtr(cloudCertId)
deployCertificateInstanceReq.ResourceType = common.StringPtr("clb") deployCertificateInstanceReq.ResourceType = common.StringPtr("clb")
deployCertificateInstanceReq.Status = common.Int64Ptr(1) deployCertificateInstanceReq.Status = common.Int64Ptr(1)
@ -146,7 +146,7 @@ func (d *DeployerProvider) deployViaSslService(ctx context.Context, cloudCertId
// 指定 SNI需部署到域名 // 指定 SNI需部署到域名
deployCertificateInstanceReq.InstanceIdList = common.StringPtrs([]string{fmt.Sprintf("%s|%s|%s", d.config.LoadbalancerId, d.config.ListenerId, d.config.Domain)}) deployCertificateInstanceReq.InstanceIdList = common.StringPtrs([]string{fmt.Sprintf("%s|%s|%s", d.config.LoadbalancerId, d.config.ListenerId, d.config.Domain)})
} }
deployCertificateInstanceResp, err := d.sdkClients.ssl.DeployCertificateInstance(deployCertificateInstanceReq) deployCertificateInstanceResp, err := d.sdkClients.SSL.DeployCertificateInstance(deployCertificateInstanceReq)
d.logger.Debug("sdk request 'ssl.DeployCertificateInstance'", slog.Any("request", deployCertificateInstanceReq), slog.Any("response", deployCertificateInstanceResp)) d.logger.Debug("sdk request 'ssl.DeployCertificateInstance'", slog.Any("request", deployCertificateInstanceReq), slog.Any("response", deployCertificateInstanceResp))
if err != nil { if err != nil {
return xerrors.Wrap(err, "failed to execute sdk request 'ssl.DeployCertificateInstance'") return xerrors.Wrap(err, "failed to execute sdk request 'ssl.DeployCertificateInstance'")
@ -163,9 +163,9 @@ func (d *DeployerProvider) deployToLoadbalancer(ctx context.Context, cloudCertId
// 查询监听器列表 // 查询监听器列表
// REF: https://cloud.tencent.com/document/api/214/30686 // REF: https://cloud.tencent.com/document/api/214/30686
listenerIds := make([]string, 0) listenerIds := make([]string, 0)
describeListenersReq := tcClb.NewDescribeListenersRequest() describeListenersReq := tcclb.NewDescribeListenersRequest()
describeListenersReq.LoadBalancerId = common.StringPtr(d.config.LoadbalancerId) describeListenersReq.LoadBalancerId = common.StringPtr(d.config.LoadbalancerId)
describeListenersResp, err := d.sdkClients.clb.DescribeListeners(describeListenersReq) describeListenersResp, err := d.sdkClients.CLB.DescribeListeners(describeListenersReq)
d.logger.Debug("sdk request 'clb.DescribeListeners'", slog.Any("request", describeListenersReq), slog.Any("response", describeListenersResp)) d.logger.Debug("sdk request 'clb.DescribeListeners'", slog.Any("request", describeListenersReq), slog.Any("response", describeListenersResp))
if err != nil { if err != nil {
return xerrors.Wrap(err, "failed to execute sdk request 'clb.DescribeListeners'") return xerrors.Wrap(err, "failed to execute sdk request 'clb.DescribeListeners'")
@ -231,15 +231,15 @@ func (d *DeployerProvider) deployToRuleDomain(ctx context.Context, cloudCertId s
// 修改负载均衡七层监听器转发规则的域名级别属性 // 修改负载均衡七层监听器转发规则的域名级别属性
// REF: https://cloud.tencent.com/document/api/214/38092 // REF: https://cloud.tencent.com/document/api/214/38092
modifyDomainAttributesReq := tcClb.NewModifyDomainAttributesRequest() modifyDomainAttributesReq := tcclb.NewModifyDomainAttributesRequest()
modifyDomainAttributesReq.LoadBalancerId = common.StringPtr(d.config.LoadbalancerId) modifyDomainAttributesReq.LoadBalancerId = common.StringPtr(d.config.LoadbalancerId)
modifyDomainAttributesReq.ListenerId = common.StringPtr(d.config.ListenerId) modifyDomainAttributesReq.ListenerId = common.StringPtr(d.config.ListenerId)
modifyDomainAttributesReq.Domain = common.StringPtr(d.config.Domain) modifyDomainAttributesReq.Domain = common.StringPtr(d.config.Domain)
modifyDomainAttributesReq.Certificate = &tcClb.CertificateInput{ modifyDomainAttributesReq.Certificate = &tcclb.CertificateInput{
SSLMode: common.StringPtr("UNIDIRECTIONAL"), SSLMode: common.StringPtr("UNIDIRECTIONAL"),
CertId: common.StringPtr(cloudCertId), CertId: common.StringPtr(cloudCertId),
} }
modifyDomainAttributesResp, err := d.sdkClients.clb.ModifyDomainAttributes(modifyDomainAttributesReq) modifyDomainAttributesResp, err := d.sdkClients.CLB.ModifyDomainAttributes(modifyDomainAttributesReq)
d.logger.Debug("sdk request 'clb.ModifyDomainAttributes'", slog.Any("request", modifyDomainAttributesReq), slog.Any("response", modifyDomainAttributesResp)) d.logger.Debug("sdk request 'clb.ModifyDomainAttributes'", slog.Any("request", modifyDomainAttributesReq), slog.Any("response", modifyDomainAttributesResp))
if err != nil { if err != nil {
return xerrors.Wrap(err, "failed to execute sdk request 'clb.ModifyDomainAttributes'") return xerrors.Wrap(err, "failed to execute sdk request 'clb.ModifyDomainAttributes'")
@ -251,10 +251,10 @@ func (d *DeployerProvider) deployToRuleDomain(ctx context.Context, cloudCertId s
func (d *DeployerProvider) modifyListenerCertificate(ctx context.Context, cloudLoadbalancerId, cloudListenerId, cloudCertId string) error { func (d *DeployerProvider) modifyListenerCertificate(ctx context.Context, cloudLoadbalancerId, cloudListenerId, cloudCertId string) error {
// 查询监听器列表 // 查询监听器列表
// REF: https://cloud.tencent.com/document/api/214/30686 // REF: https://cloud.tencent.com/document/api/214/30686
describeListenersReq := tcClb.NewDescribeListenersRequest() describeListenersReq := tcclb.NewDescribeListenersRequest()
describeListenersReq.LoadBalancerId = common.StringPtr(cloudLoadbalancerId) describeListenersReq.LoadBalancerId = common.StringPtr(cloudLoadbalancerId)
describeListenersReq.ListenerIds = common.StringPtrs([]string{cloudListenerId}) describeListenersReq.ListenerIds = common.StringPtrs([]string{cloudListenerId})
describeListenersResp, err := d.sdkClients.clb.DescribeListeners(describeListenersReq) describeListenersResp, err := d.sdkClients.CLB.DescribeListeners(describeListenersReq)
d.logger.Debug("sdk request 'clb.DescribeListeners'", slog.Any("request", describeListenersReq), slog.Any("response", describeListenersResp)) d.logger.Debug("sdk request 'clb.DescribeListeners'", slog.Any("request", describeListenersReq), slog.Any("response", describeListenersResp))
if err != nil { if err != nil {
return xerrors.Wrap(err, "failed to execute sdk request 'clb.DescribeListeners'") return xerrors.Wrap(err, "failed to execute sdk request 'clb.DescribeListeners'")
@ -264,17 +264,17 @@ func (d *DeployerProvider) modifyListenerCertificate(ctx context.Context, cloudL
// 修改监听器属性 // 修改监听器属性
// REF: https://cloud.tencent.com/document/product/214/30681 // REF: https://cloud.tencent.com/document/product/214/30681
modifyListenerReq := tcClb.NewModifyListenerRequest() modifyListenerReq := tcclb.NewModifyListenerRequest()
modifyListenerReq.LoadBalancerId = common.StringPtr(cloudLoadbalancerId) modifyListenerReq.LoadBalancerId = common.StringPtr(cloudLoadbalancerId)
modifyListenerReq.ListenerId = common.StringPtr(cloudListenerId) modifyListenerReq.ListenerId = common.StringPtr(cloudListenerId)
modifyListenerReq.Certificate = &tcClb.CertificateInput{CertId: common.StringPtr(cloudCertId)} modifyListenerReq.Certificate = &tcclb.CertificateInput{CertId: common.StringPtr(cloudCertId)}
if describeListenersResp.Response.Listeners[0].Certificate != nil && describeListenersResp.Response.Listeners[0].Certificate.SSLMode != nil { if describeListenersResp.Response.Listeners[0].Certificate != nil && describeListenersResp.Response.Listeners[0].Certificate.SSLMode != nil {
modifyListenerReq.Certificate.SSLMode = describeListenersResp.Response.Listeners[0].Certificate.SSLMode modifyListenerReq.Certificate.SSLMode = describeListenersResp.Response.Listeners[0].Certificate.SSLMode
modifyListenerReq.Certificate.CertCaId = describeListenersResp.Response.Listeners[0].Certificate.CertCaId modifyListenerReq.Certificate.CertCaId = describeListenersResp.Response.Listeners[0].Certificate.CertCaId
} else { } else {
modifyListenerReq.Certificate.SSLMode = common.StringPtr("UNIDIRECTIONAL") modifyListenerReq.Certificate.SSLMode = common.StringPtr("UNIDIRECTIONAL")
} }
modifyListenerResp, err := d.sdkClients.clb.ModifyListener(modifyListenerReq) modifyListenerResp, err := d.sdkClients.CLB.ModifyListener(modifyListenerReq)
d.logger.Debug("sdk request 'clb.ModifyListener'", slog.Any("request", modifyListenerReq), slog.Any("response", modifyListenerResp)) d.logger.Debug("sdk request 'clb.ModifyListener'", slog.Any("request", modifyListenerReq), slog.Any("response", modifyListenerResp))
if err != nil { if err != nil {
return xerrors.Wrap(err, "failed to execute sdk request 'clb.ModifyListener'") return xerrors.Wrap(err, "failed to execute sdk request 'clb.ModifyListener'")
@ -287,18 +287,18 @@ func createSdkClients(secretId, secretKey, region string) (*wSdkClients, error)
credential := common.NewCredential(secretId, secretKey) credential := common.NewCredential(secretId, secretKey)
// 注意虽然官方文档中地域无需指定,但实际需要部署到 CLB 时必传 // 注意虽然官方文档中地域无需指定,但实际需要部署到 CLB 时必传
sslClient, err := tcSsl.NewClient(credential, region, profile.NewClientProfile()) sslClient, err := tcssl.NewClient(credential, region, profile.NewClientProfile())
if err != nil { if err != nil {
return nil, err return nil, err
} }
clbClient, err := tcClb.NewClient(credential, region, profile.NewClientProfile()) clbClient, err := tcclb.NewClient(credential, region, profile.NewClientProfile())
if err != nil { if err != nil {
return nil, err return nil, err
} }
return &wSdkClients{ return &wSdkClients{
ssl: sslClient, SSL: sslClient,
clb: clbClient, CLB: clbClient,
}, nil }, nil
} }

View File

@ -9,7 +9,7 @@ import (
xerrors "github.com/pkg/errors" xerrors "github.com/pkg/errors"
"github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common" "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common"
"github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/profile" "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/profile"
tcSsl "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/ssl/v20191205" tcssl "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/ssl/v20191205"
"github.com/usual2970/certimate/internal/pkg/core/deployer" "github.com/usual2970/certimate/internal/pkg/core/deployer"
"github.com/usual2970/certimate/internal/pkg/core/uploader" "github.com/usual2970/certimate/internal/pkg/core/uploader"
@ -32,7 +32,7 @@ type DeployerConfig struct {
type DeployerProvider struct { type DeployerProvider struct {
config *DeployerConfig config *DeployerConfig
logger *slog.Logger logger *slog.Logger
sdkClient *tcSsl.Client sdkClient *tcssl.Client
sslUploader uploader.Uploader sslUploader uploader.Uploader
} }
@ -92,7 +92,7 @@ func (d *DeployerProvider) Deploy(ctx context.Context, certPem string, privkeyPe
// 证书部署到 COS 实例 // 证书部署到 COS 实例
// REF: https://cloud.tencent.com/document/product/400/91667 // REF: https://cloud.tencent.com/document/product/400/91667
deployCertificateInstanceReq := tcSsl.NewDeployCertificateInstanceRequest() deployCertificateInstanceReq := tcssl.NewDeployCertificateInstanceRequest()
deployCertificateInstanceReq.CertificateId = common.StringPtr(upres.CertId) deployCertificateInstanceReq.CertificateId = common.StringPtr(upres.CertId)
deployCertificateInstanceReq.ResourceType = common.StringPtr("cos") deployCertificateInstanceReq.ResourceType = common.StringPtr("cos")
deployCertificateInstanceReq.Status = common.Int64Ptr(1) deployCertificateInstanceReq.Status = common.Int64Ptr(1)
@ -106,9 +106,9 @@ func (d *DeployerProvider) Deploy(ctx context.Context, certPem string, privkeyPe
return &deployer.DeployResult{}, nil return &deployer.DeployResult{}, nil
} }
func createSdkClient(secretId, secretKey, region string) (*tcSsl.Client, error) { func createSdkClient(secretId, secretKey, region string) (*tcssl.Client, error) {
credential := common.NewCredential(secretId, secretKey) credential := common.NewCredential(secretId, secretKey)
client, err := tcSsl.NewClient(credential, region, profile.NewClientProfile()) client, err := tcssl.NewClient(credential, region, profile.NewClientProfile())
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -7,7 +7,7 @@ import (
xerrors "github.com/pkg/errors" xerrors "github.com/pkg/errors"
"github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common" "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common"
"github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/profile" "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/profile"
tcLive "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/live/v20180801" tclive "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/live/v20180801"
"github.com/usual2970/certimate/internal/pkg/core/deployer" "github.com/usual2970/certimate/internal/pkg/core/deployer"
"github.com/usual2970/certimate/internal/pkg/core/uploader" "github.com/usual2970/certimate/internal/pkg/core/uploader"
@ -26,7 +26,7 @@ type DeployerConfig struct {
type DeployerProvider struct { type DeployerProvider struct {
config *DeployerConfig config *DeployerConfig
logger *slog.Logger logger *slog.Logger
sdkClient *tcLive.Client sdkClient *tclive.Client
sslUploader uploader.Uploader sslUploader uploader.Uploader
} }
@ -79,15 +79,14 @@ func (d *DeployerProvider) Deploy(ctx context.Context, certPem string, privkeyPe
// 绑定证书对应的播放域名 // 绑定证书对应的播放域名
// REF: https://cloud.tencent.com/document/product/267/78655 // REF: https://cloud.tencent.com/document/product/267/78655
modifyLiveDomainCertBindingsReq := &tcLive.ModifyLiveDomainCertBindingsRequest{ modifyLiveDomainCertBindingsReq := tclive.NewModifyLiveDomainCertBindingsRequest()
DomainInfos: []*tcLive.LiveCertDomainInfo{ modifyLiveDomainCertBindingsReq.DomainInfos = []*tclive.LiveCertDomainInfo{
{ {
DomainName: common.StringPtr(d.config.Domain), DomainName: common.StringPtr(d.config.Domain),
Status: common.Int64Ptr(1), Status: common.Int64Ptr(1),
}, },
},
CloudCertId: common.StringPtr(upres.CertId),
} }
modifyLiveDomainCertBindingsReq.CloudCertId = common.StringPtr(upres.CertId)
modifyLiveDomainCertBindingsResp, err := d.sdkClient.ModifyLiveDomainCertBindings(modifyLiveDomainCertBindingsReq) modifyLiveDomainCertBindingsResp, err := d.sdkClient.ModifyLiveDomainCertBindings(modifyLiveDomainCertBindingsReq)
d.logger.Debug("sdk request 'live.ModifyLiveDomainCertBindings'", slog.Any("request", modifyLiveDomainCertBindingsReq), slog.Any("response", modifyLiveDomainCertBindingsResp)) d.logger.Debug("sdk request 'live.ModifyLiveDomainCertBindings'", slog.Any("request", modifyLiveDomainCertBindingsReq), slog.Any("response", modifyLiveDomainCertBindingsResp))
if err != nil { if err != nil {
@ -97,10 +96,10 @@ func (d *DeployerProvider) Deploy(ctx context.Context, certPem string, privkeyPe
return &deployer.DeployResult{}, nil return &deployer.DeployResult{}, nil
} }
func createSdkClient(secretId, secretKey string) (*tcLive.Client, error) { func createSdkClient(secretId, secretKey string) (*tclive.Client, error) {
credential := common.NewCredential(secretId, secretKey) credential := common.NewCredential(secretId, secretKey)
client, err := tcLive.NewClient(credential, "", profile.NewClientProfile()) client, err := tclive.NewClient(credential, "", profile.NewClientProfile())
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -6,10 +6,10 @@ import (
"strings" "strings"
xerrors "github.com/pkg/errors" xerrors "github.com/pkg/errors"
tcCdn "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cdn/v20180606" tccdn "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cdn/v20180606"
"github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common" "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common"
"github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/profile" "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/profile"
tcSsl "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/ssl/v20191205" tcssl "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/ssl/v20191205"
"github.com/usual2970/certimate/internal/pkg/core/deployer" "github.com/usual2970/certimate/internal/pkg/core/deployer"
"github.com/usual2970/certimate/internal/pkg/core/uploader" "github.com/usual2970/certimate/internal/pkg/core/uploader"
@ -35,8 +35,8 @@ type DeployerProvider struct {
var _ deployer.Deployer = (*DeployerProvider)(nil) var _ deployer.Deployer = (*DeployerProvider)(nil)
type wSdkClients struct { type wSdkClients struct {
ssl *tcSsl.Client SSL *tcssl.Client
cdn *tcCdn.Client CDN *tccdn.Client
} }
func NewDeployer(config *DeployerConfig) (*DeployerProvider, error) { func NewDeployer(config *DeployerConfig) (*DeployerProvider, error) {
@ -105,12 +105,12 @@ func (d *DeployerProvider) Deploy(ctx context.Context, certPem string, privkeyPe
// 证书部署到 ECDN 实例 // 证书部署到 ECDN 实例
// REF: https://cloud.tencent.com/document/product/400/91667 // REF: https://cloud.tencent.com/document/product/400/91667
deployCertificateInstanceReq := tcSsl.NewDeployCertificateInstanceRequest() deployCertificateInstanceReq := tcssl.NewDeployCertificateInstanceRequest()
deployCertificateInstanceReq.CertificateId = common.StringPtr(upres.CertId) deployCertificateInstanceReq.CertificateId = common.StringPtr(upres.CertId)
deployCertificateInstanceReq.ResourceType = common.StringPtr("ecdn") deployCertificateInstanceReq.ResourceType = common.StringPtr("ecdn")
deployCertificateInstanceReq.Status = common.Int64Ptr(1) deployCertificateInstanceReq.Status = common.Int64Ptr(1)
deployCertificateInstanceReq.InstanceIdList = common.StringPtrs(instanceIds) deployCertificateInstanceReq.InstanceIdList = common.StringPtrs(instanceIds)
deployCertificateInstanceResp, err := d.sdkClients.ssl.DeployCertificateInstance(deployCertificateInstanceReq) deployCertificateInstanceResp, err := d.sdkClients.SSL.DeployCertificateInstance(deployCertificateInstanceReq)
d.logger.Debug("sdk request 'ssl.DeployCertificateInstance'", slog.Any("request", deployCertificateInstanceReq), slog.Any("response", deployCertificateInstanceResp)) d.logger.Debug("sdk request 'ssl.DeployCertificateInstance'", slog.Any("request", deployCertificateInstanceReq), slog.Any("response", deployCertificateInstanceResp))
if err != nil { if err != nil {
return nil, xerrors.Wrap(err, "failed to execute sdk request 'ssl.DeployCertificateInstance'") return nil, xerrors.Wrap(err, "failed to execute sdk request 'ssl.DeployCertificateInstance'")
@ -123,10 +123,10 @@ func (d *DeployerProvider) Deploy(ctx context.Context, certPem string, privkeyPe
func (d *DeployerProvider) getDomainsByCertificateId(cloudCertId string) ([]string, error) { func (d *DeployerProvider) getDomainsByCertificateId(cloudCertId string) ([]string, error) {
// 获取证书中的可用域名 // 获取证书中的可用域名
// REF: https://cloud.tencent.com/document/product/228/42491 // REF: https://cloud.tencent.com/document/product/228/42491
describeCertDomainsReq := tcCdn.NewDescribeCertDomainsRequest() describeCertDomainsReq := tccdn.NewDescribeCertDomainsRequest()
describeCertDomainsReq.CertId = common.StringPtr(cloudCertId) describeCertDomainsReq.CertId = common.StringPtr(cloudCertId)
describeCertDomainsReq.Product = common.StringPtr("ecdn") describeCertDomainsReq.Product = common.StringPtr("ecdn")
describeCertDomainsResp, err := d.sdkClients.cdn.DescribeCertDomains(describeCertDomainsReq) describeCertDomainsResp, err := d.sdkClients.CDN.DescribeCertDomains(describeCertDomainsReq)
d.logger.Debug("sdk request 'cdn.DescribeCertDomains'", slog.Any("request", describeCertDomainsReq), slog.Any("response", describeCertDomainsResp)) d.logger.Debug("sdk request 'cdn.DescribeCertDomains'", slog.Any("request", describeCertDomainsReq), slog.Any("response", describeCertDomainsResp))
if err != nil { if err != nil {
return nil, xerrors.Wrap(err, "failed to execute sdk request 'cdn.DescribeCertDomains'") return nil, xerrors.Wrap(err, "failed to execute sdk request 'cdn.DescribeCertDomains'")
@ -145,18 +145,18 @@ func (d *DeployerProvider) getDomainsByCertificateId(cloudCertId string) ([]stri
func createSdkClients(secretId, secretKey string) (*wSdkClients, error) { func createSdkClients(secretId, secretKey string) (*wSdkClients, error) {
credential := common.NewCredential(secretId, secretKey) credential := common.NewCredential(secretId, secretKey)
sslClient, err := tcSsl.NewClient(credential, "", profile.NewClientProfile()) sslClient, err := tcssl.NewClient(credential, "", profile.NewClientProfile())
if err != nil { if err != nil {
return nil, err return nil, err
} }
cdnClient, err := tcCdn.NewClient(credential, "", profile.NewClientProfile()) cdnClient, err := tccdn.NewClient(credential, "", profile.NewClientProfile())
if err != nil { if err != nil {
return nil, err return nil, err
} }
return &wSdkClients{ return &wSdkClients{
ssl: sslClient, SSL: sslClient,
cdn: cdnClient, CDN: cdnClient,
}, nil }, nil
} }

View File

@ -8,8 +8,8 @@ import (
xerrors "github.com/pkg/errors" xerrors "github.com/pkg/errors"
"github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common" "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common"
"github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/profile" "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/profile"
tcSsl "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/ssl/v20191205" tcssl "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/ssl/v20191205"
tcTeo "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/teo/v20220901" tcteo "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/teo/v20220901"
"github.com/usual2970/certimate/internal/pkg/core/deployer" "github.com/usual2970/certimate/internal/pkg/core/deployer"
"github.com/usual2970/certimate/internal/pkg/core/uploader" "github.com/usual2970/certimate/internal/pkg/core/uploader"
@ -37,8 +37,8 @@ type DeployerProvider struct {
var _ deployer.Deployer = (*DeployerProvider)(nil) var _ deployer.Deployer = (*DeployerProvider)(nil)
type wSdkClients struct { type wSdkClients struct {
ssl *tcSsl.Client SSL *tcssl.Client
teo *tcTeo.Client TEO *tcteo.Client
} }
func NewDeployer(config *DeployerConfig) (*DeployerProvider, error) { func NewDeployer(config *DeployerConfig) (*DeployerProvider, error) {
@ -92,12 +92,12 @@ func (d *DeployerProvider) Deploy(ctx context.Context, certPem string, privkeyPe
// 配置域名证书 // 配置域名证书
// REF: https://cloud.tencent.com/document/product/1552/80764 // REF: https://cloud.tencent.com/document/product/1552/80764
modifyHostsCertificateReq := tcTeo.NewModifyHostsCertificateRequest() modifyHostsCertificateReq := tcteo.NewModifyHostsCertificateRequest()
modifyHostsCertificateReq.ZoneId = common.StringPtr(d.config.ZoneId) modifyHostsCertificateReq.ZoneId = common.StringPtr(d.config.ZoneId)
modifyHostsCertificateReq.Mode = common.StringPtr("sslcert") modifyHostsCertificateReq.Mode = common.StringPtr("sslcert")
modifyHostsCertificateReq.Hosts = common.StringPtrs([]string{d.config.Domain}) modifyHostsCertificateReq.Hosts = common.StringPtrs([]string{d.config.Domain})
modifyHostsCertificateReq.ServerCertInfo = []*tcTeo.ServerCertInfo{{CertId: common.StringPtr(upres.CertId)}} modifyHostsCertificateReq.ServerCertInfo = []*tcteo.ServerCertInfo{{CertId: common.StringPtr(upres.CertId)}}
modifyHostsCertificateResp, err := d.sdkClients.teo.ModifyHostsCertificate(modifyHostsCertificateReq) modifyHostsCertificateResp, err := d.sdkClients.TEO.ModifyHostsCertificate(modifyHostsCertificateReq)
d.logger.Debug("sdk request 'teo.ModifyHostsCertificate'", slog.Any("request", modifyHostsCertificateReq), slog.Any("response", modifyHostsCertificateResp)) d.logger.Debug("sdk request 'teo.ModifyHostsCertificate'", slog.Any("request", modifyHostsCertificateReq), slog.Any("response", modifyHostsCertificateResp))
if err != nil { if err != nil {
return nil, xerrors.Wrap(err, "failed to execute sdk request 'teo.ModifyHostsCertificate'") return nil, xerrors.Wrap(err, "failed to execute sdk request 'teo.ModifyHostsCertificate'")
@ -109,18 +109,18 @@ func (d *DeployerProvider) Deploy(ctx context.Context, certPem string, privkeyPe
func createSdkClients(secretId, secretKey string) (*wSdkClients, error) { func createSdkClients(secretId, secretKey string) (*wSdkClients, error) {
credential := common.NewCredential(secretId, secretKey) credential := common.NewCredential(secretId, secretKey)
sslClient, err := tcSsl.NewClient(credential, "", profile.NewClientProfile()) sslClient, err := tcssl.NewClient(credential, "", profile.NewClientProfile())
if err != nil { if err != nil {
return nil, err return nil, err
} }
teoClient, err := tcTeo.NewClient(credential, "", profile.NewClientProfile()) teoClient, err := tcteo.NewClient(credential, "", profile.NewClientProfile())
if err != nil { if err != nil {
return nil, err return nil, err
} }
return &wSdkClients{ return &wSdkClients{
ssl: sslClient, SSL: sslClient,
teo: teoClient, TEO: teoClient,
}, nil }, nil
} }

View File

@ -7,7 +7,7 @@ import (
xerrors "github.com/pkg/errors" xerrors "github.com/pkg/errors"
"github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common" "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common"
"github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/profile" "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/profile"
tcScf "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/scf/v20180416" tcscf "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/scf/v20180416"
"github.com/usual2970/certimate/internal/pkg/core/deployer" "github.com/usual2970/certimate/internal/pkg/core/deployer"
"github.com/usual2970/certimate/internal/pkg/core/uploader" "github.com/usual2970/certimate/internal/pkg/core/uploader"
@ -28,7 +28,7 @@ type DeployerConfig struct {
type DeployerProvider struct { type DeployerProvider struct {
config *DeployerConfig config *DeployerConfig
logger *slog.Logger logger *slog.Logger
sdkClient *tcScf.Client sdkClient *tcscf.Client
sslUploader uploader.Uploader sslUploader uploader.Uploader
} }
@ -73,7 +73,7 @@ func (d *DeployerProvider) WithLogger(logger *slog.Logger) deployer.Deployer {
func (d *DeployerProvider) Deploy(ctx context.Context, certPem string, privkeyPem string) (*deployer.DeployResult, error) { func (d *DeployerProvider) Deploy(ctx context.Context, certPem string, privkeyPem string) (*deployer.DeployResult, error) {
// 查看云函数自定义域名详情 // 查看云函数自定义域名详情
// REF: https://cloud.tencent.com/document/product/583/111924 // REF: https://cloud.tencent.com/document/product/583/111924
getCustomDomainReq := tcScf.NewGetCustomDomainRequest() getCustomDomainReq := tcscf.NewGetCustomDomainRequest()
getCustomDomainReq.Domain = common.StringPtr(d.config.Domain) getCustomDomainReq.Domain = common.StringPtr(d.config.Domain)
getCustomDomainResp, err := d.sdkClient.GetCustomDomain(getCustomDomainReq) getCustomDomainResp, err := d.sdkClient.GetCustomDomain(getCustomDomainReq)
d.logger.Debug("sdk request 'scf.GetCustomDomain'", slog.Any("request", getCustomDomainReq), slog.Any("response", getCustomDomainResp)) d.logger.Debug("sdk request 'scf.GetCustomDomain'", slog.Any("request", getCustomDomainReq), slog.Any("response", getCustomDomainResp))
@ -91,9 +91,9 @@ func (d *DeployerProvider) Deploy(ctx context.Context, certPem string, privkeyPe
// 更新云函数自定义域名 // 更新云函数自定义域名
// REF: https://cloud.tencent.com/document/product/583/111922 // REF: https://cloud.tencent.com/document/product/583/111922
updateCustomDomainReq := tcScf.NewUpdateCustomDomainRequest() updateCustomDomainReq := tcscf.NewUpdateCustomDomainRequest()
updateCustomDomainReq.Domain = common.StringPtr(d.config.Domain) updateCustomDomainReq.Domain = common.StringPtr(d.config.Domain)
updateCustomDomainReq.CertConfig = &tcScf.CertConf{ updateCustomDomainReq.CertConfig = &tcscf.CertConf{
CertificateId: common.StringPtr(upres.CertId), CertificateId: common.StringPtr(upres.CertId),
} }
updateCustomDomainReq.Protocol = getCustomDomainResp.Response.Protocol updateCustomDomainReq.Protocol = getCustomDomainResp.Response.Protocol
@ -106,9 +106,9 @@ func (d *DeployerProvider) Deploy(ctx context.Context, certPem string, privkeyPe
return &deployer.DeployResult{}, nil return &deployer.DeployResult{}, nil
} }
func createSdkClient(secretId, secretKey, region string) (*tcScf.Client, error) { func createSdkClient(secretId, secretKey, region string) (*tcscf.Client, error) {
credential := common.NewCredential(secretId, secretKey) credential := common.NewCredential(secretId, secretKey)
client, err := tcScf.NewClient(credential, region, profile.NewClientProfile()) client, err := tcscf.NewClient(credential, region, profile.NewClientProfile())
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -10,7 +10,7 @@ import (
xerrors "github.com/pkg/errors" xerrors "github.com/pkg/errors"
"github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common" "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common"
"github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/profile" "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/profile"
tcSsl "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/ssl/v20191205" tcssl "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/ssl/v20191205"
"github.com/usual2970/certimate/internal/pkg/core/deployer" "github.com/usual2970/certimate/internal/pkg/core/deployer"
"github.com/usual2970/certimate/internal/pkg/core/uploader" "github.com/usual2970/certimate/internal/pkg/core/uploader"
@ -33,7 +33,7 @@ type DeployerConfig struct {
type DeployerProvider struct { type DeployerProvider struct {
config *DeployerConfig config *DeployerConfig
logger *slog.Logger logger *slog.Logger
sdkClient *tcSsl.Client sdkClient *tcssl.Client
sslUploader uploader.Uploader sslUploader uploader.Uploader
} }
@ -93,7 +93,7 @@ func (d *DeployerProvider) Deploy(ctx context.Context, certPem string, privkeyPe
// 证书部署到云资源实例列表 // 证书部署到云资源实例列表
// REF: https://cloud.tencent.com/document/product/400/91667 // REF: https://cloud.tencent.com/document/product/400/91667
deployCertificateInstanceReq := tcSsl.NewDeployCertificateInstanceRequest() deployCertificateInstanceReq := tcssl.NewDeployCertificateInstanceRequest()
deployCertificateInstanceReq.CertificateId = common.StringPtr(upres.CertId) deployCertificateInstanceReq.CertificateId = common.StringPtr(upres.CertId)
deployCertificateInstanceReq.ResourceType = common.StringPtr(d.config.ResourceType) deployCertificateInstanceReq.ResourceType = common.StringPtr(d.config.ResourceType)
deployCertificateInstanceReq.InstanceIdList = common.StringPtrs(d.config.ResourceIds) deployCertificateInstanceReq.InstanceIdList = common.StringPtrs(d.config.ResourceIds)
@ -113,7 +113,7 @@ func (d *DeployerProvider) Deploy(ctx context.Context, certPem string, privkeyPe
return nil, ctx.Err() return nil, ctx.Err()
} }
describeHostDeployRecordDetailReq := tcSsl.NewDescribeHostDeployRecordDetailRequest() describeHostDeployRecordDetailReq := tcssl.NewDescribeHostDeployRecordDetailRequest()
describeHostDeployRecordDetailReq.DeployRecordId = common.StringPtr(fmt.Sprintf("%d", *deployCertificateInstanceResp.Response.DeployRecordId)) describeHostDeployRecordDetailReq.DeployRecordId = common.StringPtr(fmt.Sprintf("%d", *deployCertificateInstanceResp.Response.DeployRecordId))
describeHostDeployRecordDetailReq.Limit = common.Uint64Ptr(100) describeHostDeployRecordDetailReq.Limit = common.Uint64Ptr(100)
describeHostDeployRecordDetailResp, err := d.sdkClient.DescribeHostDeployRecordDetail(describeHostDeployRecordDetailReq) describeHostDeployRecordDetailResp, err := d.sdkClient.DescribeHostDeployRecordDetail(describeHostDeployRecordDetailReq)
@ -145,10 +145,10 @@ func (d *DeployerProvider) Deploy(ctx context.Context, certPem string, privkeyPe
return &deployer.DeployResult{}, nil return &deployer.DeployResult{}, nil
} }
func createSdkClient(secretId, secretKey, region string) (*tcSsl.Client, error) { func createSdkClient(secretId, secretKey, region string) (*tcssl.Client, error) {
credential := common.NewCredential(secretId, secretKey) credential := common.NewCredential(secretId, secretKey)
client, err := tcSsl.NewClient(credential, region, profile.NewClientProfile()) client, err := tcssl.NewClient(credential, region, profile.NewClientProfile())
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -7,7 +7,7 @@ import (
xerrors "github.com/pkg/errors" xerrors "github.com/pkg/errors"
"github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common" "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common"
"github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/profile" "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/profile"
tcVod "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/vod/v20180717" tcvod "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/vod/v20180717"
"github.com/usual2970/certimate/internal/pkg/core/deployer" "github.com/usual2970/certimate/internal/pkg/core/deployer"
"github.com/usual2970/certimate/internal/pkg/core/uploader" "github.com/usual2970/certimate/internal/pkg/core/uploader"
@ -28,7 +28,7 @@ type DeployerConfig struct {
type DeployerProvider struct { type DeployerProvider struct {
config *DeployerConfig config *DeployerConfig
logger *slog.Logger logger *slog.Logger
sdkClient *tcVod.Client sdkClient *tcvod.Client
sslUploader uploader.Uploader sslUploader uploader.Uploader
} }
@ -81,7 +81,7 @@ func (d *DeployerProvider) Deploy(ctx context.Context, certPem string, privkeyPe
// 设置点播域名 HTTPS 证书 // 设置点播域名 HTTPS 证书
// REF: https://cloud.tencent.com/document/api/266/102015 // REF: https://cloud.tencent.com/document/api/266/102015
setVodDomainCertificateReq := tcVod.NewSetVodDomainCertificateRequest() setVodDomainCertificateReq := tcvod.NewSetVodDomainCertificateRequest()
setVodDomainCertificateReq.Domain = common.StringPtr(d.config.Domain) setVodDomainCertificateReq.Domain = common.StringPtr(d.config.Domain)
setVodDomainCertificateReq.Operation = common.StringPtr("Set") setVodDomainCertificateReq.Operation = common.StringPtr("Set")
setVodDomainCertificateReq.CertID = common.StringPtr(upres.CertId) setVodDomainCertificateReq.CertID = common.StringPtr(upres.CertId)
@ -97,9 +97,9 @@ func (d *DeployerProvider) Deploy(ctx context.Context, certPem string, privkeyPe
return &deployer.DeployResult{}, nil return &deployer.DeployResult{}, nil
} }
func createSdkClient(secretId, secretKey string) (*tcVod.Client, error) { func createSdkClient(secretId, secretKey string) (*tcvod.Client, error) {
credential := common.NewCredential(secretId, secretKey) credential := common.NewCredential(secretId, secretKey)
client, err := tcVod.NewClient(credential, "", profile.NewClientProfile()) client, err := tcvod.NewClient(credential, "", profile.NewClientProfile())
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -8,7 +8,7 @@ import (
xerrors "github.com/pkg/errors" xerrors "github.com/pkg/errors"
"github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common" "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common"
"github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/profile" "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/profile"
tcWaf "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/waf/v20180125" tcwaf "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/waf/v20180125"
"github.com/usual2970/certimate/internal/pkg/core/deployer" "github.com/usual2970/certimate/internal/pkg/core/deployer"
"github.com/usual2970/certimate/internal/pkg/core/uploader" "github.com/usual2970/certimate/internal/pkg/core/uploader"
@ -33,7 +33,7 @@ type DeployerConfig struct {
type DeployerProvider struct { type DeployerProvider struct {
config *DeployerConfig config *DeployerConfig
logger *slog.Logger logger *slog.Logger
sdkClient *tcWaf.Client sdkClient *tcwaf.Client
sslUploader uploader.Uploader sslUploader uploader.Uploader
} }
@ -96,7 +96,7 @@ func (d *DeployerProvider) Deploy(ctx context.Context, certPem string, privkeyPe
// 查询单个 SaaS 型 WAF 域名详情 // 查询单个 SaaS 型 WAF 域名详情
// REF: https://cloud.tencent.com/document/api/627/82938 // REF: https://cloud.tencent.com/document/api/627/82938
describeDomainDetailsSaasReq := tcWaf.NewDescribeDomainDetailsSaasRequest() describeDomainDetailsSaasReq := tcwaf.NewDescribeDomainDetailsSaasRequest()
describeDomainDetailsSaasReq.Domain = common.StringPtr(d.config.Domain) describeDomainDetailsSaasReq.Domain = common.StringPtr(d.config.Domain)
describeDomainDetailsSaasReq.DomainId = common.StringPtr(d.config.DomainId) describeDomainDetailsSaasReq.DomainId = common.StringPtr(d.config.DomainId)
describeDomainDetailsSaasReq.InstanceId = common.StringPtr(d.config.InstanceId) describeDomainDetailsSaasReq.InstanceId = common.StringPtr(d.config.InstanceId)
@ -108,7 +108,7 @@ func (d *DeployerProvider) Deploy(ctx context.Context, certPem string, privkeyPe
// 编辑 SaaS 型 WAF 域名 // 编辑 SaaS 型 WAF 域名
// REF: https://cloud.tencent.com/document/api/627/94309 // REF: https://cloud.tencent.com/document/api/627/94309
modifySpartaProtectionReq := tcWaf.NewModifySpartaProtectionRequest() modifySpartaProtectionReq := tcwaf.NewModifySpartaProtectionRequest()
modifySpartaProtectionReq.Domain = common.StringPtr(d.config.Domain) modifySpartaProtectionReq.Domain = common.StringPtr(d.config.Domain)
modifySpartaProtectionReq.DomainId = common.StringPtr(d.config.DomainId) modifySpartaProtectionReq.DomainId = common.StringPtr(d.config.DomainId)
modifySpartaProtectionReq.InstanceID = common.StringPtr(d.config.InstanceId) modifySpartaProtectionReq.InstanceID = common.StringPtr(d.config.InstanceId)
@ -123,9 +123,9 @@ func (d *DeployerProvider) Deploy(ctx context.Context, certPem string, privkeyPe
return &deployer.DeployResult{}, nil return &deployer.DeployResult{}, nil
} }
func createSdkClient(secretId, secretKey, region string) (*tcWaf.Client, error) { func createSdkClient(secretId, secretKey, region string) (*tcwaf.Client, error) {
credential := common.NewCredential(secretId, secretKey) credential := common.NewCredential(secretId, secretKey)
client, err := tcWaf.NewClient(credential, region, profile.NewClientProfile()) client, err := tcwaf.NewClient(credential, region, profile.NewClientProfile())
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -7,9 +7,9 @@ import (
"strconv" "strconv"
xerrors "github.com/pkg/errors" xerrors "github.com/pkg/errors"
uCdn "github.com/ucloud/ucloud-sdk-go/services/ucdn" "github.com/ucloud/ucloud-sdk-go/services/ucdn"
usdk "github.com/ucloud/ucloud-sdk-go/ucloud" "github.com/ucloud/ucloud-sdk-go/ucloud"
uAuth "github.com/ucloud/ucloud-sdk-go/ucloud/auth" "github.com/ucloud/ucloud-sdk-go/ucloud/auth"
"github.com/usual2970/certimate/internal/pkg/core/deployer" "github.com/usual2970/certimate/internal/pkg/core/deployer"
"github.com/usual2970/certimate/internal/pkg/core/uploader" "github.com/usual2970/certimate/internal/pkg/core/uploader"
@ -30,7 +30,7 @@ type DeployerConfig struct {
type DeployerProvider struct { type DeployerProvider struct {
config *DeployerConfig config *DeployerConfig
logger *slog.Logger logger *slog.Logger
sdkClient *uCdn.UCDNClient sdkClient *ucdn.UCDNClient
sslUploader uploader.Uploader sslUploader uploader.Uploader
} }
@ -87,7 +87,7 @@ func (d *DeployerProvider) Deploy(ctx context.Context, certPem string, privkeyPe
getUcdnDomainConfigReq := d.sdkClient.NewGetUcdnDomainConfigRequest() getUcdnDomainConfigReq := d.sdkClient.NewGetUcdnDomainConfigRequest()
getUcdnDomainConfigReq.DomainId = []string{d.config.DomainId} getUcdnDomainConfigReq.DomainId = []string{d.config.DomainId}
if d.config.ProjectId != "" { if d.config.ProjectId != "" {
getUcdnDomainConfigReq.ProjectId = usdk.String(d.config.ProjectId) getUcdnDomainConfigReq.ProjectId = ucloud.String(d.config.ProjectId)
} }
getUcdnDomainConfigResp, err := d.sdkClient.GetUcdnDomainConfig(getUcdnDomainConfigReq) getUcdnDomainConfigResp, err := d.sdkClient.GetUcdnDomainConfig(getUcdnDomainConfigReq)
d.logger.Debug("sdk request 'ucdn.GetUcdnDomainConfig'", slog.Any("request", getUcdnDomainConfigReq), slog.Any("response", getUcdnDomainConfigResp)) d.logger.Debug("sdk request 'ucdn.GetUcdnDomainConfig'", slog.Any("request", getUcdnDomainConfigReq), slog.Any("response", getUcdnDomainConfigResp))
@ -101,15 +101,15 @@ func (d *DeployerProvider) Deploy(ctx context.Context, certPem string, privkeyPe
// REF: https://docs.ucloud.cn/api/ucdn-api/update_ucdn_domain_https_config_v2 // REF: https://docs.ucloud.cn/api/ucdn-api/update_ucdn_domain_https_config_v2
certId, _ := strconv.Atoi(upres.CertId) certId, _ := strconv.Atoi(upres.CertId)
updateUcdnDomainHttpsConfigV2Req := d.sdkClient.NewUpdateUcdnDomainHttpsConfigV2Request() updateUcdnDomainHttpsConfigV2Req := d.sdkClient.NewUpdateUcdnDomainHttpsConfigV2Request()
updateUcdnDomainHttpsConfigV2Req.DomainId = usdk.String(d.config.DomainId) updateUcdnDomainHttpsConfigV2Req.DomainId = ucloud.String(d.config.DomainId)
updateUcdnDomainHttpsConfigV2Req.HttpsStatusCn = usdk.String(getUcdnDomainConfigResp.DomainList[0].HttpsStatusCn) updateUcdnDomainHttpsConfigV2Req.HttpsStatusCn = ucloud.String(getUcdnDomainConfigResp.DomainList[0].HttpsStatusCn)
updateUcdnDomainHttpsConfigV2Req.HttpsStatusAbroad = usdk.String(getUcdnDomainConfigResp.DomainList[0].HttpsStatusAbroad) updateUcdnDomainHttpsConfigV2Req.HttpsStatusAbroad = ucloud.String(getUcdnDomainConfigResp.DomainList[0].HttpsStatusAbroad)
updateUcdnDomainHttpsConfigV2Req.HttpsStatusAbroad = usdk.String(getUcdnDomainConfigResp.DomainList[0].HttpsStatusAbroad) updateUcdnDomainHttpsConfigV2Req.HttpsStatusAbroad = ucloud.String(getUcdnDomainConfigResp.DomainList[0].HttpsStatusAbroad)
updateUcdnDomainHttpsConfigV2Req.CertId = usdk.Int(certId) updateUcdnDomainHttpsConfigV2Req.CertId = ucloud.Int(certId)
updateUcdnDomainHttpsConfigV2Req.CertName = usdk.String(upres.CertName) updateUcdnDomainHttpsConfigV2Req.CertName = ucloud.String(upres.CertName)
updateUcdnDomainHttpsConfigV2Req.CertType = usdk.String("ussl") updateUcdnDomainHttpsConfigV2Req.CertType = ucloud.String("ussl")
if d.config.ProjectId != "" { if d.config.ProjectId != "" {
updateUcdnDomainHttpsConfigV2Req.ProjectId = usdk.String(d.config.ProjectId) updateUcdnDomainHttpsConfigV2Req.ProjectId = ucloud.String(d.config.ProjectId)
} }
updateUcdnDomainHttpsConfigV2Resp, err := d.sdkClient.UpdateUcdnDomainHttpsConfigV2(updateUcdnDomainHttpsConfigV2Req) updateUcdnDomainHttpsConfigV2Resp, err := d.sdkClient.UpdateUcdnDomainHttpsConfigV2(updateUcdnDomainHttpsConfigV2Req)
d.logger.Debug("sdk request 'ucdn.UpdateUcdnDomainHttpsConfigV2'", slog.Any("request", updateUcdnDomainHttpsConfigV2Req), slog.Any("response", updateUcdnDomainHttpsConfigV2Resp)) d.logger.Debug("sdk request 'ucdn.UpdateUcdnDomainHttpsConfigV2'", slog.Any("request", updateUcdnDomainHttpsConfigV2Req), slog.Any("response", updateUcdnDomainHttpsConfigV2Resp))
@ -120,13 +120,13 @@ func (d *DeployerProvider) Deploy(ctx context.Context, certPem string, privkeyPe
return &deployer.DeployResult{}, nil return &deployer.DeployResult{}, nil
} }
func createSdkClient(privateKey, publicKey string) (*uCdn.UCDNClient, error) { func createSdkClient(privateKey, publicKey string) (*ucdn.UCDNClient, error) {
cfg := usdk.NewConfig() cfg := ucloud.NewConfig()
credential := uAuth.NewCredential() credential := auth.NewCredential()
credential.PrivateKey = privateKey credential.PrivateKey = privateKey
credential.PublicKey = publicKey credential.PublicKey = publicKey
client := uCdn.NewClient(&cfg, &credential) client := ucdn.NewClient(&cfg, &credential)
return client, nil return client, nil
} }

View File

@ -5,8 +5,8 @@ import (
"log/slog" "log/slog"
xerrors "github.com/pkg/errors" xerrors "github.com/pkg/errors"
usdk "github.com/ucloud/ucloud-sdk-go/ucloud" "github.com/ucloud/ucloud-sdk-go/ucloud"
uAuth "github.com/ucloud/ucloud-sdk-go/ucloud/auth" "github.com/ucloud/ucloud-sdk-go/ucloud/auth"
"github.com/usual2970/certimate/internal/pkg/core/deployer" "github.com/usual2970/certimate/internal/pkg/core/deployer"
"github.com/usual2970/certimate/internal/pkg/core/uploader" "github.com/usual2970/certimate/internal/pkg/core/uploader"
@ -87,12 +87,12 @@ func (d *DeployerProvider) Deploy(ctx context.Context, certPem string, privkeyPe
// 添加 SSL 证书 // 添加 SSL 证书
// REF: https://docs.ucloud.cn/api/ufile-api/add_ufile_ssl_cert // REF: https://docs.ucloud.cn/api/ufile-api/add_ufile_ssl_cert
addUFileSSLCertReq := d.sdkClient.NewAddUFileSSLCertRequest() addUFileSSLCertReq := d.sdkClient.NewAddUFileSSLCertRequest()
addUFileSSLCertReq.BucketName = usdk.String(d.config.Bucket) addUFileSSLCertReq.BucketName = ucloud.String(d.config.Bucket)
addUFileSSLCertReq.Domain = usdk.String(d.config.Domain) addUFileSSLCertReq.Domain = ucloud.String(d.config.Domain)
addUFileSSLCertReq.USSLId = usdk.String(upres.CertId) addUFileSSLCertReq.USSLId = ucloud.String(upres.CertId)
addUFileSSLCertReq.CertificateName = usdk.String(upres.CertName) addUFileSSLCertReq.CertificateName = ucloud.String(upres.CertName)
if d.config.ProjectId != "" { if d.config.ProjectId != "" {
addUFileSSLCertReq.ProjectId = usdk.String(d.config.ProjectId) addUFileSSLCertReq.ProjectId = ucloud.String(d.config.ProjectId)
} }
addUFileSSLCertResp, err := d.sdkClient.AddUFileSSLCert(addUFileSSLCertReq) addUFileSSLCertResp, err := d.sdkClient.AddUFileSSLCert(addUFileSSLCertReq)
d.logger.Debug("sdk request 'us3.AddUFileSSLCert'", slog.Any("request", addUFileSSLCertReq), slog.Any("response", addUFileSSLCertResp)) d.logger.Debug("sdk request 'us3.AddUFileSSLCert'", slog.Any("request", addUFileSSLCertReq), slog.Any("response", addUFileSSLCertResp))
@ -104,10 +104,10 @@ func (d *DeployerProvider) Deploy(ctx context.Context, certPem string, privkeyPe
} }
func createSdkClient(privateKey, publicKey, region string) (*usdkFile.UFileClient, error) { func createSdkClient(privateKey, publicKey, region string) (*usdkFile.UFileClient, error) {
cfg := usdk.NewConfig() cfg := ucloud.NewConfig()
cfg.Region = region cfg.Region = region
credential := uAuth.NewCredential() credential := auth.NewCredential()
credential.PrivateKey = privateKey credential.PrivateKey = privateKey
credential.PublicKey = publicKey credential.PublicKey = publicKey

View File

@ -37,7 +37,7 @@ Shell command to run this test:
--CERTIMATE_DEPLOYER_UPYUNCDN_INPUTKEYPATH="/path/to/your-input-key.pem" \ --CERTIMATE_DEPLOYER_UPYUNCDN_INPUTKEYPATH="/path/to/your-input-key.pem" \
--CERTIMATE_DEPLOYER_UPYUNCDN_USERNAME="your-username" \ --CERTIMATE_DEPLOYER_UPYUNCDN_USERNAME="your-username" \
--CERTIMATE_DEPLOYER_UPYUNCDN_PASSWORD="your-password" \ --CERTIMATE_DEPLOYER_UPYUNCDN_PASSWORD="your-password" \
--CERTIMATE_DEPLOYER_UPYUNCDN_DOMAIN="example.com" \ --CERTIMATE_DEPLOYER_UPYUNCDN_DOMAIN="example.com"
*/ */
func TestDeploy(t *testing.T) { func TestDeploy(t *testing.T) {
flag.Parse() flag.Parse()

View File

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

View File

@ -0,0 +1,263 @@
package volcenginealb
import (
"context"
"errors"
"fmt"
"log/slog"
xerrors "github.com/pkg/errors"
vealb "github.com/volcengine/volcengine-go-sdk/service/alb"
ve "github.com/volcengine/volcengine-go-sdk/volcengine"
vesession "github.com/volcengine/volcengine-go-sdk/volcengine/session"
"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/volcengine-certcenter"
"github.com/usual2970/certimate/internal/pkg/utils/sliceutil"
)
type DeployerConfig struct {
// 火山引擎 AccessKeyId。
AccessKeyId string `json:"accessKeyId"`
// 火山引擎 AccessKeySecret。
AccessKeySecret string `json:"accessKeySecret"`
// 火山引擎地域。
Region string `json:"region"`
// 部署资源类型。
ResourceType ResourceType `json:"resourceType"`
// 负载均衡实例 ID。
// 部署资源类型为 [RESOURCE_TYPE_LOADBALANCER] 时必填。
LoadbalancerId string `json:"loadbalancerId,omitempty"`
// 负载均衡监听器 ID。
// 部署资源类型为 [RESOURCE_TYPE_LISTENER] 时必填。
ListenerId string `json:"listenerId,omitempty"`
// SNI 域名(支持泛域名)。
// 部署资源类型为 [RESOURCE_TYPE_LOADBALANCER]、[RESOURCE_TYPE_LISTENER] 时选填。
Domain string `json:"domain,omitempty"`
}
type DeployerProvider struct {
config *DeployerConfig
logger *slog.Logger
sdkClient *vealb.ALB
sslUploader uploader.Uploader
}
var _ deployer.Deployer = (*DeployerProvider)(nil)
func NewDeployer(config *DeployerConfig) (*DeployerProvider, error) {
if config == nil {
panic("config is nil")
}
client, err := createSdkClient(config.AccessKeyId, config.AccessKeySecret, config.Region)
if err != nil {
return nil, xerrors.Wrap(err, "failed to create sdk client")
}
uploader, err := uploadersp.NewUploader(&uploadersp.UploaderConfig{
AccessKeyId: config.AccessKeyId,
AccessKeySecret: config.AccessKeySecret,
Region: config.Region,
})
if err != nil {
return nil, xerrors.Wrap(err, "failed to create ssl uploader")
}
return &DeployerProvider{
config: config,
logger: slog.Default(),
sdkClient: client,
sslUploader: uploader,
}, nil
}
func (d *DeployerProvider) WithLogger(logger *slog.Logger) deployer.Deployer {
if logger == nil {
d.logger = slog.Default()
} else {
d.logger = logger
}
d.sslUploader.WithLogger(logger)
return d
}
func (d *DeployerProvider) Deploy(ctx context.Context, certPem string, privkeyPem string) (*deployer.DeployResult, error) {
// 上传证书到证书中心
upres, err := d.sslUploader.Upload(ctx, certPem, privkeyPem)
if err != nil {
return nil, xerrors.Wrap(err, "failed to upload certificate file")
} else {
d.logger.Info("ssl certificate uploaded", slog.Any("result", upres))
}
// 根据部署资源类型决定部署方式
switch d.config.ResourceType {
case RESOURCE_TYPE_LOADBALANCER:
if err := d.deployToLoadbalancer(ctx, upres.CertId); err != nil {
return nil, err
}
case RESOURCE_TYPE_LISTENER:
if err := d.deployToListener(ctx, upres.CertId); err != nil {
return nil, err
}
default:
return nil, fmt.Errorf("unsupported resource type: %s", d.config.ResourceType)
}
return &deployer.DeployResult{}, nil
}
func (d *DeployerProvider) deployToLoadbalancer(ctx context.Context, cloudCertId string) error {
if d.config.LoadbalancerId == "" {
return errors.New("config `loadbalancerId` is required")
}
// 查询 ALB 实例的详细信息
// REF: https://www.volcengine.com/docs/6767/113596
describeLoadBalancerAttributesReq := &vealb.DescribeLoadBalancerAttributesInput{
LoadBalancerId: ve.String(d.config.LoadbalancerId),
}
describeLoadBalancerAttributesResp, err := d.sdkClient.DescribeLoadBalancerAttributes(describeLoadBalancerAttributesReq)
d.logger.Debug("sdk request 'alb.DescribeLoadBalancerAttributes'", slog.Any("request", describeLoadBalancerAttributesReq), slog.Any("response", describeLoadBalancerAttributesResp))
if err != nil {
return xerrors.Wrap(err, "failed to execute sdk request 'alb.DescribeLoadBalancerAttributes'")
}
// 查询 HTTPS 监听器列表
// REF: https://www.volcengine.com/docs/6767/113684
listenerIds := make([]string, 0)
describeListenersPageSize := int64(100)
describeListenersPageNumber := int64(1)
for {
describeListenersReq := &vealb.DescribeListenersInput{
LoadBalancerId: ve.String(d.config.LoadbalancerId),
Protocol: ve.String("HTTPS"),
PageNumber: ve.Int64(describeListenersPageNumber),
PageSize: ve.Int64(describeListenersPageSize),
}
describeListenersResp, err := d.sdkClient.DescribeListeners(describeListenersReq)
d.logger.Debug("sdk request 'alb.DescribeListeners'", slog.Any("request", describeListenersReq), slog.Any("response", describeListenersResp))
if err != nil {
return xerrors.Wrap(err, "failed to execute sdk request 'alb.DescribeListeners'")
}
for _, listener := range describeListenersResp.Listeners {
listenerIds = append(listenerIds, *listener.ListenerId)
}
if len(describeListenersResp.Listeners) < int(describeListenersPageSize) {
break
} else {
describeListenersPageNumber++
}
}
// 遍历更新监听证书
if len(listenerIds) == 0 {
d.logger.Info("no alb listeners to deploy")
} else {
d.logger.Info("found https listeners to deploy", slog.Any("listenerIds", listenerIds))
var errs []error
for _, listenerId := range listenerIds {
if err := d.updateListenerCertificate(ctx, listenerId, cloudCertId); err != nil {
errs = append(errs, err)
}
}
if len(errs) > 0 {
return errors.Join(errs...)
}
}
return nil
}
func (d *DeployerProvider) deployToListener(ctx context.Context, cloudCertId string) error {
if d.config.ListenerId == "" {
return errors.New("config `listenerId` is required")
}
if err := d.updateListenerCertificate(ctx, d.config.LoadbalancerId, cloudCertId); err != nil {
return err
}
return nil
}
func (d *DeployerProvider) updateListenerCertificate(ctx context.Context, cloudListenerId string, cloudCertId string) error {
// 查询指定监听器的详细信息
// REF: https://www.volcengine.com/docs/6767/113686
describeListenerAttributesReq := &vealb.DescribeListenerAttributesInput{
ListenerId: ve.String(cloudListenerId),
}
describeListenerAttributesResp, err := d.sdkClient.DescribeListenerAttributes(describeListenerAttributesReq)
d.logger.Debug("sdk request 'alb.DescribeListenerAttributes'", slog.Any("request", describeListenerAttributesReq), slog.Any("response", describeListenerAttributesResp))
if err != nil {
return xerrors.Wrap(err, "failed to execute sdk request 'alb.DescribeListenerAttributes'")
}
if d.config.Domain == "" {
// 未指定 SNI只需部署到监听器
// 修改指定监听器
// REF: https://www.volcengine.com/docs/6767/113683
modifyListenerAttributesReq := &vealb.ModifyListenerAttributesInput{
ListenerId: ve.String(cloudListenerId),
CertificateSource: ve.String("cert_center"),
CertCenterCertificateId: ve.String(cloudCertId),
}
modifyListenerAttributesResp, err := d.sdkClient.ModifyListenerAttributes(modifyListenerAttributesReq)
d.logger.Debug("sdk request 'alb.ModifyListenerAttributes'", slog.Any("request", modifyListenerAttributesReq), slog.Any("response", modifyListenerAttributesResp))
if err != nil {
return xerrors.Wrap(err, "failed to execute sdk request 'alb.ModifyListenerAttributes'")
}
} else {
// 指定 SNI需部署到扩展域名
// 修改指定监听器
// REF: https://www.volcengine.com/docs/6767/113683
modifyListenerAttributesReq := &vealb.ModifyListenerAttributesInput{
ListenerId: ve.String(cloudListenerId),
DomainExtensions: sliceutil.Map(
sliceutil.Filter(
describeListenerAttributesResp.DomainExtensions,
func(domain *vealb.DomainExtensionForDescribeListenerAttributesOutput) bool {
return *domain.Domain == d.config.Domain
},
),
func(domain *vealb.DomainExtensionForDescribeListenerAttributesOutput) *vealb.DomainExtensionForModifyListenerAttributesInput {
return &vealb.DomainExtensionForModifyListenerAttributesInput{
DomainExtensionId: domain.DomainExtensionId,
Domain: domain.Domain,
CertificateSource: ve.String("cert_center"),
CertCenterCertificateId: ve.String(cloudCertId),
Action: ve.String("modify"),
}
}),
}
modifyListenerAttributesResp, err := d.sdkClient.ModifyListenerAttributes(modifyListenerAttributesReq)
d.logger.Debug("sdk request 'alb.ModifyListenerAttributes'", slog.Any("request", modifyListenerAttributesReq), slog.Any("response", modifyListenerAttributesResp))
if err != nil {
return xerrors.Wrap(err, "failed to execute sdk request 'alb.ModifyListenerAttributes'")
}
}
return nil
}
func createSdkClient(accessKeyId, accessKeySecret, region string) (*vealb.ALB, error) {
config := ve.NewConfig().WithRegion(region).WithAkSk(accessKeyId, accessKeySecret)
session, err := vesession.NewSession(config)
if err != nil {
return nil, err
}
client := vealb.New(session)
return client, nil
}

View File

@ -0,0 +1,81 @@
package volcenginealb_test
import (
"context"
"flag"
"fmt"
"os"
"strings"
"testing"
provider "github.com/usual2970/certimate/internal/pkg/core/deployer/providers/volcengine-alb"
)
var (
fInputCertPath string
fInputKeyPath string
fAccessKeyId string
fAccessKeySecret string
fRegion string
fListenerId string
)
func init() {
argsPrefix := "CERTIMATE_DEPLOYER_VOLCENGINEALB_"
flag.StringVar(&fInputCertPath, argsPrefix+"INPUTCERTPATH", "", "")
flag.StringVar(&fInputKeyPath, argsPrefix+"INPUTKEYPATH", "", "")
flag.StringVar(&fAccessKeyId, argsPrefix+"ACCESSKEYID", "", "")
flag.StringVar(&fAccessKeySecret, argsPrefix+"ACCESSKEYSECRET", "", "")
flag.StringVar(&fRegion, argsPrefix+"REGION", "", "")
flag.StringVar(&fListenerId, argsPrefix+"LISTENERID", "", "")
}
/*
Shell command to run this test:
go test -v ./volcengine_alb_test.go -args \
--CERTIMATE_DEPLOYER_VOLCENGINEALB_INPUTCERTPATH="/path/to/your-input-cert.pem" \
--CERTIMATE_DEPLOYER_VOLCENGINEALB_INPUTKEYPATH="/path/to/your-input-key.pem" \
--CERTIMATE_DEPLOYER_VOLCENGINEALB_ACCESSKEYID="your-access-key-id" \
--CERTIMATE_DEPLOYER_VOLCENGINEALB_ACCESSKEYSECRET="your-access-key-secret" \
--CERTIMATE_DEPLOYER_VOLCENGINEALB_REGION="cn-beijing" \
--CERTIMATE_DEPLOYER_VOLCENGINEALB_LISTENERID="your-listener-id"
*/
func TestDeploy(t *testing.T) {
flag.Parse()
t.Run("Deploy", func(t *testing.T) {
t.Log(strings.Join([]string{
"args:",
fmt.Sprintf("INPUTCERTPATH: %v", fInputCertPath),
fmt.Sprintf("INPUTKEYPATH: %v", fInputKeyPath),
fmt.Sprintf("ACCESSKEYID: %v", fAccessKeyId),
fmt.Sprintf("ACCESSKEYSECRET: %v", fAccessKeySecret),
fmt.Sprintf("REGION: %v", fRegion),
fmt.Sprintf("LISTENERID: %v", fListenerId),
}, "\n"))
deployer, err := provider.NewDeployer(&provider.DeployerConfig{
AccessKeyId: fAccessKeyId,
AccessKeySecret: fAccessKeySecret,
Region: fRegion,
ResourceType: provider.RESOURCE_TYPE_LISTENER,
ListenerId: fListenerId,
})
if err != nil {
t.Errorf("err: %+v", err)
return
}
fInputCertData, _ := os.ReadFile(fInputCertPath)
fInputKeyData, _ := os.ReadFile(fInputKeyPath)
res, err := deployer.Deploy(context.Background(), string(fInputCertData), string(fInputKeyData))
if err != nil {
t.Errorf("err: %+v", err)
return
}
t.Logf("ok: %v", res)
})
}

View File

@ -7,7 +7,7 @@ import (
"strings" "strings"
xerrors "github.com/pkg/errors" xerrors "github.com/pkg/errors"
veCdn "github.com/volcengine/volc-sdk-golang/service/cdn" vecdn "github.com/volcengine/volc-sdk-golang/service/cdn"
"github.com/usual2970/certimate/internal/pkg/core/deployer" "github.com/usual2970/certimate/internal/pkg/core/deployer"
"github.com/usual2970/certimate/internal/pkg/core/uploader" "github.com/usual2970/certimate/internal/pkg/core/uploader"
@ -26,7 +26,7 @@ type DeployerConfig struct {
type DeployerProvider struct { type DeployerProvider struct {
config *DeployerConfig config *DeployerConfig
logger *slog.Logger logger *slog.Logger
sdkClient *veCdn.CDN sdkClient *vecdn.CDN
sslUploader uploader.Uploader sslUploader uploader.Uploader
} }
@ -37,7 +37,7 @@ func NewDeployer(config *DeployerConfig) (*DeployerProvider, error) {
panic("config is nil") panic("config is nil")
} }
client := veCdn.NewInstance() client := vecdn.NewInstance()
client.Client.SetAccessKey(config.AccessKeyId) client.Client.SetAccessKey(config.AccessKeyId)
client.Client.SetSecretKey(config.AccessKeySecret) client.Client.SetSecretKey(config.AccessKeySecret)
@ -80,7 +80,7 @@ func (d *DeployerProvider) Deploy(ctx context.Context, certPem string, privkeyPe
if strings.HasPrefix(d.config.Domain, "*.") { if strings.HasPrefix(d.config.Domain, "*.") {
// 获取指定证书可关联的域名 // 获取指定证书可关联的域名
// REF: https://www.volcengine.com/docs/6454/125711 // REF: https://www.volcengine.com/docs/6454/125711
describeCertConfigReq := &veCdn.DescribeCertConfigRequest{ describeCertConfigReq := &vecdn.DescribeCertConfigRequest{
CertId: upres.CertId, CertId: upres.CertId,
} }
describeCertConfigResp, err := d.sdkClient.DescribeCertConfig(describeCertConfigReq) describeCertConfigResp, err := d.sdkClient.DescribeCertConfig(describeCertConfigReq)
@ -119,7 +119,7 @@ func (d *DeployerProvider) Deploy(ctx context.Context, certPem string, privkeyPe
for _, domain := range domains { for _, domain := range domains {
// 关联证书与加速域名 // 关联证书与加速域名
// REF: https://www.volcengine.com/docs/6454/125712 // REF: https://www.volcengine.com/docs/6454/125712
batchDeployCertReq := &veCdn.BatchDeployCertRequest{ batchDeployCertReq := &vecdn.BatchDeployCertRequest{
CertId: upres.CertId, CertId: upres.CertId,
Domain: domain, Domain: domain,
} }

View File

@ -0,0 +1,72 @@
package volcenginecertcenter
import (
"context"
"log/slog"
xerrors "github.com/pkg/errors"
"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/volcengine-certcenter"
)
type DeployerConfig struct {
// 火山引擎 AccessKeyId。
AccessKeyId string `json:"accessKeyId"`
// 火山引擎 AccessKeySecret。
AccessKeySecret string `json:"accessKeySecret"`
// 火山引擎地域。
Region string `json:"region"`
}
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,
AccessKeySecret: config.AccessKeySecret,
Region: config.Region,
})
if err != nil {
return nil, xerrors.Wrap(err, "failed to create ssl uploader")
}
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.Default()
} else {
d.logger = logger
}
d.sslUploader.WithLogger(logger)
return d
}
func (d *DeployerProvider) Deploy(ctx context.Context, certPem string, privkeyPem string) (*deployer.DeployResult, error) {
// 上传证书到证书中心
upres, err := d.sslUploader.Upload(ctx, certPem, privkeyPem)
if err != nil {
return nil, xerrors.Wrap(err, "failed to upload certificate file")
} else {
d.logger.Info("ssl certificate uploaded", slog.Any("result", upres))
}
return &deployer.DeployResult{}, nil
}

View File

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

View File

@ -7,9 +7,9 @@ import (
"log/slog" "log/slog"
xerrors "github.com/pkg/errors" xerrors "github.com/pkg/errors"
veClb "github.com/volcengine/volcengine-go-sdk/service/clb" veclb "github.com/volcengine/volcengine-go-sdk/service/clb"
ve "github.com/volcengine/volcengine-go-sdk/volcengine" ve "github.com/volcengine/volcengine-go-sdk/volcengine"
veSession "github.com/volcengine/volcengine-go-sdk/volcengine/session" vesession "github.com/volcengine/volcengine-go-sdk/volcengine/session"
"github.com/usual2970/certimate/internal/pkg/core/deployer" "github.com/usual2970/certimate/internal/pkg/core/deployer"
"github.com/usual2970/certimate/internal/pkg/core/uploader" "github.com/usual2970/certimate/internal/pkg/core/uploader"
@ -25,6 +25,9 @@ type DeployerConfig struct {
Region string `json:"region"` Region string `json:"region"`
// 部署资源类型。 // 部署资源类型。
ResourceType ResourceType `json:"resourceType"` ResourceType ResourceType `json:"resourceType"`
// 负载均衡实例 ID。
// 部署资源类型为 [RESOURCE_TYPE_LOADBALANCER] 时必填。
LoadbalancerId string `json:"loadbalancerId,omitempty"`
// 负载均衡监听器 ID。 // 负载均衡监听器 ID。
// 部署资源类型为 [RESOURCE_TYPE_LISTENER] 时必填。 // 部署资源类型为 [RESOURCE_TYPE_LISTENER] 时必填。
ListenerId string `json:"listenerId,omitempty"` ListenerId string `json:"listenerId,omitempty"`
@ -33,7 +36,7 @@ type DeployerConfig struct {
type DeployerProvider struct { type DeployerProvider struct {
config *DeployerConfig config *DeployerConfig
logger *slog.Logger logger *slog.Logger
sdkClient *veClb.CLB sdkClient *veclb.CLB
sslUploader uploader.Uploader sslUploader uploader.Uploader
} }
@ -87,6 +90,11 @@ func (d *DeployerProvider) Deploy(ctx context.Context, certPem string, privkeyPe
// 根据部署资源类型决定部署方式 // 根据部署资源类型决定部署方式
switch d.config.ResourceType { switch d.config.ResourceType {
case RESOURCE_TYPE_LOADBALANCER:
if err := d.deployToLoadbalancer(ctx, upres.CertId); err != nil {
return nil, err
}
case RESOURCE_TYPE_LISTENER: case RESOURCE_TYPE_LISTENER:
if err := d.deployToListener(ctx, upres.CertId); err != nil { if err := d.deployToListener(ctx, upres.CertId); err != nil {
return nil, err return nil, err
@ -99,15 +107,89 @@ func (d *DeployerProvider) Deploy(ctx context.Context, certPem string, privkeyPe
return &deployer.DeployResult{}, nil return &deployer.DeployResult{}, nil
} }
func (d *DeployerProvider) deployToLoadbalancer(ctx context.Context, cloudCertId string) error {
if d.config.LoadbalancerId == "" {
return errors.New("config `loadbalancerId` is required")
}
// 查看指定负载均衡实例的详情
// REF: https://www.volcengine.com/docs/6406/71773
describeLoadBalancerAttributesReq := &veclb.DescribeLoadBalancerAttributesInput{
LoadBalancerId: ve.String(d.config.LoadbalancerId),
}
describeLoadBalancerAttributesResp, err := d.sdkClient.DescribeLoadBalancerAttributes(describeLoadBalancerAttributesReq)
d.logger.Debug("sdk request 'clb.DescribeLoadBalancerAttributes'", slog.Any("request", describeLoadBalancerAttributesReq), slog.Any("response", describeLoadBalancerAttributesResp))
if err != nil {
return xerrors.Wrap(err, "failed to execute sdk request 'clb.DescribeLoadBalancerAttributes'")
}
// 查询 HTTPS 监听器列表
// REF: https://www.volcengine.com/docs/6406/71776
listenerIds := make([]string, 0)
describeListenersPageSize := int64(100)
describeListenersPageNumber := int64(1)
for {
describeListenersReq := &veclb.DescribeListenersInput{
LoadBalancerId: ve.String(d.config.LoadbalancerId),
Protocol: ve.String("HTTPS"),
PageNumber: ve.Int64(describeListenersPageNumber),
PageSize: ve.Int64(describeListenersPageSize),
}
describeListenersResp, err := d.sdkClient.DescribeListeners(describeListenersReq)
d.logger.Debug("sdk request 'clb.DescribeListeners'", slog.Any("request", describeListenersReq), slog.Any("response", describeListenersResp))
if err != nil {
return xerrors.Wrap(err, "failed to execute sdk request 'clb.DescribeListeners'")
}
for _, listener := range describeListenersResp.Listeners {
listenerIds = append(listenerIds, *listener.ListenerId)
}
if len(describeListenersResp.Listeners) < int(describeListenersPageSize) {
break
} else {
describeListenersPageNumber++
}
}
// 遍历更新监听证书
if len(listenerIds) == 0 {
d.logger.Info("no clb listeners to deploy")
} else {
d.logger.Info("found https listeners to deploy", slog.Any("listenerIds", listenerIds))
var errs []error
for _, listenerId := range listenerIds {
if err := d.updateListenerCertificate(ctx, listenerId, cloudCertId); err != nil {
errs = append(errs, err)
}
}
if len(errs) > 0 {
return errors.Join(errs...)
}
}
return nil
}
func (d *DeployerProvider) deployToListener(ctx context.Context, cloudCertId string) error { func (d *DeployerProvider) deployToListener(ctx context.Context, cloudCertId string) error {
if d.config.ListenerId == "" { if d.config.ListenerId == "" {
return errors.New("config `listenerId` is required") return errors.New("config `listenerId` is required")
} }
// 修改监听器 if err := d.updateListenerCertificate(ctx, d.config.LoadbalancerId, cloudCertId); err != nil {
return err
}
return nil
}
func (d *DeployerProvider) updateListenerCertificate(ctx context.Context, cloudListenerId string, cloudCertId string) error {
// 修改指定监听器
// REF: https://www.volcengine.com/docs/6406/71775 // REF: https://www.volcengine.com/docs/6406/71775
modifyListenerAttributesReq := &veClb.ModifyListenerAttributesInput{ modifyListenerAttributesReq := &veclb.ModifyListenerAttributesInput{
ListenerId: ve.String(d.config.ListenerId), ListenerId: ve.String(cloudListenerId),
CertificateSource: ve.String("cert_center"), CertificateSource: ve.String("cert_center"),
CertCenterCertificateId: ve.String(cloudCertId), CertCenterCertificateId: ve.String(cloudCertId),
} }
@ -120,14 +202,14 @@ func (d *DeployerProvider) deployToListener(ctx context.Context, cloudCertId str
return nil return nil
} }
func createSdkClient(accessKeyId, accessKeySecret, region string) (*veClb.CLB, error) { func createSdkClient(accessKeyId, accessKeySecret, region string) (*veclb.CLB, error) {
config := ve.NewConfig().WithRegion(region).WithAkSk(accessKeyId, accessKeySecret) config := ve.NewConfig().WithRegion(region).WithAkSk(accessKeyId, accessKeySecret)
session, err := veSession.NewSession(config) session, err := vesession.NewSession(config)
if err != nil { if err != nil {
return nil, err return nil, err
} }
client := veClb.New(session) client := veclb.New(session)
return client, nil return client, nil
} }

View File

@ -40,7 +40,7 @@ Shell command to run this test:
--CERTIMATE_DEPLOYER_VOLCENGINECLB_ACCESSKEYID="your-access-key-id" \ --CERTIMATE_DEPLOYER_VOLCENGINECLB_ACCESSKEYID="your-access-key-id" \
--CERTIMATE_DEPLOYER_VOLCENGINECLB_ACCESSKEYSECRET="your-access-key-secret" \ --CERTIMATE_DEPLOYER_VOLCENGINECLB_ACCESSKEYSECRET="your-access-key-secret" \
--CERTIMATE_DEPLOYER_VOLCENGINECLB_REGION="cn-beijing" \ --CERTIMATE_DEPLOYER_VOLCENGINECLB_REGION="cn-beijing" \
--CERTIMATE_DEPLOYER_VOLCENGINECLB_LISTENERID="cn-beijing" --CERTIMATE_DEPLOYER_VOLCENGINECLB_LISTENERID="your-listener-id"
*/ */
func TestDeploy(t *testing.T) { func TestDeploy(t *testing.T) {
flag.Parse() flag.Parse()

View File

@ -6,9 +6,9 @@ import (
"strings" "strings"
xerrors "github.com/pkg/errors" xerrors "github.com/pkg/errors"
veDcdn "github.com/volcengine/volcengine-go-sdk/service/dcdn" vedcdn "github.com/volcengine/volcengine-go-sdk/service/dcdn"
ve "github.com/volcengine/volcengine-go-sdk/volcengine" ve "github.com/volcengine/volcengine-go-sdk/volcengine"
veSession "github.com/volcengine/volcengine-go-sdk/volcengine/session" vesession "github.com/volcengine/volcengine-go-sdk/volcengine/session"
"github.com/usual2970/certimate/internal/pkg/core/deployer" "github.com/usual2970/certimate/internal/pkg/core/deployer"
"github.com/usual2970/certimate/internal/pkg/core/uploader" "github.com/usual2970/certimate/internal/pkg/core/uploader"
@ -29,7 +29,7 @@ type DeployerConfig struct {
type DeployerProvider struct { type DeployerProvider struct {
config *DeployerConfig config *DeployerConfig
logger *slog.Logger logger *slog.Logger
sdkClient *veDcdn.DCDN sdkClient *vedcdn.DCDN
sslUploader uploader.Uploader sslUploader uploader.Uploader
} }
@ -86,7 +86,7 @@ func (d *DeployerProvider) Deploy(ctx context.Context, certPem string, privkeyPe
// 绑定证书 // 绑定证书
// REF: https://www.volcengine.com/docs/6559/1250189 // REF: https://www.volcengine.com/docs/6559/1250189
createCertBindReq := &veDcdn.CreateCertBindInput{ createCertBindReq := &vedcdn.CreateCertBindInput{
CertSource: ve.String("volc"), CertSource: ve.String("volc"),
CertId: ve.String(upres.CertId), CertId: ve.String(upres.CertId),
DomainNames: ve.StringSlice([]string{domain}), DomainNames: ve.StringSlice([]string{domain}),
@ -100,18 +100,18 @@ func (d *DeployerProvider) Deploy(ctx context.Context, certPem string, privkeyPe
return &deployer.DeployResult{}, nil return &deployer.DeployResult{}, nil
} }
func createSdkClient(accessKeyId, accessKeySecret, region string) (*veDcdn.DCDN, error) { func createSdkClient(accessKeyId, accessKeySecret, region string) (*vedcdn.DCDN, error) {
if region == "" { if region == "" {
region = "cn-beijing" // DCDN 服务默认区域:北京 region = "cn-beijing" // DCDN 服务默认区域:北京
} }
config := ve.NewConfig().WithRegion(region).WithAkSk(accessKeyId, accessKeySecret) config := ve.NewConfig().WithRegion(region).WithAkSk(accessKeyId, accessKeySecret)
session, err := veSession.NewSession(config) session, err := vesession.NewSession(config)
if err != nil { if err != nil {
return nil, err return nil, err
} }
client := veDcdn.New(session) client := vedcdn.New(session)
return client, nil return client, nil
} }

View File

@ -6,8 +6,8 @@ import (
"log/slog" "log/slog"
xerrors "github.com/pkg/errors" xerrors "github.com/pkg/errors"
veBase "github.com/volcengine/volc-sdk-golang/base" vebase "github.com/volcengine/volc-sdk-golang/base"
veImageX "github.com/volcengine/volc-sdk-golang/service/imagex/v2" veimagex "github.com/volcengine/volc-sdk-golang/service/imagex/v2"
"github.com/usual2970/certimate/internal/pkg/core/deployer" "github.com/usual2970/certimate/internal/pkg/core/deployer"
"github.com/usual2970/certimate/internal/pkg/core/uploader" "github.com/usual2970/certimate/internal/pkg/core/uploader"
@ -30,7 +30,7 @@ type DeployerConfig struct {
type DeployerProvider struct { type DeployerProvider struct {
config *DeployerConfig config *DeployerConfig
logger *slog.Logger logger *slog.Logger
sdkClient *veImageX.Imagex sdkClient *veimagex.Imagex
sslUploader uploader.Uploader sslUploader uploader.Uploader
} }
@ -91,7 +91,7 @@ func (d *DeployerProvider) Deploy(ctx context.Context, certPem string, privkeyPe
// 获取域名配置 // 获取域名配置
// REF: https://www.volcengine.com/docs/508/9366 // REF: https://www.volcengine.com/docs/508/9366
getDomainConfigReq := &veImageX.GetDomainConfigQuery{ getDomainConfigReq := &veimagex.GetDomainConfigQuery{
ServiceID: d.config.ServiceId, ServiceID: d.config.ServiceId,
DomainName: d.config.Domain, DomainName: d.config.Domain,
} }
@ -103,13 +103,13 @@ func (d *DeployerProvider) Deploy(ctx context.Context, certPem string, privkeyPe
// 更新 HTTPS 配置 // 更新 HTTPS 配置
// REF: https://www.volcengine.com/docs/508/66012 // REF: https://www.volcengine.com/docs/508/66012
updateHttpsReq := &veImageX.UpdateHTTPSReq{ updateHttpsReq := &veimagex.UpdateHTTPSReq{
UpdateHTTPSQuery: &veImageX.UpdateHTTPSQuery{ UpdateHTTPSQuery: &veimagex.UpdateHTTPSQuery{
ServiceID: d.config.ServiceId, ServiceID: d.config.ServiceId,
}, },
UpdateHTTPSBody: &veImageX.UpdateHTTPSBody{ UpdateHTTPSBody: &veimagex.UpdateHTTPSBody{
Domain: d.config.Domain, Domain: d.config.Domain,
HTTPS: &veImageX.UpdateHTTPSBodyHTTPS{ HTTPS: &veimagex.UpdateHTTPSBodyHTTPS{
CertID: upres.CertId, CertID: upres.CertId,
EnableHTTPS: true, EnableHTTPS: true,
}, },
@ -133,15 +133,15 @@ func (d *DeployerProvider) Deploy(ctx context.Context, certPem string, privkeyPe
return &deployer.DeployResult{}, nil return &deployer.DeployResult{}, nil
} }
func createSdkClient(accessKeyId, accessKeySecret, region string) (*veImageX.Imagex, error) { func createSdkClient(accessKeyId, accessKeySecret, region string) (*veimagex.Imagex, error) {
var instance *veImageX.Imagex var instance *veimagex.Imagex
if region == "" { if region == "" {
instance = veImageX.NewInstance() instance = veimagex.NewInstance()
} else { } else {
instance = veImageX.NewInstanceWithRegion(region) instance = veimagex.NewInstanceWithRegion(region)
} }
instance.SetCredential(veBase.Credentials{ instance.SetCredential(vebase.Credentials{
AccessKeyID: accessKeyId, AccessKeyID: accessKeyId,
SecretAccessKey: accessKeySecret, SecretAccessKey: accessKeySecret,
}) })

View File

@ -7,7 +7,7 @@ import (
"strings" "strings"
xerrors "github.com/pkg/errors" xerrors "github.com/pkg/errors"
veLive "github.com/volcengine/volc-sdk-golang/service/live/v20230101" velive "github.com/volcengine/volc-sdk-golang/service/live/v20230101"
ve "github.com/volcengine/volcengine-go-sdk/volcengine" ve "github.com/volcengine/volcengine-go-sdk/volcengine"
"github.com/usual2970/certimate/internal/pkg/core/deployer" "github.com/usual2970/certimate/internal/pkg/core/deployer"
@ -27,7 +27,7 @@ type DeployerConfig struct {
type DeployerProvider struct { type DeployerProvider struct {
config *DeployerConfig config *DeployerConfig
logger *slog.Logger logger *slog.Logger
sdkClient *veLive.Live sdkClient *velive.Live
sslUploader uploader.Uploader sslUploader uploader.Uploader
} }
@ -38,7 +38,7 @@ func NewDeployer(config *DeployerConfig) (*DeployerProvider, error) {
panic("config is nil") panic("config is nil")
} }
client := veLive.NewInstance() client := velive.NewInstance()
client.SetAccessKey(config.AccessKeyId) client.SetAccessKey(config.AccessKeyId)
client.SetSecretKey(config.AccessKeySecret) client.SetSecretKey(config.AccessKeySecret)
@ -85,7 +85,7 @@ func (d *DeployerProvider) Deploy(ctx context.Context, certPem string, privkeyPe
for { for {
// 查询域名列表 // 查询域名列表
// REF: https://www.volcengine.com/docs/6469/1186277#%E6%9F%A5%E8%AF%A2%E5%9F%9F%E5%90%8D%E5%88%97%E8%A1%A8 // REF: https://www.volcengine.com/docs/6469/1186277#%E6%9F%A5%E8%AF%A2%E5%9F%9F%E5%90%8D%E5%88%97%E8%A1%A8
listDomainDetailReq := &veLive.ListDomainDetailBody{ listDomainDetailReq := &velive.ListDomainDetailBody{
PageNum: listDomainDetailPageNum, PageNum: listDomainDetailPageNum,
PageSize: listDomainDetailPageSize, PageSize: listDomainDetailPageSize,
} }
@ -127,7 +127,7 @@ func (d *DeployerProvider) Deploy(ctx context.Context, certPem string, privkeyPe
for _, domain := range domains { for _, domain := range domains {
// 绑定证书 // 绑定证书
// REF: https://www.volcengine.com/docs/6469/1186278#%E7%BB%91%E5%AE%9A%E8%AF%81%E4%B9%A6 // REF: https://www.volcengine.com/docs/6469/1186278#%E7%BB%91%E5%AE%9A%E8%AF%81%E4%B9%A6
bindCertReq := &veLive.BindCertBody{ bindCertReq := &velive.BindCertBody{
ChainID: upres.CertId, ChainID: upres.CertId,
Domain: domain, Domain: domain,
HTTPS: ve.Bool(true), HTTPS: ve.Bool(true),

View File

@ -7,7 +7,7 @@ import (
"log/slog" "log/slog"
xerrors "github.com/pkg/errors" xerrors "github.com/pkg/errors"
veTos "github.com/volcengine/ve-tos-golang-sdk/v2/tos" "github.com/volcengine/ve-tos-golang-sdk/v2/tos"
"github.com/usual2970/certimate/internal/pkg/core/deployer" "github.com/usual2970/certimate/internal/pkg/core/deployer"
"github.com/usual2970/certimate/internal/pkg/core/uploader" "github.com/usual2970/certimate/internal/pkg/core/uploader"
@ -30,7 +30,7 @@ type DeployerConfig struct {
type DeployerProvider struct { type DeployerProvider struct {
config *DeployerConfig config *DeployerConfig
logger *slog.Logger logger *slog.Logger
sdkClient *veTos.ClientV2 sdkClient *tos.ClientV2
sslUploader uploader.Uploader sslUploader uploader.Uploader
} }
@ -91,9 +91,9 @@ func (d *DeployerProvider) Deploy(ctx context.Context, certPem string, privkeyPe
// 设置自定义域名 // 设置自定义域名
// REF: https://www.volcengine.com/docs/6559/1250189 // REF: https://www.volcengine.com/docs/6559/1250189
putBucketCustomDomainReq := &veTos.PutBucketCustomDomainInput{ putBucketCustomDomainReq := &tos.PutBucketCustomDomainInput{
Bucket: d.config.Bucket, Bucket: d.config.Bucket,
Rule: veTos.CustomDomainRule{ Rule: tos.CustomDomainRule{
Domain: d.config.Domain, Domain: d.config.Domain,
CertID: upres.CertId, CertID: upres.CertId,
}, },
@ -107,13 +107,13 @@ func (d *DeployerProvider) Deploy(ctx context.Context, certPem string, privkeyPe
return &deployer.DeployResult{}, nil return &deployer.DeployResult{}, nil
} }
func createSdkClient(accessKeyId, accessKeySecret, region string) (*veTos.ClientV2, error) { func createSdkClient(accessKeyId, accessKeySecret, region string) (*tos.ClientV2, error) {
endpoint := fmt.Sprintf("tos-%s.ivolces.com", region) endpoint := fmt.Sprintf("tos-%s.ivolces.com", region)
client, err := veTos.NewClientV2( client, err := tos.NewClientV2(
endpoint, endpoint,
veTos.WithRegion(region), tos.WithRegion(region),
veTos.WithCredentials(veTos.NewStaticCredentials(accessKeyId, accessKeySecret)), tos.WithCredentials(tos.NewStaticCredentials(accessKeyId, accessKeySecret)),
) )
if err != nil { if err != nil {
return nil, err return nil, err

View File

@ -85,7 +85,10 @@ func (u *UploaderProvider) Upload(ctx context.Context, certPem string, privkeyPe
if listUserCertificateOrderResp.Body.CertificateOrderList != nil { if listUserCertificateOrderResp.Body.CertificateOrderList != nil {
for _, certDetail := range listUserCertificateOrderResp.Body.CertificateOrderList { for _, certDetail := range listUserCertificateOrderResp.Body.CertificateOrderList {
if strings.EqualFold(certX509.SerialNumber.Text(16), *certDetail.SerialNo) { if !strings.EqualFold(certX509.SerialNumber.Text(16), *certDetail.SerialNo) {
continue
}
getUserCertificateDetailReq := &alicas.GetUserCertificateDetailRequest{ getUserCertificateDetailReq := &alicas.GetUserCertificateDetailRequest{
CertId: certDetail.CertificateId, CertId: certDetail.CertificateId,
} }
@ -117,7 +120,6 @@ func (u *UploaderProvider) Upload(ctx context.Context, certPem string, privkeyPe
} }
} }
} }
}
if listUserCertificateOrderResp.Body.CertificateOrderList == nil || len(listUserCertificateOrderResp.Body.CertificateOrderList) < int(listUserCertificateOrderLimit) { if listUserCertificateOrderResp.Body.CertificateOrderList == nil || len(listUserCertificateOrderResp.Body.CertificateOrderList) < int(listUserCertificateOrderLimit) {
break break

View File

@ -0,0 +1,139 @@
package baiducloudcert
import (
"context"
"fmt"
"log/slog"
"strings"
"time"
xerrors "github.com/pkg/errors"
"github.com/usual2970/certimate/internal/pkg/core/uploader"
"github.com/usual2970/certimate/internal/pkg/utils/certutil"
bdsdk "github.com/usual2970/certimate/internal/pkg/vendors/baiducloud-sdk/cert"
)
type UploaderConfig struct {
// 百度智能云 AccessKeyId。
AccessKeyId string `json:"accessKeyId"`
// 百度智能云 SecretAccessKey。
SecretAccessKey string `json:"secretAccessKey"`
}
type UploaderProvider struct {
config *UploaderConfig
logger *slog.Logger
sdkClient *bdsdk.Client
}
var _ uploader.Uploader = (*UploaderProvider)(nil)
func NewUploader(config *UploaderConfig) (*UploaderProvider, error) {
if config == nil {
panic("config is nil")
}
client, err := createSdkClient(config.AccessKeyId, config.SecretAccessKey)
if err != nil {
return nil, xerrors.Wrap(err, "failed to create sdk client")
}
return &UploaderProvider{
config: config,
logger: slog.Default(),
sdkClient: client,
}, nil
}
func (u *UploaderProvider) WithLogger(logger *slog.Logger) uploader.Uploader {
if logger == nil {
u.logger = slog.Default()
} else {
u.logger = logger
}
return u
}
func (u *UploaderProvider) Upload(ctx context.Context, certPem string, privkeyPem string) (res *uploader.UploadResult, err error) {
// 解析证书内容
certX509, err := certutil.ParseCertificateFromPEM(certPem)
if err != nil {
return nil, err
}
// 遍历证书列表,避免重复上传
// REF: https://cloud.baidu.com/doc/Reference/s/Gjwvz27xu#35-%E6%9F%A5%E7%9C%8B%E8%AF%81%E4%B9%A6%E5%88%97%E8%A1%A8%E8%AF%A6%E6%83%85
listCertDetail, err := u.sdkClient.ListCertDetail()
u.logger.Debug("sdk request 'cert.ListCertDetail'", slog.Any("response", listCertDetail))
if err != nil {
return nil, xerrors.Wrap(err, "failed to execute sdk request 'cert.ListCertDetail'")
} else {
for _, certDetail := range listCertDetail.Certs {
// 先对比证书通用名称
if !strings.EqualFold(certX509.Subject.CommonName, certDetail.CertCommonName) {
continue
}
// 再对比证书有效期
oldCertNotBefore, _ := time.Parse("2006-01-02T15:04:05Z", certDetail.CertStartTime)
oldCertNotAfter, _ := time.Parse("2006-01-02T15:04:05Z", certDetail.CertStopTime)
if !certX509.NotBefore.Equal(oldCertNotBefore) || !certX509.NotAfter.Equal(oldCertNotAfter) {
continue
}
// 再对比证书多域名
if certDetail.CertDNSNames != strings.Join(certX509.DNSNames, ",") {
continue
}
// 最后对比证书内容
getCertDetailResp, err := u.sdkClient.GetCertRawData(certDetail.CertId)
u.logger.Debug("sdk request 'cert.GetCertRawData'", slog.Any("certId", certDetail.CertId), slog.Any("response", getCertDetailResp))
if err != nil {
return nil, xerrors.Wrap(err, "failed to execute sdk request 'cert.GetCertRawData'")
} else {
oldCertX509, err := certutil.ParseCertificateFromPEM(getCertDetailResp.CertServerData)
if err != nil {
continue
}
if !certutil.EqualCertificate(certX509, oldCertX509) {
continue
}
}
// 如果以上信息都一致,则视为已存在相同证书,直接返回
u.logger.Info("ssl certificate already exists")
return &uploader.UploadResult{
CertId: certDetail.CertId,
CertName: certDetail.CertName,
}, nil
}
}
// 创建证书
// REF: https://cloud.baidu.com/doc/Reference/s/Gjwvz27xu#31-%E5%88%9B%E5%BB%BA%E8%AF%81%E4%B9%A6
createCertReq := &bdsdk.CreateCertArgs{}
createCertReq.CertName = fmt.Sprintf("certimate-%d", time.Now().UnixMilli())
createCertReq.CertServerData = certPem
createCertReq.CertPrivateData = privkeyPem
createCertResp, err := u.sdkClient.CreateCert(createCertReq)
u.logger.Debug("sdk request 'cert.CreateCert'", slog.Any("request", createCertReq), slog.Any("response", createCertResp))
if err != nil {
return nil, xerrors.Wrap(err, "failed to execute sdk request 'cert.CreateCert'")
}
return &uploader.UploadResult{
CertId: createCertResp.CertId,
CertName: createCertResp.CertName,
}, nil
}
func createSdkClient(accessKeyId, secretAccessKey string) (*bdsdk.Client, error) {
client, err := bdsdk.NewClient(accessKeyId, secretAccessKey, "")
if err != nil {
return nil, err
}
return client, nil
}

View File

@ -0,0 +1,72 @@
package baiducloudcert_test
import (
"context"
"encoding/json"
"flag"
"fmt"
"os"
"strings"
"testing"
provider "github.com/usual2970/certimate/internal/pkg/core/uploader/providers/baiducloud-cert"
)
var (
fInputCertPath string
fInputKeyPath string
fAccessKeyId string
fSecretAccessKey string
)
func init() {
argsPrefix := "CERTIMATE_UPLOADER_BAIDUCLOUDCAS_"
flag.StringVar(&fInputCertPath, argsPrefix+"INPUTCERTPATH", "", "")
flag.StringVar(&fInputKeyPath, argsPrefix+"INPUTKEYPATH", "", "")
flag.StringVar(&fAccessKeyId, argsPrefix+"ACCESSKEYID", "", "")
flag.StringVar(&fSecretAccessKey, argsPrefix+"SECRETACCESSKEY", "", "")
}
/*
Shell command to run this test:
go test -v ./baiducloud_cas_test.go -args \
--CERTIMATE_UPLOADER_BAIDUCLOUDCAS_INPUTCERTPATH="/path/to/your-input-cert.pem" \
--CERTIMATE_UPLOADER_BAIDUCLOUDCAS_INPUTKEYPATH="/path/to/your-input-key.pem" \
--CERTIMATE_UPLOADER_BAIDUCLOUDCAS_ACCESSKEYID="your-access-key-id" \
--CERTIMATE_UPLOADER_BAIDUCLOUDCAS_SECRETACCESSKEY="your-access-key-secret"
*/
func TestDeploy(t *testing.T) {
flag.Parse()
t.Run("Deploy", func(t *testing.T) {
t.Log(strings.Join([]string{
"args:",
fmt.Sprintf("INPUTCERTPATH: %v", fInputCertPath),
fmt.Sprintf("INPUTKEYPATH: %v", fInputKeyPath),
fmt.Sprintf("ACCESSKEYID: %v", fAccessKeyId),
fmt.Sprintf("SECRETACCESSKEY: %v", fSecretAccessKey),
}, "\n"))
uploader, err := provider.NewUploader(&provider.UploaderConfig{
AccessKeyId: fAccessKeyId,
SecretAccessKey: fSecretAccessKey,
})
if err != nil {
t.Errorf("err: %+v", err)
return
}
fInputCertData, _ := os.ReadFile(fInputCertPath)
fInputKeyData, _ := os.ReadFile(fInputKeyPath)
res, err := uploader.Upload(context.Background(), string(fInputCertData), string(fInputKeyData))
if err != nil {
t.Errorf("err: %+v", err)
return
}
sres, _ := json.Marshal(res)
t.Logf("ok: %s", string(sres))
})
}

View File

@ -59,9 +59,9 @@ func (u *UploaderProvider) Upload(ctx context.Context, certPem string, privkeyPe
PrivateKey: privkeyPem, PrivateKey: privkeyPem,
} }
uploadHttpsCertificateResp, err := u.sdkClient.UploadHttpsCertificate(uploadHttpsCertificateReq) uploadHttpsCertificateResp, err := u.sdkClient.UploadHttpsCertificate(uploadHttpsCertificateReq)
u.logger.Debug("sdk request 'ssl.UploadHttpsCertificate'", slog.Any("response", uploadHttpsCertificateResp)) u.logger.Debug("sdk request 'console.UploadHttpsCertificate'", slog.Any("response", uploadHttpsCertificateResp))
if err != nil { if err != nil {
return nil, xerrors.Wrap(err, "failed to execute sdk request 'ssl.UploadHttpsCertificate'") return nil, xerrors.Wrap(err, "failed to execute sdk request 'console.UploadHttpsCertificate'")
} }
return &uploader.UploadResult{ return &uploader.UploadResult{

View File

@ -27,6 +27,6 @@ type Uploader interface {
// 表示证书上传结果的数据结构,包含上传后的证书 ID、名称和其他数据。 // 表示证书上传结果的数据结构,包含上传后的证书 ID、名称和其他数据。
type UploadResult struct { type UploadResult struct {
CertId string `json:"certId"` CertId string `json:"certId"`
CertName string `json:"certName"` CertName string `json:"certName,omitzero"`
ExtendedData map[string]any `json:"extendedData,omitempty"` ExtendedData map[string]any `json:"extendedData,omitempty"`
} }

View File

@ -8,44 +8,29 @@ import (
func (c *Client) UpdateSystemSSL(req *UpdateSystemSSLRequest) (*UpdateSystemSSLResponse, error) { func (c *Client) UpdateSystemSSL(req *UpdateSystemSSLRequest) (*UpdateSystemSSLResponse, error) {
resp := &UpdateSystemSSLResponse{} resp := &UpdateSystemSSLResponse{}
err := c.sendRequestWithResult(http.MethodPost, "/settings/ssl/update", req, resp) err := c.sendRequestWithResult(http.MethodPost, "/settings/ssl/update", req, resp)
if err != nil { return resp, err
return nil, err
}
return resp, nil
} }
func (c *Client) SearchWebsiteSSL(req *SearchWebsiteSSLRequest) (*SearchWebsiteSSLResponse, error) { func (c *Client) SearchWebsiteSSL(req *SearchWebsiteSSLRequest) (*SearchWebsiteSSLResponse, error) {
resp := &SearchWebsiteSSLResponse{} resp := &SearchWebsiteSSLResponse{}
err := c.sendRequestWithResult(http.MethodPost, "/websites/ssl/search", req, resp) err := c.sendRequestWithResult(http.MethodPost, "/websites/ssl/search", req, resp)
if err != nil { return resp, err
return nil, err
}
return resp, nil
} }
func (c *Client) UploadWebsiteSSL(req *UploadWebsiteSSLRequest) (*UploadWebsiteSSLResponse, error) { func (c *Client) UploadWebsiteSSL(req *UploadWebsiteSSLRequest) (*UploadWebsiteSSLResponse, error) {
resp := &UploadWebsiteSSLResponse{} resp := &UploadWebsiteSSLResponse{}
err := c.sendRequestWithResult(http.MethodPost, "/websites/ssl/upload", req, resp) err := c.sendRequestWithResult(http.MethodPost, "/websites/ssl/upload", req, resp)
if err != nil { return resp, err
return nil, err
}
return resp, nil
} }
func (c *Client) GetHttpsConf(req *GetHttpsConfRequest) (*GetHttpsConfResponse, error) { func (c *Client) GetHttpsConf(req *GetHttpsConfRequest) (*GetHttpsConfResponse, error) {
resp := &GetHttpsConfResponse{} resp := &GetHttpsConfResponse{}
err := c.sendRequestWithResult(http.MethodGet, fmt.Sprintf("/websites/%d/https", req.WebsiteID), req, resp) err := c.sendRequestWithResult(http.MethodGet, fmt.Sprintf("/websites/%d/https", req.WebsiteID), req, resp)
if err != nil { return resp, err
return nil, err
}
return resp, nil
} }
func (c *Client) UpdateHttpsConf(req *UpdateHttpsConfRequest) (*UpdateHttpsConfResponse, error) { func (c *Client) UpdateHttpsConf(req *UpdateHttpsConfRequest) (*UpdateHttpsConfResponse, error) {
resp := &UpdateHttpsConfResponse{} resp := &UpdateHttpsConfResponse{}
err := c.sendRequestWithResult(http.MethodPost, fmt.Sprintf("/websites/%d/https", req.WebsiteID), req, resp) err := c.sendRequestWithResult(http.MethodPost, fmt.Sprintf("/websites/%d/https", req.WebsiteID), req, resp)
if err != nil { return resp, err
return nil, err
}
return resp, nil
} }

View File

@ -77,9 +77,9 @@ func (c *Client) sendRequest(method string, path string, params interface{}) (*r
resp, err := req.Send() resp, err := req.Send()
if err != nil { if err != nil {
return nil, fmt.Errorf("1panel api error: failed to send request: %w", err) return resp, fmt.Errorf("1panel api error: failed to send request: %w", err)
} else if resp.IsError() { } else if resp.IsError() {
return nil, fmt.Errorf("1panel api error: unexpected status code: %d, %s", resp.StatusCode(), resp.Body()) return resp, fmt.Errorf("1panel api error: unexpected status code: %d, %s", resp.StatusCode(), resp.Body())
} }
return resp, nil return resp, nil
@ -88,6 +88,9 @@ func (c *Client) sendRequest(method string, path string, params interface{}) (*r
func (c *Client) sendRequestWithResult(method string, path string, params interface{}, result BaseResponse) error { func (c *Client) sendRequestWithResult(method string, path string, params interface{}, result BaseResponse) error {
resp, err := c.sendRequest(method, path, params) resp, err := c.sendRequest(method, path, params)
if err != nil { if err != nil {
if resp != nil {
json.Unmarshal(resp.Body(), &result)
}
return err return err
} }

View File

@ -6,16 +6,22 @@ type BaseResponse interface {
} }
type baseResponse struct { type baseResponse struct {
Code int32 `json:"code"` Code *int32 `json:"code,omitempty"`
Message string `json:"message"` Message *string `json:"message,omitempty"`
} }
func (r *baseResponse) GetCode() int32 { func (r *baseResponse) GetCode() int32 {
return r.Code if r.Code != nil {
return *r.Code
}
return 0
} }
func (r *baseResponse) GetMessage() string { func (r *baseResponse) GetMessage() string {
return r.Message if r.Message != nil {
return *r.Message
}
return ""
} }
type UpdateSystemSSLRequest struct { type UpdateSystemSSLRequest struct {
@ -38,7 +44,7 @@ type SearchWebsiteSSLRequest struct {
type SearchWebsiteSSLResponse struct { type SearchWebsiteSSLResponse struct {
baseResponse baseResponse
Data struct { Data *struct {
Items []*struct { Items []*struct {
ID int64 `json:"id"` ID int64 `json:"id"`
PEM string `json:"pem"` PEM string `json:"pem"`
@ -50,7 +56,7 @@ type SearchWebsiteSSLResponse struct {
CreatedAt string `json:"createdAt"` CreatedAt string `json:"createdAt"`
} `json:"items"` } `json:"items"`
Total int32 `json:"total"` Total int32 `json:"total"`
} `json:"data"` } `json:"data,omitempty"`
} }
type UploadWebsiteSSLRequest struct { type UploadWebsiteSSLRequest struct {
@ -73,13 +79,13 @@ type GetHttpsConfRequest struct {
type GetHttpsConfResponse struct { type GetHttpsConfResponse struct {
baseResponse baseResponse
Data struct { Data *struct {
Enable bool `json:"enable"` Enable bool `json:"enable"`
HttpConfig string `json:"httpConfig"` HttpConfig string `json:"httpConfig"`
SSLProtocol []string `json:"SSLProtocol"` SSLProtocol []string `json:"SSLProtocol"`
Algorithm string `json:"algorithm"` Algorithm string `json:"algorithm"`
Hsts bool `json:"hsts"` Hsts bool `json:"hsts"`
} `json:"data"` } `json:"data,omitempty"`
} }
type UpdateHttpsConfRequest struct { type UpdateHttpsConfRequest struct {

View File

@ -0,0 +1,93 @@
package cert
import (
"errors"
"fmt"
"github.com/baidubce/bce-sdk-go/bce"
"github.com/baidubce/bce-sdk-go/http"
"github.com/baidubce/bce-sdk-go/services/cert"
)
func (c *Client) CreateCert(args *CreateCertArgs) (*CreateCertResult, error) {
if args == nil {
return nil, errors.New("unset args")
}
result, err := c.Client.CreateCert(&args.CreateCertArgs)
if err != nil {
return nil, err
}
return &CreateCertResult{CreateCertResult: *result}, nil
}
func (c *Client) ListCerts() (*ListCertResult, error) {
result, err := c.Client.ListCerts()
if err != nil {
return nil, err
}
return &ListCertResult{ListCertResult: *result}, nil
}
func (c *Client) ListCertDetail() (*ListCertDetailResult, error) {
result, err := c.Client.ListCertDetail()
if err != nil {
return nil, err
}
return &ListCertDetailResult{ListCertDetailResult: *result}, nil
}
func (c *Client) GetCertMeta(id string) (*CertificateMeta, error) {
result, err := c.Client.GetCertMeta(id)
if err != nil {
return nil, err
}
return &CertificateMeta{CertificateMeta: *result}, nil
}
func (c *Client) GetCertDetail(id string) (*CertificateDetailMeta, error) {
result, err := c.Client.GetCertDetail(id)
if err != nil {
return nil, err
}
return &CertificateDetailMeta{CertificateDetailMeta: *result}, nil
}
func (c *Client) GetCertRawData(id string) (*CertificateRawData, error) {
result := &CertificateRawData{}
err := bce.NewRequestBuilder(c).
WithMethod(http.GET).
WithURL(cert.URI_PREFIX + cert.REQUEST_CERT_URL + "/" + id + "/rawData").
WithResult(result).
Do()
return result, err
}
func (c *Client) UpdateCertName(id string, args *UpdateCertNameArgs) error {
if args == nil {
return errors.New("unset args")
}
err := c.Client.UpdateCertName(id, &args.UpdateCertNameArgs)
return err
}
func (c *Client) UpdateCertData(id string, args *UpdateCertDataArgs) error {
if args == nil {
return fmt.Errorf("unset args")
}
err := c.Client.UpdateCertData(id, &args.UpdateCertDataArgs)
return err
}
func (c *Client) DeleteCert(id string) error {
err := c.Client.DeleteCert(id)
return err
}

View File

@ -0,0 +1,17 @@
package cert
import (
"github.com/baidubce/bce-sdk-go/services/cert"
)
type Client struct {
*cert.Client
}
func NewClient(ak, sk, endPoint string) (*Client, error) {
client, err := cert.NewClient(ak, sk, endPoint)
if err != nil {
return nil, err
}
return &Client{client}, nil
}

View File

@ -0,0 +1,48 @@
package cert
import "github.com/baidubce/bce-sdk-go/services/cert"
type CreateCertArgs struct {
cert.CreateCertArgs
}
type CreateCertResult struct {
cert.CreateCertResult
}
type UpdateCertNameArgs struct {
cert.UpdateCertNameArgs
}
type CertificateMeta struct {
cert.CertificateMeta
}
type CertificateDetailMeta struct {
cert.CertificateDetailMeta
}
type CertificateRawData struct {
CertId string `json:"certId"`
CertName string `json:"certName"`
CertServerData string `json:"certServerData"`
CertPrivateData string `json:"certPrivateKey"`
CertLinkData string `json:"certLinkData,omitempty"`
CertType int `json:"certType,omitempty"`
}
type ListCertResult struct {
cert.ListCertResult
}
type ListCertDetailResult struct {
cert.ListCertDetailResult
}
type UpdateCertDataArgs struct {
cert.UpdateCertDataArgs
}
type CertInServiceMeta struct {
cert.CertInServiceMeta
}

View File

@ -5,28 +5,19 @@ import (
) )
func (c *Client) CreateCertificate(req *CreateCertificateRequest) (*CreateCertificateResponse, error) { func (c *Client) CreateCertificate(req *CreateCertificateRequest) (*CreateCertificateResponse, error) {
resp := CreateCertificateResponse{} resp := &CreateCertificateResponse{}
err := c.sendRequestWithResult(http.MethodPost, "/v2/domain/certificate", req, &resp) err := c.sendRequestWithResult(http.MethodPost, "/v2/domain/certificate", req, resp)
if err != nil { return resp, err
return nil, err
}
return &resp, nil
} }
func (c *Client) GetDomainConfig(req *GetDomainConfigRequest) (*GetDomainConfigResponse, error) { func (c *Client) GetDomainConfig(req *GetDomainConfigRequest) (*GetDomainConfigResponse, error) {
resp := GetDomainConfigResponse{} resp := &GetDomainConfigResponse{}
err := c.sendRequestWithResult(http.MethodGet, "/v2/domain/config", req, &resp) err := c.sendRequestWithResult(http.MethodGet, "/v2/domain/config", req, resp)
if err != nil { return resp, err
return nil, err
}
return &resp, nil
} }
func (c *Client) SetDomainConfig(req *SetDomainConfigRequest) (*SetDomainConfigResponse, error) { func (c *Client) SetDomainConfig(req *SetDomainConfigRequest) (*SetDomainConfigResponse, error) {
resp := SetDomainConfigResponse{} resp := &SetDomainConfigResponse{}
err := c.sendRequestWithResult(http.MethodPost, "/v2/domain/config", req, &resp) err := c.sendRequestWithResult(http.MethodPost, "/v2/domain/config", req, resp)
if err != nil { return resp, err
return nil, err
}
return &resp, nil
} }

View File

@ -4,6 +4,8 @@ import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"net/http" "net/http"
"net/url"
"reflect"
"strings" "strings"
"time" "time"
@ -35,21 +37,33 @@ func (c *Client) sendRequest(method string, path string, params interface{}) (*r
req.Method = method req.Method = method
req.URL = "https://cdn.api.baishan.com" + path req.URL = "https://cdn.api.baishan.com" + path
if strings.EqualFold(method, http.MethodGet) { if strings.EqualFold(method, http.MethodGet) {
qs := make(map[string]string) qs := url.Values{}
if params != nil { if params != nil {
temp := make(map[string]any) temp := make(map[string]any)
jsonb, _ := json.Marshal(params) jsonb, _ := json.Marshal(params)
json.Unmarshal(jsonb, &temp) json.Unmarshal(jsonb, &temp)
for k, v := range temp { for k, v := range temp {
if v != nil { if v != nil {
qs[k] = fmt.Sprintf("%v", v) rv := reflect.ValueOf(v)
switch rv.Kind() {
case reflect.Slice, reflect.Array:
for i := 0; i < rv.Len(); i++ {
qs.Add(fmt.Sprintf("%s[]", k), fmt.Sprintf("%v", rv.Index(i).Interface()))
}
case reflect.Map:
for _, rk := range rv.MapKeys() {
qs.Add(fmt.Sprintf("%s[%s]", k, rk.Interface()), fmt.Sprintf("%v", rv.MapIndex(rk).Interface()))
}
default:
qs.Set(k, fmt.Sprintf("%v", v))
}
} }
} }
} }
req = req. req = req.
SetQueryParams(qs). SetQueryParam("token", c.apiToken).
SetQueryParam("token", c.apiToken) SetQueryParamsFromValues(qs)
} else { } else {
req = req. req = req.
SetHeader("Content-Type", "application/json"). SetHeader("Content-Type", "application/json").
@ -59,9 +73,9 @@ func (c *Client) sendRequest(method string, path string, params interface{}) (*r
resp, err := req.Send() resp, err := req.Send()
if err != nil { if err != nil {
return nil, fmt.Errorf("baishan api error: failed to send request: %w", err) return resp, fmt.Errorf("baishan api error: failed to send request: %w", err)
} else if resp.IsError() { } else if resp.IsError() {
return nil, fmt.Errorf("baishan api error: unexpected status code: %d, %s", resp.StatusCode(), resp.Body()) return resp, fmt.Errorf("baishan api error: unexpected status code: %d, %s", resp.StatusCode(), resp.Body())
} }
return resp, nil return resp, nil
@ -70,6 +84,9 @@ func (c *Client) sendRequest(method string, path string, params interface{}) (*r
func (c *Client) sendRequestWithResult(method string, path string, params interface{}, result BaseResponse) error { func (c *Client) sendRequestWithResult(method string, path string, params interface{}, result BaseResponse) error {
resp, err := c.sendRequest(method, path, params) resp, err := c.sendRequest(method, path, params)
if err != nil { if err != nil {
if resp != nil {
json.Unmarshal(resp.Body(), &result)
}
return err return err
} }

View File

@ -1,21 +1,29 @@
package baishansdk package baishansdk
import "encoding/json"
type BaseResponse interface { type BaseResponse interface {
GetCode() int GetCode() int32
GetMessage() string GetMessage() string
} }
type baseResponse struct { type baseResponse struct {
Code int `json:"code"` Code *int32 `json:"code,omitempty"`
Message string `json:"message"` Message *string `json:"message,omitempty"`
} }
func (r *baseResponse) GetCode() int { func (r *baseResponse) GetCode() int32 {
return r.Code if r.Code != nil {
return *r.Code
}
return 0
} }
func (r *baseResponse) GetMessage() string { func (r *baseResponse) GetMessage() string {
return r.Message if r.Message != nil {
return *r.Message
}
return ""
} }
type CreateCertificateRequest struct { type CreateCertificateRequest struct {
@ -26,7 +34,7 @@ type CreateCertificateRequest struct {
type CreateCertificateResponse struct { type CreateCertificateResponse struct {
baseResponse baseResponse
Data *DomainCertificate `json:"data"` Data *DomainCertificate `json:"data,omitempty"`
} }
type GetDomainConfigRequest struct { type GetDomainConfigRequest struct {
@ -39,7 +47,7 @@ type GetDomainConfigResponse struct {
Data []*struct { Data []*struct {
Domain string `json:"domain"` Domain string `json:"domain"`
Config *DomainConfig `json:"config"` Config *DomainConfig `json:"config"`
} `json:"data"` } `json:"data,omitempty"`
} }
type SetDomainConfigRequest struct { type SetDomainConfigRequest struct {
@ -51,11 +59,11 @@ type SetDomainConfigResponse struct {
baseResponse baseResponse
Data *struct { Data *struct {
Config *DomainConfig `json:"config"` Config *DomainConfig `json:"config"`
} `json:"data"` } `json:"data,omitempty"`
} }
type DomainCertificate struct { type DomainCertificate struct {
CertId int64 `json:"cert_id"` CertId json.Number `json:"cert_id"`
Name string `json:"name"` Name string `json:"name"`
CertStartTime string `json:"cert_start_time"` CertStartTime string `json:"cert_start_time"`
CertExpireTime string `json:"cert_expire_time"` CertExpireTime string `json:"cert_expire_time"`
@ -66,7 +74,7 @@ type DomainConfig struct {
} }
type DomainConfigHttps struct { type DomainConfigHttps struct {
CertId int64 `json:"cert_id"` CertId json.Number `json:"cert_id"`
ForceHttps *string `json:"force_https,omitempty"` ForceHttps *string `json:"force_https,omitempty"`
EnableHttp2 *string `json:"http2,omitempty"` EnableHttp2 *string `json:"http2,omitempty"`
EnableOcsp *string `json:"ocsp,omitempty"` EnableOcsp *string `json:"ocsp,omitempty"`

View File

@ -1,46 +1,31 @@
package btpanelsdk package btpanelsdk
func (c *Client) ConfigSavePanelSSL(req *ConfigSavePanelSSLRequest) (*ConfigSavePanelSSLResponse, error) { func (c *Client) ConfigSavePanelSSL(req *ConfigSavePanelSSLRequest) (*ConfigSavePanelSSLResponse, error) {
resp := ConfigSavePanelSSLResponse{} resp := &ConfigSavePanelSSLResponse{}
err := c.sendRequestWithResult("/config?action=SavePanelSSL", req, &resp) err := c.sendRequestWithResult("/config?action=SavePanelSSL", req, resp)
if err != nil { return resp, err
return nil, err
}
return &resp, nil
} }
func (c *Client) SiteSetSSL(req *SiteSetSSLRequest) (*SiteSetSSLResponse, error) { func (c *Client) SiteSetSSL(req *SiteSetSSLRequest) (*SiteSetSSLResponse, error) {
resp := SiteSetSSLResponse{} resp := &SiteSetSSLResponse{}
err := c.sendRequestWithResult("/site?action=SetSSL", req, &resp) err := c.sendRequestWithResult("/site?action=SetSSL", req, resp)
if err != nil { return resp, err
return nil, err
}
return &resp, nil
} }
func (c *Client) SystemServiceAdmin(req *SystemServiceAdminRequest) (*SystemServiceAdminResponse, error) { func (c *Client) SystemServiceAdmin(req *SystemServiceAdminRequest) (*SystemServiceAdminResponse, error) {
resp := SystemServiceAdminResponse{} resp := &SystemServiceAdminResponse{}
err := c.sendRequestWithResult("/system?action=ServiceAdmin", req, &resp) err := c.sendRequestWithResult("/system?action=ServiceAdmin", req, resp)
if err != nil { return resp, err
return nil, err
}
return &resp, nil
} }
func (c *Client) SSLCertSaveCert(req *SSLCertSaveCertRequest) (*SSLCertSaveCertResponse, error) { func (c *Client) SSLCertSaveCert(req *SSLCertSaveCertRequest) (*SSLCertSaveCertResponse, error) {
resp := SSLCertSaveCertResponse{} resp := &SSLCertSaveCertResponse{}
err := c.sendRequestWithResult("/ssl/cert/save_cert", req, &resp) err := c.sendRequestWithResult("/ssl/cert/save_cert", req, resp)
if err != nil { return resp, err
return nil, err
}
return &resp, nil
} }
func (c *Client) SSLSetBatchCertToSite(req *SSLSetBatchCertToSiteRequest) (*SSLSetBatchCertToSiteResponse, error) { func (c *Client) SSLSetBatchCertToSite(req *SSLSetBatchCertToSiteRequest) (*SSLSetBatchCertToSiteResponse, error) {
resp := SSLSetBatchCertToSiteResponse{} resp := &SSLSetBatchCertToSiteResponse{}
err := c.sendRequestWithResult("/ssl?action=SetBatchCertToSite", req, &resp) err := c.sendRequestWithResult("/ssl?action=SetBatchCertToSite", req, resp)
if err != nil { return resp, err
return nil, err
}
return &resp, nil
} }

View File

@ -84,9 +84,9 @@ func (c *Client) sendRequest(path string, params interface{}) (*resty.Response,
SetFormData(data) SetFormData(data)
resp, err := req.Post(url) resp, err := req.Post(url)
if err != nil { if err != nil {
return nil, fmt.Errorf("baota api error: failed to send request: %w", err) return resp, fmt.Errorf("baota api error: failed to send request: %w", err)
} else if resp.IsError() { } else if resp.IsError() {
return nil, fmt.Errorf("baota api error: unexpected status code: %d, %s", resp.StatusCode(), resp.Body()) return resp, fmt.Errorf("baota api error: unexpected status code: %d, %s", resp.StatusCode(), resp.Body())
} }
return resp, nil return resp, nil

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