diff --git a/go.mod b/go.mod index 94892da7e0..d1212d31a8 100644 --- a/go.mod +++ b/go.mod @@ -120,6 +120,7 @@ require ( github.com/gopherjs/gopherjs v1.17.2 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-cleanhttp v0.5.2 // indirect + github.com/hashicorp/go-hclog v1.6.3 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/hashicorp/go-retryablehttp v0.7.7 // indirect github.com/hashicorp/go-rootcerts v1.0.2 // indirect @@ -127,6 +128,7 @@ require ( github.com/hashicorp/go-secure-stdlib/strutil v0.1.2 // indirect github.com/hashicorp/go-sockaddr v1.0.2 // indirect github.com/hashicorp/hcl v1.0.0 // indirect + github.com/hashicorp/terraform-plugin-log v0.9.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/kolo/xmlrpc v0.0.0-20220921171641-a4b6fa1dd06b // indirect github.com/mattn/go-colorable v0.1.13 // indirect @@ -148,6 +150,7 @@ require ( github.com/sony/gobreaker v0.5.0 // indirect github.com/stretchr/objx v0.5.2 // indirect github.com/tjfoc/gmsm v1.4.1 // indirect + github.com/vercel/terraform-provider-vercel v1.14.1 // indirect github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 // indirect go.mongodb.org/mongo-driver v1.13.1 // indirect go.opentelemetry.io/auto/sdk v1.1.0 // indirect diff --git a/go.sum b/go.sum index 32552503ad..ad4f4120c5 100644 --- a/go.sum +++ b/go.sum @@ -127,6 +127,7 @@ github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7 github.com/exoscale/egoscale v0.102.4 h1:GBKsZMIOzwBfSu+4ZmWka3Ejf2JLiaBDHp4CQUgvp2E= github.com/exoscale/egoscale v0.102.4/go.mod h1:ROSmPtle0wvf91iLZb09++N/9BH2Jo9XxIpAEumvocA= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= +github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM= github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU= github.com/fatih/structs v1.1.0 h1:Q7juDM0QtcnhCpeyLGQKyg4TOIghuNXrkL32pHAUMxo= @@ -251,6 +252,8 @@ github.com/hashicorp/go-sockaddr v1.0.2 h1:ztczhD1jLxIRjVejw8gFomI1BQZOe2WoVOu0S github.com/hashicorp/go-sockaddr v1.0.2/go.mod h1:rB4wwRAUzs07qva3c5SdrY/NEtAUjGlgmH/UkBUC97A= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +github.com/hashicorp/terraform-plugin-log v0.9.0 h1:i7hOA+vdAItN1/7UrfBqBwvYPQ9TFvymaRGZED3FCV0= +github.com/hashicorp/terraform-plugin-log v0.9.0/go.mod h1:rKL8egZQ/eXSyDqzLUuwUYLVdlYeamldAHSxjUFADow= github.com/hashicorp/vault/api v1.16.0 h1:nbEYGJiAPGzT9U4oWgaaB0g+Rj8E59QuHKyA5LhwQN4= github.com/hashicorp/vault/api v1.16.0/go.mod h1:KhuUhzOD8lDSk29AtzNjgAu2kxRA9jL9NAbkFlqvkBA= github.com/huaweicloud/huaweicloud-sdk-go-v3 v0.1.142 h1:9iOJ8tfNLw8uSiR5yx7VcHEYSOajJq5hb9SXF0BCUdA= @@ -298,7 +301,9 @@ github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/matryer/moq v0.0.0-20190312154309-6cfb0558e1bd/go.mod h1:9ELz6aaclSIGnZBoaSLZ3NAl1VTufbOrXBPvtcy6WiQ= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= +github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.11/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= +github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= @@ -406,6 +411,7 @@ github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5 github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= github.com/stretchr/testify v1.7.5/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= @@ -423,6 +429,8 @@ github.com/urfave/cli/v2 v2.27.6 h1:VdRdS98FNhKZ8/Az8B7MTyGQmpIr36O1EHybx/LaZ4g= github.com/urfave/cli/v2 v2.27.6/go.mod h1:3Sevf16NykTbInEnD0yKkjDAeZDS0A6bzhBH5hrMvTQ= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= +github.com/vercel/terraform-provider-vercel v1.14.1 h1:ghAjFkMMzka4XuoBYdu1OXM/K7FQEj8wUd+xMPPOGrg= +github.com/vercel/terraform-provider-vercel v1.14.1/go.mod h1:AdFCiUD0XP8XOi6tnhaCh7I0vyq2TAPmI+GcIp3+7SI= github.com/vultr/govultr/v2 v2.17.2 h1:gej/rwr91Puc/tgh+j33p/BLR16UrIPnSr+AIwYWZQs= github.com/vultr/govultr/v2 v2.17.2/go.mod h1:ZFOKGWmgjytfyjeyAdhQlSWwTjh2ig+X49cAp50dzXI= github.com/xddxdd/ottoext v0.0.0-20221109171055-210517fa4419 h1:PT5KYEimicg1GRkBtBxCLcHWvMcBRGljOLwG/y4+T5c= @@ -528,6 +536,7 @@ golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -537,6 +546,7 @@ golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211103235746-7861aae1554b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= diff --git a/providers/_all/all.go b/providers/_all/all.go index c4f4820ffb..399c0758eb 100644 --- a/providers/_all/all.go +++ b/providers/_all/all.go @@ -55,5 +55,6 @@ import ( _ "github.com/StackExchange/dnscontrol/v4/providers/sakuracloud" _ "github.com/StackExchange/dnscontrol/v4/providers/softlayer" _ "github.com/StackExchange/dnscontrol/v4/providers/transip" + _ "github.com/StackExchange/dnscontrol/v4/providers/vercel" _ "github.com/StackExchange/dnscontrol/v4/providers/vultr" ) diff --git a/providers/vercel/vercelProvider.go b/providers/vercel/vercelProvider.go new file mode 100644 index 0000000000..882ef41827 --- /dev/null +++ b/providers/vercel/vercelProvider.go @@ -0,0 +1,122 @@ +package vercel + +/* +Vercel DNS provider (vercel.com) + +Info required in `creds.json`: + - account_id + - api_token +*/ + +import ( + "context" + "encoding/json" + "errors" + + "github.com/StackExchange/dnscontrol/v4/models" + "github.com/StackExchange/dnscontrol/v4/providers" + vercelClient "github.com/vercel/terraform-provider-vercel/client" +) + +var defaultNameservers = []string{ + "ns1.vercel-dns.com", + "ns2.vercel-dns.com", +} + +var features = providers.DocumentationNotes{ + // The default for unlisted capabilities is 'Cannot'. + // See providers/capabilities.go for the entire list of capabilities. + providers.CanAutoDNSSEC: providers.Cannot(), + providers.CanGetZones: providers.Cannot(), + providers.CanConcur: providers.Unimplemented(), + providers.CanUseAlias: providers.Can(), + providers.CanUseCAA: providers.Can(), + providers.CanUseDHCID: providers.Cannot(), + providers.CanUseDS: providers.Cannot(), + providers.CanUseDSForChildren: providers.Cannot(), + providers.CanUseLOC: providers.Cannot(), + providers.CanUseNAPTR: providers.Cannot(), + providers.CanUsePTR: providers.Cannot(), + providers.CanUseSOA: providers.Cannot(), + providers.CanUseSRV: providers.Can(), + providers.CanUseSSHFP: providers.Cannot(), + providers.CanUseTLSA: providers.Cannot(), + providers.DocCreateDomains: providers.Unimplemented(), + providers.DocDualHost: providers.Cannot(), + providers.DocOfficiallySupported: providers.Cannot(), +} + +// hednsProvider stores login credentials and represents and API connection +type vercelProvider struct { + client vercelClient.Client + teamID string +} + +func init() { + const providerName = "Vercel" + const providerMaintainer = "@SukkaW" + fns := providers.DspFuncs{ + Initializer: newProvider, + } + providers.RegisterDomainServiceProviderType(providerName, fns, providers.CanUseSRV, features) + providers.RegisterMaintainer(providerName, providerMaintainer) +} + +func newProvider(creds map[string]string, meta json.RawMessage) (providers.DNSServiceProvider, error) { + if creds["account_id"] == "" || creds["api_token"] == "" { + return nil, errors.New("api_token required for ns1") + } + + // Enable Sleep API Rate limit strategy - it will sleep until new tokens are available + // see https://help.ns1.com/hc/en-us/articles/360020250573-About-API-rate-limiting + // this strategy would imply the least sleep time for non-parallel client requests + c := vercelClient.New( + creds["api_token"], + ) + + ctx := context.Background() + + team, err := c.Team(ctx, creds["account_id"]) + if err != nil { + return nil, err + } + + c = c.WithTeam(team) + return &vercelProvider{ + client: *c, + // store this information so that we can access this anywhere we want + teamID: creds["account_id"], + }, nil +} + +// GetNameservers returns the default Vercel nameservers. +// Though Vercel RESTful API supports getting "intendedNameServers", but it is not implemented in the Go SDK +// Let's hard-coded this for now +func (c *vercelProvider) GetNameservers(_ string) ([]*models.Nameserver, error) { + return models.ToNameservers(defaultNameservers) +} + +func (c *vercelProvider) GetZoneRecords(domain string, meta map[string]string) (models.Records, error) { + var zoneRecords []*models.RecordConfig + ctx := context.Background() + + records, err := c.client.ListDNSRecords(ctx, domain, c.teamID) + if err != nil { + return nil, err + } + + for _, record := range records { + zoneRecords = append(zoneRecords, &models.RecordConfig{ + Type: record.RecordType, + Name: record.Name, + Original: record, + TTL: uint32(record.TTL), // we can do this convertion safely as TTL won't be that big and 4294967295 would be enough + }) + } + + return zoneRecords, nil +} + +func (c *vercelProvider) GetZoneRecordsCorrections(dc *models.DomainConfig, records models.Records) ([]*models.Correction, int, error) { + return nil, 0, nil +}