././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1631521193.3539517 sushy-oem-idrac-3.0.1/0000775000175000017500000000000000000000000014547 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1631521128.0 sushy-oem-idrac-3.0.1/.stestr.conf0000664000175000017500000000006600000000000017022 0ustar00zuulzuul00000000000000[DEFAULT] test_path=./sushy_oem_idrac/tests top_dir=. ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1631521193.0 sushy-oem-idrac-3.0.1/AUTHORS0000664000175000017500000000063300000000000015621 0ustar00zuulzuul00000000000000Aija Jauntēva Devendra Kulkarni Dhuldev Valekar DhuldevValekar3 Ilya Etingof Mahendra Kamble Riccardo Pittau Richard Pioso erbarr sonali bhausaheb borkar ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1631521128.0 sushy-oem-idrac-3.0.1/CONTRIBUTING.rst0000664000175000017500000000123100000000000017205 0ustar00zuulzuul00000000000000If you would like to contribute to the development of OpenStack, you must follow the steps in this page: http://docs.openstack.org/infra/manual/developers.html If you already have a good understanding of how the system works and your OpenStack accounts are set up, you can skip to the development workflow section of this documentation to learn how changes to OpenStack should be submitted for review via the Gerrit tool: http://docs.openstack.org/infra/manual/developers.html#development-workflow Pull requests submitted through GitHub will be ignored. Bugs should be filed in StoryBoard, not GitHub: https://storyboard.openstack.org/#!/project/960 ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1631521193.0 sushy-oem-idrac-3.0.1/ChangeLog0000664000175000017500000000446200000000000016327 0ustar00zuulzuul00000000000000CHANGES ======= 3.0.1 ----- * Exclude BOSS controllers in clear\_foreign\_config 3.0.0 ----- * Add OEM Task extension * Fix exposing system constants * Update default IncludeInExport value * Add RAID clear foreign config method * Fix IncludeInExport allowed value validation * Add RAID mode conversion methods * Update set\_virtual\_boot\_device for no manager * Increase version of hacking and pycodestyle * Add Flake8 W503 ignore * Enable coverage HTML output * Fix missing Target@Redfish.AllowableValues * Add Python3 Xena unit tests * setup.cfg: Replace dashes with underscores * Use TOX\_CONSTRAINTS\_FILE * Expose manager constants 2.1.0 ----- * Add reset iDRAC method * Update RETRY\_COUNT for virtual media boot * Update virtual media boot-related constants 2.0.0 ----- * Update export system configuration * Add import system configuration method * Update export system config class and constants * Add real-time status check to Lifecycle service * Add resources to put iDRAC in known good state * Add get PXE port MACs for BIOS mode * Add export system configuration * Remove lower constraints * Fix lower-constraints with the new pip resolver 1.0.0 ----- * Use safe version of hacking * Use wallaby CI tests * Fix GET HTTP 202 status without Location * Use victoria tests * Python 3 only * Add pep8 import order check * Switch to the new canonical constraints URL on master * Bump hacking to 3.0.0 * Drop support for Python 2.7 * Bump sushy requirements to 2.0.0+ * Add basic CI jobs and .gitreview * Summon Zuul * Reduce debug verbosity * Improve async call debugging * Reduce async task poll period * Remove autogenerated Changelog from git * Shorten Redfish task service poll period 0.0.2 ----- * Indicate package description is in markdown format 0.0.1 ----- * Rename package to \`sushy-oem-idrac\` * Rephrase package maturity status * Update README * Update unit test to match changed implementation * Align vmedia integration test with ironic behaviour * Support \`permanent\` option of \`set\_virtual\_boot\_device\` * Make ImportConfiguration functional * Rename reboot -> utils * Add missing test case * Add functional virtual media boot test * Add primitive Redfish task monitor * Progress with \`set\_virtual\_boot\_device\` action call * Accommodate changed sushy OEM architecture * Initial revision * Initial commit ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1631521128.0 sushy-oem-idrac-3.0.1/HACKING.rst0000664000175000017500000000020400000000000016341 0ustar00zuulzuul00000000000000Sushy Style Commandments ======================== Read the OpenStack Style Commandments https://docs.openstack.org/hacking/latest/ ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1631521128.0 sushy-oem-idrac-3.0.1/LICENSE0000664000175000017500000002363700000000000015567 0ustar00zuulzuul00000000000000 Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1631521193.3539517 sushy-oem-idrac-3.0.1/PKG-INFO0000664000175000017500000000502500000000000015646 0ustar00zuulzuul00000000000000Metadata-Version: 2.1 Name: sushy-oem-idrac Version: 3.0.1 Summary: Dell EMC iDRAC OEM extension package for the sushy library Home-page: https://docs.openstack.org/sushy/latest/ Author: OpenStack Author-email: openstack-discuss@lists.openstack.org License: UNKNOWN Description: Dell EMC OEM extension for sushy ================================ Sushy is a client [library](https://github.com/openstack/sushy) designed to communicate with [Redfish](https://en.wikipedia.org/wiki/Redfish_(specification)) based BMC. Redfish specification offers extensibility mechanism to let hardware vendors introduce their own features with the common Redfish framework. At the same time, `sushy` supports extending its data model by loading extensions found within its "oem" namespace. The `sushy-oem-idrac` package is a sushy extension package that aims at adding high-level hardware management abstractions, that are specific to Dell EMC BMC (which is known under the name of iDRAC), to the tree of sushy Redfish resources. Example use ----------- Once installed, sushy user can access Dell EMC OEM resources. For example, OEM extension of Manager resource can be instrumental for switching the node to boot from a virtual media device: ```python import sushy root = sushy.Sushy('http://mydellemcbmc.example.com') manager = root.get_manager('iDRAC.Embedded.1') oem_manager = manager.get_oem_extension('Dell') oem_manager.set_virtual_boot_device( sushy.VIRTUAL_MEDIA_CD, persistent=False, manager=manager) ``` See full example of virtual media boot setup in the [functional test suite](https://github.com/etingof/sushy-oem-idrac/blob/master/sushy_oem_idrac/tests/functional/vmedia_boot.py). Platform: UNKNOWN Classifier: Environment :: OpenStack Classifier: Intended Audience :: Information Technology Classifier: Intended Audience :: System Administrators Classifier: License :: OSI Approved :: Apache Software License Classifier: Operating System :: POSIX :: Linux Classifier: Programming Language :: Python Classifier: Programming Language :: Python :: 3 :: Only Classifier: Programming Language :: Python :: 3 Classifier: Programming Language :: Python :: 3.6 Classifier: Programming Language :: Python :: 3.7 Description-Content-Type: text/markdown ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1631521128.0 sushy-oem-idrac-3.0.1/README.md0000664000175000017500000000261200000000000016027 0ustar00zuulzuul00000000000000 Dell EMC OEM extension for sushy ================================ Sushy is a client [library](https://github.com/openstack/sushy) designed to communicate with [Redfish](https://en.wikipedia.org/wiki/Redfish_(specification)) based BMC. Redfish specification offers extensibility mechanism to let hardware vendors introduce their own features with the common Redfish framework. At the same time, `sushy` supports extending its data model by loading extensions found within its "oem" namespace. The `sushy-oem-idrac` package is a sushy extension package that aims at adding high-level hardware management abstractions, that are specific to Dell EMC BMC (which is known under the name of iDRAC), to the tree of sushy Redfish resources. Example use ----------- Once installed, sushy user can access Dell EMC OEM resources. For example, OEM extension of Manager resource can be instrumental for switching the node to boot from a virtual media device: ```python import sushy root = sushy.Sushy('http://mydellemcbmc.example.com') manager = root.get_manager('iDRAC.Embedded.1') oem_manager = manager.get_oem_extension('Dell') oem_manager.set_virtual_boot_device( sushy.VIRTUAL_MEDIA_CD, persistent=False, manager=manager) ``` See full example of virtual media boot setup in the [functional test suite](https://github.com/etingof/sushy-oem-idrac/blob/master/sushy_oem_idrac/tests/functional/vmedia_boot.py). ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1631521128.0 sushy-oem-idrac-3.0.1/babel.cfg0000664000175000017500000000002100000000000016266 0ustar00zuulzuul00000000000000[python: **.py] ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1631521128.0 sushy-oem-idrac-3.0.1/requirements.txt0000664000175000017500000000045300000000000020035 0ustar00zuulzuul00000000000000# The order of packages is significant, because pip processes them in the order # of appearance. Changing the order has an impact on the overall integration # process, which may cause wedges in the gate later. pbr!=2.1.0,>=2.0.0 # Apache-2.0 python-dateutil>=2.7.0 # BSD sushy>=3.11.0 # Apache-2.0 ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1631521193.3579519 sushy-oem-idrac-3.0.1/setup.cfg0000664000175000017500000000342200000000000016371 0ustar00zuulzuul00000000000000[metadata] name = sushy-oem-idrac summary = Dell EMC iDRAC OEM extension package for the sushy library description_file = README.md long_description_content_type = text/markdown author = OpenStack author_email = openstack-discuss@lists.openstack.org home_page = https://docs.openstack.org/sushy/latest/ classifier = Environment :: OpenStack Intended Audience :: Information Technology Intended Audience :: System Administrators License :: OSI Approved :: Apache Software License Operating System :: POSIX :: Linux Programming Language :: Python Programming Language :: Python :: 3 :: Only Programming Language :: Python :: 3 Programming Language :: Python :: 3.6 Programming Language :: Python :: 3.7 [files] packages = sushy_oem_idrac [entry_points] sushy.resources.manager.oems = dell = sushy_oem_idrac.resources.manager.manager:get_extension sushy.resources.system.oems = dell = sushy_oem_idrac.resources.system.system:get_extension sushy.resources.task.oems = dell = sushy_oem_idrac.resources.taskservice.task:get_extension [build_sphinx] source-dir = doc/source build-dir = doc/build all_files = 1 warning-is-error = 1 [upload_sphinx] upload-dir = doc/build/html [compile_catalog] directory = sushy_oem_idrac/locale domain = sushy_oem_idrac [update_catalog] domain = sushy_oem_idrac output_dir = sushy_oem_idrac/locale input_file = sushy_oem_idrac/locale/sushy_oem_idrac.pot [extract_messages] keywords = _ gettext ngettext l_ lazy_gettext mapping_file = babel.cfg output_file = sushy_oem_idrac/locale/sushy_oem_idrac.pot [build_releasenotes] all_files = 1 build-dir = releasenotes/build source-dir = releasenotes/source [pbr] autodoc_index_modules = True api_doc_dir = reference/api autodoc_exclude_modules = sushy_oem_idrac.tests.* [egg_info] tag_build = tag_date = 0 ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1631521128.0 sushy-oem-idrac-3.0.1/setup.py0000664000175000017500000000200600000000000016257 0ustar00zuulzuul00000000000000# Copyright (c) 2013 Hewlett-Packard Development Company, L.P. # # 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. # THIS FILE IS MANAGED BY THE GLOBAL REQUIREMENTS REPO - DO NOT EDIT import setuptools # In python < 2.7.4, a lazy loading of package `pbr` will break # setuptools if some other modules registered functions in `atexit`. # solution from: http://bugs.python.org/issue15881#msg170215 try: import multiprocessing # noqa except ImportError: pass setuptools.setup( setup_requires=['pbr>=2.0.0'], pbr=True) ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1631521193.3499517 sushy-oem-idrac-3.0.1/sushy_oem_idrac/0000775000175000017500000000000000000000000017724 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1631521128.0 sushy-oem-idrac-3.0.1/sushy_oem_idrac/__init__.py0000664000175000017500000000144000000000000022034 0ustar00zuulzuul00000000000000# Copyright (c) 2021 Dell Inc. or its subsidiaries. # # 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 sushy_oem_idrac.resources.manager.constants import * # noqa from sushy_oem_idrac.resources.system.constants import * # noqa from sushy_oem_idrac.resources.taskservice.constants import * # noqa ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1631521128.0 sushy-oem-idrac-3.0.1/sushy_oem_idrac/asynchronous.py0000664000175000017500000000504000000000000023030 0ustar00zuulzuul00000000000000# 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 datetime import datetime from datetime import timedelta import logging import time from dateutil import parser import sushy LOG = logging.getLogger(__name__) TASK_POLL_PERIOD = 1 def _to_datetime(retry_after_str): if retry_after_str.isdigit(): # Retry-After: 120 return datetime.now() + timedelta(seconds=int(retry_after_str)) else: # Retry-After: Fri, 31 Dec 1999 23:59:59 GMT return parser.parse(retry_after_str) def http_call(conn, method, *args, **kwargs): handle = getattr(conn, method.lower()) sleep_for = kwargs.pop('sushy_task_poll_period', TASK_POLL_PERIOD) response = handle(*args, **kwargs) LOG.debug('Finished HTTP %s with args %s %s, response is ' '%d', method, args or '', kwargs, response.status_code) location = None while response.status_code == 202: location = response.headers.get('Location', location) if not location: raise sushy.exceptions.ExtensionError( error='Response %d to HTTP %s with args %s, kwargs %s ' 'does not include Location: in ' 'header' % (response.status_code, method.upper(), args, kwargs)) retry_after = response.headers.get('Retry-After') if retry_after: retry_after = _to_datetime(retry_after) sleep_for = max(0, (retry_after - datetime.now()).total_seconds()) LOG.debug('Sleeping for %d secs before retrying HTTP GET ' '%s', sleep_for, location) time.sleep(sleep_for) response = conn.get(location) LOG.debug('Finished HTTP GET %s, response is ' '%d', location, response.status_code) if response.status_code >= 400: raise sushy.exceptions.ExtensionError( error='HTTP %s with args %s, kwargs %s failed ' 'with code %s' % (method.upper(), args, kwargs, response.status_code)) return response ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1631521128.0 sushy-oem-idrac-3.0.1/sushy_oem_idrac/constants.py0000664000175000017500000000126200000000000022313 0ustar00zuulzuul00000000000000# Copyright (c) 2021 Dell Inc. or its subsidiaries. # # 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. IDRAC_CONFIG_PENDING = 'LC068' IDRAC_JOB_RUNNING = 'RAC0679' NO_FOREIGN_CONFIG = 'STOR018' ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1631521193.3499517 sushy-oem-idrac-3.0.1/sushy_oem_idrac/resources/0000775000175000017500000000000000000000000021736 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1631521128.0 sushy-oem-idrac-3.0.1/sushy_oem_idrac/resources/__init__.py0000664000175000017500000000000000000000000024035 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1631521193.3499517 sushy-oem-idrac-3.0.1/sushy_oem_idrac/resources/manager/0000775000175000017500000000000000000000000023350 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1631521128.0 sushy-oem-idrac-3.0.1/sushy_oem_idrac/resources/manager/__init__.py0000664000175000017500000000000000000000000025447 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1631521128.0 sushy-oem-idrac-3.0.1/sushy_oem_idrac/resources/manager/constants.py0000664000175000017500000000716100000000000025743 0ustar00zuulzuul00000000000000# Copyright (c) 2020-2021 Dell Inc. or its subsidiaries. # # 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. # export system config action constants EXPORT_TARGET_ALL = 'all' """Export entire system configuration""" EXPORT_TARGET_BIOS = 'BIOS' """Export BIOS related configuration""" EXPORT_TARGET_IDRAC = 'iDRAC' """Export IDRAC related configuration""" EXPORT_TARGET_NIC = 'NIC' """Export NIC related configuration""" EXPORT_TARGET_RAID = 'RAID' """Export RAID related configuration""" # iDRAC Reset action constants RESET_IDRAC_GRACEFUL_RESTART = 'graceful restart' """Perform a graceful shutdown followed by a restart of the system""" RESET_IDRAC_FORCE_RESTART = 'force restart' """Perform an immediate (non-graceful) shutdown, followed by a restart""" # ImportSystemConfiguration ShutdownType values IMPORT_SHUTDOWN_GRACEFUL = 'graceful shutdown' """Graceful shutdown for Import System Configuration Will wait for the host up to 5 minutes to shut down before timing out. The operating system can potentially deny or ignore the graceful shutdown request. """ IMPORT_SHUTDOWN_FORCED = 'forced shutdown' """Forced shutdown for Import System Configuration The host server will be powered off immediately. Should be used when it is safe to power down the host. """ IMPORT_SHUTDOWN_NO_REBOOT = 'no shutdown' """No reboot for Import System Configuration No shutdown performed. Explicit reboot is necessary to apply changes. """ # ExportUse in ExportSystemConfiguration EXPORT_USE_DEFAULT = 'Default' """Default export type Leaves some attributes commented out and requires user to enable them before they can be applied during import. """ EXPORT_USE_CLONE = 'Clone' """Clone export type suitable for cloning a 'golden' configuration. Compared to Default export type, more attributes are enabled and storage settings adjusted to aid in cloning process. """ EXPORT_USE_REPLACE = 'Replace' """Replace export type suited for retiring or replacing complete configuration. Compared to Clone export type, most attributes are enabled and storage settings adjusted to aid in the replace process. """ # IncludeInExport in ExportSystemConfiguration INCLUDE_EXPORT_DEFAULT = 'Default' """Default for what to include in export. Does not include read-only attributes, and depending on Export Use, passwords are marked as ****** (for Default) or are set to default password values (for Clone and Replace). """ INCLUDE_EXPORT_READ_ONLY = 'Include read only attributes' """Includes read-only attributes. In addition to values included by Default option, this also includes read-only attributes that cannot be changed via Import and are provided for informational purposes only. """ INCLUDE_EXPORT_PASSWORD_HASHES = 'Include password hash values' """Include password hashes. When using Clone or Replace, include password hashes, instead of default password. Can be used to replicate passwords across systems. """ INCLUDE_EXPORT_READ_ONLY_PASSWORD_HASHES = ('Include read only attributes and ' 'password hash values') """Includes both read-only attributes and password hashes. INCLUDE_EXPORT_READ_ONLY and INCLUDE_EXPORT_PASSWORD_HASHES combined """ ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1631521128.0 sushy-oem-idrac-3.0.1/sushy_oem_idrac/resources/manager/idrac_card_service.py0000664000175000017500000000645100000000000027523 0ustar00zuulzuul00000000000000# Copyright (c) 2020-2021 Dell Inc. or its subsidiaries. # # 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 logging from sushy import exceptions from sushy.resources import base from sushy_oem_idrac.resources.manager import constants as mgr_cons from sushy_oem_idrac.resources.manager import mappings as mgr_maps LOG = logging.getLogger(__name__) class ForceActionField(base.CompositeField): target_uri = base.Field('target', required=True) allowed_values = base.Field('Force@Redfish.AllowableValues', adapter=list) class ActionsField(base.CompositeField): reset_idrac = ForceActionField('#DelliDRACCardService.iDRACReset') class DelliDRACCardService(base.ResourceBase): _actions = ActionsField('Actions') identity = base.Field('Id', required=True) def __init__(self, connector, identity, redfish_version=None, registries=None): """A class representing a DelliDRACCardService. :param connector: A Connector instance :param identity: The identity of the DelliDRACCardService resource :param redfish_version: The version of Redfish. Used to construct the object according to schema of the given version. :param registries: Dict of Redfish Message Registry objects to be used in any resource that needs registries to parse messages. """ super(DelliDRACCardService, self).__init__( connector, identity, redfish_version, registries) def get_allowed_reset_idrac_values(self): """Get the allowed values for resetting the idrac. :returns: A set of allowed values. """ reset_action = self._actions.reset_idrac if not reset_action.allowed_values: LOG.warning('Could not figure out the allowed values for the ' 'reset idrac action for %s', self.identity) return set(mgr_maps.RESET_IDRAC_VALUE_MAP_REV) return set([mgr_maps.RESET_IDRAC_VALUE_MAP[value] for value in set(mgr_maps.RESET_IDRAC_VALUE_MAP). intersection(reset_action.allowed_values)]) def reset_idrac(self): """Reset the iDRAC. """ reset_type = mgr_cons.RESET_IDRAC_GRACEFUL_RESTART valid_resets = self.get_allowed_reset_idrac_values() if reset_type not in valid_resets: raise exceptions.InvalidParameterValueError( parameter='value', value=reset_type, valid_values=valid_resets) reset_type = mgr_maps.RESET_IDRAC_VALUE_MAP_REV[reset_type] target_uri = self._actions.reset_idrac.target_uri payload = {"Force": reset_type} LOG.debug('Resetting the iDRAC %s ...', self.identity) self._conn.post(target_uri, data=payload) LOG.info('The iDRAC %s is being reset', self.identity) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1631521128.0 sushy-oem-idrac-3.0.1/sushy_oem_idrac/resources/manager/job_collection.py0000664000175000017500000000412700000000000026713 0ustar00zuulzuul00000000000000# Copyright (c) 2020-2021 Dell Inc. or its subsidiaries. # # 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 logging from sushy.resources import base LOG = logging.getLogger(__name__) class DellJobCollection(base.ResourceBase): identity = base.Field('Id', required=True) _JOB_EXPAND = '?$expand=.($levels=1)' def __init__(self, connector, identity, redfish_version=None, registries=None): """A class representing a DellJobCollection. :param connector: A Connector instance :param identity: The identity of the DellJobCollection resource :param redfish_version: The version of Redfish. Used to construct the object according to schema of the given version. :param registries: Dict of Redfish Message Registry objects to be used in any resource that needs registries to parse messages """ super(DellJobCollection, self).__init__( connector, identity, redfish_version, registries) def get_unfinished_jobs(self): """Get the unfinished jobs. :returns: A list of unfinished jobs. """ job_expand_uri = '%s%s' % (self._path, self._JOB_EXPAND) unfinished_jobs = [] LOG.debug('Getting unfinished jobs...') job_response = self._conn.get(job_expand_uri) data = job_response.json() for job in data[u'Members']: if ((job[u'JobState'] == 'Scheduled') or ( job[u'JobState'] == 'Running')): unfinished_jobs.append(job['Id']) LOG.info('Got unfinished jobs') return unfinished_jobs ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1631521128.0 sushy-oem-idrac-3.0.1/sushy_oem_idrac/resources/manager/job_service.py0000664000175000017500000000430700000000000026220 0ustar00zuulzuul00000000000000# Copyright (c) 2020-2021 Dell Inc. or its subsidiaries. # # 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 logging from sushy.resources import base from sushy.resources import common LOG = logging.getLogger(__name__) class ActionsField(base.CompositeField): delete_job_queue = common.ActionField("#DellJobService.DeleteJobQueue") class DellJobService(base.ResourceBase): _actions = ActionsField('Actions') identity = base.Field('Id', required=True) def __init__(self, connector, identity, redfish_version=None, registries=None): """A class representing a DellJobService. :param connector: A Connector instance :param identity: The identity of the DellJobService resource :param redfish_version: The version of Redfish. Used to construct the object according to schema of the given version. :param registries: Dict of Redfish Message Registry objects to be used in any resource that needs registries to parse messages. """ super(DellJobService, self).__init__( connector, identity, redfish_version, registries) def delete_jobs(self, job_ids=['JID_CLEARALL']): """Delete the given jobs, or all jobs. :param job_ids: a list of job ids to delete. Clearing all the jobs may be accomplished using the keyword JID_CLEARALL as the job_id. """ target_uri = self._actions.delete_job_queue.target_uri for job_id in job_ids: LOG.debug('Deleting the job %s', job_id) payload = {'JobID': job_id} self._conn.post(target_uri, data=payload) LOG.info('Deleted the job %s', job_id) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1631521128.0 sushy-oem-idrac-3.0.1/sushy_oem_idrac/resources/manager/lifecycle_service.py0000664000175000017500000000571600000000000027412 0ustar00zuulzuul00000000000000# Copyright (c) 2020-2021 Dell Inc. or its subsidiaries. # # 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 logging from sushy.resources import base from sushy.resources import common LOG = logging.getLogger(__name__) class ActionsField(base.CompositeField): remote_service_api_status = common.ActionField( "#DellLCService.GetRemoteServicesAPIStatus") class DellLCService(base.ResourceBase): _actions = ActionsField('Actions') _OK_STATUS_CODE = 200 _READY_STATUS = 'Ready' identity = base.Field('Id', required=True) def __init__(self, connector, identity, redfish_version=None, registries=None): """A class representing a DellLCService. :param connector: A Connector instance :param identity: The identity of the DellLCService resource :param redfish_version: The version of Redfish. Used to construct the object according to schema of the given version. :param registries: Dict of Redfish Message Registry objects to be used in any resource that needs registries to parse messages. """ super(DellLCService, self).__init__( connector, identity, redfish_version, registries) def _is_remote_service_api_status_ready(self, status_field): """Checks remote service status field :param status_field: Status field to check, e.g., LCStatus, RTStatus :returns: True if response returned and status field is Ready, otherwise False. """ target_uri = self._actions.remote_service_api_status.target_uri response = self._conn.post(target_uri, data={}) if response.status_code != self._OK_STATUS_CODE: return False data = response.json() return data[status_field] == self._READY_STATUS def is_idrac_ready(self): """Indicates if the iDRAC is ready to accept commands. :returns: A boolean value True/False based on remote service api status response. """ LOG.debug('Checking to see if the iDRAC is ready...') return self._is_remote_service_api_status_ready('LCStatus') def is_realtime_ready(self): """Indicates if real-time operations are ready to be accepted. :returns: True if ready to accept real-time operations, otherwise false. """ LOG.debug('Checking to see if the real-time operations are ready...') return self._is_remote_service_api_status_ready('RTStatus') ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1631521128.0 sushy-oem-idrac-3.0.1/sushy_oem_idrac/resources/manager/manager.py0000664000175000017500000006145100000000000025343 0ustar00zuulzuul00000000000000# Copyright (c) 2020-2021 Dell Inc. or its subsidiaries. # # 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 logging import subprocess import time from urllib.parse import urlparse import sushy from sushy.resources import base from sushy.resources import common from sushy.resources.oem import base as oem_base from sushy.taskmonitor import TaskMonitor from sushy import utils as sushy_utils from sushy_oem_idrac import asynchronous from sushy_oem_idrac import constants from sushy_oem_idrac.resources.manager import constants as mgr_cons from sushy_oem_idrac.resources.manager import idrac_card_service from sushy_oem_idrac.resources.manager import job_collection from sushy_oem_idrac.resources.manager import job_service from sushy_oem_idrac.resources.manager import lifecycle_service from sushy_oem_idrac.resources.manager import mappings as mgr_maps from sushy_oem_idrac import utils LOG = logging.getLogger(__name__) # System Configuration Tag Constant _SYSTEM_CONFIG_TAG = "SystemConfiguration" # Response Code Constant _RESPONSE_OK_CODE = 200 class SharedParameters(base.CompositeField): allowed_target_values = base.Field('Target@Redfish.AllowableValues') class ExportActionField(common.ActionField): shared_parameters = SharedParameters('ShareParameters') allowed_export_use_values = base.Field( 'ExportUse@Redfish.AllowableValues', adapter=list) allowed_include_in_export_values = base.Field( 'IncludeInExport@Redfish.AllowableValues', adapter=list) class ImportActionField(common.ActionField): allowed_shutdown_type_values = base.Field( 'ShutdownType@Redfish.AllowableValues', adapter=list) class DellManagerActionsField(base.CompositeField): import_system_configuration = ImportActionField( lambda key, **kwargs: key.endswith( '#OemManager.ImportSystemConfiguration')) export_system_configuration = ExportActionField( lambda key, **kwargs: key.endswith( '#OemManager.ExportSystemConfiguration')) class DellManagerExtension(oem_base.OEMResourceBase): _actions = DellManagerActionsField('Actions') ACTION_DATA = { 'ShareParameters': { 'Target': 'ALL' }, 'ImportBuffer': None } # NOTE(etingof): iDRAC job would fail if this XML has # insignificant whitespaces IDRAC_CONFIG_CD = """\ \ \ \ %s\ \ \ VCD-DVD\ \ \ \ """ IDRAC_CONFIG_FLOPPY = """\ \ \ \ %s\ \ \ VFDD\ \ \ \ """ IDRAC_MEDIA_TYPES = { sushy.VIRTUAL_MEDIA_FLOPPY: IDRAC_CONFIG_FLOPPY, sushy.VIRTUAL_MEDIA_CD: IDRAC_CONFIG_CD } RETRY_COUNT = 35 RETRY_DELAY = 15 _IDRAC_IS_READY_RETRIES = 96 _IDRAC_IS_READY_RETRY_DELAY_SEC = 10 @property def import_system_configuration_uri(self): return self._actions.import_system_configuration.target_uri @property def export_system_configuration_uri(self): return self._actions.export_system_configuration.target_uri @property @sushy_utils.cache_it def idrac_card_service(self): """Property to reference `DelliDRACCardService` instance of this manager. """ path = sushy_utils.get_sub_resource_path_by( self, ["Links", "Oem", "Dell", "DelliDRACCardService"], is_collection=False) return idrac_card_service.DelliDRACCardService( self._conn, path, self.redfish_version, self.registries) @property @sushy_utils.cache_it def lifecycle_service(self): """Property to reference `DellLCService` instance of this manager. """ path = sushy_utils.get_sub_resource_path_by( self, ["Links", "Oem", "Dell", "DellLCService"], is_collection=False) return lifecycle_service.DellLCService( self._conn, path, self.redfish_version, self.registries) @property @sushy_utils.cache_it def job_service(self): """Property to reference `DellJobService` instance of this manager. """ path = sushy_utils.get_sub_resource_path_by( self, ["Links", "Oem", "Dell", "DellJobService"], is_collection=False) return job_service.DellJobService( self._conn, path, self.redfish_version, self.registries) @property @sushy_utils.cache_it def job_collection(self): """Property to reference `DellJobService` instance of this manager. """ path = sushy_utils.get_sub_resource_path_by( self, ["Links", "Oem", "Dell", "Jobs"], is_collection=False) return job_collection.DellJobCollection( self._conn, path, self.redfish_version, self.registries) def set_virtual_boot_device(self, device, persistent=False, manager=None, system=None): """Set boot device for a node. Dell iDRAC Redfish implementation does not support setting boot device to virtual media via standard Redfish means. However, this still can be done via an OEM extension. :param device: Boot device. Values are vendor-specific. :param persistent: Whether to set next-boot, or make the change permanent. Default: False. :param manager: Manager of OEM extension. Optional. :param system: System of OEM extension. Optional. :raises: InvalidParameterValue if Dell OEM extension can't be used. :raises: ExtensionError on failure to perform requested operation. """ try: idrac_media = self.IDRAC_MEDIA_TYPES[device] except KeyError: raise sushy.exceptions.InvalidParameterValue( error='Unknown or unsupported device %s' % device) idrac_media = idrac_media % ( manager.identity if manager else self._parent_resource.identity, 'Disabled' if persistent else 'Enabled') action_data = dict(self.ACTION_DATA, ImportBuffer=idrac_media) # TODO(etingof): figure out if on-time or persistent boot can at # all be implemented via this OEM call attempts = self.RETRY_COUNT rebooted = False while True: try: response = asynchronous.http_call( self._conn, 'post', self.import_system_configuration_uri, data=action_data, sushy_task_poll_period=1) LOG.info("Set boot device to %(device)s via " "Dell OEM magic spell (%(retries)d " "retries)", {'device': device, 'retries': self.RETRY_COUNT - attempts}) return response except (sushy.exceptions.ServerSideError, sushy.exceptions.BadRequestError) as exc: LOG.warning( 'Dell OEM set boot device failed (attempts left ' '%d): %s', attempts, exc) errors = exc.body and exc.body.get( '@Message.ExtendedInfo') or [] for error in errors: message_id = error.get('MessageId') LOG.warning('iDRAC error: %s', error.get('Message', 'Unknown error')) if constants.IDRAC_CONFIG_PENDING in message_id: if not rebooted: LOG.warning( 'Let\'s try to turn it off and on again... ' 'This may consume one-time boot settings if ' 'set previously!') utils.reboot_system(system) rebooted = True break elif constants.IDRAC_JOB_RUNNING in message_id: pass else: time.sleep(self.RETRY_DELAY) if not attempts: LOG.error('Too many (%d) retries, bailing ' 'out.', self.RETRY_COUNT) raise attempts -= 1 def get_allowed_export_target_values(self): """Get the allowed targets of export system configuration. :returns: A set of allowed values. """ export_action = self._actions.export_system_configuration allowed_values = export_action.shared_parameters.allowed_target_values if not allowed_values: LOG.warning('Could not figure out the allowed values for the ' 'target of export system configuration at %s', self.path) return set(mgr_maps.EXPORT_CONFIG_VALUE_MAP_REV) return set([mgr_maps.EXPORT_CONFIG_VALUE_MAP[value] for value in set(mgr_maps.EXPORT_CONFIG_VALUE_MAP). intersection(allowed_values)]) def get_allowed_export_use_values(self): """Get allowed export use values of export system configuration. :returns: A set of allowed export use values. """ export_action = self._actions.export_system_configuration allowed_values = export_action.allowed_export_use_values if not allowed_values: LOG.warning('Could not figure out the allowed values for the ' 'export use of export system configuration at %s', self.path) return set(mgr_maps.EXPORT_USE_VALUE_MAP_REV) return set([mgr_maps.EXPORT_USE_VALUE_MAP[value] for value in set(mgr_maps.EXPORT_USE_VALUE_MAP). intersection(allowed_values)]) def get_allowed_include_in_export_values(self): """Get allowed include in export values of export system configuration. :returns: A set of allowed include in export values. """ export_action = self._actions.export_system_configuration allowed_values = export_action.allowed_include_in_export_values if not allowed_values: LOG.warning('Could not figure out the allowed values for the ' 'include in export of export system configuration at ' '%s', self.path) return set(mgr_maps.INCLUDE_EXPORT_VALUE_MAP_REV) return set([mgr_maps.INCLUDE_EXPORT_VALUE_MAP[value] for value in set(mgr_maps.INCLUDE_EXPORT_VALUE_MAP). intersection(allowed_values)]) def _export_system_configuration( self, target, export_use=mgr_cons.EXPORT_USE_DEFAULT, include_in_export=mgr_cons.INCLUDE_EXPORT_DEFAULT): """Export system configuration. It exports system configuration for specified target like NIC, BIOS, RAID and allows to configure purpose for export and what to include. :param target: Component of the system to export the configuration from. Can be the entire system. Valid values can be gotten from `get_allowed_export_system_config_values`. :param export_use: Export use. Optional, defaults to "Default". Valid values can be gotten from `get_allowed_export_use_values`. :param include_in_export: What to include in export. Optional. Defaults to "Default". Valid values can be gotten from `get_allowed_include_in_export_values`. :returns: Response object containing configuration details. :raises: InvalidParameterValueError on invalid target. :raises: ExtensionError on failure to perform requested operation """ valid_allowed_targets = self.get_allowed_export_target_values() if target not in valid_allowed_targets: raise sushy.exceptions.InvalidParameterValueError( parameter='target', value=target, valid_values=valid_allowed_targets) allowed_export_use = self.get_allowed_export_use_values() if export_use not in allowed_export_use: raise sushy.exceptions.InvalidParameterValueError( parameter='export_use', value=export_use, valid_values=allowed_export_use) allowed_include_in_export = self.get_allowed_include_in_export_values() if include_in_export not in allowed_include_in_export: # Check if value contains comma and validate each item separately # Older iDRACs used to include comma separated option in # AllowableValues but got removed in newer versions violating # AllowableValues validation logic. include_in_export_rev =\ mgr_maps.INCLUDE_EXPORT_VALUE_MAP_REV.get(include_in_export) all_items_valid = False if include_in_export_rev is not None: items = include_in_export_rev.split(',') all_items_valid = True for item in items: if (mgr_maps.INCLUDE_EXPORT_VALUE_MAP[item] not in allowed_include_in_export): all_items_valid = False break if not all_items_valid: raise sushy.exceptions.InvalidParameterValueError( parameter='include_in_export', value=include_in_export, valid_values=allowed_include_in_export) target = mgr_maps.EXPORT_CONFIG_VALUE_MAP_REV[target] export_use = mgr_maps.EXPORT_USE_VALUE_MAP_REV[export_use] include_in_export =\ mgr_maps.INCLUDE_EXPORT_VALUE_MAP_REV[include_in_export] action_data = { 'ShareParameters': { 'Target': target }, 'ExportFormat': "JSON", 'ExportUse': export_use, 'IncludeInExport': include_in_export } try: response = asynchronous.http_call( self._conn, 'post', self.export_system_configuration_uri, data=action_data) LOG.info("Successfully exported system configuration " "for %(target)s", {'target': target}) return response except (sushy.exceptions.ExtensionError, sushy.exceptions.InvalidParameterValueError) as exc: LOG.error('Dell OEM export system configuration failed : %s', exc) raise def export_system_configuration(self): """Export system configuration. Exports ALL targets for cloning and includes password hashes and read-only attributes. :returns: Response object containing configuration details. :raises: InvalidParameterValueError on invalid target. :raises: ExtensionError on failure to perform requested operation """ include_in_export = mgr_cons.INCLUDE_EXPORT_READ_ONLY_PASSWORD_HASHES return self._export_system_configuration( mgr_cons.EXPORT_TARGET_ALL, export_use=mgr_cons.EXPORT_USE_CLONE, include_in_export=include_in_export) def get_pxe_port_macs_bios(self, ethernet_interfaces_mac): """Get a list of pxe port MAC addresses for BIOS. :param ethernet_interfaces_mac: Dictionary of ethernet interfaces. :returns: List of pxe port MAC addresses. :raises: ExtensionError on failure to perform requested operation. """ pxe_port_macs = [] # Get NIC configuration nic_settings = self._export_system_configuration( target=mgr_cons.EXPORT_TARGET_NIC) if nic_settings.status_code != _RESPONSE_OK_CODE: error = (('An error occurred when attempting to export ' 'the system configuration. Status code: %(code), ' 'Error details: %(err)'), {'code': nic_settings.status_code, 'err': nic_settings.__dict__}) LOG.error(error) raise sushy.exceptions.ExtensionError(error=error) # Parse the exported system configuration for the NIC # ports that are set to PXE boot json_data = nic_settings.json() if _SYSTEM_CONFIG_TAG in json_data.keys(): for root in json_data[_SYSTEM_CONFIG_TAG]['Components']: nic_id = root['FQDD'] for child in root['Attributes']: if child.get('Name') == "LegacyBootProto": if child['Value'] == "PXE": mac_address = ethernet_interfaces_mac[nic_id] pxe_port_macs.append(mac_address) return pxe_port_macs else: error = (('Failed to get system configuration from response')) LOG.error(error) raise sushy.exceptions.ExtensionError(error=error) def get_allowed_import_shutdown_type_values(self): """Get the allowed shutdown types of import system configuration. :returns: A set of allowed shutdown type values. """ import_action = self._actions.import_system_configuration allowed_values = import_action.allowed_shutdown_type_values if not allowed_values: LOG.warning('Could not figure out the allowed values for the ' 'shutdown type of import system configuration at %s', self.path) return set(mgr_maps.IMPORT_SHUTDOWN_VALUE_MAP_REV) return set([mgr_maps.IMPORT_SHUTDOWN_VALUE_MAP[value] for value in set(mgr_maps.IMPORT_SHUTDOWN_VALUE_MAP). intersection(allowed_values)]) def import_system_configuration(self, import_buffer): """Imports system configuration. Caller needs to handle system reboot separately. :param import_buffer: Configuration data to be imported. :returns: Task monitor instance to watch for task completion """ action_data = dict(self.ACTION_DATA, ImportBuffer=import_buffer) # Caller needs to handle system reboot separately to preserve # one-time boot settings. shutdown_type = mgr_cons.IMPORT_SHUTDOWN_NO_REBOOT allowed_shutdown_types = self.get_allowed_import_shutdown_type_values() if shutdown_type not in allowed_shutdown_types: raise sushy.exceptions.InvalidParameterValueError( parameter='shutdown_type', value=shutdown_type, valid_values=allowed_shutdown_types) action_data['ShutdownType'] =\ mgr_maps.IMPORT_SHUTDOWN_VALUE_MAP_REV[shutdown_type] response = self._conn.post(self.import_system_configuration_uri, data=action_data) return TaskMonitor.from_response( self._conn, response, self.import_system_configuration_uri) def reset_idrac(self, wait=True, ready_wait_time=60): """Reset the iDRAC and wait for it to become ready. :param wait: Whether to return immediately or wait for iDRAC to become operational. :param ready_wait_time: Amount of time in seconds to wait before starting to check on the iDRAC's status. """ self.idrac_card_service.reset_idrac() if not wait: return host = urlparse(self._conn._url).netloc LOG.debug("iDRAC %(host)s was reset, " "waiting for return to operational state", {'host': host}) self._wait_for_idrac(host, ready_wait_time) self._wait_until_idrac_is_ready(host, self._IDRAC_IS_READY_RETRIES, self._IDRAC_IS_READY_RETRY_DELAY_SEC) def _wait_for_idrac_state(self, host, alive=True, ping_count=3, retries=24): """Wait for iDRAC to become pingable or not pingable. :param host: Hostname or IP of the iDRAC interface. :param alive: True for pingable state and False for not pingable state. :param ping_count: Number of consecutive ping results, per 'alive', for success. :param retries: Number of ping retries. :returns: True on reaching specified host ping state; otherwise, False. """ if alive: ping_type = "pingable" else: ping_type = "not pingable" LOG.debug("Waiting for iDRAC %(host)s to become %(ping_type)s", {'host': host, 'ping_type': ping_type}) response_count = 0 while retries > 0: response = self._ping_host(host) retries -= 1 if response == alive: response_count += 1 LOG.debug("iDRAC %(host)s is %(ping_type)s, " "count=%(response_count)s", {'host': host, 'ping_type': ping_type, 'response_count': response_count}) if response_count == ping_count: LOG.debug("Reached specified %(alive)s count for iDRAC " "%(host)s", {'alive': alive, 'host': host}) return True else: response_count = 0 if alive: LOG.debug("iDRAC %(host)s is still not pingable", {'host': host}) else: LOG.debug("iDRAC %(host)s is still pingable", {'host': host}) time.sleep(10) return False def _wait_for_idrac(self, host, post_pingable_wait_time): """Wait for iDRAC to transition from unpingable to pingable. :param host: Hostname or IP of the iDRAC interface. :param post_pingable_wait_time: Amount of time in seconds to wait after the host becomes pingable. :raises: ExtensionError on failure to perform requested operation. """ state_reached = self._wait_for_idrac_state( host, alive=False, ping_count=2, retries=24) if not state_reached: error_msg = ("Timed out waiting iDRAC %(host)s to become not " "pingable", {'host': host}) LOG.error(error_msg) raise sushy.exceptions.ExtensionError(error=error_msg) LOG.debug("iDRAC %(host)s has become not pingable", {'host': host}) state_reached = self._wait_for_idrac_state(host, alive=True, ping_count=3, retries=24) if not state_reached: error_msg = ("Timed out waiting iDRAC %(host)s to become pingable", {'host': host}) LOG.error(error_msg) raise sushy.exceptions.ExtensionError(error=error_msg) LOG.debug("iDRAC %(host)s has become pingable", {'host': host}) time.sleep(post_pingable_wait_time) def _wait_until_idrac_is_ready(self, host, retries, retry_delay): """Wait until the iDRAC is in a ready state. :param host: Hostname or IP of the iDRAC interface. :param retries: The number of times to check if the iDRAC is ready. :param retry_delay: The number of seconds to wait between retries. :raises: ExtensionError on failure to perform requested operation. """ while retries > 0: LOG.debug("Checking to see if iDRAC %(host)s is ready", {'host': host}) if self.lifecycle_service.is_idrac_ready(): LOG.debug("iDRAC %(host)s is ready", {'host': host}) return LOG.debug("iDRAC %(host)s is not ready", {'host': host}) retries -= 1 if retries > 0: time.sleep(retry_delay) if retries == 0: error_msg = ("Timed out waiting iDRAC %(host)s to become " "ready after reset", {'host': host}) LOG.error(error_msg) raise sushy.exceptions.ExtensionError(error=error_msg) def _ping_host(self, host): """Ping the hostname or IP of a host. :param host: Hostname or IP. :returns: True if host is alive; otherwise, False. """ response = subprocess.call(["ping", "-c", "1", host]) return response == 0 def get_extension(*args, **kwargs): return DellManagerExtension ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1631521128.0 sushy-oem-idrac-3.0.1/sushy_oem_idrac/resources/manager/mappings.py0000664000175000017500000000412500000000000025542 0ustar00zuulzuul00000000000000# Copyright (c) 2020-2021 Dell Inc. or its subsidiaries. # # 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 sushy import utils from sushy_oem_idrac.resources.manager import constants as mgr_cons EXPORT_CONFIG_VALUE_MAP = { 'ALL': mgr_cons.EXPORT_TARGET_ALL, 'BIOS': mgr_cons.EXPORT_TARGET_BIOS, 'IDRAC': mgr_cons.EXPORT_TARGET_IDRAC, 'NIC': mgr_cons.EXPORT_TARGET_NIC, 'RAID': mgr_cons.EXPORT_TARGET_RAID } EXPORT_CONFIG_VALUE_MAP_REV = utils.revert_dictionary(EXPORT_CONFIG_VALUE_MAP) RESET_IDRAC_VALUE_MAP = { 'Graceful': mgr_cons.RESET_IDRAC_GRACEFUL_RESTART, 'Force': mgr_cons.RESET_IDRAC_FORCE_RESTART, } RESET_IDRAC_VALUE_MAP_REV = utils.revert_dictionary(RESET_IDRAC_VALUE_MAP) IMPORT_SHUTDOWN_VALUE_MAP = { 'Graceful': mgr_cons.IMPORT_SHUTDOWN_GRACEFUL, 'Forced': mgr_cons.IMPORT_SHUTDOWN_FORCED, 'NoReboot': mgr_cons.IMPORT_SHUTDOWN_NO_REBOOT } IMPORT_SHUTDOWN_VALUE_MAP_REV =\ utils.revert_dictionary(IMPORT_SHUTDOWN_VALUE_MAP) EXPORT_USE_VALUE_MAP = { 'Default': mgr_cons.EXPORT_USE_DEFAULT, 'Clone': mgr_cons.EXPORT_USE_CLONE, 'Replace': mgr_cons.EXPORT_USE_REPLACE } EXPORT_USE_VALUE_MAP_REV = utils.revert_dictionary(EXPORT_USE_VALUE_MAP) INCLUDE_EXPORT_VALUE_MAP = { 'Default': mgr_cons.INCLUDE_EXPORT_DEFAULT, 'IncludeReadOnly': mgr_cons.INCLUDE_EXPORT_READ_ONLY, 'IncludePasswordHashValues': mgr_cons.INCLUDE_EXPORT_PASSWORD_HASHES, 'IncludeReadOnly,IncludePasswordHashValues': mgr_cons.INCLUDE_EXPORT_READ_ONLY_PASSWORD_HASHES } INCLUDE_EXPORT_VALUE_MAP_REV =\ utils.revert_dictionary(INCLUDE_EXPORT_VALUE_MAP) ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1631521193.3499517 sushy-oem-idrac-3.0.1/sushy_oem_idrac/resources/system/0000775000175000017500000000000000000000000023262 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1631521128.0 sushy-oem-idrac-3.0.1/sushy_oem_idrac/resources/system/constants.py0000664000175000017500000000132100000000000025645 0ustar00zuulzuul00000000000000# Copyright (c) 2021 Dell Inc. or its subsidiaries. # # 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. PHYSICAL_DISK_STATE_MODE_RAID = 'RAID' """RAID mode""" PHYSICAL_DISK_STATE_MODE_NONRAID = 'Non-RAID' """Non-RAID mode""" ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1631521128.0 sushy-oem-idrac-3.0.1/sushy_oem_idrac/resources/system/raid_service.py0000664000175000017500000001305000000000000026272 0ustar00zuulzuul00000000000000# Copyright (c) 2021 Dell Inc. or its subsidiaries. # # 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 logging from sushy import exceptions from sushy.resources import base from sushy.resources import common from sushy import taskmonitor from sushy_oem_idrac import constants LOG = logging.getLogger(__name__) class ActionsField(base.CompositeField): convert_to_raid = common.ActionField("#DellRaidService.ConvertToRAID") convert_to_nonraid = common.ActionField( "#DellRaidService.ConvertToNonRAID") clear_foreign_config = common.ActionField( "#DellRaidService.ClearForeignConfig") class DellRaidService(base.ResourceBase): identity = base.Field('Id', required=True) _actions = ActionsField('Actions') def __init__(self, connector, identity, redfish_version=None, registries=None, root=None): """A class representing a DellRaidService. :param connector: A Connector instance :param identity: The identity of the DellRaidService resource :param redfish_version: The version of Redfish. Used to construct the object according to schema of the given version. :param registries: Dict of Redfish Message Registry objects to be used in any resource that needs registries to parse messages. :param root: Sushy root object. Empty for Sushy root itself. """ super(DellRaidService, self).__init__( connector, identity, redfish_version=redfish_version, registries=registries, root=root) def convert_to_raid(self, physical_disk_fqdds): """Converts physical disks to a state usable for RAID :param physical_disk_fqdds: An array of FQDDs where each identifies a physical drive. :returns: Sushy's TaskMonitor instance for TaskService task """ target_uri = self._actions.convert_to_raid.target_uri payload = {'PDArray': physical_disk_fqdds} response = self._conn.post(target_uri, data=payload) task_monitor = self._get_task_monitor_from_dell_job(response) LOG.info('Converting to RAID mode: %s', physical_disk_fqdds) return task_monitor def convert_to_nonraid(self, physical_disk_fqdds): """Converts physical disks to non-RAID state. :param physical_disk_fqdds: An array of FQDDs where each identifies a physical drive. :returns: Sushy's TaskMonitor instance for TaskService task """ target_uri = self._actions.convert_to_nonraid.target_uri payload = {'PDArray': physical_disk_fqdds} response = self._conn.post(target_uri, data=payload) task_monitor = self._get_task_monitor_from_dell_job(response) LOG.info('Converting to non-RAID mode: %s', physical_disk_fqdds) return task_monitor def clear_foreign_config(self, controller_fqdd): """Clears foreign configuration Prepares any foreign physical disks for inclusion in the local configuration :param controller_fqdd: FQDD of controller to clear foreign config :returns: Sushy's TaskMonitor instance for TaskService task if there are foreign drives to clear, otherwise None. """ target_uri = self._actions.clear_foreign_config.target_uri payload = {'TargetFQDD': controller_fqdd} try: response = self._conn.post(target_uri, data=payload) except exceptions.BadRequestError as ex: # Check if failed for no foreign drives errors = ex.body and ex.body.get('@Message.ExtendedInfo') or [] no_foreign_conf = [x for x in errors if constants.NO_FOREIGN_CONFIG in x.get('MessageId')] if len(no_foreign_conf) == 0: raise ex else: LOG.debug('%s: %s', no_foreign_conf[0].get('Message'), controller_fqdd) return task_mon = self._get_task_monitor_from_dell_job(response) LOG.info('Clearing foreign config: %s', controller_fqdd) return task_mon def _get_task_monitor_from_dell_job(self, response): """From OEM job response returns generic Task monitor :param response: Response from OEM job :returns: Sushy's TaskMonitor instance for TaskService task """ location = response.headers.get('Location') if not location: raise exceptions.ExtensionError( error='Response %s does not include Location in header' % (response.url)) task_id = location.split('/')[-1] task = None for t in self.root.get_task_service().tasks.get_members(): if t.identity == task_id: task = t break if not task: raise exceptions.ExtensionError( error="Did not find task by id %s" % task_id) return taskmonitor.TaskMonitor( self._conn, task.path, redfish_version=self.redfish_version, registries=self.registries) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1631521128.0 sushy-oem-idrac-3.0.1/sushy_oem_idrac/resources/system/system.py0000664000175000017500000001463600000000000025172 0ustar00zuulzuul00000000000000# Copyright (c) 2021 Dell Inc. or its subsidiaries. # # 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 sushy from sushy import exceptions from sushy.resources.oem import base as oem_base from sushy import utils as sushy_utils from sushy_oem_idrac.resources.system import constants as sys_cons from sushy_oem_idrac.resources.system import raid_service def _filter_disks_not_in_mode(controller_to_disks, mode): """Filters disks that are not in requested mode :param controller_to_disks: dictionary of controllers and their drives :param mode: constants.PHYSICAL_DISK_STATE_MODE_RAID or constants.PHYSICAL_DISK_STATE_MODE_NONRAID :returns: dictionary of controllers and their drives that need mode changed """ sushy_raw_device = sushy.VOLUME_TYPE_RAW_DEVICE for controller, drives in controller_to_disks.items(): toprocess_drives = [] for drive in drives: is_raw_device = False volumes = None try: volumes = drive.volumes except exceptions.MissingAttributeError: pass if (volumes and (volumes[0].volume_type == sushy_raw_device or volumes[0].raid_type is None)): is_raw_device = True if (mode == sys_cons.PHYSICAL_DISK_STATE_MODE_RAID and is_raw_device or mode == sys_cons.PHYSICAL_DISK_STATE_MODE_NONRAID and not is_raw_device): toprocess_drives.append(drive) controller_to_disks[controller] = toprocess_drives return controller_to_disks class DellSystemExtension(oem_base.OEMResourceBase): @property @sushy_utils.cache_it def raid_service(self): """`DellRaidService` of the system""" path = sushy_utils.get_sub_resource_path_by( self, ["Links", "Oem", "Dell", "DellRaidService"], is_collection=False) return raid_service.DellRaidService( self._conn, path, redfish_version=self.redfish_version, registries=self.registries, root=self.root) def change_physical_disk_state(self, mode, controller_to_disks=None): """Converts physical disks RAID status Converts only those disks that are not already in requested mode. :param mode: constants.PHYSICAL_DISK_STATE_MODE_RAID or constants.PHYSICAL_DISK_STATE_MODE_NONRAID :param controller_to_disks: dictionary of controllers and their drives. Optional, if not provided, processes all RAID, except BOSS, controller drives. :returns: List of task monitors for each controller's disks if any drives need changes """ if not controller_to_disks: controller_to_disks = self._get_controller_to_disks() # Do not process BOSS controllers as can't convert their disks boss_controllers = [c for c in controller_to_disks if 'BOSS' in c.name.upper()] for c in boss_controllers: controller_to_disks.pop(c) controller_to_disks = _filter_disks_not_in_mode( controller_to_disks, mode) # Convert by each controller that have eligible disks task_monitors = [] for controller, drives in controller_to_disks.items(): if drives: drive_fqdds = [d.identity for d in drives] if mode == sys_cons.PHYSICAL_DISK_STATE_MODE_RAID: task_monitors.append( self.raid_service.convert_to_raid(drive_fqdds)) elif mode == sys_cons.PHYSICAL_DISK_STATE_MODE_NONRAID: task_monitors.append( self.raid_service.convert_to_nonraid(drive_fqdds)) return task_monitors def clear_foreign_config(self, storage_list=None): """Clears foreign config on given controllers :param storage_list: List of storage objects, each of which corresponds to a controller :returns: List of task monitors, where each entry is for a controller that has foreign config to clear """ if storage_list is None: storage_list = self._get_storage_list() # Do not process BOSS controllers as not supporting clearing boss_storage = [s for s in storage_list if any(c for c in s.storage_controllers if 'BOSS' in c.name.upper())] for s in boss_storage: storage_list.remove(s) task_monitors = [] for storage in storage_list: task_mon = self.raid_service.clear_foreign_config(storage.identity) if task_mon: task_monitors.append(task_mon) return task_monitors def _get_controller_to_disks(self): """Gets all RAID controllers and their disks on system :returns: dictionary of RAID controllers and their disks """ controller_to_disks = {} for storage in self._parent_resource.storage.get_members(): controller = (storage.storage_controllers[0] if storage.storage_controllers else None) if not controller or controller and not controller.raid_types: continue controller_to_disks[controller] = storage.drives return controller_to_disks def _get_storage_list(self): """Gets all storage items corresponding to RAID controllers :returns: list of storage items """ storage_list = [] for storage in self._parent_resource.storage.get_members(): controller = (storage.storage_controllers[0] if storage.storage_controllers else None) if not controller or controller and not controller.raid_types: continue storage_list.append(storage) return storage_list def get_extension(*args, **kwargs): return DellSystemExtension ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1631521193.3499517 sushy-oem-idrac-3.0.1/sushy_oem_idrac/resources/taskservice/0000775000175000017500000000000000000000000024261 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1631521128.0 sushy-oem-idrac-3.0.1/sushy_oem_idrac/resources/taskservice/constants.py0000664000175000017500000001177500000000000026662 0ustar00zuulzuul00000000000000# Copyright (c) 2021 Dell Inc. or its subsidiaries. # # 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. # Job state constants JOB_STATE_COMPLETED = "Completed" """A job is in completed state""" JOB_STATE_COMPLETED_ERRORS = "Completed with errors" """A job is in completed state with errors""" JOB_STATE_DOWNLOADED = "Downloaded" """A job is in downloaded state""" JOB_STATE_DOWNLOADING = "Downloading" """A job is in downloading state""" JOB_STATE_FAILED = "Failed" """A job is in failed state""" JOB_STATE_NEW = "New" """A job is in newly created state""" JOB_STATE_PAUSED = "Paused" """A job is in paused state""" JOB_STATE_PENDING_ACTIVATION = "Pending activation" """A job is in pending activation state""" JOB_STATE_READY_EXECUTION = "Ready for execution" """A job is in ready for execution state""" JOB_STATE_REBOOT_COMPLETED = "Reboot completed" """A job is in reboot completed state""" JOB_STATE_REBOOT_FAILED = "Reboot failed" """A job is in reboot failed state""" JOB_STATE_REBOOT_PENDING = "Reboot pending" """A job is in pending state for reboot""" JOB_STATE_RUNNING = "Running" """A job is in running state""" JOB_STATE_SCHEDULED = "Scheduled" """A job is in scheduled state""" JOB_STATE_SCHEDULING = "Scheduling" """A job is in scheduling state""" JOB_STATE_UNKNOWN = "Unknown" """A job is in unknown state""" JOB_STATE_WAITING = "Waiting" """A job is in waiting state""" # Job type constants JOB_TYPE_BIOS_CONF = "BIOS configuration" """A BIOS configuration job""" JOB_TYPE_EXPORT_CONF = "Export configuration" """A server configuration profile export job""" JOB_TYPE_FC_CONF = "Fibre Channel configuration" """A Fibre Channel configuration job""" JOB_TYPE_FACTORY_CONF_EXPORT = "Factory configuration export" """A factory configuration export job""" JOB_TYPE_FIRMWARE_ROLLBACK = "Firmware rollback" """A firmware rollback job""" JOB_TYPE_FIRMWARE_UPDATE = "Firmware update" """A firmware update job""" JOB_TYPE_HW_INVENTORY_EXPORT = "Hardware inventory export" """A hardware inventory export job""" JOB_TYPE_IMPORT_CONF = "Import configuration" """A server configuration profile import job""" JOB_TYPE_INBAND_BIOS_CONF = "Inband BIOS configuration" """An inband BIOS configuration job""" JOB_TYPE_LC_CONF = "LC configuration" """A lifecycle controller attribute configuration job""" JOB_TYPE_LC_EXPORT = "LC export" """A lifecycle controller export job""" JOB_TYPE_LC_LOG_EXPORT = "LC log export" """A lifecycle controller log export job""" JOB_TYPE_LICENSE_EXPORT = "License export" """A license export job""" JOB_TYPE_LICENSE_IMPORT = "License import" """A license import job""" JOB_TYPE_MSG_REG_EXPORT = "Message registry export" """Export message registry report job""" JOB_TYPE_NIC_CONF = "NIC configuration" """A NIC configuration job""" JOB_TYPE_OS_DEPLOY = "OS deploy" """Operating System deploy job""" JOB_TYPE_RAID_CONF = "RAID configuration" """A RAID configuration job""" JOB_TYPE_RT_NO_REBOOT_CONF = "Real-time no reboot configuration" """A real time configuration job without reboot""" JOB_TYPE_REBOOT_FORCE = "Reboot force" """A reboot job with forced shutdown""" JOB_TYPE_REBOOT_NO_FORCE = "Reboot no force" """A graceful reboot job without forced shutdown""" JOB_TYPE_REBOOT_POWER_CYCLE = "Reboot power cycle" """A power cycle job""" JOB_TYPE_REMOTE_DIAG = "Remote diagnostics" """A remote diagnostics job""" JOB_TYPE_REPO_UPDATE = "Repository update" """An update job from a repository""" JOB_TYPE_SA_COL_EXP_HEALTH_DATA = "SA collect and export health data" """Support Assist collect and export health data job""" JOB_TYPE_SA_COL_HEALTH_DATA = "SA collect health data" """Support Assist collect health data job""" JOB_TYPE_SA_EXP_HEALTH_DATA = "SA export health data" """Support Assist export health data job""" JOB_TYPE_SA_ISM = "SA expose iSM" """Support Assist expose iDRAC Service Module installer package to host job""" JOB_TYPE_SA_REG = "SA registration" """Support Assist register iDRAC to Dell backend server job""" JOB_TYPE_SEKM_REKEY = "SEKM rekey" """A Secure Enterprise Key Manager rekey job""" JOB_TYPE_SEKM_STATUS_SET = "SEKM status set" """A Secure Enterprise Key Manager status set job""" JOB_TYPE_SHUTDOWN = "Shutdown" """A shutdown job""" JOB_TYPE_SYS_ERASE = "System erase" """A selective system erase job""" JOB_TYPE_SYS_INFO_CONF = "System info configuration" """A system info configuration job""" JOB_TYPE_THERMAL_HIST_EXP = "Thermal history export" """A thermal history export job""" JOB_TYPE_UNKNOWN = "Unknown" """An unknown job""" JOB_TYPE_IDRAC_CONF = "iDRAC configuration" """An iDRAC configuration job""" ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1631521128.0 sushy-oem-idrac-3.0.1/sushy_oem_idrac/resources/taskservice/mappings.py0000664000175000017500000000726600000000000026464 0ustar00zuulzuul00000000000000# Copyright (c) 2021 Dell Inc. or its subsidiaries. # # 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 sushy import utils from sushy_oem_idrac.resources.taskservice import constants as ts_cons JOB_STATE_VALUE_MAP = { "New": ts_cons.JOB_STATE_NEW, "Scheduled": ts_cons.JOB_STATE_SCHEDULED, "Running": ts_cons.JOB_STATE_RUNNING, "Completed": ts_cons.JOB_STATE_COMPLETED, "Downloading": ts_cons.JOB_STATE_DOWNLOADING, "Downloaded": ts_cons.JOB_STATE_DOWNLOADED, "Scheduling": ts_cons.JOB_STATE_SCHEDULING, "ReadyForExecution": ts_cons.JOB_STATE_READY_EXECUTION, "Waiting": ts_cons.JOB_STATE_WAITING, "Paused": ts_cons.JOB_STATE_PAUSED, "Failed": ts_cons.JOB_STATE_FAILED, "CompletedWithErrors": ts_cons.JOB_STATE_COMPLETED_ERRORS, "RebootPending": ts_cons.JOB_STATE_REBOOT_PENDING, "RebootFailed": ts_cons.JOB_STATE_REBOOT_FAILED, "RebootCompleted": ts_cons.JOB_STATE_REBOOT_COMPLETED, "PendingActivation": ts_cons.JOB_STATE_PENDING_ACTIVATION, "Unknown": ts_cons.JOB_STATE_UNKNOWN } JOB_STATE_VALUE_MAP_REV = utils.revert_dictionary(JOB_STATE_VALUE_MAP) JOB_TYPE_VALUE_MAP = { "FirmwareUpdate": ts_cons.JOB_TYPE_FIRMWARE_UPDATE, "FirmwareRollback": ts_cons.JOB_TYPE_FIRMWARE_ROLLBACK, "RepositoryUpdate": ts_cons.JOB_TYPE_REPO_UPDATE, "RebootPowerCycle": ts_cons.JOB_TYPE_REBOOT_POWER_CYCLE, "RebootForce": ts_cons.JOB_TYPE_REBOOT_FORCE, "RebootNoForce": ts_cons.JOB_TYPE_REBOOT_NO_FORCE, "Shutdown": ts_cons.JOB_TYPE_SHUTDOWN, "RAIDConfiguration": ts_cons.JOB_TYPE_RAID_CONF, "BIOSConfiguration": ts_cons.JOB_TYPE_BIOS_CONF, "NICConfiguration": ts_cons.JOB_TYPE_NIC_CONF, "FCConfiguration": ts_cons.JOB_TYPE_FC_CONF, "iDRACConfiguration": ts_cons.JOB_TYPE_IDRAC_CONF, "SystemInfoConfiguration": ts_cons.JOB_TYPE_SYS_INFO_CONF, "InbandBIOSConfiguration": ts_cons.JOB_TYPE_INBAND_BIOS_CONF, "ExportConfiguration": ts_cons.JOB_TYPE_EXPORT_CONF, "ImportConfiguration": ts_cons.JOB_TYPE_IMPORT_CONF, "RemoteDiagnostics": ts_cons.JOB_TYPE_REMOTE_DIAG, "RealTimeNoRebootConfiguration": ts_cons.JOB_TYPE_RT_NO_REBOOT_CONF, "LCLogExport": ts_cons.JOB_TYPE_LC_LOG_EXPORT, "HardwareInventoryExport": ts_cons.JOB_TYPE_HW_INVENTORY_EXPORT, "FactoryConfigurationExport": ts_cons.JOB_TYPE_FACTORY_CONF_EXPORT, "LicenseImport": ts_cons.JOB_TYPE_LICENSE_IMPORT, "LicenseExport": ts_cons.JOB_TYPE_LICENSE_EXPORT, "ThermalHistoryExport": ts_cons.JOB_TYPE_THERMAL_HIST_EXP, "LCConfig": ts_cons.JOB_TYPE_LC_CONF, "LCExport": ts_cons.JOB_TYPE_LC_EXPORT, "SACollectHealthData": ts_cons.JOB_TYPE_SA_COL_HEALTH_DATA, "SAExportHealthData": ts_cons.JOB_TYPE_SA_EXP_HEALTH_DATA, "SACollectExportHealthData": ts_cons.JOB_TYPE_SA_COL_EXP_HEALTH_DATA, "SAExposeISM": ts_cons.JOB_TYPE_SA_ISM, "SARegistration": ts_cons.JOB_TYPE_SA_REG, "SystemErase": ts_cons.JOB_TYPE_SYS_ERASE, "MessageRegistryExport": ts_cons.JOB_TYPE_MSG_REG_EXPORT, "OSDeploy": ts_cons.JOB_TYPE_OS_DEPLOY, "SEKMRekey": ts_cons.JOB_TYPE_SEKM_REKEY, "SEKMStatusSet": ts_cons.JOB_TYPE_SEKM_STATUS_SET, "Unknown": ts_cons.JOB_TYPE_UNKNOWN } JOB_TYPE_VALUE_MAP_REV = utils.revert_dictionary(JOB_TYPE_VALUE_MAP) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1631521128.0 sushy-oem-idrac-3.0.1/sushy_oem_idrac/resources/taskservice/task.py0000664000175000017500000000432500000000000025601 0ustar00zuulzuul00000000000000# Copyright (c) 2021 Dell Inc. or its subsidiaries. # # 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 logging from sushy.resources import base from sushy.resources.oem import base as oem_base from sushy_oem_idrac.resources.taskservice import mappings as ts_maps LOG = logging.getLogger(__name__) class DellTaskExtension(oem_base.OEMResourceBase): """Dell OEM extension for DellJob type""" identity = base.Field('Id', required=True) name = base.Field('Name', required=True) description = base.Field('Description') completion_time = base.Field('CompletionTime') """Job completion time""" end_time = base.Field('EndTime') """End time of job Timestamp until when the service will wait for a job to complete. If a job does not complete within this time, it is killed and marked as failed. TIME_NA is a default value and implies EndTime is not applicable. """ job_state = base.MappedField('JobState', ts_maps.JOB_STATE_VALUE_MAP) """Job state""" job_type = base.MappedField('JobType', ts_maps.JOB_TYPE_VALUE_MAP) """Job type""" message = base.Field('Message') """The status message for job""" message_args = base.Field('MessageArgs') """Array of message arguments for message field""" message_id = base.Field('MessageId') """Message id for job""" percent_complete = base.Field('PercentComplete', adapter=int) """The percentage completion of job""" start_time = base.Field('StartTime') """Scheduled start time of job String that will contain a timestamp in Edm.DateTime format. TIME_NOW is a default value and implies apply pending configuration now. """ def get_extension(*args, **kwargs): return DellTaskExtension ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1631521193.3499517 sushy-oem-idrac-3.0.1/sushy_oem_idrac/tests/0000775000175000017500000000000000000000000021066 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1631521128.0 sushy-oem-idrac-3.0.1/sushy_oem_idrac/tests/__init__.py0000664000175000017500000000000000000000000023165 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1631521193.3539517 sushy-oem-idrac-3.0.1/sushy_oem_idrac/tests/functional/0000775000175000017500000000000000000000000023230 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1631521128.0 sushy-oem-idrac-3.0.1/sushy_oem_idrac/tests/functional/__init__.py0000664000175000017500000000000000000000000025327 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1631521128.0 sushy-oem-idrac-3.0.1/sushy_oem_idrac/tests/functional/vmedia_boot.py0000664000175000017500000000630000000000000026071 0ustar00zuulzuul00000000000000# 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 logging import os import sys import sushy from sushy_oem_idrac import utils USERNAME = 'root' PASSWORD = 'calvin' SERVICE_ROOT = 'http://demo.snmplabs.com:80/redfish/v1' SYSTEM_ID = '437XR1138R2' BOOT_DEVICE = sushy.VIRTUAL_MEDIA_CD BOOT_MODE = sushy.BOOT_SOURCE_MODE_BIOS BOOT_IMAGE = 'http://demo.snmplabs.com/mini.iso' LOG = logging.getLogger(__name__) def main(): """Boot Dell node from virtual media device""" LOG.setLevel(logging.INFO) handler = logging.StreamHandler() handler.setLevel(logging.INFO) LOG.addHandler(handler) authenticator = sushy.auth.BasicAuth(USERNAME, PASSWORD) conn = sushy.Sushy(SERVICE_ROOT, verify=False, auth=authenticator) LOG.info('connected to %s', SERVICE_ROOT) system = conn.get_system( os.path.join(SERVICE_ROOT, 'Systems', SYSTEM_ID)) LOG.info('read system resource %s', system.identity) for manager in system.managers: LOG.info('trying manager %s', manager.identity) for v_media in manager.virtual_media.get_members(): if BOOT_DEVICE not in v_media.media_types: continue LOG.info( 'device %s is present at %s', BOOT_DEVICE, manager.identity) try: manager_oem = manager.get_oem_extension('Dell') except sushy.exceptions.OEMExtensionNotFoundError: LOG.info('Dell OEM not found') continue LOG.info('found Dell OEM extension at %s', manager.identity) if v_media.inserted: v_media.eject_media() LOG.info('ejected virtual media') v_media.insert_media(BOOT_IMAGE, inserted=True, write_protected=True) LOG.info('inserted boot image %s into virtual media', BOOT_IMAGE) # the caller (e.g. ironic) sets boot mode first, boot device second system.set_system_boot_source( BOOT_DEVICE, enabled=sushy.BOOT_SOURCE_ENABLED_CONTINUOUS, mode=BOOT_MODE) # with Dell, patching System tree does not work as expected # we need to reboot for the new boot mode to take effect utils.reboot_system(system) LOG.info('set boot mode to %s', BOOT_MODE) manager_oem.set_virtual_boot_device( BOOT_DEVICE, persistent=False, manager=manager, system=system) LOG.info('set boot device to %s', BOOT_DEVICE) # real caller should better not use our way to reboot utils.reboot_system(system) LOG.info('system rebooted') return 0 if __name__ == '__main__': sys.exit(main()) ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1631521193.3539517 sushy-oem-idrac-3.0.1/sushy_oem_idrac/tests/unit/0000775000175000017500000000000000000000000022045 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1631521128.0 sushy-oem-idrac-3.0.1/sushy_oem_idrac/tests/unit/__init__.py0000664000175000017500000000000000000000000024144 0ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1631521128.0 sushy-oem-idrac-3.0.1/sushy_oem_idrac/tests/unit/base.py0000664000175000017500000000132400000000000023331 0ustar00zuulzuul00000000000000# -*- coding: utf-8 -*- # Copyright 2019 OpenStack Foundation # # 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 oslotest import base class TestCase(base.BaseTestCase): """Test case base class for all unit tests""" ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1631521193.3539517 sushy-oem-idrac-3.0.1/sushy_oem_idrac/tests/unit/json_samples/0000775000175000017500000000000000000000000024542 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1631521128.0 sushy-oem-idrac-3.0.1/sushy_oem_idrac/tests/unit/json_samples/export_configuration_nic_bios.json0000664000175000017500000011707200000000000033562 0ustar00zuulzuul00000000000000{ "SystemConfiguration": { "Comments": [ { "Comment": "Export type is Normal,JSON,Selective" }, { "Comment": "Exported configuration may contain commented attributes. Attributes may be commented due to dependency, destructive nature, preserving server identity or for security reasons." } ], "Model": "PowerEdge R7525", "ServiceTag": "C6DCS33", "TimeStamp": "Wed Feb 3 06:53:31 2021", "Components": [ { "FQDD": "NIC.Integrated.1-4-1", "Attributes": [ { "Name": "BlnkLeds", "Value": "0", "Set On Import": "True", "Comment": "Read and Write" }, { "Name": "VirtMacAddr", "Value": "00:00:00:00:00:00", "Set On Import": "False", "Comment": "Read and Write" }, { "Name": "VirtualizationMode", "Value": "NONE", "Set On Import": "True", "Comment": "Read and Write" }, { "Name": "LegacyBootProto", "Value": "NONE", "Set On Import": "True", "Comment": "Read and Write" }, { "Name": "LnkSpeed", "Value": "AutoNeg", "Set On Import": "True", "Comment": "Read and Write" }, { "Name": "WakeOnLan", "Value": "Disabled", "Set On Import": "True", "Comment": "Read and Write" }, { "Name": "VLanId", "Value": "0", "Set On Import": "False", "Comment": "Read and Write" }, { "Name": "NumberVFAdvertised", "Value": "8", "Set On Import": "False", "Comment": "Read and Write" } ] }, { "FQDD": "NIC.Integrated.1-2-1", "Attributes": [ { "Name": "BlnkLeds", "Value": "0", "Set On Import": "True", "Comment": "Read and Write" }, { "Name": "VirtMacAddr", "Value": "00:00:00:00:00:00", "Set On Import": "False", "Comment": "Read and Write" }, { "Name": "VirtualizationMode", "Value": "NONE", "Set On Import": "True", "Comment": "Read and Write" }, { "Name": "LegacyBootProto", "Value": "NONE", "Set On Import": "True", "Comment": "Read and Write" }, { "Name": "LnkSpeed", "Value": "AutoNeg", "Set On Import": "True", "Comment": "Read and Write" }, { "Name": "WakeOnLan", "Value": "Disabled", "Set On Import": "True", "Comment": "Read and Write" }, { "Name": "VLanId", "Value": "0", "Set On Import": "False", "Comment": "Read and Write" }, { "Name": "NumberVFAdvertised", "Value": "8", "Set On Import": "False", "Comment": "Read and Write" } ] }, { "FQDD": "NIC.Integrated.1-3-1", "Attributes": [ { "Name": "BlnkLeds", "Value": "0", "Set On Import": "True", "Comment": "Read and Write" }, { "Name": "VirtMacAddr", "Value": "00:00:00:00:00:00", "Set On Import": "False", "Comment": "Read and Write" }, { "Name": "VirtualizationMode", "Value": "NONE", "Set On Import": "True", "Comment": "Read and Write" }, { "Name": "LegacyBootProto", "Value": "PXE", "Set On Import": "True", "Comment": "Read and Write" }, { "Name": "LnkSpeed", "Value": "AutoNeg", "Set On Import": "True", "Comment": "Read and Write" }, { "Name": "WakeOnLan", "Value": "Disabled", "Set On Import": "True", "Comment": "Read and Write" }, { "Name": "VLanId", "Value": "0", "Set On Import": "False", "Comment": "Read and Write" }, { "Name": "NumberVFAdvertised", "Value": "8", "Set On Import": "False", "Comment": "Read and Write" } ] }, { "FQDD": "NIC.Integrated.1-1-1", "Attributes": [ { "Name": "BlnkLeds", "Value": "0", "Set On Import": "True", "Comment": "Read and Write" }, { "Name": "VirtMacAddr", "Value": "00:00:00:00:00:00", "Set On Import": "False", "Comment": "Read and Write" }, { "Name": "VirtualizationMode", "Value": "NONE", "Set On Import": "True", "Comment": "Read and Write" }, { "Name": "LegacyBootProto", "Value": "NONE", "Set On Import": "True", "Comment": "Read and Write" }, { "Name": "LnkSpeed", "Value": "AutoNeg", "Set On Import": "True", "Comment": "Read and Write" }, { "Name": "WakeOnLan", "Value": "Disabled", "Set On Import": "True", "Comment": "Read and Write" }, { "Name": "VLanId", "Value": "0", "Set On Import": "False", "Comment": "Read and Write" }, { "Name": "NumberVFAdvertised", "Value": "8", "Set On Import": "False", "Comment": "Read and Write" } ] }, { "FQDD": "NIC.Embedded.1-1-1", "Attributes": [ { "Name": "BlnkLeds", "Value": "0", "Set On Import": "True", "Comment": "Read and Write" }, { "Name": "EEEControl", "Value": "Enabled", "Set On Import": "True", "Comment": "Read and Write" }, { "Name": "VirtMacAddr", "Value": "F4:02:70:B8:A6:7A", "Set On Import": "False", "Comment": "Read and Write" }, { "Name": "TcpIpViaDHCP", "Value": "Enabled", "Set On Import": "True", "Comment": "Read and Write" }, { "Name": "IpAutoConfig", "Value": "Enabled", "Set On Import": "True", "Comment": "Read and Write" }, { "Name": "IscsiViaDHCP", "Value": "Disabled", "Set On Import": "True", "Comment": "Read and Write" }, { "Name": "ChapAuthEnable", "Value": "Disabled", "Set On Import": "True", "Comment": "Read and Write" }, { "Name": "IscsiTgtBoot", "Value": "Enabled", "Set On Import": "True", "Comment": "Read and Write" }, { "Name": "DhcpVendId", "Value": "BRCM ISAN", "Set On Import": "True", "Comment": "Read and Write" }, { "Name": "LnkUpDelayTime", "Value": "0", "Set On Import": "True", "Comment": "Read and Write" }, { "Name": "TcpTimestmp", "Value": "Disabled", "Set On Import": "True", "Comment": "Read and Write" }, { "Name": "FirstHddTarget", "Value": "Disabled", "Set On Import": "True", "Comment": "Read and Write" }, { "Name": "LunBusyRetryCnt", "Value": "0", "Set On Import": "True", "Comment": "Read and Write" }, { "Name": "IpVer", "Value": "IPv4", "Set On Import": "True", "Comment": "Read and Write" }, { "Name": "IscsiInitiatorIpAddr", "Value": "0.0.0.0", "Set On Import": "False", "Comment": "Read and Write" }, { "Name": "IscsiInitiatorSubnet", "Value": "0.0.0.0", "Set On Import": "False", "Comment": "Read and Write" }, { "Name": "IscsiInitiatorSubnetPrefix", "Value": "0", "Set On Import": "False", "Comment": "Read and Write" }, { "Name": "IscsiInitiatorGateway", "Value": "0.0.0.0", "Set On Import": "False", "Comment": "Read and Write" }, { "Name": "IscsiInitiatorPrimDns", "Value": "0.0.0.0", "Set On Import": "False", "Comment": "Read and Write" }, { "Name": "IscsiInitiatorSecDns", "Value": "0.0.0.0", "Set On Import": "False", "Comment": "Read and Write" }, { "Name": "IscsiInitiatorName", "Value": "iqn.1995-05.com.broadcom.iscsiboot", "Set On Import": "False", "Comment": "Read and Write" }, { "Name": "IscsiInitiatorChapId", "Value": "", "Set On Import": "False", "Comment": "Read and Write" }, { "Name": "IscsiInitiatorChapPwd", "Value": "", "Set On Import": "False", "Comment": "Read and Write" }, { "Name": "ConnectFirstTgt", "Value": "Disabled", "Set On Import": "False", "Comment": "Read and Write" }, { "Name": "FirstTgtIpAddress", "Value": "0.0.0.0", "Set On Import": "False", "Comment": "Read and Write" }, { "Name": "FirstTgtTcpPort", "Value": "3260", "Set On Import": "False", "Comment": "Read and Write" }, { "Name": "FirstTgtBootLun", "Value": "0", "Set On Import": "False", "Comment": "Read and Write" }, { "Name": "FirstTgtIscsiName", "Value": "", "Set On Import": "False", "Comment": "Read and Write" }, { "Name": "FirstTgtChapId", "Value": "", "Set On Import": "False", "Comment": "Read and Write" }, { "Name": "FirstTgtChapPwd", "Value": "", "Set On Import": "False", "Comment": "Read and Write" }, { "Name": "ConnectSecondTgt", "Value": "Disabled", "Set On Import": "False", "Comment": "Read and Write" }, { "Name": "SecondTgtIpAddress", "Value": "0.0.0.0", "Set On Import": "False", "Comment": "Read and Write" }, { "Name": "SecondTgtTcpPort", "Value": "3260", "Set On Import": "False", "Comment": "Read and Write" }, { "Name": "SecondTgtBootLun", "Value": "0", "Set On Import": "False", "Comment": "Read and Write" }, { "Name": "SecondTgtIscsiName", "Value": "", "Set On Import": "False", "Comment": "Read and Write" }, { "Name": "SecondTgtChapId", "Value": "", "Set On Import": "False", "Comment": "Read and Write" }, { "Name": "SecondTgtChapPwd", "Value": "", "Set On Import": "False", "Comment": "Read and Write" }, { "Name": "SecondaryDeviceMacAddr", "Value": "00:00:00:00:00:00", "Set On Import": "False", "Comment": "Read and Write" }, { "Name": "UseIndTgtPortal", "Value": "Disabled", "Set On Import": "False", "Comment": "Read and Write" }, { "Name": "UseIndTgtName", "Value": "Disabled", "Set On Import": "False", "Comment": "Read and Write" }, { "Name": "BootOptionROM", "Value": "Enabled", "Set On Import": "True", "Comment": "Read and Write" }, { "Name": "LegacyBootProto", "Value": "NONE", "Set On Import": "True", "Comment": "Read and Write" }, { "Name": "BootStrapType", "Value": "AutoDetect", "Set On Import": "True", "Comment": "Read and Write" }, { "Name": "HideSetupPrompt", "Value": "Disabled", "Set On Import": "True", "Comment": "Read and Write" }, { "Name": "BannerMessageTimeout", "Value": "5", "Set On Import": "True", "Comment": "Read and Write" }, { "Name": "LnkSpeed", "Value": "AutoNeg", "Set On Import": "True", "Comment": "Read and Write" }, { "Name": "WakeOnLan", "Value": "Disabled", "Set On Import": "True", "Comment": "Read and Write" }, { "Name": "VLanMode", "Value": "Disabled", "Set On Import": "True", "Comment": "Read and Write" }, { "Name": "VLanId", "Value": "1", "Set On Import": "False", "Comment": "Read and Write" }, { "Name": "PermitTotalPortShutdown", "Value": "Disabled", "Set On Import": "True", "Comment": "Read and Write" } ] }, { "FQDD": "NIC.Slot.1-2-1", "Attributes": [ { "Name": "BlnkLeds", "Value": "0", "Set On Import": "True", "Comment": "Read and Write" }, { "Name": "VirtMacAddr", "Value": "00:00:00:00:00:00", "Set On Import": "False", "Comment": "Read and Write" }, { "Name": "VirtualizationMode", "Value": "NONE", "Set On Import": "True", "Comment": "Read and Write" }, { "Name": "NParEP", "Value": "Disabled", "Set On Import": "False", "Comment": "Read and Write" }, { "Name": "LegacyBootProto", "Value": "NONE", "Set On Import": "True", "Comment": "Read and Write" }, { "Name": "VLanId", "Value": "0", "Set On Import": "False", "Comment": "Read and Write" }, { "Name": "NumberVFAdvertised", "Value": "64", "Set On Import": "False", "Comment": "Read and Write" }, { "Name": "INTEL_LLDPAgent", "Value": "Enabled", "Set On Import": "True", "Comment": "Read and Write" }, { "Name": "TcpIpViaDHCP", "Value": "Disabled", "Set On Import": "True", "Comment": "Read and Write" }, { "Name": "IscsiViaDHCP", "Value": "Disabled", "Set On Import": "False", "Comment": "Read and Write" }, { "Name": "ChapAuthEnable", "Value": "Disabled", "Set On Import": "True", "Comment": "Read and Write" }, { "Name": "ChapMutualAuth", "Value": "Disabled", "Set On Import": "False", "Comment": "Read and Write" }, { "Name": "IscsiInitiatorIpAddr", "Value": "0.0.0.0", "Set On Import": "False", "Comment": "Read and Write" }, { "Name": "IscsiInitiatorSubnet", "Value": "0.0.0.0", "Set On Import": "False", "Comment": "Read and Write" }, { "Name": "IscsiInitiatorGateway", "Value": "0.0.0.0", "Set On Import": "False", "Comment": "Read and Write" }, { "Name": "IscsiInitiatorName", "Value": "", "Set On Import": "False", "Comment": "Read and Write" }, { "Name": "IscsiInitiatorChapId", "Value": "", "Set On Import": "False", "Comment": "Read and Write" }, { "Name": "IscsiInitiatorChapPwd", "Value": "", "Set On Import": "False", "Comment": "Read and Write" }, { "Name": "FirstTgtIpAddress", "Value": "0.0.0.0", "Set On Import": "False", "Comment": "Read and Write" }, { "Name": "FirstTgtTcpPort", "Value": "3260", "Set On Import": "False", "Comment": "Read and Write" }, { "Name": "FirstTgtBootLun", "Value": "0", "Set On Import": "False", "Comment": "Read and Write" }, { "Name": "FirstTgtIscsiName", "Value": "", "Set On Import": "False", "Comment": "Read and Write" }, { "Name": "FirstTgtChapPwd", "Value": "", "Set On Import": "False", "Comment": "Read and Write" }, { "Name": "VFDistribution", "Value": "64:0:0:0:0:0:0:0", "Set On Import": "False", "Comment": "Read and Write" } ] }, { "FQDD": "NIC.Slot.1-1-1", "Attributes": [ { "Name": "BlnkLeds", "Value": "0", "Set On Import": "True", "Comment": "Read and Write" }, { "Name": "VirtMacAddr", "Value": "00:00:00:00:00:00", "Set On Import": "False", "Comment": "Read and Write" }, { "Name": "VirtualizationMode", "Value": "NONE", "Set On Import": "True", "Comment": "Read and Write" }, { "Name": "NParEP", "Value": "Disabled", "Set On Import": "False", "Comment": "Read and Write" }, { "Name": "LegacyBootProto", "Value": "NONE", "Set On Import": "True", "Comment": "Read and Write" }, { "Name": "VLanId", "Value": "0", "Set On Import": "False", "Comment": "Read and Write" }, { "Name": "NumberVFAdvertised", "Value": "64", "Set On Import": "False", "Comment": "Read and Write" }, { "Name": "INTEL_LLDPAgent", "Value": "Enabled", "Set On Import": "True", "Comment": "Read and Write" }, { "Name": "TcpIpViaDHCP", "Value": "Disabled", "Set On Import": "True", "Comment": "Read and Write" }, { "Name": "IscsiViaDHCP", "Value": "Disabled", "Set On Import": "False", "Comment": "Read and Write" }, { "Name": "ChapAuthEnable", "Value": "Disabled", "Set On Import": "True", "Comment": "Read and Write" }, { "Name": "ChapMutualAuth", "Value": "Disabled", "Set On Import": "False", "Comment": "Read and Write" }, { "Name": "IscsiInitiatorIpAddr", "Value": "0.0.0.0", "Set On Import": "False", "Comment": "Read and Write" }, { "Name": "IscsiInitiatorSubnet", "Value": "0.0.0.0", "Set On Import": "False", "Comment": "Read and Write" }, { "Name": "IscsiInitiatorGateway", "Value": "0.0.0.0", "Set On Import": "False", "Comment": "Read and Write" }, { "Name": "IscsiInitiatorName", "Value": "", "Set On Import": "False", "Comment": "Read and Write" }, { "Name": "IscsiInitiatorChapId", "Value": "", "Set On Import": "False", "Comment": "Read and Write" }, { "Name": "IscsiInitiatorChapPwd", "Value": "", "Set On Import": "False", "Comment": "Read and Write" }, { "Name": "FirstTgtIpAddress", "Value": "0.0.0.0", "Set On Import": "False", "Comment": "Read and Write" }, { "Name": "FirstTgtTcpPort", "Value": "3260", "Set On Import": "False", "Comment": "Read and Write" }, { "Name": "FirstTgtBootLun", "Value": "0", "Set On Import": "False", "Comment": "Read and Write" }, { "Name": "FirstTgtIscsiName", "Value": "", "Set On Import": "False", "Comment": "Read and Write" }, { "Name": "FirstTgtChapPwd", "Value": "", "Set On Import": "False", "Comment": "Read and Write" }, { "Name": "VFDistribution", "Value": "64:0:0:0:0:0:0:0", "Set On Import": "False", "Comment": "Read and Write" } ] }, { "FQDD": "NIC.Embedded.2-1-1", "Attributes": [ { "Name": "BlnkLeds", "Value": "0", "Set On Import": "True", "Comment": "Read and Write" }, { "Name": "EEEControl", "Value": "Enabled", "Set On Import": "True", "Comment": "Read and Write" }, { "Name": "VirtMacAddr", "Value": "F4:02:70:B8:A6:7B", "Set On Import": "False", "Comment": "Read and Write" }, { "Name": "TcpIpViaDHCP", "Value": "Enabled", "Set On Import": "True", "Comment": "Read and Write" }, { "Name": "IpAutoConfig", "Value": "Enabled", "Set On Import": "True", "Comment": "Read and Write" }, { "Name": "IscsiViaDHCP", "Value": "Disabled", "Set On Import": "True", "Comment": "Read and Write" }, { "Name": "ChapAuthEnable", "Value": "Disabled", "Set On Import": "True", "Comment": "Read and Write" }, { "Name": "IscsiTgtBoot", "Value": "Enabled", "Set On Import": "True", "Comment": "Read and Write" }, { "Name": "DhcpVendId", "Value": "BRCM ISAN", "Set On Import": "True", "Comment": "Read and Write" }, { "Name": "LnkUpDelayTime", "Value": "0", "Set On Import": "True", "Comment": "Read and Write" }, { "Name": "TcpTimestmp", "Value": "Disabled", "Set On Import": "True", "Comment": "Read and Write" }, { "Name": "FirstHddTarget", "Value": "Disabled", "Set On Import": "True", "Comment": "Read and Write" }, { "Name": "LunBusyRetryCnt", "Value": "0", "Set On Import": "True", "Comment": "Read and Write" }, { "Name": "IpVer", "Value": "IPv4", "Set On Import": "True", "Comment": "Read and Write" }, { "Name": "IscsiInitiatorIpAddr", "Value": "0.0.0.0", "Set On Import": "False", "Comment": "Read and Write" }, { "Name": "IscsiInitiatorSubnet", "Value": "0.0.0.0", "Set On Import": "False", "Comment": "Read and Write" }, { "Name": "IscsiInitiatorSubnetPrefix", "Value": "0", "Set On Import": "False", "Comment": "Read and Write" }, { "Name": "IscsiInitiatorGateway", "Value": "0.0.0.0", "Set On Import": "False", "Comment": "Read and Write" }, { "Name": "IscsiInitiatorPrimDns", "Value": "0.0.0.0", "Set On Import": "False", "Comment": "Read and Write" }, { "Name": "IscsiInitiatorSecDns", "Value": "0.0.0.0", "Set On Import": "False", "Comment": "Read and Write" }, { "Name": "IscsiInitiatorName", "Value": "iqn.1995-05.com.broadcom.iscsiboot", "Set On Import": "False", "Comment": "Read and Write" }, { "Name": "IscsiInitiatorChapId", "Value": "", "Set On Import": "False", "Comment": "Read and Write" }, { "Name": "IscsiInitiatorChapPwd", "Value": "", "Set On Import": "False", "Comment": "Read and Write" }, { "Name": "ConnectFirstTgt", "Value": "Disabled", "Set On Import": "False", "Comment": "Read and Write" }, { "Name": "FirstTgtIpAddress", "Value": "0.0.0.0", "Set On Import": "False", "Comment": "Read and Write" }, { "Name": "FirstTgtTcpPort", "Value": "3260", "Set On Import": "False", "Comment": "Read and Write" }, { "Name": "FirstTgtBootLun", "Value": "0", "Set On Import": "False", "Comment": "Read and Write" }, { "Name": "FirstTgtIscsiName", "Value": "", "Set On Import": "False", "Comment": "Read and Write" }, { "Name": "FirstTgtChapId", "Value": "", "Set On Import": "False", "Comment": "Read and Write" }, { "Name": "FirstTgtChapPwd", "Value": "", "Set On Import": "False", "Comment": "Read and Write" }, { "Name": "ConnectSecondTgt", "Value": "Disabled", "Set On Import": "False", "Comment": "Read and Write" }, { "Name": "SecondTgtIpAddress", "Value": "0.0.0.0", "Set On Import": "False", "Comment": "Read and Write" }, { "Name": "SecondTgtTcpPort", "Value": "3260", "Set On Import": "False", "Comment": "Read and Write" }, { "Name": "SecondTgtBootLun", "Value": "0", "Set On Import": "False", "Comment": "Read and Write" }, { "Name": "SecondTgtIscsiName", "Value": "", "Set On Import": "False", "Comment": "Read and Write" }, { "Name": "SecondTgtChapId", "Value": "", "Set On Import": "False", "Comment": "Read and Write" }, { "Name": "SecondTgtChapPwd", "Value": "", "Set On Import": "False", "Comment": "Read and Write" }, { "Name": "SecondaryDeviceMacAddr", "Value": "00:00:00:00:00:00", "Set On Import": "False", "Comment": "Read and Write" }, { "Name": "UseIndTgtPortal", "Value": "Disabled", "Set On Import": "False", "Comment": "Read and Write" }, { "Name": "UseIndTgtName", "Value": "Disabled", "Set On Import": "False", "Comment": "Read and Write" }, { "Name": "BootOptionROM", "Value": "Enabled", "Set On Import": "True", "Comment": "Read and Write" }, { "Name": "LegacyBootProto", "Value": "NONE", "Set On Import": "True", "Comment": "Read and Write" }, { "Name": "BootStrapType", "Value": "AutoDetect", "Set On Import": "True", "Comment": "Read and Write" }, { "Name": "HideSetupPrompt", "Value": "Disabled", "Set On Import": "True", "Comment": "Read and Write" }, { "Name": "BannerMessageTimeout", "Value": "5", "Set On Import": "True", "Comment": "Read and Write" }, { "Name": "LnkSpeed", "Value": "AutoNeg", "Set On Import": "True", "Comment": "Read and Write" }, { "Name": "WakeOnLan", "Value": "Disabled", "Set On Import": "True", "Comment": "Read and Write" }, { "Name": "VLanMode", "Value": "Disabled", "Set On Import": "True", "Comment": "Read and Write" }, { "Name": "VLanId", "Value": "1", "Set On Import": "False", "Comment": "Read and Write" }, { "Name": "PermitTotalPortShutdown", "Value": "Disabled", "Set On Import": "True", "Comment": "Read and Write" } ] }, { "FQDD": "NIC.Slot.2-2-1", "Attributes": [ { "Name": "BlnkLeds", "Value": "0", "Set On Import": "True", "Comment": "Read and Write" }, { "Name": "VirtMacAddr", "Value": "00:00:00:00:00:00", "Set On Import": "False", "Comment": "Read and Write" }, { "Name": "VirtualizationMode", "Value": "NONE", "Set On Import": "True", "Comment": "Read and Write" }, { "Name": "NParEP", "Value": "Disabled", "Set On Import": "False", "Comment": "Read and Write" }, { "Name": "LegacyBootProto", "Value": "NONE", "Set On Import": "True", "Comment": "Read and Write" }, { "Name": "VLanId", "Value": "0", "Set On Import": "False", "Comment": "Read and Write" }, { "Name": "NumberVFAdvertised", "Value": "64", "Set On Import": "False", "Comment": "Read and Write" }, { "Name": "INTEL_LLDPAgent", "Value": "Enabled", "Set On Import": "True", "Comment": "Read and Write" }, { "Name": "TcpIpViaDHCP", "Value": "Disabled", "Set On Import": "True", "Comment": "Read and Write" }, { "Name": "IscsiViaDHCP", "Value": "Disabled", "Set On Import": "False", "Comment": "Read and Write" }, { "Name": "ChapAuthEnable", "Value": "Disabled", "Set On Import": "True", "Comment": "Read and Write" }, { "Name": "ChapMutualAuth", "Value": "Disabled", "Set On Import": "False", "Comment": "Read and Write" }, { "Name": "IscsiInitiatorIpAddr", "Value": "0.0.0.0", "Set On Import": "False", "Comment": "Read and Write" }, { "Name": "IscsiInitiatorSubnet", "Value": "0.0.0.0", "Set On Import": "False", "Comment": "Read and Write" }, { "Name": "IscsiInitiatorGateway", "Value": "0.0.0.0", "Set On Import": "False", "Comment": "Read and Write" }, { "Name": "IscsiInitiatorName", "Value": "", "Set On Import": "False", "Comment": "Read and Write" }, { "Name": "IscsiInitiatorChapId", "Value": "", "Set On Import": "False", "Comment": "Read and Write" }, { "Name": "IscsiInitiatorChapPwd", "Value": "", "Set On Import": "False", "Comment": "Read and Write" }, { "Name": "FirstTgtIpAddress", "Value": "0.0.0.0", "Set On Import": "False", "Comment": "Read and Write" }, { "Name": "FirstTgtTcpPort", "Value": "3260", "Set On Import": "False", "Comment": "Read and Write" }, { "Name": "FirstTgtBootLun", "Value": "0", "Set On Import": "False", "Comment": "Read and Write" }, { "Name": "FirstTgtIscsiName", "Value": "", "Set On Import": "False", "Comment": "Read and Write" }, { "Name": "FirstTgtChapPwd", "Value": "", "Set On Import": "False", "Comment": "Read and Write" }, { "Name": "VFDistribution", "Value": "64:0:0:0:0:0:0:0", "Set On Import": "False", "Comment": "Read and Write" } ] }, { "FQDD": "NIC.Slot.2-1-1", "Attributes": [ { "Name": "BlnkLeds", "Value": "0", "Set On Import": "True", "Comment": "Read and Write" }, { "Name": "VirtMacAddr", "Value": "00:00:00:00:00:00", "Set On Import": "False", "Comment": "Read and Write" }, { "Name": "VirtualizationMode", "Value": "NONE", "Set On Import": "True", "Comment": "Read and Write" }, { "Name": "NParEP", "Value": "Disabled", "Set On Import": "False", "Comment": "Read and Write" }, { "Name": "LegacyBootProto", "Value": "NONE", "Set On Import": "True", "Comment": "Read and Write" }, { "Name": "VLanId", "Value": "0", "Set On Import": "False", "Comment": "Read and Write" }, { "Name": "NumberVFAdvertised", "Value": "64", "Set On Import": "False", "Comment": "Read and Write" }, { "Name": "INTEL_LLDPAgent", "Value": "Enabled", "Set On Import": "True", "Comment": "Read and Write" }, { "Name": "TcpIpViaDHCP", "Value": "Disabled", "Set On Import": "True", "Comment": "Read and Write" }, { "Name": "IscsiViaDHCP", "Value": "Disabled", "Set On Import": "False", "Comment": "Read and Write" }, { "Name": "ChapAuthEnable", "Value": "Disabled", "Set On Import": "True", "Comment": "Read and Write" }, { "Name": "ChapMutualAuth", "Value": "Disabled", "Set On Import": "False", "Comment": "Read and Write" }, { "Name": "IscsiInitiatorIpAddr", "Value": "0.0.0.0", "Set On Import": "False", "Comment": "Read and Write" }, { "Name": "IscsiInitiatorSubnet", "Value": "0.0.0.0", "Set On Import": "False", "Comment": "Read and Write" }, { "Name": "IscsiInitiatorGateway", "Value": "0.0.0.0", "Set On Import": "False", "Comment": "Read and Write" }, { "Name": "IscsiInitiatorName", "Value": "", "Set On Import": "False", "Comment": "Read and Write" }, { "Name": "IscsiInitiatorChapId", "Value": "", "Set On Import": "False", "Comment": "Read and Write" }, { "Name": "IscsiInitiatorChapPwd", "Value": "", "Set On Import": "False", "Comment": "Read and Write" }, { "Name": "FirstTgtIpAddress", "Value": "0.0.0.0", "Set On Import": "False", "Comment": "Read and Write" }, { "Name": "FirstTgtTcpPort", "Value": "3260", "Set On Import": "False", "Comment": "Read and Write" }, { "Name": "FirstTgtBootLun", "Value": "0", "Set On Import": "False", "Comment": "Read and Write" }, { "Name": "FirstTgtIscsiName", "Value": "", "Set On Import": "False", "Comment": "Read and Write" }, { "Name": "FirstTgtChapPwd", "Value": "", "Set On Import": "False", "Comment": "Read and Write" }, { "Name": "VFDistribution", "Value": "64:0:0:0:0:0:0:0", "Set On Import": "False", "Comment": "Read and Write" } ] } ] } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1631521128.0 sushy-oem-idrac-3.0.1/sushy_oem_idrac/tests/unit/json_samples/idrac_card_service.json0000664000175000017500000000131300000000000031226 0ustar00zuulzuul00000000000000{ "@odata.context": "/redfish/v1/$metadata#DelliDRACCard.DelliDRACCardService", "@odata.id": "/redfish/v1/Dell/Managers/iDRAC.Embedded.1/DelliDRACCardService", "@odata.type": "#DelliDRACCardService.v1_1_0.DelliDRACCardService", "Actions": { "#DelliDRACCardService.iDRACReset": { "Force@Redfish.AllowableValues": [ "Graceful", "Force" ], "target": "/redfish/v1/Dell/Managers/iDRAC.Embedded.1/DelliDRACCardService/Actions/DelliDRACCardService.iDRACReset" } }, "Description": "The DelliDRACCardService resource provides some actions to support iDRAC configurations.", "Id": "DelliDRACCardService", "Name": "DelliDRACCardService" } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1631521128.0 sushy-oem-idrac-3.0.1/sushy_oem_idrac/tests/unit/json_samples/job_collection_expanded.json0000664000175000017500000000221600000000000032273 0ustar00zuulzuul00000000000000{ "@odata.context": "/redfish/v1/$metadata#DellJobCollection.DellJobCollection", "@odata.id": "/redfish/v1/Managers/iDRAC.Embedded.1/Jobs", "@odata.type": "#DellJobCollection.DellJobCollection", "Description": "Collection of Job Instances", "Id": "JobQueue", "Members": [ { "@odata.context": "/redfish/v1/$metadata#DellJob.DellJob", "@odata.id": "/redfish/v1/Managers/iDRAC.Embedded.1/Jobs/RID_878460711202", "@odata.type": "#DellJob.v1_0_2.DellJob", "CompletionTime": "2020-04-25T15:21:33", "Description": "Job Instance", "EndTime": "TIME_NA", "Id": "RID_878460711202", "JobState": "Running", "JobType": "RebootForce", "Message": "Reboot is complete.", "MessageArgs": [ ], "MessageArgs@odata.count": 0, "MessageId": "RED030", "Name": "Reboot3", "PercentComplete": 100, "StartTime": "TIME_NOW", "TargetSettingsURI": null } ], "Name": "JobQueue" } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1631521128.0 sushy-oem-idrac-3.0.1/sushy_oem_idrac/tests/unit/json_samples/job_service.json0000664000175000017500000000107100000000000027726 0ustar00zuulzuul00000000000000{ "@odata.context": "/redfish/v1/$metadata#DellJobService.DellJobService", "@odata.id": "/redfish/v1/Dell/Managers/iDRAC.Embedded.1/DellJobService", "@odata.type": "#DellJobService.v1_1_0.DellJobService", "Actions": { "#DellJobService.DeleteJobQueue": { "target": "/redfish/v1/Dell/Managers/iDRAC.Embedded.1/DellJobService/Actions/DellJobService.DeleteJobQueue" } }, "Description": "The DellJobService resource provides some actions to support Job management functionality.", "Id": "Job Service", "Name": "DellJobService" } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1631521128.0 sushy-oem-idrac-3.0.1/sushy_oem_idrac/tests/unit/json_samples/lifecycle_service.json0000664000175000017500000000111700000000000031114 0ustar00zuulzuul00000000000000{ "@odata.context": "/redfish/v1/$metadata#DellLCService.DellLCService", "@odata.id": "/redfish/v1/Dell/Managers/iDRAC.Embedded.1/DellLCService", "@odata.type": "#DellLCService.v1_1_0.DellLCService", "Actions": { "#DellLCService.GetRemoteServicesAPIStatus": { "target": "/redfish/v1/Dell/Managers/iDRAC.Embedded.1/DellLCService/Actions/DellLCService.GetRemoteServicesAPIStatus" } }, "Description": "The DellLCService resource provides some actions to support Lifecycle Controller functionality.", "Id": "DellLCService", "Name": "DellLCService" } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1631521128.0 sushy-oem-idrac-3.0.1/sushy_oem_idrac/tests/unit/json_samples/manager.json0000664000175000017500000002405300000000000027053 0ustar00zuulzuul00000000000000{ "@odata.context": "/redfish/v1/$metadata#Manager.Manager", "@odata.id": "/redfish/v1/Managers/iDRAC.Embedded.1", "@odata.type": "#Manager.v1_3_3.Manager", "Actions": { "#Manager.Reset": { "ResetType@Redfish.AllowableValues": [ "GracefulRestart" ], "target": "/redfish/v1/Managers/iDRAC.Embedded.1/Actions/Manager.Reset" }, "Oem": { "DellManager.v1_0_0#DellManager.ResetToDefaults": { "ResetType@Redfish.AllowableValues": [ "All", "ResetAllWithRootDefaults", "Default" ], "target": "/redfish/v1/Managers/iDRAC.Embedded.1/Actions/Oem/DellManager.ResetToDefaults" }, "OemManager.v1_0_0#OemManager.ExportSystemConfiguration": { "ExportFormat@Redfish.AllowableValues": [ "XML", "JSON" ], "ExportUse@Redfish.AllowableValues": [ "Default", "Clone", "Replace" ], "IncludeInExport@Redfish.AllowableValues": [ "Default", "IncludeReadOnly", "IncludePasswordHashValues" ], "ShareParameters": { "IgnoreCertificateWarning@Redfish.AllowableValues": [ "Disabled", "Enabled" ], "ProxySupport@Redfish.AllowableValues": [ "Disabled", "EnabledProxyDefault", "Enabled" ], "ProxyType@Redfish.AllowableValues": [ "HTTP", "SOCKS4" ], "ShareType@Redfish.AllowableValues": [ "LOCAL", "NFS", "CIFS", "HTTP", "HTTPS" ], "Target@Redfish.AllowableValues": [ "ALL", "IDRAC", "BIOS", "NIC", "RAID" ] }, "target": "/redfish/v1/Managers/iDRAC.Embedded.1/Actions/Oem/EID_674_Manager.ExportSystemConfiguration" }, "OemManager.v1_0_0#OemManager.ImportSystemConfiguration": { "HostPowerState@Redfish.AllowableValues": [ "On", "Off" ], "ImportSystemConfiguration@Redfish.AllowableValues": [ "TimeToWait", "ImportBuffer" ], "ShareParameters": { "IgnoreCertificateWarning@Redfish.AllowableValues": [ "Disabled", "Enabled" ], "ProxySupport@Redfish.AllowableValues": [ "Disabled", "EnabledProxyDefault", "Enabled" ], "ProxyType@Redfish.AllowableValues": [ "HTTP", "SOCKS4" ], "ShareType@Redfish.AllowableValues": [ "LOCAL", "NFS", "CIFS", "HTTP", "HTTPS" ], "Target@Redfish.AllowableValues": [ "ALL", "IDRAC", "BIOS", "NIC", "RAID" ] }, "ShutdownType@Redfish.AllowableValues": [ "Graceful", "Forced", "NoReboot" ], "target": "/redfish/v1/Managers/iDRAC.Embedded.1/Actions/Oem/EID_674_Manager.ImportSystemConfiguration" }, "OemManager.v1_0_0#OemManager.ImportSystemConfigurationPreview": { "ImportSystemConfigurationPreview@Redfish.AllowableValues": [ "ImportBuffer" ], "ShareParameters": { "IgnoreCertificateWarning@Redfish.AllowableValues": [ "Disabled", "Enabled" ], "ProxySupport@Redfish.AllowableValues": [ "Disabled", "EnabledProxyDefault", "Enabled" ], "ProxyType@Redfish.AllowableValues": [ "HTTP", "SOCKS4" ], "ShareType@Redfish.AllowableValues": [ "LOCAL", "NFS", "CIFS", "HTTP", "HTTPS" ], "Target@Redfish.AllowableValues": [ "ALL" ] }, "target": "/redfish/v1/Managers/iDRAC.Embedded.1/Actions/Oem/EID_674_Manager.ImportSystemConfigurationPreview" } } }, "CommandShell": { "ConnectTypesSupported": [ "SSH", "Telnet", "IPMI" ], "ConnectTypesSupported@odata.count": 3, "MaxConcurrentSessions": 5, "ServiceEnabled": true }, "DateTime": "2019-08-07T12:47:37-04:00", "DateTimeLocalOffset": "-04:00", "Description": "BMC", "EthernetInterfaces": { "@odata.id": "/redfish/v1/Managers/iDRAC.Embedded.1/EthernetInterfaces" }, "FirmwareVersion": "3.34.34.34", "GraphicalConsole": { "ConnectTypesSupported": [ "KVMIP" ], "ConnectTypesSupported@odata.count": 1, "MaxConcurrentSessions": 6, "ServiceEnabled": true }, "HostInterfaces": { "@odata.id": "/redfish/v1/Managers/iDRAC.Embedded.1/HostInterfaces" }, "Id": "iDRAC.Embedded.1", "Links": { "ManagerForChassis": [ { "@odata.id": "/redfish/v1/Chassis/System.Embedded.1" } ], "ManagerForChassis@odata.count": 1, "ManagerForServers": [ { "@odata.id": "/redfish/v1/Systems/System.Embedded.1" } ], "ManagerForServers@odata.count": 1, "ManagerInChassis": { "@odata.id": "/redfish/v1/Chassis/System.Embedded.1" }, "Oem": { "Dell": { "DellAttributes": [ { "@odata.id": "/redfish/v1/Managers/iDRAC.Embedded.1/Attributes" }, { "@odata.id": "/redfish/v1/Managers/System.Embedded.1/Attributes" }, { "@odata.id": "/redfish/v1/Managers/LifecycleController.Embedded.1/Attributes" } ], "DellAttributes@odata.count": 3, "DellJobService": { "@odata.id": "/redfish/v1/Dell/Managers/iDRAC.Embedded.1/DellJobService" }, "DellLCService": { "@odata.id": "/redfish/v1/Dell/Managers/iDRAC.Embedded.1/DellLCService" }, "DellLicenseCollection": { "@odata.id": "/redfish/v1/Dell/Managers/iDRAC.Embedded.1/DellLicenseCollection" }, "DellLicenseManagementService": { "@odata.id": "/redfish/v1/Dell/Managers/iDRAC.Embedded.1/DellLicenseManagementService" }, "DellPersistentStorageService": { "@odata.id": "/redfish/v1/Dell/Managers/iDRAC.Embedded.1/DellPersistentStorageService" }, "DellSwitchConnectionCollection": { "@odata.id": "/redfish/v1/Dell/Systems/System.Embedded.1/NetworkPorts/DellSwitchConnectionCollection" }, "DelliDRACCardService": { "@odata.id": "/redfish/v1/Dell/Managers/iDRAC.Embedded.1/DelliDRACCardService" }, "DellvFlashCollection": { "@odata.id": "/redfish/v1/Dell/Managers/iDRAC.Embedded.1/DellvFlashCollection" }, "Jobs": { "@odata.id": "/redfish/v1/Managers/iDRAC.Embedded.1/Jobs" } } } }, "LogServices": { "@odata.id": "/redfish/v1/Managers/iDRAC.Embedded.1/LogServices" }, "ManagerType": "BMC", "Model": "14G Monolithic", "Name": "Manager", "NetworkProtocol": { "@odata.id": "/redfish/v1/Managers/iDRAC.Embedded.1/NetworkProtocol" }, "Oem": { "Dell": { "DelliDRACCard": { "@odata.context": "/redfish/v1/$metadata#DelliDRACCard.DelliDRACCard", "@odata.id": "/redfish/v1/Dell/Managers/iDRAC.Embedded.1/DelliDRACCard/iDRAC.Embedded.1-1%23IDRACinfo", "@odata.type": "#DelliDRACCard.v1_0_0.DelliDRACCard", "IPMIVersion": "2.0", "URLString": "https://10.19.133.11:443" } } }, "PowerState": "On", "Redundancy": [], "Redundancy@odata.count": 0, "SerialConsole": { "ConnectTypesSupported": [], "ConnectTypesSupported@odata.count": 0, "MaxConcurrentSessions": 0, "ServiceEnabled": false }, "SerialInterfaces": { "@odata.id": "/redfish/v1/Managers/iDRAC.Embedded.1/SerialInterfaces" }, "Status": { "Health": "OK", "State": "Enabled" }, "UUID": "3256444f-c0c7-3780-5310-00544c4c4544", "VirtualMedia": { "@odata.id": "/redfish/v1/Managers/iDRAC.Embedded.1/VirtualMedia" } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1631521128.0 sushy-oem-idrac-3.0.1/sushy_oem_idrac/tests/unit/json_samples/manager_collection.json0000664000175000017500000000056600000000000031271 0ustar00zuulzuul00000000000000{ "@odata.context": "/redfish/v1/$metadata#ManagerCollection.ManagerCollection", "@odata.id": "/redfish/v1/Managers", "@odata.type": "#ManagerCollection.ManagerCollection", "Description": "BMC", "Members": [ { "@odata.id": "/redfish/v1/Managers/iDRAC.Embedded.1" } ], "Members@odata.count": 1, "Name": "Manager" } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1631521128.0 sushy-oem-idrac-3.0.1/sushy_oem_idrac/tests/unit/json_samples/raid_service.json0000664000175000017500000002260600000000000030102 0ustar00zuulzuul00000000000000{ "@odata.context": "/redfish/v1/$metadata#DellRaidService.DellRaidService", "@odata.id": "/redfish/v1/Systems/System.Embedded.1/Oem/Dell/DellRaidService", "@odata.type": "#DellRaidService.v1_3_0.DellRaidService", "Actions": { "#DellRaidService.AssignSpare": { "target": "/redfish/v1/Systems/System.Embedded.1/Oem/Dell/DellRaidService/Actions/DellRaidService.AssignSpare" }, "#DellRaidService.BlinkTarget": { "target": "/redfish/v1/Systems/System.Embedded.1/Oem/Dell/DellRaidService/Actions/DellRaidService.BlinkTarget" }, "#DellRaidService.CancelBackgroundInitialization": { "target": "/redfish/v1/Systems/System.Embedded.1/Oem/Dell/DellRaidService/Actions/DellRaidService.CancelBackgroundInitialization" }, "#DellRaidService.CancelCheckConsistency": { "target": "/redfish/v1/Systems/System.Embedded.1/Oem/Dell/DellRaidService/Actions/DellRaidService.CancelCheckConsistency" }, "#DellRaidService.CancelRebuildPhysicalDisk": { "target": "/redfish/v1/Systems/System.Embedded.1/Oem/Dell/DellRaidService/Actions/DellRaidService.CancelRebuildPhysicalDisk" }, "#DellRaidService.ChangePDState": { "State@Redfish.AllowableValues": [ "Offline", "Online" ], "target": "/redfish/v1/Systems/System.Embedded.1/Oem/Dell/DellRaidService/Actions/DellRaidService.ChangePDState" }, "#DellRaidService.CheckVDValues": { "VDPropNameArrayIn@Redfish.AllowableValues": [ "RAIDLevel", "Size", "SpanDepth", "SpanLength", "StartingLBA", "T10PIStatus" ], "target": "/redfish/v1/Systems/System.Embedded.1/Oem/Dell/DellRaidService/Actions/DellRaidService.CheckVDValues" }, "#DellRaidService.ClearControllerPreservedCache": { "target": "/redfish/v1/Systems/System.Embedded.1/Oem/Dell/DellRaidService/Actions/DellRaidService.ClearControllerPreservedCache" }, "#DellRaidService.ClearForeignConfig": { "target": "/redfish/v1/Systems/System.Embedded.1/Oem/Dell/DellRaidService/Actions/DellRaidService.ClearForeignConfig" }, "#DellRaidService.ConvertToNonRAID": { "target": "/redfish/v1/Systems/System.Embedded.1/Oem/Dell/DellRaidService/Actions/DellRaidService.ConvertToNonRAID" }, "#DellRaidService.ConvertToRAID": { "target": "/redfish/v1/Systems/System.Embedded.1/Oem/Dell/DellRaidService/Actions/DellRaidService.ConvertToRAID" }, "#DellRaidService.EnableControllerEncryption": { "Mode@Redfish.AllowableValues": [ "DKM", "LKM", "SEKM" ], "target": "/redfish/v1/Systems/System.Embedded.1/Oem/Dell/DellRaidService/Actions/DellRaidService.EnableControllerEncryption" }, "#DellRaidService.GetAvailableDisks": { "BlockSizeInBytes@Redfish.AllowableValues": [ "4096", "512", "All" ], "DiskEncrypt@Redfish.AllowableValues": [ "All", "FDE", "NonFDE" ], "DiskType@Redfish.AllowableValues": [ "All", "HDD", "SSD" ], "Diskprotocol@Redfish.AllowableValues": [ "AllProtocols", "NVMe", "SAS", "SATA" ], "FormFactor@Redfish.AllowableValues": [ "All", "M.2" ], "RaidLevel@Redfish.AllowableValues": [ "NoRAID", "RAID0", "RAID1", "RAID10", "RAID5", "RAID50", "RAID6", "RAID60" ], "T10PIStatus@Redfish.AllowableValues": [ "All", "T10PICapable", "T10PIIncapable" ], "target": "/redfish/v1/Systems/System.Embedded.1/Oem/Dell/DellRaidService/Actions/DellRaidService.GetAvailableDisks" }, "#DellRaidService.GetDHSDisks": { "target": "/redfish/v1/Systems/System.Embedded.1/Oem/Dell/DellRaidService/Actions/DellRaidService.GetDHSDisks" }, "#DellRaidService.GetRAIDLevels": { "BlockSizeInBytes@Redfish.AllowableValues": [ "4096", "512", "All" ], "DiskEncrypt@Redfish.AllowableValues": [ "All", "FDE", "NonFDE" ], "DiskType@Redfish.AllowableValues": [ "All", "HDD", "SSD" ], "Diskprotocol@Redfish.AllowableValues": [ "AllProtocols", "NVMe", "SAS", "SATA" ], "FormFactor@Redfish.AllowableValues": [ "All", "M.2" ], "T10PIStatus@Redfish.AllowableValues": [ "All", "T10PICapable", "T10PIIncapable" ], "target": "/redfish/v1/Systems/System.Embedded.1/Oem/Dell/DellRaidService/Actions/DellRaidService.GetRAIDLevels" }, "#DellRaidService.ImportForeignConfig": { "target": "/redfish/v1/Systems/System.Embedded.1/Oem/Dell/DellRaidService/Actions/DellRaidService.ImportForeignConfig" }, "#DellRaidService.LockVirtualDisk": { "target": "/redfish/v1/Systems/System.Embedded.1/Oem/Dell/DellRaidService/Actions/DellRaidService.LockVirtualDisk" }, "#DellRaidService.OnlineCapacityExpansion": { "target": "/redfish/v1/Systems/System.Embedded.1/Oem/Dell/DellRaidService/Actions/DellRaidService.OnlineCapacityExpansion" }, "#DellRaidService.PrepareToRemove": { "target": "/redfish/v1/Systems/System.Embedded.1/Oem/Dell/DellRaidService/Actions/DellRaidService.PrepareToRemove" }, "#DellRaidService.RAIDLevelMigration": { "NewRaidLevel@Redfish.AllowableValues": [ "NoRAID", "RAID0", "RAID1", "RAID10", "RAID5", "RAID50", "RAID6", "RAID60" ], "target": "/redfish/v1/Systems/System.Embedded.1/Oem/Dell/DellRaidService/Actions/DellRaidService.RAIDLevelMigration" }, "#DellRaidService.ReKey": { "Mode@Redfish.AllowableValues": [ "LKM", "SEKM" ], "target": "/redfish/v1/Systems/System.Embedded.1/Oem/Dell/DellRaidService/Actions/DellRaidService.ReKey" }, "#DellRaidService.RebuildPhysicalDisk": { "target": "/redfish/v1/Systems/System.Embedded.1/Oem/Dell/DellRaidService/Actions/DellRaidService.RebuildPhysicalDisk" }, "#DellRaidService.RemoveControllerKey": { "target": "/redfish/v1/Systems/System.Embedded.1/Oem/Dell/DellRaidService/Actions/DellRaidService.RemoveControllerKey" }, "#DellRaidService.RenameVD": { "target": "/redfish/v1/Systems/System.Embedded.1/Oem/Dell/DellRaidService/Actions/DellRaidService.RenameVD" }, "#DellRaidService.ReplacePhysicalDisk": { "target": "/redfish/v1/Systems/System.Embedded.1/Oem/Dell/DellRaidService/Actions/DellRaidService.ReplacePhysicalDisk" }, "#DellRaidService.ResetConfig": { "target": "/redfish/v1/Systems/System.Embedded.1/Oem/Dell/DellRaidService/Actions/DellRaidService.ResetConfig" }, "#DellRaidService.SetAssetName": { "target": "/redfish/v1/Systems/System.Embedded.1/Oem/Dell/DellRaidService/Actions/DellRaidService.SetAssetName" }, "#DellRaidService.SetBootVD": { "target": "/redfish/v1/Systems/System.Embedded.1/Oem/Dell/DellRaidService/Actions/DellRaidService.SetBootVD" }, "#DellRaidService.SetControllerKey": { "target": "/redfish/v1/Systems/System.Embedded.1/Oem/Dell/DellRaidService/Actions/DellRaidService.SetControllerKey" }, "#DellRaidService.StartPatrolRead": { "target": "/redfish/v1/Systems/System.Embedded.1/Oem/Dell/DellRaidService/Actions/DellRaidService.StartPatrolRead" }, "#DellRaidService.StopPatrolRead": { "target": "/redfish/v1/Systems/System.Embedded.1/Oem/Dell/DellRaidService/Actions/DellRaidService.StopPatrolRead" }, "#DellRaidService.UnBlinkTarget": { "target": "/redfish/v1/Systems/System.Embedded.1/Oem/Dell/DellRaidService/Actions/DellRaidService.UnBlinkTarget" }, "#DellRaidService.UnLockSecureForeignConfig": { "target": "/redfish/v1/Systems/System.Embedded.1/Oem/Dell/DellRaidService/Actions/DellRaidService.UnLockSecureForeignConfig" }, "#DellRaidService.UnassignSpare": { "target": "/redfish/v1/Systems/System.Embedded.1/Oem/Dell/DellRaidService/Actions/DellRaidService.UnassignSpare" } }, "Description": "The DellRaidService resource provides some actions to support RAID functionality.", "Id": "DellRaidService", "Name": "DellRaidService" }././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1631521128.0 sushy-oem-idrac-3.0.1/sushy_oem_idrac/tests/unit/json_samples/root.json0000664000175000017500000000352200000000000026422 0ustar00zuulzuul00000000000000{ "@odata.context": "/redfish/v1/$metadata#ServiceRoot.ServiceRoot", "@odata.id": "/redfish/v1", "@odata.type": "#ServiceRoot.v1_3_0.ServiceRoot", "AccountService": { "@odata.id": "/redfish/v1/Managers/iDRAC.Embedded.1/AccountService" }, "Chassis": { "@odata.id": "/redfish/v1/Chassis" }, "Description": "Root Service", "EventService": { "@odata.id": "/redfish/v1/EventService" }, "Fabrics": { "@odata.id": "/redfish/v1/Fabrics" }, "Id": "RootService", "JsonSchemas": { "@odata.id": "/redfish/v1/JSONSchemas" }, "Links": { "Sessions": { "@odata.id": "/redfish/v1/Sessions" } }, "Managers": { "@odata.id": "/redfish/v1/Managers" }, "Name": "Root Service", "Oem": { "Dell": { "@odata.context": "/redfish/v1/$metadata#DellServiceRoot.DellServiceRoot", "@odata.type": "#DellServiceRoot.v1_0_0.ServiceRootSummary", "IsBranded": 0, "ManagerMACAddress": "4c:d9:8f:20:73:84", "ServiceTag": "GTS7DV2" } }, "Product": "Integrated Dell Remote Access Controller", "ProtocolFeaturesSupported": { "ExpandQuery": { "ExpandAll": true, "Levels": true, "Links": true, "MaxLevels": 1, "NoLinks": true }, "FilterQuery": true, "SelectQuery": true }, "RedfishVersion": "1.4.0", "Registries": { "@odata.id": "/redfish/v1/Registries" }, "SessionService": { "@odata.id": "/redfish/v1/SessionService" }, "Systems": { "@odata.id": "/redfish/v1/Systems" }, "Tasks": { "@odata.id": "/redfish/v1/TaskService" }, "UpdateService": { "@odata.id": "/redfish/v1/UpdateService" } } ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1631521128.0 sushy-oem-idrac-3.0.1/sushy_oem_idrac/tests/unit/json_samples/system.json0000664000175000017500000003515200000000000026767 0ustar00zuulzuul00000000000000{ "@odata.context": "/redfish/v1/$metadata#ComputerSystem.ComputerSystem", "@odata.id": "/redfish/v1/Systems/System.Embedded.1", "@odata.type": "#ComputerSystem.v1_10_0.ComputerSystem", "Actions": { "#ComputerSystem.Reset": { "target": "/redfish/v1/Systems/System.Embedded.1/Actions/ComputerSystem.Reset", "ResetType@Redfish.AllowableValues": [ "On", "ForceOff", "ForceRestart", "GracefulRestart", "GracefulShutdown", "PushPowerButton", "Nmi", "PowerCycle" ] } }, "AssetTag": "", "Bios": { "@odata.id": "/redfish/v1/Systems/System.Embedded.1/Bios" }, "BiosVersion": "2.10.2", "Boot": { "BootOptions": { "@odata.id": "/redfish/v1/Systems/System.Embedded.1/BootOptions" }, "Certificates": { "@odata.id": "/redfish/v1/Systems/System.Embedded.1/Boot/Certificates" }, "BootOrder": [ "Boot0006", "Boot0009", "Boot0007", "Boot0005", "Boot0003", "Boot0004", "Boot0008", "Boot0002" ], "BootOrder@odata.count": 8, "BootSourceOverrideEnabled": "Disabled", "BootSourceOverrideMode": "UEFI", "BootSourceOverrideTarget": "None", "UefiTargetBootSourceOverride": null, "BootSourceOverrideTarget@Redfish.AllowableValues": [ "None", "Pxe", "Floppy", "Cd", "Hdd", "BiosSetup", "Utilities", "UefiTarget", "SDCard", "UefiHttp" ] }, "Description": "Computer System which represents a machine (physical or virtual) and the local resources such as memory, cpu and other devices that can be accessed from that machine.", "EthernetInterfaces": { "@odata.id": "/redfish/v1/Systems/System.Embedded.1/EthernetInterfaces" }, "HostName": "", "HostWatchdogTimer": { "FunctionEnabled": false, "Status": { "State": "Disabled" }, "TimeoutAction": "None" }, "HostingRoles": [], "HostingRoles@odata.count": 0, "Id": "System.Embedded.1", "IndicatorLED": "Lit", "Links": { "Chassis": [ { "@odata.id": "/redfish/v1/Chassis/System.Embedded.1" } ], "Chassis@odata.count": 1, "CooledBy": [ { "@odata.id": "/redfish/v1/Chassis/System.Embedded.1/Thermal#/Fans/0" }, { "@odata.id": "/redfish/v1/Chassis/System.Embedded.1/Thermal#/Fans/1" }, { "@odata.id": "/redfish/v1/Chassis/System.Embedded.1/Thermal#/Fans/2" }, { "@odata.id": "/redfish/v1/Chassis/System.Embedded.1/Thermal#/Fans/3" }, { "@odata.id": "/redfish/v1/Chassis/System.Embedded.1/Thermal#/Fans/4" }, { "@odata.id": "/redfish/v1/Chassis/System.Embedded.1/Thermal#/Fans/5" }, { "@odata.id": "/redfish/v1/Chassis/System.Embedded.1/Thermal#/Fans/6" }, { "@odata.id": "/redfish/v1/Chassis/System.Embedded.1/Thermal#/Fans/7" }, { "@odata.id": "/redfish/v1/Chassis/System.Embedded.1/Thermal#/Fans/8" }, { "@odata.id": "/redfish/v1/Chassis/System.Embedded.1/Thermal#/Fans/9" }, { "@odata.id": "/redfish/v1/Chassis/System.Embedded.1/Thermal#/Fans/10" }, { "@odata.id": "/redfish/v1/Chassis/System.Embedded.1/Thermal#/Fans/11" }, { "@odata.id": "/redfish/v1/Chassis/System.Embedded.1/Thermal#/Fans/12" }, { "@odata.id": "/redfish/v1/Chassis/System.Embedded.1/Thermal#/Fans/13" }, { "@odata.id": "/redfish/v1/Chassis/System.Embedded.1/Thermal#/Fans/14" }, { "@odata.id": "/redfish/v1/Chassis/System.Embedded.1/Thermal#/Fans/15" } ], "CooledBy@odata.count": 16, "ManagedBy": [ { "@odata.id": "/redfish/v1/Managers/iDRAC.Embedded.1" } ], "ManagedBy@odata.count": 1, "Oem": { "Dell": { "@odata.type": "#DellOem.v1_1_0.DellOemLinks", "BootOrder": { "@odata.id": "/redfish/v1/Systems/System.Embedded.1/Oem/Dell/DellBootSources" }, "DellBootSources": { "@odata.id": "/redfish/v1/Systems/System.Embedded.1/Oem/Dell/DellBootSources" }, "DellSoftwareInstallationService": { "@odata.id": "/redfish/v1/Systems/System.Embedded.1/Oem/Dell/DellSoftwareInstallationService" }, "DellVideoCollection": { "@odata.id": "/redfish/v1/Systems/System.Embedded.1/Oem/Dell/DellVideo" }, "DellChassisCollection": { "@odata.id": "/redfish/v1/Chassis/System.Embedded.1/Oem/Dell/DellChassis" }, "DellPresenceAndStatusSensorCollection": { "@odata.id": "/redfish/v1/Systems/System.Embedded.1/Oem/Dell/DellPresenceAndStatusSensors" }, "DellSensorCollection": { "@odata.id": "/redfish/v1/Systems/System.Embedded.1/Oem/Dell/DellSensors" }, "DellRollupStatusCollection": { "@odata.id": "/redfish/v1/Systems/System.Embedded.1/Oem/Dell/DellRollupStatus" }, "DellPSNumericSensorCollection": { "@odata.id": "/redfish/v1/Systems/System.Embedded.1/Oem/Dell/DellPSNumericSensors" }, "DellVideoNetworkCollection": { "@odata.id": "/redfish/v1/Systems/System.Embedded.1/Oem/Dell/DellVideoNetwork" }, "DellOSDeploymentService": { "@odata.id": "/redfish/v1/Systems/System.Embedded.1/Oem/Dell/DellOSDeploymentService" }, "DellMetricService": { "@odata.id": "/redfish/v1/Systems/System.Embedded.1/Oem/Dell/DellMetricService" }, "DellGPUSensorCollection": { "@odata.id": "/redfish/v1/Systems/System.Embedded.1/Oem/Dell/DellGPUSensors" }, "DellRaidService": { "@odata.id": "/redfish/v1/Systems/System.Embedded.1/Oem/Dell/DellRaidService" }, "DellNumericSensorCollection": { "@odata.id": "/redfish/v1/Systems/System.Embedded.1/Oem/Dell/DellNumericSensors" }, "DellBIOSService": { "@odata.id": "/redfish/v1/Systems/System.Embedded.1/Oem/Dell/DellBIOSService" }, "DellSlotCollection": { "@odata.id": "/redfish/v1/Systems/System.Embedded.1/Oem/Dell/DellSlots" } } }, "PoweredBy": [ { "@odata.id": "/redfish/v1/Chassis/System.Embedded.1/Power#/PowerSupplies/0" }, { "@odata.id": "/redfish/v1/Chassis/System.Embedded.1/Power#/PowerSupplies/1" } ], "PoweredBy@odata.count": 2 }, "Manufacturer": "Dell Inc.", "Memory": { "@odata.id": "/redfish/v1/Systems/System.Embedded.1/Memory" }, "MemorySummary": { "MemoryMirroring": "System", "Status": { "Health": "OK", "HealthRollup": "OK", "State": "Enabled" }, "TotalSystemMemoryGiB": 192 }, "Model": "PowerEdge R640", "Name": "System", "NetworkInterfaces": { "@odata.id": "/redfish/v1/Systems/System.Embedded.1/NetworkInterfaces" }, "Oem": { "Dell": { "@odata.type": "#DellOem.v1_1_0.DellOemResources", "DellSystem": { "BIOSReleaseDate": "02/24/2021", "BaseBoardChassisSlot": "NA", "BatteryRollupStatus": "OK", "BladeGeometry": "NotApplicable", "CMCIP": null, "CPURollupStatus": "OK", "ChassisModel": "", "ChassisName": "Main System Chassis", "ChassisServiceTag": "8CYCZ23", "ChassisSystemHeightUnit": 1, "CurrentRollupStatus": "OK", "EstimatedExhaustTemperatureCelsius": 46, "EstimatedSystemAirflowCFM": 26, "ExpressServiceCode": "18197565051", "FanRollupStatus": "OK", "Id": "System.Embedded.1", "IDSDMRollupStatus": null, "IntrusionRollupStatus": "OK", "IsOEMBranded": "False", "LastSystemInventoryTime": "2021-06-16T09:46:25+00:00", "LastUpdateTime": "2021-05-31T15:39:10+00:00", "LicensingRollupStatus": "OK", "MaxCPUSockets": 2, "MaxDIMMSlots": 24, "MaxPCIeSlots": 3, "MemoryOperationMode": "OptimizerMode", "Name": "DellSystem", "NodeID": "8CYCZ23", "PSRollupStatus": "OK", "PlatformGUID": "33325a4f-c0b8-4380-5910-00434c4c4544", "PopulatedDIMMSlots": 12, "PopulatedPCIeSlots": 1, "PowerCapEnabledState": "Disabled", "SDCardRollupStatus": null, "SELRollupStatus": "OK", "ServerAllocationWatts": null, "StorageRollupStatus": "OK", "SysMemErrorMethodology": "Multi-bitECC", "SysMemFailOverState": "NotInUse", "SysMemLocation": "SystemBoardOrMotherboard", "SysMemPrimaryStatus": "OK", "SystemGeneration": "14G Monolithic", "SystemID": 1814, "SystemRevision": "I", "TempRollupStatus": "OK", "TempStatisticsRollupStatus": "OK", "UUID": "4c4c4544-0043-5910-8043-b8c04f5a3233", "VoltRollupStatus": "OK", "smbiosGUID": "44454c4c-4300-1059-8043-b8c04f5a3233", "@odata.context": "/redfish/v1/$metadata#DellSystem.DellSystem", "@odata.type": "#DellSystem.v1_2_0.DellSystem", "@odata.id": "/redfish/v1/Systems/System.Embedded.1/Oem/Dell/DellSystem/System.Embedded.1" } } }, "PCIeDevices": [ { "@odata.id": "/redfish/v1/Systems/System.Embedded.1/PCIeDevices/25-0" }, { "@odata.id": "/redfish/v1/Systems/System.Embedded.1/PCIeDevices/24-0" }, { "@odata.id": "/redfish/v1/Systems/System.Embedded.1/PCIeDevices/0-28" }, { "@odata.id": "/redfish/v1/Systems/System.Embedded.1/PCIeDevices/0-23" }, { "@odata.id": "/redfish/v1/Systems/System.Embedded.1/PCIeDevices/0-31" }, { "@odata.id": "/redfish/v1/Systems/System.Embedded.1/PCIeDevices/3-0" }, { "@odata.id": "/redfish/v1/Systems/System.Embedded.1/PCIeDevices/0-0" }, { "@odata.id": "/redfish/v1/Systems/System.Embedded.1/PCIeDevices/0-17" }, { "@odata.id": "/redfish/v1/Systems/System.Embedded.1/PCIeDevices/59-0" } ], "PCIeDevices@odata.count": 9, "PCIeFunctions": [ { "@odata.id": "/redfish/v1/Systems/System.Embedded.1/PCIeDevices/25-0/PCIeFunctions/25-0-1" }, { "@odata.id": "/redfish/v1/Systems/System.Embedded.1/PCIeDevices/24-0/PCIeFunctions/24-0-0" }, { "@odata.id": "/redfish/v1/Systems/System.Embedded.1/PCIeDevices/25-0/PCIeFunctions/25-0-0" }, { "@odata.id": "/redfish/v1/Systems/System.Embedded.1/PCIeDevices/0-28/PCIeFunctions/0-28-4" }, { "@odata.id": "/redfish/v1/Systems/System.Embedded.1/PCIeDevices/0-23/PCIeFunctions/0-23-0" }, { "@odata.id": "/redfish/v1/Systems/System.Embedded.1/PCIeDevices/0-31/PCIeFunctions/0-31-0" }, { "@odata.id": "/redfish/v1/Systems/System.Embedded.1/PCIeDevices/0-28/PCIeFunctions/0-28-0" }, { "@odata.id": "/redfish/v1/Systems/System.Embedded.1/PCIeDevices/3-0/PCIeFunctions/3-0-0" }, { "@odata.id": "/redfish/v1/Systems/System.Embedded.1/PCIeDevices/0-0/PCIeFunctions/0-0-0" }, { "@odata.id": "/redfish/v1/Systems/System.Embedded.1/PCIeDevices/0-17/PCIeFunctions/0-17-5" }, { "@odata.id": "/redfish/v1/Systems/System.Embedded.1/PCIeDevices/59-0/PCIeFunctions/59-0-1" }, { "@odata.id": "/redfish/v1/Systems/System.Embedded.1/PCIeDevices/59-0/PCIeFunctions/59-0-0" }, { "@odata.id": "/redfish/v1/Systems/System.Embedded.1/PCIeDevices/0-31/PCIeFunctions/0-31-4" } ], "PCIeFunctions@odata.count": 13, "PartNumber": "06NR82A02", "PowerState": "On", "ProcessorSummary": { "Count": 2, "LogicalProcessorCount": 80, "Model": "Intel(R) Xeon(R) Gold 6230 CPU @ 2.10GHz", "Status": { "Health": "OK", "HealthRollup": "OK", "State": "Enabled" } }, "Processors": { "@odata.id": "/redfish/v1/Systems/System.Embedded.1/Processors" }, "SKU": "8CYCZ23", "SecureBoot": { "@odata.id": "/redfish/v1/Systems/System.Embedded.1/SecureBoot" }, "SerialNumber": "CNIVC000180873", "SimpleStorage": { "@odata.id": "/redfish/v1/Systems/System.Embedded.1/SimpleStorage" }, "Status": { "Health": "OK", "HealthRollup": "OK", "State": "Enabled" }, "Storage": { "@odata.id": "/redfish/v1/Systems/System.Embedded.1/Storage" }, "SystemType": "Physical", "TrustedModules": [ { "FirmwareVersion": "Unknown", "InterfaceType": null, "Status": { "State": "Disabled" } } ], "TrustedModules@odata.count": 1, "UUID": "4c4c4544-0043-5910-8043-b8c04f5a3233" }././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1631521128.0 sushy-oem-idrac-3.0.1/sushy_oem_idrac/tests/unit/json_samples/task.json0000664000175000017500000000243200000000000026400 0ustar00zuulzuul00000000000000{ "@odata.context": "/redfish/v1/$metadata#Task.Task", "@odata.id": "/redfish/v1/TaskService/Tasks/JID_257309938313", "@odata.type": "#Task.v1_4_3.Task", "Description": "Server Configuration and other Tasks running on iDRAC are listed here", "Id": "JID_257309938313", "Messages": [ { "Message": "Task successfully scheduled.", "MessageArgs": [], "MessageArgs@odata.count": 0, "MessageId": "IDRAC.2.5.JCP001" } ], "Messages@odata.count": 1, "Name": "Configure: RAID.Integrated.1-1", "Oem": { "Dell": { "@odata.type": "#DellJob.v1_1_0.DellJob", "CompletionTime": null, "Description": "Job Instance", "EndTime": "TIME_NA", "Id": "JID_257309938313", "JobState": "Scheduled", "JobType": "RAIDConfiguration", "Message": "Task successfully scheduled.", "MessageArgs": [], "MessageId": "IDRAC.2.5.JCP001", "Name": "Configure: RAID.Integrated.1-1", "PercentComplete": 0, "StartTime": "TIME_NOW", "TargetSettingsURI": null } }, "PercentComplete": 0, "TaskState": "Starting", "TaskStatus": "OK" }././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1631521128.0 sushy-oem-idrac-3.0.1/sushy_oem_idrac/tests/unit/test_asynchronous.py0000664000175000017500000000354500000000000026220 0ustar00zuulzuul00000000000000# Copyright (c) 2020 Dell Inc. or its subsidiaries. # # 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. from unittest import mock from oslotest.base import BaseTestCase import sushy from sushy_oem_idrac.asynchronous import http_call class AsychronousTestCase(BaseTestCase): def setUp(self): super(AsychronousTestCase, self).setUp() self.conn = mock.Mock() def test_http_call_post_accepted(self): mock_post_response = self.conn.post.return_value mock_post_response.status_code = 202 mock_post_response.headers.get.return_value = '1' mock_get_202_response = mock.Mock() mock_get_202_response.status_code = 202 mock_get_202_response.headers.get.return_value = '1' mock_get_200_response = mock.Mock() mock_get_200_response.status_code = 200 self.conn.get.side_effect = [ mock_get_202_response, mock_get_200_response] resp = http_call(self.conn, 'POST') self.assertIs(resp, mock_get_200_response) def test_http_call_post_accepted_no_location(self): mock_response = self.conn.post.return_value mock_response.status_code = 202 mock_response.headers.get.return_value = None self.assertRaises(sushy.exceptions.ExtensionError, http_call, self.conn, 'POST') ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1631521128.0 sushy-oem-idrac-3.0.1/sushy_oem_idrac/tests/unit/test_idrac_card_service.py0000664000175000017500000000547100000000000027260 0ustar00zuulzuul00000000000000# Copyright (c) 2020-2021 Dell Inc. or its subsidiaries. # # 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 json from unittest import mock from oslotest.base import BaseTestCase from sushy_oem_idrac.resources.manager import constants as mgr_cons from sushy_oem_idrac.resources.manager import idrac_card_service class DelliDRACCardServiceTestCase(BaseTestCase): def setUp(self): super(DelliDRACCardServiceTestCase, self).setUp() self.conn = mock.Mock() with open('sushy_oem_idrac/tests/unit/json_samples/' 'idrac_card_service.json') as f: mock_response = self.conn.get.return_value mock_response.json.return_value = json.load(f) mock_response.status_code = 200 mock_response = self.conn.post.return_value mock_response.status_code = 202 mock_response.headers.get.return_value = '1' self.idrac_card_service = idrac_card_service.DelliDRACCardService( self.conn, '/redfish/v1/Dell/Managers/iDRAC.Embedded.1') def test_reset_idrac(self): self.idrac_card_service.reset_idrac() target_uri = ('/redfish/v1/Dell/Managers/iDRAC.Embedded.1' '/DelliDRACCardService' '/Actions/DelliDRACCardService.iDRACReset') self.conn.post.assert_called_once_with(target_uri, data={'Force': 'Graceful'}) def test_get_allowed_reset_idrac_values(self): expected_values = {mgr_cons.RESET_IDRAC_GRACEFUL_RESTART, mgr_cons.RESET_IDRAC_FORCE_RESTART} allowed_values = \ self.idrac_card_service.get_allowed_reset_idrac_values() self.assertEqual(expected_values, allowed_values) def test_get_allowed_reset_idrac_values_not_provided_by_idrac(self): idrac_service_json = self.idrac_card_service.json base_property = '#DelliDRACCardService.iDRACReset' remove_property = 'Force@Redfish.AllowableValues' idrac_service_json['Actions'][base_property].pop(remove_property) expected_values = {mgr_cons.RESET_IDRAC_GRACEFUL_RESTART, mgr_cons.RESET_IDRAC_FORCE_RESTART} allowed_values = \ self.idrac_card_service.get_allowed_reset_idrac_values() self.assertEqual(expected_values, allowed_values) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1631521128.0 sushy-oem-idrac-3.0.1/sushy_oem_idrac/tests/unit/test_job_collection.py0000664000175000017500000000351600000000000026450 0ustar00zuulzuul00000000000000# Copyright (c) 2020-2021 Dell Inc. or its subsidiaries. # # 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 json from unittest import mock from oslotest.base import BaseTestCase from sushy_oem_idrac.resources.manager import job_collection class DellJobCollectionTestCase(BaseTestCase): def setUp(self): super(DellJobCollectionTestCase, self).setUp() self.conn = mock.Mock() with open('sushy_oem_idrac/tests/unit/json_samples/' 'job_collection_expanded.json') as f: mock_response = self.conn.get.return_value mock_response.json.return_value = json.load(f) mock_response.status_code = 200 mock_response = self.conn.post.return_value mock_response.status_code = 202 mock_response.headers.get.return_value = '1' self.job_collection = job_collection.DellJobCollection( self.conn, '/redfish/v1/Managers/iDRAC.Embedded.1/Jobs') def test_get_unfinished_jobs(self): expected_unfinished_jobs = ['RID_878460711202'] actual_unfinished_jobs = self.job_collection.get_unfinished_jobs() target_uri = ('/redfish/v1/Managers/iDRAC.Embedded.1' '/Jobs?$expand=.($levels=1)') self.conn.get.assert_called_with(target_uri) self.assertEqual(expected_unfinished_jobs, actual_unfinished_jobs) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1631521128.0 sushy-oem-idrac-3.0.1/sushy_oem_idrac/tests/unit/test_job_service.py0000664000175000017500000000367400000000000025762 0ustar00zuulzuul00000000000000# Copyright (c) 2020-2021 Dell Inc. or its subsidiaries. # # 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 json from unittest import mock from oslotest.base import BaseTestCase from sushy_oem_idrac.resources.manager import job_service class DellJobServiceTestCase(BaseTestCase): def setUp(self): super(DellJobServiceTestCase, self).setUp() self.conn = mock.Mock() with open('sushy_oem_idrac/tests/unit/json_samples/' 'job_service.json') as f: mock_response = self.conn.get.return_value mock_response.json.return_value = json.load(f) mock_response.status_code = 200 mock_response = self.conn.post.return_value mock_response.status_code = 202 mock_response.headers.get.return_value = '1' self.job_service = job_service.DellJobService( self.conn, '/redfish/v1/Dell/Managers/iDRAC.Embedded.1/DellJobService') def test_delete_jobs(self): job_ids = ['JID_471269252011', 'JID_471269252012'] self.job_service.delete_jobs(job_ids=job_ids) target_uri = ('/redfish/v1/Dell/Managers' '/iDRAC.Embedded.1/DellJobService' '/Actions/''DellJobService.DeleteJobQueue') for job_id in job_ids: self.conn.post.assert_any_call(target_uri, data={'JobID': job_id}) self.assertEqual(2, self.conn.post.call_count) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1631521128.0 sushy-oem-idrac-3.0.1/sushy_oem_idrac/tests/unit/test_lifecycle_service.py0000664000175000017500000001012200000000000027131 0ustar00zuulzuul00000000000000# Copyright (c) 2020-2021 Dell Inc. or its subsidiaries. # # 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 json from unittest import mock from oslotest.base import BaseTestCase from sushy_oem_idrac.resources.manager import lifecycle_service class DellLCServiceTestCase(BaseTestCase): def setUp(self): super(DellLCServiceTestCase, self).setUp() self.conn = mock.Mock() with open('sushy_oem_idrac/tests/unit/json_samples/' 'lifecycle_service.json') as f: mock_response = self.conn.get.return_value mock_response.json.return_value = json.load(f) mock_response.status_code = 200 mock_response = self.conn.post.return_value mock_response.status_code = 202 mock_response.headers.get.return_value = '1' self.lifecycle_service = lifecycle_service.DellLCService( self.conn, '/redfish/v1/Dell/Managers/iDRAC.Embedded.1/DellLCService') def test_is_idrac_ready_true(self): mock_response = self.conn.post.return_value mock_response.status_code = 200 mock_response.json.return_value = { "LCStatus": "Ready", "RTStatus": "Ready", "ServerStatus": "OutOfPOST", "Status": "Ready" } target_uri = ('/redfish/v1/Dell/Managers/iDRAC.Embedded.1' '/DellLCService' '/Actions/DellLCService.GetRemoteServicesAPIStatus') idrac_ready_response = self.lifecycle_service.is_idrac_ready() self.conn.post.assert_called_once_with(target_uri, data={}) self.assertTrue(idrac_ready_response) def test_is_idrac_ready_false(self): mock_response = self.conn.post.return_value mock_response.status_code = 202 mock_response.json.return_value = { "LCStatus": "NotReady", "RTStatus": "NotReady", "ServerStatus": "OutOfPOST", "Status": "NotReady" } target_uri = ('/redfish/v1/Dell/Managers/iDRAC.Embedded.1' '/DellLCService' '/Actions/DellLCService.GetRemoteServicesAPIStatus') idrac_ready_response = self.lifecycle_service.is_idrac_ready() self.conn.post.assert_called_once_with(target_uri, data={}) self.assertFalse(idrac_ready_response) def test_is_realtime_ready_true(self): mock_response = self.conn.post.return_value mock_response.status_code = 200 mock_response.json.return_value = { "LCStatus": "Ready", "RTStatus": "Ready", "ServerStatus": "OutOfPOST", "Status": "Ready" } self.assertTrue(self.lifecycle_service.is_realtime_ready()) target_uri = ('/redfish/v1/Dell/Managers/iDRAC.Embedded.1' '/DellLCService' '/Actions/DellLCService.GetRemoteServicesAPIStatus') self.conn.post.assert_called_once_with(target_uri, data={}) def test_is_realtime_ready_false(self): mock_response = self.conn.post.return_value mock_response.status_code = 202 mock_response.json.return_value = { "LCStatus": "Ready", "RTStatus": "NotReady", "ServerStatus": "OutOfPOST", "Status": "NotReady" } self.assertFalse(self.lifecycle_service.is_realtime_ready()) target_uri = ('/redfish/v1/Dell/Managers/iDRAC.Embedded.1' '/DellLCService' '/Actions/DellLCService.GetRemoteServicesAPIStatus') self.conn.post.assert_called_once_with(target_uri, data={}) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1631521128.0 sushy-oem-idrac-3.0.1/sushy_oem_idrac/tests/unit/test_manager.py0000664000175000017500000006675200000000000025110 0ustar00zuulzuul00000000000000# Copyright 2017 Red Hat, Inc. # All Rights Reserved. # Copyright (c) 2020-2021 Dell Inc. or its subsidiaries. # # 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 json from unittest import mock from oslotest.base import BaseTestCase import sushy from sushy.resources.manager import manager from sushy.taskmonitor import TaskMonitor from sushy_oem_idrac.resources.manager import constants as mgr_cons from sushy_oem_idrac.resources.manager import idrac_card_service as idrac_card from sushy_oem_idrac.resources.manager import job_collection as jc from sushy_oem_idrac.resources.manager import job_service as job from sushy_oem_idrac.resources.manager import lifecycle_service as lifecycle from sushy_oem_idrac.resources.manager import manager as oem_manager class ManagerTestCase(BaseTestCase): def setUp(self): super(ManagerTestCase, self).setUp() self.conn = mock.Mock() with open('sushy_oem_idrac/tests/unit/json_samples/' 'manager.json') as f: mock_response = self.conn.get.return_value mock_response.json.return_value = json.load(f) mock_response.status_code = 200 mock_response = self.conn.post.return_value mock_response.status_code = 202 mock_response.headers = { 'Location': '/redfish/v1/TaskService/Tasks/JID_905749031119'} mock_response.content = None self.manager = manager.Manager(self.conn, '/redfish/v1/Managers/BMC', redfish_version='1.0.2') @mock.patch('sushy.resources.oem.common._global_extn_mgrs_by_resource', {}) def test_import_system_configuration_uri(self): oem = self.manager.get_oem_extension('Dell') self.assertEqual( '/redfish/v1/Managers/iDRAC.Embedded.1/Actions/Oem/EID_674_Manager' '.ImportSystemConfiguration', oem.import_system_configuration_uri) @mock.patch('sushy.resources.oem.common._global_extn_mgrs_by_resource', {}) def test_set_virtual_boot_device_cd(self): oem = self.manager.get_oem_extension('Dell') oem.set_virtual_boot_device( sushy.VIRTUAL_MEDIA_CD, manager=self.manager) self.conn.post.assert_called_once_with( '/redfish/v1/Managers/iDRAC.Embedded.1/Actions/Oem/EID_674_Manager' '.ImportSystemConfiguration', data={'ShareParameters': {'Target': 'ALL'}, 'ImportBuffer': '' 'Enabled' 'VCD-DVD' ''}) @mock.patch('sushy.resources.oem.common._global_extn_mgrs_by_resource', {}) def test_set_virtual_boot_device_cd_no_manager_passed(self): oem = self.manager.get_oem_extension('Dell') oem.set_virtual_boot_device(sushy.VIRTUAL_MEDIA_CD) self.conn.post.assert_called_once_with( '/redfish/v1/Managers/iDRAC.Embedded.1/Actions/Oem/EID_674_Manager' '.ImportSystemConfiguration', data={'ShareParameters': {'Target': 'ALL'}, 'ImportBuffer': '' 'Enabled' 'VCD-DVD' ''}) @mock.patch('sushy.resources.oem.common._global_extn_mgrs_by_resource', {}) def test_get_allowed_export_target_values(self): oem = self.manager.get_oem_extension('Dell') expected_values = {mgr_cons.EXPORT_TARGET_IDRAC, mgr_cons.EXPORT_TARGET_RAID, mgr_cons.EXPORT_TARGET_ALL, mgr_cons.EXPORT_TARGET_BIOS, mgr_cons.EXPORT_TARGET_NIC} allowed_values = oem.get_allowed_export_target_values() self.assertEqual(expected_values, allowed_values) @mock.patch('sushy.resources.oem.common._global_extn_mgrs_by_resource', {}) def test_get_allowed_export_target_values_missing(self): oem = self.manager.get_oem_extension('Dell') export_action = ('OemManager.v1_0_0' '#OemManager.ExportSystemConfiguration') oem.json['Actions']['Oem'][export_action]['ShareParameters'].pop( 'Target@Redfish.AllowableValues') oem.refresh() oem = self.manager.get_oem_extension('Dell') expected_values = {mgr_cons.EXPORT_TARGET_IDRAC, mgr_cons.EXPORT_TARGET_RAID, mgr_cons.EXPORT_TARGET_ALL, mgr_cons.EXPORT_TARGET_BIOS, mgr_cons.EXPORT_TARGET_NIC} allowed_values = oem.get_allowed_export_target_values() self.assertEqual(expected_values, allowed_values) @mock.patch('sushy.resources.oem.common._global_extn_mgrs_by_resource', {}) def test_export_system_configuration_uri(self): oem = self.manager.get_oem_extension('Dell') self.assertEqual( '/redfish/v1/Managers/iDRAC.Embedded.1/Actions/Oem/EID_674_Manager' '.ExportSystemConfiguration', oem.export_system_configuration_uri) @mock.patch('sushy.resources.oem.common._global_extn_mgrs_by_resource', {}) def test__export_system_configuration(self): oem = self.manager.get_oem_extension('Dell') oem._export_system_configuration( target=mgr_cons.EXPORT_TARGET_ALL) self.conn.post.assert_called_once_with( '/redfish/v1/Managers/iDRAC.Embedded.1/Actions/Oem/EID_674_Manager' '.ExportSystemConfiguration', data={'ShareParameters': {'Target': 'ALL'}, 'ExportFormat': 'JSON', 'ExportUse': 'Default', 'IncludeInExport': 'Default'}) @mock.patch('sushy.resources.oem.common._global_extn_mgrs_by_resource', {}) def test__export_system_configuration_nondefault(self): oem = self.manager.get_oem_extension('Dell') include_in_export = mgr_cons.INCLUDE_EXPORT_READ_ONLY_PASSWORD_HASHES oem._export_system_configuration( target=mgr_cons.EXPORT_TARGET_RAID, export_use=mgr_cons.EXPORT_USE_CLONE, include_in_export=include_in_export) self.conn.post.assert_called_once_with( '/redfish/v1/Managers/iDRAC.Embedded.1/Actions/Oem/EID_674_Manager' '.ExportSystemConfiguration', data={'ShareParameters': {'Target': 'RAID'}, 'ExportFormat': 'JSON', 'ExportUse': 'Clone', 'IncludeInExport': 'IncludeReadOnly,Include' 'PasswordHashValues'}) @mock.patch('sushy.resources.oem.common._global_extn_mgrs_by_resource', {}) def test__export_system_configuration_invalid_target(self): oem = self.manager.get_oem_extension('Dell') target = "xyz" self.assertRaises(sushy.exceptions.InvalidParameterValueError, oem._export_system_configuration, target) def test__export_system_configuration_invalid_export_use(self): oem = self.manager.get_oem_extension('Dell') self.assertRaises(sushy.exceptions.InvalidParameterValueError, oem._export_system_configuration, "RAID", export_use="ABC") def test__export_system_configuration_invalid_include_in_export(self): oem = self.manager.get_oem_extension('Dell') self.assertRaises(sushy.exceptions.InvalidParameterValueError, oem._export_system_configuration, "RAID", include_in_export="ABC") def test__export_system_configuration_invalid_include_in_export_part(self): oem = self.manager.get_oem_extension('Dell') export_action = ('OemManager.v1_0_0' '#OemManager.ExportSystemConfiguration') # Remove `IncludePasswordHashValues` from allowed values oem.json['Actions']['Oem'][export_action]['IncludeInExport@Redfish.' 'AllowableValues'] =\ ['Default', 'IncludeReadOnly'] oem.refresh() oem = self.manager.get_oem_extension('Dell') include_in_export = mgr_cons.INCLUDE_EXPORT_READ_ONLY_PASSWORD_HASHES self.assertRaises(sushy.exceptions.InvalidParameterValueError, oem._export_system_configuration, "RAID", include_in_export=include_in_export) def test__export_system_configuration_include_in_export_legacy( self): oem = self.manager.get_oem_extension('Dell') export_action = ('OemManager.v1_0_0' '#OemManager.ExportSystemConfiguration') # Add `IncludeReadOnly,IncludePasswordHashValues` to allowed values oem.json['Actions']['Oem'][export_action]['IncludeInExport@Redfish.' 'AllowableValues'] =\ ['Default', 'IncludeReadOnly', 'IncludePasswordHashValues', 'IncludeReadOnly,IncludePasswordHashValues'] oem.refresh() include_in_export = mgr_cons.INCLUDE_EXPORT_READ_ONLY_PASSWORD_HASHES oem._export_system_configuration( target=mgr_cons.EXPORT_TARGET_RAID, export_use=mgr_cons.EXPORT_USE_CLONE, include_in_export=include_in_export) self.conn.post.assert_called_once_with( '/redfish/v1/Managers/iDRAC.Embedded.1/Actions/Oem/EID_674_Manager' '.ExportSystemConfiguration', data={'ShareParameters': {'Target': 'RAID'}, 'ExportFormat': 'JSON', 'ExportUse': 'Clone', 'IncludeInExport': 'IncludeReadOnly,Include' 'PasswordHashValues'}) @mock.patch('sushy.resources.oem.common._global_extn_mgrs_by_resource', {}) def test_get_allowed_export_use_values(self): oem = self.manager.get_oem_extension('Dell') expected_values = {mgr_cons.EXPORT_USE_DEFAULT, mgr_cons.EXPORT_USE_CLONE, mgr_cons.EXPORT_USE_REPLACE} allowed_values = oem.get_allowed_export_use_values() self.assertIsInstance(allowed_values, set) self.assertEqual(expected_values, allowed_values) @mock.patch.object(oem_manager, 'LOG', autospec=True) def test_get_allowed_export_use_values_missing(self, mock_log): oem = self.manager.get_oem_extension('Dell') export_action = ('OemManager.v1_0_0' '#OemManager.ExportSystemConfiguration') oem.json['Actions']['Oem'][export_action].pop( 'ExportUse@Redfish.AllowableValues') oem.refresh() expected_values = {mgr_cons.EXPORT_USE_DEFAULT, mgr_cons.EXPORT_USE_CLONE, mgr_cons.EXPORT_USE_REPLACE} allowed_values = oem.get_allowed_export_use_values() self.assertIsInstance(allowed_values, set) self.assertEqual(expected_values, allowed_values) mock_log.warning.assert_called_once() @mock.patch('sushy.resources.oem.common._global_extn_mgrs_by_resource', {}) def test_get_allowed_include_in_export_values(self): oem = self.manager.get_oem_extension('Dell') expected_values = {mgr_cons.INCLUDE_EXPORT_DEFAULT, mgr_cons.INCLUDE_EXPORT_READ_ONLY, mgr_cons.INCLUDE_EXPORT_PASSWORD_HASHES} allowed_values = oem.get_allowed_include_in_export_values() self.assertIsInstance(allowed_values, set) self.assertEqual(expected_values, allowed_values) @mock.patch.object(oem_manager, 'LOG', autospec=True) def test_get_allowed_include_in_export_values_missing(self, mock_log): oem = self.manager.get_oem_extension('Dell') export_action = ('OemManager.v1_0_0' '#OemManager.ExportSystemConfiguration') oem.json['Actions']['Oem'][export_action].pop( 'IncludeInExport@Redfish.AllowableValues') oem.refresh() expected_values = {mgr_cons.INCLUDE_EXPORT_DEFAULT, mgr_cons.INCLUDE_EXPORT_READ_ONLY, mgr_cons.INCLUDE_EXPORT_PASSWORD_HASHES, mgr_cons.INCLUDE_EXPORT_READ_ONLY_PASSWORD_HASHES} allowed_values = oem.get_allowed_include_in_export_values() self.assertIsInstance(allowed_values, set) self.assertEqual(expected_values, allowed_values) mock_log.warning.assert_called_once() @mock.patch('sushy.resources.oem.common._global_extn_mgrs_by_resource', {}) def test_export_system_configuration(self): oem = self.manager.get_oem_extension('Dell') oem._export_system_configuration = mock.Mock() mock_response = mock.Mock() oem._export_system_configuration.return_value = mock_response response = oem.export_system_configuration() self.assertEqual(mock_response, response) include_in_export = mgr_cons.INCLUDE_EXPORT_READ_ONLY_PASSWORD_HASHES oem._export_system_configuration.assert_called_once_with( mgr_cons.EXPORT_TARGET_ALL, export_use=mgr_cons.EXPORT_USE_CLONE, include_in_export=include_in_export) @mock.patch('sushy.resources.oem.common._global_extn_mgrs_by_resource', {}) def test_get_pxe_port_macs_bios(self): oem = self.manager.get_oem_extension('Dell') oem._export_system_configuration = mock.Mock() with open('sushy_oem_idrac/tests/unit/json_samples/' 'export_configuration_nic_bios.json') as f: mock_response = oem._export_system_configuration.return_value mock_response.json.return_value = json.load(f) mock_response.status_code = 200 ethernet_interfaces_mac = {'NIC.Integrated.1-4-1': '68:05:CA:AF:AA:C9', 'NIC.Slot.7-2-1': '3C:FD:FE:CD:67:31', 'NIC.Slot.7-1-1': '3C:FD:FE:CD:67:30', 'NIC.Integrated.1-2-1': '68:05:CA:AF:AA:C7', 'NIC.Integrated.1-3-1': '68:05:CA:AF:AA:C8', 'NIC.Integrated.1-1-1': '68:05:CA:AF:AA:C6'} self.assertEqual(["68:05:CA:AF:AA:C8"], oem.get_pxe_port_macs_bios(ethernet_interfaces_mac)) @mock.patch('sushy.resources.oem.common._global_extn_mgrs_by_resource', {}) def test_get_pxe_port_macs_bios_invalid_system_config_tag(self): oem = self.manager.get_oem_extension('Dell') oem._export_system_configuration = mock.Mock() mock_response = oem._export_system_configuration.return_value mock_response.json.return_value = {'Model': 'PowerEdge R7525'} mock_response.status_code = 200 ethernet_interfaces_mac = {'NIC.Integrated.1-4-1': '68:05:CA:AF:AA:C9', 'NIC.Slot.7-2-1': '3C:FD:FE:CD:67:31', 'NIC.Slot.7-1-1': '3C:FD:FE:CD:67:30', 'NIC.Integrated.1-2-1': '68:05:CA:AF:AA:C7', 'NIC.Integrated.1-3-1': '68:05:CA:AF:AA:C8', 'NIC.Integrated.1-1-1': '68:05:CA:AF:AA:C6'} self.assertRaises(sushy.exceptions.ExtensionError, oem.get_pxe_port_macs_bios, ethernet_interfaces_mac) @mock.patch('sushy.resources.oem.common._global_extn_mgrs_by_resource', {}) def test_get_pxe_port_macs_bios_invalid_response(self): oem = self.manager.get_oem_extension('Dell') oem._export_system_configuration = mock.Mock() mock_response = oem._export_system_configuration.return_value mock_response.status_code = 204 ethernet_interfaces_mac = {'NIC.Integrated.1-4-1': '68:05:CA:AF:AA:C9', 'NIC.Slot.7-2-1': '3C:FD:FE:CD:67:31', 'NIC.Slot.7-1-1': '3C:FD:FE:CD:67:30', 'NIC.Integrated.1-2-1': '68:05:CA:AF:AA:C7', 'NIC.Integrated.1-3-1': '68:05:CA:AF:AA:C8', 'NIC.Integrated.1-1-1': '68:05:CA:AF:AA:C6'} self.assertRaises(sushy.exceptions.ExtensionError, oem.get_pxe_port_macs_bios, ethernet_interfaces_mac) def test_idrac_card_service(self): oem = self.manager.get_oem_extension('Dell') with open('sushy_oem_idrac/tests/unit/json_samples/' 'idrac_card_service.json') as f: mock_response = self.conn.get.return_value mock_response.json.return_value = json.load(f) mock_response.status_code = 200 idrac_card_service = oem.idrac_card_service self.assertEqual( '/redfish/v1/Dell/Managers/iDRAC.Embedded.1/DelliDRACCardService', idrac_card_service.path) self.assertIsInstance(idrac_card_service, idrac_card.DelliDRACCardService) @mock.patch('sushy.resources.oem.common._global_extn_mgrs_by_resource', {}) def test_lifecycle_service(self): oem = self.manager.get_oem_extension('Dell') with open('sushy_oem_idrac/tests/unit/json_samples/' 'lifecycle_service.json') as f: mock_response = self.conn.get.return_value mock_response.json.return_value = json.load(f) mock_response.status_code = 200 lifecycle_service = oem.lifecycle_service self.assertEqual( '/redfish/v1/Dell/Managers/iDRAC.Embedded.1/DellLCService', lifecycle_service.path) self.assertIsInstance(lifecycle_service, lifecycle.DellLCService) @mock.patch('sushy.resources.oem.common._global_extn_mgrs_by_resource', {}) def test_job_service(self): oem = self.manager.get_oem_extension('Dell') with open('sushy_oem_idrac/tests/unit/json_samples/' 'job_service.json') as f: mock_response = self.conn.get.return_value mock_response.json.return_value = json.load(f) mock_response.status_code = 200 job_service = oem.job_service self.assertEqual( '/redfish/v1/Dell/Managers/iDRAC.Embedded.1/DellJobService', job_service.path) self.assertIsInstance(job_service, job.DellJobService) @mock.patch('sushy.resources.oem.common._global_extn_mgrs_by_resource', {}) def test_job_collection(self): oem = self.manager.get_oem_extension('Dell') with open('sushy_oem_idrac/tests/unit/json_samples/' 'job_collection_expanded.json') as f: mock_response = self.conn.get.return_value mock_response.json.return_value = json.load(f) mock_response.status_code = 200 job_collection = oem.job_collection self.assertEqual( '/redfish/v1/Managers/iDRAC.Embedded.1/Jobs', job_collection.path) self.assertIsInstance(job_collection, jc.DellJobCollection) def test_get_allowed_import_shutdown_type_values(self): oem = self.manager.get_oem_extension('Dell') expected_values = {mgr_cons.IMPORT_SHUTDOWN_GRACEFUL, mgr_cons.IMPORT_SHUTDOWN_FORCED, mgr_cons.IMPORT_SHUTDOWN_NO_REBOOT} allowed_values = oem.get_allowed_import_shutdown_type_values() self.assertIsInstance(allowed_values, set) self.assertEqual(expected_values, allowed_values) @mock.patch.object(oem_manager, 'LOG', autospec=True) def test_get_allowed_import_shutdown_type_values_missing(self, mock_log): oem = self.manager.get_oem_extension('Dell') import_action = ('OemManager.v1_0_0' '#OemManager.ImportSystemConfiguration') oem.json['Actions']['Oem'][import_action].pop( 'ShutdownType@Redfish.AllowableValues') oem.refresh() expected_values = {mgr_cons.IMPORT_SHUTDOWN_GRACEFUL, mgr_cons.IMPORT_SHUTDOWN_FORCED, mgr_cons.IMPORT_SHUTDOWN_NO_REBOOT} allowed_values = oem.get_allowed_import_shutdown_type_values() self.assertIsInstance(allowed_values, set) self.assertEqual(expected_values, allowed_values) mock_log.warning.assert_called_once() def test_import_system_configuration(self): oem = self.manager.get_oem_extension('Dell') result = oem.import_system_configuration('{"key": "value"}') self.conn.post.assert_called_once_with( '/redfish/v1/Managers/iDRAC.Embedded.1/Actions/Oem/EID_674_Manager' '.ImportSystemConfiguration', data={'ShareParameters': {'Target': 'ALL'}, 'ImportBuffer': '{"key": "value"}', 'ShutdownType': 'NoReboot'}) self.assertIsInstance(result, TaskMonitor) self.assertEqual('/redfish/v1/TaskService/Tasks/JID_905749031119', result.task_monitor_uri) def test_reset_idrac_with_wait_true(self): oem_manager = self.manager.get_oem_extension('Dell') oem_manager.idrac_card_service.reset_idrac = mock.Mock() oem_manager._conn._url = "https://1.2.3.4" oem_manager._wait_for_idrac = mock.Mock() oem_manager._wait_until_idrac_is_ready = mock.Mock() oem_manager.reset_idrac(wait=True) oem_manager.idrac_card_service.reset_idrac.assert_called() oem_manager._wait_for_idrac.assert_called_with('1.2.3.4', 60) oem_manager._wait_until_idrac_is_ready.assert_called_with( '1.2.3.4', 96, 10) def test_reset_idrac_with_wait_false(self): oem_manager = self.manager.get_oem_extension('Dell') oem_manager.idrac_card_service.reset_idrac = mock.Mock() oem_manager._wait_for_idrac = mock.Mock() oem_manager._wait_until_idrac_is_ready = mock.Mock() oem_manager.reset_idrac(wait=False) oem_manager.idrac_card_service.reset_idrac.assert_called() oem_manager._wait_for_idrac.assert_not_called() oem_manager._wait_until_idrac_is_ready.assert_not_called() def test__wait_until_idrac_is_ready(self): oem_manager = self.manager.get_oem_extension('Dell') oem_manager.lifecycle_service.is_idrac_ready = mock.Mock() oem_manager.lifecycle_service.is_idrac_ready.side_effect = \ [False, True] oem_manager._wait_until_idrac_is_ready('1.2.3.4', 96, 10) oem_manager.lifecycle_service.is_idrac_ready.assert_called_with() @mock.patch('time.sleep', autospec=True) def test__wait_until_idrac_is_ready_with_timeout(self, mock_time_sleep): oem_manager = self.manager.get_oem_extension('Dell') oem_manager.lifecycle_service.is_idrac_ready = mock.Mock() oem_manager.lifecycle_service.is_idrac_ready.return_value = False self.assertRaises(sushy.exceptions.ExtensionError, oem_manager._wait_until_idrac_is_ready, '1.2.3.4', 96, 10) @mock.patch('time.sleep', autospec=True) def test__wait_for_idrac_with_state_reached(self, mock_time_sleep): oem_manager = self.manager.get_oem_extension('Dell') oem_manager._wait_for_idrac_state = mock.Mock() oem_manager._wait_for_idrac_state.return_value = True oem_manager._wait_for_idrac('1.2.3.4', 30) oem_manager._wait_for_idrac_state.assert_called_with( '1.2.3.4', alive=True, ping_count=3, retries=24) oem_manager._wait_for_idrac_state.assert_any_call( '1.2.3.4', alive=False, ping_count=2, retries=24) self.assertEqual(2, oem_manager._wait_for_idrac_state.call_count) @mock.patch('time.sleep', autospec=True) def test__wait_for_idrac_with_first_state_not_reached(self, mock_time_sleep): oem_manager = self.manager.get_oem_extension('Dell') oem_manager._wait_for_idrac_state = mock.Mock() oem_manager._wait_for_idrac_state.return_value = False self.assertRaises(sushy.exceptions.ExtensionError, oem_manager._wait_for_idrac, '1.2.3.4', 30) @mock.patch('time.sleep', autospec=True) def test__wait_for_idrac_with_second_state_not_reached(self, mock_time_sleep): oem_manager = self.manager.get_oem_extension('Dell') oem_manager._wait_for_idrac_state = mock.Mock() oem_manager._wait_for_idrac_state.side_effect = [True, False] self.assertRaises(sushy.exceptions.ExtensionError, oem_manager._wait_for_idrac, '1.2.3.4', 30) @mock.patch('time.sleep', autospec=True) def test__wait_for_idrac_state_with_pingable(self, mock_time_sleep): oem_manager = self.manager.get_oem_extension('Dell') oem_manager._ping_host = mock.Mock() oem_manager._ping_host.return_value = True response = oem_manager._wait_for_idrac_state('1.2.3.4') self.assertEqual(True, response) self.assertEqual(3, oem_manager._ping_host.call_count) @mock.patch('time.sleep', autospec=True) def test__wait_for_idrac_state_without_pingable(self, mock_time_sleep): oem_manager = self.manager.get_oem_extension('Dell') oem_manager._ping_host = mock.Mock() oem_manager._ping_host.return_value = False response = oem_manager._wait_for_idrac_state('1.2.3.4') self.assertEqual(False, response) self.assertEqual(24, oem_manager._ping_host.call_count) @mock.patch('subprocess.call', autospec=True) def test__ping_host_alive(self, mock_call): oem_manager = self.manager.get_oem_extension('Dell') mock_call.return_value = 0 result = oem_manager._ping_host('1.2.3.4') self.assertTrue(result) mock_call.assert_called_with(["ping", "-c", "1", '1.2.3.4']) @mock.patch('subprocess.call', autospec=True) def test__ping_host_not_alive(self, mock_call): oem_manager = self.manager.get_oem_extension('Dell') mock_call.return_value = 1 result = oem_manager._ping_host('1.2.3.4') self.assertFalse(result) mock_call.assert_called_with(["ping", "-c", "1", '1.2.3.4']) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1631521128.0 sushy-oem-idrac-3.0.1/sushy_oem_idrac/tests/unit/test_raid_service.py0000664000175000017500000002150000000000000026113 0ustar00zuulzuul00000000000000# Copyright (c) 2021 Dell Inc. or its subsidiaries. # # 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 json from unittest import mock from oslotest.base import BaseTestCase from sushy import exceptions from sushy import taskmonitor from sushy_oem_idrac.resources.system import raid_service class DellRaidService(BaseTestCase): def setUp(self): super(DellRaidService, self).setUp() self.conn = mock.Mock() with open('sushy_oem_idrac/tests/unit/json_samples/' 'raid_service.json') as f: mock_response = self.conn.get.return_value mock_response.json.return_value = json.load(f) mock_response.status_code = 200 self.mock_response = mock.Mock() self.mock_response.status_code = 202 self.mock_response.headers = { 'Location': '/redfish/v1/Managers/iDRAC.Embedded.1/Oem/Dell/Jobs/' 'JID_999888777666' } self.root = mock.Mock() self.raid_service = raid_service.DellRaidService( self.conn, '/redfish/v1/Systems/System.Embedded.1/Oem/Dell/' 'DellRaidService', root=self.root ) @mock.patch.object(raid_service.DellRaidService, '_get_task_monitor_from_dell_job', autospec=True) def test_convert_to_raid(self, mock_get_task_mon): mock_task_mon = mock.Mock() mock_get_task_mon.return_value = mock_task_mon fqdds = ["Disk.Bay.0:Enclosure.Internal.0-1:RAID.Integrated.1-1", "Disk.Bay.1:Enclosure.Internal.0-1:RAID.Integrated.1-1"] task_mon = self.raid_service.convert_to_raid(fqdds) self.conn.post.assert_called_once_with( '/redfish/v1/Systems/System.Embedded.1/Oem/Dell/DellRaidService/' 'Actions/DellRaidService.ConvertToRAID', data={'PDArray': fqdds}) self.assertEqual(mock_task_mon, task_mon) @mock.patch.object(raid_service.DellRaidService, '_get_task_monitor_from_dell_job', autospec=True) def test_convert_to_nonraid(self, mock_get_task_mon): mock_task_mon = mock.Mock() mock_get_task_mon.return_value = mock_task_mon fqdds = ["Disk.Bay.0:Enclosure.Internal.0-1:RAID.Integrated.1-1", "Disk.Bay.1:Enclosure.Internal.0-1:RAID.Integrated.1-1"] task_mon = self.raid_service.convert_to_nonraid(fqdds) self.conn.post.assert_called_once_with( '/redfish/v1/Systems/System.Embedded.1/Oem/Dell/DellRaidService/' 'Actions/DellRaidService.ConvertToNonRAID', data={'PDArray': fqdds}) self.assertEqual(mock_task_mon, task_mon) @mock.patch.object(raid_service.DellRaidService, '_get_task_monitor_from_dell_job', autospec=True) def test_clear_foreign_config(self, mock_get_task_mon): mock_task_mon = mock.Mock() mock_get_task_mon.return_value = mock_task_mon result = self.raid_service.clear_foreign_config('RAID.Integrated.1-1') self.conn.post.assert_called_once_with( '/redfish/v1/Systems/System.Embedded.1/Oem/Dell/DellRaidService/' 'Actions/DellRaidService.ClearForeignConfig', data={'TargetFQDD': 'RAID.Integrated.1-1'}) self.assertEqual(mock_task_mon, result) def test_clear_foreign_config_no_config(self): mock_response = mock.Mock() mock_response.status_code = 400 mock_response.json.return_value = { "error": { "@Message.ExtendedInfo": [ { "Message": "No foreign configurations detected.", "MessageArgs": [], "MessageArgs@odata.count": 0, "MessageId": "IDRAC.2.5.STOR018", "RelatedProperties": [], "RelatedProperties@odata.count": 0, "Resolution": "If the only foreign drives present are " "in a secured locked state, run a " "secure erase operation on the drives " "to securely erase data or unlock these " "drives and retry the operation. " "Otherwise the operation was not " "successful because there are no " "foreign drives.", "Severity": "Warning" } ], "code": "Base.1.8.GeneralError", "message": "A general error has occurred. See ExtendedInfo " "for more information" } } no_config_error = exceptions.BadRequestError( 'POST', '/redfish/v1/Dell/Systems/System.Embedded.1/' 'DellRaidService/Actions/DellRaidService.ClearForeignConfig', mock_response) self.conn.post.side_effect = no_config_error result = self.raid_service.clear_foreign_config('RAID.Integrated.1-1') self.assertIsNone(result) def test_clear_foreign_config_bad_request(self): mock_response = mock.Mock() mock_response.status_code = 400 mock_response.json.return_value = { "error": { "@Message.ExtendedInfo": [ { "Message": "Controller not found.", "MessageArgs": [], "MessageArgs@odata.count": 0, "MessageId": "IDRAC.2.4.STOR030", "RelatedProperties": [], "RelatedProperties@odata.count": 0, "Resolution": "Provide a valid controller FQDD (Fully " "Qualified Device Descriptor) and retry " "the operation.", "Severity": "Warning" } ], "code": "Base.1.7.GeneralError", "message": "A general error has occurred. See ExtendedInfo " "for more information" } } no_config_error = exceptions.BadRequestError( 'POST', '/redfish/v1/Dell/Systems/System.Embedded.1/' 'DellRaidService/Actions/DellRaidService.ClearForeignConfig', mock_response) self.conn.post.side_effect = no_config_error self.assertRaises(exceptions.BadRequestError, self.raid_service.clear_foreign_config, 'RAID.Integrated.999') def test__get_task_monitor_from_dell_job(self): mock_task1 = mock.Mock(identity='JID_111222333444', path='/TaskService/Task/JID_111222333444') mock_task2 = mock.Mock(identity='JID_999888777666', path='/TaskService/Task/JID_999888777666') mock_tasks = mock.Mock() mock_tasks.get_members.return_value = [mock_task1, mock_task2] self.root.get_task_service.return_value.tasks = mock_tasks task_mon = self.raid_service._get_task_monitor_from_dell_job( self.mock_response) self.assertIsInstance(task_mon, taskmonitor.TaskMonitor) self.assertEqual('/TaskService/Task/JID_999888777666', task_mon.task_monitor_uri) def test__get_task_monitor_from_dell_job_location_missing(self): mock_response = mock.Mock() mock_response.status_code = 202 mock_response.headers = { 'Connection': 'Keep-Alive' } self.assertRaisesRegex( exceptions.ExtensionError, 'does not include Location', self.raid_service._get_task_monitor_from_dell_job, mock_response) def test__get_task_monitor_from_dell_job_task_not_found(self): mock_task1 = mock.Mock(identity='JID_000000000000', path='/TaskService/Task/JID_000000000000') mock_tasks = mock.Mock() mock_tasks.get_members.return_value = [mock_task1] self.root.get_task_service.return_value.tasks = mock_tasks self.assertRaisesRegex( exceptions.ExtensionError, 'not find task by id', self.raid_service._get_task_monitor_from_dell_job, self.mock_response) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1631521128.0 sushy-oem-idrac-3.0.1/sushy_oem_idrac/tests/unit/test_root.py0000664000175000017500000000326100000000000024443 0ustar00zuulzuul00000000000000# Copyright 2017 Red Hat, Inc. # 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 json from unittest import mock from oslotest.base import BaseTestCase from sushy import main class RootTestCase(BaseTestCase): @mock.patch('sushy.auth.SessionOrBasicAuth', autospec=True) @mock.patch('sushy.connector.Connector', autospec=True) @mock.patch('sushy.resources.sessionservice.sessionservice.' 'SessionService', autospec=True) def setUp(self, mock_session_service, mock_connector, mock_auth): super(RootTestCase, self).setUp() self.conn = mock.Mock() self.sess_serv = mock.Mock() self.sess_serv.create_session.return_value = (None, None) mock_session_service.return_value = self.sess_serv mock_connector.return_value = self.conn with open('sushy_oem_idrac/tests/unit/json_samples/root.json') as f: self.conn.get.return_value.json.return_value = json.load(f) self.root = main.Sushy('http://foo.bar:1234', verify=True, auth=mock_auth) def test_oem_vendors(self): self.assertEqual(['Dell'], self.root.oem_vendors) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1631521128.0 sushy-oem-idrac-3.0.1/sushy_oem_idrac/tests/unit/test_system.py0000664000175000017500000001206600000000000025007 0ustar00zuulzuul00000000000000# Copyright (c) 2021 Dell Inc. or its subsidiaries. # # 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 json from unittest import mock from oslotest.base import BaseTestCase from sushy import exceptions from sushy_oem_idrac.resources.system import constants as sys_cons from sushy_oem_idrac.resources.system import raid_service from sushy_oem_idrac.resources.system import system as oem_system class SystemTestCase(BaseTestCase): def setUp(self): super(SystemTestCase, self).setUp() self.conn = mock.Mock() with open('sushy_oem_idrac/tests/unit/json_samples/' 'system.json') as f: mock_response = self.conn.get.return_value mock_response.json.return_value = json.load(f) mock_response.status_code = 200 self.oem_system = oem_system.DellSystemExtension( self.conn, '/redfish/v1/Systems/System.Embedded.1') mock_perc_raid = mock.Mock( identity='Disk.Bay.0:Enclosure.Internal.0-1:RAID.Integrated.1-1') type(mock_perc_raid).volumes = mock.PropertyMock( side_effect=exceptions.MissingAttributeError) mock_perc_nonraid = mock.Mock( identity='Disk.Bay.1:Enclosure.Internal.0-1:RAID.Integrated.1-1', volumes=[mock.Mock(volume_type='rawdevice', raid_type=None)]) mock_boss_controller = mock.MagicMock(raid_types=['RAID1']) mock_boss_controller.name = 'BOSS-S1' mock_boss = mock.Mock(storage_controllers=[mock_boss_controller], drives=mock.Mock()) mock_perc_controller = mock.MagicMock(raid_types=['RAID1']) mock_perc_controller.name = 'PERC' mock_perc = mock.Mock(storage_controllers=[mock_perc_controller], drives=[mock_perc_raid, mock_perc_nonraid]) mock_system = mock.Mock() mock_storage_nocontroller = mock.Mock(storage_controllers=[]) mock_storage_nonraid = mock.Mock( storage_controllers=[mock.Mock(raid_types=[])]) mock_storage_boss = mock_boss mock_storage_raid = mock_perc mock_system.storage.get_members.return_value = [ mock_storage_nocontroller, mock_storage_nonraid, mock_storage_boss, mock_storage_raid] self.oem_system._parent_resource = mock_system def test_raid_service(self): with open('sushy_oem_idrac/tests/unit/json_samples/' 'raid_service.json') as f: mock_response = self.conn.get.return_value mock_response.json.return_value = json.load(f) mock_response.status_code = 200 result = self.oem_system.raid_service self.assertEqual( '/redfish/v1/Systems/System.Embedded.1/Oem/Dell/DellRaidService', result.path) self.assertIsInstance(result, raid_service.DellRaidService) def test_change_physical_disk_state_raid(self): mock_taskmon = mock.Mock() mock_raid = mock.Mock() mock_raid.return_value = mock_taskmon mock_nonraid = mock.Mock() self.oem_system.raid_service.convert_to_raid = mock_raid self.oem_system.raid_service.convert_to_nonraid = mock_nonraid task_mons = self.oem_system.change_physical_disk_state( sys_cons.PHYSICAL_DISK_STATE_MODE_RAID) self.assertEqual([mock_taskmon], task_mons) mock_raid.assert_called_once_with( ['Disk.Bay.1:Enclosure.Internal.0-1:RAID.Integrated.1-1']) mock_nonraid.assert_not_called() def test_change_physical_disk_state_nonraid(self): mock_taskmon = mock.Mock() mock_raid = mock.Mock() mock_nonraid = mock.Mock() mock_nonraid.return_value = mock_taskmon self.oem_system.raid_service.convert_to_raid = mock_raid self.oem_system.raid_service.convert_to_nonraid = mock_nonraid task_mons = self.oem_system.change_physical_disk_state( sys_cons.PHYSICAL_DISK_STATE_MODE_NONRAID) self.assertEqual([mock_taskmon], task_mons) mock_raid.assert_not_called() mock_nonraid.assert_called_once_with( ['Disk.Bay.0:Enclosure.Internal.0-1:RAID.Integrated.1-1']) def test_clear_foreign_config(self): mock_taskmon = mock.Mock() mock_clear_foreign_config = mock.Mock() mock_clear_foreign_config.side_effect = [mock_taskmon] self.oem_system.raid_service.clear_foreign_config =\ mock_clear_foreign_config task_mons = self.oem_system.clear_foreign_config() self.assertEqual([mock_taskmon], task_mons) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1631521128.0 sushy-oem-idrac-3.0.1/sushy_oem_idrac/tests/unit/test_task.py0000664000175000017500000000477700000000000024437 0ustar00zuulzuul00000000000000# Copyright (c) 2021 Dell Inc. or its subsidiaries. # # 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 json from unittest import mock from oslotest.base import BaseTestCase from sushy.resources.taskservice import task as sushy_task from sushy_oem_idrac.resources.taskservice import constants as ts_cons from sushy_oem_idrac.resources.taskservice import task class TaskTestCase(BaseTestCase): def setUp(self): super(TaskTestCase, self).setUp() self.conn = mock.Mock() with open('sushy_oem_idrac/tests/unit/json_samples/' 'task.json') as f: mock_response = self.conn.get.return_value mock_response.json.return_value = json.load(f) mock_response.status_code = 200 self.task = sushy_task.Task( self.conn, '/redfish/v1/TaskService/Tasks/JID_257309938313') self.oem_task = task.DellTaskExtension( self.conn, '/redfish/v1/TaskService/Tasks/JID_257309938313') self.oem_task = self.oem_task.set_parent_resource( self.task, 'Dell') def test_parse_attributes(self): self.assertEqual('JID_257309938313', self.oem_task.identity) self.assertEqual('Configure: RAID.Integrated.1-1', self.oem_task.name) self.assertEqual('Job Instance', self.oem_task.description) self.assertIsNone(self.oem_task.completion_time) self.assertEqual('TIME_NA', self.oem_task.end_time) self.assertEqual(ts_cons.JOB_STATE_SCHEDULED, self.oem_task.job_state) self.assertEqual(ts_cons.JOB_TYPE_RAID_CONF, self.oem_task.job_type) self.assertEqual('Task successfully scheduled.', self.oem_task.message) self.assertEqual([], self.oem_task.message_args) self.assertEqual('IDRAC.2.5.JCP001', self.oem_task.message_id) self.assertEqual(0, self.oem_task.percent_complete) self.assertEqual('TIME_NOW', self.oem_task.start_time) ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1631521128.0 sushy-oem-idrac-3.0.1/sushy_oem_idrac/utils.py0000664000175000017500000000221500000000000021436 0ustar00zuulzuul00000000000000# 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 logging import time import sushy LOG = logging.getLogger(__name__) def reboot_system(system): if system.power_state != sushy.POWER_STATE_OFF: system.reset_system(sushy.RESET_FORCE_OFF) LOG.info('Requested system power OFF') while system.power_state != sushy.POWER_STATE_OFF: time.sleep(30) system.refresh() LOG.info('System is powered OFF') system.reset_system(sushy.RESET_ON) LOG.info('Requested system power ON') while system.power_state != sushy.POWER_STATE_ON: time.sleep(30) system.refresh() LOG.info('System powered ON') ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1631521193.3499517 sushy-oem-idrac-3.0.1/sushy_oem_idrac.egg-info/0000775000175000017500000000000000000000000021416 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1631521193.0 sushy-oem-idrac-3.0.1/sushy_oem_idrac.egg-info/PKG-INFO0000664000175000017500000000502500000000000022515 0ustar00zuulzuul00000000000000Metadata-Version: 2.1 Name: sushy-oem-idrac Version: 3.0.1 Summary: Dell EMC iDRAC OEM extension package for the sushy library Home-page: https://docs.openstack.org/sushy/latest/ Author: OpenStack Author-email: openstack-discuss@lists.openstack.org License: UNKNOWN Description: Dell EMC OEM extension for sushy ================================ Sushy is a client [library](https://github.com/openstack/sushy) designed to communicate with [Redfish](https://en.wikipedia.org/wiki/Redfish_(specification)) based BMC. Redfish specification offers extensibility mechanism to let hardware vendors introduce their own features with the common Redfish framework. At the same time, `sushy` supports extending its data model by loading extensions found within its "oem" namespace. The `sushy-oem-idrac` package is a sushy extension package that aims at adding high-level hardware management abstractions, that are specific to Dell EMC BMC (which is known under the name of iDRAC), to the tree of sushy Redfish resources. Example use ----------- Once installed, sushy user can access Dell EMC OEM resources. For example, OEM extension of Manager resource can be instrumental for switching the node to boot from a virtual media device: ```python import sushy root = sushy.Sushy('http://mydellemcbmc.example.com') manager = root.get_manager('iDRAC.Embedded.1') oem_manager = manager.get_oem_extension('Dell') oem_manager.set_virtual_boot_device( sushy.VIRTUAL_MEDIA_CD, persistent=False, manager=manager) ``` See full example of virtual media boot setup in the [functional test suite](https://github.com/etingof/sushy-oem-idrac/blob/master/sushy_oem_idrac/tests/functional/vmedia_boot.py). Platform: UNKNOWN Classifier: Environment :: OpenStack Classifier: Intended Audience :: Information Technology Classifier: Intended Audience :: System Administrators Classifier: License :: OSI Approved :: Apache Software License Classifier: Operating System :: POSIX :: Linux Classifier: Programming Language :: Python Classifier: Programming Language :: Python :: 3 :: Only Classifier: Programming Language :: Python :: 3 Classifier: Programming Language :: Python :: 3.6 Classifier: Programming Language :: Python :: 3.7 Description-Content-Type: text/markdown ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1631521193.0 sushy-oem-idrac-3.0.1/sushy_oem_idrac.egg-info/SOURCES.txt0000664000175000017500000000511300000000000023302 0ustar00zuulzuul00000000000000.stestr.conf AUTHORS CONTRIBUTING.rst ChangeLog HACKING.rst LICENSE README.md babel.cfg requirements.txt setup.cfg setup.py test-requirements.txt tox.ini sushy_oem_idrac/__init__.py sushy_oem_idrac/asynchronous.py sushy_oem_idrac/constants.py sushy_oem_idrac/utils.py sushy_oem_idrac.egg-info/PKG-INFO sushy_oem_idrac.egg-info/SOURCES.txt sushy_oem_idrac.egg-info/dependency_links.txt sushy_oem_idrac.egg-info/entry_points.txt sushy_oem_idrac.egg-info/not-zip-safe sushy_oem_idrac.egg-info/pbr.json sushy_oem_idrac.egg-info/requires.txt sushy_oem_idrac.egg-info/top_level.txt sushy_oem_idrac/resources/__init__.py sushy_oem_idrac/resources/manager/__init__.py sushy_oem_idrac/resources/manager/constants.py sushy_oem_idrac/resources/manager/idrac_card_service.py sushy_oem_idrac/resources/manager/job_collection.py sushy_oem_idrac/resources/manager/job_service.py sushy_oem_idrac/resources/manager/lifecycle_service.py sushy_oem_idrac/resources/manager/manager.py sushy_oem_idrac/resources/manager/mappings.py sushy_oem_idrac/resources/system/constants.py sushy_oem_idrac/resources/system/raid_service.py sushy_oem_idrac/resources/system/system.py sushy_oem_idrac/resources/taskservice/constants.py sushy_oem_idrac/resources/taskservice/mappings.py sushy_oem_idrac/resources/taskservice/task.py sushy_oem_idrac/tests/__init__.py sushy_oem_idrac/tests/functional/__init__.py sushy_oem_idrac/tests/functional/vmedia_boot.py sushy_oem_idrac/tests/unit/__init__.py sushy_oem_idrac/tests/unit/base.py sushy_oem_idrac/tests/unit/test_asynchronous.py sushy_oem_idrac/tests/unit/test_idrac_card_service.py sushy_oem_idrac/tests/unit/test_job_collection.py sushy_oem_idrac/tests/unit/test_job_service.py sushy_oem_idrac/tests/unit/test_lifecycle_service.py sushy_oem_idrac/tests/unit/test_manager.py sushy_oem_idrac/tests/unit/test_raid_service.py sushy_oem_idrac/tests/unit/test_root.py sushy_oem_idrac/tests/unit/test_system.py sushy_oem_idrac/tests/unit/test_task.py sushy_oem_idrac/tests/unit/json_samples/export_configuration_nic_bios.json sushy_oem_idrac/tests/unit/json_samples/idrac_card_service.json sushy_oem_idrac/tests/unit/json_samples/job_collection_expanded.json sushy_oem_idrac/tests/unit/json_samples/job_service.json sushy_oem_idrac/tests/unit/json_samples/lifecycle_service.json sushy_oem_idrac/tests/unit/json_samples/manager.json sushy_oem_idrac/tests/unit/json_samples/manager_collection.json sushy_oem_idrac/tests/unit/json_samples/raid_service.json sushy_oem_idrac/tests/unit/json_samples/root.json sushy_oem_idrac/tests/unit/json_samples/system.json sushy_oem_idrac/tests/unit/json_samples/task.json zuul.d/project.yaml././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1631521193.0 sushy-oem-idrac-3.0.1/sushy_oem_idrac.egg-info/dependency_links.txt0000664000175000017500000000000100000000000025464 0ustar00zuulzuul00000000000000 ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1631521193.0 sushy-oem-idrac-3.0.1/sushy_oem_idrac.egg-info/entry_points.txt0000664000175000017500000000043000000000000024711 0ustar00zuulzuul00000000000000[sushy.resources.manager.oems] dell = sushy_oem_idrac.resources.manager.manager:get_extension [sushy.resources.system.oems] dell = sushy_oem_idrac.resources.system.system:get_extension [sushy.resources.task.oems] dell = sushy_oem_idrac.resources.taskservice.task:get_extension ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1631521193.0 sushy-oem-idrac-3.0.1/sushy_oem_idrac.egg-info/not-zip-safe0000664000175000017500000000000100000000000023644 0ustar00zuulzuul00000000000000 ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1631521193.0 sushy-oem-idrac-3.0.1/sushy_oem_idrac.egg-info/pbr.json0000664000175000017500000000005600000000000023075 0ustar00zuulzuul00000000000000{"git_version": "7859b33", "is_release": true}././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1631521193.0 sushy-oem-idrac-3.0.1/sushy_oem_idrac.egg-info/requires.txt0000664000175000017500000000007000000000000024013 0ustar00zuulzuul00000000000000pbr!=2.1.0,>=2.0.0 python-dateutil>=2.7.0 sushy>=3.11.0 ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1631521193.0 sushy-oem-idrac-3.0.1/sushy_oem_idrac.egg-info/top_level.txt0000664000175000017500000000002000000000000024140 0ustar00zuulzuul00000000000000sushy_oem_idrac ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1631521128.0 sushy-oem-idrac-3.0.1/test-requirements.txt0000664000175000017500000000100300000000000021002 0ustar00zuulzuul00000000000000# The order of packages is significant, because pip processes them in the order # of appearance. Changing the order has an impact on the overall integration # process, which may cause wedges in the gate later. coverage!=4.4,>=4.0 # Apache-2.0 python-subunit>=1.0.0 # Apache-2.0/BSD sphinx!=1.6.6,!=1.6.7,>=1.6.2 # BSD openstackdocstheme>=1.18.1 # Apache-2.0 oslotest>=3.2.0 # Apache-2.0 stestr>=2.0.0 # Apache-2.0 testscenarios>=0.4 # Apache-2.0/BSD testtools>=2.2.0 # MIT # releasenotes reno>=2.5.0 # Apache-2.0 ././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1631521128.0 sushy-oem-idrac-3.0.1/tox.ini0000664000175000017500000000424300000000000016065 0ustar00zuulzuul00000000000000[tox] minversion = 3.1.0 envlist = py3,pep8 skipsdist = True ignore_basepython_conflict=true [testenv] usedevelop = True install_command = pip install {opts} {packages} basepython = python3 setenv = VIRTUAL_ENV={envdir} PYTHONWARNINGS=default::DeprecationWarning deps = -c{env:TOX_CONSTRAINTS_FILE:https://releases.openstack.org/constraints/upper/master} -r{toxinidir}/test-requirements.txt -r{toxinidir}/requirements.txt commands = stestr run --slowest {posargs} [testenv:pep8] deps = hacking>=4.1.0,<5.0.0 # Apache-2.0 flake8-import-order>=0.17.1 # LGPLv3 pycodestyle>=2.0.0,<3.0.0 # MIT commands = flake8 {posargs} [testenv:venv] commands = {posargs} [testenv:cover] setenv = {[testenv]setenv} PYTHON=coverage run --source sushy_oem_idrac --omit='*tests*' --parallel-mode # After running this target, visit sushy_oem_idrac/cover/index.html # in your browser, to see a nicer presentation report with annotated # HTML listings detailing missed lines. commands = coverage erase stestr run {posargs} coverage combine coverage report --omit='*tests*' coverage html -d ./cover --omit='*tests*' coverage xml -o cover/coverage.xml --omit='*tests*' [testenv:docs] commands = python setup.py build_sphinx [testenv:releasenotes] commands = sphinx-build -a -E -W -d releasenotes/build/doctrees -b html releasenotes/source releasenotes/build/html [testenv:debug] commands = oslo_debug_helper -t sushy_oem_idrac/tests {posargs} [flake8] # E123, E125 skipped as they are invalid PEP-8. # [W503] Line break before binary operator. show-source = True ignore = E123,E125,W503 # [H106] Don't put vim configuration in source files. # [H203] Use assertIs(Not)None to check for None. # [H204] Use assert(Not)Equal to check for equality. # [H205] Use assert(Greater|Less)(Equal) for comparison. # [H210] Require 'autospec', 'spec', or 'spec_set' in mock.patch/mock.patch.object calls # [H904] Delay string interpolations at logging calls. enable-extensions=H106,H203,H204,H205,H210,H904 builtins = _ exclude=.venv,.git,.tox,dist,doc,*lib/python*,*egg,build import-order-style = pep8 application-import-names = sushy_oem_idrac filename = *.py ././@PaxHeader0000000000000000000000000000003400000000000011452 xustar000000000000000028 mtime=1631521193.3539517 sushy-oem-idrac-3.0.1/zuul.d/0000775000175000017500000000000000000000000015770 5ustar00zuulzuul00000000000000././@PaxHeader0000000000000000000000000000002600000000000011453 xustar000000000000000022 mtime=1631521128.0 sushy-oem-idrac-3.0.1/zuul.d/project.yaml0000664000175000017500000000016600000000000020325 0ustar00zuulzuul00000000000000- project: templates: - check-requirements - openstack-cover-jobs - openstack-python3-xena-jobs