diff --git a/confluent_server/confluent/discovery/handlers/xcc.py b/confluent_server/confluent/discovery/handlers/xcc.py index be330ed7..d3c3eda4 100644 --- a/confluent_server/confluent/discovery/handlers/xcc.py +++ b/confluent_server/confluent/discovery/handlers/xcc.py @@ -13,12 +13,16 @@ # limitations under the License. import confluent.discovery.handlers.imm as immhandler +import confluent.netutil as netutil import confluent.util as util +import eventlet.support.greendns import json import pyghmi.exceptions as pygexc import pyghmi.redfish.oem.lenovo.xcc as xcc import pyghmi.util.webclient as webclient import struct +getaddrinfo = eventlet.support.greendns.getaddrinfo + def fixup_uuid(uuidprop): baduuid = ''.join(uuidprop.split()) @@ -225,6 +229,33 @@ class NodeHandler(immhandler.NodeHandler): if not isdefault: self._setup_xcc_account(user, passwd, wc) self._convert_sha256account(user, passwd, wc) + cd = self.configmanager.get_node_attributes( + nodename, ['secret.hardwaremanagementuser', + 'secret.hardwaremanagementpassword', + 'hardwaremanagement.manager'], True) + cd = cd.get(nodename, {}) + if ('hardwaremanagement.manager' in cd and + cd['hardwaremanagement.manager']['value'] and + not cd['hardwaremanagement.manager']['value'].startswith( + 'fe80::')): + newip = cd['hardwaremanagement.manager']['value'] + newipinfo = getaddrinfo(newip, 0)[0] + newip = newipinfo[-1][0] + if ':' in newip: + raise exc.NotImplementedException('IPv6 remote config TODO') + netconfig = netutil.get_nic_config(self.configmanager, nodename, ip=newip) + newmask = netutil.cidr_to_mask(netconfig['prefix']) + # do not change the ipv4_config if the current config looks + statargs = {'ENET_IPv4Ena': '1', 'ENET_IPv4AddrSource': '0', 'ENET_IPv4StaticIPAddr': newip, 'ENET_IPv4StaticIPNetMask': newmask} + if netconfig['ipv4_gateway']: + statargs['ENET_IPv4GatewayIPAddr'] = netconfig['ipv4_gateway'] + wc.grab_json_response('/api/dataset', statargs) + elif self.ipaddr.startswith('fe80::'): + self.configmanager.set_node_attributes( + {nodename: {'hardwaremanagement.manager': self.ipaddr}}) + else: + raise exc.TargetEndpointUnreachable( + 'hardwaremanagement.manager must be set to desired address (No IPv6 Link Local detected)') ff = self.info.get('attributes', {}).get('enclosure-form-factor', '') if ff not in ('dense-computing', [u'dense-computing']): return diff --git a/confluent_server/confluent/netutil.py b/confluent_server/confluent/netutil.py index 28fc71c8..d268551f 100644 --- a/confluent_server/confluent/netutil.py +++ b/confluent_server/confluent/netutil.py @@ -24,6 +24,19 @@ import eventlet.support.greendns getaddrinfo = eventlet.support.greendns.getaddrinfo +def mask_to_cidr(mask): + maskn = socket.inet_pton(socket.AF_INET, mask) + maskn = struct.unpack('!I', maskn)[0] + cidr = 32 + while maskn & 0b1 == 0 and cidr > 0: + cidr -= 1 + maskn >>= 1 + return cidr + +def cidr_to_mask(cidr): + return socket.inet_ntop( + socket.AF_INET, struct.pack('!I', (2**32 - 1) ^ (2**(32 - cidr) - 1))) + def ip_on_same_subnet(first, second, prefix): addrinf = socket.getaddrinfo(first, None, 0, socket.SOCK_STREAM)[0] fam = addrinf[0]