Example #1
0
    def test_create_and_delete_ports(self):
        tenant_id = 'ten-1'
        network_id = 'net1-id'
        segmentation_id = 1001
        vms = ['vm1', 'vm2', 'vm3']

        network_context = self._get_network_context(tenant_id, network_id,
                                                    segmentation_id)
        self.drv.create_network_precommit(network_context)

        for vm_id in vms:
            port_context = self._get_port_context(tenant_id, network_id, vm_id,
                                                  network_context)
            self.drv.create_port_precommit(port_context)

        vm_list = db.get_vms(tenant_id)
        provisioned_vms = len(vm_list)
        expected_vms = len(vms)
        self.assertEqual(
            expected_vms, provisioned_vms, 'There should be %d '
            'hosts, not %d' % (expected_vms, provisioned_vms))

        # Now test the delete ports
        for vm_id in vms:
            port_context = self._get_port_context(tenant_id, network_id, vm_id,
                                                  network_context)
            self.drv.delete_port_precommit(port_context)

        vm_list = db.get_vms(tenant_id)
        provisioned_vms = len(vm_list)
        expected_vms = 0
        self.assertEqual(
            expected_vms, provisioned_vms, 'There should be %d '
            'VMs, not %d' % (expected_vms, provisioned_vms))
    def test_create_and_delete_ports(self):
        tenant_id = "ten-1"
        network_id = "net1-id"
        segmentation_id = 1001
        vms = ["vm1", "vm2", "vm3"]

        network_context = self._get_network_context(tenant_id, network_id, segmentation_id)
        self.drv.create_network_precommit(network_context)

        for vm_id in vms:
            port_context = self._get_port_context(tenant_id, network_id, vm_id, network_context)
            self.drv.create_port_precommit(port_context)

        vm_list = db.get_vms(tenant_id)
        provisioned_vms = len(vm_list)
        expected_vms = len(vms)
        self.assertEqual(
            expected_vms, provisioned_vms, "There should be %d " "hosts, not %d" % (expected_vms, provisioned_vms)
        )

        # Now test the delete ports
        for vm_id in vms:
            port_context = self._get_port_context(tenant_id, network_id, vm_id, network_context)
            self.drv.delete_port_precommit(port_context)

        vm_list = db.get_vms(tenant_id)
        provisioned_vms = len(vm_list)
        expected_vms = 0
        self.assertEqual(
            expected_vms, provisioned_vms, "There should be %d " "VMs, not %d" % (expected_vms, provisioned_vms)
        )
    def test_create_and_delete_ports(self):
        tenant_id = 'ten-1'
        network_id = 'net1-id'
        segmentation_id = 1001
        vms = ['vm1', 'vm2', 'vm3']

        network_context = self._get_network_context(tenant_id,
                                                    network_id,
                                                    segmentation_id)
        self.drv.create_network_precommit(network_context)

        for vm_id in vms:
            port_context = self._get_port_context(tenant_id,
                                                  network_id,
                                                  vm_id,
                                                  network_context)
            self.drv.create_port_precommit(port_context)

        vm_list = db.get_vms(tenant_id)
        provisioned_vms = len(vm_list)
        expected_vms = len(vms)
        self.assertEqual(expected_vms, provisioned_vms,
                         'There should be %d '
                         'hosts, not %d' % (expected_vms, provisioned_vms))

        # Now test the delete ports
        for vm_id in vms:
            port_context = self._get_port_context(tenant_id,
                                                  network_id,
                                                  vm_id,
                                                  network_context)
            self.drv.delete_port_precommit(port_context)

        vm_list = db.get_vms(tenant_id)
        provisioned_vms = len(vm_list)
        expected_vms = 0
        self.assertEqual(expected_vms, provisioned_vms,
                         'There should be %d '
                         'VMs, not %d' % (expected_vms, provisioned_vms))
    def test_num_vm_is_valid(self):
        tenant_id = "test"
        network_id = "123"
        port_id = 456
        host_id = "ubuntu1"

        vm_to_remember = ["vm1", "vm2", "vm3"]
        vm_to_forget = ["vm2", "vm1"]

        for vm in vm_to_remember:
            db.remember_vm(vm, host_id, port_id, network_id, tenant_id)
        for vm in vm_to_forget:
            db.forget_vm(vm, host_id, port_id, network_id, tenant_id)

        num_vms = len(db.get_vms(tenant_id))
        expected = len(vm_to_remember) - len(vm_to_forget)

        self.assertEqual(expected, num_vms, "There should be %d records, " "got %d records" % (expected, num_vms))
        # clean up afterwards
        db.forget_vm("vm3", host_id, port_id, network_id, tenant_id)
    def test_num_vm_is_valid(self):
        tenant_id = 'test'
        network_id = '123'
        port_id = 456
        host_id = 'ubuntu1'

        vm_to_remember = ['vm1', 'vm2', 'vm3']
        vm_to_forget = ['vm2', 'vm1']

        for vm in vm_to_remember:
            db.remember_vm(vm, host_id, port_id, network_id, tenant_id)
        for vm in vm_to_forget:
            db.forget_vm(vm, host_id, port_id, network_id, tenant_id)

        num_vms = len(db.get_vms(tenant_id))
        expected = len(vm_to_remember) - len(vm_to_forget)

        self.assertEqual(expected, num_vms,
                         'There should be %d records, '
                         'got %d records' % (expected, num_vms))
        # clean up afterwards
        db.forget_vm('vm3', host_id, port_id, network_id, tenant_id)
    def test_num_vm_is_valid(self):
        tenant_id = 'test'
        network_id = '123'
        port_id = 456
        host_id = 'ubuntu1'

        vm_to_remember = ['vm1', 'vm2', 'vm3']
        vm_to_forget = ['vm2', 'vm1']

        for vm in vm_to_remember:
            db.remember_vm(vm, host_id, port_id, network_id, tenant_id)
        for vm in vm_to_forget:
            db.forget_vm(vm, host_id, port_id, network_id, tenant_id)

        num_vms = len(db.get_vms(tenant_id))
        expected = len(vm_to_remember) - len(vm_to_forget)

        self.assertEqual(expected, num_vms,
                         'There should be %d records, '
                         'got %d records' % (expected, num_vms))
        # clean up afterwards
        db.forget_vm('vm3', host_id, port_id, network_id, tenant_id)
