Remove the tools/ directory from the sushy tree
All the tools have been moved to the "sushy-tools" project and can now be removed from the tree. The documentation was also updated to use the new project instead. Depends-On: I13df916ec8ddb3347c21105b32d354ade1bfd191 Change-Id: Icc7ab83b0091a4adebe81f379c20877bfa76b0c2
This commit is contained in:
parent
392a4a6272
commit
e24a9a9f82
|
@ -1,4 +1,97 @@
|
|||
.. _contributing:
|
||||
|
||||
============
|
||||
Contributing
|
||||
============
|
||||
.. include:: ../../CONTRIBUTING.rst
|
||||
|
||||
|
||||
Running a Redfish emulator
|
||||
==========================
|
||||
|
||||
Testing and/or developing Sushy without owning a real baremetal machine
|
||||
that supports the Redfish protocol is possible by running an emulator,
|
||||
the `sushy-tools`_ project ships with two emulators that can be used
|
||||
for this purpose. To install it run::
|
||||
|
||||
sudo pip install --user sushy-tools
|
||||
|
||||
.. note::
|
||||
Installing the dependencies requires libvirt development files.
|
||||
For example, run the following command to install them on Fedora::
|
||||
|
||||
sudo dnf install -y libvirt-devel
|
||||
|
||||
|
||||
Static emulator
|
||||
~~~~~~~~~~~~~~~
|
||||
|
||||
After installing `sushy-tools`_ you will have a new CLI tool named
|
||||
``sushy-static``. This tool creates a HTTP server to serve any of the
|
||||
`Redfish mockups <https://www.dmtf.org/standards/redfish>`_. The files
|
||||
are static so operations like changing the boot device or the power state
|
||||
**will not** have any effect. But that should be enough for enabling
|
||||
people to test parts of the library.
|
||||
|
||||
To use ``sushy-static`` we need the Redfish mockup files that can be
|
||||
downloaded from https://www.dmtf.org/standards/redfish, for example::
|
||||
|
||||
wget https://www.dmtf.org/sites/default/files/standards/documents/DSP2043_1.0.0.zip
|
||||
|
||||
After the download, extract the files somewhere in the file-system::
|
||||
|
||||
unzip DSP2043_1.0.0.zip -d <output-path>
|
||||
|
||||
Now run ``sushy-static`` pointing to those files. For example to serve
|
||||
the ``DSP2043-server`` mockup files, run::
|
||||
|
||||
sushy-static --mockup-files <output-path>/DSP2043-server
|
||||
|
||||
|
||||
Libvirt emulator
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
The second emulator shipped by `sushy-tools`_ is the CLI tool named
|
||||
``sushy-emulator``. This tool starts a ReST API that users can use to
|
||||
interact with virtual machines using the Redfish protocol. So operations
|
||||
such as changing the boot device or the power state will actually affect
|
||||
the virtual machines. This allows users to test the library in a more
|
||||
dynamic way. To run it do
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
sushy-emulator
|
||||
|
||||
# Or, running with custom parameters
|
||||
sushy-emulator --port 8000 --libvirt-uri "qemu:///system"
|
||||
|
||||
That's it, now you can test Sushy against the ``http://locahost:8000``
|
||||
endpoint.
|
||||
|
||||
|
||||
Enabling SSL
|
||||
~~~~~~~~~~~~
|
||||
|
||||
Both mockup servers supports `SSL`_ if you want Sushy with it. To set it
|
||||
up, first you need to generate key and certificate files with OpenSSL
|
||||
use following command::
|
||||
|
||||
openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -days 365
|
||||
|
||||
Start the mockup server passing the ``--ssl-certificate`` and
|
||||
``--ssl-key`` parameters to it to it, for example::
|
||||
|
||||
sushy-emulator --ssl-key key.pem --ssl-certificate cert.pem
|
||||
|
||||
Now to connect with `SSL`_ to the server use the ``verify`` parameter
|
||||
pointing to the certificate file when instantiating Sushy, for example:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
import sushy
|
||||
|
||||
# Note the HTTP"S"
|
||||
s = sushy.Sushy('https://localhost:8000', verify='cert.pem', username='foo', password='bar')
|
||||
|
||||
.. _SSL: https://en.wikipedia.org/wiki/Secure_Sockets_Layer
|
||||
.. _sushy-tools: https://git.openstack.org/cgit/openstack/sushy-tools
|
||||
|
|
|
@ -73,82 +73,6 @@ To use sushy in a project:
|
|||
print(sys_inst.get_allowed_system_boot_source_values())
|
||||
|
||||
|
||||
Running a mockup server
|
||||
-----------------------
|
||||
|
||||
Static mockup
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
Sushy ships a small script at ``tools/mockup_server.py``
|
||||
that creates a HTTP server to serve any of the `Redfish mockups
|
||||
<https://www.dmtf.org/standards/redfish>`_. The files are static so
|
||||
operations like changing the boot device or the power state **will not**
|
||||
have any effect. But that should be enough for enabling people to test
|
||||
parts of the library. To setup it do:
|
||||
|
||||
#. Download the .zip containing the Redfish mockups files from
|
||||
https://www.dmtf.org/standards/redfish, for example::
|
||||
|
||||
wget https://www.dmtf.org/sites/default/files/standards/documents/DSP2043_1.0.0.zip
|
||||
|
||||
#. Extract it somewhere in the file-system::
|
||||
|
||||
unzip DSP2043_1.0.0.zip -d <output-path>
|
||||
|
||||
#. Now run the ``mockup_server.py`` script::
|
||||
|
||||
python sushy/tools/mockup_server.py --mockup-files <output-path>/DSP2043-server --port 8000
|
||||
|
||||
|
||||
Libvirt mockup
|
||||
~~~~~~~~~~~~~~
|
||||
|
||||
Sushy also ships a small application at ``tools/mockup_server_libvirt``
|
||||
that starts a ReST API that users can use to interact with virtual
|
||||
machines using the Redfish protocol. So operations such as changing
|
||||
the boot device or the power state will actually affect the virtual
|
||||
machines. This allows users to test the library in a more dynamic way. To
|
||||
setup it do:
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
tox -elibvirt-simulator
|
||||
|
||||
# Or, running with custom parameters
|
||||
tox -elibvirt-simulator -- --port 8000 --libvirt-uri "qemu:///system"
|
||||
|
||||
.. note::
|
||||
Installing the dependencies requires libvirt development files.
|
||||
For example, run the following command to install them on Fedora::
|
||||
|
||||
sudo dnf install -y libvirt-devel
|
||||
|
||||
That's it, now you can test Sushy against the ``http://locahost:8000``
|
||||
endpoint.
|
||||
|
||||
|
||||
Enabling SSL
|
||||
~~~~~~~~~~~~
|
||||
|
||||
Both mockup servers supports `SSL`_ if you want Sushy with it. To set it
|
||||
up, first you need to generate key and certificate files with OpenSSL
|
||||
use following command::
|
||||
|
||||
openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -days 365
|
||||
|
||||
Start the mockup server passing the ``--ssl-certificate`` and
|
||||
``--ssl-key`` parameters to it to it, for example::
|
||||
|
||||
python sushy/tools/mockup_server.py --ssl-key key.pem --ssl-certificate cert.pem --mockup-files <output-path>/DSP2043-server --port 8000
|
||||
|
||||
Now to connect with `SSL`_ to the server use the ``verify`` parameter
|
||||
pointing to the certificate file when instantiating Sushy, for example:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
import sushy
|
||||
|
||||
# Note the HTTP"S"
|
||||
s = sushy.Sushy('https://localhost:8000', verify='cert.pem', username='foo', password='bar')
|
||||
|
||||
.. _SSL: https://en.wikipedia.org/wiki/Secure_Sockets_Layer
|
||||
If you do not have any real baremetal machine that supports the Redfish
|
||||
protocol you can look at the :ref:`contributing` page to learn how to
|
||||
run a Redfish emulator.
|
||||
|
|
|
@ -1,106 +0,0 @@
|
|||
#!/usr/bin/env python
|
||||
#
|
||||
# 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 argparse
|
||||
import os
|
||||
import ssl
|
||||
import sys
|
||||
|
||||
try:
|
||||
from http import server as http_server
|
||||
except ImportError:
|
||||
import BaseHTTPServer as http_server # Py2
|
||||
|
||||
REDFISH_MOCKUP_FILES = None
|
||||
|
||||
|
||||
class RequestHandler(http_server.BaseHTTPRequestHandler):
|
||||
|
||||
REDFISH_SUBURI = '/redfish/v1'
|
||||
|
||||
def _log_request(self, method):
|
||||
print(self.headers)
|
||||
content_length = int(self.headers.get('content-length', 0))
|
||||
if content_length > 0:
|
||||
print('Data: %s\n' % self.rfile.read(content_length))
|
||||
|
||||
def do_GET(self):
|
||||
self._log_request('GET')
|
||||
path = self.path.rstrip('/')
|
||||
if not path.startswith(self.REDFISH_SUBURI):
|
||||
self.send_error(404)
|
||||
return
|
||||
|
||||
resource_path = path.replace(self.REDFISH_SUBURI, '').lstrip('/')
|
||||
fpath = os.path.join(REDFISH_MOCKUP_FILES, resource_path, 'index.json')
|
||||
if not os.path.exists(fpath):
|
||||
self.send_error(404, 'Sub-URI %s not found' % resource_path)
|
||||
return
|
||||
|
||||
self.send_response(200)
|
||||
self.send_header('Content-type', 'application/json')
|
||||
self.end_headers()
|
||||
|
||||
with open(fpath, 'r') as f:
|
||||
self.wfile.write(f.read().encode('utf-8'))
|
||||
|
||||
def do_POST(self):
|
||||
self._log_request('POST')
|
||||
self.send_response(204)
|
||||
self.end_headers()
|
||||
|
||||
def do_PATCH(self):
|
||||
self._log_request('PATCH')
|
||||
self.send_response(204)
|
||||
self.end_headers()
|
||||
|
||||
|
||||
def parse_args():
|
||||
parser = argparse.ArgumentParser('MockupServer')
|
||||
parser.add_argument('-p', '--port',
|
||||
type=int,
|
||||
default=8000,
|
||||
help='The port to bind the server to')
|
||||
parser.add_argument('-m', '--mockup-files',
|
||||
type=str,
|
||||
required=True,
|
||||
help=('The path to the Redfish Mockup files in '
|
||||
'the filesystem'))
|
||||
parser.add_argument('-c', '--ssl-certificate',
|
||||
type=str,
|
||||
help='SSL certificate to use for HTTPS')
|
||||
parser.add_argument('-k', '--ssl-key',
|
||||
type=str,
|
||||
help='SSL key to use for HTTPS')
|
||||
return parser.parse_args()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
args = parse_args()
|
||||
if not os.path.exists(args.mockup_files):
|
||||
print('Mockup files %s not found' % args.mockup_files)
|
||||
sys.exit(1)
|
||||
|
||||
REDFISH_MOCKUP_FILES = os.path.realpath(args.mockup_files)
|
||||
httpd = http_server.HTTPServer(('', args.port), RequestHandler)
|
||||
|
||||
if args.ssl_certificate and args.ssl_key:
|
||||
httpd.socket = ssl.wrap_socket(
|
||||
httpd.socket, keyfile=args.ssl_key,
|
||||
certfile=args.ssl_certificate, server_side=True)
|
||||
|
||||
httpd.serve_forever()
|
|
@ -1,214 +0,0 @@
|
|||
#!/usr/bin/env python
|
||||
#
|
||||
# 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 argparse
|
||||
import ssl
|
||||
import xml.etree.ElementTree as ET
|
||||
|
||||
import flask
|
||||
import libvirt
|
||||
|
||||
app = flask.Flask(__name__)
|
||||
# Turn off strict_slashes on all routes
|
||||
app.url_map.strict_slashes = False
|
||||
|
||||
LIBVIRT_URI = None
|
||||
|
||||
BOOT_DEVICE_MAP = {
|
||||
'Pxe': 'network',
|
||||
'Hdd': 'hd',
|
||||
'Cd': 'cdrom',
|
||||
}
|
||||
|
||||
BOOT_DEVICE_MAP_REV = {v: k for k, v in BOOT_DEVICE_MAP.items()}
|
||||
|
||||
|
||||
class libvirt_open(object):
|
||||
|
||||
def __init__(self, uri, readonly=False):
|
||||
self.uri = uri
|
||||
self.readonly = readonly
|
||||
|
||||
def __enter__(self):
|
||||
try:
|
||||
self._conn = (libvirt.openReadOnly(self.uri)
|
||||
if self.readonly else
|
||||
libvirt.open(self.uri))
|
||||
return self._conn
|
||||
except libvirt.libvirtError as e:
|
||||
print('Error when connecting to the libvirt URI "%(uri)s": '
|
||||
'%(error)s' % {'uri': self.uri, 'error': e})
|
||||
flask.abort(500)
|
||||
|
||||
def __exit__(self, type, value, traceback):
|
||||
self._conn.close()
|
||||
|
||||
|
||||
def get_libvirt_domain(connection, domain):
|
||||
try:
|
||||
return connection.lookupByName(domain)
|
||||
except libvirt.libvirtError:
|
||||
flask.abort(404)
|
||||
|
||||
|
||||
@app.route('/redfish/v1/')
|
||||
def root_resource():
|
||||
return flask.render_template('root.json')
|
||||
|
||||
|
||||
@app.route('/redfish/v1/Systems')
|
||||
def system_collection_resource():
|
||||
with libvirt_open(LIBVIRT_URI, readonly=True) as conn:
|
||||
domains = conn.listDefinedDomains()
|
||||
return flask.render_template(
|
||||
'system_collection.json', system_count=len(domains),
|
||||
systems=domains)
|
||||
|
||||
|
||||
def _get_total_cpus(domain, tree):
|
||||
total_cpus = 0
|
||||
if domain.isActive():
|
||||
total_cpus = domain.maxVcpus()
|
||||
else:
|
||||
# If we can't get it from maxVcpus() try to find it by
|
||||
# inspecting the domain XML
|
||||
if total_cpus <= 0:
|
||||
vcpu_element = tree.find('.//vcpu')
|
||||
if vcpu_element is not None:
|
||||
total_cpus = int(vcpu_element.text)
|
||||
return total_cpus
|
||||
|
||||
|
||||
def _get_boot_source_target(tree):
|
||||
boot_source_target = None
|
||||
boot_element = tree.find('.//boot')
|
||||
if boot_element is not None:
|
||||
boot_source_target = (
|
||||
BOOT_DEVICE_MAP_REV.get(boot_element.get('dev')))
|
||||
return boot_source_target
|
||||
|
||||
|
||||
@app.route('/redfish/v1/Systems/<identity>', methods=['GET', 'PATCH'])
|
||||
def system_resource(identity):
|
||||
if flask.request.method == 'GET':
|
||||
with libvirt_open(LIBVIRT_URI, readonly=True) as conn:
|
||||
domain = get_libvirt_domain(conn, identity)
|
||||
power_state = 'On' if domain.isActive() else 'Off'
|
||||
total_memory_gb = int(domain.maxMemory() / 1024 / 1024)
|
||||
|
||||
tree = ET.fromstring(domain.XMLDesc())
|
||||
total_cpus = _get_total_cpus(domain, tree)
|
||||
boot_source_target = _get_boot_source_target(tree)
|
||||
|
||||
return flask.render_template(
|
||||
'system.json', identity=identity, uuid=domain.UUIDString(),
|
||||
power_state=power_state, total_memory_gb=total_memory_gb,
|
||||
total_cpus=total_cpus, boot_source_target=boot_source_target)
|
||||
|
||||
elif flask.request.method == 'PATCH':
|
||||
boot = flask.request.json.get('Boot')
|
||||
if not boot:
|
||||
return 'PATCH only works for the Boot element', 400
|
||||
|
||||
target = BOOT_DEVICE_MAP.get(boot.get('BootSourceOverrideTarget'))
|
||||
if not target:
|
||||
return 'Missing the BootSourceOverrideTarget element', 400
|
||||
|
||||
# NOTE(lucasagomes): In libvirt we always set the boot
|
||||
# device frequency to "continuous" so, we are ignoring the
|
||||
# BootSourceOverrideEnabled element here
|
||||
|
||||
# TODO(lucasagomes): We should allow changing the boot mode from
|
||||
# BIOS to UEFI (and vice-versa)
|
||||
|
||||
with libvirt_open(LIBVIRT_URI) as conn:
|
||||
domain = get_libvirt_domain(conn, identity)
|
||||
tree = ET.fromstring(domain.XMLDesc())
|
||||
for os_element in tree.findall('os'):
|
||||
# Remove all "boot" elements
|
||||
for boot_element in os_element.findall('boot'):
|
||||
os_element.remove(boot_element)
|
||||
|
||||
# Add a new boot element with the request boot device
|
||||
boot_element = ET.SubElement(os_element, 'boot')
|
||||
boot_element.set('dev', target)
|
||||
|
||||
conn.defineXML(ET.tostring(tree).decode('utf-8'))
|
||||
|
||||
return '', 204
|
||||
|
||||
|
||||
@app.route('/redfish/v1/Systems/<identity>/Actions/ComputerSystem.Reset',
|
||||
methods=['POST'])
|
||||
def system_reset_action(identity):
|
||||
reset_type = flask.request.json.get('ResetType')
|
||||
with libvirt_open(LIBVIRT_URI) as conn:
|
||||
domain = get_libvirt_domain(conn, identity)
|
||||
try:
|
||||
if reset_type in ('On', 'ForceOn'):
|
||||
if not domain.isActive():
|
||||
domain.create()
|
||||
elif reset_type == 'ForceOff':
|
||||
if domain.isActive():
|
||||
domain.destroy()
|
||||
elif reset_type == 'GracefulShutdown':
|
||||
if domain.isActive():
|
||||
domain.shutdown()
|
||||
elif reset_type == 'GracefulRestart':
|
||||
if domain.isActive():
|
||||
domain.reboot()
|
||||
elif reset_type == 'ForceRestart':
|
||||
if domain.isActive():
|
||||
domain.reset()
|
||||
elif reset_type == 'Nmi':
|
||||
if domain.isActive():
|
||||
domain.injectNMI()
|
||||
except libvirt.libvirtError:
|
||||
flask.abort(500)
|
||||
|
||||
return '', 204
|
||||
|
||||
|
||||
def parse_args():
|
||||
parser = argparse.ArgumentParser('MockupServerLibvirt')
|
||||
parser.add_argument('-p', '--port',
|
||||
type=int,
|
||||
default=8000,
|
||||
help='The port to bind the server to')
|
||||
parser.add_argument('-u', '--libvirt-uri',
|
||||
type=str,
|
||||
default='qemu:///system',
|
||||
help='The libvirt URI')
|
||||
parser.add_argument('-c', '--ssl-certificate',
|
||||
type=str,
|
||||
help='SSL certificate to use for HTTPS')
|
||||
parser.add_argument('-k', '--ssl-key',
|
||||
type=str,
|
||||
help='SSL key to use for HTTPS')
|
||||
return parser.parse_args()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
args = parse_args()
|
||||
LIBVIRT_URI = args.libvirt_uri
|
||||
|
||||
ssl_context = None
|
||||
if args.ssl_certificate and args.ssl_key:
|
||||
ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2)
|
||||
ssl_context.load_cert_chain(args.ssl_certificate, args.ssl_key)
|
||||
|
||||
app.run(host='', port=args.port, ssl_context=ssl_context)
|
|
@ -1,2 +0,0 @@
|
|||
flask
|
||||
libvirt-python
|
|
@ -1,36 +0,0 @@
|
|||
{
|
||||
"@odata.type": "#ServiceRoot.v1_0_2.ServiceRoot",
|
||||
"Id": "RedvirtService",
|
||||
"Name": "Redvirt Service",
|
||||
"RedfishVersion": "1.0.2",
|
||||
"UUID": "85775665-c110-4b85-8989-e6162170b3ec",
|
||||
"Systems": {
|
||||
"@odata.id": "/redfish/v1/Systems"
|
||||
},
|
||||
"Chassis": {
|
||||
"@odata.id": "/redfish/v1/Chassis"
|
||||
},
|
||||
"Managers": {
|
||||
"@odata.id": "/redfish/v1/Managers"
|
||||
},
|
||||
"Tasks": {
|
||||
"@odata.id": "/redfish/v1/TaskService"
|
||||
},
|
||||
"SessionService": {
|
||||
"@odata.id": "/redfish/v1/SessionService"
|
||||
},
|
||||
"AccountService": {
|
||||
"@odata.id": "/redfish/v1/AccountService"
|
||||
},
|
||||
"EventService": {
|
||||
"@odata.id": "/redfish/v1/EventService"
|
||||
},
|
||||
"Links": {
|
||||
"Sessions": {
|
||||
"@odata.id": "/redfish/v1/SessionService/Sessions"
|
||||
}
|
||||
},
|
||||
"@odata.context": "/redfish/v1/$metadata#ServiceRoot.ServiceRoot",
|
||||
"@odata.id": "/redfish/v1/",
|
||||
"@Redfish.Copyright": "Copyright 2014-2016 Distributed Management Task Force, Inc. (DMTF). For the full DMTF copyright policy, see http://www.dmtf.org/about/policies/copyright."
|
||||
}
|
|
@ -1,120 +0,0 @@
|
|||
{
|
||||
"@odata.type": "#ComputerSystem.v1_1_0.ComputerSystem",
|
||||
"Id": "{{ identity }}",
|
||||
"Name": "WebFrontEnd483",
|
||||
"SystemType": "Physical",
|
||||
"AssetTag": "Chicago-45Z-2381",
|
||||
"Manufacturer": "Contoso",
|
||||
"Model": "3500RX",
|
||||
"SKU": "8675309",
|
||||
"SerialNumber": "437XR1138R2",
|
||||
"PartNumber": "224071-J23",
|
||||
"Description": "Web Front End node",
|
||||
"UUID": "{{ uuid }}",
|
||||
"HostName": "web483",
|
||||
"Status": {
|
||||
"State": "Enabled",
|
||||
"Health": "OK",
|
||||
"HealthRollUp": "OK"
|
||||
},
|
||||
"IndicatorLED": "Off",
|
||||
"PowerState": "{{ power_state }}",
|
||||
"Boot": {
|
||||
"BootSourceOverrideEnabled": "Continuous",
|
||||
"BootSourceOverrideTarget": "{{ boot_source_target }}",
|
||||
"BootSourceOverrideTarget@Redfish.AllowableValues": [
|
||||
"Pxe",
|
||||
"Cd",
|
||||
"Hdd"
|
||||
],
|
||||
"BootSourceOverrideMode": "UEFI",
|
||||
"UefiTargetBootSourceOverride": "/0x31/0x33/0x01/0x01"
|
||||
},
|
||||
"TrustedModules": [
|
||||
{
|
||||
"FirmwareVersion": "1.13b",
|
||||
"InterfaceType": "TPM1_2",
|
||||
"Status": {
|
||||
"State": "Enabled",
|
||||
"Health": "OK"
|
||||
}
|
||||
}
|
||||
],
|
||||
"Oem": {
|
||||
"Contoso": {
|
||||
"@odata.type": "http://Contoso.com/Schema#Contoso.ComputerSystem",
|
||||
"ProductionLocation": {
|
||||
"FacilityName": "PacWest Production Facility",
|
||||
"Country": "USA"
|
||||
}
|
||||
},
|
||||
"Chipwise": {
|
||||
"@odata.type": "http://Chipwise.com/Schema#Chipwise.ComputerSystem",
|
||||
"Style": "Executive"
|
||||
}
|
||||
},
|
||||
"BiosVersion": "P79 v1.33 (02/28/2015)",
|
||||
"ProcessorSummary": {
|
||||
"Count": {{ total_cpus }},
|
||||
"ProcessorFamily": "Multi-Core Intel(R) Xeon(R) processor 7xxx Series",
|
||||
"Status": {
|
||||
"State": "Enabled",
|
||||
"Health": "OK",
|
||||
"HealthRollUp": "OK"
|
||||
}
|
||||
},
|
||||
"MemorySummary": {
|
||||
"TotalSystemMemoryGiB": {{ total_memory_gb }},
|
||||
"Status": {
|
||||
"State": "Enabled",
|
||||
"Health": "OK",
|
||||
"HealthRollUp": "OK"
|
||||
}
|
||||
},
|
||||
"Bios": {
|
||||
"@odata.id": "/redfish/v1/Systems/{{ identity }}/BIOS"
|
||||
},
|
||||
"Processors": {
|
||||
"@odata.id": "/redfish/v1/Systems/{{ identity }}/Processors"
|
||||
},
|
||||
"Memory": {
|
||||
"@odata.id": "/redfish/v1/Systems/{{ identity }}/Memory"
|
||||
},
|
||||
"EthernetInterfaces": {
|
||||
"@odata.id": "/redfish/v1/Systems/{{ identity }}/EthernetInterfaces"
|
||||
},
|
||||
"SimpleStorage": {
|
||||
"@odata.id": "/redfish/v1/Systems/{{ identity }}/SimpleStorage"
|
||||
},
|
||||
"LogServices": {
|
||||
"@odata.id": "/redfish/v1/Systems/{{ identity }}/LogServices"
|
||||
},
|
||||
"Links": {
|
||||
"Chassis": [
|
||||
],
|
||||
"ManagedBy": [
|
||||
]
|
||||
},
|
||||
"Actions": {
|
||||
"#ComputerSystem.Reset": {
|
||||
"target": "/redfish/v1/Systems/{{ identity }}/Actions/ComputerSystem.Reset",
|
||||
"ResetType@Redfish.AllowableValues": [
|
||||
"On",
|
||||
"ForceOff",
|
||||
"GracefulShutdown",
|
||||
"GracefulRestart",
|
||||
"ForceRestart",
|
||||
"Nmi",
|
||||
"ForceOn"
|
||||
]
|
||||
},
|
||||
"Oem": {
|
||||
"#Contoso.Reset": {
|
||||
"target": "/redfish/v1/Systems/{{ identity }}/Oem/Contoso/Actions/Contoso.Reset"
|
||||
}
|
||||
}
|
||||
},
|
||||
"@odata.context": "/redfish/v1/$metadata#ComputerSystem.ComputerSystem",
|
||||
"@odata.id": "/redfish/v1/Systems/{{ identity }}",
|
||||
"@Redfish.Copyright": "Copyright 2014-2016 Distributed Management Task Force, Inc. (DMTF). For the full DMTF copyright policy, see http://www.dmtf.org/about/policies/copyright."
|
||||
}
|
|
@ -1,15 +0,0 @@
|
|||
{
|
||||
"@odata.type": "#ComputerSystemCollection.ComputerSystemCollection",
|
||||
"Name": "Computer System Collection",
|
||||
"Members@odata.count": {{ system_count }},
|
||||
"Members": [
|
||||
{% for system in systems %}
|
||||
{
|
||||
"@odata.id": "/redfish/v1/Systems/{{ system }}"
|
||||
}{% if not loop.last %},{% endif %}
|
||||
{% endfor %}
|
||||
],
|
||||
"@odata.context": "/redfish/v1/$metadata#ComputerSystemCollection.ComputerSystemCollection",
|
||||
"@odata.id": "/redfish/v1/Systems",
|
||||
"@Redfish.Copyright": "Copyright 2014-2016 Distributed Management Task Force, Inc. (DMTF). For the full DMTF copyright policy, see http://www.dmtf.org/about/policies/copyright."
|
||||
}
|
4
tox.ini
4
tox.ini
|
@ -37,10 +37,6 @@ commands =
|
|||
[testenv:debug]
|
||||
commands = oslo_debug_helper {posargs}
|
||||
|
||||
[testenv:libvirt-simulator]
|
||||
commands = python tools/mockup_server_libvirt/mockup_server_libvirt.py {posargs}
|
||||
deps = -r{toxinidir}/tools/mockup_server_libvirt/requirements.txt
|
||||
|
||||
[flake8]
|
||||
# E123, E125 skipped as they are invalid PEP-8.
|
||||
|
||||
|
|
Loading…
Reference in New Issue