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:
Thiago Paiva 2016-03-01 16:49:09 -03:00 committed by Gabriel Bezerra
parent 85577a1b03
commit caa0e7a657
9 changed files with 7650 additions and 140 deletions

View File

@ -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
View 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.")

View File

@ -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',

File diff suppressed because it is too large Load Diff

View 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()

View 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
)

View File

@ -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',

View File

@ -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
View 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]