Browse Source

Merge "Fix proxy extension for neutron RBAC"

Zuul 8 months ago
parent
commit
f2b80ade00

+ 54
- 5
neutron_lbaas/services/loadbalancer/proxy_plugin.py View File

@@ -144,6 +144,10 @@ class LoadBalancerProxyPluginv2(loadbalancerv2.LoadBalancerPluginBaseV2):
144 144
             e = lib_exc.NotAuthorized()
145 145
             e.msg = str(r.content)
146 146
             raise e
147
+        elif r.status_code == 403:
148
+            e = lib_exc.AdminRequired()
149
+            e.msg = str(r.content)
150
+            raise e
147 151
         elif r.status_code == 404:
148 152
             e = lib_exc.NotFound()
149 153
             e.msg = str(r.content)
@@ -167,7 +171,7 @@ class LoadBalancerProxyPluginv2(loadbalancerv2.LoadBalancerPluginBaseV2):
167 171
         res = {}
168 172
         for k in map:
169 173
             if k not in keys:
170
-                if map[k]:
174
+                if map[k] or map[k] == '' or isinstance(map[k], bool):
171 175
                     res[k] = map[k]
172 176
         if 'tenant_id' in res:
173 177
             res['project_id'] = res.pop('tenant_id')
@@ -194,7 +198,13 @@ class LoadBalancerProxyPluginv2(loadbalancerv2.LoadBalancerPluginBaseV2):
194 198
         r = self._filter(FILTER, res[resource_])
195 199
         r = self.post(self._path(resource, sub_resource, resource_id),
196 200
                       context.auth_token, {resource_: r})
197
-        return r[resource_]
201
+        response = r[resource_]
202
+        # neutron is looking for tenant_id in the response for RBAC
203
+        if 'project_id' in response:
204
+            response['tenant_id'] = response['project_id']
205
+        else:
206
+            response['tenant_id'] = context.tenant_id
207
+        return response
198 208
 
199 209
     def _get_resources(self, resource, context, filters=None, fields=None,
200 210
                        sub_resource=None, resource_id=None,
@@ -207,22 +217,54 @@ class LoadBalancerProxyPluginv2(loadbalancerv2.LoadBalancerPluginBaseV2):
207 217
                 filters['project_id'] = filters.pop('tenant_id')
208 218
             args['filters'] = filters
209 219
         if fields:
220
+            if 'tenant_id' in fields:
221
+                fields.remove('tenant_id')
222
+                if 'project_id' not in fields:
223
+                    fields.append('project_id')
210 224
             args['fields'] = fields
225
+
226
+        LOG.debug("context-tenant-id %s" % context.tenant_id)
227
+
211 228
         res = self.get(self._path(resource, sub_resource, resource_id),
212 229
                        context.auth_token, args)
213
-        return res[self.pluralize(resource_)] if not pass_through else res
230
+        response = res[self.pluralize(resource_)] if not pass_through else res
231
+        # neutron is looking for tenant_id in the response for RBAC
232
+        if isinstance(response, (list,)):
233
+            for e in response:
234
+                e['tenant_id'] = e.get('project_id', context.tenant_id)
235
+        else:
236
+            if 'project_id' in response:
237
+                response['tenant_id'] = response.get(
238
+                    'project_id', context.tenant_id)
239
+        return response
214 240
 
215 241
     def _get_resource(self, resource, context, id, fields=None,
216 242
                       sub_resource=None, resource_id=None):
217 243
         # not sure how to test that or if we even support sorting/filtering?
218 244
         args = {}
219 245
         if fields:
246
+            if 'tenant_id' in fields:
247
+                fields.remove('tenant_id')
248
+                if 'project_id' not in fields:
249
+                    fields.append('project_id')
220 250
             args['fields'] = fields
221 251
         resource_ = resource if not sub_resource else sub_resource
252
+
253
+        LOG.debug("-get_resource context-tenant-id %s" % context.tenant_id)
254
+
222 255
         res = self.get('{}/{}'.format(
223 256
             self._path(resource, sub_resource, resource_id), id),
224 257
                        context.auth_token, args)
225
-        return res[resource_]
258
+        response = res[resource_]
259
+        if ('provisioning_status' in response) and (
260
+                    response['provisioning_status'] == 'DELETED'):
261
+            raise lib_exc.NotFound()
262
+        # neutron is looking for tenant_id in the response for RBAC
263
+        if 'project_id' in response:
264
+            response['tenant_id'] = response['project_id']
265
+        else:
266
+            response['tenant_id'] = context.tenant_id
267
+        return response
226 268
 
227 269
     def _update_resource(self, resource, context, id, res,
228 270
                          sub_resource=None, resource_id=None):
@@ -233,7 +275,13 @@ class LoadBalancerProxyPluginv2(loadbalancerv2.LoadBalancerPluginBaseV2):
233 275
             resource, sub_resource, resource_id), id),
