sigs.k8s.io/external-dns@v0.14.1/provider/tencentcloud/tencent_cloud.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 tencentcloud 18 19 import ( 20 "context" 21 "encoding/json" 22 "fmt" 23 "os" 24 "strings" 25 26 log "github.com/sirupsen/logrus" 27 28 "sigs.k8s.io/external-dns/endpoint" 29 "sigs.k8s.io/external-dns/plan" 30 "sigs.k8s.io/external-dns/provider" 31 "sigs.k8s.io/external-dns/provider/tencentcloud/cloudapi" 32 ) 33 34 const ( 35 TencentCloudEmptyPrefix = "@" 36 DefaultAPIRate = 9 37 ) 38 39 func NewTencentCloudProvider(domainFilter endpoint.DomainFilter, zoneIDFilter provider.ZoneIDFilter, configFile string, zoneType string, dryRun bool) (*TencentCloudProvider, error) { 40 cfg := tencentCloudConfig{} 41 if configFile != "" { 42 contents, err := os.ReadFile(configFile) 43 if err != nil { 44 return nil, fmt.Errorf("failed to read Tencent Cloud config file '%s': %w", configFile, err) 45 } 46 err = json.Unmarshal(contents, &cfg) 47 if err != nil { 48 return nil, fmt.Errorf("failed to parse Tencent Cloud config file '%s': %w", configFile, err) 49 } 50 } 51 52 var apiService cloudapi.TencentAPIService = cloudapi.NewTencentAPIService(cfg.RegionId, DefaultAPIRate, cfg.SecretId, cfg.SecretKey, cfg.InternetEndpoint) 53 if dryRun { 54 apiService = cloudapi.NewReadOnlyAPIService(cfg.RegionId, DefaultAPIRate, cfg.SecretId, cfg.SecretKey, cfg.InternetEndpoint) 55 } 56 57 tencentCloudProvider := &TencentCloudProvider{ 58 domainFilter: domainFilter, 59 zoneIDFilter: zoneIDFilter, 60 apiService: apiService, 61 vpcID: cfg.VPCId, 62 privateZone: zoneType == "private", 63 } 64 65 return tencentCloudProvider, nil 66 } 67 68 type TencentCloudProvider struct { 69 provider.BaseProvider 70 apiService cloudapi.TencentAPIService 71 domainFilter endpoint.DomainFilter 72 zoneIDFilter provider.ZoneIDFilter // Private Zone only 73 vpcID string // Private Zone only 74 privateZone bool 75 } 76 77 type tencentCloudConfig struct { 78 RegionId string `json:"regionId" yaml:"regionId"` 79 SecretId string `json:"secretId" yaml:"secretId"` 80 SecretKey string `json:"secretKey" yaml:"secretKey"` 81 VPCId string `json:"vpcId" yaml:"vpcId"` 82 InternetEndpoint bool `json:"internetEndpoint" yaml:"internetEndpoint"` 83 } 84 85 func (p *TencentCloudProvider) Records(ctx context.Context) ([]*endpoint.Endpoint, error) { 86 if p.privateZone { 87 return p.privateZoneRecords() 88 } 89 return p.dnsRecords() 90 } 91 92 func (p *TencentCloudProvider) ApplyChanges(ctx context.Context, changes *plan.Changes) error { 93 if !changes.HasChanges() { 94 return nil 95 } 96 97 log.Infof("apply changes. %s", cloudapi.JsonWrapper(changes)) 98 99 if p.privateZone { 100 return p.applyChangesForPrivateZone(changes) 101 } 102 return p.applyChangesForDNS(changes) 103 } 104 105 func getSubDomain(domain string, endpoint *endpoint.Endpoint) string { 106 name := endpoint.DNSName 107 name = name[:len(name)-len(domain)] 108 name = strings.TrimSuffix(name, ".") 109 110 if name == "" { 111 return TencentCloudEmptyPrefix 112 } 113 return name 114 } 115 116 func getDnsDomain(subDomain string, domain string) string { 117 if subDomain == TencentCloudEmptyPrefix { 118 return domain 119 } 120 return subDomain + "." + domain 121 }