def deallocate_mac_address(self, context, address): mac = db_api.mac_address_find(context, address=address, scope=db_api.ONE) if not mac: raise exceptions.NotFound( message="No MAC address %s found" % netaddr.EUI(address)) db_api.mac_address_update(context, mac, deallocated=True, deallocated_at=timeutils.utcnow())
def allocate_mac_address(self, context, net_id, port_id, reuse_after, mac_address=None): if mac_address: mac_address = netaddr.EUI(mac_address).value deallocated_mac = db_api.mac_address_find(context, reuse_after=reuse_after, scope=db_api.ONE, address=mac_address) if deallocated_mac: return db_api.mac_address_update(context, deallocated_mac, deallocated=False, deallocated_at=None) ranges = db_api.mac_address_range_find_allocation_counts( context, address=mac_address) for result in ranges: rng, addr_count = result if rng["last_address"] - rng["first_address"] <= addr_count: continue next_address = None if mac_address: next_address = mac_address else: address = True while address: next_address = rng["next_auto_assign_mac"] rng["next_auto_assign_mac"] = next_address + 1 address = db_api.mac_address_find( context, tenant_id=context.tenant_id, scope=db_api.ONE, address=next_address) address = db_api.mac_address_create(context, address=next_address, mac_address_range_id=rng["id"]) return address raise exceptions.MacAddressGenerationFailure(net_id=net_id)
def test_delete_mac_with_mac_range_do_not_use(self): macs = lambda mar: db_api.mac_address_find( self.context, mac_address_range_id=mar["id"], scope=db_api.ALL) with self._stubs(do_not_use=True) as mar: self.assertEqual(len(macs(mar)), 1) with self.assertRaises(n_exc_ext.MacAddressGenerationFailure): self.ipam.allocate_mac_address(self.context, 0, 0, 0) self.assertEqual(len(macs(mar)), 0)
def test_delete_mac_with_mac_range_do_not_use(self): macs = lambda mar: db_api.mac_address_find( self.context, mac_address_range_id=mar["id"], scope=db_api.ALL) with self._stubs(do_not_use=True) as mar: self.assertEqual(len(macs(mar)), 1) with self.assertRaises(exceptions.MacAddressGenerationFailure): self.ipam.allocate_mac_address(self.context, 0, 0, 0) self.assertEqual(len(macs(mar)), 0)
def deallocate_mac_address(self, context, address): mac = db_api.mac_address_find(context, address=address, scope=db_api.ONE) if not mac: raise exceptions.NotFound(message="No MAC address %s found" % netaddr.EUI(address)) db_api.mac_address_update(context, mac, deallocated=True, deallocated_at=timeutils.utcnow())
def allocate_mac_address(self, context, net_id, port_id, reuse_after, mac_address=None): if mac_address: mac_address = netaddr.EUI(mac_address).value with context.session.begin(subtransactions=True): deallocated_mac = db_api.mac_address_find( context, lock_mode=True, reuse_after=reuse_after, scope=db_api.ONE, address=mac_address) if deallocated_mac: return db_api.mac_address_update( context, deallocated_mac, deallocated=False, deallocated_at=None) with context.session.begin(subtransactions=True): ranges = db_api.mac_address_range_find_allocation_counts( context, address=mac_address) for result in ranges: rng, addr_count = result last = rng["last_address"] first = rng["first_address"] if last - first <= addr_count: continue next_address = None if mac_address: next_address = mac_address else: address = True while address: next_address = rng["next_auto_assign_mac"] rng["next_auto_assign_mac"] = next_address + 1 address = db_api.mac_address_find( context, tenant_id=context.tenant_id, scope=db_api.ONE, address=next_address) address = db_api.mac_address_create( context, address=next_address, mac_address_range_id=rng["id"]) return address raise exceptions.MacAddressGenerationFailure(net_id=net_id)
def deallocate_mac_address(self, context, address): admin_context = context.elevated() mac = db_api.mac_address_find(admin_context, address=address, scope=db_api.ONE) if not mac: raise exceptions.NotFound( message="No MAC address %s found" % netaddr.EUI(address)) if mac["mac_address_range"]["do_not_use"]: db_api.mac_address_delete(admin_context, mac) else: db_api.mac_address_update(admin_context, mac, deallocated=True, deallocated_at=timeutils.utcnow())
def deallocate_mac_address(self, context, address, **kwargs): admin_context = context.elevated() mac = db_api.mac_address_find(admin_context, address=address, scope=db_api.ONE) if not mac: raise q_exc.MacAddressNotFound( mac_address_id=address, readable_mac=netaddr.EUI(address)) if (mac["mac_address_range"] is None or mac["mac_address_range"]["do_not_use"]): db_api.mac_address_delete(admin_context, mac) else: db_api.mac_address_update(admin_context, mac, deallocated=True, deallocated_at=timeutils.utcnow())
def deallocate_mac_address(self, context, address): admin_context = context.elevated() mac = db_api.mac_address_find(admin_context, address=address, scope=db_api.ONE) if not mac: raise exceptions.NotFound(message="No MAC address %s found" % netaddr.EUI(address)) if mac["mac_address_range"]["do_not_use"]: db_api.mac_address_delete(admin_context, mac) else: db_api.mac_address_update(admin_context, mac, deallocated=True, deallocated_at=timeutils.utcnow())
def allocate_mac_address(self, context, net_id, port_id, reuse_after, mac_address=None): if mac_address: mac_address = netaddr.EUI(mac_address).value for retry in xrange(cfg.CONF.QUARK.mac_address_retry_max): try: with context.session.begin(): deallocated_mac = db_api.mac_address_find( context, lock_mode=True, reuse_after=reuse_after, deallocated=True, scope=db_api.ONE, address=mac_address, order_by="address ASC") if deallocated_mac: return db_api.mac_address_update(context, deallocated_mac, deallocated=False, deallocated_at=None) break except Exception: LOG.exception("Error in mac reallocate...") continue # This could fail if a large chunk of MACs were chosen explicitly, # but under concurrent load enough MAC creates should iterate without # any given thread exhausting its retry count. for retry in xrange(cfg.CONF.QUARK.mac_address_retry_max): next_address = None with context.session.begin(): try: fn = db_api.mac_address_range_find_allocation_counts mac_range = fn(context, address=mac_address) if not mac_range: break rng, addr_count = mac_range last = rng["last_address"] first = rng["first_address"] if (last - first + 1) <= addr_count: # Somehow, the range got filled up without us # knowing, so set the next_auto_assign to be -1 # so we never try to create new ones # in this range rng["next_auto_assign_mac"] = -1 context.session.add(rng) continue if mac_address: next_address = mac_address else: next_address = rng["next_auto_assign_mac"] next_auto = next_address + 1 if next_auto > last: next_auto = -1 db_api.mac_address_range_update( context, rng, next_auto_assign_mac=next_auto) except Exception: LOG.exception("Error in updating mac range") continue # Based on the above, this should only fail if a MAC was # was explicitly chosen at some point. As such, fall through # here and get in line for a new MAC address to try try: with context.session.begin(): address = db_api.mac_address_create( context, address=next_address, mac_address_range_id=rng["id"]) return address except Exception: LOG.exception("Error in creating mac. MAC possibly duplicate") continue raise exceptions.MacAddressGenerationFailure(net_id=net_id)
def allocate_mac_address(self, context, net_id, port_id, reuse_after, mac_address=None): if mac_address: mac_address = netaddr.EUI(mac_address).value kwargs = {"network_id": net_id, "port_id": port_id, "mac_address": mac_address} LOG.info(("Attempting to allocate a new MAC address " "[{0}]").format(utils.pretty_kwargs(**kwargs))) for retry in xrange(CONF.QUARK.mac_address_retry_max): LOG.info("Attemping to reallocate deallocated MAC (step 1 of 3)," " attempt {0} of {1}".format( retry + 1, CONF.QUARK.mac_address_retry_max)) try: with context.session.begin(): deallocated_mac = db_api.mac_address_find( context, lock_mode=True, reuse_after=reuse_after, deallocated=True, scope=db_api.ONE, address=mac_address, order_by="address ASC") if deallocated_mac: dealloc = netaddr.EUI(deallocated_mac["address"]) LOG.info("Found a suitable deallocated MAC {0}".format( str(dealloc))) address = db_api.mac_address_update( context, deallocated_mac, deallocated=False, deallocated_at=None) LOG.info("MAC assignment for port ID {0} completed " "with address {1}".format(port_id, dealloc)) return address break except Exception: LOG.exception("Error in mac reallocate...") continue LOG.info("Couldn't find a suitable deallocated MAC, attempting " "to create a new one") # This could fail if a large chunk of MACs were chosen explicitly, # but under concurrent load enough MAC creates should iterate without # any given thread exhausting its retry count. for retry in xrange(CONF.QUARK.mac_address_retry_max): LOG.info("Attemping to find a range to create a new MAC in " "(step 2 of 3), attempt {0} of {1}".format( retry + 1, CONF.QUARK.mac_address_retry_max)) next_address = None with context.session.begin(): try: fn = db_api.mac_address_range_find_allocation_counts mac_range = fn(context, address=mac_address) if not mac_range: LOG.info("No MAC ranges could be found given " "the criteria") break rng, addr_count = mac_range LOG.info("Found a MAC range {0}".format(rng["cidr"])) last = rng["last_address"] first = rng["first_address"] if (last - first + 1) <= addr_count: # Somehow, the range got filled up without us # knowing, so set the next_auto_assign to be -1 # so we never try to create new ones # in this range rng["next_auto_assign_mac"] = -1 context.session.add(rng) LOG.info("MAC range {0} is full".format(rng["cidr"])) continue if mac_address: next_address = mac_address else: next_address = rng["next_auto_assign_mac"] next_auto = next_address + 1 if next_auto > last: next_auto = -1 db_api.mac_address_range_update( context, rng, next_auto_assign_mac=next_auto) except Exception: LOG.exception("Error in updating mac range") continue # Based on the above, this should only fail if a MAC was # was explicitly chosen at some point. As such, fall through # here and get in line for a new MAC address to try try: mac_readable = str(netaddr.EUI(next_address)) LOG.info("Attempting to create new MAC {0} " "(step 3 of 3)".format(mac_readable)) with context.session.begin(): address = db_api.mac_address_create( context, address=next_address, mac_address_range_id=rng["id"]) LOG.info("MAC assignment for port ID {0} completed with " "address {1}".format(port_id, mac_readable)) return address except Exception: LOG.info("Failed to create new MAC {0}".format(mac_readable)) LOG.exception("Error in creating mac. MAC possibly duplicate") continue raise exceptions.MacAddressGenerationFailure(net_id=net_id)
def allocate_mac_address(self, context, net_id, port_id, reuse_after, mac_address=None): if mac_address: mac_address = netaddr.EUI(mac_address).value for retry in xrange(cfg.CONF.QUARK.mac_address_retry_max): try: with context.session.begin(): deallocated_mac = db_api.mac_address_find( context, lock_mode=True, reuse_after=reuse_after, deallocated=True, scope=db_api.ONE, address=mac_address, order_by="address ASC") if deallocated_mac: return db_api.mac_address_update( context, deallocated_mac, deallocated=False, deallocated_at=None) break except Exception: LOG.exception("Error in mac reallocate...") continue # This could fail if a large chunk of MACs were chosen explicitly, # but under concurrent load enough MAC creates should iterate without # any given thread exhausting its retry count. for retry in xrange(cfg.CONF.QUARK.mac_address_retry_max): next_address = None with context.session.begin(): try: fn = db_api.mac_address_range_find_allocation_counts mac_range = fn(context, address=mac_address) if not mac_range: break rng, addr_count = mac_range last = rng["last_address"] first = rng["first_address"] if (last - first + 1) <= addr_count: # Somehow, the range got filled up without us # knowing, so set the next_auto_assign to be -1 # so we never try to create new ones # in this range rng["next_auto_assign_mac"] = -1 context.session.add(rng) continue if mac_address: next_address = mac_address else: next_address = rng["next_auto_assign_mac"] next_auto = next_address + 1 if next_auto > last: next_auto = -1 db_api.mac_address_range_update( context, rng, next_auto_assign_mac=next_auto) except Exception: LOG.exception("Error in updating mac range") continue # Based on the above, this should only fail if a MAC was # was explicitly chosen at some point. As such, fall through # here and get in line for a new MAC address to try try: with context.session.begin(): address = db_api.mac_address_create( context, address=next_address, mac_address_range_id=rng["id"]) return address except Exception: LOG.exception("Error in creating mac. MAC possibly duplicate") continue raise exceptions.MacAddressGenerationFailure(net_id=net_id)