cloudstack-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From h...@apache.org
Subject [4/4] git commit: Wired up the creation of the SourceNat router in the element
Date Fri, 28 Sep 2012 05:17:05 GMT
Wired up the creation of the SourceNat router in the element

Project: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/commit/fe997651
Tree: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/tree/fe997651
Diff: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/diff/fe997651

Branch: refs/heads/nicira-l3support
Commit: fe997651a6da0d3883cf54b0c32bf5f975b3fce0
Parents: bfc8da1
Author: Hugo Trippaers <htrippaers@schubergphilis.com>
Authored: Thu Sep 27 15:34:53 2012 -0700
Committer: Hugo Trippaers <htrippaers@schubergphilis.com>
Committed: Thu Sep 27 15:34:53 2012 -0700

----------------------------------------------------------------------
 .../cloud/agent/api/CreateLogicalRouterAnswer.java |   40 ++++
 .../agent/api/CreateLogicalRouterCommand.java      |  115 +++++++++++
 .../cloud/api/commands/AddNiciraNvpDeviceCmd.java  |    2 +
 .../cloud/network/element/NiciraNvpElement.java    |  159 ++++++++++++++-
 .../cloud/network/nicira/L3GatewayAttachment.java  |   10 +-
 .../com/cloud/network/nicira/PatchAttachment.java  |   39 ++++
 .../com/cloud/network/nicira/RouterNextHop.java    |    4 +
 .../cloud/network/resource/NiciraNvpResource.java  |  109 ++++++++++
 8 files changed, 461 insertions(+), 17 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/fe997651/plugins/network-elements/nicira-nvp/src/com/cloud/agent/api/CreateLogicalRouterAnswer.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/nicira-nvp/src/com/cloud/agent/api/CreateLogicalRouterAnswer.java
