Refactored and renamed class WizardPermission and the code areas using it. Corrections to RBAC messages. Sorted Messages.resx.

Signed-off-by: Konstantina Chremmou <konstantina.chremmou@citrix.com>
This commit is contained in:
Konstantina Chremmou 2021-11-17 22:11:15 +00:00 committed by Danilo Del Busso
parent 6ed9e28da1
commit e265e86cfa
19 changed files with 404 additions and 369 deletions

View File

@ -37,6 +37,7 @@ using System.Windows.Forms;
using XenAdmin.Actions;
using XenAdmin.Core;
using XenAdmin.Dialogs;
using XenAdmin.Network;
using XenAPI;
@ -380,23 +381,6 @@ namespace XenAdmin.Commands
launcher.Run();
}
/// <summary>
/// Check that the list of RBAC methods can be executed with the session's roles on the given VM
/// </summary>
/// <param name="vm">The VM to check roles on</param>
/// <param name="staticRbacDependencies">List of the methods to check</param>
/// <returns>true if the current roles can be used to execute the given methods</returns>
protected bool CheckRbacPermissions(VM vm, RbacMethodList staticRbacDependencies)
{
if (vm.Connection.Session.IsLocalSuperuser)
return true;
var currentRoles = vm.Connection.Session.Roles;
var validRoles = Role.ValidRoleList(staticRbacDependencies, vm.Connection);
return currentRoles.Any(currentRole => validRoles.Contains(currentRole));
}
#region ICommand Members
/// <summary>

View File

@ -30,7 +30,10 @@
*/
using System.Collections.Generic;
using System.Linq;
using XenAdmin.Actions;
using XenAdmin.Actions.VMActions;
using XenAdmin.Core;
using XenAdmin.Dialogs;
using XenAPI;
@ -54,29 +57,42 @@ namespace XenAdmin.Commands
{
}
private bool CheckRbacPermissions(VM vm, RbacMethodList methodList, string warningMessage)
{
if (vm.Connection.Session.IsLocalSuperuser)
return true;
var currentRoles = vm.Connection.Session.Roles;
var validRoles = Role.ValidRoleList(methodList, vm.Connection);
if (currentRoles.Any(currentRole => validRoles.Contains(currentRole)))
return true;
currentRoles.Sort();
using (var dlg = new ErrorDialog(string.Format(warningMessage, currentRoles[0].FriendlyName())))
dlg.ShowDialog(Parent);
return false;
}
protected override void RunCore(SelectedItemCollection selection)
{
var template = (VM)selection[0].XenObject;
if (CrossPoolCopyTemplateCommand.CanRun(template, null))
{
if (!CheckRbacPermissions(template, VMCrossPoolMigrateAction.StaticRBACDependencies))
{
using (var dlg = new ErrorDialog(Messages.RBAC_CROSS_POOL_MIGRATE_VM_BLOCKED))
dlg.ShowDialog(Parent);
return;
}
new CrossPoolCopyTemplateCommand(MainWindowCommandInterface, selection).Run();
}
else
{
if (!CheckRbacPermissions(template, VMCopyAction.StaticRBACDependencies))
{
using (var dlg = new ErrorDialog(Messages.RBAC_INTRA_POOL_COPY_VM_BLOCKED))
dlg.ShowDialog(Parent);
return;
}
new CopyVMDialog(template).ShowPerXenObject(template, Program.MainWindow);
var rbac = new RbacMethodList();
rbac.AddRange(SrRefreshAction.StaticRBACDependencies);
rbac.AddRange(VMCopyAction.StaticRBACDependencies);
rbac.AddRange(VMCloneAction.StaticRBACDependencies);
if (CheckRbacPermissions(template, rbac, Messages.RBAC_INTRA_POOL_COPY_TEMPLATE_BLOCKED))
new CopyVMDialog(template).ShowPerXenObject(template, Program.MainWindow);
}
}

View File

@ -30,7 +30,10 @@
*/
using System.Collections.Generic;
using System.Linq;
using XenAdmin.Actions;
using XenAdmin.Actions.VMActions;
using XenAdmin.Core;
using XenAdmin.Dialogs;
using XenAPI;
@ -54,29 +57,42 @@ namespace XenAdmin.Commands
{
}
private bool CheckRbacPermissions(VM vm, RbacMethodList methodList, string warningMessage)
{
if (vm.Connection.Session.IsLocalSuperuser)
return true;
var currentRoles = vm.Connection.Session.Roles;
var validRoles = Role.ValidRoleList(methodList, vm.Connection);
if (currentRoles.Any(currentRole => validRoles.Contains(currentRole)))
return true;
currentRoles.Sort();
using (var dlg = new ErrorDialog(string.Format(warningMessage, currentRoles[0].FriendlyName())))
dlg.ShowDialog(Parent);
return false;
}
protected override void RunCore(SelectedItemCollection selection)
{
var vm = (VM)selection[0].XenObject;
if (CrossPoolCopyVMCommand.CanRun(vm, null))
{
if (!CheckRbacPermissions(vm, VMCrossPoolMigrateAction.StaticRBACDependencies))
{
using (var dlg = new ErrorDialog(Messages.RBAC_CROSS_POOL_MIGRATE_VM_BLOCKED))
dlg.ShowDialog(Parent);
return;
}
new CrossPoolCopyVMCommand(MainWindowCommandInterface, selection).Run();
}
else
{
if (!CheckRbacPermissions(vm, VMCopyAction.StaticRBACDependencies))
{
using (var dlg = new ErrorDialog(Messages.RBAC_INTRA_POOL_COPY_VM_BLOCKED))
dlg.ShowDialog(Parent);
return;
}
new CopyVMDialog(vm).ShowPerXenObject(vm, Program.MainWindow);
var rbac = new RbacMethodList();
rbac.AddRange(SrRefreshAction.StaticRBACDependencies);
rbac.AddRange(VMCopyAction.StaticRBACDependencies);
rbac.AddRange(VMCloneAction.StaticRBACDependencies);
if (CheckRbacPermissions(vm, rbac, Messages.RBAC_INTRA_POOL_COPY_VM_BLOCKED))
new CopyVMDialog(vm).ShowPerXenObject(vm, Program.MainWindow);
}
}

View File

@ -146,7 +146,8 @@ namespace XenAdmin.Wizards
if (selectedHostsConnections.Any(Helpers.ConnectionRequiresRbac))
{
rbacWarningPage.AddApiMethodsCheck(selectedHostsConnections, SingleHostStatusAction.StaticRBACDependencies, Messages.RBAC_GET_SYSTEM_STATUS_BLOCKED);
rbacWarningPage.SetPermissionChecks(selectedHostsConnections,
new WizardRbacCheck(Messages.RBAC_GET_SYSTEM_STATUS_BLOCKED, SingleHostStatusAction.StaticRBACDependencies) {Blocking = true});
AddAfterPage(bugToolPageSelectHosts1, rbacWarningPage);
}
}

View File

@ -356,9 +356,16 @@ namespace XenAdmin.Wizards.CrossPoolMigrateWizard
if (Helpers.ConnectionRequiresRbac(xenConnection) || Helpers.ConnectionRequiresRbac(TargetConnection))
{
m_pageTargetRbac.AddApiMethodsCheck(new List<IXenConnection> { xenConnection, TargetConnection },
VMCrossPoolMigrateAction.StaticRBACDependencies,
Messages.RBAC_CROSS_POOL_MIGRATE_VM_BLOCKED);
var message = wizardMode == WizardMode.Copy
? m_vmMappings.Any(IsTemplate)
? Messages.RBAC_CROSS_POOL_COPY_TEMPLATE_BLOCKED
: Messages.RBAC_CROSS_POOL_COPY_VM_BLOCKED
: m_vmMappings.Any(IsTemplate)
? Messages.RBAC_CROSS_POOL_MIGRATE_TEMPLATE_BLOCKED
: Messages.RBAC_CROSS_POOL_MIGRATE_VM_BLOCKED;
m_pageTargetRbac.SetPermissionChecks(new List<IXenConnection> {xenConnection, TargetConnection},
new WizardRbacCheck(message, VMCrossPoolMigrateAction.StaticRBACDependencies) {Blocking = true});
AddAfterPage(m_pageDestination, m_pageTargetRbac);
}
@ -403,9 +410,17 @@ namespace XenAdmin.Wizards.CrossPoolMigrateWizard
AddAfterPage(m_pageCopyMode, m_pageIntraPoolCopy);
if (Helpers.ConnectionRequiresRbac(xenConnection))
{
m_pageTargetRbac.AddApiMethodsCheck(xenConnection,
VMCopyAction.StaticRBACDependencies,
Messages.RBAC_INTRA_POOL_COPY_VM_BLOCKED);
var message = m_vmMappings.Any(IsTemplate)
? Messages.RBAC_INTRA_POOL_COPY_TEMPLATE_BLOCKED
: Messages.RBAC_INTRA_POOL_COPY_VM_BLOCKED;
var rbac = new RbacMethodList();
rbac.AddRange(VMCopyAction.StaticRBACDependencies);
rbac.AddRange(VMCloneAction.StaticRBACDependencies);
rbac.AddRange(SrRefreshAction.StaticRBACDependencies);
m_pageTargetRbac.SetPermissionChecks(xenConnection,
new WizardRbacCheck(message, rbac) {Blocking = true});
AddAfterPage(m_pageCopyMode, m_pageTargetRbac);
}
}
@ -413,13 +428,6 @@ namespace XenAdmin.Wizards.CrossPoolMigrateWizard
{
RemovePagesFrom(1);
AddAfterPage(m_pageCopyMode, m_pageDestination, m_pageStorage, m_pageFinish);
if (Helpers.ConnectionRequiresRbac(xenConnection))
{
m_pageTargetRbac.AddApiMethodsCheck(xenConnection,
VMCloneAction.StaticRBACDependencies,
Messages.RBAC_CROSS_POOL_CLONE_VM_BLOCKED);
AddAfterPage(m_pageCopyMode, m_pageTargetRbac);
}
}
}
if (type != typeof(CrossPoolMigrateFinishPage))

