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  }