Skip to content

Commit e45a9c8

Browse files
khackworthcardoe
authored andcommitted
Changing the route logic from a /24 to a /17
1 parent 3b9a622 commit e45a9c8

File tree

2 files changed

+107
-71
lines changed

2 files changed

+107
-71
lines changed

python/understack-workflows/tests/test_netapp_value_objects.py

Lines changed: 103 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -509,8 +509,8 @@ def test_from_nexthop_ip_third_octet_zero(self):
509509
assert str(spec.gateway) == "100.127.0.17"
510510
assert str(spec.destination) == "100.126.0.0/17"
511511

512-
def test_from_nexthop_ip_third_octet_128(self):
513-
"""Test route destination calculation for third octet = 128."""
512+
def test_from_nexthop_ip_third_octet_128_range(self):
513+
"""Test route destination calculation for third octet in 128-255 range."""
514514
spec = RouteSpec.from_nexthop_ip("os-test-project", "100.127.128.17")
515515

516516
assert spec.svm_name == "os-test-project"
@@ -531,34 +531,55 @@ def test_from_nexthop_ip_various_valid_ips(self):
531531
assert spec.destination == expected_destination
532532
assert str(spec.gateway) == nexthop_ip
533533

534-
def test_calculate_destination_third_octet_zero(self):
535-
"""Test _calculate_destination static method for third octet = 0."""
536-
destination = RouteSpec._calculate_destination("100.127.0.17")
537-
assert destination == ipaddress.IPv4Network("100.126.0.0/17")
534+
def test_calculate_destination_third_octet_0_to_127_range(self):
535+
"""Test _calculate_destination static method for third octet in 0-127 range."""
536+
# Test boundary values and some values in between
537+
test_cases = [
538+
"100.127.0.17", # Lower boundary
539+
"100.127.64.17", # Middle value
540+
"100.127.127.17", # Upper boundary
541+
]
538542

539-
def test_calculate_destination_third_octet_128(self):
540-
"""Test _calculate_destination static method for third octet = 128."""
541-
destination = RouteSpec._calculate_destination("100.127.128.17")
542-
assert destination == ipaddress.IPv4Network("100.126.128.0/17")
543+
for ip in test_cases:
544+
destination = RouteSpec._calculate_destination(ip)
545+
assert destination == ipaddress.IPv4Network("100.126.0.0/17")
546+
547+
def test_calculate_destination_third_octet_128_to_255_range(self):
548+
"""Test _calculate_destination static 128-255 range."""
549+
# Test boundary values and some values in between
550+
test_cases = [
551+
"100.127.128.17", # Lower boundary
552+
"100.127.192.17", # Middle value
553+
"100.127.255.17", # Upper boundary
554+
]
555+
556+
for ip in test_cases:
557+
destination = RouteSpec._calculate_destination(ip)
558+
assert destination == ipaddress.IPv4Network("100.126.128.0/17")
543559

544560
def test_calculate_destination_invalid_pattern(self):
545-
"""Test _calculate_destination with unsupported third octet values."""
561+
"""Test _calculate_destination with IPs outside 100.64.0.0/10 subnet."""
546562
invalid_ips = [
547-
"100.127.1.17",
548-
"100.127.64.17",
549-
"100.127.127.17",
550-
"100.127.129.17",
551-
"100.127.255.17",
563+
"192.168.1.17", # Private network
564+
"10.0.0.17", # Private network
565+
"172.16.0.17", # Private network
566+
"8.8.8.8", # Public network
567+
"100.63.255.17", # Just below 100.64.0.0/10
568+
"100.128.0.17", # Just above 100.64.0.0/10
552569
]
553570

554571
for invalid_ip in invalid_ips:
555-
with pytest.raises(ValueError, match="Unsupported IP pattern"):
572+
with pytest.raises(
573+
ValueError, match="not within required 100.64.0.0/10 subnet"
574+
):
556575
RouteSpec._calculate_destination(invalid_ip)
557576

558577
def test_from_nexthop_ip_invalid_pattern(self):
559-
"""Test from_nexthop_ip with unsupported IP patterns."""
560-
with pytest.raises(ValueError, match="Unsupported IP pattern"):
561-
RouteSpec.from_nexthop_ip("os-test-project", "100.127.64.17")
578+
"""Test from_nexthop_ip with IPs outside carrier-grade NAT range."""
579+
with pytest.raises(
580+
ValueError, match="not within required 100.64.0.0/10 subnet"
581+
):
582+
RouteSpec.from_nexthop_ip("os-test-project", "192.168.1.17")
562583

