Make VPN Great Again
diff --git a/views/ngXosViews/vpnDashboard/src/index.html b/views/ngXosViews/vpnDashboard/src/index.html
index 1842119..b19740a 100644
--- a/views/ngXosViews/vpnDashboard/src/index.html
+++ b/views/ngXosViews/vpnDashboard/src/index.html
@@ -22,6 +22,8 @@
<!-- endbower --><!-- endjs -->
<!-- inject:js -->
<script src="/xosHelpers/src/xosHelpers.module.js"></script>
+<script src="/xosHelpers/src/ui_components/table/table.component.js"></script>
+<script src="/xosHelpers/src/ui_components/ui-components.module.js"></script>
<script src="/xosHelpers/src/services/noHyperlinks.interceptor.js"></script>
<script src="/xosHelpers/src/services/csrfToken.interceptor.js"></script>
<script src="/xosHelpers/src/services/api.services.js"></script>
diff --git a/xos/core/admin.py b/xos/core/admin.py
index b0efbd4..5d2343f 100644
--- a/xos/core/admin.py
+++ b/xos/core/admin.py
@@ -894,7 +894,7 @@
class TenantRoleAdmin(XOSBaseAdmin):
model = TenantRole
- pass
+ fields = ('role',)
class TenantPrivilegeInline(XOSTabularInline):
model = TenantPrivilege
@@ -2177,6 +2177,6 @@
admin.site.register(TenantRoot, TenantRootAdmin)
admin.site.register(TenantRootRole, TenantRootRoleAdmin)
admin.site.register(Tenant, TenantAdmin)
- admin.site.register(TenantRole)
+ admin.site.register(TenantRole, TenantRootRoleAdmin)
admin.site.register(TenantAttribute, TenantAttributeAdmin)
# admin.site.register(Container, ContainerAdmin)
diff --git a/xos/core/models/service.py b/xos/core/models/service.py
index 97fa890..015564a 100644
--- a/xos/core/models/service.py
+++ b/xos/core/models/service.py
@@ -1,9 +1,10 @@
-from django.db import models
-from core.models import PlCoreBase,SingletonModel,PlCoreBaseManager
-from core.models.plcorebase import StrippedCharField
-from xos.exceptions import *
-from operator import attrgetter
import json
+from operator import attrgetter
+
+from core.models import PlCoreBase, PlCoreBaseManager, SingletonModel
+from core.models.plcorebase import StrippedCharField
+from django.db import models
+from xos.exceptions import *
COARSE_KIND="coarse"
@@ -813,9 +814,9 @@
def __unicode__(self): return u'%s' % (self.role)
class TenantPrivilege(PlCoreBase):
- user = models.ForeignKey('User', related_name="tenant_privileges")
- tenant = models.ForeignKey('Tenant', related_name="tenant_privileges")
- role = models.ForeignKey('TenantRole', related_name="tenant_privileges")
+ user = models.ForeignKey('User', related_name="tenantprivileges")
+ tenant = models.ForeignKey('Tenant', related_name="tenantprivileges")
+ role = models.ForeignKey('TenantRole', related_name="tenantprivileges")
class Meta:
unique_together = ('user', 'tenant', 'role')
diff --git a/xos/core/xoslib/methods/vpnview.py b/xos/core/xoslib/methods/vpnview.py
index ccd2141..bb4544e 100644
--- a/xos/core/xoslib/methods/vpnview.py
+++ b/xos/core/xoslib/methods/vpnview.py
@@ -27,23 +27,29 @@
clients_can_see_each_other = ReadOnlyField()
ca_crt = ReadOnlyField()
port_number = ReadOnlyField()
+ protocol = ReadOnlyField()
failover_servers = ReadOnlyField()
creator = ReadOnlyField()
instance = ReadOnlyField()
script_text = ReadOnlyField()
- provider_service = serializers.PrimaryKeyRelatedField(queryset=VPNService.get_service_objects().all(), default=get_default_vpn_service)
+ provider_service = serializers.PrimaryKeyRelatedField(
+ queryset=VPNService.get_service_objects().all(),
+ default=get_default_vpn_service)
- humanReadableName = serializers.SerializerMethodField("getHumanReadableName")
+ humanReadableName = serializers.SerializerMethodField(
+ "getHumanReadableName")
- computeNodeName = serializers.SerializerMethodField("getComputeNodeName")
+ computeNodeName = serializers.SerializerMethodField(
+ "getComputeNodeName")
class Meta:
model = VPNTenant
fields = ('humanReadableName', 'id', 'provider_service',
'service_specific_attribute', 'vpn_subnet',
- 'server_network', 'creator', 'instance',
- 'computeNodeName', 'is_persistent', 'clients_can_see_each_other',
- 'ca_crt', 'port_number', 'script_text', 'failover_servers')
+ 'server_network', 'creator', 'instance', 'protocol',
+ 'computeNodeName', 'is_persistent',
+ 'clients_can_see_each_other', 'ca_crt', 'port_number',
+ 'script_text', 'failover_servers')
def getHumanReadableName(self, obj):
return obj.__unicode__()
@@ -62,7 +68,13 @@
def get_queryset(self):
queryset = VPNTenant.get_tenant_objects().all()
- queryset = [ tenant for tenant in queryset if self.request.user.can_update_tenant(tenant, ['access', 'Access'])]
+ queryset = [
+ tenant
+ for tenant in queryset
+ if self.request.user.can_update_tenant(tenant,
+ ['access', 'Access'])]
for tenant in queryset:
- tenant.script_text = tenant.create_client_script(self.request.user.email + "-" + tenant.id)
+ tenant.script_text = (
+ tenant.create_client_script(
+ self.request.user.email + "-" + str(tenant.id)))
return queryset
diff --git a/xos/services/vpn/admin.py b/xos/services/vpn/admin.py
index fbc0ede..77a411b 100644
--- a/xos/services/vpn/admin.py
+++ b/xos/services/vpn/admin.py
@@ -5,7 +5,6 @@
from core.models import TenantPrivilege, User
from django import forms
from django.contrib import admin
-from django.core import serializers
from services.vpn.models import VPN_KIND, VPNService, VPNTenant
from xos.exceptions import XOSValidationError
@@ -124,16 +123,14 @@
vpn_subnet = forms.GenericIPAddressField(protocol="IPv4", required=True)
is_persistent = forms.BooleanField(required=False)
clients_can_see_each_other = forms.BooleanField(required=False)
- failover_servers = forms.ModelMultipleChoiceField(
- queryset=VPNTenant.get_tenant_objects(),
- required=False,
- widget=forms.CheckboxSelectMultiple())
+ failover_servers = forms.ModelMultipleChoiceField(required=False)
protocol = forms.ChoiceField(required=True, choices=[
- ("udp", "udp"), ("tcp", "tcp")])
+ ("tcp", "tcp"), ("udp", "udp")])
def __init__(self, *args, **kwargs):
super(VPNTenantForm, self).__init__(*args, **kwargs)
self.fields['kind'].widget.attrs['readonly'] = True
+ self.fields['failover_servers'].widget.attrs['rows'] = 100
# self.fields['script_name'].widget.attrs['readonly'] = True
self.fields[
'provider_service'].queryset = (
@@ -151,11 +148,9 @@
self.instance.clients_can_see_each_other)
self.fields['is_persistent'].initial = self.instance.is_persistent
self.initial['protocol'] = self.instance.protocol
- if (self.instance.failover_servers):
- self.initial['failover_servers'] = [
- model.pk for model in list(
- serializers.deserialize(
- 'json', self.instance.failover_servers))]
+ self.initial['failover_servers'] = self.instance.failover_servers
+ self.fields['failover_servers'].queryset = (
+ VPNTenant.get_tenant_objects().exclude(pk=self.instance.pk))
if (not self.instance) or (not self.instance.pk):
self.fields['creator'].initial = get_request().user
@@ -163,6 +158,8 @@
self.fields['server_network'].initial = "10.66.77.0"
self.fields['clients_can_see_each_other'].initial = True
self.fields['is_persistent'].initial = True
+ self.fields['failover_servers'].queryset = (
+ VPNTenant.get_tenant_objects())
if VPNService.get_service_objects().exists():
self.fields["provider_service"].initial = (
VPNService.get_service_objects().all()[0])
@@ -174,9 +171,9 @@
self.instance.server_network = self.cleaned_data.get('server_network')
self.instance.clients_can_see_each_other = self.cleaned_data.get(
'clients_can_see_each_other')
- self.instance.failover_servers = (
- serializers.serialize(
- "json", self.cleaned_data.get('failover_servers')))
+
+ for tenant in self.cleaned_data['failover_servers']:
+ self.instance.failover_servers.add(tenant)
self.instance.protocol = self.cleaned_data.get("protocol")
self.instance.port_number = (
diff --git a/xos/services/vpn/models.py b/xos/services/vpn/models.py
index a782080..dfae1e8 100644
--- a/xos/services/vpn/models.py
+++ b/xos/services/vpn/models.py
@@ -92,7 +92,7 @@
'ca_crt': None,
'port': None,
'script_text': None,
- 'failover_servers': [],
+ 'failover_servers': set(),
'protocol': None}
def __init__(self, *args, **kwargs):
@@ -182,7 +182,7 @@
@property
def failover_servers(self):
- self.get_attribute(
+ return self.get_attribute(
"failover_servers", self.default_attributes["failover_servers"])
@failover_servers.setter
@@ -253,14 +253,14 @@
return script
def get_client_cert(self, client_name):
- return open(
- VPNService.OPENVPN_PREFIX + "server-" + self.id + "/issued/" +
- client_name + ".crt").readlines()
+ with open(VPNService.OPENVPN_PREFIX + "server-" + str(self.id) +
+ "/issued/" + client_name + ".crt", 'r') as f:
+ return f.readlines()
def get_client_key(self, client_name):
- return open(
- VPNService.OPENVPN_PREFIX + "server-" + self.id + "/private/" +
- client_name + ".key").readlines()
+ with open(VPNService.OPENVPN_PREFIX + "server-" + str(self.id) +
+ "/private/" + client_name + ".key", 'r') as f:
+ return f.readlines()
def generate_client_conf(self, client_name):
"""str: Generates the client configuration to use to connect to this
@@ -268,16 +268,19 @@
"""
conf = ("client\n" +
"dev tun\n" +
- "proto " + self.protocol + "\n" +
- "remote " + str(self.nat_ip) + " " + str(self.port_number) +
- "\n" +
- "resolv-retry infinite\n" +
- "nobind\n" +
- "ca ca.crt\n" +
- "cert " + client_name + ".crt\n" +
- "key " + client_name + ".key\n" +
- "comp-lzo\n" +
- "verb 3\n")
+ self.get_remote_line(
+ self.nat_ip, self.port_number, self.protocol))
+ for remote in self.failover_servers:
+ conf += self.get_remote_line(
+ remote.nat_ip, remote.port_number, remote.protocol)
+
+ conf += ("resolv-retry 60\n" +
+ "nobind\n" +
+ "ca ca.crt\n" +
+ "cert " + client_name + ".crt\n" +
+ "key " + client_name + ".key\n" +
+ "comp-lzo\n" +
+ "verb 3\n")
if self.is_persistent:
conf += "persist-tun\n"
@@ -285,6 +288,10 @@
return conf
+ def get_remote_line(self, host, port_number, protocol):
+ return ("remote " + str(host) + " " + str(port_number) + " " +
+ str(protocol) + "\n")
+
def model_policy_vpn_tenant(pk):
"""Manages the contain for the VPN Tenant."""