xenadmin/XenAdmin/Wizards/RollingUpgradeWizard/RollingUpgradeWizardSelectPool.cs
Mihaela Stoica 0e5f1335d4 CP-24498: RPU wizard to block the selection of unlicensed hosts
Also includes some improvements to the Select Pools page of the RPU wizard
- do not show the checkbox if the item is disabled
- show the icon for the pool items, not only for hosts (making this consistent with the similar page in the Update Wizard)

Signed-off-by: Mihaela Stoica <mihaela.stoica@citrix.com>
2017-09-25 13:27:06 +01:00

383 lines
14 KiB
C#

/* Copyright (c) Citrix Systems, Inc.
* 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.
*
* 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;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;
using XenAdmin.Controls;
using XenAdmin.Controls.DataGridViewEx;
using XenAdmin.Core;
using XenAdmin.Network;
using XenAdmin.Properties;
using System.Linq;
using XenAPI;
using XenAdmin.Dialogs;
namespace XenAdmin.Wizards.RollingUpgradeWizard
{
public partial class RollingUpgradeWizardSelectPool : XenTabPage
{
private static readonly log4net.ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
public RollingUpgradeWizardSelectPool()
{
InitializeComponent();
this.dataGridView1.CheckBoxClicked += DataGridRowClicked;
this.Dock = DockStyle.Fill;
}
public override string Text
{
get
{
return Messages.SELECT_POOL;
}
}
public override string PageTitle
{
get
{
return Messages.SELECT_POOL;
}
}
public override string HelpID
{
get { return "Selectpool"; }
}
public override void PageLeave(PageLoadedDirection direction, ref bool cancel)
{
if (direction == PageLoadedDirection.Forward)
{
if (!AllSelectedHostsConnected())
{
dataGridView1.Invalidate();
cancel = true;
return;
}
foreach (var selectedMaster in SelectedMasters)
{
if (!(selectedMaster.Connection.Session.IsLocalSuperuser || selectedMaster.Connection.Session.Roles.Any(role => role.name_label == Role.MR_ROLE_POOL_ADMIN)))
{
using (var dlg = new ThreeButtonDialog(
new ThreeButtonDialog.Details(SystemIcons.Warning, string.Format(Messages.RBAC_UPGRADE_WIZARD_MESSAGE, selectedMaster.Connection.Username,
selectedMaster.Name()), Messages.ROLLING_POOL_UPGRADE)))
{
dlg.ShowDialog(this);
}
DeselectMaster(selectedMaster);
cancel = true;
return;
}
}
}
base.PageLeave(direction, ref cancel);
}
private bool AllSelectedHostsConnected()
{
var disconnectedServerNames = new List<string>();
foreach (UpgradeDataGridViewRow row in dataGridView1.Rows)
{
if (row.Checked == CheckState.Checked && ((row.Tag is Host && !row.HasPool) || row.Tag is Pool))
{
IXenConnection connection = ((IXenObject)row.Tag).Connection;
if (connection == null || !connection.IsConnected)
disconnectedServerNames.Add(((IXenObject)row.Tag).Name());
}
}
if (disconnectedServerNames.Count > 0)
{
using (var dlg = new ThreeButtonDialog(
new ThreeButtonDialog.Details(SystemIcons.Warning,
string.Format(Messages.ROLLING_UPGRADE_DISCONNECTED_SERVER, Helpers.StringifyList(disconnectedServerNames)),
Messages.ROLLING_POOL_UPGRADE)))
{
dlg.ShowDialog(this);
}
return false;
}
return true;
}
private void DeselectMaster(Host master)
{
foreach (UpgradeDataGridViewRow row in dataGridView1.Rows)
{
if (row.Tag is Host && row.Tag == master)
{
row.Checked = CheckState.Unchecked;
}
else if (row.Tag is Pool && ((Pool)(row.Tag)).master.opaque_ref == master.opaque_ref)
{
row.Checked = CheckState.Unchecked;
}
}
}
public IList<Host> SelectedMasters
{
get
{
List<Host> hosts = new List<Host>();
foreach (UpgradeDataGridViewRow row in dataGridView1.Rows)
{
if (row.Tag is Host)
{
if (!row.HasPool && ((int)row.Cells[1].Value) == 1)
hosts.Add((Host)row.Tag);
}
else if (row.Tag is Pool && ((int)row.Cells[1].Value) == 1)
{
Pool pool = ((Pool)(row.Tag));
Host host = pool.Connection.Resolve(pool.master);
hosts.Add(host);
}
}
return hosts;
}
}
public override void PageLoaded(PageLoadedDirection direction)
{
base.PageLoaded(direction);
BuildServerList();
}
public override void SelectDefaultControl()
{
dataGridView1.Select();
}
private void BuildServerList()
{
IList<Host> masters = SelectedMasters;
dataGridView1.Rows.Clear();
List<IXenConnection> xenConnections = ConnectionsManager.XenConnectionsCopy;
xenConnections.Sort();
foreach (IXenConnection xenConnection in xenConnections)
{
Pool pool = Helpers.GetPool(xenConnection);
Pool poolOfOne = Helpers.GetPoolOfOne(xenConnection);
bool restricted = Helpers.FeatureForbidden(xenConnection, Host.RestrictRpu);
bool hasPool = true;
if (pool != null)
{
int index = dataGridView1.Rows.Add(new UpgradeDataGridViewRow(pool));
if ((restricted && !pool.RollingUpgrade()) || pool.IsUpgradeForbidden())
{
((DataGridViewExRow)dataGridView1.Rows[index]).Enabled = false;
if (restricted)
dataGridView1.Rows[index].Cells[NameColumn.Name].ToolTipText = Messages.ROLLING_UPGRADE_UNLICENSED_POOL;
}
else if (masters.Contains(pool.Connection.Resolve(pool.master)))
dataGridView1.CheckBoxChange(index, 1);
}
else
{
hasPool = false;
}
Host[] hosts = xenConnection.Cache.Hosts;
Array.Sort(hosts);
foreach (Host host in hosts)
{
int index = dataGridView1.Rows.Add(new UpgradeDataGridViewRow(host, hasPool));
if (restricted || (poolOfOne != null && poolOfOne.IsUpgradeForbidden()))
{
((DataGridViewExRow)dataGridView1.Rows[index]).Enabled = false;
if (restricted)
dataGridView1.Rows[index].Cells[NameColumn.Name].ToolTipText = Messages.ROLLING_UPGRADE_UNLICENSED_HOST;
}
else if (!hasPool && masters.Contains(host))
dataGridView1.CheckBoxChange(index, 1);
}
}
foreach (DataGridViewRow row in dataGridView1.Rows)
{
dataGridView1.ExpandCollapseClicked(row.Index);
}
}
public override bool EnableNext()
{
bool clearAllButtonEnabled = false;
bool selectAllButtonEnabled = false;
foreach (UpgradeDataGridViewRow row in dataGridView1.Rows)
{
if ((row.Tag is Host && !row.HasPool) || row.Tag is Pool)
{
int val = (int)row.Cells[1].Value;
if (val > 0)
clearAllButtonEnabled = true;
else
selectAllButtonEnabled = true;
}
}
buttonClearAll.Enabled = clearAllButtonEnabled;
buttonSelectAll.Enabled = selectAllButtonEnabled;
return clearAllButtonEnabled;
}
private class UpgradeDataGridView : PoolHostDataGridViewOneCheckbox
{
public UpgradeDataGridView(){}
public UpgradeDataGridView(IContainer container) : base(container){}
protected override void SortColumns()
{
UpgradeDataGridViewRow firstRow = Rows[0] as UpgradeDataGridViewRow;
if (firstRow == null) return;
if (columnToBeSortedIndex == firstRow.NameCellIndex ||
columnToBeSortedIndex == firstRow.DescriptionCellIndex ||
columnToBeSortedIndex == firstRow.VersionCellIndex)
SortAndRebuildTree(new CollapsingPoolHostRowSorter<UpgradeDataGridViewRow>(direction, columnToBeSortedIndex));
}
protected override void OnCellPainting(DataGridViewCellPaintingEventArgs e)
{
base.OnCellPainting(e);
if (e.RowIndex >= 0)
{
var row = (PoolHostDataGridViewOneCheckboxRow)Rows[e.RowIndex];
if (row != null && !row.Enabled && e.ColumnIndex == row.PoolCheckBoxCellIndex)
{
e.PaintBackground(e.ClipBounds, true);
e.Handled = true;
}
}
}
}
public class UpgradeDataGridViewRow : PoolHostDataGridViewOneCheckboxRow
{
private DataGridViewTextBoxCell _description;
private DataGridViewTextBoxCell _version;
public UpgradeDataGridViewRow(Pool pool)
: base(pool)
{
}
public UpgradeDataGridViewRow(Host host, bool hasPool)
: base(host, hasPool)
{
}
public int DescriptionCellIndex
{
get { return Cells.IndexOf(_description); }
}
public int VersionCellIndex
{
get { return Cells.IndexOf(_version); }
}
public string DescriptionText
{
get { return (string) Cells[DescriptionCellIndex].Value; }
}
public string VersionText
{
get { return (string)Cells[VersionCellIndex].Value; }
}
protected override void SetupAdditionalDetailsColumns()
{
_description = new DataGridViewTextBoxCell();
_version = new DataGridViewTextBoxCell();
Cells.Add(_description);
Cells.Add(_version);
}
protected override void UpdateAdditionalDetailsForPool(Pool pool, Host master)
{
_description.Value = pool.Description();
_version.Value = pool.SmallerVersionHost().ProductVersionTextShort();
}
protected override void UpdateAdditionalDetailsForHost( Host host )
{
_description.Value = host.Description();
_version.Value = host.ProductVersionTextShort();
}
}
private void buttonSelectAll_Click(object sender, EventArgs e)
{
foreach (UpgradeDataGridViewRow row in dataGridView1.Rows)
{
var checkrow = row.Cells[1] as DataGridViewCheckBoxCell;
if (row.Enabled)
checkrow.Value = 1;
}
OnPageUpdated();
}
private void buttonClearAll_Click(object sender, EventArgs e)
{
foreach (DataGridViewRow row in dataGridView1.Rows)
{
var checkrow = row.Cells[1] as DataGridViewCheckBoxCell;
checkrow.Value = 0;
}
OnPageUpdated();
}
private void DataGridRowClicked(object sender, EventArgs e)
{
OnPageUpdated();
}
}
}