Skip to content
Closed
Show file tree
Hide file tree
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
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import { Input } from '@/components/ui/input';
import { Spinner } from '@/components/ui/spinner';
import { m } from '@/paraglide/messages';
import { useSetIngress } from '../hooks/useIngress';
import { dnsRecordType } from '../lib/publicIp';
import { DnsRecordGuide } from './DnsRecordGuide';

/**
Expand Down Expand Up @@ -91,7 +92,10 @@ export function BindDomainDialog({
<DnsRecordGuide
intro={m.domains_bind_step1()}
rows={[
{ label: m.domains_record_type(), value: 'A' },
{
label: m.domains_record_type(),
value: publicIp ? dnsRecordType(publicIp) : 'A',
},
publicIp
? {
label: m.domains_record_value(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import { useConfig } from '@/features/settings/hooks/useConfig';
import { useUpdateSettings } from '@/features/settings/hooks/useUpdateSettings';
import { updateSettings } from '@/lib/api';
import { m } from '@/paraglide/messages';
import { dnsRecordType } from '../lib/publicIp';
import { DnsRecordGuide } from './DnsRecordGuide';

/**
Expand Down Expand Up @@ -118,7 +119,10 @@ function DomainDialog({
label: m.domains_sandbox_record_host(),
value: `*.${domain || m.domains_sandbox_field_placeholder()}`,
},
{ label: m.domains_record_type(), value: 'A' },
{
label: m.domains_record_type(),
value: publicIp ? dnsRecordType(publicIp) : 'A',
},
publicIp
? {
label: m.domains_record_value(),
Expand Down
18 changes: 18 additions & 0 deletions packages/console/src/features/ingress/lib/publicIp.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { describe, expect, it } from 'vitest';
import { dnsRecordType } from './publicIp';

describe('dnsRecordType', () => {
it('labels an IPv4 address as an A record', () => {
expect(dnsRecordType('203.0.113.10')).toBe('A');
});

it('labels an IPv6 address as an AAAA record, not A', () => {
expect(dnsRecordType('2001:db8::10')).toBe('AAAA');
});

it('labels a full-form IPv6 address as AAAA too', () => {
expect(dnsRecordType('2001:0db8:0000:0000:0000:0000:0000:0010')).toBe(
'AAAA',
);
});
});
12 changes: 12 additions & 0 deletions packages/console/src/features/ingress/lib/publicIp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,15 @@ export function detectPublicIp(statuses: IngressDomainStatus[]): string | null {
);
return (here ?? ready)?.probe.dnsAddresses[0] ?? null;
}

/**
* detectPublicIp picks one address without keeping track of its family, so
* the DNS dialogs cannot just hard-code "A" as the record type: an
* IPv6-only probe would then tell the operator to create an A record for a
* value Node itself classifies as invalid for that record type. A bare
* colon check is enough here, every IPv6 textual form has one and no IPv4
* dotted-quad ever does.
*/
export function dnsRecordType(ip: string): 'A' | 'AAAA' {
return ip.includes(':') ? 'AAAA' : 'A';
}