Add per-host board management protocol setting in sysinv
Use bm_type field to store board management protocol setting, available bm protocols: redfish ipmi dynamic none (bm is not provisioned) The old service parameter bmc_access_method is removed. Partial-Bug: 1852328 Change-Id: I5097e53f6fc1bfbe23d2a1b765b5bc0e25423c22 Signed-off-by: Bin Qian <bin.qian@windriver.com>
This commit is contained in:
parent
28b3bd8ba2
commit
fde5811001
|
@ -1,2 +1,2 @@
|
|||
SRC_DIR="sysinv"
|
||||
TIS_PATCH_VER=339
|
||||
TIS_PATCH_VER=340
|
||||
|
|
|
@ -1396,14 +1396,24 @@ class HostController(rest.RestController):
|
|||
delta.add(key)
|
||||
ihost_orig[key] = defaults[key]
|
||||
|
||||
bm_list = ['bm_type', 'bm_ip',
|
||||
'bm_username', 'bm_password']
|
||||
bm_list = ['bm_ip', 'bm_username', 'bm_password']
|
||||
for bmi in bm_list:
|
||||
if bmi in ihost_dict:
|
||||
delta.add(bmi)
|
||||
changed_paths.append({'path': '/' + str(bmi),
|
||||
'value': ihost_dict[bmi],
|
||||
'op': 'replace'})
|
||||
if ihost_dict.get('bm_ip') and ihost_dict.get('bm_username'):
|
||||
implict_bm_type = constants.HOST_BM_TYPE_DEFAULT
|
||||
else:
|
||||
implict_bm_type = constants.HOST_BM_TYPE_DEPROVISIONED
|
||||
|
||||
if ihost_dict.get('bm_type') is None:
|
||||
ihost_dict['bm_type'] = implict_bm_type
|
||||
delta.add('bm_type')
|
||||
changed_paths.append({'path': '/bm_type',
|
||||
'value': ihost_dict['bm_type'],
|
||||
'op': 'replace'})
|
||||
|
||||
self._bm_semantic_check_and_update(ihost_orig, ihost_dict,
|
||||
delta, changed_paths,
|
||||
|
@ -3808,15 +3818,24 @@ class HostController(rest.RestController):
|
|||
|
||||
password_exists = password_exists and patch_bm_password is not None
|
||||
|
||||
bm_type_orig = ohost.get('bm_type') or ""
|
||||
bm_type_patch = phost.get('bm_type') or ""
|
||||
if bm_type_patch.lower() == 'none':
|
||||
bm_type_patch = ''
|
||||
if (not bm_type_patch) and (bm_type_orig != bm_type_patch):
|
||||
LOG.info("bm_type None from %s to %s." %
|
||||
(ohost['bm_type'], phost['bm_type']))
|
||||
bm_type_patch = phost.get('bm_type')
|
||||
# Semantic Check: Validate BM type against supported list
|
||||
if bm_type_patch not in constants.HOST_BM_VALID_TYPE_LIST:
|
||||
raise wsme.exc.ClientSideError(
|
||||
_("%s: Rejected: '%s' is not a supported board management "
|
||||
"type. Must be one of %s" %
|
||||
(phost['hostname'],
|
||||
phost['bm_type'],
|
||||
constants.HOST_BM_VALID_TYPE_LIST)))
|
||||
|
||||
bm_type_changed_to_none = True
|
||||
bm_type_orig = ohost.get('bm_type')
|
||||
if bm_type_orig != bm_type_patch:
|
||||
if bm_type_patch == constants.HOST_BM_TYPE_DEPROVISIONED:
|
||||
LOG.info("BM is to be deprovisioned")
|
||||
bm_type_changed_to_none = True
|
||||
else:
|
||||
LOG.info("BM type %s is changed to %s" %
|
||||
(bm_type_orig, bm_type_patch))
|
||||
|
||||
if 'bm_ip' in delta:
|
||||
obm_ip = ohost['bm_ip'] or ""
|
||||
|
@ -3831,50 +3850,19 @@ class HostController(rest.RestController):
|
|||
"controller IP Address is not user-modifiable." %
|
||||
(constants.REGION_PRIMARY, phost['hostname'])))
|
||||
|
||||
if (phost['bm_ip'] or phost['bm_type'] or phost['bm_username']):
|
||||
if (not phost['bm_type'] or
|
||||
(phost['bm_type'] and phost['bm_type'].lower() ==
|
||||
constants.BM_TYPE_NONE)) and not bm_type_changed_to_none:
|
||||
raise wsme.exc.ClientSideError(
|
||||
_("%s: Rejected: Board Management controller Type "
|
||||
"is not provisioned. Provisionable values: 'bmc'."
|
||||
% phost['hostname']))
|
||||
if phost['bm_ip'] or phost['bm_type'] or phost['bm_username']:
|
||||
if bm_type_patch == constants.HOST_BM_TYPE_DEPROVISIONED:
|
||||
if not bm_type_changed_to_none:
|
||||
raise wsme.exc.ClientSideError(
|
||||
_("%s: Rejected: Board Management controller Type "
|
||||
"is not provisioned. Provisionable values: '%s'." %
|
||||
(phost['hostname'],
|
||||
constants.HOST_BM_VALID_PROVISIONED_TYPE_LIST)))
|
||||
elif not phost['bm_username']:
|
||||
raise wsme.exc.ClientSideError(
|
||||
_("%s: Rejected: Board Management controller username "
|
||||
"is not configured." % phost['hostname']))
|
||||
|
||||
# Semantic Check: Validate BM type against supported list
|
||||
# ilo, quanta is kept for backwards compatability only
|
||||
valid_bm_type_list = [None, 'None', constants.BM_TYPE_NONE,
|
||||
constants.BM_TYPE_GENERIC,
|
||||
'ilo', 'ilo3', 'ilo4', 'quanta']
|
||||
|
||||
if not phost['bm_type']:
|
||||
phost['bm_type'] = None
|
||||
|
||||
if not (phost['bm_type'] in valid_bm_type_list):
|
||||
raise wsme.exc.ClientSideError(
|
||||
_("%s: Rejected: '%s' is not a supported board management "
|
||||
"type. Must be one of %s" %
|
||||
(phost['hostname'],
|
||||
phost['bm_type'],
|
||||
valid_bm_type_list)))
|
||||
|
||||
bm_type_str = phost['bm_type']
|
||||
if (phost['bm_type'] and
|
||||
bm_type_str.lower() != constants.BM_TYPE_NONE):
|
||||
LOG.info("Updating bm_type from %s to %s" %
|
||||
(phost['bm_type'], constants.BM_TYPE_GENERIC))
|
||||
phost['bm_type'] = constants.BM_TYPE_GENERIC
|
||||
if hostupdate:
|
||||
hostupdate.ihost_val_update(
|
||||
{'bm_type': constants.BM_TYPE_GENERIC})
|
||||
else:
|
||||
phost['bm_type'] = None
|
||||
if hostupdate:
|
||||
hostupdate.ihost_val_update({'bm_type': None})
|
||||
|
||||
if (phost['bm_type'] and phost['bm_ip'] and
|
||||
(ohost['bm_ip'] != phost['bm_ip'])):
|
||||
if not cutils.is_valid_ip(phost['bm_ip']):
|
||||
|
|
|
@ -154,8 +154,6 @@ FORCE_LOCKING = "Force Locking"
|
|||
OPERATIONAL_ENABLED = 'enabled'
|
||||
OPERATIONAL_DISABLED = 'disabled'
|
||||
|
||||
BM_TYPE_GENERIC = 'bmc'
|
||||
BM_TYPE_NONE = 'none'
|
||||
PROVISIONED = 'provisioned'
|
||||
PROVISIONING = 'provisioning'
|
||||
UNPROVISIONED = 'unprovisioned'
|
||||
|
@ -956,7 +954,6 @@ SERVICE_PARAM_PLAT_MTCE_HBS_FAILURE_THRESHOLD = 'heartbeat_failure_threshold'
|
|||
SERVICE_PARAM_PLAT_MTCE_HBS_DEGRADE_THRESHOLD = 'heartbeat_degrade_threshold'
|
||||
SERVICE_PARAM_PLAT_MTCE_MNFA_THRESHOLD = 'mnfa_threshold'
|
||||
SERVICE_PARAM_PLAT_MTCE_MNFA_TIMEOUT = 'mnfa_timeout'
|
||||
SERVICE_PARAM_PLAT_MTCE_BMC_ACCESS_METHOD = 'bmc_access_method'
|
||||
|
||||
SERVICE_PARAM_PLAT_MTCE_WORKER_BOOT_TIMEOUT_DEFAULT = 720
|
||||
SERVICE_PARAM_PLAT_MTCE_CONTROLLER_BOOT_TIMEOUT_DEFAULT = 1200
|
||||
|
@ -966,7 +963,6 @@ SERVICE_PARAM_PLAT_MTCE_HBS_FAILURE_THRESHOLD_DEFAULT = 10
|
|||
SERVICE_PARAM_PLAT_MTCE_HBS_DEGRADE_THRESHOLD_DEFAULT = 6
|
||||
SERVICE_PARAM_PLAT_MTCE_MNFA_THRESHOLD_DEFAULT = 2
|
||||
SERVICE_PARAM_PLAT_MTCE_MNFA_TIMEOUT_DEFAULT = 0
|
||||
SERVICE_PARAM_PLAT_MTCE_BMC_ACCESS_METHOD_DEFAULT = 'learn'
|
||||
|
||||
# default time to live seconds
|
||||
PM_TTL_DEFAULT = 86400
|
||||
|
@ -1540,3 +1536,18 @@ MELLANOX_DRIVERS = [DRIVER_MLX_CX3,
|
|||
|
||||
# Traffic control
|
||||
TRAFFIC_CONTROL_SCRIPT = '/usr/local/bin/tc_setup.sh'
|
||||
|
||||
# Host Board Management Constants
|
||||
HOST_BM_TYPE_DEPROVISIONED = "none"
|
||||
HOST_BM_TYPE_IPMI = "ipmi"
|
||||
HOST_BM_TYPE_REDFISH = "redfish"
|
||||
HOST_BM_TYPE_DYNAMIC = "dynamic"
|
||||
HOST_BM_TYPE_DEFAULT = HOST_BM_TYPE_DYNAMIC
|
||||
|
||||
HOST_BM_VALID_TYPE_LIST = [HOST_BM_TYPE_DEPROVISIONED,
|
||||
HOST_BM_TYPE_DYNAMIC,
|
||||
HOST_BM_TYPE_IPMI,
|
||||
HOST_BM_TYPE_REDFISH]
|
||||
HOST_BM_VALID_PROVISIONED_TYPE_LIST = [HOST_BM_TYPE_DYNAMIC,
|
||||
HOST_BM_TYPE_IPMI,
|
||||
HOST_BM_TYPE_REDFISH]
|
||||
|
|
|
@ -228,25 +228,6 @@ def _validate_mnfa_timeout(name, value):
|
|||
SERVICE_PARAM_PLAT_MTCE_MNFA_TIMEOUT_MAX)
|
||||
|
||||
|
||||
def _validate_bmc_access_method(name, value):
|
||||
error = False
|
||||
try:
|
||||
if str(value) != SERVICE_PARAM_PLAT_MTCE_BMC_ACCESS_METHOD_LEARN and \
|
||||
str(value) != SERVICE_PARAM_PLAT_MTCE_BMC_ACCESS_METHOD_IPMI and \
|
||||
str(value) != SERVICE_PARAM_PLAT_MTCE_BMC_ACCESS_METHOD_REDFISH:
|
||||
error = True
|
||||
|
||||
except ValueError:
|
||||
error = True
|
||||
|
||||
if error is True:
|
||||
raise wsme.exc.ClientSideError(_(
|
||||
"Method must be one of '%s', '%s' or '%s'" %
|
||||
(SERVICE_PARAM_PLAT_MTCE_BMC_ACCESS_METHOD_LEARN,
|
||||
SERVICE_PARAM_PLAT_MTCE_BMC_ACCESS_METHOD_IPMI,
|
||||
SERVICE_PARAM_PLAT_MTCE_BMC_ACCESS_METHOD_REDFISH)))
|
||||
|
||||
|
||||
def _validate_ipv4(name, value):
|
||||
"""Check if router_id value is valid"""
|
||||
if not netaddr.valid_ipv4(value):
|
||||
|
@ -369,7 +350,6 @@ PLATFORM_MTCE_PARAMETER_MANDATORY = [
|
|||
constants.SERVICE_PARAM_PLAT_MTCE_HBS_DEGRADE_THRESHOLD,
|
||||
constants.SERVICE_PARAM_PLAT_MTCE_MNFA_THRESHOLD,
|
||||
constants.SERVICE_PARAM_PLAT_MTCE_MNFA_TIMEOUT,
|
||||
constants.SERVICE_PARAM_PLAT_MTCE_BMC_ACCESS_METHOD,
|
||||
]
|
||||
|
||||
PLATFORM_SYSINV_PARAMETER_PROTECTED = ['firewall_rules_id']
|
||||
|
@ -392,9 +372,6 @@ SERVICE_PARAM_PLAT_MTCE_MNFA_THRESHOLD_MIN = 2
|
|||
SERVICE_PARAM_PLAT_MTCE_MNFA_THRESHOLD_MAX = 100
|
||||
SERVICE_PARAM_PLAT_MTCE_MNFA_TIMEOUT_MIN = 100
|
||||
SERVICE_PARAM_PLAT_MTCE_MNFA_TIMEOUT_MAX = 86400
|
||||
SERVICE_PARAM_PLAT_MTCE_BMC_ACCESS_METHOD_LEARN = 'learn'
|
||||
SERVICE_PARAM_PLAT_MTCE_BMC_ACCESS_METHOD_REDFISH = 'redfish'
|
||||
SERVICE_PARAM_PLAT_MTCE_BMC_ACCESS_METHOD_IPMI = 'ipmi'
|
||||
|
||||
|
||||
PLATFORM_MTCE_PARAMETER_VALIDATOR = {
|
||||
|
@ -414,8 +391,6 @@ PLATFORM_MTCE_PARAMETER_VALIDATOR = {
|
|||
_validate_mnfa_threshold,
|
||||
constants.SERVICE_PARAM_PLAT_MTCE_MNFA_TIMEOUT:
|
||||
_validate_mnfa_timeout,
|
||||
constants.SERVICE_PARAM_PLAT_MTCE_BMC_ACCESS_METHOD:
|
||||
_validate_bmc_access_method,
|
||||
}
|
||||
|
||||
PLATFORM_MTCE_PARAMETER_RESOURCE = {
|
||||
|
@ -427,7 +402,6 @@ PLATFORM_MTCE_PARAMETER_RESOURCE = {
|
|||
constants.SERVICE_PARAM_PLAT_MTCE_HBS_DEGRADE_THRESHOLD: 'platform::mtce::params::heartbeat_degrade_threshold',
|
||||
constants.SERVICE_PARAM_PLAT_MTCE_MNFA_THRESHOLD: 'platform::mtce::params::mnfa_threshold',
|
||||
constants.SERVICE_PARAM_PLAT_MTCE_MNFA_TIMEOUT: 'platform::mtce::params::mnfa_timeout',
|
||||
constants.SERVICE_PARAM_PLAT_MTCE_BMC_ACCESS_METHOD: 'platform::mtce::params::bmc_access_method',
|
||||
}
|
||||
|
||||
RADOSGW_CONFIG_PARAMETER_MANDATORY = [
|
||||
|
|
|
@ -487,11 +487,6 @@ class ConductorManager(service.PeriodicService):
|
|||
'name': constants.SERVICE_PARAM_PLAT_MTCE_MNFA_TIMEOUT,
|
||||
'value': constants.SERVICE_PARAM_PLAT_MTCE_MNFA_TIMEOUT_DEFAULT,
|
||||
},
|
||||
{'service': constants.SERVICE_TYPE_PLATFORM,
|
||||
'section': constants.SERVICE_PARAM_SECTION_PLATFORM_MAINTENANCE,
|
||||
'name': constants.SERVICE_PARAM_PLAT_MTCE_BMC_ACCESS_METHOD,
|
||||
'value': constants.SERVICE_PARAM_PLAT_MTCE_BMC_ACCESS_METHOD_DEFAULT,
|
||||
},
|
||||
{'service': constants.SERVICE_TYPE_RADOSGW,
|
||||
'section': constants.SERVICE_PARAM_SECTION_RADOSGW_CONFIG,
|
||||
'name': constants.SERVICE_PARAM_NAME_RADOSGW_SERVICE_ENABLED,
|
||||
|
|
|
@ -39,6 +39,7 @@ class FakeConductorAPI(object):
|
|||
self.store_default_config = mock.MagicMock()
|
||||
self.kube_upgrade_control_plane = mock.MagicMock()
|
||||
self.kube_upgrade_kubelet = mock.MagicMock()
|
||||
self.create_barbican_secret = mock.MagicMock()
|
||||
|
||||
def create_ihost(self, context, values):
|
||||
# Create the host in the DB as the code under test expects this
|
||||
|
@ -1305,6 +1306,45 @@ class TestPatch(TestHost):
|
|||
self.assertEqual(constants.AVAILABILITY_ONLINE, ihost.availability)
|
||||
self.assertEqual(constants.PROVISIONED, ihost.invprovision)
|
||||
|
||||
def test_update_host_bm_valid(self):
|
||||
# Create controller-0, provisioned
|
||||
c0_host = self._create_controller_0(
|
||||
invprovision=constants.PROVISIONED,
|
||||
administrative=constants.ADMIN_UNLOCKED,
|
||||
operational=constants.OPERATIONAL_DISABLED,
|
||||
availability=constants.AVAILABILITY_OFFLINE)
|
||||
self._create_test_host_platform_interface(c0_host)
|
||||
|
||||
bm_ip = '128.224.141.222'
|
||||
bm_username = 'root'
|
||||
|
||||
for bm_type in constants.HOST_BM_VALID_PROVISIONED_TYPE_LIST:
|
||||
bm_password = 'password' + bm_type
|
||||
response = self._patch_host(c0_host['hostname'],
|
||||
[{'path': '/bm_type',
|
||||
'value': bm_type,
|
||||
'op': 'replace'},
|
||||
{'path': '/bm_ip',
|
||||
'value': bm_ip,
|
||||
'op': 'replace'},
|
||||
{'path': '/bm_username',
|
||||
'value': bm_username,
|
||||
'op': 'replace'},
|
||||
{'path': '/bm_password',
|
||||
'value': bm_password,
|
||||
'op': 'replace'}],
|
||||
'')
|
||||
self.assertEqual(response.content_type, 'application/json')
|
||||
self.assertEqual(response.status_code, http_client.OK)
|
||||
|
||||
ihost = self._get_test_host_by_hostname(c0_host['hostname'])
|
||||
self.assertEqual(bm_type, ihost.bm_type)
|
||||
self.assertEqual(bm_ip, ihost.bm_ip)
|
||||
self.assertEqual(bm_username, ihost.bm_username)
|
||||
|
||||
self.fake_conductor_api.create_barbican_secret.assert_called_with(
|
||||
mock.ANY, ihost.uuid, bm_password)
|
||||
|
||||
def test_unlock_action_controller(self):
|
||||
# Create controller-0
|
||||
c0_host = self._create_controller_0(
|
||||
|
|
|
@ -134,7 +134,7 @@ def get_test_ihost(**kw):
|
|||
'serialid': kw.get('serialid', 'sysinv123456'),
|
||||
'bm_ip': kw.get('bm_ip', "128.224.150.193"),
|
||||
'bm_mac': kw.get('bm_mac', "a4:5d:36:fc:a5:6c"),
|
||||
'bm_type': kw.get('bm_type', constants.BM_TYPE_GENERIC),
|
||||
'bm_type': kw.get('bm_type', constants.HOST_BM_TYPE_DEPROVISIONED),
|
||||
'bm_username': kw.get('bm_username', "ihostbmusername"),
|
||||
'action': kw.get('action', "none"),
|
||||
'task': kw.get('task', None),
|
||||
|
|
Loading…
Reference in New Issue