Changeset 40937
- Timestamp:
- Oct 11, 2019, 3:49:23 PM (7 years ago)
- Location:
- branches/ipp-259_genericise_backups/tools/backups
- Files:
-
- 8 added
- 2 deleted
- 3 edited
-
backup.py (modified) (11 diffs)
-
backup_atlassian_applications.py (deleted)
-
backup_atlassian_applications_test.py (deleted)
-
backup_test.py (modified) (6 diffs)
-
confluence_backup.config (added)
-
confluence_backup.py (added)
-
confluence_backup_test.py (added)
-
jira_backup.config (added)
-
jira_backup.py (added)
-
jira_backup_test.py (added)
-
testing/confluence_test.config (added)
-
testing/jira_test.config (added)
-
utils/config_parse_helper.py (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
branches/ipp-259_genericise_backups/tools/backups/backup.py
r40932 r40937 1 1 import configparser 2 2 import datetime 3 import os 3 4 import os.path as path 4 5 import socket 5 6 import subprocess 7 from configparser import ConfigParser 6 8 7 9 import backups.utils.config_parse_helper as cfg_help 8 10 import backups.utils.errors as errs 9 11 import backups.utils.subprocess_utils as sub_utils 10 from configparser import ConfigParser12 from backups.utils.config_parse_helper import ConfigSchema, ConfigSchemaLine 11 13 12 14 DEFAULT_CONFIG_FILE = path.join(path.dirname(__file__), 'atlassian_backups.config') … … 19 21 20 22 def __init__(self, config_file=None): 21 self.config_file = DEFAULT_CONFIG_FILE if config_file is None else config_file 22 self.load_config(self.config_file) 23 if config_file is None: 24 raise errs.ValidationError("ValidationError: Backup class must be given a config") 25 self.load_config(config_file) 23 26 24 27 def load_config(self, config_class_or_filepath): … … 33 36 config.read(config_class_or_filepath) 34 37 35 self. _read_default_section(config)38 self.read_default_section(config) 36 39 if self._has_copy_section(config): 37 self. _read_copy_config_section(config)40 self.read_copy_config_section(config) 38 41 if self._has_tar_section(config): 39 self. _read_tar_config_section(config)42 self.read_tar_config_section(config) 40 43 if self._has_rsync_section(config): 41 self. _read_rsync_config_section(config)44 self.read_rsync_config_section(config) 42 45 if self._has_mysqldump_section(config): 43 self. _read_mysqldump_config_section(config)46 self.read_mysqldump_config_section(config) 44 47 45 48 def _has_copy_section(self, config_parser: ConfigParser) -> bool: … … 63 66 return self.run_mysqldump 64 67 65 DEFAULT_SCHEMA = cfg_help.ConfigSchema('DEFAULT', 66 [ cfg_help.ConfigSchemaLine('backup_paths', True, list, cfg_help.SpecialSchemaProcessing.commma_separated) 67 , cfg_help.ConfigSchemaLine('source_machine', True, str) 68 , cfg_help.ConfigSchemaLine('verbose', False, bool) 69 ] 70 ) 71 72 def _read_default_section(self, config: ConfigParser): 73 self.default_dict = cfg_help.parse_config(config, self.DEFAULT_SCHEMA) 68 DEFAULT_SCHEMA = ConfigSchema('DEFAULT', 69 [ ConfigSchemaLine('backup_paths', True, list, cfg_help.SpecialSchemaProcessing.commma_separated) 70 , ConfigSchemaLine('source_machine', True, str) 71 , ConfigSchemaLine('verbose', False, bool) 72 , ConfigSchemaLine('make_dirs', False, bool) 73 ] 74 ) 75 76 def read_default_section(self, config: ConfigParser, schema: ConfigSchema=DEFAULT_SCHEMA): 77 self.default_dict = cfg_help.parse_config(config, schema) 74 78 self.hostname_is_valid() 75 76 COPY_SCHEMA = cfg_help.ConfigSchema('COPY', 77 [ cfg_help.ConfigSchemaLine('sources', True, list, cfg_help.SpecialSchemaProcessing.commma_separated) 78 , cfg_help.ConfigSchemaLine('additional_args', False, list, cfg_help.SpecialSchemaProcessing.space_separated) 79 ] 80 ) 81 82 def _read_copy_config_section(self, config: ConfigParser): 83 self.copy_dict = cfg_help.parse_config(config, self.COPY_SCHEMA) 84 85 TAR_SCHEMA = cfg_help.ConfigSchema('TAR', 86 [ cfg_help.ConfigSchemaLine('sources', True, list, cfg_help.SpecialSchemaProcessing.commma_separated) 87 , cfg_help.ConfigSchemaLine('additional_args', False, list, cfg_help.SpecialSchemaProcessing.space_separated) 88 , cfg_help.ConfigSchemaLine('target_filename', True, str) 89 , cfg_help.ConfigSchemaLine('prefix_date', True, bool) 90 ] 91 ) 92 93 def _read_tar_config_section(self, config: ConfigParser): 94 self.tar_dict = cfg_help.parse_config(config, self.TAR_SCHEMA) 95 96 RSYNC_SCHEMA = cfg_help.ConfigSchema('RSYNC', 97 [ cfg_help.ConfigSchemaLine('sources', True, list, cfg_help.SpecialSchemaProcessing.commma_separated) 98 , cfg_help.ConfigSchemaLine('additional_args', False, list, cfg_help.SpecialSchemaProcessing.space_separated) 99 ] 100 ) 101 102 def _read_rsync_config_section(self, config: ConfigParser): 103 self.rsync_dict = cfg_help.parse_config(config, self.RSYNC_SCHEMA) 104 105 MYSQLDUMP_SCHEMA = cfg_help.ConfigSchema('MYSQLDUMP', 106 [ cfg_help.ConfigSchemaLine('user', True, str) 107 , cfg_help.ConfigSchemaLine('password', True, str) 108 , cfg_help.ConfigSchemaLine('db_name', True, str) 109 , cfg_help.ConfigSchemaLine('additional_args', False, list, cfg_help.SpecialSchemaProcessing.space_separated) 110 , cfg_help.ConfigSchemaLine('target_filename', True, str) 111 , cfg_help.ConfigSchemaLine('prefix_date', True, bool) 112 ] 113 ) 114 115 def _read_mysqldump_config_section(self, config: ConfigParser): 116 self.mysqldump_dict = cfg_help.parse_config(config, self.MYSQLDUMP_SCHEMA) 79 self.maybe_make_backup_dirs() 80 81 COPY_SCHEMA = ConfigSchema('COPY', 82 [ ConfigSchemaLine('sources', True, list, cfg_help.SpecialSchemaProcessing.commma_separated) 83 , ConfigSchemaLine('additional_args', False, list, cfg_help.SpecialSchemaProcessing.space_separated) 84 ] 85 ) 86 87 def read_copy_config_section(self, config: ConfigParser, schema: ConfigSchema=COPY_SCHEMA): 88 self.copy_dict = cfg_help.parse_config(config, schema) 89 90 TAR_SCHEMA = ConfigSchema('TAR', 91 [ ConfigSchemaLine('sources', True, list, cfg_help.SpecialSchemaProcessing.commma_separated) 92 , ConfigSchemaLine('additional_args', False, list, cfg_help.SpecialSchemaProcessing.space_separated) 93 , ConfigSchemaLine('target_filename', True, str) 94 , ConfigSchemaLine('prefix_date', True, bool) 95 ] 96 ) 97 98 def read_tar_config_section(self, config: ConfigParser, schema: ConfigSchema=TAR_SCHEMA): 99 self.tar_dict = cfg_help.parse_config(config, schema) 100 101 RSYNC_SCHEMA = ConfigSchema('RSYNC', 102 [ ConfigSchemaLine('sources', True, list, cfg_help.SpecialSchemaProcessing.commma_separated) 103 , ConfigSchemaLine('additional_args', False, list, cfg_help.SpecialSchemaProcessing.space_separated) 104 ] 105 ) 106 107 def read_rsync_config_section(self, config: ConfigParser, schema: ConfigSchema=RSYNC_SCHEMA): 108 self.rsync_dict = cfg_help.parse_config(config, schema) 109 110 MYSQLDUMP_SCHEMA = ConfigSchema('MYSQLDUMP', 111 [ ConfigSchemaLine('user', True, str) 112 , ConfigSchemaLine('password', True, str) 113 , ConfigSchemaLine('db_name', True, str) 114 , ConfigSchemaLine('additional_args', False, list, cfg_help.SpecialSchemaProcessing.space_separated) 115 , ConfigSchemaLine('target_filename', True, str) 116 , ConfigSchemaLine('prefix_date', True, bool) 117 ] 118 ) 119 120 def read_mysqldump_config_section(self, config: ConfigParser, schema: ConfigSchema=MYSQLDUMP_SCHEMA): 121 self.mysqldump_dict = cfg_help.parse_config(config, schema) 117 122 118 123 def hostname_is_valid(self) -> bool: … … 122 127 actual_hostname = socket.gethostname() 123 128 return actual_hostname == self.default_dict['source_machine'] 129 130 def target_backup_paths_ok(self, raise_error=False): 131 for bp in self.default_dict['backup_paths']: 132 if not path.exists(bp): 133 if raise_error: 134 raise errs.ValidationError(f"ValidationError: target path does not exist: {bp}") 135 return False 136 return True 137 138 def maybe_make_backup_dirs(self): 139 if self.default_dict is None or 'make_dirs' not in self.default_dict.keys(): 140 return 141 if self.default_dict['make_dirs']: 142 for backup_path in self.default_dict['backup_paths']: 143 if not os.path.exists(backup_path): 144 os.makedirs(backup_path) 124 145 125 146 def run_backup(self): … … 132 153 if self.run_copy is None or False: 133 154 return 0 155 self.target_backup_paths_ok(raise_error=True) 134 156 135 157 for bp in self.default_dict['backup_paths']: 136 if not path.exists(bp):137 raise errs.ValidationError(f"ValidationError: target path does not exist: {bp}")158 # if not path.exists(bp): 159 # raise errs.ValidationError(f"ValidationError: target path does not exist: {bp}") 138 160 139 161 for s in self.copy_dict['sources']: … … 143 165 args = [s, bp] 144 166 if 'additional_args' in self.copy_dict.keys(): 145 print("hiya")146 167 args = args + self.copy_dict['additional_args'] 147 168 sub_utils.cp_wrapper(args) … … 168 189 169 190 try: 170 print(all_args)171 191 sub_utils.tar_wrapper(all_args) 172 192 sub_utils.chmod_wrapper(['774', filename]) … … 184 204 return 0 185 205 206 self.target_backup_paths_ok(raise_error=True) 186 207 backup_paths = self.default_dict['backup_paths'] 187 208 for bp in backup_paths: 188 if not path.exists(bp):189 raise errs.ValidationError(f"ValidationError: target path does not exist: {bp}")209 # if not path.exists(bp): 210 # raise errs.ValidationError(f"ValidationError: target path does not exist: {bp}") 190 211 191 212 for s in self.rsync_dict['sources']: … … 195 216 args = [s, bp] 196 217 if 'additional_args' in self.rsync_dict.keys(): 197 print("hiya")198 218 args = args + self.rsync_dict['additional_args'] 199 print(args)200 219 sub_utils.local_rsync_wrapper(args) 201 220 except errs.SubprocessError as e: … … 240 259 for d in range(1, len(backup_paths)): 241 260 sub_utils.cp_wrapper([dump_filename, backup_paths[d]]) 242 243 244 def get_date(custom_date=None, custom_format="%Y-%b-%d"): 261 return 0 262 263 264 def get_date(custom_date=None, custom_format="%Y_%m_%d"): 245 265 # Format is currently: 2019-10-08 246 266 if custom_date is not None: -
branches/ipp-259_genericise_backups/tools/backups/backup_test.py
r40932 r40937 27 27 source_machine = socket.gethostname() 28 28 config['DEFAULT'] = \ 29 { 30 'backup_paths' : backup_paths, 31 'source_machine' : source_machine, 32 'verbose' : verbose, 33 } 29 { 'backup_paths' : backup_paths 30 , 'source_machine' : source_machine 31 , 'verbose' : verbose 32 } 34 33 return config 35 34 … … 107 106 Backup(config_file=config) 108 107 109 with pytest.raises(errs. ConfigError):108 with pytest.raises(errs.ValidationError): 110 109 Backup(config_file=None) 111 110 … … 136 135 backy.default_dict['source_machine'] = actual_hostname 137 136 assert backy.hostname_is_valid() is True 137 138 139 class TestFilepathVerifications(object): 140 141 def test_default_target_paths_do_not_exist_in_testing(self): 142 backy = Backup(config_file=TEST_DEFAULT_CONFIG_FILE) 143 assert backy.target_backup_paths_ok() is False 144 145 def test_raising_an_error_if_a_backup_path_does_not_exist(self): 146 with pytest.raises(errs.ValidationError) as e: 147 backy = Backup(config_file=TEST_DEFAULT_CONFIG_FILE) 148 backy.target_backup_paths_ok(raise_error=True) 149 assert "ValidationError: target path does not exist" in str(e) 150 151 def test_an_incorrect_path_then_correct_path(self, tmpdir): 152 backy = Backup(config_file=TEST_DEFAULT_CONFIG_FILE) 153 154 backy.default_dict['backup_paths'] = ["/not/real/path"] 155 assert backy.target_backup_paths_ok() is False 156 157 backy.default_dict['backup_paths'] = [tmpdir] 158 assert backy.target_backup_paths_ok() is True 159 160 def test_backup_paths_created_if_make_dirs_given(self, tmpdir): 161 config = ConfigParser() 162 config['DEFAULT'] = \ 163 { 'backup_paths' : f"{tmpdir}/bck1/bobby/backup, {tmpdir}/bck2" 164 , 'source_machine' : 'rocket' 165 , 'verbose' : 'True' 166 } 167 bck1_path = os.path.join(tmpdir, 'bck1') 168 bck1b_path = os.path.join(tmpdir, 'bck1/bobby') 169 bck1bb_path = os.path.join(tmpdir, 'bck1/bobby/backup') 170 bck2_path = os.path.join(tmpdir, 'bck2') 171 assert not os.path.exists(bck1_path) 172 assert not os.path.exists(bck1b_path) 173 assert not os.path.exists(bck1bb_path) 174 assert not os.path.exists(bck2_path) 175 # backup dirs not created automatically 176 Backup(config) 177 assert not os.path.exists(bck1_path) 178 assert not os.path.exists(bck1b_path) 179 assert not os.path.exists(bck1bb_path) 180 assert not os.path.exists(bck2_path) 181 182 # make_dirs included in config - when loaded dirs created. 183 config['DEFAULT'] = \ 184 { 'backup_paths' : f"{tmpdir}/bck1/bobby/backup, {tmpdir}/bck2" 185 , 'source_machine' : 'rocket' 186 , 'verbose' : 'True' 187 , 'make_dirs' : 'True' 188 } 189 backy = Backup(config) 190 assert backy.default_dict['make_dirs'] is True 191 assert os.path.exists(bck1_path) 192 assert os.path.exists(bck1b_path) 193 assert os.path.exists(bck1bb_path) 194 assert os.path.exists(bck2_path) 138 195 139 196 … … 265 322 assert not os.path.exists(expected_tar1) 266 323 backy._run_tar() 267 print(expected_tar1)268 324 assert os.path.exists(expected_tar1) 269 325 … … 422 478 """ 423 479 424 dumper_password = "not_a_real_password"425 426 480 def test_mysql_dump_is_ok(self, tmpdir): 427 481 config = make_default_config(tmpdir, ['bck1', 'bck2']) … … 442 496 assert not os.path.exists(expected_dump1) 443 497 assert not os.path.exists(expected_dump2) 444 backy._run_mysqldump()498 result = backy._run_mysqldump() 445 499 assert os.path.exists(expected_dump1) 446 500 assert os.path.exists(expected_dump2) 501 502 assert result == 0 447 503 448 504 def test_mysql_dump_fails_with_incorrect_password(self, tmpdir): -
branches/ipp-259_genericise_backups/tools/backups/utils/config_parse_helper.py
r40920 r40937 86 86 for csl_key in schema.options: 87 87 csl = schema.get_schema_line(csl_key) 88 print(csl)89 88 90 89 if config.has_option(section, csl_key):
Note:
See TracChangeset
for help on using the changeset viewer.
