Пример #1
0
    def _delete(self, models, options):
        index_names = [index._name for index in registry.get_indices(models)]

        if not options["force"]:
            response = input(
                "Are you sure you want to delete "
                "the '{}' indexes? [y/N]: ".format(", ".join(index_names))
            )
            if response.lower() != "y":
                self.stdout.write("Aborted")
                return False

        for index in registry.get_indices(models):
            doc = index._doc_types[0]
            if getattr(doc, "time_based", None):
                self.stdout.write(
                    "Deletion of time-based indices is not supported yet,"
                    "delete the index '{}' directly using the Elasticseach deletion API".format(
                        index._name
                    )
                )
            else:
                self.stdout.write("Deleting index '{}'".format(index._name))
                index.delete(ignore=404)
        return True
Пример #2
0
    def test_handle(self, elasticsearch_dsl_default_connection):
        """ Verify the command removes all but the newest indexes. """

        # Use now as initial time, so indexes are created AFTER the current index so expected values are accurate
        initial_time = datetime.datetime.now()
        # Create 2 more indexes than we expect to exist after removal
        for number in range(
                1, settings.ELASTICSEARCH_DSL_INDEX_RETENTION_LIMIT + 2):
            current_time = initial_time + datetime.timedelta(seconds=number)
            freezer = freeze_time(current_time)
            freezer.start()
            for index in registry.get_indices():
                ElasticsearchUtils.create_index(index)
            freezer.stop()

        # Prune indexes and confirm the right indexes are removed
        call_command('remove_unused_indexes')
        indices_client = elasticsearch_dsl_default_connection.indices
        for index in registry.get_indices():
            # pylint: disable=protected-access
            index_alias = ElasticsearchUtils.get_alias_by_index_name(
                index._name)
            current_alias = indices_client.get_alias(name=index_alias)
            indexes_to_keep = current_alias.keys()

            # check that we keep the current indexes, which we don't want removed
            all_indexes = self.get_current_index_names(
                indices_client=indices_client, index_prefix=index_alias)
            assert set(all_indexes).issuperset(set(indexes_to_keep))

            # check that other indexes are removed, excepting those that don't hit the retention limit
            expected_count = settings.ELASTICSEARCH_DSL_INDEX_RETENTION_LIMIT + len(
                indexes_to_keep)
            assert len(all_indexes) == expected_count

        # Attempt to prune indexes again and confirm that no indexes are removed
        call_command('remove_unused_indexes')

        for index in registry.get_indices():
            # check that we keep the current indexes, which we don't want removed
            # pylint: disable=protected-access
            index_alias = ElasticsearchUtils.get_alias_by_index_name(
                index._name)
            all_indexes = self.get_current_index_names(
                indices_client=indices_client, index_prefix=index_alias)
            current_alias = indices_client.get_alias(name=index_alias)
            indexes_to_keep = current_alias.keys()
            assert set(all_indexes).issuperset(set(indexes_to_keep))

            # check that index count remains the same as before
            expected_count = settings.ELASTICSEARCH_DSL_INDEX_RETENTION_LIMIT + len(
                indexes_to_keep)
            assert len(all_indexes) == expected_count

        # Cleanup indexes created by this test
        for index in registry.get_indices():
            # pylint: disable=protected-access
            indices_client.delete(index=index._name + '_*')
Пример #3
0
    def _delete(self, models, options):
        index_names = [str(index) for index in registry.get_indices(models)]

        if not options['force']:
            response = input("Are you sure you want to delete "
                             "the '{}' indexes? [n/Y]: ".format(
                                 ", ".join(index_names)))
            if response.lower() != 'y':
                self.stdout.write('Aborted')
                return False

        for index in registry.get_indices(models):
            self.stdout.write("Deleting index '{}'".format(index))
            index.delete(ignore=404)
        return True
