Changelog: https://roxy-wi.org/changelog#6_3_0
pull/355/head
Pavel Loginov 2022-11-28 10:47:18 +03:00
parent a239ce0755
commit bab73f1694
36 changed files with 610 additions and 120 deletions

View File

@ -42,11 +42,15 @@ def ssh_connect(server_ip):
def ssh_command(server_ip: str, commands: list, **kwargs):
if server_ip == '':
return 'error: IP cannot be empty'
if kwargs.get('timeout'):
timeout = kwargs.get('timeout')
else:
timeout = 1
try:
with ssh_connect(server_ip) as ssh:
for command in commands:
try:
stdin, stdout, stderr = ssh.run_command(command)
stdin, stdout, stderr = ssh.run_command(command, timeout=timeout)
except Exception as e:
print(f'error: {e}')
roxywi_common.logging('Roxy-WI server', f' Something wrong with SSH connection. Probably sudo with password {e}', roxywi=1)
@ -74,10 +78,9 @@ def ssh_command(server_ip: str, commands: list, **kwargs):
except Exception as e:
roxywi_common.logging('Roxy-WI server', f' Something wrong with SSH connection. Probably sudo with password {e}', roxywi=1)
except Exception as e:
print(e)
roxywi_common.logging('Roxy-WI server',
f' Something wrong with SSH connection. Probably sudo with password {e}', roxywi=1)
return str(e)
f' Something wrong with SSH connection: {e}', roxywi=1)
return str(f'error: {e}')
def subprocess_execute(cmd):

View File

@ -48,15 +48,19 @@ class SshConnection:
elif e == "Invalid argument":
raise paramiko.SSHException('error: Check the IP of the server')
else:
raise paramiko.SSHException(str(e))
raise paramiko.SSHException(f'error: {e}')
return self
def __exit__(self, exc_type, exc_val, exc_tb):
self.ssh.close()
def run_command(self, command):
def run_command(self, command, **kwargs):
if kwargs.get('timeout'):
timeout = kwargs.get('timeout')
else:
timeout = 1
try:
stdin, stdout, stderr = self.ssh.exec_command(command, get_pty=True, timeout=2)
stdin, stdout, stderr = self.ssh.exec_command(command, get_pty=True, timeout=timeout)
except Exception as e:
raise paramiko.SSHException(str(e))

View File

@ -2821,7 +2821,7 @@ if form.getvalue('nettools_icmp_server_from'):
output, stderr = server_mod.subprocess_execute(action_for_sending)
else:
action_for_sending = [action_for_sending]
output = server_mod.ssh_command(server_from, action_for_sending, raw=1)
output = server_mod.ssh_command(server_from, action_for_sending, raw=1, timeout=15)
if stderr != '':
print(f'error: {stderr}')
@ -4110,13 +4110,14 @@ if act == 'updateSystemInfo':
env.globals['string_to_dict'] = common.string_to_dict
template = env.get_template('ajax/show_system_info.html')
if server_mod.get_system_info(server_ip):
try:
server_mod.get_system_info(server_ip)
system_info = sql.select_one_system_info(server_id)
template = template.render(system_info=system_info, server_ip=server_ip, server_id=server_id)
print(template)
else:
print('error: Cannot update server info')
except Exception as e:
print(f'error: Cannot update server info: {e}')
if act == 'findInConfigs':
server_ip = serv

View File

@ -105,6 +105,6 @@ rendered_template = template.render(
socket_log_id=roxy_logs.roxy_wi_log(log_id=1, file="socket"), error=stderr,
roxy_wi_log=roxy_logs.roxy_wi_log(), servers=user_params['servers'], is_checker_worker=is_checker_worker,
is_metrics_worker=is_metrics_worker, host=host, user_services=user_params['user_services'],
token=user_params['token']
token=user_params['token'], guide_me=1
)
print(rendered_template)

View File

@ -3,7 +3,12 @@
set_fact:
ansible_port: "{{SSH_PORT}}"
- name: Add NGINX
- name: Ensure group "nginx" exists
ansible.builtin.group:
name: nginx
state: present
- name: Add NGINX User
ansible.builtin.user:
name: nginx
group: nginx

View File

@ -44,7 +44,7 @@ except Exception as e:
rendered_template = template.render(
title="Servers: ", role=user_params['role'], user=user_params['user'], users=sql.select_users(group=user_group),
groups=sql.select_groups(), servers=servers, roles=sql.select_roles(), sshs=sql.select_ssh(group=user_group),
masters=masters, group=user_group, services=services, timezones=pytz.all_timezones,
masters=masters, group=user_group, services=services, timezones=pytz.all_timezones, guide_me=1,
token=user_params['token'], settings=settings, backups=sql.select_backups(), page="servers.py",
geoip_country_codes=geoip_country_codes, user_services=user_params['user_services'], ldap_enable=ldap_enable,
user_status=user_subscription['user_status'], user_plan=user_subscription['user_plan'], gits=gits,

View File

@ -5,18 +5,18 @@
<script src="/inc/fontawesome.min.js"></script>
{% include 'include/del_confirm.html' %}
<div id="tabs">
<ul>
<ul id="admin-tabs">
<li><a href="#users" title="Admin area: Manage users - Roxy-WI">Users</a></li>
<li><a href="#groups" title="Admin area: Manage groups - Roxy-WI">Groups</a></li>
<li><a href="#servers" title="Admin area: Manage servers - Roxy-WI">Servers</a></li>
<li><a href="#ssh" title="Admin area: Manage SSH credentials - Roxy-WI">SSH credentials</a></li>
<li><a href="#checker" title="Admin area: Manage checker - Roxy-WI">Checker</a></li>
<li><a href="#openvpn" title="Admin area: OpenVPN - Roxy-WI">OpenVPN</a></li>
<li><a href="#openvpn" title="Admin area: OpenVPN - Roxy-WI" id="admin-tabs-vpn">OpenVPN</a></li>
<li><a href="#settings" title="Admin area: Manage Roxy-WI settings - Roxy-WI">Settings</a></li>
<li><a href="#services" title="Admin area: Manage Roxy-WI services - Roxy-WI">Services</a></li>
<li><a href="#updatehapwi" title="Admin area: Update Roxy-WI - Roxy-WI">Update</a></li>
<li><a href="#backup" title="Admin area: Backup configs - Roxy-WI">Backup</a></li>
<li><a href="#installmon" title="Servers: Monitoring service installation - Roxy-WI">Monitoring installation</a></li>
<li><a href="#backup" title="Admin area: Backup configs - Roxy-WI" id="admin-tabs-backup">Backup</a></li>
<li><a href="#installmon" title="Servers: Monitoring service installation - Roxy-WI" id="admin-tabs-mon">Monitoring installation</a></li>
{% include 'include/login.html' %}
</ul>
<ul id='browse_histroy'></ul>
@ -184,4 +184,5 @@
});
</script>
<link href="/inc/css/servers.css" rel="stylesheet"/>
{% include 'include/intro/admin.html' %}
{% endblock %}