b/plugins/network-elements/nicira-nvp/src/com/cloud/agent/api/CreateLogicalRouterAnswer.java
new file mode 100644
index 0000000..3337e92
--- /dev/null
+++ b/plugins/network-elements/nicira-nvp/src/com/cloud/agent/api/CreateLogicalRouterAnswer.java
@@ -0,0 +1,40 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+// 
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package com.cloud.agent.api;
+
+/**
+ * 
+ */
+public class CreateLogicalRouterAnswer extends Answer {
+
+    private String _logicalRouterUuid;
+
+    public CreateLogicalRouterAnswer(Command command, boolean success,
+            String details, String logicalRouterUuid) {
+        super(command, success, details);
+        this._logicalRouterUuid = logicalRouterUuid;
+    }
+    
+    public CreateLogicalRouterAnswer(Command command, Exception e) {
+        super(command, e);
+    }
+
+    public String getLogicalSwitchUuid() {
+        return _logicalRouterUuid;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/fe997651/plugins/network-elements/nicira-nvp/src/com/cloud/agent/api/CreateLogicalRouterCommand.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/nicira-nvp/src/com/cloud/agent/api/CreateLogicalRouterCommand.java
b/plugins/network-elements/nicira-nvp/src/com/cloud/agent/api/CreateLogicalRouterCommand.java
new file mode 100644
index 0000000..57440df
--- /dev/null
+++ b/plugins/network-elements/nicira-nvp/src/com/cloud/agent/api/CreateLogicalRouterCommand.java
@@ -0,0 +1,115 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+// 
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package com.cloud.agent.api;
+
+/**
+ * 
+ */
+public class CreateLogicalRouterCommand extends Command {
+	private String _gatewayServiceUuid;
+	private String _logicalSwitchUuid;
+	private long _vlanId;
+	private String _name;
+	private String _ownerName;
+	private String _publicIpCidr;
+	private String _publicNextHop;
+	private String _internalIpCidr;
+	
+	public CreateLogicalRouterCommand(String gatewayServiceUuid, long vlanId,
+			String logicalSwitchUuid, String name, 
+			String publicIpCidr, String publicNextHop, 
+			String internalIpCidr, String ownerName) {
+		super();
+		this._gatewayServiceUuid = gatewayServiceUuid;
+		this._logicalSwitchUuid = logicalSwitchUuid;
+		this._vlanId = vlanId;
+		this._name = name;
+		this._ownerName = ownerName;
+		this._publicIpCidr = publicIpCidr;
+		this._publicNextHop = publicNextHop;
+		this._internalIpCidr = internalIpCidr;
+	}
+	
+    @Override
+    public boolean executeInSequence() {
+        return false;
+    }
+
+	public String getGatewayServiceUuid() {
+		return _gatewayServiceUuid;
+	}
+
+	public void setGatewayServiceUuid(String gatewayServiceUuid) {
+		this._gatewayServiceUuid = gatewayServiceUuid;
+	}
+	
+	public String getLogicalSwitchUuid() {
+		return _logicalSwitchUuid;
+	}
+	
+	public void setLogicalSwitchUuid(String logicalSwitchUuid) {
+		_logicalSwitchUuid = logicalSwitchUuid;
+	}
+
+	public long getVlanId() {
+		return _vlanId;
+	}
+
+	public void setVlanId(long vlanId) {
+		this._vlanId = vlanId;
+	}
+
+	public String getName() {
+		return _name;
+	}
+
+	public void setName(String name) {
+		this._name = name;
+	}
+
+	public String getOwnerName() {
+		return _ownerName;
+	}
+
+	public void setOwnerName(String ownerName) {
+		this._ownerName = ownerName;
+	}
+
+	public String getPublicIpCidr() {
+		return _publicIpCidr;
+	}
+
+	public void setPublicIpCidr(String publicIpCidr) {
+		this._publicIpCidr = publicIpCidr;
+	}
+
+	public String getInternalIpCidr() {
+		return _internalIpCidr;
+	}
+
+	public void setInternalIpCidr(String internalIpCidr) {
+		this._internalIpCidr = internalIpCidr;
+	}
+	
+	public String getPublicNextHop() {
+		return _publicNextHop;
+	}
+	
+	public void setPublicNextHop(String publicNextHop) {
+		this._publicNextHop = publicNextHop;
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/fe997651/plugins/network-elements/nicira-nvp/src/com/cloud/api/commands/AddNiciraNvpDeviceCmd.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/nicira-nvp/src/com/cloud/api/commands/AddNiciraNvpDeviceCmd.java
b/plugins/network-elements/nicira-nvp/src/com/cloud/api/commands/AddNiciraNvpDeviceCmd.java
index 6eac21f..28bc1fc 100644
--- a/plugins/network-elements/nicira-nvp/src/com/cloud/api/commands/AddNiciraNvpDeviceCmd.java
+++ b/plugins/network-elements/nicira-nvp/src/com/cloud/api/commands/AddNiciraNvpDeviceCmd.java
@@ -67,6 +67,8 @@ public class AddNiciraNvpDeviceCmd extends BaseCmd {
     @Parameter(name=ApiConstants.NICIRA_NVP_TRANSPORT_ZONE_UUID, type=CommandType.STRING,
required = true, description="The Transportzone UUID configured on the Nicira Controller")
     private String transportzoneuuid;
     
+    //FIXME add optional gateway service uuid
+    
     /////////////////////////////////////////////////////
     /////////////////// Accessors ///////////////////////
     /////////////////////////////////////////////////////

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/fe997651/plugins/network-elements/nicira-nvp/src/com/cloud/network/element/NiciraNvpElement.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/nicira-nvp/src/com/cloud/network/element/NiciraNvpElement.java
b/plugins/network-elements/nicira-nvp/src/com/cloud/network/element/NiciraNvpElement.java
index 1fcccdb..638ed8a 100644
--- a/plugins/network-elements/nicira-nvp/src/com/cloud/network/element/NiciraNvpElement.java
+++ b/plugins/network-elements/nicira-nvp/src/com/cloud/network/element/NiciraNvpElement.java
@@ -47,6 +47,8 @@ import javax.naming.ConfigurationException;
 import org.apache.log4j.Logger;
 
 import com.cloud.agent.AgentManager;
+import com.cloud.agent.api.CreateLogicalRouterAnswer;
+import com.cloud.agent.api.CreateLogicalRouterCommand;
 import com.cloud.agent.api.CreateLogicalSwitchPortAnswer;
 import com.cloud.agent.api.CreateLogicalSwitchPortCommand;
 import com.cloud.agent.api.DeleteLogicalSwitchPortAnswer;
@@ -62,6 +64,9 @@ import com.cloud.api.commands.DeleteNiciraNvpDeviceCmd;
 import com.cloud.api.commands.ListNiciraNvpDeviceNetworksCmd;
 import com.cloud.api.commands.ListNiciraNvpDevicesCmd;
 import com.cloud.api.response.NiciraNvpDeviceResponse;
+import com.cloud.configuration.ConfigurationManager;
+import com.cloud.dc.Vlan;
+import com.cloud.dc.dao.VlanDao;
 import com.cloud.deploy.DeployDestination;
 import com.cloud.exception.ConcurrentOperationException;
 import com.cloud.exception.InsufficientCapacityException;
@@ -80,11 +85,15 @@ import com.cloud.network.Network.Service;
 import com.cloud.network.NetworkVO;
 import com.cloud.network.Networks;
 import com.cloud.network.Networks.BroadcastDomainType;
+import com.cloud.network.NetworkManager;
 import com.cloud.network.NiciraNvpDeviceVO;
 import com.cloud.network.NiciraNvpNicMappingVO;
 import com.cloud.network.PhysicalNetworkServiceProvider;
 import com.cloud.network.PhysicalNetworkVO;
+import com.cloud.network.PublicIpAddress;
+import com.cloud.network.addr.PublicIp;
 import com.cloud.network.dao.NetworkDao;
+import com.cloud.network.dao.NetworkServiceMapDao;
 import com.cloud.network.dao.NiciraNvpDao;
 import com.cloud.network.dao.NiciraNvpNicMappingDao;
 import com.cloud.network.dao.PhysicalNetworkDao;
@@ -98,11 +107,13 @@ import com.cloud.resource.ResourceState;
 import com.cloud.resource.ResourceStateAdapter;
 import com.cloud.resource.ServerResource;
 import com.cloud.resource.UnableDeleteHostException;
+import com.cloud.user.Account;
 import com.cloud.utils.component.AdapterBase;
 import com.cloud.utils.component.Inject;
 import com.cloud.utils.db.DB;
 import com.cloud.utils.db.Transaction;
 import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.utils.net.NetUtils;
 import com.cloud.vm.NicProfile;
 import com.cloud.vm.NicVO;
 import com.cloud.vm.ReservationContext;
@@ -111,7 +122,7 @@ import com.cloud.vm.VirtualMachineProfile;
 import com.cloud.vm.dao.NicDao;
 
 @Local(value = NetworkElement.class)
-public class NiciraNvpElement extends AdapterBase implements ConnectivityProvider, NiciraNvpElementService,
ResourceStateAdapter {
+public class NiciraNvpElement extends AdapterBase implements ConnectivityProvider, SourceNatServiceProvider,
NiciraNvpElementService, ResourceStateAdapter, IpDeployer {
     private static final Logger s_logger = Logger.getLogger(NiciraNvpElement.class);
     
     private static final Map<Service, Map<Capability, String>> capabilities =
setCapabilities();
@@ -137,6 +148,14 @@ public class NiciraNvpElement extends AdapterBase implements ConnectivityProvide
     NiciraNvpNicMappingDao _niciraNvpNicMappingDao;
     @Inject
     NetworkDao _networkDao;
+    @Inject
+    NetworkManager _networkManager;
+    @Inject
+    ConfigurationManager _configMgr;
+    @Inject
+    NetworkServiceMapDao _ntwkSrvcDao;
+    @Inject
+    VlanDao _vlanDao;
     
     @Override
     public Map<Service, Map<Capability, String>> getCapabilities() {
@@ -148,12 +167,23 @@ public class NiciraNvpElement extends AdapterBase implements ConnectivityProvide
         return Provider.NiciraNvp;
     }
     
-    private boolean canHandle(Network network) {
+    private boolean canHandle(Network network, Service service) {
+    	s_logger.debug("Checking if NiciraNvpElement can handle service " + service.getName()
+ " on network " + network.getDisplayText());
         if (network.getBroadcastDomainType() != BroadcastDomainType.Lswitch) {
             return false;
         }
         
-        return true;        
+        if (!_networkManager.isProviderForNetwork(getProvider(), network.getId())) {
+        	s_logger.debug("NiciraNvpElement is not a provider for network " + network.getDisplayText());
+        	return false;
+        }
+        
+        if (!_ntwkSrvcDao.canProviderSupportServiceInNetwork(network.getId(), service, Network.Provider.NiciraNvp))
{
+        	s_logger.debug("NiciraNvpElement can't provide the " + service.getName() + " service
on network " + network.getDisplayText());
+        	return false;
+        }
+        
+        return true;
     }
     
     @Override
@@ -169,12 +199,79 @@ public class NiciraNvpElement extends AdapterBase implements ConnectivityProvide
             DeployDestination dest, ReservationContext context)
             throws ConcurrentOperationException, ResourceUnavailableException,
             InsufficientCapacityException {
+    	s_logger.debug("entering NiciraNvpElement implement function for network " 
+            + network.getDisplayText() + " (state " + network.getState() + ")");
         
-        if (!canHandle(network)) {
+        if (!canHandle(network, Service.Connectivity)) {
             return false;
         }
         
-        return true;
+        if (network.getBroadcastUri() == null) {
+            s_logger.error("Nic has no broadcast Uri with the LSwitch Uuid");
+            return false;
+        }
+        
+        List<NiciraNvpDeviceVO> devices = _niciraNvpDao.listByPhysicalNetwork(network.getPhysicalNetworkId());
+        if (devices.isEmpty()) {
+            s_logger.error("No NiciraNvp Controller on physical network " + network.getPhysicalNetworkId());
+            return false;
+        }
+        NiciraNvpDeviceVO niciraNvpDevice = devices.get(0);
+        HostVO niciraNvpHost = _hostDao.findById(niciraNvpDevice.getHostId());
+        _hostDao.loadDetails(niciraNvpHost);
+        
+        Account owner = context.getAccount();
+        
+		/**
+		 * Lock the network as we might need to do multiple operations that
+		 * should be done only once.
+		 */
+		Network lock = _networkDao.acquireInLockTable(network.getId(),
+				_networkManager.getNetworkLockTimeout());
+		if (lock == null) {
+			throw new ConcurrentOperationException("Unable to lock network "
+					+ network.getId());
+		}
+		try {
+			if (_networkManager.isProviderSupportServiceInNetwork(
+					network.getId(), Service.SourceNat, Provider.NiciraNvp)) {
+				s_logger.debug("Apparently we are supposed to provide SourceNat on this network");
+				
+				PublicIp sourceNatIp = _networkManager.assignSourceNatIpAddressToGuestNetwork(owner,
network);
+				String publicCidr = sourceNatIp.getAddress().addr() + "/" + NetUtils.getCidrSize(sourceNatIp.getVlanNetmask());
+				String internalCidr = network.getGateway() + "/" + network.getCidr().split("/")[1];
+				long vlanid = (Vlan.UNTAGGED.equals(sourceNatIp.getVlanTag())) ? 0 : Long.parseLong(sourceNatIp.getVlanTag());
+				
+				CreateLogicalRouterCommand cmd = new CreateLogicalRouterCommand(
+						niciraNvpHost.getDetail("gatewayserviceuuid"), 
+						vlanid, 
+						network.getBroadcastUri().getSchemeSpecificPart(),
+						"router-" + network.getDisplayText(),
+						publicCidr,
+						sourceNatIp.getGateway(),
+						internalCidr,
+						context.getDomain().getName() + "-" + context.getAccount().getAccountName());
+				CreateLogicalRouterAnswer answer = 
+						(CreateLogicalRouterAnswer) _agentMgr.easySend(niciraNvpHost.getId(), cmd);
+				if (answer.getResult() == false) {
+					s_logger.error("Failed to create Logical Router for network " + network.getDisplayText());
+					return false;
+				}
+				
+			}
+
+
+		} finally {
+			if (lock != null) {
+				_networkDao.releaseFromLockTable(lock.getId());
+				if (s_logger.isDebugEnabled()) {
+					s_logger.debug("Lock is released for network id "
+							+ lock.getId() + " as a part of router startup in "
+							+ dest);
+				}
+			}
+		}
+		return true;
     }
 
     @Override
@@ -184,7 +281,7 @@ public class NiciraNvpElement extends AdapterBase implements ConnectivityProvide
             throws ConcurrentOperationException, ResourceUnavailableException,
             InsufficientCapacityException {
         
-        if (!canHandle(network)) {
+        if (!canHandle(network, Service.Connectivity)) {
             return false;
         }
 
@@ -244,7 +341,7 @@ public class NiciraNvpElement extends AdapterBase implements ConnectivityProvide
             ReservationContext context) throws ConcurrentOperationException,
             ResourceUnavailableException {
 
-        if (!canHandle(network)) {
+        if (!canHandle(network, Service.Connectivity)) {
             return false;
         }
 
@@ -286,7 +383,7 @@ public class NiciraNvpElement extends AdapterBase implements ConnectivityProvide
     public boolean shutdown(Network network, ReservationContext context,
             boolean cleanup) throws ConcurrentOperationException,
             ResourceUnavailableException {
-        if (!canHandle(network)) {
+        if (!canHandle(network, Service.Connectivity)) {
             return false;
         }
 
@@ -296,7 +393,7 @@ public class NiciraNvpElement extends AdapterBase implements ConnectivityProvide
     @Override
     public boolean destroy(Network network)
             throws ConcurrentOperationException, ResourceUnavailableException {
-        if (!canHandle(network)) {
+        if (!canHandle(network, Service.Connectivity)) {
             return false;
         }
 
@@ -318,18 +415,34 @@ public class NiciraNvpElement extends AdapterBase implements ConnectivityProvide
 
     @Override
     public boolean canEnableIndividualServices() {
-        return false;
+        return true;
     }
 
     @Override
     public boolean verifyServicesCombination(Set<Service> services) {
-        return true;
+    	// This element can only function in a Nicra Nvp based
+    	// SDN network, so Connectivity needs to be present here
+    	if (services.contains(Service.Connectivity)) {
+    		return true;
+    	}
+    	s_logger.debug("Unable to provide services without Connectivity service enabled for
this element");
+        return false;
     }
 
     private static Map<Service, Map<Capability, String>> setCapabilities() {
         Map<Service, Map<Capability, String>> capabilities = new HashMap<Service,
Map<Capability, String>>();
 
+        // Basic L2 SDN provisioning
         capabilities.put(Service.Connectivity, null);
+        
+        // L3 Support : SourceNat
+        capabilities.put(Service.Gateway, null);
+        Map<Capability, String> sourceNatCapabilities = new HashMap<Capability,
String>();
+        sourceNatCapabilities.put(Capability.SupportedSourceNatTypes, "peraccount");
+        sourceNatCapabilities.put(Capability.RedundantRouter, "true");
+        capabilities.put(Service.SourceNat, sourceNatCapabilities);
+        
+
         return capabilities;
     }
 
@@ -540,4 +653,28 @@ public class NiciraNvpElement extends AdapterBase implements ConnectivityProvide
         return new DeleteHostAnswer(true);
     }
 
+    /**
+     * From interface SourceNatServiceProvider
+     */
+	@Override
+	public IpDeployer getIpDeployer(Network network) {
+		return this;
+	}
+
+	/**
+	 * From interface IpDeployer
+	 * @param network
+	 * @param ipAddress
+	 * @param services
+	 * @return
+	 * @throws ResourceUnavailableException
+	 */
+	@Override
+	public boolean applyIps(Network network,
+			List<? extends PublicIpAddress> ipAddress, Set<Service> services)
+			throws ResourceUnavailableException {
+		// TODO Auto-generated method stub
+		return false;
+	}
+
 }

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/fe997651/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/L3GatewayAttachment.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/L3GatewayAttachment.java
b/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/L3GatewayAttachment.java
index 65a0a8e..8b807fd 100644
--- a/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/L3GatewayAttachment.java
+++ b/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/L3GatewayAttachment.java
@@ -22,15 +22,13 @@ package com.cloud.network.nicira;
 public class L3GatewayAttachment extends Attachment {
 	private String l3_gateway_service_uuid;
 	private String type = "L3GatewayAttachment";
-	private int vlan_id;
+	private Long vlan_id;
 	
 	public L3GatewayAttachment(String l3_gateway_service_uuid) {
 		this.l3_gateway_service_uuid = l3_gateway_service_uuid;
-		// VLAN 0 is untagged, set explicitly of no vlan is given in the constructor
-		this.vlan_id = 0;
 	}
 	
-	public L3GatewayAttachment(String l3_gateway_service_uuid, int vlan_id) {
+	public L3GatewayAttachment(String l3_gateway_service_uuid, long vlan_id) {
 		this.l3_gateway_service_uuid = l3_gateway_service_uuid;
 		this.vlan_id = vlan_id;
 	}
@@ -43,11 +41,11 @@ public class L3GatewayAttachment extends Attachment {
 		this.l3_gateway_service_uuid = l3_gateway_service_uuid;
 	}
 	
-	public int getVlanId() {
+	public long getVlanId() {
 		return vlan_id;
 	}
 	
-	public void setVlanId(int vlan_id) {
+	public void setVlanId(long vlan_id) {
 		this.vlan_id = vlan_id;
 	}
 

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/fe997651/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/PatchAttachment.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/PatchAttachment.java
b/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/PatchAttachment.java
new file mode 100644
index 0000000..e57c249
--- /dev/null
+++ b/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/PatchAttachment.java
@@ -0,0 +1,39 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+// 
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package com.cloud.network.nicira;
+
+/**
+ * 
+ */
+public class PatchAttachment extends Attachment {
+	private final String type = "PatchAttachment";
+	private String peer_port_uuid;
+	
+	public PatchAttachment(String peerPortUuid) {
+		this.peer_port_uuid = peerPortUuid;
+	}
+
+	public String getPeerPortUuid() {
+		return peer_port_uuid;
+	}
+
+	public void setPeerPortUuid(String peerPortUuid) {
+		this.peer_port_uuid = peerPortUuid;
+	}
+	
+	
+}

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/fe997651/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/RouterNextHop.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/RouterNextHop.java
b/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/RouterNextHop.java
index be302fa..c018af3 100644
--- a/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/RouterNextHop.java
+++ b/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/RouterNextHop.java
@@ -22,6 +22,10 @@ package com.cloud.network.nicira;
 public class RouterNextHop {
 	private String gateway_ip_address;
 	private String type = "RouterNextHop";
+	
+	public RouterNextHop(String gatewayIpAddress) {
+		this.gateway_ip_address = gatewayIpAddress;
+	}
 		
 	public String getGatewayIpAddress() {
 		return gateway_ip_address;

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/fe997651/plugins/network-elements/nicira-nvp/src/com/cloud/network/resource/NiciraNvpResource.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/nicira-nvp/src/com/cloud/network/resource/NiciraNvpResource.java
b/plugins/network-elements/nicira-nvp/src/com/cloud/network/resource/NiciraNvpResource.java
index 31cac6f..4aa6ff1 100644
--- a/plugins/network-elements/nicira-nvp/src/com/cloud/network/resource/NiciraNvpResource.java
+++ b/plugins/network-elements/nicira-nvp/src/com/cloud/network/resource/NiciraNvpResource.java
@@ -27,6 +27,8 @@ import org.apache.log4j.Logger;
 import com.cloud.agent.IAgentControl;
 import com.cloud.agent.api.Answer;
 import com.cloud.agent.api.Command;
+import com.cloud.agent.api.CreateLogicalRouterAnswer;
+import com.cloud.agent.api.CreateLogicalRouterCommand;
 import com.cloud.agent.api.CreateLogicalSwitchAnswer;
 import com.cloud.agent.api.CreateLogicalSwitchCommand;
 import com.cloud.agent.api.CreateLogicalSwitchPortAnswer;
@@ -48,17 +50,28 @@ import com.cloud.agent.api.UpdateLogicalSwitchPortAnswer;
 import com.cloud.agent.api.UpdateLogicalSwitchPortCommand;
 import com.cloud.host.Host;
 import com.cloud.host.Host.Type;
+import com.cloud.network.nicira.Attachment;
 import com.cloud.network.nicira.ControlClusterStatus;
+import com.cloud.network.nicira.L3GatewayAttachment;
+import com.cloud.network.nicira.LogicalRouterConfig;
+import com.cloud.network.nicira.LogicalRouterPort;
 import com.cloud.network.nicira.LogicalSwitch;
 import com.cloud.network.nicira.LogicalSwitchPort;
+import com.cloud.network.nicira.Match;
 import com.cloud.network.nicira.NiciraNvpApi;
 import com.cloud.network.nicira.NiciraNvpApiException;
 import com.cloud.network.nicira.NiciraNvpList;
 import com.cloud.network.nicira.NiciraNvpTag;
+import com.cloud.network.nicira.PatchAttachment;
+import com.cloud.network.nicira.RouterNextHop;
+import com.cloud.network.nicira.SingleDefaultRouteImplictRoutingConfig;
+import com.cloud.network.nicira.SourceNatRule;
 import com.cloud.network.nicira.TransportZoneBinding;
 import com.cloud.network.nicira.VifAttachment;
 import com.cloud.resource.ServerResource;
 
+import edu.emory.mathcs.backport.java.util.Arrays;
+
 public class NiciraNvpResource implements ServerResource {
     private static final Logger s_logger = Logger.getLogger(NiciraNvpResource.class);
     
@@ -197,6 +210,9 @@ public class NiciraNvpResource implements ServerResource {
         else if (cmd instanceof FindLogicalSwitchPortCommand) {
         	return executeRequest((FindLogicalSwitchPortCommand) cmd, numRetries);
         }
+        else if (cmd instanceof CreateLogicalRouterCommand) {
+        	return executeRequest((CreateLogicalRouterCommand) cmd, 0); //TODO set to numRetries
when done
+        }
         s_logger.debug("Received unsupported command " + cmd.toString());
         return Answer.createUnsupportedCommandAnswer(cmd);
     }
@@ -340,6 +356,99 @@ public class NiciraNvpResource implements ServerResource {
         }    	
     }
     
+    private Answer executeRequest(CreateLogicalRouterCommand cmd, int numRetries) {
+    	String routerName = cmd.getName();
+    	String gatewayServiceUuid = cmd.getGatewayServiceUuid();
+    	String logicalSwitchUuid = cmd.getLogicalSwitchUuid();
+    	
+        List<NiciraNvpTag> tags = new ArrayList<NiciraNvpTag>();
+        tags.add(new NiciraNvpTag("cs_account",cmd.getOwnerName()));
+        
+        String publicNetworkNextHopIp = cmd.getPublicNextHop();
+        String publicNetworkIpAddress = cmd.getPublicIpCidr();
+        String internalNetworkAddress = cmd.getInternalIpCidr();
+        
+        s_logger.debug("Creating a logical router with external ip " 
+        		+ publicNetworkIpAddress + " and internal ip " + internalNetworkAddress
+        		+ "on gateway service " + gatewayServiceUuid);
+        
+        try {
+        	// Create the Router
+        	LogicalRouterConfig lrc = new LogicalRouterConfig();
+        	lrc.setDisplayName(routerName);
+        	lrc.setTags(tags);
+        	lrc.setRoutingConfig(new SingleDefaultRouteImplictRoutingConfig(
+        			new RouterNextHop(publicNetworkNextHopIp)));
+        	lrc = _niciraNvpApi.createLogicalRouter(lrc);
+        	
+        	try {
+	        	// Create the outside port for the router
+	        	LogicalRouterPort lrpo = new LogicalRouterPort();
+	        	lrpo.setAdminStatusEnabled(true);
+	        	lrpo.setDisplayName(routerName + "-port");
+	        	lrpo.setTags(tags);
+	        	List<String> outsideIpAddresses = new ArrayList<String>();
+	        	outsideIpAddresses.add(publicNetworkIpAddress);
+	        	lrpo.setIpAddresses(outsideIpAddresses);
+	        	lrpo = _niciraNvpApi.createLogicalRouterPort(lrc.getUuid(),lrpo);
+	        	
+	        	// Attach the outside port to the gateway service on the correct VLAN
+	        	L3GatewayAttachment attachment = new L3GatewayAttachment(gatewayServiceUuid);
+	        	if (cmd.getVlanId() != 0) {
+	        		attachment.setVlanId(cmd.getVlanId());
+	        	}
+	        	_niciraNvpApi.modifyLogicalRouterPortAttachment(lrc.getUuid(), lrpo.getUuid(),
attachment);
+	        	
+	        	// Create the inside port for the router
+	        	LogicalRouterPort lrpi = new LogicalRouterPort();
+	        	lrpi.setAdminStatusEnabled(true);
+	        	lrpi.setDisplayName(routerName + "-port");
+	        	lrpi.setTags(tags);
+	        	List<String> insideIpAddresses = new ArrayList<String>();
+	        	insideIpAddresses.add(internalNetworkAddress);
+	        	lrpi.setIpAddresses(insideIpAddresses);
+	        	lrpi = _niciraNvpApi.createLogicalRouterPort(lrc.getUuid(),lrpi);
+	        	
+	        	// Create the inside port on the lswitch
+	            LogicalSwitchPort lsp = new LogicalSwitchPort(routerName + "-port", tags, true);
+	            lsp = _niciraNvpApi.createLogicalSwitchPort(logicalSwitchUuid, lsp);
+	       	
+	        	// Attach the inside router port to the lswitch port with a PatchAttachment
+	            _niciraNvpApi.modifyLogicalRouterPortAttachment(lrc.getUuid(), lrpi.getUuid(),

+	            		new PatchAttachment(lsp.getUuid()));
+	        	
+	        	// Attach the inside lswitch port to the router with a PatchAttachment
+	            _niciraNvpApi.modifyLogicalSwitchPortAttachment(logicalSwitchUuid, lsp.getUuid(),

+	            		new PatchAttachment(lrpi.getUuid()));
+	            
+	            // Setup the source nat rule
+	            SourceNatRule snr = new SourceNatRule();
+	            snr.setToSourceIpAddressMin(publicNetworkIpAddress.split("/")[0]);
+	            snr.setToSourceIpAddressMax(publicNetworkIpAddress.split("/")[0]);
+	            Match match = new Match();
+	            match.setSourceIpAddresses(internalNetworkAddress);
+	            snr.setMatch(match);
+	            _niciraNvpApi.createLogicalRouterNatRule(lrc.getUuid(), snr);
+        	} finally {
+        		// We need to destroy the router if we already created it
+        		// this will also take care of any router ports
+        		// TODO Clean up the switchport
+        		try {
+        			_niciraNvpApi.deleteLogicalRouter(lrc.getUuid());
+        		} catch (NiciraNvpApiException e) {}
+        	}
+            
+            return new CreateLogicalRouterAnswer(cmd, true, "Logical Router created (uuid
" + lrc.getUuid() + ")", lrc.getUuid());    	
+        } catch (NiciraNvpApiException e) {
+        	if (numRetries > 0) {
+        		return retry(cmd, --numRetries);
+        	} 
+        	else {
+        		return new CreateLogicalRouterAnswer(cmd, e);
+        	}
+        }
+    }
+    
     private Answer executeRequest(ReadyCommand cmd) {
         return new ReadyAnswer(cmd);
     }


Mime
View raw message