Skip to content

Commit 2157d7a

Browse files
authored
Skip network creation if network already exists in HNS (#1300)
* skip network creation if network already exists * address comments * address feedback
1 parent 31a3b27 commit 2157d7a

File tree

3 files changed

+59
-8
lines changed

3 files changed

+59
-8
lines changed

network/hnswrapper/hnsv2wrapperfake.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ func (f Hnsv2wrapperFake) GetNetworkByName(networkName string) (*hcn.HostCompute
167167
if network, ok := f.Cache.networks[networkName]; ok {
168168
return network.GetHCNObj(), nil
169169
}
170-
return &hcn.HostComputeNetwork{}, nil
170+
return nil, hcn.NetworkNotFoundError{}
171171
}
172172

173173
func (f Hnsv2wrapperFake) GetNetworkByID(networkID string) (*hcn.HostComputeNetwork, error) {

network/network_windows.go

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ package network
55

66
import (
77
"encoding/json"
8+
"errors"
89
"fmt"
910
"strconv"
1011
"strings"
@@ -310,14 +311,27 @@ func (nm *networkManager) newNetworkImplHnsV2(nwInfo *NetworkInfo, extIf *extern
310311
return nil, err
311312
}
312313

313-
// Create the HNS network.
314-
log.Printf("[net] Creating hcn network: %+v", hcnNetwork)
315-
hnsResponse, err := hnsv2.CreateNetwork(hcnNetwork)
314+
// check if network exists, only create the network does not exist
315+
hnsResponse, err := hnsv2.GetNetworkByName(hcnNetwork.Name)
316+
316317
if err != nil {
317-
return nil, fmt.Errorf("Failed to create hcn network: %s due to error: %v", hcnNetwork.Name, err)
318-
}
318+
// if network not found, create the HNS network.
319+
if errors.As(err, &hcn.NetworkNotFoundError{}) {
320+
log.Printf("[net] Creating hcn network: %+v", hcnNetwork)
321+
hnsResponse, err = hnsv2.CreateNetwork(hcnNetwork)
322+
323+
if err != nil {
324+
return nil, fmt.Errorf("Failed to create hcn network: %s due to error: %v", hcnNetwork.Name, err)
325+
}
319326

320-
log.Printf("[net] Successfully created hcn network with response: %+v", hnsResponse)
327+
log.Printf("[net] Successfully created hcn network with response: %+v", hnsResponse)
328+
} else {
329+
// we can't validate if the network already exists, don't continue
330+
return nil, fmt.Errorf("Failed to create hcn network: %s, failed to query for existing network with error: %v", hcnNetwork.Name, err)
331+
}
332+
} else {
333+
log.Printf("[net] Network with name %s already exists", hcnNetwork.Name)
334+
}
321335

322336
var vlanid int
323337
opt, _ := nwInfo.Options[genericData].(map[string]interface{})

network/network_windows_test.go

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ import (
1111
"testing"
1212

1313
"github.com/Azure/azure-container-networking/network/hnswrapper"
14+
15+
"github.com/Microsoft/hcsshim/hcn"
1416
)
1517

1618
func TestNewAndDeleteNetworkImplHnsV2(t *testing.T) {
@@ -20,7 +22,7 @@ func TestNewAndDeleteNetworkImplHnsV2(t *testing.T) {
2022

2123
// this hnsv2 variable overwrites the package level variable in network
2224
// we do this to avoid passing around os specific objects in platform agnostic code
23-
hnsv2 = hnswrapper.Hnsv2wrapperFake{}
25+
hnsv2 = hnswrapper.NewHnsv2wrapperFake()
2426

2527
nwInfo := &NetworkInfo{
2628
Id: "d3e97a83-ba4c-45d5-ba88-dc56757ece28",
@@ -47,3 +49,38 @@ func TestNewAndDeleteNetworkImplHnsV2(t *testing.T) {
4749
t.Fatal(err)
4850
}
4951
}
52+
53+
func TestSuccesfulNetworkCreationWhenAlreadyExists(t *testing.T) {
54+
nm := &networkManager{
55+
ExternalInterfaces: map[string]*externalInterface{},
56+
}
57+
58+
// this hnsv2 variable overwrites the package level variable in network
59+
// we do this to avoid passing around os specific objects in platform agnostic code
60+
hnsv2 = hnswrapper.NewHnsv2wrapperFake()
61+
62+
network := &hcn.HostComputeNetwork{
63+
Name: "azure-vlan1-172-28-1-0_24",
64+
}
65+
66+
_, err := hnsv2.CreateNetwork(network)
67+
68+
// network name is derived from network info id
69+
nwInfo := &NetworkInfo{
70+
Id: "azure-vlan1-172-28-1-0_24",
71+
MasterIfName: "eth0",
72+
Mode: "bridge",
73+
}
74+
75+
extInterface := &externalInterface{
76+
Name: "eth0",
77+
Subnets: []string{"subnet1", "subnet2"},
78+
}
79+
80+
_, err = nm.newNetworkImplHnsV2(nwInfo, extInterface)
81+
82+
if err != nil {
83+
fmt.Printf("+%v", err)
84+
t.Fatal(err)
85+
}
86+
}

0 commit comments

Comments
 (0)