View File

@ -25,11 +25,11 @@
{% if not role %}
{% if line.startswith('#HideBlockStart') %}
<!--{{line}}
{% continue %}
{% continue %}
{% endif %}
{% if line.startswith('#HideBlockEnd') %}
{{line}}-->
{% continue %}
{% continue %}
{% endif %}
{% endif %}
{% if service == 'nginx' %}
@ -42,7 +42,7 @@
</span><br />
{% continue %}
{% endif %}
{%- if "server {" in line -%}
{%- if "server {" in line -%}
{% if i > 1 %}
</div>
{% endif %}
@ -77,9 +77,9 @@
{% if "#" not in line %}
<span class="numRow">
{{ i }}
</span>
</span>
<span class="paramInSec">
&emsp;{{ line }}
&emsp;{{ line }}
</span><br />
{% continue %}
{% endif %}
@ -91,13 +91,13 @@
<span class="comment">
&emsp;{{ line }}
</span><br />
{% continue %}
{% continue %}
{% endif %}
{% if line|length > 1 %}
<span class="configLine">
<span class="numRow">{{ i }}</span>
<span class="numRow">{{ i }}</span>
&emsp;&emsp;{{ line }}
</span><br />
</span><br />
{% endif %}
{% elif service == 'apache' %}
{% if i == 0 and "<VirtualHost" not in line %}
@ -229,7 +229,7 @@
</div><span class="param">{{- line -}}
{% if role %}
<span class="accordion-link">
<a href="/app/sections.py?serv={{serv}}&section={{ line }}">Edit/Delete</a>
<a href="/app/sections.py?serv={{serv}}&section={{ line }}" target="_blank">Edit/Delete</a>
</span>
{% endif %}
{%- set backend = line.split(' ') -%}
@ -238,8 +238,8 @@
</span>
{%- set backend = backend|join('_') -%}
{%- do section_name.update({i: backend}) -%}
<span id="{{-section_name[i]|replace('\n', '')-}}" class="accordion-link"></span>
</span><div>
<span id="{{-section_name[i]|replace('\n', '')-}}" class="accordion-link" target="_blank"></span>
</span><div>
{% continue %}
{%- endif -%}
{%- if line.startswith('frontend') -%}
@ -248,19 +248,19 @@
<span class="accordion-link">
<a href="/app/sections.py?serv={{serv}}&section={{ line }}">Edit/Delete</a>
</span>
{% endif %}
{% endif %}
{% set backend = line.split(' ') %}
<span class="accordion-link">
<a href="/app/statsview.py?serv={{serv}}#{{ backend[1]}}" target="_blank">Stats</a>
</span>
</span>
{% set backend = backend|join('_') %}
{% do section_name.update({i: backend}) %}
<span id="{{section_name[i]|replace('\n', '')}}" class="accordion-link"></span>
</span><div>
<span id="{{section_name[i]|replace('\n', '')}}" class="accordion-link"></span>
</span><div>
{% continue %}
{%- endif -%}
{% if line.startswith('backend') %}
</div><span class="param">{{ line }}
</div><span class="param">{{ line }}
{% if role %}
<span class="accordion-link">
<a href="/app/sections.py?serv={{serv}}&section={{ line }}">Edit/Delete</a>
@ -274,7 +274,7 @@
{% continue %}
{% endif %}
{% if line.startswith('cache') %}
</div><span class="param">{{ line }}
</div><span class="param">{{ line }}
{% if role %}
<span class="accordion-link">
<a href="/app/sections.py?serv={{serv}}&section={{ line }}">Edit/Delete</a>
@ -327,9 +327,9 @@
{% if "timeout" not in line and "default-server" not in line and "#use_backend" not in line and "#" not in line%}
<span class="numRow">
{{ i }}
</span>
</span>
<span class="paramInSec">
{{ line }}
{{ line }}
</span><br />
{% continue %}
{% endif %}
@ -341,13 +341,13 @@
<span class="comment">
{{ line }}
</span><br />
{% continue %}
{% continue %}
{% endif %}
{% if line|length > 1 %}
<span class="configLine">
<span class="numRow">{{ i }}</span>
<span class="numRow">{{ i }}</span>
{{ line }}
</span><br />
</span><br />
{% endif %}
{%- if "bind" in line and "@" not in line and "-" not in line -%}
{%- set bind = line.split(':')[1] -%}

View File

@ -82,8 +82,9 @@
{% else %}
<div style="text-align: center;">
<br />
<h3>You have not installed OpenVPN client.
Read <a href="https://roxy-wi.org/services.py?service=openvpn" title="OpenVPN" style="color: #5d9ceb;" target="_blank">hear</a>
how to install OpenVPN client</h3>
<h3>You have not installed OpenVPN client.</h3>
<img src="/inc/images/no_servers.png" alt="There is no server">
<h4>Read <a href="https://roxy-wi.org/services/openvpn" title="OpenVPN" style="color: #5d9ceb;" target="_blank">here</a>
how to install OpenVPN client.</h4>
</div>
{% endif %}
{% endif %}

