Frank的学习之路

Day_26_CMDB_1_总结_结构的设计和数据的采集

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.自动化运维:

         代码发布系统:发布代码

         必须知道的是:

                   服务器的IPHOSTNAME

                  

         装机需求:    

         传统运维:

         10IDC运维

        

         自动化运维:

                   自动装机系统:

                   colber

                  

         必须知道的是:

                   服务器的IP,hostname

        

         年底资产审查:

                   传统运维

                   excel表格

                  

                   自动化运维:

                   需要服务器自己上报信息

                  

                   必须知道的是:

                   服务器的IPHostname,硬盘,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    # 表示MasterIP

    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      # 接受指定idsalve

salt-key -r  salve_id      # 拒绝指定idsalve

salt-key -d  salve_id      # 删除指定idsalve

"""


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代码具体类basiccpu,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代码具体类basiccpu,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')


返回顶部