Consul-Template: Looping over a k/v pair and using the result in another key - consul-template

Given the Consul keys:
flyway/tweedle/server: postgres
flyway/beetle/server: postgres
flyway/battle/server: mysql
service/tweedle/repo: fox/tweedle.git
service/beetle/repo: fox/beetle.git
service/battle/repo: fox/battle.git
I'm trying to loop through the top set, using the key to lookup values in the bottom set, using this code (that doesn't work):
{
{{ range $key, $pairs :=tree "flyway/" | explode }}
$key: {{ key "service/{{$key}}/repo" }}
{{ end }}
}
to get:
tweedle: fox/tweedle.git
beetle: fox/beetle.git
battle: fox/battle.git

My colleague, Brian answered this in the support ticket with HashiCorp.
Just wanted to share the answer here, so that it would benefit others as well. This is how it can be done:
{
{{ range $key, $pairs := tree "flyway/" | explode }}
{{ $name := $key }}
{{ range $key, $pairs := tree ($name | printf "service/%s/") | explode }}
{{ $name}}: {{ $pairs }}
{{ end }}
{{ end }}
}

Related

jinja template nested loop only giving last loop value as output in ansible playbook

My playbook task is to fetch all resource groups then list all the vms under each resource group and for each vm find the tags associated with it. I am getting correct output when running my playbook. But I am not able to save it correctly using jinja template. Here, is the template I am using:
{
{% for rg in group_list %}
"resource_group": "{{ rg }}",
{% for vm in vm_list %}
"vmId": "{{ vm }}",
{% if vmTag_json|length > 0 %}
{% for key, value in vmTag_json.items() %}
"Key": "{{ key }}",
"Value": "{{ value }}"
{% if not loop.last %},{% endif %}
{% endfor %}
{% else %}
"tags": "NA"
{% endif %}
{% endfor %}
{% endfor %}
}
And the output I am getting is:
{
"resource_group": "RG1",
"vmId": "VM-01",
"Key": "Test",
"Value": "win"
"vmId": "VM-02",
"Key": "Test",
"Value": "win"
}
Tags value is coming same for every machine which is the last value in the loop. Also a "," should come after "Value": "win" if the loop is not ended, it is also not coming and if I put it then it also comes after the last value.

Twig sort function, sorting numbers low-high

