diff --git a/confluent_server/confluent/config/attributes.py b/confluent_server/confluent/config/attributes.py index 6e8d0bb0..55e449bc 100644 --- a/confluent_server/confluent/config/attributes.py +++ b/confluent_server/confluent/config/attributes.py @@ -156,6 +156,12 @@ node = { 'indicates candidate managers, either for ' 'high availability or load balancing purposes.') }, + 'discovery.passwordrules': { + 'description': 'Any specified rules shall be configured on the BMC ' + 'upon discovery. "expiration=no,loginfailures=no" ' + 'would disable password expiration and login failures ' + 'triggering a lockout.' + }, 'discovery.policy': { 'description': 'Policy to use for auto-configuration of discovered ' 'and identified nodes. Valid values are "manual", ' diff --git a/confluent_server/confluent/discovery/handlers/bmc.py b/confluent_server/confluent/discovery/handlers/bmc.py index 4f26a88a..5f053716 100644 --- a/confluent_server/confluent/discovery/handlers/bmc.py +++ b/confluent_server/confluent/discovery/handlers/bmc.py @@ -45,7 +45,7 @@ class NodeHandler(generic.NodeHandler): def config(self, nodename, reset=False): self._bmcconfig(nodename, reset) - def _bmcconfig(self, nodename, reset=False): + def _bmcconfig(self, nodename, reset=False, customconfig=None): # TODO(jjohnson2): set ip parameters, user/pass, alert cfg maybe # In general, try to use https automation, to make it consistent # between hypothetical secure path and today. @@ -74,6 +74,8 @@ class NodeHandler(generic.NodeHandler): ic = self._get_ipmicmd(user, passwd) else: raise + if customconfig: + customconfig(ic) currusers = ic.get_users() lanchan = ic.get_network_channel() userdata = ic.xraw_command(netfn=6, command=0x44, data=(lanchan, diff --git a/confluent_server/confluent/discovery/handlers/xcc.py b/confluent_server/confluent/discovery/handlers/xcc.py index ad222489..7cbafd5e 100644 --- a/confluent_server/confluent/discovery/handlers/xcc.py +++ b/confluent_server/confluent/discovery/handlers/xcc.py @@ -13,11 +13,13 @@ # limitations under the License. import confluent.discovery.handlers.imm as immhandler +import confluent.util as util import pyghmi.exceptions as pygexc import pyghmi.ipmi.oem.lenovo.imm as imm + class NodeHandler(immhandler.NodeHandler): devname = 'XCC' @@ -41,16 +43,45 @@ class NodeHandler(immhandler.NodeHandler): #if ipmicmd: # ipmicmd.ipmi_session.logout() + def validate_cert(self, certificate): + # broadly speaking, merely checks consistency moment to moment, + # but if https_cert gets stricter, this check means something + fprint = util.get_fingerprint(self.https_cert) + return util.cert_matches(fprint, certificate) + + def set_password_policy(self, ic): + ruleset = {'USER_GlobalMinPassChgInt': '0'} + for rule in self.ruleset.split(','): + if '=' not in rule: + continue + name, value = rule.split('=') + if value.lower() in ('no', 'none', 'disable', 'disabled'): + value = '0' + if name.lower() in ('expiry', 'expiration'): + ruleset['USER_GlobalPassExpPeriod'] = value + if int(value) < 5: + ruleset['USER_GlobalPassExpWarningPeriod'] = value + if name.lower() in ('lockout', 'loginfailures'): + if value.lower() in ('no', 'none', 'disable', 'disabled'): + value = '0' + ruleset['USER_GlobalMaxLoginFailures'] = value + ic.register_key_handler(self.validate_cert) + ic.oem_init() + ic._oem.immhandler.wc.grab_json_response('/api/dataset', ruleset) + def config(self, nodename, reset=False): # TODO(jjohnson2): set ip parameters, user/pass, alert cfg maybe # In general, try to use https automation, to make it consistent # between hypothetical secure path and today. - ic = self._bmcconfig(nodename) + dpp = self.configmanager.get_node_attributes( + nodename, 'discovery.passwordrules') + self.ruleset = dpp.get(nodename, {}).get( + 'discovery.passwordrules', {}).get('value', '') + ic = self._bmcconfig(nodename, customconfig=self.set_password_policy) ff = self.info.get('attributes', {}).get('enclosure-form-factor', '') if ff not in ('dense-computing', [u'dense-computing']): return # Ok, we can get the enclosure uuid now.. - ic.oem_init() enclosureuuid = ic._oem.immhandler.get_property( '/v2/ibmc/smm/chassis/uuid') enclosureuuid = ic._oem.immhandler.get_property(