mirror of
https://github.com/netbox-community/netbox.git
synced 2025-07-14 09:51:22 -06:00
Closes #2805: Allow null route distinguisher for VRFs
This commit is contained in:
parent
613e8f05c2
commit
bcfa760cf9
@ -2,6 +2,7 @@ v2.5.5 (FUTURE)
|
|||||||
|
|
||||||
## Enhancements
|
## Enhancements
|
||||||
|
|
||||||
|
* [#2805](https://github.com/digitalocean/netbox/issues/2805) - Allow null route distinguisher for VRFs
|
||||||
* [#2809](https://github.com/digitalocean/netbox/issues/2809) - Remove VRF child prefixes table; link to main prefixes view
|
* [#2809](https://github.com/digitalocean/netbox/issues/2809) - Remove VRF child prefixes table; link to main prefixes view
|
||||||
* [#2825](https://github.com/digitalocean/netbox/issues/2825) - Include directly connected device for front/rear ports
|
* [#2825](https://github.com/digitalocean/netbox/issues/2825) - Include directly connected device for front/rear ports
|
||||||
|
|
||||||
|
@ -83,7 +83,7 @@ An IP address can be designated as the network address translation (NAT) inside
|
|||||||
|
|
||||||
A VRF object in NetBox represents a virtual routing and forwarding (VRF) domain. Each VRF is essentially a separate routing table. VRFs are commonly used to isolate customers or organizations from one another within a network, or to route overlapping address space (e.g. multiple instances of the 10.0.0.0/8 space).
|
A VRF object in NetBox represents a virtual routing and forwarding (VRF) domain. Each VRF is essentially a separate routing table. VRFs are commonly used to isolate customers or organizations from one another within a network, or to route overlapping address space (e.g. multiple instances of the 10.0.0.0/8 space).
|
||||||
|
|
||||||
Each VRF is assigned a unique name and route distinguisher (RD). The RD is expected to take one of the forms prescribed in [RFC 4364](https://tools.ietf.org/html/rfc4364#section-4.2), however its formatting is not strictly enforced.
|
Each VRF is assigned a unique name and an optional route distinguisher (RD). The RD is expected to take one of the forms prescribed in [RFC 4364](https://tools.ietf.org/html/rfc4364#section-4.2), however its formatting is not strictly enforced.
|
||||||
|
|
||||||
Each prefix and IP address may be assigned to one (and only one) VRF. If you have a prefix or IP address which exists in multiple VRFs, you will need to create a separate instance of it in NetBox for each VRF. Any IP prefix or address not assigned to a VRF is said to belong to the "global" table.
|
Each prefix and IP address may be assigned to one (and only one) VRF. If you have a prefix or IP address which exists in multiple VRFs, you will need to create a separate instance of it in NetBox for each VRF. Any IP prefix or address not assigned to a VRF is said to belong to the "global" table.
|
||||||
|
|
||||||
|
18
netbox/ipam/migrations/0024_vrf_allow_null_rd.py
Normal file
18
netbox/ipam/migrations/0024_vrf_allow_null_rd.py
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
# Generated by Django 2.1.5 on 2019-01-31 18:14
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('ipam', '0023_change_logging'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='vrf',
|
||||||
|
name='rd',
|
||||||
|
field=models.CharField(blank=True, max_length=21, null=True, unique=True),
|
||||||
|
),
|
||||||
|
]
|
@ -29,6 +29,8 @@ class VRF(ChangeLoggedModel, CustomFieldModel):
|
|||||||
rd = models.CharField(
|
rd = models.CharField(
|
||||||
max_length=21,
|
max_length=21,
|
||||||
unique=True,
|
unique=True,
|
||||||
|
blank=True,
|
||||||
|
null=True,
|
||||||
verbose_name='Route distinguisher'
|
verbose_name='Route distinguisher'
|
||||||
)
|
)
|
||||||
tenant = models.ForeignKey(
|
tenant = models.ForeignKey(
|
||||||
|
@ -16,7 +16,7 @@ class VRFTest(APITestCase):
|
|||||||
|
|
||||||
self.vrf1 = VRF.objects.create(name='Test VRF 1', rd='65000:1')
|
self.vrf1 = VRF.objects.create(name='Test VRF 1', rd='65000:1')
|
||||||
self.vrf2 = VRF.objects.create(name='Test VRF 2', rd='65000:2')
|
self.vrf2 = VRF.objects.create(name='Test VRF 2', rd='65000:2')
|
||||||
self.vrf3 = VRF.objects.create(name='Test VRF 3', rd='65000:3')
|
self.vrf3 = VRF.objects.create(name='Test VRF 3') # No RD
|
||||||
|
|
||||||
def test_get_vrf(self):
|
def test_get_vrf(self):
|
||||||
|
|
||||||
@ -44,19 +44,26 @@ class VRFTest(APITestCase):
|
|||||||
|
|
||||||
def test_create_vrf(self):
|
def test_create_vrf(self):
|
||||||
|
|
||||||
data = {
|
data_list = [
|
||||||
|
# VRF with RD
|
||||||
|
{
|
||||||
'name': 'Test VRF 4',
|
'name': 'Test VRF 4',
|
||||||
'rd': '65000:4',
|
'rd': '65000:4',
|
||||||
|
},
|
||||||
|
# VRF without RD
|
||||||
|
{
|
||||||
|
'name': 'Test VRF 5',
|
||||||
}
|
}
|
||||||
|
]
|
||||||
|
|
||||||
url = reverse('ipam-api:vrf-list')
|
url = reverse('ipam-api:vrf-list')
|
||||||
response = self.client.post(url, data, format='json', **self.header)
|
|
||||||
|
|
||||||
|
for data in data_list:
|
||||||
|
response = self.client.post(url, data, format='json', **self.header)
|
||||||
self.assertHttpStatus(response, status.HTTP_201_CREATED)
|
self.assertHttpStatus(response, status.HTTP_201_CREATED)
|
||||||
self.assertEqual(VRF.objects.count(), 4)
|
vrf = VRF.objects.get(pk=response.data['id'])
|
||||||
vrf4 = VRF.objects.get(pk=response.data['id'])
|
self.assertEqual(vrf.name, data['name'])
|
||||||
self.assertEqual(vrf4.name, data['name'])
|
self.assertEqual(vrf.rd, data['rd'] if 'rd' in data else None)
|
||||||
self.assertEqual(vrf4.rd, data['rd'])
|
|
||||||
|
|
||||||
def test_create_vrf_bulk(self):
|
def test_create_vrf_bulk(self):
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user