Browse Source

Merge "Only return share host for admins using shares API" into stable/ocata

Jenkins 2 years ago
parent
commit
7b60653007

+ 1
- 0
etc/manila/policy.json View File

@@ -22,6 +22,7 @@
22 22
     "share:get": "rule:default",
23 23
     "share:get_all": "rule:default",
24 24
     "share:list_by_share_server_id": "rule:admin_api",
25
+    "share:list_by_host": "rule:admin_api",
25 26
     "share:update": "rule:default",
26 27
     "share:access_get": "rule:default",
27 28
     "share:access_get_all": "rule:default",

+ 1
- 1
manila/api/views/share_replicas.py View File

@@ -54,7 +54,6 @@ class ReplicationViewBuilder(common.ViewBuilder):
54 54
             'share_id': replica.get('share_id'),
55 55
             'availability_zone': replica.get('availability_zone'),
56 56
             'created_at': replica.get('created_at'),
57
-            'host': replica.get('host'),
58 57
             'status': replica.get('status'),
59 58
             'share_network_id': replica.get('share_network_id'),
60 59
             'replica_state': replica.get('replica_state'),
@@ -63,6 +62,7 @@ class ReplicationViewBuilder(common.ViewBuilder):
63 62
 
64 63
         if context.is_admin:
65 64
             replica_dict['share_server_id'] = replica.get('share_server_id')
65
+            replica_dict['host'] = replica.get('host')
66 66
 
67 67
         self.update_versioned_resource_dict(request, replica_dict, replica)
68 68
         return {'share_replica': replica_dict}

+ 1
- 2
manila/api/views/shares.py View File

@@ -80,7 +80,6 @@ class ViewBuilder(common.ViewBuilder):
80 80
             'name': share.get('display_name'),
81 81
             'description': share.get('display_description'),
82 82
             'project_id': share.get('project_id'),
83
-            'host': share_instance.get('host'),
84 83
             'snapshot_id': share.get('snapshot_id'),
85 84
             'share_network_id': share_instance.get('share_network_id'),
86 85
             'share_proto': share.get('share_proto'),
@@ -92,12 +91,12 @@ class ViewBuilder(common.ViewBuilder):
92 91
             'is_public': share.get('is_public'),
93 92
             'export_locations': export_locations,
94 93
         }
95
-
96 94
         self.update_versioned_resource_dict(request, share_dict, share)
97 95
 
98 96
         if context.is_admin:
99 97
             share_dict['share_server_id'] = share_instance.get(
100 98
                 'share_server_id')
99
+            share_dict['host'] = share_instance.get('host')
101 100
         return {'share': share_dict}
102 101
 
103 102
     @common.ViewBuilder.versioned_method("2.2")

+ 2
- 0
manila/share/api.py View File

@@ -1518,6 +1518,8 @@ class API(base.Base):
1518 1518
         is_public = strutils.bool_from_string(is_public, strict=True)
1519 1519
 
1520 1520
         # Get filtered list of shares
1521
+        if 'host' in search_opts:
1522
+            policy.check_policy(context, 'share', 'list_by_host')
1521 1523
         if 'share_server_id' in search_opts:
1522 1524
             # NOTE(vponomaryov): this is project_id independent
1523 1525
             policy.check_policy(context, 'share', 'list_by_share_server_id')

+ 42
- 40
manila/tests/api/v1/test_shares.py View File

@@ -90,7 +90,6 @@ class ShareAPITest(test.TestCase):
90 90
             'export_location': 'fake_location',
91 91
             'export_locations': ['fake_location', 'fake_location2'],
92 92
             'project_id': 'fakeproject',
93
-            'host': 'fakehost',
94 93
             'created_at': datetime.datetime(1, 1, 1, 1, 1, 1),
95 94
             'share_proto': 'FAKEPROTO',
96 95
             'metadata': {},
@@ -123,6 +122,7 @@ class ShareAPITest(test.TestCase):
123 122
             share['share_proto'] = share['share_proto'].upper()
124 123
         if admin:
125 124
             share['share_server_id'] = 'fake_share_server_id'
