kolla-cli/kolla_cli/api/properties.py

199 lines
7.8 KiB
Python

# Copyright(c) 2016, Oracle and/or its affiliates. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import logging
import yaml
from kolla_cli.api.exceptions import InvalidArgument
from kolla_cli.common.properties import AnsibleProperties
from kolla_cli.common.utils import check_arg
from kolla_cli.common.utils import safe_decode
import kolla_cli.i18n as u
MYPY = False
if MYPY:
from typing import Dict # noqa
from typing import List # noqa
LOG = logging.getLogger(__name__)
GLOBAL_TYPE = 'global'
GROUP_TYPE = 'group'
HOST_TYPE = 'host'
PROP_TYPES = [GLOBAL_TYPE, GROUP_TYPE, HOST_TYPE]
class PropertyApi(object):
def property_set(self, property_dict,
property_type=GLOBAL_TYPE, change_set=None):
# type: (Dict[str,str], str, List[str]) -> None
"""Set a property
: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
or hosts to set the property for
:type change_set: list of strings
"""
ansible_properties = AnsibleProperties()
for key, value in property_dict.items():
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:
original_value = value
value = yaml.safe_load(value)
# this check is to make sure that we can assign an empty
# string to a property. without this safe_load will turn
# an empty string into a None which is different than an
# empty string.
if isinstance(original_value, str) and value is None:
value = ''
if current_property.value is None:
current_property_type = None
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)
if type(value) is str and '"' in value:
raise InvalidArgument(u._('Cannot use double quotes in '
'a property value.'))
self._check_type(property_type)
if property_type is not GLOBAL_TYPE:
check_arg(change_set, u._('Change Set'), list, none_ok=True)
change_set = safe_decode(change_set)
if property_type == GLOBAL_TYPE:
ansible_properties.set_property(property_dict)
elif property_type == GROUP_TYPE:
ansible_properties.set_group_property(property_dict, change_set)
else:
ansible_properties.set_host_property(property_dict, change_set)
def property_clear(self, property_list, property_type=GLOBAL_TYPE,
change_set=None):
# type: (List[str], str, List[str]) -> None
"""Clear a property
: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
groups or hosts to clear the property for
:type change_set: list of strings
"""
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)
change_set = safe_decode(change_set)
ansible_properties = AnsibleProperties()
if property_type == GLOBAL_TYPE:
ansible_properties.clear_property(property_list)
elif property_type == GROUP_TYPE:
ansible_properties.clear_group_property(property_list, change_set)
else:
ansible_properties.clear_host_property(property_list, change_set)
def property_get(self, property_type=GLOBAL_TYPE, get_set=None):
# type: (str, List[str]) -> List[Property]
"""Returns a list of Property objects
:param property_type: one of 'global', 'group', or 'host'
:type property_type: string
:param get_set: optional list of hosts or groups to be used when
getting group or host related property lists
:type get_set: list of strings
:return: properties
:rtype: list of Property objects
"""
self._check_type(property_type)
get_set = safe_decode(get_set)
ansible_properties = AnsibleProperties()
result_list = []
if property_type == GLOBAL_TYPE:
property_list = ansible_properties.get_all_unique()
elif property_type == GROUP_TYPE:
property_list = ansible_properties.get_group_list(get_set)
else:
property_list = ansible_properties.get_host_list(get_set)
override_flags = ansible_properties.get_all_override_flags()
for prop in property_list:
result = Property(prop, override_flags.get(prop.name, None))
result_list.append(result)
return result_list
def _check_type(self, property_type):
if property_type is None or property_type not in PROP_TYPES:
raise InvalidArgument(u._('Property Type ({value} is not one of '
'global, group or host')
.format(value=property_type))
class Property(object):
"""Property
Members:
- name (str): key
- value (Any): value
- file_name (str): name of file property is from
- overrides (bool): does the property override some other value
- orig_value (str): the value which is overridden or None
- target (str): group or host name for group or host properties
- prop_type (str): one of 'global', 'group' or 'host'
- ovr_global (bool): true if property is overridden at global level
- ovr_group (bool): true if property is overridden at group 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):
self.name = ansible_property.name
self.value = ansible_property.value
self.file_name = ansible_property.file_name
self.overrides = ansible_property.overrides
self.orig_value = ansible_property.orig_value
self.target = ansible_property.target
self.prop_type = ansible_property.prop_type
self.value_type = ansible_property.value_type
if override_flags is not None:
self.ovr_global = override_flags.ovr_global
self.ovr_group = override_flags.ovr_group
self.ovr_host = override_flags.ovr_host
else:
self.ovr_global = False
self.ovr_group = False
self.ovr_host = False