Skip to content
Open
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 13 additions & 2 deletions openwisp_controller/subnet_division/base/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,12 @@ class AbstractSubnetDivisionRule(TimeStampedEditableModel, OrgMixin):
)
number_of_subnets = models.PositiveSmallIntegerField(
verbose_name=_("Number of Subnets"),
help_text=_("Indicates how many subnets will be created"),
validators=[MinValueValidator(1)],
help_text=_(
"Indicates how many subnets will be created. "
"Set to 0 to assign IP addresses directly "
"from the main subnet.
),
validators=[MinValueValidator(0)],
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Allowing 0 here still conflicts with non-zero subnet assumptions in validation.

Line [43] enables number_of_subnets=0, but current validators still enforce child-subnet assumptions (_validate_master_subnet_consistency and _validate_ip_address_consistency). This can reject valid zero-subnet scenarios or validate against the wrong target subnet size.

💡 Suggested alignment for zero-subnet mode
diff --git a/openwisp_controller/subnet_division/base/models.py b/openwisp_controller/subnet_division/base/models.py
@@
-        available = 2 ** (self.size - master_subnet.prefixlen)
-        # Account for the reserved subnet
-        available -= 1
-        if self.number_of_subnets >= available:
+        available = 2 ** (self.size - master_subnet.prefixlen)
+        # Account for the reserved subnet only when subnets are requested
+        available -= 1
+        if self.number_of_subnets > 0 and self.number_of_subnets >= available:
             raise ValidationError(
@@
     def _validate_ip_address_consistency(self):
         try:
-            next(
-                ip_network(str(self.master_subnet.subnet)).subnets(new_prefix=self.size)
-            )[self.number_of_ips - 1]
+            target_subnet = ip_network(str(self.master_subnet.subnet))
+            if self.number_of_subnets > 0:
+                target_subnet = next(target_subnet.subnets(new_prefix=self.size))
+            target_subnet[self.number_of_ips - 1]
         except IndexError:
             raise ValidationError(
                 {
                     "number_of_ips": _(
                         f"Generated subnets of size /{self.size} cannot accommodate "
                         f"{self.number_of_ips} IP Addresses."
                     )
                 }
             )
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@openwisp_controller/subnet_division/base/models.py` at line 43, The model
currently allows number_of_subnets=0 via validators=[MinValueValidator(0)] but
the validation methods _validate_master_subnet_consistency and
_validate_ip_address_consistency assume at least one subnet and therefore reject
or miscompute zero-subnet cases; fix by either tightening the field validator to
MinValueValidator(1) if zero should be disallowed, or (preferable for
zero-subnet support) keep MinValueValidator(0) and update
_validate_master_subnet_consistency and _validate_ip_address_consistency to
early-return (no-op) when self.number_of_subnets == 0 so they skip child-subnet
checks and avoid referencing a non-existent target subnet size.

)
Comment thread
coderabbitai[bot] marked this conversation as resolved.
size = models.PositiveSmallIntegerField(
verbose_name=_("Size of subnets"),
Expand Down Expand Up @@ -69,6 +73,13 @@ def rule_class(self):
return import_string(self.type)

def clean(self):
# Auto-fill organization from master subnet
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

Remove redundant inline comment in clean().

The comment at Line [76] repeats what the code already makes clear and can be dropped for cleaner readability.

As per coding guidelines, "Avoid unnecessary comments or docstrings for code that is already clear."

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@openwisp_controller/subnet_division/base/models.py` at line 76, Remove the
redundant inline comment inside the clean() method (the comment that states
"Auto-fill organization from master subnet") since it simply repeats what the
code does; delete that comment line from the clean() function in models.py and
leave the implementation unchanged to improve readability.

if (
self.master_subnet_id
and self.master_subnet.organization_id is not None
and not self.organization_id
):
self.organization_id = self.master_subnet.organization_id
super().clean()
self._validate_label()
self._validate_master_subnet_validity()
Expand Down
Loading