Skip to content

Commit b699e96

Browse files
committed
Add a CNAME recursive resolving datasource
1 parent f8e43d8 commit b699e96

File tree

5 files changed

+192
-0
lines changed

5 files changed

+192
-0
lines changed
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
---
2+
# generated by https://github.com/hashicorp/terraform-plugin-docs
3+
page_title: "dns_recursive_cname_record_set Data Source - terraform-provider-dns"
4+
subcategory: ""
5+
description: |-
6+
Use this data source to get DNS CNAME record set of the host.
7+
---
8+
9+
# dns_recursive_cname_record_set (Data Source)
10+
11+
Use this data source to get DNS CNAME record set of the host.
12+
13+
## Example Usage
14+
15+
```terraform
16+
data "dns_recursive_cname_record_set" "hashicorp" {
17+
host = "www.hashicorp.com"
18+
}
19+
20+
output "hashi_cnames" {
21+
value = data.dns_recursive_cname_record_set.hashicorp.cnames
22+
}
23+
```
24+
25+
<!-- schema generated by tfplugindocs -->
26+
## Schema
27+
28+
### Required
29+
30+
- `host` (String) Host to recursively look up.
31+
32+
### Read-Only
33+
34+
- `cnames` (List of String) Chained CNAME records associated with host.
35+
- `id` (String) Always set to the host.
36+
- `last_cname` (String) The final CNAME at end of the chain.
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
data "dns_recursive_cname_record_set" "hashicorp" {
2+
host = "www.hashicorp.com"
3+
}
4+
5+
output "hashi_cnames" {
6+
value = data.dns_recursive_cname_record_set.hashicorp.cnames
7+
}
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
// Copyright (c) HashiCorp, Inc.
2+
// SPDX-License-Identifier: MPL-2.0
3+
4+
package provider
5+
6+
import (
7+
"context"
8+
"fmt"
9+
"net"
10+
"strings"
11+
12+
"github.com/hashicorp/terraform-plugin-framework/datasource"
13+
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
14+
"github.com/hashicorp/terraform-plugin-framework/types"
15+
)
16+
17+
var (
18+
_ datasource.DataSource = (*dnsCNAMERecursiveRecordSetDataSource)(nil)
19+
)
20+
21+
func NewDnsCNAMERecursiveRecordSetDataSource() datasource.DataSource {
22+
return &dnsCNAMERecursiveRecordSetDataSource{}
23+
}
24+
25+
type dnsCNAMERecursiveRecordSetDataSource struct{}
26+
27+
func (d *dnsCNAMERecursiveRecordSetDataSource) Metadata(ctx context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) {
28+
resp.TypeName = req.ProviderTypeName + "_recursive_cname_record_set"
29+
}
30+
31+
func (d *dnsCNAMERecursiveRecordSetDataSource) Schema(ctx context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) {
32+
resp.Schema = schema.Schema{
33+
Description: "Use this data source to get DNS CNAME record set of the host.",
34+
Attributes: map[string]schema.Attribute{
35+
"host": schema.StringAttribute{
36+
Required: true,
37+
Description: "Host to recursively look up.",
38+
},
39+
"cnames": schema.ListAttribute{
40+
ElementType: types.StringType,
41+
Computed: true,
42+
Description: "Chained CNAME records associated with host.",
43+
},
44+
"last_cname": schema.StringAttribute{
45+
Computed: true,
46+
Description: "The final CNAME at end of the chain.",
47+
},
48+
"id": schema.StringAttribute{
49+
Computed: true,
50+
Description: "Always set to the host.",
51+
},
52+
},
53+
}
54+
}
55+
56+
func (d *dnsCNAMERecursiveRecordSetDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {
57+
var config cnameRecursiveRecordSetConfig
58+
59+
resp.Diagnostics.Append(req.Config.Get(ctx, &config)...)
60+
if resp.Diagnostics.HasError() {
61+
return
62+
}
63+
64+
cnames := []string{}
65+
66+
host := config.Host.ValueString()
67+
for cname, err := net.LookupCNAME(host); cname != host; cname, err = net.LookupCNAME(host) {
68+
if err != nil {
69+
resp.Diagnostics.AddError(fmt.Sprintf("error looking up CNAME records for %q: ", host), err.Error())
70+
return
71+
}
72+
cnames = append(cnames, strings.Clone(cname))
73+
host = cname
74+
}
75+
76+
config.CNAMES, _ = types.ListValueFrom(ctx, types.StringType, cnames)
77+
if len(cnames) > 0 {
78+
config.LastCNAME = types.StringValue(cnames[len(cnames)-1])
79+
}
80+
config.ID = config.Host
81+
resp.Diagnostics.Append(resp.State.Set(ctx, config)...)
82+
}
83+
84+
type cnameRecursiveRecordSetConfig struct {
85+
ID types.String `tfsdk:"id"`
86+
Host types.String `tfsdk:"host"`
87+
CNAMES types.List `tfsdk:"cnames"`
88+
LastCNAME types.String `tfsdk:"last_cname"`
89+
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
// Copyright (c) HashiCorp, Inc.
2+
// SPDX-License-Identifier: MPL-2.0
3+
4+
package provider
5+
6+
import (
7+
"testing"
8+
9+
"github.com/hashicorp/terraform-plugin-testing/helper/resource"
10+
)
11+
12+
func TestAccDataDnsRecursiveCnameRecordSet_Basic(t *testing.T) {
13+
recordName := "data.dns_recursive_cname_record_set.test"
14+
15+
resource.UnitTest(t, resource.TestCase{
16+
ProtoV5ProviderFactories: testProtoV5ProviderFactories,
17+
Steps: []resource.TestStep{
18+
{
19+
Config: `
20+
data "dns_recursive_cname_record_set" "test" {
21+
host = "terraform-provider-dns-cname.hashicorptest.com"
22+
}
23+
`,
24+
Check: resource.ComposeAggregateTestCheckFunc(
25+
resource.TestCheckResourceAttr(recordName, "cnames.0", "example.com."),
26+
resource.TestCheckNoResourceAttr(recordName, "cnames.1"),
27+
resource.TestCheckResourceAttr(recordName, "last_cname", "example.com."),
28+
resource.TestCheckResourceAttr(recordName, "host", "terraform-provider-dns-cname.hashicorptest.com"),
29+
resource.TestCheckResourceAttr(recordName, "id", "terraform-provider-dns-cname.hashicorptest.com"),
30+
),
31+
},
32+
},
33+
})
34+
}
35+
36+
func TestAccDataDnsRecursiveCnameRecordSet_Complex(t *testing.T) {
37+
recordName := "data.dns_recursive_cname_record_set.test"
38+
39+
resource.UnitTest(t, resource.TestCase{
40+
ProtoV5ProviderFactories: testProtoV5ProviderFactories,
41+
Steps: []resource.TestStep{
42+
{
43+
Config: `
44+
data "dns_recursive_cname_record_set" "test" {
45+
host = "test2.tony.docusign.dev"
46+
}
47+
`,
48+
Check: resource.ComposeAggregateTestCheckFunc(
49+
resource.TestCheckResourceAttr(recordName, "cnames.0", "stage.services.docusign.net."),
50+
resource.TestCheckResourceAttr(recordName, "cnames.1", "stage.services.docusign.net.akadns.net."),
51+
resource.TestCheckNoResourceAttr(recordName, "cnames.2"),
52+
resource.TestCheckResourceAttr(recordName, "last_cname", "stage.services.docusign.net.akadns.net."),
53+
resource.TestCheckResourceAttr(recordName, "host", "test2.tony.docusign.dev"),
54+
resource.TestCheckResourceAttr(recordName, "id", "test2.tony.docusign.dev"),
55+
),
56+
},
57+
},
58+
})
59+
}

internal/provider/provider_framework.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -347,6 +347,7 @@ func (p *dnsProvider) DataSources(ctx context.Context) []func() datasource.DataS
347347
NewDnsARecordSetDataSource,
348348
NewDnsAAAARecordSetDataSource,
349349
NewDnsCNAMERecordSetDataSource,
350+
NewDnsCNAMERecursiveRecordSetDataSource,
350351
NewDnsMXRecordSetDataSource,
351352
NewDnsNSRecordSetDataSource,
352353
NewDnsPTRRecordSetDataSource,

0 commit comments

Comments
 (0)