diff --git a/controllers/hosts.go b/controllers/hosts.go index 013ef6abd..5ae3cb8a8 100644 --- a/controllers/hosts.go +++ b/controllers/hosts.go @@ -31,6 +31,7 @@ func hostHandlers(r *mux.Router) { r.HandleFunc("/api/hosts/adm/authenticate", authenticateHost).Methods(http.MethodPost) r.HandleFunc("/api/v1/host", Authorize(true, false, "host", http.HandlerFunc(pull))).Methods(http.MethodGet) r.HandleFunc("/api/v1/host/{hostid}/signalpeer", Authorize(true, false, "host", http.HandlerFunc(signalPeer))).Methods(http.MethodPost) + r.HandleFunc("/api/v1/fallback/host/{hostid}", Authorize(true, false, "host", http.HandlerFunc(hostUpdateFallback))).Methods(http.MethodPut) r.HandleFunc("/api/v1/auth-register/host", socketHandler) } @@ -141,6 +142,8 @@ func pull(w http.ResponseWriter, r *http.Request) { Peers: hPU.Peers, PeerIDs: hPU.PeerIDs, HostNetworkInfo: hPU.HostNetworkInfo, + EgressRoutes: hPU.EgressRoutes, + FwUpdate: hPU.FwUpdate, } logger.Log(1, hostID, "completed a pull") @@ -208,6 +211,51 @@ func updateHost(w http.ResponseWriter, r *http.Request) { json.NewEncoder(w).Encode(apiHostData) } +// swagger:route PUT /api/v1/fallback/host/{hostid} hosts hostUpdateFallback +// +// Updates a Netclient host on Netmaker server. +// +// Schemes: https +// +// Security: +// oauth +// +// Responses: +// 200: apiHostResponse +func hostUpdateFallback(w http.ResponseWriter, r *http.Request) { + var params = mux.Vars(r) + hostid := params["hostid"] + currentHost, err := logic.GetHost(hostid) + if err != nil { + slog.Error("error getting host", "id", hostid, "error", err) + return + } + + var hostUpdate models.HostUpdate + err = json.NewDecoder(r.Body).Decode(&hostUpdate) + if err != nil { + logger.Log(0, r.Header.Get("user"), "failed to update a host:", err.Error()) + logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal")) + return + } + slog.Info("recieved host update", "name", hostUpdate.Host.Name, "id", hostUpdate.Host.ID) + switch hostUpdate.Action { + case models.CheckIn: + _ = mq.HandleHostCheckin(&hostUpdate.Host, currentHost) + + case models.UpdateHost: + + _ = logic.UpdateHostFromClient(&hostUpdate.Host, currentHost) + err := logic.UpsertHost(currentHost) + if err != nil { + slog.Error("failed to update host", "id", currentHost.ID, "error", err) + return + } + + } + +} + // swagger:route DELETE /api/hosts/{hostid} hosts deleteHost // // Deletes a Netclient host from Netmaker server. @@ -497,7 +545,7 @@ func authenticateHost(response http.ResponseWriter, request *http.Request) { // Create EMQX creds and ACLs if not found if servercfg.GetBrokerType() == servercfg.EmqxBrokerType { - if err := mq.CreateEmqxUser(host.ID.String(), host.HostPass, false); err != nil { + if err := mq.CreateEmqxUser(host.ID.String(), authRequest.Password, false); err != nil { slog.Error("failed to create host credentials for EMQX: ", err.Error()) } else { if err := mq.CreateHostACL(host.ID.String(), servercfg.GetServerInfo().Server); err != nil { diff --git a/models/structs.go b/models/structs.go index 5b21f9211..fc03cc957 100644 --- a/models/structs.go +++ b/models/structs.go @@ -225,12 +225,14 @@ type TrafficKeys struct { // HostPull - response of a host's pull type HostPull struct { - Host Host `json:"host" yaml:"host"` - Nodes []Node `json:"nodes" yaml:"nodes"` - Peers []wgtypes.PeerConfig `json:"peers" yaml:"peers"` - ServerConfig ServerConfig `json:"server_config" yaml:"server_config"` - PeerIDs PeerMap `json:"peer_ids,omitempty" yaml:"peer_ids,omitempty"` - HostNetworkInfo HostInfoMap `json:"host_network_info,omitempty" yaml:"host_network_info,omitempty"` + Host Host `json:"host" yaml:"host"` + Nodes []Node `json:"nodes" yaml:"nodes"` + Peers []wgtypes.PeerConfig `json:"peers" yaml:"peers"` + ServerConfig ServerConfig `json:"server_config" yaml:"server_config"` + PeerIDs PeerMap `json:"peer_ids,omitempty" yaml:"peer_ids,omitempty"` + HostNetworkInfo HostInfoMap `json:"host_network_info,omitempty" yaml:"host_network_info,omitempty"` + EgressRoutes []EgressNetworkRoutes `json:"egress_network_routes"` + FwUpdate FwUpdate `json:"fw_update"` } // NodeGet - struct for a single node get response @@ -261,6 +263,7 @@ type ServerConfig struct { MQPort string `yaml:"mqport"` MQUserName string `yaml:"mq_username"` MQPassword string `yaml:"mq_password"` + BrokerType string `yaml:"broker_type"` Server string `yaml:"server"` Broker string `yaml:"broker"` IsPro bool `yaml:"isee" json:"Is_EE"` diff --git a/mq/handlers.go b/mq/handlers.go index 6df352833..066b6f825 100644 --- a/mq/handlers.go +++ b/mq/handlers.go @@ -104,7 +104,7 @@ func UpdateHost(client mqtt.Client, msg mqtt.Message) { var sendPeerUpdate bool switch hostUpdate.Action { case models.CheckIn: - sendPeerUpdate = handleHostCheckin(&hostUpdate.Host, currentHost) + sendPeerUpdate = HandleHostCheckin(&hostUpdate.Host, currentHost) case models.Acknowledgement: hu := hostactions.GetAction(currentHost.ID.String()) if hu != nil { @@ -258,7 +258,7 @@ func ClientPeerUpdate(client mqtt.Client, msg mqtt.Message) { slog.Info("sent peer updates after signal received from", "id", id) } -func handleHostCheckin(h, currentHost *models.Host) bool { +func HandleHostCheckin(h, currentHost *models.Host) bool { if h == nil { return false } diff --git a/mq/util.go b/mq/util.go index 6ecee1414..d99891098 100644 --- a/mq/util.go +++ b/mq/util.go @@ -78,7 +78,7 @@ func publish(host *models.Host, dest string, msg []byte) error { if encryptErr != nil { return encryptErr } - if mqclient == nil { + if mqclient == nil || !mqclient.IsConnectionOpen() { return errors.New("cannot publish ... mqclient not connected") } diff --git a/servercfg/serverconf.go b/servercfg/serverconf.go index 46b4178f5..dcf4fd8c4 100644 --- a/servercfg/serverconf.go +++ b/servercfg/serverconf.go @@ -119,6 +119,7 @@ func GetServerInfo() models.ServerConfig { cfg.APIPort = GetAPIPort() cfg.DNSMode = "off" cfg.Broker = GetPublicBrokerEndpoint() + cfg.BrokerType = GetBrokerType() if IsDNSMode() { cfg.DNSMode = "on" }