563584
def test_calculate_destination_invalid_ip_format(self):
564585
"""Test _calculate_destination with invalid IP format."""
@@ -574,16 +595,16 @@ def test_calculate_destination_invalid_ip_format(self):
574595
with pytest.raises((ValueError, ipaddress.AddressValueError)):
575596
RouteSpec._calculate_destination(invalid_format)
576597

577-
def test_calculate_destination_comprehensive_third_octet_zero(self):
578-
"""Test comprehensive route destination calculation for third octet = 0."""
579-
# Test various IP addresses with third octet = 0 within 100.64.0.0/10 subnet
598+
def test_calculate_destination_comprehensive_third_octet_0_to_127(self):
599+
"""Test comprehensive route destination calculation for range 0-127."""
600+
# Test various IP addresses with third octets 0-127 within 100.64.0.0/10 subnet
580601
test_ips = [
581-
"100.64.0.1",
582-
"100.65.0.1",
583-
"100.66.0.254",
584-
"100.67.0.100",
585-
"100.68.0.3",
586-
"100.127.0.255",
602+
"100.64.0.1", # Third octet = 0
603+
"100.65.1.1", # Third octet = 1
604+
"100.66.63.254", # Third octet = 63
605+
"100.67.64.100", # Third octet = 64
606+
"100.68.126.3", # Third octet = 126
607+
"100.127.127.255", # Third octet = 127 (boundary)
587608
]
588609

589610
for ip in test_ips:
@@ -592,16 +613,16 @@ def test_calculate_destination_comprehensive_third_octet_zero(self):
592613
"100.126.0.0/17"
593614
), f"Failed for IP: {ip}"
594615

595-
def test_calculate_destination_comprehensive_third_octet_128(self):
596-
"""Test comprehensive route destination calculation for third octet = 128."""
597-
# Test various IP addresses with third octet = 128 within 100.64.0.0/10 subnet
616+
def test_calculate_destination_comprehensive_third_octet_128_to_255(self):
617+
"""Test comprehensive route destination calculation for range 128-255."""
618+
# Test various IP addresses with third octets 128-255 within subnet
598619
test_ips = [
599-
"100.64.128.1",
600-
"100.65.128.1",
601-
"100.66.128.254",
602-
"100.67.128.100",
603-
"100.68.128.3",
604-
"100.127.128.255",
620+
"100.64.128.1", # Third octet = 128 (boundary)
621+
"100.65.129.1", # Third octet = 129
622+
"100.66.192.254", # Third octet = 192
623+
"100.67.200.100", # Third octet = 200
624+
"100.68.254.3", # Third octet = 254
625+
"100.127.255.255", # Third octet = 255 (boundary)
605626
]
606627

607628
for ip in test_ips:
@@ -611,13 +632,21 @@ def test_calculate_destination_comprehensive_third_octet_128(self):
611632
), f"Failed for IP: {ip}"
612633

613634
def test_calculate_destination_comprehensive_invalid_patterns(self):
614-
"""Test comprehensive error handling for all invalid third octet values."""
615-
# Test all invalid third octet values (not 0 or 128) within 100.64.0.0/10 subnet
616-
invalid_third_octets = [1, 2, 63, 64, 127, 129, 192, 254, 255]
635+
"""Test comprehensive error handling for IPs outside carrier-grade NAT range."""
636+
# Test IPs outside 100.64.0.0/10 subnet - these should all fail
637+
invalid_base_addresses = [
638+
"100.63", # Just below the range
639+
"100.128", # Just above the range
640+
"192.168", # Private network
641+
"10.0", # Private network
642+
"172.16", # Private network
643+
]
617644

618-
for third_octet in invalid_third_octets:
619-
invalid_ip = f"100.64.{third_octet}.1"
620-
with pytest.raises(ValueError, match="Unsupported IP pattern"):
645+
for base_addr in invalid_base_addresses:
646+
invalid_ip = f"{base_addr}.1.1"
647+
with pytest.raises(
648+
ValueError, match="not within required 100.64.0.0/10 subnet"
649+
):
621650
RouteSpec._calculate_destination(invalid_ip)
622651

623652
def test_from_nexthop_ip_comprehensive_valid_patterns(self):
@@ -653,15 +682,23 @@ def test_from_nexthop_ip_comprehensive_valid_patterns(self):
653682
assert spec.destination == expected_destination
654683

655684
def test_from_nexthop_ip_comprehensive_invalid_patterns(self):
656-
"""Test RouteSpec.from_nexthop_ip with comprehensive invalid IP patterns."""
685+
"""Test RouteSpec.from_nexthop_ip with IPs outside carrier-grade NAT range."""
657686
svm_name = "os-550e8400-e29b-41d4-a716-446655440000"
658687

