From bc025eb12e56da356e76f28af931f44201484ecd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=80=97=E5=AD=90?= Date: Fri, 29 Nov 2024 17:35:30 +0800 Subject: [PATCH 1/2] refactor: update dnspod client --- client.go | 19 ++- dnspod/client.go | 360 +++++++++++++++++++++++++++++++++++++++ dnspod/models.go | 434 +++++++++++++++++++++++++++++++++++++++++++++++ go.mod | 5 +- go.sum | 6 +- 5 files changed, 809 insertions(+), 15 deletions(-) create mode 100644 dnspod/client.go create mode 100644 dnspod/models.go diff --git a/client.go b/client.go index 90cb9ad..a266bae 100644 --- a/client.go +++ b/client.go @@ -8,10 +8,10 @@ import ( "time" "github.com/libdns/libdns" - "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common" tp "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/profile" - dnspod "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dnspod/v20210323" + + "github.com/libdns/tencentcloud/dnspod" ) // getClient gets the client for Tencent Cloud DNS @@ -38,7 +38,8 @@ func (p *Provider) describeRecordList(ctx context.Context, zone string) ([]libdn if err != nil { return nil, err } - list := []libdns.Record{} + + var list []libdns.Record request := dnspod.NewDescribeRecordListRequest() request.Domain = common.StringPtr(strings.Trim(zone, ".")) request.Offset = common.Uint64Ptr(0) @@ -46,7 +47,7 @@ func (p *Provider) describeRecordList(ctx context.Context, zone string) ([]libdn totalCount := uint64(100) for *request.Offset < totalCount { - response, err := client.DescribeRecordList(request) + response, err := client.DescribeRecordListWithContext(ctx, request) if err != nil { return nil, err } @@ -73,13 +74,15 @@ func (p *Provider) createRecord(ctx context.Context, zone string, record libdns. if err != nil { return "", err } + request := dnspod.NewCreateRecordRequest() request.Domain = common.StringPtr(strings.Trim(zone, ".")) request.SubDomain = common.StringPtr(record.Name) request.RecordType = common.StringPtr(record.Type) request.RecordLine = common.StringPtr("默认") request.Value = common.StringPtr(record.Value) - response, err := client.CreateRecord(request) + response, err := client.CreateRecordWithContext(ctx, request) + if err != nil { return "", err } @@ -92,6 +95,7 @@ func (p *Provider) modifyRecord(ctx context.Context, zone string, record libdns. if err != nil { return err } + recordId, _ := strconv.Atoi(record.ID) request := dnspod.NewModifyRecordRequest() request.Domain = common.StringPtr(strings.Trim(zone, ".")) @@ -101,7 +105,7 @@ func (p *Provider) modifyRecord(ctx context.Context, zone string, record libdns. request.Value = common.StringPtr(record.Value) request.RecordId = common.Uint64Ptr(uint64(recordId)) - _, err = client.ModifyRecord(request) + _, err = client.ModifyRecordWithContext(ctx, request) if err != nil { return err } @@ -114,12 +118,13 @@ func (p *Provider) deleteRecord(ctx context.Context, zone string, record libdns. if err != nil { return err } + recordId, _ := strconv.Atoi(record.ID) request := dnspod.NewDeleteRecordRequest() request.Domain = common.StringPtr(strings.Trim(zone, ".")) request.RecordId = common.Uint64Ptr(uint64(recordId)) - _, err = client.DeleteRecord(request) + _, err = client.DeleteRecordWithContext(ctx, request) if err != nil { return err } diff --git a/dnspod/client.go b/dnspod/client.go new file mode 100644 index 0000000..45aab8d --- /dev/null +++ b/dnspod/client.go @@ -0,0 +1,360 @@ +// Copyright (c) 2017-2018 THL A29 Limited, a Tencent company. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package dnspod + +import ( + "context" + "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" +) + +const APIVersion = "2021-03-23" + +type Client struct { + common.Client +} + +func NewClient(credential common.CredentialIface, region string, clientProfile *profile.ClientProfile) (client *Client, err error) { + client = &Client{} + client.Init(region). + WithCredential(credential). + WithProfile(clientProfile) + return +} + +func NewCreateRecordRequest() (request *CreateRecordRequest) { + request = &CreateRecordRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + + request.Init().WithApiInfo("dnspod", APIVersion, "CreateRecord") + + return +} + +func NewCreateRecordResponse() (response *CreateRecordResponse) { + response = &CreateRecordResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return + +} + +// CreateRecordWithContext +// 添加记录 +// +// 备注:新添加的解析记录存在短暂的索引延迟,如果查询不到新增记录,请在 30 秒后重试 +// +// 可能返回的错误码: +// +// FAILEDOPERATION = "FailedOperation" +// FAILEDOPERATION_DNSSECINCOMPLETECLOSED = "FailedOperation.DNSSECIncompleteClosed" +// FAILEDOPERATION_DOMAINISLOCKED = "FailedOperation.DomainIsLocked" +// FAILEDOPERATION_DOMAINISSPAM = "FailedOperation.DomainIsSpam" +// FAILEDOPERATION_LOGINAREANOTALLOWED = "FailedOperation.LoginAreaNotAllowed" +// FAILEDOPERATION_LOGINFAILED = "FailedOperation.LoginFailed" +// FAILEDOPERATION_MUSTADDDEFAULTLINEFIRST = "FailedOperation.MustAddDefaultLineFirst" +// FAILEDOPERATION_UNKNOWERROR = "FailedOperation.UnknowError" +// INVALIDPARAMETER_ACCOUNTISBANNED = "InvalidParameter.AccountIsBanned" +// INVALIDPARAMETER_CUSTOMMESSAGE = "InvalidParameter.CustomMessage" +// INVALIDPARAMETER_DNSSECADDCNAMEERROR = "InvalidParameter.DnssecAddCnameError" +// INVALIDPARAMETER_DOMAINIDINVALID = "InvalidParameter.DomainIdInvalid" +// INVALIDPARAMETER_DOMAININVALID = "InvalidParameter.DomainInvalid" +// INVALIDPARAMETER_DOMAINISALIASER = "InvalidParameter.DomainIsAliaser" +// INVALIDPARAMETER_DOMAINNOTALLOWEDMODIFYRECORDS = "InvalidParameter.DomainNotAllowedModifyRecords" +// INVALIDPARAMETER_DOMAINNOTBEIAN = "InvalidParameter.DomainNotBeian" +// INVALIDPARAMETER_DOMAINRECORDEXIST = "InvalidParameter.DomainRecordExist" +// INVALIDPARAMETER_EMAILNOTVERIFIED = "InvalidParameter.EmailNotVerified" +// INVALIDPARAMETER_INVALIDWEIGHT = "InvalidParameter.InvalidWeight" +// INVALIDPARAMETER_LOGINTOKENIDERROR = "InvalidParameter.LoginTokenIdError" +// INVALIDPARAMETER_LOGINTOKENNOTEXISTS = "InvalidParameter.LoginTokenNotExists" +// INVALIDPARAMETER_LOGINTOKENVALIDATEFAILED = "InvalidParameter.LoginTokenValidateFailed" +// INVALIDPARAMETER_MOBILENOTVERIFIED = "InvalidParameter.MobileNotVerified" +// INVALIDPARAMETER_MXINVALID = "InvalidParameter.MxInvalid" +// INVALIDPARAMETER_RECORDLINEINVALID = "InvalidParameter.RecordLineInvalid" +// INVALIDPARAMETER_RECORDTYPEINVALID = "InvalidParameter.RecordTypeInvalid" +// INVALIDPARAMETER_RECORDVALUEINVALID = "InvalidParameter.RecordValueInvalid" +// INVALIDPARAMETER_RECORDVALUELENGTHINVALID = "InvalidParameter.RecordValueLengthInvalid" +// INVALIDPARAMETER_REQUESTIPLIMITED = "InvalidParameter.RequestIpLimited" +// INVALIDPARAMETER_SUBDOMAININVALID = "InvalidParameter.SubdomainInvalid" +// INVALIDPARAMETER_UNREALNAMEUSER = "InvalidParameter.UnrealNameUser" +// INVALIDPARAMETER_URLVALUEILLEGAL = "InvalidParameter.UrlValueIllegal" +// INVALIDPARAMETER_USERNOTEXISTS = "InvalidParameter.UserNotExists" +// INVALIDPARAMETERVALUE_DOMAINNOTEXISTS = "InvalidParameterValue.DomainNotExists" +// INVALIDPARAMETERVALUE_USERIDINVALID = "InvalidParameterValue.UserIdInvalid" +// LIMITEXCEEDED_AAAACOUNTLIMIT = "LimitExceeded.AAAACountLimit" +// LIMITEXCEEDED_ATNSRECORDLIMIT = "LimitExceeded.AtNsRecordLimit" +// LIMITEXCEEDED_FAILEDLOGINLIMITEXCEEDED = "LimitExceeded.FailedLoginLimitExceeded" +// LIMITEXCEEDED_HIDDENURLEXCEEDED = "LimitExceeded.HiddenUrlExceeded" +// LIMITEXCEEDED_NSCOUNTLIMIT = "LimitExceeded.NsCountLimit" +// LIMITEXCEEDED_RECORDTTLLIMIT = "LimitExceeded.RecordTtlLimit" +// LIMITEXCEEDED_SRVCOUNTLIMIT = "LimitExceeded.SrvCountLimit" +// LIMITEXCEEDED_SUBDOMAINLEVELLIMIT = "LimitExceeded.SubdomainLevelLimit" +// LIMITEXCEEDED_SUBDOMAINROLLLIMIT = "LimitExceeded.SubdomainRollLimit" +// LIMITEXCEEDED_SUBDOMAINWCARDLIMIT = "LimitExceeded.SubdomainWcardLimit" +// LIMITEXCEEDED_URLCOUNTLIMIT = "LimitExceeded.UrlCountLimit" +// OPERATIONDENIED_DOMAINOWNERALLOWEDONLY = "OperationDenied.DomainOwnerAllowedOnly" +// OPERATIONDENIED_IPINBLACKLISTNOTALLOWED = "OperationDenied.IPInBlacklistNotAllowed" +// OPERATIONDENIED_NOPERMISSIONTOOPERATEDOMAIN = "OperationDenied.NoPermissionToOperateDomain" +// OPERATIONDENIED_NOTADMIN = "OperationDenied.NotAdmin" +// OPERATIONDENIED_NOTAGENT = "OperationDenied.NotAgent" +// OPERATIONDENIED_NOTMANAGEDUSER = "OperationDenied.NotManagedUser" +// REQUESTLIMITEXCEEDED_REQUESTLIMITEXCEEDED = "RequestLimitExceeded.RequestLimitExceeded" +func (c *Client) CreateRecordWithContext(ctx context.Context, request *CreateRecordRequest) (response *CreateRecordResponse, err error) { + if request == nil { + request = NewCreateRecordRequest() + } + + if c.GetCredential() == nil { + return nil, errors.New("CreateRecord require credential") + } + + request.SetContext(ctx) + + response = NewCreateRecordResponse() + err = c.Send(request, response) + return +} + +func NewDescribeRecordListRequest() (request *DescribeRecordListRequest) { + request = &DescribeRecordListRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + + request.Init().WithApiInfo("dnspod", APIVersion, "DescribeRecordList") + + return +} + +func NewDescribeRecordListResponse() (response *DescribeRecordListResponse) { + response = &DescribeRecordListResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return + +} + +// DescribeRecordListWithContext +// 获取某个域名下的解析记录列表 +// +// 备注: +// +// 1. 新添加的解析记录存在短暂的索引延迟,如果查询不到新增记录,请在 30 秒后重试 +// +// 2. API获取的记录总条数会比控制台多2条,原因是: 为了防止用户误操作导致解析服务不可用,对2021-10-29 14:24:26之后添加的域名,在控制台都不显示这2条NS记录。 +// +// 可能返回的错误码: +// +// AUTHFAILURE = "AuthFailure" +// FAILEDOPERATION = "FailedOperation" +// FAILEDOPERATION_NOTDOMAINOWNER = "FailedOperation.NotDomainOwner" +// FAILEDOPERATION_NOTREALNAMEDUSER = "FailedOperation.NotRealNamedUser" +// FAILEDOPERATION_UNKNOWERROR = "FailedOperation.UnknowError" +// INTERNALERROR = "InternalError" +// INVALIDPARAMETER = "InvalidParameter" +// INVALIDPARAMETER_DOMAINIDINVALID = "InvalidParameter.DomainIdInvalid" +// INVALIDPARAMETER_DOMAININVALID = "InvalidParameter.DomainInvalid" +// INVALIDPARAMETER_DOMAINISALIASER = "InvalidParameter.DomainIsAliaser" +// INVALIDPARAMETER_OPERATEFAILED = "InvalidParameter.OperateFailed" +// INVALIDPARAMETER_PARAMINVALID = "InvalidParameter.ParamInvalid" +// INVALIDPARAMETER_RECORDLINEINVALID = "InvalidParameter.RecordLineInvalid" +// INVALIDPARAMETER_RECORDTYPEINVALID = "InvalidParameter.RecordTypeInvalid" +// INVALIDPARAMETER_RESULTMORETHAN500 = "InvalidParameter.ResultMoreThan500" +// INVALIDPARAMETERVALUE_DOMAINNOTEXISTS = "InvalidParameterValue.DomainNotExists" +// INVALIDPARAMETERVALUE_LIMITINVALID = "InvalidParameterValue.LimitInvalid" +// OPERATIONDENIED_NOPERMISSIONTOOPERATEDOMAIN = "OperationDenied.NoPermissionToOperateDomain" +// REQUESTLIMITEXCEEDED = "RequestLimitExceeded" +// REQUESTLIMITEXCEEDED_REQUESTLIMITEXCEEDED = "RequestLimitExceeded.RequestLimitExceeded" +// RESOURCENOTFOUND_NODATAOFRECORD = "ResourceNotFound.NoDataOfRecord" +// UNAUTHORIZEDOPERATION = "UnauthorizedOperation" +func (c *Client) DescribeRecordListWithContext(ctx context.Context, request *DescribeRecordListRequest) (response *DescribeRecordListResponse, err error) { + if request == nil { + request = NewDescribeRecordListRequest() + } + + if c.GetCredential() == nil { + return nil, errors.New("DescribeRecordList require credential") + } + + request.SetContext(ctx) + + response = NewDescribeRecordListResponse() + err = c.Send(request, response) + return +} + +func NewModifyRecordRequest() (request *ModifyRecordRequest) { + request = &ModifyRecordRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + + request.Init().WithApiInfo("dnspod", APIVersion, "ModifyRecord") + + return +} + +func NewModifyRecordResponse() (response *ModifyRecordResponse) { + response = &ModifyRecordResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return + +} + +// ModifyRecordWithContext +// 修改记录 +// +// 可能返回的错误码: +// +// FAILEDOPERATION = "FailedOperation" +// FAILEDOPERATION_DNSSECINCOMPLETECLOSED = "FailedOperation.DNSSECIncompleteClosed" +// FAILEDOPERATION_DOMAINISLOCKED = "FailedOperation.DomainIsLocked" +// FAILEDOPERATION_DOMAINISSPAM = "FailedOperation.DomainIsSpam" +// FAILEDOPERATION_FREQUENCYLIMIT = "FailedOperation.FrequencyLimit" +// FAILEDOPERATION_LOGINAREANOTALLOWED = "FailedOperation.LoginAreaNotAllowed" +// FAILEDOPERATION_LOGINFAILED = "FailedOperation.LoginFailed" +// FAILEDOPERATION_MUSTADDDEFAULTLINEFIRST = "FailedOperation.MustAddDefaultLineFirst" +// FAILEDOPERATION_UNKNOWERROR = "FailedOperation.UnknowError" +// INVALIDPARAMETER_ACCOUNTISBANNED = "InvalidParameter.AccountIsBanned" +// INVALIDPARAMETER_CUSTOMMESSAGE = "InvalidParameter.CustomMessage" +// INVALIDPARAMETER_DNSSECADDCNAMEERROR = "InvalidParameter.DnssecAddCnameError" +// INVALIDPARAMETER_DOMAINIDINVALID = "InvalidParameter.DomainIdInvalid" +// INVALIDPARAMETER_DOMAININVALID = "InvalidParameter.DomainInvalid" +// INVALIDPARAMETER_DOMAINISALIASER = "InvalidParameter.DomainIsAliaser" +// INVALIDPARAMETER_DOMAINNOTALLOWEDMODIFYRECORDS = "InvalidParameter.DomainNotAllowedModifyRecords" +// INVALIDPARAMETER_DOMAINNOTBEIAN = "InvalidParameter.DomainNotBeian" +// INVALIDPARAMETER_DOMAINRECORDEXIST = "InvalidParameter.DomainRecordExist" +// INVALIDPARAMETER_EMAILNOTVERIFIED = "InvalidParameter.EmailNotVerified" +// INVALIDPARAMETER_INVALIDWEIGHT = "InvalidParameter.InvalidWeight" +// INVALIDPARAMETER_LOGINTOKENIDERROR = "InvalidParameter.LoginTokenIdError" +// INVALIDPARAMETER_LOGINTOKENNOTEXISTS = "InvalidParameter.LoginTokenNotExists" +// INVALIDPARAMETER_LOGINTOKENVALIDATEFAILED = "InvalidParameter.LoginTokenValidateFailed" +// INVALIDPARAMETER_MOBILENOTVERIFIED = "InvalidParameter.MobileNotVerified" +// INVALIDPARAMETER_MXINVALID = "InvalidParameter.MxInvalid" +// INVALIDPARAMETER_OPERATEFAILED = "InvalidParameter.OperateFailed" +// INVALIDPARAMETER_RECORDIDINVALID = "InvalidParameter.RecordIdInvalid" +// INVALIDPARAMETER_RECORDLINEINVALID = "InvalidParameter.RecordLineInvalid" +// INVALIDPARAMETER_RECORDTYPEINVALID = "InvalidParameter.RecordTypeInvalid" +// INVALIDPARAMETER_RECORDVALUEINVALID = "InvalidParameter.RecordValueInvalid" +// INVALIDPARAMETER_RECORDVALUELENGTHINVALID = "InvalidParameter.RecordValueLengthInvalid" +// INVALIDPARAMETER_REQUESTIPLIMITED = "InvalidParameter.RequestIpLimited" +// INVALIDPARAMETER_SUBDOMAININVALID = "InvalidParameter.SubdomainInvalid" +// INVALIDPARAMETER_UNREALNAMEUSER = "InvalidParameter.UnrealNameUser" +// INVALIDPARAMETER_URLVALUEILLEGAL = "InvalidParameter.UrlValueIllegal" +// INVALIDPARAMETER_USERNOTEXISTS = "InvalidParameter.UserNotExists" +// INVALIDPARAMETERVALUE_DOMAINNOTEXISTS = "InvalidParameterValue.DomainNotExists" +// INVALIDPARAMETERVALUE_USERIDINVALID = "InvalidParameterValue.UserIdInvalid" +// LIMITEXCEEDED_AAAACOUNTLIMIT = "LimitExceeded.AAAACountLimit" +// LIMITEXCEEDED_ATNSRECORDLIMIT = "LimitExceeded.AtNsRecordLimit" +// LIMITEXCEEDED_FAILEDLOGINLIMITEXCEEDED = "LimitExceeded.FailedLoginLimitExceeded" +// LIMITEXCEEDED_HIDDENURLEXCEEDED = "LimitExceeded.HiddenUrlExceeded" +// LIMITEXCEEDED_NSCOUNTLIMIT = "LimitExceeded.NsCountLimit" +// LIMITEXCEEDED_RECORDTTLLIMIT = "LimitExceeded.RecordTtlLimit" +// LIMITEXCEEDED_SRVCOUNTLIMIT = "LimitExceeded.SrvCountLimit" +// LIMITEXCEEDED_SUBDOMAINLEVELLIMIT = "LimitExceeded.SubdomainLevelLimit" +// LIMITEXCEEDED_SUBDOMAINROLLLIMIT = "LimitExceeded.SubdomainRollLimit" +// LIMITEXCEEDED_SUBDOMAINWCARDLIMIT = "LimitExceeded.SubdomainWcardLimit" +// LIMITEXCEEDED_URLCOUNTLIMIT = "LimitExceeded.UrlCountLimit" +// OPERATIONDENIED_DOMAINOWNERALLOWEDONLY = "OperationDenied.DomainOwnerAllowedOnly" +// OPERATIONDENIED_IPINBLACKLISTNOTALLOWED = "OperationDenied.IPInBlacklistNotAllowed" +// OPERATIONDENIED_NOPERMISSIONTOOPERATEDOMAIN = "OperationDenied.NoPermissionToOperateDomain" +// OPERATIONDENIED_NOTADMIN = "OperationDenied.NotAdmin" +// OPERATIONDENIED_NOTAGENT = "OperationDenied.NotAgent" +// OPERATIONDENIED_NOTMANAGEDUSER = "OperationDenied.NotManagedUser" +// REQUESTLIMITEXCEEDED_REQUESTLIMITEXCEEDED = "RequestLimitExceeded.RequestLimitExceeded" +func (c *Client) ModifyRecordWithContext(ctx context.Context, request *ModifyRecordRequest) (response *ModifyRecordResponse, err error) { + if request == nil { + request = NewModifyRecordRequest() + } + + if c.GetCredential() == nil { + return nil, errors.New("ModifyRecord require credential") + } + + request.SetContext(ctx) + + response = NewModifyRecordResponse() + err = c.Send(request, response) + return +} + +func NewDeleteRecordRequest() (request *DeleteRecordRequest) { + request = &DeleteRecordRequest{ + BaseRequest: &tchttp.BaseRequest{}, + } + + request.Init().WithApiInfo("dnspod", APIVersion, "DeleteRecord") + + return +} + +func NewDeleteRecordResponse() (response *DeleteRecordResponse) { + response = &DeleteRecordResponse{ + BaseResponse: &tchttp.BaseResponse{}, + } + return + +} + +// DeleteRecordWithContext +// 删除记录 +// +// 可能返回的错误码: +// +// FAILEDOPERATION = "FailedOperation" +// FAILEDOPERATION_DOMAINISLOCKED = "FailedOperation.DomainIsLocked" +// FAILEDOPERATION_DOMAINISSPAM = "FailedOperation.DomainIsSpam" +// FAILEDOPERATION_FREQUENCYLIMIT = "FailedOperation.FrequencyLimit" +// FAILEDOPERATION_LOGINAREANOTALLOWED = "FailedOperation.LoginAreaNotAllowed" +// FAILEDOPERATION_LOGINFAILED = "FailedOperation.LoginFailed" +// FAILEDOPERATION_UNKNOWERROR = "FailedOperation.UnknowError" +// INVALIDPARAMETER_DOMAINIDINVALID = "InvalidParameter.DomainIdInvalid" +// INVALIDPARAMETER_DOMAININVALID = "InvalidParameter.DomainInvalid" +// INVALIDPARAMETER_DOMAINISALIASER = "InvalidParameter.DomainIsAliaser" +// INVALIDPARAMETER_DOMAINNOTALLOWEDMODIFYRECORDS = "InvalidParameter.DomainNotAllowedModifyRecords" +// INVALIDPARAMETER_LOGINTOKENIDERROR = "InvalidParameter.LoginTokenIdError" +// INVALIDPARAMETER_LOGINTOKENNOTEXISTS = "InvalidParameter.LoginTokenNotExists" +// INVALIDPARAMETER_LOGINTOKENVALIDATEFAILED = "InvalidParameter.LoginTokenValidateFailed" +// INVALIDPARAMETER_OPERATEFAILED = "InvalidParameter.OperateFailed" +// INVALIDPARAMETER_RECORDIDINVALID = "InvalidParameter.RecordIdInvalid" +// INVALIDPARAMETER_REQUESTIPLIMITED = "InvalidParameter.RequestIpLimited" +// INVALIDPARAMETER_UNREALNAMEUSER = "InvalidParameter.UnrealNameUser" +// INVALIDPARAMETER_USERNOTEXISTS = "InvalidParameter.UserNotExists" +// INVALIDPARAMETERVALUE_DOMAINNOTEXISTS = "InvalidParameterValue.DomainNotExists" +// INVALIDPARAMETERVALUE_USERIDINVALID = "InvalidParameterValue.UserIdInvalid" +// LIMITEXCEEDED_FAILEDLOGINLIMITEXCEEDED = "LimitExceeded.FailedLoginLimitExceeded" +// OPERATIONDENIED_DOMAINOWNERALLOWEDONLY = "OperationDenied.DomainOwnerAllowedOnly" +// OPERATIONDENIED_NOPERMISSIONTOOPERATEDOMAIN = "OperationDenied.NoPermissionToOperateDomain" +// OPERATIONDENIED_NOTADMIN = "OperationDenied.NotAdmin" +// OPERATIONDENIED_NOTAGENT = "OperationDenied.NotAgent" +// OPERATIONDENIED_NOTMANAGEDUSER = "OperationDenied.NotManagedUser" +// REQUESTLIMITEXCEEDED_REQUESTLIMITEXCEEDED = "RequestLimitExceeded.RequestLimitExceeded" +func (c *Client) DeleteRecordWithContext(ctx context.Context, request *DeleteRecordRequest) (response *DeleteRecordResponse, err error) { + if request == nil { + request = NewDeleteRecordRequest() + } + + if c.GetCredential() == nil { + return nil, errors.New("DeleteRecord require credential") + } + + request.SetContext(ctx) + + response = NewDeleteRecordResponse() + err = c.Send(request, response) + return +} diff --git a/dnspod/models.go b/dnspod/models.go new file mode 100644 index 0000000..ca6e8c7 --- /dev/null +++ b/dnspod/models.go @@ -0,0 +1,434 @@ +// Copyright (c) 2017-2018 THL A29 Limited, a Tencent company. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package dnspod + +import ( + tcerr "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/errors" + tchttp "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/http" + "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/json" +) + +type CreateRecordRequest struct { + *tchttp.BaseRequest + + // 域名 + Domain *string `json:"Domain,omitnil,omitempty" name:"Domain"` + + // 记录类型,通过 API 记录类型获得,大写英文,比如:A 。 + RecordType *string `json:"RecordType,omitnil,omitempty" name:"RecordType"` + + // 记录线路,通过 API 记录线路获得,中文,比如:默认。 + RecordLine *string `json:"RecordLine,omitnil,omitempty" name:"RecordLine"` + + // 记录值,如 IP : 200.200.200.200, CNAME : cname.dnspod.com., MX : mail.dnspod.com.。 + Value *string `json:"Value,omitnil,omitempty" name:"Value"` + + // 域名 ID 。参数 DomainId 优先级比参数 Domain 高,如果传递参数 DomainId 将忽略参数 Domain 。 + DomainId *uint64 `json:"DomainId,omitnil,omitempty" name:"DomainId"` + + // 主机记录,如 www,如果不传,默认为 @。 + SubDomain *string `json:"SubDomain,omitnil,omitempty" name:"SubDomain"` + + // 线路的 ID,通过 API 记录线路获得,英文字符串,比如:10=1。参数RecordLineId优先级高于RecordLine,如果同时传递二者,优先使用RecordLineId参数。 + RecordLineId *string `json:"RecordLineId,omitnil,omitempty" name:"RecordLineId"` + + // MX 优先级,当记录类型是 MX 时有效,范围1-20,MX 记录时必选。 + MX *uint64 `json:"MX,omitnil,omitempty" name:"MX"` + + // TTL,范围1-604800,不同套餐域名最小值不同。 + TTL *uint64 `json:"TTL,omitnil,omitempty" name:"TTL"` + + // 权重信息,0到100的整数。0 表示关闭,不传该参数,表示不设置权重信息。 + Weight *uint64 `json:"Weight,omitnil,omitempty" name:"Weight"` + + // 记录初始状态,取值范围为 ENABLE 和 DISABLE 。默认为 ENABLE ,如果传入 DISABLE,解析不会生效,也不会验证负载均衡的限制。 + Status *string `json:"Status,omitnil,omitempty" name:"Status"` + + // 备注 + Remark *string `json:"Remark,omitnil,omitempty" name:"Remark"` + + // 开启DNSSEC时,强制添加CNAME/URL记录 + DnssecConflictMode *string `json:"DnssecConflictMode,omitnil,omitempty" name:"DnssecConflictMode"` + + // 记录分组 Id。可以通过接口 DescribeRecordGroupList 接口 GroupId 字段获取。 + GroupId *uint64 `json:"GroupId,omitnil,omitempty" name:"GroupId"` +} + +func (r *CreateRecordRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +// FromJsonString It is highly **NOT** recommended to use this function +// because it has no param check, nor strict type check +func (r *CreateRecordRequest) FromJsonString(s string) error { + f := make(map[string]interface{}) + if err := json.Unmarshal([]byte(s), &f); err != nil { + return err + } + delete(f, "Domain") + delete(f, "RecordType") + delete(f, "RecordLine") + delete(f, "Value") + delete(f, "DomainId") + delete(f, "SubDomain") + delete(f, "RecordLineId") + delete(f, "MX") + delete(f, "TTL") + delete(f, "Weight") + delete(f, "Status") + delete(f, "Remark") + delete(f, "DnssecConflictMode") + delete(f, "GroupId") + if len(f) > 0 { + return tcerr.NewTencentCloudSDKError("ClientError.BuildRequestError", "CreateRecordRequest has unknown keys!", "") + } + return json.Unmarshal([]byte(s), &r) +} + +type CreateRecordResponseParams struct { + // 记录ID + RecordId *uint64 `json:"RecordId,omitnil,omitempty" name:"RecordId"` + + // 唯一请求 ID,由服务端生成,每次请求都会返回(若请求因其他原因未能抵达服务端,则该次请求不会获得 RequestId)。定位问题时需要提供该次请求的 RequestId。 + RequestId *string `json:"RequestId,omitnil,omitempty" name:"RequestId"` +} + +type CreateRecordResponse struct { + *tchttp.BaseResponse + Response *CreateRecordResponseParams `json:"Response"` +} + +func (r *CreateRecordResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +// FromJsonString It is highly **NOT** recommended to use this function +// because it has no param check, nor strict type check +func (r *CreateRecordResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DescribeRecordListRequest struct { + *tchttp.BaseRequest + + // 要获取的解析记录所属的域名 + Domain *string `json:"Domain,omitnil,omitempty" name:"Domain"` + + // 要获取的解析记录所属的域名Id,如果传了DomainId,系统将会忽略Domain参数。 可以通过接口DescribeDomainList查到所有的Domain以及DomainId + DomainId *uint64 `json:"DomainId,omitnil,omitempty" name:"DomainId"` + + // 解析记录的主机头,如果传了此参数,则只会返回此主机头对应的解析记录 + Subdomain *string `json:"Subdomain,omitnil,omitempty" name:"Subdomain"` + + // 获取某种类型的解析记录,如 A,CNAME,NS,AAAA,显性URL,隐性URL,CAA,SPF等 + RecordType *string `json:"RecordType,omitnil,omitempty" name:"RecordType"` + + // 获取某条线路名称的解析记录。可以通过接口DescribeRecordLineList查看当前域名允许的线路信息 + RecordLine *string `json:"RecordLine,omitnil,omitempty" name:"RecordLine"` + + // 获取某个线路Id对应的解析记录,如果传RecordLineId,系统会忽略RecordLine参数。可以通过接口DescribeRecordLineList查看当前域名允许的线路信息 + RecordLineId *string `json:"RecordLineId,omitnil,omitempty" name:"RecordLineId"` + + // 获取某个分组下的解析记录时,传这个分组Id。 + GroupId *uint64 `json:"GroupId,omitnil,omitempty" name:"GroupId"` + + // 通过关键字搜索解析记录,当前支持搜索主机头和记录值 + Keyword *string `json:"Keyword,omitnil,omitempty" name:"Keyword"` + + // 排序字段,支持 name,line,type,value,weight,mx,ttl,updated_on 几个字段。 + SortField *string `json:"SortField,omitnil,omitempty" name:"SortField"` + + // 排序方式,正序:ASC,逆序:DESC。默认值为ASC。 + SortType *string `json:"SortType,omitnil,omitempty" name:"SortType"` + + // 偏移量,默认值为0。 + Offset *uint64 `json:"Offset,omitnil,omitempty" name:"Offset"` + + // 限制数量,当前Limit最大支持3000。默认值为100。 + Limit *uint64 `json:"Limit,omitnil,omitempty" name:"Limit"` +} + +func (r *DescribeRecordListRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +// FromJsonString It is highly **NOT** recommended to use this function +// because it has no param check, nor strict type check +func (r *DescribeRecordListRequest) FromJsonString(s string) error { + f := make(map[string]interface{}) + if err := json.Unmarshal([]byte(s), &f); err != nil { + return err + } + delete(f, "Domain") + delete(f, "DomainId") + delete(f, "Subdomain") + delete(f, "RecordType") + delete(f, "RecordLine") + delete(f, "RecordLineId") + delete(f, "GroupId") + delete(f, "Keyword") + delete(f, "SortField") + delete(f, "SortType") + delete(f, "Offset") + delete(f, "Limit") + if len(f) > 0 { + return tcerr.NewTencentCloudSDKError("ClientError.BuildRequestError", "DescribeRecordListRequest has unknown keys!", "") + } + return json.Unmarshal([]byte(s), &r) +} + +type DescribeRecordListResponseParams struct { + // 记录的数量统计信息 + RecordCountInfo *RecordCountInfo `json:"RecordCountInfo,omitnil,omitempty" name:"RecordCountInfo"` + + // 获取的记录列表 + RecordList []*RecordListItem `json:"RecordList,omitnil,omitempty" name:"RecordList"` + + // 唯一请求 ID,由服务端生成,每次请求都会返回(若请求因其他原因未能抵达服务端,则该次请求不会获得 RequestId)。定位问题时需要提供该次请求的 RequestId。 + RequestId *string `json:"RequestId,omitnil,omitempty" name:"RequestId"` +} + +type DescribeRecordListResponse struct { + *tchttp.BaseResponse + Response *DescribeRecordListResponseParams `json:"Response"` +} + +func (r *DescribeRecordListResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +// FromJsonString It is highly **NOT** recommended to use this function +// because it has no param check, nor strict type check +func (r *DescribeRecordListResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type ModifyRecordRequest struct { + *tchttp.BaseRequest + + // 域名 + Domain *string `json:"Domain,omitnil,omitempty" name:"Domain"` + + // 记录类型,通过 API 记录类型获得,大写英文,比如:A 。 + RecordType *string `json:"RecordType,omitnil,omitempty" name:"RecordType"` + + // 记录线路,通过 API 记录线路获得,中文,比如:默认。 + RecordLine *string `json:"RecordLine,omitnil,omitempty" name:"RecordLine"` + + // 记录值,如 IP : 200.200.200.200, CNAME : cname.dnspod.com., MX : mail.dnspod.com.。 + Value *string `json:"Value,omitnil,omitempty" name:"Value"` + + // 记录 ID 。可以通过接口DescribeRecordList查到所有的解析记录列表以及对应的RecordId + RecordId *uint64 `json:"RecordId,omitnil,omitempty" name:"RecordId"` + + // 域名 ID 。参数 DomainId 优先级比参数 Domain 高,如果传递参数 DomainId 将忽略参数 Domain 。可以通过接口DescribeDomainList查到所有的Domain以及DomainId + DomainId *uint64 `json:"DomainId,omitnil,omitempty" name:"DomainId"` + + // 主机记录,如 www,如果不传,默认为 @。 + SubDomain *string `json:"SubDomain,omitnil,omitempty" name:"SubDomain"` + + // 线路的 ID,通过 API 记录线路获得,英文字符串,比如:10=1。参数RecordLineId优先级高于RecordLine,如果同时传递二者,优先使用RecordLineId参数。 + RecordLineId *string `json:"RecordLineId,omitnil,omitempty" name:"RecordLineId"` + + // MX 优先级,当记录类型是 MX 时有效,范围1-20,MX 记录时必选。 + MX *uint64 `json:"MX,omitnil,omitempty" name:"MX"` + + // TTL,范围1-604800,不同等级域名最小值不同。 + TTL *uint64 `json:"TTL,omitnil,omitempty" name:"TTL"` + + // 权重信息,0到100的整数。0 表示关闭,不传该参数,表示不设置权重信息。 + Weight *uint64 `json:"Weight,omitnil,omitempty" name:"Weight"` + + // 记录初始状态,取值范围为 ENABLE 和 DISABLE 。默认为 ENABLE ,如果传入 DISABLE,解析不会生效,也不会验证负载均衡的限制。 + Status *string `json:"Status,omitnil,omitempty" name:"Status"` + + // 记录的备注信息。传空删除备注。 + Remark *string `json:"Remark,omitnil,omitempty" name:"Remark"` + + // 开启DNSSEC时,强制将其它记录修改为CNAME/URL记录 + DnssecConflictMode *string `json:"DnssecConflictMode,omitnil,omitempty" name:"DnssecConflictMode"` +} + +func (r *ModifyRecordRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +// FromJsonString It is highly **NOT** recommended to use this function +// because it has no param check, nor strict type check +func (r *ModifyRecordRequest) FromJsonString(s string) error { + f := make(map[string]interface{}) + if err := json.Unmarshal([]byte(s), &f); err != nil { + return err + } + delete(f, "Domain") + delete(f, "RecordType") + delete(f, "RecordLine") + delete(f, "Value") + delete(f, "RecordId") + delete(f, "DomainId") + delete(f, "SubDomain") + delete(f, "RecordLineId") + delete(f, "MX") + delete(f, "TTL") + delete(f, "Weight") + delete(f, "Status") + delete(f, "Remark") + delete(f, "DnssecConflictMode") + if len(f) > 0 { + return tcerr.NewTencentCloudSDKError("ClientError.BuildRequestError", "ModifyRecordRequest has unknown keys!", "") + } + return json.Unmarshal([]byte(s), &r) +} + +type ModifyRecordResponseParams struct { + // 记录ID + RecordId *uint64 `json:"RecordId,omitnil,omitempty" name:"RecordId"` + + // 唯一请求 ID,由服务端生成,每次请求都会返回(若请求因其他原因未能抵达服务端,则该次请求不会获得 RequestId)。定位问题时需要提供该次请求的 RequestId。 + RequestId *string `json:"RequestId,omitnil,omitempty" name:"RequestId"` +} + +type ModifyRecordResponse struct { + *tchttp.BaseResponse + Response *ModifyRecordResponseParams `json:"Response"` +} + +func (r *ModifyRecordResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +// FromJsonString It is highly **NOT** recommended to use this function +// because it has no param check, nor strict type check +func (r *ModifyRecordResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type DeleteRecordRequest struct { + *tchttp.BaseRequest + + // 域名 + Domain *string `json:"Domain,omitnil,omitempty" name:"Domain"` + + // 记录 ID 。可以通过接口DescribeRecordList查到所有的解析记录列表以及对应的RecordId + RecordId *uint64 `json:"RecordId,omitnil,omitempty" name:"RecordId"` + + // 域名 ID 。参数 DomainId 优先级比参数 Domain 高,如果传递参数 DomainId 将忽略参数 Domain 。可以通过接口DescribeDomainList查到所有的Domain以及DomainId + DomainId *uint64 `json:"DomainId,omitnil,omitempty" name:"DomainId"` +} + +func (r *DeleteRecordRequest) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +// FromJsonString It is highly **NOT** recommended to use this function +// because it has no param check, nor strict type check +func (r *DeleteRecordRequest) FromJsonString(s string) error { + f := make(map[string]interface{}) + if err := json.Unmarshal([]byte(s), &f); err != nil { + return err + } + delete(f, "Domain") + delete(f, "RecordId") + delete(f, "DomainId") + if len(f) > 0 { + return tcerr.NewTencentCloudSDKError("ClientError.BuildRequestError", "DeleteRecordRequest has unknown keys!", "") + } + return json.Unmarshal([]byte(s), &r) +} + +type DeleteRecordResponseParams struct { + // 唯一请求 ID,由服务端生成,每次请求都会返回(若请求因其他原因未能抵达服务端,则该次请求不会获得 RequestId)。定位问题时需要提供该次请求的 RequestId。 + RequestId *string `json:"RequestId,omitnil,omitempty" name:"RequestId"` +} + +type DeleteRecordResponse struct { + *tchttp.BaseResponse + Response *DeleteRecordResponseParams `json:"Response"` +} + +func (r *DeleteRecordResponse) ToJsonString() string { + b, _ := json.Marshal(r) + return string(b) +} + +// FromJsonString It is highly **NOT** recommended to use this function +// because it has no param check, nor strict type check +func (r *DeleteRecordResponse) FromJsonString(s string) error { + return json.Unmarshal([]byte(s), &r) +} + +type RecordCountInfo struct { + // 子域名数量 + SubdomainCount *uint64 `json:"SubdomainCount,omitnil,omitempty" name:"SubdomainCount"` + + // 列表返回的记录数 + ListCount *uint64 `json:"ListCount,omitnil,omitempty" name:"ListCount"` + + // 总的记录数 + TotalCount *uint64 `json:"TotalCount,omitnil,omitempty" name:"TotalCount"` +} + +type RecordListItem struct { + // 记录Id + RecordId *uint64 `json:"RecordId,omitnil,omitempty" name:"RecordId"` + + // 记录值 + Value *string `json:"Value,omitnil,omitempty" name:"Value"` + + // 记录状态,启用:ENABLE,暂停:DISABLE + Status *string `json:"Status,omitnil,omitempty" name:"Status"` + + // 更新时间 + UpdatedOn *string `json:"UpdatedOn,omitnil,omitempty" name:"UpdatedOn"` + + // 主机名 + Name *string `json:"Name,omitnil,omitempty" name:"Name"` + + // 记录线路 + Line *string `json:"Line,omitnil,omitempty" name:"Line"` + + // 线路Id + LineId *string `json:"LineId,omitnil,omitempty" name:"LineId"` + + // 记录类型 + Type *string `json:"Type,omitnil,omitempty" name:"Type"` + + // 记录权重,用于负载均衡记录 + // 注意:此字段可能返回 null,表示取不到有效值。 + Weight *uint64 `json:"Weight,omitnil,omitempty" name:"Weight"` + + // 记录监控状态,正常:OK,告警:WARN,宕机:DOWN,未设置监控或监控暂停则为空 + MonitorStatus *string `json:"MonitorStatus,omitnil,omitempty" name:"MonitorStatus"` + + // 记录备注说明 + Remark *string `json:"Remark,omitnil,omitempty" name:"Remark"` + + // 记录缓存时间 + TTL *uint64 `json:"TTL,omitnil,omitempty" name:"TTL"` + + // MX值,只有MX记录有 + // 注意:此字段可能返回 null,表示取不到有效值。 + MX *uint64 `json:"MX,omitnil,omitempty" name:"MX"` + + // 是否是默认的ns记录 + DefaultNS *bool `json:"DefaultNS,omitnil,omitempty" name:"DefaultNS"` +} diff --git a/go.mod b/go.mod index 8672a91..400c7cd 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,4 @@ go 1.18 require github.com/libdns/libdns v0.2.2 -require ( - github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1033 - github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dnspod v1.0.1033 -) +require github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1051 diff --git a/go.sum b/go.sum index 4c27c78..92450f8 100644 --- a/go.sum +++ b/go.sum @@ -1,6 +1,4 @@ github.com/libdns/libdns v0.2.2 h1:O6ws7bAfRPaBsgAYt8MDe2HcNBGC29hkZ9MX2eUSX3s= github.com/libdns/libdns v0.2.2/go.mod h1:4Bj9+5CQiNMVGf87wjX4CY3HQJypUHRuLvlsfsZqLWQ= -github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1033 h1:g263/dapUpOAZJa1Y9x07WgfOl7Yy+FM5Mrf4WyttS8= -github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1033/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0= -github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dnspod v1.0.1033 h1:bRCo+X6i/6B+5Q/G4+rexcMRxpSq+9XS/8+Usn6OcOA= -github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dnspod v1.0.1033/go.mod h1:ta9FOsQP/SvQAhDD6IhVhYWyY+eboPEbPWq7zpiNwZA= +github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1051 h1:3mg0L9vv9eO8UN4Oa7vNawe6yUIuXf9D0Q79rUmnblo= +github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1051/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0= From 7d4e898ce504e209a338c6722f89729397076ae1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=80=97=E5=AD=90?= Date: Fri, 29 Nov 2024 17:59:55 +0800 Subject: [PATCH 2/2] chore: add LICENSE file --- dnspod/LICENSE | 201 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 201 insertions(+) create mode 100644 dnspod/LICENSE diff --git a/dnspod/LICENSE b/dnspod/LICENSE new file mode 100644 index 0000000..d191b30 --- /dev/null +++ b/dnspod/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright (c) 2017-2018 Tencent Ltd. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file