Skip to content

Commit 0d0f40b

Browse files
committed
Added support for pre_dbe_delete and pre_dbe_create
partial-jira-bug: CEM-15158 1. Added support for pre_dbe_delete 2. Added support for pre_dbe_create 3. For #1, updated deallocation logic 4. Added UT for both cases
1 parent d063612 commit 0d0f40b

File tree

2 files changed

+1216
-19
lines changed

2 files changed

+1216
-19
lines changed

src/config/api-server/vnc_cfg_api_server/resources/virtual_port_group.py

Lines changed: 79 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ def _dealloc_ae_id(cls, prouter_name, ae_id, vpg_name):
6060
return dealloc_dict
6161

6262
@classmethod
63-
def _process_alloc_ae_id(cls, obj_dict, db_obj_dict, vpg_name):
63+
def _process_alloc_ae_id(cls, db_obj_dict, vpg_name, obj_dict=None):
6464
attr_dict = None
6565
alloc_dealloc_dict = {'allocated_ae_id': [], 'deallocated_ae_id': []}
6666
alloc_list = []
@@ -70,7 +70,9 @@ def _process_alloc_ae_id(cls, obj_dict, db_obj_dict, vpg_name):
7070
db_pi_dict = {}
7171
db_pr_dict = {}
7272
extra_deallocate_dict = {}
73-
vpg_uuid = obj_dict['uuid']
73+
vpg_uuid = db_obj_dict['uuid']
74+
if not obj_dict:
75+
obj_dict = {}
7476

7577
# process incoming PIs
7678
for ref in obj_dict.get('physical_interface_refs') or []:
@@ -95,7 +97,7 @@ def _process_alloc_ae_id(cls, obj_dict, db_obj_dict, vpg_name):
9597
return True, (attr_dict, alloc_dealloc_dict)
9698

