Skip to content

Commit 405f9f4

Browse files
tamilmani1989sharmasushant
authored andcommitted
Started azure vnet and ipam as part of CNS and enabled outbound connectivity for containers by default
1 parent 62dbeaf commit 405f9f4

File tree

5 files changed

+135
-5
lines changed

5 files changed

+135
-5
lines changed

cns/api.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ type OverlayConfiguration struct {
3535
type CreateNetworkRequest struct {
3636
NetworkName string
3737
OverlayConfiguration OverlayConfiguration
38+
Options map[string]interface{}
3839
}
3940

4041
// DeleteNetworkRequest describes request to delete the network.

cns/dockerclient/api.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ package dockerclient
66
const (
77
createNetworkPath = "/networks/create"
88
inspectNetworkPath = "/networks/"
9+
10+
OptDisableSnat = "DisableSNAT"
911
)
1012

1113
// Config describes subnet/gateway for ipam.
@@ -25,6 +27,7 @@ type NetworkConfiguration struct {
2527
Driver string
2628
IPAM IPAM
2729
Internal bool
30+
Options map[string]interface{}
2831
}
2932

3033
// DockerErrorResponse defines the error response retunred by docker.

cns/dockerclient/dockerclient.go

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"encoding/json"
99
"fmt"
1010
"net/http"
11+
"os/exec"
1112

1213
"github.com/Azure/azure-container-networking/cns/imdsclient"
1314
"github.com/Azure/azure-container-networking/log"
@@ -16,6 +17,8 @@ import (
1617
const (
1718
defaultDockerConnectionURL = "http://127.0.0.1:2375"
1819
defaultIpamPlugin = "azure-vnet"
20+
networkMode = "com.microsoft.azure.network.mode"
21+
bridgeMode = "bridge"
1922
)
2023

2124
// DockerClient specifies a client to connect to docker.
@@ -24,6 +27,16 @@ type DockerClient struct {
2427
imdsClient *imdsclient.ImdsClient
2528
}
2629

30+
func executeShellCommand(command string) error {
31+
log.Debugf("[ebtables] %s", command)
32+
cmd := exec.Command("sh", "-c", command)
33+
err := cmd.Start()
34+
if err != nil {
35+
return err
36+
}
37+
return cmd.Wait()
38+
}
39+
2740
// NewDockerClient create a new docker client.
2841
func NewDockerClient(url string) (*DockerClient, error) {
2942
return &DockerClient{
@@ -68,9 +81,11 @@ func (dockerClient *DockerClient) NetworkExists(networkName string) error {
6881
}
6982

7083
// CreateNetwork creates a network using docker network create.
71-
func (dockerClient *DockerClient) CreateNetwork(networkName string) error {
84+
func (dockerClient *DockerClient) CreateNetwork(networkName string, options map[string]interface{}) error {
7285
log.Printf("[Azure CNS] CreateNetwork")
7386

87+
enableSnat := true
88+
7489
primaryNic, err := dockerClient.imdsClient.GetPrimaryInterfaceInfoFromHost()
7590
if err != nil {
7691
return err
@@ -94,6 +109,17 @@ func (dockerClient *DockerClient) CreateNetwork(networkName string) error {
94109
Internal: true,
95110
}
96111

112+
if options != nil {
113+
if _, ok := options[OptDisableSnat]; ok {
114+
enableSnat = false
115+
}
116+
}
117+
118+
if enableSnat {
119+
netConfig.Options = make(map[string]interface{})
120+
netConfig.Options[networkMode] = bridgeMode
121+
}
122+
97123
log.Printf("[Azure CNS] Going to create network with config: %+v", netConfig)
98124

99125
netConfigJSON := new(bytes.Buffer)
@@ -123,6 +149,16 @@ func (dockerClient *DockerClient) CreateNetwork(networkName string) error {
123149
res.StatusCode, createNetworkResponse.message, ermsg)
124150
}
125151

152+
if enableSnat {
153+
cmd := fmt.Sprintf("iptables -t nat -A POSTROUTING -m iprange ! --dst-range 168.63.129.16 -m addrtype ! --dst-type local ! -d %v -j MASQUERADE",
154+
primaryNic.Subnet)
155+
err = executeShellCommand(cmd)
156+
if err != nil {
157+
log.Printf("SNAT Iptable rule was not set")
158+
return err
159+
}
160+
}
161+
126162
return nil
127163
}
128164

@@ -143,6 +179,14 @@ func (dockerClient *DockerClient) DeleteNetwork(networkName string) error {
143179

144180
// network successfully deleted.
145181
if res.StatusCode == 204 {
182+
primaryNic, err := dockerClient.imdsClient.GetPrimaryInterfaceInfoFromHost()
183+
if err != nil {
184+
return err
185+
}
186+
187+
cmd := fmt.Sprintf("iptables -t nat -D POSTROUTING -m iprange ! --dst-range 168.63.129.16 -m addrtype ! --dst-type local ! -d %v -j MASQUERADE",
188+
primaryNic.Subnet)
189+
executeShellCommand(cmd)
146190
return nil
147191
}
148192

cns/restserver/restserver.go

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,10 @@ package restserver
55

66
import (
77
"fmt"
8+
"net"
89
"net/http"
910
"time"
1011

11-
"net"
12-
1312
"github.com/Azure/azure-container-networking/cns"
1413
"github.com/Azure/azure-container-networking/cns/common"
1514
"github.com/Azure/azure-container-networking/cns/dockerclient"
@@ -187,7 +186,7 @@ func (service *httpRestService) createNetwork(w http.ResponseWriter, r *http.Req
187186
log.Printf("[Azure CNS] Unable to get routing table from node, %+v.", err.Error())
188187
}
189188

190-
err = dc.CreateNetwork(req.NetworkName)
189+
err = dc.CreateNetwork(req.NetworkName, req.Options)
191190
if err != nil {
192191
returnMessage = fmt.Sprintf("[Azure CNS] Error. CreateNetwork failed %v.", err.Error())
193192
returnCode = UnexpectedError

cns/service/main.go

Lines changed: 84 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ import (
99
"os/signal"
1010
"syscall"
1111

12+
"github.com/Azure/azure-container-networking/cnm/ipam"
13+
"github.com/Azure/azure-container-networking/cnm/network"
1214
"github.com/Azure/azure-container-networking/cns/common"
1315
"github.com/Azure/azure-container-networking/cns/restserver"
1416
acn "github.com/Azure/azure-container-networking/common"
@@ -19,14 +21,27 @@ import (
1921

2022
const (
2123
// Service name.
22-
name = "azure-cns"
24+
name = "azure-cns"
25+
pluginName = "azure-vnet"
2326
)
2427

2528
// Version is populated by make during build.
2629
var version string
2730

2831
// Command line arguments for CNM plugin.
2932
var args = acn.ArgumentList{
33+
{
34+
Name: acn.OptEnvironment,
35+
Shorthand: acn.OptEnvironmentAlias,
36+
Description: "Set the operating environment",
37+
Type: "string",
38+
DefaultValue: acn.OptEnvironmentAzure,
39+
ValueMap: map[string]interface{}{
40+
acn.OptEnvironmentAzure: 0,
41+
acn.OptEnvironmentMAS: 0,
42+
},
43+
},
44+
3045
{
3146
Name: acn.OptAPIServerURL,
3247
Shorthand: acn.OptAPIServerURLAlias,
@@ -57,6 +72,13 @@ var args = acn.ArgumentList{
5772
acn.OptLogTargetFile: log.TargetLogfile,
5873
},
5974
},
75+
{
76+
Name: acn.OptIpamQueryInterval,
77+
Shorthand: acn.OptIpamQueryIntervalAlias,
78+
Description: "Set the IPAM plugin query interval",
79+
Type: "int",
80+
DefaultValue: "",
81+
},
6082
{
6183
Name: acn.OptVersion,
6284
Shorthand: acn.OptVersionAlias,
@@ -77,9 +99,11 @@ func main() {
7799
// Initialize and parse command line arguments.
78100
acn.ParseArgs(&args, printVersion)
79101

102+
environment := acn.GetArg(acn.OptEnvironment).(string)
80103
url := acn.GetArg(acn.OptAPIServerURL).(string)
81104
logLevel := acn.GetArg(acn.OptLogLevel).(int)
82105
logTarget := acn.GetArg(acn.OptLogTarget).(int)
106+
ipamQueryInterval, _ := acn.GetArg(acn.OptIpamQueryInterval).(int)
83107
vers := acn.GetArg(acn.OptVersion).(bool)
84108

85109
if vers {
@@ -110,6 +134,33 @@ func main() {
110134
return
111135
}
112136

137+
var pluginConfig acn.PluginConfig
138+
pluginConfig.Version = version
139+
140+
// Create a channel to receive unhandled errors from the plugins.
141+
pluginConfig.ErrChan = make(chan error, 1)
142+
143+
// Create network plugin.
144+
netPlugin, err := network.NewPlugin(&pluginConfig)
145+
if err != nil {
146+
fmt.Printf("Failed to create network plugin, err:%v.\n", err)
147+
return
148+
}
149+
150+
// Create IPAM plugin.
151+
ipamPlugin, err := ipam.NewPlugin(&pluginConfig)
152+
if err != nil {
153+
fmt.Printf("Failed to create IPAM plugin, err:%v.\n", err)
154+
return
155+
}
156+
157+
// Create the key value store.
158+
pluginConfig.Store, err = store.NewJsonFileStore(platform.RuntimePath + pluginName + ".json")
159+
if err != nil {
160+
fmt.Printf("Failed to create store: %v\n", err)
161+
return
162+
}
163+
113164
// Create logging provider.
114165
log.SetName(name)
115166
log.SetLevel(logLevel)
@@ -134,6 +185,30 @@ func main() {
134185
}
135186
}
136187

188+
// Set plugin options.
189+
netPlugin.SetOption(acn.OptAPIServerURL, url)
190+
191+
ipamPlugin.SetOption(acn.OptEnvironment, environment)
192+
ipamPlugin.SetOption(acn.OptAPIServerURL, url)
193+
ipamPlugin.SetOption(acn.OptIpamQueryInterval, ipamQueryInterval)
194+
195+
if netPlugin != nil {
196+
log.Printf("Start netplugin\n")
197+
err = netPlugin.Start(&pluginConfig)
198+
if err != nil {
199+
fmt.Printf("Failed to start network plugin, err:%v.\n", err)
200+
return
201+
}
202+
}
203+
204+
if ipamPlugin != nil {
205+
err = ipamPlugin.Start(&pluginConfig)
206+
if err != nil {
207+
fmt.Printf("Failed to start IPAM plugin, err:%v.\n", err)
208+
return
209+
}
210+
}
211+
137212
// Relay these incoming signals to OS signal channel.
138213
osSignalChannel := make(chan os.Signal, 1)
139214
signal.Notify(osSignalChannel, os.Interrupt, os.Kill, syscall.SIGTERM)
@@ -150,4 +225,12 @@ func main() {
150225
if httpRestService != nil {
151226
httpRestService.Stop()
152227
}
228+
229+
if netPlugin != nil {
230+
netPlugin.Stop()
231+
}
232+
233+
if ipamPlugin != nil {
234+
ipamPlugin.Stop()
235+
}
153236
}

0 commit comments

Comments
 (0)