Skip to content

Commit b6a3eb3

Browse files
committed
In swarm-mode, add check for mapped docker network
when deleting netctl network or epg.
1 parent 36948f3 commit b6a3eb3

File tree

11 files changed

+106
-28
lines changed

11 files changed

+106
-28
lines changed

mgmtfn/dockplugin/netDriver.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -400,7 +400,7 @@ func allocateNetwork(w http.ResponseWriter, r *http.Request) {
400400
// node where a container in the network is instantiated.
401401
// We process only allocateNetwork in this case.
402402
//
403-
if pluginMode == "swarm-mode" {
403+
if pluginMode == master.SwarmMode {
404404
tag := ""
405405
log.Infof("Options: %+v", anreq.Options)
406406
if _, tagOk := anreq.Options["contiv-tag"]; tagOk {
@@ -442,7 +442,7 @@ func freeNetwork(w http.ResponseWriter, r *http.Request) {
442442
return
443443
}
444444

445-
if pluginMode == "swarm-mode" {
445+
if pluginMode == master.SwarmMode {
446446
err = deleteNetworkHelper(req.NetworkID)
447447
if err != nil {
448448
httpError(w, "Could not delete network", err)
@@ -572,7 +572,7 @@ func GetDockerNetworkName(nwID string) (string, string, string, error) {
572572
if err == nil {
573573
return dnetOper.TenantName, dnetOper.NetworkName, dnetOper.ServiceName, nil
574574
}
575-
if pluginMode == "swarm-mode" {
575+
if pluginMode == master.SwarmMode {
576576
log.Errorf("Unable to find docknet info in objstore")
577577
return "", "", "", err
578578
}

netmaster/docknet/docknet.go

+24
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,30 @@ func DeleteDockNetState(tenantName, networkName, serviceName string) error {
287287
return dnetOper.Clear()
288288
}
289289

290+
// GetDocknetState gets the docknet entry from state store
291+
func GetDocknetState(tenantName, networkName, serviceName string) (*DnetOperState, error) {
292+
log.Infof("GetDocknetState for %s.%s.%s", tenantName, networkName, serviceName)
293+
294+
// Get the state driver
295+
stateDriver, err := utils.GetStateDriver()
296+
if err != nil {
297+
log.Warnf("Couldn't get state driver for docknet %v", err)
298+
return nil, err
299+
}
300+
301+
// save docknet oper state
302+
dnetOper := DnetOperState{}
303+
dnetOper.ID = fmt.Sprintf("%s.%s.%s", tenantName, networkName, serviceName)
304+
dnetOper.StateDriver = stateDriver
305+
306+
// Read the dnet oper state
307+
err = dnetOper.Read(dnetOper.ID)
308+
if err == nil {
309+
return &dnetOper, nil
310+
}
311+
return nil, err
312+
}
313+
290314
// FindDocknetByUUID find the docknet by UUID
291315
func FindDocknetByUUID(dnetID string) (*DnetOperState, error) {
292316
log.Infof("find docker network '%s' ", dnetID)

netmaster/main.go

+2-1
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import (
2626
log "github.com/Sirupsen/logrus"
2727
"github.com/contiv/netplugin/netmaster/daemon"
2828
"github.com/contiv/netplugin/netmaster/docknet"
29+
"github.com/contiv/netplugin/netmaster/master"
2930
"github.com/contiv/netplugin/version"
3031
)
3132

@@ -153,7 +154,7 @@ func execOpts(opts *cliOpts) {
153154
}
154155
log.Infof("Control IP:Port %s:%s", controlIP, controlURL[1])
155156

156-
if opts.clusterMode == "docker" || opts.clusterMode == "swarm-mode" {
157+
if opts.clusterMode == master.Docker || opts.clusterMode == master.SwarmMode {
157158
docknet.UpdatePluginName(opts.pluginName)
158159
}
159160
}

netmaster/master/api.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,7 @@ func AllocAddressHandler(w http.ResponseWriter, r *http.Request, vars map[string
191191
}
192192

193193
if networkID == "" {
194-
if GetClusterMode() == "swarm-mode" {
194+
if GetClusterMode() == SwarmMode {
195195
// If the network was created using docker command,
196196
// we get allocReq before the network is created. Here,
197197
// we return the first IP in the subnet as gateway IP.

netmaster/master/endpointGroup.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ func CreateEndpointGroup(tenantName, networkName, groupName, ipPool, cfgdTag str
100100
}
101101

102102
// params for docker network
103-
if GetClusterMode() == "docker" {
103+
if GetClusterMode() == Docker {
104104
// Create each EPG as a docker network
105105
err = docknet.CreateDockNet(tenantName, networkName, groupName, nwCfg)
106106
if err != nil {
@@ -249,7 +249,7 @@ func DeleteEndpointGroup(tenantName, groupName string) error {
249249
return err
250250
}
251251

252-
if GetClusterMode() == "docker" {
252+
if GetClusterMode() == Docker {
253253
return docknet.DeleteDockNet(epgCfg.TenantName, epgCfg.NetworkName, epgCfg.GroupName)
254254
}
255255
return nil

netmaster/master/netmaster.go

+14-5
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,14 @@ const (
3333
defaultInfraNetName = "infra"
3434
)
3535

36+
// Plugin modes
37+
const (
38+
Docker = "docker"
39+
Kubernetes = "kubernetes"
40+
SwarmMode = "swarm-mode"
41+
Test = "test"
42+
)
43+
3644
// Run Time config of netmaster
3745
type nmRunTimeConf struct {
3846
clusterMode string
@@ -43,13 +51,14 @@ var masterRTCfg nmRunTimeConf
4351
// SetClusterMode sets the cluster mode for the contiv plugin
4452
func SetClusterMode(cm string) error {
4553
switch cm {
46-
case "docker":
47-
case "kubernetes":
48-
case "swarm-mode":
49-
case "test": // internal mode used for integration testing
54+
case Docker:
55+
case Kubernetes:
56+
case SwarmMode:
57+
case Test: // internal mode used for integration testing
5058
break
5159
default:
52-
return core.Errorf("%s not a valid cluster mode {docker | kubernetes | swarm-mode}", cm)
60+
return core.Errorf("%s not a valid cluster mode {%s | %s | %s}",
61+
cm, Docker, Kubernetes, SwarmMode)
5362
}
5463

5564
masterRTCfg.clusterMode = cm

netmaster/master/network.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,7 @@ func CreateNetwork(network intent.ConfigNetwork, stateDriver core.StateDriver, t
190190
return nil
191191
}
192192

193-
if GetClusterMode() == "docker" {
193+
if GetClusterMode() == Docker {
194194
// Create the network in docker
195195
err = docknet.CreateDockNet(tenantName, network.Name, "", nwCfg)
196196
if err != nil {
@@ -264,7 +264,7 @@ func DeleteNetworkID(stateDriver core.StateDriver, netID string) error {
264264
return core.Errorf("Error: Network has active endpoints")
265265
}
266266

267-
if GetClusterMode() == "docker" && aci == false {
267+
if GetClusterMode() == Docker && aci == false {
268268
// Delete the docker network
269269
err = docknet.DeleteDockNet(nwCfg.Tenant, nwCfg.NetworkName, "")
270270
if err != nil {

netmaster/objApi/apiController.go

+33
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import (
2525
"github.com/contiv/contivmodel"
2626
"github.com/contiv/netplugin/core"
2727
"github.com/contiv/netplugin/drivers"
28+
"github.com/contiv/netplugin/netmaster/docknet"
2829
"github.com/contiv/netplugin/netmaster/gstate"
2930
"github.com/contiv/netplugin/netmaster/intent"
3031
"github.com/contiv/netplugin/netmaster/master"
@@ -984,6 +985,22 @@ func (ac *APIController) EndpointGroupDelete(endpointGroup *contivModel.Endpoint
984985
endpointGroup.GroupName, endpointGroup.Links.AppProfile.ObjKey)
985986
}
986987

988+
// In swarm-mode work-flow, if epg is mapped to a docker network, reject the delete
989+
if master.GetClusterMode() == master.SwarmMode {
990+
dnet, err := docknet.GetDocknetState(endpointGroup.TenantName, endpointGroup.NetworkName, endpointGroup.GroupName)
991+
if err == nil {
992+
return fmt.Errorf("cannot delete group %s mapped to docker network %s",
993+
endpointGroup.GroupName, dnet.DocknetUUID)
994+
}
995+
if !strings.Contains(strings.ToLower(err.Error()), "key not found") {
996+
log.Errorf("Error getting docknet state for %s.%s. (retval = %s)",
997+
endpointGroup.TenantName, endpointGroup.GroupName, err.Error())
998+
return err
999+
}
1000+
log.Infof("No docknet state for %s.%s. (retval = %s)",
1001+
endpointGroup.TenantName, endpointGroup.GroupName, err.Error())
1002+
}
1003+
9871004
// get the netprofile structure by finding the netprofile
9881005
profileKey := GetNetprofileKey(endpointGroup.TenantName, endpointGroup.NetProfile)
9891006
netprofile := contivModel.FindNetprofile(profileKey)
@@ -1172,6 +1189,22 @@ func (ac *APIController) NetworkDelete(network *contivModel.Network) error {
11721189
network.NetworkName, svcCount)
11731190
}
11741191

1192+
// In swarm-mode work-flow, if this is mapped to a docker network, reject delete
1193+
if master.GetClusterMode() == master.SwarmMode {
1194+
docknet, err := docknet.GetDocknetState(network.TenantName, network.NetworkName, "")
1195+
if err == nil {
1196+
return fmt.Errorf("cannot delete network %s mapped to docker network %s",
1197+
network.NetworkName, docknet.DocknetUUID)
1198+
}
1199+
if !strings.Contains(strings.ToLower(err.Error()), "key not found") {
1200+
log.Errorf("Error getting docknet state for %s.%s. (retval = %s)",
1201+
network.TenantName, network.NetworkName, err.Error())
1202+
return err
1203+
}
1204+
log.Infof("No docknet state for %s.%s. (retval = %s)",
1205+
network.TenantName, network.NetworkName, err.Error())
1206+
}
1207+
11751208
// Remove link
11761209
modeldb.RemoveLinkSet(&tenant.LinkSets.Networks, network)
11771210

netmaster/objApi/objapi_test.go

+13-4
Original file line numberDiff line numberDiff line change
@@ -2333,21 +2333,30 @@ func TestEPCreate(t *testing.T) {
23332333
// TestClusterMode verifies cluster mode is correctly reflected.
23342334
func TestClusterMode(t *testing.T) {
23352335

2336-
master.SetClusterMode("kubernetes")
2336+
master.SetClusterMode(master.Kubernetes)
23372337
insp, err := contivClient.GlobalInspect("global")
23382338
if err != nil {
23392339
t.Fatalf("Error inspecting global %v", err)
23402340
}
2341-
if insp.Oper.ClusterMode != "kubernetes" {
2341+
if insp.Oper.ClusterMode != master.Kubernetes {
23422342
t.Fatalf("Error expected kubernetes, got %s", insp.Oper.ClusterMode)
23432343
}
23442344

2345-
master.SetClusterMode("docker")
2345+
master.SetClusterMode(master.Docker)
23462346
insp, err = contivClient.GlobalInspect("global")
23472347
if err != nil {
23482348
t.Fatalf("Error inspecting global %v", err)
23492349
}
2350-
if insp.Oper.ClusterMode != "docker" {
2350+
if insp.Oper.ClusterMode != master.Docker {
2351+
t.Fatalf("Error expected docker, got %s", insp.Oper.ClusterMode)
2352+
}
2353+
2354+
master.SetClusterMode(master.SwarmMode)
2355+
insp, err = contivClient.GlobalInspect("global")
2356+
if err != nil {
2357+
t.Fatalf("Error inspecting global %v", err)
2358+
}
2359+
if insp.Oper.ClusterMode != master.SwarmMode {
23512360
t.Fatalf("Error expected docker, got %s", insp.Oper.ClusterMode)
23522361
}
23532362
}

netplugin/agent/agent.go

+10-8
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import (
2525
"github.com/contiv/netplugin/mgmtfn/dockplugin"
2626
"github.com/contiv/netplugin/mgmtfn/k8splugin"
2727
"github.com/contiv/netplugin/mgmtfn/mesosplugin"
28+
"github.com/contiv/netplugin/netmaster/master"
2829
"github.com/contiv/netplugin/netmaster/mastercfg"
2930
"github.com/contiv/netplugin/netplugin/cluster"
3031
"github.com/contiv/netplugin/netplugin/plugin"
@@ -62,18 +63,19 @@ func NewAgent(pluginConfig *plugin.Config) *Agent {
6263

6364
// Initialize appropriate plugin
6465
switch opts.PluginMode {
65-
case "swarm-mode":
66+
case master.SwarmMode:
6667
fallthrough
67-
case "docker":
68+
case master.Docker:
6869
dockplugin.InitDockPlugin(netPlugin, opts.PluginMode)
6970

70-
case "kubernetes":
71+
case master.Kubernetes:
7172
k8splugin.InitCNIServer(netPlugin)
7273

73-
case "test":
74+
case master.Test:
7475
// nothing to do. internal mode for testing
7576
default:
76-
log.Fatalf("Unknown plugin mode -- should be docker | swarm-mode | kubernetes")
77+
log.Fatalf("Unknown plugin mode -- should be %s | %s | %s",
78+
master.Docker, master.SwarmMode, master.Kubernetes)
7779
}
7880
// init mesos plugin
7981
mesosplugin.InitPlugin(netPlugin)
@@ -222,10 +224,10 @@ func (ag *Agent) HandleEvents() error {
222224

223225
go handlePolicyRuleEvents(ag.netPlugin, opts, recvErr)
224226

225-
if ag.pluginConfig.Instance.PluginMode == "docker" ||
226-
ag.pluginConfig.Instance.PluginMode == "swarm-mode" {
227+
if ag.pluginConfig.Instance.PluginMode == master.Docker ||
228+
ag.pluginConfig.Instance.PluginMode == master.SwarmMode {
227229
go ag.monitorDockerEvents(recvErr)
228-
} else if ag.pluginConfig.Instance.PluginMode == "kubernetes" {
230+
} else if ag.pluginConfig.Instance.PluginMode == master.Kubernetes {
229231
// start watching kubernetes events
230232
k8splugin.InitKubServiceWatch(ag.netPlugin)
231233
}

netplugin/netd.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ func (s *StringSlice) Value() []string {
6666

6767
type cliOpts struct {
6868
hostLabel string
69-
pluginMode string // plugin could be docker | kubernetes
69+
pluginMode string // plugin could be docker | kubernetes | swarm-mode
7070
cfgFile string
7171
debug bool
7272
syslog string
@@ -137,7 +137,7 @@ func main() {
137137
flagSet.StringVar(&opts.pluginMode,
138138
"plugin-mode",
139139
"docker",
140-
"plugin mode docker|kubernetes")
140+
"plugin mode docker|kubernetes|swarm-mode")
141141
flagSet.StringVar(&opts.cfgFile,
142142
"config",
143143
"",

0 commit comments

Comments
 (0)