1
0
Fork 0
mirror of https://github.com/containers/ansible-podman-collections.git synced 2026-02-04 07:11:49 +00:00

Add multiple subnets for networks (#762)

Improve idempotency.
Signed-off-by: Sagi Shnaidman <sshnaidm@redhat.com>
This commit is contained in:
Sergey 2024-05-28 18:36:52 +03:00 committed by GitHub
parent 2887be7289
commit 9142efd82a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 308 additions and 34 deletions

View file

@ -80,6 +80,7 @@ options:
description:
- Enable IPv6 (Dual Stack) networking. You must pass a IPv6 subnet.
The subnet option must be used with the ipv6 option.
Idempotency is not supported because it generates subnets randomly.
type: bool
route:
description:
@ -95,6 +96,29 @@ options:
description:
- Create a Macvlan connection based on this device
type: str
net_config:
description:
- List of dictionaries with network configuration.
Each dictionary should contain 'subnet' and 'gateway' keys.
'ip_range' is optional.
type: list
elements: dict
suboptions:
subnet:
description:
- Subnet in CIDR format
type: str
required: true
gateway:
description:
- Gateway for the subnet
type: str
required: true
ip_range:
description:
- Allocate container IP from range
type: str
required: false
opt:
description:
- Add network options. Currently 'vlan' and 'mtu' are supported.
@ -338,6 +362,13 @@ class PodmanNetworkModuleParams:
def addparam_macvlan(self, c):
return c + ['--macvlan', self.params['macvlan']]
def addparam_net_config(self, c):
for net in self.params['net_config']:
for kw in ('subnet', 'gateway', 'ip_range'):
if kw in net and net[kw]:
c += ['--%s=%s' % (kw.replace('_', '-'), net[kw])]
return c
def addparam_interface_name(self, c):
return c + ['--interface-name', self.params['interface_name']]
@ -371,7 +402,6 @@ class PodmanNetworkDefaults:
self.defaults = {
'driver': 'bridge',
'internal': False,
'ipv6': False
}
def default_dict(self):
@ -430,26 +460,34 @@ class PodmanNetworkDiff:
return self._diff_update_and_compare('driver', before, after)
def diffparam_ipv6(self):
if LooseVersion(self.version) >= LooseVersion('4.0.0'):
before = self.info.get('ipv6_enabled', False)
after = self.params['ipv6']
return self._diff_update_and_compare('ipv6', before, after)
before = after = ''
return self._diff_update_and_compare('ipv6', before, after)
# We don't support dual stack because it generates subnets randomly
return self._diff_update_and_compare('ipv6', '', '')
def diffparam_gateway(self):
# Disable idempotency of subnet for v4, subnets are added automatically
# TODO(sshnaidm): check if it's still the issue in v5
if LooseVersion(self.version) >= LooseVersion('4.0.0'):
return self._diff_update_and_compare('gateway', '', '')
try:
before = self.info['plugins'][0]['ipam']['ranges'][0][0]['gateway']
except (IndexError, KeyError):
before = ''
after = before
if self.params['gateway'] is not None:
if LooseVersion(self.version) < LooseVersion('4.0.0'):
try:
before = self.info['plugins'][0]['ipam']['ranges'][0][0]['gateway']
except (IndexError, KeyError):
before = ''
after = before
if self.params['gateway'] is not None:
after = self.params['gateway']
return self._diff_update_and_compare('gateway', before, after)
else:
before_subs = self.info.get('subnets')
after = self.params['gateway']
return self._diff_update_and_compare('gateway', before, after)
if not before_subs:
before = None
if before_subs:
if len(before_subs) > 1 and after:
return self._diff_update_and_compare(
'gateway', ",".join([i['gateway'] for i in before_subs]), after)
before = [i.get('gateway') for i in before_subs][0]
if not after:
after = before
return self._diff_update_and_compare('gateway', before, after)
def diffparam_internal(self):
if LooseVersion(self.version) >= LooseVersion('4.0.0'):
@ -475,6 +513,18 @@ class PodmanNetworkDiff:
after = before
return self._diff_update_and_compare('ipam_driver', before, after)
def diffparam_net_config(self):
after = self.params['net_config']
if not after:
return self._diff_update_and_compare('net_config', '', '')
before_subs = self.info.get('subnets', [])
if before_subs:
before = ":".join(sorted([",".join([i['subnet'], i['gateway']]).rstrip(",") for i in before_subs]))
else:
before = ''
after = ":".join(sorted([",".join([i['subnet'], i['gateway']]).rstrip(",") for i in after]))
return self._diff_update_and_compare('net_config', before, after)
def diffparam_route(self):
routes = self.info.get('routes', [])
if routes:
@ -486,20 +536,32 @@ class PodmanNetworkDiff:
return self._diff_update_and_compare('route', sorted(before), sorted(after))
def diffparam_subnet(self):
# Disable idempotency of subnet for v4, subnets are added automatically
# TODO(sshnaidm): check if it's still the issue in v5
if LooseVersion(self.version) >= LooseVersion('4.0.0'):
return self._diff_update_and_compare('subnet', '', '')
try:
before = self.info['plugins'][0]['ipam']['ranges'][0][0]['subnet']
except (IndexError, KeyError):
before = ''
after = before
if self.params['subnet'] is not None:
# Disable idempotency of subnet for v3 and below
if LooseVersion(self.version) < LooseVersion('4.0.0'):
try:
before = self.info['plugins'][0]['ipam']['ranges'][0][0]['subnet']
except (IndexError, KeyError):
before = ''
after = before
if self.params['subnet'] is not None:
after = self.params['subnet']
if HAS_IP_ADDRESS_MODULE:
after = ipaddress.ip_network(after).compressed
return self._diff_update_and_compare('subnet', before, after)
else:
if self.params['ipv6'] is not None:
# We can't support dual stack, it generates subnets randomly
return self._diff_update_and_compare('subnet', '', '')
after = self.params['subnet']
if HAS_IP_ADDRESS_MODULE:
after = ipaddress.ip_network(after).compressed
return self._diff_update_and_compare('subnet', before, after)
if after is None:
# We can't guess what subnet was used before by default
return self._diff_update_and_compare('subnet', '', '')
before = self.info.get('subnets')
if before:
if len(before) > 1 and after:
return self._diff_update_and_compare('subnet', ",".join([i['subnet'] for i in before]), after)
before = [i['subnet'] for i in before][0]
return self._diff_update_and_compare('subnet', before, after)
def diffparam_macvlan(self):
before = after = ''
@ -778,11 +840,19 @@ def main():
quadlet_dir=dict(type='path', required=False),
quadlet_filename=dict(type='str', required=False),
quadlet_options=dict(type='list', elements='str', required=False),
net_config=dict(type='list', required=False, elements='dict',
options=dict(
subnet=dict(type='str', required=True),
gateway=dict(type='str', required=True),
ip_range=dict(type='str', required=False),
)),
),
required_by=dict( # for IP range and GW to set 'subnet' is required
ip_range=('subnet'),
gateway=('subnet'),
))
),
# define or subnet or net config
mutually_exclusive=[['subnet', 'net_config']])
PodmanNetworkManager(module).execute()

