def reconnect(self, timeout=30): try: self.ssh.connect(self.host_ip, self.host_port, self.host_username, self.host_pwd, timeout=timeout) self.transport = self.ssh.get_transport() self.transport.use_compression(self.compression) except socket.error as err: self.transport = None logger.error("Failed to connect {host}: {err}".format( host=self.host_ip, err=err)) except paramiko.ssh_exception.BadAuthenticationType as err: self.transport = None logger.error("Failed to connect {host}: {err}".format( host=self.host_ip, err=err)) except paramiko.ssh_exception.AuthenticationException as err: logger.error("Failed to connect {host}: {err}".format( host=self.host_ip, err=err)) except paramiko.ssh_exception.BadHostKeyException as err: logger.error("Failed to connect {host}: {err}".format( host=self.host_ip, err=err)) except Exception as ex: logger.error("Failed to connect {host}: {err}".format( host=self.host_ip, ex=ex)) return self.transport is not None
def main_loop(self): rlist = [] rlist.append(self.__pipe.inform) timeout = 10 try: while self.__running: readable, _, _ = select.select(rlist, [], [], timeout) if not readable: continue if self.__pipe.inform in readable: try: message = self.__pipe.read(256) except OSError, exc: logger.warn("[Error %d] appeared at reading pipe" % exc.errno) continue if len(message) == 0: continue self.handle_message(message) except KeyboardInterrupt: logger.error("Break by user.") except Exception, ex: logger.error("{0}: {1}".format(sys._getframe().f_code.co_name, ex))
def query_oid_val(self, oid): ''' Query value for oid ''' # Lookup in cache file first value = self.__query_oid_in_cachefile(oid) if value != "": return value # Lookup in snmprec file # open file try: fdh = open(self.__sim_file, 'rw') while True: line = fdh.readline() if not line: break # oid-type-value record_list = line.strip(os.linesep).split('|') if record_list[0] == oid: fdh.close() if "value" in record_list[2]: val = record_list[2].split(',')[0].split( '=')[1].strip() else: val = record_list[2] return val except IOError as e: print e logger.error("Not found oid %s" % oid) return ""
def query_oid_val(self, oid): ''' Query value for oid ''' # Lookup in cache file first value = self.__query_oid_in_cachefile(oid) if value != "": return value # Lookup in snmprec file # open file try: fdh = open(self.__sim_file, 'rw') while True: line = fdh.readline() if not line: break # oid-type-value record_list = line.strip(os.linesep).split('|') if record_list[0] == oid: fdh.close() if "value" in record_list[2]: val = record_list[2].split(',')[0].split('=')[1].strip() else: val = record_list[2] return val except IOError as e: print e logger.error("Not found oid %s" % oid) return ""
def send_command(self, cmd): logger.info("Executing command: {0}".format(cmd)) if self.transport is None or self.transport.is_active() is False: self.reconnect() if self.transport is None or self.transport.is_active() is False: logger.error("Connection not established failed.") return -1, None try: session = self.transport.open_session() session.set_combine_stderr(True) session.get_pty() session.invoke_shell() if session.send_ready(): index = 0 input_data = self.__fix_indata(cmd) if index < len(input_data): data = input_data[index] + '\n' index += 1 session.send(data) else: logger.warn("session is not ready for send") except paramiko.SSHException as ex: logger.error("Exception for command '{0}: {1}'".format(cmd, ex)) session.close() return -1, None output = self.poll(session) status = session.recv_exit_status() # send quit to notify server shutdown the channel session.send("quit\n") logger.info("Returned status {0}".format(status)) session.close() return status, output
def update_snmprec_file(self, oid, val): old_file = os.path.join(self.config_instance.snmp_data_dir, "public.snmprec") new_file = os.path.join(self.config_instance.snmp_data_dir, "new.snmprec") logger.info("update oid %s, val %s" % (oid, str(val))) # open file try: old_fdh = open(old_file, 'r') new_fdh = open(new_file, 'w') while True: line = old_fdh.readline() if not line: break record_list = line.strip(os.linesep).split('|') if record_list[0] == oid: record_list[2] = val new_line = '|'.join(["%s" % x for x in record_list]) new_fdh.write(new_line + os.linesep) else: new_fdh.write(line) except IOError as e: logger.error("Exception in updating snmprec file, exception: {}". format(e)) return new_fdh.close() old_fdh.close() os.rename(new_file, old_file)
def start(self): if not os.path.exists('/usr/bin/snmpsimd.py') \ and not os.path.exists('/bin/snmpsimd.py') \ and not os.path.exists('/usr/local/bin/snmpsimd.py'): logger.error("snmpsimd.py does not exist!") return -1 if self.__alive(): self.stop() if not os.path.exists("/var/run/snmpsim"): os.mkdir("/var/run/snmpsim") if not os.path.exists("/var/log/snmpsim"): os.mkdir("/var/log/snmpsim") data_dir = self.__config_instance.snmp_data_dir db_path = os.path.join(data_dir, self.__config_instance.db_file) args_list = ["snmpsimd.py"] endpoint_param = "--agent-udpv4-endpoint=0.0.0.0" args_list.append(endpoint_param) process_user = "******" args_list.append(process_user) process_group = "--process-group=root" args_list.append(process_group) logging_option = "--logging-method=file:/var/log/snmpsim/snmpsimd.log" args_list.append(logging_option) pid_option = "--pid-file=" + snmpsim_pid_file args_list.append(pid_option) daemonize_option = "--daemonize" args_list.append(daemonize_option) data_dir_option = "--data-dir=" + data_dir args_list.append(data_dir_option) if self.__db_type == "SQLITE": variation_modules_dir = "--variation-modules-dir=" + \ self.__config_instance.variation_modules_dir args_list.append(variation_modules_dir) sql_option = "--variation-module-options=sql:dbtype:sqlite3,database:" + db_path args_list.append(sql_option) elif self.__db_type == "WRITECACHE": writecache_option = "--variation-module-options=writecache:file:" + db_path args_list.append(writecache_option) else: return -1 logger.info("Start snmpsimd service for {0}.".format(self.__pdu_name)) logger.info(' '.join(args_list)) retcode = subprocess.call(args_list) if retcode != 0: return -1 time.sleep(1) pid = self.getpid() if pid < 0: logger.error("Failed to start snmpsim service!") return -1 logger.info("Succeed to start snmpsim service, pid: %d." % pid) return 0
def main_loop(self): rlist = [] rlist.append(self.__pipe.inform) timeout = 10 print "Total threads: {0}".format(threading.activeCount()) try: while self.__running: readable, _, _ = select.select(rlist, [], [], timeout) if not readable: continue if self.__pipe.inform in readable: try: message = self.__pipe.read(256) except OSError, exc: logger.warn("[Error %d] appeared at reading pipe" % exc.errno) continue if len(message) == 0: continue pdu_id = message.split()[0].split('.')[-2] pdu_index = self.to_index(int(pdu_id)) logger.info("Assign message to pdu {0}".format(pdu_id)) self.__pdus[pdu_index].handle_message(message) except KeyboardInterrupt: logger.error("Break by user.") except Exception, ex: logger.error("{0}: {1}".format(sys._getframe().f_code.co_name, ex))
def update(self): self.__config_parser.read(self.host_conf) try: for s in self.__config_parser.sections(): if s.upper() == "PDU": if self.__config_parser.has_option(s, "name"): self.__config_parser.set(s, "name", self.__pdu_name) if self.__config_parser.has_option(s, "dbtype"): self.__config_parser.set(s, "dbtype", self.__db_type) if self.__config_parser.has_option(s, "database"): self.__config_parser.set(s, "database", self.__db_file) if self.__config_parser.has_option(s, "snmpdata"): self.__config_parser.set(s, "snmpdata", self.__snmp_data_dir) elif s.upper() == "ESXIHOST": self.__config_parser.set(s, "host", self.__esxi_info['host']) self.__config_parser.set(s, "username", self.__esxi_info['username']) self.__config_parser.set(s, "password", self.__esxi_info['password']) if self.__esxi_info is not None: if not self.__config_parser.has_section("esxihost"): self.__config_parser.add_section("esxihost") self.__config_parser.set("esxihost", "host", self.__esxi_info['host']) self.__config_parser.set("esxihost", "username", self.__esxi_info['username']) self.__config_parser.set("esxihost", "password", self.__esxi_info['password']) self.__config_parser.write(open(self.host_conf, "w")) except Exception as ex: logger.error("Exception: {0}".format(ex))
def update_snmprec_file(self, oid, val): old_file = os.path.join(self.config_instance.snmp_data_dir, "public.snmprec") new_file = os.path.join(self.config_instance.snmp_data_dir, "new.snmprec") logger.info("update oid %s, val %s" % (oid, str(val))) # open file try: old_fdh = open(old_file, 'r') new_fdh = open(new_file, 'w') while True: line = old_fdh.readline() if not line: break record_list = line.strip(os.linesep).split('|') if record_list[0] == oid: record_list[2] = val new_line = '|'.join(["%s" % x for x in record_list]) new_fdh.write(new_line + os.linesep) else: new_fdh.write(line) except IOError as e: logger.error( "Exception in updating snmprec file, exception: {}".format(e)) return new_fdh.close() old_fdh.close() os.rename(new_file, old_file)
def delete(self): self.__config_parser.read(self.host_conf) try: self.__esxi_info = None self.__config_parser.remove_section("esxihost") self.__config_parser.write(open(self.host_conf, "w")) except Exception as ex: logger.error("Exception: {0}".format(ex))
def set_conf_instance(instance): global _conf_instance if not isinstance(instance, Config): logger.error("{0} is not Config object.".format(instance)) return if _conf_instance: return _conf_instance = instance
def set_ip_address(ifname, ip): try: s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) bin_ip = socket.inet_aton(ip) ifreq = struct.pack('16sH2s4s8s', ifname, socket.AF_INET, '\x00'*2, bin_ip, '\x00'*8) fcntl.ioctl(s, SIOCSIFADDR, ifreq) s.close() except: logger.error("Failed to set ip %s on %s" % (ip, ifname)) print "Failed to set ip %s on %s" % (ip, ifname)
def get_ip_address(ifname): try: s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) ifreq = struct.pack('16sH14s', ifname, AF_UNIX, '\x00'*14) res = fcntl.ioctl(s.fileno(), SIOCGIFADDR, ifreq) ip = struct.unpack('16sH2x4s8x', res)[2] s.close() return socket.inet_ntoa(ip) except: logger.error("Failed to get ip on %s" % ifname) return ""
def write_password(pdu, port, password): _content = '' try: matched = False password_file = config.get_conf_instance().password_file fd = open(password_file, 'r+') lines = fd.readlines() fd.close() for line in lines: # Ignore blank line if line == os.linesep: _content += line continue # Ignore comments which begins with '#' result_obj = re.search(r"^#.*", line) if result_obj: _content += line continue l = line.split(':') # If the password is already in configuration file, then update it. if pdu == int(l[1]) and port == int(l[2]): matched = True # Update password line = ':'.join([str(time.time()), str(pdu), str(port), str(password)]) line += os.linesep logger.info("Update password %s for PDU %d port %d" % (password, pdu, port)) _content += line # If the pdu and port have not been assigned a password, # then added the password if not matched: new_line = ':'.join([str(time.time()), str(pdu), str(port), str(password)]) new_line += os.linesep _content = _content + new_line logger.info("Add password %s for PDU %d port %d" % (password, pdu, port)) # Write the password settings back to the configuration file fd = open(config.get_conf_instance().password_file, 'w') fd.writelines(_content) fd.close() except IOError as e: logger.error("Error in open password file.exception: {}".format(e))
def handle_outlet(self, args): ''' 1. Get current outlet state 2. Get the current outlet action ''' # self.logger.info("handle outlet {0}/{1}".format(outlet, self.pdu)) outlet = args[0] action = args[1] logger.info("handle outlet {0}/{1}, action: {2}" .format(outlet, self.pdu, self.actions[int(action)])) vmname = self.__node_control_handler.get_node_name(1, int(outlet)) if vmname is None: self.set_outlet_field(self.outlet_action_oid_offset, outlet, 0) logger.error("No virtual node found for outlet {0}".format(outlet)) return datastore = self.__node_control_handler.get_node_datastore(vmname) if datastore is None: self.set_outlet_field(self.outlet_action_oid_offset, outlet, 0) logger.error("No datastore found for virtual node {0}" .format(vmname)) return # action = self.get_outlet_field(self.outlet_action_oid_offset, outlet) state = self.get_outlet_field(self.outlet_state_oid_offset, outlet) if self.actions[int(action)] == 'none' or \ self.actions[int(action)] == self.states[int(state)]: logger.warn("No need to execute the action: {}" .format(self.actions[int(action)])) return # restore the action default to "none" if self.actions[int(action)] == 'on': # 'on' state self.set_outlet_field(self.outlet_state_oid_offset, outlet, 5) status = self.__node_control_handler.power_on_node(datastore, vmname) elif self.actions[int(action)] == 'off': # 'off' state self.set_outlet_field(self.outlet_state_oid_offset, outlet, 4) status = self.__node_control_handler.power_off_node(datastore, vmname) elif self.actions[int(action)] == 'reboot': # 'off' state self.set_outlet_field(self.outlet_state_oid_offset, outlet, 8) status = self.__node_control_handler.reboot_node(datastore, vmname) # 'on' state self.set_outlet_field(self.outlet_state_oid_offset, outlet, 5) else: logger.error("Unknown action: {0}".format(action)) return if status != 0: logger.error("Failed to {0} virtual node." .format(self.actions[int(action)])) return self.set_outlet_field(self.outlet_action_oid_offset, outlet, 0)
def update_oid_val(self, oid, val): ''' Update value for oid ''' if not os.path.exists(self.__db_file): logger.error("Database %s does not exist!" % self.__db_file) sys.exit(1) # open db conn = sqlite3.connect(self.__db_file) cur = conn.cursor() sql_oid = '.'.join(['%10s' % x for x in str(oid).split('.')]) update_statement = 'update %s set value = \'%s\' where oid=\'%s\'' % \ (self.config_instance.default_table_name, val, sql_oid) cur.execute(update_statement) conn.commit() conn.close()
def query_oid_val(self, oid): ''' Query value for oid ''' if not os.path.exists(self.__db_file): logger.error("Database %s does not exist!" % self.__db_file) sys.exit(1) # open db conn = sqlite3.connect(self.__db_file) cur = conn.cursor() sql_oid = '.'.join(['%10s' % x for x in str(oid).split('.')]) query_statement = 'select value from %s where oid=\'%s\'' % \ (self.config_instance.default_table_name, sql_oid) cur.execute(query_statement) resultset = cur.fetchone() conn.close() if resultset: return resultset[0]
def run(self): while self.__running: try: task_name, func, args = self.__tasks_queue.get() logger.info("Running task ... {peachblow}{task_name}{normal} \ on thread {threadname}". format(peachblow=colors.PEACHBLOW, task_name=task_name, normal=colors.NORMAL, threadname=self.getName())) func(args) self.__tasks_queue.task_done() logger.info("{cyan}{task_name}{normal} Done". format(cyan=colors.CYAN, task_name=task_name, normal=colors.NORMAL)) except Exception, ex: logger.error("{0}: {1}". format(sys._getframe().f_code.co_name, ex))
def __update_oid_in_cachefile(self, oid, val): found = False try: s = shelve.open(self.__cache_file, "rw", writeback=True) for key in s.keys(): if oid == key: found = True break if found: s[key] = rfc1902.Integer(val, s[key].getTagSet(), s[key].getSubtypeSpec(), s[key].getNamedValues()) else: s[oid] = rfc1902.Integer(val) s.sync() s.close() except: logger.error("Update oid in cachefile failed.")
def run(self): while self.__running: try: task_name, func, args = self.__tasks_queue.get() logger.info("Running task ... {peachblow}{task_name}{normal} \ on thread {threadname}".format( peachblow=colors.PEACHBLOW, task_name=task_name, normal=colors.NORMAL, threadname=self.getName())) func(args) self.__tasks_queue.task_done() logger.info("{cyan}{task_name}{normal} Done".format( cyan=colors.CYAN, task_name=task_name, normal=colors.NORMAL)) except Exception, ex: logger.error("{0}: {1}".format(sys._getframe().f_code.co_name, ex))
def init(self): self.__cf.read(self.__pdu_mapping) for section in self.__cf.sections(): vm_list = {} vm_list[section] = [] for option in self.__cf.options(section): try: node_info = {} pdu_port_list = self.__cf.get(section, option).split('.') node_info['node_name'] = option node_info['control_pdu'] = int(pdu_port_list[0]) node_info['control_port'] = int(pdu_port_list[1]) vm_list[section].append(node_info) except Exception as ex: logger.error("Exception: {0}".format(ex)) continue self.__nodes_control_list.append(vm_list)
def handle_command(self, script): """ Handle the command receive from user.""" if self.WELCOME: script.writeline(self.WELCOME) status = 0 channel = script.fileobj.channel while self.__running: self.response = '' script.write(self.prompt) groups = script.expect(re.compile('(?P<input>.*)')).groupdict() try: cmdline = groups['input'].encode('ascii', 'ignore').strip() except: continue if not cmdline or len(cmdline) == 0: continue cmd = cmdline.split()[0] if cmd.upper() == 'EXIT' \ or cmd.upper() == 'QUIT': script.writeline("Quit!") break params = [] params = cmdline.split()[1:] try: self.commands[cmd.upper()](params) except Exception as ex: logger.error("Command '{0}' failed: {1}".format(cmd, ex)) self.commands['HELP']() status = 127 if len(self.response): lines = self.response.split('\n') for line in lines: script.writeline(line) channel.send_exit_status(status)
def handle_outlet(self, args): outlet = args[0] action = args[1] logger.info("handle outlet {0}/{1}, action: {2}". format(outlet, self.pdu, self.actions[int(action)])) on_offset = self.pduouton_oid_offset + "." + str(self.to_pdu(self.pdu)) action_in_oid = self.extract(self.get_outlet_field(on_offset, outlet)) logger.warn("action: {0}, action_in_oid: {1}". format(self.actions[int(action)], self.actions[int(action_in_oid)])) vmname = self.__node_control_handler.get_node_name(int(self.pdu), int(outlet)) if vmname is None: logger.error("No virtual node found for outlet {0}".format(outlet)) return datastore = self.__node_control_handler.get_node_datastore(vmname) if datastore is None: logger.error("No datastore found for virtual node {0}". format(vmname)) return # Make sure the action as the last one logger.info("last action: {0}, current action: {1}". format(self.action_list[int(outlet) - 1], self.actions[int(action)])) if self.action_list[int(outlet) - 1] == self.actions[int(action)]: logger.warn("No need to execute action for {0}/{1}". format(outlet, self.pdu)) return if self.actions[int(action)] == 'on': status = self.__node_control_handler.power_on_node(datastore, vmname) elif self.actions[int(action)] == 'off': status = self.__node_control_handler.power_off_node(datastore, vmname) elif self.actions[int(action)] == 'reboot': status = self.__node_control_handler.reboot(datastore, vmname) else: logger.error("Unknown action: {0}".format(action)) if status != 0: logger.error("Failed to {0} virtual node.". format(self.actions[int(action)])) return self.action_list[int(outlet) - 1] = self.actions[int(action)]
def __init__(self): ''' Constructor ''' super(VMwareHandler, self).__init__() self.__host_ip = None self.__username = None self.__password = None self.set_esxi_host_info() if self.__host_ip is not None: self.__ssh = sshclient.SSH(self.__host_ip, self.__username, self.__password) self.__ssh.connect() if self.__ssh.connected() is False: logger.error("Connection error for {0}@{1}". format(self.__username, self.__host_ip)) else: logger.info("Connection ok for {0}@{1}". format(self.__username, self.__host_ip)) else: logger.warn("ESXi is not set in configuration file.")
def __init__(self): ''' Constructor ''' super(VMwareHandler, self).__init__() self.__host_ip = None self.__username = None self.__password = None self.set_esxi_host_info() if self.__host_ip is not None: self.__ssh = sshclient.SSH(self.__host_ip, self.__username, self.__password) self.__ssh.connect() if self.__ssh.connected() is False: logger.error("Connection error for {0}@{1}".format( self.__username, self.__host_ip)) else: logger.info("Connection ok for {0}@{1}".format( self.__username, self.__host_ip)) else: logger.warn("ESXi is not set in configuration file.")
def init(self): self.__config_parser.read(self.host_conf) try: for s in self.__config_parser.sections(): if s.upper() == "ESXIHOST": self.__esxi_info = \ {"host": self.__config_parser.get(s, "host"), "username": self.__config_parser.get(s, "username"), "password": self.__config_parser.get(s, "password")} elif s.upper() == "PDU": if self.__config_parser.has_option(s, "name"): self.__pdu_name = \ self.__config_parser.get(s, "name").upper() if self.__config_parser.has_option(s, "dbtype"): self.__db_type = \ self.__config_parser.get(s, "dbtype").upper() if self.__config_parser.has_option(s, "database"): self.__db_file = self.__config_parser.get(s, "database") if self.__config_parser.has_option(s, "snmpdata"): self.__snmp_data_dir = \ self.__config_parser.get(s, "snmpdata") if self.__config_parser.has_option(s, "simfile"): self.__sim_file = self.__config_parser.get(s, "simfile") except ConfigParser.NoSectionError: logger.error("No section %s" % s) except ConfigParser.NoOptionError: logger.error("No option host or username or password") except ConfigParser.DuplicateSectionError: logger.error("Duplicate section %s" % s)
def handle_outlet(self, args): outlet = args[0] action = args[1] logger.info("handle outlet {0}/{1}, action: {2}".format( outlet, self.pdu, self.actions[int(action)])) on_offset = self.pduouton_oid_offset + "." + str(self.to_pdu(self.pdu)) action_in_oid = self.extract(self.get_outlet_field(on_offset, outlet)) logger.warn("action: {0}, action_in_oid: {1}".format( self.actions[int(action)], self.actions[int(action_in_oid)])) vmname = self.__node_control_handler.get_node_name( int(self.pdu), int(outlet)) if vmname is None: logger.error("No virtual node found for outlet {0}".format(outlet)) return datastore = self.__node_control_handler.get_node_datastore(vmname) if datastore is None: logger.error( "No datastore found for virtual node {0}".format(vmname)) return # Make sure the action as the last one logger.info("last action: {0}, current action: {1}".format( self.action_list[int(outlet) - 1], self.actions[int(action)])) if self.action_list[int(outlet) - 1] == self.actions[int(action)]: logger.warn("No need to execute action for {0}/{1}".format( outlet, self.pdu)) return if self.actions[int(action)] == 'on': status = self.__node_control_handler.power_on_node( datastore, vmname) elif self.actions[int(action)] == 'off': status = self.__node_control_handler.power_off_node( datastore, vmname) elif self.actions[int(action)] == 'reboot': status = self.__node_control_handler.reboot(datastore, vmname) else: logger.error("Unknown action: {0}".format(action)) if status != 0: logger.error("Failed to {0} virtual node.".format( self.actions[int(action)])) return self.action_list[int(outlet) - 1] = self.actions[int(action)]
def power_off_node(self, *args): ''' Power off VM with ESXi CLI ''' datastore = args[0] vmname = args[1] logger.info("Power off " + datastore + "/" + vmname + "...") command = self.__build_command(datastore, vmname, "getstate") status, ret = self.__execute_command(command) if status != 0: logger.error("Command failed, status : {0}".format(status)) return status if "off" in ret: logger.info("%s already is off." % vmname) return 0 command = self.__build_command(datastore, vmname, "off") status, ret = self.__execute_command(command) if status != 0: logger.error("Command failed, status : {0}".format(status)) return status logger.info(ret.strip()) return 0
def reconnect(self, timeout=30): try: self.ssh.connect(self.host_ip, self.host_port, self.host_username, self.host_pwd, timeout=timeout) self.transport = self.ssh.get_transport() self.transport.use_compression(self.compression) except socket.error as err: self.transport = None logger.error("Failed to connect {host}: {err}". format(host=self.host_ip, err=err)) except paramiko.ssh_exception.BadAuthenticationType as err: self.transport = None logger.error("Failed to connect {host}: {err}". format(host=self.host_ip, err=err)) except paramiko.ssh_exception.AuthenticationException as err: logger.error("Failed to connect {host}: {err}". format(host=self.host_ip, err=err)) except paramiko.ssh_exception.BadHostKeyException as err: logger.error("Failed to connect {host}: {err}". format(host=self.host_ip, err=err)) except Exception as ex: logger.error("Failed to connect {host}: {err}". format(host=self.host_ip, ex=ex)) return self.transport is not None
def exec_command(self, cmd, indata=None, timeout=30): logger.info("Executing command: {0}".format(cmd)) if self.transport is None or self.transport.is_active() is False: self.reconnect() if self.transport is None or self.transport.is_active() is False: logger.error("connection failed.") return -1, None input_data = self.__fix_indata(indata) try: session = self.transport.open_session() session.set_combine_stderr(True) session.get_pty() session.exec_command(cmd) except paramiko.SSHException as ex: logger.error("Exception for command '{0}: {1}'".format(cmd, ex)) session.close() return -1, None output = self.poll(session, timeout, input_data) status = session.recv_exit_status() logger.info("Returned status {0}".format(status)) session.close() return status, output
def read_password(pdu, port): try: password_file = config.get_conf_instance().password_file fd = open(password_file, 'r') while True: line = fd.readline() if not line: break # Ignore blank line if line == os.linesep: continue # Ignore comments which begins with "#" result_obj = re.search(r"^#.*", line) if result_obj: continue # The format should be: # <timestamp> <pdu number> <pdu port> <password> l = line.strip(os.linesep).split(':') try: lpdu = int(l[1]) lport = int(l[2]) except ValueError: logger.error("Converting int or float error from string.") return "" password = l[3] if lpdu == pdu and lport == port: fd.close() logger.info("Return password %s for PDU %d port %d" % (password, pdu, port)) return password fd.close() logger.error("Not found password for PDU %d port %d" % (pdu, port)) return "" except IOError as e: logger.error("Error in open password file.exception: {}".format(e)) return ""
def init(self): self.__config_parser.read(self.host_conf) try: for s in self.__config_parser.sections(): if s.upper() == "ESXIHOST": self.__esxi_info = \ {"host": self.__config_parser.get(s, "host"), "username": self.__config_parser.get(s, "username"), "password": self.__config_parser.get(s, "password")} elif s.upper() == "PDU": if self.__config_parser.has_option(s, "name"): self.__pdu_name = \ self.__config_parser.get(s, "name").upper() if self.__config_parser.has_option(s, "dbtype"): self.__db_type = \ self.__config_parser.get(s, "dbtype").upper() if self.__config_parser.has_option(s, "database"): self.__db_file = self.__config_parser.get( s, "database") if self.__config_parser.has_option(s, "snmpdata"): self.__snmp_data_dir = \ self.__config_parser.get(s, "snmpdata") if self.__config_parser.has_option(s, "simfile"): self.__sim_file = self.__config_parser.get( s, "simfile") except ConfigParser.NoSectionError: logger.error("No section %s" % s) except ConfigParser.NoOptionError: logger.error("No option host or username or password") except ConfigParser.DuplicateSectionError: logger.error("Duplicate section %s" % s)
def command_config(self, params): '''<esxi|pdu> [<list/update/add/delete> | <set/get>] [<param.1> ... < param.n>] configure vPDU ---------------------------------- config pdu set <name> - set PDU name e.g. config pdu set hawk config pdu set database <database file> - set pdu database file name e.g. config pdu set database ipia.db config pdu set datadir <snmp data dir> - set snmp data directory name e.g. config pdu set datadir hawk config pdu list -list pdu configurations config esxi -------------------------------------- config esxi list - list configuration config esxi update <option name> <value> - update configuration e.g. Update esxi ip address in configuration file, run below command: config esxi update host 10.62.59.124 Update esxi host "username" config esxi update uesrname root Update esxi host "password" config esxi update password root config esxi add <host> <uesrname> <password> - add configuration e.g. Add an ESXi host information including ip, username and passowrd config esxi add 10.62.59.128 root 1234567 config esxi delete - delete configuration e.g. Delete section "esxihost" config esxi delete esxihost Note: After update/add the configuration, please run 'config list' to be sure that the changes you made are correct. ''' if len(params) == 0: return if params[0] == "pdu": if params[1] == 'set': if params[2] == 'name': self.config_instance.pdu_name = params[3] elif params[2] == 'database': self.config_instance.db_file = params[3] elif params[2] == 'datadir': self.config_instance.snmp_data_dir = params[3] self.config_instance.update() elif params[1] == 'get': self.config_instance.init() table = Texttable() table.add_row(['name', self.config_instance.pdu_name]) table.add_row(['database', self.config_instance.db_file]) table.add_row(['snmp data dir', self.config_instance.snmp_data_dir]) table_str = table.draw() self.writeresponse(table_str) logger.info("\n" + table_str) else: logger.error("Unknown command {0}".format(params[0])) elif params[0] == "esxi": if params[1] == "list": self.config_instance.init() esxi_info = self.config_instance.esxi_info if esxi_info is not None: table = Texttable() table.header(["esxi host", "username", "password"]) table.add_row([ get_color_string(bcolors.GREEN, esxi_info['host']), get_color_string(bcolors.GREEN, esxi_info["username"]), get_color_string(bcolors.GREEN, esxi_info['password']) ]) table_str = table.draw() self.writeresponse(table_str) logger.info("\n" + table_str) return else: self.writeresponse("%sNo ESXi host info in configuration \ file.%s" % (colors.RED, colors.NORMAL)) elif params[1] == "update": if len(params[2:]) == 2: esxi_info = self.config_instance.esxi_info if esxi_info is not None: esxi_info[params[2]] = params[3] self.config_instance.update() else: self.writeresponse("%sNo %s found in configuration \ file.%s" % (colors.RED, params[1], colors.NORMAL)) elif params[1] == "add": if len(params[2:]) != 3: return if self.config_instance.esxi_info is None: esxi_info = {} logger.info("Adding esxi host: {0}, {1}, {2}" .format(params[2], params[3], params[4])) esxi_info['host'] = params[2] esxi_info['username'] = params[3] esxi_info['password'] = params[4] self.config_instance.esxi_info = esxi_info self.config_instance.update() else: self.writeresponse("ESXi info already exists.") elif params[1] == "delete": if self.config_instance.esxi_info is not None: self.config_instance.delete() else: self.writeresponse("ESXi info already deleted.") else: self.writeresponse("unknown parameters.") else: self.writeresponse("unknown parameters: {0}.".format(params[0]))
sys.exit(1) if daemon: pdusim.common.daemon.daemonize(server_pid_file) init_signal() # report_ip_thread = threading.Thread(target = pdusim.reportip.rptClient) # report_ip_thread.start() # Find the conf home dir for dir in install_data_dir: path = os.path.join(dir, 'conf', 'host.conf') if os.path.exists(path): config_home_dir = dir break if config_home_dir == "": logger.error("Cann't find conf dir.") sys.exit(1) conf = config.Config(config_home_dir) config.set_conf_instance(conf) mapping_file.set_mapping_file_handle( mapping_file.MappingFileHandle(config_home_dir) ) logger.info("Server started") server = vPDUHandler() server.serve_forever()
def command_ip(self, params): ''' [<set/get/link>] [<param.1> ... <param.n>] set/get interface IP address link up/down will bring up/down interface link. ip set <intf> <addr> <netmask> e.g.: Set enp0s8 address to 10.0.1.2 ip set enp0s8 10.0.1.2 255.255.255.0 ip get <intf> e.g.: Get enp0s8 address ip get enp0s8 The output will be: ip address: 10.0.1.2, netmask: 255.255.255.0 ip link list - list all avaialbe ethernet interfaces ip link <intf> status - Get specific interface link status ip link <intf> up - Bring up link for interface ip link <intf> down - Bring down link for interface ''' if len(params) == 0: return ifname_list = get_net_interfaces() if params[0] == 'link': if params[1] == 'list': self.writeresponse( colors.CYAN + "Available interfaces:" + colors.NORMAL ) self.writeresponse( colors.RED + ' '.join(ifname_list) + colors.NORMAL ) return else: ifname = params[1] if ifname not in ifname_list: logger.error("%s not exists." % ifname) self.writeresponse("%s%s not exists.%s" % (colors.RED, ifname, colors.NORMAL)) return subcmd = params[2] if subcmd == 'up': link_up(ifname) elif subcmd == 'down': link_down(ifname) elif subcmd == 'status': ret = link_status(ifname) if ret: self.writeresponse("%s link up" % ifname) else: self.writeresponse("%s link down" % ifname) else: logger.error("unknown parameters.") else: ifname = params[1] if ifname not in ifname_list: logger.error("%s not exists." % ifname) self.writeresponse("%s%s not exists.%s" % (colors.RED, ifname, colors.NORMAL)) return if params[0] == 'get': ip_address = get_ip_address(ifname) netmask = get_netmask(ifname) self.writeresponse( colors.GREEN + "ip address: " + ip_address + ", " + "netmask: " + convert_int_to_ip(get_netmask_int(netmask)) + colors.NORMAL ) elif params[0] == 'set': set_ip_address(ifname, params[2]) if len(params) > 3: netmask = params[3] int_netmask = convert_ip_to_int(netmask) set_netmask(ifname, get_mask(int_netmask)) status = link_status(ifname) if not status: link_up(ifname) else: logger.error("unknown parameters.")
def command_config(self, params): '''<esxi|pdu> [<list/update/add/delete> | <set/get>] [<param.1> ... < param.n>] configure vPDU ---------------------------------- config pdu set <name> - set PDU name e.g. config pdu set hawk config pdu set database <database file> - set pdu database file name e.g. config pdu set database ipia.db config pdu set datadir <snmp data dir> - set snmp data directory name e.g. config pdu set datadir hawk config pdu list -list pdu configurations config esxi -------------------------------------- config esxi list - list configuration config esxi update <option name> <value> - update configuration e.g. Update esxi ip address in configuration file, run below command: config esxi update host 10.62.59.124 Update esxi host "username" config esxi update uesrname root Update esxi host "password" config esxi update password root config esxi add <host> <uesrname> <password> - add configuration e.g. Add an ESXi host information including ip, username and passowrd config esxi add 10.62.59.128 root 1234567 config esxi delete - delete configuration e.g. Delete section "esxihost" config esxi delete esxihost Note: After update/add the configuration, please run 'config list' to be sure that the changes you made are correct. ''' if len(params) == 0: return if params[0] == "pdu": if params[1] == 'set': if params[2] == 'name': self.config_instance.pdu_name = params[3] elif params[2] == 'database': self.config_instance.db_file = params[3] elif params[2] == 'datadir': self.config_instance.snmp_data_dir = params[3] self.config_instance.update() elif params[1] == 'get': self.config_instance.init() table = Texttable() table.add_row(['name', self.config_instance.pdu_name]) table.add_row(['database', self.config_instance.db_file]) table.add_row(['snmp data dir', self.config_instance.snmp_data_dir]) table_str = table.draw() self.writeresponse(table_str) logger.info("\n" + table_str) elif params[1] == 'list': self.config_instance.init() table = Texttable() table.add_row(['pdu name', self.config_instance.pdu_name]) table.add_row(['dbtype', self.config_instance.db_type]) table.add_row(['database', self.config_instance.db_file]) table.add_row(['snmpdata', self.config_instance.snmp_data_dir]) table.add_row(['simfile', self.config_instance.sim_file]) table_str = table.draw() self.writeresponse(table_str) logger.info("\n" + table_str) else: logger.error("Unknown command {0}".format(params[0])) elif params[0] == "esxi": if params[1] == "list": self.config_instance.init() esxi_info = self.config_instance.esxi_info if esxi_info is not None: table = Texttable() table.header(["esxi host", "username", "password"]) table.add_row([ get_color_string(bcolors.GREEN, esxi_info['host']), get_color_string(bcolors.GREEN, esxi_info["username"]), get_color_string(bcolors.GREEN, esxi_info['password']) ]) table_str = table.draw() self.writeresponse(table_str) logger.info("\n" + table_str) return else: self.writeresponse("%sNo ESXi host info in configuration \ file.%s" % (colors.RED, colors.NORMAL)) elif params[1] == "update": if len(params[2:]) == 2: esxi_info = self.config_instance.esxi_info if esxi_info is not None: esxi_info[params[2]] = params[3] self.config_instance.update() else: self.writeresponse("%sNo %s found in configuration \ file.%s" % (colors.RED, params[1], colors.NORMAL)) elif params[1] == "add": if len(params[2:]) != 3: return if self.config_instance.esxi_info is None: esxi_info = {} logger.info("Adding esxi host: {0}, {1}, {2}" .format(params[2], params[3], params[4])) esxi_info['host'] = params[2] esxi_info['username'] = params[3] esxi_info['password'] = params[4] self.config_instance.esxi_info = esxi_info self.config_instance.update() else: self.writeresponse("ESXi info already exists.") elif params[1] == "delete": if self.config_instance.esxi_info is not None: self.config_instance.delete() else: self.writeresponse("ESXi info already deleted.") else: self.writeresponse("unknown parameters.") else: self.writeresponse("unknown parameters: {0}.".format(params[0]))
def command_vpdu(self, params): '''[<start/stop/restart/status>] Control vpdu service and get vpdu service status. vpdu start - Start vPDU and SNMP simulator service vpdu stop - Stop vPDU and SNMP simulator service vpdu restart - Restart vPDU and SNMP simulator service vpdu status - Get vPDU and SNMP simulator status ''' if len(params) == 0: return global pdu_sim logger.info("Executing action: %s" % params[0]) if params[0] == 'start': if pdu_sim.is_alive(): self.writeresponse("%svpdu service [%d] is alredy running.%s" % (colors.GREEN, pdu_sim.pid, colors.NORMAL)) else: pdu_sim = pdusim.pdusim.PDUSim() pdu_sim.set_daemon() pdu_sim.start() time.sleep(1) if pdu_sim.is_alive(): self.writeresponse("%svpdu service [%d] is started.%s" % (colors.GREEN, pdu_sim.pid, colors.NORMAL)) elif params[0] == 'stop': if not pdu_sim.is_alive(): self.writeresponse("%svpdu service is already stopped.%s" % (colors.GREEN, colors.NORMAL)) return if pdu_sim.is_alive(): pdu_sim.stop() time.sleep(1) if not pdu_sim.is_alive(): self.writeresponse("%svpdu service is stopped.%s" % (colors.GREEN, colors.NORMAL)) elif params[0] == 'restart': if pdu_sim.is_alive(): pdu_sim.stop() # Wait 1 second for snmpsim exit, and then end then check again time.sleep(1) if pdu_sim: pdu_sim = pdusim.pdusim.PDUSim() pdu_sim.set_daemon() pdu_sim.start() time.sleep(1) if pdu_sim.is_alive(): self.writeresponse("%svpdu service [%d] is restarted.%s" % (colors.GREEN, pdu_sim.pid, colors.NORMAL)) logger.info("vpdu service [%d] is restarted." % pdu_sim.pid) return logger.error("Cannot restart vpdu service.") elif params[0] == 'status': if pdu_sim.is_alive() is True: response = "%svpdu service [%d] is running.%s" % \ (colors.GREEN, pdu_sim.pid, colors.NORMAL) self.writeresponse(response) logger.info(response) else: if pdu_sim.is_alive() is False: response = \ "%svpdu service is not running.%s" % (colors.RED, colors.NORMAL) self.writeresponse(response) logger.info(response)
def command_ip(self, params): ''' [<set/get/link>] [<param.1> ... <param.n>] set/get interface IP address link up/down will bring up/down interface link. ip set <intf> <addr> <netmask> e.g.: Set enp0s8 address to 10.0.1.2 ip set enp0s8 10.0.1.2 255.255.255.0 ip get <intf> e.g.: Get enp0s8 address ip get enp0s8 The output will be: ip address: 10.0.1.2, netmask: 255.255.255.0 ip link list - list all avaialbe ethernet interfaces ip link <intf> status - Get specific interface link status ip link <intf> up - Bring up link for interface ip link <intf> down - Bring down link for interface ''' if len(params) == 0: return ifname_list = NetworkUtils.get_net_interfaces() if params[0] == 'link': if params[1] == 'list': self.writeresponse( colors.CYAN + "Available interfaces:" + colors.NORMAL ) self.writeresponse( colors.RED + ' '.join(ifname_list) + colors.NORMAL ) return else: ifname = params[1] if ifname not in ifname_list: logger.error("%s not exists." % ifname) self.writeresponse("%s%s not exists.%s" % (colors.RED, ifname, colors.NORMAL)) return subcmd = params[2] if subcmd == 'up': NetowrkUtils.link_up(ifname) elif subcmd == 'down': NetworkUtils.link_down(ifname) elif subcmd == 'status': ret = NetworkUtils.link_status(ifname) if ret: self.writeresponse("%s link up" % ifname) else: self.writeresponse("%s link down" % ifname) else: logger.error("unknown parameters.") else: ifname = params[1] if ifname not in ifname_list: logger.error("%s not exists." % ifname) self.writeresponse("%s%s not exists.%s" % (colors.RED, ifname, colors.NORMAL)) return if params[0] == 'get': ip_address = NetworkUtils.get_ip_address(ifname) netmask = NetworkUtils.get_netmask(ifname) self.writeresponse( colors.GREEN + "ip address: " + ip_address + ", " + "netmask: " + NetworkUtils.convert_int_to_ip(NetworkUtils.get_netmask_int(netmask)) + colors.NORMAL ) elif params[0] == 'set': set_ip_address(ifname, params[2]) if len(params) > 3: netmask = params[3] int_netmask = NetworkUtils.convert_ip_to_int(netmask) NetworkUtils.set_netmask(ifname, NetworkUtils.get_mask(int_netmask)) status = NetworkUtils.link_status(ifname) if not status: NetworkUtils.link_up(ifname) else: logger.error("unknown parameters.")
sys.exit(1) if daemon: pdusim.common.daemon.daemonize(vpdud_pid_file) logger.info("vPDU started.") configdir_found = False for dir in install_datadir: path = os.path.join(dir, 'conf', 'host.conf') if os.path.exists(path): configdir_found = True break if not configdir_found: logger.error("Don't find the configuration dir.") sys.exit(1) # Load configuration if exists if os.path.exists("/boot/conf"): for path, _, files in os.walk("/boot/conf"): for f in files: shutil.copy(os.path.join(path, f), os.path.join(dir, "conf")) p = pipe.Pipe() conf = config.Config(dir) config.set_conf_instance(conf) # Create mapping file handle mapping_file.set_mapping_file_handle(mapping_file.MappingFileHandle(dir))
def command_vpdu(self, params): '''[<start/stop/restart/status>] Control vpdu service and get vpdu service status. vpdu start - Start vPDU and SNMP simulator service vpdu stop - Stop vPDU and SNMP simulator service vpdu restart - Restart vPDU and SNMP simulator service vpdu status - Get vPDU and SNMP simulator status ''' if len(params) == 0: return logger.info("Executing action: %s" % params[0]) if params[0] == 'start': pid = get_vpdu_pid() logger.info("vpdu pid: %d" % pid) if pid > 0: self.writeresponse("%svpdu service [%d] is alredy running.%s" % (colors.GREEN, pid, colors.NORMAL)) else: ret = start_vpdu() if ret == 0: pid = get_vpdu_pid() if pid > 0: self.writeresponse("%svpdu service [%d] is started.%s" % (colors.GREEN, pid, colors.NORMAL)) return else: # check if the snmpsim service is already running. snmpsim_pid = SNMPSimService.getpid() if snmpsim_pid > 0: os.kill(snmpsim_pid, signal.SIGTERM) self.writeresponse("%sFailed to start vpdu service.%s" % (colors.RED, colors.NORMAL)) logger.error("Failed to start vpdu service.") elif params[0] == 'stop': pid = get_vpdu_pid() if pid < 0: self.writeresponse("%svpdu service is already stopped.%s" % (colors.GREEN, colors.NORMAL)) return if pid > 0: os.kill(pid, signal.SIGTERM) # Wait 1 second for snmpsim exit, and then end then check again time.sleep(1) snmpsim_pid = SNMPSimService.getpid() if snmpsim_pid > 0: os.kill(snmpsim_pid, signal.SIGTERM) pid = get_vpdu_pid() snmpsim_pid = SNMPSimService.getpid() if pid < 0 and snmpsim_pid < 0: self.writeresponse("%svpdu service is stopped.%s" % (colors.GREEN, colors.NORMAL)) else: self.writeresponse("%sCannot stop vpdu service.vpdu pid %d, \ snmpsim pid %d.%s" % (colors.RED, pid, snmpsim_pid, colors.NORMAL)) logger.error("Cannot stop vpdu service. vpdu pid %d, \ snmpsim pid %d" % (pid, snmpsim_pid)) elif params[0] == 'restart': pid = get_vpdu_pid() if pid > 0: os.kill(pid, signal.SIGTERM) # Wait 1 second for snmpsim exit, and then end then check again time.sleep(1) snmpsim_pid = SNMPSimService.getpid() if snmpsim_pid > 0: os.kill(snmpsim_pid, signal.SIGTERM) self.writeresponse("{0}vpdu service is stopped.{1}" .format(colors.GREEN, colors.NORMAL)) logger.info("vpdu service is stopped.") ret = start_vpdu() if ret == 0: pid = get_vpdu_pid() snmpsim_pid = SNMPSimService.getpid() if pid > 0 and snmpsim_pid > 0: self.writeresponse("{0}vpdu service [{1}] is restarted.{2}" .format(colors.GREEN, pid, colors.NORMAL) ) logger.info("vpdu service [%d] is restarted." % pid) return self.writeresponse("{0}Cannot restart vpdu service. pid {1}, \ snmpsimd pid {2}{3}".format(colors.RED, pid, snmpsim_pid, colors.NORMAL) ) logger.error("Cannot restart vpdu service.") elif params[0] == 'status': vpdu_pid = get_vpdu_pid() snmpsim_pid = SNMPSimService.getpid() response = "" if vpdu_pid > 0 and snmpsim_pid > 0: response = "%svpdu service [%d] is running.%s" % \ (colors.GREEN, vpdu_pid, colors.NORMAL) self.writeresponse(response) logger.info(response) elif vpdu_pid < 0 and snmpsim_pid < 0: response = \ "%svpdu service is not running.%s" % (colors.RED, colors.NORMAL) self.writeresponse(response) logger.info(response) else: response = "{0}There is an exception, \ vpdu pid {1}, snmp sim pid {2}.{3}"\ .format(colors.RED, vpdu_pid, snmpsim_pid, colors.NORMAL) self.writeresponse(response) logger.info(response)