Browse Source

Merge "Implement watcher datamodel list in watcher-api"

changes/22/681222/1
Zuul 1 week ago
parent
commit
f274ef87ed

+ 12
- 0
watcher/api/controllers/v1/__init__.py View File

@@ -35,6 +35,7 @@ from watcher.api.controllers.v1 import action
35 35
 from watcher.api.controllers.v1 import action_plan
36 36
 from watcher.api.controllers.v1 import audit
37 37
 from watcher.api.controllers.v1 import audit_template
38
+from watcher.api.controllers.v1 import data_model
38 39
 from watcher.api.controllers.v1 import goal
39 40
 from watcher.api.controllers.v1 import scoring_engine
40 41
 from watcher.api.controllers.v1 import service
@@ -114,6 +115,9 @@ class V1(APIBase):
114 115
     audits = [link.Link]
115 116
     """Links to the audits resource"""
116 117
 
118
+    data_model = [link.Link]
119
+    """Links to the data model resource"""
120
+
117 121
     actions = [link.Link]
118 122
     """Links to the actions resource"""
119 123
 
@@ -158,6 +162,13 @@ class V1(APIBase):
158 162
                                          'audits', '',
159 163
                                          bookmark=True)
160 164
                      ]
165
+        v1.data_model = [link.Link.make_link('self', pecan.request.host_url,
166
+                                             'data_model', ''),
167
+                         link.Link.make_link('bookmark',
168
+                                             pecan.request.host_url,
169
+                                             'data_model', '',
170
+                                             bookmark=True)
171
+                         ]
161 172
         v1.actions = [link.Link.make_link('self', pecan.request.host_url,
162 173
                                           'actions', ''),
163 174
                       link.Link.make_link('bookmark',
@@ -202,6 +213,7 @@ class Controller(rest.RestController):
202 213
     scoring_engines = scoring_engine.ScoringEngineController()
203 214
     services = service.ServicesController()
204 215
     strategies = strategy.StrategiesController()
216
+    data_model = data_model.DataModelController()
205 217
 
206 218
     @wsme_pecan.wsexpose(V1)
207 219
     def get(self):

+ 68
- 0
watcher/api/controllers/v1/data_model.py View File

@@ -0,0 +1,68 @@
1
+# -*- encoding: utf-8 -*-
2
+# Copyright (c) 2019 ZTE Corporation
3
+#
4
+# Licensed under the Apache License, Version 2.0 (the "License");
5
+# you may not use this file except in compliance with the License.
6
+# You may obtain a copy of the License at
7
+#
8
+#    http://www.apache.org/licenses/LICENSE-2.0
9
+#
10
+# Unless required by applicable law or agreed to in writing, software
11
+# distributed under the License is distributed on an "AS IS" BASIS,
12
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
13
+# implied.
14
+# See the License for the specific language governing permissions and
15
+# limitations under the License.
16
+
17
+"""
18
+An Interface for users and admin to List Data Model.
19
+"""
20
+
21
+import pecan
22
+from pecan import rest
23
+from wsme import types as wtypes
24
+import wsmeext.pecan as wsme_pecan
25
+
26
+from watcher.api.controllers.v1 import types
27
+from watcher.common import exception
28
+from watcher.common import policy
29
+from watcher.decision_engine import rpcapi
30
+
31
+
32
+class DataModelController(rest.RestController):
33
+    """REST controller for data model"""
34
+    def __init__(self):
35
+        super(DataModelController, self).__init__()
36
+
37
+    from_data_model = False
38
+    """A flag to indicate if the requests to this controller are coming
39
+    from the top-level resource DataModel."""
40
+
41
+    @wsme_pecan.wsexpose(wtypes.text, wtypes.text, types.uuid)
42
+    def get_all(self, data_model_type='compute', audit_uuid=None):
43
+        """Retrieve information about the given data model.
44
+
45
+        :param data_model_type: The type of data model user wants to list.
46
+                                Supported values: compute.
47
+                                Future support values: storage, baremetal.
48
+                                The default value is compute.
49
+        :param audit_uuid: The UUID of the audit,  used to filter data model
50
+                           by the scope in audit.
51
+        """
52
+        if self.from_data_model:
53
+            raise exception.OperationNotPermitted
54
+        allowed_data_model_type = [
55
+            'compute',
56
+            ]
57
+        if data_model_type not in allowed_data_model_type:
58
+            raise exception.DataModelTypeNotFound(
59
+                data_model_type=data_model_type)
60
+        context = pecan.request.context
61
+        de_client = rpcapi.DecisionEngineAPI()
62
+        policy.enforce(context, 'data_model:get_all',
63
+                       action='data_model:get_all')
64
+        rpc_all_data_model = de_client.get_data_model_info(
65
+            context,
66
+            data_model_type,
67
+            audit_uuid)
68
+        return rpc_all_data_model

+ 4
- 0
watcher/common/exception.py View File

@@ -210,6 +210,10 @@ class InvalidIntervalOrCron(Invalid):
210 210
     msg_fmt = _("Expected an interval or cron syntax but received %(name)s")
211 211
 
212 212
 
213
+class DataModelTypeNotFound(ResourceNotFound):
214
+    msg_fmt = _("The %(data_model_type)s data model could not be found")
215
+
216
+
213 217
 class GoalNotFound(ResourceNotFound):
214 218
     msg_fmt = _("Goal %(goal)s could not be found")
215 219
 

+ 2
- 0
watcher/common/policies/__init__.py View File

@@ -17,6 +17,7 @@ from watcher.common.policies import action_plan
17 17
 from watcher.common.policies import audit
18 18
 from watcher.common.policies import audit_template
19 19
 from watcher.common.policies import base
20
+from watcher.common.policies import data_model
20 21
 from watcher.common.policies import goal
21 22
 from watcher.common.policies import scoring_engine
22 23
 from watcher.common.policies import service
@@ -30,6 +31,7 @@ def list_rules():
30 31
         action_plan.list_rules(),
31 32
         audit.list_rules(),
32 33
         audit_template.list_rules(),
34
+        data_model.list_rules(),
33 35
         goal.list_rules(),
34 36
         scoring_engine.list_rules(),
35 37
         service.list_rules(),

+ 37
- 0
watcher/common/policies/data_model.py View File

@@ -0,0 +1,37 @@
1
+# Copyright 2019 ZTE Corporation.
2
+#
3
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
4
+#    not use this file except in compliance with the License. You may obtain
5
+#    a copy of the License at
6
+#
7
+#         http://www.apache.org/licenses/LICENSE-2.0
8
+#
9
+#    Unless required by applicable law or agreed to in writing, software
10
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12
+#    License for the specific language governing permissions and limitations
13
+#    under the License.
14
+
15
+from oslo_policy import policy
16
+
17
+from watcher.common.policies import base
18
+
19
+DATA_MODEL = 'data_model:%s'
20
+
21
+rules = [
22
+    policy.DocumentedRuleDefault(
23
+        name=DATA_MODEL % 'get_all',
24
+        check_str=base.RULE_ADMIN_API,
25
+        description='List data model.',
26
+        operations=[
27
+            {
28
+                'path': '/v1/data_model',
29
+                'method': 'GET'
30
+            }
31
+        ]
32
+    ),
33
+]
34
+
35
+
36
+def list_rules():
37
+    return rules

+ 1
- 1
watcher/tests/api/test_root.py View File

@@ -37,7 +37,7 @@ class TestV1Root(base.FunctionalTest):
37 37
         not_resources = ('id', 'links', 'media_types')
38 38
         actual_resources = tuple(set(data.keys()) - set(not_resources))
39 39
         expected_resources = ('audit_templates', 'audits', 'actions',
40
-                              'action_plans', 'scoring_engines',
40
+                              'action_plans', 'data_model', 'scoring_engines',
41 41
                               'services')
42 42
         self.assertEqual(sorted(expected_resources), sorted(actual_resources))
43 43
 

+ 74
- 0
watcher/tests/api/v1/test_data_model.py View File

@@ -0,0 +1,74 @@
1
+# Copyright 2019 ZTE corporation.
2
+# All Rights Reserved.
3
+#
4
+# Licensed under the Apache License, Version 2.0 (the "License");
5
+#    you may not use this file except in compliance with the License.
6
+#    You may obtain a copy of the License at
7
+#
8
+#        http://www.apache.org/licenses/LICENSE-2.0
9
+#
10
+#    Unless required by applicable law or agreed to in writing, software
11
+#    distributed under the License is distributed on an "AS IS" BASIS,
12
+#    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+#    See the License for the specific language governing permissions and
14
+#    limitations under the License.
15
+
16
+import mock
17
+
18
+from oslo_serialization import jsonutils
19
+
20
+from watcher.decision_engine import rpcapi as deapi
21
+from watcher.tests.api import base as api_base
22
+
23
+
24
+class TestListDataModel(api_base.FunctionalTest):
25
+
26
+    def setUp(self):
27
+        super(TestListDataModel, self).setUp()
28
+        p_dcapi = mock.patch.object(deapi, 'DecisionEngineAPI')
29
+        self.mock_dcapi = p_dcapi.start()
30
+        self.mock_dcapi().get_data_model_info.return_value = \
31
+            'fake_response_value'
32
+        self.addCleanup(p_dcapi.stop)
33
+
34
+    def test_get_all(self):
35
+        response = self.get_json('/data_model/?data_model_type=compute')
36
+        self.assertEqual('fake_response_value', response)
37
+
38
+
39
+class TestDataModelPolicyEnforcement(api_base.FunctionalTest):
40
+
41
+    def setUp(self):
42
+        super(TestDataModelPolicyEnforcement, self).setUp()
43
+        p_dcapi = mock.patch.object(deapi, 'DecisionEngineAPI')
44
+        self.mock_dcapi = p_dcapi.start()
45
+        self.addCleanup(p_dcapi.stop)
46
+
47
+    def _common_policy_check(self, rule, func, *arg, **kwarg):
48
+        self.policy.set_rules({
49
+            "admin_api": "(role:admin or role:administrator)",
50
+            "default": "rule:admin_api",
51
+            rule: "rule:defaut"})
52
+        response = func(*arg, **kwarg)
53
+        self.assertEqual(403, response.status_int)
54
+        self.assertEqual('application/json', response.content_type)
55
+        self.assertTrue(
56
+            "Policy doesn't allow %s to be performed." % rule,
57
+            jsonutils.loads(response.json['error_message'])['faultstring'])
58
+
59
+    def test_policy_disallow_get_all(self):
60
+        self._common_policy_check(
61
+            "data_model:get_all", self.get_json,
62
+            "/data_model/?data_model_type=compute",
63
+            expect_errors=True)
64
+
65
+
66
+class TestDataModelEnforcementWithAdminContext(
67
+        TestListDataModel, api_base.AdminRoleTest):
68
+
69
+    def setUp(self):
70
+        super(TestDataModelEnforcementWithAdminContext, self).setUp()
71
+        self.policy.set_rules({
72
+            "admin_api": "(role:admin or role:administrator)",
73
+            "default": "rule:admin_api",
74
+            "data_model:get_all": "rule:default"})

+ 3
- 1
watcher/tests/fake_policy.py View File

@@ -58,7 +58,9 @@ policy_data = """
58 58
 
59 59
     "service:detail": "",
60 60
     "service:get": "",
61
-    "service:get_all": ""
61
+    "service:get_all": "",
62
+
63
+    "data_model:get_all": ""
62 64
 }
63 65
 """
64 66
 

Loading…
Cancel
Save