无法使用Jinja创建conf文件 - Nginx的预期变量

问题描述 投票:0回答:2

我今天学习使用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;
  }
nginx centos ansible jinja2
2个回答
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 %}

它将打印为qazxsw poi,因为qazxsw poi字面意思是在这里渲染abcdef

在循环中放置一个新行。

{{i}}

它会在循环中最后一项的末尾渲染i,即在新行上。

简单来说,你想要做的就是让{% for i in items %} {{ i }} {% endfor %} 在你的循环中包含一个新行,这样当jinja在循环中渲染时,它也会渲染一个新行。

如果你这样看,我提到的第一个循环就像这个i一样呈现,但第二个循环呈现如下:i,正如你所看到的,这个循环中每个项目的值都有一个新行。

ps:这真的很难解释:(


0
投票

我能够通过编辑我的nginx.yml文件来解决这个问题:

abcde

我应该审查YAML而不是看Jinja。 YAML中的新管道将使我的字符串成为多字符串行。

输出与上面的输出匹配。

© www.soinside.com 2019 - 2024. All rights reserved.