From fad7ef331fd07baeae3fceb0b321fd56399bb3cb Mon Sep 17 00:00:00 2001 From: aviau Date: Tue, 7 Jul 2015 18:10:58 -0400 Subject: [PATCH] Introduce MongoEngine Change-Id: Iaad35fa5e1e4134d07c5fb92c60f874a8b77a7f5 --- requirements.txt | 1 + .../v2/config/businessimpactmodulations.py | 13 ++- .../controllers/v2/config/checkmodulations.py | 11 ++- surveil/api/controllers/v2/config/commands.py | 6 +- .../controllers/v2/config/contactgroups.py | 6 +- surveil/api/controllers/v2/config/contacts.py | 6 +- .../api/controllers/v2/config/hostgroups.py | 6 +- surveil/api/controllers/v2/config/hosts.py | 24 ++++-- .../controllers/v2/config/macromodulations.py | 10 ++- .../controllers/v2/config/notificationways.py | 11 ++- surveil/api/controllers/v2/config/realms.py | 9 ++- .../api/controllers/v2/config/servicegroup.py | 6 +- surveil/api/controllers/v2/config/services.py | 2 +- .../api/controllers/v2/config/timeperiods.py | 6 +- .../api/datamodel/config/macromodulation.py | 21 ----- surveil/api/datamodel/config/timeperiod.py | 18 ----- .../businessimpactmodulation_handler.py | 15 ++-- .../config/checkmodulation_handler.py | 14 ++-- .../api/handlers/config/command_handler.py | 12 +-- .../api/handlers/config/contact_handler.py | 12 +-- .../handlers/config/contactgroup_handler.py | 14 ++-- surveil/api/handlers/config/host_handler.py | 12 +-- .../api/handlers/config/hostgroup_handler.py | 12 +-- .../config/macromodulation_handler.py | 14 ++-- .../config/notificationway_handler.py | 14 ++-- surveil/api/handlers/config/realm_handler.py | 12 +-- .../api/handlers/config/service_handler.py | 62 +++----------- .../handlers/config/servicegroup_handler.py | 14 ++-- .../api/handlers/config/timeperiod_handler.py | 12 +-- surveil/api/handlers/mongo_object_handler.py | 80 ------------------- .../mongodb_mongoengine_object_handler.py | 75 +++++++++++++++++ surveil/api/storage/__init__.py | 0 surveil/api/storage/mongodb/__init__.py | 0 .../api/storage/mongodb/config/__init__.py | 0 .../config/businessimpactmodulation.py | 22 +++++ .../storage/mongodb/config/checkmodulation.py | 22 +++++ surveil/api/storage/mongodb/config/command.py | 22 +++++ surveil/api/storage/mongodb/config/contact.py | 35 ++++++++ .../storage/mongodb/config/contactgroup.py | 23 ++++++ surveil/api/storage/mongodb/config/host.py | 33 ++++++++ .../api/storage/mongodb/config/hostgroup.py | 26 ++++++ .../storage/mongodb/config/macromodulation.py | 22 +++++ .../storage/mongodb/config/notificationway.py | 27 +++++++ surveil/api/storage/mongodb/config/realm.py | 22 +++++ surveil/api/storage/mongodb/config/service.py | 34 ++++++++ .../storage/mongodb/config/servicegroup.py | 26 ++++++ .../api/storage/mongodb/config/timeperiod.py | 22 +++++ .../api/controllers/v2/config/test_hosts.py | 24 +++--- .../v2/config/test_macromodulations.py | 43 +++++----- .../controllers/v2/config/test_services.py | 2 +- .../controllers/v2/config/test_timeperiods.py | 21 ++--- surveil/tests/api/functionalTest.py | 19 ++++- test-requirements.txt | 3 +- tox.ini | 3 +- 54 files changed, 649 insertions(+), 332 deletions(-) delete mode 100644 surveil/api/handlers/mongo_object_handler.py create mode 100644 surveil/api/handlers/mongodb_mongoengine_object_handler.py create mode 100644 surveil/api/storage/__init__.py create mode 100644 surveil/api/storage/mongodb/__init__.py create mode 100644 surveil/api/storage/mongodb/config/__init__.py create mode 100644 surveil/api/storage/mongodb/config/businessimpactmodulation.py create mode 100644 surveil/api/storage/mongodb/config/checkmodulation.py create mode 100644 surveil/api/storage/mongodb/config/command.py create mode 100644 surveil/api/storage/mongodb/config/contact.py create mode 100644 surveil/api/storage/mongodb/config/contactgroup.py create mode 100644 surveil/api/storage/mongodb/config/host.py create mode 100644 surveil/api/storage/mongodb/config/hostgroup.py create mode 100644 surveil/api/storage/mongodb/config/macromodulation.py create mode 100644 surveil/api/storage/mongodb/config/notificationway.py create mode 100644 surveil/api/storage/mongodb/config/realm.py create mode 100644 surveil/api/storage/mongodb/config/service.py create mode 100644 surveil/api/storage/mongodb/config/servicegroup.py create mode 100644 surveil/api/storage/mongodb/config/timeperiod.py diff --git a/requirements.txt b/requirements.txt index 0fc3947..1b6a8b2 100644 --- a/requirements.txt +++ b/requirements.txt @@ -13,3 +13,4 @@ pika python-surveilclient==0.10.0 six docker-py +mongoengine diff --git a/surveil/api/controllers/v2/config/businessimpactmodulations.py b/surveil/api/controllers/v2/config/businessimpactmodulations.py index 1c6bcb8..fd4ea9b 100644 --- a/surveil/api/controllers/v2/config/businessimpactmodulations.py +++ b/surveil/api/controllers/v2/config/businessimpactmodulations.py @@ -38,7 +38,9 @@ class BusinessImpactModulationsController(rest.RestController): def get_one(self, modulation_name): """Returns a specific business impact modulation.""" handler = bh.BusinessImpactModulationHandler(pecan.request) - modulation = handler.get(modulation_name) + modulation = handler.get( + {"business_impact_modulation_name": modulation_name} + ) return modulation @util.policy_enforce(['authenticated']) @@ -58,7 +60,9 @@ class BusinessImpactModulationsController(rest.RestController): def delete(self, modulation_name): """Returns a specific business impact modulation.""" handler = bh.BusinessImpactModulationHandler(pecan.request) - handler.delete(modulation_name) + handler.delete( + {"business_impact_modulation_name": modulation_name} + ) @util.policy_enforce(['authenticated']) @wsme_pecan.wsexpose(mod.BusinessImpactModulation, @@ -68,4 +72,7 @@ class BusinessImpactModulationsController(rest.RestController): def put(self, modulaion_name, modulation): """Update a specific business impact modulation.""" handler = bh.BusinessImpactModulationHandler(pecan.request) - handler.update(modulaion_name, modulation) + handler.update( + {"business_impact_modulation_name": modulaion_name}, + modulation + ) diff --git a/surveil/api/controllers/v2/config/checkmodulations.py b/surveil/api/controllers/v2/config/checkmodulations.py index d83392e..ac5adfb 100644 --- a/surveil/api/controllers/v2/config/checkmodulations.py +++ b/surveil/api/controllers/v2/config/checkmodulations.py @@ -38,7 +38,9 @@ class CheckModulationsController(rest.RestController): def get_one(self, checkmodulation_name): """Returns a specific check modulation.""" handler = checkmodulation_handler.CheckModulationHandler(pecan.request) - checkmodulation = handler.get(checkmodulation_name) + checkmodulation = handler.get( + {"checkmodulation_name": checkmodulation_name} + ) return checkmodulation @util.policy_enforce(['authenticated']) @@ -57,7 +59,7 @@ class CheckModulationsController(rest.RestController): def delete(self, checkmodulation_name): """Returns a specific check modulation.""" handler = checkmodulation_handler.CheckModulationHandler(pecan.request) - handler.delete(checkmodulation_name) + handler.delete({"checkmodulation_name": checkmodulation_name}) @util.policy_enforce(['authenticated']) @wsme_pecan.wsexpose(checkmodulation.CheckModulation, @@ -67,4 +69,7 @@ class CheckModulationsController(rest.RestController): def put(self, checkmodulation_name, checkmodulation): """Update a specific check modulation.""" handler = checkmodulation_handler.CheckModulationHandler(pecan.request) - handler.update(checkmodulation_name, checkmodulation) \ No newline at end of file + handler.update( + {"checkmodulation_name": checkmodulation_name}, + checkmodulation + ) \ No newline at end of file diff --git a/surveil/api/controllers/v2/config/commands.py b/surveil/api/controllers/v2/config/commands.py index d837f43..7c5db1d 100644 --- a/surveil/api/controllers/v2/config/commands.py +++ b/surveil/api/controllers/v2/config/commands.py @@ -32,7 +32,7 @@ class CommandController(rest.RestController): def get(self): """Returns a specific command.""" handler = command_handler.CommandHandler(pecan.request) - c = handler.get(self._id) + c = handler.get({"command_name": self._id}) return c @util.policy_enforce(['authenticated']) @@ -43,14 +43,14 @@ class CommandController(rest.RestController): :param data: a command within the request body. """ handler = command_handler.CommandHandler(pecan.request) - handler.update(self._id, data) + handler.update({"command_name": self._id}, data) @util.policy_enforce(['authenticated']) @wsme_pecan.wsexpose(None, status_code=204) def delete(self): """Delete this command.""" handler = command_handler.CommandHandler(pecan.request) - handler.delete(self._id) + handler.delete({"command_name": self._id}) class CommandsController(rest.RestController): diff --git a/surveil/api/controllers/v2/config/contactgroups.py b/surveil/api/controllers/v2/config/contactgroups.py index 298d419..c0728ce 100644 --- a/surveil/api/controllers/v2/config/contactgroups.py +++ b/surveil/api/controllers/v2/config/contactgroups.py @@ -38,7 +38,7 @@ class ContactGroupsController(rest.RestController): def get_one(self, group_name): """Returns a contact group.""" handler = contactgroup_handler.ContactGroupHandler(pecan.request) - contactgroup = handler.get(group_name) + contactgroup = handler.get({"contactgroup_name": group_name}) return contactgroup @util.policy_enforce(['authenticated']) @@ -57,7 +57,7 @@ class ContactGroupsController(rest.RestController): def delete(self, group_name): """Delete a specific contact group.""" handler = contactgroup_handler.ContactGroupHandler(pecan.request) - handler.delete(group_name) + handler.delete({"contactgroup_name": group_name}) @util.policy_enforce(['authenticated']) @wsme_pecan.wsexpose(contactgroup.ContactGroup, @@ -67,4 +67,4 @@ class ContactGroupsController(rest.RestController): def put(self, group_name, contactgroup): """Update a specific contact group.""" handler = contactgroup_handler.ContactGroupHandler(pecan.request) - handler.update(group_name, contactgroup) + handler.update({"contactgroup_name": group_name}, contactgroup) diff --git a/surveil/api/controllers/v2/config/contacts.py b/surveil/api/controllers/v2/config/contacts.py index ec8b841..36354af 100644 --- a/surveil/api/controllers/v2/config/contacts.py +++ b/surveil/api/controllers/v2/config/contacts.py @@ -38,7 +38,7 @@ class ContactsController(rest.RestController): def get_one(self, contact_name): """Returns a specific contact.""" handler = contact_handler.ContactHandler(pecan.request) - contact = handler.get(contact_name) + contact = handler.get({"contact_name": contact_name}) return contact @util.policy_enforce(['authenticated']) @@ -56,7 +56,7 @@ class ContactsController(rest.RestController): def delete(self, contact_name): """Returns a specific contact.""" handler = contact_handler.ContactHandler(pecan.request) - handler.delete(contact_name) + handler.delete({"contact_name": contact_name}) @util.policy_enforce(['authenticated']) @wsme_pecan.wsexpose(contact.Contact, @@ -66,4 +66,4 @@ class ContactsController(rest.RestController): def put(self, contact_name, contact): """Returns a specific contact.""" handler = contact_handler.ContactHandler(pecan.request) - handler.update(contact_name, contact) + handler.update({"contact_name": contact_name}, contact) diff --git a/surveil/api/controllers/v2/config/hostgroups.py b/surveil/api/controllers/v2/config/hostgroups.py index a7397d1..25db403 100644 --- a/surveil/api/controllers/v2/config/hostgroups.py +++ b/surveil/api/controllers/v2/config/hostgroups.py @@ -38,7 +38,7 @@ class HostGroupsController(rest.RestController): def get_one(self, group_name): """Returns a host group.""" handler = hostgroup_handler.HostGroupHandler(pecan.request) - hostgroup = handler.get(group_name) + hostgroup = handler.get({"hostgroup_name": group_name}) return hostgroup @util.policy_enforce(['authenticated']) @@ -56,7 +56,7 @@ class HostGroupsController(rest.RestController): def delete(self, group_name): """Returns a specific host group.""" handler = hostgroup_handler.HostGroupHandler(pecan.request) - handler.delete(group_name) + handler.delete({"hostgroup_name": group_name}) @util.policy_enforce(['authenticated']) @wsme_pecan.wsexpose(hostgroup.HostGroup, @@ -66,4 +66,4 @@ class HostGroupsController(rest.RestController): def put(self, group_name, hostgroup): """Update a specific host group.""" handler = hostgroup_handler.HostGroupHandler(pecan.request) - handler.update(group_name, hostgroup) + handler.update({"hostgroup_name": group_name}, hostgroup) diff --git a/surveil/api/controllers/v2/config/hosts.py b/surveil/api/controllers/v2/config/hosts.py index de7cd09..8e7516a 100644 --- a/surveil/api/controllers/v2/config/hosts.py +++ b/surveil/api/controllers/v2/config/hosts.py @@ -35,8 +35,12 @@ class HostServiceSubController(rest.RestController): """Returns a specific service.""" handler = service_handler.ServiceHandler(pecan.request) s = handler.get( - pecan.request.context['host_name'], - pecan.request.context['service_description'] + { + "host_name": pecan.request.context['host_name'], + "service_description": pecan.request.context[ + 'service_description' + ] + } ) return s @@ -46,8 +50,12 @@ class HostServiceSubController(rest.RestController): """Delete a specific service.""" handler = service_handler.ServiceHandler(pecan.request) handler.delete( - pecan.request.context['host_name'], - pecan.request.context['service_description'] + { + "host_name": pecan.request.context['host_name'], + "service_description": pecan.request.context[ + 'service_description' + ] + } ) @@ -83,7 +91,7 @@ class HostController(rest.RestController): def get(self): """Returns a specific host.""" handler = host_handler.HostHandler(pecan.request) - h = handler.get(self._id) + h = handler.get({"host_name": self._id}) return h @util.policy_enforce(['authenticated']) @@ -94,14 +102,14 @@ class HostController(rest.RestController): :param data: a host within the request body. """ handler = host_handler.HostHandler(pecan.request) - handler.update(self._id, data) + handler.update({"host_name": self._id}, data) @util.policy_enforce(['authenticated']) @wsme_pecan.wsexpose(None, status_code=204) def delete(self): """Delete this host.""" handler = host_handler.HostHandler(pecan.request) - handler.delete(self._id) + handler.delete({"host_name": self._id}) @pecan.expose() def _lookup(self, *remainder): @@ -120,7 +128,7 @@ class HostsController(rest.RestController): """Returns all hosts.""" handler = host_handler.HostHandler(pecan.request) hosts = handler.get_all( - templates=bool(templates) + exclude_templates=(not bool(templates)) ) return hosts diff --git a/surveil/api/controllers/v2/config/macromodulations.py b/surveil/api/controllers/v2/config/macromodulations.py index bac5478..51d7be9 100644 --- a/surveil/api/controllers/v2/config/macromodulations.py +++ b/surveil/api/controllers/v2/config/macromodulations.py @@ -35,10 +35,12 @@ class MacroModulationController(rest.RestController): @util.policy_enforce(['authenticated']) @wsme_pecan.wsexpose(macromodulation.MacroModulation, wtypes.text) - def get_one(self, timeperiod_name): + def get_one(self, macromodulation_name): """Returns a specific macro modulation.""" handler = macromodulation_handler.MacroModulationHandler(pecan.request) - modulation = handler.get(timeperiod_name) + modulation = handler.get( + {"macromodulation_name": macromodulation_name} + ) return modulation @util.policy_enforce(['authenticated']) @@ -58,7 +60,7 @@ class MacroModulationController(rest.RestController): def delete(self, modulation_name): """Returns a specific macro modulation.""" handler = macromodulation_handler.MacroModulationHandler(pecan.request) - handler.delete(modulation_name) + handler.delete({"macromodulation_name": modulation_name}) @util.policy_enforce(['authenticated']) @wsme_pecan.wsexpose(macromodulation.MacroModulation, @@ -68,4 +70,4 @@ class MacroModulationController(rest.RestController): def put(self, modulation_name, modulation): """Update a specific macro modulation.""" handler = macromodulation_handler.MacroModulationHandler(pecan.request) - handler.update(modulation_name, modulation) + handler.update({"macromodulation_name": modulation_name}, modulation) diff --git a/surveil/api/controllers/v2/config/notificationways.py b/surveil/api/controllers/v2/config/notificationways.py index 06749fe..6cbfffd 100644 --- a/surveil/api/controllers/v2/config/notificationways.py +++ b/surveil/api/controllers/v2/config/notificationways.py @@ -38,7 +38,9 @@ class NotificationWaysController(rest.RestController): def get_one(self, notificationway_name): """Returns a specific notification way.""" handler = notificationway_handler.NotificationWayHandler(pecan.request) - notificationway = handler.get(notificationway_name) + notificationway = handler.get( + {"notificationway_name": notificationway_name} + ) return notificationway @util.policy_enforce(['authenticated']) @@ -60,7 +62,7 @@ class NotificationWaysController(rest.RestController): def delete(self, notificationway_name): """Returns a specific notification way.""" handler = notificationway_handler.NotificationWayHandler(pecan.request) - handler.delete(notificationway_name) + handler.delete({"notificationway_name": notificationway_name}) @util.policy_enforce(['authenticated']) @wsme_pecan.wsexpose(notificationway.NotificationWay, @@ -70,4 +72,7 @@ class NotificationWaysController(rest.RestController): def put(self, notificationway_name, notificationway): """Update a specific notification way.""" handler = notificationway_handler.NotificationWayHandler(pecan.request) - handler.update(notificationway_name, notificationway) + handler.update( + {"notificationway_name": notificationway_name}, + notificationway + ) diff --git a/surveil/api/controllers/v2/config/realms.py b/surveil/api/controllers/v2/config/realms.py index 0c2aa3e..6d4abbd 100644 --- a/surveil/api/controllers/v2/config/realms.py +++ b/surveil/api/controllers/v2/config/realms.py @@ -38,7 +38,7 @@ class RealmsController(rest.RestController): def get_one(self, realm_name): """Returns a specific realm.""" handler = realm_handler.RealmHandler(pecan.request) - realm = handler.get(realm_name) + realm = handler.get({"realm_name": realm_name}) return realm @util.policy_enforce(['authenticated']) @@ -56,7 +56,7 @@ class RealmsController(rest.RestController): def delete(self, realm_name): """Deletes a specific realm.""" handler = realm_handler.RealmHandler(pecan.request) - handler.delete(realm_name) + handler.delete({"realm_name": realm_name}) @util.policy_enforce(['authenticated']) @wsme_pecan.wsexpose(realm.Realm, @@ -66,4 +66,7 @@ class RealmsController(rest.RestController): def put(self, realm_name, realm): """Updates a specific realm.""" handler = realm_handler.RealmHandler(pecan.request) - handler.update(realm_name, realm) + handler.update( + {"realm_name": realm_name}, + realm + ) diff --git a/surveil/api/controllers/v2/config/servicegroup.py b/surveil/api/controllers/v2/config/servicegroup.py index 83936b5..1074c5b 100644 --- a/surveil/api/controllers/v2/config/servicegroup.py +++ b/surveil/api/controllers/v2/config/servicegroup.py @@ -38,7 +38,7 @@ class ServiceGroupsController(rest.RestController): def get_one(self, group_name): """Returns a service group.""" handler = servicegroup_handler.ServiceGroupHandler(pecan.request) - servicegroup = handler.get(group_name) + servicegroup = handler.get({"servicegroup_name": group_name}) return servicegroup @util.policy_enforce(['authenticated']) @@ -57,7 +57,7 @@ class ServiceGroupsController(rest.RestController): def delete(self, group_name): """Returns a specific service group.""" handler = servicegroup_handler.ServiceGroupHandler(pecan.request) - handler.delete(group_name) + handler.delete({"servicegroup_name": group_name}) @util.policy_enforce(['authenticated']) @wsme_pecan.wsexpose(servicegroup.ServiceGroup, @@ -67,4 +67,4 @@ class ServiceGroupsController(rest.RestController): def put(self, group_name, servicegroup): """Update a specific service group.""" handler = servicegroup_handler.ServiceGroupHandler(pecan.request) - handler.update(group_name, servicegroup) + handler.update({"servicegroup_name": group_name}, servicegroup) diff --git a/surveil/api/controllers/v2/config/services.py b/surveil/api/controllers/v2/config/services.py index 10a5017..3220fe5 100644 --- a/surveil/api/controllers/v2/config/services.py +++ b/surveil/api/controllers/v2/config/services.py @@ -29,7 +29,7 @@ class ServicesController(rest.RestController): """Returns all services.""" handler = service_handler.ServiceHandler(pecan.request) services = handler.get_all( - templates=bool(templates) + exclude_templates=(not bool(templates)) ) return services diff --git a/surveil/api/controllers/v2/config/timeperiods.py b/surveil/api/controllers/v2/config/timeperiods.py index 9ef2b5d..815aad6 100644 --- a/surveil/api/controllers/v2/config/timeperiods.py +++ b/surveil/api/controllers/v2/config/timeperiods.py @@ -38,7 +38,7 @@ class TimePeriodsController(rest.RestController): def get_one(self, timeperiod_name): """Returns a specific time period.""" handler = timeperiod_handler.TimePeriodHandler(pecan.request) - timeperiod = handler.get(timeperiod_name) + timeperiod = handler.get({"timeperiod_name": timeperiod_name}) return timeperiod @util.policy_enforce(['authenticated']) @@ -56,7 +56,7 @@ class TimePeriodsController(rest.RestController): def delete(self, timeperiod_name): """Returns a specific time period.""" handler = timeperiod_handler.TimePeriodHandler(pecan.request) - handler.delete(timeperiod_name) + handler.delete({"timeperiod_name": timeperiod_name}) @util.policy_enforce(['authenticated']) @wsme_pecan.wsexpose(timeperiod.TimePeriod, @@ -66,4 +66,4 @@ class TimePeriodsController(rest.RestController): def put(self, timeperiod_name, timeperiod): """Update a specific time period.""" handler = timeperiod_handler.TimePeriodHandler(pecan.request) - handler.update(timeperiod_name, timeperiod) + handler.update({"timeperiod_name": timeperiod_name}, timeperiod) diff --git a/surveil/api/datamodel/config/macromodulation.py b/surveil/api/datamodel/config/macromodulation.py index 7ff3233..fbaae11 100644 --- a/surveil/api/datamodel/config/macromodulation.py +++ b/surveil/api/datamodel/config/macromodulation.py @@ -21,33 +21,12 @@ 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) - # _CRITICAL = wsme.wsattr(int, mandatory=True) - # _WARNING = wsme.wsattr(int, mandatory=True) macros = wsme.wsattr( wtypes.DictType(wtypes.text, int), mandatory=False ) - def __init__(self, **kwargs): - super(MacroModulation, self).__init__(**kwargs) - - # Custom fields start with '_'. Detect them and assign them. - macros = [i for i in kwargs.items() - if isinstance(i[0], str) and i[0].startswith('_')] - if len(macros) > 0: - self.macros = {} - for item in macros: - self.macros[item[0]] = item[1] - - def as_dict(self): - mod_dict = super(MacroModulation, self).as_dict() - macros = mod_dict.pop("macros", None) - if macros: - for item in macros.items(): - mod_dict[item[0]] = item[1] - return mod_dict - @classmethod def sample(cls): return cls( diff --git a/surveil/api/datamodel/config/timeperiod.py b/surveil/api/datamodel/config/timeperiod.py index e266dfd..988c555 100644 --- a/surveil/api/datamodel/config/timeperiod.py +++ b/surveil/api/datamodel/config/timeperiod.py @@ -27,24 +27,6 @@ class TimePeriod(types.Base): mandatory=False ) - def __init__(self, **kwargs): - super(TimePeriod, self).__init__(**kwargs) - - periods = [i for i in kwargs.items() if isinstance(i[0], str) - and i[0] not in ['timeperiod_name', 'exclude', 'periods']] - if len(periods) > 0: - self.periods = {} - for item in periods: - self.periods[item[0]] = item[1] - - def as_dict(self): - timeperiod_dict = super(TimePeriod, self).as_dict() - periods = timeperiod_dict.pop("periods", None) - if periods: - for item in periods.items(): - timeperiod_dict[item[0]] = item[1] - return timeperiod_dict - @classmethod def sample(cls): return cls( diff --git a/surveil/api/handlers/config/businessimpactmodulation_handler.py b/surveil/api/handlers/config/businessimpactmodulation_handler.py index ec3474c..5cafbb0 100644 --- a/surveil/api/handlers/config/businessimpactmodulation_handler.py +++ b/surveil/api/handlers/config/businessimpactmodulation_handler.py @@ -12,18 +12,21 @@ # License for the specific language governing permissions and limitations # under the License. -from surveil.api.datamodel.config import businessimpactmodulation -from surveil.api.handlers import mongo_object_handler +from surveil.api.datamodel.config import businessimpactmodulation as datamodel +from surveil.api.handlers import mongodb_mongoengine_object_handler +from surveil.api.storage.mongodb.config import (businessimpactmodulation + as storage) -class BusinessImpactModulationHandler(mongo_object_handler.MongoObjectHandler): +class BusinessImpactModulationHandler( + mongodb_mongoengine_object_handler.MongoObjectHandler +): """Fulfills a request on the Business Impact Modulation resource.""" def __init__(self, *args, **kwargs): super(BusinessImpactModulationHandler, self).__init__( - 'businessimpactmodulations', - 'business_impact_modulation_name', - businessimpactmodulation.BusinessImpactModulation, + datamodel.BusinessImpactModulation, + storage.BusinessImpactModulation, *args, **kwargs ) diff --git a/surveil/api/handlers/config/checkmodulation_handler.py b/surveil/api/handlers/config/checkmodulation_handler.py index c1ea1a6..a44e065 100644 --- a/surveil/api/handlers/config/checkmodulation_handler.py +++ b/surveil/api/handlers/config/checkmodulation_handler.py @@ -12,18 +12,20 @@ # License for the specific language governing permissions and limitations # under the License. -from surveil.api.datamodel.config import checkmodulation -from surveil.api.handlers import mongo_object_handler +from surveil.api.datamodel.config import checkmodulation as datamodel +from surveil.api.handlers import mongodb_mongoengine_object_handler +from surveil.api.storage.mongodb.config import checkmodulation as storage -class CheckModulationHandler(mongo_object_handler.MongoObjectHandler): +class CheckModulationHandler( + mongodb_mongoengine_object_handler.MongoObjectHandler +): """Fulfills a request on the Check Modulation resource.""" def __init__(self, *args, **kwargs): super(CheckModulationHandler, self).__init__( - 'checkmodulations', - 'checkmodulation_name', - checkmodulation.CheckModulation, + datamodel.CheckModulation, + storage.CheckModulation, *args, **kwargs ) diff --git a/surveil/api/handlers/config/command_handler.py b/surveil/api/handlers/config/command_handler.py index 6c04120..24ceb0d 100644 --- a/surveil/api/handlers/config/command_handler.py +++ b/surveil/api/handlers/config/command_handler.py @@ -12,18 +12,18 @@ # License for the specific language governing permissions and limitations # under the License. -from surveil.api.datamodel.config import command -from surveil.api.handlers import mongo_object_handler +from surveil.api.datamodel.config import command as command_datamodel +from surveil.api.handlers import mongodb_mongoengine_object_handler +from surveil.api.storage.mongodb.config import command as command_storage -class CommandHandler(mongo_object_handler.MongoObjectHandler): +class CommandHandler(mongodb_mongoengine_object_handler.MongoObjectHandler): """Fulfills a request on the Command resource.""" def __init__(self, *args, **kwargs): super(CommandHandler, self).__init__( - 'commands', - 'command_name', - command.Command, + command_datamodel.Command, + command_storage.Command, *args, **kwargs ) diff --git a/surveil/api/handlers/config/contact_handler.py b/surveil/api/handlers/config/contact_handler.py index 9a1f5c8..de580be 100644 --- a/surveil/api/handlers/config/contact_handler.py +++ b/surveil/api/handlers/config/contact_handler.py @@ -12,18 +12,18 @@ # License for the specific language governing permissions and limitations # under the License. -from surveil.api.datamodel.config import contact -from surveil.api.handlers import mongo_object_handler +from surveil.api.datamodel.config import contact as datamodel +from surveil.api.handlers import mongodb_mongoengine_object_handler +from surveil.api.storage.mongodb.config import contact as storage -class ContactHandler(mongo_object_handler.MongoObjectHandler): +class ContactHandler(mongodb_mongoengine_object_handler.MongoObjectHandler): """Fulfills a request on the Contact resource.""" def __init__(self, *args, **kwargs): super(ContactHandler, self).__init__( - 'contacts', - 'contact_name', - contact.Contact, + datamodel.Contact, + storage.Contact, *args, **kwargs ) diff --git a/surveil/api/handlers/config/contactgroup_handler.py b/surveil/api/handlers/config/contactgroup_handler.py index f1477e9..3b88b8c 100644 --- a/surveil/api/handlers/config/contactgroup_handler.py +++ b/surveil/api/handlers/config/contactgroup_handler.py @@ -12,18 +12,20 @@ # License for the specific language governing permissions and limitations # under the License. -from surveil.api.datamodel.config import contactgroup -from surveil.api.handlers import mongo_object_handler +from surveil.api.datamodel.config import contactgroup as datamodel +from surveil.api.handlers import mongodb_mongoengine_object_handler +from surveil.api.storage.mongodb.config import contactgroup as storage -class ContactGroupHandler(mongo_object_handler.MongoObjectHandler): +class ContactGroupHandler( + mongodb_mongoengine_object_handler.MongoObjectHandler +): """Fulfills a request on the Contact Group resource.""" def __init__(self, *args, **kwargs): super(ContactGroupHandler, self).__init__( - 'contactgroups', - 'contactgroup_name', - contactgroup.ContactGroup, + datamodel.ContactGroup, + storage.ContactGroup, *args, **kwargs ) diff --git a/surveil/api/handlers/config/host_handler.py b/surveil/api/handlers/config/host_handler.py index 0dc3c58..d7cef3f 100644 --- a/surveil/api/handlers/config/host_handler.py +++ b/surveil/api/handlers/config/host_handler.py @@ -12,18 +12,18 @@ # License for the specific language governing permissions and limitations # under the License. -from surveil.api.datamodel.config import host -from surveil.api.handlers import mongo_object_handler +from surveil.api.datamodel.config import host as host_datamodel +from surveil.api.handlers import mongodb_mongoengine_object_handler +from surveil.api.storage.mongodb.config import host as host_storage -class HostHandler(mongo_object_handler.MongoObjectHandler): +class HostHandler(mongodb_mongoengine_object_handler.MongoObjectHandler): """Fulfills a request on the Host resource.""" def __init__(self, *args, **kwargs): super(HostHandler, self).__init__( - 'hosts', - 'host_name', - host.Host, + host_datamodel.Host, + host_storage.Host, *args, **kwargs ) diff --git a/surveil/api/handlers/config/hostgroup_handler.py b/surveil/api/handlers/config/hostgroup_handler.py index ce87215..ade7a8a 100644 --- a/surveil/api/handlers/config/hostgroup_handler.py +++ b/surveil/api/handlers/config/hostgroup_handler.py @@ -12,18 +12,18 @@ # License for the specific language governing permissions and limitations # under the License. -from surveil.api.datamodel.config import hostgroup -from surveil.api.handlers import mongo_object_handler +from surveil.api.datamodel.config import hostgroup as datamodel +from surveil.api.handlers import mongodb_mongoengine_object_handler +from surveil.api.storage.mongodb.config import hostgroup as storage -class HostGroupHandler(mongo_object_handler.MongoObjectHandler): +class HostGroupHandler(mongodb_mongoengine_object_handler.MongoObjectHandler): """Fulfills a request on the host group resource.""" def __init__(self, *args, **kwargs): super(HostGroupHandler, self).__init__( - 'hostgroups', - 'hostgroup_name', - hostgroup.HostGroup, + datamodel.HostGroup, + storage.HostGroup, *args, **kwargs ) diff --git a/surveil/api/handlers/config/macromodulation_handler.py b/surveil/api/handlers/config/macromodulation_handler.py index 283acbd..36e52ac 100644 --- a/surveil/api/handlers/config/macromodulation_handler.py +++ b/surveil/api/handlers/config/macromodulation_handler.py @@ -12,18 +12,20 @@ # License for the specific language governing permissions and limitations # under the License. -from surveil.api.datamodel.config import macromodulation -from surveil.api.handlers import mongo_object_handler +from surveil.api.datamodel.config import macromodulation as datamodel +from surveil.api.handlers import mongodb_mongoengine_object_handler +from surveil.api.storage.mongodb.config import macromodulation as storage -class MacroModulationHandler(mongo_object_handler.MongoObjectHandler): +class MacroModulationHandler( + mongodb_mongoengine_object_handler.MongoObjectHandler +): """Fulfills a request on the Macro Modulation resource.""" def __init__(self, *args, **kwargs): super(MacroModulationHandler, self).__init__( - 'macromodulations', - 'macromodulation_name', - macromodulation.MacroModulation, + datamodel.MacroModulation, + storage.MacroModulation, *args, **kwargs ) diff --git a/surveil/api/handlers/config/notificationway_handler.py b/surveil/api/handlers/config/notificationway_handler.py index a701cdf..a610908 100644 --- a/surveil/api/handlers/config/notificationway_handler.py +++ b/surveil/api/handlers/config/notificationway_handler.py @@ -12,18 +12,20 @@ # License for the specific language governing permissions and limitations # under the License. -from surveil.api.datamodel.config import notificationway -from surveil.api.handlers import mongo_object_handler +from surveil.api.datamodel.config import notificationway as datamodel +from surveil.api.handlers import mongodb_mongoengine_object_handler +from surveil.api.storage.mongodb.config import notificationway as storage -class NotificationWayHandler(mongo_object_handler.MongoObjectHandler): +class NotificationWayHandler( + mongodb_mongoengine_object_handler.MongoObjectHandler +): """Fulfills a request on the Notification Way resource.""" def __init__(self, *args, **kwargs): super(NotificationWayHandler, self).__init__( - 'notificationways', - 'notificationway_name', - notificationway.NotificationWay, + datamodel.NotificationWay, + storage.NotificationWays, *args, **kwargs ) diff --git a/surveil/api/handlers/config/realm_handler.py b/surveil/api/handlers/config/realm_handler.py index 2b60e36..24bfabd 100644 --- a/surveil/api/handlers/config/realm_handler.py +++ b/surveil/api/handlers/config/realm_handler.py @@ -12,18 +12,18 @@ # License for the specific language governing permissions and limitations # under the License. -from surveil.api.datamodel.config import realm -from surveil.api.handlers import mongo_object_handler +from surveil.api.datamodel.config import realm as datamodel +from surveil.api.handlers import mongodb_mongoengine_object_handler +from surveil.api.storage.mongodb.config import realm as storage -class RealmHandler(mongo_object_handler.MongoObjectHandler): +class RealmHandler(mongodb_mongoengine_object_handler.MongoObjectHandler): """Fulfills a request on the Realm resource.""" def __init__(self, *args, **kwargs): super(RealmHandler, self).__init__( - 'realms', - 'realm_name', - realm.Realm, + datamodel.Realm, + storage.Realm, *args, **kwargs ) diff --git a/surveil/api/handlers/config/service_handler.py b/surveil/api/handlers/config/service_handler.py index 6424905..0b82af0 100644 --- a/surveil/api/handlers/config/service_handler.py +++ b/surveil/api/handlers/config/service_handler.py @@ -12,60 +12,18 @@ # License for the specific language governing permissions and limitations # under the License. -from surveil.api.datamodel.config import service -from surveil.api.handlers import handler +from surveil.api.datamodel.config import service as service_datamodel +from surveil.api.handlers import mongodb_mongoengine_object_handler +from surveil.api.storage.mongodb.config import service as service_storage -class ServiceHandler(handler.Handler): +class ServiceHandler(mongodb_mongoengine_object_handler.MongoObjectHandler): """Fulfills a request on the service resource.""" - def get(self, host_name, service_description): - """Return a service.""" - mongo_s = self.request.mongo_connection.shinken.services.find_one( - {"host_name": host_name, - "service_description": service_description} + def __init__(self, *args, **kwargs): + super(ServiceHandler, self).__init__( + service_datamodel.Service, + service_storage.Service, + *args, + **kwargs ) - return service.Service(**mongo_s) - - def update(self, id, data): - """Modify existing host.""" - host_dict = data.as_dict() - if "host_name" not in host_dict.keys(): - host_dict['host_name'] = id - - self.request.mongo_connection.shinken.hosts.update( - {"host_name": id}, - {"$set": host_dict}, - upsert=True - ) - - def delete(self, host_name, service_description): - """Delete existing service.""" - self.request.mongo_connection.shinken.services.remove( - {"host_name": host_name, - "service_description": service_description} - ) - - def create(self, data): - """Create a new service.""" - self.request.mongo_connection.shinken.services.insert( - data.as_dict() - ) - - def get_all(self, host_name=None, templates=False): - """Return all services.""" - if templates is True: - filters = {} - else: - filters = {"register": {"$ne": "0"}} - - if host_name is not None: - filters['host_name'] = host_name - - services = [ - s for s - in self.request.mongo_connection. - # Don't return templates - shinken.services.find(filters) - ] - return [service.Service(**s) for s in services] diff --git a/surveil/api/handlers/config/servicegroup_handler.py b/surveil/api/handlers/config/servicegroup_handler.py index d4c87e5..68b6a1d 100644 --- a/surveil/api/handlers/config/servicegroup_handler.py +++ b/surveil/api/handlers/config/servicegroup_handler.py @@ -12,18 +12,20 @@ # License for the specific language governing permissions and limitations # under the License. -from surveil.api.datamodel.config import servicegroup -from surveil.api.handlers import mongo_object_handler +from surveil.api.datamodel.config import servicegroup as datamodel +from surveil.api.handlers import mongodb_mongoengine_object_handler +from surveil.api.storage.mongodb.config import servicegroup as storage -class ServiceGroupHandler(mongo_object_handler.MongoObjectHandler): +class ServiceGroupHandler( + mongodb_mongoengine_object_handler.MongoObjectHandler +): """Fulfills a request on the Service Group resource.""" def __init__(self, *args, **kwargs): super(ServiceGroupHandler, self).__init__( - 'servicegroups', - 'servicegroup_name', - servicegroup.ServiceGroup, + datamodel.ServiceGroup, + storage.ServiceGroup, *args, **kwargs ) diff --git a/surveil/api/handlers/config/timeperiod_handler.py b/surveil/api/handlers/config/timeperiod_handler.py index 6a9650b..288fd71 100644 --- a/surveil/api/handlers/config/timeperiod_handler.py +++ b/surveil/api/handlers/config/timeperiod_handler.py @@ -12,18 +12,18 @@ # License for the specific language governing permissions and limitations # under the License. -from surveil.api.datamodel.config import timeperiod -from surveil.api.handlers import mongo_object_handler +from surveil.api.datamodel.config import timeperiod as datamodel +from surveil.api.handlers import mongodb_mongoengine_object_handler +from surveil.api.storage.mongodb.config import timeperiod as storage -class TimePeriodHandler(mongo_object_handler.MongoObjectHandler): +class TimePeriodHandler(mongodb_mongoengine_object_handler.MongoObjectHandler): """Fulfills a request on the Time Period resource.""" def __init__(self, *args, **kwargs): super(TimePeriodHandler, self).__init__( - 'timeperiods', - 'timeperiod_name', - timeperiod.TimePeriod, + datamodel.TimePeriod, + storage.TimePeriod, *args, **kwargs ) diff --git a/surveil/api/handlers/mongo_object_handler.py b/surveil/api/handlers/mongo_object_handler.py deleted file mode 100644 index 88fed90..0000000 --- a/surveil/api/handlers/mongo_object_handler.py +++ /dev/null @@ -1,80 +0,0 @@ -# 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 surveil.api.handlers import handler - - -class MongoObjectHandler(handler.Handler): - """Fulfills a request on a MongoDB resource.""" - - def __init__(self, - resource_colleciton, - resource_key, - resource_datamodel, - *args, - **kwargs): - super(MongoObjectHandler, self).__init__(*args, **kwargs) - self.resource_collection = resource_colleciton - self.resource_key = resource_key - self.resource_datamodel = resource_datamodel - - def _get_resource_collection(self): - shinken_db = self.request.mongo_connection.shinken - resource_colleciton = getattr(shinken_db, self.resource_collection) - return resource_colleciton - - def get(self, resource_key_value): - """Return the resource.""" - r = self._get_resource_collection().find_one( - {self.resource_key: resource_key_value}, - {'_id': 0} - ) - return self.resource_datamodel(**r) - - def update(self, resource_key_value, resource): - """Modify an existing resource.""" - resource_dict = resource.as_dict() - if self.resource_key not in resource_dict.keys(): - resource_dict[self.resource_key] = resource_key_value - - self._get_resource_collection().update( - {self.resource_key: resource_key_value}, - {"$set": resource_dict}, - upsert=True - ) - - def delete(self, resource_key_value): - """Delete existing resource.""" - self._get_resource_collection().remove( - {self.resource_key: resource_key_value} - ) - - def create(self, resource): - """Create a new resource.""" - self._get_resource_collection().insert( - resource.as_dict() - ) - - def get_all(self, templates=False): - """Return all resources.""" - if templates is True: - filters = {} - else: - filters = {"register": {"$ne": "0"}} - - resources = [r for r - in self._get_resource_collection() - .find(filters, {'_id': 0})] - resources = [self.resource_datamodel(**r) for r in resources] - return resources diff --git a/surveil/api/handlers/mongodb_mongoengine_object_handler.py b/surveil/api/handlers/mongodb_mongoengine_object_handler.py new file mode 100644 index 0000000..d445b19 --- /dev/null +++ b/surveil/api/handlers/mongodb_mongoengine_object_handler.py @@ -0,0 +1,75 @@ +# 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 surveil.api.handlers import handler + + +class MongoObjectHandler(handler.Handler): + """Fulfills a request on a MongoDB resource.""" + + def __init__(self, + resource_datamodel, + resource_storage, + *args, + **kwargs): + super(MongoObjectHandler, self).__init__(*args, **kwargs) + self.resource_datamodel = resource_datamodel + self.resource_storage = resource_storage + + def _get_mongoengine_object(self, identifier): + return self.resource_storage.objects.get(**identifier) + + def _get_dict(self, mongoengine_object): + json_object = mongoengine_object.to_mongo().to_dict() + json_object.pop('_id', None) + return json_object + + def get(self, identifier): + """Return the resource.""" + mongoengine_object = self._get_mongoengine_object(identifier) + resource_dict = self._get_dict(mongoengine_object) + return self.resource_datamodel(**resource_dict) + + def update(self, identifier, resource): + """Modify an existing resource.""" + r = self._get_mongoengine_object(identifier) + resource_dict = resource.as_dict() + for key, value in resource_dict.items(): + setattr(r, key, value) + r.save() + + def delete(self, identifier): + """Delete existing resource.""" + r = self._get_mongoengine_object(identifier) + r.delete() + r.save() + + def create(self, resource): + """Create a new resource.""" + r = self.resource_storage(**resource.as_dict()) + r.save() + + def get_all(self, identifier=None, exclude_templates=False, **kwargs): + """Return all resources.""" + identifier = identifier or {} + if exclude_templates is True: + identifier.update( + {"register__ne": "0"} + ) + + return [ + self.resource_datamodel(**self._get_dict(r)) + for r + in self.resource_storage.objects(**identifier) + ] diff --git a/surveil/api/storage/__init__.py b/surveil/api/storage/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/surveil/api/storage/mongodb/__init__.py b/surveil/api/storage/mongodb/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/surveil/api/storage/mongodb/config/__init__.py b/surveil/api/storage/mongodb/config/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/surveil/api/storage/mongodb/config/businessimpactmodulation.py b/surveil/api/storage/mongodb/config/businessimpactmodulation.py new file mode 100644 index 0000000..6bef122 --- /dev/null +++ b/surveil/api/storage/mongodb/config/businessimpactmodulation.py @@ -0,0 +1,22 @@ +# 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 mongoengine + + +class BusinessImpactModulation(mongoengine.Document): + meta = {'collection': 'businessimpactmodulations'} + business_impact_modulation_name = mongoengine.StringField(unique=True) + business_impact = mongoengine.IntField() + modulation_period = mongoengine.StringField() \ No newline at end of file diff --git a/surveil/api/storage/mongodb/config/checkmodulation.py b/surveil/api/storage/mongodb/config/checkmodulation.py new file mode 100644 index 0000000..a671dd6 --- /dev/null +++ b/surveil/api/storage/mongodb/config/checkmodulation.py @@ -0,0 +1,22 @@ +# 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 mongoengine + + +class CheckModulation(mongoengine.Document): + meta = {'collection': 'checkmodulations'} + checkmodulation_name = mongoengine.StringField(unique=True) + check_command = mongoengine.StringField() + check_period = mongoengine.StringField() \ No newline at end of file diff --git a/surveil/api/storage/mongodb/config/command.py b/surveil/api/storage/mongodb/config/command.py new file mode 100644 index 0000000..7b3b1d5 --- /dev/null +++ b/surveil/api/storage/mongodb/config/command.py @@ -0,0 +1,22 @@ +# 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 mongoengine + + +class Command(mongoengine.Document): + meta = {'collection': 'commands'} + command_name = mongoengine.StringField(unique=True) + command_line = mongoengine.StringField() + module_type = mongoengine.StringField() diff --git a/surveil/api/storage/mongodb/config/contact.py b/surveil/api/storage/mongodb/config/contact.py new file mode 100644 index 0000000..e41044d --- /dev/null +++ b/surveil/api/storage/mongodb/config/contact.py @@ -0,0 +1,35 @@ +# 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 mongoengine + + +class Contact(mongoengine.Document): + meta = {'collection': 'contacts'} + contact_name = mongoengine.StringField(unique=True) + host_notifications_enabled = mongoengine.StringField() + 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() + email = mongoengine.StringField() + pager = mongoengine.StringField() + can_submit_commands = mongoengine.StringField() + is_admin = mongoengine.StringField() + retain_status_information = mongoengine.StringField() + retain_nonstatus_information = mongoengine.StringField() + min_business_impact = mongoengine.StringField() diff --git a/surveil/api/storage/mongodb/config/contactgroup.py b/surveil/api/storage/mongodb/config/contactgroup.py new file mode 100644 index 0000000..a4347bb --- /dev/null +++ b/surveil/api/storage/mongodb/config/contactgroup.py @@ -0,0 +1,23 @@ +# 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 mongoengine + + +class ContactGroup(mongoengine.Document): + meta = {'collection': 'contactgroups'} + contactgroup_name = mongoengine.StringField(unique=True) + members = mongoengine.StringField() + alias = mongoengine.StringField() + contactgroup_members = mongoengine.StringField() \ No newline at end of file diff --git a/surveil/api/storage/mongodb/config/host.py b/surveil/api/storage/mongodb/config/host.py new file mode 100644 index 0000000..ab73116 --- /dev/null +++ b/surveil/api/storage/mongodb/config/host.py @@ -0,0 +1,33 @@ +# 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 mongoengine + + +class Host(mongoengine.Document): + meta = {'collection': 'hosts'} + host_name = mongoengine.StringField(unique=True) + address = mongoengine.StringField() + max_check_attempts = mongoengine.IntField() + check_period = mongoengine.StringField() + contacts = mongoengine.StringField() + contact_groups = mongoengine.StringField() + notification_interval = mongoengine.IntField() + notification_period = mongoengine.StringField() + use = mongoengine.StringField() + name = mongoengine.StringField() + register = mongoengine.StringField() + check_interval = mongoengine.IntField() + retry_interval = mongoengine.IntField() + custom_fields = mongoengine.DictField() diff --git a/surveil/api/storage/mongodb/config/hostgroup.py b/surveil/api/storage/mongodb/config/hostgroup.py new file mode 100644 index 0000000..907e955 --- /dev/null +++ b/surveil/api/storage/mongodb/config/hostgroup.py @@ -0,0 +1,26 @@ +# 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 mongoengine + + +class HostGroup(mongoengine.Document): + meta = {'collection': 'hostgroups'} + hostgroup_name = mongoengine.StringField(unique=True) + members = mongoengine.StringField() + alias = mongoengine.StringField() + hostgroup_members = mongoengine.StringField() + notes = mongoengine.StringField() + notes_url = mongoengine.StringField() + action_url = mongoengine.StringField() \ No newline at end of file diff --git a/surveil/api/storage/mongodb/config/macromodulation.py b/surveil/api/storage/mongodb/config/macromodulation.py new file mode 100644 index 0000000..7f40c7d --- /dev/null +++ b/surveil/api/storage/mongodb/config/macromodulation.py @@ -0,0 +1,22 @@ +# 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 mongoengine + + +class MacroModulation(mongoengine.Document): + meta = {'collection': 'macromodulations'} + macromodulation_name = mongoengine.StringField(unique=True) + modulation_period = mongoengine.StringField() + macros = mongoengine.DictField() diff --git a/surveil/api/storage/mongodb/config/notificationway.py b/surveil/api/storage/mongodb/config/notificationway.py new file mode 100644 index 0000000..a88d131 --- /dev/null +++ b/surveil/api/storage/mongodb/config/notificationway.py @@ -0,0 +1,27 @@ +# 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 mongoengine + + +class NotificationWays(mongoengine.Document): + meta = {'collection': 'notificationways'} + notificationway_name = mongoengine.StringField(unique=True) + 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() + 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 new file mode 100644 index 0000000..10f9da2 --- /dev/null +++ b/surveil/api/storage/mongodb/config/realm.py @@ -0,0 +1,22 @@ +# 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 mongoengine + + +class Realm(mongoengine.Document): + meta = {'collection': 'realms'} + realm_name = mongoengine.StringField(unique=True) + realm_members = mongoengine.StringField() + default = mongoengine.IntField() \ No newline at end of file diff --git a/surveil/api/storage/mongodb/config/service.py b/surveil/api/storage/mongodb/config/service.py new file mode 100644 index 0000000..b6521de --- /dev/null +++ b/surveil/api/storage/mongodb/config/service.py @@ -0,0 +1,34 @@ +# 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 mongoengine + + +class Service(mongoengine.Document): + meta = {'collection': 'services'} + host_name = mongoengine.StringField(unique=True) + service_description = mongoengine.StringField() + contacts = mongoengine.StringField() + check_command = mongoengine.StringField() + max_check_attempts = mongoengine.IntField() + check_interval = mongoengine.IntField() + retry_interval = mongoengine.IntField() + check_period = mongoengine.StringField() + notification_interval = mongoengine.IntField() + notification_period = mongoengine.StringField() + contact_groups = mongoengine.StringField() + passive_checks_enabled = mongoengine.StringField() + use = mongoengine.StringField() + name = mongoengine.StringField() + register = mongoengine.StringField() \ No newline at end of file diff --git a/surveil/api/storage/mongodb/config/servicegroup.py b/surveil/api/storage/mongodb/config/servicegroup.py new file mode 100644 index 0000000..a5404ec --- /dev/null +++ b/surveil/api/storage/mongodb/config/servicegroup.py @@ -0,0 +1,26 @@ +# 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 mongoengine + + +class ServiceGroup(mongoengine.Document): + meta = {'collection': 'servicegroups'} + servicegroup_name = mongoengine.StringField(unique=True) + members = mongoengine.StringField() + alias = mongoengine.StringField() + servicegroup_members = mongoengine.StringField() + notes = mongoengine.StringField() + notes_url = mongoengine.StringField() + action_url = mongoengine.StringField() \ No newline at end of file diff --git a/surveil/api/storage/mongodb/config/timeperiod.py b/surveil/api/storage/mongodb/config/timeperiod.py new file mode 100644 index 0000000..bd35a49 --- /dev/null +++ b/surveil/api/storage/mongodb/config/timeperiod.py @@ -0,0 +1,22 @@ +# 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 mongoengine + + +class TimePeriod(mongoengine.Document): + meta = {'collection': 'timeperiods'} + timeperiod_name = mongoengine.StringField(unique=True) + exclude = mongoengine.StringField() + periods = mongoengine.DictField() diff --git a/surveil/tests/api/controllers/v2/config/test_hosts.py b/surveil/tests/api/controllers/v2/config/test_hosts.py index a10e1c9..6400990 100644 --- a/surveil/tests/api/controllers/v2/config/test_hosts.py +++ b/surveil/tests/api/controllers/v2/config/test_hosts.py @@ -30,19 +30,21 @@ class TestHostController(functionalTest.FunctionalTest): "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" + "notification_interval": 30, "notification_period": "24x7", + "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' + 'use': 'test', "custom_fields": {} }, ] self.mongoconnection.shinken.hosts.insert( @@ -80,23 +82,15 @@ class TestHostController(functionalTest.FunctionalTest): def test_get_all_hosts_templates(self): self.mongoconnection.shinken.hosts.insert( copy.deepcopy( - {"host_name": "bogus-router", "address": "192.168.1.254", + {"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"} + "register": "0", "custom_fields": {}} ) ) response = self.get('/v2/config/hosts') - # Adjust self.host content to reflect custom_fields sub-dict - c_fields = {} - for h in self.hosts: - if '_CRITICAL' in h.keys(): - c_fields['_CRITICAL'] = h['_CRITICAL'] - h.pop('_CRITICAL') - h['custom_fields'] = c_fields - self.assert_count_equal_backport( json.loads(response.body.decode()), self.hosts @@ -143,7 +137,8 @@ class TestHostController(functionalTest.FunctionalTest): 'contact_groups': u'router-admins', 'host_name': u'bogus-router333', 'max_check_attempts': 5, - 'use': u'test' + 'use': u'test', + 'custom_fields': {}, } self.assertEqual(expected, mongo_host.as_dict()) @@ -167,7 +162,8 @@ class TestHostController(functionalTest.FunctionalTest): "contacts": "admin,carl", "contact_groups": "router-admins", "notification_interval": 3, - "notification_period": "24x7" + "notification_period": "24x7", + "custom_fields": {} } response = self.post_json("/v2/config/hosts", params=new_host) diff --git a/surveil/tests/api/controllers/v2/config/test_macromodulations.py b/surveil/tests/api/controllers/v2/config/test_macromodulations.py index 8e745b1..44c9120 100644 --- a/surveil/tests/api/controllers/v2/config/test_macromodulations.py +++ b/surveil/tests/api/controllers/v2/config/test_macromodulations.py @@ -27,14 +27,18 @@ class TestMacroModulationController(functionalTest.FunctionalTest): { 'macromodulation_name': 'HighDuringNight', 'modulation_period': 'night', - '_CRITICAL': 20, - '_WARNING': 10, + 'macros': { + '_CRITICAL': 10, + '_WARNING': 20 + } }, { 'macromodulation_name': 'LowDuringNight', 'modulation_period': 'night', - '_CRITICAL': 10, - '_WARNING': 20, + 'macros': { + '_CRITICAL': 20, + '_WARNING': 10 + } } ] self.mongoconnection.shinken.macromodulations.insert( @@ -50,14 +54,18 @@ class TestMacroModulationController(functionalTest.FunctionalTest): 'macromodulation_name': 'HighDuringNight', 'modulation_period': 'night', 'macros': { - '_CRITICAL': 20, - '_WARNING': 10}}, + '_CRITICAL': 10, + '_WARNING': 20 + } + }, { 'macromodulation_name': 'LowDuringNight', 'modulation_period': 'night', 'macros': { - '_CRITICAL': 10, - '_WARNING': 20}} + '_CRITICAL': 20, + '_WARNING': 10 + } + } ], json.loads(response.body.decode()) @@ -69,11 +77,14 @@ class TestMacroModulationController(functionalTest.FunctionalTest): self.assertEqual( json.loads(response.body.decode()), - {'macromodulation_name': 'HighDuringNight', - 'modulation_period': 'night', - 'macros': { - '_CRITICAL': 20, - '_WARNING': 10}} + { + 'macromodulation_name': 'HighDuringNight', + 'modulation_period': 'night', + 'macros': { + '_CRITICAL': 10, + '_WARNING': 20 + } + } ) def test_create_macromodulation(self): @@ -90,11 +101,7 @@ class TestMacroModulationController(functionalTest.FunctionalTest): self.assertIsNotNone( self.mongoconnection.shinken.macromodulations.find_one( - { - 'macromodulation_name': 'TEST_CREATE_MODULATION', - '_CRITICAL': 10, - '_WARNING': 20 - } + m ) ) diff --git a/surveil/tests/api/controllers/v2/config/test_services.py b/surveil/tests/api/controllers/v2/config/test_services.py index d9f859e..974cf24 100644 --- a/surveil/tests/api/controllers/v2/config/test_services.py +++ b/surveil/tests/api/controllers/v2/config/test_services.py @@ -80,7 +80,7 @@ class TestServiceController(functionalTest.FunctionalTest): def test_get_all_services_templates(self): self.mongoconnection.shinken.services.insert( copy.deepcopy( - {"host_name": "sample-server3", + {"host_name": "sample-server444", "service_description": "check-disk-sdb", "check_command": "check-disk!/dev/sdb1", "max_check_attempts": 5, diff --git a/surveil/tests/api/controllers/v2/config/test_timeperiods.py b/surveil/tests/api/controllers/v2/config/test_timeperiods.py index 3a9c687..0328055 100644 --- a/surveil/tests/api/controllers/v2/config/test_timeperiods.py +++ b/surveil/tests/api/controllers/v2/config/test_timeperiods.py @@ -26,13 +26,17 @@ class TestTimePeriodsController(functionalTest.FunctionalTest): self.timeperiods = [ { 'timeperiod_name': 'nonworkhours', - 'sunday': '00:00-24:00', - 'monday': '00:00-09:00,17:00-24:00' + "periods": { + 'sunday': '00:00-24:00', + 'monday': '00:00-09:00,17:00-24:00' + } }, { 'timeperiod_name': 'misc-single-days', - '1999-01-28': '00:00-24:00', - 'day 2': '00:00-24:00', + "periods": { + '1999-01-28': '00:00-24:00', + 'day 2': '00:00-24:00', + } }, ] self.mongoconnection.shinken.timeperiods.insert( @@ -75,10 +79,7 @@ class TestTimePeriodsController(functionalTest.FunctionalTest): self.post_json('/v2/config/timeperiods', t) self.assertIsNotNone( - self.mongoconnection.shinken.timeperiods.find_one( - {"timeperiod_name": 'someperiod', - "monday": "fun day", - "tuesday": "pizza day"}) + self.mongoconnection.shinken.timeperiods.find_one(t) ) def test_delete_timeperiod(self): @@ -100,7 +101,7 @@ class TestTimePeriodsController(functionalTest.FunctionalTest): self.assertEqual( self.mongoconnection.shinken.timeperiods.find_one( {'timeperiod_name': 'nonworkhours'} - )['sunday'], + )['periods']['sunday'], '00:00-24:00' ) @@ -113,6 +114,6 @@ class TestTimePeriodsController(functionalTest.FunctionalTest): self.assertEqual( self.mongoconnection.shinken.timeperiods.find_one( {'timeperiod_name': 'nonworkhours'} - )['sunday'], + )['periods']['sunday'], 'updated' ) diff --git a/surveil/tests/api/functionalTest.py b/surveil/tests/api/functionalTest.py index f2aa2ce..8309d9a 100644 --- a/surveil/tests/api/functionalTest.py +++ b/surveil/tests/api/functionalTest.py @@ -15,11 +15,13 @@ import os import influxdb +import mongoengine import mongomock from oslo_config import cfg import pecan from pecan import hooks import pecan.testing +import pymongo from surveil.tests import base @@ -36,7 +38,14 @@ class FunctionalTest(base.BaseTestCase): def setUp(self): - self.mongoconnection = mongomock.Connection() + if os.environ.get('SURVEIL_FUNCTIONAL_MONGOMOCK', None) == 'True': + self.mongoconnection = mongomock.Connection() + else: + self.mongoconnection = pymongo.MongoClient() + self.mongoconnection.drop_database('shinken') + self.mongoconnection.drop_database('alignak_live') + self.mongoconnection.drop_database('surveil') + self.ws_arbiter_url = "http://localhost:7760" self.influxdb_client = influxdb.InfluxDBClient.from_DSN( 'influxdb://root:root@influxdb:8086/db' @@ -53,6 +62,12 @@ class FunctionalTest(base.BaseTestCase): state.request.ws_arbiter_url = self.ws_arbiter_url state.request.influxdb_client = self.influxdb_client + def get_connection(alias): + return self.mongoclient + + mongoengine.connection.get_connection = get_connection + mongoengine.connect('shinken') + app_hooks = [ TestHook( self.mongoconnection, @@ -103,4 +118,6 @@ class FunctionalTest(base.BaseTestCase): setattr(self, action, make_action(action)) def tearDown(self): + if os.environ.get('SURVEIL_FUNCTIONAL_MONGOMOCK', None) != 'True': + self.mongoconnection.close() pecan.set_config({}, overwrite=True) diff --git a/test-requirements.txt b/test-requirements.txt index 5044cbc..2c263c7 100644 --- a/test-requirements.txt +++ b/test-requirements.txt @@ -5,7 +5,8 @@ sphinxcontrib-pecanwsme>=0.8 sphinxcontrib-httpdomain>=1.3.0 oslosphinx>=2.5.0 testrepository>=0.0.18 -mongomock +#mongomock +https://github.com/aviau/mongomock/archive/create_index.zip#egg=mongomock requests_mock sphinx_rtd_theme docker-compose diff --git a/tox.ini b/tox.ini index f926b2a..8cf7740 100644 --- a/tox.ini +++ b/tox.ini @@ -7,12 +7,13 @@ skipsdist = True setenv = LANGUAGE=en_US LC_ALL=en_US.utf-8 SURVEIL_INTEGRATION_TESTS=False + SURVEIL_FUNCTIONAL_MONGOMOCK=False usedevelop = True install_command = pip install -U --force-reinstall {opts} {packages} deps = -r{toxinidir}/requirements.txt -r{toxinidir}/test-requirements.txt -commands = python setup.py testr --slowest --testr-args='{posargs}' +commands = python setup.py testr --slowest --testr-args='--parallel --concurrency=1' [testenv:integration] setenv = SURVEIL_INTEGRATION_TESTS=True