Example #7
0
    def synchronize(self):
        """Sends data to EOS which differs from neutron DB."""

        LOG.info(_('Syncing Neutron <-> EOS'))
        try:
            eos_tenants = self._rpc.get_tenants()
        except arista_exc.AristaRpcError:
            msg = _('EOS is not available, will try sync later')
            LOG.warning(msg)
            return

        db_tenants = db.get_tenants()

        if not db_tenants and eos_tenants:
            # No tenants configured in Neutron. Clear all EOS state
            try:
                self._rpc.delete_this_region()
                msg = _('No Tenants configured in Neutron DB. But %d '
                        'tenants disovered in EOS during synchronization.'
                        'Enitre EOS region is cleared') % len(eos_tenants)
            except arista_exc.AristaRpcError:
                msg = _('EOS is not available, failed to delete this region')
            LOG.warning(msg)
            return

        if len(eos_tenants) > len(db_tenants):
            # EOS has extra tenants configured which should not be there.
            for tenant in eos_tenants:
                if tenant not in db_tenants:
                    try:
                        self._rpc.delete_tenant(tenant)
                    except arista_exc.AristaRpcError:
                        msg = _('EOS is not available,'
                                'failed to delete tenant %s') % tenant
                        LOG.warning(msg)
                        return

        # EOS and Neutron has matching set of tenants. Now check
        # to ensure that networks and VMs match on both sides for
        # each tenant.
        for tenant in db_tenants:
            db_nets = db.get_networks(tenant)
            db_vms = db.get_vms(tenant)
            eos_nets = self._get_eos_networks(eos_tenants, tenant)
            eos_vms = self._get_eos_vms(eos_tenants, tenant)

            # Check for the case if everything is already in sync.
            if eos_nets == db_nets:
                # Net list is same in both Neutron and EOS.
                # check the vM list
                if eos_vms == db_vms:
                    # Nothing to do. Everything is in sync for this tenant
                    break

            # Neutron DB and EOS reruires synchronization.
            # First delete anything which should not be EOS
            # delete VMs from EOS if it is not present in neutron DB
            for vm_id in eos_vms:
                if vm_id not in db_vms:
                    try:
                        self._rpc.delete_vm(tenant, vm_id)
                    except arista_exc.AristaRpcError:
                        msg = _('EOS is not available,'
                                'failed to delete vm %s') % vm_id
                        LOG.warning(msg)
                        return

            # delete network from EOS if it is not present in neutron DB
            for net_id in eos_nets:
                if net_id not in db_nets:
                    try:
                        self._rpc.delete_network(tenant, net_id)
                    except arista_exc.AristaRpcError:
                        msg = _('EOS is not available,'
                                'failed to delete network %s') % net_id
                        LOG.warning(msg)
                        return

            # update networks in EOS if it is present in neutron DB
            for net_id in db_nets:
                if net_id not in eos_nets:
                    vlan_id = db_nets[net_id]['segmentationTypeId']
                    net_name = self._ndb.get_network_name(tenant, net_id)
                    try:
                        self._rpc.create_network(tenant, net_id,
                                                 net_name,
                                                 vlan_id)
                    except arista_exc.AristaRpcError:
                        msg = _('EOS is not available, failed to create'
                                'network id %s') % net_id
                        LOG.warning(msg)
                        return

            # Update VMs in EOS if it is present in neutron DB
            for vm_id in db_vms:
                if vm_id not in eos_vms:
                    vm = db_vms[vm_id]
                    ports = self._ndb.get_all_ports_for_vm(tenant, vm_id)
                    for port in ports:
                        port_id = port['id']
                        network_id = port['network_id']
                        port_name = port['name']
                        try:
                            self._rpc.plug_host_into_network(vm['vmId'],
                                                             vm['host'],
                                                             port_id,
                                                             network_id,
                                                             tenant,
                                                             port_name)
                        except arista_exc.AristaRpcError:
                            msg = _('EOS is not available, failed to create'
                                    'vm id %s') % vm['vmId']
                            LOG.warning(msg)
