您的位置:首页 > 数据库

2.ansible2.2 callback插件获取硬件信息并插入到数据库中

2017-12-12 10:16 274 查看
pip install ansible==2.2

cat main.yml
- hosts: all
remote_user: root
vars:
tasks:
- name: hostinfo
script: hostinfo.py

cat hostinfo.py
#!/usr/bin/env python
# coding:utf8
# author:Allentuns
# time:2015-02-14
#url: http://blog.51cto.com/467754239/1616806 
from subprocess import Popen, PIPE
import urllib, urllib2
import pickle
import json
import re

###[hostname message]#####
def get_HostnameInfo(file):
with open(file, 'r') as fd:
data = fd.read().split('\n')
for line in data:
if line.startswith('HOSTNAME'):
hostname = line.split('=')[1]
break
return hostname

#####[ipaddr message]#####
def get_Ipaddr():
P = Popen(['ifconfig'], stdout=PIPE)
data = P.stdout.read()
list = []
str = ''
option = False
lines = data.split('\n')
for line in lines:
if not line.startswith(' '):
list.append(str)
str = line
else:
str += line
while True:
if '' in list:
list.remove('')
else:
break
r_devname = re.compile('(eth\d*|lo)')
r_mac = re.compile('HWaddr\s([A-F0-9:]{17})')
r_ip = re.compile('addr:([\d.]{7,15})')
for line in list:
devname = r_devname.findall(line)
mac = r_mac.findall(line)
ip = r_ip.findall(line)
if mac:
return ip[0]

#####[osversion message]#####
def get_OsVerion(file):
with open(file) as fd:
lines = fd.readlines()
os_version = lines[0][:-8]
return os_version

#####[memory message]#####
def get_MemoryInfo(file):
with open(file) as fd:
data_list = fd.read().split('\n')
MemTotal_line = data_list[0]
Memory_K = MemTotal_line.split()[1]
Memory_G = float(Memory_K) / 1000 / 1000
Memory_G2 = '%.2f' % Memory_G
memory = Memory_G2 + 'G'
return memory

#####[disk message]#####
def get_DiskInfo():
p = Popen(['fdisk', '-l'], stdout=PIPE, stderr=PIPE)
stdout, stderr = p.communicate()
diskdata = stdout

disk_initial_size = 0
re_disk_type = re.compile(r'Disk /dev/[shd]{1}.*:\s+[\d.\s\w]*,\s+([\d]+).*')
disk_size_bytes = re_disk_type.findall(diskdata)
for size in disk_size_bytes:
disk_initial_size += int(size)
disk_size_total_bytes = '%.2f' % (float(disk_initial_size) / 1000 / 1000 / 1000)
disk_size_total_G = disk_size_total_bytes + 'G'
disk = disk_size_total_G
return disk

#####[cpu message]#####
def get_CpuInfo():
p = Popen(['cat', '/proc/cpuinfo'], stdout=PIPE, stderr=PIPE)
stdout, stderr = p.communicate()
cpudata = stdout.strip()

cpu_dict = {}
re_cpu_cores = re.compile(r'processor\s+:\s+([\d])')
re_vendor_id = re.compile(r'vendor_id\s+:\s([\w]+)')
re_model_name = re.compile(r'model name\s+:\s+(.*)')

res_cpu_cores = re_cpu_cores.findall(cpudata)
cpu_dict['Cpu_Cores'] = int(res_cpu_cores[-1]) + 1
res_vendor_id = re_vendor_id.findall(cpudata)
cpu_dict['Vendor_Id'] = res_vendor_id[-1]
res_model_name = re_model_name.findall(cpudata)
cpu_dict['Model_Name'] = res_model_name[-1]
return cpu_dict

#####[Demi message]#####
def get_dmidecode():
P = Popen(['dmidecode'], stdout=PIPE)
data = P.stdout.read()
lines = data.split('\n\n')
dmidecode_line = lines[2]
line = [i.strip() for i in dmidecode_line.split('\n') if i]
Manufacturer = line[2].split(': ')[-1]
product = line[3].split(': ')[-1]
sn = line[5].split(': ')[-1]
return Manufacturer, product, sn

