From bf3a044d206f72dd9b07e3ea815dbe9f60fac326 Mon Sep 17 00:00:00 2001 From: Mario Vazquez Date: Tue, 26 Apr 2022 10:53:32 +0200 Subject: [PATCH] Move fakefish from telco-operations repo Signed-off-by: Mario Vazquez --- Makefile | 19 +++ README.md | 171 +++++++++++++++++++++++++ app/fakefish.py | 154 ++++++++++++++++++++++ app/templates/fake_interfaces.json | 13 ++ app/templates/fake_manager.json | 37 ++++++ app/templates/fake_system.json | 88 +++++++++++++ app/templates/managers.json | 16 +++ app/templates/root.json | 16 +++ app/templates/systems.json | 15 +++ app/templates/virtualmedia_cd.json | 33 +++++ app/templates/virtualmedias.json | 16 +++ custom_scripts/Containerfile | 21 +++ custom_scripts/place_your_scripts_here | 0 dell_scripts/Containerfile | 23 ++++ dell_scripts/bootfromcdonce.sh | 16 +++ dell_scripts/mountcd.sh | 19 +++ dell_scripts/poweroff.sh | 13 ++ dell_scripts/poweron.sh | 11 ++ dell_scripts/unmountcd.sh | 12 ++ 19 files changed, 693 insertions(+) create mode 100644 Makefile create mode 100644 README.md create mode 100755 app/fakefish.py create mode 100644 app/templates/fake_interfaces.json create mode 100644 app/templates/fake_manager.json create mode 100644 app/templates/fake_system.json create mode 100644 app/templates/managers.json create mode 100644 app/templates/root.json create mode 100644 app/templates/systems.json create mode 100644 app/templates/virtualmedia_cd.json create mode 100644 app/templates/virtualmedias.json create mode 100644 custom_scripts/Containerfile create mode 100644 custom_scripts/place_your_scripts_here create mode 100644 dell_scripts/Containerfile create mode 100755 dell_scripts/bootfromcdonce.sh create mode 100755 dell_scripts/mountcd.sh create mode 100755 dell_scripts/poweroff.sh create mode 100755 dell_scripts/poweron.sh create mode 100755 dell_scripts/unmountcd.sh diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..36e47ca --- /dev/null +++ b/Makefile @@ -0,0 +1,19 @@ +REGISTRY ?= quay.io +IMAGE_NAMESPACE ?= mavazque +IMAGE_NAME ?= fakefish +IMAGE_URL ?= $(REGISTRY)/$(IMAGE_NAMESPACE)/$(IMAGE_NAME) +TAG ?= latest + +.PHONY: build-dell build-custom pre-reqs + +default: pre-reqs build-custom + +build-dell: + podman build . -f dell_scripts/Containerfile -t ${IMAGE_URL}:${TAG} + +build-custom: pre-reqs + podman build . -f custom_scripts/Containerfile -t ${IMAGE_URL}:${TAG} + +.SILENT: +pre-reqs: + if [ $(shell find custom_scripts/ -name "*.sh" | grep -Ec "mountcd.sh|poweroff.sh|poweron.sh|unmountcd.sh|bootfromcdonce.sh") -ne 5 ];then echo 'Missing custom scripts or bad naming';exit 1;fi diff --git a/README.md b/README.md new file mode 100644 index 0000000..63dc742 --- /dev/null +++ b/README.md @@ -0,0 +1,171 @@ +# FakeFish + +> **WARNING**: The work exposed here is not supported in any way by Red Hat, this is the result of exploratory work. Use at your own risk. + +`FakeFish` is a flask based app that exposes a RedFish-like API with a set of limited endpoints that allow the deployment of OpenShift nodes via the Metal3 operator on hardware that doesn't support RedFish or doesn't follow the RedFish standard. + +The way it works is by running a set of scripts that interact with the hardware using vendor tools/other methods while exposing a fake RedFish API that Metal3 can query. + +The [app/](./app/) directory contains the FakeFish application. Inside the `app` directory we can find the [custom_scripts](./app/custom_scripts/) folder where we need to create scripts: + +|Script|What should it do?| +|------|----------------| +|`poweron.sh`|Power on the server| +|`poweroff.sh`|Power off the server| +|`bootfromcdonce.sh`|Set server to boot from virtual CD once| +|`mountcd.sh`|Mount the iso received in the server's virtual CD| +|`unmountcd.sh`|Unmount the iso from the server's virtual CD| + +The script names must match above naming, you can check the [dell_scripts](./dell_scripts/) folder to find example scripts with the correct naming. + +> **NOTE**: Dell scripts linked above are only meant to show how someone could implement the required scripts to make custom hardware compatible with FakeFish. Dell hardware is supported by the `idrac-virtualmedia` provider in Metal3. **These scripts are unsupported/unmaintained** and should be taken as a reference, nothing else. + +Users need to implement their own scripts, we will not maintain/add providers to this project. + +A [Containerfile](./custom_scripts/Containerfile) is included, so users can build their own container image out of it. + +## Building your own FakeFish container image + +1. Place your custom scripts inside the [custom_scripts](./custom_scripts/) folder. +2. Run the build command: + + > **NOTE**: Check the Makefile vars to customize the output container image naming and tag. + + ~~~sh + make build-custom + ~~~ + +## Usage + +You need a FakeFish process for each server you plan to install. Think of FakeFish like if it was a custom implementation of a BMC for that specific server. + +Since you will be potentially running multiple FakeFish instances, you will make use of an environment variable to configure in which port a given FakeFish instance listens on. On top of that, you need to do a bind mount for the folder containing the scripts for managing that specific server. + +An example can be found below: + +> **NOTE**: Every container is mapped to a single BMC, but if more hosts are required, different ports can be used (9001, 9002,...) + +```sh +podman run -p 9000:9000 -e PORT=9000 -v $PWD/dell_scripts:/opt/fakefish/custom_scripts:z quay.io/mavazque/fakefish:v0 + +sudo firewall-cmd --add-port=9000/tcp +``` + +Then, in the `install-config.yaml` file, it is required to specify the IP where the container is running instead of the 'real' BMC: + +```yaml +bmcAddress: redfish-virtualmedia://192.168.1.10:9000/redfish/v1/Systems/1 +``` + +## Logs + +In a successful execution you should see something like this in the logs: + +- Starting FakeFish + + ```sh + $ podman run -p 9000:9000 -e PORT=9000 -v $PWD/dell_scripts:/opt/fakefish/custom_scripts:z quay.io/mavazque/fakefish:v0 + + * Serving Flask app 'fakefish' (lazy loading) + * Environment: production + WARNING: This is a development server. Do not use it in a production deployment. + Use a production WSGI server instead. + * Debug mode: off + * Running on all addresses. + WARNING: This is a development server. Do not use it in a production deployment. + * Running on https://10.19.3.25:9000/ (Press CTRL+C to quit) + ``` + +- Provisioning Logs + + ```sh + 10.19.3.23 - - [20/Apr/2022 13:17:09] "GET /redfish/v1/Systems/1 HTTP/1.1" 200 - + 10.19.3.23 - - [20/Apr/2022 13:17:09] "GET /redfish/v1/Systems/1 HTTP/1.1" 200 - + 10.19.3.23 - - [20/Apr/2022 13:17:09] "GET /redfish/v1/Systems/1/BIOS HTTP/1.1" 404 - + 10.19.3.23 - - [20/Apr/2022 13:17:09] "GET /redfish/v1/Systems/1 HTTP/1.1" 200 - + 10.19.3.23 - - [20/Apr/2022 13:17:09] "GET /redfish/v1/Systems/1 HTTP/1.1" 200 - + 10.19.3.23 - - [20/Apr/2022 13:17:09] "GET /redfish/v1/Systems/1 HTTP/1.1" 200 - + 10.19.3.23 - - [20/Apr/2022 13:17:24] "GET /redfish/v1/Systems/1 HTTP/1.1" 200 - + 10.19.3.23 - - [20/Apr/2022 13:17:24] "GET /redfish/v1/Systems/1 HTTP/1.1" 200 - + 10.19.3.23 - - [20/Apr/2022 13:17:24] "GET /redfish/v1/Systems/1 HTTP/1.1" 200 - + 10.19.3.23 - - [20/Apr/2022 13:18:24] "GET /redfish/v1/Systems/1 HTTP/1.1" 200 - + 10.19.3.23 - - [20/Apr/2022 13:18:24] "GET /redfish/v1/Systems/1 HTTP/1.1" 200 - + 10.19.3.23 - - [20/Apr/2022 13:18:24] "GET /redfish/v1/Systems/1 HTTP/1.1" 200 - + 10.19.3.23 - - [20/Apr/2022 13:18:27] "GET /redfish/v1/Systems/1 HTTP/1.1" 200 - + 10.19.3.23 - - [20/Apr/2022 13:18:27] "GET /redfish/v1/Systems/1 HTTP/1.1" 200 - + Security Alert: Certificate is invalid - self signed certificate + Continuing execution. Use -S option for racadm to stop execution on certificate-related errors. + Server is already powered OFF. + + 10.19.3.23 - - [20/Apr/2022 13:18:32] "POST /redfish/v1/Systems/1/Actions/ComputerSystem.Reset HTTP/1.1" 204 - + 10.19.3.23 - - [20/Apr/2022 13:18:33] "GET /redfish/v1/Systems/1 HTTP/1.1" 200 - + 10.19.3.23 - - [20/Apr/2022 13:18:33] "GET /redfish/v1/Systems/1 HTTP/1.1" 200 - + 10.19.3.23 - - [20/Apr/2022 13:18:33] "GET /redfish/v1/Systems/1 HTTP/1.1" 200 - + 10.19.3.23 - - [20/Apr/2022 13:18:33] "GET /redfish/v1/Managers/1 HTTP/1.1" 200 - + 10.19.3.23 - - [20/Apr/2022 13:18:33] "GET /redfish/v1/Managers/1/VirtualMedia HTTP/1.1" 200 - + 10.19.3.23 - - [20/Apr/2022 13:18:33] "GET /redfish/v1/Managers/1/VirtualMedia/Cd HTTP/1.1" 200 - + 10.19.3.23 - - [20/Apr/2022 13:18:33] "GET /redfish/v1/Systems/1 HTTP/1.1" 200 - + 10.19.3.23 - - [20/Apr/2022 13:18:33] "GET /redfish/v1/Systems/1 HTTP/1.1" 200 - + 10.19.3.23 - - [20/Apr/2022 13:18:33] "GET /redfish/v1/Managers/1 HTTP/1.1" 200 - + 10.19.3.23 - - [20/Apr/2022 13:18:34] "GET /redfish/v1/Managers/1/VirtualMedia HTTP/1.1" 200 - + 10.19.3.23 - - [20/Apr/2022 13:18:34] "GET /redfish/v1/Managers/1/VirtualMedia/Cd HTTP/1.1" 200 - + Security Alert: Certificate is invalid - self signed certificate + Continuing execution. Use -S option for racadm to stop execution on certificate-related errors. + Disable Remote File Started. Please check status using -s + option to know Remote File Share is ENABLED or DISABLED. + + Security Alert: Certificate is invalid - self signed certificate + Continuing execution. Use -S option for racadm to stop execution on certificate-related errors. + Remote Image is now Configured + + ShareName http://10.19.3.23:6180/redfish/boot-dc055836-d26c-4256-ba6c-222e8d4559be.iso + 10.19.3.23 - - [20/Apr/2022 13:18:48] "POST /redfish/v1/Managers/1/VirtualMedia/Cd/Actions/VirtualMedia.InsertMedia HTTP/1.1" 204 - + 10.19.3.23 - - [20/Apr/2022 13:18:48] "GET /redfish/v1/Systems/1 HTTP/1.1" 200 - + Security Alert: Certificate is invalid - self signed certificate + Continuing execution. Use -S option for racadm to stop execution on certificate-related errors. + [Key=iDRAC.Embedded.1#VirtualMedia.1] + Object value modified successfully + + Security Alert: Certificate is invalid - self signed certificate + Continuing execution. Use -S option for racadm to stop execution on certificate-related errors. + [Key=iDRAC.Embedded.1#ServerBoot.1] + Object value modified successfully + + 10.19.3.23 - - [20/Apr/2022 13:18:58] "PATCH /redfish/v1/Systems/1 HTTP/1.1" 204 - + 10.19.3.23 - - [20/Apr/2022 13:18:58] "GET /redfish/v1/Systems/1 HTTP/1.1" 200 - + 10.19.3.23 - - [20/Apr/2022 13:18:58] "GET /redfish/v1/Systems/1 HTTP/1.1" 200 - + Security Alert: Certificate is invalid - self signed certificate + Continuing execution. Use -S option for racadm to stop execution on certificate-related errors. + Server power operation successful + + 10.19.3.23 - - [20/Apr/2022 13:19:04] "POST /redfish/v1/Systems/1/Actions/ComputerSystem.Reset HTTP/1.1" 204 - + 10.19.3.23 - - [20/Apr/2022 13:19:05] "GET /redfish/v1/Systems/1 HTTP/1.1" 200 - + ``` + +- Deprovisioning Logs + + ```sh + 10.19.3.23 - - [20/Apr/2022 13:23:29] "GET /redfish/v1/Systems/1 HTTP/1.1" 200 - + 10.19.3.23 - - [20/Apr/2022 13:23:29] "GET /redfish/v1/Managers/1 HTTP/1.1" 200 - + 10.19.3.23 - - [20/Apr/2022 13:23:29] "GET /redfish/v1/Managers/1/VirtualMedia HTTP/1.1" 200 - + 10.19.3.23 - - [20/Apr/2022 13:23:29] "GET /redfish/v1/Managers/1/VirtualMedia/Cd HTTP/1.1" 200 - + Security Alert: Certificate is invalid - self signed certificate + Continuing execution. Use -S option for racadm to stop execution on certificate-related errors. + Disable Remote File Started. Please check status using -s + option to know Remote File Share is ENABLED or DISABLED. + + 10.19.3.23 - - [20/Apr/2022 13:23:55] "POST /redfish/v1/Managers/1/VirtualMedia/Cd/Actions/VirtualMedia.EjectMedia HTTP/1.1" 204 - + 10.19.3.23 - - [20/Apr/2022 13:23:55] "GET /redfish/v1/Systems/1 HTTP/1.1" 200 - + 10.19.3.23 - - [20/Apr/2022 13:23:55] "GET /redfish/v1/Managers/1 HTTP/1.1" 200 - + 10.19.3.23 - - [20/Apr/2022 13:23:55] "GET /redfish/v1/Managers/1/VirtualMedia HTTP/1.1" 200 - + 10.19.3.23 - - [20/Apr/2022 13:23:55] "GET /redfish/v1/Managers/1/VirtualMedia/Cd HTTP/1.1" 200 - + 10.19.3.23 - - [20/Apr/2022 13:23:55] "GET /redfish/v1/Systems/1 HTTP/1.1" 200 - + 10.19.3.23 - - [20/Apr/2022 13:23:56] "GET /redfish/v1/Systems/1 HTTP/1.1" 200 - + Security Alert: Certificate is invalid - self signed certificate + Continuing execution. Use -S option for racadm to stop execution on certificate-related errors. + Server power operation successful + + 10.19.3.23 - - [20/Apr/2022 13:24:09] "POST /redfish/v1/Systems/1/Actions/ComputerSystem.Reset HTTP/1.1" 204 - + 10.19.3.23 - - [20/Apr/2022 13:24:10] "GET /redfish/v1/Systems/1 HTTP/1.1" 200 - + + ``` diff --git a/app/fakefish.py b/app/fakefish.py new file mode 100755 index 0000000..714c73f --- /dev/null +++ b/app/fakefish.py @@ -0,0 +1,154 @@ +#!/usr/bin/env python3 +# coding=utf-8 + +import flask +import json +import os +import requests +import subprocess +from datetime import datetime +from requests.packages.urllib3.exceptions import InsecureRequestWarning +requests.packages.urllib3.disable_warnings(InsecureRequestWarning) + +app = flask.Flask(__name__) + +try: + app.config.from_object('settings') + config = app.config +except ImportError: + config = {'PORT': os.environ.get('PORT', 9000)} + +debug = config['DEBUG'] if 'DEBUG' in list(config) else True +port = int(config['PORT']) if 'PORT' in list(config) else 9000 + +@app.route('/redfish/v1/') +def root_resource(): + return flask.render_template('root.json') + +@app.route('/redfish/v1/Managers') +def manager_collection_resource(): + return flask.render_template('managers.json') + +@app.route('/redfish/v1/Systems') +def system_collection_resource(): + return flask.render_template('systems.json') + +@app.route('/redfish/v1/Systems/1', methods=['GET', 'PATCH']) +def system_resource(): + if flask.request.method == 'GET': + return flask.render_template( + 'fake_system.json', + power_state=power_state, + ) + else: + app.logger.info('patch request') + boot = flask.request.json.get('Boot') + if not boot: + return ('PATCH only works for Boot'), 400 + if boot: + target = boot.get('BootSourceOverrideTarget') + mode = boot.get('BootSourceOverrideMode') + if not target and not mode: + return ('Missing the BootSourceOverrideTarget and/or ' + 'BootSourceOverrideMode element', 400) + else: + app.logger.info('Running script that sets boot from VirtualCD once') + try: + subprocess.check_call(['custom_scripts/bootfromcdonce.sh']) + except subprocess.CalledProcessError as e: + return ('Failed to set boot from virtualcd once', 400) + + return '', 204 + +@app.route('/redfish/v1/Systems/1/EthernetInterfaces', methods=['GET']) +def manage_interfaces(): + return flask.render_template('fake_interfaces.json') + +@app.route('/redfish/v1/Managers/1', methods=['GET']) +def manager_resource(): + return flask.render_template( + 'fake_manager.json', + date_time=datetime.now().strftime('%Y-%M-%dT%H:%M:%S+00:00'), + ) + +@app.route('/redfish/v1/Systems/1/Actions/ComputerSystem.Reset', + methods=['POST']) +def system_reset_action(): + reset_type = flask.request.json.get('ResetType') + global power_state + if reset_type == 'On': + app.logger.info('Running script that powers on the server') + try: + subprocess.check_call(['custom_scripts/poweron.sh']) + except subprocess.CalledProcessError as e: + return ('Failed to poweron the server', 400) + power_state = 'On' + else: + app.logger.info('Running script that powers off the server') + try: + subprocess.check_call(['custom_scripts/poweroff.sh']) + except subprocess.CalledProcessError as e: + return ('Failed to poweroff the server', 400) + power_state = 'Off' + + return '', 204 + + +@app.route('/redfish/v1/Managers/1/VirtualMedia', methods=['GET']) +def virtualmedia_collection_resource(): + return flask.render_template('virtualmedias.json') + +@app.route('/redfish/v1/Managers/1/VirtualMedia/Cd', methods=['GET']) +def virtualmedia_cd_resource(): + return flask.render_template( + 'virtualmedia_cd.json', + inserted=inserted, + image_url=image_url, + ) + +@app.route('/redfish/v1/Managers/1/VirtualMedia/Cd/Actions/VirtualMedia.InsertMedia', + methods=['POST']) +def virtualmedia_insert(): + image = flask.request.json.get('Image') + if not image: + return('POST only works for Image'), 400 + else: + global inserted + global image_url + inserted = True + image_url = image + app.logger.info('Running script that mounts cd with iso %s', image) + try: + subprocess.check_call(['custom_scripts/mountcd.sh', image_url]) + except subprocess.CalledProcessError as e: + return ('Failed to mount virtualcd', 400) + return '', 204 + +@app.route('/redfish/v1/Managers/1/VirtualMedia/Cd/Actions/VirtualMedia.EjectMedia', + methods=['POST']) +def virtualmedia_eject(): + global inserted + global image_url + inserted = False + image_url = '' + app.logger.info('Running script that unmounts cd') + try: + subprocess.check_call(['custom_scripts/unmountcd.sh']) + except subprocess.CalledProcessError as e: + return ('Failed to unmount virtualcd', 400) + return '', 204 + + +def run(): + """ + + """ + app.run(host='0.0.0.0', port=port, debug=False, ssl_context='adhoc') + + +if __name__ == '__main__': + + inserted = False + image_url = '' + power_state = 'On' + run() diff --git a/app/templates/fake_interfaces.json b/app/templates/fake_interfaces.json new file mode 100644 index 0000000..3038932 --- /dev/null +++ b/app/templates/fake_interfaces.json @@ -0,0 +1,13 @@ +{ + "@odata.type": "#EthernetInterfaceCollection.EthernetInterfaceCollection", + "Name": "Ethernet Interface Collection", + "Description": "Fake NICs", + "Members@odata.count": 0, + "Members": [ + + ], + "Oem": {}, + "@odata.context": "/redfish/v1/$metadata#EthernetInterfaceCollection.EthernetInterfaceCollection", + "@odata.id": "/redfish/v1/Systems/1" +} + diff --git a/app/templates/fake_manager.json b/app/templates/fake_manager.json new file mode 100644 index 0000000..be305dd --- /dev/null +++ b/app/templates/fake_manager.json @@ -0,0 +1,37 @@ +{ + "@Redfish.Copyright": "Copyright 2014-2017 Distributed Management Task Force, Inc. (DMTF). For the full DMTF copyright policy, see http://www.dmtf.org/about/policies/copyright.", + "@odata.context": "/redfish/v1/$metadata#Manager.Manager", + "@odata.id": "/redfish/v1/Managers/1", + "@odata.type": "#Manager.v1_3_1.Manager", + "DateTime": {{ date_time|string|tojson }}, + "DateTimeLocalOffset": "+00:00", + "Description": "FakeFish BMC", + "FirmwareVersion": "1.00", + "Id": "1", + "Links": { + "ManagerForChassis": [ + { + "@odata.id": "/redfish/v1/Chassis/fake-chassis" + } + ], + "ManagerForServers": [ + { + "@odata.id": "/redfish/v1/Systems/1" + } + ] + }, + "ManagerType": "BMC", + "Model": "Palc 2000", + "Name": "FakeFish Manager", + "PowerState": "On", + "ServiceEntryPointUUID": null, + "Status": { + "Health": "OK", + "State": "Enabled" + }, + "UUID": "1", + "VirtualMedia": { + "@odata.id": "/redfish/v1/Managers/1/VirtualMedia" + } +} + diff --git a/app/templates/fake_system.json b/app/templates/fake_system.json new file mode 100644 index 0000000..13f419f --- /dev/null +++ b/app/templates/fake_system.json @@ -0,0 +1,88 @@ +{ + "@odata.type": "#ComputerSystem.v1_1_0.ComputerSystem", + "Id": "1", + "Name": "fake-system", + "UUID": "1", + "Manufacturer": "FakeFish", + "Status": { + "State": "Enabled", + "Health": "OK", + "HealthRollUp": "OK" + }, + "PowerState": {{ power_state|string|tojson }}, + "Boot": { + "BootSourceOverrideEnabled": "Continuous", + "BootSourceOverrideTarget": "Hdd", + "BootSourceOverrideTarget@Redfish.AllowableValues": [ + "Pxe", + "Cd", + "Hdd" + ], + "BootSourceOverrideMode": "UEFI", + "UefiTargetBootSourceOverride": "/0x31/0x33/0x01/0x01" + }, + "ProcessorSummary": { + "Count": 8, + "Status": { + "State": "Enabled", + "Health": "OK", + "HealthRollUp": "OK" + } + }, + "MemorySummary": { + "TotalSystemMemoryGiB": 15, + "Status": { + "State": "Enabled", + "Health": "OK", + "HealthRollUp": "OK" + } + }, + "Bios": { + "@odata.id": "/redfish/v1/Systems/1/BIOS" + }, + "Processors": { + "@odata.id": "/redfish/v1/Systems/1/Processors" + }, + "Memory": { + "@odata.id": "/redfish/v1/Systems/1/Memory" + }, + "EthernetInterfaces": { + "@odata.id": "/redfish/v1/Systems/1/EthernetInterfaces" + }, + "SimpleStorage": { + "@odata.id": "/redfish/v1/Systems/1/SimpleStorage" + }, + "Storage": { + "@odata.id": "/redfish/v1/Systems/1/Storage" + }, + "IndicatorLED": "Lit", + "Links": { + "Chassis": [ + { + "@odata.id": "/redfish/v1/Chassis/fake-chassis" + } + ], + "ManagedBy": [ + { + "@odata.id": "/redfish/v1/Managers/1" + } + ] + }, + "Actions": { + "#ComputerSystem.Reset": { + "target": "/redfish/v1/Systems/1/Actions/ComputerSystem.Reset", + "ResetType@Redfish.AllowableValues": [ + "On", + "ForceOff", + "GracefulShutdown", + "GracefulRestart", + "ForceRestart", + "Nmi", + "ForceOn" + ] + } + }, + "@odata.context": "/redfish/v1/$metadata#ComputerSystem.ComputerSystem", + "@odata.id": "/redfish/v1/Systems/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/app/templates/managers.json b/app/templates/managers.json new file mode 100644 index 0000000..00e13d8 --- /dev/null +++ b/app/templates/managers.json @@ -0,0 +1,16 @@ +{ + "@odata.type": "#ManagerCollection.ManagerCollection", + "Name": "Manager Collection", + "Members@odata.count": 1, + "Members": [ + + { + "@odata.id": "/redfish/v1/Managers/1" + } + ], + "Oem": {}, + "@odata.context": "/redfish/v1/$metadata#ManagerCollection.ManagerCollection", + "@odata.id": "/redfish/v1/Managers", + "@Redfish.Copyright": "Copyright 2014-2017 Distributed Management Task Force, Inc. (DMTF). For the full DMTF copyright policy, see http://www.dmtf.org/about/policies/copyright." +} + diff --git a/app/templates/root.json b/app/templates/root.json new file mode 100644 index 0000000..b607091 --- /dev/null +++ b/app/templates/root.json @@ -0,0 +1,16 @@ +{ + "@odata.type": "#ServiceRoot.v1_5_0.ServiceRoot", + "Id": "FakeFishService", + "Name": "FakeFish Service", + "RedfishVersion": "1.5.0", + "UUID": "not-that-production-ready", + "Systems": { + "@odata.id": "/redfish/v1/Systems" + }, + "Managers": { + "@odata.id": "/redfish/v1/Managers" + }, + "@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/app/templates/systems.json b/app/templates/systems.json new file mode 100644 index 0000000..cab1448 --- /dev/null +++ b/app/templates/systems.json @@ -0,0 +1,15 @@ +{ + "@odata.type": "#ComputerSystemCollection.ComputerSystemCollection", + "Name": "Computer System Collection", + "Members@odata.count": 1, + "Members": [ + + { + "@odata.id": "/redfish/v1/Systems/1" + } + ], + "@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/app/templates/virtualmedia_cd.json b/app/templates/virtualmedia_cd.json new file mode 100644 index 0000000..d0deefb --- /dev/null +++ b/app/templates/virtualmedia_cd.json @@ -0,0 +1,33 @@ +{ + "@odata.type": "#VirtualMedia.v1_4_0.VirtualMedia", + "Id": "Cd", + "Name": "Virtual CD", + "MediaTypes": [ + "CD", + "DVD" + ], + "Image": {{ image_url|string|tojson }}, + "ImageName": "", + "ConnectedVia": "URI", + "Inserted": {{ inserted|tojson }}, + "WriteProtected": false, + "Actions": { + "#VirtualMedia.EjectMedia": { + "target": "/redfish/v1/Managers/1/VirtualMedia/Cd/Actions/VirtualMedia.EjectMedia" + }, + "#VirtualMedia.InsertMedia": { + "target": "/redfish/v1/Managers/1/VirtualMedia/Cd/Actions/VirtualMedia.InsertMedia" + }, + "Oem": {} + }, + "UserName": "", + "Password": "", + "Certificates": { + "@odata.id": "/redfish/v1/Managers/1/VirtualMedia/Cd/Certificates" + }, + "VerifyCertificate": false, + "@odata.context": "/redfish/v1/$metadata#VirtualMedia.VirtualMedia", + "@odata.id": "/redfish/v1/Managers/1/VirtualMedia/Cd", + "@Redfish.Copyright": "Copyright 2014-2017 Distributed Management Task Force, Inc. (DMTF). For the full DMTF copyright policy, see http://www.dmtf.org/about/policies/copyright." +} + diff --git a/app/templates/virtualmedias.json b/app/templates/virtualmedias.json new file mode 100644 index 0000000..25d75e2 --- /dev/null +++ b/app/templates/virtualmedias.json @@ -0,0 +1,16 @@ +{ + "@odata.type": "#VirtualMediaCollection.VirtualMediaCollection", + "Name": "Virtual Media Services", + "Description": "FakeFish Virtual Media Service Settings", + "Members@odata.count": 1, + "Members": [ + + { + "@odata.id": "/redfish/v1/Managers/1/VirtualMedia/Cd" + } + + ], + "@odata.context": "/redfish/v1/$metadata#VirtualMediaCollection.VirtualMediaCollection", + "@odata.id": "/redfish/v1/Managers/1/VirtualMedia", + "@Redfish.Copyright": "Copyright 2014-2017 Distributed Management Task Force, Inc. (DMTF). For the full DMTF copyright policy, see http://www.dmtf.org/about/policies/copyright." +} diff --git a/custom_scripts/Containerfile b/custom_scripts/Containerfile new file mode 100644 index 0000000..657635e --- /dev/null +++ b/custom_scripts/Containerfile @@ -0,0 +1,21 @@ +FROM registry.fedoraproject.org/fedora:35 +MAINTAINER Mario Vazquez + +RUN set -x && \ + dnf -y update && \ + dnf install -y python3 python3-flask python3-requests python3-pyOpenSSL && \ + dnf clean all && \ + rm -rf /var/cache/yum /var/cache/dnf + +RUN mkdir -p /opt/fakefish/ + +COPY app/fakefish.py /opt/fakefish/fakefish.py + +ADD app/templates /opt/fakefish/templates +ADD custom_scripts /opt/fakefish/custom_scripts + +WORKDIR /opt/fakefish/ + +USER 1024 + +ENTRYPOINT ["/usr/bin/python3", "-u", "/opt/fakefish/fakefish.py"] diff --git a/custom_scripts/place_your_scripts_here b/custom_scripts/place_your_scripts_here new file mode 100644 index 0000000..e69de29 diff --git a/dell_scripts/Containerfile b/dell_scripts/Containerfile new file mode 100644 index 0000000..a77042d --- /dev/null +++ b/dell_scripts/Containerfile @@ -0,0 +1,23 @@ +FROM registry.fedoraproject.org/fedora:35 +MAINTAINER Mario Vazquez + +RUN echo -ne "[racadm]\nname=Racadm\nbaseurl=http://linux.dell.com/repo/hardware/dsu/os_dependent/RHEL8_64\nenabled=1\ngpgcheck=0" > /etc/yum.repos.d/racadm.repo + +RUN set -x && \ + dnf -y update && \ + dnf install -y python3 python3-flask python3-requests python3-pyOpenSSL openssl-devel srvadmin-idracadm7 && \ + dnf clean all && \ + rm -rf /var/cache/yum /var/cache/dnf + +RUN mkdir -p /opt/fakefish/ + +COPY app/fakefish.py /opt/fakefish/fakefish.py + +ADD app/templates /opt/fakefish/templates +ADD dell_scripts /opt/fakefish/custom_scripts + +WORKDIR /opt/fakefish/ + +USER 1024 + +ENTRYPOINT ["/usr/bin/python3", "-u", "/opt/fakefish/fakefish.py"] diff --git a/dell_scripts/bootfromcdonce.sh b/dell_scripts/bootfromcdonce.sh new file mode 100755 index 0000000..f614d04 --- /dev/null +++ b/dell_scripts/bootfromcdonce.sh @@ -0,0 +1,16 @@ +#!/bin/bash + +#### IMPORTANT: This script is only meant to show how to implement required scripts to make custom hardware compatible with FakeFish. Dell hardware is supported by the `idrac-virtualmedia` provider in Metal3. +#### This script has to set the server's boot to once from cd and return 0 if operation succeeded, 1 otherwise + +/opt/dell/srvadmin/bin/idracadm7 -r 192.168.1.10 -u root -p calvin set iDRAC.VirtualMedia.BootOnce 1 +if [ $? -eq 0 ]; then + /opt/dell/srvadmin/bin/idracadm7 -r 192.168.1.10 -u root -p calvin set iDRAC.ServerBoot.FirstBootDevice VCD-DVD + if [ $? -eq 0 ]; then + exit 0 + else + exit 1 + fi +else + exit 1 +fi diff --git a/dell_scripts/mountcd.sh b/dell_scripts/mountcd.sh new file mode 100755 index 0000000..9cbc733 --- /dev/null +++ b/dell_scripts/mountcd.sh @@ -0,0 +1,19 @@ +#!/bin/bash + +#### IMPORTANT: This script is only meant to show how to implement required scripts to make custom hardware compatible with FakeFish. Dell hardware is supported by the `idrac-virtualmedia` provider in Metal3. +#### This script has to mount the iso in the server's virtualmedia and return 0 if operation succeeded, 1 otherwise +#### Note: Iso image to mount will be received as the first argument ($1) + +ISO=${1} + +# Disconnect image just in case +/opt/dell/srvadmin/bin/idracadm7 -r 192.168.1.10 -u root -p calvin remoteimage -d + +# Connect image +/opt/dell/srvadmin/bin/idracadm7 -r 192.168.1.10 -u root -p calvin remoteimage -c -l ${ISO} + +if ! /opt/dell/srvadmin/bin/idracadm7 -r 192.168.1.10 -u root -p calvin remoteimage -s | grep ${ISO}; then + exit 1 +fi + +exit 0 diff --git a/dell_scripts/poweroff.sh b/dell_scripts/poweroff.sh new file mode 100755 index 0000000..4112a05 --- /dev/null +++ b/dell_scripts/poweroff.sh @@ -0,0 +1,13 @@ +#!/bin/bash + +#### IMPORTANT: This script is only meant to show how to implement required scripts to make custom hardware compatible with FakeFish. Dell hardware is supported by the `idrac-virtualmedia` provider in Metal3. +#### This script has to poweroff the server and return 0 if operation succeeded, 1 otherwise + +/opt/dell/srvadmin/bin/idracadm7 -r 192.168.1.10 -u root -p calvin serveraction powerdown +if [ $? -eq 0 ]; then + exit 0 +else + exit 1 +fi + + diff --git a/dell_scripts/poweron.sh b/dell_scripts/poweron.sh new file mode 100755 index 0000000..c46816b --- /dev/null +++ b/dell_scripts/poweron.sh @@ -0,0 +1,11 @@ +#!/bin/bash + +#### IMPORTANT: This script is only meant to show how to implement required scripts to make custom hardware compatible with FakeFish. Dell hardware is supported by the `idrac-virtualmedia` provider in Metal3. +#### This script has to poweron the server and return 0 if operation succeeded, 1 otherwise + +/opt/dell/srvadmin/bin/idracadm7 -r 192.168.1.10 -u root -p calvin serveraction powerup +if [ $? -eq 0 ]; then + exit 0 +else + exit 1 +fi diff --git a/dell_scripts/unmountcd.sh b/dell_scripts/unmountcd.sh new file mode 100755 index 0000000..7e6f12c --- /dev/null +++ b/dell_scripts/unmountcd.sh @@ -0,0 +1,12 @@ +#!/bin/bash + +#### IMPORTANT: This script is only meant to show how to implement required scripts to make custom hardware compatible with FakeFish. Dell hardware is supported by the `idrac-virtualmedia` provider in Metal3. +#### This script has to unmount the iso from the server's virtualmedia and return 0 if operation succeeded, 1 otherwise + +# Disconnect image +/opt/dell/srvadmin/bin/idracadm7 -r 192.168.1.10 -u root -p calvin remoteimage -d +if [ $? -eq 0 ]; then + exit 0 +else + exit 1 +fi