dmtf / redfish-interface-emulator Goto Github PK
View Code? Open in Web Editor NEWThe Redfish Interface Emulator can emulate a Redfish-based interface statically (GET) or dynamically (POST, PATCH, DELETE)
License: Other
The Redfish Interface Emulator can emulate a Redfish-based interface statically (GET) or dynamically (POST, PATCH, DELETE)
License: Other
The 'doc' folder contains the HowTo's for using and developing the Redfish Emulator as PDF files. Need to post as Markdown so the documentation can be updated.
Current ServiceRoot code has links to Chassis, Managers, etc. under a Links property:
According to the spec, only Oem and Sessions should be under Links, the rest of the references to other services should be root properties of the ServiceRoot object:
account_sevice.py should be renamed account_service.py
Internal contents are correct, so this is just a naming issue.
Accessing /redfish/v1/EventService produces the expected output, but causes an error message.
Running in Redfish mode
Traceback (most recent call last):
File "C:\Users\ddon\Documents\EmRf\api_emulator\redfish\EventService_api.py", line 33, in init
g.api.add_resource(SubscriptionCollectionAPI, '/redfish/v1/EventService/Subscriptions')
File "C:\Users\ddon\Documents\EmRf\lib\site-packages\flask_restful_init_.py", line 404, in add_resource
self.register_view(self.app, resource, *urls, **kwargs)
File "C:\Users\ddon\Documents\EmRf\lib\site-packages\flask_restful_init.py", line 470, in _register_view
app.add_url_rule(rule, view_func=resource_func, **kwargs)
File "C:\Users\ddon\Documents\EmRf\lib\site-packages\flask\app.py", line 64, in wrapper_func
return f(self, *args, **kwargs)
File "C:\Users\ddon\Documents\EmRf\lib\site-packages\flask\app.py", line 1051, in add_url_rule
'existing endpoint function: %s' % endpoint)
AssertionError: View function mapping is overwriting an existing endpoint function: subscriptioncollectionapi
The HTTPS functionality in this file was added to emulator.py. The functionality is controlled by the HTTPS property in emulator-config.json. Hence this file should be remove to avoid confusion.
Error message
except Exception,e:
^
SyntaxError: invalid syntax
The above is the Python 2.x syntax.
Using the Restlet Client, which does not do automatic redirection, the URLs that must be used for accessing static and dynamic emulator resources are different.
Dynamic resources must be accessed with URLs that do NOT end with a "/" character. If the URL for a dynamic resource ends with a "/" character, the emulator gives a "500 INTERNAL SERVER ERROR" response.
Static resources must be accessed with URLS that DO end with a "/" character. If the URL for a static resource does NOT end with a "/" character, the emulator gives a "301 MOVED PERMANENTLY" response, which is a redirect.
Create a rendition of unittest.py to act as hurdle/regression for changes to the emulator. It should test the basic functionality:
Need document on how to execute the infrastructure generator and the format of the input JSON (populate_config.json).
I was looking at the contents of /redfish/v1/Systems/System-/Processors/CPU in the static mockup. I think it would be helpful if the CPU data matched real processors. For example, /redfish/v1/Systems/System-7/Processors/CPU0 shows this:
"Manufacturer": "Intel(R) Corporation",
"Model": "Multi-Core Intel(R) Xeon(R) processor 7500 Series",
"ProcessorId": {
"VendorId": "GenuineIntel",
"IdentificationRegisters": "0x34AC34DC8901274A",
"EffectiveFamily": "0x42", <<< should be “0x6”
"EffectiveModel": "0x61", <<< should be “0x2E”
"Step": "0x1", <<< should be “0x6”
"MicrocodeInfo": "0x429943" <<< should be “0x0000000B” or higher
If permissible by this team, I'd be happy to make a patch with the correct values. Please let me know. Thanks!
If a request to a resource is made that is invalid or no longer there, looking up the resource will hit a KeyError. This should be fine, but the error handling for this attempts to get the exception information by accessing the 'message' property. Not all exceptions have a message property, including KeyError, so this causes the following:
Traceback (most recent call last):
File "emulator.py", line 180, in get
config = self.get_configuration(resource_manager, path)
File "emulator.py", line 282, in get_configuration
raise PathError("Resource not found: " + str(e.message))
AttributeError: 'KeyError' object has no attribute 'message'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/Users/smcginnis/repos/SNIA/Swordfish/venv/lib/python3.7/site-packages/flask/app.py", line 1813, in full_dispatch_request
rv = self.dispatch_request()
File "/Users/smcginnis/repos/SNIA/Swordfish/venv/lib/python3.7/site-packages/flask/app.py", line 1799, in dispatch_request
return self.view_functionsrule.endpoint
File "/Users/smcginnis/repos/SNIA/Swordfish/venv/lib/python3.7/site-packages/flask_restful/init.py", line 458, in wrapper
resp = resource(*args, **kwargs)
File "/Users/smcginnis/repos/SNIA/Swordfish/venv/lib/python3.7/site-packages/flask/views.py", line 88, in view
return self.dispatch_request(*args, **kwargs)
File "/Users/smcginnis/repos/SNIA/Swordfish/venv/lib/python3.7/site-packages/flask_restful/init.py", line 573, in dispatch_request
resp = meth(*args, **kwargs)
File "emulator.py", line 189, in get
resp = INTERNAL_ERROR_Get
NameError: name 'INTERNAL_ERROR_Get' is not defined
In addition to the e.message issue, there appears to be a typo with INTERNAL_ERROR_Get. We only have an INTERNAL_ERROR variable defined, and it would appear this is what is supposed to be used there.
The emulation code for the ./Systems/{id}/ResetAction resource in located in the file ./api_emulator/redfish/ComputerSystem/ResetAction.py. A behavior of a reset action is to change the ComputerSystem.Status.State property. However, this requires the code import a module within the ComputerSystem.py code in the parent directory. Python 3.3 removed relative imports, so imports from a parent directory requires hacking PYTHONPATH or adding the parent-path to sys.path.
There is a request for a cleaner way.
Running the unmodified code from master, the emulator outputs an error on the console whenever EventService is accessed with a normal GET:
GET http://localhost:5000/redfish/v1/EventService
The Restlet Client receives a "200 OK" result and an OK-seeming Body from this GET, but the following traceback and error message appears on the console:
Traceback (most recent call last):
File "C:\Users\ddon\Documents\EmRf\api_emulator\redfish\EventService_api.py", line 33, in init
g.api.add_resource(SubscriptionCollectionAPI, '/redfish/v1/EventService/Subscriptions')
File "C:\Users\ddon\Documents\EmRf\lib\site-packages\flask_restful_init_.py", line 404, in add_resource
self.register_view(self.app, resource, *urls, **kwargs)
File "C:\Users\ddon\Documents\EmRf\lib\site-packages\flask_restful_init.py", line 470, in _register_view
app.add_url_rule(rule, view_func=resource_func, **kwargs)
File "C:\Users\ddon\Documents\EmRf\lib\site-packages\flask\app.py", line 64, in wrapper_func
return f(self, *args, **kwargs)
File "C:\Users\ddon\Documents\EmRf\lib\site-packages\flask\app.py", line 1051, in add_url_rule
'existing endpoint function: %s' % endpoint)
AssertionError: View function mapping is overwriting an existing endpoint function: subscriptioncollectionapi
The emulator currently returns "[email protected]" as the member count for several object collections (Chassis, ComputerSystem, etc). According to section 6.5.5.2 of the spec [0] this should actually be the plural form of "[email protected]". That plural form is actually correct in most places, but a few need correction.
The emulator reports the service version in the ServiceRoot object under the property name ServiceVersion. According to the spec though, the correct property name should be RedfishVersion:
how to change this populate-config.json file based on my requirements?
Chassis Count -1 Cartridge Count -12 or 24 (Server , storage,NIC,FPGA ,GPU) Each Cartridge node count -2 or 4 (if cartridge is server) SwitchCard count -2 Each SwitchCard Device count -2 (Storage ,NIC ,FPGA,GPU)
A POST command to add a new instance to the ComputerSystem collection fails with an error message that says “KeyError: ‘Links’”. This happens no matter what is in the body of the POST command.
After reviewing the pull request history (see #16 ), this appears to be a consequence of the way support for composed systems was added to the ComputerSystem dynamic resource. Perhaps that work was not completed?
The code in emulator.py seems to assume that ./infra_gen/populate_config.json exists. The populate step should be options (come up empty if desired). Options to do this are:
# Calls INFRAGEN and populates emulator according to populate-config.json
with open(INFRAGEN_CONFIG, 'r') as f:
infragen_config = json.load(f)
populate(infragen_config.get('POPULATE',10))
PATCH on Chassis returns 500 Internal Server Error.
Redfish interface emulator is a standard API designed or standard data-model designed
There are four files that talk about Python dependencies, but they do not agree with each other:
(1) dependencies/Python Packages to place in directory.txt
(2) install.py
(3) installing_dependencies.txt
(4) requirements.txt
It would be good to have at least the requirements.txt file brought up-to-date with what is currently needed. Here is a list of packages that work for stand-alone operation on Windows (I'm not sure about the list of packages needed for other situations):
setuptools
markupsafe
itsdangerous
flask
aniso8601
pytz
flask_httpauth
requests
flask_restful
StringGenerator==0.2.1
urllib3
The version of StringGenerator is specified in this list because the latest version of StringGenerator (0.3.0) does not install on my Windows system.
If the other files that talk about Python dependencies are also still needed, they should be made to be consistent with an updated requirements.txt file.
How to install intel cloud foundry in ubuntu
Emulator_ssl.py file not available
It should be possible to add new resources to many Redfish collections by doing a POST command to the collection. This currently works for the emulator's Chassis dynamic resource, but it fails for the rest of the emulator’s current set of dynamic resources.
Note: A similar problem with the ComputerSystem collection was reported separately (see #44 ), where the problems seem to be strongly tied to the way Infragen was implemented. The problem being reported here is for the other (non-ComputerSystem) dynamic resources, since it looks like they can be fixed without impacting the way Infragen currently works.
Request to place a container on Docker Hub - like was done for Redfish-Mockup-Server.
Attempts to access any of the systems under /redfish/v1/Systems result in the error.
Reason:
In Python 3, dict.values() (along with dict.keys() and dict.items()) returns a view, rather than a list. Therefor, one needs to wrap the call to dict.values() in a call to list. So: v = d.values() becomes v = list(d.values())
from flask import Flask
from flask_restful import Resource, Api
import sys, traceback
import copy
import strgen
from utils import replace_recurse
from Acclipc.mdc_webtask import *
BASE_PATH = "/redfish/v1/"
app = Flask(name)
api = Api(app)
class ResourceCollection(Resource):
def init(self):
self.rest_base = BASE_PATH
self.uuid = ""
def get(self):
"""
Configuration property - Service Root
"""
config = {
'@odata.context': self.rest_base + '$metadata#ServiceRoot',
'@odata.type': '#ServiceRoot.1.0.0.ServiceRoot',
'@odata.id': self.rest_base,
'Id': 'RootService',
'Name': 'Root Service',
'ServiceVersion': '1.0.0',
'UUID': self.uuid,
'Links': {
'Chassis': {'@odata.id': self.rest_base + 'Chassis'}
}
}
return config
class Chassis(Resource):
def __init__(self):
self.rb = BASE_PATH
self.config = {
'@odata.context': self.rb + '$metadata#ChassisCollection.ChassisCollection',
'@odata.id': self.rb + 'Chassis',
'@odata.type': '#ChassisCollection.1.0.0.ChassisCollection',
'Name': 'Chassis Collection',
'[email protected]': 1,
'Member' : self.rb + 'Chassis/Chassis-1',
}
def get(self):
try:
resp = self.config, 200
except Exception:
traceback.print_exc()
resp = INTERNAL_ERROR
return resp
class Chassisinfo(Resource):
def __init__(self):
self.rb = BASE_PATH
self.config = {
"@odata.context": self.rb +"$metadata#Chassis.Chassis",
"@odata.id": self.rb + "Chassis",
"@odata.type": "#Chassis.v1_0_0.Chassis",
'Name': 'MDC System Chassis',
"ChassisType": "RackMount",
"SerialNumber": "",
"PartNumber": "",
"MaxPower": "",
"Chassis ID": "",
"AssetTag": "",
"Oem": {
"Links": {
"Cartridge": [
{
"@odata.id": self.rb +"Chassis/Chassis-1/Cartridge"
}
],
"Switch": [
{
"@odata.id": self.rb +"Chassis/Chassis-1/Switch"
}
]
}
}
}
def get(self,ident):
global wildcards
res = login("accl","accl")
result = chassisinfo()
self.config['@odata.id']= self.rb + ident
self.config['PartNumber']= result[0]
self.config['SerialNumber']= result[1]
self.config['MaxPower']= result[2]
self.config['Chassis ID']= result[3]
self.config['AssetTag']= result[4]
return self.config, 200
class CartridgeCollection(Resource):
def __init__(self):
self.rb = BASE_PATH
self.cartridge = "Cartridge"
self.switch = "Switch"
self.config = {
'@odata.context': self.rb + '$metadata#cartridgeCollection.cartridgeCollection',
'@odata.id': self.rb + 'Cartridge',
'@odata.type': '#cartridgeCollection.1.0.0.cartridgeCollection',
'Name': 'Cartridge Collection',
'Links': {}
}
self.config['Links']['[email protected]'] = ''
self.config['Links']['Members'] = ''
def get(self,ident1,ident2):
if ident2 == self.cartridge:
self.config['Name']=self.cartridge + " Collection"
self.config['Links']['[email protected]'] = 12
self.config['Links']['Members'] = ''
return self.config, 200
elif ident2 == self.switch:
self.config['Name']=self.switch + " Collection"
self.config['Links']['[email protected]'] = 2
self.config['Links']['Members'] = ''
return self.config, 200
api.add_resource(ResourceCollection, '/redfish/v1')
api.add_resource(Chassis, '/redfish/v1/Chassis')
api.add_resource(Chassisinfo, '/redfish/v1/Chassis/string:ident')
api.add_resource(CartridgeCollection, '/redfish/v1/Chassis/string:ident1/string:ident2')
if name == 'main':
app.run('0.0.0.0', debug=True)
I am really new to this so please be kind...
I am seeing the following error when I try to start the Emulator "Traceback (most recent call last):
File "emulator.py", line 20, in
import g
File "/data/Redfish-Interface-Emulator/g.py", line 11, in
from flask import Flask
ImportError: No module named flask"
Any guidance would be appreciated!
Thanks.
redfish service get data from redfish host , redfish host is like any third-party(like inter process communication ,database ) software or need to use any specific commands.
I created my own mockup with a live redfish service from the Redfish-Mockup-Creator and Redfish-Mockup-Server runs as expected. However, when I follow the instructions to use my own mockup with the Redfish-Interface-Emulator it doesn't see my mockup that I'm trying to use. Replacing the \api_emulator\redfish\static directory with my mockup doesn't work. The readme and instructions found in /doc seem to be a little inconsistent, and I'm trying to find out what I'm doing wrong.
Use cases:
(Associated to Swordfish-Interface-Emulator repository issue 18)
Many of the dynamic resources in the emulator are supposed to support emulator-only singleton POST commands that create new resource instances from pre-defined templates. These POST commands currently fail, due to a conflict with the way Infragen was added to the emulator.
Infragen uses the emulator’s internal method calls in dynamic resources instead of the Redfish API, and by itself this might have been OK, but in many cases the merged Infragen code made changes to the methods themselves in dynamic resources. These changes are causing failures for the POST commands that are supposed to create new instances from pre-defined templates.
There is no easy way to fix this problem. If the singleton POST commands are fixed to work as originally intended, Infragen will break. If the emulator is left the way it is, the ability to add new instances from pre-defined templates will remain broken. A reasonable solution would be to fix the emulator to work as originally intended, and to revise Infragen to work via the Redfish API instead of using the emulator’s internal method calls.
The Chassis collection properties "[email protected]" and "Members" are currently being put inside a Links list.
According to the schema http://redfish.dmtf.org/schemas/v1/ChassisCollection.json, these two should be direct properties of the ChassisCollection object, and there is no ChassisCollection.Links property.
Currently, SNIA is extending code base to become the Swordfish Interface Emulator. The instructions for putting the packages together is getting complex. It would be simpler if ‘pip redfish-emul’ could be run, followed by ‘pip swordfish-emul’.
Hello,
I visite the "Chassis/{ChassisId}/Power" URL and find that the "@odata.type" is "#Power.v1_0_0.PowerMetrics", perhaps it should be "#Power.v1_0_0.Power"
Thank you.
There are several print commands in install.py, with no parentheses.
They need parentheses to be able to run with python3.5+
Using a "/" at the end of a URI makes a difference with the emulator, depending upon whether it is for a leaf node (one at the edge of the tree) or a non-leaf node (one inside the tree).
For example, this is what happens when accessing a leaf node:
GET http://localhost:5000/redfish/v1/Systems/CS_5 results in a 200 OK response and produces reasonable output, but...
GET http://localhost:5000/redfish/v1/Systems/CS_5/ gets a 500 Internal Server Error response and the emulator console reports an exception originating in emulator.py.
However, this is what happens when accessing a non-leaf node:
GET http://localhost:5000/redfish/v1/Systems results in a 301 Moved Permanently response, and...
GET http://localhost:5000/redfish/v1/Systems/ results in a 200 OK response and produces reasonable output.
Note that the emulator behavior is different for getting a 200 OK response, depending upon whether the URI is for a leaf node or a non-leaf node.
This behavior is made more obvious by the Chrome Restlet Client extension. By default, Restlet does not automatically follow redirects, so if you leave the trailing "/" off for a non-leaf node, you'll get a 301 Moved Permanently response. Using the same URI with a trailing "/" (or telling Restlet to follow redirects) gets a 200 OK response. But having a trailing "/" on a leaf node causes an exception.
The Chrome Advance REST Client (ARC) seems to silently follow redirects, so there's no obvious difference between having or not having a trailing "/" on a URI for a non-leaf node. But having a trailing "/" on a leaf node still causes an exception.
Should the emulator be showing these differences between having and not having a trailing "/" on URIs?
Hi,
I'm new to the Redfish API and maybe I'm misunderstanding the proposal of the emulator. There is a way to only allow the creation of the new system with valid resources?
From the tests I performed, the Emulator doesn't do any validation against the ResourceDictionary created when the emulator starts. It seems the initial POPULATE is used only to provide some initial examples and not to initialize which will be the valid infrastructure ...
I was expecting that in a POST to CreateGenericComputerSystem, I was enforced to provide a valid existing configuration (payload). Without this validation I was able to create systems with invalid NumberOfProcessors, for example, or any other invalid resource.
I'm misunderstanding the concept of the emulator? There is a way to do this check if a configuration is valid during the POST?
I'm trying to use it as a datacenter emulator of available resources to play (evaluate) different allocation policies of these resources, but to do that I can't have an allocation of an invalid resource. Maybe I need to create an intermediate layer to validate with the GET if the Composed system has only valid existing resources ...
Thank you!
Describe that enabling HTTPS, requires the key and cert files to exist in the execution directly - specifically named server.key and server.cert.
The Status struct is defined as being:
{ "Health": "Ok", "HealthRollup": "Ok", "Oem": "foo", "State": "Enabled" }
http://redfish.dmtf.org/schemas/v1/Resource.json
There are several emulated objects that incorrectly introduce an additional layer of a "State" key for the status the looks like:
{ "State": { "Health": "Ok", "HealthRollup": "Ok", "Oem": "foo", "State": "Enabled" } }
The following are examples of this incorrect format:
All of these are defined as having a Status
property of type Status
.
Correct examples can be found in:
And several other locations.
I got the following error when I run install.py
FileNotFoundError: [Errno 2] No such file or directory: 'Flask-RESTful-0.3.1.zip'
I installed Flask-RESTful-0.3.1 using pip, which gives the following error;
No matching distribution found for Flask-RESTful-0.3.1
if I use "pip install -r requirements.txt" command, it adds the following directory:
/usr/lib64/python3.6/site-packages/flask_restful
its version is 3.6.
and it does not contain any zip file.
I also checked:
https://github.com/flask-restful/flask-restful
It does not contain version 0.3.1
redfish emulator data is hard coded.i want read actual system chassis details and sensor details how to get actual information from system (can we use IPC communication to get data from other software ?)
The file unittests.py has two minor Python syntax issues raised if we try to run it:
File "unittests.py", line 62
logger.info('PASS: GET of {0} successful (response below)\n {1}'.format(getting, r.text))
^
TabError: inconsistent use of tabs and spaces in indentation
File "unittests.py", line 156
print'Testing interface at:', sys.argv[2]
^
SyntaxError: invalid syntax
The documentation refers to the file: emulator_config.json
several times. The file is actually named: emulator-config.json
Both my IBM CentOS server and my local wsl CentOS image are both getting a 404 return on a POST request. It is happening with both http and https requests. I would think the problem may be in the flask module or maybe requests.
Client side:
(venv) [root@IBM-R912JTS2 emulator]# curl -X POST -k -H 'Content-Type: application/json' https://9.114.207.147:5000/redfish/v1/SessionService/Sessions -d '{"UserName":"Admin"}'
curl: (7) Failed to connect to 9.114.207.147 port 5000: Connection refused
(venv) [root@IBM-R912JTS2 emulator]# clear
(venv) [root@IBM-R912JTS2 emulator]# curl -X POST -k -H 'Content-Type: application/json' https://172.24.225.83:5000/redfish/v1/SessionService/Sessions -d '{"UserName":"Admin"}'
""(venv) [root@IBM-R912JTS2 emulator]# curl -X GET -H 'Content-Type: application/json' https://172.24.225.83:5000/redfish/v1/
curl: (60) SSL certificate problem: self signed certificate
More details here: https://curl.haxx.se/docs/sslcerts.html
curl failed to verify the legitimacy of the server and therefore could not
establish a secure connection to it. To learn more about this situation and
how to fix it, please visit the web page mentioned above.
(venv) [root@IBM-R912JTS2 emulator]# curl -k -X GET -H 'Content-Type: application/json' https://172.24.225.83:5000/redfish/v1/
{
"@odata.context": "/redfish/v1/$metadata#ServiceRoot",
"@odata.type": "#ServiceRoot.1.0.0.ServiceRoot",
"@odata.id": "/redfish/v1/",
....
Server side:
(venv) [root@IBM-R912JTS2 emulator]# python3 emulator.py
/mnt/c/Users/C-VS95897/venv/lib64/python3.6/site-packages/requests/init.py:104: RequestsDependencyWarning: urllib3 (1.26.9) or chardet (5.0.0)/charset_normalizer (2.0.12) doesn't match a supported version!
RequestsDependencyWarning)
INFO:root:Mockup folders
['Redfish']
(From Don Deel) Everything looks good at first. Using a browser (or the Restlet Client in Chrome) I can see the Redfish service root and access things like the Chassis and Managers collections. But no matter what I do, attempting to access Systems results in an “Internal Server Error” message. The emulator itself keeps running, the same way it would if I simply mis-typed something.
There are several objects that have a ServiceEnabled boolean property. Most are correctly returning this as it's defined as a boolean, but the following are returning the string "true" instead:
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.