本文目录导读:

我来介绍几种用Python生成Puppet配置的方法:
使用模板引擎(推荐:Jinja2)
安装依赖
pip install jinja2 pyyaml
Puppet模板文件 (nginx.pp.j2)
# nginx.pp.j2
class {{ class_name }} {
package { 'nginx':
ensure => '{{ package_version }}',
}
service { 'nginx':
ensure => '{{ service_status }}',
enable => {{ service_enable }},
require => Package['nginx'],
}
file { '{{ config_path }}':
ensure => file,
content => template('nginx/nginx.conf.erb'),
require => Package['nginx'],
notify => Service['nginx'],
}
}
Python生成脚本
from jinja2 import Template
import yaml
import json
def generate_puppet_nginx_config(config_data):
"""生成Nginx的Puppet配置"""
template_str = """
class {{ class_name }} {
package { 'nginx':
ensure => '{{ package_version }}',
}
service { 'nginx':
ensure => '{{ service_status }}',
enable => {{ service_enable }},
require => Package['nginx'],
}
}
"""
template = Template(template_str)
return template.render(
class_name=config_data.get('class_name', 'nginx'),
package_version=config_data.get('version', 'latest'),
service_status=config_data.get('status', 'running'),
service_enable=config_data.get('enable', True)
)
# 从YAML读取配置
def generate_from_yaml(yaml_file):
with open(yaml_file, 'r') as f:
config = yaml.safe_load(f)
return generate_puppet_nginx_config(config)
# 从JSON读取配置
def generate_from_json(json_file):
with open(json_file, 'r') as f:
config = json.load(f)
return generate_puppet_nginx_config(config)
高级示例:多层Puppet配置生成
import os
from jinja2 import Environment, FileSystemLoader
class PuppetConfigGenerator:
def __init__(self, template_dir='./templates'):
self.env = Environment(loader=FileSystemLoader(template_dir))
def generate_web_server(self, server_data):
"""生成Web服务器Puppet配置"""
template = self.env.get_template('web_server.pp.j2')
return template.render(
server_name=server_data['name'],
document_root=server_data.get('doc_root', '/var/www/html'),
ports=server_data.get('ports', [80, 443]),
ssl_enabled=server_data.get('ssl', False),
ssl_cert=server_data.get('ssl_cert', ''),
ssl_key=server_data.get('ssl_key', ''),
upstreams=server_data.get('upstreams', [])
)
def generate_full_stack(self, config_file):
"""生成完整应用栈配置"""
import yaml
with open(config_file, 'r') as f:
config = yaml.safe_load(f)
puppet_code = ""
# 生成各个模块的配置
for server in config.get('servers', []):
puppet_code += self.generate_web_server(server) + "\n"
for db in config.get('databases', []):
puppet_code += self.generate_database(db) + "\n"
return puppet_code
def save_puppet_config(self, config_str, output_path):
"""保存生成的Puppet配置"""
os.makedirs(os.path.dirname(output_path), exist_ok=True)
with open(output_path, 'w') as f:
f.write(config_str)
print(f"Puppet配置已保存到: {output_path}")
# 使用示例
def example_usage():
generator = PuppetConfigGenerator()
# 配置数据
config = {
'servers': [
{
'name': 'example.com',
'doc_root': '/var/www/example',
'ports': [80, 443],
'ssl': True,
'ssl_cert': '/etc/ssl/certs/example.crt',
'ssl_key': '/etc/ssl/private/example.key',
'upstreams': [
{'name': 'app1', 'host': 'localhost', 'port': 3000}
]
}
],
'databases': [
{
'name': 'myapp_db',
'user': 'myapp',
'password': 'secure_password',
'host': 'db.example.com'
}
]
}
# 保存配置到YAML文件
with open('config.yaml', 'w') as f:
yaml.dump(config, f)
# 生成Puppet配置
puppet_code = generator.generate_full_stack('config.yaml')
generator.save_puppet_config(puppet_code, './puppet/manifests/site.pp')
# 运行示例
if __name__ == "__main__":
example_usage()
使用专门库:py-puppet
# 简单的Puppet DSL生成器
class PuppetDSL:
def __init__(self):
self.resources = []
def package(self, name, **kwargs):
resource = {
'type': 'package',
'name': name,
'params': kwargs
}
self.resources.append(resource)
return self
def service(self, name, **kwargs):
resource = {
'type': 'service',
'name': name,
'params': kwargs
}
self.resources.append(resource)
return self
def file(self, name, **kwargs):
resource = {
'type': 'file',
'name': name,
'params': kwargs
}
self.resources.append(resource)
return self
def user(self, name, **kwargs):
resource = {
'type': 'user',
'name': name,
'params': kwargs
}
self.resources.append(resource)
return self
def to_pp(self):
"""转换为Puppet DSL格式"""
output = []
for res in self.resources:
output.append(f"{res['type']} {{ '{res['name']}':")
for key, value in res['params'].items():
if isinstance(value, bool):
output.append(f" {key} => {str(value).lower()},")
elif isinstance(value, (int, float)):
output.append(f" {key} => {value},")
else:
output.append(f" {key} => '{value}',")
output.append("}\n")
return '\n'.join(output)
def save(self, filename):
"""保存到文件"""
with open(filename, 'w') as f:
f.write(self.to_pp())
# 使用示例
def create_web_server_config():
puppet = PuppetDSL()
# 添加Nginx配置
puppet.package('nginx', ensure='latest')
puppet.service('nginx', ensure='running', enable=True)
puppet.file('/etc/nginx/nginx.conf',
ensure='file',
source='puppet:///modules/nginx/nginx.conf',
require='Package[nginx]',
notify='Service[nginx]')
# 添加PHP-FPM配置
puppet.package('php-fpm', ensure='installed')
puppet.service('php-fpm', ensure='running', enable=True)
# 添加应用用户
puppet.user('www-data', ensure='present', shell='/sbin/nologin')
return puppet
# 生成配置
config = create_web_server_config()
config.save('web_server.pp')
使用模板继承(复杂项目)
from string import Template
class PuppetTemplateInheritance:
def __init__(self):
self.base_template = """
# Base configuration for $app_name
class $class_name {
include ::stdlib
include ::logrotate
# Common resources
$resources
# Additional configuration
$additional_config
}
"""
def create_application_config(self, app_name, config):
"""创建应用配置"""
# 生成资源字符串
resources = []
# 处理包
if config.get('packages'):
for pkg in config['packages']:
resources.append(f"""
package {{ '{pkg_name}':
ensure => '{version}',
}}""".format(pkg_name=pkg['name'], version=pkg.get('version', 'present')))
# 处理服务
if config.get('services'):
for svc in config['services']:
resources.append(f"""
service {{ '{svc_name}':
ensure => '{status}',
enable => {str(svc.get('enable', True)).lower()},
require => Package['{svc.get('require', '')}'],
}}""".format(svc_name=svc['name'],
status=svc.get('status', 'running'),
**svc))
# 创建模板
t = Template(self.base_template)
return t.substitute(
app_name=app_name,
class_name=f"app_{app_name}".replace('-', '_'),
resources='\n'.join(resources),
additional_config=config.get('additional_config', '')
)
# 使用示例
def generate_complex_config():
generator = PuppetTemplateInheritance()
config = {
'packages': [
{'name': 'python3', 'version': 'latest'},
{'name': 'nginx', 'version': '1.18.0'},
{'name': 'supervisor', 'version': 'present'}
],
'services': [
{
'name': 'nginx',
'status': 'running',
'enable': True,
'require': 'nginx'
},
{
'name': 'supervisor',
'status': 'running',
'enable': True,
'require': 'supervisor'
}
],
'additional_config': """
file { '/etc/nginx/sites-enabled/default':
ensure => absent,
}
"""
}
return generator.create_application_config('myapp', config)
# 使用hiera数据生成(更接近实际Puppet)
def generate_with_hiera():
import yaml
hiera_data = {
'myapp::packages': ['nginx', 'python3', 'git'],
'myapp::services': ['nginx', 'sshd'],
'myapp::config_file': '/etc/myapp/config.yaml',
'myapp::port': 8080,
'myapp::users': ['deploy', 'admin']
}
# 保存为hiera数据
with open('hiera_data.yaml', 'w') as f:
yaml.dump(hiera_data, f)
# 生成对应的Puppet配置
puppet_code = f"""
class myapp (
$packages = hiera_array('myapp::packages'),
$services = hiera_array('myapp::services'),
$config_file = hiera('myapp::config_file'),
$port = hiera('myapp::port'),
) {{
package {{ $packages:
ensure => installed,
}}
service {{ $services:
ensure => running,
enable => true,
}}
file {{ $config_file:
ensure => file,
content => template('myapp/config.erb'),
}}
}}
"""
return puppet_code
完整项目示例:配置管理工具
#!/usr/bin/env python3
"""
Puppet配置生成器 - 命令行工具
"""
import argparse
import yaml
import json
from jinja2 import Environment, FileSystemLoader
from pathlib import Path
import logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
class PuppetConfigGenerator:
def __init__(self, template_dir='./templates', output_dir='./output'):
self.template_dir = Path(template_dir)
self.output_dir = Path(output_dir)
self.env = Environment(loader=FileSystemLoader(str(template_dir)))
self.env.line_statement_prefix = '#'
def parse_config(self, config_file):
"""解析配置文件"""
ext = Path(config_file).suffix.lower()
with open(config_file, 'r') as f:
if ext == '.yaml' or ext == '.yml':
return yaml.safe_load(f)
elif ext == '.json':
return json.load(f)
else:
raise ValueError(f"Unsupported file format: {ext}")
def generate_puppet_code(self, config):
"""生成Puppet代码"""
if 'template' in config:
template = self.env.get_template(config['template'])
return template.render(config)
# 默认生成逻辑
code = []
# 处理节点定义
if 'nodes' in config:
for node_name, node_config in config['nodes'].items():
code.append(f"node '{node_name}' {{\n")
code.append(self._generate_node_content(node_config))
code.append("}\n\n")
return ''.join(code)
def _generate_node_content(self, config):
"""生成节点内容"""
lines = []
# 处理类声明
if 'classes' in config:
for cls in config['classes']:
lines.append(f" include {cls}\n")
# 处理资源
if 'resources' in config:
for resource in config['resources']:
lines.append(self._generate_resource(resource))
return ''.join(lines)
def _generate_resource(self, resource):
"""生成单个资源定义"""
lines = []
resource_type = resource['type']
title = resource['title']
lines.append(f" {resource_type} {{ '{title}':\n")
for key, value in resource.get('params', {}).items():
if isinstance(value, bool):
lines.append(f" {key} => {str(value).lower()},\n")
else:
lines.append(f" {key} => '{value}',\n")
lines.append(" }\n\n")
return ''.join(lines)
def save_config(self, config_name, puppet_code):
"""保存生成的配置"""
output_file = self.output_dir / f"{config_name}.pp"
self.output_dir.mkdir(parents=True, exist_ok=True)
with open(output_file, 'w') as f:
f.write(puppet_code)
logger.info(f"Generated {output_file}")
def main():
parser = argparse.ArgumentParser(description='Generate Puppet configuration from Python')
parser.add_argument('config_file', help='Configuration file (YAML or JSON)')
parser.add_argument('--template-dir', default='./templates', help='Template directory')
parser.add_argument('--output-dir', default='./output', help='Output directory')
parser.add_argument('--output-name', help='Output file name (without extension)')
args = parser.parse_args()
generator = PuppetConfigGenerator(args.template_dir, args.output_dir)
config = generator.parse_config(args.config_file)
puppet_code = generator.generate_puppet_code(config)
output_name = args.output_name or Path(args.config_file).stem
generator.save_config(output_name, puppet_code)
if __name__ == '__main__':
main()
使用示例配置文件
YAML配置示例 (config.yaml)
template: base_server.pp.j2
nodes:
webserver01.example.com:
classes:
- nginx
- php7.4-fpm
- supervisor
resources:
- type: file
title: /etc/nginx/nginx.conf
params:
ensure: file
source: puppet:///modules/nginx/nginx.conf
require: Package[nginx]
notify: Service[nginx]
- type: service
title: nginx
params:
ensure: running
enable: true
命令行使用
# 生成Puppet配置 python puppet_generator.py config.yaml # 指定输出目录 python puppet_generator.py config.yaml --output-dir ./puppet/manifests # 使用JSON配置 python puppet_generator.py config.json
这些方法可以根据你的具体需求选择使用,对于简单的场景,Jinja2模板就足够了;对于复杂的项目,建议使用完整的配置管理工具,关键是要保持生成的Puppet代码符合Puppet的语法规则。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播