mirror of
https://github.com/xcat2/confluent.git
synced 2025-04-19 03:27:20 +00:00
Implement XCC3 discovery
For XCC3, change to generic redfish onboarding mechanism. Extend the generic mechanism to be more specific in some ways that the XCC3 is pickier about. However, it's just reiteration of what should have already have been the case.
This commit is contained in:
parent
e9d4174ce5
commit
cfb31a0d8d
@ -74,6 +74,7 @@ import confluent.discovery.handlers.tsm as tsm
|
||||
import confluent.discovery.handlers.pxe as pxeh
|
||||
import confluent.discovery.handlers.smm as smm
|
||||
import confluent.discovery.handlers.xcc as xcc
|
||||
import confluent.discovery.handlers.xcc3 as xcc3
|
||||
import confluent.discovery.handlers.megarac as megarac
|
||||
import confluent.exceptions as exc
|
||||
import confluent.log as log
|
||||
@ -114,7 +115,7 @@ nodehandlers = {
|
||||
'service:lenovo-smm': smm,
|
||||
'service:lenovo-smm2': smm,
|
||||
'lenovo-xcc': xcc,
|
||||
'lenovo-xcc3': xcc,
|
||||
'lenovo-xcc3': xcc3,
|
||||
'megarac-bmc': megarac,
|
||||
'service:management-hardware.IBM:integrated-management-module2': imm,
|
||||
'pxe-client': pxeh,
|
||||
|
@ -80,6 +80,7 @@ class NodeHandler(generic.NodeHandler):
|
||||
wc = webclient.SecureHTTPConnection(self.ipaddr, 443, verifycallback=self.validate_cert)
|
||||
wc.set_basic_credentials(defuser, defpass)
|
||||
wc.set_header('Content-Type', 'application/json')
|
||||
wc.set_header('Accept', 'application/json')
|
||||
authmode = 0
|
||||
if not self.trieddefault:
|
||||
rsp, status = wc.grab_json_response_with_status('/redfish/v1/Managers')
|
||||
@ -114,7 +115,7 @@ class NodeHandler(generic.NodeHandler):
|
||||
if status > 400:
|
||||
self.trieddefault = True
|
||||
if status == 401:
|
||||
wc.set_basic_credentials(self.DEFAULT_USER, self.targpass)
|
||||
wc.set_basic_credentials(defuser, self.targpass)
|
||||
rsp, status = wc.grab_json_response_with_status('/redfish/v1/Managers')
|
||||
if status == 200: # Default user still, but targpass
|
||||
self.currpass = self.targpass
|
||||
@ -236,7 +237,10 @@ class NodeHandler(generic.NodeHandler):
|
||||
break
|
||||
else:
|
||||
wc.set_header('If-Match', '*')
|
||||
rsp, status = wc.grab_json_response_with_status(actualnics[0], {'IPv4StaticAddresses': [newconfig]}, method='PATCH')
|
||||
rsp, status = wc.grab_json_response_with_status(actualnics[0], {
|
||||
'DHCPv4': {'DHCPEnabled': False},
|
||||
'IPv4StaticAddresses': [newconfig]}, method='PATCH')
|
||||
|
||||
elif self.ipaddr.startswith('fe80::'):
|
||||
self.configmanager.set_node_attributes(
|
||||
{nodename: {'hardwaremanagement.manager': self.ipaddr}})
|
||||
|
102
confluent_server/confluent/discovery/handlers/xcc3.py
Normal file
102
confluent_server/confluent/discovery/handlers/xcc3.py
Normal file
@ -0,0 +1,102 @@
|
||||
# Copyright 2024 Lenovo
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import confluent.discovery.handlers.redfishbmc as redfishbmc
|
||||
import eventlet.support.greendns
|
||||
import confluent.util as util
|
||||
|
||||
webclient = eventlet.import_patched('pyghmi.util.webclient')
|
||||
|
||||
|
||||
|
||||
getaddrinfo = eventlet.support.greendns.getaddrinfo
|
||||
|
||||
|
||||
class NodeHandler(redfishbmc.NodeHandler):
|
||||
|
||||
def get_firmware_default_account_info(self):
|
||||
return ('USERID', 'PASSW0RD')
|
||||
|
||||
def scan(self):
|
||||
ip, port = self.get_web_port_and_ip()
|
||||
c = webclient.SecureHTTPConnection(ip, port,
|
||||
verifycallback=self.validate_cert)
|
||||
i = c.grab_json_response('/api/providers/logoninfo')
|
||||
modelname = i.get('items', [{}])[0].get('machine_name', None)
|
||||
if modelname:
|
||||
self.info['modelname'] = modelname
|
||||
for attrname in list(self.info.get('attributes', {})):
|
||||
val = self.info['attributes'][attrname]
|
||||
if '-uuid' == attrname[-5:] and len(val) == 32:
|
||||
val = val.lower()
|
||||
self.info['attributes'][attrname] = '-'.join([val[:8], val[8:12], val[12:16], val[16:20], val[20:]])
|
||||
attrs = self.info.get('attributes', {})
|
||||
room = attrs.get('room-id', None)
|
||||
if room:
|
||||
self.info['room'] = room
|
||||
rack = attrs.get('rack-id', None)
|
||||
if rack:
|
||||
self.info['rack'] = rack
|
||||
name = attrs.get('name', None)
|
||||
if name:
|
||||
self.info['hostname'] = name
|
||||
unumber = attrs.get('lowest-u', None)
|
||||
if unumber:
|
||||
self.info['u'] = unumber
|
||||
location = attrs.get('location', None)
|
||||
if location:
|
||||
self.info['location'] = location
|
||||
mtm = attrs.get('enclosure-machinetype-model', None)
|
||||
if mtm:
|
||||
self.info['modelnumber'] = mtm.strip()
|
||||
sn = attrs.get('enclosure-serial-number', None)
|
||||
if sn:
|
||||
self.info['serialnumber'] = sn.strip()
|
||||
if attrs.get('enclosure-form-factor', None) == 'dense-computing':
|
||||
encuuid = attrs.get('chassis-uuid', None)
|
||||
if encuuid:
|
||||
self.info['enclosure.uuid'] = fixuuid(encuuid)
|
||||
slot = int(attrs.get('slot', 0))
|
||||
if slot != 0:
|
||||
self.info['enclosure.bay'] = slot
|
||||
|
||||
def validate_cert(self, certificate):
|
||||
fprint = util.get_fingerprint(self.https_cert)
|
||||
return util.cert_matches(fprint, certificate)
|
||||
|
||||
|
||||
def remote_nodecfg(nodename, cfm):
|
||||
cfg = cfm.get_node_attributes(
|
||||
nodename, 'hardwaremanagement.manager')
|
||||
ipaddr = cfg.get(nodename, {}).get('hardwaremanagement.manager', {}).get(
|
||||
'value', None)
|
||||
ipaddr = ipaddr.split('/', 1)[0]
|
||||
ipaddr = getaddrinfo(ipaddr, 0)[0][-1]
|
||||
if not ipaddr:
|
||||
raise Exception('Cannot remote configure a system without known '
|
||||
'address')
|
||||
info = {'addresses': [ipaddr]}
|
||||
nh = NodeHandler(info, cfm)
|
||||
nh.config(nodename)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
import confluent.config.configmanager as cfm
|
||||
c = cfm.ConfigManager(None)
|
||||
import sys
|
||||
info = {'addresses': [[sys.argv[1]]]}
|
||||
print(repr(info))
|
||||
testr = NodeHandler(info, c)
|
||||
testr.config(sys.argv[2])
|
||||
|
Loading…
x
Reference in New Issue
Block a user