Skip to content

Commit

Permalink
Merge "Changes in ip_alloc, ip_free and ip_count APIs to use subnet_u…
Browse files Browse the repository at this point in the history
…uid" into R3.2
  • Loading branch information
Zuul authored and opencontrail-ci-admin committed Oct 25, 2016
2 parents e32ab6d + bb5e085 commit cc8a0b9
Show file tree
Hide file tree
Showing 7 changed files with 51 additions and 77 deletions.
11 changes: 5 additions & 6 deletions src/api-lib/vnc_api.py
Expand Up @@ -1063,7 +1063,7 @@ def kv_delete(self, key):
#end kv_delete

# reserve block of IP address from a VN
# expected format {"subnet" : "2.1.1.0/24", "count" : 4}
# expected format {"subnet" : "subnet_uuid", "count" : 4}
@check_homepage
def virtual_network_ip_alloc(self, vnobj, count=1, subnet=None, family=None):
json_body = json.dumps({'count': count, 'subnet': subnet, 'family':family})
Expand All @@ -1073,18 +1073,17 @@ def virtual_network_ip_alloc(self, vnobj, count=1, subnet=None, family=None):
#end virtual_network_ip_alloc

# free previously reserved block of IP address from a VN
# Expected format "subnet" : "2.1.1.0/24",
# "ip_addr" : ["2.1.1.239", "2.1.1.238"]
# Expected format "ip_addr" : ["2.1.1.239", "2.1.1.238"]
@check_homepage
def virtual_network_ip_free(self, vnobj, ip_list, subnet=None):
json_body = json.dumps({'ip_addr': ip_list, 'subnet': subnet})
def virtual_network_ip_free(self, vnobj, ip_list):
json_body = json.dumps({'ip_addr': ip_list})
uri = self._action_uri['virtual-network-ip-free'] % vnobj.uuid
rv = self._request_server(rest.OP_POST, uri, data=json_body)
return rv
#end virtual_network_ip_free

# return no of ip instances from a given VN/Subnet
# Expected format "subne_list" : ["2.1.1.0/24", "2.2.2.0/24"]
# Expected format "subne_list" : ["subnet_uuid1", "subnet_uuid2"]
@check_homepage
def virtual_network_subnet_ip_count(self, vnobj, subnet_list):
json_body = json.dumps({'subnet_list': subnet_list})
Expand Down
20 changes: 10 additions & 10 deletions src/config/api-server/tests/test_ip_alloc.py
Expand Up @@ -1682,8 +1682,9 @@ def test_bulk_ip_alloc_free(self):
logger.debug('Created Virtual Network object %s', vn.uuid)
net_obj = self._vnc_lib.virtual_network_read(id = vn.uuid)

subnet_uuid = net_obj.network_ipam_refs[0]['attr'].ipam_subnets[0].subnet_uuid
# request to allocate 10 ip address using bulk allocation api
data = {"subnet" : "11.1.1.0/24", "count" : 10}
data = {"subnet" : subnet_uuid, "count" : 10}
url = '/virtual-network/%s/ip-alloc' %(vn.uuid)
rv_json = self._vnc_lib._request_server(rest.OP_POST, url,
json.dumps(data))
Expand All @@ -1700,9 +1701,9 @@ def test_bulk_ip_alloc_free(self):

logger.debug('Verify bulk ip address allocation')
# Find out number of allocated ips from given VN/subnet
# We should not get 13 ip allocated from this subnet
# We should get 13 ip allocated from this subnet
# 10 user request + 3 reserved ips (first, last and gw).
data = {"subnet_list" : ["11.1.1.0/24"]}
data = {"subnet_list" : [subnet_uuid]}
url = '/virtual-network/%s/subnet-ip-count' %(vn.uuid)
rv_json = self._vnc_lib._request_server(rest.OP_POST, url,
json.dumps(data))
Expand All @@ -1711,15 +1712,14 @@ def test_bulk_ip_alloc_free(self):
self.assertEqual(allocated_ip, 10)

