编程语言
首页 > 编程语言> > Python3项目初始化10-->主机资产管理

Python3项目初始化10-->主机资产管理

作者:互联网

33、主机资产管理--启动
资产编号,ip, 主机名,使用者,os,mem,cpu, 上架时间,过保时间,
增、删、改、查
添加:
人工手工录入
ssh ip
hostname
cat /proc/cpuinfo
cat /proc/meminfo
主机内部安装了程序 agent =>server 上报数据(ip,hostname,os,mem,cpu)
扫描ip范围:ip,hostname,os
自动远程获取
text/csv/excel/xml =>导入ip,hostname,os,mem,cpu
其他第三方系统 => 调用API导入

删除:
人工删除
自动删除(与第三方系统结合)

改:
人工改
自动查
查:
自己查
提供数据 => API

查询、删除 => 人工
添加、删除 => 自动
修改 => 人工

model => table
资产编号,ip,主机名,使用者,os,arch,mem,cpu,disk,上架时间,过保时间,在线状态
机制
推:每周三所有人将作业发给我, agent=>sever V
拉:每周三我找所有人要, 扫描(ansible)

1、创建app
python manage.py startapp asset
2、启用app
settings INSTALLED_APPS 'asset.apps.AssetConfig',
3、app urls.py
app_name = 'asset'
urlpatterns = [
# path('index/', views.index, name='index'),
]
4、根路由配置 相关的url(/assert/)分发给app
path('asset/', include('asset.urls')),
5、models.py

#encoding: utf-8
from django.db import models
from django.utils import timezone
from django.core.exceptions import ObjectDoesNotExist

class Host(models.Model):
name = models.CharField(max_length=128, null=False, default='')
ip = models.GenericIPAddressField(null=False, default='0.0.0.0')
mac = models.CharField(max_length=32, null=False, default='')
os = models.CharField(max_length=64, null=False, default='')
arch = models.CharField(max_length=16, null=False, default='')
mem = models.BigIntegerField(null=False, default=0)
cpu = models.IntegerField(null=False, default=0)
disk = models.CharField(max_length=512, null=False, default='{}')

sn = models.CharField(max_length=128, null=False, default='')
user = models.CharField(max_length=128, null=False, default='')
remark = models.TextField(null=False, default='')
purchase_time = models.DateTimeField(null=False)
over_insurance_time = models.DateTimeField(null=False)

create_time = models.DateTimeField(null=False, auto_now_add=True)
last_time = models.DateTimeField(null=False)

6、迁移数据库
python manage.py makemigrations
python manage.py migrate
验证:mysql -uroot -pXXX -e "use cmdb_user;show create table asset_host;"

34、主机资产管理--Django command方法调用
创建Python包,怎么判断?下面必须存在__init__.py文件。
command => script.py
runserver
makemigrations
migrate
check

1、commands
app/management/commands/__init__.py
2、script.py
F:\py3proj\07\cmdb\asset\management\commands\collect_host.py
#encoding: utf-8
from django.core.management import BaseCommand

class Command(BaseCommand):
    def handle(self, *args, **options):
        print('test..')
执行 python manage.py 查看可运行的命令
python manage.py collect_host 查看运行结果。如下截图。

34、主机资产管理--ansible安装配置
win 7下载ssh客户端:https://www.mls-software.com/opensshd.html
win 7下载ansible:https://www.cnblogs.com/yuzhouliu/p/16459075.html
因win上面运行ansible可用度不高,需要转到Linux上面操作。

[root@www ~]# python3 -m venv py36django2
[root@www ~]# cd cmdb/kk/
[root@www kk]# source /root/py36django2/bin/activate
(py36django2) [root@www kk]# pip freeze
(py36django2) [root@www kk]# pip list
(py36django2) [root@www kk]# cat /etc/redhat-release
CentOS Linux release 7.6.1810 (Core)
(py36django2) [root@www kk]# pip install Django==2.0.5

拷贝代码到Linux环境
本地备份的代码:“cmdb0904-que-ansible.zip”
(py36django2) [root@www cmdb]# yum install gcc gcc-c++ python3-devel mysql-devel python-devel
(py36django2) [root@www cmdb]# pip install mysqlclient
(py36django2) [root@www cmdb]# python manage.py runserver 0.0.0.0:8080

因跟本地使用的数据库信息一致,故不需要在数据库这块下功夫,只需要安装基本的就好。
访问验证:http://192.168.1.118:8080/user/index/, 使用正常。

(py36django2) [root@www cmdb]# yum install ansible -y
(py36django2) [root@www cmdb]# cat etc/hosts 创建并编辑文件
localhost ansible_ssh_pass=Sunny@123
test ansible_host=192.168.1.106 ansible_user=root ansible_ssh_pass=Sunny@123
(py36django2) [root@www cmdb]# ansible all -i etc/hosts --list-hosts
(py36django2) [root@www cmdb]# ssh localhost
(py36django2) [root@www cmdb]# ansible all -m ping -i etc/hosts
(py36django2) [root@www cmdb]# ansible all -m setup -i etc/hosts >test.txt 全部信息

