2023-01-24 15:29:31 +01:00
|
|
|
|
/* Copyright (c) Cloud Software Group, Inc.
|
2013-06-24 13:41:48 +02:00
|
|
|
|
*
|
|
|
|
|
* 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.
|
|
|
|
|
*
|
|
|
|
|
* 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.Drawing;
|
|
|
|
|
using System.Windows.Forms;
|
|
|
|
|
using XenAPI;
|
|
|
|
|
using XenAdmin.Core;
|
|
|
|
|
using XenAdmin.Controls;
|
|
|
|
|
using System.ComponentModel;
|
|
|
|
|
using XenAdmin.Actions;
|
|
|
|
|
using XenAdmin.Model;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
namespace XenAdmin.SettingsPanels
|
|
|
|
|
{
|
|
|
|
|
public partial class GeneralEditPage : UserControl, IEditPage
|
|
|
|
|
{
|
|
|
|
|
private IXenObject xenObjectOrig, xenObjectCopy;
|
|
|
|
|
|
|
|
|
|
private bool _ValidToSave = true;
|
|
|
|
|
private bool saveDescription;
|
|
|
|
|
|
|
|
|
|
private readonly ToolTip InvalidParamToolTip;
|
|
|
|
|
|
2021-03-16 02:50:45 +01:00
|
|
|
|
public bool ValidToSave => _ValidToSave;
|
2013-06-24 13:41:48 +02:00
|
|
|
|
|
|
|
|
|
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
|
|
|
|
public string ObjectName
|
|
|
|
|
{
|
2021-03-16 02:50:45 +01:00
|
|
|
|
set => txtName.Text = value;
|
|
|
|
|
get => txtName.Text.Trim();
|
2013-06-24 13:41:48 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
2021-03-16 02:50:45 +01:00
|
|
|
|
public string ObjectDescription => saveDescription ? txtDescription.Text : txtDescrReadOnly.Text;
|
2013-06-24 13:41:48 +02:00
|
|
|
|
|
|
|
|
|
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
|
|
|
|
public string ServerIQN
|
|
|
|
|
{
|
2021-03-16 02:50:45 +01:00
|
|
|
|
set => txtIQN.Text = value;
|
|
|
|
|
get => txtIQN.Text.Trim();
|
2013-06-24 13:41:48 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private TagsEditor tagsEditor;
|
|
|
|
|
private FolderEditor folderEditor;
|
|
|
|
|
|
|
|
|
|
public void SetXenObjects(IXenObject orig, IXenObject clone)
|
|
|
|
|
{
|
|
|
|
|
if (clone == null)
|
|
|
|
|
return;
|
|
|
|
|
this.xenObjectCopy = clone;
|
|
|
|
|
this.xenObjectOrig = orig;
|
|
|
|
|
|
|
|
|
|
if (tagsEditor != null)
|
|
|
|
|
tagsEditor.Dispose();
|
|
|
|
|
tagsEditor = new TagsEditor(GetTagsFromXenObjectCopy(), tagsPanel);
|
|
|
|
|
tagsEditor.Location = new Point(5, 5);
|
|
|
|
|
tagsEditor.Size = new Size(tagsPanel.Width - 10, tagsPanel.Height - 10);
|
|
|
|
|
tagsEditor.Anchor = AnchorStyles.Left | AnchorStyles.Right | AnchorStyles.Top;
|
|
|
|
|
|
|
|
|
|
if (folderEditor != null)
|
|
|
|
|
folderEditor.Dispose();
|
|
|
|
|
folderEditor = new FolderEditor(clone.Path);
|
|
|
|
|
folderEditor.Parent = folderPanel;
|
|
|
|
|
folderEditor.Location = new Point(0, 2);
|
|
|
|
|
folderEditor.Size = new Size(folderPanel.Width - 6, folderPanel.Height - 4);
|
|
|
|
|
folderEditor.Anchor = AnchorStyles.Left | AnchorStyles.Right | AnchorStyles.Top;
|
|
|
|
|
|
|
|
|
|
Repopulate();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public GeneralEditPage()
|
|
|
|
|
{
|
|
|
|
|
InitializeComponent();
|
2021-03-16 02:50:45 +01:00
|
|
|
|
labelTitle.Text = string.Format(labelTitle.Text, BrandManager.BrandConsole);
|
2013-06-24 13:41:48 +02:00
|
|
|
|
|
|
|
|
|
Text = Messages.NAME_DESCRIPTION_TAGS;
|
|
|
|
|
|
|
|
|
|
InvalidParamToolTip = new ToolTip();
|
|
|
|
|
InvalidParamToolTip.IsBalloon = true;
|
|
|
|
|
InvalidParamToolTip.ToolTipIcon = ToolTipIcon.Warning;
|
|
|
|
|
InvalidParamToolTip.ToolTipTitle = Messages.INVALID_PARAMETER;
|
|
|
|
|
}
|
|
|
|
|
|
2013-12-30 13:46:56 +01:00
|
|
|
|
internal void SelectName()
|
|
|
|
|
{
|
|
|
|
|
txtName.Select();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
internal void SelectDescription()
|
|
|
|
|
{
|
|
|
|
|
txtDescription.Select();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
internal void SelectIqn()
|
|
|
|
|
{
|
|
|
|
|
txtIQN.Select();
|
|
|
|
|
}
|
|
|
|
|
|
2020-06-18 02:20:29 +02:00
|
|
|
|
public Image Image => Images.StaticImages.edit_16;
|
2013-06-24 13:41:48 +02:00
|
|
|
|
|
|
|
|
|
private void Repopulate()
|
|
|
|
|
{
|
|
|
|
|
ObjectName = Helpers.GetName(xenObjectCopy);
|
|
|
|
|
|
|
|
|
|
VM vm = xenObjectCopy as VM;
|
2017-09-03 04:33:29 +02:00
|
|
|
|
if (vm != null && vm.DescriptionType() == VM.VmDescriptionType.None)
|
2013-06-24 13:41:48 +02:00
|
|
|
|
{
|
|
|
|
|
lblDescription.Visible = false;
|
|
|
|
|
txtDescription.Visible = false;
|
|
|
|
|
lblDescrReadOnly.Visible = false;
|
|
|
|
|
txtDescrReadOnly.Visible = false;
|
|
|
|
|
}
|
2017-09-03 04:33:29 +02:00
|
|
|
|
else if (vm != null && vm.DescriptionType() == VM.VmDescriptionType.ReadOnly)
|
2013-06-24 13:41:48 +02:00
|
|
|
|
{
|
|
|
|
|
lblDescription.Visible = false;
|
|
|
|
|
txtDescription.Visible = false;
|
|
|
|
|
lblDescrReadOnly.Visible = true;
|
|
|
|
|
txtDescrReadOnly.Visible = true;
|
2017-09-03 04:33:29 +02:00
|
|
|
|
txtDescrReadOnly.Text = xenObjectCopy.Description();
|
2013-06-24 13:41:48 +02:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
lblDescription.Visible = true;
|
|
|
|
|
txtDescription.Visible = true;
|
2017-09-03 04:33:29 +02:00
|
|
|
|
txtDescription.Text = xenObjectCopy.Description();
|
2013-06-24 13:41:48 +02:00
|
|
|
|
lblDescrReadOnly.Visible = false;
|
|
|
|
|
txtDescrReadOnly.Visible = false;
|
|
|
|
|
saveDescription = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (xenObjectCopy is Host)
|
|
|
|
|
{
|
|
|
|
|
Host host = xenObjectCopy as Host;
|
2017-09-05 03:15:38 +02:00
|
|
|
|
ServerIQN = host.GetIscsiIqn();
|
2013-06-24 13:41:48 +02:00
|
|
|
|
txtIQN.Visible = true;
|
|
|
|
|
lblIQN.Visible = true;
|
|
|
|
|
labelIqnHint.Visible = true;
|
|
|
|
|
}
|
|
|
|
|
|
2016-10-10 04:29:22 +02:00
|
|
|
|
if (xenObjectCopy is VMSS)
|
|
|
|
|
{
|
|
|
|
|
lblFolder.Visible = labelTags.Visible = folderPanel.Visible = tagsPanel.Visible = false;
|
|
|
|
|
labelTitle.Text = Messages.GENERAL_PAGE_VMSS_SETTINGS;
|
|
|
|
|
}
|
|
|
|
|
|
2013-06-24 13:41:48 +02:00
|
|
|
|
if (xenObjectCopy is VM_appliance)
|
|
|
|
|
{
|
|
|
|
|
lblFolder.Visible = labelTags.Visible = folderPanel.Visible = tagsPanel.Visible = false;
|
|
|
|
|
labelTitle.Text = Messages.GENERAL_PAGE_VM_APPLIANCE_SETTINGS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
AnyTextChanged(null, null);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private List<string> GetTagsFromXenObjectCopy()
|
|
|
|
|
{
|
|
|
|
|
var tags = Tags.GetTags(xenObjectCopy);
|
|
|
|
|
if (tags != null)
|
|
|
|
|
return new List<string>(tags);
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
return new List<string>();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-03-16 02:50:45 +01:00
|
|
|
|
private bool FolderChanged => folderEditor.Path != xenObjectCopy.Path;
|
2013-06-24 13:41:48 +02:00
|
|
|
|
|
|
|
|
|
private bool TagsChanged
|
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
|
|
|
|
List<string> oldTags = GetTagsFromXenObjectCopy();
|
|
|
|
|
List<string> newTags = tagsEditor.Tags;
|
|
|
|
|
oldTags.Sort();
|
|
|
|
|
newTags.Sort();
|
|
|
|
|
return (!Helper.AreEqual(oldTags, newTags));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public bool HasChanged
|
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
|
|
|
|
if (Helpers.GetName(xenObjectCopy) != this.ObjectName ||
|
2017-09-03 04:33:29 +02:00
|
|
|
|
xenObjectCopy.Description() != this.ObjectDescription)
|
2013-06-24 13:41:48 +02:00
|
|
|
|
return true;
|
|
|
|
|
|
|
|
|
|
if (FolderChanged)
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
|
|
if (xenObjectCopy is Host)
|
|
|
|
|
{
|
|
|
|
|
Host host = xenObjectCopy as Host;
|
2017-09-05 03:15:38 +02:00
|
|
|
|
if (host.GetIscsiIqn() != ServerIQN)
|
2013-06-24 13:41:48 +02:00
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (TagsChanged)
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void ShowLocalValidationMessages()
|
|
|
|
|
{
|
|
|
|
|
if (txtName.Text.Trim() == "")
|
|
|
|
|
{
|
|
|
|
|
// Show invalid target host local validation error message.
|
2020-10-22 03:07:02 +02:00
|
|
|
|
HelpersGUI.ShowBalloonMessage(txtName, InvalidParamToolTip, Messages.GENERAL_EDIT_INVALID_NAME);
|
2013-06-24 13:41:48 +02:00
|
|
|
|
}
|
|
|
|
|
else if (xenObjectCopy is Host)
|
|
|
|
|
{
|
|
|
|
|
Host host = xenObjectCopy as Host;
|
|
|
|
|
|
2017-09-05 03:15:38 +02:00
|
|
|
|
if (Helpers.ValidateIscsiIQN(ServerIQN) || ServerIQN == host.GetIscsiIqn())
|
2013-06-24 13:41:48 +02:00
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
// Allow invalid IQN only if previously set from CLI
|
2020-10-22 03:07:02 +02:00
|
|
|
|
HelpersGUI.ShowBalloonMessage(txtIQN, InvalidParamToolTip, Messages.GENERAL_EDIT_INVALID_IQN);
|
2013-06-24 13:41:48 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-08-23 11:34:46 +02:00
|
|
|
|
public void HideLocalValidationMessages()
|
|
|
|
|
{
|
|
|
|
|
if (txtName != null)
|
|
|
|
|
{
|
|
|
|
|
InvalidParamToolTip.Hide(txtName);
|
|
|
|
|
}
|
|
|
|
|
if (txtIQN != null)
|
|
|
|
|
{
|
|
|
|
|
InvalidParamToolTip.Hide(txtIQN);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2013-06-24 13:41:48 +02:00
|
|
|
|
public void Cleanup()
|
|
|
|
|
{
|
|
|
|
|
if (InvalidParamToolTip != null)
|
|
|
|
|
InvalidParamToolTip.Dispose();
|
|
|
|
|
if (tagsEditor != null)
|
|
|
|
|
tagsEditor.Dispose();
|
|
|
|
|
if (folderEditor != null)
|
|
|
|
|
folderEditor.Dispose();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public AsyncAction SaveSettings()
|
|
|
|
|
{
|
|
|
|
|
Program.AssertOnEventThread();
|
|
|
|
|
|
|
|
|
|
if (ObjectName != "" && ObjectName != Helpers.GetName(xenObjectCopy))
|
|
|
|
|
xenObjectCopy.Set("name_label", ObjectName);
|
2017-09-03 04:33:29 +02:00
|
|
|
|
if (ObjectDescription != xenObjectCopy.Description())
|
2013-06-24 13:41:48 +02:00
|
|
|
|
xenObjectCopy.Set("name_description", ObjectDescription);
|
|
|
|
|
|
2017-09-05 03:15:38 +02:00
|
|
|
|
var host = xenObjectCopy as Host;
|
|
|
|
|
if (host != null)
|
|
|
|
|
host.SetIscsiIqn(ServerIQN);
|
2013-06-24 13:41:48 +02:00
|
|
|
|
|
|
|
|
|
if (FolderChanged || TagsChanged)
|
2014-07-21 12:19:04 +02:00
|
|
|
|
return new GeneralEditPageAction(xenObjectOrig, xenObjectCopy, folderEditor.Path, tagsEditor.Tags, true);
|
2013-06-24 13:41:48 +02:00
|
|
|
|
else
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void AnyTextChanged(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
_ValidToSave = txtName.Text.Trim().Length > 0;
|
|
|
|
|
|
|
|
|
|
if (xenObjectCopy is Host)
|
|
|
|
|
{
|
|
|
|
|
Host host = xenObjectCopy as Host;
|
|
|
|
|
|
|
|
|
|
// Allow invalid IQN only if it was set by CLI
|
2017-09-05 03:15:38 +02:00
|
|
|
|
if (ServerIQN != host.GetIscsiIqn())
|
2013-06-24 13:41:48 +02:00
|
|
|
|
{
|
|
|
|
|
_ValidToSave &= Helpers.ValidateIscsiIQN(txtIQN.Text.Trim());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-03-16 02:50:45 +01:00
|
|
|
|
public string SubText => txtName.Text;
|
2013-06-24 13:41:48 +02:00
|
|
|
|
}
|
|
|
|
|
}
|