1717
1818package com .cloud .network .rules ;
1919
20+ import java .util .ArrayList ;
21+ import java .util .HashMap ;
2022import java .util .List ;
23+ import java .util .Map ;
2124
2225import org .apache .cloudstack .network .topology .NetworkTopologyVisitor ;
26+ import org .apache .log4j .Logger ;
2327
28+ import com .cloud .agent .api .routing .IpAssocVpcCommand ;
29+ import com .cloud .agent .api .routing .NetworkElementCommand ;
30+ import com .cloud .agent .api .to .IpAddressTO ;
31+ import com .cloud .agent .manager .Commands ;
32+ import com .cloud .dc .DataCenterVO ;
33+ import com .cloud .exception .ConcurrentOperationException ;
2434import com .cloud .exception .ResourceUnavailableException ;
2535import com .cloud .network .Network ;
2636import com .cloud .network .router .VirtualRouter ;
27- import com .cloud .network .vpc .NetworkACLItem ;
37+ import com .cloud .network .vpc .PrivateGateway ;
38+ import com .cloud .network .vpc .PrivateIpAddress ;
39+ import com .cloud .network .vpc .PrivateIpVO ;
40+ import com .cloud .user .Account ;
41+ import com .cloud .vm .NicProfile ;
2842
2943public class PrivateGatewayRules extends RuleApplier {
3044
31- private final List <? extends NetworkACLItem > rules ;
45+ private static final Logger s_logger = Logger .getLogger (PrivateGatewayRules .class );
46+
47+ private final PrivateGateway _privateGateway ;
48+
49+ private boolean _isAddOperation ;
50+ private NicProfile _nicProfile ;
3251
33- public PrivateGatewayRules (final Network network , final List <? extends NetworkACLItem > rules ) {
34- super (network );
35- this .rules = rules ;
52+ public PrivateGatewayRules (final PrivateGateway privateGateway ) {
53+ super (null );
54+ this ._privateGateway = privateGateway ;
3655 }
3756
3857 @ Override
3958 public boolean accept (final NetworkTopologyVisitor visitor , final VirtualRouter router ) throws ResourceUnavailableException {
4059 this ._router = router ;
4160
42- return visitor .visit (this );
61+ boolean result = false ;
62+ try {
63+ _network = _networkModel .getNetwork (_privateGateway .getNetworkId ());
64+ NicProfile requested = _vpcNetworkHelper .createPrivateNicProfileForGateway (_privateGateway );
65+
66+ if (!_networkHelper .checkRouterVersion (router )) {
67+ s_logger .warn ("Router requires upgrade. Unable to send command to router: " + router .getId ());
68+ return false ;
69+ }
70+ _nicProfile = _itMgr .addVmToNetwork (router , _network , requested );
71+
72+ //setup source nat
73+ if (_nicProfile != null ) {
74+ _isAddOperation = true ;
75+ //result = setupVpcPrivateNetwork(router, true, guestNic);
76+ result = visitor .visit (this );
77+ }
78+ } catch (Exception ex ) {
79+ s_logger .warn ("Failed to create private gateway " + _privateGateway + " on router " + router + " due to " , ex );
80+ } finally {
81+ if (!result ) {
82+ s_logger .debug ("Failed to setup gateway " + _privateGateway + " on router " + router + " with the source nat. Will now remove the gateway." );
83+ _isAddOperation = false ;
84+ boolean isRemoved = destroyPrivateGateway (visitor );
85+
86+ if (isRemoved ) {
87+ s_logger .debug ("Removed the gateway " + _privateGateway + " from router " + router + " as a part of cleanup" );
88+ } else {
89+ s_logger .warn ("Failed to remove the gateway " + _privateGateway + " from router " + router + " as a part of cleanup" );
90+ }
91+ }
92+ }
93+ return result ;
94+ }
95+
96+ public boolean isAddOperation () {
97+ return _isAddOperation ;
98+ }
99+
100+ public NicProfile getNicProfile () {
101+ return _nicProfile ;
102+ }
103+
104+ public PrivateIpVO retrivePrivateIP () {
105+ PrivateIpVO ipVO = _privateIpDao .findByIpAndSourceNetworkId (_nicProfile .getNetworkId (), _nicProfile .getIp4Address ());
106+ return ipVO ;
107+ }
108+
109+ public Network retrievePrivateNetwork () {
110+ // This network might be the same we have already as an instance in the RuleApplier super class.
111+ // Just doing this here, but will double check is remove if it's not needed.
112+ Network network = _networkDao .findById (_nicProfile .getNetworkId ());
113+ return network ;
43114 }
44115
45- public List <? extends NetworkACLItem > getRules () {
46- return rules ;
116+ protected boolean destroyPrivateGateway (final NetworkTopologyVisitor visitor ) throws ConcurrentOperationException , ResourceUnavailableException {
117+
118+ if (!_networkModel .isVmPartOfNetwork (_router .getId (), _privateGateway .getNetworkId ())) {
119+ s_logger .debug ("Router doesn't have nic for gateway " + _privateGateway + " so no need to removed it" );
120+ return true ;
121+ }
122+
123+ Network privateNetwork = _networkModel .getNetwork (_privateGateway .getNetworkId ());
124+
125+ s_logger .debug ("Releasing private ip for gateway " + _privateGateway + " from " + _router );
126+
127+ _nicProfile = _networkModel .getNicProfile (_router , privateNetwork .getId (), null );
128+ boolean result = visitor .visit (this );
129+ if (!result ) {
130+ s_logger .warn ("Failed to release private ip for gateway " + _privateGateway + " on router " + _router );
131+ return false ;
132+ }
133+
134+ //revoke network acl on the private gateway.
135+ if (!_networkACLMgr .revokeACLItemsForPrivateGw (_privateGateway )) {
136+ s_logger .debug ("Failed to delete network acl items on " + _privateGateway + " from router " + _router );
137+ return false ;
138+ }
139+
140+ s_logger .debug ("Removing router " + _router + " from private network " + privateNetwork + " as a part of delete private gateway" );
141+ result = result && _itMgr .removeVmFromNetwork (_router , privateNetwork , null );
142+ s_logger .debug ("Private gateawy " + _privateGateway + " is removed from router " + _router );
143+ return result ;
144+ }
145+
146+ public void createVpcAssociatePrivateIPCommands (final VirtualRouter router , final List <PrivateIpAddress > ips , final Commands cmds , final boolean add ) {
147+
148+ // Ensure that in multiple vlans case we first send all ip addresses of vlan1, then all ip addresses of vlan2, etc..
149+ Map <String , ArrayList <PrivateIpAddress >> vlanIpMap = new HashMap <String , ArrayList <PrivateIpAddress >>();
150+ for (final PrivateIpAddress ipAddress : ips ) {
151+ String vlanTag = ipAddress .getBroadcastUri ();
152+ ArrayList <PrivateIpAddress > ipList = vlanIpMap .get (vlanTag );
153+ if (ipList == null ) {
154+ ipList = new ArrayList <PrivateIpAddress >();
155+ }
156+
157+ ipList .add (ipAddress );
158+ vlanIpMap .put (vlanTag , ipList );
159+ }
160+
161+ for (Map .Entry <String , ArrayList <PrivateIpAddress >> vlanAndIp : vlanIpMap .entrySet ()) {
162+ List <PrivateIpAddress > ipAddrList = vlanAndIp .getValue ();
163+ IpAddressTO [] ipsToSend = new IpAddressTO [ipAddrList .size ()];
164+ int i = 0 ;
165+
166+ for (final PrivateIpAddress ipAddr : ipAddrList ) {
167+ Network network = _networkModel .getNetwork (ipAddr .getNetworkId ());
168+ IpAddressTO ip =
169+ new IpAddressTO (Account .ACCOUNT_ID_SYSTEM , ipAddr .getIpAddress (), add , false , ipAddr .getSourceNat (), ipAddr .getBroadcastUri (), ipAddr .getGateway (),
170+ ipAddr .getNetmask (), ipAddr .getMacAddress (), null , false );
171+
172+ ip .setTrafficType (network .getTrafficType ());
173+ ip .setNetworkName (_networkModel .getNetworkTag (router .getHypervisorType (), network ));
174+ ipsToSend [i ++] = ip ;
175+
176+ }
177+
178+ IpAssocVpcCommand cmd = new IpAssocVpcCommand (ipsToSend );
179+ cmd .setAccessDetail (NetworkElementCommand .ROUTER_IP , _routerControlHelper .getRouterControlIp (router .getId ()));
180+ cmd .setAccessDetail (NetworkElementCommand .ROUTER_GUEST_IP , _routerControlHelper .getRouterIpInNetwork (ipAddrList .get (0 ).getNetworkId (), router .getId ()));
181+ cmd .setAccessDetail (NetworkElementCommand .ROUTER_NAME , router .getInstanceName ());
182+ DataCenterVO dcVo = _dcDao .findById (router .getDataCenterId ());
183+ cmd .setAccessDetail (NetworkElementCommand .ZONE_NETWORK_TYPE , dcVo .getNetworkType ().toString ());
184+
185+ cmds .addCommand ("IPAssocVpcCommand" , cmd );
186+ }
47187 }
48188}
0 commit comments