@@ -22,6 +22,7 @@ use omicron_common::api::external::Error;
2222use omicron_common:: api:: external:: ListResultVec ;
2323use omicron_common:: api:: internal:: nexus:: HostIdentifier ;
2424use omicron_common:: api:: internal:: shared:: NetworkInterface ;
25+ use omicron_common:: api:: internal:: shared:: ResolvedVpcFirewallRule ;
2526use oxnet:: IpNet ;
2627use slog:: Logger ;
2728use slog:: debug;
@@ -48,7 +49,7 @@ pub async fn resolve_firewall_rules_for_sled_agent(
4849 vpc : & db:: model:: Vpc ,
4950 rules : & [ db:: model:: VpcFirewallRule ] ,
5051 log : & Logger ,
51- ) -> Result < Vec < sled_agent_client :: types :: ResolvedVpcFirewallRule > , Error > {
52+ ) -> Result < Vec < ResolvedVpcFirewallRule > , Error > {
5253 // Collect the names of instances, subnets, and VPCs that are either
5354 // targets or host filters. We have to find the sleds for all the
5455 // targets, and we'll need information about the IP addresses or
@@ -133,6 +134,7 @@ pub async fn resolve_firewall_rules_for_sled_agent(
133134 }
134135
135136 let mut vpc_interfaces: NicMap = HashMap :: new ( ) ;
137+ let mut vpc_vni_map = HashMap :: new ( ) ;
136138 for vpc_name in & vpcs {
137139 if let Ok ( ( .., authz_vpc) ) = LookupPath :: new ( opctx, datastore)
138140 . project_id ( vpc. project_id )
@@ -144,6 +146,7 @@ pub async fn resolve_firewall_rules_for_sled_agent(
144146 . derive_vpc_network_interface_info ( opctx, & authz_vpc)
145147 . await ?
146148 {
149+ vpc_vni_map. insert ( & vpc_name. 0 , iface. vni ) ;
147150 vpc_interfaces
148151 . entry ( vpc_name. 0 . clone ( ) )
149152 . or_insert_with ( Vec :: new)
@@ -328,7 +331,7 @@ pub async fn resolve_firewall_rules_for_sled_agent(
328331 AllowedSourceIps :: List ( list) => Some (
329332 list. iter ( )
330333 . copied ( )
331- . map ( |ip| HostIdentifier :: Ip ( ip ) . into ( ) )
334+ . map ( HostIdentifier :: Ip )
332335 . collect ( ) ,
333336 ) ,
334337 }
@@ -355,50 +358,40 @@ pub async fn resolve_firewall_rules_for_sled_agent(
355358 // There are host filters, but we don't need to apply the allowlist
356359 // to this VPC either, so insert the rules as-is.
357360 ( Some ( hosts) , None ) => {
358- let mut host_addrs = Vec :: with_capacity ( hosts. len ( ) ) ;
361+ let mut host_addrs = HashSet :: with_capacity ( hosts. len ( ) ) ;
359362 for host in hosts {
360363 match & host. 0 {
361364 external:: VpcFirewallRuleHostFilter :: Instance ( name) => {
362365 for interface in instance_interfaces
363366 . get ( & name)
364367 . unwrap_or ( & no_interfaces)
365368 {
366- host_addrs. push (
367- HostIdentifier :: Ip ( IpNet :: host_net (
368- interface. ip ,
369- ) )
370- . into ( ) ,
371- )
369+ host_addrs. insert ( HostIdentifier :: Ip (
370+ IpNet :: host_net ( interface. ip ) ,
371+ ) ) ;
372372 }
373373 }
374374 external:: VpcFirewallRuleHostFilter :: Subnet ( name) => {
375375 for subnet in subnet_networks
376376 . get ( name)
377377 . unwrap_or ( & no_networks)
378378 {
379- host_addrs. push (
380- HostIdentifier :: Ip ( IpNet :: from ( * subnet) )
381- . into ( ) ,
382- ) ;
379+ host_addrs. insert ( HostIdentifier :: Ip (
380+ IpNet :: from ( * subnet) ,
381+ ) ) ;
383382 }
384383 }
385384 external:: VpcFirewallRuleHostFilter :: Ip ( addr) => {
386- host_addrs. push (
387- HostIdentifier :: Ip ( IpNet :: host_net ( * addr) )
388- . into ( ) ,
389- )
385+ host_addrs. insert ( HostIdentifier :: Ip (
386+ IpNet :: host_net ( * addr) ,
387+ ) ) ;
390388 }
391389 external:: VpcFirewallRuleHostFilter :: IpNet ( net) => {
392- host_addrs. push ( HostIdentifier :: Ip ( * net) . into ( ) )
390+ host_addrs. insert ( HostIdentifier :: Ip ( * net) ) ;
393391 }
394392 external:: VpcFirewallRuleHostFilter :: Vpc ( name) => {
395- for interface in vpc_interfaces
396- . get ( name)
397- . unwrap_or ( & no_interfaces)
398- {
399- host_addrs. push (
400- HostIdentifier :: Vpc ( interface. vni ) . into ( ) ,
401- )
393+ if let Some ( vni) = vpc_vni_map. get ( name) {
394+ host_addrs. insert ( HostIdentifier :: Vpc ( * vni) ) ;
402395 }
403396 }
404397 }
@@ -414,25 +407,23 @@ pub async fn resolve_firewall_rules_for_sled_agent(
414407 let filter_ports = rule
415408 . filter_ports
416409 . as_ref ( )
417- . map ( |ports| ports. iter ( ) . map ( |v| v. 0 . into ( ) ) . collect ( ) ) ;
410+ . map ( |ports| ports. iter ( ) . map ( |v| v. 0 ) . collect ( ) ) ;
418411
419412 let filter_protocols = rule
420413 . filter_protocols
421414 . as_ref ( )
422- . map ( |protocols| protocols. iter ( ) . map ( |v| v. 0 . into ( ) ) . collect ( ) ) ;
415+ . map ( |protocols| protocols. iter ( ) . map ( |v| v. 0 ) . collect ( ) ) ;
423416
424- sled_agent_rules. push (
425- sled_agent_client:: types:: ResolvedVpcFirewallRule {
426- status : rule. status . 0 . into ( ) ,
427- direction : rule. direction . 0 . into ( ) ,
428- targets,
429- filter_hosts,
430- filter_ports,
431- filter_protocols,
432- action : rule. action . 0 . into ( ) ,
433- priority : rule. priority . 0 . 0 ,
434- } ,
435- ) ;
417+ sled_agent_rules. push ( ResolvedVpcFirewallRule {
418+ status : rule. status . 0 ,
419+ direction : rule. direction . 0 ,
420+ targets,
421+ filter_hosts,
422+ filter_ports,
423+ filter_protocols,
424+ action : rule. action . 0 ,
425+ priority : rule. priority . 0 ,
426+ } ) ;
436427 }
437428 debug ! (
438429 log,
0 commit comments