Merge "Add HA mode support for Neutron router"
This commit is contained in:
commit
1544a7d8af
|
@ -474,6 +474,7 @@ Default::
|
|||
{
|
||||
'enable_router': True,
|
||||
'enable_distributed_router': False,
|
||||
'enable_ha_router': False,
|
||||
'enable_lb': True,
|
||||
'enable_quotas': False,
|
||||
'enable_firewall': True,
|
||||
|
@ -512,6 +513,19 @@ when your Neutron plugin (like ML2 plugin) supports DVR feature, DVR
|
|||
feature depends on l3-agent configuration, so deployers should set this
|
||||
option appropriately depending on your deployment.
|
||||
|
||||
``enable_ha_router``:
|
||||
|
||||
.. versionadded:: 2014.2(Juno)
|
||||
|
||||
Default: ``False``
|
||||
|
||||
Enable or disable HA (High Availability) mode in Neutron virtual router
|
||||
in the Router panel. For the HA router mode to be enabled, this option needs
|
||||
to be set to True and your Neutron deployment must support HA router mode.
|
||||
Even when your Neutron plugin (like ML2 plugin) supports HA router mode,
|
||||
the feature depends on l3-agent configuration, so deployers should set this
|
||||
option appropriately depending on your deployment.
|
||||
|
||||
``enable_lb``:
|
||||
|
||||
.. versionadded:: 2013.1(Grizzly)
|
||||
|
|
|
@ -943,31 +943,90 @@ def is_port_profiles_supported():
|
|||
return True
|
||||
|
||||
|
||||
def get_dvr_permission(request, operation):
|
||||
"""Check if "distributed" field can be displayed.
|
||||
# FEATURE_MAP is used to define:
|
||||
# - related neutron extension name (key: "extension")
|
||||
# - corresponding dashboard config (key: "config")
|
||||
# - RBAC policies (key: "poclies")
|
||||
# If a key is not contained, the corresponding permission check is skipped.
|
||||
FEATURE_MAP = {
|
||||
'dvr': {
|
||||
'extension': 'dvr',
|
||||
'config': {
|
||||
'name': 'enable_distributed_router',
|
||||
'default': False,
|
||||
},
|
||||
'policies': {
|
||||
'get': 'get_router:distributed',
|
||||
'create': 'create_router:distributed',
|
||||
'update': 'update_router:distributed',
|
||||
}
|
||||
},
|
||||
'l3-ha': {
|
||||
'extension': 'l3-ha',
|
||||
'config': {'name': 'enable_ha_router',
|
||||
'default': False},
|
||||
'policies': {
|
||||
'get': 'get_router:ha',
|
||||
'create': 'create_router:ha',
|
||||
'update': 'update_router:ha',
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
def get_feature_permission(request, feature, operation=None):
|
||||
"""Check if a feature-specific field can be displayed.
|
||||
|
||||
This method check a permission for a feature-specific field.
|
||||
Such field is usually provided through Neutron extension.
|
||||
|
||||
:param request: Request Object
|
||||
:param operation: Operation type. The valid value is "get" or "create"
|
||||
:param feature: feature name defined in FEATURE_MAP
|
||||
:param operation (optional): Operation type. The valid value should be
|
||||
defined in FEATURE_MAP[feature]['policies']
|
||||
It must be specified if FEATURE_MAP[feature] has 'policies'.
|
||||
"""
|
||||
network_config = getattr(settings, 'OPENSTACK_NEUTRON_NETWORK', {})
|
||||
if not network_config.get('enable_distributed_router', False):
|
||||
return False
|
||||
feature_info = FEATURE_MAP.get(feature)
|
||||
if not feature_info:
|
||||
# Translators: Only used inside Horizon code and invisible to users
|
||||
raise ValueError(_("The requested feature '%(feature)s' is unknown. "
|
||||
"Please make sure to specify a feature defined "
|
||||
"in FEATURE_MAP."))
|
||||
|
||||
# Check dashboard settings
|
||||
feature_config = feature_info.get('config')
|
||||
if feature_config:
|
||||
if not network_config.get(feature_config['name'],
|
||||
feature_config['default']):
|
||||
return False
|
||||
|
||||
# Check policy
|
||||
feature_policies = feature_info.get('policies')
|
||||
policy_check = getattr(settings, "POLICY_CHECK_FUNCTION", None)
|
||||
allowed_operations = ("get", "create", "update")
|
||||
if operation not in allowed_operations:
|
||||
raise ValueError(_("The 'operation' parameter for get_dvr_permission "
|
||||
"is invalid. It should be one of %s")
|
||||
% ' '.join(allowed_operations))
|
||||
role = (("network", "%s_router:distributed" % operation),)
|
||||
if policy_check:
|
||||
has_permission = policy.check(role, request)
|
||||
else:
|
||||
has_permission = True
|
||||
if not has_permission:
|
||||
return False
|
||||
try:
|
||||
return is_extension_supported(request, 'dvr')
|
||||
except Exception:
|
||||
msg = _('Failed to check Neutron "dvr" extension is not supported')
|
||||
LOG.info(msg)
|
||||
return False
|
||||
if feature_policies and policy_check:
|
||||
policy_name = feature_policies.get(operation)
|
||||
if not policy_name:
|
||||
# Translators: Only used inside Horizon code and invisible to users
|
||||
raise ValueError(_("The 'operation' parameter for "
|
||||
"get_feature_permission '%(feature)s' "
|
||||
"is invalid. It should be one of %(allowed)s")
|
||||
% {'feature': feature,
|
||||
'allowed': ' '.join(feature_policies.keys())})
|
||||
role = (('network', policy_name),)
|
||||
if not policy.check(role, request):
|
||||
return False
|
||||
|
||||
# Check if a required extension is enabled
|
||||
feature_extension = feature_info.get('extension')
|
||||
if feature_extension:
|
||||
try:
|
||||
return is_extension_supported(request, feature_extension)
|
||||
except Exception:
|
||||
msg = (_("Failed to check Neutron '%s' extension is not supported")
|
||||
% feature_extension)
|
||||
LOG.info(msg)
|
||||
return False
|
||||
|
||||
# If all checks are passed, now a given feature is allowed.
|
||||
return True
|
||||
|
|
|
@ -148,6 +148,9 @@
|
|||
"get_router:distributed": "rule:admin_only",
|
||||
"create_router:distributed": "rule:admin_only",
|
||||
"update_router:distributed": "rule:admin_only",
|
||||
"get_router:ha": "rule:admin_only",
|
||||
"create_router:ha": "rule:admin_only",
|
||||
"update_router:ha": "rule:admin_only",
|
||||
|
||||
"create_floatingip": "rule:regular_user",
|
||||
"update_floatingip": "rule:admin_or_owner",
|
||||
|
|
|
@ -18,6 +18,10 @@
|
|||
<dt>{% trans "Distributed" %}</dt>
|
||||
<dd>{{ router.distributed|yesno|capfirst }}</dd>
|
||||
{% endif %}
|
||||
{% if ha_supported %}
|
||||
<dt>{% trans "High Availability Mode" %}</dt>
|
||||
<dd>{{ router.ha|yesno|capfirst }}</dd>
|
||||
{% endif %}
|
||||
{% if router.external_gateway_info %}
|
||||
<dt>{% trans "External Gateway Information" %}</dt>
|
||||
<dd>{% trans "Connected External Network" %}:
|
||||
|
|
|
@ -34,26 +34,38 @@ LOG = logging.getLogger(__name__)
|
|||
class CreateForm(forms.SelfHandlingForm):
|
||||
name = forms.CharField(max_length=255, label=_("Router Name"))
|
||||
mode = forms.ChoiceField(label=_("Router Type"))
|
||||
ha = forms.ChoiceField(label=_("High Availability Mode"))
|
||||
failure_url = 'horizon:project:routers:index'
|
||||
|
||||
def __init__(self, request, *args, **kwargs):
|
||||
super(CreateForm, self).__init__(request, *args, **kwargs)
|
||||
self.dvr_enabled = api.neutron.get_dvr_permission(self.request,
|
||||
"create")
|
||||
if self.dvr_enabled:
|
||||
self.dvr_allowed = api.neutron.get_feature_permission(self.request,
|
||||
"dvr", "create")
|
||||
if self.dvr_allowed:
|
||||
mode_choices = [('server_default', _('Use Server Default')),
|
||||
('centralized', _('Centralized')),
|
||||
('distributed', _('Distributed'))]
|
||||
self.fields['mode'].choices = mode_choices
|
||||
else:
|
||||
self.fields['mode'].widget = forms.HiddenInput()
|
||||
self.fields['mode'].required = False
|
||||
del self.fields['mode']
|
||||
|
||||
self.ha_allowed = api.neutron.get_feature_permission(self.request,
|
||||
"l3-ha", "create")
|
||||
if self.ha_allowed:
|
||||
ha_choices = [('server_default', _('Use Server Default')),
|
||||
('enabled', _('Enable HA mode')),
|
||||
('disabled', _('Disable HA mode'))]
|
||||
self.fields['ha'].choices = ha_choices
|
||||
else:
|
||||
del self.fields['ha']
|
||||
|
||||
def handle(self, request, data):
|
||||
try:
|
||||
params = {'name': data['name']}
|
||||
if (self.dvr_enabled and data['mode'] != 'server_default'):
|
||||
if (self.dvr_allowed and data['mode'] != 'server_default'):
|
||||
params['distributed'] = (data['mode'] == 'distributed')
|
||||
if (self.ha_allowed and data['ha'] != 'server_default'):
|
||||
params['ha'] = (data['ha'] == 'enabled')
|
||||
router = api.neutron.router_create(request, **params)
|
||||
message = _('Router %s was successfully created.') % data['name']
|
||||
messages.success(request, message)
|
||||
|
@ -77,13 +89,14 @@ class UpdateForm(forms.SelfHandlingForm):
|
|||
router_id = forms.CharField(label=_("ID"),
|
||||
widget=forms.HiddenInput())
|
||||
mode = forms.ChoiceField(label=_("Router Type"))
|
||||
ha = forms.BooleanField(label=_("High Availability Mode"), required=False)
|
||||
|
||||
redirect_url = reverse_lazy('horizon:project:routers:index')
|
||||
|
||||
def __init__(self, request, *args, **kwargs):
|
||||
super(UpdateForm, self).__init__(request, *args, **kwargs)
|
||||
self.dvr_allowed = api.neutron.get_dvr_permission(self.request,
|
||||
"update")
|
||||
self.dvr_allowed = api.neutron.get_feature_permission(self.request,
|
||||
"dvr", "update")
|
||||
if not self.dvr_allowed:
|
||||
del self.fields['mode']
|
||||
elif kwargs.get('initial', {}).get('mode') == 'distributed':
|
||||
|
@ -98,12 +111,19 @@ class UpdateForm(forms.SelfHandlingForm):
|
|||
('distributed', _('Distributed'))]
|
||||
self.fields['mode'].choices = mode_choices
|
||||
|
||||
self.ha_allowed = api.neutron.get_feature_permission(self.request,
|
||||
"l3-ha", "update")
|
||||
if not self.ha_allowed:
|
||||
del self.fields['ha']
|
||||
|
||||
def handle(self, request, data):
|
||||
try:
|
||||
params = {'admin_state_up': (data['admin_state'] == 'True'),
|
||||
'name': data['name']}
|
||||
if self.dvr_allowed:
|
||||
params['distributed'] = (data['mode'] == 'distributed')
|
||||
if self.ha_allowed:
|
||||
params['ha'] = data['ha']
|
||||
router = api.neutron.router_update(request, data['router_id'],
|
||||
**params)
|
||||
msg = _('Router %s was successfully updated.') % data['name']
|
||||
|
|
|
@ -171,6 +171,10 @@ class RoutersTable(tables.DataTable):
|
|||
distributed = tables.Column("distributed",
|
||||
filters=(filters.yesno, filters.capfirst),
|
||||
verbose_name=_("Distributed"))
|
||||
ha = tables.Column("ha",
|
||||
filters=(filters.yesno, filters.capfirst),
|
||||
# Translators: High Availability mode of Neutron router
|
||||
verbose_name=_("HA mode"))
|
||||
ext_net = tables.Column(get_external_network,
|
||||
verbose_name=_("External Network"))
|
||||
|
||||
|
@ -180,8 +184,10 @@ class RoutersTable(tables.DataTable):
|
|||
data=data,
|
||||
needs_form_wrapper=needs_form_wrapper,
|
||||
**kwargs)
|
||||
if not api.neutron.get_dvr_permission(request, "get"):
|
||||
if not api.neutron.get_feature_permission(request, "dvr", "get"):
|
||||
del self.columns["distributed"]
|
||||
if not api.neutron.get_feature_permission(request, "l3-ha", "get"):
|
||||
del self.columns["ha"]
|
||||
|
||||
def get_object_display(self, obj):
|
||||
return obj.name
|
||||
|
|
|
@ -16,6 +16,10 @@
|
|||
<dt>{% trans "Distributed" %}</dt>
|
||||
<dd>{{ router.distributed|yesno|capfirst }}</dd>
|
||||
{% endif %}
|
||||
{% if ha_supported %}
|
||||
<dt>{% trans "High Availability Mode" %}</dt>
|
||||
<dd>{{ router.ha|yesno|capfirst }}</dd>
|
||||
{% endif %}
|
||||
{% if router.external_gateway_info %}
|
||||
<dt>{% trans "External Gateway Information" %}</dt>
|
||||
<dd>{% trans "Connected External Network" %}:
|
||||
|
|
|
@ -133,10 +133,14 @@ class RouterActionTests(test.TestCase):
|
|||
DETAIL_PATH = 'horizon:%s:routers:detail' % DASHBOARD
|
||||
|
||||
@test.create_stubs({api.neutron: ('router_create',
|
||||
'get_dvr_permission',)})
|
||||
'get_feature_permission',)})
|
||||
def test_router_create_post(self):
|
||||
router = self.routers.first()
|
||||
api.neutron.get_dvr_permission(IsA(http.HttpRequest), "create")\
|
||||
api.neutron.get_feature_permission(IsA(http.HttpRequest),
|
||||
"dvr", "create")\
|
||||
.AndReturn(False)
|
||||
api.neutron.get_feature_permission(IsA(http.HttpRequest),
|
||||
"l3-ha", "create")\
|
||||
.AndReturn(False)
|
||||
api.neutron.router_create(IsA(http.HttpRequest), name=router.name)\
|
||||
.AndReturn(router)
|
||||
|
@ -150,17 +154,22 @@ class RouterActionTests(test.TestCase):
|
|||
self.assertRedirectsNoFollow(res, self.INDEX_URL)
|
||||
|
||||
@test.create_stubs({api.neutron: ('router_create',
|
||||
'get_dvr_permission',)})
|
||||
'get_feature_permission',)})
|
||||
def test_router_create_post_mode_server_default(self):
|
||||
router = self.routers.first()
|
||||
api.neutron.get_dvr_permission(IsA(http.HttpRequest), "create")\
|
||||
api.neutron.get_feature_permission(IsA(http.HttpRequest),
|
||||
"dvr", "create")\
|
||||
.AndReturn(True)
|
||||
api.neutron.get_feature_permission(IsA(http.HttpRequest),
|
||||
"l3-ha", "create")\
|
||||
.AndReturn(True)
|
||||
api.neutron.router_create(IsA(http.HttpRequest), name=router.name)\
|
||||
.AndReturn(router)
|
||||
|
||||
self.mox.ReplayAll()
|
||||
form_data = {'name': router.name,
|
||||
'mode': 'server_default'}
|
||||
'mode': 'server_default',
|
||||
'ha': 'server_default'}
|
||||
url = reverse('horizon:%s:routers:create' % self.DASHBOARD)
|
||||
res = self.client.post(url, form_data)
|
||||
|
||||
|
@ -168,19 +177,25 @@ class RouterActionTests(test.TestCase):
|
|||
self.assertRedirectsNoFollow(res, self.INDEX_URL)
|
||||
|
||||
@test.create_stubs({api.neutron: ('router_create',
|
||||
'get_dvr_permission',)})
|
||||
def test_dvr_router_create_post(self):
|
||||
'get_feature_permission',)})
|
||||
def test_dvr_ha_router_create_post(self):
|
||||
router = self.routers.first()
|
||||
api.neutron.get_dvr_permission(IsA(http.HttpRequest), "create")\
|
||||
api.neutron.get_feature_permission(IsA(http.HttpRequest),
|
||||
"dvr", "create")\
|
||||
.MultipleTimes().AndReturn(True)
|
||||
api.neutron.get_feature_permission(IsA(http.HttpRequest),
|
||||
"l3-ha", "create")\
|
||||
.MultipleTimes().AndReturn(True)
|
||||
param = {'name': router.name,
|
||||
'distributed': True}
|
||||
'distributed': True,
|
||||
'ha': True}
|
||||
api.neutron.router_create(IsA(http.HttpRequest), **param)\
|
||||
.AndReturn(router)
|
||||
|
||||
self.mox.ReplayAll()
|
||||
form_data = {'name': router.name,
|
||||
'mode': 'distributed'}
|
||||
'mode': 'distributed',
|
||||
'ha': 'enabled'}
|
||||
url = reverse('horizon:%s:routers:create' % self.DASHBOARD)
|
||||
res = self.client.post(url, form_data)
|
||||
|
||||
|
@ -188,11 +203,15 @@ class RouterActionTests(test.TestCase):
|
|||
self.assertRedirectsNoFollow(res, self.INDEX_URL)
|
||||
|
||||
@test.create_stubs({api.neutron: ('router_create',
|
||||
'get_dvr_permission',)})
|
||||
'get_feature_permission',)})
|
||||
def test_router_create_post_exception_error_case_409(self):
|
||||
router = self.routers.first()
|
||||
api.neutron.get_dvr_permission(IsA(http.HttpRequest), "create")\
|
||||
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)
|
||||
self.exceptions.neutron.status_code = 409
|
||||
api.neutron.router_create(IsA(http.HttpRequest), name=router.name)\
|
||||
.AndRaise(self.exceptions.neutron)
|
||||
|
@ -206,10 +225,14 @@ class RouterActionTests(test.TestCase):
|
|||
self.assertRedirectsNoFollow(res, self.INDEX_URL)
|
||||
|
||||
@test.create_stubs({api.neutron: ('router_create',
|
||||
'get_dvr_permission',)})
|
||||
'get_feature_permission',)})
|
||||
def test_router_create_post_exception_error_case_non_409(self):
|
||||
router = self.routers.first()
|
||||
api.neutron.get_dvr_permission(IsA(http.HttpRequest), "create")\
|
||||
api.neutron.get_feature_permission(IsA(http.HttpRequest),
|
||||
"dvr", "create")\
|
||||
.MultipleTimes().AndReturn(False)
|
||||
api.neutron.get_feature_permission(IsA(http.HttpRequest),
|
||||
"l3-ha", "create")\
|
||||
.MultipleTimes().AndReturn(False)
|
||||
self.exceptions.neutron.status_code = 999
|
||||
api.neutron.router_create(IsA(http.HttpRequest), name=router.name)\
|
||||
|
@ -224,15 +247,20 @@ class RouterActionTests(test.TestCase):
|
|||
self.assertRedirectsNoFollow(res, self.INDEX_URL)
|
||||
|
||||
@test.create_stubs({api.neutron: ('router_get',
|
||||
'get_dvr_permission')})
|
||||
'get_feature_permission')})
|
||||
def _test_router_update_get(self, dvr_enabled=False,
|
||||
current_dvr=False):
|
||||
current_dvr=False,
|
||||
ha_enabled=False):
|
||||
router = [r for r in self.routers.list()
|
||||
if r.distributed == current_dvr][0]
|
||||
api.neutron.router_get(IsA(http.HttpRequest), router.id)\
|
||||
.AndReturn(router)
|
||||
api.neutron.get_dvr_permission(IsA(http.HttpRequest), "update")\
|
||||
api.neutron.get_feature_permission(IsA(http.HttpRequest),
|
||||
"dvr", "update")\
|
||||
.AndReturn(dvr_enabled)
|
||||
api.neutron.get_feature_permission(IsA(http.HttpRequest),
|
||||
"l3-ha", "update")\
|
||||
.AndReturn(ha_enabled)
|
||||
self.mox.ReplayAll()
|
||||
|
||||
url = reverse('horizon:%s:routers:update' % self.DASHBOARD,
|
||||
|
@ -276,10 +304,14 @@ class RouterActionTests(test.TestCase):
|
|||
|
||||
@test.create_stubs({api.neutron: ('router_get',
|
||||
'router_update',
|
||||
'get_dvr_permission')})
|
||||
def test_router_update_post_dvr_disabled(self):
|
||||
'get_feature_permission')})
|
||||
def test_router_update_post_dvr_ha_disabled(self):
|
||||
router = self.routers.first()
|
||||
api.neutron.get_dvr_permission(IsA(http.HttpRequest), "update")\
|
||||
api.neutron.get_feature_permission(IsA(http.HttpRequest),
|
||||
"dvr", "update")\
|
||||
.AndReturn(False)
|
||||
api.neutron.get_feature_permission(IsA(http.HttpRequest),
|
||||
"l3-ha", "update")\
|
||||
.AndReturn(False)
|
||||
api.neutron.router_update(IsA(http.HttpRequest), router.id,
|
||||
name=router.name,
|
||||
|
@ -300,15 +332,20 @@ class RouterActionTests(test.TestCase):
|
|||
|
||||
@test.create_stubs({api.neutron: ('router_get',
|
||||
'router_update',
|
||||
'get_dvr_permission')})
|
||||
def test_router_update_post_dvr_enabled(self):
|
||||
'get_feature_permission')})
|
||||
def test_router_update_post_dvr_ha_enabled(self):
|
||||
router = self.routers.first()
|
||||
api.neutron.get_dvr_permission(IsA(http.HttpRequest), "update")\
|
||||
api.neutron.get_feature_permission(IsA(http.HttpRequest),
|
||||
"dvr", "update")\
|
||||
.AndReturn(True)
|
||||
api.neutron.get_feature_permission(IsA(http.HttpRequest),
|
||||
"l3-ha", "update")\
|
||||
.AndReturn(True)
|
||||
api.neutron.router_update(IsA(http.HttpRequest), router.id,
|
||||
name=router.name,
|
||||
admin_state_up=router.admin_state_up,
|
||||
distributed=True)\
|
||||
distributed=True,
|
||||
ha=True)\
|
||||
.AndReturn(router)
|
||||
api.neutron.router_get(IsA(http.HttpRequest), router.id)\
|
||||
.AndReturn(router)
|
||||
|
@ -317,7 +354,8 @@ class RouterActionTests(test.TestCase):
|
|||
form_data = {'router_id': router.id,
|
||||
'name': router.name,
|
||||
'admin_state': router.admin_state_up,
|
||||
'mode': 'distributed'}
|
||||
'mode': 'distributed',
|
||||
'ha': True}
|
||||
url = reverse('horizon:%s:routers:update' % self.DASHBOARD,
|
||||
args=[router.id])
|
||||
res = self.client.post(url, form_data)
|
||||
|
|
|
@ -126,8 +126,10 @@ class DetailView(tabs.TabbedTableView):
|
|||
def get_context_data(self, **kwargs):
|
||||
context = super(DetailView, self).get_context_data(**kwargs)
|
||||
context["router"] = self._get_data()
|
||||
context['dvr_supported'] = api.neutron.get_dvr_permission(self.request,
|
||||
"get")
|
||||
context['dvr_supported'] = api.neutron.get_feature_permission(
|
||||
self.request, "dvr", "get")
|
||||
context['ha_supported'] = api.neutron.get_feature_permission(
|
||||
self.request, "l3-ha", "get")
|
||||
return context
|
||||
|
||||
def get(self, request, *args, **kwargs):
|
||||
|
@ -170,4 +172,6 @@ class UpdateView(forms.ModalFormView):
|
|||
if hasattr(router, 'distributed'):
|
||||
initial['mode'] = ('distributed' if router.distributed
|
||||
else 'centralized')
|
||||
if hasattr(router, 'ha'):
|
||||
initial['ha'] = router.ha
|
||||
return initial
|
||||
|
|
|
@ -182,7 +182,8 @@ OPENSTACK_NEUTRON_NETWORK = {
|
|||
'enable_router': True,
|
||||
'enable_quotas': True,
|
||||
'enable_ipv6': True,
|
||||
'enable_distributed_router': True,
|
||||
'enable_distributed_router': False,
|
||||
'enable_ha_router': False,
|
||||
'enable_lb': True,
|
||||
'enable_firewall': True,
|
||||
'enable_vpn': True,
|
||||
|
|
|
@ -283,6 +283,11 @@ class NeutronApiTests(test.APITestCase):
|
|||
self.assertFalse(
|
||||
api.neutron.is_extension_supported(self.request, 'doesntexist'))
|
||||
|
||||
# NOTE(amotoki): "dvr" permission tests check most of
|
||||
# get_feature_permission features.
|
||||
# These tests are not specific to "dvr" extension.
|
||||
# Please be careful if you drop "dvr" extension in future.
|
||||
|
||||
@override_settings(OPENSTACK_NEUTRON_NETWORK={'enable_distributed_router':
|
||||
True},
|
||||
POLICY_CHECK_FUNCTION=None)
|
||||
|
@ -295,10 +300,11 @@ class NeutronApiTests(test.APITestCase):
|
|||
.AndReturn({'extensions': extensions})
|
||||
self.mox.ReplayAll()
|
||||
self.assertEqual(dvr_enabled,
|
||||
api.neutron.get_dvr_permission(self.request, 'get'))
|
||||
api.neutron.get_feature_permission(self.request,
|
||||
'dvr', 'get'))
|
||||
|
||||
def test_get_dvr_permission_dvr_supported(self):
|
||||
self._test_get_dvr_permission_dvr_supported(dvr_enabled=True, )
|
||||
self._test_get_dvr_permission_dvr_supported(dvr_enabled=True)
|
||||
|
||||
def test_get_dvr_permission_dvr_not_supported(self):
|
||||
self._test_get_dvr_permission_dvr_supported(dvr_enabled=False)
|
||||
|
@ -320,8 +326,8 @@ class NeutronApiTests(test.APITestCase):
|
|||
.AndReturn({'extensions': self.api_extensions.list()})
|
||||
self.mox.ReplayAll()
|
||||
self.assertEqual(policy_check_allowed,
|
||||
api.neutron.get_dvr_permission(self.request,
|
||||
operation))
|
||||
api.neutron.get_feature_permission(self.request,
|
||||
'dvr', operation))
|
||||
|
||||
def test_get_dvr_permission_with_policy_check_allowed(self):
|
||||
self._test_get_dvr_permission_with_policy_check(True, "get")
|
||||
|
@ -338,11 +344,49 @@ class NeutronApiTests(test.APITestCase):
|
|||
@override_settings(OPENSTACK_NEUTRON_NETWORK={'enable_distributed_router':
|
||||
False})
|
||||
def test_get_dvr_permission_dvr_disabled_by_config(self):
|
||||
self.assertFalse(api.neutron.get_dvr_permission(self.request, 'get'))
|
||||
self.assertFalse(api.neutron.get_feature_permission(self.request,
|
||||
'dvr', 'get'))
|
||||
|
||||
@override_settings(OPENSTACK_NEUTRON_NETWORK={'enable_distributed_router':
|
||||
True})
|
||||
True},
|
||||
POLICY_CHECK_FUNCTION=policy.check)
|
||||
def test_get_dvr_permission_dvr_unsupported_operation(self):
|
||||
self.assertRaises(ValueError,
|
||||
api.neutron.get_dvr_permission,
|
||||
self.request, 'unSupported')
|
||||
api.neutron.get_feature_permission,
|
||||
self.request, 'dvr', 'unSupported')
|
||||
|
||||
@override_settings(OPENSTACK_NEUTRON_NETWORK={})
|
||||
def test_get_dvr_permission_dvr_default_config(self):
|
||||
self.assertFalse(api.neutron.get_feature_permission(self.request,
|
||||
'dvr', 'get'))
|
||||
|
||||
@override_settings(OPENSTACK_NEUTRON_NETWORK={})
|
||||
def test_get_dvr_permission_router_ha_default_config(self):
|
||||
self.assertFalse(api.neutron.get_feature_permission(self.request,
|
||||
'l3-ha', 'get'))
|
||||
|
||||
# NOTE(amotoki): Most of get_feature_permission are checked by "dvr" check
|
||||
# above. l3-ha check only checks l3-ha specific code.
|
||||
|
||||
@override_settings(OPENSTACK_NEUTRON_NETWORK={'enable_ha_router': True},
|
||||
POLICY_CHECK_FUNCTION=policy.check)
|
||||
def _test_get_router_ha_permission_with_policy_check(self, ha_enabled):
|
||||
self.mox.StubOutWithMock(policy, 'check')
|
||||
role = (("network", "create_router:ha"),)
|
||||
policy.check(role, self.request).AndReturn(True)
|
||||
neutronclient = self.stub_neutronclient()
|
||||
if ha_enabled:
|
||||
extensions = self.api_extensions.list()
|
||||
else:
|
||||
extensions = {}
|
||||
neutronclient.list_extensions().AndReturn({'extensions': extensions})
|
||||
self.mox.ReplayAll()
|
||||
self.assertEqual(ha_enabled,
|
||||
api.neutron.get_feature_permission(self.request,
|
||||
'l3-ha', 'create'))
|
||||
|
||||
def test_get_router_ha_permission_with_l3_ha_extension(self):
|
||||
self._test_get_router_ha_permission_with_policy_check(True)
|
||||
|
||||
def test_get_router_ha_permission_without_l3_ha_extension(self):
|
||||
self._test_get_router_ha_permission_with_policy_check(False)
|
||||
|
|
|
@ -646,10 +646,14 @@ def data(TEST):
|
|||
"alias": "dvr",
|
||||
"description":
|
||||
"Enables configuration of Distributed Virtual Routers."}
|
||||
extension_5 = {"name": "HA Router extension",
|
||||
"alias": "l3-ha",
|
||||
"description": "Add HA capability to routers."}
|
||||
TEST.api_extensions.add(extension_1)
|
||||
TEST.api_extensions.add(extension_2)
|
||||
TEST.api_extensions.add(extension_3)
|
||||
TEST.api_extensions.add(extension_4)
|
||||
TEST.api_extensions.add(extension_5)
|
||||
|
||||
# 1st agent.
|
||||
agent_dict = {"binary": "neutron-openvswitch-agent",
|
||||
|
|
Loading…
Reference in New Issue