Im trying to use the twig |sort function but find it rather confusing to figure out how to sort with numbers ranging lowest to highest.
Documentation: https://twig.symfony.com/doc/3.x/filters/sort.html
My code example:
{% for duel in group %}
{% duel.intvalue %}
{% endfor %}
Where intvalue is the data needing sorting
Can anyone help me out
I think the documentation is clear enough.
let say you have array of object users
{
"users" : [
{
"name": "third",
"age": 29
},
{
"name": "first",
"age": 2
},
{
"name": "first",
"age": 2
},
{
"name": "second",
"age": 28
}
]
}
sort your data by name
{% for user in users|sort %}
{{ user.name }},
{% endfor %}
sort your data by age
{% for user in users|sort %}
{{ user.age }},
{% endfor %}
sort data by age and show its name
{% for user in users|sort((a, b) => a.age <=> b.age) %}
{{ user.name }},
{% endfor %}
https://twigfiddle.com/tca0vz
A working example would be:
{# setup the expample #}
{% set group = [{intvalue:5},{intvalue:1},{intvalue:4},{intvalue:3},{intvalue:2}] %}
{% for duel in group|sort((a, b) => a.intvalue <=> b.intvalue) %}
{{ duel.intvalue }}
{% endfor %}
Or see this fiddle: https://twigfiddle.com/ru1gpd

How to Remove comma for the last object in nested for loop?

I want to remove the comma from the last object in nested for loop:
[{% for item1 in articles.results.entities %}
{% for item2 in articles1.results.entities %}
{% if item1.knowledgearticleid != item2.knowledgearticleid %}
{
"Id":"{{item1.knowledgearticleid}}",
"Title":"{{item1.title}}",
"Articlepublicumber":"{{item1.articlepublicnumber}}",
"Description":"{{item1.description}}"
}
{% endif %}
{% endfor %}
{% unless forloop.last %},{% endunless %}
{% endfor %}]
But this is not working; it is giving me duplicate commas:
[
{
"Id": "ddcb41c6-1f33-ea11-a813-000d3a3be5cf",
"Title": "1 Test1",
"Articlepublicumber": "KA-01992",
"Description": "Test1"
},,
{
"Id": "9564dc21-9df6-414b-ab99-da4ba534fd83",
"Title": "Test2",
"Articlepublicumber": "KA-03363",
"Description": "Test2"
}
]
Identical issue in terms of Shopify liquid snippet discussed here and this is common scenario with concatenation in any language.
With each accepted iteration, add a comma and then the “needed item”.  Except if this is the first accepted iteration, don't add the comma.
I just manage to modify your code, but test it on your end. But you got the idea right?
[{% assign list_items = "" %}
{% for item1 in articles.results.entities %}
{% for item2 in articles1.results.entities %}
{% if item1.knowledgearticleid != item2.knowledgearticleid %}
{% unless list_items == "" %}
{% assign list_items = "zzz" %}
{
"Id":"{{item1.knowledgearticleid}}",
"Title":"{{item1.title}}",
"Articlepublicumber":"{{item1.articlepublicnumber}}",
"Description":"{{item1.description}}"
}
{% endunless %}
{% unless list_items == "zzz" %}
,{
"Id":"{{item1.knowledgearticleid}}",
"Title":"{{item1.title}}",
"Articlepublicumber":"{{item1.articlepublicnumber}}",
"Description":"{{item1.description}}"
}
{% endunless %}
{% endif %}
{% endfor %}
{% endfor %}]

how to sort a dictionary by the value of a key in the dictionary?

I wrote my own wishlist in python3 flask (with apache mod_wsgi)
this is my data structure for the wishlist items:
{
},
"": {
"images": {
"pic": ""
},
"buylinks": {
"": {
"link": "",
"price": ""
}
},
"want": "",
"comments": ""
}
}
for example:
"Nintendo Joy-Con (L/R) - Gray": {
"images": {
"pic": "wishlist/joycons-grey.jpg"
},
"buylinks": {
"Amazon": {
"link": "https://www.amazon.com/dp/B01N6QKT7H",
"price": "66.99"
}
},
"want": "7/10",
"comments": "extra joycons for playing with friends on my switch"
},
right now every time I update the json file containing the wishlist data the apache server jinja template spits it iut in a different order
my jinja template looks like
<table>
<tr>
<th>Name</th>
<th>Image(s)</th>
<th>Links To Buy</th>
<th>Want/10</th>
<th>Comments</th>
</tr>
{% for key in wishlist.keys() %}
<tr>
<td><b>{{ key }}</b></td>
<td>{% for image in wishlist[key]["images"].keys() %}
<img src="{{ url_for('static', filename=wishlist[key]["images"][image]) }}" width="250px">
{% endfor %}</td>
<td>{% for merchant in wishlist[key]["buylinks"].keys() %}
{{ merchant}} (~${{ wishlist[key]["buylinks"][merchant]["price"] }})
<br>{% endfor %}</td>
<td><a> {{ wishlist[key]["want"] }} </a></td>
<td> {{ wishlist[key]["comments"] }}</td>
</tr>
{% endfor %}
</table>
how do I modify the {% for key in wishlist.keys() %} line to sort the wishlist by the value of the want key such that 10/10 is at the beginning and 0/10 is at the end? (the value to use to sort the example item would be "7/10")
I think I need to use the "sorted" function but I'm not sure how to
so to get this to work I had to add
wishlist_keys = sorted(wishlist.keys(), reverse=True, key=lambda x: wishlist[x]["want"] )
to my flask python code and pass wishlist_keys into render_template()
and change the template to
{% for key in wishlist_keys %}

How can I pass a dynamic value to another component in twig/ craft cms?

I need the title to show the (current date - 1)
When I hard code a value eg "17"
This is where the component is displaying (in index)
{% include 'home/key-facts' with {
content: {
keyFactsHeading: entry.keyFactsHeading,
keyFacts: entry.keyFacts,
keyFactsSmall: entry.keyFactsSmall,
}
Which is this file here --->
This is how I've included the date
{% include '_components/bg-type' with {
content: {
title: {{ "now"|date('Y') - 1 }}
},
} only %}
I am passing content.title into here --->
<div class="bg-type">
<div class="bg-type__text bg-type--large">
{{ content.title }}
</div>
</div>
When hardcoding the value as below it works fine but when I add
title: {{ "now"|date('Y') - 1}} I get a 500 error.
{% include '_components/bg-type' with {
content: {
title: 17
},
} only %}
Why is this? Can you also explain why what I'm trying doesn't work?
I've tried dumping {{ "now"|date('Y') - 1}} and I can see the year I want
The {{ ... }} notation is used to output data. In this case you only want to pass data towards an include. Notice you already inside a twig-statement, {% include .... %}
The correct syntax would be
{% include '_components/bg-type' with {
content: {
title: "now"|date('Y') - 1,
},
} only %}

Resources