Improved misc admin interface

This commit is contained in:
Marc Aymerich 2016-05-07 10:32:51 +00:00
parent 202d1fd632
commit fed13217dc
6 changed files with 60 additions and 17 deletions

View file

@ -71,16 +71,16 @@ Quick Start
```bash
orchestra@panel:~ ssh-copy-id root@server.address
```
Then add the servers using the web interface `/admin/orchestration/servers`, check that the SSH connection is working and Orchestra can report the uptime of the servers.
Then add the servers using the web interface `/admin/orchestration/servers`, check that the SSH connection is working and Orchestra is able to report servers uptimes.
2. Configure the services, one at a time, staring with domains, databases, webapps, websites, ...
2. Configure your services, one at a time, staring with domains, databases, webapps, websites, ...
1. Add related [routes](orchestra/contrib/orchestration) via `/admin/orchestration/route/`
2. Configure related settings on `/admin/settings/setting/`
3. If required, configure related [resources](orchestra/contrib/resources) like Account disc limit, VPS traffic, etc `/resources/resource/`
3. Test creating and deleting service instances works as expected
3. If required, configure related [resources](orchestra/contrib/resources) like *account disk limit*, *VPS traffic*, etc `/resources/resource/`
3. Test if create and delete service instances works as expected
4. Do the same for the remaining services. You can disable services that you don't want by editing `INSTALLED_APPS` setting
3. Configure billing by adding [services](orchestra/contrib/services) `/admin/services/service/add/` and [plans](orchestra/contrib/plans) `/admin/plans/plan/`. Once a service is created hit the *Update orders* button to create orders for existing service instances.
3. Configure billing by adding [services](orchestra/contrib/services) `/admin/services/service/add/` and [plans](orchestra/contrib/plans) `/admin/plans/plan/`. Once a service is created hit the *Update orders* button to create orders for existing service instances, orders for new instances will be automatically created.

View file

@ -454,3 +454,9 @@ mkhomedir_helper or create ssh homes with bash.rc and such
# exclude from change list action, support for multiple exclusion
# breadcrumbs https://orchestra.pangea.org/admin/domains/domain/?account_id=930
with open(file) as handler:
os.unlink(file)
# change filter By PHP version: by detail

View file

@ -21,6 +21,7 @@ from .models import MiscService, Miscellaneous
class MiscServicePlugin(PluginModelAdapter):
model = MiscService
name_field = 'name'
plugin_field = 'service'
class MiscServiceAdmin(ExtendedModelAdmin):
@ -56,12 +57,16 @@ class MiscServiceAdmin(ExtendedModelAdmin):
return super(MiscServiceAdmin, self).formfield_for_dbfield(db_field, **kwargs)
class MiscellaneousAdmin(AccountAdminMixin, SelectPluginAdminMixin, admin.ModelAdmin):
class MiscellaneousAdmin(SelectPluginAdminMixin, AccountAdminMixin, ExtendedModelAdmin):
list_display = (
'__str__', 'service_link', 'amount', 'account_link', 'dispaly_active'
)
list_filter = ('service__name', 'is_active')
list_select_related = ('service', 'account')
readonly_fields = ('account_link', 'service_link')
add_fields = ('service', 'account', 'description', 'is_active')
fields = ('service_link', 'account', 'description', 'is_active')
change_readonly_fields = ('identifier', 'service')
search_fields = ('identifier', 'description', 'account__username')
actions = (disable, enable)
plugin_field = 'service'
@ -82,19 +87,26 @@ class MiscellaneousAdmin(AccountAdminMixin, SelectPluginAdminMixin, admin.ModelA
return obj.service
def get_fields(self, request, obj=None):
fields = ['account', 'description', 'is_active']
if obj is not None:
fields = ['account_link', 'description', 'is_active']
fields = super().get_fields(request, obj)
fields = list(fields)
service = self.get_service(obj)
if obj:
fields.insert(1, 'account_link')
if service.has_amount:
fields.insert(-1, 'amount')
if service.has_identifier:
fields.insert(1, 'identifier')
fields.insert(2, 'identifier')
return fields
def get_form(self, request, obj=None, **kwargs):
form = super(SelectPluginAdminMixin, self).get_form(request, obj, **kwargs)
if obj:
plugin = self.plugin.get(obj.service.name)()
else:
plugin = self.plugin.get(self.plugin_value)()
self.form = plugin.get_form()
self.plugin_instance = plugin
service = self.get_service(obj)
form = super(SelectPluginAdminMixin, self).get_form(request, obj, **kwargs)
def clean_identifier(self, service=service):
identifier = self.cleaned_data['identifier']
validator_path = settings.MISCELLANEOUS_IDENTIFIER_VALIDATORS.get(service.name, None)

View file

@ -55,7 +55,7 @@ class WebAppAdmin(SelectPluginAdminMixin, AccountAdminMixin, ExtendedModelAdmin)
)
list_filter = ('type', HasWebsiteListFilter, PHPVersionListFilter)
inlines = [WebAppOptionInline]
readonly_fields = ('account_link', )
readonly_fields = ('account_link',)
change_readonly_fields = ('name', 'type', 'display_websites')
search_fields = ('name', 'account__username', 'data', 'website__domains__name')
list_prefetch_related = ('content_set__website', 'content_set__website__domains')

