mirror of
				https://github.com/xcat2/xcat-core.git
				synced 2025-10-31 03:12:30 +00:00 
			
		
		
		
	add rspconfig get network information
This commit is contained in:
		| @@ -5,12 +5,15 @@ | ||||
| # -*- coding: utf-8 -*- | ||||
| # | ||||
| from __future__ import print_function | ||||
| import gevent | ||||
| import time | ||||
| import os, stat | ||||
|  | ||||
| from common import utils | ||||
| from common.task import ParallelNodesCommand | ||||
| from common.exceptions import SelfClientException, SelfServerException | ||||
| from hwctl import openbmc_client as openbmc | ||||
| #from paramiko import SSHClient | ||||
| from pssh.pssh_client import ParallelSSHClient | ||||
| from gevent import joinall | ||||
|  | ||||
| import logging | ||||
| logger = logging.getLogger('xcatagent') | ||||
| @@ -18,6 +21,8 @@ logger = logging.getLogger('xcatagent') | ||||
| RSPCONFIG_GET_NETINFO=['ip', 'netmask', 'gateway', 'vlan', 'ipsrc', 'hostname'] | ||||
| RSPCONFIG_SET_NETINFO=['ip', 'netmask', 'gateway', 'vlan'] | ||||
|  | ||||
|  | ||||
|  | ||||
| class OpenBMCBmcConfigTask(ParallelNodesCommand): | ||||
|          | ||||
|     def dump_list(self, **kw): | ||||
| @@ -35,8 +40,65 @@ class OpenBMCBmcConfigTask(ParallelNodesCommand): | ||||
|     def dump_process(self, **kw): | ||||
|         return self.callback.info("dump_process: trigger, list and download") | ||||
|  | ||||
|     def _create_copy_file(self, filename): | ||||
|         f = open(filename, 'w') | ||||
|         f.write("#!/bin/sh \n\ | ||||
| umask 0077 \n\ | ||||
| userid=$1 \n\ | ||||
| home=`egrep \"^$userid:\" /etc/passwd | cut -f6 -d :` \n\ | ||||
| if [ -n \"$home\" ]; then \n\ | ||||
|   dest_dir=\"$home/.ssh\" \n\ | ||||
| else \n\ | ||||
|   home=`su - root -c pwd` \n\ | ||||
|   dest_dir=\"$home/.ssh\" \n\ | ||||
| fi \n\ | ||||
| mkdir -p $dest_dir \n\ | ||||
| cat /tmp/$userid/.ssh/id_rsa.pub >> $dest_dir/authorized_keys 2>&1 \n\ | ||||
| rm -f /tmp/$userid/.ssh/* 2>&1 \n\ | ||||
| rmdir \"/tmp/$userid/.ssh\" \n\ | ||||
| rmdir \"/tmp/$userid\" \n") | ||||
|  | ||||
|         f.close() | ||||
|         os.chmod(filename,stat.S_IRWXU) | ||||
|         return | ||||
|  | ||||
|     def _prepare_hosts_cfg(self, nodesinfo): | ||||
|         host_config = {} | ||||
|         for node in nodesinfo.keys(): | ||||
|             nodeinfo = nodesinfo[node] | ||||
|             utils.update2Ddict(host_config, nodeinfo['bmcip'], 'user', nodeinfo['username']) | ||||
|             utils.update2Ddict(host_config, nodeinfo['bmcip'], 'password', nodeinfo['password']) | ||||
|         return host_config  | ||||
|  | ||||
|     def pre_set_sshcfg(self, *arg, **kw): | ||||
|         self.callback.syslog("Run into pre_set_sshcfg") | ||||
|         local_home_dir=os.path.expanduser('~') | ||||
|         local_ssh_dir = local_home_dir + "/.ssh/" | ||||
|         local_public_key = local_ssh_dir + "id_rsa.pub" | ||||
|         copy_sh_file = local_ssh_dir + "./copy.sh" | ||||
|         tmp_remote_dir = "/tmp/root/.ssh/" | ||||
|         self._create_copy_file(copy_sh_file)  | ||||
|         self.callback.syslog("Generate %s file done" % copy_sh_file) | ||||
|         hosts_config = self._prepare_hosts_cfg(self.inventory) | ||||
|  | ||||
|         self.callback.syslog("Start to run SSH parallelly") | ||||
|         client = ParallelSSHClient(hosts_config.keys(), host_config=hosts_config) | ||||
|         self.callback.syslog("mkdir -p %s" % tmp_remote_dir) | ||||
|         client.run_command("/bin/mkdir -p %s" % tmp_remote_dir) | ||||
|         self.callback.info("Copy files to remote hosts: %s-->%s" % (local_ssh_dir, tmp_remote_dir)) | ||||
|         nodes_copy = client.copy_file(local_ssh_dir, tmp_remote_dir, recurse=True) | ||||
|         try: | ||||
|             joinall(nodes_copy, raise_error=True) | ||||
|         except Exception as e: | ||||
|             self.callback.info("Error: %s" % e) | ||||
|         self.callback.info("run copy.sh") | ||||
|         client.run_command("%s/copy.sh root" %(tmp_remote_dir, ))  | ||||
|         return | ||||
|  | ||||
|     def set_sshcfg(self, **kw): | ||||
|         return self.callback.info("set_sshcfg") | ||||
|         node = kw['node'] | ||||
|         nodeinfo = kw['nodeinfo'] | ||||
|         return self.callback.info("%s: ssh keys copied to %s" %(node, nodeinfo['bmcip'])) | ||||
|  | ||||
|     def set_ipdhcp(self, **kw): | ||||
|         return self.callback.info("set_ipdhcp") | ||||
| @@ -52,8 +114,9 @@ class OpenBMCBmcConfigTask(ParallelNodesCommand): | ||||
|             else: | ||||
|                 self.callback.error("get_attributes can not deal with attr %s" % attr) | ||||
|         if len(netinfo_dict): | ||||
|             self._get_netinfo(netinfo_dict.has_key('ip'), netinfo_dict.has_key('ipsrc'), netinfo_dict.has_key('netmask'), | ||||
|                               netinfo_dict.has_key('gateway'), netinfo_dict.has_key('vlan'), netinfo_dict.has_key('hostname'), **kw) | ||||
|             self._get_netinfo(ip=netinfo_dict.has_key('ip'), ipsrc=netinfo_dict.has_key('ipsrc'), netmask=netinfo_dict.has_key('netmask'), | ||||
|                               gateway=netinfo_dict.has_key('gateway'),vlan= netinfo_dict.has_key('vlan'),  | ||||
|                               hostname=netinfo_dict.has_key('hostname'), **kw) | ||||
|  | ||||
|     def set_attributes(self, attributes, **kw): | ||||
|         netinfo_dict={'vlan':False} | ||||
| @@ -115,18 +178,96 @@ class OpenBMCBmcConfigTask(ParallelNodesCommand): | ||||
|             result = "set net(%s, %s, %s) for eth0" % (ip, netmask, gateway) | ||||
|         return self.callback.info("set_netinfo %s" % result) | ||||
|  | ||||
|     def _get_netinfo(self, ip=False, ipsrc=False, netmask=False, gateway=False, vlan=False, hostname=False, **kw): | ||||
|         result = '' | ||||
|         if ip: | ||||
|             result += "Get IP, " | ||||
|         if netmask: | ||||
|             result += "Get Mask, " | ||||
|         if gateway: | ||||
|             result += "Get Gateway, " | ||||
|         if ipsrc: | ||||
|             result += "Get IP source, " | ||||
|     def _get_and_parse_netinfo(self, **kw): | ||||
|         node = kw['node'] | ||||
|         obmc = openbmc.OpenBMCRest(name=node, nodeinfo=kw['nodeinfo'], messager=self.callback, | ||||
|                                    debugmode=self.debugmode, verbose=self.verbose) | ||||
|         try: | ||||
|             obmc.login() | ||||
|             data = obmc.get_netinfo() | ||||
|         except (SelfServerException, SelfClientException) as e: | ||||
|             self.callback.info('%s: %s' % (node, e.message)) | ||||
|             return | ||||
|         netinfo = {} | ||||
|         for k, v in data.items(): | ||||
|             if k.find("network/config") >= 0: | ||||
|                 if v.has_key("HostName"): | ||||
|                     netinfo["hostname"] = v["HostName"] | ||||
|                 if v.has_key("DefaultGateway"): | ||||
|                     netinfo["defaultgateway"] = v["DefaultGateway"] | ||||
|                 continue | ||||
|             dev,match,netid = k.partition("/ipv4/") | ||||
|             if netid: | ||||
|                 if v["Origin"].find("LinkLocal") >= 0 or v["Address"].startswith("169.254"): | ||||
|                     self.callback.info("%s: Found LinkLocal address %s for interface %s, Ignoring..." % (node, v["Address"], dev)) | ||||
|                     continue | ||||
|                 nicid = dev.split('/')[-1] | ||||
|                 if not netinfo.has_key(nicid): | ||||
|                     netinfo[nicid] = {} | ||||
|                 if netinfo[nicid].has_key("ip"): | ||||
|                     self.callback.error("%s: Another valid ip %s found." % (node, v["Address"])) | ||||
|                     continue | ||||
|                 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"]) | ||||
|                 if data.has_key(dev): | ||||
|                     info = data[dev] | ||||
|                     utils.update2Ddict(netinfo, nicid, "vlanid", info["Id"]) | ||||
|                     utils.update2Ddict(netinfo, nicid, "mac", info["MACAddress"]) | ||||
|                     utils.update2Ddict(netinfo, nicid, "ntpservers", info["NTPServers"]) | ||||
|         self.callback.info("Netinfo: %s" % netinfo)  | ||||
|         return netinfo | ||||
|     def _get_netinfo(self, ip=False, ipsrc=False, netmask=False, gateway=False, vlan=False, hostname=False, ntpserver=True, **kw): | ||||
|         node = kw["node"] | ||||
|         netinfo = self._get_and_parse_netinfo(**kw) | ||||
|         if not netinfo: | ||||
|             return self.callback.error("%s: No network information get" % node) | ||||
|         defaultgateway = "n/a" | ||||
|         bmchostname = "" | ||||
|         if netinfo.has_key("defaultgateway"): | ||||
|             defaultgateway = netinfo["defaultgateway"] | ||||
|             del netinfo["defaultgateway"] | ||||
|         if netinfo.has_key("hostname"): | ||||
|             bmchostname = netinfo["hostname"] | ||||
|             del netinfo["hostname"] | ||||
|  | ||||
|         if hostname: | ||||
|             result += "Get BMC hostname, " | ||||
|             self.callback.info("%s: BMC Hostname: %s" %(node, bmchostname)) | ||||
|         dic_length = len(netinfo)  | ||||
|         self.callback.info("dic_length: %s: %s" %(dic_length, netinfo)) | ||||
|         ip_list = [] | ||||
|         ipsrc_list = [] | ||||
|         netmask_list = [] | ||||
|         gateway_list = [] | ||||
|         vlan_list = [] | ||||
|         ntpserver_list = [] | ||||
|         for nic,attrs in netinfo.items(): | ||||
|             addon_string = '' | ||||
|             if dic_length > 1: | ||||
|                 addon_string = " for %s" % nic | ||||
|             ip_list.append("BMC IP"+addon_string+": %s" % attrs["ip"]) | ||||
|             netmask_list.append("BMC Netmask"+addon_string+": %s" % attrs["netmask"]) | ||||
|             gateway_list.append("BMC Gateway"+addon_string+": %s (default: %s)" % (attrs["gateway"], defaultgateway)) | ||||
|             vlan_list.append("BMC VLAN ID"+addon_string+": %s" % attrs["vlanid"]) | ||||
|             ipsrc_list.append("BMC IP Source"+addon_string+": %s" % attrs["ipsrc"]) | ||||
|             ntpserver_list.append("BMC NTP Servers"+addon_string+": %s" % attrs["ntpservers"]) | ||||
|         if ip: | ||||
|             for i in ip_list: | ||||
|                 self.callback.info("%s: %s" % (node, i)) | ||||
|         if netmask: | ||||
|             for i in netmask_list: | ||||
|                 self.callback.info("%s: %s" % (node, i)) | ||||
|         if gateway: | ||||
|             for i in gateway_list: | ||||
|                 self.callback.info("%s: %s" % (node, i)) | ||||
|         if ipsrc: | ||||
|             for i in ipsrc_list: | ||||
|                 self.callback.info("%s: %s" % (node, i)) | ||||
|         if vlan: | ||||
|             result += "Get BMC vlan." | ||||
|         return self.callback.info("get_netinfo: %s" % result) | ||||
|             for i in vlan_list: | ||||
|                 self.callback.info("%s: %s" % (node, i)) | ||||
|         if ntpserver: | ||||
|             for i in ntpserver_list: | ||||
|                 self.callback.info("%s: %s" % (node, i)) | ||||
|         return | ||||
|   | ||||
| @@ -141,6 +141,15 @@ FIRM_URLS = { | ||||
|     } | ||||
| } | ||||
|  | ||||
| RSPCONFIG_NETINFO_URL = { | ||||
|     'get_netinfo': "/network/enumerate", | ||||
|     'hostname': "/network/config/attr/HostName", | ||||
|     'nic_ip': "/network/#NIC#/action/IP", | ||||
|     'vlan': "/network/action/VLAN", | ||||
|     'ipdhcp': "/network/action/Reset", | ||||
|     'ntpserver': "/network/#NIC#/attr/NTPServers", | ||||
| } | ||||
|  | ||||
| RSPCONFIG_APIS = { | ||||
|     'autoreboot' : { | ||||
|         'baseurl': "/control/host0/auto_reboot/", | ||||
| @@ -511,6 +520,9 @@ class OpenBMCRest(object): | ||||
|             data={"data": attr_info['get_data']} | ||||
|         return self.request(method, get_url, payload=data, cmd="get_%s" % key) | ||||
|  | ||||
|     def get_netinfo(self): | ||||
|         return self.request('GET', RSPCONFIG_NETINFO_URL['get_netinfo'], cmd="get_netinfo") | ||||
|  | ||||
| class OpenBMCImage(object): | ||||
|     def __init__(self, rawid, data=None): | ||||
|         self.id = rawid.split('/')[-1] | ||||
|   | ||||
		Reference in New Issue
	
	Block a user