def config_sync(env, skip_offline_nodes=False): """ Send specified local booth configuration to all nodes in cluster. env -- LibraryEnvironment skip_offline_nodes -- if True offline nodes will be skipped """ config = env.booth.get_config_content() authfile_path = config_structure.get_authfile(parse(config)) authfile_content = config_files.read_authfile( env.report_processor, authfile_path ) cluster_nodes_names, report_list = get_existing_nodes_names( env.get_corosync_conf() ) if not cluster_nodes_names: report_list.append(reports.corosync_config_no_nodes_defined()) env.report_processor.process_list(report_list) com_cmd = BoothSendConfig( env.report_processor, env.booth.name, config, authfile=authfile_path, authfile_data=authfile_content, skip_offline_targets=skip_offline_nodes ) com_cmd.set_targets( env.get_node_target_factory().get_target_list( cluster_nodes_names, skip_non_existing=skip_offline_nodes, ) ) run_and_raise(env.get_node_communicator(), com_cmd)
def config_sync(env, skip_offline_nodes=False): """ Send specified local booth configuration to all nodes in cluster. env -- LibraryEnvironment skip_offline_nodes -- if True offline nodes will be skipped """ config = env.booth.get_config_content() authfile_path = config_structure.get_authfile(parse(config)) authfile_content = config_files.read_authfile( env.report_processor, authfile_path ) com_cmd = BoothSendConfig( env.report_processor, env.booth.name, config, authfile=authfile_path, authfile_data=authfile_content, skip_offline_targets=skip_offline_nodes ) com_cmd.set_targets( env.get_node_target_factory().get_target_list( env.get_corosync_conf().get_nodes_names(), skip_non_existing=skip_offline_nodes, ) ) run_and_raise(env.get_node_communicator(), com_cmd)
def send_all_config_to_node(communicator, reporter, target_list, rewrite_existing=False, skip_wrong_config=False): """ Send all booth configs from default booth config directory and theri authfiles to specified node. communicator -- NodeCommunicator reporter -- report processor target_list list -- list of targets to which configs should be delivered rewrite_existing -- if True rewrite existing file skip_wrong_config -- if True skip local configs that are unreadable """ _reporter = SimpleReportProcessor(reporter) config_dict = booth_conf.read_configs(reporter, skip_wrong_config) if not config_dict: return _reporter.report(reports.booth_config_distribution_started()) file_list = [] for config, config_data in sorted(config_dict.items()): try: authfile_path = config_structure.get_authfile( config_parser.parse(config_data)) file_list.append({ "name": config, "data": config_data, "is_authfile": False }) if authfile_path: content = booth_conf.read_authfile(reporter, authfile_path) if not content: continue file_list.append({ "name": os.path.basename(authfile_path), "data": base64.b64encode(content).decode("utf-8"), "is_authfile": True }) except LibraryError: _reporter.report( reports.booth_skipping_config(config, "unable to parse config")) com_cmd = BoothSaveFiles(_reporter, file_list, rewrite_existing=rewrite_existing) com_cmd.set_targets(target_list) run(communicator, com_cmd) if _reporter.has_errors: raise LibraryError()
def send_all_config_to_node( communicator, reporter, target_list, rewrite_existing=False, skip_wrong_config=False ): """ Send all booth configs from default booth config directory and theri authfiles to specified node. communicator -- NodeCommunicator reporter -- report processor target_list list -- list of targets to which configs should be delivered rewrite_existing -- if True rewrite existing file skip_wrong_config -- if True skip local configs that are unreadable """ _reporter = SimpleReportProcessor(reporter) config_dict = booth_conf.read_configs(reporter, skip_wrong_config) if not config_dict: return _reporter.report(reports.booth_config_distribution_started()) file_list = [] for config, config_data in sorted(config_dict.items()): try: authfile_path = config_structure.get_authfile( config_parser.parse(config_data) ) file_list.append({ "name": config, "data": config_data, "is_authfile": False }) if authfile_path: content = booth_conf.read_authfile(reporter, authfile_path) if not content: continue file_list.append({ "name": os.path.basename(authfile_path), "data": base64.b64encode(content).decode("utf-8"), "is_authfile": True }) except LibraryError: _reporter.report(reports.booth_skipping_config( config, "unable to parse config" )) com_cmd = BoothSaveFiles( _reporter, file_list, rewrite_existing=rewrite_existing ) com_cmd.set_targets(target_list) run(communicator, com_cmd) if _reporter.has_errors: raise LibraryError()
def test_not_abs_path(self): path = "/etc/booth/../booth.key" self.assertTrue( config_files.read_authfile(self.mock_reporter, path) is None) assert_report_item_list_equal(self.mock_reporter.report_item_list, [ (severities.WARNING, report_codes.BOOTH_UNSUPORTED_FILE_LOCATION, { "file": path }) ])
def test_not_abs_path(self): path = "/etc/booth/../booth.key" self.assertTrue( config_files.read_authfile(self.mock_reporter, path) is None ) assert_report_item_list_equal( self.mock_reporter.report_item_list, [( severities.WARNING, report_codes.BOOTH_UNSUPORTED_FILE_LOCATION, {"file": path} )] )
def test_success(self): path = os.path.join(BOOTH_CONFIG_DIR, "file.key") mock_open = mock.mock_open(read_data="key") with patch_config_files("open", mock_open, create=True): self.assertEqual( "key", config_files.read_authfile(self.mock_reporter, path)) self.assertEqual([ mock.call(path, "rb"), mock.call().__enter__(), mock.call().read(), mock.call().__exit__(None, None, None) ], mock_open.mock_calls) self.assertEqual(0, len(self.mock_reporter.report_item_list))
def test_read_failure(self, _): path = os.path.join(BOOTH_CONFIG_DIR, "file.key") mock_open = mock.mock_open() mock_open().read.side_effect = EnvironmentError() with patch_config_files("open", mock_open, create=True): return_value = config_files.read_authfile(self.mock_reporter, path) self.assertTrue(return_value is None) assert_report_item_list_equal( self.mock_reporter.report_item_list, [(severities.WARNING, report_codes.FILE_IO_ERROR, { "file_role": file_roles.BOOTH_KEY, "file_path": path, "reason": "reason", "operation": "read", })])
def test_success(self): path = join(BOOTH_CONFIG_DIR, "file.key") mock_open = mock.mock_open(read_data="key") with patch_config_files("open", mock_open, create=True): self.assertEqual( "key", config_files.read_authfile(self.mock_reporter, path) ) self.assertEqual( [ mock.call(path, "rb"), mock.call().__enter__(), mock.call().read(), mock.call().__exit__(None, None, None) ], mock_open.mock_calls ) self.assertEqual(0, len(self.mock_reporter.report_item_list))
def config_sync(env, name, skip_offline_nodes=False): """ Send specified local booth configuration to all nodes in cluster. env -- LibraryEnvironment name -- booth instance name skip_offline_nodes -- if True offline nodes will be skipped """ config = env.booth.get_config_content() authfile_path = config_structure.get_authfile(parse(config)) authfile_content = config_files.read_authfile(env.report_processor, authfile_path) sync.send_config_to_all_nodes(env.node_communicator(), env.report_processor, env.get_corosync_conf().get_nodes(), name, config, authfile=authfile_path, authfile_data=authfile_content, skip_offline=skip_offline_nodes)
def test_read_failure(self, _): path = join(BOOTH_CONFIG_DIR, "file.key") mock_open = mock.mock_open() mock_open().read.side_effect = EnvironmentError() with patch_config_files("open", mock_open, create=True): return_value = config_files.read_authfile(self.mock_reporter, path) self.assertTrue(return_value is None) assert_report_item_list_equal( self.mock_reporter.report_item_list, [( severities.WARNING, report_codes.FILE_IO_ERROR, { "file_role": file_roles.BOOTH_KEY, "file_path": path, "reason": "reason", "operation": "read", } )] )
def config_sync(env, name, skip_offline_nodes=False): """ Send specified local booth configuration to all nodes in cluster. env -- LibraryEnvironment name -- booth instance name skip_offline_nodes -- if True offline nodes will be skipped """ config = env.booth.get_config_content() authfile_path = config_structure.get_authfile(parse(config)) authfile_content = config_files.read_authfile( env.report_processor, authfile_path ) sync.send_config_to_all_nodes( env.node_communicator(), env.report_processor, env.get_corosync_conf().get_nodes(), name, config, authfile=authfile_path, authfile_data=authfile_content, skip_offline=skip_offline_nodes )
def send_all_config_to_node( communicator, reporter, node, rewrite_existing=False, skip_wrong_config=False ): """ Send all booth configs from default booth config directory and theri authfiles to specified node. communicator -- NodeCommunicator reporter -- report processor node -- NodeAddress rewrite_existing -- if True rewrite existing file skip_wrong_config -- if True skip local configs that are unreadable """ config_dict = booth_conf.read_configs(reporter, skip_wrong_config) if not config_dict: return reporter.process(reports.booth_config_distribution_started()) file_list = [] for config, config_data in sorted(config_dict.items()): try: authfile_path = config_structure.get_authfile( config_parser.parse(config_data) ) file_list.append({ "name": config, "data": config_data, "is_authfile": False }) if authfile_path: content = booth_conf.read_authfile(reporter, authfile_path) if not content: continue file_list.append({ "name": os.path.basename(authfile_path), "data": base64.b64encode(content).decode("utf-8"), "is_authfile": True }) except LibraryError: reporter.process(reports.booth_skipping_config( config, "unable to parse config" )) data = [("data_json", json.dumps(file_list))] if rewrite_existing: data.append(("rewrite_existing", "1")) try: response = json.loads(communicator.call_node( node, "remote/booth_save_files", NodeCommunicator.format_data_dict(data) )) report_list = [] for file in response["existing"]: report_list.append(lib_reports.file_already_exists( None, file, Severities.WARNING if rewrite_existing else Severities.ERROR, ( None if rewrite_existing else report_codes.FORCE_FILE_OVERWRITE ), node.label )) for file, reason in response["failed"].items(): report_list.append(reports.booth_config_distribution_node_error( node.label, reason, file )) reporter.process_list(report_list) reporter.process( reports.booth_config_accepted_by_node(node.label, response["saved"]) ) except NodeCommunicationException as e: raise LibraryError(node_communicator_exception_to_report_item(e)) except (KeyError, ValueError): raise LibraryError(lib_reports.invalid_response_format(node.label))
def test_path_none(self): self.assertTrue( config_files.read_authfile(self.mock_reporter, None) is None) self.assertEqual(0, len(self.mock_reporter.report_item_list))
def test_path_none(self): self.assertTrue( config_files.read_authfile(self.mock_reporter, None) is None ) self.assertEqual(0, len(self.mock_reporter.report_item_list))
def send_all_config_to_node( communicator, reporter, target, rewrite_existing=False, skip_wrong_config=False ): """ Send all booth configs from default booth config directory and theri authfiles to specified node. communicator -- NodeCommunicator reporter -- report processor node -- NodeAddress rewrite_existing -- if True rewrite existing file skip_wrong_config -- if True skip local configs that are unreadable """ config_dict = booth_conf.read_configs(reporter, skip_wrong_config) if not config_dict: return reporter.process(reports.booth_config_distribution_started()) file_list = [] for config, config_data in sorted(config_dict.items()): try: authfile_path = config_structure.get_authfile( config_parser.parse(config_data) ) file_list.append({ "name": config, "data": config_data, "is_authfile": False }) if authfile_path: content = booth_conf.read_authfile(reporter, authfile_path) if not content: continue file_list.append({ "name": os.path.basename(authfile_path), "data": base64.b64encode(content).decode("utf-8"), "is_authfile": True }) except LibraryError: reporter.process(reports.booth_skipping_config( config, "unable to parse config" )) com_cmd = BoothSaveFiles( reporter, file_list, rewrite_existing=rewrite_existing ) com_cmd.set_targets([target]) response = run_and_raise(communicator, com_cmd)[0][1] try: report_list = [] for file in response["existing"]: report_list.append(lib_reports.file_already_exists( None, file, Severities.WARNING if rewrite_existing else Severities.ERROR, ( None if rewrite_existing else report_codes.FORCE_FILE_OVERWRITE ), target.label )) for file, reason in response["failed"].items(): report_list.append(reports.booth_config_distribution_node_error( target.label, reason, file )) reporter.process_list(report_list) reporter.process( reports.booth_config_accepted_by_node(target.label, response["saved"]) ) except (KeyError, ValueError): raise LibraryError(lib_reports.invalid_response_format(target.label))
def send_all_config_to_node( communicator, reporter, node, rewrite_existing=False, skip_wrong_config=False ): """ Send all booth configs from default booth config directory and theri authfiles to specified node. communicator -- NodeCommunicator reporter -- report processor node -- NodeAddress rewrite_existing -- if True rewrite existing file skip_wrong_config -- if True skip local configs that are unreadable """ config_dict = booth_conf.read_configs(reporter, skip_wrong_config) if not config_dict: return file_list = [] for config, config_data in sorted(config_dict.items()): try: authfile_path = config_structure.get_authfile( config_parser.parse(config_data) ) file_list.append({ "name": config, "data": config_data, "is_authfile": False }) if authfile_path: content = booth_conf.read_authfile(reporter, authfile_path) if not content: continue file_list.append({ "name": os.path.basename(authfile_path), "data": base64.b64encode(content).decode("utf-8"), "is_authfile": True }) except LibraryError: reporter.process(reports.booth_skipping_config( config, "unable to parse config" )) data = [("data_json", json.dumps(file_list))] if rewrite_existing: data.append(("rewrite_existing", "1")) reporter.process(reports.booth_sending_local_configs_to_node(node.label)) try: response = json.loads(communicator.call_node( node, "remote/booth_save_files", NodeCommunicator.format_data_dict(data) )) report_list = [] for file in response["existing"]: report_list.append(lib_reports.file_already_exists( None, file, Severities.WARNING if rewrite_existing else Severities.ERROR, ( None if rewrite_existing else report_codes.FORCE_FILE_OVERWRITE ), node.label )) for file, reason in response["failed"].items(): report_list.append(reports.booth_config_not_saved( node.label, reason, file )) reporter.process_list(report_list) reporter.process( reports.booth_config_saved(node.label, response["saved"]) ) except NodeCommunicationException as e: raise LibraryError(node_communicator_exception_to_report_item(e)) except (KeyError, ValueError): raise LibraryError(lib_reports.invalid_response_format(node.label))