Невозможно создать файл конфигурации с помощью Jinja - ожидаемые переменные для Nginx - PullRequest
0 голосов
/ 24 апреля 2019

Сегодня я учусь использовать 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 %}
    '

Мои сайты.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;
  }

Ответы [ 2 ]

0 голосов
/ 24 апреля 2019

Мне удалось решить эту проблему, отредактировав мой файл nginx.yml:

upstreams:
  - name: stream_{{ Env }}
    params:
    - 
      {% for host in groups.tag_Class_host %}
        server {{ hostvars[host].ipv4_local }}:{{ management_port }};
      {% endfor %}

Вместо того, чтобы смотреть на Джинджу, я должен был просмотреть YAML.Новая труба в YAML сделает мою строку многострочной.

Выход соответствует выходу выше.

0 голосов
/ 24 апреля 2019

Хорошо - так.

Чтобы понять эту проблему, важно знать, как работает шаблонизирование дзиндзя.

Для решения: просто вставьте новую строку, например, такую:

{% 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 here.

Поместив новую строку в ваш цикл.

{% for i in items %}
{{ i }}

{% endfor %}

он отобразит i в конце последнего элемента в цикле, то есть на новой строке.

Говоря простым языком, вы хотите, чтобы i также включил обеспечение новой строки в вашем цикле, чтобы, когда jinja отображал то, что находится в цикле, оно также отображало новую строку.

Если вы посмотрите на это так, первый упомянутый мной цикл будет выглядеть так abcde, а второй цикл будет выглядеть так: a\nb\nc\nd\ne, Как вы можете видеть, значение для каждого элемента в этом циклеесть положение для новой строки.

ps: это было действительно трудно объяснить :(

...