View File

@ -21,7 +21,7 @@
</div>
{% else %}
<div id="checker_tabs">
<ul>
<ul id="checker-tabs-head">
<li><a href="#channels" title="Checker channels - Roxy-WI">Channels</a></li>
<li><a href="#checker_settings" title="Checker settings - Roxy-WI">Settings</a></li>
</ul>

View File

@ -30,6 +30,9 @@
<script defer src="/inc/fontawesome.min.js"></script>
<script>FontAwesomeConfig = { searchPseudoElements: true, observeMutations: false };</script>
<script defer src="/inc/ion.sound.min.js"></script>
<script defer src="/inc/intro/introjs.min.js"></script>
<link href="/inc/intro/introjs.min.css" rel="stylesheet">
<link href="/inc/intro/introjs-modern.css" rel="stylesheet">
<link href="/inc/css/awesome.css" rel="stylesheet">
<link href="/inc/css/style.css" rel="stylesheet">
<link href="/inc/css/nprogress.css" rel="stylesheet">
@ -62,7 +65,7 @@
<nav id="menu">
<ul class="menu">
{% if user %}
<li><a href="/app/overview.py" title="Server and service status" class="overview-link">Overview</a></li>
<li><a href="/app/overview.py" title="Server and service status" class="overview-link ">Overview</a></li>
{% if '1' in user_services %}
<li class="p_menu">
<a href="/app/hapservers.py?service=haproxy" title="HAProxy servers overview" class="config-show">HAProxy</a>
@ -162,18 +165,18 @@
</li>
{% endif %}
{% if role <= 1 %}
<li class="p_menu">
<li class="p_menu" id="admin-area">
<a href="/app/users.py#users" title="Admin area" class="admin">Admin area</a>
<ul class="v_menu">
<li><a href="/app/users.py#users" title="Admin area: Manage users" class="users head-submenu">Users</a></li>
<li><a href="/app/users.py#groups" title="Admin area: Manage groups" class="group groups head-submenu">Groups</a></li>
<li><a href="/app/users.py#servers" title="Admin area: Manage servers" class="runtime servers head-submenu">Servers</a></li>
<li><a href="/app/users.py#ssh" title="Admin area: Manage SSH credentials" class="admin ssh head-submenu">SSH credentials</a></li>
<li><a href="/app/users.py#checker" title="Admin area: Checker" class="checker head-submenu">Checker</a></li>
<li><a href="/app/users.py#settings" title="Admin area: Manage Roxy-WI settings" class="settings head-submenu">Settings</a></li>
<li><a href="/app/users.py#services" title="Admin area: Manage Roxy-WI services" class="services head-submenu">Services</a></li>
<li><a href="/app/viewlogs.py" title="Admin area: View internal logs" class="logs head-submenu">Internal logs</a></li>
<li><a href="/app/users.py#updatehapwi" title="Admin area: Update Roxy-WI" class="upload updatehapwi head-submenu">Update</a></li>
<li><a href="/app/users.py#users" title="Admin area: Manage users" class="users head-submenu" id="admin-area-users">Users</a></li>
<li><a href="/app/users.py#groups" title="Admin area: Manage groups" class="group groups head-submenu" id="admin-area-groups">Groups</a></li>
<li><a href="/app/users.py#servers" title="Admin area: Manage servers" class="runtime servers head-submenu" id="admin-area-servers">Servers</a></li>
<li><a href="/app/users.py#ssh" title="Admin area: Manage SSH credentials" class="admin ssh head-submenu" id="admin-area-ssh">SSH credentials</a></li>
<li><a href="/app/users.py#checker" title="Admin area: Checker" class="checker head-submenu" id="admin-area-checker">Checker</a></li>
<li><a href="/app/users.py#settings" title="Admin area: Manage Roxy-WI settings" class="settings head-submenu" id="admin-area-settings">Settings</a></li>
<li><a href="/app/users.py#services" title="Admin area: Manage Roxy-WI services" class="services head-submenu" id="admin-area-services">Services</a></li>
<li><a href="/app/viewlogs.py" title="Admin area: View internal logs" class="logs head-submenu" id="admin-area-logs">Internal logs</a></li>
<li><a href="/app/users.py#updatehapwi" title="Admin area: Update Roxy-WI" class="upload updatehapwi head-submenu" id="admin-area-update">Update</a></li>
</ul>
</li>
{% endif %}
@ -276,12 +279,14 @@
</a>
</div>
<div class="footer-div">
<a href="https://roxy-wi.org" class="footer-link" target="_blank" title="About Roxy-WI">About</a>
<a href="https://github.com/hap-wi/roxy-wi/issues" class="footer-link" target="_blank" title="Community help">Help</a>
<a href="https://sd.roxy-wi.org" class="footer-link" target="_blank" title="Service Desk">SD</a>
<a href="https://roxy-wi.org/contacts" class="footer-link" target="_blank">Contacts</a>
<a href="https://roxy-wi.org/cabinet" class="footer-link" target="_blank" title="Private cabinet">Cabinet</a>
<a href="https://roxy-wi.org/legal" class="footer-link" target="_blank" title="Legal Note">Legal</a>
<div id="useful-links">
<a href="https://roxy-wi.org" class="footer-link" target="_blank" title="About Roxy-WI">About</a>
<a href="https://github.com/hap-wi/roxy-wi/issues" class="footer-link" target="_blank" title="Community help">Help</a>
<a href="https://sd.roxy-wi.org" class="footer-link" target="_blank" title="Service Desk">SD</a>
<a href="https://roxy-wi.org/contacts" class="footer-link" target="_blank">Contacts</a>
<a href="https://roxy-wi.org/cabinet" class="footer-link" target="_blank" title="Private cabinet">Cabinet</a>
<a href="https://roxy-wi.org/legal" class="footer-link" target="_blank" title="Legal Note">Legal</a>
</div>
</div>
</div>
<div id="show-user-settings">

View File

