Example #1
0
def validate_paths_exist(user, paths):
    operations = []
    user.paths_to_validate = paths
    operations.extend(Operation.create_for_action(user, 'validate_paths_exist'))
    logs = Operation.execute(operations)
    stderr = '\n'.join([log.stderr for log in logs])
    if 'path does not exists' in stderr:
        raise ValidationError(stderr)
Example #2
0
def create_link(modeladmin, request, queryset):
    account_id = None
    for user in queryset:
        account_id = account_id or user.account_id
        if user.account_id != account_id:
            messages.error(request,
                           "Users from the same account should be selected.")
            return
    user = queryset[0]
    form = LinkForm(user, queryset=queryset)
    action_value = 'create_link'
    if request.POST.get('post') == 'generic_confirmation':
        form = LinkForm(user, request.POST, queryset=queryset)
        if form.is_valid():
            cleaned_data = form.cleaned_data
            operations = []
            for user in queryset:
                base_home = cleaned_data['base_home']
                extension = cleaned_data['home_extension']
                target = os.path.join(base_home, extension)
                default_name = os.path.join(user.home,
                                            os.path.basename(target))
                link_name = cleaned_data['link_name'] or default_name
                user.create_link_target = target
                user.create_link_name = link_name
                operations.extend(
                    Operation.create_for_action(user, 'create_link'))
                context = {
                    'target': target,
                    'link_name': link_name,
                }
                msg = _(
                    "Created link from %(target)s to %(link_name)s") % context
                modeladmin.log_change(request, request.user, msg)
            logs = Operation.execute(operations)
            if logs:
                helpers.message_user(request, logs)
            else:
                messages.error(request,
                               "No backend operation has been executed.")
            return
    opts = modeladmin.model._meta
    app_label = opts.app_label
    context = {
        'title': _("Create link"),
        'action_name': _("Create link"),
        'action_value': action_value,
        'queryset': queryset,
        'opts': opts,
        'obj': user,
        'app_label': app_label,
        'action_checkbox_name': admin.helpers.ACTION_CHECKBOX_NAME,
        'form': form,
    }
    return TemplateResponse(request,
                            'admin/systemusers/systemuser/create_link.html',
                            context)
Example #3
0
def set_permission(modeladmin, request, queryset):
    account_id = None
    for user in queryset:
        account_id = account_id or user.account_id
        if user.account_id != account_id:
            messages.error(request, "Users from the same account should be selected.")
            return
    user = queryset[0]
    form = PermissionForm(user)
    action_value = 'set_permission'
    if request.POST.get('post') == 'generic_confirmation':
        form = PermissionForm(user, request.POST)
        if form.is_valid():
            cleaned_data = form.cleaned_data
            operations = []
            for user in queryset:
                base_home = cleaned_data['base_home']
                extension = cleaned_data['home_extension']
                action = cleaned_data['set_action']
                perms = cleaned_data['permissions']
                user.set_perm_action = action
                user.set_perm_base_home = base_home
                user.set_perm_home_extension = extension
                user.set_perm_perms = perms
                operations.extend(Operation.create_for_action(user, 'set_permission'))
                verbose_action = get_verbose_choice(form.fields['set_action'].choices,
                    user.set_perm_action)
                verbose_permissions = get_verbose_choice(form.fields['permissions'].choices,
                    user.set_perm_perms)
                context = {
                    'action': verbose_action,
                    'perms': verbose_permissions.lower(),
                    'to': os.path.join(user.set_perm_base_home, user.set_perm_home_extension),
                }
                msg = _("%(action)s %(perms)s permission to %(to)s") % context
                modeladmin.log_change(request, user, msg)
            if not operations:
                messages.error(request, _("No backend operation has been executed."))
            else:
                logs = Operation.execute(operations)
                helpers.message_user(request, logs)
            return
    opts = modeladmin.model._meta
    app_label = opts.app_label
    context = {
        'title': _("Set permission"),
        'action_name': _("Set permission"),
        'action_value': action_value,
        'queryset': queryset,
        'opts': opts,
        'obj': user,
        'app_label': app_label,
        'action_checkbox_name': admin.helpers.ACTION_CHECKBOX_NAME,
        'form': form,
    }
    return TemplateResponse(request, 'admin/systemusers/systemuser/set_permission.html', context)
