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:
commit
3eafbecb6e
@ -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')
|
||||
|
@ -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"])
|
||||
|
@ -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)
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user