sigs.k8s.io/external-dns@v0.14.1/provider/plural/client.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 plural 18 19 import ( 20 "context" 21 "fmt" 22 "net/http" 23 "net/url" 24 "strings" 25 26 "github.com/pluralsh/gqlclient" 27 "github.com/pluralsh/gqlclient/pkg/utils" 28 ) 29 30 type authedTransport struct { 31 key string 32 wrapped http.RoundTripper 33 } 34 35 func (t *authedTransport) RoundTrip(req *http.Request) (*http.Response, error) { 36 req.Header.Set("Authorization", "Bearer "+t.key) 37 return t.wrapped.RoundTrip(req) 38 } 39 40 type Client interface { 41 DnsRecords() ([]*DnsRecord, error) 42 CreateRecord(record *DnsRecord) (*DnsRecord, error) 43 DeleteRecord(name, ttype string) error 44 } 45 46 type Config struct { 47 Token string 48 Endpoint string 49 Cluster string 50 Provider string 51 } 52 53 type client struct { 54 ctx context.Context 55 pluralClient *gqlclient.Client 56 config *Config 57 } 58 59 type DnsRecord struct { 60 Type string 61 Name string 62 Records []string 63 } 64 65 func NewClient(conf *Config) (Client, error) { 66 base, err := conf.BaseUrl() 67 if err != nil { 68 return nil, err 69 } 70 httpClient := http.Client{ 71 Transport: &authedTransport{ 72 key: conf.Token, 73 wrapped: http.DefaultTransport, 74 }, 75 } 76 endpoint := base + "/gql" 77 return &client{ 78 ctx: context.Background(), 79 pluralClient: gqlclient.NewClient(&httpClient, endpoint), 80 config: conf, 81 }, nil 82 } 83 84 func (c *Config) BaseUrl() (string, error) { 85 host := "https://app.plural.sh" 86 if c.Endpoint != "" { 87 host = fmt.Sprintf("https://%s", c.Endpoint) 88 if _, err := url.Parse(host); err != nil { 89 return "", err 90 } 91 } 92 return host, nil 93 } 94 95 func (client *client) DnsRecords() ([]*DnsRecord, error) { 96 resp, err := client.pluralClient.GetDNSRecords(client.ctx, client.config.Cluster, gqlclient.Provider(strings.ToUpper(client.config.Provider))) 97 if err != nil { 98 return nil, err 99 } 100 101 records := make([]*DnsRecord, 0) 102 for _, edge := range resp.DNSRecords.Edges { 103 if edge.Node != nil { 104 record := &DnsRecord{ 105 Type: string(edge.Node.Type), 106 Name: edge.Node.Name, 107 Records: utils.ConvertStringArrayPointer(edge.Node.Records), 108 } 109 records = append(records, record) 110 } 111 } 112 return records, nil 113 } 114 115 func (client *client) CreateRecord(record *DnsRecord) (*DnsRecord, error) { 116 provider := gqlclient.Provider(strings.ToUpper(client.config.Provider)) 117 cluster := client.config.Cluster 118 attr := gqlclient.DNSRecordAttributes{ 119 Name: record.Name, 120 Type: gqlclient.DNSRecordType(record.Type), 121 Records: []*string{}, 122 } 123 124 for _, record := range record.Records { 125 attr.Records = append(attr.Records, &record) 126 } 127 128 resp, err := client.pluralClient.CreateDNSRecord(client.ctx, cluster, provider, attr) 129 if err != nil { 130 return nil, err 131 } 132 133 return &DnsRecord{ 134 Type: string(resp.CreateDNSRecord.Type), 135 Name: resp.CreateDNSRecord.Name, 136 Records: utils.ConvertStringArrayPointer(resp.CreateDNSRecord.Records), 137 }, nil 138 } 139 140 func (client *client) DeleteRecord(name, ttype string) error { 141 if _, err := client.pluralClient.DeleteDNSRecord(client.ctx, name, gqlclient.DNSRecordType(ttype)); err != nil { 142 return err 143 } 144 145 return nil 146 }