Переглянути джерело

join via api - netmaker changes

Signed-off-by: Matthew R. Kasun <[email protected]>
Matthew R. Kasun 3 роки тому
батько
коміт
6aaf449981

+ 1 - 1
controllers/dns_test.go

@@ -54,7 +54,7 @@ func TestGetNodeDNS(t *testing.T) {
 	})
 	t.Run("MultipleNodes", func(t *testing.T) {
 		createnode := &models.Node{PublicKey: "DM5qhLAE20PG9BbfBCger+Ac9D2NDOwCtY1rbYDLf34=", Endpoint: "10.100.100.3", MacAddress: "01:02:03:04:05:07", Password: "password", Network: "skynet"}
-		err := logic.CreateNode(createnode)
+		_, err := logic.CreateNode(createnode)
 		assert.Nil(t, err)
 		dns, err := logic.GetNodeDNS("skynet")
 		assert.Nil(t, err)

+ 43 - 3
controllers/node.go

@@ -15,7 +15,9 @@ import (
 	"github.com/gravitl/netmaker/models"
 	"github.com/gravitl/netmaker/mq"
 	"github.com/gravitl/netmaker/netclient/config"
+	"github.com/gravitl/netmaker/netclient/server"
 	"github.com/gravitl/netmaker/servercfg"
+	"github.com/gravitl/netmaker/tls"
 	"github.com/kr/pretty"
 	"golang.org/x/crypto/bcrypt"
 )
@@ -365,13 +367,34 @@ func createNode(w http.ResponseWriter, r *http.Request) {
 	}
 	//get node from body of request
 	var request = config.JoinRequest{}
-	node := request.Node
 	err := json.NewDecoder(r.Body).Decode(&request)
 	if err != nil {
 		log.Println("json decoder error")
 		returnErrorResponse(w, r, formatError(err, "badrequest"))
 		return
 	}
+
+	//Generate certificate for client
+	key, err := tls.ReadKey("/etc/netmaker/root.key")
+	if err != nil {
+		log.Println("error reading root private key ", err)
+		returnErrorResponse(w, r, formatError(err, "internal"))
+		return
+	}
+	ca, err := tls.ReadCert("/etc/netmaker/root.pem")
+	if err != nil {
+		log.Println("error reading root certificate ", err)
+		returnErrorResponse(w, r, formatError(err, "internal"))
+		return
+	}
+	cert, err := tls.NewEndEntityCert(*key, &request.CSR, ca, 30)
+	if err != nil {
+		log.Println("error creating client certificate ", err)
+		returnErrorResponse(w, r, formatError(err, "internal"))
+		return
+	}
+
+	node := request.Node
 	pretty.Println(node)
 	log.Println("check if network exists ", request.Node.Network)
 	networkexists, err := functions.NetworkExists(request.Node.Network)
@@ -412,16 +435,33 @@ func createNode(w http.ResponseWriter, r *http.Request) {
 		}
 	}
 
-	err = logic.CreateNode(&request.Node)
+	newNode, err := logic.CreateNode(&request.Node)
 	if err != nil {
 		log.Println("error creating node")
 		returnErrorResponse(w, r, formatError(err, "internal"))
 		return
 	}
+	// get peers
+	isIngress := false
+	if newNode.IsIngressGateway == "yes" {
+		isIngress = true
+	}
+	isDualStack := false
+	if newNode.IsDualStack == "yes" {
+		isDualStack = true
+	}
+
+	peers, _, _, err := server.GetPeers(newNode.MacAddress, newNode.Network, "", isDualStack, isIngress, false)
 
+	response := config.JoinResponse{
+		Node:        *newNode,
+		Peers:       peers,
+		Certificate: *cert,
+		CA:          *ca,
+	}
 	logger.Log(1, r.Header.Get("user"), "created new node", request.Node.Name, "on network", node.Network)
 	w.WriteHeader(http.StatusOK)
-	json.NewEncoder(w).Encode(node)
+	json.NewEncoder(w).Encode(response)
 	runForceServerUpdate(&request.Node)
 }
 

+ 1 - 1
controllers/node_grpc.go

@@ -98,7 +98,7 @@ func (s *NodeServiceServer) CreateNode(ctx context.Context, req *nodepb.Object)
 	}
 	node.CommID = commID
 
-	err = logic.CreateNode(&node)
+	_, err = logic.CreateNode(&node)
 	if err != nil {
 		return nil, err
 	}

+ 1 - 1
controllers/node_test.go