Example #4
0
def create_link(modeladmin, request, queryset):
    account_id = None
    for user in queryset:
        account_id = account_id or user.account_id
        if user.account_id != account_id:
            messages.error(request, "Users from the same account should be selected.")
            return
    user = queryset[0]
    form = LinkForm(user, queryset=queryset)
    action_value = 'create_link'
    if request.POST.get('post') == 'generic_confirmation':
        form = LinkForm(user, request.POST, queryset=queryset)
        if form.is_valid():
            cleaned_data = form.cleaned_data
            operations = []
            for user in queryset:
                base_home = cleaned_data['base_home']
                extension = cleaned_data['home_extension']
                target = os.path.join(base_home, extension)
                default_name = os.path.join(user.home, os.path.basename(target))
                link_name = cleaned_data['link_name'] or default_name
                user.create_link_target = target
                user.create_link_name = link_name
                operations.extend(Operation.create_for_action(user, 'create_link'))
                context = {
                    'target': target,
                    'link_name': link_name,
                }
                msg = _("Created link from %(target)s to %(link_name)s") % context
                modeladmin.log_change(request, request.user, msg)
            logs = Operation.execute(operations)
            if logs:
                helpers.message_user(request, logs)
            else:
                messages.error(request, "No backend operation has been executed.")
            return
    opts = modeladmin.model._meta
    app_label = opts.app_label
    context = {
        'title': _("Create link"),
        'action_name': _("Create link"),
        'action_value': action_value,
        'queryset': queryset,
        'opts': opts,
        'obj': user,
        'app_label': app_label,
        'action_checkbox_name': admin.helpers.ACTION_CHECKBOX_NAME,
        'form': form,
    }
    return TemplateResponse(request, 'admin/systemusers/systemuser/create_link.html', context)
Example #5
0
 def get_servers(self, domain, backend):
     """ Get related server IPs from registered backend routes """
     from orchestra.contrib.orchestration.manager import router
     operation = Operation(backend, domain, Operation.SAVE)
     servers = []
     for route in router.objects.get_for_operation(operation):
         servers.append(route.host.get_ip())
     return servers
Example #6
0
def monitor(resource_id, ids=None):
    with LockFile('/dev/shm/resources.monitor-%i.lock' % resource_id, expire=60*60, unlocked=bool(ids)):
        from .models import ResourceData, Resource
        resource = Resource.objects.get(pk=resource_id)
        resource_model = resource.content_type.model_class()
        logs = []
        # Execute monitors
        for monitor_name in resource.monitors:
            backend = ServiceMonitor.get_backend(monitor_name)
            model = backend.model_class()
            kwargs = {}
            if ids:
                path = get_model_field_path(model, resource_model)
                path = '%s__in' % ('__'.join(path) or 'id')
                kwargs = {
                    path: ids
                }
            # Execute monitor
            monitorings = []
            for obj in model.objects.filter(**kwargs):
                op = Operation(backend, obj, Operation.MONITOR)
                monitorings.append(op)
            logs += Operation.execute(monitorings, async=False)
        
        kwargs = {'id__in': ids} if ids else {}
        # Update used resources and trigger resource exceeded and revovery
        triggers = []
        model = resource.content_type.model_class()
        for obj in model.objects.filter(**kwargs):
            data, __ = ResourceData.get_or_create(obj, resource)
            data.update()
            if not resource.disable_trigger:
                a = data.used
                b = data.allocated
                if data.used > (data.allocated or 0):
                    op = Operation(backend, obj, Operation.EXCEEDED)
                    triggers.append(op)
                elif data.used < (data.allocated or 0):
                    op = Operation(backend, obj, Operation.RECOVERY)
                    triggers.append(op)
        Operation.execute(triggers)
        return logs
Example #7
0
def monitor(resource_id, ids=None):
    with LockFile('/dev/shm/resources.monitor-%i.lock' % resource_id, expire=60*60, unlocked=bool(ids)):
        from .models import ResourceData, Resource
        resource = Resource.objects.get(pk=resource_id)
        resource_model = resource.content_type.model_class()
        logs = []
        # Execute monitors
        for monitor_name in resource.monitors:
            backend = ServiceMonitor.get_backend(monitor_name)
            model = backend.model_class()
            kwargs = {}
            if ids:
                path = get_model_field_path(model, resource_model)
                path = '%s__in' % ('__'.join(path) or 'id')
                kwargs = {
                    path: ids
                }
            # Execute monitor
            monitorings = []
            for obj in model.objects.filter(**kwargs):
                op = Operation(backend, obj, Operation.MONITOR)
                monitorings.append(op)
            logs += Operation.execute(monitorings, async=False)
        
        kwargs = {'id__in': ids} if ids else {}
        # Update used resources and trigger resource exceeded and revovery
        triggers = []
        model = resource.content_type.model_class()
        for obj in model.objects.filter(**kwargs):
            data, __ = ResourceData.objects.get_or_create(obj, resource)
            data.update()
            if not resource.disable_trigger:
                a = data.used
                b = data.allocated
                if data.used > (data.allocated or 0):
                    op = Operation(backend, obj, Operation.EXCEEDED)
                    triggers.append(op)
                elif data.used < (data.allocated or 0):
                    op = Operation(backend, obj, Operation.RECOVERY)
                    triggers.append(op)
        Operation.execute(triggers)
        return logs