234 276
                        context.auth_token,
235 277
                        {resource_: r})
236
-        return res[resource_]
278
+        response = res[resource_]
279
+        # neutron is looking for tenant_id in the response for RBAC
280
+        if 'project_id' in response:
281
+            response['tenant_id'] = response['project_id']
282
+        else:
283
+            response['tenant_id'] = context.tenant_id
284
+        return response
237 285
 
238 286
     def _delete_resource(self, resource, context, id,
239 287
                          sub_resource=None, resource_id=None):
@@ -330,6 +378,7 @@ class LoadBalancerProxyPluginv2(loadbalancerv2.LoadBalancerPluginBaseV2):
330 378
         pass
331 379
 
332 380
     def statuses(self, context, loadbalancer_id):
381
+        LOG.debug("Statuses called!")
333 382
         return self._get_resources(LOADBALANCER, context, sub_resource=STATUS,
334 383
                                    resource_id=loadbalancer_id,
335 384
                                    pass_through=True)

+ 49
- 4
neutron_lbaas/tests/unit/db/loadbalancer/test_proxy_plugin.py View File

@@ -134,6 +134,7 @@ class LbaasLoadBalancerTests(TestLbaasProxyPluginDbTestCase):
134 134
             'provisioning_status': n_constants.ACTIVE,
135 135
             'operating_status': lb_const.ONLINE,
136 136
             'tenant_id': self._tenant_id,
137
+            'project_id': self._tenant_id,
137 138
             'listeners': [],
138 139
             'pools': [],
139 140
             'provider': 'lbaas'
@@ -248,6 +249,25 @@ class LbaasLoadBalancerTests(TestLbaasProxyPluginDbTestCase):
248 249
             self.assertEqual(expected_values[k],
249 250
                              body['loadbalancer'][k])
250 251
 
252
+    @requests_mock.mock()
253
+    def test_show_loadbalancer_deleted(self, m):
254
+        name = 'lb_show'
255
+        description = 'lb_show description'
256
+        lb_id = "testid"
257
+        expected_values = {'name': name,
258
+                           'description': description,
259
+                           'vip_address': '10.0.0.10',
260
+                           'admin_state_up': True,
261
+                           'provisioning_status': 'DELETED',
262
+                           'operating_status': lb_const.ONLINE,
263
+                           'listeners': [],
264
+                           'provider': 'lbaas',
265
+                           'id': lb_id}
266
+        m.get("{}/{}".format(self.url, lb_id),
267
+              json={'loadbalancer': expected_values})
268
+        resp, body = self._get_loadbalancer_api(lb_id)
269
+        self.assertEqual(404, resp.status_int)
270
+
251 271
     @requests_mock.mock()
252 272
     def test_update_loadbalancer(self, m):
253 273
         loadbalancer_id = "test_uuid"
@@ -349,6 +369,7 @@ class LbaasListenerTests(ListenerTestBase):
349 369
             'protocol_port': 80,
350 370
             'admin_state_up': True,
351 371
             'tenant_id': self._tenant_id,
372
+            'project_id': self._tenant_id,
352 373
             'default_pool_id': None,
353 374
             'loadbalancers': [{'id': self.lb_id}],
