vproc.py 9.41 KB
#!/usr/bin/python
# encoding:utf-8

#######################################################
#   author: liuh    2018-10-24
#   copy to device /usr/local/bin/vproc
#######################################################

import sys
import getopt
import os
import shutil
import time
import json

#######################config#####################
# ROOT_PATH="/root/UserApp/vproc"
ROOT_PATH="/root/Log/vproc"
# ROOT_PATH="./vproc"
version="v1.2"
##################################################

def usage():
    print("""
    useage: vproc command [options]

    there are vproc commands:
        read    read a key's value
        write   write a key's value
        clean   remove group of items
        lld     generate zabbix Low-level discovery json string
        watch   display items in the command line

    write command options:
        [+]-k any, --key=any | status item key.
        [+]-v any, --value=any | status item value.
        example:
            vproc write --key=vaserver.license --value=1
            vproc write --key=vaserver.va0.cameraname --value=camera1
            vproc write --key=vaserver.va0.playok --value=1

    read command options:
        [+]-k any, --key=any | status item key.
        example:
            vproc read --key=vaserver.va0.cameraname
            if executed write command example, it would be print camera1


    clean command options:
        [+]-p any, --path=any | the items's group key path
        example:
            vproc clean --path=vaserver.va0
            if executed write command example, the dir:VPROC_ROOT/vaserver/va0 would be remove.

    lld command options:
        [+]-p any, --path=any | use the first level directory/file name in the [path] as the value of the macro
        [+]-m any, --macro=any | macro name | defaule: MACRONAME
        example:
            vproc lld --path=vaserver --macro=MACRONAME
            if executed write command example, print the json string: 
            {"data":[{"{#MACRONAME}":"va0"},{"{#MACRONAME}":"license"}]}


    watch command options:
        [+]-p any, --path=any | monitoring item groups path that need to be displayed
        example:
            vproc watch --path=vaserver.va0
            if executed write command example, the display string:
                vaserver:
                    ---- va0:
                        ---- cameraname: camera1
                        ---- playok: 1

    """)


def write_single_status(key, value):
    paths = key.split('.')
    paths_len = len(paths)
    if(paths_len<2):
        print("invalid key path, must be greater than 2 level")
        sys.exit(-1)
    if(paths_len>50):
        print("invalid key path, level too deep")
        sys.exit(-1)
    fullpath = ROOT_PATH
    for path in (paths[:-1]):
        fullpath = fullpath+ "/" + path
    if not os.path.exists(fullpath):
        os.makedirs(fullpath)
    fullpath = fullpath+"/"+paths[-1]

    with open(fullpath, 'w') as f:
        f.write(value)

def read_single_status(key):
    paths = key.split('.')
    paths_len = len(paths)
    if(paths_len<2):
        print("invalid key path, must be greater than 2 level")
        sys.exit(-1)
    fullpath = ROOT_PATH
    for path in paths:
        fullpath = fullpath+ "/" + path
    if not os.path.exists(fullpath):
        return ""
    str=""
    with open(fullpath, 'r') as f:
        strs=f.readlines()
        if(len(strs)>0):
            str = strs[0]

    return str


def remove_items(key_path):
    paths = key_path.split('.')
    paths_len = len(paths)
    if(paths_len<1):
        print("invalid key path, must be greater than 1 level")
        sys.exit(-1)
    fullpath = ROOT_PATH
    for path in paths:
        fullpath = fullpath+ "/" + path

    if(os.path.exists(fullpath)):
        if(os.path.isfile(fullpath)):
            os.remove(fullpath)
            # print("remove {}".format(fullpath))
        if(os.path.isdir(fullpath)):
            shutil.rmtree(fullpath)
            # print("rmdir {}".format(fullpath))
    else:
        print("no suck file or dir: {}".format(fullpath))

def print_item(path):
    key = ""
    for node in path.split("/")[2:]:
        if(node != "."):
            key = key + node + "."
    key = key[0: len(key)-1]
    s=""
    with open(path, 'r') as f:
        strs=f.readlines()
        if(len(strs)>0):
            s= strs[0]
    print("{}:\t\t\t\t\t\t{}".format(key, s))