#free 5 allocated ip addresses from vn
data = {"subnet" : "11.1.1.0/24",
"ip_addr" : ['11.1.1.252', '11.1.1.251', '11.1.1.250',
data = {"ip_addr" : ['11.1.1.252', '11.1.1.251', '11.1.1.250',
'11.1.1.249', '11.1.1.248']}
url = '/virtual-network/%s/ip-free' %(vn.uuid)
self._vnc_lib._request_server(rest.OP_POST, url, json.dumps(data))

# Find out number of allocated ips from given VN/subnet
# We should get 5+3 ip allocated from this subnet
data = {"subnet_list" : ["11.1.1.0/24"]}
data = {"subnet_list" : [subnet_uuid]}
url = '/virtual-network/%s/subnet-ip-count' %(vn.uuid)
rv_json = self._vnc_lib._request_server(rest.OP_POST, url,
json.dumps(data))
Expand All @@ -1728,13 +1728,12 @@ def test_bulk_ip_alloc_free(self):
self.assertEqual(allocated_ip, 5)

#free remaining 5 allocated ip addresses from vn
data = {"subnet" : "11.1.1.0/24",
"ip_addr": ['11.1.1.247', '11.1.1.246', '11.1.1.245',
data = {"ip_addr": ['11.1.1.247', '11.1.1.246', '11.1.1.245',
'11.1.1.244', '11.1.1.243']}
url = '/virtual-network/%s/ip-free' %(vn.uuid)
self._vnc_lib._request_server(rest.OP_POST, url, json.dumps(data))

data = {"subnet_list" : ["11.1.1.0/24"]}
data = {"subnet_list" : [subnet_uuid]}
url = '/virtual-network/%s/subnet-ip-count' %(vn.uuid)
rv_json = self._vnc_lib._request_server(rest.OP_POST, url,
json.dumps(data))
Expand Down Expand Up @@ -1844,7 +1843,8 @@ def test_v4_ip_allocation_exhaust(self):

# Find out number of allocated ips from given VN/subnet to test
# vn_subnet_ip_count_http_post()
data = {"subnet_list" : ["11.1.1.0/24"]}
subnet_uuid = net_obj.network_ipam_refs[0]['attr'].ipam_subnets[0].subnet_uuid
data = {"subnet_list" : [subnet_uuid]}
url = '/virtual-network/%s/subnet-ip-count' %(vn.uuid)
rv_json = self._vnc_lib._request_server(rest.OP_POST, url, json.dumps(data))
ret_ip_count = json.loads(rv_json)['ip_count_list'][0]
Expand Down
19 changes: 17 additions & 2 deletions src/config/api-server/vnc_addr_mgmt.py
Expand Up @@ -1162,10 +1162,25 @@ def net_check_subnet_delete(self, db_vn_dict, req_vn_dict):

# return number of ip address currently allocated for a subnet
# count will also include reserved ips
def ip_count_req(self, vn_fq_name, subnet_name=None):
def ip_count_req(self, vn_fq_name, subnet_uuid):
if subnet_uuid is None:
return 0

db_conn = self._get_db_conn()
vn_uuid = db_conn.fq_name_to_uuid('virtual_network', vn_fq_name)
subnet_obj = self._subnet_objs[vn_uuid][subnet_name]
subnet_dicts = self._get_net_subnet_dicts(vn_uuid)
req_subnet_name = None
for subnet_name, subnet_dict in subnet_dicts.items():
if subnet_uuid == subnet_dict.get('subnet_uuid'):
req_subnet_name = subnet_name
break

if req_subnet_name is None:
# subnet is not on this network, return zero to reflect no ip addr
# is allocated from requested subnet_uuid
return 0

subnet_obj = self._subnet_objs[vn_uuid][req_subnet_name]
return subnet_obj.ip_count()
# end ip_count_req

Expand Down
3 changes: 1 addition & 2 deletions src/config/api-server/vnc_cfg_api_server.py
Expand Up @@ -3463,9 +3463,8 @@ def vn_ip_free_http_post(self, id):

req_dict = get_request().json
ip_list = req_dict['ip_addr'] if 'ip_addr' in req_dict else []
subnet = req_dict['subnet'] if 'subnet' in req_dict else None
result = vnc_cfg_types.VirtualNetworkServer.ip_free(
vn_fq_name, subnet, ip_list)
vn_fq_name, ip_list)
return result
# end vn_ip_free_http_post

Expand Down
50 changes: 5 additions & 45 deletions src/config/api-server/vnc_cfg_types.py
Expand Up @@ -1308,68 +1308,28 @@ def drop_ref(obj_uuid):


@classmethod
def ip_alloc(cls, vn_fq_name, subnet_name, count, family=None):
def ip_alloc(cls, vn_fq_name, subnet_uuid=None, count=1, family=None):
if family:
ip_version = 6 if family == 'v6' else 4
else:
ip_version = None
subnet_uuid = None
if subnet_name:
vn_uuid = cls.addr_mgmt._db_conn.fq_name_to_uuid('virtual_network',
vn_fq_name)
(ok, result) = cls.addr_mgmt._db_conn.dbe_read(
obj_type='virtual_network',
obj_ids={'uuid': vn_uuid},
obj_fields=['network_ipam_refs'])

if not ok:
raise cfgm_common.exceptions.VncError(result)
vn_dict = result

ipam_refs = vn_dict.get('network_ipam_refs') or []
for ipam in ipam_refs:
# Currently ip_alloc api is not supported for flat-ipam
# only to user-defined-ipam, we need to skip
# any flat ipam
vnsn_data = ipam['attr']
ipam_subnets = vnsn_data.get('ipam_subnets') or []
if len(ipam_subnets) is 0:
continue
first_ipam_subnet = ipam_subnets[0]
subnet = first_ipam_subnet.get('subnet') or {}
if ('ip_prefix' not in subnet):
continue

ipam_subnets = ipam['attr'].get('ipam_subnets') or []
for ipam_subnet in ipam_subnets:
subnet = ipam_subnet.get('subnet') or {}
if 'ip_prefix' in subnet:
ipam_subnet_name = subnet['ip_prefix'] + '/' +\
str(subnet['ip_prefix_len'])
if ipam_subnet_name == subnet_name:
subnet_uuid = ipam_subnet.get('subnet_uuid')
break

if subnet_uuid is None:
return {'ip_addr' : []}

ip_list = [cls.addr_mgmt.ip_alloc_req(vn_fq_name, sub=subnet_uuid,
asked_ip_version=ip_version,
alloc_id=str(uuid.uuid4()))
for i in range(count)]
msg = 'AddrMgmt: reserve %d IP for vn=%s, subnet=%s - %s' \
% (count, vn_fq_name, subnet_name if subnet_name else '', ip_list)
% (count, vn_fq_name, subnet_uuid or '', ip_list)
cls.addr_mgmt.config_log(msg, level=SandeshLevel.SYS_DEBUG)
return {'ip_addr': ip_list}
# end ip_alloc

@classmethod
def ip_free(cls, vn_fq_name, subnet_name, ip_list):
msg = 'AddrMgmt: release IP %s for vn=%s, subnet=%s' \
% (ip_list, vn_fq_name, subnet_name if subnet_name else '')
def ip_free(cls, vn_fq_name, ip_list):
msg = 'AddrMgmt: release IP %s for vn=%s' % (ip_list, vn_fq_name)
cls.addr_mgmt.config_log(msg, level=SandeshLevel.SYS_DEBUG)
for ip_addr in ip_list:
cls.addr_mgmt.ip_free_req(ip_addr, vn_fq_name, subnet_name)
cls.addr_mgmt.ip_free_req(ip_addr, vn_fq_name)
# end ip_free

@classmethod
Expand Down
22 changes: 11 additions & 11 deletions src/config/device-manager/device_manager/db.py
Expand Up @@ -211,28 +211,26 @@ def init_cs_state(self):
self.vn_ip_map[vn_subnet] = ip['ip_address']
# end init_cs_state

def reserve_ip(self, vn_uuid, subnet_prefix):
def reserve_ip(self, vn_uuid, subnet_uuid):
try:
vn = VirtualNetwork()
vn.set_uuid(vn_uuid)
ip_addr = self._manager._vnc_lib.virtual_network_ip_alloc(
vn,
subnet=subnet_prefix)
subnet_uuid=subnet_uuid)
if ip_addr:
return ip_addr[0] # ip_alloc default ip count is 1
except Exception as e:
self._logger.error("Exception: %s" % (str(e)))
return None
# end

def free_ip(self, vn_uuid, subnet_prefix, ip_addr):
def free_ip(self, vn_uuid, ip_addr):
try:
vn = VirtualNetwork()
vn.set_uuid(vn_uuid)
self._manager._vnc_lib.virtual_network_ip_free(
vn,
[ip_addr],
subnet=subnet_prefix)
vn, [ip_addr])
return True
except Exception as e:
self._logger.error("Exception: %s" % (str(e)))
Expand All @@ -246,7 +244,9 @@ def get_vn_irb_ip_map(self):
vn = VirtualNetworkDM.get(vn_uuid)
if vn_uuid not in irb_ips:
irb_ips[vn_uuid] = set()
irb_ips[vn_uuid].add((ip_addr, vn.gateways[subnet_prefix]))
irb_ips[vn_uuid].add(
(ip_addr,
vn.gateways[subnet_prefix].get('default_gateway')))
return irb_ips
# end get_vn_irb_ip_map

Expand All @@ -265,8 +265,7 @@ def evaluate_vn_irb_ip_map(self, vn_set):
create_set = new_vn_ip_set.difference(old_set)
for vn_subnet in delete_set:
(vn_uuid, subnet_prefix) = vn_subnet.split(':', 1)
ret = self.free_ip(
vn_uuid, subnet_prefix, self.vn_ip_map[vn_subnet])
ret = self.free_ip(vn_uuid, self.vn_ip_map[vn_subnet])
if ret == False:
self._logger.error("Unable to free ip for vn/subnet/pr \
(%s/%s/%s)" % (
Expand All @@ -288,8 +287,9 @@ def evaluate_vn_irb_ip_map(self, vn_set):

for vn_subnet in create_set:
(vn_uuid, subnet_prefix) = vn_subnet.split(':', 1)
subnet_uuid = vn.gateways[subnet_prefix].get('subnet_uuid')
(sub, length) = subnet_prefix.split('/')
ip_addr = self.reserve_ip(vn_uuid, subnet_prefix)
ip_addr = self.reserve_ip(vn_uuid, subnet_uuid)
if ip_addr is None:
self._logger.error("Unable to allocate ip for vn/subnet/pr \
(%s/%s/%s)" % (
Expand All @@ -307,7 +307,7 @@ def evaluate_vn_irb_ip_map(self, vn_set):
self.uuid,
subnet_prefix,
self.uuid))
if self.free_ip(vn_uuid, subnet_prefix, ip_addr) == False:
if self.free_ip(vn_uuid, ip_addr) == False:
self._logger.error("Unable to free ip for vn/subnet/pr \
(%s/%s/%s)" % (
self.uuid,
Expand Down
3 changes: 2 additions & 1 deletion src/config/device-manager/device_manager/dm_utils.py
Expand Up @@ -39,7 +39,8 @@ def get_network_gateways(ipam_refs=[]):
prefix = subnet['subnet']['ip_prefix']
prefix_len = subnet['subnet']['ip_prefix_len']
gateways[prefix + '/' + str(prefix_len)] = \
subnet.get('default_gateway', '')
{"default_gateway": subnet.get('default_gateway', ''),
"subnet_uuid": subnet.get('subnet_uuid')}
return gateways
# end get_network_gateways

Expand Down

0 comments on commit cc8a0b9

Please sign in to comment.