Skip to content

Commit

Permalink
Merge "Config check for bridge domain creation and VMI linking"
Browse files Browse the repository at this point in the history
  • Loading branch information
Zuul authored and opencontrail-ci-admin committed Feb 21, 2017
2 parents eaefadb + 4440a83 commit d8b086d
Show file tree
Hide file tree
Showing 2 changed files with 120 additions and 21 deletions.
94 changes: 77 additions & 17 deletions src/config/api-server/tests/test_crud_basic.py
Original file line number Diff line number Diff line change
Expand Up @@ -416,7 +416,7 @@ def test_physical_router_credentials(self):
raise Exception("ERROR: physical-router: password should be hidden")
#end test_physical_router_credentials

def test_bridge_domain_with_vmi_ref_multiple_bd(self):
def test_bridge_domain_with_multiple_bd_in_vn(self):
vn1_name = self.id() + '-vn-1'
vn1 = VirtualNetwork(vn1_name)
logger.info('Creating VN %s', vn1_name)
Expand All @@ -438,25 +438,85 @@ def test_bridge_domain_with_vmi_ref_multiple_bd(self):
bd2 = BridgeDomain(bd2_name, parent_obj=vn1)
bd2.set_isid(300300)
logger.info('Creating Bridge Domain %s', bd2_name)
self._vnc_lib.bridge_domain_create(bd2)
with ExpectedException(BadRequest) as e:
self._vnc_lib.bridge_domain_create(bd2)
# end test_bridge_domain_with_multiple_bd_in_vn

def test_bridge_domain_link_vmi_and_bd_in_different_vn(self):
vn1_name = self.id() + '-vn-1'
vn1 = VirtualNetwork(vn1_name)
logger.info('Creating VN %s', vn1_name)
self._vnc_lib.virtual_network_create(vn1)

vn2_name = self.id() + '-vn-2'
vn2 = VirtualNetwork(vn2_name)
logger.info('Creating VN %s', vn2_name)
self._vnc_lib.virtual_network_create(vn2)

vmi1_name = self.id() + '-port-1'
logger.info('Creating port %s', vmi1_name)
vmi1 = VirtualMachineInterface(vmi1_name, parent_obj=Project())
vmi1.add_virtual_network(vn1)
self._vnc_lib.virtual_machine_interface_create(vmi1)

bd_ref_data1 = BridgeDomainMembershipType();
bd_ref_data1.set_vlan_tag(0);
vmi2_name = self.id() + '-port-2'
logger.info('Creating port %s', vmi2_name)
vmi2 = VirtualMachineInterface(vmi2_name, parent_obj=Project())
vmi2.add_virtual_network(vn2)
self._vnc_lib.virtual_machine_interface_create(vmi2)

bd1_name = self.id() + '-bd-1'
bd1 = BridgeDomain(bd1_name, parent_obj=vn1)
bd1.set_isid(200200)
logger.info('Creating Bridge Domain %s', bd1_name)
self._vnc_lib.bridge_domain_create(bd1)

# VMI is referring to two bridge domain(bd1 and bd2) for vlan tag = 0
vmi.add_bridge_domain(bd1, bd_ref_data1);
vmi.add_bridge_domain(bd2, bd_ref_data1);
bd_ref_data1 = BridgeDomainMembershipType(vlan_tag=0)
vmi2.add_bridge_domain(bd1, bd_ref_data1)
with ExpectedException(BadRequest) as e:
self._vnc_lib.virtual_machine_interface_update(vmi)

# Link the VMI to two bridge domain for different vlan tags(0, 1)
vmi_obj = self._vnc_lib.virtual_machine_interface_read(id=vmi.uuid)
bd_ref_data1 = BridgeDomainMembershipType(vlan_tag=1);
bd_ref_data2 = BridgeDomainMembershipType(vlan_tag=2);
vmi_obj.add_bridge_domain(bd1, bd_ref_data1);
vmi_obj.add_bridge_domain(bd2, bd_ref_data2);
self._vnc_lib.virtual_machine_interface_update(vmi_obj)
# end test_bridge_domain_with_vmi_ref_multiple_bd
self._vnc_lib.virtual_machine_interface_update(vmi2)

bd_ref_data2 = BridgeDomainMembershipType(vlan_tag=0)
vmi1.add_bridge_domain(bd1, bd_ref_data2)
self._vnc_lib.virtual_machine_interface_update(vmi1)
# end test_bridge_domain_link_vmi_and_bd_in_different_vn

def test_bridge_domain_delete_vn_ref_with_bd_link(self):
vn1_name = self.id() + '-vn-1'
vn1 = VirtualNetwork(vn1_name)
logger.info('Creating VN %s', vn1_name)
self._vnc_lib.virtual_network_create(vn1)

