def __init__(self, network_dict, datastore): '''Python representation of a _network block Raises: ValueError - if a _network block has invalid information''' self.datastore = datastore self._network_block_utilization = {} self._network_id = network_dict['id'] self.network_name = network_dict['name'] self.family = network_dict['family'] self.location = network_dict['location'] self._network = ipaddress.ip_network(network_dict['network'], strict=True) self.allocation_size = network_dict['allocation_size'] self.reserved_blocks = network_dict['reserved_blocks'] # Sanity check ourselves check.is_valid_ip_family(self.family) # Work out some values based on family size, and make sure our allocation is sane total_length_of_an_ip = None if self.family == AF_INET: total_length_of_an_ip = 32 if self.allocation_size > 32 or self.allocation_size < self._network.prefixlen: raise ValueError('Allocation prefix size is too large!') if self.family == AF_INET6: total_length_of_an_ip = 128 if self.allocation_size > 128 or self.allocation_size < self._network.prefixlen: raise ValueError('Allocation prefix size is too large!') # We can calculate the number of hosts by doing powers of 2 math self._total_number_of_allocations = 2**(self.allocation_size-self._network.prefixlen) # Now the tricky bit. We need to know (in binary), how much we need to add to get # the next IP range we're allocation. # Clarity note, if we're allocating single IPs, the following equation will be 0. Anything # raised to 0 becomes 1. self._block_seperator = 2**(total_length_of_an_ip-self.allocation_size) # Depending on the size of the block, and our family, there are some allocations # that aren't valid. If we're handing out /32 addresses, we need to take in account # that the _network address and broadcast address of a block are unusable. Allocation # handles this case for >/32 blocks, but we need to handle it here otherwise. # FIXME: Confirm this logic is sane ... # IP ranges are 0-255. Powers of two math gets us 256, so drop it by one so everything # else ends up in the right ranges self._total_number_of_allocations -= 1 # In all cases, we need to handle the _network address self._mark_network_address() # If we're IPv4, we need handle the broadcast address if self.family == AF_INET: self._mark_broadcast_address()
def create_network(self, name, location, family, network, allocation_size, reserved_blocks): # pylint: disable=too-many-arguments """Creates a network in the database""" # Argument validation check.is_valid_ip_family(family) network = check.validate_and_normalize_ip_network(network) check.is_valid_prefix_size(allocation_size, family) # FIXME: make sure we're not trying to add ourselves twice query = """INSERT INTO network_topology (name, location, family, network, allocation_size, reserved_blocks) VALUES (%s, %s, %s,%s, %s, %s)""" self._do_insert(query, (name, location, int(family), network, allocation_size, reserved_blocks)) # Update our state information to see the new network self.refresh_network_topogoly()