Files
dromara--domain-admin/domain_admin/utils/fabric_util.py
T
2026-07-13 12:31:34 +08:00

142 lines
3.5 KiB
Python

# -*- coding: utf-8 -*-
"""
@File : fabric_util.py
@Date : 2023-07-26
参考
https://www.fabfile.org/installing.html
https://docs.fabfile.org/en/stable/api/connection.html
https://www.cnblogs.com/superhin/p/13887526.html
"""
import six
from fabric import Connection
import paramiko
from domain_admin.config import DEFAULT_SSH_PORT, ALLOW_COMMANDS
from domain_admin.log import logger
from domain_admin.utils.flask_ext.app_exception import AppException
# 命令白名单
allow_commands = [
# 重启nginx
'service nginx force-reload',
# docker 下的重启命令 @since 1.5.30
'docker exec -id nginx nginx -s reload',
# 红帽系reload @since 1.5.31
'systemctl reload nginx',
'systemctl reload openresty',
# 用户自定义配置的命令
*ALLOW_COMMANDS,
]
def deploy_file(host, user, password, content, remote, port=DEFAULT_SSH_PORT):
"""
远程部署文件
:param port: 端口号
:param host: 地址
:param user: 用户名
:param password: 密码
:param content: 文件内容
:param remote: 远程路径
:return:
"""
logger.info(remote)
with Connection(
host=host,
port=port,
user=user,
connect_kwargs={"password": password}
) as conn:
conn.put(six.StringIO(content), remote)
def run_command(host, user, password, command, port=DEFAULT_SSH_PORT):
"""
远程运行命令
:param port: 端口号
:param host: 地址
:param user: 用户名
:param password: 密码
:param command: 执行命令
:return:
"""
logger.info(command)
if command not in allow_commands:
raise AppException("命令不被允许,请联系管理员")
with Connection(
host=host,
port=port,
user=user,
connect_kwargs={"password": password}
) as conn:
conn.run(command, hide=True)
def deploy_file_by_key(host, user, private_key, content, remote, port=DEFAULT_SSH_PORT):
"""
远程部署文件
:param port: 端口号
:param host: 地址
:param user: 用户名
:param private_key: 私钥
:param content: 文件内容
:param remote: 远程路径
:return:
"""
logger.info(remote)
with Connection(
host=host,
port=port,
user=user,
connect_kwargs={"pkey": _get_paramiko_key(private_key)}
) as conn:
conn.put(six.StringIO(content), remote)
def run_command_by_key(host, user, private_key, command, port=DEFAULT_SSH_PORT):
"""
远程运行命令
:param port: 端口号
:param host: 地址
:param user: 用户名
:param private_key: 私钥
:param command: 命令
:return:
"""
logger.info(command)
if command not in allow_commands:
raise AppException("命令不被允许,请联系管理员")
with Connection(
host=host,
port=port,
user=user,
connect_kwargs={"pkey": _get_paramiko_key(private_key)}
) as conn:
conn.run(command, hide=True)
def _get_paramiko_key(raw_key_content):
"""
获取paramiko对象秘钥
:param raw_key_content: 原始秘钥内容
:return: paramiko 秘钥
"""
pkey = None
for pkey_class in (paramiko.RSAKey, paramiko.DSSKey, paramiko.ECDSAKey, paramiko.Ed25519Key):
try:
pkey = pkey_class.from_private_key(six.StringIO(raw_key_content))
break
except paramiko.SSHException as e:
pass
return pkey