View File

@ -86,7 +86,8 @@ namespace XenAdmin.Wizards.DRWizards
if (Helpers.ConnectionRequiresRbac(Pool.Connection))
{
RBACWarningPage.AddApiMethodsCheck(Pool.Connection, "DR_task.async_create", Messages.RBAC_DR_WIZARD_MESSAGE);
RBACWarningPage.SetPermissionChecks(Pool.Connection,
new WizardRbacCheck(Messages.RBAC_DR_WIZARD_MESSAGE, "DR_task.async_create") {Blocking = true});
AddPage(RBACWarningPage, 0);
}

View File

@ -145,10 +145,8 @@ namespace XenAdmin.Wizards.ExportWizard
AddAfterPage(m_pageExportSelectVMs, ovfPages);
}
if (!Helpers.ConnectionRequiresRbac(xenConnection))
return;
AddRbacPage();
if (Helpers.ConnectionRequiresRbac(xenConnection))
AddRbacPage();
}
m_pageExportSelectVMs.ExportAsXva = (bool)m_exportAsXva;
@ -167,14 +165,13 @@ namespace XenAdmin.Wizards.ExportWizard
private void AddRbacPage()
{
var exportAsXva = m_exportAsXva != null && (bool) m_exportAsXva;
var exportAsXva = m_exportAsXva.HasValue && m_exportAsXva.Value;
var rbacDependencies = exportAsXva
? ExportVmAction.StaticRBACDependencies
: ApplianceAction.StaticRBACDependencies;
var check = exportAsXva ? Messages.RBAC_WARNING_EXPORT_WIZARD_XVA : Messages.RBAC_WARNING_EXPORT_WIZARD_APPLIANCE;
var rbacDependencies = exportAsXva ? ExportVmAction.StaticRBACDependencies : ApplianceAction.StaticRBACDependencies;
var message = exportAsXva ? Messages.RBAC_WARNING_EXPORT_WIZARD_XVA : Messages.RBAC_WARNING_EXPORT_WIZARD_APPLIANCE;
m_pageRbac.AddApiMethodsCheck(xenConnection, rbacDependencies, check);
m_pageRbac.SetPermissionChecks(xenConnection,
new WizardRbacCheck(message, rbacDependencies) {Blocking = true});
AddAfterPage(m_pageExportAppliance, m_pageRbac);
}

View File

@ -47,11 +47,11 @@ namespace XenAdmin.Wizards.GenericPages
{
private static readonly log4net.ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
private readonly Dictionary<IXenConnection, List<WizardPermissionCheck>> checksPerConnectionDict;
private readonly Dictionary<IXenConnection, List<WizardRbacCheck>> checksPerConnectionDict;
private Thread bgThread;
private bool refreshPage = false;
private bool finished = false;
public bool blockProgress = false;
private bool refreshPage;
private bool finished;
private bool blockProgress;
public RBACWarningPage(string description)
: this()
@ -62,71 +62,55 @@ namespace XenAdmin.Wizards.GenericPages
public RBACWarningPage()
{
InitializeComponent();
checksPerConnectionDict = new Dictionary<IXenConnection, List<WizardPermissionCheck>>();
checksPerConnectionDict = new Dictionary<IXenConnection, List<WizardRbacCheck>>();
}
public override string HelpID { get { return "RBAC"; } }
public override string HelpID => "RBAC";
public override string Text { get { return Messages.RBAC_WARNING_PAGE_TEXT_TITLE; } }
public override string PageTitle { get { return Messages.RBAC_WARNING_PAGE_TEXT_TITLE; } }
public override string Text => Messages.RBAC_WARNING_PAGE_TEXT_TITLE;
public override string PageTitle => 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.
/// Clears the existing permission checks and adds the ones specified.
/// </summary>
public void AddApiMethodsCheck(IEnumerable<IXenConnection> connectionsToCheck, RbacMethodList apiMethodsToCheck, string warningMessage, bool blocking = true)
public void SetPermissionChecks(IEnumerable<IXenConnection> connectionsToCheck, params WizardRbacCheck[] checks)
{
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);
}
}
AddPermissionChecks(connection, checks);
}
/// <summary>
/// Add one check of all xapi methods for the given connection. Defaults to blocking checks.
/// Clears the existing permission checks and adds the ones specified.
/// </summary>
public void AddApiMethodsCheck(IXenConnection connectionToCheck, RbacMethodList apiMethodsToCheck, string warningMessage, bool blocking = true)
public void SetPermissionChecks(IXenConnection connectionToCheck, params WizardRbacCheck[] checks)
{
AddApiMethodsCheck(new List<IXenConnection> { connectionToCheck }, apiMethodsToCheck, warningMessage, blocking);
SetPermissionChecks(new List<IXenConnection> {connectionToCheck}, checks);
}
/// <summary>
/// Add one check of the xapi method for the given connection. Defaults to blocking checks.
/// Adds the permission checks specified to the existing ones (without clearing them first).
/// </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)
public void AddPermissionChecks(IXenConnection connection, params WizardRbacCheck[] checks)
{
if (!checksPerConnectionDict.ContainsKey(connection))
{
checksPerConnectionDict.Add(connection, new List<WizardPermissionCheck>());
}
checksPerConnectionDict.Add(connection, new List<WizardRbacCheck>());
checksPerConnectionDict[connection].AddRange(permissionChecks);
checksPerConnectionDict[connection].AddRange(checks);
}
public void ClearPermissionChecks()
private void ClearPermissionChecks()
{
DeregisterConnectionEvents();
checksPerConnectionDict.Clear();
}
#endregion
protected override void PageLoadedCore(PageLoadedDirection direction)
{
RegisterConnectionEvents();
@ -186,23 +170,22 @@ namespace XenAdmin.Wizards.GenericPages
}
}
private PermissionCheckResult RunPermissionChecks(IXenConnection connection,
List<WizardPermissionCheck> permissionChecks, out List<WizardPermissionCheck> errors,
out List<WizardPermissionCheck> warnings)
private PermissionCheckResult RunPermissionChecks(IXenConnection connection, List<WizardRbacCheck> permissionChecks,
out List<WizardRbacCheck> errors, out List<WizardRbacCheck> warnings)
{
PermissionCheckResult checkResult = PermissionCheckResult.OK;
errors = new List<WizardPermissionCheck>();
warnings = new List<WizardPermissionCheck>();
foreach (WizardPermissionCheck wpc in permissionChecks)
errors = new List<WizardRbacCheck>();
warnings = new List<WizardRbacCheck>();
foreach (WizardRbacCheck wpc in permissionChecks)
{
List<Role> rolesAbleToComplete = Role.ValidRoleList(wpc.ApiCallsToCheck, connection);
List<Role> rolesAbleToComplete = wpc.GetValidRoles(connection);
List<Role> subjectRoles = connection.Session.Roles;
if (subjectRoles.Find(rolesAbleToComplete.Contains) != null)
continue;
log.DebugFormat("Failed RBAC check: {0}", wpc.WarningMessage);
if (wpc.Blocking)
{
errors.Add(wpc);
@ -234,8 +217,8 @@ namespace XenAdmin.Wizards.GenericPages
}
else
{
List<WizardPermissionCheck> errors;
List<WizardPermissionCheck> warnings;
List<WizardRbacCheck> errors;
List<WizardRbacCheck> warnings;
checkResult = RunPermissionChecks(connection, connectionChecks.Value, out errors, out warnings);
switch (checkResult)
{
@ -255,7 +238,7 @@ namespace XenAdmin.Wizards.GenericPages
FinishedUpdating();
}
private void AddErrors(IXenConnection connection, List<WizardPermissionCheck> errors)
private void AddErrors(IXenConnection connection, List<WizardRbacCheck> errors)
{
Program.AssertOffEventThread();
@ -268,7 +251,7 @@ namespace XenAdmin.Wizards.GenericPages
List<Role> roleList = connection.Session.Roles;
roleList.Sort();
foreach (WizardPermissionCheck wizardPermissionCheck in errors)
foreach (WizardRbacCheck wizardPermissionCheck in errors)
{
// 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());
@ -295,15 +278,14 @@ namespace XenAdmin.Wizards.GenericPages
});
}
private void AddWarnings(IXenConnection connection, List<WizardPermissionCheck> warnings)
private void AddWarnings(IXenConnection connection, List<WizardRbacCheck> warnings)
{
List<Role> roleList = connection.Session.Roles;
roleList.Sort();
foreach (WizardPermissionCheck wizardPermissionCheck in warnings)
foreach (WizardRbacCheck wizardPermissionCheck in warnings)
{
if (wizardPermissionCheck.WarningAction != null)
wizardPermissionCheck.WarningAction();
wizardPermissionCheck.WarningAction?.Invoke();
// 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());
@ -366,8 +348,10 @@ namespace XenAdmin.Wizards.GenericPages
});
}
internal enum PermissionCheckResult { OK, Warning, Failed }
private abstract class PermissionCheckGridRow : DataGridViewRow
{
protected DataGridViewImageCell iconCell = new DataGridViewImageCell();
@ -420,52 +404,55 @@ namespace XenAdmin.Wizards.GenericPages
descriptionCell.Value = desc;
}
}
}
public delegate void PermissionCheckActionDelegate();
public class WizardPermissionCheck
public class WizardRbacCheck
{
private readonly RbacMethodList _apiMethodsToCheck = new RbacMethodList();
/// <summary>
/// This is the warning message will be displayed. It should be a format string with one
/// placeholder for the user's current role, which will be supplied when the page is displayed.
/// </summary>
public string WarningMessage { get; }
/// <summary>
/// Whether this check should prevent the user from proceeding further on the wizard
/// </summary>
public bool Blocking { get; set; }
public Action WarningAction { get; set; }
public WizardRbacCheck(string warningMessage, RbacMethodList methodList)
{
public RbacMethodList ApiCallsToCheck;
/// <summary>
/// This is the warning message will be displayed. It should be a format string which takes one input, the users current role, which will be supplied when the page is displayed.
/// </summary>
public string WarningMessage;
/// <summary>
/// If true, this warning will be the only one that displays, and will use the cross icon.
/// </summary>
public bool Blocking = false;
public PermissionCheckActionDelegate WarningAction;
public WizardPermissionCheck(string warningMessage)
{
this.WarningMessage = warningMessage;
ApiCallsToCheck = new RbacMethodList();
}
#if DEBUG
System.Diagnostics.Debug.Assert(warningMessage.Contains("{0}"),
"WarningMessage should be a format string with one placeholder for the user's current role");
#endif
WarningMessage = warningMessage;
_apiMethodsToCheck = methodList;
}
public void AddApiCheck(string s)
{
ApiCallsToCheck.Add(s);
}
public WizardRbacCheck(string warningMessage, params string[] strings)
: this(warningMessage, new RbacMethodList(strings))
{
}
public void AddApiCheck(RbacMethod method)
{
ApiCallsToCheck.Add(method);
}
public void AddApiMethods(params string[] strings)
{
_apiMethodsToCheck.AddRange(strings);
}
public void AddApiCheckRange(params string[] strings)
{
ApiCallsToCheck.AddRange(strings);
}
public void AddApiMethods(RbacMethodList methodList)
{
foreach (var method in methodList)
_apiMethodsToCheck.Add(method);
}
public void AddApiCheckRange(RbacMethodList methodList)
{
foreach (var method in methodList)
ApiCallsToCheck.Add(method);
}
public void AddWarningAction(PermissionCheckActionDelegate d)
{
WarningAction = d;
}
public List<Role> GetValidRoles(IXenConnection connection)
{
return Role.ValidRoleList(_apiMethodsToCheck, connection);
}
}
}

