moved linspector to bin and renamed lib

This commit is contained in:
Johannes Findeisen 2013-10-08 22:16:31 +02:00
commit b73d0abb2d
47 changed files with 24 additions and 161 deletions

View file

@ -1,28 +0,0 @@
"""
Backends can be a http service or xml-rpc service; let's say background threads providing an interface somewhere. They
should run as background threads.
Backends are absolutely no requirement for running Linspector.
Copyright (c) 2011-2013 "Johannes Findeisen and Rafael Timmerberg"
This file is part of Linspector (http://linspector.org).
Linspector is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
"""
class Backend():
def __init__(self, **kwargs):
return

View file

@ -1,30 +0,0 @@
"""
A HTTPS backend to the current Linspector instance.
A Webserver listening for requests to give information about the internal state of linspector.
(maybe providing a JSON API to the instance too...)
Copyright (c) 2011-2013 "Johannes Findeisen and Rafael Timmerberg"
This file is part of Linspector (http://linspector.org).
Linspector is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
"""
from lib.backends.backend import Backend
class HttpsBackend(Backend):
def __init__(self, **kwargs):
return

View file

@ -1,27 +0,0 @@
"""
A JSON-RPC backend using HTTP.
Copyright (c) 2011-2013 "Johannes Findeisen and Rafael Timmerberg"
This file is part of Linspector (http://linspector.org).
Linspector is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
"""
from lib.backends.backend import Backend
class JsonrpcBackend(Backend):
def __init__(self, **kwargs):
return

View file

@ -1,30 +0,0 @@
"""
The Linspector XMPP Frontend...
Just for the fun in it... Linspector connects to a XMPP Server and are accepting commands from special users and can
give back information. The Linspector admin client will then be any Jabber Client... ;)
Copyright (c) 2011-2013 "Johannes Findeisen and Rafael Timmerberg"
This file is part of Linspector (http://linspector.org).
Linspector is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
"""
from lib.backends.backend import Backend
class XmmpBackend(Backend):
def __init__(self, **kwargs):
pass

View file

View file

@ -1,73 +0,0 @@
"""
The LinspectorConfig class.
Copyright (c) 2011-2013 "Johannes Findeisen and Rafael Timmerberg"
This file is part of Linspector (http://linspector.org).
Linspector is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
"""
class LinspectorConfig(object):
def __init__(self):
self._layouts = None
self._hostgroups = None
self._members = None
self._periods = None
def set_hostgroups(self, hostgroups):
self._hostgroups = hostgroups
def get_hostgroups(self):
return self._hostgroups
def set_layouts(self, layouts):
self._layouts = layouts
def get_layouts(self):
return self._layouts
def set_members(self, members):
self._members = members
def get_members(self):
return self._members
def set_periods(self, periods):
self._periods = periods
def get_periods(self):
return self._periods
def get_enabled_layouts(self):
return [l for l in self.get_layouts() if l.is_enabled()]
def _get_by_name(self, items, name):
for itm in items:
if itm.get_name() == name:
return itm
return None
def get_hostgroup_by_name(self, name):
return self._get_by_name(self.get_hostgroups(), name)
def get_layout_by_name(self, name):
return self._get_by_name(self.get_layouts(), name)
def get_member_by_name(self, name):
return self._get_by_name(self.get_members(), name)
def get_period_by_name(self, name):
return self._get_by_name(self.get_periods(), name)

View file

@ -1,163 +0,0 @@
"""
Copyright (c) 2011-2013 "Johannes Findeisen and Rafael Timmerberg"
This file is part of Linspector (http://linspector.org).
Linspector is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
"""
class HostGroupException(Exception):
def __init__(self, msg):
self.msg = msg
def __str__(self):
return repr(self.msg)
class HostGroupMissingArgumentException(HostGroupException):
def __init__(self, missingArgument, hostgroupName):
super(HostGroupMissingArgumentException, self).__init__("no " + missingArgument + " defined for Hostgroup " + hostgroupName)
class HostGroup(object):
def __init__(self, name, **kwargs):
self.name = name
tmp = "members"
self.members = []
if not tmp in kwargs:
raise HostGroupMissingArgumentException(tmp, name)
self.add_members(kwargs[tmp])
tmp = "hosts"
self.hosts = []
if not tmp in kwargs:
raise HostGroupMissingArgumentException(tmp, name)
self.add_hosts(kwargs[tmp])
tmp = "services"
self.__services = []
if not tmp in kwargs:
raise HostGroupMissingArgumentException(tmp, name)
self.add_services(kwargs[tmp])
self.parents = []
tmp = "parents"
if tmp in kwargs:
self.add_parents(kwargs[tmp])
tmp = "processors"
self.processors = []
if tmp in kwargs:
self.add_processors(kwargs[tmp])
def _to_config_dict(self, configDict):
me = {}
me["members"] = [member.nameid for member in self.get_members()]
me["hosts"] = self.hosts
me["parents"] = [hg.get_name() for hg in self.get_parents()]
#TODO implement delegation
#me["services"] = [service._to_config_dict(configDict) for service in self.get_services()]
#me["processors"] = [processor._to_config_dict(configDict) for processor in self.get_processors()]
configDict["hostgroups"][self.get_name()] = me
def __add_internal(self, l, item):
if isinstance(item, list):
l.extend(item)
else:
l.append(item)
def add_members(self, member):
self.__add_internal(self.get_members(), member)
def add_hosts(self, host):
self.__add_internal(self.get_hosts(), host)
def add_processors(self, processor):
self.__add_internal(self.get_processors(), processor)
def add_parents(self, parent):
self.__add_internal(self.get_parents(), parent)
def add_services(self, services):
self.__add_internal(self.get_services(), services)
def get_parents(self):
return self.parents
def get_processors(self):
return self.processors
def get_services(self):
return self.__services
def get_hosts(self):
return self.hosts
def get_name(self):
return self.name
def get_members(self):
return self.members
def __str__(self):
if True:
return str(self.__dict__)
ret = "HostGroup: " + self.name + "\n"
ret += "members: {\n"
for itm in self.members:
ret += str(itm) + "\n"
ret += "}\n"
ret += "hosts: {\n"
for itm in self.hosts:
ret += str(itm) + "\n"
ret += "}\n"
ret += "services: {\n"
for itm in self._services:
ret += str(itm) + "\n"
ret += "}\n"
return ret
class HostGroupService:
def __init__(self, services, periods):
self.services = services
self.periods = periods
def __str__(self):
return "HostgroupService { " + str([str(s) for s in self.services]) + ", " + str([p.name for p in self.periods]) + "}"
def parseHostGroupList(hostgroups, hosts, members, periods, services, log):
parsedHostGroups = []
for hgname, hgValues in hostgroups.items():
hostGroup = HostGroup(hgname)
hostGroup.members = [m for m in members if m.nameid in hgValues['members']]
hostGroup.hosts = [h for h in hosts if h.name in hgValues['hosts']]
hostGroup.threshold = hgValues['threshold']
if 'parent' in hgValues:
hostGroup.parent = hgValues['parent']
hostGroup.services = []
for serviceName, servicePeriods in hgValues['services'].items():
services = []
for host in hosts:
service = host.getHostServiceByName(serviceName)
if service is not None:
services.append(service)
else:
log.w("could not find HostService(" + str(serviceName) + ") for host " + host.name)
hostGroupPeriods = [p for p in periods if p.name in servicePeriods]
hostGroup.services.append(HostGroupService(services, hostGroupPeriods))
parsedHostGroups.append(hostGroup)
return parsedHostGroups

View file

