def parse_updates(self): parsed_options = {} for path in self._collect_revisions(): options = operating_system.read_file(path, codec=self._codec) guestagent_utils.update_dict(options, parsed_options) return parsed_options
def update_acl(username, keyspace, permission, acl): permissions = acl.get(username, {}).get(keyspace) if permissions is None: guestagent_utils.update_dict({user: {keyspace: {permission}}}, acl) else: permissions.add(permission)
def parse_updates(self): parsed_options = {} for path in self._collect_revision_files(): options = operating_system.read_file(path, codec=self._codec) guestagent_utils.update_dict(options, parsed_options) return parsed_options
def update_acl(username, keyspace, permission, acl): permissions = acl.get(username, {}).get(keyspace) if permissions is None: guestagent_utils.update_dict({user: { keyspace: {permission} }}, acl) else: permissions.add(permission)
def parse_updates(self): parsed_options = {} for path in self._collect_revision_files(): options = operating_system.read_file(path, codec=self._codec, as_root=self._requires_root) guestagent_utils.update_dict(options, parsed_options) LOG.debug(f"Parsed overrides options: {parsed_options}") return parsed_options
def _configure_network(self, port=None): """Make the service accessible at a given (or default if not) port. """ instance_ip = netutils.get_my_ipv4() bind_interfaces_string = ','.join([instance_ip, '127.0.0.1']) options = {'net.bindIp': bind_interfaces_string} if port is not None: guestagent_utils.update_dict({'net.port': port}, options) self.configuration_manager.apply_system_override(options) self.status.set_host(instance_ip, port=port)
def apply_next(self, options): revision_num = self.count_revisions() + 1 old_revision_backup = guestagent_utils.build_file_path( self._revision_backup_dir, self._base_config_name, str(revision_num), self._BACKUP_EXT ) operating_system.copy( self._base_config_path, old_revision_backup, force=True, preserve=True, as_root=self._requires_root ) current = operating_system.read_file(self._base_config_path, codec=self._codec) guestagent_utils.update_dict(options, current) operating_system.write_file(self._base_config_path, current, codec=self._codec, as_root=self._requires_root) operating_system.chown(self._base_config_path, self._owner, self._group, as_root=self._requires_root) operating_system.chmod(self._base_config_path, FileMode.ADD_READ_ALL, as_root=self._requires_root)
def parse_configuration(self): """Read contents of the configuration file (applying overrides if any) and parse it into a dict. :returns: Configuration file as a Python dict. """ base_options = operating_system.read_file(self._base_config_path, codec=self._codec) if self._override_strategy: updates = self._override_strategy.parse_updates() guestagent_utils.update_dict(updates, base_options) return base_options
def parse_configuration(self): """Read contents of the configuration file (applying overrides if any) and parse it into a dict. :returns: Configuration file as a Python dict. """ base_options = operating_system.read_file(self._base_config_path, codec=self._codec) updates = self._override_strategy.parse_updates() guestagent_utils.update_dict(updates, base_options) return base_options
def test_ini_file_codec(self): data_no_none = {"Section1": {"s1k1": 's1v1', "s1k2": '3.1415926535'}, "Section2": {"s2k1": '1', "s2k2": 'True'}} self._test_file_codec(data_no_none, IniCodec()) data_with_none = {"Section1": {"s1k1": 's1v1', "s1k2": '3.1415926535'}, "Section2": {"s2k1": '1', "s2k2": 'True', "s2k3": None}} # Keys with None values will be written without value. self._test_file_codec(data_with_none, IniCodec()) # Non-string values will be converted to strings. data_with_none_as_objects = {"Section1": {"s1k1": 's1v1', "s1k2": 3.1415926535}, "Section2": {"s2k1": 1, "s2k2": True, "s2k3": None}} self._test_file_codec(data_with_none_as_objects, IniCodec(), expected_data=data_with_none) # None will be replaced with 'default_value'. default_value = '1' expected_data = guestagent_utils.update_dict( {"Section2": {"s2k3": default_value}}, dict(data_with_none)) self._test_file_codec(data_with_none, IniCodec(default_value=default_value), expected_data=expected_data)
def apply(self, group_name, change_id, options): self._initialize_import_directory() revision_file = self._find_revision_file(group_name, change_id) if revision_file is None: # Create a new file. last_revision_index = self._get_last_file_index(group_name) revision_file = guestagent_utils.build_file_path( self._revision_dir, '%s-%03d-%s' % (group_name, last_revision_index + 1, change_id), self._revision_ext) else: # Update the existing file. current = operating_system.read_file( revision_file, codec=self._codec, as_root=self._requires_root) options = guestagent_utils.update_dict(options, current) operating_system.write_file( revision_file, options, codec=self._codec, as_root=self._requires_root) operating_system.chown( revision_file, self._owner, self._group, as_root=self._requires_root) operating_system.chmod( revision_file, FileMode.ADD_READ_ALL, as_root=self._requires_root)
def apply(self, group_name, change_id, options): revision_file = self._find_revision_file(group_name, change_id) if revision_file is None: # Create a new file. last_revision_index = self._get_last_file_index(group_name) revision_file = guestagent_utils.build_file_path( self._revision_dir, '%s-%03d-%s' % (group_name, last_revision_index + 1, change_id), self._revision_ext) else: # Update the existing file. current = operating_system.read_file(revision_file, codec=self._codec) options = guestagent_utils.update_dict(options, current) operating_system.write_file(revision_file, options, codec=self._codec, as_root=self._requires_root) operating_system.chown(revision_file, self._owner, self._group, as_root=self._requires_root) operating_system.chmod(revision_file, FileMode.ADD_READ_ALL, as_root=self._requires_root)
def parse_configuration(self): """Read contents of the configuration file (applying overrides if any) and parse it into a dict. :returns: Configuration file as a Python dict. """ try: base_options = operating_system.read_file( self._base_config_path, codec=self._codec, as_root=self._requires_root) except Exception: LOG.warning('File %s not found', self._base_config_path) return None updates = self._override_strategy.parse_updates() guestagent_utils.update_dict(updates, base_options) return base_options
def update_configuration(self, options): """Update given options in the configuration. The updates are stored in a 'system' revision if the manager supports configuration overrides. Otherwise they get applied directly to the base configuration file. The 'system' revision is always applied last to ensure it overrides any user-specified configuration changes. """ if self._override_strategy: # Update the system overrides. system_overrides = self._override_strategy.get(self._current_revision + 1) guestagent_utils.update_dict(options, system_overrides) # Re-apply the updated system overrides. self._override_strategy.remove_last(1) self._override_strategy.apply_next(system_overrides) else: # Update the base configuration file. config = self.parse_configuration() guestagent_utils.update_dict(options, config) self.render_configuration(config)
def test_update_dict(self): self.assertEqual({}, guestagent_utils.update_dict({}, {})) self.assertEqual({'key': 'value'}, guestagent_utils.update_dict({}, {'key': 'value'})) self.assertEqual({'key': 'value'}, guestagent_utils.update_dict({'key': 'value'}, {})) data = {'rpc_address': "0.0.0.0", 'broadcast_rpc_address': '0.0.0.0', 'listen_address': '0.0.0.0', 'seed_provider': [{ 'class_name': 'org.apache.cassandra.locator.SimpleSeedProvider', 'parameters': [{'seeds': '0.0.0.0'}]}] } updates = {'rpc_address': "127.0.0.1", 'seed_provider': {'parameters': {'seeds': '127.0.0.1'} } } updated = guestagent_utils.update_dict(updates, data) expected = {'rpc_address': "127.0.0.1", 'broadcast_rpc_address': '0.0.0.0', 'listen_address': '0.0.0.0', 'seed_provider': [{ 'class_name': 'org.apache.cassandra.locator.SimpleSeedProvider', 'parameters': [{'seeds': '127.0.0.1'}]}] } self.assertEqual(expected, updated) updates = {'seed_provider': [{'class_name': 'org.apache.cassandra.locator.SimpleSeedProvider' }] } updated = guestagent_utils.update_dict(updates, data) expected = {'rpc_address': "127.0.0.1", 'broadcast_rpc_address': '0.0.0.0', 'listen_address': '0.0.0.0', 'seed_provider': [{ 'class_name': 'org.apache.cassandra.locator.SimpleSeedProvider'}] } self.assertEqual(expected, updated) data = {'timeout': 0, 'save': [[900, 1], [300, 10]]} updates = {'save': [[900, 1], [300, 10], [60, 10000]]} updated = guestagent_utils.update_dict(updates, data) expected = {'timeout': 0, 'save': [[900, 1], [300, 10], [60, 10000]]} self.assertEqual(expected, updated)
def update_configuration(self, options): """Update given options in the configuration. The updates are stored in a 'system' revision if the manager supports configuration overrides. Otherwise they get applied directly to the base configuration file. The 'system' revision is always applied last to ensure it overrides any user-specified configuration changes. """ if self._override_strategy: # Update the system overrides. system_overrides = self._override_strategy.get( self._current_revision + 1) guestagent_utils.update_dict(options, system_overrides) # Re-apply the updated system overrides. self._override_strategy.remove_last(1) self._override_strategy.apply_next(system_overrides) else: # Update the base configuration file. config = self.parse_configuration() guestagent_utils.update_dict(options, config) self.render_configuration(config)
def apply_next(self, options): revision_num = self.count_revisions() + 1 old_revision_backup = guestagent_utils.build_file_path( self._revision_backup_dir, self._base_config_name, str(revision_num), self._BACKUP_EXT) operating_system.copy(self._base_config_path, old_revision_backup, force=True, preserve=True, as_root=self._requires_root) current = operating_system.read_file(self._base_config_path, codec=self._codec) guestagent_utils.update_dict(options, current) operating_system.write_file(self._base_config_path, current, codec=self._codec, as_root=self._requires_root) operating_system.chown(self._base_config_path, self._owner, self._group, as_root=self._requires_root) operating_system.chmod(self._base_config_path, FileMode.ADD_READ_ALL, as_root=self._requires_root)
def _regenerate_base_configuration(self): """Gather all configuration changes and apply them in order on the base revision. Write the results to the configuration file. """ if not os.path.exists(self._base_revision_file): # Initialize the file with the current configuration contents if it # does not exist. operating_system.copy( self._base_config_path, self._base_revision_file, force=True, preserve=True, as_root=self._requires_root) base_revision = operating_system.read_file( self._base_revision_file, codec=self._codec) changes = self._import_strategy.parse_updates() updated_revision = guestagent_utils.update_dict(changes, base_revision) operating_system.write_file( self._base_config_path, updated_revision, codec=self._codec, as_root=self._requires_root)
def _regenerate_base_configuration(self): """Gather all configuration changes and apply them in order on the base revision. Write the results to the configuration file. """ if not os.path.exists(self._base_revision_file): # Initialize the file with the current configuration contents if it # does not exist. operating_system.copy( self._base_config_path, self._base_revision_file, force=True, preserve=True, as_root=self._requires_root) base_revision = operating_system.read_file( self._base_revision_file, codec=self._codec, as_root=self._requires_root) changes = self._import_strategy.parse_updates() updated_revision = guestagent_utils.update_dict(changes, base_revision) operating_system.write_file( self._base_config_path, updated_revision, codec=self._codec, as_root=self._requires_root)
def test_update_dict(self): data = [{ 'dict': {}, 'update': {}, 'expected': {}, }, { 'dict': None, 'update': {}, 'expected': {}, }, { 'dict': {}, 'update': None, 'expected': {}, }, { 'dict': {}, 'update': None, 'expected': {}, }, { 'dict': None, 'update': {'name': 'Tom'}, 'expected': {'name': 'Tom'}, }, { 'dict': {}, 'update': {'name': 'Tom'}, 'expected': {'name': 'Tom'}, }, { 'dict': {'name': 'Tom'}, 'update': {}, 'expected': {'name': 'Tom'}, }, { 'dict': {'key1': 'value1', 'dict1': {'key1': 'value1', 'key2': 'value2'}}, 'update': {'key1': 'value1+', 'key2': 'value2', 'dict1': {'key3': 'value3'}}, 'expected': {'key1': 'value1+', 'key2': 'value2', 'dict1': {'key1': 'value1', 'key2': 'value2', 'key3': 'value3'}}, }, { 'dict': {'d1': {'d2': {'d3': {'k1': 'v1'}}}}, 'update': {'d1': {'d2': {'d3': {'k2': 'v2'}}}}, 'expected': {'d1': {'d2': {'d3': {'k1': 'v1', 'k2': 'v2'}}}}, }, { 'dict': {'timeout': 0, 'save': [[900, 1], [300, 10]]}, 'update': {'save': [[300, 20], [60, 10000]]}, 'expected': {'timeout': 0, 'save': [[300, 20], [60, 10000]]}, }, { 'dict': {'rpc_address': '0.0.0.0', 'broadcast_rpc_address': '0.0.0.0', 'listen_address': '0.0.0.0', 'seed_provider': [{ 'class_name': 'org.apache.cassandra.locator.SimpleSeedProvider', 'parameters': [{'seeds': '0.0.0.0'}]}] }, 'update': {'rpc_address': '127.0.0.1', 'seed_provider': {'parameters': { 'seeds': '127.0.0.1'}} }, 'expected': {'rpc_address': '127.0.0.1', 'broadcast_rpc_address': '0.0.0.0', 'listen_address': '0.0.0.0', 'seed_provider': [{ 'class_name': 'org.apache.cassandra.locator.SimpleSeedProvider', 'parameters': [{'seeds': '127.0.0.1'}]}] }, }, { 'dict': {'rpc_address': '127.0.0.1', 'broadcast_rpc_address': '0.0.0.0', 'listen_address': '0.0.0.0', 'seed_provider': [{ 'class_name': 'org.apache.cassandra.locator.SimpleSeedProvider', 'parameters': [{'seeds': '0.0.0.0'}]}] }, 'update': {'seed_provider': [{'class_name': 'org.apache.cassandra.locator.SimpleSeedProvider'}] }, 'expected': {'rpc_address': '127.0.0.1', 'broadcast_rpc_address': '0.0.0.0', 'listen_address': '0.0.0.0', 'seed_provider': [{ 'class_name': 'org.apache.cassandra.locator.SimpleSeedProvider' }]}, }] count = 0 for record in data: count += 1 target = record['dict'] update = record['update'] expected = record['expected'] result = guestagent_utils.update_dict(update, target) msg = 'Unexpected result for test %s' % str(count) self.assertEqual(expected, result, msg)
def test_update_dict(self): data = [{ 'dict': {}, 'update': {}, 'expected': {}, }, { 'dict': None, 'update': {}, 'expected': {}, }, { 'dict': {}, 'update': None, 'expected': {}, }, { 'dict': {}, 'update': None, 'expected': {}, }, { 'dict': None, 'update': { 'name': 'Tom' }, 'expected': { 'name': 'Tom' }, }, { 'dict': {}, 'update': { 'name': 'Tom' }, 'expected': { 'name': 'Tom' }, }, { 'dict': { 'name': 'Tom' }, 'update': {}, 'expected': { 'name': 'Tom' }, }, { 'dict': { 'key1': 'value1', 'dict1': { 'key1': 'value1', 'key2': 'value2' } }, 'update': { 'key1': 'value1+', 'key2': 'value2', 'dict1': { 'key3': 'value3' } }, 'expected': { 'key1': 'value1+', 'key2': 'value2', 'dict1': { 'key1': 'value1', 'key2': 'value2', 'key3': 'value3' } }, }, { 'dict': { 'd1': { 'd2': { 'd3': { 'k1': 'v1' } } } }, 'update': { 'd1': { 'd2': { 'd3': { 'k2': 'v2' } } } }, 'expected': { 'd1': { 'd2': { 'd3': { 'k1': 'v1', 'k2': 'v2' } } } }, }, { 'dict': { 'timeout': 0, 'save': [[900, 1], [300, 10]] }, 'update': { 'save': [[300, 20], [60, 10000]] }, 'expected': { 'timeout': 0, 'save': [[300, 20], [60, 10000]] }, }, { 'dict': { 'rpc_address': '0.0.0.0', 'broadcast_rpc_address': '0.0.0.0', 'listen_address': '0.0.0.0', 'seed_provider': [{ 'class_name': 'org.apache.cassandra.locator.SimpleSeedProvider', 'parameters': [{ 'seeds': '0.0.0.0' }] }] }, 'update': { 'rpc_address': '127.0.0.1', 'seed_provider': { 'parameters': { 'seeds': '127.0.0.1' } } }, 'expected': { 'rpc_address': '127.0.0.1', 'broadcast_rpc_address': '0.0.0.0', 'listen_address': '0.0.0.0', 'seed_provider': [{ 'class_name': 'org.apache.cassandra.locator.SimpleSeedProvider', 'parameters': [{ 'seeds': '127.0.0.1' }] }] }, }, { 'dict': { 'rpc_address': '127.0.0.1', 'broadcast_rpc_address': '0.0.0.0', 'listen_address': '0.0.0.0', 'seed_provider': [{ 'class_name': 'org.apache.cassandra.locator.SimpleSeedProvider', 'parameters': [{ 'seeds': '0.0.0.0' }] }] }, 'update': { 'seed_provider': [{ 'class_name': 'org.apache.cassandra.locator.SimpleSeedProvider' }] }, 'expected': { 'rpc_address': '127.0.0.1', 'broadcast_rpc_address': '0.0.0.0', 'listen_address': '0.0.0.0', 'seed_provider': [{ 'class_name': 'org.apache.cassandra.locator.SimpleSeedProvider' }] }, }] count = 0 for record in data: count += 1 target = record['dict'] update = record['update'] expected = record['expected'] result = guestagent_utils.update_dict(update, target) msg = 'Unexpected result for test %s' % str(count) self.assertEqual(expected, result, msg)
def test_update_dict(self): self.assertEqual({}, guestagent_utils.update_dict({}, {})) self.assertEqual({'key': 'value'}, guestagent_utils.update_dict({}, {'key': 'value'})) self.assertEqual({'key': 'value'}, guestagent_utils.update_dict({'key': 'value'}, {})) data = { 'rpc_address': "0.0.0.0", 'broadcast_rpc_address': '0.0.0.0', 'listen_address': '0.0.0.0', 'seed_provider': [{ 'class_name': 'org.apache.cassandra.locator.SimpleSeedProvider', 'parameters': [{ 'seeds': '0.0.0.0' }] }] } updates = { 'rpc_address': "127.0.0.1", 'seed_provider': { 'parameters': { 'seeds': '127.0.0.1' } } } updated = guestagent_utils.update_dict(updates, data) expected = { 'rpc_address': "127.0.0.1", 'broadcast_rpc_address': '0.0.0.0', 'listen_address': '0.0.0.0', 'seed_provider': [{ 'class_name': 'org.apache.cassandra.locator.SimpleSeedProvider', 'parameters': [{ 'seeds': '127.0.0.1' }] }] } self.assertEqual(expected, updated) updates = { 'seed_provider': [{ 'class_name': 'org.apache.cassandra.locator.SimpleSeedProvider' }] } updated = guestagent_utils.update_dict(updates, data) expected = { 'rpc_address': "127.0.0.1", 'broadcast_rpc_address': '0.0.0.0', 'listen_address': '0.0.0.0', 'seed_provider': [{ 'class_name': 'org.apache.cassandra.locator.SimpleSeedProvider' }] } self.assertEqual(expected, updated) data = {'timeout': 0, 'save': [[900, 1], [300, 10]]} updates = {'save': [[900, 1], [300, 10], [60, 10000]]} updated = guestagent_utils.update_dict(updates, data) expected = {'timeout': 0, 'save': [[900, 1], [300, 10], [60, 10000]]} self.assertEqual(expected, updated)