运维前线:一线运维专家的运维方法、技巧与实践2.5 使用Django快速构建CMDB系统

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介:

2.5 使用Django快速构建CMDB系统


2.5.1 Django介绍

Django是一个免费的、开源的Web框架,由Python语言编写,由于其是在一个快节奏的新闻编译室环境中开发出来的,因此它的设计目的是让普通开发者的工作变得简单。Django遵循模型-视图-控制器(MVC)框架模式,目前由一个非盈利的独立组织的软件基金会(DSF)维持。

Django鼓励快速开发和干净实用的设计。Django可以更容易更快速地构建更好的Web应用程序。它是由经验丰富的开发人员来创建的,省去了Web开发的很多麻烦,因此你可以专注地开发应用程序而不需要去白费力气地重复工作。

Django目前已经被运维圈广泛使用,本文在此不会详细介绍Django的基础知识,有兴趣的朋友可以去Django官网查看更为详细的介绍,同时也有Django中文文档可供学习。

2.5.2 Django安装

Django的安装分为4个步骤,下面以Django 1.7.1、CentOS 6.5 x86_64为例进行讲解,详细步骤如下。

1.?安装Python 2.7.x

用CentOS 7以下版本的朋友需要将Python升级到2.7.x以上,Django对Python版本存在依赖,具体如图2-7所示。

编译步骤如下:

# yum install -y zlib-dev openssl-devel sqlite-devel bzip2-devel

# wget http://www.python.org/ftp/python/2.7.6/Python-2.7.6.tgz

# tar zxf Python-2.7.6.tgz

# cd Python-2.7.6

# ./configure --prefix=/usr/local

# make && make altinstall

(1)安装easy_install工具,操作命令如下:

$ wget https://bootstrap.pypa.io/ez_setup.py -O -| python

(2)安装Django,使用easy_install来安装,安装的版本为1.7.1,具体命令如下:

$ easy_install django==1.7.1

(3)测试Django的安装,操作命令如下:

$ easy_install django==1.7.1

$ django-admin –version

1.7.1

2.?MySQL安装

本文推荐使用yum命令进行安装,并设置MySQL root密码,创建cmdbtest数据库,具体安装步骤如下:

$ yum -y install mysql mysql-server

$ mysql_install_db --user=mysql

$ /etc/init.d/mysqld start

$ mysqladmin -u root password 'cmdbtest'

$ mysql -u root -pcmdbtest -e 'create database if not exists cmdbtest'

2.5.3 Django常用命令

完成Django的安装后,可以通过如下命令快速熟悉Django的操作,以便快速创建一个CMDB App,如果你对如下这些Django命令很熟悉,可以直接跳过。

(1)新建一个django-project:

$ django-admin startproject project-name

(2)新建App:

$ django-admin startapp app-name

(3)同步数据库:

$ python manage.py syncdb

(4)启动Django服务器:

$ python manage.py runserver

(5)Django Shell调试:

$ python manage.py shell

(6)帮助:

$ django-admin --help

$ python manage.py --help

2.5.4 Django的配置

1.?环境准备

笔者准备了两台测试机器用来进行代码测试,测试机器的环境信息分别如下。

(1)服务端机器信息:

IP: 10.20.122.100

Role: puppet server + cmdb

System OS: CentOS release 6.5 x86_64

Python version: 2.7.8 Django version: 1.7.1

Mysql version: 5.1.73

(2)客户端机器信息:

IP: 10.20.122.111

Role: puppet agent

System OS: CentOS release 6.5 x86_64

2.?软件安装

前几节已经对所需要的环境进行了安装,在这里我们再回顾一下:

(1)master安装Puppet Server。

(2)master安装Python。

(3)master安装MySQL。

(4)master安装Django。

(5)master安装项目依赖的Python模块。

(6)Agent安装Puppet Agent。

3.?创建CMDB项目

创建CMDB项目的同时,在这个项目中创建一个CMDB App,登录10.20.122.100,运行如下命令。