125
+            share['host'] = 'fakehost'
126 126
         return {'share': share}
127 127
 
128 128
     @ddt.data("1.0", "2.0", "2.1")
@@ -501,7 +501,6 @@ class ShareAPITest(test.TestCase):
501 501
             'share_server_id': 'fake_share_server_id',
502 502
             'share_type_id': 'fake_share_type_id',
503 503
             'snapshot_id': 'fake_snapshot_id',
504
-            'host': 'fake_host',
505 504
             'share_network_id': 'fake_share_network_id',
506 505
             'metadata': '%7B%27k1%27%3A+%27v1%27%7D',  # serialized k1=v1
507 506
             'extra_specs': '%7B%27k2%27%3A+%27v2%27%7D',  # serialized k2=v2
@@ -511,6 +510,8 @@ class ShareAPITest(test.TestCase):
511 510
             'offset': '1',
512 511
             'is_public': 'False',
513 512
         }
513
+        if use_admin_context:
514
+            search_opts['host'] = 'fake_host'
514 515
         # fake_key should be filtered for non-admin
515 516
         url = '/shares?fake_key=fake_value'
516 517
         for k, v in search_opts.items():
@@ -533,7 +534,6 @@ class ShareAPITest(test.TestCase):
533 534
             'share_server_id': search_opts['share_server_id'],
534 535
             'share_type_id': search_opts['share_type_id'],
535 536
             'snapshot_id': search_opts['snapshot_id'],
536
-            'host': search_opts['host'],
537 537
             'share_network_id': search_opts['share_network_id'],
538 538
             'metadata': {'k1': 'v1'},
539 539
             'extra_specs': {'k2': 'v2'},
@@ -541,6 +541,7 @@ class ShareAPITest(test.TestCase):
541 541
         }
542 542
         if use_admin_context:
543 543
             search_opts_expected.update({'fake_key': 'fake_value'})
544
+            search_opts_expected['host'] = search_opts['host']
544 545
         share_api.API.get_all.assert_called_once_with(
545 546
             req.environ['manila.context'],
546 547
             sort_key=search_opts['sort_key'],
@@ -590,7 +591,6 @@ class ShareAPITest(test.TestCase):
590 591
             'share_server_id': 'fake_share_server_id',
591 592
             'share_type_id': 'fake_share_type_id',
592 593
             'snapshot_id': 'fake_snapshot_id',
593
-            'host': 'fake_host',
594 594
             'share_network_id': 'fake_share_network_id',
595 595
             'metadata': '%7B%27k1%27%3A+%27v1%27%7D',  # serialized k1=v1
596 596
             'extra_specs': '%7B%27k2%27%3A+%27v2%27%7D',  # serialized k2=v2
@@ -600,6 +600,8 @@ class ShareAPITest(test.TestCase):
600 600
             'offset': '1',
601 601
             'is_public': 'False',
602 602
         }
603
+        if use_admin_context:
604
+            search_opts['host'] = 'fake_host'
603 605
         # fake_key should be filtered for non-admin
604 606
         url = '/shares/detail?fake_key=fake_value'
605 607
         for k, v in search_opts.items():
@@ -630,7 +632,6 @@ class ShareAPITest(test.TestCase):
630 632
             'share_server_id': search_opts['share_server_id'],
631 633
             'share_type_id': search_opts['share_type_id'],
632 634
             'snapshot_id': search_opts['snapshot_id'],
633
-            'host': search_opts['host'],
634 635
             'share_network_id': search_opts['share_network_id'],
635 636
             'metadata': {'k1': 'v1'},
636 637
             'extra_specs': {'k2': 'v2'},
@@ -638,6 +639,7 @@ class ShareAPITest(test.TestCase):
638 639
         }
639 640
         if use_admin_context:
640 641
             search_opts_expected.update({'fake_key': 'fake_value'})
