Add a new microversion for data model API
microversion 1.3 for list data model API Change-Id: Ibf8774a48c3d13ca9762bd5319f5e1ce2ed82b2f Closes-Bug: #1854121
This commit is contained in:
parent
42fea1c568
commit
6f43f2b003
@ -30,3 +30,7 @@ audits.
|
|||||||
---
|
---
|
||||||
Added ``force`` into create audit request. If ``force`` is true,
|
Added ``force`` into create audit request. If ``force`` is true,
|
||||||
audit will be executed despite of ongoing actionplan.
|
audit will be executed despite of ongoing actionplan.
|
||||||
|
|
||||||
|
1.3
|
||||||
|
---
|
||||||
|
Added list data model API.
|
||||||
|
@ -40,6 +40,7 @@ from watcher.api.controllers.v1 import goal
|
|||||||
from watcher.api.controllers.v1 import scoring_engine
|
from watcher.api.controllers.v1 import scoring_engine
|
||||||
from watcher.api.controllers.v1 import service
|
from watcher.api.controllers.v1 import service
|
||||||
from watcher.api.controllers.v1 import strategy
|
from watcher.api.controllers.v1 import strategy
|
||||||
|
from watcher.api.controllers.v1 import utils
|
||||||
from watcher.api.controllers.v1 import versions
|
from watcher.api.controllers.v1 import versions
|
||||||
|
|
||||||
|
|
||||||
@ -163,6 +164,7 @@ class V1(APIBase):
|
|||||||
'audits', '',
|
'audits', '',
|
||||||
bookmark=True)
|
bookmark=True)
|
||||||
]
|
]
|
||||||
|
if utils.allow_list_datamodel():
|
||||||
v1.data_model = [link.Link.make_link('self', base_url,
|
v1.data_model = [link.Link.make_link('self', base_url,
|
||||||
'data_model', ''),
|
'data_model', ''),
|
||||||
link.Link.make_link('bookmark',
|
link.Link.make_link('bookmark',
|
||||||
|
@ -24,6 +24,7 @@ from wsme import types as wtypes
|
|||||||
import wsmeext.pecan as wsme_pecan
|
import wsmeext.pecan as wsme_pecan
|
||||||
|
|
||||||
from watcher.api.controllers.v1 import types
|
from watcher.api.controllers.v1 import types
|
||||||
|
from watcher.api.controllers.v1 import utils
|
||||||
from watcher.common import exception
|
from watcher.common import exception
|
||||||
from watcher.common import policy
|
from watcher.common import policy
|
||||||
from watcher.decision_engine import rpcapi
|
from watcher.decision_engine import rpcapi
|
||||||
@ -49,6 +50,8 @@ class DataModelController(rest.RestController):
|
|||||||
:param audit_uuid: The UUID of the audit, used to filter data model
|
:param audit_uuid: The UUID of the audit, used to filter data model
|
||||||
by the scope in audit.
|
by the scope in audit.
|
||||||
"""
|
"""
|
||||||
|
if not utils.allow_list_datamodel():
|
||||||
|
raise exception.NotAcceptable
|
||||||
if self.from_data_model:
|
if self.from_data_model:
|
||||||
raise exception.OperationNotPermitted
|
raise exception.OperationNotPermitted
|
||||||
allowed_data_model_type = [
|
allowed_data_model_type = [
|
||||||
|
@ -176,3 +176,12 @@ def allow_force():
|
|||||||
"""
|
"""
|
||||||
return pecan.request.version.minor >= (
|
return pecan.request.version.minor >= (
|
||||||
versions.VERSIONS.MINOR_2_FORCE.value)
|
versions.VERSIONS.MINOR_2_FORCE.value)
|
||||||
|
|
||||||
|
|
||||||
|
def allow_list_datamodel():
|
||||||
|
"""Check if we should support list data model API.
|
||||||
|
|
||||||
|
Version 1.3 of the API added support to list data model.
|
||||||
|
"""
|
||||||
|
return pecan.request.version.minor >= (
|
||||||
|
versions.VERSIONS.MINOR_3_DATAMODEL.value)
|
||||||
|
@ -21,7 +21,8 @@ class VERSIONS(enum.Enum):
|
|||||||
MINOR_0_ROCKY = 0 # v1.0: corresponds to Rocky API
|
MINOR_0_ROCKY = 0 # v1.0: corresponds to Rocky API
|
||||||
MINOR_1_START_END_TIMING = 1 # v1.1: Add start/end timei for audit
|
MINOR_1_START_END_TIMING = 1 # v1.1: Add start/end timei for audit
|
||||||
MINOR_2_FORCE = 2 # v1.2: Add force field to audit
|
MINOR_2_FORCE = 2 # v1.2: Add force field to audit
|
||||||
MINOR_MAX_VERSION = 2
|
MINOR_3_DATAMODEL = 3 # v1.3: Add list datamodel API
|
||||||
|
MINOR_MAX_VERSION = 3
|
||||||
|
|
||||||
# This is the version 1 API
|
# This is the version 1 API
|
||||||
BASE_VERSION = 1
|
BASE_VERSION = 1
|
||||||
|
@ -27,8 +27,9 @@ class TestRoot(base.FunctionalTest):
|
|||||||
|
|
||||||
class TestV1Root(base.FunctionalTest):
|
class TestV1Root(base.FunctionalTest):
|
||||||
|
|
||||||
def test_get_v1_root(self):
|
def test_get_v1_root_all(self):
|
||||||
data = self.get_json('/')
|
data = self.get_json(
|
||||||
|
'/', headers={'OpenStack-API-Version': 'infra-optim 1.3'})
|
||||||
self.assertEqual('v1', data['id'])
|
self.assertEqual('v1', data['id'])
|
||||||
# Check fields are not empty
|
# Check fields are not empty
|
||||||
for f in data.keys():
|
for f in data.keys():
|
||||||
@ -43,3 +44,21 @@ class TestV1Root(base.FunctionalTest):
|
|||||||
|
|
||||||
self.assertIn({'type': 'application/vnd.openstack.watcher.v1+json',
|
self.assertIn({'type': 'application/vnd.openstack.watcher.v1+json',
|
||||||
'base': 'application/json'}, data['media_types'])
|
'base': 'application/json'}, data['media_types'])
|
||||||
|
|
||||||
|
def test_get_v1_root_without_datamodel(self):
|
||||||
|
data = self.get_json(
|
||||||
|
'/', headers={'OpenStack-API-Version': 'infra-optim 1.2'})
|
||||||
|
self.assertEqual('v1', data['id'])
|
||||||
|
# Check fields are not empty
|
||||||
|
for f in data.keys():
|
||||||
|
self.assertNotIn(f, ['', []])
|
||||||
|
# Check if all known resources are present and there are no extra ones.
|
||||||
|
not_resources = ('id', 'links', 'media_types')
|
||||||
|
actual_resources = tuple(set(data.keys()) - set(not_resources))
|
||||||
|
expected_resources = ('audit_templates', 'audits', 'actions',
|
||||||
|
'action_plans', 'scoring_engines',
|
||||||
|
'services')
|
||||||
|
self.assertEqual(sorted(expected_resources), sorted(actual_resources))
|
||||||
|
|
||||||
|
self.assertIn({'type': 'application/vnd.openstack.watcher.v1+json',
|
||||||
|
'base': 'application/json'}, data['media_types'])
|
||||||
|
@ -32,9 +32,18 @@ class TestListDataModel(api_base.FunctionalTest):
|
|||||||
self.addCleanup(p_dcapi.stop)
|
self.addCleanup(p_dcapi.stop)
|
||||||
|
|
||||||
def test_get_all(self):
|
def test_get_all(self):
|
||||||
response = self.get_json('/data_model/?data_model_type=compute')
|
response = self.get_json(
|
||||||
|
'/data_model/?data_model_type=compute',
|
||||||
|
headers={'OpenStack-API-Version': 'infra-optim 1.3'})
|
||||||
self.assertEqual('fake_response_value', response)
|
self.assertEqual('fake_response_value', response)
|
||||||
|
|
||||||
|
def test_get_all_not_acceptable(self):
|
||||||
|
response = self.get_json(
|
||||||
|
'/data_model/?data_model_type=compute',
|
||||||
|
headers={'OpenStack-API-Version': 'infra-optim 1.2'},
|
||||||
|
expect_errors=True)
|
||||||
|
self.assertEqual(406, response.status_int)
|
||||||
|
|
||||||
|
|
||||||
class TestDataModelPolicyEnforcement(api_base.FunctionalTest):
|
class TestDataModelPolicyEnforcement(api_base.FunctionalTest):
|
||||||
|
|
||||||
@ -60,6 +69,7 @@ class TestDataModelPolicyEnforcement(api_base.FunctionalTest):
|
|||||||
self._common_policy_check(
|
self._common_policy_check(
|
||||||
"data_model:get_all", self.get_json,
|
"data_model:get_all", self.get_json,
|
||||||
"/data_model/?data_model_type=compute",
|
"/data_model/?data_model_type=compute",
|
||||||
|
headers={'OpenStack-API-Version': 'infra-optim 1.3'},
|
||||||
expect_errors=True)
|
expect_errors=True)
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user