feat: remove filter from dns_record datasource and use plain structure (#58)

This commit is contained in:
Mateusz Filipowicz
2025-03-16 16:25:50 +01:00
committed by GitHub
parent b269563553
commit 02d10929c9
3 changed files with 35 additions and 60 deletions

View File

@@ -63,7 +63,7 @@ func TestDNSRecordDataSource_basic(t *testing.T) {
}
var (
dnsDataSourceFilterErrorRegex = regexp.MustCompile(`[filter.name,filter.record]`)
dnsDataSourceFilterErrorRegex = regexp.MustCompile(`[name,record]`)
)
func TestDNSRecordDataSource_errorWithoutFilter(t *testing.T) {
@@ -89,9 +89,7 @@ func testAccDnsRecordDataSourceConfig(tc dnsRecordTestCase, filterByName bool) s
return fmt.Sprintf(`
data "unifi_dns_record" "test" {
filter {
%s
}
depends_on = [unifi_dns_record.test]
}`, filter)
}
@@ -99,8 +97,5 @@ data "unifi_dns_record" "test" {
func testAccDnsRecordDataSourceWithoutFilter() string {
return `
data "unifi_dns_record" "test" {
filter {
}
}`
}

View File

@@ -8,11 +8,9 @@ import (
"github.com/filipowm/terraform-provider-unifi/internal/provider/base"
"github.com/filipowm/terraform-provider-unifi/internal/utils"
"github.com/hashicorp/terraform-plugin-framework-validators/datasourcevalidator"
"github.com/hashicorp/terraform-plugin-framework-validators/objectvalidator"
"github.com/hashicorp/terraform-plugin-framework/datasource"
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
"github.com/hashicorp/terraform-plugin-framework/path"
"github.com/hashicorp/terraform-plugin-framework/schema/validator"
)
var (
@@ -39,8 +37,8 @@ func NewDnsRecordDatasource() datasource.DataSource {
func (d *dnsRecordDatasource) ConfigValidators(_ context.Context) []datasource.ConfigValidator {
return []datasource.ConfigValidator{
datasourcevalidator.ExactlyOneOf(
path.MatchRoot("filter").AtName("name"),
path.MatchRoot("filter").AtName("record"),
path.MatchRoot("name"),
path.MatchRoot("record"),
),
}
}
@@ -67,26 +65,6 @@ func (d *dnsRecordDatasource) Schema(_ context.Context, _ datasource.SchemaReque
"This data source allows you to look up DNS records by either their name or record content. " +
"It's particularly useful for validating existing DNS configurations or referencing DNS records in other resources.",
Attributes: dnsRecordDatasourceAttributes,
Blocks: map[string]schema.Block{
"filter": schema.SingleNestedBlock{
Description: "Filter criteria to identify the specific DNS record. You must specify either the record name or content.",
Validators: []validator.Object{
objectvalidator.IsRequired(),
},
Attributes: map[string]schema.Attribute{
"name": schema.StringAttribute{
Description: "The DNS record name to look up (e.g., 'example.com', 'subdomain.example.com'). " +
"Cannot be specified together with `record`.",
Optional: true,
},
"record": schema.StringAttribute{
Description: "The DNS record content to look up (e.g., IP address for A records, target hostname for CNAME records). " +
"Cannot be specified together with `name`.",
Optional: true,
},
},
},
},
}
}
@@ -94,19 +72,15 @@ func (d *dnsRecordDatasource) Read(ctx context.Context, req datasource.ReadReque
if !d.client.SupportsDnsRecords() {
resp.Diagnostics.AddError("DNS Records are not supported", fmt.Sprintf("The Unifi controller in version %q does not support DNS records. Required controller version: %q", d.client.Version, base.ControllerVersionDnsRecords))
}
var state dnsRecordDatasourceModel
var state dnsRecordModel
resp.Diagnostics.Append(req.Config.Get(ctx, &state)...)
if resp.Diagnostics.HasError() {
return
}
if state.Filter == nil {
// TODO remove after testing validation
resp.Diagnostics.AddError("Filter is required", "Filter is required. Validation should prevent this from happening.")
return
}
site := d.client.ResolveSite(&state)
list, err := d.client.ListDNSRecord(ctx, site)
if err != nil {
resp.Diagnostics.AddError("Failed to list DNS records", err.Error())
return
@@ -115,35 +89,40 @@ func (d *dnsRecordDatasource) Read(ctx context.Context, req datasource.ReadReque
resp.Diagnostics.AddError("DNS record not found", "No DNS record found")
return
}
var nameFilter, recordFilter string
if utils.IsStringValueNotEmpty(state.Filter.Name) {
nameFilter = state.Filter.Name.ValueString()
if utils.IsStringValueNotEmpty(state.Name) {
nameFilter = state.Name.ValueString()
}
if utils.IsStringValueNotEmpty(state.Filter.Record) {
recordFilter = state.Filter.Record.ValueString()
if utils.IsStringValueNotEmpty(state.Record) {
recordFilter = state.Record.ValueString()
}
if nameFilter != "" && recordFilter != "" {
// TODO remove after testing validation
resp.Diagnostics.AddError("Filter is invalid", "Only one of 'name' or 'record' can be specified. Validation should prevent this from happening.")
return
}
var found *unifi.DNSRecord
var found []*unifi.DNSRecord
for _, record := range list {
if nameFilter != "" && record.Key == nameFilter {
found = &record
found = append(found, &record)
break
}
if recordFilter != "" && record.Value == recordFilter {
found = &record
found = append(found, &record)
break
}
}
if found == nil {
if len(found) == 0 {
resp.Diagnostics.AddError("DNS record not found", "No DNS record found")
return
} else if len(found) > 1 {
resp.Diagnostics.AddError("Multiple DNS records found", "More than one DNS record found")
return
}
(&state.dnsRecordModel).Merge(ctx, found)
state.SetID(found.ID)
(&state).Merge(ctx, found[0])
state.SetID(found[0].ID)
state.SetSite(site)
resp.Diagnostics.Append(resp.State.Set(ctx, &state)...)
}

View File

@@ -4,8 +4,11 @@ import (
"context"
"github.com/filipowm/go-unifi/unifi"
"github.com/filipowm/terraform-provider-unifi/internal/provider/base"
"github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator"
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
"github.com/hashicorp/terraform-plugin-framework/diag"
"github.com/hashicorp/terraform-plugin-framework/path"
"github.com/hashicorp/terraform-plugin-framework/schema/validator"
"github.com/hashicorp/terraform-plugin-framework/types"
)
@@ -25,11 +28,6 @@ type dnsRecordModel struct {
Weight types.Int32 `tfsdk:"weight"`
}
type dnsRecordDatasourceModel struct {
dnsRecordModel
Filter *dnsRecordFilterModel `tfsdk:"filter"`
}
type dnsRecordsDatasourceModel struct {
Site types.String `tfsdk:"site"`
Records []*dnsRecordModel `tfsdk:"result"`
@@ -52,11 +50,19 @@ var dnsRecordDatasourceAttributes = map[string]schema.Attribute{
"site": base.SiteAttribute(),
"name": schema.StringAttribute{
Description: "DNS record name.",
Optional: true,
Computed: true,
Validators: []validator.String{
stringvalidator.ConflictsWith(path.MatchRoot("record")),
},
},
"record": schema.StringAttribute{
Description: "DNS record content.",
Optional: true,
Computed: true,
Validators: []validator.String{
stringvalidator.ConflictsWith(path.MatchRoot("name")),
},
},
"enabled": schema.BoolAttribute{
Description: "Whether the DNS record is enabled.",
@@ -84,12 +90,7 @@ var dnsRecordDatasourceAttributes = map[string]schema.Attribute{
},
}
type dnsRecordFilterModel struct {
Name types.String `tfsdk:"name"`
Record types.String `tfsdk:"record"`
}
func (d *dnsRecordModel) AsUnifiModel(ctx context.Context) (interface{}, diag.Diagnostics) {
func (d *dnsRecordModel) AsUnifiModel(_ context.Context) (interface{}, diag.Diagnostics) {
return &unifi.DNSRecord{
ID: d.ID.ValueString(),
Key: d.Name.ValueString(),
@@ -103,7 +104,7 @@ func (d *dnsRecordModel) AsUnifiModel(ctx context.Context) (interface{}, diag.Di
}, diag.Diagnostics{}
}
func (d *dnsRecordModel) Merge(ctx context.Context, i interface{}) diag.Diagnostics {
func (d *dnsRecordModel) Merge(_ context.Context, i interface{}) diag.Diagnostics {
diags := diag.Diagnostics{}
other, ok := i.(*unifi.DNSRecord)
if !ok {