mirror of
https://github.com/gravitl/netmaker.git
synced 2025-10-08 18:21:18 +08:00
finished initial crud for hosts, fixed stun server close bug
This commit is contained in:
@@ -27,6 +27,7 @@ var HttpHandlers = []interface{}{
|
||||
extClientHandlers,
|
||||
ipHandlers,
|
||||
loggerHandlers,
|
||||
hostHandlers,
|
||||
}
|
||||
|
||||
// HandleRESTRequests - handles the rest requests
|
||||
|
114
controllers/hosts.go
Normal file
114
controllers/hosts.go
Normal file
@@ -0,0 +1,114 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/gravitl/netmaker/logger"
|
||||
"github.com/gravitl/netmaker/logic"
|
||||
"github.com/gravitl/netmaker/models"
|
||||
)
|
||||
|
||||
func hostHandlers(r *mux.Router) {
|
||||
r.HandleFunc("/api/hosts", logic.SecurityCheck(false, http.HandlerFunc(getHosts))).Methods("GET")
|
||||
r.HandleFunc("/api/hosts", logic.SecurityCheck(true, http.HandlerFunc(updateHost))).Methods("PUT")
|
||||
r.HandleFunc("/api/hosts/{hostid}", logic.SecurityCheck(true, http.HandlerFunc(deleteHost))).Methods("DELETE")
|
||||
// r.HandleFunc("/api/hosts/{hostid}/{network}", logic.SecurityCheck(false, http.HandlerFunc(getHosts))).Methods("PUT")
|
||||
}
|
||||
|
||||
// swagger:route GET /api/hosts hosts getHosts
|
||||
//
|
||||
// Lists all hosts.
|
||||
//
|
||||
// Schemes: https
|
||||
//
|
||||
// Security:
|
||||
// oauth
|
||||
//
|
||||
// Responses:
|
||||
// 200: getHostsSliceResponse
|
||||
func getHosts(w http.ResponseWriter, r *http.Request) {
|
||||
currentHosts, err := logic.GetAllHosts()
|
||||
if err != nil {
|
||||
logger.Log(0, r.Header.Get("user"), "failed to fetch hosts: ", err.Error())
|
||||
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
|
||||
return
|
||||
}
|
||||
logger.Log(2, r.Header.Get("user"), "fetched all hosts")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
json.NewEncoder(w).Encode(currentHosts)
|
||||
}
|
||||
|
||||
// swagger:route PUT /api/hosts/{hostid} hosts updateHost
|
||||
//
|
||||
// Updates a Netclient host on Netmaker server.
|
||||
//
|
||||
// Schemes: https
|
||||
//
|
||||
// Security:
|
||||
// oauth
|
||||
//
|
||||
// Responses:
|
||||
// 200: updateHostResponse
|
||||
func updateHost(w http.ResponseWriter, r *http.Request) {
|
||||
var newHostData models.Host
|
||||
err := json.NewDecoder(r.Body).Decode(&newHostData)
|
||||
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
|
||||
}
|
||||
|
||||
// confirm host exists
|
||||
currHost, err := logic.GetHost(newHostData.ID.String())
|
||||
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
|
||||
}
|
||||
|
||||
logic.UpdateHost(&newHostData, currHost) // update the in memory struct values
|
||||
if err = logic.UpsertHost(&newHostData); 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
|
||||
}
|
||||
|
||||
logger.Log(2, r.Header.Get("user"), "updated host", newHostData.ID.String())
|
||||
w.WriteHeader(http.StatusOK)
|
||||
json.NewEncoder(w).Encode(newHostData)
|
||||
}
|
||||
|
||||
// swagger:route DELETE /api/hosts/{hostid} hosts deleteHost
|
||||
//
|
||||
// Deletes a Netclient host from Netmaker server.
|
||||
//
|
||||
// Schemes: https
|
||||
//
|
||||
// Security:
|
||||
// oauth
|
||||
//
|
||||
// Responses:
|
||||
// 200: deleteHostResponse
|
||||
func deleteHost(w http.ResponseWriter, r *http.Request) {
|
||||
var params = mux.Vars(r)
|
||||
hostid := params["hostid"]
|
||||
// confirm host exists
|
||||
currHost, err := logic.GetHost(hostid)
|
||||
if err != nil {
|
||||
logger.Log(0, r.Header.Get("user"), "failed to delete a host:", err.Error())
|
||||
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
|
||||
return
|
||||
}
|
||||
|
||||
if err = logic.RemoveHost(currHost); err != nil {
|
||||
logger.Log(0, r.Header.Get("user"), "failed to delete a host:", err.Error())
|
||||
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
|
||||
return
|
||||
}
|
||||
|
||||
logger.Log(2, r.Header.Get("user"), "removed host", currHost.Name)
|
||||
w.WriteHeader(http.StatusOK)
|
||||
json.NewEncoder(w).Encode(currHost)
|
||||
}
|
@@ -14,96 +14,73 @@ import (
|
||||
"golang.org/x/crypto/nacl/box"
|
||||
)
|
||||
|
||||
const (
|
||||
// == Table Names ==
|
||||
// NETWORKS_TABLE_NAME - networks table
|
||||
const NETWORKS_TABLE_NAME = "networks"
|
||||
|
||||
NETWORKS_TABLE_NAME = "networks"
|
||||
// NODES_TABLE_NAME - nodes table
|
||||
const NODES_TABLE_NAME = "nodes"
|
||||
|
||||
NODES_TABLE_NAME = "nodes"
|
||||
// DELETED_NODES_TABLE_NAME - deleted nodes table
|
||||
const DELETED_NODES_TABLE_NAME = "deletednodes"
|
||||
|
||||
DELETED_NODES_TABLE_NAME = "deletednodes"
|
||||
// USERS_TABLE_NAME - users table
|
||||
const USERS_TABLE_NAME = "users"
|
||||
|
||||
USERS_TABLE_NAME = "users"
|
||||
// CERTS_TABLE_NAME - certificates table
|
||||
const CERTS_TABLE_NAME = "certs"
|
||||
|
||||
CERTS_TABLE_NAME = "certs"
|
||||
// DNS_TABLE_NAME - dns table
|
||||
const DNS_TABLE_NAME = "dns"
|
||||
|
||||
DNS_TABLE_NAME = "dns"
|
||||
// EXT_CLIENT_TABLE_NAME - ext client table
|
||||
const EXT_CLIENT_TABLE_NAME = "extclients"
|
||||
|
||||
EXT_CLIENT_TABLE_NAME = "extclients"
|
||||
// PEERS_TABLE_NAME - peers table
|
||||
const PEERS_TABLE_NAME = "peers"
|
||||
|
||||
PEERS_TABLE_NAME = "peers"
|
||||
// SERVERCONF_TABLE_NAME - stores server conf
|
||||
const SERVERCONF_TABLE_NAME = "serverconf"
|
||||
|
||||
SERVERCONF_TABLE_NAME = "serverconf"
|
||||
// SERVER_UUID_TABLE_NAME - stores unique netmaker server data
|
||||
const SERVER_UUID_TABLE_NAME = "serveruuid"
|
||||
|
||||
SERVER_UUID_TABLE_NAME = "serveruuid"
|
||||
// SERVER_UUID_RECORD_KEY - telemetry thing
|
||||
const SERVER_UUID_RECORD_KEY = "serveruuid"
|
||||
|
||||
SERVER_UUID_RECORD_KEY = "serveruuid"
|
||||
// DATABASE_FILENAME - database file name
|
||||
const DATABASE_FILENAME = "netmaker.db"
|
||||
|
||||
DATABASE_FILENAME = "netmaker.db"
|
||||
// GENERATED_TABLE_NAME - stores server generated k/v
|
||||
const GENERATED_TABLE_NAME = "generated"
|
||||
|
||||
GENERATED_TABLE_NAME = "generated"
|
||||
// NODE_ACLS_TABLE_NAME - stores the node ACL rules
|
||||
const NODE_ACLS_TABLE_NAME = "nodeacls"
|
||||
|
||||
NODE_ACLS_TABLE_NAME = "nodeacls"
|
||||
// SSO_STATE_CACHE - holds sso session information for OAuth2 sign-ins
|
||||
const SSO_STATE_CACHE = "ssostatecache"
|
||||
|
||||
SSO_STATE_CACHE = "ssostatecache"
|
||||
// METRICS_TABLE_NAME - stores network metrics
|
||||
const METRICS_TABLE_NAME = "metrics"
|
||||
|
||||
METRICS_TABLE_NAME = "metrics"
|
||||
// NETWORK_USER_TABLE_NAME - network user table tracks stats for a network user per network
|
||||
const NETWORK_USER_TABLE_NAME = "networkusers"
|
||||
|
||||
NETWORK_USER_TABLE_NAME = "networkusers"
|
||||
// USER_GROUPS_TABLE_NAME - table for storing usergroups
|
||||
const USER_GROUPS_TABLE_NAME = "usergroups"
|
||||
|
||||
USER_GROUPS_TABLE_NAME = "usergroups"
|
||||
// CACHE_TABLE_NAME - caching table
|
||||
const CACHE_TABLE_NAME = "cache"
|
||||
CACHE_TABLE_NAME = "cache"
|
||||
// HOSTS_TABLE_NAME - the table name for hosts
|
||||
HOSTS_TABLE_NAME = "hosts"
|
||||
|
||||
// == ERROR CONSTS ==
|
||||
|
||||
// NO_RECORD - no singular result found
|
||||
const NO_RECORD = "no result found"
|
||||
|
||||
NO_RECORD = "no result found"
|
||||
// NO_RECORDS - no results found
|
||||
const NO_RECORDS = "could not find any records"
|
||||
|
||||
// == Constants ==
|
||||
NO_RECORDS = "could not find any records"
|
||||
|
||||
// == DB Constants ==
|
||||
// INIT_DB - initialize db
|
||||
const INIT_DB = "init"
|
||||
|
||||
INIT_DB = "init"
|
||||
// CREATE_TABLE - create table const
|
||||
const CREATE_TABLE = "createtable"
|
||||
|
||||
CREATE_TABLE = "createtable"
|
||||
// INSERT - insert into db const
|
||||
const INSERT = "insert"
|
||||
|
||||
INSERT = "insert"
|
||||
// INSERT_PEER - insert peer into db const
|
||||
const INSERT_PEER = "insertpeer"
|
||||
|
||||
INSERT_PEER = "insertpeer"
|
||||
// DELETE - delete db record const
|
||||
const DELETE = "delete"
|
||||
|
||||
DELETE = "delete"
|
||||
// DELETE_ALL - delete a table const
|
||||
const DELETE_ALL = "deleteall"
|
||||
|
||||
DELETE_ALL = "deleteall"
|
||||
// FETCH_ALL - fetch table contents const
|
||||
const FETCH_ALL = "fetchall"
|
||||
|
||||
FETCH_ALL = "fetchall"
|
||||
// CLOSE_DB - graceful close of db const
|
||||
const CLOSE_DB = "closedb"
|
||||
CLOSE_DB = "closedb"
|
||||
)
|
||||
|
||||
func getCurrentDB() map[string]interface{} {
|
||||
switch servercfg.GetDB() {
|
||||
@@ -155,6 +132,7 @@ func createTables() {
|
||||
createTable(NETWORK_USER_TABLE_NAME)
|
||||
createTable(USER_GROUPS_TABLE_NAME)
|
||||
createTable(CACHE_TABLE_NAME)
|
||||
createTable(HOSTS_TABLE_NAME)
|
||||
}
|
||||
|
||||
func createTable(tableName string) error {
|
||||
|
139
logic/hosts.go
Normal file
139
logic/hosts.go
Normal file
@@ -0,0 +1,139 @@
|
||||
package logic
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"github.com/gravitl/netmaker/database"
|
||||
"github.com/gravitl/netmaker/models"
|
||||
)
|
||||
|
||||
// GetAllHosts - returns all hosts in flat list or error
|
||||
func GetAllHosts() ([]models.Host, error) {
|
||||
currHostMap, err := GetHostsMap()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var currentHosts = []models.Host{}
|
||||
for k := range currHostMap {
|
||||
var h = *currHostMap[k]
|
||||
currentHosts = append(currentHosts, h)
|
||||
}
|
||||
|
||||
return currentHosts, nil
|
||||
}
|
||||
|
||||
// GetHostsMap - gets all the current hosts on machine in a map
|
||||
func GetHostsMap() (map[string]*models.Host, error) {
|
||||
records, err := database.FetchRecords(database.HOSTS_TABLE_NAME)
|
||||
if err != nil && !database.IsEmptyRecord(err) {
|
||||
return nil, err
|
||||
}
|
||||
currHostMap := make(map[string]*models.Host)
|
||||
for k := range records {
|
||||
var h models.Host
|
||||
err = json.Unmarshal([]byte(records[k]), &h)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
currHostMap[h.ID.String()] = &h
|
||||
}
|
||||
|
||||
return currHostMap, nil
|
||||
}
|
||||
|
||||
// GetHost - gets a host from db given id
|
||||
func GetHost(hostid string) (*models.Host, error) {
|
||||
record, err := database.FetchRecord(database.HOSTS_TABLE_NAME, hostid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var h models.Host
|
||||
if err = json.Unmarshal([]byte(record), &h); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &h, nil
|
||||
}
|
||||
|
||||
// CreateHost - creates a host if not exist
|
||||
func CreateHost(h *models.Host) error {
|
||||
_, err := GetHost(h.ID.String())
|
||||
if (err != nil && !database.IsEmptyRecord(err)) || (err == nil) {
|
||||
return fmt.Errorf("host already exists")
|
||||
}
|
||||
|
||||
return UpsertHost(h)
|
||||
}
|
||||
|
||||
// UpdateHost - updates host data by field
|
||||
func UpdateHost(newHost, currentHost *models.Host) {
|
||||
// unchangeable fields via API here
|
||||
newHost.DaemonInstalled = currentHost.DaemonInstalled
|
||||
newHost.OS = currentHost.OS
|
||||
newHost.IPForwarding = currentHost.IPForwarding
|
||||
newHost.HostPass = currentHost.HostPass
|
||||
newHost.NodePassword = currentHost.NodePassword
|
||||
newHost.MacAddress = currentHost.MacAddress
|
||||
newHost.Debug = currentHost.Debug
|
||||
newHost.Nodes = currentHost.Nodes
|
||||
newHost.PublicKey = currentHost.PublicKey
|
||||
newHost.InternetGateway = currentHost.InternetGateway
|
||||
newHost.TrafficKeyPublic = currentHost.TrafficKeyPublic
|
||||
|
||||
// changeable fields
|
||||
if len(newHost.Version) == 0 {
|
||||
newHost.Version = currentHost.Version
|
||||
}
|
||||
|
||||
if len(newHost.Name) == 0 {
|
||||
newHost.Name = currentHost.Name
|
||||
}
|
||||
|
||||
if newHost.LocalAddress.String() != currentHost.LocalAddress.String() {
|
||||
newHost.LocalAddress = currentHost.LocalAddress
|
||||
}
|
||||
|
||||
if newHost.LocalRange.String() != currentHost.LocalRange.String() {
|
||||
newHost.LocalRange = currentHost.LocalRange
|
||||
}
|
||||
|
||||
if newHost.MTU == 0 {
|
||||
newHost.MTU = currentHost.MTU
|
||||
}
|
||||
|
||||
if newHost.ListenPort == 0 {
|
||||
newHost.ListenPort = currentHost.ListenPort
|
||||
}
|
||||
|
||||
if newHost.ProxyListenPort == 0 {
|
||||
newHost.ProxyListenPort = currentHost.ProxyListenPort
|
||||
}
|
||||
}
|
||||
|
||||
// UpsertHost - upserts into DB a given host model, does not check for existence*
|
||||
func UpsertHost(h *models.Host) error {
|
||||
data, err := json.Marshal(h)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return database.Insert(h.ID.String(), string(data), database.HOSTS_TABLE_NAME)
|
||||
}
|
||||
|
||||
// RemoveHost - removes a given host from server
|
||||
func RemoveHost(h *models.Host) error {
|
||||
if len(h.Nodes) > 0 {
|
||||
for i := range h.Nodes {
|
||||
id := h.Nodes[i]
|
||||
n, err := GetNodeByID(id)
|
||||
if err == nil {
|
||||
if err = DeleteNodeByID(&n); err != nil {
|
||||
return err // must remove associated nodes before removing a host
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return database.DeleteRecord(database.HOSTS_TABLE_NAME, h.ID.String())
|
||||
}
|
@@ -30,5 +30,5 @@ type Host struct {
|
||||
MacAddress net.HardwareAddr `json:"macaddress" yaml:"macaddress"`
|
||||
TrafficKeyPublic []byte `json:"traffickeypublic" yaml:"trafficekeypublic"`
|
||||
InternetGateway net.UDPAddr `json:"internetgateway" yaml:"internetgateway"`
|
||||
Nodes []Node `json:"nodes" yaml:"nodes"`
|
||||
Nodes []string `json:"nodes" yaml:"nodes"`
|
||||
}
|
||||
|
@@ -144,20 +144,20 @@ func normalize(address string) string {
|
||||
return address
|
||||
}
|
||||
|
||||
// Start - starts the stun server
|
||||
func Start(wg *sync.WaitGroup) {
|
||||
defer wg.Done()
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
go func() {
|
||||
go func(wg *sync.WaitGroup) {
|
||||
defer wg.Done()
|
||||
quit := make(chan os.Signal, 1)
|
||||
signal.Notify(quit, syscall.SIGTERM, os.Interrupt)
|
||||
<-quit
|
||||
cancel()
|
||||
}()
|
||||
}(wg)
|
||||
normalized := normalize(fmt.Sprintf("0.0.0.0:%d", servercfg.GetStunPort()))
|
||||
logger.Log(0, "netmaker-stun listening on", normalized, "via udp")
|
||||
err := listenUDPAndServe(ctx, "udp", normalized)
|
||||
if err != nil {
|
||||
logger.Log(0, "failed to start stun server: ", err.Error())
|
||||
}
|
||||
|
||||
}
|
||||
|
Reference in New Issue
Block a user