Added config schema right into Configuration
This commit is contained in:
parent
452648b434
commit
e77e3c88d9
@ -1,5 +1,7 @@
|
||||
import string
|
||||
|
||||
from rubick.schema import TypeValidatorRegistry, InvalidValueError
|
||||
|
||||
|
||||
class ConfigurationSection(object):
|
||||
|
||||
@ -74,12 +76,14 @@ class ConfigurationWrapper(object):
|
||||
|
||||
class Configuration(object):
|
||||
|
||||
def __init__(self):
|
||||
def __init__(self, schema=None):
|
||||
super(Configuration, self).__init__()
|
||||
self._defaults = dict()
|
||||
self._normal = dict()
|
||||
self._cli = dict()
|
||||
self._env = dict()
|
||||
self._cache = dict()
|
||||
self.schema = schema
|
||||
|
||||
def _normalize_name(self, name):
|
||||
if name.find('.') == -1:
|
||||
@ -95,8 +99,11 @@ class Configuration(object):
|
||||
|
||||
return '%s.%s' % (section, param)
|
||||
|
||||
def get(self, name, default=None, raw=False, _state=[]):
|
||||
section, name = self._normalize_name(name)
|
||||
def get(self, fullname, default=None, raw=False, _state=[]):
|
||||
if not raw and fullname in self._cache:
|
||||
return self._cache[fullname]
|
||||
|
||||
section, name = self._normalize_name(fullname)
|
||||
|
||||
if section in self._cli and name in self._cli[section]:
|
||||
value = self._cli[section][name]
|
||||
@ -116,9 +123,43 @@ class Configuration(object):
|
||||
return value
|
||||
|
||||
tmpl = string.Template(value)
|
||||
return (
|
||||
tmpl.safe_substitute(ConfigurationWrapper(self, _state + [name]))
|
||||
)
|
||||
value = tmpl.safe_substitute(
|
||||
ConfigurationWrapper(self, _state + [name]))
|
||||
|
||||
if self.schema:
|
||||
param_schema = self.schema.get_parameter(name, section=section)
|
||||
|
||||
type_validator = TypeValidatorRegistry.get_validator(
|
||||
param_schema.type)
|
||||
type_validation_result = type_validator.validate(value)
|
||||
if not isinstance(type_validation_result, InvalidValueError):
|
||||
value = type_validation_result
|
||||
|
||||
self._cache[fullname] = value
|
||||
|
||||
return value
|
||||
|
||||
def validate(self, fullname):
|
||||
if not self.schema:
|
||||
return None
|
||||
|
||||
section, name = self._normalize_name(fullname)
|
||||
|
||||
value = self.get(fullname, raw=True)
|
||||
|
||||
tmpl = string.Template(value)
|
||||
value = tmpl.safe_substitute(
|
||||
ConfigurationWrapper(self, [name]))
|
||||
|
||||
param_schema = self.schema.get_parameter(name, section=section)
|
||||
|
||||
type_validator = TypeValidatorRegistry.get_validator(
|
||||
param_schema.type)
|
||||
type_validation_result = type_validator.validate(value)
|
||||
if not isinstance(type_validation_result, InvalidValueError):
|
||||
return None
|
||||
|
||||
return type_validation_result
|
||||
|
||||
def contains(self, name, ignoreDefault=False):
|
||||
section, name = self._normalize_name(name)
|
||||
@ -148,26 +189,40 @@ class Configuration(object):
|
||||
(section in self._defaults and name in self._defaults[section])
|
||||
)
|
||||
|
||||
def set_env(self, name, value):
|
||||
section, name = self._normalize_name(name)
|
||||
def set_env(self, fullname, value):
|
||||
section, name = self._normalize_name(fullname)
|
||||
|
||||
self._env.setdefault(section, {})[name] = value
|
||||
|
||||
def set_cli(self, name, value):
|
||||
section, name = self._normalize_name(name)
|
||||
self._invalidate_cache(fullname)
|
||||
|
||||
def set_cli(self, fullname, value):
|
||||
section, name = self._normalize_name(fullname)
|
||||
|
||||
self._cli.setdefault(section, {})[name] = value
|
||||
|
||||
def set_default(self, name, value):
|
||||
section, name = self._normalize_name(name)
|
||||
self._invalidate_cache(fullname)
|
||||
|
||||
def set_default(self, fullname, value):
|
||||
section, name = self._normalize_name(fullname)
|
||||
|
||||
self._defaults.setdefault(section, {})[name] = value
|
||||
|
||||
def set(self, name, value):
|
||||
section, name = self._normalize_name(name)
|
||||
self._invalidate_cache(fullname)
|
||||
|
||||
def set(self, fullname, value):
|
||||
section, name = self._normalize_name(fullname)
|
||||
|
||||
self._normal.setdefault(section, {})[name] = value
|
||||
|
||||
self._invalidate_cache(fullname)
|
||||
|
||||
def _invalidate_cache(self, fullname):
|
||||
# We need to invalidate not only value of given parameter
|
||||
# but also values that depend on that parameter
|
||||
# Since this is hard, we'll just invalidate all cached values
|
||||
self._cache = dict()
|
||||
|
||||
def section(self, section):
|
||||
return ConfigurationSection(self, section)
|
||||
|
||||
|
@ -133,7 +133,7 @@ class OpenstackComponent(Service):
|
||||
return self._parse_config_resources(self.config_files, schema)
|
||||
|
||||
def _parse_config_resources(self, resources, schema=None):
|
||||
config = Configuration()
|
||||
config = Configuration(schema)
|
||||
|
||||
# Apply defaults
|
||||
if schema:
|
||||
@ -147,21 +147,14 @@ class OpenstackComponent(Service):
|
||||
|
||||
for resource in reversed(resources):
|
||||
self._parse_config_file(
|
||||
Mark(resource.path),
|
||||
resource.contents,
|
||||
config,
|
||||
schema,
|
||||
Mark(resource.path), resource.contents, config, schema,
|
||||
issue_reporter=resource)
|
||||
|
||||
return config
|
||||
|
||||
def _parse_config_file(
|
||||
self,
|
||||
base_mark,
|
||||
config_contents,
|
||||
config=Configuration(),
|
||||
schema=None,
|
||||
issue_reporter=None):
|
||||
def _parse_config_file(self, base_mark, config_contents,
|
||||
config=Configuration(), schema=None,
|
||||
issue_reporter=None):
|
||||
if issue_reporter:
|
||||
def report_issue(issue):
|
||||
issue_reporter.report_issue(issue)
|
||||
@ -250,9 +243,8 @@ class OpenstackComponent(Service):
|
||||
type_validation_result.message)
|
||||
report_issue(type_validation_result)
|
||||
|
||||
config.set(
|
||||
parameter_fullname,
|
||||
parameter.value.text)
|
||||
config.set(parameter_fullname,
|
||||
parameter.value.text)
|
||||
else:
|
||||
value = type_validation_result
|
||||
|
||||
@ -283,16 +275,6 @@ class KeystoneComponent(OpenstackComponent):
|
||||
name = 'keystone'
|
||||
|
||||
|
||||
class GlanceApiComponent(OpenstackComponent):
|
||||
component = 'glance_api'
|
||||
name = 'glance-api'
|
||||
|
||||
|
||||
class GlanceRegistryComponent(OpenstackComponent):
|
||||
component = 'glance_registry'
|
||||
name = 'glance-registry'
|
||||
|
||||
|
||||
class NovaApiComponent(OpenstackComponent):
|
||||
component = 'nova'
|
||||
name = 'nova-api'
|
||||
|
@ -1,6 +1,8 @@
|
||||
import unittest
|
||||
|
||||
from rubick.config_model import Configuration
|
||||
from rubick.schema import ConfigSchema, ConfigParameterSchema, \
|
||||
InvalidValueError
|
||||
|
||||
|
||||
class ConfigurationTests(unittest.TestCase):
|
||||
@ -165,7 +167,7 @@ class ConfigurationTests(unittest.TestCase):
|
||||
|
||||
self.assertEqual(self.value, c.get(self.fullparam))
|
||||
|
||||
def test_contains(self):
|
||||
def test_section_in(self):
|
||||
c = Configuration()
|
||||
|
||||
self.assertFalse(self.section in c)
|
||||
@ -210,3 +212,73 @@ class ConfigurationTests(unittest.TestCase):
|
||||
c.set('b', 'x')
|
||||
|
||||
self.assertEqual('$b', c.get('a', raw=True))
|
||||
|
||||
def test_typed_params(self):
|
||||
schema = ConfigSchema('test', '1.0', 'ini', [
|
||||
ConfigParameterSchema('param1', type='integer', section='DEFAULT')
|
||||
])
|
||||
|
||||
c = Configuration(schema)
|
||||
|
||||
c.set('param1', '123')
|
||||
|
||||
self.assertEqual(123, c.get('param1'))
|
||||
|
||||
def test_typed_params_update(self):
|
||||
schema = ConfigSchema('test', '1.0', 'ini', [
|
||||
ConfigParameterSchema('param1', type='integer', section='DEFAULT')
|
||||
])
|
||||
|
||||
c = Configuration(schema)
|
||||
|
||||
c.set('param1', '123')
|
||||
|
||||
self.assertEqual(123, c.get('param1'))
|
||||
|
||||
c.set('param1', '456')
|
||||
|
||||
self.assertEqual(456, c.get('param1'))
|
||||
|
||||
def test_typed_param_with_invalid_value_returns_string_value(self):
|
||||
schema = ConfigSchema('test', '1.0', 'ini', [
|
||||
ConfigParameterSchema('param1', type='integer', section='DEFAULT')
|
||||
])
|
||||
|
||||
c = Configuration(schema)
|
||||
|
||||
c.set('param1', '123a')
|
||||
|
||||
self.assertEqual('123a', c.get('param1'))
|
||||
|
||||
def test_getting_typed_param_raw_value(self):
|
||||
schema = ConfigSchema('test', '1.0', 'ini', [
|
||||
ConfigParameterSchema('param1', type='integer', section='DEFAULT')
|
||||
])
|
||||
|
||||
c = Configuration(schema)
|
||||
|
||||
c.set('param1', '123')
|
||||
|
||||
self.assertEqual('123', c.get('param1', raw=True))
|
||||
|
||||
def test_validate_returns_none_if_value_is_valid(self):
|
||||
schema = ConfigSchema('test', '1.0', 'ini', [
|
||||
ConfigParameterSchema('param1', type='integer', section='DEFAULT')
|
||||
])
|
||||
|
||||
c = Configuration(schema)
|
||||
|
||||
c.set('param1', '123')
|
||||
|
||||
self.assertIsNone(c.validate('param1'))
|
||||
|
||||
def test_validate_returns_error_if_valid_is_invalid(self):
|
||||
schema = ConfigSchema('test', '1.0', 'ini', [
|
||||
ConfigParameterSchema('param1', type='integer', section='DEFAULT')
|
||||
])
|
||||
|
||||
c = Configuration(schema)
|
||||
|
||||
c.set('param1', 'abc')
|
||||
|
||||
self.assertTrue(isinstance(c.validate('param1'), InvalidValueError))
|
||||
|
Loading…
x
Reference in New Issue
Block a user