运维自动化路线:
cmdb的开发需要包含三部分功能:
·采集硬件数据
·API
·页面管理
执行流程:服务器的客户端采集硬件数据,然后将硬件信息发送到API,API负责将获取到的数据保存到数据库中,后台管理程序负责对服务器信息的配置和展示。
采集硬件信息
采集硬件信息可以有两种方式实现:
1、利用puppet中的report功能
2、自己写agent,定时执行
两种方式的优缺点各异:
方式一
优点是不需要在每台服务器上步一个agent
缺点是依赖于puppet,并且使用ruby开发
方式二
优点是用于python调用shell命令,学习成本低
缺点是需要在每台服务器上发一个agent
方式一
默认情况下,puppet的client会在每半个小时连接puppet的master来同步数据,如果定义了report,那么在每次client和master同步数据时,会执行report的process函数,在该函数中定义一些逻辑,获取每台服务器信息并将信息发送给API
puppet中默认自带了5个report,放置在【/usr/lib/ruby/site_ruby/1.8/puppet/reports/】路径下。如果需要执行某个report,那么就在puppet的master的配置文件中做如下配置:
on master
/etc/puppet/puppet.conf [main] reports = store #默认 #report = true #默认 #pluginsync = true #默认
on client
/etc/puppet/puppet.conf [main] #report = true #默认 [agent] runinterval = 10 server = master.puppet.com certname = c1.puppet.com
如上述设置之后,每次执行client和master同步,就会在master服务器的 【/var/lib/puppet/reports】路径下创建一个文件,主动执行:puppet agent --test
所以,我们可以创建自己的report来实现cmdb数据的采集,创建report也有两种方式。
Demo 1
1、创建report
/usr/lib/ruby/site_ruby/1.8/puppet/reports/cmdb.rb require 'puppet' require 'fileutils' require 'puppet/util' SEPARATOR = [Regexp.escape(File::SEPARATOR.to_s), Regexp.escape(File::ALT_SEPARATOR.to_s)].join Puppet::Reports.register_report(:cmdb) do desc "Store server info These files collect quickly -- one every half hour -- so it is a good idea to perform some maintenance on them if you use this report (it's the only default report)." def process certname = self.name now = Time.now.gmtime File.open("/tmp/cmdb.json",'a') do |f| f.write(certname) f.write(' | ') f.write(now) f.write("\r\n") end end end
2、应用report
/etc/puppet/puppet.conf [main] reports = cmdb #report = true #默认 #pluginsync = true #默认
Demo 2
1、创建report
在 /etc/puppet/modules 目录下创建如下文件结构:
modules
└── cmdb
├── lib
│ └── puppet
│ └── reports
│ └── cmdb.rb
└── manifests
└── init.pp
require 'puppet' require 'fileutils' require 'puppet/util' SEPARATOR = [Regexp.escape(File::SEPARATOR.to_s), Regexp.escape(File::ALT_SEPARATOR.to_s)].join Puppet::Reports.register_report(:cmdb) do desc "Store server info These files collect quickly -- one every half hour -- so it is a good idea to perform some maintenance on them if you use this report (it's the only default report)." def process certname = self.name now = Time.now.gmtime File.open("/tmp/cmdb.json",'a') do |f| f.write(certname) f.write(' | ') f.write(now) f.write("\r\n") end end end
2、应用report
/etc/puppet/puppet.conf [main] reports = cmdb #report = true #默认 #pluginsync = true #默认
方式二
使用python调用shell命令,解析命令结果并将数据发送到API
API
·REST与技术无关,代表的是一种软件架构风格,REST是Representational State Transfer的简称,中文翻译为“表征状态转移”
·REST从资源的角度类审视整个网络,它将分布在网络中某个节点的资源通过URL进行标识,客户端应用通过URL来获取资源的表征,获得这些表征致 使这些应用转变状态
·REST与技术无关,代表的是一种软件架构风格,REST是Representational State Transfer的简称,中文翻译为“表征状态转移”
·所有的数据,不过是通过网络获取的还是操作(增删改查)的数据,都是资源,将一切数据视为资源是REST区别与其他架构风格的最本质属性
·对于REST这种面向资源的架构风格,有人提出一种全新的结构理念,即:面向资源架构(ROA:Resource Oriented Architecture)
django中可以使用 Django rest framwork 来实现:http://www.django-rest-framework.org/
class Blog(models.Model): title = models.CharField(max_length=50) content = models.TextField()
from django.contrib.auth.models import User from rest_framework import routers, serializers, viewsets from app02 import models from rest_framework.decorators import detail_route, list_route from rest_framework import response from django.shortcuts import HttpResponse # Serializers define the API representation. class UserSerializer(serializers.HyperlinkedModelSerializer): class Meta: model = User fields = ('url', 'username', 'email', 'is_staff') # ViewSets define the view behavior. class UserViewSet(viewsets.ModelViewSet): queryset = User.objects.all() serializer_class = UserSerializer # Serializers define the API representation. class BlogSerializer(serializers.HyperlinkedModelSerializer): class Meta: model = models.Blog depth = 1 fields = ('url','title', 'content',) # ViewSets define the view behavior. class BLogViewSet(viewsets.ModelViewSet): queryset = models.Blog.objects.all() serializer_class = BlogSerializer @list_route() def detail(self,request): print request #return HttpResponse('ok') return response.Response('ok')
from django.conf.urls import patterns, include, url from django.contrib import admin from rest_framework import routers from app02 import api from app02 import views # Routers provide an easy way of automatically determining the URL conf. router = routers.DefaultRouter() router.register(r'users', api.UserViewSet) router.register(r'blogs', api.BLogViewSet) urlpatterns = patterns('', url(r'^', include(router.urls)), url(r'index/', views.index), #url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework')) )
from django.shortcuts import render from rest_framework.decorators import api_view from rest_framework.response import Response # Create your views here. @api_view(['GET', 'PUT', 'DELETE','POST']) def index(request): print request.method print request.DATA return Response([{'asset': '1','request_hostname': 'c1.puppet.com' }])
后台管理页面
后台管理页面需要实现对数据表的增删改查。