View File

@ -80,7 +80,8 @@ namespace XenAdmin.Wizards
"pool.set_ha_host_failures_to_tolerate",
"pool.enable_ha",
"sr.assert_can_host_ha_statefile");
m_pageRbac.AddApiMethodsCheck(xenConnection, methodsToCheck, Messages.RBAC_HA_ENABLE_WARNING);
m_pageRbac.SetPermissionChecks(xenConnection,
new WizardRbacCheck(Messages.RBAC_HA_ENABLE_WARNING, methodsToCheck) {Blocking = true});
AddPage(m_pageRbac);
}

View File

@ -405,7 +405,6 @@ namespace XenAdmin.Wizards.ImportWizard
return;
}
m_pageRbac.ClearPermissionChecks();
m_ignoreAffinitySet = false;
switch (m_typeOfImport)
@ -414,10 +413,10 @@ namespace XenAdmin.Wizards.ImportWizard
case ImportType.Vhd:
{
var check = m_typeOfImport == ImportType.Ovf
? new RBACWarningPage.WizardPermissionCheck(Messages.RBAC_WARNING_IMPORT_WIZARD_APPLIANCE) {Blocking = true}
: new RBACWarningPage.WizardPermissionCheck(Messages.RBAC_WARNING_IMPORT_WIZARD_IMAGE) {Blocking = true};
check.AddApiCheckRange(ApplianceAction.StaticRBACDependencies);
m_pageRbac.AddPermissionChecks(selectedConnection, check);
? new WizardRbacCheck(Messages.RBAC_WARNING_IMPORT_WIZARD_APPLIANCE) {Blocking = true}
: new WizardRbacCheck(Messages.RBAC_WARNING_IMPORT_WIZARD_IMAGE) {Blocking = true};
check.AddApiMethods(ApplianceAction.StaticRBACDependencies);
m_pageRbac.SetPermissionChecks(selectedConnection, check);
AddAfterPage(m_pageHost, m_pageRbac);
}
@ -425,20 +424,20 @@ namespace XenAdmin.Wizards.ImportWizard
case ImportType.Xva:
{
//Check to see if they can import VMs at all
var importCheck = new RBACWarningPage.WizardPermissionCheck(Messages.RBAC_WARNING_IMPORT_WIZARD_XVA) {Blocking = true};
importCheck.ApiCallsToCheck.AddRange(ImportVmAction.ConstantRBACRequirements);
importCheck.ApiCallsToCheck.Add("sr.scan");//CA-337323
var importCheck = new WizardRbacCheck(Messages.RBAC_WARNING_IMPORT_WIZARD_XVA) {Blocking = true};
importCheck.AddApiMethods(ImportVmAction.ConstantRBACRequirements);
importCheck.AddApiMethods("sr.scan");//CA-337323
//Check to see if they can set the VM's affinity
var affinityCheck = new RBACWarningPage.WizardPermissionCheck(Messages.RBAC_WARNING_IMPORT_WIZARD_AFFINITY);
affinityCheck.ApiCallsToCheck.Add("vm.set_affinity");
affinityCheck.WarningAction = delegate
var affinityCheck = new WizardRbacCheck(Messages.RBAC_WARNING_IMPORT_WIZARD_AFFINITY);
affinityCheck.AddApiMethods("vm.set_affinity");
affinityCheck.WarningAction = () =>
{
//We cannot allow them to set the affinity, so we are only going
//to offer them the choice of connection, not specific host
m_ignoreAffinitySet = true;
};
m_pageRbac.AddPermissionChecks(selectedConnection, importCheck, affinityCheck);
m_pageRbac.SetPermissionChecks(selectedConnection, importCheck, affinityCheck);
AddAfterPage(m_pageXvaHost, m_pageRbac);
}
break;

View File

@ -71,7 +71,8 @@ namespace XenAdmin.Wizards.NewPolicyWizard
if (Helpers.ConnectionRequiresRbac(Pool.Connection))
{
xenTabPageRBAC.AddApiMethodsCheck(xenConnection, "VMSS.async_create", Messages.RBAC_WARNING_VMSS);
xenTabPageRBAC.SetPermissionChecks(xenConnection,
new WizardRbacCheck(Messages.RBAC_WARNING_VMSS, "VMSS.async_create") {Blocking = true});
AddPage(xenTabPageRBAC, 0);
}

View File

@ -160,38 +160,33 @@ namespace XenAdmin.Wizards
xenTabPageRbacWarning.Connection = xenConnection;
xenTabPageRbacWarning.ClearPermissionChecks();
var warningMessage = (_srToReattach == null && !disasterRecoveryTask)
var warningMessage = _srToReattach == null && !disasterRecoveryTask
? Messages.RBAC_WARNING_SR_WIZARD_CREATE
: Messages.RBAC_WARNING_SR_WIZARD_ATTACH;
RBACWarningPage.WizardPermissionCheck check =
new RBACWarningPage.WizardPermissionCheck(warningMessage) { Blocking = true };
var check = new WizardRbacCheck(warningMessage) { Blocking = true };
check.AddApiMethods("SR.probe");
check.AddApiCheckRange(new RbacMethodList("SR.probe"));
if (Helpers.KolkataOrGreater(xenConnection) && !Helpers.FeatureForbidden(xenConnection, Host.CorosyncDisabled))
check.AddApiCheckRange(new RbacMethodList("SR.probe_ext"));
check.AddApiMethods("SR.probe_ext");
if (_srToReattach == null)
{
// create
check.AddApiCheckRange(SrCreateAction.StaticRBACDependencies);
check.AddApiMethods(SrCreateAction.StaticRBACDependencies);
}
else if (disasterRecoveryTask && SR.SupportsDatabaseReplication(xenConnection, _srToReattach))
{
// "Attach SR needed for DR" case
check.AddApiCheckRange(DrTaskCreateAction.StaticRBACDependencies);
check.AddApiMethods(DrTaskCreateAction.StaticRBACDependencies);
}
else
{
// reattach
check.AddApiCheckRange(SrReattachAction.StaticRBACDependencies);
check.AddApiMethods(SrReattachAction.StaticRBACDependencies);
}
xenTabPageRbacWarning.AddPermissionChecks(xenConnection, check);
xenTabPageRbacWarning.SetPermissionChecks(xenConnection, check);
}
private bool SetFCDevicesOnLVMoHBAPage(LVMoHBA page)

