Как работать с vCenter из C# .NET
На данный момент есть два варианта работы.
- Первый - традиционный - это обращение к классам библиотеки VMWare.Vim.
Например - создаем ASP.NET C# приложение, добавляем к проекту reference - VMware.Vim.dll, VimService60.dll, VimService60.XmlSerializers.dll (который берем из установленного PowerCLI) и работаем как примерно описано тут: Getting started with vSphere .NET application development for PowerCLI users
- Второй - использование современного vSphere Management C# .NET SDK - https://github.com/vmware/vsphere-automation-sdk-.net.
Разница между ними - в функционале. Многие вещи в современном SDK еще не доработаны.
Библиотеки **VMWare.Vim** из PowerCLI до версии 6.3 (включительно) работают с System.Runtime 4.0.0 и пригоден для использования в проектах ASP.NET. Более поздние версии уже ориентированы на ASP.NET Core и для работы с ними нужен System.Runtime 4.2.0.
VM provisioning and customization using ASP.NET
https://github.com/itsChris/vmware-net/tree/master/vmware-net - vmware-net-master.zip Необходимые изменения:
( VimClient vimClient = new VimClient(); => VimClient vimClient = new VimClientImpl();)
VMware.Vim из комплекта PowerCLI 6.3 - powercli_6.3_vimdlls.rar
А вот и весь VMWare PowerCLI 6.3 целикомVMware PowerCLI 6.3.0
С текущими версиями vcenter (6.5 и выше) этот пример работает, если включить сильное шифрование (TLS 1.1, TLS 1.2) для .NET: https://kb.vmware.com/s/article/2137109
Windows Registry Editor Version 5.00 [HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\.NETFramework\v3.5] "SchUseStrongCrypto"=dword:00000001 [HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\.NETFramework\v4.0.30319] "SchUseStrongCrypto"=dword:00000001 [HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\.NETFramework\v4.5.1] "SchUseStrongCrypto"=dword:00000001 [HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\.NETFramework\v4.5.23026] "SchUseStrongCrypto"=dword:00000001 [HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\.NETFramework\v4.5.25000] "SchUseStrongCrypto"=dword:00000001 [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\v4.0.30319] "SchUseStrongCrypto"=dword:00000001
В противном случае ошибка - 'The underlying connection was closed: An unexpected error occurred on a send.'
Этот пример хорошо бы переписать под ASP.NET Core 2.0
Его в принципе невозможно собрать с версией VMware.Vim.dll из более поздних powercli 11.2, потому что она хочет System.Runtime 4.2.0.0, а он есть уже только в ASP.NET Core. Последняя версия VMware.Vim.dll, которая есть работает с ASP есть в составе PowerCLI 6.3.
https://github.com/alex-lucid/NAnt.ContinuousIntegration - nant.continuousintegration-master.zip
https://kb.vmware.com/s/article/2137109
Документация (уже не сильно актуальная)
VMWare vSphere Infrastructure SDK 2.5
VMWare vSphere Guest SDK 4.0
VMWare vSphere Web Services SDK 5.0
https://blogs.vmware.com/PowerCLI/2014/06/working-customization-specifications-powercli-part-3.html
вот кажется (полу)рабочий кусочек кода для vim25 (https://communities.vmware.com/thread/154918)
public void AssignIpToVm(string vmUuid, string ipAddress) { ManagedObjectReference vmRef = service.FindByUuid(sic.searchIndex, null, vmUuid, true); CustomizationSpec customsSpec = new CustomizationSpec(); CustomizationAdapterMapping adapterMap = new CustomizationAdapterMapping(); CustomizationIPSettings adapter = new CustomizationIPSettings(); //CustomizationCustomIpGenerator obj =new CustomizationCustomIpGenerator(); CustomizationFixedIp fixedIP = new CustomizationFixedIp(); fixedIP.ipAddress = ipAddress; adapterMap.adapter = adapter; adapterMap.adapter.ip = fixedIP; customsSpec.nicSettingMap = new CustomizationAdapterMapping[] { adapterMap }; CustomizationIdentitySettings idSettings = new CustomizationIdentitySettings(); customsSpec.identity = idSettings; CustomizationGlobalIPSettings gloIpSettings = new CustomizationGlobalIPSettings(); customsSpec.globalIPSettings = gloIpSettings; service.CustomizeVMTask(vmRef, customsSpec); }
https://communities.vmware.com/thread/452924
CustomizationSpec customsSpec2 = new CustomizationSpec(); CustomizationAdapterMapping adapterMap = new CustomizationAdapterMapping(); CustomizationIPSettings adapter = new CustomizationIPSettings(); CustomizationFixedIp fixedIP = new CustomizationFixedIp(); fixedIP.IpAddress = "192.168.2.83"; adapter.Ip = new CustomizationIpGenerator(); adapter.Gateway = new string[] {"192.168.2.3"}; adapterMap.Adapter = adapter; adapterMap.Adapter.Ip = fixedIP; adapterMap.Adapter.SubnetMask = "255.255.255.0"; customsSpec2.NicSettingMap = new CustomizationAdapterMapping[] { adapterMap }; var custwinoptions = new CustomizationWinOptions(); customsSpec2.Options = custwinoptions; customsSpec2.GlobalIPSettings = new CustomizationGlobalIPSettings(); var idid=new CustomizationSysprep(); idid.Identification = new CustomizationIdentification(); //idid.Identification.DomainAdmin = ""; //idid.Identification. idid.GuiUnattended=new CustomizationGuiUnattended(); idid.GuiUnattended.AutoLogon = true; idid.UserData = new CustomizationUserData(); var custname = new CustomizationVirtualMachineName(); idid.UserData.ComputerName = custname; idid.UserData.FullName = "userdataFullName"; idid.UserData.OrgName = "userDataOrgName"; idid.UserData.ProductId = ""; customsSpec2.Identity = idid; var cName = new CustomizationName(); customizeVMTask = targetVirtualMachine.CustomizeVM_Task(customsSpec2);
I used ASP.net with C# as based language to clone VM and change the IP. The code is work and the IP changed. FYI I used vim25api. Here is the code. VirtualMachineCloneSpec cloneSpec = new VirtualMachineCloneSpec(); string guestCustomizationScript = “your guest customization script name”; //get your customization spec item by name. CustomizationSpecItem cusSpecItem = _service.GetCustomizationSpec(_sic.customizationSpecManager, guestCustomizationScript); cloneSpec.customization = cusSpecItem.spec; //SET IP ADDRESS CustomizationFixedIp fixedIP = new CustomizationFixedIp(); fixedIP.ipAddress = ipAddress; cloneSpec.customization.nicSettingMap[0].adapter.ip = fixedIP; //USE cloneSpec AS PARAMETER TO CLONEVM_TASK ManagedObjectReference cloneTask = _service.CloneVM_Task(vmRef, vmFolderRef, cloneName, cloneSpec);
Кусочек кода на java, который кастомизирует виртуалочку
CustomizationSpecItem specItem = null; CustomizationSpecInfo info = new CustomizationSpecInfo(); specItem = new CustomizationSpecItem(); specItem.setInfo(info); CustomizationSpec cspec = new CustomizationSpec(); CustomizationGlobalIPSettings gIP = new CustomizationGlobalIPSettings(); cspec.setGlobalIPSettings(gIP); // This is windows so choose the sysprep CustomizationSysprep sprep = new CustomizationSysprep(); CustomizationGuiUnattended guiUnattended = new CustomizationGuiUnattended(); guiUnattended.setAutoLogon(false); // do not autoLogin on reboot for customization. guiUnattended.setAutoLogonCount(0); // do not autologin on reboot. CustomizationPassword pass = new CustomizationPassword(); pass.setPlainText(true); pass.setValue("ca$hc0wS"); guiUnattended.setPassword(pass); guiUnattended.setTimeZone(4); // set to Eastern time. sprep.setGuiUnattended(guiUnattended); // add VM to WORKGROUP CustomizationIdentification identification = new CustomizationIdentification(); identification.setJoinWorkgroup("WORKGROUP"); sprep.setIdentification(identification); String productId = ""; //"00477-001-0000347-84147"; /*String productId = queryProductId("OS"); // only needed for windows os's if ("Windows2008") { CustomizationLicenseFilePrintData licenseFilePrintData = new CustomizationLicenseFilePrintData(); licenseFilePrintData.setAutoMode(CustomizationLicenseDataMode.PER_SERVER); licenseFilePrintData.setAutoUsers(5); sprep.setLicenseFilePrintData(licenseFilePrintData); }*/ // setup UserData CustomizationUserData userData = new CustomizationUserData(); CustomizationFixedName n = new CustomizationFixedName(); n.setName("WinSQLCustom"); userData.setComputerName(n); userData.setProductId(productId); userData.setFullName("WinSQLCustom.maithri"); // This may change in the future userData.setOrgName("IGATE"); userData.setProductId(productId); // Product Serial (needed for Windows 2003 and 2008) sprep.setUserData(userData); cspec.setIdentity(sprep); // NicSettingMap part CustomizationAdapterMapping adaptorMap = new CustomizationAdapterMapping(); CustomizationIPSettings adapter = new CustomizationIPSettings(); CustomizationFixedIp fixedIp = new CustomizationFixedIp(); String dnsList = "10.115.200.100"; adapter.setDnsDomain(dnsList); fixedIp.setIpAddress("10.115.200.109"); adapter.setIp(fixedIp); String subnetmask = "255.255.255.0"; adapter.setSubnetMask(subnetmask); adaptorMap.setAdapter(adapter); CustomizationWinOptions options = new CustomizationWinOptions(); options.setChangeSID(true); options.setDeleteAccounts(false); cspec.setOptions(options); specItem.setSpec(cspec); System.out.println("Check Point 4"); try{ System.out.printf("vm mor2: %s \n",vmToClone); vimPort.customizeVMTask(vmToClone, specItem.getSpec()); System.out.println("Check Point 5"); } //catch (CustomizationFault fault) catch (Exception e) { e.printStackTrace();System.err.println("Sample code failed "); System.exit(1); } } catch (Exception e) { e.printStackTrace();System.err.println("Sample code failed 2 "); System.exit(1); } finally { // Always close connectionl, even if errors occure. if (vimPort != null && serviceContent != null) { try { vimPort.logout(serviceContent.getSessionManager()); } catch (com.vmware.vim25.RuntimeFaultFaultMsg rffm) { System.out.println("Sample code failed while logging out after a previous failure."); rffm.printStackTrace(); } } }
Discussion