CURE - GUI

4 minute read

Previous posts in this series:

As described in my previous posts, Micke took the responsibility of setting up and coding the GUI parts of CURE. In this post I’ll try to describe the setup, even though I’m not 100% sure what the hell I’m talking about… But I’ll give it a shot!

Server and App

Micke made some decisions regarding the GUI and went about installing the components needed on a fresh Ubuntu VM, steal what needed to be stolen and code what needed to be coded. Besides PostgreSQL, Nginx and Python 3.6.6 was installed. He decided to run the GUI as a Gunicorn app within a venv virtual environment, so also these python modules were installed.

Create a user to host and run the app and add it to www-data group (nginx process user):

sudo useradd -m cureweb
sudo passwd cureweb
sudo usermod -a -G www-data cureweb

App folder structure.

In /home/local/cureweb/cure we find (approximate) this folder structure:

Name Type Description
app folder The app directory for the CURE GUI app
migration folder Flask-Migrate extension (for SQLAlchemy database migrations )
venv folder The venv module folder
.env file The environment variables and secrets
config.py file Flask and sql config file
requirements.txt file Python pip requirements file (?)
run.py file Starts the app

If we take a closer look in the app folder we find this (approximate) content:

Name Type Description
static folder the static content such as css, fonts, images, javascript
templates folder the HTML templates
init.py file The app ini file to load SQLAlchemy, Flask etc.
api.py file Used for the “snooze” functionality on a detector
auth.py file For authenticating to LDAP (Active Directory)
forms.py file For defining the Jinja2 flaskwtf form for login
models.py file Data modeling
views.py file The routing (this is where the frontend magic happens)

And if we look in the static folder we find this (approximate) content:

Name Type Description
css folder CSS for icons, menu and browser support. mostly borrowed.
fonts folder Fonts
img folder Images
js folder Javascript such as jquery, modernizr, sortable etc.
sound folder sound (for audio warning on red alert)

And if we finally peek in the templates folder we find this (approximate) content:

Name Type Description
_detector.html file How all detector square should look-color, snooze, text, links etc.
base.html file The base template. Contains menue, js, css etc.
compact.html file Compact mode template
compact_detector.html file Compact mode template
description.html file Custom details of detector events with links etc
history.html file To get all historical events for a detector
index.html file The index file
login.html file Jinja specific to render the login form

You can find the files and folders (of importance) here

Create a service for the app.

In order for the app to run at startup, create a service.

sudo nano /etc/systemd/system/cure.service

With this content:

[Unit]
Description=Cure webapp service
After=network.target

[Service]
User=cureweb
Group=www-data
Restart=always
RestartSec=1
WorkingDirectory=/home/local/cureweb/cure
Environment="PATH=/home/local/cureweb/cure/venv/bin"
ExecStart=/home/local/cureweb/cure/venv/bin/gunicorn --workers 3 --bind unix:cure.sock run:app

[Install]
WantedBy=multi-user.target

The service can then be started and enabled.

sudo systemctl start cure
sudo systemctl enable cure

Configure nginx

With a command like this, an nginx config is made

sudo nano /etc/nginx/sites-enabled/cure

And with content similar to this

server {
    # listen on port 80 (http)
    listen 80;
    server_name cure.company.xx;
    location / {
        # redirect any requests to the same URL but on https
        return 301 https://$host$request_uri;
    }
}
server {
    # listen on port 443 (https)
    listen 443 ssl;
    server_name cure.company.xx;

    ssl                     on;
    ssl_certificate         /etc/nginx/certs/mycert.crt;
    ssl_certificate_key     /etc/nginx/certs/mycert.key;
    ssl_session_timeout     5m;
    ssl_protocols                   TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA';
    ssl_prefer_server_ciphers       on;

    # write access and error logs to /var/log
    access_log /var/log/cure_access.log;
    error_log /var/log/cure_error.log;

    location / {
        # forward application requests to the gunicorn server
        proxy_pass http://unix:/home/local/cureweb/cure/cure.sock;
        proxy_redirect off;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }

    location /static {
        # handle static files directly, without forwarding to the application
        alias /home/local/cureweb/cure/app/static;
        expires 30d;
    }
}

The result

This gif gives an idea of how the landing page will look with different levels of alerts.

Cure GUI landing page

When clicking the headline of a detector, you get the details

Cure GUI detector details

And when toggling the headline on the detector details page, you see some details on the detector itself, such as id, heartbeat, environment, status and history.

Cure GUI detector headline

And when clicking the history link you get an overview of the historical statuses for the specific detector.

Cure GUI detector history

UPDATED ON 2019-05-03 I just took the time to go through what Micke has been working on, pretty much on his own, on and off during the last 6 months. Many of my assumptions of the GUI was wrong and/or has been changed during this time, so I’ve updated this post, complete with some images on how it currently looks.

The personal experiences, viewpoints and opinions expressed in this blog post are my own and in no way represent those of the company.