Skip to content

Commit

Permalink
new: Add vpc field to Instance(...).ips property method result (#379
Browse files Browse the repository at this point in the history
)

* Support ipv4.vpc field in Instance.ips property method

* Update integration test

* Add null check
  • Loading branch information
lgarber-akamai authored Mar 18, 2024
1 parent 49dd2c6 commit 95d0b20
Show file tree
Hide file tree
Showing 5 changed files with 160 additions and 87 deletions.
7 changes: 6 additions & 1 deletion linode_api4/objects/linode.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
)
from linode_api4.objects.base import MappedObject
from linode_api4.objects.filtering import FilterableAttribute
from linode_api4.objects.networking import IPAddress, IPv6Range
from linode_api4.objects.networking import IPAddress, IPv6Range, VPCIPAddress
from linode_api4.objects.vpc import VPC, VPCSubnet
from linode_api4.paginated_list import PaginatedList

Expand Down Expand Up @@ -693,6 +693,10 @@ def ips(self):
i = IPAddress(self._client, c["address"], c)
reserved.append(i)

vpc = [
VPCIPAddress.from_json(v) for v in result["ipv4"].get("vpc", [])
]

slaac = IPAddress(
self._client,
result["ipv6"]["slaac"]["address"],
Expand All @@ -716,6 +720,7 @@ def ips(self):
"private": v4pri,
"shared": shared_ips,
"reserved": reserved,
"vpc": vpc,
},
"ipv6": {
"slaac": slaac,
Expand Down
27 changes: 27 additions & 0 deletions linode_api4/objects/networking.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from dataclasses import dataclass
from typing import Optional

from linode_api4.errors import UnexpectedResponseError
from linode_api4.objects import Base, DerivedBase, JSONObject, Property, Region
Expand Down Expand Up @@ -106,6 +107,32 @@ def to(self, linode):
return {"address": self.address, "linode_id": linode.id}


@dataclass
class VPCIPAddress(JSONObject):
"""
VPCIPAddress represents the IP address of a VPC.
NOTE: This is not implemented as a typical API object (Base) because VPC IPs
cannot be refreshed through the /networking/ips/{address} endpoint.
"""

address: str = ""
gateway: str = ""
region: str = ""
subnet_mask: str = ""
vpc_id: int = 0
subnet_id: int = 0
linode_id: int = 0
config_id: int = 0
interface_id: int = 0
prefix: int = 0

active: bool = False

address_range: Optional[str] = None
nat_1_1: Optional[str] = None


class VLAN(Base):
"""
.. note:: At this time, the Linode API only supports listing VLANs.
Expand Down
171 changes: 94 additions & 77 deletions test/fixtures/linode_instances_123_ips.json
Original file line number Diff line number Diff line change
@@ -1,89 +1,106 @@
{
"ipv4": {
"private": [
{
"address": "192.168.133.234",
"gateway": null,
"linode_id": 123,
"prefix": 17,
"public": false,
"rdns": null,
"region": "us-east",
"subnet_mask": "255.255.128.0",
"type": "ipv4"
}
],
"public": [
{
"address": "97.107.143.141",
"gateway": "97.107.143.1",
"linode_id": 123,
"prefix": 24,
"public": true,
"rdns": "test.example.org",
"region": "us-east",
"subnet_mask": "255.255.255.0",
"type": "ipv4"
}
],
"reserved": [
{
"address": "97.107.143.141",
"gateway": "97.107.143.1",
"linode_id": 123,
"prefix": 24,
"public": true,
"rdns": "test.example.org",
"region": "us-east",
"subnet_mask": "255.255.255.0",
"type": "ipv4"
}
],
"shared": [
{
"address": "97.107.143.141",
"gateway": "97.107.143.1",
"linode_id": 123,
"prefix": 24,
"public": true,
"rdns": "test.example.org",
"region": "us-east",
"subnet_mask": "255.255.255.0",
"type": "ipv4"
}
]
},
"ipv6": {
"global": [
{
"prefix": 124,
"range": "2600:3c01::2:5000:0",
"region": "us-east",
"route_target": "2600:3c01::2:5000:f"
}
],
"link_local": {
"address": "fe80::f03c:91ff:fe24:3a2f",
"gateway": "fe80::1",
"ipv4": {
"private": [
{
"address": "192.168.133.234",
"gateway": null,
"linode_id": 123,
"prefix": 64,
"prefix": 17,
"public": false,
"rdns": null,
"region": "us-east",
"subnet_mask": "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff",
"type": "ipv6"
},
"slaac": {
"address": "2600:3c03::f03c:91ff:fe24:3a2f",
"gateway": "fe80::1",
"subnet_mask": "255.255.128.0",
"type": "ipv4"
}
],
"public": [
{
"address": "97.107.143.141",
"gateway": "97.107.143.1",
"linode_id": 123,
"prefix": 64,
"prefix": 24,
"public": true,
"rdns": null,
"rdns": "test.example.org",
"region": "us-east",
"subnet_mask": "255.255.255.0",
"type": "ipv4"
}
],
"reserved": [
{
"address": "97.107.143.141",
"gateway": "97.107.143.1",
"linode_id": 123,
"prefix": 24,
"public": true,
"rdns": "test.example.org",
"region": "us-east",
"subnet_mask": "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff",
"type": "ipv6"
"subnet_mask": "255.255.255.0",
"type": "ipv4"
}
],
"vpc": [
{
"address": "10.0.0.2",
"address_range": null,
"vpc_id": 39246,
"subnet_id": 39388,
"region": "us-mia",
"linode_id": 55904908,
"config_id": 59036295,
"interface_id": 1186165,
"active": true,
"nat_1_1": "172.233.179.133",
"gateway": "10.0.0.1",
"prefix": 24,
"subnet_mask": "255.255.255.0"
}
],
"shared": [
{
"address": "97.107.143.141",
"gateway": "97.107.143.1",
"linode_id": 123,
"prefix": 24,
"public": true,
"rdns": "test.example.org",
"region": "us-east",
"subnet_mask": "255.255.255.0",
"type": "ipv4"
}
]
},
"ipv6": {
"global": [
{
"prefix": 124,
"range": "2600:3c01::2:5000:0",
"region": "us-east",
"route_target": "2600:3c01::2:5000:f"
}
],
"link_local": {
"address": "fe80::f03c:91ff:fe24:3a2f",
"gateway": "fe80::1",
"linode_id": 123,
"prefix": 64,
"public": false,
"rdns": null,
"region": "us-east",
"subnet_mask": "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff",
"type": "ipv6"
},
"slaac": {
"address": "2600:3c03::f03c:91ff:fe24:3a2f",
"gateway": "fe80::1",
"linode_id": 123,
"prefix": 64,
"public": true,
"rdns": null,
"region": "us-east",
"subnet_mask": "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff",
"type": "ipv6"
}
}
}

14 changes: 14 additions & 0 deletions test/integration/models/test_linode.py
Original file line number Diff line number Diff line change
Expand Up @@ -621,6 +621,20 @@ def test_create_vpc(
assert interface.ipv4.nat_1_1 == linode.ipv4[0]
assert interface.ip_ranges == ["10.0.0.5/32"]

vpc_ip = linode.ips.ipv4.vpc[0]
vpc_range_ip = linode.ips.ipv4.vpc[1]

assert vpc_ip.nat_1_1 == linode.ips.ipv4.public[0].address
assert vpc_ip.address_range is None
assert vpc_ip.vpc_id == vpc.id
assert vpc_ip.subnet_id == subnet.id
assert vpc_ip.config_id == config.id
assert vpc_ip.interface_id == interface.id
assert not vpc_ip.active

assert vpc_range_ip.address_range == "10.0.0.5/32"
assert not vpc_range_ip.active

def test_update_vpc(
self,
linode_for_network_interface_tests,
Expand Down
28 changes: 19 additions & 9 deletions test/unit/objects/linode_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -348,15 +348,25 @@ def test_ips(self):

ips = linode.ips

self.assertIsNotNone(ips.ipv4)
self.assertIsNotNone(ips.ipv6)
self.assertIsNotNone(ips.ipv4.public)
self.assertIsNotNone(ips.ipv4.private)
self.assertIsNotNone(ips.ipv4.shared)
self.assertIsNotNone(ips.ipv4.reserved)
self.assertIsNotNone(ips.ipv6.slaac)
self.assertIsNotNone(ips.ipv6.link_local)
self.assertIsNotNone(ips.ipv6.ranges)
assert ips.ipv4 is not None
assert ips.ipv6 is not None
assert ips.ipv4.public is not None
assert ips.ipv4.private is not None
assert ips.ipv4.shared is not None
assert ips.ipv4.reserved is not None
assert ips.ipv4.vpc is not None
assert ips.ipv6.slaac is not None
assert ips.ipv6.link_local is not None
assert ips.ipv6.ranges is not None

vpc_ip = ips.ipv4.vpc[0]
assert vpc_ip.nat_1_1 == "172.233.179.133"
assert vpc_ip.address_range == None
assert vpc_ip.vpc_id == 39246
assert vpc_ip.subnet_id == 39388
assert vpc_ip.config_id == 59036295
assert vpc_ip.interface_id == 1186165
assert vpc_ip.active

def test_initiate_migration(self):
"""
Expand Down

0 comments on commit 95d0b20

Please sign in to comment.