Get the dbname on twig silex/symfony - symfony

I'm searching how i can get the "data base name" on my twig view on silex and symfony2 or 3.
I found that i can go on "app.db" and there is "_params" and "db name" witch are twig object and protected so i can access to it.
I have tried :
app.db._params.dbname
app.db.dbname
app.db.get('dbname')
app.db.get('_params')
app.db.get('params')
There is an other solution with out set the variable in the controller??
Thank in advance

You can inject global variables into templates like described in the docs
http://symfony.com/doc/3.1/cookbook/templating/global_variables.html
# app/config/parameters.yml
parameters:
database_name: name
# app/config/config.yml
twig:
globals:
app_database_name: '%database_name%'
{# default/index.html.twig #}
{{ app_database_name }}

Related

Twig global variable into symfony controller

In my Symfony 4 application I use a Twig global variable to store the name of my website. I need to fetch its value both into my templates and controllers.
twig:
globals:
site_title: My blog
I am able to get it inside my Twig templates : {{ site_title }}
In my controller, I tried $this->getParameter('site_title') but :
The parameter "site_title" must be defined.
Try this:
$twigglobals = $this->get("twig")->getGlobals();
and you can get content by:
$site_title = $twigglobals["site_title"];

how to set a random key once using saltstack

I install a configuration for rails that looks like this (simplified):
production:
secret_key_base: 800afb35d5086b2c60ebd35c01b2bd2b522c2492
db_username: ...
db_password: ...
and so it gets installed from a template file
{{ role }}:
secret_key_base: {{ secret_key }}
db_username: {{ db_user }}
db_password: {{ db_pass }}
And the role and db user/pass get pulled from pillar and installed in that file. The secret_key it would make sense to generate randomly, e.g., {{ salt['random.get_str'](length=80) }}. But I want to generate it once, not every time the template is rendered. (Changing the secret key invalidates cookies, not something to do on each salt run.)
The only solution I've found is two-phase: I have a template.in file
{{ role }}:
secret_key_base: ||secret_key_base||
db_username: {{ db_user }}
db_password: {{ db_pass }}
that I sed into my template file on any given minion:
/srv/salt/rails/secrets.yml:
cmd.run:
# Fill in the secret key base (used for cookies). We can't use
# jinja2 for this, since jinja would complain about the other
# variables that it doesn't know how to replace. We want our
# output to be a jinja template.
- name: |
cat /srv/salt/rails/secrets.yml.in | \
sed -e 's/||secret_key_base||/{{ salt['random.get_str'](length=80) }}/;' | \
cat > /srv/salt/rails/secrets.yml
chmod 400 /srv/salt/rails/secrets.yml
- creates: /srv/salt/rails/secrets.yml
- runas: root
/var/railroad/{{host_role}}/shared/config/secrets.yml:
file.managed:
- source: salt://rails/secrets.yml
- mode: 400
- user: railroad-{{host_role}}
- group: railroad-{{host_role}}
- template: jinja
- defaults:
role: host_role
db_username: m_u
db_password: m_p
This works but has the disadvantage that a change to secrets.yml.in would not be propagated on to secrets.yml. (Suppose we add another key to the secrets file.) It also feels clunkier than necessary.
Is there a better way?
A better way
As noted in the comments, a better way is to just generate the secret by hand (after all, it's only done at host setup) and store it in pillar, where we anyway have to say a few things about each host.
Here is what the working code eventually looked like, unsimplified for those who might want to see something more complex. Much of the complexity is my host_credentials pillar data, which tries to characterise all that we need to know about each host.
{% set fqdn = grains.get('fqdn', 'unknown-host-fqdn') %}
{% set host_role = pillar['host_credentials']
[grains.get('fqdn')]
['role'] %}
{% set examplecom_web_app = pillar['host_credentials']
[grains.get('fqdn')]
['examplecom-web-app'] %}
{% set mysql_server_host = examplecom_web_app.mysql.host %}
{% set mysql_server_database = examplecom_web_app.mysql.database %}
{% set mysql_server_role = examplecom_web_app.mysql.role %}
{% set mysql_server_spec = pillar['host_credentials']
[mysql_server_host]
['mysql'] %}
{% set mongodb_server_host = examplecom_web_app.mongodb.host %}
{% set mongodb_server_spec = pillar['host_credentials']
[mongodb_server_host]
['mongodb'] %}
/var/examplecom/railroad/{{host_role}}/shared/config/secrets.yml:
file.managed:
- source: salt://rails/secrets.yml
- mode: 400
- user: railroad-{{host_role}}
- group: railroad-{{host_role}}
- template: jinja
- defaults:
role: {{ host_role }}
secret_key_base: {{ examplecom_web_app.secret_key_base }}
mysql_hostname: {{ mysql_server_host }}
mysql_username: {{ mysql_server_spec[mysql_server_database]
[mysql_server_role]
['username'] }}
mysql_password: {{ mysql_server_spec[mysql_server_database]
[mysql_server_role]
['password'] }}
mongodb_hostname: {{ mongodb_server_host }}
mongodb_username: {{ mongodb_server_spec.username }}
mongodb_password: {{ mongodb_server_spec.password }}
As an aside, I was happy to discover that jinja2 is white-space agnostic, which helps enormously with readability on such lookups.
I recommend putting the secret in a pillar and generate the value once (manually) on the master. That way you can avoid doing the stateful on-the-fly-magic in your SLS file.
jma updated his question to include an example solution.
Do I understand you correctly:
- this is salt-masterless run?
- you generate some template file on masterless node (to have some static parts generated once)
- you apply file.managed state to previously generated file?
Assuming my understandings:
First of all it will be propagated to another states if you set proper watch/require statements but in your case this would be harder to achieve as you've used cmd.run for template parsing (you must add stateful argument to express that there is some potential state changes underlying)
Remarks:
- did you see file.blockreplace? it seems that you can use this to replace first cmd.run and get file change detection "for free"
- as for one time password generation, there is nice trick to do this simply by using grains.get_or_set_hash
As the generated password is not changing for given minion (you master-less node in your case) the file.blockreplace won't report any changes unless you add changes to the template
Having said this, I think we can go further and your state actually can be as simple as this (template changes will be propagated always, key will be generated once):
/var/railroad/{{host_role}}/shared/config/secrets.yml:
file.managed:
- source: salt://rails/secrets.yml
- mode: 400
- user: railroad-{{host_role}}
- group: railroad-{{host_role}}
- template: jinja
- defaults:
role: host_role
db_username: m_u
db_password: {{ salt['grains.get_or_set_hash']('some:place:secret_key_base') }}

Passing variables with include in salt-stack

I have several states that are almost the same. All of them deploy project, create virtualenv and configure supervisor. Difference is only in repo, project name and some additional actions.
A lot of code is duplicated. Is it possible to put the same parts into file and include it with additional variables?
In Ansible it can be done this way:
tasks:
- include: wordpress.yml
vars:
wp_user: timmy
ssh_keys:
- keys/one.txt
- keys/two.txt
This question looks similar to this one
If I understood your question correctly - I believe the best way to achieve what you want is to use Salt Macros.
With this most of your state will go to macros with placeholders being parameters like:
# lib.sls
{% macro create_user(user, password) %}
{{user}}:
user.present:
- home: /home/{{user}}
- password: {{password}}
{% endmacro %}
Then your state will look like:
# john.sls
{% from 'lib.sls' import create_user with context %}
{{ create_user('john', '<password hash>') }}
and:
# jane.sls
{% from 'lib.sls' import create_user with context %}
{{ create_user('john', '<password hash>') }}
As I found out there is another way to archive it without messing with templates (more Ansible way). Create an abstract state "python-project". Create concrete roles then and provide different pillars to these roles:
salt/top.sls:
base:
'roles:python-project-1':
- match: grain
- python-project
'roles:python-project-2':
- match: grain
- python-project
pillar/top.sls:
base:
'roles:python-project-1':
- match: grain
- common-pillars
- pillars-for-the-first
'roles:python-project-2':
- match: grain
- common-pillars
- pillars-for-the-second
Structure:
pillar/top.sls
pillar/common-pillars/init.sls
pillar/pillars-for-the-first/init.sls
pillar/pillars-for-the-second/init.sls
salt/top.sls
salt/python-project/init.sls
You can use Jinja imports to do that:
top.sls
{% set user = 'john' %}
{% include 'config.sls' %}
config.sls
file.managed:
- name: '/Users/{{ user }}/.config
- user: {{ user }}

Global Params in FOSUserBundle

I try to retrieve the global param that i define in parameters.yml and config.yml
in FOSUserBundle.en.yml under registration, in message i try to pass %myparam% and in my email.txt i try pass %myparam%:param like this
{{ 'registration.email.message'|trans({'%username%': user.username, '%confirmationUrl%': confirmationUrl,'%myparam%':myparam}, 'FOSUserBundle') }}
but it dosen't works.
and can i insert html inside yml and new line?
thanks
In your config.yml under fosuserbundle configuration.
confirmation:
enabled: true
template: MYMailBundle:Registration:email.html.twig
By doing this you are creating a twig template where you can render your variables and format your html how you want.
If you want to create a newline in your yml file I think you could do it by adding a \n.

How to access project configuration parameters from javascript in Symfony2

I'm using Symfony 2.1 dev and looking for easiest way to get parameter from app/config/parameters.yml (ini).
Simple example:
I have record in parameters.yml
parameters:
url: "http://domain.com"
Then i want to use it somehow in static js file
var url = "{{ app.url }}"; // trying to avoid hardcode
This token should be replaced by actual value from coonfig after
app/console assetic:dump
So final js will have
var url = "http://domain.com";
Currently i'm thinking about writing my own console command but firstly i want to ensure there is no any standard way of doing such things in Symfony2 or maybe some bundle that can halp me?
UPDATE: i'd like to do this with AsseticBundle, like YUI and LESS
assetic:
debug: %kernel.debug%
use_controller: false
write_to: %kernel.root_dir%/../web
filters:
cssrewrite: ~
lessphp: ~
yui_js:
jar: "%kernel.root_dir%/Resources/java/yuicompressor-2.4.6.jar"
yui_css:
jar: %kernel.root_dir%/Resources/java/yuicompressor-2.4.6.jar
to add another one filter which will replace token {{ app.url }} in js file to actual "http://domain.com"
A simple solution would be to reference your parameters in the twig globals:
parameters:
url: "http://domain.com"
an_array:
twig: "is cool"
and: "symfony2 to"
twig:
globals:
app_parameters:
url: %url%
an_array: %an_array%
Then in your template:
<script>
window.parameters = {{ app_parameters|json_encode|raw }};
</script>
would render something like:
<script>
window.parameters = {"url":"http://domain.com","an_array":{"twig":"is cool","and":"symfony2 to"}};
</script>

Resources