diff --git a/ocaml/idl/api_errors.ml b/ocaml/idl/api_errors.ml index 1970cf6823..b1cc1d7b4d 100644 --- a/ocaml/idl/api_errors.ml +++ b/ocaml/idl/api_errors.ml @@ -357,7 +357,7 @@ let ha_host_cannot_access_statefile = "HA_HOST_CANNOT_ACCESS_STATEFILE" let ha_failed_to_form_liveset = "HA_FAILED_TO_FORM_LIVESET" -let ha_cannot_bond_management_iface = "HA_CANNOT_BOND_MANAGEMENT_IFACE" +let ha_cannot_change_bond_status_of_mgmt_iface = "HA_CANNOT_CHANGE_BOND_STATUS_OF_MGMT_IFACE" (* CA-16480: prevent configuration errors which nullify xHA goodness *) let ha_constraint_violation_sr_not_shared = "HA_CONSTRAINT_VIOLATION_SR_NOT_SHARED" diff --git a/ocaml/idl/datamodel.ml b/ocaml/idl/datamodel.ml index e5f04103c0..b4de993846 100644 --- a/ocaml/idl/datamodel.ml +++ b/ocaml/idl/datamodel.ml @@ -1032,8 +1032,8 @@ let _ = ~doc:"This operation cannot be performed because it would invalidate VM failover planning such that the system would be unable to guarantee to restart protected VMs after a Host failure." (); - error Api_errors.ha_cannot_bond_management_iface [ ] - ~doc:"This operation cannot be performed because creating a bond with the management interface is not allowed while HA is on. In order to do that, disable HA, create the bond then re-enable HA." + error Api_errors.ha_cannot_change_bond_status_of_mgmt_iface [ ] + ~doc:"This operation cannot be performed because creating or deleting a bond involving the management interface is not allowed while HA is on. In order to do that, disable HA, create or delete the bond then re-enable HA." (); error Api_errors.cannot_evacuate_host ["errors"] diff --git a/ocaml/xapi/xapi_bond.ml b/ocaml/xapi/xapi_bond.ml index 3fd4d49ad1..68bd638989 100644 --- a/ocaml/xapi/xapi_bond.ml +++ b/ocaml/xapi/xapi_bond.ml @@ -306,7 +306,7 @@ let create ~__context ~network ~members ~mAC ~mode ~properties = then raise (Api_errors.Server_error (Api_errors.is_tunnel_access_pif, [Ref.string_of self])); let pool = List.hd (Db.Pool.get_all ~__context) in if Db.Pool.get_ha_enabled ~__context ~self:pool && Db.PIF.get_management ~__context ~self - then raise (Api_errors.Server_error(Api_errors.ha_cannot_bond_management_iface, [])); + then raise (Api_errors.Server_error(Api_errors.ha_cannot_change_bond_status_of_mgmt_iface, [])); ) members; let hosts = List.map (fun self -> Db.PIF.get_host ~__context ~self) members in if List.length (List.setify hosts) <> 1 @@ -424,6 +424,11 @@ let destroy ~__context ~self = let local_vlans = Db.PIF.get_VLAN_slave_of ~__context ~self:master in let local_tunnels = Db.PIF.get_tunnel_transport_PIF_of ~__context ~self:master in + (* CA-86573: forbid the deletion of a bond involving the mgmt interface if HA is on *) + let pool = List.hd (Db.Pool.get_all ~__context) in + if Db.Pool.get_ha_enabled ~__context ~self:pool && Db.PIF.get_management ~__context ~self:master + then raise (Api_errors.Server_error(Api_errors.ha_cannot_change_bond_status_of_mgmt_iface, [])); + (* Copy IP configuration from master to primary member *) copy_configuration ~__context master primary_slave;