Skip to content

Commit 9d6ff92

Browse files
committed
roachprod: add A records during cluster create
Release note: none. Epic: none.
1 parent 9ddf582 commit 9d6ff92

File tree

9 files changed

+86
-23
lines changed

9 files changed

+86
-23
lines changed

pkg/roachprod/cloud/cluster_cloud.go

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -540,9 +540,16 @@ func DestroyCluster(l *logger.Logger, c *Cluster) error {
540540
// DNS entries are destroyed first to ensure that the GC job will not try
541541
// and clean-up entries prematurely.
542542
stopSpinner := ui.NewDefaultSpinner(l, "Destroying DNS entries").Start()
543+
publicRecords := make([]string, 0, len(c.VMs))
544+
for _, v := range c.VMs {
545+
publicRecords = append(publicRecords, v.PublicDNS)
546+
}
543547
dnsErr := vm.FanOutDNS(c.VMs, func(p vm.DNSProvider, vms vm.List) error {
544-
return p.DeleteRecordsBySubdomain(context.Background(), c.Name)
548+
publicRecordsErr := p.DeletePublicRecordsByName(context.Background(), publicRecords...)
549+
srvRecordsErr := p.DeleteSRVRecordsBySubdomain(context.Background(), c.Name)
550+
return errors.CombineErrors(publicRecordsErr, srvRecordsErr)
545551
})
552+
546553
stopSpinner()
547554

548555
stopSpinner = ui.NewDefaultSpinner(l, "Destroying VMs").Start()

pkg/roachprod/cloud/gc.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -570,7 +570,7 @@ func GCDNS(l *logger.Logger, cloud *Cloud, dryrun bool) error {
570570
sort.Strings(recordNames)
571571

572572
if err := destroyResource(dryrun, func() error {
573-
return p.DeleteRecordsByName(ctx, recordNames...)
573+
return p.DeleteSRVRecordsByName(ctx, recordNames...)
574574
}); err != nil {
575575
return err
576576
}

pkg/roachprod/install/services_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -334,7 +334,7 @@ func TestMultipleRegistrations(t *testing.T) {
334334
verify := func(c *SyncedCluster, servicesToRegister [][]ServiceDesc) bool {
335335
for _, services := range servicesToRegister {
336336
if len(services) == 0 {
337-
err := testDNS.DeleteRecordsBySubdomain(ctx, c.Name)
337+
err := testDNS.DeleteSRVRecordsBySubdomain(ctx, c.Name)
338338
require.NoError(t, err)
339339
continue
340340
}

pkg/roachprod/roachprod.go

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1763,6 +1763,11 @@ func Create(
17631763
// No need for ssh for local clusters.
17641764
return LoadClusters()
17651765
}
1766+
1767+
if err := CreatePublicDNS(ctx, l, clusterName); err != nil {
1768+
l.Printf("Failed to create DNS for cluster %s: %v", clusterName, err)
1769+
}
1770+
17661771
l.Printf("Created cluster %s; setting up SSH...", clusterName)
17671772
return SetupSSH(ctx, l, clusterName, false /* sync */)
17681773
}
@@ -2584,8 +2589,34 @@ func DestroyDNS(ctx context.Context, l *logger.Logger, clusterName string) error
25842589
if err != nil {
25852590
return err
25862591
}
2592+
publicRecords := make([]string, 0, len(c.VMs))
2593+
for _, v := range c.VMs {
2594+
publicRecords = append(publicRecords, v.PublicDNS)
2595+
}
2596+
2597+
return vm.FanOutDNS(c.VMs, func(p vm.DNSProvider, vms vm.List) error {
2598+
return errors.CombineErrors(
2599+
p.DeleteSRVRecordsBySubdomain(ctx, c.Name),
2600+
p.DeletePublicRecordsByName(ctx, publicRecords...),
2601+
)
2602+
})
2603+
}
2604+
2605+
// CreatePublicDNS creates or updates the public A records for the given cluster.
2606+
func CreatePublicDNS(ctx context.Context, l *logger.Logger, clusterName string) error {
2607+
c, err := GetClusterFromCache(l, clusterName)
2608+
if err != nil {
2609+
return err
2610+
}
2611+
25872612
return vm.FanOutDNS(c.VMs, func(p vm.DNSProvider, vms vm.List) error {
2588-
return p.DeleteRecordsBySubdomain(ctx, c.Name)
2613+
recs := make([]vm.DNSRecord, 0, len(c.VMs))
2614+
for _, v := range c.VMs {
2615+
rec := vm.CreateDNSRecord(v.PublicDNS, vm.A, v.PublicIP, 60)
2616+
rec.Public = true
2617+
recs = append(recs, rec)
2618+
}
2619+
return p.CreateRecords(ctx, recs...)
25892620
})
25902621
}
25912622

pkg/roachprod/vm/dns.go

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ type DNSRecord struct {
3838
Data string `json:"data"`
3939
// TTL is the time to live of the DNS record.
4040
TTL int `json:"TTL"`
41+
// Public indicates whether the DNS should be published in the public zone.
42+
Public bool
4143
}
4244

4345
// DNSProvider is an optional capability for a Provider that provides DNS
@@ -52,10 +54,12 @@ type DNSProvider interface {
5254
LookupSRVRecords(ctx context.Context, name string) ([]DNSRecord, error)
5355
// ListRecords lists all DNS records managed for the zone.
5456
ListRecords(ctx context.Context) ([]DNSRecord, error)
55-
// DeleteRecordsBySubdomain deletes all DNS records with the given subdomain.
56-
DeleteRecordsBySubdomain(ctx context.Context, subdomain string) error
57-
// DeleteRecordsByName deletes all DNS records with the given name.
58-
DeleteRecordsByName(ctx context.Context, names ...string) error
57+
// DeleteSRVRecordsBySubdomain deletes all DNS SRV records with the given subdomain.
58+
DeleteSRVRecordsBySubdomain(ctx context.Context, subdomain string) error
59+
// DeleteRecordsByName deletes all DNS SRV records with the given name.
60+
DeleteSRVRecordsByName(ctx context.Context, names ...string) error
61+
// DeletePublicRecordsByName deletes all DNS A records named.
62+
DeletePublicRecordsByName(ctx context.Context, names ...string) error
5963
// Domain returns the domain name (zone) of the DNS provider.
6064
Domain() string
6165
}

pkg/roachprod/vm/gce/dns.go

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -156,10 +156,14 @@ func (n *dnsProvider) CreateRecords(ctx context.Context, records ...vm.DNSRecord
156156
firstRecord := recordGroup[0]
157157
data := maps.Keys(combinedRecords)
158158
sort.Strings(data)
159+
zone := n.managedZone
160+
if firstRecord.Public {
161+
zone = n.publicZone
162+
}
159163
args := []string{"--project", n.dnsProject, "dns", "record-sets", command, name,
160164
"--type", string(firstRecord.Type),
161165
"--ttl", strconv.Itoa(firstRecord.TTL),
162-
"--zone", n.managedZone,
166+
"--zone", zone,
163167
"--rrdatas", strings.Join(data, ","),
164168
}
165169
cmd := exec.CommandContext(ctx, "gcloud", args...)
@@ -170,10 +174,10 @@ func (n *dnsProvider) CreateRecords(ctx context.Context, records ...vm.DNSRecord
170174
n.clearCacheEntry(name)
171175
return rperrors.TransientFailure(errors.Wrapf(err, "output: %s", out), dnsProblemLabel)
172176
}
173-
// If fastDNS is enabled, we need to wait for the records to become available
177+
// If fastDNS is enabled, we need to wait for the SRV records to become available
174178
// on the Google DNS servers.
175-
if config.FastDNS {
176-
err = n.waitForRecordsAvailable(ctx, maps.Values(combinedRecords)...)
179+
if config.FastDNS && !firstRecord.Public {
180+
err = n.waitForSRVRecordsAvailable(ctx, maps.Values(combinedRecords)...)
177181
if err != nil {
178182
return err
179183
}
@@ -210,13 +214,14 @@ func (n *dnsProvider) ListRecords(ctx context.Context) ([]vm.DNSRecord, error) {
210214
return n.listSRVRecords(ctx, "", dnsMaxResults)
211215
}
212216

213-
// DeleteRecordsByName implements the vm.DNSProvider interface.
214-
func (n *dnsProvider) DeleteRecordsByName(ctx context.Context, names ...string) error {
217+
func (n *dnsProvider) deleteRecords(
218+
ctx context.Context, zone string, recordType vm.DNSType, names ...string,
219+
) error {
215220
for _, name := range names {
216221
err := n.withRecordLock(name, func() error {
217222
args := []string{"--project", n.dnsProject, "dns", "record-sets", "delete", name,
218-
"--type", string(vm.SRV),
219-
"--zone", n.managedZone,
223+
"--type", string(recordType),
224+
"--zone", zone,
220225
}
221226
cmd := exec.CommandContext(ctx, "gcloud", args...)
222227
out, err := n.execFn(cmd)
@@ -235,8 +240,18 @@ func (n *dnsProvider) DeleteRecordsByName(ctx context.Context, names ...string)
235240
return nil
236241
}
237242

243+
// DeleteSRVRecordsByName implements the vm.DNSProvider interface.
244+
func (n *dnsProvider) DeleteSRVRecordsByName(ctx context.Context, names ...string) error {
245+
return n.deleteRecords(ctx, n.managedZone, vm.SRV, names...)
246+
}
247+
248+
// DeletePublicRecordsByName implements the vm.DNSProvider interface
249+
func (n *dnsProvider) DeletePublicRecordsByName(ctx context.Context, names ...string) error {
250+
return n.deleteRecords(ctx, n.publicZone, vm.A, names...)
251+
}
252+
238253
// DeleteRecordsBySubdomain implements the vm.DNSProvider interface.
239-
func (n *dnsProvider) DeleteRecordsBySubdomain(ctx context.Context, subdomain string) error {
254+
func (n *dnsProvider) DeleteSRVRecordsBySubdomain(ctx context.Context, subdomain string) error {
240255
suffix := fmt.Sprintf("%s.%s.", subdomain, n.Domain())
241256
records, err := n.listSRVRecords(ctx, suffix, dnsMaxResults)
242257
if err != nil {
@@ -256,7 +271,7 @@ func (n *dnsProvider) DeleteRecordsBySubdomain(ctx context.Context, subdomain st
256271
delete(names, name)
257272
}
258273
}
259-
return n.DeleteRecordsByName(ctx, maps.Keys(names)...)
274+
return n.DeleteSRVRecordsByName(ctx, maps.Keys(names)...)
260275
}
261276

262277
// Domain implements the vm.DNSProvider interface.

pkg/roachprod/vm/gce/fast_dns.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,9 @@ func googleDNSResolvers() []*net.Resolver {
3535

3636
// waitForRecordsAvailable waits for the DNS records to become available on all
3737
// the DNS servers through a standard net tools lookup.
38-
func (n *dnsProvider) waitForRecordsAvailable(ctx context.Context, records ...vm.DNSRecord) error {
38+
func (n *dnsProvider) waitForSRVRecordsAvailable(
39+
ctx context.Context, records ...vm.DNSRecord,
40+
) error {
3941
checkResolver := func(resolver *net.Resolver) error {
4042
type recordKey struct {
4143
name string

pkg/roachprod/vm/local/dns.go

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -82,8 +82,12 @@ func (n *dnsProvider) ListRecords(_ context.Context) ([]vm.DNSRecord, error) {
8282
return maps.Values(records), nil
8383
}
8484

85+
func (n *dnsProvider) DeletePublicRecordsByName(ctx context.Context, names ...string) error {
86+
return n.DeleteSRVRecordsByName(ctx, names...)
87+
}
88+
8589
// DeleteRecordsByName is part of the vm.DNSProvider interface.
86-
func (n *dnsProvider) DeleteRecordsByName(_ context.Context, names ...string) error {
90+
func (n *dnsProvider) DeleteSRVRecordsByName(_ context.Context, names ...string) error {
8791
unlock, err := lock.AcquireFilesystemLock(n.lockFilePath)
8892
if err != nil {
8993
return err
@@ -100,8 +104,8 @@ func (n *dnsProvider) DeleteRecordsByName(_ context.Context, names ...string) er
100104
return n.saveRecords(entries)
101105
}
102106

103-
// DeleteRecordsBySubdomain is part of the vm.DNSProvider interface.
104-
func (n *dnsProvider) DeleteRecordsBySubdomain(_ context.Context, subdomain string) error {
107+
// DeleteSRVRecordsBySubdomain is part of the vm.DNSProvider interface.
108+
func (n *dnsProvider) DeleteSRVRecordsBySubdomain(_ context.Context, subdomain string) error {
105109
unlock, err := lock.AcquireFilesystemLock(n.lockFilePath)
106110
if err != nil {
107111
return err

pkg/roachprod/vm/local/local.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ func DeleteCluster(l *logger.Logger, name string) error {
9393
// Local clusters are expected to specifically use the local DNS provider
9494
// implementation, and should clean up any DNS records in the local file
9595
// system cache.
96-
return p.DeleteRecordsBySubdomain(context.Background(), c.Name)
96+
return p.DeleteSRVRecordsBySubdomain(context.Background(), c.Name)
9797
}
9898

9999
// Clusters returns a list of all known local clusters.

0 commit comments

Comments
 (0)