# Extract IPv6 link-local address from facts

**URL:** <https://forum.ansible.com/t/extract-ipv6-link-local-address-from-facts/14231>\
**Category:** Ansible Project\
**Created:** [December 28, 2013, 11:30pm UTC](https://forum.ansible.com/t/extract-ipv6-link-local-address-from-facts/14231 "2013-12-28T23:30:18Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![Anand\_Buddhdev2](https://avatars.discourse-cdn.com/v4/letter/a/48db29/32.png) [@Anand\_Buddhdev2](https://forum.ansible.com/u/Anand_Buddhdev2)\
**Post date:** [December 28, 2013, 11:30pm UTC](https://forum.ansible.com/t/extract-ipv6-link-local-address-from-facts/14231/1 "2013-12-28T23:30:18Z")

</div>

Hello ansible people,

I want to extract an interface’s IPv6 link-local address from facts. I’ve figured out a round-about way of doing this in a template. I do:

{% for v6 in hostvars[inventory\_hostname][‘ansible\_em1’][‘ipv6’] %}

{% if v6.scope == ‘link’ %}

{{v6.address}};

{% endif %}

{% endfor %}

However, I don’t know how to do this in a playbook where I wish to use the link-local address in a task. Any suggestions?

Regards,

Anand

---

<div class="post-metadata">

**Author:** ![kahlil.hodgson](https://avatars.discourse-cdn.com/v4/letter/k/b9bd4f/32.png) [@kahlil.hodgson](https://forum.ansible.com/u/kahlil.hodgson)\
**Post date:** [December 29, 2013, 11:49pm UTC](https://forum.ansible.com/t/extract-ipv6-link-local-address-from-facts/14231/2 "2013-12-29T23:49:00Z")

</div>

There will be cleaner ways to do this once jinja2.7 becomes more  
readily available, but for now you could probably simulate the above  
loop with 'with\_items' and a 'when' conditional:

tasks:  
&nbsp;&nbsp;&nbsp;- name: ipv6 link local  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;debug: msg="{{ item.address }}"  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;when: item.scope == 'link'  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;with\_items: ansible\_em1.ipv6

Yes, this is an ugly hack.

K

Kahlil (Kal) Hodgson GPG: C9A02289  
Head of Technology (m) +61 (0) 4 2573 0382  
DealMax Pty Ltd (w) +61 (0) 3 9008 5281

Suite 1415  
401 Docklands Drive  
Docklands VIC 3008 Australia

"All parts should go together without forcing. You must remember that  
the parts you are reassembling were disassembled by you. Therefore,  
if you can't get them together again, there must be a reason. By all  
means, do not use a hammer." -- IBM maintenance manual, 1925

---

<div class="post-metadata">

**Author:** ![Anand\_Buddhdev2](https://avatars.discourse-cdn.com/v4/letter/a/48db29/32.png) [@Anand\_Buddhdev2](https://forum.ansible.com/u/Anand_Buddhdev2)\
**Post date:** [December 30, 2013, 11:15am UTC](https://forum.ansible.com/t/extract-ipv6-link-local-address-from-facts/14231/3 "2013-12-30T11:15:55Z")

</div>

Hi Kahlil,

Thank you for this tip. It works!

So you mentioned that with Jinja 2.7 this is easier. I already have Jinja 2.7.1. What feature of this version can I use to avoid this hack?

Regards,

Anand

---

<div class="post-metadata">

**Author:** ![kahlil.hodgson](https://avatars.discourse-cdn.com/v4/letter/k/b9bd4f/32.png) [@kahlil.hodgson](https://forum.ansible.com/u/kahlil.hodgson)\
**Post date:** [December 31, 2013, 4:31am UTC](https://forum.ansible.com/t/extract-ipv6-link-local-address-from-facts/14231/4 "2013-12-31T04:31:18Z")

</div>

Glad that helps.

In Jinja2.7 you have the following filters that can be used to traverse or extract parts of lists:

select  
selectattr  
reject  
rejectattr  
map

so I believe that following would work

{{ ansible\_em1.ipv6 | selectattr(‘scope’, ‘local’) | first | attr(‘address’) }}

just off the top of my head and untested.

Check out [http://jinja.pocoo.org/docs/templates/#list-of-builtin-filters](http://jinja.pocoo.org/docs/templates/#list-of-builtin-filters)

for more details.

Cheers!

Kal

Kahlil (Kal) Hodgson GPG: C9A02289  
Head of Technology (m) +61 (0) 4 2573 0382  
DealMax Pty Ltd (w) +61 (0) 3 9008 5281

Suite 1415  
401 Docklands Drive  
Docklands VIC 3008 Australia

“All parts should go together without forcing. You must remember that  
the parts you are reassembling were disassembled by you. Therefore,  
if you can’t get them together again, there must be a reason. By all  
means, do not use a hammer.” – IBM maintenance manual, 1925

---

<div class="post-metadata">

**Author:** ![Anand\_Buddhdev2](https://avatars.discourse-cdn.com/v4/letter/a/48db29/32.png) [@Anand\_Buddhdev2](https://forum.ansible.com/u/Anand_Buddhdev2)\
**Post date:** [January 1, 2014, 8:01pm UTC](https://forum.ansible.com/t/extract-ipv6-link-local-address-from-facts/14231/5 "2014-01-01T20:01:36Z")

</div>

Hi Kahlil,

> In Jinja2.7 you have the following filters that can be used to traverse or extract parts of lists:
> 
> select  
> selectattr  
> reject  
> rejectattr  
> map
> 
> so I believe that following would work
> 
> {{ ansible\_em1.ipv6 | selectattr(‘scope’, ‘local’) | first | attr(‘address’) }}
> 
> just off the top of my head and untested.

Your example looks logical, and looks like it should work, but I get this error when trying to use it:

TASK: [debug msg=‘{{ansible\_em1.ipv6 | selectattr(“scope”, “local”) | first | attr(“address”)}}’] \*\*\*

fatal: [[ns1.ams.authdns.ripe.net](http://ns1.ams.authdns.ripe.net)] =\> Traceback (most recent call last):

File “/Users/anandb/git/gii-ansible/portable/lib/ansible/runner/ **init**.py”, line 394, in \_executor

exec\_rc = self.\_executor\_internal(host, new\_stdin)

File “/Users/anandb/git/gii-ansible/portable/lib/ansible/runner/ **init**.py”, line 485, in \_executor\_internal

return self.\_executor\_internal\_inner(host, self.module\_name, self.module\_args, inject, port, complex\_args=complex\_args)

File “/Users/anandb/git/gii-ansible/portable/lib/ansible/runner/ **init**.py”, line 679, in \_executor\_internal\_inner

module\_args = template.template(self.basedir, module\_args, inject, fail\_on\_undefined=self.error\_on\_undefined\_vars)

File “/Users/anandb/git/gii-ansible/portable/lib/ansible/utils/template.py”, line 319, in template

varname = template\_from\_string(basedir, varname, vars, fail\_on\_undefined)

File “/Users/anandb/git/gii-ansible/portable/lib/ansible/utils/template.py”, line 539, in template\_from\_string

res = jinja2.utils.concat(rf)

File “”, line 12, in root

File “/Users/anandb/git/gii-ansible/portable/lib/jinja2/filters.py”, line 349, in do\_first

return next(iter(seq))

File “/Users/anandb/git/gii-ansible/portable/lib/jinja2/filters.py”, line 931, in \_select\_or\_reject

if modfunc(func(transfunc(item))):

File “/Users/anandb/git/gii-ansible/portable/lib/jinja2/filters.py”, line 925, in

name, item, args, kwargs)

File “/Users/anandb/git/gii-ansible/portable/lib/jinja2/environment.py”, line 438, in call\_test

raise TemplateRuntimeError(‘no test named %r’ % name)

TemplateRuntimeError: no test named ‘local’

I tried to use Google to look for examples on how to use selectattr, but found nothing useful. The Jinja2 documentation for this filter is quite sparse. If anyone has any more suggestions, I’d be grateful.

Anand

---

<div class="post-metadata">

**Author:** ![kahlil.hodgson](https://avatars.discourse-cdn.com/v4/letter/k/b9bd4f/32.png) [@kahlil.hodgson](https://forum.ansible.com/u/kahlil.hodgson)\
**Post date:** [January 1, 2014, 11:48pm UTC](https://forum.ansible.com/t/extract-ipv6-link-local-address-from-facts/14231/6 "2014-01-01T23:48:22Z")

</div>

Hi Anand,

Looking at the documentation again, it seems I misinterpreted: i did  
not realise that 'none' is a jinja test not a value. It seems the  
second argument to selectattr is a test (see the last line of the  
backtrace), which makes more sense now that I think of it.

Not sure how to insert an equality test into this using jinja  
constructs. Docs do not show a builtin equality test. Hmm had a  
quick dive into the jinja2 code on git hub and found this gem about  
the undocumented 'equalto' test

```auto

    This appears to be a useless test as it does exactly the same as the
    ``==`` operator, but it can be useful when used together with the
    `selectattr` function:

    .. sourcecode:: jinja

        {{ users|selectattr("email", "equalto", "foo@bar.invalid") }}

```

So I think the following might work:

{{ ... | selectattr('scope', 'equalto', 'local') | ... }}

Hope this helps,

K

Kahlil (Kal) Hodgson GPG: C9A02289  
Head of Technology (m) +61 (0) 4 2573 0382  
DealMax Pty Ltd (w) +61 (0) 3 9008 5281

Suite 1415  
401 Docklands Drive  
Docklands VIC 3008 Australia

"All parts should go together without forcing. You must remember that  
the parts you are reassembling were disassembled by you. Therefore,  
if you can't get them together again, there must be a reason. By all  
means, do not use a hammer." -- IBM maintenance manual, 1925

---

<div class="post-metadata">

**Author:** ![kahlil.hodgson](https://avatars.discourse-cdn.com/v4/letter/k/b9bd4f/32.png) [@kahlil.hodgson](https://forum.ansible.com/u/kahlil.hodgson)\
**Post date:** [January 1, 2014, 11:53pm UTC](https://forum.ansible.com/t/extract-ipv6-link-local-address-from-facts/14231/7 "2014-01-01T23:53:04Z")

</div>

Further note: just check the timestamp on the commit that introduced  
the 'equalto' test (2013-11-22),  
so that might not be in the version you are using.

K

Kahlil (Kal) Hodgson GPG: C9A02289  
Head of Technology (m) +61 (0) 4 2573 0382  
DealMax Pty Ltd (w) +61 (0) 3 9008 5281

Suite 1415  
401 Docklands Drive  
Docklands VIC 3008 Australia

"All parts should go together without forcing. You must remember that  
the parts you are reassembling were disassembled by you. Therefore,  
if you can't get them together again, there must be a reason. By all  
means, do not use a hammer." -- IBM maintenance manual, 1925

---

<div class="post-metadata">

**Author:** ![Anand\_Buddhdev2](https://avatars.discourse-cdn.com/v4/letter/a/48db29/32.png) [@Anand\_Buddhdev2](https://forum.ansible.com/u/Anand_Buddhdev2)\
**Post date:** [January 2, 2014, 12:21am UTC](https://forum.ansible.com/t/extract-ipv6-link-local-address-from-facts/14231/8 "2014-01-02T00:21:03Z")

</div>

Hi Kahlil,

> Further note: just check the timestamp on the commit that introduced  
> the ‘equalto’ test (2013-11-22),  
> so that might not be in the version you are using.

Thank you for taking the time to dig into this, and discovering the “equalto” test. I appreciate it a lot! It doesn’t work on my systems yet, because I have Jinja 2.7.1, which was released on 7-Aug-2013. I will keep an eye on Jinja releases, and update my module and playbook when the equalto test becomes available.

Regards,

Anand

---

<div class="post-metadata">

**Author:** ![Anand\_Buddhdev2](https://avatars.discourse-cdn.com/v4/letter/a/48db29/32.png) [@Anand\_Buddhdev2](https://forum.ansible.com/u/Anand_Buddhdev2)\
**Post date:** [January 2, 2014, 9:23am UTC](https://forum.ansible.com/t/extract-ipv6-link-local-address-from-facts/14231/9 "2014-01-02T09:23:46Z")

</div>

Hi again Kahlil,

I branched my ansible setup, and patched jinja2 with the commit from github to add the “equalto” test.

> So I think the following might work:
> 
> {{ … | selectattr(‘scope’, ‘equalto’, ‘local’) | … }}

So in my playbook I wrote:

debug: msg=‘{{ ansible\_em1.ipv6 | selectattr(“scope”, “equalto”, “link”) | first | attr(“address”) }}’

But now I get the error message:

TASK: [debug msg=‘{{ansible\_em1.ipv6 | selectattr(“scope”, “equalto”, “link”) | first | attr(“address”)}}’] \*\*\*

fatal: [[ns1.ams.authdns.ripe.net](http://ns1.ams.authdns.ripe.net)] =\> One or more undefined variables: ‘dict object’ has no attribute ‘address’

This is getting weirder!

---

<div class="post-metadata">

**Author:** ![kahlil.hodgson](https://avatars.discourse-cdn.com/v4/letter/k/b9bd4f/32.png) [@kahlil.hodgson](https://forum.ansible.com/u/kahlil.hodgson)\
**Post date:** [January 2, 2014, 11:13pm UTC](https://forum.ansible.com/t/extract-ipv6-link-local-address-from-facts/14231/10 "2014-01-02T23:13:33Z")

</div>

Hi Anand,

Fun though it may be, I hope we are not getting too off-topic by  
discussing new and obscure jinja2 features on the ansible list 🙂

I currently don't have things set up to test this, so I'm just making  
guesses based on the documentation and eye-balling the code.

My next thought is to see what we are passing to the last link in the  
filter chain with

{{ansible\_em1.ipv6 | selectattr("scope", "equalto", "link") | first | pprint }}

K

Kahlil (Kal) Hodgson GPG: C9A02289  
Head of Technology (m) +61 (0) 4 2573 0382  
DealMax Pty Ltd (w) +61 (0) 3 9008 5281

Suite 1415  
401 Docklands Drive  
Docklands VIC 3008 Australia

"All parts should go together without forcing. You must remember that  
the parts you are reassembling were disassembled by you. Therefore,  
if you can't get them together again, there must be a reason. By all  
means, do not use a hammer." -- IBM maintenance manual, 1925

---

<div class="post-metadata">

**Author:** ![Anand\_Buddhdev2](https://avatars.discourse-cdn.com/v4/letter/a/48db29/32.png) [@Anand\_Buddhdev2](https://forum.ansible.com/u/Anand_Buddhdev2)\
**Post date:** [January 2, 2014, 11:28pm UTC](https://forum.ansible.com/t/extract-ipv6-link-local-address-from-facts/14231/11 "2014-01-02T23:28:28Z")

</div>

> Hi Anand,
> 
> Fun though it may be, I hope we are not getting too off-topic by  
> discussing new and obscure jinja2 features on the ansible list 🙂

I hope so too, but no-one has told us to shut up, so maybe they also want to use about this feature.

> I currently don’t have things set up to test this, so I’m just making  
> guesses based on the documentation and eye-balling the code.
> 
> My next thought is to see what we are passing to the last link in the  
> filter chain with
> 
> {{ansible\_em1.ipv6 | selectattr(“scope”, “equalto”, “link”) | first | pprint }}

This gives me:

TASK: [debug msg=‘{{ansible\_em1.ipv6 | selectattr(“scope”, “equalto”, “link”) | first | pprint}}’] \*\*\*

ok: [[ns1.ams.authdns.ripe.net](http://ns1.ams.authdns.ripe.net)] =\> {

“msg”: “{uaddress: ufe80::baca:3aff:feee:daf3, uprefix: u64, uscope: ulink}”

}

So it _looks_ like a dictionary with an attribute called “address”. But then using attr() fails.
