From 27155ddc5eacb81223d208f819415608981653d9 Mon Sep 17 00:00:00 2001 From: Alexander Trofimov Date: Thu, 16 Apr 2015 22:21:20 +0300 Subject: [PATCH 1/2] wsp-10329 Adding hyper-v replica to HyperV Provider. Enterprise Part 2. --- .../VirtualizationErrorCodes.cs | 3 + .../VirtualizationServerProxy2012.cs | 156 ++++++++++++++++++ .../VirtualizationServerController2012.cs | 24 +++ .../esVirtualizationServer2012.asmx.cs | 13 ++ .../HyperV2012R2_Settings.ascx.resx | 39 +++++ .../HyperV2012R2_Settings.ascx | 72 +++++++- .../HyperV2012R2_Settings.ascx.cs | 88 ++++++++-- .../HyperV2012R2_Settings.ascx.designer.cs | 142 +++++++++++++++- 8 files changed, 508 insertions(+), 29 deletions(-) diff --git a/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Base/Virtualization/VirtualizationErrorCodes.cs b/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Base/Virtualization/VirtualizationErrorCodes.cs index 6ccd5695..7c92ee9f 100644 --- a/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Base/Virtualization/VirtualizationErrorCodes.cs +++ b/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Base/Virtualization/VirtualizationErrorCodes.cs @@ -113,6 +113,9 @@ public const string INSERT_DVD_DISK_ERROR = "VPS_INSERT_DVD_DISK_ERROR"; public const string EJECT_DVD_DISK_ERROR = "VPS_EJECT_DVD_DISK_ERROR"; + // Replication + public const string SET_REPLICA_SERVER_ERROR = "SET_REPLICA_SERVER_ERROR"; + public const string HOST_NAMER_IS_ALREADY_USED = "HOST_NAMER_IS_ALREADY_USED"; public const string CANNOT_CHECK_HOST_EXISTS = "CANNOT_CHECK_HOST_EXISTS"; diff --git a/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Client/VirtualizationServerProxy2012.cs b/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Client/VirtualizationServerProxy2012.cs index 93f77397..b52ec841 100644 --- a/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Client/VirtualizationServerProxy2012.cs +++ b/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Client/VirtualizationServerProxy2012.cs @@ -146,6 +146,10 @@ namespace WebsitePanel.EnterpriseServer { private System.Threading.SendOrPostCallback GetCertificatesOperationCompleted; + private System.Threading.SendOrPostCallback SetReplicaServerOperationCompleted; + + private System.Threading.SendOrPostCallback IsReplicaServerOperationCompleted; + /// public esVirtualizationServer2012() { this.Url = "http://127.0.0.1:9012/esVirtualizationServer2012.asmx"; @@ -319,6 +323,12 @@ namespace WebsitePanel.EnterpriseServer { /// public event GetCertificatesCompletedEventHandler GetCertificatesCompleted; + /// + public event SetReplicaServerCompletedEventHandler SetReplicaServerCompleted; + + /// + public event IsReplicaServerCompletedEventHandler IsReplicaServerCompleted; + /// [System.Web.Services.Protocols.SoapDocumentMethodAttribute("http://smbsaas/websitepanel/enterpriseserver/GetVirtualMachines", RequestNamespace="http://smbsaas/websitepanel/enterpriseserver", ResponseNamespace="http://smbsaas/websitepanel/enterpriseserver", Use=System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Wrapped)] public VirtualMachineMetaItemsPaged GetVirtualMachines(int packageId, string filterColumn, string filterValue, string sortColumn, int startRow, int maximumRows, bool recursive) { @@ -3173,6 +3183,100 @@ namespace WebsitePanel.EnterpriseServer { } } + /// + [System.Web.Services.Protocols.SoapDocumentMethodAttribute("http://smbsaas/websitepanel/enterpriseserver/SetReplicaServer", RequestNamespace="http://smbsaas/websitepanel/enterpriseserver", ResponseNamespace="http://smbsaas/websitepanel/enterpriseserver", Use=System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Wrapped)] + public ResultObject SetReplicaServer(int serviceId, string remoteServer, string thumbprint, string storagePath) { + object[] results = this.Invoke("SetReplicaServer", new object[] { + serviceId, + remoteServer, + thumbprint, + storagePath}); + return ((ResultObject)(results[0])); + } + + /// + public System.IAsyncResult BeginSetReplicaServer(int serviceId, string remoteServer, string thumbprint, string storagePath, System.AsyncCallback callback, object asyncState) { + return this.BeginInvoke("SetReplicaServer", new object[] { + serviceId, + remoteServer, + thumbprint, + storagePath}, callback, asyncState); + } + + /// + public ResultObject EndSetReplicaServer(System.IAsyncResult asyncResult) { + object[] results = this.EndInvoke(asyncResult); + return ((ResultObject)(results[0])); + } + + /// + public void SetReplicaServerAsync(int serviceId, string remoteServer, string thumbprint, string storagePath) { + this.SetReplicaServerAsync(serviceId, remoteServer, thumbprint, storagePath, null); + } + + /// + public void SetReplicaServerAsync(int serviceId, string remoteServer, string thumbprint, string storagePath, object userState) { + if ((this.SetReplicaServerOperationCompleted == null)) { + this.SetReplicaServerOperationCompleted = new System.Threading.SendOrPostCallback(this.OnSetReplicaServerOperationCompleted); + } + this.InvokeAsync("SetReplicaServer", new object[] { + serviceId, + remoteServer, + thumbprint, + storagePath}, this.SetReplicaServerOperationCompleted, userState); + } + + private void OnSetReplicaServerOperationCompleted(object arg) { + if ((this.SetReplicaServerCompleted != null)) { + System.Web.Services.Protocols.InvokeCompletedEventArgs invokeArgs = ((System.Web.Services.Protocols.InvokeCompletedEventArgs)(arg)); + this.SetReplicaServerCompleted(this, new SetReplicaServerCompletedEventArgs(invokeArgs.Results, invokeArgs.Error, invokeArgs.Cancelled, invokeArgs.UserState)); + } + } + + /// + [System.Web.Services.Protocols.SoapDocumentMethodAttribute("http://smbsaas/websitepanel/enterpriseserver/IsReplicaServer", RequestNamespace="http://smbsaas/websitepanel/enterpriseserver", ResponseNamespace="http://smbsaas/websitepanel/enterpriseserver", Use=System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Wrapped)] + public bool IsReplicaServer(int serviceId, string remoteServer) { + object[] results = this.Invoke("IsReplicaServer", new object[] { + serviceId, + remoteServer}); + return ((bool)(results[0])); + } + + /// + public System.IAsyncResult BeginIsReplicaServer(int serviceId, string remoteServer, System.AsyncCallback callback, object asyncState) { + return this.BeginInvoke("IsReplicaServer", new object[] { + serviceId, + remoteServer}, callback, asyncState); + } + + /// + public bool EndIsReplicaServer(System.IAsyncResult asyncResult) { + object[] results = this.EndInvoke(asyncResult); + return ((bool)(results[0])); + } + + /// + public void IsReplicaServerAsync(int serviceId, string remoteServer) { + this.IsReplicaServerAsync(serviceId, remoteServer, null); + } + + /// + public void IsReplicaServerAsync(int serviceId, string remoteServer, object userState) { + if ((this.IsReplicaServerOperationCompleted == null)) { + this.IsReplicaServerOperationCompleted = new System.Threading.SendOrPostCallback(this.OnIsReplicaServerOperationCompleted); + } + this.InvokeAsync("IsReplicaServer", new object[] { + serviceId, + remoteServer}, this.IsReplicaServerOperationCompleted, userState); + } + + private void OnIsReplicaServerOperationCompleted(object arg) { + if ((this.IsReplicaServerCompleted != null)) { + System.Web.Services.Protocols.InvokeCompletedEventArgs invokeArgs = ((System.Web.Services.Protocols.InvokeCompletedEventArgs)(arg)); + this.IsReplicaServerCompleted(this, new IsReplicaServerCompletedEventArgs(invokeArgs.Results, invokeArgs.Error, invokeArgs.Cancelled, invokeArgs.UserState)); + } + } + /// public new void CancelAsync(object userState) { base.CancelAsync(userState); @@ -4634,4 +4738,56 @@ namespace WebsitePanel.EnterpriseServer { } } } + + /// + [System.CodeDom.Compiler.GeneratedCodeAttribute("wsdl", "2.0.50727.42")] + public delegate void SetReplicaServerCompletedEventHandler(object sender, SetReplicaServerCompletedEventArgs e); + + /// + [System.CodeDom.Compiler.GeneratedCodeAttribute("wsdl", "2.0.50727.42")] + [System.Diagnostics.DebuggerStepThroughAttribute()] + [System.ComponentModel.DesignerCategoryAttribute("code")] + public partial class SetReplicaServerCompletedEventArgs : System.ComponentModel.AsyncCompletedEventArgs { + + private object[] results; + + internal SetReplicaServerCompletedEventArgs(object[] results, System.Exception exception, bool cancelled, object userState) : + base(exception, cancelled, userState) { + this.results = results; + } + + /// + public ResultObject Result { + get { + this.RaiseExceptionIfNecessary(); + return ((ResultObject)(this.results[0])); + } + } + } + + /// + [System.CodeDom.Compiler.GeneratedCodeAttribute("wsdl", "2.0.50727.42")] + public delegate void IsReplicaServerCompletedEventHandler(object sender, IsReplicaServerCompletedEventArgs e); + + /// + [System.CodeDom.Compiler.GeneratedCodeAttribute("wsdl", "2.0.50727.42")] + [System.Diagnostics.DebuggerStepThroughAttribute()] + [System.ComponentModel.DesignerCategoryAttribute("code")] + public partial class IsReplicaServerCompletedEventArgs : System.ComponentModel.AsyncCompletedEventArgs { + + private object[] results; + + internal IsReplicaServerCompletedEventArgs(object[] results, System.Exception exception, bool cancelled, object userState) : + base(exception, cancelled, userState) { + this.results = results; + } + + /// + public bool Result { + get { + this.RaiseExceptionIfNecessary(); + return ((bool)(this.results[0])); + } + } + } } diff --git a/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Code/Virtualization2012/VirtualizationServerController2012.cs b/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Code/Virtualization2012/VirtualizationServerController2012.cs index 5171fd45..4b722429 100644 --- a/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Code/Virtualization2012/VirtualizationServerController2012.cs +++ b/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Code/Virtualization2012/VirtualizationServerController2012.cs @@ -3726,6 +3726,30 @@ namespace WebsitePanel.EnterpriseServer return vs.GetCertificates(remoteServer); } + public static ResultObject SetReplicaServer(int serviceId, string remoteServer, string thumbprint, string storagePath) + { + ResultObject result = new ResultObject(); + try + { + if (string.IsNullOrEmpty(storagePath)) + throw new Exception("Please enter replication path"); + + VirtualizationServer2012 vs = GetVirtualizationProxy(serviceId); + vs.SetReplicaServer(remoteServer, thumbprint, storagePath); + } + catch (Exception ex) + { + result.AddError(VirtualizationErrorCodes.SET_REPLICA_SERVER_ERROR, ex); + } + return result; + } + + public static bool IsReplicaServer(int serviceId, string remoteServer) + { + VirtualizationServer2012 vs = GetVirtualizationProxy(serviceId); + return vs.IsReplicaServer(remoteServer); + } + #endregion } } diff --git a/WebsitePanel/Sources/WebsitePanel.EnterpriseServer/esVirtualizationServer2012.asmx.cs b/WebsitePanel/Sources/WebsitePanel.EnterpriseServer/esVirtualizationServer2012.asmx.cs index 8a3202ce..2d8275d2 100644 --- a/WebsitePanel/Sources/WebsitePanel.EnterpriseServer/esVirtualizationServer2012.asmx.cs +++ b/WebsitePanel/Sources/WebsitePanel.EnterpriseServer/esVirtualizationServer2012.asmx.cs @@ -481,6 +481,19 @@ namespace WebsitePanel.EnterpriseServer return VirtualizationServerController2012.GetCertificates(serviceId, remoteServer); } + [WebMethod] + public ResultObject SetReplicaServer(int serviceId, string remoteServer, string thumbprint, string storagePath) + { + return VirtualizationServerController2012.SetReplicaServer(serviceId, remoteServer, thumbprint, storagePath); + } + + [WebMethod] + public bool IsReplicaServer(int serviceId, string remoteServer) + { + return VirtualizationServerController2012.IsReplicaServer(serviceId, remoteServer); + } + + #endregion } } diff --git a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ProviderControls/App_LocalResources/HyperV2012R2_Settings.ascx.resx b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ProviderControls/App_LocalResources/HyperV2012R2_Settings.ascx.resx index 3c34e5ff..494ca0db 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ProviderControls/App_LocalResources/HyperV2012R2_Settings.ascx.resx +++ b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ProviderControls/App_LocalResources/HyperV2012R2_Settings.ascx.resx @@ -401,4 +401,43 @@ The following substitution variables can be used in the pattern:<br/> Hyper-V Cloud + + Set + + + Enter the thumbnail of a SSL certificate + + + SSL Certificate Thumbnail: + + + Can not to set server as a replication server with the entered server name, replication path and SSL certificate + + + Path for Replications: + + + Replica Server: + + + Replication + + + Enter path to replication virtual machines + + + Enter a replication server name + + + No Hyper-v Replication + + + Enable Hyper-V Replication + + + This is a Replica Server + + + Please enter replication path + \ No newline at end of file diff --git a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ProviderControls/HyperV2012R2_Settings.ascx b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ProviderControls/HyperV2012R2_Settings.ascx index cdca54c5..1c5c12e1 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ProviderControls/HyperV2012R2_Settings.ascx +++ b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ProviderControls/HyperV2012R2_Settings.ascx @@ -82,6 +82,26 @@ Text="*" meta:resourcekey="ExportedVpsPathValidator" Display="Dynamic" SetFocusOnError="true" /> + + + + + + + + + + + + + + + + + +
@@ -129,19 +149,55 @@
- + +
- - + + + +
- + + + No Hyper-v Replication + Enable Hyper-V Replication + This is a Replica Server + - - -
+ + + + + + + + + + + +
+ + + + + + + + +
+ +
+ +
+

