Compare commits

..

20 Commits

Author SHA1 Message Date
Idris Foughali
9af3ae092d Merge 93e5f919ba into 922b08c0ff 2025-12-02 08:13:00 +01:00
github-actions
922b08c0ff Update source translation strings
Some checks failed
CodeQL / Analyze (${{ matrix.language }}) (none, actions) (push) Has been cancelled
CodeQL / Analyze (${{ matrix.language }}) (none, javascript-typescript) (push) Has been cancelled
CodeQL / Analyze (${{ matrix.language }}) (none, python) (push) Has been cancelled
2025-12-02 05:02:22 +00:00
Bapths
84864fa5e1 Closes #20860: Add changlog message support for component object creation (#20898)
Some checks failed
CodeQL / Analyze (${{ matrix.language }}) (none, javascript-typescript) (push) Waiting to run
CodeQL / Analyze (${{ matrix.language }}) (none, python) (push) Waiting to run
CodeQL / Analyze (${{ matrix.language }}) (none, actions) (push) Waiting to run
CI / build (20.x, 3.10) (push) Has been cancelled
CI / build (20.x, 3.11) (push) Has been cancelled
CI / build (20.x, 3.12) (push) Has been cancelled
2025-12-01 17:04:21 -06:00
Jeremy Stretch
767dfccd8f Fixes #20888: Pass decimal values for min/max on latitude and longitude fields (#20892)
Some checks are pending
CI / build (20.x, 3.10) (push) Waiting to run
CI / build (20.x, 3.11) (push) Waiting to run
CI / build (20.x, 3.12) (push) Waiting to run
CodeQL / Analyze (${{ matrix.language }}) (none, actions) (push) Waiting to run
CodeQL / Analyze (${{ matrix.language }}) (none, javascript-typescript) (push) Waiting to run
CodeQL / Analyze (${{ matrix.language }}) (none, python) (push) Waiting to run
2025-12-01 10:35:44 -08:00
Idris Foughali
93e5f919ba Merge branch 'netbox-community:main' into closes-20817-Fix-datasource-sync-broken-when-cron-is-set 2025-12-01 10:07:15 +01:00
Tom Gamull
dc4bab7477 docs: fix broken bookmarks link in model features table
Some checks failed
CodeQL / Analyze (${{ matrix.language }}) (none, actions) (push) Has been cancelled
CodeQL / Analyze (${{ matrix.language }}) (none, javascript-typescript) (push) Has been cancelled
CodeQL / Analyze (${{ matrix.language }}) (none, python) (push) Has been cancelled
The bookmarks link was pointing to ../features/customization.md#bookmarks
but the bookmarks section is actually in ../features/user-preferences.md#bookmarks.

This fixes the broken anchor link.
2025-11-26 15:12:52 -05:00
ifoughali
929d024003 Merge branch 'closes-20817-Fix-datasource-sync-broken-when-cron-is-set' of https://github.com/ifoughal/netbox into closes-20817-Fix-datasource-sync-broken-when-cron-is-set 2025-11-26 09:00:22 +01:00
ifoughali
e4b614038e revert: re-added queued status set for datasource object 2025-11-26 09:00:17 +01:00
Idris Foughali
3016b1d90b Merge branch 'netbox-community:main' into closes-20817-Fix-datasource-sync-broken-when-cron-is-set 2025-11-26 08:55:12 +01:00
ifoughali
57b47dc1ea style: use != instead of not in for single SYNCING check 2025-11-26 08:05:20 +01:00
github-actions
60aa952eb1 Update source translation strings
Some checks are pending
CodeQL / Analyze (${{ matrix.language }}) (none, actions) (push) Waiting to run
CodeQL / Analyze (${{ matrix.language }}) (none, javascript-typescript) (push) Waiting to run
CodeQL / Analyze (${{ matrix.language }}) (none, python) (push) Waiting to run
2025-11-26 05:02:03 +00:00
ifoughali
da4c669312 Feat: reworked status update logic 2025-11-20 11:27:39 +01:00
ifoughali
71f707b7ac Feat: removed SCHEDULED choice due to redundency with sync interval 2025-11-20 11:26:43 +01:00
ifoughali
e11508dd6c Fix: removed status update from the enqueue method 2025-11-20 10:50:35 +01:00
ifoughali
5b5b5c8909 Revert "Feat: set status as editable field"
This reverts commit b4160ad59b.
2025-11-19 20:18:59 +01:00
Idris Foughali
a49869af42 Feat: removed QUEUED from ready for sync condition 2025-11-19 19:01:01 +00:00
Idris Foughali
2e0ff04f84 Feat: added 2 states for DataSourceStatusChoices 2025-11-19 18:52:27 +00:00
Idris Foughali
bfeba36514 Feat: added status update during save method of DataSourceForm 2025-11-19 18:51:25 +00:00
Idris Foughali
111aca115b Feat: added clean method to set data-source state to Ready or scheduled 2025-11-19 18:51:01 +00:00
Idris Foughali
b4160ad59b Feat: set status as editable field 2025-11-19 18:49:47 +00:00
9 changed files with 328 additions and 287 deletions

