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)
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)
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)
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)
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
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
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
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
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):
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)
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)
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)
def grant_permission(modeladmin, request, queryset): user = queryset.get() log = Operation.execute_action(user, 'grant_permission')
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)