我今天学习使用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;
}
可以,然后呢。
要了解这个问题,了解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 %}
它将打印为qazxsw poi,因为qazxsw poi字面意思是在这里渲染abcdef
。
在循环中放置一个新行。
{{i}}
它会在循环中最后一项的末尾渲染i
,即在新行上。
简单来说,你想要做的就是让{% for i in items %}
{{ i }}
{% endfor %}
在你的循环中包含一个新行,这样当jinja在循环中渲染时,它也会渲染一个新行。
如果你这样看,我提到的第一个循环就像这个i
一样呈现,但第二个循环呈现如下:i
,正如你所看到的,这个循环中每个项目的值都有一个新行。
ps:这真的很难解释:(
我能够通过编辑我的nginx.yml文件来解决这个问题:
abcde
我应该审查YAML而不是看Jinja。 YAML中的新管道将使我的字符串成为多字符串行。
输出与上面的输出匹配。