Merge "API layer add services list"
This commit is contained in:
commit
036cb7d765
|
@ -49,5 +49,6 @@
|
|||
"actions:get": "",
|
||||
"events:index": "",
|
||||
"events:get": "",
|
||||
"webhooks:trigger": ""
|
||||
"webhooks:trigger": "",
|
||||
"services:index": "role:admin"
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@ from senlin.api.openstack.v1 import policy_types
|
|||
from senlin.api.openstack.v1 import profile_types
|
||||
from senlin.api.openstack.v1 import profiles
|
||||
from senlin.api.openstack.v1 import receivers
|
||||
from senlin.api.openstack.v1 import services
|
||||
from senlin.api.openstack.v1 import version
|
||||
from senlin.api.openstack.v1 import webhooks
|
||||
|
||||
|
@ -306,3 +307,14 @@ class API(wsgi.Router):
|
|||
conditions={'method': 'GET'})
|
||||
|
||||
super(API, self).__init__(mapper)
|
||||
|
||||
# Services
|
||||
res = wsgi.Resource(services.ServiceController(conf))
|
||||
with mapper.submapper(controller=res) as sub_mapper:
|
||||
|
||||
sub_mapper.connect("service_index",
|
||||
"/services",
|
||||
action="index",
|
||||
conditions={'method': 'GET'})
|
||||
|
||||
super(API, self).__init__(mapper)
|
||||
|
|
|
@ -0,0 +1,53 @@
|
|||
#
|
||||
# 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 oslo_config import cfg
|
||||
from oslo_utils import timeutils
|
||||
from senlin.api.common import util
|
||||
from senlin.api.common import wsgi
|
||||
from senlin.common import exception
|
||||
from senlin.objects import service as service_obj
|
||||
|
||||
CONF = cfg.CONF
|
||||
|
||||
|
||||
class ServiceController(wsgi.Controller):
|
||||
"""WSGI controller for Services in Senlin v1 API."""
|
||||
|
||||
REQUEST_SCOPE = 'services'
|
||||
|
||||
@util.policy_enforce
|
||||
def index(self, req):
|
||||
if not req.context.is_admin:
|
||||
raise exception.Forbidden()
|
||||
now = timeutils.utcnow(with_timezone=True)
|
||||
_services = service_obj.Service.get_all(req.context)
|
||||
svcs = []
|
||||
for svc in _services:
|
||||
updated_at = svc.updated_at
|
||||
delta = now - (svc.updated_at or svc.created_at)
|
||||
delta_sec = delta.total_seconds()
|
||||
alive = abs(delta_sec) <= CONF.service_down_time
|
||||
art = (alive and "up") or "down"
|
||||
active = 'enabled'
|
||||
if svc.disabled:
|
||||
active = 'disabled'
|
||||
if updated_at:
|
||||
updated_at = timeutils.normalize_time(updated_at)
|
||||
ret_fields = {'id': svc.id, 'host': svc.host,
|
||||
'binary': svc.binary, 'topic': svc.topic,
|
||||
'disabled_reason': svc.disabled_reason,
|
||||
'status': active, 'state': art,
|
||||
'updated_at': updated_at}
|
||||
svcs.append(ret_fields)
|
||||
return {'services': svcs}
|
|
@ -90,6 +90,10 @@ engine_opts = [
|
|||
default=False,
|
||||
help=_('Flag to indicate whether to enforce unique names for '
|
||||
'Senlin objects belonging to the same project.')),
|
||||
cfg.IntOpt('service_down_time',
|
||||
default=60,
|
||||
help='Maximum time since last check-in for a service to be '
|
||||
'considered up'),
|
||||
]
|
||||
cfg.CONF.register_opts(engine_opts)
|
||||
|
||||
|
|
|
@ -0,0 +1,73 @@
|
|||
# Copyright 2012 IBM
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# 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 datetime
|
||||
import mock
|
||||
|
||||
from iso8601 import iso8601
|
||||
|
||||
from senlin.api.openstack.v1 import services
|
||||
from senlin.common import policy
|
||||
from senlin.objects import service as service_obj
|
||||
from senlin.tests.unit.api import shared
|
||||
from senlin.tests.unit.common import base
|
||||
|
||||
|
||||
fake_services_list = [
|
||||
mock.Mock(binary='senlin-engine',
|
||||
host='host1',
|
||||
id=1,
|
||||
disabled=False,
|
||||
topic='senlin-engine',
|
||||
updated_at=datetime.datetime(2012, 10, 29, 13, 42, 11,
|
||||
tzinfo=iso8601.Utc()),
|
||||
created_at=datetime.datetime(2014, 10, 29, 13, 42, 11,
|
||||
tzinfo=iso8601.Utc()),
|
||||
disabled_reason='')
|
||||
]
|
||||
|
||||
|
||||
@mock.patch.object(policy, 'enforce')
|
||||
class ServicesControllerTest(shared.ControllerTest, base.SenlinTestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(ServicesControllerTest, self).setUp()
|
||||
|
||||
# Create WSGI controller instance
|
||||
class DummyConfig(object):
|
||||
bind_port = 8778
|
||||
|
||||
cfgopts = DummyConfig()
|
||||
self.controller = services.ServiceController(options=cfgopts)
|
||||
|
||||
def tearDown(self):
|
||||
super(ServicesControllerTest, self).tearDown()
|
||||
|
||||
@mock.patch.object(service_obj.Service, 'get_all')
|
||||
def test_service_index(self, mock_call, mock_enforce):
|
||||
self._mock_enforce_setup(mock_enforce, 'index', True)
|
||||
req = self._get('/services')
|
||||
req.context.is_admin = True
|
||||
|
||||
mock_call.return_value = fake_services_list
|
||||
res_dict = self.controller.index(req)
|
||||
|
||||
response = {'services': [{'topic': 'senlin-engine',
|
||||
'binary': 'senlin-engine', 'id': 1,
|
||||
'host': 'host1', 'status': 'enabled',
|
||||
'state': 'down', 'disabled_reason': '',
|
||||
'updated_at': datetime.datetime(
|
||||
2012, 10, 29, 13, 42, 11)}]}
|
||||
self.assertEqual(res_dict, response)
|
Loading…
Reference in New Issue