Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion client/domain_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,13 @@ type recommendedCNAMEValue struct {
type domainConfigAPIResponse struct {
RecommendedCNAME []recommendedCNAMEValue `json:"recommendedCNAME"`
RecommendedIPv4 []recommendedValue `json:"recommendedIPv4"`
Misconfigured bool `json:"misconfigured"`
}

type DomainConfigResponse struct {
RecommendedCNAME string
RecommendedIPv4s []string
Misconfigured bool
}

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

response := DomainConfigResponse{}
response := DomainConfigResponse{
Misconfigured: apiResponse.Misconfigured,
}

for _, reccomendation := range apiResponse.RecommendedCNAME {
if reccomendation.Rank == 1 {
Expand Down
60 changes: 60 additions & 0 deletions client/domain_config_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package client

import (
"context"
"io"
"net/http"
"strings"
"testing"
)

func TestGetDomainConfigIncludesMisconfigured(t *testing.T) {
httpClient := &http.Client{Transport: roundTripFunc(func(r *http.Request) (*http.Response, error) {
if got, want := r.URL.Path, "/v6/domains/www.example.com/config"; got != want {
t.Fatalf("request path = %q, want %q", got, want)
}
if got, want := r.URL.Query().Get("projectIdOrName"), "prj_123"; got != want {
t.Fatalf("projectIdOrName = %q, want %q", got, want)
}
if got, want := r.URL.Query().Get("teamId"), "team_123"; got != want {
t.Fatalf("teamId = %q, want %q", got, want)
}

return &http.Response{
StatusCode: http.StatusOK,
Header: http.Header{"Content-Type": []string{"application/json"}},
Body: io.NopCloser(strings.NewReader(`{
"misconfigured": true,
"recommendedCNAME": [{"rank": 1, "value": "example.vercel-dns-017.com"}],
"recommendedIPv4": [{"rank": 1, "value": ["76.76.21.21"]}]
}`)),
}, nil
})}

testClient := New("INVALID").WithBaseURL("https://api.vercel.test")
testClient.client = httpClient
got, err := testClient.GetDomainConfig(
context.Background(),
"www.example.com",
"prj_123",
"team_123",
)
if err != nil {
t.Fatalf("GetDomainConfig() error = %v", err)
}
if !got.Misconfigured {
t.Fatal("GetDomainConfig().Misconfigured = false, want true")
}
if got.RecommendedCNAME != "example.vercel-dns-017.com" {
t.Fatalf("GetDomainConfig().RecommendedCNAME = %q, want %q", got.RecommendedCNAME, "example.vercel-dns-017.com")
}
if len(got.RecommendedIPv4s) != 1 || got.RecommendedIPv4s[0] != "76.76.21.21" {
t.Fatalf("GetDomainConfig().RecommendedIPv4s = %v, want [76.76.21.21]", got.RecommendedIPv4s)
}
}

type roundTripFunc func(*http.Request) (*http.Response, error)

func (f roundTripFunc) RoundTrip(r *http.Request) (*http.Response, error) {
return f(r)
}
5 changes: 3 additions & 2 deletions docs/data-sources/domain_config.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,15 @@ subcategory: ""
description: |-
Provides domain configuration information for a Vercel project.
This data source returns configuration details for a domain associated with a specific project,
including recommended CNAME and IPv4 values.
including its DNS configuration status and recommended CNAME and IPv4 values.
---

# vercel_domain_config (Data Source)

Provides domain configuration information for a Vercel project.

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

## Example Usage

Expand Down Expand Up @@ -69,5 +69,6 @@ resource "aws_route53_record" "www_example_com_cname" {

### Read-Only

- `misconfigured` (Boolean) Whether the domain has an invalid DNS configuration or Vercel cannot automatically generate a TLS certificate for it.
- `recommended_cname` (String) The recommended CNAME value for the domain.
- `recommended_ipv4s` (List of String) The recommended IPv4 values for the domain.
7 changes: 4 additions & 3 deletions docs/resources/project_domain.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,13 +63,14 @@ resource "vercel_project_domain" "example_redirect" {
- `redirect` (String) The domain name that serves as a target destination for redirects.
- `redirect_status_code` (Number) The HTTP status code to use when serving as a redirect.
- `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.
- `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.
- `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.

### Read-Only

- `id` (String) The ID of this resource.
- `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))
- `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.
- `misconfigured` (Boolean) Whether the domain has an invalid DNS configuration or Vercel cannot automatically generate a TLS certificate for it.
- `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))
- `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.

<a id="nestedatt--verification"></a>
### Nested Schema for `verification`
Expand Down
9 changes: 8 additions & 1 deletion vercel/data_source_domain_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ func (d *domainConfigDataSource) Schema(_ context.Context, req datasource.Schema
Provides domain configuration information for a Vercel project.

This data source returns configuration details for a domain associated with a specific project,
including recommended CNAME and IPv4 values.
including its DNS configuration status and recommended CNAME and IPv4 values.
`,
Attributes: map[string]schema.Attribute{
"domain": schema.StringAttribute{
Expand All @@ -80,6 +80,10 @@ including recommended CNAME and IPv4 values.
Computed: true,
Description: "The recommended IPv4 values for the domain.",
},
"misconfigured": schema.BoolAttribute{
Computed: true,
Description: "Whether the domain has an invalid DNS configuration or Vercel cannot automatically generate a TLS certificate for it.",
},
},
}
}
Expand All @@ -91,6 +95,7 @@ type DomainConfigDataSource struct {
TeamID types.String `tfsdk:"team_id"`
RecommendedCNAME types.String `tfsdk:"recommended_cname"`
RecommendedIPv4s types.List `tfsdk:"recommended_ipv4s"`
Misconfigured types.Bool `tfsdk:"misconfigured"`
}

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

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

diags = resp.State.Set(ctx, result)
Expand Down
1 change: 1 addition & 0 deletions vercel/data_source_domain_config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ func TestAcc_DomainConfigDataSource(t *testing.T) {
resource.TestCheckResourceAttrSet("data.vercel_domain_config.test", "project_id_or_name"),
resource.TestCheckResourceAttrSet("data.vercel_domain_config.test", "recommended_cname"),
resource.TestCheckResourceAttrSet("data.vercel_domain_config.test", "recommended_ipv4s.#"),
resource.TestCheckResourceAttrSet("data.vercel_domain_config.test", "misconfigured"),
),
},
},
Expand Down
Loading
Loading