Pavel Loginov 2021-01-09 21:42:08 +06:00
parent 03b8cbe4ba
commit e9c28c95a7
12 changed files with 321 additions and 52 deletions

View File

@ -2246,3 +2246,37 @@ if form.getvalue('geoipserv') is not None:
cmd = ["ls " + haproxy_dir + "/geoip/"]
print(funct.ssh_command(serv, cmd))
if form.getvalue('geoip_install'):
serv = form.getvalue('geoip_install')
geoip_update = form.getvalue('geoip_update')
proxy = sql.get_setting('proxy')
maxmind_key = sql.get_setting('maxmind_key')
haproxy_dir = sql.get_setting('haproxy_dir')
script = 'install_geoip.sh'
ssh_enable, ssh_user_name, ssh_user_password, ssh_key_name = funct.return_ssh_keys_path(serv)
if ssh_enable == 0:
ssh_key_name = ''
servers = sql.select_servers(server=serv)
for server in servers:
ssh_port = str(server[10])
if proxy is not None and proxy != '' and proxy != 'None':
proxy_serv = proxy
else:
proxy_serv = ''
os.system("cp scripts/%s ." % script)
commands = ["chmod +x " + script + " && ./" + script + " PROXY=" + proxy_serv + " SSH_PORT=" + ssh_port +
" UPDATE=" + str(geoip_update) + " maxmind_key=" + maxmind_key + " haproxy_dir=" + haproxy_dir +
" HOST=" + str(serv) +" USER=" + str(ssh_user_name) + " PASS=" + str(ssh_user_password) +
" KEY=" + str(ssh_key_name)]
output, error = funct.subprocess_execute(commands[0])
funct.show_installation_output(error, output, 'GeoLite2 Database')
os.system("rm -f %s" % script)

View File