vmi_name = self.id() + '-port'
logger.info('Creating port %s', vmi_name)
vmi = VirtualMachineInterface(vmi_name, parent_obj=Project())
vmi.add_virtual_network(vn1)
self._vnc_lib.virtual_machine_interface_create(vmi)

bd1_name = self.id() + '-bd-1'
bd1 = BridgeDomain(bd1_name, parent_obj=vn1)
bd1.set_isid(200200)
logger.info('Creating Bridge Domain %s', bd1_name)
self._vnc_lib.bridge_domain_create(bd1)

bd_ref_data = BridgeDomainMembershipType(vlan_tag=0)
vmi.add_bridge_domain(bd1, bd_ref_data)
self._vnc_lib.virtual_machine_interface_update(vmi)

# Try to delete the VN link with BD ref
vmi_temp = vmi
vmi_temp.del_virtual_network(vn1)
with ExpectedException(BadRequest) as e:
self._vnc_lib.virtual_machine_interface_update(vmi_temp)

# Delete the BD ref
vmi.del_bridge_domain(bd1)
self._vnc_lib.virtual_machine_interface_update(vmi)

vmi.del_virtual_network(vn1)
self._vnc_lib.virtual_machine_interface_update(vmi)
# end test_bridge_domain_with_multiple_bd_in_vn


# end class TestCrud

Expand Down
47 changes: 43 additions & 4 deletions src/config/api-server/vnc_cfg_types.py
Original file line number Diff line number Diff line change
Expand Up @@ -777,12 +777,29 @@ def _check_vrouter_link(cls, vmi_data, kvp_dict, obj_dict, db_conn):
# end _check_vrouter_link

@classmethod
def _check_bridge_domain_vmi_association(cls, obj_dict,
db_conn, create):
def _check_bridge_domain_vmi_association(cls, obj_dict, db_conn, vn_uuid,
create):
vn_fq_name = []
if vn_uuid:
vn_fq_name = db_conn.uuid_to_fq_name(vn_uuid)

bridge_domain_links = {}
bd_refs = obj_dict.get('bridge_domain_refs') or []

vn_refs = obj_dict.get('virtual_network_refs') or []
if len(vn_refs) == 0 and len(bd_refs):
msg = "Virtual network can not be updated on virtual machine "\
"interface(%s) while it refers a bridge domain"\
%(obj_dict['uuid'])
return (False, msg)

for bd in bd_refs:
bd_fq_name = bd['to']
if bd_fq_name[0:3] != vn_fq_name:
msg = "Virtual machine interface(%s) can only refer to bridge "\
"domain belonging to virtual network(%s)"\
%(obj_dict['uuid'], vn_uuid)
return (False, msg)
bd_uuid = bd.get('uuid')
if not bd_uuid:
bd_uuid = db_conn.fq_name_to_uuid('bridge_domain', bd_fq_name)
Expand Down Expand Up @@ -820,7 +837,7 @@ def pre_dbe_create(cls, tenant_name, obj_dict, db_conn):
vn_dict = result

(ok, error) = cls._check_bridge_domain_vmi_association(obj_dict,
db_conn, True)
db_conn, vn_uuid, True)
if not ok:
return (False, (400, error))

Expand Down Expand Up @@ -911,8 +928,11 @@ def pre_dbe_update(cls, id, fq_name, obj_dict, db_conn,
if not ok:
return ok, read_result

vn_uuid = None
if 'virtual_network_refs' in read_result:
vn_uuid = read_result['virtual_network_refs'][0].get('uuid')
(ok, error) = cls._check_bridge_domain_vmi_association(obj_dict,
db_conn, False)
db_conn, vn_uuid, False)
if not ok:
return (False, (400, error))

Expand Down Expand Up @@ -1005,6 +1025,25 @@ def pre_dbe_update(cls, id, fq_name, obj_dict, db_conn, **kwargs):
# end pre_dbe_update
# end class ServiceApplianceSetServer


class BridgeDomainServer(Resource, BridgeDomain):
@classmethod
def pre_dbe_create(cls, tenant_name, obj_dict, db_conn):
vn_uuid = obj_dict.get('parent_uuid')
if vn_uuid is None:
vn_uuid = db_conn.fq_name_to_uuid('virtual_network', obj_dict['fq_name'][0:3])
ok, result = cls.dbe_read(db_conn, 'virtual_network', vn_uuid, obj_fields=['bridge_domains'])
if not ok:
return ok, result
if 'bridge_domains' in result and len(result['bridge_domains']) == 1:
msg = "Virtual network(%s) can have only one bridge domain. Bridge"\
" domain(%s) is already created under this virtual network" %\
(vn_uuid, result['bridge_domains'][0]['uuid'])
return (False, (400, msg))
return True, ""
# end pre_dbe_create
# end class BridgeDomainServer

class VirtualNetworkServer(Resource, VirtualNetwork):

@classmethod
Expand Down

0 comments on commit d8b086d

Please sign in to comment.