9799
# nothing to delete, because rest of PIs shares same PR
98-
if (len(create_pi_uuids) == 0 and len(delete_pi_uuids) >= 1 and
100+
if (len(create_pi_uuids) == 0 and len(delete_pi_uuids) == 1 and
99101
len(db_pr_dict.keys()) == 1 and len(db_pi_dict.keys()) > 2):
100102
return True, (attr_dict, alloc_dealloc_dict)
101103

@@ -108,42 +110,86 @@ def _process_alloc_ae_id(cls, obj_dict, db_obj_dict, vpg_name):
108110
# allocate
109111
attr_dict, _alloc_dict = cls._alloc_ae_id(pi_pr, vpg_name)
110112
alloc_dealloc_dict['allocated_ae_id'].append(_alloc_dict)
113+
msg = "Allocating AE-ID(%s) for PI(%s) at VPG(%s)/PR(%s)" % (
114+
attr_dict, pi_uuid, vpg_name, pi_pr)
115+
cls.db_conn.config_log(msg, level=SandeshLevel.SYS_INFO)
111116
else:
112117
attr_dict = pi_ae
113118

114119
# re-allocate existing single PI if any
115120
if (len(db_pi_dict.keys()) == 1 and len(create_pi_uuids) == 1):
116121
db_pi_uuid = db_pi_dict.keys()[0]
117-
if (db_pi_dict.values()[0] != curr_pi_dict.values()[0]):
122+
if (db_pi_dict.values()[0] != curr_pi_dict.get(create_pi_uuids[0])):
118123
# allocate a new ae-id as it belongs to different PR
119124
db_pr = db_pi_dict.values()[0]
120-
attr_dict, _alloc_dict = cls._alloc_ae_id(db_pr, vpg_name)
125+
attr_dict_leftover_pi, _alloc_dict = cls._alloc_ae_id(db_pr, vpg_name)
121126
alloc_dealloc_dict['allocated_ae_id'].append(_alloc_dict)
127+
msg = "Allocating AE-ID(%s) for PI(%s) at VPG(%s)/PR(%s)" % (
128+
attr_dict_leftover_pi, db_pi_uuid, vpg_name, db_pr)
129+
cls.db_conn.config_log(msg, level=SandeshLevel.SYS_INFO)
130+
else:
131+
attr_dict_leftover_pi = attr_dict
132+
msg = "Re-using AE-ID(%s) for PI(%s) at VPG(%s)/PR(%s)" % (
133+
attr_dict_leftover_pi, db_pi_uuid, vpg_name, pi_pr)
134+
cls.db_conn.config_log(msg, level=SandeshLevel.SYS_INFO)
122135
(ok, result) = cls.db_conn.ref_update(
123136
'virtual_port_group',
124137
vpg_uuid,
125138
'physical_interface',
126139
db_pi_uuid,
127-
{'attr': attr_dict},
140+
{'attr': attr_dict_leftover_pi},
128141
'ADD',
129142
db_obj_dict.get('id_perms'),
130143
attr_to_publish=None,
131144
relax_ref_for_delete=True)
145+
msg = "Updated AE-ID(%s) in PI(%s) ref to VPG(%s)" % (
146+
attr_dict_leftover_pi, db_pi_uuid, vpg_name)
147+
cls.db_conn.config_log(msg, level=SandeshLevel.SYS_INFO)
132148

133149
# deallocate case
150+
_in_dealloc_list = []
134151
for pi_uuid in delete_pi_uuids:
135152
pi_pr = db_pi_dict.get(pi_uuid)
136153
pi_ae = db_pr_dict.get(pi_pr)
137-
if pi_ae is not None:
154+
db_pi_prs = db_pi_dict.values().count(pi_pr)
155+
# PR/VPG is already considered for deallocation, so no need
156+
# to dealloc again
157+
if '%s:%s' % (pi_pr, vpg_name) in _in_dealloc_list:
158+
continue
159+
if (pi_ae is not None and (db_pi_prs < 2 or
160+
len(delete_pi_uuids) > 1)):
138161
ae_id = pi_ae.get('ae_num')
139162
# de-allocate
140163
_dealloc_dict = cls._dealloc_ae_id(pi_pr, ae_id, vpg_name)
141164
alloc_dealloc_dict['deallocated_ae_id'].append(_dealloc_dict)
165+
# record deallocated pr/vpg
166+
_in_dealloc_list.append('%s:%s' % (pi_pr, vpg_name))
167+
msg = "Deallocated AE-ID(%s) for PI(%s) at VPG(%s)/PR(%s)" % (
168+
ae_id, pi_uuid, vpg_name, pi_pr)
169+
cls.db_conn.config_log(msg, level=SandeshLevel.SYS_INFO)
142170

143171
# de-allocate leftover single PI, if any
172+
# in delete case, whatever comes in curr_pi_dict are the
173+
# leftovers because for delete refs, ref to be deleted
174+
# will not be coming in payload
144175
if (len(curr_pi_dict.keys()) == 1 and
145176
len(db_pi_dict.keys()) == len(delete_pi_uuids) + 1):
146177
pi_uuid = curr_pi_dict.keys()[0]
178+
pi_pr = curr_pi_dict.get(pi_uuid)
179+
pi_ae = curr_pr_dict.get(pi_pr)
180+
if '%s:%s' % (pi_pr, vpg_name) not in _in_dealloc_list:
181+
if pi_ae is not None:
182+
ae_id = pi_ae.get('ae_num')
183+
_dealloc_dict = cls._dealloc_ae_id(pi_pr, ae_id, vpg_name)
184+
alloc_dealloc_dict['deallocated_ae_id'].append(
185+
_dealloc_dict)
186+
# record deallocated pr/vpg
187+
_in_dealloc_list.append('%s:%s' % (pi_pr, vpg_name))
188+
msg = ("Deallocated AE-ID(%s) from leftover PI(%s) at "
189+
"VPG(%s)/PR(%s)" % (
190+
ae_id, pi_uuid, vpg_name, pi_pr))
191+
cls.db_conn.config_log(msg, level=SandeshLevel.SYS_INFO)
192+
pi_ae = db_pr_dict.get(pi_pr)
147193
(ok, result) = cls.db_conn.ref_update(
148194
'virtual_port_group',
149195
vpg_uuid,
@@ -253,13 +299,24 @@ def update_physical_intf_type(cls, obj_dict=None,
253299

254300
@classmethod
255301
def pre_dbe_create(cls, tenant_name, obj_dict, db_conn):
302+
ret_val = ''
256303
if ('vpg-internal' in obj_dict['fq_name'][2] and
257304
obj_dict.get('virtual_port_group_user_created', True)):
258305
msg = "Virtual port group(%s) with name vpg-internal as prefix "\
259306
"can only be created internally"\
260307
% (obj_dict['uuid'])
261308
return False, (400, msg)
262309

310+
# when PI refs are added to VPG object during create VPG.
311+
# stateful_create do not allow us to allocate AE-ID and
312+
# update them in PI object refs
313+
if obj_dict.get('physical_interface_refs'):
314+
msg = ("API Infra do not support allocating AE-ID when "
315+
"Physical Interface refs are sent in VPG create request. "
316+
"Workaround: Create VPG first, then add Physical "
317+
"Interface to VPG")
318+
return False, (400, msg)
319+
263320
if obj_dict.get('virtual_port_group_trunk_port_id'):
264321
primary_vmi_id = obj_dict.get('virtual_port_group_trunk_port_id')
265322
ok, result = db_conn.dbe_read(
@@ -282,7 +339,7 @@ def pre_dbe_create(cls, tenant_name, obj_dict, db_conn):
282339
if not ok:
283340
return ok, result
284341

285-
return True, ''
342+
return True, ret_val
286343

287344
@classmethod
288345
def pre_dbe_update(cls, id, fq_name, obj_dict, db_conn, **kwargs):
@@ -302,21 +359,19 @@ def pre_dbe_update(cls, id, fq_name, obj_dict, db_conn, **kwargs):
302359
ok, res = cls.update_physical_intf_type(obj_dict, db_obj_dict)
303360
if not ok:
304361
return ok, res
305-
306-
ok, res = cls._process_alloc_ae_id(obj_dict, db_obj_dict, fq_name[-1])
362+
ok, res = cls._process_alloc_ae_id(db_obj_dict, fq_name[-1], obj_dict)
307363
if not ok:
308364
return ok, res
309-
else:
310-
obj_dict.update(res[1])
311-
if res[0] and kwargs.get('ref_args'):
312-
kwargs['ref_args']['data']['attr'] = res[0]
313-
ret_val = obj_dict
365+
if res[0] and kwargs.get('ref_args'):
366+
kwargs['ref_args']['data']['attr'] = res[0]
367+
ret_val = res[1]
314368

315369
return True, ret_val
316370
# end pre_dbe_update
317371

318372
@classmethod
319373
def pre_dbe_delete(cls, id, obj_dict, db_conn):
374+
ret_val = ''
320375
# If the user deletes VPG, make sure that all the referring
321376
# VMIs are deleted.
322377
if obj_dict.get('virtual_machine_interface_refs'):
@@ -329,7 +384,15 @@ def pre_dbe_delete(cls, id, obj_dict, db_conn):
329384
if not ok:
330385
return (False, result, None)
331386

332-
return True, '', None
387+
if obj_dict.get('physical_interface_refs'):
388+
# release ae-ids associated with PIs attached to this VPG
389+
fq_name = obj_dict.get('fq_name')
390+
ok, res = cls._process_alloc_ae_id(obj_dict, fq_name[-1])
391+
if not ok:
392+
return (ok, res, None)
393+
ret_val = res[1]
394+
395+
return True, ret_val, None
333396

334397
@classmethod
335398
def post_dbe_delete(cls, id, obj_dict, db_conn):

0 commit comments

Comments
 (0)