Start implementing IpDeployer

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

Branch: refs/heads/nicira-l3support
Commit: de41cb7cb5ee0fb128c81fb5b00f3eb537e4eec2
Parents: dd68a00
Author: Hugo Trippaers <[email protected]>
Authored: Fri Sep 28 11:32:53 2012 -0700
Committer: Hugo Trippaers <[email protected]>
Committed: Fri Sep 28 11:32:53 2012 -0700

----------------------------------------------------------------------
 .../agent/api/AssignIpToLogicalRouterAnswer.java   |   35 +++++
 .../agent/api/AssignIpToLogicalRouterCommand.java  |   98 +++++++++++++++
 .../cloud/network/element/NiciraNvpElement.java    |   46 +++++--
 .../src/com/cloud/network/nicira/NiciraNvpApi.java |   24 ++++-
 .../com/cloud/network/nicira/NiciraNvpList.java    |   10 +-
 .../cloud/network/resource/NiciraNvpResource.java  |   76 +++++++++++-
 6 files changed, 271 insertions(+), 18 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/de41cb7c/plugins/network-elements/nicira-nvp/src/com/cloud/agent/api/AssignIpToLogicalRouterAnswer.java
----------------------------------------------------------------------
diff --git 
a/plugins/network-elements/nicira-nvp/src/com/cloud/agent/api/AssignIpToLogicalRouterAnswer.java
 
