Trying to loop over a list of folder to check if the directory exists and then to clean that directory (remove all files).
{% set FOLDERS_TO_CLEAN = ['C:\Test\Folder1'] %}
{% for FOLDER in FOLDERS_TO_CLEAN %}
{% if salt['file.directory_exists']({{ FOLDER }}) %}
{{ FOLDER }}_delete:
file.directory:
- name: {{ FOLDER }}
- clean: True
- failhard: True
{% endif %}
{% endfor %}
The problematic line is the third line. With the variable FOLDER that ends up in a syntax error but when i change that to my test string it works. Any idea what i can change so that it works?
You need to have single quotes around {{ FOLDER }} in the if statement.
Like this:
{% set FOLDERS_TO_CLEAN = ['C:\Test\Folder1'] %}
{% for FOLDER in FOLDERS_TO_CLEAN %}
{% if salt['file.directory_exists']('{{ FOLDER }}') %}
{{ FOLDER }}_delete:
file.directory:
- name: {{ FOLDER }}
- clean: True
- failhard: True
{% endif %}
{% endfor %}
Related
I am learning to use Jinja today to template a config file that I manually created and tested for Nginx. So far the template works as expected and it pulls the dynamic variables as expected. However, I have one line in my conf that needs to be on two separate lines and for some reason, it puts the two host on the same line.
This seems really simple, but I can't seem to spot what is causing it. I've gotten this far so!
My nginx.yml file
---
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 %}
'
My 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 %}
My output
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;
}
The upstream should print out like below:
upstream stream_qa {
server 1.1.1.09:11111;
server 1.1.1.10:11111;
}
Okay - so.
To understand this issue, it's important to know how jinja templating works.
For the solution: Simply put a new line in, like this
{% 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 %}
The reason for this is due to how jinja templating works.
When rendering jinja, it does not know to put things on a new line, it just knows to put a copy of whatever is in your loop. So if your loop is missing provision for a new line, it will not put things on a new line.
so when you have a loop like yours, or more simply an array of [a, b, c, d, e, f]
{% for i in items %}
{{ i }}
{% endfor %}
it will print as abcdef because the {{i}} literrally means render i here.
By placing a new line in your loop.
{% for i in items %}
{{ i }}
{% endfor %}
it will render i at the end of the last item in the loop, ie on a new line.
In really simple terms, what you want to do is have i also include provision for a new line in your loop so that when jinja renders whats in the loop, its also rendering a new line.
If you look at it like this, the first loop I mentioned renders like this
abcde but the second loop renders like this: a\nb\nc\nd\ne, As you can see, the value for each item in this loop has provision for a new line.
ps: This was really difficult to explain :(
I was able to resolve this issue by editing my nginx.yml file:
upstreams:
- name: stream_{{ Env }}
params:
-
{% for host in groups.tag_Class_host %}
server {{ hostvars[host].ipv4_local }}:{{ management_port }};
{% endfor %}
Rather than looking at Jinja, I should have reviewed YAML. A new pipe in YAML will make my string a multi-string line.
The output matches the output above.
A little question : how can I change < title > < /title > with Sonata Admin ?
Everywhere there is "Admin...". And when I override a page with sonata template I got "Admin".
Thank's.
You can easy do that by override the sonata admin file translation
1- Create folder structure in traslations like this :
2- then in the SonataAdminBundle.[your-language-code].yml file add :
Admin: "You Custom title Here"
You have to override Sonata admin's standard_layout.html.twig file to achieve this.
First, define the file in sonata admin config file.
config/packages/sonata_admin.yaml
sonata_admin:
templates:
layout: 'sonata_admin/layout.html.twig'
Create a twig file named layout.html.twig inside templates/sonata_admin/ and just paste the sonata_head_title block from the bundle.
{% extends '#SonataAdmin/standard_layout.html.twig' %}
{% block sonata_head_title %}
{{ 'Admin'|trans({}, 'SonataAdminBundle') }} //remove this line to get rid of text "Admin"
{% if _title is not empty %}
{{ _title|striptags|raw }}
{% else %}
{% if action is defined %}
-
{% for menu in breadcrumbs_builder.breadcrumbs(admin, action) %}
{% if not loop.first %}
{% if loop.index != 2 %}
>
{% endif %}
{%- set translation_domain = menu.extra('translation_domain', 'messages') -%}
{%- set label = menu.label -%}
{%- if translation_domain is not same as(false) -%}
{%- set label = label|trans(menu.extra('translation_params', {}), translation_domain) -%}
{%- endif -%}
{{ label }}
{% endif %}
{% endfor %}
{% endif %}
{% endif %}
{% endblock %}
i am having trouble commenting out jinja code in a state file,
i have a for loop in sls file
{% for user_name in salt['pillar.get']('userlist') %}
get_user:
- Some code here
....
{% endfor %}
i am commenting it out with #, but the loop still running when i execute state in a minion.
# {% for user_name in salt['pillar.get']('userlist') %}
get_user:
- Some code here
....
# {% endfor %}
what i am missing?
You are commenting jinja code using YAML comment (#), and the reason your for loop is still running is because by default SLS files are rendered as Jinja templates first, and then parsed as YAML documents.
You need to use jinja comment instead, {# ..... #}
{# {% for user_name in salt['pillar.get']('userlist') %} #}
get_user:
- Some code here
....
{# {% endfor %} #}
Enclose them in {# ... #}:
{# {% for user_name in salt['pillar.get']('userlist') %} #}
get_user:
- Some code here
....
{# {% endfor %} #}
I'm trying to concatenate strings in a state, and I'm not having much luck. I've seen the posts that suggest using (|join), but all my strings are not in a single dictionary. Here's my code:
sshd_content:
file.line:
{% set admin_groups = '' %}
{% for app in grains['application_groups'] %}
{% for group in pillar['admin_users'][app]['members'] %}
{% set admin_groups = admin_groups ~ ' ' ~ group ~ '#mydomain.com' %}
{% endfor %}
{% endfor %}
- name: /etc/ssh/sshd_config
- match: AllowGroups wheel fred
- mode: replace
- content: AllowGroups wheel fred bob {{ admin_groups }}
I've tried using + instead of ~ without luck, too.
What am I doing wrong?
This state works fine:
sudoers_asmgroups_content:
file.append:
- name: /etc/sudoers.d/mygroups
- text:
{% for app in grains['application_groups'] %}
{% for group in pillar['admin_users'][app]['members'] %}
- '%{{ group }}#mydomain.com ALL=(ALL) ALL'
{% endfor %}
{% endfor %}
I found a viable solution by modifying the solution here.
It appears to be a scoping issue with the admin_groups variable. Not sure why append works, but I'm not going to argue.
For the example in the OP above, here is the code:
sshd_content:
file.line:
{% set admin_groups = [] %}
{% for app in grains['application_groups'] %}
{% for group in pillar['admin_users'][app]['members'] %}
{% do admin_groups.append(group) %}
{% endfor %}
{% endfor %}
- name: /etc/ssh/sshd_config
- match: AllowGroups wheel myadmin
- mode: replace
- content: AllowGroups wheel fred bob {{ admin_groups|join('#mydomain.com ') }}#mydomain.com
{% endif %}
Need to add the second #domain.com since the items are AD group names, and join only adds the separator when there is another value.
I am using Twig inside my Symfony 2 WebApp project. I use {% embed SomeTamplate %} to include the content of one template file in another. This workes fine, but translation is not working inside the embedded file.
Page Template:
{% extends 'AppBundle::layout.html.twig' %}
{% trans_default_domain mypages' %}
1: {{ 'pages.home.sometext'|trans }}
{% embed "block.html.twig" with {'classes': 'homepage-hero'} %}
{% block content %}
2: {{ 'pages.home.sometext'|trans }}
{% endblock %}
{% endembed %}
{% embed "block.html.twig" with {'classes': 'red-bg'} %}
{% block content %}
3: {{ 'pages.home.sometext'|trans }}
{% endblock %}
{% endembed %}
Block template:
{% trans_default_domain mypages' %}
<div class="full-width-block{% if classes is defined %} {{ classes }}{% endif %}">
X: {{ 'pages.home.sometext'|trans }}
{% block content %}
{% endblock %}
</div>
Output:
1: SomeText
X: SomeText
2: pages.home.sometext
X: SomeText
3: pages.home.sometext
So: While the translation works fine within the two template files, the same text constant within the embedded block, is not translated. How can I fix this?
the domain must be enclosed in quotes, just put the last quotation mark.
Visit http://symfony.com/doc/current/book/translation.html
Put it this way:
{% trans_default_domain "mypages" %}
I hope your problem is solved