Browse Source

Implement network availability zone column in network list

If the 'network_availability_zone'-extension is enabled, this patch adds a
column in the Networks-table named 'Availability Zones'.

Change-Id: Iea2bac351b922a0d267c4a55e0d74f6c2639d967
Partial-Bug: #1725617
tags/13.0.0.0b2
Trygve Vea 1 year ago
parent
commit
2949a9800f

+ 3
- 0
openstack_dashboard/dashboards/admin/networks/subnets/tests.py View File

@@ -428,6 +428,9 @@ class NetworkSubnetTests(test.BaseAdminViewTests):
428 428
         api.neutron.is_extension_supported(
429 429
             IsA(http.HttpRequest),
430 430
             'network-ip-availability').AndReturn(True)
431
+        api.neutron.is_extension_supported(IsA(http.HttpRequest),
432
+                                           'network_availability_zone')\
433
+            .MultipleTimes().AndReturn(True)
431 434
         api.neutron.is_extension_supported(IsA(http.HttpRequest),
432 435
                                            'dhcp_agent_scheduler')\
433 436
             .MultipleTimes().AndReturn(True)

+ 18
- 0
openstack_dashboard/dashboards/admin/networks/tables.py View File

@@ -106,6 +106,13 @@ DISPLAY_CHOICES = (
106 106
 )
107 107
 
108 108
 
109
+def get_availability_zones(network):
110
+    if 'availability_zones' in network and network.availability_zones:
111
+        return ', '.join(network.availability_zones)
112
+    else:
113
+        return _("-")
114
+
115
+
109 116
 class AdminNetworksFilterAction(project_tables.ProjectNetworksFilterAction):
110 117
     name = "filter_admin_networks"
111 118
     filter_choices = (('project', _("Project ="), True),) +\
@@ -131,6 +138,8 @@ class NetworksTable(tables.DataTable):
131 138
     admin_state = tables.Column("admin_state",
132 139
                                 verbose_name=_("Admin State"),
133 140
                                 display_choices=DISPLAY_CHOICES)
141
+    availability_zones = tables.Column(get_availability_zones,
142
+                                       verbose_name=_("Availability Zones"))
134 143
 
135 144
     def get_object_display(self, network):
136 145
         return network.name_or_id
@@ -147,6 +156,15 @@ class NetworksTable(tables.DataTable):
147 156
             request, data=data,
148 157
             needs_form_wrapper=needs_form_wrapper,
149 158
             **kwargs)
159
+        try:
160
+            if not api.neutron.is_extension_supported(
161
+                    request, "network_availability_zone"):
162
+                del self.columns["availability_zones"]
163
+        except Exception:
164
+            msg = _("Unable to check if network availability zone extension "
165
+                    "is supported")
166
+            exceptions.handle(self.request, msg)
167
+            del self.columns['availability_zones']
150 168
         try:
151 169
             if not api.neutron.is_extension_supported(request,
152 170
                                                       'dhcp_agent_scheduler'):

+ 33
- 0
openstack_dashboard/dashboards/admin/networks/tests.py View File

@@ -43,6 +43,9 @@ class NetworkTests(test.BaseAdminViewTests):
43 43
             .AndReturn(self.networks.list())
44 44
         api.keystone.tenant_list(IsA(http.HttpRequest))\
45 45
             .AndReturn([tenants, False])
46
+        api.neutron.is_extension_supported(
47
+            IsA(http.HttpRequest),
48
+            'network_availability_zone').AndReturn(True)
46 49
         for network in self.networks.list():
47 50
             usage.quotas.tenant_quota_usages(
48 51
                 IsA(http.HttpRequest), tenant_id=network.tenant_id,
@@ -70,6 +73,9 @@ class NetworkTests(test.BaseAdminViewTests):
70 73
     def test_index_network_list_exception(self):
71 74
         api.neutron.network_list(IsA(http.HttpRequest)) \
72 75
             .AndRaise(self.exceptions.neutron)
76
+        api.neutron.is_extension_supported(
77
+            IsA(http.HttpRequest),
78
+            'network_availability_zone').AndReturn(True)
73 79
         api.neutron.is_extension_supported(
74 80
             IsA(http.HttpRequest),
75 81
             'dhcp_agent_scheduler').AndReturn(True)
@@ -117,6 +123,9 @@ class NetworkTests(test.BaseAdminViewTests):
117 123
                                            'mac-learning') \
