您的位置:首页 > 编程语言 > Python开发

使用Python、Django、Bootstrap编写Web页面,以及利用ansible-cmdb、ansible等模块,在web界面获取批量服务器配置信息,以及实现批量管理服务器

2018-08-17 01:07 706 查看
版权声明: https://blog.csdn.net/Scirhh/article/details/81750987

  说明:本文适用的是Linux操作系统的用户,以及在实现之前,需要部署python2以及3的版本环境。本文需要一定的Linux,Python以及Django等基础知识。

  首先,需要搭建Django服务:

[code]  -> ~# mkdir /mnt/django     # 创建Django存放目录
-> ~# cd /mnt/django
-> ~# python3 -m venv django_env    # 创建Django虚拟环境
-> ~# source django_env/bin/activate    # 激活虚拟环境
-> ~# pip install django=1.11.9     # 安装Django模块

  然后,创建一个项目

[code]  -> ~# cd /mnt/django
-> ~# django-admin startproject ansi_pro    # 生成项目
-> ~# vim ansi_pro/ansi_pro/setting.py # 修改setting.py文件,因为Django默认是本机访问,英文环境
修改为以下内容:
ALLOWED_HOSTS = '*'
LANGUAGE_CODE = 'zh-Hans’
TIME_ZONE = 'Asia/Shanghai’
-> ~#(ansi_pro) python manage.py migrate    # 生成数据库
-> ~#(ansi_pro)python manage.py createsuperuser     # 创建超级用户,用户登录后台数据库
-> ~#(ansi_pro)nohup python manage.py runserver 0:8081 &     # 指定以8081端口访问,不指定默认为8000,浏览器直接访问127.0.0.1/admin即可

  其次,创建一个应用

[code] -> ~#(ansi_pro)python manage.py startapp webansi    # 创建应用
-> ~#(ansi_pro)vim setting.py   # 将新建的应用添加到setting激活,并注释掉跨站攻击的代码行
修改内容为如下:
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenIypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.sta@cfiles',
'webansi',
]
# 注释跨站攻击
MIDDLEWARE = [
           'django.middleware.security.SecurityMiddleware',
           'django.contrib.sessions.middleware.SessionMiddleware',
           'django.middleware.common.CommonMiddleware',
#    'django.middleware.csrf.CsrfViewMiddleware',
            'django.contrib.auth.middleware.AuthenticationMiddleware',
            'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

    到这里,简单的Django服务以及应用创建已经完成,接下来就是如何使用Django模型以及ansible模块获取服务器的配置信息以及批量管理服务器。

    为了测试,编者采用了几台虚拟机模拟集群服务器。

    首先,使用ORM映射创建数据库,并将创建的数据库注册到管理后台

[code]# 在webansi下的models.py下创建数据库
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models
​
# 主机组
class Group(models.Model):
   group = models.CharField(max_length=20)
​
   def __str__(self):
       return self.group
​
#主机信息
class Hosts(models.Model):
   hostname =models.CharField(max_length=20)
   ip_addr = models.CharField(max_length=15)
   group = models.ForeignKey(Group,on_delete=models.CASCADE)
​
   def __str__(self):
       return self.hostname
​
#模块信息
class Module(models.Model):
   mod_name = models.CharField(max_length=50)
​
   def __str__(self):
return self.mod_name
​
#模块参数
class Args(models.Model):
   mod_args = models.CharField(max_length=50)
   mod = models.ForeignKey(Module,on_delete=models.CASCADE)
​
   def __str__(self):
       return self.mod_args

注册管理后台:

[code]  # 在webansi下的admin.py编写
​
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.contrib import admin
from models import Hosts,Group,Module,Args
​
admin.site.register(Hosts)
admin.site.register(Module)
admin.site.register(Group)
admin.site.register(Args)

    其次,编写URLCONF路由

[code] # 在ansi_pro/ansi_pro/urls.py下编写
from django.conf.urls import url,include
from django.contrib import admin
from webansi import views
​
urlpatterns = [
   url(r'^admin/', admin.site.urls),
   url(r'^$', views.mainpage, name='mainpage'),
   url(r'^webansi/', include('webansi.urls')),     # 如果以webansi开头的页面,跳转到webansi目录下的urls.py下进行匹配
]

    由于在webansi目录下不存在urls.py文件,所以需要我们手动创建一个

[code] -> ~#(webansi) vim urls.py

随后在urls文件编写代码:

[code] from django.conf.urls import url
from . import views
​
urlpatterns = [
   url(r'^$', views.index, name='index'),
   url(r'^addhosts/$', views.addhosts, name='addhosts'),
   url(r'^addmodules/$', views.addmodules, name='addmodules'),
   url(r'^tasks/$', views.tasks, name='tasks'),
]

最后就是编写Django模型的views.py文件:

[code]# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.shortcuts import render,redirect,HttpResponse
from webansi.models import Group,Hosts,Module,Args
import shutil
from collections import namedtuple
from ansible.parsing.dataloader import DataLoader
from ansible.vars.manager import VariableManager
from ansible.inventory.manager import InventoryManager
from ansible.playbook.play import Play
from ansible.executor.task_queue_manager import TaskQueueManager
import ansible.constants as C
# Create your views here.
​
def mainpage(request):
   return render(request,'webansi/mainpage.html')
​
def index(request):
   return render(request,'webansi/hostsinfo.html')
​
def addhosts(request):
if request.method=='POST':
       g = request.POST.get('group')
       h = request.POST.get('hostname')        # 将页面的输入提交的信息存储到数据库中
       ip = request.POST.get('ipaddr')
       groupobj = Group.objects.get_or_create(group=g)[0]
       Hosts.objects.get_or_create(hostname=h,ip_addr=ip,group=groupobj)
​
   host_info={}
   groups = Group.objects.all()    # 获取主机组的信息
   for group in groups:
       hosts = []
       for host in group.hosts_set.all():
           hosts.append(host.hostname)    # 获取主机信息
       host_info[group] = hosts
   return render(request,'webansi/addhosts.html', {'host_info': host_info})
​
def addmodules(request):
   if request.method == 'POST':
       modename = request.POST.get('module')     # 将页面的输入提交的信息存储到数据库中
       arg = request.POST.get('args')
moduleobj = Module.objects.get_or_create(mod_name=modename)[0]
       Args.objects.get_or_create(mod_args=arg,mod=moduleobj)
​
   module_info = {}
   mods = Module.objects.all()    # 读取数据库中的模块信息以及参数
   for m in mods:
       argss=[]
       for args in m.args_set.all():
           argss.append(args.mod_args)
       module_info[m] = argss
   return render(request,'webansi/addmodules.html', {'module_info':module_info})
​
def tasks(request):
   if request.method=='POST':
       ip = request.POST.get('ipaddr')   # 将页面选择的信息传到exec_task函数去执行
       group = request.POST.get('group')
       mod = request.POST.get('module')
       args = request.POST.get('args')
       print ip,group,mod,args
       if ip :
           dest = ip
else:
           dest = group
       exec_task (dest,mod,args)
​
   hosts = list(Hosts.objects.all())
   groups = list(Group.objects.all())
   mod_info = {}
   mods = Module.objects.all()
   for m in mods:
       argss = []
       for args in m.args_set.all():
           argss.append(args.mod_args)
       mod_info[m] = argss
   result = {'hosts':hosts,'groups':groups,'mods':mods,'args':args,'mod_info':mod_info}
   return render(request, 'webansi/task.html',result)
​
# exec_task内得代码均为ansible官方文档中python API的写法,只需要修改参数即可
def exec_task(dest,mod,args):
   Options = namedtuple('Options',
                        ['connection', 'module_path', 'forks', 'become', 'become_method', 'become_user', 'check',
                         'diff'])
   options = Options(connection='smart', module_path=['/to/mymodules'], forks=10, become=None, become_method=None,
                     become_user=None, check=False, diff=False)
loader = DataLoader()
   passwords = dict()
​
   inventory = InventoryManager(loader=loader, sources=['ansicfg/dhosts.py'])
   variable_manager = VariableManager(loader=loader, inventory=inventory)
   play_source = dict(
       name="Ansible Play",
       hosts=dest,
       gather_facts='no',
       tasks=[
           dict(action=dict(module=mod, args=args), register='shell_out'),
       ]
   )
​
   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,
       )
       result = tqm.run(play)
   finally:
       if tqm is not None:
           tqm.cleanup()
