diff --git a/CHANGELOG.md b/CHANGELOG.md index 51da18a50..5a8c04b90 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +# 5.1.0 (unreleased version) +#### Notes +Extends support of the SDK to OneView REST API version 800, 1000 and 1200. + +#### Features supported +- Hypervisor Managers + # 5.0.0 #### Notes Extends support of the SDK to OneView REST API version 1200 (OneView v5.00). diff --git a/endpoints-support.md b/endpoints-support.md index acd44db36..f81dad0a2 100755 --- a/endpoints-support.md +++ b/endpoints-support.md @@ -73,6 +73,12 @@ |/rest/fcoe-networks/{id} | PATCH | :heavy_minus_sign: | :heavy_minus_sign: | :heavy_minus_sign: | |/rest/fcoe-networks/{id} | PUT | :white_check_mark: | :white_check_mark: | :white_check_mark: | |/rest/fcoe-networks/{id} | DELETE | :white_check_mark: | :white_check_mark: | :white_check_mark: | +| **Hypervisor Managers** +|/rest/hypervisor-managers |POST | :white_check_mark: | :white_check_mark: | :white_check_mark: | +|/rest/hypervisor-managers |GET | :white_check_mark: | :white_check_mark: | :white_check_mark: | +|/rest/hypervisor-managers/{id} |GET | :white_check_mark: | :white_check_mark: | :white_check_mark: | +|/rest/hypervisor-managers/{id} |PUT | :white_check_mark: | :white_check_mark: | :white_check_mark: | +|/rest/hypervisor-managers/{id} |DELETE | :white_check_mark: | :white_check_mark: | :white_check_mark: | | **Interconnects** |/rest/interconnects | GET | :white_check_mark: | :white_check_mark: | :white_check_mark: | |/rest/interconnects/{id} | GET | :white_check_mark: | :white_check_mark: | :white_check_mark: | @@ -307,7 +313,6 @@ |/rest/storage-volumes/{id}/snapshots/{snapshotId} | GET | :white_check_mark: | :white_check_mark: | :white_check_mark: | |/rest/storage-volumes/{id}/snapshots/{snapshotId} | DELETE | :white_check_mark: | :white_check_mark: | :white_check_mark: | - ## HPE Synergy Image Streamer | Endpoints | Verb | V800 | V1000 | V1020 diff --git a/examples/hypervisor_managers.py b/examples/hypervisor_managers.py new file mode 100644 index 000000000..9e827d578 --- /dev/null +++ b/examples/hypervisor_managers.py @@ -0,0 +1,93 @@ +# -*- coding: utf-8 -*- +### +# (C) Copyright [2020] Hewlett Packard Enterprise Development LP +# +# 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. +### + +from pprint import pprint + +from config_loader import try_load_from_file +from hpOneView.oneview_client import OneViewClient + +config = { + "ip": "", + "credentials": { + "userName": "", + "password": "" + } +} + +options = { + "type": "HypervisorManagerV2", + "name": "172.18.13.11", + "displayName": "vcenter", + "hypervisorType": "Vmware", + "username": "dcs", + "password": "dcs", + "initialScopeUris": [] +} + +# Try load config from a file (if there is a config file) +config = try_load_from_file(config) +oneview_client = OneViewClient.config() +hypervisor_managers = oneview_client.hypervisor_managers + +# Find recently created hypervisor manager by name +print("\nGet Hypervisor Manager by name") +hypervisor_manager = hypervisor_managers.get_by_name(options['name']) + +if hypervisor_manager: + print("\nFound hypervisor-manager by name: {}.\n uri = {}".format(hypervisor_manager.data['name'], hypervisor_manager.data['uri'])) +else: + # Create a HypervisorManager with the options provided + hypervisor_manager = hypervisor_managers.create(data=options) + print("\nCreated a hypervisor-manager with name: {}.\n uri = {}".format(hypervisor_manager.data['name'], hypervisor_manager.data['uri'])) + +# Get all, with defaults +print("\nGet all hypervisor managers") +hyp_managers_all = hypervisor_managers.get_all() +for hyp in hyp_managers_all: + print(' - {}'.format(hyp['name'])) + +# Get the first 10 records +print("\nGet the first ten hypervisor managers") +hyp_mgrs_top_ten = hypervisor_managers.get_all(0, 10) +for hyp in hyp_mgrs_top_ten: + print(' - {}'.format(hyp['name'])) + +# Filter by hypervisor type +print("\nGet all hypervisor managers filtering by hypervisor type") +hyp_mgrs_filtered = hypervisor_managers.get_all(filter="\"'hypervisorType'='Vmware'\"") +for hyp in hyp_mgrs_filtered: + print("Hypervisor with type 'Vmware' - {}".format(hyp['name'])) + +# Get all sorting by name descending +print("\nGet all hypervisor managers sorting by name") +hyp_mgrs_sorted = hypervisor_managers.get_all(sort='name:descending') +pprint(hyp_mgrs_sorted) + +# Get by uri +print("\nGet a hypervisor managers by uri") +hyp_mgrs_by_uri = hypervisor_managers.get_by_uri(hypervisor_manager.data['uri']) +pprint(hyp_mgrs_by_uri.data) + +# Update display name of recently created hypervisor manager +data_to_update = {'displayName': 'Updated vcenter'} +hypervisor_manager.update(data=data_to_update) +print("\nUpdated hypervisor manager {} successfully.\n uri = {}".format(hypervisor_manager.data['name'], hypervisor_manager.data['uri'])) +print(" with attribute 'displayName': {}".format(hypervisor_manager.data['displayName'])) + +# Delete the created hypervisor manager +hypervisor_manager.delete() +print("\nSuccessfully deleted hypervisor manager") diff --git a/hpOneView/connection.py b/hpOneView/connection.py index 9f8bb6127..e9eb3cf75 100644 --- a/hpOneView/connection.py +++ b/hpOneView/connection.py @@ -640,7 +640,11 @@ def disable_etag_validation(self): # ------------------------------------ # Uncategorized # ------------------------------------ - 'unmanaged-devices': '/rest/unmanaged-devices' + 'unmanaged-devices': '/rest/unmanaged-devices', + # ------------------------------------ + # Hypervisors + # ------------------------------------ + 'hypervisor-managers': '/rest/hypervisor-managers' } ############################################################################ diff --git a/hpOneView/oneview_client.py b/hpOneView/oneview_client.py index ab8c64a58..163b39830 100755 --- a/hpOneView/oneview_client.py +++ b/hpOneView/oneview_client.py @@ -107,6 +107,7 @@ from hpOneView.resources.settings.appliance_node_information import ApplianceNodeInformation from hpOneView.resources.settings.appliance_time_and_locale_configuration import ApplianceTimeAndLocaleConfiguration from hpOneView.resources.settings.versions import Versions +from hpOneView.resources.hypervisors.hypervisor_managers import HypervisorManagers ONEVIEW_CLIENT_INVALID_PROXY = 'Invalid Proxy format' @@ -198,6 +199,7 @@ def __init__(self, config): self.__backups = None self.__login_details = None self.__licenses = None + self.__hypervisor_managers = None @classmethod def from_json_file(cls, file_name): @@ -1171,3 +1173,13 @@ def licenses(self): if not self.__licenses: self.__licenses = Licenses(self.__connection) return self.__licenses + + @property + def hypervisor_managers(self): + """ + Gets the Hypervisor Managers API client. + + Returns: + HypervisorManagers + """ + return HypervisorManagers(self.__connection) diff --git a/hpOneView/resources/hypervisors/__init__.py b/hpOneView/resources/hypervisors/__init__.py new file mode 100755 index 000000000..e69de29bb diff --git a/hpOneView/resources/hypervisors/hypervisor_managers.py b/hpOneView/resources/hypervisors/hypervisor_managers.py new file mode 100755 index 000000000..a653e22b1 --- /dev/null +++ b/hpOneView/resources/hypervisors/hypervisor_managers.py @@ -0,0 +1,75 @@ +# -*- coding: utf-8 -*- +### +# (C) Copyright [2020] Hewlett Packard Enterprise Development LP +# +# 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. +### + +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function +from __future__ import unicode_literals +from future import standard_library + +standard_library.install_aliases() + + +from hpOneView.resources.resource import Resource + + +class HypervisorManagers(Resource): + """ + Hypervisor Managers API client. + + """ + URI = '/rest/hypervisor-managers' + + DEFAULT_VALUES = { + '800': {"type": "HypervisorManagerV2"}, + '1000': {"type": "HypervisorManagerV2"}, + '1200': {"type": "HypervisorManagerV2"} + } + + def __init__(self, connection, data=None): + super(HypervisorManagers, self).__init__(connection, data) + + def get_all(self, start=0, count=-1, filter='', sort='', query='', scope_uris=''): + """ + Gets a list of Hypervisor Managers based on optional sorting and filtering, and constrained by start and count + parameters. + + Args: + start: + The first item to return, using 0-based indexing. + If not specified, the default is 0 - start with the first available item. + count: + The number of resources to return. A count of -1 requests all items. + The actual number of items in the response might differ from the requested + count if the sum of start and count exceeds the total number of items. + filter (list or str): + A general filter/query string to narrow the list of items returned. The + default is no filter; all resources are returned. + sort: + The sort order of the returned data set. By default, the sort order is based + on create time with the oldest entry first. + query: + A general query string to narrow the list of resources returned. The default + is no query - all resources are returned. + scope_uris: + An expression to restrict the resources returned according to the scopes to + which they are assigned. + + Returns: + list: List of Hypervisor Managers + """ + return self._helper.get_all(start, count, filter=filter, sort=sort, query=query, scope_uris=scope_uris) diff --git a/tests/unit/resources/hypervisors/__init__.py b/tests/unit/resources/hypervisors/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/tests/unit/resources/hypervisors/test_hypervisor_managers.py b/tests/unit/resources/hypervisors/test_hypervisor_managers.py new file mode 100644 index 000000000..7380c13b4 --- /dev/null +++ b/tests/unit/resources/hypervisors/test_hypervisor_managers.py @@ -0,0 +1,137 @@ +# -*- coding: utf-8 -*- +### +# (C) Copyright [2020] Hewlett Packard Enterprise Development LP +# +# 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. +### + +from unittest import TestCase + +import mock + +from hpOneView.connection import connection +from hpOneView.resources.hypervisors.hypervisor_managers import HypervisorManagers +from hpOneView.resources.resource import Resource, ResourceHelper + + +class HypervisorManagersTest(TestCase): + + def setUp(self): + self.host = '127.0.0.1' + self.connection = connection(self.host) + self._hypervisor_managers = HypervisorManagers(self.connection) + self.uri = "/rest/hypervisor-managers/f0a0a113-ec97-41b4-83ce-d7c92b900e7c" + self._hypervisor_managers.data = {"uri": self.uri} + + @mock.patch.object(Resource, 'create') + def test_create_called_once(self, mock_create): + resource = dict( + type="HypervisorManagerV2", + name="172.18.13.11", + displayName="vcenter", + hypervisorType="Vmware", + username="dcs", + password="dcs", + initialScopeUris=[], + ) + + resource_rest_call = resource.copy() + mock_create.return_value = {} + + self._hypervisor_managers.create(resource, timeout=70) + mock_create.assert_called_once_with(resource_rest_call, timeout=70) + + @mock.patch.object(Resource, 'create') + def test_add_called_once_with_defaults(self, mock_create): + resource = dict( + type="HypervisorManagerV2", + name="172.18.13.11", + displayName="vcenter", + hypervisorType="Vmware", + username="dcs", + password="dcs", + initialScopeUris=[], + ) + + resource_rest_call = resource.copy() + mock_create.return_value = {} + + self._hypervisor_managers.create(resource) + mock_create.assert_called_once_with(resource_rest_call) + + @mock.patch.object(ResourceHelper, 'get_all') + def test_get_all_called_once(self, mock_get_all): + filter = 'name=TestName' + sort = 'name:ascending' + query = 'query' + scope_uris = 'rest/scopes/cd237b60-09e2-45c4-829e-082e318a6d2a' + + self._hypervisor_managers.get_all(2, 500, filter=filter, sort=sort, query=query, scope_uris=scope_uris) + mock_get_all.assert_called_once_with(2, 500, filter=filter, sort=sort, query=query, scope_uris=scope_uris) + + @mock.patch.object(ResourceHelper, 'get_all') + def test_get_all_called_once_with_default(self, mock_get_all): + self._hypervisor_managers.get_all() + mock_get_all.assert_called_once_with(0, -1, filter='', sort='', query='', scope_uris='') + + @mock.patch.object(Resource, 'get_by_uri') + def test_get_by_uri_called_once(self, mock_get_by_uri): + uri = "/rest/hypervisor-managers/f0a0a113-ec97-41b4-83ce-d7c92b900e7c" + self._hypervisor_managers.get_by_uri(uri) + mock_get_by_uri.assert_called_once_with(uri) + + @mock.patch.object(Resource, 'get_by') + def test_get_by_called_once(self, mock_get_by): + hypervisor_managers = [{'name': 'name1', 'displayName': 'display1'}, {'name': 'name2', 'displayName': 'display2'}] + mock_get_by.return_value = hypervisor_managers + result = self._hypervisor_managers.get_by("displayName", "display1") + mock_get_by.assert_called_once_with("displayName", "display1") + self.assertEqual(result, hypervisor_managers) + + @mock.patch.object(Resource, 'get_by') + def test_get_by_name_called_once(self, mock_get_by): + hypervisor_managers = [{'name': 'test name1', 'id': 1}, {'name': 'test name2', 'id': 2}] + mock_get_by.return_value = hypervisor_managers + result = self._hypervisor_managers.get_by_name("test name1") + mock_get_by.assert_called_once_with("name", "test name1") + self.assertEqual(result.data['id'], 1) + + @mock.patch.object(Resource, 'ensure_resource_data') + @mock.patch.object(ResourceHelper, 'update') + def test_update_called_once_with_default(self, mock_update, mock_ensure_client): + resource = { + "name": "HypervisorManagerNew", + "uri": self.uri + } + self._hypervisor_managers.update(resource) + mock_update.assert_called_once_with(resource, self.uri, False, -1, None) + + @mock.patch.object(Resource, 'ensure_resource_data') + @mock.patch.object(ResourceHelper, 'update') + def test_update_called_once(self, mock_update, mock_ensure_client): + resource = { + "uri": self.uri, + "name": "NewHypervisorManager" + } + self._hypervisor_managers.update(resource, 70) + mock_update.assert_called_once_with(resource, self.uri, False, 70, None) + + @mock.patch.object(ResourceHelper, 'delete') + def test_delete_called_once(self, mock_delete): + self._hypervisor_managers.delete(force=False) + mock_delete.assert_called_once_with(self.uri, custom_headers=None, force=False, timeout=-1) + + @mock.patch.object(ResourceHelper, 'delete') + def test_delete_called_once_with_force(self, mock_delete): + self._hypervisor_managers.delete(force=True) + mock_delete.assert_called_once_with(self.uri, custom_headers=None, force=True, timeout=-1) diff --git a/tests/unit/test_oneview_client.py b/tests/unit/test_oneview_client.py index 5428ab603..8799573be 100755 --- a/tests/unit/test_oneview_client.py +++ b/tests/unit/test_oneview_client.py @@ -79,6 +79,7 @@ from hpOneView.resources.settings.versions import Versions from tests.test_utils import mock_builtin from hpOneView.resources.settings.licenses import Licenses +from hpOneView.resources.hypervisors.hypervisor_managers import HypervisorManagers OS_ENVIRON_CONFIG_MINIMAL = { 'ONEVIEWSDK_IP': '172.16.100.199', @@ -922,3 +923,10 @@ def test_should_get_appliance_current_version_and_minimum_version(self): def test_lazy_loading_appliance_version_information(self): versions = self._oneview.versions self.assertEqual(versions, self._oneview.versions) + + def test_hypervisor_managers_has_right_type(self): + self.assertIsInstance(self._oneview.hypervisor_managers, HypervisorManagers) + + def test_lazy_loading_hypervisor_managers(self): + hypervisor_managers = self._oneview.hypervisor_managers + self.assertNotEqual(hypervisor_managers, self._oneview.hypervisor_managers)