Example #8
0
    def synchronize(self):
        """Sends data to EOS which differs from neutron DB."""

        LOG.info(_('Syncing Neutron <-> EOS'))
        try:
            # Get the time at which entities in the region were updated.
            # If the times match, then ML2 is in sync with EOS. Otherwise
            # perform a complete sync.
            if not self._force_sync and self._rpc.region_in_sync():
                LOG.info(_('OpenStack and EOS are in sync!'))
                return
        except arista_exc.AristaRpcError:
            LOG.warning(EOS_UNREACHABLE_MSG)
            self._force_sync = True
            return

        try:
            #Always register with EOS to ensure that it has correct credentials
            self._rpc.register_with_eos()
            eos_tenants = self._rpc.get_tenants()
        except arista_exc.AristaRpcError:
            LOG.warning(EOS_UNREACHABLE_MSG)
            self._force_sync = True
            return

        db_tenants = db.get_tenants()

        if not db_tenants and eos_tenants:
            # No tenants configured in Neutron. Clear all EOS state
            try:
                self._rpc.delete_this_region()
                msg = _('No Tenants configured in Neutron DB. But %d '
                        'tenants disovered in EOS during synchronization.'
                        'Enitre EOS region is cleared') % len(eos_tenants)
                LOG.info(msg)
                # Re-register with EOS so that the timestamp is updated.
                self._rpc.register_with_eos()
                # Region has been completely cleaned. So there is nothing to
                # syncronize
                self._force_sync = False
            except arista_exc.AristaRpcError:
                LOG.warning(EOS_UNREACHABLE_MSG)
                self._force_sync = True
            return

        # Delete tenants that are in EOS, but not in the database
        tenants_to_delete = frozenset(eos_tenants.keys()).difference(
            db_tenants.keys())

        if tenants_to_delete:
            try:
                self._rpc.delete_tenant_bulk(tenants_to_delete)
            except arista_exc.AristaRpcError:
                LOG.warning(EOS_UNREACHABLE_MSG)
                self._force_sync = True
                return

        # None of the commands have failed till now. But if subsequent
        # operations fail, then force_sync is set to true
        self._force_sync = False

        for tenant in db_tenants:
            db_nets = db.get_networks(tenant)
            db_vms = db.get_vms(tenant)
            eos_nets = self._get_eos_networks(eos_tenants, tenant)
            eos_vms = self._get_eos_vms(eos_tenants, tenant)

            db_nets_key_set = frozenset(db_nets.keys())
            db_vms_key_set = frozenset(db_vms.keys())
            eos_nets_key_set = frozenset(eos_nets.keys())
            eos_vms_key_set = frozenset(eos_vms.keys())

            # Find the networks that are present on EOS, but not in Neutron DB
            nets_to_delete = eos_nets_key_set.difference(db_nets_key_set)

            # Find the VMs that are present on EOS, but not in Neutron DB
            vms_to_delete = eos_vms_key_set.difference(db_vms_key_set)

            # Find the Networks that are present in Neutron DB, but not on EOS
            nets_to_update = db_nets_key_set.difference(eos_nets_key_set)

            # Find the VMs that are present in Neutron DB, but not on EOS
            vms_to_update = db_vms_key_set.difference(eos_vms_key_set)

            try:
                if vms_to_delete:
                    self._rpc.delete_vm_bulk(tenant, vms_to_delete)
                if nets_to_delete:
                    self._rpc.delete_network_bulk(tenant, nets_to_delete)
                if nets_to_update:
                    # Create a dict of networks keyed by id.
                    neutron_nets = dict(
                        (network['id'], network)
                        for network in self._ndb.get_all_networks_for_tenant(
                            tenant))

                    networks = [{
                        'network_id':
                        net_id,
                        'segmentation_id':
                        db_nets[net_id]['segmentationTypeId'],
                        'network_name':
                        neutron_nets.get(net_id, {'name': ''})['name'],
                    } for net_id in nets_to_update]
                    self._rpc.create_network_bulk(tenant, networks)
                if vms_to_update:
                    # Filter the ports to only the vms that we are interested
                    # in.
                    vm_ports = [
                        port
                        for port in self._ndb.get_all_ports_for_tenant(tenant)
                        if port['device_id'] in vms_to_update
                    ]
                    self._rpc.create_vm_port_bulk(tenant, vm_ports, db_vms)
            except arista_exc.AristaRpcError:
                LOG.warning(EOS_UNREACHABLE_MSG)
                self._force_sync = True
