From 69a3689dc1dbec809f9af555f54e971e8b48bc1f Mon Sep 17 00:00:00 2001 From: dave kormann Date: Thu, 27 Jun 2019 12:52:59 -0400 Subject: [PATCH] FIX: Allow configuration of IPMI privilege level This change updates the inventory handlers to provide an IPMI privilege level (with a default of "ADMINISTRATOR") when making hardware detection requests. If the privilege level is not specified, IPMI requests will fail if the user does not have ADMINISTRATOR privileges. This change depends on changes 1076 and 1077. signed-off-by: dave kormann Change-Id: I06225d00adc719c324de5fc1a4b18d7ea2ac56f4 --- .../baremetal-node-inventory/zbaremetalnodeinventory.py | 2 ++ inventoryhandlers/hwinventory/hwinventory.py | 9 +++++---- inventoryhandlers/openstack/openstackinventory.py | 2 ++ inventoryhandlers/storageinventory/storageinventory.py | 3 ++- validators/src/HostsValidation.py | 10 ++++++++++ validators/src/VersionValidation.py | 4 ++-- 6 files changed, 23 insertions(+), 7 deletions(-) mode change 100644 => 100755 inventoryhandlers/hwinventory/hwinventory.py mode change 100644 => 100755 inventoryhandlers/storageinventory/storageinventory.py diff --git a/inventoryhandlers/baremetal-node-inventory/zbaremetalnodeinventory.py b/inventoryhandlers/baremetal-node-inventory/zbaremetalnodeinventory.py index 249a5c0..b6b90e9 100644 --- a/inventoryhandlers/baremetal-node-inventory/zbaremetalnodeinventory.py +++ b/inventoryhandlers/baremetal-node-inventory/zbaremetalnodeinventory.py @@ -96,6 +96,7 @@ class zbaremetalnodeinventory(cmansibleinventoryconfig.CMAnsibleInventoryConfigP def handle(self): usersconf = self.confman.get_users_config_handler() + hostsconf = self.confman.get_hosts_config_handler() admin_user = usersconf.get_admin_user() self.add_global_var("home_dir", "/home/" + admin_user) all_vars = self.inventory['all']['vars'] @@ -177,6 +178,7 @@ class zbaremetalnodeinventory(cmansibleinventoryconfig.CMAnsibleInventoryConfigP power["ipmi_address"] = all_vars['hosts'][host]['hwmgmt']['address'] power["ipmi_password"] = all_vars['hosts'][host]['hwmgmt']['password'] power["ipmi_username"] = all_vars['hosts'][host]['hwmgmt']['user'] + power["ipmi_priv_level"] = hostsconf.get_hwmgmt_priv_level(host) power["product_family"] = all_vars['hw_inventory_details'][host]['product_family'] power["vendor"] = all_vars['hw_inventory_details'][host]['vendor'] diff --git a/inventoryhandlers/hwinventory/hwinventory.py b/inventoryhandlers/hwinventory/hwinventory.py old mode 100644 new mode 100755 index 76ea0a9..7768426 --- a/inventoryhandlers/hwinventory/hwinventory.py +++ b/inventoryhandlers/hwinventory/hwinventory.py @@ -61,7 +61,7 @@ class hwinventory(cmansibleinventoryconfig.CMAnsibleInventoryConfigPlugin): self._set_hw_types() self._add_hw_config() - + def _add_hw_config(self): try: text = Environment().from_string(JSON_HW_HOST_VAR).render( @@ -78,8 +78,9 @@ class hwinventory(cmansibleinventoryconfig.CMAnsibleInventoryConfigPlugin): hwmgmt_addr = self._hosts_config_handler.get_hwmgmt_ip(name) hwmgmt_user = self._hosts_config_handler.get_hwmgmt_user(name) hwmgmt_pass = self._hosts_config_handler.get_hwmgmt_password(name) - return hw.get_hw_data(hwmgmt_addr, hwmgmt_user, hwmgmt_pass) - + hwmgmt_priv_level = self._hosts_config_handler.get_hwmgmt_priv_level(name) + return hw.get_hw_data(hwmgmt_addr, hwmgmt_user, hwmgmt_pass, hwmgmt_priv_level) + def _set_hw_types(self): hosts = self._hosts_config_handler.get_hosts() for host in hosts: @@ -88,4 +89,4 @@ class hwinventory(cmansibleinventoryconfig.CMAnsibleInventoryConfigPlugin): host_object.vendor = hw_details.get("vendor", "Unknown") host_object.product_family = hw_details.get("product_family", "Unknown") host_object.mgmt_mac = hw_details.get('info', {}).get("MAC Address", "00:00:00:00:00:00") - self.host_objects.append(host_object) + self.host_objects.append(host_object) diff --git a/inventoryhandlers/openstack/openstackinventory.py b/inventoryhandlers/openstack/openstackinventory.py index 1f6ee81..2dde0db 100644 --- a/inventoryhandlers/openstack/openstackinventory.py +++ b/inventoryhandlers/openstack/openstackinventory.py @@ -1137,6 +1137,7 @@ class Host: self.hwmgmt_address = None self.hwmgmt_password = None self.hwmgmt_user = None + self.hwmgmt_priv_level = 'ADMINISTRATOR' self.mgmt_mac = None self.is_performance = False self.os_max_threads = 16 @@ -1427,6 +1428,7 @@ class openstackinventory(cmansibleinventoryconfig.CMAnsibleInventoryConfigPlugin host.hwmgmt_address = hostsconf.get_hwmgmt_ip(name) host.hwmgmt_user = hostsconf.get_hwmgmt_user(name) host.hwmgmt_password = hostsconf.get_hwmgmt_password(name) + host.hwmgmt_priv_level = hostsconf.get_hwmgmt_priv_level(name) host.mgmt_mac = hostsconf.get_mgmt_mac(name) diff --git a/inventoryhandlers/storageinventory/storageinventory.py b/inventoryhandlers/storageinventory/storageinventory.py old mode 100644 new mode 100755 index b0a9182..73a75b0 --- a/inventoryhandlers/storageinventory/storageinventory.py +++ b/inventoryhandlers/storageinventory/storageinventory.py @@ -1319,7 +1319,8 @@ class storageinventory(cmansibleinventoryconfig.CMAnsibleInventoryConfigPlugin): hwmgmt_addr = self._hosts_config_handler.get_hwmgmt_ip(name) hwmgmt_user = self._hosts_config_handler.get_hwmgmt_user(name) hwmgmt_pass = self._hosts_config_handler.get_hwmgmt_password(name) - return hw.get_hw_type(hwmgmt_addr, hwmgmt_user, hwmgmt_pass) + hwmgmt_priv_level = self._hosts_config_handler.get_hwmgmt_priv_level(name) + return hw.get_hw_type(hwmgmt_addr, hwmgmt_user, hwmgmt_pass, hwmgmt_priv_level) @staticmethod def _get_os_disk(hw_type): diff --git a/validators/src/HostsValidation.py b/validators/src/HostsValidation.py index 86494e8..e59ed26 100644 --- a/validators/src/HostsValidation.py +++ b/validators/src/HostsValidation.py @@ -403,12 +403,22 @@ class HostsValidation(cmvalidator.CMValidator): (attribute, profile, host)) def validate_hwmgmt(self, hwmgmt, host): + # this list may not be comprehensive, but it matches ironic's idea + # of valid privileges. In practice, we'll likely only see OPERATOR + # and ADMINISTRATOR. Case seems to matter here. + valid_ipmi_priv = ['USER', 'CALLBACK', 'OPERATOR', 'ADMINISTRATOR'] + if not hwmgmt: raise validation.ValidationError('Missing hwmgmt configuration for %s' % host) if not hwmgmt.get('user'): raise validation.ValidationError('Missing hwmgmt username for %s' % host) if not hwmgmt.get('password'): raise validation.ValidationError('Missing hwmgmt password for %s' % host) + priv_level = hwmgmt.get('priv_level') + if priv_level and priv_level not in valid_ipmi_priv: + # priv_level is optional, but should be in the valid range. + raise validation.ValidationError('Invalid IPMI privilege level %s for %s' % + (priv_level, host)) validationutils = validation.ValidationUtils() validationutils.validate_ip_address(hwmgmt.get('address')) diff --git a/validators/src/VersionValidation.py b/validators/src/VersionValidation.py index f6e891a..813cf02 100644 --- a/validators/src/VersionValidation.py +++ b/validators/src/VersionValidation.py @@ -22,10 +22,10 @@ from cmdatahandlers.api import validation class VersionValidation(cmvalidator.CMValidator): domain = 'cloud.version' - version = [2, 0, 2] + version = [2, 0, 3] # Should be same as 'version' in release build - devel_version = [2, 0, 2] + devel_version = [2, 0, 3] # Example: # {1: 'This is the first change requiring new template version (1.1.0)', -- 2.16.6