Adding subnet behavior methods for IPv6

- Adding netaddr to pip-requires. netaddr to be used from now on
instead of IPy (current IPy use should be replaced later on with
netaddr)
- Adding random cidr generation to subnet behavior method:
create_ipv6_cidr
- Adding get_allocation_pools subnet behavior method
- Adding format_allocation_pools subnet behavior method

Change-Id: I42a1685c12fc505885669dc2625ae0d2f3e5b43e
This commit is contained in:
Leonardo Maycotte 2014-10-09 16:38:28 -05:00
parent cd47e56366
commit e12980bfbc
3 changed files with 78 additions and 1 deletions

View File

@ -14,9 +14,12 @@ See the License for the specific language governing permissions and
limitations under the License.
"""
import random
import time
import IPy
import netaddr
from cloudcafe.common.tools.datagen import rand_name, random_cidr
from cloudcafe.networking.networks.common.behaviors \
@ -171,7 +174,7 @@ class SubnetsBehaviors(NetworkingBaseBehaviors):
raise InvalidIPException(msg)
def create_ipv6_cidr(self, ipv6_suffix=None, ipv6_prefix=None,
ip_range=None, suffix_max=None):
ip_range=None, suffix_max=None, randomize=True):
"""
@summary: Creates an IPv6 cidr with given or default values
@param ipv6_suffix: the CIDR suffix, by default 64
@ -183,12 +186,33 @@ class SubnetsBehaviors(NetworkingBaseBehaviors):
@type ip_range: string
@param suffix_max: the prefix that the CIDR should be less or
equal than, by default 64
@type suffix_max: int
@param randomize: randomize 32 bits of the 40-bit global identifier in
the routing prefix to prevent collisions when two private networks
are interconnected
@type randomize: bool
@return: an IPv6 CIDR
@rtype: string
"""
ipv6_suffix = ipv6_suffix or self.config.ipv6_suffix
ipv6_prefix = ipv6_prefix or self.config.ipv6_prefix
if randomize:
b1 = random.getrandbits(16)
b2 = random.getrandbits(16)
prefix_dual_octets = ipv6_prefix.split(':')
prefix_dual_octets[1] = '{:x}'.format(b1)
prefix_dual_octets[2] = '{:x}'.format(b2)
ipv6_prefix = '{0}::'.format(':'.join(prefix_dual_octets))
# To be used with /64 IPv6 networks, overwriting suffix if other
if ipv6_suffix != 64:
msg = ('Subnet create_ipv6_cidr behavior method using '
'default 64 suffix instead of {0} when creating a '
'random cidr').format(ipv6_suffix)
self._log.info(msg)
ipv6_suffix = 64
cidr = '{0}/{1}'.format(ipv6_prefix, ipv6_suffix)
if self.verify_private_ip(ip_cidr=cidr, ip_version=6,
ip_range=ip_range, suffix_max=suffix_max):
@ -197,6 +221,48 @@ class SubnetsBehaviors(NetworkingBaseBehaviors):
msg = 'Invalid IPv6 cidr {0}'.format(cidr)
raise InvalidIPException(msg)
def get_allocation_pools(self, cidr, first_increment=1,
last_decrement=1):
"""
@summary: gets default allocation pools for an IPv4/IPv6 address
@param cidr: represents IP range for the subnet and should be in the
form <network_address>/<prefix>
@type cidr: string
@param first_increment: places from the fist IP of the CIDR to the
first IP of the allocation pool
@type first_increment: int
@param last_decrement: places from the last IP of the CIDR to the last
IP of the allocation pool
@type last_decrement: int
@return: allocation pool
@rtype: dict
"""
if not self.verify_ip(cidr):
raise InvalidIPException
net = netaddr.IPNetwork(cidr)
first_ip = str(netaddr.IPAddress(net.first + first_increment))
last_ip = str(netaddr.IPAddress(net.last - last_decrement))
return dict(start=first_ip, end=last_ip)
def format_allocation_pools(self, allocation_pools):
"""
@summary: formats allocation pools for assertions removing zeros on
IPv6 addresses
@param allocation_pools: list of allocation pools
@type allocation_pools: list
@return: formated allocation pools
@rtype: list(dict)
"""
formated_allocation_pools = []
for pool in allocation_pools:
result = dict(start=str(netaddr.IPAddress(pool['start'])),
end=str(netaddr.IPAddress(pool['end'])))
formated_allocation_pools.append(result)
return formated_allocation_pools
def create_subnet(self, network_id, ip_version=None, cidr=None, name=None,
tenant_id=None, gateway_ip=None, dns_nameservers=None,
allocation_pools=None, host_routes=None,

View File

@ -27,6 +27,16 @@ class SubnetsConfig(NetworkingBaseConfig):
"""Subnet start name label for test runs"""
return self.get("starts_with_name", "test_subnet")
@property
def v4_subnets_per_network(self):
"""Subnets IPv4 quota per network"""
return int(self.get("v4_subnets_per_network", 1))
@property
def v6_subnets_per_network(self):
"""Subnets IPv6 quota per network"""
return int(self.get("v6_subnets_per_network", 1))
@property
def ipv4_suffix(self):
"""Subnet create default IPv4 suffix"""

View File

@ -1,5 +1,6 @@
mock
unittest2
IPy
netaddr
XenAPI
dateutils