diff --git a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ProviderControls/HyperV2012R2_Settings.ascx.cs b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ProviderControls/HyperV2012R2_Settings.ascx.cs index 93b5fac3..2814fe0c 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ProviderControls/HyperV2012R2_Settings.ascx.cs +++ b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ProviderControls/HyperV2012R2_Settings.ascx.cs @@ -26,21 +26,12 @@ // (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; -using System.Configuration; -using System.Data; -using System.Web; -using System.Web.Security; -using System.Web.UI; -using System.Web.UI.HtmlControls; -using System.Web.UI.WebControls; -using System.Web.UI.WebControls.WebParts; +using System; using System.Collections.Specialized; +using System.Linq; +using System.Web.UI.WebControls; +using WebsitePanel.Providers.Common; using WebsitePanel.Providers.Virtualization; -using WebsitePanel.EnterpriseServer; -using System.Web.UI.MobileControls; -using System.Collections.Generic; namespace WebsitePanel.Portal.ProviderControls { @@ -50,6 +41,11 @@ namespace WebsitePanel.Portal.ProviderControls { } + public bool IsRemoteServer { get { return radioServer.SelectedIndex > 0; } } + public string RemoteServerName { get { return IsRemoteServer ? txtServerName.Text.Trim() : ""; } } + public string CertificateThumbprint { get { return IsRemoteServer ? txtCertThumbnail.Text.Trim() : ddlCertThumbnail.SelectedValue; } } + public bool IsReplicaServer { get { return ReplicationModeList.SelectedValue == "IsReplicaServer"; } } + void IHostingServiceProviderSettings.BindSettings(StringDictionary settings) { txtServerName.Text = settings["ServerName"]; @@ -104,7 +100,23 @@ namespace WebsitePanel.Portal.ProviderControls // stop radioStopAction.SelectedValue = settings["StopAction"]; + // replica + ReplicationModeList.SelectedValue = settings["ReplicaMode"] ?? "Disabled"; + txtReplicaPath.Text = settings["ReplicaServerPath"]; + ToggleControls(); + + // replica + txtCertThumbnail.Text = settings["ReplicaServerThumbprint"]; + ddlCertThumbnail.SelectedValue = settings["ReplicaServerThumbprint"]; + + if (IsReplicaServer) + { + var serverIsRealReplica = ES.Services.VPS2012.IsReplicaServer(PanelRequest.ServiceId, RemoteServerName); + + if (!serverIsRealReplica) + ReplicaErrorTr.Visible = true; + } } void IHostingServiceProviderSettings.SaveSettings(StringDictionary settings) @@ -156,6 +168,13 @@ namespace WebsitePanel.Portal.ProviderControls // stop settings["StopAction"] = radioStopAction.SelectedValue; + + // replication + settings["ReplicaMode"] = ReplicationModeList.SelectedValue; + settings["ReplicaServerPath"] = txtReplicaPath.Text; + settings["ReplicaServerThumbprint"] = CertificateThumbprint; + + SetReplication(); } private void BindNetworksList() @@ -181,6 +200,17 @@ namespace WebsitePanel.Portal.ProviderControls } } + private void BindCertificates() + { + CertificateInfo[] certificates = ES.Services.VPS2012.GetCertificates(PanelRequest.ServiceId, RemoteServerName); + + if (certificates != null) + { + ddlCertThumbnail.Items.Clear(); + certificates.ToList().ForEach(c => ddlCertThumbnail.Items.Add(new ListItem(c.Title, c.Thumbprint))); + } + } + private void ToggleControls() { ServerNameRow.Visible = (radioServer.SelectedIndex == 1); @@ -197,6 +227,14 @@ namespace WebsitePanel.Portal.ProviderControls ManageNicConfigRow.Visible = (ddlManagementNetworks.SelectedIndex > 0); ManageAlternateNameServerRow.Visible = ManageNicConfigRow.Visible && (ddlManageNicConfig.SelectedIndex == 0); ManagePreferredNameServerRow.Visible = ManageNicConfigRow.Visible && (ddlManageNicConfig.SelectedIndex == 0); + + // Replica + IsReplicaServerRow.Visible = IsReplicaServer; + ddlCertThumbnail.Visible = !IsRemoteServer; + txtCertThumbnail.Visible = CertificateThumbnailValidator.Visible = IsRemoteServer; + IsReplicaServerRow.Visible = IsReplicaServer; + ReplicaPathErrorTr.Visible = ReplicaErrorTr.Visible = false; + if (IsReplicaServer) BindCertificates(); } protected void radioServer_SelectedIndexChanged(object sender, EventArgs e) @@ -223,5 +261,29 @@ namespace WebsitePanel.Portal.ProviderControls { ToggleControls(); } + + protected void btnSetReplicaServer_Click(object sender, EventArgs e) + { + ToggleControls(); + SetReplication(); + } + + private void SetReplication() + { + if (!IsReplicaServer) + return; + + if (txtReplicaPath.Text == "") + { + ReplicaPathErrorTr.Visible = true; + return; + } + + var thumbprint = IsRemoteServer ? txtCertThumbnail.Text : ddlCertThumbnail.SelectedValue; + ResultObject result = ES.Services.VPS2012.SetReplicaServer(PanelRequest.ServiceId, RemoteServerName, thumbprint, txtReplicaPath.Text); + + if (!result.IsSuccess) + ReplicaErrorTr.Visible = true; + } } } diff --git a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ProviderControls/HyperV2012R2_Settings.ascx.designer.cs b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ProviderControls/HyperV2012R2_Settings.ascx.designer.cs index 40718603..2ae51e9a 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ProviderControls/HyperV2012R2_Settings.ascx.designer.cs +++ b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ProviderControls/HyperV2012R2_Settings.ascx.designer.cs @@ -201,6 +201,60 @@ namespace WebsitePanel.Portal.ProviderControls { ///
protected global::System.Web.UI.WebControls.RequiredFieldValidator ExportedVpsPathValidator; + /// + /// locDvdIsoPath control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.Localize locDvdIsoPath; + + /// + /// txtDvdLibraryPath control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.TextBox txtDvdLibraryPath; + + /// + /// DvdLibraryPathValidator control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.RequiredFieldValidator DvdLibraryPathValidator; + + /// + /// locReplicaPath control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.Localize locReplicaPath; + + /// + /// txtReplicaPath control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.TextBox txtReplicaPath; + + /// + /// ReplicaPathValidator control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.RequiredFieldValidator ReplicaPathValidator; + /// /// locProcessorSettings control. /// @@ -292,40 +346,112 @@ namespace WebsitePanel.Portal.ProviderControls { protected global::System.Web.UI.WebControls.RequiredFieldValidator CpuWeightValidator; /// - /// locMediaLibrary control. + /// locReplication control. /// /// /// Auto-generated field. /// To modify move field declaration from designer file to code-behind file. /// - protected global::System.Web.UI.WebControls.Localize locMediaLibrary; + protected global::System.Web.UI.WebControls.Localize locReplication; /// - /// locDvdIsoPath control. + /// ReplicationModeList control. /// /// /// Auto-generated field. /// To modify move field declaration from designer file to code-behind file. /// - protected global::System.Web.UI.WebControls.Localize locDvdIsoPath; + protected global::System.Web.UI.WebControls.RadioButtonList ReplicationModeList; /// - /// txtDvdLibraryPath control. + /// IsReplicaServerRow control. /// /// /// Auto-generated field. /// To modify move field declaration from designer file to code-behind file. /// - protected global::System.Web.UI.WebControls.TextBox txtDvdLibraryPath; + protected global::System.Web.UI.HtmlControls.HtmlTableRow IsReplicaServerRow; /// - /// DvdLibraryPathValidator control. + /// locCertThumbnail control. /// /// /// Auto-generated field. /// To modify move field declaration from designer file to code-behind file. /// - protected global::System.Web.UI.WebControls.RequiredFieldValidator DvdLibraryPathValidator; + protected global::System.Web.UI.WebControls.Localize locCertThumbnail; + + /// + /// ddlCertThumbnail control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.DropDownList ddlCertThumbnail; + + /// + /// txtCertThumbnail control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.TextBox txtCertThumbnail; + + /// + /// btnSetReplicaServer control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.Button btnSetReplicaServer; + + /// + /// CertificateThumbnailValidator control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.RequiredFieldValidator CertificateThumbnailValidator; + + /// + /// ReplicaPathErrorTr control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.HtmlControls.HtmlTableRow ReplicaPathErrorTr; + + /// + /// locErrorPathReplica control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.Label locErrorPathReplica; + + /// + /// ReplicaErrorTr control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.HtmlControls.HtmlTableRow ReplicaErrorTr; + + /// + /// locErrorSetReplica control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.Label locErrorSetReplica; /// /// locVhd control. From 019ad51eae2ec31f5943e482776c5ba38ab4f7cd Mon Sep 17 00:00:00 2001 From: Alexander Trofimov Date: Fri, 17 Apr 2015 19:18:49 +0300 Subject: [PATCH 2/2] wsp-10329 Adding hyper-v replica to HyperV Provider. Enterprise Part 3. --- .../VirtualizationServerController2012.cs | 1 + .../HyperV2012R2_Settings.ascx.resx | 13 ++-- .../HyperV2012R2_Settings.ascx | 48 +++++++++---- .../HyperV2012R2_Settings.ascx.cs | 67 +++++++++++++++++++ .../HyperV2012R2_Settings.ascx.designer.cs | 63 +++++++++++++++++ 5 files changed, 175 insertions(+), 17 deletions(-) diff --git a/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Code/Virtualization2012/VirtualizationServerController2012.cs b/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Code/Virtualization2012/VirtualizationServerController2012.cs index 4b722429..79a19aeb 100644 --- a/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Code/Virtualization2012/VirtualizationServerController2012.cs +++ b/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.Code/Virtualization2012/VirtualizationServerController2012.cs @@ -3736,6 +3736,7 @@ namespace WebsitePanel.EnterpriseServer VirtualizationServer2012 vs = GetVirtualizationProxy(serviceId); vs.SetReplicaServer(remoteServer, thumbprint, storagePath); + result.IsSuccess = true; } catch (Exception ex) { diff --git a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ProviderControls/App_LocalResources/HyperV2012R2_Settings.ascx.resx b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ProviderControls/App_LocalResources/HyperV2012R2_Settings.ascx.resx index 494ca0db..6f5392eb 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ProviderControls/App_LocalResources/HyperV2012R2_Settings.ascx.resx +++ b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ProviderControls/App_LocalResources/HyperV2012R2_Settings.ascx.resx @@ -408,7 +408,7 @@ The following substitution variables can be used in the pattern:<br/> Enter the thumbnail of a SSL certificate - SSL Certificate Thumbnail: + SSL Certificate Thumbprint: Can not to set server as a replication server with the entered server name, replication path and SSL certificate @@ -416,9 +416,6 @@ The following substitution variables can be used in the pattern:<br/> Path for Replications: - - Replica Server: - Replication @@ -426,7 +423,7 @@ The following substitution variables can be used in the pattern:<br/> Enter path to replication virtual machines - Enter a replication server name + Enter a replication server No Hyper-v Replication @@ -437,7 +434,13 @@ The following substitution variables can be used in the pattern:<br/> This is a Replica Server + + Please add a server with the enabled replication and select it from list + Please enter replication path + + Replication Server: + \ No newline at end of file diff --git a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ProviderControls/HyperV2012R2_Settings.ascx b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ProviderControls/HyperV2012R2_Settings.ascx index 1c5c12e1..a1c3b68a 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ProviderControls/HyperV2012R2_Settings.ascx +++ b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ProviderControls/HyperV2012R2_Settings.ascx @@ -152,18 +152,40 @@ -
- - - - +
- - No Hyper-v Replication - Enable Hyper-V Replication - This is a Replica Server - -
+ + + + + + +
+ + No Hyper-v Replication + Enable Hyper-V Replication + This is a Replica Server + +
+ + + + + + + + +
+ + + + + +
+ +
+
@@ -180,6 +202,8 @@ + diff --git a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ProviderControls/HyperV2012R2_Settings.ascx.cs b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ProviderControls/HyperV2012R2_Settings.ascx.cs index 2814fe0c..974ce822 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ProviderControls/HyperV2012R2_Settings.ascx.cs +++ b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ProviderControls/HyperV2012R2_Settings.ascx.cs @@ -27,9 +27,12 @@ // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. using System; +using System.Collections.Generic; using System.Collections.Specialized; +using System.Data; using System.Linq; using System.Web.UI.WebControls; +using WebsitePanel.EnterpriseServer; using WebsitePanel.Providers.Common; using WebsitePanel.Providers.Virtualization; @@ -45,6 +48,8 @@ namespace WebsitePanel.Portal.ProviderControls public string RemoteServerName { get { return IsRemoteServer ? txtServerName.Text.Trim() : ""; } } public string CertificateThumbprint { get { return IsRemoteServer ? txtCertThumbnail.Text.Trim() : ddlCertThumbnail.SelectedValue; } } public bool IsReplicaServer { get { return ReplicationModeList.SelectedValue == "IsReplicaServer"; } } + public bool EnabledReplica { get { return ReplicationModeList.SelectedValue == "Enable"; } } + public string ReplicaServerId { get; set; } void IHostingServiceProviderSettings.BindSettings(StringDictionary settings) { @@ -103,6 +108,7 @@ namespace WebsitePanel.Portal.ProviderControls // replica ReplicationModeList.SelectedValue = settings["ReplicaMode"] ?? "Disabled"; txtReplicaPath.Text = settings["ReplicaServerPath"]; + ReplicaServerId = settings["ReplicaServerId"]; ToggleControls(); @@ -171,6 +177,7 @@ namespace WebsitePanel.Portal.ProviderControls // replication settings["ReplicaMode"] = ReplicationModeList.SelectedValue; + settings["ReplicaServerId"] = ddlReplicaServer.SelectedValue; settings["ReplicaServerPath"] = txtReplicaPath.Text; settings["ReplicaServerThumbprint"] = CertificateThumbprint; @@ -211,6 +218,64 @@ namespace WebsitePanel.Portal.ProviderControls } } + + private void BindReplicaServices() + { + ddlReplicaServer.Items.Clear(); + + ServiceInfo serviceInfo = ES.Services.Servers.GetServiceInfo(PanelRequest.ServiceId); + DataView dvServices = ES.Services.Servers.GetRawServicesByGroupName(ResourceGroups.VPS2012).Tables[0].DefaultView; + + List services = GetServices(ReplicaServerId); + + foreach (DataRowView dr in dvServices) + { + int serviceId = (int)dr["ServiceID"]; + + ServiceInfo currentServiceInfo = ES.Services.Servers.GetServiceInfo(serviceId); + if (currentServiceInfo == null || currentServiceInfo.ProviderId != serviceInfo.ProviderId) + continue; + + var currentServiceSettings = ConvertArrayToDictionary(ES.Services.Servers.GetServiceSettings(serviceId)); + if (currentServiceSettings["ReplicaMode"] == ReplicaMode.IsReplicaServer.ToString()) + continue; + + var exists = false; + if (services != null) + exists = services.Any(current => current != null && current.ServiceId == serviceId); + + var listItem = new ListItem(dr["FullServiceName"].ToString(), serviceId.ToString()) {Selected = exists}; + ddlReplicaServer.Items.Add(listItem); + } + } + + private List GetServices(string data) + { + if (string.IsNullOrEmpty(data)) + return null; + List list = new List(); + string[] servicesIds = data.Split(','); + foreach (string current in servicesIds) + { + ServiceInfo serviceInfo = ES.Services.Servers.GetServiceInfo(Utils.ParseInt(current)); + list.Add(serviceInfo); + } + + + return list; + } + + private StringDictionary ConvertArrayToDictionary(string[] settings) + { + StringDictionary r = new StringDictionary(); + foreach (string setting in settings) + { + int idx = setting.IndexOf('='); + r.Add(setting.Substring(0, idx), setting.Substring(idx + 1)); + } + return r; + } + private void ToggleControls() { ServerNameRow.Visible = (radioServer.SelectedIndex == 1); @@ -230,11 +295,13 @@ namespace WebsitePanel.Portal.ProviderControls // Replica IsReplicaServerRow.Visible = IsReplicaServer; + EnableReplicaRow.Visible = EnabledReplica; ddlCertThumbnail.Visible = !IsRemoteServer; txtCertThumbnail.Visible = CertificateThumbnailValidator.Visible = IsRemoteServer; IsReplicaServerRow.Visible = IsReplicaServer; ReplicaPathErrorTr.Visible = ReplicaErrorTr.Visible = false; if (IsReplicaServer) BindCertificates(); + if (EnabledReplica) BindReplicaServices(); } protected void radioServer_SelectedIndexChanged(object sender, EventArgs e) diff --git a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ProviderControls/HyperV2012R2_Settings.ascx.designer.cs b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ProviderControls/HyperV2012R2_Settings.ascx.designer.cs index 2ae51e9a..d8100907 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ProviderControls/HyperV2012R2_Settings.ascx.designer.cs +++ b/WebsitePanel/Sources/WebsitePanel.WebPortal/DesktopModules/WebsitePanel/ProviderControls/HyperV2012R2_Settings.ascx.designer.cs @@ -363,6 +363,60 @@ namespace WebsitePanel.Portal.ProviderControls { /// protected global::System.Web.UI.WebControls.RadioButtonList ReplicationModeList; + /// + /// EnableReplicaRow control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.HtmlControls.HtmlTableRow EnableReplicaRow; + + /// + /// locReplicaServer control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.Localize locReplicaServer; + + /// + /// ddlReplicaServer control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.DropDownList ddlReplicaServer; + + /// + /// ReplicaServerValidator control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.RequiredFieldValidator ReplicaServerValidator; + + /// + /// EnableReplicaErrorTr control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.HtmlControls.HtmlTableRow EnableReplicaErrorTr; + + /// + /// locEnableReplicaError control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.Label locEnableReplicaError; + /// /// IsReplicaServerRow control. /// @@ -417,6 +471,15 @@ namespace WebsitePanel.Portal.ProviderControls { /// protected global::System.Web.UI.WebControls.RequiredFieldValidator CertificateThumbnailValidator; + /// + /// CertificateDdlThumbnailValidator control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.RequiredFieldValidator CertificateDdlThumbnailValidator; + /// /// ReplicaPathErrorTr control. ///