Example #9
0
    def synchronize(self):
        """Sends data to EOS which differs from neutron DB."""

        LOG.info(_('Syncing Neutron <-> EOS'))
        try:
            #Always register with EOS to ensure that it has correct credentials
            self._rpc._register_with_eos()
            eos_tenants = self._rpc.get_tenants()
        except arista_exc.AristaRpcError:
            msg = _('EOS is not available, will try sync later')
            LOG.warning(msg)
            return

        db_tenants = db.get_tenants()

        if not db_tenants and eos_tenants:
            # No tenants configured in Neutron. Clear all EOS state
            try:
                self._rpc.delete_this_region()
                msg = _('No Tenants configured in Neutron DB. But %d '
                        'tenants disovered in EOS during synchronization.'
                        'Enitre EOS region is cleared') % len(eos_tenants)
            except arista_exc.AristaRpcError:
                msg = _('EOS is not available, failed to delete this region')
            LOG.warning(msg)
            return

        # EOS and Neutron has matching set of tenants. Now check
        # to ensure that networks and VMs match on both sides for
        # each tenant.
        for tenant in eos_tenants.keys():
            if tenant not in db_tenants:
                #send delete tenant to EOS
                try:
                    self._rpc.delete_tenant(tenant)
                    del eos_tenants[tenant]
                except arista_exc.AristaRpcError:
                    msg = _('EOS is not available, '
                            'failed to delete tenant %s') % tenant
                    LOG.warning(msg)

        for tenant in db_tenants:
            db_nets = db.get_networks(tenant)
            db_vms = db.get_vms(tenant)
            eos_nets = self._get_eos_networks(eos_tenants, tenant)
            eos_vms = self._get_eos_vms(eos_tenants, tenant)

            # Check for the case if everything is already in sync.
            if eos_nets == db_nets:
                # Net list is same in both Neutron and EOS.
                # check the vM list
                if eos_vms == db_vms:
                    # Nothing to do. Everything is in sync for this tenant
                    continue

            # Neutron DB and EOS reruires synchronization.
            # First delete anything which should not be EOS
            # delete VMs from EOS if it is not present in neutron DB
            for vm_id in eos_vms:
                if vm_id not in db_vms:
                    try:
                        self._rpc.delete_vm(tenant, vm_id)
                    except arista_exc.AristaRpcError:
                        msg = _('EOS is not available,'
                                'failed to delete vm %s') % vm_id
                        LOG.warning(msg)

            # delete network from EOS if it is not present in neutron DB
            for net_id in eos_nets:
                if net_id not in db_nets:
                    try:
                        self._rpc.delete_network(tenant, net_id)
                    except arista_exc.AristaRpcError:
                        msg = _('EOS is not available,'
                                'failed to delete network %s') % net_id
                        LOG.warning(msg)

            # update networks in EOS if it is present in neutron DB
            for net_id in db_nets:
                if net_id not in eos_nets:
                    vlan_id = db_nets[net_id]['segmentationTypeId']
                    net_name = self._ndb.get_network_name(tenant, net_id)
                    try:
                        self._rpc.create_network(tenant, net_id, net_name,
                                                 vlan_id)
                    except arista_exc.AristaRpcError:
                        msg = _('EOS is not available, failed to create'
                                'network id %s') % net_id
                        LOG.warning(msg)

            # Update VMs in EOS if it is present in neutron DB
            for vm_id in db_vms:
                if vm_id not in eos_vms:
                    vm = db_vms[vm_id]
                    ports = self._ndb.get_all_ports_for_vm(tenant, vm_id)
                    for port in ports:
                        port_id = port['id']
                        net_id = port['network_id']
                        port_name = port['name']
                        device_owner = port['device_owner']
                        vm_id = vm['vmId']
                        host_id = vm['host']
                        try:
                            self._rpc.plug_port_into_network(
                                vm_id, host_id, port_id, net_id, tenant,
                                port_name, device_owner)
                        except arista_exc.AristaRpcError:
                            msg = _('EOS is not available, failed to create '
                                    'vm id %s') % vm['vmId']
                            LOG.warning(msg)
