Ver código fonte

restruct migration

Matthew R Kasun 2 anos atrás
pai
commit
7da2e9b9bf
4 arquivos alterados com 135 adições e 82 exclusões
  1. 132 75
      controllers/migrate.go
  2. 1 1
      main.go
  3. 1 1
      models/migrate.go
  4. 1 5
      models/node.go

+ 132 - 75
controllers/migrate.go

@@ -2,15 +2,21 @@ package controller
 
 import (
 	"encoding/json"
+	"fmt"
+	"net"
 	"net/http"
+	"strconv"
+	"time"
 
-	"github.com/gravitl/netmaker/auth"
+	"github.com/google/uuid"
 	"github.com/gravitl/netmaker/database"
 	"github.com/gravitl/netmaker/logger"
 	"github.com/gravitl/netmaker/logic"
 	"github.com/gravitl/netmaker/models"
 	"github.com/gravitl/netmaker/servercfg"
 	"golang.org/x/crypto/bcrypt"
+	"golang.org/x/exp/slog"
+	"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
 )
 
 // swagger:route PUT /api/v1/nodes/migrate nodes migrateNode
@@ -26,95 +32,146 @@ import (
 //				200: nodeJoinResponse
 func migrate(w http.ResponseWriter, r *http.Request) {
 	data := models.MigrationData{}
+	host := models.Host{}
+	node := models.Node{}
+	nodes := []models.Node{}
+	server := models.ServerConfig{}
 	err := json.NewDecoder(r.Body).Decode(&data)
 	if err != nil {
 		logger.Log(0, r.Header.Get("user"), "error decoding request body: ", err.Error())
 		logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
 		return
 	}
-
-	var networksToAdd = []string{}
-	for i := range data.LegacyNodes {
-		legacyNode := data.LegacyNodes[i]
-		record, err := database.FetchRecord(database.NODES_TABLE_NAME, legacyNode.ID)
+	for i, legacy := range data.LegacyNodes {
+		record, err := database.FetchRecord(database.NODES_TABLE_NAME, legacy.ID)
 		if err != nil {
-			logger.Log(0, "no record for legacy node", legacyNode.ID, err.Error())
-			continue
-		} else {
-			var oldLegacyNode models.LegacyNode
-			if err = json.Unmarshal([]byte(record), &oldLegacyNode); err != nil {
-				logger.Log(0, "error decoding legacy node", err.Error())
+			slog.Error("legacy node not found", "error", err)
+			logic.ReturnErrorResponse(w, r, logic.FormatError(fmt.Errorf("legacy node not found %w", err), "badrequest"))
+			return
+		}
+		var legacyNode models.LegacyNode
+		if err = json.Unmarshal([]byte(record), &legacyNode); err != nil {
+			slog.Error("decoding legacy node", "errror", err)
+			logic.ReturnErrorResponse(w, r, logic.FormatError(fmt.Errorf("decode legacy node %w", err), "badrequest"))
+			return
+		}
+		if err := bcrypt.CompareHashAndPassword([]byte(legacyNode.Password), []byte(legacy.Password)); err != nil {
+			slog.Error("legacy node invalid password", "error", err)
+			logic.ReturnErrorResponse(w, r, logic.FormatError(fmt.Errorf("invalid password %w", err), "unauthorized"))
+			return
+		}
+		if i == 0 {
+			host, node = convertLegacyHostNode(legacyNode)
+			host.Name = data.HostName
+			if err := logic.CreateHost(&host); err != nil {
+				slog.Error("create host", "error", err)
 				logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
-				continue
+				return
 			}
-			if err := bcrypt.CompareHashAndPassword([]byte(oldLegacyNode.Password), []byte(legacyNode.Password)); err != nil {
-				logger.Log(0, "error decoding legacy password", err.Error())
-				logic.ReturnErrorResponse(w, r, logic.FormatError(err, "unauthorized"))
-				continue
+			server = servercfg.GetServerInfo()
+			if servercfg.GetBrokerType() == servercfg.EmqxBrokerType {
+				server.MQUserName = host.ID.String()
 			}
-			networksToAdd = append(networksToAdd, oldLegacyNode.Network)
-			_ = database.DeleteRecord(database.NODES_TABLE_NAME, oldLegacyNode.ID)
+			key, keyErr := logic.RetrievePublicTrafficKey()
+			if keyErr != nil {
+				slog.Error("retrieving traffickey", "error", err)
+				logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
+				return
+			}
+			server.TrafficKey = key
+		} else {
+			node = convertLegacyNode(legacyNode, host.ID)
 		}
-	}
-	if len(networksToAdd) == 0 {
-		logger.Log(0, "no valid networks to migrate for host", data.NewHost.Name)
-		logic.ReturnErrorResponse(w, r, logic.FormatError(err, "unauthorized"))
-		return
-	}
-	if !logic.HostExists(&data.NewHost) {
-		logic.CheckHostPorts(&data.NewHost)
-		if err = logic.CreateHost(&data.NewHost); err != nil {
-			logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
-			return
+		if err := logic.UpsertNode(&node); err != nil {
+			slog.Error("update node", "error", err)
+			continue
 		}
+		slog.Info("")
+		nodes = append(nodes, node)
 	}
-	key, keyErr := logic.RetrievePublicTrafficKey()
-	if keyErr != nil {
-		logger.Log(0, "error retrieving key:", keyErr.Error())
-		logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
-		return
-	}
-	server := servercfg.GetServerInfo()
-	server.TrafficKey = key
-	response := models.RegisterResponse{
-		ServerConf:    server,
-		RequestedHost: data.NewHost,
+	response := models.HostPull{
+		Host:         host,
+		Nodes:        nodes,
+		ServerConfig: server,
 	}
 	w.WriteHeader(http.StatusOK)
 	json.NewEncoder(w).Encode(&response)
-	logger.Log(0, "successfully migrated host", data.NewHost.Name, data.NewHost.ID.String())
-	// notify host of changes, peer and node updates
-	auth.CheckNetRegAndHostUpdate(networksToAdd, &data.NewHost)
-	// check for gateways
-	for _, node := range data.LegacyNodes {
-		if node.IsEgressGateway == "yes" {
-			egressGateway := models.EgressGatewayRequest{
-				NodeID:     node.ID,
-				Ranges:     node.EgressGatewayRanges,
-				NatEnabled: node.EgressGatewayNatEnabled,
-			}
-			if _, err := logic.CreateEgressGateway(egressGateway); err != nil {
-				logger.Log(0, "error creating egress gateway for node", node.ID, err.Error())
-			}
-		}
-		if node.IsIngressGateway == "yes" {
-			ingressGateway := models.IngressRequest{}
-			ingressNode, err := logic.CreateIngressGateway(node.Network, node.ID, ingressGateway)
-			if err != nil {
-				logger.Log(0, "error creating ingress gateway for node", node.ID, err.Error())
-			}
-			runUpdates(&ingressNode, true)
-		}
-		if node.IsRelay == "yes" && servercfg.Is_EE {
-			_, relayNode, err := logic.CreateRelay(models.RelayRequest{
-				NodeID:       node.ID,
-				NetID:        node.Network,
-				RelayedNodes: node.RelayAddrs,
-			})
-			if err != nil {
-				logger.Log(0, "error creating relay for node", node.ID, err.Error())
-			}
-			runUpdates(&relayNode, true)
-		}
+
+	slog.Info("migrated nodes")
+}
+
+func convertLegacyHostNode(legacy models.LegacyNode) (models.Host, models.Node) {
+	//convert host
+	host := models.Host{}
+	host.ID = uuid.New()
+	host.IPForwarding = models.ParseBool(legacy.IPForwarding)
+	host.AutoUpdate = servercfg.AutoUpdateEnabled()
+	host.Interface = "netmaker"
+	host.ListenPort = int(legacy.ListenPort)
+	host.MTU = int(legacy.MTU)
+	host.PublicKey, _ = wgtypes.ParseKey(legacy.PublicKey)
+	host.MacAddress = net.HardwareAddr(legacy.MacAddress)
+	host.TrafficKeyPublic = legacy.TrafficKeys.Mine
+	updAddr, err := net.ResolveUDPAddr("udp", legacy.InternetGateway)
+	if err == nil {
+		host.InternetGateway = *updAddr
+	}
+	host.Nodes = append([]string{}, legacy.ID)
+	host.Interfaces = legacy.Interfaces
+	//host.DefaultInterface = legacy.Defaul
+	host.EndpointIP = net.ParseIP(legacy.Endpoint)
+	host.IsDocker = models.ParseBool(legacy.IsDocker)
+	host.IsK8S = models.ParseBool(legacy.IsK8S)
+	host.IsStatic = models.ParseBool(legacy.IsStatic)
+	node := convertLegacyNode(legacy, host.ID)
+	return host, node
+}
+
+func convertLegacyNode(legacy models.LegacyNode, hostID uuid.UUID) models.Node {
+	//convert node
+	node := models.Node{}
+	node.ID, _ = uuid.Parse(legacy.ID)
+	node.HostID = hostID
+	node.Network = legacy.Network
+	_, cidr4, err := net.ParseCIDR(legacy.NetworkSettings.AddressRange)
+	if err == nil {
+		node.Address = *cidr4
+	}
+	_, cidr6, err := net.ParseCIDR(legacy.NetworkSettings.AddressRange6)
+	if err == nil {
+		node.Address6 = *cidr6
+	}
+	node.Server = legacy.Server
+	node.Connected = models.ParseBool(legacy.Connected)
+	node.Address = net.IPNet{
+		IP:   net.ParseIP(legacy.Address),
+		Mask: cidr4.Mask,
+	}
+	node.Address6 = net.IPNet{
+		IP:   net.ParseIP(legacy.Address6),
+		Mask: cidr6.Mask,
+	}
+	node.Action = models.NODE_NOOP
+	node.LocalAddress = net.IPNet{
+		IP: net.ParseIP(legacy.LocalAddress),
 	}
+	node.IsEgressGateway = models.ParseBool(legacy.IsEgressGateway)
+	node.EgressGatewayRanges = legacy.EgressGatewayRanges
+	node.IsIngressGateway = models.ParseBool(legacy.IsIngressGateway)
+	node.IsRelayed = models.ParseBool(legacy.IsRelayed)
+	node.IsRelay = models.ParseBool(legacy.IsRelay)
+	node.RelayedNodes = legacy.RelayAddrs
+	node.DNSOn = models.ParseBool(legacy.DNSOn)
+	node.PersistentKeepalive = time.Duration(legacy.PersistentKeepalive)
+	node.LastModified = time.Now()
+	node.ExpirationDateTime, _ = time.Parse(strconv.Itoa(int(legacy.ExpirationDateTime)), "0")
+	node.EgressGatewayNatEnabled = models.ParseBool(legacy.EgressGatewayNatEnabled)
+	node.EgressGatewayRequest = legacy.EgressGatewayRequest
+	node.IngressGatewayRange = legacy.IngressGatewayRange
+	node.IngressGatewayRange6 = legacy.IngressGatewayRange6
+	node.DefaultACL = legacy.DefaultACL
+	node.OwnerID = legacy.OwnerID
+	node.FailoverNode, _ = uuid.Parse(legacy.FailoverNode)
+	node.Failover = models.ParseBool(legacy.Failover)
+	return node
 }

+ 1 - 1
main.go

@@ -29,7 +29,7 @@ import (
 	"golang.org/x/exp/slog"
 )
 
-var version = "v0.20.6-testing"
+var version = "v0.20.6"
 
 // Start DB Connection and start API Request Handler
 func main() {

+ 1 - 1
models/migrate.go

@@ -2,6 +2,6 @@ package models
 
 // MigrationData struct needed to create new v0.18.0 node from v.0.17.X node
 type MigrationData struct {
-	NewHost     Host
+	HostName    string
 	LegacyNodes []LegacyNode
 }

+ 1 - 5
models/node.go

@@ -100,7 +100,6 @@ type Node struct {
 // LegacyNode - legacy struct for node model
 type LegacyNode struct {
 	ID                      string               `json:"id,omitempty" bson:"id,omitempty" yaml:"id,omitempty" validate:"required,min=5,id_unique"`
-	HostID                  string               `json:"hostid,omitempty" bson:"id,omitempty" yaml:"hostid,omitempty" validate:"required,min=5,id_unique"`
 	Address                 string               `json:"address" bson:"address" yaml:"address" validate:"omitempty,ipv4"`
 	Address6                string               `json:"address6" bson:"address6" yaml:"address6" validate:"omitempty,ipv6"`
 	LocalAddress            string               `json:"localaddress" bson:"localaddress" yaml:"localaddress" validate:"omitempty"`
@@ -109,7 +108,6 @@ type LegacyNode struct {
 	NetworkSettings         Network              `json:"networksettings" bson:"networksettings" yaml:"networksettings" validate:"-"`
 	ListenPort              int32                `json:"listenport" bson:"listenport" yaml:"listenport" validate:"omitempty,numeric,min=1024,max=65535"`
 	LocalListenPort         int32                `json:"locallistenport" bson:"locallistenport" yaml:"locallistenport" validate:"numeric,min=0,max=65535"`
-	ProxyListenPort         int32                `json:"proxy_listen_port" bson:"proxy_listen_port" yaml:"proxy_listen_port" validate:"numeric,min=0,max=65535"`
 	PublicKey               string               `json:"publickey" bson:"publickey" yaml:"publickey" validate:"required,base64"`
 	Endpoint                string               `json:"endpoint" bson:"endpoint" yaml:"endpoint" validate:"required,ip"`
 	AllowedIPs              []string             `json:"allowedips" bson:"allowedips" yaml:"allowedips"`
@@ -153,8 +151,6 @@ type LegacyNode struct {
 	FirewallInUse   string      `json:"firewallinuse" bson:"firewallinuse" yaml:"firewallinuse"`
 	InternetGateway string      `json:"internetgateway" bson:"internetgateway" yaml:"internetgateway"`
 	Connected       string      `json:"connected" bson:"connected" yaml:"connected" validate:"checkyesorno"`
-	PendingDelete   bool        `json:"pendingdelete" bson:"pendingdelete" yaml:"pendingdelete"`
-	Proxy           bool        `json:"proxy" bson:"proxy" yaml:"proxy"`
 	// == PRO ==
 	DefaultACL string `json:"defaultacl,omitempty" bson:"defaultacl,omitempty" yaml:"defaultacl,omitempty" validate:"checkyesornoorunset"`
 	OwnerID    string `json:"ownerid,omitempty" bson:"ownerid,omitempty" yaml:"ownerid,omitempty"`
@@ -529,7 +525,7 @@ func (ln *LegacyNode) ConvertToNewNode() (*Host, *Node) {
 func (n *Node) Legacy(h *Host, s *ServerConfig, net *Network) *LegacyNode {
 	l := LegacyNode{}
 	l.ID = n.ID.String()
-	l.HostID = h.ID.String()
+	//l.HostID = h.ID.String()
 	l.Address = n.Address.String()
 	l.Address6 = n.Address6.String()
 	l.Interfaces = h.Interfaces