Browse Source

added comments

Abhishek Kondur 2 years ago
parent
commit
677d9fcc8d
6 changed files with 161 additions and 136 deletions
  1. 16 18
      controllers/network.go
  2. 75 78
      controllers/node.go
  3. 43 27
      mq/dynsec.go
  4. 24 12
      mq/dynsec_helper.go
  5. 2 1
      mq/mq.go
  6. 1 0
      servercfg/serverconf.go

+ 16 - 18
controllers/network.go

@@ -443,19 +443,18 @@ func deleteNetwork(w http.ResponseWriter, r *http.Request) {
 		return
 	}
 	// Deletes the network role from MQ
-	event := mq.DynSecAction{
-		Payload: mq.MqDynsecPayload{
-			Commands: []mq.MqDynSecCmd{
-				{
-					Command:  mq.DeleteRoleCmd,
-					RoleName: network,
-				},
+	event := mq.MqDynsecPayload{
+		Commands: []mq.MqDynSecCmd{
+			{
+				Command:  mq.DeleteRoleCmd,
+				RoleName: network,
 			},
 		},
 	}
+
 	if err := mq.PublishEventToDynSecTopic(event); err != nil {
 		logger.Log(0, fmt.Sprintf("failed to send DynSec command [%v]: %v",
-			event.Payload.Commands, err.Error()))
+			event.Commands, err.Error()))
 	}
 	logger.Log(1, r.Header.Get("user"), "deleted network", network)
 	w.WriteHeader(http.StatusOK)
@@ -504,21 +503,20 @@ func createNetwork(w http.ResponseWriter, r *http.Request) {
 		return
 	}
 	// Create Role with acls for the network
-	event := mq.DynSecAction{
-		Payload: mq.MqDynsecPayload{
-			Commands: []mq.MqDynSecCmd{
-				{
-					Command:  mq.CreateRoleCmd,
-					RoleName: network.NetID,
-					Textname: "Network wide role with Acls for nodes",
-					Acls:     mq.FetchNetworkAcls(network.NetID),
-				},
+	event := mq.MqDynsecPayload{
+		Commands: []mq.MqDynSecCmd{
+			{
+				Command:  mq.CreateRoleCmd,
+				RoleName: network.NetID,
+				Textname: "Network wide role with Acls for nodes",
+				Acls:     mq.FetchNetworkAcls(network.NetID),
 			},
 		},
 	}
+
 	if err := mq.PublishEventToDynSecTopic(event); err != nil {
 		logger.Log(0, fmt.Sprintf("failed to send DynSec command [%v]: %v",
-			event.Payload.Commands, err.Error()))
+			event.Commands, err.Error()))
 	}
 
 	if servercfg.IsClientMode() != "off" {

+ 75 - 78
controllers/node.go

@@ -100,46 +100,46 @@ func authenticate(response http.ResponseWriter, request *http.Request) {
 		logic.ReturnErrorResponse(response, request, errorResponse)
 		return
 	}
-	event := mq.DynSecAction{
-		Payload: mq.MqDynsecPayload{
-			Commands: []mq.MqDynSecCmd{
-
-				{
-					Command:  mq.CreateRoleCmd,
-					RoleName: result.Network,
-					Textname: "Network wide role with Acls for nodes",
-					Acls:     mq.FetchNetworkAcls(result.Network),
-				},
+	// creates network role, node role,node client (added here to resolve any missing configuration in MQ)
+	event := mq.MqDynsecPayload{
+		Commands: []mq.MqDynSecCmd{
+
+			{
+				Command:  mq.CreateRoleCmd,
+				RoleName: result.Network,
+				Textname: "Network wide role with Acls for nodes",
+				Acls:     mq.FetchNetworkAcls(result.Network),
+			},
 
-				{
-					Command:  mq.CreateRoleCmd,
-					RoleName: fmt.Sprintf("%s-%s", "Node", result.ID),
-					Acls:     mq.FetchNodeAcls(result.ID),
-					Textname: "Role for node " + result.Name,
-				},
-				{
-					Command:  mq.CreateClientCmd,
-					Username: result.ID,
-					Password: authRequest.Password,
-					Textname: result.Name,
-					Roles: []mq.MqDynSecRole{
-						{
-							Rolename: fmt.Sprintf("%s-%s", "Node", result.ID),
-							Priority: -1,
-						},
-						{
-							Rolename: result.Network,
-							Priority: -1,
-						},
+			{
+				Command:  mq.CreateRoleCmd,
+				RoleName: fmt.Sprintf("%s-%s", "Node", result.ID),
+				Acls:     mq.FetchNodeAcls(result.ID),
+				Textname: "Role for node " + result.Name,
+			},
+			{
+				Command:  mq.CreateClientCmd,
+				Username: result.ID,
+				Password: authRequest.Password,
+				Textname: result.Name,
+				Roles: []mq.MqDynSecRole{
+					{
+						Rolename: fmt.Sprintf("%s-%s", "Node", result.ID),
+						Priority: -1,
+					},
+					{
+						Rolename: result.Network,
+						Priority: -1,
 					},
-					Groups: make([]mq.MqDynSecGroup, 0),
 				},
+				Groups: make([]mq.MqDynSecGroup, 0),
 			},
 		},
 	}
+
 	if err := mq.PublishEventToDynSecTopic(event); err != nil {
 		logger.Log(0, fmt.Sprintf("failed to send DynSec command [%v]: %v",
-			event.Payload.Commands, err.Error()))
+			event.Commands, err.Error()))
 		errorResponse.Code = http.StatusInternalServerError
 		errorResponse.Message = fmt.Sprintf("could not create mq client for node [%s]: %v", result.ID, err)
 		return
@@ -662,53 +662,51 @@ func createNode(w http.ResponseWriter, r *http.Request) {
 		return
 	}
 	// Delete Any Existing Client with this ID.
-	event := mq.DynSecAction{
-		Payload: mq.MqDynsecPayload{
-			Commands: []mq.MqDynSecCmd{
-				{
-					Command:  mq.DeleteClientCmd,
-					Username: node.ID,
-				},
+	event := mq.MqDynsecPayload{
+		Commands: []mq.MqDynSecCmd{
+			{
+				Command:  mq.DeleteClientCmd,
+				Username: node.ID,
 			},
 		},
 	}
+
 	if err := mq.PublishEventToDynSecTopic(event); err != nil {
 		logger.Log(0, fmt.Sprintf("failed to send DynSec command [%v]: %v",
-			event.Payload.Commands, err.Error()))
+			event.Commands, err.Error()))
 	}
 	// Create client for this node in Mq
-	event = mq.DynSecAction{
-		Payload: mq.MqDynsecPayload{
-			Commands: []mq.MqDynSecCmd{
-				{
-					Command:  mq.CreateRoleCmd,
-					RoleName: fmt.Sprintf("%s-%s", "Node", node.ID),
-					Acls:     mq.FetchNodeAcls(node.ID),
-					Textname: "Role for node " + node.Name,
-				},
-				{
-					Command:  mq.CreateClientCmd,
-					Username: node.ID,
-					Password: nodePassword,
-					Textname: node.Name,
-					Roles: []mq.MqDynSecRole{
-						{
-							Rolename: fmt.Sprintf("%s-%s", "Node", node.ID),
-							Priority: -1,
-						},
-						{
-							Rolename: node.Network,
-							Priority: -1,
-						},
+	event = mq.MqDynsecPayload{
+		Commands: []mq.MqDynSecCmd{
+			{
+				Command:  mq.CreateRoleCmd,
+				RoleName: fmt.Sprintf("%s-%s", "Node", node.ID),
+				Acls:     mq.FetchNodeAcls(node.ID),
+				Textname: "Role for node " + node.Name,
+			},
+			{
+				Command:  mq.CreateClientCmd,
+				Username: node.ID,
+				Password: nodePassword,
+				Textname: node.Name,
+				Roles: []mq.MqDynSecRole{
+					{
+						Rolename: fmt.Sprintf("%s-%s", "Node", node.ID),
+						Priority: -1,
+					},
+					{
+						Rolename: node.Network,
+						Priority: -1,
 					},
-					Groups: make([]mq.MqDynSecGroup, 0),
 				},
+				Groups: make([]mq.MqDynSecGroup, 0),
 			},
 		},
 	}
+
 	if err := mq.PublishEventToDynSecTopic(event); err != nil {
 		logger.Log(0, fmt.Sprintf("failed to send DynSec command [%v]: %v",
-			event.Payload.Commands, err.Error()))
+			event.Commands, err.Error()))
 	}
 
 	response := models.NodeGet{
@@ -1046,24 +1044,23 @@ func deleteNode(w http.ResponseWriter, r *http.Request) {
 		logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
 		return
 	}
-
-	event := mq.DynSecAction{
-		Payload: mq.MqDynsecPayload{
-			Commands: []mq.MqDynSecCmd{
-				{
-					Command:  mq.DeleteRoleCmd,
-					RoleName: fmt.Sprintf("%s-%s", "Node", nodeid),
-				},
-				{
-					Command:  mq.DeleteClientCmd,
-					Username: nodeid,
-				},
+	// deletes node related role and client
+	event := mq.MqDynsecPayload{
+		Commands: []mq.MqDynSecCmd{
+			{
+				Command:  mq.DeleteRoleCmd,
+				RoleName: fmt.Sprintf("%s-%s", "Node", nodeid),
+			},
+			{
+				Command:  mq.DeleteClientCmd,
+				Username: nodeid,
 			},
 		},
 	}
+
 	if err := mq.PublishEventToDynSecTopic(event); err != nil {
 		logger.Log(0, fmt.Sprintf("failed to send DynSec command [%v]: %v",
-			event.Payload.Commands, err.Error()))
+			event.Commands, err.Error()))
 	}
 	logic.ReturnSuccessResponse(w, r, nodeid+" deleted.")
 	logger.Log(1, r.Header.Get("user"), "Deleted node", nodeid, "from network", params["network"])

+ 43 - 27
mq/dynsec.go

@@ -18,38 +18,53 @@ import (
 	"golang.org/x/crypto/pbkdf2"
 )
 
-const DynamicSecSubTopic = "$CONTROL/dynamic-security/#"
-const DynamicSecPubTopic = "$CONTROL/dynamic-security/v1"
+// DynamicSecSubTopic - constant for dynamic security subscription topic
+const dynamicSecSubTopic = "$CONTROL/dynamic-security/#"
 
+// DynamicSecPubTopic - constant for dynamic security subscription topic
+const dynamicSecPubTopic = "$CONTROL/dynamic-security/v1"
+
+// mq client for admin
 var mqAdminClient mqtt.Client
 
-var (
-	CreateClientCmd  = "createClient"
+const (
+	// constant for client command
+	CreateClientCmd = "createClient"
+	// constant for disable command
 	DisableClientCmd = "disableClient"
-	DeleteClientCmd  = "deleteClient"
-	ModifyClientCmd  = "modifyClient"
-)
+	// constant for delete client command
+	DeleteClientCmd = "deleteClient"
+	// constant for modify client command
+	ModifyClientCmd = "modifyClient"
 
-var (
+	// constant for create role command
 	CreateRoleCmd = "createRole"
+	// constant for delete role command
 	DeleteRoleCmd = "deleteRole"
 )
 
+const (
+	// constant for admin user name
+	mqAdminUserName = "Netmaker-Admin"
+	// constant for server user name
+	mqNetmakerServerUserName = "Netmaker-Server"
+	// constant for exporter user name
+	mqExporterUserName = "Netmaker-Exporter"
+)
+
+// struct for dynamic security file
 type dynJSON struct {
 	Clients    []client         `json:"clients"`
 	Roles      []role           `json:"roles"`
 	DefaultAcl defaultAccessAcl `json:"defaultACLAccess"`
 }
 
-var (
-	mqAdminUserName          string = "Netmaker-Admin"
-	mqNetmakerServerUserName string = "Netmaker-Server"
-	mqExporterUserName       string = "Netmaker-Exporter"
-)
-
+// struct for client role
 type clientRole struct {
 	Rolename string `json:"rolename"`
 }
+
+// struct for MQ client
 type client struct {
 	Username   string       `json:"username"`
 	TextName   string       `json:"textName"`
@@ -59,11 +74,13 @@ type client struct {
 	Roles      []clientRole `json:"roles"`
 }
 
+// struct for MQ role
 type role struct {
 	Rolename string `json:"rolename"`
 	Acls     []Acl  `json:"acls"`
 }
 
+// struct for default acls
 type defaultAccessAcl struct {
 	PublishClientSend    bool `json:"publishClientSend"`
 	PublishClientReceive bool `json:"publishClientReceive"`
@@ -71,22 +88,19 @@ type defaultAccessAcl struct {
 	Unsubscribe          bool `json:"unsubscribe"`
 }
 
-type dynCnf struct {
-	Clients          []client         `json:"clients"`
-	Roles            []role           `json:"roles"`
-	DefaultACLAccess defaultAccessAcl `json:"defaultACLAccess"`
-}
-
+// MqDynSecGroup - struct for MQ client group
 type MqDynSecGroup struct {
 	Groupname string `json:"groupname"`
 	Priority  int    `json:"priority"`
 }
 
+// MqDynSecRole - struct for MQ client role
 type MqDynSecRole struct {
 	Rolename string `json:"rolename"`
 	Priority int    `json:"priority"`
 }
 
+// Acl - struct for MQ acls
 type Acl struct {
 	AclType  string `json:"acltype"`
 	Topic    string `json:"topic"`
@@ -94,6 +108,7 @@ type Acl struct {
 	Allow    bool   `json:"allow"`
 }
 
+// MqDynSecCmd - struct for MQ dynamic security command
 type MqDynSecCmd struct {
 	Command         string          `json:"command"`
 	Username        string          `json:"username"`
@@ -107,19 +122,18 @@ type MqDynSecCmd struct {
 	Roles           []MqDynSecRole  `json:"roles"`
 }
 
-type DynSecAction struct {
-	Payload MqDynsecPayload
-}
-
+// MqDynsecPayload - struct for dynamic security command payload
 type MqDynsecPayload struct {
 	Commands []MqDynSecCmd `json:"commands"`
 }
 
+// encodePasswordToPBKDF2 - encodes the given password with PBKDF2 hashing for MQ
 func encodePasswordToPBKDF2(password string, salt string, iterations int, keyLength int) string {
 	binaryEncoded := pbkdf2.Key([]byte(password), []byte(salt), iterations, keyLength, sha512.New)
 	return base64.StdEncoding.EncodeToString(binaryEncoded)
 }
 
+// Configure - configures the dynamic initial configuration for MQ
 func Configure() error {
 	if servercfg.Is_EE {
 		dynConfig.Clients = append(dynConfig.Clients, exporterMQClient)
@@ -155,14 +169,15 @@ func Configure() error {
 	return os.WriteFile(path, data, 0755)
 }
 
-func PublishEventToDynSecTopic(event DynSecAction) error {
+// PublishEventToDynSecTopic - publishes the message to dynamic security topic
+func PublishEventToDynSecTopic(payload MqDynsecPayload) error {
 
-	d, err := json.Marshal(event.Payload)
+	d, err := json.Marshal(payload)
 	if err != nil {
 		return err
 	}
 	var connecterr error
-	if token := mqAdminClient.Publish(DynamicSecPubTopic, 2, false, d); !token.WaitTimeout(MQ_TIMEOUT*time.Second) || token.Error() != nil {
+	if token := mqAdminClient.Publish(dynamicSecPubTopic, 2, false, d); !token.WaitTimeout(MQ_TIMEOUT*time.Second) || token.Error() != nil {
 		if token.Error() == nil {
 			connecterr = errors.New("connect timeout")
 		} else {
@@ -172,6 +187,7 @@ func PublishEventToDynSecTopic(event DynSecAction) error {
 	return connecterr
 }
 
+// watchDynSecTopic - message handler for dynamic security responses
 func watchDynSecTopic(client mqtt.Client, msg mqtt.Message) {
 
 	logger.Log(1, fmt.Sprintf("----->WatchDynSecTopic Message: %+v", string(msg.Payload())))

+ 24 - 12
mq/dynsec_helper.go

@@ -10,15 +10,21 @@ import (
 	"github.com/gravitl/netmaker/servercfg"
 )
 
-var (
-	AdminRole    string = "admin"
-	ServerRole   string = "server"
-	ExporterRole string = "exporter"
+const (
+	// constant for admin role
+	adminRole = "admin"
+	// constant for server role
+	serverRole = "server"
+	// constant for exporter role
+	exporterRole = "exporter"
+
+	// const for dynamic security file
+	dynamicSecurityFile = "dynamic-security.json"
 )
 
 var (
-	dynamicSecurityFile = "dynamic-security.json"
-	dynConfig           = dynJSON{
+	// default configuration of dynamic security
+	dynConfig = dynJSON{
 		Clients: []client{
 			{
 				Username:   mqAdminUserName,
@@ -28,7 +34,7 @@ var (
 				Iterations: 0,
 				Roles: []clientRole{
 					{
-						Rolename: AdminRole,
+						Rolename: adminRole,
 					},
 				},
 			},
@@ -40,14 +46,14 @@ var (
 				Iterations: 0,
 				Roles: []clientRole{
 					{
-						Rolename: ServerRole,
+						Rolename: serverRole,
 					},
 				},
 			},
 		},
 		Roles: []role{
 			{
-				Rolename: AdminRole,
+				Rolename: adminRole,
 				Acls: []Acl{
 					{
 						AclType:  "publishClientSend",
@@ -106,7 +112,7 @@ var (
 				},
 			},
 			{
-				Rolename: ServerRole,
+				Rolename: serverRole,
 				Acls: []Acl{
 					{
 						AclType:  "publishClientSend",
@@ -169,12 +175,12 @@ var (
 		Iterations: 101,
 		Roles: []clientRole{
 			{
-				Rolename: ExporterRole,
+				Rolename: exporterRole,
 			},
 		},
 	}
 	exporterMQRole = role{
-		Rolename: ExporterRole,
+		Rolename: exporterRole,
 		Acls: []Acl{
 			{
 				AclType:  "publishClientReceive",
@@ -186,6 +192,7 @@ var (
 	}
 )
 
+// DynListCLientsCmdResp - struct for list clients response from MQ
 type DynListCLientsCmdResp struct {
 	Responses []struct {
 		Command string          `json:"command"`
@@ -194,11 +201,13 @@ type DynListCLientsCmdResp struct {
 	} `json:"responses"`
 }
 
+// ListClientsData - struct for list clients data
 type ListClientsData struct {
 	Clients    []string `json:"clients"`
 	TotalCount int      `json:"totalCount"`
 }
 
+// GetAdminClient - fetches admin client of the MQ
 func GetAdminClient() (mqtt.Client, error) {
 	opts := mqtt.NewClientOptions()
 	setMqOptions(mqAdminUserName, servercfg.GetMqAdminPassword(), opts)
@@ -214,6 +223,7 @@ func GetAdminClient() (mqtt.Client, error) {
 	return mqclient, connecterr
 }
 
+// ListClients -  to list all clients in the MQ
 func ListClients(client mqtt.Client) (ListClientsData, error) {
 	respChan := make(chan mqtt.Message, 10)
 	defer close(respChan)
@@ -254,6 +264,7 @@ func ListClients(client mqtt.Client) (ListClientsData, error) {
 	return resp, errors.New("resp not found")
 }
 
+// FetchNetworkAcls - fetches network acls
 func FetchNetworkAcls(network string) []Acl {
 	return []Acl{
 		{
@@ -269,6 +280,7 @@ func FetchNetworkAcls(network string) []Acl {
 	}
 }
 
+// FetchNodeAcls -fetches node acls
 func FetchNodeAcls(nodeID string) []Acl {
 	return []Acl{
 

+ 2 - 1
mq/mq.go

@@ -22,12 +22,13 @@ var peer_force_send = 0
 
 var mqclient mqtt.Client
 
+// SetUpAdminClient - sets up admin client for the MQ
 func SetUpAdminClient() {
 	opts := mqtt.NewClientOptions()
 	setMqOptions(mqAdminUserName, servercfg.GetMqAdminPassword(), opts)
 	mqAdminClient = mqtt.NewClient(opts)
 	opts.SetOnConnectHandler(func(client mqtt.Client) {
-		if token := client.Subscribe(DynamicSecSubTopic, 0, mqtt.MessageHandler(watchDynSecTopic)); token.WaitTimeout(MQ_TIMEOUT*time.Second) && token.Error() != nil {
+		if token := client.Subscribe(dynamicSecSubTopic, 0, mqtt.MessageHandler(watchDynSecTopic)); token.WaitTimeout(MQ_TIMEOUT*time.Second) && token.Error() != nil {
 			client.Disconnect(240)
 			logger.Log(0, "Dynamic security client subscription failed")
 		}

+ 1 - 0
servercfg/serverconf.go

@@ -622,6 +622,7 @@ func GetMQServerPort() string {
 	return port
 }
 
+// GetMqAdminPassword - fetches the MQ Admin password
 func GetMqAdminPassword() string {
 	password := ""
 	if os.Getenv("MQ_ADMIN_PASSWORD") != "" {