mirror of
https://github.com/gravitl/netmaker.git
synced 2025-09-03 19:54:22 +08:00
NET-1933: option to force destroy network (#3311)
* option to force destroy network * fix network tests * fix network defaults func * fix network destroy action * delete network if node count is zero * push peer update network deletion * send node update
This commit is contained in:
parent
cec48be354
commit
4431dc99a7
7 changed files with 109 additions and 53 deletions
|
@ -594,7 +594,7 @@ func deleteHostFromNetwork(w http.ResponseWriter, r *http.Request) {
|
|||
w,
|
||||
r,
|
||||
logic.FormatError(
|
||||
fmt.Errorf("failed to force delete daemon node: "+err.Error()),
|
||||
fmt.Errorf("failed to force delete daemon node: %s", err.Error()),
|
||||
"internal",
|
||||
),
|
||||
)
|
||||
|
@ -634,7 +634,7 @@ func deleteHostFromNetwork(w http.ResponseWriter, r *http.Request) {
|
|||
w,
|
||||
r,
|
||||
logic.FormatError(
|
||||
fmt.Errorf("failed to force delete daemon node: "+err.Error()),
|
||||
fmt.Errorf("failed to force delete daemon node: %s", err.Error()),
|
||||
"internal",
|
||||
),
|
||||
)
|
||||
|
|
|
@ -434,6 +434,7 @@ func getNetworkACL(w http.ResponseWriter, r *http.Request) {
|
|||
// @Tags Networks
|
||||
// @Security oauth
|
||||
// @Param networkname path string true "Network name"
|
||||
// @Param force query bool false "Force Delete"
|
||||
// @Produce json
|
||||
// @Success 200 {object} models.SuccessResponse
|
||||
// @Failure 400 {object} models.ErrorResponse
|
||||
|
@ -441,10 +442,18 @@ func getNetworkACL(w http.ResponseWriter, r *http.Request) {
|
|||
func deleteNetwork(w http.ResponseWriter, r *http.Request) {
|
||||
// Set header
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
|
||||
force := r.URL.Query().Get("force") == "true"
|
||||
var params = mux.Vars(r)
|
||||
network := params["networkname"]
|
||||
err := logic.DeleteNetwork(network)
|
||||
doneCh := make(chan struct{}, 1)
|
||||
networkNodes, err := logic.GetNetworkNodes(network)
|
||||
if err != nil {
|
||||
logger.Log(0, r.Header.Get("user"),
|
||||
fmt.Sprintf("failed to get network nodes [%s]: %v", network, err))
|
||||
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
|
||||
return
|
||||
}
|
||||
err = logic.DeleteNetwork(network, force, doneCh)
|
||||
if err != nil {
|
||||
errtype := "badrequest"
|
||||
if strings.Contains(err.Error(), "Node check failed") {
|
||||
|
@ -459,7 +468,22 @@ func deleteNetwork(w http.ResponseWriter, r *http.Request) {
|
|||
go logic.DeleteDefaultNetworkPolicies(models.NetworkID(network))
|
||||
//delete network from allocated ip map
|
||||
go logic.RemoveNetworkFromAllocatedIpMap(network)
|
||||
|
||||
go func() {
|
||||
<-doneCh
|
||||
mq.PublishPeerUpdate(true)
|
||||
// send node update to clean up locally
|
||||
for _, node := range networkNodes {
|
||||
node := node
|
||||
node.PendingDelete = true
|
||||
node.Action = models.NODE_DELETE
|
||||
if err := mq.NodeUpdate(&node); err != nil {
|
||||
slog.Error("error publishing node update to node", "node", node.ID, "error", err)
|
||||
}
|
||||
}
|
||||
if servercfg.IsDNSMode() {
|
||||
logic.SetDNS()
|
||||
}
|
||||
}()
|
||||
logger.Log(1, r.Header.Get("user"), "deleted network", network)
|
||||
w.WriteHeader(http.StatusOK)
|
||||
json.NewEncoder(w).Encode("success")
|
||||
|
|
|
@ -75,11 +75,19 @@ func TestDeleteNetwork(t *testing.T) {
|
|||
t.Run("NetworkwithNodes", func(t *testing.T) {
|
||||
})
|
||||
t.Run("DeleteExistingNetwork", func(t *testing.T) {
|
||||
err := logic.DeleteNetwork("skynet")
|
||||
doneCh := make(chan struct{}, 1)
|
||||
err := logic.DeleteNetwork("skynet", false, doneCh)
|
||||
assert.Nil(t, err)
|
||||
})
|
||||
t.Run("NonExistentNetwork", func(t *testing.T) {
|
||||
err := logic.DeleteNetwork("skynet")
|
||||
doneCh := make(chan struct{}, 1)
|
||||
err := logic.DeleteNetwork("skynet", false, doneCh)
|
||||
assert.Nil(t, err)
|
||||
})
|
||||
createNetv1("test")
|
||||
t.Run("ForceDeleteNetwork", func(t *testing.T) {
|
||||
doneCh := make(chan struct{}, 1)
|
||||
err := logic.DeleteNetwork("test", true, doneCh)
|
||||
assert.Nil(t, err)
|
||||
})
|
||||
}
|
||||
|
@ -214,6 +222,15 @@ func createNet() {
|
|||
logic.CreateNetwork(network)
|
||||
}
|
||||
}
|
||||
func createNetv1(netId string) {
|
||||
var network models.Network
|
||||
network.NetID = netId
|
||||
network.AddressRange = "100.0.0.1/24"
|
||||
_, err := logic.GetNetwork(netId)
|
||||
if err != nil {
|
||||
logic.CreateNetwork(network)
|
||||
}
|
||||
}
|
||||
|
||||
func createNetDualStack() {
|
||||
var network models.Network
|
||||
|
|
|
@ -102,7 +102,7 @@ func RemoveIpFromAllocatedIpMap(networkName string, ip string) {
|
|||
// AddNetworkToAllocatedIpMap - add network to allocated ip map when network is added
|
||||
func AddNetworkToAllocatedIpMap(networkName string) {
|
||||
networkCacheMutex.Lock()
|
||||
allocatedIpMap[networkName] = map[string]net.IP{}
|
||||
allocatedIpMap[networkName] = make(map[string]net.IP)
|
||||
networkCacheMutex.Unlock()
|
||||
}
|
||||
|
||||
|
@ -171,23 +171,8 @@ func GetNetworks() ([]models.Network, error) {
|
|||
}
|
||||
|
||||
// DeleteNetwork - deletes a network
|
||||
func DeleteNetwork(network string) error {
|
||||
// remove ACL for network
|
||||
err := nodeacls.DeleteACLContainer(nodeacls.NetworkID(network))
|
||||
if err != nil {
|
||||
logger.Log(1, "failed to remove the node acls during network delete for network,", network)
|
||||
}
|
||||
// Delete default network enrollment key
|
||||
keys, _ := GetAllEnrollmentKeys()
|
||||
for _, key := range keys {
|
||||
if key.Tags[0] == network {
|
||||
if key.Default {
|
||||
DeleteEnrollmentKey(key.Value, true)
|
||||
break
|
||||
}
|
||||
func DeleteNetwork(network string, force bool, done chan struct{}) error {
|
||||
|
||||
}
|
||||
}
|
||||
nodeCount, err := GetNetworkNonServerNodeCount(network)
|
||||
if nodeCount == 0 || database.IsEmptyRecord(err) {
|
||||
// delete server nodes first then db records
|
||||
|
@ -200,7 +185,50 @@ func DeleteNetwork(network string) error {
|
|||
}
|
||||
return nil
|
||||
}
|
||||
return errors.New("node check failed. All nodes must be deleted before deleting network")
|
||||
|
||||
// Remove All Nodes
|
||||
go func() {
|
||||
nodes, err := GetNetworkNodes(network)
|
||||
if err == nil {
|
||||
for _, node := range nodes {
|
||||
node := node
|
||||
host, err := GetHost(node.HostID.String())
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
DissasociateNodeFromHost(&node, host)
|
||||
}
|
||||
}
|
||||
// remove ACL for network
|
||||
err = nodeacls.DeleteACLContainer(nodeacls.NetworkID(network))
|
||||
if err != nil {
|
||||
logger.Log(1, "failed to remove the node acls during network delete for network,", network)
|
||||
}
|
||||
// delete server nodes first then db records
|
||||
err = database.DeleteRecord(database.NETWORKS_TABLE_NAME, network)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if servercfg.CacheEnabled() {
|
||||
deleteNetworkFromCache(network)
|
||||
}
|
||||
done <- struct{}{}
|
||||
close(done)
|
||||
}()
|
||||
|
||||
// Delete default network enrollment key
|
||||
keys, _ := GetAllEnrollmentKeys()
|
||||
for _, key := range keys {
|
||||
if key.Tags[0] == network {
|
||||
if key.Default {
|
||||
DeleteEnrollmentKey(key.Value, true)
|
||||
break
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// CreateNetwork - creates a network in database
|
||||
|
|
|
@ -239,7 +239,7 @@ func UpdateNode(currentNode *models.Node, newNode *models.Node) error {
|
|||
}
|
||||
}
|
||||
|
||||
return fmt.Errorf("failed to update node " + currentNode.ID.String() + ", cannot change ID.")
|
||||
return fmt.Errorf("failed to update node %s, cannot change ID", currentNode.ID.String())
|
||||
}
|
||||
|
||||
// DeleteNode - marks node for deletion (and adds to zombie list) if called by UI or deletes node if called by node
|
||||
|
|
|
@ -42,9 +42,10 @@ func (network *Network) SetNetworkLastModified() {
|
|||
}
|
||||
|
||||
// Network.SetDefaults - sets default values for a network struct
|
||||
func (network *Network) SetDefaults() {
|
||||
func (network *Network) SetDefaults() (upsert bool) {
|
||||
if network.DefaultUDPHolePunch == "" {
|
||||
network.DefaultUDPHolePunch = "no"
|
||||
upsert = true
|
||||
}
|
||||
if network.DefaultInterface == "" {
|
||||
if len(network.NetID) < 33 {
|
||||
|
@ -52,35 +53,45 @@ func (network *Network) SetDefaults() {
|
|||
} else {
|
||||
network.DefaultInterface = network.NetID
|
||||
}
|
||||
upsert = true
|
||||
}
|
||||
if network.DefaultListenPort == 0 {
|
||||
network.DefaultListenPort = 51821
|
||||
upsert = true
|
||||
}
|
||||
if network.NodeLimit == 0 {
|
||||
network.NodeLimit = 999999999
|
||||
upsert = true
|
||||
}
|
||||
if network.DefaultKeepalive == 0 {
|
||||
network.DefaultKeepalive = 20
|
||||
upsert = true
|
||||
}
|
||||
if network.AllowManualSignUp == "" {
|
||||
network.AllowManualSignUp = "no"
|
||||
upsert = true
|
||||
}
|
||||
|
||||
if network.IsIPv4 == "" {
|
||||
network.IsIPv4 = "yes"
|
||||
upsert = true
|
||||
}
|
||||
|
||||
if network.IsIPv6 == "" {
|
||||
network.IsIPv6 = "no"
|
||||
upsert = true
|
||||
}
|
||||
|
||||
if network.DefaultMTU == 0 {
|
||||
network.DefaultMTU = 1280
|
||||
upsert = true
|
||||
}
|
||||
|
||||
if network.DefaultACL == "" {
|
||||
network.DefaultACL = "yes"
|
||||
upsert = true
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (network *Network) GetNetworkNetworkCIDR4() *net.IPNet {
|
||||
|
|
|
@ -59,32 +59,8 @@ func setNetworkDefaults() error {
|
|||
return err
|
||||
}
|
||||
for _, network := range networks {
|
||||
update := false
|
||||
newNet := network
|
||||
if strings.Contains(network.NetID, ".") {
|
||||
newNet.NetID = strings.ReplaceAll(network.NetID, ".", "")
|
||||
newNet.DefaultInterface = strings.ReplaceAll(network.DefaultInterface, ".", "")
|
||||
update = true
|
||||
}
|
||||
if strings.ContainsAny(network.NetID, "ABCDEFGHIJKLMNOPQRSTUVWXYZ") {
|
||||
newNet.NetID = strings.ToLower(network.NetID)
|
||||
newNet.DefaultInterface = strings.ToLower(network.DefaultInterface)
|
||||
update = true
|
||||
}
|
||||
if update {
|
||||
newNet.SetDefaults()
|
||||
if err := logic.SaveNetwork(&newNet); err != nil {
|
||||
logger.Log(0, "error saving networks during initial update:", err.Error())
|
||||
}
|
||||
if err := logic.DeleteNetwork(network.NetID); err != nil {
|
||||
logger.Log(0, "error deleting old network:", err.Error())
|
||||
}
|
||||
} else {
|
||||
network.SetDefaults()
|
||||
_, _, _, err = logic.UpdateNetwork(&network, &network)
|
||||
if err != nil {
|
||||
logger.Log(0, "could not set defaults on network", network.NetID)
|
||||
}
|
||||
if network.SetDefaults() {
|
||||
logic.SaveNetwork(&network)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
|
Loading…
Add table
Reference in a new issue