From d721a1b6fb8b75fe75a91c81f3d8c11b846c8253 Mon Sep 17 00:00:00 2001 From: Lena Garber Date: Thu, 29 May 2025 13:23:07 -0400 Subject: [PATCH 1/2] Implementation; needs tests --- linode_api4/objects/linode_interfaces.py | 73 ++++++++++++++++++++++++ 1 file changed, 73 insertions(+) diff --git a/linode_api4/objects/linode_interfaces.py b/linode_api4/objects/linode_interfaces.py index f12865c9..35284638 100644 --- a/linode_api4/objects/linode_interfaces.py +++ b/linode_api4/objects/linode_interfaces.py @@ -139,6 +139,41 @@ class LinodeInterfacePublicIPv4Options(JSONObject): addresses: Optional[List[LinodeInterfacePublicIPv4AddressOptions]] = None +@dataclass +class LinodeInterfaceVPCIPv6SLAACOptions(JSONObject): + """ + Options accepted for a single SLAAC when creating or updating the IPv6 configuration of a VPC Linode Interface. + + NOTE: Linode interfaces may not currently be available to all users. + """ + + range: Optional[str] = None + + +@dataclass +class LinodeInterfaceVPCIPv6RangeOptions(JSONObject): + """ + Options accepted for a single range when creating or updating the IPv6 configuration of a VPC Linode Interface. + + NOTE: Linode interfaces may not currently be available to all users. + """ + + range: Optional[str] = None + + +@dataclass +class LinodeInterfaceVPCIPv6Options(JSONObject): + """ + Options accepted when creating or updating the IPv6 configuration of a VPC Linode Interface. + + NOTE: Linode interfaces may not currently be available to all users. + """ + + is_public: Optional[bool] = None + slaac: Optional[List[LinodeInterfaceVPCIPv6SLAACOptions]] = None + ranges: Optional[List[LinodeInterfaceVPCIPv6RangeOptions]] = None + + @dataclass class LinodeInterfacePublicIPv6RangeOptions(JSONObject): """ @@ -265,6 +300,44 @@ class LinodeInterfaceVPCIPv4(JSONObject): ranges: List[LinodeInterfaceVPCIPv4Range] = field(default_factory=list) +@dataclass +class LinodeInterfaceVPCIPv6SLAAC(JSONObject): + """ + A single SLAAC entry under the IPv6 configuration of a VPC Linode Interface. + + NOTE: Linode interfaces may not currently be available to all users. + """ + + range: str = "" + address: str = "" + + +@dataclass +class LinodeInterfaceVPCIPv6Range(JSONObject): + """ + A single range under the IPv6 configuration of a VPC Linode Interface. + + NOTE: Linode interfaces may not currently be available to all users. + """ + + range: str = "" + + +@dataclass +class LinodeInterfaceVPCIPv6(JSONObject): + """ + A single address under the IPv6 configuration of a VPC Linode Interface. + + NOTE: Linode interfaces may not currently be available to all users. + """ + + put_class = LinodeInterfaceVPCIPv6Options + + is_public: bool = False + slaac: List[LinodeInterfaceVPCIPv6SLAAC] = field(default_factory=list) + ranges: List[LinodeInterfaceVPCIPv6Range] = field(default_factory=list) + + @dataclass class LinodeInterfaceVPC(JSONObject): """ From 6c65ee74fd26635e3343850d75dde56e481804f4 Mon Sep 17 00:00:00 2001 From: Lena Garber Date: Thu, 29 May 2025 13:33:49 -0400 Subject: [PATCH 2/2] Add integration tests --- linode_api4/objects/linode_interfaces.py | 46 ++++++++++--------- .../linode_instances_124_interfaces.json | 14 ++++++ .../linode_instances_124_interfaces_456.json | 16 ++++++- ...node_instances_124_upgrade-interfaces.json | 14 ++++++ test/unit/objects/linode_interface_test.py | 25 ++++++++++ 5 files changed, 92 insertions(+), 23 deletions(-) diff --git a/linode_api4/objects/linode_interfaces.py b/linode_api4/objects/linode_interfaces.py index 35284638..0598d1f3 100644 --- a/linode_api4/objects/linode_interfaces.py +++ b/linode_api4/objects/linode_interfaces.py @@ -105,73 +105,74 @@ class LinodeInterfaceVPCIPv4Options(JSONObject): @dataclass -class LinodeInterfaceVPCOptions(JSONObject): +class LinodeInterfaceVPCIPv6SLAACOptions(JSONObject): """ - VPC-exclusive options accepted when creating or updating a Linode Interface. + Options accepted for a single SLAAC when creating or updating the IPv6 configuration of a VPC Linode Interface. NOTE: Linode interfaces may not currently be available to all users. """ - subnet_id: int = 0 - ipv4: Optional[LinodeInterfaceVPCIPv4Options] = None + range: Optional[str] = None @dataclass -class LinodeInterfacePublicIPv4AddressOptions(JSONObject): +class LinodeInterfaceVPCIPv6RangeOptions(JSONObject): """ - Options accepted for a single address when creating or updating the IPv4 configuration of a public Linode Interface. + Options accepted for a single range when creating or updating the IPv6 configuration of a VPC Linode Interface. NOTE: Linode interfaces may not currently be available to all users. """ - address: str = "" - primary: Optional[bool] = None + range: Optional[str] = None @dataclass -class LinodeInterfacePublicIPv4Options(JSONObject): +class LinodeInterfaceVPCIPv6Options(JSONObject): """ - Options accepted when creating or updating the IPv4 configuration of a public Linode Interface. + Options accepted when creating or updating the IPv6 configuration of a VPC Linode Interface. NOTE: Linode interfaces may not currently be available to all users. """ - addresses: Optional[List[LinodeInterfacePublicIPv4AddressOptions]] = None + is_public: Optional[bool] = None + slaac: Optional[List[LinodeInterfaceVPCIPv6SLAACOptions]] = None + ranges: Optional[List[LinodeInterfaceVPCIPv6RangeOptions]] = None @dataclass -class LinodeInterfaceVPCIPv6SLAACOptions(JSONObject): +class LinodeInterfaceVPCOptions(JSONObject): """ - Options accepted for a single SLAAC when creating or updating the IPv6 configuration of a VPC Linode Interface. + VPC-exclusive options accepted when creating or updating a Linode Interface. NOTE: Linode interfaces may not currently be available to all users. """ - range: Optional[str] = None + subnet_id: int = 0 + ipv4: Optional[LinodeInterfaceVPCIPv4Options] = None + ipv6: Optional[LinodeInterfaceVPCIPv6Options] = None @dataclass -class LinodeInterfaceVPCIPv6RangeOptions(JSONObject): +class LinodeInterfacePublicIPv4AddressOptions(JSONObject): """ - Options accepted for a single range when creating or updating the IPv6 configuration of a VPC Linode Interface. + Options accepted for a single address when creating or updating the IPv4 configuration of a public Linode Interface. NOTE: Linode interfaces may not currently be available to all users. """ - range: Optional[str] = None + address: str = "" + primary: Optional[bool] = None @dataclass -class LinodeInterfaceVPCIPv6Options(JSONObject): +class LinodeInterfacePublicIPv4Options(JSONObject): """ - Options accepted when creating or updating the IPv6 configuration of a VPC Linode Interface. + Options accepted when creating or updating the IPv4 configuration of a public Linode Interface. NOTE: Linode interfaces may not currently be available to all users. """ - is_public: Optional[bool] = None - slaac: Optional[List[LinodeInterfaceVPCIPv6SLAACOptions]] = None - ranges: Optional[List[LinodeInterfaceVPCIPv6RangeOptions]] = None + addresses: Optional[List[LinodeInterfacePublicIPv4AddressOptions]] = None @dataclass @@ -352,6 +353,7 @@ class LinodeInterfaceVPC(JSONObject): subnet_id: int = 0 ipv4: Optional[LinodeInterfaceVPCIPv4] = None + ipv6: Optional[LinodeInterfaceVPCIPv6] = None @dataclass diff --git a/test/fixtures/linode_instances_124_interfaces.json b/test/fixtures/linode_instances_124_interfaces.json index a0ffddef..305beb1a 100644 --- a/test/fixtures/linode_instances_124_interfaces.json +++ b/test/fixtures/linode_instances_124_interfaces.json @@ -80,6 +80,20 @@ "range": "192.168.22.32/28" } ] + }, + "ipv6": { + "is_public": true, + "slaac": [ + { + "range": "1234::/64", + "address": "1234::5678" + } + ], + "ranges": [ + { + "range": "4321::/64" + } + ] } }, "public": null, diff --git a/test/fixtures/linode_instances_124_interfaces_456.json b/test/fixtures/linode_instances_124_interfaces_456.json index 7fc4f56f..0af73436 100644 --- a/test/fixtures/linode_instances_124_interfaces_456.json +++ b/test/fixtures/linode_instances_124_interfaces_456.json @@ -10,7 +10,7 @@ "vpc": { "vpc_id": 123456, "subnet_id": 789, - "ipv4" : { + "ipv4": { "addresses": [ { "address": "192.168.22.3", @@ -21,6 +21,20 @@ { "range": "192.168.22.16/28"}, { "range": "192.168.22.32/28"} ] + }, + "ipv6": { + "is_public": true, + "slaac": [ + { + "range": "1234::/64", + "address": "1234::5678" + } + ], + "ranges": [ + { + "range": "4321::/64" + } + ] } }, "public": null, diff --git a/test/fixtures/linode_instances_124_upgrade-interfaces.json b/test/fixtures/linode_instances_124_upgrade-interfaces.json index 12340c4a..bd033e90 100644 --- a/test/fixtures/linode_instances_124_upgrade-interfaces.json +++ b/test/fixtures/linode_instances_124_upgrade-interfaces.json @@ -82,6 +82,20 @@ "range": "192.168.22.32/28" } ] + }, + "ipv6": { + "is_public": true, + "slaac": [ + { + "range": "1234::/64", + "address": "1234::5678" + } + ], + "ranges": [ + { + "range": "4321::/64" + } + ] } }, "public": null, diff --git a/test/unit/objects/linode_interface_test.py b/test/unit/objects/linode_interface_test.py index db0232c9..11c62930 100644 --- a/test/unit/objects/linode_interface_test.py +++ b/test/unit/objects/linode_interface_test.py @@ -14,6 +14,7 @@ LinodeInterfaceVPCIPv4AddressOptions, LinodeInterfaceVPCIPv4Options, LinodeInterfaceVPCIPv4RangeOptions, + LinodeInterfaceVPCIPv6SLAACOptions, LinodeInterfaceVPCOptions, ) @@ -149,6 +150,13 @@ def assert_linode_124_interface_456(iface: LinodeInterface): assert iface.vpc.ipv4.ranges[0].range == "192.168.22.16/28" assert iface.vpc.ipv4.ranges[1].range == "192.168.22.32/28" + assert iface.vpc.ipv6.is_public + + assert iface.vpc.ipv6.slaac[0].range == "1234::/64" + assert iface.vpc.ipv6.slaac[0].address == "1234::5678" + + assert iface.vpc.ipv6.ranges[0].range == "4321::/64" + @staticmethod def assert_linode_124_interface_789(iface: LinodeInterface): assert iface.id == 789 @@ -261,6 +269,18 @@ def test_update_vpc(self): ) ] + iface.vpc.ipv6.is_public = False + + iface.vpc.ipv6.slaac = [ + LinodeInterfaceVPCIPv6SLAACOptions( + range="1233::/64", + ) + ] + + iface.vpc.ipv6.ranges = [ + LinodeInterfacePublicIPv6RangeOptions(range="9876::/64") + ] + with self.mock_put("/linode/instances/124/interfaces/456") as m: iface.save() @@ -282,6 +302,11 @@ def test_update_vpc(self): ], "ranges": [{"range": "192.168.22.17/28"}], }, + "ipv6": { + "is_public": False, + "slaac": [{"range": "1233::/64"}], + "ranges": [{"range": "9876::/64"}], + }, }, }