Merge "Merged v1 controlers in v2/config"

This commit is contained in:
Jenkins 2015-03-20 21:11:19 +00:00 committed by Gerrit Code Review
commit fce007cdd9
11 changed files with 840 additions and 3 deletions

View File

@ -12,20 +12,26 @@
# License for the specific language governing permissions and limitations
# under the License.
from surveil.api.controllers.v2.config import commands
from surveil.api.controllers.v2.config import hosts
from surveil.api.controllers.v2.config import reload_config
from surveil.api.controllers.v2.config import services
from pecan import rest
class ConfigController(rest.RestController):
"""Root config controller."""
# hosts = HostsController()
hosts = hosts.HostsController()
commands = commands.CommandsController()
services = services.ServicesController()
reload_config = reload_config.ReloadConfigController()
# hostgroups = HostGroupsController()
# contacts = ContactsController()
# contactgroups = ContactGroupsController()
# services = ServicesController()
# servicegroups = ServiceGroupsController()
# timeperiods = TimeperiodsController()
# realms = RealmsController()
# commands = CommandsController()
# notificationways = NotificationWayController()
# engine = EngineController()
pass

View File

@ -0,0 +1,84 @@
# 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 pecan
from pecan import rest
import wsmeext.pecan as wsme_pecan
from surveil.api.controllers.v2.datamodel import command
class CommandController(rest.RestController):
def __init__(self, command_name):
pecan.request.context['command_name'] = command_name
self._id = command_name
@wsme_pecan.wsexpose(command.Command)
def get(self):
"""Returns a specific command."""
c = pecan.request.mongo_connection.shinken.commands.find_one(
{"command_name": self._id}
)
return command.Command(**c)
@wsme_pecan.wsexpose(None, body=command.Command, status_code=204)
def put(self, data):
"""Modify this command.
:param data: a command within the request body.
"""
command_dict = data.as_dict()
if "command_name" not in command_dict.keys():
command_dict['command_name'] = self._id
pecan.request.mongo_connection.shinken.commands.update(
{"command_name": self._id},
command_dict
)
@wsme_pecan.wsexpose(None, status_code=204)
def delete(self):
"""Delete this command."""
pecan.request.mongo_connection.shinken.commands.remove(
{"command_name": self._id}
)
class CommandsController(rest.RestController):
@pecan.expose()
def _lookup(self, command_id, *remainder):
return CommandController(command_id), remainder
@wsme_pecan.wsexpose([command.Command])
def get_all(self):
"""Returns all commands."""
commands = [c for c
in pecan.request.mongo_connection.shinken.commands.find()]
return [command.Command(**c) for c in commands]
@wsme_pecan.wsexpose(command.Command,
body=command.Command,
status_code=201)
def post(self, data):
"""Create a new command.
:param data: a command within the request body.
"""
pecan.request.mongo_connection.shinken.commands.insert(
data.as_dict()
)

View File