View file

@ -1,20 +1,26 @@
from django import forms
from django.utils.encoding import force_text
from orchestra.admin.utils import admin_link
from orchestra.forms.widgets import SpanWidget
class PluginDataForm(forms.ModelForm):
data = forms.CharField(widget=forms.HiddenInput, required=False)
class PluginForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super(PluginDataForm, self).__init__(*args, **kwargs)
super().__init__(*args, **kwargs)
if self.plugin_field in self.fields:
value = self.plugin.get_name()
display = '%s <a href=".">change</a>' % force_text(self.plugin.verbose_name)
self.fields[self.plugin_field].widget = SpanWidget(original=value, display=display)
help_text = self.fields[self.plugin_field].help_text
self.fields[self.plugin_field].help_text = getattr(self.plugin, 'help_text', help_text)
class PluginDataForm(PluginForm):
data = forms.CharField(widget=forms.HiddenInput, required=False)
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
if self.instance:
for field in self.declared_fields:
initial = self.fields[field].initial
@ -37,7 +43,7 @@ class PluginDataForm(forms.ModelForm):
self.fields[field].widget = SpanWidget(original=value, display=display)
def clean(self):
super(PluginDataForm, self).clean()
super().clean()
data = {}
# Update data fields
for field in self.declared_fields:
@ -53,3 +59,15 @@ class PluginDataForm(forms.ModelForm):
except KeyError:
data[field] = value
self.cleaned_data['data'] = data
class PluginModelAdapterForm(PluginForm):
def __init__(self, *args, **kwargs):
super(PluginForm, self).__init__(*args, **kwargs)
if self.plugin_field in self.fields:
# Provide a link to the related DB object change view
value = self.plugin.related_instance.pk
link = admin_link()(self.plugin.related_instance)
display = '%s <a href=".">change</a>' % link
self.fields[self.plugin_field].widget = SpanWidget(original=value, display=display)
help_text = self.fields[self.plugin_field].help_text

View file

@ -15,6 +15,8 @@ class Plugin(object):
def __init__(self, instance=None):
# Related model instance of this plugin
self.instance = instance
from .forms import PluginForm
self.form = PluginForm
@classmethod
def get_name(cls):
@ -92,6 +94,11 @@ class PluginModelAdapter(Plugin):
model = None
name_field = None
def __init__(self, instance=None):
super().__init__(instance)
from .forms import PluginModelAdapterForm
self.form = PluginModelAdapterForm
@classmethod
def get_plugins(cls):
plugins = []