wsp-10329 Adding hyper-v replica to HyperV Provider. Server Part.
This commit is contained in:
parent
414414b11d
commit
41fd1230bf
23 changed files with 5194 additions and 37 deletions
|
@ -0,0 +1,115 @@
|
|||
// Copyright (c) 2015, Outercurve Foundation.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// - Redistributions of source code must retain the above copyright notice, this
|
||||
// list of conditions and the following disclaimer.
|
||||
//
|
||||
// - Redistributions in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
//
|
||||
// - Neither the name of the Outercurve Foundation nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from this
|
||||
// software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace WebsitePanel.Providers.Virtualization
|
||||
{
|
||||
public interface IVirtualizationServer2012
|
||||
{
|
||||
// Virtual Machines
|
||||
VirtualMachine GetVirtualMachine(string vmId);
|
||||
VirtualMachine GetVirtualMachineEx(string vmId);
|
||||
List<VirtualMachine> GetVirtualMachines();
|
||||
byte[] GetVirtualMachineThumbnailImage(string vmId, ThumbnailSize size);
|
||||
VirtualMachine CreateVirtualMachine(VirtualMachine vm);
|
||||
VirtualMachine UpdateVirtualMachine(VirtualMachine vm);
|
||||
JobResult ChangeVirtualMachineState(string vmId, VirtualMachineRequestedState newState);
|
||||
ReturnCode ShutDownVirtualMachine(string vmId, bool force, string reason);
|
||||
List<ConcreteJob> GetVirtualMachineJobs(string vmId);
|
||||
JobResult RenameVirtualMachine(string vmId, string name);
|
||||
JobResult ExportVirtualMachine(string vmId, string exportPath);
|
||||
JobResult DeleteVirtualMachine(string vmId);
|
||||
|
||||
// Snapshots
|
||||
List<VirtualMachineSnapshot> GetVirtualMachineSnapshots(string vmId);
|
||||
VirtualMachineSnapshot GetSnapshot(string snapshotId);
|
||||
JobResult CreateSnapshot(string vmId);
|
||||
JobResult RenameSnapshot(string vmId, string snapshotId, string name);
|
||||
JobResult ApplySnapshot(string vmId, string snapshotId);
|
||||
JobResult DeleteSnapshot(string snapshotId);
|
||||
JobResult DeleteSnapshotSubtree(string snapshotId);
|
||||
byte[] GetSnapshotThumbnailImage(string snapshotId, ThumbnailSize size);
|
||||
|
||||
// Virtual Switches
|
||||
List<VirtualSwitch> GetExternalSwitches(string computerName);
|
||||
List<VirtualSwitch> GetSwitches();
|
||||
bool SwitchExists(string switchId);
|
||||
VirtualSwitch CreateSwitch(string name);
|
||||
ReturnCode DeleteSwitch(string switchId);
|
||||
|
||||
// DVD operations
|
||||
string GetInsertedDVD(string vmId);
|
||||
JobResult InsertDVD(string vmId, string isoPath);
|
||||
JobResult EjectDVD(string vmId);
|
||||
|
||||
// KVP items
|
||||
List<KvpExchangeDataItem> GetKVPItems(string vmId);
|
||||
List<KvpExchangeDataItem> GetStandardKVPItems(string vmId);
|
||||
JobResult AddKVPItems(string vmId, KvpExchangeDataItem[] items);
|
||||
JobResult RemoveKVPItems(string vmId, string[] itemNames);
|
||||
JobResult ModifyKVPItems(string vmId, KvpExchangeDataItem[] items);
|
||||
|
||||
// Library
|
||||
LibraryItem[] GetLibraryItems(string path);
|
||||
|
||||
// Storage
|
||||
VirtualHardDiskInfo GetVirtualHardDiskInfo(string vhdPath);
|
||||
MountedDiskInfo MountVirtualHardDisk(string vhdPath);
|
||||
ReturnCode UnmountVirtualHardDisk(string vhdPath);
|
||||
JobResult ExpandVirtualHardDisk(string vhdPath, UInt64 sizeGB);
|
||||
JobResult ConvertVirtualHardDisk(string sourcePath, string destinationPath, VirtualHardDiskType diskType);
|
||||
void ExpandDiskVolume(string diskAddress, string volumeName);
|
||||
void DeleteRemoteFile(string path);
|
||||
string ReadRemoteFile(string path);
|
||||
void WriteRemoteFile(string path, string content);
|
||||
|
||||
// Jobs
|
||||
ConcreteJob GetJob(string jobId);
|
||||
List<ConcreteJob> GetAllJobs();
|
||||
ChangeJobStateReturnCode ChangeJobState(string jobId, ConcreteJobRequestedState newState);
|
||||
|
||||
// Configuration
|
||||
int GetProcessorCoresNumber();
|
||||
|
||||
List<CertificateInfo> GetCertificates(string remoteServer);
|
||||
void SetReplicaServer(string remoteServer, string thumbprint, string storagePath);
|
||||
void UnsetReplicaServer(string remoteServer);
|
||||
void EnableVmReplication(string vmId, string replicaServer, VmReplication replication);
|
||||
void SetVmReplication(string vmId, string replicaServer, VmReplication replication);
|
||||
void TestReplicationServer(string vmId, string replicaServer, string localThumbprint);
|
||||
void StartInitialReplication(string vmId);
|
||||
VmReplication GetReplication(string vmId);
|
||||
bool DisableVmReplication(string vmId, string replicaServer);
|
||||
ReplicationDetailInfo GetReplicationInfo(string vmId);
|
||||
void PauseReplication(string vmId);
|
||||
void ResumeReplication(string vmId);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace WebsitePanel.Providers.Virtualization
|
||||
{
|
||||
public class CertificateInfo
|
||||
{
|
||||
public string Thumbprint { get; set; }
|
||||
public string Subject { get; set; }
|
||||
public string Title { get; set; }
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
namespace WebsitePanel.Providers.Virtualization
|
||||
{
|
||||
public enum ReplicaFrequency
|
||||
{
|
||||
Seconds30 = 30,
|
||||
Minutes5 = 300,
|
||||
Minutes15 = 900,
|
||||
}
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace WebsitePanel.Providers.Virtualization
|
||||
{
|
||||
public enum ReplicaMode
|
||||
{
|
||||
None = 0,
|
||||
ReplicationEnabled = 1,
|
||||
IsReplicaServer = 2,
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
using System;
|
||||
|
||||
namespace WebsitePanel.Providers.Virtualization
|
||||
{
|
||||
public class ReplicationDetailInfo
|
||||
{
|
||||
public VmReplicationMode Mode { get; set; }
|
||||
public ReplicationState State { get; set; }
|
||||
public ReplicationHealth Health { get; set; }
|
||||
public string HealthDetails { get; set; }
|
||||
public string PrimaryServerName { get; set; }
|
||||
public string ReplicaServerName { get; set; }
|
||||
public DateTime FromTime { get; set; }
|
||||
public DateTime ToTime { get; set; }
|
||||
public string AverageSize { get; set; }
|
||||
public string MaximumSize { get; set; }
|
||||
public TimeSpan AverageLatency { get; set; }
|
||||
public int Errors { get; set; }
|
||||
public int SuccessfulReplications { get; set; }
|
||||
public string PendingSize { get; set; }
|
||||
public DateTime LastSynhronizedAt { get; set; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace WebsitePanel.Providers.Virtualization
|
||||
{
|
||||
public enum ReplicationHealth
|
||||
{
|
||||
Critical,
|
||||
Warning,
|
||||
Normal,
|
||||
NotApplicable,
|
||||
}
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace WebsitePanel.Providers.Virtualization
|
||||
{
|
||||
public enum ReplicationState
|
||||
{
|
||||
Disabled,
|
||||
Error,
|
||||
FailOverWaitingCompletion,
|
||||
FailedOver,
|
||||
NotApplicable,
|
||||
ReadyForInitialReplication,
|
||||
Replicating,
|
||||
Resynchronizing,
|
||||
ResynchronizeSuspended,
|
||||
Suspended,
|
||||
SyncedReplicationComplete,
|
||||
WaitingForInitialReplication,
|
||||
WaitingForStartResynchronize,
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
namespace WebsitePanel.Providers.Virtualization
|
||||
{
|
||||
[Persistent]
|
||||
public class VmReplication
|
||||
{
|
||||
[Persistent]
|
||||
public string Thumbprint { get; set; }
|
||||
|
||||
[Persistent]
|
||||
public string VhdToReplicate { get; set; }
|
||||
|
||||
[Persistent]
|
||||
public ReplicaFrequency ReplicaFrequency { get; set; }
|
||||
|
||||
[Persistent]
|
||||
public int AdditionalRecoveryPoints { get; set; }
|
||||
|
||||
[Persistent]
|
||||
public int VSSSnapshotFrequencyHour { get; set; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace WebsitePanel.Providers.Virtualization
|
||||
{
|
||||
public enum VmReplicationMode
|
||||
{
|
||||
None,
|
||||
Primary,
|
||||
Replica,
|
||||
TestReplica,
|
||||
}
|
||||
}
|
|
@ -134,8 +134,7 @@ namespace WebsitePanel.Providers.Virtualization
|
|||
[Persistent]
|
||||
public string Status { get; set; }
|
||||
|
||||
[Persistent]
|
||||
public string ReplicationState { get; set; }
|
||||
public ReplicationState ReplicationState { get; set; }
|
||||
|
||||
[Persistent]
|
||||
public int Generation { get; set; }
|
||||
|
|
|
@ -310,6 +310,7 @@
|
|||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Virtualization\ControllerType.cs" />
|
||||
<Compile Include="Virtualization\IVirtualizationServer2012.cs" />
|
||||
<Compile Include="Virtualization\IVirtualizationServer.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
|
@ -326,6 +327,14 @@
|
|||
<Compile Include="Virtualization\MountedDiskInfo.cs" />
|
||||
<Compile Include="Virtualization\OperationalStatus.cs" />
|
||||
<Compile Include="Virtualization\PerformanceObject.cs" />
|
||||
<Compile Include="Virtualization\Replication\CertificateInfo.cs" />
|
||||
<Compile Include="Virtualization\Replication\ReplicaFrequency.cs" />
|
||||
<Compile Include="Virtualization\Replication\ReplicationHealth.cs" />
|
||||
<Compile Include="Virtualization\Replication\VmReplicationMode.cs" />
|
||||
<Compile Include="Virtualization\Replication\ReplicaMode.cs" />
|
||||
<Compile Include="Virtualization\Replication\ReplicationState.cs" />
|
||||
<Compile Include="Virtualization\Replication\ReplicationDetailInfo.cs" />
|
||||
<Compile Include="Virtualization\Replication\VmReplication.cs" />
|
||||
<Compile Include="Virtualization\ReturnCode.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
|
|
|
@ -20,6 +20,7 @@ namespace WebsitePanel.Providers.Virtualization
|
|||
|
||||
public const Int64 Size1G = 0x40000000;
|
||||
public const Int64 Size1M = 0x100000;
|
||||
public const Int64 Size1K = 1024;
|
||||
|
||||
public const string KVP_RAM_SUMMARY_KEY = "VM-RAM-Summary";
|
||||
public const string KVP_HDD_SUMMARY_KEY = "VM-HDD-Summary";
|
||||
|
|
|
@ -20,9 +20,17 @@ namespace WebsitePanel.Providers.Virtualization
|
|||
{
|
||||
return (T)obj.Members[name].Value;
|
||||
}
|
||||
public static T GetEnum<T>(this PSObject obj, string name) where T : struct
|
||||
public static T GetEnum<T>(this PSObject obj, string name, T? defaultValue = null) where T : struct
|
||||
{
|
||||
return (T)Enum.Parse(typeof(T), GetProperty(obj, name).ToString());
|
||||
try
|
||||
{
|
||||
return (T) Enum.Parse(typeof (T), GetProperty(obj, name).ToString());
|
||||
}
|
||||
catch
|
||||
{
|
||||
if (defaultValue.HasValue) return defaultValue.Value;
|
||||
throw;
|
||||
}
|
||||
}
|
||||
public static int GetInt(this PSObject obj, string name)
|
||||
{
|
||||
|
@ -40,6 +48,25 @@ namespace WebsitePanel.Providers.Virtualization
|
|||
{
|
||||
return Convert.ToBoolean(obj.Members[name].Value);
|
||||
}
|
||||
|
||||
public static string GetMb(this PSObject obj, string name)
|
||||
{
|
||||
var bytes = GetLong(obj, name);
|
||||
|
||||
if (bytes == 0)
|
||||
return "0";
|
||||
|
||||
if (bytes > Constants.Size1G)
|
||||
return string.Format("{0:0.0} GB", bytes / Constants.Size1G);
|
||||
|
||||
if (bytes > Constants.Size1M)
|
||||
return string.Format("{0:0.0} MB", bytes / Constants.Size1M);
|
||||
|
||||
if (bytes > Constants.Size1K)
|
||||
return string.Format("{0:0.0} KB", bytes / Constants.Size1K);
|
||||
|
||||
return string.Format("{0} b", bytes);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
using System.Management.Automation.Runspaces;
|
||||
|
||||
namespace WebsitePanel.Providers.Virtualization
|
||||
{
|
||||
public static class ReplicaHelper
|
||||
{
|
||||
public static void SetReplicaServer(PowerShellManager powerShell, bool enabled, string remoteServer, string thumbprint, string storagePath)
|
||||
{
|
||||
Command cmd = new Command("Set-VMReplicationServer");
|
||||
cmd.Parameters.Add("ReplicationEnabled", enabled);
|
||||
|
||||
if (!string.IsNullOrEmpty(remoteServer))
|
||||
{
|
||||
cmd.Parameters.Add("ComputerName", remoteServer);
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(thumbprint))
|
||||
{
|
||||
cmd.Parameters.Add("AllowedAuthenticationType", "Certificate");
|
||||
cmd.Parameters.Add("CertificateThumbprint", thumbprint);
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(storagePath))
|
||||
{
|
||||
cmd.Parameters.Add("ReplicationAllowedFromAnyServer", true);
|
||||
cmd.Parameters.Add("DefaultStorageLocation", storagePath);
|
||||
}
|
||||
|
||||
powerShell.Execute(cmd, false);
|
||||
}
|
||||
|
||||
public static void SetFirewallRule(PowerShellManager powerShell, bool enabled)
|
||||
{
|
||||
Command cmd = new Command("Enable-Netfirewallrule");
|
||||
cmd.Parameters.Add("DisplayName", "Hyper-V Replica HTTPS Listener (TCP-In)");
|
||||
|
||||
powerShell.Execute(cmd, false);
|
||||
}
|
||||
|
||||
public static void RemoveVmReplication(PowerShellManager powerShell, string vmName, string server)
|
||||
{
|
||||
Command cmd = new Command("Remove-VMReplication");
|
||||
cmd.Parameters.Add("VmName", vmName);
|
||||
if (!string.IsNullOrEmpty(server)) cmd.Parameters.Add("ComputerName", server);
|
||||
|
||||
powerShell.Execute(cmd, false);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -61,5 +61,24 @@ namespace WebsitePanel.Providers.Virtualization
|
|||
|
||||
powerShell.Execute(cmd, true);
|
||||
}
|
||||
|
||||
public static void Delete(PowerShellManager powerShell, string vmName, string server)
|
||||
{
|
||||
Command cmd = new Command("Remove-VM");
|
||||
cmd.Parameters.Add("Name", vmName);
|
||||
if (!string.IsNullOrEmpty(server)) cmd.Parameters.Add("ComputerName", server);
|
||||
cmd.Parameters.Add("Force");
|
||||
powerShell.Execute(cmd, false, true);
|
||||
}
|
||||
public static void Stop(PowerShellManager powerShell, string vmName, bool force, string server)
|
||||
{
|
||||
Command cmd = new Command("Stop-VM");
|
||||
|
||||
if (force) cmd.Parameters.Add("Force");
|
||||
if (!string.IsNullOrEmpty(server)) cmd.Parameters.Add("ComputerName", server);
|
||||
//if (!string.IsNullOrEmpty(reason)) cmd.Parameters.Add("Reason", reason);
|
||||
|
||||
powerShell.Execute(cmd, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -56,7 +56,7 @@ using System.Configuration;
|
|||
|
||||
namespace WebsitePanel.Providers.Virtualization
|
||||
{
|
||||
public class HyperV2012R2 : HostingServiceProviderBase, IVirtualizationServer
|
||||
public class HyperV2012R2 : HostingServiceProviderBase, IVirtualizationServer2012
|
||||
{
|
||||
#region Provider Settings
|
||||
protected string ServerNameSettings
|
||||
|
@ -98,6 +98,20 @@ namespace WebsitePanel.Providers.Virtualization
|
|||
{
|
||||
get { return ProviderSettings.GetInt("CpuWeight"); }
|
||||
}
|
||||
|
||||
|
||||
public ReplicaMode ReplicaMode
|
||||
{
|
||||
get { return (ReplicaMode) ProviderSettings.GetInt("ReplicaMode"); }
|
||||
}
|
||||
protected string ReplicaServerPath
|
||||
{
|
||||
get { return ProviderSettings["ReplicaServerPath"]; }
|
||||
}
|
||||
protected string ReplicaServerThumbprint
|
||||
{
|
||||
get { return ProviderSettings["ReplicaServerThumbprint"]; }
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Fields
|
||||
|
@ -157,12 +171,12 @@ namespace WebsitePanel.Providers.Virtualization
|
|||
vm.RamSize = Convert.ToInt32(ConvertNullableToInt64(result[0].GetProperty("MemoryStartup")) / Constants.Size1M);
|
||||
vm.Uptime = Convert.ToInt64(result[0].GetProperty<TimeSpan>("UpTime").TotalMilliseconds);
|
||||
vm.Status = result[0].GetProperty("Status").ToString();
|
||||
vm.ReplicationState = result[0].GetProperty("ReplicationState").ToString();
|
||||
vm.Generation = result[0].GetInt("Generation");
|
||||
vm.ProcessorCount = result[0].GetInt("ProcessorCount");
|
||||
vm.ParentSnapshotId = result[0].GetString("ParentSnapshotId");
|
||||
vm.Heartbeat = VirtualMachineHelper.GetVMHeartBeatStatus(PowerShell, vm.Name);
|
||||
vm.CreatedDate = DateTime.Now;
|
||||
vm.ReplicationState = result[0].GetEnum<ReplicationState>("ReplicationState");
|
||||
|
||||
if (extendedInfo)
|
||||
{
|
||||
|
@ -222,9 +236,10 @@ namespace WebsitePanel.Providers.Virtualization
|
|||
VirtualMachine vm = new VirtualMachine
|
||||
{
|
||||
VirtualMachineId = current.GetProperty("Id").ToString(),
|
||||
Name = current.GetProperty("Name").ToString(),
|
||||
State = (VirtualMachineState)Enum.Parse(typeof(VirtualMachineState), current.GetProperty("State").ToString()),
|
||||
Uptime = Convert.ToInt64(current.GetProperty<TimeSpan>("UpTime").TotalMilliseconds)
|
||||
Name = current.GetString("Name"),
|
||||
State = current.GetEnum<VirtualMachineState>("State"),
|
||||
Uptime = Convert.ToInt64(current.GetProperty<TimeSpan>("UpTime").TotalMilliseconds),
|
||||
ReplicationState = result[0].GetEnum<ReplicationState>("ReplicationState")
|
||||
};
|
||||
vmachines.Add(vm);
|
||||
}
|
||||
|
@ -443,30 +458,11 @@ namespace WebsitePanel.Providers.Virtualization
|
|||
|
||||
public ReturnCode ShutDownVirtualMachine(string vmId, bool force, string reason)
|
||||
{
|
||||
HostedSolutionLog.LogStart("ShutDownVirtualMachine");
|
||||
ReturnCode returnCode = ReturnCode.OK;
|
||||
|
||||
var vm = GetVirtualMachine(vmId);
|
||||
|
||||
try
|
||||
{
|
||||
Command cmd = new Command("Stop-VM");
|
||||
VirtualMachineHelper.Stop(PowerShell, vm.Name, force, ServerNameSettings);
|
||||
|
||||
cmd.Parameters.Add("Name", vm.Name);
|
||||
if (force) cmd.Parameters.Add("Force");
|
||||
//if (!string.IsNullOrEmpty(reason)) cmd.Parameters.Add("Reason", reason);
|
||||
|
||||
PowerShell.Execute(cmd, true);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
HostedSolutionLog.LogError("ShutDownVirtualMachine", ex);
|
||||
throw;
|
||||
}
|
||||
|
||||
HostedSolutionLog.LogEnd("ShutDownVirtualMachine");
|
||||
|
||||
return returnCode;
|
||||
return ReturnCode.OK;
|
||||
}
|
||||
|
||||
public List<ConcreteJob> GetVirtualMachineJobs(string vmId)
|
||||
|
@ -517,10 +513,7 @@ namespace WebsitePanel.Providers.Virtualization
|
|||
//DeleteSwitch(networkAdapter.SwitchName);
|
||||
}
|
||||
|
||||
Command cmdSet = new Command("Remove-VM");
|
||||
cmdSet.Parameters.Add("Name", vm.Name);
|
||||
cmdSet.Parameters.Add("Force");
|
||||
PowerShell.Execute(cmdSet, true, true);
|
||||
VirtualMachineHelper.Delete(PowerShell, vm.Name, ServerNameSettings);
|
||||
|
||||
return JobHelper.CreateSuccessResult(ReturnCode.JobStarted);
|
||||
}
|
||||
|
@ -1963,6 +1956,284 @@ namespace WebsitePanel.Providers.Virtualization
|
|||
return !String.IsNullOrEmpty(connString);
|
||||
}
|
||||
#endregion Hyper-V Cloud
|
||||
|
||||
|
||||
#region Replication
|
||||
|
||||
public List<CertificateInfo> GetCertificates(string remoteServer)
|
||||
{
|
||||
// we cant get certificates from remote server
|
||||
if (string.IsNullOrEmpty(remoteServer))
|
||||
return null;
|
||||
|
||||
Command cmd = new Command("Get-ChildItem");
|
||||
cmd.Parameters.Add("Path", @"cert:\LocalMachine\My");
|
||||
|
||||
Collection<PSObject> result = PowerShell.Execute(cmd, true);
|
||||
|
||||
return result
|
||||
.Select(
|
||||
cert => new CertificateInfo
|
||||
{
|
||||
Subject = cert.GetString("Subject"),
|
||||
Thumbprint = cert.GetString("Thumbprint"),
|
||||
Title = string.Format("{0} ({1})", cert.GetString("Thumbprint"), cert.GetString("Subject")),
|
||||
})
|
||||
.ToList();
|
||||
}
|
||||
|
||||
public void SetReplicaServer(string remoteServer, string thumbprint, string storagePath)
|
||||
{
|
||||
// we cant enable firewall rules on remote server
|
||||
if (!string.IsNullOrEmpty(remoteServer))
|
||||
{
|
||||
ReplicaHelper.SetFirewallRule(PowerShell, true);
|
||||
}
|
||||
|
||||
ReplicaHelper.SetReplicaServer(PowerShell, true, remoteServer, thumbprint, storagePath);
|
||||
}
|
||||
|
||||
public void UnsetReplicaServer(string remoteServer)
|
||||
{
|
||||
ReplicaHelper.SetReplicaServer(PowerShell, false, remoteServer, null, null);
|
||||
}
|
||||
|
||||
public void EnableVmReplication(string vmId, string replicaServer, VmReplication replication)
|
||||
{
|
||||
if (ReplicaMode != ReplicaMode.ReplicationEnabled)
|
||||
throw new Exception("Server does not allow replication by settings");
|
||||
|
||||
var vm = GetVirtualMachineEx(vmId);
|
||||
|
||||
Command cmd = new Command("Enable-VMReplication");
|
||||
cmd.Parameters.Add("VmName", vm.Name);
|
||||
cmd.Parameters.Add("ReplicaServerName", replicaServer);
|
||||
cmd.Parameters.Add("ReplicaServerPort", 443);
|
||||
cmd.Parameters.Add("AuthenticationType", "Cert");
|
||||
cmd.Parameters.Add("CertificateThumbprint", replication.Thumbprint);
|
||||
cmd.Parameters.Add("ReplicationFrequencySec", (int)replication.ReplicaFrequency);
|
||||
|
||||
var excludes = vm.Disks
|
||||
.Select(d => d.Path)
|
||||
.Where(p => !p.Equals(replication.VhdToReplicate, StringComparison.OrdinalIgnoreCase))
|
||||
.ToArray();
|
||||
if (excludes.Any())
|
||||
cmd.Parameters.Add("ExcludedVhdPath", excludes);
|
||||
|
||||
// recovery points
|
||||
if (replication.AdditionalRecoveryPoints > 0)
|
||||
{
|
||||
if (replication.AdditionalRecoveryPoints > 24)
|
||||
throw new Exception("AdditionalRecoveryPoints can not be greater than 24");
|
||||
|
||||
cmd.Parameters.Add("RecoveryHistory", replication.AdditionalRecoveryPoints);
|
||||
|
||||
if (replication.VSSSnapshotFrequencyHour > 0)
|
||||
{
|
||||
if (replication.VSSSnapshotFrequencyHour > 12)
|
||||
throw new Exception("VSSSnapshotFrequencyHour can not be greater than 12");
|
||||
|
||||
cmd.Parameters.Add("VSSSnapshotFrequencyHour", replication.VSSSnapshotFrequencyHour);
|
||||
}
|
||||
}
|
||||
|
||||
PowerShell.Execute(cmd, true);
|
||||
|
||||
// Initial Replication
|
||||
StartInitialReplication(vmId);
|
||||
}
|
||||
|
||||
public void SetVmReplication(string vmId, string replicaServer, VmReplication replication)
|
||||
{
|
||||
if (ReplicaMode != ReplicaMode.ReplicationEnabled)
|
||||
throw new Exception("Server does not allow replication by settings");
|
||||
|
||||
var vm = GetVirtualMachineEx(vmId);
|
||||
|
||||
Command cmd = new Command("Set-VMReplication");
|
||||
cmd.Parameters.Add("VmName", vm.Name);
|
||||
cmd.Parameters.Add("ReplicaServerName", replicaServer);
|
||||
cmd.Parameters.Add("ReplicaServerPort", 443);
|
||||
cmd.Parameters.Add("AuthenticationType", "Cert");
|
||||
cmd.Parameters.Add("CertificateThumbprint", replication.Thumbprint);
|
||||
cmd.Parameters.Add("ReplicationFrequencySec", (int)replication.ReplicaFrequency);
|
||||
|
||||
var excludes = vm.Disks
|
||||
.Select(d => d.Path)
|
||||
.Where(p => !p.Equals(replication.VhdToReplicate, StringComparison.OrdinalIgnoreCase))
|
||||
.ToArray();
|
||||
if (excludes.Any())
|
||||
cmd.Parameters.Add("ExcludedVhdPath", excludes);
|
||||
|
||||
// recovery points
|
||||
if (replication.AdditionalRecoveryPoints > 0)
|
||||
{
|
||||
if (replication.AdditionalRecoveryPoints > 24)
|
||||
throw new Exception("AdditionalRecoveryPoints can not be greater than 24");
|
||||
|
||||
cmd.Parameters.Add("RecoveryHistory", replication.AdditionalRecoveryPoints);
|
||||
|
||||
if (replication.VSSSnapshotFrequencyHour > 0)
|
||||
{
|
||||
if (replication.VSSSnapshotFrequencyHour > 12)
|
||||
throw new Exception("VSSSnapshotFrequencyHour can not be greater than 12");
|
||||
|
||||
cmd.Parameters.Add("VSSSnapshotFrequencyHour", replication.VSSSnapshotFrequencyHour);
|
||||
}
|
||||
}
|
||||
|
||||
PowerShell.Execute(cmd, true);
|
||||
}
|
||||
|
||||
public void TestReplicationServer(string vmId, string replicaServer, string localThumbprint)
|
||||
{
|
||||
if (ReplicaMode != ReplicaMode.ReplicationEnabled)
|
||||
throw new Exception("Server does not allow replication by settings");
|
||||
|
||||
var vm = GetVirtualMachine(vmId);
|
||||
|
||||
Command cmd = new Command("Test-VMReplicationConnection");
|
||||
cmd.Parameters.Add("VmName", vm.Name);
|
||||
cmd.Parameters.Add("ReplicaServerName", replicaServer);
|
||||
cmd.Parameters.Add("ReplicaServerPort", 443);
|
||||
cmd.Parameters.Add("AuthenticationType", "Cert");
|
||||
cmd.Parameters.Add("CertificateThumbprint", localThumbprint);
|
||||
|
||||
PowerShell.Execute(cmd, true);
|
||||
}
|
||||
|
||||
public void StartInitialReplication(string vmId)
|
||||
{
|
||||
if (ReplicaMode != ReplicaMode.ReplicationEnabled)
|
||||
throw new Exception("Server does not allow replication by settings");
|
||||
|
||||
var vm = GetVirtualMachine(vmId);
|
||||
|
||||
Command cmd = new Command("Start-VMInitialReplication");
|
||||
cmd.Parameters.Add("VmName", vm.Name);
|
||||
|
||||
PowerShell.Execute(cmd, true);
|
||||
}
|
||||
|
||||
public VmReplication GetReplication(string vmId)
|
||||
{
|
||||
if (ReplicaMode != ReplicaMode.ReplicationEnabled)
|
||||
throw new Exception("Server does not allow replication by settings");
|
||||
|
||||
VmReplication replica = null;
|
||||
var vm = GetVirtualMachineEx(vmId);
|
||||
|
||||
Command cmd = new Command("Get-VMReplication");
|
||||
cmd.Parameters.Add("VmName", vm.Name);
|
||||
|
||||
Collection<PSObject> result = PowerShell.Execute(cmd, true);
|
||||
|
||||
if (result != null && result.Count > 0)
|
||||
{
|
||||
replica = new VmReplication();
|
||||
replica.ReplicaFrequency = result[0].GetEnum<ReplicaFrequency>("FrequencySec", ReplicaFrequency.Seconds30);
|
||||
replica.Thumbprint = result[0].GetString("CertificateThumbprint");
|
||||
replica.AdditionalRecoveryPoints = result[0].GetInt("RecoveryHistory");
|
||||
replica.VSSSnapshotFrequencyHour = result[0].GetInt("VSSSnapshotFrequencyHour");
|
||||
|
||||
List<string> excludes = new List<string>();
|
||||
foreach (dynamic item in (IEnumerable) result[0].GetProperty("ExcludedDisks"))
|
||||
excludes.Add(item.Path.ToString());
|
||||
replica.VhdToReplicate = vm.Disks
|
||||
.Select(d => d.Path)
|
||||
.FirstOrDefault(p => excludes.All(ep => !p.Equals(ep, StringComparison.OrdinalIgnoreCase)));
|
||||
}
|
||||
|
||||
return replica;
|
||||
}
|
||||
|
||||
public bool DisableVmReplication(string vmId, string replicaServer)
|
||||
{
|
||||
if (ReplicaMode != ReplicaMode.ReplicationEnabled)
|
||||
throw new Exception("Server does not allow replication by settings");
|
||||
|
||||
var vm = GetVirtualMachine(vmId);
|
||||
|
||||
ReplicaHelper.RemoveVmReplication(PowerShell, vm.Name, ServerNameSettings);
|
||||
|
||||
// move it to EnterpriseServer?
|
||||
// If we have access - delete garbage from replica server
|
||||
try
|
||||
{
|
||||
ReplicaHelper.RemoveVmReplication(PowerShell, vm.Name, replicaServer);
|
||||
// Delete replica vm
|
||||
VirtualMachineHelper.Stop(PowerShell, vm.Name, true, replicaServer);
|
||||
VirtualMachineHelper.Delete(PowerShell, vm.Name, replicaServer);
|
||||
}
|
||||
catch
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
public ReplicationDetailInfo GetReplicationInfo(string vmId)
|
||||
{
|
||||
if (ReplicaMode != ReplicaMode.ReplicationEnabled)
|
||||
throw new Exception("Server does not allow replication by settings");
|
||||
|
||||
ReplicationDetailInfo replica = null;
|
||||
var vm = GetVirtualMachine(vmId);
|
||||
|
||||
Command cmd = new Command("Measure-VMReplication");
|
||||
cmd.Parameters.Add("VmName", vm.Name);
|
||||
|
||||
Collection<PSObject> result = PowerShell.Execute(cmd, true);
|
||||
|
||||
if (result != null && result.Count > 0)
|
||||
{
|
||||
replica = new ReplicationDetailInfo();
|
||||
replica.AverageLatency = result[0].GetProperty<TimeSpan>("AverageReplicationLatency");
|
||||
replica.AverageSize = result[0].GetMb("AverageReplicationSize");
|
||||
replica.Errors = result[0].GetInt("ReplicationErrors");
|
||||
replica.FromTime = result[0].GetProperty<DateTime>("MonitoringStartTime");
|
||||
replica.Health = result[0].GetEnum<ReplicationHealth>("ReplicationHealth");
|
||||
replica.HealthDetails = result[0].GetString("ReplicationHealthDetails");
|
||||
replica.LastSynhronizedAt = result[0].GetProperty<DateTime>("LastReplicationTime");
|
||||
replica.MaximumSize = result[0].GetMb("MaximumReplicationSize");
|
||||
replica.Mode = result[0].GetEnum<VmReplicationMode>("ReplicationMode");
|
||||
replica.PendingSize = result[0].GetMb("PendingReplicationSize");
|
||||
replica.PrimaryServerName = result[0].GetString("PrimaryServerName");
|
||||
replica.ReplicaServerName = result[0].GetString("CurrentReplicaServerName");
|
||||
replica.State = result[0].GetEnum<ReplicationState>("ReplicationState");
|
||||
replica.SuccessfulReplications = result[0].GetInt("SuccessfulReplicationCount");
|
||||
replica.ToTime = result[0].GetProperty<DateTime>("MonitoringEndTime");
|
||||
}
|
||||
|
||||
return replica;
|
||||
}
|
||||
|
||||
public void PauseReplication(string vmId)
|
||||
{
|
||||
if (ReplicaMode != ReplicaMode.ReplicationEnabled)
|
||||
throw new Exception("Server does not allow replication by settings");
|
||||
|
||||
var vm = GetVirtualMachine(vmId);
|
||||
|
||||
Command cmd = new Command("Suspend-VMReplication");
|
||||
cmd.Parameters.Add("VmName", vm.Name);
|
||||
|
||||
PowerShell.Execute(cmd, true);
|
||||
}
|
||||
|
||||
public void ResumeReplication(string vmId)
|
||||
{
|
||||
if (ReplicaMode != ReplicaMode.ReplicationEnabled)
|
||||
throw new Exception("Server does not allow replication by settings");
|
||||
|
||||
var vm = GetVirtualMachine(vmId);
|
||||
|
||||
Command cmd = new Command("Resume-VMReplication");
|
||||
cmd.Parameters.Add("VmName", vm.Name);
|
||||
|
||||
PowerShell.Execute(cmd, true);
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
|
@ -56,6 +56,7 @@
|
|||
<Compile Include="Constants.cs" />
|
||||
<Compile Include="Extensions\PSObjectExtension.cs" />
|
||||
<Compile Include="Extensions\StringExtensions.cs" />
|
||||
<Compile Include="Helpers\ReplicaHelper.cs" />
|
||||
<Compile Include="Helpers\BiosHelper.cs" />
|
||||
<Compile Include="Helpers\MemoryHelper.cs" />
|
||||
<Compile Include="Helpers\VdsHelper.cs" />
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -99,6 +99,7 @@
|
|||
<Compile Include="VirtualizationServerProxy.cs">
|
||||
<SubType>code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="VirtualizationServerProxy2012.cs" />
|
||||
<Compile Include="WebServerProxy.cs" />
|
||||
<Compile Include="WindowsServerProxy.cs" />
|
||||
</ItemGroup>
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
<%@ WebService Language="C#" CodeBehind="VirtualizationServer2012.asmx.cs" Class="WebsitePanel.Server.VirtualizationServer" %>
|
File diff suppressed because it is too large
Load diff
|
@ -292,6 +292,7 @@
|
|||
<Content Include="ServiceProvider.asmx" />
|
||||
<Content Include="SharePointServer.asmx" />
|
||||
<Content Include="StatisticsServer.asmx" />
|
||||
<Content Include="VirtualizationServer2012.asmx" />
|
||||
<Content Include="VirtualizationServer.asmx" />
|
||||
<Content Include="VirtualizationServerForPrivateCloud.asmx" />
|
||||
<Content Include="bin\WebsitePanel.Server.dll.config" />
|
||||
|
@ -406,6 +407,10 @@
|
|||
<DependentUpon>StatisticsServer.asmx</DependentUpon>
|
||||
<SubType>Component</SubType>
|
||||
</Compile>
|
||||
<Compile Include="VirtualizationServer2012.asmx.cs">
|
||||
<DependentUpon>VirtualizationServer2012.asmx</DependentUpon>
|
||||
<SubType>Component</SubType>
|
||||
</Compile>
|
||||
<Compile Include="VirtualizationServer.asmx.cs">
|
||||
<DependentUpon>VirtualizationServer.asmx</DependentUpon>
|
||||
<SubType>Component</SubType>
|
||||
|
|
|
@ -26,8 +26,8 @@ REM %WSE_CLEAN% .\WebsitePanel.Server.Client\ExchangeServerHostedEditionProxy.cs
|
|||
REM %WSDL% %SERVER_URL%/HostedSharePointServer.asmx /out:.\WebsitePanel.Server.Client\HostedSharePointServerProxy.cs /namespace:WebsitePanel.Providers.HostedSolution /type:webClient /fields
|
||||
REM %WSE_CLEAN% .\WebsitePanel.Server.Client\HostedSharePointServerProxy.cs
|
||||
|
||||
%WSDL% %SERVER_URL%/HostedSharePointServerEnt.asmx /out:.\WebsitePanel.Server.Client\HostedSharePointServerEntProxy.cs /namespace:WebsitePanel.Providers.HostedSolution /type:webClient /fields
|
||||
%WSE_CLEAN% .\WebsitePanel.Server.Client\HostedSharePointServerEntProxy.cs
|
||||
REM %WSDL% %SERVER_URL%/HostedSharePointServerEnt.asmx /out:.\WebsitePanel.Server.Client\HostedSharePointServerEntProxy.cs /namespace:WebsitePanel.Providers.HostedSolution /type:webClient /fields
|
||||
REM %WSE_CLEAN% .\WebsitePanel.Server.Client\HostedSharePointServerEntProxy.cs
|
||||
|
||||
REM %WSDL% %SERVER_URL%/OCSEdgeServer.asmx /out:.\WebsitePanel.Server.Client\OCSEdgeServerProxy.cs /namespace:WebsitePanel.Providers.OCS /type:webClient /fields
|
||||
REM %WSE_CLEAN% .\WebsitePanel.Server.Client\OCSEdgeServerProxy.cs
|
||||
|
@ -50,6 +50,9 @@ REM %WSE_CLEAN% .\WebsitePanel.Server.Client\SharePointServerProxy.cs
|
|||
REM %WSDL% %SERVER_URL%/VirtualizationServer.asmx /out:.\WebsitePanel.Server.Client\VirtualizationServerProxy.cs /namespace:WebsitePanel.Providers.Virtualization /type:webClient /fields
|
||||
REM %WSE_CLEAN% .\WebsitePanel.Server.Client\VirtualizationServerProxy.cs
|
||||
|
||||
%WSDL% %SERVER_URL%/VirtualizationServer2012.asmx /out:.\WebsitePanel.Server.Client\VirtualizationServerProxy2012.cs /namespace:WebsitePanel.Providers.Virtualization2012 /type:webClient /fields
|
||||
%WSE_CLEAN% .\WebsitePanel.Server.Client\VirtualizationServerProxy2012.cs
|
||||
|
||||
REM %WSDL% %SERVER_URL%/VirtualizationServerForPrivateCloud.asmx /out:.\WebsitePanel.Server.Client\VirtualizationServerForPrivateCloudProxy.cs /namespace:WebsitePanel.Providers.VirtualizationForPC /type:webClient /fields
|
||||
REM %WSE_CLEAN% .\WebsitePanel.Server.Client\VirtualizationServerForPrivateCloudProxy.cs
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue