Refactor the validation to Server Profile Template

This patch adds a new validation to OneView Server Profile
Template to ensure OneView drivers can manage the boot order of
the Server Profile and validates the connections to have at least
one primary boot priority.

Change-Id: Ie65731a38061171627e7a0786efc083a5518085a
This commit is contained in:
Hugo Nicodemos 2016-09-27 09:58:56 +00:00
parent 566b53c828
commit 787b72794a
4 changed files with 235 additions and 182 deletions

View File

@ -739,43 +739,69 @@ class Client(BaseClient):
@auditing.audit
def validate_node_server_profile_template(self, node_info):
node_spt_uri = node_info.get('server_profile_template_uri')
server_profile_template = self.get_server_profile_template(node_info)
server_hardware = self.get_server_hardware(node_info)
self._validate_spt_server_hardware_type(
server_profile_template, server_hardware
)
self._validate_spt_enclosure_group(
server_profile_template, server_hardware
)
self._validate_spt_manage_boot(server_profile_template)
@auditing.audit
def _validate_spt_server_hardware_type(
self, server_profile_template, server_hardware
):
spt_server_hardware_type_uri = (
server_profile_template.server_hardware_type_uri
)
spt_enclosure_group_uri = server_profile_template.enclosure_group_uri
server_hardware = self.get_server_hardware(node_info)
sh_server_hardware_type_uri = server_hardware.server_hardware_type_uri
sh_enclosure_group_uri_uri = server_hardware.enclosure_group_uri
if spt_server_hardware_type_uri != sh_server_hardware_type_uri:
message = (
"Server profile template %(spt_uri)s serverHardwareTypeUri is"
" inconsistent with server hardware %(server_hardware_uri)s"
" serverHardwareTypeUri." %
{'spt_uri': node_spt_uri,
'server_hardware_uri': node_info.get('server_hardware_uri')}
)
raise exceptions.OneViewInconsistentResource(message)
if spt_enclosure_group_uri != sh_enclosure_group_uri_uri:
message = (
"Server profile template %(spt_uri)s enclosureGroupUri is"
" inconsistent with server hardware %(server_hardware_uri)s"
" serverGroupUri." %
{'spt_uri': node_spt_uri,
'server_hardware_uri': node_info.get('server_hardware_uri')}
{'spt_uri': server_profile_template.uri,
'server_hardware_uri': server_hardware.uri}
)
raise exceptions.OneViewInconsistentResource(message)
@auditing.audit
def validate_spt_boot_connections(self, uuid):
server_profile_template = self.get_server_profile_template_by_uuid(
uuid
)
def _validate_spt_enclosure_group(
self, server_profile_template, server_hardware
):
spt_enclosure_group_uri = server_profile_template.enclosure_group_uri
sh_enclosure_group_uri = server_hardware.enclosure_group_uri
for connection in server_profile_template.connections:
if spt_enclosure_group_uri != sh_enclosure_group_uri:
message = (
"Server profile template %(spt_uri)s enclosureGroupUri is"
" inconsistent with server hardware %(server_hardware_uri)s"
" serverGroupUri." %
{'spt_uri': server_profile_template.uri,
'server_hardware_uri': server_hardware.uri}
)
raise exceptions.OneViewInconsistentResource(message)
@auditing.audit
def _validate_spt_manage_boot(self, server_profile_template):
manage_boot = server_profile_template.boot.get('manageBoot')
if not manage_boot:
message = (
"Server Profile Template: %s, does not allow to manage "
"boot order." % server_profile_template.uri
)
raise exceptions.OneViewInconsistentResource(message)
@auditing.audit
def _validate_spt_boot_connections(self, server_profile_template):
spt_connections = server_profile_template.connections
for connection in spt_connections:
boot = connection.get('boot')
if boot and boot.get('priority').lower() == 'primary':
return

View File

