Skip to content

Closes #84: Introduce the max_active_branches config parameter #100

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Sep 10, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
10 changes: 9 additions & 1 deletion docs/configuration.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,18 @@
# Configuration Parameters

## `max_active_branches`

Default: None

The maximum number of _active_ branches that can exist simultaneously. This count excludes branches which have been merged or archived.

---

## `max_branches`

Default: None

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.
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.

---

Expand Down
3 changes: 3 additions & 0 deletions netbox_branching/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ class AppConfig(PluginConfig):
'netbox_branching.middleware.BranchMiddleware'
]
default_settings = {
# The maximum number of active branches (excludes merged & archived branches)
'max_active_branches': None,

# The maximum number of branches which can be provisioned simultaneously
'max_branches': None,

Expand Down
8 changes: 7 additions & 1 deletion netbox_branching/choices.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,13 @@ class BranchStatusChoices(ChoiceSet):
PROVISIONING,
SYNCING,
MERGING,
REVERTING
REVERTING,
)

ACTIVE_STATUSES = (
NEW,
READY,
*TRANSITIONAL,
)


Expand Down
17 changes: 14 additions & 3 deletions netbox_branching/models/branches.py
Original file line number Diff line number Diff line change
Expand Up @@ -127,17 +127,28 @@ def synced_time(self):

def clean(self):

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

# Enforce the maximum number of active branches
if not self.pk and (max_active_branches := get_plugin_config('netbox_branching', 'max_active_branches')):
active_branch_count = Branch.objects.filter(status__in=BranchStatusChoices.ACTIVE_STATUSES).count()
if active_branch_count >= max_active_branches:
raise ValidationError(
_(
"The configured maximum number of active branches ({max}) cannot be exceeded. One or more "
"active branches must be archived or deleted before a new branch may be created."
).format(max=max_active_branches)
)

def save(self, provision=True, *args, **kwargs):
"""
Args:
Expand Down
25 changes: 25 additions & 0 deletions netbox_branching/tests/test_branches.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from django.db import connection
from django.test import TransactionTestCase, override_settings

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

@override_settings(PLUGINS_CONFIG={
'netbox_branching': {
'max_active_branches': 2,
}
})
def test_max_active_branches(self):
"""
Verify that the max_active_branches config parameter is enforced.
"""
Branch.objects.bulk_create((
Branch(name='Branch 1', status=BranchStatusChoices.MERGED),
Branch(name='Branch 2', status=BranchStatusChoices.READY),
))

# Second active branch should be permitted (merged branches don't count)
branch = Branch(name='Branch 3')
branch.full_clean()
branch.save()

# Attempting to create a third active branch should fail
branch = Branch(name='Branch 4')
with self.assertRaises(ValidationError):
branch.full_clean()

@override_settings(PLUGINS_CONFIG={
'netbox_branching': {
'max_branches': 2,
Expand Down