Implement "blind mode" to avoid listing objects

This allows to perform actions on objects (VM, storage etc), without
listing them. This is useful when calling VM have minimal permissions
and only selected actions are allowed.

This means that app.domains['some-name'] will not raise KeyError, even
when domain do not exists. But performing actual action (like
vm.start()) will fail in that case.
This commit is contained in:
Marek Marczykowski-Górecki 2017-09-20 19:12:24 +02:00
parent 0eec5cb8c9
commit b28ddb6621
No known key found for this signature in database
GPG Key ID: 063938BA42CFA724
3 changed files with 31 additions and 4 deletions

View File

@ -83,11 +83,14 @@ class VMCollection(object):
del self._vm_objects[name]
def __getitem__(self, item):
if item not in self:
if not self.app.blind_mode and item not in self:
raise KeyError(item)
if item not in self._vm_objects:
cls = qubesadmin.utils.get_entry_point_one(VM_ENTRY_POINT,
self._vm_list[item]['class'])
if self.app.blind_mode:
cls = qubesadmin.vm.QubesVM
else:
cls = qubesadmin.utils.get_entry_point_one(VM_ENTRY_POINT,
self._vm_list[item]['class'])
self._vm_objects[item] = cls(self.app, item)
return self._vm_objects[item]
@ -128,6 +131,8 @@ class QubesBase(qubesadmin.base.PropertyHolder):
qubesd_connection_type = None
#: logger
log = None
#: do not check for object (VM, label etc) existence before really needed
blind_mode = False
def __init__(self):
super(QubesBase, self).__init__(self, 'admin.property.', 'dom0')

View File

@ -292,7 +292,7 @@ class WrapperObjectsCollection(object):
del self._objects[name]
def __getitem__(self, item):
if item not in self:
if not self.app.blind_mode and item not in self:
raise KeyError(item)
if item not in self._objects:
self._objects[item] = self._object_class(self.app, item)

View File

@ -99,6 +99,28 @@ class TC_00_VMCollection(qubesadmin.tests.QubesTestCase):
set(['test-vm', 'test-vm2']))
self.assertAllCalled()
def test_007_getitem_blind_mode(self):
self.app.blind_mode = True
try:
vm = self.app.domains['test-vm']
self.assertEqual(vm.name, 'test-vm')
except KeyError:
self.fail('VM not found in collection')
self.assertAllCalled()
with self.assertNotRaises(KeyError):
vm = self.app.domains['test-non-existent']
self.assertAllCalled()
def test_008_in_blind_mode(self):
self.app.blind_mode = True
self.app.expected_calls[('dom0', 'admin.vm.List', None, None)] = \
b'0\x00test-vm class=AppVM state=Running\n'
self.assertIn('test-vm', self.app.domains)
self.assertAllCalled()
self.assertNotIn('test-non-existent', self.app.domains)
self.assertAllCalled()
class TC_10_QubesBase(qubesadmin.tests.QubesTestCase):