diff --git a/dns/nameserver.go b/dns/nameserver.go index bb904b165..f6ede6c49 100644 --- a/dns/nameserver.go +++ b/dns/nameserver.go @@ -6,6 +6,8 @@ import ( "net/url" "strconv" "strings" + + "github.com/netbirdio/netbird/management/domain" ) const ( @@ -64,7 +66,7 @@ type NameServerGroup struct { // Primary indicates that the nameserver group is the primary resolver for any dns query Primary bool // Domains indicate the dns query domains to use with this nameserver group - Domains []string `gorm:"serializer:json"` + Domains domain.List `gorm:"serializer:json"` // Enabled group status Enabled bool // SearchDomainsEnabled indicates whether to add match domains to search domains list or not @@ -142,7 +144,7 @@ func (g *NameServerGroup) Copy() *NameServerGroup { Groups: make([]string, len(g.Groups)), Enabled: g.Enabled, Primary: g.Primary, - Domains: make([]string, len(g.Domains)), + Domains: make(domain.List, len(g.Domains)), SearchDomainsEnabled: g.SearchDomainsEnabled, } @@ -188,7 +190,7 @@ func containsNameServer(element NameServer, list []NameServer) bool { return false } -func compareGroupsList(list, other []string) bool { +func compareGroupsList[T comparable](list, other []T) bool { if len(list) != len(other) { return false } diff --git a/management/server/account/manager.go b/management/server/account/manager.go index 9bc4f9605..bba8ee6de 100644 --- a/management/server/account/manager.go +++ b/management/server/account/manager.go @@ -78,7 +78,7 @@ type Manager interface { DeleteRoute(ctx context.Context, accountID string, routeID route.ID, userID string) error ListRoutes(ctx context.Context, accountID, userID string) ([]*route.Route, error) GetNameServerGroup(ctx context.Context, accountID, userID, nsGroupID string) (*nbdns.NameServerGroup, error) - CreateNameServerGroup(ctx context.Context, accountID string, name, description string, nameServerList []nbdns.NameServer, groups []string, primary bool, domains []string, enabled bool, userID string, searchDomainsEnabled bool) (*nbdns.NameServerGroup, error) + CreateNameServerGroup(ctx context.Context, accountID string, name, description string, nameServerList []nbdns.NameServer, groups []string, primary bool, domains domain.List, enabled bool, userID string, searchDomainsEnabled bool) (*nbdns.NameServerGroup, error) SaveNameServerGroup(ctx context.Context, accountID, userID string, nsGroupToSave *nbdns.NameServerGroup) error DeleteNameServerGroup(ctx context.Context, accountID, nsGroupID, userID string) error ListNameServerGroups(ctx context.Context, accountID string, userID string) ([]*nbdns.NameServerGroup, error) diff --git a/management/server/dns.go b/management/server/dns.go index a3f32c2a9..370bce653 100644 --- a/management/server/dns.go +++ b/management/server/dns.go @@ -258,7 +258,7 @@ func convertToProtoCustomZone(zone nbdns.CustomZone) *proto.CustomZone { func convertToProtoNameServerGroup(nsGroup *nbdns.NameServerGroup) *proto.NameServerGroup { protoGroup := &proto.NameServerGroup{ Primary: nsGroup.Primary, - Domains: nsGroup.Domains, + Domains: nsGroup.Domains.ToPunycodeList(), SearchDomainsEnabled: nsGroup.SearchDomainsEnabled, NameServers: make([]*proto.NameServer, 0, len(nsGroup.NameServers)), } diff --git a/management/server/http/handlers/dns/nameservers_handler.go b/management/server/http/handlers/dns/nameservers_handler.go index 970be6d8a..469289901 100644 --- a/management/server/http/handlers/dns/nameservers_handler.go +++ b/management/server/http/handlers/dns/nameservers_handler.go @@ -9,6 +9,7 @@ import ( log "github.com/sirupsen/logrus" nbdns "github.com/netbirdio/netbird/dns" + "github.com/netbirdio/netbird/management/domain" "github.com/netbirdio/netbird/management/server/account" nbcontext "github.com/netbirdio/netbird/management/server/context" "github.com/netbirdio/netbird/management/server/http/api" @@ -83,7 +84,13 @@ func (h *nameserversHandler) createNameserverGroup(w http.ResponseWriter, r *htt return } - nsGroup, err := h.accountManager.CreateNameServerGroup(r.Context(), accountID, req.Name, req.Description, nsList, req.Groups, req.Primary, req.Domains, req.Enabled, userID, req.SearchDomainsEnabled) + domains, err := domain.FromStringList(req.Domains) + if err != nil { + util.WriteError(r.Context(), status.Errorf(status.InvalidArgument, "invalid domains format"), w) + return + } + + nsGroup, err := h.accountManager.CreateNameServerGroup(r.Context(), accountID, req.Name, req.Description, nsList, req.Groups, req.Primary, domains, req.Enabled, userID, req.SearchDomainsEnabled) if err != nil { util.WriteError(r.Context(), err, w) return @@ -123,12 +130,18 @@ func (h *nameserversHandler) updateNameserverGroup(w http.ResponseWriter, r *htt return } + domains, err := domain.FromStringList(req.Domains) + if err != nil { + util.WriteError(r.Context(), status.Errorf(status.InvalidArgument, "invalid domains format"), w) + return + } + updatedNSGroup := &nbdns.NameServerGroup{ ID: nsGroupID, Name: req.Name, Description: req.Description, Primary: req.Primary, - Domains: req.Domains, + Domains: domains, NameServers: nsList, Groups: req.Groups, Enabled: req.Enabled, @@ -227,7 +240,7 @@ func toNameserverGroupResponse(serverNSGroup *nbdns.NameServerGroup) *api.Namese Name: serverNSGroup.Name, Description: serverNSGroup.Description, Primary: serverNSGroup.Primary, - Domains: serverNSGroup.Domains, + Domains: serverNSGroup.Domains.ToSafeStringList(), Groups: serverNSGroup.Groups, Nameservers: nsList, Enabled: serverNSGroup.Enabled, diff --git a/management/server/nameserver.go b/management/server/nameserver.go index 18339335d..a8aeb4ebd 100644 --- a/management/server/nameserver.go +++ b/management/server/nameserver.go @@ -10,6 +10,7 @@ import ( "github.com/rs/xid" nbdns "github.com/netbirdio/netbird/dns" + "github.com/netbirdio/netbird/management/domain" "github.com/netbirdio/netbird/management/server/activity" "github.com/netbirdio/netbird/management/server/permissions/modules" "github.com/netbirdio/netbird/management/server/permissions/operations" @@ -18,7 +19,7 @@ import ( "github.com/netbirdio/netbird/management/server/types" ) -const domainPattern = `^(?i)[a-z0-9]+([\-\.]{1}[a-z0-9]+)*[*.a-z]{1,}$` +const domainPattern = `^(?i)[a-z0-9]+([\-]+[a-z0-9]+)*[*.a-z]{1,}$` var invalidDomainName = errors.New("invalid domain name") @@ -36,7 +37,7 @@ func (am *DefaultAccountManager) GetNameServerGroup(ctx context.Context, account } // CreateNameServerGroup creates and saves a new nameserver group -func (am *DefaultAccountManager) CreateNameServerGroup(ctx context.Context, accountID string, name, description string, nameServerList []nbdns.NameServer, groups []string, primary bool, domains []string, enabled bool, userID string, searchDomainEnabled bool) (*nbdns.NameServerGroup, error) { +func (am *DefaultAccountManager) CreateNameServerGroup(ctx context.Context, accountID string, name, description string, nameServerList []nbdns.NameServer, groups []string, primary bool, domains domain.List, enabled bool, userID string, searchDomainEnabled bool) (*nbdns.NameServerGroup, error) { unlock := am.Store.AcquireWriteLockByUID(ctx, accountID) defer unlock() @@ -252,7 +253,7 @@ func areNameServerGroupChangesAffectPeers(ctx context.Context, transaction store return anyGroupHasPeersOrResources(ctx, transaction, oldNSGroup.AccountID, oldNSGroup.Groups) } -func validateDomainInput(primary bool, domains []string, searchDomainsEnabled bool) error { +func validateDomainInput(primary bool, domains domain.List, searchDomainsEnabled bool) error { if !primary && len(domains) == 0 { return status.Errorf(status.InvalidArgument, "nameserver group primary status is false and domains are empty,"+ " it should be primary or have at least one domain") @@ -268,7 +269,7 @@ func validateDomainInput(primary bool, domains []string, searchDomainsEnabled bo } for _, domain := range domains { - if err := validateDomain(domain); err != nil { + if err := validateDomain(domain.PunycodeString()); err != nil { return status.Errorf(status.InvalidArgument, "nameserver group got an invalid domain: %s %q", domain, err) } }