118 124
             .AndReturn(mac_learning)
119 125
 
126
+        api.neutron.is_extension_supported(
127
+            IsA(http.HttpRequest),
128
+            'network_availability_zone').AndReturn(True)
120 129
         api.neutron.is_extension_supported(
121 130
             IsA(http.HttpRequest),
122 131
             'dhcp_agent_scheduler').AndReturn(True)
@@ -155,6 +164,9 @@ class NetworkTests(test.BaseAdminViewTests):
155 164
         api.neutron.is_extension_supported(
156 165
             IsA(http.HttpRequest),
157 166
             'network-ip-availability').AndReturn(True)
167
+        api.neutron.is_extension_supported(
168
+            IsA(http.HttpRequest),
169
+            'network_availability_zone').AndReturn(True)
158 170
         api.neutron.is_extension_supported(
159 171
             IsA(http.HttpRequest),
160 172
             'dhcp_agent_scheduler').AndReturn(True)
@@ -192,6 +204,9 @@ class NetworkTests(test.BaseAdminViewTests):
192 204
         api.neutron.is_extension_supported(IsA(http.HttpRequest),
193 205
                                            'mac-learning')\
194 206
             .AndReturn(mac_learning)
207
+        api.neutron.is_extension_supported(
208
+            IsA(http.HttpRequest),
209
+            'network_availability_zone').AndReturn(True)
195 210
         api.neutron.is_extension_supported(
196 211
             IsA(http.HttpRequest),
197 212
             'dhcp_agent_scheduler').AndReturn(True)
@@ -232,6 +247,9 @@ class NetworkTests(test.BaseAdminViewTests):
232 247
         api.neutron.is_extension_supported(
233 248
             IsA(http.HttpRequest),
234 249
             'dhcp_agent_scheduler').AndReturn(True)
250
+        api.neutron.is_extension_supported(
251
+            IsA(http.HttpRequest),
252
+            'network_availability_zone').AndReturn(True)
235 253
         api.neutron.is_extension_supported(
236 254
             IsA(http.HttpRequest),
237 255
             'dhcp_agent_scheduler').AndReturn(True)
@@ -333,6 +351,9 @@ class NetworkTests(test.BaseAdminViewTests):
333 351
         api.neutron.is_extension_supported(
334 352
             IsA(http.HttpRequest),
335 353
             'dhcp_agent_scheduler').AndReturn(True)
354
+        api.neutron.is_extension_supported(
355
+            IsA(http.HttpRequest),
356
+            'network_availability_zone').AndReturn(True)
336 357
         api.neutron.is_extension_supported(
337 358
             IsA(http.HttpRequest),
338 359
             'dhcp_agent_scheduler').AndReturn(True)
@@ -389,6 +410,9 @@ class NetworkTests(test.BaseAdminViewTests):
389 410
         api.neutron.is_extension_supported(
390 411
             IsA(http.HttpRequest),
391 412
             'network-ip-availability').AndReturn(True)
413
+        api.neutron.is_extension_supported(
414
+            IsA(http.HttpRequest),
415
+            'network_availability_zone').AndReturn(True)
392 416
         api.neutron.is_extension_supported(IsA(http.HttpRequest),
393 417
                                            'dhcp_agent_scheduler')\
394 418
             .AndReturn(True)
@@ -772,6 +796,9 @@ class NetworkTests(test.BaseAdminViewTests):
772 796
         api.neutron.list_dhcp_agent_hosting_networks(IsA(http.HttpRequest),
773 797
                                                      network.id).\
774 798
             AndReturn(self.agents.list())
799
+        api.neutron.is_extension_supported(
800
+            IsA(http.HttpRequest),
801
+            'network_availability_zone').AndReturn(True)
775 802
         api.neutron.is_extension_supported(
776 803
             IsA(http.HttpRequest),
777 804
             'dhcp_agent_scheduler').AndReturn(True)