​
       shutil.rmtree(C.DEFAULT_LOCAL_TMP, True)
[code]  编写主机的文件以及获取主机地址的文件:
[code]-> ~# mkdir ansicfg
-> ~# vim ansible.cfg
内容如下:
[defaults]
remote_user = root        # 指定用户
inventory = dhosts.py     # 指定主机地址文件

-> ~# vim dhost.py

内容如下:(动态获取主机)
import json
from sqlalchemy import create_engine
from sqlalchemy import Column, String, Integer
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker

engin = create_engine('sqlite://///mnt/django/ansib_pro/db.sqlite3')

Base = declarative_base()
Session = sessionmaker(bind=engin)
session = Session()

class Hosts(Base):

__tablename__ = 'webansi_host'

id =  Column(Integer,primary_key=True)
hostname = Column(String(20))
group = Column(String(20))

if __name__ == '__main__':
qset = session.query(Hosts.hostname,Hosts.group).all()
host_list = {}
for g,h in qset:
if g not in host_list:
host_list[g] = {}
host_list[g]['hosts'] = [h]
else:
host_list[g]['hosts'].append(h)
print json.dumps(host_list)
[code]    最后,利用ansible-cmdb生成服务器的配置信息:
[code]-> ~#(ansicfg) ansible -i dhosts.py  -m setup --tree /mnt/django/ansi_pro/webansi/templates/webansi/out all

-> ~#(webansi) ansible-cmdb out > ./hostsinfo.html
[code]   当上面的工作都完成的时候,接下来就是利用HTML5,以及Bootstrap编写相应的网页,为了文章的可读性,编写就不在这里一一的将每个页面的代码都写入本文果需要HTML页面的读者,可以在文章末的链接进行源码下载。(以运维实用性角度出发,所以只注重实用性,不注重美观。也由于编者不是专业的前端,所以在美观上还会有欠缺的,如果需要美观与实用性的用户,可以进行二次开发)
需要注意的是,所有的网页都要放在应用webansi下的templates目录下的webansi文件夹下。

    github源码下载:https://github.com/Scirh/Python/tree/master/django

    本文旨在提供参考,如有错误,欢迎大家指正。帮助编者不断的改进!

阅读更多
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