Пример #4
0
    def run_tests(self, test_labels, extra_tests=None, **kwargs):
        logging.disable(logging.CRITICAL)
        test_settings = {
            'AWS_STORAGE_BUCKET_NAME': TEST_BUCKET_NAME,
            'ELASTICSEARCH_DSL_AUTOSYNC': False,
        }
        test_settings.update(get_redis_test_settings())
        with override_settings(**test_settings):
            redis_client = get_redis_connection()

            # prepare test bucket

            bucket = default_storage.bucket
            bucket.objects.delete()

            # create test indices

            for index in registry.get_indices():
                index._name = f'test-{index._name}'
            try:
                call_command('search_index', '--create', '-f')
            except RequestError:
                call_command('search_index', '--delete', '-f')
                call_command('search_index', '--create', '-f')

            # run tests and make cleanup

            try:
                return super().run_tests(test_labels, extra_tests, **kwargs)
            finally:
                redis_client.flushdb()
                bucket.objects.delete()
                call_command('search_index', '--delete', '-f')
Пример #5
0
    def handle_rebuild(self, models, options, connection):
        """
        Rebuild Elasticsearch indices.

        Args:
            models: An iterable with model classes.
            options: The command line options.
            connection: The Elasticsearch connection.
        """
        index_names = [str(index) for index in registry.get_indices(models)]

        if options['current']:
            raise CommandError('Using the --current option is not supported with rebuild.')

        if not options['force']:
            answer = input("Are you sure you want to rebuild indices '{}'? [n/Y]: ".format(", ".join(index_names)))
            if answer.lower() != 'y':
                self.stdout.write('Aborted')
                return False

        self.handle_create(models, options, connection)
        self.handle_populate(models, options, connection)
        self.handle_list(models, options, connection)
        self.handle_autoalias(models, options, connection)
        self.handle_cleanup(models, options, connection)
Пример #6
0
    def handle_rebuild(self, models, options, connection):
        """
        Rebuild Elasticsearch indices.

        Args:
            models: An iterable with model classes.
            options: The command line options.
            connection: The Elasticsearch connection.
        """
        index_names = [str(index) for index in registry.get_indices(models)]

        if options['current']:
            raise CommandError(
                'Using the --current option is not supported with rebuild.')

        if not options['force']:
            answer = input(
                "Are you sure you want to rebuild indices '{}'? [n/Y]: ".
                format(", ".join(index_names)))
            if answer.lower() != 'y':
                self.stdout.write('Aborted')
                return False

        self.handle_create(models, options, connection)
        self.handle_populate(models, options, connection)
        self.handle_list(models, options, connection)
        self.handle_autoalias(models, options, connection)
        self.handle_cleanup(models, options, connection)
Пример #7
0
    def handle_cleanup(self, models, options, connection):
        """
        Delete any inactive indices for the given models.

        Args:
            models: The models to show the indices for.
            options: The command line options.
            connection: The Elasticsearch connection.
        """
        for index in registry.get_indices(models):
            indices = connection.indices.get('{}.*'.format(index))

            if indices:
                old_indices = [
                    name for name, body in indices.items()
                    if str(index) not in body.get('aliases', {})
                ]

                if old_indices:
                    self.stdout.write("Deleting old indices: {}".format(
                        ', '.join(old_indices)))
                    connection.indices.delete(index=','.join(old_indices))
                else:
                    self.stdout.write(
                        "No old indices found for {}".format(index))
            else:
                self.stdout.write('No indices for \'{}\''.format(index))
    def handle(self, *args, **options):
        self.stdout.write("# Running migrations")
        call_command("migrate")

        self.stdout.write("# Site settings")
        site = Site.objects.get_current()
        site.name = settings.SITE_NAME
        site.domain = settings.REAL_HOST
        site.save()
        Site.objects.clear_cache()

        if settings.ELASTICSEARCH_ENABLED:
            self.stdout.write("# Creating elasticsearch indices")
            # The logic comes from django_elasticsearch_dsl.managment.commands.search_index:_create
            for index in registry.get_indices(registry.get_models()):
                # noinspection PyProtectedMember
                self.stdout.write(
                    f"Creating elasticsearch index '{index._name}' if not exists"
                )
                # https://elasticsearch-py.readthedocs.io/en/master/api.html:
                # "ignore 400 cause by IndexAlreadyExistsException when creating an index"
                # See also https://github.com/elastic/elasticsearch/issues/19862
                index.create(ignore=400)
        else:
            self.stdout.write(
                "# Elasticsearch is disabled; Not creating any indices")

        # This is more brittle, so we run it last
        self.stdout.write("# Creating minio buckets")
        setup_minio()
        logger.info("Setup successful")
    def test_create_index(self):
        """ Verify the app sets the alias and creates a new index. """
        for index in registry.get_indices():
            # pylint: disable=protected-access
            index_alias = index.get_alias()
            index_name, *_ = index_alias.keys()
            index._name = index_name
            self.es.indices.delete(index=index._name, ignore=404)
            assert not self.es.indices.exists(index=index._name)

        call_command('install_es_indexes')

        # Verify the index was created
        for index in registry.get_indices():
            # pylint: disable=protected-access
            assert self.es.indices.exists(index=index._name)
