Merge "Merged v2's API skeleton"

This commit is contained in:
Jenkins 2015-03-20 20:21:26 +00:00 committed by Gerrit Code Review
commit 8d9934e095
20 changed files with 654 additions and 0 deletions

View File

@ -13,7 +13,9 @@
# under the License.
from surveil.api.controllers.v1 import v1
from surveil.api.controllers.v2 import v2
class RootController(object):
v1 = v1.V1Controller()
v2 = v2.V2Controller()

View File

View File

@ -0,0 +1,21 @@
# 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 pecan import rest
class ActionsController(rest.RestController):
# externalcommands = ExternalCommandsController()
# engine = EngineController()
pass

View File

@ -0,0 +1,20 @@
# 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 pecan import rest
class AdminController(rest.RestController):
# admin = AdminController()
pass

View File

@ -0,0 +1,21 @@
# 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 pecan import rest
class AuthController(rest.RestController):
# login = LoginController()
# logout = LogoutController()
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.v1.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,31 @@
# 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 pecan import rest
class ConfigController(rest.RestController):
"""Root config controller."""
# hosts = HostsController()
# 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,41 @@
# 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 time
import wsme
import wsme.types as wtypes
from surveil.api.controllers.v1.datamodel import types
class CheckResult(types.Base):
time_stamp = wsme.wsattr(wtypes.text,
mandatory=False,
default=str(int(time.time())))
"""The time the check was executed. Defaults to now."""
return_code = wsme.wsattr(int, mandatory=True)
"""The return code of the check."""
output = wsme.wsattr(wtypes.text, mandatory=True)
"""The output of the check."""
@classmethod
def sample(cls):
return cls(
time_stamp="1409087486",
return_code=0,
output="CPU Usage 98%|c[cpu]=98%;80;95;0;100"
)

View File

@ -0,0 +1,41 @@
# 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 wsme
import wsme.types as wtypes
from surveil.api.controllers.v1.datamodel import types
# import shinken.objects
# Command = type(
# 'Command',
# (wtypes.Base,),
# {key: wtypes.text for key in shinken.objects.Command.properties.keys()}
# )
class Command(types.Base):
command_name = wsme.wsattr(wtypes.text, mandatory=True)
"""The name of the command"""
command_line = wsme.wsattr(wtypes.text, mandatory=True)
"""This directive is used to define what is actually executed by Shinken"""
@classmethod
def sample(cls):
return cls(
command_name="check_http",
command_line="/bin/check_http"
)

View File

@ -0,0 +1,86 @@
# 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 wsme
import wsme.types as wtypes
from surveil.api.controllers.v1.datamodel import types
class Host(types.Base):
host_name = wsme.wsattr(wtypes.text, mandatory=True)
"""The name of the host"""
address = wsme.wsattr(wtypes.text, mandatory=True)
"""The address of the host. Normally, this is an IP address."""
max_check_attempts = wsme.wsattr(int, mandatory=False, default=3)
check_period = wsme.wsattr(wtypes.text, mandatory=False, default='24x7')
"""The time period during which active checks of this host can be made."""
contacts = wsme.wsattr(wtypes.text, mandatory=False, default='')
"""A list of the short names of the contacts that should be notified."""
contact_groups = wsme.wsattr(wtypes.text, mandatory=False, default='')
"""List of the short names of the contact groups that should be notified"""
notification_interval = wsme.wsattr(int, mandatory=False, default=30)
notification_period = wsme.wsattr(wtypes.text, mandatory=False,
default='24x7')
use = wsme.wsattr(wtypes.text, mandatory=False)
"""The template to use for this host"""
# TODO(aviau): Custom fields starting without '_' should raise an error.
custom_fields = wsme.wsattr(
wtypes.DictType(wtypes.text, wtypes.text),
mandatory=False
)
"""Custom fields for the host"""
def __init__(self, **kwargs):
super(Host, self).__init__(**kwargs)
# Custom fields start with '_'. Detect them ans assign them.
custom_fields = [i for i in kwargs.items()
if isinstance(i[0], str) and i[0][0] == '_']
if len(custom_fields) > 0:
self.custom_fields = {}
for item in custom_fields:
self.custom_fields[item[0]] = item[1]
def as_dict(self):
host_dict = super(Host, self).as_dict()
custom_fields = host_dict.pop("custom_fields", None)
if custom_fields:
for item in custom_fields.items():
host_dict[item[0]] = item[1]
return host_dict
@classmethod
def sample(cls):
return cls(
use="generic-host",
host_name="bogus-router",
address="192.168.1.254",
max_check_attempts=5,
check_period="24x7",
contacts="admin,carl",
contact_groups="router-admins",
notification_interval=30,
notification_period="24x7",
custom_fields={"OS_AUTH_URL": "http://localhost:8080/v2"}
)

