/* 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.Generic; using System.Text; using XenAdmin; using XenAdmin.Core; using XenAdmin.Network; namespace XenAPI { public partial class Failure : Exception { public const string CANNOT_EVACUATE_HOST = "CANNOT_EVACUATE_HOST"; public const string DEVICE_ALREADY_DETACHED = "DEVICE_ALREADY_DETACHED"; public const string HANDLE_INVALID = "HANDLE_INVALID"; public const string HA_NO_PLAN = "HA_NO_PLAN"; public const string HA_OPERATION_WOULD_BREAK_FAILOVER_PLAN = "HA_OPERATION_WOULD_BREAK_FAILOVER_PLAN"; public const string HOST_IS_SLAVE = "HOST_IS_SLAVE"; public const string HOST_OFFLINE = "HOST_OFFLINE"; public const string HOST_STILL_BOOTING = "HOST_STILL_BOOTING"; public const string NO_HOSTS_AVAILABLE = "NO_HOSTS_AVAILABLE"; public const string PATCH_ALREADY_EXISTS = "PATCH_ALREADY_EXISTS"; public const string PATCH_APPLY_FAILED = "PATCH_APPLY_FAILED"; public const string SESSION_AUTHENTICATION_FAILED = "SESSION_AUTHENTICATION_FAILED"; public const string SESSION_INVALID = "SESSION_INVALID"; public const string SR_HAS_NO_PBDS = "SR_HAS_NO_PBDS"; public const string VM_BAD_POWER_STATE = "VM_BAD_POWER_STATE"; public const string VM_REQUIRES_SR = "VM_REQUIRES_SR"; public const string VM_REQUIRES_NETWORK = "VM_REQUIRES_NETWORK"; public const string VM_MISSING_PV_DRIVERS = "VM_MISSING_PV_DRIVERS"; public const string HOST_NOT_ENOUGH_FREE_MEMORY = "HOST_NOT_ENOUGH_FREE_MEMORY"; public const string SR_BACKEND_FAILURE_72 = "SR_BACKEND_FAILURE_72"; public const string SR_BACKEND_FAILURE_73 = "SR_BACKEND_FAILURE_73"; public const string SR_BACKEND_FAILURE_107 = "SR_BACKEND_FAILURE_107"; public const string SR_BACKEND_FAILURE_140 = "SR_BACKEND_FAILURE_140"; public const string SR_BACKEND_FAILURE_222 = "SR_BACKEND_FAILURE_222"; public const string SR_BACKEND_FAILURE_225 = "SR_BACKEND_FAILURE_225"; public const string SUBJECT_CANNOT_BE_RESOLVED = "SUBJECT_CANNOT_BE_RESOLVED"; public const string OBJECT_NO_LONGER_EXISTS = "OBJECT_NOLONGER_EXISTS"; public const string PERMISSION_DENIED = "PERMISSION_DENIED"; public const string RBAC_PERMISSION_DENIED_FRIENDLY = "RBAC_PERMISSION_DENIED_FRIENDLY"; public const string RBAC_PERMISSION_DENIED = "RBAC_PERMISSION_DENIED"; public const string LICENSE_CHECKOUT_ERROR = "LICENSE_CHECKOUT_ERROR"; public const string VDI_IN_USE = "VDI_IN_USE"; public const string AUTH_ENABLE_FAILED = "AUTH_ENABLE_FAILED"; public const string POOL_AUTH_ENABLE_FAILED_WRONG_CREDENTIALS = "POOL_AUTH_ENABLE_FAILED_WRONG_CREDENTIALS"; public const string HOST_UNKNOWN_TO_MASTER = "HOST_UNKNOWN_TO_MASTER"; private static readonly log4net.ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); /// /// Changes a techy RBAC Failure into a pretty print one that shows the roles that would be required to complete the failed action. /// Requires context such as the the connection and current session to populate these fields. /// /// The Failure to update /// The current connection /// The current session, passed separately because it could be an elevated session, different to the heartbeat public static void ParseRBACFailure(Failure failure, IXenConnection Connection, Session Session) { List authRoles = Role.ValidRoleList(failure.ErrorDescription[1], Connection); failure.ErrorDescription[0] = Failure.RBAC_PERMISSION_DENIED_FRIENDLY; // Current Role(s) failure.ErrorDescription[1] = Session.FriendlyRoleDescription; // Authorized roles failure.ErrorDescription[2] = Role.FriendlyCSVRoleList(authRoles); failure.Setup(); } /// /// This overload is for the special case of us doing an action over multiple connections. Assumes the role requirement is the same across all conections. /// /// The Failure to update /// One session per connection, the ones used to perform the action. Passed separately because they could be elevated sessions, different to the heartbeat public static void ParseRBACFailure(Failure failure, Session[] Sessions) { List authRoles = Role.ValidRoleList(failure.ErrorDescription[1], Sessions[0].Connection); failure.ErrorDescription[0] = Failure.RBAC_PERMISSION_DENIED_FRIENDLY; // Current Role(s) StringBuilder sb = new StringBuilder(); foreach (Session s in Sessions) { sb.Append(string.Format(Messages.ROLE_ON_CONNECTION, s.FriendlyRoleDescription, Helpers.GetName(s.Connection).Ellipsise(50))); sb.Append(", "); } string output = sb.ToString(); // remove trailing comma and space output = output.Substring(0, output.Length - 2); failure.ErrorDescription[1] = output; // Authorized roles failure.ErrorDescription[2] = Role.FriendlyCSVRoleList(authRoles); failure.Setup(); } } }