659-
# Test invalid third octet values within 100.64.0.0/10 subnet
660-
invalid_third_octets = [1, 2, 63, 64, 127, 129, 192, 254, 255]
688+
# Test IPs outside 100.64.0.0/10 subnet - these should all fail
689+
invalid_ips = [
690+
"192.168.1.1", # Private network
691+
"10.0.0.1", # Private network
692+
"172.16.0.1", # Private network
693+
"8.8.8.8", # Public network
694+
"100.63.255.1", # Just below 100.64.0.0/10
695+
"100.128.0.1", # Just above 100.64.0.0/10
696+
]
661697

662-
for third_octet in invalid_third_octets:
663-
invalid_ip = f"100.64.{third_octet}.1"
664-
with pytest.raises(ValueError, match="Unsupported IP pattern"):
698+
for invalid_ip in invalid_ips:
699+
with pytest.raises(
700+
ValueError, match="not within required 100.64.0.0/10 subnet"
701+
):
665702
RouteSpec.from_nexthop_ip(svm_name, invalid_ip)
666703

667704
def test_from_nexthop_ip_edge_cases(self):
@@ -693,24 +730,22 @@ def test_from_nexthop_ip_edge_cases(self):
693730
assert str(spec.gateway) == ip
694731

695732
def test_calculate_destination_boundary_values(self):
696-
"""Test _calculate_destination with boundary values for third octet."""
697-
# Test exact boundary values within 100.64.0.0/10 subnet
698-
assert RouteSpec._calculate_destination("100.64.0.1") == ipaddress.IPv4Network(
699-
"100.126.0.0/17"
700-
)
701-
assert RouteSpec._calculate_destination(
702-
"100.64.128.1"
703-
) == ipaddress.IPv4Network("100.126.128.0/17")
704-
705-
# Test values just outside boundaries should fail
706-
with pytest.raises(ValueError, match="Unsupported IP pattern"):
707-
RouteSpec._calculate_destination("100.64.1.1") # Just above 0
708-
709-
with pytest.raises(ValueError, match="Unsupported IP pattern"):
710-
RouteSpec._calculate_destination("100.64.127.1") # Just below 128
711-
712-
with pytest.raises(ValueError, match="Unsupported IP pattern"):
713-
RouteSpec._calculate_destination("100.64.129.1") # Just above 128
733+
"""Test _calculate_destination with boundary values for third octet ranges."""
734+
# Test boundary values for 0-127 range (maps to 100.126.0.0/17)
735+
expected_0_127 = ipaddress.IPv4Network("100.126.0.0/17")
736+
expected_128_255 = ipaddress.IPv4Network("100.126.128.0/17")
737+
738+
# Test boundary values for 0-127 range
739+
assert RouteSpec._calculate_destination("100.64.0.1") == expected_0_127
740+
assert RouteSpec._calculate_destination("100.64.127.1") == expected_0_127
741+
742+
# Test boundary values for 128-255 range
743+
assert RouteSpec._calculate_destination("100.64.128.1") == expected_128_255
744+
assert RouteSpec._calculate_destination("100.64.255.1") == expected_128_255
745+
746+
# Test values throughout the ranges should work
747+
assert RouteSpec._calculate_destination("100.64.1.1") == expected_0_127
748+
assert RouteSpec._calculate_destination("100.64.129.1") == expected_128_255
714749

715750
def test_calculate_destination_subnet_validation(self):
716751
"""Test _calculate_destination validates IP is within 100.64.0.0/10 subnet."""

python/understack-workflows/understack_workflows/netapp/value_objects.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -680,7 +680,7 @@ def _calculate_destination(nexthop_ip: str) -> IPv4Network:
680680
IPv4Network: Route destination in CIDR format
681681
682682
Raises:
683-
ValueError: If IP is not in 100.64.0.0/10 subnet or third octet not 0 or 128
683+
ValueError: If IP is not in 100.64.0.0/10 subnet or not in /17 ranges
684684
"""
685685
ip = IPv4Address(nexthop_ip)
686686

@@ -693,9 +693,10 @@ def _calculate_destination(nexthop_ip: str) -> IPv4Network:
693693

694694
third_octet = int(str(ip).split(".")[2])
695695

696-
if third_octet == 0:
696+
# Check which /17 network the IP belongs to
697+
if 0 <= third_octet <= 127:
697698
return IPv4Network("100.126.0.0/17")
698-
elif third_octet == 128:
699+
elif 128 <= third_octet <= 255:
699700
return IPv4Network("100.126.128.0/17")
700701
else:
701702
raise ValueError(

0 commit comments

Comments
 (0)