介绍

在现代IT基础设施管理中,远程批量升级是一个常见的需求。本文将介绍如何利用Python编写的脚本结合Paramiko和SCP库,实现自动化地将升级文件分发到多个远程服务器,并在每台服务器上执行升级操作。

技术背景

Paramiko 是一个用于在Python中执行SSH连接的强大库,它支持SSH协议的各种操作,如执行命令、上传和下载文件等。SCP 则是基于SSH协议的文件传输协议,适合用于安全地在远程服务器之间传输文件。

程序设计

1. 读取配置文件 (read_config函数)

配置文件中包含了目标服务器的IP地址、用户名和密码。read_config函数从配置文件中读取这些信息,并返回一个包含配置信息的列表。

python复制代码# 示例代码片段
def read_config(file_path):
    """
    读取配置文件中的IP地址、用户和密码
    :param file_path: 配置文件路径
    :return: 配置信息的列表,每个元素是一个字典,包含ip, user, password
    """
    configs = []

    try:
        with open(file_path, 'r') as file:
            for line in file:
                line = line.strip()
                if line:  # 忽略空行
                    parts = line.split('|')
                    if len(parts) == 3:
                        config = {
                            'ip': parts[0].strip(),
                            'user': parts[1].strip(),
                            'password': parts[2].strip()
                        }
                        configs.append(config)
                    else:
                        logging.warning(f"无效配置行: {line}")

    except FileNotFoundError:
        logging.error(f"文件 {file_path} 未找到")
    except Exception as e:
        logging.error(f"读取文件 {file_path} 时发生错误: {e}")

    return configs

2. 文件传输 (scp_transfer函数)

scp_transfer函数使用SCPClient将本地的升级文件传输到远程服务器指定的路径。

python复制代码# 示例代码片段
def scp_transfer(ip, user, password, local_file, remote_path):
    """
    使用SCP传输文件到远程服务器
    :param ip: 远程服务器IP地址
    :param user: 远程服务器用户名
    :param password: 远程服务器密码
    :param local_file: 本地文件路径
    :param remote_path: 远程文件路径
    """
    try:
        ssh = paramiko.SSHClient()
        ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        ssh.connect(ip, username=user, password=password)

        with SCPClient(ssh.get_transport()) as scp:
            scp.put(local_file, remote_path)
        logging.info(f"文件 {local_file} 成功传输到 {ip}:{remote_path}")

    except Exception as e:
        logging.error(f"传输文件到 {ip} 时发生错误: {e}")

    finally:
        ssh.close()

3. 执行命令和交互 (execute_command函数)

execute_command函数连接到远程服务器,执行指定的命令,并处理交互式输入。在这里,还包括了启动升级和获取升级状态的逻辑。

python复制代码# 示例代码片段
def execute_command(ip, user, password, command, remote_path, file_name):
    """
    在远程服务器上执行命令
    :param ip: 远程服务器IP地址
    :param user: 远程服务器用户名
    :param password: 远程服务器密码
    :param command: 要执行的命令
    :param remote_path: 远程文件路径
    :param file_name: 文件名
    :return: 命令的输出
    """
    ssh = paramiko.SSHClient()
    ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())

    try:
        # 连接到远程服务器
        ssh.connect(ip, username=user, password=password)

        # 打开一个交互式shell
        shell = ssh.invoke_shell()
        time.sleep(1)  # 等待shell就绪

        # 发送命令
        shell.send(command + "\n")
        time.sleep(3)  # 等待命令执行

        # 接收命令输出
        output = shell.recv(9999).decode("utf-8")

        # 处理确认或输入密码等交互
        if "yes" in output:
            shell.send("yes\n")
            time.sleep(1)
            output += shell.recv(9999).decode("utf-8")
        if "password" in output:
            logging.info("Sending password for further authentication")
            shell.send(expPassword + "\n")
            time.sleep(10)
            output += shell.recv(9999).decode("utf-8")

        # 启动升级和获取升级状态
        logging.info("Sending upgrade pack to exp board")
        start_update(ssh, remote_path + "/" + file_name)
        logging.info("Starting upgrade command")

        percent = get_update_state(ssh)
        while percent < 100:
            time.sleep(1)
            percent = get_update_state(ssh)

        logging.info(f"Upgrade successful on {ip}")
        shell.close()

        return output

    except paramiko.SSHException as ssh_err:
        logging.error(f"SSH error: {ssh_err}")
    except Exception as e:
        logging.error(f"Error while executing command on {ip}: {e}")
    finally:
        ssh.close()

日志记录

在整个程序中,使用了日志记录器来记录程序的活动和错误,这对于远程操作和故障排除至关重要。

使用案例和注意事项

  • 确保配置文件的格式正确,包括每行的IP地址、用户名和密码用竖线分隔。
  • 注意处理SSH连接的异常情况,例如网络不稳定或服务器不可达的情况。
  • 在执行升级操作时,始终监视升级状态并记录日志,以便在需要时进行故障排除。

结论

通过本文介绍的方法,你可以使用Python和Paramiko实现一个自动化的远程批量升级解决方案。这不仅提高了效率,还减少了手动操作的出错可能性,特别适用于需要频繁升级多台远程服务器的场景。

希望本文能对你在类似项目中的工作有所帮助!如果有任何问题或意见,请随时在评论中提出。