Add new api vitrage status

To Check if vitrage is ready then you can check its
status some users don't want to check on every api call
if vitrage is ready, in that case you can check ad hoc

Change-Id: Icf39361ae47bc132bab760507967907f34b81821
This commit is contained in:
Eyal 2019-07-01 12:55:49 +03:00
parent e5998619ed
commit 5212c8021c
9 changed files with 216 additions and 3 deletions

View File

@ -2001,4 +2001,70 @@ Response Examples
"version": "v3",
"status": "CURRENT"
}
]
]
Status
^^^^^^
prints the status of vitrage
GET /v1/status
~~~~~~~~~~~~~~~
Headers
=======
- X-Auth-Token (string, required) - Keystone auth token
- Accept (string) - application/json
Path Parameters
===============
None.
Query Parameters
================
None.
Request Body
============
None.
Request Examples
================
::
GET //v1/status HTTP/1.1
Host: 135.248.19.18:8999
X-Auth-Token: 2b8882ba2ec44295bf300aecb2caa4f7
Accept: application/json
ResponseStatus code
===================
- 200 - OK
- 503 - Service Unavailable vitrage-graph is not ready
- 503 - Service Unavailable vitrage-graph is not available
Response Body
=============
Returns a JSON object with ok status
or 503 status code if not ok
Response Examples
=================
::
{
"reason": "OK"
}

View File

@ -0,0 +1,3 @@
---
features:
- Added a new API to show vitrage status.

View File

@ -30,5 +30,5 @@ OPTS = [
'keycloak'},
help='Authentication mode to use.'),
cfg.BoolOpt('check_backend', default=True,
help='Check that that backend is ready before an api call')
help='Check that backend is ready before an api call')
]

View File

@ -16,6 +16,7 @@ from vitrage.api.controllers.v1 import event
from vitrage.api.controllers.v1 import rca
from vitrage.api.controllers.v1 import resource
from vitrage.api.controllers.v1 import service
from vitrage.api.controllers.v1 import status
from vitrage.api.controllers.v1 import template
from vitrage.api.controllers.v1 import topology
from vitrage.api.controllers.v1 import webhook
@ -33,3 +34,4 @@ class V1Controller(object):
template = template.TemplateController()
event = event.EventController()
service = service.ServiceController()
status = status.StatusController()

View File

@ -18,13 +18,14 @@ from oslo_log import log
import pecan
from pecan.core import abort
from vitrage.api.controllers.rest import RootRestController
from vitrage.api.policy import enforce
LOG = log.getLogger(__name__)
# noinspection PyBroadException
class ServiceController(object):
class ServiceController(RootRestController):
@pecan.expose('json')
def index(self):
return self.get()

View File

@ -0,0 +1,38 @@
# Copyright 2019 - Nokia Corporation
#
# 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 oslo_messaging
import pecan
from pecan import rest
from vitrage.api.policy import enforce
class StatusController(rest.RestController):
@pecan.expose('json')
def index(self):
return self.get()
@pecan.expose('json')
def get(self):
enforce("get status", pecan.request.headers,
pecan.request.enforcer, {})
try:
client = pecan.request.client.prepare(timeout=5)
backend_is_alive = client.call(pecan.request.context, 'is_alive')
if backend_is_alive:
return {'reason': 'OK'}
else:
pecan.abort(503, detail='vitrage-graph is not ready')
except oslo_messaging.MessagingTimeout:
pecan.abort(503, detail='vitrage-graph is not available')

View File

@ -17,6 +17,7 @@ from vitrage.common.policies import event
from vitrage.common.policies import rca
from vitrage.common.policies import resource
from vitrage.common.policies import service
from vitrage.common.policies import status
from vitrage.common.policies import template
from vitrage.common.policies import topology
from vitrage.common.policies import webhook
@ -32,4 +33,5 @@ def list_rules():
resource.list_rules(),
webhook.list_rules(),
service.list_rules(),
status.list_rules(),
)

View File

@ -0,0 +1,37 @@
# Copyright 2019 - Nokia Corporation
#
# 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_policy import policy
from vitrage.common.policies import base
STATUS = 'get status'
rules = [
policy.DocumentedRuleDefault(
name=STATUS,
check_str=base.UNPROTECTED,
description='Get the vitrage status for the OpenStack cluster',
operations=[
{
'path': '/status',
'method': 'GET'
}
]
)
]
def list_rules():
return rules

View File

@ -0,0 +1,64 @@
# Copyright 2019 - Nokia Corporation
#
# 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.
#
# 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 mock
import oslo_messaging
from vitrage.tests.functional.api.v1 import FunctionalTest
class StatusTest(FunctionalTest):
def __init__(self, *args, **kwds):
super(StatusTest, self).__init__(*args, **kwds)
self.auth = 'noauth'
def test_get_status_ok(self):
with mock.patch('pecan.request') as request:
client = mock.Mock()
client.call.return_value = True
request.client.prepare.return_value = client
resp = self.get_json('/status/')
self.assert_dict_equal({'reason': 'OK'}, resp)
def test_get_status_not_ok(self):
with mock.patch('pecan.request') as request:
client = mock.Mock()
client.call.return_value = False
request.client.prepare.return_value = client
resp = self.get_json('/status/', expect_errors=True)
self.assertEqual(503, resp.status_code)
self.assertIn('vitrage-graph is not ready', resp.text)
def test_get_status_not_ok_timeout(self):
with mock.patch('pecan.request') as request:
client = mock.Mock()
client.call.side_effect = oslo_messaging.MessagingTimeout()
request.client.prepare.return_value = client
resp = self.get_json('/status/', expect_errors=True)
self.assertEqual(503, resp.status_code)
self.assertIn('vitrage-graph is not available', resp.text)