Merge pull request #3707 from gravitl/NM-158

NM-158: Search Domain Support
This commit is contained in:
Vishal Dalwadi
2025-11-03 12:24:28 +05:30
committed by GitHub
parent 5a15d4b3c6
commit 94770a911d
7 changed files with 120 additions and 71 deletions

View File

@@ -99,21 +99,25 @@ func createNs(w http.ResponseWriter, r *http.Request) {
}
}
if req.MatchAll {
req.MatchDomains = []string{"."}
req.Domains = []schema.NameserverDomain{
{
Domain: ".",
},
}
}
ns := schema.Nameserver{
ID: uuid.New().String(),
Name: req.Name,
NetworkID: req.NetworkID,
Description: req.Description,
MatchAll: req.MatchAll,
MatchDomains: req.MatchDomains,
Servers: req.Servers,
Tags: req.Tags,
Nodes: req.Nodes,
Status: true,
CreatedBy: r.Header.Get("user"),
CreatedAt: time.Now().UTC(),
ID: uuid.New().String(),
Name: req.Name,
NetworkID: req.NetworkID,
Description: req.Description,
Servers: req.Servers,
MatchAll: req.MatchAll,
Domains: req.Domains,
Tags: req.Tags,
Nodes: req.Nodes,
Status: true,
CreatedBy: r.Header.Get("user"),
CreatedAt: time.Now().UTC(),
}
err = ns.Create(db.WithContext(r.Context()))
@@ -242,7 +246,7 @@ func updateNs(w http.ResponseWriter, r *http.Request) {
}
ns.Servers = updateNs.Servers
ns.Tags = updateNs.Tags
ns.MatchDomains = updateNs.MatchDomains
ns.Domains = updateNs.Domains
ns.MatchAll = updateNs.MatchAll
ns.Description = updateNs.Description
ns.Name = updateNs.Name

View File