Пример #10
0
    def refresh_index(self):
        """
        Refreshes an index.

        https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-refresh.html
        """
        for index in registry.get_indices():
            ElasticsearchUtils.refresh_index(self.es, index._name)  # pylint: disable=protected-access
Пример #11
0
    def _delete(self, models, options):
        # pylint: disable=protected-access
        index_names = [index._name for index in registry.get_indices(models)]
        if not options['force']:
            response = input("Are you sure you want to delete "
                             "the '{}' indexes? [y/N]: ".format(
                                 ", ".join(index_names)))
            if response.lower() != 'y':
                self.stdout.write('Aborted')
                return False

        for index in registry.get_indices(models):
            try:
                index_alias = index.get_alias()
            except NotFoundError:
                continue
            index_name, *_ = index_alias.keys()
            index._name = index_name
            self.stdout.write("Deleting index '{}'".format(index._name))
            index.delete(ignore=404)
        return True
    def test_alias_exists(self):
        """ Verify the app does not setup a new Elasticsearch index if the alias is already set. """
        # pylint: disable=protected-access
        index_names = [index._name for index in registry.get_indices()]
        for index_name in index_names:
            # Verify the index exists
            assert self.es.indices.exists(index=index_name)

        call_command('install_es_indexes')
        for index_name in index_names:
            # Verify the index still exists
            assert self.es.indices.exists(index=index_name)
    def handle(self, *args, **options):
        for backend_name, host_cong in settings.ELASTICSEARCH_DSL.items():
            logger.info(
                'Attempting to establish initial connection to Elasticsearch host [%s]...',
                host_cong['hosts'])
            es_connection = get_connection(backend_name)
            es_connection.ping()
            logger.info('...success!')

            for index in registry.get_indices():
                ElasticsearchUtils.create_alias_and_index(
                    es_connection, index, backend_name)
Пример #14
0
 def _create(self, models, options):
     for backend in self.backends:
         for index in registry.get_indices(models):
             created_index_info = ElasticsearchUtils.create_index(
                 index, backend)
             es_connection = get_connection(backend)
             self.stdout.write(
                 'Creating index "{1}".\nSet alias "{0}" for index "{1}".'.
                 format(created_index_info.alias, created_index_info.name))
             ElasticsearchUtils.set_alias(es_connection,
                                          created_index_info.alias,
                                          created_index_info.name)
def test_index_deletion():
    """Check that deleted persons get deleted from the elasticsearch index"""
    for index in registry.get_indices(registry.get_models()):
        index.delete(ignore=404)
    for index in registry.get_indices(registry.get_models()):
        index.create()

    old_persons = [
        Person(name="Frank Underwood", party="Democrats"),
        Person(name="Claire Underwood", party="Democrats"),
    ]
    new_persons = [Person(name="Claire Underwood", party="Democrats")]

    old = RisData(sample_city, None, old_persons, [], [], [], [], [], [], 2)
    new = RisData(sample_city, None, new_persons, [], [], [], [], [], [], 2)
    body = Body(name=old.meta.name, short_name=old.meta.name, ags=old.meta.ags)
    body.save()

    import_data(body, old)
    assert len(MainappSearch({"query": "Underwood"}).execute().hits) == 2
    import_data(body, new)
    assert len(MainappSearch({"query": "Underwood"}).execute().hits) == 1
