Coverage for /Users/buh/.pyenv/versions/3.12.9/envs/es-testbed/lib/python3.12/site-packages/es_testbed/mgrs/index.py: 98%

87 statements  

« prev     ^ index     » next       coverage.py v7.6.12, created at 2025-04-17 22:23 -0600

1"""Index Entity Manager Class""" 

2 

3import typing as t 

4import logging 

5from importlib import import_module 

6from ..debug import debug, begin_end 

7from ..entities import Alias, Index 

8from ..es_api import create_index, fill_index 

9from ..utils import prettystr 

10from .entity import EntityMgr 

11from .snapshot import SnapshotMgr 

12 

13if t.TYPE_CHECKING: 

14 from elasticsearch8 import Elasticsearch 

15 from dotmap import DotMap 

16 

17logger = logging.getLogger(__name__) 

18 

19 

20class IndexMgr(EntityMgr): 

21 """Index Entity Manager Class""" 

22 

23 kind = 'index' 

24 listname = 'indices' 

25 

26 def __init__( 

27 self, 

28 client: t.Optional['Elasticsearch'] = None, 

29 plan: t.Optional['DotMap'] = None, 

30 snapmgr: t.Optional[SnapshotMgr] = None, 

31 ): 

32 self.snapmgr = snapmgr 

33 self.alias = None # Only used for tracking the rollover alias 

34 debug.lv2('Initializing IndexMgr object...') 

35 super().__init__(client=client, plan=plan) 

36 debug.lv3('IndexMgr object initialized') 

37 

38 @property 

39 def indexlist(self) -> t.Sequence[str]: 

40 """Return a list of index names currently being managed""" 

41 return [x.name for x in self.entity_list] 

42 

43 @property 

44 def policy_name(self) -> t.Union[str, None]: 

45 """Return the name of the ILM policy, if it exists""" 

46 if len(self.plan.ilm_policies) > 0: 

47 return self.plan.ilm_policies[-1] 

48 return None 

49 

50 @begin_end() 

51 def _rollover_path(self) -> None: 

52 """This is the execution path for rollover indices""" 

53 if not self.entity_list: 

54 acfg = {self.plan.rollover_alias: {'is_write_index': True}} 

55 debug.lv5(f'Creating index with config: {acfg}') 

56 create_index(self.client, self.name, aliases=acfg) 

57 self.track_alias() 

58 else: 

59 self.alias.rollover() 

60 debug.lv5('Rolled over index with alias') 

61 if self.policy_name: # We have an ILM policy 

62 kw = {'phase': 'hot', 'action': 'complete', 'name': 'complete'} 

63 debug.lv5(f'Advancing ILM policy with config: {kw}') 

64 self.last.ilm_tracker.advance(**kw) 

65 

66 @begin_end() 

67 def add( 

68 self, 

69 name: str, 

70 mappings: t.Optional[t.Dict] = None, 

71 settings: t.Optional[t.Dict] = None, 

72 ) -> None: 

73 """Create a single index""" 

74 mapvals = mappings['mappings'] or None 

75 setvals = settings['settings']['index'] or None 

76 debug.lv1(f'Creating index: "{name}"') 

77 debug.lv5(f'-- with settings: {settings}') 

78 debug.lv5(f'-- with mappings: {mappings}') 

79 create_index(self.client, name, mappings=mapvals, settings=setvals) 

80 

81 @begin_end() 

82 def add_indices(self) -> None: 

83 """Add indices according to plan""" 

84 args = import_module(f'{self.plan.modpath}.definitions') 

85 mod = import_module(f'{self.plan.modpath}.functions') 

86 func = getattr(mod, 'doc_generator') 

87 for scheme in self.plan.index_buildlist: 

88 if self.plan.rollover_alias: 

89 self._rollover_path() 

90 else: 

91 self.add(self.name, mappings=args.mappings(), settings=args.settings()) 

92 # self.filler(scheme) 

93 fill_index( 

94 self.client, 

95 name=self.name, 

96 doc_generator=func, 

97 options=scheme['options'], 

98 ) 

99 self.track_index(self.name) 

100 debug.lv2(f'Created indices: {prettystr(self.indexlist)}') 

101 if self.plan.rollover_alias: 

102 if not self.alias.verify(self.indexlist): 

103 logger.error( 

104 f'Unable to confirm rollover of alias ' 

105 f'"{self.plan.rollover_alias}" was successful' 

106 ) 

107 

108 @begin_end() 

109 def searchable(self) -> None: 

110 """If the indices were marked as searchable snapshots, we do that now""" 

111 for idx, scheme in enumerate(self.plan.index_buildlist): 

112 if scheme['target_tier'] in ['cold', 'frozen']: 

113 self.entity_list[idx].mount_ss(scheme) 

114 

115 @begin_end() 

116 def setup(self) -> None: 

117 """Setup the entity manager""" 

118 debug.lv5(f'PLAN: {prettystr(self.plan.toDict())}') 

119 if self.plan.rollover_alias: 

120 debug.lv3('rollover_alias is True...') 

121 self.add_indices() 

122 self.searchable() 

123 logger.info(f'Successfully created indices: {prettystr(self.indexlist)}') 

124 

125 @begin_end() 

126 def track_alias(self) -> None: 

127 """Track a rollover alias""" 

128 debug.lv3(f'Tracking alias: {self.plan.rollover_alias}') 

129 self.alias = Alias(client=self.client, name=self.plan.rollover_alias) 

130 

131 @begin_end() 

132 def track_index(self, name: str) -> None: 

133 """Track an index and append that tracking entity to entity_list""" 

134 debug.lv3(f'Tracking index: {name}') 

135 entity = Index( 

136 client=self.client, 

137 name=name, 

138 snapmgr=self.snapmgr, 

139 policy_name=self.policy_name, 

140 ) 

141 entity.track_ilm(self.name) 

142 self.entity_list.append(entity)