def backend_allocate(self, address_request): try: # allocate a specific IP if isinstance(address_request, ipam_req.SpecificAddressRequest): # This handles both specific and automatic address requests ip_address = str(address_request.address) self._vcns.allocate_ipam_ip_from_pool(self._nsx_pool_id, ip_addr=ip_address) else: # Allocate any free IP response = self._vcns.allocate_ipam_ip_from_pool( self._nsx_pool_id)[1] # get the ip from the response root = et.fromstring(response) ip_address = root.find('ipAddress').text except vc_exc.VcnsApiException as e: # handle backend failures error_code = self._get_vcns_error_code(e) if error_code == constants.NSX_ERROR_IPAM_ALLOCATE_IP_USED: # This IP is already in use raise ipam_exc.IpAddressAlreadyAllocated( ip=ip_address, subnet_id=self._subnet_id) if error_code == constants.NSX_ERROR_IPAM_ALLOCATE_ALL_USED: # No more IP addresses available on the pool raise ipam_exc.IpAddressGenerationFailure( subnet_id=self._subnet_id) else: raise ipam_exc.IPAllocationFailed() return ip_address
def backend_allocate(self, address_request): try: # allocate a specific IP if isinstance(address_request, ipam_req.SpecificAddressRequest): # This handles both specific and automatic address requests ip_address = str(address_request.address) # If this is the subnet gateway IP - no need to allocate it subnet = self.get_details() if str(subnet.gateway_ip) == ip_address: LOG.info("Skip allocation of gateway-ip for pool %s", self._nsx_pool_id) return ip_address else: # Allocate any free IP ip_address = None response = self.nsxlib_ipam.allocate(self._nsx_pool_id, ip_addr=ip_address) ip_address = response['allocation_id'] except nsx_lib_exc.ManagerError as e: LOG.error( "NSX IPAM failed to allocate ip %(ip)s of subnet " "%(id)s: %(e)s; code %(code)s", { 'e': e, 'ip': ip_address, 'id': self._subnet_id, 'code': e.error_code }) if e.error_code == error.ERR_CODE_IPAM_POOL_EXHAUSTED: # No more IP addresses available on the pool raise ipam_exc.IpAddressGenerationFailure( subnet_id=self._subnet_id) if e.error_code == error.ERR_CODE_IPAM_SPECIFIC_IP: # The NSX backend does not support allocation of specific IPs # prior to version 2.0. msg = (_("NSX-V3 IPAM driver does not support allocation of a " "specific ip %s for port") % ip_address) raise NotImplementedError(msg) if e.error_code == error.ERR_CODE_IPAM_IP_ALLOCATED: # This IP is already in use raise ipam_exc.IpAddressAlreadyAllocated( ip=ip_address, subnet_id=self._subnet_id) if e.error_code == error.ERR_CODE_OBJECT_NOT_FOUND: msg = (_("NSX-V3 IPAM failed to allocate: pool %s was not " "found") % self._nsx_pool_id) raise ipam_exc.IpamValueInvalid(message=msg) else: # another backend error raise ipam_exc.IPAllocationFailed() except Exception as e: LOG.error( "NSX IPAM failed to allocate ip %(ip)s of subnet " "%(id)s: %(e)s", { 'e': e, 'ip': ip_address, 'id': self._subnet_id }) # handle unexpected failures raise ipam_exc.IPAllocationFailed() return ip_address
def _verify_ip(self, session, ip_address): """Verify whether IP address can be allocated on subnet. :param session: database session :param ip_address: String representing the IP address to verify :raises: InvalidInput, IpAddressAlreadyAllocated """ # Ensure that the IP's are unique if not self.subnet_manager.check_unique_allocation( session, ip_address): raise ipam_exc.IpAddressAlreadyAllocated( subnet_id=self.subnet_manager.neutron_id, ip=ip_address) # Ensure that the IP is valid on the subnet if not ipam_utils.check_subnet_ip(self._cidr, ip_address): raise ipam_exc.InvalidIpForSubnet( subnet_id=self.subnet_manager.neutron_id, ip=ip_address)