642
+            search_opts_expected['host'] = search_opts['host']
641 643
         share_api.API.get_all.assert_called_once_with(
642 644
             req.environ['manila.context'],
643 645
             sort_key=search_opts['sort_key'],
@@ -656,8 +658,9 @@ class ShareAPITest(test.TestCase):
656 658
             shares[1]['share_type_id'], result['shares'][0]['share_type'])
657 659
         self.assertEqual(
658 660
             shares[1]['snapshot_id'], result['shares'][0]['snapshot_id'])
659
-        self.assertEqual(
660
-            shares[1]['instance']['host'], result['shares'][0]['host'])
661
+        if use_admin_context:
662
+            self.assertEqual(
663
+                shares[1]['instance']['host'], result['shares'][0]['host'])
661 664
         self.assertEqual(
662 665
             shares[1]['instance']['share_network_id'],
663 666
             result['shares'][0]['share_network_id'])
@@ -668,42 +671,41 @@ class ShareAPITest(test.TestCase):
668 671
     def test_share_list_detail_with_search_opts_by_admin(self):
669 672
         self._share_list_detail_with_search_opts(use_admin_context=True)
670 673
 
671
-    def _list_detail_common_expected(self):
672
-        return {
673
-            'shares': [
674
+    def _list_detail_common_expected(self, admin=False):
675
+        share_dict = {
676
+            'status': 'fakestatus',
677
+            'description': 'displaydesc',
678
+            'export_location': 'fake_location',
679
+            'export_locations': ['fake_location', 'fake_location2'],
680
+            'availability_zone': 'fakeaz',
681
+            'name': 'displayname',
682
+            'share_proto': 'FAKEPROTO',
683
+            'metadata': {},
684
+            'project_id': 'fakeproject',
685
+
686
+            'id': '1',
687
+            'snapshot_id': '2',
688
+            'snapshot_support': True,
689
+            'share_network_id': None,
690
+            'created_at': datetime.datetime(1, 1, 1, 1, 1, 1),
691
+            'size': 1,
692
+            'share_type': '1',
693
+            'volume_type': '1',
694
+            'is_public': False,
695
+            'links': [
674 696
                 {
675
-                    'status': 'fakestatus',
676
-                    'description': 'displaydesc',
677
-                    'export_location': 'fake_location',
678
-                    'export_locations': ['fake_location', 'fake_location2'],
679
-                    'availability_zone': 'fakeaz',
680
-                    'name': 'displayname',
681
-                    'share_proto': 'FAKEPROTO',
682
-                    'metadata': {},
683
-                    'project_id': 'fakeproject',
684
-                    'host': 'fakehost',
685
-                    'id': '1',
686
-                    'snapshot_id': '2',
687
-                    'snapshot_support': True,
688
-                    'share_network_id': None,
689
-                    'created_at': datetime.datetime(1, 1, 1, 1, 1, 1),
690
-                    'size': 1,
691
-                    'share_type': '1',
692
-                    'volume_type': '1',
693
-                    'is_public': False,
694
-                    'links': [
695
-                        {
696
-                            'href': 'http://localhost/v1/fake/shares/1',
697
-                            'rel': 'self'
698
-                        },
699
-                        {
700
-                            'href': 'http://localhost/fake/shares/1',
701
-                            'rel': 'bookmark'
702
-                        }
703
-                    ],
697
+                    'href': 'http://localhost/v1/fake/shares/1',
698
+                    'rel': 'self'
699
+                },
700
+                {
701
+                    'href': 'http://localhost/fake/shares/1',
702
+                    'rel': 'bookmark'
704 703
                 }
705
-            ]
704
+            ],
706 705
         }
706
+        if admin:
707
+            share_dict['host'] = 'fakehost'
708
+        return {'shares': [share_dict]}
707 709
 
708 710
     def _list_detail_test_common(self, req, expected):
709 711
         self.mock_object(share_api.API, 'get_all',

+ 1
- 1
manila/tests/api/v2/test_share_replicas.py View File

@@ -81,7 +81,6 @@ class ShareReplicasApiTest(test.TestCase):
81 81
 
82 82
         if not summary:
83 83
             expected_replica.update({
84
-                'host': replica['host'],
85 84
                 'availability_zone': None,
86 85
                 'created_at': None,
87 86
                 'share_network_id': replica['share_network_id'],
@@ -90,6 +89,7 @@ class ShareReplicasApiTest(test.TestCase):
90 89
 
91 90
         if admin:
92 91
             expected_replica['share_server_id'] = replica['share_server_id']
92
+            expected_replica['host'] = replica['host']
93 93
 
94 94
         return replica, expected_replica
95 95
 

+ 42
- 41
manila/tests/api/v2/test_shares.py View File

@@ -105,7 +105,6 @@ class ShareAPITest(test.TestCase):
105 105
             'export_location': 'fake_location',
106 106
             'export_locations': ['fake_location', 'fake_location2'],
107 107
             'project_id': 'fakeproject',
108
-            'host': 'fakehost',
109 108
             'created_at': datetime.datetime(1, 1, 1, 1, 1, 1),
110 109
             'share_proto': 'FAKEPROTO',
111 110
             'metadata': {},
@@ -140,6 +139,7 @@ class ShareAPITest(test.TestCase):
140 139
             share['share_proto'] = share['share_proto'].upper()
141 140
         if admin:
142 141
             share['share_server_id'] = 'fake_share_server_id'
142
+            share['host'] = 'fakehost'
143 143
         return {'share': share}
144 144
 
145 145
     def test__revert(self):
@@ -1414,7 +1414,6 @@ class ShareAPITest(test.TestCase):
1414 1414
             'share_server_id': 'fake_share_server_id',
1415 1415
             'share_type_id': 'fake_share_type_id',
1416 1416
             'snapshot_id': 'fake_snapshot_id',
1417
-            'host': 'fake_host',
1418 1417
             'share_network_id': 'fake_share_network_id',
1419 1418
             'metadata': '%7B%27k1%27%3A+%27v1%27%7D',  # serialized k1=v1
1420 1419
             'extra_specs': '%7B%27k2%27%3A+%27v2%27%7D',  # serialized k2=v2
@@ -1424,6 +1423,8 @@ class ShareAPITest(test.TestCase):
1424 1423
             'offset': '1',
1425 1424
             'is_public': 'False',
1426 1425
         }
1426
+        if use_admin_context:
1427
+            search_opts['host'] = 'fake_host'
1427 1428
         # fake_key should be filtered for non-admin
1428 1429
         url = '/shares?fake_key=fake_value'
1429 1430
         for k, v in search_opts.items():
@@ -1446,7 +1447,7 @@ class ShareAPITest(test.TestCase):
1446 1447
             'share_server_id': search_opts['share_server_id'],
1447 1448
             'share_type_id': search_opts['share_type_id'],
1448 1449
             'snapshot_id': search_opts['snapshot_id'],
1449
-            'host': search_opts['host'],
1450
+
1450 1451
             'share_network_id': search_opts['share_network_id'],
1451 1452
             'metadata': {'k1': 'v1'},
1452 1453
             'extra_specs': {'k2': 'v2'},
@@ -1454,6 +1455,7 @@ class ShareAPITest(test.TestCase):
1454 1455
         }
1455 1456
         if use_admin_context:
1456 1457
             search_opts_expected.update({'fake_key': 'fake_value'})
1458
+            search_opts_expected['host'] = search_opts['host']
1457 1459
         share_api.API.get_all.assert_called_once_with(
1458 1460
             req.environ['manila.context'],
1459 1461
             sort_key=search_opts['sort_key'],
@@ -1503,7 +1505,6 @@ class ShareAPITest(test.TestCase):
1503 1505
             'share_server_id': 'fake_share_server_id',
1504 1506
             'share_type_id': 'fake_share_type_id',
1505 1507
             'snapshot_id': 'fake_snapshot_id',
1506
-            'host': 'fake_host',
1507 1508
             'share_network_id': 'fake_share_network_id',
1508 1509
             'metadata': '%7B%27k1%27%3A+%27v1%27%7D',  # serialized k1=v1
1509 1510
             'extra_specs': '%7B%27k2%27%3A+%27v2%27%7D',  # serialized k2=v2
@@ -1513,6 +1514,8 @@ class ShareAPITest(test.TestCase):
1513 1514
             'offset': '1',
1514 1515
             'is_public': 'False',
1515 1516
         }
1517
+        if use_admin_context:
1518
+            search_opts['host'] = 'fake_host'
1516 1519
         # fake_key should be filtered for non-admin
1517 1520
         url = '/shares/detail?fake_key=fake_value'
1518 1521
         for k, v in search_opts.items():
@@ -1545,7 +1548,6 @@ class ShareAPITest(test.TestCase):
1545 1548
             'share_server_id': search_opts['share_server_id'],
1546 1549
             'share_type_id': search_opts['share_type_id'],
1547 1550
             'snapshot_id': search_opts['snapshot_id'],
1548
-            'host': search_opts['host'],
1549 1551
             'share_network_id': search_opts['share_network_id'],
1550 1552
             'metadata': {'k1': 'v1'},
1551 1553
             'extra_specs': {'k2': 'v2'},
@@ -1553,6 +1555,7 @@ class ShareAPITest(test.TestCase):
1553 1555
         }
1554 1556
         if use_admin_context:
1555 1557
             search_opts_expected.update({'fake_key': 'fake_value'})
1558
+            search_opts_expected['host'] = search_opts['host']
1556 1559
         share_api.API.get_all.assert_called_once_with(
1557 1560
             req.environ['manila.context'],
1558 1561
             sort_key=search_opts['sort_key'],
@@ -1571,8 +1574,9 @@ class ShareAPITest(test.TestCase):
1571 1574
             shares[1]['share_type_id'], result['shares'][0]['share_type'])
1572 1575
         self.assertEqual(
1573 1576
             shares[1]['snapshot_id'], result['shares'][0]['snapshot_id'])
1574
-        self.assertEqual(
1575
-            shares[1]['instance']['host'], result['shares'][0]['host'])
1577
+        if use_admin_context:
1578
+            self.assertEqual(
1579
+                shares[1]['instance']['host'], result['shares'][0]['host'])
1576 1580
         self.assertEqual(
1577 1581
             shares[1]['instance']['share_network_id'],
1578 1582
             result['shares'][0]['share_network_id'])
@@ -1583,42 +1587,40 @@ class ShareAPITest(test.TestCase):
1583 1587
     def test_share_list_detail_with_search_opts_by_admin(self):
1584 1588
         self._share_list_detail_with_search_opts(use_admin_context=True)
1585 1589
 
1586
-    def _list_detail_common_expected(self):
1587
-        return {
1588
-            'shares': [
1590
+    def _list_detail_common_expected(self, admin=False):
1591
+        share_dict = {
1592
+            'status': 'fakestatus',
1593
+            'description': 'displaydesc',
1594
+            'export_location': 'fake_location',
1595
+            'export_locations': ['fake_location', 'fake_location2'],
1596
+            'availability_zone': 'fakeaz',
1597
+            'name': 'displayname',
1598
+            'share_proto': 'FAKEPROTO',
1599
+            'metadata': {},
1600
+            'project_id': 'fakeproject',
1601
+            'id': '1',
1602
+            'snapshot_id': '2',
1603
+            'snapshot_support': True,
1604
+            'share_network_id': None,
1605
+            'created_at': datetime.datetime(1, 1, 1, 1, 1, 1),
1606
+            'size': 1,
1607
+            'share_type': '1',
1608
+            'volume_type': '1',
1609
+            'is_public': False,
1610
+            'links': [
1589 1611
                 {
1590
-                    'status': 'fakestatus',
1591
-                    'description': 'displaydesc',
1592
-                    'export_location': 'fake_location',
1593
-                    'export_locations': ['fake_location', 'fake_location2'],
1594
-                    'availability_zone': 'fakeaz',
1595
-                    'name': 'displayname',
1596
-                    'share_proto': 'FAKEPROTO',
1597
-                    'metadata': {},
1598
-                    'project_id': 'fakeproject',
1599
-                    'host': 'fakehost',
1600
-                    'id': '1',
1601
-                    'snapshot_id': '2',
1602
-                    'snapshot_support': True,
1603
-                    'share_network_id': None,
1604
-                    'created_at': datetime.datetime(1, 1, 1, 1, 1, 1),
1605
-                    'size': 1,
1606
-                    'share_type': '1',
1607
-                    'volume_type': '1',
1608
-                    'is_public': False,
1609
-                    'links': [
1610
-                        {
1611
-                            'href': 'http://localhost/v1/fake/shares/1',
1612
-                            'rel': 'self'
1613
-                        },
1614
-                        {
1615
-                            'href': 'http://localhost/fake/shares/1',
1616
-                            'rel': 'bookmark'
1617
-                        }
1618
-                    ],
1612
+                    'href': 'http://localhost/v1/fake/shares/1',
1613
+                    'rel': 'self'
1614
+                },
1615
+                {
1616
+                    'href': 'http://localhost/fake/shares/1',
1617
+                    'rel': 'bookmark'
1619 1618
                 }
1620
-            ]
1619
+            ],
1621 1620
         }
1621
+        if admin:
1622
+            share_dict['host'] = 'fakehost'
1623
+        return {'shares': [share_dict]}
1622 1624
 
1623 1625
     def _list_detail_test_common(self, req, expected):
1624 1626
         self.mock_object(share_api.API, 'get_all',
@@ -1692,7 +1694,6 @@ class ShareAPITest(test.TestCase):
1692 1694
                     'metadata': {},
1693 1695
                     'project_id': 'fakeproject',
1694 1696
                     'access_rules_status': 'active',
1695
-                    'host': 'fakehost',
1696 1697
                     'id': '1',
1697 1698
                     'snapshot_id': '2',
1698 1699
                     'share_network_id': None,

+ 14
- 9
manila/tests/share/test_api.py View File

@@ -249,24 +249,29 @@ class ShareAPITestCase(test.TestCase):
249 249
             ctx, sort_dir='desc', sort_key='created_at', filters={})
250 250
         self.assertEqual(_FAKE_LIST_OF_ALL_SHARES, shares)
251 251
 
252
-    def test_get_all_non_admin_filter_by_share_server(self):
252
+    @ddt.data(
253
+        ({'share_server_id': 'fake_share_server'}, 'list_by_share_server_id'),
254
+        ({'host': 'fake_host'}, 'list_by_host'),
255
+    )
256
+    @ddt.unpack
257
+    def test_get_all_by_non_admin_using_admin_filter(self, filters, policy):
253 258
 
254 259
         def fake_policy_checker(*args, **kwargs):
255
-            if 'list_by_share_server_id' == args[2] and not args[0].is_admin:
260
+            if policy == args[2] and not args[0].is_admin:
256 261
                 raise exception.NotAuthorized
257 262
 
258 263
         ctx = context.RequestContext('fake_uid', 'fake_pid_1', is_admin=False)
259
-        self.mock_object(share_api.policy, 'check_policy',
260
-                         mock.Mock(side_effect=fake_policy_checker))
264
+        self.mock_object(
265
+            share_api.policy, 'check_policy',
266
+            mock.Mock(side_effect=fake_policy_checker))
267
+
261 268
         self.assertRaises(
262 269
             exception.NotAuthorized,
263
-            self.api.get_all,
264
-            ctx,
265
-            {'share_server_id': 'fake'},
266
-        )
270
+            self.api.get_all, ctx, filters)
271
+
267 272
         share_api.policy.check_policy.assert_has_calls([
268 273
             mock.call(ctx, 'share', 'get_all'),
269
-            mock.call(ctx, 'share', 'list_by_share_server_id'),
274
+            mock.call(ctx, 'share', policy),
270 275
         ])
271 276
 
272 277
     def test_get_all_admin_filter_by_share_server_and_all_tenants(self):

+ 2
- 1
manila_tempest_tests/tests/api/base.py View File

@@ -671,7 +671,8 @@ class BaseSharesTest(test.BaseTestCase):
671 671
     def get_pools_for_replication_domain(self):
672 672
         # Get the list of pools for the replication domain
673 673
         pools = self.admin_client.list_pools(detail=True)['pools']
674
-        instance_host = self.shares[0]['host']
674
+        instance_host = self.admin_client.get_share(
675
+            self.shares[0]['id'])['host']
675 676
         host_pool = [p for p in pools if p['name'] == instance_host][0]
676 677
         rep_domain = host_pool['capabilities']['replication_domain']
677 678
         pools_in_rep_domain = [p for p in pools if p['capabilities'][

+ 2
- 2
manila_tempest_tests/tests/api/test_replication.py View File

@@ -25,7 +25,7 @@ from manila_tempest_tests.tests.api import base
25 25
 CONF = config.CONF
26 26
 _MIN_SUPPORTED_MICROVERSION = '2.11'
27 27
 SUMMARY_KEYS = ['share_id', 'id', 'replica_state', 'status']
28
-DETAIL_KEYS = SUMMARY_KEYS + ['availability_zone', 'host', 'updated_at',
28
+DETAIL_KEYS = SUMMARY_KEYS + ['availability_zone', 'updated_at',
29 29
                               'share_network_id', 'created_at']
30 30
 
31 31
 
@@ -201,7 +201,7 @@ class ReplicationTest(base.BaseSharesMixedTest):
201 201
                                                    cleanup_in_class=False)
202 202
         self.shares_v2_client.get_share_replica(share_replica2['id'])
203 203
 
204
-        share_replicas = self.shares_v2_client.list_share_replicas(
204
+        share_replicas = self.admin_client.list_share_replicas(
205 205
             share_id=self.shares[0]["id"])
206 206
         replica_host_set = {r['host'] for r in share_replicas}
207 207
 

+ 1
- 1
manila_tempest_tests/tests/api/test_replication_negative.py View File

@@ -185,7 +185,7 @@ class ReplicationNegativeTest(base.BaseSharesMixedTest):
185 185
         hosts = [p['name'] for p in pools]
186 186
         self.create_share_replica(self.share1["id"], self.replica_zone,
187 187
                                   cleanup_in_class=False)
188
-        share_host = self.share1['host']
188
+        share_host = self.admin_client.get_share(self.share1['id'])['host']
189 189
 
190 190
         for host in hosts:
191 191
             if host != share_host:

+ 1
- 1
manila_tempest_tests/tests/api/test_shares.py View File

@@ -42,7 +42,7 @@ class SharesNFSTest(base.BaseSharesTest):
42 42
         share = self.create_share(self.protocol)
43 43
         detailed_elements = {'name', 'id', 'availability_zone',
44 44
                              'description', 'project_id',
45
-                             'host', 'created_at', 'share_proto', 'metadata',
45
+                             'created_at', 'share_proto', 'metadata',
46 46
                              'size', 'snapshot_id', 'share_network_id',
47 47
                              'status', 'share_type', 'volume_type', 'links',
48 48
                              'is_public'}

+ 3
- 16
manila_tempest_tests/tests/api/test_shares_actions.py View File

@@ -88,7 +88,7 @@ class SharesActionsTest(base.BaseSharesTest):
88 88
             "status", "description", "links", "availability_zone",
89 89
             "created_at", "project_id", "volume_type", "share_proto", "name",
90 90
             "snapshot_id", "id", "size", "share_network_id", "metadata",
91
-            "host", "snapshot_id", "is_public",
91
+            "snapshot_id", "is_public",
92 92
         ]
93 93
         if utils.is_microversion_lt(version, '2.9'):
94 94
             expected_keys.extend(["export_location", "export_locations"])
@@ -196,7 +196,7 @@ class SharesActionsTest(base.BaseSharesTest):
196 196
             "status", "description", "links", "availability_zone",
197 197
             "created_at", "project_id", "volume_type", "share_proto", "name",
198 198
             "snapshot_id", "id", "size", "share_network_id", "metadata",
199
-            "host", "snapshot_id", "is_public", "share_type",
199
+            "snapshot_id", "is_public", "share_type",
200 200
         ]
201 201
         if utils.is_microversion_lt(version, '2.9'):
202 202
             keys.extend(["export_location", "export_locations"])
@@ -283,19 +283,6 @@ class SharesActionsTest(base.BaseSharesTest):
283 283
         if CONF.share.capability_create_share_from_snapshot_support:
284 284
             self.assertFalse(self.shares[1]['id'] in [s['id'] for s in shares])
285 285
 
286
-    @tc.attr(base.TAG_POSITIVE, base.TAG_API_WITH_BACKEND)
287
-    def test_list_shares_with_detail_filter_by_host(self):
288
-        base_share = self.shares_client.get_share(self.shares[0]['id'])
289
-        filters = {'host': base_share['host']}
290
-
291
-        # list shares
292
-        shares = self.shares_client.list_shares_with_detail(params=filters)
293
-
294
-        # verify response
295
-        self.assertGreater(len(shares), 0)
296
-        for share in shares:
297
-            self.assertEqual(filters['host'], share['host'])
298
-
299 286
     @tc.attr(base.TAG_POSITIVE, base.TAG_API_WITH_BACKEND)
300 287
     @testtools.skipIf(
301 288
         not CONF.share.multitenancy_enabled, "Only for multitenancy.")
@@ -407,7 +394,7 @@ class SharesActionsTest(base.BaseSharesTest):
407 394
 
408 395
         keys = [
409 396
             "status", "description", "links", "availability_zone",
410
-            "created_at", "export_location", "share_proto", "host",
397
+            "created_at", "export_location", "share_proto",
411 398
             "name", "snapshot_id", "id", "size", "project_id", "is_public",
412 399
         ]
413 400
         [self.assertIn(key, sh.keys()) for sh in shares for key in keys]

+ 6
- 0
manila_tempest_tests/tests/api/test_shares_negative.py View File

@@ -193,6 +193,12 @@ class SharesAPIOnlyNegativeTest(base.BaseSharesTest):
193 193
                           'fake-host', 'nfs', '/export/path',
194 194
                           'fake-type')
195 195
 
196
+    @tc.attr(base.TAG_NEGATIVE, base.TAG_API)
197
+    def test_list_by_user_with_host_filter(self):
198
+        self.assertRaises(lib_exc.Forbidden,
199
+                          self.shares_v2_client.list_shares,
200
+                          params={'host': 'fake_host'})
201
+
196 202
     @tc.attr(base.TAG_NEGATIVE, base.TAG_API)
197 203
     def test_list_by_share_server_by_user(self):
198 204
         self.assertRaises(lib_exc.Forbidden,

+ 1
- 1
manila_tempest_tests/tests/scenario/test_share_basic_ops.py View File

@@ -312,7 +312,7 @@ class ShareBasicOpsBase(manager.ShareScenarioTest):
312 312
         instance = self.boot_instance(wait_until="BUILD")
313 313
         self.create_share()
314 314
         instance = self.wait_for_active_instance(instance["id"])
315
-        self.share = self.shares_client.get_share(self.share['id'])
315
+        self.share = self.shares_admin_v2_client.get_share(self.share['id'])
316 316
 
317 317
         default_type = self.shares_v2_client.list_share_types(
318 318
             default=True)['share_type']

+ 10
- 0
releasenotes/notes/remove-host-field-from-shares-and-replicas-a087f85bc4a4ba45.yaml View File

@@ -0,0 +1,10 @@
1
+---
2
+critical:
3
+  - The "host" field is no longer returned in the JSON response of the /shares
4
+    and /share-replicas APIs when these APIs are invoked with non-admin
5
+    privileges. Applications that depend on this field must be updated as
6
+    necessary. The value of this field is privileged information and the
7
+    request context must specify administrator privileges when using these
8
+    APIs for the "host" field to be present. The use of "host" as a filter
9
+    key in the GET /shares API is controlled with the policy "list_by_host".
10
+    This policy defaults to "rule:admin_api".

Loading…
Cancel
Save