-
Notifications
You must be signed in to change notification settings - Fork 263
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
Device Redundancy Groups #2615
Device Redundancy Groups #2615
Conversation
I'd say no to this validation. There are valid real-world use cases where two devices would have the same priority. For instance, I might have a cluster of 4 firewalls with two |
Co-authored-by: Jathan McCollum <jathan@gmail.com> Co-authored-by: HanlinMiao <46973263+HanlinMiao@users.noreply.github.com> Co-authored-by: Glenn Matthews <glenn.matthews@networktocode.com>
Co-authored-by: Glenn Matthews <glenn.matthews@networktocode.com>
@@ -1039,6 +1041,11 @@ class DeviceFilterSet( | |||
field_name="virtual_chassis", | |||
label="Is a virtual chassis member", | |||
) | |||
device_redundancy_group = NaturalKeyOrPKMultipleChoiceFilter( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we want a has_device_redundancy_group
filter?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does that hold up the merge?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no
…ilterLookupExpressionTest tests.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Small requests here. Loving the changes to parse_network_string
!
@@ -383,14 +383,18 @@ def test_slug_not_modified(self): | |||
"""Ensure save method does not modify slug that is passed in.""" | |||
# This really should go on a models test page, but we don't have test structures for models. | |||
if self.slug_source is not None: | |||
new_slug_source_value = "kwyjibo" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
filter_ = self.slug_source + "__exact" | ||
self.model.objects.filter(**{filter_: self.slug_test_object}).update( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not that it's a huge deal, but exact
is the default. If we're switching to this, we might as well rip this out:
filter_ = self.slug_source + "__exact" | |
self.model.objects.filter(**{filter_: self.slug_test_object}).update( | |
self.model.objects.filter(**{self.slug_source: self.slug_test_object}).update( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did you test that suggestion?
|
||
|
||
class DeviceRedundancyGroupViewSet(StatusViewSetMixin, NautobotModelViewSet): | ||
queryset = DeviceRedundancyGroup.objects.select_related("status").prefetch_related("members") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We're safe to use select_related
, it just won't be "optimized" by Cacheops. See: Cacheops caveats, notably:
Update of "selected_related" object does not invalidate cache for queryset. Use .prefetch_related() instead.
field_name="secrets_group", | ||
queryset=SecretsGroup.objects.all(), | ||
to_field_name="slug", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Another minor nit, but pretty sure it's redundant to specify field_name
and to_field_name
here. First because field_name
is only required if the related field differs from the name of the filter defined on the filterset, and to_field_name
defaults to slug
. :)
field_name="secrets_group", | |
queryset=SecretsGroup.objects.all(), | |
to_field_name="slug", | |
queryset=SecretsGroup.objects.all(), |
@@ -1039,6 +1041,11 @@ class DeviceFilterSet( | |||
field_name="virtual_chassis", | |||
label="Is a virtual chassis member", | |||
) | |||
device_redundancy_group = NaturalKeyOrPKMultipleChoiceFilter( | |||
field_name="device_redundancy_group", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same here, field_name
is likely redundant.
field_name="device_redundancy_group", |
failover_strategy = CSVChoiceField( | ||
choices=DeviceRedundancyGroupFailoverStrategyChoices, required=False, help_text="Failover Strategy" | ||
) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Documentation for DeviceRedundancyGroup model
Closes: #1892
What's Changed
Starting
RedundancyGroup
implementation.So far what's implemented:
DeviceRedundancyGroup
model, supporting custom fields, tags, statuses,SecretGroups
failover_strategy
is a choice, currently identified asActive/Active
orActive/Passive
Device
has been updated:DeviceRedundancyGroup
asdevice_redundancy_group
device_redundancy_group_priority
ConfigContext
has been updated:ManyToManyField
todcim.DeviceRedundancyGroup
asdevice_redundancy_groups
for the purposes of applying a ConfigContext based upon aDevice
sDeviceRedundancyGroup
membershipConfigContextFilterSet
:schema
not a valid filter but exists on form, see https://demo.nautobot.com/extras/config-contexts/schema
filter form field onConfigContextFilterForm
wasn't compatible with proper filter field introduced aboveOther changes due to changes in Factory fuzzing exposing test failures
Device
s form test (DeviceTestCase
) was flakyDeviceType
from factory may not be found that has aManufacturer
with an associatedPlatform
s that is full depth and1
U heightDeviceType
of non-zero U heightBaseNetworkQuerySet
andIPAddressQuerySet
'sparse_network_string
function overhauled (used when performing incomplete searches for network addresses)b2a
(a valid abbreviated first hextet for an IPv6 address) would not return results. This was due toRE_HEXTET
requiring a unabbreviated hextet for searchingRE_HEXTET
updated to permit abbreviated forms of hextet10
would always result in only IPv4 searches, even though it also is a valid IPv6 beginning hextet. This is an ambiguous search string so should return results for both._is_ambiguous_network_string
introduced to help determine if inputted string could be either a valid IPv4 beginning octet or a valid IPv6 beginning hextetstring_search
updated to search for both IPv4 and IPv6 addresses if an ambiguous search string is givenparse_network_string
consistent (both derived IP version and always a singlenetaddr.IPNetwork
) and DRY the following changes were made:_safe_parse_network_string
introduced to forcibly try to parse inputted search string as either a IPv4 or IPv6 address or fragmentparse_ipv4
andparse_ipv6
asparse_network_string
did beforeparse_network_string
's original error handling for thrownnetaddr.core.AddrFormatError
and ensures always return a validnetaddr.IPNetwork
object_check_and_prep_ipv6
introduced to perform much of the "probably IPv6 address" logic originally done inparse_network_string
parse_ipv6
by appending the necessary:
sparse_network_string
simplified significantly by leveraging the discrete functions aboveRouteTarget
s View test case (RouteTargetTestCase
) was exposed to have a flakycsv_data
structureTenant
s name can include a comma so structure was updated to always escape this fieldPrefixFactory
may randomly decided to create a child of2.2.2.2/32
. This is because it checks the size of the prefix and attempts to create children if it's of a large enough size.prefix.size
:Prefix(2.2.2.2/31).size
correctly returns2
which can have two children in it,2.2.2.2/32
and2.2.2.3/32
Prefix(2.2.2.2/32).size
correctly returns1
but cannot have a childprefix.size
is1
VirtualChassis
Filter test case (VirtualChassisTestCase
) had too narrow of a region lookupRegion.objects.filter(sites__isnull=False, children__isnull=True, parent__isnull=True)
may not have returned the required 3 Regions. The tests below were improved in earlier commits to not require no parents and no children so updated tocls.regions = Region.objects.filter(sites__isnull=False)[:3]
Similar failure for
DynamicFilterLookupExpressionTest
Filter test asVirtualCassis
filter test above.RackGroup
Model test (test_change_rackgroup_site
) may have randomly chosen the same site to update the rackgroups existing membership tosite_b
updated to be the last object returned from an exclusion of the existing membership siteSimilar failure for
Prefix
Model test asRackGroup
above.Location
View test case (LocationTestCase
) was exposed to have a flakycsv_data
structureRIR
API View test case (RIRTest
) may have had no deleteable objects to testAggregate
has in inbound protected relationship toRIR
which would prevent deletion. Instead of increasing random pool size, an ensured deletable object was createdtest_slug_not_modified
was updated to ensure no collision on new slug source value as well as changing lookup expressions from__contains
to__exact
in the case where auto-generated names have nested details (ex: Device names:Device A
andDevice A - PSU
)TODO