Skip to content

Commit

Permalink
Merge "Alias ip support in api server"
Browse files Browse the repository at this point in the history
  • Loading branch information
Zuul authored and opencontrail-ci-admin committed Jun 27, 2016
2 parents 119ebf1 + 53208ba commit 0038dab
Show file tree
Hide file tree
Showing 7 changed files with 326 additions and 10 deletions.
98 changes: 98 additions & 0 deletions src/config/api-server/tests/test_crud_basic.py
Expand Up @@ -107,6 +107,10 @@ def test_floating_ip_crud(self):
pass
# end test_floating_ip_crud

def test_alias_ip_crud(self):
pass
# end test_alias_ip_crud

def test_id_perms(self):
# create object in enabled state
# create object in disabled state
Expand Down Expand Up @@ -298,6 +302,30 @@ def test_ip_alloc_on_net(self):
self.assertThat(ip_allocated, Equals('1.1.1.3'))
logger.info("...verified")

logger.info("Creating alias-ip-pool")
aip_pool_fixt = self.useFixture(
AliasIpPoolTestFixtureGen(self._vnc_lib, 'aip-pool',
parent_fixt=vn_fixt,
auto_prop_val=False))

logger.info("Creating auto-alloc alias-ip, expecting 1.1.1.251...")
aip_fixt = self.useFixture(
AliasIpTestFixtureGen(
self._vnc_lib, 'aip1', parent_fixt=aip_pool_fixt,
auto_prop_val=False))
ip_allocated = aip_fixt.getObj().alias_ip_address
self.assertThat(ip_allocated, Equals('1.1.1.251'))
logger.info("...verified")

logger.info("Creating specific alias-ip, expecting 1.1.1.4...")
aip_fixt = self.useFixture(
AliasIpTestFixtureGen(
self._vnc_lib, 'aip2', parent_fixt=aip_pool_fixt,
auto_prop_val=False, alias_ip_address='1.1.1.4'))
ip_allocated = aip_fixt.getObj().alias_ip_address
self.assertThat(ip_allocated, Equals('1.1.1.4'))
logger.info("...verified")

logger.info("Creating subnet 2.2.2.0/24, gateway 2.2.2.128")
subnet_vnc = IpamSubnetType(subnet=SubnetType('2.2.2.0', 24),
default_gateway='2.2.2.128')
Expand Down Expand Up @@ -1127,6 +1155,42 @@ def test_floatingip_as_instanceip(self):
virtual_network_refs=[vn_fixt.getObj()]))
# end test_floatingip_as_instanceip

def test_aliasip_as_instanceip(self):
ipam_fixt = self.useFixture(NetworkIpamTestFixtureGen(self._vnc_lib))

project_fixt = self.useFixture(ProjectTestFixtureGen(self._vnc_lib, 'default-project'))

subnet_vnc = IpamSubnetType(subnet=SubnetType('1.1.1.0', 24))
vnsn_data = VnSubnetsType([subnet_vnc])
logger.info("Creating a virtual network")
logger.info("Creating subnet 1.1.1.0/24")
vn_fixt = self.useFixture(VirtualNetworkTestFixtureGen(self._vnc_lib,
'vn-%s' %(self.id()),
network_ipam_ref_infos=[(ipam_fixt.getObj(), vnsn_data)]))
vn_fixt.getObj().set_router_external(True)
self._vnc_lib.virtual_network_update(vn_fixt.getObj())

logger.info("Fetching alias-ip-pool")
aip_pool_fixt = self.useFixture(
AliasIpPoolTestFixtureGen(self._vnc_lib, 'alias-ip-pool',
parent_fixt=vn_fixt))

logger.info("Creating auto-alloc alias-ip")
aip_fixt = self.useFixture(
AliasIpTestFixtureGen(
self._vnc_lib, 'aip1', parent_fixt=aip_pool_fixt,
project_refs=[project_fixt.getObj()]))
ip_allocated = aip_fixt.getObj().alias_ip_address