@ -1,7 +1,7 @@
<div id="backup_tabs">
<ul>
<li><a href="#git_tab" title="Admin area: Upload to Git - Roxy-WI">Git</a></li>
<li><a href="#backup_tab" title="Admin area: Manage backup - Roxy-WI">Backup</a></li>
<li><a href="#git_tab" title="Admin area: Upload to Git - Roxy-WI" id="backup-git-li">Git</a></li>
<li><a href="#backup_tab" title="Admin area: Manage backup - Roxy-WI" id="backup-backup-li">Backup</a></li>
</ul>
<div id="git_tab">

View File

@ -3,8 +3,8 @@
<table class="overview" id="ajax-servers">
<thead>
<tr class="overviewHead">
<th class="padding10 first-collumn">Name</th>
<th class="ip-field" style="width: 10%">IP</th>
<th class="padding10 first-collumn" id="server-name-th">Name</th>
<th class="ip-field" style="width: 10% " id="server-ip-th">IP</th>
<th class="checkbox-head" style="width: 5%" class="help_cursor"><span title="SSH port">Port</span></th>
{% if page != "servers.py" %}
<th style="width: 10%">Group</th>
@ -13,16 +13,16 @@
<th style="min-width: 50px; padding-left: 5px;" class="help_cursor">
<span title="Virtual IP, something like VRRP">Virt</span>
</th>
<th class="checkbox-head" style="min-width: 75px">HAProxy</th>
<th class="checkbox-head" style="min-width: 65px;">Nginx</th>
<th class="checkbox-head" style="min-width: 65px;">Apache</th>
<th style="min-width: 100px;" class="help_cursor">
<th class="checkbox-head" style="min-width: 75px" id="server-haproxy-th">HAProxy</th>
<th class="checkbox-head" style="min-width: 65px;" id="server-nginx-th">Nginx</th>
<th class="checkbox-head" style="min-width: 65px;" id="server-apache-th">Apache</th>
<th style="min-width: 100px;" class="help_cursor" id="server-firewalld-th">
<span title="If the server has a firewall enabled, enable this option">Firewalld</span>
</th>
<th class="checkbox-head" style="min-width: 80px;" class="help_cursor">
<th class="checkbox-head" style="min-width: 80px;" class="help_cursor" id="server-protected-th">
<span title="If protection is enabled, then the server is inaccessible for editing by everyone except the admin role">Protected</span>
</th>
<th style="width: 10%" class="help_cursor">
<th style="width: 10%" class="help_cursor" id="server-slave-th">
<span id="slavefor-th" title="Actions with the master config will automatically apply on the slave">Slave for</span>
</th>
<th class="cred-field">Credentials</th>
@ -182,7 +182,7 @@
<br /><span class="add-button" title="Add server" id="add-server-button">+ Add</span>
<br /><br />
<div id="checkSshConnect"></div>
<div class="add-note addName alert alert-info" style="width: inherit; margin-right: 15px;">
<div class="add-note addName alert alert-info" style="width: inherit; margin-right: 15px;" id="servers-help-link">
You can read the description of all parameters <a href="https://roxy-wi.org/description/servers" title="Servers description" target="_blank">here</a>
or read HowTo in this <a href="https://roxy-wi.org/howto/setup" title="How to setup servers, group and SSH credentials" target="_blank">article</a>
</div>

View File

@ -3,13 +3,13 @@
<td class="padding10 first-collumn" style="width: 15%;" class="help_cursor">
<span title="It's just name alias. This alias will be use in 'Servers' page for choose credentials">Name<span>
</td>
<td class="padding10 first-collumn" style="width: 25%;" class="help_cursor">
<td class="padding10 first-collumn" style="width: 25%;" class="help_cursor" id="ssh-key-enabled-td">
<span title="If it is enabled, the key will be used, if turned off - the password. Do not forget to download the keys to all servers or install the sudo without a password">SSH key</span>
</td>
{% if page != "servers.py" %}
<td style="width: 25%;">Group</td>
{% endif %}
<td style="width: 100%;" class="help_cursor">
<td style="width: 100%;" class="help_cursor" id="ssh-user-name-td">
<span title="Enter SSH user name. If SSH key disabled, enter password for SSH user">User name</span>
</td>
<td></td>

View File

@ -3,15 +3,15 @@
<table class="overview" id="ajax-users">
<thead>
<tr class="overviewHead">
<th class="padding10 first-collumn">Login</th>
<th class="padding10 first-collumn" id="user-login-th">Login</th>
<th style="width: 10%">Password</th>
<th style="width: 10%">Active</th>
<th style="width: 10%" id="user-active-th">Active</th>
<th style="width: 20%">Email</th>
<th style="width: 10%">Role</th>
<th style="width: 10%" id="user-role-th">Role</th>
{% if page != "servers.py" %}
<th style="width: 10%">Group</th>
{% endif %}
<th style="width: 100%">Services</th>
<th style="width: 100%" id="user-services-th">Services</th>
<th></th>
<th></th>
<th></th>

View File

@ -1,17 +1,16 @@
<center>
<h4 style="font-size: 25px">Welcome and let's get started!</h4>
<iframe width="760" height="415" src="https://www.youtube.com/embed/VU-LFTAQSiw" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
<img src="/inc/images/no_servers.png" alt="There is no server">
<br />
<br />
<h4>
You don't have any servers.
Watch video how to add your first server
You don't have servers yet.
Read how to <a href="https://roxy-wi.org/howto/add-existing-server" title="How to add an existing server">add an existing server</a>
or create <a href="https://roxy-wi.org/howto/add-new-server" title="How to add a new server">a new one</a>
{% if role == 2 %}
and go to the
"<a href="servers.py#servers" title="Servers">Servers</a>"
and go to the "<a href="servers.py#servers" title="Servers">Servers</a>"
{% elif role == 1 %}
and go to the
"<a href="users.py#servers" title="Servers">Admin area</a>"
and go to the "<a href="users.py#servers" title="Servers">Admin area</a>"
{% endif %}
to add your first server
</h4>

