Skip to content

Commit

Permalink
1. VMI attached to VM shouldn't be allowed to attach to a logical rou…
Browse files Browse the repository at this point in the history
…ter.

2. Check to make sure same network is not added as both internal interface
   and external network to a router
Change-Id: I0a492231ee2dea3ca0f8031100f5da60bc50eda3
Closes-Bug: 1473574
Closes-Bug: 1455583
  • Loading branch information
cijohnson committed Apr 21, 2016
1 parent 7e7f1c0 commit 85018e6
Show file tree
Hide file tree
Showing 2 changed files with 254 additions and 1 deletion.
180 changes: 179 additions & 1 deletion src/config/api-server/tests/test_logical_router.py
Original file line number Diff line number Diff line change
Expand Up @@ -382,8 +382,186 @@ def test_route_table_prefixes(self):
pass
#end test_route_table_prefixes

#end
def test_vm_port_not_added_to_lr(self):
logger.debug("*** test interface-add not allowing vm's port to be"
"attached to logical router ***")

# Create Domain
domain = Domain('my-lr-domain')
self._vnc_lib.domain_create(domain)
logger.debug('Created domain ')

# Create Project
project = Project('my-lr-proj', domain)
self._vnc_lib.project_create(project)
logger.debug('Created Project')

# Create NetworkIpam
ipam = NetworkIpam('default-network-ipam', project, IpamType("dhcp"))
self._vnc_lib.network_ipam_create(ipam)
logger.debug('Created network ipam')

ipam = self._vnc_lib.network_ipam_read(fq_name=['my-lr-domain', 'my-lr-proj',
'default-network-ipam'])
logger.debug('Read network ipam')

# Create subnets
ipam_sn_v4_vn = IpamSubnetType(subnet=SubnetType('11.1.1.0', 24))

# Create VN my-vn
vn = VirtualNetwork('my-vn', project)
vn.add_network_ipam(ipam, VnSubnetsType([ipam_sn_v4_vn]))
self._vnc_lib.virtual_network_create(vn)
logger.debug('Created Virtual Network object for my-vn: %s', vn.uuid)
net_obj = self._vnc_lib.virtual_network_read(id = vn.uuid)

# Create v4 Ip object
ip_obj = InstanceIp(name=str(uuid.uuid4()), instance_ip_family='v4')
ip_obj.uuid = ip_obj.name
logger.debug('Created Instance IP object 1 %s', ip_obj.uuid)

# Create VM
vm_inst_obj = VirtualMachine(str(uuid.uuid4()))
vm_inst_obj.uuid = vm_inst_obj.name
self._vnc_lib.virtual_machine_create(vm_inst_obj)

id_perms = IdPermsType(enable=True)
vm_port_obj = VirtualMachineInterface(
str(uuid.uuid4()), vm_inst_obj, id_perms=id_perms)
vm_port_obj.uuid = vm_port_obj.name
vm_port_obj.set_virtual_network(vn)
ip_obj.set_virtual_machine_interface(vm_port_obj)
ip_obj.set_virtual_network(net_obj)
port_id = self._vnc_lib.virtual_machine_interface_create(vm_port_obj)

logger.debug('Allocating an IP4 address for VM')
ip_id = self._vnc_lib.instance_ip_create(ip_obj)

# Create Logical Router
lr = LogicalRouter('router-test-v4', project)
lr_uuid = self._vnc_lib.logical_router_create(lr)
logger.debug('Created Logical Router ')

# Add Router Interface
lr.add_virtual_machine_interface(vm_port_obj)
logger.debug("Trying to Link VM's VMI object and LR object")
with ExpectedException(cfgm_common.exceptions.PermissionDenied) as e:
self._vnc_lib.logical_router_update(lr)
logger.debug("Linking VM's VMI object and LR object failed as expected")
lr.del_virtual_machine_interface(vm_port_obj)

# Create Port
logger.debug("Add internal interface to LR")
port_obj = self.create_port(project, net_obj)
lr.add_virtual_machine_interface(port_obj)
self._vnc_lib.logical_router_update(lr)
logger.debug("Link VM to internal interface of a LR")
with ExpectedException(cfgm_common.exceptions.PermissionDenied) as e:
port_obj.add_virtual_machine(vm_inst_obj)
self._vnc_lib.virtual_machine_interface_update(port_obj)
logger.debug("Linking VM to internal interface of LR failed as expected")
# end test_vm_port_not_added_to_lr

