Redfish: Add support for Virtual Media Operations

This commit adds support to perform virtual media
operations 'set_vm_status', 'eject_vmedia' and
'insert_vmedia'.

Change-Id: Ia4d7d4984808c0b0be87262837174090066e0f2a
Partial-Bug: 1691955
This commit is contained in:
Aparna 2017-06-13 06:14:39 +00:00
parent ca8033177c
commit ead74eadad
11 changed files with 785 additions and 0 deletions

View File

@ -68,6 +68,9 @@ SUPPORTED_REDFISH_METHODS = [
'get_pending_boot_mode',
'get_current_boot_mode',
'activate_license',
'eject_virtual_media',
'insert_virtual_media',
'set_vm_status'
]
LOG = log.get_logger(__name__)

View File

@ -22,6 +22,7 @@ from proliantutils import exception
from proliantutils.ilo import operations
from proliantutils import log
from proliantutils.redfish import main
from proliantutils.redfish.resources.manager import constants as mgr_cons
from proliantutils.redfish.resources.system import constants as sys_cons
"""
@ -61,6 +62,13 @@ BOOT_MODE_MAP_REV = (
PROLIANT_MANAGER_ID = '1'
PROLIANT_SYSTEM_ID = '1'
BOOT_OPTION_MAP = {'BOOT_ONCE': True,
'BOOT_ALWAYS': False,
'NO_BOOT': False}
VIRTUAL_MEDIA_MAP = {'FLOPPY': mgr_cons.VIRTUAL_MEDIA_FLOPPY,
'CDROM': mgr_cons.VIRTUAL_MEDIA_CD}
LOG = log.get_logger(__name__)
@ -306,3 +314,113 @@ class RedfishOperations(operations.IloOperations):
{'error': str(e)})
LOG.debug(msg)
raise exception.IloError(msg)
def _validate_virtual_media(self, device):
"""Check if the device is valid device.
:param device: virtual media device
:raises: IloInvalidInputError, if the device is not valid.
"""
if device not in VIRTUAL_MEDIA_MAP:
msg = (self._("Invalid device '%s'. Valid devices: FLOPPY or "
"CDROM.")
% device)
LOG.debug(msg)
raise exception.IloInvalidInputError(msg)
def eject_virtual_media(self, device):
"""Ejects the Virtual Media image if one is inserted.
:param device: virual media device
:raises: IloError, on an error from iLO.
:raises: IloInvalidInputError, if the device is not valid.
"""
self._validate_virtual_media(device)
manager = self._get_sushy_manager(PROLIANT_MANAGER_ID)
try:
vmedia_device = (
manager.virtual_media.get_member_from_device(
VIRTUAL_MEDIA_MAP[device]))
if not vmedia_device.inserted:
LOG.debug(self._("No media available in the device '%s' to "
"perform eject operation.") % device)
return
LOG.debug(self._("Ejecting the media image '%(url)s' from the "
"device %(device)s.") %
{'url': vmedia_device.image_url, 'device': device})
vmedia_device.eject_vmedia()
except sushy.exceptions.SushyError as e:
msg = (self._("The Redfish controller failed to eject the virtual"
" media device '%(device)s'. Error %(error)s.") %
{'device': device, 'error': str(e)})
LOG.debug(msg)
raise exception.IloError(msg)
def insert_virtual_media(self, url, device):
"""Inserts the Virtual Media image to the device.
:param url: URL to image
:param device: virual media device
:raises: IloError, on an error from iLO.
:raises: IloInvalidInputError, if the device is not valid.
"""
self._validate_virtual_media(device)
manager = self._get_sushy_manager(PROLIANT_MANAGER_ID)
try:
vmedia_device = (
manager.virtual_media.get_member_from_device(
VIRTUAL_MEDIA_MAP[device]))
if vmedia_device.inserted:
vmedia_device.eject_vmedia()
LOG.debug(self._("Inserting the image url '%(url)s' to the "
"device %(device)s.") %
{'url': url, 'device': device})
vmedia_device.insert_vmedia(url)
except sushy.exceptions.SushyError as e:
msg = (self._("The Redfish controller failed to insert the media "
"url %(url)s in the virtual media device "
"'%(device)s'. Error %(error)s.") %
{'url': url, 'device': device, 'error': str(e)})
LOG.debug(msg)
raise exception.IloError(msg)
def set_vm_status(self, device='FLOPPY',
boot_option='BOOT_ONCE', write_protect='YES'):
"""Sets the Virtual Media drive status
It sets the boot option for virtual media device.
Note: boot option can be set only for CD device.
:param device: virual media device
:param boot_option: boot option to set on the virtual media device
:param write_protect: set the write protect flag on the vmedia device
Note: It's ignored. In Redfish it is read-only.
:raises: IloError, on an error from iLO.
:raises: IloInvalidInputError, if the device is not valid.
"""
# CONNECT is a RIBCL call. There is no such property to set in Redfish.
if boot_option == 'CONNECT':
return
self._validate_virtual_media(device)
if boot_option not in BOOT_OPTION_MAP:
msg = (self._("Virtual media boot option '%s' is invalid.")
% boot_option)
LOG.debug(msg)
raise exception.IloInvalidInputError(msg)
manager = self._get_sushy_manager(PROLIANT_MANAGER_ID)
try:
vmedia_device = (
manager.virtual_media.get_member_from_device(
VIRTUAL_MEDIA_MAP[device]))
vmedia_device.set_vm_status(BOOT_OPTION_MAP[boot_option])
except sushy.exceptions.SushyError as e:
msg = (self._("The Redfish controller failed to set the virtual "
"media status for '%(device)s'. Error %(error)s") %
{'device': device, 'error': str(e)})
LOG.debug(msg)
raise exception.IloError(msg)

View File

@ -0,0 +1,23 @@
# Copyright 2017 Hewlett Packard Enterprise Development LP
#
# 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.
# Virtual Media types
VIRTUAL_MEDIA_CD = 'cd'
VIRTUAL_MEDIA_FLOPPY = 'floppy'
VIRTUAL_MEDIA_DVD = 'dvd'
VIRTUAL_MEDIA_USB_STICK = 'usb stick'

View File

@ -16,6 +16,7 @@ __author__ = 'HPE'
from sushy.resources.manager import manager
from proliantutils.redfish.resources.manager import virtual_media
from proliantutils.redfish import utils
@ -26,6 +27,8 @@ class HPEManager(manager.Manager):
from sushy
"""
_virtual_media = None
def set_license(self, key):
"""Set the license on a redfish system
@ -35,3 +38,18 @@ class HPEManager(manager.Manager):
license_service_uri = (utils.get_subresource_path_by(self,
['Oem', 'Hpe', 'Links', 'LicenseService']))
self._conn.post(license_service_uri, data=data)
@property
def virtual_media(self):
"""Property to provide reference to `VirtualMediaCollection` instance.
It is calculated once when the first time it is queried. On refresh,
this property gets reset.
"""
if self._virtual_media is None:
self._virtual_media = virtual_media.VirtualMediaCollection(
self._conn,
utils.get_subresource_path_by(self, 'VirtualMedia'),
redfish_version=self.redfish_version)
return self._virtual_media

View File

@ -0,0 +1,26 @@
# Copyright 2017 Hewlett Packard Enterprise Development LP
#
# 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 import utils
from proliantutils.redfish.resources.manager import constants as cons
VIRTUAL_MEDIA_TYPES_MAP = {
'CD': cons.VIRTUAL_MEDIA_CD,
'DVD': cons.VIRTUAL_MEDIA_DVD,
'Floppy': cons.VIRTUAL_MEDIA_FLOPPY,
'USBStick': cons.VIRTUAL_MEDIA_USB_STICK
}
VIRTUAL_MEDIA_TYPES_MAP_REV = utils.revert_dictionary(VIRTUAL_MEDIA_TYPES_MAP)

View File

@ -0,0 +1,122 @@
# Copyright 2017 Hewlett Packard Enterprise Development LP
#
# 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.
__author__ = 'HPE'
from sushy.resources import base
from sushy.resources import common
from proliantutils import exception
from proliantutils import log
from proliantutils.redfish.resources.manager import mapping as maps
LOG = log.get_logger(__name__)
def _get_media(media_types):
"""Helper method to map the media types."""
get_mapped_media = (lambda x: maps.VIRTUAL_MEDIA_TYPES_MAP[x]
if x in maps.VIRTUAL_MEDIA_TYPES_MAP else None)
return list(map(get_mapped_media, media_types))
class ActionsField(base.CompositeField):
insert_vmedia = common.ResetActionField(
'#HpeiLOVirtualMedia.InsertVirtualMedia')
eject_vmedia = common.ResetActionField(
'#HpeiLOVirtualMedia.EjectVirtualMedia')
class VirtualMedia(base.ResourceBase):
media_types = base.Field('MediaTypes', adapter=_get_media,
required=True)
"""A list of allowed media types for the instance."""
inserted = base.Field('Inserted', required=True)
"""A boolean value which represents vmedia is inserted or not."""
image_url = base.Field('Image')
"""A string which represents the virtual media image url."""
_actions = ActionsField(['Oem', 'Hpe', 'Actions'], required=True)
def _get_action_element(self, action_type):
"""Helper method to return the action object."""
action = eval("self._actions." + action_type + "_vmedia")
if not action:
if action_type == "insert":
action_path = '#HpeiLOVirtualMedia.InsertVirtualMedia'
else:
action_path = '#HpeiLOVirtualMedia.EjectVirtualMedia'
raise exception.MissingAttributeError(
attribute=action_path,
resource=self._path)
return action
def insert_vmedia(self, url):
"""Inserts Virtual Media to the device
:param url: URL to image.
:raises: SushyError, on an error from iLO.
"""
target_uri = self._get_action_element('insert').target_uri
data = {'Image': url}
self._conn.post(target_uri, data=data)
def eject_vmedia(self):
"""Ejects Virtual Media.
:raises: SushyError, on an error from iLO.
"""
target_uri = self._get_action_element('eject').target_uri
data = {}
self._conn.post(target_uri, data=data)
def set_vm_status(self, boot_on_next_reset):
"""Set the Virtual Media drive status.
:param boot_on_next_reset: boolean value
:raises: SushyError, on an error from iLO.
"""
data = {
"Oem": {
"Hpe": {
"BootOnNextServerReset": boot_on_next_reset
}
}
}
self._conn.patch(self.path, data=data)
class VirtualMediaCollection(base.ResourceCollectionBase):
@property
def _resource_type(self):
return VirtualMedia
def get_member_from_device(self, device):
"""Returns the given virtual media device object.
:param device: virtual media device to be queried
:returns virtual media device object.
"""
for vmedia_device in self.get_members():
if device in vmedia_device.media_types:
return vmedia_device

View File

@ -0,0 +1,115 @@
{
"default": {
"@odata.context": "/redfish/v1/$metadata#Managers/Members/1/VirtualMedia/Members/$entity",
"@odata.etag": "W/\"FD62A3AF\"",
"@odata.id": "/redfish/v1/Managers/1/VirtualMedia/2/",
"@odata.type": "#VirtualMedia.v1_0_0.VirtualMedia",
"ConnectedVia": "NotConnected",
"Description": "Virtual Removable Media",
"Id": "2",
"Image": "",
"Inserted": false,
"MediaTypes":
[
"CD",
"DVD"
],
"Name": "VirtualMedia",
"Oem":
{
"Hpe":
{
"@odata.type": "#HpeiLOVirtualMedia.v2_0_0.HpeiLOVirtualMedia",
"Actions":
{
"#HpeiLOVirtualMedia.EjectVirtualMedia":
{
"target": "/redfish/v1/Managers/1/VirtualMedia/2/Actions/Oem/Hpe/HpeiLOVirtualMedia.EjectVirtualMedia/"
},
"#HpeiLOVirtualMedia.InsertVirtualMedia":
{
"target": "/redfish/v1/Managers/1/VirtualMedia/2/Actions/Oem/Hpe/HpeiLOVirtualMedia.InsertVirtualMedia/"
}
},
"BootOnNextServerReset": false
}
},
"WriteProtected": true
},
"vmedia_inserted": {
"@odata.context": "/redfish/v1/$metadata#Managers/Members/1/VirtualMedia/Members/$entity",
"@odata.etag": "W/\"402B70A4\"",
"@odata.id": "/redfish/v1/Managers/1/VirtualMedia/2/",
"@odata.type": "#VirtualMedia.v1_0_0.VirtualMedia",
"ConnectedVia": "URI",
"Description": "Virtual Removable Media",
"Id": "1",
"Image": "http://172.17.1.121:8081/test",
"ImageName": "test",
"Inserted": true,
"MediaTypes":
[
"CD",
"DVD"
],
"Name": "VirtualMedia",
"Oem":
{
"Hpe":
{
"@odata.type": "#HpeiLOVirtualMedia.v2_0_0.HpeiLOVirtualMedia",
"Actions":
{
"#HpeiLOVirtualMedia.EjectVirtualMedia":
{
"target": "/redfish/v1/Managers/1/VirtualMedia/2/Actions/Oem/Hpe/HpeiLOVirtualMedia.EjectVirtualMedia/"
},
"#HpeiLOVirtualMedia.InsertVirtualMedia":
{
"target": "/redfish/v1/Managers/1/VirtualMedia/2/Actions/Oem/Hpe/HpeiLOVirtualMedia.InsertVirtualMedia/"
},
"BootOnNextServerReset": false
}
}
},
"WriteProtected": true
},
"vmedia_floppy": {
"@odata.context": "/redfish/v1/$metadata#Managers/Members/1/VirtualMedia/Members/$entity",
"@odata.etag": "W/\"6C5A7D71\"",
"@odata.id": "/redfish/v1/Managers/1/VirtualMedia/1/",
"@odata.type": "#VirtualMedia.v1_0_0.VirtualMedia",
"ConnectedVia": "NotConnected",
"Description": "Virtual Removable Media",
"Id": "1",
"Image": "",
"Inserted": false,
"MediaTypes":
[
"Floppy",
"USBStick"
],
"Name": "VirtualMedia",
"Oem":
{
"Hpe":
{
"@odata.type": "#HpeiLOVirtualMedia.v2_0_0.HpeiLOVirtualMedia",
"Actions":
{
"#HpeiLOVirtualMedia.EjectVirtualMedia":
{
"target": "/redfish/v1/Managers/1/VirtualMedia/1/Actions/Oem/Hpe/HpeiLOVirtualMedia.EjectVirtualMedia/"
},
"#HpeiLOVirtualMedia.InsertVirtualMedia":
{
"target": "/redfish/v1/Managers/1/VirtualMedia/1/Actions/Oem/Hpe/HpeiLOVirtualMedia.InsertVirtualMedia/"
}
}
}
},
"WriteProtected": false
}
}

View File

@ -0,0 +1,17 @@
{
"@odata.context": "/redfish/v1/$metadata#Managers/Members/1/VirtualMedia",
"@odata.etag": "W/\"72D11D4D\"",
"@odata.id": "/redfish/v1/Managers/1/VirtualMedia/",
"@odata.type": "#VirtualMediaCollection.VirtualMediaCollection",
"Description": "iLO Virtual Media Services Settings",
"Members":
[
{
"@odata.id": "/redfish/v1/Managers/1/VirtualMedia/2/"
}
],
"Members@odata.count": 1,
"Name": "Virtual Media Services"
}

View File

@ -18,6 +18,7 @@ import mock
import testtools
from proliantutils.redfish.resources.manager import manager
from proliantutils.redfish.resources.manager import virtual_media
class HPEManagerTestCase(testtools.TestCase):
@ -38,3 +39,24 @@ class HPEManagerTestCase(testtools.TestCase):
self.mgr_inst._conn.post.assert_called_once_with(
'/redfish/v1/Managers/1/LicenseService/',
data={'LicenseKey': 'testkey'})
def test_virtual_media(self):
self.assertIsNone(self.mgr_inst._virtual_media)
self.conn.get.return_value.json.reset_mock()
with open('proliantutils/tests/redfish/'
'json_samples/vmedia_collection.json', 'r') as f:
self.conn.get.return_value.json.return_value = json.loads(f.read())
actual_vmedia = self.mgr_inst.virtual_media
self.assertIsInstance(actual_vmedia,
virtual_media.VirtualMediaCollection)
self.conn.get.return_value.json.assert_called_once_with()
# reset mock
self.conn.get.return_value.json.reset_mock()
self.assertIs(actual_vmedia,
self.mgr_inst.virtual_media)
self.conn.get.return_value.json.assert_not_called()

View File

@ -0,0 +1,127 @@
# Copyright 2017 Hewlett Packard Enterprise Development LP
#
# 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.
__author__ = 'HPE'
import json
import mock
from sushy import exceptions
import testtools
from proliantutils import exception
from proliantutils.redfish.resources.manager import constants
from proliantutils.redfish.resources.manager import virtual_media
class VirtualMediaCollectionTestCase(testtools.TestCase):
def setUp(self):
super(VirtualMediaCollectionTestCase, self).setUp()
self.conn = mock.MagicMock()
with open('proliantutils/tests/redfish/'
'json_samples/vmedia_collection.json', 'r') as f:
self.conn.get.return_value.json.return_value = (
json.loads(f.read()))
self.vmedia_coll_inst = virtual_media.VirtualMediaCollection(
self.conn, '/redfish/v1/Managers/1/VirtualMedia',
redfish_version='1.0.2')
def test_get_member_from_device(self):
with open('proliantutils/tests/redfish/'
'json_samples/vmedia.json', 'r') as f:
self.conn.get.return_value.json.return_value = (
json.loads(f.read())['default'])
obj = self.vmedia_coll_inst.get_member_from_device(
constants.VIRTUAL_MEDIA_CD)
self.assertIsInstance(obj, virtual_media.VirtualMedia)
class VirtualMediaTestCase(testtools.TestCase):
def setUp(self):
super(VirtualMediaTestCase, self).setUp()
self.conn = mock.MagicMock()
with open('proliantutils/tests/redfish/'
'json_samples/vmedia.json', 'r') as f:
vmedia_json = json.loads(f.read())
self.conn.get.return_value.json.return_value = vmedia_json[
'default']
self.vmedia_inst = virtual_media.VirtualMedia(
self.conn, '/redfish/v1/Managers/1/VirtualMedia/2',
redfish_version='1.0.2')
def test__parse_attributes(self):
self.vmedia_inst._parse_attributes()
self.assertEqual(['cd', 'dvd'], self.vmedia_inst.media_types)
self.assertEqual(False, self.vmedia_inst.inserted)
def test__parse_attributes_missing_actions(self):
self.vmedia_inst.json.pop('Oem')
self.assertRaisesRegex(
exceptions.MissingAttributeError, 'attribute Oem/Hpe/Actions',
self.vmedia_inst._parse_attributes)
def test__get_action_element_insert(self):
value = self.vmedia_inst._get_action_element('insert')
self.assertEqual("/redfish/v1/Managers/1/VirtualMedia/2/Actions/Oem/"
"Hpe/HpeiLOVirtualMedia.InsertVirtualMedia/",
value.target_uri)
def test__get_action_element_missing_insert_action(self):
self.vmedia_inst._actions.insert_vmedia = None
self.assertRaisesRegex(
exception.MissingAttributeError,
'attribute #HpeiLOVirtualMedia.InsertVirtualMedia',
self.vmedia_inst._get_action_element, 'insert')
def test__get_action_element_eject(self):
value = self.vmedia_inst._get_action_element('eject')
self.assertEqual("/redfish/v1/Managers/1/VirtualMedia/2/Actions/Oem/"
"Hpe/HpeiLOVirtualMedia.EjectVirtualMedia/",
value.target_uri)
def test__get__action_element_missing_eject_action(self):
self.vmedia_inst._actions.eject_vmedia = None
self.assertRaisesRegex(
exception.MissingAttributeError,
'attribute #HpeiLOVirtualMedia.EjectVirtualMedia',
self.vmedia_inst._get_action_element, 'eject')
def test_insert_vmedia(self):
url = "http://1.2.3.4:5678/xyz.iso"
self.vmedia_inst.insert_vmedia(url)
self.vmedia_inst._conn.post.assert_called_once_with(
"/redfish/v1/Managers/1/VirtualMedia/2/Actions/Oem/Hpe/"
"HpeiLOVirtualMedia.InsertVirtualMedia/",
data={'Image': url})
def test_eject_vmedia(self):
self.vmedia_inst.eject_vmedia()
self.vmedia_inst._conn.post.assert_called_once_with(
"/redfish/v1/Managers/1/VirtualMedia/2/Actions/Oem/Hpe/"
"HpeiLOVirtualMedia.EjectVirtualMedia/",
data={})
def test_set_vm_status(self):
value = {'Oem': {'Hpe': {'BootOnNextServerReset': True}}}
self.vmedia_inst.set_vm_status(True)
self.vmedia_inst._conn.patch.assert_called_once_with(
"/redfish/v1/Managers/1/VirtualMedia/2",
data=value)

View File

@ -22,6 +22,8 @@ import testtools
from proliantutils import exception
from proliantutils.redfish import main
from proliantutils.redfish import redfish
from proliantutils.redfish.resources.manager import manager
from proliantutils.redfish.resources.manager import virtual_media
from proliantutils.redfish.resources.system import constants as sys_cons
from sushy.resources.system import system
@ -224,3 +226,195 @@ class RedfishOperationsTestCase(testtools.TestCase):
exception.IloError,
'The Redfish controller failed to update the license',
self.rf_client.activate_license, 'key')
def _setup_virtual_media(self):
self.conn = mock.Mock()
with open('proliantutils/tests/redfish/'
'json_samples/manager.json', 'r') as f:
self.conn.get.return_value.json.return_value = json.loads(f.read())
manager_mock = manager.HPEManager(
self.conn, '/redfish/v1/Managers/1',
redfish_version='1.0.2')
with open('proliantutils/tests/redfish/'
'json_samples/vmedia_collection.json', 'r') as f:
vmedia_collection_json = json.loads(f.read())
with open('proliantutils/tests/redfish/'
'json_samples/vmedia.json', 'r') as f:
vmedia_json = json.loads(f.read())
return manager_mock, vmedia_collection_json, vmedia_json
@mock.patch.object(redfish.RedfishOperations, '_get_sushy_manager')
@mock.patch.object(virtual_media.VirtualMedia, 'eject_vmedia')
def test_eject_virtual_media(self, eject_mock, manager_mock):
manager_mock.return_value, vmedia_collection_json, vmedia_json = (
self._setup_virtual_media())
self.conn.get.return_value.json.side_effect = [
vmedia_collection_json, vmedia_json['vmedia_inserted']]
self.rf_client.eject_virtual_media('CDROM')
eject_mock.assert_called_once_with()
@mock.patch.object(redfish.RedfishOperations, '_get_sushy_manager')
@mock.patch.object(virtual_media.VirtualMedia, 'eject_vmedia')
def test_eject_virtual_media_invalid_device(self, eject_mock,
manager_mock):
self.assertRaisesRegex(
exception.IloError,
"Invalid device 'XXXXX'. Valid devices: FLOPPY or CDROM.",
self.rf_client.eject_virtual_media,
'XXXXX')
self.assertFalse(eject_mock.called)
self.assertFalse(manager_mock.called)
@mock.patch.object(redfish.RedfishOperations, '_get_sushy_manager')
@mock.patch.object(virtual_media.VirtualMedia, 'eject_vmedia')
def test_eject_virtual_media_not_inserted(self, eject_mock, manager_mock):
manager_mock.return_value, vmedia_collection_json, vmedia_json = (
self._setup_virtual_media())
self.conn.get.return_value.json.side_effect = [
vmedia_collection_json, vmedia_json['default']]
self.rf_client.eject_virtual_media('CDROM')
self.assertFalse(eject_mock.called)
@mock.patch.object(redfish.RedfishOperations, '_get_sushy_manager')
@mock.patch.object(virtual_media.VirtualMedia, 'eject_vmedia')
def test_eject_virtual_media_floppy(self, eject_mock, manager_mock):
manager_mock.return_value, vmedia_collection_json, vmedia_json = (
self._setup_virtual_media())
self.conn.get.return_value.json.side_effect = [
vmedia_collection_json, vmedia_json['vmedia_floppy']]
self.rf_client.eject_virtual_media('FLOPPY')
self.assertFalse(eject_mock.called)
@mock.patch.object(redfish.RedfishOperations, '_get_sushy_manager')
@mock.patch.object(virtual_media.VirtualMedia, 'eject_vmedia')
def test_eject_virtual_media_fail(self, eject_mock, manager_mock):
manager_mock.return_value, vmedia_collection_json, vmedia_json = (
self._setup_virtual_media())
eject_mock.side_effect = sushy.exceptions.SushyError
self.conn.get.return_value.json.side_effect = [
vmedia_collection_json, vmedia_json['vmedia_inserted']]
msg = ("The Redfish controller failed to eject the virtual"
" media device 'CDROM'.")
self.assertRaisesRegex(exception.IloError, msg,
self.rf_client.eject_virtual_media,
'CDROM')
@mock.patch.object(redfish.RedfishOperations, '_get_sushy_manager')
@mock.patch.object(virtual_media.VirtualMedia, 'eject_vmedia')
@mock.patch.object(virtual_media.VirtualMedia, 'insert_vmedia')
def test_insert_virtual_media(self, insert_mock, eject_mock, manager_mock):
manager_mock.return_value, vmedia_collection_json, vmedia_json = (
self._setup_virtual_media())
self.conn.get.return_value.json.side_effect = [
vmedia_collection_json, vmedia_json['default']]
url = 'http://1.2.3.4:5678/xyz.iso'
self.rf_client.insert_virtual_media(url, 'CDROM')
self.assertFalse(eject_mock.called)
insert_mock.assert_called_once_with(url)
@mock.patch.object(redfish.RedfishOperations, '_get_sushy_manager')
@mock.patch.object(virtual_media.VirtualMedia, 'eject_vmedia')
@mock.patch.object(virtual_media.VirtualMedia, 'insert_vmedia')
def test_insert_virtual_media_floppy(self, insert_mock, eject_mock,
manager_mock):
manager_mock.return_value, vmedia_collection_json, vmedia_json = (
self._setup_virtual_media())
self.conn.get.return_value.json.side_effect = [
vmedia_collection_json, vmedia_json['vmedia_floppy']]
url = 'http://1.2.3.4:5678/xyz.iso'
self.rf_client.insert_virtual_media(url, 'FLOPPY')
self.assertFalse(eject_mock.called)
insert_mock.assert_called_once_with(url)
@mock.patch.object(redfish.RedfishOperations, '_get_sushy_manager')
@mock.patch.object(virtual_media.VirtualMedia, 'eject_vmedia')
@mock.patch.object(virtual_media.VirtualMedia, 'insert_vmedia')
def test_insert_virtual_media_inserted(self, insert_mock, eject_mock,
manager_mock):
manager_mock.return_value, vmedia_collection_json, vmedia_json = (
self._setup_virtual_media())
self.conn.get.return_value.json.side_effect = [
vmedia_collection_json, vmedia_json['vmedia_inserted']]
url = 'http://1.2.3.4:5678/xyz.iso'
self.rf_client.insert_virtual_media(url, 'CDROM')
eject_mock.assert_called_once_with()
insert_mock.assert_called_once_with(url)
@mock.patch.object(redfish.RedfishOperations, '_get_sushy_manager')
@mock.patch.object(virtual_media.VirtualMedia, 'eject_vmedia')
@mock.patch.object(virtual_media.VirtualMedia, 'insert_vmedia')
def test_insert_virtual_media_fail(self, insert_mock, eject_mock,
manager_mock):
manager_mock.return_value, vmedia_collection_json, vmedia_json = (
self._setup_virtual_media())
insert_mock.side_effect = sushy.exceptions.SushyError
self.conn.get.return_value.json.side_effect = [
vmedia_collection_json, vmedia_json['vmedia_inserted']]
url = 'http://1.2.3.4:5678/xyz.iso'
msg = ("The Redfish controller failed to insert the media url "
"%s in the virtual media device 'CDROM'.") % url
self.assertRaisesRegex(exception.IloError, msg,
self.rf_client.insert_virtual_media,
url, 'CDROM')
@mock.patch.object(virtual_media.VirtualMedia, 'set_vm_status')
@mock.patch.object(redfish.RedfishOperations, '_get_sushy_manager')
def test_set_vm_status(self, manager_mock, set_mock):
manager_mock.return_value, vmedia_collection_json, vmedia_json = (
self._setup_virtual_media())
self.conn.get.return_value.json.side_effect = [
vmedia_collection_json, vmedia_json['default']]
self.rf_client.set_vm_status(device='CDROM')
set_mock.assert_called_once_with(True)
@mock.patch.object(virtual_media.VirtualMedia, 'set_vm_status')
@mock.patch.object(redfish.RedfishOperations, '_get_sushy_manager')
def test_set_vm_status_fail(self, manager_mock, set_mock):
manager_mock.return_value, vmedia_collection_json, vmedia_json = (
self._setup_virtual_media())
set_mock.side_effect = sushy.exceptions.SushyError
self.conn.get.return_value.json.side_effect = [
vmedia_collection_json, vmedia_json['default']]
msg = ("The Redfish controller failed to set the virtual "
"media status.")
self.assertRaisesRegex(exception.IloError, msg,
self.rf_client.set_vm_status,
'CDROM')
@mock.patch.object(virtual_media.VirtualMedia, 'set_vm_status')
@mock.patch.object(redfish.RedfishOperations, '_get_sushy_manager')
def test_set_vm_status_not_supported_boot_option(self, manager_mock,
set_mock):
msg = ("Virtual media boot option 'XXXX' is invalid.")
self.assertRaisesRegex(exception.IloInvalidInputError, msg,
self.rf_client.set_vm_status,
device='CDROM', boot_option='XXXX')
self.assertFalse(manager_mock.called)
self.assertFalse(set_mock.called)
@mock.patch.object(virtual_media.VirtualMedia, 'set_vm_status')
@mock.patch.object(redfish.RedfishOperations, '_get_sushy_manager')
def test_set_vm_status_boot_option_connect(self, manager_mock, set_mock):
self.rf_client.set_vm_status(device='CDROM', boot_option='CONNECT')
self.assertFalse(manager_mock.called)
self.assertFalse(set_mock.called)