View File

@ -0,0 +1,96 @@
<script>
function Intro() {
var intro = introJs();
intro.setOptions({
steps: [
{
element: document.querySelector('#admin-area'),
intro: "Only the user with superAdmin role can access the Admin area section",
position: 'right'
},
{
element: document.querySelector('#admin-area-users'),
intro: "Create, edit, lock/unlock users profiles, grant roles, add new users to groups",
position: 'right'
},
{
element: document.querySelector('#add-user-button'),
intro: " Add new objects clicking by this button",
position: 'left'
},
{
element: document.querySelector('#admin-area-groups'),
intro: " Add new groups or edit existing ones",
position: 'right'
},
{
element: document.querySelector('#admin-area-servers'),
intro: "Choose servers to display on the Overview page, manage their settings and restrict access to configuration files",
position: 'right'
},
{
element: document.querySelector('#servers-help-link'),
intro: "Note that some pages have more extended guides for them",
},
{
element: document.querySelector('#admin-area-ssh'),
intro: "Configure a key-based authentication and restrict access to a server for some users",
position: 'right'
},
{
element: document.querySelector('#admin-area-checker'),
intro: "Set up notifications and the way youll get them",
position: 'right'
},
{
element: document.querySelector('#checker-tabs-head'),
intro: "Note that notification channels and settings are in the different tabs",
},
{
element: document.querySelector('#admin-area-settings'),
intro: "Tap a service name to expand its settings",
position: 'right'
},
{
element: document.querySelector('#admin-area-services'),
intro: "Run, stop and restart services by pressing buttons and read their short descriptions",
position: 'right'
},
{
element: document.querySelector('#admin-area-logs'),
intro: "Select one of all internal logs and click the Show button",
position: 'right'
},
{
element: document.querySelector('#admin-area-update'),
intro: "Update services by pressing buttons and check their versions",
position: 'right'
},
{
element: document.querySelector('#admin-tabs'),
intro: "Navigate through Admin area by clicking tabs above as wel",
},
{
element: document.querySelector('#admin-tabs-vpn'),
intro: " You can access some subsections like OpenVPN..."
},
{
element: document.querySelector('#admin-tabs-backup'),
intro: "Git and Backup...",
},
{
element: document.querySelector('#admin-tabs-mon'),
intro: "and Monitoring installation this way",
},
{
element: document.querySelector('.guid_me'),
intro: "Phew...Im a bit tired of chatting. Would you like to take a break before we continue\n" +
"with another section of Roxy?",
}
]
});
return intro;
}
setTimeout(() => { var intro_temp = Intro(); startIntro(intro_temp); }, 3000);
</script>

View File

@ -0,0 +1,76 @@
<script>
function Intro() {
var intro = introJs();
intro.setOptions({
steps: [
{
element: document.querySelector('#body'),
title: "Welcome to Roxy-WI!",
intro: "We're going to explain some basics...",
},
{
element: document.querySelector('.overview-link'),
intro: "You're here now",
position: 'right'
},
{
element: document.querySelector('#overview-roxy-wi'),
title: "Dashboard #1",
intro: "List of your servers and statuses of services which Roxy-WI manages",
},
{
element: document.querySelector('#overview-load'),
title: "Dashboard #2",
intro: "Roxy-WI server load",
},
{
element: document.querySelector('#overview-services'),
title: "Dashboard #3",
intro: "Roxy-WI services status",
},
{
element: document.querySelector('#overview-users'),
title: "Dashboard #4",
intro: "Users info - hold your cursor on a user's name to see more details",
},
{
element: document.querySelector('#overview-groups'),
title: "Dashboard #5",
intro: "Group list",
},
{
element: document.querySelector('#overview-logs'),
title: "Dashboard #6",
intro: "Last log entries",
},
{
element: document.querySelector('#overview-subs'),
intro: "Subscription info",
},
{
element: document.querySelector('#version'),
intro: "Your Roxy-WI version",
},
{
element: document.querySelector('#useful-links'),
intro: "Useful links",
},
{
element: document.querySelector('#show-user-settings-button'),
intro: "Profile settings",
},
{
element: document.querySelector('.guid_me'),
intro: "Guide mode button",
},
{
element: document.querySelector('.menu'),
intro: "7 more sections left to discover. Meet you there :)",
}
]
});
return intro;
}
setTimeout(() => { var intro_temp = Intro(); startIntro(intro_temp); }, 3000);
</script>

View File

@ -0,0 +1,104 @@
<script>
function Intro() {
var intro = introJs();
intro.setOptions({
steps: [
{
element: document.querySelector('#ajax-users'),
intro: "Welcome to Admin Area! On this tab you can manage users!",
},
{
element: document.querySelector('#user-login-th'),
intro: "Login is a name. Quite obvious",
},
{
element: document.querySelector('#user-active-th'),
intro: "Is anyone suspicious? Disable him!",
},
{
element: document.querySelector('#user-role-th'),
intro: "Or change the role, you can make it read only, for example",
},
{
element: document.querySelector('#user-services-th'),
intro: "And if someone does not need access to all services, you can solve it here",
},
{
element: document.querySelector('#server-name-th'),
intro: "A name of servers",
},
{
element: document.querySelector('#server-ip-th'),
intro: "IP or DNS name",
},
{
element: document.querySelector('#server-haproxy-th'),
intro: "Is there HAProxy? If yes press here",
},
{
element: document.querySelector('#server-nginx-th'),
intro: "Same for Nginx",
},
{
element: document.querySelector('#server-apache-th'),
intro: "And for Apache",
},
{
element: document.querySelector('#server-firewalld-th'),
intro: "If there is Firewalld service and you would like to Roxy-WI manage it enable this checkbox",
},
{
element: document.querySelector('#server-protected-th'),
intro: "This checkbox should be enabled if only admin can edit configs",
},
{
element: document.querySelector('#server-slave-th'),
intro: "Is a server secondary in a cluster? Check a Master server for Slave and configs will be automatically synced after editing on Master server",
},
{
element: document.querySelector('#ssh-key-enabled-td'),
intro: "If it is enabled, the key will be used, if turned off - the password. Do not forget to download the keys to all servers or install the sudo without a password",
},
{
element: document.querySelector('#ssh-user-name-td'),
intro: "A user name on remote server"
},
{
element: document.querySelector('#ssh_cert'),
intro: "Do not forget upload a SSH key, if you enable it",
},
{
element: document.querySelector('#backup-git-li'),
intro: "Would you like to keep configs in Git? This place for it!",
},
{
element: document.querySelector('#backup-backup-li'),
intro: "Or backup versions of config to a remote server",
},
{
element: document.querySelector('#haproxy-table'),
intro: "Need detailed statistics from HAProxy? You can install an exporter and watch graphs in Grafana",
},
{
element: document.querySelector('#nginx-table'),
intro: "Same for NGINX",
},
{
element: document.querySelector('#apache-table'),
intro: "And Apache",
},
{
element: document.querySelector('#node-table'),
intro: "This exporter provides detailed information about servers. Quite useful",
},
{
element: document.querySelector('.guid_me'),
intro: "Guide mode button",
}
]
});
return intro;
}
setTimeout(() => { var intro_temp = Intro(); startIntro(intro_temp); }, 3000);
</script>