@ -1,96 +0,0 @@
"""
Copyright (c) 2011-2013 "Johannes Findeisen and Rafael Timmerberg"
This file is part of Linspector (http://linspector.org).
Linspector is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
"""
class LayoutException(Exception):
def __init__(self, msg):
self.msg = msg
def __str__(self):
return repr(self.msg)
class Layout(object):
def __init__(self, name, enabled=False, hostgroups=None):
self._name = name
self._enabled = enabled
if hostgroups is None or len(hostgroups) <= 0:
raise LayoutException("Layout: " + self._name + " without hostgroups is useless")
else:
self._hostgroups = hostgroups
def _to_config_dict(self, configDict):
me = {}
me["hostgroups"] = [hg.name for hg in self.get_hostgroups()]
me["enabled"] = self.is_enabled()
configDict["layouts"][self.get_name()] = me
for hostgroup in self.get_hostgroups():
hostgroup._to_config_dict(configDict)
def get_name(self):
return self._name
def is_enabled(self):
return self._enabled
def get_hostgroups(self):
return self._hostgroups
def __str__(self):
ret = "Layout: 'Name:" + str(self.name) + "', 'Enabled: " + str(self.enabled) + " "
for group in self.hostgroups:
ret += str(group)
return ret
class LayoutList:
def __init__(self, layouts, hostgroups):
self.layouts = []
self.dict = layouts
self.plugins = []
for k, v in layouts.items():
if k in ("plugins", "Plugins"):
self.plugins = v
continue
else:
l = Layout(k)
for k1, v1 in v.items():
if k1 in ("enabled", "Enabled"):
l.enabled = v1
elif k1 in ("hostgroups", "Hostgroups"):
l.hostgroups = []
for group in v1:
h = None
for hostg in hostgroups:
if hostg.name == group:
h = hostg
break
if h is not None:
l.hostgroups.append(h)
else:
pass
self.layouts.append(l)
def __str__(self):
ret = ""
ret += "Plugins: " + str(self.plugins) + "\n"
for layout in self.layouts:
ret += str(layout) + "\n"
return ret

View file

@ -1,77 +0,0 @@
"""
Copyright (c) 2011-2013 "Johannes Findeisen and Rafael Timmerberg"
This file is part of Linspector (http://linspector.org).
Linspector is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
"""
import re
class Member:
def __init__(self, id, name="", comment="", tasks=None):
self.id = id
self.name = name
self.tasks = []
self.add_task(tasks)
self.comment = comment
def get_id(self):
return self.id
def add_task(self, task):
if task is None:
return
if isinstance(task, list):
self.tasks.extend(task)
else:
self.tasks.append(task)
def get_tasks(self):
return self.tasks
def __str__(self):
ret = "Member Id: " + self.nameid + " Name: " + self.name + " Filters: " + str(self.phone)
for f in self.filters:
ret += str(f)
return ret
class MemberFilter:
def __init__(self, filter, Value):
self.filter = filter
self.value = Value
def __str__(self):
return "Filter:" + str(self.filter) + " Value:" + self.value
def parseMemberList(members, filters, log):
parsedMembers = [Member(nameid, **values) for nameid, values in members.items()]
for member in parsedMembers:
mFilter = []
for filtername, replacement in member.filters.items():
found = False
for filt in filters:
if filt.name != filtername:
continue
found = True
memberFilter = filt.clone()
memberFilter.command = re.sub('@member', replacement, filt.command)
mFilter.append(memberFilter)
if not found:
log.w("filter: " + filtername + " is not defined in member " + member.name)
member.filters = mFilter
return parsedMembers

View file