View File

@ -65,7 +65,8 @@ namespace XenAdmin.Wizards.NewVMApplianceWizard
#region RBAC Warning Page Checks
if (Helpers.ConnectionRequiresRbac(Pool.Connection))
{
xenTabPageRBAC.AddApiMethodsCheck(xenConnection, "VM_appliance.async_create", Messages.RBAC_WARNING_VMSS);
xenTabPageRBAC.SetPermissionChecks(xenConnection,
new WizardRbacCheck(Messages.RBAC_WARNING_VM_APPLIANCE, "VM_appliance.async_create") {Blocking = true});
AddPage(xenTabPageRBAC, 0);
}
#endregion

View File

@ -90,42 +90,40 @@ namespace XenAdmin.Wizards.NewVMWizard
#region RBAC Warning Page Checks
if (Helpers.ConnectionRequiresRbac(connection))
{
var createCheck = new RBACWarningPage.WizardPermissionCheck(Messages.RBAC_WARNING_VM_WIZARD_BLOCK);
foreach (RbacMethod method in CreateVMAction.StaticRBACDependencies)
createCheck.AddApiCheck(method);
createCheck.Blocking = true;
var createCheck = new WizardRbacCheck(Messages.RBAC_WARNING_VM_WIZARD_BLOCK,
CreateVMAction.StaticRBACDependencies) {Blocking = true};
// 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 ()
var memCheck = new WizardRbacCheck(Messages.RBAC_WARNING_VM_WIZARD_MEM,
"vm.set_memory_limits")
{
// no point letting them continue
page_5_CpuMem.DisableMemoryControls();
});
WarningAction = () => page_5_CpuMem.DisableMemoryControls()
};
// 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 ()
var affinityCheck = new WizardRbacCheck(Messages.RBAC_WARNING_VM_WIZARD_AFFINITY, "vm.set_affinity")
{
page_4_HomeServer.DisableStep = true;
BlockAffinitySelection = true;
Program.Invoke(this, RefreshProgress);
});
WarningAction = () =>
{
page_4_HomeServer.DisableStep = true;
BlockAffinitySelection = true;
Program.Invoke(this, RefreshProgress);
}
};
page_RbacWarning.AddPermissionChecks(xenConnection, createCheck, affinityCheck, memCheck);
if (Helpers.GpuCapability(xenConnection))
{
var vgpuCheck = new RBACWarningPage.WizardPermissionCheck(Messages.RBAC_WARNING_VM_WIZARD_GPU);
vgpuCheck.ApiCallsToCheck.Add("vgpu.create");
vgpuCheck.WarningAction = new RBACWarningPage.PermissionCheckActionDelegate(() =>
var vgpuCheck = new WizardRbacCheck(Messages.RBAC_WARNING_VM_WIZARD_GPU, "vgpu.create")
{
pageVgpu.DisableStep = true;
Program.Invoke(this, RefreshProgress);
});
WarningAction = () =>
{
pageVgpu.DisableStep = true;
Program.Invoke(this, RefreshProgress);
}
};
page_RbacWarning.AddPermissionChecks(xenConnection, vgpuCheck);
}

View File

@ -29,23 +29,27 @@
* SUCH DAMAGE.
*/
using XenAdmin.Core;
using XenAPI;
namespace XenAdmin.Actions
{
public class SrRefreshAction : PureAsyncAction
public class SrRefreshAction : AsyncAction
{
public SrRefreshAction(SR Sr, bool suppress_history = false)
: base(Sr.Connection, string.Format(Messages.SR_REFRESH_ACTION_TITLE, Sr.NameWithoutHost()), suppress_history)
{
SR = Sr;
ApiMethodsToRoleCheck.AddRange(StaticRBACDependencies);
}
public static RbacMethodList StaticRBACDependencies => new RbacMethodList("SR.scan");
protected override void Run()
{
Description = string.Format(Messages.SR_REFRESH_ACTION_DESC, SR.NameWithoutHost());
XenAPI.SR.scan(Session, SR.opaque_ref);
SR.scan(Session, SR.opaque_ref);
Description = Messages.COMPLETED;
}
}

View File

@ -51,10 +51,8 @@ namespace XenAdmin.Actions.VMActions
this.Template = vm;
_cloneName = name;
_cloneDescription = description;
ApiMethodsToRoleCheck.AddRange(Role.CommonSessionApiList);
ApiMethodsToRoleCheck.AddRange(Role.CommonTaskApiList);
ApiMethodsToRoleCheck.Add("VM.clone");
ApiMethodsToRoleCheck.Add("VM.set_name_description");
ApiMethodsToRoleCheck.AddRange(StaticRBACDependencies);
}
public static RbacMethodList StaticRBACDependencies

View File

@ -52,16 +52,8 @@ namespace XenAdmin.Actions.VMActions
if (vm.is_a_template)
this.Template = vm;
_namedescription = description;
SetRBACPermissions();
}
private void SetRBACPermissions()
{
ApiMethodsToRoleCheck.AddRange(Role.CommonSessionApiList);
ApiMethodsToRoleCheck.AddRange(Role.CommonTaskApiList);
ApiMethodsToRoleCheck.Add("VM.copy");
ApiMethodsToRoleCheck.Add("VM.set_name_description");
ApiMethodsToRoleCheck.AddRange(StaticRBACDependencies);
}
public static RbacMethodList StaticRBACDependencies

View File