def create_port(self, project, vn):
## Create v4 Ip object
ip_obj = InstanceIp(name=str(uuid.uuid4()), instance_ip_family='v4')
ip_obj.uuid = ip_obj.name
logger.debug('Created Instance IP object 1 %s', ip_obj.uuid)

# Create Port
id_perms = IdPermsType(enable=True)
port_obj = VirtualMachineInterface(
str(uuid.uuid4()), parent_obj=project, id_perms=id_perms)
port_obj.uuid = port_obj.name
port_obj.set_virtual_network(vn)
ip_obj.set_virtual_machine_interface(port_obj)
ip_obj.set_virtual_network(vn)
port_id = self._vnc_lib.virtual_machine_interface_create(port_obj)

#logger.debug('Allocating an IP4 address for port')
ip_id = self._vnc_lib.instance_ip_create(ip_obj)
return port_obj
# end create_port

def test_same_network_not_attached_to_lr(self):
logger.debug("*** test interface-add gateway-set not allowing"
"same network to be attached as both internal and external"
"network of logical router ***")

# Create Domain
domain = Domain('my-lr-domain')
self._vnc_lib.domain_create(domain)
logger.debug('Created domain ')

# Create Project
project = Project('my-lr-proj', domain)
self._vnc_lib.project_create(project)
logger.debug('Created Project')

# Create NetworkIpam
ipam = NetworkIpam('default-network-ipam', project, IpamType("dhcp"))
self._vnc_lib.network_ipam_create(ipam)
logger.debug('Created network ipam')

ipam = self._vnc_lib.network_ipam_read(fq_name=['my-lr-domain', 'my-lr-proj',
'default-network-ipam'])
logger.debug('Read network ipam')

# Create subnets
ipam_sn_v4_vn = IpamSubnetType(subnet=SubnetType('11.1.1.0', 24))

# Create VN my-vn
vn = VirtualNetwork('my-vn', project)
vn.add_network_ipam(ipam, VnSubnetsType([ipam_sn_v4_vn]))
self._vnc_lib.virtual_network_create(vn)
logger.debug('Created Virtual Network object for my-vn: %s', vn.uuid)
net_obj = self._vnc_lib.virtual_network_read(id = vn.uuid)

## Create v4 Ip object
ip_obj = InstanceIp(name=str(uuid.uuid4()), instance_ip_family='v4')
ip_obj.uuid = ip_obj.name
logger.debug('Created Instance IP object 1 %s', ip_obj.uuid)

# Create Port
port_obj = self.create_port(project, net_obj)

# Create Logical Router
lr = LogicalRouter('router-test-v4', project)
lr_uuid = self._vnc_lib.logical_router_create(lr)
logger.debug('Created Logical Router ')

# Add Router Interface
lr.add_virtual_machine_interface(port_obj)
self._vnc_lib.logical_router_update(lr)

# set router_external
net_obj.set_router_external(True)
self._vnc_lib.virtual_network_update(net_obj)

logger.debug("Try adding gateway from same network as of interface to LR object")
with ExpectedException(cfgm_common.exceptions.PermissionDenied) as e:
lr.add_virtual_network(net_obj)
self._vnc_lib.logical_router_update(lr)
logger.debug("Adding gateway from same network as of interface to LR object failed as expected")
lr.del_virtual_network(net_obj)

logger.debug("Removing the interface attached to LR")
lr.del_virtual_machine_interface(port_obj)
self._vnc_lib.logical_router_update(lr)
logger.debug("Adding external gateway to LR")
lr.add_virtual_network(net_obj)
self._vnc_lib.logical_router_update(lr)

# Create Port
port_obj = self.create_port(project, net_obj)
logger.debug("Try adding interafce from same network as of gateway to LR object")
with ExpectedException(cfgm_common.exceptions.PermissionDenied) as e:
lr.add_virtual_machine_interface(port_obj)
self._vnc_lib.logical_router_update(lr)
logger.debug("Adding interface from same network as of gateway to LR object failed as expected")


# end test_same_network_not_attached_to_lr
#end class TestLogicalRouter

