feat(TALE-30): add support for new DNS configs
This is a breaking change to support 0.23-beta2
This commit is contained in:
parent
b8999161a2
commit
5a46fd0a97
@ -47,7 +47,7 @@ export default function AddDNS({ records }: Props) {
|
||||
setIp('')
|
||||
|
||||
submit({
|
||||
'dns_config.extra_records': [
|
||||
'dns.extra_records': [
|
||||
...records,
|
||||
{
|
||||
name,
|
||||
|
||||
@ -55,7 +55,7 @@ export default function AddNameserver({ nameservers }: Props) {
|
||||
}
|
||||
|
||||
submit({
|
||||
'dns_config.restricted_nameservers': splitNs,
|
||||
'dns.nameservers.split': splitNs,
|
||||
}, {
|
||||
method: 'PATCH',
|
||||
encType: 'application/json',
|
||||
@ -65,7 +65,7 @@ export default function AddNameserver({ nameservers }: Props) {
|
||||
globalNs.push(ns)
|
||||
|
||||
submit({
|
||||
'dns_config.nameservers': globalNs,
|
||||
'dns.nameservers.global': globalNs,
|
||||
}, {
|
||||
method: 'PATCH',
|
||||
encType: 'application/json',
|
||||
|
||||
@ -63,7 +63,7 @@ export default function DNS({ records, isDisabled }: Props) {
|
||||
isDisabled={isDisabled}
|
||||
onPress={() => {
|
||||
submit({
|
||||
'dns_config.extra_records': records
|
||||
'dns.extra_records': records
|
||||
.filter((_, i) => i !== index),
|
||||
}, {
|
||||
method: 'PATCH',
|
||||
|
||||
@ -134,7 +134,7 @@ export default function Domains({ baseDomain, searchDomains, disabled }: Propert
|
||||
onPress={() => {
|
||||
fetcher.submit({
|
||||
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||
'dns_config.domains': [...localDomains, newDomain]
|
||||
'dns.search_domains': [...localDomains, newDomain]
|
||||
}, {
|
||||
method: 'PATCH',
|
||||
encType: 'application/json'
|
||||
@ -212,8 +212,7 @@ function Domain({ domain, id, localDomains, isDrag, disabled, fetcher }: DomainP
|
||||
isDisabled={disabled}
|
||||
onPress={() => {
|
||||
fetcher.submit({
|
||||
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||
'dns_config.domains': localDomains.filter((_, index) => index !== id - 1)
|
||||
'dns.search_domains': localDomains.filter((_, index) => index !== id - 1)
|
||||
}, {
|
||||
method: 'PATCH',
|
||||
encType: 'application/json'
|
||||
|
||||
@ -42,7 +42,7 @@ export default function Modal({ isEnabled, disabled }: Properties) {
|
||||
onPress={() => {
|
||||
fetcher.submit({
|
||||
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||
'dns_config.magic_dns': !isEnabled
|
||||
'dns.magic_dns': !isEnabled
|
||||
}, {
|
||||
method: 'PATCH',
|
||||
encType: 'application/json'
|
||||
|
||||
@ -11,11 +11,10 @@ import AddNameserver from './dialogs/nameserver'
|
||||
|
||||
interface Props {
|
||||
nameservers: Record<string, string[]>
|
||||
override: boolean
|
||||
isDisabled: boolean
|
||||
}
|
||||
|
||||
export default function Nameservers({ nameservers, override, isDisabled }: Props) {
|
||||
export default function Nameservers({ nameservers, isDisabled }: Props) {
|
||||
return (
|
||||
<div className="flex flex-col w-2/3">
|
||||
<h1 className="text-2xl font-medium mb-4">Nameservers</h1>
|
||||
@ -37,7 +36,6 @@ export default function Nameservers({ nameservers, override, isDisabled }: Props
|
||||
isGlobal={key === 'global'}
|
||||
isDisabled={isDisabled}
|
||||
nameservers={nameservers[key]}
|
||||
override={override}
|
||||
name={key}
|
||||
/>
|
||||
))}
|
||||
@ -57,11 +55,9 @@ interface ListProps {
|
||||
isDisabled: boolean
|
||||
nameservers: string[]
|
||||
name: string
|
||||
override: boolean
|
||||
}
|
||||
|
||||
function NameserverList({ isGlobal, isDisabled, nameservers, name, override }: ListProps) {
|
||||
const [localOverride, setLocalOverride] = useState(override)
|
||||
function NameserverList({ isGlobal, isDisabled, nameservers, name }: ListProps) {
|
||||
const submit = useSubmit()
|
||||
|
||||
return (
|
||||
@ -70,30 +66,6 @@ function NameserverList({ isGlobal, isDisabled, nameservers, name, override }: L
|
||||
<h2 className="text-md font-medium opacity-80">
|
||||
{isGlobal ? 'Global Nameservers' : name}
|
||||
</h2>
|
||||
{isGlobal
|
||||
? (
|
||||
<div className="flex gap-2 items-center">
|
||||
<span className="text-sm opacity-50">
|
||||
Override local DNS
|
||||
</span>
|
||||
<Switch
|
||||
label="Override local DNS"
|
||||
defaultSelected={localOverride}
|
||||
isDisabled={isDisabled}
|
||||
onChange={() => {
|
||||
submit({
|
||||
'dns_config.override_local_dns': !localOverride,
|
||||
}, {
|
||||
method: 'PATCH',
|
||||
encType: 'application/json',
|
||||
})
|
||||
|
||||
setLocalOverride(!localOverride)
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
: undefined}
|
||||
</div>
|
||||
<TableList>
|
||||
{nameservers.map((ns, index) => (
|
||||
@ -111,14 +83,14 @@ function NameserverList({ isGlobal, isDisabled, nameservers, name, override }: L
|
||||
onPress={() => {
|
||||
if (isGlobal) {
|
||||
submit({
|
||||
'dns_config.nameservers': nameservers
|
||||
'dns.nameservers.global': nameservers
|
||||
.filter((_, i) => i !== index),
|
||||
}, {
|
||||
method: 'PATCH',
|
||||
encType: 'application/json',
|
||||
})
|
||||
} else {
|
||||
const key = `dns_config.restricted_nameservers."${name}"`
|
||||
const key = `dns.nameservers.split."${name}"`
|
||||
submit({
|
||||
[key]: nameservers
|
||||
.filter((_, i) => i !== index),
|
||||
|
||||
@ -80,7 +80,7 @@ export default function Modal({ name, disabled }: Properties) {
|
||||
variant='confirm'
|
||||
onPress={() => {
|
||||
fetcher.submit({
|
||||
'dns_config.base_domain': newName
|
||||
'dns.base_domain': newName
|
||||
}, {
|
||||
method: 'PATCH',
|
||||
encType: 'application/json'
|
||||
|
||||
@ -24,13 +24,12 @@ export async function loader() {
|
||||
const config = await loadConfig()
|
||||
const dns = {
|
||||
prefixes: config.prefixes,
|
||||
magicDns: config.dns_config.magic_dns,
|
||||
baseDomain: config.dns_config.base_domain,
|
||||
overrideLocal: config.dns_config.override_local_dns,
|
||||
nameservers: config.dns_config.nameservers,
|
||||
splitDns: config.dns_config.restricted_nameservers,
|
||||
searchDomains: config.dns_config.domains,
|
||||
extraRecords: config.dns_config.extra_records,
|
||||
magicDns: config.dns.magic_dns,
|
||||
baseDomain: config.dns.base_domain,
|
||||
nameservers: config.dns.nameservers.global,
|
||||
splitDns: config.dns.nameservers.split,
|
||||
searchDomains: config.dns.search_domains,
|
||||
extraRecords: config.dns.extra_records,
|
||||
}
|
||||
|
||||
return {
|
||||
@ -87,7 +86,6 @@ export default function Page() {
|
||||
<RenameModal name={data.baseDomain} disabled={!data.config.write} />
|
||||
<Nameservers
|
||||
nameservers={allNs}
|
||||
override={data.overrideLocal}
|
||||
isDisabled={!data.config.write}
|
||||
/>
|
||||
|
||||
|
||||
@ -27,8 +27,8 @@ export async function loader({ request, params }: LoaderFunctionArgs) {
|
||||
|
||||
if (context.config.read) {
|
||||
const config = await loadConfig()
|
||||
if (config.dns_config.magic_dns) {
|
||||
magic = config.dns_config.base_domain
|
||||
if (config.dns.magic_dns) {
|
||||
magic = config.dns.base_domain
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -29,8 +29,8 @@ export async function loader({ request }: LoaderFunctionArgs) {
|
||||
|
||||
if (context.config.read) {
|
||||
const config = await loadConfig()
|
||||
if (config.dns_config.magic_dns) {
|
||||
magic = config.dns_config.base_domain
|
||||
if (config.dns.magic_dns) {
|
||||
magic = config.dns.base_domain
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -41,8 +41,8 @@ export async function loader({ request }: LoaderFunctionArgs) {
|
||||
|
||||
if (context.config.read) {
|
||||
const config = await loadConfig()
|
||||
if (config.dns_config.magic_dns) {
|
||||
magic = config.dns_config.base_domain
|
||||
if (config.dns.magic_dns) {
|
||||
magic = config.dns.base_domain
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -89,18 +89,20 @@ const HeadscaleConfig = z.object({
|
||||
v6: z.string(),
|
||||
}),
|
||||
|
||||
dns_config: z.object({
|
||||
override_local_dns: goBool.default(false),
|
||||
nameservers: z.array(z.string()).default([]),
|
||||
restricted_nameservers: z.record(z.array(z.string())).default({}),
|
||||
domains: z.array(z.string()).default([]),
|
||||
dns: z.object({
|
||||
magic_dns: goBool.default(true),
|
||||
base_domain: z.string().default('headscale.net'),
|
||||
nameservers: z.object({
|
||||
global: z.array(z.string()).default([]),
|
||||
split: z.record(z.array(z.string())).default({}),
|
||||
}).default({ global: [], split: {} }),
|
||||
search_domains: z.array(z.string()).default([]),
|
||||
extra_records: z.array(z.object({
|
||||
name: z.string(),
|
||||
type: z.literal('A'),
|
||||
value: z.string(),
|
||||
})).default([]),
|
||||
magic_dns: goBool.default(false),
|
||||
base_domain: z.string().default('headscale.net'),
|
||||
use_username_in_magic_dns: goBool.default(false),
|
||||
}),
|
||||
|
||||
oidc: z.object({
|
||||
@ -225,11 +227,12 @@ export async function loadConfig(path?: string) {
|
||||
v6: '',
|
||||
},
|
||||
|
||||
dns_config: loaded.dns_config ?? {
|
||||
override_local_dns: false,
|
||||
nameservers: [],
|
||||
restricted_nameservers: {},
|
||||
domains: [],
|
||||
dns: loaded.dns ?? {
|
||||
nameservers: {
|
||||
global: [],
|
||||
split: {},
|
||||
},
|
||||
search_domains: [],
|
||||
extra_records: [],
|
||||
magic_dns: false,
|
||||
base_domain: 'headscale.net',
|
||||
|
||||
@ -198,7 +198,7 @@ policy:
|
||||
# - https://tailscale.com/kb/1081/magicdns/
|
||||
# - https://tailscale.com/blog/2021-09-private-dns-with-magicdns/
|
||||
#
|
||||
dns_config:
|
||||
dns_config2:
|
||||
# Whether to prefer using Headscale provided DNS or use local.
|
||||
override_local_dns: true
|
||||
|
||||
@ -259,6 +259,64 @@ dns_config:
|
||||
type: A
|
||||
value: 1.1.1.1
|
||||
|
||||
dns:
|
||||
# Whether to use [MagicDNS](https://tailscale.com/kb/1081/magicdns/).
|
||||
# Only works if there is at least a nameserver defined.
|
||||
magic_dns: true
|
||||
|
||||
# Defines the base domain to create the hostnames for MagicDNS.
|
||||
# This domain _must_ be different from the server_url domain.
|
||||
# `base_domain` must be a FQDN, without the trailing dot.
|
||||
# The FQDN of the hosts will be
|
||||
# `hostname.base_domain` (e.g., _myhost.example.com_).
|
||||
base_domain: example.com
|
||||
|
||||
# List of DNS servers to expose to clients.
|
||||
nameservers:
|
||||
global:
|
||||
- 1.1.1.1
|
||||
- 1.0.0.1
|
||||
- 2606:4700:4700::1111
|
||||
- 2606:4700:4700::1001
|
||||
|
||||
# NextDNS (see https://tailscale.com/kb/1218/nextdns/).
|
||||
# "abc123" is example NextDNS ID, replace with yours.
|
||||
# - https://dns.nextdns.io/abc123
|
||||
|
||||
# Split DNS (see https://tailscale.com/kb/1054/dns/),
|
||||
# a map of domains and which DNS server to use for each.
|
||||
split:
|
||||
{}
|
||||
# foo.bar.com:
|
||||
# - 1.1.1.1
|
||||
# darp.headscale.net:
|
||||
# - 1.1.1.1
|
||||
# - 8.8.8.8
|
||||
|
||||
# Set custom DNS search domains. With MagicDNS enabled,
|
||||
# your tailnet base_domain is always the first search domain.
|
||||
search_domains: []
|
||||
|
||||
# Extra DNS records
|
||||
# so far only A-records are supported (on the tailscale side)
|
||||
# See https://github.com/juanfont/headscale/blob/main/docs/dns-records.md#Limitations
|
||||
extra_records: []
|
||||
# - name: "grafana.myvpn.example.com"
|
||||
# type: "A"
|
||||
# value: "100.64.0.3"
|
||||
#
|
||||
# # you can also put it in one line
|
||||
# - { name: "prometheus.myvpn.example.com", type: "A", value: "100.64.0.3" }
|
||||
|
||||
# DEPRECATED
|
||||
# Use the username as part of the DNS name for nodes, with this option enabled:
|
||||
# node1.username.example.com
|
||||
# while when this is disabled:
|
||||
# node1.example.com
|
||||
# This is a legacy option as Headscale has have this wrongly implemented
|
||||
# while in upstream Tailscale, the username is not included.
|
||||
use_username_in_magic_dns: false
|
||||
|
||||
# Unix socket used for the CLI to connect without authentication
|
||||
# Note: for production you will want to set this to something like:
|
||||
unix_socket: /var/run/headscale/headscale.sock
|
||||
|
||||
Loading…
Reference in New Issue
Block a user