@ -1,286 +0,0 @@
"""
Copyright (c) 2011-2013 "Johannes Findeisen and Rafael Timmerberg"
This file is part of Linspector (http://linspector.org).
Linspector is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
"""
from os.path import isfile
from os.path import join
import json
import imp
from layouts import Layout
from hostgroups import HostGroup
from members import Member
from config import LinspectorConfig
from periods import CronPeriod, DatePeriod, IntervalPeriod
from lib.services.service import Service
from lib.processors.processor import Processor
from lib.parsers.parser import Parser
from lib.tasks.task import Task
MOD_SERVICES = "services"
MOD_PROCESSORS = "processors"
MOD_PARSERS = "parsers"
MOD_TASKS = "tasks"
KEY_LAYOUTS = "layouts"
KEY_HOSTGROUPS = "hostgroups"
KEY_MEMBERS = "members"
KEY_PERIODS = "periods"
KEY_CORE = "core"
class ConfigurationException(Exception):
def __init__(self, msg, log):
log.e(msg)
self.msg = msg
def __str__(self):
return repr(self.msg)
class ConfigParser:
def __init__(self, log):
"""
initializes a new ConfigParser Object
:param log: pre configured logger Object to post messages while parsing"
"""
self.log = log
self.hostgroups = {}
self.members = {}
self.periods = {}
self.layouts = {}
self._loadedMods = {MOD_SERVICES: {}, MOD_PROCESSORS: {}, MOD_TASKS: {}, MOD_PARSERS: {}}
def _create_new_config_dict(self):
return {"members": {}, "periods": {}, "hostgroups": {}, "layouts": {}, "core": {}}
def create_config(self, config):
configDict = self._create_new_config_dict()
for layout in config.get_layouts():
layout._to_config_dict(configDict)
def _read_json_config(self, configFilename):
"""
reads the config File and returns a dictionary, while lowering the first keys
:param configFilename: the path under which the configuration file should be found
"""
if not isfile(configFilename):
msg = "config file not found at " + str(configFilename)
raise ConfigurationException(msg, self.log)
self.configFilename = configFilename
with open(configFilename) as cfgFile:
config = cfgFile.read()
self.log.info("reading Config: " + configFilename)
return json.loads(config)
def _create_raw_Object(self, jsonDict, msgName, creator):
"""
creates an Main object from the configuration, but just parses raw data and hands it to the object
:param jsonDict: the configuration file part as dict
:param msgName: name of object for error message
:param creator: function pointer which is taking two arguments: identifier of the object and arguments.
:should return an object
:return: a list of objects returned by creator
"""
items = []
for key, val in jsonDict.items():
try:
item = creator(key, val)
items.append(item)
except Exception:
self.log.warning("ignoring " + msgName + ": " + key + "! reason:")
self.log.warning(str(Exception))
return items
def _load_module(self, clazz, modPart):
"""
imports and caches a module.
:param clazz: the filename of the module (i.e email, ping...)
:param modPart: the folder of the module. (i.e services, parsers...)
:return: the imported/cached module, or throws an error if it couldn't find it
"""
mods = self._loadedMods[modPart]
if clazz in mods:
return mods[clazz]
else:
#mod = __import__(clazz)
p = join("lib", modPart, clazz + ".py")
mod = imp.load_source(clazz, p)
mods[clazz] = mod
return mod
def replace_with_import(self, objList, modPart, items_func, class_check):
"""
replaces configuration dicts with their objects by importing and creating it in the first step.
In the second step the original list of json config dicts gets replaced by the loaded objects
:param objList: the list of objects which is iterated on
:param modPart: the folder from the module (i.e tasks, parsers)
:param items_func: function to get a pointer on the list of json-config-objects to replace. Takes one argument and
should return a list of
:param class_check: currently unsupported
"""
for obj in objList:
repl = []
items = items_func(obj)
for clazzItem in items:
try:
clazz = clazzItem["class"]
mod = self._load_module(clazz, modPart)
item = mod.create(clazzItem)
if class_check(item):
repl.append(item)
else:
self.log.warning("Ignoring class " + clazzItem["class"] + "! It does not pass the class check!")
except ImportError, err:
self.log.warning("Could not import " + clazz + ": " + str(clazzItem) + "! reason")
self.log.warning(str(err))
except KeyError, k:
self.log.warning("Key " + str(k) + " not in classItem " + str(clazzItem))
except Exception, e:
self.log.warning("Error while replacing class ( " + clazz + " ): " + str(e))
del items[:]
items.extend(repl)
def replace_pointer(self, objectList, replObjectList, id_list_func, id_get_func):
"""
replaces objects from the config by ids.
:param objectList: the list of objects to be iterated on
:param replObjectList: the list of objects to replace
:param id_list_func: function taking one argument as object and should return a list of config ids to replace
:param id_get_func: function taking one config-object as argument and should return the config id to compare
"""
for obj in objectList:
replacements = []
idList = id_list_func(obj)
for id in idList:
repl = [o for o in replObjectList if id == id_get_func(o)]
if len(repl) == 1:
replacements.append(repl[0])
del idList[:]
idList.extend(replacements)
def parse_config(self, configFilename):
pass
def parsePeriodList(name, values):
if "date" in values:
return DatePeriod(name, **values)
comp = ["weeks", "days", "hours", "minutes", "seconds", "start_date"]
if len([i for i in comp if i in values]) > 0:
return IntervalPeriod(name, **values)
comp = ["year", "month", "day", "week", "day_of_week", "hour", "minute", "second"]
if len([i for i in comp if i in values]) > 0 :
return CronPeriod(name, **values)
else:
raise ConfigurationException("could not determine correct Period(" + repr(values)+").")
class FullConfigParser(ConfigParser):
def parse_config(self, configFilename):
"""
parses the json configuration and returns a list of layouts,
which contains all necessary information of the config file.
parses the full config
Parsing will be done in 3 steps:
1. get raw Config Objects by just passing the values defined inside the config
2. replace references by objects, import services, tasks, parsers and processors
3. do sanity checks
:param configFilename: the configuration file to parse
"""
self.jsonDict = self._read_json_config(configFilename)
# first step
creator = lambda name, values: Layout(name,**values)
layouts = self._create_raw_Object(self.jsonDict[KEY_LAYOUTS], "Layout", creator)
creator = lambda name, values: Member(name, **values)
members = self._create_raw_Object(self.jsonDict[KEY_MEMBERS], "Member", creator)
creator = lambda name, values: HostGroup(name, **values)
self.hostgroups = self._create_raw_Object(self.jsonDict[KEY_HOSTGROUPS], "Hostgroup", creator)
creator = parsePeriodList
periods = self._create_raw_Object(self.jsonDict[KEY_PERIODS], "Period", creator)
#2. import and replace
items_func = lambda hostgroup: hostgroup.get_services()
class_check = lambda service: isinstance(service, Service)
self.replace_with_import(self.hostgroups, MOD_SERVICES, items_func, class_check)
items_func = lambda hostgroup: hostgroup.get_processors()
class_check = lambda processor: isinstance(processor, Processor)
self.replace_with_import(self.hostgroups, MOD_PROCESSORS, items_func, class_check)
items_func = lambda member: member.get_tasks()
class_check = lambda task: isinstance(task, Task)
self.replace_with_import(members, MOD_TASKS, items_func, class_check)
services = []
for hg in self.hostgroups:
services.extend(hg.get_services())
items_func = lambda service: service.get_parser()
class_check = lambda parser: isinstance(parser, Parser)
self.replace_with_import(services, MOD_PARSERS, items_func, class_check)
#replace object pointer
id_list_func = lambda hostgroup: hostgroup.get_members()
id_get_func = lambda member: member.get_id()
self.replace_pointer(self.hostgroups, members, id_list_func, id_get_func)
id_list_func = lambda service: service.get_periods()
id_get_func = lambda period: period.get_name()
self.replace_pointer(services, periods, id_list_func, id_get_func)
id_list_func = lambda layout: layout.get_hostgroups()
id_get_func = lambda hostgroup: hostgroup.get_name()
self.replace_pointer(layouts, self.hostgroups, id_list_func, id_get_func)
linConf = LinspectorConfig()
linConf.set_layouts(layouts)
linConf.set_hostgroups(self.hostgroups)
linConf.set_members(members)
linConf.set_periods(periods)
for hg in self.hostgroups:
for service in hg.get_services():
service.set_hostgroup(hg)
core = None
if "core" in self.jsonDict:
core = self.jsonDict["core"]
return linConf, core

View file

@ -1,93 +0,0 @@
"""
Copyright (c) 2011-2013 "Johannes Findeisen and Rafael Timmerberg"
This file is part of Linspector (http://linspector.org).
Linspector is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
"""
class Period(object):
def __init__(self, name):
self.name = name
def get_name(self):
return self.name
def createJob(self, scheduler, jobInfo, func):
pass
class IntervalPeriod(Period):
def __init__(self, name="", weeks=0, days=0, hours=0, minutes=0, seconds=0, start_date=None, comment=None):
super(IntervalPeriod, self).__init__(name)
self.days = days # number of days to wait
self.weeks = weeks # number of weeks to wait
self.hours = hours # number of hours to wait
self.minutes = minutes # number of minutes to wait
self.seconds = seconds # number of seconds to wait
self.start_date = start_date # when to first execute
self.comment = comment # comment
def createJob(self, scheduler, jobInfo, func):
return scheduler.add_interval_job(func, weeks=self.weeks, hours=self.hours, minutes=self.minutes,
seconds=self.seconds, start_date=self.start_date, args=[jobInfo])
def __str__(self):
ret = "IntervalPeriod(Name: " + self.name + ")"
return ret
class CronPeriod(Period):
def __init__(self, name="", year="*", month="*", day="*", week="*", day_of_week="*", hour="*", minute="*",
second="0", start_date=None, comment=None):
super(CronPeriod, self).__init__(name)
self.year = year # 4-digit year number
self.month = month # month number (1-12)
self.day = day # day of the month (1-31)
self.week = week # ISO week number (1-53)
self.day_of_week = day_of_week # number or name of weekday (0-6 or mon,tue,wed,thu,fri,sat,sun)
self.hour = hour # hour (0-23)
self.minute = minute # minute (0-59)
self.second = second # second (0-59)
self.start_date = start_date
self.comment = comment
def __str__(self):
ret = "CronPeriod(Name: " + self.name + ")"
return ret
def createJob(self, scheduler, jobInfo, func):
return scheduler.add_cron_job(func, year=self.year, month=self.month, day=self.day, week=self.week,
day_of_week=self.day_of_week, hour=self.hour, minute=self.minute,
second=self.second, start_date=self.start_date, args=[jobInfo])
class DatePeriod(Period):
def __init__(self, name, date, comment=None):
super(DatePeriod, self).__init__(name)
self.date = date
self.comment = comment
def __str__(self):
ret = "DatePeriod(Name: " + self.name + ", " + str(self.date) + ")"
return ret
def createJob(self, scheduler, jobInfo, func):
try:
return scheduler.add_date_job(func=func, date=self.date, args=[jobInfo])
except Exception, e:
return None

View file

View file