@@ -26,7 +26,7 @@ func TestCreateEgressGateway(t *testing.T) {
 	})
 	t.Run("Non-linux node", func(t *testing.T) {
 		createnode := models.Node{PublicKey: "DM5qhLAE20PG9BbfBCger+Ac9D2NDOwCtY1rbYDLf34=", Name: "testnode", Endpoint: "10.0.0.1", MacAddress: "01:02:03:04:05:06", Password: "password", Network: "skynet", OS: "freebsd"}
-		err := logic.CreateNode(&createnode)
+		_, err := logic.CreateNode(&createnode)
 		assert.Nil(t, err)
 		gateway.NodeID = createnode.ID
 		node, err := logic.CreateEgressGateway(gateway)

+ 14 - 13
logic/nodes.go

@@ -250,12 +250,12 @@ func ValidateNode(node *models.Node, isUpdate bool) error {
 }
 
 // CreateNode - creates a node in database
-func CreateNode(node *models.Node) error {
+func CreateNode(node *models.Node) (*models.Node, error) {
 
 	//encrypt that password so we never see it
 	hash, err := bcrypt.GenerateFromPassword([]byte(node.Password), 5)
 	if err != nil {
-		return err
+		return nil, err
 	}
 	//set password to encrypted password
 	node.Password = string(hash)
@@ -274,22 +274,22 @@ func CreateNode(node *models.Node) error {
 
 	if node.IsServer == "yes" {
 		if node.Address, err = UniqueAddressServer(node.Network); err != nil {
-			return err
+			return nil, err
 		}
 	} else if node.Address == "" {
 		if node.Address, err = UniqueAddress(node.Network); err != nil {
-			return err
+			return nil, err
 		}
 	} else if !IsIPUnique(node.Network, node.Address, database.NODES_TABLE_NAME, false) {
-		return fmt.Errorf("invalid address: ipv4 " + node.Address + " is not unique")
+		return nil, fmt.Errorf("invalid address: ipv4 " + node.Address + " is not unique")
 	}
 
 	if node.Address6 == "" {
 		if node.Address6, err = UniqueAddress6(node.Network); err != nil {
-			return err
+			return nil, err
 		}
 	} else if !IsIPUnique(node.Network, node.Address6, database.NODES_TABLE_NAME, true) {
-		return fmt.Errorf("invalid address: ipv6 " + node.Address6 + " is not unique")
+		return nil, fmt.Errorf("invalid address: ipv6 " + node.Address6 + " is not unique")
 	}
 
 	node.ID = uuid.NewString()
@@ -298,22 +298,22 @@ func CreateNode(node *models.Node) error {
 	tokenString, _ := CreateJWT(node.ID, node.MacAddress, node.Network)
 	if tokenString == "" {
 		//returnErrorResponse(w, r, errorResponse)
-		return err
+		return nil, err
 	}
 	log.Println("validating node")
 	pretty.Println(node)
 	err = ValidateNode(node, false)
 	if err != nil {
-		return err
+		return nil, err
 	}
 
 	nodebytes, err := json.Marshal(&node)
 	if err != nil {
-		return err
+		return nil, err
 	}
 	err = database.Insert(node.ID, string(nodebytes), database.NODES_TABLE_NAME)
 	if err != nil {
-		return err
+		return nil, err
 	}
 
 	defaultACLVal := acls.Allowed
@@ -327,7 +327,7 @@ func CreateNode(node *models.Node) error {
 	_, err = nodeacls.CreateNodeACL(nodeacls.NetworkID(node.Network), nodeacls.NodeID(node.ID), defaultACLVal)
 	if err != nil {
 		logger.Log(1, "failed to create node ACL for node,", node.ID, "err:", err.Error())
-		return err
+		return nil, err
 	}
 
 	if node.IsPending != "yes" {
@@ -336,8 +336,9 @@ func CreateNode(node *models.Node) error {
 	SetNetworkNodesLastModified(node.Network)
 	if servercfg.IsDNSMode() {
 		err = SetDNS()
+		return nil, err
 	}
-	return err
+	return node, nil
 }
 
 // GetAllNodes - returns all nodes in the DB

+ 1 - 1
logic/server.go

@@ -143,7 +143,7 @@ func ServerJoin(networkSettings *models.Network) (models.Node, error) {
 		node.Endpoint = node.LocalAddress
 	}
 
-	if err = CreateNode(node); err != nil {
+	if _, err = CreateNode(node); err != nil {
 		return returnNode, err
 	}
 	if err = StorePrivKey(node.ID, privateKey); err != nil {

+ 2 - 2
netclient/cli_options/flags.go

@@ -171,8 +171,8 @@ func GetFlags(hostname string) []cli.Flag {
 		&cli.StringFlag{
 			Name:    "ipforwarding",
 			EnvVars: []string{"NETCLIENT_IPFORWARDING"},
-			Value:   "on",
-			Usage:   "Sets ip forwarding on if 'on'. Ignores if 'off'. On by default.",
+			Value:   "yes",
+			Usage:   "Sets ip forwarding on if 'yes'. Ignores if 'no'. On by default.",
 		},
 		&cli.StringFlag{
 			Name:    "postup",

+ 2 - 1
netclient/config/config.go

@@ -43,10 +43,11 @@ type ServerConfig struct {
 type JoinRequest struct {
 	Node models.Node
 	Key  ed25519.PublicKey
+	CSR  x509.CertificateRequest
 }
 
 type JoinResponse struct {
-	Config      ClientConfig
+	Node        models.Node
 	Peers       []wgtypes.PeerConfig
 	Certificate x509.Certificate
 	CA          x509.Certificate

+ 10 - 2
netclient/functions/join.go

@@ -102,10 +102,15 @@ func JoinNetwork(cfg *config.ClientConfig, privateKey string) error {
 	if err != nil {
 		return err
 	}
-
+	name := tls.NewCName(cfg.Node.Name)
+	csr, err := tls.NewCSR(key, name)
+	if err != nil {
+		return err
+	}
 	request := config.JoinRequest{
 		Node: cfg.Node,
 		Key:  key.Public().(ed25519.PublicKey),
+		CSR:  *csr,
 	}
 
 	log.Println("calling api ", cfg.Server.API+"/api/nodes/join")
@@ -113,8 +118,11 @@ func JoinNetwork(cfg *config.ClientConfig, privateKey string) error {
 	if err != nil {
 		return fmt.Errorf("error joining network %w", err)
 	}
-	node := response.Config.Node
+	node := response.Node
 	peers := response.Peers
+	pretty.Println(response)
+	pretty.Println(node)
+	pretty.Println(peers)
 
 	// safety check. If returned no:de from server is local, but not currently configured as local, set to local addr
 	if cfg.Node.IsLocal != "yes" && node.IsLocal == "yes" && node.LocalRange != "" {