Skip to content

Commit

Permalink
Merge pull request #54197 from cbosdo/virt-net-nat
Browse files Browse the repository at this point in the history
Extend `virt.network_define` to create NAT networks
  • Loading branch information
dwoz authored Jan 2, 2020
2 parents caec765 + 9071f76 commit 4ec6117
Show file tree
Hide file tree
Showing 5 changed files with 146 additions and 4 deletions.
47 changes: 44 additions & 3 deletions salt/modules/virt.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@
from salt.exceptions import CommandExecutionError, SaltInvocationError
from salt.ext import six
from salt.ext.six.moves import range # pylint: disable=import-error,redefined-builtin
from salt._compat import ipaddress

log = logging.getLogger(__name__)

Expand Down Expand Up @@ -663,7 +664,8 @@ def _gen_net_xml(name,
bridge,
forward,
vport,
tag=None):
tag=None,
ip_configs=None):
'''
Generate the XML string to define a libvirt network
'''
Expand All @@ -673,6 +675,10 @@ def _gen_net_xml(name,
'forward': forward,
'vport': vport,
'tag': tag,
'ip_configs': [{
'address': ipaddress.ip_network(config['cidr']),
'dhcp_ranges': config.get('dhcp_ranges', []),
} for config in ip_configs or []],
}
fn_ = 'libvirt_network.jinja'
try:
Expand Down Expand Up @@ -4402,7 +4408,12 @@ def cpu_baseline(full=False, migratable=False, out='libvirt', **kwargs):
return cpu.toxml()


