Python Jinja2的简单使用
参考链接: https://jinja.palletsprojects.com/en/2.11.x/
下面测试使用jinja2版本: version = "2.11.2" , python版本: version = "3.7.4"
Template使用
from jinja2 import Template
template = Template('Hello {{ name }}')
print(template.render(name='dsg'))
# > output: Hello dsg
template = Template('service: {{ service.name }}, version: {{ service.version }}')
service = {'name': 'mysql', 'version': 5.7}
print(template.render(service=service))
# > output: service: mysql, version: 3.7
template = Template('service: {{ service.name }}, version: {{ service.version }}')
service = {'service': {'name': 'mysql', 'version': 5.7}}
print(template.render(service))
template = Template('service list: {% for s in services %} {{s}};{% endfor %}')
services = {'services': ['mysql', 'nginx']}
print(template.render(services))
# > output: service list: mysql; nginx;
去除空格
template = Template('service list: {% for s in services -%} {{s}};{%- endfor %}')
services = {'services': ['mysql', 'nginx']}
print(template.render(services))
# > output: service list: mysql;nginx;
直接读j2文件, j2文件示例:
# filename service.j2
name: {{ name }}
version: {{ version }}
with open('app/tmp/service.j2', 'r') as f:
buffer = f.read()
service = {'name': 'mysql', 'version': 5.7}
template = Template(buffer)
print(template.render(service))
# output:
# > name: mysql
# > version: 5.7
使用模板文件实现部署替换配置文件
# .
# |-- app
# | |-- __init__.py # 必须,
# | |-- tmp
# | |-- service.js # 配置文件模板
# | |-- nginx.js # 配置文件模板
from jinja2 import Environment, PackageLoader
env = Environment(loader=PackageLoader('app', 'tmp'))
template = env.get_template('service.j2')
content = template.render(name='mysql', version='5.8')
with open('./config', 'w') as f:
f.write(content)
print(content)
# output:
# > name: mysql
# > version: 5.7
import yaml
with open('app/config.yml') as f:
y = yaml.safe_load(f)
print(y)
template = Template('basedir = {% for node in nodes %} {% if "nginx" in nodes[node].modules %} {{ nodes[node].basedir }} {% endif %}{% endfor %}')
print(template.render(y))
# output:
# {'nodes': {'node1': {'host': '10.0.0.2', 'basedir': '/data1', 'modules': ['mysql', 'nginx']}, 'node2': {'host': '10.0.0.3', 'basedir': '/data2', 'modules': ['nginx']}}, 'services': {'mysql': {'config': {'port': 3306, 'passwd': 123456}}, 'nginx': {'config': {'port': 8088}}}}
# basedir = /data1 /data2
env = Environment(loader=PackageLoader('app', 'tmp'))
template = env.get_template('nginx.j2')
content = template.render(y)
with open('./config', 'w') as f:
f.write(content)
print(content)
nginx.j2文件内容:
version: '2'
services:
nginx:
image: nginx:11
container_name: nginx
ports:
- {{ services.nginx.config.port }}:80
volumes:
- {% for node in nodes -%} {%- if "nginx" in nodes[node].modules %}{{nodes[node].basedir}}{%- endif %} {%- endfor %}/nginx/logs/:/var/lib/nginx/logs/
- /usr/share/zoneinfo/Asia/Shanghai:/etc/localtime
restart: always
networks:
- default_bridge
networks:
default_bridge:
external: true
config.yml文件内容:
nodes:
node1:
host: 10.0.0.2
basedir: /data1
modules:
- mysql
- nginx
node2:
host: 10.0.0.3
basedir: /data2
modules:
- nginx
services:
mysql:
config:
port: 3306
passwd: 123456
nginx:
config:
port: 8088
config文件最后写入的内容:
version: '2'
services:
nginx:
image: nginx:11
container_name: nginx
ports:
- 8088:80
volumes:
- /data1/data2/nginx/logs/:/var/lib/nginx/logs/
- /usr/share/zoneinfo/Asia/Shanghai:/etc/localtime
restart: always
networks:
- default_bridge
networks:
default_bridge:
external: true
上面并没有得到我们想要的结果,如果nginx只在一台机器部署的话,结果会是我们想要的,但是多机部署就不行了。
这里我建议尽量少在模板文件中写逻辑判断,逻辑判断应该用python去实现,我们再真实环境中去替换nginx配置的basedir时都是by机器的,我们可以用python先解析出如下格式的数据:
{'10.0.0.2':{'nginx':{'basedir':'/data1'}},
'10.0.0.2':{'mysql':{'basedir':'/data1'}},
'10.0.0.3':{'nginx':{'basedir':'/data2'}}
}
如果我们要部署给10.0.0.2部署nginx时就能够正确获取basedir了。 具体怎么实现, 看大家了。
yml里面字典和列表
config.yml
nodes:
node1:
host: 10.0.0.2
basedir: /data1
modules:
- mysql
- nginx
node2:
host: 10.0.0.3
basedir: /data2
modules:
- nginx
template = Template(' {{ nodes }}')
print(template.render(y))
# 输出:
{'node1': {'host': '10.0.0.2', 'basedir': '/data1', 'modules': ['mysql', 'nginx']}, 'node2': {'host': '10.0.0.3', 'basedir': '/data2', 'modules': ['nginx']}}
config.xml
nodes:
- node1:
host: 10.0.0.2
basedir: /data1
modules:
- mysql
- nginx
- node2:
host: 10.0.0.3
basedir: /data2
modules:
- nginx
template = Template(' {{ nodes }}')
print(template.render(y))
# 输出:
[{'node1': {'host': '10.0.0.2', 'basedir': '/data1', 'modules': ['mysql', 'nginx']}}, {'node2': {'host': '10.0.0.3', 'basedir': '/data2', 'modules': ['nginx']}}]
yml格式不同,取值就会不同。