logger.info("Creating auto-alloc instance-ip, expecting an error")
with ExpectedException(PermissionDenied) as e:
iip_fixt = self.useFixture(
InstanceIpTestFixtureGen(
self._vnc_lib, 'iip1', auto_prop_val=False,
instance_ip_address=ip_allocated,
virtual_network_refs=[vn_fixt.getObj()]))
# end test_aliasip_as_instanceip

def test_name_with_reserved_xml_char(self):
self.skipTest("Skipping test_name_with_reserved_xml_char")
vn_name = self.id()+'-&vn<1>"2\''
Expand Down Expand Up @@ -1737,6 +1801,8 @@ def err_on_delete(orig_method, *args, **kwargs):
def err_on_delete(orig_method, *args, **kwargs):
if args[0] == 'floating_ip':
raise Exception("Faking db delete for floating ip")
if args[0] == 'alias_ip':
raise Exception("Faking db delete for alias ip")
return orig_method(*args, **kwargs)
with test_common.patch(
self._api_server._db_conn, 'dbe_delete', err_on_delete):
Expand All @@ -1759,6 +1825,38 @@ def err_on_delete(orig_method, *args, **kwargs):
self._vnc_lib.floating_ip_read(
id=fip_obj.uuid).floating_ip_address,
fip_obj.floating_ip_address)

# alias-ip test
aip_pool_obj = AliasIpPool(
'aip-pool-%s' %(self.id()), parent_obj=vn_obj)
self._vnc_lib.alias_ip_pool_create(aip_pool_obj)
aip_obj = AliasIp('aip-%s' %(self.id()), parent_obj=aip_pool_obj)
aip_obj.add_project(Project())
self._vnc_lib.alias_ip_create(aip_obj)
# read back to get allocated alias-ip
aip_obj = self._vnc_lib.alias_ip_read(id=aip_obj.uuid)

with test_common.patch(
self._api_server._db_conn, 'dbe_delete', err_on_delete):
try:
self._vnc_lib.alias_ip_delete(id=aip_obj.uuid)
self.assertTrue(
False, 'Alias IP delete worked unexpectedly')
except Exception as e:
self.assertThat(str(e),
Contains('"Faking db delete for alias ip"'))
# assert reservation present in zookeeper and value in iip
zk_node = "%(#)010d" % {'#': int(netaddr.IPAddress(
aip_obj.alias_ip_address))}
zk_path = '/api-server/subnets/%s:1.1.1.0/28/%s' %(
vn_obj.get_fq_name_str(), zk_node)
mock_zk = self._api_server._db_conn._zk_db._zk_client._zk_client
self.assertEqual(
mock_zk._values[zk_path][0], aip_obj.uuid)
self.assertEqual(
self._vnc_lib.alias_ip_read(
id=aip_obj.uuid).alias_ip_address,
aip_obj.alias_ip_address)
# end test_ip_addr_not_released_on_delete_error

def test_uve_trace_delete_name_from_msg(self):
Expand Down
36 changes: 36 additions & 0 deletions src/config/api-server/tests/test_ip_alloc.py
Expand Up @@ -967,6 +967,10 @@ def test_ip_alloc_clash(self):
'fip-pool-%s' %(self.id()), parent_obj=vn_obj)
self._vnc_lib.floating_ip_pool_create(fip_pool_obj)

aip_pool_obj = AliasIpPool(
'aip-pool-%s' %(self.id()), parent_obj=vn_obj)
self._vnc_lib.alias_ip_pool_create(aip_pool_obj)

iip_obj = InstanceIp('existing-iip-%s' %(self.id()))
iip_obj.add_virtual_network(vn_obj)
self._vnc_lib.instance_ip_create(iip_obj)
Expand All @@ -979,6 +983,12 @@ def test_ip_alloc_clash(self):
# read-in to find allocated address
fip_obj = self._vnc_lib.floating_ip_read(id=fip_obj.uuid)

aip_obj = AliasIp('existing-aip-%s' %(self.id()), aip_pool_obj)
aip_obj.add_project(proj_obj)
self._vnc_lib.alias_ip_create(aip_obj)
# read-in to find allocated address
aip_obj = self._vnc_lib.alias_ip_read(id=aip_obj.uuid)