Пример #16
0
    def handle_create(self, models, options, connection):
        """
        Create new indices and point the aliases to them.

        Args:
            models: An iterable with model classes.
            options: A dict with command line options.
            connection: The Elasticsearch connection.
        """
        for index in registry.get_indices(models):
            index_name = '{}.{}'.format(index, int(time.time()))
            self.stdout.write("Creating index '{}'".format(index_name))
            connection.indices.create(index=index_name, body=index.to_dict())
Пример #17
0
    def handle_create(self, models, options, connection):
        """
        Create new indices and point the aliases to them.

        Args:
            models: An iterable with model classes.
            options: A dict with command line options.
            connection: The Elasticsearch connection.
        """
        for index in registry.get_indices(models):
            index_name = '{}.{}'.format(index, int(time.time()))
            self.stdout.write("Creating index '{}'".format(index_name))
            connection.indices.create(index=index_name, body=index.to_dict())
Пример #18
0
    def handle_delete(self, models, options, connection):
        """
        Delete the current indices for the given models.

        Args:
            models: An iterable with model classes.
            options: The command line options.
            connection: The Elasticsearch connection.
        """
        index_names = [str(index) for index in registry.get_indices(models)]

        if not options['force']:
            response = input(
                "Are you sure you want to delete the '{}' indices? [n/Y]: ".format(", ".join(index_names))
            )
            if response.lower() != 'y':
                self.stdout.write('Aborted.')
                return False

        for index in registry.get_indices(models):
            self.stdout.write("Deleting index '{}'".format(index))
            connection.indices.delete('{}.*'.format(index), ignore=404)
            connection.indices.delete(str(index), ignore=404)
Пример #19
0
    def handle_delete(self, models, options, connection):
        """
        Delete the current indices for the given models.

        Args:
            models: An iterable with model classes.
            options: The command line options.
            connection: The Elasticsearch connection.
        """
        index_names = [str(index) for index in registry.get_indices(models)]

        if not options['force']:
            response = input(
                "Are you sure you want to delete the '{}' indices? [n/Y]: ".
                format(", ".join(index_names)))
            if response.lower() != 'y':
                self.stdout.write('Aborted.')
                return False

        for index in registry.get_indices(models):
            self.stdout.write("Deleting index '{}'".format(index))
            connection.indices.delete('{}.*'.format(index), ignore=404)
            connection.indices.delete(str(index), ignore=404)
Пример #20
0
 def _create(self, models, options):
     for index in registry.get_indices(models):
         doc = index._doc_types[0]
         if getattr(doc, "time_based", None):
             self._check_pipeline_ilm()
             mapping = doc._doc_type.mapping.to_dict()
             self._check_index_settings(index)
             self._check_index_mappings(index, mapping)
             self._check_index_template(index)
         else:
             try:
                 self.stdout.write(f"Creating index '{index._name}'")
                 index.create()
             except RequestError:
                 self.stdout.write(f"Index '{index._name}' already exists")
Пример #21
0
    def handle_autoalias(self, models, options, connection):
        """
        Update the aliases to point to the latest index.

        Args:
            models: An iterable with model classes.
            options: A dict with command line options.
            connection: The Elasticsearch connection.
        """
        for index in registry.get_indices(models):
            indices = connection.indices.get('{}.*'.format(index))
            index_names = indices.keys()
            index_names.sort()
            last_index = index_names[-1]

            self.stdout.write("Pointing alias '{}' to '{}'".format(last_index, index))
            connection.indices.delete_alias(name=index, index='*', ignore=404)
            connection.indices.put_alias(index=last_index, name=index)
