Parcourir la source

auto create egress on join

abhishek9686 il y a 5 mois
Parent
commit
6e10c1f407
3 fichiers modifiés avec 68 ajouts et 3 suppressions
  1. 28 2
      auth/host_session.go
  2. 2 1
      controllers/enrollmentkeys.go
  3. 38 0
      logic/acls.go

+ 28 - 2
auth/host_session.go

@@ -222,7 +222,7 @@ func SessionHandler(conn *websocket.Conn) {
 		if err = conn.WriteMessage(messageType, reponseData); err != nil {
 			logger.Log(0, "error during message writing:", err.Error())
 		}
-		go CheckNetRegAndHostUpdate(netsToAdd[:], &result.Host, uuid.Nil, []models.TagID{})
+		go CheckNetRegAndHostUpdate(netsToAdd[:], &result.Host, uuid.Nil, []models.TagID{}, false)
 	case <-timeout: // the read from req.answerCh has timed out
 		logger.Log(0, "timeout signal recv,exiting oauth socket conn")
 		break
@@ -236,7 +236,7 @@ func SessionHandler(conn *websocket.Conn) {
 }
 
 // CheckNetRegAndHostUpdate - run through networks and send a host update
-func CheckNetRegAndHostUpdate(networks []string, h *models.Host, relayNodeId uuid.UUID, tags []models.TagID) {
+func CheckNetRegAndHostUpdate(networks []string, h *models.Host, relayNodeId uuid.UUID, tags []models.TagID, autoEgress bool) {
 	// publish host update through MQ
 	for i := range networks {
 		network := networks[i]
@@ -274,6 +274,32 @@ func CheckNetRegAndHostUpdate(networks []string, h *models.Host, relayNodeId uui
 					slog.Error("failed to relay node. maybe specified relay node is actually not a relay? Or the relayed node is not in the same network with relay?", "err", err)
 				}
 			}
+			if autoEgress {
+				currRangesWithMetric := logic.GetEgressRangesWithMetric(models.NetworkID(newNode.Network))
+				ranges := []string{}
+				rangesWithMetric := []models.EgressRangeMetric{}
+				for _, iface := range h.Interfaces {
+					addr, err := logic.NormalizeCIDR(iface.Address.String())
+					if err == nil {
+						ranges = append(ranges, addr)
+					}
+					rangeWithMetric := models.EgressRangeMetric{
+						Network: addr,
+					}
+					if currRangeMetric, ok := currRangesWithMetric[addr]; ok {
+						lastMetricValue := currRangeMetric[len(currRangeMetric)-1]
+						rangeWithMetric.RouteMetric = lastMetricValue.RouteMetric + 10
+					}
+					rangesWithMetric = append(rangesWithMetric, rangeWithMetric)
+				}
+				logic.CreateEgressGateway(models.EgressGatewayRequest{
+					NodeID:           newNode.ID.String(),
+					NetID:            newNode.Network,
+					NatEnabled:       "yes",
+					Ranges:           ranges,
+					RangesWithMetric: rangesWithMetric,
+				})
+			}
 			logger.Log(1, "added new node", newNode.ID.String(), "to host", h.Name)
 			hostactions.AddAction(models.HostUpdate{
 				Action: models.JoinHostToNetwork,

+ 2 - 1
controllers/enrollmentkeys.go

@@ -359,5 +359,6 @@ func handleHostRegister(w http.ResponseWriter, r *http.Request) {
 	w.WriteHeader(http.StatusOK)
 	json.NewEncoder(w).Encode(&response)
 	// notify host of changes, peer and node updates
-	go auth.CheckNetRegAndHostUpdate(enrollmentKey.Networks, &newHost, enrollmentKey.Relay, enrollmentKey.Groups)
+	go auth.CheckNetRegAndHostUpdate(enrollmentKey.Networks, &newHost,
+		enrollmentKey.Relay, enrollmentKey.Groups, enrollmentKey.AutoEgress)
 }

+ 38 - 0
logic/acls.go

@@ -255,6 +255,44 @@ func GetEgressRanges(netID models.NetworkID) (map[string][]string, map[string]st
 	}
 	return nodeEgressMap, resultMap, nil
 }
+func sortRouteMetricByAscending(items []models.EgressRangeMetric) []models.EgressRangeMetric {
+	sort.Slice(items, func(i, j int) bool {
+		return items[i].RouteMetric < items[j].RouteMetric
+	})
+	return items
+}
+
+func GetEgressRangesWithMetric(netID models.NetworkID) map[string][]models.EgressRangeMetric {
+
+	egressMap := make(map[string][]models.EgressRangeMetric)
+	networkNodes, err := GetNetworkNodes(netID.String())
+	if err != nil {
+		return nil
+	}
+	for _, currentNode := range networkNodes {
+		if currentNode.Network != netID.String() {
+			continue
+		}
+		if currentNode.IsEgressGateway { // add the egress gateway range(s) to the result
+			if len(currentNode.EgressGatewayRequest.RangesWithMetric) > 0 {
+				for _, egressRangeI := range currentNode.EgressGatewayRequest.RangesWithMetric {
+					if value, ok := egressMap[egressRangeI.Network]; ok {
+						value = append(value, egressRangeI)
+						egressMap[egressRangeI.Network] = value
+					} else {
+						egressMap[egressRangeI.Network] = []models.EgressRangeMetric{
+							egressRangeI,
+						}
+					}
+				}
+			}
+		}
+	}
+	for key, value := range egressMap {
+		egressMap[key] = sortRouteMetricByAscending(value)
+	}
+	return egressMap
+}
 
 func checkIfAclTagisValid(t models.AclPolicyTag, netID models.NetworkID, policyType models.AclPolicyType, isSrc bool) bool {
 	switch t.ID {