Added support for settings / clearing multiple properties in a single call.

Jira-Issue: OSTACKDEV-19
This commit is contained in:
Borne Mace 2016-04-13 10:45:02 -07:00
parent 89327d10b2
commit 7a1547aa47
7 changed files with 88 additions and 59 deletions

View File

@ -63,14 +63,12 @@ class PropertyApi(object):
self.ovr_group = False
self.ovr_host = False
def property_set(self, key, value,
def property_set(self, property_dict,
property_type=GLOBAL_TYPE, change_set=None):
"""Set a property
:param key: property key
:type key: string
:param value: property value
:type value: string
:param property_dict: property dictionary containing key / values
:type property_dict: dictionary
:param property_type: one of 'global', 'group' or 'host'
:type property_type: string
:param change_set: for group or host sets this is the list of groups
@ -78,10 +76,11 @@ class PropertyApi(object):
:type change_set: list of strings
"""
check_arg(key, u._('Property Key'), str)
key = safe_decode(key)
check_arg(value, u._('Property Value'), str)
value = safe_decode(value)
for key, value in property_dict.items():
check_arg(key, u._('Property Key'), str)
check_arg(value, u._('Property Value'), str)
property_dict = safe_decode(property_dict)
self._check_type(property_type)
if property_type is not GLOBAL_TYPE:
check_arg(change_set, u._('Change Set'), list, none_ok=True)
@ -90,18 +89,18 @@ class PropertyApi(object):
ansible_properties = AnsibleProperties()
if property_type == GLOBAL_TYPE:
ansible_properties.set_property(key, value)
ansible_properties.set_property(property_dict)
elif property_type == GROUP_TYPE:
ansible_properties.set_group_property(key, value, change_set)
ansible_properties.set_group_property(property_dict, change_set)
else:
ansible_properties.set_host_property(key, value, change_set)
ansible_properties.set_host_property(property_dict, change_set)
def property_clear(self, key, property_type=GLOBAL_TYPE,
def property_clear(self, property_list, property_type=GLOBAL_TYPE,
change_set=None):
"""Clear a property
:param key: property key
:type key: string
:param property_list: property list
:type property_list: list
:param property_type: one of 'global', 'group' or 'host'
:type property_type: string
:param change_set: for group or host clears this is the list of
@ -109,8 +108,9 @@ class PropertyApi(object):
:type change_set: list of strings
"""
check_arg(key, u._('Property Key'), str)
key = safe_decode(key)
check_arg(property_list, u._('Property List'), list)
property_list = safe_decode(property_list)
self._check_type(property_type)
if property_type is not GLOBAL_TYPE:
check_arg(change_set, u._('Change Set'), list, none_ok=True)
@ -119,11 +119,11 @@ class PropertyApi(object):
ansible_properties = AnsibleProperties()
if property_type == GLOBAL_TYPE:
ansible_properties.clear_property(key)
ansible_properties.clear_property(property_list)
elif property_type == GROUP_TYPE:
ansible_properties.clear_group_property(key, change_set)
ansible_properties.clear_group_property(property_list, change_set)
else:
ansible_properties.clear_host_property(key, change_set)
ansible_properties.clear_host_property(property_list, change_set)
def property_get(self, property_type=GLOBAL_TYPE, get_set=None):
"""Returns a list of Property objects

View File

@ -54,6 +54,8 @@ class PropertySet(Command):
try:
property_name = parsed_args.propertyname.strip()
property_value = parsed_args.propertyvalue.strip()
property_dict = {}
property_dict[property_name] = property_value
if parsed_args.hosts:
if parsed_args.groups:
@ -63,16 +65,16 @@ class PropertySet(Command):
host_names = _get_names(parsed_args.hosts)
CLIENT.property_set(property_name, property_value,
CLIENT.property_set(property_dict,
'host', host_names)
elif parsed_args.groups:
group_names = _get_names(parsed_args.groups)
CLIENT.property_set(property_name, property_value,
CLIENT.property_set(property_dict,
'group', group_names)
else:
CLIENT.property_set(property_name, property_value,
CLIENT.property_set(property_dict,
'global')
except Exception:
@ -97,6 +99,8 @@ class PropertyClear(Command):
def take_action(self, parsed_args):
try:
property_name = parsed_args.propertyname.strip()
property_list = []
property_list.append(property_name)
if parsed_args.hosts:
if parsed_args.groups:
@ -106,15 +110,15 @@ class PropertyClear(Command):
host_names = _get_names(parsed_args.hosts)
CLIENT.property_clear(property_name, 'host',
CLIENT.property_clear(property_list, 'host',
host_names)
elif parsed_args.groups:
group_names = _get_names(parsed_args.groups)
CLIENT.property_clear(property_name, 'group',
CLIENT.property_clear(property_list, 'group',
group_names)
else:
CLIENT.property_clear(property_name, 'global')
CLIENT.property_clear(property_list, 'global')
except Exception:
raise Exception(traceback.format_exc())

View File

@ -242,14 +242,14 @@ class AnsibleProperties(object):
new_contents[key] = value
return new_contents
def set_property(self, property_key, property_value):
def set_property(self, property_dict):
try:
change_property(self.globals_path, property_key,
property_value, clear=False)
change_property(self.globals_path, property_dict,
clear=False)
except Exception as e:
raise e
def set_host_property(self, property_key, property_value, hosts):
def set_host_property(self, property_dict, hosts):
# if hosts is None set the property on all hosts
inventory = Inventory.load()
host_list = []
@ -264,12 +264,12 @@ class AnsibleProperties(object):
try:
for host in host_list:
file_path = os.path.join(get_host_vars_dir(), host.name)
change_property(file_path, property_key,
property_value, clear=False)
change_property(file_path, property_dict,
clear=False)
except Exception as e:
raise e
def set_group_property(self, property_key, property_value, groups):
def set_group_property(self, property_dict, groups):
# if groups is None set the property on all hosts
inventory = Inventory.load()
group_list = []
@ -284,19 +284,20 @@ class AnsibleProperties(object):
try:
for group in group_list:
file_path = os.path.join(get_group_vars_dir(), group.name)
change_property(file_path, property_key,
property_value, clear=False)
change_property(file_path, property_dict,
clear=False)
except Exception as e:
raise e
def clear_property(self, property_key):
def clear_property(self, property_list):
try:
change_property(self.globals_path, property_key,
None, clear=True)
change_property(self.globals_path,
self._list_to_dict(property_list),
clear=True)
except Exception as e:
raise e
def clear_host_property(self, property_key, hosts):
def clear_host_property(self, property_list, hosts):
# if hosts is None set the property on all hosts
inventory = Inventory.load()
host_list = []
@ -311,12 +312,12 @@ class AnsibleProperties(object):
try:
for host in host_list:
file_path = os.path.join(get_host_vars_dir(), host.name)
change_property(file_path, property_key,
None, clear=True)
change_property(file_path, self._list_to_dict(property_list),
clear=True)
except Exception as e:
raise e
def clear_group_property(self, property_key, groups):
def clear_group_property(self, property_list, groups):
# if hosts is None set the property on all hosts
inventory = Inventory.load()
group_list = []
@ -331,11 +332,17 @@ class AnsibleProperties(object):
try:
for group in group_list:
file_path = os.path.join(get_group_vars_dir(), group.name)
change_property(file_path, property_key,
None, clear=True)
change_property(file_path, self._list_to_dict(property_list),
clear=True)
except Exception as e:
raise e
def _list_to_dict(self, property_list):
property_dict = {}
for key in property_list:
property_dict[key] = ''
return property_dict
class AnsibleProperty(object):

View File

@ -176,12 +176,11 @@ def run_cmd(cmd, print_output=True):
return err, output
def change_property(file_path, property_key, property_value, clear=False):
def change_property(file_path, property_dict, clear=False):
"""change property with a file
file_path: path to property file
property_key: property name
property value: property value
property_dict: dictionary of property names and values
clear: flag to remove property
If clear, and property exists, remove it from the property file.
@ -199,8 +198,6 @@ def change_property(file_path, property_key, property_value, clear=False):
new_contents = []
read_data = sync_read_file(file_path)
lines = read_data.split('\n')
new_line = '%s: "%s"' % (property_key, property_value)
property_key_found = False
last_line_empty = False
for line in lines:
line = line.rstrip()
@ -217,17 +214,21 @@ def change_property(file_path, property_key, property_value, clear=False):
if len(split_line) > 1:
split_key = split_line[0]
split_key.rstrip()
if split_key == property_key:
property_key_found = True
if split_key in property_dict:
if clear:
# clear existing property
continue
# edit existing property
line = new_line
line = '%s: "%s"' % (split_key, property_dict[split_key])
# clear out the key after we are done, all existing keys
# will be appended at the end (or for clear, ignored)
del property_dict[split_key]
new_contents.append(line)
if not property_key_found and not clear:
# add new property to file
new_contents.append(new_line)
if not clear:
# add new properties to file
for key, value in property_dict.items():
line = '%s: "%s"' % (key, value)
new_contents.append(line)
write_data = '\n'.join(new_contents)
sync_write_file(file_path, write_data)
@ -310,6 +311,16 @@ def safe_decode(obj_to_decode):
# py3 will raise if text is already a string
pass
new_obj.append(text)
elif isinstance(obj_to_decode, dict):
new_obj = {}
for key, value in obj_to_decode.items():
try:
new_key = key.decode('utf-8')
new_value = value.decode('utf-8')
new_obj[new_key] = new_value
except AttributeError: # nosec
# py3 will raise if it is already a string
pass
else:
try:
new_obj = obj_to_decode.decode('utf-8')
@ -350,7 +361,7 @@ def check_arg(param, param_name, expected_type, none_ok=False, empty_ok=False):
class Lock(object):
""" Object which represents an exclusive resource lock
"""Object which represents an exclusive resource lock
flock usage is the default behavior but a separate pidfile mechanism
is also available. flock doesn't have the same orphaned lock issue

View File

@ -9,6 +9,7 @@ coverage>=3.6
discover
fixtures>=0.3.14
mock>=1.0
pexpect>=4.0.1
sphinx>=1.1.2,!=1.2.0,!=1.3b1,<1.3
sphinxcontrib-pecanwsme>=0.8
testrepository>=0.0.18

View File

@ -85,11 +85,15 @@ class TestFunctional(KollaCliTest):
self.log.info('updating various properties for the test')
# disable most services so the test is quicker
disabled_service_props = {}
for disabled_service in DISABLED_SERVICES:
CLIENT.property_set('enable_%s' % disabled_service, 'no')
disabled_service_props['enable_%s' % disabled_service] = 'no'
CLIENT.property_set(disabled_service_props)
enabled_service_props = {}
for enabled_service in ENABLED_SERVICES:
CLIENT.property_set('enable_%s' % enabled_service, 'yes')
enabled_service_props['enable_%s' % enabled_service] = 'yes'
CLIENT.property_set(enabled_service_props)
predeploy_cmds = test_config.get_predeploy_cmds()
for predeploy_cmd in predeploy_cmds:

View File

@ -70,7 +70,9 @@ def _password_cmd(argv):
_print_pwd_keys(path)
else:
# edit a password
change_property(path, pwd_key, pwd_value, clear_flag)
property_dict = {}
property_dict[pwd_key] = pwd_value
change_property(path, property_dict, clear_flag)
def _job_cmd(argv):