from django import forms from .models import WireGuardInstance, NETMASK_CHOICES from wgwadmlibrary.tools import is_valid_ip_or_hostname import ipaddress class WireGuardInstanceForm(forms.ModelForm): name = forms.CharField(label='Display Name', required=False) instance_id = forms.IntegerField(label='Instance ID') private_key = forms.CharField(label='Private Key') public_key = forms.CharField(label='Public Key') hostname = forms.CharField(label='Public Address') listen_port = forms.IntegerField(label='Listen Port') address = forms.GenericIPAddressField(label='VPN IP Address') netmask = forms.ChoiceField(choices=NETMASK_CHOICES, label='Netmask') post_up = forms.CharField(label='Post Up', required=False) post_down = forms.CharField(label='Post Down', required=False) peer_list_refresh_interval = forms.IntegerField(label='Web Refresh Interval', initial=20) dns_primary = forms.GenericIPAddressField(label='Primary DNS', initial='1.1.1.1', required=False) dns_secondary = forms.GenericIPAddressField(label='Secondary DNS', initial='', required=False) class Meta: model = WireGuardInstance fields = [ 'name', 'instance_id', 'private_key', 'public_key','hostname', 'listen_port', 'address', 'netmask', 'post_up', 'post_down', 'peer_list_refresh_interval', 'dns_primary', 'dns_secondary' ] def clean(self): cleaned_data = super().clean() hostname = cleaned_data.get('hostname') address = cleaned_data.get('address') netmask = cleaned_data.get('netmask') post_up = cleaned_data.get('post_up') post_down = cleaned_data.get('post_down') peer_list_refresh_interval = cleaned_data.get('peer_list_refresh_interval') if peer_list_refresh_interval < 5: raise forms.ValidationError('Peer List Refresh Interval must be at least 5 seconds') if not is_valid_ip_or_hostname(hostname): raise forms.ValidationError('Invalid hostname or IP Address') current_network = ipaddress.ip_network(f"{address}/{netmask}", strict=False) all_other_instances = WireGuardInstance.objects.all() if self.instance: all_other_instances = all_other_instances.exclude(uuid=self.instance.uuid) for instance in all_other_instances: other_network = ipaddress.ip_network(f"{instance.address}/{instance.netmask}", strict=False) if current_network.overlaps(other_network): raise forms.ValidationError(f"The network range {current_network} overlaps with another instance's network range {other_network}.") #if self.instance: # if post_up or post_down: # if self.instance.post_up != post_up or self.instance.post_down != post_down: # raise forms.ValidationError('Post Up and Post Down cannot be changed, please go to Firewall page to make changes to the firewall.') #else: # if post_up or post_down: # raise forms.ValidationError('Post Up and Post Down cannot be set, please go to Firewall page to make changes to the firewall.') return cleaned_data