@ -0,0 +1,179 @@
# 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 pecan
from pecan import rest
import requests
import wsmeext.pecan as wsme_pecan
from surveil.api.controllers.v2.datamodel import checkresult
from surveil.api.controllers.v2.datamodel import host
from surveil.api.controllers.v2.datamodel import service
class ServiceCheckResultsSubController(rest.RestController):
@wsme_pecan.wsexpose(body=checkresult.CheckResult, status_code=204)
def post(self, data):
"""Submit a new check result.
:param data: a check result within the request body.
"""
result = data.as_dict()
result['host_name'] = pecan.request.context['host_name']
result['service_description'] = pecan.request.context[
'service_description'
]
requests.post(
pecan.request.ws_arbiter_url + "/push_check_result",
data=result
)
class HostServiceSubController(rest.RestController):
results = ServiceCheckResultsSubController()
def __init__(self, service_description):
pecan.request.context['service_description'] = service_description
self._id = service_description
@wsme_pecan.wsexpose(service.Service)
def get(self):
"""Returns a specific service."""
mongo_s = pecan.request.mongo_connection.shinken.services.find_one(
{
"host_name": pecan.request.context['host_name'],
"service_description": pecan.request.context[
'service_description'
]
}
)
return service.Service(**mongo_s)
class HostServicesSubController(rest.RestController):
@wsme_pecan.wsexpose([service.Service])
def get_all(self):
"""Returns all services assocaited with this host."""
mongo_s = [
s for s
in pecan.request.mongo_connection.shinken.services.find(
{"host_name": pecan.request.context['host_name']}
)
]
services = [service.Service(**s) for s in mongo_s]
return services
@pecan.expose()
def _lookup(self, service_description, *remainder):
return HostServiceSubController(service_description), remainder
class HostCheckResultsSubController(rest.RestController):
@wsme_pecan.wsexpose(body=checkresult.CheckResult, status_code=204)
def post(self, data):
"""Submit a new check result.
:param data: a check result within the request body.
"""
result = data.as_dict()
result['host_name'] = pecan.request.context['host_name']
requests.post(
pecan.request.ws_arbiter_url + "/push_check_result",
data=result
)
class HostSubController(rest.RestController):
services = HostServicesSubController()
results = HostCheckResultsSubController()
class HostController(rest.RestController):
def __init__(self, host_name):
pecan.request.context['host_name'] = host_name
self._id = host_name
@wsme_pecan.wsexpose(host.Host)
def get(self):
"""Returns a specific host."""
h = pecan.request.mongo_connection.shinken.hosts.find_one(
{"host_name": self._id}, {'_id': 0}
)
return host.Host(**h)
@wsme_pecan.wsexpose(None, body=host.Host, status_code=204)
def put(self, data):
"""Modify this host.
:param data: a host within the request body.
"""
host_dict = data.as_dict()
if "host_name" not in host_dict.keys():
host_dict['host_name'] = self._id
pecan.request.mongo_connection.shinken.hosts.update(
{"host_name": self._id},
host_dict
)
@wsme_pecan.wsexpose(None, status_code=204)
def delete(self):
"""Delete this host."""
pecan.request.mongo_connection.shinken.hosts.remove(
{"host_name": self._id}
)
@pecan.expose()
def _lookup(self, *remainder):
return HostSubController(), remainder
class HostsController(rest.RestController):
@pecan.expose()
def _lookup(self, host_name, *remainder):
return HostController(host_name), remainder
@wsme_pecan.wsexpose([host.Host])
def get_all(self):
"""Returns all hosts."""
hosts = [h for h
in pecan.request.mongo_connection.
shinken.hosts.find(
{"register": {"$ne": "0"}}, # Don't return templates
{'_id': 0}
)]
return [host.Host(**h) for h in hosts]
@wsme_pecan.wsexpose(host.Host, body=host.Host, status_code=201)
def post(self, data):
"""Create a new host.
:param data: a host within the request body.
"""
pecan.request.mongo_connection.shinken.hosts.insert(
data.as_dict()
)

View File

@ -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 pecan
from pecan import rest
import requests
import wsmeext.pecan as wsme_pecan
from surveil.api.controllers.v2.datamodel import info
class ReloadConfigController(rest.RestController):
@wsme_pecan.wsexpose(info.Info)
def post(self):
"""Reloads Shinken's config."""
requests.post(
pecan.request.ws_arbiter_url + "/reload"
)
return info.Info(message='Arbiter reloading.')

View File

@ -0,0 +1,46 @@
# 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 pecan
from pecan import rest
import wsmeext.pecan as wsme_pecan
from surveil.api.controllers.v2.datamodel import service
class ServicesController(rest.RestController):
@wsme_pecan.wsexpose([service.Service])
def get_all(self):
"""Returns all services."""
services = [
s for s
in pecan.request.mongo_connection.
# Don't return templates
shinken.services.find({"register": {"$ne": "0"}})
]
return [service.Service(**s) for s in services]
@wsme_pecan.wsexpose(service.Service,
body=service.Service,
status_code=201)
def post(self, data):
"""Create a new service.
:param data: a service within the request body.
"""
pecan.request.mongo_connection.shinken.services.insert(
data.as_dict()
)

View File

@ -0,0 +1,101 @@
# 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 copy
import json
from surveil.api.controllers.v2.datamodel import command
from surveil.tests.api import functionalTest
class TestCommandController(functionalTest.FunctionalTest):
def setUp(self):
super(TestCommandController, self).setUp()
self.commands = [
{u"command_name": u"check_test1",
u"command_line": u"/test/test1/test.py"},
{u"command_name": u"check_test2",
u"command_line": u"/test/test2/test.py"},
]
self.mongoconnection.shinken.commands.insert(
copy.deepcopy(self.commands)
)
def test_get_all_commands(self):
response = self.app.get('/v2/config/commands')
self.assert_count_equal_backport(
json.loads(response.body.decode()),
self.commands
)
self.assertEqual(response.status_int, 200)
def test_get_specific_command(self):
response = self.app.get('/v2/config/commands/check_test2')
self.assert_count_equal_backport(
json.loads(response.body.decode()),
self.commands[1]
)
self.assertEqual(response.status_int, 200)
def test_update_command(self):
put_body = {"command_line": "test_put",
"command_name": "check_test2"}
response = self.app.put_json(
"/v2/config/commands/check_test2", params=put_body
)
expected_command = {u"command_name": u"check_test2",
u"command_line": u"test_put"}
mongo_command = command.Command(
**self.mongoconnection.shinken.commands.find_one(
{'command_name': 'check_test2'}
)
)
self.assertEqual(expected_command, mongo_command.as_dict())
self.assertEqual(response.status_int, 204)
def test_delete_command(self):
response = self.app.delete('/v2/config/commands/check_test2')
expected_commands = [
{u"command_name": u"check_test1",
u"command_line": u"/test/test1/test.py"}
]
mongo_commands = [command.Command(**c).as_dict() for c
in self.mongoconnection.shinken.commands.find()]
self.assertEqual(expected_commands, mongo_commands)
self.assertEqual(response.status_int, 204)
def test_add_command(self):
new_command = {
"command_name": "newcommand",
"command_line": "/usr/bin/newcommand -hello"
}
response = self.app.post_json(
"/v2/config/commands",
params=new_command
)
commands = [command.Command(**c).as_dict() for c
in self.mongoconnection.shinken.commands.find()]
self.assertTrue(new_command in commands)
self.assertEqual(response.status_int, 201)

