follower in symlink
This commit is contained in:
parent
d2e790a2e2
commit
302be618ce
3 changed files with 49 additions and 3 deletions
|
@ -283,10 +283,17 @@ async def test_symlink_with_follower(config_type):
|
||||||
await cfg.option('ip_admin_eth0.ip_admin_eth0').value.set(['val1', 'val2'])
|
await cfg.option('ip_admin_eth0.ip_admin_eth0').value.set(['val1', 'val2'])
|
||||||
assert await cfg.value.dict() == {'ip_admin_eth0.ip_admin_eth0': ['val1', 'val2'], 'ip_admin_eth0.netmask_admin_eth0': [None, None], 'follower': [None, None]}
|
assert await cfg.value.dict() == {'ip_admin_eth0.ip_admin_eth0': ['val1', 'val2'], 'ip_admin_eth0.netmask_admin_eth0': [None, None], 'follower': [None, None]}
|
||||||
#
|
#
|
||||||
|
assert await cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).owner.get() == 'default'
|
||||||
|
assert await cfg.option('ip_admin_eth0.netmask_admin_eth0', 1).owner.get() == 'default'
|
||||||
|
assert await cfg.option('follower', 0).owner.get() == 'default'
|
||||||
|
assert await cfg.option('follower', 1).owner.get() == 'default'
|
||||||
|
assert await cfg.option('follower').owner.get() == ['default', 'default']
|
||||||
|
#
|
||||||
assert await cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() == None
|
assert await cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() == None
|
||||||
assert await cfg.option('ip_admin_eth0.netmask_admin_eth0', 1).value.get() == None
|
assert await cfg.option('ip_admin_eth0.netmask_admin_eth0', 1).value.get() == None
|
||||||
assert await cfg.option('follower', 0).value.get() == None
|
assert await cfg.option('follower', 0).value.get() == None
|
||||||
assert await cfg.option('follower', 1).value.get() == None
|
assert await cfg.option('follower', 1).value.get() == None
|
||||||
|
assert await cfg.option('follower').value.get() == [None, None]
|
||||||
#
|
#
|
||||||
await cfg.option('ip_admin_eth0.netmask_admin_eth0', 1).value.set('val3')
|
await cfg.option('ip_admin_eth0.netmask_admin_eth0', 1).value.set('val3')
|
||||||
assert await cfg.value.dict() == {'ip_admin_eth0.ip_admin_eth0': ['val1', 'val2'], 'ip_admin_eth0.netmask_admin_eth0': [None, 'val3'], 'follower': [None, 'val3']}
|
assert await cfg.value.dict() == {'ip_admin_eth0.ip_admin_eth0': ['val1', 'val2'], 'ip_admin_eth0.netmask_admin_eth0': [None, 'val3'], 'follower': [None, 'val3']}
|
||||||
|
@ -295,6 +302,13 @@ async def test_symlink_with_follower(config_type):
|
||||||
assert await cfg.option('ip_admin_eth0.netmask_admin_eth0', 1).value.get() == 'val3'
|
assert await cfg.option('ip_admin_eth0.netmask_admin_eth0', 1).value.get() == 'val3'
|
||||||
assert await cfg.option('follower', 0).value.get() == None
|
assert await cfg.option('follower', 0).value.get() == None
|
||||||
assert await cfg.option('follower', 1).value.get() == 'val3'
|
assert await cfg.option('follower', 1).value.get() == 'val3'
|
||||||
|
assert await cfg.option('follower').value.get() == [None, 'val3']
|
||||||
|
#
|
||||||
|
assert await cfg.option('ip_admin_eth0.netmask_admin_eth0', 0).owner.get() == 'default'
|
||||||
|
assert await cfg.option('ip_admin_eth0.netmask_admin_eth0', 1).owner.get() == 'user'
|
||||||
|
assert await cfg.option('follower', 0).owner.get() == 'default'
|
||||||
|
assert await cfg.option('follower', 1).owner.get() == 'user'
|
||||||
|
assert await cfg.option('follower').owner.get() == ['default', 'user']
|
||||||
assert not await list_sessions()
|
assert not await list_sessions()
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -145,6 +145,8 @@ class CommonTiramisuOption(CommonTiramisu):
|
||||||
self._subconfig = None
|
self._subconfig = None
|
||||||
|
|
||||||
def __getattr__(self, name):
|
def __getattr__(self, name):
|
||||||
|
if name == '__name__':
|
||||||
|
return self.__class__.__name__
|
||||||
raise APIError(_('unknown method "{}" in "{}"').format(name, self.__class__.__name__))
|
raise APIError(_('unknown method "{}" in "{}"').format(name, self.__class__.__name__))
|
||||||
|
|
||||||
|
|
||||||
|
@ -451,6 +453,19 @@ class TiramisuOptionOwner(CommonTiramisuOption):
|
||||||
@option_and_connection
|
@option_and_connection
|
||||||
async def get(self):
|
async def get(self):
|
||||||
"""Get owner for a specified option"""
|
"""Get owner for a specified option"""
|
||||||
|
if self._option_bag.option.impl_is_follower() and self._option_bag.index is None:
|
||||||
|
if self._option_bag.option.impl_is_symlinkoption():
|
||||||
|
length = await self._subconfig.cfgimpl_get_length_leadership(self._option_bag)
|
||||||
|
value = []
|
||||||
|
for index in range(length):
|
||||||
|
soption_bag = self._option_bag.copy()
|
||||||
|
soption_bag.index = index
|
||||||
|
value.append(await self._values.getowner(soption_bag,
|
||||||
|
self._name,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
return value
|
||||||
|
raise APIError('index must be set with a follower option')
|
||||||
return await self._values.getowner(self._option_bag)
|
return await self._values.getowner(self._option_bag)
|
||||||
|
|
||||||
@option_and_connection
|
@option_and_connection
|
||||||
|
@ -663,7 +678,10 @@ def option_type(typ):
|
||||||
del config_bag.connection
|
del config_bag.connection
|
||||||
raise APIError(_('please specify a valid sub function ({})').format(func.__name__))
|
raise APIError(_('please specify a valid sub function ({})').format(func.__name__))
|
||||||
ret = await func(*args, **kwargs)
|
ret = await func(*args, **kwargs)
|
||||||
del config_bag.connection
|
try:
|
||||||
|
del config_bag.connection
|
||||||
|
except AttributeError:
|
||||||
|
pass
|
||||||
return ret
|
return ret
|
||||||
wrapped.func = func
|
wrapped.func = func
|
||||||
return wrapped
|
return wrapped
|
||||||
|
@ -698,6 +716,17 @@ class TiramisuOptionValue(CommonTiramisuOption):
|
||||||
async def get(self):
|
async def get(self):
|
||||||
"""Get option's value"""
|
"""Get option's value"""
|
||||||
if self._option_bag.option.impl_is_follower() and self._option_bag.index is None:
|
if self._option_bag.option.impl_is_follower() and self._option_bag.index is None:
|
||||||
|
# if it's a follower included in a symlinkoption, this should consider as a list
|
||||||
|
if self._option_bag.option.impl_is_symlinkoption():
|
||||||
|
value = []
|
||||||
|
for index in range(await self._len()):
|
||||||
|
soption_bag = self._option_bag.copy()
|
||||||
|
soption_bag.index = index
|
||||||
|
value.append(await self._subconfig.getattr(self._name,
|
||||||
|
soption_bag,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
return value
|
||||||
raise APIError('index must be set with a follower option')
|
raise APIError('index must be set with a follower option')
|
||||||
return await self._subconfig.getattr(self._name,
|
return await self._subconfig.getattr(self._name,
|
||||||
self._option_bag,
|
self._option_bag,
|
||||||
|
@ -784,6 +813,9 @@ class TiramisuOptionValue(CommonTiramisuOption):
|
||||||
|
|
||||||
@option_type('follower')
|
@option_type('follower')
|
||||||
async def len(self):
|
async def len(self):
|
||||||
|
return await self._len()
|
||||||
|
|
||||||
|
async def _len(self):
|
||||||
"""Length of follower option"""
|
"""Length of follower option"""
|
||||||
# for example if index is None
|
# for example if index is None
|
||||||
if '_length' not in vars(self):
|
if '_length' not in vars(self):
|
||||||
|
|
|
@ -307,8 +307,8 @@ class Values:
|
||||||
"convenience method to know if an option is empty"
|
"convenience method to know if an option is empty"
|
||||||
empty = opt._empty
|
empty = opt._empty
|
||||||
if index in [None, undefined] and opt.impl_is_multi():
|
if index in [None, undefined] and opt.impl_is_multi():
|
||||||
isempty = value is None or (not force_allow_empty_list and value == []) or \
|
isempty = value is None or (isinstance(value, list) and not force_allow_empty_list and value == []) or \
|
||||||
None in value or empty in value
|
(isinstance(value, list) and None in value) or empty in value
|
||||||
else:
|
else:
|
||||||
isempty = value is None or value == empty or (opt.impl_is_submulti() and value == [])
|
isempty = value is None or value == empty or (opt.impl_is_submulti() and value == [])
|
||||||
return isempty
|
return isempty
|
||||||
|
|
Loading…
Reference in a new issue