Random fixes
This commit is contained in:
parent
e5e0d3aa96
commit
7711988a63
8
TODO.md
8
TODO.md
|
@ -206,6 +206,12 @@ Php binaries should have this format: /usr/bin/php5.2-cgi
|
|||
|
||||
* better validate options and directives (url locations, filesystem paths, etc..)
|
||||
* filter php deprecated options out based on version
|
||||
* order virtualhost locations /hola / including directive
|
||||
|
||||
* make sure that you understand the risks
|
||||
|
||||
|
||||
* full support for deactivation of services/accounts
|
||||
* Display admin.is_active (disabled account/order by)
|
||||
|
||||
|
||||
* show details data on webapp changelist
|
||||
|
|
|
@ -79,13 +79,7 @@ class Account(auth.AbstractBaseUser):
|
|||
# Trigger save() on related objects that depend on this account
|
||||
for rel in self._meta.get_all_related_objects():
|
||||
source = getattr(rel, 'related_model', rel.model)
|
||||
if not source in services:
|
||||
continue
|
||||
try:
|
||||
source._meta.get_field_by_name('is_active')
|
||||
except models.FieldDoesNotExist:
|
||||
continue
|
||||
else:
|
||||
if source in services and hasattr(source, 'active'):
|
||||
for obj in getattr(self, rel.get_accessor_name()).all():
|
||||
obj.save(update_fields=[])
|
||||
|
||||
|
|
|
@ -46,7 +46,7 @@ class MailmanBackend(ServiceController):
|
|||
self.append('sed -i "/^%(address_domain)s\s*$/d" %(virtual_alias_domains)s' % context)
|
||||
|
||||
def get_virtual_aliases(self, context):
|
||||
aliases = []
|
||||
aliases = ['# %(banner)s' % context]
|
||||
for address in self.addresses:
|
||||
context['address'] = address
|
||||
aliases.append("%(address_name)s%(address)s@%(domain)s\t%(name)s%(address)s" % context)
|
||||
|
@ -65,15 +65,13 @@ class MailmanBackend(ServiceController):
|
|||
# Preserve indentation
|
||||
self.append(textwrap.dedent("""\
|
||||
if [[ ! $(grep '\s\s*%(name)s\s*$' %(virtual_alias)s) ]]; then
|
||||
echo '# %(banner)s\n%(aliases)s
|
||||
' >> %(virtual_alias)s
|
||||
echo '%(aliases)s' >> %(virtual_alias)s
|
||||
UPDATED_VIRTUAL_ALIAS=1
|
||||
else
|
||||
if [[ ! $(grep '^\s*%(address_name)s@%(address_domain)s\s\s*%(name)s\s*$' %(virtual_alias)s) ]]; then
|
||||
sed -i -e '/^.*\s%(name)s\(%(address_regex)s\)\s*$/d' \\
|
||||
-e 'N; /^\s*\\n\s*$/d; P; D' %(virtual_alias)s
|
||||
echo '# %(banner)s\n%(aliases)s
|
||||
' >> %(virtual_alias)s
|
||||
echo '%(aliases)s' >> %(virtual_alias)s
|
||||
UPDATED_VIRTUAL_ALIAS=1
|
||||
fi
|
||||
fi""") % context
|
||||
|
@ -99,15 +97,19 @@ class MailmanBackend(ServiceController):
|
|||
'%(mailman_root)s/bin/change_pw --listname="%(name)s" --password="%(password)s"' % context
|
||||
)
|
||||
self.include_virtual_alias_domain(context)
|
||||
if mail_list.active:
|
||||
self.append('chmod 775 %(mailman_root)s/lists/%(name)s' % context)
|
||||
else:
|
||||
self.append('chmod 000 %(mailman_root)s/lists/%(name)s' % context)
|
||||
|
||||
def delete(self, mail_list):
|
||||
context = self.get_context(mail_list)
|
||||
self.exclude_virtual_alias_domain(context)
|
||||
self.append(textwrap.dedent("""\
|
||||
self.append(textwrap.dedent("""
|
||||
sed -i -e '/^.*\s%(name)s\(%(address_regex)s\)\s*$/d' \\
|
||||
-e 'N; /^\s*\\n\s*$/d; P; D' %(virtual_alias)s""") % context
|
||||
)
|
||||
self.append(textwrap.dedent("""\
|
||||
self.append(textwrap.dedent("""
|
||||
# Non-existent list archives produce exit code 1
|
||||
exit_code=0
|
||||
rmlist -a %(name)s || exit_code=$?
|
||||
|
@ -119,9 +121,12 @@ class MailmanBackend(ServiceController):
|
|||
def commit(self):
|
||||
context = self.get_context_files()
|
||||
self.append(textwrap.dedent("""
|
||||
[[ $UPDATED_VIRTUAL_ALIAS == 1 ]] && { postmap %(virtual_alias)s; }
|
||||
[[ $UPDATED_VIRTUAL_ALIAS_DOMAINS == 1 ]] && { /etc/init.d/postfix reload; }
|
||||
""") % context
|
||||
if [[ $UPDATED_VIRTUAL_ALIAS == 1 ]]; then
|
||||
postmap %(virtual_alias)s
|
||||
fi
|
||||
if [[ $UPDATED_VIRTUAL_ALIAS_DOMAINS == 1 ]]; then
|
||||
/etc/init.d/postfix reload
|
||||
fi""") % context
|
||||
)
|
||||
|
||||
def get_context_files(self):
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
from django.db import models
|
||||
from django.utils.functional import cached_property
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from orchestra.core import services
|
||||
|
@ -20,7 +21,10 @@ class List(models.Model):
|
|||
help_text=_("Administration email address"))
|
||||
account = models.ForeignKey('accounts.Account', verbose_name=_("Account"),
|
||||
related_name='lists')
|
||||
|
||||
# TODO also admin
|
||||
# TODO is_active = models.BooleanField(_("active"), default=True,
|
||||
# help_text=_("Designates whether this account should be treated as active. "
|
||||
# "Unselect this instead of deleting accounts."))
|
||||
password = None
|
||||
|
||||
class Meta:
|
||||
|
@ -35,6 +39,10 @@ class List(models.Model):
|
|||
return "%s@%s" % (self.address_name, self.address_domain)
|
||||
return ''
|
||||
|
||||
@cached_property
|
||||
def active(self):
|
||||
return self.is_active and self.account.is_active
|
||||
|
||||
def get_address_name(self):
|
||||
return self.address_name or self.name
|
||||
|
||||
|
|
|
@ -21,16 +21,13 @@ def compute_resource_usage(data):
|
|||
slot = (data.created_at-ini).total_seconds()
|
||||
result += data.value * slot/total
|
||||
ini = data.created_at
|
||||
elif resource.period == resource.MONTHLY_SUM:
|
||||
elif resource.period in (resource.MONTHLY_SUM, resource.LAST):
|
||||
# FIXME Aggregation of 0s returns None! django bug?
|
||||
# value = dataset.aggregate(models.Sum('value'))['value__sum']
|
||||
values = dataset.values_list('value', flat=True)
|
||||
if values:
|
||||
has_result = True
|
||||
result += sum(values)
|
||||
elif resource.period == resource.LAST:
|
||||
result += dataset.value
|
||||
has_result = True
|
||||
else:
|
||||
raise NotImplementedError("%s support not implemented" % data.period)
|
||||
return float(result)/resource.get_scale() if has_result else None
|
||||
|
|
|
@ -239,8 +239,11 @@ class ResourceData(models.Model):
|
|||
)
|
||||
)
|
||||
elif resource.period == resource.LAST:
|
||||
# Get last monitoring data per object_id
|
||||
try:
|
||||
datasets.append(dataset.latest())
|
||||
datasets.append(
|
||||
dataset.order_by('object_id', '-id').distinct('object_id')
|
||||
)
|
||||
except MonitorData.DoesNotExist:
|
||||
continue
|
||||
else:
|
||||
|
|
|
@ -30,7 +30,7 @@ def monitor(resource_id, ids=None, async=True):
|
|||
op = Operation.create(backend, obj, Operation.MONITOR)
|
||||
operations.append(op)
|
||||
monitorings.append(op)
|
||||
# TODO async=TRue only when running with celery
|
||||
# TODO async=True only when running with celery
|
||||
Operation.execute(monitorings, async=async)
|
||||
|
||||
kwargs = {'id__in': ids} if ids else {}
|
||||
|
|
|
@ -24,7 +24,8 @@ class WebApp(models.Model):
|
|||
choices=AppType.get_plugin_choices())
|
||||
account = models.ForeignKey('accounts.Account', verbose_name=_("Account"),
|
||||
related_name='webapps')
|
||||
data = JSONField(_("data"), help_text=_("Extra information dependent of each service."))
|
||||
data = JSONField(_("data"), blank=True,
|
||||
help_text=_("Extra information dependent of each service."))
|
||||
|
||||
class Meta:
|
||||
unique_together = ('name', 'account')
|
||||
|
@ -122,4 +123,7 @@ def type_save(sender, *args, **kwargs):
|
|||
@receiver(pre_delete, sender=WebApp, dispatch_uid='webapps.type.delete')
|
||||
def type_delete(sender, *args, **kwargs):
|
||||
instance = kwargs['instance']
|
||||
instance.type_instance.delete()
|
||||
try:
|
||||
instance.type_instance.delete()
|
||||
except KeyError:
|
||||
pass
|
||||
|
|
|
@ -336,8 +336,8 @@ class PHPUploadMaxFileSize(AppOption):
|
|||
group = AppOption.PHP
|
||||
|
||||
|
||||
class PHPPostMaxSize(AppOption):
|
||||
name = 'post_max_size'
|
||||
verbose_name = _("zend_extension")
|
||||
class PHPZendExtension(AppOption):
|
||||
name = 'zend_extension'
|
||||
verbose_name = _("Zend extension")
|
||||
regex = r'^[^ ]+$'
|
||||
group = AppOption.PHP
|
||||
|
|
|
@ -142,7 +142,7 @@ WEBAPPS_ENABLED_OPTIONS = getattr(settings, 'WEBAPPS_ENABLED_OPTIONS', (
|
|||
'orchestra.apps.webapps.options.PHPSuhosinSimulation',
|
||||
'orchestra.apps.webapps.options.PHPSuhosinExecutorIncludeWhitelist',
|
||||
'orchestra.apps.webapps.options.PHPUploadMaxFileSize',
|
||||
'orchestra.apps.webapps.options.PHPPostMaxSize',
|
||||
'orchestra.apps.webapps.options.PHPZendExtension',
|
||||
))
|
||||
|
||||
|
||||
|
|
|
@ -13,11 +13,11 @@ from orchestra.forms.widgets import DynamicHelpTextSelect
|
|||
from . import settings
|
||||
from .directives import SiteDirective
|
||||
from .forms import WebsiteAdminForm
|
||||
from .models import Content, Website, Directive
|
||||
from .models import Content, Website, WebsiteDirective
|
||||
|
||||
|
||||
class DirectiveInline(admin.TabularInline):
|
||||
model = Directive
|
||||
class WebsiteDirectiveInline(admin.TabularInline):
|
||||
model = WebsiteDirective
|
||||
extra = 1
|
||||
|
||||
DIRECTIVES_HELP_TEXT = {
|
||||
|
@ -37,7 +37,7 @@ class DirectiveInline(admin.TabularInline):
|
|||
kwargs['widget'] = DynamicHelpTextSelect(
|
||||
'this.id.replace("name", "value")', self.DIRECTIVES_HELP_TEXT
|
||||
)
|
||||
return super(DirectiveInline, self).formfield_for_dbfield(db_field, **kwargs)
|
||||
return super(WebsiteDirectiveInline, self).formfield_for_dbfield(db_field, **kwargs)
|
||||
|
||||
|
||||
class ContentInline(AccountAdminMixin, admin.TabularInline):
|
||||
|
@ -61,7 +61,7 @@ class WebsiteAdmin(SelectAccountAdminMixin, ExtendedModelAdmin):
|
|||
list_display = ('name', 'display_domains', 'display_webapps', 'account_link')
|
||||
list_filter = ('protocol', 'is_active',)
|
||||
change_readonly_fields = ('name',)
|
||||
inlines = [ContentInline, DirectiveInline]
|
||||
inlines = [ContentInline, WebsiteDirectiveInline]
|
||||
filter_horizontal = ['domains']
|
||||
fieldsets = (
|
||||
(None, {
|
||||
|
|
|
@ -245,14 +245,14 @@ class Apache2Backend(ServiceController):
|
|||
option = site.get_directives().get('user_group')
|
||||
if option:
|
||||
return option[0]
|
||||
return site.account.username
|
||||
return site.get_username()
|
||||
|
||||
def get_groupname(self, site):
|
||||
option = site.get_directives().get('user_group')
|
||||
if option and ' ' in option:
|
||||
user, group = option.split()
|
||||
return group
|
||||
return site.account.username
|
||||
return site.get_groupname()
|
||||
|
||||
def get_context(self, site):
|
||||
base_apache_conf = settings.WEBSITES_BASE_APACHE_CONF
|
||||
|
|
|
@ -21,7 +21,9 @@ class WebalizerBackend(ServiceController):
|
|||
echo 'Webstats are coming soon' > %(webalizer_path)s/index.html
|
||||
fi
|
||||
echo '%(webalizer_conf)s' > %(webalizer_conf_path)s
|
||||
chown %(user)s:www-data %(webalizer_path)s""") % context
|
||||
chown %(user)s:www-data %(webalizer_path)s
|
||||
chmod g+xr %(webalizer_path)s
|
||||
""") % context
|
||||
)
|
||||
|
||||
def delete(self, content):
|
||||
|
|
|
@ -84,13 +84,13 @@ class UserGroup(SiteDirective):
|
|||
group = SiteDirective.HTTPD
|
||||
|
||||
def validate(self, directive):
|
||||
super(UserGroupDirective, self).validate(directive)
|
||||
options = directive.split()
|
||||
syetmusers = [options[0]]
|
||||
super(UserGroup, self).validate(directive)
|
||||
options = directive.value.split()
|
||||
systemusers = [options[0]]
|
||||
if len(options) > 1:
|
||||
systemusers.append(options[1])
|
||||
# TODO not sure about this dependency maybe make it part of pangea only
|
||||
from orchestra.apps.users.models import SystemUser
|
||||
from orchestra.apps.systemusers.models import SystemUser
|
||||
errors = []
|
||||
for user in systemusers:
|
||||
if not SystemUser.objects.filter(username=user).exists():
|
||||
|
|
|
@ -46,12 +46,19 @@ class Website(models.Model):
|
|||
|
||||
@property
|
||||
def unique_name(self):
|
||||
return settings.WEBSITES_UNIQUE_NAME_FORMAT % {
|
||||
context = self.get_settings_context()
|
||||
return settings.WEBSITES_UNIQUE_NAME_FORMAT % context
|
||||
|
||||
def get_settings_context(self):
|
||||
""" format settings strings """
|
||||
return {
|
||||
'id': self.id,
|
||||
'pk': self.pk,
|
||||
'account': self.account.username,
|
||||
'home': self.get_user().get_home(),
|
||||
'user': self.get_username(),
|
||||
'group': self.get_groupname(),
|
||||
'site_name': self.name,
|
||||
'protocol': self.protocol,
|
||||
'name': self.name,
|
||||
}
|
||||
|
||||
def get_protocol(self):
|
||||
|
@ -74,27 +81,27 @@ class Website(models.Model):
|
|||
if domain:
|
||||
return '%s://%s' % (self.get_protocol(), domain)
|
||||
|
||||
def get_www_log_context(self):
|
||||
return {
|
||||
'home': self.account.main_systemuser.get_home(),
|
||||
'account': self.account.username,
|
||||
'user': self.account.username,
|
||||
'site_name': self.name,
|
||||
'unique_name': self.unique_name
|
||||
}
|
||||
def get_user(self):
|
||||
return self.account.main_systemuser
|
||||
|
||||
def get_username(self):
|
||||
return self.get_user().username
|
||||
|
||||
def get_groupname(self):
|
||||
return self.get_username()
|
||||
|
||||
def get_www_access_log_path(self):
|
||||
context = self.get_www_log_context()
|
||||
context = self.get_settings_context()
|
||||
path = settings.WEBSITES_WEBSITE_WWW_ACCESS_LOG_PATH % context
|
||||
return os.path.normpath(path.replace('//', '/'))
|
||||
|
||||
def get_www_error_log_path(self):
|
||||
context = self.get_www_log_context()
|
||||
context = self.get_settings_context()
|
||||
path = settings.WEBSITES_WEBSITE_WWW_ERROR_LOG_PATH % context
|
||||
return os.path.normpath(path.replace('//', '/'))
|
||||
|
||||
|
||||
class Directive(models.Model):
|
||||
class WebsiteDirective(models.Model):
|
||||
website = models.ForeignKey(Website, verbose_name=_("web site"),
|
||||
related_name='directives')
|
||||
name = models.CharField(_("name"), max_length=128,
|
||||
|
|
|
@ -3,7 +3,7 @@ from django.utils.translation import ugettext_lazy as _
|
|||
|
||||
|
||||
WEBSITES_UNIQUE_NAME_FORMAT = getattr(settings, 'WEBSITES_UNIQUE_NAME_FORMAT',
|
||||
'%(account)s-%(name)s')
|
||||
'%(user)s-%(site_name)s')
|
||||
|
||||
|
||||
# TODO 'http', 'https', 'https-only', 'http and https' and rename to PROTOCOL
|
||||
|
@ -72,3 +72,4 @@ WEBSITES_TRAFFIC_IGNORE_HOSTS = getattr(settings, 'WEBSITES_TRAFFIC_IGNORE_HOSTS
|
|||
|
||||
#WEBSITES_DEFAULT_SSl_KEY = getattr(settings, 'WEBSITES_DEFAULT_SSl_KEY',
|
||||
# '')
|
||||
|
||||
|
|
Loading…
Reference in New Issue