Exemplo n.º 1
0
    def synchronize(self):
        LOG.info(_LI('Syncing VLANs with EOS'))
        try:
            self._rpc.register_with_eos()
            vlan_pool = self._rpc.get_vlan_allocation()
        except arista_exc.AristaRpcError:
            LOG.warning(EOS_UNREACHABLE_MSG)
            self._force_sync = True
            return

        self._assigned_vlans = {
            'default':
            self._parse_vlan_ranges(vlan_pool['assignedVlans'],
                                    return_as_ranges=True),
        }

        assigned_vlans = (self._parse_vlan_ranges(vlan_pool['assignedVlans']))
        available_vlans = frozenset(
            self._parse_vlan_ranges(vlan_pool['availableVlans']))
        used_vlans = frozenset(
            self._parse_vlan_ranges(vlan_pool['allocatedVlans']))

        self._force_sync = False

        session = db_api.get_writer_session()
        with session.begin(subtransactions=True):
            allocs = (session.query(
                vlanallocation.VlanAllocation).with_lockmode('update'))

            for alloc in allocs:
                if alloc.physical_network != 'default':
                    session.delete(alloc)

                try:
                    assigned_vlans.remove(alloc.vlan_id)
                except KeyError:
                    session.delete(alloc)
                    continue

                if alloc.allocated and alloc.vlan_id in available_vlans:
                    alloc.update({"allocated": False})
                elif not alloc.allocated and alloc.vlan_id in used_vlans:
                    alloc.update({"allocated": True})

            for vlan_id in sorted(assigned_vlans):
                allocated = vlan_id in used_vlans
                alloc = vlanallocation.VlanAllocation(
                    physical_network='default',
                    vlan_id=vlan_id,
                    allocated=allocated)
                session.add(alloc)
Exemplo n.º 2
0
    def _sync_vlan_allocations(self):
        ctx = context.get_admin_context()
        with db_api.context_manager.writer.using(ctx):
            # get existing allocations for all physical networks
            allocations = dict()
            allocs = ctx.session.query(vlan_alloc_model.VlanAllocation)
            for alloc in allocs:
                if alloc.physical_network not in allocations:
                    allocations[alloc.physical_network] = set()
                allocations[alloc.physical_network].add(alloc)

            # process vlan ranges for each configured physical network
            for (physical_network,
                 vlan_ranges) in self.network_vlan_ranges.items():
                # determine current configured allocatable vlans for
                # this physical network
                vlan_ids = set()
                for vlan_min, vlan_max in vlan_ranges:
                    vlan_ids |= set(moves.range(vlan_min, vlan_max + 1))

                # remove from table unallocated vlans not currently
                # allocatable
                if physical_network in allocations:
                    for alloc in allocations[physical_network]:
                        try:
                            # see if vlan is allocatable
                            vlan_ids.remove(alloc.vlan_id)
                        except KeyError:
                            # it's not allocatable, so check if its allocated
                            if not alloc.allocated:
                                # it's not, so remove it from table
                                LOG.debug(
                                    "Removing vlan %(vlan_id)s on "
                                    "physical network "
                                    "%(physical_network)s from pool", {
                                        'vlan_id': alloc.vlan_id,
                                        'physical_network': physical_network
                                    })
                                # This UPDATE WHERE statement blocks anyone
                                # from concurrently changing the allocation
                                # values to True while our transaction is
                                # open so we don't accidentally delete
                                # allocated segments. If someone has already
                                # allocated, count will return 0 so we don't
                                # delete.
                                count = allocs.filter_by(
                                    allocated=False,
                                    vlan_id=alloc.vlan_id,
                                    physical_network=physical_network).update(
                                        {"allocated": False})
                                if count:
                                    ctx.session.delete(alloc)
                    del allocations[physical_network]

                # add missing allocatable vlans to table
                for vlan_id in sorted(vlan_ids):
                    alloc = vlan_alloc_model.VlanAllocation(
                        physical_network=physical_network,
                        vlan_id=vlan_id,
                        allocated=False)
                    ctx.session.add(alloc)

            # remove from table unallocated vlans for any unconfigured
            # physical networks
            for allocs in allocations.values():
                for alloc in allocs:
                    if not alloc.allocated:
                        LOG.debug(
                            "Removing vlan %(vlan_id)s on physical "
                            "network %(physical_network)s from pool", {
                                'vlan_id': alloc.vlan_id,
                                'physical_network': alloc.physical_network
                            })
                        ctx.session.delete(alloc)
Exemplo n.º 3
0
    def _sync_vlan_allocations(self):
        ctx = context.get_admin_context()
        with db_api.context_manager.writer.using(ctx):
            # get existing allocations for all physical networks
            allocations = dict()
            allocs = (ctx.session.query(
                vlan_alloc_model.VlanAllocation).with_lockmode('update'))
            for alloc in allocs:
                if alloc.physical_network not in allocations:
                    allocations[alloc.physical_network] = set()
                allocations[alloc.physical_network].add(alloc)

            # process vlan ranges for each configured physical network
            for (physical_network,
                 vlan_ranges) in self.network_vlan_ranges.items():
                # determine current configured allocatable vlans for
                # this physical network
                vlan_ids = set()
                for vlan_min, vlan_max in vlan_ranges:
                    vlan_ids |= set(moves.range(vlan_min, vlan_max + 1))

                # remove from table unallocated vlans not currently
                # allocatable
                if physical_network in allocations:
                    for alloc in allocations[physical_network]:
                        try:
                            # see if vlan is allocatable
                            vlan_ids.remove(alloc.vlan_id)
                        except KeyError:
                            # it's not allocatable, so check if its allocated
                            if not alloc.allocated:
                                # it's not, so remove it from table
                                LOG.debug(
                                    "Removing vlan %(vlan_id)s on "
                                    "physical network "
                                    "%(physical_network)s from pool", {
                                        'vlan_id': alloc.vlan_id,
                                        'physical_network': physical_network
                                    })
                                ctx.session.delete(alloc)
                    del allocations[physical_network]

                # add missing allocatable vlans to table
                for vlan_id in sorted(vlan_ids):
                    alloc = vlan_alloc_model.VlanAllocation(
                        physical_network=physical_network,
                        vlan_id=vlan_id,
                        allocated=False)
                    ctx.session.add(alloc)

            # remove from table unallocated vlans for any unconfigured
            # physical networks
            for allocs in allocations.values():
                for alloc in allocs:
                    if not alloc.allocated:
                        LOG.debug(
                            "Removing vlan %(vlan_id)s on physical "
                            "network %(physical_network)s from pool", {
                                'vlan_id': alloc.vlan_id,
                                'physical_network': alloc.physical_network
                            })
                        ctx.session.delete(alloc)