View File

@ -0,0 +1,228 @@
# 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 copy
import json
import httpretty
from surveil.api.controllers.v2.datamodel import host
from surveil.tests.api import functionalTest
class TestHostController(functionalTest.FunctionalTest):
def setUp(self):
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"
},
{
"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"
},
{
"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"
},
]
self.mongoconnection.shinken.hosts.insert(
copy.deepcopy(self.hosts)
)
self.services = [
{
"host_name": "bogus-router",
"service_description": "service-example",
"check_command": "check-disk!/dev/sdb1",
"max_check_attempts": 5,
"check_interval": 5,
"retry_interval": 3,
"check_period": "24x7",
"notification_interval": 30,
"notification_period": "24x7",
"contacts": "surveil-ptl,surveil-bob",
"contact_groups": "linux-admins"
}
]
self.mongoconnection.shinken.services.insert(
copy.deepcopy(self.services)
)
def test_get_all_hosts(self):
response = self.app.get('/v2/config/hosts')
self.assert_count_equal_backport(
json.loads(response.body.decode()),
self.hosts
)
self.assertEqual(response.status_int, 200)
def test_get_all_hosts_no_templates(self):
self.mongoconnection.shinken.hosts.insert(
copy.deepcopy(
{"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",
"register": "0"}
)
)
response = self.app.get('/v2/config/hosts')
self.assert_count_equal_backport(
json.loads(response.body.decode()),
self.hosts
)
self.assertEqual(response.status_int, 200)
def test_get_specific_host(self):
response = self.app.get('/v2/config/hosts/bogus-router333')
self.assert_count_equal_backport(
json.loads(response.body.decode()),
self.hosts[2]
)
self.assertEqual(response.status_int, 200)
def test_update_host(self):
put_host = {
u"host_name": u"bogus-router333",
u"address": u"newputaddress",
u"max_check_attempts": 222225,
u"check_period": u"newtimeperiod",
u"contacts": u"aaa,bbb",
u"contact_groups": u"newgroup",
u"notification_interval": 333,
u"notification_period": u"newnotificationperiod"
}
response = self.app.put_json(
"/v2/config/hosts/bogus-router333", params=put_host
)
mongo_host = host.Host(
**self.mongoconnection.shinken.hosts.find_one(
{'host_name': 'bogus-router333'}, {'_id': 0}
)
)
self.assertEqual(put_host, mongo_host.as_dict())
self.assertEqual(response.status_int, 204)
def test_delete_host(self):
response = self.app.delete('/v2/config/hosts/bogus-router')
mongo_hosts = [host.Host(**h) for h
in self.mongoconnection.shinken.hosts.find()]
self.assertEqual(2, len(mongo_hosts))
self.assertEqual(response.status_int, 204)
def test_add_host(self):
new_host = {
"host_name": "testpost",
"address": "192.168.1.254",
"max_check_attempts": 5,
"check_period": "24x7",
"contacts": "admin,carl",
"contact_groups": "router-admins",
"notification_interval": 3,
"notification_period": "24x7"
}
response = self.app.post_json("/v2/config/hosts", params=new_host)
hosts = [host.Host(**h).as_dict() for h
in self.mongoconnection.shinken.hosts.find(None, {'_id': 0})]
self.assertTrue(new_host in hosts)
self.assertEqual(response.status_int, 201)
def test_get_associated_services(self):
response = self.app.get('/v2/config/hosts/bogus-router/services')
self.assertEqual(
self.services,
json.loads(response.body.decode())
)
def test_get_specific_service(self):
response = self.app.get(
'/v2/config/hosts/bogus-router/services/service-example'
)
self.assertEqual(
self.services[0],
json.loads(response.body.decode())
)
@httpretty.activate
def test_submit_service_result(self):
httpretty.register_uri(httpretty.POST,
self.ws_arbiter_url + "/push_check_result")
check_result = {
"return_code": "0",
"output": "TEST OUTPUT",
"time_stamp": "1409149234"
}
response = self.app.post_json(
"/v2/config/hosts/bogus-router/services/service-example/results",
params=check_result
)
self.assertEqual(response.status_int, 204)
self.assertEqual(
httpretty.last_request().parsed_body,
{
u'output': [u'TEST OUTPUT'],
u'return_code': [u'0'],
u'service_description': [u'service-example'],
u'host_name': [u'bogus-router'],
u'time_stamp': [u'1409149234']
}
)
@httpretty.activate
def test_submit_host_result(self):
httpretty.register_uri(httpretty.POST,
self.ws_arbiter_url + "/push_check_result")
check_result = {
"return_code": "0",
"output": "TEST OUTPUT",
"time_stamp": "1409149234"
}
response = self.app.post_json("/v2/config/hosts/bogus-router/results",
params=check_result)
self.assertEqual(response.status_int, 204)
self.assertEqual(
httpretty.last_request().parsed_body,
{
u'output': [u'TEST OUTPUT'],
u'return_code': [u'0'],
u'host_name': [u'bogus-router'],
u'time_stamp': [u'1409149234']
}
)

