CMDB讲解一
【1】.python的方向:
【2】.运维介绍:
【3】.目标:
【4】.cmdb设计方案1
【5】.cmdb设计方案2
【6】.cmdb设计方案3
【7】.setting自定义和全局配置
【8】.配置监控项目中间件
【9】.收集监控端数据
需要用的安装包:
import subprocess
pip3 install requests
import requests
pip3 install paramiko
import paramiko
yum install salt-master
yum install salt-minion
【1】.python的方向:
1.自动化运维(cmdb)
2.web方向
3.爬虫---数据分析 BI
4.AI
【2】.运维介绍:
CMDB系统
1.代码发布:
产品经理调研需求--->开发进行开发--->测试(自己和专业测试)--->上线(运维工程师)
传统运维:
运维拿到代码,初始的时候,上线两台机器
机器增加,通过rsync把代码复制到后续的机器
2.自动化运维:
代码发布系统:发布代码
必须知道的是:
服务器的IP,HOSTNAME等
装机需求:
传统运维:
10个IDC运维
自动化运维:
自动装机系统:
colber
必须知道的是:
服务器的IP,hostname等
年底资产审查:
传统运维
excel表格
自动化运维:
需要服务器自己上报信息
必须知道的是:
服务器的IP,Hostname,硬盘,cpu等
【3】.目标:
解放双手
cmdb目标:
让服务器自动的汇报服务器的信息
方法:
-linux命令(ifconfig,hostname,cat /proc/cpuinfo等)
-requests,get,post
三种方案:
-agent
-subprocee
-API
-ssh类
-paramiko目录(ansible软件)
-API
-saltstack
-salt-master/salt-minion
-API
目标:
更改一个配置,就能够随意的切换方案
pip3 install requests
【4】.cmdb设计方案1
此方案适合大量机器
server:
-server-urls.py
from app01 import views
urlpatterns = [
# url(r'^admin/',
admin.site.urls),
url(r'^api/', views.api),
]
-app01-views.py
from django.shortcuts import render,HttpResponse # Create your views here. def api(request): print(request.POST) print(request.body) return HttpResponse('ok')
agent:
import subprocess #1.在服务器上的agent脚本 res=subprocess.getoutput('ipconfig') print(res[9:10]) import requests #2.将拿到的数据post回去 res=requests.post('http://127.0.0.1:8000/api/',data=res[9:10]) print(res)
【5】.cmdb设计方案2
此方案适合1000台机器以下
pip3 install paramiko
#####################2.ssh类################################# import paramiko # 创建SSH对象 ssh = paramiko.SSHClient() # 允许连接不在know_host文件中的主机 ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) # 连接服务器 ssh.connect(hostname='172.21.3.153', port=22, username='root', password='123456') # 执行命令,stdin--输入,stdout--执行结果,stderr--执行命令错误信息 stdin,stdout,stderr = ssh.exec_command('ifconfig') # 获取命令的结果 result = stdout.read() print(result) # 关闭连接 ssh.close()
【6】.cmdb设计方案3
此方案中控机发送命令给服务器执行,服务器将结果放入另一个队列中,中控机将服务器信息发送API进而录入数据库
salstack的安装和配置
service iptables stop
master端:
"""
1. 安装salt-master
yum install salt-master
2. 修改配置文件:/etc/salt/master
interface: 0.0.0.0 # 表示Master的IP
interface: 172.21.3.153
3. 启动
service salt-master start
"""
slave端:
"""
1. 安装salt-minion
yum install salt-minion
2. 修改配置文件 /etc/salt/minion
master: 10.211.55.4 # master的地址
master: 172.21.3.153
或
master:
- 10.211.55.4
- 10.211.55.5
random_master: True
id: c2.salt.com # 客户端在salt-master中显示的唯一ID
3. 启动
service salt-minion start
"""
"""
salt-key -L # 查看已授权和未授权的slave
salt-key -A # 接受所有的salve
salt-key -a salve_id # 接受指定id的salve
salt-key -r salve_id # 拒绝指定id的salve
salt-key -d salve_id # 删除指定id的salve
"""
3.执行命令
在master服务器上对salve进行远程操作
salt 'c2.salt.com' cmd.run 'ifconfig'
salt '*' cmd.run 'ifconfig'
基于API的方式
import salt.client
local = salt.client.LocalClient()
result = local.cmd('c2.salt.com', 'cmd.run', ['ifconfig'])
salstack的安装资源文件:
https://www.jianshu.com/p/84de3e012753
http://www.cnblogs.com/tim1blog/p/9987313.html
【7】.setting自定义和全局配置
(7.1).-autoclient-bin-start.py
from lib.conf.config import settings
if __name__ == '__main__':
print(settings.USER)
print(settings.EMAIL)
(7.2).-autoclient-config-settings.py
# 用户自定义配置文件
USER = 'root1'
PWD = '123'
EMAIL='123@163.com'
#设置全局的配置在设置自定义前面,这样自定义调用参数优先
(7.3).-autoclient-lib-conf-config.py
from config import settings
from . import global_settings
class Settings(object):
def __init__(self):
# 设置全局的配置
for k in dir(global_settings):
if k.isupper():
value = getattr(global_settings, k)
setattr(self, k, value)
try:
# 设置自定义所有的参数给settings
for k in dir(settings):
if k.isupper():
value=getattr(settings,k)
setattr(self,k,value)
except Exception as e:
pass
settings=Settings()
(7.4).-autoclient-lib-conf-global_settings.py
EMAIL='xx@163.com'
【8】.配置监控项目中间件
(8.1).-autoclient-bin-start.py
from lib.conf.config import settings
from src.plugins import Plugins
if __name__ == '__main__':
Plugins().execute()
(8.2).-autoclient-src-service.py
from lib.conf.config import settings
mode = settings.MODE
print(mode)
def run(cmd):
if mode == 'agent':
import subprocess
res = subprocess.getoutput('cmd')
print(res[9:10])
elif mode == 'ssh':
import paramiko
# 创建SSH对象
ssh = paramiko.SSHClient()
# 允许连接不在know_host文件中的主机
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
# 连接服务器
ssh.connect(hostname='172.21.3.153', port=22, username='root', password='123456')
# 执行命令,stdin--输入,stdout--执行结果,stderr--执行命令错误信息
stdin, stdout, stderr = ssh.exec_command('cmd')
# 获取命令的结果
result = stdout.read()
print(result)
# 关闭连接
ssh.close()
elif mode == 'salt':
import subprocess
cmd1 = "salt '*' cmd.run '" + cmd + "'"
res = subprocess.getoutput(cmd1)
print(res[9:10])
else:
print('当前mode只支持agent/ssh/salt')
(8.3).-autoclient-config-settings.py
# 用户自定义配置文件
USER = 'root1'
PWD = '123'
EMAIL='123@163.com'
MODE='agent' #ssh/salt
PLUGINS_DICT={
"basic":"src.plugins.basic.Basic",
"cpu":"src.plugins.cpu.Cpu",
"disk":"src.plugins.disk.Disk",
"memory":"src.plugins.memory.Memory",
"nic":"src.plugins.nic.Nic",
}
(8.4).-autoclient-src-plugins-__init__.py
from lib.conf.config import settings
# 将字符串以模块的形式导入
import importlib
class Plugins():
def __init__(self):
self.mode = settings.MODE
self.plugins_dict = settings.PLUGINS_DICT
def execute(self):
'''
"basic":"src.plugins.basic.Basic",
"cpu":"src.plugins.cpu.Cpu",
'''
for k, v in self.plugins_dict.items():
'''
k: basic / cpu
v: src.plugins.basic.Basic /
src.plugins.cpu.Cpu
'''
module_name, class_name = v.rsplit('.', 1)
#
print(module_name, class_name)
# 将字符串以模块的形式导入
m = importlib.import_module(module_name)
obj = getattr(m, class_name) # obj代码具体类basic,cpu,disk,memory,nic类
res = obj().process()
print(res)
(8.5).-autoclient-src-plugins-basic.py
class Basic(object):
def process(self):
return 'Basic'
(8.6).-autoclient-src-plugins-cpu.py
class Cpu(object):
def process(self):
return '111'
(8.7).-autoclient-src-plugins-disk.py
class Disk(object):
def process(self):
return 'Disk'
(8.8).-autoclient-src-plugins-memory.py
class Memory(object):
def process(self):
return 'Memory'
(8.9).-autoclient-src-plugins-nic.py
class Nic(object):
def process(self):
return 'Nic'
【9】.收集监控端数据
(9.1).-autoclient-bin-start.py
from src.script import run
if __name__ == '__main__':
run()
(9.2).-autoclient-config-settings.py
# 用户自定义配置文件
USER = 'root1'
PWD = '123'
EMAIL = '123@163.com'
MODE='agent' #ssh/salt
# MODE = 'ssh' # ssh/salt
# SSH_USER = 'root'
# SSH_PWD = 'root'
# SSH_PORT = 22
DEBUG=True
import os
BASEDIR=os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
PLUGINS_DICT = {
"basic": "src.plugins.basic.Basic",
"cpu": "src.plugins.cpu.Cpu",
"disk": "src.plugins.disk.Disk",
"memory": "src.plugins.memory.Memory",
"nic": "src.plugins.nic.Nic",
"board": "src.plugins.board.Board",
}
API="http://127.0.0.1:8005/api/"
(9.3).-autoclient-files-board.out
SMBIOS 2.7 present.
Handle 0x0001, DMI type 1, 27 bytes
System Information
Manufacturer: Parallels Software
International Inc.
Product Name: Parallels Virtual
Platform
Version: None
Serial Number: Parallels-1A 1B CB 3B
64 66 4B 13 86 B0 86 FF 7E 2B 20 30
UUID:
3BCB1B1A-6664-134B-86B0-86FF7E2B2030
Wake-up Type: Power Switch
SKU Number: Undefined
Family: Parallels VM
(9.4).-autoclient-lib-conf-config.py
from config import settings
from . import global_settings
class Settings(object):
def __init__(self):
# 设置全局的配置
for k in dir(global_settings):
if k.isupper():
value = getattr(global_settings, k)
setattr(self, k, value)
try:
# 设置自定义所有的参数给settings
for k in dir(settings):
if k.isupper():
value=getattr(settings,k)
setattr(self,k,value)
except Exception as e:
pass
settings=Settings()
(9.5).-autoclient-lib-conf-global_settings.py
EMAIL='xx@163.com'
(9.6).-autoclient-lib-convert.py
#!/usr/bin/env python
# -*- coding:utf-8 -*-
def convert_to_int(value,default=0):
try:
result = int(value)
except Exception as e:
result = default
return result
def convert_mb_to_gb(value,default=0):
try:
value = value.strip('MB')
result = int(value)
except Exception as e:
result = default
return result
(9.7).-autoclient-src-plugins-__init__.py
from lib.conf.config import settings
# 将字符串以模块的形式导入
import importlib
class Plugins():
def __init__(self,hostname=None):
self.hostname=hostname
self.mode = settings.MODE
self.plugins_dict = settings.PLUGINS_DICT
self.debug=settings.DEBUG
if self.mode=='ssh':
self.ssh_user=settings.SSH_USER
self.ssh_pwd=settings.SSH_PWD
self.ssh_port=settings.SSH_PORT
def execute(self):
'''
"basic":"src.plugins.basic.Basic",
"cpu":"src.plugins.cpu.Cpu",
'''
response={}
for k, v in self.plugins_dict.items():
ret={'status':None,'data':None}
'''
k: basic / cpu
v: src.plugins.basic.Basic /
src.plugins.cpu.Cpu
'''
try:
module_name, class_name =
v.rsplit('.', 1)
#
print(module_name, class_name)
# 将字符串以模块的形式导入
m = importlib.import_module(module_name)
obj = getattr(m, class_name) # obj代码具体类basic,cpu,disk,memory,nic类
res = obj().process(self.command,self.debug)
ret['status']=True
ret['data']=res
except Exception as e:
ret['status']=False
ret['data']="[%s][%s] 采集出错的信息:%s" %(self.hostname if self.hostname else "agent",k,str(e))
response[k]=ret
return response
def command(self,cmd):
if self.mode == 'agent':
return self.__cmd_agent(cmd)
elif self.mode == 'ssh':
return self.__cmd_ssh(cmd)
elif self.mode == 'salt':
return self.__cmd_salt(cmd)
else:
print('当前mode只支持agent/ssh/salt')
def __cmd_agent(self,cmd):
import subprocess
res = subprocess.getoutput('cmd')
return res
def __cmd_ssh(self,cmd):
import paramiko
# 创建SSH对象
ssh = paramiko.SSHClient()
# 允许连接不在know_host文件中的主机
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
# 连接服务器
ssh.connect(hostname=self.hostname, port=self.ssh_port, username=self.ssh_user, password=self.ssh_pwd)
# 执行命令,stdin--输入,stdout--执行结果,stderr--执行命令错误信息
stdin, stdout, stderr = ssh.exec_command('cmd')
# 获取命令的结果
result = stdout.read()
print(result)
# 关闭连接
ssh.close()
return result
def __cmd_salt(self,cmd):
import subprocess
cmd1 = "salt '*' %s '" + cmd + "'" %self.hostname
res
= subprocess.getoutput(cmd1)
return res
(9.8).-autoclient-src-plugins-basic.py
#!/usr/bin/env python
# -*- coding:utf-8 -*-
class Basic(object):
def __init__(self):
pass
@classmethod
def initial(cls):
return cls()
def process(self, command_func, debug):
if debug:
output
= {
'os_platform': "linux",
'os_version': "CentOS release 6.6 (Final)\nKernel \r on an \m",
'hostname': 'c1.com'
}
else:
output
= {
'os_platform': command_func("uname").strip(),
'os_version': command_func("cat /etc/issue").strip().split('\n')[0],
'hostname': command_func("hostname").strip(),
}
return output
(9.9).-autoclient-src-plugins-board.py
#!/usr/bin/env python
# -*- coding:utf-8 -*-
import os
from lib.conf.config import settings
class Board(object):
def __init__(self):
pass
@classmethod
def initial(cls):
return cls()
def process(self, command_func, debug):
if debug:
output = open(os.path.join(settings.BASEDIR, 'files/board.out'), 'r', encoding='utf-8').read()
else:
output = command_func("sudo dmidecode -t1")
return self.parse(output)
def parse(self, content):
result
= {}
key_map = {
'Manufacturer': 'manufacturer',
'Product Name': 'model',
'Serial Number': 'sn',
}
for item in content.split('\n'):
row_data =
item.strip().split(':')
if len(row_data) == 2:
if row_data[0] in key_map:
result[key_map[row_data[0]]] = row_data[1].strip() if row_data[1] else row_data[1]
return result
(9.10).-autoclient-src-plugins-cpu.py
#!/usr/bin/env python
# -*- coding:utf-8 -*-
import os
from lib.conf.config import settings
class Cpu(object):
def __init__(self):
pass
@classmethod
def initial(cls):
return cls()
def process(self, command_func, debug):
if debug:
output = open(os.path.join(settings.BASEDIR, 'files/cpuinfo.out'), 'r', encoding='utf-8').read()
else:
output = command_func("cat /proc/cpuinfo")
return self.parse(output)
def parse(self, content):
"""
解析shell命令返回结果
:param content: shell 命令结果
:return:解析后的结果
"""
response = {'cpu_count': 0, 'cpu_physical_count': 0, 'cpu_model': ''}
cpu_physical_set = set()
content = content.strip()
for item in content.split('\n\n'):
for row_line in item.split('\n'):
key, value =
row_line.split(':')
key = key.strip()
if key == 'processor':
response['cpu_count'] += 1
elif key == 'physical id':
cpu_physical_set.add(value)
elif key == 'model name':
if not response['cpu_model']:
response['cpu_model'] = value
response['cpu_physical_count'] = len(cpu_physical_set)
return response
(9.11).-autoclient-src-plugins-disk.py
#!/usr/bin/env python
# -*- coding:utf-8 -*-
import re
import os
from lib.conf.config import settings
class Disk(object):
def __init__(self):
pass
@classmethod
def initial(cls):
return cls()
def process(self, command_func, debug):
if debug:
output = open(os.path.join(settings.BASEDIR, 'files/disk.out'), 'r', encoding='utf-8').read()
else:
output = command_func("sudo MegaCli -PDList -aALL")
return self.parse(output)
def parse(self, content):
"""
解析shell命令返回结果
:param content: shell 命令结果
:return:解析后的结果
"""
response = {}
result = []
for row_line in content.split("\n\n\n\n"):
result.append(row_line)
for item in result:
temp_dict = {}
for row in item.split('\n'):
if not row.strip():
continue
if len(row.split(':')) != 2:
continue
key, value = row.split(':')
name = self.mega_patter_match(key)
if name:
if key == 'Raw Size':
raw_size =
re.search('(\d+\.\d+)', value.strip())
if raw_size:
temp_dict[name] = raw_size.group()
else:
raw_size = '0'
else:
temp_dict[name] =
value.strip()
if temp_dict:
response[temp_dict['slot']] = temp_dict
return response
@staticmethod
def mega_patter_match(needle):
grep_pattern = {'Slot': 'slot', 'Raw Size': 'capacity', 'Inquiry': 'model', 'PD Type': 'pd_type'}
for key, value in grep_pattern.items():
if needle.startswith(key):
return value
return False
(9.12).-autoclient-src-plugins-memory.py
#!/usr/bin/env python
# -*- coding:utf-8 -*-
import os
from lib import convert
from lib.conf.config import settings
class Memory(object):
def __init__(self):
pass
@classmethod
def initial(cls):
return cls()
def process(self, command_func, debug):
if debug:
output = open(os.path.join(settings.BASEDIR, 'files/memory.out'), 'r', encoding='utf-8').read()
else:
output = command_func("sudo dmidecode -q -t 17 2>/dev/null")
return self.parse(output)
def parse(self, content):
"""
解析shell命令返回结果
:param content: shell 命令结果
:return:解析后的结果
"""
ram_dict = {}
key_map = {
'Size': 'capacity',
'Locator': 'slot',
'Type': 'model',
'Speed': 'speed',
'Manufacturer': 'manufacturer',
'Serial Number': 'sn',
}
devices = content.split('Memory Device')
for item in devices:
item = item.strip()
if not item:
continue
if item.startswith('#'):
continue
segment = {}
lines = item.split('\n\t')
for line in lines:
if not line.strip():
continue
if len(line.split(':')):
key, value =
line.split(':')
else:
key = line.split(':')[0]
value = ""
if key in key_map:
if key == 'Size':
segment[key_map['Size']] = convert.convert_mb_to_gb(value, 0)
else:
segment[key_map[key.strip()]] = value.strip()
ram_dict[segment['slot']] = segment
return ram_dict
(9.13).-autoclient-src-plugins-nic.py
#!/usr/bin/env python
# -*- coding:utf-8 -*-
import os
import re
from lib.conf.config import settings
class Nic(object):
def __init__(self):
pass
@classmethod
def initial(cls):
return cls()
def process(self, command_func, debug):
if debug:
output = open(os.path.join(settings.BASEDIR, 'files/nic.out'), 'r', encoding='utf-8').read()
interfaces_info = self._interfaces_ip(output)
else:
interfaces_info = self.linux_interfaces(command_func)
self.standard(interfaces_info)
return interfaces_info
def linux_interfaces(self, command_func):
'''
Obtain interface information for
*NIX/BSD variants
'''
ifaces = dict()
ip_path = 'ip'
if ip_path:
cmd1 = command_func('sudo {0} link show'.format(ip_path))
cmd2 = command_func('sudo {0} addr show'.format(ip_path))
ifaces = self._interfaces_ip(cmd1 + '\n' + cmd2)
return ifaces
def which(self, exe):
def _is_executable_file_or_link(exe):
# check for os.X_OK
doesn't suffice because directory may executable
return (os.access(exe, os.X_OK) and
(os.path.isfile(exe) or os.path.islink(exe)))
if exe:
if _is_executable_file_or_link(exe):
# executable in cwd
or fullpath
return exe
# default path
based on busybox's default
default_path = '/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin'
search_path = os.environ.get('PATH', default_path)
path_ext = os.environ.get('PATHEXT', '.EXE')
ext_list = path_ext.split(';')
search_path =
search_path.split(os.pathsep)
if True:
# Add any dirs in
the default_path which are not in search_path. If
# there was no PATH
variable found in os.environ, then this will be
# a no-op. This ensures
that all dirs in the default_path are
# searched, which lets
salt.utils.which() work well when invoked by
# salt-call running from cron
(which, depending on platform, may
# have a severely limited
PATH).
search_path.extend(
[
x for x in default_path.split(os.pathsep)
if x not in search_path
]
)
for path in search_path:
full_path =
os.path.join(path, exe)
if _is_executable_file_or_link(full_path):
return full_path
return None
def _number_of_set_bits_to_ipv4_netmask(self, set_bits):
# pylint: disable=C0103
'''
Returns an IPv4 netmask from the
integer representation of that mask.
Ex. 0xffffff00 ->
'255.255.255.0'
'''
return self.cidr_to_ipv4_netmask(self._number_of_set_bits(set_bits))
def cidr_to_ipv4_netmask(self, cidr_bits):
'''
Returns an IPv4 netmask
'''
try:
cidr_bits = int(cidr_bits)
if not 1 <= cidr_bits <= 32:
return ''
except ValueError:
return ''
netmask = ''
for idx in range(4):
if idx:
netmask += '.'
if cidr_bits >= 8:
netmask += '255'
cidr_bits -= 8
else:
netmask += '{0:d}'.format(256 - (2 ** (8 - cidr_bits)))
cidr_bits = 0
return netmask
def _number_of_set_bits(self, x):
'''
Returns the number of bits that
are set in a 32bit int
'''
# Taken from
http://stackoverflow.com/a/4912729. Many thanks!
x -= (x >> 1) & 0x55555555
x = ((x >> 2) & 0x33333333) + (x & 0x33333333)
x = ((x >> 4) + x) & 0x0f0f0f0f
x += x >> 8
x += x >> 16
return x & 0x0000003f
def _interfaces_ip(self, out):
'''
Uses ip to return a dictionary of
interfaces with various information about
each (up/down state, ip address,
netmask, and hwaddr)
'''
ret = dict()
right_keys = ['name', 'hwaddr', 'up', 'netmask', 'ipaddrs']
def parse_network(value, cols):
'''
Return a tuple of ip,
netmask, broadcast
based on the current set of
cols
'''
brd = None
if '/' in value:
# we have a CIDR in this address
ip, cidr = value.split('/') # pylint:
disable=C0103
else:
ip = value # pylint: disable=C0103
cidr = 32
if type_ == 'inet':
mask =
self.cidr_to_ipv4_netmask(int(cidr))
if 'brd' in cols:
brd =
cols[cols.index('brd') + 1]
return (ip, mask, brd)
groups = re.compile('\r?\n\\d').split(out)
for group in groups:
iface = None
data = dict()
for line in group.splitlines():
if ' ' not in line:
continue
match = re.match(r'^\d*:\s+([\w.\-]+)(?:@)?([\w.\-]+)?:\s+<(.+)>', line)
if match:
iface, parent, attrs
= match.groups()
if 'UP' in attrs.split(','):
data['up'] = True
else:
data['up'] = False
if parent and parent in right_keys:
data[parent] =
parent
continue
cols = line.split()
if len(cols) >= 2:
type_, value = tuple(cols[0:2])
iflabel = cols[-1:][0]
if type_ in ('inet',):
if 'secondary' not in cols:
ipaddr,
netmask, broadcast = parse_network(value, cols)
if type_ == 'inet':
if 'inet' not in data:
data['inet'] = list()
addr_obj
= dict()
addr_obj['address'] = ipaddr
addr_obj['netmask'] = netmask
addr_obj['broadcast'] = broadcast
data['inet'].append(addr_obj)
else:
if 'secondary' not in data:
data['secondary'] = list()
ip_, mask,
brd = parse_network(value, cols)
data['secondary'].append({
'type': type_,
'address': ip_,
'netmask': mask,
'broadcast': brd,
})
del ip_, mask, brd
elif type_.startswith('link'):
data['hwaddr'] = value
if iface:
if iface.startswith('pan') or iface.startswith('lo') or iface.startswith('v'):
del iface, data
else:
ret[iface] = data
del iface, data
return ret
def standard(self, interfaces_info):
for key, value in interfaces_info.items():
ipaddrs = set()
netmask = set()
if not 'inet' in value:
value['ipaddrs'] = ''
value['netmask'] = ''
else:
for item in value['inet']:
ipaddrs.add(item['address'])
netmask.add(item['netmask'])
value['ipaddrs'] = '/'.join(ipaddrs)
value['netmask'] = '/'.join(netmask)
del value['inet']
(9.14).-autoclient-src-client.py
import requests
from src.plugins import Plugins
from lib.conf.config import settings
class Base(object):
def post_inf(self,res):
requests.post(settings.API,data=res)
class Agent(Base):
def execute(self):
res=Plugins().execute()
print(res)
self.post_inf(res)
class SSHSalt(Base):
def get_hostname(self):
host_list=requests.get(settings.API)
#[10.0.0.1,10.0.0.2]
return host_list
def execute(self):
for hostname in settings.get_hostname():
res=Plugins(hostname).execute()
self.post_inf(res)
(9.15).-autoclient-src-script.py
from lib.conf.config import settings
from .client import Agent
from .client import SSHSalt
def run():
if settings.MODE=='agent':
obj=Agent()
else:
obj=SSHSalt()
return obj.execute()
(9.16).-autoclient-src-service.py
from lib.conf.config import settings
mode = settings.MODE
print(mode)
def run(cmd):
if mode == 'agent':
import subprocess
res = subprocess.getoutput('cmd')
print(res[9:10])
elif mode == 'ssh':
import paramiko
# 创建SSH对象
ssh = paramiko.SSHClient()
# 允许连接不在know_host文件中的主机
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
# 连接服务器
ssh.connect(hostname='172.21.3.153', port=22, username='root', password='123456')
# 执行命令,stdin--输入,stdout--执行结果,stderr--执行命令错误信息
stdin, stdout, stderr = ssh.exec_command('cmd')
# 获取命令的结果
result = stdout.read()
print(result)
# 关闭连接
ssh.close()
elif mode == 'salt':
import subprocess
cmd1 = "salt '*' cmd.run '" + cmd + "'"
res = subprocess.getoutput(cmd1)
print(res[9:10])
else:
print('当前mode只支持agent/ssh/salt')