feat: Initial commit 🎉

Set up the foundational structure for the MikroWizard deployment repository, including:
- Docker Compose configuration for MikroFront, MikroMan, PostgreSQL, and Redis Stack.
- `prepare.sh` script for host environment preparation.
- Database initialization script (`init-db.sql`).
- `.env` template for centralized configuration.

This commit marks the beginning of a streamlined deployment process for MikroWizard!
This commit is contained in:
sepehr 2024-12-16 13:45:30 +03:00
commit a8f029ee38
80 changed files with 3429 additions and 0 deletions

66
mikroman/Dockerfile Normal file
View file

@ -0,0 +1,66 @@
FROM python:3.11-slim-bullseye
WORKDIR /app
RUN apt-get update
RUN apt-get -y install cron
RUN apt-get install -y iputils-ping
RUN apt-get install -y net-tools
RUN apt-get install -y git
RUN touch /var/log/cron.log
RUN git clone https://github.com/MikroWizard/mikroman.git /app
RUN set -ex \
&& buildDeps=' \
build-essential \
gcc \
' \
&& deps=' \
htop \
' \
&& apt-get install -y $buildDeps git $deps --no-install-recommends && rm -rf /var/lib/apt/lists/* \
&& pip install uWSGI==2.0.22 \
&& pip install -r /app/reqs.txt
RUN mkdir -p /conf
RUN cp /app/conf/loginscript.sh /etc/profile
COPY server-conf.json /conf/
ARG AM_I_IN_A_DOCKER_CONTAINER=Yes
COPY init.sh /app/
COPY initpy.py /app/
RUN chmod +x /app/init.sh
# background spooler dir
RUN mkdir /tmp/pysrv_spooler
# we don't need this file with Docker but uwsgi looks for it
RUN echo `date +%s` >/app/VERSION
EXPOSE 80
# our server config file
# - you should write your own config file and put OUTSIDE the repository
# since the config file contains secrets
# - here I use the sample template from repo
# - it is also possible to override the config with env variables, either here
# or in Amazon ECS or Kubernetes configuration
#COPY /app/real-server-config.json /app/real-server-config.json
# ENV PYSRV_DATABASE_HOST host.docker.internal
# ENV PYSRV_REDIS_HOST host.docker.internal
# ENV PYSRV_DATABASE_PASSWORD x
# build either a production or dev image
ARG BUILDMODE=production
ENV ENVBUILDMODE=$BUILDMODE
RUN echo "BUILDMODE $ENVBUILDMODE"
# run in shell mode with ENV expansion
RUN cd /app && bash init.sh

67
mikroman/init.sh Normal file
View file

@ -0,0 +1,67 @@
#!/bin/bash
# test if it is in build mode!
if [[ -z "${AM_I_IN_A_DOCKER_CONTAINER}" ]]; then
echo "Starting Mikroman ..."
else
exit 0
fi
CONTAINER_ALREADY_STARTED="CONTAINER_ALREADY_STARTED_PLACEHOLDER"
if [ ! -e $CONTAINER_ALREADY_STARTED ]; then
echo "-- Initializing the mikroman for first run --"
# YOUR_JUST_ONCE_LOGIC_HERE
cd /app && export PYTHONPATH=/app/py && export PYSRV_CONFIG_PATH=/conf/server-conf.json && python3 scripts/dbmigrate.py
cat << EOF1 | tee init.sql >/dev/null
INSERT INTO public.tasks( signal, name, status) VALUES ( 100, 'check-update', false);
INSERT INTO public.tasks( signal, name, status) VALUES ( 110, 'upgrade-firmware', false);
INSERT INTO public.tasks( signal, name, status) VALUES ( 120, 'backup', false);
INSERT INTO public.tasks( signal, name, status) VALUES ( 130, 'scanner', false);
INSERT INTO public.tasks( signal, name, status) VALUES ( 140, 'downloader', false);
INSERT INTO public.tasks( signal, name, status) VALUES ( 150, 'firmware-service', false);
INSERT INTO public.tasks( signal, name, status) VALUES ( 160, 'snipet-exec', false);
INSERT INTO public.sysconfig( key, value) VALUES ( 'scan_mode', 'mac');
INSERT INTO public.sysconfig( key, value) VALUES ( 'mac_scan_interval', '5');
INSERT INTO public.sysconfig( key, value) VALUES ( 'ip_scan_interval', '4');
INSERT INTO public.sysconfig( key, value) VALUES ( 'old_firmware_action', 'keep');
INSERT INTO public.sysconfig( key, value) VALUES ( 'default_user', '');
INSERT INTO public.sysconfig( key, value) VALUES ( 'default_password', '');
INSERT INTO public.sysconfig( key, value) VALUES ( 'old_version', '');
INSERT INTO public.sysconfig( key, value) VALUES ( 'latest_version', '');
INSERT INTO public.sysconfig( key, value) VALUES ( 'default_ip', '${MW_SERVER_IP}');
INSERT INTO public.sysconfig( key, value) VALUES ( 'rad_secret', '${MW_RAD_SECRET}');
INSERT INTO public.sysconfig( key, value) VALUES ( 'system_url', 'http://${MW_SERVER_IP}');
INSERT INTO public.sysconfig( key, value) VALUES ( 'force_perms', 'True');
INSERT INTO public.sysconfig( key, value) VALUES ( 'force_radius', 'True');
INSERT INTO public.sysconfig( key, value) VALUES ( 'force_syslog', 'True');
INSERT INTO public.sysconfig( key, value) VALUES ( 'safe_install', 'True');
INSERT INTO public.sysconfig( key, value) VALUES ( 'timezone', 'UTC');
INSERT INTO public.sysconfig( key, value) VALUES ( 'username', '');
INSERT INTO public.sysconfig( key, value) VALUES ( 'install_date', '');
INSERT INTO public.sysconfig( key, value) VALUES ( 'all_ip', '');
INSERT INTO public.device_groups( id, name ) VALUES (1, 'Default');
INSERT INTO public.users(username, first_name, last_name,email, role) VALUES ('system', 'system', '','system@localhost', 'disabled');
INSERT INTO public.users(id,username, password, first_name, last_name, email, role,adminperms) VALUES ('37cc36e0-afec-4545-9219-94655805868b','mikrowizard', '$pbkdf2-sha256$29000$yVnr/d9b6917j7G2tlYqRQ$.8fbnLorUGGt6z8SZK9t7Q5WHrRnmKIYL.RW5IkyZLo', 'admin','admin','admin@localhost', 'admin','{"device": "full", "device_group": "full", "task": "full", "backup": "full", "snippet": "full", "accounting": "full", "authentication": "full", "users": "full", "permissions": "full", "settings": "full", "system_backup": "full"}');
INSERT INTO public.permissions(id, name, perms) VALUES (1, 'full', '{"api": true, "ftp": true, "password": true, "read": true, "romon": true, "sniff": true, "telnet": true, "tikapp": true, "winbox": true, "dude": true, "local": true, "policy": true, "reboot": true, "rest-api": true, "sensitive": true, "ssh": true, "test": true, "web": true, "write": true}');
INSERT INTO public.permissions(id, name, perms) VALUES (2, 'read', '{"api": true, "ftp": false, "password": true, "read": true, "romon": true, "sniff": true, "telnet": true, "tikapp": true, "winbox": true, "dude": false, "local": true, "policy": false, "reboot": true, "rest-api": true, "sensitive": true, "ssh": true, "test": true, "web": true, "write": false}');
INSERT INTO public.permissions(id, name, perms) VALUES (3, 'write', '{"api": true, "dude": false, "ftp": false, "local": true, "password": true, "policy": false, "read": true, "reboot": true, "rest-api": true, "romon": true, "sensitive": true, "sniff": true, "ssh": true, "telnet": true, "test": true, "tikapp": true, "web": true, "winbox": true, "write": true}');
INSERT INTO public.user_group_perm_rel(group_id, user_id, perm_id) VALUES ( 1, '37cc36e0-afec-4545-9219-94655805868b', 1);
EOF1
# Run the Python script
python3 /app/initpy.py
# Check if the Python script ran successfully
if [ $? -ne 0 ]; then
echo "An error occurred while executing the SQL commands."
else
touch $CONTAINER_ALREADY_STARTED
echo "SQL commands executed successfully."
fi
cron
uwsgi --ini /app/conf/uwsgi.ini:uwsgi-production --touch-reload=/app/reload
else
cron
uwsgi --ini /app/conf/uwsgi.ini:uwsgi-production --touch-reload=/app/reload
fi

44
mikroman/initpy.py Normal file
View file

@ -0,0 +1,44 @@
import json
import psycopg2
# Step 1: Read connection details from server.json
with open('/conf/server-conf.json') as f:
config = json.load(f)
# Step 2: Connect to the PostgreSQL database
try:
conn = psycopg2.connect(
dbname=config['PYSRV_DATABASE_NAME'],
user=config['PYSRV_DATABASE_USER'],
password=config['PYSRV_DATABASE_PASSWORD'],
host=config['PYSRV_DATABASE_HOST_POSTGRESQL'],
port=config['PYSRV_DATABASE_PORT']
)
cursor = conn.cursor()
print("Connected to the database successfully.")
# Step 3: Read the SQL commands from the SQL file
with open('init.sql', 'r') as sql_file:
sql_commands = sql_file.read()
# Step 4: Execute the SQL commands
cursor.execute(sql_commands)
if cursor.description: # Check if there are results
# Fetch all results
results = cursor.fetchall()
# Print each row of results
for row in results:
print(row)
conn.commit() # Commit the changes if it's not a SELECT query
print("Executed SQL commands successfully.")
except Exception as e:
print(f"An error occurred: {e}")
exit(1)
finally:
# Close the database connection
if cursor:
cursor.close()
if conn:
conn.close()
print("Database connection closed.")

28
mikroman/reqs.txt Normal file
View file

@ -0,0 +1,28 @@
Flask==2.3.2
Flask-Session2==1.3.1
passlib==1.7.4
peewee==3.16.2
peewee-migrate==1.7.1
psycopg2-binary==2.9.6
pytz==2022.7.1
redis==4.5.4
uwsgidecorators==1.1.0
beautifulsoup4==4.10.0
#chardet==4.0.0
click==8.1.7
#click==8.0.3
cron_descriptor==1.4.0
cron_validator==1.0.8
cryptography==3.4.8
feedparser==6.0.11
librouteros==3.2.1
nagiosplugin==1.3.3
paramiko==2.9.3
pexpect==4.9.0
pycryptodome==3.20.0
pyrad==2.4
python_crontab==3.0.0
Requests==2.32.2
#setuptools==59.6.0
uvloop==0.19.0
netifaces==0.11.0

17
mikroman/server-conf.json Normal file
View file

@ -0,0 +1,17 @@
{
"name": "python server config template - rename me",
"PYSRV_IS_PRODUCTION": "1",
"PYSRV_DATABASE_HOST": "127.0.0.1",
"PYSRV_DATABASE_HOST_POSTGRESQL": "127.0.0.1",
"PYSRV_DATABASE_PORT": "5432",
"PYSRV_DATABASE_NAME": "mikrowizard_db",
"PYSRV_DATABASE_USER": "mikrowizard_user",
"PYSRV_DATABASE_PASSWORD": "securepassword",
"PYSRV_CRYPT_KEY": "bN0PJaVMpV7e4NGE8cLF3FECgY_nofYDuBtlLxX7pWg=",
"PYSRV_BACKUP_FOLDER":"/backups/",
"PYSRV_FIRM_FOLDER":"/firms/",
"PYSRV_COOKIE_HTTPS_ONLY": false,
"PYSRV_REDIS_HOST": "127.0.0.1:6379",
"PYSRV_DOMAIN_NAME": "",
"PYSRV_CORS_ALLOW_ORIGIN": "*"
}

View file

@ -0,0 +1,14 @@
{
"name": "python server config template - rename me",
"PYSRV_IS_PRODUCTION": "1",
"PYSRV_DATABASE_HOST": "127.0.0.1",
"PYSRV_DATABASE_PORT": "5432",
"PYSRV_DATABASE_NAME": "${MW_DB_NAME}",
"PYSRV_DATABASE_USER": "${MW_DB_USER}",
"PYSRV_DATABASE_PASSWORD": "${MW_DB_PASSWORD}",
"PYSRV_CRYPT_KEY": "${MW_encryptKey}",
"PYSRV_COOKIE_HTTPS_ONLY": false,
"PYSRV_REDIS_HOST": "127.0.0.1:6379",
"PYSRV_CORS_ALLOW_ORIGIN": "*"
}