Skip to content
Open
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
79 changes: 79 additions & 0 deletions internal/services/dns_record/resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,29 @@ func (r *DNSRecordResource) Configure(ctx context.Context, req resource.Configur
r.client = client
}

// ensureQuotedTXT wraps s in a single pair of double quotes if not already wrapped.
// It tolerates surrounding whitespace and preserves already-quoted strings.
func ensureQuotedTXT(s string) string {
cs := strings.TrimSpace(s)
if cs == "" {
return s
}
if strings.HasPrefix(cs, "\"") && strings.HasSuffix(cs, "\"") {
return s
}
return `"` + s + `"`
}

// stripOuterQuotes removes a single surrounding pair of quotes if present.
// Used to normalize state and avoid quoted/unquoted drift for TXT records.
func stripOuterQuotes(s string) string {
cs := strings.TrimSpace(s)
if len(cs) >= 2 && strings.HasPrefix(cs, "\"") && strings.HasSuffix(cs, "\"") {
return cs[1 : len(cs)-1]
}
return s
}

func (r *DNSRecordResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
var data *DNSRecordModel

Expand All @@ -75,6 +98,18 @@ func (r *DNSRecordResource) Create(ctx context.Context, req resource.CreateReque
return
}

// Auto-quote TXT content prior to serialization (only when using content, not data)
if data != nil &&
!data.Type.IsNull() && !data.Type.IsUnknown() &&
strings.EqualFold(data.Type.ValueString(), "TXT") &&
data.Data == nil &&
!data.Content.IsNull() && !data.Content.IsUnknown() {
val := data.Content.ValueString()
if val != "" {
data.Content = types.StringValue(ensureQuotedTXT(val))
}
}

dataBytes, err := data.MarshalJSON()
if err != nil {
resp.Diagnostics.AddError("failed to serialize http request", err.Error())
Expand Down Expand Up @@ -103,6 +138,14 @@ func (r *DNSRecordResource) Create(ctx context.Context, req resource.CreateReque
}
data = &env.Result

// Normalize state: store TXT content unquoted to avoid perpetual diffs
if data != nil &&
!data.Type.IsNull() && strings.EqualFold(data.Type.ValueString(), "TXT") &&
data.Data == nil &&
!data.Content.IsNull() && !data.Content.IsUnknown() {
data.Content = types.StringValue(stripOuterQuotes(data.Content.ValueString()))
}

resp.Diagnostics.Append(resp.State.Set(ctx, &data)...)
}

Expand All @@ -123,6 +166,18 @@ func (r *DNSRecordResource) Update(ctx context.Context, req resource.UpdateReque
return
}

// Auto-quote TXT content prior to serialization (only when using content, not data)
if data != nil &&
!data.Type.IsNull() && !data.Type.IsUnknown() &&
strings.EqualFold(data.Type.ValueString(), "TXT") &&
data.Data == nil &&
!data.Content.IsNull() && !data.Content.IsUnknown() {
val := data.Content.ValueString()
if val != "" {
data.Content = types.StringValue(ensureQuotedTXT(val))
}
}

dataBytes, err := data.MarshalJSONForUpdate(*state)
if err != nil {
resp.Diagnostics.AddError("failed to serialize http request", err.Error())
Expand Down Expand Up @@ -152,6 +207,14 @@ func (r *DNSRecordResource) Update(ctx context.Context, req resource.UpdateReque
}
data = &env.Result

// Normalize state: store TXT content unquoted to avoid perpetual diffs
if data != nil &&
!data.Type.IsNull() && strings.EqualFold(data.Type.ValueString(), "TXT") &&
data.Data == nil &&
!data.Content.IsNull() && !data.Content.IsUnknown() {
data.Content = types.StringValue(stripOuterQuotes(data.Content.ValueString()))
}

resp.Diagnostics.Append(resp.State.Set(ctx, &data)...)
}

Expand Down Expand Up @@ -192,6 +255,14 @@ func (r *DNSRecordResource) Read(ctx context.Context, req resource.ReadRequest,
}
data = &env.Result

// Normalize state: store TXT content unquoted to avoid perpetual diffs
if data != nil &&
!data.Type.IsNull() && strings.EqualFold(data.Type.ValueString(), "TXT") &&
data.Data == nil &&
!data.Content.IsNull() && !data.Content.IsUnknown() {
data.Content = types.StringValue(stripOuterQuotes(data.Content.ValueString()))
}

resp.Diagnostics.Append(resp.State.Set(ctx, &data)...)
}

Expand Down Expand Up @@ -262,6 +333,14 @@ func (r *DNSRecordResource) ImportState(ctx context.Context, req resource.Import
}
data = &env.Result

// Normalize state: store TXT content unquoted to avoid perpetual diffs
if data != nil &&
!data.Type.IsNull() && strings.EqualFold(data.Type.ValueString(), "TXT") &&
data.Data == nil &&
!data.Content.IsNull() && !data.Content.IsUnknown() {
data.Content = types.StringValue(stripOuterQuotes(data.Content.ValueString()))
}

resp.Diagnostics.Append(resp.State.Set(ctx, &data)...)
}

Expand Down