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:
parent
566b53c828
commit
787b72794a
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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')
|
||||
|
|
|
@ -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',
|
||||
|
|
Loading…
Reference in New Issue