Replace the static Manager driver with a new fake one

Refactors the Manager interface to provide a single get_manager call
instead of uuid/name calls that transform identities.

Add new calls to list systems and chassis per manager.

Do not use jinja for rendering JSON, it's redundant, just use Python.

Finally, provide a manager driver that ties a manager to a system
in a 1-1 relationship. This fixes the current issue that one manager
managers all systems, and thus a virtual media is always attached
to all systems.

Change-Id: I46dd794750c182572d37bab3ebfcd608ceb1bb6c
This commit is contained in:
Dmitry Tantsur 2020-08-05 11:01:55 +02:00
parent dba36e54c5
commit b3bbb5b108
10 changed files with 260 additions and 338 deletions

View File

@ -32,23 +32,6 @@ SUSHY_EMULATOR_BOOT_LOADER_MAP = {
}
}
# This map contains statically configured Redfish Manager(s) linked
# up with the Systems each Manager pretends to manage.
#
# The first manager in the list will pretend to manage all other
# resources.
#
# If this map is not present in the configuration, a single default
# Manager is configured automatically to manage all available Systems.
SUSHY_EMULATOR_MANAGERS = [
{
u'Id': u'BMC',
u'Name': u'Manager',
u'ServiceEntryPointUUID': u'92384634-2938-2342-8820-489239905423',
u'UUID': u'58893887-8974-2487-2389-841168418919'
}
]
# This map contains statically configured Redfish Chassis linked
# up with the Systems and Managers enclosed into this Chassis.
#
@ -83,8 +66,8 @@ SUSHY_EMULATOR_INDICATOR_LEDS = {
# Manager(s) and possibly used by the System(s) if system emulation
# backend supports boot image configuration.
#
# If this map is not present in the configuration, no virtual
# media devices will be offered by the emulator.
# If this map is not present in the configuration, the following configuration
# is used:
SUSHY_EMULATOR_VMEDIA_DEVICES = {
u'Cd': {
u'Name': 'Virtual CD',

View File

@ -289,23 +289,9 @@ concurrently managed over Redfish and functionally similar tools.
Managers resource
-----------------
For emulating *Managers* resource, the user can statically configure
one or more imaginary Managers. The first configured manager will
pretend to manage all *Systems*, *Chassis* and potentially other
resources.
.. code-block:: python
SUSHY_EMULATOR_MANAGERS = [
{
"Id": "BMC",
"Name": "Manager",
"ServiceEntryPointUUID": "92384634-2938-2342-8820-489239905423",
"UUID": "58893887-8974-2487-2389-841168418919"
}
]
By default a single manager with be configured automatically.
*Managers* are emulated based on systems: each *System* has a *Manager* with
the same UUID. The first (alphabetically) manager will pretend to manage all
*Chassis* and potentially other resources.
Managers will be revealed when querying the *Managers* resource
directly, as well as other resources they manage or have some

View File

@ -27,7 +27,7 @@ from werkzeug import exceptions as wz_exc
from sushy_tools.emulator.resources.chassis import staticdriver as chsdriver
from sushy_tools.emulator.resources.drives import staticdriver as drvdriver
from sushy_tools.emulator.resources.indicators import staticdriver as inddriver
from sushy_tools.emulator.resources.managers import staticdriver as mgrdriver
from sushy_tools.emulator.resources.managers import fakedriver as fakemgrdriver
from sushy_tools.emulator.resources.storage import staticdriver as stgdriver
from sushy_tools.emulator.resources.systems import libvirtdriver
from sushy_tools.emulator.resources.systems import novadriver
@ -91,12 +91,12 @@ class Resources(object):
'driver', cls.SYSTEMS().driver)
if cls.MANAGERS is None:
cls.MANAGERS = mgrdriver.StaticDriver.initialize(
cls.MANAGERS = fakemgrdriver.FakeDriver.initialize(
app.config, app.logger)
app.logger.debug(
'Initialized manager resource backed by %s '
'driver', cls.MANAGERS().driver)
'driver', cls.MANAGERS(None, None).driver)
if cls.CHASSIS is None:
cls.CHASSIS = chsdriver.StaticDriver.initialize(
@ -150,8 +150,8 @@ class Resources(object):
def __enter__(self):
self.systems = self.SYSTEMS()
self.managers = self.MANAGERS()
self.chassis = self.CHASSIS()
self.managers = self.MANAGERS(self.systems, self.chassis)
self.indicators = self.INDICATORS()
self.vmedia = self.VMEDIA()
self.storage = self.STORAGE()
@ -350,6 +350,18 @@ def manager_collection_resource():
managers=resources.managers.managers)
def jsonify(obj_type, obj_version, obj):
obj.update({
"@odata.type": "#{0}.{1}.{0}".format(obj_type, obj_version),
"@odata.context": "/redfish/v1/$metadata#{0}.{0}".format(obj_type),
"@Redfish.Copyright": ("Copyright 2014-2017 Distributed Management "
"Task Force, Inc. (DMTF). For the full DMTF "
"copyright policy, see http://www.dmtf.org/"
"about/policies/copyright.")
})
return flask.jsonify(obj)
@app.route('/redfish/v1/Managers/<identity>', methods=['GET'])
@returns_json
def manager_resource(identity):
@ -359,29 +371,50 @@ def manager_resource(identity):
app.logger.debug('Serving resources for manager "%s"', identity)
managers = resources.managers
try:
manager = resources.managers.get_manager(identity)
except error.FishyError as exc:
return str(exc), 404
uuid = managers.uuid(identity)
systems = resources.managers.get_managed_systems(manager)
chassis = resources.managers.get_managed_chassis(manager)
# the first manager gets all resources
if uuid == managers.managers[0]:
systems = resources.systems.systems
chassis = resources.chassis.chassis
else:
systems = []
chassis = []
return flask.render_template(
'manager.json',
dateTime=datetime.now().strftime('%Y-%M-%dT%H:%M:%S+00:00'),
identity=identity,
name=resources.managers.name(identity),
uuid=uuid,
serviceEntryPointUUID=resources.managers.uuid(identity),
systems=systems,
chassis=chassis
)
uuid = manager['UUID']
return jsonify('Manager', 'v1_3_1', {
"Id": manager['Id'],
"Name": manager.get('Name'),
"UUID": uuid,
"ServiceEntryPointUUID": manager.get('ServiceEntryPointUUID'),
"ManagerType": "BMC",
"Description": "Contoso BMC",
"Model": "Joo Janta 200",
"DateTime": datetime.now().strftime('%Y-%M-%dT%H:%M:%S+00:00'),
"DateTimeLocalOffset": "+00:00",
"Status": {
"State": "Enabled",
"Health": "OK"
},
"PowerState": "On",
"FirmwareVersion": "1.00",
"VirtualMedia": {
"@odata.id": "/redfish/v1/Managers/%s/VirtualMedia" % uuid
},
"Links": {
"ManagerForServers": [
{
"@odata.id": "/redfish/v1/Systems/%s" % system
}
for system in systems
],
"ManagerForChassis": [
{
"@odata.id": "/redfish/v1/Chassis/%s" % ch
}
for ch in chassis
]
},
"@odata.id": "/redfish/v1/Managers/%s" % uuid
})
@app.route('/redfish/v1/Managers/<identity>/VirtualMedia', methods=['GET'])
@ -397,7 +430,7 @@ def virtual_media_collection_resource(identity):
return flask.render_template(
'virtual_media_collection.json',
identity=identity,
uuid=resources.managers.uuid(identity),
uuid=resources.managers.get_manager(identity)['UUID'],
devices=resources.vmedia.devices
)
@ -453,11 +486,16 @@ def virtual_media_insert(identity, device):
write_protected = flask.request.json.get('WriteProtected', False)
with Resources() as resources:
manager = resources.managers.get_manager(identity)
systems = resources.managers.get_managed_systems(manager)
if not systems:
app.logger.warning('Manager %s manages no systems', identity)
return '', 204
image_path = resources.vmedia.insert_image(
identity, device, image, inserted, write_protected)
for system in resources.systems.systems:
for system in systems:
try:
resources.systems.set_boot_image(
system, device, boot_image=image_path,
@ -469,8 +507,10 @@ def virtual_media_insert(identity, device):
'%s', system, image_path, device, ex)
app.logger.info(
'Virtual media placed into device %s manager %s image %s '
'inserted %s', device, identity, image or '<empty>', inserted)
'Virtual media placed into device %(dev)s of manager %(mgr)s for '
'systems %(sys)s. Image %(img)s inserted %(ins)s',
{'dev': device, 'mgr': identity, 'sys': systems,
'img': image or '<empty>', 'ins': inserted})
return '', 204
@ -483,7 +523,13 @@ def virtual_media_eject(identity, device):
with Resources() as resources:
resources.vmedia.eject_image(identity, device)
for system in resources.systems.systems:
manager = resources.managers.get_manager(identity)
systems = resources.managers.get_managed_systems(manager)
if not systems:
app.logger.warning('Manager %s manages no systems', identity)
return '', 204
for system in systems:
try:
resources.systems.set_boot_image(system, device)
@ -493,8 +539,8 @@ def virtual_media_eject(identity, device):
'%s', system, device, ex)
app.logger.info(
'Virtual media ejected from device %s manager %s '
'image ', device, identity)
'Virtual media ejected from device %s manager %s systems %s',
device, identity, systems)
return '', 204
@ -533,7 +579,7 @@ def system_resource(identity):
total_cpus=resources.systems.get_total_cpus(identity),
boot_source_target=resources.systems.get_boot_device(identity),
boot_source_mode=resources.systems.get_boot_mode(identity),
managers=resources.managers.managers[:1],
managers=resources.managers.get_managers_for_system(identity),
chassis=resources.chassis.chassis[:1],
indicator_led=resources.indicators.get_indicator_state(
resources.systems.uuid(identity))

