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  }