(1)创建一个Project:

$ django-admin startproject myproject

(2)进入myproject目录:

$ cd myproject

(3)创建一个CMDB App:

$ django-admin startapp cmdb

(4)创建一个存放静态文件和模板的目录:

$ mkdir static templates

运行成功后使用11命令就可以看到如图2-8所示的目录结构。

4.?配置CMDB项目信息

在图2-8中我们可以在myproject目录下看到settings.py的全局配置文件,Django在运行时会默认先加载此配置文件,因此我们需要先对它进行定义,需要配置如下6个地方,操作步骤具体如下。

(1)修改数据库设置:

DATABASES = {

'default': { 'ENGINE': 'django.db.backends.mysql',

'NAME': 'cmdbtest',

'HOST': 'localhost',

'USER': 'root',

'PASSWORD': 'cmdbtest',

'PORT': '3306',

'OPTIONS': {'init_command': 'SET storage_engine=INNODB', 'charset': 'utf8', }

} }

(2)设置App,把我们新建的CMDB App加到末尾,代码如下:

NSTALLED_APPS = ('django.contrib.admin',

'django.contrib.auth',

'django.contrib.contenttypes',

'django.contrib.sessions',

'django.contrib.messages',

'django.contrib.staticfiles', 'cmdb',

)

(3)设置静态文件存放目录:

STATICFILES_DIRS = ( os.path.join(BASE_DIR, 'static/'), )

(4)设置模板文件存放目录:

TEMPLATE_DIRS = [ os.path.join(BASE_DIR, 'templates'), ]

(5)设置登录URL:

LOGIN_URL = '/cmdb/login/'

(6)设置其他参数,可以根据自己的需求进行设置:

TEMPLATE_CONTEXT_PROCESSORS = ( 'django.core.context_processors.static', 'cmdb.context_processors.menu', "django.contrib.auth.context_processors.auth", "django.core.context_processors.request",

) CMDB_VERSION = '1.0' CMDB_NAME = u'测试 CMDB' LOGIN_REDIRECT_URL = '/home/'

到此为止基础环境已经准备完毕,接下来需要设计数据库,并定义好视图。

5.?数据表设计

Django遵循MVC设计,其中M(模型)就是数据库模型,也就是App中的models.py文件的设置,Django自带数据库的ORM(Object Relational Mapping)架构,这使得我们不用再需要学习复杂的数据库操作,只需要通过定义models即可。下面是我设置的最简单的CMDB数据结构:

# 指定解析器为Python

# !/usr/bin/env python

# 指定字符编码为utf8

# encoding:utf8

# 从django.db中导入models模块

from django.db import models

# 导入User模块

from django.contrib.auth.models import User

# Create your models here.

# 定义一个Server_Group类,从models.Model中继承,这里就是所谓的数据表结构

class Server_Group(models.Model):

    # 定义主机组名称字段

    name = models.CharField(u'主机组', max_length=255, unique=True)

    # 关联的项目字段,这里是关联一个外键

    project = models.ForeignKey("Project", verbose_name='项目名称')

    # 备注字段

    memo = models.CharField(u'备注', max_length=255, blank=True)

    # unicode返回值

    def __unicode__(self):

        # 返回的格式

        return '%s-%s' % (self.project.name, self.name)

 

    # 定义Meta属性

    class Meta:

        # 数据库中的表名

        db_table = 'server_group'

        # 存储的时候需要确认组合键是唯一的

        unique_together = (("name", "project"),)

 

# 定义一个IDC类,主要存储IDC信息,数据表结构有2个字段

class IDC(models.Model):

    # 定义IDC的名称字段

    name = models.CharField(u'IDC名称', max_length=255, unique=True)

    memo = models.CharField(u'备注', max_length=255, blank=True)

 

    def __unicode__(self):

        return self.name

 

    class Meta:

        db_table = 'idc'

 

# 定义一个Project类,主要存储项目信息,数据表结构有2个字段

