Skip to content

Commit a75fbe7

Browse files
tamilmani1989jaer-tsun
authored andcommitted
Set dns server on azure bridge for ubuntu version >= 17 (#345)
* configure dns server on azure bridge for ubuntu versions > 18. Moved hns related apis from platform package to hsnclient package * read dns server from interface instead of file and fixed few issues * renturn error on fail to configure dns * added unitest and fixed an issue in ReadFileByLines method * added a UT * addressed comments and added few tests to get code coverage * confiure dns for ubuntu17 also * corrected typo error of filename
1 parent 9a48bc7 commit a75fbe7

File tree

16 files changed

+451
-218
lines changed

16 files changed

+451
-218
lines changed

cns/hnsclient/hnsclient_linux.go

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package hnsclient
2+
3+
import (
4+
"fmt"
5+
6+
"github.com/Azure/azure-container-networking/cns"
7+
)
8+
9+
// CreateDefaultExtNetwork creates the default ext network (if it doesn't exist already)
10+
// to create external switch on windows platform.
11+
// This is windows platform specific.
12+
func CreateDefaultExtNetwork(networkType string) error {
13+
return fmt.Errorf("CreateDefaultExtNetwork shouldn't be called for linux platform")
14+
}
15+
16+
// DeleteDefaultExtNetwork deletes the default HNS network.
17+
// This is windows platform specific.
18+
func DeleteDefaultExtNetwork() error {
19+
return fmt.Errorf("DeleteDefaultExtNetwork shouldn't be called for linux platform")
20+
}
21+
22+
// CreateHnsNetwork creates the HNS network with the provided configuration
23+
// This is windows platform specific.
24+
func CreateHnsNetwork(nwConfig cns.CreateHnsNetworkRequest) error {
25+
return fmt.Errorf("CreateHnsNetwork shouldn't be called for linux platform")
26+
}
27+
28+
// DeleteHnsNetwork deletes the HNS network with the provided name.
29+
// This is windows platform specific.
30+
func DeleteHnsNetwork(networkName string) error {
31+
return fmt.Errorf("DeleteHnsNetwork shouldn't be called for linux platform")
32+
}

cns/hnsclient/hnsclient_windows.go

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
package hnsclient
2+
3+
import (
4+
"encoding/json"
5+
"fmt"
6+
"log"
7+
"strings"
8+
9+
"github.com/Azure/azure-container-networking/cns"
10+
"github.com/Microsoft/hcsshim"
11+
)
12+
13+
// CreateHnsNetwork creates the HNS network with the provided configuration
14+
func CreateHnsNetwork(nwConfig cns.CreateHnsNetworkRequest) error {
15+
log.Printf("[Azure CNS] CreateHnsNetwork")
16+
// Initialize HNS network.
17+
hnsNetwork := &hcsshim.HNSNetwork{
18+
Name: nwConfig.NetworkName,
19+
Type: nwConfig.NetworkType,
20+
NetworkAdapterName: nwConfig.NetworkAdapterName,
21+
SourceMac: nwConfig.SourceMac,
22+
DNSSuffix: nwConfig.DNSSuffix,
23+
DNSServerList: nwConfig.DNSServerList,
24+
DNSServerCompartment: nwConfig.DNSServerCompartment,
25+
ManagementIP: nwConfig.ManagementIP,
26+
AutomaticDNS: nwConfig.AutomaticDNS,
27+
}
28+
29+
for _, policy := range nwConfig.Policies {
30+
hnsNetwork.Policies = append(hnsNetwork.Policies, policy)
31+
}
32+
33+
for _, subnet := range nwConfig.Subnets {
34+
hnsSubnet := hcsshim.Subnet{
35+
AddressPrefix: subnet.AddressPrefix,
36+
GatewayAddress: subnet.GatewayAddress,
37+
}
38+
39+
hnsNetwork.Subnets = append(hnsNetwork.Subnets, hnsSubnet)
40+
}
41+
42+
for _, macPool := range nwConfig.MacPools {
43+
hnsMacPool := hcsshim.MacPool{
44+
StartMacAddress: macPool.StartMacAddress,
45+
EndMacAddress: macPool.EndMacAddress,
46+
}
47+
hnsNetwork.MacPools = append(hnsNetwork.MacPools, hnsMacPool)
48+
}
49+
50+
return createHnsNetwork(hnsNetwork)
51+
}
52+
53+
// DeleteHnsNetwork deletes the HNS network with the provided name
54+
func DeleteHnsNetwork(networkName string) error {
55+
log.Printf("[Azure CNS] DeleteHnsNetwork")
56+
57+
return deleteHnsNetwork(networkName)
58+
}
59+
60+
// CreateDefaultExtNetwork creates default HNS network named ext (if it doesn't exist already)
61+
// to create external switch on windows platform.
62+
// This allows orchestrators to start CNS which pre-provisions the network so that the
63+
// VM network blip / disconnect is avoided when calling cni add for the very first time.
64+
func CreateDefaultExtNetwork(networkType string) error {
65+
networkType = strings.ToLower(strings.TrimSpace(networkType))
66+
if len(networkType) == 0 {
67+
return nil
68+
}
69+
70+
if networkType != hnsL2Bridge && networkType != hnsL2Tunnel {
71+
return fmt.Errorf("Invalid hns network type %s", networkType)
72+
}
73+
74+
log.Printf("[Azure CNS] CreateDefaultExtNetwork")
75+
extHnsNetwork, _ := hcsshim.GetHNSNetworkByName(ExtHnsNetworkName)
76+
77+
if extHnsNetwork != nil {
78+
log.Printf("[Azure CNS] Found existing DefaultExtNetwork with type: %s", extHnsNetwork.Type)
79+
if !strings.EqualFold(networkType, extHnsNetwork.Type) {
80+
return fmt.Errorf("Network type mismatch with existing network: %s", extHnsNetwork.Type)
81+
}
82+
83+
return nil
84+
}
85+
86+
// create new hns network
87+
log.Printf("[Azure CNS] Creating DefaultExtNetwork with type %s", networkType)
88+
89+
hnsNetwork := &hcsshim.HNSNetwork{
90+
Name: ExtHnsNetworkName,
91+
Type: networkType,
92+
}
93+
94+
hnsSubnet := hcsshim.Subnet{
95+
AddressPrefix: ExtHnsNetworkAddressPrefix,
96+
GatewayAddress: ExtHnsNetworkGwAddress,
97+
}
98+
99+
hnsNetwork.Subnets = append(hnsNetwork.Subnets, hnsSubnet)
100+
101+
return createHnsNetwork(hnsNetwork)
102+
}
103+
104+
// DeleteDefaultExtNetwork deletes the default HNS network
105+
func DeleteDefaultExtNetwork() error {
106+
log.Printf("[Azure CNS] DeleteDefaultExtNetwork")
107+
108+
return deleteHnsNetwork(ExtHnsNetworkName)
109+
}
110+
111+
// createHnsNetwork calls the hcshim to create the hns network
112+
func createHnsNetwork(hnsNetwork *hcsshim.HNSNetwork) error {
113+
// Marshal the request.
114+
buffer, err := json.Marshal(hnsNetwork)
115+
if err != nil {
116+
return err
117+
}
118+
hnsRequest := string(buffer)
119+
120+
// Create the HNS network.
121+
log.Printf("[Azure CNS] HNSNetworkRequest POST request:%+v", hnsRequest)
122+
hnsResponse, err := hcsshim.HNSNetworkRequest("POST", "", hnsRequest)
123+
log.Printf("[Azure CNS] HNSNetworkRequest POST response:%+v err:%v.", hnsResponse, err)
124+
125+
return err
126+
}
127+
128+
// deleteHnsNetwork calls HNS to delete the network with the provided name
129+
func deleteHnsNetwork(networkName string) error {
130+
hnsNetwork, err := hcsshim.GetHNSNetworkByName(networkName)
131+
if err == nil {
132+
// Delete the HNS network.
133+
var hnsResponse *hcsshim.HNSNetwork
134+
log.Printf("[Azure CNS] HNSNetworkRequest DELETE id:%v", hnsNetwork.Id)
135+
hnsResponse, err = hcsshim.HNSNetworkRequest("DELETE", hnsNetwork.Id, "")
136+
log.Printf("[Azure CNS] HNSNetworkRequest DELETE response:%+v err:%v.", hnsResponse, err)
137+
}
138+
139+
return err
140+
}

cns/restserver/restserver.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import (
1414
"github.com/Azure/azure-container-networking/cns"
1515
"github.com/Azure/azure-container-networking/cns/common"
1616
"github.com/Azure/azure-container-networking/cns/dockerclient"
17+
"github.com/Azure/azure-container-networking/cns/hnsclient"
1718
"github.com/Azure/azure-container-networking/cns/imdsclient"
1819
"github.com/Azure/azure-container-networking/cns/ipamclient"
1920
"github.com/Azure/azure-container-networking/cns/networkcontainers"
@@ -428,7 +429,7 @@ func (service *HTTPRestService) createHnsNetwork(w http.ResponseWriter, r *http.
428429
} else {
429430
switch r.Method {
430431
case "POST":
431-
if err := platform.CreateHnsNetwork(req); err == nil {
432+
if err := hnsclient.CreateHnsNetwork(req); err == nil {
432433
// Save the newly created HnsNetwork name. CNS deleteHnsNetwork API
433434
// will only allow deleting these networks.
434435
networkInfo := &networkInfo{
@@ -480,7 +481,7 @@ func (service *HTTPRestService) deleteHnsNetwork(w http.ResponseWriter, r *http.
480481
case "POST":
481482
networkInfo, found := service.getNetworkInfo(req.NetworkName)
482483
if found && networkInfo.NetworkName == req.NetworkName {
483-
if err = platform.DeleteHnsNetwork(req.NetworkName); err == nil {
484+
if err = hnsclient.DeleteHnsNetwork(req.NetworkName); err == nil {
484485
returnMessage = fmt.Sprintf("[Azure CNS] Successfully deleted HNS network: %s", req.NetworkName)
485486
} else {
486487
returnMessage = fmt.Sprintf("[Azure CNS] DeleteHnsNetwork failed with error %v", err.Error())

cns/service/main.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import (
1313
"github.com/Azure/azure-container-networking/cnm/ipam"
1414
"github.com/Azure/azure-container-networking/cnm/network"
1515
"github.com/Azure/azure-container-networking/cns/common"
16+
"github.com/Azure/azure-container-networking/cns/hnsclient"
1617
"github.com/Azure/azure-container-networking/cns/restserver"
1718
acn "github.com/Azure/azure-container-networking/common"
1819
"github.com/Azure/azure-container-networking/log"
@@ -243,7 +244,7 @@ func main() {
243244

244245
// Create default ext network if commandline option is set
245246
if len(strings.TrimSpace(createDefaultExtNetworkType)) > 0 {
246-
if err := platform.CreateDefaultExtNetwork(createDefaultExtNetworkType); err == nil {
247+
if err := hnsclient.CreateDefaultExtNetwork(createDefaultExtNetworkType); err == nil {
247248
log.Printf("[Azure CNS] Successfully created default ext network")
248249
} else {
249250
log.Printf("[Azure CNS] Failed to create default ext network due to error: %v", err)
@@ -329,7 +330,7 @@ func main() {
329330
}
330331

331332
if len(strings.TrimSpace(createDefaultExtNetworkType)) > 0 {
332-
if err := platform.DeleteDefaultExtNetwork(); err == nil {
333+
if err := hnsclient.DeleteDefaultExtNetwork(); err == nil {
333334
log.Printf("[Azure CNS] Successfully deleted default ext network")
334335
} else {
335336
log.Printf("[Azure CNS] Failed to delete default ext network due to error: %v", err)

common/testfiles/test1

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
hello
2+
azure-container-networking

common/testfiles/test2

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
single

common/testfiles/test3

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
singlewith\n

common/utils.go

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,11 @@
44
package common
55

66
import (
7+
"bufio"
78
"encoding/binary"
89
"encoding/xml"
10+
"fmt"
11+
"io"
912
"net"
1013
"os"
1114

@@ -123,3 +126,35 @@ func StartProcess(path string, args []string) error {
123126

124127
return err
125128
}
129+
130+
// ReadFileByLines reads file line by line and return array of lines.
131+
func ReadFileByLines(filename string) ([]string, error) {
132+
var (
133+
lineStrArr []string
134+
)
135+
136+
f, err := os.Open(filename)
137+
if err != nil {
138+
return nil, fmt.Errorf("Error opening %s file error %v", filename, err)
139+
}
140+
141+
defer f.Close()
142+
143+
r := bufio.NewReader(f)
144+
145+
for {
146+
lineStr, err := r.ReadString('\n')
147+
if err != nil {
148+
if err != io.EOF {
149+
return nil, fmt.Errorf("Error reading %s file error %v", filename, err)
150+
}
151+
152+
lineStrArr = append(lineStrArr, lineStr)
153+
break
154+
}
155+
156+
lineStrArr = append(lineStrArr, lineStr)
157+
}
158+
159+
return lineStrArr, nil
160+
}

common/utils_test.go

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
package common
2+
3+
import (
4+
"os"
5+
"testing"
6+
)
7+
8+
func TestMain(m *testing.M) {
9+
exitCode := m.Run()
10+
os.Exit(exitCode)
11+
}
12+
13+
func TestReadFileByLines(t *testing.T) {
14+
lines, err := ReadFileByLines("testfiles/test1")
15+
if err != nil {
16+
t.Errorf("ReadFileByLines failed: %v", err)
17+
}
18+
19+
if len(lines) != 2 {
20+
t.Errorf("Line count %d didn't match expected count", len(lines))
21+
}
22+
23+
lines = nil
24+
25+
lines, err = ReadFileByLines("testfiles/test2")
26+
if err != nil {
27+
t.Errorf("ReadFileByLines failed: %v", err)
28+
}
29+
30+
if len(lines) != 1 {
31+
t.Errorf("Line count %d didn't match expected count", len(lines))
32+
}
33+
34+
lines = nil
35+
36+
lines, err = ReadFileByLines("testfiles/test3")
37+
if err != nil {
38+
t.Errorf("ReadFileByLines failed: %v", err)
39+
}
40+
41+
if len(lines) != 2 {
42+
t.Errorf("Line count %d didn't match expected count", len(lines))
43+
}
44+
45+
if lines[1] != "" {
46+
t.Errorf("Expected empty line but got %s", lines[1])
47+
}
48+
}
49+
50+
func TestFileExists(t *testing.T) {
51+
isExist, err := CheckIfFileExists("testfiles/test1")
52+
if err != nil || !isExist {
53+
t.Errorf("Returned file not found %v", err)
54+
}
55+
56+
isExist, err = CheckIfFileExists("testfiles/filenotfound")
57+
if err != nil || isExist {
58+
t.Errorf("Returned file found")
59+
}
60+
}

network/network.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ type externalInterface struct {
2626
Networks map[string]*network
2727
Subnets []string
2828
BridgeName string
29+
DNSServerIP string
2930
MacAddress net.HardwareAddr
3031
IPAddresses []*net.IPNet
3132
Routes []*route

0 commit comments

Comments
 (0)