View File

@@ -12,7 +12,7 @@ Depending on its classification, each NetBox model may support various features
| Feature | Feature Mixin | Registry Key | Description | | Feature | Feature Mixin | Registry Key | Description |
|------------------------------------------------------------|-------------------------|---------------------|-----------------------------------------------------------------------------------------| |------------------------------------------------------------|-------------------------|---------------------|-----------------------------------------------------------------------------------------|
| [Bookmarks](../features/customization.md#bookmarks) | `BookmarksMixin` | `bookmarks` | These models can be bookmarked natively in the user interface | | [Bookmarks](../features/user-preferences.md#bookmarks) | `BookmarksMixin` | `bookmarks` | These models can be bookmarked natively in the user interface |
| [Change logging](../features/change-logging.md) | `ChangeLoggingMixin` | `change_logging` | Changes to these objects are automatically recorded in the change log | | [Change logging](../features/change-logging.md) | `ChangeLoggingMixin` | `change_logging` | Changes to these objects are automatically recorded in the change log |
| Cloning | `CloningMixin` | `cloning` | Provides the `clone()` method to prepare a copy | | Cloning | `CloningMixin` | `cloning` | Provides the `clone()` method to prepare a copy |
| [Contacts](../features/contacts.md) | `ContactsMixin` | `contacts` | Contacts can be associated with these models | | [Contacts](../features/contacts.md) | `ContactsMixin` | `contacts` | Contacts can be associated with these models |

View File

@@ -13,6 +13,7 @@ class DataSourceStatusChoices(ChoiceSet):
SYNCING = 'syncing' SYNCING = 'syncing'
COMPLETED = 'completed' COMPLETED = 'completed'
FAILED = 'failed' FAILED = 'failed'
READY = 'ready'
CHOICES = ( CHOICES = (
(NEW, _('New'), 'blue'), (NEW, _('New'), 'blue'),
@@ -20,6 +21,7 @@ class DataSourceStatusChoices(ChoiceSet):
(SYNCING, _('Syncing'), 'cyan'), (SYNCING, _('Syncing'), 'cyan'),
(COMPLETED, _('Completed'), 'green'), (COMPLETED, _('Completed'), 'green'),
(FAILED, _('Failed'), 'red'), (FAILED, _('Failed'), 'red'),
(READY, _('Ready'), 'green'),
) )

View File

@@ -16,6 +16,7 @@ from utilities.forms import get_field_value
from utilities.forms.fields import CommentField, JSONField from utilities.forms.fields import CommentField, JSONField
from utilities.forms.rendering import FieldSet from utilities.forms.rendering import FieldSet
from utilities.forms.widgets import HTMXSelect from utilities.forms.widgets import HTMXSelect
from core.choices import DataSourceStatusChoices
__all__ = ( __all__ = (
'ConfigRevisionForm', 'ConfigRevisionForm',
@@ -79,14 +80,24 @@ class DataSourceForm(NetBoxModelForm):
if self.instance and self.instance.parameters: if self.instance and self.instance.parameters:
self.fields[field_name].initial = self.instance.parameters.get(name) self.fields[field_name].initial = self.instance.parameters.get(name)
def save(self, *args, **kwargs): def clean(self):
super().clean()
if not self.instance.pk:
self.cleaned_data['status'] = DataSourceStatusChoices.NEW
else:
if not self.data.get('sync_interval'):
self.cleaned_data['status'] = DataSourceStatusChoices.READY
def save(self, *args, **kwargs):
parameters = {} parameters = {}
for name in self.fields: for name in self.fields:
if name.startswith('backend_'): if name.startswith('backend_'):
parameters[name[8:]] = self.cleaned_data[name] parameters[name[8:]] = self.cleaned_data[name]
self.instance.parameters = parameters self.instance.parameters = parameters
# update status
self.instance.status = self.cleaned_data.get('status', self.instance.status)
return super().save(*args, **kwargs) return super().save(*args, **kwargs)

View File

@@ -111,10 +111,7 @@ class DataSource(JobsMixin, PrimaryModel):
@property @property
def ready_for_sync(self): def ready_for_sync(self):
return self.enabled and self.status not in ( return self.enabled and self.status != DataSourceStatusChoices.SYNCING
DataSourceStatusChoices.QUEUED,
DataSourceStatusChoices.SYNCING
)
def clean(self): def clean(self):
super().clean() super().clean()

View File

@@ -1,3 +1,5 @@
import decimal
import django.core.validators import django.core.validators
from django.db import migrations, models from django.db import migrations, models
@@ -17,8 +19,8 @@ class Migration(migrations.Migration):
max_digits=8, max_digits=8,
null=True, null=True,
validators=[ validators=[
django.core.validators.MinValueValidator(-90.0), django.core.validators.MinValueValidator(decimal.Decimal('-90.0')),
django.core.validators.MaxValueValidator(90.0), django.core.validators.MaxValueValidator(decimal.Decimal('90.0'))
], ],
), ),
), ),
@@ -31,8 +33,8 @@ class Migration(migrations.Migration):
max_digits=9, max_digits=9,
null=True, null=True,
validators=[ validators=[
django.core.validators.MinValueValidator(-180.0), django.core.validators.MinValueValidator(decimal.Decimal('-180.0')),
django.core.validators.MaxValueValidator(180.0), django.core.validators.MaxValueValidator(decimal.Decimal('180.0'))
], ],
), ),
), ),
@@ -45,8 +47,8 @@ class Migration(migrations.Migration):
max_digits=8, max_digits=8,
null=True, null=True,
validators=[ validators=[
django.core.validators.MinValueValidator(-90.0), django.core.validators.MinValueValidator(decimal.Decimal('-90.0')),
django.core.validators.MaxValueValidator(90.0), django.core.validators.MaxValueValidator(decimal.Decimal('90.0'))
], ],
), ),
), ),
@@ -59,8 +61,8 @@ class Migration(migrations.Migration):
max_digits=9, max_digits=9,
null=True, null=True,
validators=[ validators=[
django.core.validators.MinValueValidator(-180.0), django.core.validators.MinValueValidator(decimal.Decimal('-180.0')),
django.core.validators.MaxValueValidator(180.0), django.core.validators.MaxValueValidator(decimal.Decimal('180.0'))
], ],
), ),
), ),