View file

@ -328,20 +328,20 @@
that:
- info16 is not changed
- name: Create network with IPv6 'exploded'
- name: Create network with IPv6 'exploded' - dual stack
containers.podman.podman_network:
executable: "{{ test_executable | default('podman') }}"
name: "{{ network_name }}"
ipv6: true
subnet: fd4f:552c:830f:0000::/64
subnet: fd4f:552c:830f::/64
state: present
- name: Create network with IPv6 'exploded' again
- name: Create network with IPv6 'exploded' - dual stack again
containers.podman.podman_network:
executable: "{{ test_executable | default('podman') }}"
name: "{{ network_name }}"
ipv6: true
subnet: fd4f:552c:830f:0000::/64
subnet: fd4f:552c:830f::/64
state: present
register: info17
@ -498,6 +498,210 @@
name: "{{ network_name }}"
state: absent
- name: Create a network with multiple subnets
containers.podman.podman_network:
executable: "{{ test_executable | default('podman') }}"
name: "{{ network_name }}"
net_config:
- subnet: 10.44.44.0/24
gateway: 10.44.44.44
ip_range: 10.44.44.128/30
- subnet: 10.22.22.0/24
gateway: 10.22.22.244
- subnet: 10.11.1.0/24
gateway: 10.11.1.33
- name: Create a network with multiple subnets again
containers.podman.podman_network:
executable: "{{ test_executable | default('podman') }}"
name: "{{ network_name }}"
net_config:
- subnet: 10.44.44.0/24
gateway: 10.44.44.44
ip_range: 10.44.44.128/30
- subnet: 10.22.22.0/24
gateway: 10.22.22.244
- subnet: 10.11.1.0/24
gateway: 10.11.1.33
register: net2conf
- name: Check output - Create a network with multiple subnets again
assert:
that:
- net2conf is not changed
- name: Create a network with multiple subnets - different
containers.podman.podman_network:
executable: "{{ test_executable | default('podman') }}"
name: "{{ network_name }}"
net_config:
- subnet: 10.44.44.0/24
gateway: 10.44.44.44
ip_range: 10.44.44.128/30
- subnet: 10.11.12.0/24
gateway: 10.11.12.33
register: net2conf1
- name: Check output - Create a network with multiple subnets - different
assert:
that:
- net2conf1 is changed
- name: Create a network with multiple subnets - different gateway
containers.podman.podman_network:
executable: "{{ test_executable | default('podman') }}"
name: "{{ network_name }}"
net_config:
- subnet: 10.44.44.0/24
gateway: 10.44.44.41
ip_range: 10.44.44.128/30
- subnet: 10.11.12.0/24
gateway: 10.11.12.33
register: net2conf2
- name: Check output - Create a network with multiple subnets - different gateway
assert:
that:
- net2conf2 is changed
- name: Create a network with multiple subnets again - same
containers.podman.podman_network:
executable: "{{ test_executable | default('podman') }}"
name: "{{ network_name }}"
net_config:
- subnet: 10.44.44.0/24
gateway: 10.44.44.41
ip_range: 10.44.44.128/30
- subnet: 10.11.12.0/24
gateway: 10.11.12.33
register: net2conf3
- name: Check output - Create a network with multiple subnets again - same
assert:
that:
- net2conf3 is not changed
- name: Create a network with single subnet
containers.podman.podman_network:
executable: "{{ test_executable | default('podman') }}"
name: "{{ network_name }}"
subnet: 10.44.44.0/24
gateway: 10.44.44.41
register: net2conf4
- name: Check output - Create a network with single subnet
assert:
that:
- net2conf4 is changed
- name: Create a network with single subnet - again
containers.podman.podman_network:
executable: "{{ test_executable | default('podman') }}"
name: "{{ network_name }}"
subnet: 10.44.44.0/24
gateway: 10.44.44.41
register: net2conf5
- name: Check output - Create a network with single subnet - again
assert:
that:
- net2conf5 is not changed
- name: Create a network with single subnet and changed gateway
containers.podman.podman_network:
executable: "{{ test_executable | default('podman') }}"
name: "{{ network_name }}"
subnet: 10.44.44.0/24
gateway: 10.44.44.42
register: net2conf6
- name: Check output - Create a network with single subnet and changed gateway
assert:
that:
- net2conf6 is changed
- name: Create a network with single subnet - without gateway
containers.podman.podman_network:
executable: "{{ test_executable | default('podman') }}"
name: "{{ network_name }}"
subnet: 10.44.44.0/24
register: net2conf7
- name: Check output - Create a network with single subnet - without gateway
assert:
that:
- net2conf7 is not changed
- name: Create a network with multiple subnets
containers.podman.podman_network:
executable: "{{ test_executable | default('podman') }}"
name: "{{ network_name }}"
net_config:
- subnet: 10.44.44.0/24
gateway: 10.44.44.44
ip_range: 10.44.44.128/30
- subnet: 10.22.22.0/24
gateway: 10.22.22.244
- subnet: 10.17.1.0/24
gateway: 10.17.1.33
- name: Create a network with multiple subnets again
containers.podman.podman_network:
executable: "{{ test_executable | default('podman') }}"
name: "{{ network_name }}"
net_config:
- subnet: 10.44.44.0/24
gateway: 10.44.44.44
ip_range: 10.44.44.128/30
- subnet: 10.22.22.0/24
gateway: 10.22.22.244
- subnet: 10.17.1.0/24
gateway: 10.17.1.33
register: net2conf
- name: Check output - Create a network with multiple subnets again
assert:
that:
- net2conf is not changed
- name: Create a IPv6 network with multiple subnets
containers.podman.podman_network:
executable: "{{ test_executable | default('podman') }}"
name: "{{ network_name }}"
net_config:
- subnet: 2002:db8:1::/64
gateway: 2002:db8:1::12
ip_range: 2002:db8:1::128/68
- subnet: 2004:db9:1::/64
gateway: 2004:db9:1::15
- subnet: 10.15.11.0/24
gateway: 10.15.11.124
register: net6conf
- name: Check output - Create a network with multiple subnets again
assert:
that:
- net6conf is changed
- name: Create a IPv6 network with multiple subnets again
containers.podman.podman_network:
executable: "{{ test_executable | default('podman') }}"
name: "{{ network_name }}"
net_config:
- subnet: 2002:db8:1::/64
gateway: 2002:db8:1::12
ip_range: 2002:db8:1::128/68
- subnet: 2004:db9:1::/64
gateway: 2004:db9:1::15
- subnet: 10.15.11.0/24
gateway: 10.15.11.124
register: net6conf1
- name: Check output - Create a network with multiple subnets again
assert:
that:
- net6conf1 is not changed
- name: Create a Quadlet for network with filename
containers.podman.podman_network:
executable: "{{ test_executable | default('podman') }}"