Skip to content

Commit efaa69e

Browse files
committed
Closes #84: Introduce the max_active_branches config parameter (#100)
* Closes #84: Introduce the max_active_branches parameter * Rename max_active_branches to max_working_branches * Update error message
1 parent a831df0 commit efaa69e

File tree

6 files changed

+59
-8
lines changed

6 files changed

+59
-8
lines changed

docs/configuration.md

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,18 @@
11
# Configuration Parameters
22

3+
## `max_working_branches`
4+
5+
Default: None
6+
7+
The maximum number of operational branches that can exist simultaneously. This count excludes branches which have been merged or archived.
8+
9+
---
10+
311
## `max_branches`
412

513
Default: None
614

7-
The maximum number of branches that can exist simultaneously, including merged branches that have not been deleted. It may be desirable to limit the total number of provisioned branches to safeguard against excessive database size.
15+
The maximum total number of branches that can exist simultaneously, including merged branches that have not been deleted. It may be desirable to limit the total number of provisioned branches to safeguard against excessive database size.
816

917
---
1018

netbox_branching/__init__.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ class AppConfig(PluginConfig):
1616
'netbox_branching.middleware.BranchMiddleware'
1717
]
1818
default_settings = {
19+
# The maximum number of working branches (excludes merged & archived branches)
20+
'max_working_branches': None,
21+
1922
# The maximum number of branches which can be provisioned simultaneously
2023
'max_branches': None,
2124

netbox_branching/choices.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,13 @@ class BranchStatusChoices(ChoiceSet):
3030
PROVISIONING,
3131
SYNCING,
3232
MERGING,
33-
REVERTING
33+
REVERTING,
34+
)
35+
36+
WORKING = (
37+
NEW,
38+
READY,
39+
*TRANSITIONAL,
3440
)
3541

3642

netbox_branching/models/branches.py

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -127,17 +127,28 @@ def synced_time(self):
127127

128128
def clean(self):
129129

130-
# Check whether we're exceeding the maximum number of Branches
130+
# Enforce the maximum number of total branches
131131
if not self.pk and (max_branches := get_plugin_config('netbox_branching', 'max_branches')):
132-
branch_count = Branch.objects.count()
133-
if branch_count >= max_branches:
132+
total_branch_count = Branch.objects.count()
133+
if total_branch_count >= max_branches:
134134
raise ValidationError(
135135
_(
136136
"The configured maximum number of branches ({max}) cannot be exceeded. One or more existing "
137137
"branches must be deleted before a new branch may be created."
138138
).format(max=max_branches)
139139
)
140140

141+
# Enforce the maximum number of active branches
142+
if not self.pk and (max_working_branches := get_plugin_config('netbox_branching', 'max_working_branches')):
143+
working_branch_count = Branch.objects.filter(status__in=BranchStatusChoices.WORKING).count()
144+
if working_branch_count >= max_working_branches:
145+
raise ValidationError(
146+
_(
147+
"The configured maximum number of working branches ({max}) cannot be exceeded. One or more "
148+
"working branches must be merged or archived before a new branch may be created."
149+
).format(max=max_working_branches)
150+
)
151+
141152
def save(self, provision=True, *args, **kwargs):
142153
"""
143154
Args:

netbox_branching/template_content.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,7 @@ class BranchSelector(PluginTemplateExtension):
1717
def navbar(self):
1818
return self.render('netbox_branching/inc/branch_selector.html', extra_context={
1919
'active_branch': active_branch.get(),
20-
'branches': Branch.objects.exclude(
21-
status__in=[BranchStatusChoices.MERGED, BranchStatusChoices.ARCHIVED]
22-
),
20+
'branches': Branch.objects.filter(status__in=BranchStatusChoices.WORKING),
2321
})
2422

2523

netbox_branching/tests/test_branches.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
from django.db import connection
55
from django.test import TransactionTestCase, override_settings
66

7+
from netbox_branching.choices import BranchStatusChoices
78
from netbox_branching.constants import MAIN_SCHEMA
89
from netbox_branching.models import Branch
910
from netbox_branching.utilities import get_tables_to_replicate
@@ -77,6 +78,30 @@ def test_branch_schema_id(self):
7778
branch.refresh_from_db()
7879
self.assertEqual(branch.schema_id, schema_id, msg="Schema ID was changed during save()")
7980

81+
@override_settings(PLUGINS_CONFIG={
82+
'netbox_branching': {
83+
'max_working_branches': 2,
84+
}
85+
})
86+
def test_max_working_branches(self):
87+
"""
88+
Verify that the max_working_branches config parameter is enforced.
89+
"""
90+
Branch.objects.bulk_create((
91+
Branch(name='Branch 1', status=BranchStatusChoices.MERGED),
92+
Branch(name='Branch 2', status=BranchStatusChoices.READY),
93+
))
94+
95+
# Second active branch should be permitted (merged branches don't count)
96+
branch = Branch(name='Branch 3')
97+
branch.full_clean()
98+
branch.save()
99+
100+
# Attempting to create a third active branch should fail
101+
branch = Branch(name='Branch 4')
102+
with self.assertRaises(ValidationError):
103+
branch.full_clean()
104+
80105
@override_settings(PLUGINS_CONFIG={
81106
'netbox_branching': {
82107
'max_branches': 2,

0 commit comments

Comments
 (0)