diff --git a/auth/auth.go b/auth/auth.go index 771cb84f..b5c6dfb3 100644 --- a/auth/auth.go +++ b/auth/auth.go @@ -15,6 +15,7 @@ import ( "github.com/gravitl/netclient/wireguard" "github.com/gravitl/netmaker/logger" "github.com/gravitl/netmaker/models" + "github.com/gravitl/netmaker/scope" ) var ( @@ -55,12 +56,13 @@ func Authenticate(server *config.Server, host *config.Config) (string, error) { url := fmt.Sprintf("https://%s/api/hosts/adm/authenticate", server.API) headers := make(http.Header) headers.Set("Content-Type", "application/json") + headers.Set(scope.HeaderTenantID, host.TenantID) respBytes, err := ncutils.SendRequest(http.MethodPost, url, headers, data) if err != nil { var notOkErr ncutils.ErrStatusNotOk if errors.As(err, ¬OkErr) { if notOkErr.Status == http.StatusUnauthorized { - if err := cleanUpByServer(server); err != nil { + if err := cleanUpByServer(server, host); err != nil { return "", err } @@ -85,7 +87,7 @@ func Authenticate(server *config.Server, host *config.Config) (string, error) { return token.(string), nil } -func cleanUpByServer(server *config.Server) error { +func cleanUpByServer(server *config.Server, host *config.Config) error { if err := config.ReadNodeConfig(); err != nil { return err } @@ -111,7 +113,19 @@ func cleanUpByServer(server *config.Server) error { if err := config.WriteNetclientConfig(); err != nil { return err } - config.DeleteServer(server.Name) + + freshServer := config.GetServer(server.Name) + if freshServer != nil && host != nil && host.TenantID != "" { + logger.Log(0, "removing unauthorized tenant", host.TenantID, "from", server.Name) + delete(freshServer.HostIDs, host.TenantID) + if len(freshServer.HostIDs) == 0 { + config.DeleteServer(server.Name) + } else { + config.UpdateServer(server.Name, *freshServer) + } + } else { + config.DeleteServer(server.Name) + } if err := config.WriteServerConfig(); err != nil { return err } diff --git a/cmd/root.go b/cmd/root.go index 804b351b..05e63f55 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -434,9 +434,19 @@ func checkConfig() { fail = true logger.Log(0, "configuration for", config.CurrServer, "is missing") } else { - if server.MQID != netclient.ID { + if len(server.HostIDs) == 0 && netclient.ID != uuid.Nil { + // pre-multi-tenancy configs predate the HostIDs map; backfill it + // from the existing single host id instead of failing + logger.Log(0, "backfilling host id for", server.Name) + server.HostIDs = map[string]uuid.UUID{netclient.TenantID: netclient.ID} + config.UpdateServer(server.Name, *server) + if err := config.WriteServerConfig(); err != nil { + logger.Log(0, "failed to save server", server.Name, err.Error()) + } + } + if server.HostIDs[netclient.TenantID] != netclient.ID { fail = true - logger.Log(0, server.Name, "is misconfigured: MQID/Password does not match hostid/password") + logger.Log(0, server.Name, "is misconfigured: registered host ID does not match hostid/password") } } } diff --git a/cmd/server.go b/cmd/server.go index e8480145..a21dcdfc 100644 --- a/cmd/server.go +++ b/cmd/server.go @@ -38,6 +38,8 @@ func init() { serverCmd.AddCommand(listServersCmd) serverCmd.AddCommand(switchServerCmd) + leaveServerCmd.Flags().String("tenant-id", "", "leave only the specified tenant on the server") + // Here you will define your flags and configuration settings. // Cobra supports Persistent Flags which will work for this command @@ -53,10 +55,11 @@ func init() { var leaveServerCmd = &cobra.Command{ Use: "leave [servername]", Short: "leave a server", - Long: `leave the specified server`, + Long: `leave the specified server. Use --tenant-id to leave only that tenant; omit it to leave every tenant registered on the server.`, Args: cobra.ExactArgs(1), Run: func(cmd *cobra.Command, args []string) { - if err := functions.LeaveServer(args[0]); err != nil { + tenantID, _ := cmd.Flags().GetString("tenant-id") + if err := functions.LeaveServer(args[0], tenantID); err != nil { fmt.Println(err.Error()) } }, diff --git a/config/server.go b/config/server.go index 49c73d6e..0ca701cc 100644 --- a/config/server.go +++ b/config/server.go @@ -9,6 +9,7 @@ import ( "github.com/google/uuid" "github.com/gravitl/netmaker/models" + "github.com/gravitl/netmaker/schema" ) var serverMutex sync.RWMutex @@ -27,12 +28,12 @@ const ServerLockfile = "netclient-servers.lck" // Server represents a server configuration type Server struct { models.ServerConfig - Name string `json:"name" yaml:"name"` - MQID uuid.UUID `json:"mqid" yaml:"mqid"` - Nodes map[string]bool `json:"nodes" yaml:"nodes"` - AccessKey string `json:"accesskey" yaml:"accesskey"` - NameServers []string `json:"name_servers"` - DnsNameservers []models.Nameserver `json:"dns_nameservers"` + HostIDs map[string]uuid.UUID `json:"host_ids"` + Name string `json:"name" yaml:"name"` + Nodes map[string]bool `json:"nodes" yaml:"nodes"` + AccessKey string `json:"accesskey" yaml:"accesskey"` + NameServers []string `json:"name_servers"` + DnsNameservers []models.Nameserver `json:"dns_nameservers"` } // TurnConfig - struct to hold turn server config @@ -108,6 +109,17 @@ func GetServer(name string) *Server { return nil } +func GetServerByAPIHost(apiHost string) *Server { + serverMutex.RLock() + defer serverMutex.RUnlock() + for _, server := range Servers { + if server.APIHost == apiHost { + return &server + } + } + return nil +} + // GetServers - gets all the server names host has registered to. func GetServers() (servers []string) { serverMutex.RLock() @@ -164,7 +176,7 @@ func DeleteServer(k string) { } // UpdateServerConfig updates the in memory server map with values provided from netmaker server -func UpdateServerConfig(cfg *models.ServerConfig) { +func UpdateServerConfig(cfg *models.ServerConfig, host *schema.Host) { serverMutex.Lock() defer serverMutex.Unlock() if cfg == nil { @@ -175,8 +187,11 @@ func UpdateServerConfig(cfg *models.ServerConfig) { server = Server{} server.Nodes = make(map[string]bool) } + if server.HostIDs == nil { + server.HostIDs = make(map[string]uuid.UUID) + } + server.HostIDs[host.TenantID] = host.ID server.Name = cfg.Server - server.MQID = netclient.ID server.ServerConfig = *cfg Servers[cfg.Server] = server } diff --git a/flow/manager_linux.go b/flow/manager_linux.go index 0c6fceb6..32b32e67 100644 --- a/flow/manager_linux.go +++ b/flow/manager_linux.go @@ -109,10 +109,15 @@ func (m *Manager) Start(participantIdentifiers map[string]models.PeerIdentity) e identity, found := m.participantIdentifiers[ipCidr] if !found { for addr := range m.participantIdentifiers { + if addr == "0.0.0.0/0" || addr == "::/0" { + continue + } + _, cidr, err := net.ParseCIDR(addr) if err != nil { continue } + if cidr.Contains(net.ParseIP(ip)) { identity, found = m.participantIdentifiers[addr] break diff --git a/flow/tracker/tracker.go b/flow/tracker/tracker.go index 34a68828..60b2511e 100644 --- a/flow/tracker/tracker.go +++ b/flow/tracker/tracker.go @@ -184,6 +184,7 @@ func (c *FlowTracker) handleEvent(event ct.Event) error { return c.flowExporter.Export(&pbflow.FlowEvent{ Type: eventType, + TenantId: config.Netclient().TenantID, FlowId: flowID, HostId: c.hostIDStr, HostName: config.Netclient().Name, diff --git a/functions/auto_relay.go b/functions/auto_relay.go index b7e2037b..24b92493 100644 --- a/functions/auto_relay.go +++ b/functions/auto_relay.go @@ -18,6 +18,7 @@ import ( "github.com/gravitl/netmaker/logger" "github.com/gravitl/netmaker/models" "github.com/gravitl/netmaker/schema" + "github.com/gravitl/netmaker/scope" "golang.org/x/exp/slog" ) @@ -560,6 +561,7 @@ func autoRelayME(method, serverName, nodeID, peernodeID, relayID string) error { headers := make(http.Header) headers.Set("Content-Type", "application/json") headers.Set("Authorization", "Bearer "+token) + headers.Set(scope.HeaderTenantID, host.TenantID) _, err = ncutils.SendRequest(method, url, headers, models.AutoRelayMeReq{NodeID: peernodeID, AutoRelayGwID: relayID}) if err != nil { return err diff --git a/functions/daemon.go b/functions/daemon.go index 562be160..a52cf396 100644 --- a/functions/daemon.go +++ b/functions/daemon.go @@ -19,6 +19,7 @@ import ( mqtt "github.com/eclipse/paho.mqtt.golang" externalip "github.com/glendc/go-external-ip" + "github.com/google/uuid" "github.com/gravitl/netclient/auth" "github.com/gravitl/netclient/cache" "github.com/gravitl/netclient/config" @@ -595,8 +596,10 @@ func unsubscribeNode(client mqtt.Client, node *config.Node) { } // unsubscribe client broker communications for host topics -func unsubscribeHost(client mqtt.Client, server string) { - hostID := config.Netclient().ID +func unsubscribeHost(client mqtt.Client, server string, hostID uuid.UUID) { + if hostID != config.Netclient().ID { + return + } slog.Info("removing subscription for host peer updates", "host", hostID, "server", server) if token := client.Unsubscribe(fmt.Sprintf("peers/host/%s/%s", hostID.String(), server)); token.WaitTimeout(MQ_TIMEOUT*time.Second) && token.Error() != nil { slog.Error("unable to unsubscribe from host peer updates", "host", hostID, "server", server, "error", token.Error()) diff --git a/functions/list.go b/functions/list.go index 1add606e..ca21ea6e 100644 --- a/functions/list.go +++ b/functions/list.go @@ -11,6 +11,7 @@ import ( "github.com/gravitl/netclient/ncutils" "github.com/gravitl/netmaker/logger" "github.com/gravitl/netmaker/models" + "github.com/gravitl/netmaker/scope" "golang.zx2c4.com/wireguard/wgctrl/wgtypes" ) @@ -103,6 +104,7 @@ func GetNodePeers(node config.Node) ([]wgtypes.PeerConfig, error) { headers := make(http.Header) headers.Set("Content-Type", "application/json") headers.Set("Authorization", "Bearer "+token) + headers.Set(scope.HeaderTenantID, host.TenantID) respBytes, err := ncutils.SendRequest(http.MethodGet, url, headers, nil) if err != nil { return nil, err diff --git a/functions/mqhandlers.go b/functions/mqhandlers.go index ebed63e1..6d8b124c 100644 --- a/functions/mqhandlers.go +++ b/functions/mqhandlers.go @@ -28,6 +28,7 @@ import ( "github.com/gravitl/netmaker/logger" "github.com/gravitl/netmaker/models" "github.com/gravitl/netmaker/schema" + "github.com/gravitl/netmaker/scope" "golang.org/x/exp/slog" "golang.zx2c4.com/wireguard/wgctrl/wgtypes" ) @@ -492,8 +493,8 @@ func HostUpdate(client mqtt.Client, msg mqtt.Message) { resetInterface = true case models.DeleteHost: clearRetainedMsg(client, msg.Topic()) - unsubscribeHost(client, serverName) - deleteHostCfg(client, serverName) + unsubscribeHost(client, serverName, hostUpdate.Host.ID) + deleteHostCfg(client, serverName, hostUpdate.Host.TenantID) config.WriteNodeConfig() config.WriteServerConfig() config.DeleteClientNodes() @@ -648,7 +649,7 @@ func handleEndpointDetection(peers []wgtypes.PeerConfig, peerInfo models.HostInf } } -func deleteHostCfg(client mqtt.Client, server string) { +func deleteHostCfg(client mqtt.Client, server, tenantID string) { config.DeleteServerHostPeerCfg() nodes := config.GetNodes() for k, node := range nodes { @@ -658,7 +659,18 @@ func deleteHostCfg(client mqtt.Client, server string) { config.DeleteNode(k) } } - config.DeleteServer(server) + + srvCfg := config.GetServer(server) + if srvCfg != nil && tenantID != "" { + delete(srvCfg.HostIDs, tenantID) + if len(srvCfg.HostIDs) == 0 { + config.DeleteServer(server) + } else { + config.UpdateServer(server, *srvCfg) + } + } else { + config.DeleteServer(server) + } } func parseNetworkFromTopic(topic string) string { @@ -719,6 +731,7 @@ func getServerBrokerStatus() (bool, error) { url := fmt.Sprintf("https://%s/api/server/status", server.API) headers := make(http.Header) headers.Set("Content-Type", "application/json") + headers.Set(scope.HeaderTenantID, config.Netclient().TenantID) respBytes, err := ncutils.SendRequest(http.MethodGet, url, headers, nil) if err != nil { logger.Log(1, "failed to read from server during metrics publish", err.Error()) diff --git a/functions/mqpublish.go b/functions/mqpublish.go index 6367feac..e0391a4a 100644 --- a/functions/mqpublish.go +++ b/functions/mqpublish.go @@ -21,6 +21,7 @@ import ( "github.com/gravitl/netmaker/logger" "github.com/gravitl/netmaker/models" "github.com/gravitl/netmaker/schema" + "github.com/gravitl/netmaker/scope" "github.com/gravitl/netmaker/utils" "golang.org/x/exp/slog" ) @@ -194,6 +195,7 @@ func hostUpdateWithServer(server *config.Server, hu models.HostUpdate) error { headers := make(http.Header) headers.Set("Content-Type", "application/json") headers.Set("Authorization", "Bearer "+token) + headers.Set(scope.HeaderTenantID, host.TenantID) _, err = ncutils.SendRequest(http.MethodPut, url, headers, buildHostUpdatePayload(hu)) if err != nil { if denyErr := auth.AsMDMDenied(err); errors.Is(denyErr, auth.ErrMDMDenied) { diff --git a/functions/pull.go b/functions/pull.go index 7ae42171..9fa7bf01 100644 --- a/functions/pull.go +++ b/functions/pull.go @@ -15,6 +15,7 @@ import ( "github.com/gravitl/netclient/wireguard" "github.com/gravitl/netmaker/logger" "github.com/gravitl/netmaker/models" + "github.com/gravitl/netmaker/scope" ) var pMutex = sync.Mutex{} // used to mutex functions for pull @@ -39,6 +40,7 @@ func Pull(restart bool, resetIfFailedOvered bool) (models.HostPull, bool, bool, headers := make(http.Header) headers.Set("Content-Type", "application/json") headers.Set("Authorization", "Bearer "+token) + headers.Set(scope.HeaderTenantID, config.Netclient().TenantID) respBytes, err := ncutils.SendRequest(http.MethodGet, url, headers, nil) if err != nil { if denyErr := auth.AsMDMDenied(err); errors.Is(denyErr, auth.ErrMDMDenied) { @@ -82,7 +84,7 @@ func Pull(restart bool, resetIfFailedOvered bool) (models.HostPull, bool, bool, } replacePeers = wireguard.ShouldReplace(pullResponse.Peers) config.UpdateHostPeers(pullResponse.Peers) - config.UpdateServerConfig(&pullResponse.ServerConfig) + config.UpdateServerConfig(&pullResponse.ServerConfig, &pullResponse.Host) config.SetNodes(pullResponse.Nodes) UpdateHostFromServer(&pullResponse.Host) server = config.GetServer(serverName) diff --git a/functions/register.go b/functions/register.go index e46201da..c155fc6b 100644 --- a/functions/register.go +++ b/functions/register.go @@ -16,6 +16,7 @@ import ( "github.com/gravitl/netclient/posture" "github.com/gravitl/netmaker/logger" "github.com/gravitl/netmaker/models" + "github.com/gravitl/netmaker/scope" ) // Register - should be simple to register with a token @@ -44,7 +45,7 @@ func Register(token string) error { } else if defaultInterface != ncutils.GetInterfaceName() { host.DefaultInterface = defaultInterface } - shouldUpdateHost, err := doubleCheck(host) + shouldUpdateHost, err := doubleCheck(serverData.Server, serverData.TenantID, host) if err != nil { logger.FatalLog(fmt.Sprintf("error when checking host values - %v", err.Error())) } @@ -55,6 +56,7 @@ func Register(token string) error { url := fmt.Sprintf("https://%s/api/v1/host/register/%s", serverData.Server, token) headers := make(http.Header) headers.Set("Content-Type", "application/json") + headers.Set(scope.HeaderTenantID, serverData.TenantID) posture.ApplyIdentity(&host.Host) respBytes, err := ncutils.SendRequest(http.MethodPost, url, headers, host) if err != nil { @@ -81,7 +83,7 @@ func Register(token string) error { return nil } -func doubleCheck(host *config.Config) (shouldUpdate bool, err error) { +func doubleCheck(server, tenantID string, host *config.Config) (shouldUpdate bool, err error) { var shouldUpdateHost bool if len(config.CurrServer) == 0 { // should indicate a first join @@ -107,6 +109,16 @@ func doubleCheck(host *config.Config) (shouldUpdate bool, err error) { host.HostPass = ncutils.RandomString(32) shouldUpdateHost = true } + } else if tenantID != "" { + var hostIDs map[string]uuid.UUID + if server := config.GetServerByAPIHost(server); server != nil { + hostIDs = server.HostIDs + } + if existingID, ok := hostIDs[tenantID]; ok { + host.ID = existingID + } else if host.ID, err = uuid.NewUUID(); err != nil { + return false, err + } } if shouldUpdateHost { @@ -118,7 +130,7 @@ func doubleCheck(host *config.Config) (shouldUpdate bool, err error) { } func handleRegisterResponse(registerResponse *models.RegisterResponse) { - config.UpdateServerConfig(®isterResponse.ServerConf) + config.UpdateServerConfig(®isterResponse.ServerConf, ®isterResponse.RequestedHost) server := config.GetServer(registerResponse.ServerConf.Server) if err := config.SaveServer(registerResponse.ServerConf.Server, *server); err != nil { logger.Log(0, "failed to save server", err.Error()) diff --git a/functions/register_sso.go b/functions/register_sso.go index b19551a5..1c046975 100644 --- a/functions/register_sso.go +++ b/functions/register_sso.go @@ -53,7 +53,7 @@ func RegisterWithSSO(registerData *RegisterSSO) (err error) { } else { host.DefaultInterface = defaultInterface } - shouldUpdateHost, err := doubleCheck(host) + shouldUpdateHost, err := doubleCheck(registerData.API, "", host) if err != nil { logger.FatalLog(fmt.Sprintf("error when checking host values - %v", err.Error())) } diff --git a/functions/server.go b/functions/server.go index 783c88f6..4d84fcb9 100644 --- a/functions/server.go +++ b/functions/server.go @@ -4,34 +4,44 @@ import ( "errors" "fmt" "net/http" + "slices" "github.com/gravitl/netclient/auth" "github.com/gravitl/netclient/config" "github.com/gravitl/netclient/daemon" "github.com/gravitl/netclient/ncutils" + "github.com/gravitl/netmaker/scope" "golang.zx2c4.com/wireguard/wgctrl/wgtypes" ) -// SwitchServer - switches netclient server context +// SwitchServer - switches netclient server context to the given server, using +// the server's last-registered tenant. func SwitchServer(server string) error { fmt.Println("setting netclient server context to " + server) - if config.GetServer(server) == nil { + srvCfg := config.GetServer(server) + if srvCfg == nil { return errors.New("server config not found") } - currServerCtx, err := config.GetCurrServerCtxFromFile() - if err == nil { - if server == currServerCtx { - fmt.Println("netclient already switched to " + server + " context") - return nil - } + tenantID := srvCfg.TenantID + hostID, ok := srvCfg.HostIDs[tenantID] + if !ok { + return fmt.Errorf("no host identity found for tenant %q on server %q", tenantID, server) } - err = config.SetCurrServerCtxInFile(server) - if err != nil { + currServerCtx, _ := config.GetCurrServerCtxFromFile() + netclient := config.Netclient() + if server == currServerCtx && netclient.TenantID == tenantID { + fmt.Println("netclient already switched to " + server + " context") + return nil + } + + if err := config.SetCurrServerCtxInFile(server); err != nil { fmt.Println("failed to set server context ", err) return err } - config.Netclient().HostPeers = []wgtypes.PeerConfig{} + netclient.ID = hostID + netclient.TenantID = tenantID + netclient.HostPeers = []wgtypes.PeerConfig{} _ = config.WriteNetclientConfig() return daemon.Restart() } @@ -54,30 +64,119 @@ func ListServers() error { return nil } -// LeaveServer - leave the named server -func LeaveServer(s string) error { +// LeaveServer - leave the named server. If tenantID is empty, every tenant +// registered on that server is left; otherwise only the given tenant is left. +func LeaveServer(s, tenantID string) error { server := config.GetServer(s) if server == nil { return errors.New("server not found") } - token, err := auth.Authenticate(server, config.Netclient()) - if err == nil { - url := fmt.Sprintf("https://%s/api/hosts/%s?force=true", server.API, config.Netclient().ID.String()) - headers := make(http.Header) - headers.Set("Content-Type", "application/json") - headers.Set("Authorization", "Bearer "+token) - _, err = ncutils.SendRequest(http.MethodDelete, url, headers, nil) - if err != nil { + + var tenantsToLeave []string + if tenantID != "" { + if _, ok := server.HostIDs[tenantID]; !ok { + return fmt.Errorf("tenant %q not found on server %q", tenantID, s) + } + tenantsToLeave = []string{tenantID} + } else { + for tid := range server.HostIDs { + tenantsToLeave = append(tenantsToLeave, tid) + } + } + + currServerCtx, _ := config.GetCurrServerCtxFromFile() + activeTenantLeaving := s == currServerCtx && slices.Contains(tenantsToLeave, config.Netclient().TenantID) + + for _, tid := range tenantsToLeave { + if err := leaveServerTenant(server, tid); err != nil { return err } + delete(server.HostIDs, tid) + } + + serverRemoved := len(server.HostIDs) == 0 + if serverRemoved { + config.DeleteServerHostPeerCfg() + config.DeleteServer(server.Name) + config.DeleteNodes() + config.DeleteClientNodes() + fmt.Printf("left server %s\n", s) + } else { + config.UpdateServer(server.Name, *server) + fmt.Printf("left tenant %s on server %s\n", tenantID, s) + } + + if activeTenantLeaving { + switchToRemainingServer(server, serverRemoved) } - config.DeleteServerHostPeerCfg() - config.DeleteServer(server.Name) - config.DeleteNodes() - config.DeleteClientNodes() + config.WriteServerConfig() config.WriteNodeConfig() config.WriteNetclientConfig() daemon.Restart() return nil } + +func switchToRemainingServer(leftServer *config.Server, serverRemoved bool) { + netclient := config.Netclient() + + if !serverRemoved { + for tenantID, hostID := range leftServer.HostIDs { + netclient.ID = hostID + netclient.TenantID = tenantID + netclient.HostPeers = []wgtypes.PeerConfig{} + return + } + } + + for _, name := range config.GetServers() { + srvCfg := config.GetServer(name) + if srvCfg == nil || len(srvCfg.HostIDs) == 0 { + continue + } + tenantID := srvCfg.TenantID + hostID, ok := srvCfg.HostIDs[tenantID] + if !ok { + for tid, hid := range srvCfg.HostIDs { + tenantID, hostID, ok = tid, hid, true + break + } + } + _ = config.SetCurrServerCtxInFile(name) + netclient.ID = hostID + netclient.TenantID = tenantID + netclient.HostPeers = []wgtypes.PeerConfig{} + fmt.Println("switched netclient server context to " + name) + return + } + + // no servers left to switch to; clear the stale context + _ = config.SetCurrServerCtxInFile("") +} + +// leaveServerTenant deletes the host record for a single tenant on the given +// server. Auth failures are treated as non-fatal, matching prior behavior +// where local cleanup proceeds regardless. +func leaveServerTenant(server *config.Server, tenantID string) error { + hostID, ok := server.HostIDs[tenantID] + if !ok { + return nil + } + tenantServer := *server + tenantServer.TenantID = tenantID + tenantHost := *config.Netclient() + tenantHost.ID = hostID + tenantHost.TenantID = tenantID + auth.CleanJwtToken() + token, err := auth.Authenticate(&tenantServer, &tenantHost) + if err != nil { + return nil + } + url := fmt.Sprintf("https://%s/api/hosts/%s?force=true", server.API, hostID.String()) + headers := make(http.Header) + headers.Set("Content-Type", "application/json") + headers.Set("Authorization", "Bearer "+token) + headers.Set(scope.HeaderTenantID, tenantID) + _, err = ncutils.SendRequest(http.MethodDelete, url, headers, nil) + return err +} diff --git a/functions/uninstall.go b/functions/uninstall.go index 12887de6..b4b0d5a2 100644 --- a/functions/uninstall.go +++ b/functions/uninstall.go @@ -14,6 +14,7 @@ import ( "github.com/gravitl/netclient/wireguard" "github.com/gravitl/netmaker/logger" "github.com/gravitl/netmaker/models" + "github.com/gravitl/netmaker/scope" ) // Uninstall - uninstalls networks from client @@ -102,6 +103,7 @@ func deleteNodeFromServer(node *config.Node) error { headers.Set("Content-Type", "application/json") headers.Set("Authorization", "Bearer "+token) headers.Set("requestfrom", "node") + headers.Set(scope.HeaderTenantID, config.Netclient().TenantID) _, err = ncutils.SendRequest(http.MethodDelete, url, headers, nil) if err != nil { return fmt.Errorf("error deleting node from network %s on server: %v", node.Network, err) diff --git a/go.mod b/go.mod index 236a5f65..cc62cdb7 100644 --- a/go.mod +++ b/go.mod @@ -12,7 +12,7 @@ require ( github.com/google/nftables v0.3.0 github.com/google/uuid v1.6.0 github.com/gorilla/websocket v1.5.3 - github.com/gravitl/netmaker v1.6.1-0.20260724131718-c6a93b895ed2 + github.com/gravitl/netmaker v1.6.1-0.20260730051954-28cbda317089 github.com/gravitl/tcping v0.1.2-0.20230801110928-546055ebde06 github.com/hashicorp/go-retryablehttp v0.7.8 github.com/hashicorp/go-version v1.9.0 diff --git a/go.sum b/go.sum index 70158094..f486b451 100644 --- a/go.sum +++ b/go.sum @@ -75,8 +75,8 @@ github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY= github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ= github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg= github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/gravitl/netmaker v1.6.1-0.20260724131718-c6a93b895ed2 h1:5ZD7RzGk4O91+t9AQ8WfurVcaMrBdhlV7bdjzbZj3c8= -github.com/gravitl/netmaker v1.6.1-0.20260724131718-c6a93b895ed2/go.mod h1:4DCWDpA7fGV1VImKMCn1GvnGEI89oadrhikJm7i371o= +github.com/gravitl/netmaker v1.6.1-0.20260730051954-28cbda317089 h1:k/KJo9B8VtL5LI76EZv04n1RUEcwUtaQrzROvx7QGiw= +github.com/gravitl/netmaker v1.6.1-0.20260730051954-28cbda317089/go.mod h1:4DCWDpA7fGV1VImKMCn1GvnGEI89oadrhikJm7i371o= github.com/gravitl/tcping v0.1.2-0.20230801110928-546055ebde06 h1:g2fBXRNT9eiQohyHcoME3SVmeG7OKoJPWrs7A+009kU= github.com/gravitl/tcping v0.1.2-0.20230801110928-546055ebde06/go.mod h1:12iViYKWAzRPj5/oEGAaD7Wje+Nuz8M9eDJbV7qhKAA= github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ= diff --git a/networking/client-ping.go b/networking/client-ping.go index 6dc6154a..78a2f517 100644 --- a/networking/client-ping.go +++ b/networking/client-ping.go @@ -19,6 +19,7 @@ import ( "github.com/gravitl/netclient/wireguard" "github.com/gravitl/netmaker/models" "github.com/gravitl/netmaker/schema" + "github.com/gravitl/netmaker/scope" "golang.org/x/exp/slog" ) @@ -207,6 +208,7 @@ func fetchPeerInfo() (models.HostPeerInfo, error) { headers := make(http.Header) headers.Set("Content-Type", "application/json") headers.Set("Authorization", "Bearer "+token) + headers.Set(scope.HeaderTenantID, config.Netclient().TenantID) respBytes, err := ncutils.SendRequest(http.MethodGet, url, headers, nil) if err != nil { var notOkErr ncutils.ErrStatusNotOk diff --git a/posture/client.go b/posture/client.go index 88d079a4..5911b24d 100644 --- a/posture/client.go +++ b/posture/client.go @@ -9,6 +9,7 @@ import ( "github.com/gravitl/netclient/auth" "github.com/gravitl/netclient/config" "github.com/gravitl/netclient/ncutils" + "github.com/gravitl/netmaker/scope" ) // FetchStatus queries the host-authenticated posture endpoint on the named @@ -55,6 +56,7 @@ func postureGet(server *config.Server, host *config.Config) (*HostPostureStatus, headers := make(http.Header) headers.Set("Content-Type", "application/json") headers.Set("Authorization", "Bearer "+token) + headers.Set(scope.HeaderTenantID, host.TenantID) respBytes, err := ncutils.SendRequest(http.MethodGet, url, headers, nil) if err != nil { return nil, err