Skip to content
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

Overhaul of peer endpoint's IP #149

Draft
wants to merge 1 commit into
base: develop
Choose a base branch
from
Draft

Conversation

mzbroch
Copy link
Contributor

@mzbroch mzbroch commented Oct 23, 2023

  • Introduce ip attribute on the PeerEndpoint model. This attribute should always store the computed endpoint's IP Address.
  • Adds support for multiple IP addresses on the source_interface - perform primary_ip lookup.
  1. Change of peer_endpoint.source_ip
  • source_ip is set - implemented by peer_endpoint.save()
  • source_ip is removed - implemented by peer_endpoint.save()
  • source_ip is changed - implemented by peer_endpoint.save()
  1. Change of peer_group.source_ip
  • source_ip set on peergroup - send signal any time this setting changes on the parent peer_group
    this will only impact peer_endpoints if they had peer_group.source_interface inheritance before
    implemented through handle_peergroup_updates signal

  • source_ip removed on peergroup - send signal any time peer endpoint is added to the peer group
    implemented through handle_peergroup_updates signal

  • source_ip changed on the peergroup - send signal any time peer endpoint is removed from the peer group
    implemented through handle_peergroup_updates signal

  • protect peer_group.endpoints.all() from becoming invalid - implemented

  1. Change of the peer_endpoint.source_interface
  • source_interface is set - implemented by peer_endpoint.save()
  • source_interface is removed - implemented by peer_endpoint.save()
  • source_interface is changed - implemented by peer_endpoint.save()
  1. Change of peer_group.source_interface
  • source_interface added/changed/removed on PG - implemented handle_peergroup_updates
  • protect peer_group.endpoints.all() from becoming invalid - implemented peer_group.clean()
  1. PeerEndpoint group membership
  • peerendpoint added to a peer_group - IP validated during peerendpoint.clean()
  • peerendpoint removed from a peer_group - IP validated during peerendpoint.clean()
  1. Source interface has many IP addresses:
  • many IPv4 addresses - resolve source_ip based on is_primary on IPAddressAssignment
  • many IPv6 addresses - resolve source_ip based on is_primary on IPAddressAssignment
  1. Change on the interface
  • IP address is added to the interface
  • IP Address is removed on the interface
  • No IP Address on the interface
  • Multiple IP addresses on the interface
  1. Data migration
  • populate peer_endpoint.ip values

Comment on lines +453 to +456
# If source IP and source-interface, ensure source-ip is defined on source-interface:
if (self.source_ip and self.source_interface) and (
not self.source_interface.ip_addresses.filter(pk=self.source_ip.pk)):
raise ValidationError("Selected source IP is not assigned to the selected source interface")
Copy link
Contributor

Choose a reason for hiding this comment

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

Just checking - is it invalid to e.g. use a loopback IP as the source_ip but specify a physical source_interface?

Copy link
Contributor Author

@mzbroch mzbroch Oct 23, 2023

Choose a reason for hiding this comment

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

I think You are correct - if we allow for the logic defined in local_ip() :

  1. source_ip
  2. soure_interface

so that source_interface should not be validated for its IP address

raise ValidationError("Can not set both IP and Update source options")
# If source IP and source-interface, ensure source-ip is defined on source-interface:
if (self.source_ip and self.source_interface) and (
not self.source_interface.ip_addresses.filter(pk=self.source_ip.pk)):
Copy link
Contributor

Choose a reason for hiding this comment

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

Probably should add an .exists() here and in the similar logic below.

Copy link
Contributor Author

@mzbroch mzbroch Oct 23, 2023

Choose a reason for hiding this comment

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

I would say we should remove this check entirely as per above comment

"""
for endpoint in self.endpoints.all():
if not endpoint.local_ip:
raise ValidationError(f"Peer endpoint does not have a local IP")
Copy link
Contributor

Choose a reason for hiding this comment

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

Probably would be good to indicate which endpoint(s) specifically are failing?

@@ -589,28 +598,66 @@ def to_csv(self):
self.peer,
)

ip = models.ForeignKey( # Computed IP
Copy link
Contributor

Choose a reason for hiding this comment

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

should the __str__ method be changed to use this instead of local_ip?

on_delete=models.PROTECT,
blank=True,
null=True,
related_name="bgp_peer_endpoints",
Copy link
Contributor

Choose a reason for hiding this comment

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

This needs a different related_name than the source_ip related_name, doesn't it?

to="ipam.IPAddress",
on_delete=models.PROTECT,
blank=True,
null=True,
Copy link
Contributor

Choose a reason for hiding this comment

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

Should this be non-nullable?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Interesting - now I'm thinking it's possible and would be a very good validation for the data consistency


# Priority 4: Source IP defined through source-interface on the PeerGroup
if interface_source_ip and inherited_source_interface:
return interface_source_ip
Copy link
Contributor

Choose a reason for hiding this comment

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

Do we need a final else case to either return None or raise an exception?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants