Skip to content

Commit cef3893

Browse files
committed
add support for updating DNS TXT records with values > 255 characters
1 parent 6c7e5df commit cef3893

File tree

3 files changed

+63
-1
lines changed

3 files changed

+63
-1
lines changed

internal/cmd/dns/record-set/update/update.go

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package update
33
import (
44
"context"
55
"fmt"
6+
"math"
67

78
"github.com/stackitcloud/stackit-cli/internal/pkg/args"
89
"github.com/stackitcloud/stackit-cli/internal/pkg/errors"
@@ -28,6 +29,7 @@ const (
2829
nameFlag = "name"
2930
recordFlag = "record"
3031
ttlFlag = "ttl"
32+
txtType = "TXT"
3133
)
3234

3335
type inputModel struct {
@@ -38,6 +40,7 @@ type inputModel struct {
3840
Name *string
3941
Records *[]string
4042
TTL *int64
43+
Type *string
4144
}
4245

4346
func NewCmd(p *print.Printer) *cobra.Command {
@@ -76,6 +79,12 @@ func NewCmd(p *print.Printer) *cobra.Command {
7679
recordSetLabel = model.RecordSetId
7780
}
7881

82+
typeLabel, err := dnsUtils.GetRecordSetType(ctx, apiClient, model.ProjectId, model.ZoneId, model.RecordSetId)
83+
if err != nil {
84+
p.Debug(print.ErrorLevel, "get record set type: %v", err)
85+
}
86+
model.Type = typeLabel
87+
7988
if !model.AssumeYes {
8089
prompt := fmt.Sprintf("Are you sure you want to update record set %s of zone %s?", recordSetLabel, zoneLabel)
8190
err = p.PromptForConfirmation(prompt)
@@ -170,7 +179,23 @@ func buildRequest(ctx context.Context, model *inputModel, apiClient *dns.APIClie
170179
if model.Records != nil {
171180
records = utils.Ptr(make([]dns.RecordPayload, 0))
172181
for _, r := range *model.Records {
173-
records = utils.Ptr(append(*records, dns.RecordPayload{Content: utils.Ptr(r)}))
182+
result := r
183+
if len(r) > 255 && utils.PtrString(model.Type) == txtType {
184+
result = ""
185+
length := float64(len(r))
186+
chunks := int(math.Ceil(length / 255))
187+
for i := range chunks {
188+
skip := 255 * i
189+
if i == chunks-1 {
190+
// Append the left record content
191+
result += fmt.Sprintf("%q", r[0+skip:])
192+
} else {
193+
// Add 255 characters of the record data quoted to the result
194+
result += fmt.Sprintf("%q ", r[0+skip:255+skip])
195+
}
196+
}
197+
}
198+
records = utils.Ptr(append(*records, dns.RecordPayload{Content: utils.Ptr(result)}))
174199
}
175200
}
176201

internal/cmd/dns/record-set/update/update_test.go

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ package update
22

33
import (
44
"context"
5+
"fmt"
6+
"strings"
57
"testing"
68

79
"github.com/stackitcloud/stackit-cli/internal/pkg/globalflags"
@@ -24,6 +26,12 @@ var testProjectId = uuid.NewString()
2426
var testZoneId = uuid.NewString()
2527
var testRecordSetId = uuid.NewString()
2628

29+
var recordTxtOver255Char = []string{
30+
"foobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoo",
31+
"foobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoo",
32+
"foobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobar",
33+
}
34+
2735
func fixtureArgValues(mods ...func(argValues []string)) []string {
2836
argValues := []string{
2937
testRecordSetId,
@@ -330,6 +338,26 @@ func TestBuildRequest(t *testing.T) {
330338
expectedRequest: testClient.PartialUpdateRecordSet(testCtx, testProjectId, testZoneId, testRecordSetId).
331339
PartialUpdateRecordSetPayload(dns.PartialUpdateRecordSetPayload{}),
332340
},
341+
{
342+
description: "update TXT record with > 255 characters",
343+
model: fixtureInputModel(func(model *inputModel) {
344+
model.Type = utils.Ptr(txtType)
345+
model.Records = utils.Ptr([]string{strings.Join(recordTxtOver255Char, "")})
346+
}),
347+
expectedRequest: testClient.PartialUpdateRecordSet(testCtx, testProjectId, testZoneId, testRecordSetId).
348+
PartialUpdateRecordSetPayload(dns.PartialUpdateRecordSetPayload{
349+
Name: utils.Ptr("example.com"),
350+
Records: &[]dns.RecordPayload{
351+
{
352+
Content: utils.Ptr(
353+
fmt.Sprintf("\"%s\"", strings.Join(recordTxtOver255Char, "\" \"")),
354+
),
355+
},
356+
},
357+
Comment: utils.Ptr("comment"),
358+
Ttl: utils.Ptr(int64(3600)),
359+
}),
360+
},
333361
}
334362

335363
for _, tt := range tests {

internal/pkg/services/dns/utils/utils.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package utils
33
import (
44
"context"
55
"fmt"
6+
"github.com/stackitcloud/stackit-cli/internal/pkg/utils"
67

78
"github.com/stackitcloud/stackit-sdk-go/services/dns"
89
)
@@ -27,3 +28,11 @@ func GetRecordSetName(ctx context.Context, apiClient DNSClient, projectId, zoneI
2728
}
2829
return *resp.Rrset.Name, nil
2930
}
31+
32+
func GetRecordSetType(ctx context.Context, apiClient DNSClient, projectId, zoneId, recordSetId string) (*string, error) {
33+
resp, err := apiClient.GetRecordSetExecute(ctx, projectId, zoneId, recordSetId)
34+
if err != nil {
35+
return utils.Ptr(""), fmt.Errorf("get DNS recordset: %w", err)
36+
}
37+
return resp.Rrset.Type, nil
38+
}

0 commit comments

Comments
 (0)