Demm
Demm

Reputation: 13

Render variables from a file

There is a file api.yml containing a config for ansible:

config/application.properties:
 server.port: 6081
 system.default.lang: rus
 api.pdd.url: "http://{{ stage['PDD'] }}"
 api.policy.alias: "integration"
 api.order.url: "http://{{ stage['Order'] }}
 api.foo.url: "http://{{ stage['FOO'] }}

There is a stage.yml containing the key and the stage values:

default_node:
 Order: '172.16.100.40:8811'
 PDD: '172.16.100.41:8090'
 FOO: '10.100.0.11:3165

In fact, these files are larger and the 'stage' variables are also many. My task is to parse api.yml and turn it into properties-config. The problem is that I can not pull up the values ​​{{stage ['value']}} I'm trying to do it this way:

stream = yaml.load(open('api.yml'))
result={}
result.update(stream['config/application.properties'])
context= yaml.load(open('stage.yml'))
stage={}
stage.update(context['default_node'])
text = '{% for items in result | dictsort(true)%}  {{ items[0] }} = {{
     items[1] }} {%endfor%}'

template = Template(text)
properti = (template.render(result=result, stage=stage))

At the output I get this:

server.port = 6081
system.default.lang = rus
api.pdd.url = http://{{ stage['PDD'] }}
api.policy.alias = integration
api.order.url = http://{{ stage['Order'] }}
api.foo.url = http://{{ stage['FOO'] }}

And you need to get this:

server.port = 6081
system.default.lang = rus
api.pdd.url = 172.16.100.41:8090
api.policy.alias = "integration"
api.order.url = 172.16.100.40:8811
api.foo.url = 10.100.0.11:3165

Can I do it with jinja or ansible lib? Sorry for my bad english

Upvotes: 1

Views: 1168

Answers (1)

kajahno
kajahno

Reputation: 404

Following this approach, you would need to treat api.yml as a template itself and render it. Otherwise, jinja2 will treat it as a simple value of the property. Something like this would do:

import yaml
from jinja2 import Environment, Template 
import json  


stream = yaml.load(open('api.yml'))
result={}
result.update(stream['config/application.properties'])
context= yaml.load(open('stage.yml'))
stage={}
stage.update(context['default_node'])
text = """{% for items in result | dictsort(true)%}  {{ items[0] }} = {{ items[1] }} {%endfor%}"""

#Then render the results dic as well
resultsTemplate = Template(json.dumps(result))
resultsRendered = json.loads( resultsTemplate.render(stage=stage) )

template = Template(text) 
properti = (template.render(result=resultsRendered, stage=stage))

After this you will see the wanted values in the properti var:

'  api.foo.url = http://10.100.0.11:3165   api.order.url = http://172.16.100.40:8811   api.pdd.url = http://172.16.100.41:8090   api.policy.alias = integration   server.port = 6081   system.default.lang = rus'

It would be nice though if jinja2 was able to render recursively. Maybe spending some time working out with the globals and shared modes of the Environment this can be achieved.

Hope this helps.

Upvotes: 1

Related Questions