Coverage for /Users/buh/.pyenv/versions/3.12.2/envs/es-testbed/lib/python3.12/site-packages/es_testbed/_plan.py: 21%
72 statements
« prev ^ index » next coverage.py v7.4.4, created at 2024-08-30 20:56 -0600
« prev ^ index » next coverage.py v7.4.4, created at 2024-08-30 20:56 -0600
1"""TestPlan Class Definition"""
3import typing as t
4import logging
5from dotmap import DotMap
6from es_testbed.defaults import TESTPLAN
7from es_testbed.helpers.utils import build_ilm_policy, prettystr, randomstr
9logger = logging.getLogger(__name__)
12class PlanBuilder:
13 """Plan builder class"""
15 def __init__(
16 self,
17 settings: t.Dict = None,
18 autobuild: t.Optional[bool] = True,
19 ):
20 if settings is None:
21 raise ValueError('Must provide a settings dictionary')
22 self.settings = settings
23 logger.debug('SETTINGS: %s', settings)
24 self._plan = DotMap(TESTPLAN)
25 logger.debug('INITIAL PLAN: %s', prettystr(self._plan))
26 self._plan.cleanup = 'UNSET' # Future use?
27 if autobuild:
28 self.setup()
30 # ## Example settings
31 # {
32 # 'type': 'indices', # Default is indices? Or should it be data_streams?
33 # 'prefix': 'es-testbed', # The default prefix for everything we create
34 # 'rollover_alias': False, # Only respected if 'type' == 'indices'.
35 # # Will rollover after creation and filling 1st
36 # # If True, will be overridden to value of alias
37 # # If False, will be overridden with None
38 # 'uniq': 'my-unique-str', # If not provided, randomstr()
39 # 'repository': # Only used for cold/frozen tier for snapshots
40 # 'ilm': { # All of these ILM values are defaults
41 # 'enabled': False,
42 # 'phases': ['hot', 'delete'],
43 # 'readonly': PHASE # Define readonly action during named PHASE
44 # 'forcemerge': False,
45 # 'max_num_segments': 1,
46 # 'policy': {} # Define full ILM policy in advance.
47 # }
48 #
50 #
51 # # The index_buildlist
52 # # The array of indices to build. Needs at least a single element. Importing
53 # # is expected, but it can be modified or replaced after importing.
54 # 'index_buildlist': [
55 # {
56 # 'preset': 'NAME', # docgen_preset name, included or otherwise
57 # 'options': { # kwargs for the generator function
58 # 'docs': 10,
59 # 'start_at': 0,
60 # 'match': True,
61 # }
62 # 'target_tier': 'frozen' # Target tier for 1st (oldest) index created
63 # },
64 # {
65 # 'preset': 'NAME', # docgen_preset name, included or otherwise
66 # 'options': { # kwargs for the generator function
67 # 'docs': 10,
68 # 'start_at': 10,
69 # 'match': True,
70 # }
71 # 'target_tier': 'cold' # Target tier for 2nd index created
72 # },
73 # {
74 # 'preset': 'NAME', # docgen_preset name, included or otherwise
75 # 'options': { # kwargs for the generator function
76 # 'docs': 10,
77 # 'start_at': 20,
78 # 'match': True,
79 # }
80 # 'target_tier': 'hot' # Target tier for last (newest) index created
81 # },
82 # ]
83 # }
85 @property
86 def plan(self) -> DotMap:
87 """Return the Plan"""
88 return self._plan
90 def _create_lists(self) -> None:
91 names = [
92 'indices',
93 'data_stream',
94 'snapshots',
95 'ilm_policies',
96 'index_templates',
97 'component_templates',
98 ]
99 for name in names:
100 self._plan[name] = []
102 def setup(self) -> None:
103 """Do initial setup of the Plan DotMap"""
104 self._plan.uniq = randomstr(length=8, lowercase=True)
105 self._create_lists()
106 self.update(self.settings) # Override with settings.
107 self.update_rollover_alias()
108 logger.debug('Rollover alias updated')
109 self.update_ilm()
110 logger.debug('FINAL PLAN: %s', prettystr(self._plan.toDict()))
112 def update(self, settings: t.Dict) -> None:
113 """Update the Plan DotMap"""
114 self._plan.update(**settings)
116 def update_ilm(self) -> None:
117 """Update the ILM portion of the Plan DotMap"""
118 setdefault = False
119 if 'ilm' not in self._plan:
120 logger.debug('key "ilm" is not in plan')
121 setdefault = True
122 if isinstance(self._plan.ilm, dict):
123 _ = DotMap(self._plan.ilm)
124 self._plan.ilm = _
125 if isinstance(self._plan.ilm, DotMap):
126 if 'enabled' not in self._plan.ilm:
127 # Override with defaults
128 logger.debug(
129 'plan.ilm does not have key "enabled". Overriding with defaults'
130 )
131 setdefault = True
132 elif isinstance(self._plan.ilm, bool):
133 if self._plan.ilm:
134 logger.warning(
135 '"plan.ilm: True" is incorrect. Use plan.ilm.enabled: True'
136 )
137 logger.debug('plan.ilm is boolean. Overriding with defaults')
138 setdefault = True
139 if setdefault:
140 logger.debug('Setting defaults for ILM')
141 self._plan.ilm = DotMap(TESTPLAN['ilm'])
142 if self._plan.ilm.enabled:
143 ilm = self._plan.ilm
144 if not isinstance(self._plan.ilm.phases, list):
145 logger.error('Phases is not a list!')
146 self._plan.ilm.phases = TESTPLAN['ilm']['phases']
147 for entity in self._plan.index_buildlist:
148 if 'searchable' in entity and entity['searchable'] is not None:
149 if not entity['searchable'] in ilm.phases:
150 ilm.phases.append(entity['searchable'])
151 logger.debug('ILM = %s', ilm)
152 logger.debug('self._plan.ilm = %s', self._plan.ilm)
153 kwargs = {
154 'phases': ilm.phases,
155 'forcemerge': ilm.forcemerge,
156 'max_num_segments': ilm.max_num_segments,
157 'readonly': ilm.readonly,
158 'repository': self._plan.repository,
159 }
160 logger.debug('KWARGS = %s', kwargs)
161 self._plan.ilm.policy = build_ilm_policy(**kwargs)
163 def update_rollover_alias(self) -> None:
164 """Update the Rollover Alias value"""
165 if self._plan.rollover_alias:
166 self._plan.rollover_alias = f'{self._plan.prefix}-idx-{self._plan.uniq}'
167 else:
168 self._plan.rollover_alias = None