View File

@ -35,6 +35,13 @@ class AbstractManagersDriver(base.DriverBase, metaclass=abc.ABCMeta):
:returns: driver information as `str`
"""
@abc.abstractmethod
def get_manager(self, identity):
"""Get a manager by its identity
:returns: Redfish manager object.
"""
@property
@abc.abstractmethod
def managers(self):
@ -44,27 +51,27 @@ class AbstractManagersDriver(base.DriverBase, metaclass=abc.ABCMeta):
"""
@abc.abstractmethod
def uuid(self, identity):
"""Get Redfish manager UUID
def get_managed_systems(self, manager, systems_driver):
"""Get systems managed by this manager.
The universal unique identifier (UUID) for this system. Can be used
in place of manager name if there are duplicates.
If driver backend does not support non-unique manager identity,
this method may just return the `identity`.
:returns: Redfish manager UUID
:param manager: Redfish manager object.
:param systems_driver: A systems driver.
:returns: List of Redfish system UUIDs.
"""
@abc.abstractmethod
def name(self, identity):
"""Get Redfish manager name by UUID
def get_managed_chassis(self, manager, chassis_driver):
"""Get chassis managed by this manager.
The universal unique identifier (UUID) for this Redfish manager.
Can be used in place of manager name if there are duplicates.
If driver backend does not support manager names, this method may
just return the `identity`.
:returns: Redfish manager name
:param manager: Redfish manager object.
:param chassis_driver: A chassis driver.
:returns: List of Redfish chassis UUIDs.
"""
@abc.abstractmethod
def get_managers_for_system(self, ident):
"""Get managers that manage the given system.
:param ident: System UUID.
:returns: list of UUIDs representing the managers
"""

