refactor
[plstackapi.git] / planetstack / core / admin.py
index ffa21d9..d1e4cd0 100644 (file)
@@ -426,7 +426,7 @@ class SiteDeploymentsInline(PlStackTabularInline):
     model = SiteDeployments
     extra = 0
     suit_classes = 'suit-tab suit-tab-deployments'
-    fields = ['backend_status_icon', 'deployment','site']
+    fields = ['backend_status_icon', 'deployment','site', 'controller']
     readonly_fields = ('backend_status_icon', )
 
     def formfield_for_foreignkey(self, db_field, request, **kwargs):
@@ -435,28 +435,14 @@ class SiteDeploymentsInline(PlStackTabularInline):
 
         if db_field.name == 'deployment':
             kwargs['queryset'] = Deployment.select_by_user(request.user)
-        return super(SiteDeploymentsInline, self).formfield_for_foreignkey(db_field, request, **kwargs)
-
-    def queryset(self, request):
-        return SiteDeployments.select_by_user(request.user)
-
-class ControllerSitesInline(PlStackTabularInline):
-    model = ControllerSites
-    extra = 0
-    suit_classes = 'suit-tab suit-tab-admin-only'
-    fields = ['backend_status_icon', 'controller','site']
-    readonly_fields = ('backend_status_icon', )
-
-    def formfield_for_foreignkey(self, db_field, request, **kwargs):
-        if db_field.name == 'site':
-            kwargs['queryset'] = Site.select_by_user(request.user)
 
         if db_field.name == 'controller':
             kwargs['queryset'] = Controller.select_by_user(request.user)
-        return super(ControllerSitesInline, self).formfield_for_foreignkey(db_field, request, **kwargs)
+
+        return super(SiteDeploymentsInline, self).formfield_for_foreignkey(db_field, request, **kwargs)
 
     def queryset(self, request):
-        return ControllerSites.select_by_user(request.user)
+        return SiteDeployments.select_by_user(request.user)
 
 
 class SlicePrivilegeInline(PlStackTabularInline):
@@ -646,6 +632,96 @@ class DeploymentAdmin(PlanetStackBaseAdmin):
 
         return AdminFormMetaClass
 
+class ControllerAdminForm(forms.ModelForm):
+    site_deployments = forms.ModelMultipleChoiceField(
+        queryset=SiteDeployment.objects.all(),
+        required=False,
+        help_text="Select which sites deployments are managed by this controller",
+        widget=FilteredSelectMultiple(
+            verbose_name=('Site Deployments'), is_stacked=False
+        )
+    )
+
+    class Meta: 
+        model = Controller
+        
+    def __init__(self, *args, **kwds):
+        request = kwargs.pop('request', None)
+        super(ControllerAdminForm, self).__init__(*args, **kwargs)  
+
+        if self.instance and self.instance.pk:
+            self.fields['site_deployments'].initial = [x.site_deployment for x in self.instance.controllersitedeployments.all()]
+
+        def manipulate_m2m_objs(self, this_obj, selected_objs, all_relations, relation_class, local_attrname, foreign_attrname):
+        """ helper function for handling m2m relations from the MultipleChoiceField
+            this_obj: the source object we want to link from
+            selected_objs: a list of destination objects we want to link to
+            all_relations: the full set of relations involving this_obj, including ones we don't want
+            relation_class: the class that implements the relation from source to dest
+            local_attrname: field name representing this_obj in relation_class
+            foreign_attrname: field name representing selected_objs in relation_class
+            This function will remove all newobjclass relations from this_obj
+            that are not contained in selected_objs, and add any relations that
+            are in selected_objs but don't exist in the data model yet.
+        """
+        existing_dest_objs = []
+        for relation in list(all_relations):
+            if getattr(relation, foreign_attrname) not in selected_objs:
+                #print "deleting site", sdp.site
+                relation.delete()
+            else:
+                existing_dest_objs.append(getattr(relation, foreign_attrname))
+
+        for dest_obj in selected_objs:
+            if dest_obj not in existing_dest_objs:
+                #print "adding site", site
+                kwargs = {foreign_attrname: dest_obj, local_attrname: this_obj}
+                relation = relation_class(**kwargs)
+                relation.save()
+
+        def save(self, commit=True):
+            controller = super(ControllerAdminForm, self).save(commit=False)
+
+            if commit:
+                controller.save()
+
+            if controller.pk:
+                # save_m2m() doesn't seem to work with 'through' relations. So we
+                #    create/destroy the through models ourselves. There has to be
+                #    a better way...
+            self.manipulate_m2m_objs(controller, self.cleaned_data['site_deployments'], controller.controllersitedeployments.all(), ControllerSiteDeployments, "controller", "site_deployment")
+
+            self.save_m2m()
+
+            return controller 
+      
+class ControllerAdmin(PlanetStackBaseAdmin):
+    model = Controller 
+    fieldList = ['name', 'version', 'backend_type', 'auth_url', 'admin_user', 'admin_tenant',]
+    fieldsets = [(None, {'fields': fieldList, 'classes':['suit-tab suit-tab-admin-only']})]
+    inlines = [ControllerPrivilegeInline, ContrllerSiteInline] # ,ControllerImagesInline]
+    list_display = ['backend_status_icon', 'name', 'version', 'backend_type']
+    list_display_links = ('backend_status_icon', 'name', )
+    readonly_fields = ('backend_status_text',)
+
+    user_readonly_fields = []
+
+    def get_form(self, request, obj=None, **kwargs):
+        if request.user.isReadOnlyUser():
+            kwargs["form"] = ControllerAdminROForm
+        else:
+            kwargs["form"] = ControllerAdminForm
+        adminForm = super(DeploymentAdmin,self).get_form(request, obj, **kwargs)
+
+        # from stackexchange: pass the request object into the form
+
+        class AdminFormMetaClass(adminForm):
+           def __new__(cls, *args, **kwargs):
+               kwargs['request'] = request
+               return adminForm(*args, **kwargs)
+
+        return AdminFormMetaClass
+
 class ServiceAttrAsTabInline(PlStackTabularInline):
     model = ServiceAttribute
     fields = ['name','value']