diff options
author | Sawyer Bergeron <sbergeron@iol.unh.edu> | 2021-09-25 16:18:12 -0400 |
---|---|---|
committer | Sawyer Bergeron <sbergeron@iol.unh.edu> | 2021-09-25 16:29:13 -0400 |
commit | 95d39c60f7e8062cabc8c1665080a2d2c8904234 (patch) | |
tree | 786fbe0ba896b28135706c417ebfac176ea67a45 /src | |
parent | 2ebb82b5f344de1e17abd70c51c4cce765761dd1 (diff) |
Allow for "pod specific" vlan allocation for LFEDGE allocation case
Signed-off-by: Sawyer Bergeron <sbergeron@iol.unh.edu>
Change-Id: I8b75410145027f43eaf6de7bd5f1813af38d3e7f
Signed-off-by: Sawyer Bergeron <sbergeron@iol.unh.edu>
Diffstat (limited to 'src')
-rw-r--r-- | src/account/models.py | 23 | ||||
-rw-r--r-- | src/resource_inventory/migrations/0022_auto_20210925_2028.py | 23 | ||||
-rw-r--r-- | src/resource_inventory/models.py | 18 | ||||
-rw-r--r-- | src/resource_inventory/resource_manager.py | 5 |
4 files changed, 62 insertions, 7 deletions
diff --git a/src/account/models.py b/src/account/models.py index b71f0ac..2501be6 100644 --- a/src/account/models.py +++ b/src/account/models.py @@ -82,12 +82,14 @@ class VlanManager(models.Model): # if they use QinQ or a vxlan overlay, for example allow_overlapping = models.BooleanField() - def get_vlans(self, count=1): + def get_vlans(self, count=1, within=None): """ Return the IDs of available vlans as a list[int], but does not reserve them. Will throw index exception if not enough vlans are available. Always returns a list of ints + + If `within` is not none, will filter against that as a set, requiring that any vlans returned are within that set """ allocated = [] vlans = json.loads(self.vlans) @@ -104,17 +106,28 @@ class VlanManager(models.Model): continue # vlan is available and not reserved, so safe to add - allocated.append(i) + if within is not None: + if i in within: + allocated.append(i) + else: + allocated.append(i) continue if len(allocated) != count: - raise ResourceAvailabilityException("can't allocate the vlans requested") + raise ResourceAvailabilityException("There were not enough available private vlans for the allocation. Please contact the administrators.") return allocated - def get_public_vlan(self): + def get_public_vlan(self, within=None): """Return reference to an available public network without reserving it.""" - return PublicNetwork.objects.filter(lab=self.lab_set.first(), in_use=False).first() + r = PublicNetwork.objects.filter(lab=self.lab_set.first(), in_use=False) + if within is not None: + r = r.filter(vlan__in=within) + + if r.count() < 1: + raise ResourceAvailabilityException("There were not enough available public vlans for the allocation. Please contact the administrators.") + + return r.first() def reserve_public_vlan(self, vlan): """Reserves the Public Network that has the given vlan.""" diff --git a/src/resource_inventory/migrations/0022_auto_20210925_2028.py b/src/resource_inventory/migrations/0022_auto_20210925_2028.py new file mode 100644 index 0000000..2b0b902 --- /dev/null +++ b/src/resource_inventory/migrations/0022_auto_20210925_2028.py @@ -0,0 +1,23 @@ +# Generated by Django 2.2 on 2021-09-25 20:28 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('resource_inventory', '0021_resourceconfiguration_cloud_init_files'), + ] + + operations = [ + migrations.AddField( + model_name='resourcetemplate', + name='private_vlan_pool', + field=models.TextField(default=''), + ), + migrations.AddField( + model_name='resourcetemplate', + name='public_vlan_pool', + field=models.TextField(default=''), + ), + ] diff --git a/src/resource_inventory/models.py b/src/resource_inventory/models.py index 2c631dc..1505f02 100644 --- a/src/resource_inventory/models.py +++ b/src/resource_inventory/models.py @@ -193,6 +193,24 @@ class ResourceTemplate(models.Model): temporary = models.BooleanField(default=False) copy_of = models.ForeignKey("ResourceTemplate", blank=True, null=True, on_delete=models.SET_NULL) + # if these fields are empty ("") then they are implicitly "every vlan", + # otherwise we filter any allocations we try to instantiate against this list + # they should be represented as a json list of integers + private_vlan_pool = models.TextField(default="") + public_vlan_pool = models.TextField(default="") + + def private_vlan_pool_set(self): + if self.private_vlan_pool != "": + return set(json.loads(self.private_vlan_pool)) + else: + return None + + def public_vlan_pool_set(self): + if self.private_vlan_pool != "": + return set(json.loads(self.public_vlan_pool)) + else: + return None + def getConfigs(self): configs = self.resourceConfigurations.all() return list(configs) diff --git a/src/resource_inventory/resource_manager.py b/src/resource_inventory/resource_manager.py index 9406977..14a118c 100644 --- a/src/resource_inventory/resource_manager.py +++ b/src/resource_inventory/resource_manager.py @@ -74,12 +74,13 @@ class ResourceManager: vlan_manager = resourceTemplate.lab.vlan_manager for network in resourceTemplate.networks.all(): if network.is_public: - public_net = vlan_manager.get_public_vlan() + # already throws if can't get requested count, so can always expect public_net to be Some + public_net = vlan_manager.get_public_vlan(within=resourceTemplate.public_vlan_pool_set()) vlan_manager.reserve_public_vlan(public_net.vlan) networks[network.name] = public_net.vlan else: # already throws if can't get requested count, so can always index in @ 0 - vlans = vlan_manager.get_vlans(count=1) + vlans = vlan_manager.get_vlans(count=1, within=resourceTemplate.private_vlan_pool_set()) vlan_manager.reserve_vlans(vlans[0]) networks[network.name] = vlans[0] return networks |