Example #8
0
 def clean_data(self):
     data = super(SoftwareService, self).clean_data()
     if not self.instance.pk:
         try:
             log = Operation.execute_action(self.instance, 'validate_creation')[0]
         except IndexError:
             pass
         else:
             if log.state != log.SUCCESS:
                 raise ValidationError(_("Validate creation execution has failed."))
             errors = {}
             if 'user-exists' in log.stdout:
                 errors['name'] = _("User with this username already exists.")
             if 'email-exists' in log.stdout:
                 errors['email'] = _("User with this email address already exists.")
             if errors:
                 raise ValidationError(errors)
     return data
Example #9
0
 def clean_data(self):
     data = super(SoftwareService, self).clean_data()
     if not self.instance.pk:
         try:
             log = Operation.execute_action(self.instance, 'validate_creation')[0]
         except IndexError:
             pass
         else:
             if log.state != log.SUCCESS:
                 raise ValidationError(_("Validate creation execution has failed."))
             errors = {}
             if 'user-exists' in log.stdout:
                 errors['name'] = _("User with this username already exists.")
             if 'email-exists' in log.stdout:
                 errors['email'] = _("User with this email address already exists.")
             if errors:
                 raise ValidationError(errors)
     return data
Example #10
0
     backend = ServiceMonitor.get_backend(monitor_name)
     model = backend.model_class()
     kwargs = {}
     if ids:
         path = get_model_field_path(model, resource_model)
         path = '%s__in' % ('__'.join(path) or 'id')
         kwargs = {
             path: ids
         }
     # Execute monitor
     monitorings = []
     for obj in model.objects.filter(**kwargs):
         op = Operation(backend, obj, Operation.MONITOR)
         monitorings.append(op)
     # TODO async=True only when running with celery
     logs += Operation.execute(monitorings, async=async)
 
 kwargs = {'id__in': ids} if ids else {}
 # Update used resources and trigger resource exceeded and revovery
 triggers = []
 model = resource.content_type.model_class()
 for obj in model.objects.filter(**kwargs):
     data, __ = ResourceData.get_or_create(obj, resource)
     data.update()
     if not resource.disable_trigger:
         a = data.used
         b = data.allocated
         if data.used > (data.allocated or 0):
             op = Operation(backend, obj, Operation.EXCEEDED)
             triggers.append(op)
         elif data.used < (data.allocated or 0):
Example #11
0
def letsencrypt(modeladmin, request, queryset):
    wildcards = set()
    domains = set()
    content_error = ''
    contentless = queryset.exclude(content__path='/').distinct()
    if contentless:
        content_error = ungettext(
            ugettext(
                "Selected website %s doesn't have a webapp mounted on <tt>/</tt>."
            ),
            ugettext(
                "Selected websites %s don't have a webapp mounted on <tt>/</tt>."
            ),
            len(contentless),
        )
        content_error += ugettext(
            "<br>Websites need a webapp (e.g. static) mounted on </tt>/</tt> "
            "for let's encrypt HTTP-01 challenge to work.")
        content_error = content_error % ', '.join(
            (admin_link()(website) for website in contentless))
        content_error = '<ul class="errorlist"><li>%s</li></ul>' % content_error
    queryset = queryset.prefetch_related('domains')
    for website in queryset:
        for domain in website.domains.all():
            if domain.name.startswith('*.'):
                wildcards.add(domain.name)
            else:
                domains.add(domain.name)
    form = LetsEncryptForm(domains,
                           wildcards,
                           initial={'domains': '\n'.join(domains)})
    action_value = 'letsencrypt'
    if request.POST.get('post') == 'generic_confirmation':
        form = LetsEncryptForm(domains, wildcards, request.POST)
        if not content_error and form.is_valid():
            cleaned_data = form.cleaned_data
            domains = set(cleaned_data['domains'])
            operations = []
            for website in queryset:
                website_domains = [d.name for d in website.domains.all()]
                encrypt_domains = set()
                for domain in domains:
                    if is_valid_domain(domain, website_domains, wildcards):
                        encrypt_domains.add(domain)
                website.encrypt_domains = encrypt_domains
                operations.extend(
                    Operation.create_for_action(website, 'encrypt'))
                modeladmin.log_change(request, website, _("Encrypted!"))
            if not operations:
                messages.error(request,
                               _("No backend operation has been executed."))
            else:
                logs = Operation.execute(operations)
                helpers.message_user(request, logs)
                live_lineages = read_live_lineages(logs)
                errors = 0
                successes = 0
                no_https = 0
                for website in queryset:
                    try:
                        configure_cert(website, live_lineages)
                    except LookupError:
                        errors += 1
                        messages.error(
                            request,
                            _("No lineage found for website %s") %
                            website.name)
                    else:
                        if website.protocol == website.HTTP:
                            no_https += 1
                        website.save(update_fields=('name', ))
                    successes += 1
                context = {
                    'name': website.name,
                    'errors': errors,
                    'successes': successes,
                    'no_https': no_https
                }
                if errors:
                    msg = ungettext(
                        _("No lineages found for websites {name}."),
                        _("No lineages found for {errors} websites."), errors)
                    messages.error(request, msg % context)
                if successes:
                    msg = ungettext(
                        _("{name} website has successfully been encrypted."),
                        _("{successes} websites have been successfully encrypted."
                          ), successes)
                    messages.success(request, msg.format(**context))
                if no_https:
                    msg = ungettext(
                        _("{name} website does not have <b>HTTPS protocol</b> enabled."
                          ),
                        _("{no_https} websites do not have <b>HTTPS protocol</b> enabled."
                          ), no_https)
                    messages.warning(request, mark_safe(msg.format(**context)))
                return
    opts = modeladmin.model._meta
    app_label = opts.app_label
    context = {
        'title':
        _("Let's encrypt!"),
        'action_name':
        _("Encrypt"),
        'content_message':
        ugettext(
            "You are going to request certificates for the following domains.<br>"
            "This operation is safe to run multiple times, "
            "existing certificates will not be regenerated. "
            "Also notice that let's encrypt does not currently support wildcard certificates."
        ) + content_error,
        'action_value':
        action_value,
        'queryset':
        queryset,
        'opts':
        opts,
        'obj':
        website if len(queryset) == 1 else None,
        'app_label':
        app_label,
        'action_checkbox_name':
        admin.helpers.ACTION_CHECKBOX_NAME,
        'form':
        form,
    }
    return TemplateResponse(request,
                            'admin/orchestra/generic_confirmation.html',
                            context)
Example #12
0
def validate_path_exists(user, path):
    user.path_to_validate = path
    log = Operation.execute_action(user, "validate_path_exists")[0]
    if "path does not exists" in log.stderr:
        raise ValidationError(log.stderr)
