chore: use yaml-to-json library, giving better support for configuring third-party libs like libdns providers

This commit is contained in:
Johan Siebens
2025-03-10 08:40:17 +01:00
parent 978b0ecf4f
commit 828e0c920b
7 changed files with 124 additions and 120 deletions
+2 -3
View File
@@ -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
+2 -4
View File
@@ -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
View File
@@ -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_]+):([^}]*)}`)
+1
View File
@@ -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)
+2 -2
View File
@@ -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)
+28 -40
View File
@@ -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
} func route53Provider() libdns.RecordSetter {
return &externalProvider{zone: fqdn(zone), setter: p}, nil return &route53.Provider{}
} }
type externalProvider struct { type externalProvider struct {
-14
View File
@@ -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()