控制器 =>ssh =>受控主机
ansible --> inventory剧本

a、调用系统命令 output
b、系统命令工具 => Python封装 => python 3rd
c、python 3rd

hosts => 剧本 ansible_connection ansible_host ansible_user ansible_ssh_pass
ansible => -m module 任务 和 playbook 剧本
ansible python api

mysql/ansible/es/阿里云 =>第三方工具
python 3rd mysqlclient、ansible、pyes、requests
python使用

34、ansible--Python api
Python API ansible:https://docs.ansible.com/ansible/2.4/dev_guide/developing_api.html
(py36django2) [root@www etc]# pip install --upgrade pip
(py36django2) [root@www etc]# pip install ansible

(py36django2) [root@www etc]# pip uninstall cryptography
(py36django2) [root@www etc]# pip install -i http://mirrors.aliyun.com/pypi/simple/ --trusted-host mirrors.aliyun.com cryptography==36.0.2

(py36django2) [root@www pycharm_project_827]# cat etc/hosts
localhost ansible_ssh_pass=Sunny@123
test ansible_host=192.168.1.106 ansible_user=root ansible_ssh_pass=Sunny@123
(py36django2) [root@www pycharm_project_827]# ansible all -i etc/hosts -m ping
(py36django2) [root@www etc]# ssh-keygen -b 4096
(py36django2) [root@www etc]# ssh-copy-id -i ~/.ssh/id_rsa.pub localhost
(py36django2) [root@www etc]# ssh-copy-id -i ~/.ssh/id_rsa.pub 192.168.1.106

调整ansible位置,
(py36django2) [root@www pycharm_project_827]# cat etc/hosts
localhost
test ansible_host=192.168.1.106 ansible_user=root
(py36django2) [root@www pycharm_project_827]# ansible all -i etc/hosts -m ping
[root@www pycharm_project_827]# ansible -i etc/hosts all -m setup
[root@www pycharm_project_827]# ansible -i etc/hosts all -m setup -a "filter=ansible_os_family"
[root@www pycharm_project_827]# ansible -i etc/hosts all -m setup -a "filter=ansible_all_ipv4_addresses"

[root@www pycharm_project_827]# ansible --version
[root@www pycharm_project_827]# ansible-doc -l
[root@www pycharm_project_827]# ansible-doc -s setup

(py36django2) [root@www pycharm_project_827]# cat etc/test.py 创建api测试接口。
#!/usr/bin/env python
#encoding: utf-8

from __future__ import (absolute_import, division, print_function)
__metaclass__ = type

import json
import shutil
from collections import namedtuple
import ansible.constants as C
from ansible.executor.task_queue_manager import TaskQueueManager
from ansible.inventory.manager import InventoryManager
from ansible.parsing.dataloader import DataLoader
from ansible.playbook.play import Play
from ansible.plugins.callback import CallbackBase
from ansible.vars.manager import VariableManager
""""回调"""
class ResultCallback(CallbackBase):
    def v2_runner_on_ok(self, result, **kwargs):
        host = result._host
        print(dir())
        print(result.task_name)
        print(json.dumps({host.name: result._result}, indent=4))
Options = namedtuple('Options', ['connection', 'module_path', 'forks', 'become', 'become_method', 'become_user', 'check','diff'])
options = Options(connection='smart', module_path=[], forks=10, become=None,become_method=None, become_user=None,check=False, diff=False)

loader = DataLoader() # Takes care of finding and reading yaml, json and ini files
passwords = {}
results_callback = ResultCallback()
inventory = InventoryManager(loader=loader, sources='hosts') #剧本文件 sources='hosts'
variable_manager = VariableManager(loader=loader, inventory=inventory)

play_source = {
    "name": "test",
    "hosts": 'all', # 在哪些主机上运行。
    "gather_facts": 'no',
    "tasks": [{ # 执行的任务列表
        "name": 'fact', # 任务名称
        'setup': '' # 任务模块
    }
    ]
}
play = Play().load(play_source, variable_manager=variable_manager, loader=loader)

tqm = None
try:
    tqm = TaskQueueManager(
    inventory=inventory,
    variable_manager=variable_manager,
    loader=loader,
    options=options,
    passwords=passwords,
    stdout_callback=results_callback
    )
    result = tqm.run(play)
finally:
    if tqm is not None:
        tqm.cleanup()
    shutil.rmtree(C.DEFAULT_LOCAL_TMP, True)

(py36django2) [root@www etc]# python test.py
/root/py36django2/lib64/python3.6/site-packages/ansible/parsing/vault/__init__.py:44: CryptographyDeprecationWarning: Python 3.6 is no longer supported by the Python core team. Therefore, support for it is deprecated in cryptography and will be removed in a future release.
from cryptography.exceptions import InvalidSignature
Traceback (most recent call last):
File "test.py", line 55, in <module>
stdout_callback=results_callback
TypeError: __init__() got an unexpected keyword argument 'options'

