Implements #777 Add Service Identifier field to VLAN, to store VXLAN or ISID.

This commit is contained in:
Douglas Heriot 2017-01-22 20:13:55 +11:00
parent 39d083eae7
commit e18c1752ac
9 changed files with 57 additions and 9 deletions

View File

@ -83,7 +83,7 @@ One IP address can be designated as the network address translation (NAT) IP add
# VLANs
A VLAN represents an isolated layer two domain, identified by a name and a numeric ID (1-4094). Note that while it is good practice, neither VLAN names nor IDs must be unique within a site. This is to accommodate the fact that many real-world network use less-than-optimal VLAN allocations and may have overlapping VLAN ID assignments in practice.
A VLAN represents an isolated layer two domain, identified by a name and a numeric ID (1-4094). Note that while it is good practice, neither VLAN names nor IDs must be unique within a site. This is to accommodate the fact that many real-world network use less-than-optimal VLAN allocations and may have overlapping VLAN ID assignments in practice. A "service identifier" (VXLAN or ISID, 1-16777215) can uniquely identify a VLAN where the ID is not unique.
Like prefixes, each VLAN is assigned an operational status and (optionally) a functional role.

View File

@ -72,9 +72,9 @@ class VLANGroupAdmin(admin.ModelAdmin):
@admin.register(VLAN)
class VLANAdmin(admin.ModelAdmin):
list_display = ['site', 'vid', 'name', 'tenant', 'status', 'role']
list_display = ['site', 'vid', 'name', 'tenant', 'status', 'role', 'service_identifier']
list_filter = ['site', 'tenant', 'status', 'role']
search_fields = ['vid', 'name']
search_fields = ['vid', 'name', 'service_identifier']
def get_queryset(self, request):
qs = super(VLANAdmin, self).get_queryset(request)

View File

@ -484,7 +484,7 @@ class VLANForm(BootstrapMixin, CustomFieldForm):
class Meta:
model = VLAN
fields = ['site', 'group', 'vid', 'name', 'tenant', 'status', 'role', 'description']
fields = ['site', 'group', 'vid', 'name', 'tenant', 'status', 'role', 'description', 'service_identifier']
help_texts = {
'site': "The site at which this VLAN exists",
'group': "VLAN group (optional)",
@ -492,6 +492,7 @@ class VLANForm(BootstrapMixin, CustomFieldForm):
'name': "Configured VLAN name",
'status': "Operational status of this VLAN",
'role': "The primary function of this VLAN",
'service_identifier': "Unique identifier: VXLAN or ISID",
}
widgets = {
'site': forms.Select(attrs={'filter-for': 'group'}),
@ -523,7 +524,7 @@ class VLANFromCSVForm(forms.ModelForm):
class Meta:
model = VLAN
fields = ['site', 'group', 'vid', 'name', 'tenant', 'status_name', 'role', 'description']
fields = ['site', 'group', 'vid', 'name', 'tenant', 'status_name', 'role', 'description', 'service_identifier']
def save(self, *args, **kwargs):
m = super(VLANFromCSVForm, self).save(commit=False)
@ -548,7 +549,7 @@ class VLANBulkEditForm(BootstrapMixin, CustomFieldBulkEditForm):
description = forms.CharField(max_length=100, required=False)
class Meta:
nullable_fields = ['group', 'tenant', 'role', 'description']
nullable_fields = ['group', 'tenant', 'role', 'description', 'service_identifier']
def vlan_status_choices():

View File

@ -0,0 +1,25 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.5 on 2017-01-22 08:29
from __future__ import unicode_literals
import django.core.validators
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('ipam', '0013_prefix_add_is_pool'),
]
operations = [
migrations.AlterModelOptions(
name='vlan',
options={'ordering': ['site', 'group', 'vid', 'service_identifier'], 'verbose_name': 'VLAN', 'verbose_name_plural': 'VLANs'},
),
migrations.AddField(
model_name='vlan',
name='service_identifier',
field=models.PositiveIntegerField(blank=True, default=None, null=True, validators=[django.core.validators.MinValueValidator(1), django.core.validators.MaxValueValidator(16777215)], verbose_name=b'Service Identifier'),
),
]

View File

@ -513,10 +513,14 @@ class VLAN(CreatedUpdatedModel, CustomFieldModel):
status = models.PositiveSmallIntegerField('Status', choices=VLAN_STATUS_CHOICES, default=1)
role = models.ForeignKey('Role', related_name='vlans', on_delete=models.SET_NULL, blank=True, null=True)
description = models.CharField(max_length=100, blank=True)
service_identifier = models.PositiveIntegerField(null=True, blank=True, default=None, verbose_name='Service Identifier', validators=[
MinValueValidator(1),
MaxValueValidator(16777215)
])
custom_field_values = GenericRelation(CustomFieldValue, content_type_field='obj_type', object_id_field='obj_id')
class Meta:
ordering = ['site', 'group', 'vid']
ordering = ['site', 'group', 'vid', 'service_identifier']
unique_together = [
['group', 'vid'],
['group', 'name'],
@ -548,6 +552,7 @@ class VLAN(CreatedUpdatedModel, CustomFieldModel):
self.get_status_display(),
self.role.name if self.role else None,
self.description,
self.service_identifier
])
@property

View File

@ -311,7 +311,8 @@ class VLANTable(BaseTable):
status = tables.TemplateColumn(STATUS_LABEL, verbose_name='Status')
role = tables.TemplateColumn(VLAN_ROLE_LINK, verbose_name='Role')
description = tables.Column(verbose_name='Description')
service_identifier = tables.Column(verbose_name='Service Identifier')
class Meta(BaseTable.Meta):
model = VLAN
fields = ('pk', 'vid', 'site', 'group', 'name', 'prefixes', 'tenant', 'status', 'role', 'description')
fields = ('pk', 'vid', 'site', 'group', 'name', 'prefixes', 'tenant', 'status', 'role', 'description', 'service_identifier')

View File

@ -108,6 +108,16 @@
<span class="text-muted">N/A</span>
{% endif %}
</td>
</tr>
<tr>
<td>Service Identifier</td>
<td>
{% if vlan.service_identifier %}
{{ vlan.service_identifier }}
{% else %}
<span class="text-muted">None</span>
{% endif %}
</td>
</tr>
</table>
</div>

View File

@ -13,6 +13,7 @@
{% render_field form.status %}
{% render_field form.role %}
{% render_field form.description %}
{% render_field form.service_identifier %}
</div>
</div>
{% if form.custom_fields %}

View File

@ -68,10 +68,15 @@
<td>Short description (optional)</td>
<td>Security team only</td>
</tr>
<tr>
<td>Service Identifier</td>
<td>VXLAN identifier or ISID</td>
<td>1001400</td>
</tr>
</tbody>
</table>
<h4>Example</h4>
<pre>LAS2,Backend Network,1400,Cameras,Internal,Active,Security,Security team only</pre>
<pre>LAS2,Backend Network,1400,Cameras,Internal,Active,Security,Security team only,1001400</pre>
</div>
</div>
{% endblock %}