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."""