Merge remote-tracking branch 'origin/master' into reconcile_openstack
diff --git a/xos/ceilometer/admin.py b/xos/ceilometer/admin.py
index 8b6f469..8644ab7 100644
--- a/xos/ceilometer/admin.py
+++ b/xos/ceilometer/admin.py
@@ -11,6 +11,7 @@
 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
@@ -49,12 +50,18 @@
 
     def __init__(self,*args,**kwargs):

         super (MonitoringChannelForm,self ).__init__(*args,**kwargs)

-        self.fields['kind'].default = CEILOMETER_KIND

         self.fields['kind'].widget.attrs['readonly'] = True

         self.fields['provider_service'].queryset = CeilometerService.get_service_objects().all()

         if self.instance:

             # fields for the attributes

             self.fields['creator'].initial = self.instance.creator

+        if (not self.instance) or (not self.instance.pk):

+            # default fields for an 'add' form

+            self.fields['kind'].initial = CEILOMETER_KIND

+            self.fields['creator'].initial = get_request().user

+            if CeilometerService.get_service_objects().exists():

+               self.fields["provider_service"].initial = CeilometerService.get_service_objects().all()[0]

+

 

     def save(self, commit=True):

         self.instance.creator = self.cleaned_data.get("creator")

@@ -67,10 +74,10 @@
     list_display = ('backend_status_icon', 'id', )
     list_display_links = ('backend_status_icon', 'id')
     fieldsets = [ (None, {'fields': ['backend_status_text', 'kind', 'provider_service', 'service_specific_attribute',
-                                     'sliver',
-                                     'creator'],
+                                     'ceilometer_url', 'tenant_list_str',
+                                     'sliver', 'creator'],
                           'classes':['suit-tab suit-tab-general']})]
-    readonly_fields = ('backend_status_text', 'sliver', 'service_specific_attribute')
+    readonly_fields = ('backend_status_text', 'sliver', 'service_specific_attribute', 'ceilometer_url', 'tenant_list_str')
     form = MonitoringChannelForm
 
     suit_form_tabs = (('general','Details'),)
diff --git a/xos/ceilometer/models.py b/xos/ceilometer/models.py
index 2b2e990..ee5cbf9 100644
--- a/xos/ceilometer/models.py
+++ b/xos/ceilometer/models.py
@@ -8,6 +8,8 @@
 from operator import itemgetter, attrgetter, methodcaller
 import traceback
 from xos.exceptions import *
+from core.models import SlicePrivilege, SitePrivilege
+from sets import Set
 
 CEILOMETER_KIND = "ceilometer"
 
@@ -48,6 +50,67 @@
         self.cleanup_container()
         super(MonitoringChannel, self).delete(*args, **kwargs)
 
+    @property
+    def addresses(self):
+        if not self.sliver:
+            return {}
+
+        addresses = {}
+        for ns in self.sliver.ports.all():
+            if "private" in ns.network.name.lower():
+                addresses["private"] = (ns.ip, ns.mac)
+            elif "nat" in ns.network.name.lower():
+                addresses["nat"] = (ns.ip, ns.mac)
+            elif "ceilometer_client_access" in ns.network.labels.lower():
+                addresses["ceilometer"] = (ns.ip, ns.mac)
+        return addresses
+
+    @property
+    def private_ip(self):
+        return self.addresses.get("nat", (None, None))[0]
+
+    @property
+    def ceilometer_ip(self):
+        return self.addresses.get("ceilometer", (None, None))[0]
+
+    @property
+    def site_tenant_list(self):
+        tenant_ids = Set()
+        for sp in SitePrivilege.objects.filter(user=self.creator):
+            site = sp.site
+            for cs in site.controllersite.all():
+               if cs.tenant_id:
+                   tenant_ids.add(cs.tenant_id)
+        return tenant_ids
+
+    @property
+    def slice_tenant_list(self):
+        tenant_ids = Set()
+        for sp in SlicePrivilege.objects.filter(user=self.creator):
+            slice = sp.slice
+            for cs in slice.controllerslices.all():
+               if cs.tenant_id:
+                   tenant_ids.add(cs.tenant_id)
+        for slice in Slice.objects.filter(creator=self.creator):
+            for cs in slice.controllerslices.all():
+                if cs.tenant_id:
+                    tenant_ids.add(cs.tenant_id)
+        return tenant_ids
+
+    @property
+    def tenant_list(self):
+        return self.slice_tenant_list | self.site_tenant_list
+
+    @property
+    def tenant_list_str(self):
+        return ", ".join(self.tenant_list)
+
+    @property
+    def ceilometer_url(self):
+        if not self.ceilometer_ip:
+            return None
+        return "http://" + self.ceilometer_ip + "/uri/to/ceilometer/api/"
+
 def model_policy_monitoring_channel(pk):
     # TODO: this should be made in to a real model_policy
     with transaction.atomic():
diff --git a/xos/cord/admin.py b/xos/cord/admin.py
index 4c98750..6137212 100644
--- a/xos/cord/admin.py
+++ b/xos/cord/admin.py
@@ -11,6 +11,7 @@
 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
@@ -55,13 +56,18 @@
 
     def __init__(self,*args,**kwargs):

         super (VOLTTenantForm,self ).__init__(*args,**kwargs)

-        self.fields['kind'].default = "vOLT"

         self.fields['kind'].widget.attrs['readonly'] = True

         self.fields['provider_service'].queryset = VOLTService.get_service_objects().all()

         if self.instance:

             # fields for the attributes

             self.fields['vlan_id'].initial = self.instance.vlan_id

             self.fields['creator'].initial = self.instance.creator

+        if (not self.instance) or (not self.instance.pk):

+            # default fields for an 'add' form

+            self.fields['kind'].initial = VOLT_KIND

+            self.fields['creator'].initial = get_request().user

+            if VOLTService.get_service_objects().exists():

+               self.fields["provider_service"].initial = VOLTService.get_service_objects().all()[0]

 

     def save(self, commit=True):

         self.instance.vlan_id = self.cleaned_data.get("vlan_id")

@@ -157,7 +163,6 @@
 
     def __init__(self,*args,**kwargs):

         super (VCPETenantForm,self ).__init__(*args,**kwargs)

-        self.fields['kind'].default = "vCPE"

         self.fields['kind'].widget.attrs['readonly'] = True

         self.fields['provider_service'].queryset = VCPEService.get_service_objects().all()

         if self.instance:

@@ -166,6 +171,12 @@
             self.fields['creator'].initial = self.instance.creator

             self.fields['instance'].initial = self.instance.instance

             self.fields['last_ansible_hash'].initial = self.instance.last_ansible_hash

+        if (not self.instance) or (not self.instance.pk):

+            # default fields for an 'add' form

+            self.fields['kind'].initial = VCPE_KIND

+            self.fields['creator'].initial = get_request().user

+            if VCPEService.get_service_objects().exists():

+               self.fields["provider_service"].initial = VCPEService.get_service_objects().all()[0]

 

     def save(self, commit=True):

         self.instance.creator = self.cleaned_data.get("creator")

@@ -248,7 +259,6 @@
 
     def __init__(self,*args,**kwargs):

         super (VBNGTenantForm,self ).__init__(*args,**kwargs)

-        self.fields['kind'].default = "vBNG"

         self.fields['kind'].widget.attrs['readonly'] = True

         self.fields['provider_service'].queryset = VBNGService.get_service_objects().all()

         if self.instance:

@@ -257,6 +267,11 @@
             self.fields['mapped_hostname'].initial = self.instance.mapped_hostname

             self.fields['mapped_ip'].initial = self.instance.mapped_ip

             self.fields['mapped_mac'].initial = self.instance.mapped_mac

+        if (not self.instance) or (not self.instance.pk):

+            # default fields for an 'add' form

+            self.fields['kind'].initial = VBNG_KIND

+            if VBNGService.get_service_objects().exists():

+               self.fields["provider_service"].initial = VBNGService.get_service_objects().all()[0]

 

     def save(self, commit=True):

         self.instance.routeable_subnet = self.cleaned_data.get("routeable_subnet")

@@ -310,10 +325,12 @@
 
     def __init__(self,*args,**kwargs):

         super (CordSubscriberRootForm,self ).__init__(*args,**kwargs)

-        self.fields['kind'].default = CORD_SUBSCRIBER_KIND

         self.fields['kind'].widget.attrs['readonly'] = True

         if self.instance:

             self.fields['url_filter_level'].initial = self.instance.url_filter_level

+        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):

         self.instance.url_filter_level = self.cleaned_data.get("url_filter_level")

diff --git a/xos/tosca/samples/ceilometer.yaml b/xos/tosca/samples/ceilometer.yaml
index aeb4acb..9797d59 100644
--- a/xos/tosca/samples/ceilometer.yaml
+++ b/xos/tosca/samples/ceilometer.yaml
@@ -21,6 +21,22 @@
     Private:
       type: tosca.nodes.NetworkTemplate
 
+    ceilometer_network:
+      type: tosca.nodes.network.Network.XOS

+      properties:

+          ip_version: 4

+          labels: ceilometer_client_access

+      requirements:

+          - network_template:

+              node: Private

+              relationship: tosca.relationships.UsesNetworkTemplate

+          - owner:

+              node: mysite_ceilometer

+              relationship: tosca.relationships.MemberOfSlice

+          - connection:

+              node: mysite_ceilometer

+              relationship: tosca.relationships.ConnectsToSlice
+
     mysite:
       type: tosca.nodes.Site