Skip to content
Snippets Groups Projects
Commit 71df5da1 authored by Karel van Klink's avatar Karel van Klink :smiley_cat:
Browse files

Add optional TTL security field to BGP session product block

parent ec61421c
Branches
Tags
1 merge request!412Add optional TTL security field to BGP session product block
Pipeline #93730 passed
Showing
with 68 additions and 3 deletions
......@@ -36,6 +36,7 @@
*[NREN]: National Research and Education Network
*[OOB]: Out-of-band
*[OSS]: Operational Support Systems
*[OTRS]: Trouble Ticket system software package
*[PoP]: Point of Presence
*[REST]: Representational State Transfer
*[RFC]: Request For Comments
......@@ -44,6 +45,7 @@
*[SNMP]: Simple Network Management Protocol
*[SOT]: Source Of Truth
*[TBA]: To be added
*[TTL]: Time To Live
*[UAT]: User Acceptance Testing
*[VM]: Virtual Machine
*[VRF]: Virtual Routing and Forwarding
......
......@@ -55,6 +55,7 @@ OIDC
OOB
OPA
(OSS|oss)
OTRS
PHASE 1
Po[Pp]
Pydantic
......@@ -69,6 +70,7 @@ SOT
SURF
TBA
TERMINATED?
TTL
TWAMP
UAT
UTC
......
......@@ -259,6 +259,7 @@ class L3CoreServiceImportModel(BaseModel):
is_multi_hop: bool
rtbh_enabled: bool # whether Remote Triggered Blackhole is enabled
prefix_limit: NonNegativeInt | None = None
ttl_security: NonNegativeInt | None = None
class BFDSettingsModel(BaseModel):
"""BFD Settings model."""
......
"""Add optional TTL security to BGP session.
Revision ID: a3177c5f9641
Revises: fffe36624681
Create Date: 2025-04-28 10:21:54.820219
"""
import sqlalchemy as sa
from alembic import op
# revision identifiers, used by Alembic.
revision = 'a3177c5f9641'
down_revision = 'fffe36624681'
branch_labels = None
depends_on = None
def upgrade() -> None:
conn = op.get_bind()
conn.execute(sa.text("""
INSERT INTO resource_types (resource_type, description) VALUES ('ttl_security', 'BGP TTL security') RETURNING resource_types.resource_type_id
"""))
conn.execute(sa.text("""
INSERT INTO product_block_resource_types (product_block_id, resource_type_id) VALUES ((SELECT product_blocks.product_block_id FROM product_blocks WHERE product_blocks.name IN ('BGPSession')), (SELECT resource_types.resource_type_id FROM resource_types WHERE resource_types.resource_type IN ('ttl_security')))
"""))
def downgrade() -> None:
conn = op.get_bind()
conn.execute(sa.text("""
DELETE FROM product_block_resource_types WHERE product_block_resource_types.product_block_id IN (SELECT product_blocks.product_block_id FROM product_blocks WHERE product_blocks.name IN ('BGPSession')) AND product_block_resource_types.resource_type_id = (SELECT resource_types.resource_type_id FROM resource_types WHERE resource_types.resource_type IN ('ttl_security'))
"""))
conn.execute(sa.text("""
DELETE FROM subscription_instance_values USING product_block_resource_types WHERE subscription_instance_values.subscription_instance_id IN (SELECT subscription_instances.subscription_instance_id FROM subscription_instances WHERE subscription_instances.subscription_instance_id IN (SELECT product_blocks.product_block_id FROM product_blocks WHERE product_blocks.name IN ('BGPSession'))) AND product_block_resource_types.resource_type_id = (SELECT resource_types.resource_type_id FROM resource_types WHERE resource_types.resource_type IN ('ttl_security'))
"""))
conn.execute(sa.text("""
DELETE FROM subscription_instance_values WHERE subscription_instance_values.resource_type_id IN (SELECT resource_types.resource_type_id FROM resource_types WHERE resource_types.resource_type IN ('ttl_security'))
"""))
conn.execute(sa.text("""
DELETE FROM resource_types WHERE resource_types.resource_type IN ('ttl_security')
"""))
......@@ -48,6 +48,7 @@ class BGPSessionInactive(ProductBlockModel, lifecycle=[SubscriptionLifecycle.INI
bfd_enabled: bool = False
ip_type: IPTypes | None = None
prefix_limit: NonNegativeInt | None = None
ttl_security: NonNegativeInt | None = None
class BGPSessionProvisioning(BGPSessionInactive, lifecycle=[SubscriptionLifecycle.PROVISIONING]):
......@@ -65,6 +66,7 @@ class BGPSessionProvisioning(BGPSessionInactive, lifecycle=[SubscriptionLifecycl
bfd_enabled: bool
ip_type: IPTypes
prefix_limit: NonNegativeInt | None
ttl_security: NonNegativeInt | None
class BGPSession(BGPSessionProvisioning, lifecycle=[SubscriptionLifecycle.ACTIVE]):
......@@ -83,6 +85,7 @@ class BGPSession(BGPSessionProvisioning, lifecycle=[SubscriptionLifecycle.ACTIVE
bfd_enabled: Settings for BFD.
ip_type: The IP type of the session.
prefix_limit: A prefix limit, if required.
ttl_security: A limit on time-to-live used for TTL security.
"""
peer_address: IPAddress
......@@ -97,3 +100,4 @@ class BGPSession(BGPSessionProvisioning, lifecycle=[SubscriptionLifecycle.ACTIVE
bfd_enabled: bool
ip_type: IPTypes
prefix_limit: NonNegativeInt | None
ttl_security: NonNegativeInt | None
......@@ -58,6 +58,7 @@
"v4_bgp_bfd_enabled": "IPv4 BGP - BFD enabled",
"v4_bgp_multipath_enabled": "IPv4 - BGP multipath enabled",
"v4_bgp_prefix_limit": "IPv4 - BGP prefix limit",
"v4_bgp_ttl_security": "IPv4 - BGP TTL security",
"v4_bgp_is_passive": "IPv4 - BGP is passive",
"v4_bgp_send_default_route": "IPv4 - BGP send default route",
"v4_bgp_add_v4_multicast": "IPv4 - BGP add multicast",
......@@ -71,6 +72,7 @@
"v6_bgp_bfd_enabled": "IPv6 - BGP BFD enabled",
"v6_bgp_multipath_enabled": "IPv6 - BGP multipath enabled",
"v6_bgp_prefix_limit": "IPv6 - BGP prefix limit",
"v6_bgp_ttl_security": "IPv6 - BGP TTL security",
"v6_bgp_is_passive": "IPv6 - BGP is passive",
"v6_bgp_send_default_route": "IPv6 - BGP send default route",
"v6_bgp_add_v6_multicast": "IPv6 - BGP add multicast"
......
......@@ -40,6 +40,7 @@ def initial_input_form_generator() -> FormGenerator:
is_multi_hop: bool
rtbh_enabled: bool
prefix_limit: NonNegativeInt | None = None
ttl_security: NonNegativeInt | None = None
class ServiceBindingPort(BaseModel):
edge_port: UUIDstr
......
......@@ -70,6 +70,7 @@ def initial_input_form_generator(product_name: str) -> FormGenerator:
bfd_enabled: bool = False
multipath_enabled: bool = False
prefix_limit: NonNegativeInt | None = None
ttl_security: NonNegativeInt | None = None
is_passive: bool = False
add_v4_multicast: bool = Field(default=False, exclude=True)
send_default_route: bool = False
......@@ -91,6 +92,7 @@ def initial_input_form_generator(product_name: str) -> FormGenerator:
bfd_enabled: bool = False
multipath_enabled: bool = False
prefix_limit: NonNegativeInt | None = None
ttl_security: NonNegativeInt | None = None
is_passive: bool = False
add_v6_multicast: bool = Field(default=False, exclude=True)
send_default_route: bool = False
......
......@@ -74,6 +74,7 @@ def initial_input_form_generator(subscription_id: UUIDstr) -> FormGenerator:
bfd_enabled: bool = False
multipath_enabled: bool = False
prefix_limit: NonNegativeInt | None = None
ttl_security: NonNegativeInt | None = None
is_passive: bool = False
add_v4_multicast: bool = Field(default=False, exclude=True)
send_default_route: bool = False
......@@ -95,6 +96,7 @@ def initial_input_form_generator(subscription_id: UUIDstr) -> FormGenerator:
bfd_enabled: bool = False
multipath_enabled: bool = False
prefix_limit: NonNegativeInt | None = None
ttl_security: NonNegativeInt | None = None
is_passive: bool = False
add_v6_multicast: bool = Field(default=False, exclude=True)
send_default_route: bool = False
......@@ -282,6 +284,7 @@ def initial_input_form_generator(subscription_id: UUIDstr) -> FormGenerator:
v4_bgp_bfd_enabled: bool = Field(v4_peer.bfd_enabled, exclude=True)
v4_bgp_multipath_enabled: bool = Field(v4_peer.multipath_enabled, exclude=True)
v4_bgp_prefix_limit: NonNegativeInt | None = Field(v4_peer.prefix_limit, exclude=True)
v4_bgp_ttl_security: NonNegativeInt | None = Field(v4_peer.ttl_security, exclude=True)
v4_bgp_is_passive: bool = Field(v4_peer.is_passive, exclude=True)
v4_bgp_send_default_route: bool = Field(v4_peer.send_default_route, exclude=True)
v4_bgp_add_v4_multicast: bool = Field(bool(IPFamily.V4MULTICAST in v4_peer.families), exclude=True)
......@@ -299,6 +302,7 @@ def initial_input_form_generator(subscription_id: UUIDstr) -> FormGenerator:
v6_bgp_bfd_enabled: bool = Field(v6_peer.bfd_enabled, exclude=True)
v6_bgp_multipath_enabled: bool = Field(v6_peer.multipath_enabled, exclude=True)
v6_bgp_prefix_limit: NonNegativeInt | None = Field(v6_peer.prefix_limit, exclude=True)
v6_bgp_ttl_security: NonNegativeInt | None = Field(v6_peer.ttl_security, exclude=True)
v6_bgp_is_passive: bool = Field(v6_peer.is_passive, exclude=True)
v6_bgp_send_default_route: bool = Field(v6_peer.send_default_route, exclude=True)
v6_bgp_add_v6_multicast: bool = Field(bool(IPFamily.V6MULTICAST in v6_peer.families), exclude=True)
......@@ -323,6 +327,7 @@ def initial_input_form_generator(subscription_id: UUIDstr) -> FormGenerator:
bfd_enabled=self.v4_bgp_bfd_enabled,
multipath_enabled=self.v4_bgp_multipath_enabled,
prefix_limit=self.v4_bgp_prefix_limit,
ttl_security=self.v4_bgp_ttl_security,
is_passive=self.v4_bgp_is_passive,
send_default_route=self.v4_bgp_send_default_route,
add_v4_multicast=self.v4_bgp_add_v4_multicast,
......@@ -348,6 +353,7 @@ def initial_input_form_generator(subscription_id: UUIDstr) -> FormGenerator:
bfd_enabled=self.v6_bgp_bfd_enabled,
multipath_enabled=self.v6_bgp_multipath_enabled,
prefix_limit=self.v6_bgp_prefix_limit,
ttl_security=self.v6_bgp_ttl_security,
is_passive=self.v6_bgp_is_passive,
send_default_route=self.v6_bgp_send_default_route,
add_v6_multicast=self.v6_bgp_add_v6_multicast,
......
......@@ -148,7 +148,7 @@ def check_kentik_entry_exists(subscription: Router) -> None:
license on it. This is because there can be multiple, valid, non-archiving licenses for devices.
Raises:
ProcessFailureError when a Kentik device is missing, or configured incorrectly.
ProcessFailureError: when a Kentik device is missing, or configured incorrectly.
"""
client = KentikClient()
......
......@@ -62,6 +62,7 @@ def bgp_session_subscription_factory(faker):
has_custom_policies: bool = False,
multipath_enabled: bool | None = True,
prefix_limit: NonNegativeInt | None = None,
ttl_security: NonNegativeInt | None = None,
send_default_route: bool | None = True,
is_passive: bool | None = False,
rtbh_enabled: bool | None = False,
......@@ -77,6 +78,7 @@ def bgp_session_subscription_factory(faker):
authentication_key=authentication_key or faker.password(),
multipath_enabled=multipath_enabled,
prefix_limit=prefix_limit,
ttl_security=ttl_security,
send_default_route=send_default_route,
is_multi_hop=is_multi_hop,
rtbh_enabled=rtbh_enabled,
......
......@@ -68,7 +68,8 @@ def test_modify_l3_core_service_add_new_edge_port_success(
"authentication_key": faker.password(),
"peer_address": faker.ipv4(),
"bfd_enabled": False,
"prefix_limit": 1000,
"prefix_limit": faker.random_int(min=500, max=1000),
"ttl_security": faker.random_int(max=255),
},
"v6_bgp_peer": {
"authentication_key": faker.password(),
......@@ -142,7 +143,8 @@ def sbp_input_form_data(faker):
"v6_bgp_is_passive": True,
"v6_bgp_peer_address": faker.ipv6(),
"v6_bgp_add_v6_multicast": True,
"v6_bgp_prefix_limit": 3000,
"v6_bgp_prefix_limit": faker.random_int(min=2500, max=3000),
"v6_bgp_ttl_security": faker.random_int(max=255),
}
return _generate_form_data
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment