Esempio n. 1
0
 def _stubs(self, do_not_use):
     self.ipam = quark.ipam.QuarkIpamANY()
     mar = db_api.mac_address_range_create(self.context,
                                           cidr="00:00:00:00:00:00/40",
                                           first_address=0,
                                           last_address=255,
                                           next_auto_assign_mac=6,
                                           do_not_use=do_not_use)
     mac = db_api.mac_address_create(self.context,
                                     address=1,
                                     mac_address_range=mar)
     db_api.mac_address_update(self.context,
                               mac,
                               deallocated=True,
                               deallocated_at=datetime.datetime(1970, 1, 1))
     self.context.session.flush()
     yield mar
Esempio n. 2
0
    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)
Esempio n. 3
0
 def _stubs(self, do_not_use):
     self.ipam = quark.ipam.QuarkIpamANY()
     mar = db_api.mac_address_range_create(
         self.context,
         cidr="00:00:00:00:00:00/40",
         first_address=0, last_address=255,
         next_auto_assign_mac=6,
         do_not_use=do_not_use)
     mac = db_api.mac_address_create(
         self.context,
         address=1,
         mac_address_range=mar)
     db_api.mac_address_update(
         self.context, mac,
         deallocated=True,
         deallocated_at=datetime.datetime(1970, 1, 1))
     self.context.session.flush()
     yield mar
Esempio n. 4
0
    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)
Esempio n. 5
0
    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)
Esempio n. 6
0
File: ipam.py Progetto: roaet/quark
    def allocate_mac_address(self, context, net_id, port_id, reuse_after,
                             mac_address=None,
                             use_forbidden_mac_range=False, **kwargs):
        if mac_address:
            mac_address = netaddr.EUI(mac_address).value

        kwargs.update({"network_id": net_id, "port_id": port_id,
                       "mac_address": mac_address,
                       "use_forbidden_mac_range": use_forbidden_mac_range})
        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():
                    transaction = db_api.transaction_create(context)
                update_kwargs = {
                    "deallocated": False,
                    "deallocated_at": None,
                    "transaction_id": transaction.id
                }
                filter_kwargs = {
                    "deallocated": True,
                }
                if mac_address is not None:
                    filter_kwargs["address"] = mac_address
                if reuse_after is not None:
                    filter_kwargs["reuse_after"] = reuse_after
                elevated = context.elevated()
                result = db_api.mac_address_reallocate(
                    elevated, update_kwargs, **filter_kwargs)
                if not result:
                    break

                reallocated_mac = db_api.mac_address_reallocate_find(
                    elevated, transaction.id)
                if reallocated_mac:
                    dealloc = netaddr.EUI(reallocated_mac["address"])
                    LOG.info("Found a suitable deallocated MAC {0}".format(
                        str(dealloc)))
                    LOG.info("MAC assignment for port ID {0} completed "
                             "with address {1}".format(port_id, dealloc))
                    return reallocated_mac
            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,
                           use_forbidden_mac_range=use_forbidden_mac_range)

                    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
                        db_api.mac_range_update_set_full(context, 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"]
                        if next_address + 1 > rng["last_address"]:
                            db_api.mac_range_update_set_full(context, rng)
                        else:
                            db_api.mac_range_update_next_auto_assign_mac(
                                context, rng)
                        context.session.refresh(rng)
                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 n_exc_ext.MacAddressGenerationFailure(net_id=net_id)
Esempio n. 7
0
    def allocate_mac_address(self, context, net_id, port_id, reuse_after,
                             mac_address=None,
                             use_forbidden_mac_range=False):
        if mac_address:
            mac_address = netaddr.EUI(mac_address).value

        kwargs = {"network_id": net_id, "port_id": port_id,
                  "mac_address": mac_address,
                  "use_forbidden_mac_range": use_forbidden_mac_range}
        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():
                    transaction = db_api.transaction_create(context)
                update_kwargs = {
                    "deallocated": False,
                    "deallocated_at": None,
                    "transaction_id": transaction.id
                }
                filter_kwargs = {
                    "reuse_after": reuse_after,
                    "deallocated": True,
                    "address": mac_address
                }
                elevated = context.elevated()
                result = db_api.mac_address_reallocate(
                    elevated, update_kwargs, **filter_kwargs)
                if not result:
                    break

                reallocated_mac = db_api.mac_address_reallocate_find(
                    elevated, transaction.id)
                if reallocated_mac:
                    dealloc = netaddr.EUI(reallocated_mac["address"])
                    LOG.info("Found a suitable deallocated MAC {0}".format(
                        str(dealloc)))
                    LOG.info("MAC assignment for port ID {0} completed "
                             "with address {1}".format(port_id, dealloc))
                    return reallocated_mac
            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,
                           use_forbidden_mac_range=use_forbidden_mac_range)

                    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
                        db_api.mac_range_update_set_full(context, 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"]
                        if next_address + 1 > rng["last_address"]:
                            db_api.mac_range_update_set_full(context, rng)
                        else:
                            db_api.mac_range_update_next_auto_assign_mac(
                                context, rng)
                        context.session.refresh(rng)
                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)
Esempio n. 8
0
    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)
Esempio n. 9
0
    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)