Пример #22
0
def switch_es_index(app_label, model_name, index_name, new_index_name):
    model = apps.get_model(app_label, model_name)
    indices = registry.get_indices(models=[model])
    old_index = _get_index(indices=indices, index_name=index_name)
    new_index = old_index.clone(name=new_index_name)
    old_index_actual_name = None

    if old_index.exists():
        # Alias can not be used to delete an index.
        # https://www.elastic.co/guide/en/elasticsearch/reference/6.0/indices-delete-index.html
        # So get the index actual name to delete it
        old_index_info = old_index.get()
        # The info is a dictionary and the key is the actual name of the index
        old_index_actual_name = list(old_index_info.keys())[0]

    # Put alias into the new index name and delete the old index if its exist
    new_index.put_alias(name=index_name)
    if old_index_actual_name:
        old_index.connection.indices.delete(index=old_index_actual_name)
Пример #23
0
def switch_es_index(app_label, model_name, index_name, new_index_name):
    model = apps.get_model(app_label, model_name)
    indices = registry.get_indices(models=[model])
    old_index = _get_index(indices=indices, index_name=index_name)
    new_index = old_index.clone(name=new_index_name)
    old_index_actual_name = None

    if old_index.exists():
        # Alias can not be used to delete an index.
        # https://www.elastic.co/guide/en/elasticsearch/reference/6.0/indices-delete-index.html
        # So get the index actual name to delete it
        old_index_info = old_index.get()
        # The info is a dictionary and the key is the actual name of the index
        old_index_actual_name = list(old_index_info.keys())[0]

    # Put alias into the new index name and delete the old index if its exist
    new_index.put_alias(name=index_name)
    if old_index_actual_name:
        old_index.connection.indices.delete(index=old_index_actual_name)
Пример #24
0
    def handle_autoalias(self, models, options, connection):
        """
        Update the aliases to point to the latest index.

        Args:
            models: An iterable with model classes.
            options: A dict with command line options.
            connection: The Elasticsearch connection.
        """
        for index in registry.get_indices(models):
            indices = connection.indices.get('{}.*'.format(index))
            index_names = indices.keys()
            index_names.sort()
            last_index = index_names[-1]

            self.stdout.write("Pointing alias '{}' to '{}'".format(
                last_index, index))
            connection.indices.delete_alias(name=index, index='*', ignore=404)
            connection.indices.put_alias(index=last_index, name=index)
Пример #25
0
def pytest_runtest_setup(item):
    from django_elasticsearch_dsl.registries import registry
    from mcod.core.api.rdf.registry import registry as rdf_registry
    import random
    import string

    es_marker = item.get_closest_marker('elasticsearch')

    if es_marker:
        for index in registry.get_indices():
            index.delete(ignore=404)
            index.settings(**settings.ELASTICSEARCH_DSL_INDEX_SETTINGS)
            index.create()

    sparql_marker = item.get_closest_marker('sparql')
    if sparql_marker:
        chars = string.ascii_uppercase + string.ascii_lowercase
        graph_name = ''.join(random.choice(chars) for _ in range(18))
        graph_uri = f'<http://test.mcod/{graph_name}>'
        rdf_registry.create_named_graph(graph_uri)
Пример #26
0
 def handle(self, *args, **options):
     self.stdout.write("Running migrations")
     call_command("migrate")
     self.stdout.write("Creating minio buckets")
     setup_minio()
     if settings.ELASTICSEARCH_ENABLED:
         self.stdout.write("Creating elasticsearch indices")
         # The logic comes from django_elasticsearch_dsl.managment.commands.search_index:_create
         for index in registry.get_indices(registry.get_models()):
             self.stdout.write(
                 "Creating elasticsearch index '{}' if not exists".format(
                     index._name
                 )
             )
             # https://elasticsearch-py.readthedocs.io/en/master/api.html:
             # "ignore 400 cause by IndexAlreadyExistsException when creating an index"
             # See also https://github.com/elastic/elasticsearch/issues/19862
             index.create(ignore=400)
     else:
         self.stdout.write("Elasticsearch is disabled; Not creating any indices")
Пример #27
0
    def handle_cleanup(self, models, options, connection):
        """
        Delete any inactive indices for the given models.

        Args:
            models: The models to show the indices for.
            options: The command line options.
            connection: The Elasticsearch connection.
        """
        for index in registry.get_indices(models):
            indices = connection.indices.get('{}.*'.format(index))

            if indices:
                old_indices = [name for name, body in indices.items() if str(index) not in body.get('aliases', {})]

                if old_indices:
                    self.stdout.write("Deleting old indices: {}".format(', '.join(old_indices)))
                    connection.indices.delete(index=','.join(old_indices))
                else:
                    self.stdout.write("No old indices found for {}".format(index))
            else:
                self.stdout.write('No indices for \'{}\''.format(index))