if __name__ == '__main__':
#####[get data]#####
hostname = get_HostnameInfo('/etc/sysconfig/network')
ip = get_Ipaddr()
osversion = get_OsVerion('/etc/issue')
memory = get_MemoryInfo('/proc/meminfo')
disk = get_DiskInfo()
Vendor_Id = get_CpuInfo()['Vendor_Id']
Model_Name = get_CpuInfo()['Model_Name']
Cpu_Cores = get_CpuInfo()['Cpu_Cores']
Manufacturer, product, sn = get_dmidecode()

#####[get dict]#####
hostinfo = {
'hostname': hostname,
'ip': ip,
'osversion': osversion,
'memory': memory,
'disk': disk,
#'vendor_id': Vendor_Id,
'model_name': Model_Name,
'cpu_core': Cpu_Cores,
'product': product,
'Manufacturer': Manufacturer,
#'sn': sn,
}
print hostinfo

cat ansible_callback.py
# -*- coding:utf8 -*-
'''
Created on 2017年1月13日
ansible 2.2
ssh_args = ""
@author: qiancheng
'''
import sys
import commands
import MySQLdb
import os
import json
from collections import namedtuple
from ansible.inventory import Inventory
from ansible.vars import VariableManager
from ansible.parsing.dataloader import DataLoader
from ansible.executor.playbook_executor import PlaybookExecutor
from ansible.plugins.callback import CallbackBase
from ansible.errors import AnsibleParserError

class mycallback(CallbackBase):
# 这里是状态回调,各种成功失败的状态,里面的各种方法其实都是从写于CallbackBase父类里面的,其实还有很多,可以根据需要拿出来用
def __init__(self, *args):
super(mycallback, self).__init__(display=None)
self.status_ok = json.dumps({})
self.status_fail = json.dumps({})
self.status_unreachable = json.dumps({})
self.status_playbook = ''
self.status_no_hosts = False
self.host_ok = {}
self.host_failed = {}
self.host_unreachable = {}

def v2_runner_on_ok(self, result):
host = result._host.get_name()
self.runner_on_ok(host, result._result)
# self.status_ok=json.dumps({host:result._result},indent=4)
self.host_ok[host] = result

def v2_runner_on_failed(self, result, ignore_errors=False):
host = result._host.get_name()
self.runner_on_failed(host, result._result, ignore_errors)
# self.status_fail=json.dumps({host:result._result},indent=4)
self.host_failed[host] = result

def v2_runner_on_unreachable(self, result):
host = result._host.get_name()
self.runner_on_unreachable(host, result._result)
# self.status_unreachable=json.dumps({host:result._result},indent=4)
self.host_unreachable[host] = result

def v2_playbook_on_no_hosts_matched(self):
self.playbook_on_no_hosts_matched()
self.status_no_hosts = True

def v2_playbook_on_play_start(self, play):
self.playbook_on_play_start(play.name)
self.playbook_path = play.name

class my_ansible_play():
# 这里是ansible运行
# 初始化各项参数,大部分都定义好,只有几个参数是必须要传入的
def __init__(self, playbook, extra_vars={},
host_list='/etc/ansible/hosts',
connection='ssh',
become=False,
become_user=None,
module_path=None,
fork=50,
ansible_cfg=None,  # os.environ["ANSIBLE_CONFIG"] = None
passwords={},
check=False):
self.playbook_path = playbook
self.passwords = passwords
self.extra_vars = extra_vars
Options = namedtuple('Options',
['listtags', 'listtasks', 'listhosts', 'syntax', 'connection', 'module_path',
'forks', 'private_key_file', 'ssh_common_args', 'ssh_extra_args', 'sftp_extra_args',
'scp_extra_args', 'become', 'become_method', 'become_user', 'verbosity', 'check'])
self.options = Options(listtags=False, listtasks=False,
listhosts=False, syntax=False,
connection=connection, module_path=module_path,
forks=fork, private_key_file=None,
ssh_common_args=None, ssh_extra_args=None,
sftp_extra_args=None, scp_extra_args=None,
become=become, become_method=None,
become_user=become_user,
verbosity=None, check=check)
if ansible_cfg != None:
os.environ["ANSIBLE_CONFIG"] = ansible_cfg
self.variable_manager = VariableManager()
self.loader = DataLoader()
self.inventory = Inventory(loader=self.loader, variable_manager=self.variable_manager, host_list=host_list)