354 375
             'id': '123'
@@ -407,7 +428,6 @@ class LbaasListenerTests(ListenerTestBase):
407 428
                            'protocol': 'HTTP',
408 429
                            'connection_limit': 100,
409 430
                            'admin_state_up': False,
410
-                           'tenant_id': self._tenant_id,
411 431
                            'loadbalancers': [{'id': self.lb_id}]}
412 432
 
413 433
         listener_id = uuidutils.generate_uuid()
@@ -449,13 +469,14 @@ class LbaasListenerTests(ListenerTestBase):
449 469
                            'connection_limit': -1,
450 470
                            'admin_state_up': True,
451 471
                            'tenant_id': self._tenant_id,
472
+                           'project_id': self._tenant_id,
452 473
                            'default_pool_id': None,
453 474
                            'loadbalancers': [{'id': self.lb_id}]}
454 475
         listener_id = uuidutils.generate_uuid()
455 476
         m.get("{}/{}".format(self.url, listener_id),
456 477
               json={'listener': expected_values})
457 478
         resp, body = self._get_listener_api(listener_id)
458
-        for k in expected_values:
479
+        for k in body['listener']:
459 480
             self.assertEqual(expected_values[k], body['listener'][k])
460 481
 
461 482
     @requests_mock.mock()
@@ -467,6 +488,7 @@ class LbaasListenerTests(ListenerTestBase):
467 488
                            'connection_limit': -1,
468 489
                            'admin_state_up': True,
469 490
                            'tenant_id': self._tenant_id,
491
+                           'project_id': self._tenant_id,
470 492
                            'loadbalancers': [{'id': self.lb_id}]}
471 493
 
472 494
         listener_id = uuidutils.generate_uuid()
@@ -499,6 +521,7 @@ class LbaasL7Tests(ListenerTestBase):
499 521
             'redirect_pool_id': None,
500 522
             'redirect_url': None,
501 523
             'tenant_id': self._tenant_id,
524
+            'project_id': self._tenant_id,
502 525
         }
503 526
         expected.update(extras)
504 527
         listener_id = uuidutils.generate_uuid()
@@ -519,6 +542,7 @@ class LbaasL7Tests(ListenerTestBase):
519 542
             'redirect_pool_id': None,
520 543
             'redirect_url': None,
521 544
             'tenant_id': self._tenant_id,
545
+            'project_id': self._tenant_id,
522 546
         }
523 547
         expected.update(extras)
524 548
         listener_id = uuidutils.generate_uuid()
@@ -546,6 +570,7 @@ class LbaasL7Tests(ListenerTestBase):
546 570
             'redirect_pool_id': None,
547 571
             'redirect_url': 'redirect_url',
548 572
             'tenant_id': self._tenant_id,
573
+            'project_id': self._tenant_id,
549 574
             'position': 1,
550 575
         }
551 576
         expected.update(extras)
@@ -589,6 +614,7 @@ class LbaasL7Tests(ListenerTestBase):
589 614
             'redirect_pool_id': None,
590 615
             'redirect_url': None,
591 616
             'tenant_id': self._tenant_id,
617
+            'project_id': self._tenant_id,
592 618
             'listener_id': listener_id,
593 619
             'id': l7policy_id,
594 620
         }
@@ -644,7 +670,9 @@ class LbaasL7Tests(ListenerTestBase):
644 670
             'type': lb_const.L7_RULE_TYPE_HOST_NAME,
645 671
             'compare_type': lb_const.L7_RULE_COMPARE_TYPE_EQUAL_TO,
646 672
             'key': None,
647
-            'value': 'value1'
673
+            'value': 'value1',
674
+            'project_id': self._tenant_id,
675
+            'tenant_id': self._tenant_id,
648 676
         }
649 677
 
650 678
         m.post(self._rules(l7_policy_id), json={'rule': expected})
@@ -773,6 +801,7 @@ class LbaasPoolTests(PoolTestBase):
773 801
             'lb_algorithm': 'ROUND_ROBIN',
