OneView client with managers
This patch implements object managers for OneView objects and uses it for the new ClientV2 class. This will make the UX of python-oneview client much simpler than having a ton of specific methods directly on the Client object. Change-Id: I7502212fa340e3a142b5aaa5b590dd4d4254e022
This commit is contained in:
parent
85577a1b03
commit
caa0e7a657
@ -13,7 +13,9 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import abc
|
||||
import json
|
||||
import six
|
||||
import time
|
||||
|
||||
import requests
|
||||
@ -21,9 +23,7 @@ import retrying
|
||||
|
||||
from oneview_client import exceptions
|
||||
from oneview_client import ilo_utils
|
||||
from oneview_client.models import ServerHardware
|
||||
from oneview_client.models import ServerProfile
|
||||
from oneview_client.models import ServerProfileTemplate
|
||||
from oneview_client import managers
|
||||
from oneview_client import states
|
||||
|
||||
|
||||
@ -44,7 +44,8 @@ SERVER_HARDWARE_PREFIX_URI = '/rest/server-hardware/'
|
||||
SERVER_PROFILE_TEMPLATE_PREFIX_URI = '/rest/server-profile-templates/'
|
||||
|
||||
|
||||
class Client(object):
|
||||
@six.add_metaclass(abc.ABCMeta)
|
||||
class BaseClient(object):
|
||||
|
||||
def __init__(
|
||||
self, manager_url, username, password,
|
||||
@ -131,6 +132,147 @@ class Client(object):
|
||||
except requests.RequestException as e:
|
||||
raise exceptions.OneViewConnectionError(e.message)
|
||||
|
||||
# --- 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': SUPPORTED_ONEVIEW_VERSION,
|
||||
'Auth': self.session_id
|
||||
}
|
||||
url = '%s%s' % (self.manager_url, uri)
|
||||
body = json.dumps(body)
|
||||
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
|
||||
|
||||
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: _check_request_status(response),
|
||||
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)
|
||||
|
||||
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)
|
||||
|
||||
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
|
||||
|
||||
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)
|
||||
finally:
|
||||
ilo_utils.ilo_logout(host_ip, ilo_token)
|
||||
|
||||
|
||||
class ClientV2(BaseClient):
|
||||
|
||||
def __init__(
|
||||
self, manager_url, username, password,
|
||||
allow_insecure_connections=False, tls_cacert_file='',
|
||||
max_polling_attempts=20
|
||||
):
|
||||
super(ClientV2, self).__init__(manager_url, username, password,
|
||||
allow_insecure_connections,
|
||||
tls_cacert_file, max_polling_attempts)
|
||||
# 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
|
||||
):
|
||||
super(Client, self).__init__(manager_url, username, password,
|
||||
allow_insecure_connections,
|
||||
tls_cacert_file, max_polling_attempts)
|
||||
# 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 ---
|
||||
def get_node_power_state(self, node_info):
|
||||
return self.get_server_hardware(node_info).power_state
|
||||
@ -182,18 +324,10 @@ class Client(object):
|
||||
def get_server_hardware(self, node_info):
|
||||
uuid = node_info['server_hardware_uri'].split("/")[-1]
|
||||
|
||||
return self.get_server_hardware_by_uuid(uuid)
|
||||
return self._server_hardware.get(uuid)
|
||||
|
||||
def get_server_hardware_by_uuid(self, uuid):
|
||||
server_hardware_uri = SERVER_HARDWARE_PREFIX_URI + str(uuid)
|
||||
server_hardware_json = self._prepare_and_do_request(
|
||||
uri=server_hardware_uri
|
||||
)
|
||||
if server_hardware_json.get("uri") is None:
|
||||
message = "OneView Server Hardware resource not found."
|
||||
raise exceptions.OneViewResourceNotFoundError(message)
|
||||
|
||||
return ServerHardware.from_json(server_hardware_json)
|
||||
return self._server_hardware.get(uuid)
|
||||
|
||||
def get_server_profile_from_hardware(self, node_info):
|
||||
server_hardware = self.get_server_hardware(node_info)
|
||||
@ -207,34 +341,17 @@ class Client(object):
|
||||
)
|
||||
raise exceptions.OneViewServerProfileAssociatedError(message)
|
||||
|
||||
server_profile_json = self._prepare_and_do_request(
|
||||
uri=server_profile_uri
|
||||
)
|
||||
server_profile_uuid = server_profile_uri.split("/")[-1]
|
||||
|
||||
if server_profile_json.get('uri') is None:
|
||||
message = "OneView Server Profile resource not found."
|
||||
raise exceptions.OneViewResourceNotFoundError(message)
|
||||
|
||||
return ServerProfile.from_json(server_profile_json)
|
||||
return self._server_profile.get(server_profile_uuid)
|
||||
|
||||
def get_server_profile_template(self, node_info):
|
||||
uuid = node_info['server_profile_template_uri'].split("/")[-1]
|
||||
|
||||
return self.get_server_profile_template_by_uuid(uuid)
|
||||
return self._server_profile.get(uuid)
|
||||
|
||||
def get_server_profile_template_by_uuid(self, uuid):
|
||||
server_profile_template_uri = SERVER_PROFILE_TEMPLATE_PREFIX_URI \
|
||||
+ str(uuid)
|
||||
|
||||
spt_json = self._prepare_and_do_request(
|
||||
uri=server_profile_template_uri
|
||||
)
|
||||
|
||||
if spt_json.get("uri") is None:
|
||||
message = "OneView Server Profile Template resource not found."
|
||||
raise exceptions.OneViewResourceNotFoundError(message)
|
||||
|
||||
return ServerProfileTemplate.from_json(spt_json)
|
||||
return self._server_profile_template.get(uuid)
|
||||
|
||||
def get_boot_order(self, node_info):
|
||||
server_profile = self.get_server_profile_from_hardware(
|
||||
@ -457,106 +574,6 @@ class Client(object):
|
||||
)
|
||||
raise exceptions.OneViewInconsistentResource(message)
|
||||
|
||||
# --- 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': SUPPORTED_ONEVIEW_VERSION,
|
||||
'Auth': self.session_id
|
||||
}
|
||||
url = '%s%s' % (self.manager_url, uri)
|
||||
body = json.dumps(body)
|
||||
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
|
||||
|
||||
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: _check_request_status(response),
|
||||
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)
|
||||
|
||||
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)
|
||||
|
||||
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
|
||||
|
||||
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)
|
||||
finally:
|
||||
ilo_utils.ilo_logout(host_ip, ilo_token)
|
||||
|
||||
|
||||
def _check_request_status(response):
|
||||
repeat = False
|
||||
|
228
oneview_client/managers.py
Normal file
228
oneview_client/managers.py
Normal file
@ -0,0 +1,228 @@
|
||||
# -*- encoding: utf-8 -*-
|
||||
#
|
||||
# Copyright 2015 Hewlett-Packard Development Company, L.P.
|
||||
# Copyright 2015 Universidade Federal de Campina Grande
|
||||
# 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 abc
|
||||
import six
|
||||
|
||||
from oneview_client import exceptions
|
||||
from oneview_client import models
|
||||
|
||||
|
||||
ONEVIEW_POWER_ON = 'On'
|
||||
ONEVIEW_POWER_OFF = 'Off'
|
||||
|
||||
|
||||
@six.add_metaclass(abc.ABCMeta)
|
||||
class OneViewManager(object):
|
||||
|
||||
def __init__(self, oneview_client):
|
||||
self.oneview_client = oneview_client
|
||||
|
||||
@abc.abstractproperty
|
||||
def model(self):
|
||||
pass
|
||||
|
||||
@abc.abstractproperty
|
||||
def uri_prefix(self):
|
||||
pass
|
||||
|
||||
def list(self, **kwargs):
|
||||
resource_uri = self.uri_prefix
|
||||
resource_json = self.oneview_client._prepare_and_do_request(
|
||||
uri=resource_uri
|
||||
)
|
||||
|
||||
members = resource_json.get("members")
|
||||
resources = [self.model.from_json(resource) for resource in members]
|
||||
|
||||
for k, v in kwargs.items():
|
||||
resources = [r for r in resources if getattr(r, k) == v]
|
||||
|
||||
return resources
|
||||
|
||||
def get(self, uuid):
|
||||
resource_uri = self.uri_prefix + str(uuid)
|
||||
resource_json = self.oneview_client._prepare_and_do_request(
|
||||
uri=resource_uri
|
||||
)
|
||||
if resource_json.get("uri") is None:
|
||||
message = "OneView Server Hardware resource not found."
|
||||
raise exceptions.OneViewResourceNotFoundError(message)
|
||||
|
||||
return self.model.from_json(resource_json)
|
||||
|
||||
@abc.abstractmethod
|
||||
def create(self, **kwargs):
|
||||
pass
|
||||
|
||||
@abc.abstractmethod
|
||||
def delete(self, uuid):
|
||||
pass
|
||||
|
||||
|
||||
@six.add_metaclass(abc.ABCMeta)
|
||||
class OneViewIdentityMapManager(OneViewManager):
|
||||
"""Manager that holds instances of OneView objects on cache
|
||||
|
||||
This abstract class lays the ground for classes that have objects retrieved
|
||||
from OneView stored in IdentityMaps (cache) for avoiding unecessary round
|
||||
trips to OneView's REST API. The objects are stored in the maps for the
|
||||
entire life of the client's instance but may be refreshed by calling
|
||||
`list()`
|
||||
"""
|
||||
identity_map = {}
|
||||
|
||||
def list(self, **kwargs):
|
||||
obj_list = super(OneViewIdentityMapManager, self).list()
|
||||
self.identity_map = {obj.uuid: obj for obj in obj_list}
|
||||
return self.identity_map.items()
|
||||
|
||||
def get(self, uuid):
|
||||
if uuid not in self.identity_map.keys():
|
||||
obj = super(OneViewIdentityMapManager, self).get(uuid)
|
||||
self.identity_map[uuid] = obj
|
||||
|
||||
return self.identity_map.get(uuid)
|
||||
|
||||
|
||||
@six.add_metaclass(abc.ABCMeta)
|
||||
class OneViewIndexManager(object):
|
||||
|
||||
def __init__(self, oneview_client):
|
||||
self.oneview_client = oneview_client
|
||||
|
||||
@abc.abstractproperty
|
||||
def model(self):
|
||||
pass
|
||||
|
||||
@abc.abstractproperty
|
||||
def uri_index(self):
|
||||
pass
|
||||
|
||||
def list(self, **kwargs):
|
||||
resource_uri = self.uri_index
|
||||
resource_json = self.oneview_client._prepare_and_do_request(
|
||||
uri=resource_uri
|
||||
)
|
||||
|
||||
members = resource_json.get("members")
|
||||
resources = [self.model.from_json(resource) for resource in members]
|
||||
|
||||
for k, v in kwargs.items():
|
||||
resources = [r for r in resources if getattr(r, k) == v]
|
||||
|
||||
return resources
|
||||
|
||||
def get(self, uuid):
|
||||
resource_uri = self.uri_index + '&filter=uuid:' + str(uuid)
|
||||
resource_json = self.oneview_client._prepare_and_do_request(
|
||||
uri=resource_uri
|
||||
)
|
||||
members = resource_json.get("members")
|
||||
if len(members) == 0:
|
||||
message = "OneView Server Hardware resource not found."
|
||||
raise exceptions.OneViewResourceNotFoundError(message)
|
||||
|
||||
return self.model.from_json(members[0])
|
||||
|
||||
|
||||
class EnclosureManager(OneViewManager):
|
||||
model = models.Enclosure
|
||||
uri_prefix = '/rest/enclosures/'
|
||||
|
||||
def create(self, **kwargs):
|
||||
raise NotImplementedError("Enclosure isn't supposed to be created.")
|
||||
|
||||
def delete(self, uuid):
|
||||
raise NotImplementedError("Enclosure isn't supposed to be deleted.")
|
||||
|
||||
|
||||
class EnclosureGroupManager(OneViewIdentityMapManager):
|
||||
# NOTE: This is an OneViewIdentityMapManager subclass. Objects stored by
|
||||
# this class live for the entire life of the client or until the
|
||||
# `list()` method is called.
|
||||
model = models.EnclosureGroup
|
||||
uri_prefix = '/rest/enclosure-groups/'
|
||||
|
||||
def create(self, **kwargs):
|
||||
raise NotImplementedError("EnclosureGroup isn't supposed to be "
|
||||
"created.")
|
||||
|
||||
def delete(self, uuid):
|
||||
raise NotImplementedError("EnclosureGroup isn't supposed to be "
|
||||
"deleted.")
|
||||
|
||||
|
||||
class ServerHardwareManager(OneViewManager):
|
||||
model = models.ServerHardware
|
||||
uri_prefix = '/rest/server-hardware/'
|
||||
|
||||
def create(self, **kwargs):
|
||||
raise NotImplementedError("ServerHardware isn't supposed to be "
|
||||
"created.")
|
||||
|
||||
def delete(self, uuid):
|
||||
raise NotImplementedError("ServerHardware isn't supposed to be "
|
||||
"deleted.")
|
||||
|
||||
|
||||
class ServerHardwareIndexManager(OneViewIndexManager):
|
||||
model = models.ServerHardware
|
||||
uri_index = '/rest/index/resources?category=server-hardware'
|
||||
|
||||
|
||||
class ServerHardwareTypeManager(OneViewIdentityMapManager):
|
||||
# NOTE: This is an OneViewIdentityMapManager subclass. Objects stored by
|
||||
# this class live for the entire life of the client or until the
|
||||
# `list()` method is called.
|
||||
model = models.ServerHardwareType
|
||||
uri_prefix = '/rest/server-hardware-types/'
|
||||
|
||||
def create(self, **kwargs):
|
||||
raise NotImplementedError("ServerHardwareType isn't supposed to be "
|
||||
"created.")
|
||||
|
||||
def delete(self, uuid):
|
||||
raise NotImplementedError("ServerHardwareType isn't supposed to be "
|
||||
"deleted.")
|
||||
|
||||
|
||||
class ServerProfileManager(OneViewManager):
|
||||
model = models.ServerProfile
|
||||
uri_prefix = '/rest/server-profiles/'
|
||||
|
||||
def create(self, **kwargs):
|
||||
raise NotImplementedError("ServerProfile isn't supposed to be "
|
||||
"created.")
|
||||
|
||||
def delete(self, uuid):
|
||||
raise NotImplementedError("ServerProfile isn't supposed to be "
|
||||
"deleted.")
|
||||
|
||||
|
||||
class ServerProfileTemplateManager(OneViewManager):
|
||||
model = models.ServerProfileTemplate
|
||||
uri_prefix = '/rest/server-profile-templates/'
|
||||
|
||||
def create(self, **kwargs):
|
||||
raise NotImplementedError("ServerProfileTemplate isn't supposed to be "
|
||||
"created.")
|
||||
|
||||
def delete(self, uuid):
|
||||
raise NotImplementedError("ServerProfileTemplate isn't supposed to be "
|
||||
"deleted.")
|
@ -25,15 +25,33 @@ class OneViewObject(object):
|
||||
instance = cls()
|
||||
for attr_key in instance.attribute_map:
|
||||
attribute_value = json.get(attr_key)
|
||||
setattr(instance,
|
||||
instance.attribute_map.get(attr_key),
|
||||
attribute_value)
|
||||
if attribute_value:
|
||||
setattr(instance,
|
||||
instance.attribute_map.get(attr_key),
|
||||
attribute_value)
|
||||
return instance
|
||||
|
||||
def update_from_json(self, json):
|
||||
for attr_key in self.attribute_map:
|
||||
attribute_value = json.get(attr_key)
|
||||
if attribute_value:
|
||||
setattr(self,
|
||||
self.attribute_map.get(attr_key),
|
||||
attribute_value)
|
||||
|
||||
def __getattribute__(self, name):
|
||||
try:
|
||||
return super(OneViewObject, self).__getattribute__(name)
|
||||
except AttributeError:
|
||||
self.lazy_reload()
|
||||
return super(OneViewObject, self).__getattribute__(name)
|
||||
|
||||
|
||||
class EnclosureGroup(OneViewObject):
|
||||
attribute_map = {
|
||||
'uri': 'uri',
|
||||
'uuid': 'uuid',
|
||||
'name': 'name',
|
||||
'enclosureTypeUri': 'enclosure_type_uri',
|
||||
'status': 'status',
|
||||
}
|
||||
@ -52,6 +70,8 @@ class Enclosure(OneViewObject):
|
||||
class ServerHardwareType(OneViewObject):
|
||||
attribute_map = {
|
||||
'uri': 'uri',
|
||||
'uuid': 'uuid',
|
||||
'name': 'name',
|
||||
}
|
||||
|
||||
|
||||
@ -59,6 +79,7 @@ class ServerHardware(OneViewObject):
|
||||
attribute_map = {
|
||||
'uri': 'uri',
|
||||
'uuid': 'uuid',
|
||||
'name': 'name',
|
||||
'powerState': 'power_state',
|
||||
'serverProfileUri': 'server_profile_uri',
|
||||
'serverHardwareTypeUri': 'server_hardware_type_uri',
|
||||
@ -83,10 +104,16 @@ class ServerHardware(OneViewObject):
|
||||
"There is no portMap on the Server Hardware requested. Is "
|
||||
"this a DL server?")
|
||||
|
||||
@property
|
||||
def cpus(self):
|
||||
return (self.processor_count * self.processor_core_count)
|
||||
|
||||
|
||||
class ServerProfileTemplate(OneViewObject):
|
||||
attribute_map = {
|
||||
'uri': 'uri',
|
||||
'uuid': 'uuid',
|
||||
'name': 'name',
|
||||
'serverHardwareTypeUri': 'server_hardware_type_uri',
|
||||
'enclosureGroupUri': 'enclosure_group_uri',
|
||||
'connections': 'connections',
|
||||
|
6529
oneview_client/tests/fixtures.py
Normal file
6529
oneview_client/tests/fixtures.py
Normal file
File diff suppressed because it is too large
Load Diff
595
oneview_client/tests/functional/test_oneview_client.py
Normal file
595
oneview_client/tests/functional/test_oneview_client.py
Normal file
@ -0,0 +1,595 @@
|
||||
# -*- encoding: utf-8 -*-
|
||||
#
|
||||
# (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 mock
|
||||
import requests
|
||||
import six.moves.http_client as http_client
|
||||
import unittest
|
||||
|
||||
from oneview_client import client
|
||||
from oneview_client import exceptions
|
||||
from oneview_client import models
|
||||
from oneview_client.tests import fixtures
|
||||
|
||||
|
||||
PROPERTIES_DICT = {"cpu_arch": "x86_64",
|
||||
"cpus": "8",
|
||||
"local_gb": "10",
|
||||
"memory_mb": "4096",
|
||||
"capabilities": "server_hardware_type_uri:fake_sht_uri,"
|
||||
"enclosure_group_uri:fake_eg_uri"}
|
||||
|
||||
DRIVER_INFO_DICT = {'server_hardware_uri': 'fake_sh_uri',
|
||||
'server_profile_template_uri': 'fake_spt_uri'}
|
||||
|
||||
|
||||
@mock.patch.object(client.Client, '_authenticate', autospec=True)
|
||||
class OneViewClientTestCase(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(OneViewClientTestCase, self).setUp()
|
||||
self.manager_url = 'https://1.2.3.4'
|
||||
self.username = 'user'
|
||||
self.password = 'password'
|
||||
|
||||
@mock.patch.object(requests, 'get', autospec=True)
|
||||
def test_server_hardware_list(self, mock_get, mock__authenticate):
|
||||
oneview_client = client.Client(self.manager_url,
|
||||
self.username,
|
||||
self.password)
|
||||
response = mock_get.return_value
|
||||
response.status_code = http_client.OK
|
||||
response.json = mock.MagicMock(
|
||||
return_value=fixtures.SERVER_HARDWARE_LIST_JSON
|
||||
)
|
||||
mock_get.return_value = response
|
||||
|
||||
server_hardware_list = oneview_client._server_hardware.list()
|
||||
mock_get.assert_called_once_with(
|
||||
url='https://1.2.3.4/rest/server-hardware/',
|
||||
headers=mock.ANY,
|
||||
verify=True
|
||||
)
|
||||
for sh in server_hardware_list:
|
||||
self.assertIsInstance(sh, models.ServerHardware)
|
||||
|
||||
@mock.patch.object(requests, 'get', autospec=True)
|
||||
def test_server_hardware_get(self, mock_get, mock__authenticate):
|
||||
oneview_client = client.Client(self.manager_url,
|
||||
self.username,
|
||||
self.password)
|
||||
response = mock_get.return_value
|
||||
response.status_code = http_client.OK
|
||||
response.json = mock.MagicMock(
|
||||
return_value=fixtures.SERVER_HARDWARE_JSON
|
||||
)
|
||||
mock_get.return_value = response
|
||||
|
||||
sh = oneview_client._server_hardware.get('aaaa-bbbb-cccc')
|
||||
mock_get.assert_called_once_with(
|
||||
url='https://1.2.3.4/rest/server-hardware/aaaa-bbbb-cccc',
|
||||
headers=mock.ANY,
|
||||
verify=True
|
||||
)
|
||||
self.assertIsInstance(sh, models.ServerHardware)
|
||||
|
||||
@mock.patch.object(requests, 'get', autospec=True)
|
||||
def test_server_hardware_get_not_found(self, mock_get, mock__authenticate):
|
||||
oneview_client = client.Client(self.manager_url,
|
||||
self.username,
|
||||
self.password)
|
||||
response = mock_get.return_value
|
||||
response.status_code = http_client.NOT_FOUND
|
||||
mock_get.return_value = response
|
||||
|
||||
self.assertRaises(
|
||||
exceptions.OneViewResourceNotFoundError,
|
||||
oneview_client._server_hardware.get,
|
||||
'aaaa-bbbb-cccc'
|
||||
)
|
||||
|
||||
def test_server_hardware_create(self, mock__authenticate):
|
||||
oneview_client = client.Client(self.manager_url,
|
||||
self.username,
|
||||
self.password)
|
||||
self.assertRaises(
|
||||
NotImplementedError,
|
||||
oneview_client._server_hardware.create,
|
||||
name='something',
|
||||
description='somethingelse',
|
||||
something=0
|
||||
)
|
||||
|
||||
def test_server_hardware_delete(self, mock__authenticate):
|
||||
oneview_client = client.Client(self.manager_url,
|
||||
self.username,
|
||||
self.password)
|
||||
self.assertRaises(
|
||||
NotImplementedError,
|
||||
oneview_client._server_hardware.delete,
|
||||
'aaaa-bbbb-cccc'
|
||||
)
|
||||
|
||||
@mock.patch.object(requests, 'get', autospec=True)
|
||||
def test_server_profile_template_list(self, mock_get, mock__authenticate):
|
||||
oneview_client = client.Client(self.manager_url,
|
||||
self.username,
|
||||
self.password)
|
||||
response = mock_get.return_value
|
||||
response.status_code = http_client.OK
|
||||
response.json = mock.MagicMock(
|
||||
return_value=fixtures.SERVER_PROFILE_TEMPLATE_LIST_JSON
|
||||
)
|
||||
mock_get.return_value = response
|
||||
|
||||
server_profile_template_list = (
|
||||
oneview_client._server_profile_template.list()
|
||||
)
|
||||
mock_get.assert_called_once_with(
|
||||
url='https://1.2.3.4/rest/server-profile-templates/',
|
||||
headers=mock.ANY,
|
||||
verify=True
|
||||
)
|
||||
for spt in server_profile_template_list:
|
||||
self.assertIsInstance(spt, models.ServerProfileTemplate)
|
||||
|
||||
@mock.patch.object(requests, 'get', autospec=True)
|
||||
def test_server_profile_template_get(self, mock_get, mock__authenticate):
|
||||
oneview_client = client.Client(self.manager_url,
|
||||
self.username,
|
||||
self.password)
|
||||
response = mock_get.return_value
|
||||
response.status_code = http_client.OK
|
||||
response.json = mock.MagicMock(
|
||||
return_value=fixtures.SERVER_PROFILE_TEMPLATE_JSON
|
||||
)
|
||||
mock_get.return_value = response
|
||||
|
||||
spt = oneview_client._server_profile_template.get('aaaa-bbbb-cccc')
|
||||
mock_get.assert_called_once_with(
|
||||
url='https://1.2.3.4/rest/server-profile-templates/aaaa-bbbb-cccc',
|
||||
headers=mock.ANY,
|
||||
verify=True
|
||||
)
|
||||
self.assertIsInstance(spt, models.ServerProfileTemplate)
|
||||
|
||||
@mock.patch.object(requests, 'get', autospec=True)
|
||||
def test_server_profile_template_get_not_found(self, mock_get,
|
||||
mock__authenticate):
|
||||
oneview_client = client.Client(self.manager_url,
|
||||
self.username,
|
||||
self.password)
|
||||
response = mock_get.return_value
|
||||
response.status_code = http_client.NOT_FOUND
|
||||
mock_get.return_value = response
|
||||
|
||||
self.assertRaises(
|
||||
exceptions.OneViewResourceNotFoundError,
|
||||
oneview_client._server_profile_template.get,
|
||||
'aaaa-bbbb-cccc'
|
||||
)
|
||||
|
||||
def test_server_profile_template_create(self, mock__authenticate):
|
||||
oneview_client = client.Client(self.manager_url,
|
||||
self.username,
|
||||
self.password)
|
||||
self.assertRaises(
|
||||
NotImplementedError,
|
||||
oneview_client._server_profile_template.create,
|
||||
name='something',
|
||||
description='somethingelse',
|
||||
something=0
|
||||
)
|
||||
|
||||
def test_server_profile_template_delete(self, mock__authenticate):
|
||||
oneview_client = client.Client(self.manager_url,
|
||||
self.username,
|
||||
self.password)
|
||||
self.assertRaises(
|
||||
NotImplementedError,
|
||||
oneview_client._server_profile_template.delete,
|
||||
'aaaa-bbbb-cccc'
|
||||
)
|
||||
|
||||
@mock.patch.object(requests, 'get', autospec=True)
|
||||
def test_server_profile_list(self, mock_get, mock__authenticate):
|
||||
oneview_client = client.Client(self.manager_url,
|
||||
self.username,
|
||||
self.password)
|
||||
response = mock_get.return_value
|
||||
response.status_code = http_client.OK
|
||||
response.json = mock.MagicMock(
|
||||
return_value=fixtures.SERVER_PROFILE_LIST_JSON
|
||||
)
|
||||
mock_get.return_value = response
|
||||
|
||||
server_profile_list = oneview_client._server_profile.list()
|
||||
mock_get.assert_called_once_with(
|
||||
url='https://1.2.3.4/rest/server-profiles/',
|
||||
headers=mock.ANY,
|
||||
verify=True
|
||||
)
|
||||
for sp in server_profile_list:
|
||||
self.assertIsInstance(sp, models.ServerProfile)
|
||||
|
||||
@mock.patch.object(requests, 'get', autospec=True)
|
||||
def test_server_profile_get(self, mock_get, mock__authenticate):
|
||||
oneview_client = client.Client(self.manager_url,
|
||||
self.username,
|
||||
self.password)
|
||||
response = mock_get.return_value
|
||||
response.status_code = http_client.OK
|
||||
response.json = mock.MagicMock(
|
||||
return_value=fixtures.SERVER_PROFILE_JSON
|
||||
)
|
||||
mock_get.return_value = response
|
||||
|
||||
sp = oneview_client._server_profile.get('aaaa-bbbb-cccc')
|
||||
mock_get.assert_called_once_with(
|
||||
url='https://1.2.3.4/rest/server-profiles/aaaa-bbbb-cccc',
|
||||
headers=mock.ANY,
|
||||
verify=True
|
||||
)
|
||||
self.assertIsInstance(sp, models.ServerProfile)
|
||||
|
||||
@mock.patch.object(requests, 'get', autospec=True)
|
||||
def test_server_profile_get_not_found(self, mock_get, mock__authenticate):
|
||||
oneview_client = client.Client(self.manager_url,
|
||||
self.username,
|
||||
self.password)
|
||||
response = mock_get.return_value
|
||||
response.status_code = http_client.NOT_FOUND
|
||||
mock_get.return_value = response
|
||||
|
||||
self.assertRaises(
|
||||
exceptions.OneViewResourceNotFoundError,
|
||||
oneview_client._server_profile.get,
|
||||
'aaaa-bbbb-cccc'
|
||||
)
|
||||
|
||||
def test_server_profile_create(self, mock__authenticate):
|
||||
oneview_client = client.Client(self.manager_url,
|
||||
self.username,
|
||||
self.password)
|
||||
self.assertRaises(
|
||||
NotImplementedError,
|
||||
oneview_client._server_profile.create,
|
||||
name='something',
|
||||
description='somethingelse',
|
||||
something=0
|
||||
)
|
||||
|
||||
def test_server_profile_delete(self, mock__authenticate):
|
||||
oneview_client = client.Client(self.manager_url,
|
||||
self.username,
|
||||
self.password)
|
||||
self.assertRaises(
|
||||
NotImplementedError,
|
||||
oneview_client._server_profile.delete,
|
||||
'aaaa-bbbb-cccc'
|
||||
)
|
||||
|
||||
|
||||
@mock.patch.object(client.ClientV2, '_authenticate', autospec=True)
|
||||
class OneViewClientV2TestCase(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(OneViewClientV2TestCase, self).setUp()
|
||||
self.manager_url = 'https://1.2.3.4'
|
||||
self.username = 'user'
|
||||
self.password = 'password'
|
||||
|
||||
@mock.patch.object(requests, 'get', autospec=True)
|
||||
def test_server_hardware_list(self, mock_get, mock__authenticate):
|
||||
oneview_client = client.ClientV2(self.manager_url,
|
||||
self.username,
|
||||
self.password)
|
||||
response = mock_get.return_value
|
||||
response.status_code = http_client.OK
|
||||
response.json = mock.MagicMock(
|
||||
return_value=fixtures.SERVER_HARDWARE_LIST_JSON
|
||||
)
|
||||
mock_get.return_value = response
|
||||
|
||||
server_hardware_list = oneview_client.server_hardware.list()
|
||||
mock_get.assert_called_once_with(
|
||||
url='https://1.2.3.4/rest/server-hardware/',
|
||||
headers=mock.ANY,
|
||||
verify=True
|
||||
)
|
||||
for sh in server_hardware_list:
|
||||
self.assertIsInstance(sh, models.ServerHardware)
|
||||
|
||||
@mock.patch.object(requests, 'get', autospec=True)
|
||||
def test_server_hardware_index_list(self, mock_get, mock__authenticate):
|
||||
oneview_client = client.ClientV2(self.manager_url,
|
||||
self.username,
|
||||
self.password)
|
||||
response = mock_get.return_value
|
||||
response.status_code = http_client.OK
|
||||
response.json = mock.MagicMock(
|
||||
return_value=fixtures.INDEX_SERVER_HARDWARE_LIST_JSON
|
||||
)
|
||||
mock_get.return_value = response
|
||||
|
||||
server_hardware_list = oneview_client.server_hardware_index.list()
|
||||
mock_get.assert_called_once_with(
|
||||
url='https://1.2.3.4/rest/index/resources?' +
|
||||
'category=server-hardware',
|
||||
headers=mock.ANY,
|
||||
verify=True
|
||||
)
|
||||
for sh in server_hardware_list:
|
||||
self.assertIsInstance(sh, models.ServerHardware)
|
||||
|
||||
@mock.patch.object(requests, 'get', autospec=True)
|
||||
def test_server_hardware_get(self, mock_get, mock__authenticate):
|
||||
oneview_client = client.ClientV2(self.manager_url,
|
||||
self.username,
|
||||
self.password)
|
||||
response = mock_get.return_value
|
||||
response.status_code = http_client.OK
|
||||
response.json = mock.MagicMock(
|
||||
return_value=fixtures.SERVER_HARDWARE_JSON
|
||||
)
|
||||
mock_get.return_value = response
|
||||
|
||||
sh = oneview_client.server_hardware.get('aaaa-bbbb-cccc')
|
||||
mock_get.assert_called_once_with(
|
||||
url='https://1.2.3.4/rest/server-hardware/aaaa-bbbb-cccc',
|
||||
headers=mock.ANY,
|
||||
verify=True
|
||||
)
|
||||
self.assertIsInstance(sh, models.ServerHardware)
|
||||
|
||||
@mock.patch.object(requests, 'get', autospec=True)
|
||||
def test_server_hardware_index_get(self, mock_get, mock__authenticate):
|
||||
oneview_client = client.ClientV2(self.manager_url,
|
||||
self.username,
|
||||
self.password)
|
||||
response = mock_get.return_value
|
||||
response.status_code = http_client.OK
|
||||
response.json = mock.MagicMock(
|
||||
return_value=fixtures.INDEX_SERVER_HARDWARE_JSON
|
||||
)
|
||||
mock_get.return_value = response
|
||||
|
||||
sh = oneview_client.server_hardware_index.get('aaaa-bbbb-cccc')
|
||||
mock_get.assert_called_once_with(
|
||||
url='https://1.2.3.4/rest/index/resources?' +
|
||||
'category=server-hardware&filter=uuid:aaaa-bbbb-cccc',
|
||||
headers=mock.ANY,
|
||||
verify=True
|
||||
)
|
||||
self.assertIsInstance(sh, models.ServerHardware)
|
||||
|
||||
@mock.patch.object(requests, 'get', autospec=True)
|
||||
def test_server_hardware_get_not_found(self, mock_get, mock__authenticate):
|
||||
oneview_client = client.ClientV2(self.manager_url,
|
||||
self.username,
|
||||
self.password)
|
||||
response = mock_get.return_value
|
||||
response.status_code = http_client.NOT_FOUND
|
||||
mock_get.return_value = response
|
||||
|
||||
self.assertRaises(
|
||||
exceptions.OneViewResourceNotFoundError,
|
||||
oneview_client.server_hardware.get,
|
||||
'aaaa-bbbb-cccc'
|
||||
)
|
||||
|
||||
@mock.patch.object(requests, 'get', autospec=True)
|
||||
def test_server_hardware_index_get_not_found(self, mock_get,
|
||||
mock__authenticate):
|
||||
oneview_client = client.ClientV2(self.manager_url,
|
||||
self.username,
|
||||
self.password)
|
||||
response = mock_get.return_value
|
||||
response.status_code = http_client.NOT_FOUND
|
||||
mock_get.return_value = response
|
||||
|
||||
self.assertRaises(
|
||||
exceptions.OneViewResourceNotFoundError,
|
||||
oneview_client.server_hardware_index.get,
|
||||
'aaaa-bbbb-cccc'
|
||||
)
|
||||
|
||||
def test_server_hardware_create(self, mock__authenticate):
|
||||
oneview_client = client.ClientV2(self.manager_url,
|
||||
self.username,
|
||||
self.password)
|
||||
self.assertRaises(
|
||||
NotImplementedError,
|
||||
oneview_client.server_hardware.create,
|
||||
name='something',
|
||||
description='somethingelse',
|
||||
something=0
|
||||
)
|
||||
|
||||
def test_server_hardware_delete(self, mock__authenticate):
|
||||
oneview_client = client.ClientV2(self.manager_url,
|
||||
self.username,
|
||||
self.password)
|
||||
self.assertRaises(
|
||||
NotImplementedError,
|
||||
oneview_client.server_hardware.delete,
|
||||
'aaaa-bbbb-cccc'
|
||||
)
|
||||
|
||||
##########################################################
|
||||
@mock.patch.object(requests, 'get', autospec=True)
|
||||
def test_server_profile_template_list(self, mock_get, mock__authenticate):
|
||||
oneview_client = client.ClientV2(self.manager_url,
|
||||
self.username,
|
||||
self.password)
|
||||
response = mock_get.return_value
|
||||
response.status_code = http_client.OK
|
||||
response.json = mock.MagicMock(
|
||||
return_value=fixtures.SERVER_PROFILE_TEMPLATE_LIST_JSON
|
||||
)
|
||||
mock_get.return_value = response
|
||||
|
||||
server_profile_template_list = (
|
||||
oneview_client.server_profile_template.list()
|
||||
)
|
||||
mock_get.assert_called_once_with(
|
||||
url='https://1.2.3.4/rest/server-profile-templates/',
|
||||
headers=mock.ANY,
|
||||
verify=True
|
||||
)
|
||||
for spt in server_profile_template_list:
|
||||
self.assertIsInstance(spt, models.ServerProfileTemplate)
|
||||
|
||||
@mock.patch.object(requests, 'get', autospec=True)
|
||||
def test_server_profile_template_get(self, mock_get, mock__authenticate):
|
||||
oneview_client = client.ClientV2(self.manager_url,
|
||||
self.username,
|
||||
self.password)
|
||||
response = mock_get.return_value
|
||||
response.status_code = http_client.OK
|
||||
response.json = mock.MagicMock(
|
||||
return_value=fixtures.SERVER_PROFILE_TEMPLATE_JSON
|
||||
)
|
||||
mock_get.return_value = response
|
||||
|
||||
spt = oneview_client.server_profile_template.get('aaaa-bbbb-cccc')
|
||||
mock_get.assert_called_once_with(
|
||||
url='https://1.2.3.4/rest/server-profile-templates/aaaa-bbbb-cccc',
|
||||
headers=mock.ANY,
|
||||
verify=True
|
||||
)
|
||||
self.assertIsInstance(spt, models.ServerProfileTemplate)
|
||||
|
||||
@mock.patch.object(requests, 'get', autospec=True)
|
||||
def test_server_profile_template_get_not_found(self, mock_get,
|
||||
mock__authenticate):
|
||||
oneview_client = client.ClientV2(self.manager_url,
|
||||
self.username,
|
||||
self.password)
|
||||
response = mock_get.return_value
|
||||
response.status_code = http_client.NOT_FOUND
|
||||
mock_get.return_value = response
|
||||
|
||||
self.assertRaises(
|
||||
exceptions.OneViewResourceNotFoundError,
|
||||
oneview_client.server_profile_template.get,
|
||||
'aaaa-bbbb-cccc'
|
||||
)
|
||||
|
||||
def test_server_profile_template_create(self, mock__authenticate):
|
||||
oneview_client = client.ClientV2(self.manager_url,
|
||||
self.username,
|
||||
self.password)
|
||||
self.assertRaises(
|
||||
NotImplementedError,
|
||||
oneview_client.server_profile_template.create,
|
||||
name='something',
|
||||
description='somethingelse',
|
||||
something=0
|
||||
)
|
||||
|
||||
def test_server_profile_template_delete(self, mock__authenticate):
|
||||
oneview_client = client.ClientV2(self.manager_url,
|
||||
self.username,
|
||||
self.password)
|
||||
self.assertRaises(
|
||||
NotImplementedError,
|
||||
oneview_client.server_profile_template.delete,
|
||||
'aaaa-bbbb-cccc'
|
||||
)
|
||||
|
||||
@mock.patch.object(requests, 'get', autospec=True)
|
||||
def test_server_profile_list(self, mock_get, mock__authenticate):
|
||||
oneview_client = client.ClientV2(self.manager_url,
|
||||
self.username,
|
||||
self.password)
|
||||
response = mock_get.return_value
|
||||
response.status_code = http_client.OK
|
||||
response.json = mock.MagicMock(
|
||||
return_value=fixtures.SERVER_PROFILE_LIST_JSON
|
||||
)
|
||||
mock_get.return_value = response
|
||||
|
||||
server_profile_list = oneview_client.server_profile.list()
|
||||
mock_get.assert_called_once_with(
|
||||
url='https://1.2.3.4/rest/server-profiles/',
|
||||
headers=mock.ANY,
|
||||
verify=True
|
||||
)
|
||||
for sp in server_profile_list:
|
||||
self.assertIsInstance(sp, models.ServerProfile)
|
||||
|
||||
@mock.patch.object(requests, 'get', autospec=True)
|
||||
def test_server_profile_get(self, mock_get, mock__authenticate):
|
||||
oneview_client = client.ClientV2(self.manager_url,
|
||||
self.username,
|
||||
self.password)
|
||||
response = mock_get.return_value
|
||||
response.status_code = http_client.OK
|
||||
response.json = mock.MagicMock(
|
||||
return_value=fixtures.SERVER_PROFILE_JSON
|
||||
)
|
||||
mock_get.return_value = response
|
||||
|
||||
sp = oneview_client.server_profile.get('aaaa-bbbb-cccc')
|
||||
mock_get.assert_called_once_with(
|
||||
url='https://1.2.3.4/rest/server-profiles/aaaa-bbbb-cccc',
|
||||
headers=mock.ANY,
|
||||
verify=True
|
||||
)
|
||||
self.assertIsInstance(sp, models.ServerProfile)
|
||||
|
||||
@mock.patch.object(requests, 'get', autospec=True)
|
||||
def test_server_profile_get_not_found(self, mock_get, mock__authenticate):
|
||||
oneview_client = client.ClientV2(self.manager_url,
|
||||
self.username,
|
||||
self.password)
|
||||
response = mock_get.return_value
|
||||
response.status_code = http_client.NOT_FOUND
|
||||
mock_get.return_value = response
|
||||
|
||||
self.assertRaises(
|
||||
exceptions.OneViewResourceNotFoundError,
|
||||
oneview_client.server_profile.get,
|
||||
'aaaa-bbbb-cccc'
|
||||
)
|
||||
|
||||
def test_server_profile_create(self, mock__authenticate):
|
||||
oneview_client = client.ClientV2(self.manager_url,
|
||||
self.username,
|
||||
self.password)
|
||||
self.assertRaises(
|
||||
NotImplementedError,
|
||||
oneview_client.server_profile.create,
|
||||
name='something',
|
||||
description='somethingelse',
|
||||
something=0
|
||||
)
|
||||
|
||||
def test_server_profile_delete(self, mock__authenticate):
|
||||
oneview_client = client.ClientV2(self.manager_url,
|
||||
self.username,
|
||||
self.password)
|
||||
self.assertRaises(
|
||||
NotImplementedError,
|
||||
oneview_client.server_profile.delete,
|
||||
'aaaa-bbbb-cccc'
|
||||
)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
74
oneview_client/tests/unit/test_managers.py
Normal file
74
oneview_client/tests/unit/test_managers.py
Normal file
@ -0,0 +1,74 @@
|
||||
# -*- encoding: utf-8 -*-
|
||||
#
|
||||
# (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 mock
|
||||
import unittest
|
||||
|
||||
from oneview_client import client
|
||||
from oneview_client import managers
|
||||
from oneview_client import models
|
||||
from oneview_client.tests import fixtures
|
||||
|
||||
|
||||
class TestServerHardwareManager(unittest.TestCase):
|
||||
|
||||
def test_get(self):
|
||||
pass
|
||||
|
||||
|
||||
class TestServerHardwareIndexManager(unittest.TestCase):
|
||||
|
||||
@mock.patch.object(client, "ClientV2", autospec=True)
|
||||
def test_list(self, mock_client):
|
||||
oneview_client = mock_client(manager_url='https://something',
|
||||
username='user',
|
||||
password='pass')
|
||||
oneview_client._prepare_and_do_request.return_value = (
|
||||
fixtures.INDEX_SERVER_HARDWARE_LIST_JSON
|
||||
)
|
||||
index_manager = managers.ServerHardwareIndexManager(oneview_client)
|
||||
objects = index_manager.list()
|
||||
oneview_client._prepare_and_do_request.assert_called_once_with(
|
||||
uri=managers.ServerHardwareIndexManager.uri_index
|
||||
)
|
||||
for obj in objects:
|
||||
self.assertIsInstance(obj, models.ServerHardware)
|
||||
|
||||
@mock.patch.object(client, "ClientV2", autospec=True)
|
||||
def test_get(self, mock_client):
|
||||
uuid = "37333036-3831-584D-5131-303030323038"
|
||||
oneview_client = mock_client(manager_url='https://something',
|
||||
username='user',
|
||||
password='pass')
|
||||
json = fixtures.INDEX_SERVER_HARDWARE_JSON
|
||||
|
||||
json['members'] = [m for m in json['members']
|
||||
if m.get('uri').endswith(uuid)]
|
||||
|
||||
oneview_client._prepare_and_do_request.return_value = json
|
||||
|
||||
index_manager = managers.ServerHardwareIndexManager(oneview_client)
|
||||
obj = index_manager.get(uuid)
|
||||
oneview_client._prepare_and_do_request.assert_called_once_with(
|
||||
uri=managers.ServerHardwareIndexManager.uri_index +
|
||||
"&filter=uuid:" + uuid
|
||||
)
|
||||
self.assertIsInstance(obj, models.ServerHardware)
|
||||
self.assertEqual(
|
||||
obj.uri,
|
||||
"/rest/server-hardware/" + uuid
|
||||
)
|
@ -30,17 +30,23 @@ class Test(unittest.TestCase):
|
||||
def test_enclosuregroup_from_json(self):
|
||||
json = {
|
||||
'uri': 'http://something.com/1111-2222-3333-4444',
|
||||
'uuid': '1111-2222-3333-4444',
|
||||
'name': 'my-enclosure-group',
|
||||
'enclosureTypeUri': 'something1',
|
||||
'status': 'something2',
|
||||
}
|
||||
eg = EnclosureGroup.from_json(json)
|
||||
enclosure_group_attribute_map = {
|
||||
'uri': 'uri',
|
||||
'uuid': 'uuid',
|
||||
'name': 'name',
|
||||
'enclosureTypeUri': 'enclosure_type_uri',
|
||||
'status': 'status',
|
||||
}
|
||||
self.assertEqual(eg.attribute_map, enclosure_group_attribute_map)
|
||||
self.assertEqual(eg.uri, 'http://something.com/1111-2222-3333-4444')
|
||||
self.assertEqual(eg.uuid, '1111-2222-3333-4444')
|
||||
self.assertEqual(eg.name, 'my-enclosure-group')
|
||||
self.assertEqual(eg.enclosure_type_uri, 'something1')
|
||||
|
||||
def test_enclosure_from_json(self):
|
||||
@ -66,18 +72,25 @@ class Test(unittest.TestCase):
|
||||
def test_serverhardwaretype_from_json(self):
|
||||
json = {
|
||||
'uri': 'http://something.com/1111-2222-3333-4444',
|
||||
'uuid': 'aaaa-bbbb-cccc',
|
||||
'name': 'my-server-hardware-type'
|
||||
}
|
||||
sht = ServerHardwareType.from_json(json)
|
||||
sht_attribute_map = {
|
||||
'uri': 'uri',
|
||||
'uuid': 'uuid',
|
||||
'name': 'name'
|
||||
}
|
||||
self.assertEqual(sht.attribute_map, sht_attribute_map)
|
||||
self.assertEqual(sht.uri, 'http://something.com/1111-2222-3333-4444')
|
||||
self.assertEqual(sht.uuid, 'aaaa-bbbb-cccc')
|
||||
self.assertEqual(sht.name, 'my-server-hardware-type')
|
||||
|
||||
def test_serverhardware_from_json(self):
|
||||
json = {
|
||||
'uri': 'http://something.com/1111-2222-3333-4444',
|
||||
'uuid': '1111-2222-3333-4444',
|
||||
'name': 'my-server-profile',
|
||||
'powerState': 'Powered On',
|
||||
'serverProfileUri': 'something1',
|
||||
'serverHardwareTypeUri': 'something2',
|
||||
@ -100,6 +113,7 @@ class Test(unittest.TestCase):
|
||||
sh_attribute_map = {
|
||||
'uri': 'uri',
|
||||
'uuid': 'uuid',
|
||||
'name': 'name',
|
||||
'powerState': 'power_state',
|
||||
'serverProfileUri': 'server_profile_uri',
|
||||
'serverHardwareTypeUri': 'server_hardware_type_uri',
|
||||
@ -116,6 +130,7 @@ class Test(unittest.TestCase):
|
||||
self.assertEqual(sh.attribute_map, sh_attribute_map)
|
||||
self.assertEqual(sh.uri, 'http://something.com/1111-2222-3333-4444')
|
||||
self.assertEqual(sh.uuid, '1111-2222-3333-4444')
|
||||
self.assertEqual(sh.name, 'my-server-profile')
|
||||
self.assertEqual(sh.power_state, 'Powered On')
|
||||
self.assertEqual(sh.state_reason, 'something5')
|
||||
self.assertDictContainsSubset(
|
||||
@ -130,12 +145,15 @@ class Test(unittest.TestCase):
|
||||
def test_serverprofiletemplate_from_json(self):
|
||||
json = {
|
||||
'uri': 'http://something.com/1111-2222-3333-4444',
|
||||
'name': 'my-server-profile-template',
|
||||
'serverHardwareTypeUri': 'something1',
|
||||
'enclosureGroupUri': 'something2',
|
||||
}
|
||||
spt = ServerProfileTemplate.from_json(json)
|
||||
spt_attribute_map = {
|
||||
'uri': 'uri',
|
||||
'uuid': 'uuid',
|
||||
'name': 'name',
|
||||
'serverHardwareTypeUri': 'server_hardware_type_uri',
|
||||
'enclosureGroupUri': 'enclosure_group_uri',
|
||||
'boot': 'boot',
|
||||
|
@ -392,10 +392,13 @@ class OneViewClientTestCase(unittest.TestCase):
|
||||
@mock.patch.object(client.Client, '_prepare_and_do_request', autospec=True)
|
||||
def test_get_server_hardware_by_uuid(self, mock__prepare_do_request):
|
||||
mock__prepare_do_request.return_value = {
|
||||
"uri": "/rest/server-hardware/555"
|
||||
"uri": "/rest/server-hardware/555",
|
||||
"processorCoreCount": 5,
|
||||
"processorCount": 2,
|
||||
}
|
||||
uuid = 555
|
||||
self.oneview_client.get_server_hardware_by_uuid(uuid)
|
||||
sh = self.oneview_client.get_server_hardware_by_uuid(uuid)
|
||||
self.assertEqual(sh.cpus, 10)
|
||||
mock__prepare_do_request.assert_called_once_with(
|
||||
self.oneview_client, uri="/rest/server-hardware/555"
|
||||
)
|
||||
|
19
oneview_client/utils.py
Normal file
19
oneview_client/utils.py
Normal file
@ -0,0 +1,19 @@
|
||||
# (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.
|
||||
|
||||
|
||||
def get_uuid_from_uri(uri):
|
||||
if uri:
|
||||
return uri.split("/")[-1]
|
Loading…
x
Reference in New Issue
Block a user