# 定义运行的方法和返回值
def run(self):
complex_msg = {}
if not os.path.exists(self.playbook_path):
code = 1000
results = {'playbook': self.playbook_path, 'msg': self.playbook_path + ' playbook is not exist',
'flag': False}
# results=self.playbook_path+'playbook is not existed'
# return code,complex_msg,results
pbex = PlaybookExecutor(playbooks=[self.playbook_path],
inventory=self.inventory,
variable_manager=self.variable_manager,
loader=self.loader,
options=self.options,
passwords=self.passwords)
self.results_callback = mycallback()
pbex._tqm._stdout_callback = self.results_callback
try:
code = pbex.run()
except AnsibleParserError:
code = 1001
results = {'playbook': self.playbook_path, 'msg': self.playbook_path + ' playbook have syntax error',
'flag': False}
# results='syntax error in '+self.playbook_path #语法错误
return code, results
if self.results_callback.status_no_hosts:
code = 1002
results = {'playbook': self.playbook_path, 'msg': self.results_callback.status_no_hosts, 'flag': False,
'executed': False}
# results='no host match in '+self.playbook_path
return code, results

def get_result(self):
self.result_all = {'success': {}, 'fail': {}, 'unreachable': {}}
# print result_all
# print dir(self.results_callback)
for host, result in self.results_callback.host_ok.items():
self.result_all['success'][host] = result._result

for host, result in self.results_callback.host_failed.items():
self.result_all['failed'][host] = result._result['msg']
# print result._result['msg']

for host, result in self.results_callback.host_unreachable.items():
self.result_all['unreachable'][host] = result._result['msg']

return self.result_all['success']

class DB():
def __init__(self):
self.db = MySQLdb.connect("localhost", "root", "root", "cmdb")
#这里自己修改地址
self.cursor = self.db.cursor()
def insert_hosts(self,dict_temps):
for i in dict_temps.keys():
dict_temp = dict_temps[i]['stdout']
ipdict = eval(dict_temp.encode("utf-8"))
ip = ipdict['ip']
hostname = ipdict['hostname']
vcpus = ipdict['cpu_core']
mem = ipdict['memory']
disk_total = ipdict['disk']
check_host = "select * from hosts_copy where IP = '%s' " % (ip)
flag = self.cursor.execute(check_host)
if flag != 0L:
sql = "update hosts_copy set hostname = '%s',vcpus = '%s',mem = '%s',disk_total ='%s' where ip = '%s' " % (
hostname, vcpus, mem, disk_total, ip)
try:
print (sql, '******************')
self.cursor.execute(sql)
# 提交到数据库执行
self.db.commit()
print (" '%s' update successfully !") % (ip)
except:
# 发生错误时回滚
self.db.rollback()
print 'Something is wrong !!! '
else:
sql = "INSERT INTO hosts_copy(ip,hostname,vcpus,mem,disk_total) VALUES('%s','%s','%s','%s','%s')" % (
ip, hostname, vcpus, mem, disk_total)
print sql
self.cursor.execute(sql)
self.db.commit()

'''
for i in self.result_all['success'].keys():
#print i, self.result_all['success'][i]
return self.result_all['success'][i]['stdout']
#print self.result_all['fail']
#print self.result_all['unreachable']
'''

if __name__ == '__main__':
play_book = my_ansible_play('/home/python/main.yml')
play_book.run()
dict_temps = play_book.get_result()
db = DB()
db.insert_hosts(dict_temps)


这样就实现通过ansible执行脚本,然后获取客户端的结果,再把它插入到数据库中。这个主要是获取硬件信息

效果图

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  ansible callback