From f9cf2c241ba427e35ae6bb2843071e2b6cffffaf Mon Sep 17 00:00:00 2001 From: Rajesh Battala Date: Mon, 5 May 2014 12:55:59 +0530 Subject: [PATCH] CLOUDSTACK-6518 [Hyper-V] Efficient way of finding the empty nic in VR/VpcVR to configure VPC entities --- .../cloud/agent/api/GetVmConfigAnswer.java | 7 +- .../agent/api/ModifyVmNicConfigCommand.java | 17 + .../HypervResource/CloudStackTypes.cs | 13 +- .../HypervResourceController.cs | 68 ++-- .../HypervResource/IWmiCallsV2.cs | 6 +- .../HypervResource/WmiCallsV2.cs | 291 +++++++++++++++--- .../resource/HypervDirectConnectResource.java | 51 ++- 7 files changed, 365 insertions(+), 88 deletions(-) diff --git a/core/src/com/cloud/agent/api/GetVmConfigAnswer.java b/core/src/com/cloud/agent/api/GetVmConfigAnswer.java index 46e003ecae3..e0d15363418 100644 --- a/core/src/com/cloud/agent/api/GetVmConfigAnswer.java +++ b/core/src/com/cloud/agent/api/GetVmConfigAnswer.java @@ -42,13 +42,15 @@ public class GetVmConfigAnswer extends Answer { public class NicDetails { String macAddress; int vlanid; + boolean state; public NicDetails() { } - public NicDetails(String macAddress, int vlanid) { + public NicDetails(String macAddress, int vlanid, boolean state) { this.macAddress = macAddress; this.vlanid = vlanid; + this.state = state; } public String getMacAddress() { @@ -59,6 +61,9 @@ public class GetVmConfigAnswer extends Answer { return vlanid; } + public boolean getState() { + return state; + } } @Override diff --git a/core/src/com/cloud/agent/api/ModifyVmNicConfigCommand.java b/core/src/com/cloud/agent/api/ModifyVmNicConfigCommand.java index 5f4f0e1d9ac..54c0eb098b1 100644 --- a/core/src/com/cloud/agent/api/ModifyVmNicConfigCommand.java +++ b/core/src/com/cloud/agent/api/ModifyVmNicConfigCommand.java @@ -22,6 +22,9 @@ public class ModifyVmNicConfigCommand extends Command { int vlan; String macAddress; int index; + boolean enable; + String switchLableName; + protected ModifyVmNicConfigCommand() { } @@ -37,10 +40,24 @@ public class ModifyVmNicConfigCommand extends Command { this.index = position; } + public ModifyVmNicConfigCommand(String vmName, int vlan, int position, boolean enable) { + this.vmName = vmName; + this.vlan = vlan; + this.index = position; + this.enable = enable; + } + public String getVmName() { return vmName; } + public String getSwitchLableName() { + return switchLableName; + } + + public void setSwitchLableName(String switchlableName) { + this.switchLableName = switchlableName; + } @Override public boolean executeInSequence() { diff --git a/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/CloudStackTypes.cs b/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/CloudStackTypes.cs index f7bed713c3e..4516191c014 100644 --- a/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/CloudStackTypes.cs +++ b/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/CloudStackTypes.cs @@ -717,11 +717,22 @@ namespace HypervResource public string macaddress; [JsonProperty("vlanid")] public int vlanid; + [JsonProperty("state")] + public bool state; public NicDetails() { } - public NicDetails(String macaddress, int vlanid) + public NicDetails(String macaddress, int vlanid, int enabledState) { this.macaddress = macaddress; this.vlanid = vlanid; + if (enabledState == 2) + { + this.state = true; + } + else + { + this.state = false; + } + } } diff --git a/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/HypervResourceController.cs b/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/HypervResourceController.cs index c28cb66120b..37f5f5304b7 100644 --- a/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/HypervResourceController.cs +++ b/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/HypervResourceController.cs @@ -1077,11 +1077,10 @@ namespace HypervResource using (log4net.NDC.Push(Guid.NewGuid().ToString())) { logger.Info(CloudStackTypes.PlugNicCommand + Utils.CleanString(cmd.ToString())); - object ansContent = new { result = true, - details = "instead of plug, change he network settings", + details = "Hot Nic plug not supported, change any empty virtual network adapter network settings", contextMap = contextMap }; return ReturnCloudStackTypedJArray(ansContent, CloudStackTypes.PlugNicAnswer); @@ -1394,18 +1393,21 @@ namespace HypervResource logger.Info(CloudStackTypes.ModifyVmNicConfigCommand + Utils.CleanString(cmd.ToString())); bool result = false; String vmName = cmd.vmName; - uint vlan = (uint)cmd.vlan; + String vlan = cmd.vlan; string macAddress = cmd.macAddress; - uint pos = cmd.index; + uint pos = cmd.index; + bool enable = cmd.enable; + string switchLableName = cmd.switchLableName; if (macAddress != null) { - wmiCallsV2.ModifyVmVLan(vmName, vlan, macAddress); - } - else if (pos > 1) - { - wmiCallsV2.ModifyVmVLan(vmName, vlan, pos); - } + wmiCallsV2.ModifyVmVLan(vmName, vlan, macAddress); result = true; + } + else if (pos >= 1) + { + wmiCallsV2.ModifyVmVLan(vmName, vlan, pos, enable, switchLableName); + result = true; + } object ansContent = new { @@ -1432,31 +1434,37 @@ namespace HypervResource List nicDetails = new List(); var nicSettingsViaVm = wmiCallsV2.GetEthernetPortSettings(vm); NicDetails nic = null; - String[] macAddress = new String[nicSettingsViaVm.Length]; - int index = 0; + int index = 0; + int[] nicStates = new int[8]; + int[] nicVlan = new int[8]; + int vlanid = 1; + + var ethernetConnections = wmiCallsV2.GetEthernetConnections(vm); + foreach (EthernetPortAllocationSettingData item in ethernetConnections) + { + EthernetSwitchPortVlanSettingData vlanSettings = wmiCallsV2.GetVlanSettings(item); + if (vlanSettings == null) + { + vlanid = -1; + } + else + { + vlanid = vlanSettings.AccessVlanId; + } + nicStates[index] = (Int32)(item.EnabledState); + nicVlan[index] = vlanid; + index++; + } + + index = 0; foreach (SyntheticEthernetPortSettingData item in nicSettingsViaVm) { - macAddress[index++] = item.Address; - } - - index = 0; - var ethernetConnections = wmiCallsV2.GetEthernetConnections(vm); - int vlanid = 1; - foreach (EthernetPortAllocationSettingData item in ethernetConnections) - { - EthernetSwitchPortVlanSettingData vlanSettings = wmiCallsV2.GetVlanSettings(item); - if (vlanSettings == null) - { - vlanid = -1; - } - else - { - vlanid = vlanSettings.AccessVlanId; - } - nic = new NicDetails(macAddress[index++], vlanid); + nic = new NicDetails(item.Address, nicVlan[index], nicStates[index]); + index++; nicDetails.Add(nic); } + result = true; object ansContent = new diff --git a/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/IWmiCallsV2.cs b/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/IWmiCallsV2.cs index c5e5bf3b690..68731987649 100644 --- a/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/IWmiCallsV2.cs +++ b/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/IWmiCallsV2.cs @@ -70,7 +70,9 @@ namespace HypervResource void SetState(ComputerSystem vm, ushort requiredState); Dictionary GetVmSync(String privateIpAddress); string GetVmNote(System.Management.ManagementPath sysPath); - void ModifyVmVLan(string vmName, uint vlanid, string mac); - void ModifyVmVLan(string vmName, uint vlanid, uint pos); + void ModifyVmVLan(string vmName, String vlanid, string mac); + void ModifyVmVLan(string vmName, String vlanid, uint pos, bool enable, string switchLabelName); + void DisableVmNics(); + void DisableNicVlan(String mac, String vmName); } } diff --git a/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/WmiCallsV2.cs b/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/WmiCallsV2.cs index 71d8cbdd308..fb14a0f7c63 100644 --- a/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/WmiCallsV2.cs +++ b/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/WmiCallsV2.cs @@ -229,7 +229,6 @@ namespace HypervResource string errMsg = vmName; var diskDrives = vmInfo.disks; var bootArgs = vmInfo.bootArgs; - string defaultvlan = "4094"; // assert errMsg = vmName + ": missing disk information, array empty or missing, agent expects *at least* one disk for a VM"; @@ -380,6 +379,8 @@ namespace HypervResource } int nicCount = 0; + int enableState = 2; + // Add the Nics to the VM in the deviceId order. foreach (var nc in nicInfo) { @@ -418,13 +419,17 @@ namespace HypervResource throw ex; } } - if(nicIp.Equals("0.0.0.0") && nicNetmask.Equals("255.255.255.255") ) { - // this is the extra nic added to VR. - vlan = defaultvlan; - } - + + if (nicid == nicCount) { + if (nicIp.Equals("0.0.0.0") && nicNetmask.Equals("255.255.255.255")) + { + // this is the extra nic added to VR. + vlan = null; + enableState = 3; + } + // Create network adapter var newAdapter = CreateNICforVm(newVm, mac); String switchName =""; @@ -432,10 +437,11 @@ namespace HypervResource { switchName = nic.name; } - + EthernetPortAllocationSettingData portSettings = null; // connection to vswitch - var portSettings = AttachNicToPort(newVm, newAdapter, switchName); - + portSettings = AttachNicToPort(newVm, newAdapter, switchName, enableState); + //reset the flag for other nics + enableState = 2; // set vlan if (vlan != null) { @@ -449,6 +455,8 @@ namespace HypervResource logger.DebugFormat("Created adapter {0} on port {1}, {2}", newAdapter.Path, portSettings.Path, (vlan == null ? "No VLAN" : "VLAN " + vlan)); + // logger.DebugFormat("Created adapter {0} on port {1}, {2}", + // newAdapter.Path, portSettings.Path, (vlan == null ? "No VLAN" : "VLAN " + vlan)); } } nicCount++; @@ -464,14 +472,8 @@ namespace HypervResource String bootargs = bootArgs; AddUserData(vm, bootargs); - - // Verify key added to subsystem - //kvpInfo = GetKvpSettings(vmSettings); - - // HostExchangesItems are embedded objects in the sense that the object value is stored and not a reference to the object. - //kvpProps = kvpInfo.HostExchangeItems; - } + // call patch systemvm iso only for systemvms if (vmName.StartsWith("r-") || vmName.StartsWith("s-") || vmName.StartsWith("v-")) { @@ -524,7 +526,7 @@ namespace HypervResource return false; } - private EthernetPortAllocationSettingData AttachNicToPort(ComputerSystem newVm, SyntheticEthernetPortSettingData newAdapter, String vSwitchName) + private EthernetPortAllocationSettingData AttachNicToPort(ComputerSystem newVm, SyntheticEthernetPortSettingData newAdapter, String vSwitchName, int enableState) { // Get the virtual switch VirtualEthernetSwitch vSwitch = GetExternalVirtSwitch(vSwitchName); @@ -553,7 +555,7 @@ namespace HypervResource var newEthernetPortSettings = new EthernetPortAllocationSettingData((ManagementBaseObject)defaultEthernetPortSettingsObj.LateBoundObject.Clone()); newEthernetPortSettings.LateBoundObject["Parent"] = newAdapter.Path.Path; newEthernetPortSettings.LateBoundObject["HostResource"] = new string[] { vSwitch.Path.Path }; - + newEthernetPortSettings.LateBoundObject["EnabledState"] = enableState; //3 disabled 2 Enabled // Insert NIC into vm string[] newResources = new string[] { newEthernetPortSettings.LateBoundObject.GetText(System.Management.TextFormat.CimDtd20) }; ManagementPath[] newResourcePaths = AddVirtualResource(newResources, newVm); @@ -913,13 +915,16 @@ namespace HypervResource return new ResourceAllocationSettingData((ManagementBaseObject)defaultDiskDriveSettings.LateBoundObject.Clone()); } - // Modify the systemvm nic's VLAN id - public void ModifyVmVLan(string vmName, uint vlanid, String mac) - { + // Modify the systemvm nic's VLAN id + public void ModifyVmVLan(string vmName, String vlanid, String mac) + { + int enableState = 2; + bool enable = true; ComputerSystem vm = GetComputerSystem(vmName); SyntheticEthernetPortSettingData[] nicSettingsViaVm = GetEthernetPortSettings(vm); // Obtain controller for Hyper-V virtualisation subsystem - VirtualSystemManagementService vmMgmtSvc = GetVirtualisationSystemManagementService(); + VirtualSystemManagementService vmMgmtSvc = GetVirtualisationSystemManagementService(); + EthernetPortAllocationSettingData networkAdapter = null; string normalisedMAC = string.Join("", (mac.Split(new char[] { ':' }))); int index = 0; foreach (SyntheticEthernetPortSettingData item in nicSettingsViaVm) @@ -929,35 +934,229 @@ namespace HypervResource break; } index++; + } + String vSwitchName = ""; + VirtualEthernetSwitch vSwitch = GetExternalVirtSwitch(vSwitchName); + EthernetPortAllocationSettingData[] ethernetConnections = GetEthernetConnections(vm); + networkAdapter = ethernetConnections[index]; + networkAdapter.LateBoundObject["EnabledState"] = enableState; //3 disabled 2 Enabled + networkAdapter.LateBoundObject["HostResource"] = new string[] { vSwitch.Path.Path }; + + ModifyVmResources(vmMgmtSvc, vm, new String[] { + networkAdapter.LateBoundObject.GetText(TextFormat.CimDtd20) + }); + + EthernetSwitchPortVlanSettingData vlanSettings = GetVlanSettings(ethernetConnections[index]); + + if (vlanSettings == null) + { + // when modifying nic to not connected dont create vlan + if (enable) + { + if (vlanid != null) + { + SetPortVlan(vlanid, networkAdapter); + } + } + } + else + { + if (enable) + { + if (vlanid != null) + { + //Assign vlan configuration to nic + vlanSettings.LateBoundObject["AccessVlanId"] = vlanid; + vlanSettings.LateBoundObject["OperationMode"] = 1; + ModifyFeatureVmResources(vmMgmtSvc, vm, new String[] { + vlanSettings.LateBoundObject.GetText(TextFormat.CimDtd20)}); + } + } + else + { + var virtSysMgmtSvc = GetVirtualisationSystemManagementService(); + + // This method will remove the vlan settings present on the Nic + ManagementPath jobPath; + var ret_val = virtSysMgmtSvc.RemoveFeatureSettings(new ManagementPath[] { vlanSettings.Path }, + out jobPath); + + // If the Job is done asynchronously + if (ret_val == ReturnCode.Started) + { + JobCompleted(jobPath); + } + else if (ret_val != ReturnCode.Completed) + { + var errMsg = string.Format( + "Failed to remove vlan resource {0} from VM {1} (GUID {2}) due to {3}", + vlanSettings.Path, + vm.ElementName, + vm.Name, + ReturnCode.ToString(ret_val)); + var ex = new WmiException(errMsg); + logger.Error(errMsg, ex); + } + } } - - //TODO: make sure the index wont be out of range. - - EthernetPortAllocationSettingData[] ethernetConnections = GetEthernetConnections(vm); - EthernetSwitchPortVlanSettingData vlanSettings = GetVlanSettings(ethernetConnections[index]); - - //Assign configuration to new NIC - vlanSettings.LateBoundObject["AccessVlanId"] = vlanid; - vlanSettings.LateBoundObject["OperationMode"] = 1; - ModifyFeatureVmResources(vmMgmtSvc, vm, new String[] { - vlanSettings.LateBoundObject.GetText(TextFormat.CimDtd20)}); + } + + // This is disabling the VLAN settings on the specified nic. It works Awesome. + public void DisableNicVlan(String mac, String vmName) + { + ComputerSystem vm = GetComputerSystem(vmName); + SyntheticEthernetPortSettingData[] nicSettingsViaVm = GetEthernetPortSettings(vm); + // Obtain controller for Hyper-V virtualisation subsystem + VirtualSystemManagementService vmMgmtSvc = GetVirtualisationSystemManagementService(); + string normalisedMAC = string.Join("", (mac.Split(new char[] { ':' }))); + int index = 0; + foreach (SyntheticEthernetPortSettingData item in nicSettingsViaVm) + { + if (normalisedMAC.ToLower().Equals(item.Address.ToLower())) + { + break; + } + index++; + } + + //TODO: make sure the index wont be out of range. + + EthernetPortAllocationSettingData[] ethernetConnections = GetEthernetConnections(vm); + EthernetSwitchPortVlanSettingData vlanSettings = GetVlanSettings(ethernetConnections[index]); + + var virtSysMgmtSvc = GetVirtualisationSystemManagementService(); + + // This method will remove the vlan settings present on the Nic + ManagementPath jobPath; + var ret_val = virtSysMgmtSvc.RemoveFeatureSettings(new ManagementPath[]{ vlanSettings.Path}, + out jobPath); + + // If the Job is done asynchronously + if (ret_val == ReturnCode.Started) + { + JobCompleted(jobPath); + } + else if (ret_val != ReturnCode.Completed) + { + var errMsg = string.Format( + "Failed to remove vlan resource {0} from VM {1} (GUID {2}) due to {3}", + vlanSettings.Path, + vm.ElementName, + vm.Name, + ReturnCode.ToString(ret_val)); + var ex = new WmiException(errMsg); + logger.Error(errMsg, ex); + throw ex; + } } - // Modify the systemvm nic's VLAN id - public void ModifyVmVLan(string vmName, uint vlanid, uint pos) - { - ComputerSystem vm = GetComputerSystem(vmName); - // Obtain controller for Hyper-V virtualisation subsystem - VirtualSystemManagementService vmMgmtSvc = GetVirtualisationSystemManagementService(); + // Modify All VM Nics to disable + public void DisableVmNics() + { + ComputerSystem vm = GetComputerSystem("test"); + EthernetPortAllocationSettingData[] ethernetConnections = GetEthernetConnections(vm); + // Get the virtual switch + VirtualEthernetSwitch vSwitch = GetExternalVirtSwitch("vswitch2"); + + foreach (EthernetPortAllocationSettingData epasd in ethernetConnections) + { + epasd.LateBoundObject["EnabledState"] = 2; //3 disabled 2 Enabled + epasd.LateBoundObject["HostResource"] = new string[] { vSwitch.Path.Path }; + + VirtualSystemManagementService vmMgmtSvc = GetVirtualisationSystemManagementService(); + ModifyVmResources(vmMgmtSvc, vm, new String[] { + epasd.LateBoundObject.GetText(TextFormat.CimDtd20) + }); + } + } - EthernetPortAllocationSettingData[] ethernetConnections = GetEthernetConnections(vm); - EthernetSwitchPortVlanSettingData vlanSettings = GetVlanSettings(ethernetConnections[pos]); + // Modify the systemvm nic's VLAN id + public void ModifyVmVLan(string vmName, String vlanid, uint pos, bool enable, string switchLabelName) + { + // This if to modify the VPC VR nics + // 1. Enable the network adapter and connect to a switch + // 2. modify the vlan id + int enableState = 2; + ComputerSystem vm = GetComputerSystem(vmName); + EthernetPortAllocationSettingData[] ethernetConnections = GetEthernetConnections(vm); + // Obtain controller for Hyper-V virtualisation subsystem + EthernetPortAllocationSettingData networkAdapter = null; + VirtualSystemManagementService vmMgmtSvc = GetVirtualisationSystemManagementService(); + + String vSwitchName = ""; + if (switchLabelName != null) + vSwitchName = switchLabelName; + VirtualEthernetSwitch vSwitch = GetExternalVirtSwitch(vSwitchName); + if (pos <= ethernetConnections.Length) + { + if (enable == false) + { + enableState = 3; + } + + networkAdapter = ethernetConnections[pos]; + networkAdapter.LateBoundObject["EnabledState"] = enableState; //3 disabled 2 Enabled + networkAdapter.LateBoundObject["HostResource"] = new string[] { vSwitch.Path.Path }; + ModifyVmResources(vmMgmtSvc, vm, new String[] { + networkAdapter.LateBoundObject.GetText(TextFormat.CimDtd20) + }); + } - //Assign configuration to new NIC - vlanSettings.LateBoundObject["AccessVlanId"] = vlanid; - vlanSettings.LateBoundObject["OperationMode"] = 1; - ModifyFeatureVmResources(vmMgmtSvc, vm, new String[] { - vlanSettings.LateBoundObject.GetText(TextFormat.CimDtd20)}); + // check when nic is disabled, removing vlan is required or not. + EthernetPortAllocationSettingData[] vmEthernetConnections = GetEthernetConnections(vm); + EthernetSwitchPortVlanSettingData vlanSettings = GetVlanSettings(vmEthernetConnections[pos]); + + if (vlanSettings == null) + { + // when modifying nic to not connected dont create vlan + if (enable) + { + if (vlanid != null) + { + SetPortVlan(vlanid, networkAdapter); + } + } + } + else + { + if (enable) + { + if (vlanid != null) + { + //Assign vlan configuration to nic + vlanSettings.LateBoundObject["AccessVlanId"] = vlanid; + vlanSettings.LateBoundObject["OperationMode"] = 1; + ModifyFeatureVmResources(vmMgmtSvc, vm, new String[] { + vlanSettings.LateBoundObject.GetText(TextFormat.CimDtd20)}); + } + } + else + { + var virtSysMgmtSvc = GetVirtualisationSystemManagementService(); + + // This method will remove the vlan settings present on the Nic + ManagementPath jobPath; + var ret_val = virtSysMgmtSvc.RemoveFeatureSettings(new ManagementPath[] { vlanSettings.Path }, + out jobPath); + + // If the Job is done asynchronously + if (ret_val == ReturnCode.Started) + { + JobCompleted(jobPath); + } + else if (ret_val != ReturnCode.Completed) + { + var errMsg = string.Format( + "Failed to remove vlan resource {0} from VM {1} (GUID {2}) due to {3}", + vlanSettings.Path, + vm.ElementName, + vm.Name, + ReturnCode.ToString(ret_val)); + var ex = new WmiException(errMsg); + logger.Error(errMsg, ex); + } + } + } } public void AttachIso(string displayName, string iso) 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 12fc39d1973..7888e43896e 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 @@ -177,7 +177,6 @@ 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 @@ -535,11 +534,15 @@ public class HypervDirectConnectResource extends ServerResourceBase implements S } int vlanId = Integer.parseInt(BroadcastDomainType.getValue(broadcastUri)); int publicNicInfo = -1; - publicNicInfo = getVmNics(vmName, maxid); + publicNicInfo = getVmFreeNicIndex(vmName); if (publicNicInfo > 0) { - modifyNicVlan(vmName, vlanId, publicNicInfo); + modifyNicVlan(vmName, vlanId, publicNicInfo, true, cmd.getNic().getName()); + return new PlugNicAnswer(cmd, true, "success"); } - return new PlugNicAnswer(cmd, true, "success"); + String msg = " Plug Nic failed for the vm as it has reached max limit of NICs to be added"; + s_logger.warn(msg); + return new PlugNicAnswer(cmd, false, msg); + } catch (Exception e) { s_logger.error("Unexpected exception: ", e); return new PlugNicAnswer(cmd, false, "Unable to execute PlugNicCommand due to " + e.toString()); @@ -563,7 +566,7 @@ public class HypervDirectConnectResource extends ServerResourceBase implements S int publicNicInfo = -1; publicNicInfo = getVmNics(vmName, vlanId); if (publicNicInfo > 0) { - modifyNicVlan(vmName, maxid, publicNicInfo); + modifyNicVlan(vmName, 2, publicNicInfo, false, ""); } return new UnPlugNicAnswer(cmd, true, "success"); } catch (Exception e) { @@ -1765,6 +1768,37 @@ public class HypervDirectConnectResource extends ServerResourceBase implements S return new IpAssocAnswer(cmd, results); } + + protected int getVmFreeNicIndex(String vmName) { + GetVmConfigCommand vmConfig = new GetVmConfigCommand(vmName); + URI agentUri = null; + int nicposition = -1; + try { + String cmdName = GetVmConfigCommand.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(vmConfig), agentUri); + Answer[] result = s_gson.fromJson(ansStr, Answer[].class); + s_logger.debug("GetVmConfigCommand response received " + + s_gson.toJson(result)); + if (result.length > 0) { + GetVmConfigAnswer ans = ((GetVmConfigAnswer)result[0]); + List nics = ans.getNics(); + for (NicDetails nic : nics) { + if (nic.getState() == false) { + nicposition = nics.indexOf(nic); + break; + } + } + } + return nicposition; + } + protected int getVmNics(String vmName, int vlanid) { GetVmConfigCommand vmConfig = new GetVmConfigCommand(vmName); URI agentUri = null; @@ -1816,8 +1850,9 @@ public class HypervDirectConnectResource extends ServerResourceBase implements S } } - protected void modifyNicVlan(String vmName, int vlanId, int pos) { - ModifyVmNicConfigCommand modifynic = new ModifyVmNicConfigCommand(vmName, vlanId, pos); + protected void modifyNicVlan(String vmName, int vlanId, int pos, boolean enable, String switchLabelName) { + ModifyVmNicConfigCommand modifyNic = new ModifyVmNicConfigCommand(vmName, vlanId, pos, enable); + modifyNic.setSwitchLableName(switchLabelName); URI agentUri = null; try { String cmdName = ModifyVmNicConfigCommand.class.getName(); @@ -1828,7 +1863,7 @@ public class HypervDirectConnectResource extends ServerResourceBase implements S String errMsg = "Could not generate URI for Hyper-V agent"; s_logger.error(errMsg, e); } - String ansStr = postHttpRequest(s_gson.toJson(modifynic), agentUri); + 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));