Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
smartpublicbuilding
openhab-pb-stack
Commits
963ed803
Commit
963ed803
authored
Feb 12, 2019
by
dobli
Browse files
added ui frame to file generation
parent
9f9d8bf0
Changes
4
Show whitespace changes
Inline
Side-by-side
building_manager.py
View file @
963ed803
#!/usr/bin/env python3
#!/usr/bin/env python3
""" Python module to assist creating and maintaining docker openHab stacks."""
""" Python module to assist creating and maintaining docker openHab stacks."""
import
crypt
import
crypt
from
enum
import
Enum
import
logging
import
logging
import
os
import
os
from
hashlib
import
md5
from
hashlib
import
md5
...
@@ -42,10 +43,11 @@ COMPOSE_NAME = 'docker-stack.yml'
...
@@ -42,10 +43,11 @@ COMPOSE_NAME = 'docker-stack.yml'
SKELETON_NAME
=
'docker-skeleton.yml'
SKELETON_NAME
=
'docker-skeleton.yml'
TEMPLATES_NAME
=
'docker-templates.yml'
TEMPLATES_NAME
=
'docker-templates.yml'
CONFIG_DIRS
=
[
'mosquitto'
,
'nodered'
,
'ssh'
,
CONFIG_DIRS
=
[
'mosquitto'
,
'nodered'
,
'ssh'
,
'traefik'
,
'volumerize'
,
'postgres'
]
'traefik'
,
'volumerize'
,
'postgres'
,
'pb-framr'
]
TEMPLATE_FILES
=
[
TEMPLATE_FILES
=
[
'mosquitto/mosquitto.conf'
,
'nodered/nodered_package.json'
,
'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
=
{
EDIT_FILES
=
{
"mosquitto_passwords"
:
"mosquitto/mosquitto_passwords"
,
"mosquitto_passwords"
:
"mosquitto/mosquitto_passwords"
,
...
@@ -56,7 +58,8 @@ EDIT_FILES = {
...
@@ -56,7 +58,8 @@ EDIT_FILES = {
"known_hosts"
:
"ssh/known_hosts"
,
"known_hosts"
:
"ssh/known_hosts"
,
"backup_config"
:
"volumerize/backup_config.json"
,
"backup_config"
:
"volumerize/backup_config.json"
,
"postgres_user"
:
"postgres/user"
,
"postgres_user"
:
"postgres/user"
,
"postgres_passwd"
:
"postgres/passwd"
"postgres_passwd"
:
"postgres/passwd"
,
"pb_framr_pages"
:
"pb-framr/pages.json"
}
}
CONSTRAINTS
=
{
"building"
:
"node.labels.building"
}
CONSTRAINTS
=
{
"building"
:
"node.labels.building"
}
SERVICES
=
{
SERVICES
=
{
...
@@ -66,6 +69,10 @@ SERVICES = {
...
@@ -66,6 +69,10 @@ SERVICES = {
"postgres"
:
"postgres_X"
,
"postgres"
:
"postgres_X"
,
"mqtt"
:
"mqtt_X"
"mqtt"
:
"mqtt_X"
}
}
FRONTEND_SERVICES
=
{
"openhab"
:
"OpenHAB"
,
"nodered"
:
"Node-RED"
}
# Default Swarm port
# Default Swarm port
SWARM_PORT
=
2377
SWARM_PORT
=
2377
...
@@ -73,6 +80,22 @@ SWARM_PORT = 2377
...
@@ -73,6 +80,22 @@ SWARM_PORT = 2377
UID
=
9001
UID
=
9001
# Username for admin
# Username for admin
ADMIN_USER
=
'ohadmin'
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):
...
@@ -399,6 +422,25 @@ def generate_traefik_user_line(username, password):
return
line
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
):
def
generate_mosquitto_file
(
base_dir
,
username
,
password
):
"""Generates a mosquitto password file using mosquitto_passwd system tool
"""Generates a mosquitto password file using mosquitto_passwd system tool
...
@@ -531,6 +573,26 @@ def generate_volumerize_file(base_dir, hosts):
...
@@ -531,6 +573,26 @@ def generate_volumerize_file(base_dir, hosts):
base_dir
,
EDIT_FILES
[
'backup_config'
],
configs
,
json
=
True
)
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
):
def
create_or_replace_config_file
(
base_dir
,
config_path
,
content
,
json
=
False
):
"""Creates or replaces a config file with new content
"""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):
...
@@ -545,8 +607,6 @@ def create_or_replace_config_file(base_dir, config_path, content, json=False):
json
.
dump
(
content
,
file
,
indent
=
2
)
json
.
dump
(
content
,
file
,
indent
=
2
)
else
:
else
:
file
.
write
(
content
)
file
.
write
(
content
)
# >>>
# >>>
...
@@ -929,8 +989,15 @@ def init_menu(args):
...
@@ -929,8 +989,15 @@ def init_menu(args):
generate_id_rsa_files
(
base_dir
)
generate_id_rsa_files
(
base_dir
)
generate_host_key_files
(
base_dir
,
hosts
)
generate_host_key_files
(
base_dir
,
hosts
)
frames
=
[]
for
i
,
host
in
enumerate
(
hosts
):
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(answers)
print
(
f
"Configuration files for
{
stack_name
}
generated in
{
base_dir
}
"
)
print
(
f
"Configuration files for
{
stack_name
}
generated in
{
base_dir
}
"
)
...
@@ -949,25 +1016,25 @@ def init_machine_menu(base_dir, host, increment):
...
@@ -949,25 +1016,25 @@ def init_machine_menu(base_dir, host, increment):
:base_dir: Directory of config files
:base_dir: Directory of config files
:host: docker-machine host
:host: docker-machine host
:increment: incrementing number to ensure ports are unique
:increment: incrementing number to ensure ports are unique
:return: choosen building name and services
"""
"""
# Prompt for services
# Prompt for services
building
=
qust
.
text
(
f
'Choose a name for building on server
{
host
}
'
,
building
=
qust
.
text
(
f
'Choose a name for building on server
{
host
}
'
,
default
=
f
'
{
host
}
'
,
style
=
st
).
ask
()
default
=
f
'
{
host
}
'
,
style
=
st
).
ask
()
services
=
qust
.
checkbox
(
f
'What services shall
{
host
}
provide?'
,
services
=
qust
.
checkbox
(
f
'What services shall
{
host
}
provide?'
,
choices
=
generate_cb_choices
(
SERVICES
.
keys
(),
choices
=
generate_cb_service_choices
(
checked
=
True
),
checked
=
True
),
style
=
st
).
ask
()
style
=
st
).
ask
()
if
'sftp'
in
services
:
if
Service
.
SFTP
in
services
:
add_sftp_service
(
base_dir
,
host
,
increment
)
add_sftp_service
(
base_dir
,
host
,
increment
)
if
'openhab'
in
services
:
if
Service
.
OPENHAB
in
services
:
add_openhab_service
(
base_dir
,
host
)
add_openhab_service
(
base_dir
,
host
)
if
'nodered'
in
services
:
if
Service
.
NODERED
in
services
:
add_nodered_service
(
base_dir
,
host
)
add_nodered_service
(
base_dir
,
host
)
if
'mqtt'
in
services
:
if
Service
.
MQTT
in
services
:
add_mqtt_service
(
base_dir
,
host
,
increment
)
add_mqtt_service
(
base_dir
,
host
,
increment
)
if
'postgres'
in
services
:
if
Service
.
POSTGRES
in
services
:
add_postgres_service
(
base_dir
,
host
)
add_postgres_service
(
base_dir
,
host
)
print
(
building
)
return
building
,
services
# *** Exec Menu Entries ***
# *** Exec Menu Entries ***
...
@@ -1008,6 +1075,17 @@ def generate_cb_choices(list, checked=False):
...
@@ -1008,6 +1075,17 @@ def generate_cb_choices(list, checked=False):
return
[{
'name'
:
m
,
'checked'
:
checked
}
for
m
in
list
]
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
=
''
):
def
docker_client_prompt
(
message_details
=
''
):
"""Show list of docker machines and return selection
"""Show list of docker machines and return selection
...
...
template_configs/docker-skeleton.yml
View file @
963ed803
...
@@ -37,6 +37,10 @@ configs:
...
@@ -37,6 +37,10 @@ configs:
file
:
./postgres/user
file
:
./postgres/user
postgres_passwd
:
postgres_passwd
:
file
:
./postgres/passwd
file
:
./postgres/passwd
landing_logo
:
file
:
./pb-framr/logo.svg
landing_pages
:
file
:
./pb-framr/pages.json
volumes
:
volumes
:
openhab_addons
:
openhab_addons
:
...
@@ -71,3 +75,25 @@ services:
...
@@ -71,3 +75,25 @@ services:
placement
:
placement
:
constraints
:
constraints
:
-
node.role == manager
-
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
template_configs/docker-templates.yml
View file @
963ed803
...
@@ -37,6 +37,10 @@ configs:
...
@@ -37,6 +37,10 @@ configs:
file
:
./postgres/user
file
:
./postgres/user
postgres_passwd
:
postgres_passwd
:
file
:
./postgres/passwd
file
:
./postgres/passwd
landing_logo
:
file
:
./pb-framr/logo.svg
landing_pages
:
file
:
./pb-framr/pages.json
volumes
:
volumes
:
openhab_addons
:
openhab_addons
:
...
...
template_configs/pb-framr/logo.svg
0 → 100644
View file @
963ed803
<?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>
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment