运维自动化路线:html
cmdb的开发须要包含三部分功能:python
执行流程:服务器的客户端采集硬件数据,而后将硬件信息发送到API,API负责将获取到的数据保存到数据库中,后台管理程序负责对服务器信息的配置和展现。shell
采集硬件信息能够有两种方式实现:数据库
两种方式的优缺点各异:方式一,优势是不须要在每台服务器上步一个agent,缺点是依赖于puppet,而且使用ruby开发;方式二,优势是用于python调用shell命令,学习成本低,缺点是须要在每台服务器上发一个agent。django
默认状况下,puppet的client会在每半个小时链接puppet的master来同步数据,若是定义了report,那么在每次client和master同步数据时,会执行report的process函数,在该函数中定义一些逻辑,获取每台服务器信息并将信息发送给APIjson
puppet中默认自带了5个report,放置在【/usr/lib/ruby/site_ruby/1.8/puppet/reports/】路径下。若是须要执行某个report,那么就在puppet的master的配置文件中作以下配置:api
on masterruby
1
2
3
4
5
6
|
/
etc
/
puppet
/
puppet.conf
[main]
reports
=
store
#默认
#report = true #默认
#pluginsync = true #默认
|
on client服务器
1
2
3
4
5
6
7
8
|
/
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
一、建立report
二、应用report
Demo 2
一、建立report
在 /etc/puppet/modules 目录下建立以下文件结构:
modules └── cmdb ├── lib │ └── puppet │ └── reports │ └── cmdb.rb └── manifests └── init.pp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
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
|
二、应用report
1
2
3
4
5
|
/
etc
/
puppet
/
puppet.conf
[main]
reports
=
cmdb
#report = true #默认
#pluginsync = true #默认
|
方式二
使用python调用shell命令,解析命令结果并将数据发送到API
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' }])
后台管理页面须要实现对数据表的增删改查。
问题:
一、paramiko执行sudo
1
2
3
4
|
/
etc
/
sudoers
Defaults requiretty
Defaults:cmdb !requiretty
|