View File

@ -0,0 +1,87 @@
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
from sushy_tools.emulator.resources.managers.base import AbstractManagersDriver
from sushy_tools import error
class FakeDriver(AbstractManagersDriver):
"""Redfish manager that copied systems."""
def __init__(self, systems, chassis):
self._systems = systems
self._chassis = chassis
def get_manager(self, identity):
"""Get a manager by its identity
:returns: Redfish manager UUID.
"""
try:
system_uuid = self._systems.uuid(identity)
system_name = self._systems.name(identity)
except error.AliasAccessError:
raise
except error.FishyError:
msg = 'Manager with UUID %s was not found' % identity
self._logger.error(msg)
raise error.FishyError(msg)
else:
result = {'Id': system_uuid,
'UUID': system_uuid,
'Name': '%s-Manager' % system_name}
self._logger.debug('Found manager %(mgr)s by UUID %(id)s',
{'mgr': result, 'id': identity})
return result
@property
def driver(self):
"""Return human-friendly driver information
:returns: driver information as `str`
"""
return '<static-managers>'
@property
def managers(self):
"""Return available Redfish managers
:returns: list of UUIDs representing the managers
"""
return sorted(self._systems.systems)
def get_managed_systems(self, manager):
"""Get systems managed by this manager.
:param manager: Redfish manager object.
:returns: List of Redfish system UUIDs.
"""
return [manager['UUID']]
def get_managed_chassis(self, manager):
"""Get chassis managed by this manager.
:param manager: Redfish manager object.
:returns: List of Redfish chassis UUIDs.
"""
if manager['UUID'] == self.managers[0]:
return self._chassis.chassis
else:
return []
def get_managers_for_system(self, ident):
"""Get managers that manage the given system.
:param ident: System UUID.
:returns: list of UUIDs representing the managers
"""
return [self._systems.uuid(ident)]