class Project(models.Model):

    name = models.CharField(u'项目名称', max_length=255, unique=True)

    memo = models.CharField(u'备注', max_length=255, blank=True)

 

    def __unicode__(self):

        return self.name

 

    class Meta:

        db_table = 'project'

 

# 定义一个Server_Role类,主要存储服务器角色信息,数据表结构有3个字段

class Server_Role(models.Model):

    name = models.CharField(u'角色', max_length=255)

    # 关联Server_Group,也就是服务器组

    group = models.ForeignKey("Server_Group", verbose_name='项目组')

    memo = models.CharField(u'备注', max_length=255, blank=True)

 

    def __unicode__(self):

        return '%s-%s-%s' % (self.group.project.name, self.group.name, self.name)

 

    class Meta:

        # 设置数据库表名

        db_table = 'server_role'

        # 存储的时候需要确认组合键是唯一的

        unique_together = (("name", "group"),)

 

 

# CMDB核心数据表结构,用来存储服务器系统信息

class Server_Device(models.Model):

    # 服务器状态选择,具体的字段存储数据为0~3的int数字

    SERVER_STATUS = (

        (0, u'下线'),

        (1, u'在线'),

        (2, u'待上线'),

        (3, u'测试'),

    )

    # 定义一个名称字段,若blank没有设置则默认为False,不能为空,且unique=True必须唯一

    name = models.CharField(u'主机名称', max_length=100, unique=True)

    # 定义SN编号字段, blank=True,可以为空

    sn = models.CharField(u'SN号', max_length=200, blank=True)

    # 公网IP字段,可以为空

    public_ip = models.CharField(u'外网IP', max_length=200, blank=True)

    # 私网IP字段,可以为空

    private_ip = models.CharField(u'内网IP', max_length=200, blank=True)

    # 定义MAC地址字段

    mac = models.CharField(u'MAC地址', max_length=200, blank=True)

    # 定义操作系统字段

    os = models.CharField(u'操作系统', max_length=200, blank=True)

   # 定义磁盘信息字段

    disk = models.CharField(u'磁盘', max_length=200, blank=True)

    # 定义内存信息字段

    mem = models.CharField(u'内存', max_length=200, blank=True)

    # 定义CPU信息字段

    cpu = models.CharField(u'CPU', max_length=200, blank=True)

    # 关联IDC信息

    idc = models.ForeignKey(IDC, max_length=255, blank=True, null=True, verbose_

    name='机房名称')

    # 定义一个多对多字段,一台服务器可以对应多个角色

    role = models.ManyToManyField("Server_Role", verbose_name='角色', blank=True)

    # 机器状态,默认都为在线状态

    status = models.SmallIntegerField(verbose_name='机器状态', choices=SERVER_STATUS,

    default=1)

    # 管理用户信息

    admin = models.ForeignKey('auth.User', verbose_name='管理员', null=True, blank=True)

    # 定义备注字段

    memo = models.CharField(u'备注', max_length=200, blank=True)

 

    def __unicode__(self):

        return self.name

 

    class Meta:

        db_table = 'server_device'

初始化数据库,同时设置登录所需要的username和password,命令如下:

$ python manage.py syncdb

Operations to perform:

Apply all migrations: admin, contenttypes, auth, sessions

Running migrations:

Applying contenttypes.0001_initial... OK

Applying auth.0001_initial... OK

Applying admin.0001_initial... OK

Applying sessions.0001_initial... OK

You have installed Django's auth system, and don't have any superusers defined.

Would you like to create one now? (yes/no): yes

# 这里输入用户名

Username (leave blank to use 'root'): admin

Email address:

# 这里输入密码

Password:

# 重复输入密码

Password (again):

Superuser created successfully.

在命令行登录数据库,并查看数据库信息,就能看到如图2-9所示的内容,说明数据库已创建成功。

6.?视图设置