@ -1,70 +0,0 @@
"""
Copyright (c) 2011-2013 "Johannes Findeisen and Rafael Timmerberg"
This file is part of Linspector (http://linspector.org).
Linspector is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
"""
import subprocess as sp
from subprocess import Popen
from subprocess import CalledProcessError
from datetime import datetime as dt
#TODO: Move this to shell.py service file. this definitely is shell execution. (hanez)
class Command:
def __init__(self, command, log):
self.command = command
self.log = log
self.output = None
self.error = None
self.retcode = 0
self.commandStart = 0
def __str__(self):
return self.command
def call(self):
# self.commandStart = dt.now()
# "called at: "
# process = sp.Popen(stdout=PIPE, *popenargs, **kwargs)
# self.output, self.error = process.communicate()
# self.retcode = process.poll()
try:
self.commandStart = dt.now()
self.log.info("calling command " + str(self.command) + " at " + str(self.commandStart))
#self.output=sp.check_output(self.command.split())
process = Popen(self.command, stdout=sp.PIPE, stderr=sp.PIPE, shell=True)
self.output, self.error = process.communicate()
self.log.debug(str(self.output))
self.log.debug(str(self.error))
self.retcode = process.poll()
except CalledProcessError:
self.error = CalledProcessError.output
self.retcode = CalledProcessError.returncode
def getOutput(self):
return self.output
def getError(self):
return self.error
def getAllOutput(self):
return str(self.output) + str(self.error) + str(self.retcode)
def getReturnCode(self):
return self.retcode

View file

@ -1,153 +0,0 @@
"""
Copyright (c) 2011-2013 "Johannes Findeisen and Rafael Timmerberg"
This file is part of Linspector (http://linspector.org).
Linspector is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
"""
import sys
import os
import time
import atexit
from signal import SIGTERM
class Daemon:
"""
A generic daemon class.
Usage: subclass the Daemon class and override the run() method
"""
def __init__(self, pidfile, stdin='/dev/null', stdout='/dev/null', stderr='/dev/null'):
self.stdin = stdin
self.stdout = stdout
self.stderr = stderr
self.pidfile = pidfile
def daemonize(self):
"""
do the UNIX double-fork magic, see Stevens' "Advanced
Programming in the UNIX Environment" for details (ISBN 0201563177)
http://www.erlenstar.demon.co.uk/unix/faq_2.html#SEC16
"""
try:
pid = os.fork()
if pid > 0:
# exit first parent
sys.exit(0)
except OSError, e:
sys.stderr.write("fork #1 failed: %d (%s)\n" % (e.errno, e.strerror))
sys.exit(1)
# decouple from parent environment
os.chdir("/")
os.setsid()
os.umask(0)
# do second fork
try:
pid = os.fork()
if pid > 0:
# exit from second parent
sys.exit(0)
except OSError, e:
sys.stderr.write("fork #2 failed: %d (%s)\n" % (e.errno, e.strerror))
sys.exit(1)
# redirect standard file descriptors
sys.stdout.flush()
sys.stderr.flush()
si = file(self.stdin, 'r')
so = file(self.stdout, 'a+')
se = file(self.stderr, 'a+', 0)
os.dup2(si.fileno(), sys.stdin.fileno())
os.dup2(so.fileno(), sys.stdout.fileno())
os.dup2(se.fileno(), sys.stderr.fileno())
# write pidfile
atexit.register(self.delpid)
pid = str(os.getpid())
file(self.pidfile, 'w+').write("%s\n" % pid)
def delpid(self):
os.remove(self.pidfile)
def start(self):
"""
Start the daemon
"""
# Check for a pidfile to see if the daemon already runs
try:
pf = file(self.pidfile, 'r')
pid = int(pf.read().strip())
pf.close()
except IOError:
pid = None
if pid:
message = "pidfile %s already exist. daemon already running?\n"
sys.stderr.write(message % self.pidfile)
sys.exit(1)
# Start the daemon
self.daemonize()
self.run()
def stop(self):
"""
Stop the daemon
"""
# Get the pid from the pidfile
try:
pf = file(self.pidfile, 'r')
pid = int(pf.read().strip())
pf.close()
except IOError:
pid = None
if not pid:
message = "pidfile %s does not exist. daemon not running?\n"
sys.stderr.write(message % self.pidfile)
return # not an error in a restart
# Try killing the daemon process
try:
while 1:
os.kill(pid, SIGTERM)
time.sleep(0.1)
except OSError, err:
err = str(err)
if err.find("No such process") > 0:
if os.path.exists(self.pidfile):
os.remove(self.pidfile)
else:
print str(err)
sys.exit(1)
def restart(self):
"""
Restart the daemon
"""
self.stop()
self.start()
def run(self):
"""
You should override this method when you subclass Daemon.
It will be called after the process has been
daemonized by start() or restart().
"""

View file

@ -1,25 +0,0 @@
"""
The interface class should contain all stuff for frontend/backend communication to the Linspector core.
Copyright (c) 2011-2013 "Johannes Findeisen and Rafael Timmerberg"
This file is part of Linspector (http://linspector.org).
Linspector is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
"""
class Interface():
def __init__(self):
pass

View file

@ -1,122 +0,0 @@
"""
This is what job_function needs as parameter for each job to successfully
execute.
Copyright (c) 2011-2013 "Johannes Findeisen and Rafael Timmerberg"
This file is part of Linspector (http://linspector.org).
Linspector is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
"""
from datetime import datetime
def generateId():
i = 0
while True:
yield i
i += 1
class Job:
def __init__(self, service, host, members, processors, core):
self.service = service
self.host = host
self.members = members
self.processors = processors
self.core = core
self.jobInfos = []
self.jobThreshold = 0
def __str__(self):
return str(self.__dict__)
def set_logger(self, log):
self.log = log
def set_job(self, job):
self.job = job
def handle_threshold(self, jobInfo, serviceThreshold, executionSucessful):
if executionSucessful:
if self.jobThreshold > 0:
self.jobThreshold -= 1
else:
self.jobThreshold += 1
if self.jobThreshold >= serviceThreshold:
self.log.debug("Threshold reached!")
self.handle_alarm(jobInfo, self.jobThreshold - serviceThreshold)
def handle_alarm(self, jobInfo, thresholdOffset):
for member in self.service.get_hostgroup().get_members():
#TODO: Put Tasks in a run queue and execute them in a background thread. FIFO! Reduces delay in core.
for task in member.get_tasks():
task.execute(jobInfo.get_message(), self.core)
def handle_call(self):
self.log.debug("handle call")
self.log.debug(self.service)
try:
jobInfo = JobInfo(self.host, self.service)
self.service._execute(jobInfo)
jobInfo.set_execution_end()
self.handle_threshold(jobInfo, self.service.get_threshold(), jobInfo.was_execution_successful())
self.log.debug("Code: " + str(jobInfo.get_errorcode()) + ", Message: " + str(jobInfo.get_message()))
self.jobInfos.append(jobInfo)
except Exception, e:
self.log.debug(e)
class JobInfo(object):
def __init__(self, host, service):
self.id = generateId()
self.host = host
self.service = service
self.executionBegin = datetime.now()
self._errorcode = -1
self._message = None
self._executionSuccess = False
def get_host(self):
return self.host
def set_result(self, result):
self.result = result
def set_execution_end(self):
self.executionEnd = datetime.now()
def set_execution_successful(self, successful):
self._executionSuccess = successful
def was_execution_successful(self):
return self._executionSuccess
def set_message(self, msg):
self._message = msg
def get_message(self):
return self._message
def set_errorcode(self, errcode):
self._errorcode = errcode
def get_errorcode(self):
return self._errorcode

View file

@ -1,42 +0,0 @@
"""
Copyright (c) 2011-2013 "Johannes Findeisen and Rafael Timmerberg"
This file is part of Linspector (http://linspector.org).
Linspector is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
"""
from ..core import logger
from ..core.daemon import Daemon
"""
TODO: Think about, that daemonizing this software is not our goal but when we want to that, this needs a rewrite and
should maybe move over to the daemon frontend. daemon.py will remain the the base for this and should stay in lib/core .
Since a daemon it normally not a frontend we should think about how to handle this. When daemonizing a real frontend
like "Lish" will make no sense but a frontend like "https" or "xmpp" could be useful anyway...
"""
class LinspectorDaemon(Daemon):
def run(self):
while True:
try:
a = 2
logger.writeLogToFile(_logfile, "Running!")
print "running!"
except Exception as err:
#logger.writeLogToFile(_logfile, str(err))
print "failed"
sys.exit(1)
time.sleep(1)

