mirror of
https://github.com/MikroWizard/mikroman.git
synced 2025-07-02 01:54:32 +02:00
Add snippet Execute,Better Task Results , fix some bugs
This commit is contained in:
parent
733307de8d
commit
463161c291
7 changed files with 188 additions and 31 deletions
|
@ -1,12 +1,12 @@
|
||||||
# 027_permissions.py
|
# 017_permissions.py
|
||||||
|
|
||||||
def migrate(migrator, database, fake=False, **kwargs):
|
def migrate(migrator, database, fake=False, **kwargs):
|
||||||
|
|
||||||
|
|
||||||
migrator.sql("""CREATE TABLE task_results(
|
migrator.sql("""CREATE TABLE task_results(
|
||||||
id serial PRIMARY KEY NOT NULL,
|
id serial PRIMARY KEY NOT NULL,
|
||||||
task_type text,
|
task_type text,
|
||||||
result text,
|
result text,
|
||||||
|
info text,
|
||||||
|
external_id int,
|
||||||
created timestamp not null default CURRENT_TIMESTAMP
|
created timestamp not null default CURRENT_TIMESTAMP
|
||||||
)""")
|
)""")
|
||||||
|
|
||||||
|
|
|
@ -31,7 +31,7 @@ def scan_network():
|
||||||
if not status:
|
if not status:
|
||||||
if start and end and port:
|
if start and end and port:
|
||||||
db_syslog.add_syslog_event(get_myself(), "Scanner","start", get_ip(),get_agent(),json.dumps(input))
|
db_syslog.add_syslog_event(get_myself(), "Scanner","start", get_ip(),get_agent(),json.dumps(input))
|
||||||
bgtasks.scan_with_ip(start=start,end=end,port=port,password=password,username=username)
|
bgtasks.scan_with_ip(start=start,end=end,port=port,password=password,username=username,user=get_myself())
|
||||||
return buildResponse({'status': True},200)
|
return buildResponse({'status': True},200)
|
||||||
else:
|
else:
|
||||||
return buildResponse({'status': status},200)
|
return buildResponse({'status': status},200)
|
||||||
|
|
|
@ -5,15 +5,16 @@
|
||||||
# MikroWizard.com , Mikrotik router management solution
|
# MikroWizard.com , Mikrotik router management solution
|
||||||
# Author: sepehr.ha@gmail.com
|
# Author: sepehr.ha@gmail.com
|
||||||
|
|
||||||
from flask import request
|
from flask import request,session
|
||||||
|
|
||||||
from libs.db import db_user_tasks,db_syslog
|
from libs.db import db_user_tasks,db_syslog,db_tasks,db_sysconfig
|
||||||
from libs.webutil import app, login_required,buildResponse,get_myself,get_ip,get_agent
|
from libs.webutil import app, login_required,buildResponse,get_myself,get_ip,get_agent
|
||||||
from functools import reduce
|
from functools import reduce
|
||||||
|
import bgtasks
|
||||||
import operator
|
import operator
|
||||||
import logging
|
import logging
|
||||||
import json
|
import json
|
||||||
|
import datetime
|
||||||
log = logging.getLogger("api.snippet")
|
log = logging.getLogger("api.snippet")
|
||||||
|
|
||||||
@app.route('/api/snippet/list', methods = ['POST'])
|
@app.route('/api/snippet/list', methods = ['POST'])
|
||||||
|
@ -96,3 +97,89 @@ def user_snippet_delete():
|
||||||
return buildResponse({"result":"success"}, 200)
|
return buildResponse({"result":"success"}, 200)
|
||||||
else:
|
else:
|
||||||
return buildResponse({"result":"failed","err":"Failed to delete snippet"}, 200)
|
return buildResponse({"result":"failed","err":"Failed to delete snippet"}, 200)
|
||||||
|
|
||||||
|
@app.route('/api/snippet/exec', methods = ['POST'])
|
||||||
|
@login_required(role='admin',perm={'task':'write'})
|
||||||
|
def exec_snippet():
|
||||||
|
"""crate user task"""
|
||||||
|
input = request.json
|
||||||
|
description=input.get('description',None)
|
||||||
|
snippetid=input.get('id',False)
|
||||||
|
members=input.get('members', False)
|
||||||
|
task_type=input.get('task_type',"backup")
|
||||||
|
selection_type=input.get('selection_type',False)
|
||||||
|
# taskdata=input.get('data',False)
|
||||||
|
utasks=db_user_tasks.UserTasks
|
||||||
|
|
||||||
|
# todo
|
||||||
|
# add owner check devids and dev groups with owner
|
||||||
|
if not description:
|
||||||
|
return buildResponse({'status': 'failed'},200,error="Wrong name/desc")
|
||||||
|
#check if cron is valid and correct
|
||||||
|
taskdata={}
|
||||||
|
taskdata['memebrs']=members
|
||||||
|
taskdata['owner']=members
|
||||||
|
snipet=db_user_tasks.get_snippet(snippetid)
|
||||||
|
if snipet:
|
||||||
|
taskdata['snippet']={'id':snipet.id,'code':snipet.content,'description':snipet.description,'name':snipet.name}
|
||||||
|
else:
|
||||||
|
return buildResponse({'status': 'failed'}, 200, error="Wrong snippet")
|
||||||
|
|
||||||
|
if selection_type not in ["devices","groups"]:
|
||||||
|
return buildResponse({'status': 'failed'}, 200, error="Wrong member type")
|
||||||
|
if task_type != 'snipet_exec':
|
||||||
|
return buildResponse({'status': 'failed'}, 200, error="Wrong task type")
|
||||||
|
try:
|
||||||
|
data={
|
||||||
|
'name':snipet.name,
|
||||||
|
'description':description,
|
||||||
|
'snippetid':int(snippetid),
|
||||||
|
'cron':None,
|
||||||
|
'desc_cron': None,
|
||||||
|
'action': 'snipet_exec',
|
||||||
|
'task_type':'snipet_exec',
|
||||||
|
'selection_type':selection_type,
|
||||||
|
'data':json.dumps(taskdata),
|
||||||
|
'created': datetime.datetime.now()
|
||||||
|
}
|
||||||
|
task=utasks.create(**data)
|
||||||
|
status=db_tasks.exec_snipet_status().status
|
||||||
|
uid = session.get("userid") or False
|
||||||
|
default_ip=db_sysconfig.get_sysconfig('default_ip')
|
||||||
|
if not uid:
|
||||||
|
return buildResponse({'result':'failed','err':"No User"}, 200)
|
||||||
|
if not status:
|
||||||
|
bgtasks.exec_snipet(task=task,default_ip=default_ip,devices=members,uid=uid)
|
||||||
|
res={'status': True}
|
||||||
|
else:
|
||||||
|
res={'status': status}
|
||||||
|
#add members to task
|
||||||
|
db_syslog.add_syslog_event(get_myself(), "Snippet","execute", get_ip(),get_agent(),json.dumps(input))
|
||||||
|
return buildResponse([{'status': 'success'}],200)
|
||||||
|
except Exception as e:
|
||||||
|
log.error(e)
|
||||||
|
return buildResponse({'status': 'failed','massage':str(e)},200)
|
||||||
|
|
||||||
|
|
||||||
|
@app.route('/api/snippet/executed', methods = ['POST'])
|
||||||
|
@login_required(role='admin',perm={'task':'write'})
|
||||||
|
def get_executed_snippet():
|
||||||
|
"""crate user task"""
|
||||||
|
input = request.json
|
||||||
|
id=input.get('id', False)
|
||||||
|
snipet=db_user_tasks.get_snippet(id)
|
||||||
|
if not snipet:
|
||||||
|
return buildResponse({'status': 'failed'}, 200, error="Wrong snippet")
|
||||||
|
utasks=db_user_tasks.UserTasks
|
||||||
|
tasks=utasks.select().where(utasks.snippetid==id).where(utasks.task_type=='snipet_exec')
|
||||||
|
taks_ids=[task.id for task in tasks]
|
||||||
|
task_res=db_tasks.TaskResults
|
||||||
|
executed_tasks=task_res.select().where(task_res.external_id<<taks_ids).order_by(task_res.id.desc())
|
||||||
|
executed_tasks=list(executed_tasks.dicts())
|
||||||
|
for task in executed_tasks:
|
||||||
|
task['result']=json.loads(task['result'])
|
||||||
|
task['info']=json.loads(task['info'])
|
||||||
|
if executed_tasks:
|
||||||
|
return buildResponse(executed_tasks, 200)
|
||||||
|
else:
|
||||||
|
return buildResponse({'status': 'failed'}, 200)
|
||||||
|
|
|
@ -46,6 +46,7 @@ def user_tasks_list():
|
||||||
clauses.append(utaks.task_type == task_type)
|
clauses.append(utaks.task_type == task_type)
|
||||||
if not ISPRO:
|
if not ISPRO:
|
||||||
clauses.append(utaks.task_type != 'firmware')
|
clauses.append(utaks.task_type != 'firmware')
|
||||||
|
clauses.append(utaks.task_type != 'snipet_exec')
|
||||||
expr=""
|
expr=""
|
||||||
logs = []
|
logs = []
|
||||||
selector=[utaks.id,utaks.name,utaks.description,utaks.desc_cron,utaks.action,utaks.task_type,utaks.dev_ids,utaks.snippetid,utaks.data,utaks.cron,utaks.selection_type,utaks.created]
|
selector=[utaks.id,utaks.name,utaks.description,utaks.desc_cron,utaks.action,utaks.task_type,utaks.dev_ids,utaks.snippetid,utaks.data,utaks.cron,utaks.selection_type,utaks.created]
|
||||||
|
@ -108,7 +109,6 @@ def user_tasks_create():
|
||||||
if len(members):
|
if len(members):
|
||||||
db_user_tasks.add_member_to_task(task.id, members, selection_type)
|
db_user_tasks.add_member_to_task(task.id, members, selection_type)
|
||||||
taskid=task.id
|
taskid=task.id
|
||||||
if task_type=="backup":
|
|
||||||
crontab = CronTab(user=True)
|
crontab = CronTab(user=True)
|
||||||
directory=Path(app.root_path).parent.absolute()
|
directory=Path(app.root_path).parent.absolute()
|
||||||
command = "python3 {}/task_run.py {}".format(directory,taskid)
|
command = "python3 {}/task_run.py {}".format(directory,taskid)
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
# Author: sepehr.ha@gmail.com thanks to Tomi.Mickelsson@iki.fi
|
# Author: sepehr.ha@gmail.com thanks to Tomi.Mickelsson@iki.fi
|
||||||
|
|
||||||
from uwsgidecorators import spool
|
from uwsgidecorators import spool
|
||||||
|
from playhouse.shortcuts import model_to_dict
|
||||||
from libs import util
|
from libs import util
|
||||||
import time
|
import time
|
||||||
from libs.db import db_tasks,db_device,db_events,db_user_group_perm,db_device
|
from libs.db import db_tasks,db_device,db_events,db_user_group_perm,db_device
|
||||||
|
@ -20,6 +20,7 @@ import socket
|
||||||
from libs.check_routeros.routeros_check.resource import RouterOSCheckResource
|
from libs.check_routeros.routeros_check.resource import RouterOSCheckResource
|
||||||
from typing import Dict
|
from typing import Dict
|
||||||
import json
|
import json
|
||||||
|
import datetime
|
||||||
|
|
||||||
sensor_pile = queue.LifoQueue()
|
sensor_pile = queue.LifoQueue()
|
||||||
other_sensor_pile = queue.LifoQueue()
|
other_sensor_pile = queue.LifoQueue()
|
||||||
|
@ -27,7 +28,9 @@ other_sensor_pile = queue.LifoQueue()
|
||||||
import logging
|
import logging
|
||||||
log = logging.getLogger("bgtasks")
|
log = logging.getLogger("bgtasks")
|
||||||
|
|
||||||
|
def serialize_datetime(obj):
|
||||||
|
if isinstance(obj, datetime.datetime):
|
||||||
|
return obj.isoformat()
|
||||||
|
|
||||||
@spool(pass_arguments=True)
|
@spool(pass_arguments=True)
|
||||||
def check_devices_for_update(*args, **kwargs):
|
def check_devices_for_update(*args, **kwargs):
|
||||||
|
@ -267,6 +270,11 @@ def scan_with_ip(*args, **kwargs):
|
||||||
mikrotiks=[]
|
mikrotiks=[]
|
||||||
scan_results=[]
|
scan_results=[]
|
||||||
dev_number=0
|
dev_number=0
|
||||||
|
info={
|
||||||
|
'user':kwargs.get('user','Unknown'),
|
||||||
|
'start_ip':start_ip,
|
||||||
|
'end_ip':end_ip
|
||||||
|
}
|
||||||
for ip_int in range(int(start_ip), int(end_ip)):
|
for ip_int in range(int(start_ip), int(end_ip)):
|
||||||
ip=str(ipaddress.IPv4Address(ip_int))
|
ip=str(ipaddress.IPv4Address(ip_int))
|
||||||
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||||
|
@ -358,7 +366,7 @@ def scan_with_ip(*args, **kwargs):
|
||||||
continue
|
continue
|
||||||
sock.close()
|
sock.close()
|
||||||
try:
|
try:
|
||||||
db_tasks.add_task_result('ip-scan', json.dumps(scan_results))
|
db_tasks.add_task_result('ip-scan', json.dumps(scan_results),json.dumps(info))
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
#ugly hack to reset sequnce number if device id
|
#ugly hack to reset sequnce number if device id
|
||||||
|
@ -382,3 +390,62 @@ def scan_with_ip(*args, **kwargs):
|
||||||
task.status=0
|
task.status=0
|
||||||
task.save()
|
task.save()
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@spool(pass_arguments=True)
|
||||||
|
def exec_snipet(*args, **kwargs):
|
||||||
|
task=db_tasks.exec_snipet_status()
|
||||||
|
if not task.status:
|
||||||
|
task.status=1
|
||||||
|
task.save()
|
||||||
|
default_ip=kwargs.get('default_ip',False)
|
||||||
|
try:
|
||||||
|
if kwargs.get('devices',False) and kwargs.get('task',False):
|
||||||
|
devids=kwargs.get('devices',False)
|
||||||
|
devs=False
|
||||||
|
uid=kwargs.get('uid',False)
|
||||||
|
utask=kwargs.get('task',False)
|
||||||
|
taskdata=json.loads(utask.data)
|
||||||
|
if "0" == devids:
|
||||||
|
devs=list(db_user_group_perm.DevUserGroupPermRel.get_user_devices(uid))
|
||||||
|
else:
|
||||||
|
devids=devids
|
||||||
|
devs=list(db_user_group_perm.DevUserGroupPermRel.get_user_devices_by_ids(uid,devids))
|
||||||
|
num_threads = len(devs)
|
||||||
|
q = queue.Queue()
|
||||||
|
threads = []
|
||||||
|
log.error(devs)
|
||||||
|
for dev in devs:
|
||||||
|
peer_ip=dev.peer_ip if dev.peer_ip else default_ip
|
||||||
|
if not peer_ip and '[mikrowizard]' in taskdata['snippet']['code']:
|
||||||
|
log.error("no peer ip")
|
||||||
|
num_threads=num_threads-1
|
||||||
|
continue
|
||||||
|
snipet_code=taskdata['snippet']['code']
|
||||||
|
if '[mikrowizard]' in taskdata['snippet']['code']:
|
||||||
|
snipet_code=snipet_code.replace('[mikrowizard]', peer_ip)
|
||||||
|
t = Thread(target=util.run_snippets, args=(dev, snipet_code, q))
|
||||||
|
t.start()
|
||||||
|
threads.append(t)
|
||||||
|
for t in threads:
|
||||||
|
t.join()
|
||||||
|
res=[]
|
||||||
|
for _ in range(num_threads):
|
||||||
|
qres=q.get()
|
||||||
|
res.append(qres)
|
||||||
|
try:
|
||||||
|
db_tasks.add_task_result('snipet_exec', json.dumps(res),json.dumps(model_to_dict(utask),default=serialize_datetime),utask.id)
|
||||||
|
except Exception as e:
|
||||||
|
log.error(e)
|
||||||
|
pass
|
||||||
|
except Exception as e:
|
||||||
|
log.error(e)
|
||||||
|
task.status=0
|
||||||
|
task.save()
|
||||||
|
return False
|
||||||
|
task.status=0
|
||||||
|
task.save()
|
||||||
|
return False
|
||||||
|
|
|
@ -48,10 +48,15 @@ def downloader_job_status():
|
||||||
def firmware_service_status():
|
def firmware_service_status():
|
||||||
return (Tasks.select().where(Tasks.signal == 150).get())
|
return (Tasks.select().where(Tasks.signal == 150).get())
|
||||||
|
|
||||||
|
def exec_snipet_status():
|
||||||
|
return (Tasks.select().where(Tasks.signal == 160).get())
|
||||||
|
|
||||||
|
|
||||||
class TaskResults(BaseModel):
|
class TaskResults(BaseModel):
|
||||||
task_type = TextField()
|
task_type = TextField()
|
||||||
result = DateTimeField()
|
result = DateTimeField()
|
||||||
|
info = TextField()
|
||||||
|
external_id = IntegerField()
|
||||||
created = DateTimeField()
|
created = DateTimeField()
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
|
@ -60,8 +65,8 @@ class TaskResults(BaseModel):
|
||||||
# whether the index is unique or not.
|
# whether the index is unique or not.
|
||||||
db_table = 'task_results'
|
db_table = 'task_results'
|
||||||
|
|
||||||
def add_task_result(task_type,result):
|
def add_task_result(task_type,result,info=None,eid=None):
|
||||||
tr = TaskResults(task_type=task_type, result=result)
|
tr = TaskResults(task_type=task_type, result=result,info=info,external_id=eid)
|
||||||
tr.save()
|
tr.save()
|
||||||
|
|
||||||
# --------------------------------------------------------------------------
|
# --------------------------------------------------------------------------
|
||||||
|
|
|
@ -599,7 +599,7 @@ def check_update(options,router=False):
|
||||||
return False,False,False,False
|
return False,False,False,False
|
||||||
|
|
||||||
def log_alert(type,dev,massage):
|
def log_alert(type,dev,massage):
|
||||||
log.error("Alert: {} {}".format(type,massage))
|
log.error("Alert: {} {} Device: {} ".format(type,massage,dev.ip))
|
||||||
|
|
||||||
def backup_routers(dev,q):
|
def backup_routers(dev,q):
|
||||||
status=backup_router(dev)
|
status=backup_router(dev)
|
||||||
|
@ -607,7 +607,7 @@ def backup_routers(dev,q):
|
||||||
|
|
||||||
def run_snippets(dev, snippet,q):
|
def run_snippets(dev, snippet,q):
|
||||||
result=run_snippet(dev, snippet)
|
result=run_snippet(dev, snippet)
|
||||||
q.put({"id": dev.id, "result":result})
|
q.put({"devid": dev.id,"devip": dev.ip,"devname": dev.name, "status":True if result else False , "result":result if result else 'Exec Failed'})
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def run_snippet(dev, snippet):
|
def run_snippet(dev, snippet):
|
||||||
|
@ -638,7 +638,8 @@ def run_snippet(dev, snippet):
|
||||||
try:
|
try:
|
||||||
ssh=SSH_Helper(options)
|
ssh=SSH_Helper(options)
|
||||||
result=ssh.exec_command(snippet)
|
result=ssh.exec_command(snippet)
|
||||||
|
if not result:
|
||||||
|
result="executed successfully"
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
log.error(e)
|
log.error(e)
|
||||||
log_alert('ssh',dev,'During backup ssh error')
|
log_alert('ssh',dev,'During backup ssh error')
|
||||||
|
@ -895,9 +896,6 @@ def download_firmware_to_repository(version,q,arch="all",all_package=False):
|
||||||
log.error(links)
|
log.error(links)
|
||||||
firm=db_firmware.Firmware()
|
firm=db_firmware.Firmware()
|
||||||
for lnk in links:
|
for lnk in links:
|
||||||
log.error("oooooooooooooooooooooooooooooooooooooooooo")
|
|
||||||
log.error(lnk)
|
|
||||||
log.error("oooooooooooooooooooooooooooooooooooooooooo")
|
|
||||||
if all_package and arch+"-allpackage" == lnk:
|
if all_package and arch+"-allpackage" == lnk:
|
||||||
arch_togo=lnk
|
arch_togo=lnk
|
||||||
link=links[lnk]["link"]
|
link=links[lnk]["link"]
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue