Commit 963ed803 authored by dobli's avatar dobli
Browse files

added ui frame to file generation

parent 9f9d8bf0
#!/usr/bin/env python3
""" Python module to assist creating and maintaining docker openHab stacks."""
import crypt
from enum import Enum
import logging
import os
from hashlib import md5
......@@ -42,10 +43,11 @@ COMPOSE_NAME = 'docker-stack.yml'
SKELETON_NAME = 'docker-skeleton.yml'
TEMPLATES_NAME = 'docker-templates.yml'
CONFIG_DIRS = ['mosquitto', 'nodered', 'ssh',
'traefik', 'volumerize', 'postgres']
'traefik', 'volumerize', 'postgres', 'pb-framr']
TEMPLATE_FILES = [
'mosquitto/mosquitto.conf', 'nodered/nodered_package.json',
'nodered/nodered_settings.js', 'ssh/sshd_config', 'traefik/traefik.toml'
'pb-framr/logo.svg', 'nodered/nodered_settings.js',
'ssh/sshd_config', 'traefik/traefik.toml'
]
EDIT_FILES = {
"mosquitto_passwords": "mosquitto/mosquitto_passwords",
......@@ -56,7 +58,8 @@ EDIT_FILES = {
"known_hosts": "ssh/known_hosts",
"backup_config": "volumerize/backup_config.json",
"postgres_user": "postgres/user",
"postgres_passwd": "postgres/passwd"
"postgres_passwd": "postgres/passwd",
"pb_framr_pages": "pb-framr/pages.json"
}
CONSTRAINTS = {"building": "node.labels.building"}
SERVICES = {
......@@ -66,6 +69,10 @@ SERVICES = {
"postgres": "postgres_X",
"mqtt": "mqtt_X"
}
FRONTEND_SERVICES = {
"openhab": "OpenHAB",
"nodered": "Node-RED"
}
# Default Swarm port
SWARM_PORT = 2377
......@@ -73,6 +80,22 @@ SWARM_PORT = 2377
UID = 9001
# Username for admin
ADMIN_USER = 'ohadmin'
class Service(Enum):
SFTP = ("SFTP", "sftp_X", False)
OPENHAB = ("OpenHAB", "openhab_X", True, '/', 'dashboard')
NODERED = ("Node-RED", "nodered_X", True, 'nodered', 'ballot')
POSTGRES = ("Postgre SQL", "postgres_X", False)
MQTT = ("Mosquitto MQTT Broker", "mqtt_X", False)
def __init__(self, fullname, compose_entry, frontend,
prefix=None, icon=None):
self.fullname = fullname
self.compose_entry = compose_entry
self.frontend = frontend
self.prefix = prefix
self.icon = icon
# >>>
......@@ -399,6 +422,25 @@ def generate_traefik_user_line(username, password):
return line
def generate_pb_framr_entry(host, service):
"""Generates a single entry of the framr file
:host: host this entry is intended for
:service: entry from service enum
:returns: a dict fitting the asked entry
"""
entry = {}
entry['title'] = service.fullname
if service.prefix == "/":
entry['url'] = f'http://{host}/'
pass
else:
entry['url'] = f'/{service.prefix}_{host}'
entry['icon'] = service.icon
return entry
def generate_mosquitto_file(base_dir, username, password):
"""Generates a mosquitto password file using mosquitto_passwd system tool
......@@ -531,6 +573,26 @@ def generate_volumerize_file(base_dir, hosts):
base_dir, EDIT_FILES['backup_config'], configs, json=True)
def generate_pb_framr_file(base_dir, frames):
"""Generates config for pb framr landing page
:base_dir: path that contains custom config folder
:frames: a dict that contains hosts with matching name and services
"""
configs = []
for f in frames:
building = {
'instance': f['building'],
'entries': [generate_pb_framr_entry(f['host'], s)
for s in f['services'] if s.frontend]
}
configs.append(building)
create_or_replace_config_file(
base_dir, EDIT_FILES['pb_framr_pages'], configs, json=True)
def create_or_replace_config_file(base_dir, config_path, content, json=False):
"""Creates or replaces a config file with new content
......@@ -545,8 +607,6 @@ def create_or_replace_config_file(base_dir, config_path, content, json=False):
json.dump(content, file, indent=2)
else:
file.write(content)
# >>>
......@@ -929,8 +989,15 @@ def init_menu(args):
generate_id_rsa_files(base_dir)
generate_host_key_files(base_dir, hosts)
frames = []
for i, host in enumerate(hosts):
init_machine_menu(base_dir, host, i)
building, services = init_machine_menu(base_dir, host, i)
frames.append({'host': host,
'building': building, 'services': services})
# When frames is not empty generate frame config
if frames:
generate_pb_framr_file(base_dir, frames)
# print(answers)
print(f"Configuration files for {stack_name} generated in {base_dir}")
......@@ -949,25 +1016,25 @@ def init_machine_menu(base_dir, host, increment):
:base_dir: Directory of config files
:host: docker-machine host
:increment: incrementing number to ensure ports are unique
:return: choosen building name and services
"""
# Prompt for services
building = qust.text(f'Choose a name for building on server {host}',
default=f'{host}', style=st).ask()
services = qust.checkbox(f'What services shall {host} provide?',
choices=generate_cb_choices(SERVICES.keys(),
checked=True),
choices=generate_cb_service_choices(checked=True),
style=st).ask()
if 'sftp' in services:
if Service.SFTP in services:
add_sftp_service(base_dir, host, increment)
if 'openhab' in services:
if Service.OPENHAB in services:
add_openhab_service(base_dir, host)
if 'nodered' in services:
if Service.NODERED in services:
add_nodered_service(base_dir, host)
if 'mqtt' in services:
if Service.MQTT in services:
add_mqtt_service(base_dir, host, increment)
if 'postgres' in services:
if Service.POSTGRES in services:
add_postgres_service(base_dir, host)
print(building)
return building, services
# *** Exec Menu Entries ***
......@@ -1008,6 +1075,17 @@ def generate_cb_choices(list, checked=False):
return [{'name': m, 'checked': checked} for m in list]
def generate_cb_service_choices(checked=False):
"""Generates checkbox entries for the sevice enum
:checked: if true, selections will be checked by default
:returns: A list of dicts with name keys
"""
return [
{'name': s.fullname, 'value': s, 'checked': checked} for s in Service
]
def docker_client_prompt(message_details=''):
"""Show list of docker machines and return selection
......
......@@ -37,6 +37,10 @@ configs:
file: ./postgres/user
postgres_passwd:
file: ./postgres/passwd
landing_logo:
file: ./pb-framr/logo.svg
landing_pages:
file: ./pb-framr/pages.json
volumes:
openhab_addons:
......@@ -71,3 +75,25 @@ services:
placement:
constraints:
- node.role == manager
landing:
image: doblix/pb-framr
networks:
- habnet
configs:
- source: landing_logo
target: /usr/share/nginx/html/logo.svg
- source: landing_pages
target: /usr/share/nginx/html/pages.json
deploy:
labels:
- traefik.docker.network=habnet
- traefik.port=80
- traefik.backend=landing
- traefik.main.frontend.priority=2
- traefik.main.frontend.redirect.regex=^(.*)/landing$$
- traefik.main.frontend.redirect.replacement=$$1/landing/
- traefik.main.frontend.rule=PathPrefix:/landing;ReplacePathRegex:^/landing/(.*)
/$$1
placement:
constraints:
- node.role == manager
......@@ -37,6 +37,10 @@ configs:
file: ./postgres/user
postgres_passwd:
file: ./postgres/passwd
landing_logo:
file: ./pb-framr/logo.svg
landing_pages:
file: ./pb-framr/pages.json
volumes:
openhab_addons:
......
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
width="105.83334mm"
height="105.83334mm"
viewBox="0 0 105.83334 105.83334"
version="1.1"
id="svg8">
<defs
id="defs2" />
<metadata
id="metadata5">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
id="layer1"
transform="translate(-28.600533,-86.069031)">
<circle
style="opacity:1;fill:#ff0000;fill-opacity:1;stroke:none;stroke-width:0.12197291;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
id="path881"
cx="81.517204"
cy="138.9857"
r="52.916672" />
<g
transform="matrix(1.4629556,0,0,1.4629556,-15.525955,-77.21686)"
id="g891"
style="fill:#ffffff">
<text
id="text859"
y="143.47997"
x="52.784073"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:10.58333302px;line-height:1.25;font-family:OpenSans;-inkscape-font-specification:OpenSans;letter-spacing:0px;word-spacing:0px;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.26458332"
xml:space="preserve"><tspan
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:12.69999981px;font-family:OpenSans;-inkscape-font-specification:OpenSans;fill:#ffffff;stroke-width:0.26458332"
y="143.47997"
x="52.784073"
id="tspan857">Your</tspan></text>
<text
id="text859-8"
y="158.60701"
x="48.7006"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:10.58333302px;line-height:1.25;font-family:Z003;-inkscape-font-specification:Z003;letter-spacing:0px;word-spacing:0px;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.26458332"
xml:space="preserve"><tspan
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:12.69999981px;font-family:OpenSans;-inkscape-font-specification:'OpenSans Bold';fill:#ffffff;stroke-width:0.26458332"
y="158.60701"
x="48.7006"
id="tspan857-9">Logo</tspan></text>
</g>
</g>
</svg>
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment