CORD-1083 move CordSubscriberRoot to rcord repo
Change-Id: If017242579752aa2d813c1d462d36944fb735056
diff --git a/xos/admin.py b/xos/admin.py
new file mode 100644
index 0000000..84e0ecd
--- /dev/null
+++ b/xos/admin.py
@@ -0,0 +1,70 @@
+from django.contrib import admin
+
+#from services.volt.models import *
+from services.rcord.models import *
+from django import forms
+from django.utils.safestring import mark_safe
+from django.contrib.auth.admin import UserAdmin
+from django.contrib.admin.widgets import FilteredSelectMultiple
+from django.contrib.auth.forms import ReadOnlyPasswordHashField
+from django.contrib.auth.signals import user_logged_in
+from django.utils import timezone
+from django.contrib.contenttypes import generic
+from suit.widgets import LinkedSelect
+from core.admin import ServiceAppAdmin,SliceInline,ServiceAttrAsTabInline, ReadOnlyAwareAdmin, XOSTabularInline, ServicePrivilegeInline, TenantRootTenantInline, TenantRootPrivilegeInline
+from core.middleware import get_request
+
+from functools import update_wrapper
+from django.contrib.admin.views.main import ChangeList
+from django.core.urlresolvers import reverse
+from django.contrib.admin.utils import quote
+
+#class VOLTTenantInline(XOSTabularInline):
+# model = VOLTTenant
+# fields = ['provider_service', 'subscriber_root', 'service_specific_id']
+# readonly_fields = ['provider_service', 'subscriber_root', 'service_specific_id']
+# extra = 0
+# max_num = 0
+# suit_classes = 'suit-tab suit-tab-volttenants'
+# fk_name = 'subscriber_root'
+# verbose_name = 'subscribed tenant'
+# verbose_name_plural = 'subscribed tenants'
+#
+# @property
+# def selflink_reverse_path(self):
+# return "admin:cord_volttenant_change"
+
+class CordSubscriberRootForm(forms.ModelForm):
+ def __init__(self,*args,**kwargs):
+ super (CordSubscriberRootForm,self ).__init__(*args,**kwargs)
+ self.fields['kind'].widget.attrs['readonly'] = True
+ if (not self.instance) or (not self.instance.pk):
+ # default fields for an 'add' form
+ self.fields['kind'].initial = CORD_SUBSCRIBER_KIND
+
+ def save(self, commit=True):
+ return super(CordSubscriberRootForm, self).save(commit=commit)
+
+ class Meta:
+ model = CordSubscriberRoot
+ fields = '__all__'
+
+class CordSubscriberRootAdmin(ReadOnlyAwareAdmin):
+ list_display = ('backend_status_icon', 'id', 'name', )
+ list_display_links = ('backend_status_icon', 'id', 'name', )
+ fieldsets = [ (None, {'fields': ['backend_status_text', 'kind', 'name', 'service_specific_id', # 'service_specific_attribute',
+ 'url_filter_level', "uplink_speed", "downlink_speed", "status", "enable_uverse", "cdn_enable"],
+ 'classes':['suit-tab suit-tab-general']})]
+ readonly_fields = ('backend_status_text', 'service_specific_attribute',)
+ form = CordSubscriberRootForm
+ inlines = (TenantRootPrivilegeInline) # VOLTTenantInline
+
+ suit_form_tabs =(('general', 'Cord Subscriber Root Details'),
+# ('volttenants','VOLT Tenancy'),
+ ('tenantrootprivileges','Privileges')
+ )
+
+ def get_queryset(self, request):
+ return CordSubscriberRoot.get_tenant_objects_by_user(request.user)
+
+admin.site.register(CordSubscriberRoot, CordSubscriberRootAdmin)
diff --git a/xos/attic/cordsubscriberroot_bottom.py b/xos/attic/cordsubscriberroot_bottom.py
new file mode 100644
index 0000000..5821215
--- /dev/null
+++ b/xos/attic/cordsubscriberroot_bottom.py
@@ -0,0 +1 @@
+CordSubscriberRoot.setup_simple_attributes()
diff --git a/xos/attic/cordsubscriberroot_model.py b/xos/attic/cordsubscriberroot_model.py
new file mode 100644
index 0000000..e4ee81f
--- /dev/null
+++ b/xos/attic/cordsubscriberroot_model.py
@@ -0,0 +1,112 @@
+# 'simple_attributes' will be expanded into properties and setters that
+# store the attribute using self.set_attribute / self.get_attribute.
+
+simple_attributes = ( ("devices", []), )
+
+sync_attributes = ("firewall_enable",
+ "firewall_rules",
+ "url_filter_enable",
+ "url_filter_rules",
+ "cdn_enable",
+ "uplink_speed",
+ "downlink_speed",
+ "enable_uverse",
+ "status")
+
+def __init__(self, *args, **kwargs):
+ super(CordSubscriberRoot, self).__init__(*args, **kwargs)
+
+def find_device(self, mac):
+ for device in self.devices:
+ if device["mac"] == mac:
+ return device
+ return None
+
+def update_device(self, mac, **kwargs):
+ # kwargs may be "level" or "mac"
+ # Setting one of these to None will cause None to be stored in the db
+ devices = self.devices
+ for device in devices:
+ if device["mac"] == mac:
+ for arg in kwargs.keys():
+ device[arg] = kwargs[arg]
+ self.devices = devices
+ return device
+ raise ValueError("Device with mac %s not found" % mac)
+
+def create_device(self, **kwargs):
+ if "mac" not in kwargs:
+ raise XOSMissingField("The mac field is required")
+
+ if self.find_device(kwargs['mac']):
+ raise XOSDuplicateKey("Device with mac %s already exists" % kwargs["mac"])
+
+ device = kwargs.copy()
+
+ devices = self.devices
+ devices.append(device)
+ self.devices = devices
+
+ return device
+
+def delete_device(self, mac):
+ devices = self.devices
+ for device in devices:
+ if device["mac"]==mac:
+ devices.remove(device)
+ self.devices = devices
+ return
+
+ raise ValueError("Device with mac %s not found" % mac)
+
+#--------------------------------------------------------------------------
+# Deprecated -- devices used to be called users
+
+def find_user(self, uid):
+ return self.find_device(uid)
+
+def update_user(self, uid, **kwargs):
+ return self.update_device(uid, **kwargs)
+
+def create_user(self, **kwargs):
+ return self.create_device(**kwargs)
+
+def delete_user(self, uid):
+ return self.delete_user(uid)
+
+# ------------------------------------------------------------------------
+
+@property
+def services(self):
+ return {"cdn": self.cdn_enable,
+ "url_filter": self.url_filter_enable,
+ "firewall": self.firewall_enable}
+
+@services.setter
+def services(self, value):
+ pass
+
+def invalidate_related_objects(self):
+ # Dirty all vSGs related to this subscriber, so the vSG synchronizer
+ # will run.
+
+ # TODO: This should be reimplemented to use a watcher instead.
+
+ # NOTE: "vOLT" and "vCPE" are hardcoded below. They had better agree
+ # with the kinds defined in the vOLT and vCPE models.
+
+ for tenant in self.subscribed_tenants.all():
+ if tenant.kind == "vOLT":
+ for inner_tenant in tenant.subscribed_tenants.all():
+ if inner_tenant.kind == "vCPE":
+ inner_tenant.save()
+
+def save(self, *args, **kwargs):
+ self.validate_unique_service_specific_id(none_okay=True)
+ if (not hasattr(self, 'caller') or not self.caller.is_admin):
+ if (self.has_field_changed("service_specific_id")):
+ raise XOSPermissionDenied("You do not have permission to change service_specific_id")
+ super(CordSubscriberRoot, self).save(*args, **kwargs)
+
+ self.invalidate_related_objects()
+
diff --git a/xos/attic/header.py b/xos/attic/header.py
new file mode 100644
index 0000000..afa4e4c
--- /dev/null
+++ b/xos/attic/header.py
@@ -0,0 +1,21 @@
+from django.db import models
+from django.db.models import *
+from core.models import Service, PlCoreBase, Slice, Instance, Tenant, TenantWithContainer, Node, Image, User, Flavor, TenantRoot, NetworkParameter, NetworkParameterType, Port, AddressPool, User
+from core.models.plcorebase import StrippedCharField
+import os
+from django.db import models, transaction
+from django.forms.models import model_to_dict
+from django.db.models import Q
+from operator import itemgetter, attrgetter, methodcaller
+from core.models import Tag
+from core.models.service import LeastLoadedNodeScheduler
+from services.vrouter.models import VRouterService, VRouterTenant
+import traceback
+from xos.exceptions import *
+from xos.config import Config
+
+class ConfigurationError(Exception):
+ pass
+
+CORD_SUBSCRIBER_KIND = "CordSubscriberRoot"
+
diff --git a/xos/header.py b/xos/header.py
new file mode 100644
index 0000000..afa4e4c
--- /dev/null
+++ b/xos/header.py
@@ -0,0 +1,21 @@
+from django.db import models
+from django.db.models import *
+from core.models import Service, PlCoreBase, Slice, Instance, Tenant, TenantWithContainer, Node, Image, User, Flavor, TenantRoot, NetworkParameter, NetworkParameterType, Port, AddressPool, User
+from core.models.plcorebase import StrippedCharField
+import os
+from django.db import models, transaction
+from django.forms.models import model_to_dict
+from django.db.models import Q
+from operator import itemgetter, attrgetter, methodcaller
+from core.models import Tag
+from core.models.service import LeastLoadedNodeScheduler
+from services.vrouter.models import VRouterService, VRouterTenant
+import traceback
+from xos.exceptions import *
+from xos.config import Config
+
+class ConfigurationError(Exception):
+ pass
+
+CORD_SUBSCRIBER_KIND = "CordSubscriberRoot"
+
diff --git a/xos/rcord-onboard.yaml b/xos/rcord-onboard.yaml
new file mode 100644
index 0000000..8e7dac5
--- /dev/null
+++ b/xos/rcord-onboard.yaml
@@ -0,0 +1,17 @@
+tosca_definitions_version: tosca_simple_yaml_1_0
+
+description: Onboard rcord models
+
+imports:
+ - custom_types/xos.yaml
+
+topology_template:
+ node_templates:
+ library#rcord:
+ type: tosca.nodes.ServiceController
+ properties:
+ base_url: file:///opt/cord/orchestration/profiles/rcord/xos/
+ # The following will concatenate with base_url automatically, if
+ # base_url is non-null.
+ xproto: ./
+ admin: admin.py
diff --git a/xos/rcord.xproto b/xos/rcord.xproto
new file mode 100644
index 0000000..f2e6ac8
--- /dev/null
+++ b/xos/rcord.xproto
@@ -0,0 +1,18 @@
+option name = "rcord";
+option verbose_name = "RCORD Profile";
+
+message CordSubscriberRoot (TenantRoot){
+ option kind = "CordSubscriberRoot";
+
+ required bool firewall_enable = 1 [default = False, null = False, db_index = False, blank = True];
+ optional string firewall_rules = 2 [default = "accept all anywhere anywhere", null = True, db_index = False, blank = True];
+ required bool url_filter_enable = 3 [default = False, null = False, db_index = False, blank = True];
+ optional string url_filter_rules = 4 [default = "allow all", null = True, db_index = False, blank = True];
+ required string url_filter_level = 5 [default = "PG", max_length = 30, content_type = "stripped", blank = False, null = False, db_index = False];
+ required bool cdn_enable = 6 [default = False, null = False, db_index = False, blank = True];
+ required bool is_demo_user = 7 [default = False, null = False, db_index = False, blank = True];
+ required int32 uplink_speed = 8 [default = 1000000000, null = False, db_index = False, blank = False];
+ required int32 downlink_speed = 9 [default = 1000000000, null = False, db_index = False, blank = False];
+ required bool enable_uverse = 10 [default = True, null = False, db_index = False, blank = True];
+ required string status = 11 [default = "enabled", choices = "(('enabled', 'Enabled'), ('suspended', 'Suspended'), ('delinquent', 'Delinquent'), ('copyrightviolation', 'Copyright Violation'))", max_length = 30, content_type = "stripped", blank = False, null = False, db_index = False];
+}