From 8cce7b58f6bab545ee347b22fb1c88e25053ca5b Mon Sep 17 00:00:00 2001 From: root Date: Wed, 5 Nov 2014 21:29:14 +0000 Subject: [PATCH] Improved performance on domain admin --- TODO.md | 26 ++++---------------------- orchestra/apps/domains/admin.py | 13 +++++++++---- orchestra/apps/domains/forms.py | 2 +- orchestra/apps/domains/models.py | 2 +- 4 files changed, 15 insertions(+), 28 deletions(-) diff --git a/TODO.md b/TODO.md index 18bdabf1..76dd02cc 100644 --- a/TODO.md +++ b/TODO.md @@ -159,45 +159,30 @@ Remember that, as always with QuerySets, any subsequent chained methods which im * Resource monitoring without ROUTE alert or explicit error - * Domain validation has to be done with injected records and subdomains * Names: lower andupper case allow or disallow ? webapps/account.username etc * Split plans into a separate app (plans and rates / services ) ? -* reconsider binding webapps to systemusers (pangea multiple users wordpress-ftp, moodle-pangea, etc) - * sync() ServiceController method that synchronizes orchestra and servers (delete or import) * validate address.forward: if mailbox in account.mailboxes then: _("Please use mailboxes field") or consider removing mailbox support on forward (user@pangea.org instead) -* reespell systemuser to system_user -* remove order in account admin and others -* create admin prefetch_related on ExtendedModelAdmin +* reespell systemuser to system_user + +* remove order in account admin and others admininlines * Databases.User add reverse M2M databases widget (like mailbox.addresses) -* One domain zone validation for each save, not one per subdomain, maybe on modeladmin.save_related? prevent save on model_related, and save it on save_related() - * Change permissions periodically on the web server, to ensure security -* Apache RLimit ? - -* Patch suexec: if user mismatch, check user belongs to suexecusergroup group - -* fuck suexec http://www.litespeedtech.com/support/forum/threads/solved-cloudlinux-php-lsapi-say-no-to-suexec.5812/ - -* http://mail-archives.apache.org/mod_mbox/httpd-dev/201409.mbox/%3C5411FFBE.9050506@loginroot.com%3E ?? - * Root owned logs on user's home ? - +* reconsider binding webapps to systemusers (pangea multiple users wordpress-ftp, moodle-pangea, etc) * Secondary user home in /home/secondaryuser and simlink to /home/main/webapps/app so it can have private storage? - * Grant permissions like in webfaction - * Secondaryusers home should be under mainuser home. i.e. /home/mainuser/webapps/seconduser_webapp/ * Make one dedicated CGI user for each account only for CGI execution (fpm/fcgid). Different from the files owner, and without W permissions, so attackers can not inject backdors and malware. * In most cases we can prevent the creation of files for the CGI users, preventing attackers to upload and executing PHPShells. @@ -209,6 +194,3 @@ Remember that, as always with QuerySets, any subsequent chained methods which im * resource min max allocation with validation * mailman needs both aliases when address_name is provided (default messages and bounces and all) - -* specify field on ValidationError under model.clean() of form.clean(): ValidationError({'bark_volume': ["Must be louder!",]} - * And raise ValidationError once at the end collecting all errors at once diff --git a/orchestra/apps/domains/admin.py b/orchestra/apps/domains/admin.py index bea4093e..adbed919 100644 --- a/orchestra/apps/domains/admin.py +++ b/orchestra/apps/domains/admin.py @@ -4,7 +4,7 @@ from django import forms from django.contrib import admin from django.utils.translation import ugettext_lazy as _ -from orchestra.admin import ChangeListDefaultFilter, ExtendedModelAdmin +from orchestra.admin import ExtendedModelAdmin from orchestra.admin.utils import admin_link, change_url from orchestra.apps.accounts.admin import AccountAdminMixin from orchestra.utils import apps @@ -46,14 +46,19 @@ class DomainInline(admin.TabularInline): account_link = admin_link('account') def display_records(self, domain): - return ', '.join(domain.records.values_list('type', flat=True)) + return ', '.join([record.type for record in domain.records.all()]) display_records.short_description = _("Declared records") def has_add_permission(self, *args, **kwargs): return False + + def get_queryset(self, request): + """ Order by structured name and imporve performance """ + qs = super(DomainInline, self).get_queryset(request) + return qs.select_related('account').prefetch_related('records') -class DomainAdmin(ChangeListDefaultFilter, AccountAdminMixin, ExtendedModelAdmin): +class DomainAdmin(AccountAdminMixin, ExtendedModelAdmin): list_display = ( 'structured_name', 'display_is_top', 'websites', 'account_link' ) @@ -99,7 +104,7 @@ class DomainAdmin(ChangeListDefaultFilter, AccountAdminMixin, ExtendedModelAdmin def get_queryset(self, request): """ Order by structured name and imporve performance """ qs = super(DomainAdmin, self).get_queryset(request) - qs = qs.select_related('top') + qs = qs.select_related('top', 'account') # For some reason if we do this we know for sure that join table will be called T4 query = str(qs.query) table = re.findall(r'(T\d+)\."account_id"', query)[0] diff --git a/orchestra/apps/domains/forms.py b/orchestra/apps/domains/forms.py index 80be59a5..072a211a 100644 --- a/orchestra/apps/domains/forms.py +++ b/orchestra/apps/domains/forms.py @@ -68,8 +68,8 @@ class CreateDomainAdminForm(forms.ModelForm): # self.save_formset(request, form, formset, change=change) -# TODO do it in admin class RecordInlineFormSet(forms.models.BaseInlineFormSet): + # TODO def clean(self): """ Checks if everything is consistent """ if any(self.errors): diff --git a/orchestra/apps/domains/models.py b/orchestra/apps/domains/models.py index 27d4a375..71b1c540 100644 --- a/orchestra/apps/domains/models.py +++ b/orchestra/apps/domains/models.py @@ -62,7 +62,7 @@ class Domain(models.Model): def render_zone(self): origin = self.origin zone = origin.render_records() - for subdomain in origin.get_subdomains(): + for subdomain in origin.get_subdomains().prefetch_related('records'): zone += subdomain.render_records() return zone