diff --git a/networks/forms.py b/networks/forms.py index 5cbeac4..7c3b07d 100644 --- a/networks/forms.py +++ b/networks/forms.py @@ -6,10 +6,13 @@ from django.utils.translation import ugettext_lazy as _ class AddNetPool(forms.Form): name = forms.CharField(error_messages={'required': _('No pool name has been entered')}, max_length=20) - subnet = forms.CharField(error_messages={'required': _('No subnet has been entered')}, + subnet = forms.CharField(error_messages={'required': _('No IPv4 subnet has been entered')}, max_length=20, required=False) + subnet6 = forms.CharField(error_messages={'required': _('No IPv6 subnet has been entered')}, + max_length=42, required=False) forward = forms.CharField(max_length=100) dhcp4 = forms.BooleanField(required=False) + dhcp6 = forms.BooleanField(required=False) fixed = forms.BooleanField(required=False) bridge_name = forms.CharField(max_length=20, required=False) openvswitch = forms.BooleanField(required=False) @@ -32,6 +35,15 @@ class AddNetPool(forms.Form): raise forms.ValidationError(_('The pool subnet must not exceed 20 characters')) return subnet + def clean_subnet6(self): + subnet = self.cleaned_data['subnet6'] + have_symbol = re.match('^[0-9a-fA-F:/]+$', subnet if subnet else ":") + if not have_symbol: + raise forms.ValidationError(_('The pool subnet must not contain any special characters')) + elif len(subnet) > 42: + raise forms.ValidationError(_('The pool subnet must not exceed 42 characters')) + return subnet + def clean_bridge_name(self): bridge_name = self.cleaned_data['bridge_name'] if self.cleaned_data['forward'] == 'bridge': diff --git a/networks/templates/create_net_block.html b/networks/templates/create_net_block.html index f9df47b..c40f0bd 100644 --- a/networks/templates/create_net_block.html +++ b/networks/templates/create_net_block.html @@ -20,10 +20,21 @@ -
- +
+
- + +
+
+
+ +
+
@@ -38,15 +49,22 @@
-
- +
+
- + +
+
+
+ +
+ +
+
+
+ +
+
diff --git a/networks/templates/modify_ipv6_fixed_address.html b/networks/templates/modify_ipv6_fixed_address.html index fcc7eff..0e31eb0 100644 --- a/networks/templates/modify_ipv6_fixed_address.html +++ b/networks/templates/modify_ipv6_fixed_address.html @@ -24,7 +24,7 @@
- +
@@ -36,7 +36,7 @@
- +
diff --git a/networks/templates/networks.html b/networks/templates/networks.html index ac6a3a8..3d9239f 100644 --- a/networks/templates/networks.html +++ b/networks/templates/networks.html @@ -41,7 +41,7 @@
- {% trans "Warning:" %} {% trans "Hypervisor doesn't have any Networks" %} + {% trans "Warning" %}: {% trans "Hypervisor doesn't have any network" %}
{% else %} @@ -54,8 +54,8 @@
-

{% trans "Device:" %}

-

{% trans "Forward:" %}

+

{% trans "Device" %}:

+

{% trans "Forward" %}:

{{ pool.device }}

@@ -81,6 +81,14 @@ $('.bridge_name_form_group_dhcp').show(); } }).change(); + + $('#enable_ipv6').change(function (eventObject) { + if ($(this).is(':checked')) { + $('.ipv6_group').show(); + } else { + $('.ipv6_group').hide(); + } + }).change(); }); {% endblock %} \ No newline at end of file diff --git a/networks/views.py b/networks/views.py index b71e75e..4d507b3 100644 --- a/networks/views.py +++ b/networks/views.py @@ -31,7 +31,9 @@ def networks(request, compute_id): compute.password, compute.type) networks = conn.get_networks_info() - dhcp4 = netmask = gateway = '' + dhcp4 = netmask4 = gateway4 = '' + dhcp6 = prefix6 = gateway6 = '' + ipv4 = ipv6 = False if request.method == 'POST': if 'create' in request.POST: @@ -39,15 +41,24 @@ def networks(request, compute_id): if form.is_valid(): data = form.cleaned_data if data['name'] in networks: - msg = _("Pool name already in use") + msg = _("Network pool name already in use") error_messages.append(msg) if data['forward'] == 'bridge' and data['bridge_name'] == '': error_messages.append('Please enter bridge name') if data['subnet']: - gateway, netmask, dhcp4 = network_size(data['subnet'], data['dhcp4']) + ipv4 = True + gateway4, netmask4, dhcp4 = network_size(data['subnet'], data['dhcp4']) + if data['subnet6']: + ipv6 = True + gateway6, prefix6, dhcp6 = network_size(data['subnet6'], data['dhcp6']) + if prefix6 != '64': + error_messages.append('For libvirt, the IPv6 network prefix must be /64') if not error_messages: - conn.create_network(data['name'], data['forward'], gateway, netmask, - dhcp4, data['bridge_name'], data['openvswitch'], data['fixed']) + conn.create_network(data['name'], + data['forward'], + ipv4, gateway4, netmask4, dhcp4, + ipv6, gateway6, prefix6, dhcp6, + data['bridge_name'], data['openvswitch'], data['fixed']) return HttpResponseRedirect(reverse('network', args=[compute_id, data['name']])) else: for msg_err in form.errors.values(): @@ -151,7 +162,7 @@ def network(request, compute_id, pool): try: ret_val = conn.modify_fixed_address(name, address, mac_duid, family) - messages.success(request, "{} Fixed Address Operation Completed.".format(family)) + messages.success(request, "{} Fixed Address Operation Completed.".format(family.upper())) return HttpResponseRedirect(request.get_full_path()) except libvirtError as lib_err: error_messages.append(lib_err.message) @@ -161,7 +172,7 @@ def network(request, compute_id, pool): ip = request.POST.get('address', '') family = request.POST.get('family', 'ipv4') conn.delete_fixed_address(ip, family) - messages.success(request, "{} Fixed Address is Deleted.".format(family)) + messages.success(request, "{} Fixed Address is Deleted.".format(family.upper())) return HttpResponseRedirect(request.get_full_path()) if 'modify_dhcp_range' in request.POST: range_start = request.POST.get('range_start', '') @@ -169,7 +180,7 @@ def network(request, compute_id, pool): family = request.POST.get('family', 'ipv4') try: conn.modify_dhcp_range(range_start, range_end, family) - messages.success(request, "{} DHCP Range is Changed.".format(family)) + messages.success(request, "{} DHCP Range is Changed.".format(family.upper())) return HttpResponseRedirect(request.get_full_path()) except libvirtError as lib_err: error_messages.append(lib_err.message) diff --git a/vrtManager/network.py b/vrtManager/network.py index d077c05..ebe54af 100644 --- a/vrtManager/network.py +++ b/vrtManager/network.py @@ -7,14 +7,18 @@ from libvirt import VIR_NETWORK_UPDATE_COMMAND_ADD_LAST, VIR_NETWORK_UPDATE_COMM from libvirt import VIR_NETWORK_UPDATE_AFFECT_LIVE, VIR_NETWORK_UPDATE_AFFECT_CONFIG -def network_size(net, dhcp=None): +def network_size(subnet, dhcp=None): """ Func return gateway, mask and dhcp pool. """ - mask = IP(net).strNetmask() - addr = IP(net) - gateway = addr[1].strNormal() - dhcp_pool = [addr[2].strNormal(), addr[addr.len() - 2].strNormal()] + mask = IP(subnet).strNetmask() + addr = IP(subnet) + gateway = addr[1].strCompressed() + if addr.version() == 4: + dhcp_pool = [addr[2].strCompressed(), addr[addr.len() - 2].strCompressed()] + if addr.version() == 6: + mask = mask.lstrip('/') if '/' in mask else mask + dhcp_pool = [IP(addr[0].strCompressed() + hex(256)), IP(addr[0].strCompressed() + hex(512 - 1))] if dhcp: return gateway, mask, dhcp_pool else: @@ -30,15 +34,18 @@ class wvmNetworks(wvmConnect): net = self.get_network(network) net_status = net.isActive() net_bridge = net.bridgeName() - net_forwd = util.get_xml_path(net.XMLDesc(0), "/network/forward/@mode") + net_forward = util.get_xml_path(net.XMLDesc(0), "/network/forward/@mode") networks.append({'name': network, 'status': net_status, - 'device': net_bridge, 'forward': net_forwd}) + 'device': net_bridge, 'forward': net_forward}) return networks def define_network(self, xml): self.wvm.networkDefineXML(xml) - def create_network(self, name, forward, gateway, mask, dhcp4, bridge, openvswitch, fixed=False): + def create_network(self, name, forward, + ipv4, gateway, mask, dhcp4, + ipv6, gateway6, prefix6, dhcp6, + bridge, openvswitch, fixed=False): xml = """ %s""" % name @@ -53,19 +60,25 @@ class wvmNetworks(wvmConnect): if openvswitch is True: xml += """""" if forward != 'bridge': - xml += """ - """ % (gateway, mask) - if dhcp4: - xml += """ - """ % (dhcp4[0], dhcp4[1]) - if fixed: - fist_oct = int(dhcp4[0].strip().split('.')[3]) - last_oct = int(dhcp4[1].strip().split('.')[3]) - for ip in range(fist_oct, last_oct + 1): - xml += """""" % (util.randomMAC(), gateway[:-2], ip) - xml += """""" - - xml += """""" + if ipv4: + xml += """""" % (gateway, mask) + if dhcp4: + xml += """ + """ % (dhcp4[0], dhcp4[1]) + if fixed: + fist_oct = int(dhcp4[0].strip().split('.')[3]) + last_oct = int(dhcp4[1].strip().split('.')[3]) + for ip in range(fist_oct, last_oct + 1): + xml += """""" % (util.randomMAC(), gateway[:-2], ip) + xml += """""" + xml += """""" + if ipv6: + xml += """""" % (gateway6, prefix6) + if dhcp6: + xml += """ + """ % (dhcp6[0], dhcp6[1]) + xml += """""" + xml += """""" xml += """""" self.define_network(xml) net = self.get_network(name)