Skip to content

Commit 7376169

Browse files
authored
Fix project domain readiness checks (#575)
1 parent 4e3ab7c commit 7376169

9 files changed

Lines changed: 282 additions & 29 deletions

client/domain_config.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,13 @@ type recommendedCNAMEValue struct {
2020
type domainConfigAPIResponse struct {
2121
RecommendedCNAME []recommendedCNAMEValue `json:"recommendedCNAME"`
2222
RecommendedIPv4 []recommendedValue `json:"recommendedIPv4"`
23+
Misconfigured bool `json:"misconfigured"`
2324
}
2425

2526
type DomainConfigResponse struct {
2627
RecommendedCNAME string
2728
RecommendedIPv4s []string
29+
Misconfigured bool
2830
}
2931

3032
func (c *Client) GetDomainConfig(ctx context.Context, domain, projectIdOrName, teamID string) (DomainConfigResponse, error) {
@@ -49,7 +51,9 @@ func (c *Client) GetDomainConfig(ctx context.Context, domain, projectIdOrName, t
4951
return DomainConfigResponse{}, fmt.Errorf("unable to get domain config: %w", err)
5052
}
5153

52-
response := DomainConfigResponse{}
54+
response := DomainConfigResponse{
55+
Misconfigured: apiResponse.Misconfigured,
56+
}
5357

5458
for _, reccomendation := range apiResponse.RecommendedCNAME {
5559
if reccomendation.Rank == 1 {

client/domain_config_test.go

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
package client
2+
3+
import (
4+
"context"
5+
"io"
6+
"net/http"
7+
"strings"
8+
"testing"
9+
)
10+
11+
func TestGetDomainConfigIncludesMisconfigured(t *testing.T) {
12+
httpClient := &http.Client{Transport: roundTripFunc(func(r *http.Request) (*http.Response, error) {
13+
if got, want := r.URL.Path, "/v6/domains/www.example.com/config"; got != want {
14+
t.Fatalf("request path = %q, want %q", got, want)
15+
}
16+
if got, want := r.URL.Query().Get("projectIdOrName"), "prj_123"; got != want {
17+
t.Fatalf("projectIdOrName = %q, want %q", got, want)
18+
}
19+
if got, want := r.URL.Query().Get("teamId"), "team_123"; got != want {
20+
t.Fatalf("teamId = %q, want %q", got, want)
21+
}
22+
23+
return &http.Response{
24+
StatusCode: http.StatusOK,
25+
Header: http.Header{"Content-Type": []string{"application/json"}},
26+
Body: io.NopCloser(strings.NewReader(`{
27+
"misconfigured": true,
28+
"recommendedCNAME": [{"rank": 1, "value": "example.vercel-dns-017.com"}],
29+
"recommendedIPv4": [{"rank": 1, "value": ["76.76.21.21"]}]
30+
}`)),
31+
}, nil
32+
})}
33+
34+
testClient := New("INVALID").WithBaseURL("https://api.vercel.test")
35+
testClient.client = httpClient
36+
got, err := testClient.GetDomainConfig(
37+
context.Background(),
38+
"www.example.com",
39+
"prj_123",
40+
"team_123",
41+
)
42+
if err != nil {
43+
t.Fatalf("GetDomainConfig() error = %v", err)
44+
}
45+
if !got.Misconfigured {
46+
t.Fatal("GetDomainConfig().Misconfigured = false, want true")
47+
}
48+
if got.RecommendedCNAME != "example.vercel-dns-017.com" {
49+
t.Fatalf("GetDomainConfig().RecommendedCNAME = %q, want %q", got.RecommendedCNAME, "example.vercel-dns-017.com")
50+
}
51+
if len(got.RecommendedIPv4s) != 1 || got.RecommendedIPv4s[0] != "76.76.21.21" {
52+
t.Fatalf("GetDomainConfig().RecommendedIPv4s = %v, want [76.76.21.21]", got.RecommendedIPv4s)
53+
}
54+
}
55+
56+
type roundTripFunc func(*http.Request) (*http.Response, error)
57+
58+
func (f roundTripFunc) RoundTrip(r *http.Request) (*http.Response, error) {
59+
return f(r)
60+
}

docs/data-sources/domain_config.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,15 @@ subcategory: ""
55
description: |-
66
Provides domain configuration information for a Vercel project.
77
This data source returns configuration details for a domain associated with a specific project,
8-
including recommended CNAME and IPv4 values.
8+
including its DNS configuration status and recommended CNAME and IPv4 values.
99
---
1010

1111
# vercel_domain_config (Data Source)
1212

1313
Provides domain configuration information for a Vercel project.
1414

1515
This data source returns configuration details for a domain associated with a specific project,
16-
including recommended CNAME and IPv4 values.
16+
including its DNS configuration status and recommended CNAME and IPv4 values.
1717

1818
## Example Usage
1919

@@ -69,5 +69,6 @@ resource "aws_route53_record" "www_example_com_cname" {
6969

7070
### Read-Only
7171

72+
- `misconfigured` (Boolean) Whether the domain has an invalid DNS configuration or Vercel cannot automatically generate a TLS certificate for it.
7273
- `recommended_cname` (String) The recommended CNAME value for the domain.
7374
- `recommended_ipv4s` (List of String) The recommended IPv4 values for the domain.

docs/resources/project_domain.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,13 +63,14 @@ resource "vercel_project_domain" "example_redirect" {
6363
- `redirect` (String) The domain name that serves as a target destination for redirects.
6464
- `redirect_status_code` (Number) The HTTP status code to use when serving as a redirect.
6565
- `team_id` (String) The ID of the team the project exists under. Required when configuring a team resource if a default team has not been set in the provider.
66-
- `wait_for_ready` (Boolean) Wait until the project domain is verified before considering it created. This is useful when another resource, such as an alias, depends on the domain being ready immediately.
66+
- `wait_for_ready` (Boolean) Wait until the project domain is verified and has a valid DNS configuration before considering it created. DNS records must be configured independently before enabling this option because dependent resources are not created until the wait completes.
6767

6868
### Read-Only
6969

7070
- `id` (String) The ID of this resource.
71-
- `verification` (Attributes List) A list of verification challenges, one of which must be completed to verify the domain for use on the project. Once the challenge is satisfied, the domain will be verified automatically on the next refresh. Typically used to configure DNS records (e.g. a `TXT` record) for domains hosted with an external DNS provider. (see [below for nested schema](#nestedatt--verification))
72-
- `verified` (Boolean) Whether the domain is verified for use with the project. If `false`, the challenges in `verification` must be completed before the domain will serve traffic for the project.
71+
- `misconfigured` (Boolean) Whether the domain has an invalid DNS configuration or Vercel cannot automatically generate a TLS certificate for it.
72+
- `verification` (Attributes List) A list of ownership verification challenges, one of which must be completed to verify the domain for use with the project. These are typically `TXT` records and do not describe the `A` or `CNAME` records needed to route traffic to Vercel. (see [below for nested schema](#nestedatt--verification))
73+
- `verified` (Boolean) Whether ownership of the domain is verified for use with the project. This does not indicate whether the domain's DNS records point to Vercel; use `misconfigured` for that status.
7374

7475
<a id="nestedatt--verification"></a>
7576
### Nested Schema for `verification`

vercel/data_source_domain_config.go

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ func (d *domainConfigDataSource) Schema(_ context.Context, req datasource.Schema
5555
Provides domain configuration information for a Vercel project.
5656
5757
This data source returns configuration details for a domain associated with a specific project,
58-
including recommended CNAME and IPv4 values.
58+
including its DNS configuration status and recommended CNAME and IPv4 values.
5959
`,
6060
Attributes: map[string]schema.Attribute{
6161
"domain": schema.StringAttribute{
@@ -80,6 +80,10 @@ including recommended CNAME and IPv4 values.
8080
Computed: true,
8181
Description: "The recommended IPv4 values for the domain.",
8282
},
83+
"misconfigured": schema.BoolAttribute{
84+
Computed: true,
85+
Description: "Whether the domain has an invalid DNS configuration or Vercel cannot automatically generate a TLS certificate for it.",
86+
},
8387
},
8488
}
8589
}
@@ -91,6 +95,7 @@ type DomainConfigDataSource struct {
9195
TeamID types.String `tfsdk:"team_id"`
9296
RecommendedCNAME types.String `tfsdk:"recommended_cname"`
9397
RecommendedIPv4s types.List `tfsdk:"recommended_ipv4s"`
98+
Misconfigured types.Bool `tfsdk:"misconfigured"`
9499
}
95100

96101
// Read will read domain config information by requesting it from the Vercel API, and will update terraform
@@ -128,6 +133,7 @@ func (d *domainConfigDataSource) Read(ctx context.Context, req datasource.ReadRe
128133
TeamID: config.TeamID,
129134
RecommendedCNAME: types.StringValue(out.RecommendedCNAME),
130135
RecommendedIPv4s: types.ListValueMust(types.StringType, ipv4Values),
136+
Misconfigured: types.BoolValue(out.Misconfigured),
131137
}
132138

133139
tflog.Info(ctx, "read domain config", map[string]any{
@@ -136,6 +142,7 @@ func (d *domainConfigDataSource) Read(ctx context.Context, req datasource.ReadRe
136142
"teamId": result.TeamID.ValueString(),
137143
"recommendedCNAME": result.RecommendedCNAME.ValueString(),
138144
"recommendedIPv4s": result.RecommendedIPv4s.Elements(),
145+
"misconfigured": result.Misconfigured.ValueBool(),
139146
})
140147

141148
diags = resp.State.Set(ctx, result)

vercel/data_source_domain_config_test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ func TestAcc_DomainConfigDataSource(t *testing.T) {
2323
resource.TestCheckResourceAttrSet("data.vercel_domain_config.test", "project_id_or_name"),
2424
resource.TestCheckResourceAttrSet("data.vercel_domain_config.test", "recommended_cname"),
2525
resource.TestCheckResourceAttrSet("data.vercel_domain_config.test", "recommended_ipv4s.#"),
26+
resource.TestCheckResourceAttrSet("data.vercel_domain_config.test", "misconfigured"),
2627
),
2728
},
2829
},

0 commit comments

Comments
 (0)