mirror of
https://github.com/MikroWizard/mikroman.git
synced 2025-06-21 12:28:59 +02:00
Fixed Firmware download from the Mikrotik website when there are multiple npk available Fixed Mikrowizard system permission error when it is set to None Fixed user device group permissions Some minor UI improvements Fix IP scan for one IP scan / Fix not scanning the last IP in the range Fix manual snippet execution not working when device groups are selected Some minor bug fixes and improvements New: Show background tasks and be able to stop them while running in the background (like an IP scanner) Add support for manual MikroWizard update dashboard/settings page update to version 1.0.5 Enhancement: Show permission error in some pages when the user doesn't have permission for that page/action show better charts/graphs in the dashboard and device interface details show more info on the dashboard about update and version information and license
190 lines
7.3 KiB
Python
190 lines
7.3 KiB
Python
#!/usr/bin/python
|
|
# -*- coding: utf-8 -*-
|
|
|
|
# api_snippet.py: API for code snippets
|
|
# MikroWizard.com , Mikrotik router management solution
|
|
# Author: sepehr.ha@gmail.com
|
|
|
|
from flask import request,session
|
|
|
|
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.db.db_groups import devs, get_devs_of_groups
|
|
from functools import reduce
|
|
import bgtasks
|
|
import operator
|
|
import logging
|
|
import json
|
|
import datetime
|
|
log = logging.getLogger("api.snippet")
|
|
|
|
@app.route('/api/snippet/list', methods = ['POST'])
|
|
@login_required(role='admin',perm={'snippet':'read'})
|
|
def user_snippet_list():
|
|
"""return snippets list """
|
|
input = request.json
|
|
name=input.get('name',False)
|
|
description=input.get('description',False)
|
|
content=input.get('content',False)
|
|
snips=db_user_tasks.Snippets
|
|
page=input.get('page',0)
|
|
size=input.get('size',10000)
|
|
# build where query
|
|
clauses = []
|
|
if name and name!="":
|
|
clauses.append(snips.name.contains(name))
|
|
if description and description!="":
|
|
clauses.append(snips.description.contains(description))
|
|
if content and content!="":
|
|
clauses.append(snips.content == content)
|
|
|
|
expr=""
|
|
logs = []
|
|
selector=[snips.id,snips.name,snips.description,snips.content,snips.created]
|
|
try:
|
|
if len(clauses):
|
|
expr = reduce(operator.and_, clauses)
|
|
query=snips.select(*selector).where(expr)
|
|
else:
|
|
query=snips.select(*selector)
|
|
query=query.order_by(snips.id.desc())
|
|
query=query.paginate(page,size)
|
|
logs=list(query.dicts())
|
|
except Exception as e:
|
|
return buildResponse({"status":"failed", "err":str(e)},400)
|
|
return buildResponse(logs,200)
|
|
|
|
@app.route('/api/snippet/save', methods = ['POST'])
|
|
@login_required(role='admin',perm={'snippet':'write'})
|
|
def user_snippet_save():
|
|
"""save or create snippets"""
|
|
|
|
input = request.json
|
|
id=input.get('id', 0)
|
|
name=input.get('name', False)
|
|
description=input.get('description', False)
|
|
content=input.get('content', False)
|
|
|
|
# if id is 0 then we are creating new snippet
|
|
# else edit the snippet with provided id
|
|
if id==0:
|
|
snippet=db_user_tasks.get_snippet_by_name(name)
|
|
if snippet:
|
|
return buildResponse({"result":"failed","err":"Snippet already exists"}, 200)
|
|
snippet=db_user_tasks.create_snippet(name,description,content)
|
|
if snippet:
|
|
db_syslog.add_syslog_event(get_myself(), "Snippet","Create", get_ip(),get_agent(),json.dumps(input))
|
|
return buildResponse({"result":"success"}, 200)
|
|
else:
|
|
return buildResponse({"result":"failed","err":"Snippet create failed"}, 200)
|
|
else:
|
|
snippet=db_user_tasks.get_snippet(id)
|
|
if snippet:
|
|
db_syslog.add_syslog_event(get_myself(), "Snippet","Update", get_ip(),get_agent(),json.dumps(input))
|
|
snippet=db_user_tasks.update_snippet(id, name, description, content)
|
|
return buildResponse({"result":"success"}, 200)
|
|
else:
|
|
return buildResponse({"result":"failed","err":"Snippet not found"}, 200)
|
|
|
|
@app.route('/api/snippet/delete', methods = ['POST'])
|
|
@login_required(role='admin',perm={'snippet':'full'})
|
|
def user_snippet_delete():
|
|
input = request.json
|
|
id=input.get('id', 0)
|
|
snippet=db_user_tasks.get_snippet(id)
|
|
if snippet:
|
|
db_syslog.add_syslog_event(get_myself(), "Snippet","Delete", get_ip(),get_agent(),json.dumps(input))
|
|
snippet=db_user_tasks.delete_snippet(id)
|
|
return buildResponse({"result":"success"}, 200)
|
|
else:
|
|
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={}
|
|
if selection_type=="devices":
|
|
taskdata['memebrs']=members
|
|
elif selection_type=="groups":
|
|
devs=get_devs_of_groups(members)
|
|
devids=[dev.id for dev in devs]
|
|
taskdata['memebrs']=devids
|
|
uid = session.get("userid") or False
|
|
if not uid:
|
|
return buildResponse({'result':'failed','err':"No User"}, 200)
|
|
taskdata['owner']=str(uid)
|
|
default_ip=db_sysconfig.get_sysconfig('default_ip')
|
|
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
|
|
if not status:
|
|
bgtasks.exec_snipet(task=task,default_ip=default_ip,devices=taskdata['memebrs'],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)
|