First files to the project
This commit is contained in:
commit
cda8eb1232
26 changed files with 2657 additions and 0 deletions
108
.gitignore
vendored
Normal file
108
.gitignore
vendored
Normal file
|
|
@ -0,0 +1,108 @@
|
|||
# Byte-compiled / optimized / DLL files
|
||||
__pycache__/
|
||||
*.py[cod]
|
||||
*$py.class
|
||||
|
||||
# C extensions
|
||||
*.so
|
||||
|
||||
# Distribution / packaging
|
||||
.Python
|
||||
build/
|
||||
develop-eggs/
|
||||
dist/
|
||||
downloads/
|
||||
eggs/
|
||||
.eggs/
|
||||
lib/
|
||||
lib64/
|
||||
parts/
|
||||
sdist/
|
||||
var/
|
||||
wheels/
|
||||
*.egg-info/
|
||||
.installed.cfg
|
||||
*.egg
|
||||
MANIFEST
|
||||
|
||||
# PyInstaller
|
||||
# Usually these files are written by a python script from a template
|
||||
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
||||
*.manifest
|
||||
*.spec
|
||||
|
||||
# Installer logs
|
||||
pip-log.txt
|
||||
pip-delete-this-directory.txt
|
||||
|
||||
# Unit test / coverage reports
|
||||
htmlcov/
|
||||
.tox/
|
||||
.coverage
|
||||
.coverage.*
|
||||
.cache
|
||||
nosetests.xml
|
||||
coverage.xml
|
||||
*.cover
|
||||
.hypothesis/
|
||||
|
||||
# Translations
|
||||
*.mo
|
||||
*.pot
|
||||
|
||||
# Django stuff:
|
||||
*.log
|
||||
.static_storage/
|
||||
.media/
|
||||
local_settings.py
|
||||
|
||||
# Flask stuff:
|
||||
instance/
|
||||
.webassets-cache
|
||||
|
||||
# Scrapy stuff:
|
||||
.scrapy
|
||||
|
||||
# Sphinx documentation
|
||||
docs/_build/
|
||||
|
||||
# PyBuilder
|
||||
target/
|
||||
|
||||
# Jupyter Notebook
|
||||
.ipynb_checkpoints
|
||||
|
||||
# pyenv
|
||||
.python-version
|
||||
|
||||
# celery beat schedule file
|
||||
celerybeat-schedule
|
||||
|
||||
# SageMath parsed files
|
||||
*.sage.py
|
||||
|
||||
# Environments
|
||||
.env
|
||||
.venv
|
||||
env/
|
||||
venv/
|
||||
ENV/
|
||||
env.bak/
|
||||
venv.bak/
|
||||
|
||||
# Spyder project settings
|
||||
.spyderproject
|
||||
.spyproject
|
||||
|
||||
# Rope project settings
|
||||
.ropeproject
|
||||
|
||||
# mkdocs documentation
|
||||
/site
|
||||
|
||||
# mypy
|
||||
.mypy_cache/
|
||||
|
||||
/backups
|
||||
/settings/config.py
|
||||
/media/js/jsutils
|
||||
3
__init__.py
Normal file
3
__init__.py
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
from flask import Blueprint, g
|
||||
|
||||
pastafari_app=Blueprint('pastafari_app', __name__)
|
||||
541
admin/dashboard.py
Normal file
541
admin/dashboard.py
Normal file
|
|
@ -0,0 +1,541 @@
|
|||
from settings import config
|
||||
from flask import g, url_for, request, session, make_response
|
||||
from paramecio2.libraries.generate_admin_class import GenerateAdminClass
|
||||
from paramecio2.libraries.i18n import I18n
|
||||
from paramecio2.modules.admin import admin_app, t as admin_t
|
||||
from paramecio2.libraries.db.coreforms import SelectForm, SelectModelForm
|
||||
from paramecio2.libraries.mtemplates import PTemplate, env_theme
|
||||
from paramecio2.libraries import datetime
|
||||
from paramecio2.libraries.urls import make_media_url
|
||||
from modules.monit.models.monit import Server, ServerData, Alerts
|
||||
from paramecio2.libraries.db.webmodel import WebModel
|
||||
from paramecio2.libraries.lists import AjaxList
|
||||
from paramecio2.libraries.db.extraforms.fileform import FileForm
|
||||
from paramecio2.libraries.formsutils import show_form
|
||||
from modules.pastafari2.libraries.task import Task as SSHTask
|
||||
from modules.pastafari2.models.tasks import Task, LogTask
|
||||
from modules.pastafari2.libraries.configtask import config_task
|
||||
from modules.pastafari2.models.pastafari2 import ServerGroup
|
||||
from pathlib import Path
|
||||
import paramiko
|
||||
import socket
|
||||
import os
|
||||
try:
|
||||
import ujson as json
|
||||
except:
|
||||
import json
|
||||
|
||||
env=env_theme(__file__)
|
||||
|
||||
t=PTemplate(env)
|
||||
|
||||
t.env.directories=admin_t.env.directories
|
||||
|
||||
t.env.directories.insert(1, os.path.dirname(__file__).replace('/admin', '')+'/templates/admin')
|
||||
|
||||
system_path='./ssh/'
|
||||
|
||||
@admin_app.route('/pastafari2/dashboard/')
|
||||
def pastafari2_dashboard():
|
||||
|
||||
return t.load_template('dash_pastafari.phtml', title=I18n.lang('pastafari2', 'servers_dashboard', 'Servers Dashboard'), path_module='admin_app.pastafari2_dashboard')
|
||||
|
||||
@admin_app.route('/pastafari2/settings/')
|
||||
def pastafari2_settings():
|
||||
"""
|
||||
forms={}
|
||||
|
||||
forms['ssh_key_priv']=FileForm('ssh_key_priv', '', '')
|
||||
forms['ssh_key_pub']=FileForm('ssh_key_pub', '', '')
|
||||
|
||||
forms['ssh_key_priv'].help=I18n.lang('pastafari2', 'ssh_key_priv_file_help', 'Global private SSH key used for enter in servers')
|
||||
forms['ssh_key_pub'].help=I18n.lang('pastafari2', 'ssh_key_pub_file_help', 'Global public SSH key used for enter in servers')
|
||||
|
||||
forms['ssh_key_priv'].label=I18n.lang('pastafari2', 'ssh_key_priv_file', 'Global private SSH')
|
||||
forms['ssh_key_pub'].label=I18n.lang('pastafari2', 'ssh_key_pub_file', 'Global public SSH')
|
||||
|
||||
forms['ssh_key_priv'].required=True
|
||||
forms['ssh_key_pub'].required=True
|
||||
|
||||
html_forms=show_form({}, forms, t, yes_error=False, pass_values=True, modelform_tpl='forms/modelform.phtml')
|
||||
"""
|
||||
|
||||
txt_error=''
|
||||
txt_generate_key='<p>You have created your ssh keys</p>'
|
||||
txt_generate_key_button='Regenerate SSH keys'
|
||||
regenerate=True
|
||||
|
||||
if not os.path.isdir(system_path):
|
||||
|
||||
try:
|
||||
Path(system_path).mkdir(mode=511)
|
||||
|
||||
except:
|
||||
|
||||
txt_error='<p><strong>You need create ssh directory for save ssh keys</strong></p>'
|
||||
|
||||
#Get ssh key
|
||||
|
||||
if not os.path.isfile(system_path+'id_rsa'):
|
||||
|
||||
txt_generate_key='<p>You need generate a global private ssh key, because doesn\'t exists</p>'
|
||||
txt_generate_key_button='Generate SSH keys'
|
||||
regenerate=False
|
||||
pass
|
||||
|
||||
return t.load_template('settings.phtml', title=I18n.lang('pastafari2', 'settings', 'Settings'), path_module='admin_app.pastafari2_settings', txt_error=txt_error, txt_generate_key=txt_generate_key, txt_generate_key_button=txt_generate_key_button, regenerate=regenerate)
|
||||
|
||||
@admin_app.route('/pastafari2/edit_global_ssh_keys/', methods=['POST'])
|
||||
def pastafari2_edit_global_ssh_keys():
|
||||
|
||||
form={}
|
||||
|
||||
error=0
|
||||
|
||||
if not os.path.isfile(system_path+'id_rsa'):
|
||||
|
||||
try:
|
||||
|
||||
key=paramiko.RSAKey.generate(2048)
|
||||
key.write_private_key_file(system_path+'id_rsa')
|
||||
|
||||
with open(system_path+'id_rsa.pub',"w") as pub_key:
|
||||
pub_key.write("%s %s" % (key.get_name(), key.get_base64()))
|
||||
|
||||
except:
|
||||
|
||||
error=1
|
||||
|
||||
"""
|
||||
if not 'ssh_key_priv_file' in request.files:
|
||||
error=1
|
||||
form['ssh_key_priv']='ssh private key file required'
|
||||
|
||||
if not 'ssh_key_pub_file' in request.files:
|
||||
error=1
|
||||
form['ssh_key_pub']='ssh public key file required'
|
||||
|
||||
if not error:
|
||||
ssh_key_priv=request.files['ssh_key_priv_file']
|
||||
ssh_key_pub=request.files['ssh_key_pub_file']
|
||||
|
||||
if ssh_key_priv.filename=='':
|
||||
error=1
|
||||
form['ssh_key_priv']='ssh private key file required'
|
||||
|
||||
if ssh_key_pub.filename=='':
|
||||
error=1
|
||||
form['ssh_key_pub']='ssh private key file required'
|
||||
|
||||
if not os.path.isdir(system_path):
|
||||
|
||||
try:
|
||||
Path(system_path).mkdir(mode=511)
|
||||
|
||||
except:
|
||||
|
||||
error=1
|
||||
form['ssh_key_priv']='You need create ssh directory for save ssh keys'
|
||||
|
||||
if not error:
|
||||
|
||||
#Load keys
|
||||
|
||||
#Check keys
|
||||
|
||||
|
||||
|
||||
pass
|
||||
"""
|
||||
|
||||
#return {'form': form, 'error': error}
|
||||
return {'error': error}
|
||||
|
||||
@admin_app.route('/pastafari2/add_server/')
|
||||
def pastafari2_add_server():
|
||||
|
||||
db=g.connection
|
||||
|
||||
group_form=SelectModelForm('group_id', '', ServerGroup(db), 'group', 'id', field_parent=None)
|
||||
|
||||
return t.load_template('add_server.phtml', title=I18n.lang('pastafari2', 'add_server', 'Add server'), path_module='admin_app.pastafari2_dashboard', group_form=group_form)
|
||||
|
||||
|
||||
@admin_app.route('/pastafari2/add_server_task/', methods=['POST'])
|
||||
def pastafari2_add_server_task():
|
||||
|
||||
db=g.connection
|
||||
|
||||
#task=Task(db)
|
||||
|
||||
#task.safe_query()
|
||||
|
||||
#logtask=LogTask(db)
|
||||
|
||||
#server=ServerTask(db)
|
||||
#(self, server, conn, remote_user='root', remote_password='', private_key='./ssh/id_rsa', password_key='', remote_path='leviathan', task_id=0, data={}):
|
||||
error_form={}
|
||||
|
||||
server_host=request.form.get('server_host', '')
|
||||
server_username=request.form.get('server_username', '')
|
||||
server_password=request.form.get('server_password', '')
|
||||
repeat_server_password=request.form.get('repeat_server_password', '')
|
||||
group_id=request.form.get('group_id', '')
|
||||
private_key='./ssh/id_rsa'
|
||||
public_key='./ssh/id_rsa.pub'
|
||||
remote_path='pastafari2'
|
||||
task_id=0
|
||||
ip=''
|
||||
error=0
|
||||
data={}
|
||||
ssh_user=config_task.remote_user
|
||||
|
||||
#make ping to server
|
||||
|
||||
if server_host=='':
|
||||
error=1
|
||||
error_form['#server_host_error']=I18n.lang('pastafari2', 'error_hostname', 'Error: you need enter a valid hostname')
|
||||
|
||||
txt_error=''
|
||||
|
||||
try:
|
||||
#print("IP address of %s: %s" %(remote_host, socket.gethostbyname(remote_host)))
|
||||
ip=socket.gethostbyname(server_host)
|
||||
pass
|
||||
except socket.error as err_msg:
|
||||
error=1
|
||||
error_form['#server_host_error']=I18n.lang('pastafari2', 'error_getting_ip_host', 'Error: '+err_msg)
|
||||
|
||||
if not error:
|
||||
|
||||
group_name=''
|
||||
|
||||
if group_id!='':
|
||||
server_group=ServerGroup(db)
|
||||
arr_group=server_group.set_conditions('WHERE id=%s', [group_id]).select_a_row_where()
|
||||
group_name=arr_group['group']
|
||||
|
||||
data={'ssh_user': ssh_user, 'pub_key': public_key, 'url_stats': config.domain_url+url_for('monit_app.monit_get_data', api_key=config.monit_api_key), 'hostname': server_host, 'ip': ip, 'group_id': group_id, 'group_name': group_name}
|
||||
|
||||
with SSHTask(server_host, db, remote_user=server_username, remote_password=server_password, private_key=private_key, remote_path=remote_path, task_id=task_id, data=data) as ssh_task:
|
||||
if not ssh_task.prepare_connection():
|
||||
error=1
|
||||
txt_error=I18n.lang('pastafari2', 'error_connection', 'Error: cannot connect to server')
|
||||
error_form['#server_host_error']=I18n.lang('pastafari2', 'error_connection', 'Error: cannot connect to server')
|
||||
else:
|
||||
# Prepare task for install monit
|
||||
pass
|
||||
|
||||
task=Task(db)
|
||||
|
||||
task_id=0
|
||||
|
||||
path_task='modules.pastafari2.tasks.system.task'
|
||||
|
||||
if not task.run_task(server_host, path_task, 'Add new server', 'add_new_server', 'Task for add a new server', user=server_username, password=server_password, where_sql_server='', url='', data=data, send_task=True):
|
||||
|
||||
error=1
|
||||
error_form['#server_host_error']=I18n.lang('pastafari2', 'error_exec_task', 'Error: cannot execute the task')
|
||||
|
||||
task_id=task.task_id
|
||||
|
||||
return {'error': error, 'txt_error': txt_error, 'error_form': error_form, 'task_id': task_id}
|
||||
|
||||
# Maybe translate to api
|
||||
|
||||
@admin_app.route('/pastafari2/progress/')
|
||||
def pastafari2_progress():
|
||||
|
||||
db=g.connection
|
||||
|
||||
task_id=request.args.get('task_id', '0')
|
||||
|
||||
position=request.args.get('position', '0')
|
||||
|
||||
task=Task(db)
|
||||
|
||||
arr_task=task.set_conditions('WHERE id=%s', [task_id]).select_a_row_where()
|
||||
|
||||
#print(arr_task)
|
||||
|
||||
return t.load_template('progress.phtml', title=I18n.lang('pastafari2', 'task_progress', 'Task progress'), path_module='admin_app.pastafari2_dashboard', name_task=arr_task['name_task'], description_task=arr_task['description_task'], position=position, task_id=task_id, server=arr_task['server'])
|
||||
|
||||
|
||||
|
||||
@admin_app.route('/pastafari2/getprogress/', methods=['POST'])
|
||||
def pastafari2_getprogress():
|
||||
|
||||
s=session
|
||||
|
||||
db=g.connection
|
||||
|
||||
if request.args.get('task_id', '0')=='0':
|
||||
|
||||
s['get_progress']=s.get('get_progress', 0)
|
||||
|
||||
try:
|
||||
|
||||
task_id=int(request.args.get('task_id', '0'))
|
||||
except:
|
||||
task_id=0
|
||||
|
||||
try:
|
||||
position=int(request.args.get('position', '0'))
|
||||
except:
|
||||
position=0
|
||||
|
||||
task=Task(db)
|
||||
logtask=LogTask(db)
|
||||
|
||||
arr_task=task.select_a_row(task_id)
|
||||
|
||||
arr_rows={'wait': 1}
|
||||
|
||||
if arr_task:
|
||||
|
||||
logtask.set_limit([position, 5])
|
||||
|
||||
logtask.set_order({'id': 0})
|
||||
|
||||
logtask.conditions=['WHERE task_id=%s', [task_id]]
|
||||
|
||||
server=request.args.get('server', '')
|
||||
|
||||
if server!='':
|
||||
logtask.conditions=['WHERE task_id=%s and logtask.server=%s', [task_id, server]]
|
||||
|
||||
logtask.yes_reset_conditions=False
|
||||
|
||||
c=0
|
||||
|
||||
arr_rows=[]
|
||||
|
||||
with logtask.select([], True) as cursor:
|
||||
for arr_row in cursor:
|
||||
arr_rows.append(arr_row)
|
||||
c+=1
|
||||
|
||||
if c==0:
|
||||
arr_rows=[]
|
||||
|
||||
c_error=logtask.set_conditions('WHERE task_id=%s and logtask.error=%s and logtask.status=%s', [task_id, 1, 1]).select_count()
|
||||
|
||||
if c_error==0:
|
||||
|
||||
arr_rows={'wait': 1}
|
||||
else:
|
||||
logtask.limit=''
|
||||
|
||||
with logtask.set_conditions('WHERE task_id=%s and logtask.error=%s and logtask.status=%s', [task_id, 1, 1]).select([], True) as cursor:
|
||||
for arr_row in cursor:
|
||||
arr_rows.append(arr_row)
|
||||
|
||||
else:
|
||||
|
||||
arr_rows=[{'task_id': task_id, 'progress': 100, 'message': 'Error: no exists task', 'error': 1, 'status': 1}]
|
||||
|
||||
db.close()
|
||||
|
||||
#header=response.headers
|
||||
|
||||
resp=make_response(json.dumps(arr_rows))
|
||||
|
||||
resp.headers['Content-Type']='application/json'
|
||||
|
||||
return resp
|
||||
|
||||
@admin_app.route('/pastafari2/get_servers/', methods=['POST'])
|
||||
def get_servers_task():
|
||||
|
||||
db=g.connection
|
||||
|
||||
group_sql=''
|
||||
|
||||
count_data=[]
|
||||
sql_data=[]
|
||||
|
||||
group_id=request.form.get('group_id', '')
|
||||
|
||||
group_sql_count=''
|
||||
group_sql=''
|
||||
|
||||
if group_id!='':
|
||||
group_sql_count=' WHERE `group_id`=%s'
|
||||
count_data=[group_id]
|
||||
sql_data=[group_id]
|
||||
group_sql=' WHERE `group_id`=%s'
|
||||
|
||||
|
||||
|
||||
fields=[[I18n.lang('pastafari2', 'hostname', 'Hostname'), True], ['IP', True], [I18n.lang('pastafari2', 'selected', 'Selected'), False], [I18n.lang('pastafari2', 'options', 'Options'), False]]
|
||||
arr_order_fields=['hostname', 'ip']
|
||||
|
||||
count_query=['select count(serverdbtask.id) as num_elements from serverdbtask'+group_sql_count, count_data]
|
||||
|
||||
# server.id as select_id,
|
||||
|
||||
# select hostname, ip, date, num_updates, id from serverofuser where user_id=%s;
|
||||
|
||||
str_query=['select serverdbtask.hostname, serverdbtask.ip, serverdbtask.id as select_id, serverdbtask.id from serverdbtask'+group_sql, sql_data]
|
||||
|
||||
ajax=AjaxList(db, fields, arr_order_fields, count_query, str_query)
|
||||
|
||||
#ajax.func_fields['id']=options_server
|
||||
#ajax.func_fields['ip']=options_ip
|
||||
ajax.func_fields['select_id']=options_selected
|
||||
ajax.func_fields['id']=options_options
|
||||
ajax.limit=0
|
||||
|
||||
#{'fields': [['Hostname', True], ['IP', True], ['Status', True], ['Options', False]], 'rows': [{'hostname': 'debian-pc.localdomain', 'ip': '<span id="ip_192.168.122.125">192.168.122.125</span>', 'date': '<img src="/mediafrom/pastafari2/images/status_green.png" />', 'id': '<a href="#">View stats</a>'}, {'hostname': 'DESKTOP-HLHPSSO', 'ip': '<span id="ip_192.168.122.81">192.168.122.81</span>', 'date': '<img src="/mediafrom/pastafari2/images/status_green.png" />', 'id': '<a href="#">View stats</a>'}], 'html_pages': ''}
|
||||
|
||||
return ajax.show()
|
||||
|
||||
"""
|
||||
def options_server(row_id, row):
|
||||
|
||||
#'<a href="{}">{}</a>'.format(url_for('.services', server_id=row_id), I18n.lang('monit', 'services', 'Services'))
|
||||
|
||||
arr_options=['<a href="{}">{}</a>'.format("", I18n.lang('pastafari2', 'edit', 'Edit'))]
|
||||
arr_options.append('<a href="{}">{}</a>'.format("", I18n.lang('pastafari2', 'make_task', 'Make task')))
|
||||
arr_options.append('<a href="{}">{}</a>'.format("", I18n.lang('pastafari2', 'delete', 'Delete')))
|
||||
"""
|
||||
|
||||
def options_selected(row_id, row):
|
||||
|
||||
return '<input type="checkbox" name="server_id_{}" class="server_id" value="{}"/>'.format(row_id, row_id)
|
||||
|
||||
def options_options(row_id, row):
|
||||
|
||||
arr_options=['<a href="{}">{}</a>'.format("", I18n.lang('pastafari2', 'edit', 'Edit'))]
|
||||
#arr_options.append('<a href="{}">{}</a>'.format("", I18n.lang('pastafari2', 'make_task', 'Make task')))
|
||||
arr_options.append('<a href="{}">{}</a>'.format("", I18n.lang('pastafari2', 'delete', 'Delete')))
|
||||
|
||||
return '<br />'.join(arr_options)
|
||||
|
||||
|
||||
@admin_app.route('/pastafari2/get_groups/', methods=['GET'])
|
||||
def get_groups_task():
|
||||
|
||||
db=g.connection
|
||||
|
||||
arr_groups=[]
|
||||
|
||||
with db.query('select * from servergroup', []) as cursor:
|
||||
for data in cursor:
|
||||
arr_groups.append(data)
|
||||
|
||||
return json.dumps(arr_groups)
|
||||
|
||||
|
||||
@admin_app.route('/pastafari2/update_task/', methods=['POST'])
|
||||
def pastafari2_update_task():
|
||||
|
||||
db=g.connection
|
||||
|
||||
ids=json.loads(request.form.get('ids', '[]'))
|
||||
arr_ids=[]
|
||||
|
||||
error=0
|
||||
txt_error=''
|
||||
error_form={}
|
||||
|
||||
#print(ids)
|
||||
for v in ids:
|
||||
arr_ids.append(str(int(v)))
|
||||
|
||||
where_sql='WHERE id IN ('+",".join(arr_ids)+') order by hostname ASC'
|
||||
|
||||
#print(where_sql)
|
||||
|
||||
task=Task(db)
|
||||
|
||||
task_id=0
|
||||
|
||||
path_task='modules.pastafari2.tasks.system.ping'
|
||||
|
||||
data={}
|
||||
|
||||
server_host=''
|
||||
|
||||
user=config_task.remote_user
|
||||
|
||||
ssh_key_priv='./ssh/id_rsa'
|
||||
|
||||
if not task.run_task(server_host, path_task, 'Update server', 'update_server', 'Task for update servers', user=user, password='', where_sql_server=where_sql, ssh_key_priv=ssh_key_priv, url='', data=data, send_task=True):
|
||||
|
||||
error=1
|
||||
error_form['#server_host_error']=I18n.lang('pastafari2', 'error_exec_task', 'Error: cannot execute the task')
|
||||
|
||||
task_id=task.task_id
|
||||
|
||||
return {'error': error, 'txt_error': txt_error, 'error_form': error_form, 'task_id': task_id}
|
||||
|
||||
return {}
|
||||
|
||||
@admin_app.route('/pastafari2/multiprogress/')
|
||||
def pastafari2_multiprogress():
|
||||
|
||||
db=g.connection
|
||||
|
||||
task_id=request.args.get('task_id', '')
|
||||
|
||||
task=Task(db)
|
||||
|
||||
arr_task=task.select_a_row(task_id)
|
||||
|
||||
num_servers=task.set_conditions('WHERE parent_id=%s', [task_id]).select_count()
|
||||
|
||||
if arr_task:
|
||||
|
||||
return t.load_template('multiprogress.phtml', title=I18n.lang('pastafari2', 'task_progress', 'Task progress'), path_module='admin_app.pastafari2_dashboard', name_task=arr_task['name_task'], description_task=arr_task['description_task'], task_id=task_id, server=arr_task['server'], num_servers=num_servers)
|
||||
|
||||
else:
|
||||
|
||||
return ""
|
||||
|
||||
@admin_app.route('/pastafari2/get_servers_task/')
|
||||
def pastafari2_get_servers_task():
|
||||
|
||||
db=g.connection
|
||||
|
||||
task_id=request.args.get('task_id', '')
|
||||
|
||||
task=Task(db)
|
||||
|
||||
arr_ids=task.set_conditions('WHERE parent_id=%s', [task_id]).select_to_array(['id', 'hostname', 'server'])
|
||||
|
||||
resp=make_response(json.dumps(arr_ids))
|
||||
|
||||
resp.headers['Content-Type']='application/json'
|
||||
|
||||
return resp
|
||||
|
||||
@admin_app.route('/pastafari2/get_multiprogress/')
|
||||
def pastafari2_get_multiprogress():
|
||||
|
||||
s=session
|
||||
|
||||
db=g.connection
|
||||
|
||||
ids=request.args.get('ids', '[]')
|
||||
|
||||
final_ids=[str(i) for i in json.loads(ids)]
|
||||
|
||||
final_str=",".join(['%s']*len(final_ids))
|
||||
|
||||
#print(final_str)
|
||||
#for i in final_ids:
|
||||
|
||||
|
||||
task=Task(db)
|
||||
|
||||
logtask=LogTask(db)
|
||||
|
||||
arr_log=logtask.set_limit([20]).set_conditions('WHERE task_id IN ({})'.format(final_str), final_ids).select_to_array([], True)
|
||||
|
||||
resp=make_response(json.dumps(arr_log))
|
||||
|
||||
resp.headers['Content-Type']='application/json'
|
||||
|
||||
return resp
|
||||
|
||||
43
admin/groups.py
Normal file
43
admin/groups.py
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
from settings import config
|
||||
from flask import g, url_for, request, session, make_response
|
||||
from paramecio2.libraries.generate_admin_class import GenerateAdminClass
|
||||
from paramecio2.libraries.i18n import I18n
|
||||
from paramecio2.modules.admin import admin_app, t as admin_t
|
||||
from paramecio2.libraries.db.coreforms import SelectForm
|
||||
from paramecio2.libraries.mtemplates import PTemplate, env_theme
|
||||
from paramecio2.libraries import datetime
|
||||
from paramecio2.libraries.urls import make_media_url
|
||||
from paramecio2.libraries.db.webmodel import WebModel
|
||||
from paramecio2.libraries.lists import AjaxList
|
||||
from paramecio2.libraries.db.extraforms.fileform import FileForm
|
||||
from paramecio2.libraries.formsutils import show_form
|
||||
from modules.pastafari2.libraries.task import Task as SSHTask
|
||||
from modules.pastafari2.libraries.configtask import config_task
|
||||
from modules.pastafari2.models.tasks import Task, LogTask
|
||||
from modules.pastafari2.models.pastafari2 import ServerGroup
|
||||
|
||||
@admin_app.route('/pastafari2/groups/', methods=['GET', 'POST'])
|
||||
def pastafari2_groups():
|
||||
|
||||
t=admin_t
|
||||
|
||||
db=g.connection
|
||||
|
||||
groups=ServerGroup(db)
|
||||
|
||||
url=url_for('admin_app.pastafari2_groups')
|
||||
|
||||
admin=GenerateAdminClass(groups, url, t)
|
||||
|
||||
admin.list.raw_query=False
|
||||
|
||||
form_admin=admin.show()
|
||||
|
||||
if type(form_admin).__name__=='str':
|
||||
|
||||
return t.load_template('content.phtml', title=I18n.lang('admin', 'groups_edit', 'Groups edit'), contents=form_admin, path_module='admin_app.pastafari2_groups')
|
||||
else:
|
||||
|
||||
return form_admin
|
||||
|
||||
return ""
|
||||
0
app.py
Normal file
0
app.py
Normal file
83
libraries/configtask.py
Normal file
83
libraries/configtask.py
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
import os
|
||||
|
||||
class ConfigTask:
|
||||
|
||||
def __init__(self):
|
||||
|
||||
#Local paths
|
||||
|
||||
# Scheme: code task: {description task, module task}
|
||||
|
||||
self.libraries={}
|
||||
|
||||
self.base_path=os.path.dirname(os.path.dirname(__file__))
|
||||
|
||||
self.tasks_path=['tasks', 'modules/pastafari2/tasks']
|
||||
|
||||
self.scripts_path=['scripts', 'modules/pastafari2/scripts']
|
||||
|
||||
self.logs_path='logs'
|
||||
|
||||
#Remote paths
|
||||
|
||||
self.remote_path='/home/spanel'
|
||||
|
||||
#Relative to remote_path
|
||||
|
||||
self.tmp_sftp_path='tmp'
|
||||
|
||||
self.remote_user='spanel'
|
||||
|
||||
self.remote_password=None
|
||||
|
||||
#Local home
|
||||
|
||||
self.home=''
|
||||
|
||||
#SSH configuration
|
||||
|
||||
self.user_key=''
|
||||
|
||||
self.public_key=''
|
||||
|
||||
self.private_key=''
|
||||
|
||||
self.password_key=None
|
||||
|
||||
self.port=22
|
||||
|
||||
self.deny_missing_host_key=True
|
||||
|
||||
#Internal tasks
|
||||
|
||||
self.num_of_forks=10
|
||||
|
||||
self.stop_if_error=False
|
||||
|
||||
self.num_errors=0
|
||||
|
||||
self.num_success=0
|
||||
|
||||
self.num_total=0
|
||||
|
||||
self.num_servers=0
|
||||
|
||||
self.file_resume=None
|
||||
|
||||
#Used if in next versions, pastafari try use others tasks servers.
|
||||
|
||||
self.server_task='http://127.0.0.1:1337'
|
||||
|
||||
self.url_host=''
|
||||
|
||||
self.url_monit=''
|
||||
|
||||
self.api_key=''
|
||||
|
||||
self.ssh_directory=os.path.expanduser('~')+'/.ssh'
|
||||
|
||||
# Class for global configuration
|
||||
|
||||
config_task=ConfigTask()
|
||||
630
libraries/task.py
Normal file
630
libraries/task.py
Normal file
|
|
@ -0,0 +1,630 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
import paramiko, json
|
||||
import os, sys,traceback
|
||||
from stat import S_ISDIR
|
||||
from modules.pastafari2.models import tasks
|
||||
#from modules.pastafari2.models.servers import ServerGroupTask
|
||||
from modules.pastafari2.libraries.configtask import config_task
|
||||
from paramecio2.libraries.i18n import I18n
|
||||
from paramecio2.libraries.db.webmodel import WebModel
|
||||
|
||||
class Task:
|
||||
|
||||
#($server='', $ssh_user='root', $ssh_key_priv='./ssh/id_rsa', $ssh_key_password='', $ssh_path='leviathan', $mysql_conn=false)
|
||||
|
||||
def __init__(self, server, conn, remote_user='root', remote_password='', private_key='./ssh/id_rsa', password_key='', remote_path='leviathan', task_id=0, data={}):
|
||||
|
||||
self.config=config_task
|
||||
|
||||
self.server=server
|
||||
|
||||
self.name_task=''
|
||||
|
||||
self.codename_task=''
|
||||
|
||||
self.description_task=''
|
||||
|
||||
self.txt_error=''
|
||||
|
||||
self.os_server=''
|
||||
|
||||
self.files=[]
|
||||
|
||||
# Format first array element is command with the interpreter, the task is agnostic, the files in os directory. The commands are setted with 750 permission.
|
||||
# First element is the file, next elements are the arguments
|
||||
|
||||
self.commands_to_execute=[];
|
||||
|
||||
#THe files to delete
|
||||
|
||||
self.delete_files=[];
|
||||
|
||||
self.delete_directories=[];
|
||||
|
||||
#The id of the task in db
|
||||
|
||||
self.id=task_id
|
||||
|
||||
self.user=''
|
||||
self.password=''
|
||||
|
||||
self.connection=conn
|
||||
|
||||
self.logtask=tasks.LogTask(self.connection)
|
||||
self.task=tasks.Task(self.connection)
|
||||
self.taskdone=tasks.TaskDone(self.connection)
|
||||
|
||||
self.ssh=paramiko.SSHClient()
|
||||
|
||||
self.logtask.reset_require()
|
||||
self.task.reset_require()
|
||||
|
||||
self.one_time=False
|
||||
|
||||
self.version='1.0'
|
||||
|
||||
self.simultaneous=False
|
||||
|
||||
self.error_post_task=''
|
||||
|
||||
self.data=data
|
||||
|
||||
self.remote_user=remote_user
|
||||
|
||||
self.remote_password=remote_password
|
||||
|
||||
self.private_key=private_key
|
||||
|
||||
self.password_key=password_key
|
||||
|
||||
self.remote_path=remote_path
|
||||
|
||||
"""
|
||||
self.pre_task=None
|
||||
|
||||
self.error_task=None
|
||||
|
||||
self.post_task=None
|
||||
"""
|
||||
|
||||
def prepare_connection(self):
|
||||
|
||||
#self.ssh.load_system_host_keys()
|
||||
|
||||
#Check if the unknown host keys are rejected or not
|
||||
|
||||
#if self.config.deny_missing_host_key == False:
|
||||
|
||||
#self.ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
|
||||
# Check if in known_hosts
|
||||
check_ssh_host= paramiko.hostkeys.HostKeys()
|
||||
|
||||
if not os.path.isfile(self.config.ssh_directory+'/known_hosts'):
|
||||
f=open(self.config.ssh_directory+'/known_hosts', 'w')
|
||||
f.write('')
|
||||
f.close()
|
||||
|
||||
self.ssh.load_system_host_keys(self.config.ssh_directory+'/known_hosts')
|
||||
|
||||
check_ssh_host.load(self.config.ssh_directory+'/known_hosts')
|
||||
|
||||
host_key=self.ssh.get_host_keys()
|
||||
|
||||
add_host=False
|
||||
|
||||
rsa=None
|
||||
if self.private_key!='':
|
||||
rsa=paramiko.RSAKey.from_private_key_file(self.private_key, self.password_key)
|
||||
|
||||
if check_ssh_host.lookup(self.server)==None:
|
||||
|
||||
# Be tolerant for the first connect with hostkey policy
|
||||
|
||||
self.ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
|
||||
|
||||
add_host=True
|
||||
|
||||
try:
|
||||
|
||||
self.ssh.connect(self.server, port=self.config.port, username=self.remote_user, password=self.remote_password, pkey=rsa, key_filename=None, timeout=None, allow_agent=True, look_for_keys=True, compress=False, sock=None, gss_auth=False, gss_kex=False, gss_deleg_creds=True, gss_host=None, banner_timeout=None)
|
||||
|
||||
if add_host:
|
||||
host_key.save(self.config.ssh_directory+'/known_hosts')
|
||||
|
||||
except paramiko.SSHException as e:
|
||||
self.txt_error="Error: cannot connect to the server SSHException\n"+str(e)
|
||||
return False
|
||||
|
||||
except paramiko.AuthenticationException as e:
|
||||
self.txt_error="Error: cannot connect to the server AuthenticationException \n"+str(e)
|
||||
return False
|
||||
|
||||
except paramiko.BadHostKeyException as e:
|
||||
self.txt_error="Error: cannot connect to the server BadHostKeyException\n"+str(e)
|
||||
return False
|
||||
|
||||
except OSError as e:
|
||||
self.txt_error="Error: cannot connect to the server OsError \n"+str(e)
|
||||
return False
|
||||
|
||||
except:
|
||||
self.txt_error="Error: cannot connect to the server Generic\n"+traceback.format_exc()
|
||||
return False
|
||||
|
||||
#finally:
|
||||
# self.ssh.close()
|
||||
|
||||
return True
|
||||
|
||||
|
||||
def upload_files(self):
|
||||
|
||||
try:
|
||||
|
||||
sftp=self.ssh.open_sftp()
|
||||
|
||||
except:
|
||||
|
||||
self.txt_error='Sorry, error connecting to sftp: '+traceback.format_exc()
|
||||
return False
|
||||
|
||||
c=len(self.files)
|
||||
|
||||
if c>0:
|
||||
|
||||
percent=100/c
|
||||
|
||||
progress=0
|
||||
|
||||
for f in self.files:
|
||||
|
||||
source_file=f[0]
|
||||
|
||||
source_file=source_file.replace('${os_server}', self.os_server)
|
||||
|
||||
permissions=f[1]
|
||||
#dest_file=self.remote_path+'/'+source_file
|
||||
dest_file=source_file
|
||||
try:
|
||||
|
||||
if not os.path.isfile(source_file):
|
||||
self.txt_error="Sorry, you don't have source file to upload "+source_file
|
||||
return False
|
||||
|
||||
dir_file=os.path.dirname(dest_file)
|
||||
|
||||
parts_dir_file=dir_file.split('/')
|
||||
|
||||
# Create remote directory
|
||||
|
||||
try:
|
||||
|
||||
f_stat=sftp.stat(dir_file)
|
||||
|
||||
except IOError:
|
||||
|
||||
try:
|
||||
|
||||
final_path=''
|
||||
|
||||
for d in parts_dir_file:
|
||||
|
||||
final_path+=d+'/'
|
||||
|
||||
#print(self.remote_path+'/'+final_path)
|
||||
|
||||
try:
|
||||
|
||||
f_stat=sftp.stat(final_path)
|
||||
|
||||
except IOError:
|
||||
|
||||
sftp.mkdir(final_path)
|
||||
|
||||
except:
|
||||
|
||||
self.txt_error='Sorry, error creating the directories for the files: '+traceback.format_exc()
|
||||
return False
|
||||
|
||||
# Upload file
|
||||
|
||||
try:
|
||||
|
||||
sftp.put(source_file, dest_file, callback=None, confirm=True)
|
||||
|
||||
sftp.chmod(dest_file, permissions)
|
||||
|
||||
progress+=percent
|
||||
|
||||
self.logtask.insert({'task_id': self.id, 'progress': progress, 'message': I18n.lang('pastafari', 'uploading_files', 'Uploading file: ')+source_file, 'error': 0, 'server': self.server})
|
||||
|
||||
except:
|
||||
|
||||
self.txt_error='Sorry, cannot upload file '+source_file+': '+traceback.format_exc()
|
||||
return False
|
||||
|
||||
# Create directory recursively if not exists
|
||||
|
||||
except:
|
||||
self.txt_error='Error: '+traceback.format_exc()
|
||||
return False
|
||||
|
||||
self.logtask.insert({'task_id': self.id, 'progress': 100, 'message': I18n.lang('pastafari', 'upload_successful', 'Files uploaded successfully...'), 'error': 0, 'server': self.server})
|
||||
|
||||
return True
|
||||
|
||||
def delete_files_and_dirs(self):
|
||||
|
||||
sftp=self.ssh.open_sftp()
|
||||
|
||||
c=len(self.delete_files)
|
||||
|
||||
if c>0:
|
||||
|
||||
percent=100/c
|
||||
|
||||
progress=0
|
||||
|
||||
for filepath in self.delete_files:
|
||||
|
||||
filepath=filepath.replace('${os_server}', self.os_server)
|
||||
|
||||
try:
|
||||
|
||||
#print(self.remote_path+'/'+filepath)
|
||||
|
||||
sftp.remove(filepath)
|
||||
|
||||
progress+=percent
|
||||
|
||||
self.logtask.insert({'task_id': self.id, 'progress': progress, 'message': I18n.lang('pastafari', 'cleaning_files', 'Cleaning file: ')+filepath, 'error': 0, 'server': self.server})
|
||||
|
||||
except IOError:
|
||||
|
||||
self.txt_error="Sorry, cannot remove file "+filepath+" from server."
|
||||
|
||||
return False
|
||||
|
||||
|
||||
c=len(self.delete_directories)
|
||||
|
||||
if c>0:
|
||||
|
||||
percent=100/c
|
||||
|
||||
progress=0
|
||||
|
||||
for path in self.delete_directories:
|
||||
|
||||
try:
|
||||
|
||||
path=path.replace('${os_server}', self.os_server)
|
||||
|
||||
self.delete_dir(path, sftp)
|
||||
|
||||
progress+=percent
|
||||
|
||||
self.logtask.insert({'task_id': self.id, 'progress': progress, 'message': I18n.lang('pastafari', 'cleaning_directories', 'Cleaning directory: ')+path, 'error': 0, 'server': self.server})
|
||||
|
||||
|
||||
except IOError:
|
||||
|
||||
self.txt_error+="Sorry, cannot remove directory "+path+" from server."
|
||||
|
||||
return False
|
||||
|
||||
|
||||
return True
|
||||
|
||||
|
||||
def isdir(self, path, sftp):
|
||||
try:
|
||||
return S_ISDIR(sftp.stat(path).st_mode)
|
||||
except IOError:
|
||||
return False
|
||||
|
||||
def delete_dir(self, path, sftp):
|
||||
|
||||
#path=self.config.remote_path+'/'+path
|
||||
|
||||
if path != "/":
|
||||
|
||||
files = sftp.listdir(path)
|
||||
|
||||
for f in files:
|
||||
filepath = os.path.join(path, f)
|
||||
try:
|
||||
if self.isdir(filepath, sftp):
|
||||
self.delete_dir(filepath, sftp)
|
||||
else:
|
||||
sftp.remove(filepath)
|
||||
except IOError:
|
||||
self.txt_error="Sorry, cannot remove "+filepath+" from server."
|
||||
return False
|
||||
|
||||
sftp.rmdir(path)
|
||||
|
||||
return True
|
||||
|
||||
def exec(self):
|
||||
|
||||
# Get task
|
||||
|
||||
#self.id=task_id
|
||||
|
||||
self.task.reset_require()
|
||||
|
||||
self.task.valid_fields=['name_task', 'description_task', 'error', 'status', 'server']
|
||||
|
||||
self.logtask.valid_fields=self.logtask.fields.keys()
|
||||
|
||||
if self.id==0:
|
||||
|
||||
# Insert the task
|
||||
|
||||
self.task.reset_require()
|
||||
|
||||
self.task.insert({'name_task': self.name_task, 'description_task': self.description_task, 'server': self.server})
|
||||
|
||||
self.id=self.task.insert_id()
|
||||
|
||||
if not self.prepare_connection():
|
||||
#self.task.conditions=['WHERE id=%s', [self.id]]
|
||||
#self.task.update({'error': 1, 'status': 1})
|
||||
|
||||
self.logtask.insert({'task_id': self.id, 'progress': 100, 'message': self.txt_error, 'error': 1, 'status': 1, 'server': self.server})
|
||||
|
||||
self.make_error_task()
|
||||
|
||||
return False
|
||||
|
||||
# Pre task
|
||||
|
||||
if hasattr(self, 'pre_task'):
|
||||
self.logtask.insert({'task_id': self.id, 'progress': 0, 'message': I18n.lang('pastafari', 'pre_tasks', 'Begin pre tasks execution...'), 'error': 0, 'status': 0, 'server': self.server})
|
||||
|
||||
if self.pre_task():
|
||||
self.logtask.insert({'task_id': self.id, 'progress': 100, 'message': I18n.lang('pastafari', 'pre_tasks_executed', 'Pre tasks executed successfully...'), 'error': 0, 'status': 0, 'server': self.server})
|
||||
else:
|
||||
#self.logtask.set_conditions('where id=%s', [last_log_id])
|
||||
|
||||
self.logtask.insert({'progress': 100, 'error': 1, 'message': "Error executing pre task "+self.txt_error, 'status': 1, 'server': self.server, 'task_id': self.id})
|
||||
|
||||
self.make_error_task()
|
||||
|
||||
return False
|
||||
|
||||
#Check if script was executed
|
||||
|
||||
if self.codename_task!='':
|
||||
|
||||
if self.one_time==True:
|
||||
|
||||
with self.ssh.open_sftp() as sftp:
|
||||
|
||||
try:
|
||||
|
||||
with sftp.file(self.remote_path+'/tasks/'+self.codename_task) as f:
|
||||
version=f.read()
|
||||
version=version.decode('utf-8').strip()
|
||||
|
||||
if version==self.version:
|
||||
#self.task.conditions=['WHERE id=%s', [self.id]]
|
||||
#self.task.update({'error': 0, 'status': 1})
|
||||
|
||||
self.logtask.insert({'task_id': self.id, 'progress': 100, 'message': 'This script was executed correctly in this server', 'error': 0, 'status': 1, 'server': self.server})
|
||||
|
||||
return True
|
||||
|
||||
except IOError:
|
||||
# It was not executed
|
||||
pass
|
||||
|
||||
if not self.upload_files():
|
||||
#self.task.conditions=['WHERE id=%s', [self.id]]
|
||||
#self.task.update({'error': 1, 'status': 1})
|
||||
|
||||
self.logtask.insert({'task_id': self.id, 'progress': 100, 'message': self.txt_error, 'error': 1, 'status': 1, 'server': self.server})
|
||||
|
||||
self.make_error_task()
|
||||
|
||||
return False
|
||||
|
||||
self.logtask.insert({'task_id': self.id, 'progress': 0, 'message': 'Executing commands...', 'error': 0, 'status': 0, 'server': self.server})
|
||||
|
||||
# Execute commands
|
||||
|
||||
json_code=[]
|
||||
|
||||
for c in self.commands_to_execute:
|
||||
|
||||
try:
|
||||
command=c[0]
|
||||
|
||||
command=command.replace('${os_server}', self.os_server)
|
||||
|
||||
arguments=c[1]
|
||||
|
||||
sudo_str=''
|
||||
|
||||
if len(c)==3:
|
||||
sudo_str='sudo '
|
||||
|
||||
#, get_pty=True
|
||||
stdin, stdout, stderr = self.ssh.exec_command(sudo_str+command+' '+arguments)
|
||||
|
||||
for line in stdout:
|
||||
|
||||
if line==None:
|
||||
|
||||
line="[]"
|
||||
|
||||
line=line.strip()
|
||||
|
||||
try:
|
||||
json_code=json.loads(line)
|
||||
|
||||
if not 'progress' in json_code or not 'message' in json_code or not 'error' in json_code:
|
||||
#self.task.conditions=['WHERE id=%s', [self.id]]
|
||||
#self.task.update({'error': 1, 'status': 1})
|
||||
|
||||
self.logtask.insert({'task_id': self.id, 'progress': 100, 'message': 'Malformed json code: '+str(line), 'error': 1, 'status': 1, 'server': self.server})
|
||||
self.make_error_task()
|
||||
return False
|
||||
|
||||
else:
|
||||
|
||||
json_code['task_id']=self.id
|
||||
|
||||
json_code['server']=self.server
|
||||
|
||||
self.logtask.insert(json_code)
|
||||
|
||||
if json_code['error']==1:
|
||||
self.make_error_task()
|
||||
return False
|
||||
|
||||
|
||||
|
||||
except:
|
||||
|
||||
#self.task.conditions=['WHERE id=%s', [self.id]]
|
||||
#self.task.update({'error': 0, 'status':0})
|
||||
|
||||
self.logtask.insert({'task_id': self.id, 'progress': 0, 'no_progress': 1, 'message': str(line), 'error': 0, 'status': 0, 'server': self.server})
|
||||
|
||||
#return False
|
||||
|
||||
last_log_id=self.logtask.insert_id()
|
||||
|
||||
if stdout.channel.recv_exit_status()>0:
|
||||
#line=stdout.readlines()
|
||||
#logging.warning(action.codename+" WARNING: "+line)
|
||||
final_text='Error executing the command: %s' % command
|
||||
|
||||
#self.task.conditions=['WHERE id=%s', [self.id]]
|
||||
#self.task.update({'error': 1, 'status': 1})
|
||||
|
||||
for line in stdout:
|
||||
final_text+=' '+line
|
||||
|
||||
for line in stderr:
|
||||
final_text+=' '+line
|
||||
|
||||
self.logtask.set_conditions('where id=%s', [last_log_id])
|
||||
|
||||
self.logtask.update({'progress': 100, 'error': 1, 'message': final_text, 'status': 1, 'server': self.server})
|
||||
self.make_error_task()
|
||||
return False
|
||||
|
||||
except:
|
||||
|
||||
#self.task.conditions=['WHERE id=%s', [self.id]]
|
||||
#self.task.update({'error': 1, 'status': 1})
|
||||
|
||||
self.logtask.insert({'task_id': self.id, 'progress': 100, 'message': traceback.format_exc(), 'error': 1, 'status': 1, 'server': self.server})
|
||||
self.make_error_task()
|
||||
return False
|
||||
|
||||
# Clean files
|
||||
|
||||
if not self.delete_files_and_dirs():
|
||||
|
||||
#self.task.conditions=['WHERE id=%s', [self.id]]
|
||||
#self.task.update({'error': 1, 'status': 1})
|
||||
|
||||
self.logtask.insert({'task_id': self.id, 'progress': 100, 'message': self.txt_error, 'error': 1, 'status': 1, 'server': self.server})
|
||||
self.make_error_task()
|
||||
return False
|
||||
|
||||
#Upload files
|
||||
|
||||
#self.ssh.close()
|
||||
|
||||
# FInish task
|
||||
|
||||
#Put this version how executed
|
||||
|
||||
if self.codename_task!='':
|
||||
|
||||
if self.one_time==True:
|
||||
|
||||
with self.ssh.open_sftp() as sftp:
|
||||
|
||||
try:
|
||||
path_check=self.remote_path+'/tasks/'
|
||||
|
||||
f_stat=sftp.stat(path_check)
|
||||
|
||||
except IOError:
|
||||
|
||||
sftp.mkdir(path_check)
|
||||
|
||||
with sftp.file(path_check+self.codename_task, 'w') as f:
|
||||
f.write(self.version)
|
||||
|
||||
if hasattr(self, 'post_task'):
|
||||
self.logtask.insert({'task_id': self.id, 'progress': 0, 'message': I18n.lang('pastafari', 'post_tasks', 'Post tasks executing...'), 'error': 0, 'status': 0, 'server': self.server})
|
||||
|
||||
if self.post_task():
|
||||
self.logtask.insert({'task_id': self.id, 'progress': 100, 'message': I18n.lang('pastafari', 'post_tasks_executed', 'Post tasks executed successfully...'), 'error': 0, 'status': 0, 'server': self.server})
|
||||
else:
|
||||
#self.logtask.set_conditions('where id=%s', [last_log_id])
|
||||
|
||||
#self.logtask.update({'progress': 100, 'error': 1, 'message': "Error executing post task", 'status': 1, 'server': self.server})
|
||||
|
||||
self.logtask.insert({'task_id': self.id, 'progress': 100, 'message': I18n.lang('pastafari', 'error_post_tasks_executed', 'Error executing post task -> '+self.error_post_task), 'error': 1, 'status': 1, 'server': self.server})
|
||||
self.make_error_task()
|
||||
return False
|
||||
|
||||
|
||||
if 'progress' in json_code:
|
||||
#if json_code['progress']!=100:
|
||||
self.logtask.insert({'task_id': self.id, 'progress': 100, 'message': I18n.lang('pastafari', 'finished_successfully', 'All tasks done successfully...'), 'error': 0, 'status': 1, 'server': self.server})
|
||||
else:
|
||||
self.logtask.insert({'task_id': self.id, 'progress': 100, 'message': I18n.lang('pastafari', 'finished_successfully', 'All tasks done successfully...'), 'error': 0, 'status': 1, 'server': self.server})
|
||||
|
||||
# Add
|
||||
self.taskdone.create_forms()
|
||||
|
||||
self.taskdone.insert({'name_task': self.codename_task, 'ip': self.server})
|
||||
|
||||
#self.task.conditions=['WHERE id=%s', [self.id]]
|
||||
#self.task.update({'error': 0, 'status': 1})
|
||||
|
||||
#connection.close()
|
||||
return True
|
||||
|
||||
def make_error_task(self):
|
||||
|
||||
if hasattr(self, 'error_task'):
|
||||
self.logtask.insert({'task_id': self.id, 'progress': 0, 'message': I18n.lang('pastafari', 'error_tasks', 'Error tasks executing...'), 'error': 0, 'status': 0, 'server': self.server})
|
||||
|
||||
if self.error_task():
|
||||
self.logtask.insert({'task_id': self.id, 'progress': 100, 'message': I18n.lang('pastafari', 'error_tasks_executed', 'Sorry, you have an error, please, review the log...'), 'error': 1, 'status': 1, 'server': self.server})
|
||||
else:
|
||||
self.logtask.insert({'task_id': self.id, 'progress': 100, 'message': I18n.lang('pastafari', 'error_tasks_executed', 'Error Post task cannot be executed...'), 'error': 1, 'status': 1, 'server': self.server})
|
||||
|
||||
return False
|
||||
|
||||
def __del__(self):
|
||||
|
||||
#self.connection.close()
|
||||
|
||||
if self.ssh!=None:
|
||||
self.ssh.close()
|
||||
|
||||
def __enter__(self):
|
||||
|
||||
return self
|
||||
|
||||
def __exit__(self, exc_type, exc_value, tb):
|
||||
|
||||
if exc_type is not None:
|
||||
traceback.print_exception(exc_type, exc_value, tb)
|
||||
|
||||
return True
|
||||
|
||||
|
||||
|
||||
7
media/css/jquery-ui.min.css
vendored
Normal file
7
media/css/jquery-ui.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
5
media/css/jquery-ui.theme.min.css
vendored
Normal file
5
media/css/jquery-ui.theme.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
6
media/js/jquery-ui.min.js
vendored
Normal file
6
media/js/jquery-ui.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
31
models/pastafari2.py
Normal file
31
models/pastafari2.py
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
from paramecio2.libraries.db.webmodel import WebModel
|
||||
from paramecio2.libraries.db import corefields
|
||||
from paramecio2.libraries.db.extrafields.dictfield import DictField
|
||||
from paramecio2.libraries.db.extrafields.datefield import DateField
|
||||
from paramecio2.libraries.db.extrafields.datetimefield import DateTimeField
|
||||
from paramecio2.libraries.db.extrafields.ipfield import IpField
|
||||
from paramecio2.libraries.db.extrafields.urlfield import UrlField
|
||||
from paramecio2.libraries.db.extrafields.urlfield import DomainField
|
||||
from paramecio2.libraries.db.extrafields.dictfield import DictField
|
||||
from paramecio2.libraries.db.extrafields.jsonfield import JsonValueField
|
||||
from paramecio2.libraries.db.extrafields.parentfield import ParentField
|
||||
from paramecio2.libraries.urls import make_media_url
|
||||
from paramecio2.libraries import datetime
|
||||
from paramecio2.modules.admin.models.admin import UserAdmin
|
||||
from modules.monit.models.monit import Server
|
||||
|
||||
class ServerGroup(WebModel):
|
||||
|
||||
def __init__(self, connection):
|
||||
|
||||
super().__init__(connection)
|
||||
self.register(corefields.CharField('group'), True)
|
||||
self.register(corefields.CharField('code_group'), True)
|
||||
|
||||
|
||||
class ServerDbTask(Server):
|
||||
|
||||
def __init__(self, connection=None):
|
||||
|
||||
super().__init__(connection)
|
||||
self.register(corefields.ForeignKeyField('group_id', ServerGroup(connection), 11, False, 'id', 'group', select_fields=[]))
|
||||
306
models/tasks.py
Normal file
306
models/tasks.py
Normal file
|
|
@ -0,0 +1,306 @@
|
|||
from paramecio2.libraries.db.webmodel import WebModel
|
||||
from paramecio2.libraries.db import corefields
|
||||
from paramecio2.libraries.db.extrafields.ipfield import IpField
|
||||
from paramecio2.libraries.db.extrafields.arrayfield import ArrayField
|
||||
from paramecio2.libraries.db.extrafields.parentfield import ParentField
|
||||
from paramecio2.libraries.db.extrafields.datefield import DateField
|
||||
from paramecio2.libraries.db.extrafields.dictfield import DictField
|
||||
from paramecio2.libraries.i18n import I18n
|
||||
import urllib3
|
||||
try:
|
||||
import ujson as json
|
||||
except:
|
||||
import json
|
||||
|
||||
from redis import Redis
|
||||
from rq import Queue
|
||||
import importlib
|
||||
import traceback
|
||||
from modules.monit.models.monit import LonelyIpField
|
||||
|
||||
class Task(WebModel):
|
||||
|
||||
def __init__(self, connection):
|
||||
|
||||
super().__init__(connection)
|
||||
|
||||
self.register(corefields.CharField('name_task'), True)
|
||||
self.register(corefields.CharField('description_task'), True)
|
||||
self.register(corefields.CharField('codename_task'), True)
|
||||
self.register(corefields.CharField('path'))
|
||||
self.register(IpField('server'))
|
||||
self.register(corefields.CharField('hostname'))
|
||||
self.register(corefields.CharField('where_sql_server'), 2000)
|
||||
self.register(corefields.CharField('user'))
|
||||
self.register(corefields.CharField('password'), 2000)
|
||||
self.register(corefields.CharField('user_path'))
|
||||
self.register(corefields.CharField('os_codename'))
|
||||
self.register(corefields.CharField('url_return'))
|
||||
self.register(corefields.CharField('ssh_user'))
|
||||
self.register(corefields.CharField('ssh_key_pub'))
|
||||
self.register(corefields.CharField('ssh_key_priv'))
|
||||
self.register(corefields.CharField('ssh_key_password'))
|
||||
self.register(DictField('data', corefields.CharField('')))
|
||||
self.register(corefields.IntegerField('num_servers'))
|
||||
self.register(corefields.BooleanField('is_parent'))
|
||||
self.register(ParentField('parent_id', size=11, required=False, field_name='name_task'))
|
||||
self.fields['where_sql_server'].escape=True
|
||||
|
||||
self.txt_error=''
|
||||
|
||||
def run_task(self, server, path, name_task, codename_task, description_task, data={}, user='', password='', where_sql_server='', url='', ssh_key_priv='', ssh_key_password='', send_task=True):
|
||||
|
||||
logtask=LogTask(self.connection)
|
||||
#servers=Server(self.connection)
|
||||
|
||||
self.safe_query()
|
||||
logtask.safe_query()
|
||||
|
||||
parent_id=None
|
||||
yes_parent=False
|
||||
"""
|
||||
if type(server).__name__=='list':
|
||||
server_list=server
|
||||
server=None
|
||||
yes_parent=True
|
||||
"""
|
||||
if self.insert({'name_task': name_task,'description_task': description_task, 'url_return': url, 'server': server, 'where_sql_server': where_sql_server, 'data': data , 'user': user, 'password': password, 'path': path, 'where_sql_server' : where_sql_server, 'ssh_key_priv': ssh_key_priv, 'ssh_key_password': ssh_key_password}):
|
||||
|
||||
task_id=self.insert_id()
|
||||
parent_id=task_id
|
||||
self.task_id=task_id
|
||||
arr_ids=[]
|
||||
|
||||
if where_sql_server!='':
|
||||
yes_parent=True
|
||||
|
||||
"""
|
||||
if yes_parent:
|
||||
for server in server_list:
|
||||
self.insert({'name_task': name_task,'description_task': description_task, 'url_return': url, 'server': server, 'where_sql_server': '', 'data': data , 'user': user, 'password': password, 'path': path, 'where_sql_server' : where_sql_server, 'ssh_key_priv': ssh_key_priv, 'ssh_key_password': ssh_key_password, 'parent_id': parent_id})
|
||||
arr_ids.append(self.insert_id())
|
||||
"""
|
||||
|
||||
if send_task:
|
||||
"""
|
||||
http = urllib3.PoolManager()
|
||||
|
||||
try:
|
||||
|
||||
r = http.request('GET', 'http://127.0.0.1:1337', fields={'task_id': task_id, 'api_key': api_key})
|
||||
|
||||
if r.status!=200:
|
||||
self.error=True
|
||||
self.txt_error="Cannot access to task server: Error "+str(r.status)
|
||||
return False
|
||||
|
||||
else:
|
||||
resp=json.loads(r.data.decode('utf-8'))
|
||||
|
||||
if resp['error']:
|
||||
self.error=True
|
||||
self.txt_error=resp['message']
|
||||
logtask.insert(resp)
|
||||
return False
|
||||
|
||||
except urllib3.exceptions.MaxRetryError:
|
||||
self.txt_error='Cannot connect to the task server, check if is up'
|
||||
return False
|
||||
"""
|
||||
|
||||
return self.send_task(task_id, yes_parent, where_sql_server)
|
||||
|
||||
"""
|
||||
q = Queue(connection=Redis(host=redis_host, port=redis_port, password=redis_password))
|
||||
|
||||
try:
|
||||
|
||||
if where_sql_server=='':
|
||||
result = q.enqueue('modules.pastafari.servers.server_rq.send_pastafari_task', task_id, server, job_timeout=rq_timeout)
|
||||
|
||||
else:
|
||||
|
||||
for arr_server in servers.set_conditions(where_sql_server, []).select_to_array(['ip']):
|
||||
result=q.enqueue('modules.pastafari.servers.server_rq.send_pastafari_task', task_id, arr_server['ip'], job_timeout=rq_timeout)
|
||||
except:
|
||||
|
||||
self.error=True
|
||||
self.txt_error=traceback.format_exc()
|
||||
return False
|
||||
"""
|
||||
|
||||
|
||||
|
||||
return True
|
||||
|
||||
else:
|
||||
|
||||
self.error=True
|
||||
self.txt_error="Cannot insert the task"
|
||||
return False
|
||||
|
||||
|
||||
def send_task(self, task_id, yes_parent=False, where_sql_server=''):
|
||||
|
||||
"""
|
||||
http = urllib3.PoolManager()
|
||||
|
||||
try:
|
||||
|
||||
r = http.request('GET', 'http://127.0.0.1:1337', fields={'task_id': task_id, 'api_key': api_key})
|
||||
|
||||
if r.status!=200:
|
||||
self.error=True
|
||||
self.txt_error="Cannot access to task server: Error "+str(r.status)
|
||||
return False
|
||||
|
||||
else:
|
||||
resp=json.loads(r.data.decode('utf-8'))
|
||||
|
||||
if resp['error']:
|
||||
self.error=True
|
||||
self.txt_error=resp['message']
|
||||
logtask.insert(resp)
|
||||
return False
|
||||
|
||||
except urllib3.exceptions.MaxRetryError:
|
||||
self.error=True
|
||||
self.txt_error='Cannot connect to the task server, check if is up'
|
||||
return False
|
||||
"""
|
||||
|
||||
q = Queue(connection=Redis())
|
||||
|
||||
if yes_parent:
|
||||
arr_task=self.select_a_row(task_id)
|
||||
#If where sql, send multiple tasks.
|
||||
sql_insert_values=[]
|
||||
sql_insert='insert into task (`name_task`, `description_task`, `url_return`, `server`, `hostname`, `data`, `user`, `password`, `path`, `ssh_key_priv`, `ssh_key_password`, `parent_id`) VALUES '
|
||||
|
||||
with self.query('select id, hostname from serverdbtask '+where_sql_server) as cursor:
|
||||
|
||||
for row in cursor:
|
||||
arr_task['server']=row['hostname']
|
||||
sql_insert_values.append("('"+arr_task['name_task']+"', '"+arr_task['description_task']+"', '"+arr_task['url_return']+"', '"+arr_task['server']+"', '"+arr_task['server']+"', '"+arr_task['data']+"', '"+arr_task['user']+"', '"+arr_task['password']+"', '"+arr_task['path']+"', '"+arr_task['ssh_key_priv']+"', '"+arr_task['ssh_key_password']+"', '"+str(task_id)+"')")
|
||||
|
||||
#self.insert({'name_task': name_task,'description_task': description_task, 'url_return': url, 'server': server, 'where_sql_server': where_sql_server, 'data': data , 'user': user, 'password': password, 'path': path, 'where_sql_server' : where_sql_server, 'ssh_key_priv': ssh_key_priv, 'ssh_key_password': ssh_key_password})
|
||||
pass
|
||||
|
||||
final_sql=sql_insert+", ".join(sql_insert_values)
|
||||
|
||||
self.query(final_sql)
|
||||
|
||||
with self.query('select id from task WHERE parent_id=%s', [task_id]) as cursor:
|
||||
|
||||
for row in cursor:
|
||||
#print(row)
|
||||
result = q.enqueue(task, row['id'], job_timeout=3600)
|
||||
|
||||
else:
|
||||
|
||||
#Enqueue task function.
|
||||
|
||||
result = q.enqueue(task, task_id, job_timeout=3600)
|
||||
|
||||
return True
|
||||
|
||||
# Function used in rq worker for exec the ssh task.
|
||||
|
||||
def task(task_id):
|
||||
|
||||
conn=WebModel.connection()
|
||||
|
||||
task=Task(conn)
|
||||
|
||||
logtask=LogTask(conn)
|
||||
logtask.safe_query()
|
||||
|
||||
arr_task=task.select_a_row(task_id)
|
||||
|
||||
if not arr_task:
|
||||
|
||||
self.logtask.insert({'task_id': task_id, 'progress': 100, 'message': I18n.lang('pastafari', 'error_task_not_exists', 'Error: task not exists'), 'status': 1, 'error': 1, 'server': ''})
|
||||
|
||||
conn.close()
|
||||
|
||||
return False
|
||||
|
||||
server=arr_task['server']
|
||||
|
||||
try:
|
||||
|
||||
ssh_task=importlib.import_module(arr_task['path'])
|
||||
|
||||
"""
|
||||
| name_task | varchar(255) | NO | | | |
|
||||
| description_task | varchar(255) | NO | | | |
|
||||
| codename_task | varchar(255) | NO | | | |
|
||||
| path | varchar(255) | NO | | | |
|
||||
| server | varchar(255) | NO | | | |
|
||||
| hostname | varchar(255) | NO | | | |
|
||||
| where_sql_server | varchar(255) | NO | | | |
|
||||
| user | varchar(255) | NO | | | |
|
||||
| password | varchar(255) | NO | | | |
|
||||
| user_path | varchar(255) | NO | | | |
|
||||
| os_codename | varchar(255) | NO | | | |
|
||||
| url_return | varchar(255) | NO | | | |
|
||||
| data | text | NO | | NULL | |
|
||||
| ssh_key_pub | varchar(255) | NO | | | |
|
||||
| ssh_key_priv | varchar(255) | NO | | | |
|
||||
| ssh_user | varchar(255) | NO | | | |
|
||||
| num_servers | int(11) | NO | | 0 | |
|
||||
+------------------+--------------+------+-----+---------+----------------+
|
||||
"""
|
||||
|
||||
remote_user=arr_task['user']
|
||||
remote_password=arr_task['password']
|
||||
private_key=arr_task['ssh_key_priv']
|
||||
password_key=arr_task.get('ssh_key_password', '')
|
||||
|
||||
final_task=ssh_task.ServerTask(server, conn, remote_user=remote_user, remote_password=remote_password, private_key=private_key, password_key=password_key, remote_path='pastafari2', task_id=task_id, data=json.loads(arr_task['data']))
|
||||
|
||||
final_task.exec()
|
||||
|
||||
except:
|
||||
|
||||
if conn==None:
|
||||
conn=WebModel.connection()
|
||||
logtask.sqlclass=conn
|
||||
|
||||
logtask.insert({'task_id': task_id, 'progress': 100, 'message': I18n.lang('pastafari', 'error_in_task', 'Error: error in task ')+traceback.format_exc(), 'error': 1, 'status': 1, 'server': server})
|
||||
|
||||
conn.close()
|
||||
|
||||
return False
|
||||
|
||||
conn.close()
|
||||
|
||||
return True
|
||||
|
||||
|
||||
class LogTask(WebModel):
|
||||
|
||||
def __init__(self, connection):
|
||||
|
||||
super().__init__(connection)
|
||||
|
||||
self.register(DateField('path'))
|
||||
self.register(corefields.ForeignKeyField('task_id', Task(connection), size=11, required=False, identifier_field='id', named_field="name_task"))
|
||||
self.register(IpField('server'))
|
||||
self.register(corefields.DoubleField('progress'))
|
||||
self.register(corefields.BooleanField('no_progress'))
|
||||
self.register(corefields.TextField('message'))
|
||||
self.register(corefields.BooleanField('error'))
|
||||
self.register(corefields.BooleanField('status'))
|
||||
self.register(ArrayField('data', corefields.CharField('data')))
|
||||
self.register(corefields.BooleanField('code_error'))
|
||||
|
||||
# For grouping
|
||||
|
||||
class TaskDone(WebModel):
|
||||
|
||||
def __init__(self, connection):
|
||||
|
||||
super().__init__(connection)
|
||||
self.register(corefields.CharField('name_task'), True)
|
||||
self.register(LonelyIpField('ip'), True)
|
||||
10
scripts/system/alive.sh
Normal file
10
scripts/system/alive.sh
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
#!/bin/bash
|
||||
|
||||
echo '{"progress": 0, "message": "This server is up!!!", "error":0, "code_error": 0, "sucks": 1}'
|
||||
|
||||
sleep 1
|
||||
|
||||
echo '{"progress": 100, "message": "Finishing scripts without errors", "error":0, "code_error": 0, "sucks": 1}'
|
||||
|
||||
exit 0
|
||||
|
||||
29
scripts/system/install_git.sh
Normal file
29
scripts/system/install_git.sh
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
#!/bin/sh
|
||||
|
||||
echo "Installing git"
|
||||
|
||||
echo '{"error": 0, "status": 0, "progress": 0, "no_progress":0, "message": "Installing git..."}'
|
||||
|
||||
sleep 1
|
||||
|
||||
sudo DEBIAN_FRONTEND="noninteractive" apt-get install -y git
|
||||
|
||||
if [ $? -eq 0 ]; then
|
||||
|
||||
sleep 1
|
||||
|
||||
#echo "Installed git sucessfully if not error..."
|
||||
echo '{"error": 0, "status": 0, "progress": 100, "no_progress":0, "message": "Installed git sucessfully..."}'
|
||||
|
||||
sleep 1
|
||||
|
||||
else
|
||||
|
||||
echo "Sorry, cannot update the server..."
|
||||
|
||||
exit;
|
||||
|
||||
fi
|
||||
|
||||
|
||||
|
||||
19
scripts/system/install_psutil.sh
Normal file
19
scripts/system/install_psutil.sh
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
#!/bin/sh
|
||||
|
||||
# Install pip
|
||||
|
||||
sleep 1
|
||||
|
||||
echo '{"error": 0, "status": 0, "progress": 100, "no_progress":0, "message": "Installing python3-psutil..."}'
|
||||
|
||||
sudo DEBIAN_FRONTEND="noninteractive" apt-get install -y python3-pip
|
||||
|
||||
#sudo pip3 install psutil
|
||||
sudo apt-get install -y python3-psutil
|
||||
|
||||
#echo "Installed python3-psutil sucessfully if not error..."
|
||||
|
||||
sleep 1
|
||||
|
||||
echo '{"error": 0, "status": 0, "progress": 100, "no_progress":0, "message": "Installed python3-psutil sucessfully..."}'
|
||||
|
||||
27
scripts/system/install_python.sh
Normal file
27
scripts/system/install_python.sh
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
#!/bin/sh
|
||||
|
||||
sleep 1
|
||||
|
||||
echo '{"error": 0, "status": 0, "progress": 0, "no_progress":0, "message": "Installing Python..."}'
|
||||
|
||||
sleep 1
|
||||
|
||||
sudo apt-get -y install python3 python3-pip
|
||||
|
||||
if [ $? -eq 0 ]; then
|
||||
|
||||
#echo "Installed python3 sucessfully if not error..."
|
||||
echo '{"error": 0, "status": 0, "progress": 100, "no_progress":0, "message": "Installed python sucessfully..."}'
|
||||
|
||||
sleep 1
|
||||
|
||||
else
|
||||
|
||||
echo "Sorry, cannot install python..."
|
||||
|
||||
exit 1;
|
||||
|
||||
fi
|
||||
|
||||
sleep 1
|
||||
|
||||
192
scripts/system/install_pzoo_stats.py
Normal file
192
scripts/system/install_pzoo_stats.py
Normal file
|
|
@ -0,0 +1,192 @@
|
|||
#!/usr/bin/python3 -u
|
||||
|
||||
# A script for install pzoo user
|
||||
|
||||
import subprocess
|
||||
import argparse
|
||||
import re
|
||||
import os
|
||||
import shutil
|
||||
import pwd
|
||||
from subprocess import call
|
||||
from pathlib import Path
|
||||
from time import sleep
|
||||
|
||||
parser = argparse.ArgumentParser(description='A script for install leviathan user')
|
||||
|
||||
#parser.add_argument('--url', help='The url where notify updates', required=True)
|
||||
parser.add_argument('--url_stats', help='The url where pastafaristats notify the stats', required=True)
|
||||
parser.add_argument('--user', help='The user for pastafari', required=True)
|
||||
parser.add_argument('--pub_key', help='The pub key used in pastafari user', required=True)
|
||||
parser.add_argument('--group', help='Server group', required=False)
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
#url=args.url
|
||||
|
||||
check_url = re.compile(
|
||||
r'^(?:http|ftp)s?://' # http:// or https://
|
||||
r'(?:(?:[A-Z0-9](?:[A-Z0-9-]{0,61}[A-Z0-9])?\.)+(?:[A-Z]{2,6}\.?|[A-Z0-9-]{2,}\.?)|' #domain...
|
||||
r'localhost|' #localhost...
|
||||
r'\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})' # ...or ip
|
||||
r'(?::\d+)?' # optional port
|
||||
r'(?:/?|[/?]\S+)$', re.IGNORECASE)
|
||||
|
||||
print('{"error": 0, "status": 0, "progress": 0, "no_progress":0, "message": "Installing tools for monitoring the server..."}')
|
||||
|
||||
#check_url.match(args.url) and
|
||||
|
||||
if check_url.match(args.url_stats):
|
||||
|
||||
try:
|
||||
u=pwd.getpwnam(args.user)
|
||||
|
||||
if call("sudo userdel -r %s" % args.user, shell=True) > 0:
|
||||
print('Error, user with same username exists and cannot delete of the server')
|
||||
exit(1)
|
||||
else:
|
||||
print('Cleaning user with the same name')
|
||||
|
||||
except:
|
||||
pass
|
||||
|
||||
# Create users
|
||||
|
||||
if call("sudo useradd -m -s /bin/bash %s" % args.user, shell=True) > 0:
|
||||
|
||||
# Delete user with this name, you should not install it in a old server.
|
||||
|
||||
if call("sudo userdel -r %s" % args.user, shell=True) > 0:
|
||||
print('Error, remove the old user')
|
||||
exit(1)
|
||||
else:
|
||||
|
||||
if call("sudo useradd -m -s /bin/sh %s" % args.user, shell=True) > 0:
|
||||
print('Error, cannot add a new user')
|
||||
exit(1)
|
||||
|
||||
else:
|
||||
print('Added user')
|
||||
|
||||
if call("sudo mkdir -p /home/"+args.user+"/.ssh && sudo chown "+args.user+":"+args.user+" /home/"+args.user+"/.ssh && sudo chmod 700 /home/"+args.user+"/.ssh", shell=True) > 0:
|
||||
print('Error, cannot add ssh directory')
|
||||
exit(1)
|
||||
else:
|
||||
print('Added ssh directory')
|
||||
|
||||
if call("sudo cp "+args.pub_key+" /home/"+args.user+"/.ssh/authorized_keys && sudo chown "+args.user+":"+args.user+" /home/"+args.user+"/.ssh/authorized_keys && sudo chmod 600 /home/"+args.user+"/.ssh/authorized_keys", shell=True) > 0:
|
||||
print('Error, cannot pub key to user')
|
||||
exit(1)
|
||||
else:
|
||||
print('Added pub key to user')
|
||||
|
||||
# Edit sudo file
|
||||
|
||||
with open('modules/pastafari2/scripts/system/sudoers.d/spanel') as f:
|
||||
sudoers=f.read()
|
||||
|
||||
with open('/etc/sudoers.d/spanel', 'w') as f:
|
||||
sudoers=sudoers.replace("spanel", args.user)
|
||||
f.write(sudoers)
|
||||
|
||||
# Installing composer things for php alerts...
|
||||
|
||||
|
||||
#mkdir $HOME/pzoo/scripts
|
||||
|
||||
#chown $USER:$USER $HOME/pzoo/scripts
|
||||
|
||||
#su - $USER -s /bin/bash -c "composer --working-dir=$HOME/scripts require guzzlehttp/guzzle:~6.0"
|
||||
|
||||
#pt=Path('/home/'+args.user+'/pzoo/tasks')
|
||||
|
||||
#pt.mkdir(mode=0o755, parents=True, exist_ok=True)
|
||||
|
||||
# Create scripts pzoo
|
||||
"""
|
||||
ps=Path('/home/'+args.user+'/pzoo/scripts')
|
||||
|
||||
ps.mkdir(mode=0o755, parents=True, exist_ok=True)
|
||||
|
||||
shutil.chown('/home/'+args.user+'/pzoo', args.user, args.user)
|
||||
|
||||
shutil.chown('/home/'+args.user+'/pzoo/scripts', args.user, args.user)
|
||||
|
||||
|
||||
if call("su - "+args.user+" -s /bin/bash -c \"composer --working-dir=/home/"+args.user+"/pzoo/scripts require guzzlehttp/guzzle:~6.0\"", shell=True)>0:
|
||||
print('Error, cannot install scripts for use in check scripts')
|
||||
exit(1)
|
||||
else:
|
||||
print('Composer dependencies for check scripts added successfully')
|
||||
|
||||
# Edit get_updates.py
|
||||
|
||||
with open('scripts/system/get_updates.py') as f:
|
||||
get_updates=f.read()
|
||||
|
||||
with open('/etc/cron.daily/get_updates.py', 'w') as f:
|
||||
url_updates=args.url.replace('/getinfo/', '/getupdates/')
|
||||
get_updates=get_updates.replace("http://url/to/server/token/ip", url_updates)
|
||||
f.write(get_updates)
|
||||
|
||||
os.chmod('/etc/cron.daily/get_updates.py', 0o700)
|
||||
"""
|
||||
if call("sudo pip3 install --upgrade git+https://bitbucket.org/paramecio/pastafaristats", shell=True)>0:
|
||||
print('Error, cannot install pastafari stats')
|
||||
exit(1)
|
||||
else:
|
||||
print('Added pastafari stats')
|
||||
|
||||
# Add configuration to pastafari stats
|
||||
|
||||
if not os.path.isdir('/etc/pastafari'):
|
||||
# Create pastafari dir
|
||||
p=Path('/etc/pastafari')
|
||||
p.mkdir(mode=0o755, parents=False, exist_ok=True)
|
||||
|
||||
with open('/etc/pastafari/stats.cfg', 'w') as f:
|
||||
|
||||
f.write("[DEFAULT]\n\nurl_server="+args.url_stats+"\ngroup="+args.group)
|
||||
|
||||
|
||||
with open('/etc/systemd/system/pastafaristats.service', 'w') as f:
|
||||
|
||||
systemd_unit="""
|
||||
# Save it in /etc/systemd/system/pastafaristats.service
|
||||
|
||||
[Unit]
|
||||
Description=Pastafari Stats
|
||||
After=syslog.target
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=pzoo
|
||||
Group=pzoo
|
||||
ExecStart=pastafaristats
|
||||
Restart=always
|
||||
Environment=PYTHONUNBUFFERED=1
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
"""
|
||||
|
||||
systemd_unit=systemd_unit.replace('pzoo', args.user)
|
||||
|
||||
f.write(systemd_unit)
|
||||
|
||||
if call("sudo systemctl enable pastafaristats.service && sudo systemctl start pastafaristats.service", shell=True)>0:
|
||||
print('Error, cannot start pastafari stats')
|
||||
exit(1)
|
||||
else:
|
||||
print('Pastafari stats ready')
|
||||
|
||||
print('{"error": 0, "status": 0, "progress": 100, "no_progress":0, "message": "Tools installed..."}')
|
||||
|
||||
sleep(1)
|
||||
|
||||
else:
|
||||
|
||||
print('Error installing the module, not valid url')
|
||||
|
||||
exit(1)
|
||||
1
scripts/system/sudoers.d/spanel
Normal file
1
scripts/system/sudoers.d/spanel
Normal file
|
|
@ -0,0 +1 @@
|
|||
spanel ALL=(ALL) NOPASSWD: ALL
|
||||
10
settings/config_admin.py
Normal file
10
settings/config_admin.py
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
from paramecio2.libraries.config_admin import config_admin
|
||||
from paramecio2.libraries.i18n import I18n
|
||||
|
||||
#modules_admin=[[I18n.lang('admin', 'users_admin', 'User\'s Admin'), 'paramecio.modules.admin.admin.ausers', 'ausers']]
|
||||
|
||||
config_admin.append([I18n.lang('pastafari2', 'pastafari_admin', 'Pastafari admin')])
|
||||
|
||||
config_admin.append([I18n.lang('pastafari2', 'settings', 'Settings'), 'modules.pastafari2.admin.dashboard', 'admin_app.pastafari2_settings', 'fa-code'])
|
||||
config_admin.append([I18n.lang('pastafari2', 'servers', 'Servers'), 'modules.pastafari2.admin.dashboard', 'admin_app.pastafari2_dashboard', 'fa-linux'])
|
||||
config_admin.append([I18n.lang('pastafari2', 'groups', 'Groups'), 'modules.pastafari2.admin.groups', 'admin_app.pastafari2_groups', 'fa-object-group'])
|
||||
14
tasks/system/ping.py
Normal file
14
tasks/system/ping.py
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
from modules.pastafari2.libraries.task import Task
|
||||
from modules.pastafari2.models.pastafari2 import ServerDbTask
|
||||
|
||||
class ServerTask(Task):
|
||||
|
||||
def __init__(self, server, conn, remote_user='root', remote_password='', private_key='./ssh/id_rsa', password_key='', remote_path='leviathan', task_id=0, data={}):
|
||||
|
||||
super().__init__(server, conn, remote_user, remote_password, private_key, password_key, remote_path, task_id, data)
|
||||
|
||||
self.files=[['modules/pastafari2/scripts/system/alive.sh', 0o755]]
|
||||
|
||||
self.commands_to_execute=[]
|
||||
|
||||
self.commands_to_execute.append(['modules/pastafari2/scripts/system/alive.sh', ''])
|
||||
38
tasks/system/task.py
Normal file
38
tasks/system/task.py
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
from modules.pastafari2.libraries.task import Task
|
||||
from modules.pastafari2.models.pastafari2 import ServerDbTask
|
||||
|
||||
class ServerTask(Task):
|
||||
|
||||
def __init__(self, server, conn, remote_user='root', remote_password='', private_key='./ssh/id_rsa', password_key='', remote_path='leviathan', task_id=0, data={}):
|
||||
|
||||
super().__init__(server, conn, remote_user, remote_password, private_key, password_key, remote_path, task_id, data)
|
||||
|
||||
#self.files=[['modules/pastafari2/scripts/system/alive.sh', 0o755]]
|
||||
|
||||
self.files=[['modules/pastafari2/scripts/system/install_pzoo_stats.py', 0o755]]
|
||||
self.files.append(['modules/pastafari2/scripts/system/install_python.sh', 0o755])
|
||||
self.files.append(['modules/pastafari2/scripts/system/install_psutil.sh', 0o755])
|
||||
self.files.append(['modules/pastafari2/scripts/system/install_git.sh', 0o755])
|
||||
self.files.append(['modules/pastafari2/scripts/system/sudoers.d/spanel', 0o640])
|
||||
|
||||
self.files.append([self.data['pub_key'], 0o600])
|
||||
|
||||
self.commands_to_execute=[]
|
||||
|
||||
#self.commands_to_execute.append(['modules/pastafari2/scripts/system/alive.sh', ''])
|
||||
self.commands_to_execute.append(['modules/pastafari2/scripts/system/install_git.sh', ''])
|
||||
self.commands_to_execute.append(['modules/pastafari2/scripts/system/install_python.sh', ''])
|
||||
self.commands_to_execute.append(['modules/pastafari2/scripts/system/install_psutil.sh', ''])
|
||||
self.commands_to_execute.append(['modules/pastafari2/scripts/system/install_pzoo_stats.py', '--user='+self.data['ssh_user']+' --pub_key='+self.data['pub_key']+' --url_stats='+self.data['url_stats']+' --group='+self.data['group_name']])
|
||||
|
||||
def post_task(self):
|
||||
|
||||
server=ServerDbTask(self.connection)
|
||||
|
||||
server.safe_query()
|
||||
|
||||
#'subdomain_id': self.data['subdomain_id']
|
||||
|
||||
server.insert({'hostname': self.data['hostname'], 'ip': self.data['ip'], 'group_id': self.data['group_id']})
|
||||
|
||||
return True
|
||||
42
templates/admin/add_server.phtml
Normal file
42
templates/admin/add_server.phtml
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
<%inherit file="dashboard.phtml"/>
|
||||
<%block name="content">
|
||||
<div id="principal_container">
|
||||
<p><a href="${url_for('.pastafari2_dashboard')}">Servers</a> >> ${lang('pastafari2', 'add_server', 'Add server')}</p>
|
||||
<h2>${lang('pastafari2', 'add_server', 'Add server')}</h2>
|
||||
<div class="form">
|
||||
<form method="post" name="add_server" id="add_server_form">
|
||||
<p>Please fill the form for add the new server to the system.</p>
|
||||
<p><label>${lang('pastafari2', 'server_host', 'Server host')}* <span class="pastafari2_error error" id="server_host_error"></span></label> <input type="text" name="server_host" value=""></p>
|
||||
<p><label>${lang('pastafari2', 'server_group', 'Server group')} <span class="pastafari2_error error" id="group_id_error"></span></label> ${group_form.form()|n}</p>
|
||||
<p><label>${lang('pastafari2', 'server_username', 'Server username')} <span class="pastafari2_error error" id="server_username_error"></span></label> <input type="text" name="server_username" value=""></p>
|
||||
<p><label>${lang('pastafari2', 'server_password', 'Server password.')} <span class="pastafari2_error error" id="server_password_error"></span></label> <input type="password" name="server_password" value=""></p>
|
||||
<p><label>${lang('pastafari2', 'repeat_server_password', 'Repeat server password')} <span class="pastafari2_error error" id="repeat_server_password_error"></span></label> <input type="password" name="repeat_server_password" value=""></p>
|
||||
<p><input type="submit" value="${lang('pastafari2', 'send', 'Send')}"/></p>
|
||||
</form>
|
||||
</div>
|
||||
<p><a href="${url_for('.pastafari2_dashboard')}">Servers</a> >> ${lang('pastafari2', 'add_server', 'Add server')}</p>
|
||||
<script type="text/javascript" src="${make_media_url('js/jsutils/posting2.js', 'monit')}"></script>
|
||||
<script>
|
||||
var options={url: "${url_for('.pastafari2_add_server_task')}", loading: '#layer_loading', success: function (data) {
|
||||
|
||||
task_id=data.task_id;
|
||||
|
||||
if(task_id>0) {
|
||||
|
||||
location.href="${url_for('.pastafari2_progress')}?task_id="+task_id;
|
||||
|
||||
}
|
||||
|
||||
|
||||
}, error_data: function (data) {
|
||||
|
||||
console.log(JSON.stringify(data));
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
jQuery('#add_server_form').sendPost(options);
|
||||
|
||||
</script>
|
||||
</div>
|
||||
</%block>
|
||||
135
templates/admin/dash_pastafari.phtml
Normal file
135
templates/admin/dash_pastafari.phtml
Normal file
|
|
@ -0,0 +1,135 @@
|
|||
<%inherit file="dashboard.phtml"/>
|
||||
<%block name="content">
|
||||
<div id="principal_container">
|
||||
<p><a href="${url_for('.pastafari2_add_server')}">${lang('pastafari2', 'add_server', 'Add server')}</a>
|
||||
<p>${lang('monit', 'choose_group', 'Choose group')}:
|
||||
<select name="group_id" id="group_id">
|
||||
|
||||
</select>
|
||||
</p>
|
||||
<input type="button" name="select_all" class="select_all" value="${lang('pastafari2', 'select_all_servers', 'Select all servers')}" />
|
||||
<input type="button" name="deselect_all" class="deselect_all" value="${lang('pastafari2', 'deselect_all_servers', 'Deselect all servers')}" />
|
||||
<input type="button" name="update_selected_servers" class="update_selected_servers button_blue" value="${lang('pastafari2', 'update_selected_servers', 'Update selected servers')}" />
|
||||
<div id="table_servers">
|
||||
</div>
|
||||
<input type="button" name="select_all" class="select_all" value="${lang('pastafari2', 'select_all_servers', 'Select all servers')}" />
|
||||
<input type="button" name="deselect_all" class="deselect_all" value="${lang('pastafari2', 'deselect_all_servers', 'Deselect all servers')}" />
|
||||
<input type="button" name="update_selected_servers" class="update_selected_servers button_blue" value="${lang('pastafari2', 'update_selected_servers', 'Update selected servers')}" />
|
||||
</div>
|
||||
</%block>
|
||||
<%block name="jscript_block">
|
||||
<script language="Javascript" src="${make_media_url('js/jsutils/posting2.js', 'monit')}"></script>
|
||||
<script language="Javascript" src="${make_media_url('js/jsutils/ajax_list.js', 'monit')}"></script>
|
||||
<script>
|
||||
$(document).ready(function () {
|
||||
|
||||
options={'url': "${url_for('.get_servers_task')}", extra_data: {'group_code': $('#group_servers').val()}};
|
||||
|
||||
alist=$('#table_servers').ajaxList('table_list', options);
|
||||
|
||||
function update_groups() {
|
||||
|
||||
$.ajax({
|
||||
url: "${url_for('.get_groups_task')}",
|
||||
data: {},
|
||||
success: function (data) {
|
||||
|
||||
$('#group_id').html('<option value="">All groups</option>');
|
||||
|
||||
for(i in data) {
|
||||
|
||||
$('#group_id').append('<option value="'+data[i]['id']+'">'+data[i]['group']+'</option>');
|
||||
|
||||
}
|
||||
|
||||
},
|
||||
dataType: 'json'
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
update_groups();
|
||||
|
||||
$('#group_id').click(function () {
|
||||
|
||||
options={'url': "${url_for('.get_servers_task')}", extra_data: {'group_id': $('#group_id').val()}};
|
||||
|
||||
alist.updateAjax('table_list', options, 0);
|
||||
|
||||
});
|
||||
|
||||
$('.select_all').click( function () {
|
||||
|
||||
|
||||
$('.server_id').prop('checked', true);
|
||||
|
||||
});
|
||||
|
||||
$('.deselect_all').click( function () {
|
||||
|
||||
|
||||
$('.server_id').prop('checked', false);
|
||||
|
||||
});
|
||||
|
||||
|
||||
$('.update_selected_servers').click( function () {
|
||||
|
||||
if($('.server_id:checked').length==0) {
|
||||
|
||||
alert("${lang('pastafari2', 'no_servers_selected', 'No servers selected')}");
|
||||
return false;
|
||||
|
||||
}
|
||||
else {
|
||||
|
||||
$('#layer_loading').show();
|
||||
|
||||
server_ids=[];
|
||||
|
||||
$('.server_id').each( function () {
|
||||
|
||||
server_ids.push($(this).val());
|
||||
|
||||
});
|
||||
|
||||
$.ajax({
|
||||
|
||||
url:"${url_for('.pastafari2_update_task')}",
|
||||
data: {'ids': JSON.stringify(server_ids)},
|
||||
success: function (data) {
|
||||
|
||||
if(!data.error) {
|
||||
|
||||
//Redirect to multiprogress
|
||||
location.href="${url_for('.pastafari2_multiprogress')}?task_id="+data.task_id;
|
||||
|
||||
}
|
||||
else {
|
||||
|
||||
alert(data.txt_error);
|
||||
|
||||
}
|
||||
|
||||
$('#layer_loading').hide();
|
||||
|
||||
},
|
||||
error: function (data) {
|
||||
|
||||
$('#layer_loading').hide();
|
||||
alert('Error: '+data.status+' '+data.statusText);
|
||||
|
||||
},
|
||||
type: 'POST',
|
||||
dataType: 'json',
|
||||
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
</script>
|
||||
</%block>
|
||||
104
templates/admin/multiprogress.phtml
Normal file
104
templates/admin/multiprogress.phtml
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
<%inherit file="dashboard.phtml"/>
|
||||
<%block name="content">
|
||||
<h2>${name_task}</h2>
|
||||
<p>${description_task}</p>
|
||||
<hr />
|
||||
<p>${lang('pastafari2', 'num_servers', 'Number of servers')}: <span id="num_servers">${num_servers}</span></p>
|
||||
<p>${lang('pastafari2', 'completed_tasks', 'Completed tasks')}: <span id="num_completed">0</span></p>
|
||||
<p id="detecting_servers" style="display:none;">${lang('pastafari2', 'loading_servers', 'Loading servers...')} <i class="fa fa-cog fa-spin fa-fw"></i></p>
|
||||
<table class="table_servers" style="width:100%;">
|
||||
<tr class="row_server" id="father_server" style="display:none;">
|
||||
<td class="hostname">Hostname</td>
|
||||
<td class="progress"><span class="progress_text">In progress</span> <i class="fa fa-cog fa-spin fa-fw"></i></td>
|
||||
<td><a href="#" class="server_log">${lang('pastafari2', 'server_log', 'Server log')}</a></td>
|
||||
</tr>
|
||||
</table>
|
||||
<div id="finished" style="display:none;">
|
||||
<p><strong>All tasks were finished.</strong></p>
|
||||
</div>
|
||||
</%block>
|
||||
<%block name="jscript_block">
|
||||
<script>
|
||||
|
||||
ids=[];
|
||||
|
||||
//Get all tasks, next process 50 next progress.
|
||||
$.ajax({
|
||||
url: "${url_for('.pastafari2_get_servers_task')}",
|
||||
data: {task_id: ${task_id}},
|
||||
success: function (data) {
|
||||
|
||||
for(i in data) {
|
||||
|
||||
//console.log(data[i]);
|
||||
new_row=$(father_server).clone().appendTo('.table_servers');
|
||||
new_row.prop('id', 'task_'+data[i].id);
|
||||
//console.log(data[i]);
|
||||
new_row.children('.hostname').html(data[i].hostname);
|
||||
|
||||
new_row.find('.server_log').attr('href', "${url_for('.pastafari2_progress')}?task_id="+data[i].id);
|
||||
|
||||
new_row.show();
|
||||
|
||||
ids.push(data[i].id);
|
||||
//console.log($('#father_server').attr('id'));
|
||||
|
||||
}
|
||||
|
||||
get_log();
|
||||
|
||||
setInterval(get_log, 1000);
|
||||
|
||||
},
|
||||
dataType: 'json'
|
||||
});
|
||||
|
||||
function get_log() {
|
||||
|
||||
$.ajax({
|
||||
url: "${url_for('.pastafari2_get_multiprogress')}",
|
||||
data: {ids: JSON.stringify(ids)},
|
||||
success: function (data) {
|
||||
|
||||
/*$('.row_server').each(function () {
|
||||
|
||||
console.log($(this).attr('id'));
|
||||
|
||||
});*/
|
||||
|
||||
for(i in data) {
|
||||
|
||||
//console.log(data[i]);
|
||||
|
||||
//If is no_progress then show message.
|
||||
|
||||
if(!data[i].no_progress) {
|
||||
//console.log('#server_'+data[i].server);
|
||||
$('#task_'+data[i].task_id).find('.progress_text').html(data[i].message);
|
||||
|
||||
if(data[i].status==1) {
|
||||
|
||||
if(data[i].error==0) {
|
||||
|
||||
$('#task_'+data[i].task_id).find('i').removeClass('fa-cog fa-spin fa-fw').addClass('fa-check');
|
||||
|
||||
}
|
||||
else {
|
||||
|
||||
$('#task_'+data[i].task_id).find('i').removeClass('fa-cog fa-spin fa-fw').addClass('fa-times');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
},
|
||||
dataType: 'json'
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
</script>
|
||||
</%block>
|
||||
224
templates/admin/progress.phtml
Normal file
224
templates/admin/progress.phtml
Normal file
|
|
@ -0,0 +1,224 @@
|
|||
<%inherit file="dashboard.phtml"/>
|
||||
<%block name="extra_css">
|
||||
<link href="${make_media_url('css/jquery-ui.min.css', 'pastafari2')}" rel="stylesheet">
|
||||
<link href="${make_media_url('css/jquery-ui-theme.min.css', 'pastafari2')}" rel="stylesheet">
|
||||
<style>
|
||||
.ui-progressbar {
|
||||
position: relative;
|
||||
}
|
||||
.progress-label {
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
top: 4px;
|
||||
font-weight: bold;
|
||||
color: #fff;
|
||||
text-shadow: 1px 1px 0 #000;
|
||||
}
|
||||
</style>
|
||||
</%block>
|
||||
<%block name="content">
|
||||
<h2>${lang('pastafari2', 'task progress', 'Task progress')} - ${name_task}</h2>
|
||||
<p>${description_task}</p>
|
||||
<hr />
|
||||
<i class="fa fa-cog fa-spin fa-5x fa-fw margin-bottom" id="gear"></i>
|
||||
<div id="progressbar"><div class="progress-label">${lang('pastafari2', 'processing_task', 'Processing task...')}</div></div>
|
||||
<div id="no_progress" style="border: solid #cbcbcb 1px;height:150px;overflow:scroll;padding:2px;"></div>
|
||||
</%block>
|
||||
<%block name="jscript_block">
|
||||
<script language="Javascript" src="${make_media_url('js/jquery-ui.min.js', 'pastafari2')}"></script>
|
||||
<script>
|
||||
|
||||
position=${position};
|
||||
yes_progress=1;
|
||||
yes_position=0;
|
||||
last_status=0;
|
||||
|
||||
text_complete="Complete!";
|
||||
|
||||
var progressbar = $( "#progressbar" ),
|
||||
progressLabel = $( ".progress-label" );
|
||||
|
||||
progressbar.progressbar({
|
||||
value: false,
|
||||
change: function() {
|
||||
|
||||
if(progressbar.progressbar( "value" )>0)
|
||||
{
|
||||
|
||||
progressLabel.text( progressbar.progressbar( "value" ) + "%" );
|
||||
console.log('Progress '+progressbar.progressbar( "value" ) + "%");
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
progressbar.progressbar( "value", false);
|
||||
progressLabel.text( "Processing task..." );
|
||||
console.log('Processing task...');
|
||||
|
||||
}
|
||||
},
|
||||
complete: function() {
|
||||
progressLabel.text( text_complete );
|
||||
}
|
||||
});
|
||||
|
||||
objDiv = document.getElementById("no_progress");
|
||||
|
||||
function update_messages_queue(message)
|
||||
{
|
||||
|
||||
//timeout=setTimeout(function () {
|
||||
|
||||
progressbar.progressbar( "value", false );
|
||||
|
||||
$('#no_progress').append(message);
|
||||
objDiv.scrollTop = objDiv.scrollHeight;
|
||||
|
||||
//}, 600);
|
||||
|
||||
//return timeout;
|
||||
|
||||
}
|
||||
|
||||
function update_progress_messages_queue(message, progress)
|
||||
{
|
||||
|
||||
console.log('Getting progress...');
|
||||
|
||||
//timeout=setTimeout(function () {
|
||||
|
||||
progress=parseInt(progress);
|
||||
|
||||
progressbar.progressbar( "value", progress );
|
||||
|
||||
$('#no_progress').append(message+'<br />');
|
||||
|
||||
objDiv.scrollTop = objDiv.scrollHeight;
|
||||
|
||||
//}, 600);
|
||||
|
||||
//return timeout;
|
||||
|
||||
}
|
||||
|
||||
function finish_progress_error(progress)
|
||||
{
|
||||
|
||||
progressbar.progressbar( "value", progress );
|
||||
progressLabel.text( "ERROR, please see the log" );
|
||||
|
||||
}
|
||||
|
||||
|
||||
function update_progress()
|
||||
{
|
||||
|
||||
//pastafari/showprogress/tasks
|
||||
|
||||
$.ajax({
|
||||
url: "${url_for('.pastafari2_getprogress')}?task_id=${task_id}&server=${server}&position="+position,
|
||||
method: "POST",
|
||||
dataType: "json",
|
||||
data: {}
|
||||
}).done(function(data) {
|
||||
|
||||
if(!data.hasOwnProperty("wait"))
|
||||
{
|
||||
|
||||
x=data.length;
|
||||
|
||||
for(k=0;k<x;k++)
|
||||
{
|
||||
|
||||
if(data[k].no_progress==1)
|
||||
{
|
||||
//yes_progress=0;
|
||||
//$('#no_progress').append(data[k].message+'<br />');
|
||||
update_messages_queue(data[k].message+'<br />');
|
||||
|
||||
//Scroll
|
||||
|
||||
}
|
||||
else
|
||||
if(data[k].no_progress==0)
|
||||
{
|
||||
|
||||
update_progress_messages_queue(data[k].message, data[k].progress);
|
||||
|
||||
}
|
||||
|
||||
if(data[k].status!=1)
|
||||
{
|
||||
position+=1;
|
||||
last_status=0;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
position+=1;
|
||||
last_status=1;
|
||||
|
||||
if(data[k].error==1)
|
||||
{
|
||||
text_complete='ERROR, please view the log';
|
||||
finish_progress_error(data[k].progress);
|
||||
console.log('ERROR, please view the log');
|
||||
console.log('Error, finishing progress...');
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
//progressLabel.text( "Complete!" );
|
||||
|
||||
}
|
||||
|
||||
//clearTimeout(update_interval);
|
||||
|
||||
$('#gear').removeClass('fa-spin');
|
||||
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
if(last_status==0)
|
||||
{
|
||||
|
||||
update_interval = setTimeout(update_progress, 1000);
|
||||
console.log('Updating progress...');
|
||||
|
||||
}
|
||||
else {
|
||||
|
||||
console.log('Finishing progress...');
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
console.log('Updating waiting progress...');
|
||||
update_interval = setTimeout(update_progress, 1000);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}).fail(function (data) {
|
||||
|
||||
alert('Error: '+data.status+' '+data.statusText);
|
||||
/*clearInterval(update_interval);*/
|
||||
text_complete='ERROR, please view the log';
|
||||
finish_progress_error(100);
|
||||
$('#gear').removeClass('fa-spin');
|
||||
});
|
||||
}
|
||||
|
||||
update_progress();
|
||||
|
||||
</script>
|
||||
</%block>
|
||||
49
templates/admin/settings.phtml
Normal file
49
templates/admin/settings.phtml
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
<%inherit file="dashboard.phtml"/>
|
||||
<%block name="content">
|
||||
<div id="principal_container">
|
||||
<form method="post" name="generate_key" id="generate_key">
|
||||
<h2>${lang('pastafari2', 'global_ssh_keys', 'Global ssh keys')}</h2>
|
||||
<div class="form">
|
||||
${txt_error|n}
|
||||
${txt_generate_key|n}
|
||||
</div>
|
||||
% if not regenerate:
|
||||
<p><input type="submit" value="${txt_generate_key_button}" /></p>
|
||||
|
||||
% endif
|
||||
</form>
|
||||
</div>
|
||||
</%block>
|
||||
<%block name="jscript_block">
|
||||
<script language="Javascript" src="${make_media_url('js/jsutils/ajax_list.js', 'monit')}"></script>
|
||||
<script language="Javascript" src="${make_media_url('js/jsutils/posting2.js', 'monit')}"></script>
|
||||
<script>
|
||||
|
||||
% if not regenerate:
|
||||
|
||||
var options={url: "${url_for('admin_app.pastafari2_edit_global_ssh_keys')}", loading: '#layer_loading', pre_callback: function (data) {
|
||||
|
||||
//alert('This action overwrite all ssh keys');
|
||||
|
||||
}, success: function (data) {
|
||||
|
||||
/*$('#added_alert_success').show();
|
||||
|
||||
|
||||
setTimeout(function () {
|
||||
|
||||
$('#added_alert_success').fadeOut();
|
||||
|
||||
}, 3000);*/
|
||||
|
||||
location.href="${url_for('admin_app.pastafari2_settings')}";
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
$('#generate_key').sendPost(options);
|
||||
|
||||
% endif
|
||||
|
||||
</script>
|
||||
</%block>
|
||||
Loading…
Add table
Add a link
Reference in a new issue