Files

118 lines
3.8 KiB
Go

package service
import (
"context"
"fmt"
"github.com/bufbuild/connect-go"
"github.com/jsiebens/ionscale/internal/config"
"github.com/jsiebens/ionscale/internal/domain"
api "github.com/jsiebens/ionscale/pkg/gen/ionscale/v1"
)
func (s *Service) GetDNSConfig(ctx context.Context, req *connect.Request[api.GetDNSConfigRequest]) (*connect.Response[api.GetDNSConfigResponse], error) {
principal := CurrentPrincipal(ctx)
if !principal.IsSystemAdmin() && !principal.IsTailnetAdmin(req.Msg.TailnetId) {
return nil, connect.NewError(connect.CodePermissionDenied, fmt.Errorf("permission denied"))
}
tailnet, err := s.repository.GetTailnet(ctx, req.Msg.TailnetId)
if err != nil {
return nil, logError(err)
}
if tailnet == nil {
return nil, connect.NewError(connect.CodeNotFound, fmt.Errorf("tailnet not found"))
}
resp := &api.GetDNSConfigResponse{
Config: domainDNSConfigToApiDNSConfig(tailnet),
}
return connect.NewResponse(resp), nil
}
func (s *Service) SetDNSConfig(ctx context.Context, req *connect.Request[api.SetDNSConfigRequest]) (*connect.Response[api.SetDNSConfigResponse], error) {
principal := CurrentPrincipal(ctx)
if !principal.IsSystemAdmin() && !principal.IsTailnetAdmin(req.Msg.TailnetId) {
return nil, connect.NewError(connect.CodePermissionDenied, fmt.Errorf("permission denied"))
}
dnsConfig := req.Msg.Config
if dnsConfig.HttpsCerts && !dnsConfig.MagicDns {
return nil, connect.NewError(connect.CodeFailedPrecondition, fmt.Errorf("MagicDNS must be enabled when enabling HTTPS Certs"))
}
if dnsConfig.HttpsCerts && s.dnsProvider == nil {
return nil, connect.NewError(connect.CodeFailedPrecondition, fmt.Errorf("A DNS provider must be configured when enabling HTTPS Certs"))
}
tailnet, err := s.repository.GetTailnet(ctx, req.Msg.TailnetId)
if err != nil {
return nil, logError(err)
}
if tailnet == nil {
return nil, connect.NewError(connect.CodeNotFound, fmt.Errorf("tailnet not found"))
}
oldConfig := tailnet.DNSConfig
newConfig := apiDNSConfigToDomainDNSConfig(req.Msg.Config)
if oldConfig.Equal(&newConfig) {
return connect.NewResponse(&api.SetDNSConfigResponse{Config: domainDNSConfigToApiDNSConfig(tailnet)}), nil
}
tailnet.DNSConfig = newConfig
if err := s.repository.SaveTailnet(ctx, tailnet); err != nil {
return nil, logError(err)
}
s.sessionManager.NotifyAll(tailnet.ID)
return connect.NewResponse(&api.SetDNSConfigResponse{Config: domainDNSConfigToApiDNSConfig(tailnet)}), nil
}
func domainRoutesToApiRoutes(routes map[string][]string) map[string]*api.Routes {
var result = map[string]*api.Routes{}
for k, v := range routes {
result[k] = &api.Routes{Routes: v}
}
return result
}
func apiRoutesToDomainRoutes(routes map[string]*api.Routes) map[string][]string {
var result = map[string][]string{}
for k, v := range routes {
result[k] = v.Routes
}
return result
}
func apiDNSConfigToDomainDNSConfig(dnsConfig *api.DNSConfig) domain.DNSConfig {
if dnsConfig == nil {
return domain.DNSConfig{}
}
return domain.DNSConfig{
MagicDNS: dnsConfig.MagicDns,
HttpsCertsEnabled: dnsConfig.HttpsCerts,
OverrideLocalDNS: dnsConfig.OverrideLocalDns,
Nameservers: dnsConfig.Nameservers,
Routes: apiRoutesToDomainRoutes(dnsConfig.Routes),
SearchDomains: dnsConfig.SearchDomains,
}
}
func domainDNSConfigToApiDNSConfig(tailnet *domain.Tailnet) *api.DNSConfig {
tailnetDomain := domain.SanitizeTailnetName(tailnet.Name)
dnsConfig := tailnet.DNSConfig
return &api.DNSConfig{
MagicDns: dnsConfig.MagicDNS,
HttpsCerts: dnsConfig.HttpsCertsEnabled,
MagicDnsSuffix: fmt.Sprintf("%s.%s", tailnetDomain, config.MagicDNSSuffix()),
OverrideLocalDns: dnsConfig.OverrideLocalDNS,
Nameservers: dnsConfig.Nameservers,
Routes: domainRoutesToApiRoutes(dnsConfig.Routes),
SearchDomains: dnsConfig.SearchDomains,
}
}