View File

@ -1,122 +0,0 @@
# Copyright 2019 Red Hat, Inc.
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import uuid
from sushy_tools.emulator.resources.managers.base import AbstractManagersDriver
from sushy_tools import error
class StaticDriver(AbstractManagersDriver):
"""Redfish manager backed by configuration file"""
def __init__(self):
managers = self._config.get('SUSHY_EMULATOR_MANAGERS')
if not managers:
# Default Manager
managers = [
{
u'Id': u'BMC',
u'Name': u'Manager',
u'ServiceEntryPointUUID': u'92384634-2938-2342-'
u'8820-489239905423',
u'UUID': u'58893887-8974-2487-2389-841168418919',
}
]
self._managers_by_id = {
x['Id']: x for x in managers
}
self._managers_by_uuid = {
x['UUID']: x for x in managers if 'UUID' in x
}
self._managers_by_name = {
x['Name']: x for x in managers if 'Name' in x
}
if len(self._managers_by_uuid) != len(managers):
raise error.FishyError(
'Conflicting UUIDs in static managers configuration')
def _get_manager(self, identity):
try:
uu_identity = str(uuid.UUID(identity))
return self._managers_by_uuid[uu_identity]
except (ValueError, KeyError):
try:
uu_identity = self._managers_by_name[identity]['UUID']
except KeyError:
try:
uu_identity = self._managers_by_id[identity]['UUID']
except KeyError:
msg = ('Error finding manager by UUID/Name/Id '
'"%(identity)s"' % {'identity': identity})
self._logger.debug(msg)
raise error.FishyError(msg)
raise error.AliasAccessError(uu_identity)
@property
def driver(self):
"""Return human-friendly driver information
:returns: driver information as `str`
"""
return '<static-managers>'
@property
def managers(self):
"""Return available Redfish managers
:returns: list of UUIDs representing the managers
"""
return sorted(self._managers_by_uuid)
def uuid(self, identity):
"""Get Redfish manager UUID
The universal unique identifier (UUID) for this system. Can be used
in place of manager name if there are duplicates.
If driver backend does not support non-unique manager identity,
this method may just return the `identity`.
:returns: Redfish manager UUID
"""
manager = self._get_manager(identity)
return manager.get('UUID')
def name(self, identity):
"""Get Redfish manager name by UUID
The universal unique identifier (UUID) for this Redfish manager.
Can be used in place of manager name if there are duplicates.
If driver backend does not support manager names, this method may
just return the `identity`.
:returns: Redfish manager name
"""
manager = self._get_manager(identity)
return manager.get('Name')