@ -31834,16 +31834,34 @@ namespace XenAdmin {
}
/// <summary>
/// Looks up a localized string similar to Current access levels do not allow cloning of VMs across pools. Log in as a different user with sufficient privileges on the host and try again..
/// Looks up a localized string similar to A {0} user cannot copy templates across pools. Log in as a different user with sufficient privileges on both source and destination servers and try again..
/// </summary>
public static string RBAC_CROSS_POOL_CLONE_VM_BLOCKED {
public static string RBAC_CROSS_POOL_COPY_TEMPLATE_BLOCKED {
get {
return ResourceManager.GetString("RBAC_CROSS_POOL_CLONE_VM_BLOCKED", resourceCulture);
return ResourceManager.GetString("RBAC_CROSS_POOL_COPY_TEMPLATE_BLOCKED", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Current access levels do not allow migration of VMs across pools. Log in as a different user with sufficient privileges on both source and target hosts and try again..
/// Looks up a localized string similar to A {0} user cannot copy VMs across pools. Log in as a different user with sufficient privileges on both source and destination servers and try again..
/// </summary>
public static string RBAC_CROSS_POOL_COPY_VM_BLOCKED {
get {
return ResourceManager.GetString("RBAC_CROSS_POOL_COPY_VM_BLOCKED", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to A {0} user cannot migrate templates across pools. Log in as a different user with sufficient privileges on both source and destination servers and try again..
/// </summary>
public static string RBAC_CROSS_POOL_MIGRATE_TEMPLATE_BLOCKED {
get {
return ResourceManager.GetString("RBAC_CROSS_POOL_MIGRATE_TEMPLATE_BLOCKED", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to A {0} user cannot migrate VMs across pools. Log in as a different user with sufficient privileges on both source and destination servers and try again..
/// </summary>
public static string RBAC_CROSS_POOL_MIGRATE_VM_BLOCKED {
get {
@ -31852,7 +31870,7 @@ namespace XenAdmin {
}
/// <summary>
/// Looks up a localized string similar to User {0} does not have sufficient permissions to run a Disaster Recovery wizard. Login as a different user with sufficient privileges and try again..
/// Looks up a localized string similar to A {0} user does not have sufficient permissions to use Disaster Recovery. Login as a different user with sufficient privileges and try again..
/// </summary>
public static string RBAC_DR_WIZARD_MESSAGE {
get {
@ -31861,7 +31879,7 @@ namespace XenAdmin {
}
/// <summary>
/// Looks up a localized string similar to Current access levels do not allow download of system status report. Log in as a different user with sufficient privileges on the source host and try again..
/// Looks up a localized string similar to A {0} user cannot download system status reports. Log in as a different user with sufficient privileges and try again..
/// </summary>
public static string RBAC_GET_SYSTEM_STATUS_BLOCKED {
get {
@ -31901,7 +31919,16 @@ namespace XenAdmin {
}
/// <summary>
/// Looks up a localized string similar to Current access levels do not allow copying of VMs. Log in as a different user with sufficient privileges on the host and try again..
/// Looks up a localized string similar to A {0} user cannot copy templates. Log in as a different user with sufficient privileges and try again..
/// </summary>
public static string RBAC_INTRA_POOL_COPY_TEMPLATE_BLOCKED {
get {
return ResourceManager.GetString("RBAC_INTRA_POOL_COPY_TEMPLATE_BLOCKED", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to A {0} user cannot copy VMs. Log in as a different user with sufficient privileges and try again..
/// </summary>
public static string RBAC_INTRA_POOL_COPY_VM_BLOCKED {
get {

View File

@ -1596,6 +1596,9 @@ The user you are currently logged into '{1}' with is a member of '{0}'. Proceedi
Do you want to continue?</value>
</data>
<data name="AD_COORDINATOR_UNAVAILABLE_BLURB" xml:space="preserve">
<value>Please wait while {0} establishes your current external authentication configuration.</value>
</data>
<data name="AD_COULD_NOT_RESOLVE_SUFFIX" xml:space="preserve">
<value>Subject could not be resolved in your AD</value>
</data>
@ -1663,9 +1666,6 @@ Do you want to continue?</value>
Do you want to continue?</value>
</data>
<data name="AD_COORDINATOR_UNAVAILABLE_BLURB" xml:space="preserve">
<value>Please wait while {0} establishes your current external authentication configuration.</value>
</data>
<data name="AD_NOT_CONFIGURED_BLURB" xml:space="preserve">
<value>AD is not currently configured for pool '{0}'. To enable AD authentication, click Join Domain.</value>
</data>
@ -1916,12 +1916,12 @@ Note that if RBAC is enabled, only alerts which you have privileges to dismiss w
<data name="ALLOWED_MTU_VALUE" xml:space="preserve">
<value>Allowed MTU value: {0}</value>
</data>
<data name="ALLOWED_UPDATES_DIALOG_MESSAGE" xml:space="preserve">
<value>Would you like {0} to periodically check the internet for new versions of {0} and {1}?</value>
</data>
<data name="ALLOWED_UPDATES_DIALOG_CHECKBOX" xml:space="preserve">
<value>&amp;Show internet proxy settings</value>
</data>
<data name="ALLOWED_UPDATES_DIALOG_MESSAGE" xml:space="preserve">
<value>Would you like {0} to periodically check the internet for new versions of {0} and {1}?</value>
</data>
<data name="ALLOW_TO_CONTINUE" xml:space="preserve">
<value>&amp;Allow to continue</value>
</data>
@ -2664,15 +2664,15 @@ This will cancel compilation of the status report.</value>
<data name="CERTIFICATE_VALIDITY_PERIOD_VALUE" xml:space="preserve">
<value>Valid from {0} to {1}</value>
</data>
<data name="CERTIFICATE_VERIFICATION_KEY" xml:space="preserve">
<value>Certificate Verification</value>
</data>
<data name="CERTIFICATE_VERIFICATION_HOST_DISABLED_IN_POOL" xml:space="preserve">
<value>Enabled on the pool, but disabled on:</value>
</data>
<data name="CERTIFICATE_VERIFICATION_HOST_DISABLED_STANDALONE" xml:space="preserve">
<value>Disabled, but enabled on the pool</value>
</data>
<data name="CERTIFICATE_VERIFICATION_KEY" xml:space="preserve">
<value>Certificate Verification</value>
</data>
<data name="CFU_STATUS_CHECK_DESCRIPTION" xml:space="preserve">
<value>Ability to download updates</value>
</data>
@ -2780,12 +2780,6 @@ Do you want to assign it to the schedule '{2}' instead?</value>
<data name="CHECKING_SECURITY_PROTOCOL_GROUP" xml:space="preserve">
<value>Checking security protocol</value>
</data>
<data name="CHECKING_VSWITCH_CONTROLLER" xml:space="preserve">
<value>vSwitch Controller check</value>
</data>
<data name="CHECKING_VSWITCH_CONTROLLER_GROUP" xml:space="preserve">
<value>Checking vSwitch Controller configuration</value>
</data>
<data name="CHECKING_SERVER_NEEDS_REBOOT" xml:space="preserve">
<value>Checking reboots required</value>
</data>
@ -2807,6 +2801,12 @@ Do you want to assign it to the schedule '{2}' instead?</value>
<data name="CHECKING_UPGRADE_HOTFIX_STATUS" xml:space="preserve">
<value>Checking upgrade hotfix status</value>
</data>
<data name="CHECKING_VSWITCH_CONTROLLER" xml:space="preserve">
<value>vSwitch Controller check</value>
</data>
<data name="CHECKING_VSWITCH_CONTROLLER_GROUP" xml:space="preserve">
<value>Checking vSwitch Controller configuration</value>
</data>
<data name="CHECKING_XENCENTER_VERSION" xml:space="preserve">
<value>Checking {0} version</value>
</data>
@ -3673,6 +3673,9 @@ This action cannot be undone. Are you sure you want to continue?</value>
<data name="CONVERT_TO_TEMPLATE" xml:space="preserve">
<value>Convert VM to Template</value>
</data>
<data name="COORDINATOR" xml:space="preserve">
<value>Coordinator</value>
</data>
<data name="COPY" xml:space="preserve">
<value>Copy</value>
</data>
@ -5646,15 +5649,15 @@ Would you like to eject these ISOs before continuing?</value>
<data name="EULAS" xml:space="preserve">
<value>EULAs</value>
</data>
<data name="EVACUATE_HOST_CLUSER_CREATING" xml:space="preserve">
<value>You cannot nominate a new coordinator while the pool is in the process of creating a cluster.</value>
</data>
<data name="EVACUATE_HOST_DIALOG_TITLE" xml:space="preserve">
<value>Enter Maintenance Mode - {0}</value>
</data>
<data name="EVACUATE_HOST_EJECT_CD_PROMPT" xml:space="preserve">
<value>{0} Eject the CD</value>
</data>
<data name="EVACUATE_HOST_CLUSER_CREATING" xml:space="preserve">
<value>You cannot nominate a new coordinator while the pool is in the process of creating a cluster.</value>
</data>
<data name="EVACUATE_HOST_HA_DISABLING" xml:space="preserve">
<value>You cannot nominate a new coordinator while HA is being disabled on the pool.</value>
</data>
@ -8297,9 +8300,6 @@ This will permanently delete and reinitialize all local storage on the servers.
<data name="MANUAL_CHECK_FOR_UPDATES_UNLICENSED_INFO" xml:space="preserve">
<value>Subscription Advantage required</value>
</data>
<data name="COORDINATOR" xml:space="preserve">
<value>Coordinator</value>
</data>
<data name="MAX" xml:space="preserve">
<value>Max</value>
</data>
@ -8448,12 +8448,12 @@ Are you sure you want to detach this storage repository?</value>
<data name="MESSAGEBOX_ENABLE_TLS_VERIFICATION_BLURB" xml:space="preserve">
<value>Certificate verification is not enabled on '{0}'. Would you like to enable it now?</value>
</data>
<data name="MESSAGEBOX_ENABLE_TLS_VERIFICATION_WARNING" xml:space="preserve">
<value>Before enabling certificate verification ensure that there are no operations running in the pool, otherwise they will be interrupted.</value>
</data>
<data name="MESSAGEBOX_ENABLE_TLS_VERIFICATION_BUTTON" xml:space="preserve">
<value>&amp;Yes, Enable certificate verification</value>
</data>
<data name="MESSAGEBOX_ENABLE_TLS_VERIFICATION_WARNING" xml:space="preserve">
<value>Before enabling certificate verification ensure that there are no operations running in the pool, otherwise they will be interrupted.</value>
</data>
<data name="MESSAGEBOX_ERRORTEXT" xml:space="preserve">
<value>Unable to connect to server '{0}'.
{1}
@ -8516,11 +8516,14 @@ This action is final and unrecoverable.</value>
<data name="MESSAGEBOX_PASSWORD_WRITE_FAILED" xml:space="preserve">
<value>Writing password information failed: {0}</value>
</data>
<data name="MESSAGEBOX_POOL_COORDINATOR_REMOVE" xml:space="preserve">
<value>You cannot remove the coordinator from the pool.</value>
</data>
<data name="MESSAGEBOX_POOL_DELETE" xml:space="preserve">
<value>The pool Coordinator will become a standalone server, are you sure you want to continue?</value>
</data>
<data name="MESSAGEBOX_POOL_COORDINATOR_REMOVE" xml:space="preserve">
<value>You cannot remove the coordinator from the pool.</value>
<data name="MESSAGEBOX_POOL_MEMBERS_EJECT" xml:space="preserve">
<value>You must eject all other pool members from the pool before you can delete the pool.</value>
</data>
<data name="MESSAGEBOX_PROGRAM_UNEXPECTED" xml:space="preserve">
<value>[{0}] There has been an unexpected error. Technical details about this error have been saved to the following file. Please send this to your support representative.
@ -8564,9 +8567,6 @@ Do you want to continue?</value>
Do you want to continue?</value>
</data>
<data name="MESSAGEBOX_POOL_MEMBERS_EJECT" xml:space="preserve">
<value>You must eject all other pool members from the pool before you can delete the pool.</value>
</data>
<data name="MESSAGEBOX_VIF_DELETE" xml:space="preserve">
<value>This will delete the selected network interface permanently. Continue?</value>
</data>
@ -8881,8 +8881,14 @@ You should only proceed if you have verified that these settings are correct.</v
<data name="NEWNETWORK_VNAME" xml:space="preserve">
<value>New Private Network</value>
</data>
<data name="NEW_POOL_CLUSTERING_ENABLED" xml:space="preserve">
<value>Clustering is enabled on this server.</value>
<data name="NEWPOOL_COORDINATOR_CONNECTING" xml:space="preserve">
<value>The coordinator is still connecting</value>
</data>
<data name="NEWPOOL_COORDINATOR_DISCONNECTED" xml:space="preserve">
<value>The coordinator is disconnected</value>
</data>
<data name="NEWPOOL_COORDINATOR_ROLE" xml:space="preserve">
<value>Your current role on the coordinator is not authorized to add hosts to the coordinator's pool</value>
</data>
<data name="NEWPOOL_DIFFERENT_HOMOGENEOUS_UPDATES_FROM_COORDINATOR" xml:space="preserve">
<value>This server has different updates from the coordinator</value>
@ -8926,15 +8932,6 @@ You should only proceed if you have verified that these settings are correct.</v
<data name="NEWPOOL_LINUXPACK" xml:space="preserve">
<value>This server's Linux pack installation state differs from that of the coordinator</value>
</data>
<data name="NEWPOOL_COORDINATOR_CONNECTING" xml:space="preserve">
<value>The coordinator is still connecting</value>
</data>
<data name="NEWPOOL_COORDINATOR_DISCONNECTED" xml:space="preserve">
<value>The coordinator is disconnected</value>
</data>
<data name="NEWPOOL_COORDINATOR_ROLE" xml:space="preserve">
<value>Your current role on the coordinator is not authorized to add hosts to the coordinator's pool</value>
</data>
<data name="NEWPOOL_MAX_NUMBER_HOST_REACHED" xml:space="preserve">
<value>The pool has already reached the maximum number of servers allowed by your license</value>
</data>
@ -9402,12 +9399,6 @@ Review these settings, then click Previous if you need to change anything. Other
<data name="NEWVMWIZARD_NETWORKMEDIAPAGE_TITLE" xml:space="preserve">
<value>Locate the operating system installation media</value>
</data>
<data name="NEWVMWIZARD_STORAGEPAGE_DISK" xml:space="preserve">
<value>Disk '{0}'</value>
</data>
<data name="NEWVMWIZARD_STORAGEPAGE_DISK_DESCRIPTION" xml:space="preserve">
<value>Created by template provisioner</value>
</data>
<data name="NEWVMWIZARD_STORAGEPAGE_DEFAULT_LOCAL" xml:space="preserve">
<value>The default SR '{0}' cannot be seen from the VM's home server.</value>
</data>
@ -9417,9 +9408,21 @@ Review these settings, then click Previous if you need to change anything. Other
<data name="NEWVMWIZARD_STORAGEPAGE_DEFAULT_NOSPACE" xml:space="preserve">
<value>The default SR '{0}' does not have enough free space for the new VM's disks.</value>
</data>
<data name="NEWVMWIZARD_STORAGEPAGE_DISK" xml:space="preserve">
<value>Disk '{0}'</value>
</data>
<data name="NEWVMWIZARD_STORAGEPAGE_DISK_DESCRIPTION" xml:space="preserve">
<value>Created by template provisioner</value>
</data>
<data name="NEWVMWIZARD_STORAGEPAGE_NAME" xml:space="preserve">
<value>Storage</value>
</data>
<data name="NEWVMWIZARD_STORAGEPAGE_NOSTORAGE" xml:space="preserve">
<value>&lt;no suitable storage&gt;</value>
</data>
<data name="NEWVMWIZARD_STORAGEPAGE_SROVERCOMMIT" xml:space="preserve">
<value>The SR '{0}' is overcommitted. There is only {1} of free space and the new VM requires {2}.</value>
</data>
<data name="NEWVMWIZARD_STORAGEPAGE_SUGGESTED_LOCAL" xml:space="preserve">
<value>The SR suggested by the template ('{0}') cannot be seen from the VM's home server.</value>
</data>
@ -9429,12 +9432,6 @@ Review these settings, then click Previous if you need to change anything. Other
<data name="NEWVMWIZARD_STORAGEPAGE_SUGGESTED_NOSPACE" xml:space="preserve">
<value>The SR suggested by the template ('{0}') does not have enough free space for the new VM's disks.</value>
</data>
<data name="NEWVMWIZARD_STORAGEPAGE_NOSTORAGE" xml:space="preserve">
<value>&lt;no suitable storage&gt;</value>
</data>
<data name="NEWVMWIZARD_STORAGEPAGE_SROVERCOMMIT" xml:space="preserve">
<value>The SR '{0}' is overcommitted. There is only {1} of free space and the new VM requires {2}.</value>
</data>
<data name="NEWVMWIZARD_STORAGEPAGE_TITLE" xml:space="preserve">
<value>Configure storage for the new VM</value>
</data>
@ -9456,9 +9453,6 @@ Review these settings, then click Previous if you need to change anything. Other
<data name="NEWVMWIZARD_TEMPLATEPAGE_GOOROOM" xml:space="preserve">
<value>Gooroom</value>
</data>
<data name="NEWVMWIZARD_TEMPLATEPAGE_ROCKY" xml:space="preserve">
<value>Rocky</value>
</data>
<data name="NEWVMWIZARD_TEMPLATEPAGE_LINX" xml:space="preserve">
<value>Linx</value>
</data>
@ -9477,6 +9471,9 @@ Review these settings, then click Previous if you need to change anything. Other
<data name="NEWVMWIZARD_TEMPLATEPAGE_REDHAT" xml:space="preserve">
<value>Red Hat</value>
</data>
<data name="NEWVMWIZARD_TEMPLATEPAGE_ROCKY" xml:space="preserve">
<value>Rocky</value>
</data>
<data name="NEWVMWIZARD_TEMPLATEPAGE_SCILINUX" xml:space="preserve">
<value>Scientific Linux</value>
</data>
@ -9580,6 +9577,9 @@ Do you want to enable AD authentication on your server and join it to the same d
All pool members must use the same authentication method. Do you want to enable AD authentication on these servers and join them to the same domain as the pool?</value>
</data>
<data name="NEW_POOL_CLUSTERING_ENABLED" xml:space="preserve">
<value>Clustering is enabled on this server.</value>
</data>
<data name="NEW_POOL_CPU_MASKING_MESSAGE" xml:space="preserve">
<value>You are attempting to add the server '{0}' to a pool with a coordinator that is using an older CPU.
@ -9716,12 +9716,12 @@ It is strongly recommended that you Cancel and apply the latest version of the p
<data name="NICS_ARE_SRIOV_ENABLED" xml:space="preserve">
<value>SR-IOV is already enabled on all the SR-IOV capable NICs.</value>
</data>
<data name="NIC_HIDDEN" xml:space="preserve">
<value>{0} (Hidden)</value>
</data>
<data name="NIC_BONDED_MEMBER" xml:space="preserve">
<value>{0} (Bonded member)</value>
</data>
<data name="NIC_HIDDEN" xml:space="preserve">
<value>{0} (Hidden)</value>
</data>
<data name="NIC_TAB_TITLE" xml:space="preserve">
<value>Network Interface Cards</value>
</data>
@ -9761,14 +9761,14 @@ It is strongly recommended that you Cancel and apply the latest version of the p
<data name="NOTIFICATIONS_SUBMODE_EVENTS_STATUS" xml:space="preserve">
<value>Events: {0}</value>
</data>
<data name="NOTIFICATIONS_SUBMODE_EVENTS_STATUS_IN_PROGRESS" xml:space="preserve">
<value>{0} in progress</value>
<data name="NOTIFICATIONS_SUBMODE_EVENTS_STATUS_ERROR" xml:space="preserve">
<value>1 error</value>
</data>
<data name="NOTIFICATIONS_SUBMODE_EVENTS_STATUS_ERRORS" xml:space="preserve">
<value>{0} errors</value>
</data>
<data name="NOTIFICATIONS_SUBMODE_EVENTS_STATUS_ERROR" xml:space="preserve">
<value>1 error</value>
<data name="NOTIFICATIONS_SUBMODE_EVENTS_STATUS_IN_PROGRESS" xml:space="preserve">
<value>{0} in progress</value>
</data>
<data name="NOTIFICATIONS_SUBMODE_EVENTS_UNREAD_MANY" xml:space="preserve">
<value>Events ({0} errors)</value>
@ -10555,12 +10555,12 @@ File not found</value>
<data name="PLAN_ACTION_ERROR" xml:space="preserve">
<value> error.</value>
</data>
<data name="PLAN_ACTION_FAILURE_NO_HOSTS_AVAILABLE" xml:space="preserve">
<value>Server '{0}' could not be evacuated because there were no servers available to accommodate all the VMs being migrated from this server. Please reboot the other servers that are pending a reboot following the update installation, and then press Retry to resume the process.</value>
</data>
<data name="PLAN_ACTION_FAILURE_NOT_ENOUGH_MEMORY" xml:space="preserve">
<value>Server '{0}' could not be evacuated because there was not enough free memory on the other servers to migrate all the VMs from this server. Please suspend or shut down some VMs and then press Retry to resume the process.</value>
</data>
<data name="PLAN_ACTION_FAILURE_NO_HOSTS_AVAILABLE" xml:space="preserve">
<value>Server '{0}' could not be evacuated because there were no servers available to accommodate all the VMs being migrated from this server. Please reboot the other servers that are pending a reboot following the update installation, and then press Retry to resume the process.</value>
</data>
<data name="PLAN_ACTION_STATUS_INSTALLING_XENSERVER" xml:space="preserve">
<value>Installing {0} on '{1}'...</value>
</data>
@ -10674,6 +10674,12 @@ Please reconnect the host and try again</value>
<data name="POOL_COLON" xml:space="preserve">
<value>Pool:</value>
</data>
<data name="POOL_COORDINATOR" xml:space="preserve">
<value>Pool coordinator</value>
</data>
<data name="POOL_COORDINATOR_GONE" xml:space="preserve">
<value>Could not find the pool coordinator in {0}'s cache.</value>
</data>
<data name="POOL_DELETE_HA_ENABLED" xml:space="preserve">
<value>Pool '{0}' has HA enabled. You must disable HA before making the pool into a standalone server.</value>
</data>
@ -10740,12 +10746,6 @@ Please reconnect the host and try again</value>
<data name="POOL_LICENSE" xml:space="preserve">
<value>Pool License</value>
</data>
<data name="POOL_COORDINATOR" xml:space="preserve">
<value>Pool coordinator</value>
</data>
<data name="POOL_COORDINATOR_GONE" xml:space="preserve">
<value>Could not find the pool coordinator in {0}'s cache.</value>
</data>
<data name="POOL_NAME_EMPTY" xml:space="preserve">
<value>Pool name cannot be empty</value>
</data>
@ -10799,12 +10799,24 @@ If this value does not correspond to a server within the selected resource pool
<data name="PROBING_HBA_TITLE" xml:space="preserve">
<value>Probing for LUNs on {0}</value>
</data>
<data name="PROBLEM_HEALTH_CHECK_SERVICE_DESCRIPTION" xml:space="preserve">
<value>{0}: Health Check has been removed in {1} {2}.</value>
<data name="PROBLEM_COORDINATOR_PENDING_RESTART_HOST" xml:space="preserve">
<value>{0}: The coordinator needs to be rebooted first</value>
</data>
<data name="PROBLEM_COORDINATOR_PENDING_RESTART_HOST_THIS_UPDATE" xml:space="preserve">
<value>{0}: This update requires the coordinator to be rebooted first</value>
</data>
<data name="PROBLEM_COORDINATOR_PENDING_RESTART_TOOLSTACK" xml:space="preserve">
<value>{0}: Toolstack on coordinator needs to be restarted first</value>
</data>
<data name="PROBLEM_COORDINATOR_PENDING_RESTART_TOOLSTACK_THIS_UPDATE" xml:space="preserve">
<value>{0}: This update requires the toolstack on coordinator to be restarted first</value>
</data>
<data name="PROBLEM_HEALTH_CHECK_HELP" xml:space="preserve">
<value>Disable Health Check</value>
</data>
<data name="PROBLEM_HEALTH_CHECK_SERVICE_DESCRIPTION" xml:space="preserve">
<value>{0}: Health Check has been removed in {1} {2}.</value>
</data>
<data name="PROBLEM_HOSTPROBLEM_TITLE" xml:space="preserve">
<value>Server '{0}'</value>
</data>
@ -10820,15 +10832,6 @@ If this value does not correspond to a server within the selected resource pool
<data name="PROBLEM_LEGACY_PROTOCOL_INFO_SERVER" xml:space="preserve">
<value>If you are upgrading to {0} and above, you will not be able to use security protocols earlier than TLS 1.2 for communication with the server and you may lose permanently access to it.</value>
</data>
<data name="PROBLEM_VSWITCH_CONTROLLER_DESCRIPTION" xml:space="preserve">
<value>{0}: Support for the vSwitch Controller has been removed in {1}.</value>
</data>
<data name="PROBLEM_VSWITCH_CONTROLLER_INFO_ERROR" xml:space="preserve">
<value>Support for the vSwitch Controller has been removed in {0}. You must deconfigure the controller because any features that require it will no longer work. Please click the link below for more information.</value>
</data>
<data name="PROBLEM_VSWITCH_CONTROLLER_INFO_WARNING" xml:space="preserve">
<value>If you are upgrading to {0} and above, you must deconfigure the vSwitch Controller because support for it has been removed in this release and any features that require it will no longer work. Please click the link below for more information.</value>
</data>
<data name="PROBLEM_MAC_ADDRESS_IS_DUPLICATE" xml:space="preserve">
<value>The MAC address entered has already been assigned to the VM:
{1}
@ -10838,18 +10841,6 @@ Are you sure you want to continue?</value>
<data name="PROBLEM_MAC_ADDRESS_IS_DUPLICATE_TITLE" xml:space="preserve">
<value>Duplicate MAC address</value>
</data>
<data name="PROBLEM_COORDINATOR_PENDING_RESTART_HOST" xml:space="preserve">
<value>{0}: The coordinator needs to be rebooted first</value>
</data>
<data name="PROBLEM_COORDINATOR_PENDING_RESTART_HOST_THIS_UPDATE" xml:space="preserve">
<value>{0}: This update requires the coordinator to be rebooted first</value>
</data>
<data name="PROBLEM_COORDINATOR_PENDING_RESTART_TOOLSTACK" xml:space="preserve">
<value>{0}: Toolstack on coordinator needs to be restarted first</value>
</data>
<data name="PROBLEM_COORDINATOR_PENDING_RESTART_TOOLSTACK_THIS_UPDATE" xml:space="preserve">
<value>{0}: This update requires the toolstack on coordinator to be restarted first</value>
</data>
<data name="PROBLEM_POOLPROBLEM_TITLE" xml:space="preserve">
<value>Pool '{0}'</value>
</data>
@ -10876,6 +10867,15 @@ Click Previous if you need to go back and specify a different network location o
<data name="PROBLEM_VMPROBLEM_TITLE" xml:space="preserve">
<value>VM '{0}'</value>
</data>
<data name="PROBLEM_VSWITCH_CONTROLLER_DESCRIPTION" xml:space="preserve">
<value>{0}: Support for the vSwitch Controller has been removed in {1}.</value>
</data>
<data name="PROBLEM_VSWITCH_CONTROLLER_INFO_ERROR" xml:space="preserve">
<value>Support for the vSwitch Controller has been removed in {0}. You must deconfigure the controller because any features that require it will no longer work. Please click the link below for more information.</value>
</data>
<data name="PROBLEM_VSWITCH_CONTROLLER_INFO_WARNING" xml:space="preserve">
<value>If you are upgrading to {0} and above, you must deconfigure the vSwitch Controller because support for it has been removed in this release and any features that require it will no longer work. Please click the link below for more information.</value>
</data>
<data name="PROBLEM_XENCENTER_VERSION_TITLE" xml:space="preserve">
<value>{0} version</value>
</data>
@ -11028,11 +11028,23 @@ To access this console switch to an account with the following role:
{1}</value>
</data>
<data name="RBAC_CROSS_POOL_COPY_TEMPLATE_BLOCKED" xml:space="preserve">
<value>A {0} user cannot copy templates across pools. Log in as a different user with sufficient privileges on both source and destination servers and try again.</value>
</data>
<data name="RBAC_CROSS_POOL_COPY_VM_BLOCKED" xml:space="preserve">
<value>A {0} user cannot copy VMs across pools. Log in as a different user with sufficient privileges on both source and destination servers and try again.</value>
</data>
<data name="RBAC_CROSS_POOL_MIGRATE_TEMPLATE_BLOCKED" xml:space="preserve">
<value>A {0} user cannot migrate templates across pools. Log in as a different user with sufficient privileges on both source and destination servers and try again.</value>
</data>
<data name="RBAC_CROSS_POOL_MIGRATE_VM_BLOCKED" xml:space="preserve">
<value>Current access levels do not allow migration of VMs across pools. Log in as a different user with sufficient privileges on both source and target hosts and try again.</value>
<value>A {0} user cannot migrate VMs across pools. Log in as a different user with sufficient privileges on both source and destination servers and try again.</value>
</data>
<data name="RBAC_DR_WIZARD_MESSAGE" xml:space="preserve">
<value>User {0} does not have sufficient permissions to run a Disaster Recovery wizard. Login as a different user with sufficient privileges and try again.</value>
<value>A {0} user does not have sufficient permissions to use Disaster Recovery. Login as a different user with sufficient privileges and try again.</value>
</data>
<data name="RBAC_GET_SYSTEM_STATUS_BLOCKED" xml:space="preserve">
<value>A {0} user cannot download system status reports. Log in as a different user with sufficient privileges and try again.</value>
</data>
<data name="RBAC_HA_CONFIGURE_WARNING" xml:space="preserve">
<value>Your current role is '{1}'.
@ -11047,6 +11059,12 @@ To configure HA settings, switch to an account with one of the following roles:
<data name="RBAC_HTTP_FAILURE" xml:space="preserve">
<value>A {0} user cannot perform this action.</value>
</data>
<data name="RBAC_INTRA_POOL_COPY_TEMPLATE_BLOCKED" xml:space="preserve">
<value>A {0} user cannot copy templates. Log in as a different user with sufficient privileges and try again.</value>
</data>
<data name="RBAC_INTRA_POOL_COPY_VM_BLOCKED" xml:space="preserve">
<value>A {0} user cannot copy VMs. Log in as a different user with sufficient privileges and try again.</value>
</data>
<data name="RBAC_NO_WIZARD_LIMITS" xml:space="preserve">
<value>Check complete, you have full access to the features in this wizard.</value>
</data>
@ -11530,6 +11548,9 @@ The coordinator must be upgraded first, so if you skip the coordinator, the roll
<data name="ROTATE_POOL_SECRET_HA" xml:space="preserve">
<value>You cannot rotate the pool secret when HA is on.</value>
</data>
<data name="ROTATE_POOL_SECRET_MENU" xml:space="preserve">
<value>Rotate &amp;Pool Secret</value>
</data>
<data name="ROTATE_POOL_SECRET_PENDING_CLUSTER" xml:space="preserve">
<value>You cannot enable clustering while a pool secret rotation is in progress.</value>
</data>
@ -11539,9 +11560,6 @@ The coordinator must be upgraded first, so if you skip the coordinator, the roll
<data name="ROTATE_POOL_SECRET_PENDING_NEW_COORDINATOR" xml:space="preserve">
<value>You cannot nominate a new coordinator while a pool secret rotation is in progress.</value>
</data>
<data name="ROTATE_POOL_SECRET_MENU" xml:space="preserve">
<value>Rotate &amp;Pool Secret</value>
</data>
<data name="ROTATE_POOL_SECRET_RBAC_RESTRICTION" xml:space="preserve">
<value>A {0} user does not have sufficient permissions to rotate the pool secret. Please login using an account with one of the following roles:
@ -11619,12 +11637,12 @@ The coordinator must be upgraded first, so if you skip the coordinator, the roll
<data name="SAVING_SEARCH" xml:space="preserve">
<value>Saving search '{0}'...</value>
</data>
<data name="SAVING_VM_PROPERTIES_ACTION_TITLE" xml:space="preserve">
<value>Saving VM properties</value>
</data>
<data name="SAVING_VM_PROPERTIES_ACTION_DESC" xml:space="preserve">
<value>Saving configuration...</value>
</data>
<data name="SAVING_VM_PROPERTIES_ACTION_TITLE" xml:space="preserve">
<value>Saving VM properties</value>
</data>
<data name="SAVING_WLB_CONFIGURATION" xml:space="preserve">
<value>Saving Workload Balancing configuration.</value>
</data>
@ -11937,16 +11955,6 @@ The coordinator must be upgraded first, so if you skip the coordinator, the roll
<data name="SLACK_LABEL" xml:space="preserve">
<value>Slack:</value>
</data>
<data name="SUPPORTER_ALREADY_CONNECTED" xml:space="preserve">
<value>Server '{0}' is a member of pool '{1}' and is already connected.</value>
</data>
<data name="SUPPORTER_CONNECTION_ERROR" xml:space="preserve">
<value>Server '{0}' is in a pool. To connect to a pool, you must connect to the pool coordinator.
Do you want to connect to the pool coordinator '{1}'?</value>
</data>
<data name="SUPPORTER_TOO_OLD" xml:space="preserve">
<value>This pool contains servers earlier than {0} {1}. Please use an earlier version of {2} to manage this pool.</value>
</data>
<data name="SMALLER_THAN" xml:space="preserve">
<value>smaller than</value>
</data>
@ -12143,13 +12151,13 @@ You may need to reboot your server(s) to enable SR-IOV network.</value>
<data name="SR_DETACHED" xml:space="preserve">
<value>The SR is currently detached.</value>
</data>
<data name="SR_DISKSIZE_EXCEEDS_DISK_MAX_SIZE" xml:space="preserve">
<value>You cannot create a disk greater than {0} on this SR.</value>
</data>
<data name="SR_DISK_SPACE_ALLOCATION" xml:space="preserve">
<value>Initial allocation: {0}
Incremental allocation: {1}</value>
</data>
<data name="SR_DISKSIZE_EXCEEDS_DISK_MAX_SIZE" xml:space="preserve">
<value>You cannot create a disk greater than {0} on this SR.</value>
</data>
<data name="SR_DOES_NOT_NEED_UPGRADE" xml:space="preserve">
<value>This SR does not need to be upgraded.</value>
</data>
@ -12168,12 +12176,12 @@ Incremental allocation: {1}</value>
<data name="SR_IS_LOCAL" xml:space="preserve">
<value>VMs without a home server cannot have disks on local storage</value>
</data>
<data name="SR_PICKER_DISK_TOO_BIG" xml:space="preserve">
<value>Disk size ({0}) exceeds SR size ({1})</value>
</data>
<data name="SR_NOT_ENOUGH_SPACE" xml:space="preserve">
<value>SR '{0}' does not have {1} of free space to import virtual disk {2}.</value>
</data>
<data name="SR_PICKER_DISK_TOO_BIG" xml:space="preserve">
<value>Disk size ({0}) exceeds SR size ({1})</value>
</data>
<data name="SR_PICKER_INSUFFICIENT_SPACE" xml:space="preserve">
<value>{0} required when only {1} available</value>
</data>
@ -12401,6 +12409,16 @@ The upper limit: SR size / {2}</value>
<data name="SUNDAY_SHORT" xml:space="preserve">
<value>Sun</value>
</data>
<data name="SUPPORTER_ALREADY_CONNECTED" xml:space="preserve">
<value>Server '{0}' is a member of pool '{1}' and is already connected.</value>
</data>
<data name="SUPPORTER_CONNECTION_ERROR" xml:space="preserve">
<value>Server '{0}' is in a pool. To connect to a pool, you must connect to the pool coordinator.
Do you want to connect to the pool coordinator '{1}'?</value>
</data>
<data name="SUPPORTER_TOO_OLD" xml:space="preserve">
<value>This pool contains servers earlier than {0} {1}. Please use an earlier version of {2} to manage this pool.</value>
</data>
<data name="SUPP_PACK_DESCRIPTION" xml:space="preserve">
<value>{0} (version {1})</value>
</data>
@ -13120,12 +13138,12 @@ Note that if RBAC is enabled, only updates which you have privileges to dismiss
<data name="UPGRADEWIZARD_WARNING_INCOMPATIBLE_CPUS" xml:space="preserve">
<value>{0}: Check skipped because hosts in pool '{1}' have incompatible CPUs</value>
</data>
<data name="UPGRADE_HOST" xml:space="preserve">
<value>Upgrade host {0}</value>
</data>
<data name="UPGRADE_COORDINATOR" xml:space="preserve">
<value>Upgrade coordinator {0}</value>
</data>
<data name="UPGRADE_HOST" xml:space="preserve">
<value>Upgrade host {0}</value>
</data>
<data name="UPGRADE_PLAN" xml:space="preserve">
<value>Apply Upgrade</value>
</data>
@ -13386,14 +13404,14 @@ To start a {0} trial, click the button below.</value>
<data name="VBD_EDIT_CURRENTLY_IN_USE_BY" xml:space="preserve">
<value>{0} - currently in use by '{1}'</value>
</data>
<data name="VCPU_ONLY_WHEN_HALTED" xml:space="preserve">
<value>The vCPUs can only be changed when the VM is shut down.</value>
</data>
<data name="VCPUS_MORE_THAN_PCPUS" xml:space="preserve">
<value>The number of VCPUs is greater than the number of physical CPUs on the host server. This will significantly reduce VM performance.
To optimize VM performance, you should reduce the number of VCPUs to less than or equal to the number of physical CPUs.</value>
</data>
<data name="VCPU_ONLY_WHEN_HALTED" xml:space="preserve">
<value>The vCPUs can only be changed when the VM is shut down.</value>
</data>
<data name="VDI" xml:space="preserve">
<value>VDI</value>
</data>
@ -14725,13 +14743,4 @@ Any disk in your VM's DVD drive will be ejected when installing {1}.</value>
<data name="YOU_ARE_HERE" xml:space="preserve">
<value>You are here</value>
</data>
<data name="RBAC_CROSS_POOL_CLONE_VM_BLOCKED" xml:space="preserve">
<value>Current access levels do not allow cloning of VMs across pools. Log in as a different user with sufficient privileges on the host and try again.</value>
</data>
<data name="RBAC_INTRA_POOL_COPY_VM_BLOCKED" xml:space="preserve">
<value>Current access levels do not allow copying of VMs. Log in as a different user with sufficient privileges on the host and try again.</value>
</data>
<data name="RBAC_GET_SYSTEM_STATUS_BLOCKED" xml:space="preserve">
<value>Current access levels do not allow download of system status report. Log in as a different user with sufficient privileges on the source host and try again.</value>
</data>
</root>