Example #10
0
    def synchronize(self):
        """Sends data to EOS which differs from neutron DB."""

        LOG.info(_('Syncing Neutron <-> EOS'))
        try:
            # Get the time at which entities in the region were updated.
            # If the times match, then ML2 is in sync with EOS. Otherwise
            # perform a complete sync.
            if not self._force_sync and self._rpc.region_in_sync():
                LOG.info(_('OpenStack and EOS are in sync!'))
                return
        except arista_exc.AristaRpcError:
            LOG.warning(EOS_UNREACHABLE_MSG)
            self._force_sync = True
            return

        try:
            #Always register with EOS to ensure that it has correct credentials
            self._rpc.register_with_eos()
            eos_tenants = self._rpc.get_tenants()
        except arista_exc.AristaRpcError:
            LOG.warning(EOS_UNREACHABLE_MSG)
            self._force_sync = True
            return

        db_tenants = db.get_tenants()

        if not db_tenants and eos_tenants:
            # No tenants configured in Neutron. Clear all EOS state
            try:
                self._rpc.delete_this_region()
                msg = _('No Tenants configured in Neutron DB. But %d '
                        'tenants disovered in EOS during synchronization.'
                        'Enitre EOS region is cleared') % len(eos_tenants)
                LOG.info(msg)
                # Re-register with EOS so that the timestamp is updated.
                self._rpc.register_with_eos()
                # Region has been completely cleaned. So there is nothing to
                # syncronize
                self._force_sync = False
            except arista_exc.AristaRpcError:
                LOG.warning(EOS_UNREACHABLE_MSG)
                self._force_sync = True
            return

        # Delete tenants that are in EOS, but not in the database
        tenants_to_delete = frozenset(eos_tenants.keys()).difference(
            db_tenants.keys())

        if tenants_to_delete:
            try:
                self._rpc.delete_tenant_bulk(tenants_to_delete)
            except arista_exc.AristaRpcError:
                LOG.warning(EOS_UNREACHABLE_MSG)
                self._force_sync = True
                return

        # None of the commands have failed till now. But if subsequent
        # operations fail, then force_sync is set to true
        self._force_sync = False

        for tenant in db_tenants:
            db_nets = db.get_networks(tenant)
            db_vms = db.get_vms(tenant)
            eos_nets = self._get_eos_networks(eos_tenants, tenant)
            eos_vms = self._get_eos_vms(eos_tenants, tenant)

            db_nets_key_set = frozenset(db_nets.keys())
            db_vms_key_set = frozenset(db_vms.keys())
            eos_nets_key_set = frozenset(eos_nets.keys())
            eos_vms_key_set = frozenset(eos_vms.keys())

            # Find the networks that are present on EOS, but not in Neutron DB
            nets_to_delete = eos_nets_key_set.difference(db_nets_key_set)

            # Find the VMs that are present on EOS, but not in Neutron DB
            vms_to_delete = eos_vms_key_set.difference(db_vms_key_set)

            # Find the Networks that are present in Neutron DB, but not on EOS
            nets_to_update = db_nets_key_set.difference(eos_nets_key_set)

            # Find the VMs that are present in Neutron DB, but not on EOS
            vms_to_update = db_vms_key_set.difference(eos_vms_key_set)

            try:
                if vms_to_delete:
                    self._rpc.delete_vm_bulk(tenant, vms_to_delete)
                if nets_to_delete:
                    self._rpc.delete_network_bulk(tenant, nets_to_delete)
                if nets_to_update:
                    # Create a dict of networks keyed by id.
                    neutron_nets = dict(
                        (network['id'], network) for network in
                        self._ndb.get_all_networks_for_tenant(tenant)
                    )

                    networks = [
                        {'network_id': net_id,
                         'segmentation_id':
                            db_nets[net_id]['segmentationTypeId'],
                         'network_name':
                            neutron_nets.get(net_id, {'name': ''})['name'], }
                        for net_id in nets_to_update
                    ]
                    self._rpc.create_network_bulk(tenant, networks)
                if vms_to_update:
                    # Filter the ports to only the vms that we are interested
                    # in.
                    vm_ports = [
                        port for port in self._ndb.get_all_ports_for_tenant(
                            tenant) if port['device_id'] in vms_to_update
                    ]
                    self._rpc.create_vm_port_bulk(tenant, vm_ports, db_vms)
            except arista_exc.AristaRpcError:
                LOG.warning(EOS_UNREACHABLE_MSG)
                self._force_sync = True