Skip to content

Commit 2c98dd4

Browse files
committed
global setting resize capability
1 parent aa46cf1 commit 2c98dd4

13 files changed

+481
-29
lines changed

core/core.go

+2
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,7 @@ type Resource interface {
183183
State
184184
Init(rsrcCfg interface{}) error
185185
Deinit()
186+
Reinit(rsrcCfg interface{}) error
186187
Description() string
187188
GetList() (uint, string)
188189
Allocate(interface{}) (interface{}, error)
@@ -196,6 +197,7 @@ type ResourceManager interface {
196197
Init() error
197198
Deinit()
198199
DefineResource(id, desc string, rsrcCfg interface{}) error
200+
RedefineResource(id, desc string, rsrcCfg interface{}) error
199201
UndefineResource(id, desc string) error
200202
GetResourceList(id, desc string) (uint, string)
201203
AllocateResourceVal(id, desc string, reqValue interface{}) (interface{}, error)

netmaster/gstate/gstate.go

+98-9
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ package gstate
1818
import (
1919
"encoding/json"
2020
"errors"
21+
"strconv"
22+
"strings"
23+
"sync"
2124

2225
"github.com/jainvipin/bitset"
2326

@@ -37,6 +40,9 @@ const (
3740
vxlanLocalVlanRange = "1-4094"
3841
)
3942

43+
//GlobalMutex used to syncronize global configuration changes
44+
var GlobalMutex sync.Mutex
45+
4046
// AutoParams specifies various parameters for the auto allocation and resource
4147
// management for networks and endpoints. This allows for hands-free
4248
// allocation of resources without having to specify these each time these
@@ -149,15 +155,15 @@ func (g *Oper) Clear() error {
149155
return g.StateDriver.ClearState(key)
150156
}
151157

152-
func (gc *Cfg) initVXLANBitset(vxlans string) (*resources.AutoVXLANCfgResource, uint, error) {
158+
func (gc *Cfg) initVXLANBitset(vxlans string) (*resources.AutoVXLANCfgResource, error) {
153159

154160
vxlanRsrcCfg := &resources.AutoVXLANCfgResource{}
155161
vxlanRsrcCfg.VXLANs = netutils.CreateBitset(14)
156162

157163
vxlanRange := netutils.TagRange{}
158164
vxlanRanges, err := netutils.ParseTagRanges(vxlans, "vxlan")
159165
if err != nil {
160-
return nil, 0, err
166+
return nil, err
161167
}
162168
// XXX: REVISIT, we seem to accept one contiguous vxlan range
163169
vxlanRange = vxlanRanges[0]
@@ -169,11 +175,12 @@ func (gc *Cfg) initVXLANBitset(vxlans string) (*resources.AutoVXLANCfgResource,
169175

170176
// Initialize local vlan bitset
171177
vxlanRsrcCfg.LocalVLANs, err = gc.initVLANBitset(vxlanLocalVlanRange)
178+
vxlanRsrcCfg.FreeVXLANsStart = freeVXLANsStart
172179
if err != nil {
173-
return nil, 0, err
180+
return nil, err
174181
}
175182

176-
return vxlanRsrcCfg, freeVXLANsStart, nil
183+
return vxlanRsrcCfg, nil
177184
}
178185

179186
// GetVxlansInUse gets the vlans that are currently in use
@@ -339,11 +346,10 @@ func (gc *Cfg) Process(res string) error {
339346
}
340347
}
341348
// Only define a vxlan resource if a valid range was specified
342-
var freeVXLANsStart uint
343349
if res == "vxlan" {
350+
var vxlanRsrcCfg *resources.AutoVXLANCfgResource
344351
if gc.Auto.VXLANs != "" {
345-
var vxlanRsrcCfg *resources.AutoVXLANCfgResource
346-
vxlanRsrcCfg, freeVXLANsStart, err = gc.initVXLANBitset(gc.Auto.VXLANs)
352+
vxlanRsrcCfg, err = gc.initVXLANBitset(gc.Auto.VXLANs)
347353
if err != nil {
348354
return err
349355
}
@@ -353,7 +359,7 @@ func (gc *Cfg) Process(res string) error {
353359
}
354360
}
355361

356-
g := &Oper{FreeVXLANsStart: freeVXLANsStart}
362+
g := &Oper{FreeVXLANsStart: vxlanRsrcCfg.FreeVXLANsStart}
357363

358364
g.StateDriver = gc.StateDriver
359365
err = g.Write()
@@ -381,7 +387,6 @@ func (gc *Cfg) DeleteResources(res string) error {
381387
log.Errorf("Error deleting vlan resource. Err: %v", err)
382388
}
383389
} else if res == "vxlan" {
384-
385390
err = ra.UndefineResource("global", resources.AutoVXLANResource)
386391
if err != nil {
387392
log.Errorf("Error deleting vxlan resource. Err: %v", err)
@@ -390,6 +395,53 @@ func (gc *Cfg) DeleteResources(res string) error {
390395
return err
391396
}
392397

398+
// UpdateResources deletes associated resources
399+
func (gc *Cfg) UpdateResources(res string) error {
400+
log.Infof("Received update resource for res %s", res)
401+
tempRm, err := resources.GetStateResourceManager()
402+
if err != nil {
403+
return err
404+
}
405+
406+
ra := core.ResourceManager(tempRm)
407+
408+
err = gc.checkErrors(res)
409+
if err != nil {
410+
return core.Errorf("process failed on error checks %s", err)
411+
}
412+
413+
if res == "vlan" {
414+
var vlanRsrcCfg *bitset.BitSet
415+
vlanRsrcCfg, err = gc.initVLANBitset(gc.Auto.VLANs)
416+
if err != nil {
417+
return err
418+
}
419+
err = ra.RedefineResource("global", resources.AutoVLANResource, vlanRsrcCfg)
420+
if err != nil {
421+
log.Errorf("Error deleting vlan resource. Err: %v", err)
422+
}
423+
} else if res == "vxlan" {
424+
var vxlanRsrcCfg *resources.AutoVXLANCfgResource
425+
vxlanRsrcCfg, err = gc.initVXLANBitset(gc.Auto.VXLANs)
426+
if err != nil {
427+
return err
428+
}
429+
err = ra.RedefineResource("global", resources.AutoVXLANResource, vxlanRsrcCfg)
430+
if err != nil {
431+
log.Errorf("Error deleting vxlan resource. Err: %v", err)
432+
}
433+
g := &Oper{FreeVXLANsStart: vxlanRsrcCfg.FreeVXLANsStart}
434+
435+
g.StateDriver = gc.StateDriver
436+
err = g.Write()
437+
if err != nil {
438+
log.Errorf("error '%s' updating global oper state %v \n", err, g)
439+
return err
440+
}
441+
}
442+
return err
443+
}
444+
393445
// AssignDefaultNetwork assigns a default network for a tenant based on the configuration
394446
// in case configuration is absent it uses the provided network name to be the default
395447
// network. It records the default network in oper state (derived or configured)
@@ -436,3 +488,40 @@ func (gc *Cfg) UnassignNetwork(networkName string) error {
436488

437489
return nil
438490
}
491+
492+
//CheckInBitRange to check if range includes inuse vlans
493+
func (gc *Cfg) CheckInBitRange(ranges, inUse, pktTagType string) bool {
494+
495+
tags := strings.Split(inUse, ",")
496+
497+
if len(inUse) == 0 {
498+
return true
499+
}
500+
minUsed := 0
501+
maxUsed := 0
502+
if strings.Contains(tags[0], "-") {
503+
minUsed, _ = strconv.Atoi(strings.Split(tags[0], "-")[0])
504+
maxUsed, _ = strconv.Atoi(strings.Split(tags[0], "-")[1])
505+
} else {
506+
minUsed, _ = strconv.Atoi(tags[0])
507+
maxUsed = minUsed
508+
}
509+
510+
if len(inUse) > 1 {
511+
if strings.Contains(tags[len(tags)-1], "-") {
512+
maxUsed, _ = strconv.Atoi(strings.Split(tags[len(tags)-1], "-")[1])
513+
} else {
514+
maxUsed, _ = strconv.Atoi(strings.TrimSpace(tags[len(tags)-1]))
515+
}
516+
}
517+
518+
r, err := netutils.ParseTagRanges(ranges, pktTagType)
519+
if err != nil {
520+
return false
521+
}
522+
523+
if r[0].Min > minUsed || r[0].Max < maxUsed {
524+
return false
525+
}
526+
return true
527+
}

netmaster/master/endpointGroup.go

+4
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@ func CreateEndpointGroup(tenantName, networkName, groupName string) error {
4444
}
4545

4646
// Read global config
47+
gstate.GlobalMutex.Lock()
48+
defer gstate.GlobalMutex.Unlock()
4749
gCfg := gstate.Cfg{}
4850
gCfg.StateDriver = stateDriver
4951
err = gCfg.Read(tenantName)
@@ -153,6 +155,8 @@ func DeleteEndpointGroup(tenantName, groupName string) error {
153155
}
154156

155157
// Delete the endpoint group state
158+
gstate.GlobalMutex.Lock()
159+
defer gstate.GlobalMutex.Unlock()
156160
gCfg := gstate.Cfg{}
157161
gCfg.StateDriver = stateDriver
158162
err = gCfg.Read(epgCfg.TenantName)

netmaster/master/netmaster.go

+103-9
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ package master
1717

1818
import (
1919
"errors"
20+
"fmt"
2021

2122
"github.com/cenkalti/backoff"
2223
"github.com/contiv/netplugin/core"
@@ -123,6 +124,8 @@ func CreateGlobal(stateDriver core.StateDriver, gc *intent.ConfigGlobal) error {
123124
masterGc.StateDriver = stateDriver
124125
masterGc.Read("global")
125126

127+
gstate.GlobalMutex.Lock()
128+
defer gstate.GlobalMutex.Unlock()
126129
gCfg := &gstate.Cfg{}
127130
gCfg.StateDriver = stateDriver
128131
gCfg.Read("global")
@@ -159,11 +162,105 @@ func CreateGlobal(stateDriver core.StateDriver, gc *intent.ConfigGlobal) error {
159162
masterGc.FwdMode = gc.FwdMode
160163
}
161164

165+
if len(gcfgUpdateList) > 0 {
166+
// Delete old state
167+
168+
gOper := &gstate.Oper{}
169+
gOper.StateDriver = stateDriver
170+
err = gOper.Read("")
171+
if err == nil {
172+
for _, res := range gcfgUpdateList {
173+
err = gCfg.UpdateResources(res)
174+
if err != nil {
175+
return err
176+
}
177+
}
178+
} else {
179+
180+
for _, res := range gcfgUpdateList {
181+
// setup resources
182+
err = gCfg.Process(res)
183+
if err != nil {
184+
log.Errorf("Error updating the config %+v. Error: %s", gCfg, err)
185+
return err
186+
}
187+
}
188+
}
189+
190+
err = gCfg.Write()
191+
if err != nil {
192+
log.Errorf("error updating global config.Error: %s", err)
193+
return err
194+
}
195+
}
162196
err = masterGc.Write()
163197
if err != nil {
164198
return err
165199
}
166200

201+
return nil
202+
}
203+
204+
// UpdateGlobal updates the global state
205+
func UpdateGlobal(stateDriver core.StateDriver, gc *intent.ConfigGlobal) error {
206+
log.Infof("Received global update with intent {%v}", gc)
207+
var err error
208+
gcfgUpdateList := []string{}
209+
210+
masterGc := &mastercfg.GlobConfig{}
211+
masterGc.StateDriver = stateDriver
212+
masterGc.Read("global")
213+
214+
gstate.GlobalMutex.Lock()
215+
defer gstate.GlobalMutex.Unlock()
216+
217+
gCfg := &gstate.Cfg{}
218+
gCfg.StateDriver = stateDriver
219+
gCfg.Read("global")
220+
221+
_, vlansInUse := gCfg.GetVlansInUse()
222+
_, vxlansInUse := gCfg.GetVxlansInUse()
223+
224+
// check for valid values
225+
if gc.NwInfraType != "" {
226+
switch gc.NwInfraType {
227+
case "default", "aci", "aci-opflex":
228+
// These values are acceptable.
229+
default:
230+
return errors.New("Invalid fabric mode")
231+
}
232+
masterGc.NwInfraType = gc.NwInfraType
233+
}
234+
if gc.VLANs != "" {
235+
236+
if !gCfg.CheckInBitRange(gc.VLANs, vlansInUse, "vlan") {
237+
return fmt.Errorf("cannot update the vlan range due to existing vlans %s", vlansInUse)
238+
}
239+
_, err := netutils.ParseTagRanges(gc.VLANs, "vlan")
240+
if err != nil {
241+
return err
242+
}
243+
gCfg.Auto.VLANs = gc.VLANs
244+
gcfgUpdateList = append(gcfgUpdateList, "vlan")
245+
}
246+
247+
if gc.VXLANs != "" {
248+
if !gCfg.CheckInBitRange(gc.VXLANs, vxlansInUse, "vxlan") {
249+
return fmt.Errorf("cannot update the vxlan range due to existing vxlans %s", vxlansInUse)
250+
}
251+
252+
_, err = netutils.ParseTagRanges(gc.VXLANs, "vxlan")
253+
if err != nil {
254+
return err
255+
}
256+
gCfg.Auto.VXLANs = gc.VXLANs
257+
gcfgUpdateList = append(gcfgUpdateList, "vxlan")
258+
}
259+
260+
if gc.FwdMode != "" {
261+
masterGc.FwdMode = gc.FwdMode
262+
}
263+
167264
if len(gcfgUpdateList) > 0 {
168265
// Delete old state
169266

@@ -172,20 +269,12 @@ func CreateGlobal(stateDriver core.StateDriver, gc *intent.ConfigGlobal) error {
172269
err = gOper.Read("")
173270
if err == nil {
174271
for _, res := range gcfgUpdateList {
175-
err = gCfg.DeleteResources(res)
272+
err = gCfg.UpdateResources(res)
176273
if err != nil {
177274
return err
178275
}
179276
}
180277
}
181-
for _, res := range gcfgUpdateList {
182-
// setup resources
183-
err = gCfg.Process(res)
184-
if err != nil {
185-
log.Errorf("Error updating the config %+v. Error: %s", gCfg, err)
186-
return err
187-
}
188-
}
189278

190279
err = gCfg.Write()
191280
if err != nil {
@@ -194,6 +283,11 @@ func CreateGlobal(stateDriver core.StateDriver, gc *intent.ConfigGlobal) error {
194283
}
195284
}
196285

286+
err = masterGc.Write()
287+
if err != nil {
288+
return err
289+
}
290+
197291
return nil
198292
}
199293

netmaster/master/network.go

+4
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,8 @@ func validateNetworkConfig(tenant *intent.ConfigTenant) error {
7777
func CreateNetwork(network intent.ConfigNetwork, stateDriver core.StateDriver, tenantName string) error {
7878
var extPktTag, pktTag uint
7979

80+
gstate.GlobalMutex.Lock()
81+
defer gstate.GlobalMutex.Unlock()
8082
gCfg := gstate.Cfg{}
8183
gCfg.StateDriver = stateDriver
8284
err := gCfg.Read("")
@@ -447,6 +449,8 @@ func DeleteNetworkID(stateDriver core.StateDriver, netID string) error {
447449
}
448450
}
449451

452+
gstate.GlobalMutex.Lock()
453+
defer gstate.GlobalMutex.Unlock()
450454
gCfg := &gstate.Cfg{}
451455
gCfg.StateDriver = stateDriver
452456
err = gCfg.Read("")

0 commit comments

Comments
 (0)