blob: b33c7ad1149d6ac3b784590c646ea867b67e96f7 [file] [log] [blame]
Scott Bakerfb9544a2016-03-25 10:55:03 -07001from rest_framework.decorators import api_view
2from rest_framework.response import Response
3from rest_framework.reverse import reverse
4from rest_framework import serializers
5from rest_framework import generics
6from rest_framework import viewsets
Scott Bakera7919e22016-03-31 16:30:00 -07007from rest_framework import status
Scott Bakerfb9544a2016-03-25 10:55:03 -07008from rest_framework.decorators import detail_route, list_route
9from rest_framework.views import APIView
10from core.models import *
11from django.forms import widgets
12from django.conf.urls import patterns, url
13from services.cord.models import VOLTTenant, VBNGTenant, CordSubscriberRoot
Scott Bakera7919e22016-03-31 16:30:00 -070014from api.xosapi_helpers import PlusModelSerializer, XOSViewSet, ReadOnlyField
Scott Bakerfb9544a2016-03-25 10:55:03 -070015from django.shortcuts import get_object_or_404
16from xos.apibase import XOSListCreateAPIView, XOSRetrieveUpdateDestroyAPIView, XOSPermissionDenied
17from xos.exceptions import *
18import json
19import subprocess
Scott Baker12d71082016-03-28 13:23:20 -070020from django.views.decorators.csrf import ensure_csrf_cookie
Scott Bakerfb9544a2016-03-25 10:55:03 -070021
Scott Baker12d71082016-03-28 13:23:20 -070022class CordSubscriberNew(CordSubscriberRoot):
23 class Meta:
24 proxy = True
25 app_label = "cord"
Scott Bakerfb9544a2016-03-25 10:55:03 -070026
Scott Baker12d71082016-03-28 13:23:20 -070027 def __init__(self, *args, **kwargs):
28 super(CordSubscriberNew, self).__init__(*args, **kwargs)
29
30 def __unicode__(self):
31 return u"cordSubscriber-%s" % str(self.id)
32
33 @property
34 def features(self):
35 return {"cdn": self.cdn_enable,
36 "uplink_speed": self.uplink_speed,
37 "downlink_speed": self.downlink_speed,
38 "uverse": self.enable_uverse,
39 "status": self.status}
40
41 @features.setter
42 def features(self, value):
43 self.cdn_enable = value.get("cdn", self.get_default_attribute("cdn_enable"))
44 self.uplink_speed = value.get("uplink_speed", self.get_default_attribute("uplink_speed"))
45 self.downlink_speed = value.get("downlink_speed", self.get_default_attribute("downlink_speed"))
46 self.enable_uverse = value.get("uverse", self.get_default_attribute("enable_uverse"))
47 self.status = value.get("status", self.get_default_attribute("status"))
48
Scott Baker6054ce52016-03-31 11:53:57 -070049
Scott Bakerc4200f92016-03-28 15:07:36 -070050 def update_features(self, value):
51 d=self.features
52 d.update(value)
53 self.features = d
54
Scott Baker85f2cd32016-03-28 16:23:53 -070055 @property
56 def identity(self):
Scott Baker69c56882016-04-01 09:17:35 -070057 return {"account_num": self.service_specific_id,
58 "name": self.name}
Scott Baker85f2cd32016-03-28 16:23:53 -070059
60 @identity.setter
61 def identity(self, value):
Scott Baker69c56882016-04-01 09:17:35 -070062 self.service_specific_id = value.get("account_num", self.service_specific_id)
63 self.name = value.get("name", self.name)
Scott Baker85f2cd32016-03-28 16:23:53 -070064
65 def update_identity(self, value):
66 d=self.identity
67 d.update(value)
68 self.identity = d
69
70 @property
71 def related(self):
72 related = {}
73 if self.volt:
74 related["volt_id"] = self.volt.id
75 related["s_tag"] = self.volt.s_tag
76 related["c_tag"] = self.volt.c_tag
77 if self.volt.vcpe:
78 related["vsg_id"] = self.volt.vcpe.id
79 if self.volt.vcpe.instance:
80 related["instance_id"] = self.volt.vcpe.instance.id
81 related["instance_name"] = self.volt.vcpe.instance.name
82 related["wan_container_ip"] = self.volt.vcpe.wan_container_ip
Scott Baker8ca0c072016-03-30 09:42:56 -070083 if self.volt.vcpe.instance.node:
84 related["compute_node_name"] = self.volt.vcpe.instance.node.name
Scott Baker85f2cd32016-03-28 16:23:53 -070085 return related
86
Scott Baker12d71082016-03-28 13:23:20 -070087 def save(self, *args, **kwargs):
88 super(CordSubscriberNew, self).save(*args, **kwargs)
89
Scott Baker69c56882016-04-01 09:17:35 -070090# Add some structure to the REST API by subdividing the object into
91# features, identity, and related.
92
Scott Bakerc4200f92016-03-28 15:07:36 -070093class FeatureSerializer(serializers.Serializer):
94 cdn = serializers.BooleanField(required=False)
95 uplink_speed = serializers.IntegerField(required=False)
96 downlink_speed = serializers.IntegerField(required=False)
97 uverse = serializers.BooleanField(required=False)
98 status = serializers.CharField(required=False)
Scott Baker12d71082016-03-28 13:23:20 -070099
Scott Baker85f2cd32016-03-28 16:23:53 -0700100class IdentitySerializer(serializers.Serializer):
101 account_num = serializers.CharField(required=False)
Scott Baker69c56882016-04-01 09:17:35 -0700102 name = serializers.CharField(required=False)
Scott Baker85f2cd32016-03-28 16:23:53 -0700103
Scott Bakera7919e22016-03-31 16:30:00 -0700104class CordSubscriberSerializer(PlusModelSerializer):
Scott Bakerfb9544a2016-03-25 10:55:03 -0700105 id = ReadOnlyField()
Scott Bakerfb9544a2016-03-25 10:55:03 -0700106 humanReadableName = serializers.SerializerMethodField("getHumanReadableName")
Scott Baker6054ce52016-03-31 11:53:57 -0700107 features = FeatureSerializer(required=False)
108 identity = IdentitySerializer(required=False)
Scott Baker85f2cd32016-03-28 16:23:53 -0700109 related = serializers.DictField(required=False)
Scott Bakerfb9544a2016-03-25 10:55:03 -0700110
Scott Baker40f15682016-03-31 12:00:15 -0700111 nested_fields = ["features", "identity"]
112
Scott Bakerfb9544a2016-03-25 10:55:03 -0700113 class Meta:
Scott Baker12d71082016-03-28 13:23:20 -0700114 model = CordSubscriberNew
115 fields = ('humanReadableName',
116 'id',
Scott Baker85f2cd32016-03-28 16:23:53 -0700117 'features',
118 'identity',
119 'related')
Scott Bakerfb9544a2016-03-25 10:55:03 -0700120
121 def getHumanReadableName(self, obj):
122 return obj.__unicode__()
123
Scott Baker12d71082016-03-28 13:23:20 -0700124# @ensure_csrf_cookie
Scott Bakerfb9544a2016-03-25 10:55:03 -0700125class CordSubscriberViewSet(XOSViewSet):
126 base_name = "subscriber"
Scott Bakerd9d55f22016-03-25 13:33:11 -0700127 method_name = "subscriber"
Scott Bakerfb9544a2016-03-25 10:55:03 -0700128 method_kind = "viewset"
Scott Baker12d71082016-03-28 13:23:20 -0700129 queryset = CordSubscriberNew.get_tenant_objects().select_related().all()
130 serializer_class = CordSubscriberSerializer
Scott Bakerfb9544a2016-03-25 10:55:03 -0700131
Scott Baker0aa863f2016-04-05 21:27:10 -0700132 custom_serializers = {"set_features": FeatureSerializer,
133 "set_feature": FeatureSerializer,
134 "set_identities": IdentitySerializer,
135 "set_identity": IdentitySerializer}
136
Scott Bakerfb9544a2016-03-25 10:55:03 -0700137 @classmethod
Scott Bakerbca3a1b2016-03-28 13:22:10 -0700138 def get_urlpatterns(self, api_path="^"):
Scott Bakerd9d55f22016-03-25 13:33:11 -0700139 patterns = super(CordSubscriberViewSet, self).get_urlpatterns(api_path=api_path)
Scott Baker12d71082016-03-28 13:23:20 -0700140 patterns.append( self.detail_url("features/$", {"get": "get_features", "put": "set_features"}, "features") )
141 patterns.append( self.detail_url("features/(?P<feature>[a-zA-Z0-9\-_]+)/$", {"get": "get_feature", "put": "set_feature"}, "get_feature") )
Scott Baker20189bf2016-03-28 16:39:56 -0700142 patterns.append( self.detail_url("identity/$", {"get": "get_identities", "put": "set_identities"}, "identities") )
143 patterns.append( self.detail_url("identity/(?P<identity>[a-zA-Z0-9\-_]+)/$", {"get": "get_identity", "put": "set_identity"}, "get_identity") )
Scott Bakerfb9544a2016-03-25 10:55:03 -0700144
Scott Bakera7919e22016-03-31 16:30:00 -0700145 patterns.append( url(self.api_path + "account_num_lookup/(?P<account_num>[0-9\-]+)/$", self.as_view({"get": "account_num_detail"}), name="account_num_detail") )
146
147 patterns.append( url(self.api_path + "ssidmap/(?P<ssid>[0-9\-]+)/$", self.as_view({"get": "ssiddetail"}), name="ssiddetail") )
148 patterns.append( url(self.api_path + "ssidmap/$", self.as_view({"get": "ssidlist"}), name="ssidlist") )
Scott Bakerfb9544a2016-03-25 10:55:03 -0700149
150 return patterns
151
152 def list(self, request):
153 object_list = self.filter_queryset(self.get_queryset())
154
155 serializer = self.get_serializer(object_list, many=True)
156
Scott Bakerc4200f92016-03-28 15:07:36 -0700157 return Response(serializer.data)
Scott Bakerfb9544a2016-03-25 10:55:03 -0700158
Scott Baker12d71082016-03-28 13:23:20 -0700159 def get_features(self, request, pk=None):
Scott Bakerfb9544a2016-03-25 10:55:03 -0700160 subscriber = self.get_object()
Scott Bakerc4200f92016-03-28 15:07:36 -0700161 return Response(FeatureSerializer(subscriber.features).data)
Scott Bakerfb9544a2016-03-25 10:55:03 -0700162
Scott Baker20189bf2016-03-28 16:39:56 -0700163 def set_features(self, request, pk=None):
164 subscriber = self.get_object()
165 ser = FeatureSerializer(subscriber.features, data=request.data)
166 ser.is_valid(raise_exception = True)
167 subscriber.update_features(ser.validated_data)
168 subscriber.save()
169 return Response(FeatureSerializer(subscriber.features).data)
170
Scott Baker12d71082016-03-28 13:23:20 -0700171 def get_feature(self, request, pk=None, feature=None):
Scott Bakerfb9544a2016-03-25 10:55:03 -0700172 subscriber = self.get_object()
Scott Bakerc4200f92016-03-28 15:07:36 -0700173 return Response({feature: FeatureSerializer(subscriber.features).data[feature]})
Scott Bakerfb9544a2016-03-25 10:55:03 -0700174
Scott Baker12d71082016-03-28 13:23:20 -0700175 def set_feature(self, request, pk=None, feature=None):
Scott Bakerfb9544a2016-03-25 10:55:03 -0700176 subscriber = self.get_object()
Scott Bakerc4200f92016-03-28 15:07:36 -0700177 if [feature] != request.data.keys():
178 raise serializers.ValidationError("feature %s does not match keys in request body (%s)" % (feature, ",".join(request.data.keys())))
179 ser = FeatureSerializer(subscriber.features, data=request.data)
180 ser.is_valid(raise_exception = True)
181 subscriber.update_features(ser.validated_data)
Scott Baker20189bf2016-03-28 16:39:56 -0700182 subscriber.save()
Scott Baker85f2cd32016-03-28 16:23:53 -0700183 return Response({feature: FeatureSerializer(subscriber.features).data[feature]})
Scott Bakerfb9544a2016-03-25 10:55:03 -0700184
Scott Baker20189bf2016-03-28 16:39:56 -0700185 def get_identities(self, request, pk=None):
Scott Bakerfb9544a2016-03-25 10:55:03 -0700186 subscriber = self.get_object()
Scott Baker20189bf2016-03-28 16:39:56 -0700187 return Response(IdentitySerializer(subscriber.identity).data)
188
189 def set_identities(self, request, pk=None):
190 subscriber = self.get_object()
191 ser = IdentitySerializer(subscriber.identity, data=request.data)
Scott Bakerc4200f92016-03-28 15:07:36 -0700192 ser.is_valid(raise_exception = True)
Scott Baker20189bf2016-03-28 16:39:56 -0700193 subscriber.update_identity(ser.validated_data)
Scott Bakerc4200f92016-03-28 15:07:36 -0700194 subscriber.save()
Scott Baker20189bf2016-03-28 16:39:56 -0700195 return Response(IdentitySerializer(subscriber.identity).data)
196
197 def get_identity(self, request, pk=None, identity=None):
198 subscriber = self.get_object()
199 return Response({identity: IdentitySerializer(subscriber.identity).data[identity]})
200
201 def set_identity(self, request, pk=None, identity=None):
202 subscriber = self.get_object()
203 if [identity] != request.data.keys():
204 raise serializers.ValidationError("identity %s does not match keys in request body (%s)" % (identity, ",".join(request.data.keys())))
205 ser = IdentitySerializer(subscriber.identity, data=request.data)
206 ser.is_valid(raise_exception = True)
207 subscriber.update_identity(ser.validated_data)
208 subscriber.save()
209 return Response({identity: IdentitySerializer(subscriber.identity).data[identity]})
Scott Bakerfb9544a2016-03-25 10:55:03 -0700210
Scott Bakera7919e22016-03-31 16:30:00 -0700211 def account_num_detail(self, pk=None, account_num=None):
212 object_list = CordSubscriberNew.get_tenant_objects().all()
213 object_list = [x for x in object_list if x.service_specific_id == account_num]
214 if not object_list:
215 return Response("Failed to find account_num %s" % account_num, status=status.HTTP_404_NOT_FOUND)
216
217 return Response( object_list[0].id )
218
Scott Bakerfb9544a2016-03-25 10:55:03 -0700219 def ssidlist(self, request):
Scott Baker12d71082016-03-28 13:23:20 -0700220 object_list = CordSubscriberNew.get_tenant_objects().all()
Scott Bakerfb9544a2016-03-25 10:55:03 -0700221
222 ssidmap = [ {"service_specific_id": x.service_specific_id, "subscriber_id": x.id} for x in object_list ]
223
224 return Response({"ssidmap": ssidmap})
225
226 def ssiddetail(self, pk=None, ssid=None):
Scott Baker12d71082016-03-28 13:23:20 -0700227 object_list = CordSubscriberNew.get_tenant_objects().all()
Scott Bakerfb9544a2016-03-25 10:55:03 -0700228
229 ssidmap = [ {"service_specific_id": x.service_specific_id, "subscriber_id": x.id} for x in object_list if str(x.service_specific_id)==str(ssid) ]
230
231 if len(ssidmap)==0:
232 raise XOSNotFound("didn't find ssid %s" % str(ssid))
233
234 return Response( ssidmap[0] )
235