解决方法:严格注意Python包版本,安装低版本的包,解决问题。
(py36django2) [root@www etc]# pip uninstall cryptography
(py36django2) [root@www etc]# pip uninstall ansible==2.9.27
(py36django2) [root@www etc]# pip install ansible==2.4.2.0
(py36django2) [root@www etc]# pip install cryptography==36.0.2
(py36django2) [root@www etc]# cd /tmp/pycharm_project_827/etc
(py36django2) [root@www etc]# python test.py 可以输出整个ansible信息。

将api指向model服务。
...
    last_time = models.DateTimeField(null=False)
    @classmethod
    def create_or_replace(cls,ip,name,mac,os,arch,mem,cpu,disk):
        obj = None
        try:
            obj = cls.objects.get(ip=ip)
        except ObjectDoesNotExist as e:
            obj = cls()
            obj.ip = ip
            obj.purchase_time = timezone.now()
            obj.over_insurance_time = timezone.now()
        obj.name = name
        obj.mac = mac
        obj.os = os
        obj.arch = arch
        obj.mem = mem
        obj.cpu = cpu
        obj.disk = disk
        obj.last_time = timezone.now()
        obj.save()
        return obj
编辑脚本collect_host.py服务,
#encoding: utf-8
from django.core.management import BaseCommand
import json
import os
from django.conf import settings
import shutil
from collections import namedtuple
import ansible.constants as C
from ansible.executor.task_queue_manager import TaskQueueManager
from ansible.inventory.manager import InventoryManager
from ansible.parsing.dataloader import DataLoader
from ansible.playbook.play import Play
from ansible.plugins.callback import CallbackBase
from ansible.vars.manager import VariableManager
from asset.models import Host

class ResultCallback(CallbackBase):
    def v2_runner_on_ok(self, result, **kwargs):
        if result.task_name == 'collect_host':
            self.collect_host(result._result)
            def collect_host(self, result):
                facts = result.get('ansible_facts', {})
                ip = facts.get('ansible_default_ipv4', {}).get('address', '')
                name = facts.get('ansible_nodename', '')
                mac = facts.get('ansible_default_ipv4', {}).get('macaddress', '')
                os = facts.get('ansible_os_family', '')
                arch = facts.get('ansible_architecture', '')
                mem = facts.get('ansible_memtotal_mb', '')
                cpu = facts.get('ansible_processor_vcpus', '')
                disk = [{'name': i.get('device'), 'total': int(i.get('size_total'))/1024/1024} for i in facts.get('ansible_mounts', [])]
                Host.create_or_replace(ip, name, mac, os, arch, mem, cpu, json.dumps(disk))

class Command(BaseCommand):
    def handle(self, *args, **options):
        AnsibleOptions = namedtuple('AnsibleOptions',['connection', 'module_path', 'forks', 'become', 'become_method', 'become_user', 'check','diff'])
        ansibleoptions = AnsibleOptions(connection='smart', module_path=[], forks=10, become=None, become_method=None,become_user=None, check=False, diff=False)

        loader = DataLoader() # Takes care of finding and reading yaml, json and ini files
        passwords = {}
        results_callback = ResultCallback()
        inventory = InventoryManager(loader=loader, sources=os.path.join(settings.BASE_DIR, 'etc', 'hosts')) # 剧本文件 sources='hosts'
        variable_manager = VariableManager(loader=loader, inventory=inventory)

# ansible all -i etc/hosts -m setup
        play_source = {
            "name": "cmdb",
            "hosts": 'all', # 在哪些主机上运行。
            "gather_facts": 'no',
            "tasks": [{ # 执行的任务列表
                "name": 'collect_host', # 任务名称
                'setup': '' # 任务模块
            }
            ]
        }
        play = Play().load(play_source, variable_manager=variable_manager, loader=loader)

        tqm = None
        try:
            tqm = TaskQueueManager(
                inventory=inventory,
                variable_manager=variable_manager,
                loader=loader,
                options=ansibleoptions,
                passwords=passwords,
                stdout_callback=results_callback
            )
         result = tqm.run(play)
    finally:
        if tqm is not None:
            tqm.cleanup()
        shutil.rmtree(C.DEFAULT_LOCAL_TMP, True)

(py36django2) [root@www pycharm_project_827]# cd /tmp/pycharm_project_827
(py36django2) [root@www pycharm_project_827]# python manage.py collect_host 执行脚本,查看数据库有记录。
(py36django2) [root@www etc]# mysql -uroot -pSunny@123 -e 'use cmdb_user;select * from asset_host;' 查看有记录
(py36django2) [root@www etc]# mysql -uroot -pSunny@123 -e 'use cmdb_user;select count(1) from asset_host;'

标签:10,www,--,etc,ansible,py36django2,import,root,Python3
来源: https://www.cnblogs.com/sunnyyangwang/p/16701236.html