if __name__ == '__main__':
Expand Down
75 changes: 75 additions & 0 deletions src/config/api-server/vnc_cfg_types.py
Original file line number Diff line number Diff line change
Expand Up @@ -442,6 +442,66 @@ def dbe_delete_notification(cls, obj_ids, obj_dict):
class LogicalRouterServer(Resource, LogicalRouter):
generate_default_instance = False

@classmethod
def is_port_in_use_by_vm(cls, obj_dict, db_conn):
for vmi_ref in obj_dict.get('virtual_machine_interface_refs', []):
vmi_id = vmi_ref['uuid']
ok, read_result = cls.dbe_read(
db_conn, 'virtual-machine-interface', vmi_ref['uuid'])
if not ok:
return ok, read_result
if (read_result['parent_type'] == 'virtual-machine' or
read_result.get('virtual_machine_refs')):
msg = "Port(%s) already in use by virtual-machine(%s)" %\
(vmi_id, read_result['parent_uuid'])
return (False, (403, msg))
return (True, '')

@classmethod
def is_port_gateway_in_same_network(cls, db_conn, vmi_refs, vn_refs):
interface_vn_uuids = []
for vmi_ref in vmi_refs:
ok, vmi_result = cls.dbe_read(
db_conn, 'virtual-machine-interface', vmi_ref['uuid'])
if not ok:
return ok, vmi_result
interface_vn_uuids.append(
vmi_result['virtual_network_refs'][0]['uuid'])
for vn_ref in vn_refs:
if vn_ref['uuid'] in interface_vn_uuids:
msg = "Logical router interface and gateway cannot be in VN(%s)" %\
(vn_ref['uuid'])
return (False, (403, msg))
return (True, '')

@classmethod
def check_port_gateway_not_in_same_network(cls, db_conn, lr_id, obj_dict):
if ('virtual_network_refs' in obj_dict and
'virtual_machine_interface_refs' in obj_dict):
ok, result = cls.is_port_gateway_in_same_network(db_conn,
obj_dict['virtual_machine_interface_refs'],
obj_dict['virtual_network_refs'])
if not ok:
return ok, result
if ('virtual_network_refs' in obj_dict or
'virtual_machine_interface_refs' in obj_dict):
ok, read_result = cls.dbe_read(db_conn, 'logical-router', lr_id)
if not ok:
return ok, read_result
if 'virtual_network_refs' in obj_dict:
ok, result = cls.is_port_gateway_in_same_network(db_conn,
read_result.get('virtual_machine_interface_refs', []),
obj_dict['virtual_network_refs'])
if not ok:
return ok, result
if 'virtual_machine_interface_refs' in obj_dict:
ok, result = cls.is_port_gateway_in_same_network(db_conn,
obj_dict['virtual_machine_interface_refs'],
read_result.get('virtual_network_refs', []))
if not ok:
return ok, result
return (True, '')

@classmethod
def pre_dbe_create(cls, tenant_name, obj_dict, db_conn):
user_visibility = obj_dict['id_perms'].get('user_visible', True)
Expand All @@ -454,6 +514,15 @@ def pre_dbe_create(cls, tenant_name, obj_dict, db_conn):
return QuotaHelper.verify_quota_for_resource(**verify_quota_kwargs)
# end pre_dbe_create

@classmethod
def pre_dbe_update(cls, id, fq_name, obj_dict, db_conn, **kwargs):
ok, result = cls.check_port_gateway_not_in_same_network(db_conn, id,
obj_dict)
if not ok:
return (ok, result)
return cls.is_port_in_use_by_vm(obj_dict, db_conn)
# end pre_dbe_create

# end class LogicalRouterServer


Expand Down Expand Up @@ -622,6 +691,12 @@ def pre_dbe_update(cls, id, fq_name, obj_dict, db_conn,
if not ok:
return ok, read_result

# check if the vmi is a internal interface of a logical
# router
if (read_result.get('logical_router_back_refs') and
obj_dict.get('virtual_machine_refs')):
return (False,
(403, 'Logical router interface cannot be used by VM'))
# check if vmi is going to point to vm and if its using
# gateway address in iip, disallow
for iip_ref in read_result.get('instance_ip_back_refs') or []:
Expand Down

0 comments on commit 85018e6

Please sign in to comment.