@@ -802,6 +829,9 @@ class NetworkTests(test.BaseAdminViewTests):
802 829
         api.neutron.list_dhcp_agent_hosting_networks(IsA(http.HttpRequest),
803 830
                                                      network.id).\
804 831
             AndReturn(self.agents.list())
832
+        api.neutron.is_extension_supported(
833
+            IsA(http.HttpRequest),
834
+            'network_availability_zone').AndReturn(True)
805 835
         api.neutron.is_extension_supported(
806 836
             IsA(http.HttpRequest),
807 837
             'dhcp_agent_scheduler').AndReturn(True)
@@ -825,6 +855,9 @@ class NetworkTests(test.BaseAdminViewTests):
825 855
     @test.create_stubs({api.neutron: ('is_extension_supported',)})
826 856
     @test.update_settings(FILTER_DATA_FIRST={'admin.networks': True})
827 857
     def test_networks_list_with_admin_filter_first(self):
858
+        api.neutron.is_extension_supported(
859
+            IsA(http.HttpRequest),
860
+            'network_availability_zone').AndReturn(True)
828 861
         api.neutron.is_extension_supported(
829 862
             IsA(http.HttpRequest),
830 863
             'dhcp_agent_scheduler').AndReturn(True)

+ 25
- 0
openstack_dashboard/dashboards/project/networks/tables.py View File

@@ -150,6 +150,13 @@ STATUS_DISPLAY_CHOICES = (
150 150
 )
151 151
 
152 152
 
153
+def get_availability_zones(network):
154
+    if 'availability_zones' in network and network.availability_zones:
155
+        return ', '.join(network.availability_zones)
156
+    else:
157
+        return _("-")
158
+
159
+
153 160
 class ProjectNetworksFilterAction(tables.FilterAction):
154 161
     name = "filter_project_networks"
155 162
     filter_type = "server"
@@ -178,6 +185,24 @@ class NetworksTable(tables.DataTable):
178 185
     admin_state = tables.Column("admin_state",
179 186
                                 verbose_name=_("Admin State"),
180 187
                                 display_choices=DISPLAY_CHOICES)
188
+    availability_zones = tables.Column(get_availability_zones,
189
+                                       verbose_name=_("Availability Zones"))
190
+
191
+    def __init__(self, request, data=None, needs_form_wrapper=None, **kwargs):
192
+        super(NetworksTable, self).__init__(
193
+            request,
194
+            data=data,
195
+            needs_form_wrapper=needs_form_wrapper,
196
+            **kwargs)
197
+        try:
198
+            if not api.neutron.is_extension_supported(
199
+                    request, "network_availability_zone"):
200
+                del self.columns["availability_zones"]
201
+        except Exception:
202
+            msg = _("Unable to check if network availability zone extension "
203
+                    "is supported")
204
+            exceptions.handle(self.request, msg)
205
+            del self.columns['availability_zones']
181 206
 
182 207
     def get_object_display(self, network):
183 208
         return network.name_or_id

+ 59
- 10
openstack_dashboard/dashboards/project/networks/tests.py View File

@@ -123,7 +123,8 @@ class NetworkStubMixin(object):
123 123
 
124 124
 class NetworkTests(test.TestCase, NetworkStubMixin):
125 125
 