def watch_items(key_paths):
    for key_path in key_paths:
        watch_root = ROOT_PATH
        midpath = ""
        paths = key_path.split('.')
        paths_len = len(paths)
        if(paths_len>0):
            for path in paths:
                watch_root = watch_root+ "/" + path
                midpath = midpath+ path + "/"
        if(os.path.isfile(watch_root)):
            print_item(watch_root)
        else:
            filepaths = []
            if not os.path.exists(watch_root):
                print("no suck file or dir: {}".format(watch_root))
            for parent_dir, dirnames, filenames in os.walk(watch_root):
                for file in filenames:
                    file_full_name = os.path.join(parent_dir, file)
                    filepaths.append(file_full_name)
            for path in filepaths:
                print_item(path)

def lld_json(paths, macro):
    subobjs = []
    for key_path in paths:
        filepaths = []
        watch_root = ROOT_PATH
        midpath = ""
        paths = key_path.split('.')
        paths_len = len(paths)
        if(paths_len>0):
            for path in paths:
                watch_root = watch_root+ "/" + path
                midpath = midpath+ path + "/"
        if(os.path.isfile(watch_root)):
            return ""
        else:
            if not os.path.exists(watch_root):
                print("no suck file or dir: {}".format(watch_root))
            for parent_dir, dirnames, filenames in os.walk(watch_root):
                for file in filenames:
                    if(watch_root == parent_dir):
                        file_full_name = os.path.join(parent_dir, file)
                        filepaths.append(file)
                for dirname in dirnames:
                    if(watch_root == parent_dir):
                        filepaths.append(dirname)
        for fp in filepaths:
            objkey = "{{#{}}}".format(macro)
            subobj = {objkey: fp}
            subobjs.append(subobj)
    obj = {'data': subobjs}
    return json.dumps(obj)



def main():
    argc = len(sys.argv)
    if argc < 3 or (sys.argv[1]!= "read" and sys.argv[1]!= "write" 
        and sys.argv[1]!= "clean" and sys.argv[1]!= "watch" and sys.argv[1]!= "lld"):
        usage()
        sys.exit(-1)

    try:
        options,args = getopt.getopt(sys.argv[2:],"-h-k:-v:-p:-m:",["help","key=","value=", "path=", "macro="])
    except getopt.GetoptError:
        print("error: invalid args")
        sys.exit(-1)

    keys=[]
    values=[]
    key_paths=[]
    macros=[]
    if(sys.argv[1] == "write"):
        for name,value in options:
            if name in ("-h","--help"):
                usage()
            if name in ("-k","--key"):
                keys.append(value)
            if name in ("-v","--value"):
                values.append(value)
        keys_len = len(keys)
        values_len = len(values)
        if keys_len != values_len:
            print("invalid args, keys count is {}, values count is {}".format(keys_len, values_len))
            sys.exit(-1)
        for index in range(len(keys)):
            write_single_status(keys[index], values[index])
        sys.exit(0)
    if(sys.argv[1] == "read"):
        for name,value in options:
            if name in ("-h","--help"):
                usage()
            if name in ("-k","--key"):
                keys.append(value)
            if name in ("-v","--value"):
                values.append(value)
        for index in range(len(keys)):
            readvalue = read_single_status(keys[index])
            if(len(values)>0):
                if(index < len(values)-1):
                    defaultvalue = values[index]
                else:
                    defaultvalue = values[0]

            if(readvalue == "" and len(values)>0):
                print(defaultvalue)
            else:
                print(readvalue)
        sys.exit(0)
    if(sys.argv[1] == "clean"):
        for name,value in options:
            if name in ("-h","--help"):
                usage()
            if name in ("-p","--path"):
                key_paths.append(value)
        for index in range(len(key_paths)):
            remove_items(key_paths[index])
        sys.exit(0)
    if(sys.argv[1] == "lld"):
        for name,value in options:
            if name in ("-h","--help"):
                usage()
            if name in ("-p","--path"):
                key_paths.append(value)
            if name in ("-m","--macro"):
                macros.append(value)
        if len(macros) > 0:
            print(lld_json(key_paths, macros[0]))
        else:
            print(lld_json(key_paths, "MACRONAME"))
        sys.exit(0)
    if(sys.argv[1] == "watch"):
        for name,value in options:
            if name in ("-h","--help"):
                usage()
            if name in ("-p","--path"):
                key_paths.append(value)
        while True:
            try:
                os.system("clear")
                os.system("date")
                watch_items(key_paths)
                time.sleep(1)
            except KeyboardInterrupt, e:
                print ''
                print "bye"
                sys.exit(0)
        sys.exit(0)


if __name__ == '__main__':
    main()