b/plugins/network-elements/nicira-nvp/src/com/cloud/agent/api/AssignIpToLogicalRouterAnswer.java
new file mode 100644
index 0000000..1eda213
--- /dev/null
+++ 
b/plugins/network-elements/nicira-nvp/src/com/cloud/agent/api/AssignIpToLogicalRouterAnswer.java
@@ -0,0 +1,35 @@
+// 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;
+
+import com.cloud.agent.api.Command;
+
+/**
+ * 
+ */
+public class AssignIpToLogicalRouterAnswer extends Answer {
+       
+    public AssignIpToLogicalRouterAnswer(Command command, boolean success,
+            String details) {
+        super(command, success, details);
+    }
+    
+    public AssignIpToLogicalRouterAnswer(Command command, Exception e) {
+        super(command, e);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/de41cb7c/plugins/network-elements/nicira-nvp/src/com/cloud/agent/api/AssignIpToLogicalRouterCommand.java
----------------------------------------------------------------------
diff --git 
a/plugins/network-elements/nicira-nvp/src/com/cloud/agent/api/AssignIpToLogicalRouterCommand.java
 
b/plugins/network-elements/nicira-nvp/src/com/cloud/agent/api/AssignIpToLogicalRouterCommand.java
new file mode 100644
index 0000000..98c36a8
--- /dev/null
+++ 
b/plugins/network-elements/nicira-nvp/src/com/cloud/agent/api/AssignIpToLogicalRouterCommand.java
@@ -0,0 +1,98 @@
+// 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;
+
+import com.cloud.network.IpAddress;
+
+/**
+ * 
+ */
+public class AssignIpToLogicalRouterCommand extends Command {
+       private String logicalRouterUuid;
+       private String gatewayServiceUuid;
+       private String publicIpCidr;
+       private long publicIpVlan;
+       private boolean sourceNat;
+       private String internalNetworkCidr;
+
+       public AssignIpToLogicalRouterCommand(String logicalRouterUuid, String 
gatewayServiceUuid, String publicIpCidr, long publicIpVlan, boolean sourceNat, 
String internetNetworkCidr) {
+               this.logicalRouterUuid = logicalRouterUuid;
+               this.gatewayServiceUuid = gatewayServiceUuid;
+               this.publicIpCidr = publicIpCidr;
+               this.sourceNat = sourceNat;
+               this.internalNetworkCidr = internetNetworkCidr;
+               this.publicIpVlan = publicIpVlan;
+       }
+       
+       public String getLogicalRouterUuid() {
+               return logicalRouterUuid;
+       }
+
+       public void setLogicalRouterUuid(String logicalRouterUuid) {
+               this.logicalRouterUuid = logicalRouterUuid;
+       }
+
+       public String getGatewayServiceUuid() {
+               return gatewayServiceUuid;
+       }
+
+       public void setGatewayServiceUuid(String gatewayServiceUuid) {
+               this.gatewayServiceUuid = gatewayServiceUuid;
+       }
+
+       public String getPublicIpCidr() {
+               return publicIpCidr;
+       }
+
+       public void setPublicIpCidr(String publicIpCidr) {
+               this.publicIpCidr = publicIpCidr;
+       }
+
+       public long getPublicIpVlan() {
+               return publicIpVlan;
+       }
+
+       public void setPublicIpVlan(long publicIpVlan) {
+               this.publicIpVlan = publicIpVlan;
+       }
+
+       public boolean isSourceNat() {
+               return sourceNat;
+       }
+
+       public void setSourceNat(boolean sourceNat) {
+               this.sourceNat = sourceNat;
+       }
+
+       public String getInternalNetworkCidr() {
+               return internalNetworkCidr;
+       }
+
+       public void setInternalNetworkCidr(String internalNetworkCidr) {
+               this.internalNetworkCidr = internalNetworkCidr;
+       }
+
+       /* (non-Javadoc)
+        * @see com.cloud.agent.api.Command#executeInSequence()
+        */
+       @Override
+       public boolean executeInSequence() {
+               // TODO Auto-generated method stub
+               return false;
+       }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/de41cb7c/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 9a220dc..7a0b268 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
@@ -256,6 +256,10 @@ public class NiciraNvpElement extends AdapterBase 
implements
                                        + network.getId());
                }
                try {
+                       // FIXME Check if any services other than connectiviy 
are required
+                       // If that is the case start the logical router with 
only the
+                       // internal interface, leave the external interfaces to 
the
+                       // IpDeployer
                        if (_networkManager.isProviderSupportServiceInNetwork(
                                        network.getId(), Service.SourceNat, 
Provider.NiciraNvp)) {
                                s_logger.debug("Apparently we are supposed to 
provide SourceNat on this network");
@@ -457,9 +461,10 @@ public class NiciraNvpElement extends AdapterBase 
implements
                        NiciraNvpRouterMappingVO routermapping = 
_niciraNvpRouterMappingDao
                                        .findByNetworkIdI(network.getId());
                        if (routermapping == null) {
-                               s_logger.error("No logical router uuid found 
for network "
+                               s_logger.warn("No logical router uuid found for 
network "
                                                + network.getDisplayText());
-                               return false;
+                               // This might be cause by a failed deployment, 
so don't make shutdown fail as well.
+                               return true;
                        }
 
                        DeleteLogicalRouterCommand cmd = new 
DeleteLogicalRouterCommand(routermapping.getLogicalRouterUuid());
@@ -470,6 +475,8 @@ public class NiciraNvpElement extends AdapterBase implements
                                                + network.getDisplayText());
                                return false;
                        }
+                       
+                       
_niciraNvpRouterMappingDao.remove(routermapping.getId());
                }
 
                return true;
@@ -507,11 +514,15 @@ public class NiciraNvpElement extends AdapterBase 
implements
        public boolean verifyServicesCombination(Set<Service> services) {
                // 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;
+               if (!services.contains(Service.Connectivity)) {
+                       s_logger.warn("Unable to provide services without 
Connectivity service enabled for this element");
+                       return false;
                }
-               s_logger.debug("Unable to provide services without Connectivity 
service enabled for this element");
-               return false;
+               if ((services.contains(Service.PortForwarding) || 
services.contains(Service.StaticNat)) && 
!services.contains(Service.PortForwarding)) {
+                       s_logger.warn("Unable to provider StaticNat and/or 
PortForwarding without the SourceNat service");
+                       return false;
+               }
+               return true;
        }
 
        private static Map<Service, Map<Capability, String>> setCapabilities() {
@@ -808,8 +819,14 @@ public class NiciraNvpElement extends AdapterBase 
implements
                        List<? extends PublicIpAddress> ipAddress, Set<Service> 
services)
                        throws ResourceUnavailableException {
                s_logger.debug("Entering applyIps"); // TODO Remove this line
-               // TODO Auto-generated method stub
-               return false;
+               
+               // The Nicira Nvp L3 Gateway doesn't need the addresses 
configured on
+               // the router interface. Only configure the CIDR and individual 
ip
+               // addresses become available when DNAT rules are created for 
them.
+               // The cidr setup is done during implementation of the logical 
router
+               // in the function implement 
+               
+               return true;
        }
 
        /**
@@ -819,9 +836,12 @@ public class NiciraNvpElement extends AdapterBase 
implements
        public boolean applyStaticNats(Network config,
                        List<? extends StaticNat> rules)
                        throws ResourceUnavailableException {
+               // FIXME Implement this
                s_logger.debug("Entering applyStaticNats"); // TODO Remove this 
line
-               // TODO Auto-generated method stub
-               return false;
+               for (StaticNat rule : rules) {
+                       s_logger.debug ("StaticNat rule : from " + 
rule.getSourceIpAddressId() + " to " + rule.getDestIpAddress() + 
(rule.isForRevoke() ? " for revoke" : ""));
+               }
+               return true;
        }
 
        /**
@@ -830,8 +850,12 @@ public class NiciraNvpElement extends AdapterBase 
implements
        @Override
        public boolean applyPFRules(Network network, List<PortForwardingRule> 
rules)
                        throws ResourceUnavailableException {
+               // FIXME Implement this
                s_logger.debug("Entering applyPFRules"); // TODO Remove this 
line
-               // TODO Auto-generated method stub
+               for (PortForwardingRule rule : rules) {
+                       s_logger.debug ("PortForwardingRule rule : from " + 
rule.getSourceIpAddressId() + 
+                                       " to " + 
rule.getDestinationIpAddress().addr() + " port " + 
rule.getDestinationPortStart() + "-" + rule.getDestinationPortEnd());
+               }
                return false;
        }
 

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/de41cb7c/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/NiciraNvpApi.java
----------------------------------------------------------------------
diff --git 
a/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/NiciraNvpApi.java
 
b/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/NiciraNvpApi.java
index 1c7b741..a04dd1e 100644
--- 
a/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/NiciraNvpApi.java
+++ 
b/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/NiciraNvpApi.java
@@ -181,7 +181,7 @@ public class NiciraNvpApi {
             
         NiciraNvpList<LogicalSwitchPort> lspl = executeRetrieveObject(new 
TypeToken<NiciraNvpList<LogicalSwitchPort>>(){}.getType(), uri, params);
                 
-        if (lspl == null || lspl.getResult_count() != 1) {
+        if (lspl == null || lspl.getResultCount() != 1) {
             throw new NiciraNvpApiException("Unexpected response from API");
         }
         
@@ -262,6 +262,28 @@ public class NiciraNvpApi {
        executeDeleteObject(uri);
     }
     
+    public NiciraNvpList<LogicalRouterPort> 
findLogicalRouterPortByGatewayServiceAndVlanId(String logicalRouterUuid, String 
gatewayServiceUuid, long vlanId) throws NiciraNvpApiException {
+       String uri = "/ws.v1/lrouter/" + logicalRouterUuid + "/lport";
+        Map<String,String> params = new HashMap<String,String>();
+        params.put("attachment_gwsvc_uuid", gatewayServiceUuid);
+        params.put("attachment_vlan", "0");
+        params.put("fields","*");
+        
+        return executeRetrieveObject(new 
TypeToken<NiciraNvpList<LogicalRouterPort>>(){}.getType(), uri, params);
+    }
+    
+    public LogicalRouterConfig findOneLogicalRouterByUuid(String 
logicalRouterUuid) throws NiciraNvpApiException {
+       String uri = "/ws.v1/lrouter/" + logicalRouterUuid;
+       
+       return executeRetrieveObject(new 
TypeToken<LogicalRouterConfig>(){}.getType(), uri, 
Collections.<String,String>emptyMap());
+    }
+    
+    public void updateLogicalRouterPortConfig(String logicalRouterUuid, 
LogicalRouterPort logicalRouterPort) throws NiciraNvpApiException {
+       String uri = "/ws.v1/lrouter/" + logicalRouterUuid + "/lport" + 
logicalRouterPort.getUuid();
+       
+       executeUpdateObject(logicalRouterPort, uri, 
Collections.<String,String>emptyMap());
+    }
+    
     private <T> void executeUpdateObject(T newObject, String uri, 
Map<String,String> parameters) throws NiciraNvpApiException {
         String url;
         try {

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/de41cb7c/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/NiciraNvpList.java
----------------------------------------------------------------------
diff --git 
a/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/NiciraNvpList.java
 
b/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/NiciraNvpList.java
index 13d352d..c97e40e 100644
--- 
a/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/NiciraNvpList.java
+++ 
b/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/NiciraNvpList.java
@@ -30,12 +30,16 @@ public class NiciraNvpList<T> {
         this.results = results;
     }
 
-    public int getResult_count() {
+    public int getResultCount() {
         return result_count;
     }
 
-    public void setResult_count(int result_count) {
+    public void setResultCount(int result_count) {
         this.result_count = result_count;
-    }        
+    }
+    
+    public boolean isEmpty() {
+       return result_count == 0;
+    }
 
 }

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/de41cb7c/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 817c630..96ed856 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
@@ -26,6 +26,8 @@ import org.apache.log4j.Logger;
 
 import com.cloud.agent.IAgentControl;
 import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.AssignIpToLogicalRouterAnswer;
+import com.cloud.agent.api.AssignIpToLogicalRouterCommand;
 import com.cloud.agent.api.Command;
 import com.cloud.agent.api.CreateLogicalRouterAnswer;
 import com.cloud.agent.api.CreateLogicalRouterCommand;
@@ -218,6 +220,9 @@ public class NiciraNvpResource implements ServerResource {
         else if (cmd instanceof DeleteLogicalRouterCommand) {
                return executeRequest((DeleteLogicalRouterCommand) cmd, 
numRetries);
         }
+        else if (cmd instanceof AssignIpToLogicalRouterCommand) {
+               return executeRequest((AssignIpToLogicalRouterCommand) cmd, 
numRetries);
+        }
         s_logger.debug("Received unsupported command " + cmd.toString());
         return Answer.createUnsupportedCommandAnswer(cmd);
     }
@@ -345,7 +350,7 @@ public class NiciraNvpResource implements ServerResource {
         
         try {
                NiciraNvpList<LogicalSwitchPort> ports = 
_niciraNvpApi.findLogicalSwitchPortsByUuid(logicalSwitchUuid, 
logicalSwitchPortUuid);
-               if (ports.getResult_count() == 0) {
+               if (ports.getResultCount() == 0) {
                        return new FindLogicalSwitchPortAnswer(cmd, false, 
"Logical switchport " + logicalSwitchPortUuid + " not found", null);
                }
                else {
@@ -434,13 +439,15 @@ public class NiciraNvpResource implements ServerResource {
                    match.setSourceIpAddresses(internalNetworkAddress);
                    snr.setMatch(match);
                    _niciraNvpApi.createLogicalRouterNatRule(lrc.getUuid(), 
snr);
-               } finally {
+               } catch (NiciraNvpApiException e) {
                        // 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) {}
+                       } catch (NiciraNvpApiException ex) {}
+                       
+                       throw e;
                }
             
             return new CreateLogicalRouterAnswer(cmd, true, "Logical Router 
created (uuid " + lrc.getUuid() + ")", lrc.getUuid());     
@@ -468,6 +475,69 @@ public class NiciraNvpResource implements ServerResource {
         }
     }
     
+    private Answer executeRequest(AssignIpToLogicalRouterCommand cmd, int 
numRetries) {
+       try {
+               LogicalRouterConfig lrc = 
_niciraNvpApi.findOneLogicalRouterByUuid(cmd.getLogicalRouterUuid());
+               
+               NiciraNvpList<LogicalRouterPort> ports = 
+                               
_niciraNvpApi.findLogicalRouterPortByGatewayServiceAndVlanId(cmd.getLogicalRouterUuid(),
 
+                                               cmd.getGatewayServiceUuid(), 
cmd.getPublicIpVlan());
+               
+               String publicNetworkIpAddress = cmd.getPublicIpCidr();          
        
+               
+               if (ports.isEmpty()) {
+                       // No attachment on this network, we need to create one
+                       // Create the outside port for the router
+                       LogicalRouterPort lrpo = new LogicalRouterPort();
+                       lrpo.setAdminStatusEnabled(true);
+                       lrpo.setDisplayName(lrc.getDisplayName() + 
"-outside-port");
+                       lrpo.setTags(lrc.getTags());
+                       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(cmd.getGatewayServiceUuid());
+                       if (cmd.getPublicIpVlan() != 0) {
+                               attachment.setVlanId(cmd.getPublicIpVlan());
+                       }
+                       
_niciraNvpApi.modifyLogicalRouterPortAttachment(lrc.getUuid(), lrpo.getUuid(), 
attachment);
+                       return new AssignIpToLogicalRouterAnswer(cmd, true, "Ip 
address configured on new logical router port");
+               }
+               else {
+                       // There is already and attachment to this public 
network, see if we need to add this IP
+                       boolean found = false;
+                       LogicalRouterPort publicPort = null;
+                       for (LogicalRouterPort port : ports.getResults()) {
+                               for (String cidr : port.getIpAddresses()) {
+                                       if 
(publicNetworkIpAddress.equals(cidr)) {
+                                               found = true;
+                                               publicPort = port;
+                                               break;
+                                       }
+                               }
+                       }
+                       if (found) {
+                               s_logger.warn("Ip " + publicNetworkIpAddress + 
" is already configured on logical router " + cmd.getLogicalRouterUuid());
+                               return new AssignIpToLogicalRouterAnswer(cmd, 
true, "Ip address already alocated on logical Router");
+                       }
+                       
+                       publicPort.getIpAddresses().add(publicNetworkIpAddress);
+                       
_niciraNvpApi.updateLogicalRouterPortConfig(cmd.getLogicalRouterUuid(), 
publicPort);
+                       return new AssignIpToLogicalRouterAnswer(cmd, true, "Ip 
address configured on existing logical router port");
+               }
+        } catch (NiciraNvpApiException e) {
+               if (numRetries > 0) {
+                       return retry(cmd, --numRetries);
+               } 
+               else {
+                       return new DeleteLogicalRouterAnswer(cmd, e);
+               }
+        }
+       
+    }
+    
     private Answer executeRequest(ReadyCommand cmd) {
         return new ReadyAnswer(cmd);
     }

Reply via email to