Пример #28
0
    def handle_list(self, models, options, connection):
        """
        List the current Elasticsearch indices.

        Args:
            models: The models to show the indices for.
            options: The command line options.
            connection: The Elasticsearch connection.
        """
        for index in registry.get_indices(models):
            indices = connection.indices.get('{}.*'.format(index))

            if indices:
                active_index = None
                for index_name, index_body in indices.items():
                    if str(index) in index_body.get('aliases', {}):
                        active_index = index_name
                        break

                self.stdout.write('Indices for \'{}\' (current {}): {}'.format(
                    index, active_index, ', '.join(indices.keys())))
            else:
                self.stdout.write('No indices for \'{}\''.format(index))
Пример #29
0
    def handle_list(self, models, options, connection):
        """
        List the current Elasticsearch indices.

        Args:
            models: The models to show the indices for.
            options: The command line options.
            connection: The Elasticsearch connection.
        """
        for index in registry.get_indices(models):
            indices = connection.indices.get('{}.*'.format(index))

            if indices:
                active_index = None
                for index_name, index_body in indices.items():
                    if str(index) in index_body.get('aliases', {}):
                        active_index = index_name
                        break

                self.stdout.write('Indices for \'{}\' (current {}): {}'.format(
                    index, active_index, ', '.join(indices.keys())
                ))
            else:
                self.stdout.write('No indices for \'{}\''.format(index))
Пример #30
0
def pytest_runtest_teardown(item, nextitem):
    from mcod.core.api.rdf.registry import registry as rdf_registry
    from django_elasticsearch_dsl.registries import registry
    from mcod.resources.indexed_data import es_connections
    import shutil

    worker = os.environ.get('PYTEST_XDIST_WORKER', '')
    archives_path = os.path.join(settings.DATASETS_MEDIA_ROOT, 'archives', worker)
    if os.path.exists(archives_path):
        shutil.rmtree(archives_path)

    es_marker = item.get_closest_marker('elasticsearch')
    if es_marker:
        worker = os.environ.get('PYTEST_XDIST_WORKER', '')
        idx_prefix = getattr(settings, 'ELASTICSEARCH_INDEX_PREFIX', None)
        es = es_connections.get_connection()
        for res_index in es.indices.get_alias(f'{idx_prefix}-{worker}-*'):
            es.indices.delete(index=res_index, ignore=[404])
        for index in registry.get_indices():
            index.delete(ignore=404)

    sparql_marker = item.get_closest_marker('sparql')
    if sparql_marker:
        rdf_registry.delete_named_graph()
Пример #31
0
 def setup_method(self):
     models = registry.get_models()
     for index in registry.get_indices(models):
         index.delete(ignore=404)
         index.create()
Пример #32
0
def create_new_es_index(app_label, model_name, index_name, new_index_name):
    model = apps.get_model(app_label, model_name)
    indices = registry.get_indices(models=[model])
    old_index = _get_index(indices=indices, index_name=index_name)
    new_index = old_index.clone(name=new_index_name)
    new_index.create()
Пример #33
0
 def _delete(self, models):
     for index in registry.get_indices(models):
         index.delete(ignore=404)
     return True
Пример #34
0
 def _create(self, models):
     for index in registry.get_indices(models):
         index.create()
Пример #35
0
 def _create(self, models, options):
     for index in registry.get_indices(models):
         self.stdout.write("Creating index '{}'".format(index))
         index.create()
Пример #36
0
def create_new_es_index(app_label, model_name, index_name, new_index_name):
    model = apps.get_model(app_label, model_name)
    indices = registry.get_indices(models=[model])
    old_index = _get_index(indices=indices, index_name=index_name)
    new_index = old_index.clone(name=new_index_name)
    new_index.create()