Fixes/v1.5.1 (#3938)

* fix(go): set persistent keep alive when registering host using sso;

* fix(go): run posture check violations on delete;

* fix(go): upsert node on approving pending host;

* fix(go): resolve concurrency issues during group delete cleanup;

* fix(go): update doc links;

* fix(go): add created and updated fields to host;

* fix(go): skip delete and update superadmin on sync users;

* fix(go): use conn directly for now;

* fix(go): remove acl for idp groups;

* fix(go): quote fields;

* fix(go): use filters with count;

* feat(go): add a search query;

* fix(go): cleanup acls;

* fix(go): review fixes;

* fix(go): remove additional loop;

* fix(go): fix

* v1.5.1: separate out idp sync and reset signals for HA

* v1.5.1: add grps with name for logging

* v1.5.1: clear posture check violations when all checks are deleted

* v1.5.1: set static when default host

* v1.5.1: fix db status check

* rm set max conns

* v1.5.1: reset auto assigned gw when disconnected

* fix(go): skip global network admin and user groups when splitting;

* v1.5.1: fix update node call from client

* fix(go): separate out migration from normal usage;

* fix(go): skip default groups;

* fix(go): create policies for existing groups on network create;

* fix(go): skip fatal log on clickhouse conn;

* fix(go): add posture check cleanup;

---------

Co-authored-by: VishalDalwadi <dalwadivishal26@gmail.com>
Co-authored-by: Vishal Dalwadi <51291657+VishalDalwadi@users.noreply.github.com>
This commit is contained in:
Abhishek Kondur
2026-03-28 01:08:59 +05:30
committed by GitHub
parent c3c3ed1fb8
commit 12cc967ba1
27 changed files with 664 additions and 450 deletions
+13 -4
View File
@@ -206,6 +206,7 @@ func getHosts(w http.ResponseWriter, r *http.Request) {
// @Security oauth
// @Produce json
// @Param os query []string false "Filter by OS" Enums(windows, linux, darwin)
// @Param q query string false "Search across fields"
// @Param page query int false "Page number"
// @Param per_page query int false "Items per page"
// @Success 200 {array} models.ApiHost
@@ -216,6 +217,8 @@ func listHosts(w http.ResponseWriter, r *http.Request) {
osFilters = append(osFilters, filter)
}
q := r.URL.Query().Get("q")
var page, pageSize int
page, _ = strconv.Atoi(r.URL.Query().Get("page"))
if page == 0 {
@@ -230,6 +233,7 @@ func listHosts(w http.ResponseWriter, r *http.Request) {
currentHosts, err := (&schema.Host{}).ListAll(
r.Context(),
dbtypes.WithFilter("os", osFilters...),
dbtypes.WithSearchQuery(q, "id", "name", "public_key", "endpoint_ip", "endpoint_ipv6"),
dbtypes.InAscOrder("name"),
dbtypes.WithPagination(page, pageSize),
)
@@ -245,6 +249,7 @@ func listHosts(w http.ResponseWriter, r *http.Request) {
total, err := (&schema.Host{}).Count(
r.Context(),
dbtypes.WithFilter("os", osFilters...),
dbtypes.WithSearchQuery(q, "id", "name", "public_key", "endpoint_ip", "endpoint_ipv6"),
)
if err != nil {
logic.ReturnErrorResponse(w, r, logic.FormatError(err, logic.Internal))
@@ -1572,7 +1577,6 @@ func approvePendingHost(w http.ResponseWriter, r *http.Request) {
for _, tagI := range key.Groups {
newNode.Tags[tagI] = struct{}{}
}
logic.UpsertNode(newNode)
}
if key.Relay != uuid.Nil && !newNode.IsRelayed {
// check if relay node exists and acting as relay
@@ -1587,14 +1591,19 @@ func approvePendingHost(w http.ResponseWriter, r *http.Request) {
if err := logic.UpsertNode(&updatedRelayNode); err != nil {
slog.Error("failed to update node", "nodeid", key.Relay.String())
}
if err := logic.UpsertNode(newNode); err != nil {
slog.Error("failed to update node", "nodeid", key.Relay.String())
}
} else {
slog.Error("failed to relay node. maybe specified relay node is actually not a relay? Or the relayed node is not in the same network with relay?", "err", err)
}
}
err = logic.UpsertNode(newNode)
if err != nil {
err = fmt.Errorf("failed to update node: %w", err)
slog.Error("failed to update node", "nodeid", newNode.ID.String())
logic.ReturnErrorResponse(w, r, logic.FormatError(err, logic.Internal))
return
}
logger.Log(1, "added new node", newNode.ID.String(), "to host", h.Name)
mq.HostUpdate(&models.HostUpdate{
Action: models.JoinHostToNetwork,
+34 -1
View File
@@ -1,6 +1,7 @@
package controller
import (
"context"
"encoding/json"
"fmt"
"net/http"
@@ -9,6 +10,7 @@ import (
"github.com/gorilla/mux"
"github.com/gravitl/netmaker/database"
"github.com/gravitl/netmaker/db"
"github.com/gravitl/netmaker/logger"
"github.com/gravitl/netmaker/logic"
"github.com/gravitl/netmaker/models"
@@ -687,7 +689,6 @@ func updateNode(w http.ResponseWriter, r *http.Request) {
if servercfg.IsPro && newNode.AutoAssignGateway {
mq.HostUpdate(&models.HostUpdate{Action: models.CheckAutoAssignGw, Host: *host, Node: *newNode})
}
mq.PublishPeerUpdate(false)
if servercfg.IsDNSMode() {
logic.SetDNS()
}
@@ -701,7 +702,39 @@ func updateNode(w http.ResponseWriter, r *http.Request) {
_ = logic.UpdateMetrics(newNode.ID.String(), metrics)
}
if servercfg.IsPro {
gwNode, err := logic.GetNodeByID(newNode.ID.String())
if err != nil {
slog.Error("disconnect gw: failed to re-fetch node", "node", newNode.ID, "error", err)
} else if gwNode.IsGw && len(gwNode.RelayedNodes) > 0 {
newRelayedNodes := []string{}
var displacedNodes []models.Node
for _, relayedNodeID := range gwNode.RelayedNodes {
relayedNode, err := logic.GetNodeByID(relayedNodeID)
if err != nil {
continue
}
if relayedNode.AutoAssignGateway && relayedNode.RelayedBy == gwNode.ID.String() {
displacedNodes = append(displacedNodes, relayedNode)
continue
}
newRelayedNodes = append(newRelayedNodes, relayedNodeID)
}
if len(displacedNodes) > 0 {
logic.UpdateRelayNodes(gwNode.ID.String(), gwNode.RelayedNodes, newRelayedNodes)
for _, dNode := range displacedNodes {
dHost := &schema.Host{ID: dNode.HostID}
if err := dHost.Get(db.WithContext(context.TODO())); err != nil {
slog.Error("disconnect gw: failed to get host for displaced node", "node", dNode.ID, "error", err)
continue
}
mq.HostUpdate(&models.HostUpdate{Action: models.CheckAutoAssignGw, Host: *dHost, Node: dNode})
}
}
}
}
}
mq.PublishPeerUpdate(false)
}(relayUpdate, newNode)
}
+11 -6
View File
@@ -1031,6 +1031,7 @@ func getUsers(w http.ResponseWriter, r *http.Request) {
// @Param mfa_status query string false "Filter by MFA Status" Enums(enabled, disabled)
// @Param role query []string false "Filter by Role" Enums(super-admin, admin, platform-user, service-user, auditor)
// @Param auth_type query string false "Filter by Auth Type" Enums(basic, oauth)
// @Param q query string false "Search across fields"
// @Param page query int false "Page number"
// @Param per_page query int false "Items per page"
// @Success 200 {array} models.ReturnUser
@@ -1067,6 +1068,8 @@ func listUsers(w http.ResponseWriter, r *http.Request) {
authTypeFilter = append(authTypeFilter, filter)
}
q := r.URL.Query().Get("q")
var page, pageSize int
page, _ = strconv.Atoi(r.URL.Query().Get("page"))
if page == 0 {
@@ -1084,6 +1087,7 @@ func listUsers(w http.ResponseWriter, r *http.Request) {
dbtypes.WithFilter("is_mfa_enabled", mfaStatusFilter...),
dbtypes.WithFilter("platform_role_id", roleFilter...),
dbtypes.WithFilter("auth_type", authTypeFilter...),
dbtypes.WithSearchQuery(q, "username"),
dbtypes.InAscOrder("username"),
dbtypes.WithPagination(page, pageSize),
)
@@ -1110,6 +1114,7 @@ func listUsers(w http.ResponseWriter, r *http.Request) {
dbtypes.WithFilter("is_mfa_enabled", mfaStatusFilter...),
dbtypes.WithFilter("platform_role_id", roleFilter...),
dbtypes.WithFilter("auth_type", authTypeFilter...),
dbtypes.WithSearchQuery(q, "username"),
)
if err != nil {
logic.ReturnErrorResponse(w, r, logic.FormatError(err, logic.Internal))
@@ -1528,8 +1533,8 @@ func updateUser(w http.ResponseWriter, r *http.Request) {
Type: schema.UserSub,
},
Diff: models.Diff{
Old: logic.ToReturnUser(&oldUser),
New: logic.ToReturnUser(&userchange),
Old: logic.ToUserEventLog(&oldUser),
New: logic.ToUserEventLog(&userchange),
},
Origin: schema.Dashboard,
}
@@ -1704,7 +1709,7 @@ func deleteUser(w http.ResponseWriter, r *http.Request) {
},
Origin: schema.Dashboard,
Diff: models.Diff{
Old: logic.ToReturnUser(user),
Old: logic.ToUserEventLog(user),
New: nil,
},
})
@@ -1843,7 +1848,7 @@ func bulkDeleteUsers(w http.ResponseWriter, r *http.Request) {
Type: schema.UserSub,
},
Origin: schema.Dashboard,
Diff: models.Diff{Old: logic.ToReturnUser(user), New: nil},
Diff: models.Diff{Old: logic.ToUserEventLog(user), New: nil},
})
logger.Log(1, username, "was deleted")
deleted++
@@ -1986,8 +1991,8 @@ func bulkUpdateUserStatus(w http.ResponseWriter, r *http.Request) {
Type: schema.UserSub,
},
Diff: models.Diff{
Old: logic.ToReturnUser(&oldUser),
New: logic.ToReturnUser(user),
Old: logic.ToUserEventLog(&oldUser),
New: logic.ToUserEventLog(user),
},
Origin: schema.Dashboard,
})