@@ -926,7 +926,7 @@ fn push_interface_validation_cte<'a>(
926
926
/// <time_created> AS time_created, <time_modified> AS time_modified,
927
927
/// NULL AS time_deleted, <instance_id> AS instance_id, <vpc_id> AS vpc_id,
928
928
/// <subnet_id> AS subnet_id, <mac> AS mac, <maybe IP allocation subquery>,
929
- /// <slot> AS slot, <is_primary> AS is_primary
929
+ /// <slot> AS slot, <is_primary> AS is_primary, <transit_ips> AS transit_ips
930
930
/// ```
931
931
///
932
932
/// Instance validation
@@ -1204,8 +1204,20 @@ impl QueryFragment<Pg> for InsertQuery {
1204
1204
} else {
1205
1205
select_from_cte ( out. reborrow ( ) , dsl:: slot:: NAME ) ?;
1206
1206
}
1207
+ out. push_sql ( " AS " ) ;
1208
+ out. push_identifier ( dsl:: slot:: NAME ) ?;
1207
1209
out. push_sql ( ", " ) ;
1210
+
1208
1211
select_from_cte ( out. reborrow ( ) , dsl:: is_primary:: NAME ) ?;
1212
+ out. push_sql ( " AS " ) ;
1213
+ out. push_identifier ( dsl:: is_primary:: NAME ) ?;
1214
+ out. push_sql ( ", " ) ;
1215
+
1216
+ out. push_bind_param :: < sql_types:: Array < sql_types:: Inet > , Vec < IpNetwork > > (
1217
+ & self . interface . transit_ips ,
1218
+ ) ?;
1219
+ out. push_sql ( " AS " ) ;
1220
+ out. push_identifier ( dsl:: transit_ips:: NAME ) ?;
1209
1221
1210
1222
Ok ( ( ) )
1211
1223
}
@@ -1260,6 +1272,8 @@ impl QueryFragment<Pg> for InsertQueryValues {
1260
1272
out. push_identifier ( dsl:: slot:: NAME ) ?;
1261
1273
out. push_sql ( ", " ) ;
1262
1274
out. push_identifier ( dsl:: is_primary:: NAME ) ?;
1275
+ out. push_sql ( ", " ) ;
1276
+ out. push_identifier ( dsl:: transit_ips:: NAME ) ?;
1263
1277
out. push_sql ( ") " ) ;
1264
1278
self . 0 . walk_ast ( out)
1265
1279
}
@@ -2191,6 +2205,7 @@ mod tests {
2191
2205
description : String :: from ( "description" ) ,
2192
2206
} ,
2193
2207
Some ( requested_ip) ,
2208
+ vec ! [ ] ,
2194
2209
)
2195
2210
. unwrap ( ) ;
2196
2211
let err = context. datastore ( )
@@ -2220,6 +2235,7 @@ mod tests {
2220
2235
description : String :: from ( "description" ) ,
2221
2236
} ,
2222
2237
Some ( requested_ip) ,
2238
+ vec ! [ ] ,
2223
2239
)
2224
2240
. unwrap ( ) ;
2225
2241
let inserted_interface = context
@@ -2252,6 +2268,7 @@ mod tests {
2252
2268
description : String :: from ( "description" ) ,
2253
2269
} ,
2254
2270
None ,
2271
+ vec ! [ ] ,
2255
2272
)
2256
2273
. unwrap ( ) ;
2257
2274
let err = context. datastore ( )
@@ -2290,6 +2307,7 @@ mod tests {
2290
2307
description : String :: from ( "description" ) ,
2291
2308
} ,
2292
2309
None ,
2310
+ vec ! [ ] ,
2293
2311
)
2294
2312
. unwrap ( ) ;
2295
2313
let inserted_interface = context
@@ -2334,6 +2352,7 @@ mod tests {
2334
2352
description : String :: from ( "description" ) ,
2335
2353
} ,
2336
2354
None ,
2355
+ vec ! [ ] ,
2337
2356
)
2338
2357
. unwrap ( ) ;
2339
2358
let inserted_interface = context
@@ -2353,6 +2372,7 @@ mod tests {
2353
2372
description : String :: from ( "description" ) ,
2354
2373
} ,
2355
2374
Some ( inserted_interface. ip . ip ( ) ) ,
2375
+ vec ! [ ] ,
2356
2376
)
2357
2377
. unwrap ( ) ;
2358
2378
let result = context
@@ -2601,6 +2621,7 @@ mod tests {
2601
2621
description : String :: from ( "description" ) ,
2602
2622
} ,
2603
2623
None ,
2624
+ vec ! [ ] ,
2604
2625
)
2605
2626
. unwrap ( ) ;
2606
2627
let _ = context
@@ -2620,6 +2641,7 @@ mod tests {
2620
2641
description : String :: from ( "description" ) ,
2621
2642
} ,
2622
2643
None ,
2644
+ vec ! [ ] ,
2623
2645
)
2624
2646
. unwrap ( ) ;
2625
2647
let result = context
@@ -2651,6 +2673,7 @@ mod tests {
2651
2673
description : String :: from ( "description" ) ,
2652
2674
} ,
2653
2675
None ,
2676
+ vec ! [ ] ,
2654
2677
)
2655
2678
. unwrap ( ) ;
2656
2679
let _ = context
@@ -2667,6 +2690,7 @@ mod tests {
2667
2690
description : String :: from ( "description" ) ,
2668
2691
} ,
2669
2692
None ,
2693
+ vec ! [ ] ,
2670
2694
)
2671
2695
. unwrap ( ) ;
2672
2696
let result = context
@@ -2695,6 +2719,7 @@ mod tests {
2695
2719
description : String :: from ( "description" ) ,
2696
2720
} ,
2697
2721
None ,
2722
+ vec ! [ ] ,
2698
2723
)
2699
2724
. unwrap ( ) ;
2700
2725
let _ = context
@@ -2737,6 +2762,7 @@ mod tests {
2737
2762
description : String :: from ( "description" ) ,
2738
2763
} ,
2739
2764
None ,
2765
+ vec ! [ ] ,
2740
2766
)
2741
2767
. unwrap ( ) ;
2742
2768
let _ = context
@@ -2755,6 +2781,7 @@ mod tests {
2755
2781
description : String :: from ( "description" ) ,
2756
2782
} ,
2757
2783
addr,
2784
+ vec ! [ ] ,
2758
2785
)
2759
2786
. unwrap ( ) ;
2760
2787
let result = context
@@ -2794,6 +2821,7 @@ mod tests {
2794
2821
description : String :: from ( "description" ) ,
2795
2822
} ,
2796
2823
None ,
2824
+ vec ! [ ] ,
2797
2825
)
2798
2826
. unwrap ( ) ;
2799
2827
let _ = context
@@ -2823,6 +2851,7 @@ mod tests {
2823
2851
description : String :: from ( "description" ) ,
2824
2852
} ,
2825
2853
None ,
2854
+ vec ! [ ] ,
2826
2855
)
2827
2856
. unwrap ( ) ;
2828
2857
let result = context
@@ -2856,6 +2885,7 @@ mod tests {
2856
2885
description : String :: from ( "description" ) ,
2857
2886
} ,
2858
2887
None ,
2888
+ vec ! [ ] ,
2859
2889
)
2860
2890
. unwrap ( ) ;
2861
2891
let result = context
@@ -2900,6 +2930,7 @@ mod tests {
2900
2930
"The random MAC address {:?} is not a valid {} address" ,
2901
2931
inserted. mac, kind,
2902
2932
) ;
2933
+ assert_eq ! ( inserted. transit_ips, incomplete. transit_ips) ;
2903
2934
}
2904
2935
2905
2936
// Test that we fail to insert an interface if there are no available slots
@@ -2924,6 +2955,7 @@ mod tests {
2924
2955
description : String :: from ( "description" ) ,
2925
2956
} ,
2926
2957
None ,
2958
+ vec ! [ ] ,
2927
2959
)
2928
2960
. unwrap ( ) ;
2929
2961
let inserted_interface = context
@@ -2959,6 +2991,7 @@ mod tests {
2959
2991
description : String :: from ( "description" ) ,
2960
2992
} ,
2961
2993
None ,
2994
+ vec ! [ ] ,
2962
2995
)
2963
2996
. unwrap ( ) ;
2964
2997
let result = context
@@ -2998,6 +3031,7 @@ mod tests {
2998
3031
description : String :: from ( "description" ) ,
2999
3032
} ,
3000
3033
None ,
3034
+ vec ! [ ] ,
3001
3035
)
3002
3036
. unwrap ( ) ;
3003
3037
let intf = context
@@ -3025,6 +3059,7 @@ mod tests {
3025
3059
description : String :: from ( "description" ) ,
3026
3060
} ,
3027
3061
None ,
3062
+ vec ! [ ] ,
3028
3063
)
3029
3064
. unwrap ( ) ;
3030
3065
let intf = context
@@ -3056,6 +3091,7 @@ mod tests {
3056
3091
description : String :: from ( "description" ) ,
3057
3092
} ,
3058
3093
None ,
3094
+ vec ! [ ] ,
3059
3095
)
3060
3096
. unwrap ( ) ;
3061
3097
let intf = context
@@ -3099,6 +3135,7 @@ mod tests {
3099
3135
description : String :: from ( "description" ) ,
3100
3136
} ,
3101
3137
Some ( IpAddr :: V4 ( addr) ) ,
3138
+ vec ! [ ] ,
3102
3139
)
3103
3140
. unwrap ( ) ;
3104
3141
let _ = context
@@ -3119,6 +3156,7 @@ mod tests {
3119
3156
description : String :: from ( "description" ) ,
3120
3157
} ,
3121
3158
None ,
3159
+ vec ! [ ] ,
3122
3160
)
3123
3161
. unwrap ( ) ;
3124
3162
@@ -3173,4 +3211,45 @@ mod tests {
3173
3211
"fd00::ffff:ffff:ffff:fffe" . parse:: <IpAddr >( ) . unwrap( ) ,
3174
3212
) ;
3175
3213
}
3214
+
3215
+ #[ tokio:: test]
3216
+ async fn test_insert_with_transit_ips ( ) {
3217
+ let context = TestContext :: new ( "test_insert_with_transit_ips" , 2 ) . await ;
3218
+ let instance = context. create_stopped_instance ( ) . await ;
3219
+ let instance_id = InstanceUuid :: from_untyped_uuid ( instance. id ( ) ) ;
3220
+
3221
+ // Create transit IPs to test with
3222
+ let transit_ips = vec ! [
3223
+ "10.0.0.0/24" . parse( ) . unwrap( ) ,
3224
+ "192.168.1.0/24" . parse( ) . unwrap( ) ,
3225
+ "172.16.0.0/16" . parse( ) . unwrap( ) ,
3226
+ ] ;
3227
+
3228
+ let interface = IncompleteNetworkInterface :: new_instance (
3229
+ Uuid :: new_v4 ( ) ,
3230
+ instance_id,
3231
+ context. net1 . subnets [ 0 ] . clone ( ) ,
3232
+ IdentityMetadataCreateParams {
3233
+ name : "interface-with-transit" . parse ( ) . unwrap ( ) ,
3234
+ description : String :: from ( "Test interface with transit IPs" ) ,
3235
+ } ,
3236
+ None , // Auto-assign IP
3237
+ transit_ips. clone ( ) ,
3238
+ )
3239
+ . unwrap ( ) ;
3240
+
3241
+ let inserted_interface = context
3242
+ . datastore ( )
3243
+ . instance_create_network_interface_raw (
3244
+ context. opctx ( ) ,
3245
+ interface. clone ( ) ,
3246
+ )
3247
+ . await
3248
+ . expect ( "Failed to insert interface with transit IPs" ) ;
3249
+
3250
+ // Verify the basic interface properties
3251
+ assert_interfaces_eq ( & interface, & inserted_interface. clone ( ) . into ( ) ) ;
3252
+
3253
+ context. success ( ) . await ;
3254
+ }
3176
3255
}
0 commit comments