Skip to content

Commit 34fa79f

Browse files
committed
Add Nexus and database support for IPv6 NAT
- Renames NAT tables in the database to be IP-family agnostic - Renames NAT-enry-related types to be IP-family agnostic - Adds a generic `IpNet` database model type - Adds handling of IPv6 addresses for NAT entries, for both services and instances - Fixes #5090. Fixes #8749.
1 parent 19b92d1 commit 34fa79f

File tree

36 files changed

+672
-580
lines changed

36 files changed

+672
-580
lines changed

common/src/api/external/mod.rs

Lines changed: 43 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -901,6 +901,7 @@ impl JsonSchema for Hostname {
901901
// General types used to implement API resources
902902

903903
/// Identifies a type of API resource
904+
// NOTE: Please keep this enum in alphabetical order.
904905
#[derive(
905906
Clone,
906907
Copy,
@@ -920,76 +921,76 @@ pub enum ResourceType {
920921
AddressLotBlock,
921922
AffinityGroup,
922923
AffinityGroupMember,
923-
AntiAffinityGroup,
924-
AntiAffinityGroupMember,
925924
Alert,
926925
AlertReceiver,
927926
AllowList,
927+
AntiAffinityGroup,
928+
AntiAffinityGroupMember,
928929
BackgroundTask,
929-
BgpConfig,
930930
BgpAnnounceSet,
931+
BgpConfig,
931932
Blueprint,
932-
Fleet,
933-
Silo,
934-
SiloUser,
935-
SiloGroup,
936-
SiloQuotas,
937-
IdentityProvider,
938-
SamlIdentityProvider,
939-
SshKey,
940933
Certificate,
941934
ConsoleSession,
942-
DeviceAuthRequest,
943-
DeviceAccessToken,
944-
Project,
945935
Dataset,
936+
DeviceAccessToken,
937+
DeviceAuthRequest,
946938
Disk,
939+
Fleet,
940+
FloatingIp,
941+
IdentityProvider,
947942
Image,
948-
SiloImage,
949-
ProjectImage,
950943
Instance,
951-
LoopbackAddress,
952-
SiloAuthSettings,
953-
SwitchPortSettings,
954-
SupportBundle,
955-
IpPool,
956-
IpPoolResource,
957944
InstanceNetworkInterface,
958945
InternetGateway,
959-
InternetGatewayIpPool,
960946
InternetGatewayIpAddress,
947+
InternetGatewayIpPool,
948+
IpPool,
949+
IpPoolResource,
950+
LldpLinkConfig,
951+
LoopbackAddress,
952+
MetricProducer,
953+
NatEntry,
954+
Oximeter,
961955
PhysicalDisk,
956+
Probe,
957+
ProbeNetworkInterface,
958+
Project,
959+
ProjectImage,
962960
Rack,
961+
RoleBuiltin,
962+
RouterRoute,
963+
SagaDbg,
964+
SamlIdentityProvider,
963965
Service,
964966
ServiceNetworkInterface,
967+
Silo,
968+
SiloAuthSettings,
969+
SiloGroup,
970+
SiloImage,
971+
SiloQuotas,
972+
SiloUser,
965973
Sled,
966974
SledInstance,
967975
SledLedger,
968-
Switch,
969-
SagaDbg,
970976
Snapshot,
971-
Volume,
972-
Vpc,
973-
VpcFirewallRule,
974-
VpcSubnet,
975-
VpcRouter,
976-
RouterRoute,
977-
Oximeter,
978-
MetricProducer,
979-
RoleBuiltin,
980-
TufRepo,
977+
SshKey,
978+
SupportBundle,
979+
Switch,
980+
SwitchPort,
981+
SwitchPortSettings,
981982
TufArtifact,
983+
TufRepo,
982984
TufTrustRoot,
983-
SwitchPort,
984985
UserBuiltin,
985-
Zpool,
986986
Vmm,
987-
Ipv4NatEntry,
988-
FloatingIp,
989-
Probe,
990-
ProbeNetworkInterface,
991-
LldpLinkConfig,
987+
Volume,
988+
Vpc,
989+
VpcFirewallRule,
990+
VpcRouter,
991+
VpcSubnet,
992992
WebhookSecret,
993+
Zpool,
993994
}
994995

995996
// IDENTITY METADATA

dev-tools/omdb/src/bin/omdb/nexus.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -909,7 +909,7 @@ async fn cmd_nexus_background_tasks_show(
909909
"dns_config_external",
910910
"dns_servers_external",
911911
"dns_propagation_external",
912-
"nat_v4_garbage_collector",
912+
"nat_garbage_collector",
913913
"blueprint_loader",
914914
"blueprint_executor",
915915
] {

dev-tools/omdb/tests/env.out

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -128,8 +128,8 @@ task: "metrics_producer_gc"
128128
unregisters Oximeter metrics producers that have not renewed their lease
129129

130130

131-
task: "nat_v4_garbage_collector"
132-
prunes soft-deleted IPV4 NAT entries from ipv4_nat_entry table based on a
131+
task: "nat_garbage_collector"
132+
prunes soft-deleted NAT entries from nat_entry table based on a
133133
predetermined retention policy
134134

135135

@@ -336,8 +336,8 @@ task: "metrics_producer_gc"
336336
unregisters Oximeter metrics producers that have not renewed their lease
337337

338338

339-
task: "nat_v4_garbage_collector"
340-
prunes soft-deleted IPV4 NAT entries from ipv4_nat_entry table based on a
339+
task: "nat_garbage_collector"
340+
prunes soft-deleted NAT entries from nat_entry table based on a
341341
predetermined retention policy
342342

343343

@@ -531,8 +531,8 @@ task: "metrics_producer_gc"
531531
unregisters Oximeter metrics producers that have not renewed their lease
532532

533533

534-
task: "nat_v4_garbage_collector"
535-
prunes soft-deleted IPV4 NAT entries from ipv4_nat_entry table based on a
534+
task: "nat_garbage_collector"
535+
prunes soft-deleted NAT entries from nat_entry table based on a
536536
predetermined retention policy
537537

538538

dev-tools/omdb/tests/successes.out

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -340,8 +340,8 @@ task: "metrics_producer_gc"
340340
unregisters Oximeter metrics producers that have not renewed their lease
341341

342342

343-
task: "nat_v4_garbage_collector"
344-
prunes soft-deleted IPV4 NAT entries from ipv4_nat_entry table based on a
343+
task: "nat_garbage_collector"
344+
prunes soft-deleted NAT entries from nat_entry table based on a
345345
predetermined retention policy
346346

347347

@@ -487,7 +487,7 @@ task: "dns_propagation_external"
487487
[::1]:REDACTED_PORT success
488488

489489

490-
task: "nat_v4_garbage_collector"
490+
task: "nat_garbage_collector"
491491
configured period: every <REDACTED_DURATION>s
492492
currently executing: no
493493
last completed activation: <REDACTED ITERATIONS>, triggered by a periodic timer firing
@@ -1034,7 +1034,7 @@ task: "dns_propagation_external"
10341034
[::1]:REDACTED_PORT success
10351035

10361036

1037-
task: "nat_v4_garbage_collector"
1037+
task: "nat_garbage_collector"
10381038
configured period: every <REDACTED_DURATION>s
10391039
currently executing: no
10401040
last completed activation: <REDACTED ITERATIONS>, triggered by a periodic timer firing

nexus/db-model/src/ipnet.rs

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
// This Source Code Form is subject to the terms of the Mozilla Public
2+
// License, v. 2.0. If a copy of the MPL was not distributed with this
3+
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
4+
5+
use diesel::backend::Backend;
6+
use diesel::deserialize;
7+
use diesel::deserialize::FromSql;
8+
use diesel::pg::Pg;
9+
use diesel::serialize;
10+
use diesel::serialize::ToSql;
11+
use diesel::sql_types;
12+
use ipnetwork::IpNetwork;
13+
use serde::Deserialize;
14+
use serde::Serialize;
15+
16+
#[derive(
17+
Clone,
18+
Copy,
19+
Debug,
20+
Eq,
21+
PartialEq,
22+
AsExpression,
23+
FromSqlRow,
24+
Serialize,
25+
Deserialize,
26+
)]
27+
#[diesel(sql_type = sql_types::Inet)]
28+
pub enum IpNet {
29+
V4(crate::Ipv4Net),
30+
V6(crate::Ipv6Net),
31+
}
32+
33+
impl ::std::fmt::Display for IpNet {
34+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
35+
match self {
36+
IpNet::V4(inner) => inner.fmt(f),
37+
IpNet::V6(inner) => inner.fmt(f),
38+
}
39+
}
40+
}
41+
42+
impl From<IpNet> for ::std::net::IpAddr {
43+
fn from(value: IpNet) -> Self {
44+
match value {
45+
IpNet::V4(inner) => ::std::net::IpAddr::V4(inner.addr()),
46+
IpNet::V6(inner) => ::std::net::IpAddr::V6(inner.addr()),
47+
}
48+
}
49+
}
50+
51+
impl From<ipnetwork::IpNetwork> for IpNet {
52+
fn from(value: ipnetwork::IpNetwork) -> Self {
53+
match value {
54+
IpNetwork::V4(ipv4) => Self::from(oxnet::Ipv4Net::from(ipv4)),
55+
IpNetwork::V6(ipv6) => Self::from(oxnet::Ipv6Net::from(ipv6)),
56+
}
57+
}
58+
}
59+
60+
impl From<oxnet::Ipv4Net> for IpNet {
61+
fn from(value: oxnet::Ipv4Net) -> Self {
62+
Self::V4(crate::Ipv4Net::from(value))
63+
}
64+
}
65+
66+
impl From<oxnet::Ipv6Net> for IpNet {
67+
fn from(value: oxnet::Ipv6Net) -> Self {
68+
Self::V6(crate::Ipv6Net::from(value))
69+
}
70+
}
71+
72+
impl From<oxnet::IpNet> for IpNet {
73+
fn from(value: oxnet::IpNet) -> Self {
74+
match value {
75+
oxnet::IpNet::V4(ipv4_net) => {
76+
Self::V4(crate::Ipv4Net::from(ipv4_net))
77+
}
78+
oxnet::IpNet::V6(ipv6_net) => {
79+
Self::V6(crate::Ipv6Net::from(ipv6_net))
80+
}
81+
}
82+
}
83+
}
84+
85+
impl ToSql<sql_types::Inet, Pg> for IpNet {
86+
fn to_sql<'a>(
87+
&'a self,
88+
out: &mut serialize::Output<'a, '_, Pg>,
89+
) -> serialize::Result {
90+
let inner = match self {
91+
IpNet::V4(inner) => IpNetwork::V4(inner.0.into()),
92+
IpNet::V6(inner) => IpNetwork::V6(inner.0.into()),
93+
};
94+
<IpNetwork as ToSql<sql_types::Inet, Pg>>::to_sql(
95+
&inner,
96+
&mut out.reborrow(),
97+
)
98+
}
99+
}
100+
101+
impl<DB> FromSql<sql_types::Inet, DB> for IpNet
102+
where
103+
DB: Backend,
104+
IpNetwork: FromSql<sql_types::Inet, DB>,
105+
{
106+
fn from_sql(bytes: DB::RawValue<'_>) -> deserialize::Result<Self> {
107+
let inet = IpNetwork::from_sql(bytes)?;
108+
match inet {
109+
IpNetwork::V4(net) => Ok(Self::V4(crate::Ipv4Net(net.into()))),
110+
IpNetwork::V6(net) => Ok(Self::V6(crate::Ipv6Net(net.into()))),
111+
}
112+
}
113+
}

nexus/db-model/src/ipv4_nat_entry.rs

Lines changed: 0 additions & 76 deletions
This file was deleted.

0 commit comments

Comments
 (0)