Skip to content

Commit

Permalink
Added arguments to fakefish + customizable tls settings
Browse files Browse the repository at this point in the history
  • Loading branch information
mvazquezc committed Jun 20, 2022
1 parent 7633e1d commit 6d44e8e
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 22 deletions.
19 changes: 16 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ A [Containerfile](./custom_scripts/Containerfile) is included, so users can buil

> **NOTE**: Check the Makefile vars to customize the output container image naming and tag.
> **NOTE2**: If you plan to run self-signed TLS certs, add them to the app/ folder before running the make command and make sure the cert names are properly configured in the Containerfile.
~~~sh
make build-custom
~~~
Expand All @@ -39,14 +41,25 @@ A [Containerfile](./custom_scripts/Containerfile) is included, so users can buil

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 and another one to configure which BMC IP it provides service to. On top of that, you can do a bind mount for the folder containing the scripts for managing that specific server or use the scripts inside the container image.
Currently, FakeFish exposes the following arguments:

|Argument|What is it used for|Default|Required|
|--------|-------------------|-------|--------|
|`--tls-mode`|Configures TLS for FakeFish, three available modes: `adhoc` (FakeFish generated certs), `self-signed` (user provided certs), `disabled` (TLS disabled).|`adhoc`|No|
|`--cert-file`|Configures the certificate public key that will be used in `self-signed` tls mode.|`./cert.pem`|No|
|`--key-file`|Configures the certificate private key that will be used in `self-signed` tls mode.|`./cert.key`|No|
|`--remote-bmc` or `-r`|Defines the BMC IP a FakeFish instance will connect to.|`None`|Yes|
|`--listen-port` or `-p`|Defines the port a FakeFish instance will listen on.|`9000`|No|
|`--debug` or `-d`|Starts a FakeFish instance in debug mode.|`False`|No|

Since you will be potentially running multiple FakeFish instances, you will make use of the `--listen-port` argument to configure in which port a given FakeFish instance listens on and `--remote-bmc` to configure which BMC IP it provides service to. On top of that, you can do a bind mount for the folder containing the scripts for managing that specific server or use the scripts inside the container image.

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 -e BMC_IP=172.20.10.10 -v $PWD/dell_scripts:/opt/fakefish/custom_scripts:z quay.io/mavazque/fakefish:v0
podman run -p 9000:9000 -v $PWD/dell_scripts:/opt/fakefish/custom_scripts:z quay.io/mavazque/fakefish:latest --listen-port 9000 --remote-bmc 172.20.10.10

sudo firewall-cmd --add-port=9000/tcp
~~~
Expand All @@ -64,7 +77,7 @@ In a successful execution you should see something like this in the logs:
- Starting FakeFish

~~~sh
$ podman run -p 9000:9000 -e PORT=9000 -e BMC_IP=172.20.10.10 -v $PWD/dell_scripts:/opt/fakefish/custom_scripts:z quay.io/mavazque/fakefish:v0
$ podman run -p 9000:9000 -v $PWD/dell_scripts:/opt/fakefish/custom_scripts:z quay.io/mavazque/fakefish:latest --listen-port 9000 --remote-bmc 172.20.10.10

* Serving Flask app 'fakefish' (lazy loading)
* Environment: production
Expand Down
46 changes: 29 additions & 17 deletions app/fakefish.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,14 @@
import os
import requests
import subprocess
import argparse
from datetime import datetime
from werkzeug.http import parse_authorization_header
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 = bool(config['DEBUG']) if 'DEBUG' in list(config) else False
port = int(config['PORT']) if 'PORT' in list(config) else 9000

@app.route('/redfish/v1/')
def root_resource():
return flask.render_template('root.json')
Expand Down Expand Up @@ -172,21 +164,41 @@ def set_env_vars(bmc_endpoint, username, password):
my_env["BMC_PASSWORD"] = password
return my_env

def run():
def run(port, debug, tls_mode, cert_file, key_file):
"""
"""
app.run(host='0.0.0.0', port=port, debug=debug, ssl_context='adhoc')
if tls_mode == 'adhoc':
app.run(host='::', port=port, debug=debug, ssl_context='adhoc')
elif tls_mode == 'disabled':
app.run(host='::', port=port, debug=debug)
else:
if os.path.exists(cert_file) and os.path.exists(key_file):
app.run(host='::', port=port, debug=debug, ssl_context=(cert_file, key_file))
else:
app.logger.error('%s or %s not found.', cert_file, key_file)
exit()


if __name__ == '__main__':

bmc_ip = os.environ.get('BMC_IP', None)
if bmc_ip is None:
app.logger.error('Configure the BMC IP using the environment variable BMC_IP')
exit()
parser = argparse.ArgumentParser(description='FakeFish, an experimental RedFish proxy that calls shell scripts for executing hardware actions.')
parser.add_argument('--tls-mode', type=str, choices=['adhoc', 'self-signed', 'disabled'], default='adhoc', help='Configures TLS mode. \
\'self-signed\' mode expects users to configure a cert and a key files. (default: %(default)s)')
parser.add_argument('--cert-file', type=str, default='./cert.pem', help='Path to the certificate public key file. (default: %(default)s)')
parser.add_argument('--key-file', type=str, default='./cert.key', help='Path to the certificate private key file. (default: %(default)s)')
parser.add_argument('-r', '--remote-bmc', type=str, required=True, help='The BMC IP this FakeFish instance will connect to. e.g: 192.168.1.10')
parser.add_argument('-p','--listen-port', type=int, required=False, default=9000, help='The port where this FakeFish instance will listen for connections.')
parser.add_argument('--debug', action='store_true')
args = parser.parse_args()

bmc_ip = args.remote_bmc
port = args.listen_port
debug = args.debug
tls_mode = args.tls_mode
cert_file = args.cert_file
key_file = args.key_file

inserted = False
image_url = ''
power_state = 'On'
run()
run(port, debug, tls_mode, cert_file, key_file)
5 changes: 4 additions & 1 deletion custom_scripts/Containerfile
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,16 @@ RUN set -x && \

RUN mkdir -p /opt/fakefish/

COPY app/fakefish.py /opt/fakefish/fakefish.py
# The stars in the command below will only copy those files if they exist
COPY app/fakefish.py app/cert.pem* app/cert.key* /opt/fakefish/

ADD app/templates /opt/fakefish/templates
ADD custom_scripts /opt/fakefish/custom_scripts

WORKDIR /opt/fakefish/

RUN chown -R 1024 /opt/fakefish/

USER 1024

ENTRYPOINT ["/usr/bin/python3", "-u", "/opt/fakefish/fakefish.py"]
5 changes: 4 additions & 1 deletion dell_scripts/Containerfile
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,16 @@ RUN set -x && \

RUN mkdir -p /opt/fakefish/

COPY app/fakefish.py /opt/fakefish/fakefish.py
# The stars in the command below will only copy those files if they exist
COPY app/fakefish.py app/cert.pem* app/cert.key* /opt/fakefish/

ADD app/templates /opt/fakefish/templates
ADD dell_scripts /opt/fakefish/custom_scripts

WORKDIR /opt/fakefish/

RUN chown -R 1024 /opt/fakefish/

USER 1024

ENTRYPOINT ["/usr/bin/python3", "-u", "/opt/fakefish/fakefish.py"]

0 comments on commit 6d44e8e

Please sign in to comment.