[staging/edk2-redfish-client Tools PATCH 1/6] RedfishClientPkg/Tools: Initial commit of Redfish Profile Simulator


Abner Chang
 

This is an open source project on DMTF GitHub.
(https://github.com/DMTF/Redfish-Profile-Simulator)
This tool simulates the HTTP request methods (POST, PATCH, PUT, GET) on
Redfish resource maintained by Redfish Profile Simulator.
EDK2 open source uses this simulator for the use case when Redfish service
has not been set up on the platform, or for the quick Redfish firmware
feature development.

We clone this project under RedfishClientPkg and maintain it by edk2
because this project has currently been using and updating rarely.
That is easier for edk2 to add features to the simulator or modify the
simulator to align with edk2 requirement on Redfish service.

The license of this tool is on the term of BSD 3-Clause License.
Refer to LICENSE.md.

Signed-off-by: Abner Chang <abner.chang@hpe.com>
Cc: Nickle Wang <nickle.wang@hpe.com>
Cc: Liming Gao <gaoliming@byosoft.com.cn>
---
.../Redfish-Profile-Simulator/AUTHORS.md | 2 +
.../Redfish-Profile-Simulator/CHANGELOG.md | 15 +
.../Redfish-Profile-Simulator/LICENSE.md | 57 ++++
.../Tools/Redfish-Profile-Simulator/README.md | 96 ++++++
.../SimpleOcpServerV1/redfish/index.json | 3 +
.../redfish/v1/$metadata/index.xml | 147 +++++++++
.../v1/AccountService/Accounts/index.json | 19 ++
.../AccountService/Accounts/jane/index.json | 19 ++
.../AccountService/Accounts/john/index.json | 19 ++
.../AccountService/Accounts/root/index.json | 19 ++
.../v1/AccountService/Roles/Admin/index.json | 17 +
.../AccountService/Roles/Operator/index.json | 15 +
.../Roles/ReadOnlyUser/index.json | 13 +
.../v1/AccountService/Roles/index.json | 19 ++
.../redfish/v1/AccountService/index.json | 25 ++
.../redfish/v1/Chassis/A33/Power/index.json | 28 ++
.../redfish/v1/Chassis/A33/Thermal/index.json | 150 +++++++++
.../redfish/v1/Chassis/A33/index.json | 46 +++
.../redfish/v1/Chassis/index.json | 13 +
.../bmc/EthernetInterfaces/eth0/index.json | 60 ++++
.../bmc/EthernetInterfaces/index.json | 15 +
.../Managers/bmc/NetworkProtocol/index.json | 47 +++
.../redfish/v1/Managers/bmc/index.json | 53 +++
.../redfish/v1/Managers/index.json | 13 +
.../Sessions/SESSION123456/index.json | 10 +
.../v1/SessionService/Sessions/index.json | 12 +
.../redfish/v1/SessionService/index.json | 17 +
.../LogServices/SEL/Entries/1/index.json | 27 ++
.../LogServices/SEL/Entries/2/index.json | 27 ++
.../LogServices/SEL/Entries/index.json | 62 ++++
.../2M220100SL/LogServices/SEL/index.json | 27 ++
.../Systems/2M220100SL/LogServices/index.json | 15 +
.../redfish/v1/Systems/2M220100SL/index.json | 70 ++++
.../redfish/v1/Systems/index.json | 13 +
.../SimpleOcpServerV1/redfish/v1/index.json | 31 ++
.../redfish/v1/odata/index.json | 56 ++++
.../redfishProfileSimulator.py | 125 +++++++
.../v1sim/__init__.py | 4 +
.../v1sim/accountService.py | 76 +++++
.../v1sim/chassis.py | 115 +++++++
.../v1sim/common_services.py | 28 ++
.../v1sim/flask_redfish_auth.py | 278 ++++++++++++++++
.../v1sim/managers.py | 211 ++++++++++++
.../v1sim/network.py | 48 +++
.../v1sim/redfishURIs.py | 309 ++++++++++++++++++
.../v1sim/resource.py | 100 ++++++
.../v1sim/security.py | 35 ++
.../v1sim/serviceRoot.py | 87 +++++
.../v1sim/serviceVersions.py | 9 +
.../v1sim/sessionService.py | 41 +++
.../v1sim/storage.py | 116 +++++++
.../v1sim/systems.py | 198 +++++++++++
.../v1sim/updateService.py | 84 +++++
53 files changed, 3141 insertions(+)
create mode 100644 RedfishClientPkg/Tools/Redfish-Profile-Simulator/AUTHORS.md
create mode 100644 RedfishClientPkg/Tools/Redfish-Profile-Simulator/CHANGELOG.md
create mode 100644 RedfishClientPkg/Tools/Redfish-Profile-Simulator/LICENSE.md
create mode 100644 RedfishClientPkg/Tools/Redfish-Profile-Simulator/README.md
create mode 100644 RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/index.json
create mode 100644 RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/$metadata/index.xml
create mode 100644 RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/AccountService/Accounts/index.json
create mode 100644 RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/AccountService/Accounts/jane/index.json
create mode 100644 RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/AccountService/Accounts/john/index.json
create mode 100644 RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/AccountService/Accounts/root/index.json
create mode 100644 RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/AccountService/Roles/Admin/index.json
create mode 100644 RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/AccountService/Roles/Operator/index.json
create mode 100644 RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/AccountService/Roles/ReadOnlyUser/index.json
create mode 100644 RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/AccountService/Roles/index.json
create mode 100644 RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/AccountService/index.json
create mode 100644 RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/Chassis/A33/Power/index.json
create mode 100644 RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/Chassis/A33/Thermal/index.json
create mode 100644 RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/Chassis/A33/index.json
create mode 100644 RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/Chassis/index.json
create mode 100644 RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/Managers/bmc/EthernetInterfaces/eth0/index.json
create mode 100644 RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/Managers/bmc/EthernetInterfaces/index.json
create mode 100644 RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/Managers/bmc/NetworkProtocol/index.json
create mode 100644 RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/Managers/bmc/index.json
create mode 100644 RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/Managers/index.json
create mode 100644 RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/SessionService/Sessions/SESSION123456/index.json
create mode 100644 RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/SessionService/Sessions/index.json
create mode 100644 RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/SessionService/index.json
create mode 100644 RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/Systems/2M220100SL/LogServices/SEL/Entries/1/index.json
create mode 100644 RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/Systems/2M220100SL/LogServices/SEL/Entries/2/index.json
create mode 100644 RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/Systems/2M220100SL/LogServices/SEL/Entries/index.json
create mode 100644 RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/Systems/2M220100SL/LogServices/SEL/index.json
create mode 100644 RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/Systems/2M220100SL/LogServices/index.json
create mode 100644 RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/Systems/2M220100SL/index.json
create mode 100644 RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/Systems/index.json
create mode 100644 RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/index.json
create mode 100644 RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/odata/index.json
create mode 100644 RedfishClientPkg/Tools/Redfish-Profile-Simulator/redfishProfileSimulator.py
create mode 100644 RedfishClientPkg/Tools/Redfish-Profile-Simulator/v1sim/__init__.py
create mode 100644 RedfishClientPkg/Tools/Redfish-Profile-Simulator/v1sim/accountService.py
create mode 100644 RedfishClientPkg/Tools/Redfish-Profile-Simulator/v1sim/chassis.py
create mode 100644 RedfishClientPkg/Tools/Redfish-Profile-Simulator/v1sim/common_services.py
create mode 100644 RedfishClientPkg/Tools/Redfish-Profile-Simulator/v1sim/flask_redfish_auth.py
create mode 100644 RedfishClientPkg/Tools/Redfish-Profile-Simulator/v1sim/managers.py
create mode 100644 RedfishClientPkg/Tools/Redfish-Profile-Simulator/v1sim/network.py
create mode 100644 RedfishClientPkg/Tools/Redfish-Profile-Simulator/v1sim/redfishURIs.py
create mode 100644 RedfishClientPkg/Tools/Redfish-Profile-Simulator/v1sim/resource.py
create mode 100644 RedfishClientPkg/Tools/Redfish-Profile-Simulator/v1sim/security.py
create mode 100644 RedfishClientPkg/Tools/Redfish-Profile-Simulator/v1sim/serviceRoot.py
create mode 100644 RedfishClientPkg/Tools/Redfish-Profile-Simulator/v1sim/serviceVersions.py
create mode 100644 RedfishClientPkg/Tools/Redfish-Profile-Simulator/v1sim/sessionService.py
create mode 100644 RedfishClientPkg/Tools/Redfish-Profile-Simulator/v1sim/storage.py
create mode 100644 RedfishClientPkg/Tools/Redfish-Profile-Simulator/v1sim/systems.py
create mode 100644 RedfishClientPkg/Tools/Redfish-Profile-Simulator/v1sim/updateService.py

diff --git a/RedfishClientPkg/Tools/Redfish-Profile-Simulator/AUTHORS.md b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/AUTHORS.md
new file mode 100644
index 0000000000..536f67e918
--- /dev/null
+++ b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/AUTHORS.md
@@ -0,0 +1,2 @@
+# Original Contribution:
+* Paul Vancil - Dell Inc. -- Dell Extreme Scale Infrastructure (ESI) Architecture Team
diff --git a/RedfishClientPkg/Tools/Redfish-Profile-Simulator/CHANGELOG.md b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/CHANGELOG.md
new file mode 100644
index 0000000000..38bb8685d1
--- /dev/null
+++ b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/CHANGELOG.md
@@ -0,0 +1,15 @@
+# Change Log
+
+## [0.9.6] - 2018-05-25
+- Fixed setuptools config to install all necessary Python modules
+- Enabled OpenBMC Static OBmcMonolythicPower8
+- Made simulator more generic to support other mockups
+- Fixed several properties in the Computer System resource
+- Fixed Content-Type header when returning XML
+
+## [0.9.2] - 2016-12-08
+- Fixex code to work with late change in mockup data. It was failing to load
+- Fixed incomplete code in systems.py modeling logs
+
+## [0.9.1] - 2016-09-06
+- Initial Public Release
diff --git a/RedfishClientPkg/Tools/Redfish-Profile-Simulator/LICENSE.md b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/LICENSE.md
new file mode 100644
index 0000000000..18e3361b0d
--- /dev/null
+++ b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/LICENSE.md
@@ -0,0 +1,57 @@
+The Distributed Management Task Force (DMTF) grants rights under copyright in
+this software on the terms of the BSD 3-Clause License as set forth below; no
+other rights are granted by DMTF. This software might be subject to other rights
+(such as patent rights) of other parties.
+
+
+### Copyrights.
+
+Copyright (c) 2016, Contributing Member(s) of Distributed Management Task Force,
+Inc.. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice, this
+list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above copyright notice, this
+list of conditions and the following disclaimer in the documentation and/or
+other materials provided with the distribution.
+* Neither the name of the Distributed Management Task Force (DMTF) nor the names
+of its contributors may be used to endorse or promote products derived from this
+software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+### Patents.
+
+This software may be subject to third party patent rights, including provisional
+patent rights ("patent rights"). DMTF makes no representations to users of the
+standard as to the existence of such rights, and is not responsible to
+recognize, disclose, or identify any or all such third party patent right,
+owners or claimants, nor for any incomplete or inaccurate identification or
+disclosure of such rights, owners or claimants. DMTF shall have no liability to
+any party, in any manner or circumstance, under any legal theory whatsoever, for
+failure to recognize, disclose, or identify any such third party patent rights,
+or for such party's reliance on the software or incorporation thereof in its
+product, protocols or testing procedures. DMTF shall have no liability to any
+party using such software, whether such use is foreseeable or not, nor to any
+patent owner or claimant, and shall have no liability or responsibility for
+costs or losses incurred if software is withdrawn or modified after publication,
+and shall be indemnified and held harmless by any party using the software from
+any and all claims of infringement by a patent owner for such use.
+
+DMTF Members that contributed to this software source code might have made
+patent licensing commitments in connection with their participation in the DMTF.
+For details, see http://dmtf.org/sites/default/files/patent-10-18-01.pdf and
+http://www.dmtf.org/about/policies/disclosures.
diff --git a/RedfishClientPkg/Tools/Redfish-Profile-Simulator/README.md b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/README.md
new file mode 100644
index 0000000000..660938f880
--- /dev/null
+++ b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/README.md
@@ -0,0 +1,96 @@
+Copyright 2016-2018 Distributed Management Task Force, Inc. All rights reserved.
+
+# Redfish Profile Simulator
+
+## About
+
+***Redfish Profile Simulator*** is a Python34 real simulator of the "simple monolithic server" feature profile.
+
+* A simple, minimal Redfish Service
+* For a monolithic Server
+* Aligned with: OCP Remote Machine Management Spec feature set
+
+### Description
+
+* Based on flask
+* Initial resources are loaded from a catfish mockup into python dictionary structures
+ * After that, data is read/patched... to the dictionaries
+* Supports BasicAuth, as well as Redfish Session Auth (for one session, one user)
+* Uses:
+ * easy to add new URIs for testing a client
+ * easy to tweak behavior or add bad responses to test a client
+ * allows testing of authentication -- which current mockup servers dont do
+ * easy to insert print statements in service to see if data coming across good..etc
+
+### Current Limitation:
+
+* supports a single user/passwd and token
+* the user/passwd is: root/password123456
+* The authToken for Session Auth is: 123456SESSIONauthcode
+* Supports only HTTP (not HTTPS)
+* with redfishtool, use options: redfishtool.py -r127.0.0.1:5000 -u root -p password123456 -S Never <subcmd>
+
+## Usage
+
+* ` python redfishProfileSimulatorMain.py [options]`
+* `[Options]`:
+
+ -V, --Version,--- the program version
+ -h, --help, --- help
+ -H<hostIP>, --Host=<hostIp> --- host IP address. dflt=127.0.0.1
+ -P<port>,--Port=<port> --- the port to use. dflt=5000
+ -p<profile_path>, --profile=<profile_path> --- the path to the Redfish profile to use. dflt="SimpleOcpServerV1"
+
+## Implementation
+
+* The simulation includes an http server, RestEngine, and dynamic Redfish datamodel.
+* You can GET, PATCH,... to the service just like a real Redfish service.
+* Both Basic and Redfish Session/Token authentication are supported
+ * for a single user/passwd and token
+ * the user/passwd is: root/password123456
+ * The authToken for Session Auth is: 123456SESSIONauthcode
+ * these can be changed by editing the redfishURSs.py file---will make dynamic later.
+* The http service and Rest engine is built on Flask, and all code is Python 3.4+
+* The data model resources are "initialized" from the SPMF "SimpleOcpServerV1" Mockup.
+ * and stored as python dictionaries
+ * then the dictionaries are updated with patches, posts, deletes.
+* The program can be extended to support other mockup \"profiles\".
+* By default, the simulation runs on localhost (127.0.0.1), on port 5000.
+ * These can be changed with CLI options: -P<port> -H <hostIP> | --port=<port> --host=<hostIp>
+
+## Simple OCP Server V1 Mockup Description
+
+* A Monolithic server:
+ * One ComputerSystem
+ * One Chassis
+ * One Manager
+
+* Provides basic management features aligned with OCP Remote Machine Management Spec 1.01:
+ * Power-on/off/reset
+ * Boot to PXE, HDD, BIOS setup (boot override)
+ * 4 temp sensors per DCMI (CPU1, CPU2, Board, Inlet)
+ * Simple Power Reading, and DCMI Power Limiting
+ * Fan Monitoring w/ redundancy
+ * Set asset tag and Indicator LED
+ * Basic inventory (serial#, model, SKU, Vendor, BIOS ver…)
+ * User Management
+ * BMC management: get/set IP, version, enable/disable protocol
+
+* What it does NOT have -- that the Redfish 1.0 model supports
+ * No PSUs in model (RMM spec did not include PSUs)
+ * No ProcessorInfo, MemoryInfo, StorageInfo, System-EthernetInterfaceInfo
+ * No Tasks
+ * JsonSchema and Registries collections left out (since that is optional)
+ * No EventService--Remote Machine Management spec used basic PET alerts
+ * Uses only the pre-defined privileges and roles
+
+## TO DO
+
+Some limitations to be extended in current implementation
+
+* Auth supports a single hard-coded username, password, and AuthToken, although the protocol is 100% compliant with respect to testing clients trying to authenticate
+ * ex with basic auth, you have to use the hard coded user/password
+ * ex with Session Auth, you just use the hard coded AuthToken
+* adding and deleting users not implemented--has 3 or 4 users predefined
+* accountService properties can be written, but failed logins, lockouts, etc is not implemented
+* system log not implemented yet
diff --git a/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/index.json b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/index.json
new file mode 100644
index 0000000000..759e3e6fdb
--- /dev/null
+++ b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/index.json
@@ -0,0 +1,3 @@
+{
+ "v1": "/redfish/v1/"
+}
diff --git a/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/$metadata/index.xml b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/$metadata/index.xml
new file mode 100644
index 0000000000..37d9529b10
--- /dev/null
+++ b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/$metadata/index.xml
@@ -0,0 +1,147 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright 2014-2016 Distributed Management Task Force, Inc. (DMTF). For the full DMTF copyright policy, see http://www.dmtf.org/about/policies/copyright.-->
+<edmx:Edmx xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx" Version="4.0">
+
+ <edmx:Reference Uri="http://redfish.dmtf.org/schemas/v1/ServiceRoot_v1.xml">
+ <edmx:Include Namespace="ServiceRoot"/>
+ <edmx:Include Namespace="ServiceRoot.v1_0_2"/>
+ </edmx:Reference>
+ <edmx:Reference Uri="http://redfish.dmtf.org/schemas/v1/AccountService_v1.xml">
+ <edmx:Include Namespace="AccountService"/>
+ <edmx:Include Namespace="AccountService.v1_0_2"/>
+ </edmx:Reference>
+ <edmx:Reference Uri="http://redfish.dmtf.org/schemas/v1/Chassis_v1.xml">
+ <edmx:Include Namespace="Chassis"/>
+ <edmx:Include Namespace="Chassis.v1_2_0"/>
+ </edmx:Reference>
+ <edmx:Reference Uri="http://redfish.dmtf.org/schemas/v1/ChassisCollection_v1.xml">
+ <edmx:Include Namespace="ChassisCollection"/>
+ </edmx:Reference>
+ <edmx:Reference Uri="http://redfish.dmtf.org/schemas/v1/ComputerSystem_v1.xml">
+ <edmx:Include Namespace="ComputerSystem"/>
+ <edmx:Include Namespace="ComputerSystem.v1_1_0"/>
+ </edmx:Reference>
+ <edmx:Reference Uri="http://redfish.dmtf.org/schemas/v1/ComputerSystemCollection_v1.xml">
+ <edmx:Include Namespace="ComputerSystemCollection"/>
+ </edmx:Reference>
+ <edmx:Reference Uri="http://redfish.dmtf.org/schemas/v1/EthernetInterface_v1.xml">
+ <edmx:Include Namespace="EthernetInterface"/>
+ <edmx:Include Namespace="EthernetInterface.v1_0_2"/>
+ </edmx:Reference>
+ <edmx:Reference Uri="http://redfish.dmtf.org/schemas/v1/EthernetInterfaceCollection_v1.xml">
+ <edmx:Include Namespace="EthernetInterfaceCollection"/>
+ </edmx:Reference>
+ <edmx:Reference Uri="http://redfish.dmtf.org/schemas/v1/IPAddresses_v1.xml">
+ <edmx:Include Namespace="IPAddresses"/>
+ <edmx:Include Namespace="IPAddresses.v1_0_2"/>
+ </edmx:Reference>
+ <edmx:Reference Uri="http://redfish.dmtf.org/schemas/v1/JsonSchemaFile_v1.xml">
+ <edmx:Include Namespace="JsonSchemaFile"/>
+ <edmx:Include Namespace="JsonSchemaFile.v1_0_2"/>
+ </edmx:Reference>
+ <edmx:Reference Uri="http://redfish.dmtf.org/schemas/v1/JsonSchemaFileCollection_v1.xml">
+ <edmx:Include Namespace="JsonSchemaFileCollection"/>
+ </edmx:Reference>
+ <edmx:Reference Uri="http://redfish.dmtf.org/schemas/v1/EventDestination_v1.xml">
+ <edmx:Include Namespace="EventDestination"/>
+ <edmx:Include Namespace="EventDestination.v1_0_2"/>
+ </edmx:Reference>
+ <edmx:Reference Uri="http://redfish.dmtf.org/schemas/v1/EventDestinationCollection_v1.xml">
+ <edmx:Include Namespace="EventDestinationCollection"/>
+ </edmx:Reference>
+ <edmx:Reference Uri="http://redfish.dmtf.org/schemas/v1/LogEntry_v1.xml">
+ <edmx:Include Namespace="LogEntry"/>
+ <edmx:Include Namespace="LogEntry.v1_0_2"/>
+ </edmx:Reference>
+ <edmx:Reference Uri="http://redfish.dmtf.org/schemas/v1/LogEntryCollection_v1.xml">
+ <edmx:Include Namespace="LogEntryCollection"/>
+ </edmx:Reference>
+ <edmx:Reference Uri="http://redfish.dmtf.org/schemas/v1/Role_v1.xml">
+ <edmx:Include Namespace="Role"/>
+ <edmx:Include Namespace="Role.v1_0_2"/>
+ </edmx:Reference>
+ <edmx:Reference Uri="http://redfish.dmtf.org/schemas/v1/RoleCollection_v1.xml">
+ <edmx:Include Namespace="RoleCollection"/>
+ </edmx:Reference>
+ <edmx:Reference Uri="http://redfish.dmtf.org/schemas/v1/LogService_v1.xml">
+ <edmx:Include Namespace="LogService"/>
+ <edmx:Include Namespace="LogService.v1_0_2"/>
+ </edmx:Reference>
+ <edmx:Reference Uri="http://redfish.dmtf.org/schemas/v1/LogServiceCollection_v1.xml">
+ <edmx:Include Namespace="LogServiceCollection"/>
+ </edmx:Reference>
+ <edmx:Reference Uri="http://redfish.dmtf.org/schemas/v1/Manager_v1.xml">
+ <edmx:Include Namespace="Manager"/>
+ <edmx:Include Namespace="Manager.v1_1_0"/>
+ </edmx:Reference>
+ <edmx:Reference Uri="http://redfish.dmtf.org/schemas/v1/ManagerCollection_v1.xml">
+ <edmx:Include Namespace="ManagerCollection"/>
+ </edmx:Reference>
+ <edmx:Reference Uri="http://redfish.dmtf.org/schemas/v1/ManagerAccount_v1.xml">
+ <edmx:Include Namespace="ManagerAccount"/>
+ <edmx:Include Namespace="ManagerAccount.v1_0_2"/>
+ </edmx:Reference>
+ <edmx:Reference Uri="http://redfish.dmtf.org/schemas/v1/ManagerAccountCollection_v1.xml">
+ <edmx:Include Namespace="ManagerAccountCollection"/>
+ </edmx:Reference>
+ <edmx:Reference Uri="http://redfish.dmtf.org/schemas/v1/ManagerNetworkProtocol_v1.xml">
+ <edmx:Include Namespace="ManagerNetworkProtocol"/>
+ <edmx:Include Namespace="ManagerNetworkProtocol.v1_0_2"/>
+ </edmx:Reference>
+ <edmx:Reference Uri="http://redfish.dmtf.org/schemas/v1/Message_v1.xml">
+ <edmx:Include Namespace="Message"/>
+ <edmx:Include Namespace="Message.v1_0_2"/>
+ </edmx:Reference>
+ <edmx:Reference Uri="http://redfish.dmtf.org/schemas/v1/MessageRegistry_v1.xml">
+ <edmx:Include Namespace="MessageRegistry"/>
+ <edmx:Include Namespace="MessageRegistry.v1_0_2"/>
+ </edmx:Reference>
+ <edmx:Reference Uri="http://redfish.dmtf.org/schemas/v1/MessageRegistryCollection_v1.xml">
+ <edmx:Include Namespace="MessageRegistryCollection"/>
+ </edmx:Reference>
+ <edmx:Reference Uri="http://redfish.dmtf.org/schemas/v1/MessageRegistryFile_v1.xml">
+ <edmx:Include Namespace="MessageRegistryFile"/>
+ <edmx:Include Namespace="MessageRegistryFile.v1_0_2"/>
+ </edmx:Reference>
+ <edmx:Reference Uri="http://redfish.dmtf.org/schemas/v1/MessageRegistryFileCollection_v1.xml">
+ <edmx:Include Namespace="MessageRegistryFileCollection"/>
+ </edmx:Reference>
+ <edmx:Reference Uri="http://redfish.dmtf.org/schemas/v1/PhysicalContext_v1.xml">
+ <edmx:Include Namespace="PhysicalContext"/>
+ <edmx:Include Namespace="PhysicalContext.v1_0_2"/>
+ </edmx:Reference>
+ <edmx:Reference Uri="http://redfish.dmtf.org/schemas/v1/Power_v1.xml">
+ <edmx:Include Namespace="Power"/>
+ <edmx:Include Namespace="Power.v1_1_0"/>
+ </edmx:Reference>
+ <edmx:Reference Uri="http://redfish.dmtf.org/schemas/v1/Privileges_v1.xml">
+ <edmx:Include Namespace="Privileges"/>
+ <edmx:Include Namespace="Privileges.v1_0_2"/>
+ </edmx:Reference>
+ <edmx:Reference Uri="http://redfish.dmtf.org/schemas/v1/Session_v1.xml">
+ <edmx:Include Namespace="Session"/>
+ <edmx:Include Namespace="Session.v1_0_2"/>
+ </edmx:Reference>
+ <edmx:Reference Uri="http://redfish.dmtf.org/schemas/v1/SessionCollection_v1.xml">
+ <edmx:Include Namespace="SessionCollection"/>
+ </edmx:Reference>
+ <edmx:Reference Uri="http://redfish.dmtf.org/schemas/v1/SessionService_v1.xml">
+ <edmx:Include Namespace="SessionService"/>
+ <edmx:Include Namespace="SessionService.v1_0_2"/>
+ </edmx:Reference>
+ <edmx:Reference Uri="http://redfish.dmtf.org/schemas/v1/Thermal_v1.xml">
+ <edmx:Include Namespace="Thermal"/>
+ <edmx:Include Namespace="Thermal.v1_1_0"/>
+ </edmx:Reference>
+ <edmx:Reference Uri="http://redfish.dmtf.org/schemas/v1/RedfishExtensions_v1.xml">
+ <edmx:Include Namespace="RedfishExtensions.v1_0_0" Alias="Redfish"/>
+ </edmx:Reference>
+
+ <edmx:DataServices>
+
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Service">
+ <EntityContainer Name="Service" Extends="ServiceRoot.v1_0_0.ServiceContainer"/>
+ </Schema>
+
+ </edmx:DataServices>
+</edmx:Edmx>
diff --git a/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/AccountService/Accounts/index.json b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/AccountService/Accounts/index.json
new file mode 100644
index 0000000000..80f0cf34e6
--- /dev/null
+++ b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/AccountService/Accounts/index.json
@@ -0,0 +1,19 @@
+{
+ "@odata.type": "#ManagerAccountCollection.ManagerAccountCollection",
+ "Name": "Accounts Collection",
+ "Members@odata.count": 3,
+ "Members": [
+ {
+ "@odata.id": "/redfish/v1/AccountService/Accounts/root"
+ },
+ {
+ "@odata.id": "/redfish/v1/AccountService/Accounts/jane"
+ },
+ {
+ "@odata.id": "/redfish/v1/AccountService/Accounts/john"
+ }
+ ],
+ "@odata.context": "/redfish/v1/$metadata#ManagerAccountCollection.ManagerAccountCollection",
+ "@odata.id": "/redfish/v1/AccountService/Accounts",
+ "@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."
+}
diff --git a/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/AccountService/Accounts/jane/index.json b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/AccountService/Accounts/jane/index.json
new file mode 100644
index 0000000000..51e2ce59a9
--- /dev/null
+++ b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/AccountService/Accounts/jane/index.json
@@ -0,0 +1,19 @@
+{
+ "@odata.type": "#ManagerAccount.v1_0_2.ManagerAccount",
+ "Id": "jane",
+ "Name": "UserAccount",
+ "Description": "User Account",
+ "Enabled": true,
+ "Password": null,
+ "UserName": "jane",
+ "RoleId": "Operator",
+ "Locked": false,
+ "Links": {
+ "Role": {
+ "@odata.id": "/redfish/v1/AccountService/Roles/Operator"
+ }
+ },
+ "@odata.context": "/redfish/v1/$metadata#ManagerAccount.ManagerAccount",
+ "@odata.id": "/redfish/v1/AccountService/Accounts/jane",
+ "@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."
+}
diff --git a/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/AccountService/Accounts/john/index.json b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/AccountService/Accounts/john/index.json
new file mode 100644
index 0000000000..a8106d6e88
--- /dev/null
+++ b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/AccountService/Accounts/john/index.json
@@ -0,0 +1,19 @@
+{
+ "@odata.type": "#ManagerAccount.v1_0_2.ManagerAccount",
+ "Id": "john",
+ "Name": "UserAccount",
+ "Description": "User Account",
+ "Enabled": true,
+ "Password": null,
+ "UserName": "john",
+ "RoleId": "ReadOnlyUser",
+ "Locked": false,
+ "Links": {
+ "Role": {
+ "@odata.id": "/redfish/v1/AccountService/Roles/ReadOnlyUser"
+ }
+ },
+ "@odata.context": "/redfish/v1/$metadata#ManagerAccount.ManagerAccount",
+ "@odata.id": "/redfish/v1/AccountService/Accounts/john",
+ "@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."
+}
diff --git a/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/AccountService/Accounts/root/index.json b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/AccountService/Accounts/root/index.json
new file mode 100644
index 0000000000..c966e7c771
--- /dev/null
+++ b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/AccountService/Accounts/root/index.json
@@ -0,0 +1,19 @@
+{
+ "@odata.type": "#ManagerAccount.v1_0_2.ManagerAccount",
+ "Id": "root",
+ "Name": "UserAccount",
+ "Description": "User Account",
+ "Enabled": true,
+ "Password": null,
+ "UserName": "root",
+ "RoleId": "Admin",
+ "Locked": false,
+ "Links": {
+ "Role": {
+ "@odata.id": "/redfish/v1/AccountService/Roles/Admin"
+ }
+ },
+ "@odata.context": "/redfish/v1/$metadata#ManagerAccount.ManagerAccount",
+ "@odata.id": "/redfish/v1/AccountService/Accounts/root",
+ "@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."
+}
diff --git a/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/AccountService/Roles/Admin/index.json b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/AccountService/Roles/Admin/index.json
new file mode 100644
index 0000000000..4debc374de
--- /dev/null
+++ b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/AccountService/Roles/Admin/index.json
@@ -0,0 +1,17 @@
+{
+ "@odata.type": "#Role.v1_0_2.Role",
+ "Id": "Admin",
+ "Name": "User Role",
+ "Description": "Admin User Role",
+ "IsPredefined": true,
+ "AssignedPrivileges": [
+ "Login",
+ "ConfigureManager",
+ "ConfigureUsers",
+ "ConfigureSelf",
+ "ConfigureComponents"
+ ],
+ "@odata.context": "/redfish/v1/$metadata#Role.Role",
+ "@odata.id": "/redfish/v1/AccountService/Roles/Admin",
+ "@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."
+}
diff --git a/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/AccountService/Roles/Operator/index.json b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/AccountService/Roles/Operator/index.json
new file mode 100644
index 0000000000..f30e747c16
--- /dev/null
+++ b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/AccountService/Roles/Operator/index.json
@@ -0,0 +1,15 @@
+{
+ "@odata.type": "#Role.v1_0_2.Role",
+ "Id": "Operator",
+ "Name": "User Role",
+ "Description": "Operator User Role",
+ "IsPredefined": true,
+ "AssignedPrivileges": [
+ "Login",
+ "ConfigureSelf",
+ "ConfigureComponents"
+ ],
+ "@odata.context": "/redfish/v1/$metadata#Role.Role",
+ "@odata.id": "/redfish/v1/AccountService/Roles/Operator",
+ "@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."
+}
diff --git a/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/AccountService/Roles/ReadOnlyUser/index.json b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/AccountService/Roles/ReadOnlyUser/index.json
new file mode 100644
index 0000000000..09a8cc3961
--- /dev/null
+++ b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/AccountService/Roles/ReadOnlyUser/index.json
@@ -0,0 +1,13 @@
+{
+ "@odata.type": "#Role.v1_0_2.Role",
+ "Id": "ReadOnlyUser",
+ "Name": "User Role",
+ "Description": "ReadOnlyUser User Role",
+ "IsPredefined": true,
+ "AssignedPrivileges": [
+ "Login"
+ ],
+ "@odata.context": "/redfish/v1/$metadata#Role.Role",
+ "@odata.id": "/redfish/v1/AccountService/Roles/ReadOnlyUser",
+ "@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."
+}
diff --git a/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/AccountService/Roles/index.json b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/AccountService/Roles/index.json
new file mode 100644
index 0000000000..f295d07d1f
--- /dev/null
+++ b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/AccountService/Roles/index.json
@@ -0,0 +1,19 @@
+{
+ "@odata.type": "#RoleCollection.RoleCollection",
+ "Name": "Roles Collection",
+ "Members@odata.count": 3,
+ "Members": [
+ {
+ "@odata.id": "/redfish/v1/AccountService/Roles/Admin"
+ },
+ {
+ "@odata.id": "/redfish/v1/AccountService/Roles/Operator"
+ },
+ {
+ "@odata.id": "/redfish/v1/AccountService/Roles/ReadOnlyUser"
+ }
+ ],
+ "@odata.context": "/redfish/v1/$metadata#RoleCollection.RoleCollection",
+ "@odata.id": "/redfish/v1/AccountService/Roles",
+ "@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."
+}
diff --git a/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/AccountService/index.json b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/AccountService/index.json
new file mode 100644
index 0000000000..f0e3659588
--- /dev/null
+++ b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/AccountService/index.json
@@ -0,0 +1,25 @@
+{
+ "@odata.type": "#AccountService.v1_0_2.AccountService",
+ "Id": "AccountService",
+ "Name": "Account Service",
+ "Description": "Account Service",
+ "Status": {
+ "State": "Enabled",
+ "Health": "OK"
+ },
+ "ServiceEnabled": true,
+ "AuthFailureLoggingThreshold": 3,
+ "MinPasswordLength": 8,
+ "AccountLockoutThreshold": 5,
+ "AccountLockoutDuration": 30,
+ "AccountLockoutCounterResetAfter": 30,
+ "Accounts": {
+ "@odata.id": "/redfish/v1/AccountService/Accounts"
+ },
+ "Roles": {
+ "@odata.id": "/redfish/v1/AccountService/Roles"
+ },
+ "@odata.context": "/redfish/v1/$metadata#AccountService.AccountService",
+ "@odata.id": "/redfish/v1/AccountService",
+ "@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."
+}
diff --git a/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/Chassis/A33/Power/index.json b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/Chassis/A33/Power/index.json
new file mode 100644
index 0000000000..04094bf678
--- /dev/null
+++ b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/Chassis/A33/Power/index.json
@@ -0,0 +1,28 @@
+{
+ "@odata.type": "#Power.v1_1_0.Power",
+ "Id": "Power",
+ "Name": "Power",
+ "PowerControl": [
+ {
+ "@odata.id": "/redfish/v1/Chassis/A33/Power#/PowerControl/0",
+ "MemberId": "0",
+ "Name": "System Power Control",
+ "PowerConsumedWatts": 224,
+ "PowerCapacityWatts": 600,
+ "PowerLimit": {
+ "LimitInWatts": 450,
+ "LimitException": "LogEventOnly",
+ "CorrectionInMs": 1000
+ },
+ "Status": {
+ "State": "Enabled",
+ "Health": "OK"
+ },
+ "Oem": {}
+ }
+ ],
+ "Oem": {},
+ "@odata.context": "/redfish/v1/$metadata#Power.Power",
+ "@odata.id": "/redfish/v1/Chassis/A33/Power",
+ "@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."
+}
diff --git a/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/Chassis/A33/Thermal/index.json b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/Chassis/A33/Thermal/index.json
new file mode 100644
index 0000000000..e7b92a34e1
--- /dev/null
+++ b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/Chassis/A33/Thermal/index.json
@@ -0,0 +1,150 @@
+{
+ "@odata.type": "#Thermal.v1_1_0.Thermal",
+ "Id": "Thermal",
+ "Name": "Thermal",
+ "Temperatures": [
+ {
+ "@odata.id": "/redfish/v1/Chassis/A33/Thermal#/Temperatures/0",
+ "MemberId": "0",
+ "Name": "Inlet Temp",
+ "SensorNumber": 42,
+ "Status": {
+ "State": "Enabled",
+ "Health": "OK"
+ },
+ "ReadingCelsius": 25,
+ "UpperThresholdNonCritical": 35,
+ "UpperThresholdCritical": 40,
+ "UpperThresholdFatal": 50,
+ "MinReadingRangeTemp": 0,
+ "MaxReadingRangeTemp": 200,
+ "PhysicalContext": "Intake"
+ },
+ {
+ "@odata.id": "/redfish/v1/Chassis/A33/Thermal#/Temperatures/1",
+ "MemberId": "1",
+ "Name": "Board Temp",
+ "SensorNumber": 43,
+ "Status": {
+ "State": "Enabled",
+ "Health": "OK"
+ },
+ "ReadingCelsius": 35,
+ "UpperThresholdNonCritical": 30,
+ "UpperThresholdCritical": 40,
+ "UpperThresholdFatal": 50,
+ "MinReadingRangeTemp": 0,
+ "MaxReadingRangeTemp": 200,
+ "PhysicalContext": "SystemBoard"
+ },
+ {
+ "@odata.id": "/redfish/v1/Chassis/A33/Thermal#/Temperatures/2",
+ "MemberId": "2",
+ "Name": "CPU1 Temp",
+ "SensorNumber": 44,
+ "Status": {
+ "State": "Enabled",
+ "Health": "OK"
+ },
+ "ReadingCelsius": 45,
+ "UpperThresholdNonCritical": 60,
+ "UpperThresholdCritical": 82,
+ "MinReadingRangeTemp": 0,
+ "MaxReadingRangeTemp": 200,
+ "PhysicalContext": "CPU"
+ },
+ {
+ "@odata.id": "/redfish/v1/Chassis/A33/Thermal#/Temperatures/3",
+ "MemberId": "3",
+ "Name": "CPU2 Temp",
+ "SensorNumber": 45,
+ "Status": {
+ "State": "Enabled",
+ "Health": "OK"
+ },
+ "ReadingCelsius": 46,
+ "UpperThresholdNonCritical": 60,
+ "UpperThresholdCritical": 82,
+ "MinReadingRangeTemp": 0,
+ "MaxReadingRangeTemp": 200,
+ "PhysicalContext": "CPU"
+ }
+ ],
+ "Fans": [
+ {
+ "@odata.id": "/redfish/v1/Chassis/A33/Thermal#/Fans/0",
+ "MemberId": "0",
+ "Name": "BaseBoard System Fan 1",
+ "PhysicalContext": "Backplane",
+ "Status": {
+ "State": "Enabled",
+ "Health": "OK"
+ },
+ "Reading": 2100,
+ "ReadingUnits": "RPM",
+ "UpperThresholdNonCritical": 42,
+ "UpperThresholdCritical": 4200,
+ "UpperThresholdFatal": 42,
+ "LowerThresholdNonCritical": 42,
+ "LowerThresholdCritical": 5,
+ "LowerThresholdFatal": 42,
+ "MinReadingRange": 0,
+ "MaxReadingRange": 5000,
+ "Redundancy": [
+ {
+ "@odata.id": "/redfish/v1/Chassis/A33/Thermal#/Redundancy/0"
+ }
+ ]
+ },
+ {
+ "@odata.id": "/redfish/v1/Chassis/A33/Thermal#/Fans/1",
+ "MemberId": "1",
+ "Name": "BaseBoard System Fan 2",
+ "PhysicalContext": "Backplane",
+ "Status": {
+ "State": "Enabled",
+ "Health": "OK"
+ },
+ "Reading": 2100,
+ "ReadingUnits": "RPM",
+ "UpperThresholdNonCritical": 42,
+ "UpperThresholdCritical": 4200,
+ "UpperThresholdFatal": 42,
+ "LowerThresholdNonCritical": 42,
+ "LowerThresholdCritical": 5,
+ "LowerThresholdFatal": 42,
+ "MinReadingRange": 0,
+ "MaxReadingRange": 5000,
+ "Redundancy": [
+ {
+ "@odata.id": "/redfish/v1/Chassis/A33/Thermal#/Redundancy/0"
+ }
+ ]
+ }
+ ],
+ "Redundancy": [
+ {
+ "@odata.id": "/redfish/v1/Chassis/A33/Thermal#/Redundancy/0",
+ "MemberId": "0",
+ "Name": "BaseBoard System Fans",
+ "RedundancySet": [
+ {
+ "@odata.id": "/redfish/v1/Chassis/A33/Thermal#/Fans/0"
+ },
+ {
+ "@odata.id": "/redfish/v1/Chassis/A33/Thermal#/Fans/1"
+ }
+ ],
+ "Mode": "N+m",
+ "Status": {
+ "State": "Enabled",
+ "Health": "OK"
+ },
+ "MinNumNeeded": 1,
+ "MaxNumSupported": 2
+ }
+ ],
+ "@odata.context": "/redfish/v1/$metadata#Thermal.Thermal",
+ "@odata.id": "/redfish/v1/Chassis/A33/Thermal",
+ "@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."
+}
diff --git a/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/Chassis/A33/index.json b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/Chassis/A33/index.json
new file mode 100644
index 0000000000..74e2de8d7a
--- /dev/null
+++ b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/Chassis/A33/index.json
@@ -0,0 +1,46 @@
+{
+ "@odata.type": "#Chassis.v1_2_0.Chassis",
+ "Id": "A33",
+ "Name": "Catfish System Chassis",
+ "ChassisType": "RackMount",
+ "Manufacturer": "CatfishManufacturer",
+ "Model": "YellowCat1000",
+ "SerialNumber": "2M220100SL",
+ "SKU": "8675309",
+ "PartNumber": "224071-J23",
+ "AssetTag": "CATFISHASSETTAG",
+ "IndicatorLED": "Lit",
+ "PowerState": "On",
+ "Status": {
+ "State": "Enabled",
+ "Health": "OK"
+ },
+ "Thermal": {
+ "@odata.id": "/redfish/v1/Chassis/A33/Thermal"
+ },
+ "Power": {
+ "@odata.id": "/redfish/v1/Chassis/A33/Power"
+ },
+ "Links": {
+ "ComputerSystems": [
+ {
+ "@odata.id": "/redfish/v1/Systems/2M220100SL"
+ }
+ ],
+ "ManagedBy": [
+ {
+ "@odata.id": "/redfish/v1/Managers/bmc"
+ }
+ ],
+ "ManagersInChassis": [
+ {
+ "@odata.id": "/redfish/v1/Managers/bmc"
+ }
+ ],
+ "Oem": {}
+ },
+ "Oem": {},
+ "@odata.context": "/redfish/v1/$metadata#Chassis.Chassis",
+ "@odata.id": "/redfish/v1/Chassis/A33",
+ "@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."
+}
diff --git a/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/Chassis/index.json b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/Chassis/index.json
new file mode 100644
index 0000000000..fb90ededfd
--- /dev/null
+++ b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/Chassis/index.json
@@ -0,0 +1,13 @@
+{
+ "@odata.type": "#ChassisCollection.ChassisCollection",
+ "Name": "Chassis Collection",
+ "Members@odata.count": 1,
+ "Members": [
+ {
+ "@odata.id": "/redfish/v1/Chassis/A33"
+ }
+ ],
+ "@odata.context": "/redfish/v1/$metadata#ChassisCollection.ChassisCollection",
+ "@odata.id": "/redfish/v1/Chassis",
+ "@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."
+}
diff --git a/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/Managers/bmc/EthernetInterfaces/eth0/index.json b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/Managers/bmc/EthernetInterfaces/eth0/index.json
new file mode 100644
index 0000000000..f3e8528dc4
--- /dev/null
+++ b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/Managers/bmc/EthernetInterfaces/eth0/index.json
@@ -0,0 +1,60 @@
+{
+ "@odata.type": "#EthernetInterface.v1_0_2.EthernetInterface",
+ "Id": "eth0",
+ "Name": "Manager Ethernet Interface",
+ "Description": "Management Network Interface",
+ "Status": {
+ "State": "Enabled",
+ "Health": "OK"
+ },
+ "InterfaceEnabled": true,
+ "PermanentMACAddress": "AA:BB:CC:DD:EE:FF",
+ "MACAddress": "AA:BB:CC:DD:EE:FF",
+ "SpeedMbps": 100,
+ "AutoNeg": true,
+ "FullDuplex": true,
+ "MTUSize": 1500,
+ "HostName": "MyHostName",
+ "FQDN": "MyHostName.MyDomainName.com",
+ "MaxIPv6StaticAddresses": 1,
+ "VLAN": {
+ "VLANEnable": true,
+ "VLANId": 101
+ },
+ "IPv4Addresses": [
+ {
+ "Address": "192.168.0.10",
+ "SubnetMask": "255.255.252.0",
+ "AddressOrigin": "DHCP",
+ "Gateway": "192.168.0.1",
+ "Oem": {}
+ }
+ ],
+ "IPv6AddressPolicyTable": [
+ {
+ "Prefix": "::1/128",
+ "Precedence": 50,
+ "Label": 0
+ }
+ ],
+ "IPv6StaticAddresses": [
+ {
+ "Address": "fe80::1ec1:deff:fe6f:1e24",
+ "PrefixLength": 16
+ }
+ ],
+ "IPv6DefaultGateway": "fe80::1ec1:deff:fe6f:1e24",
+ "IPv6Addresses": [
+ {
+ "Address": "fe80::1ec1:deff:fe6f:1e24",
+ "PrefixLength": 64,
+ "AddressOrigin": "SLAAC",
+ "AddressState": "Preferred",
+ "Oem": {}
+ }
+ ],
+ "Oem": {},
+ "@odata.context": "/redfish/v1/$metadata#EthernetInterface.EthernetInterface",
+ "@odata.id": "/redfish/v1/Managers/bmc/EthernetInterfaces/eth0",
+ "@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."
+}
diff --git a/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/Managers/bmc/EthernetInterfaces/index.json b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/Managers/bmc/EthernetInterfaces/index.json
new file mode 100644
index 0000000000..77b85973e4
--- /dev/null
+++ b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/Managers/bmc/EthernetInterfaces/index.json
@@ -0,0 +1,15 @@
+{
+ "@odata.type": "#EthernetInterfaceCollection.EthernetInterfaceCollection",
+ "Name": "Ethernet Network Interface Collection",
+ "Description": "Collection of EthernetInterfaces for this Manager",
+ "Members@odata.count": 1,
+ "Members": [
+ {
+ "@odata.id": "/redfish/v1/Managers/bmc/EthernetInterfaces/eth0"
+ }
+ ],
+ "Oem": {},
+ "@odata.context": "/redfish/v1/$metadata#EthernetInterfaceCollection.EthernetInterfaceCollection",
+ "@odata.id": "/redfish/v1/Managers/bmc/EthernetInterfaces",
+ "@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."
+}
diff --git a/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/Managers/bmc/NetworkProtocol/index.json b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/Managers/bmc/NetworkProtocol/index.json
new file mode 100644
index 0000000000..192fca543e
--- /dev/null
+++ b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/Managers/bmc/NetworkProtocol/index.json
@@ -0,0 +1,47 @@
+{
+ "@odata.type": "#ManagerNetworkProtocol.v1_0_2.ManagerNetworkProtocol",
+ "Id": "NetworkProtocol",
+ "Name": "Manager Network Protocol",
+ "Description": "Manager Network Service Status",
+ "Status": {
+ "State": "Enabled",
+ "Health": "OK"
+ },
+ "HostName": "myBmcHostname",
+ "FQDN": "mymanager.mydomain.com",
+ "HTTP": {
+ "ProtocolEnabled": true,
+ "Port": 80
+ },
+ "HTTPS": {
+ "ProtocolEnabled": true,
+ "Port": 443
+ },
+ "IPMI": {
+ "ProtocolEnabled": true,
+ "Port": 623
+ },
+ "SSH": {
+ "ProtocolEnabled": true,
+ "Port": 22
+ },
+ "SNMP": {
+ "ProtocolEnabled": true,
+ "Port": 161
+ },
+ "SSDP": {
+ "ProtocolEnabled": true,
+ "Port": 1900,
+ "NotifyMulticastIntervalSeconds": 600,
+ "NotifyTTL": 5,
+ "NotifyIPv6Scope": "Site"
+ },
+ "Telnet": {
+ "ProtocolEnabled": true,
+ "Port": 23
+ },
+ "Oem": {},
+ "@odata.context": "/redfish/v1/$metadata#ManagerNetworkProtocol.ManagerNetworkProtocol",
+ "@odata.id": "/redfish/v1/Managers/bmc/NetworkProtocol",
+ "@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."
+}
diff --git a/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/Managers/bmc/index.json b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/Managers/bmc/index.json
new file mode 100644
index 0000000000..8e270e8b02
--- /dev/null
+++ b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/Managers/bmc/index.json
@@ -0,0 +1,53 @@
+{
+ "@odata.type": "#Manager.v1_1_0.Manager",
+ "Id": "bmc",
+ "Name": "Manager",
+ "ManagerType": "BMC",
+ "Description": "BMC",
+ "ServiceEntryPointUUID": "92384634-2938-2342-8820-489239905423",
+ "UUID": "00000000-0000-0000-0000-000000000000",
+ "Model": "CatfishBMC",
+ "DateTime": "2015-03-13T04:14:33+06:00",
+ "DateTimeLocalOffset": "+06:00",
+ "Status": {
+ "State": "Enabled",
+ "Health": "OK"
+ },
+ "FirmwareVersion": "1.00",
+ "NetworkProtocol": {
+ "@odata.id": "/redfish/v1/Managers/bmc/NetworkProtocol"
+ },
+ "EthernetInterfaces": {
+ "@odata.id": "/redfish/v1/Managers/bmc/EthernetInterfaces"
+ },
+ "Links": {
+ "ManagerForServers": [
+ {
+ "@odata.id": "/redfish/v1/Systems/2M220100SL"
+ }
+ ],
+ "ManagerForChassis": [
+ {
+ "@odata.id": "/redfish/v1/Chassis/A33"
+ }
+ ],
+ "ManagerInChassis": {
+ "@odata.id": "/redfish/v1/Chassis/A33"
+ },
+ "Oem": {}
+ },
+ "Actions": {
+ "#Manager.Reset": {
+ "target": "/redfish/v1/Managers/bmc/Actions/Manager.Reset",
+ "ResetType@Redfish.AllowableValues": [
+ "ForceRestart",
+ "GracefulRestart"
+ ]
+ },
+ "Oem": {}
+ },
+ "Oem": {},
+ "@odata.context": "/redfish/v1/$metadata#Manager.Manager",
+ "@odata.id": "/redfish/v1/Managers/bmc",
+ "@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."
+}
diff --git a/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/Managers/index.json b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/Managers/index.json
new file mode 100644
index 0000000000..8e5f5e0349
--- /dev/null
+++ b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/Managers/index.json
@@ -0,0 +1,13 @@
+{
+ "@odata.type": "#ManagerCollection.ManagerCollection",
+ "Name": "Manager Collection",
+ "Members@odata.count": 1,
+ "Members": [
+ {
+ "@odata.id": "/redfish/v1/Managers/bmc"
+ }
+ ],
+ "@odata.context": "/redfish/v1/$metadata#ManagerCollection.ManagerCollection",
+ "@odata.id": "/redfish/v1/Managers",
+ "@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."
+}
diff --git a/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/SessionService/Sessions/SESSION123456/index.json b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/SessionService/Sessions/SESSION123456/index.json
new file mode 100644
index 0000000000..dce8d48925
--- /dev/null
+++ b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/SessionService/Sessions/SESSION123456/index.json
@@ -0,0 +1,10 @@
+{
+ "@odata.type": "#Session.v1_0_2.Session",
+ "Id": "SESSION123456",
+ "Name": "User Session",
+ "Description": "Manager User Session",
+ "UserName": "root",
+ "Oem": {},
+ "@odata.context": "/redfish/v1/$metadata#Session.Session",
+ "@odata.id": "/redfish/v1/SessionService/Sessions/SESSION123456"
+}
diff --git a/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/SessionService/Sessions/index.json b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/SessionService/Sessions/index.json
new file mode 100644
index 0000000000..d009bf9d19
--- /dev/null
+++ b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/SessionService/Sessions/index.json
@@ -0,0 +1,12 @@
+{
+ "@odata.type": "#SessionCollection.SessionCollection",
+ "Name": "Session Collection",
+ "Members@odata.count": 1,
+ "Members": [
+ {
+ "@odata.id": "/redfish/v1/SessionService/Sessions/SESSION123456"
+ }
+ ],
+ "@odata.context": "/redfish/v1/$metadata#SessionCollection.SessionCollection",
+ "@odata.id": "/redfish/v1/SessionService/Sessions"
+}
diff --git a/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/SessionService/index.json b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/SessionService/index.json
new file mode 100644
index 0000000000..ed1764ebaf
--- /dev/null
+++ b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/SessionService/index.json
@@ -0,0 +1,17 @@
+{
+ "@odata.type": "#SessionService.v1_0_2.SessionService",
+ "Id": "SessionService",
+ "Name": "Session Service",
+ "Description": "Session Service",
+ "Status": {
+ "State": "Enabled",
+ "Health": "OK"
+ },
+ "ServiceEnabled": true,
+ "SessionTimeout": 30,
+ "Sessions": {
+ "@odata.id": "/redfish/v1/SessionService/Sessions"
+ },
+ "@odata.context": "/redfish/v1/$metadata#SessionService.SessionService",
+ "@odata.id": "/redfish/v1/SessionService"
+}
diff --git a/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/Systems/2M220100SL/LogServices/SEL/Entries/1/index.json b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/Systems/2M220100SL/LogServices/SEL/Entries/1/index.json
new file mode 100644
index 0000000000..5156ff13d5
--- /dev/null
+++ b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/Systems/2M220100SL/LogServices/SEL/Entries/1/index.json
@@ -0,0 +1,27 @@
+{
+ "@odata.type": "#LogEntry.v1_0_2.LogEntry",
+ "Id": "1",
+ "Name": "Log Entry 1",
+ "EntryType": "SEL",
+ "OemRecordFormat": "CompanyX",
+ "Severity": "Critical",
+ "Created": "2012-03-07T14:44:00Z",
+ "EntryCode": "Assert",
+ "SensorType": "Temperature",
+ "SensorNumber": 1,
+ "Message": "Message for Event, Description for SEL, OEM depends",
+ "MessageId": "Event.1.0.TempAssert",
+ "MessageArgs": [
+ "ArrayOfMessageArgs"
+ ],
+ "Links": {
+ "OriginOfCondition": {
+ "@odata.id": "/redfish/v1/Chassis/1/Thermal"
+ },
+ "Oem": {}
+ },
+ "Oem": {},
+ "@odata.context": "/redfish/v1/$metadata#LogEntry.LogEntry",
+ "@odata.id": "/redfish/v1/Systems/2M220100SL/LogServices/SEL/Entries/1",
+ "@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."
+}
diff --git a/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/Systems/2M220100SL/LogServices/SEL/Entries/2/index.json b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/Systems/2M220100SL/LogServices/SEL/Entries/2/index.json
new file mode 100644
index 0000000000..308d224055
--- /dev/null
+++ b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/Systems/2M220100SL/LogServices/SEL/Entries/2/index.json
@@ -0,0 +1,27 @@
+{
+ "@odata.type": "#LogEntry.v1_0_2.LogEntry",
+ "Id": "2",
+ "Name": "Log Entry 2",
+ "EntryType": "SEL",
+ "OemRecordFormat": "CompanyX",
+ "Severity": "Critical",
+ "Created": "2012-03-07T14:45:00Z",
+ "EntryCode": "Assert",
+ "SensorType": "Temperature",
+ "SensorNumber": 2,
+ "Message": "Message for Event, Description for SEL, OEM depends",
+ "MessageId": "Event.1.0.TempAssert",
+ "MessageArgs": [
+ "ArrayOfMessageArgs"
+ ],
+ "Links": {
+ "OriginOfCondition": {
+ "@odata.id": "/redfish/v1/Chassis/1/Thermal"
+ },
+ "Oem": {}
+ },
+ "Oem": {},
+ "@odata.context": "/redfish/v1/$metadata#LogEntry.LogEntry",
+ "@odata.id": "/redfish/v1/Systems/2M220100SL/LogServices/SEL/Entries/2",
+ "@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."
+}
diff --git a/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/Systems/2M220100SL/LogServices/SEL/Entries/index.json b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/Systems/2M220100SL/LogServices/SEL/Entries/index.json
new file mode 100644
index 0000000000..2102e5da43
--- /dev/null
+++ b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/Systems/2M220100SL/LogServices/SEL/Entries/index.json
@@ -0,0 +1,62 @@
+{
+ "@odata.type": "#LogEntryCollection.LogEntryCollection",
+ "Name": "Log Service Collection",
+ "Description": "Collection of Logs for this System",
+ "Members@odata.count": 2,
+ "Members": [
+ {
+ "@odata.type": "#LogEntry.v1_0_2.LogEntry",
+ "Id": "1",
+ "Name": "Log Entry 1",
+ "EntryType": "SEL",
+ "OemRecordFormat": "CompanyX",
+ "Severity": "Critical",
+ "Created": "2012-03-07T14:44:00Z",
+ "EntryCode": "Assert",
+ "SensorType": "Temperature",
+ "SensorNumber": 1,
+ "Message": "Message for Event, Description for SEL, OEM depends",
+ "MessageId": "Event.1.0.TempAssert",
+ "MessageArgs": [
+ "ArrayOfMessageArgs"
+ ],
+ "Links": {
+ "OriginOfCondition": {
+ "@odata.id": "/redfish/v1/Chassis/1/Thermal"
+ },
+ "Oem": {}
+ },
+ "Oem": {},
+ "@odata.id": "/redfish/v1/Systems/2M220100SL/LogServices/SEL/Entries/1"
+ },
+ {
+ "@odata.type": "#LogEntry.v1_0_2.LogEntry",
+ "Id": "2",
+ "Name": "Log Entry 2",
+ "EntryType": "SEL",
+ "OemRecordFormat": "CompanyX",
+ "Severity": "Critical",
+ "Created": "2012-03-07T14:45:00Z",
+ "EntryCode": "Assert",
+ "SensorType": "Temperature",
+ "SensorNumber": 2,
+ "Message": "Message for Event, Description for SEL, OEM depends",
+ "MessageId": "Event.1.0.TempAssert",
+ "MessageArgs": [
+ "ArrayOfMessageArgs"
+ ],
+ "Links": {
+ "OriginOfCondition": {
+ "@odata.id": "/redfish/v1/Chassis/1/Thermal"
+ },
+ "Oem": {}
+ },
+ "Oem": {},
+ "@odata.id": "/redfish/v1/Systems/2M220100SL/LogServices/SEL/Entries/2"
+ }
+ ],
+ "@odata.nextLink": "/redfish/v1/Systems/2M220100SL/LogServices/SEL/Entries?$skiptoken=2",
+ "@odata.context": "/redfish/v1/$metadata#LogEntryCollection.LogEntryCollection",
+ "@odata.id": "/redfish/v1/Systems/2M220100SL/LogServices/SEL/Entries",
+ "@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."
+}
diff --git a/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/Systems/2M220100SL/LogServices/SEL/index.json b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/Systems/2M220100SL/LogServices/SEL/index.json
new file mode 100644
index 0000000000..74c748e95e
--- /dev/null
+++ b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/Systems/2M220100SL/LogServices/SEL/index.json
@@ -0,0 +1,27 @@
+{
+ "@odata.type": "#LogService.v1_0_2.LogService",
+ "Id": "SEL",
+ "Name": "System Log Service",
+ "MaxNumberOfRecords": 1000,
+ "OverWritePolicy": "WrapsWhenFull",
+ "DateTime": "2015-03-13T04:14:33+06:00",
+ "DateTimeLocalOffset": "+06:00",
+ "ServiceEnabled": true,
+ "Status": {
+ "State": "Enabled",
+ "Health": "OK"
+ },
+ "Oem": {},
+ "Actions": {
+ "#LogService.ClearLog": {
+ "target": "/redfish/v1/Systems/2M220100SL/LogServices/SEL/Actions/LogService.Reset"
+ },
+ "Oem": {}
+ },
+ "Entries": {
+ "@odata.id": "/redfish/v1/Systems/2M220100SL/LogServices/SEL/Entries"
+ },
+ "@odata.context": "/redfish/v1/$metadata#LogService.LogService",
+ "@odata.id": "/redfish/v1/Systems/2M220100SL/LogServices/SEL",
+ "@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."
+}
diff --git a/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/Systems/2M220100SL/LogServices/index.json b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/Systems/2M220100SL/LogServices/index.json
new file mode 100644
index 0000000000..2dc5bf57c4
--- /dev/null
+++ b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/Systems/2M220100SL/LogServices/index.json
@@ -0,0 +1,15 @@
+{
+ "@odata.type": "#LogServiceCollection.LogServiceCollection",
+ "Name": "Log Service Collection",
+ "Description": "Collection of Logs for this System",
+ "Members@odata.count": 1,
+ "Members": [
+ {
+ "@odata.id": "/redfish/v1/Systems/2M220100SL/LogServices/SEL"
+ }
+ ],
+ "Oem": {},
+ "@odata.context": "/redfish/v1/$metadata#LogServiceCollection.LogServiceCollection",
+ "@odata.id": "/redfish/v1/Systems/2M220100SL/LogServices",
+ "@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."
+}
diff --git a/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/Systems/2M220100SL/index.json b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/Systems/2M220100SL/index.json
new file mode 100644
index 0000000000..814f5f6373
--- /dev/null
+++ b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/Systems/2M220100SL/index.json
@@ -0,0 +1,70 @@
+{
+ "@odata.type": "#ComputerSystem.v1_1_0.ComputerSystem",
+ "Id": "2M220100SL",
+ "Name": "Catfish System",
+ "SystemType": "Physical",
+ "AssetTag": "CATFISHASSETTAG",
+ "Manufacturer": "CatfishManufacturer",
+ "Model": "YellowCat1000",
+ "SerialNumber": "2M220100SL",
+ "SKU": "867530",
+ "PartNumber": "224071-J23",
+ "Description": "Catfish Implementation Recipe of simple scale-out monolithic server",
+ "UUID": "00000000-0000-0000-0000-000000000000",
+ "HostName": "catfishHostname",
+ "PowerState": "On",
+ "BiosVersion": "X00.1.2.3.4(build-23)",
+ "Status": {
+ "State": "Enabled",
+ "Health": "OK"
+ },
+ "IndicatorLED": "Off",
+ "Boot": {
+ "BootSourceOverrideEnabled": "Once",
+ "BootSourceOverrideMode": "UEFI",
+ "UefiTargetBootSourceOverride": "uefiDevicePath",
+ "BootSourceOverrideTarget": "Pxe",
+ "BootSourceOverrideTarget@Redfish.AllowableValues": [
+ "None",
+ "Pxe",
+ "Usb",
+ "Hdd",
+ "BiosSetup",
+ "UefiTarget",
+ "UefiHttp"
+ ]
+ },
+ "LogServices": {
+ "@odata.id": "/redfish/v1/Systems/2M220100SL/LogServices"
+ },
+ "Links": {
+ "Chassis": [
+ {
+ "@odata.id": "/redfish/v1/Chassis/A33"
+ }
+ ],
+ "ManagedBy": [
+ {
+ "@odata.id": "/redfish/v1/Managers/bmc"
+ }
+ ],
+ "Oem": {}
+ },
+ "Actions": {
+ "#ComputerSystem.Reset": {
+ "target": "/redfish/v1/Systems/2M220100SL/Actions/ComputerSystem.Reset",
+ "ResetType@Redfish.AllowableValues": [
+ "On",
+ "ForceOff",
+ "GracefulShutdown",
+ "ForceRestart",
+ "Nmi",
+ "GracefulRestart",
+ "ForceOn"
+ ]
+ }
+ },
+ "@odata.context": "/redfish/v1/$metadata#ComputerSystem.ComputerSystem",
+ "@odata.id": "/redfish/v1/Systems/2M220100SL",
+ "@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."
+}
diff --git a/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/Systems/index.json b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/Systems/index.json
new file mode 100644
index 0000000000..091849e1a6
--- /dev/null
+++ b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/Systems/index.json
@@ -0,0 +1,13 @@
+{
+ "@odata.type": "#ComputerSystemCollection.ComputerSystemCollection",
+ "Name": "Computer System Collection",
+ "Members@odata.count": 1,
+ "Members": [
+ {
+ "@odata.id": "/redfish/v1/Systems/2M220100SL"
+ }
+ ],
+ "@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."
+}
diff --git a/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/index.json b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/index.json
new file mode 100644
index 0000000000..89312bcec1
--- /dev/null
+++ b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/index.json
@@ -0,0 +1,31 @@
+{
+ "@odata.type": "#ServiceRoot.v1_0_2.ServiceRoot",
+ "Id": "RootService",
+ "Name": "Root Service",
+ "RedfishVersion": "1.0.2",
+ "UUID": "92384634-2938-2342-8820-489239905423",
+ "Systems": {
+ "@odata.id": "/redfish/v1/Systems"
+ },
+ "Chassis": {
+ "@odata.id": "/redfish/v1/Chassis"
+ },
+ "Managers": {
+ "@odata.id": "/redfish/v1/Managers"
+ },
+ "SessionService": {
+ "@odata.id": "/redfish/v1/SessionService"
+ },
+ "AccountService": {
+ "@odata.id": "/redfish/v1/AccountService"
+ },
+ "Links": {
+ "Sessions": {
+ "@odata.id": "/redfish/v1/SessionService/Sessions"
+ }
+ },
+ "Oem": {},
+ "@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."
+}
diff --git a/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/odata/index.json b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/odata/index.json
new file mode 100644
index 0000000000..ef253a35cb
--- /dev/null
+++ b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/odata/index.json
@@ -0,0 +1,56 @@
+{
+ "value": [
+ {
+ "name": "Service",
+ "kind": "Singleton",
+ "url": "/redfish/v1/"
+ },
+ {
+ "name": "Systems",
+ "kind": "Singleton",
+ "url": "/redfish/v1/Systems"
+ },
+ {
+ "name": "Chassis",
+ "kind": "Singleton",
+ "url": "/redfish/v1/Chassis"
+ },
+ {
+ "name": "Managers",
+ "kind": "Singleton",
+ "url": "/redfish/v1/Managers"
+ },
+ {
+ "name": "AccountService",
+ "kind": "Singleton",
+ "url": "/redfish/v1/AccountService"
+ },
+ {
+ "name": "SessionService",
+ "kind": "Singleton",
+ "url": "/redfish/v1/SessionService"
+ },
+ {
+ "name": "EventService",
+ "kind": "Singleton",
+ "url": "/redfish/v1/EventService"
+ },
+ {
+ "name": "JsonSchemas",
+ "kind": "Singleton",
+ "url": "/redfish/v1/JsonSchemas"
+ },
+ {
+ "name": "Registries",
+ "kind": "Singleton",
+ "url": "/redfish/v1/Registries"
+ },
+ {
+ "name": "Sessions",
+ "kind": "Singleton",
+ "url": "/redfish/v1/SessionService/Sessions"
+ }
+ ],
+ "@odata.context": "/redfish/v1/$metadata",
+ "@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."
+}
diff --git a/RedfishClientPkg/Tools/Redfish-Profile-Simulator/redfishProfileSimulator.py b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/redfishProfileSimulator.py
new file mode 100644
index 0000000000..24be52bafc
--- /dev/null
+++ b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/redfishProfileSimulator.py
@@ -0,0 +1,125 @@
+# Copyright Notice:
+# Copyright 2016 Distributed Management Task Force, Inc. All rights reserved.
+# License: BSD 3-Clause License. For full text see link: https://github.com/DMTF/Redfish-Profile-Simulator/blob/master/LICENSE.md
+
+# This program is dependent on the following Python packages that should be installed separately with pip:
+# pip install Flask
+#
+# standard python packages
+import sys
+import getopt
+import os
+
+rfVersion = "0.9.6"
+rfProgram1 = "redfishProfileSimulator"
+rfProgram2 = " "
+rfUsage1 = "[-Vh] [--Version][--help]"
+rfUsage2 = "[-H<hostIP>] [-P<port>] [-p<profile_path>]"
+rfUsage3 = "[--Host=<hostIP>] [--Port=<port>] [--profile_path=<profile_path>]"
+
+
+def rf_usage():
+ print("Usage:")
+ print(" ", rfProgram1, " ", rfUsage1)
+ print(" ", rfProgram1, " ", rfUsage2)
+ print(" ", rfProgram2, " ", rfUsage3)
+
+
+def rf_help():
+ print(rfProgram1,"implements a simulation of a redfish service for the \"Simple OCP Server V1\" Mockup.")
+ print(" The simulation includes an http server, RestEngine, and dynamic Redfish datamodel.")
+ print(" You can GET, PATHCH,... to the service just like a real Redfish service.")
+ print(" Both Basic and Redfish Session/Token authentication is supported (for a single user/passwd and token")
+ print(" the user/passwd is: root/password123456. The authToken is: 123456SESSIONauthcode")
+ print(" these can be changed by editing the redfishURIs.py file. will make dynamic later.")
+ print(" The http service and Rest engine is built on Flask, and all code is Python 3.4+")
+ print(" The data model resources are \"initialized\" from the SPMF \"SimpleOcpServerV1\" Mockup.")
+ print(" and stored as python dictionaries--then the dictionaries are updated with patches, posts, deletes.")
+ print(" The program can be extended to support other mockup \"profiles\".")
+ print("")
+ print(" By default, the simulation runs on localhost (127.0.0.1), on port 5000.")
+ print(" These can be changed with CLI options: -P<port> -H <hostIP> | --port=<port> --host=<hostIp>")
+ print("")
+ print("Version: ", rfVersion)
+ rf_usage()
+ print("")
+ print(" -V, --Version, --- the program version")
+ print(" -h, --help, --- help")
+ print(" -H<hostIP>, --Host=<hostIp> --- host IP address. dflt=127.0.0.1")
+ print(" -P<port>, --Port=<port> --- the port to use. dflt=5000")
+ print(" -p<profile_path>, --profile=<profile_path> --- the path to the Redfish profile to use. "
+ "dflt=\"./MockupData/SimpleOcpServerV1\" ")
+
+
+def main(argv):
+ # set default option args
+ rf_profile_path = os.path.abspath("./MockupData/SimpleOcpServerV1")
+ rf_host = "127.0.0.1"
+ rf_port = 5000
+
+ try:
+ opts, args = getopt.getopt(argv[1:], "VhH:P:p:",
+ ["Version", "help", "Host=", "Port=", "profile="])
+ except getopt.GetoptError:
+ print(rfProgram1, ": Error parsing options")
+ rf_usage()
+ sys.exit(2)
+ for opt, arg in opts:
+ if opt in ("-h", "--help"):
+ rf_help()
+ sys.exit(0)
+ elif opt in ("-V", "--Version"):
+ print("Version:", rfVersion)
+ sys.exit(0)
+ elif opt in ("-p", "--profile"):
+ rf_profile_path = arg
+ elif opt in "--Host=":
+ rf_host = arg
+ elif opt in "--Port=":
+ rf_port=int(arg)
+ else:
+ print(" ", rfProgram1, ": Error: unsupported option")
+ rf_usage()
+ sys.exit(2)
+
+ print("{} Version: {}".format(rfProgram1,rfVersion))
+ print(" Starting redfishProfileSimulator at: hostIP={}, port={}".format(rf_host, rf_port))
+ print(" Using Profile at {}".format(rf_profile_path))
+
+ if os.path.isdir(rf_profile_path):
+ # import the classes and code we run from main.
+ from v1sim.serviceVersions import RfServiceVersions
+ from v1sim.serviceRoot import RfServiceRoot
+ # rfApi_SimpleServer is a function in ./RedfishProfileSim/redfishURIs.py.
+ # It loads the flask APIs (URIs), and starts the flask service
+ from v1sim.redfishURIs import rfApi_SimpleServer
+
+ # create the root service resource
+ root_path = os.path.normpath("redfish/v1")
+
+ # create the version resource for GET /redfish
+ versions = RfServiceVersions(rf_profile_path, "redfish")
+ root = RfServiceRoot(rf_profile_path, root_path)
+
+ # start the flask REST API service
+ rfApi_SimpleServer(root, versions, host=rf_host, port=rf_port)
+ else:
+ print("invalid profile path")
+
+
+if __name__ == "__main__":
+ main(sys.argv)
+
+
+
+
+ #http://127.0.0.1:5000/
+
+ #app.run(host="0.0.0.0") # run on all IPs
+ #run(host=None, port=None, debug=None, **options)
+ # host=0.0.0.0 server avail externally -- all IPs
+ # host=127.0.0.1 is default
+ # port=5000 default, or port defined in SERVER_NAME config var
+
+
+
diff --git a/RedfishClientPkg/Tools/Redfish-Profile-Simulator/v1sim/__init__.py b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/v1sim/__init__.py
new file mode 100644
index 0000000000..72007ff42a
--- /dev/null
+++ b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/v1sim/__init__.py
@@ -0,0 +1,4 @@
+# Copyright Notice:
+# Copyright 2016 Distributed Management Task Force, Inc. All rights reserved.
+# License: BSD 3-Clause License. For full text see link: https://github.com/DMTF/Redfish-Profile-Simulator/blob/master/LICENSE.md
+
diff --git a/RedfishClientPkg/Tools/Redfish-Profile-Simulator/v1sim/accountService.py b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/v1sim/accountService.py
new file mode 100644
index 0000000000..1c056f0b86
--- /dev/null
+++ b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/v1sim/accountService.py
@@ -0,0 +1,76 @@
+# Copyright Notice:
+# Copyright 2016 Distributed Management Task Force, Inc. All rights reserved.
+# License: BSD 3-Clause License. For full text see link: https://github.com/DMTF/Redfish-Profile-Simulator/blob/master/LICENSE.md
+
+import os
+
+from .resource import RfResource, RfCollection
+
+
+class RfAccountServiceObj(RfResource):
+ # create instance of each AccountService
+ def create_sub_objects(self, base_path, rel_path):
+ if os.path.isdir(os.path.join(base_path, os.path.normpath("redfish/v1/AccountService/Accounts"))):
+ self.components["Accounts"] = RfAccountCollection(base_path,
+ os.path.normpath("redfish/v1/AccountService/Accounts"),
+ parent=self)
+
+ if os.path.isdir(os.path.join(base_path, os.path.normpath("redfish/v1/AccountService/Roles"))):
+ self.components["Roles"] = RfRoleCollection(base_path,
+ os.path.normpath("redfish/v1/AccountService/Roles"),
+ parent=self)
+
+ def patch_resource(self, patch_data):
+ # first verify client didn't send us a property we cant patch
+ patachables = ("MinPasswordLength", "AccountLockoutThreshold",
+ "AccountLockoutDuration", "AccountLockoutCounterResetAfter")
+
+ for key in patch_data.keys():
+ if key not in patachables:
+ return 4, 400, "Invalid Patch Property Sent", ""
+
+ # now patch the valid properties sent
+ for key in patch_data.keys():
+ new_val = patch_data[key]
+ print("new_val:{}".format(new_val))
+ try:
+ num_val = round(new_val)
+ except ValueError:
+ return 4, 400, "invalid value", ""
+ else:
+ patch_data[key] = num_val
+
+ # if here, we know all the patch data is valid properties and properties
+ new_duration = self.res_data["AccountLockoutDuration"]
+ new_reset_after = self.res_data["AccountLockoutCounterResetAfter"]
+ if "AccountLockoutDuration" in patch_data:
+ new_duration = patch_data["AccountLockoutDuration"]
+ if "AccountLockoutCounterResetAfter" in patch_data:
+ new_reset_after = patch_data["AccountLockoutCounterResetAfter"]
+ if new_duration < new_reset_after:
+ return 4, 400, "invalid value", ""
+
+ # if here, all values are good. set them
+ for key in patch_data.keys():
+ self.res_data[key] = patch_data[key]
+ return 0, 204, None, None
+
+
+class RfAccountCollection(RfCollection):
+ def element_type(self):
+ return RfAccountObj
+
+
+# Service Collection Entries
+class RfAccountObj(RfResource):
+ pass
+
+
+class RfRoleCollection(RfCollection):
+ def element_type(self):
+ return RfRoleObj
+
+
+# Service Collection Entries
+class RfRoleObj(RfResource):
+ pass
diff --git a/RedfishClientPkg/Tools/Redfish-Profile-Simulator/v1sim/chassis.py b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/v1sim/chassis.py
new file mode 100644
index 0000000000..88e5a000f3
--- /dev/null
+++ b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/v1sim/chassis.py
@@ -0,0 +1,115 @@
+# Copyright Notice:
+# Copyright 2016 Distributed Management Task Force, Inc. All rights reserved.
+# License: BSD 3-Clause License. For full text see link: https://github.com/DMTF/Redfish-Profile-Simulator/blob/master/LICENSE.md
+
+import os
+
+from .resource import RfResource, RfCollection
+
+
+class RfChassisCollection(RfCollection):
+ def element_type(self):
+ return RfChassisObj
+
+
+class RfChassisObj(RfResource):
+ # create the dependent sub-objects that live under the chassis object
+ def create_sub_objects(self, base_path, rel_path):
+ resource_path = os.path.join(base_path, rel_path);
+ contents = os.listdir(resource_path)
+ for item in contents:
+ if item == "Thermal":
+ self.components[item] = RfChassisThermal(base_path, os.path.join(rel_path, item), parent=self)
+ elif item == "Power":
+ self.components[item] = RfChassisPower(base_path, os.path.join(rel_path, item), parent=self)
+
+ def patch_resource(self, patch_data):
+ # first verify client didn't send us a property we cant patch
+ for key in patch_data.keys():
+ if key != "AssetTag" and key != "IndicatorLED":
+ return 4, 400, "Invalid Patch Property Sent", ""
+ # now patch the valid properties sent
+ if "AssetTag" in patch_data:
+ self.res_data['AssetTag'] = patch_data['AssetTag']
+ if "IndicatorLED" in patch_data:
+ self.res_data['IndicatorLED'] = patch_data['IndicatorLED']
+ return 0, 204, None, None
+
+ def reset_resource(self, reset_data):
+ if "ResetType" in reset_data:
+ # print("RESETDATA: {}".format(resetData))
+ value = reset_data['ResetType']
+ valid_values = self.res_data["Actions"]["#Chassis.Reset"]["ResetType@Redfish.AllowableValues"]
+ if value in valid_values:
+ # it is a supoported reset action modify other properties appropritely
+ if value == "On":
+ self.res_data["PowerState"] = "On"
+ print("PROFILE_SIM--SERVER WAS RESET. power now ON")
+ elif value == "ForceOff":
+ self.res_data["PowerState"] = "Off"
+ print("PROFILE_SIM--SERVER WAS RESET. Power now Off")
+ return 0, 204, "Chassis Reset", ""
+ else:
+ return 4, 400, "Invalid reset value: ResetType", ""
+ else: # invalid request
+ return 4, 400, "Invalid request property", ""
+
+
+# subclass Thermal Metrics
+class RfChassisThermal(RfResource):
+ pass
+
+
+# subclass Power Metrics
+class RfChassisPower(RfResource):
+ def create_sub_objects(self, base_path, rel_path):
+ resource_path = os.path.join(base_path, rel_path);
+ contents = os.listdir(resource_path)
+ for item in contents:
+ if item == "FastPowerMeter":
+ self.components[item] = RfFastPowerMeter(base_path, os.path.join(rel_path, item), parent=self)
+ elif item == "FederatedGroupCapping":
+ self.components[item] = RfFederatedGroupCapping(base_path, os.path.join(rel_path, item), parent=self)
+ elif item == "PowerMeter":
+ self.components[item] = RfPowerMeter(base_path, os.path.join(rel_path, item), parent=self)
+
+ def patch_resource(self, patchData):
+ # first verify client didn't send us a property we cant patch
+ for key in patchData.keys():
+ if key != "PowerControl":
+ return 4, 400, "Invalid Patch Property Sent", ""
+ else: # Powercontrol:
+ for prop2 in patchData["PowerControl"][0].keys():
+ if prop2 != "PowerLimit":
+ return 4, 400, "Invalid Patch Property Sent", ""
+ else: # PowerLimit
+ for prop3 in patchData["PowerControl"][0]["PowerLimit"].keys():
+ if prop3 != "LimitInWatts" and prop3 != "LimitException" and prop3 != "CorrectionInMs":
+ return 4, 400, "Invalid Patch Property Sent", ""
+ # now patch the valid properties sent
+ if "PowerControl" in patchData:
+ if "PowerLimit" in patchData["PowerControl"][0]:
+ patch_power_limit_dict = patchData["PowerControl"][0]["PowerLimit"]
+ catfish_power_limit_dict = self.res_data["PowerControl"][0]["PowerLimit"]
+ if "LimitInWatts" in patch_power_limit_dict:
+ self.res_data["PowerControl"][0]["PowerLimit"]["LimitInWatts"] = \
+ patch_power_limit_dict['LimitInWatts']
+ if "LimitException" in patch_power_limit_dict:
+ self.res_data["PowerControl"][0]["PowerLimit"]['LimitException'] = \
+ patch_power_limit_dict['LimitException']
+ if "CorrectionInMs" in patch_power_limit_dict:
+ self.res_data["PowerControl"][0]["PowerLimit"]['CorrectionInMs'] = \
+ patch_power_limit_dict['CorrectionInMs']
+ return 0, 204, None, None
+
+
+class RfFastPowerMeter(RfResource):
+ pass
+
+
+class RfFederatedGroupCapping(RfResource):
+ pass
+
+
+class RfPowerMeter(RfResource):
+ pass
diff --git a/RedfishClientPkg/Tools/Redfish-Profile-Simulator/v1sim/common_services.py b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/v1sim/common_services.py
new file mode 100644
index 0000000000..b1a5082d45
--- /dev/null
+++ b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/v1sim/common_services.py
@@ -0,0 +1,28 @@
+import os
+
+from .resource import RfCollection, RfResource
+
+
+class RfLogServiceCollection(RfCollection):
+ def element_type(self):
+ return RfLogService
+
+
+class RfLogService(RfResource):
+ def create_sub_objects(self, base_path, rel_path):
+ resource_path = os.path.join(base_path, rel_path);
+ contents = os.listdir(resource_path)
+ for item in contents:
+ if item == "Entries":
+ self.components[item] = RfLogEntriesCollection(base_path,
+ os.path.join(rel_path, item),
+ parent=self)
+
+
+class RfLogEntriesCollection(RfCollection):
+ def element_type(self):
+ return RfLogEntry
+
+
+class RfLogEntry(RfResource):
+ pass
diff --git a/RedfishClientPkg/Tools/Redfish-Profile-Simulator/v1sim/flask_redfish_auth.py b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/v1sim/flask_redfish_auth.py
new file mode 100644
index 0000000000..61a5fd97e9
--- /dev/null
+++ b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/v1sim/flask_redfish_auth.py
@@ -0,0 +1,278 @@
+# Copyright Notice:
+# Copyright 2016 Distributed Management Task Force, Inc. All rights reserved.
+# License: BSD 3-Clause License. For full text see link: https://github.com/DMTF/Redfish-Profile-Simulator/blob/master/LICENSE.md
+
+"""
+flask_redfish_auth
+
+adapted from:
+ flask_httpauth
+ ==================
+ This module provides Basic and Digest HTTP authentication for Flask routes.
+ :copyright: (C) 2014 by Miguel Grinberg.
+ :license: MIT, see LICENSE for more details,
+ at https://github.com/miguelgrinberg/Flask-HTTPAuth/blob/master/LICENSE
+
+ see documentation at: http://flask.pocoo.org/snippets/8/
+ code and docs at: https://github.com/miguelgrinberg/flask-httpauth/
+
+**** modified to implement EITHER Redfish Token Auth or Basic Auth
+ this file is imported by: catfishURIs.py
+
+ Usage: In RedfishProfileSimulator: see this flow below in redfishURIs.py
+ ... in redfishURIs.py
+ from .flask_redfish_auth import RfHTTPBasicOrTokenAuth
+ ...
+ #create instance of the modified Basic or Redfish Token auth
+ # this is what is in this file
+ auth=RfHTTPBasicOrTokenAuth
+
+ #define basic auth decorator used by flask
+ @auth.verify_basic_password
+ def verifyRfPasswd(user,passwd):
+ ...
+
+ #define Redfish Token/Session auth decorator used by flask
+ @auth.verify_token
+ def verifyRfToken(auth_token):
+ ..
+
+ @app.route("/api", methods=['GET'])
+ @auth.rfAuthRequired
+ def api()
+ ...
+"""
+
+from functools import wraps
+
+from flask import request, make_response
+
+
+# this is the Base HTTP Auth class that is used to derive the Redfish "Basic or Token Auth" class
+class HTTPAuth(object):
+ def __init__(self, scheme=None, realm=None):
+ def default_get_password(userx):
+ return None
+
+ def default_basic_auth_error():
+ return "Unauthorized Access"
+
+ def default_token_auth_error():
+ return "Unauthorized Access. Invalid authentication token"
+
+ self.scheme = scheme
+ self.realm = realm or "Authentication Required"
+ self.get_password(default_get_password)
+ self.basic_error_handler(default_basic_auth_error)
+ self.token_error_handler(default_token_auth_error)
+
+ def get_password(self, f):
+ self.get_password_callback = f
+ return f
+
+ def token_error_handler(self, f):
+ @wraps(f)
+ def decorated(*args, **kwargs):
+ res = f(*args, **kwargs)
+ if type(res) == str:
+ res = make_response(res)
+ res.status_code = 401
+ return res
+
+ self.auth_token_error_callback = decorated
+ return decorated
+
+ def basic_error_handler(self, f):
+ @wraps(f)
+ def decorated(*args, **kwargs):
+ res = f(*args, **kwargs)
+ if type(res) == str:
+ res = make_response(res)
+ res.status_code = 401
+ if 'WWW-Authenticate' not in res.headers.keys():
+ res.headers['WWW-Authenticate'] = self.authenticate_header()
+ return res
+
+ self.auth_basic_error_callback = decorated
+ return decorated
+
+ # for redfish, we need to hook this to check if its token auth before trying basic auth
+ def rfAuthRequired(self, f):
+ @wraps(f)
+ def decorated(*args, **kwargs):
+ auth = request.authorization
+ print("in rfAuthRequired")
+ print("headers: {}".format(request.headers))
+ # We need to ignore authentication headers for OPTIONS to avoid
+ # unwanted interactions with CORS.
+ # Chrome and Firefox issue a preflight OPTIONS request to check
+ # Access-Control-* headers, and will fail if it returns 401.
+ if request.method != 'OPTIONS':
+ # auth is None if the Basic auth header didn't come in the request
+ found_token = False
+ if (auth is None):
+ ###print("auth is None")
+ # check if we have a redfish auth token
+ hdr_token_key = "X-Auth-Token"
+ auth_token = request.headers.get(hdr_token_key)
+ ###print("token={}".format(auth_token))
+ if (auth_token is not None):
+ found_token = True
+ # yeah! we have an auth token in the headers
+ authOk = self.verify_token_callback(auth_token)
+ ###print("verify_token={}".format(authOk))
+ if (authOk is not True):
+ # we had an auth token, but it didn't validate
+ return (self.auth_token_error_callback())
+
+ # now continue with normal Basic Auth validation
+ if (found_token is not True):
+ ###print("try basic")
+ if auth:
+ password = self.get_password_callback(auth.username)
+ else:
+ password = None
+ ###print("basic auth: auth={}, pwd={}".format(auth,password))
+ if (not self.authenticate(auth, password)):
+ return (self.auth_basic_error_callback())
+ ###print("now execute the function")
+ return (f(*args, **kwargs))
+
+ return (decorated)
+
+ def username(self):
+ if not request.authorization:
+ return ""
+ return request.authorization.username
+
+
+# this class is derived from HTTPAuth above
+class RfHTTPBasicOrTokenAuth(HTTPAuth):
+ def __init__(self, scheme=None, realm=None):
+ super(RfHTTPBasicOrTokenAuth, self).__init__(scheme, realm)
+ self.hash_password(None)
+ self.verify_basic_password(None)
+ self.verify_token(None)
+
+ def hash_password(self, f):
+ self.hash_password_callback = f
+ return f
+
+ def verify_basic_password(self, f):
+ self.verify_password_callback = f
+ return f
+
+ def verify_token(self, f):
+ self.verify_token_callback = f
+ return f
+
+ def authenticate_header(self):
+ return '{0} realm="{1}"'.format(self.scheme or 'Basic', self.realm)
+
+ def authenticate(self, auth, stored_password):
+ if auth:
+ username = auth.username
+ client_password = auth.password
+ else:
+ username = ""
+ client_password = ""
+ if self.verify_password_callback:
+ return self.verify_password_callback(username, client_password)
+ if not auth:
+ return False
+ if self.hash_password_callback:
+ try:
+ client_password = self.hash_password_callback(client_password)
+ except TypeError:
+ client_password = self.hash_password_callback(username,
+ client_password)
+ return client_password == stored_password
+
+
+'''
+class HTTPDigestAuth(HTTPAuth):
+ def __init__(self, scheme=None, realm=None, use_ha1_pw=False):
+ super(HTTPDigestAuth, self).__init__(scheme, realm)
+ self.use_ha1_pw = use_ha1_pw
+ self.random = SystemRandom()
+ try:
+ self.random.random()
+ except NotImplementedError:
+ self.random = Random()
+
+ def _generate_random():
+ return md5(str(self.random.random()).encode('utf-8')).hexdigest()
+
+ def default_generate_nonce():
+ session["auth_nonce"] = _generate_random()
+ return session["auth_nonce"]
+
+ def default_verify_nonce(nonce):
+ return nonce == session.get("auth_nonce")
+
+ def default_generate_opaque():
+ session["auth_opaque"] = _generate_random()
+ return session["auth_opaque"]
+
+ def default_verify_opaque(opaque):
+ return opaque == session.get("auth_opaque")
+
+ self.generate_nonce(default_generate_nonce)
+ self.generate_opaque(default_generate_opaque)
+ self.verify_nonce(default_verify_nonce)
+ self.verify_opaque(default_verify_opaque)
+
+ def generate_nonce(self, f):
+ self.generate_nonce_callback = f
+ return f
+
+ def verify_nonce(self, f):
+ self.verify_nonce_callback = f
+ return f
+
+ def generate_opaque(self, f):
+ self.generate_opaque_callback = f
+ return f
+
+ def verify_opaque(self, f):
+ self.verify_opaque_callback = f
+ return f
+
+ def get_nonce(self):
+ return self.generate_nonce_callback()
+
+ def get_opaque(self):
+ return self.generate_opaque_callback()
+
+ def generate_ha1(self, username, password):
+ a1 = username + ":" + self.realm + ":" + password
+ a1 = a1.encode('utf-8')
+ return md5(a1).hexdigest()
+
+ def authenticate_header(self):
+ session["auth_nonce"] = self.get_nonce()
+ session["auth_opaque"] = self.get_opaque()
+ return '{0} realm="{1}",nonce="{49}",opaque="{3}"'.format(
+ self.scheme or 'Digest', self.realm, session["auth_nonce"],
+ session["auth_opaque"])
+
+ def authenticate(self, auth, stored_password_or_ha1):
+ if not auth or not auth.username or not auth.realm or not auth.uri \
+ or not auth.nonce or not auth.response \
+ or not stored_password_or_ha1:
+ return False
+ if not(self.verify_nonce_callback(auth.nonce)) or \
+ not(self.verify_opaque_callback(auth.opaque)):
+ return False
+ if self.use_ha1_pw:
+ ha1 = stored_password_or_ha1
+ else:
+ a1 = auth.username + ":" + auth.realm + ":" + \
+ stored_password_or_ha1
+ ha1 = md5(a1.encode('utf-8')).hexdigest()
+ a2 = request.method + ":" + auth.uri
+ ha2 = md5(a2.encode('utf-8')).hexdigest()
+ a3 = ha1 + ":" + auth.nonce + ":" + ha2
+ response = md5(a3.encode('utf-8')).hexdigest()
+ return response == auth.response
+'''
diff --git a/RedfishClientPkg/Tools/Redfish-Profile-Simulator/v1sim/managers.py b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/v1sim/managers.py
new file mode 100644
index 0000000000..e09ae3d500
--- /dev/null
+++ b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/v1sim/managers.py
@@ -0,0 +1,211 @@
+# Copyright Notice:
+# Copyright 2016 Distributed Management Task Force, Inc. All rights reserved.
+# License: BSD 3-Clause License. For full text see link: https://github.com/DMTF/Redfish-Profile-Simulator/blob/master/LICENSE.md
+
+import os
+
+from .common_services import RfLogServiceCollection
+from .network import RfNetworkService
+from .resource import RfResource, RfCollection
+from .security import RfSecurityService
+
+
+class RfManagersCollection(RfCollection):
+ def element_type(self):
+ return RfManagerObj
+
+
+class RfManagerObj(RfResource):
+ """
+ create the dependent sub-objects that live under the Manager object
+ """
+
+ def create_sub_objects(self, base_path, rel_path):
+ resource_path = os.path.join(base_path, rel_path);
+ contents = os.listdir(resource_path)
+ for item in contents:
+ if item == "EthernetInterfaces":
+ self.components[item] = RfManagerEthernetColl(base_path, os.path.join(rel_path, item), parent=self)
+ elif item == "NetworkProtocol":
+ self.components[item] = RfManagerNetworkProtocol(base_path, os.path.join(rel_path, item), parent=self)
+ elif item == "SerialInterfaces":
+ self.components[item] = RfSerialInterfaceCollection(base_path, os.path.join(rel_path, item),
+ parent=self)
+ elif item == "VirutalMedia":
+ self.components[item] = RfVirtualMediaCollection(base_path, os.path.join(rel_path, item), parent=self)
+ elif item == "NICs":
+ self.components[item] = RfNics(base_path, os.path.join(rel_path, item), parent=self)
+ elif item == "LogServices":
+ self.components[item] = RfLogServiceCollection(base_path, os.path.join(rel_path, item), parent=self)
+ elif item == "ActiveHealthSystem":
+ self.components[item] = RfActiveHealthSystem(base_path, os.path.join(rel_path, item), parent=self)
+ elif item == "DateTime":
+ self.components[item] = RfDateTime(base_path, os.path.join(rel_path, item), parent=self)
+ elif item == "EmbeddedMedia":
+ self.components[item] = RfEmbeddedMedia(base_path, os.path.join(rel_path, item), parent=self)
+ elif item == "FederationGroups":
+ self.components[item] = RfFederationGroupCollection(base_path, os.path.join(rel_path, item),
+ parent=self)
+ elif item == "FederationPeers":
+ self.components[item] = RfFederationPeerCollection(base_path, os.path.join(rel_path, item), parent=self)
+ elif item == "LicenseService":
+ self.components[item] = RfLicenseServiceCollection(base_path, os.path.join(rel_path, item), parent=self)
+ elif item == "SecurityService":
+ self.components[item] = RfSecurityService(base_path, os.path.join(rel_path, item), parent=self)
+ elif item == "UpdateService":
+ self.components[item] = RfManagerUpdateService(base_path, os.path.join(rel_path, item), parent=self)
+ elif item == "NetworkService":
+ self.components[item] = RfNetworkService(base_path, os.path.join(rel_path, item), parent=self)
+
+ def patch_resource(self, patch_data):
+ # first verify client didn't send us a property we cant patch
+ for key in patch_data.keys():
+ if key != "DateTime" and key != "DateTimeLocalOffset":
+ return 4, 400, "Invalid Patch Property Sent", ""
+
+ date_time = None
+ date_time_offset = None
+ local_offset = None
+
+ # now patch the valid properties sent
+ if "DateTime" in patch_data:
+ date_time = patch_data['DateTime']
+ date_time_offset = date_time[-6:] # get last 6 chars ....+00:00 or -00:00
+ if "DateTimeLocalOffset" in patch_data:
+ local_offset = patch_data['DateTimeLocalOffset']
+
+ # verify that if both DateTime and DateTimeLocalOffset were sent, thant
+ # the offsets are the same. (no reason to send both though)
+ if date_time_offset is not None and local_offset is not None:
+ if date_time_offset != local_offset:
+ return 4, 409, "Offsets in DateTime and DateTimeLocalOffset conflict", None # 409 Conflict
+
+ # reconcile localOffset and the offset in DateTime to write back
+ # if only DateTime was updated, also update dateTimeLocalOffset
+ if local_offset is None:
+ local_offset = date_time_offset
+ # if only DateTimeLocalOffset was updated (timezone change), also update DateTime
+ if date_time is None:
+ date_time = self.res_data['DateTime'] # read current value to get time
+ date_time = date_time[:-6] # strip the offset
+ date_time = date_time + local_offset # add back the offset sent in in DateTimeLocalOFfset
+
+ # TODO: issue 1545 in SPMF is ambiguity of what patching DateTimeLocalOffset should actually do.
+ # this may need to be updated once issue is resolved
+
+ # now write the valid properties with updated values
+ self.res_data['DateTime'] = date_time
+ self.res_data['DateTimeLocalOffset'] = local_offset
+ return 0, 204, None, None
+
+ def reset_resource(self, reset_data):
+ if "ResetType" in reset_data:
+ value = reset_data['ResetType']
+ valid_values = self.res_data["Actions"]["#Manager.Reset"]["ResetType@Redfish.AllowableValues"]
+ if value in valid_values:
+ # it is a supoported reset action modify other properties appropritely
+ # nothing to do--manager always on in this profile
+ return 0, 204, "System Reset", ""
+ else:
+ return 4, 400, "Invalid reset value: ResetType", ""
+ else: # invalid request
+ return 4, 400, "Invalid request property", ""
+
+
+class RfManagerNetworkProtocol(RfResource):
+ pass
+
+
+# the Manager Ethernet Collection
+class RfManagerEthernetColl(RfCollection):
+ def element_type(self):
+ return RfManagerEthernet
+
+
+# the Manager Ethernet Instance
+class RfManagerEthernet(RfResource):
+ def patch_resource(self, patch_data):
+ # TODO: check and save the data
+ # for now, just return ok w/ 204 no content
+ return 0, 204, None, None
+
+
+class RfSerialInterfaceCollection(RfCollection):
+ def element_type(self):
+ return RfSerialInterface
+
+
+class RfSerialInterface(RfResource):
+ pass
+
+
+class RfVirtualMediaCollection(RfCollection):
+ def element_type(self):
+ return RfVirtualMedia
+
+
+class RfVirtualMedia(RfResource):
+ pass
+
+
+class RfNics(RfResource):
+ def create_sub_objects(self, base_path, rel_path):
+ resource_path = os.path.join(base_path, rel_path);
+ contents = os.listdir(resource_path)
+ for item in contents:
+ if item == "Dedicated":
+ self.components[item] = RfDedicatedNicCollection(base_path,
+ os.path.join(rel_path, item),
+ parent=self)
+
+
+class RfDedicatedNicCollection(RfCollection):
+ def element_type(self):
+ return RfNic
+
+
+class RfNic(RfResource):
+ pass
+
+
+class RfActiveHealthSystem(RfResource):
+ pass
+
+
+class RfDateTime(RfResource):
+ pass
+
+
+class RfEmbeddedMedia(RfResource):
+ pass
+
+
+class RfLicenseServiceCollection(RfCollection):
+ def element_type(self):
+ return RfLicenseService
+
+
+class RfLicenseService(RfResource):
+ pass
+
+
+class RfFederationGroupCollection(RfCollection):
+ def element_type(self):
+ return RfFederationGroup
+
+
+class RfFederationGroup(RfResource):
+ pass
+
+
+class RfFederationPeerCollection(RfCollection):
+ def element_type(self):
+ return RfFederationPeer
+
+
+class RfFederationPeer(RfResource):
+ pass
+
+
+class RfManagerUpdateService(RfResource):
+ pass
diff --git a/RedfishClientPkg/Tools/Redfish-Profile-Simulator/v1sim/network.py b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/v1sim/network.py
new file mode 100644
index 0000000000..d96d29c5ad
--- /dev/null
+++ b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/v1sim/network.py
@@ -0,0 +1,48 @@
+import os
+
+from .resource import RfCollection, RfResource
+
+
+class RfNetworkService(RfResource):
+ pass
+
+
+class RfEthernetCollection(RfCollection):
+ def element_type(self):
+ return RfEthernet
+
+ def create_sub_objects(self, base_path, rel_path):
+ self.elements = {}
+ resource_path = os.path.join(base_path, rel_path);
+ contents = os.listdir(resource_path)
+ for item in contents:
+ if item == "VLANs":
+ self.components[item] = RfVLanCollection(base_path, os.path.join(rel_path, item), parent=self)
+ else:
+ item_path = os.path.join(resource_path, item)
+ if os.path.isdir(item_path):
+ etype = self.element_type() # type: Type[RfEthernetCollection]
+ self.elements[item] = etype(base_path,
+ os.path.normpath("%s/%s" % (rel_path, item)),
+ parent=self)
+
+class RfEthernet(RfResource):
+ pass
+
+
+class RfVLanCollection(RfCollection):
+ def element_type(self):
+ return RfVLan
+
+
+class RfVLan(RfResource):
+ pass
+
+
+class RfNetworkInterfaceCollection(RfCollection):
+ def element_type(self):
+ return RfNetworkInterface
+
+
+class RfNetworkInterface(RfResource):
+ pass
diff --git a/RedfishClientPkg/Tools/Redfish-Profile-Simulator/v1sim/redfishURIs.py b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/v1sim/redfishURIs.py
new file mode 100644
index 0000000000..2380a4058a
--- /dev/null
+++ b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/v1sim/redfishURIs.py
@@ -0,0 +1,309 @@
+# Copyright Notice:
+# Copyright 2016 Distributed Management Task Force, Inc. All rights reserved.
+# License: BSD 3-Clause License. For full text see link: https://github.com/DMTF/Redfish-Profile-Simulator/blob/master/LICENSE.md
+
+import json
+
+from flask import Flask
+from flask import request
+
+from .flask_redfish_auth import RfHTTPBasicOrTokenAuth
+from .resource import RfResource, RfResourceRaw, RfCollection
+
+
+def rfApi_SimpleServer(root, versions, host="127.0.0.1", port=5000):
+ app = Flask(__name__)
+
+ # create auth class that does basic or redifish session auth
+ auth = RfHTTPBasicOrTokenAuth()
+
+ # define basic auth decorator used by flask
+ # for basic auth, we only support user=catfish, passwd=hunter
+ @auth.verify_basic_password
+ def verify_rf_passwd(user, passwd):
+ if user == "root":
+ if passwd == "password123456":
+ return True
+ return False
+
+ # define Redfish Token/Session auth decorator used by flask
+ # for session token auth, only support toden: 123456CATFISHauthcode
+ @auth.verify_token
+ def verify_rf_token(auth_token):
+ # lookup the user for this token
+ # lookup the privileges for this user
+ # check privilege
+ # print("at verify_rf_token. auth_token={}".format(auth_token))
+ if auth_token == "123456SESSIONauthcode": # the magic token
+ return True
+ else:
+ return False
+
+ # define redfish URI APIs for flask
+
+ # GET /redfish
+ @app.route("/redfish", methods=['GET'])
+ @app.route("/redfish/", methods=['GET'])
+ def rf_versions():
+ return versions.get_resource()
+
+ # GET /redfish/v1
+ @app.route("/redfish/v1", methods=['GET'])
+ @app.route("/redfish/v1/", methods=['GET'])
+ def rf_service_root():
+ return root.get_resource()
+
+ # GET /redfish/v1/$metadata
+ @app.route("/redfish/v1/$metadata", methods=['GET'])
+ def rf_metadata(rf_path='$metadata'):
+ return resolve_path(root, rf_path)
+
+ # GET /redfish/v1/odata
+ @app.route("/redfish/v1/odata", methods=['GET'])
+ @app.route("/redfish/v1/odata/", methods=['GET'])
+ def rf_odata(rf_path='odata'):
+ return resolve_path(root, rf_path)
+
+ @app.route("/redfish/v1/<path:rf_path>", methods=['GET'])
+ @app.route("/redfish/v1/<path:rf_path>/", methods=['GET'])
+ @auth.rfAuthRequired
+ def rf_subsystems(rf_path):
+ return resolve_path(root, rf_path)
+
+ # this is a special test API -- an authenticated service root
+ @app.route("/redfish/v1/A", methods=['GET'])
+ @auth.rfAuthRequired
+ def rf_service_root2():
+ print("root2")
+ return root.get_resource()
+
+ @app.route("/redfish/v1/Systems/<path:sys_path>", methods=['PATCH'])
+ @app.route("/redfish/v1/Systems/<path:sys_path>/", methods=['PATCH'])
+ @auth.rfAuthRequired
+ def rf_computer_systempatch(sys_path):
+ rdata = request.get_json(cache=True)
+ print("rdata:{}".format(rdata))
+ obj = patch_path(root.systems, sys_path)
+ rc, status_code, err_string, resp = obj.patch_resource(rdata)
+ if rc == 0:
+ return "", status_code
+ else:
+ return err_string, status_code
+
+ @app.route("/redfish/v1/Systems/<string:system_id>/Actions/ComputerSystem.Reset", methods=['POST'])
+ @app.route("/redfish/v1/Systems/<string:system_id>/Actions/ComputerSystem.Reset/", methods=['POST'])
+ @auth.rfAuthRequired
+ def rf_computer_systemreset(system_id):
+ # print("in reset")
+ rdata = request.get_json(cache=True)
+ # print("rdata:{}".format(rdata))
+ rc, status_code, err_string, resp = root.components['Systems'].get_element(system_id).reset_resource(rdata)
+ if rc == 0:
+ return "", status_code
+ else:
+ return err_string, status_code
+
+ @app.route("/redfish/v1/Systems/<string:system_id>/bios/Actions/Bios.ResetBios", methods=['POST'])
+ @app.route("/redfish/v1/Systems/<string:system_id>/bios/Actions/Bios.ResetBios/", methods=['POST'])
+ @auth.rfAuthRequired
+ def rf_computer_biosreset(system_id):
+ # print("in reset")
+ rdata = request.get_json(cache=True)
+ # print("rdata:{}".format(rdata))
+ system = root.systems.get_element(system_id)
+ bios = system.get_component("bios")
+ rc, status_code, err_string, resp = bios.reset_resource(rdata)
+ if rc == 0:
+ return "", status_code
+ else:
+ return err_string, status_code
+
+ @app.route("/redfish/v1/Systems/<string:system_id>/bios/Actions/Bios.ChangePassword", methods=['PATCH'])
+ @app.route("/redfish/v1/Systems/<string:system_id>/bios/Actions/Bios.ChangePassword/", methods=['PATCH'])
+ @auth.rfAuthRequired
+ def rf_computer_change_pswd(system_id):
+ # print("in reset")
+ rdata = request.get_json(cache=True)
+ # print("rdata:{}".format(rdata))
+ system = root.systems.get_element(system_id)
+ bios = system.get_component("bios")
+ rc, status_code, err_string, resp = bios.change_password(rdata)
+ if rc == 0:
+ return "", status_code
+ else:
+ return err_string, status_code
+
+ @app.route("/redfish/v1/Chassis/<string:chassis_id>/Actions/Chassis.Reset", methods=['POST'])
+ @app.route("/redfish/v1/Chassis/<string:chassis_id>/Actions/Chassis.Reset/", methods=['POST'])
+ @auth.rfAuthRequired
+ def rf_computer_chassisreset(chassis_id):
+ # print("in reset")
+ rdata = request.get_json(cache=True)
+ # print("rdata:{}".format(rdata))
+ rc, status_code, err_string, resp = root.chassis.get_element(chassis_id).reset_resource(rdata)
+ if rc == 0:
+ return "", status_code
+ else:
+ return err_string, status_code
+
+ @app.route("/redfish/v1/Chassis/<string:chassis_id>/Power", methods=['PATCH'])
+ @app.route("/redfish/v1/Chassis/<string:chassis_id>/Power/", methods=['PATCH'])
+ @auth.rfAuthRequired
+ def rf_chassis_powerpatch(chassis_id):
+ # rawdata=request.data
+ rdata = request.get_json(cache=True)
+ # print("RRrdata:{}".format(rdata))
+ rc, status_code, err_string, resp = root.chassis.get_element(chassis_id).power.patch_resource(rdata)
+ if rc == 0:
+ return "", status_code
+ else:
+ return err_string, status_code
+
+ @app.route("/redfish/v1/Managers/<string:manager_id>", methods=['PATCH'])
+ @app.route("/redfish/v1/Managers/<string:manager_id>/", methods=['PATCH'])
+ @auth.rfAuthRequired
+ def rf_patch_manager_entity(manager_id):
+ rdata = request.get_json(cache=True)
+ # print("RRrdata:{}".format(rdata))
+ rc, status_code, err_string, resp = root.managers.get_element(manager_id).patch_resource(rdata)
+ if rc == 0:
+ return "", status_code
+ else:
+ return err_string, status_code
+
+ # rest/v1/Managers/1
+ @app.route("/redfish/v1/Managers/<string:manager_id>/Actions/Manager.Reset", methods=['POST'])
+ @app.route("/redfish/v1/Managers/<string:manager_id>/Actions/Manager.Reset/", methods=['POST'])
+ @auth.rfAuthRequired
+ def rf_reset_manager(manager_id):
+ rdata = request.get_json(cache=True)
+ # print("rdata:{}".format(rdata))
+ rc, status_code, err_string, resp = root.managers.get_element(manager_id).reset_resource(rdata)
+ if rc == 0:
+ return "", status_code
+ else:
+ return err_string, status_code
+
+ @app.route("/redfish/v1/Managers/<string:manager_id>/EthernetInterfaces/<string:eth_id>", methods=['PATCH'])
+ @app.route("/redfish/v1/Managers/<string:manager_id>/EthernetInterfaces/<string:eth_id>/", methods=['PATCH'])
+ @auth.rfAuthRequired
+ def rf_patch_manager_nic_entity(manager_id, eth_id):
+ resp = root.managers.get_element(manager_id).ethernetColl.get_interface(eth_id).get_resource()
+ rdata = request.get_json(cache=True)
+ # print("RRrdata:{}".format(rdata))
+ ethernet_coll = root.managers.get_element(manager_id).ethernetColl
+ rc, status_code, err_string, resp = ethernet_coll.get_interface(eth_id).patch_resource(rdata)
+ if rc == 0:
+ return "", status_code
+ else:
+ return err_string, status_code
+
+ @app.route("/redfish/v1/SessionService", methods=['PATCH'])
+ @app.route("/redfish/v1/SessionService/", methods=['PATCH'])
+ @auth.rfAuthRequired
+ def rf_patch_session_service():
+ rdata = request.get_json(cache=True)
+ # print("RRrdata:{}".format(rdata))
+ rc, status_code, err_string, resp = root.sessionService.patch_resource(rdata)
+ if rc == 0:
+ return "", status_code
+ else:
+ return err_string, status_code
+
+ # TODO: call root.sessionService.sessions.sessionLogin(usr,pwd), return resp, status_code, hdr
+ # login API, user catfish, password=hunter, authToken=123456CATFISHauthcode
+ @app.route("/redfish/v1/SessionService/Sessions", methods=['POST'])
+ def rf_login():
+ print("login")
+ rdata = request.get_json(cache=True)
+ print("rdata:{}".format(rdata))
+ if rdata["UserName"] == "root" and rdata["Password"] == "password123456":
+ x = {"Id": "SESSION123456"}
+ resp = json.dumps(x)
+ print("resp:{}".format(resp))
+ hdr = {"X-Auth-Token": "123456SESSIONauthcode",
+ "Location": "/redfish/v1/SessionService/Sessions/SESSION123456"}
+ return resp, 201, hdr
+ else:
+ return "", 401
+
+ # TODO: call root.sessionService.sessions.delete(sessId), return resp,status,hdr
+ # logout API
+ @app.route("/redfish/v1/SessionService/Sessions/<string:session_id>", methods=['DELETE'])
+ @auth.rfAuthRequired
+ def rf_session_logout(session_id):
+ print("session logout %s" % session_id)
+ # rdata=request.get_json(cache=True)
+ # print("rdata:{}".format(rdata))
+ return "", 204
+
+ @app.route("/redfish/v1/AccountService", methods=['PATCH'])
+ @auth.rfAuthRequired
+ def rf_patch_account_service():
+ rdata = request.get_json(cache=True)
+ rc, status_code, err_string, resp = root.accountService.patch_resource(rdata)
+ if rc == 0:
+ return "", status_code
+ else:
+ return err_string, status_code
+
+ def resolve_path(service, path):
+ parts = path.split('/')
+ result = service
+ current_obj = service
+ for part in parts:
+ if isinstance(current_obj, RfCollection):
+ result = current_obj.get_element(part)
+ current_obj = result
+ elif isinstance(current_obj, RfResource):
+ result = current_obj.get_component(part)
+ if not result:
+ result = current_obj.get_attribute(part)
+ break
+ else:
+ current_obj = result
+
+ if isinstance(result, (RfResource, RfResourceRaw)):
+ return result.get_resource()
+ else:
+ return result
+
+ def patch_path(service, path):
+ parts = path.split('/')
+ result = None
+ current_obj = service
+ for part in parts:
+ if isinstance(current_obj, RfCollection):
+ result = current_obj.get_element(part)
+ current_obj = result
+ elif isinstance(current_obj, RfResource):
+ result = current_obj.get_component(part)
+ if not result:
+ result = current_obj
+ break
+ else:
+ current_obj = result
+ return result
+
+ '''
+ @app.route("/rest/v1/xxx/x", methods=['GET'])
+ def rfXxxx():
+ resp=xxx.getObject()
+ return(resp)
+ '''
+
+ # END file redfishURIs
+
+ # start Flask REST engine running
+ app.run(host=host, port=port)
+
+ # never returns
+
+
+'''
+reference source links:
+https://gist.github.com/lrei/2408383
+http://docs.python-requests.org/en/v0.10.6/api/
+http://flask.pocoo.org/docs/0.10/quickstart/
+
+'''
diff --git a/RedfishClientPkg/Tools/Redfish-Profile-Simulator/v1sim/resource.py b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/v1sim/resource.py
new file mode 100644
index 0000000000..6fee348064
--- /dev/null
+++ b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/v1sim/resource.py
@@ -0,0 +1,100 @@
+# Copyright Notice:
+# Copyright 2016 Distributed Management Task Force, Inc. All rights reserved.
+# License: BSD 3-Clause License. For full text see link: https://github.com/DMTF/Redfish-Profile-Simulator/blob/master/LICENSE.md
+
+import json
+import os
+import sys
+
+import flask
+
+if sys.version_info >= (3, 5):
+ from typing import Type
+
+
+class RfResource:
+ def __init__(self, base_path, rel_path, parent=None):
+ self.parent = parent
+ self.components = {}
+
+ path = os.path.join(base_path, rel_path)
+ indx_file_path = os.path.join(path, "index.json")
+ print("*****Loading Mockup json file:{}".format(indx_file_path))
+ if os.path.exists(indx_file_path):
+ res_file = open(indx_file_path, "r")
+ res_rawdata = res_file.read()
+ self.res_data = json.loads(res_rawdata)
+ self.create_sub_objects(base_path, rel_path)
+ self.final_init_processing(base_path, rel_path)
+ else:
+ self.res_data = {}
+
+ def create_sub_objects(self, base_path, rel_path):
+ pass
+
+ def final_init_processing(self, base_path, rel_path):
+ pass
+
+ def get_resource(self):
+ return flask.jsonify(self.res_data)
+
+ def get_attribute(self, attribute):
+ return flask.jsonify(self.res_data[attribute])
+
+ def get_component(self, component):
+ if component in self.components:
+ return self.components[component]
+ else:
+ return None
+
+ def patch_resource(self, patch_data):
+ for key in patch_data.keys():
+ if key in self.res_data:
+ self.res_data[key] = patch_data[key]
+ else:
+ raise Exception("attribute %s not found" % key)
+
+
+class RfResourceRaw:
+ def __init__(self, base_path, rel_path, parent=None):
+ self.parent = parent
+ path = os.path.join(base_path, rel_path)
+ indx_file_path = os.path.join(path, "index.xml")
+ print("*****Loading Mockup raw data file:{}".format(indx_file_path))
+ res_file = open(indx_file_path, "r")
+ res_raw_data = res_file.read()
+ self.res_data = res_raw_data
+ self.create_subobjects(base_path, rel_path)
+ self.final_init_processing(base_path, rel_path)
+
+ def create_subobjects(self, base_path, rel_path):
+ pass
+
+ def final_init_processing(self, base_path, rel_path):
+ pass
+
+ def get_resource(self):
+ return flask.Response(response=self.res_data, status=200, mimetype='application/xml')
+
+
+class RfCollection(RfResource):
+ def create_sub_objects(self, base_path, rel_path):
+ self.elements = {}
+ subpath = os.path.join(base_path, rel_path)
+ contents = os.listdir(subpath)
+ for item in contents:
+ item_path = os.path.join(subpath, item)
+ if os.path.isdir(item_path):
+ etype = self.element_type() # type: Type[RfResource]
+ self.elements[item] = etype(base_path,
+ os.path.normpath("%s/%s" % (rel_path, item)),
+ parent=self)
+
+ def element_type(self):
+ pass
+
+ def get_elements(self):
+ return self.elements
+
+ def get_element(self, element_id):
+ return self.elements[element_id]
diff --git a/RedfishClientPkg/Tools/Redfish-Profile-Simulator/v1sim/security.py b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/v1sim/security.py
new file mode 100644
index 0000000000..deec1b2df9
--- /dev/null
+++ b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/v1sim/security.py
@@ -0,0 +1,35 @@
+import os
+
+from .resource import RfResource
+
+
+class RfSecurityService(RfResource):
+ def create_sub_objects(self, base_path, rel_path):
+ resource_path = os.path.join(base_path, rel_path);
+ contents = os.listdir(resource_path)
+ for item in contents:
+ if item == "ESKM":
+ self.components[item] = RfESKM(base_path, os.path.join(rel_path, item), parent=self)
+ if item == "HttpsCert":
+ self.components[item] = RfHttpsCert(base_path, os.path.join(rel_path, item), parent=self)
+ if item == "SSO":
+ self.components[item] = RfSSO(base_path, os.path.join(rel_path, item), parent=self)
+ if item == "CertificateAuthentication":
+ self.components[item] = RfCertificateAuthentication(base_path, os.path.join(rel_path, item),
+ parent=self)
+
+
+class RfESKM(RfResource):
+ pass
+
+
+class RfHttpsCert(RfResource):
+ pass
+
+
+class RfSSO(RfResource):
+ pass
+
+
+class RfCertificateAuthentication(RfResource):
+ pass
diff --git a/RedfishClientPkg/Tools/Redfish-Profile-Simulator/v1sim/serviceRoot.py b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/v1sim/serviceRoot.py
new file mode 100644
index 0000000000..6334ab1b5a
--- /dev/null
+++ b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/v1sim/serviceRoot.py
@@ -0,0 +1,87 @@
+# Copyright Notice:
+# Copyright 2016 Distributed Management Task Force, Inc. All rights reserved.
+# License: BSD 3-Clause License. For full text see link: https://github.com/DMTF/Redfish-Profile-Simulator/blob/master/LICENSE.md
+
+import os
+
+from .accountService import RfAccountServiceObj
+from .chassis import RfChassisCollection
+from .managers import RfManagersCollection
+from .resource import RfResource, RfCollection
+from .resource import RfResourceRaw
+from .sessionService import RfSessionServiceObj
+from .systems import RfSystemsCollection
+from .updateService import RfUpdateServiceObj
+
+
+class RfServiceRoot(RfResource):
+ def create_sub_objects(self, base_path, rel_path):
+ resource_path = os.path.join(base_path, rel_path);
+ contents = os.listdir(resource_path)
+ for item in contents:
+ if item == "odata":
+ self.components[item] = RfOdataServiceDoc(base_path, os.path.join(rel_path, item), parent=self)
+ elif item == "$metadata":
+ self.components[item] = RfOdataMetadata(base_path, os.path.join(rel_path, item), parent=self)
+ elif item == "Systems":
+ self.components[item] = RfSystemsCollection(base_path, os.path.join(rel_path, item), parent=self)
+ elif item == "Chassis":
+ self.components[item] = RfChassisCollection(base_path, os.path.join(rel_path, item), parent=self)
+ elif item == "Managers":
+ self.components[item] = RfManagersCollection(base_path, os.path.join(rel_path, item), parent=self)
+ elif item == "AccountService":
+ self.components[item] = RfAccountServiceObj(base_path, os.path.join(rel_path, item), parent=self)
+ elif item == "SessionService":
+ self.components[item] = RfSessionServiceObj(base_path, os.path.join(rel_path, item), parent=self)
+ elif item == "ResourceDirectory":
+ self.components[item] = RfResourceDirectoryObj(base_path, os.path.join(rel_path, item), parent=self)
+ elif item == "UpdateService":
+ self.components[item] = RfUpdateServiceObj(base_path, os.path.join(rel_path, item), parent=self)
+ elif item == "Registries":
+ self.components[item] = RfRegistryCollection(base_path, os.path.join(rel_path, item), parent=self)
+ elif item == "EventService":
+ self.components[item] = RfEventServiceObj(base_path, os.path.join(rel_path, item), parent=self)
+
+ def final_init_processing(self, base_path, rel_path):
+ print("\n\n{}".format(self.res_data['Name']))
+
+
+class RfOdataServiceDoc(RfResource):
+ pass
+
+
+class RfOdataMetadata(RfResourceRaw):
+ pass
+
+
+class RfResourceDirectoryObj(RfResource):
+ pass
+
+
+class RfRegistryCollection(RfCollection):
+ def element_type(self):
+ return RfRegistry
+
+
+class RfRegistry(RfResource):
+ pass
+
+
+class RfEventServiceObj(RfResource):
+ def create_sub_objects(self, base_path, rel_path):
+ resource_path = os.path.join(base_path, rel_path);
+ contents = os.listdir(resource_path)
+ for item in contents:
+ if item == "EventSubscriptions":
+ self.components[item] = RfEventSubscriptionCollection(base_path,
+ os.path.join(rel_path, item),
+ parent=self)
+
+
+class RfEventSubscriptionCollection(RfCollection):
+ def element_type(self):
+ return RfEventSubscription
+
+
+class RfEventSubscription(RfResource):
+ pass
diff --git a/RedfishClientPkg/Tools/Redfish-Profile-Simulator/v1sim/serviceVersions.py b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/v1sim/serviceVersions.py
new file mode 100644
index 0000000000..00279e5019
--- /dev/null
+++ b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/v1sim/serviceVersions.py
@@ -0,0 +1,9 @@
+# Copyright Notice:
+# Copyright 2016 Distributed Management Task Force, Inc. All rights reserved.
+# License: BSD 3-Clause License. For full text see link: https://github.com/DMTF/Redfish-Profile-Simulator/blob/master/LICENSE.md
+
+from .resource import RfResource
+
+
+class RfServiceVersions(RfResource):
+ pass
diff --git a/RedfishClientPkg/Tools/Redfish-Profile-Simulator/v1sim/sessionService.py b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/v1sim/sessionService.py
new file mode 100644
index 0000000000..0eeb93b91a
--- /dev/null
+++ b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/v1sim/sessionService.py
@@ -0,0 +1,41 @@
+# Copyright Notice:
+# Copyright 2016 Distributed Management Task Force, Inc. All rights reserved.
+# License: BSD 3-Clause License. For full text see link: https://github.com/DMTF/Redfish-Profile-Simulator/blob/master/LICENSE.md
+
+import os
+
+from .resource import RfResource, RfCollection
+
+
+class RfSessionServiceObj(RfResource):
+ # create instance of sessionService
+ def create_sub_objects(self, base_path, rel_path):
+ self.components["Sessions"] = RfSessionCollection(base_path,
+ os.path.normpath("redfish/v1/SessionService/Sessions"),
+ parent=self)
+
+ def patch_resource(self, patch_data):
+ # first verify client didn't send us a property we cant patch
+ for key in patch_data.keys():
+ if key != "SessionTimeout":
+ return 4, 400, "Invalid Patch Property Sent", ""
+ # now patch the valid properties sent
+ if "SessionTimeout" in patch_data:
+ new_val = patch_data['SessionTimeout']
+ if new_val < 30 or new_val > 86400:
+ return 4, 400, "Bad Request-not in correct range", ""
+ else:
+ self.res_data['SessionTimeout'] = new_val
+ return 0, 204, None, None
+ else:
+ return 4, 400, "Invalid Patch Property Sent", ""
+
+
+class RfSessionCollection(RfCollection):
+ def element_type(self):
+ return RfSessionObj
+
+
+# Service Collection Entries
+class RfSessionObj(RfResource):
+ pass
diff --git a/RedfishClientPkg/Tools/Redfish-Profile-Simulator/v1sim/storage.py b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/v1sim/storage.py
new file mode 100644
index 0000000000..04586d8332
--- /dev/null
+++ b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/v1sim/storage.py
@@ -0,0 +1,116 @@
+# Copyright Notice:
+# Copyright 2016 Distributed Management Task Force, Inc. All rights reserved.
+# License: BSD 3-Clause License. For full text see link: https://github.com/DMTF/Redfish-Profile-Simulator/blob/master/LICENSE.md
+
+import os
+
+from .resource import RfResource, RfCollection
+
+
+class RfSimpleStorageCollection(RfCollection):
+ def element_type(self):
+ return RfSimpleStorage
+
+
+class RfSimpleStorage(RfResource):
+ pass
+
+
+class RfSmartStorage(RfResource):
+ def create_sub_objects(self, base_path, rel_path):
+ resource_path = os.path.join(base_path, rel_path);
+ contents = os.listdir(resource_path)
+ for item in contents:
+ if item == "ArrayControllers":
+ self.components[item] = RfArrayControllerCollection(base_path,
+ os.path.join(rel_path, item),
+ parent=self)
+ if item == "HostBusAdapters":
+ self.components[item] = RfHostBusAdapterCollection(base_path,
+ os.path.join(rel_path, item),
+ parent=self)
+
+
+class RfArrayControllerCollection(RfCollection):
+ def element_type(self):
+ return RfArrayController
+
+
+class RfArrayController(RfResource):
+ def create_sub_objects(self, base_path, rel_path):
+ resource_path = os.path.join(base_path, rel_path);
+ contents = os.listdir(resource_path)
+ for item in contents:
+ if item == "DiskDrives":
+ self.components[item] = RfDiskDriveCollection(base_path, os.path.join(rel_path, item),
+ parent=self)
+ if item == "LogicalDrives":
+ self.components[item] = RfLogicalDriveCollection(base_path, os.path.join(rel_path, item),
+ parent=self)
+
+ if item == "StorageEnclosures":
+ self.components[item] = RfStorageEnclosureCollection(base_path, os.path.join(rel_path, item),
+ parent=self)
+ if item == "UnconfiguredDrives":
+ self.components[item] = RfUnconfiguredDriveCollection(base_path, os.path.join(rel_path, item),
+ parent=self)
+
+
+class RfHostBusAdapterCollection(RfCollection):
+ def element_type(self):
+ return RfHostBusAdapter
+
+
+class RfHostBusAdapter(RfResource):
+ pass
+
+
+class RfDiskDriveCollection(RfCollection):
+ def element_type(self):
+ return RfDiskDrive
+
+
+class RfDiskDrive(RfResource):
+ pass
+
+
+class RfLogicalDriveCollection(RfCollection):
+ def element_type(self):
+ return RfLogicalDrive
+
+
+class RfLogicalDrive(RfResource):
+ def create_sub_objects(self, base_path, rel_path):
+ resource_path = os.path.join(base_path, rel_path);
+ contents = os.listdir(resource_path)
+ for item in contents:
+ if item == "DataDrives":
+ self.components[item] = RfDataDriveCollection(base_path, os.path.join(rel_path, item),
+ parent=self)
+
+
+class RfDataDriveCollection(RfCollection):
+ def element_type(self):
+ return RfDataDrive
+
+
+class RfDataDrive(RfResource):
+ pass
+
+
+class RfStorageEnclosureCollection(RfCollection):
+ def element_type(self):
+ return RfStorageEnclosure
+
+
+class RfStorageEnclosure(RfResource):
+ pass
+
+
+class RfUnconfiguredDriveCollection(RfCollection):
+ def element_type(self):
+ return RfUnconfiguredDrive
+
+
+class RfUnconfiguredDrive(RfResource):
+ pass
diff --git a/RedfishClientPkg/Tools/Redfish-Profile-Simulator/v1sim/systems.py b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/v1sim/systems.py
new file mode 100644
index 0000000000..b107f035db
--- /dev/null
+++ b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/v1sim/systems.py
@@ -0,0 +1,198 @@
+# Copyright Notice:
+# Copyright 2016 Distributed Management Task Force, Inc. All rights reserved.
+# License: BSD 3-Clause License. For full text see link: https://github.com/DMTF/Redfish-Profile-Simulator/blob/master/LICENSE.md
+
+import os
+
+from .common_services import RfLogServiceCollection
+from .network import RfEthernetCollection, RfNetworkInterfaceCollection
+from .resource import RfResource, RfCollection
+from .storage import RfSimpleStorageCollection, RfSmartStorage
+
+
+class RfSystemsCollection(RfCollection):
+ def element_type(self):
+ return RfSystemObj
+
+
+class RfSystemObj(RfResource):
+ def create_sub_objects(self, base_path, rel_path):
+ resource_path = os.path.join(base_path, rel_path)
+ contents = os.listdir(resource_path)
+ for item in contents:
+ if item == "Bios":
+ self.components[item] = RfBios(base_path, os.path.join(rel_path, item), parent=self)
+ elif item == "EthernetInterfaces":
+ self.components[item] = RfEthernetCollection(base_path, os.path.join(rel_path, item), parent=self)
+ elif item == "LogServices":
+ self.components[item] = RfLogServiceCollection(base_path, os.path.join(rel_path, item), parent=self)
+ elif item == "Memory":
+ self.components[item] = RfMemoryCollection(base_path, os.path.join(rel_path, item), parent=self)
+ elif item == "Processors":
+ self.components[item] = RfProcessorCollection(base_path, os.path.join(rel_path, item), parent=self)
+ elif item == "SimpleStorage":
+ self.components[item] = RfSimpleStorageCollection(base_path, os.path.join(rel_path, item), parent=self)
+ elif item == "SmartStorage":
+ self.components[item] = RfSmartStorage(base_path, os.path.join(rel_path, item), parent=self)
+ elif item == "SecureBoot":
+ self.components[item] = RfSecureBoot(base_path, os.path.join(rel_path, item), parent=self)
+ elif item == "NetworkInterfaces":
+ self.components[item] = RfNetworkInterfaceCollection(base_path, os.path.join(rel_path, item), parent=self)
+ elif item == "PCIeDevices":
+ self.components[item] = RfPCIeDeviceCollection(base_path, os.path.join(rel_path, item), parent=self)
+ elif item == "PCISlots":
+ self.components[item] = RfPCISlotCollection(base_path, os.path.join(rel_path, item), parent=self)
+ elif item == "FirmwareInventory":
+ self.components[item] = RfSystemFirmwareInventory(base_path, os.path.join(rel_path, item), parent=self)
+ elif item == "USBDevices":
+ self.components[item] = RfUSBDeviceCollection(base_path, os.path.join(rel_path, item), parent=self)
+ elif item == "USBPorts":
+ self.components[item] = RfUSBPortCollection(base_path, os.path.join(rel_path, item), parent=self)
+
+ def patch_resource(self, patch_data):
+ # first verify client didn't send us a property we cant patch
+ for key in patch_data.keys():
+ if key != "AssetTag" and key != "IndicatorLED" and key != "Boot":
+ return 4, 400, "Invalid Patch Property Sent", ""
+ elif key == "Boot":
+ for prop2 in patch_data["Boot"].keys():
+ if prop2 != "BootSourceOverrideEnabled" and prop2 != "BootSourceOverrideTarget":
+ return 4, 400, "Invalid Patch Property Sent", ""
+ # now patch the valid properties sent
+ if "AssetTag" in patch_data:
+ print("assetTag:{}".format(patch_data["AssetTag"]))
+ self.res_data['AssetTag'] = patch_data['AssetTag']
+ if "IndicatorLED" in patch_data:
+ self.res_data['IndicatorLED'] = patch_data['IndicatorLED']
+ if "Boot" in patch_data:
+ boot_data = patch_data["Boot"]
+ if "BootSourceOverrideEnabled" in boot_data:
+ value = boot_data["BootSourceOverrideEnabled"]
+ valid_values = ["Once", "Disabled", "Continuous"]
+ if value in valid_values:
+ self.res_data['Boot']['BootSourceOverrideEnabled'] = value
+ else:
+ return 4, 400, "Invalid_Value_Specified: BootSourceOverrideEnable", ""
+ if "BootSourceOverrideTarget" in boot_data:
+ value = boot_data["BootSourceOverrideTarget"]
+ valid_values = self.res_data['Boot']['BootSourceOverrideTarget@Redfish.AllowableValues']
+ if value in valid_values:
+ self.res_data['Boot']['BootSourceOverrideTarget'] = value
+ else:
+ return 4, 400, "Invalid_Value_Specified: BootSourceOverrideTarget", ""
+ return 0, 204, None, None
+
+ def reset_resource(self, reset_data):
+ if "ResetType" in reset_data:
+ # print("RESETDATA: {}".format(resetData))
+ value = reset_data['ResetType']
+ valid_values = self.res_data["Actions"]["#ComputerSystem.Reset"]["ResetType@Redfish.AllowableValues"]
+ if value in valid_values:
+ # it is a supoported reset action modify other properties appropritely
+ if value == "On" or value == "ForceRestart" or value == "GracefulRestart":
+ self.res_data["PowerState"] = "On"
+ print("PROFILE_SIM--SERVER WAS RESET. power now ON")
+ elif value == "GracefulShutdown" or value == "ForceOff":
+ self.res_data["PowerState"] = "Off"
+ print("PROFILE_SIM--SERVER WAS RESET. Power now Off")
+ return 0, 204, "System Reset", ""
+ else:
+ return 4, 400, "Invalid reset value: ResetType", ""
+ else: # invalid request
+ return 4, 400, "Invalid request property", ""
+
+
+# subclass Logs Collection
+class RfMemoryCollection(RfCollection):
+ def element_type(self):
+ return RfMemory
+
+
+class RfMemory(RfResource):
+ pass
+
+
+class RfProcessorCollection(RfCollection):
+ def element_type(self):
+ return RfProcessor
+
+
+class RfProcessor(RfResource):
+ pass
+
+
+class RfBios(RfResource):
+ def create_sub_objects(self, base_path, rel_path):
+ resource_path = os.path.join(base_path, rel_path)
+ contents = os.listdir(resource_path)
+ for item in contents:
+ if item == "Settings":
+ self.components[item] = RfBiosSettings(base_path, os.path.join(rel_path, item), parent=self)
+
+ def reset_resource(self, req_data):
+ print("bios was reset")
+ return 0, 204, "Bios Reset", ""
+
+ def change_password(self, req_data):
+ if "PasswordName" in req_data and "OldPassword" in req_data and "NewPassword" in req_data:
+ print("changed password of type %s" % req_data["PasswordName"])
+ return 0, 204, "Password Change", ""
+ else: # invalid request
+ return 4, 400, "Invalid request property", ""
+
+
+class RfBiosSettings(RfResource):
+ def patch_resource(self, patch_data):
+ if "Attributes" not in patch_data:
+ return 4, 400, "Invalid Payload. No Attributes found", ""
+ for key in patch_data["Attributes"].keys():
+ # verify client didn't send us a property we cant patch
+ if key not in self.res_data["Attributes"]:
+ return 4, 400, "Invalid Patch Property Sent", ""
+ else:
+ self.parent.res_data["Attributes"][key] = patch_data["Attributes"][key]
+ return 0, 204, None, None
+
+
+class RfPCIeDeviceCollection(RfCollection):
+ def element_type(self):
+ return RfPCIeDevice
+
+
+class RfPCIeDevice(RfResource):
+ pass
+
+
+class RfPCISlotCollection(RfCollection):
+ def element_type(self):
+ return RfPCISlot
+
+
+class RfPCISlot(RfResource):
+ pass
+
+
+class RfSecureBoot(RfResource):
+ pass
+
+
+class RfSystemFirmwareInventory(RfResource):
+ pass
+
+
+class RfUSBDeviceCollection(RfCollection):
+ def element_type(self):
+ return RfUSBDevice
+
+
+class RfUSBDevice(RfResource):
+ pass
+
+
+class RfUSBPortCollection(RfCollection):
+ def element_type(self):
+ return RfUSBPort
+
+
+class RfUSBPort(RfResource):
+ pass
diff --git a/RedfishClientPkg/Tools/Redfish-Profile-Simulator/v1sim/updateService.py b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/v1sim/updateService.py
new file mode 100644
index 0000000000..66bdf35f42
--- /dev/null
+++ b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/v1sim/updateService.py
@@ -0,0 +1,84 @@
+# Copyright Notice:
+# Copyright 2016 Distributed Management Task Force, Inc. All rights reserved.
+# License: BSD 3-Clause License. For full text see link: https://github.com/DMTF/Redfish-Profile-Simulator/blob/master/LICENSE.md
+
+import os
+
+from .resource import RfResource, RfCollection
+
+
+class RfUpdateServiceObj(RfResource):
+ def create_sub_objects(self, base_path, rel_path):
+ if os.path.isdir(os.path.join(base_path, os.path.normpath("redfish/v1/UpdateService/ComponentRepository"))):
+ self.components["ComponentRepository"] \
+ = RfComponentRepositoryCollection(base_path,
+ os.path.normpath("redfish/v1/UpdateService/ComponentRepository"),
+ parent=self)
+ if os.path.isdir(os.path.join(base_path, os.path.normpath("redfish/v1/UpdateService/FirmwareInventory"))):
+ self.components["FirmwareInventory"] \
+ = RfFirmwareInventoryCollection(base_path,
+ os.path.normpath("redfish/v1/UpdateService/FirmwareInventory"),
+ parent=self)
+
+ if os.path.isdir(os.path.join(base_path, os.path.normpath("redfish/v1/UpdateService/InstallSets"))):
+ self.components["InstallSets"] \
+ = RfInstallSetCollection(base_path,
+ os.path.normpath("redfish/v1/UpdateService/InstallSets"),
+ parent=self)
+
+ if os.path.isdir(os.path.join(base_path, os.path.normpath("redfish/v1/UpdateService/SoftwareInventory"))):
+ self.components["SoftwareInventory"] \
+ = RfSoftwareInventoryCollection(base_path,
+ os.path.normpath("redfish/v1/UpdateService/SoftwareInventory"),
+ parent=self)
+
+ if os.path.isdir(os.path.join(base_path, os.path.normpath("redfish/v1/UpdateService/UpdateTaskQueue"))):
+ self.components["UpdateTaskQueue"] \
+ = RfUpdateTaskQueueCollection(base_path,
+ os.path.normpath("redfish/v1/UpdateService/UpdateTaskQueue"),
+ parent=self)
+
+
+class RfComponentRepositoryCollection(RfCollection):
+ def element_type(self):
+ return RfComponentRepository
+
+
+class RfComponentRepository(RfResource):
+ pass
+
+
+class RfFirmwareInventoryCollection(RfCollection):
+ def element_type(self):
+ return RfComponentRepository
+
+
+class RfFirmwareInventory(RfResource):
+ pass
+
+
+class RfInstallSetCollection(RfCollection):
+ def element_type(self):
+ return RfInstallSet
+
+
+class RfInstallSet(RfResource):
+ pass
+
+
+class RfSoftwareInventoryCollection(RfCollection):
+ def element_type(self):
+ return RfSoftwareInventory
+
+
+class RfSoftwareInventory(RfResource):
+ pass
+
+
+class RfUpdateTaskQueueCollection(RfCollection):
+ def element_type(self):
+ return RfUpdateTaskQueue
+
+
+class RfUpdateTaskQueue(RfResource):
+ pass
--
2.17.1


Nickle Wang
 

Reviewed-by: Nickle Wang <nickle.wang@hpe.com>

What git SHA version that we forked here? Do we keep git version information in our README? I think it would be useful to know which version that we forked from DMTF repository later.

Thanks,
Nickle

-----Original Message-----
From: Chang, Abner (HPS SW/FW Technologist) <abner.chang@hpe.com>
Sent: Thursday, July 22, 2021 2:08 PM
To: devel@edk2.groups.io
Cc: Wang, Nickle (HPS SW) <nickle.wang@hpe.com>; Liming Gao <gaoliming@byosoft.com.cn>
Subject: [staging/edk2-redfish-client Tools PATCH 1/6] RedfishClientPkg/Tools: Initial commit of Redfish Profile Simulator

This is an open source project on DMTF GitHub.
(https://github.com/DMTF/Redfish-Profile-Simulator)
This tool simulates the HTTP request methods (POST, PATCH, PUT, GET) on
Redfish resource maintained by Redfish Profile Simulator.
EDK2 open source uses this simulator for the use case when Redfish service
has not been set up on the platform, or for the quick Redfish firmware
feature development.

We clone this project under RedfishClientPkg and maintain it by edk2
because this project has currently been using and updating rarely.
That is easier for edk2 to add features to the simulator or modify the
simulator to align with edk2 requirement on Redfish service.

The license of this tool is on the term of BSD 3-Clause License.
Refer to LICENSE.md.

Signed-off-by: Abner Chang <abner.chang@hpe.com>
Cc: Nickle Wang <nickle.wang@hpe.com>
Cc: Liming Gao <gaoliming@byosoft.com.cn>
---
.../Redfish-Profile-Simulator/AUTHORS.md | 2 +
.../Redfish-Profile-Simulator/CHANGELOG.md | 15 +
.../Redfish-Profile-Simulator/LICENSE.md | 57 ++++
.../Tools/Redfish-Profile-Simulator/README.md | 96 ++++++
.../SimpleOcpServerV1/redfish/index.json | 3 +
.../redfish/v1/$metadata/index.xml | 147 +++++++++
.../v1/AccountService/Accounts/index.json | 19 ++
.../AccountService/Accounts/jane/index.json | 19 ++
.../AccountService/Accounts/john/index.json | 19 ++
.../AccountService/Accounts/root/index.json | 19 ++
.../v1/AccountService/Roles/Admin/index.json | 17 +
.../AccountService/Roles/Operator/index.json | 15 +
.../Roles/ReadOnlyUser/index.json | 13 +
.../v1/AccountService/Roles/index.json | 19 ++
.../redfish/v1/AccountService/index.json | 25 ++
.../redfish/v1/Chassis/A33/Power/index.json | 28 ++
.../redfish/v1/Chassis/A33/Thermal/index.json | 150 +++++++++
.../redfish/v1/Chassis/A33/index.json | 46 +++
.../redfish/v1/Chassis/index.json | 13 +
.../bmc/EthernetInterfaces/eth0/index.json | 60 ++++
.../bmc/EthernetInterfaces/index.json | 15 +
.../Managers/bmc/NetworkProtocol/index.json | 47 +++
.../redfish/v1/Managers/bmc/index.json | 53 +++
.../redfish/v1/Managers/index.json | 13 +
.../Sessions/SESSION123456/index.json | 10 +
.../v1/SessionService/Sessions/index.json | 12 +
.../redfish/v1/SessionService/index.json | 17 +
.../LogServices/SEL/Entries/1/index.json | 27 ++
.../LogServices/SEL/Entries/2/index.json | 27 ++
.../LogServices/SEL/Entries/index.json | 62 ++++
.../2M220100SL/LogServices/SEL/index.json | 27 ++
.../Systems/2M220100SL/LogServices/index.json | 15 +
.../redfish/v1/Systems/2M220100SL/index.json | 70 ++++
.../redfish/v1/Systems/index.json | 13 +
.../SimpleOcpServerV1/redfish/v1/index.json | 31 ++
.../redfish/v1/odata/index.json | 56 ++++
.../redfishProfileSimulator.py | 125 +++++++
.../v1sim/__init__.py | 4 +
.../v1sim/accountService.py | 76 +++++
.../v1sim/chassis.py | 115 +++++++
.../v1sim/common_services.py | 28 ++
.../v1sim/flask_redfish_auth.py | 278 ++++++++++++++++
.../v1sim/managers.py | 211 ++++++++++++
.../v1sim/network.py | 48 +++
.../v1sim/redfishURIs.py | 309 ++++++++++++++++++
.../v1sim/resource.py | 100 ++++++
.../v1sim/security.py | 35 ++
.../v1sim/serviceRoot.py | 87 +++++
.../v1sim/serviceVersions.py | 9 +
.../v1sim/sessionService.py | 41 +++
.../v1sim/storage.py | 116 +++++++
.../v1sim/systems.py | 198 +++++++++++
.../v1sim/updateService.py | 84 +++++
53 files changed, 3141 insertions(+)
create mode 100644 RedfishClientPkg/Tools/Redfish-Profile-Simulator/AUTHORS.md
create mode 100644 RedfishClientPkg/Tools/Redfish-Profile-Simulator/CHANGELOG.md
create mode 100644 RedfishClientPkg/Tools/Redfish-Profile-Simulator/LICENSE.md
create mode 100644 RedfishClientPkg/Tools/Redfish-Profile-Simulator/README.md
create mode 100644 RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/index.json
create mode 100644 RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/$metadata/index.xml
create mode 100644 RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/AccountService/Accounts/index.json
create mode 100644 RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/AccountService/Accounts/jane/index.json
create mode 100644 RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/AccountService/Accounts/john/index.json
create mode 100644 RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/AccountService/Accounts/root/index.json
create mode 100644 RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/AccountService/Roles/Admin/index.json
create mode 100644 RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/AccountService/Roles/Operator/index.json
create mode 100644 RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/AccountService/Roles/ReadOnlyUser/index.json
create mode 100644 RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/AccountService/Roles/index.json
create mode 100644 RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/AccountService/index.json
create mode 100644 RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/Chassis/A33/Power/index.json
create mode 100644 RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/Chassis/A33/Thermal/index.json
create mode 100644 RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/Chassis/A33/index.json
create mode 100644 RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/Chassis/index.json
create mode 100644 RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/Managers/bmc/EthernetInterfaces/eth0/index.json
create mode 100644 RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/Managers/bmc/EthernetInterfaces/index.json
create mode 100644 RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/Managers/bmc/NetworkProtocol/index.json
create mode 100644 RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/Managers/bmc/index.json
create mode 100644 RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/Managers/index.json
create mode 100644 RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/SessionService/Sessions/SESSION123456/index.json
create mode 100644 RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/SessionService/Sessions/index.json
create mode 100644 RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/SessionService/index.json
create mode 100644 RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/Systems/2M220100SL/LogServices/SEL/Entries/1/index.json
create mode 100644 RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/Systems/2M220100SL/LogServices/SEL/Entries/2/index.json
create mode 100644 RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/Systems/2M220100SL/LogServices/SEL/Entries/index.json
create mode 100644 RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/Systems/2M220100SL/LogServices/SEL/index.json
create mode 100644 RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/Systems/2M220100SL/LogServices/index.json
create mode 100644 RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/Systems/2M220100SL/index.json
create mode 100644 RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/Systems/index.json
create mode 100644 RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/index.json
create mode 100644 RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/odata/index.json
create mode 100644 RedfishClientPkg/Tools/Redfish-Profile-Simulator/redfishProfileSimulator.py
create mode 100644 RedfishClientPkg/Tools/Redfish-Profile-Simulator/v1sim/__init__.py
create mode 100644 RedfishClientPkg/Tools/Redfish-Profile-Simulator/v1sim/accountService.py
create mode 100644 RedfishClientPkg/Tools/Redfish-Profile-Simulator/v1sim/chassis.py
create mode 100644 RedfishClientPkg/Tools/Redfish-Profile-Simulator/v1sim/common_services.py
create mode 100644 RedfishClientPkg/Tools/Redfish-Profile-Simulator/v1sim/flask_redfish_auth.py
create mode 100644 RedfishClientPkg/Tools/Redfish-Profile-Simulator/v1sim/managers.py
create mode 100644 RedfishClientPkg/Tools/Redfish-Profile-Simulator/v1sim/network.py
create mode 100644 RedfishClientPkg/Tools/Redfish-Profile-Simulator/v1sim/redfishURIs.py
create mode 100644 RedfishClientPkg/Tools/Redfish-Profile-Simulator/v1sim/resource.py
create mode 100644 RedfishClientPkg/Tools/Redfish-Profile-Simulator/v1sim/security.py
create mode 100644 RedfishClientPkg/Tools/Redfish-Profile-Simulator/v1sim/serviceRoot.py
create mode 100644 RedfishClientPkg/Tools/Redfish-Profile-Simulator/v1sim/serviceVersions.py
create mode 100644 RedfishClientPkg/Tools/Redfish-Profile-Simulator/v1sim/sessionService.py
create mode 100644 RedfishClientPkg/Tools/Redfish-Profile-Simulator/v1sim/storage.py
create mode 100644 RedfishClientPkg/Tools/Redfish-Profile-Simulator/v1sim/systems.py
create mode 100644 RedfishClientPkg/Tools/Redfish-Profile-Simulator/v1sim/updateService.py

diff --git a/RedfishClientPkg/Tools/Redfish-Profile-Simulator/AUTHORS.md b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/AUTHORS.md
new file mode 100644
index 0000000000..536f67e918
--- /dev/null
+++ b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/AUTHORS.md
@@ -0,0 +1,2 @@
+# Original Contribution:
+* Paul Vancil - Dell Inc. -- Dell Extreme Scale Infrastructure (ESI) Architecture Team
diff --git a/RedfishClientPkg/Tools/Redfish-Profile-Simulator/CHANGELOG.md b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/CHANGELOG.md
new file mode 100644
index 0000000000..38bb8685d1
--- /dev/null
+++ b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/CHANGELOG.md
@@ -0,0 +1,15 @@
+# Change Log
+
+## [0.9.6] - 2018-05-25
+- Fixed setuptools config to install all necessary Python modules
+- Enabled OpenBMC Static OBmcMonolythicPower8
+- Made simulator more generic to support other mockups
+- Fixed several properties in the Computer System resource
+- Fixed Content-Type header when returning XML
+
+## [0.9.2] - 2016-12-08
+- Fixex code to work with late change in mockup data. It was failing to load
+- Fixed incomplete code in systems.py modeling logs
+
+## [0.9.1] - 2016-09-06
+- Initial Public Release
diff --git a/RedfishClientPkg/Tools/Redfish-Profile-Simulator/LICENSE.md b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/LICENSE.md
new file mode 100644
index 0000000000..18e3361b0d
--- /dev/null
+++ b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/LICENSE.md
@@ -0,0 +1,57 @@
+The Distributed Management Task Force (DMTF) grants rights under copyright in
+this software on the terms of the BSD 3-Clause License as set forth below; no
+other rights are granted by DMTF. This software might be subject to other rights
+(such as patent rights) of other parties.
+
+
+### Copyrights.
+
+Copyright (c) 2016, Contributing Member(s) of Distributed Management Task Force,
+Inc.. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice, this
+list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above copyright notice, this
+list of conditions and the following disclaimer in the documentation and/or
+other materials provided with the distribution.
+* Neither the name of the Distributed Management Task Force (DMTF) nor the names
+of its contributors may be used to endorse or promote products derived from this
+software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+### Patents.
+
+This software may be subject to third party patent rights, including provisional
+patent rights ("patent rights"). DMTF makes no representations to users of the
+standard as to the existence of such rights, and is not responsible to
+recognize, disclose, or identify any or all such third party patent right,
+owners or claimants, nor for any incomplete or inaccurate identification or
+disclosure of such rights, owners or claimants. DMTF shall have no liability to
+any party, in any manner or circumstance, under any legal theory whatsoever, for
+failure to recognize, disclose, or identify any such third party patent rights,
+or for such party's reliance on the software or incorporation thereof in its
+product, protocols or testing procedures. DMTF shall have no liability to any
+party using such software, whether such use is foreseeable or not, nor to any
+patent owner or claimant, and shall have no liability or responsibility for
+costs or losses incurred if software is withdrawn or modified after publication,
+and shall be indemnified and held harmless by any party using the software from
+any and all claims of infringement by a patent owner for such use.
+
+DMTF Members that contributed to this software source code might have made
+patent licensing commitments in connection with their participation in the DMTF.
+For details, see http://dmtf.org/sites/default/files/patent-10-18-01.pdf and
+http://www.dmtf.org/about/policies/disclosures.
diff --git a/RedfishClientPkg/Tools/Redfish-Profile-Simulator/README.md b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/README.md
new file mode 100644
index 0000000000..660938f880
--- /dev/null
+++ b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/README.md
@@ -0,0 +1,96 @@
+Copyright 2016-2018 Distributed Management Task Force, Inc. All rights reserved.
+
+# Redfish Profile Simulator
+
+## About
+
+***Redfish Profile Simulator*** is a Python34 real simulator of the "simple monolithic server" feature profile.
+
+* A simple, minimal Redfish Service
+* For a monolithic Server
+* Aligned with: OCP Remote Machine Management Spec feature set
+
+### Description
+
+* Based on flask
+* Initial resources are loaded from a catfish mockup into python dictionary structures
+ * After that, data is read/patched... to the dictionaries
+* Supports BasicAuth, as well as Redfish Session Auth (for one session, one user)
+* Uses:
+ * easy to add new URIs for testing a client
+ * easy to tweak behavior or add bad responses to test a client
+ * allows testing of authentication -- which current mockup servers dont do
+ * easy to insert print statements in service to see if data coming across good..etc
+
+### Current Limitation:
+
+* supports a single user/passwd and token
+* the user/passwd is: root/password123456
+* The authToken for Session Auth is: 123456SESSIONauthcode
+* Supports only HTTP (not HTTPS)
+* with redfishtool, use options: redfishtool.py -r127.0.0.1:5000 -u root -p password123456 -S Never <subcmd>
+
+## Usage
+
+* ` python redfishProfileSimulatorMain.py [options]`
+* `[Options]`:
+
+ -V, --Version,--- the program version
+ -h, --help, --- help
+ -H<hostIP>, --Host=<hostIp> --- host IP address. dflt=127.0.0.1
+ -P<port>,--Port=<port> --- the port to use. dflt=5000
+ -p<profile_path>, --profile=<profile_path> --- the path to the Redfish profile to use. dflt="SimpleOcpServerV1"
+
+## Implementation
+
+* The simulation includes an http server, RestEngine, and dynamic Redfish datamodel.
+* You can GET, PATCH,... to the service just like a real Redfish service.
+* Both Basic and Redfish Session/Token authentication are supported
+ * for a single user/passwd and token
+ * the user/passwd is: root/password123456
+ * The authToken for Session Auth is: 123456SESSIONauthcode
+ * these can be changed by editing the redfishURSs.py file---will make dynamic later.
+* The http service and Rest engine is built on Flask, and all code is Python 3.4+
+* The data model resources are "initialized" from the SPMF "SimpleOcpServerV1" Mockup.
+ * and stored as python dictionaries
+ * then the dictionaries are updated with patches, posts, deletes.
+* The program can be extended to support other mockup \"profiles\".
+* By default, the simulation runs on localhost (127.0.0.1), on port 5000.
+ * These can be changed with CLI options: -P<port> -H <hostIP> | --port=<port> --host=<hostIp>
+
+## Simple OCP Server V1 Mockup Description
+
+* A Monolithic server:
+ * One ComputerSystem
+ * One Chassis
+ * One Manager
+
+* Provides basic management features aligned with OCP Remote Machine Management Spec 1.01:
+ * Power-on/off/reset
+ * Boot to PXE, HDD, BIOS setup (boot override)
+ * 4 temp sensors per DCMI (CPU1, CPU2, Board, Inlet)
+ * Simple Power Reading, and DCMI Power Limiting
+ * Fan Monitoring w/ redundancy
+ * Set asset tag and Indicator LED
+ * Basic inventory (serial#, model, SKU, Vendor, BIOS ver…)
+ * User Management
+ * BMC management: get/set IP, version, enable/disable protocol
+
+* What it does NOT have -- that the Redfish 1.0 model supports
+ * No PSUs in model (RMM spec did not include PSUs)
+ * No ProcessorInfo, MemoryInfo, StorageInfo, System-EthernetInterfaceInfo
+ * No Tasks
+ * JsonSchema and Registries collections left out (since that is optional)
+ * No EventService--Remote Machine Management spec used basic PET alerts
+ * Uses only the pre-defined privileges and roles
+
+## TO DO
+
+Some limitations to be extended in current implementation
+
+* Auth supports a single hard-coded username, password, and AuthToken, although the protocol is 100% compliant with respect to testing clients trying to authenticate
+ * ex with basic auth, you have to use the hard coded user/password
+ * ex with Session Auth, you just use the hard coded AuthToken
+* adding and deleting users not implemented--has 3 or 4 users predefined
+* accountService properties can be written, but failed logins, lockouts, etc is not implemented
+* system log not implemented yet
diff --git a/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/index.json b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/index.json
new file mode 100644
index 0000000000..759e3e6fdb
--- /dev/null
+++ b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/index.json
@@ -0,0 +1,3 @@
+{
+ "v1": "/redfish/v1/"
+}
diff --git a/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/$metadata/index.xml b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/$metadata/index.xml
new file mode 100644
index 0000000000..37d9529b10
--- /dev/null
+++ b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/$metadata/index.xml
@@ -0,0 +1,147 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright 2014-2016 Distributed Management Task Force, Inc. (DMTF). For the full DMTF copyright policy, see http://www.dmtf.org/about/policies/copyright.-->
+<edmx:Edmx xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx" Version="4.0">
+
+ <edmx:Reference Uri="http://redfish.dmtf.org/schemas/v1/ServiceRoot_v1.xml">
+ <edmx:Include Namespace="ServiceRoot"/>
+ <edmx:Include Namespace="ServiceRoot.v1_0_2"/>
+ </edmx:Reference>
+ <edmx:Reference Uri="http://redfish.dmtf.org/schemas/v1/AccountService_v1.xml">
+ <edmx:Include Namespace="AccountService"/>
+ <edmx:Include Namespace="AccountService.v1_0_2"/>
+ </edmx:Reference>
+ <edmx:Reference Uri="http://redfish.dmtf.org/schemas/v1/Chassis_v1.xml">
+ <edmx:Include Namespace="Chassis"/>
+ <edmx:Include Namespace="Chassis.v1_2_0"/>
+ </edmx:Reference>
+ <edmx:Reference Uri="http://redfish.dmtf.org/schemas/v1/ChassisCollection_v1.xml">
+ <edmx:Include Namespace="ChassisCollection"/>
+ </edmx:Reference>
+ <edmx:Reference Uri="http://redfish.dmtf.org/schemas/v1/ComputerSystem_v1.xml">
+ <edmx:Include Namespace="ComputerSystem"/>
+ <edmx:Include Namespace="ComputerSystem.v1_1_0"/>
+ </edmx:Reference>
+ <edmx:Reference Uri="http://redfish.dmtf.org/schemas/v1/ComputerSystemCollection_v1.xml">
+ <edmx:Include Namespace="ComputerSystemCollection"/>
+ </edmx:Reference>
+ <edmx:Reference Uri="http://redfish.dmtf.org/schemas/v1/EthernetInterface_v1.xml">
+ <edmx:Include Namespace="EthernetInterface"/>
+ <edmx:Include Namespace="EthernetInterface.v1_0_2"/>
+ </edmx:Reference>
+ <edmx:Reference Uri="http://redfish.dmtf.org/schemas/v1/EthernetInterfaceCollection_v1.xml">
+ <edmx:Include Namespace="EthernetInterfaceCollection"/>
+ </edmx:Reference>
+ <edmx:Reference Uri="http://redfish.dmtf.org/schemas/v1/IPAddresses_v1.xml">
+ <edmx:Include Namespace="IPAddresses"/>
+ <edmx:Include Namespace="IPAddresses.v1_0_2"/>
+ </edmx:Reference>
+ <edmx:Reference Uri="http://redfish.dmtf.org/schemas/v1/JsonSchemaFile_v1.xml">
+ <edmx:Include Namespace="JsonSchemaFile"/>
+ <edmx:Include Namespace="JsonSchemaFile.v1_0_2"/>
+ </edmx:Reference>
+ <edmx:Reference Uri="http://redfish.dmtf.org/schemas/v1/JsonSchemaFileCollection_v1.xml">
+ <edmx:Include Namespace="JsonSchemaFileCollection"/>
+ </edmx:Reference>
+ <edmx:Reference Uri="http://redfish.dmtf.org/schemas/v1/EventDestination_v1.xml">
+ <edmx:Include Namespace="EventDestination"/>
+ <edmx:Include Namespace="EventDestination.v1_0_2"/>
+ </edmx:Reference>
+ <edmx:Reference Uri="http://redfish.dmtf.org/schemas/v1/EventDestinationCollection_v1.xml">
+ <edmx:Include Namespace="EventDestinationCollection"/>
+ </edmx:Reference>
+ <edmx:Reference Uri="http://redfish.dmtf.org/schemas/v1/LogEntry_v1.xml">
+ <edmx:Include Namespace="LogEntry"/>
+ <edmx:Include Namespace="LogEntry.v1_0_2"/>
+ </edmx:Reference>
+ <edmx:Reference Uri="http://redfish.dmtf.org/schemas/v1/LogEntryCollection_v1.xml">
+ <edmx:Include Namespace="LogEntryCollection"/>
+ </edmx:Reference>
+ <edmx:Reference Uri="http://redfish.dmtf.org/schemas/v1/Role_v1.xml">
+ <edmx:Include Namespace="Role"/>
+ <edmx:Include Namespace="Role.v1_0_2"/>
+ </edmx:Reference>
+ <edmx:Reference Uri="http://redfish.dmtf.org/schemas/v1/RoleCollection_v1.xml">
+ <edmx:Include Namespace="RoleCollection"/>
+ </edmx:Reference>
+ <edmx:Reference Uri="http://redfish.dmtf.org/schemas/v1/LogService_v1.xml">
+ <edmx:Include Namespace="LogService"/>
+ <edmx:Include Namespace="LogService.v1_0_2"/>
+ </edmx:Reference>
+ <edmx:Reference Uri="http://redfish.dmtf.org/schemas/v1/LogServiceCollection_v1.xml">
+ <edmx:Include Namespace="LogServiceCollection"/>
+ </edmx:Reference>
+ <edmx:Reference Uri="http://redfish.dmtf.org/schemas/v1/Manager_v1.xml">
+ <edmx:Include Namespace="Manager"/>
+ <edmx:Include Namespace="Manager.v1_1_0"/>
+ </edmx:Reference>
+ <edmx:Reference Uri="http://redfish.dmtf.org/schemas/v1/ManagerCollection_v1.xml">
+ <edmx:Include Namespace="ManagerCollection"/>
+ </edmx:Reference>
+ <edmx:Reference Uri="http://redfish.dmtf.org/schemas/v1/ManagerAccount_v1.xml">
+ <edmx:Include Namespace="ManagerAccount"/>
+ <edmx:Include Namespace="ManagerAccount.v1_0_2"/>
+ </edmx:Reference>
+ <edmx:Reference Uri="http://redfish.dmtf.org/schemas/v1/ManagerAccountCollection_v1.xml">
+ <edmx:Include Namespace="ManagerAccountCollection"/>
+ </edmx:Reference>
+ <edmx:Reference Uri="http://redfish.dmtf.org/schemas/v1/ManagerNetworkProtocol_v1.xml">
+ <edmx:Include Namespace="ManagerNetworkProtocol"/>
+ <edmx:Include Namespace="ManagerNetworkProtocol.v1_0_2"/>
+ </edmx:Reference>
+ <edmx:Reference Uri="http://redfish.dmtf.org/schemas/v1/Message_v1.xml">
+ <edmx:Include Namespace="Message"/>
+ <edmx:Include Namespace="Message.v1_0_2"/>
+ </edmx:Reference>
+ <edmx:Reference Uri="http://redfish.dmtf.org/schemas/v1/MessageRegistry_v1.xml">
+ <edmx:Include Namespace="MessageRegistry"/>
+ <edmx:Include Namespace="MessageRegistry.v1_0_2"/>
+ </edmx:Reference>
+ <edmx:Reference Uri="http://redfish.dmtf.org/schemas/v1/MessageRegistryCollection_v1.xml">
+ <edmx:Include Namespace="MessageRegistryCollection"/>
+ </edmx:Reference>
+ <edmx:Reference Uri="http://redfish.dmtf.org/schemas/v1/MessageRegistryFile_v1.xml">
+ <edmx:Include Namespace="MessageRegistryFile"/>
+ <edmx:Include Namespace="MessageRegistryFile.v1_0_2"/>
+ </edmx:Reference>
+ <edmx:Reference Uri="http://redfish.dmtf.org/schemas/v1/MessageRegistryFileCollection_v1.xml">
+ <edmx:Include Namespace="MessageRegistryFileCollection"/>
+ </edmx:Reference>
+ <edmx:Reference Uri="http://redfish.dmtf.org/schemas/v1/PhysicalContext_v1.xml">
+ <edmx:Include Namespace="PhysicalContext"/>
+ <edmx:Include Namespace="PhysicalContext.v1_0_2"/>
+ </edmx:Reference>
+ <edmx:Reference Uri="http://redfish.dmtf.org/schemas/v1/Power_v1.xml">
+ <edmx:Include Namespace="Power"/>
+ <edmx:Include Namespace="Power.v1_1_0"/>
+ </edmx:Reference>
+ <edmx:Reference Uri="http://redfish.dmtf.org/schemas/v1/Privileges_v1.xml">
+ <edmx:Include Namespace="Privileges"/>
+ <edmx:Include Namespace="Privileges.v1_0_2"/>
+ </edmx:Reference>
+ <edmx:Reference Uri="http://redfish.dmtf.org/schemas/v1/Session_v1.xml">
+ <edmx:Include Namespace="Session"/>
+ <edmx:Include Namespace="Session.v1_0_2"/>
+ </edmx:Reference>
+ <edmx:Reference Uri="http://redfish.dmtf.org/schemas/v1/SessionCollection_v1.xml">
+ <edmx:Include Namespace="SessionCollection"/>
+ </edmx:Reference>
+ <edmx:Reference Uri="http://redfish.dmtf.org/schemas/v1/SessionService_v1.xml">
+ <edmx:Include Namespace="SessionService"/>
+ <edmx:Include Namespace="SessionService.v1_0_2"/>
+ </edmx:Reference>
+ <edmx:Reference Uri="http://redfish.dmtf.org/schemas/v1/Thermal_v1.xml">
+ <edmx:Include Namespace="Thermal"/>
+ <edmx:Include Namespace="Thermal.v1_1_0"/>
+ </edmx:Reference>
+ <edmx:Reference Uri="http://redfish.dmtf.org/schemas/v1/RedfishExtensions_v1.xml">
+ <edmx:Include Namespace="RedfishExtensions.v1_0_0" Alias="Redfish"/>
+ </edmx:Reference>
+
+ <edmx:DataServices>
+
+ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Service">
+ <EntityContainer Name="Service" Extends="ServiceRoot.v1_0_0.ServiceContainer"/>
+ </Schema>
+
+ </edmx:DataServices>
+</edmx:Edmx>
diff --git a/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/AccountService/Accounts/index.json b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/AccountService/Accounts/index.json
new file mode 100644
index 0000000000..80f0cf34e6
--- /dev/null
+++ b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/AccountService/Accounts/index.json
@@ -0,0 +1,19 @@
+{
+ "@odata.type": "#ManagerAccountCollection.ManagerAccountCollection",
+ "Name": "Accounts Collection",
+ "Members@odata.count": 3,
+ "Members": [
+ {
+ "@odata.id": "/redfish/v1/AccountService/Accounts/root"
+ },
+ {
+ "@odata.id": "/redfish/v1/AccountService/Accounts/jane"
+ },
+ {
+ "@odata.id": "/redfish/v1/AccountService/Accounts/john"
+ }
+ ],
+ "@odata.context": "/redfish/v1/$metadata#ManagerAccountCollection.ManagerAccountCollection",
+ "@odata.id": "/redfish/v1/AccountService/Accounts",
+ "@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."
+}
diff --git a/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/AccountService/Accounts/jane/index.json b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/AccountService/Accounts/jane/index.json
new file mode 100644
index 0000000000..51e2ce59a9
--- /dev/null
+++ b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/AccountService/Accounts/jane/index.json
@@ -0,0 +1,19 @@
+{
+ "@odata.type": "#ManagerAccount.v1_0_2.ManagerAccount",
+ "Id": "jane",
+ "Name": "UserAccount",
+ "Description": "User Account",
+ "Enabled": true,
+ "Password": null,
+ "UserName": "jane",
+ "RoleId": "Operator",
+ "Locked": false,
+ "Links": {
+ "Role": {
+ "@odata.id": "/redfish/v1/AccountService/Roles/Operator"
+ }
+ },
+ "@odata.context": "/redfish/v1/$metadata#ManagerAccount.ManagerAccount",
+ "@odata.id": "/redfish/v1/AccountService/Accounts/jane",
+ "@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."
+}
diff --git a/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/AccountService/Accounts/john/index.json b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/AccountService/Accounts/john/index.json
new file mode 100644
index 0000000000..a8106d6e88
--- /dev/null
+++ b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/AccountService/Accounts/john/index.json
@@ -0,0 +1,19 @@
+{
+ "@odata.type": "#ManagerAccount.v1_0_2.ManagerAccount",
+ "Id": "john",
+ "Name": "UserAccount",
+ "Description": "User Account",
+ "Enabled": true,
+ "Password": null,
+ "UserName": "john",
+ "RoleId": "ReadOnlyUser",
+ "Locked": false,
+ "Links": {
+ "Role": {
+ "@odata.id": "/redfish/v1/AccountService/Roles/ReadOnlyUser"
+ }
+ },
+ "@odata.context": "/redfish/v1/$metadata#ManagerAccount.ManagerAccount",
+ "@odata.id": "/redfish/v1/AccountService/Accounts/john",
+ "@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."
+}
diff --git a/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/AccountService/Accounts/root/index.json b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/AccountService/Accounts/root/index.json
new file mode 100644
index 0000000000..c966e7c771
--- /dev/null
+++ b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/AccountService/Accounts/root/index.json
@@ -0,0 +1,19 @@
+{
+ "@odata.type": "#ManagerAccount.v1_0_2.ManagerAccount",
+ "Id": "root",
+ "Name": "UserAccount",
+ "Description": "User Account",
+ "Enabled": true,
+ "Password": null,
+ "UserName": "root",
+ "RoleId": "Admin",
+ "Locked": false,
+ "Links": {
+ "Role": {
+ "@odata.id": "/redfish/v1/AccountService/Roles/Admin"
+ }
+ },
+ "@odata.context": "/redfish/v1/$metadata#ManagerAccount.ManagerAccount",
+ "@odata.id": "/redfish/v1/AccountService/Accounts/root",
+ "@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."
+}
diff --git a/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/AccountService/Roles/Admin/index.json b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/AccountService/Roles/Admin/index.json
new file mode 100644
index 0000000000..4debc374de
--- /dev/null
+++ b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/AccountService/Roles/Admin/index.json
@@ -0,0 +1,17 @@
+{
+ "@odata.type": "#Role.v1_0_2.Role",
+ "Id": "Admin",
+ "Name": "User Role",
+ "Description": "Admin User Role",
+ "IsPredefined": true,
+ "AssignedPrivileges": [
+ "Login",
+ "ConfigureManager",
+ "ConfigureUsers",
+ "ConfigureSelf",
+ "ConfigureComponents"
+ ],
+ "@odata.context": "/redfish/v1/$metadata#Role.Role",
+ "@odata.id": "/redfish/v1/AccountService/Roles/Admin",
+ "@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."
+}
diff --git a/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/AccountService/Roles/Operator/index.json b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/AccountService/Roles/Operator/index.json
new file mode 100644
index 0000000000..f30e747c16
--- /dev/null
+++ b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/AccountService/Roles/Operator/index.json
@@ -0,0 +1,15 @@
+{
+ "@odata.type": "#Role.v1_0_2.Role",
+ "Id": "Operator",
+ "Name": "User Role",
+ "Description": "Operator User Role",
+ "IsPredefined": true,
+ "AssignedPrivileges": [
+ "Login",
+ "ConfigureSelf",
+ "ConfigureComponents"
+ ],
+ "@odata.context": "/redfish/v1/$metadata#Role.Role",
+ "@odata.id": "/redfish/v1/AccountService/Roles/Operator",
+ "@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."
+}
diff --git a/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/AccountService/Roles/ReadOnlyUser/index.json b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/AccountService/Roles/ReadOnlyUser/index.json
new file mode 100644
index 0000000000..09a8cc3961
--- /dev/null
+++ b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/AccountService/Roles/ReadOnlyUser/index.json
@@ -0,0 +1,13 @@
+{
+ "@odata.type": "#Role.v1_0_2.Role",
+ "Id": "ReadOnlyUser",
+ "Name": "User Role",
+ "Description": "ReadOnlyUser User Role",
+ "IsPredefined": true,
+ "AssignedPrivileges": [
+ "Login"
+ ],
+ "@odata.context": "/redfish/v1/$metadata#Role.Role",
+ "@odata.id": "/redfish/v1/AccountService/Roles/ReadOnlyUser",
+ "@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."
+}
diff --git a/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/AccountService/Roles/index.json b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/AccountService/Roles/index.json
new file mode 100644
index 0000000000..f295d07d1f
--- /dev/null
+++ b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/AccountService/Roles/index.json
@@ -0,0 +1,19 @@
+{
+ "@odata.type": "#RoleCollection.RoleCollection",
+ "Name": "Roles Collection",
+ "Members@odata.count": 3,
+ "Members": [
+ {
+ "@odata.id": "/redfish/v1/AccountService/Roles/Admin"
+ },
+ {
+ "@odata.id": "/redfish/v1/AccountService/Roles/Operator"
+ },
+ {
+ "@odata.id": "/redfish/v1/AccountService/Roles/ReadOnlyUser"
+ }
+ ],
+ "@odata.context": "/redfish/v1/$metadata#RoleCollection.RoleCollection",
+ "@odata.id": "/redfish/v1/AccountService/Roles",
+ "@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."
+}
diff --git a/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/AccountService/index.json b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/AccountService/index.json
new file mode 100644
index 0000000000..f0e3659588
--- /dev/null
+++ b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/AccountService/index.json
@@ -0,0 +1,25 @@
+{
+ "@odata.type": "#AccountService.v1_0_2.AccountService",
+ "Id": "AccountService",
+ "Name": "Account Service",
+ "Description": "Account Service",
+ "Status": {
+ "State": "Enabled",
+ "Health": "OK"
+ },
+ "ServiceEnabled": true,
+ "AuthFailureLoggingThreshold": 3,
+ "MinPasswordLength": 8,
+ "AccountLockoutThreshold": 5,
+ "AccountLockoutDuration": 30,
+ "AccountLockoutCounterResetAfter": 30,
+ "Accounts": {
+ "@odata.id": "/redfish/v1/AccountService/Accounts"
+ },
+ "Roles": {
+ "@odata.id": "/redfish/v1/AccountService/Roles"
+ },
+ "@odata.context": "/redfish/v1/$metadata#AccountService.AccountService",
+ "@odata.id": "/redfish/v1/AccountService",
+ "@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."
+}
diff --git a/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/Chassis/A33/Power/index.json b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/Chassis/A33/Power/index.json
new file mode 100644
index 0000000000..04094bf678
--- /dev/null
+++ b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/Chassis/A33/Power/index.json
@@ -0,0 +1,28 @@
+{
+ "@odata.type": "#Power.v1_1_0.Power",
+ "Id": "Power",
+ "Name": "Power",
+ "PowerControl": [
+ {
+ "@odata.id": "/redfish/v1/Chassis/A33/Power#/PowerControl/0",
+ "MemberId": "0",
+ "Name": "System Power Control",
+ "PowerConsumedWatts": 224,
+ "PowerCapacityWatts": 600,
+ "PowerLimit": {
+ "LimitInWatts": 450,
+ "LimitException": "LogEventOnly",
+ "CorrectionInMs": 1000
+ },
+ "Status": {
+ "State": "Enabled",
+ "Health": "OK"
+ },
+ "Oem": {}
+ }
+ ],
+ "Oem": {},
+ "@odata.context": "/redfish/v1/$metadata#Power.Power",
+ "@odata.id": "/redfish/v1/Chassis/A33/Power",
+ "@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."
+}
diff --git a/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/Chassis/A33/Thermal/index.json b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/Chassis/A33/Thermal/index.json
new file mode 100644
index 0000000000..e7b92a34e1
--- /dev/null
+++ b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/Chassis/A33/Thermal/index.json
@@ -0,0 +1,150 @@
+{
+ "@odata.type": "#Thermal.v1_1_0.Thermal",
+ "Id": "Thermal",
+ "Name": "Thermal",
+ "Temperatures": [
+ {
+ "@odata.id": "/redfish/v1/Chassis/A33/Thermal#/Temperatures/0",
+ "MemberId": "0",
+ "Name": "Inlet Temp",
+ "SensorNumber": 42,
+ "Status": {
+ "State": "Enabled",
+ "Health": "OK"
+ },
+ "ReadingCelsius": 25,
+ "UpperThresholdNonCritical": 35,
+ "UpperThresholdCritical": 40,
+ "UpperThresholdFatal": 50,
+ "MinReadingRangeTemp": 0,
+ "MaxReadingRangeTemp": 200,
+ "PhysicalContext": "Intake"
+ },
+ {
+ "@odata.id": "/redfish/v1/Chassis/A33/Thermal#/Temperatures/1",
+ "MemberId": "1",
+ "Name": "Board Temp",
+ "SensorNumber": 43,
+ "Status": {
+ "State": "Enabled",
+ "Health": "OK"
+ },
+ "ReadingCelsius": 35,
+ "UpperThresholdNonCritical": 30,
+ "UpperThresholdCritical": 40,
+ "UpperThresholdFatal": 50,
+ "MinReadingRangeTemp": 0,
+ "MaxReadingRangeTemp": 200,
+ "PhysicalContext": "SystemBoard"
+ },
+ {
+ "@odata.id": "/redfish/v1/Chassis/A33/Thermal#/Temperatures/2",
+ "MemberId": "2",
+ "Name": "CPU1 Temp",
+ "SensorNumber": 44,
+ "Status": {
+ "State": "Enabled",
+ "Health": "OK"
+ },
+ "ReadingCelsius": 45,
+ "UpperThresholdNonCritical": 60,
+ "UpperThresholdCritical": 82,
+ "MinReadingRangeTemp": 0,
+ "MaxReadingRangeTemp": 200,
+ "PhysicalContext": "CPU"
+ },
+ {
+ "@odata.id": "/redfish/v1/Chassis/A33/Thermal#/Temperatures/3",
+ "MemberId": "3",
+ "Name": "CPU2 Temp",
+ "SensorNumber": 45,
+ "Status": {
+ "State": "Enabled",
+ "Health": "OK"
+ },
+ "ReadingCelsius": 46,
+ "UpperThresholdNonCritical": 60,
+ "UpperThresholdCritical": 82,
+ "MinReadingRangeTemp": 0,
+ "MaxReadingRangeTemp": 200,
+ "PhysicalContext": "CPU"
+ }
+ ],
+ "Fans": [
+ {
+ "@odata.id": "/redfish/v1/Chassis/A33/Thermal#/Fans/0",
+ "MemberId": "0",
+ "Name": "BaseBoard System Fan 1",
+ "PhysicalContext": "Backplane",
+ "Status": {
+ "State": "Enabled",
+ "Health": "OK"
+ },
+ "Reading": 2100,
+ "ReadingUnits": "RPM",
+ "UpperThresholdNonCritical": 42,
+ "UpperThresholdCritical": 4200,
+ "UpperThresholdFatal": 42,
+ "LowerThresholdNonCritical": 42,
+ "LowerThresholdCritical": 5,
+ "LowerThresholdFatal": 42,
+ "MinReadingRange": 0,
+ "MaxReadingRange": 5000,
+ "Redundancy": [
+ {
+ "@odata.id": "/redfish/v1/Chassis/A33/Thermal#/Redundancy/0"
+ }
+ ]
+ },
+ {
+ "@odata.id": "/redfish/v1/Chassis/A33/Thermal#/Fans/1",
+ "MemberId": "1",
+ "Name": "BaseBoard System Fan 2",
+ "PhysicalContext": "Backplane",
+ "Status": {
+ "State": "Enabled",
+ "Health": "OK"
+ },
+ "Reading": 2100,
+ "ReadingUnits": "RPM",
+ "UpperThresholdNonCritical": 42,
+ "UpperThresholdCritical": 4200,
+ "UpperThresholdFatal": 42,
+ "LowerThresholdNonCritical": 42,
+ "LowerThresholdCritical": 5,
+ "LowerThresholdFatal": 42,
+ "MinReadingRange": 0,
+ "MaxReadingRange": 5000,
+ "Redundancy": [
+ {
+ "@odata.id": "/redfish/v1/Chassis/A33/Thermal#/Redundancy/0"
+ }
+ ]
+ }
+ ],
+ "Redundancy": [
+ {
+ "@odata.id": "/redfish/v1/Chassis/A33/Thermal#/Redundancy/0",
+ "MemberId": "0",
+ "Name": "BaseBoard System Fans",
+ "RedundancySet": [
+ {
+ "@odata.id": "/redfish/v1/Chassis/A33/Thermal#/Fans/0"
+ },
+ {
+ "@odata.id": "/redfish/v1/Chassis/A33/Thermal#/Fans/1"
+ }
+ ],
+ "Mode": "N+m",
+ "Status": {
+ "State": "Enabled",
+ "Health": "OK"
+ },
+ "MinNumNeeded": 1,
+ "MaxNumSupported": 2
+ }
+ ],
+ "@odata.context": "/redfish/v1/$metadata#Thermal.Thermal",
+ "@odata.id": "/redfish/v1/Chassis/A33/Thermal",
+ "@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."
+}
diff --git a/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/Chassis/A33/index.json b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/Chassis/A33/index.json
new file mode 100644
index 0000000000..74e2de8d7a
--- /dev/null
+++ b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/Chassis/A33/index.json
@@ -0,0 +1,46 @@
+{
+ "@odata.type": "#Chassis.v1_2_0.Chassis",
+ "Id": "A33",
+ "Name": "Catfish System Chassis",
+ "ChassisType": "RackMount",
+ "Manufacturer": "CatfishManufacturer",
+ "Model": "YellowCat1000",
+ "SerialNumber": "2M220100SL",
+ "SKU": "8675309",
+ "PartNumber": "224071-J23",
+ "AssetTag": "CATFISHASSETTAG",
+ "IndicatorLED": "Lit",
+ "PowerState": "On",
+ "Status": {
+ "State": "Enabled",
+ "Health": "OK"
+ },
+ "Thermal": {
+ "@odata.id": "/redfish/v1/Chassis/A33/Thermal"
+ },
+ "Power": {
+ "@odata.id": "/redfish/v1/Chassis/A33/Power"
+ },
+ "Links": {
+ "ComputerSystems": [
+ {
+ "@odata.id": "/redfish/v1/Systems/2M220100SL"
+ }
+ ],
+ "ManagedBy": [
+ {
+ "@odata.id": "/redfish/v1/Managers/bmc"
+ }
+ ],
+ "ManagersInChassis": [
+ {
+ "@odata.id": "/redfish/v1/Managers/bmc"
+ }
+ ],
+ "Oem": {}
+ },
+ "Oem": {},
+ "@odata.context": "/redfish/v1/$metadata#Chassis.Chassis",
+ "@odata.id": "/redfish/v1/Chassis/A33",
+ "@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."
+}
diff --git a/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/Chassis/index.json b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/Chassis/index.json
new file mode 100644
index 0000000000..fb90ededfd
--- /dev/null
+++ b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/Chassis/index.json
@@ -0,0 +1,13 @@
+{
+ "@odata.type": "#ChassisCollection.ChassisCollection",
+ "Name": "Chassis Collection",
+ "Members@odata.count": 1,
+ "Members": [
+ {
+ "@odata.id": "/redfish/v1/Chassis/A33"
+ }
+ ],
+ "@odata.context": "/redfish/v1/$metadata#ChassisCollection.ChassisCollection",
+ "@odata.id": "/redfish/v1/Chassis",
+ "@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."
+}
diff --git a/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/Managers/bmc/EthernetInterfaces/eth0/index.json b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/Managers/bmc/EthernetInterfaces/eth0/index.json
new file mode 100644
index 0000000000..f3e8528dc4
--- /dev/null
+++ b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/Managers/bmc/EthernetInterfaces/eth0/index.json
@@ -0,0 +1,60 @@
+{
+ "@odata.type": "#EthernetInterface.v1_0_2.EthernetInterface",
+ "Id": "eth0",
+ "Name": "Manager Ethernet Interface",
+ "Description": "Management Network Interface",
+ "Status": {
+ "State": "Enabled",
+ "Health": "OK"
+ },
+ "InterfaceEnabled": true,
+ "PermanentMACAddress": "AA:BB:CC:DD:EE:FF",
+ "MACAddress": "AA:BB:CC:DD:EE:FF",
+ "SpeedMbps": 100,
+ "AutoNeg": true,
+ "FullDuplex": true,
+ "MTUSize": 1500,
+ "HostName": "MyHostName",
+ "FQDN": "MyHostName.MyDomainName.com",
+ "MaxIPv6StaticAddresses": 1,
+ "VLAN": {
+ "VLANEnable": true,
+ "VLANId": 101
+ },
+ "IPv4Addresses": [
+ {
+ "Address": "192.168.0.10",
+ "SubnetMask": "255.255.252.0",
+ "AddressOrigin": "DHCP",
+ "Gateway": "192.168.0.1",
+ "Oem": {}
+ }
+ ],
+ "IPv6AddressPolicyTable": [
+ {
+ "Prefix": "::1/128",
+ "Precedence": 50,
+ "Label": 0
+ }
+ ],
+ "IPv6StaticAddresses": [
+ {
+ "Address": "fe80::1ec1:deff:fe6f:1e24",
+ "PrefixLength": 16
+ }
+ ],
+ "IPv6DefaultGateway": "fe80::1ec1:deff:fe6f:1e24",
+ "IPv6Addresses": [
+ {
+ "Address": "fe80::1ec1:deff:fe6f:1e24",
+ "PrefixLength": 64,
+ "AddressOrigin": "SLAAC",
+ "AddressState": "Preferred",
+ "Oem": {}
+ }
+ ],
+ "Oem": {},
+ "@odata.context": "/redfish/v1/$metadata#EthernetInterface.EthernetInterface",
+ "@odata.id": "/redfish/v1/Managers/bmc/EthernetInterfaces/eth0",
+ "@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."
+}
diff --git a/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/Managers/bmc/EthernetInterfaces/index.json b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/Managers/bmc/EthernetInterfaces/index.json
new file mode 100644
index 0000000000..77b85973e4
--- /dev/null
+++ b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/Managers/bmc/EthernetInterfaces/index.json
@@ -0,0 +1,15 @@
+{
+ "@odata.type": "#EthernetInterfaceCollection.EthernetInterfaceCollection",
+ "Name": "Ethernet Network Interface Collection",
+ "Description": "Collection of EthernetInterfaces for this Manager",
+ "Members@odata.count": 1,
+ "Members": [
+ {
+ "@odata.id": "/redfish/v1/Managers/bmc/EthernetInterfaces/eth0"
+ }
+ ],
+ "Oem": {},
+ "@odata.context": "/redfish/v1/$metadata#EthernetInterfaceCollection.EthernetInterfaceCollection",
+ "@odata.id": "/redfish/v1/Managers/bmc/EthernetInterfaces",
+ "@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."
+}
diff --git a/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/Managers/bmc/NetworkProtocol/index.json b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/Managers/bmc/NetworkProtocol/index.json
new file mode 100644
index 0000000000..192fca543e
--- /dev/null
+++ b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/Managers/bmc/NetworkProtocol/index.json
@@ -0,0 +1,47 @@
+{
+ "@odata.type": "#ManagerNetworkProtocol.v1_0_2.ManagerNetworkProtocol",
+ "Id": "NetworkProtocol",
+ "Name": "Manager Network Protocol",
+ "Description": "Manager Network Service Status",
+ "Status": {
+ "State": "Enabled",
+ "Health": "OK"
+ },
+ "HostName": "myBmcHostname",
+ "FQDN": "mymanager.mydomain.com",
+ "HTTP": {
+ "ProtocolEnabled": true,
+ "Port": 80
+ },
+ "HTTPS": {
+ "ProtocolEnabled": true,
+ "Port": 443
+ },
+ "IPMI": {
+ "ProtocolEnabled": true,
+ "Port": 623
+ },
+ "SSH": {
+ "ProtocolEnabled": true,
+ "Port": 22
+ },
+ "SNMP": {
+ "ProtocolEnabled": true,
+ "Port": 161
+ },
+ "SSDP": {
+ "ProtocolEnabled": true,
+ "Port": 1900,
+ "NotifyMulticastIntervalSeconds": 600,
+ "NotifyTTL": 5,
+ "NotifyIPv6Scope": "Site"
+ },
+ "Telnet": {
+ "ProtocolEnabled": true,
+ "Port": 23
+ },
+ "Oem": {},
+ "@odata.context": "/redfish/v1/$metadata#ManagerNetworkProtocol.ManagerNetworkProtocol",
+ "@odata.id": "/redfish/v1/Managers/bmc/NetworkProtocol",
+ "@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."
+}
diff --git a/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/Managers/bmc/index.json b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/Managers/bmc/index.json
new file mode 100644
index 0000000000..8e270e8b02
--- /dev/null
+++ b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/Managers/bmc/index.json
@@ -0,0 +1,53 @@
+{
+ "@odata.type": "#Manager.v1_1_0.Manager",
+ "Id": "bmc",
+ "Name": "Manager",
+ "ManagerType": "BMC",
+ "Description": "BMC",
+ "ServiceEntryPointUUID": "92384634-2938-2342-8820-489239905423",
+ "UUID": "00000000-0000-0000-0000-000000000000",
+ "Model": "CatfishBMC",
+ "DateTime": "2015-03-13T04:14:33+06:00",
+ "DateTimeLocalOffset": "+06:00",
+ "Status": {
+ "State": "Enabled",
+ "Health": "OK"
+ },
+ "FirmwareVersion": "1.00",
+ "NetworkProtocol": {
+ "@odata.id": "/redfish/v1/Managers/bmc/NetworkProtocol"
+ },
+ "EthernetInterfaces": {
+ "@odata.id": "/redfish/v1/Managers/bmc/EthernetInterfaces"
+ },
+ "Links": {
+ "ManagerForServers": [
+ {
+ "@odata.id": "/redfish/v1/Systems/2M220100SL"
+ }
+ ],
+ "ManagerForChassis": [
+ {
+ "@odata.id": "/redfish/v1/Chassis/A33"
+ }
+ ],
+ "ManagerInChassis": {
+ "@odata.id": "/redfish/v1/Chassis/A33"
+ },
+ "Oem": {}
+ },
+ "Actions": {
+ "#Manager.Reset": {
+ "target": "/redfish/v1/Managers/bmc/Actions/Manager.Reset",
+ "ResetType@Redfish.AllowableValues": [
+ "ForceRestart",
+ "GracefulRestart"
+ ]
+ },
+ "Oem": {}
+ },
+ "Oem": {},
+ "@odata.context": "/redfish/v1/$metadata#Manager.Manager",
+ "@odata.id": "/redfish/v1/Managers/bmc",
+ "@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."
+}
diff --git a/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/Managers/index.json b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/Managers/index.json
new file mode 100644
index 0000000000..8e5f5e0349
--- /dev/null
+++ b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/Managers/index.json
@@ -0,0 +1,13 @@
+{
+ "@odata.type": "#ManagerCollection.ManagerCollection",
+ "Name": "Manager Collection",
+ "Members@odata.count": 1,
+ "Members": [
+ {
+ "@odata.id": "/redfish/v1/Managers/bmc"
+ }
+ ],
+ "@odata.context": "/redfish/v1/$metadata#ManagerCollection.ManagerCollection",
+ "@odata.id": "/redfish/v1/Managers",
+ "@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."
+}
diff --git a/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/SessionService/Sessions/SESSION123456/index.json b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/SessionService/Sessions/SESSION123456/index.json
new file mode 100644
index 0000000000..dce8d48925
--- /dev/null
+++ b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/SessionService/Sessions/SESSION123456/index.json
@@ -0,0 +1,10 @@
+{
+ "@odata.type": "#Session.v1_0_2.Session",
+ "Id": "SESSION123456",
+ "Name": "User Session",
+ "Description": "Manager User Session",
+ "UserName": "root",
+ "Oem": {},
+ "@odata.context": "/redfish/v1/$metadata#Session.Session",
+ "@odata.id": "/redfish/v1/SessionService/Sessions/SESSION123456"
+}
diff --git a/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/SessionService/Sessions/index.json b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/SessionService/Sessions/index.json
new file mode 100644
index 0000000000..d009bf9d19
--- /dev/null
+++ b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/SessionService/Sessions/index.json
@@ -0,0 +1,12 @@
+{
+ "@odata.type": "#SessionCollection.SessionCollection",
+ "Name": "Session Collection",
+ "Members@odata.count": 1,
+ "Members": [
+ {
+ "@odata.id": "/redfish/v1/SessionService/Sessions/SESSION123456"
+ }
+ ],
+ "@odata.context": "/redfish/v1/$metadata#SessionCollection.SessionCollection",
+ "@odata.id": "/redfish/v1/SessionService/Sessions"
+}
diff --git a/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/SessionService/index.json b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/SessionService/index.json
new file mode 100644
index 0000000000..ed1764ebaf
--- /dev/null
+++ b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/SessionService/index.json
@@ -0,0 +1,17 @@
+{
+ "@odata.type": "#SessionService.v1_0_2.SessionService",
+ "Id": "SessionService",
+ "Name": "Session Service",
+ "Description": "Session Service",
+ "Status": {
+ "State": "Enabled",
+ "Health": "OK"
+ },
+ "ServiceEnabled": true,
+ "SessionTimeout": 30,
+ "Sessions": {
+ "@odata.id": "/redfish/v1/SessionService/Sessions"
+ },
+ "@odata.context": "/redfish/v1/$metadata#SessionService.SessionService",
+ "@odata.id": "/redfish/v1/SessionService"
+}
diff --git a/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/Systems/2M220100SL/LogServices/SEL/Entries/1/index.json b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/Systems/2M220100SL/LogServices/SEL/Entries/1/index.json
new file mode 100644
index 0000000000..5156ff13d5
--- /dev/null
+++ b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/Systems/2M220100SL/LogServices/SEL/Entries/1/index.json
@@ -0,0 +1,27 @@
+{
+ "@odata.type": "#LogEntry.v1_0_2.LogEntry",
+ "Id": "1",
+ "Name": "Log Entry 1",
+ "EntryType": "SEL",
+ "OemRecordFormat": "CompanyX",
+ "Severity": "Critical",
+ "Created": "2012-03-07T14:44:00Z",
+ "EntryCode": "Assert",
+ "SensorType": "Temperature",
+ "SensorNumber": 1,
+ "Message": "Message for Event, Description for SEL, OEM depends",
+ "MessageId": "Event.1.0.TempAssert",
+ "MessageArgs": [
+ "ArrayOfMessageArgs"
+ ],
+ "Links": {
+ "OriginOfCondition": {
+ "@odata.id": "/redfish/v1/Chassis/1/Thermal"
+ },
+ "Oem": {}
+ },
+ "Oem": {},
+ "@odata.context": "/redfish/v1/$metadata#LogEntry.LogEntry",
+ "@odata.id": "/redfish/v1/Systems/2M220100SL/LogServices/SEL/Entries/1",
+ "@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."
+}
diff --git a/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/Systems/2M220100SL/LogServices/SEL/Entries/2/index.json b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/Systems/2M220100SL/LogServices/SEL/Entries/2/index.json
new file mode 100644
index 0000000000..308d224055
--- /dev/null
+++ b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/Systems/2M220100SL/LogServices/SEL/Entries/2/index.json
@@ -0,0 +1,27 @@
+{
+ "@odata.type": "#LogEntry.v1_0_2.LogEntry",
+ "Id": "2",
+ "Name": "Log Entry 2",
+ "EntryType": "SEL",
+ "OemRecordFormat": "CompanyX",
+ "Severity": "Critical",
+ "Created": "2012-03-07T14:45:00Z",
+ "EntryCode": "Assert",
+ "SensorType": "Temperature",
+ "SensorNumber": 2,
+ "Message": "Message for Event, Description for SEL, OEM depends",
+ "MessageId": "Event.1.0.TempAssert",
+ "MessageArgs": [
+ "ArrayOfMessageArgs"
+ ],
+ "Links": {
+ "OriginOfCondition": {
+ "@odata.id": "/redfish/v1/Chassis/1/Thermal"
+ },
+ "Oem": {}
+ },
+ "Oem": {},
+ "@odata.context": "/redfish/v1/$metadata#LogEntry.LogEntry",
+ "@odata.id": "/redfish/v1/Systems/2M220100SL/LogServices/SEL/Entries/2",
+ "@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."
+}
diff --git a/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/Systems/2M220100SL/LogServices/SEL/Entries/index.json b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/Systems/2M220100SL/LogServices/SEL/Entries/index.json
new file mode 100644
index 0000000000..2102e5da43
--- /dev/null
+++ b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/Systems/2M220100SL/LogServices/SEL/Entries/index.json
@@ -0,0 +1,62 @@
+{
+ "@odata.type": "#LogEntryCollection.LogEntryCollection",
+ "Name": "Log Service Collection",
+ "Description": "Collection of Logs for this System",
+ "Members@odata.count": 2,
+ "Members": [
+ {
+ "@odata.type": "#LogEntry.v1_0_2.LogEntry",
+ "Id": "1",
+ "Name": "Log Entry 1",
+ "EntryType": "SEL",
+ "OemRecordFormat": "CompanyX",
+ "Severity": "Critical",
+ "Created": "2012-03-07T14:44:00Z",
+ "EntryCode": "Assert",
+ "SensorType": "Temperature",
+ "SensorNumber": 1,
+ "Message": "Message for Event, Description for SEL, OEM depends",
+ "MessageId": "Event.1.0.TempAssert",
+ "MessageArgs": [
+ "ArrayOfMessageArgs"
+ ],
+ "Links": {
+ "OriginOfCondition": {
+ "@odata.id": "/redfish/v1/Chassis/1/Thermal"
+ },
+ "Oem": {}
+ },
+ "Oem": {},
+ "@odata.id": "/redfish/v1/Systems/2M220100SL/LogServices/SEL/Entries/1"
+ },
+ {
+ "@odata.type": "#LogEntry.v1_0_2.LogEntry",
+ "Id": "2",
+ "Name": "Log Entry 2",
+ "EntryType": "SEL",
+ "OemRecordFormat": "CompanyX",
+ "Severity": "Critical",
+ "Created": "2012-03-07T14:45:00Z",
+ "EntryCode": "Assert",
+ "SensorType": "Temperature",
+ "SensorNumber": 2,
+ "Message": "Message for Event, Description for SEL, OEM depends",
+ "MessageId": "Event.1.0.TempAssert",
+ "MessageArgs": [
+ "ArrayOfMessageArgs"
+ ],
+ "Links": {
+ "OriginOfCondition": {
+ "@odata.id": "/redfish/v1/Chassis/1/Thermal"
+ },
+ "Oem": {}
+ },
+ "Oem": {},
+ "@odata.id": "/redfish/v1/Systems/2M220100SL/LogServices/SEL/Entries/2"
+ }
+ ],
+ "@odata.nextLink": "/redfish/v1/Systems/2M220100SL/LogServices/SEL/Entries?$skiptoken=2",
+ "@odata.context": "/redfish/v1/$metadata#LogEntryCollection.LogEntryCollection",
+ "@odata.id": "/redfish/v1/Systems/2M220100SL/LogServices/SEL/Entries",
+ "@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."
+}
diff --git a/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/Systems/2M220100SL/LogServices/SEL/index.json b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/Systems/2M220100SL/LogServices/SEL/index.json
new file mode 100644
index 0000000000..74c748e95e
--- /dev/null
+++ b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/Systems/2M220100SL/LogServices/SEL/index.json
@@ -0,0 +1,27 @@
+{
+ "@odata.type": "#LogService.v1_0_2.LogService",
+ "Id": "SEL",
+ "Name": "System Log Service",
+ "MaxNumberOfRecords": 1000,
+ "OverWritePolicy": "WrapsWhenFull",
+ "DateTime": "2015-03-13T04:14:33+06:00",
+ "DateTimeLocalOffset": "+06:00",
+ "ServiceEnabled": true,
+ "Status": {
+ "State": "Enabled",
+ "Health": "OK"
+ },
+ "Oem": {},
+ "Actions": {
+ "#LogService.ClearLog": {
+ "target": "/redfish/v1/Systems/2M220100SL/LogServices/SEL/Actions/LogService.Reset"
+ },
+ "Oem": {}
+ },
+ "Entries": {
+ "@odata.id": "/redfish/v1/Systems/2M220100SL/LogServices/SEL/Entries"
+ },
+ "@odata.context": "/redfish/v1/$metadata#LogService.LogService",
+ "@odata.id": "/redfish/v1/Systems/2M220100SL/LogServices/SEL",
+ "@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."
+}
diff --git a/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/Systems/2M220100SL/LogServices/index.json b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/Systems/2M220100SL/LogServices/index.json
new file mode 100644
index 0000000000..2dc5bf57c4
--- /dev/null
+++ b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/Systems/2M220100SL/LogServices/index.json
@@ -0,0 +1,15 @@
+{
+ "@odata.type": "#LogServiceCollection.LogServiceCollection",
+ "Name": "Log Service Collection",
+ "Description": "Collection of Logs for this System",
+ "Members@odata.count": 1,
+ "Members": [
+ {
+ "@odata.id": "/redfish/v1/Systems/2M220100SL/LogServices/SEL"
+ }
+ ],
+ "Oem": {},
+ "@odata.context": "/redfish/v1/$metadata#LogServiceCollection.LogServiceCollection",
+ "@odata.id": "/redfish/v1/Systems/2M220100SL/LogServices",
+ "@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."
+}
diff --git a/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/Systems/2M220100SL/index.json b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/Systems/2M220100SL/index.json
new file mode 100644
index 0000000000..814f5f6373
--- /dev/null
+++ b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/Systems/2M220100SL/index.json
@@ -0,0 +1,70 @@
+{
+ "@odata.type": "#ComputerSystem.v1_1_0.ComputerSystem",
+ "Id": "2M220100SL",
+ "Name": "Catfish System",
+ "SystemType": "Physical",
+ "AssetTag": "CATFISHASSETTAG",
+ "Manufacturer": "CatfishManufacturer",
+ "Model": "YellowCat1000",
+ "SerialNumber": "2M220100SL",
+ "SKU": "867530",
+ "PartNumber": "224071-J23",
+ "Description": "Catfish Implementation Recipe of simple scale-out monolithic server",
+ "UUID": "00000000-0000-0000-0000-000000000000",
+ "HostName": "catfishHostname",
+ "PowerState": "On",
+ "BiosVersion": "X00.1.2.3.4(build-23)",
+ "Status": {
+ "State": "Enabled",
+ "Health": "OK"
+ },
+ "IndicatorLED": "Off",
+ "Boot": {
+ "BootSourceOverrideEnabled": "Once",
+ "BootSourceOverrideMode": "UEFI",
+ "UefiTargetBootSourceOverride": "uefiDevicePath",
+ "BootSourceOverrideTarget": "Pxe",
+ "BootSourceOverrideTarget@Redfish.AllowableValues": [
+ "None",
+ "Pxe",
+ "Usb",
+ "Hdd",
+ "BiosSetup",
+ "UefiTarget",
+ "UefiHttp"
+ ]
+ },
+ "LogServices": {
+ "@odata.id": "/redfish/v1/Systems/2M220100SL/LogServices"
+ },
+ "Links": {
+ "Chassis": [
+ {
+ "@odata.id": "/redfish/v1/Chassis/A33"
+ }
+ ],
+ "ManagedBy": [
+ {
+ "@odata.id": "/redfish/v1/Managers/bmc"
+ }
+ ],
+ "Oem": {}
+ },
+ "Actions": {
+ "#ComputerSystem.Reset": {
+ "target": "/redfish/v1/Systems/2M220100SL/Actions/ComputerSystem.Reset",
+ "ResetType@Redfish.AllowableValues": [
+ "On",
+ "ForceOff",
+ "GracefulShutdown",
+ "ForceRestart",
+ "Nmi",
+ "GracefulRestart",
+ "ForceOn"
+ ]
+ }
+ },
+ "@odata.context": "/redfish/v1/$metadata#ComputerSystem.ComputerSystem",
+ "@odata.id": "/redfish/v1/Systems/2M220100SL",
+ "@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."
+}
diff --git a/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/Systems/index.json b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/Systems/index.json
new file mode 100644
index 0000000000..091849e1a6
--- /dev/null
+++ b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/Systems/index.json
@@ -0,0 +1,13 @@
+{
+ "@odata.type": "#ComputerSystemCollection.ComputerSystemCollection",
+ "Name": "Computer System Collection",
+ "Members@odata.count": 1,
+ "Members": [
+ {
+ "@odata.id": "/redfish/v1/Systems/2M220100SL"
+ }
+ ],
+ "@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."
+}
diff --git a/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/index.json b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/index.json
new file mode 100644
index 0000000000..89312bcec1
--- /dev/null
+++ b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/index.json
@@ -0,0 +1,31 @@
+{
+ "@odata.type": "#ServiceRoot.v1_0_2.ServiceRoot",
+ "Id": "RootService",
+ "Name": "Root Service",
+ "RedfishVersion": "1.0.2",
+ "UUID": "92384634-2938-2342-8820-489239905423",
+ "Systems": {
+ "@odata.id": "/redfish/v1/Systems"
+ },
+ "Chassis": {
+ "@odata.id": "/redfish/v1/Chassis"
+ },
+ "Managers": {
+ "@odata.id": "/redfish/v1/Managers"
+ },
+ "SessionService": {
+ "@odata.id": "/redfish/v1/SessionService"
+ },
+ "AccountService": {
+ "@odata.id": "/redfish/v1/AccountService"
+ },
+ "Links": {
+ "Sessions": {
+ "@odata.id": "/redfish/v1/SessionService/Sessions"
+ }
+ },
+ "Oem": {},
+ "@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."
+}
diff --git a/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/odata/index.json b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/odata/index.json
new file mode 100644
index 0000000000..ef253a35cb
--- /dev/null
+++ b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/MockupData/SimpleOcpServerV1/redfish/v1/odata/index.json
@@ -0,0 +1,56 @@
+{
+ "value": [
+ {
+ "name": "Service",
+ "kind": "Singleton",
+ "url": "/redfish/v1/"
+ },
+ {
+ "name": "Systems",
+ "kind": "Singleton",
+ "url": "/redfish/v1/Systems"
+ },
+ {
+ "name": "Chassis",
+ "kind": "Singleton",
+ "url": "/redfish/v1/Chassis"
+ },
+ {
+ "name": "Managers",
+ "kind": "Singleton",
+ "url": "/redfish/v1/Managers"
+ },
+ {
+ "name": "AccountService",
+ "kind": "Singleton",
+ "url": "/redfish/v1/AccountService"
+ },
+ {
+ "name": "SessionService",
+ "kind": "Singleton",
+ "url": "/redfish/v1/SessionService"
+ },
+ {
+ "name": "EventService",
+ "kind": "Singleton",
+ "url": "/redfish/v1/EventService"
+ },
+ {
+ "name": "JsonSchemas",
+ "kind": "Singleton",
+ "url": "/redfish/v1/JsonSchemas"
+ },
+ {
+ "name": "Registries",
+ "kind": "Singleton",
+ "url": "/redfish/v1/Registries"
+ },
+ {
+ "name": "Sessions",
+ "kind": "Singleton",
+ "url": "/redfish/v1/SessionService/Sessions"
+ }
+ ],
+ "@odata.context": "/redfish/v1/$metadata",
+ "@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."
+}
diff --git a/RedfishClientPkg/Tools/Redfish-Profile-Simulator/redfishProfileSimulator.py b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/redfishProfileSimulator.py
new file mode 100644
index 0000000000..24be52bafc
--- /dev/null
+++ b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/redfishProfileSimulator.py
@@ -0,0 +1,125 @@
+# Copyright Notice:
+# Copyright 2016 Distributed Management Task Force, Inc. All rights reserved.
+# License: BSD 3-Clause License. For full text see link: https://github.com/DMTF/Redfish-Profile-Simulator/blob/master/LICENSE.md
+
+# This program is dependent on the following Python packages that should be installed separately with pip:
+# pip install Flask
+#
+# standard python packages
+import sys
+import getopt
+import os
+
+rfVersion = "0.9.6"
+rfProgram1 = "redfishProfileSimulator"
+rfProgram2 = " "
+rfUsage1 = "[-Vh] [--Version][--help]"
+rfUsage2 = "[-H<hostIP>] [-P<port>] [-p<profile_path>]"
+rfUsage3 = "[--Host=<hostIP>] [--Port=<port>] [--profile_path=<profile_path>]"
+
+
+def rf_usage():
+ print("Usage:")
+ print(" ", rfProgram1, " ", rfUsage1)
+ print(" ", rfProgram1, " ", rfUsage2)
+ print(" ", rfProgram2, " ", rfUsage3)
+
+
+def rf_help():
+ print(rfProgram1,"implements a simulation of a redfish service for the \"Simple OCP Server V1\" Mockup.")
+ print(" The simulation includes an http server, RestEngine, and dynamic Redfish datamodel.")
+ print(" You can GET, PATHCH,... to the service just like a real Redfish service.")
+ print(" Both Basic and Redfish Session/Token authentication is supported (for a single user/passwd and token")
+ print(" the user/passwd is: root/password123456. The authToken is: 123456SESSIONauthcode")
+ print(" these can be changed by editing the redfishURIs.py file. will make dynamic later.")
+ print(" The http service and Rest engine is built on Flask, and all code is Python 3.4+")
+ print(" The data model resources are \"initialized\" from the SPMF \"SimpleOcpServerV1\" Mockup.")
+ print(" and stored as python dictionaries--then the dictionaries are updated with patches, posts, deletes.")
+ print(" The program can be extended to support other mockup \"profiles\".")
+ print("")
+ print(" By default, the simulation runs on localhost (127.0.0.1), on port 5000.")
+ print(" These can be changed with CLI options: -P<port> -H <hostIP> | --port=<port> --host=<hostIp>")
+ print("")
+ print("Version: ", rfVersion)
+ rf_usage()
+ print("")
+ print(" -V, --Version, --- the program version")
+ print(" -h, --help, --- help")
+ print(" -H<hostIP>, --Host=<hostIp> --- host IP address. dflt=127.0.0.1")
+ print(" -P<port>, --Port=<port> --- the port to use. dflt=5000")
+ print(" -p<profile_path>, --profile=<profile_path> --- the path to the Redfish profile to use. "
+ "dflt=\"./MockupData/SimpleOcpServerV1\" ")
+
+
+def main(argv):
+ # set default option args
+ rf_profile_path = os.path.abspath("./MockupData/SimpleOcpServerV1")
+ rf_host = "127.0.0.1"
+ rf_port = 5000
+
+ try:
+ opts, args = getopt.getopt(argv[1:], "VhH:P:p:",
+ ["Version", "help", "Host=", "Port=", "profile="])
+ except getopt.GetoptError:
+ print(rfProgram1, ": Error parsing options")
+ rf_usage()
+ sys.exit(2)
+ for opt, arg in opts:
+ if opt in ("-h", "--help"):
+ rf_help()
+ sys.exit(0)
+ elif opt in ("-V", "--Version"):
+ print("Version:", rfVersion)
+ sys.exit(0)
+ elif opt in ("-p", "--profile"):
+ rf_profile_path = arg
+ elif opt in "--Host=":
+ rf_host = arg
+ elif opt in "--Port=":
+ rf_port=int(arg)
+ else:
+ print(" ", rfProgram1, ": Error: unsupported option")
+ rf_usage()
+ sys.exit(2)
+
+ print("{} Version: {}".format(rfProgram1,rfVersion))
+ print(" Starting redfishProfileSimulator at: hostIP={}, port={}".format(rf_host, rf_port))
+ print(" Using Profile at {}".format(rf_profile_path))
+
+ if os.path.isdir(rf_profile_path):
+ # import the classes and code we run from main.
+ from v1sim.serviceVersions import RfServiceVersions
+ from v1sim.serviceRoot import RfServiceRoot
+ # rfApi_SimpleServer is a function in ./RedfishProfileSim/redfishURIs.py.
+ # It loads the flask APIs (URIs), and starts the flask service
+ from v1sim.redfishURIs import rfApi_SimpleServer
+
+ # create the root service resource
+ root_path = os.path.normpath("redfish/v1")
+
+ # create the version resource for GET /redfish
+ versions = RfServiceVersions(rf_profile_path, "redfish")
+ root = RfServiceRoot(rf_profile_path, root_path)
+
+ # start the flask REST API service
+ rfApi_SimpleServer(root, versions, host=rf_host, port=rf_port)
+ else:
+ print("invalid profile path")
+
+
+if __name__ == "__main__":
+ main(sys.argv)
+
+
+
+
+ #http://127.0.0.1:5000/
+
+ #app.run(host="0.0.0.0") # run on all IPs
+ #run(host=None, port=None, debug=None, **options)
+ # host=0.0.0.0 server avail externally -- all IPs
+ # host=127.0.0.1 is default
+ # port=5000 default, or port defined in SERVER_NAME config var
+
+
+
diff --git a/RedfishClientPkg/Tools/Redfish-Profile-Simulator/v1sim/__init__.py b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/v1sim/__init__.py
new file mode 100644
index 0000000000..72007ff42a
--- /dev/null
+++ b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/v1sim/__init__.py
@@ -0,0 +1,4 @@
+# Copyright Notice:
+# Copyright 2016 Distributed Management Task Force, Inc. All rights reserved.
+# License: BSD 3-Clause License. For full text see link: https://github.com/DMTF/Redfish-Profile-Simulator/blob/master/LICENSE.md
+
diff --git a/RedfishClientPkg/Tools/Redfish-Profile-Simulator/v1sim/accountService.py b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/v1sim/accountService.py
new file mode 100644
index 0000000000..1c056f0b86
--- /dev/null
+++ b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/v1sim/accountService.py
@@ -0,0 +1,76 @@
+# Copyright Notice:
+# Copyright 2016 Distributed Management Task Force, Inc. All rights reserved.
+# License: BSD 3-Clause License. For full text see link: https://github.com/DMTF/Redfish-Profile-Simulator/blob/master/LICENSE.md
+
+import os
+
+from .resource import RfResource, RfCollection
+
+
+class RfAccountServiceObj(RfResource):
+ # create instance of each AccountService
+ def create_sub_objects(self, base_path, rel_path):
+ if os.path.isdir(os.path.join(base_path, os.path.normpath("redfish/v1/AccountService/Accounts"))):
+ self.components["Accounts"] = RfAccountCollection(base_path,
+ os.path.normpath("redfish/v1/AccountService/Accounts"),
+ parent=self)
+
+ if os.path.isdir(os.path.join(base_path, os.path.normpath("redfish/v1/AccountService/Roles"))):
+ self.components["Roles"] = RfRoleCollection(base_path,
+ os.path.normpath("redfish/v1/AccountService/Roles"),
+ parent=self)
+
+ def patch_resource(self, patch_data):
+ # first verify client didn't send us a property we cant patch
+ patachables = ("MinPasswordLength", "AccountLockoutThreshold",
+ "AccountLockoutDuration", "AccountLockoutCounterResetAfter")
+
+ for key in patch_data.keys():
+ if key not in patachables:
+ return 4, 400, "Invalid Patch Property Sent", ""
+
+ # now patch the valid properties sent
+ for key in patch_data.keys():
+ new_val = patch_data[key]
+ print("new_val:{}".format(new_val))
+ try:
+ num_val = round(new_val)
+ except ValueError:
+ return 4, 400, "invalid value", ""
+ else:
+ patch_data[key] = num_val
+
+ # if here, we know all the patch data is valid properties and properties
+ new_duration = self.res_data["AccountLockoutDuration"]
+ new_reset_after = self.res_data["AccountLockoutCounterResetAfter"]
+ if "AccountLockoutDuration" in patch_data:
+ new_duration = patch_data["AccountLockoutDuration"]
+ if "AccountLockoutCounterResetAfter" in patch_data:
+ new_reset_after = patch_data["AccountLockoutCounterResetAfter"]
+ if new_duration < new_reset_after:
+ return 4, 400, "invalid value", ""
+
+ # if here, all values are good. set them
+ for key in patch_data.keys():
+ self.res_data[key] = patch_data[key]
+ return 0, 204, None, None
+
+
+class RfAccountCollection(RfCollection):
+ def element_type(self):
+ return RfAccountObj
+
+
+# Service Collection Entries
+class RfAccountObj(RfResource):
+ pass
+
+
+class RfRoleCollection(RfCollection):
+ def element_type(self):
+ return RfRoleObj
+
+
+# Service Collection Entries
+class RfRoleObj(RfResource):
+ pass
diff --git a/RedfishClientPkg/Tools/Redfish-Profile-Simulator/v1sim/chassis.py b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/v1sim/chassis.py
new file mode 100644
index 0000000000..88e5a000f3
--- /dev/null
+++ b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/v1sim/chassis.py
@@ -0,0 +1,115 @@
+# Copyright Notice:
+# Copyright 2016 Distributed Management Task Force, Inc. All rights reserved.
+# License: BSD 3-Clause License. For full text see link: https://github.com/DMTF/Redfish-Profile-Simulator/blob/master/LICENSE.md
+
+import os
+
+from .resource import RfResource, RfCollection
+
+
+class RfChassisCollection(RfCollection):
+ def element_type(self):
+ return RfChassisObj
+
+
+class RfChassisObj(RfResource):
+ # create the dependent sub-objects that live under the chassis object
+ def create_sub_objects(self, base_path, rel_path):
+ resource_path = os.path.join(base_path, rel_path);
+ contents = os.listdir(resource_path)
+ for item in contents:
+ if item == "Thermal":
+ self.components[item] = RfChassisThermal(base_path, os.path.join(rel_path, item), parent=self)
+ elif item == "Power":
+ self.components[item] = RfChassisPower(base_path, os.path.join(rel_path, item), parent=self)
+
+ def patch_resource(self, patch_data):
+ # first verify client didn't send us a property we cant patch
+ for key in patch_data.keys():
+ if key != "AssetTag" and key != "IndicatorLED":
+ return 4, 400, "Invalid Patch Property Sent", ""
+ # now patch the valid properties sent
+ if "AssetTag" in patch_data:
+ self.res_data['AssetTag'] = patch_data['AssetTag']
+ if "IndicatorLED" in patch_data:
+ self.res_data['IndicatorLED'] = patch_data['IndicatorLED']
+ return 0, 204, None, None
+
+ def reset_resource(self, reset_data):
+ if "ResetType" in reset_data:
+ # print("RESETDATA: {}".format(resetData))
+ value = reset_data['ResetType']
+ valid_values = self.res_data["Actions"]["#Chassis.Reset"]["ResetType@Redfish.AllowableValues"]
+ if value in valid_values:
+ # it is a supoported reset action modify other properties appropritely
+ if value == "On":
+ self.res_data["PowerState"] = "On"
+ print("PROFILE_SIM--SERVER WAS RESET. power now ON")
+ elif value == "ForceOff":
+ self.res_data["PowerState"] = "Off"
+ print("PROFILE_SIM--SERVER WAS RESET. Power now Off")
+ return 0, 204, "Chassis Reset", ""
+ else:
+ return 4, 400, "Invalid reset value: ResetType", ""
+ else: # invalid request
+ return 4, 400, "Invalid request property", ""
+
+
+# subclass Thermal Metrics
+class RfChassisThermal(RfResource):
+ pass
+
+
+# subclass Power Metrics
+class RfChassisPower(RfResource):
+ def create_sub_objects(self, base_path, rel_path):
+ resource_path = os.path.join(base_path, rel_path);
+ contents = os.listdir(resource_path)
+ for item in contents:
+ if item == "FastPowerMeter":
+ self.components[item] = RfFastPowerMeter(base_path, os.path.join(rel_path, item), parent=self)
+ elif item == "FederatedGroupCapping":
+ self.components[item] = RfFederatedGroupCapping(base_path, os.path.join(rel_path, item), parent=self)
+ elif item == "PowerMeter":
+ self.components[item] = RfPowerMeter(base_path, os.path.join(rel_path, item), parent=self)
+
+ def patch_resource(self, patchData):
+ # first verify client didn't send us a property we cant patch
+ for key in patchData.keys():
+ if key != "PowerControl":
+ return 4, 400, "Invalid Patch Property Sent", ""
+ else: # Powercontrol:
+ for prop2 in patchData["PowerControl"][0].keys():
+ if prop2 != "PowerLimit":
+ return 4, 400, "Invalid Patch Property Sent", ""
+ else: # PowerLimit
+ for prop3 in patchData["PowerControl"][0]["PowerLimit"].keys():
+ if prop3 != "LimitInWatts" and prop3 != "LimitException" and prop3 != "CorrectionInMs":
+ return 4, 400, "Invalid Patch Property Sent", ""
+ # now patch the valid properties sent
+ if "PowerControl" in patchData:
+ if "PowerLimit" in patchData["PowerControl"][0]:
+ patch_power_limit_dict = patchData["PowerControl"][0]["PowerLimit"]
+ catfish_power_limit_dict = self.res_data["PowerControl"][0]["PowerLimit"]
+ if "LimitInWatts" in patch_power_limit_dict:
+ self.res_data["PowerControl"][0]["PowerLimit"]["LimitInWatts"] = \
+ patch_power_limit_dict['LimitInWatts']
+ if "LimitException" in patch_power_limit_dict:
+ self.res_data["PowerControl"][0]["PowerLimit"]['LimitException'] = \
+ patch_power_limit_dict['LimitException']
+ if "CorrectionInMs" in patch_power_limit_dict:
+ self.res_data["PowerControl"][0]["PowerLimit"]['CorrectionInMs'] = \
+ patch_power_limit_dict['CorrectionInMs']
+ return 0, 204, None, None
+
+
+class RfFastPowerMeter(RfResource):
+ pass
+
+
+class RfFederatedGroupCapping(RfResource):
+ pass
+
+
+class RfPowerMeter(RfResource):
+ pass
diff --git a/RedfishClientPkg/Tools/Redfish-Profile-Simulator/v1sim/common_services.py b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/v1sim/common_services.py
new file mode 100644
index 0000000000..b1a5082d45
--- /dev/null
+++ b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/v1sim/common_services.py
@@ -0,0 +1,28 @@
+import os
+
+from .resource import RfCollection, RfResource
+
+
+class RfLogServiceCollection(RfCollection):
+ def element_type(self):
+ return RfLogService
+
+
+class RfLogService(RfResource):
+ def create_sub_objects(self, base_path, rel_path):
+ resource_path = os.path.join(base_path, rel_path);
+ contents = os.listdir(resource_path)
+ for item in contents:
+ if item == "Entries":
+ self.components[item] = RfLogEntriesCollection(base_path,
+ os.path.join(rel_path, item),
+ parent=self)
+
+
+class RfLogEntriesCollection(RfCollection):
+ def element_type(self):
+ return RfLogEntry
+
+
+class RfLogEntry(RfResource):
+ pass
diff --git a/RedfishClientPkg/Tools/Redfish-Profile-Simulator/v1sim/flask_redfish_auth.py b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/v1sim/flask_redfish_auth.py
new file mode 100644
index 0000000000..61a5fd97e9
--- /dev/null
+++ b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/v1sim/flask_redfish_auth.py
@@ -0,0 +1,278 @@
+# Copyright Notice:
+# Copyright 2016 Distributed Management Task Force, Inc. All rights reserved.
+# License: BSD 3-Clause License. For full text see link: https://github.com/DMTF/Redfish-Profile-Simulator/blob/master/LICENSE.md
+
+"""
+flask_redfish_auth
+
+adapted from:
+ flask_httpauth
+ ==================
+ This module provides Basic and Digest HTTP authentication for Flask routes.
+ :copyright: (C) 2014 by Miguel Grinberg.
+ :license: MIT, see LICENSE for more details,
+ at https://github.com/miguelgrinberg/Flask-HTTPAuth/blob/master/LICENSE
+
+ see documentation at: http://flask.pocoo.org/snippets/8/
+ code and docs at: https://github.com/miguelgrinberg/flask-httpauth/
+
+**** modified to implement EITHER Redfish Token Auth or Basic Auth
+ this file is imported by: catfishURIs.py
+
+ Usage: In RedfishProfileSimulator: see this flow below in redfishURIs.py
+ ... in redfishURIs.py
+ from .flask_redfish_auth import RfHTTPBasicOrTokenAuth
+ ...
+ #create instance of the modified Basic or Redfish Token auth
+ # this is what is in this file
+ auth=RfHTTPBasicOrTokenAuth
+
+ #define basic auth decorator used by flask
+ @auth.verify_basic_password
+ def verifyRfPasswd(user,passwd):
+ ...
+
+ #define Redfish Token/Session auth decorator used by flask
+ @auth.verify_token
+ def verifyRfToken(auth_token):
+ ..
+
+ @app.route("/api", methods=['GET'])
+ @auth.rfAuthRequired
+ def api()
+ ...
+"""
+
+from functools import wraps
+
+from flask import request, make_response
+
+
+# this is the Base HTTP Auth class that is used to derive the Redfish "Basic or Token Auth" class
+class HTTPAuth(object):
+ def __init__(self, scheme=None, realm=None):
+ def default_get_password(userx):
+ return None
+
+ def default_basic_auth_error():
+ return "Unauthorized Access"
+
+ def default_token_auth_error():
+ return "Unauthorized Access. Invalid authentication token"
+
+ self.scheme = scheme
+ self.realm = realm or "Authentication Required"
+ self.get_password(default_get_password)
+ self.basic_error_handler(default_basic_auth_error)
+ self.token_error_handler(default_token_auth_error)
+
+ def get_password(self, f):
+ self.get_password_callback = f
+ return f
+
+ def token_error_handler(self, f):
+ @wraps(f)
+ def decorated(*args, **kwargs):
+ res = f(*args, **kwargs)
+ if type(res) == str:
+ res = make_response(res)
+ res.status_code = 401
+ return res
+
+ self.auth_token_error_callback = decorated
+ return decorated
+
+ def basic_error_handler(self, f):
+ @wraps(f)
+ def decorated(*args, **kwargs):
+ res = f(*args, **kwargs)
+ if type(res) == str:
+ res = make_response(res)
+ res.status_code = 401
+ if 'WWW-Authenticate' not in res.headers.keys():
+ res.headers['WWW-Authenticate'] = self.authenticate_header()
+ return res
+
+ self.auth_basic_error_callback = decorated
+ return decorated
+
+ # for redfish, we need to hook this to check if its token auth before trying basic auth
+ def rfAuthRequired(self, f):
+ @wraps(f)
+ def decorated(*args, **kwargs):
+ auth = request.authorization
+ print("in rfAuthRequired")
+ print("headers: {}".format(request.headers))
+ # We need to ignore authentication headers for OPTIONS to avoid
+ # unwanted interactions with CORS.
+ # Chrome and Firefox issue a preflight OPTIONS request to check
+ # Access-Control-* headers, and will fail if it returns 401.
+ if request.method != 'OPTIONS':
+ # auth is None if the Basic auth header didn't come in the request
+ found_token = False
+ if (auth is None):
+ ###print("auth is None")
+ # check if we have a redfish auth token
+ hdr_token_key = "X-Auth-Token"
+ auth_token = request.headers.get(hdr_token_key)
+ ###print("token={}".format(auth_token))
+ if (auth_token is not None):
+ found_token = True
+ # yeah! we have an auth token in the headers
+ authOk = self.verify_token_callback(auth_token)
+ ###print("verify_token={}".format(authOk))
+ if (authOk is not True):
+ # we had an auth token, but it didn't validate
+ return (self.auth_token_error_callback())
+
+ # now continue with normal Basic Auth validation
+ if (found_token is not True):
+ ###print("try basic")
+ if auth:
+ password = self.get_password_callback(auth.username)
+ else:
+ password = None
+ ###print("basic auth: auth={}, pwd={}".format(auth,password))
+ if (not self.authenticate(auth, password)):
+ return (self.auth_basic_error_callback())
+ ###print("now execute the function")
+ return (f(*args, **kwargs))
+
+ return (decorated)
+
+ def username(self):
+ if not request.authorization:
+ return ""
+ return request.authorization.username
+
+
+# this class is derived from HTTPAuth above
+class RfHTTPBasicOrTokenAuth(HTTPAuth):
+ def __init__(self, scheme=None, realm=None):
+ super(RfHTTPBasicOrTokenAuth, self).__init__(scheme, realm)
+ self.hash_password(None)
+ self.verify_basic_password(None)
+ self.verify_token(None)
+
+ def hash_password(self, f):
+ self.hash_password_callback = f
+ return f
+
+ def verify_basic_password(self, f):
+ self.verify_password_callback = f
+ return f
+
+ def verify_token(self, f):
+ self.verify_token_callback = f
+ return f
+
+ def authenticate_header(self):
+ return '{0} realm="{1}"'.format(self.scheme or 'Basic', self.realm)
+
+ def authenticate(self, auth, stored_password):
+ if auth:
+ username = auth.username
+ client_password = auth.password
+ else:
+ username = ""
+ client_password = ""
+ if self.verify_password_callback:
+ return self.verify_password_callback(username, client_password)
+ if not auth:
+ return False
+ if self.hash_password_callback:
+ try:
+ client_password = self.hash_password_callback(client_password)
+ except TypeError:
+ client_password = self.hash_password_callback(username,
+ client_password)
+ return client_password == stored_password
+
+
+'''
+class HTTPDigestAuth(HTTPAuth):
+ def __init__(self, scheme=None, realm=None, use_ha1_pw=False):
+ super(HTTPDigestAuth, self).__init__(scheme, realm)
+ self.use_ha1_pw = use_ha1_pw
+ self.random = SystemRandom()
+ try:
+ self.random.random()
+ except NotImplementedError:
+ self.random = Random()
+
+ def _generate_random():
+ return md5(str(self.random.random()).encode('utf-8')).hexdigest()
+
+ def default_generate_nonce():
+ session["auth_nonce"] = _generate_random()
+ return session["auth_nonce"]
+
+ def default_verify_nonce(nonce):
+ return nonce == session.get("auth_nonce")
+
+ def default_generate_opaque():
+ session["auth_opaque"] = _generate_random()
+ return session["auth_opaque"]
+
+ def default_verify_opaque(opaque):
+ return opaque == session.get("auth_opaque")
+
+ self.generate_nonce(default_generate_nonce)
+ self.generate_opaque(default_generate_opaque)
+ self.verify_nonce(default_verify_nonce)
+ self.verify_opaque(default_verify_opaque)
+
+ def generate_nonce(self, f):
+ self.generate_nonce_callback = f
+ return f
+
+ def verify_nonce(self, f):
+ self.verify_nonce_callback = f
+ return f
+
+ def generate_opaque(self, f):
+ self.generate_opaque_callback = f
+ return f
+
+ def verify_opaque(self, f):
+ self.verify_opaque_callback = f
+ return f
+
+ def get_nonce(self):
+ return self.generate_nonce_callback()
+
+ def get_opaque(self):
+ return self.generate_opaque_callback()
+
+ def generate_ha1(self, username, password):
+ a1 = username + ":" + self.realm + ":" + password
+ a1 = a1.encode('utf-8')
+ return md5(a1).hexdigest()
+
+ def authenticate_header(self):
+ session["auth_nonce"] = self.get_nonce()
+ session["auth_opaque"] = self.get_opaque()
+ return '{0} realm="{1}",nonce="{49}",opaque="{3}"'.format(
+ self.scheme or 'Digest', self.realm, session["auth_nonce"],
+ session["auth_opaque"])
+
+ def authenticate(self, auth, stored_password_or_ha1):
+ if not auth or not auth.username or not auth.realm or not auth.uri \
+ or not auth.nonce or not auth.response \
+ or not stored_password_or_ha1:
+ return False
+ if not(self.verify_nonce_callback(auth.nonce)) or \
+ not(self.verify_opaque_callback(auth.opaque)):
+ return False
+ if self.use_ha1_pw:
+ ha1 = stored_password_or_ha1
+ else:
+ a1 = auth.username + ":" + auth.realm + ":" + \
+ stored_password_or_ha1
+ ha1 = md5(a1.encode('utf-8')).hexdigest()
+ a2 = request.method + ":" + auth.uri
+ ha2 = md5(a2.encode('utf-8')).hexdigest()
+ a3 = ha1 + ":" + auth.nonce + ":" + ha2
+ response = md5(a3.encode('utf-8')).hexdigest()
+ return response == auth.response
+'''
diff --git a/RedfishClientPkg/Tools/Redfish-Profile-Simulator/v1sim/managers.py b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/v1sim/managers.py
new file mode 100644
index 0000000000..e09ae3d500
--- /dev/null
+++ b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/v1sim/managers.py
@@ -0,0 +1,211 @@
+# Copyright Notice:
+# Copyright 2016 Distributed Management Task Force, Inc. All rights reserved.
+# License: BSD 3-Clause License. For full text see link: https://github.com/DMTF/Redfish-Profile-Simulator/blob/master/LICENSE.md
+
+import os
+
+from .common_services import RfLogServiceCollection
+from .network import RfNetworkService
+from .resource import RfResource, RfCollection
+from .security import RfSecurityService
+
+
+class RfManagersCollection(RfCollection):
+ def element_type(self):
+ return RfManagerObj
+
+
+class RfManagerObj(RfResource):
+ """
+ create the dependent sub-objects that live under the Manager object
+ """
+
+ def create_sub_objects(self, base_path, rel_path):
+ resource_path = os.path.join(base_path, rel_path);
+ contents = os.listdir(resource_path)
+ for item in contents:
+ if item == "EthernetInterfaces":
+ self.components[item] = RfManagerEthernetColl(base_path, os.path.join(rel_path, item), parent=self)
+ elif item == "NetworkProtocol":
+ self.components[item] = RfManagerNetworkProtocol(base_path, os.path.join(rel_path, item), parent=self)
+ elif item == "SerialInterfaces":
+ self.components[item] = RfSerialInterfaceCollection(base_path, os.path.join(rel_path, item),
+ parent=self)
+ elif item == "VirutalMedia":
+ self.components[item] = RfVirtualMediaCollection(base_path, os.path.join(rel_path, item), parent=self)
+ elif item == "NICs":
+ self.components[item] = RfNics(base_path, os.path.join(rel_path, item), parent=self)
+ elif item == "LogServices":
+ self.components[item] = RfLogServiceCollection(base_path, os.path.join(rel_path, item), parent=self)
+ elif item == "ActiveHealthSystem":
+ self.components[item] = RfActiveHealthSystem(base_path, os.path.join(rel_path, item), parent=self)
+ elif item == "DateTime":
+ self.components[item] = RfDateTime(base_path, os.path.join(rel_path, item), parent=self)
+ elif item == "EmbeddedMedia":
+ self.components[item] = RfEmbeddedMedia(base_path, os.path.join(rel_path, item), parent=self)
+ elif item == "FederationGroups":
+ self.components[item] = RfFederationGroupCollection(base_path, os.path.join(rel_path, item),
+ parent=self)
+ elif item == "FederationPeers":
+ self.components[item] = RfFederationPeerCollection(base_path, os.path.join(rel_path, item), parent=self)
+ elif item == "LicenseService":
+ self.components[item] = RfLicenseServiceCollection(base_path, os.path.join(rel_path, item), parent=self)
+ elif item == "SecurityService":
+ self.components[item] = RfSecurityService(base_path, os.path.join(rel_path, item), parent=self)
+ elif item == "UpdateService":
+ self.components[item] = RfManagerUpdateService(base_path, os.path.join(rel_path, item), parent=self)
+ elif item == "NetworkService":
+ self.components[item] = RfNetworkService(base_path, os.path.join(rel_path, item), parent=self)
+
+ def patch_resource(self, patch_data):
+ # first verify client didn't send us a property we cant patch
+ for key in patch_data.keys():
+ if key != "DateTime" and key != "DateTimeLocalOffset":
+ return 4, 400, "Invalid Patch Property Sent", ""
+
+ date_time = None
+ date_time_offset = None
+ local_offset = None
+
+ # now patch the valid properties sent
+ if "DateTime" in patch_data:
+ date_time = patch_data['DateTime']
+ date_time_offset = date_time[-6:] # get last 6 chars ....+00:00 or -00:00
+ if "DateTimeLocalOffset" in patch_data:
+ local_offset = patch_data['DateTimeLocalOffset']
+
+ # verify that if both DateTime and DateTimeLocalOffset were sent, thant
+ # the offsets are the same. (no reason to send both though)
+ if date_time_offset is not None and local_offset is not None:
+ if date_time_offset != local_offset:
+ return 4, 409, "Offsets in DateTime and DateTimeLocalOffset conflict", None # 409 Conflict
+
+ # reconcile localOffset and the offset in DateTime to write back
+ # if only DateTime was updated, also update dateTimeLocalOffset
+ if local_offset is None:
+ local_offset = date_time_offset
+ # if only DateTimeLocalOffset was updated (timezone change), also update DateTime
+ if date_time is None:
+ date_time = self.res_data['DateTime'] # read current value to get time
+ date_time = date_time[:-6] # strip the offset
+ date_time = date_time + local_offset # add back the offset sent in in DateTimeLocalOFfset
+
+ # TODO: issue 1545 in SPMF is ambiguity of what patching DateTimeLocalOffset should actually do.
+ # this may need to be updated once issue is resolved
+
+ # now write the valid properties with updated values
+ self.res_data['DateTime'] = date_time
+ self.res_data['DateTimeLocalOffset'] = local_offset
+ return 0, 204, None, None
+
+ def reset_resource(self, reset_data):
+ if "ResetType" in reset_data:
+ value = reset_data['ResetType']
+ valid_values = self.res_data["Actions"]["#Manager.Reset"]["ResetType@Redfish.AllowableValues"]
+ if value in valid_values:
+ # it is a supoported reset action modify other properties appropritely
+ # nothing to do--manager always on in this profile
+ return 0, 204, "System Reset", ""
+ else:
+ return 4, 400, "Invalid reset value: ResetType", ""
+ else: # invalid request
+ return 4, 400, "Invalid request property", ""
+
+
+class RfManagerNetworkProtocol(RfResource):
+ pass
+
+
+# the Manager Ethernet Collection
+class RfManagerEthernetColl(RfCollection):
+ def element_type(self):
+ return RfManagerEthernet
+
+
+# the Manager Ethernet Instance
+class RfManagerEthernet(RfResource):
+ def patch_resource(self, patch_data):
+ # TODO: check and save the data
+ # for now, just return ok w/ 204 no content
+ return 0, 204, None, None
+
+
+class RfSerialInterfaceCollection(RfCollection):
+ def element_type(self):
+ return RfSerialInterface
+
+
+class RfSerialInterface(RfResource):
+ pass
+
+
+class RfVirtualMediaCollection(RfCollection):
+ def element_type(self):
+ return RfVirtualMedia
+
+
+class RfVirtualMedia(RfResource):
+ pass
+
+
+class RfNics(RfResource):
+ def create_sub_objects(self, base_path, rel_path):
+ resource_path = os.path.join(base_path, rel_path);
+ contents = os.listdir(resource_path)
+ for item in contents:
+ if item == "Dedicated":
+ self.components[item] = RfDedicatedNicCollection(base_path,
+ os.path.join(rel_path, item),
+ parent=self)
+
+
+class RfDedicatedNicCollection(RfCollection):
+ def element_type(self):
+ return RfNic
+
+
+class RfNic(RfResource):
+ pass
+
+
+class RfActiveHealthSystem(RfResource):
+ pass
+
+
+class RfDateTime(RfResource):
+ pass
+
+
+class RfEmbeddedMedia(RfResource):
+ pass
+
+
+class RfLicenseServiceCollection(RfCollection):
+ def element_type(self):
+ return RfLicenseService
+
+
+class RfLicenseService(RfResource):
+ pass
+
+
+class RfFederationGroupCollection(RfCollection):
+ def element_type(self):
+ return RfFederationGroup
+
+
+class RfFederationGroup(RfResource):
+ pass
+
+
+class RfFederationPeerCollection(RfCollection):
+ def element_type(self):
+ return RfFederationPeer
+
+
+class RfFederationPeer(RfResource):
+ pass
+
+
+class RfManagerUpdateService(RfResource):
+ pass
diff --git a/RedfishClientPkg/Tools/Redfish-Profile-Simulator/v1sim/network.py b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/v1sim/network.py
new file mode 100644
index 0000000000..d96d29c5ad
--- /dev/null
+++ b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/v1sim/network.py
@@ -0,0 +1,48 @@
+import os
+
+from .resource import RfCollection, RfResource
+
+
+class RfNetworkService(RfResource):
+ pass
+
+
+class RfEthernetCollection(RfCollection):
+ def element_type(self):
+ return RfEthernet
+
+ def create_sub_objects(self, base_path, rel_path):
+ self.elements = {}
+ resource_path = os.path.join(base_path, rel_path);
+ contents = os.listdir(resource_path)
+ for item in contents:
+ if item == "VLANs":
+ self.components[item] = RfVLanCollection(base_path, os.path.join(rel_path, item), parent=self)
+ else:
+ item_path = os.path.join(resource_path, item)
+ if os.path.isdir(item_path):
+ etype = self.element_type() # type: Type[RfEthernetCollection]
+ self.elements[item] = etype(base_path,
+ os.path.normpath("%s/%s" % (rel_path, item)),
+ parent=self)
+
+class RfEthernet(RfResource):
+ pass
+
+
+class RfVLanCollection(RfCollection):
+ def element_type(self):
+ return RfVLan
+
+
+class RfVLan(RfResource):
+ pass
+
+
+class RfNetworkInterfaceCollection(RfCollection):
+ def element_type(self):
+ return RfNetworkInterface
+
+
+class RfNetworkInterface(RfResource):
+ pass
diff --git a/RedfishClientPkg/Tools/Redfish-Profile-Simulator/v1sim/redfishURIs.py b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/v1sim/redfishURIs.py
new file mode 100644
index 0000000000..2380a4058a
--- /dev/null
+++ b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/v1sim/redfishURIs.py
@@ -0,0 +1,309 @@
+# Copyright Notice:
+# Copyright 2016 Distributed Management Task Force, Inc. All rights reserved.
+# License: BSD 3-Clause License. For full text see link: https://github.com/DMTF/Redfish-Profile-Simulator/blob/master/LICENSE.md
+
+import json
+
+from flask import Flask
+from flask import request
+
+from .flask_redfish_auth import RfHTTPBasicOrTokenAuth
+from .resource import RfResource, RfResourceRaw, RfCollection
+
+
+def rfApi_SimpleServer(root, versions, host="127.0.0.1", port=5000):
+ app = Flask(__name__)
+
+ # create auth class that does basic or redifish session auth
+ auth = RfHTTPBasicOrTokenAuth()
+
+ # define basic auth decorator used by flask
+ # for basic auth, we only support user=catfish, passwd=hunter
+ @auth.verify_basic_password
+ def verify_rf_passwd(user, passwd):
+ if user == "root":
+ if passwd == "password123456":
+ return True
+ return False
+
+ # define Redfish Token/Session auth decorator used by flask
+ # for session token auth, only support toden: 123456CATFISHauthcode
+ @auth.verify_token
+ def verify_rf_token(auth_token):
+ # lookup the user for this token
+ # lookup the privileges for this user
+ # check privilege
+ # print("at verify_rf_token. auth_token={}".format(auth_token))
+ if auth_token == "123456SESSIONauthcode": # the magic token
+ return True
+ else:
+ return False
+
+ # define redfish URI APIs for flask
+
+ # GET /redfish
+ @app.route("/redfish", methods=['GET'])
+ @app.route("/redfish/", methods=['GET'])
+ def rf_versions():
+ return versions.get_resource()
+
+ # GET /redfish/v1
+ @app.route("/redfish/v1", methods=['GET'])
+ @app.route("/redfish/v1/", methods=['GET'])
+ def rf_service_root():
+ return root.get_resource()
+
+ # GET /redfish/v1/$metadata
+ @app.route("/redfish/v1/$metadata", methods=['GET'])
+ def rf_metadata(rf_path='$metadata'):
+ return resolve_path(root, rf_path)
+
+ # GET /redfish/v1/odata
+ @app.route("/redfish/v1/odata", methods=['GET'])
+ @app.route("/redfish/v1/odata/", methods=['GET'])
+ def rf_odata(rf_path='odata'):
+ return resolve_path(root, rf_path)
+
+ @app.route("/redfish/v1/<path:rf_path>", methods=['GET'])
+ @app.route("/redfish/v1/<path:rf_path>/", methods=['GET'])
+ @auth.rfAuthRequired
+ def rf_subsystems(rf_path):
+ return resolve_path(root, rf_path)
+
+ # this is a special test API -- an authenticated service root
+ @app.route("/redfish/v1/A", methods=['GET'])
+ @auth.rfAuthRequired
+ def rf_service_root2():
+ print("root2")
+ return root.get_resource()
+
+ @app.route("/redfish/v1/Systems/<path:sys_path>", methods=['PATCH'])
+ @app.route("/redfish/v1/Systems/<path:sys_path>/", methods=['PATCH'])
+ @auth.rfAuthRequired
+ def rf_computer_systempatch(sys_path):
+ rdata = request.get_json(cache=True)
+ print("rdata:{}".format(rdata))
+ obj = patch_path(root.systems, sys_path)
+ rc, status_code, err_string, resp = obj.patch_resource(rdata)
+ if rc == 0:
+ return "", status_code
+ else:
+ return err_string, status_code
+
+ @app.route("/redfish/v1/Systems/<string:system_id>/Actions/ComputerSystem.Reset", methods=['POST'])
+ @app.route("/redfish/v1/Systems/<string:system_id>/Actions/ComputerSystem.Reset/", methods=['POST'])
+ @auth.rfAuthRequired
+ def rf_computer_systemreset(system_id):
+ # print("in reset")
+ rdata = request.get_json(cache=True)
+ # print("rdata:{}".format(rdata))
+ rc, status_code, err_string, resp = root.components['Systems'].get_element(system_id).reset_resource(rdata)
+ if rc == 0:
+ return "", status_code
+ else:
+ return err_string, status_code
+
+ @app.route("/redfish/v1/Systems/<string:system_id>/bios/Actions/Bios.ResetBios", methods=['POST'])
+ @app.route("/redfish/v1/Systems/<string:system_id>/bios/Actions/Bios.ResetBios/", methods=['POST'])
+ @auth.rfAuthRequired
+ def rf_computer_biosreset(system_id):
+ # print("in reset")
+ rdata = request.get_json(cache=True)
+ # print("rdata:{}".format(rdata))
+ system = root.systems.get_element(system_id)
+ bios = system.get_component("bios")
+ rc, status_code, err_string, resp = bios.reset_resource(rdata)
+ if rc == 0:
+ return "", status_code
+ else:
+ return err_string, status_code
+
+ @app.route("/redfish/v1/Systems/<string:system_id>/bios/Actions/Bios.ChangePassword", methods=['PATCH'])
+ @app.route("/redfish/v1/Systems/<string:system_id>/bios/Actions/Bios.ChangePassword/", methods=['PATCH'])
+ @auth.rfAuthRequired
+ def rf_computer_change_pswd(system_id):
+ # print("in reset")
+ rdata = request.get_json(cache=True)
+ # print("rdata:{}".format(rdata))
+ system = root.systems.get_element(system_id)
+ bios = system.get_component("bios")
+ rc, status_code, err_string, resp = bios.change_password(rdata)
+ if rc == 0:
+ return "", status_code
+ else:
+ return err_string, status_code
+
+ @app.route("/redfish/v1/Chassis/<string:chassis_id>/Actions/Chassis.Reset", methods=['POST'])
+ @app.route("/redfish/v1/Chassis/<string:chassis_id>/Actions/Chassis.Reset/", methods=['POST'])
+ @auth.rfAuthRequired
+ def rf_computer_chassisreset(chassis_id):
+ # print("in reset")
+ rdata = request.get_json(cache=True)
+ # print("rdata:{}".format(rdata))
+ rc, status_code, err_string, resp = root.chassis.get_element(chassis_id).reset_resource(rdata)
+ if rc == 0:
+ return "", status_code
+ else:
+ return err_string, status_code
+
+ @app.route("/redfish/v1/Chassis/<string:chassis_id>/Power", methods=['PATCH'])
+ @app.route("/redfish/v1/Chassis/<string:chassis_id>/Power/", methods=['PATCH'])
+ @auth.rfAuthRequired
+ def rf_chassis_powerpatch(chassis_id):
+ # rawdata=request.data
+ rdata = request.get_json(cache=True)
+ # print("RRrdata:{}".format(rdata))
+ rc, status_code, err_string, resp = root.chassis.get_element(chassis_id).power.patch_resource(rdata)
+ if rc == 0:
+ return "", status_code
+ else:
+ return err_string, status_code
+
+ @app.route("/redfish/v1/Managers/<string:manager_id>", methods=['PATCH'])
+ @app.route("/redfish/v1/Managers/<string:manager_id>/", methods=['PATCH'])
+ @auth.rfAuthRequired
+ def rf_patch_manager_entity(manager_id):
+ rdata = request.get_json(cache=True)
+ # print("RRrdata:{}".format(rdata))
+ rc, status_code, err_string, resp = root.managers.get_element(manager_id).patch_resource(rdata)
+ if rc == 0:
+ return "", status_code
+ else:
+ return err_string, status_code
+
+ # rest/v1/Managers/1
+ @app.route("/redfish/v1/Managers/<string:manager_id>/Actions/Manager.Reset", methods=['POST'])
+ @app.route("/redfish/v1/Managers/<string:manager_id>/Actions/Manager.Reset/", methods=['POST'])
+ @auth.rfAuthRequired
+ def rf_reset_manager(manager_id):
+ rdata = request.get_json(cache=True)
+ # print("rdata:{}".format(rdata))
+ rc, status_code, err_string, resp = root.managers.get_element(manager_id).reset_resource(rdata)
+ if rc == 0:
+ return "", status_code
+ else:
+ return err_string, status_code
+
+ @app.route("/redfish/v1/Managers/<string:manager_id>/EthernetInterfaces/<string:eth_id>", methods=['PATCH'])
+ @app.route("/redfish/v1/Managers/<string:manager_id>/EthernetInterfaces/<string:eth_id>/", methods=['PATCH'])
+ @auth.rfAuthRequired
+ def rf_patch_manager_nic_entity(manager_id, eth_id):
+ resp = root.managers.get_element(manager_id).ethernetColl.get_interface(eth_id).get_resource()
+ rdata = request.get_json(cache=True)
+ # print("RRrdata:{}".format(rdata))
+ ethernet_coll = root.managers.get_element(manager_id).ethernetColl
+ rc, status_code, err_string, resp = ethernet_coll.get_interface(eth_id).patch_resource(rdata)
+ if rc == 0:
+ return "", status_code
+ else:
+ return err_string, status_code
+
+ @app.route("/redfish/v1/SessionService", methods=['PATCH'])
+ @app.route("/redfish/v1/SessionService/", methods=['PATCH'])
+ @auth.rfAuthRequired
+ def rf_patch_session_service():
+ rdata = request.get_json(cache=True)
+ # print("RRrdata:{}".format(rdata))
+ rc, status_code, err_string, resp = root.sessionService.patch_resource(rdata)
+ if rc == 0:
+ return "", status_code
+ else:
+ return err_string, status_code
+
+ # TODO: call root.sessionService.sessions.sessionLogin(usr,pwd), return resp, status_code, hdr
+ # login API, user catfish, password=hunter, authToken=123456CATFISHauthcode
+ @app.route("/redfish/v1/SessionService/Sessions", methods=['POST'])
+ def rf_login():
+ print("login")
+ rdata = request.get_json(cache=True)
+ print("rdata:{}".format(rdata))
+ if rdata["UserName"] == "root" and rdata["Password"] == "password123456":
+ x = {"Id": "SESSION123456"}
+ resp = json.dumps(x)
+ print("resp:{}".format(resp))
+ hdr = {"X-Auth-Token": "123456SESSIONauthcode",
+ "Location": "/redfish/v1/SessionService/Sessions/SESSION123456"}
+ return resp, 201, hdr
+ else:
+ return "", 401
+
+ # TODO: call root.sessionService.sessions.delete(sessId), return resp,status,hdr
+ # logout API
+ @app.route("/redfish/v1/SessionService/Sessions/<string:session_id>", methods=['DELETE'])
+ @auth.rfAuthRequired
+ def rf_session_logout(session_id):
+ print("session logout %s" % session_id)
+ # rdata=request.get_json(cache=True)
+ # print("rdata:{}".format(rdata))
+ return "", 204
+
+ @app.route("/redfish/v1/AccountService", methods=['PATCH'])
+ @auth.rfAuthRequired
+ def rf_patch_account_service():
+ rdata = request.get_json(cache=True)
+ rc, status_code, err_string, resp = root.accountService.patch_resource(rdata)
+ if rc == 0:
+ return "", status_code
+ else:
+ return err_string, status_code
+
+ def resolve_path(service, path):
+ parts = path.split('/')
+ result = service
+ current_obj = service
+ for part in parts:
+ if isinstance(current_obj, RfCollection):
+ result = current_obj.get_element(part)
+ current_obj = result
+ elif isinstance(current_obj, RfResource):
+ result = current_obj.get_component(part)
+ if not result:
+ result = current_obj.get_attribute(part)
+ break
+ else:
+ current_obj = result
+
+ if isinstance(result, (RfResource, RfResourceRaw)):
+ return result.get_resource()
+ else:
+ return result
+
+ def patch_path(service, path):
+ parts = path.split('/')
+ result = None
+ current_obj = service
+ for part in parts:
+ if isinstance(current_obj, RfCollection):
+ result = current_obj.get_element(part)
+ current_obj = result
+ elif isinstance(current_obj, RfResource):
+ result = current_obj.get_component(part)
+ if not result:
+ result = current_obj
+ break
+ else:
+ current_obj = result
+ return result
+
+ '''
+ @app.route("/rest/v1/xxx/x", methods=['GET'])
+ def rfXxxx():
+ resp=xxx.getObject()
+ return(resp)
+ '''
+
+ # END file redfishURIs
+
+ # start Flask REST engine running
+ app.run(host=host, port=port)
+
+ # never returns
+
+
+'''
+reference source links:
+https://gist.github.com/lrei/2408383
+http://docs.python-requests.org/en/v0.10.6/api/
+http://flask.pocoo.org/docs/0.10/quickstart/
+
+'''
diff --git a/RedfishClientPkg/Tools/Redfish-Profile-Simulator/v1sim/resource.py b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/v1sim/resource.py
new file mode 100644
index 0000000000..6fee348064
--- /dev/null
+++ b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/v1sim/resource.py
@@ -0,0 +1,100 @@
+# Copyright Notice:
+# Copyright 2016 Distributed Management Task Force, Inc. All rights reserved.
+# License: BSD 3-Clause License. For full text see link: https://github.com/DMTF/Redfish-Profile-Simulator/blob/master/LICENSE.md
+
+import json
+import os
+import sys
+
+import flask
+
+if sys.version_info >= (3, 5):
+ from typing import Type
+
+
+class RfResource:
+ def __init__(self, base_path, rel_path, parent=None):
+ self.parent = parent
+ self.components = {}
+
+ path = os.path.join(base_path, rel_path)
+ indx_file_path = os.path.join(path, "index.json")
+ print("*****Loading Mockup json file:{}".format(indx_file_path))
+ if os.path.exists(indx_file_path):
+ res_file = open(indx_file_path, "r")
+ res_rawdata = res_file.read()
+ self.res_data = json.loads(res_rawdata)
+ self.create_sub_objects(base_path, rel_path)
+ self.final_init_processing(base_path, rel_path)
+ else:
+ self.res_data = {}
+
+ def create_sub_objects(self, base_path, rel_path):
+ pass
+
+ def final_init_processing(self, base_path, rel_path):
+ pass
+
+ def get_resource(self):
+ return flask.jsonify(self.res_data)
+
+ def get_attribute(self, attribute):
+ return flask.jsonify(self.res_data[attribute])
+
+ def get_component(self, component):
+ if component in self.components:
+ return self.components[component]
+ else:
+ return None
+
+ def patch_resource(self, patch_data):
+ for key in patch_data.keys():
+ if key in self.res_data:
+ self.res_data[key] = patch_data[key]
+ else:
+ raise Exception("attribute %s not found" % key)
+
+
+class RfResourceRaw:
+ def __init__(self, base_path, rel_path, parent=None):
+ self.parent = parent
+ path = os.path.join(base_path, rel_path)
+ indx_file_path = os.path.join(path, "index.xml")
+ print("*****Loading Mockup raw data file:{}".format(indx_file_path))
+ res_file = open(indx_file_path, "r")
+ res_raw_data = res_file.read()
+ self.res_data = res_raw_data
+ self.create_subobjects(base_path, rel_path)
+ self.final_init_processing(base_path, rel_path)
+
+ def create_subobjects(self, base_path, rel_path):
+ pass
+
+ def final_init_processing(self, base_path, rel_path):
+ pass
+
+ def get_resource(self):
+ return flask.Response(response=self.res_data, status=200, mimetype='application/xml')
+
+
+class RfCollection(RfResource):
+ def create_sub_objects(self, base_path, rel_path):
+ self.elements = {}
+ subpath = os.path.join(base_path, rel_path)
+ contents = os.listdir(subpath)
+ for item in contents:
+ item_path = os.path.join(subpath, item)
+ if os.path.isdir(item_path):
+ etype = self.element_type() # type: Type[RfResource]
+ self.elements[item] = etype(base_path,
+ os.path.normpath("%s/%s" % (rel_path, item)),
+ parent=self)
+
+ def element_type(self):
+ pass
+
+ def get_elements(self):
+ return self.elements
+
+ def get_element(self, element_id):
+ return self.elements[element_id]
diff --git a/RedfishClientPkg/Tools/Redfish-Profile-Simulator/v1sim/security.py b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/v1sim/security.py
new file mode 100644
index 0000000000..deec1b2df9
--- /dev/null
+++ b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/v1sim/security.py
@@ -0,0 +1,35 @@
+import os
+
+from .resource import RfResource
+
+
+class RfSecurityService(RfResource):
+ def create_sub_objects(self, base_path, rel_path):
+ resource_path = os.path.join(base_path, rel_path);
+ contents = os.listdir(resource_path)
+ for item in contents:
+ if item == "ESKM":
+ self.components[item] = RfESKM(base_path, os.path.join(rel_path, item), parent=self)
+ if item == "HttpsCert":
+ self.components[item] = RfHttpsCert(base_path, os.path.join(rel_path, item), parent=self)
+ if item == "SSO":
+ self.components[item] = RfSSO(base_path, os.path.join(rel_path, item), parent=self)
+ if item == "CertificateAuthentication":
+ self.components[item] = RfCertificateAuthentication(base_path, os.path.join(rel_path, item),
+ parent=self)
+
+
+class RfESKM(RfResource):
+ pass
+
+
+class RfHttpsCert(RfResource):
+ pass
+
+
+class RfSSO(RfResource):
+ pass
+
+
+class RfCertificateAuthentication(RfResource):
+ pass
diff --git a/RedfishClientPkg/Tools/Redfish-Profile-Simulator/v1sim/serviceRoot.py b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/v1sim/serviceRoot.py
new file mode 100644
index 0000000000..6334ab1b5a
--- /dev/null
+++ b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/v1sim/serviceRoot.py
@@ -0,0 +1,87 @@
+# Copyright Notice:
+# Copyright 2016 Distributed Management Task Force, Inc. All rights reserved.
+# License: BSD 3-Clause License. For full text see link: https://github.com/DMTF/Redfish-Profile-Simulator/blob/master/LICENSE.md
+
+import os
+
+from .accountService import RfAccountServiceObj
+from .chassis import RfChassisCollection
+from .managers import RfManagersCollection
+from .resource import RfResource, RfCollection
+from .resource import RfResourceRaw
+from .sessionService import RfSessionServiceObj
+from .systems import RfSystemsCollection
+from .updateService import RfUpdateServiceObj
+
+
+class RfServiceRoot(RfResource):
+ def create_sub_objects(self, base_path, rel_path):
+ resource_path = os.path.join(base_path, rel_path);
+ contents = os.listdir(resource_path)
+ for item in contents:
+ if item == "odata":
+ self.components[item] = RfOdataServiceDoc(base_path, os.path.join(rel_path, item), parent=self)
+ elif item == "$metadata":
+ self.components[item] = RfOdataMetadata(base_path, os.path.join(rel_path, item), parent=self)
+ elif item == "Systems":
+ self.components[item] = RfSystemsCollection(base_path, os.path.join(rel_path, item), parent=self)
+ elif item == "Chassis":
+ self.components[item] = RfChassisCollection(base_path, os.path.join(rel_path, item), parent=self)
+ elif item == "Managers":
+ self.components[item] = RfManagersCollection(base_path, os.path.join(rel_path, item), parent=self)
+ elif item == "AccountService":
+ self.components[item] = RfAccountServiceObj(base_path, os.path.join(rel_path, item), parent=self)
+ elif item == "SessionService":
+ self.components[item] = RfSessionServiceObj(base_path, os.path.join(rel_path, item), parent=self)
+ elif item == "ResourceDirectory":
+ self.components[item] = RfResourceDirectoryObj(base_path, os.path.join(rel_path, item), parent=self)
+ elif item == "UpdateService":
+ self.components[item] = RfUpdateServiceObj(base_path, os.path.join(rel_path, item), parent=self)
+ elif item == "Registries":
+ self.components[item] = RfRegistryCollection(base_path, os.path.join(rel_path, item), parent=self)
+ elif item == "EventService":
+ self.components[item] = RfEventServiceObj(base_path, os.path.join(rel_path, item), parent=self)
+
+ def final_init_processing(self, base_path, rel_path):
+ print("\n\n{}".format(self.res_data['Name']))
+
+
+class RfOdataServiceDoc(RfResource):
+ pass
+
+
+class RfOdataMetadata(RfResourceRaw):
+ pass
+
+
+class RfResourceDirectoryObj(RfResource):
+ pass
+
+
+class RfRegistryCollection(RfCollection):
+ def element_type(self):
+ return RfRegistry
+
+
+class RfRegistry(RfResource):
+ pass
+
+
+class RfEventServiceObj(RfResource):
+ def create_sub_objects(self, base_path, rel_path):
+ resource_path = os.path.join(base_path, rel_path);
+ contents = os.listdir(resource_path)
+ for item in contents:
+ if item == "EventSubscriptions":
+ self.components[item] = RfEventSubscriptionCollection(base_path,
+ os.path.join(rel_path, item),
+ parent=self)
+
+
+class RfEventSubscriptionCollection(RfCollection):
+ def element_type(self):
+ return RfEventSubscription
+
+
+class RfEventSubscription(RfResource):
+ pass
diff --git a/RedfishClientPkg/Tools/Redfish-Profile-Simulator/v1sim/serviceVersions.py b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/v1sim/serviceVersions.py
new file mode 100644
index 0000000000..00279e5019
--- /dev/null
+++ b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/v1sim/serviceVersions.py
@@ -0,0 +1,9 @@
+# Copyright Notice:
+# Copyright 2016 Distributed Management Task Force, Inc. All rights reserved.
+# License: BSD 3-Clause License. For full text see link: https://github.com/DMTF/Redfish-Profile-Simulator/blob/master/LICENSE.md
+
+from .resource import RfResource
+
+
+class RfServiceVersions(RfResource):
+ pass
diff --git a/RedfishClientPkg/Tools/Redfish-Profile-Simulator/v1sim/sessionService.py b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/v1sim/sessionService.py
new file mode 100644
index 0000000000..0eeb93b91a
--- /dev/null
+++ b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/v1sim/sessionService.py
@@ -0,0 +1,41 @@
+# Copyright Notice:
+# Copyright 2016 Distributed Management Task Force, Inc. All rights reserved.
+# License: BSD 3-Clause License. For full text see link: https://github.com/DMTF/Redfish-Profile-Simulator/blob/master/LICENSE.md
+
+import os
+
+from .resource import RfResource, RfCollection
+
+
+class RfSessionServiceObj(RfResource):
+ # create instance of sessionService
+ def create_sub_objects(self, base_path, rel_path):
+ self.components["Sessions"] = RfSessionCollection(base_path,
+ os.path.normpath("redfish/v1/SessionService/Sessions"),
+ parent=self)
+
+ def patch_resource(self, patch_data):
+ # first verify client didn't send us a property we cant patch
+ for key in patch_data.keys():
+ if key != "SessionTimeout":
+ return 4, 400, "Invalid Patch Property Sent", ""
+ # now patch the valid properties sent
+ if "SessionTimeout" in patch_data:
+ new_val = patch_data['SessionTimeout']
+ if new_val < 30 or new_val > 86400:
+ return 4, 400, "Bad Request-not in correct range", ""
+ else:
+ self.res_data['SessionTimeout'] = new_val
+ return 0, 204, None, None
+ else:
+ return 4, 400, "Invalid Patch Property Sent", ""
+
+
+class RfSessionCollection(RfCollection):
+ def element_type(self):
+ return RfSessionObj
+
+
+# Service Collection Entries
+class RfSessionObj(RfResource):
+ pass
diff --git a/RedfishClientPkg/Tools/Redfish-Profile-Simulator/v1sim/storage.py b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/v1sim/storage.py
new file mode 100644
index 0000000000..04586d8332
--- /dev/null
+++ b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/v1sim/storage.py
@@ -0,0 +1,116 @@
+# Copyright Notice:
+# Copyright 2016 Distributed Management Task Force, Inc. All rights reserved.
+# License: BSD 3-Clause License. For full text see link: https://github.com/DMTF/Redfish-Profile-Simulator/blob/master/LICENSE.md
+
+import os
+
+from .resource import RfResource, RfCollection
+
+
+class RfSimpleStorageCollection(RfCollection):
+ def element_type(self):
+ return RfSimpleStorage
+
+
+class RfSimpleStorage(RfResource):
+ pass
+
+
+class RfSmartStorage(RfResource):
+ def create_sub_objects(self, base_path, rel_path):
+ resource_path = os.path.join(base_path, rel_path);
+ contents = os.listdir(resource_path)
+ for item in contents:
+ if item == "ArrayControllers":
+ self.components[item] = RfArrayControllerCollection(base_path,
+ os.path.join(rel_path, item),
+ parent=self)
+ if item == "HostBusAdapters":
+ self.components[item] = RfHostBusAdapterCollection(base_path,
+ os.path.join(rel_path, item),
+ parent=self)
+
+
+class RfArrayControllerCollection(RfCollection):
+ def element_type(self):
+ return RfArrayController
+
+
+class RfArrayController(RfResource):
+ def create_sub_objects(self, base_path, rel_path):
+ resource_path = os.path.join(base_path, rel_path);
+ contents = os.listdir(resource_path)
+ for item in contents:
+ if item == "DiskDrives":
+ self.components[item] = RfDiskDriveCollection(base_path, os.path.join(rel_path, item),
+ parent=self)
+ if item == "LogicalDrives":
+ self.components[item] = RfLogicalDriveCollection(base_path, os.path.join(rel_path, item),
+ parent=self)
+
+ if item == "StorageEnclosures":
+ self.components[item] = RfStorageEnclosureCollection(base_path, os.path.join(rel_path, item),
+ parent=self)
+ if item == "UnconfiguredDrives":
+ self.components[item] = RfUnconfiguredDriveCollection(base_path, os.path.join(rel_path, item),
+ parent=self)
+
+
+class RfHostBusAdapterCollection(RfCollection):
+ def element_type(self):
+ return RfHostBusAdapter
+
+
+class RfHostBusAdapter(RfResource):
+ pass
+
+
+class RfDiskDriveCollection(RfCollection):
+ def element_type(self):
+ return RfDiskDrive
+
+
+class RfDiskDrive(RfResource):
+ pass
+
+
+class RfLogicalDriveCollection(RfCollection):
+ def element_type(self):
+ return RfLogicalDrive
+
+
+class RfLogicalDrive(RfResource):
+ def create_sub_objects(self, base_path, rel_path):
+ resource_path = os.path.join(base_path, rel_path);
+ contents = os.listdir(resource_path)
+ for item in contents:
+ if item == "DataDrives":
+ self.components[item] = RfDataDriveCollection(base_path, os.path.join(rel_path, item),
+ parent=self)
+
+
+class RfDataDriveCollection(RfCollection):
+ def element_type(self):
+ return RfDataDrive
+
+
+class RfDataDrive(RfResource):
+ pass
+
+
+class RfStorageEnclosureCollection(RfCollection):
+ def element_type(self):
+ return RfStorageEnclosure
+
+
+class RfStorageEnclosure(RfResource):
+ pass
+
+
+class RfUnconfiguredDriveCollection(RfCollection):
+ def element_type(self):
+ return RfUnconfiguredDrive
+
+
+class RfUnconfiguredDrive(RfResource):
+ pass
diff --git a/RedfishClientPkg/Tools/Redfish-Profile-Simulator/v1sim/systems.py b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/v1sim/systems.py
new file mode 100644
index 0000000000..b107f035db
--- /dev/null
+++ b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/v1sim/systems.py
@@ -0,0 +1,198 @@
+# Copyright Notice:
+# Copyright 2016 Distributed Management Task Force, Inc. All rights reserved.
+# License: BSD 3-Clause License. For full text see link: https://github.com/DMTF/Redfish-Profile-Simulator/blob/master/LICENSE.md
+
+import os
+
+from .common_services import RfLogServiceCollection
+from .network import RfEthernetCollection, RfNetworkInterfaceCollection
+from .resource import RfResource, RfCollection
+from .storage import RfSimpleStorageCollection, RfSmartStorage
+
+
+class RfSystemsCollection(RfCollection):
+ def element_type(self):
+ return RfSystemObj
+
+
+class RfSystemObj(RfResource):
+ def create_sub_objects(self, base_path, rel_path):
+ resource_path = os.path.join(base_path, rel_path)
+ contents = os.listdir(resource_path)
+ for item in contents:
+ if item == "Bios":
+ self.components[item] = RfBios(base_path, os.path.join(rel_path, item), parent=self)
+ elif item == "EthernetInterfaces":
+ self.components[item] = RfEthernetCollection(base_path, os.path.join(rel_path, item), parent=self)
+ elif item == "LogServices":
+ self.components[item] = RfLogServiceCollection(base_path, os.path.join(rel_path, item), parent=self)
+ elif item == "Memory":
+ self.components[item] = RfMemoryCollection(base_path, os.path.join(rel_path, item), parent=self)
+ elif item == "Processors":
+ self.components[item] = RfProcessorCollection(base_path, os.path.join(rel_path, item), parent=self)
+ elif item == "SimpleStorage":
+ self.components[item] = RfSimpleStorageCollection(base_path, os.path.join(rel_path, item), parent=self)
+ elif item == "SmartStorage":
+ self.components[item] = RfSmartStorage(base_path, os.path.join(rel_path, item), parent=self)
+ elif item == "SecureBoot":
+ self.components[item] = RfSecureBoot(base_path, os.path.join(rel_path, item), parent=self)
+ elif item == "NetworkInterfaces":
+ self.components[item] = RfNetworkInterfaceCollection(base_path, os.path.join(rel_path, item), parent=self)
+ elif item == "PCIeDevices":
+ self.components[item] = RfPCIeDeviceCollection(base_path, os.path.join(rel_path, item), parent=self)
+ elif item == "PCISlots":
+ self.components[item] = RfPCISlotCollection(base_path, os.path.join(rel_path, item), parent=self)
+ elif item == "FirmwareInventory":
+ self.components[item] = RfSystemFirmwareInventory(base_path, os.path.join(rel_path, item), parent=self)
+ elif item == "USBDevices":
+ self.components[item] = RfUSBDeviceCollection(base_path, os.path.join(rel_path, item), parent=self)
+ elif item == "USBPorts":
+ self.components[item] = RfUSBPortCollection(base_path, os.path.join(rel_path, item), parent=self)
+
+ def patch_resource(self, patch_data):
+ # first verify client didn't send us a property we cant patch
+ for key in patch_data.keys():
+ if key != "AssetTag" and key != "IndicatorLED" and key != "Boot":
+ return 4, 400, "Invalid Patch Property Sent", ""
+ elif key == "Boot":
+ for prop2 in patch_data["Boot"].keys():
+ if prop2 != "BootSourceOverrideEnabled" and prop2 != "BootSourceOverrideTarget":
+ return 4, 400, "Invalid Patch Property Sent", ""
+ # now patch the valid properties sent
+ if "AssetTag" in patch_data:
+ print("assetTag:{}".format(patch_data["AssetTag"]))
+ self.res_data['AssetTag'] = patch_data['AssetTag']
+ if "IndicatorLED" in patch_data:
+ self.res_data['IndicatorLED'] = patch_data['IndicatorLED']
+ if "Boot" in patch_data:
+ boot_data = patch_data["Boot"]
+ if "BootSourceOverrideEnabled" in boot_data:
+ value = boot_data["BootSourceOverrideEnabled"]
+ valid_values = ["Once", "Disabled", "Continuous"]
+ if value in valid_values:
+ self.res_data['Boot']['BootSourceOverrideEnabled'] = value
+ else:
+ return 4, 400, "Invalid_Value_Specified: BootSourceOverrideEnable", ""
+ if "BootSourceOverrideTarget" in boot_data:
+ value = boot_data["BootSourceOverrideTarget"]
+ valid_values = self.res_data['Boot']['BootSourceOverrideTarget@Redfish.AllowableValues']
+ if value in valid_values:
+ self.res_data['Boot']['BootSourceOverrideTarget'] = value
+ else:
+ return 4, 400, "Invalid_Value_Specified: BootSourceOverrideTarget", ""
+ return 0, 204, None, None
+
+ def reset_resource(self, reset_data):
+ if "ResetType" in reset_data:
+ # print("RESETDATA: {}".format(resetData))
+ value = reset_data['ResetType']
+ valid_values = self.res_data["Actions"]["#ComputerSystem.Reset"]["ResetType@Redfish.AllowableValues"]
+ if value in valid_values:
+ # it is a supoported reset action modify other properties appropritely
+ if value == "On" or value == "ForceRestart" or value == "GracefulRestart":
+ self.res_data["PowerState"] = "On"
+ print("PROFILE_SIM--SERVER WAS RESET. power now ON")
+ elif value == "GracefulShutdown" or value == "ForceOff":
+ self.res_data["PowerState"] = "Off"
+ print("PROFILE_SIM--SERVER WAS RESET. Power now Off")
+ return 0, 204, "System Reset", ""
+ else:
+ return 4, 400, "Invalid reset value: ResetType", ""
+ else: # invalid request
+ return 4, 400, "Invalid request property", ""
+
+
+# subclass Logs Collection
+class RfMemoryCollection(RfCollection):
+ def element_type(self):
+ return RfMemory
+
+
+class RfMemory(RfResource):
+ pass
+
+
+class RfProcessorCollection(RfCollection):
+ def element_type(self):
+ return RfProcessor
+
+
+class RfProcessor(RfResource):
+ pass
+
+
+class RfBios(RfResource):
+ def create_sub_objects(self, base_path, rel_path):
+ resource_path = os.path.join(base_path, rel_path)
+ contents = os.listdir(resource_path)
+ for item in contents:
+ if item == "Settings":
+ self.components[item] = RfBiosSettings(base_path, os.path.join(rel_path, item), parent=self)
+
+ def reset_resource(self, req_data):
+ print("bios was reset")
+ return 0, 204, "Bios Reset", ""
+
+ def change_password(self, req_data):
+ if "PasswordName" in req_data and "OldPassword" in req_data and "NewPassword" in req_data:
+ print("changed password of type %s" % req_data["PasswordName"])
+ return 0, 204, "Password Change", ""
+ else: # invalid request
+ return 4, 400, "Invalid request property", ""
+
+
+class RfBiosSettings(RfResource):
+ def patch_resource(self, patch_data):
+ if "Attributes" not in patch_data:
+ return 4, 400, "Invalid Payload. No Attributes found", ""
+ for key in patch_data["Attributes"].keys():
+ # verify client didn't send us a property we cant patch
+ if key not in self.res_data["Attributes"]:
+ return 4, 400, "Invalid Patch Property Sent", ""
+ else:
+ self.parent.res_data["Attributes"][key] = patch_data["Attributes"][key]
+ return 0, 204, None, None
+
+
+class RfPCIeDeviceCollection(RfCollection):
+ def element_type(self):
+ return RfPCIeDevice
+
+
+class RfPCIeDevice(RfResource):
+ pass
+
+
+class RfPCISlotCollection(RfCollection):
+ def element_type(self):
+ return RfPCISlot
+
+
+class RfPCISlot(RfResource):
+ pass
+
+
+class RfSecureBoot(RfResource):
+ pass
+
+
+class RfSystemFirmwareInventory(RfResource):
+ pass
+
+
+class RfUSBDeviceCollection(RfCollection):
+ def element_type(self):
+ return RfUSBDevice
+
+
+class RfUSBDevice(RfResource):
+ pass
+
+
+class RfUSBPortCollection(RfCollection):
+ def element_type(self):
+ return RfUSBPort
+
+
+class RfUSBPort(RfResource):
+ pass
diff --git a/RedfishClientPkg/Tools/Redfish-Profile-Simulator/v1sim/updateService.py b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/v1sim/updateService.py
new file mode 100644
index 0000000000..66bdf35f42
--- /dev/null
+++ b/RedfishClientPkg/Tools/Redfish-Profile-Simulator/v1sim/updateService.py
@@ -0,0 +1,84 @@
+# Copyright Notice:
+# Copyright 2016 Distributed Management Task Force, Inc. All rights reserved.
+# License: BSD 3-Clause License. For full text see link: https://github.com/DMTF/Redfish-Profile-Simulator/blob/master/LICENSE.md
+
+import os
+
+from .resource import RfResource, RfCollection
+
+
+class RfUpdateServiceObj(RfResource):
+ def create_sub_objects(self, base_path, rel_path):
+ if os.path.isdir(os.path.join(base_path, os.path.normpath("redfish/v1/UpdateService/ComponentRepository"))):
+ self.components["ComponentRepository"] \
+ = RfComponentRepositoryCollection(base_path,
+ os.path.normpath("redfish/v1/UpdateService/ComponentRepository"),
+ parent=self)
+ if os.path.isdir(os.path.join(base_path, os.path.normpath("redfish/v1/UpdateService/FirmwareInventory"))):
+ self.components["FirmwareInventory"] \
+ = RfFirmwareInventoryCollection(base_path,
+ os.path.normpath("redfish/v1/UpdateService/FirmwareInventory"),
+ parent=self)
+
+ if os.path.isdir(os.path.join(base_path, os.path.normpath("redfish/v1/UpdateService/InstallSets"))):
+ self.components["InstallSets"] \
+ = RfInstallSetCollection(base_path,
+ os.path.normpath("redfish/v1/UpdateService/InstallSets"),
+ parent=self)
+
+ if os.path.isdir(os.path.join(base_path, os.path.normpath("redfish/v1/UpdateService/SoftwareInventory"))):
+ self.components["SoftwareInventory"] \
+ = RfSoftwareInventoryCollection(base_path,
+ os.path.normpath("redfish/v1/UpdateService/SoftwareInventory"),
+ parent=self)
+
+ if os.path.isdir(os.path.join(base_path, os.path.normpath("redfish/v1/UpdateService/UpdateTaskQueue"))):
+ self.components["UpdateTaskQueue"] \
+ = RfUpdateTaskQueueCollection(base_path,
+ os.path.normpath("redfish/v1/UpdateService/UpdateTaskQueue"),
+ parent=self)
+
+
+class RfComponentRepositoryCollection(RfCollection):
+ def element_type(self):
+ return RfComponentRepository
+
+
+class RfComponentRepository(RfResource):
+ pass
+
+
+class RfFirmwareInventoryCollection(RfCollection):
+ def element_type(self):
+ return RfComponentRepository
+
+
+class RfFirmwareInventory(RfResource):
+ pass
+
+
+class RfInstallSetCollection(RfCollection):
+ def element_type(self):
+ return RfInstallSet
+
+
+class RfInstallSet(RfResource):
+ pass
+
+
+class RfSoftwareInventoryCollection(RfCollection):
+ def element_type(self):
+ return RfSoftwareInventory
+
+
+class RfSoftwareInventory(RfResource):
+ pass
+
+
+class RfUpdateTaskQueueCollection(RfCollection):
+ def element_type(self):
+ return RfUpdateTaskQueue
+
+
+class RfUpdateTaskQueue(RfResource):
+ pass
--
2.17.1