Support modification of non string properties
Support modification of non string properties. Introduced the concept of types to the AnsibleProperty object and when a property is set if the type is not str or None then the value will be loaded via yaml and processed into the appropriate python type. At write time it is then written out via yaml dump rather than always writing it out as a string. Change-Id: Iab1d10430cb919cf968e4357c93e23ed360bf338 Jira-Issue: OPENSTACK-1698
This commit is contained in:
parent
c8a5730220
commit
3d47927ad3
@ -12,6 +12,7 @@
|
|||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
import logging
|
import logging
|
||||||
|
import yaml
|
||||||
|
|
||||||
import kollacli.i18n as u
|
import kollacli.i18n as u
|
||||||
|
|
||||||
@ -44,21 +45,29 @@ class PropertyApi(object):
|
|||||||
:type change_set: list of strings
|
:type change_set: list of strings
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
ansible_properties = AnsibleProperties()
|
||||||
for key, value in property_dict.items():
|
for key, value in property_dict.items():
|
||||||
check_arg(key, u._('Property Key'), str)
|
check_arg(key, u._('Property Key'), str)
|
||||||
|
current_property = ansible_properties.get_property(key)
|
||||||
|
if current_property is not None:
|
||||||
|
current_property_type = current_property.value_type
|
||||||
|
if (current_property_type is not str and
|
||||||
|
current_property is not None):
|
||||||
|
value = yaml.safe_load(value)
|
||||||
|
check_arg(value, u._('Property Value'),
|
||||||
|
current_property_type, empty_ok=True)
|
||||||
|
property_dict[key] = value
|
||||||
|
else:
|
||||||
check_arg(value, u._('Property Value'), str, empty_ok=True)
|
check_arg(value, u._('Property Value'), str, empty_ok=True)
|
||||||
if '"' in value:
|
if type(value) is str and '"' in value:
|
||||||
raise InvalidArgument(u._('Cannot use double quotes in '
|
raise InvalidArgument(u._('Cannot use double quotes in '
|
||||||
'a property value.'))
|
'a property value.'))
|
||||||
property_dict = safe_decode(property_dict)
|
|
||||||
|
|
||||||
self._check_type(property_type)
|
self._check_type(property_type)
|
||||||
if property_type is not GLOBAL_TYPE:
|
if property_type is not GLOBAL_TYPE:
|
||||||
check_arg(change_set, u._('Change Set'), list, none_ok=True)
|
check_arg(change_set, u._('Change Set'), list, none_ok=True)
|
||||||
change_set = safe_decode(change_set)
|
change_set = safe_decode(change_set)
|
||||||
|
|
||||||
ansible_properties = AnsibleProperties()
|
|
||||||
|
|
||||||
if property_type == GLOBAL_TYPE:
|
if property_type == GLOBAL_TYPE:
|
||||||
ansible_properties.set_property(property_dict)
|
ansible_properties.set_property(property_dict)
|
||||||
elif property_type == GROUP_TYPE:
|
elif property_type == GROUP_TYPE:
|
||||||
@ -142,7 +151,7 @@ class Property(object):
|
|||||||
|
|
||||||
Members:
|
Members:
|
||||||
- name (str): key
|
- name (str): key
|
||||||
- value (str): value
|
- value (Any): value
|
||||||
- file_name (str): name of file property is from
|
- file_name (str): name of file property is from
|
||||||
- overrides (bool): does the property override some other value
|
- overrides (bool): does the property override some other value
|
||||||
- orig_value (str): the value which is overridden or None
|
- orig_value (str): the value which is overridden or None
|
||||||
@ -151,6 +160,7 @@ class Property(object):
|
|||||||
- ovr_global (bool): true if property is overridden at global level
|
- ovr_global (bool): true if property is overridden at global level
|
||||||
- ovr_group (bool): true if property is overridden at group level
|
- ovr_group (bool): true if property is overridden at group level
|
||||||
- ovr_host (bool): true if property is overridden at host level
|
- ovr_host (bool): true if property is overridden at host level
|
||||||
|
- value_type (type): the python type of the value
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, ansible_property, override_flags):
|
def __init__(self, ansible_property, override_flags):
|
||||||
@ -161,6 +171,7 @@ class Property(object):
|
|||||||
self.orig_value = ansible_property.orig_value
|
self.orig_value = ansible_property.orig_value
|
||||||
self.target = ansible_property.target
|
self.target = ansible_property.target
|
||||||
self.prop_type = ansible_property.prop_type
|
self.prop_type = ansible_property.prop_type
|
||||||
|
self.value_type = ansible_property.value_type
|
||||||
|
|
||||||
if override_flags is not None:
|
if override_flags is not None:
|
||||||
self.ovr_global = override_flags.ovr_global
|
self.ovr_global = override_flags.ovr_global
|
||||||
|
@ -219,8 +219,9 @@ def _run_deploy_rules(playbook):
|
|||||||
expected_files = ['account.ring.gz',
|
expected_files = ['account.ring.gz',
|
||||||
'container.ring.gz',
|
'container.ring.gz',
|
||||||
'object.ring.gz']
|
'object.ring.gz']
|
||||||
is_enabled = properties.get_property('enable_swift')
|
is_swift_enabled = _is_service_enabled('swift', inventory, properties)
|
||||||
if is_string_true(is_enabled):
|
|
||||||
|
if is_swift_enabled:
|
||||||
path_pre = os.path.join(get_kolla_etc(), 'config', 'swift')
|
path_pre = os.path.join(get_kolla_etc(), 'config', 'swift')
|
||||||
for expected_file in expected_files:
|
for expected_file in expected_files:
|
||||||
path = os.path.join(path_pre, expected_file)
|
path = os.path.join(path_pre, expected_file)
|
||||||
@ -235,15 +236,10 @@ def _run_deploy_rules(playbook):
|
|||||||
|
|
||||||
|
|
||||||
def _is_service_enabled(servicename, inventory, properties):
|
def _is_service_enabled(servicename, inventory, properties):
|
||||||
service_enabled = False
|
|
||||||
|
|
||||||
service = inventory.get_service(servicename)
|
service = inventory.get_service(servicename)
|
||||||
if service is not None:
|
if service is not None:
|
||||||
enabled_property = 'enable_' + servicename.replace('-', '_')
|
enabled_property = 'enable_' + servicename.replace('-', '_')
|
||||||
is_enabled = properties.get_property(enabled_property)
|
is_enabled = properties.get_property_value(enabled_property)
|
||||||
if is_string_true(is_enabled):
|
if type(is_enabled) is str:
|
||||||
service_enabled = True
|
is_enabled = is_string_true(is_enabled)
|
||||||
else:
|
return is_enabled
|
||||||
service_enabled = False
|
|
||||||
|
|
||||||
return service_enabled
|
|
||||||
|
@ -14,7 +14,6 @@
|
|||||||
import copy
|
import copy
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
import six
|
|
||||||
import yaml
|
import yaml
|
||||||
|
|
||||||
import kollacli.i18n as u
|
import kollacli.i18n as u
|
||||||
@ -220,7 +219,7 @@ class AnsibleProperties(object):
|
|||||||
prop_list += self.group_props[group.name]
|
prop_list += self.group_props[group.name]
|
||||||
return prop_list
|
return prop_list
|
||||||
|
|
||||||
def get_property(self, property_name):
|
def get_property_value(self, property_name):
|
||||||
self._load_properties()
|
self._load_properties()
|
||||||
prop_val = None
|
prop_val = None
|
||||||
if property_name in self.unique_global_props:
|
if property_name in self.unique_global_props:
|
||||||
@ -228,6 +227,10 @@ class AnsibleProperties(object):
|
|||||||
prop_val = prop.value
|
prop_val = prop.value
|
||||||
return prop_val
|
return prop_val
|
||||||
|
|
||||||
|
def get_property(self, property_name):
|
||||||
|
self._load_properties()
|
||||||
|
return self.unique_global_props.get(property_name)
|
||||||
|
|
||||||
def get_all_unique(self):
|
def get_all_unique(self):
|
||||||
self._load_properties()
|
self._load_properties()
|
||||||
unique_list = []
|
unique_list = []
|
||||||
@ -239,21 +242,6 @@ class AnsibleProperties(object):
|
|||||||
self._load_properties()
|
self._load_properties()
|
||||||
return self.unique_override_flags
|
return self.unique_override_flags
|
||||||
|
|
||||||
# TODO(bmace) -- if this isn't used for 2.1.x it should be removed
|
|
||||||
# property listing is still being tweaked so leaving for
|
|
||||||
# the time being in case we want to use it
|
|
||||||
def filter_jinja2(self, contents):
|
|
||||||
new_contents = {}
|
|
||||||
for key, value in contents.items():
|
|
||||||
if not isinstance(value, six.string_types):
|
|
||||||
LOG.debug('removing non-string: %s', value)
|
|
||||||
continue
|
|
||||||
if value and '{{' in value and '}}' in value:
|
|
||||||
LOG.debug('removing jinja2 value: %s', value)
|
|
||||||
continue
|
|
||||||
new_contents[key] = value
|
|
||||||
return new_contents
|
|
||||||
|
|
||||||
def set_property(self, property_dict):
|
def set_property(self, property_dict):
|
||||||
change_property(self.globals_path, property_dict,
|
change_property(self.globals_path, property_dict,
|
||||||
clear=False)
|
clear=False)
|
||||||
@ -365,6 +353,7 @@ class AnsibleProperty(object):
|
|||||||
self.overrides = overrides
|
self.overrides = overrides
|
||||||
self.orig_value = orig_value
|
self.orig_value = orig_value
|
||||||
self.target = target
|
self.target = target
|
||||||
|
self.value_type = type(value)
|
||||||
|
|
||||||
|
|
||||||
class OverrideFlags(object):
|
class OverrideFlags(object):
|
||||||
|
@ -62,9 +62,9 @@ class HostLogs(object):
|
|||||||
|
|
||||||
ansible_properties = AnsibleProperties()
|
ansible_properties = AnsibleProperties()
|
||||||
base_distro = \
|
base_distro = \
|
||||||
ansible_properties.get_property('kolla_base_distro')
|
ansible_properties.get_property_value('kolla_base_distro')
|
||||||
install_type = \
|
install_type = \
|
||||||
ansible_properties.get_property('kolla_install_type')
|
ansible_properties.get_property_value('kolla_install_type')
|
||||||
# typically this prefix will be "ol-openstack-"
|
# typically this prefix will be "ol-openstack-"
|
||||||
container_prefix = base_distro + '-' + install_type + '-'
|
container_prefix = base_distro + '-' + install_type + '-'
|
||||||
|
|
||||||
|
@ -286,7 +286,13 @@ def change_property(file_path, property_dict, clear=False):
|
|||||||
# clear existing property
|
# clear existing property
|
||||||
continue
|
continue
|
||||||
# edit existing property
|
# edit existing property
|
||||||
line = '%s: "%s"' % (split_key, cloned_dict[split_key])
|
value = cloned_dict[split_key]
|
||||||
|
if type(value) is not str:
|
||||||
|
value = yaml.safe_dump(value).strip()
|
||||||
|
line = '%s: %s' % (split_key, value)
|
||||||
|
else:
|
||||||
|
line = '%s: "%s"' % (split_key, value)
|
||||||
|
|
||||||
# clear out the key after we are done, all existing keys
|
# clear out the key after we are done, all existing keys
|
||||||
# will be appended at the end (or for clear, ignored)
|
# will be appended at the end (or for clear, ignored)
|
||||||
del cloned_dict[split_key]
|
del cloned_dict[split_key]
|
||||||
@ -294,10 +300,22 @@ def change_property(file_path, property_dict, clear=False):
|
|||||||
if not clear:
|
if not clear:
|
||||||
# add new properties to file
|
# add new properties to file
|
||||||
for key, value in cloned_dict.items():
|
for key, value in cloned_dict.items():
|
||||||
|
if type(value) is not str:
|
||||||
|
value = yaml.safe_dump(value).strip()
|
||||||
|
line = '%s: %s' % (key, value)
|
||||||
|
else:
|
||||||
line = '%s: "%s"' % (key, value)
|
line = '%s: "%s"' % (key, value)
|
||||||
|
|
||||||
|
# when we are doing an append we want to avoid
|
||||||
|
# blank lines before the new entry
|
||||||
|
if new_contents[-1:][0] == '':
|
||||||
|
del new_contents[-1]
|
||||||
new_contents.append(line)
|
new_contents.append(line)
|
||||||
|
|
||||||
write_data = '\n'.join(new_contents)
|
# if the last line is blank, trim it off
|
||||||
|
if new_contents[-1:][0] == '':
|
||||||
|
del new_contents[-1]
|
||||||
|
write_data = '\n'.join(new_contents) + '\n'
|
||||||
sync_write_file(file_path, write_data)
|
sync_write_file(file_path, write_data)
|
||||||
|
|
||||||
|
|
||||||
|
@ -195,8 +195,8 @@ class TestFunctional(KollaCliTest):
|
|||||||
bad_path = self._is_size_ok(sizes, 0, '=', 3)
|
bad_path = self._is_size_ok(sizes, 0, '=', 3)
|
||||||
self.assertIsNone(bad_path, 'Size of file %s is ' % bad_path +
|
self.assertIsNone(bad_path, 'Size of file %s is ' % bad_path +
|
||||||
'different from initial size '
|
'different from initial size '
|
||||||
'(%s %s)'
|
'(%s %s %s)'
|
||||||
% (switch, targets_csv))
|
% (switch, targets_csv, str(sizes)))
|
||||||
|
|
||||||
# test setting empty string
|
# test setting empty string
|
||||||
value = '""'
|
value = '""'
|
||||||
|
Loading…
Reference in New Issue
Block a user