10分钟用python搭建一个超好用的CMDB系统


Posted in Python onJuly 17, 2019

CMDB 是什么,作为 IT 工程师的你想必已经听说过了,或者已经烂熟了,容我再介绍一下,以防有读者还不知道。CMDB 的全称是 Configuration Management Data Base,翻译下就是配置管理数据库,它存储与管理企业 IT 架构中设备的各种配置信息,它支撑服务流程的运转、发挥着配置信息的价值。在今天,无论是自动化运维、标准化运维、DevOps、甚至是时髦的智能运维,其实都离开不 CMDB,可以说 CMDB 是运维体系的基石,有了配置信息数据库,后面各种标准、流程都可以建立在 CMDB 基础之上,从而实现真正的标准化、自动化、智能化运维,节约运维成本的同时,也降低运维流程混乱带来的操作风险。

今天分享一个开源的 cmdb 系统的搭建过程,通过这一系列搭建的过程你不仅可以获得一个支持全文检索、自带 restful api 的 cmdb 系统,而且还可以学到不少时髦的技术。

后端技术:

  • Python3
  • Django
  • Django REST framework
  • Elasticsearch
  • uwsgi
  • Nginx
  • Docker

前端技术:

  • Vue
  • Element-ui
  • Vue-Router
  • Vuex
  • Axios

先看一下这个 CMDB 系统的容颜,设计上参考了饿了么内部的 cmdb 系统:

10分钟用python搭建一个超好用的CMDB系统

基本功能有:热添加删除表、自定义字段类型,方便增删改查的前端界面,强大的搜索查找能力(后端使用elasticsearch存储数据 ) 可以配合 kibana 使用,查看数据的删除修改记录、历史版本等,还带有表级权限管理,开放所有 API。

github 仓库
后端:https://github.com/open-cmdb/cmdb
前端:https://github.com/open-cmdb/cmdb-web

下面介绍两种方法搭建此开源 cmdb 系统 ,一个是使用 Docker,适用于 linux 操作系统 ,另一个是不使用 Docker,适用于 windows 和 linux 。最后介绍下 vue 环境的搭建。

1. 使用 Docker

如果你熟悉容器技术,推荐使用此方法,不过最新的 Docker 目前还不支持大多数的 windows 版本,因此如果使用容器,请使用 ubuntu 或 centos 等 Linux 操作系统。首先要安装 Docker,安装 Docker 的方法请参考我之前的一篇文章docker容器从入门到痴迷,或直接网上搜索对应操作系统的安装方法对着做即可,没有难度。

环境准备:

1、一台可以访问互联网的 linux 服务器 内存最好 >= 4G ,并创建一个具有 sudo 权限的普通用户,注意要有 yum 命令,如果没有可以安装下
2、一个 cmdb 专用的邮箱,用于发送密码和验证码,如果使用163、qq等第三方邮箱请在设置里面打开POP3/SMTP/IMAP服务并生成授权码。如果不使用注册和忘记密码功能,也可以不准备

一键安装

将下述代码保存到 install_cmdb.py 并执行 sudo python3 install_cmdb.py 即可一键安装。

# -*- coding: utf-8 -*-
import os
import subprocess
import argparse
import time

def base(cmd):
 if subprocess.call(cmd, shell=True):
  raise Exception("{} 执行失败".format(cmd))

def install_docker():
 base("sudo yum install -y yum-utils device-mapper-persistent-data lvm2")
 base("sudo yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo")
 base("sudo yum makecache fast")
 base("sudo yum -y install docker-ce")
 if(not os.path.exists("/etc/docker")):
  base("mkdir -p /etc/docker")
 with open("/etc/docker/daemon.json", "w") as f:
  f.write('{\n "registry-mirrors": ["https://9f4w4icn.mirror.aliyuncs.com"] \n}')
 base("sudo systemctl daemon-reload")
 base("sudo systemctl start docker")

def create_dir():
 if (not os.path.exists("/var/cmdb/db")):
  base("sudo mkdir -p /var/cmdb/db")
 if (not os.path.exists("/var/cmdb/es")):
  base("sudo mkdir -p /var/cmdb/es")

def run_db_container():
 base("sudo docker run --name cmdb-db -d -e MYSQL_ROOT_PASSWORD=cmdbcmdb -v /var/cmdb/db:/var/lib/mysql mysql:5.7.21")

def run_es_container():
 base("sudo docker run --name cmdb-es -d -v /var/cmdb/es:/usr/share/elasticsearch/data elasticsearch:5.6.8")

def init_db():
 base("sudo docker run -it --rm --link cmdb-db -e ENV=PRO -e DB_HOST=cmdb-db -e DB_PORT=3306 -e DB_USERNAME=root -e DB_PASSWORD=cmdbcmdb -e DB_NAME=cmdb mingmingtang/cmdb init-db")

def run_cmdb_container(site_url, email_host, email_port, email_username, email_password):
 base("sudo docker run -d --name cmdb --link cmdb-db --link cmdb-es -p 80:80 -e ENV=PRO -e SITE_URL={} -e DB_HOST=cmdb-db -e DB_PORT=3306 -e DB_USERNAME=root -e DB_PASSWORD=cmdbcmdb -e DB_NAME=cmdb -e ELASTICSEARCH_HOSTS=cmdb-es -e EMAIL_HOST={} -e EMAIL_PORT={} -e EMAIL_USERNAME={} -e EMAIL_PASSWORD={} mingmingtang/cmdb start".format(site_url, email_host, email_port, email_username, email_password))

def input_para(help):
 value = ""
 while(not value):
  value = raw_input(help)
 return value

if __name__ == '__main__':
 if(os.geteuid() != 0):
  raise("请以root权限运行")
 site_url = input_para("请输入网站域名或IP(http://cmdb.xxx.com):")
 email_host = input_para("网站邮箱服务器(smtp.163.com):")
 email_port = input_para("邮箱服务器端口(25):")
 email_username = input_para("邮箱用户名(cmdb@163.com):")
 email_password = input_para("邮箱密码|独立授权码(P@ssw0rd):")

 print("开始安装docker")
 install_docker()
 print("开始创建目录")
 create_dir()
 print("开始运行mysql容器")
 run_db_container()
 print("开始运行elasticsearch容器")
 run_es_container()
 print("等待数据库启动完成(10s)")
 time.sleep(10)
 print("开始初始化数据库")
 init_db()
 print("开始运行cmdb")
 run_cmdb_container(site_url, email_host, email_port, email_username, email_password)
 print("完成!")

输入网站地址和邮箱信息开始安装,如下图所示:

10分钟用python搭建一个超好用的CMDB系统

如果一切顺利一会儿后您将看到安装完成,如果失败了可能就要调整一些系统参数并删除已运行的容器重新执行了,不过根据我的安装经验,基本不会出错,容器还是非常方便部署的。

10分钟用python搭建一个超好用的CMDB系统

执行

sudo docker ps

将看到三个正在运行的容器,分别是 cmdb,cmdb-es,cmdb-db,如下图所示

10分钟用python搭建一个超好用的CMDB系统

其中 cmdb 运行着 web 服务器(nginx,uwsgi,django,vue.js),cmdb-es 运行着 Elasticsearch 全文检索引擎,也存储你的配置信息,cmdb-db 运行着 mysql,保存着 web 服务器的元数据(django 的知识库)。

在浏览器中输入"localhost" 尽情的开始享用吧。

2. 不使用 Docker

下面的内容主要是分享给 windows 用户的,linux 用户也可以对比操作,没有问题。使用 Docker 虽然方便部署,但它屏蔽了一些细节,不利于二次开发和问题排查。在不使用 Docker 的情况下,我们不仅要装软件,还要安装依赖,配置环境,虽然麻烦,但是可以学到更多知识,出了问题也可以很快定位,更能加深对项目框架的理解,也是值得的。

(1)安装 mysql,创建数据库,配置权限

如果你的本机已经安装 mysql,则不心再安装,直接创建数据库,配置权限即可。

安装 mysql