774 802
             'admin_state_up': True,
775 803
             'tenant_id': self._tenant_id,
804
+            'project_id': self._tenant_id,
776 805
             'healthmonitor_id': None,
777 806
             'members': [],
778 807
             'id': uuidutils.generate_uuid()
@@ -808,6 +837,7 @@ class LbaasPoolTests(PoolTestBase):
808 837
             'lb_algorithm': 'ROUND_ROBIN',
809 838
             'admin_state_up': True,
810 839
             'tenant_id': self._tenant_id,
840
+            'project_id': self._tenant_id,
811 841
             'listeners': [{'id': self.listener_id}],
812 842
             'healthmonitor_id': None,
813 843
             'members': []
@@ -834,6 +864,7 @@ class LbaasPoolTests(PoolTestBase):
834 864
             'lb_algorithm': 'LEAST_CONNECTIONS',
835 865
             'admin_state_up': True,
836 866
             'tenant_id': self._tenant_id,
867
+            'project_id': self._tenant_id,
837 868
             'listeners': [{'id': self.listener_id}],
838 869
             'healthmonitor_id': None,
839 870
             'members': []
@@ -883,7 +914,8 @@ class LbaasPoolTests(PoolTestBase):
883 914
             'protocol': 'BLANK',
884 915
             'lb_algorithm': 'LEAST_CONNECTIONS',
885 916
             'admin_state_up': True,
886
-            'tenant_id': self._tenant_id
917
+            'tenant_id': self._tenant_id,
918
+            'project_id': self._tenant_id,
887 919
         }}
888 920
         m.get(self.url, json={'pools': [data]})
889 921
         m.post(self.url, status_code=webob.exc.HTTPBadRequest.code)
@@ -899,6 +931,7 @@ class LbaasPoolTests(PoolTestBase):
899 931
                            'lb_algorithm': 'ROUND_ROBIN',
900 932
                            'admin_state_up': True,
901 933
                            'tenant_id': self._tenant_id,
934
+                           'project_id': self._tenant_id,
902 935
                            'session_persistence': {'cookie_name': None,
903 936
                                                    'type': 'HTTP_COOKIE'},
904 937
                            'loadbalancers': [{'id': self.lb_id}],
@@ -972,6 +1005,7 @@ class LbaasMemberTests(MemberTestBase):
972 1005
             'weight': 1,
973 1006
             'admin_state_up': True,
974 1007
             'tenant_id': self._tenant_id,
1008
+            'project_id': self._tenant_id,
975 1009
             'subnet_id': '',
976 1010
             'name': 'member1',
977 1011
             'id': uuidutils.generate_uuid()
@@ -1001,6 +1035,7 @@ class LbaasMemberTests(MemberTestBase):
1001 1035
             'weight': 1,
1002 1036
             'admin_state_up': True,
1003 1037
             'tenant_id': self._tenant_id,
1038
+            'project_id': self._tenant_id,
1004 1039
             'subnet_id': '',
1005 1040
             'name': 'member1',
1006 1041
             'id': uuidutils.generate_uuid()
@@ -1037,6 +1072,7 @@ class LbaasMemberTests(MemberTestBase):
1037 1072
             'weight': 1,
1038 1073
             'admin_state_up': True,
1039 1074
             'tenant_id': self._tenant_id,
1075
+            'project_id': self._tenant_id,
1040 1076
             'subnet_id': '',
1041 1077
             'name': 'member1',
1042 1078
             'id': uuidutils.generate_uuid()
@@ -1074,6 +1110,7 @@ class LbaasMemberTests(MemberTestBase):
1074 1110
                            'weight': 1,
1075 1111
                            'admin_state_up': True,
1076 1112
                            'tenant_id': self._tenant_id,
1113
+                           'project_id': self._tenant_id,
1077 1114
                            'subnet_id': self.test_subnet_id}}
1078 1115
         m.post(self._members(pool_id='WRONG_POOL_ID'), status_code=404)
1079 1116
         resp, body = self._create_member_api('WRONG_POOL_ID', data)
