Improved wordpressmu backend resiliance
This commit is contained in:
parent
0b30e0e9dd
commit
c10e8dd793
3
TODO.md
3
TODO.md
|
@ -467,3 +467,6 @@ with open(file) as handler:
|
||||||
|
|
||||||
|
|
||||||
# SAVE INISTIAL PASSWORD from all services, and just use it to create the service, never update it
|
# SAVE INISTIAL PASSWORD from all services, and just use it to create the service, never update it
|
||||||
|
|
||||||
|
|
||||||
|
# Don't use system groups for unixmailbackends
|
||||||
|
|
|
@ -3,7 +3,6 @@ from functools import partial
|
||||||
|
|
||||||
from django import forms
|
from django import forms
|
||||||
from django.contrib.admin import helpers
|
from django.contrib.admin import helpers
|
||||||
from django.contrib.auth.hashers import identify_hasher
|
|
||||||
from django.core import validators
|
from django.core import validators
|
||||||
from django.forms.models import modelformset_factory, BaseModelFormSet
|
from django.forms.models import modelformset_factory, BaseModelFormSet
|
||||||
from django.template import Template, Context
|
from django.template import Template, Context
|
||||||
|
@ -136,9 +135,11 @@ class AdminPasswordChangeForm(forms.Form):
|
||||||
ix = '_%i' % ix
|
ix = '_%i' % ix
|
||||||
password = self.cleaned_data.get('password%s' % ix)
|
password = self.cleaned_data.get('password%s' % ix)
|
||||||
if password:
|
if password:
|
||||||
|
# lazy loading because of passlib
|
||||||
|
from django.contrib.auth.hashers import identify_hasher
|
||||||
self.password_provided = True
|
self.password_provided = True
|
||||||
try:
|
try:
|
||||||
hasher = identify_hasher(password)
|
identify_hasher(password)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
raise forms.ValidationError(
|
raise forms.ValidationError(
|
||||||
self.error_messages['bad_hash'],
|
self.error_messages['bad_hash'],
|
||||||
|
@ -161,7 +162,7 @@ class AdminPasswordChangeForm(forms.Form):
|
||||||
password = self.cleaned_data[field_name]
|
password = self.cleaned_data[field_name]
|
||||||
if password:
|
if password:
|
||||||
if self.raw:
|
if self.raw:
|
||||||
self.password = password
|
self.user.password = password
|
||||||
else:
|
else:
|
||||||
self.user.set_password(password)
|
self.user.set_password(password)
|
||||||
if commit:
|
if commit:
|
||||||
|
|
|
@ -26,7 +26,7 @@ class MiscServicePlugin(PluginModelAdapter):
|
||||||
|
|
||||||
class MiscServiceAdmin(ExtendedModelAdmin):
|
class MiscServiceAdmin(ExtendedModelAdmin):
|
||||||
list_display = (
|
list_display = (
|
||||||
'name', 'verbose_name', 'num_instances', 'has_identifier', 'has_amount', 'is_active'
|
'display_name', 'display_verbose_name', 'num_instances', 'has_identifier', 'has_amount', 'is_active'
|
||||||
)
|
)
|
||||||
list_editable = ('is_active',)
|
list_editable = ('is_active',)
|
||||||
list_filter = ('has_identifier', 'has_amount', IsActiveListFilter)
|
list_filter = ('has_identifier', 'has_amount', IsActiveListFilter)
|
||||||
|
@ -37,6 +37,18 @@ class MiscServiceAdmin(ExtendedModelAdmin):
|
||||||
change_readonly_fields = ('name',)
|
change_readonly_fields = ('name',)
|
||||||
actions = (disable, enable)
|
actions = (disable, enable)
|
||||||
|
|
||||||
|
def display_name(self, misc):
|
||||||
|
return '<span title="%s">%s</span>' % (misc.description, misc.name)
|
||||||
|
display_name.short_description = _("name")
|
||||||
|
display_name.allow_tags = True
|
||||||
|
display_name.admin_order_field = 'name'
|
||||||
|
|
||||||
|
def display_verbose_name(self, misc):
|
||||||
|
return '<span title="%s">%s</span>' % (misc.description, misc.verbose_name)
|
||||||
|
display_verbose_name.short_description = _("verbose name")
|
||||||
|
display_verbose_name.allow_tags = True
|
||||||
|
display_verbose_name.admin_order_field = 'verbose_name'
|
||||||
|
|
||||||
def num_instances(self, misc):
|
def num_instances(self, misc):
|
||||||
""" return num slivers as a link to slivers changelist view """
|
""" return num slivers as a link to slivers changelist view """
|
||||||
num = misc.instances__count
|
num = misc.instances__count
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import re
|
import re
|
||||||
import sys
|
import sys
|
||||||
import textwrap
|
import textwrap
|
||||||
|
import time
|
||||||
from functools import partial
|
from functools import partial
|
||||||
from urllib.parse import urlparse
|
from urllib.parse import urlparse
|
||||||
|
|
||||||
|
@ -27,6 +28,15 @@ class WordpressMuController(ServiceController):
|
||||||
)
|
)
|
||||||
VERIFY = settings.SAAS_WORDPRESS_VERIFY_SSL
|
VERIFY = settings.SAAS_WORDPRESS_VERIFY_SSL
|
||||||
|
|
||||||
|
def with_retry(self, method, *args, retries=1, sleep=0.5, **kwargs):
|
||||||
|
for i in range(retries):
|
||||||
|
try:
|
||||||
|
return method(*args, **kwargs)
|
||||||
|
except requests.exceptions.ConnectionError:
|
||||||
|
if i >= retries:
|
||||||
|
raise
|
||||||
|
time.sleep(sleep)
|
||||||
|
|
||||||
def login(self, session):
|
def login(self, session):
|
||||||
main_url = self.get_main_url()
|
main_url = self.get_main_url()
|
||||||
login_url = main_url + '/wp-login.php'
|
login_url = main_url + '/wp-login.php'
|
||||||
|
@ -36,7 +46,7 @@ class WordpressMuController(ServiceController):
|
||||||
'redirect_to': '/wp-admin/'
|
'redirect_to': '/wp-admin/'
|
||||||
}
|
}
|
||||||
sys.stdout.write("Login URL: %s\n" % login_url)
|
sys.stdout.write("Login URL: %s\n" % login_url)
|
||||||
response = session.post(login_url, data=login_data, verify=self.VERIFY)
|
response = self.with_retry(session.post, login_url, data=login_data, verify=self.VERIFY)
|
||||||
if response.url != main_url + '/wp-admin/':
|
if response.url != main_url + '/wp-admin/':
|
||||||
raise IOError("Failure login to remote application (%s)" % login_url)
|
raise IOError("Failure login to remote application (%s)" % login_url)
|
||||||
|
|
||||||
|
@ -59,7 +69,7 @@ class WordpressMuController(ServiceController):
|
||||||
'class="edit">%s</a>' % saas.name
|
'class="edit">%s</a>' % saas.name
|
||||||
)
|
)
|
||||||
sys.stdout.write("Search URL: %s\n" % search)
|
sys.stdout.write("Search URL: %s\n" % search)
|
||||||
content = session.get(search, verify=self.VERIFY).content.decode('utf8')
|
content = self.with_retry(session.get, search, verify=self.VERIFY).content.decode('utf8')
|
||||||
# Get id
|
# Get id
|
||||||
ids = regex.search(content)
|
ids = regex.search(content)
|
||||||
if not ids and not blog_id:
|
if not ids and not blog_id:
|
||||||
|
@ -84,7 +94,7 @@ class WordpressMuController(ServiceController):
|
||||||
url = self.get_main_url()
|
url = self.get_main_url()
|
||||||
url += '/wp-admin/network/site-new.php'
|
url += '/wp-admin/network/site-new.php'
|
||||||
sys.stdout.write("Create URL: %s\n" % url)
|
sys.stdout.write("Create URL: %s\n" % url)
|
||||||
content = session.get(url, verify=self.VERIFY).content.decode('utf8')
|
content = self.with_retry(session.get, url, verify=self.VERIFY).content.decode('utf8')
|
||||||
|
|
||||||
wpnonce = re.compile('name="_wpnonce_add-blog"\s+value="([^"]*)"')
|
wpnonce = re.compile('name="_wpnonce_add-blog"\s+value="([^"]*)"')
|
||||||
try:
|
try:
|
||||||
|
@ -101,7 +111,7 @@ class WordpressMuController(ServiceController):
|
||||||
}
|
}
|
||||||
|
|
||||||
# Validate response
|
# Validate response
|
||||||
response = session.post(url, data=data, verify=self.VERIFY)
|
response = self.with_retry(session.post, url, data=data, verify=self.VERIFY)
|
||||||
self.validate_response(response)
|
self.validate_response(response)
|
||||||
blog_id = re.compile(r'<link id="wp-admin-canonical" rel="canonical" href="http(?:[^ ]+)/wp-admin/network/site-new.php\?id=([0-9]+)" />')
|
blog_id = re.compile(r'<link id="wp-admin-canonical" rel="canonical" href="http(?:[^ ]+)/wp-admin/network/site-new.php\?id=([0-9]+)" />')
|
||||||
content = response.content.decode('utf8')
|
content = response.content.decode('utf8')
|
||||||
|
@ -120,7 +130,7 @@ class WordpressMuController(ServiceController):
|
||||||
action_url = re.search(url_regex, content).groups()[0].replace("&", '&')
|
action_url = re.search(url_regex, content).groups()[0].replace("&", '&')
|
||||||
sys.stdout.write("%s confirm URL: %s\n" % (action, action_url))
|
sys.stdout.write("%s confirm URL: %s\n" % (action, action_url))
|
||||||
|
|
||||||
content = session.get(action_url, verify=self.VERIFY).content.decode('utf8')
|
content = self.with_retry(session.get, action_url, verify=self.VERIFY).content.decode('utf8')
|
||||||
wpnonce = re.compile('name="_wpnonce"\s+value="([^"]*)"')
|
wpnonce = re.compile('name="_wpnonce"\s+value="([^"]*)"')
|
||||||
try:
|
try:
|
||||||
wpnonce = wpnonce.search(content).groups()[0]
|
wpnonce = wpnonce.search(content).groups()[0]
|
||||||
|
@ -135,7 +145,7 @@ class WordpressMuController(ServiceController):
|
||||||
action_url = self.get_main_url()
|
action_url = self.get_main_url()
|
||||||
action_url += '/wp-admin/network/sites.php?action=%sblog' % action
|
action_url += '/wp-admin/network/sites.php?action=%sblog' % action
|
||||||
sys.stdout.write("%s URL: %s\n" % (action, action_url))
|
sys.stdout.write("%s URL: %s\n" % (action, action_url))
|
||||||
response = session.post(action_url, data=data, verify=self.VERIFY)
|
response = self.with_retry(session.post, action_url, data=data, verify=self.VERIFY)
|
||||||
self.validate_response(response)
|
self.validate_response(response)
|
||||||
|
|
||||||
def is_active(self, content):
|
def is_active(self, content):
|
||||||
|
|
Loading…
Reference in a new issue