我今天正在学习使用Jinja来为我手动创建并为Nginx测试的配置文件建立模板。到目前为止,模板可以按预期工作,并且可以按预期提取动态变量。但是,我的conf中有一行需要分在两个单独的行中,由于某种原因,它将两个主机放在同一行中。
这看起来真的很简单,但是我似乎无法发现引起它的原因。我已经做到了!
我的nginx.yml文件
---
test_url: abc.{{ nginx_domain }}
nginx_ssl_port: 443
nginx_proxy_conf_dir: /etc/some/place
nginx_ssl_key_dir: /etc/somekey/place
nginx_ssl_cert_dir: /etc/somecert/place
nginx_proxy_log_dir: /etc/some/proxy/place
##Env depends on ansible inventory
test_nginx_proxy_sites:
- name: test
params:
- 'listen {{ nginx_ssl_port }} ssl'
- 'server_name {{test_url}}'
- 'include {{ nginx_proxy_conf_dir }}/conf.d/ssl.conf'
- 'ssl_certificate {{ nginx_ssl_cert_dir }}/{{ nginx_domain }}.crt'
- 'ssl_certificate_key {{ nginx_ssl_key_dir }}/{{ nginx_domain }}.key'
- 'access_log {{ nginx_proxy_log_dir }}/management_access.log'
- 'error_log {{ nginx_proxy_log_dir }}/management_error.log'
locations:
- path: /
location_params:
- 'proxy_pass http://stream_{{ Env }}/'
- 'include {{ nginx_proxy_conf_dir }}/conf.d/proxy.conf'
upstreams:
- name: stream_{{ Env }}
params:
- '{% for host in groups.tag_Class_host %}
server {{ hostvars[host].ipv4_local }}:{{ management_port }};
{% endfor %}
'
我的sites.conf.j2
{{ remotely_managed }}
server {
{% if item.blocks is defined and item.blocks|length > 0 %}
{% for block in item.blocks %}
{{ block }}
{% endfor %}
{% endif %}
{% for param in item.params %}
{{ param }};
{% endfor %}
{% if item.locations is defined and item.locations|length > 0 %}
{% for location in item.locations %}
location {% if location.match is defined %}{{ location.match }} {% endif %}{{ location.path }} {
{% if location.root is defined %}
root {{ location.root }};
{% endif %}
{% if location.location_params is defined and location.location_params|length > 0 %}
{% for param in location.location_params %}
{{ param }};
{% endfor %}
{% endif %}
}
{% endfor %}
{% endif %}
{% if item.errors is defined and item.errors|length > 0 %}
{% for error in item.errors %}
{{ error.directive }};
location {{ error.location }} {
{% for param in error.error_params %}
{{ param }};
{% endfor %}
}
{% endfor %}
{% endif %}
}
{% if item.upstreams is defined %}
{% for u in item.upstreams %}
upstream {{ u.name }} {
{% if u.params is defined %}
{% for param in u.params %}
{{ param }}
{% endfor %}
{% endif %}
}
{% endfor %}
{% endif %}
我的输出
server {
server_name abc.mytest.com;
include /etc/nginx/conf.d/ssl.conf;
ssl_certificate /etc/somecert/place/certs/abc.mytest.com.crt;
ssl_certificate_key /etc/somekey/place/private/abc.mytest.com.key;
access_log /var/log/nginx/management_access.log;
error_log /var/log/nginx/management_error.log;
location / {
proxy_pass http://stream_qa/;
include /etc/nginx/conf.d/proxy.conf;
}
}
upstream stream_qa {
server 1.1.1.09:11111; server 1.1.1.10:11111;
}
上游应打印如下:
upstream stream_qa {
server 1.1.1.09:11111;
server 1.1.1.10:11111;
}
答案 0 :(得分:0)
好的-是的。
要了解此问题,了解jinja模板的工作原理很重要。
解决方案:像这样简单地插入新行
{% if item.upstreams is defined %}
{% for u in item.upstreams %}
upstream {{ u.name }} {
{% if u.params is defined %}
{% for param in u.params %}
{{ param }}
{% endfor %}
{% endif %}
这样做的原因是由于Jinja模板的工作原理。
渲染jinja时,它不知道将内容放到新行中,而只是知道将循环中的内容放到一个副本中。因此,如果您的循环缺少对新行的准备,则不会将事情放到新行上。
因此,当您遇到类似您的循环时,或更简单地说,是一个[a, b, c, d, e, f]
的数组
{% for i in items %}
{{ i }}
{% endfor %}
它将打印为abcdef
,因为{{i}}
的字面意思是在此处渲染i
。
通过在循环中放置新行。
{% for i in items %}
{{ i }}
{% endfor %}
它将在循环中最后一项的末尾(即在新行上)呈现i
。
简而言之,您想做的是i
还包括在循环中提供新行,以便jinja渲染循环中的内容时,还可以渲染新行。
如果您这样看,我提到的第一个循环就是这样渲染的
abcde
,但第二个循环的呈现方式如下:a\nb\nc\nd\ne
,如您所见,该循环中每个项目的值都提供了新行。
ps:这真的很难解释:(
答案 1 :(得分:0)
我能够通过编辑nginx.yml文件来解决此问题:
upstreams:
- name: stream_{{ Env }}
params:
-
{% for host in groups.tag_Class_host %}
server {{ hostvars[host].ipv4_local }}:{{ management_port }};
{% endfor %}
我应该查看YAML,而不是查看Jinja。 YAML中的新管道将使我的字符串成为多字符串行。
输出与上面的输出匹配。