View file

@ -1,77 +0,0 @@
"""
Copyright (c) 2011-2013 "Johannes Findeisen and Rafael Timmerberg"
This file is part of Linspector (http://linspector.org).
Linspector is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
"""
import logging
import logging.handlers
import os
import os.path as path
class Logger():
"""
Logger class that prints its messages and keeps them also inside a logfile
"""
def __init__(self, logfile="./linspector.log", logLevel=logging.DEBUG, logfileLevel=logging.DEBUG):
"""
initializes a new Logger object.
:param logLevel: the LoggingLevel from the console output (DEBUG default)
:param logfile: the file where to log. Logs are rotated by default.
:param logfileLevel: the LoggingLevel for the file Logger. (DEBUG default)
"""
logfile = path.expanduser(logfile)
if not path.exists(path.dirname(logfile)):
os.makedirs(path.dirname(logfile))
self.log = logging.getLogger("LinspectorLogger")
self.log.setLevel(logging.DEBUG)
consoleHandler = logging.StreamHandler()
consoleHandler.setLevel(logLevel)
fileHandler = logging.handlers.RotatingFileHandler(logfile, maxBytes=1024000, backupCount=4)
fileHandler.setLevel(logfileLevel)
consoleFormatter = logging.Formatter('[%(levelname)s]: %(message)s')
fileFormatter = logging.Formatter('%(asctime)s [%(levelname)s]: %(message)s')
consoleHandler.setFormatter(consoleFormatter)
fileHandler.setFormatter(fileFormatter)
self.log.addHandler(consoleHandler)
self.log.addHandler(fileHandler)
def d(self, message):
self.log.debug(message)
def i(self, message):
self.log.info(message)
def w(self, message):
self.log.warn(message)
def e(self, message):
self.log.error(message)
def c(self, message):
self.log.critical(message)
def close(self):
logging.shutdown()

View file

@ -1,25 +0,0 @@
"""
Copyright (c) 2011-2013 "Johannes Findeisen and Rafael Timmerberg"
This file is part of Linspector (http://linspector.org).
Linspector is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
"""
from apscheduler.scheduler import Scheduler
class Scheduler(Scheduler):
def test(self):
pass

View file

@ -1,28 +0,0 @@
"""
Frontends are GUI interfaces to Linspector. This could be a shell or other terminal based GUI.
Frontends are absolutely no requirement for running Linspector. If no frontend is selected Linspector will just log
stuff to stdout.
Copyright (c) 2011-2013 "Johannes Findeisen and Rafael Timmerberg"
This file is part of Linspector (http://linspector.org).
Linspector is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
"""
class Frontend():
def __init__(self, **kwargs):
return

View file

@ -1,197 +0,0 @@
"""
Lish is the Linspector Interactive Shell...
This will become a commandline interface to Linspector. Think of a network switch or router like those from Cisco.
Copyright (c) 2011-2013 "Johannes Findeisen and Rafael Timmerberg"
This file is part of Linspector (http://linspector.org).
Linspector is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
"""
from lib.frontends.frontend import Frontend
import os
from shlex import split as shsplit
from cmd import Cmd
__version__ = "0.1"
class LishFrontend(Frontend):
def __init__(self, **kwargs):
#print(kwargs)
#self.jobs = kwargs["jobs"]
commander = LishCommander(kwargs)
run = True
while run:
try:
commander.cmdloop("Lish - Linspector interactive shell (" + __version__ + ")")
except KeyboardInterrupt, ki:
run = False
except Exception, err:
print(err)
if commander.can_exit():
run = False
class CommandBase(Cmd, object):
def __init__(self):
super(CommandBase, self).__init__()
self._needs_update = False
def get_completion(self, args, text, showOnZeroText=True):
if len(text) == 0 and showOnZeroText:
return args
else:
return [x for x in args if x.startswith(text)]
class Exit(CommandBase, object):
def __init__(self):
super(Exit, self).__init__()
self.set_can_exit(False)
def set_can_exit(self, canExit=True):
self._canExit = canExit
def can_exit(self):
return self._canExit
def do_exit(self, text):
self.set_can_exit()
return self.can_exit()
def help_exit(self):
print("exits linspector")
do_EOF = do_exit
help_EOF = help_exit
class LogCommander(Cmd, object):
def do_log(self, text):
print("executed %s" % text)
def help_log(self):
print("manage logging")
class ShellCommander(CommandBase, object):
def do_shell(self, text):
os.system(text)
def help_shell(self):
print("execute any shell command. Can also be achieved by a '!' prefix")
def complete_shell(self, text, line, begidx, endidx):
try:
PATH = os.environ['PATH'].split(os.pathsep)
bins = []
for p in PATH:
bins.extend(os.listdir(p))
return self.get_completion(bins, text, False)
except:
pass
class HostgroupCommander(Exit, object):
def __init__(self, hostgroup):
super(HostgroupCommander, self).__init__()
self.prompt = "<HG:%s>" % hostgroup.get_name()
self._hostgroup = hostgroup
def do_member(self, text):
print("dear maintainer, ")
print("I typed '%s', and would appreciate, if you could stay away from outside to implement it" % text)
print("must be kidding me!!!")
return True
def help_member(self):
print("gives you control over a member of the hostgroup")
class LishCommander(Exit, ShellCommander, LogCommander):
def __init__(self, kwargs):
super(LishCommander, self).__init__()
self.prompt = "<Lish>: "
self._linConf = kwargs["linspectorConfig"]
self._jobs = kwargs["jobs"]
self._scheduler = kwargs["scheduler"]
self._hostgroupArgs = ["list", "select"]
def do_hostgroup(self, text):
args = shsplit(text)
if args[0] == "list":
print("current active Hostgroups:\n")
for l in self._linConf.get_enabled_layouts():
print l.get_name()
space = 4 * " "
for hg in l.get_hostgroups():
print space + hg.get_name()
print 3 * "\n"
elif args[0] == "select":
if len(args) < 2 or len(args[1]) == 0:
print("must select an hostgroup")
else:
hgName = args[1]
hg = self._linConf.get_hostgroup_by_name(hgName)
if hg is None:
print("unknown hostgroup %s! type hostgroup list to get a list of hostgroups" % hgName)
else:
try:
hgCommander = HostgroupCommander(hg)
hgCommander.cmdloop("Entering Hostmode of " + hgName + ":\n")
except KeyboardInterrupt, ke:
pass
def do_python(self, text):
exec text
def do_jobs(self, text):
if text == "list":
for job in self._scheduler.get_jobs():
print job
def help_jobs(self):
print "Job helper functions"
def help_python(self):
print '''
executes python using 'exec'.
'''
def help_hostgroup(self):
print '''
usage:
hostgroup list
prints a list of all hostgroups
hostgroup select HOSTGROUPNAME
select a hostgroup to make changes on it
'''
def complete_hostgroup(self, text, line, begidx, endidx):
if begidx == 10:
return [x for x in self._hostgroupArgs if x.startswith(text)] if len(text) > 0 else self._hostgroupArgs

View file

@ -1,33 +0,0 @@
"""
Copyright (c) 2011-2013 "Johannes Findeisen and Rafael Timmerberg"
This file is part of Linspector (http://linspector.org).
Linspector is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
"""
class Parser:
def __init__(self, **kwargs):
pass
def parse_data(self, data):
self.pre_parse(data)
return self.generate_parse_result(data)
def pre_parse(self, data):
pass
def generate_parse_result(self, result):
pass

