From 352197c5d2f5b51c7db0d1f9a07cf39b9abf5e27 Mon Sep 17 00:00:00 2001 From: Chris Church Date: Fri, 28 Mar 2014 22:04:26 -0400 Subject: [PATCH] Removed admin support (no longer used or maintained). --- awx/main/admin.py | 391 ----------------------------- awx/main/forms.py | 159 ------------ awx/main/views.py | 13 +- awx/settings/defaults.py | 2 - awx/templates/admin/base_site.html | 251 ------------------ awx/templates/admin/error.html | 20 -- awx/urls.py | 12 - 7 files changed, 5 insertions(+), 843 deletions(-) delete mode 100644 awx/main/admin.py delete mode 100644 awx/main/forms.py delete mode 100644 awx/templates/admin/base_site.html delete mode 100644 awx/templates/admin/error.html diff --git a/awx/main/admin.py b/awx/main/admin.py deleted file mode 100644 index 3b63f647d2..0000000000 --- a/awx/main/admin.py +++ /dev/null @@ -1,391 +0,0 @@ -# Copyright (c) 2014 AnsibleWorks, Inc. -# All Rights Reserved. - -# Django admin isn't officially supported! - -# Python -import json -import urllib - -# Django -from django.conf.urls import * -from django.contrib import admin -from django.contrib.admin.util import unquote -from django.contrib import messages -from django.core.urlresolvers import reverse -from django.http import HttpResponseRedirect -from django.utils.timezone import now -from django.utils.translation import ugettext_lazy as _ -from django.contrib.auth.models import User -from django.contrib.auth.admin import UserAdmin - -# AWX -from awx.lib.compat import format_html -from awx.main.models import * -from awx.main.forms import * - - -class UserAdmin(UserAdmin): - fieldsets = ( - (None, {'fields': ('username', 'password')}), - (_('Personal info'), {'fields': ('first_name', 'last_name', 'email')}), - (_('Permissions'), {'fields': ('is_active', 'is_staff', 'is_superuser')}), - (_('Important dates'), {'fields': ('last_login', 'date_joined')}), - ) - readonly_fields = ('last_login', 'date_joined') - list_display = ('username', 'email', 'first_name', 'last_name', 'is_staff') - list_filter = ('is_staff', 'is_superuser', 'is_active', 'groups') - search_fields = ('username', 'first_name', 'last_name', 'email') - ordering = ('username',) - -try: - admin.site.unregister(User) -except admin.site.NotRegistered: - pass -admin.site.register(User, UserAdmin) - -# FIXME: Hide auth.Group admin - -class BaseModelAdmin(admin.ModelAdmin): - - def save_model(self, request, obj, form, change): - # Automatically set created_by when saved from the admin. - # FIXME: Doesn't handle inline model instances yet. - if hasattr(obj, 'created_by') and obj.created_by is None: - obj.created_by = request.user - return super(BaseModelAdmin, self).save_model(request, obj, form, change) - -class OrganizationAdmin(BaseModelAdmin): - - list_display = ('name', 'description', 'active') - list_filter = ('active', 'tags') - fieldsets = ( - (None, {'fields': (('name', 'active'), 'description',)}), - (_('Members'), {'fields': ('users', 'admins',)}), - (_('Projects'), {'fields': ('projects',)}), - (_('Tags'), {'fields': ('tags',)}), - (_('Audit'), {'fields': ('created', 'created_by',)}), - ) - readonly_fields = ('active', 'created', 'created_by') - filter_horizontal = ('users', 'admins', 'projects') - -class InventoryHostInline(admin.StackedInline): - - model = Host - extra = 0 - fields = ('name', 'description', 'active', 'tags') - readonly_fields = ('active',) - -class InventoryGroupInline(admin.StackedInline): - - model = Group - extra = 0 - fields = ('name', 'description', 'active', 'parents', 'hosts', 'tags') - readonly_fields = ('active',) - filter_horizontal = ('parents', 'hosts') - -class InventoryAdmin(BaseModelAdmin): - - list_display = ('name', 'organization', 'description', 'active') - list_filter = ('organization', 'active') - form = InventoryAdminForm - fieldsets = ( - (None, {'fields': (('name', 'active'), 'organization', 'description', - 'variables')}), - (_('Tags'), {'fields': ('tags',)}), - (_('Audit'), {'fields': ('created', 'created_by',)}), - ) - readonly_fields = ('active', 'created', 'created_by') - inlines = [InventoryHostInline, InventoryGroupInline] - -class JobHostSummaryInline(admin.TabularInline): - - model = JobHostSummary - extra = 0 - can_delete = False - - def has_add_permission(self, request): - return False - -class JobEventInline(admin.StackedInline): - - model = JobEvent - extra = 0 - can_delete = False - - def has_add_permission(self, request): - return False - - def get_event_data_display(self, obj): - return format_html('
{0}
', - json.dumps(obj.event_data, indent=4)) - get_event_data_display.short_description = _('Event data') - get_event_data_display.allow_tags = True - -class JobHostSummaryInlineForHost(JobHostSummaryInline): - - fields = ('job', 'changed', 'dark', 'failures', 'ok', 'processed', - 'skipped', 'failed') - readonly_fields = ('job', 'changed', 'dark', 'failures', 'ok', 'processed', - 'skipped', 'failed') - -class JobEventInlineForHost(JobEventInline): - - fields = ('job', 'created', 'event', 'get_event_data_display') - readonly_fields = ('job', 'created', 'event', 'get_event_data_display') - -class HostAdmin(BaseModelAdmin): - - list_display = ('name', 'inventory', 'description', 'active') - list_filter = ('inventory', 'active') - form = HostAdminForm - fieldsets = ( - (None, {'fields': (('name', 'active'), 'inventory', 'description', - 'variables', - )}), - (_('Tags'), {'fields': ('tags',)}), - (_('Audit'), {'fields': ('created', 'created_by',)}), - ) - readonly_fields = ('active', 'created', 'created_by') - # FIXME: Edit reverse of many to many for groups. - inlines = [JobHostSummaryInlineForHost, JobEventInlineForHost] - -class GroupAdmin(BaseModelAdmin): - - list_display = ('name', 'description', 'active') - form = GroupAdminForm - fieldsets = ( - (None, {'fields': (('name', 'active'), 'inventory', 'description', - 'parents', 'variables')}), - (_('Tags'), {'fields': ('tags',)}), - (_('Audit'), {'fields': ('created', 'created_by',)}), - ) - readonly_fields = ('active', 'created', 'created_by') - filter_horizontal = ('parents', 'hosts') - -class CredentialAdmin(BaseModelAdmin): - - fieldsets = ( - (None, {'fields': (('name', 'active'), ('user', 'team'), 'description')}), - (_('Auth Info'), {'fields': (('username', 'password'), - 'ssh_key_data', 'ssh_key_unlock', - ('sudo_username', 'sudo_password'))}), - (_('Tags'), {'fields': ('tags',)}), - (_('Audit'), {'fields': ('created', 'created_by',)}), - ) - readonly_fields = ('active', 'created', 'created_by') - -class TeamAdmin(BaseModelAdmin): - - list_display = ('name', 'description', 'active') - filter_horizontal = ('projects', 'users') - -class ProjectUpdateInline(admin.StackedInline): - - model = ProjectUpdate - extra = 0 - can_delete = True - fields = ('created', 'status', 'result_stdout') - readonly_fields = ('created', 'status', 'result_stdout') - - def has_add_permission(self, request): - return False - -class ProjectAdmin(BaseModelAdmin): - - list_display = ('name', 'description', 'active') - fieldsets = ( - (None, {'fields': (('name', 'active'), 'description', 'local_path', - 'get_playbooks_display')}), - (_('SCM'), {'fields': ('scm_type', 'scm_url', 'scm_branch')}), - (_('Tags'), {'fields': ('tags',)}), - (_('Audit'), {'fields': ('created', 'created_by',)}), - ) - readonly_fields = ('active', 'created', 'created_by', - 'get_playbooks_display') - form = ProjectAdminForm - inlines = [ProjectUpdateInline] - - def get_playbooks_display(self, obj): - return '
'.join([format_html('{0}', x) for x in - obj.playbooks]) - get_playbooks_display.short_description = _('Playbooks') - get_playbooks_display.allow_tags = True - -class PermissionAdmin(BaseModelAdmin): - - list_display = ('name', 'description', 'active') - -class JobTemplateAdmin(BaseModelAdmin): - - list_display = ('name', 'description', 'active', 'get_create_link_display', - 'get_jobs_link_display') - fieldsets = ( - (None, {'fields': ('name', 'active', 'description', - 'get_create_link_display', 'get_jobs_link_display')}), - (_('Job Parameters'), {'fields': ('inventory', 'project', 'playbook', - 'credential', 'job_type')}), - (_('More Options'), {'fields': ('forks', 'limit', 'verbosity', - 'extra_vars', 'job_tags', 'host_config_key'), - 'classes': ('collapse',)}), - (_('Tags'), {'fields': ('tags',)}), - (_('Audit'), {'fields': ('created', 'created_by',)}), - ) - readonly_fields = ('active', 'created', 'created_by', - 'get_create_link_display', 'get_jobs_link_display') - form = JobTemplateAdminForm - - def get_create_link_display(self, obj): - if not obj or not obj.pk: - return '' - info = Job._meta.app_label, Job._meta.module_name - create_url = reverse('admin:%s_%s_add' % info, - current_app=self.admin_site.name) - create_opts = { - 'job_template': obj.pk, - 'job_type': obj.job_type, - 'description': obj.description, - 'name': '%s %s' % (obj.name, now().isoformat()), - } - if obj.inventory: - create_opts['inventory'] = obj.inventory.pk - if obj.project: - create_opts['project'] = obj.project.pk - if obj.playbook: - create_opts['playbook'] = obj.playbook - if obj.credential: - create_opts['credential'] = obj.credential.pk - if obj.forks: - create_opts['forks'] = obj.forks - if obj.limit: - create_opts['limit'] = obj.limit - if obj.verbosity: - create_opts['verbosity'] = obj.verbosity - if obj.extra_vars: - create_opts['extra_vars'] = obj.extra_vars - if obj.job_tags: - create_opts['job_tags'] = obj.job_tags - create_url += '?%s' % urllib.urlencode(create_opts) - return format_html('{1}', create_url, 'Create Job') - get_create_link_display.short_description = _('Create Job') - get_create_link_display.allow_tags = True - - def get_jobs_link_display(self, obj): - if not obj or not obj.pk: - return '' - info = Job._meta.app_label, Job._meta.module_name - jobs_url = reverse('admin:%s_%s_changelist' % info, - current_app=self.admin_site.name) - jobs_url += '?job_template__id__exact=%d' % obj.pk - return format_html('{1}', jobs_url, 'View Jobs') - get_jobs_link_display.short_description = _('View Jobs') - get_jobs_link_display.allow_tags = True - -class JobHostSummaryInlineForJob(JobHostSummaryInline): - - fields = ('host', 'changed', 'dark', 'failures', 'ok', 'processed', - 'skipped', 'failed') - readonly_fields = ('host', 'changed', 'dark', 'failures', 'ok', - 'processed', 'skipped', 'failed') - -class JobEventInlineForJob(JobEventInline): - - fields = ('created', 'event', 'get_event_data_display', 'failed', 'host') - readonly_fields = ('created', 'event', 'get_event_data_display', 'failed', - 'host') - -class JobAdmin(BaseModelAdmin): - - list_display = ('__unicode__', 'job_template', 'project', 'playbook', 'status') - list_filter = ('status',) - fieldsets = ( - (None, {'fields': ('job_template', 'description')}), - (_('Job Parameters'), {'fields': ('inventory', 'project', 'playbook', - 'credential', 'job_type')}), - (_('More Options'), {'fields': ('forks', 'limit', 'verbosity', - 'extra_vars', 'job_tags'), - 'classes': ('collapse',)}), - (_('Start Job'), {'fields': ('start_job', 'ssh_password', - 'sudo_password', 'ssh_key_unlock')}), - (_('Tags'), {'fields': ('tags',)}), - (_('Audit'), {'fields': ('created', 'created_by',)}), - (_('Job Status'), {'fields': (('status', 'failed', 'cancel_job'), - 'get_result_stdout_display', - 'get_result_traceback_display', - 'celery_task_id')}), - ) - readonly_fields = ('status', 'failed', 'get_job_template_display', - 'get_result_stdout_display', - 'get_result_traceback_display', 'celery_task_id', - 'created', 'created_by') - form = JobAdminForm - inlines = [JobHostSummaryInlineForJob, JobEventInlineForJob] - - def get_readonly_fields(self, request, obj=None): - ro_fields = list(super(JobAdmin, self).get_readonly_fields(request, obj)) - if obj and obj.pk and obj.status != 'new': - ro_fields.extend(['description', 'job_template', - 'inventory', 'project', 'playbook', 'credential', - 'job_type', 'forks', 'limit', - 'verbosity', 'extra_vars', 'job_tags']) - return ro_fields - - def get_fieldsets(self, request, obj=None): - fsets = list(super(JobAdmin, self).get_fieldsets(request, obj)) - if not obj or not obj.pk or obj.status == 'new': - fsets = [fs for fs in fsets if - 'created' not in fs[1]['fields'] and - 'celery_task_id' not in fs[1]['fields']] - if not obj or (obj and obj.pk and not obj.can_start): - fsets = [fs for fs in fsets if 'start_job' not in fs[1]['fields']] - if not obj or (obj and obj.pk and not obj.can_cancel): - for fs in fsets: - if 'celery_task_id' in fs[1]['fields']: - fs[1]['fields'] = ('status', 'get_result_stdout_display', - 'get_result_traceback_display', - 'celery_task_id') - return fsets - - def get_inline_instances(self, request, obj=None): - if obj and obj.pk and obj.status != 'new': - return super(JobAdmin, self).get_inline_instances(request, obj) - else: - return [] - - def get_job_template_display(self, obj): - if obj.job_template: - info = JobTemplate._meta.app_label, JobTemplate._meta.module_name - job_template_url = reverse('admin:%s_%s_change' % info, - args=(obj.job_template.pk,), - current_app=self.admin_site.name) - return format_html('{1}', job_template_url, - obj.job_template) - else: - return _('(None)') - get_job_template_display.short_description = _('Job template') - get_job_template_display.allow_tags = True - - def get_result_stdout_display(self, obj): - return format_html('
{0}
', - obj.result_stdout or ' ') - get_result_stdout_display.short_description = _('Stdout') - get_result_stdout_display.allow_tags = True - - def get_result_traceback_display(self, obj): - return format_html('
{0}
', - obj.result_traceback or ' ') - get_result_traceback_display.short_description = _('Traceback') - get_result_traceback_display.allow_tags = True - -admin.site.register(Organization, OrganizationAdmin) -admin.site.register(Inventory, InventoryAdmin) -#admin.site.register(Tag, TagAdmin) -#admin.site.register(AuditTrail, AuditTrailAdmin) -admin.site.register(Host, HostAdmin) -admin.site.register(Group, GroupAdmin) -#admin.site.register(VariableData, VariableDataAdmin) -admin.site.register(Team, TeamAdmin) -admin.site.register(Project, ProjectAdmin) -admin.site.register(Credential, CredentialAdmin) -admin.site.register(JobTemplate, JobTemplateAdmin) -admin.site.register(Job, JobAdmin) diff --git a/awx/main/forms.py b/awx/main/forms.py deleted file mode 100644 index 027dc4f0ee..0000000000 --- a/awx/main/forms.py +++ /dev/null @@ -1,159 +0,0 @@ -# Copyright (c) 2014 AnsibleWorks, Inc. -# All Rights Reserved. - -# Python -import json - -# PyYAML -import yaml - -# Django -from django import forms -from django.utils.translation import ugettext_lazy as _ - -# AWX -from awx.main.models import * - -EMPTY_CHOICE = ('', '---------') - -class PlaybookOption(object): - - def __init__(self, project, playbook): - self.project, self.playbook = project, playbook - - def __unicode__(self): - return self.playbook - -class PlaybookSelect(forms.Select): - '''Custom select widget for playbooks related to a project.''' - - def render_option(self, selected_choices, option_value, obj): - opt = super(PlaybookSelect, self).render_option(selected_choices, - option_value, - unicode(obj)) - # Add a class with the project ID so JS can filter the options. - if hasattr(obj, 'project'): - opt = opt.replace('">', '" class="project-%s">' % obj.project.pk) - return opt - -class ModelFormWithVariables(forms.ModelForm): - '''Custom model form to validate variable data.''' - - def clean_variables(self): - value = self.cleaned_data.get('variables', '') - try: - json.loads(value.strip() or '{}') - except ValueError: - try: - yaml.safe_load(value) - except yaml.YAMLError: - raise forms.ValidationError('Must be valid JSON or YAML') - return value - -class InventoryAdminForm(ModelFormWithVariables): - '''Custom model form for Inventory.''' - - class Meta: - model = Inventory - -class HostAdminForm(ModelFormWithVariables): - '''Custom model form for Hosts.''' - - class Meta: - model = Host - -class GroupAdminForm(ModelFormWithVariables): - '''Custom model form for Groups.''' - - class Meta: - model = Group - -class ProjectAdminForm(forms.ModelForm): - '''Custom admin form for Projects.''' - - local_path = forms.ChoiceField(choices=[]) - - class Meta: - model = Project - - def __init__(self, *args, **kwargs): - super(ProjectAdminForm, self).__init__(*args, **kwargs) - self.fields['local_path'].choices = [(x, x) for x in Project.get_local_path_choices()] - -class JobTemplateAdminForm(forms.ModelForm): - '''Custom admin form for creating/editing JobTemplates.''' - - playbook = forms.ChoiceField(choices=[EMPTY_CHOICE], widget=PlaybookSelect) - - class Meta: - model = JobTemplate - - def __init__(self, *args, **kwargs): - super(JobTemplateAdminForm, self).__init__(*args, **kwargs) - playbook_choices = [] - for project in Project.objects.all(): - for playbook in project.playbooks: - playbook_choices.append((playbook, - PlaybookOption(project, playbook))) - self.fields['playbook'].choices = [EMPTY_CHOICE] + playbook_choices - -class JobAdminForm(JobTemplateAdminForm): - '''Custom admin form for creating Jobs.''' - - start_job = forms.BooleanField(initial=False, required=False) - ssh_password = forms.CharField(label=_('SSH password'), required=False) - sudo_password = forms.CharField(required=False) - ssh_key_unlock = forms.CharField(label=_('SSH key passphrase'), - required=False) - cancel_job = forms.BooleanField(initial=False, required=False) - - class Meta: - model = Job - - def __init__(self, *args, **kwargs): - super(JobAdminForm, self).__init__(*args, **kwargs) - if self.instance.pk and self.instance.status != 'new': - self.fields.pop('playbook', None) - if (not self.data or self.data.get('start_job', '')) and \ - self.instance.credential and self.instance.can_start: - for field in self.instance.get_passwords_needed_to_start(): - if field not in self.fields: - continue - self.fields[field].required = True - - def clean_start_job(self): - return self.cleaned_data.get('start_job', False) - - def clean_cancel_job(self): - return self.cleaned_data.get('cancel_job', False) - - def clean(self): - if self.instance.credential and self.instance.can_start: - for field in self.instance.get_passwords_needed_to_start(): - if field in self.fields: - self.fields[field].required = True - return super(JobAdminForm, self).clean() - - def save(self, commit=True): - instance = super(JobAdminForm, self).save(commit) - save_m2m = getattr(self, 'save_m2m', lambda: None) - should_start = bool(self.cleaned_data.get('start_job', '') and - instance.can_start) - start_opts = {} - for field in ('ssh_password', 'sudo_password', 'ssh_key_unlock'): - value = self.cleaned_data.get(field, '') - if value: - start_opts[field] = value - should_cancel = bool(self.cleaned_data.get('cancel_job', '') and - instance.can_cancel) - def new_save_m2m(): - save_m2m() - if should_start: - instance.start(**start_opts) - if should_cancel: - instance.cancel() - if commit: - new_save_m2m() - else: - self.save_m2m = new_save_m2m - return instance diff --git a/awx/main/views.py b/awx/main/views.py index 3ab721ca13..10299dc2ed 100644 --- a/awx/main/views.py +++ b/awx/main/views.py @@ -11,14 +11,11 @@ def handle_error(request, status=404, **kwargs): # FIXME: Should attempt to check HTTP Accept request header and return # plain JSON response instead of HTML (maybe only for /api/*). context = kwargs - if 'django.contrib.admin' in settings.INSTALLED_APPS and request.path.startswith('/admin/'): - template_name = 'admin/error.html' - else: - # Return enough context to popuplate the base API template. - description = u'
%s
' % context.get('content', '') - context['description'] = mark_safe(description) - context['content'] = '' - template_name = 'error.html' + # Return enough context to popuplate the base API template. + description = u'
%s
' % context.get('content', '') + context['description'] = mark_safe(description) + context['content'] = '' + template_name = 'error.html' return render(request, template_name, context, status=status) def handle_403(request): diff --git a/awx/settings/defaults.py b/awx/settings/defaults.py index 9b7d2365cb..cce44e1735 100644 --- a/awx/settings/defaults.py +++ b/awx/settings/defaults.py @@ -140,8 +140,6 @@ INSTALLED_APPS = ( 'awx.main', 'awx.api', 'awx.ui', - # Django admin is disabled and not supported by default. - #'django.contrib.admin', ) INTERNAL_IPS = ('127.0.0.1',) diff --git a/awx/templates/admin/base_site.html b/awx/templates/admin/base_site.html deleted file mode 100644 index c9cdfed4f5..0000000000 --- a/awx/templates/admin/base_site.html +++ /dev/null @@ -1,251 +0,0 @@ -{# Admin site customizations. #} -{% extends "admin/base.html" %} -{% load i18n %} - -{% block title %}{{ title }} | {% trans 'AWX Admin' %}{% endblock %} - -{% block extrastyle %} -{{ block.super }} - - -{% endblock %} - -{% block extrahead %} -{{ block.super }} -{% endblock %} - -{% block blockbots %} -{{ block.super }} - -{% endblock %} - -{% block branding %} -

{% block branding_title %}{% trans 'AWX Admin' %}{% endblock %}

-{% endblock %} - -{% block userlinks %} -{{ block.super }} -{% endblock %} - -{% block nav-global %} -{% if user.is_active and user.is_staff and not is_popup %} -{# Placeholder for version/hostname info. #} -{% endif %} -{{ block.super }} -{% endblock %} - -{% block content_title %} -{{ block.super }} -{% endblock %} diff --git a/awx/templates/admin/error.html b/awx/templates/admin/error.html deleted file mode 100644 index 185e18ab63..0000000000 --- a/awx/templates/admin/error.html +++ /dev/null @@ -1,20 +0,0 @@ -{% extends "admin/base_site.html" %} -{% load i18n %} - -{% block title %}{{ name }}{% endblock %} - -{% block nav-global %}{% endblock %} - -{% block content_title %}{% endblock %} - -{% block breadcrumbs %} - -{% endblock %} - -{% block content %} -

{{ name }}

-

{{ content }}

-{% endblock %} diff --git a/awx/urls.py b/awx/urls.py index 90ba9c208f..e34cf24a46 100644 --- a/awx/urls.py +++ b/awx/urls.py @@ -18,15 +18,3 @@ urlpatterns += patterns('awx.main.views', url(r'^404.html$', 'handle_404'), url(r'^500.html$', 'handle_500'), ) - -if 'django.contrib.admin' in settings.INSTALLED_APPS: - from django.contrib import admin - admin.autodiscover() - urlpatterns += patterns('', - url(r'^admin/', include(admin.site.urls)), - ) - urlpatterns += patterns('awx.main.views', - url(r'^admin/403.html$', 'handle_403'), - url(r'^admin/404.html$', 'handle_404'), - url(r'^admin/500.html$', 'handle_500'), - )