features: add check_with_netvm, similar to check_with_template
Allow using default feature value from netvm, not template. This makes sense for network-related features like using tor, supporting ipv6 etc. Similarly to check_with_template, expose it also on Admin API.
This commit is contained in:
parent
f223594f92
commit
bf59b00f1d
1
Makefile
1
Makefile
@ -69,6 +69,7 @@ ADMIN_API_METHODS_SIMPLE = \
|
|||||||
admin.vm.device.mic.Detach \
|
admin.vm.device.mic.Detach \
|
||||||
admin.vm.device.mic.List \
|
admin.vm.device.mic.List \
|
||||||
admin.vm.device.mic.Set.persistent \
|
admin.vm.device.mic.Set.persistent \
|
||||||
|
admin.vm.feature.CheckWithNetvm \
|
||||||
admin.vm.feature.CheckWithTemplate \
|
admin.vm.feature.CheckWithTemplate \
|
||||||
admin.vm.feature.Get \
|
admin.vm.feature.Get \
|
||||||
admin.vm.feature.List \
|
admin.vm.feature.List \
|
||||||
|
@ -883,6 +883,19 @@ class QubesAdminAPI(qubes.api.AbstractQubesAPI):
|
|||||||
raise qubes.exc.QubesFeatureNotFoundError(self.dest, self.arg)
|
raise qubes.exc.QubesFeatureNotFoundError(self.dest, self.arg)
|
||||||
return value
|
return value
|
||||||
|
|
||||||
|
@qubes.api.method('admin.vm.feature.CheckWithNetvm', no_payload=True,
|
||||||
|
scope='local', read=True)
|
||||||
|
@asyncio.coroutine
|
||||||
|
def vm_feature_checkwithnetvm(self):
|
||||||
|
# validation of self.arg done by qrexec-policy is enough
|
||||||
|
|
||||||
|
self.fire_event_for_permission()
|
||||||
|
try:
|
||||||
|
value = self.dest.features.check_with_netvm(self.arg)
|
||||||
|
except KeyError:
|
||||||
|
raise qubes.exc.QubesFeatureNotFoundError(self.dest, self.arg)
|
||||||
|
return value
|
||||||
|
|
||||||
@qubes.api.method('admin.vm.feature.Remove', no_payload=True,
|
@qubes.api.method('admin.vm.feature.Remove', no_payload=True,
|
||||||
scope='local', write=True)
|
scope='local', write=True)
|
||||||
@asyncio.coroutine
|
@asyncio.coroutine
|
||||||
|
@ -90,6 +90,10 @@ class AdminAPITestCase(qubes.tests.QubesTestCase):
|
|||||||
self.base_dir_patch.stop()
|
self.base_dir_patch.stop()
|
||||||
if os.path.exists(self.test_base_dir):
|
if os.path.exists(self.test_base_dir):
|
||||||
shutil.rmtree(self.test_base_dir)
|
shutil.rmtree(self.test_base_dir)
|
||||||
|
try:
|
||||||
|
del self.netvm
|
||||||
|
except AttributeError:
|
||||||
|
pass
|
||||||
del self.vm
|
del self.vm
|
||||||
del self.template
|
del self.template
|
||||||
self.app.close()
|
self.app.close()
|
||||||
@ -1047,6 +1051,31 @@ class TC_00_VMs(AdminAPITestCase):
|
|||||||
b'test-vm1', b'test-feature')
|
b'test-vm1', b'test-feature')
|
||||||
self.assertFalse(self.app.save.called)
|
self.assertFalse(self.app.save.called)
|
||||||
|
|
||||||
|
def test_315_feature_checkwithnetvm(self):
|
||||||
|
self.vm.features['test-feature'] = 'some-value'
|
||||||
|
value = self.call_mgmt_func(b'admin.vm.feature.CheckWithNetvm',
|
||||||
|
b'test-vm1', b'test-feature')
|
||||||
|
self.assertEqual(value, 'some-value')
|
||||||
|
self.assertFalse(self.app.save.called)
|
||||||
|
|
||||||
|
def test_316_feature_checkwithnetvm_netvm(self):
|
||||||
|
self.netvm = self.app.add_new_vm('AppVM', label='red',
|
||||||
|
name='test-netvm1',
|
||||||
|
template='test-template',
|
||||||
|
provides_network=True)
|
||||||
|
self.vm.netvm = self.netvm
|
||||||
|
self.netvm.features['test-feature'] = 'some-value'
|
||||||
|
value = self.call_mgmt_func(b'admin.vm.feature.CheckWithNetvm',
|
||||||
|
b'test-vm1', b'test-feature')
|
||||||
|
self.assertEqual(value, 'some-value')
|
||||||
|
self.assertFalse(self.app.save.called)
|
||||||
|
|
||||||
|
def test_317_feature_checkwithnetvm_none(self):
|
||||||
|
with self.assertRaises(qubes.exc.QubesFeatureNotFoundError):
|
||||||
|
self.call_mgmt_func(b'admin.vm.feature.CheckWithNetvm',
|
||||||
|
b'test-vm1', b'test-feature')
|
||||||
|
self.assertFalse(self.app.save.called)
|
||||||
|
|
||||||
def test_320_feature_set(self):
|
def test_320_feature_set(self):
|
||||||
value = self.call_mgmt_func(b'admin.vm.feature.Set',
|
value = self.call_mgmt_func(b'admin.vm.feature.Set',
|
||||||
b'test-vm1', b'test-feature', b'some-value')
|
b'test-vm1', b'test-feature', b'some-value')
|
||||||
|
@ -186,6 +186,20 @@ class Features(dict):
|
|||||||
|
|
||||||
return default
|
return default
|
||||||
|
|
||||||
|
def check_with_netvm(self, feature, default=_NO_DEFAULT):
|
||||||
|
''' Check if the vm's netvm has the specified feature. '''
|
||||||
|
if feature in self:
|
||||||
|
return self[feature]
|
||||||
|
|
||||||
|
if hasattr(self.vm, 'netvm') and self.vm.netvm is not None:
|
||||||
|
return self.vm.netvm.features.check_with_netvm(feature,
|
||||||
|
default)
|
||||||
|
|
||||||
|
if default is self._NO_DEFAULT:
|
||||||
|
raise KeyError(feature)
|
||||||
|
|
||||||
|
return default
|
||||||
|
|
||||||
|
|
||||||
class Tags(set):
|
class Tags(set):
|
||||||
'''Manager of the tags.
|
'''Manager of the tags.
|
||||||
|
Loading…
Reference in New Issue
Block a user