Merge "protect host capabilities"
This commit is contained in:
commit
7c61537c84
|
@ -19,6 +19,7 @@
|
||||||
# Copyright (c) 2013-2018 Wind River Systems, Inc.
|
# Copyright (c) 2013-2018 Wind River Systems, Inc.
|
||||||
#
|
#
|
||||||
|
|
||||||
|
import ast
|
||||||
import cgi
|
import cgi
|
||||||
import copy
|
import copy
|
||||||
import json
|
import json
|
||||||
|
@ -1721,6 +1722,62 @@ class HostController(rest.RestController):
|
||||||
def _patch_gen(self, uuid, patch, profile_uuid):
|
def _patch_gen(self, uuid, patch, profile_uuid):
|
||||||
return self._patch(uuid, patch, profile_uuid)
|
return self._patch(uuid, patch, profile_uuid)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _validate_capability_is_not_set(old, new):
|
||||||
|
is_set, _ = new
|
||||||
|
return not is_set
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _validate_capability_is_equal(old, new):
|
||||||
|
return old == new
|
||||||
|
|
||||||
|
def _validate_capabilities(self, old_caps, new_caps):
|
||||||
|
""" Reject updating read-only host capabilities:
|
||||||
|
1. stor_function. This field is set to 'monitor' for hosts that are
|
||||||
|
running ceph monitor process: controller-0, controller-1, storage-0.
|
||||||
|
2. Personality. This field is "virtual": not saved in the database but
|
||||||
|
returned via API and displayed via "system host-show".
|
||||||
|
|
||||||
|
:param old_caps: current host capabilities
|
||||||
|
:type old_caps: dict
|
||||||
|
:param new_caps: updated host capabilies (to be set)
|
||||||
|
:type new_caps: str
|
||||||
|
:raises: wsme.exc.ClientSideError when attempting to change read-only
|
||||||
|
capabilities
|
||||||
|
"""
|
||||||
|
if type(new_caps) == str:
|
||||||
|
try:
|
||||||
|
new_caps = ast.literal_eval(new_caps)
|
||||||
|
except SyntaxError:
|
||||||
|
pass
|
||||||
|
if type(new_caps) != dict:
|
||||||
|
raise wsme.exc.ClientSideError(
|
||||||
|
_("Changing capabilities type is not allowed: "
|
||||||
|
"old_value={}, new_value={}").format(
|
||||||
|
old_caps, new_caps))
|
||||||
|
PROTECTED_CAPABILITIES = [
|
||||||
|
('Personality',
|
||||||
|
self._validate_capability_is_not_set),
|
||||||
|
(constants.IHOST_STOR_FUNCTION,
|
||||||
|
self._validate_capability_is_equal)]
|
||||||
|
for capability, validate in PROTECTED_CAPABILITIES:
|
||||||
|
old_is_set, old_value = (
|
||||||
|
capability in old_caps, old_caps.get(capability))
|
||||||
|
new_is_set, new_value = (
|
||||||
|
capability in new_caps, new_caps.get(capability))
|
||||||
|
if not validate((old_is_set, old_value),
|
||||||
|
(new_is_set, new_value)):
|
||||||
|
if old_is_set:
|
||||||
|
raise wsme.exc.ClientSideError(
|
||||||
|
_("Changing capability not allowed: "
|
||||||
|
"name={}, old_value={}, new_value={}. ").format(
|
||||||
|
capability, old_value, new_value))
|
||||||
|
else:
|
||||||
|
raise wsme.exc.ClientSideError(
|
||||||
|
_("Setting capability not allowed: "
|
||||||
|
"name={}, value={}. ").format(
|
||||||
|
capability, new_value))
|
||||||
|
|
||||||
def _patch(self, uuid, patch, myprofile_uuid):
|
def _patch(self, uuid, patch, myprofile_uuid):
|
||||||
log_start = cutils.timestamped("ihost_patch_start")
|
log_start = cutils.timestamped("ihost_patch_start")
|
||||||
|
|
||||||
|
@ -1745,6 +1802,9 @@ class HostController(rest.RestController):
|
||||||
LOG.exception(e)
|
LOG.exception(e)
|
||||||
raise wsme.exc.ClientSideError(_("Patching Error: %s") % e)
|
raise wsme.exc.ClientSideError(_("Patching Error: %s") % e)
|
||||||
|
|
||||||
|
self._validate_capabilities(
|
||||||
|
ihost_dict['capabilities'], patched_ihost['capabilities'])
|
||||||
|
|
||||||
defaults = objects.host.get_defaults()
|
defaults = objects.host.get_defaults()
|
||||||
|
|
||||||
ihost_dict_orig = dict(ihost_obj.as_dict())
|
ihost_dict_orig = dict(ihost_obj.as_dict())
|
||||||
|
|
|
@ -3096,11 +3096,11 @@ class ConductorManager(service.PeriodicService):
|
||||||
self.dbapi,
|
self.dbapi,
|
||||||
constants.CINDER_BACKEND_CEPH
|
constants.CINDER_BACKEND_CEPH
|
||||||
):
|
):
|
||||||
ihost_capabilities = ihost.capabilities
|
ihost.capabilities.update({
|
||||||
ihost_dict = {'stor_function': constants.STOR_FUNCTION_MONITOR}
|
constants.IHOST_STOR_FUNCTION:
|
||||||
ihost_capabilities.update(ihost_dict)
|
constants.STOR_FUNCTION_MONITOR})
|
||||||
ihost_val = {'capabilities': ihost_capabilities}
|
self.dbapi.ihost_update(ihost_uuid,
|
||||||
self.dbapi.ihost_update(ihost_uuid, ihost_val)
|
{'capabilities': ihost.capabilities})
|
||||||
|
|
||||||
# Check whether a disk has been removed.
|
# Check whether a disk has been removed.
|
||||||
if idisks and len(idisk_dict_array) > 0:
|
if idisks and len(idisk_dict_array) > 0:
|
||||||
|
@ -4240,14 +4240,11 @@ class ConductorManager(service.PeriodicService):
|
||||||
|
|
||||||
if ceph_backend and ceph_backend.task != \
|
if ceph_backend and ceph_backend.task != \
|
||||||
constants.SB_TASK_PROVISION_STORAGE:
|
constants.SB_TASK_PROVISION_STORAGE:
|
||||||
LOG.debug("iplatform monitor check system has ceph backend")
|
ihost.capabilities.update({
|
||||||
ihost_capabilities = ihost.capabilities
|
constants.IHOST_STOR_FUNCTION:
|
||||||
ihost_dict = {
|
constants.STOR_FUNCTION_MONITOR})
|
||||||
'stor_function': constants.STOR_FUNCTION_MONITOR,
|
self.dbapi.ihost_update(ihost_uuid,
|
||||||
}
|
{'capabilities': ihost.capabilities})
|
||||||
ihost_capabilities.update(ihost_dict)
|
|
||||||
ihost_val = {'capabilities': ihost_capabilities}
|
|
||||||
self.dbapi.ihost_update(ihost_uuid, ihost_val)
|
|
||||||
|
|
||||||
storage_lvm = StorageBackendConfig.get_configured_backend_conf(
|
storage_lvm = StorageBackendConfig.get_configured_backend_conf(
|
||||||
self.dbapi,
|
self.dbapi,
|
||||||
|
|
Loading…
Reference in New Issue