2
0
mirror of https://github.com/xcat2/xcat-core.git synced 2025-05-22 03:32:04 +00:00

Merge pull request #4884 from xuweibj/rspconfig_setnet

rspconfig set ip/netmask/gateway/vlan in python
This commit is contained in:
zet809 2018-03-16 13:54:57 +08:00 committed by GitHub
commit 3eafbecb6e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 171 additions and 24 deletions

View File

@ -82,6 +82,16 @@ def sort_string_with_numbers(origin_list):
new_list.sort()
return [string for __,string in new_list]
def mask_str2int(mask):
count_bit = lambda bin_str: len([i for i in bin_str if i=='1'])
mask_splited = mask.split('.')
mask_count = [count_bit(bin(int(i))) for i in mask_splited]
return sum(mask_count)
def mask_int2str(mask_int):
mask_num = (0x1 << 32) - (0x1 << (32 - mask_int))
return "%s.%s.%s.%s" % (str((mask_num >> 24) & 0xff), str((mask_num >>16)&0xff), str((mask_num >> 8) & 0xff), str(mask_num & 0xff))
class Messager(object):
def __init__(self, name=None):
self.logger = logging.getLogger(name or 'xcatagent')

View File

@ -296,7 +296,7 @@ rmdir \"/tmp/$userid\" \n")
return
else:
self._set_netinfo(netinfo_dict['ip'], netinfo_dict['netmask'],
netinfo_dict['gateway'], netinfo_dict['vlan'])
netinfo_dict['gateway'], netinfo_dict['vlan'], **kw)
def _set_hostname(self, hostname, **kw):
node = kw['node']
@ -324,6 +324,10 @@ rmdir \"/tmp/$userid\" \n")
if not netinfo:
return self.callback.error('No network information get', node)
if 'error' in netinfo:
self.callback.info('%s: %s' % (node, netinfo['error']))
return
bmcip = node_info['bmcip']
nic = self._get_facing_nic(bmcip, netinfo)
if not nic:
@ -394,12 +398,91 @@ rmdir \"/tmp/$userid\" \n")
result = '%s: %s: %s' % (node, openbmc.RSPCONFIG_APIS[key]['display_name'], str_value.split('.')[-1])
self.callback.info(result)
def _set_netinfo(self, ip, netmask, gateway, vlan=False, **kw):
def _print_bmc_netinfo(self, node, ip, netmask, gateway, vlan):
self.callback.info('%s: BMC IP: %s'% (node, ip))
self.callback.info('%s: BMC Netmask: %s' % (node, netmask))
self.callback.info('%s: BMC Gateway: %s' % (node, gateway))
if vlan:
result = "set net(%s, %s, %s) for vlan %s" % (ip, netmask, gateway, vlan)
else:
result = "set net(%s, %s, %s) for eth0" % (ip, netmask, gateway)
return self.callback.info("set_netinfo %s" % result)
self.callback.info('%s: BMC VLAN ID: %s' % (node, vlan))
def _set_netinfo(self, ip, netmask, gateway, vlan=False, **kw):
node = kw['node']
node_info = kw['nodeinfo']
obmc = openbmc.OpenBMCRest(name=node, nodeinfo=node_info, messager=self.callback,
debugmode=self.debugmode, verbose=self.verbose)
try:
obmc.login()
netinfo = obmc.get_netinfo()
except (SelfServerException, SelfClientException) as e:
self.callback.error(e.message, node)
return
if not netinfo:
return self.callback.error("No network information get", node)
if 'error' in netinfo:
return self.callback.info('%s: %s' % (node, netinfo['error']))
bmcip = node_info['bmcip']
origin_nic = nic = self._get_facing_nic(bmcip, netinfo)
if not nic:
return self.callback.error('Can not get facing NIC for %s' % bmcip, node)
prefix = int(utils.mask_str2int(netmask))
if (ip == netinfo[nic]['ip'] and prefix == netinfo[nic]['netmask'] and
gateway == netinfo[nic]['gateway']):
if not vlan or vlan == str(netinfo[nic]['vlanid']):
self._print_bmc_netinfo(node, ip, netmask, gateway, vlan)
return
origin_type = netinfo[origin_nic]['ipsrc']
origin_ip_obj = netinfo[origin_nic]['ipobj']
if vlan:
pre_nic = nic.split('_')[0]
try:
obmc.set_vlan(pre_nic, vlan)
sleep( 15 )
except (SelfServerException, SelfClientException) as e:
self.callback.error(e.message, node)
return
nic = pre_nic + '_' + vlan
try:
obmc.set_netinfo(nic, ip, prefix, gateway)
sleep( 5 )
nic_netinfo = obmc.get_nic_netinfo(nic)
except (SelfServerException, SelfClientException) as e:
self.callback.error(e.message, node)
return
if not nic_netinfo:
return self.callback.error('Did not get info for NIC %s' % nic, node)
set_success = False
for net_id, attr in nic_netinfo.items():
if (attr['ip'] == ip and
attr["netmask"] == prefix and
attr['gateway'] == gateway):
set_success = True
if not set_success:
return self.callback.error('Config BMC IP failed', node)
try:
if origin_type == 'DHCP':
obmc.disable_dhcp(origin_nic)
elif origin_type == 'Static':
obmc.delete_ip_object(origin_nic, origin_ip_obj)
else:
self.callback.error('Get wrong Origin type %s for NIC %s IP object %s' % (origin_type, nic, origin_ip_obj), node)
except (SelfServerException, SelfClientException) as e:
self.callback.error(e.message, node)
self. _print_bmc_netinfo(node, ip, netmask, gateway, vlan)
def _get_netinfo(self, ip=False, ipsrc=False, netmask=False, gateway=False, vlan=False, hostname=False, ntpservers=False, **kw):
node = kw['node']
@ -424,6 +507,10 @@ rmdir \"/tmp/$userid\" \n")
if hostname:
self.callback.info("%s: BMC Hostname: %s" %(node, bmchostname))
if 'error' in netinfo:
return self.callback.info('%s: %s' % (node, netinfo['error']))
dic_length = len(netinfo)
netinfodict = {'ip':[], 'netmask':[], 'gateway':[],
'vlan':[], 'ipsrc':[], 'ntpservers':[]}
@ -432,7 +519,7 @@ rmdir \"/tmp/$userid\" \n")
if dic_length > 1:
addon_string = " for %s" % nic
netinfodict['ip'].append("BMC IP"+addon_string+": %s" % attrs["ip"])
netinfodict['netmask'].append("BMC Netmask"+addon_string+": %s" % attrs["netmask"])
netinfodict['netmask'].append("BMC Netmask"+addon_string+": %s" % utils.mask_int2str(attrs["netmask"]))
netinfodict['gateway'].append("BMC Gateway"+addon_string+": %s (default: %s)" % (attrs["gateway"], defaultgateway))
netinfodict['vlan'].append("BMC VLAN ID"+addon_string+": %s" % attrs["vlanid"])
netinfodict['ipsrc'].append("BMC IP Source"+addon_string+": %s" % attrs["ipsrc"])

