Initial commit: enterprise digital platform with portal SSO, DigiServer, IT Assets, NetworkView, Server Monitor

This commit is contained in:
ske087
2026-05-10 21:07:50 +03:00
commit 8d9df56b0b
364 changed files with 73655 additions and 0 deletions
@@ -0,0 +1,11 @@
[defaults]
remote_user = pi
host_key_checking = False
deprecation_warnings = False
private_key_file = ssh_keys/app_key
roles_path = roles
retry_files_enabled = False
[ssh_connection]
ssh_args = -o ControlMaster=auto -o ControlPersist=60s -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no
pipelining = True
@@ -0,0 +1,453 @@
---
# Update_Rest_WMT_client Push standard WMT client files to target devices
# ──────────────────────────────────────────────────────────────────────────
# What this playbook does (in order):
#
# 1. Verify that WMT_project exists on the controller
# 2. Kill any running WMT app.py on the target
# 3. Remove previous WMT_old (if any) and rename WMT → WMT_old
# 4. Copy WMT_project → fresh WMT on the target
# 5. Fix execute permissions on scripts
# 6. Migrate config values: old config.txt → new config.txt
# Rules:
# • For every key that exists in BOTH old and new config → use old value
# • Key exists only in new config (new feature) → keep new default
# • Key exists only in old config (removed key) → skip / ignore
# File structure, comments, and new keys are always from
# the new template (WMT_project/data/config.txt).
# 7. Restore runtime data files (log.txt, tag.txt) from WMT_old
# 8. Delete WMT_old (migration complete, backup no longer needed)
# 9. Reboot the target host
#
# Run via: Ansible > Playbooks > "Update_Rest_WMT_client" or
# POST /api/ansible/execute { "playbook": "Update_Rest_WMT_client.yml" }
# ──────────────────────────────────────────────────────────────────────────
- name: Update WMT client files on target devices
hosts: all
gather_facts: false
become: false
tasks:
# ── 1. Verify source exists on the controller ─────────────────────────
- name: Check WMT_project source folder exists on controller
delegate_to: localhost
stat:
path: /home/pi/Desktop/WMT_project
register: wmt_project_stat
- name: Fail if WMT_project is missing on the controller
delegate_to: localhost
fail:
msg: >
/home/pi/Desktop/WMT_project not found on the Ansible controller.
Ensure the WMT_project folder is present before running this playbook.
when: not wmt_project_stat.stat.exists
# ── 2. Kill any running WMT app.py ────────────────────────────────────
- name: Stop running WMT app.py (if any)
shell: pkill -f "python3.*WMT/app.py"
ignore_errors: true
changed_when: false
- name: Wait for process to terminate
wait_for:
timeout: 4
# ── 3a. Remove previous WMT_old backup (if one exists from a prior run)
- name: Check if WMT_old already exists
stat:
path: /home/pi/Desktop/WMT_old
register: wmt_old_stat
- name: Remove previous WMT_old folder
file:
path: /home/pi/Desktop/WMT_old
state: absent
when: wmt_old_stat.stat.exists
# ── 3b. Rename current WMT → WMT_old ─────────────────────────────────
- name: Check if WMT folder currently exists
stat:
path: /home/pi/Desktop/WMT
register: wmt_stat
- name: Rename WMT to WMT_old
command: mv /home/pi/Desktop/WMT /home/pi/Desktop/WMT_old
when: wmt_stat.stat.exists
# ── 4. Copy fresh WMT_project → WMT ──────────────────────────────────
- name: Copy WMT_project to target as /home/pi/Desktop/WMT
copy:
src: /home/pi/Desktop/WMT_project/
dest: /home/pi/Desktop/WMT/
owner: pi
group: pi
mode: preserve
force: true
- name: Ensure WMT/data directory exists
file:
path: /home/pi/Desktop/WMT/data
state: directory
owner: pi
group: pi
mode: '0755'
# ── 5. Fix execute permissions ────────────────────────────────────────
- name: Ensure app.py is executable
file:
path: /home/pi/Desktop/WMT/app.py
owner: pi
group: pi
mode: '0755'
- name: Ensure setup_port_capability.sh is executable
file:
path: /home/pi/Desktop/WMT/setup_port_capability.sh
state: file
owner: pi
group: pi
mode: '0755'
ignore_errors: true
# ── 6. Migrate config values from old config.txt into new template ────
#
# Strategy (line-preserving Python migration):
# • Read WMT_old/data/config.txt → source of device-specific values
# • Read WMT/data/config.txt → new template (correct keys & comments)
# • Walk the new template line by line:
# - Keep all comment lines and blank lines unchanged
# - For each key=value line:
# If old config has the SAME section + key → replace value with old value
# If old config does NOT have that key → keep new default value
# - Keys only in old config are silently ignored (removed features)
# • Write the result back to WMT/data/config.txt
#
- name: Check if old config.txt exists in WMT_old
stat:
path: /home/pi/Desktop/WMT_old/data/config.txt
register: old_cfg_stat
- name: Migrate config values (old → new template)
shell: |
python3 << 'PYEOF'
import configparser, os, re, sys
old_path = '/home/pi/Desktop/WMT_old/data/config.txt'
new_path = '/home/pi/Desktop/WMT/data/config.txt'
if not os.path.exists(old_path):
print('No old config.txt found keeping new defaults as-is')
sys.exit(0)
if not os.path.exists(new_path):
print('New config.txt missing nothing to migrate into')
sys.exit(1)
# Parse old config to get existing values
old = configparser.ConfigParser()
old.read(old_path)
# Walk new template line by line, replacing values where old config has them
current_section = None
output_lines = []
migrated = []
kept_new = []
with open(new_path, 'r') as f:
for line in f:
stripped = line.rstrip('\n')
# Detect section header e.g. [device]
section_match = re.match(r'^\s*\[([^\]]+)\]\s*$', stripped)
if section_match:
current_section = section_match.group(1)
output_lines.append(line)
continue
# Detect key = value line (skip comments and blank lines)
kv_match = re.match(r'^([^#;\s][^=]*?)\s*=\s*(.*)', stripped)
if kv_match and current_section:
key = kv_match.group(1).strip()
new_val = kv_match.group(2)
if old.has_section(current_section) and old.has_option(current_section, key):
old_val = old.get(current_section, key)
if old_val != new_val:
output_lines.append(f'{key}={old_val}\n')
migrated.append(f' [{current_section}] {key} = {old_val!r} (was: {new_val!r})')
else:
output_lines.append(line)
else:
output_lines.append(line)
kept_new.append(f' [{current_section}] {key} = {new_val!r} (new key keeping default)')
else:
output_lines.append(line)
with open(new_path, 'w') as f:
f.writelines(output_lines)
print('=== Config migration complete ===')
if migrated:
print(f'Migrated {len(migrated)} value(s) from old config:')
for m in migrated:
print(m)
if kept_new:
print(f'Kept {len(kept_new)} new default(s) (not in old config):')
for k in kept_new:
print(k)
PYEOF
register: cfg_migration_result
when: old_cfg_stat.stat.exists
changed_when: true
- name: Show config migration output
debug:
msg: "{{ cfg_migration_result.stdout_lines }}"
when: old_cfg_stat.stat.exists
- name: Note no old config found, new defaults kept
debug:
msg: "WMT_old/data/config.txt not found new WMT_project defaults will be used."
when: not old_cfg_stat.stat.exists
# ── 7. Restore runtime data files from WMT_old ───────────────────────
- name: Check if log.txt exists in WMT_old
stat:
path: /home/pi/Desktop/WMT_old/data/log.txt
register: old_log_stat
- name: Restore log.txt from WMT_old
copy:
src: /home/pi/Desktop/WMT_old/data/log.txt
dest: /home/pi/Desktop/WMT/data/log.txt
owner: pi
group: pi
mode: '0644'
remote_src: true
when: old_log_stat.stat.exists
- name: Check if tag.txt exists in WMT_old
stat:
path: /home/pi/Desktop/WMT_old/data/tag.txt
register: old_tag_stat
- name: Restore tag.txt from WMT_old (pending card posts)
copy:
src: /home/pi/Desktop/WMT_old/data/tag.txt
dest: /home/pi/Desktop/WMT/data/tag.txt
owner: pi
group: pi
mode: '0644'
remote_src: true
when: old_tag_stat.stat.exists
# ── 8. Remove WMT_old now that migration is complete ─────────────────
- name: Remove WMT_old folder (migration done, no longer needed)
file:
path: /home/pi/Desktop/WMT_old
state: absent
# ── 9. Show final config and reboot ───────────────────────────────────
- name: Show final config.txt on target
command: cat /home/pi/Desktop/WMT/data/config.txt
register: final_cfg
changed_when: false
- name: Display final config.txt
debug:
msg: "{{ final_cfg.stdout_lines }}"
- name: Show updated app.py version
command: head -1 /home/pi/Desktop/WMT/app.py
register: app_version
changed_when: false
- name: Report update summary
debug:
msg: >
✓ WMT updated on {{ inventory_hostname }} {{ app_version.stdout }}.
Rebooting now to apply changes.
- name: Reboot target to apply all changes
become: true
reboot:
msg: "Rebooting after WMT client update"
reboot_timeout: 180
pre_reboot_delay: 3
post_reboot_delay: 15
- name: Update WMT client files on target devices
hosts: all
gather_facts: false
become: false
tasks:
# ── 1. Confirm WMT_project source exists on the controller ────────────
- name: Check that WMT_project source folder exists on controller
delegate_to: localhost
stat:
path: /home/pi/Desktop/WMT_project
register: wmt_project_stat
- name: Fail if WMT_project is missing on the controller
delegate_to: localhost
fail:
msg: >
/home/pi/Desktop/WMT_project was not found on the Ansible controller.
Make sure the WMT_project folder is present before running this playbook.
when: not wmt_project_stat.stat.exists
# ── 2. Ensure WMT destination directory exists on target ─────────────
- name: Ensure /home/pi/Desktop/WMT directory exists
file:
path: /home/pi/Desktop/WMT
state: directory
owner: pi
group: pi
mode: '0755'
# ── 3. Kill any running WMT app.py process ────────────────────────────
- name: Stop running WMT app.py (if any)
shell: pkill -f "python3.*WMT/app.py"
ignore_errors: true
changed_when: false
- name: Wait for process to terminate
wait_for:
timeout: 3
# ── 4. Copy WMT_project → WMT, preserving device-specific data files ─
- name: Copy WMT_project files to target (excluding device-specific data)
copy:
src: /home/pi/Desktop/WMT_project/
dest: /home/pi/Desktop/WMT/
owner: pi
group: pi
mode: preserve
force: true
# Exclude device-specific files that must never be overwritten
# Note: Ansible's copy module does not support 'exclude' natively;
# we restore the originals in step 4b4e below.
# ── 4b-4e. Restore device-specific data files from the target backup ──
# Strategy: before overwriting we slurp the existing files, then
# write them back so the 'copy' above cannot clobber them.
- name: Check if device config.txt exists (pre-copy)
stat:
path: /home/pi/Desktop/WMT/data/config.txt
register: cfg_stat
- name: Slurp existing config.txt (if present)
slurp:
src: /home/pi/Desktop/WMT/data/config.txt
register: cfg_backup
when: cfg_stat.stat.exists
- name: Restore config.txt after copy (device config must not be overwritten)
copy:
content: "{{ cfg_backup.content | b64decode }}"
dest: /home/pi/Desktop/WMT/data/config.txt
owner: pi
group: pi
mode: '0644'
when: cfg_stat.stat.exists
# idmasa.txt is a legacy Prezenta file not used by WMT, not restored
- name: Check if log.txt exists
stat:
path: /home/pi/Desktop/WMT/data/log.txt
register: log_stat
- name: Slurp existing log.txt (if present)
slurp:
src: /home/pi/Desktop/WMT/data/log.txt
register: log_backup
when: log_stat.stat.exists
- name: Restore log.txt after copy
copy:
content: "{{ log_backup.content | b64decode }}"
dest: /home/pi/Desktop/WMT/data/log.txt
owner: pi
group: pi
mode: '0644'
when: log_stat.stat.exists
- name: Check if tag.txt exists
stat:
path: /home/pi/Desktop/WMT/data/tag.txt
register: tag_stat
- name: Slurp existing tag.txt (if present)
slurp:
src: /home/pi/Desktop/WMT/data/tag.txt
register: tag_backup
when: tag_stat.stat.exists
- name: Restore tag.txt after copy
copy:
content: "{{ tag_backup.content | b64decode }}"
dest: /home/pi/Desktop/WMT/data/tag.txt
owner: pi
group: pi
mode: '0644'
when: tag_stat.stat.exists
# ── 5. Fix execute permissions on scripts ─────────────────────────────
- name: Ensure app.py is executable
file:
path: /home/pi/Desktop/WMT/app.py
owner: pi
group: pi
mode: '0755'
- name: Ensure setup_port_capability.sh is executable
file:
path: /home/pi/Desktop/WMT/setup_port_capability.sh
state: file
owner: pi
group: pi
mode: '0755'
ignore_errors: true
# ── 6. Ensure WMT/data directory is intact ────────────────────────────
- name: Ensure WMT/data directory exists
file:
path: /home/pi/Desktop/WMT/data
state: directory
owner: pi
group: pi
mode: '0755'
# ── 7. Restart WMT app in a new lxterminal session ────────────────────
- name: Launch WMT app.py in background lxterminal
shell: >
DISPLAY=:0 lxterminal -e
"bash -c 'cd /home/pi/Desktop/WMT; python3 app.py; exec bash'" &
environment:
DISPLAY: ":0"
ignore_errors: true
changed_when: true
- name: Wait for WMT app to start
wait_for:
timeout: 5
# ── 8. Confirm update on target ───────────────────────────────────────
- name: Show updated app.py version line
command: head -1 /home/pi/Desktop/WMT/app.py
register: app_version
changed_when: false
- name: Report update result
debug:
msg: >
✓ WMT client updated on {{ inventory_hostname }} ({{ ansible_host }}).
Version: {{ app_version.stdout }}
@@ -0,0 +1,55 @@
---
# Distribute SSH Public Key to All Devices
# ─────────────────────────────────────────
# Purpose : Push the monitoring server's public key to every device so that
# all subsequent Ansible playbooks can use key-based authentication.
#
# Auth : Connects with ansible_password (set via --extra-vars at runtime).
# No SSH key is required on the target to run this playbook.
#
# Run via : Ansible > SSH Setup > "Deploy SSH Keys to All Devices" button, or
# POST /api/ansible/ssh/distribute-keys
#
# After : Disable "Use password authentication" in SSH Settings so all other
# playbooks switch back to key-based auth automatically.
- name: Distribute SSH Public Key to All Devices
hosts: all
gather_facts: false
become: false
tasks:
- name: Ensure .ssh directory exists with correct permissions
file:
path: /home/pi/.ssh
state: directory
mode: '0700'
owner: pi
group: pi
- name: Deploy controller public key to authorized_keys
authorized_key:
user: pi
key: "{{ lookup('file', playbook_dir + '/../ssh_keys/app_key.pub') }}"
state: present
exclusive: false
- name: Set correct permissions on authorized_keys
file:
path: /home/pi/.ssh/authorized_keys
mode: '0600'
owner: pi
group: pi
- name: Count keys in authorized_keys
shell: grep -c "" /home/pi/.ssh/authorized_keys
register: key_count
changed_when: false
- name: Confirm successful deployment
debug:
msg: >-
SSH key deployed on {{ inventory_hostname }} ({{ ansible_host }}).
authorized_keys now contains {{ key_count.stdout }} key(s).
Key-based authentication is ready.
@@ -0,0 +1,174 @@
---
# Migrate devices from Prezenta app to WMT
# ──────────────────────────────────────────────────────────────────────────
# What this playbook does (in order):
#
# 1. Create /home/pi/Desktop/WMT on the target
# 2. Copy /home/pi/Desktop/WMT_project from the CONTROLLER to /home/pi/Desktop/WMT on the target
# 3. Read idmasa.txt from the target (checks Prezenta/data/ first, falls back to Prezenta/Files/ for older app models)
# 4. Write that value as work_place in WMT/data/config.txt (replaces notconfig)
# 5. Update ~/.config/wayfire.ini [autostart] start_python to launch from WMT
# 6. Rename /home/pi/Desktop/Prezenta → /home/pi/Desktop/Prezenta_Old_Data
# 7. Reboot the host
#
# Run via: Ansible > Playbooks > "Migrate to WMT" or POST /api/ansible/execute
# ──────────────────────────────────────────────────────────────────────────
- name: Migrate devices from Prezenta to WMT
hosts: all
gather_facts: false
become: false
tasks:
# ── 1. Ensure destination directory exists ────────────────────────────
- name: Create WMT directory on target
file:
path: /home/pi/Desktop/WMT
state: directory
owner: pi
group: pi
mode: '0755'
# ── 2. Copy WMT_project from controller → target as WMT ──────────────
- name: Copy WMT_project folder to target as /home/pi/Desktop/WMT
copy:
src: /home/pi/Desktop/WMT_project/
dest: /home/pi/Desktop/WMT/
owner: pi
group: pi
mode: preserve
force: true
# ── 3. Ensure WMT data directory exists (in case config.txt is missing)
- name: Ensure WMT/data directory exists
file:
path: /home/pi/Desktop/WMT/data
state: directory
owner: pi
group: pi
mode: '0755'
# ── 4. Read idmasa.txt supports two Prezenta layouts ───────────────
# Modern layout : Prezenta/data/idmasa.txt
# Older layout : Prezenta/Files/idmasa.txt
- name: Check for idmasa.txt in modern path (Prezenta/data/)
stat:
path: /home/pi/Desktop/Prezenta/data/idmasa.txt
register: idmasa_data_stat
- name: Check for idmasa.txt in older path (Prezenta/Files/)
stat:
path: /home/pi/Desktop/Prezenta/Files/idmasa.txt
register: idmasa_files_stat
- name: Resolve idmasa.txt path (prefer data/, fall back to Files/)
set_fact:
idmasa_path: >-
{{
'/home/pi/Desktop/Prezenta/data/idmasa.txt'
if idmasa_data_stat.stat.exists
else '/home/pi/Desktop/Prezenta/Files/idmasa.txt'
}}
- name: Show which idmasa.txt will be used
debug:
msg: "Using idmasa.txt from: {{ idmasa_path }}"
- name: Fail if idmasa.txt was not found in either location
fail:
msg: >-
idmasa.txt not found in Prezenta/data/ or Prezenta/Files/.
Cannot determine work_place aborting migration.
when:
- not idmasa_data_stat.stat.exists
- not idmasa_files_stat.stat.exists
- name: Read idmasa.txt from resolved path
slurp:
src: "{{ idmasa_path }}"
register: idmasa_raw
- name: Decode idmasa value
set_fact:
work_place_value: "{{ idmasa_raw.content | b64decode | trim }}"
- name: Show detected work_place value
debug:
msg: "work_place will be set to: '{{ work_place_value }}'"
# ── 5. Replace work_place value in WMT/data/config.txt ───────────────
- name: Replace work_place in WMT config.txt
lineinfile:
path: /home/pi/Desktop/WMT/data/config.txt
regexp: '^work_place\s*=.*'
line: "work_place={{ work_place_value }}"
backup: true
- name: Confirm work_place change
command: grep 'work_place' /home/pi/Desktop/WMT/data/config.txt
register: wp_check
changed_when: false
- name: Show work_place line in config.txt
debug:
msg: "{{ wp_check.stdout }}"
# ── 6. Update wayfire.ini autostart to launch from WMT ───────────────
- name: Update wayfire.ini start_python path from Prezenta to WMT
lineinfile:
path: /home/pi/.config/wayfire.ini
regexp: "^start_python\\s*=.*"
line: "start_python = lxterminal -e \"bash -c 'cd /home/pi/Desktop/WMT; python3 app.py; exec bash'\""
backrefs: false
backup: true
- name: Confirm wayfire.ini change
command: grep "start_python" /home/pi/.config/wayfire.ini
register: wayfire_check
changed_when: false
- name: Show wayfire.ini start_python line
debug:
msg: "{{ wayfire_check.stdout }}"
# ── 7. Kill any running Prezenta app.py before renaming ──────────────
- name: Kill any process running from Prezenta app.py
shell: pkill -f "python3.*Prezenta/app.py"
ignore_errors: true
changed_when: false
- name: Wait a moment for the process to terminate
wait_for:
timeout: 3
# ── 8. Rename Prezenta → Prezenta_Old_Data ─────────────────────────── #
- name: Check if Prezenta folder exists
stat:
path: /home/pi/Desktop/Prezenta
register: prezenta_stat
- name: Check if Prezenta_Old_Data already exists
stat:
path: /home/pi/Desktop/Prezenta_Old_Data
register: prezenta_old_stat
- name: Rename Prezenta to Prezenta_Old_Data
command: mv /home/pi/Desktop/Prezenta /home/pi/Desktop/Prezenta_Old_Data
when:
- prezenta_stat.stat.exists
- not prezenta_old_stat.stat.exists
- name: Warn if Prezenta_Old_Data already exists (rename skipped)
debug:
msg: "⚠ Prezenta_Old_Data already exists — rename skipped to avoid overwrite."
when: prezenta_old_stat.stat.exists
# ── 9. Reboot ─────────────────────────────────────────────────────────
- name: Reboot host to apply all changes
become: true
reboot:
msg: "Rebooting after WMT migration"
reboot_timeout: 180
pre_reboot_delay: 3
post_reboot_delay: 15
@@ -0,0 +1,29 @@
- become: true
hosts: all
name: Restart monitoring service
tasks:
- name: Stop prezenta service
systemd:
name: prezenta.service
state: stopped
- name: Wait for service to stop
wait_for:
timeout: 10
- name: Start prezenta service
systemd:
enabled: true
name: prezenta.service
state: started
- name: Verify service is running
register: service_status
systemd:
name: prezenta.service
- name: Report service restart
uri:
body:
device_ip: '{{ ansible_host }}'
hostname: '{{ inventory_hostname }}'
service_status: '{{ service_status.status.ActiveState }}'
body_format: json
method: POST
url: http://{{ ansible_controller_ip }}/api/service_restarted
@@ -0,0 +1,49 @@
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAACFwAAAAdzc2gtcn
NhAAAAAwEAAQAAAgEA5e+hvZjALgvbF3RnGdcJ9s6E1C7gwKY20V2GEXb6Uckk9ezM+/am
2roETSQ1fNR1ydEY7bbi2kG2zuAWcyfTilGK8BKa1n81g+DarCf37WHSYcNVLslLOnPl1o
6Q7SfkCCFnNSvRBWMGZN++WpHUholr+t18OEWTHw1lwxgsOME0V7jOLDedEhsWMsHU3x/R
zghunx4Wxa+OHz81qBOefbCi34CyZ1DUlOhxNy3oI95YQoX4aaTOnW15+LUsSmS53Ks6zd
CK9xcA6ktHje9hNBYQhkWQn8TnYRkDb2QMpkljUi0oFrsihiF7eAX4PqYW+tMFd/ZPcWmL
2W+IJfX36bX1PpwIIB/BWQ+vA3ijCaXmMoYRK1dS6CBJv28nh1xYxoVXmQDbEV+phcv4yv
929Ooiijo+Lr+gUdAZTXWdzzJkNkcn0Zpgoq+s47OVUVF+0Z/0ksP1hLz1mhBKxrjKvaUr
CIgxGoEvPzS1+9/EfbD1Yzl469RX8J5hCYVAkJ0/iPWWe5Ma6T0vre7M3k+ySXCzkwrnK0
qZfiUlhJyNVo4SzIsRB9uU5Ks/qeHI4ZPBIzbCrjn0JZVOWMgE8LYlEFgtD/uL77Wvqivp
1Z3g6i1ViACOiCEW2vvTfARxn6XUTCeuzwaQxJYChL30R4+H9juOwxs4XRSJJ4k6376pRY
8AAAdQgRXFN4EVxTcAAAAHc3NoLXJzYQAAAgEA5e+hvZjALgvbF3RnGdcJ9s6E1C7gwKY2
0V2GEXb6Uckk9ezM+/am2roETSQ1fNR1ydEY7bbi2kG2zuAWcyfTilGK8BKa1n81g+DarC
f37WHSYcNVLslLOnPl1o6Q7SfkCCFnNSvRBWMGZN++WpHUholr+t18OEWTHw1lwxgsOME0
V7jOLDedEhsWMsHU3x/Rzghunx4Wxa+OHz81qBOefbCi34CyZ1DUlOhxNy3oI95YQoX4aa
TOnW15+LUsSmS53Ks6zdCK9xcA6ktHje9hNBYQhkWQn8TnYRkDb2QMpkljUi0oFrsihiF7
eAX4PqYW+tMFd/ZPcWmL2W+IJfX36bX1PpwIIB/BWQ+vA3ijCaXmMoYRK1dS6CBJv28nh1
xYxoVXmQDbEV+phcv4yv929Ooiijo+Lr+gUdAZTXWdzzJkNkcn0Zpgoq+s47OVUVF+0Z/0
ksP1hLz1mhBKxrjKvaUrCIgxGoEvPzS1+9/EfbD1Yzl469RX8J5hCYVAkJ0/iPWWe5Ma6T
0vre7M3k+ySXCzkwrnK0qZfiUlhJyNVo4SzIsRB9uU5Ks/qeHI4ZPBIzbCrjn0JZVOWMgE
8LYlEFgtD/uL77Wvqivp1Z3g6i1ViACOiCEW2vvTfARxn6XUTCeuzwaQxJYChL30R4+H9j
uOwxs4XRSJJ4k6376pRY8AAAADAQABAAACADFFgc+qeVgEo1ypzWQMn+56v5zmNLQjifCg
TVfVunsnEpv+M8i0SHnrTXuoTCvlLR5jh6d8vqzNUxqOi1D+0kY8Bf0+x146YSHS35jvca
G1Cgt3+3tsmAm9Bx3MbALdvu/9FGwg6Qfx+c9I4LXwtO1lajWWG4XFZurLCKjfN66rvAcm
K0vvWOGl20JiJbbwTxmK1gWTwYZ4AYjxlxJereI6JRSms9QOzpbgHk6YMDvra9dJdPtSXR
IAARiJ3iVM40UFjjLHQtgC3mfWXM1t49Lw/XaAVqbd30T/wqwucMV7SWS1F3eTfyjl6NrF
0LXACoGSEYRszAY9+0FLNI4J4KcUlgE0k6O9zRATxNRvgfZesJj60BqmKgGbGpSPRI8FCS
6bhvcAiluqNrJVqcB5sMMeNab+bzeryqkyeU+04/+IN5Uwr4RZ+2LeGyCNHhLNWmRQdkEf
4Pl0bpYAISfMNCIJtiFm+H9qUmTynbRUS6Gw4RrifygIrKEYyLpBGobYtEh9vxwZVksHg9
0JF3ty6MQ4HHhHIsdaANtYCjtuuTmbtqIIh8QPHQ7bm6mQOmmUtebM0zPzGNWg+mqNG0zZ
RZj2gVhapy8U/AzdtuIWWNYxkUfvJH+ISH+hfkUIogb6Onb9FP6P44+HCUTaJ6IcO35YRd
C9Ab5HqiisdTtfVph9AAABAQD0Dxssll7RdLVaZk5tgXSF0KW8uaMg/do8bBwqdVTr7JcF
eEp1d7tcXX3fs9txLg5BP63CKOmkeRMAq8LrcxXx5kC+RGyUYifRfpUAuB72NiakBkaQ9q
9kLKzz4xa5UlCW2c9ZOuPv6jWSamwJifgt4YBFM0cFCcETnUFF+SL/ehz2vBkrHpieoDDe
liVrL7BmM5z4oSYYmihA3K9bM0gdGP1T3e4gVZtTepu548VMioyYNpJDL0tCHI9FEqxUqv
U/83oFy0zEsnjx7yg4sWwn6agY7ZhIAHxU7tCbHXo0stERTUarINPTmaxoPnK7222pkkOa
dPkZiDCMapAW+IesAAABAQD6a4kGBlXGixy2IgwwWFxnyZndTjZ5fAcHX0/3/4mHZDtYl1
u0wTP5gANKbuQuun9cA501LMpc+ya6W0XFJneIopFcqsBIvaWF8CptbmA35GiSlwFKpq1b
dDkBaxhYU5TY+vpDPKXMqPJoyswO9yf4WnBaOFoc1H674Q+NfFV1csjHngtJWZm3LG/xti
mYZ9DXTEricVAZ7KiCwOMKyfF4cdhcqUdBtB9Lv7s8bNWq/+eRSsrnQuqLOudUY7AYjWJs
YwLzDdCeEMtlf//G8rDnJ8Zy2hyOhZmVkcRbF1xu79setwwdECgEA3aRz3YzVgZq7UrLa9
jm5AskEpH00pwlAAABAQDrD0ANclu3ogbHEpcngjITOnh+40lVz6ouI99LYtRp5r3bYAHz
0fczdeODu9QaskEg/M5ys+4Dwb4Zlqbl+6aEpigNELj0FwBhb6z5XCBn4mctYjS7I/XhPF
shNZia0Wg4KiEUdVG8aYLozMXG8N0SYMi3Km3vrvGQEjyZImBEAcaIKC7ya+2XXmL3lUwH
RFysrV/q76wXFjqLE6PNoj+UTFR5L0JB8FbR3lsOZVsfE+kn2gmUk3xbiCB+9kO2leXT50
+mv2eTvWzD/leSWqrxelFyNRrsBqlQfjXKT0S2sotrtwuoSR+zCkutwLeWMGB06IIq8vvK
QIadJAFAnFKjAAAAF3NlcnZlcl9tb25pdG9yaXphcmVfYXBwAQID
-----END OPENSSH PRIVATE KEY-----
@@ -0,0 +1 @@
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDl76G9mMAuC9sXdGcZ1wn2zoTULuDApjbRXYYRdvpRyST17Mz79qbaugRNJDV81HXJ0RjttuLaQbbO4BZzJ9OKUYrwEprWfzWD4NqsJ/ftYdJhw1UuyUs6c+XWjpDtJ+QIIWc1K9EFYwZk375akdSGiWv63Xw4RZMfDWXDGCw4wTRXuM4sN50SGxYywdTfH9HOCG6fHhbFr44fPzWoE559sKLfgLJnUNSU6HE3Legj3lhChfhppM6dbXn4tSxKZLncqzrN0Ir3FwDqS0eN72E0FhCGRZCfxOdhGQNvZAymSWNSLSgWuyKGIXt4Bfg+phb60wV39k9xaYvZb4gl9ffptfU+nAggH8FZD68DeKMJpeYyhhErV1LoIEm/byeHXFjGhVeZANsRX6mFy/jK/3b06iKKOj4uv6BR0BlNdZ3PMmQ2RyfRmmCir6zjs5VRUX7Rn/SSw/WEvPWaEErGuMq9pSsIiDEagS8/NLX738R9sPVjOXjr1FfwnmEJhUCQnT+I9ZZ7kxrpPS+t7szeT7JJcLOTCucrSpl+JSWEnI1WjhLMixEH25Tkqz+p4cjhk8EjNsKuOfQllU5YyATwtiUQWC0P+4vvta+qK+nVneDqLVWIAI6IIRba+9N8BHGfpdRMJ67PBpDElgKEvfRHj4f2O47DGzhdFIkniTrfvqlFjw== server_monitorizare_app