View File

@ -2,4 +2,34 @@
<span id="show-user-settings-button" class="menu-bar login" title="User settings for user {{ user }}" style="margin-top: 7px;"></span>
{% else %}
<a href=/app/login.py title="Login" class="login"> Login</a>
{% endif %}
{% if guide_me %}
{% if page %}
<style>
.guid_me {
float: right;
position: absolute;
color: #fff !important;
cursor: pointer;
top: 13px;
right: 11px;
font-size: 15px;
margin-right: 10px
}
</style>
{% else %}
<style>
.guid_me {
float: right;
position: absolute;
color: #fff !important;
cursor: pointer;
top: 8px;
right: 7px;
font-size: 17px;
margin-right: 10px
}
</style>
{% endif %}
<span class="info guid_me" title="Guide me" onclick="startIntroAgain()"></span>
{% endif %}

View File

@ -1,5 +1,5 @@
<table>
{% if page == 'users.py' %}
{% if page == 'users.py' %}
<table id="grafana-table">
<caption><h3>Installing Grafana and Prometheus servers</h3></caption>
<tr class="overviewHead">
<td class="padding10 first-collumn">Current installation</td>
@ -30,14 +30,14 @@
</td>
</tr>
</table>
{% endif %}
<table>
{% endif %}
<table id="haproxy-table">
<caption><h3>Install HAProxy Exporter</h3></caption>
<tr class="overviewHead">
<td class="padding10 first-collumn" style="width: 20%;">Current installation</td>
<td class="padding10 first-collumn" style="width: 30%;">Available Versions</td>
<td class="padding10 first-collumn" style="width: 30%;">Server</td>
<td class="help_cursor" style="width: 20%;" title="This exporter will be used by an external Prometheus. Also use this checkbox if you update the Exporter">External Prometheus</td>
<td class="help_cursor" style="width: 20%;" title="This exporter will be used by an external Prometheus. Also use this checkbox if you update the Exporter" data-intro="This exporter will be used by an external Prometheus. Also use this checkbox if you update the Exporter">External Prometheus</td>
<td></td>
<td></td>
</tr>
@ -62,7 +62,7 @@
</td>
</tr>
</table>
<table>
<table id="nginx-table">
<caption><h3>Install NGINX Exporter</h3></caption>
<tr class="overviewHead">
<td class="padding10 first-collumn" style="width: 20%;">Current installation</td>
@ -93,7 +93,7 @@
</td>
</tr>
</table>
<table>
<table id="apache-table">
<caption><h3>Install Apache Exporter</h3></caption>
<tr class="overviewHead">
<td class="padding10 first-collumn" style="width: 20%;">Current installation</td>
@ -124,7 +124,7 @@
</td>
</tr>
</table>
<table style="margin-top: 20px">
<table style="margin-top: 20px" id="node-table">
<caption><h3>Install Node Exporter</h3></caption>
<tr class="overviewHead">
<td class="padding10 first-collumn" style="width: 20%;">Current installation</td>

View File

@ -21,9 +21,10 @@
{% elif services == '0' %}
<div style="text-align: center;">
<br />
<h3>You have not installed Metrics service.
Read <a href="https://roxy-wi.org/services/metrics#installation" title="Metrics installation" style="color: #5d9ceb;" target="_blank">hear</a>
how to install Metrics service</h3>
<h3>You have not installed Metrics service.</h3>
<img src="/inc/images/no_servers.png" alt="There is no server">
<h4>Read <a href="https://roxy-wi.org/services/metrics#installation" title="Metrics installation" style="color: #5d9ceb;" target="_blank">here</a>
how to install Metrics service</h4>
</div>
{% else %}
{% if servers|length == 0 %}

View File

