序读项目由来
终极目标,运维平台。自动化。装机,监控,安装软件,部署
基础服务,资产管理,之前是excel,现在是客户端自动获取,变更记录
后台管理 api 采集资产
四种模式
agent 定时,每天执行一次,采集的资产回报给api,api负责入库
ssh,需要中控机,不用部署agent,去api拿没有采集的主机,远程通过paramiko执行命令拿到数据回报给api
salt,利用salt内部原理rbc,列队形式执行命令
pupet,利用报表,每半个小时向master回报,我们利用报表执行自己的ruby脚本,资产拿到回报给api
一 四种模式
api 其他系统调用数据,不能让人直接用数据库。还可以提交数据,做统一化的管理。
agent客户端有自定义的脚本,通过任务计划每天采集信息给api
ssh 通过api 链接 数据库,查看谁没有给我信息,那我拿到主机名,我链接上去,执行命令,取返回值在给api
slat rpc模式。 内部提供队列,zero mq
30分钟自动链接,提供信息给中间,中间代码会整理这个信息
二 各个模式代码
import subprocess import requests ### pip3 install request ################### 采集数据 ################## result = subprocess.getoutput('ifconfig') print(result) # 正则处理获取的数据 ################## 整理资产信息 ################### date_dict = { 'nic':{}, 'disk':{}, 'mem':{} } ################### 发送数据 ################## requests.post('http://www.127.0.0.1:8000/assets.html',data=date_dict)
# 基于 paramiko 模块 # pip3 install paramiko import requests import paramiko ################### 获取未采集主机名 ################## # result = requests.get('http://www.127.0.0.1:8000/assets.html') con = ['c1.com','c2.com'] # 未收集到的主机名称 ################### 通过paramiko链接远程服务器,执行命令 ################## # 创建SSH对象 ssh = paramiko.SSHClient() # 允许链接不在know_hosts文件中的主机 ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) # 链接服务器 ssh.connect(hostname='c1.com',port=22,username='joker',password='123') # 执行命令 stdin,stdout,stderr = ssh.exec_command('ifconfig') # 获取结果 result = stdout.read() # 关闭链接 ssh.close() print(result) ################## 整理资产信息 ################### date_dict = {result} ################### 发送数据 ################## requests.post('http://www.127.0.0.1:8000/assets.html',data=date_dict)
# 安装saltstack http://www.cnblogs.com/wupeiqi/articles/6415436.html # linux 上 rpm --import https://repo.saltstack.com/yum # Master : yum install salt-master 服务器端 # Slave : yum install salt-minion 客户端 # Master准备 # a . 配置文件,监听本机ip # vim /etc/salt/master # interface 本机ip地址 # b. 启动master # /etc/init.d/salt-master start # Slave准备 # a . 配置文件,链接哪个master # vim /etc/salt/minion # master : 远程master地址 # b . 启动slave # /etc/init.d/salt-minion start # 1. 配置 好了 之后创建关系 # Master : # 查看 # Master: salt-key -L 第一次执行命令的时候 # Accepted Keys: # Denied Keys: 拒绝 # Unaccepted Keys: 未接受 # c1.com # c2.com # c3.com # Rejected Keys: 拒绝 # 2. 接受 # Master: salt-key -a c1.com -a 后面可以正则匹配 # 在查看 # Master: salt-key -L # Accepted Keys: # c1.com # Denied Keys: # Unaccepted Keys: # c2.com # c3.com # Rejected Keys: # 3. 执行命令 # 通过py 文件执行命令 # from salt import client # local = salt.client.LocalClient() # resutl = local.cmd('bogon','cmd.run',['ifconfig']) # resutl.keys() # ['bogon'] # resutl.values() # ifconfig 的结果 # 通过 传输命令执行 # master: # salt 'c1.com' cmd.run 'ifconfig'
################### 获取未采集主机名 ################## # result = requests.get('http://www.127.0.0.1:8000/assets.html') con = ['c1.com','c2.com'] # 未收集到的主机名称 ################### 远程服务器执行命令 ################## # 2种方式 import subprocess result = subprocess.getoutput("salt 'c1.com' cmd.run 'ifconfig'") import salt.client local = salt.client.LocalClient() resutl = local.cmd('c1.com','cmd.run',['ifconfig']) ################## 整理资产信息 ################### date_dict = {result} ################### 发送数据 ################## requests.post('http://www.127.0.0.1:8000/assets.html',data=date_dict)
三 面向对象的继承
四 代码
流程
# agent 形式 # 1. 采集资产 # 2. 将资产数据发送到api(post 表示要创建资产) # ssh形式 # 1. 获取今日未采集主机列表 # 2. 采集资产 # 3. 将资产数据发送到api(post 表示要创建资产) # salt形式 # 1. 获取今日未采集主机列表 # 2. 采集资产 # 3. 将资产数据发送到api(post 表示要创建资产) # agent 自己取内容,拿标识往后台发 需要维护一个主机名文件 才知道给谁发 # 其他模式不需要,因为他先要获取主机名
# 文件结构
# bin 可执行文件 src 业务逻辑,采集资产信息 lib 公共功能 conf 配置文件 bin 可执行文件
1. 资产信息的插件的封装
# 采集资产: 三种不同的形式,而形式都在test里面 from day73.conf import settings class BasePlugin(object): def __init__(self): mode_lsit = ['SSH','Salt','Agent'] # 配置文件里面的模式在这个列表里,执行命令 if settings.MODE in mode_lsit: self.mode = settings.MODE else: raise Exception('配置文件错误') def ssh(self,cmd): # paramiko pass def agent(self,cmd): pass def salt(self,cmd): pass def shell_cmd(self,cmd): # 获取 SETTINGS 里面的 模式 if self.mode == 'SSH': ret = self.ssh(cmd) elif self.mode == 'Salt': ret =self.salt(cmd) else: ret = self.agent(cmd) return ret def execute(self): # self 是 DiskPlugin 的对象 obj # 执行判断平台的命令 # agent 模式,代码放在远程的服务器上 # import subprocess # subprocess.getoutput('') # ssh 模式,paramiko模块远程链接上执行命令 # saltstack 模式,调用salt接口执行命令 ret = self.shell_cmd('查看平台命令') # 不需要做判断 模式了,在内部判断了哪种模式 if ret == 'win': return self.windows() elif ret == 'linux': return self.linux() else: raise Exception('只支持windows和Linux') def linux(self): raise Exception('....') def windows(self): raise Exception('....') class DiskPlugin(BasePlugin): # 硬盘 def linux(self): output = self.shell_cmd('fdisk -l') # 正则表达式,取该取的内容返回 return output def windows(self): output = self.shell_cmd('xxx') return output class MemPlugin(BasePlugin): # 内存 def linux(self): output = self.shell_cmd('free') return output def windows(self): output = self.shell_cmd('xxx') return output obj = BasePlugin() obj.execute() # 就会执行命令,会自动分辨是哪个平台
用到的知识点:
面向对象的继承
2. 数据打包
将,内存,硬盘,网卡等信息打包在一起
# 将数据打包返回 # from .plugins.disk import DiskPlugin 导入 采集对象类 # from .plugins.mem import MemPlugin # from .plugins.nic import NicPlugin from day73.conf import settings def pack(): # 如果需要其他信息,就需要更改源码,这是我们不想看到的 # obj1 = DiskPlugin() # disk_info = obj1.execute() # # obj2 = MemPlugin() # mem_info = obj2.execute() # # obj3 = NicPlugin() # nic_info = obj3.execute() # # response = { # 'nic':nic_info, # 'mem':mem_info, # 'disk':disk_info # } # 通过配置文件解决 response = {} ''' settings.PLUGINS PLUGINS = { 'disk':'src.plugins.disk.DiskPlugin', 'men':'src.plugins.mem.MemPlugin', 'nic':'src.plugins.nic.NickPlugin', } ''' ''' # from 导入模块 from day73.src.plugins import disk content = disk.DiskPlugin().execute() # 实例化 并且 执行 方法,返回内容 # 字符串的导入模块 import importlib M = importlib.import_module('PY文件路径') # py 文件 M = importlib.import_module('src.plugins.disk') # py 文件 cls = getattr(M, 'DiskPlugin') # 反射 content = cls.DiskPlugin().execute() # 实例化 并且 执行 方法,返回内容 ''' for k,v in settings.PLUGINS.items(): import importlib m_path,classname = v.rsplit('.',maxsplit=1) # 从右边第一个点进行分割 M = importlib.import_module(m_path) # py 文件 cls = getattr(M, classname) # 是否有这个类 # 'disk':'src.plugins.disk.DiskPlugin', # v 是字符串,所以要用反射 response[k] = cls().execute() # v().execute() 执行命令后的结果,参考.execute流程 return response
用到的知识点:
# 字符串的导入模块 import importlib M = importlib.import_module('PY文件路径') # py 文件 M = importlib.import_module('src.plugins.disk') # py 文件 cls = getattr(M, 'DiskPlugin') # 反射 content = cls.DiskPlugin().execute() # 实例化 并且 执行 方法,返回内容
3. bin目录启动文件导入
# package.PY文件在SRC目录下导入 # from day73.src import package # data_dict = package.pack() # 将package.PY文件的代码放入到SRC里面的__init__文件中,然后导入包 # 导入包,文件夹,默认就会加载文件夹下的__INIT__文件 from day73.src import plugins data_dict = plugins.pack() # 相当于将PACK放到了plugins里面了,就可以调用了
4. 代码流程
代码流程进阶 AutoClient 上面流程的三四步骤,如下的获取资产信息步骤