Example #13
0
def letsencrypt(modeladmin, request, queryset):
    wildcards = set()
    domains = set()
    content_error = ''
    contentless = queryset.exclude(content__path='/').distinct()
    if contentless:
        content_error = ungettext(
            ugettext("Selected website %s doesn't have a webapp mounted on <tt>/</tt>."),
            ugettext("Selected websites %s don't have a webapp mounted on <tt>/</tt>."),
            len(contentless),
        )
        content_error += ugettext("<br>Websites need a webapp (e.g. static) mounted on </tt>/</tt> "
                                  "for let's encrypt HTTP-01 challenge to work.")
        content_error = content_error % ', '.join((admin_link()(website) for website in contentless))
        content_error = '<ul class="errorlist"><li>%s</li></ul>' % content_error
    queryset = queryset.prefetch_related('domains')
    for website in queryset:
        for domain in website.domains.all():
            if domain.name.startswith('*.'):
                wildcards.add(domain.name)
            else:
                domains.add(domain.name)
    form = LetsEncryptForm(domains, wildcards, initial={'domains': '\n'.join(domains)})
    action_value = 'letsencrypt'
    if request.POST.get('post') == 'generic_confirmation':
        form = LetsEncryptForm(domains, wildcards, request.POST)
        if not content_error and form.is_valid():
            cleaned_data = form.cleaned_data
            domains = set(cleaned_data['domains'])
            operations = []
            for website in queryset:
                website_domains = [d.name for d in website.domains.all()]
                encrypt_domains = set()
                for domain in domains:
                    if is_valid_domain(domain, website_domains, wildcards):
                        encrypt_domains.add(domain)
                website.encrypt_domains = encrypt_domains
                operations.extend(Operation.create_for_action(website, 'encrypt'))
                modeladmin.log_change(request, website, _("Encrypted!"))
            if not operations:
                messages.error(request, _("No backend operation has been executed."))
            else:
                logs = Operation.execute(operations)
                helpers.message_user(request, logs)
                live_lineages = read_live_lineages(logs)
                errors = 0
                successes = 0
                no_https = 0
                for website in queryset:
                    try:
                        configure_cert(website, live_lineages)
                    except LookupError:
                        errors += 1
                        messages.error(request, _("No lineage found for website %s") % website.name)
                    else:
                        if website.protocol == website.HTTP:
                            no_https += 1
                        website.save(update_fields=('name',))
                    successes += 1
                context = {
                    'name': website.name,
                    'errors': errors,
                    'successes': successes,
                    'no_https': no_https
                }
                if errors:
                    msg = ungettext(
                        _("No lineages found for websites {name}."),
                        _("No lineages found for {errors} websites."),
                        errors)
                    messages.error(request, msg % context)
                if successes:
                    msg = ungettext(
                        _("{name} website has successfully been encrypted."),
                        _("{successes} websites have been successfully encrypted."),
                        successes)
                    messages.success(request, msg.format(**context))
                if no_https:
                    msg = ungettext(
                        _("{name} website does not have <b>HTTPS protocol</b> enabled."),
                        _("{no_https} websites do not have <b>HTTPS protocol</b> enabled."),
                        no_https)
                    messages.warning(request, mark_safe(msg.format(**context)))
                return
    opts = modeladmin.model._meta
    app_label = opts.app_label
    context = {
        'title': _("Let's encrypt!"),
        'action_name': _("Encrypt"),
        'content_message': ugettext("You are going to request certificates for the following domains.<br>"
            "This operation is safe to run multiple times, "
            "existing certificates will not be regenerated. "
            "Also notice that let's encrypt does not currently support wildcard certificates.") + content_error,
        'action_value': action_value,
        'queryset': queryset,
        'opts': opts,
        'obj': website if len(queryset) == 1 else None,
        'app_label': app_label,
        'action_checkbox_name': admin.helpers.ACTION_CHECKBOX_NAME,
        'form': form,
    }
    return TemplateResponse(request, 'admin/orchestra/generic_confirmation.html', context)
Example #14
0
def grant_permission(modeladmin, request, queryset):
    user = queryset.get()
    log = Operation.execute_action(user, 'grant_permission')
Example #15
0
def set_permission(modeladmin, request, queryset):
    account_id = None
    for user in queryset:
        account_id = account_id or user.account_id
        if user.account_id != account_id:
            messages.error(request,
                           "Users from the same account should be selected.")
            return
    user = queryset[0]
    form = PermissionForm(user)
    action_value = 'set_permission'
    if request.POST.get('post') == 'generic_confirmation':
        form = PermissionForm(user, request.POST)
        if form.is_valid():
            cleaned_data = form.cleaned_data
            operations = []
            for user in queryset:
                base_home = cleaned_data['base_home']
                extension = cleaned_data['home_extension']
                action = cleaned_data['set_action']
                perms = cleaned_data['permissions']
                user.set_perm_action = action
                user.set_perm_base_home = base_home
                user.set_perm_home_extension = extension
                user.set_perm_perms = perms
                operations.extend(
                    Operation.create_for_action(user, 'set_permission'))
                verbose_action = get_verbose_choice(
                    form.fields['set_action'].choices, user.set_perm_action)
                verbose_permissions = get_verbose_choice(
                    form.fields['permissions'].choices, user.set_perm_perms)
                context = {
                    'action':
                    verbose_action,
                    'perms':
                    verbose_permissions.lower(),
                    'to':
                    os.path.join(user.set_perm_base_home,
                                 user.set_perm_home_extension),
                }
                msg = _("%(action)s %(perms)s permission to %(to)s") % context
                modeladmin.log_change(request, user, msg)
            if not operations:
                messages.error(request,
                               _("No backend operation has been executed."))
            else:
                logs = Operation.execute(operations)
                helpers.message_user(request, logs)
            return
    opts = modeladmin.model._meta
    app_label = opts.app_label
    context = {
        'title': _("Set permission"),
        'action_name': _("Set permission"),
        'action_value': action_value,
        'queryset': queryset,
        'opts': opts,
        'obj': user,
        'app_label': app_label,
        'action_checkbox_name': admin.helpers.ACTION_CHECKBOX_NAME,
        'form': form,
    }
    return TemplateResponse(
        request, 'admin/systemusers/systemuser/set_permission.html', context)