@ -19,7 +19,7 @@
<style>
.fa-sync-alt { margin-bottom: -1px; }
</style>
<table class="overview-wi">
<table class="overview-wi" id="overview-roxy-wi">
<tr class="overviewHead">
<td class="padding10 first-collumn-wi">
{% if role <= 2 %}
@ -63,7 +63,7 @@
<tr class="{{ loop.cycle('odd', 'even') }}" id="{{s[2]}}"></tr>
{% endfor %}
</table>
<table class="overview-wi">
<table class="overview-wi" id="overview-load">
<tr class="overviewHead" style="height: 30px;">
<td class="padding10 first-collumn-wi" colspan="2">
{% if role <= 1 %}
@ -91,15 +91,15 @@
</td>
</tr>
</table>
<table class="overview-wi">
<table class="overview-wi" id="overview-services">
<tr class="overviewHead">
<td class="padding10 first-collumn-wi" colspan=4>
{% if role <= 1 %}
<a href="/app/users.py#services" title="View services status" class="logs_link">
Services status
Roxy-WI services status
</a>
{% else %}
Services status
Roxy-WI services status
{% endif %}
</td>
</tr>
@ -311,7 +311,7 @@
{% elif role == 1 %}
{% set admin_uri = 'users.py' %}
{% endif %}
<table class="overview-wi">
<table class="overview-wi" id="overview-users">
<thead>
<tr class="overviewHead" style="height: 30px;">
<td class="padding10 first-collumn-wi">
@ -337,7 +337,7 @@
</table>
{% endif %}
{% if role <= 1 %}
<table class="overview-wi">
<table class="overview-wi" id="overview-groups">
<tr class="overviewHead">
<td class="padding10 first-collumn-wi">
<a href="users.py#groups" title="Manage groups" class="logs_link">Group</a>
@ -394,7 +394,7 @@
</table>
{% endif %}
{% if role <= 2 %}
<table class="overview-wi">
<table class="overview-wi" id="overview-logs">
<tr class="overviewHead">
<td class="padding10 first-collumn-wi">
{% if role == 2 %}
@ -437,7 +437,7 @@
</table>
{% endif %}
{% if role <= 1 %}
<table class="overview-wi">
<table class="overview-wi" id="overview-subs">
<tr class="overviewHead" style="height: 30px;">
<td class="padding10 first-collumn-wi" colspan="2">
<a href="https://roxy-wi.org/cabinet" title="Personal cabinet" class="logs_link" target="_blank">Subscription</a>
@ -450,6 +450,7 @@
<p><span class="ui-icon ui-icon-alert" style="float:left; margin:3px 12px 20px 0;"></span>Are you sure?</p>
</div>
<script>
showOverview(ip, hostnamea)
showOverview(ip, hostnamea);
</script>
{% include 'include/intro/ovw.html' %}
{% endblock %}

View File

@ -16,8 +16,10 @@
{% if not is_terraform %}
<center>
<br />
<h3>You have not installed Terraform. Read <a href="https://www.terraform.io/downloads.html"
title="Download Terraform" target="_blank">here</a> how to install Terraform</h3>
<h3>You have not installed Terraform.</h3>
<img src="/inc/images/no_servers.png" alt="There is no server">
<h4>Read <a href="https://www.terraform.io/downloads.html"
title="Download Terraform" target="_blank">here</a> how to install Terraform.</h4>
</center>
{% elif servers|length == 0 %}
{% include 'include/getstarted.html' %}

View File

@ -16,9 +16,9 @@
<li><a href="#checker" title="Servers: Manage checker - Roxy-WI">Checker</a></li>
<li><a href="#settings" title="Admin area: Manage Roxy-WI settings - Roxy-WI">Settings</a></li>
<li><a href="#installproxy" title="Servers: Proxy service installation - Roxy-WI">Proxy installation</a></li>
<li><a href="#backup" title="Servers: Backup configs - Roxy-WI">Backup</a></li>
<li><a href="#installmon" title="Servers: Monitoring service installation - Roxy-WI">Monitoring installation</a></li>
<li><a href="#geolite2" title="Servers: GeoLite2 - Roxy-WI">GeoLite2</a></li>
<li><a href="#backup" title="Servers: Backup configs - Roxy-WI">Backup</a></li>
{% include 'include/login.html' %}
</ul>
<ul id='browse_histroy'></ul>
@ -118,7 +118,9 @@
</table>
<div id="ajax"></div>
</div>
<div id="backup">
{% include 'include/admin_backup.html' %}
</div>
<div id="installmon">
{% include 'include/mon_installation.html' %}
</div>
@ -178,10 +180,6 @@
{% endfor %}
</div>
</div>
<div id="backup">
{% include 'include/admin_backup.html' %}
</div>
</div>
{% include 'include/admins_dialogs.html' %}
{% include 'include/change_pass_form.html' %}
@ -219,4 +217,5 @@
});
</script>
<link href="/inc/css/servers.css" rel="stylesheet"/>
{% include 'include/intro/servers.html' %}
{% endblock %}

View File

@ -21,14 +21,17 @@
{% elif smon|length == 0 and action != 'add' and action != 'history' and action != 'checker_history' %}
<div style="text-align: center;">
<br />
<h3>You do not have added servers in SMON service. Create your first server <a href="smon.py?action=add" title="Roxy-WI SMON" target="_blank">here</a> before use</h3>
<h3>You do not have added servers in SMON service.</h3>
<img src="/inc/images/no_servers.png" alt="There is no server">
<h4>Create your first server <a href="smon.py?action=add" title="Roxy-WI SMON" target="_blank">here</a> before use</h4>
<br />
<iframe width="860" height="515" src="https://www.youtube.com/embed/bJtRJeHG5B0" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
</div>
{% elif smon|length == 0 and action != 'add' and action == 'history' %}
<div style="text-align: center;">
<br />
<h3>No events added yet. Click here <a href="smon.py?action=add" title="Roxy-WI SMON" target="_blank">here</a> to see if new check have been added</h3>
<h3>No events added yet.</h3>
<img src="/inc/images/no_servers.png" alt="There is no server">
<h4>Click <a href="smon.py?action=add" title="Roxy-WI SMON" target="_blank">here</a> to see if new check have been added</h4>
<br />
</div>
{% elif smon|length == 0 and action != 'add' and action == 'checker_history' %}

View File

@ -44,7 +44,7 @@ rendered_template = template.render(
title="Admin area: Manage users", role=user_params['role'], user=user_params['user'], users=users, groups=sql.select_groups(),
servers=sql.select_servers(full=1), roles=sql.select_roles(), masters=masters, sshs=sql.select_ssh(),
settings=settings, backups=sql.select_backups(), services=services, timezones=pytz.all_timezones,
page="users.py", user_services=user_params['user_services'], ldap_enable=ldap_enable, gits=gits,
page="users.py", user_services=user_params['user_services'], ldap_enable=ldap_enable, gits=gits, guide_me=1,
user_status=user_subscription['user_status'], user_plan=user_subscription['user_plan'], token=user_params['token']
)
print(rendered_template)