126
-    @test.create_stubs({api.neutron: ('network_list',),
126
+    @test.create_stubs({api.neutron: ('network_list',
127
+                                      'is_extension_supported'),
127 128
                         quotas: ('tenant_quota_usages',)})
128 129
     def test_index(self):
129 130
         quota_data = self.quota_usages.first()
@@ -136,6 +137,9 @@ class NetworkTests(test.TestCase, NetworkStubMixin):
136 137
         quotas.tenant_quota_usages(
137 138
             IsA(http.HttpRequest), targets=('subnets', )) \
138 139
             .MultipleTimes().AndReturn(quota_data)
140
+        api.neutron.is_extension_supported(
141
+            IsA(http.HttpRequest), 'network_availability_zone')\
142
+            .MultipleTimes().AndReturn(True)
139 143
 
140 144
         self.mox.ReplayAll()
141 145
 
@@ -144,7 +148,8 @@ class NetworkTests(test.TestCase, NetworkStubMixin):
144 148
         networks = res.context['networks_table'].data
145 149
         self.assertItemsEqual(networks, self.networks.list())
146 150
 
147
-    @test.create_stubs({api.neutron: ('network_list',),
151
+    @test.create_stubs({api.neutron: ('network_list',
152
+                                      'is_extension_supported'),
148 153
                         quotas: ('tenant_quota_usages',)})
149 154
     def test_index_network_list_exception(self):
150 155
         quota_data = self.neutron_quota_usages.first()
@@ -155,6 +160,9 @@ class NetworkTests(test.TestCase, NetworkStubMixin):
155 160
         quotas.tenant_quota_usages(
156 161
             IsA(http.HttpRequest), targets=('networks', )) \
157 162
             .MultipleTimes().AndReturn(quota_data)
163
+        api.neutron.is_extension_supported(
164
+            IsA(http.HttpRequest), 'network_availability_zone')\
165
+            .MultipleTimes().AndReturn(True)
158 166
         self.mox.ReplayAll()
159 167
 
160 168
         res = self.client.get(INDEX_URL)
@@ -194,6 +202,9 @@ class NetworkTests(test.TestCase, NetworkStubMixin):
194 202
         quotas.tenant_quota_usages(
195 203
             IsA(http.HttpRequest), targets=('subnets', )) \
196 204
             .MultipleTimes().AndReturn(quota_data)
205
+        api.neutron.is_extension_supported(
206
+            IsA(http.HttpRequest), 'network_availability_zone')\
207
+            .MultipleTimes().AndReturn(True)
197 208
 
198 209
         self.mox.ReplayAll()
199 210
         url = urlunquote(reverse('horizon:project:networks:detail',
@@ -219,6 +230,9 @@ class NetworkTests(test.TestCase, NetworkStubMixin):
219 230
         quotas.tenant_quota_usages(
220 231
             IsA(http.HttpRequest), targets=('subnets', )) \
221 232
             .MultipleTimes().AndReturn(quota_data)
233
+        api.neutron.is_extension_supported(
234
+            IsA(http.HttpRequest), 'network_availability_zone')\
235
+            .MultipleTimes().AndReturn(True)
222 236
         self.mox.ReplayAll()
223 237
 
224 238
         url = urlunquote(reverse('horizon:project:networks:subnets_tab',
@@ -290,6 +304,9 @@ class NetworkTests(test.TestCase, NetworkStubMixin):
290 304
         quotas.tenant_quota_usages(
291 305
             IsA(http.HttpRequest), targets=('subnets', )) \
292 306
             .MultipleTimes().AndReturn(quota_data)
307
+        api.neutron.is_extension_supported(
308
+            IsA(http.HttpRequest), 'network_availability_zone')\
309
+            .MultipleTimes().AndReturn(True)
293 310
         self.mox.ReplayAll()
294 311
 
295 312
         url = urlunquote(reverse('horizon:project:networks:subnets_tab',
@@ -330,6 +347,9 @@ class NetworkTests(test.TestCase, NetworkStubMixin):
330 347
         quotas.tenant_quota_usages(
331 348
             IsA(http.HttpRequest), targets=('subnets', )) \
332 349
             .MultipleTimes().AndReturn(quota_data)
350
+        api.neutron.is_extension_supported(
351
+            IsA(http.HttpRequest), 'network_availability_zone')\
352
+            .MultipleTimes().AndReturn(True)
333 353
         self.mox.ReplayAll()
334 354
 
335 355
         url = urlunquote(reverse('horizon:project:networks:subnets_tab',
@@ -911,7 +931,8 @@ class NetworkTests(test.TestCase, NetworkStubMixin):
911 931
 
912 932
     @test.create_stubs({api.neutron: ('network_get',
913 933
                                       'network_list',
914
-                                      'network_delete')})
934
+                                      'network_delete',
935
+                                      'is_extension_supported')})
915 936
     def test_delete_network_no_subnet(self):
916 937
         network = self.networks.first()
917 938
         network.subnets = []
@@ -919,6 +940,9 @@ class NetworkTests(test.TestCase, NetworkStubMixin):
919 940
                                 network.id,
920 941
                                 expand_subnet=False)\
921 942
             .AndReturn(network)
943
+        api.neutron.is_extension_supported(
944
+            IsA(http.HttpRequest), 'network_availability_zone')\
945
+            .MultipleTimes().AndReturn(True)
922 946
         self._stub_net_list()
923 947
         api.neutron.network_delete(IsA(http.HttpRequest), network.id)
924 948
 
@@ -931,7 +955,8 @@ class NetworkTests(test.TestCase, NetworkStubMixin):
931 955
     @test.create_stubs({api.neutron: ('network_get',
932 956
                                       'network_list',
933 957
                                       'network_delete',
934
-                                      'subnet_delete')})
958
+                                      'subnet_delete',
959
+                                      'is_extension_supported')})
935 960
     def test_delete_network_with_subnet(self):
936 961
         network = self.networks.first()
937 962
         network.subnets = [subnet.id for subnet in network.subnets]
@@ -941,6 +966,9 @@ class NetworkTests(test.TestCase, NetworkStubMixin):
941 966
                                 network.id,
942 967
                                 expand_subnet=False)\
943 968
             .AndReturn(network)
969
+        api.neutron.is_extension_supported(
970
+            IsA(http.HttpRequest), 'network_availability_zone')\
971
+            .MultipleTimes().AndReturn(True)
944 972
         self._stub_net_list()
945 973
         api.neutron.subnet_delete(IsA(http.HttpRequest), subnet_id)
946 974
         api.neutron.subnet_delete(IsA(http.HttpRequest), subnetv6_id)
@@ -956,7 +984,8 @@ class NetworkTests(test.TestCase, NetworkStubMixin):
956 984
     @test.create_stubs({api.neutron: ('network_get',
957 985
                                       'network_list',
958 986
                                       'network_delete',
959
-                                      'subnet_delete')})
987
+                                      'subnet_delete',
988
+                                      'is_extension_supported')})
960 989
     def test_delete_network_exception(self):
961 990
         network = self.networks.first()
962 991
         network.subnets = [subnet.id for subnet in network.subnets]
@@ -966,6 +995,9 @@ class NetworkTests(test.TestCase, NetworkStubMixin):
966 995
                                 network.id,
967 996
                                 expand_subnet=False)\
