fix vyos_l3_interface adding multiple addresses to interface (#36377)
* fix vyos_l3_interface adding multiple addresses to interface Signed-off-by: Trishna Guha <trishnaguha17@gmail.com> * add test Signed-off-by: Trishna Guha <trishnaguha17@gmail.com>
This commit is contained in:
parent
66c38dd6c3
commit
3d06ce245a
2 changed files with 57 additions and 22 deletions
|
@ -88,14 +88,39 @@ commands:
|
||||||
sample:
|
sample:
|
||||||
- set interfaces ethernet eth0 address '192.168.0.1/24'
|
- set interfaces ethernet eth0 address '192.168.0.1/24'
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
import socket
|
||||||
|
import re
|
||||||
|
|
||||||
from copy import deepcopy
|
from copy import deepcopy
|
||||||
|
|
||||||
from ansible.module_utils.basic import AnsibleModule
|
from ansible.module_utils.basic import AnsibleModule
|
||||||
|
from ansible.module_utils.network.common.utils import is_masklen, validate_ip_address
|
||||||
from ansible.module_utils.network.common.utils import remove_default_spec
|
from ansible.module_utils.network.common.utils import remove_default_spec
|
||||||
from ansible.module_utils.network.vyos.vyos import load_config, run_commands
|
from ansible.module_utils.network.vyos.vyos import load_config, run_commands
|
||||||
from ansible.module_utils.network.vyos.vyos import vyos_argument_spec
|
from ansible.module_utils.network.vyos.vyos import vyos_argument_spec
|
||||||
|
|
||||||
|
|
||||||
|
def is_ipv4(value):
|
||||||
|
if value:
|
||||||
|
address = value.split('/')
|
||||||
|
if is_masklen(address[1]) and validate_ip_address(address[0]):
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def is_ipv6(value):
|
||||||
|
if value:
|
||||||
|
address = value.split('/')
|
||||||
|
if 0 <= int(address[1]) <= 128:
|
||||||
|
try:
|
||||||
|
socket.inet_pton(socket.AF_INET6, address[0])
|
||||||
|
except socket.error:
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
def search_obj_in_list(name, lst):
|
def search_obj_in_list(name, lst):
|
||||||
for o in lst:
|
for o in lst:
|
||||||
if o['name'] == name:
|
if o['name'] == name:
|
||||||
|
@ -115,6 +140,7 @@ def map_obj_to_commands(updates, module):
|
||||||
state = w['state']
|
state = w['state']
|
||||||
|
|
||||||
obj_in_have = search_obj_in_list(name, have)
|
obj_in_have = search_obj_in_list(name, have)
|
||||||
|
|
||||||
if state == 'absent' and obj_in_have:
|
if state == 'absent' and obj_in_have:
|
||||||
if not ipv4 and not ipv6 and (obj_in_have['ipv4'] or obj_in_have['ipv6']):
|
if not ipv4 and not ipv6 and (obj_in_have['ipv4'] or obj_in_have['ipv6']):
|
||||||
if name == "lo":
|
if name == "lo":
|
||||||
|
@ -122,24 +148,24 @@ def map_obj_to_commands(updates, module):
|
||||||
else:
|
else:
|
||||||
commands.append('delete interfaces ethernet ' + name + ' address')
|
commands.append('delete interfaces ethernet ' + name + ' address')
|
||||||
else:
|
else:
|
||||||
if ipv4 and obj_in_have['ipv4']:
|
if ipv4 and ipv4 in obj_in_have['ipv4']:
|
||||||
if name == "lo":
|
if name == "lo":
|
||||||
commands.append('delete interfaces loopback lo address ' + ipv4)
|
commands.append('delete interfaces loopback lo address ' + ipv4)
|
||||||
else:
|
else:
|
||||||
commands.append('delete interfaces ethernet ' + name + ' address ' + ipv4)
|
commands.append('delete interfaces ethernet ' + name + ' address ' + ipv4)
|
||||||
if ipv6 and obj_in_have['ipv6']:
|
if ipv6 and ipv6 in obj_in_have['ipv6']:
|
||||||
if name == "lo":
|
if name == "lo":
|
||||||
commands.append('delete interfaces loopback lo address ' + ipv6)
|
commands.append('delete interfaces loopback lo address ' + ipv6)
|
||||||
else:
|
else:
|
||||||
commands.append('delete interfaces ethernet ' + name + ' address ' + ipv6)
|
commands.append('delete interfaces ethernet ' + name + ' address ' + ipv6)
|
||||||
elif (state == 'present' and obj_in_have):
|
elif (state == 'present' and obj_in_have):
|
||||||
if ipv4 and ipv4 != obj_in_have['ipv4']:
|
if ipv4 and ipv4 not in obj_in_have['ipv4']:
|
||||||
if name == "lo":
|
if name == "lo":
|
||||||
commands.append('set interfaces loopback lo address ' + ipv4)
|
commands.append('set interfaces loopback lo address ' + ipv4)
|
||||||
else:
|
else:
|
||||||
commands.append('set interfaces ethernet ' + name + ' address ' + ipv4)
|
commands.append('set interfaces ethernet ' + name + ' address ' + ipv4)
|
||||||
|
|
||||||
if ipv6 and ipv6 != obj_in_have['ipv6']:
|
if ipv6 and ipv6 not in obj_in_have['ipv6']:
|
||||||
if name == "lo":
|
if name == "lo":
|
||||||
commands.append('set interfaces loopback lo address ' + ipv6)
|
commands.append('set interfaces loopback lo address ' + ipv6)
|
||||||
else:
|
else:
|
||||||
|
@ -151,29 +177,32 @@ def map_obj_to_commands(updates, module):
|
||||||
def map_config_to_obj(module):
|
def map_config_to_obj(module):
|
||||||
obj = []
|
obj = []
|
||||||
output = run_commands(module, ['show interfaces'])
|
output = run_commands(module, ['show interfaces'])
|
||||||
lines = output[0].splitlines()
|
lines = re.split(r'\n[e|l]', output[0])[1:]
|
||||||
|
|
||||||
if len(lines) > 3:
|
if len(lines) > 0:
|
||||||
for line in lines[3:]:
|
for line in lines:
|
||||||
splitted_line = line.split()
|
splitted_line = line.split()
|
||||||
|
|
||||||
if len(splitted_line) > 1:
|
if len(splitted_line) > 0:
|
||||||
name = splitted_line[0]
|
ipv4 = []
|
||||||
address = splitted_line[1]
|
ipv6 = []
|
||||||
|
|
||||||
if address == '-':
|
if splitted_line[0].lower().startswith('th'):
|
||||||
address = None
|
name = 'e' + splitted_line[0].lower()
|
||||||
|
elif splitted_line[0].lower().startswith('o'):
|
||||||
|
name = 'l' + splitted_line[0].lower()
|
||||||
|
|
||||||
|
for i in splitted_line[1:]:
|
||||||
|
if (('.' in i or ':' in i) and '/' in i):
|
||||||
|
value = i.split(r'\n')[0]
|
||||||
|
if is_ipv4(value):
|
||||||
|
ipv4.append(value)
|
||||||
|
elif is_ipv6(value):
|
||||||
|
ipv6.append(value)
|
||||||
|
|
||||||
if address is not None and ':' not in address:
|
|
||||||
obj.append({'name': name,
|
obj.append({'name': name,
|
||||||
'ipv4': address,
|
'ipv4': ipv4,
|
||||||
'ipv6': None})
|
'ipv6': ipv6})
|
||||||
else:
|
|
||||||
obj.append({'name': name,
|
|
||||||
'ipv6': address,
|
|
||||||
'ipv4': None})
|
|
||||||
else:
|
|
||||||
obj[-1]['ipv6'] = splitted_line[0]
|
|
||||||
|
|
||||||
return obj
|
return obj
|
||||||
|
|
||||||
|
|
|
@ -149,6 +149,7 @@
|
||||||
aggregate:
|
aggregate:
|
||||||
- { name: eth1, ipv4: 192.168.2.10/24 }
|
- { name: eth1, ipv4: 192.168.2.10/24 }
|
||||||
- { name: eth2, ipv4: 192.168.3.10/24, ipv6: "fd5d:12c9:2201:1::1/64" }
|
- { name: eth2, ipv4: 192.168.3.10/24, ipv6: "fd5d:12c9:2201:1::1/64" }
|
||||||
|
- { name: eth2, ipv4: 192.168.4.10/24 }
|
||||||
register: result
|
register: result
|
||||||
|
|
||||||
- assert:
|
- assert:
|
||||||
|
@ -157,12 +158,14 @@
|
||||||
- '"set interfaces ethernet eth1 address 192.168.2.10/24" in result.commands'
|
- '"set interfaces ethernet eth1 address 192.168.2.10/24" in result.commands'
|
||||||
- '"set interfaces ethernet eth2 address 192.168.3.10/24" in result.commands'
|
- '"set interfaces ethernet eth2 address 192.168.3.10/24" in result.commands'
|
||||||
- '"set interfaces ethernet eth2 address fd5d:12c9:2201:1::1/64" in result.commands'
|
- '"set interfaces ethernet eth2 address fd5d:12c9:2201:1::1/64" in result.commands'
|
||||||
|
- '"set interfaces ethernet eth2 address 192.168.4.10/24" in result.commands'
|
||||||
|
|
||||||
- name: Set IP addresses on aggregate (idempotent)
|
- name: Set IP addresses on aggregate (idempotent)
|
||||||
vyos_l3_interface:
|
vyos_l3_interface:
|
||||||
aggregate:
|
aggregate:
|
||||||
- { name: eth1, ipv4: 192.168.2.10/24 }
|
- { name: eth1, ipv4: 192.168.2.10/24 }
|
||||||
- { name: eth2, ipv4: 192.168.3.10/24, ipv6: "fd5d:12c9:2201:1::1/64" }
|
- { name: eth2, ipv4: 192.168.3.10/24, ipv6: "fd5d:12c9:2201:1::1/64" }
|
||||||
|
- { name: eth2, ipv4: 192.168.4.10/24 }
|
||||||
register: result
|
register: result
|
||||||
|
|
||||||
- assert:
|
- assert:
|
||||||
|
@ -174,6 +177,7 @@
|
||||||
aggregate:
|
aggregate:
|
||||||
- { name: eth1, ipv4: 192.168.2.10/24 }
|
- { name: eth1, ipv4: 192.168.2.10/24 }
|
||||||
- { name: eth2, ipv4: 192.168.3.10/24, ipv6: "fd5d:12c9:2201:1::1/64" }
|
- { name: eth2, ipv4: 192.168.3.10/24, ipv6: "fd5d:12c9:2201:1::1/64" }
|
||||||
|
- { name: eth2, ipv4: 192.168.4.10/24 }
|
||||||
state: absent
|
state: absent
|
||||||
register: result
|
register: result
|
||||||
|
|
||||||
|
@ -183,12 +187,14 @@
|
||||||
- '"delete interfaces ethernet eth1 address 192.168.2.10/24" in result.commands'
|
- '"delete interfaces ethernet eth1 address 192.168.2.10/24" in result.commands'
|
||||||
- '"delete interfaces ethernet eth2 address 192.168.3.10/24" in result.commands'
|
- '"delete interfaces ethernet eth2 address 192.168.3.10/24" in result.commands'
|
||||||
- '"delete interfaces ethernet eth2 address fd5d:12c9:2201:1::1/64" in result.commands'
|
- '"delete interfaces ethernet eth2 address fd5d:12c9:2201:1::1/64" in result.commands'
|
||||||
|
- '"delete interfaces ethernet eth2 address 192.168.4.10/24" in result.commands'
|
||||||
|
|
||||||
- name: Remove IP addresses on aggregate (idempotent)
|
- name: Remove IP addresses on aggregate (idempotent)
|
||||||
vyos_l3_interface:
|
vyos_l3_interface:
|
||||||
aggregate:
|
aggregate:
|
||||||
- { name: eth1, ipv4: 192.168.2.10/24 }
|
- { name: eth1, ipv4: 192.168.2.10/24 }
|
||||||
- { name: eth2, ipv4: 192.168.3.10/24, ipv6: "fd5d:12c9:2201:1::1/64" }
|
- { name: eth2, ipv4: 192.168.3.10/24, ipv6: "fd5d:12c9:2201:1::1/64" }
|
||||||
|
- { name: eth2, ipv4: 192.168.4.10/24 }
|
||||||
state: absent
|
state: absent
|
||||||
register: result
|
register: result
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue