MikroWizard Initial commit | MikroMan Welcome to the world :)
This commit is contained in:
commit
8c49b9a55d
96 changed files with 12274 additions and 0 deletions
438
py/api/api_account.py
Normal file
438
py/api/api_account.py
Normal file
|
|
@ -0,0 +1,438 @@
|
|||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# api_account.py: API For managing accounts and permissions
|
||||
# MikroWizard.com , Mikrotik router management solution
|
||||
# Author: sepehr.ha@gmail.com
|
||||
|
||||
from ctypes import util
|
||||
from flask import request, session, g, jsonify
|
||||
from libs.util import ISPRO
|
||||
from libs.db import db,db_permissions,db_user_group_perm,db_groups,db_sysconfig,db_syslog
|
||||
|
||||
import json
|
||||
from libs import webutil,account
|
||||
from libs.webutil import app, login_required, get_myself , buildResponse
|
||||
from libs.mschap3.mschap import nt_password_hash
|
||||
|
||||
import logging
|
||||
log = logging.getLogger("api")
|
||||
|
||||
@app.route('/api/login', methods = ['POST'])
|
||||
def login():
|
||||
"""Logs the user in with username+password.
|
||||
On success returns the user object,
|
||||
on error returns error."""
|
||||
|
||||
input = request.json or {}
|
||||
username = input.get('username')
|
||||
password = input.get('password')
|
||||
|
||||
if not username or not password:
|
||||
return webutil.warn_reply("Missing input")
|
||||
|
||||
u = db.get_user_by_username(username)
|
||||
if not u or not account.check_password(u.password, password):
|
||||
# error
|
||||
try:
|
||||
db_syslog.add_syslog_event(u.id, "User login","Failed login",webutil.get_ip(),webutil.get_agent(),json.dumps({"username":username}))
|
||||
except:
|
||||
pass
|
||||
return webutil.warn_reply("Invalid login credentials")
|
||||
else:
|
||||
# success
|
||||
account.build_session(u, is_permanent=input.get('remember', True))
|
||||
tz=db_sysconfig.get_sysconfig('timezone')
|
||||
# log.info("LOGIN OK agent={}".format(webutil.get_agent()))
|
||||
res={
|
||||
"username":u.username,
|
||||
"name":u.username,
|
||||
"partner_id":u.id,
|
||||
"uid":u.id,
|
||||
"first_name":u.first_name,
|
||||
"last_name":u.last_name,
|
||||
"role":u.role,
|
||||
"tags":u.tags,
|
||||
"tz":tz,
|
||||
"perms":json.loads(u.adminperms)
|
||||
}
|
||||
db_syslog.add_syslog_event(u.id, "User login","Successful login",webutil.get_ip(),webutil.get_agent(),json.dumps({"username":username}))
|
||||
return buildResponse(res, 200)
|
||||
|
||||
@app.route('/api/user/create', methods = ['POST'])
|
||||
@login_required(role='admin',perm={'users':'write'})
|
||||
def create_user():
|
||||
"""Create new user."""
|
||||
|
||||
input = request.json or {}
|
||||
username = input.get('username')
|
||||
passwd = input.get('password')
|
||||
email = input.get('email')
|
||||
fname = input.get('first_name')
|
||||
lname = input.get('last_name')
|
||||
role = input.get('role', 'user')
|
||||
company = input.get('company')
|
||||
adminperms = input.get('adminperms',[])
|
||||
userperms = input.get('userperms',[])
|
||||
|
||||
if not username or not passwd or not fname or not lname or not role:
|
||||
resp={"status":"failed","err":"invalid data"}
|
||||
return buildResponse(resp, 200)
|
||||
|
||||
u = db.get_user_by_username(username)
|
||||
if u:
|
||||
msg = "User Name already Taken: {}".format(username)
|
||||
resp={"status":"failed","err":msg}
|
||||
return buildResponse(resp, 200)
|
||||
|
||||
err = account.check_password_validity(passwd)
|
||||
if err:
|
||||
err = "Invalid password : {}".format(err)
|
||||
resp={"status":"failed","err":err}
|
||||
return buildResponse(resp, 200)
|
||||
newpass = account.hash_password(passwd)
|
||||
nthashhex=''.join(list("{:02x}".format(ord(c)) for c in nt_password_hash(passwd)))
|
||||
# create new user
|
||||
u = db.User()
|
||||
u.username = username
|
||||
u.company = company
|
||||
u.first_name = fname
|
||||
u.last_name = lname
|
||||
u.password = newpass
|
||||
u.email= email
|
||||
u.adminperms= json.dumps(adminperms)
|
||||
u.hash = nthashhex
|
||||
u.tags = []
|
||||
u.role = role # set default to what makes sense to your app
|
||||
u.save(force_insert=True)
|
||||
account.new_signup_steps(u)
|
||||
for perm in userperms:
|
||||
db_user_group_perm.DevUserGroupPermRel.create_user_group_perm(u.id, int(perm['group_id']), int(perm['perm_id']))
|
||||
db_syslog.add_syslog_event(webutil.get_myself(), "User Managment","Create", webutil.get_ip(),webutil.get_agent(),json.dumps(input))
|
||||
return buildResponse(u, 200)
|
||||
|
||||
@app.route('/api/user/delete' ,methods=['POST'])
|
||||
@login_required(role='admin', perm={'users':'full'})
|
||||
def user_delete():
|
||||
"""Deletes a user. Only for superusers"""
|
||||
input = request.json or {}
|
||||
uid = input.get('uid')
|
||||
try:
|
||||
u = db.get_user(uid)
|
||||
except:
|
||||
u=False
|
||||
|
||||
if not u:
|
||||
msg = "User not found: {}".format(uid)
|
||||
resp={"status":"failed","err":msg}
|
||||
return buildResponse(resp, 200)
|
||||
|
||||
u.delete_instance(recursive=True)
|
||||
db_syslog.add_syslog_event(webutil.get_myself(), "User Managment", "Delete", webutil.get_ip(), webutil.get_agent(), json.dumps(input))
|
||||
return buildResponse({}, 200)
|
||||
|
||||
@app.route('/api/user/change_password' ,methods=['POST'])
|
||||
@login_required
|
||||
def user_change_password():
|
||||
"""Changes user password."""
|
||||
input = request.json or {}
|
||||
uid = webutil.get_myself().id
|
||||
oldpass = input.get('oldpass')
|
||||
newpass = input.get('newpass')
|
||||
#check if oldpass is correct
|
||||
try:
|
||||
u = db.get_user(uid)
|
||||
except:
|
||||
u=False
|
||||
|
||||
if not u or not account.check_password(u.password, oldpass):
|
||||
msg = "Current password is incorrect"
|
||||
resp={"status":"failed","err":msg}
|
||||
return buildResponse(resp, 200)
|
||||
|
||||
err = account.check_password_validity(newpass)
|
||||
if not err:
|
||||
newpass = account.hash_password(newpass)
|
||||
nthashhex=''.join(list("{:02x}".format(ord(c)) for c in nt_password_hash(newpass)))
|
||||
else:
|
||||
err = "Invalid password : {}".format(err)
|
||||
resp={"status":"failed","err":err}
|
||||
return buildResponse(resp, 200)
|
||||
|
||||
u.password = newpass
|
||||
|
||||
u.hash = nthashhex
|
||||
u.save()
|
||||
db_syslog.add_syslog_event(webutil.get_myself(), "User Managment", "Change Password", webutil.get_ip(), webutil.get_agent(), json.dumps(input))
|
||||
resp={"status":"success"}
|
||||
return buildResponse(resp, 200)
|
||||
|
||||
|
||||
@app.route('/api/logout', methods = ['POST'])
|
||||
@login_required
|
||||
def logout():
|
||||
"""Logs out the user, clears the session."""
|
||||
db_syslog.add_syslog_event(webutil.get_myself(), "User Logout","User Logged out", webutil.get_ip(),webutil.get_agent(),json.dumps({'logout':True}))
|
||||
session.clear()
|
||||
return jsonify({}), 200
|
||||
|
||||
|
||||
@app.route('/api/me', methods=['GET', 'POST'])
|
||||
def me():
|
||||
"""Return info about me."""
|
||||
me = get_myself()
|
||||
if me:
|
||||
res={
|
||||
"username":me.username,
|
||||
"first_name":me.first_name,
|
||||
"last_name":me.last_name,
|
||||
"role":me.role,
|
||||
"tags":me.tags,
|
||||
"uid":me.id,
|
||||
"perms":json.loads(me.adminperms),
|
||||
"tz":db_sysconfig.get_sysconfig('timezone'),
|
||||
"ISPRO":ISPRO
|
||||
}
|
||||
reply = res
|
||||
else:
|
||||
reply = {"username":"public","first_name":"guest","last_name":"guest","role":"admin"}
|
||||
return buildResponse(reply, 200)
|
||||
|
||||
|
||||
@app.route('/api/user/edit', methods = ['POST'])
|
||||
@login_required(role='admin',perm={'users':'write'})
|
||||
def user_edit():
|
||||
"""Edit user info. Only for admins with write perm"""
|
||||
err=False
|
||||
input = request.json or {}
|
||||
uid = input.get('id')
|
||||
username = input.get('username')
|
||||
passwd = input.get('password')
|
||||
email = input.get('email')
|
||||
fname = input.get('first_name')
|
||||
lname = input.get('last_name')
|
||||
role = input.get('role', 'user')
|
||||
adminperms = input.get('adminperms',[])
|
||||
|
||||
if passwd:
|
||||
err = account.check_password_validity(passwd)
|
||||
if not err:
|
||||
newpass = account.hash_password(passwd)
|
||||
nthashhex=''.join(list("{:02x}".format(ord(c)) for c in nt_password_hash(passwd)))
|
||||
else:
|
||||
err = "Invalid password : {}".format(err)
|
||||
resp={"status":"failed","err":err}
|
||||
return buildResponse(resp, 200)
|
||||
|
||||
try:
|
||||
u = db.get_user(uid)
|
||||
except:
|
||||
u=False
|
||||
|
||||
if not u:
|
||||
msg = "User not found: {}".format(uid)
|
||||
resp={"status":"failed","err":msg}
|
||||
return buildResponse(resp, 200)
|
||||
ucheck = db.get_user_by_username(username)
|
||||
if ucheck and str(ucheck.id) != uid:
|
||||
msg = "User Name already Taken: {}".format(username)
|
||||
resp={"status":"failed","err":msg}
|
||||
return buildResponse(resp, 200)
|
||||
if username:
|
||||
u.username = username
|
||||
if fname:
|
||||
u.first_name = fname
|
||||
|
||||
if lname:
|
||||
u.last_name = lname
|
||||
|
||||
if role:
|
||||
u.role = role
|
||||
if adminperms and str(u.id) != "37cc36e0-afec-4545-9219-94655805868b":
|
||||
u.adminperms= json.dumps(adminperms)
|
||||
if email:
|
||||
u.email= email
|
||||
if passwd and passwd!="":
|
||||
u.password = newpass
|
||||
u.hash = nthashhex
|
||||
u.save()
|
||||
resp={"status":"success"}
|
||||
if err:
|
||||
resp={"status":"failed","err":err}
|
||||
db_syslog.add_syslog_event(webutil.get_myself(), "User Managment","Edit", webutil.get_ip(),webutil.get_agent(),json.dumps(input))
|
||||
return buildResponse(resp, 200)
|
||||
|
||||
|
||||
@app.route('/api/users/list' ,methods=['POST'])
|
||||
@login_required(role='admin',perm={'users':'read'})
|
||||
def users():
|
||||
"""Search list of users. """
|
||||
|
||||
input = request.args or {}
|
||||
page = input.get('page')
|
||||
size = input.get('size')
|
||||
search = input.get('search')
|
||||
|
||||
reply = list(db.query_users(page, size, search))
|
||||
return buildResponse(reply, 200)
|
||||
|
||||
@app.route('/api/perms/list' ,methods=['POST'])
|
||||
@login_required(role='admin',perm={'permissions':'read'})
|
||||
def perms():
|
||||
"""Search list of perms. """
|
||||
|
||||
input = request.args or {}
|
||||
page = input.get('page')
|
||||
size = input.get('size')
|
||||
search = input.get('search')
|
||||
|
||||
reply = db_permissions.query_perms(page, size, search).dicts()
|
||||
for rep in reply:
|
||||
rep["perms"]=json.loads(rep["perms"])
|
||||
return buildResponse(reply, 200)
|
||||
|
||||
@app.route('/api/perms/create' ,methods=['POST'])
|
||||
@login_required(role='admin',perm={'permissions':'write'})
|
||||
def perms_create():
|
||||
"""Create permission record"""
|
||||
|
||||
input = request.json or {}
|
||||
name = input.get('name')
|
||||
perms = input.get('perms')
|
||||
#check if we dont have permission with same name
|
||||
perm = db_permissions.get_perm_by_name(name)
|
||||
if perm or name.lower() in ['full','read','write']:
|
||||
return buildResponse({"status":"failed","err":"Permission with same name already exists"}, 200)
|
||||
for perm in perms:
|
||||
if perm not in ["api","ftp","password","read","romon","sniff","telnet","tikapp","winbox","dude",'rest-api',"local","policy","reboot","sensitive","ssh","test","web","write"]:
|
||||
return buildResponse({"status":"failed", "err":"Invalid permission"}, 200)
|
||||
perms=json.dumps(perms)
|
||||
db_permissions.create_perm(name, perms)
|
||||
|
||||
|
||||
# reply = db_permissions.query_perms(page, size, search)
|
||||
db_syslog.add_syslog_event(webutil.get_myself(), "Perms Managment","Create", webutil.get_ip(),webutil.get_agent(),json.dumps(input))
|
||||
return buildResponse({}, 200)
|
||||
|
||||
@app.route('/api/perms/edit' ,methods=['POST'])
|
||||
@login_required(role='admin',perm={'permissions':'write'})
|
||||
def perms_edit():
|
||||
"""Edit permission record"""
|
||||
|
||||
input = request.json or {}
|
||||
name = input.get('name')
|
||||
perms = input.get('perms')
|
||||
id = input.get('id')
|
||||
|
||||
#check if we dont have permission with same name
|
||||
perm = db_permissions.get_perm(id)
|
||||
if not perm:
|
||||
return buildResponse({"status":"failed", "err":"Permission not exists"}, 200)
|
||||
for per in perms:
|
||||
if per not in ["api","ftp","password","read","romon","sniff","telnet","tikapp","winbox","dude","rest-api","local","policy","reboot","sensitive","ssh","test","web","write"]:
|
||||
return buildResponse({"status":"failed", "err":"Invalid permission"}, 200)
|
||||
perms=json.dumps(perms)
|
||||
#we are not allowed to change default mikrotik groups name
|
||||
if name.lower() in ['full','read','write']:
|
||||
return buildResponse({"status":"failed", "err":"Invalid permission name"}, 200)
|
||||
if perm.name.lower() in ['full','read','write']:
|
||||
return buildResponse({"status":"failed", "err":"Invalid permission name"}, 200)
|
||||
perm.name=name
|
||||
perm.perms=perms
|
||||
perm.save()
|
||||
|
||||
# reply = db_permissions.query_perms(page, size, search)
|
||||
db_syslog.add_syslog_event(webutil.get_myself(), "Perms Managment","Edit", webutil.get_ip(),webutil.get_agent(),json.dumps(input))
|
||||
return buildResponse({'status':'success'}, 200)
|
||||
|
||||
|
||||
@app.route('/api/userperms/list' ,methods=['POST'])
|
||||
@login_required(role='admin',perm={'users':'read'})
|
||||
def userperms():
|
||||
"""Search list of userperms."""
|
||||
|
||||
input = request.json or {}
|
||||
uid = input.get('uid')
|
||||
|
||||
#check if user exist
|
||||
|
||||
user = db.get_user(uid)
|
||||
if not user:
|
||||
return buildResponse({"status":"failed", "err":"User not exists"}, 200)
|
||||
|
||||
res=[]
|
||||
reply = db_user_group_perm.DevUserGroupPermRel.get_user_group_perms(uid)
|
||||
for data in reply:
|
||||
res.append({"id":data.id,"user_id":data.user_id.id,"group_id":data.group_id.id,"group_name":data.group_id.name,"perm_id":data.perm_id.id,"perm_name":data.perm_id.name})
|
||||
return buildResponse(res, 200)
|
||||
|
||||
@app.route('/api/userperms/create' ,methods=['POST'])
|
||||
@login_required(role='admin',perm={'users':'write'})
|
||||
def userperms_create():
|
||||
"""Create user permission record"""
|
||||
|
||||
input = request.json or {}
|
||||
uid = input.get('uid')
|
||||
gid = input.get('gid')
|
||||
pid = input.get('pid')
|
||||
|
||||
#check if user exist
|
||||
user = db.get_user(uid)
|
||||
if not user:
|
||||
return buildResponse({"status":"failed", "err":"User not exists"}, 200)
|
||||
|
||||
#check if group exist
|
||||
group = db_groups.get_group(gid)
|
||||
if not group:
|
||||
return buildResponse({"status":"failed", "err":"Group not exists"}, 200)
|
||||
|
||||
#check if permission exist
|
||||
perm = db_permissions.get_perm(pid)
|
||||
if not perm:
|
||||
return buildResponse({"status":"failed", "err":"Permission not exists"}, 200)
|
||||
|
||||
db_user_group_perm.DevUserGroupPermRel.create_user_group_perm(uid, gid, pid)
|
||||
|
||||
# reply = db_permissions.query_perms(page, size, search)
|
||||
db_syslog.add_syslog_event(webutil.get_myself(), "UserPerms Managment","Create", webutil.get_ip(),webutil.get_agent(),json.dumps(input))
|
||||
return buildResponse({'status':'success'}, 200)
|
||||
|
||||
@app.route('/api/userperms/delete' ,methods=['POST'])
|
||||
@login_required(role='admin', perm={'users':'write'})
|
||||
def userperms_delete():
|
||||
"""Delete user permission record"""
|
||||
|
||||
input = request.json or {}
|
||||
id = input.get('id')
|
||||
|
||||
if(id == '1' or id == 1):
|
||||
return buildResponse({"status":"failed", "err":"Cannot delete admin permission"}, 200)
|
||||
#check if permission exist
|
||||
perm = db_user_group_perm.DevUserGroupPermRel.get_user_group_perm(id)
|
||||
if not perm:
|
||||
return buildResponse({"status":"failed", "err":"Permission not exists"}, 200)
|
||||
db_user_group_perm.DevUserGroupPermRel.delete_user_group_perm(id)
|
||||
db_syslog.add_syslog_event(webutil.get_myself(), "UserPerms Managment", "Delete", webutil.get_ip(), webutil.get_agent(), json.dumps(input))
|
||||
return buildResponse({'status':'success'}, 200)
|
||||
|
||||
|
||||
@app.route('/api/perms/delete' ,methods=['POST'])
|
||||
@login_required(role='admin', perm={'permissions':'full'})
|
||||
def perms_delete():
|
||||
"""Delete permission record"""
|
||||
|
||||
input = request.json or {}
|
||||
id = input.get('id')
|
||||
|
||||
#check if permission exist
|
||||
perm = db_permissions.get_perm(id)
|
||||
if perm.name in ['full','read','write']:
|
||||
return buildResponse({"status":"failed", "err":"Cannot delete default permission"}, 200)
|
||||
if not perm:
|
||||
return buildResponse({"status":"failed", "err":"Permission not exists"}, 200)
|
||||
res=db_permissions.delete_perm(id)
|
||||
if not res:
|
||||
return buildResponse({"status":"failed", "err":"Unable to Delete Permission"}, 200)
|
||||
# reply = db_permissions.query_perms(page, size, search)
|
||||
db_syslog.add_syslog_event(webutil.get_myself(), "Perms Managment","Delete", webutil.get_ip(),webutil.get_agent(),json.dumps(input))
|
||||
return buildResponse({'status':'success'}, 200)
|
||||
83
py/api/api_backups.py
Normal file
83
py/api/api_backups.py
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# api_bakcups.py: API for managing bakcups
|
||||
# MikroWizard.com , Mikrotik router management solution
|
||||
# Author: sepehr.ha@gmail.com
|
||||
|
||||
from flask import request, jsonify
|
||||
|
||||
from libs.db import db_tasks,db_backups,db_device,db_syslog
|
||||
from libs import util
|
||||
from libs.webutil import app, login_required,buildResponse,get_myself,get_ip,get_agent
|
||||
import bgtasks
|
||||
import logging
|
||||
import json
|
||||
|
||||
log = logging.getLogger("api.firmware")
|
||||
|
||||
@app.route('/api/backup/make', methods = ['POST'])
|
||||
@login_required(role='admin',perm={'backup':'write'})
|
||||
def backup_create():
|
||||
input = request.json
|
||||
devids=input.get('devids',False)
|
||||
status=db_tasks.backup_job_status().status
|
||||
if not status:
|
||||
db_syslog.add_syslog_event(get_myself(), "Backup Managment","Create", get_ip(),get_agent(),json.dumps(input))
|
||||
if devids=="0":
|
||||
all_devices=list(db_device.get_all_device())
|
||||
bgtasks.backup_devices(devices=all_devices)
|
||||
else:
|
||||
devices=db_device.get_devices_by_id(devids)
|
||||
bgtasks.backup_devices(devices=devices)
|
||||
return buildResponse([{'status': status}],200)
|
||||
else:
|
||||
return buildResponse([{'status': status}],200)
|
||||
|
||||
|
||||
@app.route('/api/backup/list', methods = ['POST'])
|
||||
@login_required(role='admin',perm={'backup':'read'})
|
||||
def backup_list():
|
||||
input = request.json
|
||||
page = input.get('page')
|
||||
devid = input.get('devid',False)
|
||||
size = input.get('size')
|
||||
search = input.get('search')
|
||||
backups = db_backups.query_backup_jobs(page, size, search,devid=devid)
|
||||
reply=[]
|
||||
for back in backups:
|
||||
data={}
|
||||
if back.devid:
|
||||
dev=back.devid
|
||||
data['id']=back.id
|
||||
data['filesize']=util.sizeof_fmt(back.filesize)
|
||||
data['created']=back.created
|
||||
data['devname']=dev.name
|
||||
data['devip']=dev.ip
|
||||
data['devmac']=dev.mac
|
||||
else:
|
||||
data['id']=back.id
|
||||
data['filesize']=util.sizeof_fmt(back.filesize)
|
||||
data['created']=back.created
|
||||
data['devname']='Deleted Device'
|
||||
data['devip']=''
|
||||
data['devmac']=''
|
||||
reply.append(data)
|
||||
return buildResponse(reply, 200)
|
||||
|
||||
@app.route('/api/backup/get', methods = ['POST'])
|
||||
@login_required(role='admin',perm={'backup':'read'})
|
||||
def backup_get():
|
||||
input = request.json
|
||||
id=input.get('id')
|
||||
back=db_backups.get_backup(id)
|
||||
path=back.dir
|
||||
with open(path, 'r') as file:
|
||||
file_content = file.read()
|
||||
return buildResponse({"content":file_content}, 200)
|
||||
|
||||
@app.route('/api/backup/status', methods = ['POST'])
|
||||
@login_required(role='admin',perm={'backup':'read'})
|
||||
def backup_status():
|
||||
status=db_tasks.update_check_status().status
|
||||
return jsonify({'status': status})
|
||||
559
py/api/api_dev.py
Normal file
559
py/api/api_dev.py
Normal file
|
|
@ -0,0 +1,559 @@
|
|||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# api_bakcups.py: API for managing bakcups
|
||||
# MikroWizard.com , Mikrotik router management solution
|
||||
# Author: sepehr.ha@gmail.com
|
||||
|
||||
from flask import request,redirect ,session
|
||||
import datetime
|
||||
import html
|
||||
|
||||
import config
|
||||
import re
|
||||
from libs.red import RedisDB
|
||||
from libs.webutil import app,buildResponse,login_required,get_myself,get_ip,get_agent
|
||||
from libs import util
|
||||
from libs.db import db_device,db_groups,db_user_group_perm,db_user_tasks,db_sysconfig,db_syslog
|
||||
import logging
|
||||
import json
|
||||
from playhouse.shortcuts import model_to_dict
|
||||
log = logging.getLogger("api")
|
||||
try:
|
||||
from libs import utilpro
|
||||
ISPRO=True
|
||||
except ImportError:
|
||||
ISPRO=False
|
||||
pass
|
||||
|
||||
@app.route('/', methods = ['GET'])
|
||||
def index():
|
||||
"""Just a redirect to api list."""
|
||||
if config.IS_PRODUCTION:
|
||||
return "not available", 400
|
||||
return redirect('/api/list')
|
||||
|
||||
@app.route('/api/dev/list', methods = ['POST'])
|
||||
@login_required(role='admin',perm={'device':'read'})
|
||||
def list_devs():
|
||||
"""Return devs list of assigned to user , all for admin"""
|
||||
input = request.json
|
||||
# Get devices that are in the group
|
||||
group_id = int(input.get('group_id', False))
|
||||
page = input.get('page')
|
||||
size = input.get('size')
|
||||
search = input.get('search',False)
|
||||
page = int(page or 0)
|
||||
limit = int(size or 1000)
|
||||
res = []
|
||||
try:
|
||||
# Get devices that current user have access
|
||||
uid = session.get("userid") or False
|
||||
if not uid:
|
||||
return buildResponse({'result':'failed','err':"No User"}, 200)
|
||||
# Get devices that current user have access
|
||||
devs=db_user_group_perm.DevUserGroupPermRel.get_user_devices(uid,group_id).paginate(page, limit).dicts()
|
||||
for dev in devs:
|
||||
temp=dev
|
||||
del temp['user_name']
|
||||
del temp['password']
|
||||
if ' ' not in temp['uptime']:
|
||||
temp['uptime'] = temp['uptime'].replace('w',' week ').replace('d',' day ').replace('h',' hour ').replace('m',' min ')
|
||||
res.append(temp)
|
||||
except Exception as e:
|
||||
return buildResponse({'result':'failed','err':str(e)},200)
|
||||
return buildResponse(res,200)
|
||||
|
||||
@app.route('/api/dev/get_editform', methods = ['POST'])
|
||||
@login_required(role='admin',perm={'device':'full'})
|
||||
def get_editform():
|
||||
"""return device editable data"""
|
||||
input = request.json
|
||||
# get devices that are in the group
|
||||
devid = int(input.get('devid', False))
|
||||
res = {}
|
||||
try:
|
||||
dev=db_device.get_device(devid)
|
||||
if not dev:
|
||||
return buildResponse({'status': 'failed'}, 200, error="Wrong Data")
|
||||
res['user_name']=util.decrypt_data(dev['user_name'])
|
||||
res['password']=util.decrypt_data(dev['password'])
|
||||
res['ip']=dev['ip']
|
||||
res['peer_ip']=dev['peer_ip']
|
||||
res['name']=dev['name']
|
||||
res['id']=dev['id']
|
||||
try:
|
||||
res['ips']=json.loads(db_sysconfig.get_sysconfig('all_ip'))
|
||||
except Exception as e:
|
||||
res['ips']=[]
|
||||
except Exception as e:
|
||||
log.error(e)
|
||||
return buildResponse({'status': 'failed'}, 200, error="Wrong Data")
|
||||
return buildResponse(res,200)
|
||||
|
||||
@app.route('/api/dev/save_editform', methods = ['POST'])
|
||||
@login_required(role='admin', perm={'device':'full'})
|
||||
def save_editform():
|
||||
"""save device configuration"""
|
||||
input = request.json
|
||||
devid = int(input.get('id', False))
|
||||
user_name = input.get('user_name', False)
|
||||
password = input.get('password', False)
|
||||
ip = input.get('ip', False)
|
||||
peer_ip = input.get('peer_ip', False)
|
||||
name = input.get('name', False)
|
||||
try:
|
||||
if db_device.update_device(devid, util.crypt_data(user_name), util.crypt_data(password), ip, peer_ip, name):
|
||||
db_syslog.add_syslog_event(get_myself(), "Device", "Edit", get_ip(),get_agent(),json.dumps(input))
|
||||
return buildResponse({"result":"success"}, 200)
|
||||
else:
|
||||
return buildResponse({"result":"failed","err":"Unable to update device"}, 200)
|
||||
except Exception as e:
|
||||
log.error(e)
|
||||
return buildResponse({"result":"failed","err":str(e)}, 200)
|
||||
|
||||
|
||||
@app.route('/api/devgroup/list', methods = ['POST'])
|
||||
@login_required(role='admin',perm={'device_group':'read'})
|
||||
def list_devgroups():
|
||||
"""return dev groups"""
|
||||
|
||||
# build HTML of the method list
|
||||
devs = []
|
||||
try:
|
||||
devs=list(db_groups.query_groups_api())
|
||||
except Exception as e:
|
||||
return buildResponse({'result':'failed','err':str(e)},200)
|
||||
return buildResponse(devs,200)
|
||||
|
||||
@app.route('/api/devgroup/delete', methods = ['POST'])
|
||||
@login_required(role='admin',perm={'device_group':'full'})
|
||||
def delete_group():
|
||||
"""delete dev group"""
|
||||
input = request.json
|
||||
gid = input.get('gid', False)
|
||||
try:
|
||||
if db_user_group_perm.DevUserGroupPermRel.delete_group(gid):
|
||||
db_syslog.add_syslog_event(get_myself(), "Device Group","Delete", get_ip(),get_agent(),json.dumps(input))
|
||||
return buildResponse({"result":"success"}, 200)
|
||||
else:
|
||||
return buildResponse({"result":"failed",'err':'Unable to delete'}, 200)
|
||||
except Exception as e:
|
||||
return buildResponse({"result":"failed",'err':'Unable to delete'}, 200)
|
||||
|
||||
|
||||
@app.route('/api/devgroup/members', methods = ['POST'])
|
||||
@login_required(role='admin',perm={'device_group':'read','device':'read'})
|
||||
def list_devgroups_members():
|
||||
"""return list of dev groups"""
|
||||
input = request.json
|
||||
gid=input.get('gid',False)
|
||||
# get devices that are in the group
|
||||
devs = []
|
||||
try:
|
||||
devs=list(db_groups.devs(gid))
|
||||
except Exception as e:
|
||||
return buildResponse({'result':'failed','err':str(e)},200)
|
||||
return buildResponse(devs,200)
|
||||
|
||||
@app.route('/api/devgroup/update_save_group', methods = ['POST'])
|
||||
@login_required(role='admin',perm={'device_group':'write','device':'read'})
|
||||
def update_save_group():
|
||||
"""save device group config"""
|
||||
input = request.json
|
||||
devids= input.get('array_agg', False)
|
||||
name = input.get('name', False)
|
||||
id = input.get('id', False)
|
||||
|
||||
# First check if we are editiong or creating new group
|
||||
# if id is 0 then we are creating new group
|
||||
|
||||
if id==0:
|
||||
# create new group and add devices to it
|
||||
try:
|
||||
group=db_groups.create_group(name)
|
||||
if group:
|
||||
db_syslog.add_syslog_event(get_myself(), "Device Group","Create", get_ip(),get_agent(),json.dumps(input))
|
||||
gid=group.id
|
||||
db_groups.add_devices_to_group(gid,devids)
|
||||
else:
|
||||
return buildResponse({'result':'failed','err':"Group not created"}, 200)
|
||||
return buildResponse({"result":"success"}, 200)
|
||||
except Exception as e:
|
||||
return buildResponse({'result':'failed','err':str(e)}, 200)
|
||||
else:
|
||||
# update group and add devices to it
|
||||
try:
|
||||
group=db_groups.update_group(id, name)
|
||||
db_groups.add_devices_to_group(group.id, devids)
|
||||
#get all dev ids from group and compare to devids,remove devs not availble in devids
|
||||
devs=db_groups.devs2(id)
|
||||
ids=[]
|
||||
for dev in devs:
|
||||
ids.append(dev.id)
|
||||
dev_to_remove=list(set(ids)-set(devids))
|
||||
db_groups.delete_from_group(dev_to_remove)
|
||||
db_syslog.add_syslog_event(get_myself(), "Device Group","Update", get_ip(),get_agent(),json.dumps(input))
|
||||
return buildResponse({"result":"success"}, 200)
|
||||
except Exception as e:
|
||||
return buildResponse({'result':'failed','err':str(e)}, 200)
|
||||
|
||||
|
||||
@app.route('/api/search/groups', methods = ['POST'])
|
||||
@login_required(role='admin',perm={'device_group':'read','device':'read'})
|
||||
def search_groups():
|
||||
"""search in devices"""
|
||||
input = request.json
|
||||
searchstr=input.get('searchstr',False)
|
||||
dev_groups = []
|
||||
group=db_groups.DevGroups
|
||||
try:
|
||||
if searchstr and searchstr!="":
|
||||
# find device groups that contains searchstr in the name
|
||||
dev_groups = (group
|
||||
.select()
|
||||
.where(group.name.contains(searchstr))
|
||||
.dicts())
|
||||
else:
|
||||
# return first 10 ordered alphabeticaly
|
||||
dev_groups = (group
|
||||
.select()
|
||||
.order_by(group.name)
|
||||
.limit(10)
|
||||
.dicts())
|
||||
except Exception as e:
|
||||
return buildResponse({'result':'failed','err':str(e)},200)
|
||||
return buildResponse(dev_groups,200)
|
||||
|
||||
@app.route('/api/search/devices', methods = ['POST'])
|
||||
@login_required(role='admin',perm={'device':'read'})
|
||||
def search_devices():
|
||||
"""search in groups"""
|
||||
input = request.json
|
||||
searchstr=input.get('searchstr',False)
|
||||
# build HTML of the method list
|
||||
device=db_device.Devices
|
||||
searchstr=input.get('searchstr',False)
|
||||
devs = []
|
||||
try:
|
||||
if searchstr and searchstr!="":
|
||||
# find devices that contains searchstr in the name
|
||||
devs = (device
|
||||
.select()
|
||||
.where(device.name.contains(searchstr))
|
||||
.dicts())
|
||||
else:
|
||||
# return first 10 ordered alphabeticaly
|
||||
devs = (device
|
||||
.select()
|
||||
.order_by(device.name)
|
||||
.limit(10)
|
||||
.dicts())
|
||||
except Exception as e:
|
||||
return buildResponse({'result':'failed','err':str(e)},200)
|
||||
return buildResponse(devs,200)
|
||||
|
||||
|
||||
@app.route('/api/taskmember/details', methods = ['POST'])
|
||||
@login_required(role='admin',perm={'device_group':'read','device':'read'})
|
||||
def get_taskmember_details():
|
||||
"""search in groups"""
|
||||
# build HTML of the method list
|
||||
input = request.json
|
||||
tid=input.get('taskid',False)
|
||||
if not tid:
|
||||
return buildResponse({"success":'failed',"err":"Wrong task"},200)
|
||||
res=[]
|
||||
utask=db_user_tasks.UserTasks.get_utask_by_id(tid)
|
||||
members=db_user_tasks.get_task_devices(utask,False)
|
||||
if utask.selection_type=="groups":
|
||||
for group in members:
|
||||
tmp = model_to_dict(group)
|
||||
res.append({"id":tmp['id'], "name":tmp['name']})
|
||||
else:
|
||||
for dev in members:
|
||||
tmp = model_to_dict(dev)
|
||||
res.append({"id":tmp['id'],"name":tmp['name'],"mac":tmp['mac']})
|
||||
return buildResponse(res,200)
|
||||
|
||||
|
||||
@app.route('/api/dev/info', methods = ['POST'])
|
||||
@login_required(role='admin',perm={'device':'read'})
|
||||
def dev_info():
|
||||
"""return dev info"""
|
||||
input = request.json
|
||||
devid=input.get('devid',False)
|
||||
if not devid or not isinstance(devid, int):
|
||||
return buildResponse({'status': 'failed'},200,error="Wrong Data")
|
||||
res=db_device.get_device(devid)
|
||||
options=util.build_api_options(db_device.get_devices_by_id([res['id'],])[0])
|
||||
network_info=[]
|
||||
try:
|
||||
if util.check_port(options['host'],options['port']):
|
||||
router=util.RouterOSCheckResource(options)
|
||||
network_info=util.get_network_data(router)
|
||||
del network_info['total']
|
||||
except:
|
||||
pass
|
||||
interfaces=[]
|
||||
for iface in network_info:
|
||||
interfaces.append(network_info[iface])
|
||||
#fix and change some data
|
||||
res['interfaces']=interfaces
|
||||
res.pop('user_name')
|
||||
res.pop('password')
|
||||
res.pop('wifi_config')
|
||||
res['created']=res['created'].strftime("%Y-%m-%d %H:%M:%S")
|
||||
res['modified']=res['modified'].strftime("%Y-%m-%d %H:%M:%S")
|
||||
#get data from redis
|
||||
if ISPRO:
|
||||
res['is_radio']=utilpro.check_is_radio(res['id'])
|
||||
try:
|
||||
del res['sensors']
|
||||
except Exception as e:
|
||||
log.error(e)
|
||||
return buildResponse({'status': 'failed'}, 200, error="Wrong Data")
|
||||
pass
|
||||
return buildResponse(res,200)
|
||||
|
||||
@app.route('/api/dev/sensors', methods = ['POST'])
|
||||
@login_required(role='admin',perm={'device':'read'})
|
||||
def dev_sensors():
|
||||
"""return dev sensors chart data"""
|
||||
input = request.json
|
||||
devid=input.get('devid',False)
|
||||
total=input.get('total','bps')
|
||||
delta=input.get('delta',"5m")
|
||||
if delta not in ["5m","1h","daily","live"]:
|
||||
return buildResponse({'status': 'failed'},200,error="Wrong Data")
|
||||
if not devid or not isinstance(devid, int):
|
||||
return buildResponse({'status': 'failed'},200,error="Wrong Data")
|
||||
dev=db_device.get_device(devid)
|
||||
if delta=="5m":
|
||||
start_time=datetime.datetime.now()-datetime.timedelta(minutes=5*24)
|
||||
elif delta=="1h":
|
||||
start_time=datetime.datetime.now()-datetime.timedelta(hours=24)
|
||||
elif delta=="daily":
|
||||
start_time=datetime.datetime.now()-datetime.timedelta(days=30)
|
||||
else:
|
||||
start_time=datetime.datetime.now()-datetime.timedelta(days=30)
|
||||
end_time=datetime.datetime.now()
|
||||
try:
|
||||
res={}
|
||||
res['sensors']=json.loads(dev['sensors'])
|
||||
redopts={
|
||||
"dev_id":dev['id'],
|
||||
"keys":res['sensors'],
|
||||
"start_time":start_time,
|
||||
"end_time":end_time,
|
||||
"delta":delta,
|
||||
}
|
||||
colors={
|
||||
'backgroundColor': 'rgba(77,189,116,.2)',
|
||||
'borderColor': '#4dbd74',
|
||||
'pointHoverBackgroundColor': '#fff'
|
||||
}
|
||||
reddb=RedisDB(redopts)
|
||||
data=reddb.get_dev_data_keys()
|
||||
tz=db_sysconfig.get_sysconfig('timezone')
|
||||
res["radio-sensors"]=[]
|
||||
for key in res['sensors'][:]:
|
||||
if "rx" in key or "tx" in key or "rxp" in key or "txp" in key or "radio" in key:
|
||||
if "radio" in key:
|
||||
res["radio-sensors"].append(key)
|
||||
if not 'total' in key:
|
||||
res['sensors'].remove(key)
|
||||
continue
|
||||
if "total" in key:
|
||||
if total=='bps' and 'rx/tx-total' in res['sensors'] and 'rx/tx-total' in res['sensors']:
|
||||
continue
|
||||
if total!='bps' and 'rxp/txp-total' in res['sensors'] and 'rxp/txp-total' in res['sensors']:
|
||||
continue
|
||||
temp=[]
|
||||
ids=['yA','yB']
|
||||
colors=['#17522f','#171951']
|
||||
|
||||
datasets=[]
|
||||
lables=[]
|
||||
data_keys=['tx-total','rx-total']
|
||||
if total!='bps':
|
||||
data_keys=['txp-total','rxp-total']
|
||||
for idx, val in enumerate(data_keys) :
|
||||
for d in data[val]:
|
||||
if len(lables) <= len(data[val]):
|
||||
edatetime=datetime.datetime.fromtimestamp(d[0]/1000)
|
||||
lables.append(util.utc2local(edatetime,tz=tz).strftime("%m/%d/%Y, %H:%M:%S %Z"))
|
||||
temp.append(round(d[1],1))
|
||||
datasets.append({'borderColor': colors[idx],'type': 'line','yAxisID': ids[idx],'data':temp,'unit':val.split("-")[0],'backgroundColor': colors[idx],'pointHoverBackgroundColor': '#fff'})
|
||||
temp=[]
|
||||
|
||||
if total=='bps':
|
||||
res["rx/tx-total"]={'labels':lables,'datasets':datasets}
|
||||
res['sensors'].append("rx/tx-total")
|
||||
else:
|
||||
res["rxp/txp-total"]={'labels':lables,'datasets':datasets}
|
||||
res['sensors'].append("rxp/txp-total")
|
||||
|
||||
else:
|
||||
temp={"labels":[],"data":[]}
|
||||
for d in data[key]:
|
||||
edatetime=datetime.datetime.fromtimestamp(d[0]/1000)
|
||||
temp["labels"].append(util.utc2local(edatetime,tz=tz).strftime("%m/%d/%Y, %H:%M:%S %Z"))
|
||||
temp["data"].append(round(d[1],1))
|
||||
res[key]={'labels':temp["labels"],'datasets':[{'data':temp['data'],'backgroundColor': 'rgba(77,189,116,.2)','borderColor': '#fff','pointHoverBackgroundColor': '#fff'}]}
|
||||
if 'rxp-total' in res['sensors']:
|
||||
res['sensors'].remove('txp-total')
|
||||
res['sensors'].remove('rxp-total')
|
||||
elif 'rx-total' in res['sensors']:
|
||||
res['sensors'].remove('tx-total')
|
||||
res['sensors'].remove('rx-total')
|
||||
except Exception as e:
|
||||
log.error(e)
|
||||
return buildResponse({'status': 'failed'}, 200, error="Error in generating data")
|
||||
pass
|
||||
return buildResponse(res,200)
|
||||
|
||||
|
||||
|
||||
@app.route('/api/dev/ifstat', methods = ['POST'])
|
||||
@login_required(role='admin',perm={'device':'read'})
|
||||
def dev_ifstat():
|
||||
"""return device interfaces info"""
|
||||
input = request.json
|
||||
devid=input.get('devid',False)
|
||||
chart_type=input.get('type','bps')
|
||||
delta=input.get('delta',"5m")
|
||||
interface=input.get('interface',False)
|
||||
if delta not in ["5m","1h","daily","live"]:
|
||||
return buildResponse({'status': 'failed'},200,error="Wrong Data")
|
||||
if not devid or not isinstance(devid, int):
|
||||
return buildResponse({'status': 'failed'},200,error="Wrong Data")
|
||||
res=db_device.get_device(devid)
|
||||
if delta=="5m":
|
||||
start_time=datetime.datetime.now()-datetime.timedelta(minutes=5*24)
|
||||
elif delta=="1h":
|
||||
start_time=datetime.datetime.now()-datetime.timedelta(hours=24)
|
||||
elif delta=="daily":
|
||||
start_time=datetime.datetime.now()-datetime.timedelta(days=30)
|
||||
else:
|
||||
start_time=datetime.datetime.now()-datetime.timedelta(days=30)
|
||||
|
||||
end_time=datetime.datetime.now()
|
||||
#Fix and change some data
|
||||
#Get data from redis
|
||||
res['name']="Device : " + db_device.get_device(devid)['name'] + " - Interface : " + interface
|
||||
try:
|
||||
res['sensors']=json.loads(res['sensors'])
|
||||
for sensor in res['sensors'][:]:
|
||||
regex=r'.*{}$'.format(interface)
|
||||
if not bool(re.match(regex,sensor)):
|
||||
res['sensors'].remove(sensor)
|
||||
redopts={
|
||||
"dev_id":res['id'],
|
||||
"keys":res['sensors'],
|
||||
"start_time":start_time,
|
||||
"end_time":end_time,
|
||||
"delta":delta,
|
||||
}
|
||||
colors={
|
||||
'backgroundColor': 'rgba(77,189,116,.2)',
|
||||
'borderColor': '#4dbd74',
|
||||
'pointHoverBackgroundColor': '#fff'
|
||||
}
|
||||
reddb=RedisDB(redopts)
|
||||
data=reddb.get_dev_data_keys()
|
||||
|
||||
temp=[]
|
||||
ids=['yA','yB']
|
||||
colors=['#17522f','#171951']
|
||||
|
||||
datasets=[]
|
||||
lables=[]
|
||||
tz=db_sysconfig.get_sysconfig('timezone')
|
||||
data_keys=['tx-{}'.format(interface),'rx-{}'.format(interface)]
|
||||
if chart_type=='bps':
|
||||
data_keys=['tx-{}'.format(interface),'rx-{}'.format(interface)]
|
||||
elif chart_type=='pps':
|
||||
data_keys=['txp-{}'.format(interface),'rxp-{}'.format(interface)]
|
||||
for idx, val in enumerate(data_keys):
|
||||
for d in data[val]:
|
||||
if len(lables) <= len(data[val]):
|
||||
edatetime=datetime.datetime.fromtimestamp(d[0]/1000)
|
||||
lables.append(util.utc2local(edatetime,tz=tz).strftime("%m/%d/%Y, %H:%M:%S %Z"))
|
||||
temp.append(round(d[1],1))
|
||||
datasets.append({'label':val,'borderColor': colors[idx],'type': 'line','yAxisID': ids[idx],'data':temp,'unit':val.split("-")[0],'backgroundColor': colors[idx],'pointHoverBackgroundColor': '#fff'})
|
||||
temp=[]
|
||||
res["data"]={'labels':lables,'datasets':datasets}
|
||||
|
||||
except Exception as e:
|
||||
log.error(e)
|
||||
return buildResponse({'status': 'failed'}, 200, error="Error in generating data")
|
||||
pass
|
||||
return buildResponse(res,200)
|
||||
|
||||
@app.route('/api/dev/delete', methods = ['POST'])
|
||||
@login_required(role='admin',perm={'device':'full'})
|
||||
def dev_delete():
|
||||
"""return dev info"""
|
||||
input = request.json
|
||||
devids=input.get('devids', False)
|
||||
res={}
|
||||
# ToDo: we need to delete redis keys also
|
||||
try:
|
||||
for dev in devids:
|
||||
if db_groups.delete_device(dev):
|
||||
db_syslog.add_syslog_event(get_myself(), "Device","Delete", get_ip(),get_agent(),json.dumps(input))
|
||||
res['status']='success'
|
||||
else:
|
||||
res['status'] = 'failed'
|
||||
res['err'] = 'Unable to Delete Device'
|
||||
except Exception as e:
|
||||
log.error(e)
|
||||
return buildResponse({'status': 'failed'}, 200, error=str(e))
|
||||
return buildResponse(res, 200)
|
||||
|
||||
#Development tool , We dont want this in production
|
||||
@app.route('/api/list', methods = ['GET'])
|
||||
def list_api():
|
||||
"""List the available REST APIs in this service as HTML. Queries
|
||||
methods directly from Flask, no need to maintain separate API doc.
|
||||
(Maybe this could be used as a start to generate Swagger API spec too.)"""
|
||||
|
||||
# decide whether available in production
|
||||
if config.IS_PRODUCTION:
|
||||
return "not available in production", 400
|
||||
|
||||
# build HTML of the method list
|
||||
apilist = []
|
||||
rules = sorted(app.url_map.iter_rules(), key=lambda x: str(x))
|
||||
for rule in rules:
|
||||
f = app.view_functions[rule.endpoint]
|
||||
docs = f.__doc__ or ''
|
||||
module = f.__module__ + ".py"
|
||||
|
||||
# remove noisy OPTIONS
|
||||
methods = sorted([x for x in rule.methods if x != "OPTIONS"])
|
||||
url = html.escape(str(rule))
|
||||
if not "/api/" in url and not "/auth/" in url:
|
||||
continue
|
||||
apilist.append("<div><a href='{}'><b>{}</b></a> {}<br/>{} <i>{}</i></div>".format(
|
||||
url, url, methods, docs, module))
|
||||
|
||||
header = """<body>
|
||||
<title>MikroWizard Generated API LIST</title>
|
||||
<style>
|
||||
body { width: 80%; margin: 20px auto;
|
||||
font-family: Courier; }
|
||||
section { background: #eee; padding: 40px 20px;
|
||||
border: 1px dashed #aaa; }
|
||||
i { color: #888; }
|
||||
</style>"""
|
||||
title = """
|
||||
<section>
|
||||
<h2>REST API ({} end-points)</h2>
|
||||
<h3>IS_PRODUCTION={} IS_LOCAL_DEV={} Started ago={}</h3>
|
||||
""".format(len(apilist), config.IS_PRODUCTION, config.IS_LOCAL_DEV,
|
||||
config.started_ago(True))
|
||||
footer = "</section></body>"
|
||||
|
||||
return header + title + "<br/>".join(apilist) + footer
|
||||
151
py/api/api_firmware.py
Normal file
151
py/api/api_firmware.py
Normal file
|
|
@ -0,0 +1,151 @@
|
|||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# api_firmware.py: API for managing firmware
|
||||
# MikroWizard.com , Mikrotik router management solution
|
||||
# Author: sepehr.ha@gmail.com
|
||||
|
||||
from flask import request, jsonify,session,send_file
|
||||
from playhouse.shortcuts import model_to_dict
|
||||
import datetime
|
||||
from libs.db import db_tasks,db_sysconfig,db_device,db_firmware,db_syslog
|
||||
from libs import util
|
||||
from libs.webutil import app, login_required, get_myself,buildResponse,get_myself,get_ip,get_agent
|
||||
import bgtasks
|
||||
import re
|
||||
import logging
|
||||
log = logging.getLogger("api.firmware")
|
||||
import json
|
||||
|
||||
@app.route('/api/firmware/check_firmware_update', methods = ['POST'])
|
||||
@login_required(role='admin',perm={'device':'write'})
|
||||
def check_firmware_update():
|
||||
"""Chck fimware update status"""
|
||||
input = request.json
|
||||
devids=input.get('devids',"0")
|
||||
status=db_tasks.update_check_status().status
|
||||
uid = session.get("userid") or False
|
||||
if not uid:
|
||||
return buildResponse({'result':'failed','err':"No User"}, 200)
|
||||
#if devices is [0] then check firmware for all devices of user
|
||||
if not status:
|
||||
bgtasks.check_devices_for_update(devices=devids,uid=uid)
|
||||
db_syslog.add_syslog_event(get_myself(), "Firmware","Check", get_ip(),get_agent(),json.dumps(input))
|
||||
res={'status': True}
|
||||
else:
|
||||
res={'status': status}
|
||||
|
||||
return buildResponse(res,200)
|
||||
|
||||
@app.route('/api/firmware/check_task_status', methods = ['GET'])
|
||||
@login_required(role='admin',perm={'device':'read'})
|
||||
def check_task_status():
|
||||
"""Return firmware update check service status"""
|
||||
status=db_tasks.update_check_status().status
|
||||
return jsonify({'status': status})
|
||||
|
||||
@app.route('/api/firmware/update_firmware', methods = ['POST'])
|
||||
@login_required(role='admin',perm={'device':'full'})
|
||||
def update_device():
|
||||
"""Update devices"""
|
||||
status=db_tasks.update_job_status().status
|
||||
input=request.json
|
||||
devids=input.get('devids',"0")
|
||||
uid = session.get("userid") or False
|
||||
if not uid:
|
||||
return buildResponse({'result':'failed','err':"No User"}, 200)
|
||||
if not status:
|
||||
db_syslog.add_syslog_event(get_myself(), "Firmware","update", get_ip(),get_agent(),json.dumps(input))
|
||||
bgtasks.update_device(devices=devids,uid=uid)
|
||||
res={'status': True}
|
||||
else:
|
||||
res={'status': status}
|
||||
return buildResponse(res,200)
|
||||
|
||||
@app.route('/api/firmware/get_firms', methods = ['POST'])
|
||||
@login_required(role='admin',perm={'settings':'full'})
|
||||
def get_firms():
|
||||
"""get list of of downloaded firmwares in local repo"""
|
||||
input = request.json or {}
|
||||
page = input.get('page')
|
||||
size = input.get('size')
|
||||
search = input.get('search')
|
||||
|
||||
reply = db_firmware.query_firms(page, size, search).dicts()
|
||||
data={
|
||||
"firms":reply,
|
||||
"updateBehavior":db_sysconfig.get_sysconfig("old_firmware_action"),
|
||||
"firmwaretoinstall":db_sysconfig.get_sysconfig("latest_version"),
|
||||
"firmwaretoinstallv6":db_sysconfig.get_sysconfig("old_version"),
|
||||
}
|
||||
return buildResponse(data, 200)
|
||||
|
||||
@app.route('/api/firmware/get_downloadable_firms', methods = ['POST'])
|
||||
@login_required(role='admin',perm={'settings':'full'})
|
||||
def get_downloadable_firms():
|
||||
"""get list of availble Firmwares from Mikrotik Official webstire"""
|
||||
input = request.json or {}
|
||||
versions=util.get_mikrotik_versions()
|
||||
versions = sorted(versions, key=lambda x: [int(y) if y.isdigit() else int(re.sub(r'\D', '', y)) for y in x.split('.')])
|
||||
|
||||
return buildResponse({"versions":versions}, 200)
|
||||
|
||||
@app.route('/api/firmware/download_firmware_to_repository', methods = ['POST'])
|
||||
@login_required(role='admin',perm={'settings':'full'})
|
||||
def download_firmware_to_repository():
|
||||
"""Download Firmware from Mikrotik Official website"""
|
||||
input = request.json or {}
|
||||
version=input.get('version')
|
||||
status=db_tasks.downloader_job_status().status
|
||||
|
||||
if not status:
|
||||
db_syslog.add_syslog_event(get_myself(), "Firmware","Download", get_ip(),get_agent(),json.dumps(input))
|
||||
bgtasks.download_firmware(version=version)
|
||||
return buildResponse({'status': True}, 200)
|
||||
else:
|
||||
return buildResponse({'status': status}, 200)
|
||||
|
||||
@app.route('/api/firmware/update_firmware_settings', methods = ['POST'])
|
||||
@login_required(role='admin',perm={'settings':'write'})
|
||||
def update_firmware_settings():
|
||||
"""Change system settings for firmware update"""
|
||||
input = request.json or {}
|
||||
updateBehavior=input.get('updatebehavior')
|
||||
firmwaretoinstall=input.get('firmwaretoinstall')
|
||||
firmwaretoinstallv6=input.get('firmwaretoinstallv6')
|
||||
db_sysconfig.update_sysconfig("old_firmware_action", updateBehavior)
|
||||
db_sysconfig.update_sysconfig("latest_version", firmwaretoinstall)
|
||||
db_sysconfig.update_sysconfig("old_version", firmwaretoinstallv6)
|
||||
db_syslog.add_syslog_event(get_myself(), "Firmware","settings", get_ip(),get_agent(),json.dumps(input))
|
||||
return buildResponse({'status': True}, 200)
|
||||
|
||||
def serialize_datetime(obj):
|
||||
if isinstance(obj, datetime.datetime):
|
||||
return obj.isoformat()
|
||||
|
||||
@app.route('/api/firmware/get_firmware/<firmid>', methods = ['POST','GET'])
|
||||
def get_firmware(firmid):
|
||||
"""Download firmware of given id from repo"""
|
||||
firm=db_firmware.get_firm(firmid)
|
||||
dev_ip=request.remote_addr
|
||||
# log.error(dev_ip)
|
||||
# if dev_ip:
|
||||
# dev=db_device.query_device_by_ip(dev_ip)
|
||||
# if not dev:
|
||||
# return buildResponse({'result':'failed', 'err':"Device not found"}, 200)
|
||||
|
||||
if firm:
|
||||
log.error(dev_ip)
|
||||
data={
|
||||
"devip":dev_ip,
|
||||
# "devid":dev.id,
|
||||
"firm":model_to_dict(firm),
|
||||
}
|
||||
db_syslog.add_syslog_event(get_myself(), "Firmware","download", get_ip(),get_agent(),json.dumps(data,default=serialize_datetime))
|
||||
# if dev.arch != firm.architecture:
|
||||
# return buildResponse({'result':'failed','err':"Wrong architecture"}, 200)
|
||||
path=firm.location
|
||||
return send_file(path, as_attachment=True)
|
||||
# log.error(dev)
|
||||
return buildResponse({'result':'failed','err':"somthing went wrong"}, 200)
|
||||
|
||||
496
py/api/api_logs.py
Normal file
496
py/api/api_logs.py
Normal file
File diff suppressed because one or more lines are too long
39
py/api/api_scanner.py
Normal file
39
py/api/api_scanner.py
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# api_scanner.py: API for device scanner in network
|
||||
# MikroWizard.com , Mikrotik router management solution
|
||||
# Author: sepehr.ha@gmail.com
|
||||
|
||||
from flask import request
|
||||
|
||||
from libs.db import db_tasks,db_syslog
|
||||
from libs.webutil import app, login_required,buildResponse,get_myself,get_ip,get_agent
|
||||
import bgtasks
|
||||
import json
|
||||
import logging
|
||||
log = logging.getLogger("api.scanner")
|
||||
|
||||
@app.route('/api/scanner/scan', methods = ['POST'])
|
||||
@login_required(role='admin',perm={'device':'full'})
|
||||
def scan_network():
|
||||
"""Do scan requested network for given ip range to find mikrotik devices"""
|
||||
input = request.json
|
||||
start=input.get('start',False)
|
||||
end=input.get('end',False)
|
||||
port=input.get('port',8728)
|
||||
if not port:
|
||||
port=8728
|
||||
password=input.get('password',False)
|
||||
username=input.get('user',False)
|
||||
status=db_tasks.scanner_job_status().status
|
||||
|
||||
if not status:
|
||||
if start and end and port:
|
||||
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)
|
||||
return buildResponse({'status': True},200)
|
||||
else:
|
||||
return buildResponse({'status': status},200)
|
||||
else:
|
||||
return buildResponse({'status': status},200)
|
||||
98
py/api/api_snippet.py
Normal file
98
py/api/api_snippet.py
Normal file
|
|
@ -0,0 +1,98 @@
|
|||
#!/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
|
||||
|
||||
from libs.db import db_user_tasks,db_syslog
|
||||
from libs.webutil import app, login_required,buildResponse,get_myself,get_ip,get_agent
|
||||
from functools import reduce
|
||||
import operator
|
||||
import logging
|
||||
import json
|
||||
|
||||
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)
|
||||
51
py/api/api_sysconfig.py
Normal file
51
py/api/api_sysconfig.py
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# api_sysconfig.py: API for MikroWizard system config
|
||||
# MikroWizard.com , Mikrotik router management solution
|
||||
# Author: sepehr.ha@gmail.com
|
||||
|
||||
from flask import request
|
||||
|
||||
from libs.db import db_sysconfig,db_syslog
|
||||
from libs import util
|
||||
from libs.webutil import app, login_required,buildResponse,get_myself,get_ip,get_agent
|
||||
import time
|
||||
import logging
|
||||
import json
|
||||
|
||||
log = logging.getLogger("api.sysconfig")
|
||||
|
||||
@app.route('/api/sysconfig/get_all', methods = ['POST'])
|
||||
@login_required(role='admin',perm={'settings':'read'})
|
||||
def sysconfig_get_all():
|
||||
"""get all system configs"""
|
||||
|
||||
input = request.json
|
||||
sysconfig=db_sysconfig.get_all()
|
||||
res={}
|
||||
for s in sysconfig:
|
||||
res[s.key]={"value":s.value,"modified":s.modified}
|
||||
return buildResponse({"sysconfigs":res})
|
||||
|
||||
|
||||
@app.route('/api/sysconfig/save_all', methods = ['POST'])
|
||||
@login_required(role='admin',perm={'settings':'write'})
|
||||
def sysconfig_save_all():
|
||||
"""save system configs"""
|
||||
|
||||
input = request.json
|
||||
data=[]
|
||||
now=time.time()
|
||||
for k,v in input.items():
|
||||
if k=="default_password" and v['value']=="":
|
||||
continue
|
||||
elif k=="default_user" and v['value']=="":
|
||||
continue
|
||||
elif k=="default_password" or k=="default_user":
|
||||
v['value']=util.crypt_data(v['value'])
|
||||
data.append({"key":k,"value":v['value'],"modified":"NOW"})
|
||||
db_syslog.add_syslog_event(get_myself(), "Sys Config","Update", get_ip(),get_agent(),json.dumps(input))
|
||||
db_sysconfig.save_all(data)
|
||||
|
||||
return buildResponse({"status":"success"})
|
||||
239
py/api/api_user_tasks.py
Normal file
239
py/api/api_user_tasks.py
Normal file
|
|
@ -0,0 +1,239 @@
|
|||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# api_user_tasks.py: API for create modify schedule tasks
|
||||
# MikroWizard.com , Mikrotik router management solution
|
||||
# Author: sepehr.ha@gmail.com
|
||||
|
||||
from flask import request
|
||||
from libs.db import db_syslog,db_user_tasks
|
||||
from libs.webutil import app, login_required,buildResponse,get_myself,get_ip,get_agent
|
||||
from functools import reduce
|
||||
import operator
|
||||
from crontab import CronTab,CronSlices
|
||||
import logging
|
||||
from cron_descriptor import get_description
|
||||
import json
|
||||
from pathlib import Path
|
||||
try:
|
||||
from libs import utilpro
|
||||
ISPRO=True
|
||||
except ImportError:
|
||||
ISPRO=False
|
||||
pass
|
||||
log = logging.getLogger("api.usertasks")
|
||||
|
||||
|
||||
@app.route('/api/user_tasks/list', methods = ['POST'])
|
||||
@login_required(role='admin',perm={'task':'read'})
|
||||
def user_tasks_list():
|
||||
"""return user task list"""
|
||||
input = request.json
|
||||
name=input.get('name',False)
|
||||
description=input.get('description',False)
|
||||
action=input.get('action',False)
|
||||
task_type=input.get('task_type',False)
|
||||
utaks=db_user_tasks.UserTasks
|
||||
# build where query
|
||||
clauses = []
|
||||
if name:
|
||||
clauses.append(utaks.name.contains(name))
|
||||
if description:
|
||||
clauses.append(utaks.description.contains(description))
|
||||
if action:
|
||||
clauses.append(utaks.action == action)
|
||||
if task_type:
|
||||
clauses.append(utaks.task_type == task_type)
|
||||
if not ISPRO:
|
||||
clauses.append(utaks.task_type != 'firmware')
|
||||
expr=""
|
||||
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]
|
||||
try:
|
||||
if len(clauses):
|
||||
expr = reduce(operator.and_, clauses)
|
||||
query=utaks.select(*selector).where(expr)
|
||||
else:
|
||||
query=utaks.select(*selector)
|
||||
query=query.order_by(utaks.id.desc())
|
||||
logs=list(query.dicts())
|
||||
except Exception as e:
|
||||
return buildResponse({"status":"failed", "err":str(e)},200)
|
||||
return buildResponse(logs,200)
|
||||
|
||||
@app.route('/api/user_tasks/create', methods = ['POST'])
|
||||
@login_required(role='admin',perm={'task':'write'})
|
||||
def user_tasks_create():
|
||||
"""crate user task"""
|
||||
input = request.json
|
||||
name=input.get('name',False)
|
||||
description=input.get('description',False)
|
||||
snippetid=input.get('snippetid',False)
|
||||
members=input.get('members', False)
|
||||
cron=input.get('cron',False)
|
||||
action=input.get('action',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 name or not description:
|
||||
return buildResponse({'status': 'failed'},200,error="Wrong name/desc")
|
||||
#check if cron is valid and correct
|
||||
if cron and not CronSlices.is_valid(cron):
|
||||
return buildResponse({'status': 'failed'},200,error="Wrong Cron")
|
||||
|
||||
data={
|
||||
'name':name,
|
||||
'description':description,
|
||||
'snippetid':int(snippetid) if snippetid else 0,
|
||||
'cron':cron,
|
||||
'desc_cron': get_description(cron),
|
||||
'action': action,
|
||||
'task_type':task_type,
|
||||
'selection_type':selection_type,
|
||||
'data':json.dumps(taskdata) if taskdata else None
|
||||
}
|
||||
|
||||
if selection_type not in ["devices","groups"]:
|
||||
return buildResponse({'status': 'failed'}, 200, error="Wrong member type")
|
||||
|
||||
if task_type not in ["backup","snippet","firmware"]:
|
||||
return buildResponse({'status': 'failed'}, 200, error="Wrong task type")
|
||||
try:
|
||||
task=utasks.create(**data)
|
||||
#add members to task
|
||||
if len(members):
|
||||
db_user_tasks.add_member_to_task(task.id, members, selection_type)
|
||||
taskid=task.id
|
||||
if task_type=="backup":
|
||||
crontab = CronTab(user=True)
|
||||
directory=Path(app.root_path).parent.absolute()
|
||||
command = "python3 {}/task_run.py {}".format(directory,taskid)
|
||||
comment = "MikroWizard task #" + "taskid:{};".format(taskid)
|
||||
jobs = crontab.find_comment(comment)
|
||||
if len(list(jobs)) > 0:
|
||||
jobs = crontab.find_comment(comment)
|
||||
crontab.remove(jobs)
|
||||
crontab.write()
|
||||
job = crontab.new(command=command,comment=comment)
|
||||
job.setall(cron)
|
||||
crontab.write()
|
||||
db_syslog.add_syslog_event(get_myself(), "Task","Create", get_ip(),get_agent(),json.dumps(input))
|
||||
return buildResponse([{'status': 'success',"taskid":taskid}],200)
|
||||
except Exception as e:
|
||||
log.error(e)
|
||||
return buildResponse({'status': 'failed','massage':str(e)},200)
|
||||
|
||||
|
||||
@app.route('/api/user_tasks/edit', methods = ['POST'])
|
||||
@login_required(role='admin',perm={'task':'write'})
|
||||
def user_tasks_edit():
|
||||
"""create edit user task"""
|
||||
input = request.json
|
||||
name=input.get('name',False)
|
||||
task_id=input.get('id', False)
|
||||
description=input.get('description',False)
|
||||
snippetid=input.get('snippetid',False)
|
||||
members=input.get('members', False)
|
||||
cron=input.get('cron',False)
|
||||
action=input.get('action',False)
|
||||
task_type=input.get('task_type',"backup")
|
||||
selection_type=input.get('selection_type',False)
|
||||
taskdata=input.get('data', False)
|
||||
# todo
|
||||
# add owner check devids and dev groups with owner
|
||||
if not name or not description:
|
||||
return buildResponse({'status': 'failed'},200,error="Wrong name/desc")
|
||||
# Check if cron is valid and correct
|
||||
if cron and not CronSlices.is_valid(cron):
|
||||
return buildResponse({'status': 'failed'},200,error="Wrong Cron")
|
||||
|
||||
if selection_type not in ["devices","groups"]:
|
||||
return buildResponse({'status': 'failed'}, 200, error="Wrong member type")
|
||||
|
||||
if task_type not in ["backup","snippet","firmware"]:
|
||||
return buildResponse({'status': 'failed'}, 200, error="Wrong task type")
|
||||
|
||||
# check task exist and valid
|
||||
utask=db_user_tasks.get_object_or_none(db_user_tasks.UserTasks, id=task_id)
|
||||
|
||||
data={
|
||||
'name':name,
|
||||
'description':description,
|
||||
'snippetid':int(snippetid) if snippetid else 0,
|
||||
'cron':cron,
|
||||
'desc_cron': get_description(cron),
|
||||
'action': action,
|
||||
'task_type':task_type,
|
||||
'selection_type':selection_type,
|
||||
'data':json.dumps(taskdata) if taskdata else None
|
||||
}
|
||||
|
||||
# Update utask
|
||||
utasks=db_user_tasks.UserTasks
|
||||
utasks.update(**data).where(utasks.id == utask.id).execute()
|
||||
|
||||
# Delete old members
|
||||
db_user_tasks.delete_members(utask.id)
|
||||
# Add new members
|
||||
if len(members):
|
||||
db_user_tasks.add_member_to_task(task_id, members, selection_type)
|
||||
|
||||
try:
|
||||
taskid=utask.id
|
||||
crontab = CronTab(user=True)
|
||||
directory=Path(app.root_path).parent.absolute()
|
||||
command = "/usr/local/bin/python3 {}/task_run.py {} >> /var/log/cron.log 2>&1".format(directory,taskid)
|
||||
comment = "MikroWizard task #" + "taskid:{};".format(taskid)
|
||||
jobs = crontab.find_comment(comment)
|
||||
if len(list(jobs)) > 0:
|
||||
jobs = crontab.find_comment(comment)
|
||||
crontab.remove(jobs)
|
||||
crontab.write()
|
||||
job = crontab.new(command=command,comment=comment)
|
||||
job.setall(cron)
|
||||
crontab.write()
|
||||
db_syslog.add_syslog_event(get_myself(), "Task","Edit", get_ip(),get_agent(),json.dumps(input))
|
||||
return buildResponse([{'status': 'success',"taskid":taskid}],200)
|
||||
except Exception as e:
|
||||
log.error(e)
|
||||
return buildResponse({'status': 'failed','massage':str(e)},200)
|
||||
|
||||
|
||||
@app.route('/api/user_tasks/delete', methods = ['POST'])
|
||||
@login_required(role='admin',perm={'task':'full'})
|
||||
def user_tasks_delete():
|
||||
"""delete user task"""
|
||||
input = request.json
|
||||
taskid=input.get('taskid',False)
|
||||
utaks=db_user_tasks.UserTasks
|
||||
crontab = CronTab(user=True)
|
||||
utask=db_user_tasks.get_object_or_none(db_user_tasks.UserTasks, id=taskid)
|
||||
comment = "MikroWizard task #" + "taskid:{};".format(taskid)
|
||||
if not taskid:
|
||||
return buildResponse({'status': 'failed'},200,error="Wrong name/desc")
|
||||
try:
|
||||
jobs = crontab.find_comment(comment)
|
||||
if len(list(jobs)) > 0:
|
||||
jobs = crontab.find_comment(comment)
|
||||
crontab.remove(jobs)
|
||||
crontab.write()
|
||||
# Delete old members
|
||||
db_user_tasks.delete_members(utask.id)
|
||||
# delete task
|
||||
res=utaks.delete().where(utaks.id == utask.id).execute()
|
||||
if res:
|
||||
db_syslog.add_syslog_event(get_myself(), "Task","Delete", get_ip(),get_agent(),json.dumps(input))
|
||||
return buildResponse([{'status': 'success',"taskid":res}],200)
|
||||
else:
|
||||
return buildResponse([{'status': 'failed',"massage":"record not exist"}],200)
|
||||
except Exception as e:
|
||||
log.error(e)
|
||||
return buildResponse({'status': 'failed','massage':str(e)},200)
|
||||
|
||||
|
||||
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue