Allow regular users to specify VNIC type for port
VNIC type needs to be specified when creating a server with an SR-IOV port. In this case, a user first creates a port with vnic_type=direct and creates a server with the created port. To allow this scenario, horizon needs to allow users to specify VNIC type for port. This commit also clean up the code duplication on the port security and mac state fields in the port create form. The code in the admin form for them are completely duplicated with that in the project form. Change-Id: Ib6e91ed7f720e2720994025429da0dcef2fa4e25 Closes-Bug: #1402959
This commit is contained in:
parent
98d0714939
commit
09efe2d432
|
@ -14,7 +14,6 @@
|
|||
|
||||
import logging
|
||||
|
||||
from django.conf import settings
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
|
@ -39,56 +38,6 @@ class CreatePort(project_forms.CreatePort):
|
|||
required=False)
|
||||
failure_url = 'horizon:admin:networks:detail'
|
||||
|
||||
def __init__(self, request, *args, **kwargs):
|
||||
super(CreatePort, self).__init__(request, *args, **kwargs)
|
||||
|
||||
try:
|
||||
if api.neutron.is_extension_supported(request, 'binding'):
|
||||
neutron_settings = getattr(settings,
|
||||
'OPENSTACK_NEUTRON_NETWORK', {})
|
||||
supported_vnic_types = neutron_settings.get(
|
||||
'supported_vnic_types', ['*'])
|
||||
if supported_vnic_types:
|
||||
if supported_vnic_types == ['*']:
|
||||
vnic_type_choices = api.neutron.VNIC_TYPES
|
||||
else:
|
||||
vnic_type_choices = [
|
||||
vnic_type for vnic_type in api.neutron.VNIC_TYPES
|
||||
if vnic_type[0] in supported_vnic_types
|
||||
]
|
||||
|
||||
self.fields['binding__vnic_type'] = \
|
||||
forms.ThemableChoiceField(
|
||||
choices=vnic_type_choices,
|
||||
label=_("Binding: VNIC Type"),
|
||||
help_text=_(
|
||||
"The VNIC type that is bound to the neutron "
|
||||
"port"),
|
||||
required=False)
|
||||
except Exception:
|
||||
msg = _("Unable to verify the VNIC types extension in Neutron")
|
||||
exceptions.handle(self.request, msg)
|
||||
|
||||
try:
|
||||
if api.neutron.is_extension_supported(request, 'mac-learning'):
|
||||
self.fields['mac_state'] = forms.BooleanField(
|
||||
label=_("MAC Learning State"), initial=False,
|
||||
required=False)
|
||||
except Exception:
|
||||
msg = _("Unable to retrieve MAC learning state")
|
||||
exceptions.handle(self.request, msg)
|
||||
|
||||
try:
|
||||
if api.neutron.is_extension_supported(request, 'port-security'):
|
||||
self.fields['port_security_enabled'] = forms.BooleanField(
|
||||
label=_("Port Security"),
|
||||
help_text=_("Enable anti-spoofing rules for the port"),
|
||||
initial=True,
|
||||
required=False)
|
||||
except Exception:
|
||||
msg = _("Unable to retrieve port security state")
|
||||
exceptions.handle(self.request, msg)
|
||||
|
||||
def handle(self, request, data):
|
||||
network_id = self.initial['network_id']
|
||||
try:
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
|
||||
import logging
|
||||
|
||||
from django.conf import settings
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
|
@ -76,6 +77,19 @@ class CreatePort(forms.SelfHandlingForm):
|
|||
label=_("MAC Address"),
|
||||
required=False,
|
||||
help_text=_("Specify the MAC address for the new port"))
|
||||
mac_state = forms.BooleanField(
|
||||
label=_("MAC Learning State"), initial=False,
|
||||
required=False)
|
||||
port_security_enabled = forms.BooleanField(
|
||||
label=_("Port Security"),
|
||||
help_text=_("Enable anti-spoofing rules for the port"),
|
||||
initial=True,
|
||||
required=False)
|
||||
binding__vnic_type = forms.ThemableChoiceField(
|
||||
label=_("VNIC Type"),
|
||||
help_text=_("The VNIC type that is bound to the network port"),
|
||||
required=False)
|
||||
|
||||
failure_url = 'horizon:project:networks:detail'
|
||||
|
||||
def __init__(self, request, *args, **kwargs):
|
||||
|
@ -91,20 +105,51 @@ class CreatePort(forms.SelfHandlingForm):
|
|||
self.fields['subnet_id'].widget = forms.HiddenInput()
|
||||
self.fields['fixed_ip'].widget = forms.HiddenInput()
|
||||
|
||||
if api.neutron.is_extension_supported(request, 'mac-learning'):
|
||||
self.fields['mac_state'] = forms.BooleanField(
|
||||
label=_("MAC Learning State"), initial=False, required=False)
|
||||
self._hide_field_if_not_supported(
|
||||
request, 'mac_state', 'mac-learning',
|
||||
_("Unable to retrieve MAC learning state"))
|
||||
self._hide_field_if_not_supported(
|
||||
request, 'port_security_enabled', 'port-security',
|
||||
_("Unable to retrieve port security state"))
|
||||
|
||||
self._populate_vnic_type_choices(request)
|
||||
|
||||
def _hide_field_if_not_supported(self, request, field, extension_alias,
|
||||
failure_message):
|
||||
is_supproted = False
|
||||
try:
|
||||
if api.neutron.is_extension_supported(request, 'port-security'):
|
||||
self.fields['port_security_enabled'] = forms.BooleanField(
|
||||
label=_("Port Security"),
|
||||
help_text=_("Enable anti-spoofing rules for the port"),
|
||||
initial=True,
|
||||
required=False)
|
||||
is_supproted = api.neutron.is_extension_supported(
|
||||
request, extension_alias)
|
||||
except Exception:
|
||||
msg = _("Unable to retrieve port security state")
|
||||
exceptions.handle(self.request, msg)
|
||||
exceptions.handle(self.request, failure_message)
|
||||
if not is_supproted:
|
||||
del self.fields[field]
|
||||
return is_supproted
|
||||
|
||||
def _populate_vnic_type_choices(self, request):
|
||||
neutron_settings = getattr(settings, 'OPENSTACK_NEUTRON_NETWORK', {})
|
||||
supported_vnic_types = neutron_settings.get('supported_vnic_types',
|
||||
['*'])
|
||||
# When a list of VNIC types is empty, hide the corresponding field.
|
||||
if not supported_vnic_types:
|
||||
del self.fields['binding__vnic_type']
|
||||
return
|
||||
|
||||
binding_supported = self._hide_field_if_not_supported(
|
||||
request, 'binding__vnic_type', 'binding',
|
||||
_("Unable to verify the VNIC types extension in Neutron"))
|
||||
if not binding_supported:
|
||||
# binding__vnic_type field is already deleted, so return here
|
||||
return
|
||||
|
||||
if supported_vnic_types == ['*']:
|
||||
vnic_type_choices = api.neutron.VNIC_TYPES
|
||||
else:
|
||||
vnic_type_choices = [
|
||||
vnic_type for vnic_type in api.neutron.VNIC_TYPES
|
||||
if vnic_type[0] in supported_vnic_types
|
||||
]
|
||||
self.fields['binding__vnic_type'].choices = vnic_type_choices
|
||||
|
||||
def _get_subnet_choices(self, kwargs):
|
||||
try:
|
||||
|
|
Loading…
Reference in New Issue