968 997
             .AndReturn(network)
998
+        api.neutron.is_extension_supported(
999
+            IsA(http.HttpRequest), 'network_availability_zone')\
1000
+            .MultipleTimes().AndReturn(True)
969 1001
         self._stub_net_list()
970 1002
         api.neutron.subnet_delete(IsA(http.HttpRequest), subnet_id)
971 1003
         api.neutron.subnet_delete(IsA(http.HttpRequest), subnetv6_id)
@@ -999,6 +1031,9 @@ class NetworkViewTests(test.TestCase, NetworkStubMixin):
999 1031
         quotas.tenant_quota_usages(
1000 1032
             IsA(http.HttpRequest), targets=('subnets', )) \
1001 1033
             .MultipleTimes().AndReturn(quota_data)
1034
+        api.neutron.is_extension_supported(
1035
+            IsA(http.HttpRequest), 'network_availability_zone')\
1036
+            .MultipleTimes().AndReturn(True)
1002 1037
 
1003 1038
         self.mox.ReplayAll()
1004 1039
 
@@ -1028,6 +1063,9 @@ class NetworkViewTests(test.TestCase, NetworkStubMixin):
1028 1063
         quotas.tenant_quota_usages(
1029 1064
             IsA(http.HttpRequest), targets=('subnets', )) \
1030 1065
             .MultipleTimes().AndReturn(quota_data)
1066
+        api.neutron.is_extension_supported(
1067
+            IsA(http.HttpRequest), 'network_availability_zone')\
1068
+            .MultipleTimes().AndReturn(True)
1031 1069
 
1032 1070
         self.mox.ReplayAll()
1033 1071
 
@@ -1042,7 +1080,8 @@ class NetworkViewTests(test.TestCase, NetworkStubMixin):
1042 1080
                       "The create button should be disabled")
1043 1081
         return button
1044 1082
 