@@ -1087,6 +1124,7 @@ class LbaasMemberTests(MemberTestBase):
1087 1124
                            'weight': 1,
1088 1125
                            'admin_state_up': True,
1089 1126
                            'tenant_id': self._tenant_id,
1127
+                           'project_id': self._tenant_id,
1090 1128
                            'subnet_id': self.test_subnet_id,
1091 1129
                            'name': 123}}
1092 1130
         resp, body = self._create_member_api('POOL_ID', data)
@@ -1149,6 +1187,7 @@ class TestLbaasHealthMonitorTests(HealthMonitorTestBase):
1149 1187
             'expected_codes': '200',
1150 1188
             'admin_state_up': True,
1151 1189
             'tenant_id': self._tenant_id,
1190
+            'project_id': self._tenant_id,
1152 1191
             'pools': [{'id': self.pool_id}],
1153 1192
             'name': 'monitor1',
1154 1193
             'id': self.hm_id
@@ -1182,6 +1221,7 @@ class TestLbaasHealthMonitorTests(HealthMonitorTestBase):
1182 1221
             'expected_codes': '200',
1183 1222
             'admin_state_up': True,
1184 1223
             'tenant_id': self._tenant_id,
1224
+            'project_id': self._tenant_id,
1185 1225
             'pools': [{'id': self.pool_id}],
1186 1226
             'name': 'monitor1'
1187 1227
         }
@@ -1210,6 +1250,7 @@ class TestLbaasHealthMonitorTests(HealthMonitorTestBase):
1210 1250
             'expected_codes': '200,404',
1211 1251
             'admin_state_up': True,
1212 1252
             'tenant_id': self._tenant_id,
1253
+            'project_id': self._tenant_id,
1213 1254
             'pools': [{'id': self.pool_id}],
1214 1255
             'name': 'monitor2'
1215 1256
         }
@@ -1249,6 +1290,7 @@ class TestLbaasHealthMonitorTests(HealthMonitorTestBase):
1249 1290
                                   'max_retries': 2,
1250 1291
                                   'admin_state_up': True,
1251 1292
                                   'tenant_id': self._tenant_id,
1293
+                                  'project_id': self._tenant_id,
1252 1294
                                   'pool_id': self.pool_id}}
1253 1295
         resp, body = self._create_healthmonitor_api(data)
1254 1296
         self.assertEqual(webob.exc.HTTPBadRequest.code, resp.status_int)
@@ -1261,6 +1303,7 @@ class TestLbaasHealthMonitorTests(HealthMonitorTestBase):
1261 1303
                                   'timeout': 1,
1262 1304
                                   'max_retries': 1,
1263 1305
                                   'tenant_id': self._tenant_id,
1306
+                                  'project_id': self._tenant_id,
1264 1307
                                   'pool_id': uuidutils.generate_uuid()}}
1265 1308
         resp, body = self._create_healthmonitor_api(data)
1266 1309
         self.assertEqual(webob.exc.HTTPNotFound.code, resp.status_int)
@@ -1273,6 +1316,7 @@ class TestLbaasHealthMonitorTests(HealthMonitorTestBase):
1273 1316
                                   'timeout': 1,
1274 1317
                                   'max_retries': 1,
1275 1318
                                   'tenant_id': self._tenant_id,
1319
+                                  'project_id': self._tenant_id,
1276 1320
                                   'pool_id': self.pool_id}}
1277 1321
         resp, body = self._create_healthmonitor_api(data)
1278 1322
         self.assertEqual(webob.exc.HTTPConflict.code, resp.status_int)
@@ -1289,6 +1333,7 @@ class TestLbaasHealthMonitorTests(HealthMonitorTestBase):
1289 1333
             'expected_codes': '200',
1290 1334
             'admin_state_up': True,
1291 1335
             'tenant_id': self._tenant_id,
1336
+            'project_id': self._tenant_id,
1292 1337
             'pools': [{'id': self.pool_id}],
1293 1338
             'name': '',
1294 1339
             'max_retries_down': 3,

Loading…
Cancel
Save