Fellype Cavalcante 000809f779 Remove old validations of memory_mb before manage state
This patch serves to correct the problem presented in UFCG OneView CI,
in which the node was being created and changed the state to manageable,
and only validate the memory_mb after that.

Change-Id: Id0ef20b320a622da6990f6ffaf26256059582743
2017-08-22 15:09:28 -03:00

869 lines
32 KiB
Python

# (c) Copyright 2015 Hewlett Packard Enterprise Development LP
# Copyright 2015 Universidade Federal de Campina Grande
#
# 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 abc
import json
import six
import time
import requests
import retrying
from oneview_client import auditing
from oneview_client import exceptions
from oneview_client import ilo_utils
from oneview_client import managers
from oneview_client import states
from oneview_client import utils
SUPPORTED_ONEVIEW_VERSION = 200
WAIT_DO_REQUEST_IN_MILLISECONDS = 1000
WAIT_TASK_IN_MILLISECONDS = 1000
GET_REQUEST_TYPE = 'GET'
PUT_REQUEST_TYPE = 'PUT'
POST_REQUEST_TYPE = 'POST'
DELETE_REQUEST_TYPE = 'DELETE'
MOMENTARY_PRESS = 'MomentaryPress'
PRESS_AND_HOLD = 'PressAndHold'
SERVER_HARDWARE_PREFIX_URI = '/rest/server-hardware/'
SERVER_PROFILE_TEMPLATE_PREFIX_URI = '/rest/server-profile-templates/'
SERVER_PROFILE_PREFIX_URI = '/rest/server-profiles/'
@six.add_metaclass(abc.ABCMeta)
class BaseClient(object):
def __init__(
self, manager_url, username, password,
allow_insecure_connections=False, tls_cacert_file='',
max_polling_attempts=20, audit_enabled=False,
audit_map_file='', audit_output_file=''
):
self.manager_url = manager_url
self.username = username
self.password = password
self.allow_insecure_connections = allow_insecure_connections
self.tls_cacert_file = tls_cacert_file
self.max_polling_attempts = max_polling_attempts
self.audit_enabled = audit_enabled
self.audit_map_file = audit_map_file
self.audit_output_file = audit_output_file
self.audit_case_methods = []
if self.allow_insecure_connections:
requests.packages.urllib3.disable_warnings(
requests.packages.urllib3.exceptions.InsecureRequestWarning
)
if self.audit_enabled:
self.audit_case_methods = auditing.read_audit_map_file(
self.audit_map_file
)
self.session_id = self.get_session()
@auditing.audit
def verify_credentials(self):
return self._authenticate()
@auditing.audit
def get_session(self):
response = self._authenticate()
return response.json().get('sessionID')
@auditing.audit
def _authenticate(self):
if self.manager_url in ("", None):
raise exceptions.OneViewConnectionError(
"Can't connect to OneView: 'manager_url' configuration"
"parameter is blank")
url = '%s/rest/login-sessions' % self.manager_url
body = {
'userName': self.username,
'password': self.password
}
headers = {
'content-type': 'application/json'
}
verify_ssl = self._get_verify_connection_option()
r = requests.post(url,
data=json.dumps(body),
headers=headers,
verify=verify_ssl)
if r.status_code == 400:
raise exceptions.OneViewNotAuthorizedException()
else:
return r
@auditing.audit
def _logout(self):
if self.manager_url in ("", None):
raise exceptions.OneViewConnectionError(
"Can't connect to OneView: 'manager_url' configuration"
"parameter is blank")
url = '%s/rest/login-sessions' % self.manager_url
headers = {
'X-Api-Version': str(SUPPORTED_ONEVIEW_VERSION),
'Auth': self.session_id
}
verify_ssl = self._get_verify_connection_option()
r = requests.delete(url,
headers=headers,
verify=verify_ssl)
if r.status_code == 400:
raise exceptions.OneViewNotAuthorizedException()
@auditing.audit
def _get_verify_connection_option(self):
verify_status = False
user_cacert = self.tls_cacert_file
if self.allow_insecure_connections is False:
if not user_cacert:
verify_status = True
else:
verify_status = user_cacert
return verify_status
@auditing.audit
def verify_oneview_version(self):
if not self._is_oneview_version_compatible():
msg = ("The version of the OneView's API is unsupported. "
"Supported version is '%s'" % SUPPORTED_ONEVIEW_VERSION)
raise exceptions.IncompatibleOneViewAPIVersion(msg)
@auditing.audit
def _is_oneview_version_compatible(self):
versions = self.get_oneview_version()
v = SUPPORTED_ONEVIEW_VERSION
min_version_compatible = versions.get("minimumVersion") <= v
max_version_compatible = versions.get("currentVersion") >= v
return min_version_compatible and max_version_compatible
@auditing.audit
def get_oneview_version(self):
url = '%s/rest/version' % self.manager_url
headers = {"Accept-Language": "en_US"}
verify_ssl = self._get_verify_connection_option()
response = requests.get(
url, headers=headers, verify=verify_ssl
)
self._check_request_status(response, url)
versions = response.json()
return versions
# --- Requests ---
def _prepare_and_do_request(
self, uri, body={}, request_type=GET_REQUEST_TYPE
):
json_response = {}
try:
if not self.session_id:
self.session_id = self.get_session()
headers = {
'content-type': 'application/json',
'X-Api-Version': str(SUPPORTED_ONEVIEW_VERSION),
'Auth': self.session_id
}
url = '%s%s' % (self.manager_url, uri)
body = json.dumps(body)
try:
response = self._do_request(url, headers, body, request_type)
except exceptions.OneViewNotAuthorizedException:
self.session_id = self.get_session()
headers['Auth'] = self.session_id
response = self._do_request(url, headers, body, request_type)
json_response = response.json()
except requests.RequestException as e:
connection_error = str(e.message).split(':')[-1]
log_message = ("Can't connect to OneView: %s" % connection_error)
raise exceptions.OneViewConnectionError(log_message)
return json_response
@auditing.audit
def _do_request(self, url, headers, body, request_type):
verify_status = self._get_verify_connection_option()
@retrying.retry(
stop_max_attempt_number=self.max_polling_attempts,
retry_on_result=lambda response: self._check_request_status(
response, url
),
wait_fixed=WAIT_DO_REQUEST_IN_MILLISECONDS
)
def request(url, headers, body, request_type):
if request_type == PUT_REQUEST_TYPE:
response = requests.put(
url, data=body, headers=headers, verify=verify_status
)
elif request_type == POST_REQUEST_TYPE:
response = requests.post(
url, data=body, headers=headers, verify=verify_status
)
elif request_type == DELETE_REQUEST_TYPE:
response = requests.delete(
url, headers=headers, verify=verify_status
)
else:
response = requests.get(
url, headers=headers, verify=verify_status
)
return response
return request(url, headers, body, request_type)
@auditing.audit
def _wait_for_task_to_complete(self, task):
@retrying.retry(
retry_on_result=lambda task: task.get('percentComplete') < 100,
wait_fixed=WAIT_TASK_IN_MILLISECONDS,
retry_on_exception=lambda task: False
)
def wait(task):
uri = task.get('uri')
task = self._prepare_and_do_request(uri)
task_state = task.get("taskState")
error_code = task.get("errorCode")
if (not task_state) and error_code:
details = task.get("details")
if error_code == "RESOURCE_NOT_FOUND":
raise exceptions.OneViewResourceNotFoundError(details)
else:
raise exceptions.OneViewTaskError("%s - %s"
% (error_code, details))
elif task_state.lower() == 'error':
raise exceptions.OneViewTaskError("The task '%s' returned an "
"error state" % uri)
return task
return wait(task)
@auditing.audit
def _get_ilo_access(self, server_hardware_uuid):
uri = ("/rest/server-hardware/%s/remoteConsoleUrl"
% server_hardware_uuid)
json = self._prepare_and_do_request(uri)
url = json.get("remoteConsoleUrl")
ip_key = "addr="
host_ip = url[url.rfind(ip_key) + len(ip_key):]
host_ip = host_ip[:host_ip.find("&")]
session_key = "sessionkey="
token = url[url.rfind(session_key) + len(session_key):]
return host_ip, token
@auditing.audit
def get_sh_mac_from_ilo(self, server_hardware_uuid, nic_index=0):
host_ip, ilo_token = self._get_ilo_access(server_hardware_uuid)
try:
return ilo_utils.get_mac_from_ilo(host_ip,
ilo_token,
nic_index,
self.allow_insecure_connections)
finally:
ilo_utils.ilo_logout(host_ip, ilo_token)
@auditing.audit
def _set_onetime_boot(self, server_hardware_uuid, boot_device):
host_ip, ilo_token = self._get_ilo_access(server_hardware_uuid)
oneview_ilo_mapping = {
'HardDisk': 'Hdd',
'PXE': 'Pxe',
'CD': 'Cd',
'USB': 'Usb',
}
try:
ilo_device = oneview_ilo_mapping[boot_device]
return ilo_utils.set_onetime_boot(host_ip, ilo_token,
ilo_device,
self.allow_insecure_connections)
except exceptions.IloException as e:
raise e
except KeyError as e:
raise exceptions.IloException(
"Set one-time boot to %s is not supported." % boot_device
)
finally:
ilo_utils.ilo_logout(host_ip, ilo_token)
def _check_request_status(self, response, url):
repeat = False
status = response.status_code
if status in (401, 403):
error_code = response.json().get('errorCode')
raise exceptions.OneViewNotAuthorizedException(error_code)
elif status == 404:
raise exceptions.OneViewResourceNotFoundError(url)
elif status in (408, 409,):
time.sleep(10)
repeat = True
elif status == 500:
raise exceptions.OneViewInternalServerError()
# Any other unexpected status are logged
elif status not in (200, 202,):
message = (
"OneView appliance returned an unknown response status: %s"
% status
)
raise exceptions.UnknowOneViewResponseError(message)
return repeat
class ClientV2(BaseClient):
def __init__(
self, manager_url, username, password,
allow_insecure_connections=False, tls_cacert_file='',
max_polling_attempts=20, audit_enabled=False,
audit_map_file='', audit_output_file=''
):
super(ClientV2, self).__init__(manager_url, username, password,
allow_insecure_connections,
tls_cacert_file, max_polling_attempts,
audit_enabled, audit_map_file,
audit_output_file)
# Next generation
self.enclosure = managers.EnclosureManager(self)
self.enclosure_group = managers.EnclosureGroupManager(self)
self.server_hardware = managers.ServerHardwareManager(self)
self.server_hardware_index = managers.ServerHardwareIndexManager(self)
self.server_hardware_type = managers.ServerHardwareTypeManager(self)
self.server_profile = managers.ServerProfileManager(self)
self.server_profile_template = managers.ServerProfileTemplateManager(
self
)
class Client(BaseClient):
def __init__(
self, manager_url, username, password,
allow_insecure_connections=False, tls_cacert_file='',
max_polling_attempts=20, audit_enabled=False,
audit_map_file='', audit_output_file=''
):
super(Client, self).__init__(manager_url, username, password,
allow_insecure_connections,
tls_cacert_file, max_polling_attempts,
audit_enabled, audit_map_file,
audit_output_file)
# Next generation
self._enclosure_group = managers.EnclosureGroupManager(self)
self._server_hardware = managers.ServerHardwareManager(self)
self._server_profile_template = managers.ServerProfileTemplateManager(
self
)
self._server_profile = managers.ServerProfileManager(self)
# --- Power Driver ---
@auditing.audit
def get_node_power_state(self, node_info):
return self.get_server_hardware(node_info).power_state
@auditing.audit
def power_on(self, node_info):
if self.get_node_power_state(node_info) == states.ONEVIEW_POWER_ON:
ret = states.ONEVIEW_POWER_ON
else:
ret = self.set_node_power_state(node_info, states.ONEVIEW_POWER_ON)
return ret
@auditing.audit
def power_off(self, node_info):
if self.get_node_power_state(node_info) == states.ONEVIEW_POWER_OFF:
ret = states.ONEVIEW_POWER_OFF
else:
ret = self.set_node_power_state(
node_info, states.ONEVIEW_POWER_OFF, PRESS_AND_HOLD
)
return ret
@auditing.audit
def set_node_power_state(
self, node_info, state, press_type=MOMENTARY_PRESS
):
body = {'powerState': state, 'powerControl': press_type}
power_state_uri = (node_info.get('server_hardware_uri') +
'/powerState')
task = self._prepare_and_do_request(
uri=power_state_uri, body=body, request_type=PUT_REQUEST_TYPE
)
try:
self._wait_for_task_to_complete(task)
except exceptions.OneViewTaskError as e:
raise exceptions.OneViewErrorStateSettingPowerState(e.message)
return state
# --- Management Driver ---
@auditing.audit
def get_server_hardware(self, node_info):
uuid = node_info['server_hardware_uri'].split("/")[-1]
return self._server_hardware.get(uuid)
@auditing.audit
def get_server_hardware_by_uuid(self, uuid):
return self._server_hardware.get(uuid)
@auditing.audit
def get_server_profile_from_hardware(self, node_info):
server_hardware = self.get_server_hardware(node_info)
server_profile_uri = server_hardware.server_profile_uri
if server_profile_uri is None:
message = (
"There is no server profile assigned to"
" %(server_hardware_uri)s" %
{'server_hardware_uri': node_info.get('server_hardware_uri')}
)
raise exceptions.OneViewServerProfileAssociatedError(message)
server_profile_uuid = server_profile_uri.split("/")[-1]
return self._server_profile.get(server_profile_uuid)
@auditing.audit
def get_server_profile_template(self, node_info):
uuid = node_info['server_profile_template_uri'].split("/")[-1]
return self._server_profile_template.get(uuid)
@auditing.audit
def get_server_profile_template_by_uuid(self, uuid):
return self._server_profile_template.get(uuid)
@auditing.audit
def get_server_profile_by_uuid(self, uuid):
return self._server_profile.get(uuid)
@auditing.audit
def get_boot_order(self, node_info):
server_profile = self.get_server_profile_from_hardware(
node_info
)
return server_profile.boot.get("order")
@auditing.audit
def set_boot_device(self, node_info, new_primary_boot_device,
onetime=False):
if new_primary_boot_device is None:
raise exceptions.OneViewBootDeviceInvalidError()
boot_order = self.get_boot_order(node_info)
if new_primary_boot_device == boot_order[0]:
return
if onetime:
try:
sh_uuid = utils.get_uuid_from_uri(
node_info['server_hardware_uri']
)
self._set_onetime_boot(sh_uuid, new_primary_boot_device)
return
except exceptions.IloException:
# Falls back to persistent in case of failure
pass
self._persistent_set_boot_device(node_info, boot_order,
new_primary_boot_device)
@auditing.audit
def _persistent_set_boot_device(self, node_info, boot_order,
new_primary_boot_device):
if new_primary_boot_device in boot_order:
boot_order.remove(new_primary_boot_device)
boot_order.insert(0, new_primary_boot_device)
server_profile = self.get_server_profile_from_hardware(
node_info
)
manage_boot = server_profile.boot.get("manageBoot")
server_profile.boot = {
"manageBoot": manage_boot,
"order": boot_order
}
boot_order_dict = server_profile.to_oneview_dict()
task = self._prepare_and_do_request(
uri=server_profile.uri, body=boot_order_dict,
request_type=PUT_REQUEST_TYPE
)
try:
self._wait_for_task_to_complete(task)
except exceptions.OneViewTaskError as e:
raise exceptions.OneViewErrorSettingBootDevice(e.message)
# ---- Deploy Driver ----
@auditing.audit
def clone_template_and_apply(self,
server_profile_name,
server_hardware_uuid,
server_profile_template_uuid):
if not server_profile_name:
raise ValueError(
'Missing Server Profile name.'
)
if not server_hardware_uuid:
raise ValueError(
'Missing Server Hardware uuid.'
)
if not server_profile_template_uuid:
raise ValueError(
'Missing Server Profile Template uuid.'
)
server_hardware_uri = '%s%s' % (
SERVER_HARDWARE_PREFIX_URI,
server_hardware_uuid
)
server_profile_template_uri = '%s%s' % (
SERVER_PROFILE_TEMPLATE_PREFIX_URI,
server_profile_template_uuid
)
generate_new_profile_uri = '%s/new-profile' % (
server_profile_template_uri
)
server_profile_from_template_json = self._prepare_and_do_request(
uri=generate_new_profile_uri
)
server_profile_from_template_json['serverHardwareUri'] = (
server_hardware_uri
)
server_profile_from_template_json['name'] = server_profile_name
server_profile_from_template_json['serverProfileTemplateUri'] = ""
post_profile_task = self._prepare_and_do_request(
uri=SERVER_PROFILE_PREFIX_URI,
body=server_profile_from_template_json,
request_type=POST_REQUEST_TYPE
)
try:
complete_task = self._wait_for_task_to_complete(
post_profile_task
)
except exceptions.OneViewTaskError as e:
raise exceptions.OneViewServerProfileAssignmentError(e.message)
server_profile_uri = (
complete_task.get('associatedResource').get('resourceUri')
)
uuid = server_profile_uri.split("/")[-1]
server_profile = self.get_server_profile_by_uuid(uuid)
return server_profile
@auditing.audit
def delete_server_profile(self, uuid):
if not uuid:
raise ValueError('Missing Server Profile uuid.')
delete_profile_task = self._prepare_and_do_request(
uri='%s%s' % (SERVER_PROFILE_PREFIX_URI, uuid),
request_type=DELETE_REQUEST_TYPE
)
try:
complete_task = self._wait_for_task_to_complete(
delete_profile_task
)
except exceptions.OneViewTaskError as e:
raise exceptions.OneViewServerProfileDeletionError(e.message)
return complete_task.get('associatedResource').get('resourceUri')
# ---- Node Validate ----
@auditing.audit
def validate_connections(self, oneview_info, ports, network_interface):
if network_interface != 'neutron':
self._is_node_port_mac_compatible_with_server_hardware(
oneview_info, ports)
self._validate_server_profile_template_mac_type(oneview_info)
elif oneview_info.get('use_oneview_ml2_driver'):
valid_ports = utils.get_oneview_connection_ports(ports)
self._validate_node_and_port_server_hardware_uri(
oneview_info, valid_ports)
self._validate_connection_mac(oneview_info, valid_ports)
def is_node_port_mac_compatible_with_server_hardware(
self, node_info, ports
):
# NOTE(mrtenio): While the connection validation patch
# is not accepted, we need to refer to the new validation.
self._is_node_port_mac_compatible_with_server_hardware(
node_info, ports)
@auditing.audit
def _is_node_port_mac_compatible_with_server_hardware(
self, node_info, ports
):
if not ports:
return
server_hardware = self.get_server_hardware(node_info)
try:
mac = server_hardware.get_mac(nic_index=0)
except exceptions.OneViewException:
mac = self.get_sh_mac_from_ilo(server_hardware.uuid, nic_index=0)
for port in ports:
if port.address.lower() == mac:
return
message = (
"The ports of the node are not compatible with its "
"server hardware %(server_hardware_uri)s." %
{'server_hardware_uri': server_hardware.uri}
)
raise exceptions.OneViewInconsistentResource(message)
def validate_server_profile_template_mac_type(self, spt_uuid):
info = {"server_profile_template_uri": spt_uuid}
self._validate_server_profile_template_mac_type(info)
@auditing.audit
def _validate_server_profile_template_mac_type(self, oneview_info):
server_profile_template = self.get_server_profile_template(
oneview_info
)
if server_profile_template.mac_type != 'Physical':
message = (
"The server profile template %s is not set to use "
"physical MAC." % server_profile_template.uri
)
raise exceptions.OneViewInconsistentResource(message)
@auditing.audit
def _validate_node_and_port_server_hardware_uri(self, oneview_info, ports):
node_hardware_id = utils.get_uuid_from_uri(
oneview_info.get('server_hardware_uri')
)
for port in ports:
switch_info = utils.get_switch_info(port)
port_hardware_id = switch_info.get('server_hardware_id')
if port_hardware_id.lower() != node_hardware_id.lower():
raise exceptions.OneViewInconsistentResource(
"The Server Hardware ID of the port %(port_id)s "
"doesn't match the Server Hardware ID %(server_hardware)s "
"of the node." % {
'port_id': port.uuid,
'server_hardware': node_hardware_id
}
)
@auditing.audit
def _validate_connection_mac(self, oneview_info, ports):
server_hardware = self.get_server_hardware(oneview_info)
for port in ports:
if port.address.lower() not in utils.get_all_macs(server_hardware):
raise exceptions.OneViewInconsistentResource(
"The MAC address %(mac)s of the port %(port_id)s doesn't"
" have a corresponding MAC address in the Server Hardware"
" %(server_hardware_uri)s" % {
'mac': port.address,
'port_id': port.uuid,
'server_hardware_uri': server_hardware.uri
}
)
@auditing.audit
def validate_node_server_hardware(
self, node_info, node_memorymb, node_cpus
):
# NOTE(fellypefca): This is temporary to fix the problems of CI.
pass
@auditing.audit
def validate_node_server_hardware_type(self, node_info):
node_sht_uri = node_info.get('server_hardware_type_uri')
server_hardware = self.get_server_hardware(node_info)
server_hardware_sht_uri = server_hardware.server_hardware_type_uri
if server_hardware_sht_uri != node_sht_uri:
message = (
"Node server_hardware_type_uri is inconsistent"
" with OneView's server hardware %(server_hardware_uri)s"
" serverHardwareTypeUri." %
{'server_hardware_uri': node_info.get('server_hardware_uri')}
)
raise exceptions.OneViewInconsistentResource(message)
@auditing.audit
def check_server_profile_is_applied(self, node_info):
self.get_server_profile_from_hardware(node_info)
@auditing.audit
def validate_node_enclosure_group(self, node_info):
server_hardware = self.get_server_hardware(node_info)
sh_enclosure_group_uri = server_hardware.enclosure_group_uri
node_enclosure_group_uri = node_info.get('enclosure_group_uri')
if node_enclosure_group_uri not in ('', 'None', None):
if sh_enclosure_group_uri != node_enclosure_group_uri:
message = (
"Node enclosure_group_uri '%(node_enclosure_group_uri)s' "
"is inconsistent with OneView's server hardware "
"serverGroupUri '%(sh_enclosure_group_uri)s' of "
"ServerHardware %(server_hardware)s"
% {
'node_enclosure_group_uri': node_enclosure_group_uri,
'sh_enclosure_group_uri': sh_enclosure_group_uri,
'server_hardware': server_hardware.uuid,
}
)
raise exceptions.OneViewInconsistentResource(message)
@auditing.audit
def is_node_port_mac_compatible_with_server_profile(
self, node_info, ports
):
server_profile = self.get_server_profile_from_hardware(
node_info
)
if server_profile.connections:
primary_boot_connection = None
for connection in server_profile.connections:
boot = connection.get('boot')
if (boot is not None and
boot.get('priority').lower() == 'primary'):
primary_boot_connection = connection
if primary_boot_connection is None:
message = (
"No primary boot connection configured for server profile"
" %s." % server_profile.uri
)
raise exceptions.OneViewInconsistentResource(message)
mac = primary_boot_connection.get('mac')
else:
# If no connections on Server Profile, the connections are not
# being managed or the server is rack based. In both cases, fall
# back to 1st nic from iLO
server_hardware = self.get_server_hardware(node_info)
mac = self.get_sh_mac_from_ilo(server_hardware.uuid, nic_index=0)
for port in ports:
if port.address.lower() == mac.lower():
return
message = (
"The ports of the node are not compatible with its"
" server profile %(server_profile_uri)s." %
{'server_profile_uri': server_profile.uri}
)
raise exceptions.OneViewInconsistentResource(message)
@auditing.audit
def validate_node_server_profile_template(self, node_info):
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
)
sh_server_hardware_type_uri = server_hardware.server_hardware_type_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': server_profile_template.uri,
'server_hardware_uri': server_hardware.uri}
)
raise exceptions.OneViewInconsistentResource(message)
@auditing.audit
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
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
message = (
"No primary boot connection configured for server profile"
" template %s." % server_profile_template.uri
)
raise exceptions.OneViewInconsistentResource(message)