View File

@ -1,40 +0,0 @@
{
"@odata.type": "#Manager.v1_3_1.Manager",
"Id": {{ identity|string|tojson }},
"Name": {{ name|string|tojson }},
"UUID": {{ uuid|string|tojson }},
"ServiceEntryPointUUID": {{ serviceEntryPointUUID|string|tojson }},
"ManagerType": "BMC",
"Description": "Contoso BMC",
"Model": "Joo Janta 200",
"DateTime": {{ dateTime|string|tojson }},
"DateTimeLocalOffset": "+00:00",
"Status": {
"State": "Enabled",
"Health": "OK"
},
"PowerState": "On",
"FirmwareVersion": "1.00",
"VirtualMedia": {
"@odata.id": {{ "/redfish/v1/Managers/%s/VirtualMedia"|format(uuid)|string|tojson }}
},
"Links": {
"ManagerForServers": [
{% for system in systems %}
{
"@odata.id": {{ "/redfish/v1/Systems/%s"|format(system)|tojson }}
}{% if not loop.last %},{% endif %}
{% endfor %}
],
"ManagerForChassis": [
{%- for chassis_ in chassis %}
{
"@odata.id": {{ "/redfish/v1/Chassis/%s"|format(chassis_)|tojson }}
}{% if not loop.last %},{% endif %}
{% endfor -%}
]
},
"@odata.context": "/redfish/v1/$metadata#Manager.Manager",
"@odata.id": {{ "/redfish/v1/Managers/%s"|format(identity)|string|tojson }},
"@Redfish.Copyright": "Copyright 2014-2017 Distributed Management Task Force, Inc. (DMTF). For the full DMTF copyright policy, see http://www.dmtf.org/about/policies/copyright."
}

View File

@ -0,0 +1,53 @@
# Copyright 2019 Red Hat, Inc.
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
from oslotest import base
from six.moves import mock
from sushy_tools.emulator.resources.managers import fakedriver as fakemgrdriver
from sushy_tools import error
class FakeDriverTestCase(base.BaseTestCase):
def setUp(self):
super(FakeDriverTestCase, self).setUp()
self.identity = 'xxx'
self.systems = mock.Mock(systems=[self.identity])
self.systems.uuid.return_value = 'xxx'
self.systems.name.return_value = 'name'
self.manager = {'UUID': self.identity,
'Id': self.identity,
'Name': 'name-Manager'}
self.chassis = mock.Mock(chassis=[])
test_driver = fakemgrdriver.FakeDriver.initialize({}, mock.Mock())
self.test_driver = test_driver(self.systems, self.chassis)
def test_get_manager_not_found(self):
self.systems.uuid.side_effect = error.FishyError('boom')
self.assertRaises(
error.FishyError, self.test_driver.get_manager, 'foo')
def test_get_manager_by_uuid(self):
manager = self.test_driver.get_manager('xxx')
self.assertEqual(self.manager, manager)
def test_managers(self):
managers = self.test_driver.managers
self.assertEqual([self.identity], managers)
def test_managed_systems(self):
self.assertEqual(
['xxx'], self.test_driver.get_managed_systems(self.manager))

View File