@ -0,0 +1,43 @@
#!/bin/bash
set -e -o pipefail
country_location="GeoLite2-Country-CSV_*/GeoLite2-Country-Locations-en.csv"
country_ip="GeoLite2-Country-CSV_*/GeoLite2-Country-Blocks-IPv4.csv"
haproxy_dir="{{haproxy_dir}}"
MAXMIND_LICENSE="{{maxmind_key}}"
cd /tmp
if [[ ! -d geo2lite ]]; then
mkdir geo2lite && cd geo2lite && mkdir subnets
else
cd geo2lite
fi
if [[ -f geoip2lite.zip ]]; then
rm -f geoip2lite.zip
fi
wget "https://download.maxmind.com/app/geoip_download?edition_id=GeoLite2-Country-CSV&license_key=${MAXMIND_LICENSE}&suffix=zip" -qO geoip2lite.zip && unzip -oq geoip2lite.zip
function get_ips_by_country {
rm -f subnets/$2.subnets
cat $country_ip |grep $1 |awk -F"," '{print $1}' >> subnets/$2.subnets
}
while read line; do
country_code_dig=$(echo $line |awk -F"," '{print $1}')
country_code_buk=$(echo $line |awk -F"," '{print $5}')
if [[ $country_code_dig != '' ]] && [[ $country_code_buk != '' ]] && [[ $country_code_buk != 'country_iso_code' ]] ; then
get_ips_by_country $country_code_dig $country_code_buk
fi
done < $country_location
if [[ ! -d "$haproxy_dir"/geoip ]]; then
mkdir "$haproxy_dir"/geoip
fi
cp subnets/* "$haproxy_dir"/geoip

View File

@ -0,0 +1,45 @@
- hosts: "{{ variable_host }}"
become: yes
become_method: sudo
tasks:
- name: Set SSH port
set_fact:
ansible_port: "{{SSH_PORT}}"
- name: Creates directory
file:
path: "{{haproxy_dir}}/geoip"
state: directory
- name: Creates directory
file:
path: "{{haproxy_dir}}/scripts"
state: directory
- name: Install wget
package:
name: "{{ item }}"
state: present
environment:
http_proxy: "{{PROXY}}"
https_proxy: "{{PROXY}}"
with_items:
- wget
- unzip
- name: Copy GeoIP script in place.
template:
src: /var/www/haproxy-wi/app/scripts/ansible/roles/geoip.sh.j2
dest: "{{haproxy_dir}}/scripts/geoip.sh"
mode: 0777
- name: Execute the script
command: "{{haproxy_dir}}/scripts/geoip.sh"
- name: Update geoip every Wednesday
cron:
name: "Update geoip"
minute: "0"
hour: "01"
weekday: "3"
job: "{{haproxy_dir}}/scripts/geoip.sh"

View File

@ -0,0 +1,41 @@
#!/bin/bash
for ARGUMENT in "$@"
do
KEY=$(echo "$ARGUMENT" | cut -f1 -d=)
VALUE=$(echo "$ARGUMENT" | cut -f2 -d=)
case "$KEY" in
PROXY) PROXY=${VALUE} ;;
UPDATE) UPDATE=${VALUE} ;;
maxmind_key) maxmind_key=${VALUE} ;;
haproxy_dir) haproxy_dir=${VALUE} ;;
HOST) HOST=${VALUE} ;;
USER) USER=${VALUE} ;;
PASS) PASS=${VALUE} ;;
KEY) KEY=${VALUE} ;;
SSH_PORT) SSH_PORT=${VALUE} ;;
*)
esac
done
export ANSIBLE_HOST_KEY_CHECKING=False
export ANSIBLE_DISPLAY_SKIPPED_HOSTS=False
export ACTION_WARNINGS=False
export LOCALHOST_WARNING=False
export COMMAND_WARNINGS=False
PWD=$(pwd)
PWD=$PWD/scripts/ansible/
echo "$HOST ansible_port=$SSH_PORT" > $PWD/$HOST
if [[ $KEY == "" ]]; then
ansible-playbook $PWD/roles/geoip.yml -e "ansible_user=$USER ansible_ssh_pass=$PASS variable_host=$HOST PROXY=$PROXY UPDATE=$UPDATE haproxy_dir=$haproxy_dir maxmind_key=$maxmind_key SSH_PORT=$SSH_PORT" -i $PWD/$HOST
else
ansible-playbook $PWD/roles/geoip.yml --key-file $KEY -e "ansible_user=$USER variable_host=$HOST PROXY=$PROXY UPDATE=$UPDATE haproxy_dir=$haproxy_dir maxmind_key=$maxmind_key SSH_PORT=$SSH_PORT" -i $PWD/$HOST
fi
if [ $? -gt 0 ]
then
echo "error: Cannot download GeoLite2 database"
fi
rm -f $PWD/$HOST

View File

@ -40,7 +40,6 @@ fi
if [ $? -gt 0 ]
then
echo "error: Can't install Haproxy service <br /><br />"
exit 1
echo "error: Cannot install Haproxy service"
fi
rm -f $PWD/$HOST

View File

@ -2,7 +2,7 @@
import funct
import sql
from jinja2 import Environment, FileSystemLoader
env = Environment(extensions=["jinja2.ext.do"],loader=FileSystemLoader('templates/'), autoescape=True)
env = Environment(extensions=["jinja2.ext.do"], loader=FileSystemLoader('templates/'), autoescape=True)
template = env.get_template('servers.html')
form = funct.form
@ -15,26 +15,47 @@ try:
grafana, stderr = funct.subprocess_execute("service grafana-server status |grep Active |awk '{print $1}'")
user_group = funct.get_user_group(id=1)
settings = sql.get_setting('', all=1)
geoip_country_codes = sql.select_geoip_country_codes()
services = []
services_name = {'checker_haproxy': 'Checker backends master service',}
for s, v in services_name.items():
cmd = "systemctl status %s |grep Act |awk '{print $2}'" % s
status, stderr = funct.subprocess_execute(cmd)
if s != 'keep_alive':
service_name = s.split('_')[0]
else:
service_name = s
cmd = "rpm --query haproxy-wi-"+service_name+"-* |awk -F\""+service_name + "\" '{print $2}' |awk -F\".noa\" '{print $1}' |sed 's/-//1' |sed 's/-/./'"
service_ver, stderr = funct.subprocess_execute(cmd)
try:
services.append([s, status, v, service_ver[0]])
except Exception:
services.append([s, status, v, ''])
except Exception as e:
pass
output_from_parsed_template = template.render(title = "Servers: ",
role = role,
user = user,
users = sql.select_users(group=user_group),
groups = sql.select_groups(),
servers = sql.get_dick_permit(virt=1, disable=0),
roles = sql.select_roles(),
masters = sql.select_servers(get_master_servers=1, uuid=user_id.value),
group = user_group,
sshs = sql.select_ssh(group=user_group),
telegrams = sql.get_user_telegram_by_group(user_group),
token = token,
versions = funct.versions(),
settings = settings,
backups = sql.select_backups(),
grafana = ''.join(grafana),
page = "servers.py",
ldap_enable = ldap_enable)
output_from_parsed_template = template.render(title="Servers: ",
role=role,
user=user,
users=sql.select_users(group=user_group),
groups=sql.select_groups(),
servers=sql.get_dick_permit(virt=1, disable=0),
roles=sql.select_roles(),
masters=sql.select_servers(get_master_servers=1, uuid=user_id.value),
group=user_group,
sshs=sql.select_ssh(group=user_group),
telegrams=sql.get_user_telegram_by_group(user_group),
token=token,
versions=funct.versions(),
settings=settings,
backups=sql.select_backups(),
grafana=''.join(grafana),
page="servers.py",
geoip_country_codes=geoip_country_codes,
services=services,
ldap_enable=ldap_enable)
print(output_from_parsed_template)

View File

@ -0,0 +1,6 @@
<div class="group_error">
<div class="alert alert-danger">
<b>Do not edit this section if your group is "ALL"!</b> Add first <a href="users.py#groups" title="Admin Area: Groups">group</a>
or change your current group at <a href="users.py#users" title="Admin Area: Users">users</a> page
</div>
</div>

View File

@ -16,28 +16,34 @@
<li><a href="#settings" title="Admin area: Manage HAProxy-WI settings - HAProxy-WI">Settings</a></li>
<li><a href="#installproxy" title="Servers: Proxy service installation - HAProxy-WI">Proxy installation</a></li>
<li><a href="#installmon" title="Servers: Monitoring service installation - HAProxy-WI">Monitoring installation</a></li>
<li><a href="#geolite2" title="Servers: GeoLite2 - HAProxy-WI">GeoLite2</a></li>
<li><a href="#backup" title="Servers: Backup configs - HAProxy-WI">Backup</a></li>
{% include 'include/login.html' %}
</ul>
<ul id='browse_histroy'></ul>
<div id="users">
{% include 'include/admin_users.html' %}
{% include 'include/servers_group_error.html' %}
</div>
<div id="servers">
{% include 'include/admin_servers.html' %}
{% include 'include/servers_group_error.html' %}
</div>
<div id="ssh">
{% include 'include/admin_ssh.html' %}
{% include 'include/servers_group_error.html' %}
</div>
<div id="checker">
{% include 'include/admin_telegram.html' %}
{% include 'include/servers_group_error.html' %}
</div>
<div id="settings">
{% include 'include/admin_settings.html' %}
{% include 'include/servers_group_error.html' %}
</div>
<div id="installproxy">
@ -114,21 +120,64 @@
{% include 'include/mon_installation.html' %}
</div>
<div id="geolite2">
<table>
<caption><h3>Install GeoLite2</h3></caption>
<tr class="overviewHead">
<td class="padding10 first-collumn">Server</td>
<td class="padding10 first-collumn" style="width: 30%;">Current installation</td>
<td class="" style="width: 30%;" title="GeoLite2 DB is released every Tuesday. Should HAProxy-WI update it?">Updating</td>
<td></td>
<td></td>
</tr>
<tr>
<td class="padding10 first-collumn">
<select autofocus required name="geoipserv" id="geoipserv">
<option disabled selected>Choose server</option>
{% for select in servers %}
<option value="{{ select.2 }}">{{ select.1 }}</option>
{% endfor %}
</select>
</td>
<td id="cur_geoip" class="padding10"></td>
<td class="checkbox">
{{ checkbox('updating_geoip', title="Update the database?", checked='checked') }}
</td>
<td>
<span class="ui-button ui-widget ui-corner-all" id="geoip_install" title="Install GeoLite2" style="display: none;">Install</span>
</td>
</tr>
</table>
<div id="ajax-geoip"></div>
<div class="add-note addName alert-info" style="width: inherit; margin-right: 15px; margin-bottom: 15px;">
Read the "how to" in this <a href="https://haproxy-wi.org/howto.py?howto=geoip" title="GeoLite2 description" target="_blank">article</a>
</div>
<table style="min-width: 40%;">
<tr class="overviewHead">
<th colspan=13 style="background-color: #d1ecf1; padding: 10px;">
<span id="table_metrics_head" style="position: absolute;margin-left: 43%;">Country codes</span>
<span id="show_country_codes" class="add switcher_table_metric" title="Show country codes"></span>
<span id="hide_country_codes" class="minus switcher_table_metric" title="Hide country codes" style="display: none;"></span>
</th>
</tr>
</table>
<div id="geoip_country_codes" style="display: none;">
{% for code in geoip_country_codes %}
<div class="geoip_country_code" id="{{code.1}}">{{code.1}} ({{code.2}})</div>
{% endfor %}
</div>
</div>
<div id="backup">
{% include 'include/admin_backup.html' %}
</div>
</div>
<div id="group_error" style="display: none; clear: both;">
<div class="alert alert-danger">
<b>Do not edit this section if your group is "ALL"!</b> Add first<a href="users.py#groups" title="Admin Area: Groups">group</a> or edit your own group at<a href="users.py#users" title="Admin Area: Users">users</a> page
{% include 'include/servers_group_error.html' %}
</div>
</div>
{% include 'include/admins_dialogs.html' %}
{% include 'include/change_pass_form.html' %}
<script>
if($('#new-server-group-add').val() == 1) {
$('#group_error').css('display', 'block');
$('.group_error').css('display', 'block');
$('#add-user-button').css('display', 'none');
$('#add-server-button').css('display', 'none');
$('.passwordChange').css('display', 'none');
@ -191,5 +240,10 @@
padding-top: 0.6em !important;
}
}
.group_error {
display: none;
clear: both;
height: 60px;
}
</style>
{% endblock %}

View File

@ -61,7 +61,7 @@ $( function() {
type: frm.attr('method'),
success: function( data ) {
data = data.replace('\n', '<br>');
if (data.indexOf('error: ') != '-1' || data.indexOf('Fatal') != '-1') {
if (data.indexOf('error: ') != '-1' || data.indexOf('Fatal') != '-1' || data.indexOf('Error(s)') != '-1') {
toastr.clear();
toastr.error(data);
} else {

View File

@ -1059,16 +1059,13 @@ function replace_text(id_textarea, text_var) {
$(id_textarea).text(text_val);
}
function createHistroy() {
try {
var get_history_array = JSON.parse(Cookies.get('history'));
}
catch {
if(localStorage.getItem('history') === null) {
var get_history_array = ['login.py', 'login.py','login.py'];
Cookies.set('history', JSON.stringify(get_history_array), { expires: 10, path: '/app', samesite: 'strict', secure: 'true' });
localStorage.setItem('history', JSON.stringify(get_history_array));
}
}
function listHistroy() {
var browse_history = JSON.parse(Cookies.get('history'));
var browse_history = JSON.parse(localStorage.getItem('history'));
var history_link = '';
var title = []
var link_text = []
@ -1082,7 +1079,7 @@ function listHistroy() {
if (i == 2) {
if(cur_url[1] !== undefined) {
browse_history[2] = cur_url[0] + '?' + cur_url[1]
}else {
} else {
browse_history[2] = cur_url[0]
}
}
@ -1095,16 +1092,11 @@ function listHistroy() {
link_text[i] = $(this).find('a').text();
history_link = '<li><a href="'+browse_history[i]+'" title="'+title[i]+'">'+link_text[i]+'</a></li>'
$('#browse_histroy').append(history_link);
} else if (browse_history[i].split('?')[0] == link2) {
title[i] = $(this).find('a').attr('title');
link_text[i] = $(this).find('a').text();
history_link = '<li><a href="'+browse_history[i]+'" title="'+title[i]+'">'+link_text[i]+'</a></li>'
$('#browse_histroy').append(history_link);
}
});
});
}
Cookies.set('history', JSON.stringify(browse_history), { expires: 10, path: '/app', samesite: 'strict', secure: 'true' });
localStorage.setItem('history', JSON.stringify(browse_history));
}
createHistroy()
listHistroy()
@ -1224,7 +1216,7 @@ async function waitConsumer() {
cur_url = cur_url.split('?');
if (cur_url[0] != 'servers.py#installproxy' && cur_url[0] != 'servers.py#installmon' &&
cur_url[0] != 'users.py#installmon' && cur_url[0] != 'ha.py' && cur_url[0] != 'users.py#updatehapwi' &&
cur_url[0] != 'add.py?service=nginx#ssl' && cur_url[0] != 'add.py#ssl') {
cur_url[0] != 'add.py?service=nginx#ssl' && cur_url[0] != 'add.py#ssl' && cur_url[0] != 'servers.py#geolite2') {
NProgress.configure({showSpinner: false});
$.ajax({
url: "options.py",

View File

@ -42,10 +42,9 @@ ul#browse_histroy li {
padding-right: 5px;
}
ul#browse_histroy li+li:before {
content: "\003e";
color: #000;
font-weight: bold;
margin-right: 2.5px;
content: "/";
color: #767676;
margin: 0 9px 0px 2.5px;
}
#browse_histroy a {
color: #767676;
@ -570,7 +569,6 @@ ul{
.ui-button {
padding-left: 10px !important;
padding-right: 10px !important;
background: #f4f9f380 !important;
}
@media all and (-webkit-min-device-pixel-ratio:0) and (min-resolution: .001dpcm) {
.ui-checkboxradio-label {
@ -678,15 +676,13 @@ td,th {
padding:15px;
margin-bottom:20px;
border:1px solid transparent;
border-radius:4px;
width: 400px;
display: block;
}
.alert a {
cursor: pointer;
font-weight: bold;
padding-left: 10px;
margin-bottom: 10px;
margin-bottom: 10px;
color: #23527c !important;
}
.alert-danger, .alert-info, .alert-success, .alert-warning, .added {
margin-left: 15px;

View File

@ -179,6 +179,7 @@ $( function() {
} else if (data.indexOf('success') != '-1' ){
toastr.remove();
toastr.success(data);
$( "#haproxyaddserv" ).trigger( "selectmenuchange" );
} else if (data.indexOf('Info') != '-1' ){
toastr.remove();
toastr.info(data);
@ -213,6 +214,7 @@ $( function() {
} else if (data.indexOf('success') != '-1' ){
toastr.clear();
toastr.success(data);
$("#nginxaddserv").trigger( "selectmenuchange" );
} else if (data.indexOf('Info') != '-1' ){
toastr.clear();
toastr.info(data);
@ -273,6 +275,7 @@ $( function() {
toastr.success(data);
$('#cur_haproxy_exp_ver').text('HAProxy expoter is installed');
$('#haproxy_exp_install').text('Update');
$("#haproxy_exp_addserv").trigger( "selectmenuchange" );
} else if (data.indexOf('Info') != '-1' ){
toastr.clear();
toastr.info(data);
@ -303,6 +306,7 @@ $( function() {
toastr.success(data);
$('#cur_nginx_exp_ver').text('Nginx expoter is installed');
$('#nginx_exp_install').text('Update');
$("#nginx_exp_addserv").trigger( "selectmenuchange" );
} else if (data.indexOf('Info') != '-1' ){
toastr.clear();
toastr.info(data);
@ -738,6 +742,40 @@ $( function() {
}
} );
});
$( "#geoip_install" ).click(function() {
var updating_geoip = 0;
if ($('#updating_geoip').is(':checked')) {
updating_geoip = '1';
}
$("#ajax-geoip").html(wait_mess);
$.ajax( {
url: "options.py",
data: {
geoip_install: $('#geoipserv option:selected').val(),
geoip_update: updating_geoip,
token: $('#token').val()
},
type: "POST",
success: function( data ) {
data = data.replace(/^\s+|\s+$/g,'');
$("#ajax-geoip").html('')
if (data.indexOf('error:') != '-1' || data.indexOf('FAILED') != '-1') {
toastr.clear();
toastr.error(data);
} else if (data.indexOf('success:') != '-1' ){
toastr.clear();
toastr.success(data);
$( "#geoipserv" ).trigger( "selectmenuchange" );
} else if (data.indexOf('Info') != '-1' ){
toastr.clear();
toastr.info(data);
} else {
toastr.clear();
toastr.info(data);
}
}
} );
});
} );
function common_ajax_action_after_success(dialog_id, new_group, ajax_append_id, data) {
toastr.clear();