View File

@ -162,11 +162,14 @@ FIRM_URLS = {
}
RSPCONFIG_NETINFO_URL = {
'delete_ip_object': "/network/#NIC#/ipv4/#OBJ#",
'disable_dhcp': "/network/#NIC#/attr/DHCPEnabled",
'get_netinfo': "/network/enumerate",
'nic_ip': "/network/#NIC#/action/IP",
'vlan': "/network/action/VLAN",
'get_nic_netinfo': "/network/#NIC#/ipv4/enumerate",
'ipdhcp': "/network/action/Reset",
'nic_ip': "/network/#NIC#/action/IP",
'ntpservers': "/network/#NIC#/attr/NTPServers",
'vlan': "/network/action/VLAN",
}
PASSWD_URL = '/user/root/action/SetPassword'
@ -285,7 +288,7 @@ class OpenBMCRest(object):
code = resp.status_code
if code != requests.codes.ok:
description = ''.join(data['data']['description'])
error = 'Error: [%d] %s' % (code, description)
error = '[%d] %s' % (code, description)
self._print_record_log(error, cmd)
raise SelfClientException(error, code)
@ -308,12 +311,12 @@ class OpenBMCRest(object):
response = self.session.request(method, url, httpheaders, data=data, timeout=timeout)
return self.handle_response(response, cmd=cmd)
except SelfServerException as e:
e.message = 'Error: BMC did not respond. ' \
e.message = 'BMC did not respond. ' \
'Validate BMC configuration and retry the command.'
self._print_record_log(e.message, cmd)
raise
except ValueError:
error = 'Error: Received wrong format response: %s' % response
error = 'Received wrong format response: %s' % response
self._print_record_log(error, cmd)
raise SelfServerException(error)
@ -360,13 +363,13 @@ class OpenBMCRest(object):
try:
data = json.loads(response)
except ValueError:
error = 'Error: Received wrong format response when running command \'%s\': %s' % \
error = 'Received wrong format response when running command \'%s\': %s' % \
(request_cmd, response)
self._print_record_log(error, cmd=cmd)
raise SelfServerException(error)
if data['message'] != '200 OK':
error = 'Error: Failed to upload update file %s : %s-%s' % \
error = 'Failed to upload update file %s : %s-%s' % \
(files, data['message'], \
''.join(data['data']['description']))
self._print_record_log(error, cmd=cmd)
@ -392,7 +395,7 @@ class OpenBMCRest(object):
chassis_stat = states[PROJECT_URL + '/state/chassis0']['CurrentPowerState']
return {'host': host_stat.split('.')[-1], 'chassis': chassis_stat.split('.')[-1]}
except KeyError:
error = 'Error: Received wrong format response: %s' % states
error = 'Received wrong format response: %s' % states
raise SelfServerException(error)
def set_power_state(self, state):
@ -406,7 +409,7 @@ class OpenBMCRest(object):
try:
return {'bmc': state.split('.')[-1]}
except KeyError:
error = 'Error: Received wrong format response: %s' % state
error = 'Received wrong format response: %s' % state
raise SelfServerException(error)
def reboot_bmc(self, optype='warm'):
@ -448,7 +451,7 @@ class OpenBMCRest(object):
boot_state = BOOTSOURCE_GET_STATE.get(boot_source.split('.')[-1], error)
return boot_state
except KeyError:
error = 'Error: Received wrong format response: %s' % states
error = 'Received wrong format response: %s' % states
raise SelfServerException(error)
def get_beacon_info(self):
@ -462,7 +465,7 @@ class OpenBMCRest(object):
beacon_dict[key_id] = value['State'].split('.')[-1]
return beacon_dict
except KeyError:
error = 'Error: Received wrong format response: %s' % beacon_data
error = 'Received wrong format response: %s' % beacon_data
raise SelfServerException(error)
def set_beacon_state(self, state):
@ -494,7 +497,7 @@ class OpenBMCRest(object):
return sensor_dict
except KeyError:
error = 'Error: Received wrong format response: %s' % sensor_data
error = 'Received wrong format response: %s' % sensor_data
raise SelfServerException(error)
def get_inventory_info(self):
@ -531,7 +534,7 @@ class OpenBMCRest(object):
return inverntory_dict
except KeyError:
error = 'Error: Received wrong format response: %s' % inventory_data
error = 'Received wrong format response: %s' % inventory_data
raise SelfServerException(error)
def list_firmware(self):
@ -586,7 +589,7 @@ class OpenBMCRest(object):
eventlog_dict[str(id)] = event_log_line
return eventlog_dict
except KeyError:
error = 'Error: Received wrong format response: %s' % eventlog_data
error = 'Received wrong format response: %s' % eventlog_data
raise SelfServerException(error)
# Parse a single eventlog entry and return data in formatted string
@ -717,7 +720,7 @@ class OpenBMCRest(object):
return dump_dict
except KeyError:
error = 'Error: Received wrong format response: %s' % dump_data
error = 'Received wrong format response: %s' % dump_data
raise SelfServerException(error)
def download_dump(self, download_id, file_path):
@ -732,6 +735,50 @@ class OpenBMCRest(object):
url = HTTP_PROTOCOL + self.bmcip + GARD_CLEAR_URL
return self.request('POST', url, payload=payload, cmd='clear_gard')
def set_vlan(self, nic, vlan_id):
payload = { "data": [nic, vlan_id] }
return self.request('POST', RSPCONFIG_NETINFO_URL['vlan'], payload=payload, cmd='set_vlan')
def set_netinfo(self, nic, ip, netmask, gateway):
payload = { "data": ["xyz.openbmc_project.Network.IP.Protocol.IPv4", ip, netmask, gateway] }
path = RSPCONFIG_NETINFO_URL['nic_ip'].replace('#NIC#', nic)
return self.request('POST', path, payload=payload, cmd='set_netinfo')
def disable_dhcp(self, nic):
payload = { "data": 0 }
path = RSPCONFIG_NETINFO_URL['disable_dhcp'].replace('#NIC#', nic)
return self.request('PUT', path, payload=payload, cmd='disable_dhcp')
def delete_ip_object(self, nic, ip_object):
path = RSPCONFIG_NETINFO_URL['delete_ip_object'].replace('#OBJ#', ip_object).replace('#NIC#', nic)
return self.request('DELETE', path, cmd='delete_ip_object')
def get_nic_netinfo(self, nic):
path = RSPCONFIG_NETINFO_URL['get_nic_netinfo'].replace('#NIC#', nic)
data = self.request('GET', path, cmd='get_nic_netinfo')
try:
netinfo = {}
for k, v in data.items():
dev,match,netid = k.partition("/ipv4/")
if 'LinkLocal' in v["Origin"] or v["Address"].startswith("169.254"):
msg = "Found LinkLocal address %s for interface %s, Ignoring..." % (v["Address"], dev)
self._print_record_log(msg, 'get_netinfo')
continue
utils.update2Ddict(netinfo, netid, 'ip', v['Address'])
utils.update2Ddict(netinfo, netid, 'ipsrc', v['Origin'].split('.')[-1])
utils.update2Ddict(netinfo, netid, 'netmask', v['PrefixLength'])
utils.update2Ddict(netinfo, netid, 'gateway', v['Gateway'])
return netinfo
except KeyError:
error = 'Received wrong format response: %s' % data
raise SelfServerException(error)
def get_netinfo(self):
data = self.request('GET', RSPCONFIG_NETINFO_URL['get_netinfo'], cmd="get_netinfo")
try:
@ -755,11 +802,14 @@ class OpenBMCRest(object):
if 'ip' in netinfo[nicid]:
msg = "%s: Another valid ip %s found." % (node, v["Address"])
self._print_record_log(msg, 'get_netinfo')
continue
del netinfo[nicid]
netinfo['error'] = 'Interfaces with multiple IP addresses are not supported'
break
utils.update2Ddict(netinfo, nicid, "ipsrc", v["Origin"].split('.')[-1])
utils.update2Ddict(netinfo, nicid, "netmask", v["PrefixLength"])
utils.update2Ddict(netinfo, nicid, "gateway", v["Gateway"])
utils.update2Ddict(netinfo, nicid, "ip", v["Address"])
utils.update2Ddict(netinfo, nicid, "ipobj", netid)
if dev in data:
info = data[dev]
utils.update2Ddict(netinfo, nicid, "vlanid", info.get("Id", "Disable"))
@ -771,7 +821,7 @@ class OpenBMCRest(object):
utils.update2Ddict(netinfo, nicid, "ntpservers", ntpservers)
return netinfo
except KeyError:
error = 'Error: Received wrong format response: %s' % data
error = 'Received wrong format response: %s' % data
raise SelfServerException(error)