def network_define(name, bridge, forward, **kwargs):
def network_define(name,
bridge,
forward,
ipv4_config=None,
ipv6_config=None,
**kwargs):
'''
Create libvirt network.
Expand All @@ -4413,10 +4424,38 @@ def network_define(name, bridge, forward, **kwargs):
:param tag: Vlan tag
:param autostart: Network autostart (default True)
:param start: Network start (default True)
:param ipv4_config: IP v4 configuration
Dictionary describing the IP v4 setup like IP range and
a possible DHCP configuration. The structure is documented
in net-define-ip_.
..versionadded:: Neon
:type ipv4_config: dict or None
:param ipv6_config: IP v6 configuration
Dictionary describing the IP v6 setup like IP range and
a possible DHCP configuration. The structure is documented
in net-define-ip_.
..versionadded:: Neon
:type ipv6_config: dict or None
:param connection: libvirt connection URI, overriding defaults
:param username: username to connect with, overriding defaults
:param password: password to connect with, overriding defaults
.. _net-define-ip:
** IP configuration definition
Both the IPv4 and IPv6 configuration dictionaries can contain the following properties:
cidr
CIDR notation for the network. For example '192.168.124.0/24'
dhcp_ranges
A list of dictionary with ``'start'`` and ``'end'`` properties.
CLI Example:
.. code-block:: bash
Expand All @@ -4430,12 +4469,14 @@ def network_define(name, bridge, forward, **kwargs):
tag = kwargs.get('tag', None)
autostart = kwargs.get('autostart', True)
starting = kwargs.get('start', True)

net_xml = _gen_net_xml(
name,
bridge,
forward,
vport,
tag,
tag=tag,
ip_configs=[config for config in [ipv4_config, ipv6_config] if config],
)
try:
conn.networkDefineXML(net_xml)
Expand Down
38 changes: 38 additions & 0 deletions salt/states/virt.py
Original file line number Diff line number Diff line change
Expand Up @@ -658,13 +658,34 @@ def network_running(name,
forward,
vport=None,
tag=None,
ipv4_config=None,
ipv6_config=None,
autostart=True,
connection=None,
username=None,
password=None):
'''
Defines and starts a new network with specified arguments.
:param bridge: Bridge name
:param forward: Forward mode(bridge, router, nat)
:param vport: Virtualport type (Default: ``'None'``)
:param tag: Vlan tag (Default: ``'None'``)
:param ipv4_config:
IPv4 network configuration. See the :py:func`virt.network_define
<salt.modules.virt.network_define>` function corresponding parameter documentation
for more details on this dictionary.
(Default: None).
.. versionadded:: neon
:param ipv6_config:
IPv6 network configuration. See the :py:func`virt.network_define
<salt.modules.virt.network_define>` function corresponding parameter documentation
for more details on this dictionary.
(Default: None).
.. versionadded:: neon
:param autostart: Network autostart (default ``'True'``)
:param connection: libvirt connection URI, overriding defaults
.. versionadded:: 2019.2.0
Expand All @@ -690,6 +711,21 @@ def network_running(name,
- tag: 180
- autostart: True
.. code-block:: yaml
network_name:
virt.network_define:
- bridge: natted
- forward: nat
- ipv4_config:
cidr: 192.168.42.0/24
dhcp_ranges:
- start: 192.168.42.10
end: 192.168.42.25
- start: 192.168.42.100
end: 192.168.42.150
- autostart: True
'''
ret = {'name': name,
'changes': {},
Expand All @@ -712,6 +748,8 @@ def network_running(name,
forward,
vport=vport,
tag=tag,
ipv4_config=ipv4_config,
ipv6_config=ipv6_config,
autostart=autostart,
start=True,
connection=connection,
Expand Down
13 changes: 12 additions & 1 deletion salt/templates/virt/libvirt_network.jinja
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,15 @@
<vlan>
<tag id='{{ tag }}'/>
</vlan>{% endif %}
</network>
{% for ip_config in ip_configs %}
<ip family='ipv{{ ip_config.address.version }}'
address='{{ ip_config.address.network_address }}'
prefix='{{ ip_config.address.prefixlen }}'>
<dhcp>
{% for range in ip_config.dhcp_ranges %}
<range start='{{ range.start }}' end='{{ range.end }}' />
{% endfor %}
</dhcp>
</ip>
{% endfor %}
</network>
26 changes: 26 additions & 0 deletions tests/unit/modules/test_virt.py
Original file line number Diff line number Diff line change
Expand Up @@ -2016,6 +2016,32 @@ def test_network(self):
self.assertEqual(root.find('forward').attrib['mode'], 'bridge')
self.assertEqual(root.find('virtualport').attrib['type'], 'openvswitch')

def test_network_nat(self):
'''
Test virt._get_net_xml() in a nat setup
'''
xml_data = virt._gen_net_xml('network', 'main', 'nat', None, ip_configs=[
{
'cidr': '192.168.2.0/24',
'dhcp_ranges': [
{'start': '192.168.2.10', 'end': '192.168.2.25'},
{'start': '192.168.2.110', 'end': '192.168.2.125'},
]
}
])
root = ET.fromstring(xml_data)
self.assertEqual(root.find('name').text, 'network')
self.assertEqual(root.find('bridge').attrib['name'], 'main')
self.assertEqual(root.find('forward').attrib['mode'], 'nat')
self.assertEqual(root.find("./ip[@address='192.168.2.0']").attrib['prefix'], '24')
self.assertEqual(root.find("./ip[@address='192.168.2.0']").attrib['family'], 'ipv4')
self.assertEqual(
root.find("./ip[@address='192.168.2.0']/dhcp/range[@start='192.168.2.10']").attrib['end'],
'192.168.2.25')
self.assertEqual(
root.find("./ip[@address='192.168.2.0']/dhcp/range[@start='192.168.2.110']").attrib['end'],
'192.168.2.125')

def test_domain_capabilities(self):
'''
Test the virt.domain_capabilities parsing
Expand Down
26 changes: 26 additions & 0 deletions tests/unit/states/test_virt.py
Original file line number Diff line number Diff line change
Expand Up @@ -616,6 +616,19 @@ def test_network_running(self):
'bridge',
vport='openvswitch',
tag=180,
ipv4_config={
'cidr': '192.168.2.0/24',
'dhcp_ranges': [
{'start': '192.168.2.10', 'end': '192.168.2.25'},
{'start': '192.168.2.110', 'end': '192.168.2.125'},
]
},
ipv6_config={
'cidr': '2001:db8:ca2:2::1/64',
'dhcp_ranges': [
{'start': '2001:db8:ca2:1::10', 'end': '2001:db8:ca2::1f'},
]
},
autostart=False,
connection='myconnection',
username='user',
Expand All @@ -627,6 +640,19 @@ def test_network_running(self):
tag=180,
autostart=False,
start=True,
ipv4_config={
'cidr': '192.168.2.0/24',
'dhcp_ranges': [
{'start': '192.168.2.10', 'end': '192.168.2.25'},
{'start': '192.168.2.110', 'end': '192.168.2.125'},
]
},
ipv6_config={
'cidr': '2001:db8:ca2:2::1/64',
'dhcp_ranges': [
{'start': '2001:db8:ca2:1::10', 'end': '2001:db8:ca2::1f'},
]
},
connection='myconnection',
username='user',
password='secret')
Expand Down

0 comments on commit 4ec6117

Please sign in to comment.