@@ -44,6 +44,7 @@ use nexus_test_utils::wait_for_producer;
4444use nexus_types:: external_api:: params:: IpAssignment ;
4545use nexus_types:: external_api:: params:: PrivateIpStackCreate ;
4646use nexus_types:: external_api:: params:: PrivateIpv4StackCreate ;
47+ use nexus_types:: external_api:: params:: PrivateIpv4StackUpdate ;
4748use nexus_types:: external_api:: params:: PrivateIpv6StackCreate ;
4849use nexus_types:: external_api:: params:: SshKeyCreate ;
4950use nexus_types:: external_api:: shared:: IpKind ;
@@ -3568,7 +3569,7 @@ async fn test_instance_update_network_interfaces(
35683569 description : Some ( new_description. clone ( ) ) ,
35693570 } ,
35703571 primary : false ,
3571- transit_ips : vec ! [ ] ,
3572+ .. Default :: default ( )
35723573 } ;
35733574
35743575 // Verify we fail to update the NIC when the instance is running
@@ -3655,7 +3656,7 @@ async fn test_instance_update_network_interfaces(
36553656 description : None ,
36563657 } ,
36573658 primary : true ,
3658- transit_ips : vec ! [ ] ,
3659+ .. Default :: default ( )
36593660 } ;
36603661 let updated_primary_iface1 = NexusRequest :: object_put (
36613662 client,
@@ -3753,7 +3754,7 @@ async fn test_instance_update_network_interfaces(
37533754 description : None ,
37543755 } ,
37553756 primary : true ,
3756- transit_ips : vec ! [ ] ,
3757+ .. Default :: default ( )
37573758 } ;
37583759 let new_primary_iface = NexusRequest :: object_put (
37593760 client,
@@ -3849,6 +3850,21 @@ async fn test_instance_update_network_interfaces(
38493850 assert_eq ! ( iface. identity. name, if_params[ 0 ] . identity. name) ;
38503851}
38513852
3853+ #[ nexus_test]
3854+ async fn cannot_make_new_primary_nic_lacking_ip_stack_for_external_addresses (
3855+ _cptestctx : & ControlPlaneTestContext ,
3856+ ) {
3857+ todo ! ( )
3858+ }
3859+
3860+
3861+ #[ nexus_test]
3862+ async fn cannot_remove_ip_stack_with_outstanding_external_ips_of_the_same_version (
3863+ _cptestctx : & ControlPlaneTestContext ,
3864+ ) {
3865+ todo ! ( )
3866+ }
3867+
38523868#[ nexus_test]
38533869async fn can_add_instance_network_interface_ip_stack (
38543870 _cptestctx : & ControlPlaneTestContext ,
@@ -3906,11 +3922,13 @@ async fn test_instance_update_network_interface_transit_ips(
39063922 description : None ,
39073923 } ,
39083924 primary : false ,
3909- transit_ips : vec ! [
3910- "10.0.0.0/9" . parse( ) . unwrap( ) ,
3911- "10.128.0.0/9" . parse( ) . unwrap( ) ,
3912- "1.1.1.1/32" . parse( ) . unwrap( ) ,
3913- ] ,
3925+ ipv4 : PrivateIpv4StackUpdate :: Modify {
3926+ transit_ips : vec ! [
3927+ "10.0.0.0/9" . parse( ) . unwrap( ) ,
3928+ "10.128.0.0/9" . parse( ) . unwrap( ) ,
3929+ "1.1.1.1/32" . parse( ) . unwrap( ) ,
3930+ ] ,
3931+ } ,
39143932 } ;
39153933
39163934 // Verify that a selection of transit IPs (mixture of private and global
@@ -3926,12 +3944,14 @@ async fn test_instance_update_network_interface_transit_ips(
39263944 // Non-canonical form (e.g., host identifier is nonzero) subnets should
39273945 // be rejected.
39283946 let with_extra_bits = params:: InstanceNetworkInterfaceUpdate {
3929- transit_ips : vec ! [
3930- "10.0.0.0/9" . parse( ) . unwrap( ) ,
3931- "10.128.0.0/9" . parse( ) . unwrap( ) ,
3932- // Invalid vvv
3933- "172.30.255.255/24" . parse( ) . unwrap( ) ,
3934- ] ,
3947+ ipv4 : PrivateIpv4StackUpdate :: Modify {
3948+ transit_ips : vec ! [
3949+ "10.0.0.0/9" . parse( ) . unwrap( ) ,
3950+ "10.128.0.0/9" . parse( ) . unwrap( ) ,
3951+ // Invalid vvv
3952+ "172.30.255.255/24" . parse( ) . unwrap( ) ,
3953+ ] ,
3954+ } ,
39353955 ..base_update. clone ( )
39363956 } ;
39373957 let err = object_put_error (
@@ -3948,11 +3968,13 @@ async fn test_instance_update_network_interface_transit_ips(
39483968
39493969 // Multicast IP blocks should be rejected.
39503970 let with_mc1 = params:: InstanceNetworkInterfaceUpdate {
3951- transit_ips : vec ! [
3952- "10.0.0.0/9" . parse( ) . unwrap( ) ,
3953- "10.128.0.0/9" . parse( ) . unwrap( ) ,
3954- "224.0.0.0/4" . parse( ) . unwrap( ) ,
3955- ] ,
3971+ ipv4 : PrivateIpv4StackUpdate :: Modify {
3972+ transit_ips : vec ! [
3973+ "10.0.0.0/9" . parse( ) . unwrap( ) ,
3974+ "10.128.0.0/9" . parse( ) . unwrap( ) ,
3975+ "224.0.0.0/4" . parse( ) . unwrap( ) ,
3976+ ] ,
3977+ } ,
39563978 ..base_update. clone ( )
39573979 } ;
39583980 let err = object_put_error (
@@ -3968,11 +3990,13 @@ async fn test_instance_update_network_interface_transit_ips(
39683990 ) ;
39693991
39703992 let with_mc2 = params:: InstanceNetworkInterfaceUpdate {
3971- transit_ips : vec ! [
3972- "10.0.0.0/9" . parse( ) . unwrap( ) ,
3973- "10.128.0.0/9" . parse( ) . unwrap( ) ,
3974- "230.20.20.128/32" . parse( ) . unwrap( ) ,
3975- ] ,
3993+ ipv4 : PrivateIpv4StackUpdate :: Modify {
3994+ transit_ips : vec ! [
3995+ "10.0.0.0/9" . parse( ) . unwrap( ) ,
3996+ "10.128.0.0/9" . parse( ) . unwrap( ) ,
3997+ "230.20.20.128/32" . parse( ) . unwrap( ) ,
3998+ ] ,
3999+ } ,
39764000 ..base_update. clone ( )
39774001 } ;
39784002 let err = object_put_error (
@@ -3989,11 +4013,13 @@ async fn test_instance_update_network_interface_transit_ips(
39894013
39904014 // Loopback ranges.
39914015 let with_lo1 = params:: InstanceNetworkInterfaceUpdate {
3992- transit_ips : vec ! [
3993- "10.0.0.0/9" . parse( ) . unwrap( ) ,
3994- "10.128.0.0/9" . parse( ) . unwrap( ) ,
3995- "127.42.77.0/24" . parse( ) . unwrap( ) ,
3996- ] ,
4016+ ipv4 : PrivateIpv4StackUpdate :: Modify {
4017+ transit_ips : vec ! [
4018+ "10.0.0.0/9" . parse( ) . unwrap( ) ,
4019+ "10.128.0.0/9" . parse( ) . unwrap( ) ,
4020+ "127.42.77.0/24" . parse( ) . unwrap( ) ,
4021+ ] ,
4022+ } ,
39974023 ..base_update. clone ( )
39984024 } ;
39994025 let err = object_put_error (
@@ -4009,11 +4035,13 @@ async fn test_instance_update_network_interface_transit_ips(
40094035 ) ;
40104036
40114037 let with_lo2 = params:: InstanceNetworkInterfaceUpdate {
4012- transit_ips : vec ! [
4013- "10.0.0.0/9" . parse( ) . unwrap( ) ,
4014- "10.128.0.0/9" . parse( ) . unwrap( ) ,
4015- "127.0.0.1/32" . parse( ) . unwrap( ) ,
4016- ] ,
4038+ ipv4 : PrivateIpv4StackUpdate :: Modify {
4039+ transit_ips : vec ! [
4040+ "10.0.0.0/9" . parse( ) . unwrap( ) ,
4041+ "10.128.0.0/9" . parse( ) . unwrap( ) ,
4042+ "127.0.0.1/32" . parse( ) . unwrap( ) ,
4043+ ] ,
4044+ } ,
40174045 ..base_update. clone ( )
40184046 } ;
40194047 let err = object_put_error (
@@ -4027,11 +4055,13 @@ async fn test_instance_update_network_interface_transit_ips(
40274055
40284056 // Overlapping IP ranges should be rejected, as should identical ranges.
40294057 let with_dup1 = params:: InstanceNetworkInterfaceUpdate {
4030- transit_ips : vec ! [
4031- "10.0.0.0/9" . parse( ) . unwrap( ) ,
4032- "10.128.0.0/9" . parse( ) . unwrap( ) ,
4033- "10.0.0.0/9" . parse( ) . unwrap( ) ,
4034- ] ,
4058+ ipv4 : PrivateIpv4StackUpdate :: Modify {
4059+ transit_ips : vec ! [
4060+ "10.0.0.0/9" . parse( ) . unwrap( ) ,
4061+ "10.128.0.0/9" . parse( ) . unwrap( ) ,
4062+ "10.0.0.0/9" . parse( ) . unwrap( ) ,
4063+ ] ,
4064+ } ,
40354065 ..base_update. clone ( )
40364066 } ;
40374067 let err = object_put_error (
@@ -4047,11 +4077,13 @@ async fn test_instance_update_network_interface_transit_ips(
40474077 ) ;
40484078
40494079 let with_dup2 = params:: InstanceNetworkInterfaceUpdate {
4050- transit_ips : vec ! [
4051- "10.0.0.0/9" . parse( ) . unwrap( ) ,
4052- "10.128.0.0/9" . parse( ) . unwrap( ) ,
4053- "10.128.32.0/24" . parse( ) . unwrap( ) ,
4054- ] ,
4080+ ipv4 : PrivateIpv4StackUpdate :: Modify {
4081+ transit_ips : vec ! [
4082+ "10.0.0.0/9" . parse( ) . unwrap( ) ,
4083+ "10.128.0.0/9" . parse( ) . unwrap( ) ,
4084+ "10.128.32.0/24" . parse( ) . unwrap( ) ,
4085+ ] ,
4086+ } ,
40554087 ..base_update. clone ( )
40564088 } ;
40574089 let err = object_put_error (
@@ -4068,10 +4100,12 @@ async fn test_instance_update_network_interface_transit_ips(
40684100
40694101 // Verify that we also catch more specific CIDRs appearing sooner in the list.
40704102 let with_dup3 = params:: InstanceNetworkInterfaceUpdate {
4071- transit_ips : vec ! [
4072- "10.20.20.0/30" . parse( ) . unwrap( ) ,
4073- "10.0.0.0/8" . parse( ) . unwrap( ) ,
4074- ] ,
4103+ ipv4 : PrivateIpv4StackUpdate :: Modify {
4104+ transit_ips : vec ! [
4105+ "10.20.20.0/30" . parse( ) . unwrap( ) ,
4106+ "10.0.0.0/8" . parse( ) . unwrap( ) ,
4107+ ] ,
4108+ } ,
40754109 ..base_update. clone ( )
40764110 } ;
40774111 let err = object_put_error (
@@ -4097,7 +4131,9 @@ async fn test_instance_update_network_interface_transit_ips(
40974131 // As a final sanity test, we can still effectively remove spoof checking
40984132 // using the unspecified network address.
40994133 let allow_all = params:: InstanceNetworkInterfaceUpdate {
4100- transit_ips : vec ! [ "0.0.0.0/0" . parse( ) . unwrap( ) ] ,
4134+ ipv4 : PrivateIpv4StackUpdate :: Modify {
4135+ transit_ips : vec ! [ "0.0.0.0/0" . parse( ) . unwrap( ) ] ,
4136+ } ,
41014137 ..base_update. clone ( )
41024138 } ;
41034139
0 commit comments