Improved VPS backend

This commit is contained in:
Marc Aymerich 2015-09-21 13:57:15 +00:00
parent 760d6956de
commit d6925abd72
7 changed files with 74 additions and 50 deletions

View File

@ -124,16 +124,12 @@ require_once(/etc/moodles/.$moodle_host.config.php);``` moodle/drupl
* make account available on all admin forms
# WPMU blog traffic
* more robust backend error handling, continue executing but exit code > 0 if failure: failing_cmd || exit_code=1 and don't forget to call super.commit()!!
* website directives uniquenes validation on serializers
+ is_Active custom filter with support for instance.account.is_Active annotate with F() needed (django 1.8)
# delete apache logs and php logs
* document service help things: discount/refound/compensation effect and metric table
* Document metric interpretation help_text
* document plugin serialization, data_serializer?
@ -385,8 +381,6 @@ Case
# Mailer: mark as sent
# Implement wordpressmu change password or remove password from the form
# Deprecate orchestra start/stop/restart services management commands?
# Enable/disable ignore period orders list filter

View File

@ -236,45 +236,50 @@ class ChangePasswordAdminMixin(object):
name='%s_%s_change_password' % info)
] + super(ChangePasswordAdminMixin, self).get_urls()
def get_change_password_username(self, obj):
return str(obj)
@sensitive_post_parameters_m
def change_password(self, request, id, form_url=''):
if not self.has_change_permission(request):
raise PermissionDenied
# TODO use this insetad of self.get_object(), in other places
user = get_object_or_404(self.get_queryset(request), pk=id)
obj = get_object_or_404(self.get_queryset(request), pk=id)
related = []
for obj_name_attr in ('username', 'name', 'hostname'):
try:
# don't know why getattr(user, 'username', user.name) doesn't work
username = user.username
obj_name = getattr(obj, obj_name_attr)
except AttributeError:
username = user.name
if hasattr(user, 'account'):
account = user.account
if user.account.username == username:
related.append(user.account)
pass
else:
account = user
if account.username == username:
break
if hasattr(obj, 'account'):
account = obj.account
if obj.account.username == obj_name:
related.append(obj.account)
else:
account = obj
if account.username == obj_name:
for rel in account.get_related_passwords():
if not isinstance(user, type(rel)):
if not isinstance(obj, type(rel)):
related.append(rel)
if request.method == 'POST':
form = self.change_password_form(user, request.POST, related=related)
form = self.change_password_form(obj, request.POST, related=related)
if form.is_valid():
form.save()
change_message = self.construct_change_message(request, form, None)
self.log_change(request, user, change_message)
self.log_change(request, obj, change_message)
msg = _('Password changed successfully.')
messages.success(request, msg)
update_session_auth_hash(request, form.user) # This is safe
return HttpResponseRedirect('..')
else:
form = self.change_password_form(user, related=related)
form = self.change_password_form(obj, related=related)
fieldsets = [
(user._meta.verbose_name.capitalize(), {
(obj._meta.verbose_name.capitalize(), {
'classes': ('wide',),
'fields': ('password1', 'password2')
}),
@ -285,9 +290,10 @@ class ChangePasswordAdminMixin(object):
'fields': ('password1_%i' % ix, 'password2_%i' % ix)
}))
obj_username = self.get_change_password_username(obj)
adminForm = admin.helpers.AdminForm(form, fieldsets, {})
context = {
'title': _('Change password: %s') % escape(username),
'title': _('Change password: %s') % obj_username,
'adminform': adminForm,
'errors': admin.helpers.AdminErrorList(form, []),
'form_url': form_url,
@ -299,7 +305,8 @@ class ChangePasswordAdminMixin(object):
'has_change_permission': True,
'has_absolute_url': False,
'opts': self.model._meta,
'original': user,
'original': obj,
'obj_username': obj_username,
'save_as': False,
'show_save': True,
'password': random_ascii(10),

View File

@ -19,6 +19,7 @@ class WordPressForm(SaaSBaseForm):
help_text = 'Admin URL: <a href="{0}">{0}</a>'.format(admin_url)
self.fields['site_url'].help_text = mark_safe(help_text)
class WordPressDataSerializer(serializers.Serializer):
email = serializers.EmailField(label=_("Email"))

View File

@ -3,7 +3,7 @@ from django.contrib import admin
from django.contrib.auth.admin import UserAdmin
from django.utils.translation import ugettext_lazy as _
from orchestra.admin import ExtendedModelAdmin
from orchestra.admin import ExtendedModelAdmin, ChangePasswordAdminMixin
from orchestra.contrib.accounts.actions import list_accounts
from orchestra.contrib.accounts.admin import AccountAdminMixin
from orchestra.forms import UserCreationForm, NonStoredUserChangeForm
@ -11,7 +11,7 @@ from orchestra.forms import UserCreationForm, NonStoredUserChangeForm
from .models import VPS
class VPSAdmin(AccountAdminMixin, ExtendedModelAdmin):
class VPSAdmin(ChangePasswordAdminMixin, AccountAdminMixin, ExtendedModelAdmin):
list_display = ('hostname', 'type', 'template', 'account_link')
list_filter = ('type', 'template')
form = NonStoredUserChangeForm
@ -40,12 +40,8 @@ class VPSAdmin(AccountAdminMixin, ExtendedModelAdmin):
)
actions = (list_accounts,)
def get_urls(self):
useradmin = UserAdmin(VPS, self.admin_site)
return [
url(r'^(\d+)/password/$',
self.admin_site.admin_view(useradmin.user_change_password))
] + super(VPSAdmin, self).get_urls()
def get_change_password_username(self, obj):
return 'root@%s' % obj.hostname
admin.site.register(VPS, VPSAdmin)

View File

@ -4,6 +4,8 @@ import textwrap
from orchestra.contrib.orchestration import ServiceController
from orchestra.contrib.resources import ServiceMonitor
from . import settings
class ProxmoxOVZ(ServiceController):
model = 'vps.VPS'
@ -34,39 +36,58 @@ class ProxmoxOVZ(ServiceController):
super(ProxmoxOVZ, self).prepare()
self.append(self.GET_PROXMOX_INFO)
def get_vzset_args(self, vps):
args = []
def get_vzset_args(self, context):
args = list(settings.VPS_DEFAULT_VZSET_ARGS)
for resource, arg_name in self.RESOURCES:
try:
allocation = getattr(vps.resources, resource).allocated
except AttributeError:
allocation = context[resource]
except KeyError:
pass
else:
args.append('--%s %i' % (arg_name, allocation))
return ' '.join(args)
def run_ssh_commands(self, ssh_commands):
commands = '\n '.join(ssh_commands)
self.append(textwrap.dedent("""\
cat << EOF | ssh root@${info[1]}
%s
EOF""") % commands
)
def save(self, vps):
# TODO create the container
context = self.get_context(vps)
self.append('info=( $(get_vz_info %(hostname)s) )' % context)
vzset_args = self.get_vzset_args(vps)
self.append(textwrap.dedent("""
info=( $(get_vz_info %(hostname)s) )
echo "Managing ${info[@]}"\
""") % context
)
ssh_commands = []
vzset_args = self.get_vzset_args(context)
if vzset_args:
context['vzset_args'] = vzset_args
self.append(textwrap.dedent("""\
cat << EOF | ssh root@${info[1]}
pvectl vzset ${info[0]} %(vzset_args)s
EOF""") % context
)
ssh_commands.append("pvectl vzset ${info[0]} %(vzset_args)s" % context)
if hasattr(vps, 'password'):
context['password'] = vps.password.replace('$', '\\$')
self.append(textwrap.dedent("""\
cat << EOF | ssh root@${info[1]}
echo 'root:%(password)s' | vzctl exec ${info[0]} chpasswd -e
EOF""") % context
ssh_commands.append(textwrap.dedent("""\
echo 'root:%(password)s' \\
| chroot /var/lib/vz/private/${info[0]} chpasswd -e""") % context
)
self.run_ssh_commands(ssh_commands)
def get_context(self, vps):
return {
context = {
'hostname': vps.hostname,
}
for resource, __ in self.RESOURCES:
try:
allocation = getattr(vps.resources, resource).allocated
except AttributeError:
pass
else:
context[resource] = allocation
return context
# TODO rename to proxmox

View File

@ -27,3 +27,8 @@ VPS_DEFAULT_TEMPLATE = Setting('VPS_DEFAULT_TEMPLATE',
'debian7',
choices=VPS_TEMPLATES
)
VPS_DEFAULT_VZSET_ARGS = Setting('VPS_DEFAULT_VZSET_ARGS',
('--onboot yes',),
)

View File

@ -8,7 +8,7 @@
<div>
{% if is_popup %}<input type="hidden" name="{{ is_popup_var }}" value="1" />{% endif %}
{% if to_field %}<input type="hidden" name="{{ to_field_var }}" value="{{ to_field }}" />{% endif %}
<p>{% blocktrans with username=original %}Enter a new password for the user <strong>{{ username }}</strong>, suggestion '{{ password }}'.{% endblocktrans %}</p>
<p>{% blocktrans with username=obj_username %}Enter a new password for the user <strong>{{ username }}</strong>, suggestion '{{ password }}'.{% endblocktrans %}</p>
{% if errors %}
<p class="errornote">