单位用的是puppet。Open***的用户也用puppet管理着,因为这边项目人员流动比较频繁,随之而来的就是得不断的修改puppet user模块的配置文件,而且kvm每开通一台虚拟机也得去puppet里去增加node,虽然不复杂,但天天改也烦,所以...


Puppet是用ruby写的,咱不会啊,正面搞不定,哪就迂回下,从配置文件下手,不是每次都要修改配置文件吗,咱就用程序去生成。一开始准备选择用php写,但考虑到文件权限这块,最终还是放弃用python.


语言:python

框架:flask

模块:jinja2,sqlalchemy


flask作wsgi,通过查询mysql,再利用jinja2 渲染puppet配置文件模板达到动态生成配置文件的目的。flak比较小巧的框架,也比较容易上手,倒是sqlalchemy这块花了一些时间。个人不太习惯django哪种写模型的时候,表字段都得在类里定义好,还是比较喜欢分开来,表定义交给mysql。sqlalchemy也有这问题,GG一下,大多文档包括官网也都是从定义字段开始,没办法只好硬着头皮看官方文档,sqlalchemy中文文档太少。


来几张图:

wKioL1RN1hPDyDSnAAYQpkV9gmM181.jpg

wKiom1RN1b_i5Y5fAAG4zWdphzU533.jpg


再来点干货:

# -*- coding: utf-8 -*-
"""
	Name: Puppet-Partner
	Author: xnile
	Author-email: xnile@qq.com
	Description: Puppet-Partner is used to manage nodes and users for Puppet.
	~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

"""
from flask import Flask, request, session, redirect, url_for, abort, \
     render_template, flash, jsonify
from flask.ext.paginate import Pagination
from sqlalchemy import create_engine, ForeignKeyConstraint
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker,relationship
from jinja2 import Environment, PackageLoader
import sys
import json

reload(sys)
sys.setdefaultencoding('utf8')

""" config """
DEBUG = True
SECRET_KEY = 'somekey'
JSONIFY_PRETTYPRINT_REGULAR = False

app = Flask(__name__)
app.config.from_object(__name__)

"""connecting"""
engine = create_engine('mysql+mysqldb://root:@localhost/puppet',echo=True)
Base = declarative_base(engine)     

class Group(Base):
	"""mapping"""
	__tablename__  = 'puppet_groups'
	__table_args__ = {'autoload':True}

class Users(Base):
	"""maping and relationship"""
	__tablename__  = 'puppet_users'
	__table_args__ = (
			ForeignKeyConstraint(['gid'], ['puppet_groups.gid']),
			{'autoload':True,}
			)
	onetoone = relationship("Group")

def loadSession():
	""""""
	metadata = Base.metadata
	Session = sessionmaker(bind=engine)
	session = Session()
	return session					

def CreateConf():
	""" Generate configuration files """
	session = loadSession()
	groups = session.query(Group).all()
	for group in groups:
		session = loadSession()
		users = session.query(Users).filter(Users.gid==group.gid).all()
		env = Environment(loader=PackageLoader('conf','templates'))
		template = env.get_template('user.pp')
		data = template.render(users=users,group=group)
		f = open('conf/' + group.gname + '.pp','w')
		f.write(data)
		f.close()
	 	
@app.route('/')
def index():
	""""""
	CreateConf()
	return render_template('index.html')

@app.route('/user_add',methods=['POST','GET'])
def user_add():
	"""Add users"""
	session = loadSession()
	group = session.query(Group).all()
	if request.method == 'POST':
		username = request.form['username']
		password = request.form['password']
		gid		 = int(request.form['gid'])
		ed_group = Users(username=username,password=password,gid=gid)
		session  = loadSession()
		session.add(ed_group)
		session.commit()
	return render_template('user_add.html',groups=group)

if __name__ == '__main__':
	app.run(host='0.0.0.0',port=8080)


欢迎拍砖,呵呵呵。。。