moved linspector to bin and renamed lib
This commit is contained in:
parent
3f592b61c0
commit
b73d0abb2d
47 changed files with 24 additions and 161 deletions
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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)
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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().
|
||||
"""
|
||||
|
|
@ -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
|
||||
122
lib/core/job.py
122
lib/core/job.py
|
|
@ -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
|
||||
|
|
@ -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)
|
||||
|
|
@ -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()
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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)
|
||||
|
|
@ -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)
|
||||
|
|
@ -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)
|
||||
|
|
@ -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
|
||||
|
|
@ -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)
|
||||
|
|
@ -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)
|
||||
|
|
@ -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)
|
||||
|
|
@ -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
|
||||
|
|
@ -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)
|
||||
|
|
@ -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)
|
||||
|
|
@ -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()
|
||||
|
|
@ -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)
|
||||
|
|
@ -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)
|
||||
|
|
@ -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)
|
||||
|
|
@ -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)
|
||||
|
|
@ -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
|
||||
|
|
@ -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)
|
||||
Loading…
Add table
Add a link
Reference in a new issue