从网官下载最新的 MySQL Community Server [https://dev.mysql.com/downloads/mysql/]
比如我下载的是 mysql-8.0.12-winx64.zip ,这是个免安装版本,直接解压到你想安装的目录内,并在里面新建 my.ini 文件,位置如下图所示:

10分钟用python搭建一个超好用的CMDB系统

my.ini 的文件内容如下所示:

[mysqld]
# 设置3306端口
port=3306
# 设置mysql的安装目录
basedir=D:\program\mysql\mysql-8.0.12-winx64
# 设置mysql数据库的数据的存放目录
datadir=D:\program\mysql\mysql-8.0.12-winx64\data
# 允许最大连接数
max_connections=200
# 允许连接失败的次数。这是为了防止有人从该主机试图攻击数据库系统
max_connect_errors=10
# 服务端使用的字符集默认为UTF8
character-set-server=utf8
# 创建新表时将使用的默认存储引擎
default-storage-engine=INNODB
# 默认使用“mysql_native_password”插件认证
default_authentication_plugin=mysql_native_password
[mysql]
# 设置mysql客户端默认字符集
default-character-set=utf8
[client]
# 设置mysql客户端连接服务端时默认使用的端口
port=3306
default-character-set=utf8

请注意下面的路径设置要正确,

# 设置mysql的安装目录
basedir=D:\program\mysql\mysql-8.0.12-winx64
# 设置mysql数据库的数据的存放目录
datadir=D:\program\mysql\mysql-8.0.12-winx64\data

如果你想从任意一个命令窗口启动 mysql,请把 D:\program\mysql\mysql-8.0.12-winx64\bin 加入环境变量。*

这个 my.ini 文件的编码一定保存为 gbk 格式,否则会报错,我费了好长时间才发现这个问题。

接下来在MySQL安装目录的 bin 目录(D:\program\mysql\mysql-8.0.12-winx64\bin)下以管理员权限执行命令:mysqld --initialize --console;执行完成后,在输出信息中会打印 root 用户的初始密码,比如

[Server] A temporary password is generated for root@localhost: rIafvf5f5G,a

表示临时密码为 rIafvf5f5G,a ,用于 root 用户第一次登陆,之后再修改 root 用户的密码。

这一步执行后完成初始化操作,并在安装目录下生成 data 文件夹,用于存放数据。执行

mysqld --install

完成 mysql 服务的安装,安装完成之后,就可以通过命令 net start mysql 启动 mysql 的服务了。通过命令 net stop mysql 停止服务。通过命令 sc delete mysql /mysqld -remove 卸载 mysql 服务。接下来就可以建库、用户、分配权限了。

修改 root 密码:
在 mysql 安装目录的 bin 目录下执行命令:mysql -u root -p 然后输入上面的密码,进入 mysql 环境,执行

ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '新密码';

注意命令尾的“;”一定要有,这是 mysql 的语法,

管理员 root 的 host 是 localhost,代表仅限 localhost 登录访问。如果要允许开放其他 ip 登录,则需要添加新的 host。如果要允许所有 ip 访问,可以直接修改成“%”;

ALTER USER 'root'@'%' IDENTIFIED BY '远程登陆密码';

创建数据库,并分配用户权限

使用 root 用户登陆 mysql 并执行

mysql>create database cmdb;

即可创建数据库 cmdb,但是这个数据库只能有 root 访问,如果要使用其他用户访问,则先新建用户,例如让 aaron 用户可以完全控制 cmdb

mysql>CREATE USER 'aaron'@'%' IDENTIFIED BY 'aaron';
Query OK, 0 rows affected (0.48 sec)
mysql> grant all on cmdb.* to 'aaron'@'%';
Query OK, 0 rows affected (0.23 sec)

至此 mysql 已安装配置完毕。

(2)安装 Elasticsearch

这一步很简单,官网下载解压,进入其 bin 目录运行如下图所示的 bat 文件即可 :

10分钟用python搭建一个超好用的CMDB系统

如果运行失败,说明本机没有安装 java,或者没有正确地配置 java 环境变量,这些操作也非常简单,网上到处都是,不在此详述。

(3)运行 cmdb 后端 api 服务、前端 ui

首先准备 Python3 的环境,这个也很简单,直接官网下载,运行即可,记得把 Python 添加到 Path 变量中。

如果你的电脑里有多个项目,为防止项目的依赖包版本冲突,建议使用 virtualenv 来为每个项目前创建一个虚拟的 Python 环境,将各自的依赖包装在自己的虚拟环境里。

(1)部署后端

执行以下命令,注意命令后面的注释。

git clone https://github.com/open-cmdb/cmdb.git
cd cmdb
#如创建了虚拟环境,请先激活
pip install -r requirements.txt #如果这一步有包安装失败,提示却少 microsoft visual c++ 14.0 的话,请在网站 https://www.lfd.uci.edu/~gohlke/pythonlibs/ 上查找相应的whl文件,直接 pip install .whl文件即可。

接下来修改3个文件

修改 apps/mgmt/views.py 文件,注释掉 “ from . import initialize ”这一行。

修改 manage.py

将 APP_NAME = BASE_DIR.rsplit("/", 1)[-1] 修改为

APP_NAME = BASE_DIR.rsplit("\", 1)[-1] ,这是因为windows的路径\ 在python 里会变成 \。

修改 cmdb/settings.py 文件,修改mysql 数据库的配置信息如下所示:

DATABASES = {
 'default': {
 'ENGINE': 'django.db.backends.mysql',
 'NAME': "cmdb",
 "HOST": "127.0.0.1",
 "PORT": 3306,
 "USER": "aaron",
 "PASSWORD": "aaron"
 }
}

接着在命令窗口继续执行以下操作:请关注注释内容。

python manage.py makemigrations 
python manage.py migrate
python manage.py cmdb_create_superuser #这一步创建一可以登陆的管理员用户
#修改 apps/mgmt/views.py 文件,取消注释“ from . import initialize ”
python manage.py runserver #这一步启动后端的 api 服务

此时一个后端的服务已经启动了,在浏览器中打开 “127.0.0.1:8000”就可以看到 api 的接口了。

10分钟用python搭建一个超好用的CMDB系统

(2)使用 nginx 部署前端并连接后端 api 服务

在命令容器执行以下命令:

git clone https://github.com/open-cmdb/cmdb-web.git

获取前端的源代码,然后下载下载 ngnix 压缩包,并解压至安装目录,修改配置文件 nginx.conf,添加如下 server 配置:

server {
  listen 8080;
  server_name localhost;
  error_page 500 502 503 504 /50x.html;
  location = /50x.html {
  root html;
  }
  
  root E:\GitHub\cmdb-web\dist;
  index index.html;
  location / {
  try_files $uri $uri/ @router;
  index index.html;
  }
  
  location @router {
  rewrite ^.*$ /index.html last;
  }

  location ~ /api{
  proxy_pass http://127.0.0.1:8000;
  }
 }

其中以配置

location ~ /api{
  proxy_pass http://127.0.0.1:8000;
  }

让前台发过来中以 api 开头的 url 请求都转发至 http://127.0.0.1:8000 进行解析,即第一步部署的 django 项目,这样就连接了前端和后端。然后我们在 nginx.exe 所在的目录下启动 nginx 服务。

10分钟用python搭建一个超好用的CMDB系统

接下来在浏览器中输入 127.0.0.1:8080 即可正常访问本文开始处的 cmdb 系统,您可以尝试下强大的搜索功能及增删改功能。

10分钟用python搭建一个超好用的CMDB系统

点击右上方【API 文档】 可以访问 cmdb 的接口文档,非常方便。

10分钟用python搭建一个超好用的CMDB系统

至此系统搭建完毕。如果要用于生产环境,请使用 linux 操作系统,并使用 uwsgi 来驱动 django 项目。

3. Vue 环境搭建

我想你不会仅仅满足于将别人的项目下载下来能运行就行了,你肯定想对其进行改造来满足自己的需求。因此你可能会需要修改前端或后端,后端的修改其实上面部署的已经可以了,你可以直接阅读 django 项目的源代码进行修改调试。如果要修改前端代码进行调试,你就需要搭建 Vue 环境。

你可能会问了,Vue 是个啥?Vue 是一个 javascript 框架,如果说 jQuery,你可能就知道了,使用方法是类似的,在 html 上引入一行 javascript 的文件,就可以使用框架的特性了。 Vue 是一套用于构建用户界面的渐进式框架。与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用。Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合。另一方面,当与现代化的工具链以及各种支持类库结合使用时,Vue 也完全能够为复杂的单页应用提供驱动。
学习 vue 需要有 html、css、javascript 基础
新手可以通过 html 上引入 Vue 的 js 文件来使用 vue,如下所示:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Vue 测试实例 </title>
	<script src="https://cdn.staticfile.org/vue/2.4.2/vue.min.js"></script>
</head>
<body>
<div id="app">
 	<p>{{ message }}</p>
</div>

<script>
 new Vue({
	 el: '#app',
	 data: {
	 message: 'Hello Vue.js!'
	 }
})
</script>
</body>
</html>

但是在较复杂的项目中,还是要使用工具来帮助我们管理项目的层级及文件之间的依赖关系,这就需要使用 vue 的命令行工具 vue-cli ,vue-cli 需要 npm 工具来安装,npm 工具集成在 node.js 中,因此需要安装 node.js。

安装 node.js 非常简单,直接官网下载解压即可使用:

10分钟用python搭建一个超好用的CMDB系统

将此路径添加到环境变量 Path 中,你就可以在任意的命令窗口使用 npm 命令了。

1、安装 vue-cli

先安装淘宝镜像,大家都知道国内直接使用 npm 的官方镜像是非常慢的,这里推荐使用淘宝 NPM 镜像。

npm install -g cnpm --registry=https://registry.npm.taobao.org

执行结果如下:

10分钟用python搭建一个超好用的CMDB系统

这样就可以使用 cnpm 命令来安装模块了:使用 cnpm 安装 vue-cli

10分钟用python搭建一个超好用的CMDB系统

然后就可以使用 vue init webpack my-project 来建一个项目my-project,这里需要进行一些配置,默认回车即可,如下图所示:

10分钟用python搭建一个超好用的CMDB系统

等依赖安装完毕后,进入项目,执行以下命令:

C:\Users\xx>cd my-project
C:\Users\xx\my-project>cnpm install
C:\Users\xx\my-project>cnpm run dev

运行成功后后打印如下信息:

10分钟用python搭建一个超好用的CMDB系统

此时打开浏览器,输入 http://localhost:8081

10分钟用python搭建一个超好用的CMDB系统

如果要把这个页面部署在 nginx 服务器上,你还需要 build 来生成静态资源,如下图所示:

10分钟用python搭建一个超好用的CMDB系统

这时会在 my-project 下生成 dist 目录,相当于我们写程序编译生成的目标文件。my-project 下的内容如下:

10分钟用python搭建一个超好用的CMDB系统

10分钟用python搭建一个超好用的CMDB系统

此时已经可以开启你的 vue 之旅了。

当学会了 Vue 之后,你就可以修改本项目的前端源代码来满足自己的需求了,进入 src 目录,查看并修改源代码之后,进入 cmdb_web 的项目目录,执行

# 安装依赖,如果慢可换成 cnpm
npm install
# 启动服务,默认端口为8080,如果被占用会自动选取一个未被占用的端口
npm run dev
# 建立静态文件,可以放在 nginx 上运行
npm run build
# 查看建立报告
npm run build --report

即可将生成的 dist 部署到 web 服务器了。

也许你想这样实在太麻烦了,自己动手写一个 cmdb 系统,当然也可以,但是我不推荐这样做,毕竟你的时间是有限的,自己写一个要比拿优秀的代码来改造要慢得多,当然大神例外,作为一般人我们应该避免重复造轮子,学会站在巨人的肩膀上。开发一个项目最好是找 github 上优秀的开源项目,拿来做修改以满足自己的需求,这才是正确的做法。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
python爬虫入门教程--快速理解HTTP协议(一)
May 25 Python
python实现堆和索引堆的代码示例
Mar 19 Python
完美解决python3.7 pip升级 拒绝访问问题
Jul 12 Python
你还在@微信官方?聊聊Python生成你想要的微信头像
Sep 25 Python
python 实现将小图片放到另一个较大的白色或黑色背景图片中
Dec 12 Python
keras获得model中某一层的某一个Tensor的输出维度教程
Jan 24 Python
postman和python mock测试过程图解
Feb 22 Python
Python运行异常管理解决方案
Mar 09 Python
Python使用os.listdir和os.walk获取文件路径
May 21 Python
python numpy库np.percentile用法说明
Jun 08 Python
PyCharm 2020.2下配置Anaconda环境的方法步骤
Sep 23 Python
DjangoRestFramework 使用 simpleJWT 登陆认证完整记录
Jun 22 Python
在SQLite-Python中实现返回、查询中文字段的方法
Jul 17 #Python
PIL图像处理模块paste方法简单使用详解
Jul 17 #Python
python 实现GUI(图形用户界面)编程详解
Jul 17 #Python
解决python tkinter界面卡死的问题
Jul 17 #Python
Python 实现数据结构-堆栈和队列的操作方法
Jul 17 #Python
Python 实现数据结构-循环队列的操作方法
Jul 17 #Python
Python图像处理PIL各模块详细介绍(推荐)
Jul 17 #Python
You might like
无JS,完全php面向过程数据分页实现代码
2012/08/27 PHP
php基于Fleaphp框架实现cvs数据导入MySQL的方法
2016/02/23 PHP
让iframe自适应高度(支持XHTML,支持FF)
2007/07/24 Javascript
JS添加删除一组文本框并对输入信息加以验证判断其正确性
2013/04/11 Javascript
js jquery获取随机生成id的服务器控件的三种方法
2013/07/11 Javascript
JQuery each打印JS对象的方法
2013/11/13 Javascript
node.js中使用q.js实现api的promise化
2014/09/17 Javascript
JQuery中使用on方法绑定hover事件实例
2014/12/09 Javascript
PHP 数组current和next用法分享
2015/03/05 Javascript
JavaScript获得表单target属性的方法
2015/04/02 Javascript
jQuery实现网页抖动的菜单抖动效果
2015/08/07 Javascript
jQuery实现的登录浮动框效果代码
2015/09/26 Javascript
jquery实现简单实用的弹出层效果代码
2015/10/15 Javascript
js实现瀑布流的三种方式比较
2020/06/28 Javascript
Bootstrap按钮功能之查询按钮和重置按钮
2016/10/26 Javascript
Javascript实现跨域后台设置拦截的方法详解
2017/08/04 Javascript
laravel5.4+vue+element简单搭建的示例代码
2017/08/29 Javascript
vue中v-model动态生成的实例详解
2017/10/27 Javascript
Vue.js实现大屏数字滚动翻转效果
2019/11/29 Javascript
python paramiko实现ssh远程访问的方法
2013/12/03 Python
Python中处理unchecked未捕获异常实例
2015/01/17 Python
scrapy自定义pipeline类实现将采集数据保存到mongodb的方法
2015/04/16 Python
Python爬虫辅助利器PyQuery模块的安装使用攻略
2016/04/24 Python
python3 实现的人人影视网站自动签到
2016/06/19 Python
Python绘制股票移动均线的实例
2019/08/24 Python
docker-py 用Python调用Docker接口的方法
2019/08/30 Python
python画环形图的方法
2020/03/25 Python
Python如何绘制日历图和热力图
2020/08/07 Python
大学生自荐书范文
2013/12/10 职场文书
社区党建工作方案
2014/06/10 职场文书
小学家长学校培训材料
2014/08/24 职场文书
爱牙日活动总结
2014/08/29 职场文书
本科毕业论文致谢怎么写
2015/05/14 职场文书
女性健康讲座主持词
2015/07/04 职场文书
golang 实现并发求和
2021/05/08 Golang
Spring Cloud Gateway去掉url前缀
2021/07/15 Java/Android