1045
-    @test.create_stubs({api.neutron: ('network_list',),
1083
+    @test.create_stubs({api.neutron: ('network_list',
1084
+                                      'is_extension_supported'),
1046 1085
                         quotas: ('tenant_quota_usages',)})
1047 1086
     def test_network_create_button_disabled_when_quota_exceeded_index(self):
1048 1087
         networks_tables.CreateNetwork()
@@ -1052,7 +1091,8 @@ class NetworkViewTests(test.TestCase, NetworkStubMixin):
1052 1091
         self._test_create_button_disabled_when_quota_exceeded(_find_net_button,
1053 1092
                                                               network_quota=0)
1054 1093
 
1055
-    @test.create_stubs({api.neutron: ('network_list',),
1094
+    @test.create_stubs({api.neutron: ('network_list',
1095
+                                      'is_extension_supported'),
1056 1096
                         quotas: ('tenant_quota_usages',)})
1057 1097
     def test_subnet_create_button_disabled_when_quota_exceeded_index(self):
1058 1098
         network_id = self.networks.first().id
@@ -1065,7 +1105,8 @@ class NetworkViewTests(test.TestCase, NetworkStubMixin):
1065 1105
         self._test_create_button_disabled_when_quota_exceeded(
1066 1106
             _find_subnet_button, subnet_quota=0)
1067 1107
 
1068
-    @test.create_stubs({api.neutron: ('network_list',),
1108
+    @test.create_stubs({api.neutron: ('network_list',
1109
+                                      'is_extension_supported'),
1069 1110
                         quotas: ('tenant_quota_usages',)})
1070 1111
     def test_network_create_button_shown_when_quota_disabled_index(self):
1071 1112
         # if quota_data doesnt contain a networks["available"] key its disabled
@@ -1074,7 +1115,8 @@ class NetworkViewTests(test.TestCase, NetworkStubMixin):
1074 1115
             lambda res: self.getAndAssertTableAction(res, 'networks', 'create')
1075 1116
         )
1076 1117
 
1077
-    @test.create_stubs({api.neutron: ('network_list',),
1118
+    @test.create_stubs({api.neutron: ('network_list',
1119
+                                      'is_extension_supported'),
1078 1120
                         quotas: ('tenant_quota_usages',)})
1079 1121
     def test_subnet_create_button_shown_when_quota_disabled_index(self):
1080 1122
         # if quota_data doesnt contain a subnets["available"] key, its disabled
@@ -1106,6 +1148,9 @@ class NetworkViewTests(test.TestCase, NetworkStubMixin):
1106 1148
         quotas.tenant_quota_usages(
1107 1149
             IsA(http.HttpRequest), targets=('subnets', )) \
1108 1150
             .MultipleTimes().AndReturn(quota_data)
1151
+        api.neutron.is_extension_supported(
1152
+            IsA(http.HttpRequest), 'network_availability_zone')\
1153
+            .MultipleTimes().AndReturn(True)
1109 1154
 
1110 1155
         self.mox.ReplayAll()
1111 1156
 
@@ -1135,7 +1180,8 @@ class NetworkViewTests(test.TestCase, NetworkStubMixin):
1135 1180
         self.assertNotIn('disabled', create_action.classes,
1136 1181
                          'The create button should be enabled')
1137 1182
 
1138
-    @test.create_stubs({api.neutron: ('network_list',),
1183
+    @test.create_stubs({api.neutron: ('network_list',
1184
+                                      'is_extension_supported'),
1139 1185
                         quotas: ('tenant_quota_usages',)})
1140 1186
     def test_create_button_attributes(self):
1141 1187
         create_action = self._test_create_button_shown_when_quota_disabled(
@@ -1184,6 +1230,9 @@ class NetworkViewTests(test.TestCase, NetworkStubMixin):
1184 1230
         quotas.tenant_quota_usages(
1185 1231
             IsA(http.HttpRequest), targets=('ports',)) \
1186 1232
             .MultipleTimes().AndReturn(quota_data)
1233
+        api.neutron.is_extension_supported(
1234
+            IsA(http.HttpRequest), 'network_availability_zone')\
1235
+            .MultipleTimes().AndReturn(True)
1187 1236
 
1188 1237
         self.mox.ReplayAll()
1189 1238
 

Loading…
Cancel
Save