feat(provider): new deployment provider: tencentcloud eomakers

This commit is contained in:
Bigsk
2026-07-14 00:32:39 +08:00
committed by GitHub
parent 4c5ee94517
commit 77ef8677f9
20 changed files with 1038 additions and 26 deletions
@@ -0,0 +1,7 @@
package tencentcloudeomakers
const (
DomainMatchPatternExact = "exact"
DomainMatchPatternWildcard = "wildcard"
DomainMatchPatternCertSan = "certsan"
)
@@ -0,0 +1,357 @@
package tencentcloudeomakers
import (
"context"
"crypto/x509"
"errors"
"fmt"
"log/slog"
"strings"
"time"
"github.com/samber/lo"
"github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common"
"github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/profile"
tceo "github.com/certimate-go/certimate/pkg/sdk3rd-trimmed/github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/teo/v20220901"
"github.com/certimate-go/certimate/pkg/core"
cmgrimpl "github.com/certimate-go/certimate/pkg/core/certmgr/providers/tencentcloud-ssl"
tceomakersssdk "github.com/certimate-go/certimate/pkg/sdk3rd/tencentcloud/teomakers"
xcert "github.com/certimate-go/certimate/pkg/utils/cert"
xcerthostname "github.com/certimate-go/certimate/pkg/utils/cert/hostname"
xcertkey "github.com/certimate-go/certimate/pkg/utils/cert/key"
xtencentcloud "github.com/certimate-go/certimate/pkg/utils/third-party/tencentcloud"
)
type (
Provider = core.Deployer
DeployResult = core.DeployerDeployResult
)
type DeployerConfig struct {
// 腾讯云 SecretId。
SecretId string `json:"secretId"`
// 腾讯云 SecretKey。
SecretKey string `json:"secretKey"`
// 腾讯云项目 ID。
ProjectId int64 `json:"projectId,omitempty"`
// 腾讯云接口端点。
Endpoint string `json:"endpoint,omitempty"`
// EdgeOne Makers API Token。
MakersApiToken string `json:"makersApiToken"`
// EdgeOne Makers 项目 ID。
MakersProjectId string `json:"makersProjectId"`
// 域名匹配模式。
// 零值时默认值 [DOMAIN_MATCH_PATTERN_EXACT]。
DomainMatchPattern string `json:"domainMatchPattern,omitempty"`
// 加速域名列表(支持泛域名)。
Domains []string `json:"domains"`
// 是否启用多证书模式。
EnableMultipleSSL bool `json:"enableMultipleSSL,omitempty"`
}
type Deployer struct {
config *DeployerConfig
logger *slog.Logger
sdkClients *wSDKClients
sdkCertmgr core.Certmgr
}
var _ Provider = (*Deployer)(nil)
type wSDKClients struct {
TEO *tceo.Client
TEOMakers *tceomakersssdk.Client
}
func NewDeployer(config *DeployerConfig) (*Deployer, error) {
if config == nil {
return nil, fmt.Errorf("the configuration of the deployer provider is nil")
}
clients, err := createSDKClients(config.SecretId, config.SecretKey, config.Endpoint, config.MakersApiToken)
if err != nil {
return nil, fmt.Errorf("could not create client: %w", err)
}
pcertmgr, err := cmgrimpl.NewCertmgr(&cmgrimpl.CertmgrConfig{
SecretId: config.SecretId,
SecretKey: config.SecretKey,
ProjectId: config.ProjectId,
Endpoint: lo.Ternary(xtencentcloud.IsIntlAPIEndpoint(config.Endpoint), "ssl.intl.tencentcloudapi.com", ""),
})
if err != nil {
return nil, fmt.Errorf("could not create certmgr: %w", err)
}
return &Deployer{
config: config,
logger: slog.Default(),
sdkClients: clients,
sdkCertmgr: pcertmgr,
}, nil
}
func (d *Deployer) SetLogger(logger *slog.Logger) {
if logger == nil {
d.logger = slog.New(slog.DiscardHandler)
} else {
d.logger = logger
}
d.sdkCertmgr.SetLogger(logger)
}
func (d *Deployer) Deploy(ctx context.Context, certPEM, privkeyPEM string) (*DeployResult, error) {
if d.config.MakersProjectId == "" {
return nil, fmt.Errorf("config `makersProjectId` is required")
}
// 上传证书
upres, err := d.sdkCertmgr.Upload(ctx, certPEM, privkeyPEM)
if err != nil {
return nil, fmt.Errorf("failed to upload certificate file: %w", err)
} else {
d.logger.Info("ssl certificate uploaded", slog.Any("result", upres))
}
// 获取全部可部署的域名列表
domainsInMakers, err := d.getAllDomainsInProject(ctx, d.config.MakersProjectId)
if err != nil {
return nil, err
}
// 获取待部署的域名列表
var domains []string
switch d.config.DomainMatchPattern {
case "", DomainMatchPatternExact:
{
if len(d.config.Domains) == 0 {
return nil, fmt.Errorf("config `domains` is required")
}
domains = d.config.Domains
}
case DomainMatchPatternWildcard:
{
if len(d.config.Domains) == 0 {
return nil, fmt.Errorf("config `domains` is required")
}
domainCandidates := lo.Map(domainsInMakers, func(domainInfo *tceomakersssdk.PagesZoneCustomDomain, _ int) string {
return lo.FromPtr(domainInfo.Domain)
})
domains = lo.Filter(domainCandidates, func(domain string, _ int) bool {
for _, configDomain := range d.config.Domains {
if xcerthostname.IsMatch(configDomain, domain) {
return true
}
}
return false
})
if len(domains) == 0 {
return nil, fmt.Errorf("could not find any domains matched by wildcard")
}
}
case DomainMatchPatternCertSan:
{
domainCandidates := lo.Map(domainsInMakers, func(domainInfo *tceomakersssdk.PagesZoneCustomDomain, _ int) string {
return lo.FromPtr(domainInfo.Domain)
})
domains = lo.Filter(domainCandidates, func(domain string, _ int) bool {
return xcerthostname.IsMatchByCertificatePEM(certPEM, domain)
})
if len(domains) == 0 {
return nil, fmt.Errorf("could not find any domains matched by certificate")
}
}
default:
return nil, fmt.Errorf("unsupported domain match pattern: '%s'", d.config.DomainMatchPattern)
}
// 批量更新域名证书
if len(domains) == 0 {
d.logger.Info("no edgeone makers domains to deploy")
} else {
d.logger.Info("found edgeone makers domains to deploy", slog.Any("domains", domains))
// 获取站点 ID
zoneId := domainsInMakers[0].ZoneId
// 获取证书列表
describeHostCertificatesReq := tceo.NewDescribeHostCertificatesRequest()
describeHostCertificatesReq.ZoneId = zoneId
describeHostCertificatesResp, err := d.sdkClients.TEO.DescribeHostCertificatesWithContext(ctx, describeHostCertificatesReq)
d.logger.Debug("sdk request 'teo.DescribeHostCertificates'", slog.Any("request", describeHostCertificatesReq), slog.Any("response", describeHostCertificatesResp))
if err != nil {
return nil, fmt.Errorf("failed to execute sdk request 'teo.DescribeHostCertificates': %w", err)
}
// 跳过已部署过的域名
domains = lo.Filter(domains, func(domain string, _ int) bool {
var deployed bool
domainInfo, _ := lo.Find(domainsInMakers, func(domainInfo *tceomakersssdk.PagesZoneCustomDomain) bool {
return domain == lo.FromPtr(domainInfo.Domain)
})
if domainInfo != nil && describeHostCertificatesResp.Response != nil {
deployed = lo.SomeBy(describeHostCertificatesResp.Response.HostCertificates, func(hostInfo *tceo.HostCertificate) bool {
return domain == lo.FromPtr(hostInfo.Host) &&
lo.SomeBy(hostInfo.HostCertInfo, func(certInfo *tceo.CertificateInfo) bool {
return upres.CertId == lo.FromPtr(certInfo.CertId)
})
})
}
return !deployed
})
// 配置域名证书
// REF: https://cloud.tencent.com/document/api/1552/80764
modifyHostsCertificateReqs := make([]*tceo.ModifyHostsCertificateRequest, 0)
if d.config.EnableMultipleSSL {
const algRSA = "RSA"
const algECC = "ECC"
privkey, err := xcert.ParsePrivateKeyFromPEM(privkeyPEM)
if err != nil {
return nil, fmt.Errorf("failed to parse private key: %w", err)
}
privkeyAlg, _, _ := xcertkey.GetPrivateKeyAlgorithm(privkey)
privkeyAlgStr := ""
switch privkeyAlg {
case x509.RSA:
privkeyAlgStr = algRSA
case x509.ECDSA:
privkeyAlgStr = algECC
}
for _, domain := range domains {
modifyHostsCertificateReq := tceo.NewModifyHostsCertificateRequest()
modifyHostsCertificateReq.ZoneId = zoneId
modifyHostsCertificateReq.Mode = common.StringPtr("sslcert")
modifyHostsCertificateReq.Hosts = common.StringPtrs([]string{domain})
modifyHostsCertificateReq.ServerCertInfo = []*tceo.ServerCertInfo{{CertId: common.StringPtr(upres.CertId)}}
domainInfo, _ := lo.Find(domainsInMakers, func(domainInfo *tceomakersssdk.PagesZoneCustomDomain) bool {
return domain == lo.FromPtr(domainInfo.Domain)
})
if domainInfo != nil && describeHostCertificatesResp.Response != nil {
for _, hostInfo := range describeHostCertificatesResp.Response.HostCertificates {
if lo.FromPtr(hostInfo.Host) != domain {
continue
}
for _, certInfo := range hostInfo.HostCertInfo {
if lo.FromPtr(certInfo.CertId) == upres.CertId {
continue
}
if strings.Split(lo.FromPtr(certInfo.SignAlgo), " ")[0] == privkeyAlgStr {
continue
}
certExpireTime, _ := time.Parse("2006-01-02T15:04:05Z", lo.FromPtr(certInfo.ExpireTime))
if certExpireTime.Before(time.Now()) {
continue
}
modifyHostsCertificateReq.ServerCertInfo = append(modifyHostsCertificateReq.ServerCertInfo, &tceo.ServerCertInfo{CertId: certInfo.CertId})
}
}
}
modifyHostsCertificateReqs = append(modifyHostsCertificateReqs, modifyHostsCertificateReq)
}
} else {
modifyHostsCertificateReq := tceo.NewModifyHostsCertificateRequest()
modifyHostsCertificateReq.ZoneId = zoneId
modifyHostsCertificateReq.Mode = common.StringPtr("sslcert")
modifyHostsCertificateReq.Hosts = common.StringPtrs(domains)
modifyHostsCertificateReq.ServerCertInfo = []*tceo.ServerCertInfo{{CertId: common.StringPtr(upres.CertId)}}
modifyHostsCertificateReqs = append(modifyHostsCertificateReqs, modifyHostsCertificateReq)
}
var errs []error
for _, modifyHostsCertificateReq := range modifyHostsCertificateReqs {
select {
case <-ctx.Done():
return nil, ctx.Err()
default:
modifyHostsCertificateResp, err := d.sdkClients.TEO.ModifyHostsCertificateWithContext(ctx, modifyHostsCertificateReq)
d.logger.Debug("sdk request 'teo.ModifyHostsCertificate'", slog.Any("request", modifyHostsCertificateReq), slog.Any("response", modifyHostsCertificateResp))
if err != nil {
err = fmt.Errorf("failed to execute sdk request 'teo.ModifyHostsCertificate': %w", err)
errs = append(errs, err)
}
}
}
if len(errs) > 0 {
return nil, errors.Join(errs...)
}
}
return &DeployResult{}, nil
}
func (d *Deployer) getAllDomainsInProject(ctx context.Context, makersProjectId string) ([]*tceomakersssdk.PagesZoneCustomDomain, error) {
// 查询创建过的 Pages 自定义域名列表
// REF: https://docs.edgeone.site/#/?id=describepageszonecustomdomains
describeMakersZoneCustomDomainsReq := &tceomakersssdk.DescribePagesZoneCustomDomainsRequest{
ProjectId: common.StringPtr(makersProjectId),
}
describeMakersZoneCustomDomainsResp, err := d.sdkClients.TEOMakers.DescribePagesZoneCustomDomainsWithContext(ctx, describeMakersZoneCustomDomainsReq)
d.logger.Debug("api request 'teo.makers.DescribePagesZoneCustomDomains'", slog.Any("request", describeMakersZoneCustomDomainsReq), slog.Any("response", describeMakersZoneCustomDomainsResp))
if err != nil {
return nil, fmt.Errorf("failed to execute sdk request 'teo.makers.DescribePagesZoneCustomDomains': %w", err)
}
domains := make([]*tceomakersssdk.PagesZoneCustomDomain, 0)
for _, domainItem := range describeMakersZoneCustomDomainsResp.Data.Response.PagesDomains {
if lo.FromPtr(domainItem.Type) == "Custom" && lo.FromPtr(domainItem.ZoneId) != "" {
domains = append(domains, domainItem)
}
}
return domains, nil
}
func createSDKClients(secretId, secretKey, endpoint, makersApiToken string) (*wSDKClients, error) {
wsdk := &wSDKClients{}
{
credential := common.NewCredential(secretId, secretKey)
cpf := profile.NewClientProfile()
if endpoint != "" {
cpf.HttpProfile.Endpoint = endpoint
}
client, err := tceo.NewClient(credential, "", cpf)
if err != nil {
return nil, err
}
wsdk.TEO = client
}
{
client, err := tceomakersssdk.NewClient(
tceomakersssdk.WithApiToken(makersApiToken),
)
if err != nil {
return nil, err
}
wsdk.TEOMakers = client
}
return wsdk, nil
}
@@ -0,0 +1,64 @@
package tencentcloudeomakers_test
import (
"strings"
"testing"
"github.com/certimate-go/certimate/pkg/core/deployer/internal/tester"
impl "github.com/certimate-go/certimate/pkg/core/deployer/providers/tencentcloud-eomakers"
)
var (
fp = tester.Args("TENCENTCLOUDEOMAKERS_")
fTestCertPath string
fTestKeyPath string
fSecretId string
fSecretKey string
fMakersApiToken string
fMakersProjectId string
fDomains string
)
func init() {
fp.DefineString(&fTestCertPath, "TESTCERTPATH")
fp.DefineString(&fTestKeyPath, "TESTKEYPATH")
fp.DefineString(&fSecretId, "SECRETID")
fp.DefineString(&fSecretKey, "SECRETKEY")
fp.DefineString(&fMakersApiToken, "MAKERSAPITOKEN")
fp.DefineString(&fMakersProjectId, "MAKERSPROJECTID")
fp.DefineString(&fDomains, "DOMAINS")
}
/*
Shell command to run this test:
go test -v ./tencentcloud_eomakers_test.go -args \
--TENCENTCLOUDEOMAKERS_TESTCERTPATH="/path/to/your-test-cert.pem" \
--TENCENTCLOUDEOMAKERS_TESTKEYPATH="/path/to/your-test-key.pem" \
--TENCENTCLOUDEOMAKERS_SECRETID="your-secret-id" \
--TENCENTCLOUDEOMAKERS_SECRETKEY="your-secret-key" \
--TENCENTCLOUDEOMAKERS_MAKERSAPITOKEN="your-makers-api-token" \
--TENCENTCLOUDEOMAKERS_MAKERSPROJECTID="your-makers-project-id" \
--TENCENTCLOUDEOMAKERS_DOMAINS="example.com"
*/
func TestProvider(t *testing.T) {
fp.Parse()
t.Run("Deploy", func(t *testing.T) {
provider, err := impl.NewDeployer(&impl.DeployerConfig{
SecretId: fSecretId,
SecretKey: fSecretKey,
MakersApiToken: fMakersApiToken,
MakersProjectId: fMakersProjectId,
DomainMatchPattern: impl.DomainMatchPatternExact,
Domains: strings.Split(fDomains, ";"),
EnableMultipleSSL: true,
})
if err != nil {
t.Errorf("err: %+v", err)
return
}
tester.TestDeploy(t, provider, tester.TestDeployArgs{CertPath: fTestCertPath, KeyPath: fTestKeyPath})
})
}
@@ -5,6 +5,7 @@ import (
"errors"
"github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common"
tchttp "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/http"
"github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/profile"
teo "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/teo/v20220901"
)
@@ -48,6 +49,41 @@ func (c *Client) DescribeAccelerationDomainsWithContext(ctx context.Context, req
return
}
func NewDescribeHostCertificatesRequest() (request *DescribeHostCertificatesRequest) {
request = &DescribeHostCertificatesRequest{
BaseRequest: &tchttp.BaseRequest{},
}
request.Init().WithApiInfo("teo", APIVersion, "DescribeHostCertificates")
return
}
func NewDescribeHostCertificatesResponse() (response *DescribeHostCertificatesResponse) {
response = &DescribeHostCertificatesResponse{
BaseResponse: &tchttp.BaseResponse{},
}
return
}
func (c *Client) DescribeHostCertificatesWithContext(ctx context.Context, request *DescribeHostCertificatesRequest) (response *DescribeHostCertificatesResponse, err error) {
if request == nil {
request = NewDescribeHostCertificatesRequest()
}
c.InitBaseRequest(&request.BaseRequest, "teo", APIVersion, "DescribeHostCertificates")
if c.GetCredential() == nil {
return nil, errors.New("DescribeHostCertificates require credential")
}
request.SetContext(ctx)
response = NewDescribeHostCertificatesResponse()
err = c.Send(request, response)
return
}
func NewModifyHostsCertificateRequest() (request *ModifyHostsCertificateRequest) {
return teo.NewModifyHostsCertificateRequest()
}
@@ -1,19 +1,50 @@
package v20220901
import (
tchttp "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/http"
teo "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/teo/v20220901"
)
type (
AccelerationDomain = teo.AccelerationDomain
AdvancedFilter = teo.AdvancedFilter
CertificateInfo = teo.CertificateInfo
MutualTLS = teo.MutualTLS
ServerCertInfo = teo.ServerCertInfo
UpstreamCertInfo = teo.UpstreamCertInfo
)
type DescribeAccelerationDomainsRequest = teo.DescribeAccelerationDomainsRequest
type DescribeAccelerationDomainsResponse = teo.DescribeAccelerationDomainsResponse
type DescribeHostCertificatesRequest struct {
*tchttp.BaseRequest
ZoneId *string `json:"ZoneId,omitnil,omitempty" name:"ZoneId"`
Filters []*AdvancedFilter `json:"Filters,omitnil,omitempty" name:"Filters"`
}
type DescribeHostCertificatesResponse struct {
*tchttp.BaseResponse
Response *DescribeHostCertificatesResponseParams `json:"Response" name:"Response"`
}
type DescribeHostCertificatesResponseParams struct {
RequestId *string `json:"RequestId,omitnil,omitempty" name:"RequestId"`
TotalCount *int64 `json:"TotalCount,omitnil,omitempty" name:"TotalCount"`
HostCertificates []*HostCertificate `json:"HostCertificates,omitnil,omitempty" name:"HostCertificates"`
}
type ModifyHostsCertificateRequest = teo.ModifyHostsCertificateRequest
type ModifyHostsCertificateResponse = teo.ModifyHostsCertificateResponse
type HostCertificate struct {
ApplyType *string `json:"ApplyType,omitnil,omitempty" name:"ApplyType"`
ClientCertInfo *MutualTLS `json:"ClientCertInfo,omitnil,omitempty" name:"ClientCertInfo"`
Host *string `json:"Host,omitnil,omitempty" name:"Host"`
HostCertInfo []*CertificateInfo `json:"HostCertInfo,omitnil,omitempty" name:"HostCertInfo"`
Mode *string `json:"Mode,omitnil,omitempty" name:"Mode"`
ServerCertInfo []*ServerCertInfo `json:"ServerCertInfo,omitnil,omitempty" name:"ServerCertInfo"`
UpstreamCertInfo *UpstreamCertInfo `json:"UpstreamCertInfo,omitnil,omitempty" name:"UpstreamCertInfo"`
}
@@ -0,0 +1,45 @@
package teomakers
import (
"context"
"net/http"
)
type DescribePagesZoneCustomDomainsRequest struct {
sdkRequestBase
ProjectId *string `json:"ProjectId,omitempty"`
}
type DescribePagesZoneCustomDomainsResponse struct {
sdkResponseBase
Data *struct {
Response *struct {
RequestId *string `json:"RequestId,omitempty"`
TotalCount *int64 `json:"TotalCount,omitempty"`
PagesDomains []*PagesZoneCustomDomain `json:"PagesDomains,omitempty"`
} `json:"Response,omitempty"`
} `json:"Data,omitempty"`
}
func (c *Client) DescribePagesZoneCustomDomains(req *DescribePagesZoneCustomDomainsRequest) (*DescribePagesZoneCustomDomainsResponse, error) {
return c.DescribePagesZoneCustomDomainsWithContext(context.Background(), req)
}
func (c *Client) DescribePagesZoneCustomDomainsWithContext(ctx context.Context, req *DescribePagesZoneCustomDomainsRequest) (*DescribePagesZoneCustomDomainsResponse, error) {
httpreq, err := c.newRequest(http.MethodPost, "/", "DescribePagesZoneCustomDomains", req)
if err != nil {
return nil, err
} else {
httpreq.SetBody(req)
httpreq.SetContext(ctx)
}
result := &DescribePagesZoneCustomDomainsResponse{}
if _, err := c.doRequestWithResult(httpreq, result); err != nil {
return result, err
}
return result, nil
}
+109
View File
@@ -0,0 +1,109 @@
// A simple SDK client for Tencent Cloud EdgeOne Pages.
// API documentation: https://docs.edgeone.site/
package teomakers
import (
"encoding/json"
"fmt"
"time"
"github.com/go-resty/resty/v2"
"github.com/certimate-go/certimate/internal/app"
)
type Client struct {
rc *resty.Client
}
func NewClient(optFns ...OptionsFunc) (*Client, error) {
options := &Options{}
for _, fn := range optFns {
fn(options)
}
if options.ApiToken == "" {
return nil, fmt.Errorf("sdkerr: unset apiToken")
}
httper := resty.New().
SetBaseURL("https://pages-api.cloud.tencent.com/v1").
SetHeader("Accept", "application/json").
SetHeader("Authorization", "Bearer "+options.ApiToken).
SetHeader("Content-Type", "application/json").
SetHeader("User-Agent", app.AppUserAgent)
return &Client{rc: httper}, nil
}
func (c *Client) SetTimeout(timeout time.Duration) *Client {
c.rc.SetTimeout(timeout)
return c
}
func (c *Client) newRequest(method string, path string, action string, params sdkRequest) (*resty.Request, error) {
if method == "" {
return nil, fmt.Errorf("sdkerr: unset method")
}
if path == "" {
return nil, fmt.Errorf("sdkerr: unset path")
}
if action == "" {
return nil, fmt.Errorf("sdkerr: unset action")
}
req := c.rc.R()
req.Method = method
req.URL = path
if params != nil {
params.SetAction(action)
req.SetBody(params)
}
return req, nil
}
func (c *Client) doRequest(req *resty.Request) (*resty.Response, error) {
if req == nil {
return nil, fmt.Errorf("sdkerr: nil request")
}
// WARN:
// PLEASE DO NOT USE `req.SetResult` or `req.SetError` HERE! USE `doRequestWithResult` INSTEAD.
resp, err := req.Send()
if err != nil {
return resp, fmt.Errorf("sdkerr: failed to send request: %w", err)
} else if resp.IsError() {
return resp, fmt.Errorf("sdkerr: unexpected status code: %d (resp: %s)", resp.StatusCode(), resp.String())
}
return resp, nil
}
func (c *Client) doRequestWithResult(req *resty.Request, res sdkResponse) (*resty.Response, error) {
if req == nil {
return nil, fmt.Errorf("sdkerr: nil request")
}
resp, err := c.doRequest(req)
if err != nil {
if resp != nil {
json.Unmarshal(resp.Body(), &res)
}
return resp, err
}
if len(resp.Body()) != 0 {
if err := json.Unmarshal(resp.Body(), &res); err != nil {
return resp, fmt.Errorf("sdkerr: failed to unmarshal response: %w (resp: %s)", err, resp.String())
} else {
if rCode := res.GetCode(); rCode != 0 {
return resp, fmt.Errorf("sdkerr: api error: code='%d', message='%s'", rCode, res.GetMessage())
}
}
}
return resp, nil
}
@@ -0,0 +1,26 @@
package teomakers
import (
teo "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/teo/v20220901"
)
type (
OwnershipVerification = teo.OwnershipVerification
DnsVerification = teo.DnsVerification
FileVerification = teo.FileVerification
NsVerification = teo.NsVerification
)
type PagesZoneCustomDomain struct {
Type *string `json:"Type,omitempty"`
Domain *string `json:"Domain,omitempty"`
ForceRedirectHTTPS *string `json:"ForceRedirectHTTPS,omitempty"`
RedirectStatusCode *int32 `json:"RedirectStatusCode,omitempty"`
CurrentCname *string `json:"CurrentCname,omitempty"`
MainDomain *string `json:"MainDomain,omitempty"`
Status *string `json:"Status,omitempty"`
OwnershipVerification *OwnershipVerification `json:"OwnershipVerification,omitempty"`
Cname *string `json:"Cname,omitempty"`
Area *string `json:"Area,omitempty"`
ZoneId *string `json:"ZoneId,omitempty"`
}
@@ -0,0 +1,13 @@
package teomakers
type Options struct {
ApiToken string
}
type OptionsFunc func(*Options)
func WithApiToken(apiToken string) OptionsFunc {
return func(o *Options) {
o.ApiToken = apiToken
}
}
@@ -0,0 +1,44 @@
package teomakers
type sdkRequest interface {
SetAction(action string)
}
type sdkRequestBase struct {
Action *string `json:"Action,omitempty"`
}
func (r *sdkRequestBase) SetAction(action string) {
r.Action = &action
}
var _ sdkRequest = (*sdkRequestBase)(nil)
type sdkResponse interface {
GetCode() int
GetMessage() string
}
type sdkResponseBase struct {
Code *int `json:"Code,omitempty"`
Message *string `json:"Message,omitempty"`
RequestId *string `json:"RequestId,omitempty"`
}
func (r *sdkResponseBase) GetCode() int {
if r.Code == nil {
return 0
}
return *r.Code
}
func (r *sdkResponseBase) GetMessage() string {
if r.Message == nil {
return ""
}
return *r.Message
}
var _ sdkResponse = (*sdkResponseBase)(nil)