CLOUDSTACK-6106 supporting VPC VR on Hyper-V

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

Branch: refs/heads/resize-root
Commit: 1b4325d2c88d49b394256f2130c509eebfe9bf36
Parents: 794b38a
Author: Rajesh Battala <rajesh.batt...@citrix.com>
Authored: Wed Mar 12 07:26:08 2014 +0530
Committer: Rajesh Battala <rajesh.batt...@citrix.com>
Committed: Fri Mar 14 17:36:43 2014 +0530

----------------------------------------------------------------------
 .../agent/api/ModifyVmNicConfigCommand.java     |   7 +
 .../hypervisor/hyperv/guru/HypervGuru.java      |  45 ++++--
 .../resource/HypervDirectConnectResource.java   | 138 ++++++++++++++++---
 .../com/cloud/network/vpc/VpcManagerImpl.java   |   1 +
 4 files changed, 158 insertions(+), 33 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/1b4325d2/core/src/com/cloud/agent/api/ModifyVmNicConfigCommand.java
----------------------------------------------------------------------
diff --git a/core/src/com/cloud/agent/api/ModifyVmNicConfigCommand.java 
b/core/src/com/cloud/agent/api/ModifyVmNicConfigCommand.java
index 0230bec..5f4f0e1 100644
--- a/core/src/com/cloud/agent/api/ModifyVmNicConfigCommand.java
+++ b/core/src/com/cloud/agent/api/ModifyVmNicConfigCommand.java
@@ -21,6 +21,7 @@ public class ModifyVmNicConfigCommand extends Command {
     String vmName;
     int vlan;
     String macAddress;
+    int index;
     protected ModifyVmNicConfigCommand() {
     }
 
@@ -30,6 +31,12 @@ public class ModifyVmNicConfigCommand extends Command {
         this.macAddress = macAddress;
     }
 
+    public ModifyVmNicConfigCommand(String vmName, int vlan, int position) {
+        this.vmName = vmName;
+        this.vlan = vlan;
+        this.index = position;
+    }
+
     public String getVmName() {
         return vmName;
     }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/1b4325d2/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/guru/HypervGuru.java
----------------------------------------------------------------------
diff --git 
a/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/guru/HypervGuru.java
 
b/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/guru/HypervGuru.java
index bf0795d..4e8d3d5 100644
--- 
a/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/guru/HypervGuru.java
+++ 
b/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/guru/HypervGuru.java
@@ -34,6 +34,7 @@ import com.cloud.storage.dao.GuestOSDao;
 import com.cloud.exception.InsufficientAddressCapacityException;
 import com.cloud.hypervisor.hyperv.manager.HypervManager;
 import com.cloud.network.NetworkModel;
+import com.cloud.network.Networks.BroadcastDomainType;
 import com.cloud.network.Networks.TrafficType;
 import com.cloud.network.dao.NetworkDao;
 import com.cloud.network.dao.NetworkVO;
@@ -74,16 +75,20 @@ public class HypervGuru extends HypervisorGuruBase 
implements HypervisorGuru {
         if(vm.getVirtualMachine().getType() ==  
VirtualMachine.Type.DomainRouter) {
 
             NicProfile publicNicProfile = null;
+            NicProfile controlNicProfile = null;
+            NicProfile profile = null;
             for(NicProfile nicProfile : nicProfiles) {
                 if(nicProfile.getTrafficType() == TrafficType.Public) {
                     publicNicProfile = nicProfile;
                     break;
                 }
+                else if (nicProfile.getTrafficType() == TrafficType.Control) {
+                    controlNicProfile = nicProfile;
+                }
             }
 
-            if(publicNicProfile != null) {
+            if(publicNicProfile != null || controlNicProfile != null) {
                 NicTO[] nics = to.getNics();
-
                 // reserve extra NICs
                 NicTO[] expandedNics = new NicTO[MaxNicSupported];
                 int i = 0;
@@ -95,18 +100,27 @@ public class HypervGuru extends HypervisorGuruBase 
implements HypervisorGuru {
                 }
                 deviceId++;
 
-                long networkId = publicNicProfile.getNetworkId();
+                long networkId = 0;
+                if(publicNicProfile != null ) {
+                    networkId= publicNicProfile.getNetworkId();
+                    profile = publicNicProfile;
+                }
+                else {
+                    networkId =  controlNicProfile.getNetworkId();
+                    profile = controlNicProfile;
+                }
+
                 NetworkVO network = _networkDao.findById(networkId);
                 // for Hyperv Hot Nic plug is not supported and it will 
support upto 8 nics.
                 // creating the VR with extra nics (actual nics(3) + extra 
nics) will be 8
                 for(; i < MaxNicSupported; i++) {
                     NicTO nicTo = new NicTO();
                     nicTo.setDeviceId(deviceId++);
-                    
nicTo.setBroadcastType(publicNicProfile.getBroadcastType());
-                    nicTo.setType(publicNicProfile.getTrafficType());
+                    nicTo.setBroadcastType(BroadcastDomainType.Vlan);
+                    nicTo.setType(TrafficType.Public);
                     nicTo.setIp("0.0.0.0");
                     nicTo.setNetmask("255.255.255.255");
-                    nicTo.setName(publicNicProfile.getName());
+                    nicTo.setName(profile.getName());
 
                     try {
                         String mac = 
_networkMgr.getNextAvailableMacAddressInNetwork(networkId);
@@ -114,16 +128,16 @@ public class HypervGuru extends HypervisorGuruBase 
implements HypervisorGuru {
                     } catch (InsufficientAddressCapacityException e) {
                         throw new CloudRuntimeException("unable to allocate 
mac address on network: " + networkId);
                     }
-                    nicTo.setDns1(publicNicProfile.getDns1());
-                    nicTo.setDns2(publicNicProfile.getDns2());
-                    if (publicNicProfile.getGateway() != null) {
+                    nicTo.setDns1(profile.getDns1());
+                    nicTo.setDns2(profile.getDns2());
+                    if (publicNicProfile != null && 
publicNicProfile.getGateway() != null) {
                         nicTo.setGateway(publicNicProfile.getGateway());
                     } else {
                         nicTo.setGateway(network.getGateway());
                     }
                     nicTo.setDefaultNic(false);
-                    nicTo.setBroadcastUri(publicNicProfile.getBroadCastUri());
-                    nicTo.setIsolationuri(publicNicProfile.getIsolationUri());
+                    nicTo.setBroadcastUri(profile.getBroadCastUri());
+                    nicTo.setIsolationuri(profile.getIsolationUri());
 
                     Integer networkRate = 
_networkMgr.getNetworkRate(network.getId(), null);
                     nicTo.setNetworkRateMbps(networkRate);
@@ -137,9 +151,12 @@ public class HypervGuru extends HypervisorGuruBase 
implements HypervisorGuru {
             for(NicTO nicTo : sortNicsByDeviceId(to.getNics())) {
                 sbMacSequence.append(nicTo.getMac()).append("|");
             }
-            sbMacSequence.deleteCharAt(sbMacSequence.length() - 1);
-            String bootArgs = to.getBootArgs();
-            to.setBootArgs(bootArgs + " nic_macs=" + sbMacSequence.toString());
+
+            if (!sbMacSequence.toString().isEmpty()) {
+                sbMacSequence.deleteCharAt(sbMacSequence.length() - 1);
+                String bootArgs = to.getBootArgs();
+                to.setBootArgs(bootArgs + " nic_macs=" + 
sbMacSequence.toString());
+            }
 
         }
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/1b4325d2/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/resource/HypervDirectConnectResource.java
----------------------------------------------------------------------
diff --git 
a/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/resource/HypervDirectConnectResource.java
 
b/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/resource/HypervDirectConnectResource.java
index a3ffa75..b1f5a67 100644
--- 
a/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/resource/HypervDirectConnectResource.java
+++ 
b/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/resource/HypervDirectConnectResource.java
@@ -83,10 +83,14 @@ import com.cloud.agent.api.NetworkUsageCommand;
 import com.cloud.agent.api.PingCommand;
 import com.cloud.agent.api.PingRoutingCommand;
 import com.cloud.agent.api.PingTestCommand;
+import com.cloud.agent.api.PlugNicAnswer;
+import com.cloud.agent.api.PlugNicCommand;
 import com.cloud.agent.api.SetupGuestNetworkCommand;
 import com.cloud.agent.api.StartCommand;
 import com.cloud.agent.api.StartupCommand;
 import com.cloud.agent.api.StartupRoutingCommand;
+import com.cloud.agent.api.UnPlugNicAnswer;
+import com.cloud.agent.api.UnPlugNicCommand;
 import com.cloud.agent.api.StartupRoutingCommand.VmState;
 import com.cloud.agent.api.StartupStorageCommand;
 import com.cloud.agent.api.UnsupportedAnswer;
@@ -172,7 +176,7 @@ public class HypervDirectConnectResource extends 
ServerResourceBase implements S
     protected final int _retry = 24;
     protected final int _sleep = 10000;
     protected static final int DEFAULT_DOMR_SSHPORT = 3922;
-
+    private final int maxid = 4094;
     private String _clusterGuid;
 
     // Used by initialize to assert object configured before
@@ -477,7 +481,12 @@ public class HypervDirectConnectResource extends 
ServerResourceBase implements S
             answer = execute((SetStaticRouteCommand) cmd);
         } else if (clazz == SetMonitorServiceCommand.class) {
             answer = execute((SetMonitorServiceCommand) cmd);
-        } else {
+        } else if (clazz == PlugNicCommand.class) {
+            answer = execute((PlugNicCommand)cmd);
+        } else if (clazz == UnPlugNicCommand.class) {
+            answer = execute((UnPlugNicCommand)cmd);
+        }
+        else {
             if (clazz == StartCommand.class) {
                 VirtualMachineTO vmSpec = 
((StartCommand)cmd).getVirtualMachine();
                 if (vmSpec.getType() != VirtualMachine.Type.User) {
@@ -509,6 +518,59 @@ public class HypervDirectConnectResource extends 
ServerResourceBase implements S
         return answer;
     }
 
+
+    private PlugNicAnswer execute(PlugNicCommand cmd) {
+        if (s_logger.isInfoEnabled()) {
+            s_logger.info("Executing resource PlugNicCommand " + 
s_gson.toJson(cmd));
+        }
+
+        try {
+
+            String vmName = cmd.getVmName();
+            NicTO nic = cmd.getNic();
+            URI broadcastUri = nic.getBroadcastUri();
+            if (BroadcastDomainType.getSchemeValue(broadcastUri) != 
BroadcastDomainType.Vlan) {
+                throw new InternalErrorException("Unable to assign a public IP 
to a VIF on network " + nic.getBroadcastUri());
+            }
+            int vlanId = 
Integer.parseInt(BroadcastDomainType.getValue(broadcastUri));
+            int publicNicInfo = -1;
+            publicNicInfo = getVmNics(vmName, maxid);
+            if (publicNicInfo > 0) {
+                modifyNicVlan(vmName, vlanId, publicNicInfo);
+            }
+            return new PlugNicAnswer(cmd, true, "success");
+        } catch (Exception e) {
+            s_logger.error("Unexpected exception: ", e);
+            return new PlugNicAnswer(cmd, false, "Unable to execute 
PlugNicCommand due to " + e.toString());
+        }
+    }
+
+
+    private UnPlugNicAnswer execute(UnPlugNicCommand cmd) {
+        if (s_logger.isInfoEnabled()) {
+            s_logger.info("Executing resource UnPlugNicCommand " + 
s_gson.toJson(cmd));
+        }
+
+        try {
+            String vmName = cmd.getVmName();
+            NicTO nic = cmd.getNic();
+            URI broadcastUri = nic.getBroadcastUri();
+            if (BroadcastDomainType.getSchemeValue(broadcastUri) != 
BroadcastDomainType.Vlan) {
+                throw new InternalErrorException("Unable to unassign a public 
IP to a VIF on network " + nic.getBroadcastUri());
+            }
+            int vlanId = 
Integer.parseInt(BroadcastDomainType.getValue(broadcastUri));
+            int publicNicInfo = -1;
+            publicNicInfo = getVmNics(vmName, vlanId);
+            if (publicNicInfo > 0) {
+                modifyNicVlan(vmName, maxid, publicNicInfo);
+            }
+            return new UnPlugNicAnswer(cmd, true, "success");
+        } catch (Exception e) {
+            s_logger.error("Unexpected exception: ", e);
+            return new UnPlugNicAnswer(cmd, false, "Unable to execute 
unPlugNicCommand due to " + e.toString());
+        }
+    }
+
     @Override
     public ExecutionResult executeInVR(String routerIP, String script, String 
args) {
         Pair<Boolean, String> result;
@@ -621,14 +683,18 @@ public class HypervDirectConnectResource extends 
ServerResourceBase implements S
 
     protected ExecutionResult 
prepareNetworkElementCommand(SetupGuestNetworkCommand cmd) {
         NicTO nic = cmd.getNic();
-        String routerIp = getRouterSshControlIp(cmd);
         String domrName =
                 cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME);
 
         try {
-            int ethDeviceNum = findRouterEthDeviceIndex(domrName, routerIp,
-                    nic.getMac());
-            nic.setDeviceId(ethDeviceNum);
+            URI broadcastUri = nic.getBroadcastUri();
+            int vlanId = 
Integer.parseInt(BroadcastDomainType.getValue(broadcastUri));
+            int ethDeviceNum = getVmNics(domrName, vlanId);
+            if (ethDeviceNum > 0) {
+                nic.setDeviceId(ethDeviceNum);
+            } else {
+                return new ExecutionResult(false, "Prepare SetupGuestNetwork 
failed due to unable to find the nic");
+            }
         } catch (Exception e) {
             String msg = "Prepare SetupGuestNetwork failed due to " + 
e.toString();
             s_logger.warn(msg, e);
@@ -640,23 +706,27 @@ public class HypervDirectConnectResource extends 
ServerResourceBase implements S
 
     private ExecutionResult prepareNetworkElementCommand(IpAssocVpcCommand 
cmd) {
         String routerName = 
cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME);
-        String routerIp = getRouterSshControlIp(cmd);
 
         try {
             IpAddressTO[] ips = cmd.getIpAddresses();
             for (IpAddressTO ip : ips) {
-
-                int ethDeviceNum = findRouterEthDeviceIndex(routerName, 
routerIp, ip.getVifMacAddress());
-                if (ethDeviceNum < 0) {
+                URI broadcastUri = 
BroadcastDomainType.fromString(ip.getBroadcastUri());
+                if (BroadcastDomainType.getSchemeValue(broadcastUri) != 
BroadcastDomainType.Vlan) {
+                    throw new InternalErrorException("Invalid Broadcast URI " 
+ ip.getBroadcastUri());
+                }
+                int vlanId = 
Integer.parseInt(BroadcastDomainType.getValue(broadcastUri));
+                int publicNicInfo = -1;
+                publicNicInfo = getVmNics(routerName, vlanId);
+                if (publicNicInfo < 0) {
                     if (ip.isAdd()) {
                         throw new InternalErrorException("Failed to find DomR 
VIF to associate/disassociate IP with.");
-                    } else {
+                        } else {
                         s_logger.debug("VIF to deassociate IP with does not 
exist, return success");
                         continue;
                     }
                 }
 
-                ip.setNicDevId(ethDeviceNum);
+                ip.setNicDevId(publicNicInfo);
             }
         } catch (Exception e) {
             s_logger.error("Prepare Ip Assoc failure on applying one ip due to 
exception:  ", e);
@@ -668,12 +738,17 @@ public class HypervDirectConnectResource extends 
ServerResourceBase implements S
 
     protected ExecutionResult prepareNetworkElementCommand(SetSourceNatCommand 
cmd) {
         String routerName = 
cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME);
-        String routerIp = getRouterSshControlIp(cmd);
         IpAddressTO pubIp = cmd.getIpAddress();
 
         try {
-            int ethDeviceNum = findRouterEthDeviceIndex(routerName, routerIp, 
pubIp.getVifMacAddress());
-            pubIp.setNicDevId(ethDeviceNum);
+            String broadcastUri = pubIp.getBroadcastUri();
+            int vlanId = 
Integer.parseInt(BroadcastDomainType.getValue(broadcastUri));
+            int ethDeviceNum = getVmNics(routerName, vlanId);
+            if (ethDeviceNum > 0) {
+                pubIp.setNicDevId(ethDeviceNum);
+            } else {
+                return new ExecutionResult(false, "Prepare Ip SNAT failed due 
to unable to find the nic");
+            }
         } catch (Exception e) {
             String msg = "Prepare Ip SNAT failure due to " + e.toString();
             s_logger.error(msg, e);
@@ -686,12 +761,16 @@ public class HypervDirectConnectResource extends 
ServerResourceBase implements S
         NicTO nic = cmd.getNic();
         String routerName =
                 cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME);
-        String routerIp = getRouterSshControlIp(cmd);
 
         try {
-            int ethDeviceNum = findRouterEthDeviceIndex(routerName, routerIp,
-                    nic.getMac());
-            nic.setDeviceId(ethDeviceNum);
+            URI broadcastUri = nic.getBroadcastUri();
+            int vlanId = 
Integer.parseInt(BroadcastDomainType.getValue(broadcastUri));
+            int ethDeviceNum = getVmNics(routerName, vlanId);
+            if (ethDeviceNum > 0) {
+                nic.setDeviceId(ethDeviceNum);
+            } else {
+                return new ExecutionResult(false, "Prepare SetNetworkACL 
failed due to unable to find the nic");
+            }
         } catch (Exception e) {
             String msg = "Prepare SetNetworkACL failed due to " + e.toString();
             s_logger.error(msg, e);
@@ -1730,6 +1809,27 @@ public class HypervDirectConnectResource extends 
ServerResourceBase implements S
         }
     }
 
+    protected void modifyNicVlan(String vmName, int vlanId, int pos) {
+        ModifyVmNicConfigCommand modifynic = new 
ModifyVmNicConfigCommand(vmName, vlanId, pos);
+        URI agentUri = null;
+        try {
+            String cmdName = ModifyVmNicConfigCommand.class.getName();
+            agentUri =
+                    new URI("https", null, _agentIp, _port,
+                            "/api/HypervResource/" + cmdName, null, null);
+        } catch (URISyntaxException e) {
+            String errMsg = "Could not generate URI for Hyper-V agent";
+            s_logger.error(errMsg, e);
+        }
+        String ansStr = postHttpRequest(s_gson.toJson(modifynic), agentUri);
+        Answer[] result = s_gson.fromJson(ansStr, Answer[].class);
+        s_logger.debug("executeRequest received response "
+                + s_gson.toJson(result));
+        if (result.length > 0) {
+            ModifyVmNicConfigAnswer ans = ((ModifyVmNicConfigAnswer)result[0]);
+        }
+    }
+
     protected void assignPublicIpAddress(final String vmName, final String 
privateIpAddress, final String publicIpAddress, final boolean add, final 
boolean firstIP,
             final boolean sourceNat, final String broadcastId, final String 
vlanGateway, final String vlanNetmask, final String vifMacAddress) throws 
Exception {
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/1b4325d2/server/src/com/cloud/network/vpc/VpcManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/vpc/VpcManagerImpl.java 
b/server/src/com/cloud/network/vpc/VpcManagerImpl.java
index c5a048c..2e63639 100644
--- a/server/src/com/cloud/network/vpc/VpcManagerImpl.java
+++ b/server/src/com/cloud/network/vpc/VpcManagerImpl.java
@@ -2289,6 +2289,7 @@ public class VpcManagerImpl extends ManagerBase 
implements VpcManager, VpcProvis
         hTypes.add(HypervisorType.KVM);
         hTypes.add(HypervisorType.Simulator);
         hTypes.add(HypervisorType.LXC);
+        hTypes.add(HypervisorType.Hyperv);
         return hTypes;
     }
 

Reply via email to