View File

@@ -646,7 +646,10 @@ class Device(
decimal_places=6, decimal_places=6,
blank=True, blank=True,
null=True, null=True,
validators=[MinValueValidator(-90.0), MaxValueValidator(90.0)], validators=[
MinValueValidator(decimal.Decimal('-90.0')),
MaxValueValidator(decimal.Decimal('90.0'))
],
help_text=_("GPS coordinate in decimal format (xx.yyyyyy)") help_text=_("GPS coordinate in decimal format (xx.yyyyyy)")
) )
longitude = models.DecimalField( longitude = models.DecimalField(
@@ -655,7 +658,10 @@ class Device(
decimal_places=6, decimal_places=6,
blank=True, blank=True,
null=True, null=True,
validators=[MinValueValidator(-180.0), MaxValueValidator(180.0)], validators=[
MinValueValidator(decimal.Decimal('-180.0')),
MaxValueValidator(decimal.Decimal('180.0'))
],
help_text=_("GPS coordinate in decimal format (xx.yyyyyy)") help_text=_("GPS coordinate in decimal format (xx.yyyyyy)")
) )
services = GenericRelation( services = GenericRelation(

View File

@@ -1,3 +1,5 @@
import decimal
from django.contrib.contenttypes.fields import GenericRelation from django.contrib.contenttypes.fields import GenericRelation
from django.core.exceptions import ValidationError from django.core.exceptions import ValidationError
from django.core.validators import MaxValueValidator, MinValueValidator from django.core.validators import MaxValueValidator, MinValueValidator
@@ -211,7 +213,10 @@ class Site(ContactsMixin, ImageAttachmentsMixin, PrimaryModel):
decimal_places=6, decimal_places=6,
blank=True, blank=True,
null=True, null=True,
validators=[MinValueValidator(-90.0), MaxValueValidator(90.0)], validators=[
MinValueValidator(decimal.Decimal('-90.0')),
MaxValueValidator(decimal.Decimal('90.0'))
],
help_text=_('GPS coordinate in decimal format (xx.yyyyyy)') help_text=_('GPS coordinate in decimal format (xx.yyyyyy)')
) )
longitude = models.DecimalField( longitude = models.DecimalField(
@@ -220,7 +225,10 @@ class Site(ContactsMixin, ImageAttachmentsMixin, PrimaryModel):
decimal_places=6, decimal_places=6,
blank=True, blank=True,
null=True, null=True,
validators=[MinValueValidator(-180.0), MaxValueValidator(180.0)], validators=[
MinValueValidator(decimal.Decimal('-180.0')),
MaxValueValidator(decimal.Decimal('180.0'))
],
help_text=_('GPS coordinate in decimal format (xx.yyyyyy)') help_text=_('GPS coordinate in decimal format (xx.yyyyyy)')
) )

View File

@@ -559,6 +559,7 @@ class ComponentCreateView(GetReturnURLMixin, BaseObjectView):
form.instance._replicated_base = hasattr(self.form, "replication_fields") form.instance._replicated_base = hasattr(self.form, "replication_fields")
if form.is_valid(): if form.is_valid():
changelog_message = form.cleaned_data.pop('changelog_message', '')
new_components = [] new_components = []
data = deepcopy(request.POST) data = deepcopy(request.POST)
pattern_count = len(form.cleaned_data[self.form.replication_fields[0]]) pattern_count = len(form.cleaned_data[self.form.replication_fields[0]])
@@ -585,6 +586,9 @@ class ComponentCreateView(GetReturnURLMixin, BaseObjectView):
# Create the new components # Create the new components
new_objs = [] new_objs = []
for component_form in new_components: for component_form in new_components:
# Record changelog message (if any)
if changelog_message:
component_form.instance._changelog_message = changelog_message
obj = component_form.save() obj = component_form.save()
new_objs.append(obj) new_objs.append(obj)

File diff suppressed because it is too large Load Diff