BIN
inc/images/no_servers.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 158 KiB

File diff suppressed because one or more lines are too long

13
inc/intro/intro.module.js Normal file

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,55 @@
.introjs-tooltip {
background-color: var(--menu-color);
color: #fff;
}
.introjs-button,
.introjs-button:hover, .introjs-button:focus, .introjs-button:active,
.introjs-disabled, .introjs-disabled:focus, .introjs-disabled:hover {
outline: none;
background-image: none;
background-color: transparent;
color: #fff;
border: 1px solid transparent;
/*border-radius: 50px;*/
box-shadow: none;
border-shadow: none;
text-shadow: none;
}
.introjs-button:hover, .introjs-button:focus, .introjs-button:active {
border: 1px solid #fff
}
.introjs-disabled, .introjs-disabled:focus, .introjs-disabled:hover {
color: #ccc;
border: 1px solid transparent;
}
.introjs-arrow {
border: 10px solid #fff;
}
.introjs-arrow.top, .introjs-arrow.top-middle, .introjs-arrow.top-right {
border-color: transparent transparent var(--menu-color);
top: -20px;
left: 20px;
}
.introjs-arrow.bottom, .introjs-arrow.bottom-middle, .introjs-arrow.bottom-right {
border-color: rgba(000, 0, 0, 0.5) transparent transparent;
bottom: -20px;
left: 20px;
}
.introjs-arrow.left, .introjs-arrow.right {
top: 20px;
}
.introjs-arrow.left-bottom, .introjs-arrow.right-bottom {
bottom: 20px;
}
.introjs-arrow.left, .introjs-arrow.left-bottom {
left: -20px;
border-color: transparent rgba(000, 0, 0, 0.5) transparent transparent;
}
.introjs-arrow.right, .introjs-arrow.right-bottom {
right: -20px;
border-color: transparent transparent transparent rgba(000, 0, 0, 0.5);
}

2
inc/intro/introjs.min.css vendored Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

13
inc/intro/introjs.min.js vendored Normal file

File diff suppressed because one or more lines are too long

View File

@ -1589,7 +1589,78 @@ function statAgriment() {
sendGet('/page/send/'+cur_url);
}
}
window.onload = statAgriment;
function startIntroAgain() {
var intro_url = cur_url[0].split('#')[0];
var intro_history = {};
if (intro_url.split('#')[0] == 'users.py' || intro_url.split('#')[0] == 'servers.py') {
$("#tabs").tabs("option", "active", 0);
}
if(localStorage.getItem('intro') === null) {
startIntro();
} else {
intro_history = JSON.parse(localStorage.getItem('intro'));
delete intro_history[intro_url];
localStorage.setItem('intro', JSON.stringify(intro_history));
startIntro();
}
}
function startIntro(intro) {
intro = intro.setOptions({'exitOnOverlayClick': false});
var intro_url = cur_url[0].split('#')[0];
var intro_history = {};
intro.onbeforechange(function (targetElement) {
if (intro_url == 'users.py' && this._currentStep == 5) {
$("#tabs").tabs("option", "active", 2);
} else if (intro_url == 'users.py' && this._currentStep == 13) {
$("#tabs").tabs("option", "active", 3);
} else if (intro_url == 'users.py' && this._currentStep == 16) {
$("#tabs").tabs("option", "active", 9);
} else if (intro_url == 'users.py' && this._currentStep == 18) {
$("#tabs").tabs("option", "active", 10);
}
if (intro_url == 'servers.py' && this._currentStep == 5) {
$("#tabs").tabs("option", "active", 1);
} else if (intro_url == 'servers.py' && this._currentStep == 13) {
$("#tabs").tabs("option", "active", 2);
} else if (intro_url == 'servers.py' && this._currentStep == 16) {
$("#tabs").tabs("option", "active", 6);
} else if (intro_url == 'servers.py' && this._currentStep == 18) {
$("#tabs").tabs("option", "active", 7);
}
});
intro.onbeforeexit(function () {
if(localStorage.getItem('intro') === null) {
intro_history[intro_url] = '1';
localStorage.setItem('intro', JSON.stringify(intro_history));
} else {
intro_history = localStorage.getItem('intro');
intro_history = JSON.parse(intro_history);
intro_history[intro_url] = '1';
localStorage.setItem('intro', JSON.stringify(intro_history));
}
});
intro.onexit(function() {
sendGet('intro/' + intro_url + '/' + this._currentStep);
});
if(localStorage.getItem('intro') === null) {
if (intro_url.split('#')[0] == 'users.py' || intro_url.split('#')[0] == 'servers.py') {
$( "#tabs" ).tabs( "option", "active", 0 );
}
intro.start();
} else {
intro_history = localStorage.getItem('intro');
intro_history = JSON.parse(intro_history);
if (intro_history[intro_url] != '1') {
if (intro_url.split('#')[0] == 'users.py' || intro_url.split('#')[0] == 'servers.py') {
$( "#tabs" ).tabs( "option", "active", 0 );
}
intro.start();
}
}
}
document.addEventListener("DOMContentLoaded", function(event){
statAgriment();
});
function sendGet(page) {
var xmlHttp = new XMLHttpRequest();
var theUrl = 'https://roxy-wi.org/' + page;

View File

@ -26,6 +26,9 @@
<meta name="msapplication-TileColor" content="#ffffff">
<meta name="msapplication-TileImage" content="/inc/images/favicon/ms-icon-144x144.png">
<meta name="theme-color" content="#ffffff">
<script defer src="/inc/intro/introjs.min.js"></script>
<link href="/inc/intro/introjs.min.css" rel="stylesheet">
<link href="/inc/intro/introjs-modern.css" rel="stylesheet">
<link href="/inc/css/style.css" rel="stylesheet">
<link href="/inc/css/nprogress.css" rel="stylesheet">
<link href="/inc/css/provisioning.css" rel="stylesheet">