Skip to content

Commit

Permalink
Merge pull request #2121 from ddymko/vultr-v2-updates
Browse files Browse the repository at this point in the history
Vultr : Update vultr provider to use API v2
  • Loading branch information
k8s-ci-robot authored Jun 9, 2021
2 parents 7b8c69b + efe799e commit ab91b0c
Show file tree
Hide file tree
Showing 5 changed files with 155 additions and 120 deletions.
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ require (
github.com/fatih/structs v1.1.0 // indirect
github.com/ffledgling/pdns-go v0.0.0-20180219074714-524e7daccd99
github.com/golang/sync v0.0.0-20180314180146-1d60e4601c6f
github.com/google/go-cmp v0.4.1
github.com/google/go-cmp v0.5.2
github.com/gophercloud/gophercloud v0.1.0
github.com/gorilla/mux v1.7.4 // indirect
github.com/hooklift/gowsdl v0.4.0
Expand All @@ -53,7 +53,7 @@ require (
github.com/transip/gotransip/v6 v6.6.0
github.com/ultradns/ultradns-sdk-go v0.0.0-20200616202852-e62052662f60
github.com/vinyldns/go-vinyldns v0.0.0-20200211145900-fe8a3d82e556
github.com/vultr/govultr v0.4.2
github.com/vultr/govultr/v2 v2.5.1
go.etcd.io/etcd v0.5.0-alpha.5.0.20200401174654-e694b7bb0875
go.uber.org/ratelimit v0.1.0
golang.org/x/net v0.0.0-20201224014010-6772e930b67b
Expand Down
19 changes: 8 additions & 11 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -390,10 +390,11 @@ github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5a
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.4.1 h1:/exdXoGamhu5ONeUJH0deniYLWYvQwW66yvlfiiKTu0=
github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk=
github.com/google/go-cmp v0.5.2 h1:X2ev0eStA3AbceY54o37/0PQ/UWqKEiiO2dKL5OPaFM=
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8=
github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU=
github.com/google/gofuzz v0.0.0-20161122191042-44d81051d367/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/gofuzz v1.1.0 h1:Hsa8mG0dQ46ij8Sl2AYJDUv1oA9/d6Vk+3LG99Oe02g=
Expand Down Expand Up @@ -464,8 +465,8 @@ github.com/hashicorp/go-multierror v0.0.0-20161216184304-ed905158d874/go.mod h1:
github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
github.com/hashicorp/go-multierror v1.1.0 h1:B9UzwGQJehnUY1yNrnwREHc3fGbC2xefo8g4TbElacI=
github.com/hashicorp/go-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+vmowP0z+KUhOZdA=
github.com/hashicorp/go-retryablehttp v0.6.6 h1:HJunrbHTDDbBb/ay4kxa1n+dLmttUlnP3V9oNE4hmsM=
github.com/hashicorp/go-retryablehttp v0.6.6/go.mod h1:vAew36LZh98gCBJNLH42IQ1ER/9wtLZZ8meHqQvEYWY=
github.com/hashicorp/go-retryablehttp v0.7.0 h1:eu1EI/mbirUgP5C8hVsTNaGZreBDlYiwC1FZWkvQPQ4=
github.com/hashicorp/go-retryablehttp v0.7.0/go.mod h1:vAew36LZh98gCBJNLH42IQ1ER/9wtLZZ8meHqQvEYWY=
github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU=
github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU=
github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4=
Expand Down Expand Up @@ -639,7 +640,6 @@ github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzE
github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w=
github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w=
github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c=
github.com/nbio/st v0.0.0-20140626010706-e9e8d9816f32 h1:W6apQkHrMkS0Muv8G/TipAy/FJl/rCYT0+EuS8+Z0z4=
github.com/nbio/st v0.0.0-20140626010706-e9e8d9816f32/go.mod h1:9wM+0iRr9ahx58uYLpLIr5fm8diHn0JbqRycJi6w0Ms=
github.com/ncw/swift v1.0.47/go.mod h1:23YIA4yWVnGwv2dQlN4bB7egfYX6YLn0Yo/S6zZO/ZM=
github.com/nesv/go-dynect v0.6.0 h1:Ow/DiSm4LAISwnFku/FITSQHnU6pBvhQMsUE5Gu6Oq4=
Expand Down Expand Up @@ -870,8 +870,8 @@ github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtX
github.com/vektah/gqlparser v1.1.2/go.mod h1:1ycwN7Ij5njmMkPPAOaRFY4rET2Enx7IkVv3vaXspKw=
github.com/vinyldns/go-vinyldns v0.0.0-20200211145900-fe8a3d82e556 h1:UbVjBjgJUYGD8MlobEdOR+yTeNqaNa2Gf1/nskVNCSE=
github.com/vinyldns/go-vinyldns v0.0.0-20200211145900-fe8a3d82e556/go.mod h1:RWc47jtnVuQv6+lY3c768WtXCas/Xi+U5UFc5xULmYg=
github.com/vultr/govultr v0.4.2 h1:9i8xKZ+xp6vwZ9raqHoBLzhB4wCnMj7nOQTj5YIRLWY=
github.com/vultr/govultr v0.4.2/go.mod h1:TUuUizMOFc7z+PNMssb6iGjKjQfpw5arIaOLfocVudQ=
github.com/vultr/govultr/v2 v2.5.1 h1:Bh3G7nqHs0Gv7OQRExfYFppbuscwVKFDK05b8XBYYnQ=
github.com/vultr/govultr/v2 v2.5.1/go.mod h1:BvOhVe6/ZpjwcoL6/unkdQshmbS9VGbowI4QT+3DGVU=
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=
github.com/xeipuuv/gojsonschema v0.0.0-20180618132009-1d523034197f/go.mod h1:5yf86TLmAcydyeJq5YvxkGPE2fm/u4myDekKRoLuqhs=
Expand Down Expand Up @@ -1006,7 +1006,6 @@ golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLL
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200625001655-4c5254603344 h1:vGXIOMxbNfDTk/aXCmfdLgkrSV+Z2tcbze+pEc3v5W4=
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20201224014010-6772e930b67b h1:iFwSg7t5GZmB/Q5TjiEAsdoLDrdJRC1RiF2WhuV29Qw=
golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
Expand Down Expand Up @@ -1064,11 +1063,9 @@ golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200420163511-1957bb5e6d1f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1 h1:ogLJMz+qpzav7lGMh10LMvAkM/fAoGlaiiHYiFYdm80=
golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68 h1:nxC68pudNYkKU6jWhgrqdreuFiOQWj1Fs7T3VrH4Pjw=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 h1:v+OssWQX+hTHEmOBgwxdZxK4zHq3yOs8F9J7mk0PY8E=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
Expand Down
2 changes: 1 addition & 1 deletion main.go
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ func main() {
case "vinyldns":
p, err = vinyldns.NewVinylDNSProvider(domainFilter, zoneIDFilter, cfg.DryRun)
case "vultr":
p, err = vultr.NewVultrProvider(domainFilter, cfg.DryRun)
p, err = vultr.NewVultrProvider(ctx, domainFilter, cfg.DryRun)
case "ultradns":
p, err = ultradns.NewUltraDNSProvider(domainFilter, cfg.DryRun)
case "cloudflare":
Expand Down
155 changes: 85 additions & 70 deletions provider/vultr/vultr.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,11 @@ import (
"context"
"fmt"
"os"
"strconv"
"strings"

log "github.com/sirupsen/logrus"
"github.com/vultr/govultr"
"github.com/vultr/govultr/v2"
"golang.org/x/oauth2"

"sigs.k8s.io/external-dns/endpoint"
"sigs.k8s.io/external-dns/plan"
Expand All @@ -51,30 +51,33 @@ type VultrProvider struct {
type VultrChanges struct {
Action string

ResourceRecordSet govultr.DNSRecord
ResourceRecordSet *govultr.DomainRecordReq
}

// NewVultrProvider initializes a new Vultr BNS based provider
func NewVultrProvider(domainFilter endpoint.DomainFilter, dryRun bool) (*VultrProvider, error) {
func NewVultrProvider(ctx context.Context, domainFilter endpoint.DomainFilter, dryRun bool) (*VultrProvider, error) {
apiKey, ok := os.LookupEnv("VULTR_API_KEY")
if !ok {
return nil, fmt.Errorf("no token found")
}

client := govultr.NewClient(nil, apiKey)
oauthClient := oauth2.NewClient(ctx, oauth2.StaticTokenSource(&oauth2.Token{
AccessToken: apiKey,
}))
client := govultr.NewClient(oauthClient)
client.SetUserAgent(fmt.Sprintf("ExternalDNS/%s", client.UserAgent))

provider := &VultrProvider{
p := &VultrProvider{
client: *client,
domainFilter: domainFilter,
DryRun: dryRun,
}

return provider, nil
return p, nil
}

// Zones returns list of hosted zones
func (p *VultrProvider) Zones(ctx context.Context) ([]govultr.DNSDomain, error) {
func (p *VultrProvider) Zones(ctx context.Context) ([]govultr.Domain, error) {
zones, err := p.fetchZones(ctx)
if err != nil {
return nil, err
Expand Down Expand Up @@ -108,34 +111,58 @@ func (p *VultrProvider) Records(ctx context.Context) ([]*endpoint.Endpoint, erro
name = zone.Domain
}

endPointTTL := endpoint.NewEndpointWithTTL(name, r.Type, endpoint.TTL(r.TTL), r.Data)
endpoints = append(endpoints, endPointTTL)
endpoints = append(endpoints, endpoint.NewEndpointWithTTL(name, r.Type, endpoint.TTL(r.TTL), r.Data))
}
}
}

return endpoints, nil
}

func (p *VultrProvider) fetchRecords(ctx context.Context, domain string) ([]govultr.DNSRecord, error) {
records, err := p.client.DNSRecord.List(ctx, domain)
if err != nil {
return nil, err
func (p *VultrProvider) fetchRecords(ctx context.Context, domain string) ([]govultr.DomainRecord, error) {
var allRecords []govultr.DomainRecord
listOptions := &govultr.ListOptions{}

for {
records, meta, err := p.client.DomainRecord.List(ctx, domain, listOptions)
if err != nil {
return nil, err
}

allRecords = append(allRecords, records...)

if meta.Links.Next == "" {
break
} else {
listOptions.Cursor = meta.Links.Next
continue
}
}

return records, nil
return allRecords, nil
}

func (p *VultrProvider) fetchZones(ctx context.Context) ([]govultr.DNSDomain, error) {
var zones []govultr.DNSDomain
func (p *VultrProvider) fetchZones(ctx context.Context) ([]govultr.Domain, error) {
var zones []govultr.Domain
listOptions := &govultr.ListOptions{}

allZones, err := p.client.DNSDomain.List(ctx)
if err != nil {
return nil, err
}
for {
allZones, meta, err := p.client.Domain.List(ctx, listOptions)
if err != nil {
return nil, err
}

for _, zone := range allZones {
if p.domainFilter.Match(zone.Domain) {
zones = append(zones, zone)
for _, zone := range allZones {
if p.domainFilter.Match(zone.Domain) {
zones = append(zones, zone)
}
}

if meta.Links.Next == "" {
break
} else {
listOptions.Cursor = meta.Links.Next
continue
}
}

Expand All @@ -153,24 +180,21 @@ func (p *VultrProvider) submitChanges(ctx context.Context, changes []*VultrChang
return err
}

zoneChanges := seperateChangesByZone(zones, changes)
zoneChanges := separateChangesByZone(zones, changes)

for zoneName, changes := range zoneChanges {
for _, change := range changes {
log.WithFields(log.Fields{
"record": change.ResourceRecordSet.Name,
"type": change.ResourceRecordSet.Type,
"ttl": change.ResourceRecordSet.TTL,
"priority": change.ResourceRecordSet.Priority,
"action": change.Action,
"zone": zoneName,
"record": change.ResourceRecordSet.Name,
"type": change.ResourceRecordSet.Type,
"ttl": change.ResourceRecordSet.TTL,
"action": change.Action,
"zone": zoneName,
}).Info("Changing record.")

switch change.Action {
case vultrCreate:
priority := getPriority(change.ResourceRecordSet.Priority)
err = p.client.DNSRecord.Create(ctx, zoneName, change.ResourceRecordSet.Type, change.ResourceRecordSet.Name, change.ResourceRecordSet.Data, change.ResourceRecordSet.TTL, priority)
if err != nil {
if _, err := p.client.DomainRecord.Create(ctx, zoneName, change.ResourceRecordSet); err != nil {
return err
}
case vultrDelete:
Expand All @@ -179,26 +203,15 @@ func (p *VultrProvider) submitChanges(ctx context.Context, changes []*VultrChang
return err
}

err = p.client.DNSRecord.Delete(ctx, zoneName, strconv.Itoa(id))
if err != nil {
if err := p.client.DomainRecord.Delete(ctx, zoneName, id); err != nil {
return err
}
case vultrUpdate:
id, err := p.getRecordID(ctx, zoneName, change.ResourceRecordSet)
if err != nil {
return err
}

record := &govultr.DNSRecord{
RecordID: id,
Type: change.ResourceRecordSet.Type,
Name: change.ResourceRecordSet.Name,
Data: change.ResourceRecordSet.Data,
TTL: change.ResourceRecordSet.TTL,
}

err = p.client.DNSRecord.Update(ctx, zoneName, record)
if err != nil {
if err := p.client.DomainRecord.Update(ctx, zoneName, id, change.ResourceRecordSet); err != nil {
return err
}
}
Expand Down Expand Up @@ -228,19 +241,20 @@ func newVultrChanges(action string, endpoints []*endpoint.Endpoint) []*VultrChan

change := &VultrChanges{
Action: action,
ResourceRecordSet: govultr.DNSRecord{
ResourceRecordSet: &govultr.DomainRecordReq{
Type: e.RecordType,
Name: e.DNSName,
Data: e.Targets[0],
TTL: ttl,
},
}

changes = append(changes, change)
}
return changes
}

func seperateChangesByZone(zones []govultr.DNSDomain, changes []*VultrChanges) map[string][]*VultrChanges {
func separateChangesByZone(zones []govultr.Domain, changes []*VultrChanges) map[string][]*VultrChanges {
change := make(map[string][]*VultrChanges)
zoneNameID := provider.ZoneIDName{}

Expand All @@ -260,30 +274,31 @@ func seperateChangesByZone(zones []govultr.DNSDomain, changes []*VultrChanges) m
return change
}

func (p *VultrProvider) getRecordID(ctx context.Context, zone string, record govultr.DNSRecord) (recordID int, err error) {
records, err := p.client.DNSRecord.List(ctx, zone)
if err != nil {
return 0, err
}

for _, r := range records {
strippedName := strings.TrimSuffix(record.Name, "."+zone)
if record.Name == zone {
strippedName = ""
func (p *VultrProvider) getRecordID(ctx context.Context, zone string, record *govultr.DomainRecordReq) (recordID string, err error) {
listOptions := &govultr.ListOptions{}
for {
records, meta, err := p.client.DomainRecord.List(ctx, zone, listOptions)
if err != nil {
return "0", err
}

if r.Name == strippedName && r.Type == record.Type {
return r.RecordID, nil
for _, r := range records {
strippedName := strings.TrimSuffix(record.Name, "."+zone)
if record.Name == zone {
strippedName = ""
}

if r.Name == strippedName && r.Type == record.Type {
return r.ID, nil
}
}
if meta.Links.Next == "" {
break
} else {
listOptions.Cursor = meta.Links.Next
continue
}
}

return 0, fmt.Errorf("no record was found")
}

func getPriority(priority *int) int {
p := 0
if priority != nil {
p = *priority
}
return p
return "", fmt.Errorf("no record was found")
}
Loading

0 comments on commit ab91b0c

Please sign in to comment.