-
Notifications
You must be signed in to change notification settings - Fork 32
Begin fleshing out DNS records #12
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
package client | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
"net/http" | ||
"strings" | ||
) | ||
|
||
// SRV defines the metata required for creating an SRV type DNS Record. | ||
type SRV struct { | ||
Port int64 `json:"port"` | ||
Priority int64 `json:"priority"` | ||
Target string `json:"target"` | ||
Weight int64 `json:"weight"` | ||
} | ||
|
||
// CreateDNSRecordRequest defines the information necessary to create a DNS record within Vercel. | ||
type CreateDNSRecordRequest struct { | ||
Domain string `json:"-"` | ||
MXPriority int64 `json:"mxPriority,omitempty"` | ||
Name string `json:"name"` | ||
SRV *SRV `json:"srv,omitempty"` | ||
TTL int64 `json:"ttl,omitempty"` | ||
Type string `json:"type"` | ||
Value string `json:"value,omitempty"` | ||
} | ||
|
||
// CreateProjectDomain creates a DNS record for a specified domain name within Vercel. | ||
func (c *Client) CreateDNSRecord(ctx context.Context, teamID string, request CreateDNSRecordRequest) (r DNSRecord, err error) { | ||
url := fmt.Sprintf("%s/v4/domains/%s/records", c.baseURL, request.Domain) | ||
if teamID != "" { | ||
url = fmt.Sprintf("%s?teamId=%s", url, teamID) | ||
} | ||
|
||
req, err := http.NewRequestWithContext( | ||
ctx, | ||
"POST", | ||
url, | ||
strings.NewReader(string(mustMarshal(request))), | ||
) | ||
if err != nil { | ||
return r, err | ||
} | ||
|
||
var response struct { | ||
RecordID string `json:"uid"` | ||
} | ||
err = c.doRequest(req, &response) | ||
if err != nil { | ||
return r, err | ||
} | ||
|
||
return c.GetDNSRecord(ctx, response.RecordID, teamID) | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
package client | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
"net/http" | ||
"strings" | ||
) | ||
|
||
// DeleteDNSRecord removes a DNS domain from Vercel. | ||
func (c *Client) DeleteDNSRecord(ctx context.Context, domain, recordID, teamID string) error { | ||
url := fmt.Sprintf("%s/v2/domains/%s/records/%s", c.baseURL, domain, recordID) | ||
if teamID != "" { | ||
url = fmt.Sprintf("%s?teamId=%s", url, teamID) | ||
} | ||
|
||
req, err := http.NewRequestWithContext( | ||
ctx, | ||
"DELETE", | ||
url, | ||
strings.NewReader(""), | ||
) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
return c.doRequest(req, nil) | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
package client | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
"net/http" | ||
"strings" | ||
) | ||
|
||
// DNSRecord is the information Vercel surfaces about a DNS record associated with a particular domain. | ||
type DNSRecord struct { | ||
Creator string `json:"creator"` | ||
Domain string `json:"domain"` | ||
ID string `json:"id"` | ||
Name string `json:"name"` | ||
TTL int64 `json:"ttl"` | ||
Value string `json:"value"` | ||
RecordType string `json:"recordType"` | ||
Priority int64 `json:"priority"` | ||
} | ||
|
||
// GetDNSRecord retrieves information about a DNS domain from Vercel. | ||
func (c *Client) GetDNSRecord(ctx context.Context, recordID, teamID string) (r DNSRecord, err error) { | ||
url := fmt.Sprintf("%s/domains/records/%s", c.baseURL, recordID) | ||
if teamID != "" { | ||
url = fmt.Sprintf("%s?teamId=%s", url, teamID) | ||
} | ||
|
||
req, err := http.NewRequestWithContext( | ||
ctx, | ||
"GET", | ||
url, | ||
strings.NewReader(""), | ||
) | ||
if err != nil { | ||
return r, err | ||
} | ||
|
||
err = c.doRequest(req, &r) | ||
return r, err | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
package client | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
"net/http" | ||
"strings" | ||
) | ||
|
||
// ListDNSRecords is a test helper for listing DNS records that exist for a given domain. | ||
// We limit this to 100, as this is the largest limit allowed by the API. | ||
// This is only used by the sweeper script, so this is safe to do so, but converting | ||
// into a production ready function would require some refactoring. | ||
func (c *Client) ListDNSRecords(ctx context.Context, domain, teamID string) (r []DNSRecord, err error) { | ||
url := fmt.Sprintf("%s/v4/domains/%s/records?limit=100", c.baseURL, domain) | ||
if teamID != "" { | ||
url = fmt.Sprintf("%s&teamId=%s", url, teamID) | ||
} | ||
|
||
req, err := http.NewRequestWithContext( | ||
ctx, | ||
"GET", | ||
url, | ||
strings.NewReader(""), | ||
) | ||
if err != nil { | ||
return r, err | ||
} | ||
|
||
dr := struct { | ||
Records []DNSRecord `json:"records"` | ||
}{} | ||
err = c.doRequest(req, &dr) | ||
return dr.Records, err | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
package client | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
"net/http" | ||
"strings" | ||
|
||
"github.com/hashicorp/terraform-plugin-log/tflog" | ||
) | ||
|
||
type SRVUpdate struct { | ||
Port *int64 `json:"port"` | ||
Priority *int64 `json:"priority"` | ||
Target *string `json:"target"` | ||
Weight *int64 `json:"weight"` | ||
} | ||
|
||
type UpdateDNSRecordRequest struct { | ||
MXPriority *int64 `json:"mxPriority,omitempty"` | ||
Name *string `json:"name,omitempty"` | ||
SRV *SRVUpdate `json:"srv,omitempty"` | ||
TTL *int64 `json:"ttl,omitempty"` | ||
Value *string `json:"value,omitempty"` | ||
} | ||
|
||
func (c *Client) UpdateDNSRecord(ctx context.Context, teamID, recordID string, request UpdateDNSRecordRequest) (r DNSRecord, err error) { | ||
url := fmt.Sprintf("%s/v4/domains/records/%s", c.baseURL, recordID) | ||
if teamID != "" { | ||
url = fmt.Sprintf("%s?teamId=%s", url, teamID) | ||
} | ||
|
||
payload := string(mustMarshal(request)) | ||
req, err := http.NewRequestWithContext( | ||
ctx, | ||
"PATCH", | ||
url, | ||
strings.NewReader(payload), | ||
) | ||
if err != nil { | ||
return r, err | ||
} | ||
|
||
tflog.Trace(ctx, "updating DNS record", map[string]interface{}{ | ||
"url": url, | ||
"payload": payload, | ||
}) | ||
err = c.doRequest(req, &r) | ||
return r, err | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,142 @@ | ||
--- | ||
# generated by https://github.com/hashicorp/terraform-plugin-docs | ||
page_title: "vercel_dns_record Resource - terraform-provider-vercel" | ||
subcategory: "" | ||
description: |- | ||
Provides a DNS Record resource. | ||
DNS records are instructions that live in authoritative DNS servers and provide information about a domain. | ||
For more detailed information, please see the Vercel documentation https://vercel.com/docs/concepts/projects/custom-domains#dns-records | ||
--- | ||
|
||
# vercel_dns_record (Resource) | ||
|
||
Provides a DNS Record resource. | ||
|
||
DNS records are instructions that live in authoritative DNS servers and provide information about a domain. | ||
|
||
For more detailed information, please see the [Vercel documentation](https://vercel.com/docs/concepts/projects/custom-domains#dns-records) | ||
|
||
## Example Usage | ||
|
||
```terraform | ||
resource "vercel_dns_record" "a" { | ||
domain = "example.com" | ||
name = "subdomain" # for subdomain.example.com | ||
type = "A" | ||
ttl = 60 | ||
value = "192.168.0.1" | ||
} | ||
|
||
resource "vercel_dns_record" "aaaa" { | ||
domain = "example.com" | ||
name = "subdomain" | ||
type = "AAAA" | ||
ttl = 60 | ||
value = "::0" | ||
} | ||
|
||
resource "vercel_dns_record" "alias" { | ||
domain = "example.com" | ||
name = "subdomain" | ||
type = "ALIAS" | ||
ttl = 60 | ||
value = "example2.com." | ||
} | ||
|
||
resource "vercel_dns_record" "caa" { | ||
domain = "example.com" | ||
name = "subdomain" | ||
type = "CAA" | ||
ttl = 60 | ||
value = "1 issue \"letsencrypt.org\"" | ||
} | ||
|
||
resource "vercel_dns_record" "cname" { | ||
domain = "example.com" | ||
name = "subdomain" | ||
type = "CNAME" | ||
ttl = 60 | ||
value = "example2.com." | ||
} | ||
|
||
resource "vercel_dns_record" "mx" { | ||
domain = "example.com" | ||
name = "subdomain" | ||
type = "MX" | ||
ttl = 60 | ||
mx_priority = 333 | ||
value = "example2.com." | ||
} | ||
|
||
resource "vercel_dns_record" "srv" { | ||
domain = "example.com" | ||
name = "subdomain" | ||
type = "SRV" | ||
ttl = 60 | ||
srv = { | ||
port = 6000 | ||
weight = 60 | ||
priority = 127 | ||
target = "example2.com." | ||
} | ||
} | ||
|
||
resource "vercel_dns_record" "txt" { | ||
domain = "example.com" | ||
name = "subdomain" | ||
type = "TXT" | ||
ttl = 60 | ||
value = "some text value" | ||
} | ||
``` | ||
|
||
<!-- schema generated by tfplugindocs --> | ||
## Schema | ||
|
||
### Required | ||
|
||
- `domain` (String) The domain name, or zone, that the DNS record should be created beneath. | ||
- `name` (String) The subdomain name of the record. This should be an empty string if the rercord is for the root domain. | ||
- `type` (String) The type of DNS record. | ||
|
||
### Optional | ||
|
||
- `mx_priority` (Number) The priority of the MX record. The priority specifies the sequence that an email server receives emails. A smaller value indicates a higher priority. | ||
- `srv` (Attributes) Settings for an SRV record. (see [below for nested schema](#nestedatt--srv)) | ||
- `team_id` (String) The team ID that the domain and DNS records belong to. | ||
- `ttl` (Number) The TTL value in seconds. Must be a number between 60 and 2147483647. If unspecified, it will default to 60 seconds. | ||
- `value` (String) The value of the DNS record. The format depends on the 'type' property. | ||
For an 'A' record, this should be a valid IPv4 address. | ||
For an 'AAAA' record, this should be an IPv6 address. | ||
For 'ALIAS' records, this should be a hostname. | ||
For 'CAA' records, this should specify specify which Certificate Authorities (CAs) are allowed to issue certificates for the domain. | ||
For 'CNAME' records, this should be a different domain name. | ||
For 'MX' records, this should specify the mail server responsible for accepting messages on behalf of the domain name. | ||
For 'TXT' records, this can contain arbitrary text. | ||
|
||
### Read-Only | ||
|
||
- `id` (String) The ID of this resource. | ||
|
||
<a id="nestedatt--srv"></a> | ||
### Nested Schema for `srv` | ||
|
||
Optional: | ||
|
||
- `port` (Number) The TCP or UDP port on which the service is to be found. | ||
- `priority` (Number) The priority of the target host, lower value means more preferred. | ||
- `target` (String) The canonical hostname of the machine providing the service, ending in a dot. | ||
- `weight` (Number) A relative weight for records with the same priority, higher value means higher chance of getting picked. | ||
|
||
## Import | ||
|
||
Import is supported using the following syntax: | ||
|
||
```shell | ||
# Import via the team_id and record ID. | ||
# Record ID can be taken from the network tab on the domains page. | ||
terraform import vercel_dns_record.example team_xxxxxxxxxxxxxxxxxxxxxxxx/rec_xxxxxxxxxxxxxxxxxxxxxxxxxxxx | ||
|
||
# If importing without a team, simply use the record ID. | ||
terraform import vercel_dns_record.personal_example rec_xxxxxxxxxxxxxxxxxxxxxxxxxxxx | ||
``` |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
# Import via the team_id and record ID. | ||
# Record ID can be taken from the network tab on the domains page. | ||
terraform import vercel_dns_record.example team_xxxxxxxxxxxxxxxxxxxxxxxx/rec_xxxxxxxxxxxxxxxxxxxxxxxxxxxx | ||
|
||
# If importing without a team, simply use the record ID. | ||
terraform import vercel_dns_record.personal_example rec_xxxxxxxxxxxxxxxxxxxxxxxxxxxx |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could this be problematic if someone uses more than 100 domains?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good shout, it's currently only used by the sweeper (script to remove any orphaned test resources). So it shouldn't be an issue for anything.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll add a comment explaining this though.