View File

@ -0,0 +1,19 @@
# 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 wsme
class Info(wsme.types.Base):
message = wsme.types.text

View File

@ -0,0 +1,58 @@
# 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 wsme
import wsme.types as wtypes
from surveil.api.controllers.v1.datamodel import types
class Service(types.Base):
host_name = wsme.wsattr(wtypes.text, mandatory=True)
service_description = wsme.wsattr(wtypes.text, mandatory=True)
check_command = wsme.wsattr(wtypes.text, mandatory=True)
max_check_attempts = wsme.wsattr(int, mandatory=True)
check_interval = wsme.wsattr(int, mandatory=True)
retry_interval = wsme.wsattr(int, mandatory=True)
check_period = wsme.wsattr(wtypes.text, mandatory=True)
notification_interval = wsme.wsattr(int, mandatory=True)
notification_period = wsme.wsattr(wtypes.text, mandatory=True)
contacts = wsme.wsattr(wtypes.text, mandatory=True)
contact_groups = wsme.wsattr(wtypes.text, mandatory=True)
@classmethod
def sample(cls):
return cls(
host_name="sample-server",
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=3,
notification_period="24x7",
contacts="surveil-ptl,surveil-bob",
contact_groups="linux-admins",
)

View File

@ -0,0 +1,36 @@
# 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 inspect
import wsme
from wsme import types as wtypes
class Base(wtypes.Base):
"""Base class for all API types."""
def as_dict(self):
keys = [
member[0] for member
in inspect.getmembers(self.__class__)
if member[0][0] is not '_' and type(member[1]) is wtypes.wsattr
]
return self.as_dict_from_keys(keys)
def as_dict_from_keys(self, keys):
return dict((k, getattr(self, k))
for k in keys
if hasattr(self, k) and
getattr(self, k) != wsme.Unset)

View File

@ -0,0 +1,24 @@
# 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
class HelloController(rest.RestController):
@pecan.expose()
def get(self):
"""Says hello."""
return "Hello World!"

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.v1.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.v1.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,24 @@
# 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 pecan import rest
from surveil.api.controllers.v2.status import hosts as v2_hosts
class StatusController(rest.RestController):
# events = EventsController()
hosts = v2_hosts.HostsController()
# services = ServicesController()
# metrics = MetricsController()

View File

@ -0,0 +1,39 @@
# 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
class HostsController(rest.RestController):
# curl -X GET http://127.0.0.1:8080/v2/titilambert/myproject/builds/
# @wsme_pecan.wsexpose([Host])
@pecan.expose()
def get_all(self):
"""Returns all hosts with filters ???"""
pass
@pecan.expose()
def _lookup(self, host_id, *remainder):
return HostController(host_id), remainder
class HostController(rest.RestController):
# events = EventsController()
# config = ConfigController()
# services = ServicesController()
# metrics = MetricsController()
# externalcommands = ExternalCommandsController()
pass

View File

@ -0,0 +1,28 @@
# 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.controllers.v2 import actions as v2_actions
from surveil.api.controllers.v2 import admin as v2_admin
from surveil.api.controllers.v2 import auth as v2_auth
from surveil.api.controllers.v2 import config as v2_config
from surveil.api.controllers.v2 import status as v2_status
class V2Controller(object):
"""Version 2 API controller root."""
actions = v2_actions.ActionsController()
config = v2_config.ConfigController()
status = v2_status.StatusController()
surveil = v2_admin.AdminController()
auth = v2_auth.AuthController()