Work on vpn view
diff --git a/views/ngXosViews/vpnDashboard/src/css/dev.css b/views/ngXosViews/vpnDashboard/src/css/dev.css
index 67c3992..4c504c9 100644
--- a/views/ngXosViews/vpnDashboard/src/css/dev.css
+++ b/views/ngXosViews/vpnDashboard/src/css/dev.css
@@ -9,3 +9,6 @@
display: table-cell;
padding: 5px;
}
+.header {
+ font-weight: bold;
+}
diff --git a/views/ngXosViews/vpnDashboard/src/js/main.js b/views/ngXosViews/vpnDashboard/src/js/main.js
index b3b7f85..7a576df 100644
--- a/views/ngXosViews/vpnDashboard/src/js/main.js
+++ b/views/ngXosViews/vpnDashboard/src/js/main.js
@@ -12,18 +12,18 @@
.state('vpnList', {
url: '/',
template: '<vpn-list></vpn-list>'
- })
- .state('clientScript', {
- url: '/client/:tenantId',
- template: '<client-script></client-script>'
});
})
+.config(($compileProvider) => {
+ $compileProvider.aHrefSanitizationWhitelist(
+ /^\s*(https?|ftp|mailto|tel|file|blob):/);
+})
.service('Vpn', function($http, $q){
this.getVpnTenants = () => {
let deferred = $q.defer();
- $http.get('/xoslib/vpntenants/')
+ $http.get('/xoslib/vpntenant/')
.then((res) => {
deferred.resolve(res.data)
})
@@ -33,19 +33,6 @@
return deferred.promise;
}
- this.getVpnTenants = (tenantId) => {
- let deferred = $q.defer();
-
- $http.get('/xoslib/clientscript/', {params: {tenantId: tenantId}})
- .then((res) => {
- deferred.resolve(res.data)
- })
- .catch((e) => {
- deferred.reject(e);
- });
-
- return deferred.promise;
- };
})
.config(function($httpProvider){
$httpProvider.interceptors.push('NoHyperlinks');
@@ -66,27 +53,12 @@
.catch((e) => {
throw new Error(e);
});
- }
- };
-})
-.directive('clientScript', function(){
- return {
- restrict: 'E',
- scope: {
- tenantId: '=tenantId',
- },
- bindToController: true,
- controllerAs: 'vm',
- templateUrl: 'templates/client-script.tpl.html',
- controller: function(Vpn){
- // retrieving user list
- Vpn.getClientScript(tenantId)
- .then((script_location) => {
- this.script_location = script_location;
- })
- .catch((e) => {
- throw new Error(e);
- });
+
+ this.getScriptLocation = function(vpn) {
+ var content = vpn.create_client_script();
+ var blob = new Blob([ content ], { type : 'text/plain' });
+ return (window.URL || window.webkitURL).createObjectURL( blob );
+ }
}
};
});
diff --git a/views/ngXosViews/vpnDashboard/src/templates/client-script.tpl.html b/views/ngXosViews/vpnDashboard/src/templates/client-script.tpl.html
deleted file mode 100644
index 6810580..0000000
--- a/views/ngXosViews/vpnDashboard/src/templates/client-script.tpl.html
+++ /dev/null
@@ -1,4 +0,0 @@
-<a href="/static/vpn/{{ vm.script_location }}" download id="download" hidden>{{ vm.script_location }}</a>
-<script>
-// document.getElementById('download').click();
-</script>
diff --git a/views/ngXosViews/vpnDashboard/src/templates/vpn-list.tpl.html b/views/ngXosViews/vpnDashboard/src/templates/vpn-list.tpl.html
index 8d4df52..95d197f 100644
--- a/views/ngXosViews/vpnDashboard/src/templates/vpn-list.tpl.html
+++ b/views/ngXosViews/vpnDashboard/src/templates/vpn-list.tpl.html
@@ -1,17 +1,19 @@
-<div class="row">
- <h1>VPN List</h1>
-</div>
-<div class="row">
- <div class="cell">ID</div>
- <div class="cell">VPN Network</div>
- <div class="cell">VPN Subnet</div>
- <div class="cell">Script Link</div>
-</div>
-<div class="row" ng-repeat="vpn in vm.vpns">
- <div class="cell">{{vpn.instance.instance_id}}</div>
- <div class="cell">{{vpn.server_network}}</div>
- <div class="cell">{{vpn.vpn_subnet}}</div>
- <div class="cell">
- <a href="client/{{ vpn.pk }}/" target="_blank">Script</a>
+<div style="display: table;">
+ <div class="row">
+ <h1 class="cell">VPN List</h1>
+ </div>
+ <div class="row">
+ <div class="cell header">ID</div>
+ <div class="cell header">VPN Network</div>
+ <div class="cell header">VPN Subnet</div>
+ <div class="cell header">Script Link</div>
+ </div>
+ <div class="row" ng-repeat="vpn in vm.vpns">
+ <div class="cell">{{ vpn.id }}</div>
+ <div class="cell">{{ vpn.server_network }}</div>
+ <div class="cell">{{ vpn.vpn_subnet }}</div>
+ <div class="cell">
+ <a download="connect-{{ vpn.id }}.vpn" ng-href="{{ vm.getScriptLocation(vpn) }}">Script</a>
+ </div>
</div>
</div>
diff --git a/xos/core/xoslib/methods/vpnview.py b/xos/core/xoslib/methods/vpnview.py
index f8983ab..ccbb2e7 100644
--- a/xos/core/xoslib/methods/vpnview.py
+++ b/xos/core/xoslib/methods/vpnview.py
@@ -1,16 +1,65 @@
from django.core.exceptions import PermissionDenied
+from plus import PlusSerializerMixin
+from rest_framework import serializers
from rest_framework.response import Response
+from rest_framework.status import HTTP_200_OK
from rest_framework.views import APIView
-from services.vpn.models import VPNTenant
+from services.vpn.models import VPNService, VPNTenant
+from xos.apibase import XOSListCreateAPIView
-class VpnTenantsList(APIView):
+if hasattr(serializers, "ReadOnlyField"):
+ # rest_framework 3.x
+ ReadOnlyField = serializers.ReadOnlyField
+else:
+ # rest_framework 2.x
+ ReadOnlyField = serializers.Field
+
+def get_default_vpn_service():
+ vpn_services = VPNService.get_service_objects().all()
+ if vpn_services:
+ return vpn_services[0].id
+ return None
+
+class VPNTenantSerializer(serializers.ModelSerializer, PlusSerializerMixin):
+ id = ReadOnlyField()
+ service_specific_attribute = ReadOnlyField()
+ server_network = ReadOnlyField()
+ vpn_subnet = ReadOnlyField()
+ is_persistent = ReadOnlyField()
+ clients_can_see_each_other = ReadOnlyField()
+ ca_crt = ReadOnlyField()
+ port_number = ReadOnlyField()
+ creator = ReadOnlyField()
+ instance = ReadOnlyField()
+ provider_service = serializers.PrimaryKeyRelatedField(queryset=VPNService.get_service_objects().all(), default=get_default_vpn_service)
+
+ humanReadableName = serializers.SerializerMethodField("getHumanReadableName")
+
+ 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')
+
+ def getHumanReadableName(self, obj):
+ return obj.__unicode__()
+
+ def getComputeNodeName(self, obj):
+ instance = obj.instance
+ if not instance:
+ return None
+ return instance.node.name
+
+class VPNTenantList(XOSListCreateAPIView):
+ serializer_class = VPNTenantSerializer
+ queryset = VPNTenant.get_tenant_objects().all()
method_kind = "list"
- method_name = "vpntenants"
+ method_name = "vpntenant"
- def get(self, request, format=None):
- if (not request.user.is_authenticated()):
- raise PermissionDenied("You must be authenticated in order to use this API")
- return Response(VPNTenant.get_tenant_objects())
class ClientScript(APIView):
method_kind = "detail"
@@ -19,5 +68,6 @@
def get(self, request, format=None):
if (not request.user.is_authenticated()):
raise PermissionDenied("You must be authenticated in order to use this API")
- teant_id = request.QUERY_PARAMS.get('tenantId', None)
- return Response(VPNTenant.get_tenant_objects().filter(pk=tenantId))
+ tenantId = request.QUERY_PARAMS.get('tenantId', None)
+ serializer = VPNTenantSerializer(VPNTenant.get_tenant_objects().filter(id=tenantId)[0])
+ return Response(serializer.data, status=HTTP_200_OK)
diff --git a/xos/services/vpn/models.py b/xos/services/vpn/models.py
index 7e324af..146168f 100644
--- a/xos/services/vpn/models.py
+++ b/xos/services/vpn/models.py
@@ -32,7 +32,6 @@
'server_network': None,
'clients_can_see_each_other': True,
'is_persistent': True,
- 'script': None,
'ca_crt': None,
'port': None}
@@ -140,36 +139,25 @@
def port_number(self, value):
self.set_attribute("port", value)
- @property
- def script(self):
- """string: the location of the client script that is generated when
- this method is called.
- """
- script_name = str(time.time()) + ".vpn"
- self.create_client_script(script_name)
- return script_name
-
- def create_client_script(self, script_name):
- script = open("/opt/xos/core/static/vpn/" + script_name, 'w')
+ def create_client_script(self):
+ script = ""
# write the configuration portion
- script.write("printf \"%b\" \"")
- for line in self.generate_client_conf().splitlines():
- script.write(line + r"\n")
- script.write("\" > client.conf\n")
- script.write("printf \"%b\" \"")
- for line in self.generate_login().splitlines():
- script.write(line + r"\n")
- script.write("\" > login.up\n")
- script.write("printf \"%b\" \"")
+ script += ("printf \"%b\" \"")
+ script += self.generate_client_conf()
+ script += ("\" > client.conf\n")
+ script += ("printf \"%b\" \"")
+ script += self.generate_login()
+ script += ("\" > login.up\n")
+ script += ("printf \"%b\" \"")
for line in self.ca_crt:
- script.write(line.rstrip() + r"\n")
- script.write("\" > ca.crt\n")
+ script += (line.rstrip() + r"\n")
+ script += ("\" > ca.crt\n")
# make sure openvpn is installed
- script.write("apt-get update\n")
- script.write("apt-get install openvpn\n")
- script.write("openvpn client.conf &\n")
+ script += ("apt-get update\n")
+ script += ("apt-get install openvpn\n")
+ script += ("openvpn client.conf &\n")
# close the script
- script.close()
+ return script;
def generate_login(self):
return str(time.time()) + "\npassword\n"