I want to trigger custom named event if sls state fails.
I have following code:
check-if-needs-restarting:
{% if grains['os'] == 'CentOS' %}
cmd.run:
- name: needs-restarting -r
- onfail:
- cmd.run:
- name: salt-call event.send needs-restarting
{% endif %}
but somehow it crashes salt renderer:
An un-handled exception was caught by salt's global exception handler:
SaltRenderError: Could not locate requisite of [cmd] present in state with name
Any idea why? I tried fire_event instead but thn I dont have custom name I want "needs-restarting"
onfail like other global state arguments works only with states as arguments
See examples in the official documentation
I'm using salt-cloud to deploy VMs and I'm trying to get them registred in my DNS with the Saltstack Reactor system.
I have a reactor.conf with this trigger:
reactor:
- 'salt/cloud/*/created': # Add a VM
- /srv/reactor/initialize_vm.sls
initilize_vm.sls :
invoke_orchestrate_add_to_dns:
runner.state.orchestrate:
- mods: orch.add_to_dns
- pillar:
event_name: {{ name }}
event_profile: {{ profile }}
orch/add_to_dns.sls:
{% set name = pillar['event_name'] %}
{% set profile = pillar['event_profile'] %}
vm-add-dns-{{ name }}:
sqlite3.row_present:
- db: /var/lib/powerdns/pdns.sqlite3
- table: records
- where_sql: "name='{{ name }}' and type='A'"
- data:
domain_id: 1
name: {{ name }}
type: A
content: {{ ??? }}
ttl: 300
prio: 0
disabled: 0
I just need to know the IP address of the new minion. But as the orchestration run on the master, I can't just do a content: {{ grains['fqdn_ip4'] }}.
Any ideas to get minions informations ?
You can use the Salt Mine to get information from minions. To use the Salt Mine you need to know which minion you want to have information from. Luckily the reactor receives the data from the event bus. data['id'] contains the minion ID.
In the Salt Mine you can add a function to retrieve a minions IP like this:
mine_functions:
public_ip4:
- mine_function: grains.get
- fqdn_ip4
Now you can use mine.get in your sls files to get the IP address from a minion. In your case it will be the minion ID you just received from the event bus like this:
{%- for server, addrs in salt['mine.get'](data['id']', 'public_ip4') %}
{{ addrs[0] }}
{% endfor %}
Notes:
I don't use Salt Cloud and orchestration for DNS so I can't combine
your code with mine and check if it works. I hope it will be useful
for you :)
I named the mine public_ip4 instead of fqdn_ip4. It's to
clarify that this is a name in the Salt Mine and not the Grain you
are requesting.
If you don't wish to add configuration you can also do the following:
{% set ip = salt.saltutil.runner('salt.execute', [data['id']], {'fun': 'grains.get', 'kwarg': {'key':'fqdn_ip4'}})[data['id']] %}
Or as mentioned in the comments:
{% set ip = salt['saltutil.runner']('cache.grains', tgt=data['id'])[data['id']]['fqdn_ip4'][0] %}
Figured I'd add this here as a reference for others.
I've been looking for an explanation in the SaltStack docs about what 'with context' means. But there's only examples of using context.
What is 'context'?
What does it do here? And why is Debian ignored in the map.jinja file? (for example map.log_dir seems to "jump down" a level)
# config.sls
{% from "bind/map.jinja" import map with context %}
include:
- bind
{{ map.log_dir }}:
file.directory:
- user: root
- group: {{ salt['pillar.get']('bind:config:group', map.group) }}
- mode: 775
- require:
- pkg: bind
# map.jinja
{% set map = salt['grains.filter_by']({
'Debian': {
'pkgs': ['bind9', 'bind9utils', 'dnssec-tools'],
'service': 'bind9',
'config_source_dir': 'bind/files/debian',
'zones_source_dir': 'zones',
'config': '/etc/bind/named.conf',
'local_config': '/etc/bind/named.conf.local',
'key_config': '/etc/bind/named.conf.key',
'options_config': '/etc/bind/named.conf.options',
'default_config': '/etc/default/bind9',
'default_zones_config': '/etc/bind/named.conf.default-zones',
'named_directory': '/var/cache/bind/zones',
'log_dir': '/var/log/bind9',
'user': 'root',
'group': 'bind',
'mode': '644'
},
'RedHat': {
'pkgs': ['bind'],
'service': 'named',
'config_source_dir': 'bind/files/redhat',
'zones_source_dir': 'zones',
'config': '/etc/named.conf',
'local_config': '/etc/named.conf.local',
'default_config': '/etc/sysconfig/named',
'named_directory': '/var/named/data',
'log_dir': '/var/log/named',
'user': 'root',
'group': 'named',
'mode': '640'
},
Since this page is the top search result for "jinja import with context" (and the other answer doesn't actually say what it does), and I keep coming back to this page every couple of months when I need to mess with Salt but forget what with context does:
When you import foo in jinja, normally the macros you've defined in foo don't have access to variables in the file you're importing it from. As an optimization, Jinja will then cache this if you import again later in the file. If instead you do import foo with context, then the macros in foo can access the variables in the file it's being imported from. The trade-off is that Jinja no longer caches foo, so you pay in render time.
When you do include, your variables do get passed into the other file. You then render the contents of the other file and paste them in. If you do include foo without context, you don't pass the variables of the current file in. This is useful, because Jinja will optimize this by caching the contents of foo, speeding up your render.
with context is part of the jinja template engine.
You can read more about it in the jinja docs:
import context
behavior
context API
Regarding the missing debian data - is this your complete map.jinja? the snippet misses }, default='Debian') %} according to grains.filter_by
I would like to search some parameters in my parameters.yml file from a template in twig, depending on a variable. I have tried the following but it didn't work:
parameters.yml
twig:
globals:
status:
0: Paused
1: Running
2: Closed
template.html.twig
(game.status value can be 1, 2 or 3)
{% set var_status = game.status %}
{% set var_statustext = status.get(var_status) %}
<p>Status: {{ var_statustext }}</p>
Also I would like to access this parameters in the controller.
How could I do it? Thanks in advance.
You're looking for a way to access the value of the the global variable status (type => array) for a given key that is itself stored in another variable game.status (type => integer/string ).
Assuming game.status returns 1 ...
Then you can output Running using:
{{ attribute(status, game.status) }}
The attribute function is what you're looking for.
I want to do this in the main app/config/config.yml file:
variables:
a: 1
email: jim#email.com
variable2: hello
And this in any controller:
$variables = **get Yaml config data**
echo $variables['email'];
Of course I can't, but is anything like this possible?
I've seen where you can set global variables for access by Twig, but not seen how a Symfony2 controller can get them.
Of course if there's a better method as well then please mention that as this to me seems a good way of doing it.
Use parameters in parameters.yml for that:
parameters:
email: boss#acme.com
This way you'll be able to get it in a controller this way:
$email = $this->container->getParameter('email');
You can also create a Twig global in config.yml to have access to it from Twig using the same parameter:
twig:
globals:
email: %email%
And in Twig:
{{ email }}