@@ -442,12 +442,12 @@ func validateNameserverReq(ns schema.Nameserver) error {
return errors.New("invalid nameserver " + nsIPStr)
}
}
if !ns.MatchAll && len(ns.MatchDomains) == 0 {
if !ns.MatchAll && len(ns.Domains) == 0 {
return errors.New("atleast one match domain is required")
}
if !ns.MatchAll {
for _, matchDomain := range ns.MatchDomains {
if !IsValidMatchDomain(matchDomain) {
for _, domain := range ns.Domains {
if !IsValidMatchDomain(domain.Domain) {
return errors.New("invalid match domain")
}
}
@@ -494,20 +494,22 @@ func getNameserversForNode(node *models.Node) (returnNsLi []models.Nameserver) {
_, all := nsI.Tags["*"]
if all {
for _, matchDomain := range nsI.MatchDomains {
for _, domain := range nsI.Domains {
returnNsLi = append(returnNsLi, models.Nameserver{
IPs: filteredIps,
MatchDomain: matchDomain,
IPs: filteredIps,
MatchDomain: domain.Domain,
IsSearchDomain: domain.IsSearchDomain,
})
}
continue
}
if _, ok := nsI.Nodes[node.ID.String()]; ok {
for _, matchDomain := range nsI.MatchDomains {
for _, domain := range nsI.Domains {
returnNsLi = append(returnNsLi, models.Nameserver{
IPs: filteredIps,
MatchDomain: matchDomain,
IPs: filteredIps,
MatchDomain: domain.Domain,
IsSearchDomain: domain.IsSearchDomain,
})
}
}
@@ -560,20 +562,22 @@ func getNameserversForHost(h *models.Host) (returnNsLi []models.Nameserver) {
_, all := nsI.Tags["*"]
if all {
for _, matchDomain := range nsI.MatchDomains {
for _, domain := range nsI.Domains {
returnNsLi = append(returnNsLi, models.Nameserver{
IPs: filteredIps,
MatchDomain: matchDomain,
IPs: filteredIps,
MatchDomain: domain.Domain,
IsSearchDomain: domain.IsSearchDomain,
})
}
continue
}
if _, ok := nsI.Nodes[node.ID.String()]; ok {
for _, matchDomain := range nsI.MatchDomains {
for _, domain := range nsI.Domains {
returnNsLi = append(returnNsLi, models.Nameserver{
IPs: filteredIps,
MatchDomain: matchDomain,
IPs: filteredIps,
MatchDomain: domain.Domain,
IsSearchDomain: domain.IsSearchDomain,
})
}

View File

@@ -100,14 +100,37 @@ func migrateNameservers() {
if err != nil {
continue
}
ns := &schema.Nameserver{
NetworkID: netI.NetID,
}
nameservers, _ := ns.ListByNetwork(db.WithContext(context.TODO()))
for _, nsI := range nameservers {
if len(nsI.Domains) != 0 {
for _, matchDomain := range nsI.MatchDomains {
nsI.Domains = append(nsI.Domains, schema.NameserverDomain{
Domain: matchDomain,
})
}
nsI.MatchDomains = []string{}
_ = nsI.Update(db.WithContext(context.TODO()))
}
}
if len(netI.NameServers) > 0 {
ns := schema.Nameserver{
ID: uuid.NewString(),
Name: "upstream nameservers",
NetworkID: netI.NetID,
Servers: []string{},
MatchAll: true,
MatchDomains: []string{"."},
ID: uuid.NewString(),
Name: "upstream nameservers",
NetworkID: netI.NetID,
Servers: []string{},
MatchAll: true,
Domains: []schema.NameserverDomain{
{
Domain: ".",
},
},
Tags: datatypes.JSONMap{
"*": struct{}{},
},
@@ -147,12 +170,16 @@ func migrateNameservers() {
continue
}
ns := schema.Nameserver{
ID: uuid.NewString(),
Name: fmt.Sprintf("%s gw nameservers", h.Name),
NetworkID: node.Network,
Servers: []string{node.IngressDNS},
MatchAll: true,
MatchDomains: []string{"."},
ID: uuid.NewString(),
Name: fmt.Sprintf("%s gw nameservers", h.Name),
NetworkID: node.Network,
Servers: []string{node.IngressDNS},
MatchAll: true,
Domains: []schema.NameserverDomain{
{
Domain: ".",
},
},
Nodes: datatypes.JSONMap{
node.ID.String(): struct{}{},
},

View File

@@ -44,8 +44,9 @@ type EgressDomain struct {
Domain string `json:"domain"`
}
type Nameserver struct {
IPs []string `json:"ips"`
MatchDomain string `json:"match_domain"`
IPs []string `json:"ips"`
MatchDomain string `json:"match_domain"`
IsSearchDomain bool `json:"is_search_domain"`
}
type OldPeerUpdateFields struct {

View File

@@ -1551,7 +1551,7 @@ func getUserRemoteAccessGwsV1(w http.ResponseWriter, r *http.Request) {
}
}
if !found && len(extClients) > 0 {
if !found && len(extClients) > 0 && deviceID == "" {
// TODO: prevent ip clashes.
gwClient = extClients[0]
}

View File

@@ -40,12 +40,12 @@ func ValidateNameserverReq(ns schema.Nameserver) error {
return errors.New("cannot use netmaker IP as nameserver")
}
}
if !ns.MatchAll && len(ns.MatchDomains) == 0 {
if !ns.MatchAll && len(ns.Domains) == 0 {
return errors.New("atleast one match domain is required")
}
if !ns.MatchAll {
for _, matchDomain := range ns.MatchDomains {
if !logic.IsValidMatchDomain(matchDomain) {
for _, domain := range ns.Domains {
if !logic.IsValidMatchDomain(domain.Domain) {
return errors.New("invalid match domain")
}
}
@@ -90,10 +90,11 @@ func GetNameserversForNode(node *models.Node) (returnNsLi []models.Nameserver) {
_, all := nsI.Tags["*"]
if all {
for _, matchDomain := range nsI.MatchDomains {
for _, domain := range nsI.Domains {
returnNsLi = append(returnNsLi, models.Nameserver{
IPs: filteredIps,
MatchDomain: matchDomain,
IPs: filteredIps,
MatchDomain: domain.Domain,
IsSearchDomain: domain.IsSearchDomain,
})
}
continue
@@ -101,10 +102,11 @@ func GetNameserversForNode(node *models.Node) (returnNsLi []models.Nameserver) {
foundTag := false
for tagI := range node.Tags {
if _, ok := nsI.Tags[tagI.String()]; ok {
for _, matchDomain := range nsI.MatchDomains {
for _, domain := range nsI.Domains {
returnNsLi = append(returnNsLi, models.Nameserver{
IPs: filteredIps,
MatchDomain: matchDomain,
IPs: filteredIps,
MatchDomain: domain.Domain,
IsSearchDomain: domain.IsSearchDomain,
})
}
foundTag = true
@@ -117,10 +119,11 @@ func GetNameserversForNode(node *models.Node) (returnNsLi []models.Nameserver) {
continue
}
if _, ok := nsI.Nodes[node.ID.String()]; ok {
for _, matchDomain := range nsI.MatchDomains {
for _, domain := range nsI.Domains {
returnNsLi = append(returnNsLi, models.Nameserver{
IPs: nsI.Servers,
MatchDomain: matchDomain,
IPs: nsI.Servers,
MatchDomain: domain.Domain,
IsSearchDomain: domain.IsSearchDomain,
})
}
}
@@ -173,10 +176,11 @@ func GetNameserversForHost(h *models.Host) (returnNsLi []models.Nameserver) {
_, all := nsI.Tags["*"]
if all {
for _, matchDomain := range nsI.MatchDomains {
for _, domain := range nsI.Domains {
returnNsLi = append(returnNsLi, models.Nameserver{
IPs: filteredIps,
MatchDomain: matchDomain,
IPs: filteredIps,
MatchDomain: domain.Domain,
IsSearchDomain: domain.IsSearchDomain,
})
}
continue
@@ -184,10 +188,11 @@ func GetNameserversForHost(h *models.Host) (returnNsLi []models.Nameserver) {
foundTag := false
for tagI := range node.Tags {
if _, ok := nsI.Tags[tagI.String()]; ok {
for _, matchDomain := range nsI.MatchDomains {
for _, domain := range nsI.Domains {
returnNsLi = append(returnNsLi, models.Nameserver{
IPs: filteredIps,
MatchDomain: matchDomain,
IPs: filteredIps,
MatchDomain: domain.Domain,
IsSearchDomain: domain.IsSearchDomain,
})
}
foundTag = true
@@ -200,10 +205,11 @@ func GetNameserversForHost(h *models.Host) (returnNsLi []models.Nameserver) {
continue
}
if _, ok := nsI.Nodes[node.ID.String()]; ok {
for _, matchDomain := range nsI.MatchDomains {
for _, domain := range nsI.Domains {
returnNsLi = append(returnNsLi, models.Nameserver{
IPs: nsI.Servers,
MatchDomain: matchDomain,
IPs: nsI.Servers,
MatchDomain: domain.Domain,
IsSearchDomain: domain.IsSearchDomain,
})
}
}

View File

@@ -9,12 +9,14 @@ import (
)
type Nameserver struct {
ID string `gorm:"primaryKey" json:"id"`
Name string `gorm:"name" json:"name"`
NetworkID string `gorm:"network_id" json:"network_id"`
Description string `gorm:"description" json:"description"`
Servers datatypes.JSONSlice[string] `gorm:"servers" json:"servers"`
MatchAll bool `gorm:"match_all" json:"match_all"`
ID string `gorm:"primaryKey" json:"id"`
Name string `gorm:"name" json:"name"`
NetworkID string `gorm:"network_id" json:"network_id"`
Description string `gorm:"description" json:"description"`
Servers datatypes.JSONSlice[string] `gorm:"servers" json:"servers"`
MatchAll bool `gorm:"match_all" json:"match_all"`
Domains datatypes.JSONSlice[NameserverDomain] `gorm:"domains" json:"domains"`
// TODO: deprecate
MatchDomains datatypes.JSONSlice[string] `gorm:"match_domains" json:"match_domains"`
Tags datatypes.JSONMap `gorm:"tags" json:"tags"`
Nodes datatypes.JSONMap `gorm:"nodes" json:"nodes"`
@@ -24,6 +26,11 @@ type Nameserver struct {
UpdatedAt time.Time `gorm:"updated_at" json:"updated_at"`
}
type NameserverDomain struct {
Domain string `json:"domain"`
IsSearchDomain bool `json:"is_search_domain"`
}
func (ns *Nameserver) Get(ctx context.Context) error {
return db.FromContext(ctx).Model(&Nameserver{}).First(&ns).Where("id = ?", ns.ID).Error
}