3

I have a string with IP addr: 192.168.10.2

I want to extract first three octets of the IP in Ansible and I tried to use this regex.

{{comp_ip | regex_replace("^[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}"), "//1"}}

This does not yield any result. Can someone correct me where I went wrong?

techraf
  • 64,883
  • 27
  • 193
  • 198
spamulap12
  • 97
  • 1
  • 9

3 Answers3

12

If already have dot-separated IP-address, there is a simple way:

{{ comp_ip.split('.')[0:3] | join('.') }}
Konstantin Suvorov
  • 65,183
  • 9
  • 162
  • 193
  • this is a cool trick and clear. So in general can we use any python methods through pipe in ansible? – spamulap12 Nov 29 '16 at 17:26
  • No, pipes are for filters, see my [other](http://stackoverflow.com/a/39794185/2795592) answer for details. But you can use python methods of strings and dicts with dot-notation. – Konstantin Suvorov Nov 29 '16 at 17:54
2

You are doing it right, you just have to use parenthesis in Regex to make a group. It is better to match the whole ip and end your regex with $, and also change //1 to \\1 in your code.

Change regex from:

^[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}

To this regex:

^([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3})\.[0-9]{1,3}$

This is the full code:

{{comp_ip | regex_replace('^([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3})\.[0-9]{1,3}$', '\\1')}}
Ibrahim
  • 6,006
  • 3
  • 39
  • 50
  • thanks, but it has some issue with syntax I bileve. The offending line appears to be: set_fact: net: {{comp_ip | regex_replace('^([0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3})'), '\\1'}} ^ here – spamulap12 Nov 29 '16 at 01:30
  • No syntax error with this, but o/p has nothing in it {"net": "(u'', '\\\\1')"} – spamulap12 Nov 29 '16 at 01:42
  • @spamulap12 Try the updated full code, I made a small change. By the way, does the input has only `ip`? or does it have something before, and after the `ip`? – Ibrahim Nov 29 '16 at 02:02
  • This is the full ansible code I am trying with `code` - name: COMP IP set_fact: comp_ip: "192.168.10.2" - name: Extract net set_fact: net: "{{comp_ip | regex_replace('^[\s\S]*?([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3})[\s\S]*$'), '\\1'}}" I get the syntax error like before :( – spamulap12 Nov 29 '16 at 02:09
  • The full code has a typo, the closing bracket of regex_replace should be after the \\1 `{{comp_ip | regex_replace('^([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3})\.[0-9]{1,3}$', '\\1')}}` – spamulap12 Nov 29 '16 at 03:20
  • @spamulap12 Yes, you're right, how did we miss that. – Ibrahim Nov 29 '16 at 03:23
  • @spamulap12 my pleasure. – Ibrahim Nov 29 '16 at 03:24
1

In case you want to calculate your network address you can use Ansible ipaddr filter which provides exactly this functionality: http://docs.ansible.com/ansible/latest/playbooks_filters_ipaddr.html

---
- hosts: localhost
  vars:
    my_ip: "{{ ansible_default_ipv4.network }}/{{ ansible_default_ipv4.netmask }}"
  tasks:
    - debug: msg="network {{ my_ip | ipaddr('network') }}"
    - debug: msg="netmask {{ my_ip | ipaddr('netmask') }}"
panticz
  • 2,135
  • 25
  • 16