Merge "Routers can be created with availability zone"
This commit is contained in:
commit
0ff122d830
@ -1728,3 +1728,15 @@ def policy_get(request, policy_id, **kwargs):
|
|||||||
policy = neutronclient(request).show_qos_policy(
|
policy = neutronclient(request).show_qos_policy(
|
||||||
policy_id, **kwargs).get('policy')
|
policy_id, **kwargs).get('policy')
|
||||||
return QoSPolicy(policy)
|
return QoSPolicy(policy)
|
||||||
|
|
||||||
|
|
||||||
|
@profiler.trace
|
||||||
|
def list_availability_zones(request, resource=None, state=None):
|
||||||
|
az_list = neutronclient(request).list_availability_zones().get(
|
||||||
|
'availability_zones')
|
||||||
|
if resource:
|
||||||
|
az_list = [az for az in az_list if az['resource'] == resource]
|
||||||
|
if state:
|
||||||
|
az_list = [az for az in az_list if az['state'] == state]
|
||||||
|
|
||||||
|
return sorted(az_list, key=lambda zone: zone['name'])
|
||||||
|
@ -41,6 +41,12 @@ class CreateForm(forms.SelfHandlingForm):
|
|||||||
required=False)
|
required=False)
|
||||||
mode = forms.ChoiceField(label=_("Router Type"))
|
mode = forms.ChoiceField(label=_("Router Type"))
|
||||||
ha = forms.ChoiceField(label=_("High Availability Mode"))
|
ha = forms.ChoiceField(label=_("High Availability Mode"))
|
||||||
|
az_hints = forms.MultipleChoiceField(
|
||||||
|
label=_("Availability Zone Hints"),
|
||||||
|
required=False,
|
||||||
|
help_text=_("Availability Zones where the router may be scheduled. "
|
||||||
|
"Leaving this unset is equivalent to selecting all "
|
||||||
|
"Availability Zones"))
|
||||||
failure_url = 'horizon:project:routers:index'
|
failure_url = 'horizon:project:routers:index'
|
||||||
|
|
||||||
def __init__(self, request, *args, **kwargs):
|
def __init__(self, request, *args, **kwargs):
|
||||||
@ -70,6 +76,17 @@ class CreateForm(forms.SelfHandlingForm):
|
|||||||
else:
|
else:
|
||||||
del self.fields['external_network']
|
del self.fields['external_network']
|
||||||
|
|
||||||
|
az_supported = api.neutron.is_extension_supported(
|
||||||
|
self.request, 'router_availability_zone')
|
||||||
|
|
||||||
|
if az_supported:
|
||||||
|
zones = api.neutron.list_availability_zones(self.request, 'router',
|
||||||
|
'available')
|
||||||
|
self.fields['az_hints'].choices = [(zone['name'], zone['name'])
|
||||||
|
for zone in zones]
|
||||||
|
else:
|
||||||
|
del self.fields['az_hints']
|
||||||
|
|
||||||
def _get_network_list(self, request):
|
def _get_network_list(self, request):
|
||||||
search_opts = {'router:external': True}
|
search_opts = {'router:external': True}
|
||||||
try:
|
try:
|
||||||
@ -94,6 +111,8 @@ class CreateForm(forms.SelfHandlingForm):
|
|||||||
if 'external_network' in data and data['external_network']:
|
if 'external_network' in data and data['external_network']:
|
||||||
params['external_gateway_info'] = {'network_id':
|
params['external_gateway_info'] = {'network_id':
|
||||||
data['external_network']}
|
data['external_network']}
|
||||||
|
if 'az_hints' in data and data['az_hints']:
|
||||||
|
params['availability_zone_hints'] = data['az_hints']
|
||||||
if (self.dvr_allowed and data['mode'] != 'server_default'):
|
if (self.dvr_allowed and data['mode'] != 'server_default'):
|
||||||
params['distributed'] = (data['mode'] == 'distributed')
|
params['distributed'] = (data['mode'] == 'distributed')
|
||||||
if (self.ha_allowed and data['ha'] != 'server_default'):
|
if (self.ha_allowed and data['ha'] != 'server_default'):
|
||||||
|
@ -257,7 +257,8 @@ class RouterActionTests(RouterMixin, test.TestCase):
|
|||||||
|
|
||||||
@test.create_stubs({api.neutron: ('router_create',
|
@test.create_stubs({api.neutron: ('router_create',
|
||||||
'get_feature_permission',
|
'get_feature_permission',
|
||||||
'network_list')})
|
'network_list',
|
||||||
|
'is_extension_supported')})
|
||||||
def test_router_create_post(self):
|
def test_router_create_post(self):
|
||||||
router = self.routers.first()
|
router = self.routers.first()
|
||||||
api.neutron.get_feature_permission(IsA(http.HttpRequest),
|
api.neutron.get_feature_permission(IsA(http.HttpRequest),
|
||||||
@ -268,6 +269,9 @@ class RouterActionTests(RouterMixin, test.TestCase):
|
|||||||
.AndReturn(False)
|
.AndReturn(False)
|
||||||
api.neutron.network_list(IsA(http.HttpRequest))\
|
api.neutron.network_list(IsA(http.HttpRequest))\
|
||||||
.AndReturn(self.networks.list())
|
.AndReturn(self.networks.list())
|
||||||
|
api.neutron.is_extension_supported(IsA(http.HttpRequest),
|
||||||
|
"router_availability_zone")\
|
||||||
|
.AndReturn(False)
|
||||||
params = {'name': router.name,
|
params = {'name': router.name,
|
||||||
'admin_state_up': router.admin_state_up}
|
'admin_state_up': router.admin_state_up}
|
||||||
api.neutron.router_create(IsA(http.HttpRequest), **params)\
|
api.neutron.router_create(IsA(http.HttpRequest), **params)\
|
||||||
@ -284,7 +288,8 @@ class RouterActionTests(RouterMixin, test.TestCase):
|
|||||||
|
|
||||||
@test.create_stubs({api.neutron: ('router_create',
|
@test.create_stubs({api.neutron: ('router_create',
|
||||||
'get_feature_permission',
|
'get_feature_permission',
|
||||||
'network_list')})
|
'network_list',
|
||||||
|
'is_extension_supported')})
|
||||||
def test_router_create_post_mode_server_default(self):
|
def test_router_create_post_mode_server_default(self):
|
||||||
router = self.routers.first()
|
router = self.routers.first()
|
||||||
api.neutron.get_feature_permission(IsA(http.HttpRequest),
|
api.neutron.get_feature_permission(IsA(http.HttpRequest),
|
||||||
@ -295,6 +300,9 @@ class RouterActionTests(RouterMixin, test.TestCase):
|
|||||||
.AndReturn(True)
|
.AndReturn(True)
|
||||||
api.neutron.network_list(IsA(http.HttpRequest))\
|
api.neutron.network_list(IsA(http.HttpRequest))\
|
||||||
.AndReturn(self.networks.list())
|
.AndReturn(self.networks.list())
|
||||||
|
api.neutron.is_extension_supported(IsA(http.HttpRequest),
|
||||||
|
"router_availability_zone")\
|
||||||
|
.AndReturn(False)
|
||||||
params = {'name': router.name,
|
params = {'name': router.name,
|
||||||
'admin_state_up': router.admin_state_up}
|
'admin_state_up': router.admin_state_up}
|
||||||
api.neutron.router_create(IsA(http.HttpRequest), **params)\
|
api.neutron.router_create(IsA(http.HttpRequest), **params)\
|
||||||
@ -313,7 +321,8 @@ class RouterActionTests(RouterMixin, test.TestCase):
|
|||||||
|
|
||||||
@test.create_stubs({api.neutron: ('router_create',
|
@test.create_stubs({api.neutron: ('router_create',
|
||||||
'get_feature_permission',
|
'get_feature_permission',
|
||||||
'network_list')})
|
'network_list',
|
||||||
|
'is_extension_supported')})
|
||||||
def test_dvr_ha_router_create_post(self):
|
def test_dvr_ha_router_create_post(self):
|
||||||
router = self.routers.first()
|
router = self.routers.first()
|
||||||
api.neutron.get_feature_permission(IsA(http.HttpRequest),
|
api.neutron.get_feature_permission(IsA(http.HttpRequest),
|
||||||
@ -324,6 +333,9 @@ class RouterActionTests(RouterMixin, test.TestCase):
|
|||||||
.MultipleTimes().AndReturn(True)
|
.MultipleTimes().AndReturn(True)
|
||||||
api.neutron.network_list(IsA(http.HttpRequest))\
|
api.neutron.network_list(IsA(http.HttpRequest))\
|
||||||
.AndReturn(self.networks.list())
|
.AndReturn(self.networks.list())
|
||||||
|
api.neutron.is_extension_supported(IsA(http.HttpRequest),
|
||||||
|
"router_availability_zone")\
|
||||||
|
.AndReturn(False)
|
||||||
param = {'name': router.name,
|
param = {'name': router.name,
|
||||||
'distributed': True,
|
'distributed': True,
|
||||||
'ha': True,
|
'ha': True,
|
||||||
@ -344,7 +356,47 @@ class RouterActionTests(RouterMixin, test.TestCase):
|
|||||||
|
|
||||||
@test.create_stubs({api.neutron: ('router_create',
|
@test.create_stubs({api.neutron: ('router_create',
|
||||||
'get_feature_permission',
|
'get_feature_permission',
|
||||||
'network_list')})
|
'network_list',
|
||||||
|
'is_extension_supported',
|
||||||
|
'list_availability_zones')})
|
||||||
|
def test_az_router_create_post(self):
|
||||||
|
router = self.routers.first()
|
||||||
|
api.neutron.get_feature_permission(IsA(http.HttpRequest),
|
||||||
|
"dvr", "create")\
|
||||||
|
.MultipleTimes().AndReturn(False)
|
||||||
|
api.neutron.get_feature_permission(IsA(http.HttpRequest),
|
||||||
|
"l3-ha", "create")\
|
||||||
|
.AndReturn(False)
|
||||||
|
api.neutron.network_list(IsA(http.HttpRequest))\
|
||||||
|
.AndReturn(self.networks.list())
|
||||||
|
api.neutron.is_extension_supported(IsA(http.HttpRequest),
|
||||||
|
"router_availability_zone")\
|
||||||
|
.AndReturn(True)
|
||||||
|
api.neutron.list_availability_zones(IsA(http.HttpRequest),
|
||||||
|
"router", "available")\
|
||||||
|
.AndReturn(self.neutron_availability_zones.list())
|
||||||
|
param = {'name': router.name,
|
||||||
|
'availability_zone_hints': ['nova'],
|
||||||
|
'admin_state_up': router.admin_state_up}
|
||||||
|
api.neutron.router_create(IsA(http.HttpRequest), **param)\
|
||||||
|
.AndReturn(router)
|
||||||
|
self.mox.ReplayAll()
|
||||||
|
|
||||||
|
form_data = {'name': router.name,
|
||||||
|
'mode': 'server_default',
|
||||||
|
'ha': 'server_default',
|
||||||
|
'az_hints': 'nova',
|
||||||
|
'admin_state_up': router.admin_state_up}
|
||||||
|
url = reverse('horizon:%s:routers:create' % self.DASHBOARD)
|
||||||
|
res = self.client.post(url, form_data)
|
||||||
|
|
||||||
|
self.assertNoFormErrors(res)
|
||||||
|
self.assertRedirectsNoFollow(res, self.INDEX_URL)
|
||||||
|
|
||||||
|
@test.create_stubs({api.neutron: ('router_create',
|
||||||
|
'get_feature_permission',
|
||||||
|
'network_list',
|
||||||
|
'is_extension_supported')})
|
||||||
def test_router_create_post_exception_error_case_409(self):
|
def test_router_create_post_exception_error_case_409(self):
|
||||||
router = self.routers.first()
|
router = self.routers.first()
|
||||||
api.neutron.get_feature_permission(IsA(http.HttpRequest),
|
api.neutron.get_feature_permission(IsA(http.HttpRequest),
|
||||||
@ -356,6 +408,9 @@ class RouterActionTests(RouterMixin, test.TestCase):
|
|||||||
self.exceptions.neutron.status_code = 409
|
self.exceptions.neutron.status_code = 409
|
||||||
api.neutron.network_list(IsA(http.HttpRequest))\
|
api.neutron.network_list(IsA(http.HttpRequest))\
|
||||||
.MultipleTimes().AndReturn(self.networks.list())
|
.MultipleTimes().AndReturn(self.networks.list())
|
||||||
|
api.neutron.is_extension_supported(IsA(http.HttpRequest),
|
||||||
|
"router_availability_zone")\
|
||||||
|
.AndReturn(False)
|
||||||
params = {'name': router.name,
|
params = {'name': router.name,
|
||||||
'admin_state_up': router.admin_state_up}
|
'admin_state_up': router.admin_state_up}
|
||||||
api.neutron.router_create(IsA(http.HttpRequest), **params)\
|
api.neutron.router_create(IsA(http.HttpRequest), **params)\
|
||||||
@ -372,6 +427,7 @@ class RouterActionTests(RouterMixin, test.TestCase):
|
|||||||
|
|
||||||
@test.create_stubs({api.neutron: ('router_create',
|
@test.create_stubs({api.neutron: ('router_create',
|
||||||
'get_feature_permission',
|
'get_feature_permission',
|
||||||
|
'is_extension_supported',
|
||||||
'network_list')})
|
'network_list')})
|
||||||
def test_router_create_post_exception_error_case_non_409(self):
|
def test_router_create_post_exception_error_case_non_409(self):
|
||||||
router = self.routers.first()
|
router = self.routers.first()
|
||||||
@ -384,6 +440,9 @@ class RouterActionTests(RouterMixin, test.TestCase):
|
|||||||
self.exceptions.neutron.status_code = 999
|
self.exceptions.neutron.status_code = 999
|
||||||
api.neutron.network_list(IsA(http.HttpRequest))\
|
api.neutron.network_list(IsA(http.HttpRequest))\
|
||||||
.MultipleTimes().AndReturn(self.networks.list())
|
.MultipleTimes().AndReturn(self.networks.list())
|
||||||
|
api.neutron.is_extension_supported(IsA(http.HttpRequest),
|
||||||
|
"router_availability_zone")\
|
||||||
|
.MultipleTimes().AndReturn(False)
|
||||||
params = {'name': router.name,
|
params = {'name': router.name,
|
||||||
'admin_state_up': router.admin_state_up}
|
'admin_state_up': router.admin_state_up}
|
||||||
api.neutron.router_create(IsA(http.HttpRequest), **params)\
|
api.neutron.router_create(IsA(http.HttpRequest), **params)\
|
||||||
|
@ -46,6 +46,7 @@ def data(TEST):
|
|||||||
TEST.ip_availability = utils.TestDataContainer()
|
TEST.ip_availability = utils.TestDataContainer()
|
||||||
TEST.qos_policies = utils.TestDataContainer()
|
TEST.qos_policies = utils.TestDataContainer()
|
||||||
TEST.tp_ports = utils.TestDataContainer()
|
TEST.tp_ports = utils.TestDataContainer()
|
||||||
|
TEST.neutron_availability_zones = utils.TestDataContainer()
|
||||||
|
|
||||||
# Data return by neutronclient.
|
# Data return by neutronclient.
|
||||||
TEST.api_agents = utils.TestDataContainer()
|
TEST.api_agents = utils.TestDataContainer()
|
||||||
@ -361,7 +362,8 @@ def data(TEST):
|
|||||||
'distributed': True,
|
'distributed': True,
|
||||||
'external_gateway_info':
|
'external_gateway_info':
|
||||||
{'network_id': ext_net['id']},
|
{'network_id': ext_net['id']},
|
||||||
'tenant_id': '1'}
|
'tenant_id': '1',
|
||||||
|
'availability_zone_hints': ['nova']}
|
||||||
TEST.api_routers.add(router_dict)
|
TEST.api_routers.add(router_dict)
|
||||||
TEST.routers.add(neutron.Router(router_dict))
|
TEST.routers.add(neutron.Router(router_dict))
|
||||||
router_dict = {'id': '10e3dc42-1ce1-4d48-87cf-7fc333055d6c',
|
router_dict = {'id': '10e3dc42-1ce1-4d48-87cf-7fc333055d6c',
|
||||||
@ -879,3 +881,12 @@ def data(TEST):
|
|||||||
{'trunk_id': tdata['trunk_id'],
|
{'trunk_id': tdata['trunk_id'],
|
||||||
'segmentation_type': 'vlan',
|
'segmentation_type': 'vlan',
|
||||||
'segmentation_id': tdata['tag_2']}))
|
'segmentation_id': tdata['tag_2']}))
|
||||||
|
|
||||||
|
# Availability Zones
|
||||||
|
TEST.neutron_availability_zones.add(
|
||||||
|
{
|
||||||
|
'state': 'available',
|
||||||
|
'resource': 'router',
|
||||||
|
'name': 'nova'
|
||||||
|
}
|
||||||
|
)
|
||||||
|
Loading…
Reference in New Issue
Block a user