上文中我们已经成功设置了Django的M(Models,模型),下面我们来设置V(View,视图),如下代码是一个登出页面和一个home页面的View:

# encoding:utf8

# Create your views here.

# 导入需要使用的模块

from django.template import RequestContext

from django.shortcuts import render_to_response

from django.contrib.auth.decorators import login_required

from django.contrib.auth.views import logout_then_login

# 判断用户是否登录

@login_required

# 登出时的调用

def logout_view(request):

    return logout_then_login(request)

# 判断用户是否登录

@login_required

# 登录后调用home页所展示的页面,template为home.html

def home(request):

    return render_to_response('home.html', locals(), context_instance=RequestCo

    ntext(request))

 

URL设置(这里直接使用了Django自带的login函数,所以不需要自己写login view):

# 设置字符编码

# encoding:utf8

# 从urls中导入patterns、include、url模块

from django.conf.urls import patterns, include, url

# 从contrib中导入admin模块

from django.contrib import admin

# 从http中导入HttpResponseRedirect模块

from django.http import HttpResponseRedirect

 

# 设置前端访问的URL对应的后端视图

urlpatterns = patterns('',

                     # url什么参数都不带时,直接重定向到login

                       url(r'^$', lambda x: HttpResponseRedirect('/login/')),

                     # 登出对应的视图为cmdb.views.logout_view

                         url(r'^logout/$','cmdb.views.logout_view', name='cmdb_logout'),

                     # 登录对应的view为django.contrib.auth.views.login,对应的

                           template为login.html

                       url(r'^login/$','django.contrib.auth.views.login', {'template_

                       name': 'login.html'},

                           name='cmdb_login'),

                     # home页面,对应的view为cmdb.views.home

                       url(r'^home/$', 'cmdb.views.home', name='home'),

)

通过如上定义,现在就启动Django服务,登录后即可看到如图2-10所示的界面。代码已托管至Github网站https://github.com/oysterclub/open-cmdb,有兴趣的朋友可以去复制下来查看、修改或使用。下面就来展示一下登录界面的效果图(注,前端框架为bootstrap)。

利用python manage.py syncdb命令输入的用户名和密码登录。登录后的页面为home空白页(见图2-11),具体如下(home空白页主要是为了以后做导向流页面或数据图表展示页面,这里先留空):

 

图2-11 系统登录后的界面

7.?使用Python程序获取Facts数据

通过如上定义,我们已经完成了视图、数据表结构的定义。而数据的来源既可以通过添加,也可以通过Facter工具来获取。下面我们就来讲讲如何自动获取Agent机器的系统数据(如果想要充分了解Facter工具,可以参考阅读《Puppet实战》的第9章“Facter介绍”)。Facter工具会在Puppet Agent与Puppet Master通信的时候把获取到的Agent主机系统信息和自己定义的Facts信息汇报给Puppet Master,生成一个hostname.yaml格式的文件,文件存放在/var/lib/puppet/yaml/facts目录下,文件的格式如图2-12所示,其中的values数据:domain、ipaddress、macaddress等正是构建CMDB所需要的系统数据,因此我们可以通过一个Python程序来处理这些数据,并录入MySQL中,最终通过Django来实现前端展示。因此一个最简单的CMDB系统就构建完成了。

 

图2-12 Facter上报至Puppet Master后的yaml部分信息

我们先来具体看一下facter_message.py程序(Python程序处理Facter数据),完整代码如下:

#!/usr/bin/env python

# encoding: utf8

__authors__ = ['liuyu', 'chenlijun']

__version__ = 1.0

__date__ = '2015-09-06 14:58:23'

__licence__ = 'GPL licence'

 

# 导入模块

import yaml

import os

# IPy主要用来判断IP类型,IPy.IP('ip').iptype()

import IPy

 

# yaml文件目录

yaml_dir = '/var/lib/puppet/yaml/facts'

 

# 结果集,结果集的格式{'cmdb_agent':()}

all_host_facter_message = {}

 

# 结果列表

result_list = ['name',

               'SN',

               'public_ip',

               'private_ip',

               'mac',

               'os',

               'disk',

               'mem',

               'cpu',

               'idc',

               'role',

               'status',

               'admin',

               'memo']

 

# db对应的Facter字段,需要获取其他的字段时可以一一对应

list_field = {'name': 'fqdn',

              'public_ip': 'ipaddress__interfaces',

              'private_ip': 'ipaddress__interfaces',

              'mac': 'macaddress__interfaces',

              'os': ['operatingsystem', 'operatingsystemrelease', 'hardwaremodel'],

              'disk': 'blockdevice__blockdevices',

              'mem': 'memorysize',

              'cpu': ['processorcount', 'processor0']}

 

# ruby objectobjectconstruct

def construct_ruby_object(loader, suffix, node):

    return loader.construct_yaml_map(node)

 

def construct_ruby_sym(loader, node):

    return loader.construct_yaml_str(node)

 

# 读取数据

def yaml_file_handle(filename):

    stream = open(filename)

    mydata = yaml.load(stream)

    return mydata

 

# 获取IP的类型

def get_ip_type(ip):

    try:

        return IPy.IP(ip).iptype().lower()

    except Exception, e:

        print e

 

# 处理单个Agent的数据

def handle_facter_message(data):

    # 定义一个结果字典,字段和db一样,处理完的结果和db中的一样

    result_dict = {}

    # 对结果进行处理

    for db_field in result_list:

        # 定义一个字段结果字符

        value = ''

        # result_list中的字段是否存在于我们需要的Facter取值列表中,如果存在

        if db_field in list_field:

            facter_field = list_field[db_field]

            # 先判断facter_field的类型,然后进行处理

            if type(facter_field) == type([]):

                for tag in facter_field:

                    if data.get(tag):

                        value += data[tag] + ' '

            else:

                # 由于disk、IP等需要进一步处理,所以用了一个__来分隔,然后再进行处理

                field_tmp = facter_field.split("__")

                if len(field_tmp) == 2:

                    if db_field == 'disk':

                        for tag in data[field_tmp[1]].split(","):

                            # 对磁盘进行处理, 由于磁盘的字段为blockdevice_type_size,

                                  所以需要单独进行处理

                            f = field_tmp[0] + '_' + tag + '_' + 'size'

                            if data.get(f):

                                # 去除sr0 tag的字段

                                if tag != 'sr0':

                                    # 结果字符串

                                    value += tag + ':' + str(int(data[f]) / 1024 /

                                    1024 / 1024) + 'G' + ' '

                    # 对外网IP进行处理

                    elif db_field == 'public_ip':

                        for tag in data[field_tmp[1]].split(","):

                            f = field_tmp[0] + '_' + tag

                            if data.get(f):

                                # 去除lo tag的字段

                                if tag != 'lo':

                                    if get_ip_type(data[f]) == 'public':

                                        # 结果字符串

                                        value += data[f] + ' '

                    # 对内外IP进行处理

                    elif db_field == 'private_ip':

                        for tag in data[field_tmp[1]].split(","):

                            f = field_tmp[0] + '_' + tag

                            if data.get(f):

                                # 去除lo tag的字段

                                if tag != 'lo':

                                    if get_ip_type(data[f]) == 'private':

                                        # 结果字符串

                                        value += data[f] + ' '

                    else:

                        # 其他的字段直接就处理了

                        for tag in data[field_tmp[1]].split(","):

                            f = field_tmp[0] + '_' + tag

                            if data.get(f):

                                # 去除lo tag的字段

                                if tag != 'lo':

                                    # 结果字符串

                                    value += tag + ':' + data[f] + ' '

                else:

                    if data.get(facter_field):

                        # 结果字符串

                        value = data[facter_field]

            # 将结果添加到result列表中

            result_dict[db_field] = value.strip()

        # 如果不存在

        else:

            result_dict[db_field] = ''

    # 返回结果字典

    return result_dict

 

# 定义获取facter的函数

def get_all_host_facter_message():

    # 由于Puppet的yaml文件是Ruby格式的,因此需要进行转换

    yaml.add_multi_constructor(u"!ruby/object:", construct_ruby_object)

    yaml.add_constructor(u"!ruby/sym", construct_ruby_sym)

    # 获取所有有Facter信息的主机文件名称

    for dirpath, dirnames, filenames in os.walk(yaml_dir):

        # 只需要处理yaml目录下以yaml结尾的文件

        if dirpath == yaml_dir:

            for file in filenames:

                file_name, file_ext = os.path.splitext(file)

                if file_ext == '.yaml':

                    host_yaml_path = yaml_dir + '/' + file

                    # 得到yaml文件的内容, 字典形式

                    host_yaml_result_dict = yaml_file_handle(host_yaml_path)

                    # 对单个Agent的数据进行处理

                    if host_yaml_result_dict:

                        # 由于有key为facts,所以可以直接查找facts key的值

                        if host_yaml_result_dict.has_key('facts'):

                            data_dict = host_yaml_result_dict['facts']['values']

                        # 没有的就直接取

                        else:

                            data_dict = host_yaml_result_dict['values']

 

                    # 现在就可以对data进行处理,获取我们所需要的数据了

                    result_dict = handle_facter_message(data_dict)

                    all_host_facter_message[file_name] = result_dict

    #返回我们最终的数据结果集

    return all_host_facter_message

以上程序可以过滤Facter中我们想要得到的Agent数据,运行facter_message.py程序,结果输出如下:

$ python facter_message.py

{'puppetclient.domain.com':

{'status': '',

'name': 'puppetclient.domain.com',

'mem': '1.83 GB',

'memo': '',

'idc': '',

'public_ip': '',

'admin': '',

'mac': 'eth0:00:1A:4A:25:E2:12 eth1:00:1A:4A:25:E2:13',

'role': '',

'private_ip': '10.20.122.111',

'disk': 'vda:20G vdb:30G',

'os': 'CentOS 6.5 x86_64',

'cpu': '2 Intel Core 2 Duo P9xxx (Penryn Class Core 2)',

'SN': ''}

}

到这里,我们能够看到facter_message.py得到的数据字段和models.py中数据结构的字段正好一样,下一步我们就可以直接将facter_message.py的数据导入到数据库中了,具体程序如下:

# 检测用户是否登录

@login_required

# 定义一个views,用来处理导入信息

def import_data(request, model):

    # 导入计数器

    import_num = 0

    # 查看model是否存在于定义的模板中

    if model in BASE_ADMIN:

        # 获取tag名称

        tag_name = BASE_ADMIN[model]['name']

        # 获取model名称

        model_name = BASE_ADMIN[model]['model']

        # 这里只处理server_device的导入信息

        if model == 'server_device':

            server_device_data = get_all_host_facter_message()

            # 进行数据入库处理

            for hostname, facter_message in server_device_data.items():

                # 主机名处理,判断facter_message中name key是否有值,

                if facter_message['name']:

                    # 如果有值,name就使用该值

                    name = facter_message['name']

                # 如果没有这个值

                else:

                    # 就使用hostname

                    name = hostname

                # 对于IDC信息、User信息、项目角色信息的处理都需要自己去写Facter插件,不

                       写的都为空,然后进行处理

                # IDC关联处理,如果facter_message中的idc key有值

                if facter_message['idc']:

                    # idc_name就为该值

                    idc_name = facter_message['idc']

                    # 同时处理该IDC信息是否存在于IDC表中,如果有则取出ID

                    if IDC.objects.filter(name=idc_name):

                        idc_id = IDC.objects.get(name=idc_name).id

                    # 如果没有,则进行保存,然后取出ID

                    else:

                        idc_sql = IDC(name=idc_name)

                        try:

                            idc_sql.save()

                            # 取出ID

                            idc_id = IDC.objects.get(name=idc_name).id

                        except Exception, e:

                            return e

                # 如果idc key没有值,则为None

                else:

                    idc_id = None

                # 管理员信息关联处理,如果用户存在则关联,不存在则跳过

                if facter_message['admin']:

                    admin_name = facter_message['admin']

                    # 如果用户存在User表中则取ID,若没有则为空

                    if User.objects.filter(username=admin_name):

                        user_id = User.objects.get(username=admin_name).id

                    else:

                        user_id = None

                # 没有就为空

                else:

                    user_id = None

                # 这里还有一个角色多对多关系的处理,由于这里没有定义机器角色,因此此处不处理

                      角色信息

                # 判断主机是否存在于server_device表中,如果不存在则添加

                if not model_name.objects.filter(name=name):

                    import_sql = model_name(name=name,

                                            sn=facter_message['sn'],

                                            public_ip=facter_message['public_ip'],

                                            private_ip=facter_message['private_ip'],

                                            mac=facter_message['mac'],

                                            idc=idc_id,

                                            os=facter_message['os'],

                                            disk=facter_message['disk'],

                                            mem=facter_message['mem'],

                                            cpu=facter_message['cpu'],

                                            admin=user_id,

                                            memo=facter_message['memo'],

                    )

                    try:

                        # 保存

                        import_sql.save()

                    except Exception, e:

                        return e

                # 如果有了,则查询数据,若信息不对则更新

                elif not model_name.objects.filter(name=name,

                    sn=facter_message['sn'],

                    public_ip=facter_message['public_ip'],

                    private_ip=facter_message['private_ip'],

                    mac=facter_message['mac'],

                    os=facter_message['os'],

                    disk=facter_message['disk'],

                    mem=facter_message['mem'],

                    cpu=facter_message['cpu'],

                    memo=facter_message['memo']):

                    try:

                        # 更新数据库

                            model_name.objects.filter(name=name).update(sn=

                            facter_message['sn'],

                            public_ip=facter_message['public_ip'],

                            private_ip=facter_message['private_ip'],

                            mac=facter_message['mac'],

                            os=facter_message['os'],

                            disk=facter_message['disk'],

                            mem=facter_message['mem'],

                            cpu=facter_message['cpu'],

                            memo=facter_message['memo'],

                        )

                    except Exception, e:

                        return e

                # 如果有了,且信息ok,则跳过

                else:

                    continue

        return HttpResponseRedirect('/cmdb/%s/show/' % model)

 

    return render_to_response('all_data_show.html', locals(), context_instance=RequestContext(request))

重新登录CMDB之后的页面,有一个导入主机的按钮,点击导入主机按钮,就可以自动导入通过Facter获取的Agent主机信息了,如图2-13所示。

我们还可以通过添加的方式来维护CMDB的内容,到目前为止我们已经完成了使用Python和Puppet来构建一个小型的、简单的CMDB系统。

CMDB是需要我们定期进行维护和更新的,因此它还需要提供历史查看、API等更实用的功能,为此在2.6节中我们将介绍一下Django提供的几个好用的功能模块。

 

图2-13 信息导入界面

相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
16天前
|
运维 监控 持续交付
自动化运维在现代数据中心的应用与实践####
本文探讨了自动化运维技术在现代数据中心中的应用现状与实践案例,分析了其如何提升运维效率、降低成本并增强系统稳定性。通过具体实例,展示了自动化工具如Ansible、Puppet及Docker在环境配置、软件部署、故障恢复等方面的实际应用效果,为读者提供了一套可参考的实施框架。 ####
|
16天前
|
运维 监控 Devops
自动化运维实践:打造高效的DevOps流水线
在软件开发的快节奏中,自动化运维成为提升效率、确保质量的关键。本文将引导你理解自动化运维的价值,通过实际案例分享如何构建一个高效、可靠的DevOps流水线。我们将从持续集成(CI)开始,逐步深入到持续部署(CD),并展示代码示例来具体说明。准备好让你的运维工作飞跃式进步了吗?让我们开始吧!
|
16天前
|
人工智能 运维 自然语言处理
智能化运维:AI在IT运维领域的深度应用与实践####
本文探讨了人工智能(AI)技术在IT运维领域的深度融合与实践应用,通过分析AI驱动的自动化监控、故障预测与诊断、容量规划及智能决策支持等关键方面,揭示了AI如何赋能IT运维,提升效率、降低成本并增强系统稳定性。文章旨在为读者提供一个关于AI在现代IT运维中应用的全面视角,展示其实际价值与未来发展趋势。 ####
111 4
|
18天前
|
机器学习/深度学习 数据采集 人工智能
智能化运维在企业IT管理中的应用与实践####
本文深入探讨了智能化运维(AIOps)的核心技术原理,通过对比传统运维模式,揭示了AIOps如何利用大数据、机器学习等先进技术提升故障预测准确性、优化资源分配及自动化处理流程。同时,文章详细阐述了智能化运维平台的实施步骤,包括数据收集与分析、模型训练与部署、以及持续监控与优化,旨在为企业IT部门提供一套切实可行的智能化转型路径。最后,通过几个典型应用案例,如某大型电商平台的智能告警系统和金融企业的自动化故障排查流程,直观展示了智能化运维在实际业务场景中的显著成效,强调了其在提升运维效率、降低运营成本方面的关键作用。 ####
42 4
|
19天前
|
数据采集 机器学习/深度学习 人工智能
智能运维在IT管理中的实践与探索
【10月更文挑战第21天】 本文深入探讨了智能运维(AIOps)技术在现代IT管理中的应用,通过分析其核心组件、实施策略及面临的挑战,揭示了智能运维如何助力企业实现自动化监控、故障预测与快速响应,从而提升整体运维效率与系统稳定性。文章还结合具体案例,展示了智能运维在实际环境中的显著成效。
41 4
|
22天前
|
机器学习/深度学习 数据采集 人工智能
智能化运维:从自动化到AIOps的演进与实践####
本文探讨了智能运维(AIOps)的崛起背景,深入分析了其核心概念、关键技术、应用场景及面临的挑战,并对比了传统IT运维模式,揭示了AIOps如何引领运维管理向更高效、智能的方向迈进。通过实际案例分析,展示了AIOps在不同行业中的应用成效,为读者提供了对未来智能运维趋势的洞察与思考。 ####
53 1
|
29天前
|
运维 监控 持续交付
云计算环境下的运维自动化实践
本文探讨了在云计算环境下实施运维自动化的必要性、挑战及解决方案,重点介绍了如何利用现代技术工具实现高效的云资源管理和监控。通过具体案例分析,展示了自动化运维在提升系统稳定性、降低人力成本方面的优势。
|
25天前
|
数据采集 机器学习/深度学习 人工智能
智能运维在IT管理中的实践与探索####
【10月更文挑战第21天】 本文深入探讨了智能运维(AIOps)技术在现代IT管理中的应用,通过分析其核心组件、实施策略及面临的挑战,揭示了智能运维如何助力企业实现自动化监控、故障预测与快速响应,从而提升整体运维效率与系统稳定性。文章还结合具体案例,展示了智能运维在实际环境中的显著成效。 ####
|
28天前
|
数据采集 机器学习/深度学习 运维
智能运维在IT服务管理中的实践与挑战####
本文深入探讨了智能运维(AIOps)在现代IT服务管理中的应用,通过分析其如何提升效率、预测故障并优化资源分配,阐述了智能运维的实施策略与面临的主要挑战。不同于传统摘要,本部分旨在直接概述文章的核心观点与结论,为读者提供快速了解全文主旨的窗口。
|
1月前
|
Python
Django 框架的路由系统
Django 框架的路由系统
44 6
下一篇
DataWorks