Skip to content

Commit 7d8f10d

Browse files
author
Vipin Jain
committed
incremental add/delete of json config
1 parent 0903c39 commit 7d8f10d

File tree

5 files changed

+209
-62
lines changed

5 files changed

+209
-62
lines changed

core/error.go

+10
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,20 @@ limitations under the License.
1515

1616
package core
1717

18+
import "strings"
19+
1820
type Error struct {
1921
Desc string
2022
}
2123

2224
func (e *Error) Error() string {
2325
return e.Desc
2426
}
27+
28+
func ErrIfKeyExists(err error) error {
29+
if err == nil || strings.Contains(err.Error(), "Key not found") {
30+
return nil
31+
} else {
32+
return err
33+
}
34+
}

drivers/ovsdriver.go

+2-10
Original file line numberDiff line numberDiff line change
@@ -527,14 +527,6 @@ func (d *OvsDriver) CreateNetwork(id string) error {
527527
return nil
528528
}
529529

530-
func errIfKeyExists(err error) error {
531-
if strings.Contains(err.Error(), "Key not found") {
532-
return nil
533-
} else {
534-
return err
535-
}
536-
}
537-
538530
func (d *OvsDriver) DeleteNetwork(value string) error {
539531
var err error
540532
var gOper gstate.Oper
@@ -549,7 +541,7 @@ func (d *OvsDriver) DeleteNetwork(value string) error {
549541
operNwState := OvsOperNetworkState{StateDriver: d.stateDriver}
550542
err = operNwState.Read(cfgNetState.Id)
551543
if err != nil {
552-
return errIfKeyExists(err)
544+
return core.ErrIfKeyExists(err)
553545
}
554546

555547
err = gOper.Read(d.stateDriver, operNwState.Tenant)
@@ -578,7 +570,7 @@ func (d *OvsDriver) DeleteNetwork(value string) error {
578570

579571
err = operNwState.Clear()
580572
if err != nil {
581-
return errIfKeyExists(err)
573+
return core.ErrIfKeyExists(err)
582574
}
583575

584576
return nil
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
2+
{
3+
"Tenants" : [ {
4+
"Name" : "tenant-one",
5+
"Networks" : [
6+
{
7+
"Name" : "orange",
8+
"Endpoints" : [
9+
{
10+
"Container" : "myContainer2",
11+
"Host" : "host1"
12+
}
13+
]
14+
}
15+
]
16+
} ]
17+
}

netdcli/cfg.go

+167-49
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,10 @@ func getEpName(net *ConfigNetworkJson, ep *ConfigEpJson) string {
6969
}
7070
}
7171

72+
func postProcessing() {
73+
time.Sleep(1 * time.Second)
74+
}
75+
7276
func tenantPresent(allCfg *ConfigJson, tenantId string) bool {
7377
for _, tenant := range allCfg.Tenants {
7478
if tenantId == tenant.Name {
@@ -105,20 +109,25 @@ func epPresent(allCfg *ConfigJson, epId string) bool {
105109
return false
106110
}
107111

108-
func deleteDelta(allCfg *ConfigJson, defOpts *cliOpts) error {
109-
112+
func initEtcd(defOpts *cliOpts) (*drivers.EtcdStateDriver, error) {
110113
etcdDriver := &drivers.EtcdStateDriver{}
111114
driverConfig := &drivers.EtcdStateDriverConfig{}
112115
driverConfig.Etcd.Machines = []string{defOpts.etcdUrl}
113116
config := &core.Config{V: driverConfig}
114117
err := etcdDriver.Init(config)
118+
return etcdDriver, err
119+
}
120+
121+
func deleteDelta(allCfg *ConfigJson, defOpts *cliOpts) error {
122+
123+
etcdDriver, err := initEtcd(defOpts)
115124
if err != nil {
116125
log.Fatalf("Failed to init etcd driver. Error: %s", err)
117126
}
118127

119128
keys, err := etcdDriver.ReadRecursive(drivers.EP_CFG_PATH_PREFIX)
120129
if err != nil {
121-
return err
130+
return core.ErrIfKeyExists(err)
122131
}
123132
for _, key := range keys {
124133
epId := strings.TrimPrefix(key, drivers.EP_CFG_PATH_PREFIX)
@@ -133,7 +142,7 @@ func deleteDelta(allCfg *ConfigJson, defOpts *cliOpts) error {
133142
if err != nil {
134143
log.Printf("error '%s' deleting ep %s \n", err, epId)
135144
}
136-
time.Sleep(1 * time.Second)
145+
postProcessing()
137146
}
138147
}
139148

@@ -154,7 +163,7 @@ func deleteDelta(allCfg *ConfigJson, defOpts *cliOpts) error {
154163
if err != nil {
155164
log.Printf("error '%s' deleting net %s \n", err, netId)
156165
}
157-
time.Sleep(1 * time.Second)
166+
postProcessing()
158167
}
159168
}
160169

@@ -175,64 +184,84 @@ func deleteDelta(allCfg *ConfigJson, defOpts *cliOpts) error {
175184
if err != nil {
176185
log.Printf("error '%s' deleting tenant %s \n", err, tenantId)
177186
}
178-
time.Sleep(1 * time.Second)
187+
postProcessing()
179188
}
180189
}
181190

182191
return nil
183192
}
184193

185-
func executeJsonCfg(defOpts *cliOpts) error {
186-
data, err := ioutil.ReadFile(opts.idStr)
187-
if err != nil {
188-
return err
189-
}
190-
191-
allCfg := &ConfigJson{}
192-
err = json.Unmarshal(data, allCfg)
194+
func processAdditions(allCfg *ConfigJson, defOpts *cliOpts) (err error) {
195+
etcdDriver, err := initEtcd(defOpts)
193196
if err != nil {
194-
log.Printf("unmarshal error '%s', tenants %v \n", err, allCfg)
195-
return err
197+
log.Fatalf("Failed to init etcd driver. Error: %s", err)
196198
}
197-
// log.Printf("parsed config %v \n", allCfg)
198-
199-
deleteDelta(allCfg, defOpts)
200199

201200
for _, tenant := range allCfg.Tenants {
202-
opts := *defOpts
203-
opts.construct.Set(CLI_CONSTRUCT_GLOBAL)
204-
opts.oper.Set(CLI_OPER_CREATE)
205-
opts.tenant = tenant.Name
206-
opts.pktTagType = tenant.DefaultNetType
207-
opts.subnetCidr = tenant.SubnetPool
208-
opts.allocSubnetLen = tenant.AllocSubnetLen
209-
opts.vlans = tenant.Vlans
210-
opts.vxlans = tenant.Vxlans
211-
212-
log.Printf("creating tenant %s \n", opts.tenant)
213-
err = executeOpts(&opts)
214-
if err != nil {
215-
log.Printf("error pushing global config state: %s \n", err)
216-
return err
201+
addTenant := true
202+
if defOpts.cfgAdditions && len(tenant.Networks) != 0 {
203+
gcfg := gstate.Cfg{}
204+
err = gcfg.Read(etcdDriver, tenant.Name)
205+
if core.ErrIfKeyExists(err) != nil {
206+
log.Fatalf("error reading the tenant %s , err '%s'\n",
207+
tenant, err)
208+
}
209+
if err == nil {
210+
addTenant = false
211+
}
217212
}
218213

219-
for _, net := range tenant.Networks {
220-
opts = *defOpts
221-
222-
opts.construct.Set(CLI_CONSTRUCT_NW)
214+
if addTenant {
215+
opts := *defOpts
216+
opts.construct.Set(CLI_CONSTRUCT_GLOBAL)
223217
opts.oper.Set(CLI_OPER_CREATE)
224218
opts.tenant = tenant.Name
225-
opts.idStr = net.Name
226-
if net.PktTag != "" {
227-
opts.pktTag = net.PktTag
228-
}
229-
log.Printf(" creating network %s \n", opts.idStr)
219+
opts.pktTagType = tenant.DefaultNetType
220+
opts.subnetCidr = tenant.SubnetPool
221+
opts.allocSubnetLen = tenant.AllocSubnetLen
222+
opts.vlans = tenant.Vlans
223+
opts.vxlans = tenant.Vxlans
224+
225+
log.Printf("creating tenant %s \n", opts.tenant)
230226
err = executeOpts(&opts)
231227
if err != nil {
232-
log.Printf("error pushing network config state: %s \n", err)
233-
return err
228+
log.Printf("error pushing global config state: %s \n", err)
229+
return
230+
}
231+
}
232+
233+
for _, net := range tenant.Networks {
234+
235+
addNetwork := true
236+
if defOpts.cfgAdditions && len(tenant.Networks) != 0 {
237+
nwCfg := &drivers.OvsCfgNetworkState{StateDriver: etcdDriver}
238+
err = nwCfg.Read(net.Name)
239+
if core.ErrIfKeyExists(err) != nil {
240+
log.Fatalf("error reading the net %s , err '%s'\n",
241+
net, err)
242+
}
243+
if err == nil {
244+
addNetwork = false
245+
}
246+
}
247+
248+
if addNetwork {
249+
opts = *defOpts
250+
opts.construct.Set(CLI_CONSTRUCT_NW)
251+
opts.oper.Set(CLI_OPER_CREATE)
252+
opts.tenant = tenant.Name
253+
opts.idStr = net.Name
254+
if net.PktTag != "" {
255+
opts.pktTag = net.PktTag
256+
}
257+
log.Printf(" creating network %s \n", opts.idStr)
258+
err = executeOpts(&opts)
259+
if err != nil {
260+
log.Printf("error pushing network config state: %s \n", err)
261+
return
262+
}
263+
postProcessing()
234264
}
235-
time.Sleep(1 * time.Second)
236265

237266
for _, ep := range net.Endpoints {
238267
opts = *defOpts
@@ -247,12 +276,101 @@ func executeJsonCfg(defOpts *cliOpts) error {
247276
err = executeOpts(&opts)
248277
if err != nil {
249278
log.Printf("error pushing ep config state: %s \n", err)
250-
return err
279+
return
251280
}
252-
time.Sleep(1 * time.Second)
281+
postProcessing()
253282
}
254283
}
255284
}
256285

257-
return err
286+
return
287+
}
288+
289+
func processDeletions(allCfg *ConfigJson, defOpts *cliOpts) (err error) {
290+
for _, tenant := range allCfg.Tenants {
291+
for _, net := range tenant.Networks {
292+
for _, ep := range net.Endpoints {
293+
opts = *defOpts
294+
opts.construct.Set(CLI_CONSTRUCT_EP)
295+
opts.oper.Set(CLI_OPER_DELETE)
296+
opts.idStr = getEpName(&net, &ep)
297+
opts.netId = net.Name
298+
opts.contName = ep.Container
299+
opts.homingHost = ep.Host
300+
opts.intfName = ep.Intf
301+
log.Printf("deleting ep %s \n", opts.idStr)
302+
err = executeOpts(&opts)
303+
if err != nil {
304+
log.Printf("error pushing ep config state: %s \n", err)
305+
return
306+
}
307+
postProcessing()
308+
}
309+
310+
if len(net.Endpoints) == 0 {
311+
opts = *defOpts
312+
opts.construct.Set(CLI_CONSTRUCT_NW)
313+
opts.oper.Set(CLI_OPER_DELETE)
314+
opts.tenant = tenant.Name
315+
opts.idStr = net.Name
316+
log.Printf("deleting network %s \n", opts.idStr)
317+
err = executeOpts(&opts)
318+
if err != nil {
319+
log.Printf("error pushing network config state: %s \n", err)
320+
return
321+
}
322+
postProcessing()
323+
}
324+
}
325+
326+
if len(tenant.Networks) == 0 {
327+
opts := *defOpts
328+
opts.construct.Set(CLI_CONSTRUCT_GLOBAL)
329+
opts.oper.Set(CLI_OPER_DELETE)
330+
opts.tenant = tenant.Name
331+
332+
log.Printf("deleting tenant %s \n", opts.tenant)
333+
err = executeOpts(&opts)
334+
if err != nil {
335+
log.Printf("error pushing global config state: %s \n", err)
336+
return
337+
}
338+
}
339+
}
340+
return
341+
}
342+
343+
func executeJsonCfg(defOpts *cliOpts) (err error) {
344+
data, err := ioutil.ReadFile(opts.idStr)
345+
if err != nil {
346+
return err
347+
}
348+
349+
allCfg := &ConfigJson{}
350+
err = json.Unmarshal(data, allCfg)
351+
if err != nil {
352+
log.Printf("unmarshal error '%s', tenants %v \n", err, allCfg)
353+
return
354+
}
355+
// log.Printf("parsed config %v \n", allCfg)
356+
357+
if defOpts.cfgDesired {
358+
err = deleteDelta(allCfg, defOpts)
359+
}
360+
if err != nil {
361+
log.Printf("error deleting delta '%s' \n", err)
362+
return
363+
}
364+
365+
if defOpts.cfgDeletions {
366+
err = processDeletions(allCfg, defOpts)
367+
} else {
368+
err = processAdditions(allCfg, defOpts)
369+
}
370+
if err != nil {
371+
log.Printf("error processing cfg '%s' \n", err)
372+
return
373+
}
374+
375+
return
258376
}

netdcli/netdcli.go

+13-3
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,9 @@ func (c *Construct) Get() interface{} {
105105

106106
type cliOpts struct {
107107
help bool
108-
cfgFile bool
108+
cfgDesired bool
109+
cfgAdditions bool
110+
cfgDeletions bool
109111
oper Operation
110112
construct Construct
111113
etcdUrl string
@@ -139,7 +141,15 @@ func init() {
139141
flagSet.Var(&opts.construct,
140142
"construct",
141143
"Construct to operate on i.e network or endpoint")
142-
flagSet.BoolVar(&opts.cfgFile,
144+
flagSet.BoolVar(&opts.cfgAdditions,
145+
"add-cfg",
146+
false,
147+
"Json file describing addition to global and network intent")
148+
flagSet.BoolVar(&opts.cfgDeletions,
149+
"del-cfg",
150+
false,
151+
"Json file describing deletion from global and network intent")
152+
flagSet.BoolVar(&opts.cfgDesired,
143153
"cfg",
144154
false,
145155
"Json file describing the global and network intent")
@@ -458,7 +468,7 @@ func main() {
458468
}
459469
opts.idStr = flagSet.Arg(0)
460470

461-
if opts.cfgFile {
471+
if opts.cfgDesired || opts.cfgDeletions || opts.cfgAdditions {
462472
err = executeJsonCfg(&opts)
463473
} else {
464474
err = executeOpts(&opts)

0 commit comments

Comments
 (0)