mirror of
				https://github.com/xcat2/xcat-core.git
				synced 2025-10-31 03:12:30 +00:00 
			
		
		
		
	rspconfig set ip/netmask/gateway/vlan in python
This commit is contained in:
		| @@ -82,6 +82,20 @@ def sort_string_with_numbers(origin_list): | ||||
|     new_list.sort() | ||||
|     return [string for __,string in new_list] | ||||
|  | ||||
| def exchange_mask(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 exchange_maskint(mask_int): | ||||
|     bin_arr = ['0' for i in range(32)] | ||||
|     for i in range(mask_int): | ||||
|         bin_arr[i] = '1' | ||||
|     tmpmask = [''.join(bin_arr[i * 8:i * 8 + 8]) for i in range(4)] | ||||
|     tmpmask = [str(int(tmpstr, 2)) for tmpstr in tmpmask] | ||||
|     return '.'.join(tmpmask) | ||||
|  | ||||
| class Messager(object): | ||||
|     def __init__(self, name=None): | ||||
|         self.logger = logging.getLogger(name or 'xcatagent') | ||||
|   | ||||
| @@ -167,7 +167,7 @@ class OpenBMCBmcConfigTask(ParallelNodesCommand): | ||||
|                 if (20-i) % 8 == 0: | ||||
|                     self.callback.info('%s: Still waiting for dump %s to be generated... '  % (node, dump_id)) | ||||
|  | ||||
|                 sleep( 15 ) | ||||
|                 gevent.sleep( 15 ) | ||||
|  | ||||
|             if flag:  | ||||
|                 self._dump_download(obmc, node, str(dump_id), flag_dump_process=True) | ||||
| @@ -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) | ||||
|  | ||||
|         if (ip == netinfo[nic]['ip'] and netmask == utils.exchange_maskint(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) | ||||
|                 gevent.sleep( 15 ) | ||||
|             except (SelfServerException, SelfClientException) as e: | ||||
|                 self.callback.error(e.message, node) | ||||
|                 return | ||||
|             nic = pre_nic + '_' + vlan | ||||
|  | ||||
|         prefix = int(utils.exchange_mask(netmask)) | ||||
|         try: | ||||
|             obmc.set_netinfo(nic, ip, prefix, gateway) | ||||
|             gevent.sleep( 5 ) | ||||
|             nic_netinfo = obmc.get_nic_netinfo(nic) | ||||
|         except (SelfServerException, SelfClientException) as e: | ||||
|             self.callback.error(e.message, node) | ||||
|             return | ||||
|  | ||||
|         if not 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: | ||||
|                 attr_netmask = utils.exchange_maskint(attr["netmask"]) | ||||
|                 if (attr_netmask == netmask 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.exchange_maskint(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) | ||||
|             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) | ||||
|          | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user