Coverage for curator/actions/create_index.py: 100%

1"""Create index action class"""

2 import logging

3# pylint: disable=import-error, broad-except

4 from elasticsearch8.exceptions import RequestError

5 from curator.exceptions import ConfigurationError, FailedExecution

6 from curator.helpers.date_ops import parse_date_pattern

7 from curator.helpers.utils import report_failure

8

9 class CreateIndex:

10 """Create Index Action Class"""

11 def __init__(self, client, name=None, extra_settings=None, ignore_existing=False):

12 """

13 :param client: A client connection object

14 :param name: A name, which can contain :py:func:`time.strftime` strings

15 :param extra_settings: The `settings` and `mappings` for the index. For more information

16 see `the create indices documentation </https://www.elastic.co/guide/en/elasticsearch/reference/8.6/indices-create-index.html>`_.

17 :param ignore_existing: If an index already exists, and this setting is ``True``, ignore

18 the 400 error that results in a ``resource_already_exists_exception`` and return that

19 it was successful.

20

21 :type client: :py:class:`~.elasticsearch.Elasticsearch`

22 :type name: str

23 :type extra_settings: dict

24 :type ignore_existing: bool

25 """

26 if extra_settings is None:

27 extra_settings = {}

28 if not name:

29 raise ConfigurationError('Value for "name" not provided.')

30 #: The :py:func:`~.curator.helpers.date_ops.parse_date_pattern` rendered

31 #: version of what was passed as ``name``.

32 self.name = parse_date_pattern(name)

33 #: Extracted from the action definition, it should be a boolean informing

34 #: whether to ignore the error if the index already exists.

35 self.ignore_existing = ignore_existing

36 #: An :py:class:`~.elasticsearch.Elasticsearch` client object

37 self.client = client

38 #: Any extra settings for the index, like aliases, mappings, or settings. Gets the value

39 #: from param ``extra_settings``.

40 self.extra_settings = extra_settings

41 #: Gets any ``aliases`` from :py:attr:`extra_settings` or is :py:class:`None`

42 self.aliases = None

43 #: Gets any ``mappings`` from :py:attr:`extra_settings` or is :py:class:`None`

44 self.mappings = None

45 #: Gets any ``settings`` from :py:attr:`extra_settings` or is :py:class:`None`

46 self.settings = None

47

48 if 'aliases' in extra_settings:

49 self.aliases = extra_settings.pop('aliases')

50 if 'mappings' in extra_settings:

51 self.mappings = extra_settings.pop('mappings')

52 if 'settings' in extra_settings:

53 self.settings = extra_settings.pop('settings')

54 self.loggit = logging.getLogger('curator.actions.create_index')

55

56 def do_dry_run(self):

57 """Log what the output would be, but take no action."""

58 self.loggit.info('DRY-RUN MODE. No changes will be made.')

59 msg = f'DRY-RUN: create_index "{self.name}" with arguments: {self.extra_settings}'

60 self.loggit.info(msg)

61

62 def do_action(self):

63 """

64 :py:meth:`~.elasticsearch.client.IndicesClient.create` index identified by :py:attr:`name`

65 with values from :py:attr:`aliases`, :py:attr:`mappings`, and :py:attr:`settings`

66 """

67 msg = f'Creating index "{self.name}" with settings: {self.extra_settings}'

68 self.loggit.info(msg)

69 try:

70 self.client.indices.create(

71 index=self.name, aliases=self.aliases, mappings=self.mappings,

72 settings=self.settings

73 )

74 # Most likely error is a 400, `resource_already_exists_exception`

75 except RequestError as err:

76 match_list = ["index_already_exists_exception", "resource_already_exists_exception"]

77 if err.error in match_list and self.ignore_existing:

78 self.loggit.warning('Index %s already exists.', self.name)

79 else:

80 raise FailedExecution(f'Index {self.name} already exists.') from err

81 # pylint: disable=broad-except

82 except Exception as err:

83 report_failure(err)