You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

159 lines
4.8 KiB
Python

"""
This program is designed to inspect an application environment
This program should only be run on unix friendly systems
"""
from __future__ import division
import os
import subprocess
from sets import Set
import re
class Analysis:
def __init__(self):
self.logs = []
pass
def post(self,object):
self.logs.append(object)
"""
This class is designed to analyze environment variables. Environment variables can either be folders, files or simple values
The class returns a quantifiable assessment of the environment variables (expected 100%)
"""
class Env(Analysis):
def __init__(self,values):
Analysis.__init__(self)
self.values = values
"""
This function evaluate the validity of an environment variable by returning a 1 or 0 (computable)
The function will use propositional logic (https://en.wikipedia.org/wiki/Propositional_calculus)
"""
def evaluate(self,id):
if id in os.environ :
#
# We can inspect to make sure the environment variable is not a path or filename.
# Using propositional logic we proceed as follows:
# - (p) We determine if the value is an folder or file name (using regex)
# - (q) In case of a file or folder we check for existance
# The final result is a conjuction of p and q
#
value = os.environ[id]
expressions = [os.sep,'(\\.\w+)$']
p = sum([ re.search(xchar,value) is not None for xchar in expressions])
q = os.path.exists(value)
return int(p and q)
else:
return 0
def composite (self):
r = [ self.evaluate(id) for id in self.values] ;
N = len(r)
n = sum(r)
return n/N
class Sandbox(Analysis):
def __init__(self,conf):
Analysis.__init__(self)
self.sandbox_path = conf['path']
self.requirements_path = conf['requirements']
def get_requirements (self):
f = open(self.requirements_path)
return [ name.replace('-',' ').replace('_',' ') for name in f.read().split('\n') if name != '']
"""
This function will return the modules installed in the sandbox (virtual environment)
"""
def get_sandbox_requirements(self):
cmd = ['freeze']
xchar = ''.join([os.sep]*2)
pip_vm = ''.join([self.sandbox_path,os.sep,'bin',os.sep,'pip']).replace(xchar,os.sep)
cmd = [pip_vm]+cmd
r = subprocess.check_output(cmd).split('\n')
return [row.replace('-',' ').replace('_',' ') for row in r if row.strip() != '']
def evaluate(self):
pass
"""
This function returns the ratio of existing modules relative to the ones expected
"""
def composite(self):
required_modules= self.get_requirements()
sandbox_modules = self.get_sandbox_requirements()
N = len(requirements)
n = len(Set(required_modules) - Set(sandbox_modules))
return n/N
"""
This class performs the analysis of a list of processes and determines
The class provides a quantifiable measure of how many processes it found over all
"""
class Processes(Analysis):
def __init__(self,names):
Analysis.__init__(self)
self.names = names
def evaluate(self,name):
cmd = "".join(['ps aux |grep -E "^ {0,}',name,'" |wc -l'])
handler = subprocess.Popen(cmd,shell=True,stdout=subprocess.PIPE)
return int(handler.communicate()[0].replace('\n','')) > 0
def composite(self):
r = [ self.evaluate(name) for name in self.names]
N = len(r)
n = sum(r)
return n/N
"""
This class returns an application's both memory and cpu usage
"""
class DetailProcess(Analysis):
def __init__(self,names):
self.names = names;
def evaluate(self,name) :
cmd = "ps -eo pmem,pcpu,vsize,comm|grep :app$"
handler = subprocess.Popen(cmd.replace(":app",name),shell=True,stdout=subprocess.PIPE)
ostream = handler.communicate()[0].split(' ')
return [float(value) for value in ostream if value.strip() not in ['',name]] +[name]
def composite(self):
#value = self.evaluate(self.name)
#row= {"memory_usage":value[0],"cpu_usage":value[1]}
#return row
ma = [self.evaluate(name) for name in self.names]
return [{"memory_usage":row[0],"cpu_usage":row[1],"memory_available":row[2]/1000,"label":row[3]} for row in ma]
"""
This class will require
"""
class QueueServer(Analysis):
def __init__(self,conf):
Analysis.__init__(self)
pass
def is_running(self):
p = Process(['rabbitmq-server'])
return p.composite()
def has_virtualhost(self,name):
return 0
def has_user(self,uid):
return 0
def composite(self):
if self.is_running() :
pass
else:
return [0,0,0]
"""
Normalization will be required for the data produced by this class
"""
class DatabaseServer(Analysis):
def __init__(self,conf):
Analysis.__init__(self)
pass
def has_table(self,name):
pass
def has_fields(self,table,fields):
pass
def has_data(self,table):
pass
"""
This function will return the number of test-cases of the last build.
The use of the returned number will have to be normalized if used in a dataset.
"""
#class TestCaseCount(Analysis):
#pass