@ -3884,14 +3884,7 @@ SERVER_PROFILE_TEMPLATE_LIST_JSON = {
],
"bootMode": None,
"boot": {
"manageBoot": True,
"order": [
"CD",
"Floppy",
"USB",
"HardDisk",
"PXE"
]
"manageBoot": False,
},
"bios": {
"manageBios": False,
@ -3963,7 +3956,7 @@ SERVER_PROFILE_TEMPLATE_LIST_JSON = {
],
"bootMode": None,
"boot": {
"manageBoot": True,
"manageBoot": False,
"order": [
"CD",
"Floppy",
@ -4033,13 +4026,7 @@ SERVER_PROFILE_TEMPLATE_LIST_JSON = {
"pxeBootPolicy": None
},
"boot": {
"manageBoot": True,
"order": [
"CD",
"USB",
"HardDisk",
"PXE"
]
"manageBoot": False,
},
"bios": {
"manageBios": False,

View File

@ -311,7 +311,83 @@ class OneViewClientTestCase(unittest.TestCase):
)
@mock.patch.object(requests, 'get', autospec=True)
def test_validate_spt_boot_connections(self, mock_get, mock__authenticate):
def test_validate_node_server_profile_template(
self, mock_get, mock__authenticate
):
oneview_client = client.Client(self.manager_url,
self.username,
self.password)
server_profile_template = copy.deepcopy(
fixtures.SERVER_PROFILE_TEMPLATE_JSON
)
server_hardware = copy.deepcopy(fixtures.SERVER_HARDWARE_JSON)
server_hardware['serverHardwareTypeUri'] = (
"/rest/server-hardware-types/934E00C0-45F0-4329-AA8C-A0864E834ED4"
)
node_info = {
'server_profile_template_uri':
server_profile_template.get('uri'),
'server_hardware_uri':
server_hardware.get('uri'),
}
response = mock_get.return_value
response.status_code = http_client.OK
response.json = mock.MagicMock()
response.json.side_effect = [
server_profile_template, server_hardware
]
mock_get.return_value = response
oneview_client.validate_node_server_profile_template(
node_info
)
@mock.patch.object(requests, 'get', autospec=True)
def test_validate_node_server_profile_template_manage_boot_false(
self, mock_get, mock__authenticate
):
oneview_client = client.Client(self.manager_url,
self.username,
self.password)
server_profile_template = copy.deepcopy(
fixtures.SERVER_PROFILE_TEMPLATE_JSON
)
server_profile_template['boot']['manageBoot'] = False
server_hardware = copy.deepcopy(fixtures.SERVER_HARDWARE_JSON)
server_hardware['serverHardwareTypeUri'] = (
"/rest/server-hardware-types/934E00C0-45F0-4329-AA8C-A0864E834ED4"
)
node_info = {
'server_profile_template_uri':
server_profile_template.get('uri'),
'server_hardware_uri':
server_hardware.get('uri'),
}
response = mock_get.return_value
response.status_code = http_client.OK
response.json = mock.MagicMock()
response.json.side_effect = [
server_profile_template, server_hardware
]
mock_get.return_value = response
self.assertRaises(
exceptions.OneViewInconsistentResource,
oneview_client.validate_node_server_profile_template,
node_info
)
@mock.patch.object(requests, 'get', autospec=True)
def test__validate_server_profile_template_boot_connections(
self, mock_get, mock__authenticate
):
oneview_client = client.Client(self.manager_url,
self.username,
self.password)
@ -324,6 +400,28 @@ class OneViewClientTestCase(unittest.TestCase):
# Two connections, Primary second
fixtures.SERVER_PROFILE_TEMPLATE_LIST_JSON.get('members')[3],
]
for spt in passes:
server_profile_template = models.ServerProfileTemplate.from_json(
spt
)
response = mock_get.return_value
response.status_code = http_client.OK
response.json = mock.MagicMock(
return_value=server_profile_template
)
mock_get.return_value = response
oneview_client._validate_spt_boot_connections(
server_profile_template
)
@mock.patch.object(requests, 'get', autospec=True)
def test__validate_server_profile_template_boot_connections_fails(
self, mock_get, mock__authenticate
):
oneview_client = client.Client(self.manager_url,
self.username,
self.password)
fails = [
# Single connection, no primary
fixtures.SERVER_PROFILE_TEMPLATE_LIST_JSON.get('members')[1],
@ -332,27 +430,21 @@ class OneViewClientTestCase(unittest.TestCase):
# No connections
fixtures.SERVER_PROFILE_TEMPLATE_LIST_JSON.get('members')[9],
]
for spt in passes:
response = mock_get.return_value
response.status_code = http_client.OK
response.json = mock.MagicMock(
return_value=spt
)
mock_get.return_value = response
oneview_client.validate_spt_boot_connections(
utils.get_uuid_from_uri(spt.get('uri'))
)
for spt in fails:
server_profile_template = models.ServerProfileTemplate.from_json(
spt
)
response = mock_get.return_value
response.status_code = http_client.OK
response.json = mock.MagicMock(
return_value=spt
return_value=server_profile_template
)
mock_get.return_value = response
self.assertRaises(
exceptions.OneViewInconsistentResource,
oneview_client.validate_spt_boot_connections,
utils.get_uuid_from_uri(spt.get('uri'))
oneview_client._validate_spt_boot_connections,
server_profile_template
)
@mock.patch.object(client.Client, '_wait_for_task_to_complete')

View File

@ -769,141 +769,93 @@ class OneViewClientTestCase(unittest.TestCase):
{}
)
@mock.patch.object(client.Client, 'get_server_profile_template',
autospec=True)
@mock.patch.object(client.Client, 'get_server_hardware', autospec=True)
def test_validate_node_server_profile_template_inconsistent_sht(
self, mock_server_hardware, mock_server_template
):
server_hardware_mock = models.ServerHardware()
setattr(server_hardware_mock,
"server_hardware_type_uri",
"/sht_uri")
setattr(server_hardware_mock, "enclosure_group_uri", "eg_uri")
server_profile_template_mock = models.ServerProfileTemplate()
setattr(server_profile_template_mock,
"server_hardware_type_uri",
"/inconsistent_uri")
setattr(server_profile_template_mock,
"enclosure_group_uri",
"/inconsistent_uri")
mock_server_hardware.return_value = server_hardware_mock
mock_server_template.return_value = server_profile_template_mock
driver_info = {
"server_hardware_uri": "/any_uri",
"server_profile_template_uri": "/profile_uri"
}
exc_expected_msg = (
"Server profile template /profile_uri serverHardwareTypeUri is"
" inconsistent with server hardware /any_uri"
" serverHardwareTypeUri."
def test_validate_node_server_profile_template_inconsistent_sht(self):
server_profile_template = models.ServerProfileTemplate()
setattr(server_profile_template, "uri", "/any_uri")
setattr(
server_profile_template, "server_hardware_type_uri", "/any_uri"
)
self.assertRaisesRegexp(
exceptions.OneViewInconsistentResource,
exc_expected_msg,
self.oneview_client.validate_node_server_profile_template,
driver_info
server_hardware = models.ServerHardware()
setattr(server_hardware, "uri", "/any_uri")
setattr(server_hardware, "server_hardware_type_uri", "/sht_uri")
with self.assertRaises(exceptions.OneViewInconsistentResource):
self.oneview_client._validate_spt_server_hardware_type(
server_profile_template, server_hardware
)
def test_validate_node_server_profile_template_inconsistent_eg(self):
server_profile_template = models.ServerProfileTemplate()
setattr(server_profile_template, "uri", "/any_uri")
setattr(server_profile_template, "enclosure_group_uri", "/any_uri")
server_hardware = models.ServerHardware()
setattr(server_hardware, "uri", "/any_uri")
setattr(server_hardware, "enclosure_group_uri", "/eg_uri")
with self.assertRaises(exceptions.OneViewInconsistentResource):
self.oneview_client._validate_spt_enclosure_group(
server_profile_template, server_hardware
)
def test__validate_server_profile_template_manage_boot(self):
server_profile_template = models.ServerProfileTemplate()
setattr(server_profile_template, "uri", "/any_uri")
spt_manage_boot = {'manageBoot': True}
setattr(server_profile_template, "boot", spt_manage_boot)
self.oneview_client._validate_spt_manage_boot(
server_profile_template
)
@mock.patch.object(client.Client, 'get_server_profile_template',
autospec=True)
@mock.patch.object(client.Client, 'get_server_hardware', autospec=True)
def test_validate_node_server_profile_template_inconsistent_eg(
self, mock_server_hardware, mock_server_template
):
server_hardware_mock = models.ServerHardware()
setattr(server_hardware_mock,
"server_hardware_type_uri",
"/sht_uri")
setattr(server_hardware_mock, "enclosure_group_uri", "eg_uri")
def test__validate_server_profile_template_manage_boot_false(self):
server_profile_template = models.ServerProfileTemplate()
setattr(server_profile_template, "uri", "/any_uri")
spt_manage_boot = {'manageBoot': False}
setattr(server_profile_template, "boot", spt_manage_boot)
server_profile_template_mock = models.ServerProfileTemplate()
setattr(server_profile_template_mock,
"server_hardware_type_uri",
"/sht_uri")
setattr(server_profile_template_mock,
"enclosure_group_uri",
"/inconsistent_uri")
with self.assertRaises(exceptions.OneViewInconsistentResource):
self.oneview_client._validate_spt_manage_boot(
server_profile_template
)
mock_server_hardware.return_value = server_hardware_mock
mock_server_template.return_value = server_profile_template_mock
driver_info = {
"server_hardware_uri": "/any_uri",
"server_profile_template_uri": "/profile_uri"
}
exc_expected_msg = (
"Server profile template /profile_uri enclosureGroupUri is"
" inconsistent with server hardware /any_uri"
" serverGroupUri."
)
self.assertRaisesRegexp(
exceptions.OneViewInconsistentResource,
exc_expected_msg,
self.oneview_client.validate_node_server_profile_template,
driver_info
)
@mock.patch.object(client.Client, 'get_server_profile_template_by_uuid',
autospec=True)
def test_validate_spt_boot_connections(
self, mock_server_template
):
server_hardware_mock = models.ServerHardware()
setattr(server_hardware_mock, "server_hardware_type_uri", "/sht_uri")
setattr(server_hardware_mock, "enclosure_group_uri", "/eg_uri")
profile_template_mock = models.ServerProfileTemplate()
setattr(profile_template_mock, "uri", "/template_uri")
setattr(profile_template_mock, "server_hardware_type_uri", "/sht_uri")
setattr(profile_template_mock, "enclosure_group_uri", "/eg_uri")
# Negative scenario
profile_template_mock_connections = [
{'boot': {'priority': u'NotBootable'},
'mac': u'56:88:7B:C0:00:0B'}
]
setattr(profile_template_mock,
"connections",
profile_template_mock_connections)
mock_server_template.return_value = profile_template_mock
exc_expected_msg = (
"No primary boot connection configured for server profile"
" template /template_uri."
)
server_profile_template_uuid = '11111111-2222-3333-4444-5555555555'
self.assertRaisesRegexp(
exceptions.OneViewInconsistentResource,
exc_expected_msg,
self.oneview_client.validate_spt_boot_connections,
server_profile_template_uuid
)
# Positive scenario
def test__validate_spt_boot_connections(self):
server_profile_template = models.ServerProfileTemplate()
setattr(server_profile_template, "uri", "/template_uri")
profile_template_mock_connections = [
{'boot': {'priority': u'Primary'},
'mac': u'56:88:7B:C0:00:0B'}
]
setattr(profile_template_mock,
setattr(server_profile_template,
"connections",
profile_template_mock_connections)
mock_server_template.return_value = profile_template_mock
self.oneview_client.validate_spt_boot_connections(
server_profile_template_uuid
self.oneview_client._validate_spt_boot_connections(
server_profile_template
)
def test__validate_spt_boot_connections_no_primary_boot(self):
server_profile_template = models.ServerProfileTemplate()
setattr(server_profile_template, "uri", "/template_uri")
profile_template_mock_connections = [
{'boot': {'priority': u'NotBootable'},
'mac': u'56:88:7B:C0:00:0B'}
]
setattr(server_profile_template,
"connections",
profile_template_mock_connections)
with self.assertRaises(exceptions.OneViewInconsistentResource):
self.oneview_client._validate_spt_boot_connections(
server_profile_template
)
def test__validate_spt_boot_connections_more_than_one_connection(self):
server_profile_template = models.ServerProfileTemplate()
setattr(server_profile_template, "uri", "/template_uri")
# More than one connection, Primary first
profile_template_mock_connections = [
{'boot': {'priority': u'Primary'},
@ -911,14 +863,12 @@ class OneViewClientTestCase(unittest.TestCase):
{'boot': {'priority': u'NotBootable'},
'mac': u'56:88:7B:C0:00:0C'}
]
setattr(profile_template_mock,
setattr(server_profile_template,
"connections",
profile_template_mock_connections)
mock_server_template.return_value = profile_template_mock
self.oneview_client.validate_spt_boot_connections(
server_profile_template_uuid
self.oneview_client._validate_spt_boot_connections(
server_profile_template
)
# More than one connection, Primary NOT first
@ -928,14 +878,12 @@ class OneViewClientTestCase(unittest.TestCase):
{'boot': {'priority': u'Primary'},
'mac': u'56:88:7B:C0:00:0C'}
]
setattr(profile_template_mock,
setattr(server_profile_template,
"connections",
profile_template_mock_connections)
mock_server_template.return_value = profile_template_mock
self.oneview_client.validate_spt_boot_connections(
server_profile_template_uuid
self.oneview_client._validate_spt_boot_connections(
server_profile_template
)
@mock.patch.object(client.Client, 'get_server_profile_template_by_uuid',