View file

@ -1,29 +0,0 @@
"""
Copyright (c) 2011-2013 "Johannes Findeisen and Rafael Timmerberg"
This file is part of Linspector (http://linspector.org).
Linspector is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
"""
from lib.parsers.parser import Parser
class ShellParser(Parser):
def __init__(self, **kwargs):
pass
def create(kwargs):
return ShellParser(**kwargs)

View file

@ -1,31 +0,0 @@
"""
The MariaDB processor
Copyright (c) 2011-2013 "Johannes Findeisen and Rafael Timmerberg"
This file is part of Linspector (http://linspector.org).
Linspector is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
"""
from lib.processors.processor import Processor
class MariadbProcessor(Processor):
def __init__(self, **kwargs):
Processor.__init__(self, **kwargs)
def create(kwargs):
return MariadbProcessor(**kwargs)

View file

@ -1,31 +0,0 @@
"""
The MongoDB processor
Copyright (c) 2011-2013 "Johannes Findeisen and Rafael Timmerberg"
This file is part of Linspector (http://linspector.org).
Linspector is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
"""
from lib.processors.processor import Processor
class MongodbProcessor(Processor):
def __init__(self, **kwargs):
Processor.__init__(self, **kwargs)
def create(kwargs):
return MongodbProcessor(**kwargs)

View file

@ -1,25 +0,0 @@
"""
The processor class for postprocessing polled data.
Copyright (c) 2011-2013 "Johannes Findeisen and Rafael Timmerberg"
This file is part of Linspector (http://linspector.org).
Linspector is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
"""
class Processor:
def __init__(self, **kwargs):
pass

View file

@ -1,31 +0,0 @@
"""
The syslog processor
Copyright (c) 2011-2013 "Johannes Findeisen and Rafael Timmerberg"
This file is part of Linspector (http://linspector.org).
Linspector is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
"""
from lib.processors.processor import Processor
class SyslogProcessor(Processor):
def __init__(self, **kwargs):
Processor.__init__(self, **kwargs)
def create(kwargs):
return SyslogProcessor(**kwargs)

View file

@ -1,72 +0,0 @@
"""
The http service.
This is for checking the availability and output of HTTP services. Basic HTTP
content could be fetched and compared.HTTPS is not validating the server certificate!
This should just return 0 on success and NOT 0 on error. Just to make internals generic
to just report this code and not use a parser.
Copyright (c) 2011-2013 "Johannes Findeisen and Rafael Timmerberg"
This file is part of Linspector (http://linspector.org).
Linspector is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
"""
import urllib
from lib.services.service import Service
class HttpService(Service):
def __init__(self, **kwargs):
super(HttpService, self).__init__(**kwargs)
args = self.get_arguments()
self.method = "get"
if "method" in args:
self.method = args["method"]
self.params = None
if "params" in args:
self.params = kwargs["params"]
self.path = "/"
if "path" in args:
self.path = kwargs["path"]
self.port = "80"
if "port" in args:
self.port = kwargs["port"]
self.protocol = "http"
if "protocol" in args:
self.protocol = kwargs["protocol"]
def needs_arguments(self):
return True
def execute(self):
params = urllib.urlencode(self.params)
if self.method is "get":
f = urllib.urlopen(self.protocol + "://" + self._host + ":" + self.port + self.path + "?%s" % params)
elif self.method is "post":
f = urllib.urlopen(self.protocol + "://" + self._host + ":" + self.port + self.path, params)
#print f.read()
def create(kwargs):
return HttpService(**kwargs)

View file

@ -1,265 +0,0 @@
"""
The ping service in pure Python.
Copyright (c) 2011-2013 "Johannes Findeisen and Rafael Timmerberg"
This file is part of Linspector (http://linspector.org).
Linspector is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
"""
# http://code.activestate.com/recipes/409689-icmplib-library-for-creating-and-reading-icmp-pack/
from lib.services.service import Service
import struct
class Packet(object):
"""Creates ICMPv4 and v6 packets.
header
two-item sequence containing the type and code of the packet,
respectively.
version
Automatically set to version of protocol being used or None if ambiguous.
data
Contains data of the packet. Can only assign a subclass of basestring
or None.
packet
binary representation of packet.
"""
header_table = {
0 : (0, 4),
#3 : (15, 4), Overlap with ICMPv6
3 : (15, None),
#4 : (0, 4), Deprecated by RFC 1812
5 : (3, 4),
8 : (0, 4),
9 : (0, 4),
10: (0, 4),
11: (1, 4),
12: (1, 4),
13: (0, 4),
14: (0, 4),
15: (0, 4),
16: (0, 4),
17: (0, 4),
18: (0, 4),
1: (4, 6),
2: (0, 6),
#3 : (2, 6), Overlap with ICMPv4
#4 : (2, 6), Type of 4 in ICMPv4 is deprecated
4: (2, None),
128: (0, 6),
129: (0, 6),
130: (0, 6),
131: (0, 6),
132: (0, 6),
133: (0, 6),
134: (0, 6),
135: (0, 6),
136: (0, 6),
137: (0, 6),
}
def _setheader(self, header):
"""Set type, code, and version for the packet."""
if len(header) != 2:
raise ValueError("header data must be in a two-item sequence")
type_, code = header
try:
max_range, version = self.header_table[type_]
except KeyError:
raise ValueError("%s is not a valid type argument" % type_)
else:
if code > max_range:
raise ValueError("%s is not a valid code value for type %s" %\
(type_, code))
self._type, self._code, self._version = type_, code, version
header = property(lambda self: (self._type, self._code), _setheader,
doc="type and code of packet")
version = property(lambda self: self._version,
doc="Protocol version packet is using or None if "
"ambiguous")
def _setdata(self, data):
"""Setter for self.data; will only accept a basestring or None type."""
if not isinstance(data, basestring) and not isinstance(data, type(None)):
raise TypeError("value must be a subclass of basestring or None, "
"not %s" % type(data))
self._data = data
data = property(lambda self: self._data, _setdata,
doc="data contained within the packet")
def __init__(self, header=(None, None), data=None):
"""Set instance attributes if given."""
#XXX: Consider using __slots__
# self._version initialized by setting self.header
self.header = header
self.data = data
self.type = None
self.code = None
def __repr__(self):
return "<ICMPv%s packet: type = %s, code = %s, data length = %s>" % \
(self.version, self.type, self.code, len(self.data))
def create(self):
"""Return a packet."""
# Kept as a separate method instead of rolling into 'packet' property so
# as to allow passing method around without having to define a lambda
# method.
args = [self.header[0], self.header[1], 0]
pack_format = "!BBH"
if self.data:
pack_format += "%ss" % len(self.data)
args.append(self.data)
# ICMPv6 has the IP stack calculate the checksum
# For ambiguous cases, just go ahead and calculate it just in case
if self.version == 4 or not self.version:
args[2] = self._checksum(struct.pack(pack_format, *args))
return struct.pack(pack_format, *args)
packet = property(create,
doc="Complete ICMP packet")
def _checksum(self, checksum_packet):
"""Calculate checksum"""
byte_count = len(checksum_packet)
#XXX: Think there is an error here about odd number of bytes
if byte_count % 2:
odd_byte = ord(checksum_packet[-1])
checksum_packet = checksum_packet[:-1]
else:
odd_byte = 0
two_byte_chunks = struct.unpack("!%sH" % (len(checksum_packet)/2),
checksum_packet)
total = 0
for two_bytes in two_byte_chunks:
total += two_bytes
else:
total += odd_byte
total = (total >> 16) + (total & 0xFFFF)
total += total >> 16
return ~total
def parse(cls, packet):
"""Parse ICMP packet and return an instance of Packet"""
string_len = len(packet) - 4 # Ignore IP header
pack_format = "!BBH"
if string_len:
pack_format += "%ss" % string_len
unpacked_packet = struct.unpack(pack_format, packet)
packetType, code, checksum = unpacked_packet[:3]
try:
data = unpacked_packet[3]
except IndexError:
data = None
return cls((packetType, code), data)
parse = classmethod(parse)
import socket
import time
import os
class PingResponse(object):
def __init__(self, bufferLength, address, ident, seq, rtt):
self.bufferLength = bufferLength
self.address = address
self.ident = ident
self.seq = seq
self.rtt = rtt
def get_response_time(self):
return self.rtt
def __str__(self):
return "%d bytes from %s: id=%s, seq=%u, rtt=%.3f ms" % \
(self.bufferLength, self.address, self.ident, self.seq, self.rtt)
class PingService(Service):
def __init__(self, **kwargs):
super(PingService, self).__init__(**kwargs)
self.dataLen = 56
self.bufferSize = 1500
def execute(self, host):
self.ping(host)
def ping(self, address):
print "PING (%s): %d data bytes" % (address, self.dataLen)
## create socket
s = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.getprotobyname('icmp'))
s.connect((address, 22))
## setuid back to normal user
processId = os.getpid()
os.setuid(processId)
base_packet = Packet((8, 0))
seqNum = 0
## create ping packet
pdata = struct.pack("!HHd", processId, seqNum, time.time())
## send initial packet
base_packet.data = pdata
s.send(base_packet.packet)
## recv packet
buf = s.recv(self.bufferSize)
current_time = time.time()
## parse packet; remove IP header first
r = Packet.parse(buf[20:])
## parse ping data
(ident, seq, timestamp) = struct.unpack("!HHd", r.data)
## calculate rounttrip time
rtt = current_time - timestamp
rtt *= 1000
return PingResponse(len(buf), address, ident, seq, rtt)
def parse_result(self, executionResult):
fails = {}
for host, pingResult in executionResult.items():
for failKey, failVal in self.get_fails().items():
respTime = pingResult.get_response_time()
if int(failVal) > int(respTime):
fails[failKey] = pingResult
return fails
def handle_result(self, parseResult):
for member in self.get_hostgroup().get_members():
for failKey, pingResult in parseResult.items():
for task in member.get_tasks():
if failKey == task.get_task_type():
task._execute()
def create(kwargs):
return PingService(**kwargs)

