From da45205cb0bbdf51e8948f5df2723a74c13d193e Mon Sep 17 00:00:00 2001 From: aviau Date: Mon, 20 Jul 2015 14:10:00 -0400 Subject: [PATCH] Changed comma-separated stringfields to lists Change-Id: I8c2ad414d300357a80652e495f4fb7da28ab401c --- Dockerfile | 3 - requirements.txt | 2 +- setup.cfg | 1 + .../config/businessimpactmodulation.py | 6 +- .../api/datamodel/config/checkmodulation.py | 6 +- surveil/api/datamodel/config/command.py | 4 +- surveil/api/datamodel/config/contact.py | 14 +- surveil/api/datamodel/config/contactgroup.py | 14 +- surveil/api/datamodel/config/host.py | 19 +- surveil/api/datamodel/config/hostgroup.py | 12 +- .../api/datamodel/config/macromodulation.py | 4 +- .../api/datamodel/config/notificationway.py | 26 +- surveil/api/datamodel/config/realm.py | 9 +- surveil/api/datamodel/config/service.py | 20 +- surveil/api/datamodel/config/servicegroup.py | 15 +- surveil/api/datamodel/config/timeperiod.py | 6 +- surveil/api/storage/mongodb/config/contact.py | 8 +- .../storage/mongodb/config/contactgroup.py | 4 +- surveil/api/storage/mongodb/config/host.py | 10 +- .../api/storage/mongodb/config/hostgroup.py | 8 +- .../storage/mongodb/config/notificationway.py | 8 +- surveil/api/storage/mongodb/config/realm.py | 6 +- surveil/api/storage/mongodb/config/service.py | 12 +- .../storage/mongodb/config/servicegroup.py | 8 +- .../api/storage/mongodb/config/timeperiod.py | 1 + surveil/cmd/init.py | 120 ++++------ surveil/cmd/pack_upload.py | 95 +++----- surveil/cmd/surveil_from_nagios.py | 226 ++++++++++++++++++ .../v2/config/test_contactgroup.py | 14 +- .../controllers/v2/config/test_contacts.py | 12 +- .../controllers/v2/config/test_hostgroup.py | 14 +- .../api/controllers/v2/config/test_hosts.py | 84 ++++--- .../v2/config/test_notificationways.py | 58 ++--- .../api/controllers/v2/config/test_realms.py | 12 +- .../v2/config/test_servicegroup.py | 26 +- .../controllers/v2/config/test_services.py | 40 ++-- surveil/tests/cmd/__init__.py | 0 surveil/tests/cmd/nagios_config/config.cfg | 23 ++ .../tests/cmd/nagios_config/other_file.cfg | 3 + surveil/tests/cmd/test_surveil_from_nagios.py | 92 +++++++ tools/docker/alignak_container/Dockerfile | 2 +- tox.ini | 2 +- 42 files changed, 719 insertions(+), 330 deletions(-) create mode 100644 surveil/cmd/surveil_from_nagios.py create mode 100644 surveil/tests/cmd/__init__.py create mode 100644 surveil/tests/cmd/nagios_config/config.cfg create mode 100644 surveil/tests/cmd/nagios_config/other_file.cfg create mode 100644 surveil/tests/cmd/test_surveil_from_nagios.py diff --git a/Dockerfile b/Dockerfile index de6e653..9f6978c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -7,9 +7,6 @@ RUN apt-get update && apt-get install -y vim python-pip python3-pip python-dev l # VirtualEnv RUN virtualenv /opt/surveil/env -# Surveil needs alignak (as a lib) -RUN useradd alignak && /opt/surveil/env/bin/pip install pycurl https://github.com/Alignak-monitoring/alignak/archive/d7f457d5ed94f08d9a6a38809106d3e0d35a1712.tar.gz - # Download packs ENV MONITORING_TOOLS_VERSION 0.4.0 RUN apt-get install -y subversion && \ diff --git a/requirements.txt b/requirements.txt index 1b6a8b2..8029199 100644 --- a/requirements.txt +++ b/requirements.txt @@ -10,7 +10,7 @@ keystonemiddleware PasteDeploy influxdb==2.6.0 pika -python-surveilclient==0.10.0 +python-surveilclient==0.12.0 six docker-py mongoengine diff --git a/setup.cfg b/setup.cfg index 5ce3282..d1908fc 100644 --- a/setup.cfg +++ b/setup.cfg @@ -16,6 +16,7 @@ console_scripts = surveil-pack-upload = surveil.cmd.pack_upload:main surveil-os-discovery = surveil.cmd.os_discovery:main surveil-os-interface = surveil.cmd.surveil_os_interface:main + surveil-from-nagios = surveil.cmd.surveil_from_nagios:main [build_sphinx] source-dir = doc/source diff --git a/surveil/api/datamodel/config/businessimpactmodulation.py b/surveil/api/datamodel/config/businessimpactmodulation.py index 60baa2f..66fbbdf 100644 --- a/surveil/api/datamodel/config/businessimpactmodulation.py +++ b/surveil/api/datamodel/config/businessimpactmodulation.py @@ -19,11 +19,11 @@ from surveil.api.datamodel import types class BusinessImpactModulation(types.Base): - business_impact_modulation_name = wsme.wsattr(wtypes.text, mandatory=True) + business_impact_modulation_name = wsme.wsattr(wtypes.text, mandatory=False) - business_impact = wsme.wsattr(int, mandatory=True) + business_impact = wsme.wsattr(int, mandatory=False) - modulation_period = wsme.wsattr(wtypes.text, mandatory=True) + modulation_period = wsme.wsattr(wtypes.text, mandatory=False) @classmethod def sample(cls): diff --git a/surveil/api/datamodel/config/checkmodulation.py b/surveil/api/datamodel/config/checkmodulation.py index afc751f..e5fef10 100644 --- a/surveil/api/datamodel/config/checkmodulation.py +++ b/surveil/api/datamodel/config/checkmodulation.py @@ -19,11 +19,11 @@ from surveil.api.datamodel import types class CheckModulation(types.Base): - checkmodulation_name = wsme.wsattr(wtypes.text, mandatory=True) + checkmodulation_name = wsme.wsattr(wtypes.text, mandatory=False) - check_command = wsme.wsattr(wtypes.text, mandatory=True) + check_command = wsme.wsattr(wtypes.text, mandatory=False) - check_period = wsme.wsattr(wtypes.text, mandatory=True) + check_period = wsme.wsattr(wtypes.text, mandatory=False) @classmethod def sample(cls): diff --git a/surveil/api/datamodel/config/command.py b/surveil/api/datamodel/config/command.py index ec1736d..5c87ace 100644 --- a/surveil/api/datamodel/config/command.py +++ b/surveil/api/datamodel/config/command.py @@ -27,10 +27,10 @@ from surveil.api.datamodel import types class Command(types.Base): - command_name = wsme.wsattr(wtypes.text, mandatory=True) + command_name = wsme.wsattr(wtypes.text, mandatory=False) """The name of the command""" - command_line = wsme.wsattr(wtypes.text, mandatory=True) + command_line = wsme.wsattr(wtypes.text, mandatory=False) """This directive is used to define what is actually executed by Shinken""" module_type = wsme.wsattr(wtypes.text, mandatory=False) diff --git a/surveil/api/datamodel/config/contact.py b/surveil/api/datamodel/config/contact.py index a53c441..98866ab 100644 --- a/surveil/api/datamodel/config/contact.py +++ b/surveil/api/datamodel/config/contact.py @@ -19,7 +19,7 @@ from surveil.api.datamodel import types class Contact(types.Base): - contact_name = wsme.wsattr(wtypes.text, mandatory=True) + contact_name = wsme.wsattr(wtypes.text, mandatory=False) host_notifications_enabled = wsme.wsattr(int, mandatory=False) @@ -29,13 +29,17 @@ class Contact(types.Base): service_notification_period = wsme.wsattr(wtypes.text, mandatory=False) - host_notification_options = wsme.wsattr(wtypes.text, mandatory=False) + host_notification_options = wsme.wsattr(wtypes.ArrayType(wtypes.text), + mandatory=False) - service_notification_options = wsme.wsattr(wtypes.text, mandatory=False) + service_notification_options = wsme.wsattr(wtypes.ArrayType(wtypes.text), + mandatory=False) - host_notification_commands = wsme.wsattr(wtypes.text, mandatory=False) + host_notification_commands = wsme.wsattr(wtypes.ArrayType(wtypes.text), + mandatory=False) - service_notification_commands = wsme.wsattr(wtypes.text, mandatory=False) + service_notification_commands = wsme.wsattr(wtypes.ArrayType(wtypes.text), + mandatory=False) email = wsme.wsattr(wtypes.text, mandatory=False) diff --git a/surveil/api/datamodel/config/contactgroup.py b/surveil/api/datamodel/config/contactgroup.py index abc5b2e..706c5b7 100644 --- a/surveil/api/datamodel/config/contactgroup.py +++ b/surveil/api/datamodel/config/contactgroup.py @@ -19,15 +19,21 @@ from surveil.api.datamodel import types class ContactGroup(types.Base): - contactgroup_name = wsme.wsattr(wtypes.text, mandatory=True) - members = wsme.wsattr(wtypes.text, mandatory=False) + contactgroup_name = wsme.wsattr(wtypes.text, mandatory=False) + members = wsme.wsattr(wtypes.ArrayType(wtypes.text), + mandatory=False) alias = wsme.wsattr(wtypes.text, mandatory=False) - contactgroup_members = wsme.wsattr(wtypes.text, mandatory=False) + contactgroup_members = wsme.wsattr(wtypes.ArrayType(wtypes.text), + mandatory=False) @classmethod def sample(cls): return cls( contactgroup_name='novell-admins', alias='Novell Administrators', - members='jdoe,rtobert,tzach' + members=[ + 'jdoe', + 'rtobert', + 'tzach' + ] ) diff --git a/surveil/api/datamodel/config/host.py b/surveil/api/datamodel/config/host.py index 5cf30fe..71b2d69 100644 --- a/surveil/api/datamodel/config/host.py +++ b/surveil/api/datamodel/config/host.py @@ -19,7 +19,7 @@ from surveil.api.datamodel import types class Host(types.Base): - host_name = wsme.wsattr(wtypes.text, mandatory=True) + host_name = wsme.wsattr(wtypes.text, mandatory=False) """The name of the host""" address = wsme.wsattr(wtypes.text, mandatory=False) @@ -30,21 +30,23 @@ class Host(types.Base): check_period = wsme.wsattr(wtypes.text, mandatory=False) """The time period during which active checks of this host can be made.""" - contacts = wsme.wsattr(wtypes.text, mandatory=False) + contacts = wsme.wsattr(wtypes.ArrayType(wtypes.text), mandatory=False) """A list of the short names of the contacts that should be notified.""" - contact_groups = wsme.wsattr(wtypes.text, mandatory=False) - """List of the short names of the contact groups that should be notified""" + contact_groups = wsme.wsattr(wtypes.ArrayType(wtypes.text), + mandatory=False) + """List of the short names of contact groups that should be notified""" notification_interval = wsme.wsattr(int, mandatory=False) notification_period = wsme.wsattr(wtypes.text, mandatory=False) - use = wsme.wsattr(wtypes.text, mandatory=False) + use = wsme.wsattr(wtypes.ArrayType(wtypes.text), mandatory=False) """The template to use for this host""" name = wsme.wsattr(wtypes.text, mandatory=False) + # TODO(aviau): int! register = wsme.wsattr(wtypes.text, mandatory=False) check_interval = wsme.wsattr(int, mandatory=False) @@ -61,13 +63,14 @@ class Host(types.Base): @classmethod def sample(cls): return cls( - use="generic-host", + use=["generic-host"], host_name="bogus-router", address="192.168.1.254", max_check_attempts=5, check_period="24x7", - contacts="admin,carl", - contact_groups="router-admins", + contacts=["admin", + "carl"], + contact_groups=["router-admins"], notification_interval=30, notification_period="24x7", custom_fields={"OS_AUTH_URL": "http://localhost:8080/v2"} diff --git a/surveil/api/datamodel/config/hostgroup.py b/surveil/api/datamodel/config/hostgroup.py index aae146f..377f110 100644 --- a/surveil/api/datamodel/config/hostgroup.py +++ b/surveil/api/datamodel/config/hostgroup.py @@ -19,10 +19,11 @@ from surveil.api.datamodel import types class HostGroup(types.Base): - hostgroup_name = wsme.wsattr(wtypes.text, mandatory=True) - members = wsme.wsattr(wtypes.text, mandatory=False) + hostgroup_name = wsme.wsattr(wtypes.text, mandatory=False) + members = wsme.wsattr(wtypes.ArrayType(wtypes.text), mandatory=False) alias = wsme.wsattr(wtypes.text, mandatory=False) - hostgroup_members = wsme.wsattr(wtypes.text, mandatory=False) + hostgroup_members = wsme.wsattr(wtypes.ArrayType(wtypes.text), + mandatory=False) notes = wsme.wsattr(wtypes.text, mandatory=False) notes_url = wsme.wsattr(wtypes.text, mandatory=False) action_url = wsme.wsattr(wtypes.text, mandatory=False) @@ -32,5 +33,8 @@ class HostGroup(types.Base): return cls( hostgroup_name='dbservices', alias='Novell Servers', - members='netware1,netware2,netware3,netware4' + members=['netware1', + 'netware2', + 'netware3', + 'netware4'] ) diff --git a/surveil/api/datamodel/config/macromodulation.py b/surveil/api/datamodel/config/macromodulation.py index fbaae11..ee32a96 100644 --- a/surveil/api/datamodel/config/macromodulation.py +++ b/surveil/api/datamodel/config/macromodulation.py @@ -19,8 +19,8 @@ from surveil.api.datamodel import types class MacroModulation(types.Base): - macromodulation_name = wsme.wsattr(wtypes.text, mandatory=True) - modulation_period = wsme.wsattr(wtypes.text, mandatory=True) + macromodulation_name = wsme.wsattr(wtypes.text, mandatory=False) + modulation_period = wsme.wsattr(wtypes.text, mandatory=False) macros = wsme.wsattr( wtypes.DictType(wtypes.text, int), diff --git a/surveil/api/datamodel/config/notificationway.py b/surveil/api/datamodel/config/notificationway.py index abce6f9..17b2a10 100644 --- a/surveil/api/datamodel/config/notificationway.py +++ b/surveil/api/datamodel/config/notificationway.py @@ -19,13 +19,17 @@ from surveil.api.datamodel import types class NotificationWay(types.Base): - notificationway_name = wsme.wsattr(wtypes.text, mandatory=True) - host_notification_period = wsme.wsattr(wtypes.text, mandatory=True) - service_notification_period = wsme.wsattr(wtypes.text, mandatory=True) - host_notification_options = wsme.wsattr(wtypes.text, mandatory=True) - service_notification_options = wsme.wsattr(wtypes.text, mandatory=True) - host_notification_commands = wsme.wsattr(wtypes.text, mandatory=True) - service_notification_commands = wsme.wsattr(wtypes.text, mandatory=True) + notificationway_name = wsme.wsattr(wtypes.text, mandatory=False) + host_notification_period = wsme.wsattr(wtypes.text, mandatory=False) + service_notification_period = wsme.wsattr(wtypes.text, mandatory=False) + host_notification_options = wsme.wsattr(wtypes.ArrayType(wtypes.text), + mandatory=False) + service_notification_options = wsme.wsattr(wtypes.ArrayType(wtypes.text), + mandatory=False) + host_notification_commands = wsme.wsattr(wtypes.ArrayType(wtypes.text), + mandatory=False) + service_notification_commands = wsme.wsattr(wtypes.ArrayType(wtypes.text), + mandatory=False) min_business_impact = wsme.wsattr(int, mandatory=False) @classmethod @@ -34,8 +38,8 @@ class NotificationWay(types.Base): notificationway_name="email_in_day", host_notification_period="24x7", service_notification_period="24x7", - host_notification_options="d,u,r,f,s", - service_notification_options="w,u,c,r,f", - service_notification_commands="notify-service", - host_notification_commands="notify-host" + host_notification_options=["d", "u", "r", "f", "s"], + service_notification_options=["w", "u", "c", "r", "f"], + service_notification_commands=["notify-service"], + host_notification_commands=["notify-host"] ) diff --git a/surveil/api/datamodel/config/realm.py b/surveil/api/datamodel/config/realm.py index b29ed44..2f1d409 100644 --- a/surveil/api/datamodel/config/realm.py +++ b/surveil/api/datamodel/config/realm.py @@ -19,14 +19,15 @@ from surveil.api.datamodel import types class Realm(types.Base): - realm_name = wsme.wsattr(wtypes.text, mandatory=True) - realm_members = wsme.wsattr(wtypes.text, mandatory=True) - default = wsme.wsattr(int, mandatory=True) + realm_name = wsme.wsattr(wtypes.text, mandatory=False) + realm_members = wsme.wsattr(wtypes.ArrayType(wtypes.text), + mandatory=False) + default = wsme.wsattr(int, mandatory=False) @classmethod def sample(cls): return cls( realm_name='World', - realm_members='Europe,America,Asia', + realm_members=['Europe', 'America', 'Asia'], default=0 ) diff --git a/surveil/api/datamodel/config/service.py b/surveil/api/datamodel/config/service.py index 271af2a..2da641c 100644 --- a/surveil/api/datamodel/config/service.py +++ b/surveil/api/datamodel/config/service.py @@ -19,9 +19,10 @@ from surveil.api.datamodel import types class Service(types.Base): - host_name = wsme.wsattr(wtypes.text, mandatory=True) + host_name = wsme.wsattr(wtypes.ArrayType(wtypes.text), + mandatory=False) - service_description = wsme.wsattr(wtypes.text, mandatory=True) + service_description = wsme.wsattr(wtypes.text, mandatory=False) check_command = wsme.wsattr(wtypes.text, mandatory=False) @@ -37,13 +38,16 @@ class Service(types.Base): notification_period = wsme.wsattr(wtypes.text, mandatory=False) - contacts = wsme.wsattr(wtypes.text, mandatory=False) + contacts = wsme.wsattr(wtypes.ArrayType(wtypes.text), + mandatory=False) - contact_groups = wsme.wsattr(wtypes.text, mandatory=False) + contact_groups = wsme.wsattr(wtypes.ArrayType(wtypes.text), + mandatory=False) passive_checks_enabled = wsme.wsattr(wtypes.text, mandatory=False) - use = wsme.wsattr(wtypes.text, mandatory=False) + use = wsme.wsattr(wtypes.ArrayType(wtypes.text), + mandatory=False) name = wsme.wsattr(wtypes.text, mandatory=False) @@ -52,7 +56,7 @@ class Service(types.Base): @classmethod def sample(cls): return cls( - host_name="sample-server", + host_name=["sample-server"], service_description="check-disk-sdb", check_command="check-disk!/dev/sdb1", max_check_attempts=5, @@ -61,7 +65,7 @@ class Service(types.Base): check_period="24x7", notification_interval=3, notification_period="24x7", - contacts="surveil-ptl,surveil-bob", - contact_groups="linux-admins", + contacts=["surveil-ptl", "surveil-bob"], + contact_groups=["linux-admins"], passive_checks_enabled='1', ) diff --git a/surveil/api/datamodel/config/servicegroup.py b/surveil/api/datamodel/config/servicegroup.py index 45ed2da..4a4fa56 100644 --- a/surveil/api/datamodel/config/servicegroup.py +++ b/surveil/api/datamodel/config/servicegroup.py @@ -19,10 +19,12 @@ from surveil.api.datamodel import types class ServiceGroup(types.Base): - servicegroup_name = wsme.wsattr(wtypes.text, mandatory=True) - members = wsme.wsattr(wtypes.text, mandatory=True) + servicegroup_name = wsme.wsattr(wtypes.text, mandatory=False) + members = wsme.wsattr(wtypes.ArrayType(wtypes.text), + mandatory=False) alias = wsme.wsattr(wtypes.text, mandatory=False) - servicegroup_members = wsme.wsattr(wtypes.text, mandatory=False) + servicegroup_members = wsme.wsattr(wtypes.ArrayType(wtypes.text), + mandatory=False) notes = wsme.wsattr(wtypes.text, mandatory=False) notes_url = wsme.wsattr(wtypes.text, mandatory=False) action_url = wsme.wsattr(wtypes.text, mandatory=False) @@ -32,5 +34,10 @@ class ServiceGroup(types.Base): return cls( servicegroup_name='dbservices', alias='Database Services', - members='ms1,SQL Server,ms1,SQL Serverc Agent,ms1,SQL DTC' + members=['ms1', + 'SQL Server', + 'ms1', + 'SQL Serverc Agent', + 'ms1', + 'SQL DTC'] ) diff --git a/surveil/api/datamodel/config/timeperiod.py b/surveil/api/datamodel/config/timeperiod.py index 988c555..f04b10c 100644 --- a/surveil/api/datamodel/config/timeperiod.py +++ b/surveil/api/datamodel/config/timeperiod.py @@ -19,8 +19,10 @@ from surveil.api.datamodel import types class TimePeriod(types.Base): - timeperiod_name = wsme.wsattr(wtypes.text, mandatory=True) - exclude = wsme.wsattr(wtypes.text, mandatory=False) + timeperiod_name = wsme.wsattr(wtypes.text, mandatory=False) + exclude = wsme.wsattr(wtypes.ArrayType(wtypes.text), + mandatory=False) + alias = wsme.wsattr(wtypes.text, mandatory=False) periods = wsme.wsattr( wtypes.DictType(wtypes.text, wtypes.text), diff --git a/surveil/api/storage/mongodb/config/contact.py b/surveil/api/storage/mongodb/config/contact.py index 2a0048e..8646618 100644 --- a/surveil/api/storage/mongodb/config/contact.py +++ b/surveil/api/storage/mongodb/config/contact.py @@ -22,10 +22,10 @@ class Contact(mongoengine.Document): service_notifications_enabled = mongoengine.StringField() host_notification_period = mongoengine.StringField() service_notification_period = mongoengine.StringField() - host_notification_options = mongoengine.StringField() - service_notification_options = mongoengine.StringField() - host_notification_commands = mongoengine.StringField() - service_notification_commands = mongoengine.StringField() + host_notification_options = mongoengine.ListField() + service_notification_options = mongoengine.ListField() + host_notification_commands = mongoengine.ListField() + service_notification_commands = mongoengine.ListField() email = mongoengine.StringField() pager = mongoengine.StringField() can_submit_commands = mongoengine.StringField() diff --git a/surveil/api/storage/mongodb/config/contactgroup.py b/surveil/api/storage/mongodb/config/contactgroup.py index 793ed8e..c59c089 100644 --- a/surveil/api/storage/mongodb/config/contactgroup.py +++ b/surveil/api/storage/mongodb/config/contactgroup.py @@ -18,6 +18,6 @@ import mongoengine class ContactGroup(mongoengine.Document): meta = {'collection': 'contactgroups'} contactgroup_name = mongoengine.StringField() - members = mongoengine.StringField() + members = mongoengine.ListField() alias = mongoengine.StringField() - contactgroup_members = mongoengine.StringField() \ No newline at end of file + contactgroup_members = mongoengine.ListField() diff --git a/surveil/api/storage/mongodb/config/host.py b/surveil/api/storage/mongodb/config/host.py index 8ab548c..d9ce2c9 100644 --- a/surveil/api/storage/mongodb/config/host.py +++ b/surveil/api/storage/mongodb/config/host.py @@ -20,16 +20,16 @@ class Host(mongoengine.Document): 'collection': 'hosts', 'strict': False } - host_name = mongoengine.StringField() + name = mongoengine.StringField(unique=True, sparse=True) + host_name = mongoengine.StringField(unique=True, sparse=True) address = mongoengine.StringField() max_check_attempts = mongoengine.IntField() check_period = mongoengine.StringField() - contacts = mongoengine.StringField() - contact_groups = mongoengine.StringField() + contacts = mongoengine.ListField() + contact_groups = mongoengine.ListField() notification_interval = mongoengine.IntField() notification_period = mongoengine.StringField() - use = mongoengine.StringField() - name = mongoengine.StringField() + use = mongoengine.ListField() register = mongoengine.StringField() check_interval = mongoengine.IntField() retry_interval = mongoengine.IntField() diff --git a/surveil/api/storage/mongodb/config/hostgroup.py b/surveil/api/storage/mongodb/config/hostgroup.py index 4695b49..7013806 100644 --- a/surveil/api/storage/mongodb/config/hostgroup.py +++ b/surveil/api/storage/mongodb/config/hostgroup.py @@ -17,10 +17,10 @@ import mongoengine class HostGroup(mongoengine.Document): meta = {'collection': 'hostgroups'} - hostgroup_name = mongoengine.StringField() - members = mongoengine.StringField() + hostgroup_name = mongoengine.StringField(unique=True) + members = mongoengine.ListField() alias = mongoengine.StringField() - hostgroup_members = mongoengine.StringField() + hostgroup_members = mongoengine.ListField() notes = mongoengine.StringField() notes_url = mongoengine.StringField() - action_url = mongoengine.StringField() \ No newline at end of file + action_url = mongoengine.StringField() diff --git a/surveil/api/storage/mongodb/config/notificationway.py b/surveil/api/storage/mongodb/config/notificationway.py index e4e3ce7..d920450 100644 --- a/surveil/api/storage/mongodb/config/notificationway.py +++ b/surveil/api/storage/mongodb/config/notificationway.py @@ -20,8 +20,8 @@ class NotificationWays(mongoengine.Document): notificationway_name = mongoengine.StringField() host_notification_period = mongoengine.StringField() service_notification_period = mongoengine.StringField() - host_notification_options = mongoengine.StringField() - service_notification_options = mongoengine.StringField() - host_notification_commands = mongoengine.StringField() - service_notification_commands = mongoengine.StringField() + host_notification_options = mongoengine.ListField() + service_notification_options = mongoengine.ListField() + host_notification_commands = mongoengine.ListField() + service_notification_commands = mongoengine.ListField() min_business_impact = mongoengine.IntField() \ No newline at end of file diff --git a/surveil/api/storage/mongodb/config/realm.py b/surveil/api/storage/mongodb/config/realm.py index b3cd05c..620c26a 100644 --- a/surveil/api/storage/mongodb/config/realm.py +++ b/surveil/api/storage/mongodb/config/realm.py @@ -17,6 +17,6 @@ import mongoengine class Realm(mongoengine.Document): meta = {'collection': 'realms'} - realm_name = mongoengine.StringField() - realm_members = mongoengine.StringField() - default = mongoengine.IntField() \ No newline at end of file + realm_name = mongoengine.StringField(unique=True) + realm_members = mongoengine.ListField() + default = mongoengine.IntField() diff --git a/surveil/api/storage/mongodb/config/service.py b/surveil/api/storage/mongodb/config/service.py index 77df377..8936bd7 100644 --- a/surveil/api/storage/mongodb/config/service.py +++ b/surveil/api/storage/mongodb/config/service.py @@ -20,9 +20,9 @@ class Service(mongoengine.Document): 'collection': 'services', 'strict': False } - host_name = mongoengine.StringField() + host_name = mongoengine.ListField() service_description = mongoengine.StringField() - contacts = mongoengine.StringField() + contacts = mongoengine.ListField() check_command = mongoengine.StringField() max_check_attempts = mongoengine.IntField() check_interval = mongoengine.IntField() @@ -30,8 +30,8 @@ class Service(mongoengine.Document): check_period = mongoengine.StringField() notification_interval = mongoengine.IntField() notification_period = mongoengine.StringField() - contact_groups = mongoengine.StringField() + contact_groups = mongoengine.ListField() passive_checks_enabled = mongoengine.StringField() - use = mongoengine.StringField() - name = mongoengine.StringField() - register = mongoengine.StringField() \ No newline at end of file + use = mongoengine.ListField() + name = mongoengine.StringField(unique=True, sparse=True) + register = mongoengine.StringField() diff --git a/surveil/api/storage/mongodb/config/servicegroup.py b/surveil/api/storage/mongodb/config/servicegroup.py index 4b63dc9..7de66e7 100644 --- a/surveil/api/storage/mongodb/config/servicegroup.py +++ b/surveil/api/storage/mongodb/config/servicegroup.py @@ -17,10 +17,10 @@ import mongoengine class ServiceGroup(mongoengine.Document): meta = {'collection': 'servicegroups'} - servicegroup_name = mongoengine.StringField() - members = mongoengine.StringField() + servicegroup_name = mongoengine.StringField(unique=True) + members = mongoengine.ListField() alias = mongoengine.StringField() - servicegroup_members = mongoengine.StringField() + servicegroup_members = mongoengine.ListField() notes = mongoengine.StringField() notes_url = mongoengine.StringField() - action_url = mongoengine.StringField() \ No newline at end of file + action_url = mongoengine.StringField() diff --git a/surveil/api/storage/mongodb/config/timeperiod.py b/surveil/api/storage/mongodb/config/timeperiod.py index b59e67d..ebedf25 100644 --- a/surveil/api/storage/mongodb/config/timeperiod.py +++ b/surveil/api/storage/mongodb/config/timeperiod.py @@ -20,3 +20,4 @@ class TimePeriod(mongoengine.Document): timeperiod_name = mongoengine.StringField() exclude = mongoengine.StringField() periods = mongoengine.DictField() + alias = mongoengine.StringField() diff --git a/surveil/cmd/init.py b/surveil/cmd/init.py index f93a63a..a15e6b8 100644 --- a/surveil/cmd/init.py +++ b/surveil/cmd/init.py @@ -15,7 +15,6 @@ """Script to reinitialize surveil.""" import optparse -import subprocess import sys import influxdb @@ -23,6 +22,7 @@ import pymongo import surveilclient.client as sc from surveil.api import config +from surveil.cmd import pack_upload def main(): @@ -49,6 +49,14 @@ def main(): action='store_true') opts, _ = parser.parse_args(sys.argv) + surveil_api_url = 'http://localhost:5311/v2' + surveil_auth_url = 'http://localhost:5311/v2/auth' + surveil_api_version = '2_0' + + cli_surveil = sc.Client(surveil_api_url, + auth_url=surveil_auth_url, + version=surveil_api_version) + # Create a basic config in mongodb mongo = pymongo.MongoClient(config.surveil_api_config['mongodb_uri']) @@ -71,73 +79,43 @@ def main(): if opts.packs: print ("Uploading packs...") # Load the shinken packs - subprocess.call( - [ - "surveil-pack-upload", - "--mongo-uri=" + config.surveil_api_config['mongodb_uri'], - "/usr/share/monitoring/packs/sfl/openstack-keystone-http/", - ] + pack_upload.upload_pack( + "/usr/share/monitoring/packs/sfl/openstack-keystone-http/", + cli_surveil ) - subprocess.call( - [ - "surveil-pack-upload", - "--mongo-uri=" + config.surveil_api_config['mongodb_uri'], - "/usr/share/monitoring/packs/sfl/openstack-glance-http/", - ] + pack_upload.upload_pack( + "/usr/share/monitoring/packs/sfl/openstack-glance-http/", + cli_surveil ) - - subprocess.call( - [ - "surveil-pack-upload", - "--mongo-uri=" + config.surveil_api_config['mongodb_uri'], - "/usr/share/monitoring/packs/sfl/generic-host/", - ] + pack_upload.upload_pack( + "/usr/share/monitoring/packs/sfl/generic-host/", + cli_surveil ) - - subprocess.call( - [ - "surveil-pack-upload", - "--mongo-uri=" + config.surveil_api_config['mongodb_uri'], - "/usr/share/monitoring/packs/sfl/linux-system-nrpe/", - ] + pack_upload.upload_pack( + "/usr/share/monitoring/packs/sfl/linux-system-nrpe/", + cli_surveil ) - - subprocess.call( - [ - "surveil-pack-upload", - "--mongo-uri=" + config.surveil_api_config['mongodb_uri'], - "/usr/share/monitoring/packs/sfl/openstack-nova-http/", - ] + pack_upload.upload_pack( + "/usr/share/monitoring/packs/sfl/openstack-nova-http/", + cli_surveil ) - - subprocess.call( - [ - "surveil-pack-upload", - "--mongo-uri=" + config.surveil_api_config['mongodb_uri'], - "/usr/share/monitoring/packs/sfl/openstack-cinder-http/", - ] + pack_upload.upload_pack( + "/usr/share/monitoring/packs/sfl/openstack-cinder-http/", + cli_surveil ) - - subprocess.call( - [ - "surveil-pack-upload", - "--mongo-uri=" + config.surveil_api_config['mongodb_uri'], - "/usr/share/monitoring/packs/sfl/openstack-host/", - ] + pack_upload.upload_pack( + "/usr/share/monitoring/packs/sfl/openstack-host/", + cli_surveil ) - cli_surveil = sc.Client('http://localhost:5311/v2', - auth_url='http://localhost:5311/v2/auth', - version='2_0') - # if --demo is specified, you get more hosts. if opts.demo is True: print("Creating demo configuration...") # shinken's ws-arbiter cli_surveil.config.hosts.create( - use="generic-host", - contact_groups="admins", + use=["generic-host"], + contact_groups=["admins"], host_name="ws-arbiter", address="localhost" ) @@ -145,9 +123,9 @@ def main(): check_command="check_tcp!7760", check_interval="5", check_period="24x7", - contact_groups="admins", - contacts="admin", - host_name="ws-arbiter", + contact_groups=["admins"], + contacts=["admin"], + host_name=["ws-arbiter"], max_check_attempts="5", notification_interval="30", notification_period="24x7", @@ -158,7 +136,7 @@ def main(): # Linux-keystone template cli_surveil.config.hosts.create( host_name='test_keystone', - use='openstack-keystone-http', + use=['openstack-keystone-http'], address='127.0.0.1', custom_fields={ "_OS_AUTH_URL": "bla", @@ -173,7 +151,7 @@ def main(): # openstack-host template cli_surveil.config.hosts.create( host_name='openstackceilometer-host', - use='openstack-host', + use=['openstack-host'], address='127.0.0.1', custom_fields={ "_OS_AUTH_URL": "bla", @@ -188,7 +166,7 @@ def main(): # DOWN HOST (cant resolve) cli_surveil.config.hosts.create( host_name='srv-apache-01', - use='linux-system-nrpe', + use=['linux-system-nrpe'], address='srv-apache-01', custom_fields={ "_TRAFFICLIMIT": "100000", @@ -199,7 +177,7 @@ def main(): cli_surveil.config.hosts.create( host_name='myparentisdown', address='dfgsdgsdgf', - parents='srv-apache-01', + parents=['srv-apache-01'], ) # UP host, no template @@ -211,7 +189,7 @@ def main(): # NRPE host, UP cli_surveil.config.hosts.create( host_name='srv-monitoring-01', - use='linux-system-nrpe', + use=['linux-system-nrpe'], address='127.0.0.1', custom_fields={ "_TRAFFICLIMIT": "500000", @@ -221,8 +199,8 @@ def main(): # Has parent, UP cli_surveil.config.hosts.create( host_name='sw-iwebcore-01', - parents='srv-monitoring-01', - use='generic-host', + parents=['srv-monitoring-01'], + use=['generic-host'], address='127.0.0.1', custom_fields={ "_TRAFFICLIMIT": "200000", @@ -232,8 +210,8 @@ def main(): # Has chain of 2 parents, UP cli_surveil.config.hosts.create( host_name='srv-ldap-01', - parents='sw-iwebcore-01', - use='generic-host', + parents=['sw-iwebcore-01'], + use=['generic-host'], address='127.0.0.1', custom_fields={ "_TRAFFICLIMIT": "5000000", @@ -242,8 +220,8 @@ def main(): # UP host with down service cli_surveil.config.hosts.create( - use="generic-host", - contact_groups="admins", + use=["generic-host"], + contact_groups=["admins"], host_name="myserviceisdown", address="localhost" ) @@ -251,9 +229,9 @@ def main(): check_command="check_tcp!4553", check_interval="5", check_period="24x7", - contact_groups="admins", - contacts="admin", - host_name="myserviceisdown", + contact_groups=["admins"], + contacts=["admin"], + host_name=["myserviceisdown"], max_check_attempts="5", notification_interval="30", notification_period="24x7", diff --git a/surveil/cmd/pack_upload.py b/surveil/cmd/pack_upload.py index b34d419..f7357fb 100644 --- a/surveil/cmd/pack_upload.py +++ b/surveil/cmd/pack_upload.py @@ -1,27 +1,25 @@ # Copyright 2014 - Savoir-Faire Linux inc. # -# This program 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. +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at # -# 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. +# http://www.apache.org/licenses/LICENSE-2.0 # -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see ``. +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. """Script to push a Shinken pack to Surveil""" import argparse -import fnmatch -import os import sys -from pymongo import mongo_client -from alignak.objects import config +import surveilclient.client as sc + +from surveil.cmd import surveil_from_nagios def main(): @@ -30,56 +28,37 @@ def main(): prog='surveil-pack-upload', add_help=False, ) - parser.add_argument('--mongo-uri', - default='mongodb://localhost:27017', - help='Defaults to localhost', type=str) - parser.add_argument('pack', metavar='[Pack]', type=str, nargs=1, + parser.add_argument('--surveil_api_url', + default='http://localhost:5311/v2', + type=str) + parser.add_argument('--surveil_auth_url', + default='http://localhost:5311/v2/auth', + type=str) + parser.add_argument('--surveil_api_version', + default='2_0', + type=str) + parser.add_argument('pack', + metavar='[Pack]', + type=str, + nargs=1, help='Pack directory') (options, args) = parser.parse_known_args(sys.argv[1:]) - pack_dir = options.pack[0] - pack_name = os.path.basename(os.path.normpath(pack_dir)) + cli_surveil = sc.Client(options.surveil_api_url, + auth_url=options.surveil_auth_url, + version=options.surveil_api_version) - # Find the .cfg files - cfg_files = [ - os.path.join(dirpath, f) - for dirpath, dirnames, files in os.walk(pack_dir) - for f in fnmatch.filter(files, '*.cfg') - ] + upload_pack(options.pack[0], cli_surveil) - # Load the config - conf = config.Config() - loaded_conf = conf.read_config(cfg_files) - raw_objects = conf.read_config_buf(loaded_conf) - # Remove the empty items - non_empty_config = {k: v for k, v in raw_objects.items() if v} +def upload_pack(pack_dir, client): + # pack_name = os.path.basename(os.path.normpath(pack_dir)) - for config_type in non_empty_config: - for config_item in non_empty_config[config_type]: - # Tag the config objects - config_item['SURVEIL_PACK_NAME'] = pack_name + surveil_config = surveil_from_nagios.load_config(pack_dir) - # Replace lists with csv - items_to_modify = ( - [i for i in config_item.items() if isinstance(i[1], list)] - ) - for i in items_to_modify: - config_item[i[0]] = ','.join(i[1]) - - # Remove the existing pack from mongodb - mongo = mongo_client.MongoClient(options.mongo_uri) - mongo_shinken = mongo.shinken - for collection in ( - [c for c - in mongo_shinken.collection_names() - if not c.startswith("system.")] - ): - mongo_shinken[collection].remove({'SURVEIL_PACK_NAME': pack_name}) - - # Add the replacement pack - for config_type in non_empty_config: - mongo_shinken[config_type + 's'].insert( - non_empty_config[config_type] - ) + config_manager = client.config + for object_type, objects in surveil_config.items(): + object_manager = getattr(config_manager, object_type) + for object in objects: + object_manager.create(**object) diff --git a/surveil/cmd/surveil_from_nagios.py b/surveil/cmd/surveil_from_nagios.py new file mode 100644 index 0000000..a998def --- /dev/null +++ b/surveil/cmd/surveil_from_nagios.py @@ -0,0 +1,226 @@ +# Copyright 2014 - Savoir-Faire Linux inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +from __future__ import print_function + +import argparse +import fnmatch +import json +import os +import re +import sys + +import six +import wsme + +from surveil.api.datamodel.config import businessimpactmodulation +from surveil.api.datamodel.config import checkmodulation +from surveil.api.datamodel.config import command +from surveil.api.datamodel.config import contact +from surveil.api.datamodel.config import contactgroup +from surveil.api.datamodel.config import host +from surveil.api.datamodel.config import hostgroup +from surveil.api.datamodel.config import macromodulation +from surveil.api.datamodel.config import notificationway +from surveil.api.datamodel.config import realm +from surveil.api.datamodel.config import service +from surveil.api.datamodel.config import servicegroup +from surveil.api.datamodel.config import timeperiod + + +def main(): + # Parse the arguments + parser = argparse.ArgumentParser(add_help=False) + + parser.add_argument( + 'path', + metavar='[path]', + type=str, + nargs=1, + help='Configuration path' + ) + + (options, args) = parser.parse_known_args(sys.argv[1:]) + + pack_dir = options.path[0] + + surveil_config = load_config(pack_dir) + + print(json.dumps(surveil_config, indent=4, sort_keys=True)) + + +def load_config(path): + """From a directory, returns Surveil configuration""" + + if os.path.isdir(path): + # Find the .cfg files + cfg_files = [ + os.path.join(dirpath, f) + for dirpath, dirnames, files in os.walk(path) + for f in fnmatch.filter(files, '*.cfg') + ] + else: + cfg_files = [path] + + nagios_config = {} + + for cfg_file in cfg_files: + # Open the file + f = open(cfg_file, 'r') + config_string = f.read() + f.close() + + # Load the config + file_config = _load_nagios_config(config_string) + + # Append to the loaded config + for object_type, objects in file_config.items(): + nagios_config[object_type] = nagios_config.get( + object_type, + [] + ) + objects + + surveil_config = _transform_config(nagios_config) + + return surveil_config + + +def _load_nagios_config(config_string): + """Given a nagios configuration string, returns a python dict""" + config = {} + + # Find all config objects + config_objects = re.finditer( + r'define\s(?P\w*)\s*{(?P[^{}]*)}', + config_string + ) + + # For each object in the file... + for object_match in config_objects: + object_type = object_match.group("object_type") + + config_object = {} + + # For each property of the object... + for property_match in re.finditer( + r'(?P[^\s]+)\s*(?P.*?)\s*\n', + object_match.group("object_properties") + ): + + config_object[ + property_match.group('property') + ] = property_match.group('value') + + # Append the config object + config[object_type + 's'] = config.get( + object_type + 's', [] + ) + [config_object] + + return config + + +def _transform_config(nagios_config): + """Given a nagios config dict, returns surveil configuration""" + transformed_config = {} + + for object_type, objects in nagios_config.items(): + for config_object in objects: + + # PROPERTY NAMES TRANSFORMATIONS + name_transformed_obj = _transform_property_names( + config_object, + object_type + ) + + # PROPERTY TYPES TRANSORMATIONS + type_transformed_obj = _transform_property_types( + name_transformed_obj, + object_type + ) + + transformed_config[object_type] = transformed_config.get( + object_type, + [] + ) + [type_transformed_obj] + + return transformed_config + + +def _transform_property_types(config_object, object_type): + transformed_object = {} + + datamodels = { + "businessimpactmodulations": businessimpactmodulation.BusinessImpactModulation, + "checkmodulations": checkmodulation.CheckModulation, + "commands": command.Command, + "contacts": contact.Contact, + "contactgroups": contactgroup.ContactGroup, + "hosts": host.Host, + "hostgroups": hostgroup.HostGroup, + "macromodulations": macromodulation.MacroModulation, + "notificationways": notificationway.NotificationWay, + "realms": realm.Realm, + "services": service.Service, + "servicegroups": servicegroup.ServiceGroup, + "timeperiods": timeperiod.TimePeriod, + } + object_datamodel = datamodels[object_type] + object_wsmeattrs = object_datamodel._wsme_attributes + for attribute in object_wsmeattrs: + + if attribute.name in config_object: + # COMMA-SEPARATED => List + if isinstance(attribute._get_datatype(), wsme.types.ArrayType): + transformed_object[attribute.name] = config_object[attribute.name].split(',') + # Integers + elif attribute._get_datatype() in six.integer_types: + transformed_object[attribute.name] = int(config_object[attribute.name]) + # Strings + else: + transformed_object[attribute.name] = config_object[attribute.name] + + return transformed_object + + +def _transform_property_names(config_object, object_type): + transformed_object = {} + + # HOSTS + if object_type in ['hosts', 'services']: + transformed_object['custom_fields'] = {} + for property, value in config_object.items(): + if property.startswith('_'): + transformed_object['custom_fields'][property] = value + else: + transformed_object[property] = value + # TIMEPERIODS + elif object_type == 'timeperiods': + transformed_object['periods'] = {} + properties = [p.name for p in timeperiod.TimePeriod._wsme_attributes] + for property, value in config_object.items(): + if property not in properties: + transformed_object['periods'][property] = value + else: + transformed_object[property] = value + # OTHER OBJECTS + else: + for property, value in config_object.items(): + transformed_object[property] = value + return transformed_object + + +if __name__ == "__main__": + main() + + diff --git a/surveil/tests/api/controllers/v2/config/test_contactgroup.py b/surveil/tests/api/controllers/v2/config/test_contactgroup.py index a5284a7..051d943 100644 --- a/surveil/tests/api/controllers/v2/config/test_contactgroup.py +++ b/surveil/tests/api/controllers/v2/config/test_contactgroup.py @@ -27,11 +27,13 @@ class TestContactGroupsController(functionalTest.FunctionalTest): self.groups = [ { 'contactgroup_name': 'novell-admins', - 'members': 'jdoe,rtobert,tzach', + 'members': ["jdoe", "rtobert", "tzach"], + 'contactgroup_members': [] }, { 'contactgroup_name': 'linux-adminx', - 'members': 'linus,richard', + 'members': ['linus', 'richard'], + 'contactgroup_members': [] }, ] self.mongoconnection.shinken.contactgroups.insert( @@ -58,7 +60,7 @@ class TestContactGroupsController(functionalTest.FunctionalTest): def test_create_contactgroup(self): g = contactgroup.ContactGroup( contactgroup_name='John', - members="marie,bob,joe", + members=["marie", "bob", "joe"], ) self.post_json('/v2/config/contactgroups', g.as_dict()) @@ -83,18 +85,18 @@ class TestContactGroupsController(functionalTest.FunctionalTest): self.mongoconnection.shinken.contactgroups.find_one( {'contactgroup_name': 'novell-admins'} )['members'], - 'jdoe,rtobert,tzach' + ['jdoe', 'rtobert', 'tzach'] ) self.put_json( '/v2/config/contactgroups/novell-admins', {"contactgroup_name": "novell-admins", - "members": "updated"} + "members": ["updated"]} ) self.assertEqual( self.mongoconnection.shinken.contactgroups.find_one( {'contactgroup_name': 'novell-admins'} )['members'], - 'updated' + ['updated'] ) diff --git a/surveil/tests/api/controllers/v2/config/test_contacts.py b/surveil/tests/api/controllers/v2/config/test_contacts.py index 3522bec..5510668 100644 --- a/surveil/tests/api/controllers/v2/config/test_contacts.py +++ b/surveil/tests/api/controllers/v2/config/test_contacts.py @@ -27,11 +27,19 @@ class TestContactsController(functionalTest.FunctionalTest): self.contacts = [ { 'contact_name': 'bobby', - 'email': 'bob@bob.com' + 'email': 'bob@bob.com', + 'service_notification_options': [], + 'service_notification_commands': [], + 'host_notification_options': [], + 'host_notification_commands': [] }, { 'contact_name': 'marie', - 'email': 'marie@marie.com' + 'email': 'marie@marie.com', + 'service_notification_options': [], + 'service_notification_commands': [], + 'host_notification_options': [], + 'host_notification_commands': [] }, ] self.mongoconnection.shinken.contacts.insert( diff --git a/surveil/tests/api/controllers/v2/config/test_hostgroup.py b/surveil/tests/api/controllers/v2/config/test_hostgroup.py index 11fc9d3..ab5fedd 100644 --- a/surveil/tests/api/controllers/v2/config/test_hostgroup.py +++ b/surveil/tests/api/controllers/v2/config/test_hostgroup.py @@ -27,11 +27,13 @@ class TestHostGroupsController(functionalTest.FunctionalTest): self.groups = [ { 'hostgroup_name': 'novell-servers', - 'members': 'netware1,netware2,netware3,netware4', + 'members': ['netware1', 'netware2', 'netware3', 'netware4'], + 'hostgroup_members': [] }, { 'hostgroup_name': 'otherservers', - 'members': 'googul,sfl', + 'members': ['googul', 'sfl'], + 'hostgroup_members': [] }, ] self.mongoconnection.shinken.hostgroups.insert( @@ -58,7 +60,7 @@ class TestHostGroupsController(functionalTest.FunctionalTest): def test_create_hostgroup(self): s = hostgroup.HostGroup( hostgroup_name='John', - members="marie,bob,joe", + members=['marie', 'bob', 'joe'], ) self.post_json('/v2/config/hostgroups', s.as_dict()) @@ -83,18 +85,18 @@ class TestHostGroupsController(functionalTest.FunctionalTest): self.mongoconnection.shinken.hostgroups.find_one( {'hostgroup_name': 'novell-servers'} )['members'], - 'netware1,netware2,netware3,netware4' + ['netware1', 'netware2', 'netware3', 'netware4'] ) self.put_json( '/v2/config/hostgroups/novell-servers', {"hostgroup_name": "novell-servers", - "members": "updated"} + "members": ["updated"]} ) self.assertEqual( self.mongoconnection.shinken.hostgroups.find_one( {'hostgroup_name': 'novell-servers'} )['members'], - 'updated' + ['updated'] ) diff --git a/surveil/tests/api/controllers/v2/config/test_hosts.py b/surveil/tests/api/controllers/v2/config/test_hosts.py index 6400990..861d527 100644 --- a/surveil/tests/api/controllers/v2/config/test_hosts.py +++ b/surveil/tests/api/controllers/v2/config/test_hosts.py @@ -26,25 +26,41 @@ class TestHostController(functionalTest.FunctionalTest): super(TestHostController, self).setUp() self.hosts = [ { - "host_name": "bogus-router", "address": "192.168.1.254", - "max_check_attempts": 5, "check_period": "24x7", - "contacts": "admin,carl", "contact_groups": "router-admins", - "notification_interval": 30, "notification_period": "24x7", - "custom_fields": {} + "host_name": "bogus-router", + "address": "192.168.1.254", + "max_check_attempts": 5, + "check_period": "24x7", + "contacts": ["admin", "carl"], + "contact_groups": ["router-admins"], + "notification_interval": 30, + "notification_period": "24x7", + "custom_fields": {}, + "use": [] }, { - "host_name": "bogus-router2", "address": "192.168.1.254", - "max_check_attempts": 5, "check_period": "24x7", - "contacts": "admin,carl", "contact_groups": "router-admins", - "notification_interval": 30, "notification_period": "24x7", - "custom_fields": {} + "host_name": "bogus-router2", + "address": "192.168.1.254", + "max_check_attempts": 5, + "check_period": "24x7", + "contacts": ["admin", "carl"], + "contact_groups": ["router-admins"], + "notification_interval": 30, + "notification_period": "24x7", + "custom_fields": {}, + "use": [] }, { - "host_name": "bogus-router333", "address": "192.168.1.254", - "max_check_attempts": 5, "check_period": "24x7", - "contacts": "admin,carl", "contact_groups": "router-admins", - "notification_interval": 30, "notification_period": "24x7", - 'use': 'test', "custom_fields": {} + "host_name": "bogus-router333", + "address": "192.168.1.254", + "max_check_attempts": 5, + "check_period": "24x7", + "contacts": ["admin", "carl"], + "contact_groups": ["router-admins"], + "notification_interval": 30, + "notification_period": "24x7", + 'use': ['test'], + "custom_fields": {}, + "use": [] }, ] self.mongoconnection.shinken.hosts.insert( @@ -53,7 +69,7 @@ class TestHostController(functionalTest.FunctionalTest): self.services = [ { - "host_name": "bogus-router", + "host_name": ["bogus-router"], "service_description": "service-example", "check_command": "check-disk!/dev/sdb1", "max_check_attempts": 5, @@ -62,8 +78,9 @@ class TestHostController(functionalTest.FunctionalTest): "check_period": "24x7", "notification_interval": 30, "notification_period": "24x7", - "contacts": "surveil-ptl,surveil-bob", - "contact_groups": "linux-admins" + "contacts": ["surveil-ptl", "surveil-bob"], + "contact_groups": ["linux-admins"], + "use": [] } ] self.mongoconnection.shinken.services.insert( @@ -82,11 +99,17 @@ class TestHostController(functionalTest.FunctionalTest): def test_get_all_hosts_templates(self): self.mongoconnection.shinken.hosts.insert( copy.deepcopy( - {"host_name": "bogus-router345345", "address": "192.168.1.254", - "max_check_attempts": 5, "check_period": "24x7", - "contacts": "admin,carl", "contact_groups": "router-admins", - "notification_interval": 30, "notification_period": "24x7", - "register": "0", "custom_fields": {}} + {"host_name": "bogus-router345345", + "address": "192.168.1.254", + "max_check_attempts": 5, + "check_period": "24x7", + "contacts": ["admin", "carl"], + "contact_groups": ["router-admins"], + "notification_interval": 30, + "notification_period": "24x7", + "register": "0", + "custom_fields": {}, + "use": []} ) ) response = self.get('/v2/config/hosts') @@ -116,7 +139,7 @@ class TestHostController(functionalTest.FunctionalTest): def test_update_host(self): put_host = { u'host_name': u'bogus-router333', - u'contacts': u'newcontacts', + u'contacts': [u'newcontacts'], } response = self.put_json( "/v2/config/hosts/bogus-router333", params=put_host @@ -132,12 +155,12 @@ class TestHostController(functionalTest.FunctionalTest): 'address': u'192.168.1.254', 'check_period': u'24x7', 'notification_interval': 30, - 'contacts': u'newcontacts', + 'contacts': [u'newcontacts'], 'notification_period': u'24x7', - 'contact_groups': u'router-admins', + 'contact_groups': [u'router-admins'], 'host_name': u'bogus-router333', 'max_check_attempts': 5, - 'use': u'test', + 'use': [], 'custom_fields': {}, } @@ -159,11 +182,12 @@ class TestHostController(functionalTest.FunctionalTest): "address": "192.168.1.254", "max_check_attempts": 5, "check_period": "24x7", - "contacts": "admin,carl", - "contact_groups": "router-admins", + "contacts": ["admin", "carl"], + "contact_groups": ["router-admins"], "notification_interval": 3, "notification_period": "24x7", - "custom_fields": {} + "custom_fields": {}, + "use": [] } response = self.post_json("/v2/config/hosts", params=new_host) diff --git a/surveil/tests/api/controllers/v2/config/test_notificationways.py b/surveil/tests/api/controllers/v2/config/test_notificationways.py index 91f8d73..eeb980e 100644 --- a/surveil/tests/api/controllers/v2/config/test_notificationways.py +++ b/surveil/tests/api/controllers/v2/config/test_notificationways.py @@ -28,19 +28,19 @@ class TestNotificationWayController(functionalTest.FunctionalTest): 'notificationway_name': 'email_in_day', 'host_notification_period': '24x7', 'service_notification_period': '24x7', - 'host_notification_options': 'd,u', - 'service_notification_options': 'w,c,r', - 'host_notification_commands': 'notify-service', - 'service_notification_commands': 'notify-host' + 'host_notification_options': ['d', 'u'], + 'service_notification_options': ['w', 'c', 'r'], + 'host_notification_commands': ['notify-service'], + 'service_notification_commands': ['notify-host'] }, { 'notificationway_name': 'email_all_time', 'host_notification_period': '24x7', 'service_notification_period': '24x7', - 'host_notification_options': 'd,r,f,u', - 'service_notification_options': 'w,f,c,r', - 'host_notification_commands': 'notify-service', - 'service_notification_commands': 'notify-host', + 'host_notification_options': ['d', 'r', 'f', 'u'], + 'service_notification_options': ['w', 'f', 'c', 'r'], + 'host_notification_commands': ['notify-service'], + 'service_notification_commands': ['notify-host'], 'min_business_impact': 5 } ] @@ -58,19 +58,19 @@ class TestNotificationWayController(functionalTest.FunctionalTest): 'notificationway_name': 'email_in_day', 'host_notification_period': '24x7', 'service_notification_period': '24x7', - 'host_notification_options': 'd,u', - 'service_notification_options': 'w,c,r', - 'host_notification_commands': 'notify-service', - 'service_notification_commands': 'notify-host' + 'host_notification_options': ['d', 'u'], + 'service_notification_options': ['w', 'c', 'r'], + 'host_notification_commands': ['notify-service'], + 'service_notification_commands': ['notify-host'] }, { 'notificationway_name': 'email_all_time', 'host_notification_period': '24x7', 'service_notification_period': '24x7', - 'host_notification_options': 'd,r,f,u', - 'service_notification_options': 'w,f,c,r', - 'host_notification_commands': 'notify-service', - 'service_notification_commands': 'notify-host', + 'host_notification_options': ['d', 'r', 'f', 'u'], + 'service_notification_options': ['w', 'f', 'c', 'r'], + 'host_notification_commands': ['notify-service'], + 'service_notification_commands': ['notify-host'], 'min_business_impact': 5 } ] @@ -86,10 +86,10 @@ class TestNotificationWayController(functionalTest.FunctionalTest): 'notificationway_name': 'email_all_time', 'host_notification_period': '24x7', 'service_notification_period': '24x7', - 'host_notification_options': 'd,r,f,u', - 'service_notification_options': 'w,f,c,r', - 'host_notification_commands': 'notify-service', - 'service_notification_commands': 'notify-host', + 'host_notification_options': ['d', 'r', 'f', 'u'], + 'service_notification_options': ['w', 'f', 'c', 'r'], + 'host_notification_commands': ['notify-service'], + 'service_notification_commands': ['notify-host'], 'min_business_impact': 5 } ) @@ -99,10 +99,10 @@ class TestNotificationWayController(functionalTest.FunctionalTest): 'notificationway_name': 'test_create_notification', 'host_notification_period': '24x7', 'service_notification_period': '24x7', - 'host_notification_options': 'd,r,f,u', - 'service_notification_options': 'w,f,c,r', - 'host_notification_commands': 'notify-service', - 'service_notification_commands': 'notify-host', + 'host_notification_options': ['d', 'r', 'f', 'u'], + 'service_notification_options': ['w', 'f', 'c', 'r'], + 'host_notification_commands': ['notify-service'], + 'service_notification_commands': ['notify-host'], 'min_business_impact': 5 } @@ -146,10 +146,10 @@ class TestNotificationWayController(functionalTest.FunctionalTest): 'notificationway_name': 'email_all_time', 'host_notification_period': '24x7', 'service_notification_period': '24x7', - 'host_notification_options': 'd,r,f,u', - 'service_notification_options': 'w,f,c,r', - 'host_notification_commands': 'notify-service', - 'service_notification_commands': 'notify-host', + 'host_notification_options': ['d', 'r', 'f', 'u'], + 'service_notification_options': ['w', 'f', 'c', 'r'], + 'host_notification_commands': ['notify-service'], + 'service_notification_commands': ['notify-host'], 'min_business_impact': 3 } ) @@ -157,6 +157,6 @@ class TestNotificationWayController(functionalTest.FunctionalTest): self.assertEqual( self.mongoconnection.shinken.notificationways.find_one( {'notificationway_name': 'email_all_time'} - )['min_business_impact'], + )['min_business_impact'], 3 ) diff --git a/surveil/tests/api/controllers/v2/config/test_realms.py b/surveil/tests/api/controllers/v2/config/test_realms.py index e3aecd3..65a6851 100644 --- a/surveil/tests/api/controllers/v2/config/test_realms.py +++ b/surveil/tests/api/controllers/v2/config/test_realms.py @@ -27,12 +27,12 @@ class TestRealmsController(functionalTest.FunctionalTest): self.realms = [ { 'realm_name': 'World', - 'realm_members': 'Europe,America,Asia', + 'realm_members': ['Europe', 'America', 'Asia'], 'default': 0 }, { 'realm_name': 'Anti-world', - 'realm_members': 'void,black-hole', + 'realm_members': ['void', 'black-hole'], 'default': 1 }, ] @@ -60,7 +60,7 @@ class TestRealmsController(functionalTest.FunctionalTest): def test_create_realm(self): r = realm.Realm( realm_name='John', - realm_members="marie,bob,joe", + realm_members=['marie', 'bob', 'joe'], default=1 ) @@ -86,13 +86,13 @@ class TestRealmsController(functionalTest.FunctionalTest): self.mongoconnection.shinken.realms.find_one( {'realm_name': 'World'} )['realm_members'], - 'Europe,America,Asia' + ['Europe', 'America', 'Asia'] ) self.put_json( '/v2/config/realms/World', {"realm_name": "World", - "realm_members": "updated", + "realm_members": ["updated"], "default": 0} ) @@ -100,5 +100,5 @@ class TestRealmsController(functionalTest.FunctionalTest): self.mongoconnection.shinken.realms.find_one( {'realm_name': 'World'} )['realm_members'], - 'updated' + ['updated'] ) diff --git a/surveil/tests/api/controllers/v2/config/test_servicegroup.py b/surveil/tests/api/controllers/v2/config/test_servicegroup.py index 3be9a6d..ced5280 100644 --- a/surveil/tests/api/controllers/v2/config/test_servicegroup.py +++ b/surveil/tests/api/controllers/v2/config/test_servicegroup.py @@ -27,11 +27,20 @@ class TestServiceGroupsController(functionalTest.FunctionalTest): self.groups = [ { 'servicegroup_name': 'dbservices', - 'members': 'ms1,SQL Server,ms1,SQL Serverc Agent,ms1,SQL DTC', + 'members': ['ms1', + 'SQL Server', + 'ms1', + 'SQL Serverc Agent', + 'ms1', + 'SQL DTC'], + 'servicegroup_members': [] }, { 'servicegroup_name': 'otherservices', - 'members': 'some,other,member', + 'members': ['some', + 'other', + 'member'], + 'servicegroup_members': [] }, ] self.mongoconnection.shinken.servicegroups.insert( @@ -58,7 +67,7 @@ class TestServiceGroupsController(functionalTest.FunctionalTest): def test_create_servicegroup(self): s = servicegroup.ServiceGroup( servicegroup_name='John', - members="marie,bob,joe", + members=['marie', 'bob', 'joe'], ) self.post_json('/v2/config/servicegroups', s.as_dict()) @@ -83,18 +92,23 @@ class TestServiceGroupsController(functionalTest.FunctionalTest): self.mongoconnection.shinken.servicegroups.find_one( {'servicegroup_name': 'dbservices'} )['members'], - 'ms1,SQL Server,ms1,SQL Serverc Agent,ms1,SQL DTC' + ['ms1', + 'SQL Server', + 'ms1', + 'SQL Serverc Agent', + 'ms1', + 'SQL DTC'] ) self.put_json( '/v2/config/servicegroups/dbservices', {"servicegroup_name": "dbservices", - "members": "updated"} + "members": ["updated"]} ) self.assertEqual( self.mongoconnection.shinken.servicegroups.find_one( {'servicegroup_name': 'dbservices'} )['members'], - 'updated' + ['updated'] ) diff --git a/surveil/tests/api/controllers/v2/config/test_services.py b/surveil/tests/api/controllers/v2/config/test_services.py index 974cf24..3d66790 100644 --- a/surveil/tests/api/controllers/v2/config/test_services.py +++ b/surveil/tests/api/controllers/v2/config/test_services.py @@ -25,7 +25,7 @@ class TestServiceController(functionalTest.FunctionalTest): super(TestServiceController, self).setUp() self.services = [ { - "host_name": "sample-server1", + "host_name": ["sample-server1"], "service_description": "check-", "check_command": "check-disk!/dev/sdb1", "max_check_attempts": 5, @@ -34,12 +34,13 @@ class TestServiceController(functionalTest.FunctionalTest): "check_period": "24x7", "notification_interval": 30, "notification_period": "24x7", - "contacts": "surveil-ptl,surveil-bob", - "contact_groups": "linux-admins" + "contacts": ["surveil-ptl", "surveil-bob"], + "contact_groups": ["linux-admins"], + "use": [] }, { - "host_name": "sample-server2", - "service_description": "check-disk-sdb", + "host_name": ["sample-server2"], + "service_description": "check-disk-sdb2", "check_command": "check-disk!/dev/sdb1", "max_check_attempts": 5, "check_interval": 5, @@ -47,12 +48,13 @@ class TestServiceController(functionalTest.FunctionalTest): "check_period": "24x7", "notification_interval": 30, "notification_period": "24x7", - "contacts": "surveil-ptl,surveil-bob", - "contact_groups": "linux-admins" + "contacts": ["surveil-ptl", "surveil-bob"], + "contact_groups": ["linux-admins"], + "use": [] }, { - "host_name": "sample-server3", - "service_description": "check-disk-sdb", + "host_name": ["sample-server3"], + "service_description": "check-disk-sdb3", "check_command": "check-disk!/dev/sdb1", "max_check_attempts": 5, "check_interval": 5, @@ -60,8 +62,9 @@ class TestServiceController(functionalTest.FunctionalTest): "check_period": "24x7", "notification_interval": 30, "notification_period": "24x7", - "contacts": "surveil-ptl,surveil-bob", - "contact_groups": "linux-admins" + "contacts": ["surveil-ptl", "surveil-bob"], + "contact_groups": ["linux-admins"], + "use": [] }, ] self.mongoconnection.shinken.services.insert( @@ -80,8 +83,8 @@ class TestServiceController(functionalTest.FunctionalTest): def test_get_all_services_templates(self): self.mongoconnection.shinken.services.insert( copy.deepcopy( - {"host_name": "sample-server444", - "service_description": "check-disk-sdb", + {"host_name": ["sample-server444"], + "service_description": "check-disk-sdb2", "check_command": "check-disk!/dev/sdb1", "max_check_attempts": 5, "check_interval": 5, @@ -89,9 +92,9 @@ class TestServiceController(functionalTest.FunctionalTest): "check_period": "24x7", "notification_interval": 30, "notification_period": "24x7", - "contacts": "surveil-ptl,surveil-bob", + "contacts": ["surveil-ptl", "surveil-bob"], "register": "0", - "contact_groups": "linux-admins"} + "contact_groups": ["linux-admins"]} ) ) response = self.get('/v2/config/services') @@ -112,7 +115,7 @@ class TestServiceController(functionalTest.FunctionalTest): def test_add_service(self): new_service = { - "host_name": "SOMEHOSTNAME", + "host_name": ["SOMEHOSTNAME"], "service_description": "check-new-thing", "check_command": "check-disk!/dev/sdb1", "max_check_attempts": 5, @@ -121,8 +124,9 @@ class TestServiceController(functionalTest.FunctionalTest): "check_period": "24x7", "notification_interval": 30, "notification_period": "24x7", - "contacts": "surveil-ptl,surveil-bob", - "contact_groups": "linux-admins" + "contacts": ["surveil-ptl", "surveil-bob"], + "contact_groups": ["linux-admins"], + "use": [] } response = self.post_json( "/v2/config/services", diff --git a/surveil/tests/cmd/__init__.py b/surveil/tests/cmd/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/surveil/tests/cmd/nagios_config/config.cfg b/surveil/tests/cmd/nagios_config/config.cfg new file mode 100644 index 0000000..547f926 --- /dev/null +++ b/surveil/tests/cmd/nagios_config/config.cfg @@ -0,0 +1,23 @@ + define host{ + use generic-host + contact_groups admins + host_name localhost + address localhost + _custom_yolo sdfsdf + check_interval 324 + } + + define service { + host_name test + } + + define timeperiod{ + timeperiod_name workhours + alias Normal Work Hours + monday 09:00-17:00 + tuesday 09:00-17:00 + wednesday 09:00-17:00 + thursday 09:00-17:00 + friday 09:00-17:00 + } + diff --git a/surveil/tests/cmd/nagios_config/other_file.cfg b/surveil/tests/cmd/nagios_config/other_file.cfg new file mode 100644 index 0000000..e91ae1e --- /dev/null +++ b/surveil/tests/cmd/nagios_config/other_file.cfg @@ -0,0 +1,3 @@ + define service { + host_name hai + } \ No newline at end of file diff --git a/surveil/tests/cmd/test_surveil_from_nagios.py b/surveil/tests/cmd/test_surveil_from_nagios.py new file mode 100644 index 0000000..ddff8c6 --- /dev/null +++ b/surveil/tests/cmd/test_surveil_from_nagios.py @@ -0,0 +1,92 @@ +# Copyright 2014 - Savoir-Faire Linux inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +import os + +from surveil.cmd import surveil_from_nagios +from surveil.tests import base as base_test + + +class TestSurveilFromNagios(base_test.BaseTestCase): + + def setUp(self): + self.nagios_config_folder = os.path.join( + os.path.dirname(os.path.abspath(__file__)), + 'nagios_config' + ) + + def test_surveil_from_nagios_config_cfg(self): + surveil_cfg = surveil_from_nagios.load_config( + self.nagios_config_folder + ) + + self.assert_count_equal_backport( + surveil_cfg, + { + 'hosts': [ + { + 'custom_fields': {'_custom_yolo': 'sdfsdf'}, + 'contact_groups': [ + 'admins' + ], + 'use': [ + 'generic-host' + ], + 'host_name': 'localhost', + 'check_interval': 324, + 'address': 'localhost'} + ], + 'services': [ + { + 'host_name': [ + 'hai' + ] + }, + { + 'host_name': [ + 'test' + ] + } + ], + 'timeperiods': [ + { + 'timeperiod_name': 'workhours', + 'alias': 'Normal Work Hours', + 'periods': + { + 'friday': '09:00-17:00', + 'monday': '09:00-17:00', + 'thursday': '09:00-17:00', + 'tuesday': '09:00-17:00', + 'wednesday': '09:00-17:00' + } + } + ] + } + ) + + def test_load_single_file(self): + other_file_path = os.path.join( + self.nagios_config_folder, + 'other_file.cfg' + ) + + single_file_config = surveil_from_nagios.load_config( + other_file_path + ) + + self.assertEqual( + single_file_config, + {'services': [{'host_name': ['hai']}]} + ) \ No newline at end of file diff --git a/tools/docker/alignak_container/Dockerfile b/tools/docker/alignak_container/Dockerfile index 3dc3d08..568010f 100644 --- a/tools/docker/alignak_container/Dockerfile +++ b/tools/docker/alignak_container/Dockerfile @@ -34,7 +34,7 @@ RUN cd /tmp && \ # mod-surveil RUN pip install python-surveilclient==0.11.0 RUN cd /tmp && \ - wget -O mod-surveil-config.tar.gz https://github.com/Alignak-monitoring/mod-surveil/archive/8d7e37333de85f5e90d6fe1780e55e4d90515a2f.tar.gz && \ + wget -O mod-surveil-config.tar.gz https://github.com/Alignak-monitoring/mod-surveil/archive/fdc98b4fc036aa483ecb58459f11f9a87cf2254a.tar.gz && \ tar -zxvf mod-surveil-config.tar.gz && \ mv /tmp/mod-surveil-*/alignak/modules/mod_surveil /var/lib/alignak/modules/mod-surveil && \ rm -rfv /tmp/mod-surveil* diff --git a/tox.ini b/tox.ini index 8cf7740..19c8816 100644 --- a/tox.ini +++ b/tox.ini @@ -30,5 +30,5 @@ commands = {posargs} commands = python setup.py build_sphinx [flake8] -exclude = .venv,.git,.tox,env,dist,*openstack/common*,*lib/python*/,*egg,build,*doc/conf.py,surveil/cmd/pack_upload.py +exclude = .venv,.git,.tox,env,dist,*openstack/common*,*lib/python*/,*egg,build,*doc/conf.py,surveil/cmd/pack_upload.py,surveil/cmd/surveil_from_nagios.py