@ -1,78 +0,0 @@
# Copyright 2019 Red Hat, Inc.
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import uuid
from oslotest import base
from six.moves import mock
from sushy_tools.emulator.resources.managers.staticdriver import StaticDriver
from sushy_tools import error
class StaticDriverTestCase(base.BaseTestCase):
def setUp(self):
self.managers = [
{
"Id": "BMC",
"Name": "The manager",
"UUID": "58893887-8974-2487-2389-841168418919",
"ServiceEntryPointUUID": "92384634-2938-2342-8820-489239905423"
}
]
self.identity = self.managers[0]['Id']
self.uuid = self.managers[0]['UUID']
self.name = self.managers[0]['Name']
test_driver = StaticDriver.initialize(
{'SUSHY_EMULATOR_MANAGERS': self.managers},
mock.MagicMock())
self.test_driver = test_driver()
super(StaticDriverTestCase, self).setUp()
def test__get_manager_by_id(self):
self.assertRaises(
error.AliasAccessError, self.test_driver._get_manager,
self.identity)
def test__get_manager_by_name(self):
self.assertRaises(
error.AliasAccessError, self.test_driver._get_manager, self.name)
def test__get_manager_by_uuid(self):
domain_id = uuid.UUID(self.uuid)
manager = self.test_driver._get_manager(str(domain_id))
self.assertEqual(
self.managers[0], manager)
def test_uuid_ok(self):
self.assertEqual(self.uuid, self.test_driver.uuid(self.uuid))
def test_uuid_fail(self):
self.assertRaises(error.FishyError, self.test_driver.uuid, 'xxx')
def test_name_ok(self):
self.assertRaises(error.AliasAccessError,
self.test_driver.name, self.name)
def test_name_fail(self):
self.assertRaises(error.FishyError, self.test_driver.name, 'xxx')
def test_managers(self):
managers = self.test_driver.managers
self.assertEqual([self.uuid], managers)

View File

@ -143,22 +143,22 @@ class EmulatorTestCase(base.BaseTestCase):
def test_manager_resource_get(self, resources_mock):
resources_mock = resources_mock.return_value.__enter__.return_value
systems_mock = resources_mock.systems
systems_mock.systems = ['xxx']
managers_mock = resources_mock.managers
managers_mock.managers = ['xxxx-yyyy-zzzz']
managers_mock.uuid.return_value = 'xxxx-yyyy-zzzz'
managers_mock.name.return_value = 'name'
chassis_mock = resources_mock.chassis
chassis_mock.chassis = ['chassis0']
managers_mock.get_manager.return_value = {
'UUID': 'xxxx-yyyy-zzzz',
'Name': 'name',
'Id': 'xxxx-yyyy-zzzz',
}
managers_mock.get_managed_systems.return_value = ['xxx']
managers_mock.get_managed_chassis.return_value = ['chassis0']
response = self.app.get('/redfish/v1/Managers/xxxx-yyyy-zzzz')
self.assertEqual(200, response.status_code)
self.assertEqual(200, response.status_code, response.json)
self.assertEqual('xxxx-yyyy-zzzz', response.json['Id'])
self.assertEqual('xxxx-yyyy-zzzz', response.json['UUID'])
self.assertEqual('xxxx-yyyy-zzzz',
response.json['ServiceEntryPointUUID'])
self.assertIsNone(response.json['ServiceEntryPointUUID'])
self.assertEqual([{'@odata.id': '/redfish/v1/Systems/xxx'}],
response.json['Links']['ManagerForServers'])
self.assertEqual([{'@odata.id': '/redfish/v1/Chassis/chassis0'}],
@ -187,7 +187,7 @@ class EmulatorTestCase(base.BaseTestCase):
systems_mock.get_boot_device.return_value = 'Cd'
systems_mock.get_boot_mode.return_value = 'Legacy'
managers_mock = resources_mock.managers
managers_mock.managers = ['aaaa-bbbb-cccc']
managers_mock.get_managers_for_system.return_value = ['aaaa-bbbb-cccc']
chassis_mock = resources_mock.chassis
chassis_mock.chassis = ['chassis0']
indicators_mock = resources_mock.indicators
@ -485,7 +485,7 @@ class EmulatorTestCase(base.BaseTestCase):
resources_mock = resources_mock.return_value.__enter__.return_value
managers_mock = resources_mock.managers
managers_mock.managers = [self.uuid]
managers_mock.uuid.return_value = self.uuid
managers_mock.get_manager.return_value = {'UUID': self.uuid}
vmedia_mock = resources_mock.vmedia
vmedia_mock.devices = ['CD', 'Floppy']