View file

@ -1,142 +0,0 @@
"""
Copyright (c) 2011-2013 "Johannes Findeisen and Rafael Timmerberg"
This file is part of Linspector (http://linspector.org).
Linspector is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
"""
KEY_PARSER = "parser"
KEY_COMMENT = "comment"
KEY_THRESHOLD = "threshold"
KEY_FAILS = "fails"
KEY_PERIODS = "periods"
KEY_ARGS = "args"
class Service(object):
def __init__(self, **kwargs):
self._args = {}
if KEY_ARGS in kwargs:
self.add_arguments(kwargs[KEY_ARGS])
elif self.needs_arguments():
raise Exception("Error: needs arguments but none provided!")
self._parser = []
if KEY_PARSER in kwargs:
self.add_parser(kwargs[KEY_PARSER])
self._comment = None
if KEY_COMMENT in kwargs:
self._comment = kwargs[KEY_COMMENT]
self._threshold = 0
if KEY_THRESHOLD in kwargs:
self._threshold = kwargs[KEY_THRESHOLD]
self._fails = {}
if KEY_FAILS in kwargs:
self.put_fails(kwargs[KEY_FAILS])
self._periods = []
if KEY_PERIODS in kwargs:
self.add_periods(kwargs[KEY_PERIODS])
def add_arguments(self, args):
for key, val in args.items():
self._args[key] = val
def add_argument(self, key, value):
self._args[key] = value
def get_arguments(self):
return self._args
def add_periods(self, period):
if period is not None:
if isinstance(period, list):
self._periods.extend(period)
else:
self._periods.append(period)
def set_hostgroup(self, hostgroup):
self.hostgroup = hostgroup
def get_hostgroup(self):
return self.hostgroup
def get_periods(self):
return self._periods
def get_fails(self):
return self._fails
def has_fail(self, fail):
return fail in self.get_fails()
def put_fail(self, key, value):
self._fails[key] = value
def put_fails(self, fails):
for key, value in fails.items():
self.put_fail(key, value)
def get_threshold(self):
return self._threshold
def get_comment(self):
return self._comment
def get_parser(self):
return self._parser
def add_parser(self, parser):
if parser is not None:
if isinstance(parser, list):
self._parser.extend(parser)
else:
self._parser.append(parser)
def needs_arguments(self):
return False
def _execute(self, jobInfo):
try:
self.pre_execute(jobInfo)
self.execute(jobInfo)
self.parse_result(jobInfo)
self.post_execute(jobInfo)
except Exception, e:
self.set_execution_successful(False)
self._threshold -= 1
raise e
def execute(self, jobInfo):
pass
def pre_execute(self, jobInfo):
pass
def parse_result(self, jobInfo):
result = []
for parser in self.get_parser():
result.append(parser.parse(jobInfo))
return result
def post_execute(self, jobInfo):
pass

View file

@ -1,43 +0,0 @@
"""
The shell service. This is for executing local shell commands and retrieve the output.
Copyright (c) 2011-2013 "Johannes Findeisen and Rafael Timmerberg"
This file is part of Linspector (http://linspector.org).
Linspector is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
"""
from lib.services.service import Service
class ShellService(Service):
def __init__(self, **kwargs):
super(ShellService, self).__init__(**kwargs)
args = self.get_arguments()
if "command" in args:
self.command = args["command"]
else:
raise Exception("There is no command argument")
def needs_arguments(self):
return True
def execute(self):
self.command.call()
def create(kwargs):
return ShellService(**kwargs)

View file

@ -1,73 +0,0 @@
"""
The snmpget service in pure Python.
Copyright (c) 2011-2013 "Johannes Findeisen and Rafael Timmerberg"
This file is part of Linspector (http://linspector.org).
Linspector is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
"""
#from pysnmp.entity.rfc3413.oneliner import cmdgen
from lib.services.service import Service
class SnmpgetService(Service):
def __init__(self, **kwargs):
super(SnmpgetService, self).__init__(**kwargs)
args = self.get_arguments()
if "community" in args:
self.community = args["community"]
else:
raise Exception("There is no community")
if "oid" in args:
self.oid = args["oid"]
else:
raise Exception("There is no oid")
self.port = "161"
if "port" in args:
self.port = args["port"]
def needs_arguments(self):
return True
def execute(self):
pass
#cmdGen = cmdgen.CommandGenerator()
#errorIndication, errorStatus, errorIndex, varBinds = cmdGen.getCmd(
# cmdgen.CommunityData(self.community),
# cmdgen.UdpTransportTarget((self._host, self.port)),
# cmdgen.MibVariable(self.oid)
#)
#if errorIndication:
# print(errorIndication)
#else:
# if errorStatus:
# print('%s at %s' % (
# errorStatus.prettyPrint(),
# errorIndex and varBinds[int(errorIndex) - 1] or '?'
# ))
# else:
# for name, val in varBinds:
# print('%s = %s' % (name.prettyPrint(), val.prettyPrint()))
def create(kwargs):
return SnmpgetService(**kwargs)

View file

