diff --git a/openstack_dashboard/dashboards/router/nexus1000v/forms.py b/openstack_dashboard/dashboards/router/nexus1000v/forms.py
index 212edf7c56..7f60087d1e 100644
--- a/openstack_dashboard/dashboards/router/nexus1000v/forms.py
+++ b/openstack_dashboard/dashboards/router/nexus1000v/forms.py
@@ -53,14 +53,16 @@ class CreateNetworkProfile(forms.SelfHandlingForm):
required=True)
segment_type = forms.ChoiceField(label=_('Segment Type'),
choices=[('vlan', _('VLAN')),
- ('overlay', _('OVERLAY'))],
+ ('overlay', _('Overlay')),
+ ('trunk', _('Trunk'))],
widget=forms.Select
(attrs={'class': 'switchable',
'data-slug': 'segtype'}))
+ # Sub type options available for Overlay segment type
sub_type = forms.ChoiceField(label=_('Sub Type'),
- choices=[('native_vxlan', _('NATIVE VXLAN')),
- ('enhanced', _('ENHANCED')),
- ('other', _('OTHER'))],
+ choices=[('native_vxlan', _('Native VXLAN')),
+ ('enhanced', _('Enhanced VXLAN')),
+ ('other', _('Other'))],
required=False,
widget=forms.Select
(attrs={'class': 'switchable switched',
@@ -68,9 +70,24 @@ class CreateNetworkProfile(forms.SelfHandlingForm):
'data-switch-on': 'segtype',
'data-segtype-overlay':
_("Sub Type")}))
+ # Sub type options available for Trunk segment type
+ sub_type_trunk = forms.ChoiceField(label=_('Sub Type'),
+ choices=[('vlan', _('VLAN'))],
+ required=False,
+ widget=forms.Select
+ (attrs={'class': 'switched',
+ 'data-switch-on': 'segtype',
+ 'data-segtype-trunk': _("Sub Type")}))
segment_range = forms.CharField(max_length=255,
label=_("Segment Range"),
- required=True,
+ required=False,
+ widget=forms.TextInput
+ (attrs={'class': 'switched',
+ 'data-switch-on': 'segtype',
+ 'data-segtype-vlan':
+ _("Segment Range"),
+ 'data-segtype-overlay':
+ _("Segment Range")}),
help_text=_("1-4093 for VLAN; "
"5000-10000 for Overlay"))
multicast_ip_range = forms.CharField(max_length=30,
@@ -83,8 +100,8 @@ class CreateNetworkProfile(forms.SelfHandlingForm):
'data-subtype-native_vxlan':
_("Multicast IP Range")}),
help_text=_("Multicast IPv4 range"
- "(e.g. 132.0.0.0-"
- "132.0.0.100)"))
+ "(e.g. 224.0.0.0-"
+ "224.0.0.100)"))
other_subtype = forms.CharField(max_length=255,
label=_("Sub Type Value (Manual Input)"),
required=False,
@@ -112,7 +129,8 @@ class CreateNetworkProfile(forms.SelfHandlingForm):
self.fields['project'].choices = get_tenant_choices(request)
def clean(self):
- # If sub_type is 'other' then assign this new value for sub_type
+ # If sub_type is 'other' or 'trunk' then
+ # assign this new value for sub_type
cleaned_data = super(CreateNetworkProfile, self).clean()
segment_type = cleaned_data.get('segment_type')
@@ -123,6 +141,11 @@ class CreateNetworkProfile(forms.SelfHandlingForm):
cleaned_data['sub_type'] = other_subtype
LOG.debug('subtype is now %(params)s',
{'params': other_subtype})
+ elif segment_type == 'trunk':
+ sub_type_trunk = cleaned_data.get('sub_type_trunk')
+ cleaned_data['sub_type'] = sub_type_trunk
+ LOG.debug('subtype is now %(params)s',
+ {'params': sub_type_trunk})
return cleaned_data
diff --git a/openstack_dashboard/dashboards/router/nexus1000v/templates/nexus1000v/_create_network_profile.html b/openstack_dashboard/dashboards/router/nexus1000v/templates/nexus1000v/_create_network_profile.html
index 6a14cd566a..3af06ce110 100644
--- a/openstack_dashboard/dashboards/router/nexus1000v/templates/nexus1000v/_create_network_profile.html
+++ b/openstack_dashboard/dashboards/router/nexus1000v/templates/nexus1000v/_create_network_profile.html
@@ -17,9 +17,9 @@
{% trans "Description" %}:
{% trans "Name" %}: {% blocktrans %} Select a name for your network profile.{% endblocktrans %}
-
{% trans "Segment Type" %}: {% blocktrans %} Segment types available are VLAN and OVERLAY.{% endblocktrans %}
-
{% trans "Segment Sub Type" %}: {% blocktrans %} Sub types available are for the Overlay segment. Available sub-types for overlay are: native_vxlan, enhanced or 'other' (eg. GRE) which can be manually inputed as a text parameter for subtype.{% endblocktrans %}
-
{% trans "Segment Range" %}: {% blocktrans %} Segment Ranges are 1-4093 for VLAN and above 5000 for enhanced overlay.{% endblocktrans %}
+
{% trans "Segment Type" %}: {% blocktrans %} Segment types available are VLAN, Overlay and Trunk.{% endblocktrans %}
+
{% trans "Segment Sub Type" %}: {% blocktrans %} Sub types available are for the Overlay and Trunk segments. Available sub-types for Overlay are: Native-VXLAN, Enhanced-VXLAN or 'Other' (eg. GRE) which can be manually inputed as a text parameter for subtype. Available sub-type for Trunk is: VLAN.{% endblocktrans %}
+
{% trans "Segment Range" %}: {% blocktrans %} Segment Ranges are 1-4093 for VLAN and above 5000 for Enhanced-VXLAN Overlay.{% endblocktrans %}
{% endblock %}
diff --git a/openstack_dashboard/dashboards/router/nexus1000v/tests.py b/openstack_dashboard/dashboards/router/nexus1000v/tests.py
index 00de01b4bd..d957ae335c 100644
--- a/openstack_dashboard/dashboards/router/nexus1000v/tests.py
+++ b/openstack_dashboard/dashboards/router/nexus1000v/tests.py
@@ -133,3 +133,73 @@ if api.neutron.is_port_profiles_supported():
self.assertRedirectsNoFollow(res,
reverse
('horizon:router:nexus1000v:index'))
+
+ @test.create_stubs({api.neutron: ('profile_create',),
+ api.keystone: ('tenant_list',)})
+ def test_create_overlay_other_net_profile(self):
+ tenants = self.tenants.list()
+ net_profile = self.net_profiles.list()[2]
+ params = {'name': net_profile.name,
+ 'segment_type': net_profile.segment_type,
+ 'segment_range': net_profile.segment_range,
+ 'sub_type': net_profile.other_subtype,
+ 'tenant_id': net_profile.project,
+ # overlay 'other' profiles have no multicast_ip_range
+ # or physical_network type
+ 'multicast_ip_range': '',
+ 'physical_network': ''}
+
+ api.neutron.profile_create(IsA(http.HttpRequest),
+ **params).AndReturn(net_profile)
+ api.keystone.tenant_list(
+ IsA(http.HttpRequest)).AndReturn([tenants, False])
+ self.mox.ReplayAll()
+
+ form_data = {'name': net_profile.name,
+ 'segment_type': net_profile.segment_type,
+ 'segment_range': net_profile.segment_range,
+ 'sub_type': net_profile.sub_type,
+ 'other_subtype': net_profile.other_subtype,
+ 'project': net_profile.project}
+ form_data.update(form_data_overlay())
+ url = reverse('horizon:router:nexus1000v:create_network_profile')
+ res = self.client.post(url, form_data)
+
+ self.assertNoFormErrors(res)
+ self.assertRedirectsNoFollow(res,
+ reverse
+ ('horizon:router:nexus1000v:index'))
+
+ @test.create_stubs({api.neutron: ('profile_create',),
+ api.keystone: ('tenant_list',)})
+ def test_create_trunk_net_profile(self):
+ tenants = self.tenants.list()
+ net_profile = self.net_profiles.list()[3]
+ params = {'name': net_profile.name,
+ 'segment_type': net_profile.segment_type,
+ 'sub_type': net_profile.sub_type_trunk,
+ 'tenant_id': net_profile.project,
+ # trunk profiles have no multicast_ip_range,
+ # no segment_range or no physical_network type
+ 'multicast_ip_range': '',
+ 'segment_range': '',
+ 'physical_network': ''}
+
+ api.neutron.profile_create(IsA(http.HttpRequest),
+ **params).AndReturn(net_profile)
+ api.keystone.tenant_list(
+ IsA(http.HttpRequest)).AndReturn([tenants, False])
+ self.mox.ReplayAll()
+
+ form_data = {'name': net_profile.name,
+ 'segment_type': net_profile.segment_type,
+ 'sub_type_trunk': net_profile.sub_type_trunk,
+ 'project': net_profile.project}
+ form_data.update(form_data_no_overlay())
+ url = reverse('horizon:router:nexus1000v:create_network_profile')
+ res = self.client.post(url, form_data)
+
+ self.assertNoFormErrors(res)
+ self.assertRedirectsNoFollow(res,
+ reverse
+ ('horizon:router:nexus1000v:index'))
diff --git a/openstack_dashboard/test/test_data/neutron_data.py b/openstack_dashboard/test/test_data/neutron_data.py
index 6445833f73..e64af7862f 100644
--- a/openstack_dashboard/test/test_data/neutron_data.py
+++ b/openstack_dashboard/test/test_data/neutron_data.py
@@ -911,3 +911,47 @@ def data(TEST):
TEST.api_network_profile_binding.add(network_profile_binding_dict)
TEST.network_profile_binding.add(neutron.Profile(
network_profile_binding_dict))
+
+ # 3rd network profile for network when using the cisco n1k plugin
+ # Profile applied on 1st network
+ net_profile_dict = {'name': 'net_profile_test3',
+ 'segment_type': 'overlay',
+ 'sub_type': 'other',
+ 'other_subtype': 'GRE',
+ 'segment_range': '11000-11100',
+ 'id':
+ '00000000-3333-3333-3333-000000000000',
+ 'project': '1'}
+
+ TEST.api_net_profiles.add(net_profile_dict)
+ TEST.net_profiles.add(neutron.Profile(net_profile_dict))
+
+ # 3rd network profile binding
+ network_profile_binding_dict = {'profile_id':
+ '00000000-3333-3333-3333-000000000000',
+ 'tenant_id': '1'}
+
+ TEST.api_network_profile_binding.add(network_profile_binding_dict)
+ TEST.network_profile_binding.add(neutron.Profile(
+ network_profile_binding_dict))
+
+ # 4th network profile for network when using the cisco n1k plugin
+ # Profile applied on 1st network
+ net_profile_dict = {'name': 'net_profile_test4',
+ 'segment_type': 'trunk',
+ 'sub_type_trunk': 'vlan',
+ 'id':
+ '00000000-4444-4444-4444-000000000000',
+ 'project': '1'}
+
+ TEST.api_net_profiles.add(net_profile_dict)
+ TEST.net_profiles.add(neutron.Profile(net_profile_dict))
+
+ # 4th network profile binding
+ network_profile_binding_dict = {'profile_id':
+ '00000000-4444-4444-4444-000000000000',
+ 'tenant_id': '1'}
+
+ TEST.api_network_profile_binding.add(network_profile_binding_dict)
+ TEST.network_profile_binding.add(neutron.Profile(
+ network_profile_binding_dict))