3636import com .cloud .network .vpc .VpcManager ;
3737import com .cloud .network .vpc .VpcVO ;
3838import com .cloud .network .vpc .dao .NetworkACLDao ;
39+ import com .cloud .vm .VMInstanceVO ;
3940import com .cloud .vm .dao .VMInstanceDao ;
4041import com .cloud .vm .Nic ;
4142import com .cloud .vm .NicVO ;
8081import com .cloud .utils .component .ManagerBase ;
8182import com .cloud .utils .concurrency .NamedThreadFactory ;
8283import com .cloud .utils .db .DB ;
84+ import com .cloud .utils .fsm .StateListener ;
8385import com .cloud .utils .exception .CloudRuntimeException ;
8486import com .cloud .vm .dao .DomainRouterDao ;
8587import com .cloud .vm .dao .NicDao ;
8688
8789@ Component
8890@ Local (value = {OvsTunnelManager .class })
89- public class OvsTunnelManagerImpl extends ManagerBase implements OvsTunnelManager {
91+ public class OvsTunnelManagerImpl extends ManagerBase implements OvsTunnelManager , StateListener < VirtualMachine . State , VirtualMachine . Event , VirtualMachine > {
9092 public static final Logger s_logger = Logger .getLogger (OvsTunnelManagerImpl .class .getName ());
9193
9294 // boolean _isEnabled;
@@ -133,7 +135,12 @@ public boolean configure(String name, Map<String, Object> params)
133135 _executorPool = Executors .newScheduledThreadPool (10 , new NamedThreadFactory ("OVS" ));
134136 _cleanupExecutor = Executors .newScheduledThreadPool (1 , new NamedThreadFactory ("OVS-Cleanup" ));
135137
138+ // register for network ACL updated for a VPC.
136139 _messageBus .subscribe ("Network_ACL_Replaced" , new NetworkAclEventsSubscriber ());
140+
141+ // register for VM state transition updates
142+ VirtualMachine .State .getStateMachine ().registerListener (this );
143+
137144 return true ;
138145 }
139146
@@ -540,92 +547,6 @@ private String generateBridgeNameForVpc(long vpcId) {
540547 return "OVS-DR-VPC-Bridge" + vpcId ;
541548 }
542549
543- public boolean sendVpcTopologyChangeUpdate (OvsVpcPhysicalTopologyConfigCommand updateCmd , long hostId , String bridgeName ) {
544- try {
545- s_logger .debug ("Sending VPC topology update to the host " + hostId );
546- updateCmd .setHostId (hostId );
547- updateCmd .setBridgeName (bridgeName );
548- Answer ans = _agentMgr .send (hostId , updateCmd );
549- if (ans .getResult ()) {
550- s_logger .debug ("Successfully updated the host " + hostId + " with latest VPC topology." );
551- return true ;
552- } else {
553- s_logger .debug ("Failed to update the host " + hostId + " with latest VPC topology." );
554- return false ;
555- }
556- } catch (Exception e ) {
557- s_logger .debug ("Failed to updated the host " + hostId + " with latest VPC topology." );
558- return false ;
559- }
560- }
561-
562- OvsVpcPhysicalTopologyConfigCommand prepareVpcTopologyUpdate (long vpcId ) {
563- VpcVO vpc = _vpcDao .findById (vpcId );
564- assert (vpc != null ): "invalid vpc id" ;
565-
566- List <? extends Network > vpcNetworks = _vpcMgr .getVpcNetworks (vpcId );
567- List <Long > hostIds = _ovsNetworkToplogyGuru .getVpcSpannedHosts (vpcId );
568- List <Long > vmIds = _ovsNetworkToplogyGuru .getAllActiveVmsInVpc (vpcId );
569-
570- List <OvsVpcPhysicalTopologyConfigCommand .Host > hosts = new ArrayList <>();
571- List <OvsVpcPhysicalTopologyConfigCommand .Tier > tiers = new ArrayList <>();
572- List <OvsVpcPhysicalTopologyConfigCommand .Vm > vms = new ArrayList <>();
573-
574- for (Long hostId : hostIds ) {
575- HostVO hostDetails = _hostDao .findById (hostId );
576- String remoteIp = null ;
577- for (Network network : vpcNetworks ) {
578- try {
579- remoteIp = getGreEndpointIP (hostDetails , network );
580- } catch (Exception e ) {
581-
582- }
583- }
584- OvsVpcPhysicalTopologyConfigCommand .Host host = new OvsVpcPhysicalTopologyConfigCommand .Host (hostId , remoteIp );
585- hosts .add (host );
586- }
587-
588- for (Network network : vpcNetworks ) {
589- String key = network .getBroadcastUri ().getAuthority ();
590- long gre_key ;
591- if (key .contains ("." )) {
592- String [] parts = key .split ("\\ ." );
593- gre_key = Long .parseLong (parts [1 ]);
594- } else {
595- try {
596- gre_key = Long .parseLong (BroadcastDomainType .getValue (key ));
597- } catch (Exception e ) {
598- return null ;
599- }
600- }
601- NicVO nic = _nicDao .findByIp4AddressAndNetworkId (network .getGateway (), network .getId ());
602- OvsVpcPhysicalTopologyConfigCommand .Tier tier = new OvsVpcPhysicalTopologyConfigCommand .Tier (gre_key ,
603- network .getUuid (), network .getGateway (), nic .getMacAddress (), network .getCidr ());
604- tiers .add (tier );
605- }
606-
607- for (long vmId : vmIds ) {
608- VirtualMachine vmInstance = _vmInstanceDao .findById (vmId );
609- List <OvsVpcPhysicalTopologyConfigCommand .Nic > vmNics = new ArrayList <OvsVpcPhysicalTopologyConfigCommand .Nic >();
610- for (Nic vmNic :_nicDao .listByVmId (vmId )) {
611- Network network = _networkDao .findById (vmNic .getNetworkId ());
612- if (network .getTrafficType () == TrafficType .Guest ) {
613- OvsVpcPhysicalTopologyConfigCommand .Nic nic = new OvsVpcPhysicalTopologyConfigCommand .Nic (
614- vmNic .getIp4Address (), vmNic .getMacAddress (), ((Long )vmNic .getNetworkId ()).toString ());
615- vmNics .add (nic );
616- }
617- }
618- OvsVpcPhysicalTopologyConfigCommand .Vm vm = new OvsVpcPhysicalTopologyConfigCommand .Vm (
619- vmInstance .getHostId (), vmNics .toArray (new OvsVpcPhysicalTopologyConfigCommand .Nic [vmNics .size ()]));
620- vms .add (vm );
621- }
622- return new OvsVpcPhysicalTopologyConfigCommand (
623- hosts .toArray (new OvsVpcPhysicalTopologyConfigCommand .Host [hosts .size ()]),
624- tiers .toArray (new OvsVpcPhysicalTopologyConfigCommand .Tier [tiers .size ()]),
625- vms .toArray (new OvsVpcPhysicalTopologyConfigCommand .Vm [vms .size ()]),
626- vpc .getCidr ());
627- }
628-
629550 @ DB
630551 protected void checkAndCreateVpcTunnelNetworks (Host host , long vpcId ) {
631552
@@ -731,16 +652,158 @@ protected void checkAndCreateVpcTunnelNetworks(Host host, long vpcId) {
731652 s_logger .warn ("Ovs Tunnel network created tunnel failed" , e );
732653 }
733654 }
655+ }
656+
657+ @ Override
658+ public boolean preStateTransitionEvent (VirtualMachine .State oldState ,
659+ VirtualMachine .Event event , VirtualMachine .State newState ,
660+ VirtualMachine vo , boolean status , Object opaque ) {
661+ return true ;
662+ }
663+
664+ @ Override
665+ public boolean postStateTransitionEvent (VirtualMachine .State oldState , VirtualMachine .Event event ,
666+ VirtualMachine .State newState , VirtualMachine vm ,
667+ boolean status , Object opaque ) {
668+
669+ if (!status ) {
670+ return false ;
671+ }
672+
673+ if (VirtualMachine .State .isVmStarted (oldState , event , newState )) {
674+ if (s_logger .isTraceEnabled ()) {
675+ s_logger .trace ("Security Group Mgr: handling start of vm id" + vm .getId ());
676+ }
677+ handleVmStateChange ((VMInstanceVO )vm );
678+ } else if (VirtualMachine .State .isVmStopped (oldState , event , newState )) {
679+ if (s_logger .isTraceEnabled ()) {
680+ s_logger .trace ("Security Group Mgr: handling stop of vm id" + vm .getId ());
681+ }
682+ handleVmStateChange ((VMInstanceVO )vm );
683+ } else if (VirtualMachine .State .isVmMigrated (oldState , event , newState )) {
684+ if (s_logger .isTraceEnabled ()) {
685+ s_logger .trace ("Security Group Mgr: handling migration of vm id" + vm .getId ());
686+ }
687+ handleVmStateChange ((VMInstanceVO )vm );
688+ }
689+
690+ return true ;
691+ }
692+
693+ public void handleVmStateChange (VMInstanceVO vm ) {
694+
695+ // get the VPC's impacted with the VM start
696+ List <Long > vpcIds = _ovsNetworkToplogyGuru .getVpcIdsVmIsPartOf (vm .getId ());
697+ if (vpcIds == null || vpcIds .isEmpty ()) {
698+ return ;
699+ }
700+
701+ for (Long vpcId : vpcIds ) {
702+ VpcVO vpc = _vpcDao .findById (vpcId );
703+ if (vpc == null || !vpc .usesDistributedRouter ()) {
704+ return ;
705+ }
706+
707+ // get the list of hosts on which VPC spans (i.e hosts that need to be aware of VPC topology change update)
708+ List <Long > vpcSpannedHostIds = _ovsNetworkToplogyGuru .getVpcSpannedHosts (vpcId );
709+ String bridgeName =generateBridgeNameForVpc (vpcId );
734710
735- OvsVpcPhysicalTopologyConfigCommand topologyConfigCommand = prepareVpcTopologyUpdate (vpcId );
736- for (Long id : vpcSpannedHostIds ) {
737- if (!sendVpcTopologyChangeUpdate (topologyConfigCommand , id , bridgeName )) {
738- s_logger .debug ("Failed to send VPC topology change update to host : " + id + ". Moving on with rest of" +
739- "the host update." );
711+ OvsVpcPhysicalTopologyConfigCommand topologyConfigCommand = prepareVpcTopologyUpdate (vpcId );
712+ for (Long id : vpcSpannedHostIds ) {
713+ if (!sendVpcTopologyChangeUpdate (topologyConfigCommand , id , bridgeName )) {
714+ s_logger .debug ("Failed to send VPC topology change update to host : " + id + ". Moving on " +
715+ "with rest of the host update." );
716+ }
717+ }
718+ }
719+ }
720+
721+ public boolean sendVpcTopologyChangeUpdate (OvsVpcPhysicalTopologyConfigCommand updateCmd , long hostId , String bridgeName ) {
722+ try {
723+ s_logger .debug ("Sending VPC topology update to the host " + hostId );
724+ updateCmd .setHostId (hostId );
725+ updateCmd .setBridgeName (bridgeName );
726+ Answer ans = _agentMgr .send (hostId , updateCmd );
727+ if (ans .getResult ()) {
728+ s_logger .debug ("Successfully updated the host " + hostId + " with latest VPC topology." );
729+ return true ;
730+ } else {
731+ s_logger .debug ("Failed to update the host " + hostId + " with latest VPC topology." );
732+ return false ;
740733 }
734+ } catch (Exception e ) {
735+ s_logger .debug ("Failed to updated the host " + hostId + " with latest VPC topology." );
736+ return false ;
741737 }
742738 }
743739
740+ OvsVpcPhysicalTopologyConfigCommand prepareVpcTopologyUpdate (long vpcId ) {
741+ VpcVO vpc = _vpcDao .findById (vpcId );
742+ assert (vpc != null ): "invalid vpc id" ;
743+
744+ List <? extends Network > vpcNetworks = _vpcMgr .getVpcNetworks (vpcId );
745+ List <Long > hostIds = _ovsNetworkToplogyGuru .getVpcSpannedHosts (vpcId );
746+ List <Long > vmIds = _ovsNetworkToplogyGuru .getAllActiveVmsInVpc (vpcId );
747+
748+ List <OvsVpcPhysicalTopologyConfigCommand .Host > hosts = new ArrayList <>();
749+ List <OvsVpcPhysicalTopologyConfigCommand .Tier > tiers = new ArrayList <>();
750+ List <OvsVpcPhysicalTopologyConfigCommand .Vm > vms = new ArrayList <>();
751+
752+ for (Long hostId : hostIds ) {
753+ HostVO hostDetails = _hostDao .findById (hostId );
754+ String remoteIp = null ;
755+ for (Network network : vpcNetworks ) {
756+ try {
757+ remoteIp = getGreEndpointIP (hostDetails , network );
758+ } catch (Exception e ) {
759+
760+ }
761+ }
762+ OvsVpcPhysicalTopologyConfigCommand .Host host = new OvsVpcPhysicalTopologyConfigCommand .Host (hostId , remoteIp );
763+ hosts .add (host );
764+ }
765+
766+ for (Network network : vpcNetworks ) {
767+ String key = network .getBroadcastUri ().getAuthority ();
768+ long gre_key ;
769+ if (key .contains ("." )) {
770+ String [] parts = key .split ("\\ ." );
771+ gre_key = Long .parseLong (parts [1 ]);
772+ } else {
773+ try {
774+ gre_key = Long .parseLong (BroadcastDomainType .getValue (key ));
775+ } catch (Exception e ) {
776+ return null ;
777+ }
778+ }
779+ NicVO nic = _nicDao .findByIp4AddressAndNetworkId (network .getGateway (), network .getId ());
780+ OvsVpcPhysicalTopologyConfigCommand .Tier tier = new OvsVpcPhysicalTopologyConfigCommand .Tier (gre_key ,
781+ network .getUuid (), network .getGateway (), nic .getMacAddress (), network .getCidr ());
782+ tiers .add (tier );
783+ }
784+
785+ for (long vmId : vmIds ) {
786+ VirtualMachine vmInstance = _vmInstanceDao .findById (vmId );
787+ List <OvsVpcPhysicalTopologyConfigCommand .Nic > vmNics = new ArrayList <OvsVpcPhysicalTopologyConfigCommand .Nic >();
788+ for (Nic vmNic :_nicDao .listByVmId (vmId )) {
789+ Network network = _networkDao .findById (vmNic .getNetworkId ());
790+ if (network .getTrafficType () == TrafficType .Guest ) {
791+ OvsVpcPhysicalTopologyConfigCommand .Nic nic = new OvsVpcPhysicalTopologyConfigCommand .Nic (
792+ vmNic .getIp4Address (), vmNic .getMacAddress (), network .getUuid ());
793+ vmNics .add (nic );
794+ }
795+ }
796+ OvsVpcPhysicalTopologyConfigCommand .Vm vm = new OvsVpcPhysicalTopologyConfigCommand .Vm (
797+ vmInstance .getHostId (), vmNics .toArray (new OvsVpcPhysicalTopologyConfigCommand .Nic [vmNics .size ()]));
798+ vms .add (vm );
799+ }
800+ return new OvsVpcPhysicalTopologyConfigCommand (
801+ hosts .toArray (new OvsVpcPhysicalTopologyConfigCommand .Host [hosts .size ()]),
802+ tiers .toArray (new OvsVpcPhysicalTopologyConfigCommand .Tier [tiers .size ()]),
803+ vms .toArray (new OvsVpcPhysicalTopologyConfigCommand .Vm [vms .size ()]),
804+ vpc .getCidr ());
805+ }
806+
744807 // Subscriber to ACL replace events. On acl replace event, if the vpc is enabled for distributed routing
745808 // send the ACL update to all the hosts on which VPC spans
746809 public class NetworkAclEventsSubscriber implements MessageSubscriber {
@@ -755,14 +818,14 @@ public void onPublishMessage(String senderAddress, String subject, Object args)
755818 for (Long id : vpcSpannedHostIds ) {
756819 if (!sendVpcRoutingPolicyChangeUpdate (cmd , id , bridgeName )) {
757820 s_logger .debug ("Failed to send VPC routing policy change update to host : " + id +
758- ". Moving on with rest of the host updates." );
821+ ". But moving on with sending the host updates to the rest of the hosts ." );
759822 }
760823 }
761824 }
762825 }
763826 }
764827
765- OvsVpcRoutingPolicyConfigCommand prepareVpcRoutingPolicyUpdate (long vpcId ) {
828+ private OvsVpcRoutingPolicyConfigCommand prepareVpcRoutingPolicyUpdate (long vpcId ) {
766829 VpcVO vpc = _vpcDao .findById (vpcId );
767830 assert (vpc != null ): "invalid vpc id" ;
768831 List <OvsVpcRoutingPolicyConfigCommand .Acl > acls = new ArrayList <>();
0 commit comments