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

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

2

3 import typing as t

4 import logging

5 from dotmap import DotMap # type: ignore

6 from es_pii_tool.task import Task

7 from es_pii_tool.helpers import steps as s

8

9 logger = logging.getLogger(__name__)

10

11# pylint: disable=W0718

12

13

14 class 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