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

50 statements  

« prev     ^ index     » next       coverage.py v7.2.7, created at 2023-07-20 21:00 -0600

1"""Open index action class""" 

2import logging 

3from curator.exceptions import ConfigurationError 

4from curator.helpers.date_ops import parse_date_pattern 

5from curator.helpers.testers import rollable_alias, verify_client_object 

6from curator.helpers.utils import report_failure 

7 

8class Rollover: 

9 """Rollover Action Class""" 

10 def __init__( 

11 self, client, name=None, conditions=None, new_index=None, extra_settings=None, 

12 wait_for_active_shards=1 

13 ): 

14 """ 

15 :param client: A client connection object 

16 :param name: The name of the single-index-mapped alias to test for rollover conditions. 

17 :param new_index: A new index name 

18 :param conditions: Conditions to test 

19 :param extra_settings: Must be either ``None``, or a dictionary of settings to apply to the new index on rollover. This is used in place of ``settings`` in the Rollover API, mostly because it's already existent in other places here in Curator 

20 :param wait_for_active_shards: The number of shards expected to be active before returning. 

21 

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

23 :type name: str 

24 :type new_index: str 

25 :type conditions: dict 

26 :type extra_settings: dict or None 

27 :type wait_for_active_shards: int 

28 """ 

29 self.loggit = logging.getLogger('curator.actions.rollover') 

30 if not isinstance(conditions, dict): 

31 raise ConfigurationError('"conditions" must be a dictionary') 

32 else: 

33 self.loggit.debug('"conditions" is %s', conditions) 

34 if not isinstance(extra_settings, dict) and extra_settings is not None: 

35 raise ConfigurationError( 

36 '"extra_settings" must be a dictionary or None') 

37 verify_client_object(client) 

38 #: Object attribute that gets the value of param ``client``. 

39 self.client = client 

40 #: Object attribute that gets the value of param ``conditions``. 

41 self.conditions = conditions 

42 #: Object attribute that gets the value of param ``extra_settings``. 

43 self.settings = extra_settings 

44 #: The :py:func:`~.curator.helpers.date_ops.parse_date_pattern` rendered version of what 

45 #: was passed as ``new_index``, or else ``None`` 

46 self.new_index = parse_date_pattern(new_index) if new_index else new_index 

47 #: Object attribute that gets the value of param ``wait_for_active_shards``. 

48 self.wait_for_active_shards = wait_for_active_shards 

49 

50 #: Object attribute that gets the value of param ``name``. 

51 self.name = None 

52 # Verify that `conditions` and `settings` are good? 

53 # Verify that `name` is an alias, and is only mapped to one index. 

54 if rollable_alias(client, name): 

55 self.name = name 

56 else: 

57 raise ValueError( 

58 f'Unable to perform index rollover with alias ' 

59 f'"{name}". See previous logs for more details.' 

60 ) 

61 

62 def log_result(self, result): 

63 """Log the results based on whether the index rolled over or not""" 

64 dryrun_string = '' 

65 if result['dry_run']: 

66 dryrun_string = 'DRY-RUN: ' 

67 self.loggit.debug('%sResult: %s', dryrun_string, result) 

68 rollover_string = ( 

69 f"{dryrun_string}Old index {result['old_index']} " 

70 f"rolled over to new index {result['new_index']}" 

71 ) 

72 # Success is determined by at one condition being True 

73 success = False 

74 for k in list(result['conditions'].keys()): 

75 if result['conditions'][k]: 

76 success = True 

77 if result['dry_run'] and success: # log "successful" dry-run 

78 self.loggit.info(rollover_string) 

79 elif result['rolled_over']: 

80 self.loggit.info(rollover_string) 

81 else: 

82 msg = ( 

83 f"{dryrun_string}Rollover conditions not met. " 

84 f"Index {result['old_index']} not rolled over." 

85 ) 

86 self.loggit.info(msg) 

87 

88 def doit(self, dry_run=False): 

89 """ 

90 This exists solely to prevent having to have duplicate code in both :py:meth:`do_dry_run` 

91 and :py:meth:`do_action` because :py:meth:`~.elasticsearch.client.IndicesClient.rollover` 

92 has its own ``dry_run`` flag. 

93 """ 

94 return self.client.indices.rollover( 

95 alias=self.name, 

96 new_index=self.new_index, 

97 conditions=self.conditions, 

98 settings=self.settings, 

99 dry_run=dry_run, 

100 wait_for_active_shards=self.wait_for_active_shards, 

101 ) 

102 

103 def do_dry_run(self): 

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

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

106 self.log_result(self.doit(dry_run=True)) 

107 

108 def do_action(self): 

109 """ 

110 :py:meth:`~.elasticsearch.client.IndicesClient.rollover` the index referenced by alias 

111 :py:attr:`name` 

112 """ 

113 self.loggit.info('Performing index rollover') 

114 try: 

115 self.log_result(self.doit()) 

116 # pylint: disable=broad-except 

117 except Exception as err: 

118 report_failure(err)