mirror of
https://github.com/gravitl/netmaker.git
synced 2024-09-20 23:36:18 +08:00
Merge pull request #2199 from gravitl/GRA-1529-key-update
refactor key updates on host basis vice node
This commit is contained in:
commit
7652904e87
|
@ -20,6 +20,8 @@ import (
|
|||
|
||||
func hostHandlers(r *mux.Router) {
|
||||
r.HandleFunc("/api/hosts", logic.SecurityCheck(true, http.HandlerFunc(getHosts))).Methods(http.MethodGet)
|
||||
r.HandleFunc("/api/hosts/keys", logic.SecurityCheck(true, http.HandlerFunc(updateAllKeys))).Methods(http.MethodPut)
|
||||
r.HandleFunc("/api/hosts/{hostid}/keys", logic.SecurityCheck(true, http.HandlerFunc(updateKeys))).Methods(http.MethodPut)
|
||||
r.HandleFunc("/api/hosts/{hostid}", logic.SecurityCheck(true, http.HandlerFunc(updateHost))).Methods(http.MethodPut)
|
||||
r.HandleFunc("/api/hosts/{hostid}", logic.SecurityCheck(true, http.HandlerFunc(deleteHost))).Methods(http.MethodDelete)
|
||||
r.HandleFunc("/api/hosts/{hostid}/networks/{network}", logic.SecurityCheck(true, http.HandlerFunc(addHostToNetwork))).Methods(http.MethodPost)
|
||||
|
@ -447,3 +449,80 @@ func authenticateHost(response http.ResponseWriter, request *http.Request) {
|
|||
response.Header().Set("Content-Type", "application/json")
|
||||
response.Write(successJSONResponse)
|
||||
}
|
||||
|
||||
// swagger:route POST /api/hosts/keys host updateAllKeys
|
||||
//
|
||||
// Update keys for a network.
|
||||
//
|
||||
// Schemes: https
|
||||
//
|
||||
// Security:
|
||||
// oauth
|
||||
//
|
||||
// Responses:
|
||||
// 200: networkBodyResponse
|
||||
func updateAllKeys(w http.ResponseWriter, r *http.Request) {
|
||||
var errorResponse = models.ErrorResponse{}
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
hosts, err := logic.GetAllHosts()
|
||||
if err != nil {
|
||||
errorResponse.Code = http.StatusBadRequest
|
||||
errorResponse.Message = err.Error()
|
||||
logger.Log(0, r.Header.Get("user"),
|
||||
"error retrieving hosts ", err.Error())
|
||||
logic.ReturnErrorResponse(w, r, errorResponse)
|
||||
return
|
||||
}
|
||||
go func() {
|
||||
hostUpdate := models.HostUpdate{}
|
||||
hostUpdate.Action = models.UpdateKeys
|
||||
for _, host := range hosts {
|
||||
hostUpdate.Host = host
|
||||
logger.Log(2, "updating host", host.ID.String(), " for a key update")
|
||||
if err = mq.HostUpdate(&hostUpdate); err != nil {
|
||||
logger.Log(0, "failed to send update to node during a network wide key update", host.ID.String(), err.Error())
|
||||
}
|
||||
}
|
||||
}()
|
||||
logger.Log(2, r.Header.Get("user"), "updated keys for all hosts")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
||||
// swagger:route POST /api/hosts/{hostid}keys host updateKeys
|
||||
//
|
||||
// Update keys for a network.
|
||||
//
|
||||
// Schemes: https
|
||||
//
|
||||
// Security:
|
||||
// oauth
|
||||
//
|
||||
// Responses:
|
||||
// 200: networkBodyResponse
|
||||
func updateKeys(w http.ResponseWriter, r *http.Request) {
|
||||
var errorResponse = models.ErrorResponse{}
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
var params = mux.Vars(r)
|
||||
hostid := params["hostid"]
|
||||
host, err := logic.GetHost(hostid)
|
||||
if err != nil {
|
||||
logger.Log(0, "failed to retrieve host", hostid, err.Error())
|
||||
errorResponse.Code = http.StatusBadRequest
|
||||
errorResponse.Message = err.Error()
|
||||
logger.Log(0, r.Header.Get("user"),
|
||||
"error retrieving hosts ", err.Error())
|
||||
logic.ReturnErrorResponse(w, r, errorResponse)
|
||||
return
|
||||
}
|
||||
go func() {
|
||||
hostUpdate := models.HostUpdate{
|
||||
Action: models.UpdateKeys,
|
||||
Host: *host,
|
||||
}
|
||||
if err = mq.HostUpdate(&hostUpdate); err != nil {
|
||||
logger.Log(0, "failed to send host key update", host.ID.String(), err.Error())
|
||||
}
|
||||
}()
|
||||
logger.Log(2, r.Header.Get("user"), "updated key on host", host.Name)
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
|
|
@ -23,7 +23,6 @@ func networkHandlers(r *mux.Router) {
|
|||
r.HandleFunc("/api/networks", logic.SecurityCheck(true, checkFreeTierLimits(networks_l, http.HandlerFunc(createNetwork)))).Methods(http.MethodPost)
|
||||
r.HandleFunc("/api/networks/{networkname}", logic.SecurityCheck(false, http.HandlerFunc(getNetwork))).Methods(http.MethodGet)
|
||||
r.HandleFunc("/api/networks/{networkname}", logic.SecurityCheck(true, http.HandlerFunc(deleteNetwork))).Methods(http.MethodDelete)
|
||||
r.HandleFunc("/api/networks/{networkname}/keyupdate", logic.SecurityCheck(true, http.HandlerFunc(keyUpdate))).Methods(http.MethodPost)
|
||||
// ACLs
|
||||
r.HandleFunc("/api/networks/{networkname}/acls", logic.SecurityCheck(true, http.HandlerFunc(updateNetworkACL))).Methods(http.MethodPut)
|
||||
r.HandleFunc("/api/networks/{networkname}/acls", logic.SecurityCheck(true, http.HandlerFunc(getNetworkACL))).Methods(http.MethodGet)
|
||||
|
@ -104,44 +103,6 @@ func getNetwork(w http.ResponseWriter, r *http.Request) {
|
|||
json.NewEncoder(w).Encode(network)
|
||||
}
|
||||
|
||||
// swagger:route POST /api/networks/{networkname}/keyupdate networks keyUpdate
|
||||
//
|
||||
// Update keys for a network.
|
||||
//
|
||||
// Schemes: https
|
||||
//
|
||||
// Security:
|
||||
// oauth
|
||||
//
|
||||
// Responses:
|
||||
// 200: networkBodyResponse
|
||||
func keyUpdate(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
var params = mux.Vars(r)
|
||||
netname := params["networkname"]
|
||||
network, err := logic.KeyUpdate(netname)
|
||||
if err != nil {
|
||||
logger.Log(0, r.Header.Get("user"), fmt.Sprintf("failed to update keys for network [%s]: %v",
|
||||
netname, err))
|
||||
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
|
||||
return
|
||||
}
|
||||
logger.Log(2, r.Header.Get("user"), "updated key on network", netname)
|
||||
w.WriteHeader(http.StatusOK)
|
||||
json.NewEncoder(w).Encode(network)
|
||||
nodes, err := logic.GetNetworkNodes(netname)
|
||||
if err != nil {
|
||||
logger.Log(0, "failed to retrieve network nodes for network", netname, err.Error())
|
||||
return
|
||||
}
|
||||
for _, node := range nodes {
|
||||
logger.Log(2, "updating node ", node.ID.String(), " for a key update")
|
||||
if err = mq.NodeUpdate(&node); err != nil {
|
||||
logger.Log(1, "failed to send update to node during a network wide key update", node.ID.String(), err.Error())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// swagger:route PUT /api/networks/{networkname}/acls networks updateNetworkACL
|
||||
//
|
||||
// Update a network ACL (Access Control List).
|
||||
|
|
|
@ -153,6 +153,10 @@ func UpdateHost(newHost, currentHost *models.Host) {
|
|||
// UpdateHostFromClient - used for updating host on server with update recieved from client
|
||||
func UpdateHostFromClient(newHost, currHost *models.Host) (sendPeerUpdate bool) {
|
||||
|
||||
if newHost.PublicKey != currHost.PublicKey {
|
||||
currHost.PublicKey = newHost.PublicKey
|
||||
sendPeerUpdate = true
|
||||
}
|
||||
if newHost.ListenPort != 0 && currHost.ListenPort != newHost.ListenPort {
|
||||
currHost.ListenPort = newHost.ListenPort
|
||||
sendPeerUpdate = true
|
||||
|
|
|
@ -555,15 +555,6 @@ func ParseNetwork(value string) (models.Network, error) {
|
|||
return network, err
|
||||
}
|
||||
|
||||
// KeyUpdate - updates keys on network
|
||||
func KeyUpdate(netname string) (models.Network, error) {
|
||||
err := networkNodesUpdateAction(netname, models.NODE_UPDATE_KEY)
|
||||
if err != nil {
|
||||
return models.Network{}, err
|
||||
}
|
||||
return models.Network{}, nil
|
||||
}
|
||||
|
||||
// SaveNetwork - save network struct to database
|
||||
func SaveNetwork(network *models.Network) error {
|
||||
data, err := json.Marshal(network)
|
||||
|
@ -587,46 +578,11 @@ func NetworkExists(name string) (bool, error) {
|
|||
return len(network) > 0, nil
|
||||
}
|
||||
|
||||
// == Private ==
|
||||
|
||||
func networkNodesUpdateAction(networkName string, action string) error {
|
||||
|
||||
collections, err := database.FetchRecords(database.NODES_TABLE_NAME)
|
||||
if err != nil {
|
||||
if database.IsEmptyRecord(err) {
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
for k, value := range collections {
|
||||
var node models.Node
|
||||
err := json.Unmarshal([]byte(value), &node)
|
||||
if err != nil {
|
||||
if IsLegacyNode(k) { // ignore legacy nodes
|
||||
continue
|
||||
}
|
||||
fmt.Println("error in node address assignment!")
|
||||
return err
|
||||
}
|
||||
if action == models.NODE_UPDATE_KEY {
|
||||
continue
|
||||
}
|
||||
if node.Network == networkName {
|
||||
node.Action = action
|
||||
data, err := json.Marshal(&node)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
database.Insert(node.ID.String(), string(data), database.NODES_TABLE_NAME)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// SortNetworks - Sorts slice of Networks by their NetID alphabetically with numbers first
|
||||
func SortNetworks(unsortedNetworks []models.Network) {
|
||||
sort.Slice(unsortedNetworks, func(i, j int) bool {
|
||||
return unsortedNetworks[i].NetID < unsortedNetworks[j].NetID
|
||||
})
|
||||
}
|
||||
|
||||
// == Private ==
|
||||
|
|
|
@ -113,6 +113,8 @@ const (
|
|||
RequestAck = "REQ_ACK"
|
||||
// CheckIn - update last check in times and public address and interfaces
|
||||
CheckIn = "CHECK_IN"
|
||||
// UpdateKeys - update wireguard private/public keys
|
||||
UpdateKeys = "UPDATE_KEYS"
|
||||
)
|
||||
|
||||
// HostUpdate - struct for host update
|
||||
|
|
|
@ -19,8 +19,6 @@ const (
|
|||
// MAX_NAME_LENGTH - max name length of node
|
||||
MAX_NAME_LENGTH = 62
|
||||
// == ACTIONS == (can only be set by server)
|
||||
// NODE_UPDATE_KEY - action to update key
|
||||
NODE_UPDATE_KEY = "updatekey"
|
||||
// NODE_DELETE - delete node action
|
||||
NODE_DELETE = "delete"
|
||||
// NODE_IS_PENDING - node pending status
|
||||
|
|
|
@ -16,6 +16,7 @@ import (
|
|||
"github.com/gravitl/netmaker/models"
|
||||
"github.com/gravitl/netmaker/netclient/ncutils"
|
||||
"github.com/gravitl/netmaker/servercfg"
|
||||
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
|
||||
)
|
||||
|
||||
// DefaultHandler default message queue handler -- NOT USED
|
||||
|
@ -117,6 +118,28 @@ func UpdateHost(client mqtt.Client, msg mqtt.Message) {
|
|||
}
|
||||
}
|
||||
case models.UpdateHost:
|
||||
if hostUpdate.Host.PublicKey != currentHost.PublicKey {
|
||||
//remove old peer entry
|
||||
peerUpdate := models.HostPeerUpdate{
|
||||
ServerVersion: servercfg.GetVersion(),
|
||||
Peers: []wgtypes.PeerConfig{
|
||||
{
|
||||
PublicKey: currentHost.PublicKey,
|
||||
Remove: true,
|
||||
},
|
||||
},
|
||||
}
|
||||
data, err := json.Marshal(&peerUpdate)
|
||||
if err != nil {
|
||||
logger.Log(2, "json error", err.Error())
|
||||
}
|
||||
hosts := logic.GetRelatedHosts(hostUpdate.Host.ID.String())
|
||||
server := servercfg.GetServer()
|
||||
for _, host := range hosts {
|
||||
publish(&host, fmt.Sprintf("peers/host/%s/%s", host.ID.String(), server), data)
|
||||
}
|
||||
|
||||
}
|
||||
sendPeerUpdate = logic.UpdateHostFromClient(&hostUpdate.Host, currentHost)
|
||||
err := logic.UpsertHost(currentHost)
|
||||
if err != nil {
|
||||
|
|
Loading…
Reference in a new issue