View File

@ -0,0 +1,32 @@
# 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 httpretty
from surveil.tests.api import functionalTest
class TestReloadConfigController(functionalTest.FunctionalTest):
@httpretty.activate
def test_reload_config(self):
httpretty.register_uri(httpretty.POST,
self.ws_arbiter_url + "/reload")
response = self.app.post("/v2/config/reload_config")
self.assertEqual(response.status_int, 200)
self.assertEqual(
httpretty.last_request().path,
'/reload'
)

View File

@ -0,0 +1,128 @@
# 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 copy
import json
from surveil.api.controllers.v2.datamodel import service
from surveil.tests.api import functionalTest
class TestServiceController(functionalTest.FunctionalTest):
def setUp(self):
super(TestServiceController, self).setUp()
self.services = [
{
"host_name": "sample-server1",
"service_description": "check-",
"check_command": "check-disk!/dev/sdb1",
"max_check_attempts": 5,
"check_interval": 5,
"retry_interval": 3,
"check_period": "24x7",
"notification_interval": 30,
"notification_period": "24x7",
"contacts": "surveil-ptl,surveil-bob",
"contact_groups": "linux-admins"
},
{
"host_name": "sample-server2",
"service_description": "check-disk-sdb",
"check_command": "check-disk!/dev/sdb1",
"max_check_attempts": 5,
"check_interval": 5,
"retry_interval": 3,
"check_period": "24x7",
"notification_interval": 30,
"notification_period": "24x7",
"contacts": "surveil-ptl,surveil-bob",
"contact_groups": "linux-admins"
},
{
"host_name": "sample-server3",
"service_description": "check-disk-sdb",
"check_command": "check-disk!/dev/sdb1",
"max_check_attempts": 5,
"check_interval": 5,
"retry_interval": 3,
"check_period": "24x7",
"notification_interval": 30,
"notification_period": "24x7",
"contacts": "surveil-ptl,surveil-bob",
"contact_groups": "linux-admins"
},
]
self.mongoconnection.shinken.services.insert(
copy.deepcopy(self.services)
)
def test_get_all_services(self):
response = self.app.get('/v2/config/services')
self.assert_count_equal_backport(
json.loads(response.body.decode()),
self.services
)
self.assertEqual(response.status_int, 200)
def test_get_all_services_no_templates(self):
self.mongoconnection.shinken.services.insert(
copy.deepcopy(
{"host_name": "sample-server3",
"service_description": "check-disk-sdb",
"check_command": "check-disk!/dev/sdb1",
"max_check_attempts": 5,
"check_interval": 5,
"retry_interval": 3,
"check_period": "24x7",
"notification_interval": 30,
"notification_period": "24x7",
"contacts": "surveil-ptl,surveil-bob",
"register": "0",
"contact_groups": "linux-admins"}
)
)
response = self.app.get('/v2/config/services')
self.assert_count_equal_backport(
json.loads(response.body.decode()),
self.services
)
self.assertEqual(response.status_int, 200)
def test_add_host(self):
new_service = {
"host_name": "SOMEHOSTNAME",
"service_description": "check-new-thing",
"check_command": "check-disk!/dev/sdb1",
"max_check_attempts": 5,
"check_interval": 5,
"retry_interval": 3,
"check_period": "24x7",
"notification_interval": 30,
"notification_period": "24x7",
"contacts": "surveil-ptl,surveil-bob",
"contact_groups": "linux-admins"
}
response = self.app.post_json(
"/v2/config/services",
params=new_service
)
services = [service.Service(**s).as_dict() for s in
self.mongoconnection.shinken.services.find()]
self.assertTrue(new_service in services)
self.assertEqual(response.status_int, 201)