def listinstalled(summary=False): options = '-f=${binary:Package};${Version};${Architecture}' + ( ';${binary:Summary}\n' if summary else '\n') command = ['dpkg-query', options, '-W'] try: output = check_output(command, stderr=PIPE, universal_newlines=True).splitlines() except CalledProcessError as e: return command_error(e, command) except FileNotFoundError as e: return command_error(e, command) #Lista di chiavi per le informazioni sull'app keys = ['name', 'version', 'architecture'] if summary: keys.append('summary') #Conterrà una lista di dizionari con tutte le app installate nel sistema pkgs = list() #Inserimento valori nella lista apps() for i in output: appinfo = i.split(';') pkgs.append(dict(zip(keys, appinfo))) return command_success(data=pkgs)
def locate(name, insensitive=True): #Cannot search on empty string if not name: return command_error( returncode=255, stderr='Empty search string not allowed' ) try: command = ['locate', '-i', name] if insensitive is False: command.pop(1) found = check_output(command, stderr=PIPE, universal_newlines=True).splitlines() except CalledProcessError as e: return command_error( e, command ) return command_success( data=found )
def getuser(user): try: command = ['getent', 'passwd', user] userinfo = check_output(command, stderr=PIPE, universal_newlines=True).splitlines() except CalledProcessError as e: return command_error(e, command) #Info sull'utente dal file /etc/passwd userinfo = userinfo[0].split(':') #Getting user groups usergroups = getusergroups(user) if usergroups['returncode'] is 0: usergroups = usergroups['data'] else: return usergroups #Returns the entire error dictionary as created by "command_error" function return command_success( data=dict({ 'uname': userinfo[0], 'canlogin': '******' if userinfo[1] == 'x' else 'no', 'uid': userinfo[2], 'gid': userinfo[3], 'geco': userinfo[4].split(','), 'home': userinfo[5], 'shell': userinfo[6], 'group': usergroups.pop(0), #Main user group 'groups': usergroups if usergroups else "< No groups >" }))
def aptshow(pkgname, onlydependences=False): mode = 'depends' if onlydependences else 'show' try: command = ['apt-cache', mode, pkgname] output = check_output(command, stderr=PIPE, universal_newlines=True) except CalledProcessError as e: return command_error(e, command) if onlydependences: #Remove the first line (header) toreturn = re.sub('^.*\\n', '', output) else: #On multiple results only keep the first one output = output.split('\n\n')[0] output = output.splitlines( ) #<-- We use splitlines() here because onlydependences does not need a split-lined output #Check whether the package is installed or not isinstalled = None try: command = ['dpkg', '-s', pkgname] check_call(command) except CalledProcessError as e: isinstalled = False if isinstalled is None: isinstalled = True #Removing useless lines linestomantain = [ 'Package:', 'Version:', 'Priority:', 'Section:', 'Origin:', 'Installed-Size:', 'Depends:', 'Description', ' ' ] output = list( filter( lambda line: any(line.startswith(s) for s in linestomantain), output)) #Merging all of descrition lines i = 0 n = len(output) while i < n: if output[i].startswith(' '): output[i - 1] = output[i - 1] + output[i] #<-- Merge lines del output[i] #<-- Delete current line n -= 1 else: i += 1 #Converting list to dictionary toreturn = dict() for line in output: dictelems = line.split(':', maxsplit=1) toreturn.update({dictelems[0]: dictelems[1]}) #Is this package installed? toreturn.update({'Installed': 1 if isinstalled else 0}) return command_success(data=toreturn)
def adduser(user, password, shell="/bin/bash"): logid = mongolog(locals()) if not shell: return command_error( returncode=200, stderr="String containing new shell name cannot be empty", logid=logid) try: command = ['useradd', '-m', '-p', password, '-s', shell, user] check_output(command, stderr=PIPE, universal_newlines=True) except CalledProcessError as e: return command_error(e, command, logid) return command_success(logid=logid)
def updatedb(): try: command = ['updatedb'] check_call(command, stderr=PIPE) except CalledProcessError as e: return command_error( e, command ) return command_success()
def getusergroups(user): command = ['groups', user] try: usergroups = check_output(command, stderr=PIPE, universal_newlines=True).splitlines() except CalledProcessError as e: command_error(e, command) # .------Removing username from list # | .----------. # V V | usergroups = re.sub('^.*: ', '', usergroups[0]) #Only first line contains the groups usergroups = usergroups.split(' ') return command_success(data=usergroups)
def hostname(newhostname=""): command = ['hostname'] if newhostname: logid = mongolog( locals() ) command.append(newhostname) try: hostname = check_output(command, stderr=PIPE, universal_newlines=True) except CalledProcessError as e: if newhostname: return command_error( e, command, logid ) else: return command_error( e, command ) if newhostname: return command_success( logid=logid ) else: return command_success( data=hostname )
def aptupdate(): logid = mongolog(locals()) try: command = ['apt-get', 'update'] check_call(command) except CalledProcessError as e: return command_error(e, command, logid) return command_success(logid=logid)
def delroute(route): logid = mongolog(locals()) if not type(route) is type(dict()): command_error( returncode=202, stderr='delroute function can only accept a dictionary as argument', logid=logid) command = [ 'route', 'del', '-net', route['Destination'], 'netmask', route['Genmask'], 'gw', route['Gateway'] ] try: check_call(command) except CalledProcessError as e: return command_error(e, command, logid) return command_success(logid=logid)
def ifacedown(iface): logid = mongolog(locals()) command = ['ifconfig', iface, 'down'] try: check_call(command) except CalledProcessError as e: return command_error(e, command, logid) return command_success(logid=logid)
def updateusershell(user, shell): logid = mongolog(locals()) if not shell: return command_error( returncode=200, stderr="String containing new shell name cannot be empty", logid=logid) command = ['chsh', user, '-s', shell] try: check_call(command) # check_output(command, stderr=PIPE, universal_newlines=True) except CalledProcessError as e: return command_error(e, command, logid) return command_success(logid=logid)
def ifacestat(iface="", namesonly=False): command = ['ifconfig', '-a'] if iface: command.append(iface) try: output = check_output(command, stderr=PIPE, universal_newlines=True) except CalledProcessError as e: return command_error(e, command) #After this split each list item contains an interface specs output = output.split('\n\n') #Removing empty line at the end del output[-1] #List or dict to be returned #If namesonly=True is a list, dict instead ifaces = list() if namesonly else dict() for iface in output: #Splitting interface lines iface = iface.splitlines() #Getting iface name on first line #We need to split first line and reinsert the second item in the original list firstline = iface.pop(0).split(None, maxsplit=1) #Returns a list cotaining all interfaces name if namesonly: ifaces.append(firstline[0]) #Returns a dict containig all interfaces specs else: iface.insert(0, firstline[1]) #Cutting out useless lines i = 0 #Using "enumerate" because we need to modify the original list for index, value in enumerate(iface): #"i" indicates where to stop cutting i += 1 #Removing leading and trailing spaces iface[index] = iface[index].strip() if iface[index].startswith('UP') or iface[index].startswith( 'DOWN'): break #A dictionary where the key is the interface name and the value is part of the lines related to such interface ifaces.update({firstline[0]: iface[:i]}) # '\n'.join(iface[:i]) }) return command_success(data=ifaces)
def aptsearch(pkgname, namesonly=True): #Cannot search on empty string if not pkgname: command_error(returncode=255, stderr='Empty search string not allowed') command = ['apt-cache', 'search', pkgname] if namesonly: command.append('--names-only') try: output = check_output(command, stderr=PIPE, universal_newlines=True).splitlines() except CalledProcessError as e: return command_error(e, command) keys = ['name', 'desc'] pkgs = list() for i in output: appinfo = i.split(' - ') pkgs.append(dict(zip(keys, appinfo))) return command_success(data=pkgs)
def addroute(gw, net, netmask, default=False): logid = mongolog(locals()) command = ['route', 'add'] #If default is true we just need "gw" parameters if default: command = command + ['default', 'gw', gw] #If default in False "net" and "netmask" must be set elif net is None or netmask is None: command_error( returncode=201, stderr= 'On non-default route you must enter "net" and "netmask" parameters' ) else: command = command + ['-net', net, 'netmask', netmask, 'gw', gw] try: check_call(command) except CalledProcessError as e: return command_error(e, command, logid) return command_success(logid=logid)
def manageobjs(filename, op): logid = mongolog(locals()) command = [op, filename] try: #Shrinks the output --------. # | # v check_call(command, stdout=DEVNULL) except CalledProcessError as e: return command_error(e, command, logid) return command_success(logid=logid)
def aptremove(pkgname, purge=False): logid = mongolog(locals(), {'dependencies': aptshow(pkgname, onlydependences=True)}) command = ['apt-get', 'purge' if purge else 'remove', '-y', pkgname] environ = { 'DEBIAN_FRONTEND': 'noninteractive', 'PATH': os.environ.get('PATH') } try: check_call(command, env=environ) #stdout=open(os.devnull, 'wb'), stderr=STDOUT) except CalledProcessError as e: return command_error(e, command, logid) return command_success(logid=logid)
def ifaceup(iface, address="", netmask="", broadcast=""): logid = mongolog(locals()) command = ['ifconfig', iface] if address: command.append(address) if netmask: command = command + ['netmask', netmask] if broadcast: command = command + ['broadcast', broadcast] command.append('up') try: check_output = check_call(command, stderr=PIPE, universal_newlines=True) except CalledProcessError as e: return command_error(e, command, logid) return command_success(logid=logid)
def getroutes(): command = ['route', '-n'] try: output = check_output(command, stderr=PIPE, universal_newlines=True).splitlines() except CalledProcessError as e: return command_error(e, command) #Removing useless header output.pop(0) #Storing useful header to use later header = output.pop(0).split() routes = list(map(lambda route: dict(zip(header, route.split())), output)) return command_success(data=routes)
def updateuserpass(user, password): #We literally cannot store password in mongo log, #hence here we are removing password from locals() localsvar = locals() del localsvar['password'] logid = mongolog(localsvar) try: command = ['echo', user + ':' + password] p1 = Popen(command, stdout=PIPE) command = ['/usr/sbin/chpasswd'] p2 = Popen(command, stdin=p1.stdout) p1.stdout.close() except CalledProcessError as e: return command_error(e, command, logid) return command_success(logid=logid)
def addusertogroups(user, *groups): #Logging operation to mongo first userinfo = getuser(user) if not userinfo['returncode'] is 0: return userinfo userinfo = userinfo['data'] logid = mongolog(locals(), userinfo) try: for group in groups: command = ['adduser', user, group] check_call(command) except CalledProcessError as e: return command_error(e, command, logid) #ObjectID of mongo return command_success(logid=logid)
def createalias(aliasname, address, netmask="", broadcast=""): #Turning alias name into main interface name iface = re.sub(':.*', '', aliasname) #Check wether "iface" is a real interface aliases = ifacestat(namesonly=True) if aliases['returncode'] is 0: if not iface in aliases['data']: return command_error(returncode=197, stderr="No interface found with such name: " + iface) else: return aliases return ifaceup(iface=aliasname, address=address, netmask=netmask, broadcast=broadcast)
def removeuser(user, removehome=False): userinfo = getuser(user) if userinfo['returncode'] is 0: userinfo = userinfo['data'] else: return userinfo logid = mongolog(locals(), userinfo) try: command = ['deluser', user] if removehome: command.append('--remove-home') check_output(command, stderr=PIPE, universal_newlines=True) except CalledProcessError as e: return command_error(e, command, logid) return command_success(logid=logid)
def manageapache(op): #Can only accept these parameters acceptedparams = ['stop', 'status', 'reload', 'restart'] if not any(op in param for param in acceptedparams): return command_error(returncode=-1, stderr='Bad parameter: ' + op) else: command = ['systemctl', op, 'apache2', '-q', '-n0', '--no-pager'] toreturn = None try: if op is "status": #Avoid to print journal (log) lines in output command.append('-n0') #We are using Popen here because check_output fails to return stdout and stderr on exit code != 0 toreturn = Popen( command, stdout=PIPE, universal_newlines=True).communicate()[0].splitlines() #Filtering useless lines linestomantain = ['loaded', 'active', 'memory', 'cpu'] toreturn = list( filter( lambda line: any(s in line.lower() for s in linestomantain), toreturn)) #Formatting output toreturn = dict( map(lambda line: line.lstrip().split(':', maxsplit=1), toreturn)) else: #Logging operation to MongoDB; in this specific case "toreturn" contains mongo logid toreturn = mongolog(locals()) check_call(command) except CalledProcessError: pass return command_success(data=toreturn)
def aptinstall(pkgname): logid = mongolog(locals(), {'dependencies': aptshow(pkgname, onlydependences=True)}) command = ['apt-get', 'install', '-y', pkgname] environ = { 'DEBIAN_FRONTEND': 'noninteractive', 'PATH': os.environ.get('PATH') } try: check_call( command, env=environ) #, stdout=open(os.devnull, 'wb'), stderr=STDOUT) except CalledProcessError: return command_error( returncode=14, stderr='Package installation error. Package name: "' + pkgname + '"', logid=logid) return command_success(logid=logid)
def removeuserfromgroups(user, *groups): #Logging operation to mongo first userinfo = getuser(user) if userinfo['returncode'] is 0: userinfo = userinfo['data'] else: return userinfo logid = mongolog(locals(), userinfo) try: for group in groups: command = ['gpasswd', '-d', user, group] check_call(command) # check_output(command, stderr=PIPE, universal_newlines=True) except CalledProcessError as e: return command_error(e, command, logid) #ObjectID of mongo return command_success(logid=logid)
def removerepofile(filename): result = filedel(externalreposdir + filename)['logid'] filedel( externalreposdir + filename + '.save') #Ignores errors if file not exists ignoring return dictionary logid = mongolog(locals()) repospath = '/etc/apt/sources.list.d/' try: os.remove(repospath + filename + '.list') os.remove(repospath + filename + '.list.save') except FileNotFoundError: return command_error(returncode=10, stderr='File to remove not found: "' + repospath + '"', logid=logid) if result['returncode'] is 0: return command_succes(logid=logid) else: return result
def getsysteminfo( getall=True, getproc=False, getcpu=False, getmem=False ): #Creating the tuple to return toreturn = () ##### KERNEL E ARCH ##### #uname -a #/etc/os-release ##### CPU ##### if getall or getcpu: #Reading cpu stat from /opt files with open('/proc/cpuinfo', 'r') as cpuorig: cpuraw = cpuorig.read().splitlines() #Removing duplicate lines by converting list() to set() cpuraw = set(cpuraw) #Removing empty lines cpuraw = list( filter( None, cpuraw ) ) #Removing useless lines linestoremove = ('flags', 'apicid', 'processor', 'core id', 'coreid') cpuraw = list( filter( lambda line: not any(s in line for s in linestoremove), cpuraw ) ) #Deleting all tabulation and spaces for each line of the cpuraw set cpuraw cpuraw = map( lambda line: re.sub('[\t| ]*:[\t| ]*', ':', line), cpuraw ) #We got three fields named "cpu Mhz", but to use them as dictionry keys #we need to rename them all cpuaf = list() i = 1 for line in cpuraw: #Adds an incremental number to the key if 'mhz' in line.lower(): cpuaf.append( re.sub('^.*:', 'core' + str(i) +' MHz:', line) ) i += 1 else: cpuaf.append( line ) #Buiding final dictionary cotaining cpu information in the right form cpu = dict() for line in cpuaf: line = line.split(':') cpu.update({ line[0]: line[1] }) #Adding cpu dict to the tuple to return toreturn = toreturn + (cpu,) ##### MEMORY ##### if getall or getmem: #Reading memory status from /opt files with open('/proc/meminfo', 'r') as memorig: memraw = memorig.read().splitlines() #Filling mem dict with memory information mem = dict() for line in memraw: line = re.sub(' ', '', line) #Removing spaces for each line line = line.split(':') #Splitting by colon mem.update({ line[0].lower() : line[1] }) #Appending the dictionary to a list to return toreturn = toreturn + (mem,) #### PROCESSES ##### if getall or getproc: #Reading processes status using top command command = ['top', '-b', '-n1'] try: procraw = check_output(command, stderr=PIPE, universal_newlines=True).splitlines() except CalledProcessError as e: return command_error( e, command ) #Removing headers from the output of top command i = 0 while 'PID' not in procraw[i]: i+=1 procraw = procraw[i:] proc = list(map( lambda line: line.split(), procraw )) toreturn = toreturn + (proc,) # |_____________________________________________________________________ Real Value # procraw = procraw[i:] # # #Getting header and splitting fields for use final dictionary keys # keys = procraw.pop(0).lstrip() # keys = keys.split() # # proc = list() # # for line in procraw: # line = procraw.pop(0).lstrip() #Removing initial spaces # line = line.split() #Splitting by spaces # proc.append( dict( zip(keys, line) ) ) #Creating a dictionary for each process and inserting into a list to return # # toreturn = toreturn + (proc,) #dict, dict, list return command_success( data=toreturn )