From eb2e6af3fd9665f68ebe70b97b67d650de0075b3 Mon Sep 17 00:00:00 2001 From: VenkateshRavula Date: Mon, 28 Jun 2021 18:05:40 +0530 Subject: [PATCH 1/9] refactored appliance node info --- .github/workflows/run_tests.yml | 25 +++++++------------ examples/appliance_node_information.py | 12 ++++----- hpeOneView/oneview_client.py | 8 ++---- .../settings/appliance_node_information.py | 14 +++++------ .../test_appliance_node_information.py | 8 +++--- tests/unit/test_oneview_client.py | 9 +++---- 6 files changed, 32 insertions(+), 44 deletions(-) diff --git a/.github/workflows/run_tests.yml b/.github/workflows/run_tests.yml index 524bd3088..029c34020 100644 --- a/.github/workflows/run_tests.yml +++ b/.github/workflows/run_tests.yml @@ -52,22 +52,15 @@ jobs: - name: Run tox tests run: tox -# - name: Deploy to GitHub Pages -# if: success() -# uses: crazy-max/ghaction-github-pages@v2 -# with: -# target_branch: gh-pages -# keep_history: true -# build_dir: docs/build/html/. -# env: -# GH_PAT: ${{ secrets.ONEVIEW_DEPLOY_TOKEN }} - - - name: Deploy to GitHub pages - uses: peaceiris/actions-gh-pages@v3 - with: - github_token: ${{ secrets.GITHUB_TOKEN }} - publish_dir: docs/build/html/. - keep_files: true + - name: Deploy to GitHub Pages + if: success() + uses: crazy-max/ghaction-github-pages@v2 + with: + target_branch: gh-pages + keep_history: true + build_dir: docs/build/html/. + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: coveralls uses: AndreMiras/coveralls-python-action@develop diff --git a/examples/appliance_node_information.py b/examples/appliance_node_information.py index 3e347b666..92080bdb6 100644 --- a/examples/appliance_node_information.py +++ b/examples/appliance_node_information.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- ### -# (C) Copyright [2019] Hewlett Packard Enterprise Development LP +# (C) Copyright [2021] 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. @@ -29,15 +29,15 @@ # Try load config from a file (if there is a config file) config = try_load_from_file(config) - oneview_client = OneViewClient(config) +app_node_info = oneview_client.appliance_node_information # Get node status information from appliance print("\nGet node status information from appliance:\n ") -node_status = oneview_client.appliance_node_information.get_status() -pprint(node_status) +node_status = app_node_info.get_status() +pprint(node_status.data) # Get node version information from appliance print("\nGet node version information from appliance\n") -node_version = oneview_client.appliance_node_information.get_version() -pprint(node_version) +node_version = app_node_info.get_version() +pprint(node_version.data) diff --git a/hpeOneView/oneview_client.py b/hpeOneView/oneview_client.py index 9d1ea6ed8..6ba91644d 100755 --- a/hpeOneView/oneview_client.py +++ b/hpeOneView/oneview_client.py @@ -1094,9 +1094,7 @@ def appliance_device_snmp_v3_users(self): Returns: ApplianceDeviceSNMPv3Users: """ - if not self.__appliance_device_snmp_v3_users: - self.__appliance_device_snmp_v3_users = ApplianceDeviceSNMPv3Users(self.__connection) - return self.__appliance_device_snmp_v3_users + return ApplianceDeviceSNMPv3Users(self.__connection) @property def appliance_node_information(self): @@ -1106,9 +1104,7 @@ def appliance_node_information(self): Returns: ApplianceNodeInformation: """ - if not self.__appliance_node_information: - self.__appliance_node_information = ApplianceNodeInformation(self.__connection) - return self.__appliance_node_information + return ApplianceNodeInformation(self.__connection) @property def appliance_time_and_locale_configuration(self): diff --git a/hpeOneView/resources/settings/appliance_node_information.py b/hpeOneView/resources/settings/appliance_node_information.py index 8d85bf88e..67afbc4a2 100644 --- a/hpeOneView/resources/settings/appliance_node_information.py +++ b/hpeOneView/resources/settings/appliance_node_information.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- ### -# (C) Copyright [2019] Hewlett Packard Enterprise Development LP +# (C) Copyright [2021] 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. @@ -24,18 +24,18 @@ standard_library.install_aliases() -from hpeOneView.resources.resource import ResourceClient +from hpeOneView.resources.resource import Resource -class ApplianceNodeInformation(object): +class ApplianceNodeInformation(Resource): """ ApplianceNodeInformation API client. """ URI = '/rest/appliance/nodeinfo' - def __init__(self, con): - self._client = ResourceClient(con, self.URI) + def __init__(self, connection, data=None): + super(ApplianceNodeInformation, self).__init__(connection, data) def get_status(self): """ @@ -45,7 +45,7 @@ def get_status(self): dict: Node's status information """ uri = self.URI + '/status' - return self._client.get(uri) + return super(ApplianceNodeInformation, self).get_by_uri(uri) def get_version(self): """ @@ -55,4 +55,4 @@ def get_version(self): dict: Node's version information """ uri = self.URI + '/version' - return self._client.get(uri) + return super(ApplianceNodeInformation, self).get_by_uri(uri) diff --git a/tests/unit/resources/settings/test_appliance_node_information.py b/tests/unit/resources/settings/test_appliance_node_information.py index ddd232c1c..beb2e1ed9 100644 --- a/tests/unit/resources/settings/test_appliance_node_information.py +++ b/tests/unit/resources/settings/test_appliance_node_information.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- ### -# (C) Copyright [2020] Hewlett Packard Enterprise Development LP +# (C) Copyright [2021] 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. @@ -21,7 +21,7 @@ from hpeOneView.connection import connection from hpeOneView.resources.settings.appliance_node_information import ApplianceNodeInformation -from hpeOneView.resources.resource import ResourceClient +from hpeOneView.resources.resource import Resource class ApplianceTimeAndLocaleConfigurationTest(unittest.TestCase): @@ -30,12 +30,12 @@ def setUp(self): self.connection = connection(self.host, 800) self._node_information = ApplianceNodeInformation(self.connection) - @mock.patch.object(ResourceClient, 'get') + @mock.patch.object(Resource, 'get_by_uri') def test_get_status_called_once(self, mock_get): self._node_information.get_status() mock_get.assert_called_once_with('/rest/appliance/nodeinfo/status') - @mock.patch.object(ResourceClient, 'get') + @mock.patch.object(Resource, 'get_by_uri') def test_get_version_called_once(self, mock_get): self._node_information.get_version() mock_get.assert_called_once_with('/rest/appliance/nodeinfo/version') diff --git a/tests/unit/test_oneview_client.py b/tests/unit/test_oneview_client.py index f86c2cd5c..cf29e9124 100755 --- a/tests/unit/test_oneview_client.py +++ b/tests/unit/test_oneview_client.py @@ -931,17 +931,16 @@ def test_appliance_device_device_snmp_v3_users_has_right_type(self): self.assertIsInstance(self._oneview.appliance_device_snmp_v3_users, ApplianceDeviceSNMPv3Users) - def test_lazy_loading_appliance_device_device_snmp_v3_users(self): + def test_appliance_device_device_snmp_v3_users(self): appliance_device_snmp_v3_users = self._oneview.appliance_device_snmp_v3_users - self.assertEqual(appliance_device_snmp_v3_users, self._oneview.appliance_device_snmp_v3_users) + self.assertNotEqual(appliance_device_snmp_v3_users, self._oneview.appliance_device_snmp_v3_users) def test_appliance_node_information_has_right_type(self): - self.assertIsInstance(self._oneview.appliance_node_information, - ApplianceNodeInformation) + self.assertIsInstance(self._oneview.appliance_node_information, ApplianceNodeInformation) def test_lazy_loading_appliance_node_information(self): appliance_node_information = self._oneview.appliance_node_information - self.assertEqual(appliance_node_information, self._oneview.appliance_node_information) + self.assertNotEqual(appliance_node_information, self._oneview.appliance_node_information) def test_appliance_time_and_locale_configuration_has_right_type(self): self.assertIsInstance(self._oneview.appliance_time_and_locale_configuration, From 046571e3a0732046b3aef57b23e5f58f722d7a94 Mon Sep 17 00:00:00 2001 From: VenkateshRavula Date: Mon, 28 Jun 2021 18:13:52 +0530 Subject: [PATCH 2/9] update changelog --- .github/workflows/run_tests.yml | 8 ++++---- CHANGELOG.md | 10 ++++++++++ endpoints-support.md | 7 +++++-- 3 files changed, 19 insertions(+), 6 deletions(-) diff --git a/.github/workflows/run_tests.yml b/.github/workflows/run_tests.yml index 029c34020..8c144911e 100644 --- a/.github/workflows/run_tests.yml +++ b/.github/workflows/run_tests.yml @@ -53,13 +53,13 @@ jobs: run: tox - name: Deploy to GitHub Pages - if: success() - uses: crazy-max/ghaction-github-pages@v2 - with: + if: success() + uses: crazy-max/ghaction-github-pages@v2 + with: target_branch: gh-pages keep_history: true build_dir: docs/build/html/. - env: + env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: coveralls diff --git a/CHANGELOG.md b/CHANGELOG.md index ae0b69b68..404fe804d 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,13 @@ +# 6.2.0(unreleased) +#### Notes +Extends support of the SDK to OneView REST API version 3000 (OneView v6.20) + +#### Bug fixes & Enhancements +- [#157] (https://github.com/HewlettPackard/oneview-python/issues/157) Add appliance ha-nodes endpoint to sdk + +#### Features supported +- Appliance Node Information + # 6.1.0 #### Notes Extends support of the SDK to OneView REST API version 2800 (OneView v6.10) and ImageStreamer REST API version 2020 (I3S v6.10). diff --git a/endpoints-support.md b/endpoints-support.md index ee313f170..78b1d48ed 100755 --- a/endpoints-support.md +++ b/endpoints-support.md @@ -18,10 +18,13 @@ ## HPE OneView -| Endpoints | Verb | V800 | V1000 | V1200 | V1600 | V1800 | V2000 | V2200 | V2400 | V2600 | V2800 | -| --------------------------------------------------------------------------------------- | ------------------ | :------------------: | :------------------:| :------------------: | :-----------------: | :-----------------: | :-----------------: | :-----------------: | :-----------------: | :-----------------: | :-----------------: | +| Endpoints | Verb | V800 | V1000 | V1200 | V1600 | V1800 | V2000 | V2200 | V2400 | V2600 | V2800 | V3000 | +| --------------------------------------------------------------------------------------- | ------------------ | :------------------: | :------------------:| :------------------: | :-----------------: | :-----------------: | :-----------------: | :-----------------: | :-----------------: | :-----------------: | :-----------------: | :-----------------: | | **Appliance Configuration Timeconfig** |/rest/appliance/configuration/timeconfig/locales |GET | :heavy_minus_sign: | :heavy_minus_sign: | :heavy_minus_sign: | :heavy_minus_sign: | :heavy_minus_sign: | :heavy_minus_sign: | :heavy_minus_sign: | :white_check_mark: | :white_check_mark: | :white_check_mark: | +| **Appliance Node Information** +|/rest/appliance/nodeinfo/status |GET | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | +|/rest/appliance/nodeinfo/version |GET | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | | **Appliance SNMPv1 Trap Destinations** |/rest/appliance/trap-destinations |GET | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | |/rest/appliance/trap-destinations/validation |POST | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | From ee647631f258318f96509bc060834ceee794e55b Mon Sep 17 00:00:00 2001 From: VenkateshRavula Date: Mon, 28 Jun 2021 18:38:04 +0530 Subject: [PATCH 3/9] added appliance health status resource --- CHANGELOG.md | 1 + endpoints-support.md | 2 + examples/appliance_health_status.py | 38 +++++++++++++++ hpeOneView/oneview_client.py | 12 +++++ .../settings/appliance_health_status.py | 47 +++++++++++++++++++ .../settings/test_appliance_health_status.py | 36 ++++++++++++++ .../test_appliance_node_information.py | 2 +- tests/unit/test_oneview_client.py | 10 +++- 8 files changed, 146 insertions(+), 2 deletions(-) create mode 100644 examples/appliance_health_status.py create mode 100644 hpeOneView/resources/settings/appliance_health_status.py create mode 100644 tests/unit/resources/settings/test_appliance_health_status.py diff --git a/CHANGELOG.md b/CHANGELOG.md index 404fe804d..b0191d3f7 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ Extends support of the SDK to OneView REST API version 3000 (OneView v6.20) #### Features supported - Appliance Node Information +- Appliance Health Status # 6.1.0 #### Notes diff --git a/endpoints-support.md b/endpoints-support.md index 78b1d48ed..478b3e8ef 100755 --- a/endpoints-support.md +++ b/endpoints-support.md @@ -25,6 +25,8 @@ | **Appliance Node Information** |/rest/appliance/nodeinfo/status |GET | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | |/rest/appliance/nodeinfo/version |GET | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | +| **Appliance Health-Status** +|/rest/appliance/health-status |GET | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | | **Appliance SNMPv1 Trap Destinations** |/rest/appliance/trap-destinations |GET | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | |/rest/appliance/trap-destinations/validation |POST | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | diff --git a/examples/appliance_health_status.py b/examples/appliance_health_status.py new file mode 100644 index 000000000..8894b8b38 --- /dev/null +++ b/examples/appliance_health_status.py @@ -0,0 +1,38 @@ +# -*- coding: utf-8 -*- +### +# (C) Copyright [2021] 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 hpeOneView.oneview_client import OneViewClient +from config_loader import try_load_from_file + +config = { + "ip": "", + "credentials": { + "userName": "", + "password": "" + } +} + +# Try load config from a file (if there is a config file) +config = try_load_from_file(config) +oneview_client = OneViewClient(config) +app_health = oneview_client.appliance_health_status + +# Get health status information from appliance +print("\nGet health status information from appliance:\n ") +health_status = app_health.get_health_status() +pprint(health_status.data) diff --git a/hpeOneView/oneview_client.py b/hpeOneView/oneview_client.py index 6ba91644d..67017d916 100755 --- a/hpeOneView/oneview_client.py +++ b/hpeOneView/oneview_client.py @@ -105,6 +105,7 @@ from hpeOneView.resources.settings.appliance_device_snmp_v3_trap_destinations import ApplianceDeviceSNMPv3TrapDestinations from hpeOneView.resources.settings.appliance_device_snmp_v3_users import ApplianceDeviceSNMPv3Users from hpeOneView.resources.settings.appliance_node_information import ApplianceNodeInformation +from hpeOneView.resources.settings.appliance_health_status import ApplianceHealthStatus from hpeOneView.resources.settings.appliance_time_and_locale_configuration import ApplianceTimeAndLocaleConfiguration from hpeOneView.resources.settings.versions import Versions from hpeOneView.resources.hypervisors.hypervisor_managers import HypervisorManagers @@ -201,6 +202,7 @@ def __init__(self, config): self.__appliance_device_snmp_v3_users = None self.__appliance_time_and_locale_configuration = None self.__appliance_node_information = None + self.__appliance_health_status = None self.__versions = None self.__backups = None self.__login_details = None @@ -1106,6 +1108,16 @@ def appliance_node_information(self): """ return ApplianceNodeInformation(self.__connection) + @property + def appliance_health_status(self): + """ + Gets the ApplianceHealthStatus API client. + + Returns: + ApplianceHealthStatus: + """ + return ApplianceHealthStatus(self.__connection) + @property def appliance_time_and_locale_configuration(self): """ diff --git a/hpeOneView/resources/settings/appliance_health_status.py b/hpeOneView/resources/settings/appliance_health_status.py new file mode 100644 index 000000000..8e82a758d --- /dev/null +++ b/hpeOneView/resources/settings/appliance_health_status.py @@ -0,0 +1,47 @@ +# -*- coding: utf-8 -*- +### +# (C) Copyright [2021] 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 hpeOneView.resources.resource import Resource + + +class ApplianceHealthStatus(Resource): + """ + ApplianceHealthStatus API client. + + """ + URI = '/rest/appliance/health-status' + + def __init__(self, connection, data=None): + super(ApplianceHealthStatus, self).__init__(connection, data) + + def get_health_status(self): + """ + Retrieves appliance health status + + Returns: + dict: appliance health status + """ + return super(ApplianceHealthStatus, self).get_by_uri(self.URI) diff --git a/tests/unit/resources/settings/test_appliance_health_status.py b/tests/unit/resources/settings/test_appliance_health_status.py new file mode 100644 index 000000000..65aa57b07 --- /dev/null +++ b/tests/unit/resources/settings/test_appliance_health_status.py @@ -0,0 +1,36 @@ +# -*- coding: utf-8 -*- +### +# (C) Copyright [2021] 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. +### + +import unittest + +import mock + +from hpeOneView.connection import connection +from hpeOneView.resources.settings.appliance_health_status import ApplianceHealthStatus +from hpeOneView.resources.resource import Resource + + +class ApplianceHealthStatusTest(unittest.TestCase): + def setUp(self): + self.host = '127.0.0.1' + self.connection = connection(self.host, 800) + self._health_status = ApplianceHealthStatus(self.connection) + + @mock.patch.object(Resource, 'get_by_uri') + def test_get_health_status_called_once(self, mock_get): + self._health_status.get_health_status() + mock_get.assert_called_once_with('/rest/appliance/health-status') diff --git a/tests/unit/resources/settings/test_appliance_node_information.py b/tests/unit/resources/settings/test_appliance_node_information.py index beb2e1ed9..99a1acbc1 100644 --- a/tests/unit/resources/settings/test_appliance_node_information.py +++ b/tests/unit/resources/settings/test_appliance_node_information.py @@ -24,7 +24,7 @@ from hpeOneView.resources.resource import Resource -class ApplianceTimeAndLocaleConfigurationTest(unittest.TestCase): +class ApplianceNodeInformationTest(unittest.TestCase): def setUp(self): self.host = '127.0.0.1' self.connection = connection(self.host, 800) diff --git a/tests/unit/test_oneview_client.py b/tests/unit/test_oneview_client.py index cf29e9124..a5969fbe0 100755 --- a/tests/unit/test_oneview_client.py +++ b/tests/unit/test_oneview_client.py @@ -76,6 +76,7 @@ from hpeOneView.resources.settings.appliance_device_snmp_v3_trap_destinations import ApplianceDeviceSNMPv3TrapDestinations from hpeOneView.resources.settings.appliance_device_snmp_v3_users import ApplianceDeviceSNMPv3Users from hpeOneView.resources.settings.appliance_node_information import ApplianceNodeInformation +from hpeOneView.resources.settings.appliance_health_status import ApplianceHealthStatus from hpeOneView.resources.settings.appliance_time_and_locale_configuration import ApplianceTimeAndLocaleConfiguration from hpeOneView.resources.settings.versions import Versions from tests.test_utils import mock_builtin @@ -938,10 +939,17 @@ def test_appliance_device_device_snmp_v3_users(self): def test_appliance_node_information_has_right_type(self): self.assertIsInstance(self._oneview.appliance_node_information, ApplianceNodeInformation) - def test_lazy_loading_appliance_node_information(self): + def test_appliance_node_information(self): appliance_node_information = self._oneview.appliance_node_information self.assertNotEqual(appliance_node_information, self._oneview.appliance_node_information) + def test_appliance_health_status_has_right_type(self): + self.assertIsInstance(self._oneview.appliance_health_status, ApplianceHealthStatus) + + def test_appliance_health_status(self): + appliance_health_status = self._oneview.appliance_health_status + self.assertNotEqual(appliance_health_status, self._oneview.appliance_health_status) + def test_appliance_time_and_locale_configuration_has_right_type(self): self.assertIsInstance(self._oneview.appliance_time_and_locale_configuration, ApplianceTimeAndLocaleConfiguration) From 14637d9eb750c11164764528882fb2d8ff3d56cb Mon Sep 17 00:00:00 2001 From: VenkateshRavula Date: Mon, 28 Jun 2021 20:05:05 +0530 Subject: [PATCH 4/9] added HA nodes resource --- CHANGELOG.md | 1 + endpoints-support.md | 6 ++ examples/ha_nodes.py | 59 ++++++++++++++ hpeOneView/oneview_client.py | 12 +++ .../settings/appliance_health_status.py | 2 +- .../settings/appliance_node_information.py | 3 +- hpeOneView/resources/settings/ha_nodes.py | 43 +++++++++++ .../unit/resources/settings/test_ha_nodes.py | 77 +++++++++++++++++++ 8 files changed, 201 insertions(+), 2 deletions(-) create mode 100644 examples/ha_nodes.py create mode 100644 hpeOneView/resources/settings/ha_nodes.py create mode 100644 tests/unit/resources/settings/test_ha_nodes.py diff --git a/CHANGELOG.md b/CHANGELOG.md index b0191d3f7..a1b4fd1e0 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ Extends support of the SDK to OneView REST API version 3000 (OneView v6.20) #### Features supported - Appliance Node Information - Appliance Health Status +- HA Nodes # 6.1.0 #### Notes diff --git a/endpoints-support.md b/endpoints-support.md index 478b3e8ef..97475101f 100755 --- a/endpoints-support.md +++ b/endpoints-support.md @@ -122,6 +122,12 @@ |/rest/firmware-drivers/schema | GET | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | |/rest/firmware-drivers/{id} | GET | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | |/rest/firmware-drivers/{id} | DELETE | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | +| **HA Nodes** +|/rest/appliance/ha-nodes |GET | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | +|/rest/appliance/ha-nodes/{id} |GET | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | +|/rest/appliance/ha-nodes/{id} |PUT | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | +|/rest/appliance/ha-nodes/{id} |PATCH | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | +|/rest/appliance/ha-nodes/{id} |DELETE | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | | **Hypervisor Cluster Profiles** |/rest/hypervisor-cluster-profiles |POST | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | |/rest/hypervisor-cluster-profiles |GET | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | diff --git a/examples/ha_nodes.py b/examples/ha_nodes.py new file mode 100644 index 000000000..ccd7309b2 --- /dev/null +++ b/examples/ha_nodes.py @@ -0,0 +1,59 @@ +# -*- coding: utf-8 -*- +### +# (C) Copyright [2021] 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 hpeOneView.oneview_client import OneViewClient +from config_loader import try_load_from_file + +config = { + "ip": "", + "credentials": { + "userName": "", + "password": "" + } +} + +# Try load config from a file (if there is a config file) +config = try_load_from_file(config) +oneview_client = OneViewClient(config) +ha_nodes = oneview_client.ha_nodes + +# Get all HA nodes from appliance +print("\nGet all HA nodes from appliance:\n ") +all_nodes = ha_nodes.get_all() +for node in all_nodes: + print(" - {}".format(node['name'])) + +# Get HA node by uri from appliance +print("\nGet HA node by uri from appliance\n") +node_by_uri = ha_nodes.get_by_uri(all_nodes[0]['uri']) +pprint(node_by_uri.data) + +# update description of HA node +data = {'description': 'updated node'} +ha_node = ha_nodes.update(data) +print("\n## Update HA node successfully!") +pprint(ha_node.data) + +# Patch update +print("\nUpdate the HA node using patch") +ha_node.patch(operation="replace", path="/role", value="Standby") +pprint(ha_node.data) + +# Delete HA node +ha_node.delete() +print("\n## Delete HA node successfully!") diff --git a/hpeOneView/oneview_client.py b/hpeOneView/oneview_client.py index 67017d916..ea0567d9f 100755 --- a/hpeOneView/oneview_client.py +++ b/hpeOneView/oneview_client.py @@ -106,6 +106,7 @@ from hpeOneView.resources.settings.appliance_device_snmp_v3_users import ApplianceDeviceSNMPv3Users from hpeOneView.resources.settings.appliance_node_information import ApplianceNodeInformation from hpeOneView.resources.settings.appliance_health_status import ApplianceHealthStatus +from hpeOneView.resources.settings.ha_nodes import HANodes from hpeOneView.resources.settings.appliance_time_and_locale_configuration import ApplianceTimeAndLocaleConfiguration from hpeOneView.resources.settings.versions import Versions from hpeOneView.resources.hypervisors.hypervisor_managers import HypervisorManagers @@ -211,6 +212,7 @@ def __init__(self, config): self.__certificates_server = None self.__appliance_configuration_timeconfig = None self.__appliance_ssh_access = None + self.__ha_nodes = None @classmethod def from_json_file(cls, file_name): @@ -1118,6 +1120,16 @@ def appliance_health_status(self): """ return ApplianceHealthStatus(self.__connection) + @property + def ha_nodes(self): + """ + Gets the HANodes API client. + + Returns: + HANodes: + """ + return HANodes(self.__connection) + @property def appliance_time_and_locale_configuration(self): """ diff --git a/hpeOneView/resources/settings/appliance_health_status.py b/hpeOneView/resources/settings/appliance_health_status.py index 8e82a758d..ad778644e 100644 --- a/hpeOneView/resources/settings/appliance_health_status.py +++ b/hpeOneView/resources/settings/appliance_health_status.py @@ -29,7 +29,7 @@ class ApplianceHealthStatus(Resource): """ - ApplianceHealthStatus API client. + Retrieves the health information from the appliance. """ URI = '/rest/appliance/health-status' diff --git a/hpeOneView/resources/settings/appliance_node_information.py b/hpeOneView/resources/settings/appliance_node_information.py index 67afbc4a2..c23f6b667 100644 --- a/hpeOneView/resources/settings/appliance_node_information.py +++ b/hpeOneView/resources/settings/appliance_node_information.py @@ -29,7 +29,8 @@ class ApplianceNodeInformation(Resource): """ - ApplianceNodeInformation API client. + The nodeinfo resource manager provides REST APIs to + retrieve information about the nodes of the appliance. """ URI = '/rest/appliance/nodeinfo' diff --git a/hpeOneView/resources/settings/ha_nodes.py b/hpeOneView/resources/settings/ha_nodes.py new file mode 100644 index 000000000..2c5a1bee4 --- /dev/null +++ b/hpeOneView/resources/settings/ha_nodes.py @@ -0,0 +1,43 @@ +# -*- coding: utf-8 -*- +### +# (C) Copyright [2021] 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 hpeOneView.resources.resource import Resource, ResourcePatchMixin, unavailable_method + + +class HANodes(Resource, ResourcePatchMixin): + """ + HA Nodes resources represent the individual members used to provide + high-availability for the management appliance cluster. + + """ + URI = '/rest/appliance/ha-nodes' + + def __init__(self, connection, data=None): + super(HANodes, self).__init__(connection, data) + + def create(self): + """Create method is not available""" + unavailable_method() diff --git a/tests/unit/resources/settings/test_ha_nodes.py b/tests/unit/resources/settings/test_ha_nodes.py new file mode 100644 index 000000000..aa9bd495a --- /dev/null +++ b/tests/unit/resources/settings/test_ha_nodes.py @@ -0,0 +1,77 @@ +# -*- coding: utf-8 -*- +### +# (C) Copyright [2021] 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. +### + +import unittest + +import mock + +from hpeOneView.connection import connection +from hpeOneView.resources.settings.ha_nodes import HANodes +from hpeOneView.resources.resource import Resource, ResourcePatchMixin, ResourceHelper + + +class HANodesTest(unittest.TestCase): + def setUp(self): + self.host = '127.0.0.1' + self.connection = connection(self.host, 800) + self.uri = "/rest/appliance/ha-nodes" + self._ha_nodes = HANodes(self.connection) + + @mock.patch.object(Resource, 'get_by_uri') + def test_get_ha_nodes_called_once(self, mock_get): + self._ha_nodes.get_by_uri() + mock_get.assert_called_once_with('/rest/appliance/ha-nodes') + + @mock.patch.object(Resource, 'get_all') + def test_get_all_called_once_with_default(self, mock_get_all): + self._ha_nodes.get_all() + mock_get_all.assert_called_once_with() + + @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": "enc101 appliance bay 1", + "oldUri": "/rest/appliance/ha-nodes/1", + "role": "Standby" + } + self._ha_nodes.update(resource) + mock_update.assert_called_once_with(resource, self.uri, False, -1, None) + + @mock.patch.object(ResourcePatchMixin, 'patch_request') + def test_patch_called_once(self, mock_patch): + uri = '/rest/appliance/ha-nodes/1' + + resource = { + "operation": "replace", "path": "/role", "value": "Standby" + } + self._ha_nodes.patch("replace", "/role", "Standby") + mock_patch.assert_called_once_with( + self.uri, body=[resource], custom_headers=None, timeout=-1) + + @mock.patch.object(ResourcePatchMixin, 'patch_request') + def test_patch(self, mock_pacth): + self._resource.patch("replace", "/templateCompliance", "Compliant") + mock_pacth.assert_called_once_with(self.uri, body=[{'path': '/templateCompliance', + 'op': 'replace', + 'value': 'Compliant'}], + custom_headers=None, timeout=-1) + + @mock.patch.object(Resource, 'delete') + def test_delete_called_once(self, mock_delete): + self._ha_nodes.delete() + mock_delete.assert_called_once_with() \ No newline at end of file From 21d007a2046e90aa6ae84eb5f84861b66e47052a Mon Sep 17 00:00:00 2001 From: VenkateshRavula Date: Mon, 28 Jun 2021 20:24:51 +0530 Subject: [PATCH 5/9] added UTs --- .../unit/resources/settings/test_ha_nodes.py | 30 ------------------- 1 file changed, 30 deletions(-) diff --git a/tests/unit/resources/settings/test_ha_nodes.py b/tests/unit/resources/settings/test_ha_nodes.py index aa9bd495a..d051b846c 100644 --- a/tests/unit/resources/settings/test_ha_nodes.py +++ b/tests/unit/resources/settings/test_ha_nodes.py @@ -41,36 +41,6 @@ def test_get_all_called_once_with_default(self, mock_get_all): self._ha_nodes.get_all() mock_get_all.assert_called_once_with() - @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": "enc101 appliance bay 1", - "oldUri": "/rest/appliance/ha-nodes/1", - "role": "Standby" - } - self._ha_nodes.update(resource) - mock_update.assert_called_once_with(resource, self.uri, False, -1, None) - - @mock.patch.object(ResourcePatchMixin, 'patch_request') - def test_patch_called_once(self, mock_patch): - uri = '/rest/appliance/ha-nodes/1' - - resource = { - "operation": "replace", "path": "/role", "value": "Standby" - } - self._ha_nodes.patch("replace", "/role", "Standby") - mock_patch.assert_called_once_with( - self.uri, body=[resource], custom_headers=None, timeout=-1) - - @mock.patch.object(ResourcePatchMixin, 'patch_request') - def test_patch(self, mock_pacth): - self._resource.patch("replace", "/templateCompliance", "Compliant") - mock_pacth.assert_called_once_with(self.uri, body=[{'path': '/templateCompliance', - 'op': 'replace', - 'value': 'Compliant'}], - custom_headers=None, timeout=-1) - @mock.patch.object(Resource, 'delete') def test_delete_called_once(self, mock_delete): self._ha_nodes.delete() From 33fe29159a11298f326bd217fa226453620a2997 Mon Sep 17 00:00:00 2001 From: VenkateshRavula Date: Mon, 28 Jun 2021 20:28:05 +0530 Subject: [PATCH 6/9] modify UTs --- tests/unit/resources/settings/test_ha_nodes.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/unit/resources/settings/test_ha_nodes.py b/tests/unit/resources/settings/test_ha_nodes.py index d051b846c..be68acd5e 100644 --- a/tests/unit/resources/settings/test_ha_nodes.py +++ b/tests/unit/resources/settings/test_ha_nodes.py @@ -33,7 +33,7 @@ def setUp(self): @mock.patch.object(Resource, 'get_by_uri') def test_get_ha_nodes_called_once(self, mock_get): - self._ha_nodes.get_by_uri() + self._ha_nodes.get_by_uri('/rest/appliance/ha-nodes') mock_get.assert_called_once_with('/rest/appliance/ha-nodes') @mock.patch.object(Resource, 'get_all') From f47edd4288c14d987626671c0ab5f3eb4e1fc066 Mon Sep 17 00:00:00 2001 From: VenkateshRavula Date: Mon, 28 Jun 2021 20:30:08 +0530 Subject: [PATCH 7/9] modify ha nodes UTs --- tests/unit/resources/settings/test_ha_nodes.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/unit/resources/settings/test_ha_nodes.py b/tests/unit/resources/settings/test_ha_nodes.py index be68acd5e..6b7a966b3 100644 --- a/tests/unit/resources/settings/test_ha_nodes.py +++ b/tests/unit/resources/settings/test_ha_nodes.py @@ -21,7 +21,7 @@ from hpeOneView.connection import connection from hpeOneView.resources.settings.ha_nodes import HANodes -from hpeOneView.resources.resource import Resource, ResourcePatchMixin, ResourceHelper +from hpeOneView.resources.resource import Resource class HANodesTest(unittest.TestCase): From 53d270753aeae25b9283ff338568660d3f85ca1f Mon Sep 17 00:00:00 2001 From: VenkateshRavula Date: Mon, 28 Jun 2021 20:32:31 +0530 Subject: [PATCH 8/9] fix flake errors --- tests/unit/resources/settings/test_ha_nodes.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/unit/resources/settings/test_ha_nodes.py b/tests/unit/resources/settings/test_ha_nodes.py index 6b7a966b3..184746f20 100644 --- a/tests/unit/resources/settings/test_ha_nodes.py +++ b/tests/unit/resources/settings/test_ha_nodes.py @@ -44,4 +44,4 @@ def test_get_all_called_once_with_default(self, mock_get_all): @mock.patch.object(Resource, 'delete') def test_delete_called_once(self, mock_delete): self._ha_nodes.delete() - mock_delete.assert_called_once_with() \ No newline at end of file + mock_delete.assert_called_once_with() From 95e8c7d3691b923d08845aa81ab8aa9f43944349 Mon Sep 17 00:00:00 2001 From: VenkateshRavula Date: Tue, 29 Jun 2021 14:09:15 +0530 Subject: [PATCH 9/9] modified ha node example --- examples/ha_nodes.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/examples/ha_nodes.py b/examples/ha_nodes.py index ccd7309b2..b4f14edc1 100644 --- a/examples/ha_nodes.py +++ b/examples/ha_nodes.py @@ -43,15 +43,15 @@ node_by_uri = ha_nodes.get_by_uri(all_nodes[0]['uri']) pprint(node_by_uri.data) -# update description of HA node -data = {'description': 'updated node'} -ha_node = ha_nodes.update(data) +# update role of HA node +data = {'role': 'Standby'} +ha_node = node_by_uri.update(data) print("\n## Update HA node successfully!") pprint(ha_node.data) -# Patch update +# Patch update role print("\nUpdate the HA node using patch") -ha_node.patch(operation="replace", path="/role", value="Standby") +ha_node.patch(operation="replace", path="/role", value="Active") pprint(ha_node.data) # Delete HA node