Add method to add API methods checks to RBAC page

Also minor refactor of wizards that were using the same logic

Signed-off-by: Danilo Del Busso <Danilo.Del.Busso@citrix.com>
This commit is contained in:
Danilo Del Busso 2021-10-28 13:46:00 +01:00 committed by Danilo Del Busso
parent 02d4434572
commit ae1efbd54d
11 changed files with 99 additions and 133 deletions

View File

@ -144,9 +144,9 @@ namespace XenAdmin.Wizards
var selectedHostsConnections = bugToolPageSelectHosts1.SelectedHosts.Select(host => host.Connection).ToList();
if (selectedHostsConnections.Any(ConnectionRequiresRBAC))
if (selectedHostsConnections.Any(Helpers.ConnectionRequiresRbac))
{
ConfigureRbacPage(selectedHostsConnections, SingleHostStatusAction.StaticRBACDependencies, Messages.RBAC_CROSS_POOL_MIGRATE_VM_BLOCKED);
rbacWarningPage.AddApiMethodsCheck(selectedHostsConnections, SingleHostStatusAction.StaticRBACDependencies, Messages.RBAC_CROSS_POOL_MIGRATE_VM_BLOCKED);
AddAfterPage(bugToolPageSelectHosts1, rbacWarningPage);
}
}
@ -157,35 +157,6 @@ namespace XenAdmin.Wizards
}
}
private static bool ConnectionRequiresRBAC(IXenConnection connection)
{
if (connection == null)
throw new NullReferenceException("RBAC check was given a null connection");
if (connection.Session.IsLocalSuperuser)
return false;
return Helpers.GetCoordinator(connection).external_auth_type != Auth.AUTH_TYPE_NONE;
}
private void ConfigureRbacPage(IEnumerable<IXenConnection> connectionsToCheck, RbacMethodList apiMethodsToCheck, string pageMessage)
{
rbacWarningPage.ClearPermissionChecks();
var permissionCheck = new RBACWarningPage.WizardPermissionCheck(pageMessage) { Blocking = true };
permissionCheck.AddApiCheckRange(apiMethodsToCheck);
var connectionsAdded = new List<IXenConnection>();
foreach (var connection in connectionsToCheck)
{
if (!connectionsAdded.Contains(connection))
{
rbacWarningPage.AddPermissionChecks(connection, permissionCheck);
connectionsAdded.Add(connection);
}
}
}
protected override bool RunNextPagePrecheck(XenTabPage senderPage)
{
if (senderPage.GetType() == typeof(GenericSelectHostsPage))

View File

@ -354,9 +354,9 @@ namespace XenAdmin.Wizards.CrossPoolMigrateWizard
m_pageStorage.TargetConnection = TargetConnection;
m_pageNetwork.TargetConnection = TargetConnection;
if (ConnectionRequiresRBAC(xenConnection) || ConnectionRequiresRBAC(TargetConnection))
if (Helpers.ConnectionRequiresRbac(xenConnection) || Helpers.ConnectionRequiresRbac(TargetConnection))
{
ConfigureRbacPage(new List<IXenConnection> { xenConnection, TargetConnection },
m_pageTargetRbac.AddApiMethodsCheck(new List<IXenConnection> { xenConnection, TargetConnection },
VMCrossPoolMigrateAction.StaticRBACDependencies,
Messages.RBAC_CROSS_POOL_MIGRATE_VM_BLOCKED);
AddAfterPage(m_pageDestination, m_pageTargetRbac);
@ -401,9 +401,9 @@ namespace XenAdmin.Wizards.CrossPoolMigrateWizard
{
RemovePagesFrom(1);
AddAfterPage(m_pageCopyMode, m_pageIntraPoolCopy);
if (ConnectionRequiresRBAC(xenConnection))
if (Helpers.ConnectionRequiresRbac(xenConnection))
{
ConfigureRbacPage(new List<IXenConnection> { xenConnection },
m_pageTargetRbac.AddApiMethodsCheck(xenConnection,
VMCopyAction.StaticRBACDependencies,
Messages.RBAC_INTRA_POOL_COPY_VM_BLOCKED);
AddAfterPage(m_pageCopyMode, m_pageTargetRbac);
@ -413,9 +413,9 @@ namespace XenAdmin.Wizards.CrossPoolMigrateWizard
{
RemovePagesFrom(1);
AddAfterPage(m_pageCopyMode, m_pageDestination, m_pageStorage, m_pageFinish);
if (ConnectionRequiresRBAC(xenConnection))
if (Helpers.ConnectionRequiresRbac(xenConnection))
{
ConfigureRbacPage(new List<IXenConnection> { xenConnection },
m_pageTargetRbac.AddApiMethodsCheck(xenConnection,
VMCloneAction.StaticRBACDependencies,
Messages.RBAC_CROSS_POOL_CLONE_VM_BLOCKED);
AddAfterPage(m_pageCopyMode, m_pageTargetRbac);
@ -439,37 +439,6 @@ namespace XenAdmin.Wizards.CrossPoolMigrateWizard
return FormatHelpId(CurrentStepTabPage.HelpID);
}
private bool ConnectionRequiresRBAC(IXenConnection connection)
{
if (connection == null)
throw new NullReferenceException("RBAC check was given a null connection");
if (connection.Session.IsLocalSuperuser)
return false;
return Helpers.GetCoordinator(connection).external_auth_type != Auth.AUTH_TYPE_NONE;
}
private void ConfigureRbacPage(IEnumerable<IXenConnection> connectionsToCheck, RbacMethodList apiMethodsToCheck, string pageMessage)
{
m_pageTargetRbac.ClearPermissionChecks();
var permissionCheck = new RBACWarningPage.WizardPermissionCheck(pageMessage) { Blocking = true };
permissionCheck.AddApiCheckRange(apiMethodsToCheck);
var connectionsAdded = new List<IXenConnection>();
foreach (var connection in connectionsToCheck)
{
if (!connectionsAdded.Contains(connection))
{
m_pageTargetRbac.AddPermissionChecks(connection, permissionCheck);
connectionsAdded.Add(connection);
}
}
}
private IEnumerable<SummaryDetails> GetVMMappingSummary()
{
//Use decorators to build a summary

View File

@ -83,15 +83,13 @@ namespace XenAdmin.Wizards.DRWizards
WizardType = wizardType;
#region RBAC Warning Page Checks
if (!Pool.Connection.Session.IsLocalSuperuser &&
Helpers.GetCoordinator(Pool.Connection).external_auth_type != Auth.AUTH_TYPE_NONE)
if (Helpers.ConnectionRequiresRbac(Pool.Connection))
{
RBACWarningPage.WizardPermissionCheck check = new RBACWarningPage.WizardPermissionCheck(Messages.RBAC_DR_WIZARD_MESSAGE);
check.AddApiCheck("DR_task.async_create");
check.Blocking = true;
RBACWarningPage.AddPermissionChecks(xenConnection, check);
RBACWarningPage.AddApiMethodsCheck(Pool.Connection, "DR_task.async_create", Messages.RBAC_DR_WIZARD_MESSAGE);
AddPage(RBACWarningPage, 0);
}
#endregion
DRFailoverWizardReportPage1.SummaryRetreiver = GetSummaryReport;

View File

@ -145,8 +145,22 @@ namespace XenAdmin.Wizards.ExportWizard
AddAfterPage(m_pageExportSelectVMs, ovfPages);
}
ConfigureRbacPage();
}
if (!Helpers.ConnectionRequiresRbac(xenConnection))
return;
var exportAsXva = m_exportAsXva != null && (bool)m_exportAsXva;
var rbacDependencies = exportAsXva
? ExportVmAction.StaticRBACDependencies
: ApplianceAction.StaticRBACDependencies;
var check = exportAsXva ?
Messages.RBAC_WARNING_EXPORT_WIZARD_XVA :
Messages.RBAC_WARNING_EXPORT_WIZARD_APPLIANCE;
m_pageRbac.AddApiMethodsCheck(xenConnection, rbacDependencies, check);
AddAfterPage(m_pageExportAppliance, m_pageRbac);
}
m_pageExportSelectVMs.ExportAsXva = (bool)m_exportAsXva;
@ -175,23 +189,7 @@ namespace XenAdmin.Wizards.ExportWizard
return base.WizardPaneHelpID();
}
private void ConfigureRbacPage()
{
if (xenConnection == null || xenConnection.Session.IsLocalSuperuser || Helpers.GetCoordinator(xenConnection).external_auth_type == Auth.AUTH_TYPE_NONE)
return;
bool exportAsXva = (bool)m_exportAsXva;
m_pageRbac.ClearPermissionChecks();
var check = exportAsXva
? new RBACWarningPage.WizardPermissionCheck(Messages.RBAC_WARNING_EXPORT_WIZARD_XVA) {Blocking = true}
: new RBACWarningPage.WizardPermissionCheck(Messages.RBAC_WARNING_EXPORT_WIZARD_APPLIANCE) {Blocking = true};
check.AddApiCheckRange(exportAsXva ? ExportVmAction.StaticRBACDependencies : ApplianceAction.StaticRBACDependencies);
m_pageRbac.AddPermissionChecks(xenConnection, check);
AddAfterPage(m_pageExportAppliance, m_pageRbac);
}
protected override IEnumerable<Tuple> GetSummary()
protected override IEnumerable<Tuple> GetSummary()
{
return (bool)m_exportAsXva ? GetSummaryXva() : GetSummaryOvf();
}

View File

@ -38,6 +38,7 @@ using XenAdmin.Network;
using XenAPI;
using System.Threading;
using XenAdmin.Core;
using IXenConnection = XenAdmin.Network.IXenConnection;
namespace XenAdmin.Wizards.GenericPages
@ -70,6 +71,46 @@ namespace XenAdmin.Wizards.GenericPages
public override string PageTitle { get { return Messages.RBAC_WARNING_PAGE_TEXT_TITLE; } }
#region AddApiMethodsCheck and overloads
/// <summary>
/// Add one check of all xapi methods for each of the given connections. Defaults to blocking checks.
/// </summary>
public void AddApiMethodsCheck(IEnumerable<IXenConnection> connectionsToCheck, RbacMethodList apiMethodsToCheck, string warningMessage, bool blocking = true)
{
ClearPermissionChecks();
var permissionCheck = new WizardPermissionCheck(warningMessage) { Blocking = blocking };
permissionCheck.AddApiCheckRange(apiMethodsToCheck);
var connectionsAdded = new List<IXenConnection>();
// only add connections once
foreach (var connection in connectionsToCheck)
{
if (!connectionsAdded.Contains(connection))
{
AddPermissionChecks(connection, permissionCheck);
connectionsAdded.Add(connection);
}
}
}
/// <summary>
/// Add one check of all xapi methods for the given connection. Defaults to blocking checks.
/// </summary>
public void AddApiMethodsCheck(IXenConnection connectionToCheck, RbacMethodList apiMethodsToCheck, string warningMessage, bool blocking = true)
{
AddApiMethodsCheck(new List<IXenConnection> { connectionToCheck }, apiMethodsToCheck, warningMessage, blocking);
}
/// <summary>
/// Add one check of the xapi method for the given connection. Defaults to blocking checks.
/// </summary>
public void AddApiMethodsCheck(IXenConnection connectionToCheck, string apiMethodToCheck, string warningMessage, bool blocking = true)
{
AddApiMethodsCheck(new List<IXenConnection> { connectionToCheck }, new RbacMethodList(apiMethodToCheck), warningMessage, blocking);
}
#endregion
public void AddPermissionChecks(IXenConnection connection, params WizardPermissionCheck[] permissionChecks)
{
if (!checksPerConnectionDict.ContainsKey(connection))
@ -80,7 +121,7 @@ namespace XenAdmin.Wizards.GenericPages
checksPerConnectionDict[connection].AddRange(permissionChecks);
}
public void ClearPermissionChecks()
public void ClearPermissionChecks()
{
DeregisterConnectionEvents();
checksPerConnectionDict.Clear();
@ -229,8 +270,8 @@ namespace XenAdmin.Wizards.GenericPages
foreach (WizardPermissionCheck wizardPermissionCheck in errors)
{
// the string is a format string that needs to take the current role (we use the subject they were authorised under which could be a group or user)
string description = String.Format(wizardPermissionCheck.WarningMessage, roleList[0].FriendlyName());
// the string is a format string that needs to take the current role (we use the subject they were authorized under which could be a group or user)
var description = string.Format(wizardPermissionCheck.WarningMessage, roleList[0].FriendlyName());
AddDetailsRow(description, PermissionCheckResult.Failed);
}

View File

@ -65,15 +65,13 @@ namespace XenAdmin.Wizards
xenTabPageHaFinish = new HAFinishPage();
this.pool = pool;
_rbacNeeded = !pool.Connection.Session.IsLocalSuperuser &&
Helpers.GetCoordinator(pool.Connection).external_auth_type != Auth.AUTH_TYPE_NONE;
_rbacNeeded = Helpers.ConnectionRequiresRbac(pool.Connection);
AddPage(xenTabPageIntro);
if (_rbacNeeded)
{
var check = new RBACWarningPage.WizardPermissionCheck(Messages.RBAC_HA_ENABLE_WARNING) {Blocking = true};
check.AddApiCheckRange(
var methodsToCheck = new RbacMethodList(
"vm.set_ha_restart_priority",
"vm.set_order",
"vm.set_start_delay",
@ -81,10 +79,8 @@ namespace XenAdmin.Wizards
"pool.ha_compute_hypothetical_max_host_failures_to_tolerate",
"pool.set_ha_host_failures_to_tolerate",
"pool.enable_ha",
"sr.assert_can_host_ha_statefile"
);
m_pageRbac.AddPermissionChecks(xenConnection, check);
"sr.assert_can_host_ha_statefile");
m_pageRbac.AddApiMethodsCheck(xenConnection, methodsToCheck, Messages.RBAC_HA_ENABLE_WARNING);
AddPage(m_pageRbac);
}

View File

@ -401,9 +401,9 @@ namespace XenAdmin.Wizards.ImportWizard
private void ConfigureRbacPage(IXenConnection selectedConnection)
{
if (selectedConnection == null || selectedConnection.Session == null || selectedConnection.Session.IsLocalSuperuser ||
Helpers.GetCoordinator(selectedConnection).external_auth_type == Auth.AUTH_TYPE_NONE)
if(!Helpers.ConnectionRequiresRbac(selectedConnection)){
return;
}
m_pageRbac.ClearPermissionChecks();
m_ignoreAffinitySet = false;

View File

@ -68,19 +68,13 @@ namespace XenAdmin.Wizards.NewPolicyWizard
xenTabPageSnapshotFrequency.Connection = pool.Connection;
#region RBAC Warning Page Checks
if (Pool.Connection.Session.IsLocalSuperuser || Helpers.GetCoordinator(Pool.Connection).external_auth_type == Auth.AUTH_TYPE_NONE)
if (Helpers.ConnectionRequiresRbac(Pool.Connection))
{
//do nothing
}
else
{
RBACWarningPage.WizardPermissionCheck check;
check = new RBACWarningPage.WizardPermissionCheck(Messages.RBAC_WARNING_VMSS);
check.AddApiCheck("VMSS.async_create");
check.Blocking = true;
xenTabPageRBAC.AddPermissionChecks(xenConnection, check);
xenTabPageRBAC.AddApiMethodsCheck(xenConnection, "VMSS.async_create", Messages.RBAC_WARNING_VMSS);
AddPage(xenTabPageRBAC, 0);
}
#endregion
AddPages(xenTabPagePolicy, xenTabPageVMsPage);

View File

@ -63,16 +63,9 @@ namespace XenAdmin.Wizards.NewVMApplianceWizard
xenTabPageVMs.Pool = pool;
#region RBAC Warning Page Checks
if (Pool.Connection.Session.IsLocalSuperuser || Helpers.GetCoordinator(Pool.Connection).external_auth_type == Auth.AUTH_TYPE_NONE)
if (Helpers.ConnectionRequiresRbac(Pool.Connection))
{
//do nothing
}
else
{
RBACWarningPage.WizardPermissionCheck check = new RBACWarningPage.WizardPermissionCheck(Messages.RBAC_WARNING_VM_APPLIANCE);
check.AddApiCheck("VM_appliance.async_create");
check.Blocking = true;
xenTabPageRBAC.AddPermissionChecks(xenConnection, check);
xenTabPageRBAC.AddApiMethodsCheck(xenConnection, "VM_appliance.async_create", Messages.RBAC_WARNING_VMSS);
AddPage(xenTabPageRBAC, 0);
}
#endregion

View File

@ -88,13 +88,8 @@ namespace XenAdmin.Wizards.NewVMWizard
page_CloudConfigParameters = new Page_CloudConfigParameters();
#region RBAC Warning Page Checks
if (connection.Session.IsLocalSuperuser || Helpers.GetCoordinator(connection).external_auth_type == Auth.AUTH_TYPE_NONE)
if (Helpers.ConnectionRequiresRbac(connection))
{
//page_RbacWarning.DisableStep = true;
}
else
{
// Check to see if they can even create a VM
var createCheck = new RBACWarningPage.WizardPermissionCheck(Messages.RBAC_WARNING_VM_WIZARD_BLOCK);
foreach (RbacMethod method in CreateVMAction.StaticRBACDependencies)
createCheck.AddApiCheck(method);
@ -103,7 +98,7 @@ namespace XenAdmin.Wizards.NewVMWizard
// Check to see if they can set memory values
var memCheck = new RBACWarningPage.WizardPermissionCheck(Messages.RBAC_WARNING_VM_WIZARD_MEM);
memCheck.AddApiCheck("vm.set_memory_limits");
memCheck.WarningAction = new RBACWarningPage.PermissionCheckActionDelegate(delegate()
memCheck.WarningAction = new RBACWarningPage.PermissionCheckActionDelegate(delegate ()
{
// no point letting them continue
page_5_CpuMem.DisableMemoryControls();
@ -113,7 +108,7 @@ namespace XenAdmin.Wizards.NewVMWizard
// Check to see if they can set the VM's affinity
var affinityCheck = new RBACWarningPage.WizardPermissionCheck(Messages.RBAC_WARNING_VM_WIZARD_AFFINITY);
affinityCheck.ApiCallsToCheck.Add("vm.set_affinity");
affinityCheck.WarningAction = new RBACWarningPage.PermissionCheckActionDelegate(delegate()
affinityCheck.WarningAction = new RBACWarningPage.PermissionCheckActionDelegate(delegate ()
{
page_4_HomeServer.DisableStep = true;
BlockAffinitySelection = true;

View File

@ -1913,5 +1913,16 @@ namespace XenAdmin.Core
{
return connection?.Cache.GPU_groups.Any(g => g.PGPUs.Count > 0 && g.supported_VGPU_types.Count != 0) ?? false;
}
public static bool ConnectionRequiresRbac(IXenConnection connection)
{
if (connection?.Session == null)
throw new NullReferenceException("RBAC check was given a null connection");
if (connection.Session.IsLocalSuperuser)
return false;
return GetCoordinator(connection).external_auth_type != Auth.AUTH_TYPE_NONE;
}
}
}