diff --git a/lib/main/admin.py b/lib/main/admin.py index 14c54a5d94..ea13f05c40 100644 --- a/lib/main/admin.py +++ b/lib/main/admin.py @@ -329,7 +329,6 @@ class JobAdmin(BaseModelAdmin): 'classes': ('collapse',)}), (_('Start Job'), {'fields': ('start_job', 'ssh_password', 'sudo_password', 'ssh_key_unlock')}), - #(_('Cancel Job'), {'fields': ('cancel_job',)}), #(_('Tags'), {'fields': ('tags',)}), (_('Audit Trail'), {'fields': ('creation_date', 'created_by', 'audit_trail',)}), diff --git a/lib/main/custom_filters.py b/lib/main/custom_filters.py index e2e1bf4ea8..ce3b66779d 100644 --- a/lib/main/custom_filters.py +++ b/lib/main/custom_filters.py @@ -23,16 +23,12 @@ class CustomFilterBackend(object): def filter_queryset(self, request, queryset, view): - keys = request.GET.keys() - terms = {} order_by = None - for key in keys: + for key, value in request.GET.items(): - value = request.GET[key] - - if key in [ 'page', 'page_size' ]: + if key in [ 'page', 'page_size', 'format' ]: continue if key == 'order_by': diff --git a/lib/main/serializers.py b/lib/main/serializers.py index 5fe707858a..2c40987b42 100644 --- a/lib/main/serializers.py +++ b/lib/main/serializers.py @@ -42,7 +42,8 @@ class OrganizationSerializer(BaseSerializer): res = dict( audit_trail = reverse('main:organizations_audit_trail_list', args=(obj.pk,)), - projects = reverse('main:organizations_projects_list', args=(obj.pk,)), + projects = reverse('main:organizations_projects_list', args=(obj.pk,)), + inventories = reverse('main:organizations_inventories_list', args=(obj.pk,)), users = reverse('main:organizations_users_list', args=(obj.pk,)), admins = reverse('main:organizations_admins_list', args=(obj.pk,)), tags = reverse('main:organizations_tags_list', args=(obj.pk,)), @@ -96,12 +97,12 @@ class InventorySerializer(BaseSerializer): class Meta: model = Inventory - fields = ('url', 'id', 'name', 'description', 'creation_date', 'organization') + fields = ('url', 'id', 'name', 'description', 'creation_date', 'related') def get_related(self, obj): res = dict( - hosts = reverse('main:hosts_list', args=(obj.pk,)), - groups = reverse('main:groups_list', args=(obj.pk,)), + hosts = reverse('main:inventory_hosts_list', args=(obj.pk,)), + groups = reverse('main:inventory_groups_list', args=(obj.pk,)), organization = reverse('main:organizations_detail', args=(obj.organization.pk,)), ) if obj.created_by: @@ -116,9 +117,10 @@ class HostSerializer(BaseSerializer): class Meta: model = Host - fields = ('url', 'id', 'name', 'description', 'creation_date', 'inventory') + fields = ('url', 'id', 'name', 'description', 'creation_date', 'related') def get_related(self, obj): + print self, obj res = dict( variable_data = reverse('main:hosts_variable_detail', args=(obj.pk,)), inventory = reverse('main:inventory_detail', args=(obj.inventory.pk,)), diff --git a/lib/main/urls.py b/lib/main/urls.py index 8363d188de..6703b39eef 100644 --- a/lib/main/urls.py +++ b/lib/main/urls.py @@ -30,6 +30,7 @@ organizations_urls = patterns('lib.main.views', url(r'^(?P[0-9]+)/audit_trail/$', 'organizations_audit_trail_list'), url(r'^(?P[0-9]+)/users/$', 'organizations_users_list'), url(r'^(?P[0-9]+)/admins/$', 'organizations_admins_list'), + url(r'^(?P[0-9]+)/inventories/$', 'organizations_inventories_list'), url(r'^(?P[0-9]+)/projects/$', 'organizations_projects_list'), url(r'^(?P[0-9]+)/tags/$', 'organizations_tags_list'), url(r'^(?P[0-9]+)/teams/$', 'organizations_teams_list'), diff --git a/lib/main/views.py b/lib/main/views.py index cbe6beb076..cf1034ee3e 100644 --- a/lib/main/views.py +++ b/lib/main/views.py @@ -139,6 +139,22 @@ class OrganizationsAuditTrailList(BaseSubList): raise PermissionDenied() return AuditTrail.objects.filter(organization_by_audit_trail__in = [ organization ]) +class OrganizationsInventoriesList(BaseSubList): + + model = Inventory + serializer_class = InventorySerializer + permission_classes = (CustomRbac,) + parent_model = Organization + relationship = 'inventories' + postable = False + + def _get_queryset(self): + ''' to list inventories in the organization, I must be a superuser or org admin ''' + organization = Organization.objects.get(pk=self.kwargs['pk']) + if not (self.request.user.is_superuser or self.request.user in organization.admins.all()): + # FIXME: use: organization.can_user_administrate(...) ? + raise PermissionDenied() + return Inventory.objects.filter(organization__in=[organization]) class OrganizationsUsersList(BaseSubList): diff --git a/lib/settings/defaults.py b/lib/settings/defaults.py index c2e24d85b0..378e340d83 100644 --- a/lib/settings/defaults.py +++ b/lib/settings/defaults.py @@ -183,7 +183,7 @@ BROKER_URL = 'django://' CELERY_TASK_SERIALIZER = 'json' CELERY_RESULT_SERIALIZER = 'json' CELERY_TRACK_STARTED = True -CELERYD_TASK_TIME_LIMIT = 600 -CELERYD_TASK_SOFT_TIME_LIMIT = 540 +CELERYD_TASK_TIME_LIMIT = 3600 +CELERYD_TASK_SOFT_TIME_LIMIT = 3540 CELERYBEAT_SCHEDULER = 'djcelery.schedulers.DatabaseScheduler' CELERYBEAT_MAX_LOOP_INTERVAL = 60 diff --git a/lib/templates/admin/base_site.html b/lib/templates/admin/base_site.html index dfba63ee12..c99e253c11 100644 --- a/lib/templates/admin/base_site.html +++ b/lib/templates/admin/base_site.html @@ -135,6 +135,27 @@ pre.result-display { var django = django || {}; if (django.jQuery) { (function($) { + window.refreshJobStatus = function() { + var status = $('.field-status p').text(); + if (status == 'Running' || status == 'Pending') { + var url = '{{ request.path }}'; + $.get(url, function(data) { + var selectors = [ + '.form-row.field-status', + '.field-get_result_stdout_display pre', + '.field-get_result_stderr_display pre', + '.field-get_result_traceback_display pre', + '.field-get_result_stdout_display pre', + '#job_host_summaries-group', + '#job_events-group', + ] + $.each(selectors, function(index, selector) { + $(selector).html($(data).find(selector).html()); + }); + setTimeout('window.refreshJobStatus()', 5000); + }); + } + } // Update playbook list based on project selected. function onProjectChange() { var project_pk = $('select[name="project"]').val() || 0; @@ -144,6 +165,7 @@ if (django.jQuery) { $(function() { $('select[name="project"]').each(onProjectChange).change(onProjectChange); }) + setTimeout('window.refreshJobStatus()', 2000); })(django.jQuery); } diff --git a/lib/templates/rest_framework/api.html b/lib/templates/rest_framework/api.html index 39ec9a2b3f..56a2222de6 100644 --- a/lib/templates/rest_framework/api.html +++ b/lib/templates/rest_framework/api.html @@ -75,6 +75,7 @@ $(function() { $(this).html('"' + s.replace(/\"/g, '') + '"'); } }); + $('.btn-primary').removeClass('btn-primary').addClass('btn-success'); }); {% endblock %}