sigs.k8s.io/external-dns@v0.14.1/provider/tencentcloud/cloudapi/tencentapi.go (about) 1 /* 2 Copyright 2022 The Kubernetes Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package cloudapi 18 19 import ( 20 "encoding/json" 21 "fmt" 22 "net" 23 "time" 24 25 log "github.com/sirupsen/logrus" 26 "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/errors" 27 dnspod "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dnspod/v20210323" 28 privatedns "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/privatedns/v20201028" 29 ) 30 31 type defaultTencentAPIService struct { 32 RetryDefault int 33 TaskCheckInterval time.Duration 34 ClientSetService TencentClientSetService 35 } 36 37 func NewTencentAPIService(region string, rate int, secretId string, secretKey string, internetEndpoint bool) *defaultTencentAPIService { 38 tencentAPIService := &defaultTencentAPIService{ 39 RetryDefault: 3, 40 TaskCheckInterval: 3 * time.Second, 41 ClientSetService: NewTencentClientSetService(region, rate, secretId, secretKey, internetEndpoint), 42 } 43 return tencentAPIService 44 } 45 46 //////////////////////////////////////////////////////////////// 47 // PrivateDns API 48 //////////////////////////////////////////////////////////////// 49 50 func (api *defaultTencentAPIService) CreatePrivateZoneRecord(request *privatedns.CreatePrivateZoneRecordRequest) (response *privatedns.CreatePrivateZoneRecordResponse, err error) { 51 apiAction := CreatePrivateZoneRecord 52 for times := 1; times <= api.RetryDefault; times++ { 53 client := api.ClientSetService.PrivateDnsCli(apiAction.Name) 54 if response, err = client.CreatePrivateZoneRecord(request); err != nil { 55 requestJson := JsonWrapper(request) 56 if retry := dealWithError(apiAction, requestJson, err); retry || times == api.RetryDefault { 57 APIErrorRecord(apiAction, requestJson, JsonWrapper(response), err) 58 return nil, err 59 } 60 continue 61 } 62 break 63 } 64 APIRecord(apiAction, JsonWrapper(request), JsonWrapper(response)) 65 return response, nil 66 } 67 68 func (api *defaultTencentAPIService) DeletePrivateZoneRecord(request *privatedns.DeletePrivateZoneRecordRequest) (response *privatedns.DeletePrivateZoneRecordResponse, err error) { 69 apiAction := DeletePrivateZoneRecord 70 for times := 1; times <= api.RetryDefault; times++ { 71 client := api.ClientSetService.PrivateDnsCli(apiAction.Name) 72 if response, err = client.DeletePrivateZoneRecord(request); err != nil { 73 requestJson := JsonWrapper(request) 74 if retry := dealWithError(apiAction, requestJson, err); retry || times == api.RetryDefault { 75 APIErrorRecord(apiAction, requestJson, JsonWrapper(response), err) 76 return nil, err 77 } 78 continue 79 } 80 break 81 } 82 APIRecord(apiAction, JsonWrapper(request), JsonWrapper(response)) 83 return response, nil 84 } 85 86 func (api *defaultTencentAPIService) ModifyPrivateZoneRecord(request *privatedns.ModifyPrivateZoneRecordRequest) (response *privatedns.ModifyPrivateZoneRecordResponse, err error) { 87 apiAction := ModifyPrivateZoneRecord 88 for times := 1; times <= api.RetryDefault; times++ { 89 client := api.ClientSetService.PrivateDnsCli(apiAction.Name) 90 if response, err = client.ModifyPrivateZoneRecord(request); err != nil { 91 requestJson := JsonWrapper(request) 92 if retry := dealWithError(apiAction, requestJson, err); retry || times == api.RetryDefault { 93 APIErrorRecord(apiAction, requestJson, JsonWrapper(response), err) 94 return nil, err 95 } 96 continue 97 } 98 break 99 } 100 APIRecord(apiAction, JsonWrapper(request), JsonWrapper(response)) 101 return response, nil 102 } 103 104 func (api *defaultTencentAPIService) DescribePrivateZoneList(request *privatedns.DescribePrivateZoneListRequest) (response *privatedns.DescribePrivateZoneListResponse, err error) { 105 apiAction := DescribePrivateZoneList 106 for times := 1; times <= api.RetryDefault; times++ { 107 client := api.ClientSetService.PrivateDnsCli(apiAction.Name) 108 if response, err = client.DescribePrivateZoneList(request); err != nil { 109 requestJson := JsonWrapper(request) 110 if retry := dealWithError(apiAction, requestJson, err); retry || times == api.RetryDefault { 111 APIErrorRecord(apiAction, requestJson, JsonWrapper(response), err) 112 return nil, err 113 } 114 continue 115 } 116 break 117 } 118 APIRecord(apiAction, JsonWrapper(request), JsonWrapper(response)) 119 return response, nil 120 } 121 122 func (api *defaultTencentAPIService) DescribePrivateZoneRecordList(request *privatedns.DescribePrivateZoneRecordListRequest) (response *privatedns.DescribePrivateZoneRecordListResponse, err error) { 123 apiAction := DescribePrivateZoneRecordList 124 for times := 1; times <= api.RetryDefault; times++ { 125 client := api.ClientSetService.PrivateDnsCli(apiAction.Name) 126 if response, err = client.DescribePrivateZoneRecordList(request); err != nil { 127 requestJson := JsonWrapper(request) 128 if retry := dealWithError(apiAction, requestJson, err); retry || times == api.RetryDefault { 129 APIErrorRecord(apiAction, requestJson, JsonWrapper(response), err) 130 return nil, err 131 } 132 continue 133 } 134 break 135 } 136 APIRecord(apiAction, JsonWrapper(request), JsonWrapper(response)) 137 return response, nil 138 } 139 140 //////////////////////////////////////////////////////////////// 141 // DnsPod API 142 //////////////////////////////////////////////////////////////// 143 144 func (api *defaultTencentAPIService) DescribeDomainList(request *dnspod.DescribeDomainListRequest) (response *dnspod.DescribeDomainListResponse, err error) { 145 apiAction := DescribeDomainList 146 for times := 1; times <= api.RetryDefault; times++ { 147 client := api.ClientSetService.DnsPodCli(apiAction.Name) 148 if response, err = client.DescribeDomainList(request); err != nil { 149 requestJson := JsonWrapper(request) 150 if retry := dealWithError(apiAction, requestJson, err); retry || times == api.RetryDefault { 151 APIErrorRecord(apiAction, requestJson, JsonWrapper(response), err) 152 return nil, err 153 } 154 continue 155 } 156 break 157 } 158 APIRecord(apiAction, JsonWrapper(request), JsonWrapper(response)) 159 return response, nil 160 } 161 162 func (api *defaultTencentAPIService) DescribeRecordList(request *dnspod.DescribeRecordListRequest) (response *dnspod.DescribeRecordListResponse, err error) { 163 apiAction := DescribeRecordList 164 for times := 1; times <= api.RetryDefault; times++ { 165 client := api.ClientSetService.DnsPodCli(apiAction.Name) 166 if response, err = client.DescribeRecordList(request); err != nil { 167 requestJson := JsonWrapper(request) 168 if retry := dealWithError(apiAction, requestJson, err); retry || times == api.RetryDefault { 169 APIErrorRecord(apiAction, requestJson, JsonWrapper(response), err) 170 return nil, err 171 } 172 continue 173 } 174 break 175 } 176 APIRecord(apiAction, JsonWrapper(request), JsonWrapper(response)) 177 return response, nil 178 } 179 180 func (api *defaultTencentAPIService) CreateRecord(request *dnspod.CreateRecordRequest) (response *dnspod.CreateRecordResponse, err error) { 181 apiAction := CreateRecord 182 for times := 1; times <= api.RetryDefault; times++ { 183 client := api.ClientSetService.DnsPodCli(apiAction.Name) 184 if response, err = client.CreateRecord(request); err != nil { 185 requestJson := JsonWrapper(request) 186 if retry := dealWithError(apiAction, requestJson, err); retry || times == api.RetryDefault { 187 APIErrorRecord(apiAction, requestJson, JsonWrapper(response), err) 188 return nil, err 189 } 190 continue 191 } 192 break 193 } 194 APIRecord(apiAction, JsonWrapper(request), JsonWrapper(response)) 195 return response, nil 196 } 197 198 func (api *defaultTencentAPIService) DeleteRecord(request *dnspod.DeleteRecordRequest) (response *dnspod.DeleteRecordResponse, err error) { 199 apiAction := DeleteRecord 200 for times := 1; times <= api.RetryDefault; times++ { 201 client := api.ClientSetService.DnsPodCli(apiAction.Name) 202 if response, err = client.DeleteRecord(request); err != nil { 203 requestJson := JsonWrapper(request) 204 if retry := dealWithError(apiAction, requestJson, err); retry || times == api.RetryDefault { 205 APIErrorRecord(apiAction, requestJson, JsonWrapper(response), err) 206 return nil, err 207 } 208 continue 209 } 210 break 211 } 212 APIRecord(apiAction, JsonWrapper(request), JsonWrapper(response)) 213 return response, nil 214 } 215 216 func (api *defaultTencentAPIService) ModifyRecord(request *dnspod.ModifyRecordRequest) (response *dnspod.ModifyRecordResponse, err error) { 217 apiAction := ModifyRecord 218 for times := 1; times <= api.RetryDefault; times++ { 219 client := api.ClientSetService.DnsPodCli(apiAction.Name) 220 if response, err = client.ModifyRecord(request); err != nil { 221 requestJson := JsonWrapper(request) 222 if retry := dealWithError(apiAction, requestJson, err); retry || times == api.RetryDefault { 223 APIErrorRecord(apiAction, requestJson, JsonWrapper(response), err) 224 return nil, err 225 } 226 continue 227 } 228 break 229 } 230 APIRecord(apiAction, JsonWrapper(request), JsonWrapper(response)) 231 return response, nil 232 } 233 234 //////////////////////////////////////////////////////////////// 235 // API Error Report 236 //////////////////////////////////////////////////////////////// 237 238 func dealWithError(action Action, request string, err error) bool { 239 log.Errorf("dealWithError %s/%s request: %s, error: %s.", action.Service, action.Name, request, err.Error()) 240 if sdkError, ok := err.(*errors.TencentCloudSDKError); ok { 241 if sdkError.Code == "RequestLimitExceeded" { 242 return true 243 } else if sdkError.Code == "InternalError" || sdkError.Code == "ClientError.HttpStatusCodeError" { 244 return false 245 } else if sdkError.Code == "ClientError.NetworkError" { 246 return false 247 } else if sdkError.Code == "AuthFailure.UnauthorizedOperation" || sdkError.Code == "UnauthorizedOperation.CamNoAuth" { 248 return false 249 } 250 return false 251 } 252 253 if _, ok := err.(net.Error); ok { 254 return true 255 } 256 257 return false 258 } 259 260 func APIErrorRecord(apiAction Action, request string, response string, err error) { 261 log.Infof(fmt.Sprintf("APIError API: %s/%s Request: %s, Response: %s, Error: %s", apiAction.Service, apiAction.Name, request, response, err.Error())) 262 } 263 264 func APIRecord(apiAction Action, request string, response string) { 265 message := fmt.Sprintf("APIRecord API: %s/%s Request: %s, Response: %s", apiAction.Service, apiAction.Name, request, response) 266 267 if apiAction.ReadOnly { 268 // log.Infof(message) 269 } else { 270 log.Infof(message) 271 } 272 } 273 274 func JsonWrapper(obj interface{}) string { 275 if jsonStr, jsonErr := json.Marshal(obj); jsonErr == nil { 276 return string(jsonStr) 277 } 278 return "json_format_error" 279 }