private async Task <TaskInfo> GetVimTaskInfo(ManagedObjectReference task) { await Connect(); TaskInfo info = new TaskInfo(); try { RetrievePropertiesResponse response = await _vim.RetrievePropertiesAsync( _props, FilterFactory.TaskFilter(task) ); ObjectContent[] oc = response.returnval; info = (TaskInfo)oc[0]?.propSet[0]?.val; } catch (Exception ex) { _logger.LogError(ex, "Failed to get TaskInfo for {0}", task.Value); info = new TaskInfo { task = task, state = TaskInfoState.error }; } return(info); }
public override async Task <VmNetwork[]> GetVmNetworks(ManagedObjectReference mor) { var result = new List <VmNetwork>(); RetrievePropertiesResponse response = await _client.vim.RetrievePropertiesAsync( _client.props, FilterFactory.VmFilter(mor, "name config")); ObjectContent[] oc = response.returnval; foreach (ObjectContent obj in oc) { string vmName = obj.GetProperty("name").ToString(); VirtualMachineConfigInfo config = obj.GetProperty("config") as VirtualMachineConfigInfo; foreach (VirtualEthernetCard card in config.hardware.device.OfType <VirtualEthernetCard>()) { if (card.backing is VirtualEthernetCardDistributedVirtualPortBackingInfo) { var back = card.backing as VirtualEthernetCardDistributedVirtualPortBackingInfo; result.Add(new VmNetwork { NetworkMOR = $"DistributedVirtualPortgroup|{back.port.portgroupKey}", VmName = vmName }); } } } return(result.ToArray()); }
public override async Task <PortGroupAllocation[]> LoadPortGroups() { var list = new List <PortGroupAllocation>(); RetrievePropertiesResponse response = await _client.vim.RetrievePropertiesAsync( _client.props, FilterFactory.OpaqueNetworkFilter(_client.cluster)); ObjectContent[] clunkyTree = response.returnval; foreach (var dvpg in clunkyTree.FindType("OpaqueNetwork")) { var config = (OpaqueNetworkSummary)dvpg.GetProperty("summary"); if (Regex.Match(config.name, _client.ExcludeNetworkMask).Success) { continue; } list.Add( new PortGroupAllocation { Net = config.name, Key = $"{config.opaqueNetworkType}#{config.opaqueNetworkId}", Switch = config.opaqueNetworkType } ); } return(list.ToArray()); }
public override async Task <VmNetwork[]> GetVmNetworks(ManagedObjectReference mor) { List <VmNetwork> result = new List <VmNetwork>(); RetrievePropertiesResponse response = await _client.vim.RetrievePropertiesAsync( _client.props, FilterFactory.VmFilter(mor, "name config.hardware")); ObjectContent[] oc = response.returnval; foreach (ObjectContent obj in oc) { // if (!obj.IsInPool(_client.pool)) // continue; string vmName = obj.GetProperty("name").ToString(); VirtualHardware hardware = obj.GetProperty("config.hardware") as VirtualHardware; foreach (VirtualEthernetCard card in hardware.device.OfType <VirtualEthernetCard>()) { result.Add(new VmNetwork { NetworkMOR = ((VirtualEthernetCardNetworkBackingInfo)card.backing).deviceName, VmName = vmName }); } } return(result.ToArray()); }
public override async Task <PortGroupAllocation[]> LoadPortGroups() { RetrievePropertiesResponse response = await _client.vim.RetrievePropertiesAsync( _client.props, FilterFactory.NetworkFilter(_client.net)); ObjectContent[] oc = response.returnval; HostPortGroup[] pgs = (HostPortGroup[])oc[0].propSet[0].val; var list = new List <PortGroupAllocation>(); foreach (HostPortGroup pg in pgs) { if (Regex.Match(pg.spec.name, _client.ExcludeNetworkMask).Success) { continue; } if (pg.spec.name.Contains("#")) { list.Add(new PortGroupAllocation { Net = pg.spec.name, Key = "HostPortGroup|" + pg.spec.name, VlanId = pg.spec.vlanId, Switch = pg.spec.vswitchName }); } } return(list.ToArray()); }
private async Task <Vm> GetVirtualMachine(ManagedObjectReference mor) { RetrievePropertiesResponse response = await _vim.RetrievePropertiesAsync( _props, FilterFactory.VmFilter(mor)); ObjectContent[] oc = response.returnval; return((oc.Length > 0) ? LoadVm(oc[0]) : null); }
private async Task <NetVimClient.ObjectContent[]> LoadReferenceTree(VimPortTypeClient client) { var plan = new TraversalSpec { name = "FolderTraverseSpec", type = "Folder", path = "childEntity", selectSet = new SelectionSpec[] { new TraversalSpec() { type = "Datacenter", path = "datastore", selectSet = new SelectionSpec[] { new SelectionSpec { name = "FolderTraverseSpec" } } }, new TraversalSpec() { type = "Folder", path = "childEntity", selectSet = new SelectionSpec[] { new SelectionSpec { name = "FolderTraverseSpec" } } } } }; var props = new PropertySpec[] { new PropertySpec { type = "Datastore", pathSet = new string[] { "name", "browser" } } }; ObjectSpec objectspec = new ObjectSpec(); objectspec.obj = _sic.rootFolder; objectspec.selectSet = new SelectionSpec[] { plan }; PropertyFilterSpec filter = new PropertyFilterSpec(); filter.propSet = props; filter.objectSet = new ObjectSpec[] { objectspec }; PropertyFilterSpec[] filters = new PropertyFilterSpec[] { filter }; RetrievePropertiesResponse response = await client.RetrievePropertiesAsync(_props, filters); return(response.returnval); }
private async Task <VirtualMachine> GetMachineById(Guid id) { ManagedObjectReference machineReference = _connectionService.GetMachineById(id); if (machineReference == null) { // lookup reference machineReference = await GetVm(id); // return null if not found if (machineReference == null) { return(null); } } if (_client == null) { return(null); } // retrieve all machine properties we need RetrievePropertiesResponse propertiesResponse = await _client.RetrievePropertiesAsync( _props, VmFilter(machineReference, "name summary.guest.toolsStatus summary.runtime.host summary.runtime.powerState config.hardware.device")); NetVimClient.ObjectContent vm = propertiesResponse.returnval.FirstOrDefault(); bool vmToolsAvailable = false; var toolsStatus = vm.GetProperty("summary.guest.toolsStatus"); if (toolsStatus != null) { var virtualMachineToolsStatus = (VirtualMachineToolsStatus)toolsStatus; vmToolsAvailable = !( virtualMachineToolsStatus == VirtualMachineToolsStatus.toolsNotInstalled || virtualMachineToolsStatus == VirtualMachineToolsStatus.toolsNotRunning ); } VirtualMachine machine = new VirtualMachine { Devices = vm.GetProperty("config.hardware.device") as VirtualDevice[], HostReference = ((ManagedObjectReference)vm.GetProperty("summary.runtime.host")).Value, Id = id, Name = vm.GetProperty("name") as string, Reference = vm.obj, State = (VirtualMachinePowerState)vm.GetProperty("summary.runtime.powerState") == VirtualMachinePowerState.poweredOn ? "on" : "off", VmToolsAvailable = vmToolsAvailable }; return(machine); }
private async Task <TaskInfo> GetVimTaskInfo(ManagedObjectReference task) { TaskInfo info = new TaskInfo(); RetrievePropertiesResponse response = await _client.RetrievePropertiesAsync( _props, TaskFilter(task)); NetVimClient.ObjectContent[] oc = response.returnval; info = (TaskInfo)oc[0].propSet[0].val; return(info); }
public async Task <bool> VmToolsAvailable(Guid uuid) { ManagedObjectReference vmReference = vmReference = await GetVm(uuid); //retrieve the properties specificied RetrievePropertiesResponse response = await _client.RetrievePropertiesAsync( _props, VmFilter(vmReference)); return(VmToolsAvailable(response)); }
private async Task <string> GetDistributedSwitchUuid(ManagedObjectReference mor) { RetrievePropertiesResponse response = await _client.RetrievePropertiesAsync(_props, PortGroupFilter(mor)); ManagedObjectReference switchMOR = ((DVPortgroupConfigInfo)response.returnval[0].propSet[0].val).distributedVirtualSwitch; response = await _client.RetrievePropertiesAsync(_props, SwitchFilter(switchMOR)); var config = ((VMwareDVSConfigInfo)response.returnval[0].GetProperty("config")); // if this is an uplink switch, return null so that we don't use it as a NIC if ((config.uplinkPortgroup[0].Value.Equals(mor.Value))) { return(null); } return((string)response.returnval[0].GetProperty("uuid")); }
public bool VmToolsAvailable(RetrievePropertiesResponse propertiesResponse) { NetVimClient.ObjectContent[] oc = propertiesResponse.returnval; NetVimClient.ObjectContent obj = oc[0]; foreach (DynamicProperty dp in obj.propSet) { if (dp.val.GetType() == typeof(VirtualMachineSummary)) { VirtualMachineSummary vmSummary = (VirtualMachineSummary)dp.val; //check vmware tools status var tools_status = vmSummary.guest.toolsStatus; if (tools_status == VirtualMachineToolsStatus.toolsNotInstalled || tools_status == VirtualMachineToolsStatus.toolsNotRunning) { return(false); } } } return(true); }
public async Task <string> GetPowerState(Guid uuid) { _logger.LogDebug("GetPowerState called"); ManagedObjectReference vmReference = vmReference = await GetVm(uuid); if (vmReference == null) { _logger.LogDebug($"could not get state, vmReference is null"); return("error"); } //retrieve the properties specificied RetrievePropertiesResponse response = await _client.RetrievePropertiesAsync( _props, VmFilter(vmReference)); return(GetPowerState(response)); }
private async Task <Vm[]> ReloadVmCache() { List <string> existing = _vmCache.Values .Where(v => v.Host == _config.Host) .Select(o => o.Id) .ToList(); List <Vm> list = new List <Vm>(); //retrieve the properties specificied RetrievePropertiesResponse response = await _vim.RetrievePropertiesAsync( _props, FilterFactory.VmFilter(_pool)); // _vms ObjectContent[] oc = response.returnval; //iterate through the collection of Vm's foreach (ObjectContent obj in oc) { Vm vm = LoadVm(obj); if (vm != null) { //_logger.LogDebug($"refreshing cache [{_config.Host}] found: {vm.Name}"); list.Add(vm); } } List <string> active = list.Select(o => o.Id).ToList(); _logger.LogDebug($"refreshing cache [{_config.Host}] existing: {existing.Count} active: {active.Count}"); foreach (string key in existing.Except(active)) { if (_vmCache.TryRemove(key, out Vm stale)) { _logger.LogDebug($"removing stale cache entry [{_config.Host}] {stale.Name}"); } } //return an array of vm's return(list.ToArray()); }
private async Task getRecentTasks() { if (_sic != null && _sic.taskManager != null) { PropertyFilterSpec[] filters = createPFSForRecentTasks(_sic.taskManager); RetrievePropertiesResponse response = await _client.RetrievePropertiesAsync(_props, filters); _runningTasks.Clear(); foreach (var task in response.returnval) { try { var vmString = _connectionService.GetVmGuidByName(((ManagedObjectReference)task.GetProperty("info.entity")).Value).ToString(); var broadcastTime = DateTime.UtcNow.ToString(); var taskId = task.GetProperty("info.key") != null?task.GetProperty("info.key").ToString() : ""; var taskType = task.GetProperty("info.descriptionId") != null?task.GetProperty("info.descriptionId").ToString() : ""; var progress = task.GetProperty("info.progress") != null?task.GetProperty("info.progress").ToString() : ""; var state = task.GetProperty("info.state") != null?task.GetProperty("info.state").ToString() : ""; var notification = new Notification() { broadcastTime = DateTime.UtcNow.ToString(), taskId = taskId, taskName = taskType.Replace("VirtualMachine.", ""), taskType = taskType, progress = progress, state = state }; var vmTasks = _runningTasks.ContainsKey(vmString) ? _runningTasks[vmString] : new List <Notification>(); vmTasks.Add(notification); _runningTasks.AddOrUpdate(vmString, vmTasks, (k, v) => (v = vmTasks)); } catch (Exception ex) { this._logger.LogError(ex.Message); } } } }
public override async Task <PortGroupAllocation[]> LoadPortGroups() { var list = new List <PortGroupAllocation>(); RetrievePropertiesResponse response = await _client.vim.RetrievePropertiesAsync( _client.props, FilterFactory.DistributedPortgroupFilter(_client.cluster)); ObjectContent[] clunkyTree = response.returnval; foreach (var dvpg in clunkyTree.FindType("DistributedVirtualPortgroup")) { var config = (DVPortgroupConfigInfo)dvpg.GetProperty("config"); if (config.distributedVirtualSwitch.Value == _client.dvs.Value) { string net = dvpg.GetProperty("name") as string; if (Regex.Match(net, _client.ExcludeNetworkMask).Success) { continue; } if ( config.defaultPortConfig is VMwareDVSPortSetting && ((VMwareDVSPortSetting)config.defaultPortConfig).vlan is VmwareDistributedVirtualSwitchVlanIdSpec ) { list.Add( new PortGroupAllocation { Net = net, Key = dvpg.obj.AsString(), VlanId = ((VmwareDistributedVirtualSwitchVlanIdSpec)((VMwareDVSPortSetting)config.defaultPortConfig).vlan).vlanId, Switch = _client.UplinkSwitch } ); } } } return(list.ToArray()); }
protected async Task <TaskInfo> WaitForVimTask(ManagedObjectReference task) { int i = 0; TaskInfo info = new TaskInfo(); //iterate the search until complete or timeout occurs do { //check every so often await Task.Delay(2000); RetrievePropertiesResponse response = await _client.vim.RetrievePropertiesAsync( _client.props, FilterFactory.TaskFilter(task)); ObjectContent[] oc = response.returnval; info = (TaskInfo)oc[0].propSet[0].val; i++; } while ((info.state == TaskInfoState.running || info.state == TaskInfoState.queued)); //return the task info return(info); }
public string GetPowerState(RetrievePropertiesResponse propertiesResponse) { VmPowerState State = VmPowerState.off; string state = null; NetVimClient.ObjectContent[] oc = propertiesResponse.returnval; NetVimClient.ObjectContent obj = oc[0]; foreach (DynamicProperty dp in obj.propSet) { if (dp.val.GetType() == typeof(VirtualMachineSummary)) { try { VirtualMachineSummary summary = (VirtualMachineSummary)dp.val; //vm.Name = summary.config.name; //vm.Path = summary.config.vmPathName; //vm.Id = summary.config.uuid; //vm.IpAddress = summary.guest.ipAddress; //vm.Os = summary.guest.guestId; State = (summary.runtime.powerState == VirtualMachinePowerState.poweredOn) ? VmPowerState.running : VmPowerState.off; //vm.IsPoweredOn = (summary.runtime.powerState == VirtualMachinePowerState.poweredOn); //vm.Reference = summary.vm.AsString(); //summary.vm.type + "|" + summary.vm.Value; //vm.Stats = String.Format("{0} | mem-{1}% cpu-{2}%", summary.overallStatus, // Math.Round(((float)summary.quickStats.guestMemoryUsage / (float)summary.runtime.maxMemoryUsage) * 100, 0), // Math.Round(((float)summary.quickStats.overallCpuUsage / (float)summary.runtime.maxCpuUsage) * 100, 0)); //vm.Annotations = summary.config.annotation.Lines(); //vm.ContextNumbers = vm.Annotations.FindOne("context").Value(); //vm.ContextNames = vm.Annotations.FindOne("display").Value(); //vm.HasGuestAgent = (vm.Annotations.FindOne("guestagent").Value() == "true"); //vm.Question = GetQuestion(summary.runtime.question); //vm.Status = "deployed"; //if (_tasks.ContainsKey(vm.Id)) //{ // var t = _tasks[vm.Id]; // vm.Task = new VmTask { Name= t.Action, WhenCreated = t.WhenCreated, Progress = t.Progress }; //} } catch (Exception ex) { _logger.LogDebug(ex.Message); } } } if (State == VmPowerState.running) { state = "on"; } else if (State == VmPowerState.off) { state = "off"; } else { state = "error"; } return(state); }
public async Task <string> UploadFileToVm(Guid uuid, string username, string password, string filepath, Stream fileStream) { _logger.LogDebug("UploadFileToVm called"); ManagedObjectReference vmReference = vmReference = await GetVm(uuid); if (vmReference == null) { var errorMessage = $"could not upload file, vmReference is null"; _logger.LogDebug(errorMessage); return(errorMessage); } //retrieve the properties specificied RetrievePropertiesResponse response = await _client.RetrievePropertiesAsync( _props, VmFilter(vmReference)); NetVimClient.ObjectContent[] oc = response.returnval; NetVimClient.ObjectContent obj = oc[0]; foreach (DynamicProperty dp in obj.propSet) { if (dp.val.GetType() == typeof(VirtualMachineSummary)) { VirtualMachineSummary vmSummary = (VirtualMachineSummary)dp.val; //check vmware tools status var tools_status = vmSummary.guest.toolsStatus; if (tools_status == VirtualMachineToolsStatus.toolsNotInstalled || tools_status == VirtualMachineToolsStatus.toolsNotRunning) { var errorMessage = $"could not upload file, VM Tools is not running"; _logger.LogDebug(errorMessage); return(errorMessage); } // user credentials on the VM NamePasswordAuthentication credentialsAuth = new NamePasswordAuthentication() { interactiveSession = false, username = username, password = password }; ManagedObjectReference fileManager = new ManagedObjectReference() { type = "GuestFileManager", Value = "guestOperationsFileManager" }; // upload the file GuestFileAttributes fileAttributes = new GuestFileAttributes(); var fileTransferUrl = _client.InitiateFileTransferToGuestAsync(fileManager, vmReference, credentialsAuth, filepath, fileAttributes, fileStream.Length, true).Result; // Replace IP address with hostname RetrievePropertiesResponse hostResponse = await _client.RetrievePropertiesAsync(_props, HostFilter(vmSummary.runtime.host, "name")); string hostName = hostResponse.returnval[0].propSet[0].val as string; if (!fileTransferUrl.Contains(hostName)) { fileTransferUrl = fileTransferUrl.Replace("https://", ""); var s = fileTransferUrl.IndexOf("/"); fileTransferUrl = "https://" + hostName + fileTransferUrl.Substring(s); } // http put to url using (var httpClientHandler = new HttpClientHandler()) { using (var httpClient = new HttpClient(httpClientHandler)) { httpClient.DefaultRequestHeaders.Accept.Clear(); using (MemoryStream ms = new MemoryStream()) { var timeout = _configuration.GetSection("vmOptions").GetValue("Timeout", 3); httpClient.Timeout = TimeSpan.FromMinutes(timeout); fileStream.CopyTo(ms); var fileContent = new ByteArrayContent(ms.ToArray()); var uploadResponse = await httpClient.PutAsync(fileTransferUrl, fileContent); } } } } } return(""); }
private async Task getRecentTasks() { if (_sic != null && _sic.taskManager != null) { var pendingVms = await _dbContext.Vms .Include(x => x.VmTeams) .Where(x => x.HasPendingTasks) .ToArrayAsync(); var stillPendingVmIds = new List <Guid>(); PropertyFilterSpec[] filters = createPFSForRecentTasks(_sic.taskManager); RetrievePropertiesResponse response = await _client.RetrievePropertiesAsync(_props, filters); _runningTasks.Clear(); var forceCheckMachineState = false; foreach (var task in response.returnval) { try { Guid?vmId = null; var vmRef = task.GetProperty("info.entity") != null ? ((ManagedObjectReference)task.GetProperty("info.entity")).Value : null; if (vmRef != null) { vmId = _connectionService.GetVmIdByRef(vmRef); } var broadcastTime = DateTime.UtcNow.ToString(); var taskId = task.GetProperty("info.key") != null?task.GetProperty("info.key").ToString() : ""; var taskType = task.GetProperty("info.descriptionId") != null?task.GetProperty("info.descriptionId").ToString() : ""; var progress = task.GetProperty("info.progress") != null?task.GetProperty("info.progress").ToString() : ""; var state = task.GetProperty("info.state") != null?task.GetProperty("info.state").ToString() : ""; var notification = new Notification() { broadcastTime = DateTime.UtcNow.ToString(), taskId = taskId, taskName = taskType.Replace("VirtualMachine.", ""), taskType = taskType, progress = progress, state = state }; if (vmId.HasValue) { var id = vmId.Value.ToString(); var vmTasks = _runningTasks.ContainsKey(id) ? _runningTasks[id] : new List <Notification>(); vmTasks.Add(notification); _runningTasks.AddOrUpdate(id, vmTasks, (k, v) => (v = vmTasks)); } if ((state == TaskInfoState.queued.ToString() || state == TaskInfoState.running.ToString())) { _tasksPending = true; if (vmId.HasValue) { stillPendingVmIds.Add(vmId.Value); } } if (state == TaskInfoState.success.ToString() && (this.GetPowerTaskTypes().Contains(taskType))) { if (vmId.HasValue) { forceCheckMachineState = true; } } } catch (Exception ex) { this._logger.LogError(ex, "Exception processing task"); } } foreach (var vm in pendingVms) { if (!stillPendingVmIds.Contains(vm.Id)) { vm.HasPendingTasks = false; } } var vmsToUpdate = await _dbContext.Vms .Include(x => x.VmTeams) .Where(x => stillPendingVmIds.Contains(x.Id)) .ToArrayAsync(); foreach (var vm in vmsToUpdate) { vm.HasPendingTasks = true; } await _dbContext.SaveChangesAsync(); if (forceCheckMachineState) { _machineStateService.CheckState(); } } }
private async Task <ObjectContent[]> LoadReferenceTree(VimPortTypeClient client) { var plan = new TraversalSpec { name = "FolderTraverseSpec", type = "Folder", path = "childEntity", selectSet = new SelectionSpec[] { new TraversalSpec() { type = "Datacenter", path = "hostFolder", selectSet = new SelectionSpec[] { new SelectionSpec { name = "FolderTraverseSpec" } } }, new TraversalSpec() { type = "Datacenter", path = "networkFolder", selectSet = new SelectionSpec[] { new SelectionSpec { name = "FolderTraverseSpec" } } }, new TraversalSpec() { type = "ComputeResource", path = "resourcePool", selectSet = new SelectionSpec[] { new TraversalSpec { type = "ResourcePool", path = "resourcePool" } } }, new TraversalSpec() { type = "ComputeResource", path = "host" }, new TraversalSpec() { type = "Folder", path = "childEntity" } } }; var props = new PropertySpec[] { new PropertySpec { type = "Datacenter", pathSet = new string[] { "name", "parent", "vmFolder" } }, new PropertySpec { type = "ComputeResource", pathSet = new string[] { "name", "parent", "resourcePool", "host" } }, new PropertySpec { type = "HostSystem", pathSet = new string[] { "configManager" } }, new PropertySpec { type = "ResourcePool", pathSet = new string[] { "name", "parent", "resourcePool" } }, new PropertySpec { type = "DistributedVirtualSwitch", pathSet = new string[] { "name", "parent", "uuid" } }, new PropertySpec { type = "DistributedVirtualPortgroup", pathSet = new string[] { "name", "parent", "config" } } }; ObjectSpec objectspec = new ObjectSpec(); objectspec.obj = _sic.rootFolder; objectspec.selectSet = new SelectionSpec[] { plan }; PropertyFilterSpec filter = new PropertyFilterSpec(); filter.propSet = props; filter.objectSet = new ObjectSpec[] { objectspec }; PropertyFilterSpec[] filters = new PropertyFilterSpec[] { filter }; RetrievePropertiesResponse response = await client.RetrievePropertiesAsync(_props, filters); return(response.returnval); }
private async Task LoadCache() { var plan = new TraversalSpec { name = "FolderTraverseSpec", type = "Folder", path = "childEntity", selectSet = new SelectionSpec[] { new TraversalSpec() { type = "Datacenter", path = "networkFolder", selectSet = new SelectionSpec[] { new SelectionSpec { name = "FolderTraverseSpec" } } }, new TraversalSpec() { type = "Datacenter", path = "vmFolder", selectSet = new SelectionSpec[] { new SelectionSpec { name = "FolderTraverseSpec" } } }, new TraversalSpec() { type = "Datacenter", path = "datastore", selectSet = new SelectionSpec[] { new SelectionSpec { name = "FolderTraverseSpec" } } }, new TraversalSpec() { type = "Folder", path = "childEntity", selectSet = new SelectionSpec[] { new SelectionSpec { name = "FolderTraverseSpec" } } }, } }; var props = new PropertySpec[] { new PropertySpec { type = "DistributedVirtualSwitch", pathSet = new string[] { "name", "uuid", "config.uplinkPortgroup" } }, new PropertySpec { type = "DistributedVirtualPortgroup", pathSet = new string[] { "name", "host", "config.distributedVirtualSwitch" } }, new PropertySpec { type = "Network", pathSet = new string[] { "name", "host" } }, new PropertySpec { type = "VirtualMachine", pathSet = new string[] { "name", "config.uuid", "summary.runtime.powerState", "guest.net" } }, new PropertySpec { type = "Datastore", pathSet = new string[] { "name", "browser" } } }; ObjectSpec objectspec = new ObjectSpec(); objectspec.obj = _sic.rootFolder; objectspec.selectSet = new SelectionSpec[] { plan }; PropertyFilterSpec filter = new PropertyFilterSpec(); filter.propSet = props; filter.objectSet = new ObjectSpec[] { objectspec }; PropertyFilterSpec[] filters = new PropertyFilterSpec[] { filter }; _logger.LogInformation($"Starting RetrieveProperties at {DateTime.UtcNow}"); RetrievePropertiesResponse response = await _client.RetrievePropertiesAsync(_props, filters); _logger.LogInformation($"Finished RetrieveProperties at {DateTime.UtcNow}"); _logger.LogInformation($"Starting LoadMachineCache at {DateTime.UtcNow}"); await LoadMachineCache(response.returnval.FindType("VirtualMachine")); _logger.LogInformation($"Finished LoadMachineCache at {DateTime.UtcNow}"); _logger.LogInformation($"Starting LoadNetworkCache at {DateTime.UtcNow}"); LoadNetworkCache( response.returnval.FindType("DistributedVirtualSwitch"), response.returnval.Where(o => o.obj.type.EndsWith("Network") || o.obj.type.EndsWith("DistributedVirtualPortgroup")).ToArray()); _logger.LogInformation($"Finished LoadNetworkCache at {DateTime.UtcNow}"); _logger.LogInformation($"Starting LoadDatastoreCache at {DateTime.UtcNow}"); LoadDatastoreCache(response.returnval.FindType("Datastore")); _logger.LogInformation($"Finished LoadDatastoreCache at {DateTime.UtcNow}"); }
public async Task <string[]> GetFiles(string path, bool recursive) { await Connect(); List <string> list = new List <string>(); DatastorePath dsPath = new DatastorePath(path); string oldRoot = ""; string pattern = dsPath.File ?? "*"; RetrievePropertiesResponse response = await _vim.RetrievePropertiesAsync( _props, FilterFactory.DatastoreFilter(_res) ); ObjectContent[] oc = response.returnval; foreach (ObjectContent obj in oc) { ManagedObjectReference dsBrowser = (ManagedObjectReference)obj.propSet[0].val; var capability = obj.propSet[1].val as DatastoreCapability; var summary = obj.propSet[2].val as DatastoreSummary; // if topLevelDirectory not supported (vsan), map from directory name to guid) if ( capability.topLevelDirectoryCreateSupportedSpecified && !capability.topLevelDirectoryCreateSupported && dsPath.TopLevelFolder.HasValue() ) { oldRoot = dsPath.TopLevelFolder; string target = summary.url + oldRoot; if (!_dsnsMap.ContainsKey(target)) { var result = await _vim.ConvertNamespacePathToUuidPathAsync( _dsns, _datacenter, target ); _dsnsMap.Add(target, result.Replace(summary.url, "")); } dsPath.TopLevelFolder = _dsnsMap[target]; // vmcloud sddc errors on Search_Datastore() // so force SearchDatastoreSubFolders() recursive = true; pattern = "*" + Path.GetExtension(dsPath.File); _logger.LogDebug("mapped datastore namespace: " + dsPath.ToString()); } if (summary.name == dsPath.Datastore) { ManagedObjectReference task = null; TaskInfo info = null; var spec = new HostDatastoreBrowserSearchSpec { matchPattern = new string[] { pattern }, }; var results = new List <HostDatastoreBrowserSearchResults>(); if (recursive) { try { task = await _vim.SearchDatastoreSubFolders_TaskAsync( dsBrowser, dsPath.FolderPath, spec ); info = await WaitForVimTask(task); if (info.result != null) { results.AddRange((HostDatastoreBrowserSearchResults[])info.result); } } catch (Exception ex) { _logger.LogError(ex, "error searching datastore."); } } else { task = await _vim.SearchDatastore_TaskAsync( dsBrowser, dsPath.FolderPath, spec ); info = await WaitForVimTask(task); if (info.result != null) { results.Add((HostDatastoreBrowserSearchResults)info.result); } } foreach (HostDatastoreBrowserSearchResults result in results) { if (result != null && result.file != null && result.file.Length > 0) { string fp = result.folderPath; if (oldRoot.HasValue()) { fp = fp.Replace(dsPath.TopLevelFolder, oldRoot); } if (!fp.EndsWith("/")) { fp += "/"; } list.AddRange(result.file.Select(o => fp + o.path)); } } } } return(list.ToArray()); }
//id, feature (iso, net, boot, guest), label, value public async Task <Vm> ReconfigureVm(string id, string feature, string label, string newvalue) { await Connect(); int index = 0; if (int.TryParse(label, out index)) { label = ""; } Vm vm = _vmCache[id]; RetrievePropertiesResponse response = await _vim.RetrievePropertiesAsync( _props, FilterFactory.VmFilter(vm.AsVim(), "config")); ObjectContent[] oc = response.returnval; VirtualMachineConfigInfo config = (VirtualMachineConfigInfo)oc[0].GetProperty("config"); VirtualMachineConfigSpec vmcs = new VirtualMachineConfigSpec(); switch (feature) { case "iso": VirtualCdrom cdrom = (VirtualCdrom)((label.HasValue()) ? config.hardware.device.Where(o => o.deviceInfo.label == label).SingleOrDefault() : config.hardware.device.OfType <VirtualCdrom>().ToArray()[index]); if (cdrom != null) { if (cdrom.backing.GetType() != typeof(VirtualCdromIsoBackingInfo)) { cdrom.backing = new VirtualCdromIsoBackingInfo(); } ((VirtualCdromIsoBackingInfo)cdrom.backing).fileName = newvalue; cdrom.connectable = new VirtualDeviceConnectInfo { connected = true, startConnected = true }; vmcs.deviceChange = new VirtualDeviceConfigSpec[] { new VirtualDeviceConfigSpec { device = cdrom, operation = VirtualDeviceConfigSpecOperation.edit, operationSpecified = true } }; } break; case "net": case "eth": VirtualEthernetCard card = (VirtualEthernetCard)((label.HasValue()) ? config.hardware.device.Where(o => o.deviceInfo.label == label).SingleOrDefault() : config.hardware.device.OfType <VirtualEthernetCard>().ToArray()[index]); if (card != null) { if (newvalue.StartsWith("_none_")) { card.connectable = new VirtualDeviceConnectInfo() { connected = false, startConnected = false, }; } else { _netman.UpdateEthernetCardBacking(card, newvalue); card.connectable.connected = true; } vmcs.deviceChange = new VirtualDeviceConfigSpec[] { new VirtualDeviceConfigSpec { device = card, operation = VirtualDeviceConfigSpecOperation.edit, operationSpecified = true } }; } break; case "boot": int delay = 0; if (Int32.TryParse(newvalue, out delay)) { vmcs.AddBootOption(delay); } break; case "guest": if (newvalue.HasValue() && !newvalue.EndsWith("\n")) { newvalue += "\n"; } vmcs.annotation = config.annotation + newvalue; if (vm.State == VmPowerState.Running && vmcs.annotation.HasValue()) { vmcs.AddGuestInfo(Regex.Split(vmcs.annotation, "\r\n|\r|\n")); } break; default: throw new Exception("Invalid change request."); //break; } ManagedObjectReference task = await _vim.ReconfigVM_TaskAsync(vm.AsVim(), vmcs); TaskInfo info = await WaitForVimTask(task); if (info.state == TaskInfoState.error) { throw new Exception(info.error.localizedMessage); } return(await GetVirtualMachine(vm.AsVim())); }
public async Task <Vm> Save(string id) { await Connect(); Vm vm = _vmCache[id]; //protect stock disks; only save a disk if it is local to the workspace //i.e. the disk folder matches the workspaceId if (vm.Name.Tag().HasValue() && !vm.DiskPath.Contains(vm.Name.Tag())) { throw new InvalidOperationException("External templates must be cloned into local templates in order to be saved."); } _logger.LogDebug($"Save: get current snap for vm {vm.Name}"); //Get the current snapshot mor ManagedObjectReference mor = null; RetrievePropertiesResponse response = await _vim.RetrievePropertiesAsync( _props, FilterFactory.VmFilter(vm.AsVim(), "snapshot")); ObjectContent[] oc = response.returnval; mor = ((VirtualMachineSnapshotInfo)oc.First().GetProperty("snapshot")).currentSnapshot as ManagedObjectReference; // if (oc.Length > 0 && oc[0].propSet.Length > 0 && oc[0].propSet[0].val != null) // mor = ((VirtualMachineSnapshotInfo)oc[0].propSet[0].val).currentSnapshot; //add new snapshot _logger.LogDebug($"Save: add new snap for vm {vm.Name}"); ManagedObjectReference task = await _vim.CreateSnapshot_TaskAsync( vm.AsVim(), "Root Snap", "Created by TopoMojo Save at " + DateTime.UtcNow.ToString("s") + "Z", false, false); TaskInfo info = await WaitForVimTask(task); //remove previous snapshot if (mor != null) { _logger.LogDebug($"Save: remove previous snap for vm {vm.Name}"); task = await _vim.RemoveSnapshot_TaskAsync(mor, false, true); await Task.Delay(500); info = await GetVimTaskInfo(task); if (info.state == TaskInfoState.error) { throw new Exception(info.error.localizedMessage); } if (info.progress < 100) { var t = new VimHostTask { Task = task, Action = "saving", WhenCreated = DateTime.UtcNow }; vm.Task = new VmTask { Name = t.Action, WhenCreated = t.WhenCreated, Progress = t.Progress }; _tasks.Add(vm.Id, t); } } _vmCache.TryUpdate(vm.Id, vm, vm); return(vm); }
public async Task <string[]> GetFiles(string path, bool recursive) { await Connect(); List <string> list = new List <string>(); DatastorePath dsPath = new DatastorePath(path); RetrievePropertiesResponse response = await _vim.RetrievePropertiesAsync( _props, FilterFactory.DatastoreFilter(_res)); ObjectContent[] oc = response.returnval; foreach (ObjectContent obj in oc) { ManagedObjectReference dsBrowser = (ManagedObjectReference)obj.propSet[0].val; string dsName = ((DatastoreSummary)obj.propSet[1].val).name; if (dsName == dsPath.Datastore) { ManagedObjectReference task = null; TaskInfo info = null; HostDatastoreBrowserSearchSpec spec = new HostDatastoreBrowserSearchSpec { matchPattern = new string[] { dsPath.File } }; List <HostDatastoreBrowserSearchResults> results = new List <HostDatastoreBrowserSearchResults>(); if (recursive) { task = await _vim.SearchDatastoreSubFolders_TaskAsync( dsBrowser, dsPath.FolderPath, spec); info = await WaitForVimTask(task); if (info.result != null) { results.AddRange((HostDatastoreBrowserSearchResults[])info.result); } } else { task = await _vim.SearchDatastore_TaskAsync( dsBrowser, dsPath.FolderPath, spec); info = await WaitForVimTask(task); if (info.result != null) { results.Add((HostDatastoreBrowserSearchResults)info.result); } } foreach (HostDatastoreBrowserSearchResults result in results) { if (result != null && result.file != null && result.file.Length > 0) { string fp = result.folderPath; if (!fp.EndsWith("/")) { fp += "/"; } list.AddRange(result.file.Select(o => fp + o.path)); } } } } return(list.ToArray()); }