vm_obj = VirtualMachine('vm-%s' %(self.id()))
self._vnc_lib.virtual_machine_create(vm_obj)

Expand Down Expand Up @@ -1023,18 +1033,44 @@ def test_ip_alloc_clash(self):
'Ip address already in use') as e:
self._vnc_lib.floating_ip_create(fip2_obj)

# allocate alias-ip clashing with existing alias-ip
aip2_obj = AliasIp('clashing-aip-%s' %(self.id()), aip_pool_obj,
alias_ip_address=aip_obj.alias_ip_address)
aip2_obj.add_project(proj_obj)
with ExpectedException(cfgm_common.exceptions.PermissionDenied,
'Ip address already in use') as e:
self._vnc_lib.alias_ip_create(aip2_obj)

# allocate floating-ip clashing with existing instance-ip
fip2_obj.set_floating_ip_address(iip_obj.instance_ip_address)
with ExpectedException(cfgm_common.exceptions.PermissionDenied,
'Ip address already in use') as e:
self._vnc_lib.floating_ip_create(fip2_obj)

# allocate alias-ip clashing with existing instance-ip
aip2_obj.set_alias_ip_address(iip_obj.instance_ip_address)
with ExpectedException(cfgm_common.exceptions.PermissionDenied,
'Ip address already in use') as e:
self._vnc_lib.alias_ip_create(aip2_obj)

# allocate alias-ip clashing with existing floating-ip
aip2_obj.set_alias_ip_address(fip_obj.floating_ip_address)
with ExpectedException(cfgm_common.exceptions.PermissionDenied,
'Ip address already in use') as e:
self._vnc_lib.alias_ip_create(aip2_obj)

# allocate floating-ip with gateway ip and verify failure
fip2_obj.set_floating_ip_address('11.1.1.254')
with ExpectedException(cfgm_common.exceptions.PermissionDenied,
'Ip address already in use') as e:
self._vnc_lib.floating_ip_create(fip2_obj)

# allocate alias-ip with gateway ip and verify failure
aip2_obj.set_alias_ip_address('11.1.1.254')
with ExpectedException(cfgm_common.exceptions.PermissionDenied,
'Ip address already in use') as e:
self._vnc_lib.alias_ip_create(aip2_obj)

# allocate 2 instance-ip with gateway ip - should work
# then verify iip cannot # ref to vm port (during iip-update
# or vmi-update)
Expand Down
65 changes: 55 additions & 10 deletions src/config/api-server/vnc_addr_mgmt.py
Expand Up @@ -834,10 +834,11 @@ def net_check_subnet(self, req_vn_dict):
# end net_check_subnet

# check subnets associated with a virtual network, return error if
# any subnet is being deleted and has backref to instance-ip/floating-ip
# any subnet is being deleted and has backref to
# instance-ip/floating-ip/alias-ip
def net_check_subnet_delete(self, db_vn_dict, req_vn_dict):
db_conn = self._get_db_conn()
# if all instance-ip/floating-ip are part of requested list
# if all ips are part of requested list
# things are ok.
# eg. existing [1.1.1.0/24, 2.2.2.0/24],
# requested [1.1.1.0/24] OR
Expand All @@ -856,18 +857,20 @@ def net_check_subnet_delete(self, db_vn_dict, req_vn_dict):
# read the instance ip and floating ip pool only if subnet is being
# deleted. Skip the port check if no subnet is being deleted
vn_id = {'uuid': db_vn_dict['uuid']}
obj_fields = ['network_ipam_refs', 'instance_ip_back_refs', 'floating_ip_pools']
obj_fields = ['network_ipam_refs', 'instance_ip_back_refs', 'floating_ip_pools', 'alias_ip_pools']
(read_ok, db_vn_dict) = db_conn.dbe_read('virtual_network', vn_id, obj_fields)
if not read_ok:
return (False, (500, db_vn_dict))

