Add URIOpt
This change add URIOpt which validates string as URI. Closes-Bug: #1500398 Change-Id: Ie8736b8654b9feb2a2b174159f08dbea03568d84
This commit is contained in:
parent
bb0f7e3880
commit
45ee2bed52
@ -1268,6 +1268,19 @@ class HostnameOpt(Opt):
|
||||
**kwargs)
|
||||
|
||||
|
||||
class URIOpt(Opt):
|
||||
|
||||
"""Opt with URI type
|
||||
|
||||
Option with ``type`` :class:`oslo_config.types.URI`
|
||||
|
||||
.. versionadded:: 3.12
|
||||
"""
|
||||
|
||||
def __init__(self, name, **kwargs):
|
||||
super(URIOpt, self).__init__(name, type=types.URI(), **kwargs)
|
||||
|
||||
|
||||
class MultiOpt(Opt):
|
||||
|
||||
"""Multi-value option.
|
||||
|
@ -77,9 +77,8 @@ def _format_defaults(opt):
|
||||
default_str = str(opt.sample_default)
|
||||
elif opt.default is None:
|
||||
default_str = '<None>'
|
||||
elif (isinstance(opt, cfg.StrOpt) or
|
||||
isinstance(opt, cfg.IPOpt) or
|
||||
isinstance(opt, cfg.HostnameOpt)):
|
||||
elif (isinstance(opt, (cfg.StrOpt, cfg.IPOpt,
|
||||
cfg.HostnameOpt, cfg.URIOpt))):
|
||||
default_str = opt.default
|
||||
elif isinstance(opt, cfg.BoolOpt):
|
||||
default_str = str(opt.default).lower()
|
||||
|
@ -494,6 +494,13 @@ class CliOptsTestCase(BaseTestCase):
|
||||
('port_arg_deprecated_group_and_name',
|
||||
dict(opt_class=cfg.PortOpt, default=None,
|
||||
cli_args=['--old-oof=80'], value=80, deps=('oof', 'old'))),
|
||||
('uri_default',
|
||||
dict(opt_class=cfg.URIOpt, default='http://example.com',
|
||||
cli_args=[], value='http://example.com', deps=(None, None))),
|
||||
('uri_arg',
|
||||
dict(opt_class=cfg.URIOpt, default=None,
|
||||
cli_args=['--foo', 'http://example.com'],
|
||||
value='http://example.com', deps=(None, None))),
|
||||
('multistr_default',
|
||||
dict(opt_class=cfg.MultiStrOpt, default=['bar'], cli_args=[],
|
||||
value=['bar'], deps=(None, None))),
|
||||
@ -659,6 +666,17 @@ class PositionalTestCase(BaseTestCase):
|
||||
def test_positional_port_arg(self):
|
||||
self._do_pos_test(cfg.PortOpt, None, ['443'], 443)
|
||||
|
||||
def test_positional_uri_default(self):
|
||||
self._do_pos_test(cfg.URIOpt, 'http://example.com', [],
|
||||
'http://example.com')
|
||||
|
||||
def test_positional_uri_none_default(self):
|
||||
self._do_pos_test(cfg.URIOpt, None, [], None)
|
||||
|
||||
def test_positional_uri_arg(self):
|
||||
self._do_pos_test(cfg.URIOpt, None, ['http://example.com'],
|
||||
'http://example.com')
|
||||
|
||||
def test_positional_multistr_none_default(self):
|
||||
self._do_pos_test(cfg.MultiStrOpt, None, [], None)
|
||||
|
||||
|
@ -143,6 +143,9 @@ class GeneratorTestCase(base.BaseTestCase):
|
||||
'hostname_opt': cfg.HostnameOpt('hostname_opt',
|
||||
default='compute01.nova.site1',
|
||||
help='a hostname'),
|
||||
'uri_opt': cfg.URIOpt('uri_opt',
|
||||
default='http://example.com',
|
||||
help='a URI'),
|
||||
'multi_opt': cfg.MultiStrOpt('multi_opt',
|
||||
default=['1', '2', '3'],
|
||||
help='multiple strings'),
|
||||
|
@ -637,3 +637,15 @@ class HostnameTypeTests(TypeTestHelper, unittest.TestCase):
|
||||
self.assertEqual(255, len(test_str))
|
||||
self.assertInvalid(test_str)
|
||||
self.assertConvertedEqual(test_str[:-2])
|
||||
|
||||
|
||||
class URITypeTests(TypeTestHelper, unittest.TestCase):
|
||||
type = types.URI()
|
||||
|
||||
def test_uri(self):
|
||||
self.assertConvertedValue('http://example.com', 'http://example.com')
|
||||
self.assertInvalid('invalid') # it doesn't include a scheme
|
||||
self.assertInvalid('http://') # it doesn't include an authority
|
||||
|
||||
def test_repr(self):
|
||||
self.assertEqual('URI', repr(types.URI()))
|
||||
|
@ -25,6 +25,7 @@ import warnings
|
||||
|
||||
import abc
|
||||
import netaddr
|
||||
import rfc3986
|
||||
import six
|
||||
|
||||
|
||||
@ -655,3 +656,36 @@ class Hostname(ConfigType):
|
||||
|
||||
def _formatter(self, value):
|
||||
return value
|
||||
|
||||
|
||||
class URI(ConfigType):
|
||||
|
||||
"""URI type
|
||||
|
||||
Represents URI. Value will be validated as RFC 3986.
|
||||
|
||||
:param type_name: Type name to be used in the sample config file.
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self, type_name='uri value'):
|
||||
super(URI, self).__init__(type_name=type_name)
|
||||
|
||||
def __call__(self, value):
|
||||
if not rfc3986.is_valid_uri(value, require_scheme=True,
|
||||
require_authority=True):
|
||||
raise ValueError('invalid URI: %r' % value)
|
||||
self.value = value
|
||||
return value
|
||||
|
||||
def __repr__(self):
|
||||
return 'URI'
|
||||
|
||||
def __eq__(self, other):
|
||||
return (
|
||||
(self.__class__ == other.__class__) and
|
||||
(self.value == other.value)
|
||||
)
|
||||
|
||||
def _formatter(self, value):
|
||||
return value
|
||||
|
@ -7,3 +7,4 @@ netaddr!=0.7.16,>=0.7.12 # BSD
|
||||
six>=1.9.0 # MIT
|
||||
stevedore>=1.10.0 # Apache-2.0
|
||||
oslo.i18n>=2.1.0 # Apache-2.0
|
||||
rfc3986>=0.2.0 # Apache-2.0
|
||||
|
Loading…
x
Reference in New Issue
Block a user