Coverage for /Users/buh/.pyenv/versions/3.12.2/envs/pii/lib/python3.12/site-packages/es_pii_tool/redacters/steps.py: 100%

50 statements  

« prev     ^ index     » next       coverage.py v7.5.0, created at 2024-10-01 16:39 -0600

1"""Steps to redact a snapshot mounted index""" 

2 

3import typing as t 

4import logging 

5from dotmap import DotMap # type: ignore 

6from es_pii_tool.task import Task 

7from es_pii_tool.helpers import steps as s 

8 

9logger = logging.getLogger(__name__) 

10 

11# pylint: disable=W0718 

12 

13 

14class RedactionSteps: 

15 """All of the redaction steps for the final flow""" 

16 

17 def __init__(self, task: Task, var: DotMap): 

18 self.task = task 

19 self.var = var # These are the variables from RedactSnapshot 

20 self.counter = 1 # Counter will track the step number for us 

21 self.steps: t.Sequence = [] # Steps to execute will be ordered here 

22 self.data = DotMap() 

23 

24 def prep_steps(self): 

25 """Execute the preparatory steps for all indices""" 

26 # PREPARATORY STEPS 

27 # All indices will do these steps 

28 prepsteps = [ 

29 s.resolve_index, # Resolve whether an index or data_stream 

30 s.get_index_lifecycle_data, # Get INDEX lifecycle from settings, if any 

31 s.get_ilm_explain_data, # Get ILM explain data, if any 

32 s.get_ilm_lifecycle_data, # Get ILM lifecycle data, if any 

33 s.clone_ilm_policy, # If an ILM policy exists for index, clone it. 

34 ] 

35 

36 for func in prepsteps: 

37 stepname = f'step{str(self.counter).zfill(2)}_{func.__name__}' 

38 logger.debug('Attempting %s', stepname) 

39 func(self.task, stepname, self.var, data=self.data) 

40 self.counter += 1 

41 

42 def first_steps(self): 

43 """ 

44 Append the first steps to :py:attr:`steps` 

45 """ 

46 self.steps = [ 

47 s.pre_delete, # Force delete var.redaction_target, just in case 

48 s.restore_index, # Restore to var.redaction_target 

49 s.un_ilm_the_restored_index, # Remove ILM from var.redaction_target 

50 s.redact_from_index, # Redact specified docs from var.redaction_target 

51 s.forcemerge_index, # Force merge, if configured to do so 

52 s.clear_cache, # Clear the index cache for var.redaction_target 

53 s.confirm_redaction, # Confirm the docs were redacted 

54 s.snapshot_index, # Snapshot var.redaction_target 

55 s.mount_snapshot, # Mount the snapshotted index as var.mount_name 

56 ] 

57 

58 def ilm_steps(self): 

59 """ 

60 Append ILM specific steps only if there is a new ILM lifecycle name 

61 """ 

62 # After the prep steps, this value should be known 

63 if bool(self.data.new.ilmname): 

64 self.steps.append(s.apply_ilm_policy) # Apply the cloned ILM policy 

65 self.steps.append(s.confirm_ilm_phase) 

66 # Confirm we're in the expected phase and steps are "completed" 

67 

68 def delete_original(self): 

69 """ 

70 Append steps to delete the original index 

71 """ 

72 self.steps.append(s.un_ilm_the_original_index) # Remove ILM as a precaution 

73 self.steps.append(s.close_old_index) # Close it - Also precautionary 

74 self.steps.append(s.delete_old_index) # Delete it 

75 

76 def get_steps(self): 

77 """ 

78 Meta-step to populate :py:attr:`steps` 

79 """ 

80 # Do preparatory steps on all indices 

81 self.prep_steps() 

82 

83 # Set the first steps in self.steps 

84 self.first_steps() 

85 

86 # Add configuration dependent steps 

87 self.ilm_steps() 

88 

89 self.steps.append(s.delete_redaction_target) # Delete var.redaction_target 

90 

91 # After the prep steps, these values should be known 

92 is_data_stream = bool(self.data.data_stream) 

93 

94 # Only if original index was not a data_stream 

95 if not is_data_stream: 

96 self.steps.append(s.fix_aliases) # Collect and fix aliases to apply 

97 

98 # Remove original index 

99 self.delete_original() 

100 

101 # Reassociate as needed 

102 if is_data_stream: 

103 self.steps.append(s.reassociate_index_with_ds) # Reassociate with ds 

104 else: 

105 self.steps.append(s.assign_aliases) # Reassociate with aliases 

106 

107 # Final step 

108 self.steps.append(s.record_it) 

109 

110 def run(self) -> None: 

111 """ 

112 Run the steps in sequence 

113 

114 Step numbers are calculated by :py:attr:`counter`, which makes it easier 

115 to number steps if they are changed or reordered. 

116 """ 

117 self.get_steps() 

118 

119 # Now we finish the steps 

120 for func in self.steps: 

121 stepname = f'step{str(self.counter).zfill(2)}_{func.__name__}' 

122 logger.debug('Attempting %s', stepname) 

123 func(self.task, stepname, self.var, data=self.data) 

124 self.counter += 1