# if all subnets are being removed, check for any iip backrefs
# or floating pools still present in DB version of VN
# or floating/alias pools still present in DB version of VN
if len(requested_subnets) == 0:
if db_vn_dict.get('instance_ip_back_refs'):
return False, "Cannot Delete IP Block, Instance IP(s) in use"
if db_vn_dict.get('floating_ip_pools'):
return False, "Cannot Delete IP Block, Floating Pool(s) in use"
if db_vn_dict.get('alias_ip_pools'):
return False, "Cannot Delete IP Block, Alias Pool(s) in use"
else:
return True, ""

Expand All @@ -892,9 +895,9 @@ def net_check_subnet_delete(self, db_vn_dict, req_vn_dict):
level=SandeshLevel.SYS_ERR)
continue
if not all_matching_cidrs(inst_ip, requested_subnets):
return False,\
"Cannot Delete IP Block, IP(%s) is in use"\
% (inst_ip)
return (False,
"Cannot Delete IP Block, IP(%s) is in use"
% (inst_ip))

fip_pool_refs = db_vn_dict.get('floating_ip_pools', [])
for ref in fip_pool_refs:
Expand Down Expand Up @@ -934,9 +937,51 @@ def net_check_subnet_delete(self, db_vn_dict, req_vn_dict):
level=SandeshLevel.SYS_ERR)
continue
if not all_matching_cidrs(fip_addr, requested_subnets):
return False,\
"Cannot Delete IP Block, Floating IP(%s) is in use"\
% (fip_addr)
return (False,
"Cannot Delete IP Block, Floating IP(%s) is in use"
% (fip_addr))

aip_pool_refs = db_vn_dict.get('alias_ip_pools', [])
for ref in aip_pool_refs:
try:
(ok, result) = db_conn.dbe_read(
'alias_ip_pool', {'uuid': ref['uuid']})
except cfgm_common.exceptions.NoIdError:
continue
if not ok:
self.config_log(
"Error in subnet delete alias-ip-pool check: %s"
%(result),
level=SandeshLevel.SYS_ERR)
return False, result

alias_ips = result.get('alias_ips', [])
for alias_ip in alias_ips:
# get alias_ip_address and this should be in
# new subnet_list
try:
(read_ok, read_result) = db_conn.dbe_read(
'alias_ip', {'uuid': floating_ip['uuid']})
except cfgm_common.exceptions.NoIdError:
continue
if not read_ok:
self.config_log(
"Error in subnet delete floating-ip check: %s"
%(read_result),
level=SandeshLevel.SYS_ERR)
return False, result

aip_addr = read_result.get('alias_ip_address')
if not aip_addr:
self.config_log(
"Error in subnet delete aip null: %s"
%(alias_ip['uuid']),
level=SandeshLevel.SYS_ERR)
continue
if not all_matching_cidrs(aip_addr, requested_subnets):
return (False,
"Cannot Delete IP Block, Floating IP(%s) is in use"
% (aip_addr))

return True, ""
# end net_check_subnet_delete
Expand Down
3 changes: 3 additions & 0 deletions src/config/api-server/vnc_cfg_api_server.py
Expand Up @@ -1281,6 +1281,8 @@ def __init__(self, args_str=None):
'access-control-list').generate_default_instance = False
self.get_resource_class(
'floating-ip-pool').generate_default_instance = False
self.get_resource_class(
'alias-ip-pool').generate_default_instance = False
self.get_resource_class('instance-ip').generate_default_instance = False
self.get_resource_class('logical-router').generate_default_instance = False
self.get_resource_class('security-group').generate_default_instance = False
Expand Down Expand Up @@ -1429,6 +1431,7 @@ def __init__(self, args_str=None):
vnc_cfg_types.SecurityGroupServer.addr_mgmt = addr_mgmt
vnc_cfg_types.VirtualMachineInterfaceServer.addr_mgmt = addr_mgmt
vnc_cfg_types.FloatingIpServer.addr_mgmt = addr_mgmt
vnc_cfg_types.AliasIpServer.addr_mgmt = addr_mgmt
vnc_cfg_types.InstanceIpServer.addr_mgmt = addr_mgmt
vnc_cfg_types.VirtualNetworkServer.addr_mgmt = addr_mgmt
vnc_cfg_types.InstanceIpServer.manager = self
Expand Down

0 comments on commit 0038dab

Please sign in to comment.