Skip to main content

Developing and deploying a Python Application: Dev/Test

This tutorial gives some examples for easing development of applications running in the Avassa platform. I.e., some pointers to how you can develop the application on one machine and connect to an Avassa site-host on another machine during the development phase. NOTE, it's of course possible to develop on a machine where the Edge Enforcer is installed.

Please make sure you read the introduction first.

Pipfile

Note the addition of avassa-client below.

Pipfile
[[source]]
url = "https://pypi.org/simple"
verify_ssl = true
name = "pypi"

[packages]
avassa-client = "*"

[dev-packages]

[requires]
python_version = "3"

Python code

The python code used as an example, see below for explanations.

demo.py
import json
import logging
import os
import time
import avassa_client

logger = logging.getLogger(__name__)
logging.basicConfig(level=logging.INFO)

# By default we will connect to api.internal, i.e. the Edge Enforcer
edge_enforcer_host=os.environ.get('EE_HOST', default="https://api.internal:4646")
role_id=os.environ.get('APPROLE_ID', default=None)

secret_id = os.environ.get('APPROLE_SECRET_ID', default=None)
if secret_id:
client=avassa_client.approle_login(host=edge_enforcer_host, role_id=role_id, secret_id=secret_id)
logger.info('Successfully connected using approle')
else:
# If no secret/role id, assume username/password
client=avassa_client.login(host=edge_enforcer_host, username=os.environ['EE_USER'], password=os.environ['EE_PASSWORD'])
logger.info('Successfully connected using username/password')

app_version=os.environ.get('VERSION', 'unknown version')
logger.info(f'Starting {app_version}')

# Get a list of applications, NOTE keys=true to only return a list of apps
(code, msg, _, applications) = avassa_client.get_request(client, '/v1/state/applications?keys=true')
if code == 200:
applications = json.loads(applications)
for app in applications:
logger.info(app)
else:
logger.error(f'Failed to get apps: {msg}')


# Here we can generate a custom alert
payload = {
'id': 'demo-alert-id',
'name': 'demo application',
'description': 'Fredrik is a bad hacker and caused this error!',
'severity': 'warning'
}
avassa_client.post_request(client, '/v1/alert', payload)

# Then we can clear the alert

payload = {
'id': 'demo-alert-id',
'name': 'demo application',
}
avassa_client.post_request(client, '/v1/clear', payload)

while True:
logger.info("I'm still alive...")
time.sleep(10)

Alerts in the UI

The example code will generate (and clear) alerts, in the UI it looks like this alert-list

Testing with Edge Enforcer APIs

While developing the application, it is possible to shorten the dev/test cycle by running the code on your development machine. If any of the Avassa site hosts are reachable from the development machine, you can enabled outside (outside the machine) access to the Edge Enforcer APIs by setting management-ipv4-access-list in the site configuration:

name: stockholm-cluster
...
management-ipv4-access-list:
- 0.0.0.0/0

With the python code getting settings from the environment, we can now run the python code locally.

note

Make sure you replace the IP address and credentials below. In the example, the Edge Enforcer runs on IP 192.168.100.64.

export API_CA_CERT=$(supctl -k --host=192.168.100.64:4646 do get-api-ca-cert | jq -r ".cert") 
export EE_HOST="https://192.168.100.64:4646"
export EE_USER="fredrik@example.com"
export EE_PASSWORD='my secret password'
python3 demo.py
INFO:__main__:Successfully connected using username/password
INFO:__main__:Starting unknown version
INFO:__main__:I'm still alive...

Note that we declare APPROLE_SECRET_ID and API_CA_CERT as environment variables in the application specification.

note

This assumes an approle with the name demo is declared.

There are multiple SYS_ variables an application can use, see the reference docs.

demo.app.yaml
name: demo
# During development I keep version commented out
# otherwise I have to change the version every time I test a new app spec.
# Once out of the development phase, I always set a version.
# version: "1.0"
services:
- name: demo-svc
mode: replicated
replicas: 1
containers:
- name: demo
image: registry-1.docker.io/fredrikjanssonse/avassa-app-tutorial:v1.0
approle: demo
env:
APPROLE_SECRET_ID: ${SYS_APPROLE_SECRET_ID}
API_CA_CERT: ${SYS_API_CA_CERT}