Fabric

# fabric_basic.py
from fabric import Connection
host = '192.168.10.50'
user = 'root'
password = 'abc123'
# 实例化Connection类以建立SSH连接
c = Connection(host=host, user=user, connect_kwargs={ 'password': 'abc123'} )
print(c.config)

# 在远程系统上运行命令(用run方法),并获得返回结果
result = c.run('uname -r')
# 显示执行命令返回的结果
print(result.stdout.strip())
# 继续执行命令
c.run('df')
# 切换当前目录连续执行多条命令
with c.cd('/home'):
    c.run("mkdir -p testdir")
    c.run("touch testfile")
    c.run("ls -l")
# 自动切换回之前的当前目录
c.run("pwd")
c.close()
# fabric_sudo1.py
from invoke import Responder
from fabric import Connection

c = Connection('test@192.168.0.114', connect_kwargs={'password': '123456'})
user = 'test'
password = '123456'
sudopass = Responder(
    pattern=f'\[sudo\] password for {user}:',
    response=password + '\n'
)

# 注意需要设置pty=True
c.run('sudo cat /etc/shadow', pty=True, watchers=[sudopass])
c.close()
# fabric_sudo2.py
from fabric import Config
from fabric import Connection

# 预先配置sudo密码
config = Config({
    'sudo': {
        'password': '123456'
    }
})
c = Connection('test@192.168.0.114',connect_kwargs={'password': '123456'},config=config)
# 使用sudo方法执行命令
c.sudo('cat /etc/shadow')
c.close()

# fabric_sudo3.py

from invoke import Responder
from fabric import Connection

c = Connection('test@192.168.0.114', connect_kwargs={'password': '123456'})
user = 'test'
password = '123456'
sudopass = Responder(
    pattern=f'\[sudo\] password for {user}:',
    response=password + '\n'
)

# 注意需要设置pty=True
c.run('cd /home/', pty=True, watchers=[sudopass])
c.run('sudo mkdir -p /home/testdir', pty=True, watchers=[sudopass])
c.run('sudo touch testfile', pty=True, watchers=[sudopass])
c.run('ls -l', pty=True, watchers=[sudopass])
c.run('pwd', pty=True, watchers=[sudopass])
c.close()
# fabric_group.py
from fabric import SerialGroup as Group

hosts = (
    "root@192.168.10.50", "gly@192.168.10.60"
)
pool = Group(*hosts, connect_kwargs={"password": "abc123"})


def upload(c):
    if not c.run('test -e /tmp/test', warn=True):
        print("dd")
        c.run('mkdir -p /tmp/test')
    c.put('fabric_basic.py', '/tmp/test')


for conn in pool:
    upload(conn)

# fabric_group2.py
from fabric import SerialGroup as Group
hosts = (
  "root@192.168.10.50", "gly@192.168.10.60"
)
pool = Group(*hosts, connect_kwargs={"password": "abc123"})
pool.run("sudo ls")
pool.run('mkdir  /tmp/test')
pool.put('fabric_basic.py','/tmp/test')
pool.close()
#
# if results = pool.run('uname -s')
# for connection, result in results.items():
#   print("{0.host}: {1.stdout}".format(connection, result))
# if pool.run('test -f /opt/mydata/myfile', warn=True).failed:
#     pool.put('myfiles.tgz', '/opt/mydata')
#     pool.run('tar -C /opt/mydata -xzvf /opt/mydata/myfiles.tgz')

# upload_byfabric.py
from fabric import SerialGroup as Group
from fabric import Config
import invoke
# 定义目标服务器集合
hosts = (
    "root@192.168.10.50", "gly@192.168.10.60"
)
# 配置sudo密码
config = Config(overrides={
    'sudo': {
        'password': 'abc123'
    }
})
# 创建SerialGroupd对象统一建立组成员服务器的SSH连接
group = Group(*hosts, connect_kwargs={"password": "abc123"}, config=config)
# 本地文件打包
invoke.run("tar -czf source_test.tar.gz *.py")
# 计算本地压缩包文件的MD5值
local_md5 = invoke.run("md5sum source_test.tar.gz").stdout.split(' ')[0]
# 定义上传校验函数
def upload_check(c):
    c.sudo("mkdir -p /source_test")
    # 修改目标目录权限
    c.sudo("chmod 777 /source_test")
    # 上传压缩包文件
    c.put("source_test.tar.gz", "/source_test/")
    # 计算已上传的压缩包文件的MD5值
    remote_md5 = c.run("md5sum /source_test/source_test.tar.gz").stdout.split(' ')[0]
    # 比较本地与远程压缩包文件的MD5值进行校验
    if remote_md5 == local_md5:
        print(c.host + "服务器上已完成上传")
        c.run("tar -zxvf /source_test/source_test.tar.gz -C /source_test")
    else:
        print(c.host + "服务器上上传失败")
    # 还原目标目录权限
    c.sudo("chmod 754 /source_test")
# 遍历组成员执行上传校验函数
for conn in group:
    upload_check(conn)
group.close()

# sysinfo_byfabric.py
from fabric import SerialGroup as Group