@ -1,68 +0,0 @@
"""
The ssh service This is for executing remote shell commands and retrieve the output.
This service is using paramiko (http://www.lag.net/paramiko/).
Copyright (c) 2011-2013 "Johannes Findeisen and Rafael Timmerberg"
This file is part of Linspector (http://linspector.org).
Linspector is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
"""
import paramiko
import pprint
import os
from lib.services.service import Service
class SshService(Service):
def __init__(self, **kwargs):
super(SshService, self).__init__(**kwargs)
args = self.get_arguments()
if "command" in args:
self.command = args["command"]
else:
raise Exception("There is no command argument")
def needs_arguments(self):
return True
def execute(self):
path = os.path.join(os.environ['HOME'], '.ssh', 'id_rsa')
key = paramiko.RSAKey.from_private_key_file(path)
client = paramiko.SSHClient()
client.get_host_keys().add('hanez.org', 'ssh-rsa', key)
pprint.pprint(client._host_keys)
client.connect('hanez.org', username='hanez')
#self.command.call() ist dann das:
stdin, stdout, stderr = client.exec_command('ls')
for line in stdout:
print '... ' + line.strip('\n')
client.close()
def create(kwargs):
return SshService(**kwargs)
# def main():
# # service = SshService(parser, log, command='uptime')
# return
#
# if __name__ == "__main__":
# main()

View file

@ -1,67 +0,0 @@
"""
The tcpconnect service. This is to check if a service on a specific port is reachable.
This should just return 0 on success and NOT 0 on error. Just to make internals generic to just report this code and
not use a parser.
Copyright (c) 2011-2013 "Johannes Findeisen and Rafael Timmerberg"
This file is part of Linspector (http://linspector.org).
Linspector is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
"""
import socket
from lib.services.service import Service
class TcpconnectService(Service):
def __init__(self, **kwargs):
super(TcpconnectService, self).__init__(**kwargs)
args = self.get_arguments()
if "port" in args:
self.port = args["port"]
else:
raise Exception("There is no port set")
def needs_arguments(self):
return True
def execute(self, jobInfo):
try:
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
except socket.error, msg:
jobInfo.set_errorcode(2)
jobInfo.set_message("[tcpconnect] Could not create socket to host: " + jobInfo.get_host() +
" on port: " + str(self.port) + " (" + str(msg) + ")")
try:
sock.connect((jobInfo.get_host(), self.port))
except socket.error, msg:
jobInfo.set_errorcode(1)
jobInfo.set_message("[tcpconnect] Could not establish connection to host: " + jobInfo.get_host() +
" on port: " + str(self.port) + " (" + str(msg) + ")")
if jobInfo.get_errorcode() == -1:
jobInfo.set_execution_successful(True)
jobInfo.set_errorcode(0)
jobInfo.set_message("[tcpconnect] Connection successful established to host: " + jobInfo.get_host() +
" on port: " + str(self.port))
sock.close()
def create(kwargs):
return TcpconnectService(**kwargs)

View file

View file

@ -1,49 +0,0 @@
"""
The Jabber (XMPP) task.
Uses: http://xmpppy.sourceforge.net/
Copyright (c) 2011-2013 "Johannes Findeisen and Rafael Timmerberg"
This file is part of Linspector (http://linspector.org).
Linspector is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
"""
import xmpp
from lib.tasks.task import Task
class JabberTask(Task):
def __init__(self, **kwargs):
if not "type" in kwargs:
raise Exception("'type' not in typeDict " + str(kwargs))
if not "args" in kwargs:
raise Exception("typeDict " + str(kwargs) + " has nor arguments!")
self.set_task_type(kwargs["type"])
self.recipient = kwargs["args"]["rcpt"]
def execute(self, msg, core):
#TODO: totally unstable just to use values from core. make checks before...!
client = xmpp.Client(core["tasks"]["jabber"]["host"], core["tasks"]["jabber"]["port"], None)
client.connect(server=(core["tasks"]["jabber"]["host"], core["tasks"]["jabber"]["port"]))
client.auth(core["tasks"]["jabber"]["username"], core["tasks"]["jabber"]["password"], 'alert')
client.sendInitPresence()
message = xmpp.Message(self.recipient, msg)
message.setAttr('type', 'chat')
client.send(message)
def create(taskDict):
return JabberTask(**taskDict)

View file

@ -1,54 +0,0 @@
"""
The mail task.
http://docs.python.org/2/library/email-examples.html#
Copyright (c) 2011-2013 "Johannes Findeisen and Rafael Timmerberg"
This file is part of Linspector (http://linspector.org).
Linspector is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
"""
import datetime
import smtplib
from email.mime.text import MIMEText
from lib.tasks.task import Task
class MailTask(Task):
def __init__(self, **kwargs):
if not "type" in kwargs:
raise Exception("'type' not in typeDict " + str(kwargs))
if not "args" in kwargs:
raise Exception("typeDict " + str(kwargs) + " has no arguments!")
self.set_task_type(kwargs["type"])
self.recipient = kwargs["args"]["rcpt"]
def execute(self, msg, core):
message = MIMEText(msg)
message['Subject'] = msg
now = datetime.datetime.now()
message['Date'] = now.strftime("%a, %d %b %Y %H:%M:%S")
#TODO: totally unstable just to use values from core. make checks before...!
message['From'] = core["tasks"]["mail"]["from"]
message['To'] = self.recipient
s = smtplib.SMTP(core["tasks"]["mail"]["host"], core["tasks"]["mail"]["port"])
s.login(core["tasks"]["mail"]["username"], core["tasks"]["mail"]["password"])
s.sendmail(core["tasks"]["mail"]["from"], self.recipient, message.as_string())
s.quit()
def create(taskDict):
return MailTask(**taskDict)

View file

@ -1,39 +0,0 @@
"""
The sms task.
Copyright (c) 2011-2013 "Johannes Findeisen and Rafael Timmerberg"
This file is part of Linspector (http://linspector.org).
Linspector is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
"""
from lib.tasks.task import Task
class SmsTask(Task):
def __init__(self, **kwargs):
if not "type" in kwargs:
raise Exception("'type' not in typeDict " + str(kwargs))
if not "args" in kwargs:
raise Exception("typeDict " + str(kwargs) + " has no arguments!")
self.set_task_type(kwargs["type"])
self.recipient = kwargs["args"]["rcpt"]
def execute(self, msg):
pass
def create(taskDict):
return SmsTask(**taskDict)

View file

@ -1,31 +0,0 @@
"""
The task class.
Copyright (c) 2011-2013 "Johannes Findeisen and Rafael Timmerberg"
This file is part of Linspector (http://linspector.org).
Linspector is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
"""
class Task:
def set_task_type(self, taskType):
self._taskType = taskType
def get_task_type(self):
return self._taskType
def execute(self, msg):
pass

View file

@ -1,45 +0,0 @@
"""
The tweet/twitter task.
Uses: tweepy
Copyright (c) 2011-2013 "Johannes Findeisen and Rafael Timmerberg"
This file is part of Linspector (http://linspector.org).
Linspector is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
"""
import tweepy
from lib.tasks.task import Task
class TweetTask(Task):
def __init__(self, **kwargs):
if not "type" in kwargs:
raise Exception("'type' not in typeDict " + str(kwargs))
if not "args" in kwargs:
raise Exception("typeDict " + str(kwargs) + " has no arguments!")
self.set_task_type(kwargs["type"])
self.recipient = kwargs["args"]["rcpt"]
def execute(self, msg, core):
auth = tweepy.BasicAuthHandler("user", "pass")
api = tweepy.API(auth)
api.update_status(self.recipient)
print(self.get_task_type())
def create(taskDict):
return TweetTask(**taskDict)