mirror of
https://github.com/jsiebens/ionscale.git
synced 2026-03-31 15:07:49 +01:00
chore: use yaml-to-json library, giving better support for configuring third-party libs like libdns providers
This commit is contained in:
@@ -7,7 +7,6 @@ require (
|
|||||||
github.com/a-h/templ v0.2.663
|
github.com/a-h/templ v0.2.663
|
||||||
github.com/apparentlymart/go-cidr v1.1.0
|
github.com/apparentlymart/go-cidr v1.1.0
|
||||||
github.com/bufbuild/connect-go v1.10.0
|
github.com/bufbuild/connect-go v1.10.0
|
||||||
github.com/caarlos0/env/v6 v6.10.1
|
|
||||||
github.com/caddyserver/certmagic v0.20.0
|
github.com/caddyserver/certmagic v0.20.0
|
||||||
github.com/coreos/go-oidc/v3 v3.10.0
|
github.com/coreos/go-oidc/v3 v3.10.0
|
||||||
github.com/dustinkirkland/golang-petname v0.0.0-20240422154211-76c06c4bde6b
|
github.com/dustinkirkland/golang-petname v0.0.0-20240422154211-76c06c4bde6b
|
||||||
@@ -18,7 +17,6 @@ require (
|
|||||||
github.com/hashicorp/go-bexpr v0.1.14
|
github.com/hashicorp/go-bexpr v0.1.14
|
||||||
github.com/hashicorp/go-getter v1.7.4
|
github.com/hashicorp/go-getter v1.7.4
|
||||||
github.com/hashicorp/go-multierror v1.1.1
|
github.com/hashicorp/go-multierror v1.1.1
|
||||||
github.com/imdario/mergo v0.3.16
|
|
||||||
github.com/jsiebens/go-edit v0.1.0
|
github.com/jsiebens/go-edit v0.1.0
|
||||||
github.com/jsiebens/mockoidc v0.1.0-rc2
|
github.com/jsiebens/mockoidc v0.1.0-rc2
|
||||||
github.com/klauspost/compress v1.17.11
|
github.com/klauspost/compress v1.17.11
|
||||||
@@ -36,6 +34,7 @@ require (
|
|||||||
github.com/nleeper/goment v1.4.4
|
github.com/nleeper/goment v1.4.4
|
||||||
github.com/ory/dockertest/v3 v3.10.0
|
github.com/ory/dockertest/v3 v3.10.0
|
||||||
github.com/prometheus/client_golang v1.19.1
|
github.com/prometheus/client_golang v1.19.1
|
||||||
|
github.com/puzpuzpuz/xsync/v3 v3.5.1
|
||||||
github.com/rodaine/table v1.2.0
|
github.com/rodaine/table v1.2.0
|
||||||
github.com/sony/sonyflake v1.2.0
|
github.com/sony/sonyflake v1.2.0
|
||||||
github.com/spf13/cobra v1.8.1
|
github.com/spf13/cobra v1.8.1
|
||||||
@@ -55,6 +54,7 @@ require (
|
|||||||
gorm.io/gorm v1.25.9
|
gorm.io/gorm v1.25.9
|
||||||
gorm.io/plugin/prometheus v0.1.0
|
gorm.io/plugin/prometheus v0.1.0
|
||||||
inet.af/netaddr v0.0.0-20230525184311-b8eac61e914a
|
inet.af/netaddr v0.0.0-20230525184311-b8eac61e914a
|
||||||
|
sigs.k8s.io/yaml v1.4.0
|
||||||
tailscale.com v1.80.0
|
tailscale.com v1.80.0
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -191,7 +191,6 @@ require (
|
|||||||
github.com/prometheus/client_model v0.6.1 // indirect
|
github.com/prometheus/client_model v0.6.1 // indirect
|
||||||
github.com/prometheus/common v0.55.0 // indirect
|
github.com/prometheus/common v0.55.0 // indirect
|
||||||
github.com/prometheus/procfs v0.15.1 // indirect
|
github.com/prometheus/procfs v0.15.1 // indirect
|
||||||
github.com/puzpuzpuz/xsync/v3 v3.5.1 // indirect
|
|
||||||
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
|
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
|
||||||
github.com/safchain/ethtool v0.3.0 // indirect
|
github.com/safchain/ethtool v0.3.0 // indirect
|
||||||
github.com/sirupsen/logrus v1.9.3 // indirect
|
github.com/sirupsen/logrus v1.9.3 // indirect
|
||||||
|
|||||||
@@ -295,8 +295,6 @@ github.com/bits-and-blooms/bitset v1.13.0 h1:bAQ9OPNFYbGHV6Nez0tmNI0RiEu7/hxlYJR
|
|||||||
github.com/bits-and-blooms/bitset v1.13.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8=
|
github.com/bits-and-blooms/bitset v1.13.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8=
|
||||||
github.com/bufbuild/connect-go v1.10.0 h1:QAJ3G9A1OYQW2Jbk3DeoJbkCxuKArrvZgDt47mjdTbg=
|
github.com/bufbuild/connect-go v1.10.0 h1:QAJ3G9A1OYQW2Jbk3DeoJbkCxuKArrvZgDt47mjdTbg=
|
||||||
github.com/bufbuild/connect-go v1.10.0/go.mod h1:CAIePUgkDR5pAFaylSMtNK45ANQjp9JvpluG20rhpV8=
|
github.com/bufbuild/connect-go v1.10.0/go.mod h1:CAIePUgkDR5pAFaylSMtNK45ANQjp9JvpluG20rhpV8=
|
||||||
github.com/caarlos0/env/v6 v6.10.1 h1:t1mPSxNpei6M5yAeu1qtRdPAK29Nbcf/n3G7x+b3/II=
|
|
||||||
github.com/caarlos0/env/v6 v6.10.1/go.mod h1:hvp/ryKXKipEkcuYjs9mI4bBCg+UI0Yhgm5Zu0ddvwc=
|
|
||||||
github.com/caddyserver/certmagic v0.17.2/go.mod h1:ouWUuC490GOLJzkyN35eXfV8bSbwMwSf4bdhkIxtdQE=
|
github.com/caddyserver/certmagic v0.17.2/go.mod h1:ouWUuC490GOLJzkyN35eXfV8bSbwMwSf4bdhkIxtdQE=
|
||||||
github.com/caddyserver/certmagic v0.20.0 h1:bTw7LcEZAh9ucYCRXyCpIrSAGplplI0vGYJ4BpCQ/Fc=
|
github.com/caddyserver/certmagic v0.20.0 h1:bTw7LcEZAh9ucYCRXyCpIrSAGplplI0vGYJ4BpCQ/Fc=
|
||||||
github.com/caddyserver/certmagic v0.20.0/go.mod h1:N4sXgpICQUskEWpj7zVzvWD41p3NYacrNoZYiRM2jTg=
|
github.com/caddyserver/certmagic v0.20.0/go.mod h1:N4sXgpICQUskEWpj7zVzvWD41p3NYacrNoZYiRM2jTg=
|
||||||
@@ -590,8 +588,6 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:
|
|||||||
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||||
github.com/illarion/gonotify/v2 v2.0.3 h1:B6+SKPo/0Sw8cRJh1aLzNEeNVFfzE3c6N+o+vyxM+9A=
|
github.com/illarion/gonotify/v2 v2.0.3 h1:B6+SKPo/0Sw8cRJh1aLzNEeNVFfzE3c6N+o+vyxM+9A=
|
||||||
github.com/illarion/gonotify/v2 v2.0.3/go.mod h1:38oIJTgFqupkEydkkClkbL6i5lXV/bxdH9do5TALPEE=
|
github.com/illarion/gonotify/v2 v2.0.3/go.mod h1:38oIJTgFqupkEydkkClkbL6i5lXV/bxdH9do5TALPEE=
|
||||||
github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4=
|
|
||||||
github.com/imdario/mergo v0.3.16/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY=
|
|
||||||
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
|
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
|
||||||
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
|
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
|
||||||
github.com/insomniacslk/dhcp v0.0.0-20231206064809-8c70d406f6d2 h1:9K06NfxkBh25x56yVhWWlKFE8YpicaSfHwoV8SFbueA=
|
github.com/insomniacslk/dhcp v0.0.0-20231206064809-8c70d406f6d2 h1:9K06NfxkBh25x56yVhWWlKFE8YpicaSfHwoV8SFbueA=
|
||||||
@@ -1619,6 +1615,8 @@ modernc.org/token v1.1.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM=
|
|||||||
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
|
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
|
||||||
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
|
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
|
||||||
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
|
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
|
||||||
|
sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E=
|
||||||
|
sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY=
|
||||||
software.sslmate.com/src/go-pkcs12 v0.4.0 h1:H2g08FrTvSFKUj+D309j1DPfk5APnIdAQAB8aEykJ5k=
|
software.sslmate.com/src/go-pkcs12 v0.4.0 h1:H2g08FrTvSFKUj+D309j1DPfk5APnIdAQAB8aEykJ5k=
|
||||||
software.sslmate.com/src/go-pkcs12 v0.4.0/go.mod h1:Qiz0EyvDRJjjxGyUQa2cCNZn/wMyzrRJ/qcDXOQazLI=
|
software.sslmate.com/src/go-pkcs12 v0.4.0/go.mod h1:Qiz0EyvDRJjjxGyUQa2cCNZn/wMyzrRJ/qcDXOQazLI=
|
||||||
tailscale.com v1.80.0 h1:7joWtDtdHEHJvGmOag10RNITKp1I4Ts7Hrn6pU33/1I=
|
tailscale.com v1.80.0 h1:7joWtDtdHEHJvGmOag10RNITKp1I4Ts7Hrn6pU33/1I=
|
||||||
|
|||||||
+89
-57
@@ -2,17 +2,18 @@ package config
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/caddyserver/certmagic"
|
"github.com/caddyserver/certmagic"
|
||||||
"github.com/jsiebens/ionscale/internal/domain"
|
"github.com/jsiebens/ionscale/internal/domain"
|
||||||
"github.com/jsiebens/ionscale/internal/key"
|
"github.com/jsiebens/ionscale/internal/key"
|
||||||
"github.com/jsiebens/ionscale/internal/util"
|
"github.com/jsiebens/ionscale/internal/util"
|
||||||
"github.com/mitchellh/go-homedir"
|
"github.com/mitchellh/go-homedir"
|
||||||
"gopkg.in/yaml.v3"
|
|
||||||
"net/url"
|
"net/url"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"regexp"
|
"regexp"
|
||||||
|
"sigs.k8s.io/yaml"
|
||||||
"strings"
|
"strings"
|
||||||
"tailscale.com/tailcfg"
|
"tailscale.com/tailcfg"
|
||||||
tkey "tailscale.com/types/key"
|
tkey "tailscale.com/types/key"
|
||||||
@@ -88,7 +89,7 @@ func LoadConfig(path string) (*Config, error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
keepAliveInterval = cfg.PollNet.KeepAliveInterval
|
keepAliveInterval = time.Duration(cfg.PollNet.KeepAliveInterval)
|
||||||
magicDNSSuffix = cfg.DNS.MagicDNSSuffix
|
magicDNSSuffix = cfg.DNS.MagicDNSSuffix
|
||||||
|
|
||||||
if cfg.DNS.Provider.Zone != "" {
|
if cfg.DNS.Provider.Zone != "" {
|
||||||
@@ -116,7 +117,7 @@ func defaultConfig() *Config {
|
|||||||
AcmeCA: certmagic.LetsEncryptProductionCA,
|
AcmeCA: certmagic.LetsEncryptProductionCA,
|
||||||
},
|
},
|
||||||
PollNet: PollNet{
|
PollNet: PollNet{
|
||||||
KeepAliveInterval: defaultKeepAliveInterval,
|
KeepAliveInterval: Duration(defaultKeepAliveInterval),
|
||||||
},
|
},
|
||||||
DNS: DNS{
|
DNS: DNS{
|
||||||
MagicDNSSuffix: defaultMagicDNSSuffix,
|
MagicDNSSuffix: defaultMagicDNSSuffix,
|
||||||
@@ -142,21 +143,21 @@ type ServerKeys struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type Config struct {
|
type Config struct {
|
||||||
ListenAddr string `yaml:"listen_addr,omitempty"`
|
ListenAddr string `json:"listen_addr,omitempty"`
|
||||||
StunListenAddr string `yaml:"stun_listen_addr,omitempty"`
|
StunListenAddr string `json:"stun_listen_addr,omitempty"`
|
||||||
MetricsListenAddr string `yaml:"metrics_listen_addr,omitempty"`
|
MetricsListenAddr string `json:"metrics_listen_addr,omitempty"`
|
||||||
PublicAddr string `yaml:"public_addr,omitempty"`
|
PublicAddr string `json:"public_addr,omitempty"`
|
||||||
StunPublicAddr string `yaml:"stun_public_addr,omitempty"`
|
StunPublicAddr string `json:"stun_public_addr,omitempty"`
|
||||||
Tls Tls `yaml:"tls,omitempty"`
|
Tls Tls `json:"tls,omitempty"`
|
||||||
PollNet PollNet `yaml:"poll_net,omitempty"`
|
PollNet PollNet `json:"poll_net,omitempty"`
|
||||||
Keys Keys `yaml:"keys,omitempty"`
|
Keys Keys `json:"keys,omitempty"`
|
||||||
Database Database `yaml:"database,omitempty"`
|
Database Database `json:"database,omitempty"`
|
||||||
Auth Auth `yaml:"auth,omitempty"`
|
Auth Auth `json:"auth,omitempty"`
|
||||||
DNS DNS `yaml:"dns,omitempty"`
|
DNS DNS `json:"dns,omitempty"`
|
||||||
DERP DERP `yaml:"derp,omitempty"`
|
DERP DERP `json:"derp,omitempty"`
|
||||||
Logging Logging `yaml:"logging,omitempty"`
|
Logging Logging `json:"logging,omitempty"`
|
||||||
|
|
||||||
PublicUrl *url.URL `yaml:"-"`
|
PublicUrl *url.URL `json:"-"`
|
||||||
|
|
||||||
stunHost string
|
stunHost string
|
||||||
stunPort int
|
stunPort int
|
||||||
@@ -165,79 +166,79 @@ type Config struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type Tls struct {
|
type Tls struct {
|
||||||
Disable bool `yaml:"disable"`
|
Disable bool `json:"disable"`
|
||||||
ForceHttps bool `yaml:"force_https"`
|
ForceHttps bool `json:"force_https"`
|
||||||
CertFile string `yaml:"cert_file,omitempty"`
|
CertFile string `json:"cert_file,omitempty"`
|
||||||
KeyFile string `yaml:"key_file,omitempty"`
|
KeyFile string `json:"key_file,omitempty"`
|
||||||
AcmeEnabled bool `yaml:"acme,omitempty"`
|
AcmeEnabled bool `json:"acme,omitempty"`
|
||||||
AcmeEmail string `yaml:"acme_email,omitempty"`
|
AcmeEmail string `json:"acme_email,omitempty"`
|
||||||
AcmeCA string `yaml:"acme_ca,omitempty"`
|
AcmeCA string `json:"acme_ca,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type PollNet struct {
|
type PollNet struct {
|
||||||
KeepAliveInterval time.Duration `yaml:"keep_alive_interval"`
|
KeepAliveInterval Duration `json:"keep_alive_interval"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type Logging struct {
|
type Logging struct {
|
||||||
Level string `yaml:"level,omitempty"`
|
Level string `json:"level,omitempty"`
|
||||||
Format string `yaml:"format,omitempty"`
|
Format string `json:"format,omitempty"`
|
||||||
File string `yaml:"file,omitempty"`
|
File string `json:"file,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type Database struct {
|
type Database struct {
|
||||||
Type string `yaml:"type,omitempty"`
|
Type string `json:"type,omitempty"`
|
||||||
Url string `yaml:"url,omitempty"`
|
Url string `json:"url,omitempty"`
|
||||||
MaxOpenConns int `yaml:"max_open_conns,omitempty"`
|
MaxOpenConns int `json:"max_open_conns,omitempty"`
|
||||||
MaxIdleConns int `yaml:"max_idle_conns,omitempty"`
|
MaxIdleConns int `json:"max_idle_conns,omitempty"`
|
||||||
ConnMaxLifetime time.Duration `yaml:"conn_max_life_time,omitempty"`
|
ConnMaxLifetime Duration `json:"conn_max_life_time,omitempty"`
|
||||||
ConnMaxIdleTime time.Duration `yaml:"conn_max_idle_time,omitempty"`
|
ConnMaxIdleTime Duration `json:"conn_max_idle_time,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type Keys struct {
|
type Keys struct {
|
||||||
ControlKey string `yaml:"control_key,omitempty"`
|
ControlKey string `json:"control_key,omitempty"`
|
||||||
LegacyControlKey string `yaml:"legacy_control_key,omitempty"`
|
LegacyControlKey string `json:"legacy_control_key,omitempty"`
|
||||||
SystemAdminKey string `yaml:"system_admin_key,omitempty"`
|
SystemAdminKey string `json:"system_admin_key,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type Auth struct {
|
type Auth struct {
|
||||||
Provider AuthProvider `yaml:"provider,omitempty"`
|
Provider AuthProvider `json:"provider,omitempty"`
|
||||||
SystemAdminPolicy SystemAdminPolicy `yaml:"system_admins"`
|
SystemAdminPolicy SystemAdminPolicy `json:"system_admins"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type AuthProvider struct {
|
type AuthProvider struct {
|
||||||
Issuer string `yaml:"issuer"`
|
Issuer string `json:"issuer"`
|
||||||
ClientID string `yaml:"client_id"`
|
ClientID string `json:"client_id"`
|
||||||
ClientSecret string `yaml:"client_secret"`
|
ClientSecret string `json:"client_secret"`
|
||||||
Scopes []string `yaml:"additional_scopes" `
|
Scopes []string `json:"additional_scopes" `
|
||||||
}
|
}
|
||||||
|
|
||||||
type DNS struct {
|
type DNS struct {
|
||||||
MagicDNSSuffix string `yaml:"magic_dns_suffix"`
|
MagicDNSSuffix string `json:"magic_dns_suffix"`
|
||||||
Provider DNSProvider `yaml:"provider,omitempty"`
|
Provider DNSProvider `json:"provider,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type DNSProvider struct {
|
type DNSProvider struct {
|
||||||
Name string `yaml:"name"`
|
Name string `json:"name"`
|
||||||
Zone string `yaml:"zone"`
|
Zone string `json:"zone"`
|
||||||
Configuration map[string]string `yaml:"config"`
|
Configuration json.RawMessage `json:"config"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type SystemAdminPolicy struct {
|
type SystemAdminPolicy struct {
|
||||||
Subs []string `yaml:"subs,omitempty"`
|
Subs []string `json:"subs,omitempty"`
|
||||||
Emails []string `yaml:"emails,omitempty"`
|
Emails []string `json:"emails,omitempty"`
|
||||||
Filters []string `yaml:"filters,omitempty"`
|
Filters []string `json:"filters,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type DERP struct {
|
type DERP struct {
|
||||||
Server DERPServer `yaml:"server,omitempty"`
|
Server DERPServer `json:"server,omitempty"`
|
||||||
Sources []string `yaml:"sources,omitempty"`
|
Sources []string `json:"sources,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type DERPServer struct {
|
type DERPServer struct {
|
||||||
Disabled bool `yaml:"disabled,omitempty"`
|
Disabled bool `json:"disabled,omitempty"`
|
||||||
RegionID int `yaml:"region_id,omitempty"`
|
RegionID int `json:"region_id,omitempty"`
|
||||||
RegionCode string `yaml:"region_code,omitempty"`
|
RegionCode string `json:"region_code,omitempty"`
|
||||||
RegionName string `yaml:"region_name,omitempty"`
|
RegionName string `json:"region_name,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Config) Validate() (*Config, error) {
|
func (c *Config) Validate() (*Config, error) {
|
||||||
@@ -356,6 +357,37 @@ func (c *Config) DefaultDERPMap() *tailcfg.DERPMap {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Duration time.Duration
|
||||||
|
|
||||||
|
func (d Duration) Std() time.Duration {
|
||||||
|
return time.Duration(d)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d Duration) MarshalJSON() ([]byte, error) {
|
||||||
|
return json.Marshal(time.Duration(d).String())
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *Duration) UnmarshalJSON(b []byte) error {
|
||||||
|
var v interface{}
|
||||||
|
if err := json.Unmarshal(b, &v); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
switch value := v.(type) {
|
||||||
|
case float64:
|
||||||
|
*d = Duration(value)
|
||||||
|
return nil
|
||||||
|
case string:
|
||||||
|
tmp, err := time.ParseDuration(value)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
*d = Duration(tmp)
|
||||||
|
return nil
|
||||||
|
default:
|
||||||
|
return fmt.Errorf("invalid duration")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Match ${VAR:default} syntax for variables with default values
|
// Match ${VAR:default} syntax for variables with default values
|
||||||
var optionalEnvRegex = regexp.MustCompile(`\${([a-zA-Z0-9_]+):([^}]*)}`)
|
var optionalEnvRegex = regexp.MustCompile(`\${([a-zA-Z0-9_]+):([^}]*)}`)
|
||||||
|
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ database:
|
|||||||
type: ${DB_TYPE:sqlite}
|
type: ${DB_TYPE:sqlite}
|
||||||
url: ${DB_URL}
|
url: ${DB_URL}
|
||||||
max_open_conns: ${DB_MAX_OPEN_CONNS:5}
|
max_open_conns: ${DB_MAX_OPEN_CONNS:5}
|
||||||
|
conn_max_life_time: ${DB_CONN_MAX_LIFE_TIME:5s}
|
||||||
`
|
`
|
||||||
if _, err := tempFile.Write([]byte(yamlContent)); err != nil {
|
if _, err := tempFile.Write([]byte(yamlContent)); err != nil {
|
||||||
t.Fatalf("Failed to write to temp file: %v", err)
|
t.Fatalf("Failed to write to temp file: %v", err)
|
||||||
|
|||||||
@@ -39,8 +39,8 @@ func OpenDB(config *config.Database, logger *zap.Logger) (*sql.DB, domain.Reposi
|
|||||||
|
|
||||||
sqlDB.SetMaxOpenConns(config.MaxOpenConns)
|
sqlDB.SetMaxOpenConns(config.MaxOpenConns)
|
||||||
sqlDB.SetMaxIdleConns(config.MaxIdleConns)
|
sqlDB.SetMaxIdleConns(config.MaxIdleConns)
|
||||||
sqlDB.SetConnMaxLifetime(config.ConnMaxLifetime)
|
sqlDB.SetConnMaxLifetime(config.ConnMaxLifetime.Std())
|
||||||
sqlDB.SetConnMaxIdleTime(config.ConnMaxIdleTime)
|
sqlDB.SetConnMaxIdleTime(config.ConnMaxIdleTime.Std())
|
||||||
|
|
||||||
repository := domain.NewRepository(db)
|
repository := domain.NewRepository(db)
|
||||||
|
|
||||||
|
|||||||
+27
-39
@@ -2,9 +2,9 @@ package dns
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/jsiebens/ionscale/internal/config"
|
"github.com/jsiebens/ionscale/internal/config"
|
||||||
"github.com/jsiebens/ionscale/internal/mapping"
|
|
||||||
"github.com/libdns/azure"
|
"github.com/libdns/azure"
|
||||||
"github.com/libdns/cloudflare"
|
"github.com/libdns/cloudflare"
|
||||||
"github.com/libdns/digitalocean"
|
"github.com/libdns/digitalocean"
|
||||||
@@ -15,6 +15,14 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var factories = map[string]func() libdns.RecordSetter{
|
||||||
|
"azure": azureProvider,
|
||||||
|
"cloudflare": cloudflareProvider,
|
||||||
|
"digitalocean": digitalOceanProvider,
|
||||||
|
"googleclouddns": googleCloudDNSProvider,
|
||||||
|
"route53": route53Provider,
|
||||||
|
}
|
||||||
|
|
||||||
type Provider interface {
|
type Provider interface {
|
||||||
SetRecord(ctx context.Context, recordType, recordName, value string) error
|
SetRecord(ctx context.Context, recordType, recordName, value string) error
|
||||||
}
|
}
|
||||||
@@ -29,60 +37,40 @@ func NewProvider(config config.DNS) (Provider, error) {
|
|||||||
return nil, fmt.Errorf("invalid MagicDNS suffix [%s], not part of zone [%s]", config.MagicDNSSuffix, p.Zone)
|
return nil, fmt.Errorf("invalid MagicDNS suffix [%s], not part of zone [%s]", config.MagicDNSSuffix, p.Zone)
|
||||||
}
|
}
|
||||||
|
|
||||||
switch p.Name {
|
factory, ok := factories[p.Name]
|
||||||
case "azure":
|
if !ok {
|
||||||
return configureAzureProvider(p.Zone, p.Configuration)
|
|
||||||
case "cloudflare":
|
|
||||||
return configureCloudflareProvider(p.Zone, p.Configuration)
|
|
||||||
case "digitalocean":
|
|
||||||
return configureDigitalOceanProvider(p.Zone, p.Configuration)
|
|
||||||
case "googleclouddns":
|
|
||||||
return configureGoogleCloudDNSProvider(p.Zone, p.Configuration)
|
|
||||||
case "route53":
|
|
||||||
return configureRoute53Provider(p.Zone, p.Configuration)
|
|
||||||
default:
|
|
||||||
return nil, fmt.Errorf("unknown dns provider: %s", p.Name)
|
return nil, fmt.Errorf("unknown dns provider: %s", p.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return newProvider(p.Zone, p.Configuration, factory)
|
||||||
}
|
}
|
||||||
|
|
||||||
func configureAzureProvider(zone string, values map[string]string) (Provider, error) {
|
func newProvider(zone string, values json.RawMessage, factory func() libdns.RecordSetter) (Provider, error) {
|
||||||
p := &azure.Provider{}
|
p := factory()
|
||||||
if err := mapping.CopyViaJson(values, p); err != nil {
|
if err := json.Unmarshal(values, p); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return &externalProvider{zone: fqdn(zone), setter: p}, nil
|
return &externalProvider{zone: fqdn(zone), setter: p}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func configureCloudflareProvider(zone string, values map[string]string) (Provider, error) {
|
func azureProvider() libdns.RecordSetter {
|
||||||
p := &cloudflare.Provider{}
|
return &azure.Provider{}
|
||||||
if err := mapping.CopyViaJson(values, p); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &externalProvider{zone: fqdn(zone), setter: p}, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func configureDigitalOceanProvider(zone string, values map[string]string) (Provider, error) {
|
func cloudflareProvider() libdns.RecordSetter {
|
||||||
p := &digitalocean.Provider{}
|
return &cloudflare.Provider{}
|
||||||
if err := mapping.CopyViaJson(values, p); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &externalProvider{zone: fqdn(zone), setter: p}, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func configureGoogleCloudDNSProvider(zone string, values map[string]string) (Provider, error) {
|
func digitalOceanProvider() libdns.RecordSetter {
|
||||||
p := &googleclouddns.Provider{}
|
return &digitalocean.Provider{}
|
||||||
if err := mapping.CopyViaJson(values, p); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &externalProvider{zone: fqdn(zone), setter: p}, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func configureRoute53Provider(zone string, values map[string]string) (Provider, error) {
|
func googleCloudDNSProvider() libdns.RecordSetter {
|
||||||
p := &route53.Provider{}
|
return &googleclouddns.Provider{}
|
||||||
if err := mapping.CopyViaJson(values, p); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
}
|
||||||
return &externalProvider{zone: fqdn(zone), setter: p}, nil
|
|
||||||
|
func route53Provider() libdns.RecordSetter {
|
||||||
|
return &route53.Provider{}
|
||||||
}
|
}
|
||||||
|
|
||||||
type externalProvider struct {
|
type externalProvider struct {
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
package mapping
|
package mapping
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/jsiebens/ionscale/internal/config"
|
"github.com/jsiebens/ionscale/internal/config"
|
||||||
"github.com/jsiebens/ionscale/internal/domain"
|
"github.com/jsiebens/ionscale/internal/domain"
|
||||||
@@ -15,19 +14,6 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
func CopyViaJson[F any, T any](f F, t T) error {
|
|
||||||
raw, err := json.Marshal(f)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := json.Unmarshal(raw, t); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func ToDNSConfig(m *domain.Machine, tailnet *domain.Tailnet, c *domain.DNSConfig) *tailcfg.DNSConfig {
|
func ToDNSConfig(m *domain.Machine, tailnet *domain.Tailnet, c *domain.DNSConfig) *tailcfg.DNSConfig {
|
||||||
certsEnabled := c.HttpsCertsEnabled && config.DNSProviderConfigured()
|
certsEnabled := c.HttpsCertsEnabled && config.DNSProviderConfigured()
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user