hosts = (
    "test@192.168.0.114","test@192.168.0.114"
)
# 创建SerialGroupd对象统一建立组成员服务器的SSH连接
group = Group(*hosts, connect_kwargs={"password": "123456"})
# 定义汇总服务器系统信息的数组
data_total = []


# 定义执行Shell命令采集系统信息的函数
def get_sysinfo(c):
    # 定义采集服务器系统信息的命令字典
    sys_commands = {
        "hostname": "hostname",
        "kernel": "uname -r",
        "architecture": "uname -m",
        "ipadd": "hostname -I",
        "cpu_idle": "top -n 1 -b | sed -n '3p' | awk '{print $8}'",
        "memory_used": "free -m | sed -n '2p' | awk '{print $3}'",
        "memory_total": "free -m | sed -n '2p' | awk '{print $2}'",
        "process_number": "ps -A --no-headers | wc -l",
        "disk_usage": "df / | sed -n '2p' | awk '{print $5}'"
    }
    data_sys = {}  # 定义汇集单台服务器系统信息结果的字典
    # 遍历字典执行Shell命令采集多种系统信息(其中CPU和内存使用率需单独计算)
    for item, command in sys_commands.items():
        if item == "cpu_idle":
            cpu_idle = c.run(command).stdout.rstrip('\n')
            if cpu_idle == "id,":
                cpu_idle = 100
            cpu_usage = str(round(100 - float(cpu_idle), 2)) + "%"
            data_sys['cpu_usage'] = cpu_usage
        elif item == "memory_used":
            memory_used = c.run(command).stdout.rstrip('\n')
        elif item == "memory_total":
            memory_total = c.run(command).stdout.rstrip('\n')
            memory_usage = str(round(int(memory_used) / int(memory_total), 2)) + "%"
            data_sys['memory_usage'] = memory_usage
        else:
            data_sys[item] = c.run(command).stdout.rstrip('\n')
    data_total.append(data_sys)


# 定义输出系统信息报告的函数(这里输出到控制台)
def report(label, item):
    print(f"\n{label:15}", end=" ")
    for data_sys in data_total:
        print(f"{data_sys[item]:40}", end=" ")


# 遍历组成员采集各服务器系统信息
for conn in group:
    get_sysinfo(conn)
group.close()
# 定义报告用的系统信息项目字典
item_names = {'hostname': '服务器', 'kernel': 'Linux内核', 'architecture': '体系结构', 'ipadd': 'IP地址', 'cpu_usage': 'CPU使用率',
              'memory_usage': '内存使用率', 'process_number': '当前进程数', 'disk_usage': '磁盘使用率'}
# 输出系统信息报告
print("===============================服务器系统信息============================")
for item, label in item_names.items():
    report(label, item)

image.png
# lamp_byfabric.pt
# 采用ThreadingGroupd对象并发执行
from fabric import ThreadingGroup as Group
hosts = (
    "root@192.168.10.50", "root@192.168.10.51"
)
group = Group(*hosts, connect_kwargs={"password": "abc123"})
print("自动安装LAMP ......")
# 安装Apache服务器
group.run("yum install httpd -y")
# 安装并启动MariaDB服务器
group.run("yum install mariadb mariadb-server -y")
group.run("systemctl start mariadb")
group.run("systemctl enable mariadb")
# 以非交互方式运行MariaDB数据库安全配置向导
group.run("echo -e '\ny\nabc123\nabc123\ny\ny\ny\ny\n' | /usr/bin/mysql_secure_installation")
# 安装PHP
group.run("yum install pcre gcc-c++ zlib* php php-mysqlnd php-gd libjpeg* php-ldap php-odbc php-pear php-xml* php-json php-mbstring php-bcmath php-mhash -y")
# 生成PHP测试文件
group.run("echo '<?php phpinfo(); ?>' |  tee /var/www/html/test.php")
# 启动Apache服务器
group.run("systemctl start httpd")
group.run("systemctl enable httpd")
# 防火墙开启HTTP和HTTPS服务
group.run("systemctl start firewalld",warn=True)
group.run("firewall-cmd --permanent --zone=public --add-service=http  --add-service=https",warn=True)
group.run("firewall-cmd  --reload")
# 安装phpMyAdmin
group.run("curl -o phpMyAdmin.zip https://files.phpmyadmin.net/phpMyAdmin/4.9.10/phpMyAdmin-4.9.10-all-languages.zip")
group.run("mv phpMyAdmin.zip /var/www/html")
group.run("unzip -d /var/www/html /var/www/html/phpMyAdmin.zip")
group.run("rm /var/www/html/phpMyAdmin.zip")
group.run("mv /var/www/html/phpMyAdmin-4.9.10-all-languages /var/www/html/phpmyadmin")
group.run("mv /var/www/html/phpmyadmin/config.sample.inc.php /var/www/html/phpmyadmin/config.inc.php")
group.close()

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,456评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,370评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,337评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,583评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,596评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,572评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,936评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,595评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,850评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,601评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,685评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,371评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,951评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,934评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,167评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,636评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,411评论 2 342

推荐阅读更多精彩内容