mirror of
https://github.com/ansible/awx.git
synced 2026-02-22 13:36:02 -03:30
Merge pull request #600 from wwitzel3/django111
Upgrade AWX major dependencies
This commit is contained in:
12
Makefile
12
Makefile
@@ -203,8 +203,11 @@ develop:
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
version_file:
|
version_file:
|
||||||
mkdir -p /var/lib/awx/
|
mkdir -p /var/lib/awx/; \
|
||||||
python -c "import awx as awx; print awx.__version__" > /var/lib/awx/.awx_version
|
if [ "$(VENV_BASE)" ]; then \
|
||||||
|
. $(VENV_BASE)/awx/bin/activate; \
|
||||||
|
fi; \
|
||||||
|
python -c "import awx as awx; print awx.__version__" > /var/lib/awx/.awx_version; \
|
||||||
|
|
||||||
# Do any one-time init tasks.
|
# Do any one-time init tasks.
|
||||||
comma := ,
|
comma := ,
|
||||||
@@ -284,7 +287,7 @@ flower:
|
|||||||
@if [ "$(VENV_BASE)" ]; then \
|
@if [ "$(VENV_BASE)" ]; then \
|
||||||
. $(VENV_BASE)/awx/bin/activate; \
|
. $(VENV_BASE)/awx/bin/activate; \
|
||||||
fi; \
|
fi; \
|
||||||
$(PYTHON) manage.py celery flower --address=0.0.0.0 --port=5555 --broker=amqp://guest:guest@$(RABBITMQ_HOST):5672//
|
celery flower --address=0.0.0.0 --port=5555 --broker=amqp://guest:guest@$(RABBITMQ_HOST):5672//
|
||||||
|
|
||||||
collectstatic:
|
collectstatic:
|
||||||
@if [ "$(VENV_BASE)" ]; then \
|
@if [ "$(VENV_BASE)" ]; then \
|
||||||
@@ -322,8 +325,7 @@ celeryd:
|
|||||||
@if [ "$(VENV_BASE)" ]; then \
|
@if [ "$(VENV_BASE)" ]; then \
|
||||||
. $(VENV_BASE)/awx/bin/activate; \
|
. $(VENV_BASE)/awx/bin/activate; \
|
||||||
fi; \
|
fi; \
|
||||||
$(PYTHON) manage.py celeryd -l DEBUG -B -Ofair --autoreload --autoscale=100,4 --schedule=$(CELERY_SCHEDULE_FILE) -Q tower_scheduler,tower_broadcast_all,$(COMPOSE_HOST),$(AWX_GROUP_QUEUES) -n celery@$(COMPOSE_HOST)
|
celery worker -A awx -l DEBUG -B -Ofair --autoscale=100,4 --schedule=$(CELERY_SCHEDULE_FILE) -Q tower_scheduler,tower_broadcast_all,$(COMPOSE_HOST),$(AWX_GROUP_QUEUES) -n celery@$(COMPOSE_HOST)
|
||||||
#$(PYTHON) manage.py celery multi show projects jobs default -l DEBUG -Q:projects projects -Q:jobs jobs -Q:default default -c:projects 1 -c:jobs 3 -c:default 3 -Ofair -B --schedule=$(CELERY_SCHEDULE_FILE)
|
|
||||||
|
|
||||||
# Run to start the zeromq callback receiver
|
# Run to start the zeromq callback receiver
|
||||||
receiver:
|
receiver:
|
||||||
|
|||||||
@@ -1,15 +1,17 @@
|
|||||||
# Copyright (c) 2015 Ansible, Inc.
|
# Copyright (c) 2015 Ansible, Inc.
|
||||||
# All Rights Reserved.
|
# All Rights Reserved.
|
||||||
|
from __future__ import absolute_import, unicode_literals
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
import warnings
|
import warnings
|
||||||
|
|
||||||
from pkg_resources import get_distribution
|
from pkg_resources import get_distribution
|
||||||
|
from .celery import app as celery_app
|
||||||
|
|
||||||
__version__ = get_distribution('awx').version
|
__version__ = get_distribution('awx').version
|
||||||
|
|
||||||
__all__ = ['__version__']
|
__all__ = ['__version__', 'celery_app']
|
||||||
|
|
||||||
# Check for the presence/absence of "devonly" module to determine if running
|
# Check for the presence/absence of "devonly" module to determine if running
|
||||||
# from a source code checkout or release packaage.
|
# from a source code checkout or release packaage.
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ from rest_framework.filters import BaseFilterBackend
|
|||||||
|
|
||||||
# AWX
|
# AWX
|
||||||
from awx.main.utils import get_type_for_model, to_python_boolean
|
from awx.main.utils import get_type_for_model, to_python_boolean
|
||||||
|
from awx.main.utils.db import get_all_field_names
|
||||||
from awx.main.models.credential import CredentialType
|
from awx.main.models.credential import CredentialType
|
||||||
from awx.main.models.rbac import RoleAncestorEntry
|
from awx.main.models.rbac import RoleAncestorEntry
|
||||||
|
|
||||||
@@ -70,7 +71,7 @@ class TypeFilterBackend(BaseFilterBackend):
|
|||||||
types_map[ct_type] = ct.pk
|
types_map[ct_type] = ct.pk
|
||||||
model = queryset.model
|
model = queryset.model
|
||||||
model_type = get_type_for_model(model)
|
model_type = get_type_for_model(model)
|
||||||
if 'polymorphic_ctype' in model._meta.get_all_field_names():
|
if 'polymorphic_ctype' in get_all_field_names(model):
|
||||||
types_pks = set([v for k,v in types_map.items() if k in types])
|
types_pks = set([v for k,v in types_map.items() if k in types])
|
||||||
queryset = queryset.filter(polymorphic_ctype_id__in=types_pks)
|
queryset = queryset.filter(polymorphic_ctype_id__in=types_pks)
|
||||||
elif model_type in types:
|
elif model_type in types:
|
||||||
@@ -119,7 +120,7 @@ class FieldLookupBackend(BaseFilterBackend):
|
|||||||
'last_updated': 'last_job_run',
|
'last_updated': 'last_job_run',
|
||||||
}.get(name, name)
|
}.get(name, name)
|
||||||
|
|
||||||
if name == 'type' and 'polymorphic_ctype' in model._meta.get_all_field_names():
|
if name == 'type' and 'polymorphic_ctype' in get_all_field_names(model):
|
||||||
name = 'polymorphic_ctype'
|
name = 'polymorphic_ctype'
|
||||||
new_parts.append('polymorphic_ctype__model')
|
new_parts.append('polymorphic_ctype__model')
|
||||||
else:
|
else:
|
||||||
@@ -136,7 +137,7 @@ class FieldLookupBackend(BaseFilterBackend):
|
|||||||
new_parts.pop()
|
new_parts.pop()
|
||||||
new_parts.append(name_alt)
|
new_parts.append(name_alt)
|
||||||
else:
|
else:
|
||||||
field = model._meta.get_field_by_name(name)[0]
|
field = model._meta.get_field(name)
|
||||||
if isinstance(field, ForeignObjectRel) and getattr(field.field, '__prevent_search__', False):
|
if isinstance(field, ForeignObjectRel) and getattr(field.field, '__prevent_search__', False):
|
||||||
raise PermissionDenied(_('Filtering on %s is not allowed.' % name))
|
raise PermissionDenied(_('Filtering on %s is not allowed.' % name))
|
||||||
elif getattr(field, '__prevent_search__', False):
|
elif getattr(field, '__prevent_search__', False):
|
||||||
@@ -375,7 +376,7 @@ class OrderByBackend(BaseFilterBackend):
|
|||||||
# given the limited number of views with multiple types,
|
# given the limited number of views with multiple types,
|
||||||
# sorting on polymorphic_ctype.model is effectively the same.
|
# sorting on polymorphic_ctype.model is effectively the same.
|
||||||
new_order_by = []
|
new_order_by = []
|
||||||
if 'polymorphic_ctype' in queryset.model._meta.get_all_field_names():
|
if 'polymorphic_ctype' in get_all_field_names(queryset.model):
|
||||||
for field in order_by:
|
for field in order_by:
|
||||||
if field == 'type':
|
if field == 'type':
|
||||||
new_order_by.append('polymorphic_ctype__model')
|
new_order_by.append('polymorphic_ctype__model')
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ from rest_framework import views
|
|||||||
from awx.api.filters import FieldLookupBackend
|
from awx.api.filters import FieldLookupBackend
|
||||||
from awx.main.models import * # noqa
|
from awx.main.models import * # noqa
|
||||||
from awx.main.utils import * # noqa
|
from awx.main.utils import * # noqa
|
||||||
|
from awx.main.utils.db import get_all_field_names
|
||||||
from awx.api.serializers import ResourceAccessListElementSerializer
|
from awx.api.serializers import ResourceAccessListElementSerializer
|
||||||
from awx.api.versioning import URLPathVersioning, get_request_version
|
from awx.api.versioning import URLPathVersioning, get_request_version
|
||||||
from awx.api.metadata import SublistAttachDetatchMetadata
|
from awx.api.metadata import SublistAttachDetatchMetadata
|
||||||
@@ -321,8 +322,7 @@ class ListAPIView(generics.ListAPIView, GenericAPIView):
|
|||||||
return page
|
return page
|
||||||
|
|
||||||
def get_description_context(self):
|
def get_description_context(self):
|
||||||
opts = self.model._meta
|
if 'username' in get_all_field_names(self.model):
|
||||||
if 'username' in opts.get_all_field_names():
|
|
||||||
order_field = 'username'
|
order_field = 'username'
|
||||||
else:
|
else:
|
||||||
order_field = 'name'
|
order_field = 'name'
|
||||||
|
|||||||
@@ -477,7 +477,7 @@ class BaseSerializer(serializers.ModelSerializer):
|
|||||||
return super(BaseSerializer, self).run_validation(data)
|
return super(BaseSerializer, self).run_validation(data)
|
||||||
except ValidationError as exc:
|
except ValidationError as exc:
|
||||||
# Avoid bug? in DRF if exc.detail happens to be a list instead of a dict.
|
# Avoid bug? in DRF if exc.detail happens to be a list instead of a dict.
|
||||||
raise ValidationError(detail=serializers.get_validation_error_detail(exc))
|
raise ValidationError(detail=serializers.as_serializer_error(exc))
|
||||||
|
|
||||||
def get_validation_exclusions(self, obj=None):
|
def get_validation_exclusions(self, obj=None):
|
||||||
# Borrowed from DRF 2.x - return model fields that should be excluded
|
# Borrowed from DRF 2.x - return model fields that should be excluded
|
||||||
|
|||||||
420
awx/api/urls.py
420
awx/api/urls.py
@@ -1,420 +0,0 @@
|
|||||||
# Copyright (c) 2015 Ansible, Inc.
|
|
||||||
# All Rights Reserved.
|
|
||||||
|
|
||||||
# noqa
|
|
||||||
|
|
||||||
from django.conf.urls import include, patterns, url as original_url
|
|
||||||
|
|
||||||
def url(regex, view, kwargs=None, name=None, prefix=''):
|
|
||||||
# Set default name from view name (if a string).
|
|
||||||
if isinstance(view, basestring) and name is None:
|
|
||||||
name = view
|
|
||||||
return original_url(regex, view, kwargs, name, prefix)
|
|
||||||
|
|
||||||
organization_urls = patterns('awx.api.views',
|
|
||||||
url(r'^$', 'organization_list'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/$', 'organization_detail'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/users/$', 'organization_users_list'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/admins/$', 'organization_admins_list'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/inventories/$', 'organization_inventories_list'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/projects/$', 'organization_projects_list'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/workflow_job_templates/$', 'organization_workflow_job_templates_list'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/teams/$', 'organization_teams_list'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/credentials/$', 'organization_credential_list'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/activity_stream/$', 'organization_activity_stream_list'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/notification_templates/$', 'organization_notification_templates_list'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/notification_templates_any/$', 'organization_notification_templates_any_list'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/notification_templates_error/$', 'organization_notification_templates_error_list'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/notification_templates_success/$', 'organization_notification_templates_success_list'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/instance_groups/$', 'organization_instance_groups_list'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/object_roles/$', 'organization_object_roles_list'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/access_list/$', 'organization_access_list'),
|
|
||||||
)
|
|
||||||
|
|
||||||
user_urls = patterns('awx.api.views',
|
|
||||||
url(r'^$', 'user_list'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/$', 'user_detail'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/teams/$', 'user_teams_list'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/organizations/$', 'user_organizations_list'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/admin_of_organizations/$', 'user_admin_of_organizations_list'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/projects/$', 'user_projects_list'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/credentials/$', 'user_credentials_list'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/roles/$', 'user_roles_list'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/activity_stream/$', 'user_activity_stream_list'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/access_list/$', 'user_access_list'),
|
|
||||||
|
|
||||||
)
|
|
||||||
|
|
||||||
project_urls = patterns('awx.api.views',
|
|
||||||
url(r'^$', 'project_list'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/$', 'project_detail'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/playbooks/$', 'project_playbooks'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/inventories/$', 'project_inventories'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/scm_inventory_sources/$', 'project_scm_inventory_sources'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/teams/$', 'project_teams_list'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/update/$', 'project_update_view'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/project_updates/$', 'project_updates_list'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/activity_stream/$', 'project_activity_stream_list'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/schedules/$', 'project_schedules_list'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/notification_templates_any/$', 'project_notification_templates_any_list'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/notification_templates_error/$', 'project_notification_templates_error_list'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/notification_templates_success/$', 'project_notification_templates_success_list'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/object_roles/$', 'project_object_roles_list'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/access_list/$', 'project_access_list'),
|
|
||||||
)
|
|
||||||
|
|
||||||
project_update_urls = patterns('awx.api.views',
|
|
||||||
url(r'^$', 'project_update_list'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/$', 'project_update_detail'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/cancel/$', 'project_update_cancel'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/stdout/$', 'project_update_stdout'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/scm_inventory_updates/$', 'project_update_scm_inventory_updates'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/notifications/$', 'project_update_notifications_list'),
|
|
||||||
)
|
|
||||||
|
|
||||||
team_urls = patterns('awx.api.views',
|
|
||||||
url(r'^$', 'team_list'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/$', 'team_detail'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/projects/$', 'team_projects_list'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/users/$', 'team_users_list'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/credentials/$', 'team_credentials_list'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/roles/$', 'team_roles_list'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/object_roles/$', 'team_object_roles_list'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/activity_stream/$', 'team_activity_stream_list'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/access_list/$', 'team_access_list'),
|
|
||||||
)
|
|
||||||
|
|
||||||
inventory_urls = patterns('awx.api.views',
|
|
||||||
url(r'^$', 'inventory_list'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/$', 'inventory_detail'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/hosts/$', 'inventory_hosts_list'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/groups/$', 'inventory_groups_list'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/root_groups/$', 'inventory_root_groups_list'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/variable_data/$', 'inventory_variable_data'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/script/$', 'inventory_script_view'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/tree/$', 'inventory_tree_view'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/inventory_sources/$', 'inventory_inventory_sources_list'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/update_inventory_sources/$', 'inventory_inventory_sources_update'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/activity_stream/$', 'inventory_activity_stream_list'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/job_templates/$', 'inventory_job_template_list'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/ad_hoc_commands/$', 'inventory_ad_hoc_commands_list'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/access_list/$', 'inventory_access_list'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/object_roles/$', 'inventory_object_roles_list'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/instance_groups/$', 'inventory_instance_groups_list'),
|
|
||||||
#url(r'^(?P<pk>[0-9]+)/single_fact/$', 'inventory_single_fact_view'),
|
|
||||||
)
|
|
||||||
|
|
||||||
host_urls = patterns('awx.api.views',
|
|
||||||
url(r'^$', 'host_list'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/$', 'host_detail'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/variable_data/$', 'host_variable_data'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/groups/$', 'host_groups_list'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/all_groups/$', 'host_all_groups_list'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/job_events/', 'host_job_events_list'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/job_host_summaries/$', 'host_job_host_summaries_list'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/activity_stream/$', 'host_activity_stream_list'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/inventory_sources/$', 'host_inventory_sources_list'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/smart_inventories/$', 'host_smart_inventories_list'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/ad_hoc_commands/$', 'host_ad_hoc_commands_list'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/ad_hoc_command_events/$', 'host_ad_hoc_command_events_list'),
|
|
||||||
#url(r'^(?P<pk>[0-9]+)/single_fact/$', 'host_single_fact_view'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/fact_versions/$', 'host_fact_versions_list'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/fact_view/$', 'host_fact_compare_view'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/insights/$', 'host_insights'),
|
|
||||||
)
|
|
||||||
|
|
||||||
group_urls = patterns('awx.api.views',
|
|
||||||
url(r'^$', 'group_list'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/$', 'group_detail'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/children/$', 'group_children_list'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/hosts/$', 'group_hosts_list'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/all_hosts/$', 'group_all_hosts_list'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/variable_data/$', 'group_variable_data'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/job_events/$', 'group_job_events_list'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/job_host_summaries/$', 'group_job_host_summaries_list'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/potential_children/$', 'group_potential_children_list'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/activity_stream/$', 'group_activity_stream_list'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/inventory_sources/$', 'group_inventory_sources_list'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/ad_hoc_commands/$', 'group_ad_hoc_commands_list'),
|
|
||||||
#url(r'^(?P<pk>[0-9]+)/single_fact/$', 'group_single_fact_view'),
|
|
||||||
)
|
|
||||||
|
|
||||||
inventory_source_urls = patterns('awx.api.views',
|
|
||||||
url(r'^$', 'inventory_source_list'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/$', 'inventory_source_detail'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/update/$', 'inventory_source_update_view'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/inventory_updates/$', 'inventory_source_updates_list'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/activity_stream/$', 'inventory_source_activity_stream_list'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/schedules/$', 'inventory_source_schedules_list'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/groups/$', 'inventory_source_groups_list'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/hosts/$', 'inventory_source_hosts_list'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/notification_templates_any/$', 'inventory_source_notification_templates_any_list'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/notification_templates_error/$', 'inventory_source_notification_templates_error_list'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/notification_templates_success/$', 'inventory_source_notification_templates_success_list'),
|
|
||||||
)
|
|
||||||
|
|
||||||
inventory_update_urls = patterns('awx.api.views',
|
|
||||||
url(r'^$', 'inventory_update_list'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/$', 'inventory_update_detail'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/cancel/$', 'inventory_update_cancel'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/stdout/$', 'inventory_update_stdout'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/notifications/$', 'inventory_update_notifications_list'),
|
|
||||||
)
|
|
||||||
|
|
||||||
inventory_script_urls = patterns('awx.api.views',
|
|
||||||
url(r'^$', 'inventory_script_list'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/$', 'inventory_script_detail'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/object_roles/$', 'inventory_script_object_roles_list'),
|
|
||||||
)
|
|
||||||
|
|
||||||
credential_type_urls = patterns('awx.api.views',
|
|
||||||
url(r'^$', 'credential_type_list'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/$', 'credential_type_detail'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/credentials/$', 'credential_type_credential_list'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/activity_stream/$', 'credential_type_activity_stream_list'),
|
|
||||||
)
|
|
||||||
|
|
||||||
credential_urls = patterns('awx.api.views',
|
|
||||||
url(r'^$', 'credential_list'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/activity_stream/$', 'credential_activity_stream_list'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/$', 'credential_detail'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/access_list/$', 'credential_access_list'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/object_roles/$', 'credential_object_roles_list'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/owner_users/$', 'credential_owner_users_list'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/owner_teams/$', 'credential_owner_teams_list'),
|
|
||||||
# See also credentials resources on users/teams.
|
|
||||||
)
|
|
||||||
|
|
||||||
role_urls = patterns('awx.api.views',
|
|
||||||
url(r'^$', 'role_list'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/$', 'role_detail'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/users/$', 'role_users_list'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/teams/$', 'role_teams_list'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/parents/$', 'role_parents_list'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/children/$', 'role_children_list'),
|
|
||||||
)
|
|
||||||
|
|
||||||
job_template_urls = patterns('awx.api.views',
|
|
||||||
url(r'^$', 'job_template_list'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/$', 'job_template_detail'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/launch/$', 'job_template_launch'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/jobs/$', 'job_template_jobs_list'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/callback/$', 'job_template_callback'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/schedules/$', 'job_template_schedules_list'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/survey_spec/$', 'job_template_survey_spec'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/activity_stream/$', 'job_template_activity_stream_list'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/notification_templates_any/$', 'job_template_notification_templates_any_list'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/notification_templates_error/$', 'job_template_notification_templates_error_list'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/notification_templates_success/$', 'job_template_notification_templates_success_list'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/instance_groups/$', 'job_template_instance_groups_list'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/access_list/$', 'job_template_access_list'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/object_roles/$', 'job_template_object_roles_list'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/labels/$', 'job_template_label_list'),
|
|
||||||
)
|
|
||||||
|
|
||||||
job_urls = patterns('awx.api.views',
|
|
||||||
url(r'^$', 'job_list'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/$', 'job_detail'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/start/$', 'job_start'), # TODO: remove in 3.3
|
|
||||||
url(r'^(?P<pk>[0-9]+)/cancel/$', 'job_cancel'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/relaunch/$', 'job_relaunch'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/job_host_summaries/$', 'job_job_host_summaries_list'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/job_events/$', 'job_job_events_list'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/activity_stream/$', 'job_activity_stream_list'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/stdout/$', 'job_stdout'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/notifications/$', 'job_notifications_list'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/labels/$', 'job_label_list'),
|
|
||||||
)
|
|
||||||
|
|
||||||
job_host_summary_urls = patterns('awx.api.views',
|
|
||||||
url(r'^(?P<pk>[0-9]+)/$', 'job_host_summary_detail'),
|
|
||||||
)
|
|
||||||
|
|
||||||
job_event_urls = patterns('awx.api.views',
|
|
||||||
url(r'^$', 'job_event_list'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/$', 'job_event_detail'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/children/$', 'job_event_children_list'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/hosts/$', 'job_event_hosts_list'),
|
|
||||||
)
|
|
||||||
|
|
||||||
ad_hoc_command_urls = patterns('awx.api.views',
|
|
||||||
url(r'^$', 'ad_hoc_command_list'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/$', 'ad_hoc_command_detail'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/cancel/$', 'ad_hoc_command_cancel'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/relaunch/$', 'ad_hoc_command_relaunch'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/events/$', 'ad_hoc_command_ad_hoc_command_events_list'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/activity_stream/$', 'ad_hoc_command_activity_stream_list'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/notifications/$', 'ad_hoc_command_notifications_list'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/stdout/$', 'ad_hoc_command_stdout'),
|
|
||||||
)
|
|
||||||
|
|
||||||
ad_hoc_command_event_urls = patterns('awx.api.views',
|
|
||||||
url(r'^$', 'ad_hoc_command_event_list'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/$', 'ad_hoc_command_event_detail'),
|
|
||||||
)
|
|
||||||
|
|
||||||
system_job_template_urls = patterns('awx.api.views',
|
|
||||||
url(r'^$', 'system_job_template_list'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/$', 'system_job_template_detail'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/launch/$', 'system_job_template_launch'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/jobs/$', 'system_job_template_jobs_list'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/schedules/$', 'system_job_template_schedules_list'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/notification_templates_any/$', 'system_job_template_notification_templates_any_list'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/notification_templates_error/$', 'system_job_template_notification_templates_error_list'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/notification_templates_success/$', 'system_job_template_notification_templates_success_list'),
|
|
||||||
)
|
|
||||||
|
|
||||||
system_job_urls = patterns('awx.api.views',
|
|
||||||
url(r'^$', 'system_job_list'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/$', 'system_job_detail'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/cancel/$', 'system_job_cancel'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/notifications/$', 'system_job_notifications_list'),
|
|
||||||
)
|
|
||||||
|
|
||||||
workflow_job_template_urls = patterns('awx.api.views',
|
|
||||||
url(r'^$', 'workflow_job_template_list'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/$', 'workflow_job_template_detail'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/workflow_jobs/$', 'workflow_job_template_jobs_list'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/launch/$', 'workflow_job_template_launch'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/copy/$', 'workflow_job_template_copy'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/schedules/$', 'workflow_job_template_schedules_list'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/survey_spec/$', 'workflow_job_template_survey_spec'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/workflow_nodes/$', 'workflow_job_template_workflow_nodes_list'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/activity_stream/$', 'workflow_job_template_activity_stream_list'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/notification_templates_any/$', 'workflow_job_template_notification_templates_any_list'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/notification_templates_error/$', 'workflow_job_template_notification_templates_error_list'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/notification_templates_success/$', 'workflow_job_template_notification_templates_success_list'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/access_list/$', 'workflow_job_template_access_list'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/object_roles/$', 'workflow_job_template_object_roles_list'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/labels/$', 'workflow_job_template_label_list'),
|
|
||||||
)
|
|
||||||
|
|
||||||
workflow_job_urls = patterns('awx.api.views',
|
|
||||||
url(r'^$', 'workflow_job_list'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/$', 'workflow_job_detail'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/workflow_nodes/$', 'workflow_job_workflow_nodes_list'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/labels/$', 'workflow_job_label_list'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/cancel/$', 'workflow_job_cancel'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/relaunch/$', 'workflow_job_relaunch'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/notifications/$', 'workflow_job_notifications_list'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/activity_stream/$', 'workflow_job_activity_stream_list'),
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
notification_template_urls = patterns('awx.api.views',
|
|
||||||
url(r'^$', 'notification_template_list'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/$', 'notification_template_detail'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/test/$', 'notification_template_test'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/notifications/$', 'notification_template_notification_list'),
|
|
||||||
)
|
|
||||||
|
|
||||||
notification_urls = patterns('awx.api.views',
|
|
||||||
url(r'^$', 'notification_list'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/$', 'notification_detail'),
|
|
||||||
)
|
|
||||||
|
|
||||||
label_urls = patterns('awx.api.views',
|
|
||||||
url(r'^$', 'label_list'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/$', 'label_detail'),
|
|
||||||
)
|
|
||||||
|
|
||||||
workflow_job_template_node_urls = patterns('awx.api.views',
|
|
||||||
url(r'^$', 'workflow_job_template_node_list'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/$', 'workflow_job_template_node_detail'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/success_nodes/$', 'workflow_job_template_node_success_nodes_list'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/failure_nodes/$', 'workflow_job_template_node_failure_nodes_list'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/always_nodes/$', 'workflow_job_template_node_always_nodes_list'),
|
|
||||||
)
|
|
||||||
|
|
||||||
workflow_job_node_urls = patterns('awx.api.views',
|
|
||||||
url(r'^$', 'workflow_job_node_list'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/$', 'workflow_job_node_detail'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/success_nodes/$', 'workflow_job_node_success_nodes_list'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/failure_nodes/$', 'workflow_job_node_failure_nodes_list'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/always_nodes/$', 'workflow_job_node_always_nodes_list'),
|
|
||||||
)
|
|
||||||
|
|
||||||
schedule_urls = patterns('awx.api.views',
|
|
||||||
url(r'^$', 'schedule_list'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/$', 'schedule_detail'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/jobs/$', 'schedule_unified_jobs_list'),
|
|
||||||
)
|
|
||||||
|
|
||||||
activity_stream_urls = patterns('awx.api.views',
|
|
||||||
url(r'^$', 'activity_stream_list'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/$', 'activity_stream_detail'),
|
|
||||||
)
|
|
||||||
|
|
||||||
instance_urls = patterns('awx.api.views',
|
|
||||||
url(r'^$', 'instance_list'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/$', 'instance_detail'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/jobs/$', 'instance_unified_jobs_list'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/instance_groups/$', 'instance_instance_groups_list'),
|
|
||||||
)
|
|
||||||
|
|
||||||
instance_group_urls = patterns('awx.api.views',
|
|
||||||
url(r'^$', 'instance_group_list'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/$', 'instance_group_detail'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/jobs/$', 'instance_group_unified_jobs_list'),
|
|
||||||
url(r'^(?P<pk>[0-9]+)/instances/$', 'instance_group_instance_list'),
|
|
||||||
)
|
|
||||||
|
|
||||||
v1_urls = patterns('awx.api.views',
|
|
||||||
url(r'^$', 'api_v1_root_view'),
|
|
||||||
url(r'^ping/$', 'api_v1_ping_view'),
|
|
||||||
url(r'^config/$', 'api_v1_config_view'),
|
|
||||||
url(r'^auth/$', 'auth_view'),
|
|
||||||
url(r'^authtoken/$', 'auth_token_view'),
|
|
||||||
url(r'^me/$', 'user_me_list'),
|
|
||||||
url(r'^dashboard/$', 'dashboard_view'),
|
|
||||||
url(r'^dashboard/graphs/jobs/$','dashboard_jobs_graph_view'),
|
|
||||||
url(r'^settings/', include('awx.conf.urls')),
|
|
||||||
url(r'^instances/', include(instance_urls)),
|
|
||||||
url(r'^instance_groups/', include(instance_group_urls)),
|
|
||||||
url(r'^schedules/', include(schedule_urls)),
|
|
||||||
url(r'^organizations/', include(organization_urls)),
|
|
||||||
url(r'^users/', include(user_urls)),
|
|
||||||
url(r'^projects/', include(project_urls)),
|
|
||||||
url(r'^project_updates/', include(project_update_urls)),
|
|
||||||
url(r'^teams/', include(team_urls)),
|
|
||||||
url(r'^inventories/', include(inventory_urls)),
|
|
||||||
url(r'^hosts/', include(host_urls)),
|
|
||||||
url(r'^groups/', include(group_urls)),
|
|
||||||
url(r'^inventory_sources/', include(inventory_source_urls)),
|
|
||||||
url(r'^inventory_updates/', include(inventory_update_urls)),
|
|
||||||
url(r'^inventory_scripts/', include(inventory_script_urls)),
|
|
||||||
url(r'^credentials/', include(credential_urls)),
|
|
||||||
url(r'^roles/', include(role_urls)),
|
|
||||||
url(r'^job_templates/', include(job_template_urls)),
|
|
||||||
url(r'^jobs/', include(job_urls)),
|
|
||||||
url(r'^job_host_summaries/', include(job_host_summary_urls)),
|
|
||||||
url(r'^job_events/', include(job_event_urls)),
|
|
||||||
url(r'^ad_hoc_commands/', include(ad_hoc_command_urls)),
|
|
||||||
url(r'^ad_hoc_command_events/', include(ad_hoc_command_event_urls)),
|
|
||||||
url(r'^system_job_templates/', include(system_job_template_urls)),
|
|
||||||
url(r'^system_jobs/', include(system_job_urls)),
|
|
||||||
url(r'^notification_templates/', include(notification_template_urls)),
|
|
||||||
url(r'^notifications/', include(notification_urls)),
|
|
||||||
url(r'^workflow_job_templates/',include(workflow_job_template_urls)),
|
|
||||||
url(r'^workflow_jobs/' ,include(workflow_job_urls)),
|
|
||||||
url(r'^labels/', include(label_urls)),
|
|
||||||
url(r'^workflow_job_template_nodes/', include(workflow_job_template_node_urls)),
|
|
||||||
url(r'^workflow_job_nodes/', include(workflow_job_node_urls)),
|
|
||||||
url(r'^unified_job_templates/$','unified_job_template_list'),
|
|
||||||
url(r'^unified_jobs/$', 'unified_job_list'),
|
|
||||||
url(r'^activity_stream/', include(activity_stream_urls)),
|
|
||||||
)
|
|
||||||
|
|
||||||
v2_urls = patterns('awx.api.views',
|
|
||||||
url(r'^$', 'api_v2_root_view'),
|
|
||||||
url(r'^credential_types/', include(credential_type_urls)),
|
|
||||||
url(r'^hosts/(?P<pk>[0-9]+)/ansible_facts/$', 'host_ansible_facts_detail'),
|
|
||||||
url(r'^jobs/(?P<pk>[0-9]+)/extra_credentials/$', 'job_extra_credentials_list'),
|
|
||||||
url(r'^job_templates/(?P<pk>[0-9]+)/extra_credentials/$', 'job_template_extra_credentials_list'),
|
|
||||||
)
|
|
||||||
|
|
||||||
urlpatterns = patterns('awx.api.views',
|
|
||||||
url(r'^$', 'api_root_view'),
|
|
||||||
url(r'^(?P<version>(v2))/', include(v2_urls)),
|
|
||||||
url(r'^(?P<version>(v1|v2))/', include(v1_urls))
|
|
||||||
)
|
|
||||||
0
awx/api/urls/Pipfile
Normal file
0
awx/api/urls/Pipfile
Normal file
7
awx/api/urls/__init__.py
Normal file
7
awx/api/urls/__init__.py
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
# Copyright (c) 2017 Ansible, Inc.
|
||||||
|
# All Rights Reserved.
|
||||||
|
|
||||||
|
from __future__ import absolute_import, unicode_literals
|
||||||
|
from .urls import urlpatterns
|
||||||
|
|
||||||
|
__all__ = ['urlpatterns']
|
||||||
17
awx/api/urls/activity_stream.py
Normal file
17
awx/api/urls/activity_stream.py
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
# Copyright (c) 2017 Ansible, Inc.
|
||||||
|
# All Rights Reserved.
|
||||||
|
|
||||||
|
from django.conf.urls import url
|
||||||
|
|
||||||
|
from awx.api.views import (
|
||||||
|
ActivityStreamList,
|
||||||
|
ActivityStreamDetail,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
urls = [
|
||||||
|
url(r'^$', ActivityStreamList.as_view(), name='activity_stream_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/$', ActivityStreamDetail.as_view(), name='activity_stream_detail'),
|
||||||
|
]
|
||||||
|
|
||||||
|
__all__ = ['urls']
|
||||||
29
awx/api/urls/ad_hoc_command.py
Normal file
29
awx/api/urls/ad_hoc_command.py
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
# Copyright (c) 2017 Ansible, Inc.
|
||||||
|
# All Rights Reserved.
|
||||||
|
|
||||||
|
from django.conf.urls import url
|
||||||
|
|
||||||
|
from awx.api.views import (
|
||||||
|
AdHocCommandList,
|
||||||
|
AdHocCommandDetail,
|
||||||
|
AdHocCommandCancel,
|
||||||
|
AdHocCommandRelaunch,
|
||||||
|
AdHocCommandAdHocCommandEventsList,
|
||||||
|
AdHocCommandActivityStreamList,
|
||||||
|
AdHocCommandNotificationsList,
|
||||||
|
AdHocCommandStdout,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
urls = [
|
||||||
|
url(r'^$', AdHocCommandList.as_view(), name='ad_hoc_command_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/$', AdHocCommandDetail.as_view(), name='ad_hoc_command_detail'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/cancel/$', AdHocCommandCancel.as_view(), name='ad_hoc_command_cancel'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/relaunch/$', AdHocCommandRelaunch.as_view(), name='ad_hoc_command_relaunch'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/events/$', AdHocCommandAdHocCommandEventsList.as_view(), name='ad_hoc_command_ad_hoc_command_events_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/activity_stream/$', AdHocCommandActivityStreamList.as_view(), name='ad_hoc_command_activity_stream_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/notifications/$', AdHocCommandNotificationsList.as_view(), name='ad_hoc_command_notifications_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/stdout/$', AdHocCommandStdout.as_view(), name='ad_hoc_command_stdout'),
|
||||||
|
]
|
||||||
|
|
||||||
|
__all__ = ['urls']
|
||||||
17
awx/api/urls/ad_hoc_command_event.py
Normal file
17
awx/api/urls/ad_hoc_command_event.py
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
# Copyright (c) 2017 Ansible, Inc.
|
||||||
|
# All Rights Reserved.
|
||||||
|
|
||||||
|
from django.conf.urls import url
|
||||||
|
|
||||||
|
from awx.api.views import (
|
||||||
|
AdHocCommandEventList,
|
||||||
|
AdHocCommandEventDetail,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
urls = [
|
||||||
|
url(r'^$', AdHocCommandEventList.as_view(), name='ad_hoc_command_event_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/$', AdHocCommandEventDetail.as_view(), name='ad_hoc_command_event_detail'),
|
||||||
|
]
|
||||||
|
|
||||||
|
__all__ = ['urls']
|
||||||
27
awx/api/urls/credential.py
Normal file
27
awx/api/urls/credential.py
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
# Copyright (c) 2017 Ansible, Inc.
|
||||||
|
# All Rights Reserved.
|
||||||
|
|
||||||
|
from django.conf.urls import url
|
||||||
|
|
||||||
|
from awx.api.views import (
|
||||||
|
CredentialList,
|
||||||
|
CredentialActivityStreamList,
|
||||||
|
CredentialDetail,
|
||||||
|
CredentialAccessList,
|
||||||
|
CredentialObjectRolesList,
|
||||||
|
CredentialOwnerUsersList,
|
||||||
|
CredentialOwnerTeamsList,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
urls = [
|
||||||
|
url(r'^$', CredentialList.as_view(), name='credential_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/activity_stream/$', CredentialActivityStreamList.as_view(), name='credential_activity_stream_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/$', CredentialDetail.as_view(), name='credential_detail'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/access_list/$', CredentialAccessList.as_view(), name='credential_access_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/object_roles/$', CredentialObjectRolesList.as_view(), name='credential_object_roles_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/owner_users/$', CredentialOwnerUsersList.as_view(), name='credential_owner_users_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/owner_teams/$', CredentialOwnerTeamsList.as_view(), name='credential_owner_teams_list'),
|
||||||
|
]
|
||||||
|
|
||||||
|
__all__ = ['urls']
|
||||||
21
awx/api/urls/credential_type.py
Normal file
21
awx/api/urls/credential_type.py
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
# Copyright (c) 2017 Ansible, Inc.
|
||||||
|
# All Rights Reserved.
|
||||||
|
|
||||||
|
from django.conf.urls import url
|
||||||
|
|
||||||
|
from awx.api.views import (
|
||||||
|
CredentialTypeList,
|
||||||
|
CredentialTypeDetail,
|
||||||
|
CredentialTypeCredentialList,
|
||||||
|
CredentialTypeActivityStreamList,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
urls = [
|
||||||
|
url(r'^$', CredentialTypeList.as_view(), name='credential_type_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/$', CredentialTypeDetail.as_view(), name='credential_type_detail'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/credentials/$', CredentialTypeCredentialList.as_view(), name='credential_type_credential_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/activity_stream/$', CredentialTypeActivityStreamList.as_view(), name='credential_type_activity_stream_list'),
|
||||||
|
]
|
||||||
|
|
||||||
|
__all__ = ['urls']
|
||||||
37
awx/api/urls/group.py
Normal file
37
awx/api/urls/group.py
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
# Copyright (c) 2017 Ansible, Inc.
|
||||||
|
# All Rights Reserved.
|
||||||
|
|
||||||
|
from django.conf.urls import url
|
||||||
|
|
||||||
|
from awx.api.views import (
|
||||||
|
GroupList,
|
||||||
|
GroupDetail,
|
||||||
|
GroupChildrenList,
|
||||||
|
GroupHostsList,
|
||||||
|
GroupAllHostsList,
|
||||||
|
GroupVariableData,
|
||||||
|
GroupJobEventsList,
|
||||||
|
GroupJobHostSummariesList,
|
||||||
|
GroupPotentialChildrenList,
|
||||||
|
GroupActivityStreamList,
|
||||||
|
GroupInventorySourcesList,
|
||||||
|
GroupAdHocCommandsList,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
urls = [
|
||||||
|
url(r'^$', GroupList.as_view(), name='group_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/$', GroupDetail.as_view(), name='group_detail'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/children/$', GroupChildrenList.as_view(), name='group_children_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/hosts/$', GroupHostsList.as_view(), name='group_hosts_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/all_hosts/$', GroupAllHostsList.as_view(), name='group_all_hosts_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/variable_data/$', GroupVariableData.as_view(), name='group_variable_data'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/job_events/$', GroupJobEventsList.as_view(), name='group_job_events_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/job_host_summaries/$', GroupJobHostSummariesList.as_view(), name='group_job_host_summaries_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/potential_children/$', GroupPotentialChildrenList.as_view(), name='group_potential_children_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/activity_stream/$', GroupActivityStreamList.as_view(), name='group_activity_stream_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/inventory_sources/$', GroupInventorySourcesList.as_view(), name='group_inventory_sources_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/ad_hoc_commands/$', GroupAdHocCommandsList.as_view(), name='group_ad_hoc_commands_list'),
|
||||||
|
]
|
||||||
|
|
||||||
|
__all__ = ['urls']
|
||||||
43
awx/api/urls/host.py
Normal file
43
awx/api/urls/host.py
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
# Copyright (c) 2017 Ansible, Inc.
|
||||||
|
# All Rights Reserved.
|
||||||
|
|
||||||
|
from django.conf.urls import url
|
||||||
|
|
||||||
|
from awx.api.views import (
|
||||||
|
HostList,
|
||||||
|
HostDetail,
|
||||||
|
HostVariableData,
|
||||||
|
HostGroupsList,
|
||||||
|
HostAllGroupsList,
|
||||||
|
HostJobEventsList,
|
||||||
|
HostJobHostSummariesList,
|
||||||
|
HostActivityStreamList,
|
||||||
|
HostInventorySourcesList,
|
||||||
|
HostSmartInventoriesList,
|
||||||
|
HostAdHocCommandsList,
|
||||||
|
HostAdHocCommandEventsList,
|
||||||
|
HostFactVersionsList,
|
||||||
|
HostFactCompareView,
|
||||||
|
HostInsights,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
urls = [
|
||||||
|
url(r'^$', HostList.as_view(), name='host_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/$', HostDetail.as_view(), name='host_detail'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/variable_data/$', HostVariableData.as_view(), name='host_variable_data'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/groups/$', HostGroupsList.as_view(), name='host_groups_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/all_groups/$', HostAllGroupsList.as_view(), name='host_all_groups_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/job_events/', HostJobEventsList.as_view(), name='host_job_events_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/job_host_summaries/$', HostJobHostSummariesList.as_view(), name='host_job_host_summaries_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/activity_stream/$', HostActivityStreamList.as_view(), name='host_activity_stream_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/inventory_sources/$', HostInventorySourcesList.as_view(), name='host_inventory_sources_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/smart_inventories/$', HostSmartInventoriesList.as_view(), name='host_smart_inventories_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/ad_hoc_commands/$', HostAdHocCommandsList.as_view(), name='host_ad_hoc_commands_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/ad_hoc_command_events/$', HostAdHocCommandEventsList.as_view(), name='host_ad_hoc_command_events_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/fact_versions/$', HostFactVersionsList.as_view(), name='host_fact_versions_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/fact_view/$', HostFactCompareView.as_view(), name='host_fact_compare_view'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/insights/$', HostInsights.as_view(), name='host_insights'),
|
||||||
|
]
|
||||||
|
|
||||||
|
__all__ = ['urls']
|
||||||
22
awx/api/urls/instance.py
Normal file
22
awx/api/urls/instance.py
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
# Copyright (c) 2017 Ansible, Inc.
|
||||||
|
# All Rights Reserved.
|
||||||
|
|
||||||
|
from django.conf.urls import url
|
||||||
|
|
||||||
|
from awx.api.views import (
|
||||||
|
InstanceList,
|
||||||
|
InstanceDetail,
|
||||||
|
InstanceUnifiedJobsList,
|
||||||
|
InstanceInstanceGroupsList,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
urls = [
|
||||||
|
url(r'^$', InstanceList.as_view(), name='instance_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/$', InstanceDetail.as_view(), name='instance_detail'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/jobs/$', InstanceUnifiedJobsList.as_view(), name='instance_unified_jobs_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/instance_groups/$', InstanceInstanceGroupsList.as_view(),
|
||||||
|
name='instance_instance_groups_list'),
|
||||||
|
]
|
||||||
|
|
||||||
|
__all__ = ['urls']
|
||||||
21
awx/api/urls/instance_group.py
Normal file
21
awx/api/urls/instance_group.py
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
# Copyright (c) 2017 Ansible, Inc.
|
||||||
|
# All Rights Reserved.
|
||||||
|
|
||||||
|
from django.conf.urls import url
|
||||||
|
|
||||||
|
from awx.api.views import (
|
||||||
|
InstanceGroupList,
|
||||||
|
InstanceGroupDetail,
|
||||||
|
InstanceGroupUnifiedJobsList,
|
||||||
|
InstanceGroupInstanceList,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
urls = [
|
||||||
|
url(r'^$', InstanceGroupList.as_view(), name='instance_group_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/$', InstanceGroupDetail.as_view(), name='instance_group_detail'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/jobs/$', InstanceGroupUnifiedJobsList.as_view(), name='instance_group_unified_jobs_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/instances/$', InstanceGroupInstanceList.as_view(), name='instance_group_instance_list'),
|
||||||
|
]
|
||||||
|
|
||||||
|
__all__ = ['urls']
|
||||||
45
awx/api/urls/inventory.py
Normal file
45
awx/api/urls/inventory.py
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
# Copyright (c) 2017 Ansible, Inc.
|
||||||
|
# All Rights Reserved.
|
||||||
|
|
||||||
|
from django.conf.urls import url
|
||||||
|
|
||||||
|
from awx.api.views import (
|
||||||
|
InventoryList,
|
||||||
|
InventoryDetail,
|
||||||
|
InventoryHostsList,
|
||||||
|
InventoryGroupsList,
|
||||||
|
InventoryRootGroupsList,
|
||||||
|
InventoryVariableData,
|
||||||
|
InventoryScriptView,
|
||||||
|
InventoryTreeView,
|
||||||
|
InventoryInventorySourcesList,
|
||||||
|
InventoryInventorySourcesUpdate,
|
||||||
|
InventoryActivityStreamList,
|
||||||
|
InventoryJobTemplateList,
|
||||||
|
InventoryAdHocCommandsList,
|
||||||
|
InventoryAccessList,
|
||||||
|
InventoryObjectRolesList,
|
||||||
|
InventoryInstanceGroupsList,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
urls = [
|
||||||
|
url(r'^$', InventoryList.as_view(), name='inventory_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/$', InventoryDetail.as_view(), name='inventory_detail'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/hosts/$', InventoryHostsList.as_view(), name='inventory_hosts_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/groups/$', InventoryGroupsList.as_view(), name='inventory_groups_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/root_groups/$', InventoryRootGroupsList.as_view(), name='inventory_root_groups_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/variable_data/$', InventoryVariableData.as_view(), name='inventory_variable_data'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/script/$', InventoryScriptView.as_view(), name='inventory_script_view'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/tree/$', InventoryTreeView.as_view(), name='inventory_tree_view'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/inventory_sources/$', InventoryInventorySourcesList.as_view(), name='inventory_inventory_sources_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/update_inventory_sources/$', InventoryInventorySourcesUpdate.as_view(), name='inventory_inventory_sources_update'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/activity_stream/$', InventoryActivityStreamList.as_view(), name='inventory_activity_stream_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/job_templates/$', InventoryJobTemplateList.as_view(), name='inventory_job_template_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/ad_hoc_commands/$', InventoryAdHocCommandsList.as_view(), name='inventory_ad_hoc_commands_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/access_list/$', InventoryAccessList.as_view(), name='inventory_access_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/object_roles/$', InventoryObjectRolesList.as_view(), name='inventory_object_roles_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/instance_groups/$', InventoryInstanceGroupsList.as_view(), name='inventory_instance_groups_list'),
|
||||||
|
]
|
||||||
|
|
||||||
|
__all__ = ['urls']
|
||||||
19
awx/api/urls/inventory_script.py
Normal file
19
awx/api/urls/inventory_script.py
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
# Copyright (c) 2017 Ansible, Inc.
|
||||||
|
# All Rights Reserved.
|
||||||
|
|
||||||
|
from django.conf.urls import url
|
||||||
|
|
||||||
|
from awx.api.views import (
|
||||||
|
InventoryScriptList,
|
||||||
|
InventoryScriptDetail,
|
||||||
|
InventoryScriptObjectRolesList,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
urls = [
|
||||||
|
url(r'^$', InventoryScriptList.as_view(), name='inventory_script_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/$', InventoryScriptDetail.as_view(), name='inventory_script_detail'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/object_roles/$', InventoryScriptObjectRolesList.as_view(), name='inventory_script_object_roles_list'),
|
||||||
|
]
|
||||||
|
|
||||||
|
__all__ = ['urls']
|
||||||
38
awx/api/urls/inventory_source.py
Normal file
38
awx/api/urls/inventory_source.py
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
# Copyright (c) 2017 Ansible, Inc.
|
||||||
|
# All Rights Reserved.
|
||||||
|
|
||||||
|
from django.conf.urls import url
|
||||||
|
|
||||||
|
from awx.api.views import (
|
||||||
|
InventorySourceList,
|
||||||
|
InventorySourceDetail,
|
||||||
|
InventorySourceUpdateView,
|
||||||
|
InventorySourceUpdatesList,
|
||||||
|
InventorySourceActivityStreamList,
|
||||||
|
InventorySourceSchedulesList,
|
||||||
|
InventorySourceGroupsList,
|
||||||
|
InventorySourceHostsList,
|
||||||
|
InventorySourceNotificationTemplatesAnyList,
|
||||||
|
InventorySourceNotificationTemplatesErrorList,
|
||||||
|
InventorySourceNotificationTemplatesSuccessList,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
urls = [
|
||||||
|
url(r'^$', InventorySourceList.as_view(), name='inventory_source_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/$', InventorySourceDetail.as_view(), name='inventory_source_detail'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/update/$', InventorySourceUpdateView.as_view(), name='inventory_source_update_view'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/inventory_updates/$', InventorySourceUpdatesList.as_view(), name='inventory_source_updates_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/activity_stream/$', InventorySourceActivityStreamList.as_view(), name='inventory_source_activity_stream_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/schedules/$', InventorySourceSchedulesList.as_view(), name='inventory_source_schedules_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/groups/$', InventorySourceGroupsList.as_view(), name='inventory_source_groups_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/hosts/$', InventorySourceHostsList.as_view(), name='inventory_source_hosts_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/notification_templates_any/$', InventorySourceNotificationTemplatesAnyList.as_view(),
|
||||||
|
name='inventory_source_notification_templates_any_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/notification_templates_error/$', InventorySourceNotificationTemplatesErrorList.as_view(),
|
||||||
|
name='inventory_source_notification_templates_error_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/notification_templates_success/$', InventorySourceNotificationTemplatesSuccessList.as_view(),
|
||||||
|
name='inventory_source_notification_templates_success_list'),
|
||||||
|
]
|
||||||
|
|
||||||
|
__all__ = ['urls']
|
||||||
23
awx/api/urls/inventory_update.py
Normal file
23
awx/api/urls/inventory_update.py
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
# Copyright (c) 2017 Ansible, Inc.
|
||||||
|
# All Rights Reserved.
|
||||||
|
|
||||||
|
from django.conf.urls import url
|
||||||
|
|
||||||
|
from awx.api.views import (
|
||||||
|
InventoryUpdateList,
|
||||||
|
InventoryUpdateDetail,
|
||||||
|
InventoryUpdateCancel,
|
||||||
|
InventoryUpdateStdout,
|
||||||
|
InventoryUpdateNotificationsList,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
urls = [
|
||||||
|
url(r'^$', InventoryUpdateList.as_view(), name='inventory_update_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/$', InventoryUpdateDetail.as_view(), name='inventory_update_detail'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/cancel/$', InventoryUpdateCancel.as_view(), name='inventory_update_cancel'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/stdout/$', InventoryUpdateStdout.as_view(), name='inventory_update_stdout'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/notifications/$', InventoryUpdateNotificationsList.as_view(), name='inventory_update_notifications_list'),
|
||||||
|
]
|
||||||
|
|
||||||
|
__all__ = ['urls']
|
||||||
37
awx/api/urls/job.py
Normal file
37
awx/api/urls/job.py
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
# Copyright (c) 2017 Ansible, Inc.
|
||||||
|
# All Rights Reserved.
|
||||||
|
|
||||||
|
from django.conf.urls import url
|
||||||
|
|
||||||
|
from awx.api.views import (
|
||||||
|
JobList,
|
||||||
|
JobDetail,
|
||||||
|
JobStart,
|
||||||
|
JobCancel,
|
||||||
|
JobRelaunch,
|
||||||
|
JobJobHostSummariesList,
|
||||||
|
JobJobEventsList,
|
||||||
|
JobActivityStreamList,
|
||||||
|
JobStdout,
|
||||||
|
JobNotificationsList,
|
||||||
|
JobLabelList,
|
||||||
|
JobHostSummaryDetail,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
urls = [
|
||||||
|
url(r'^$', JobList.as_view(), name='job_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/$', JobDetail.as_view(), name='job_detail'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/start/$', JobStart.as_view(), name='job_start'), # Todo: Remove In 3.3
|
||||||
|
url(r'^(?P<pk>[0-9]+)/cancel/$', JobCancel.as_view(), name='job_cancel'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/relaunch/$', JobRelaunch.as_view(), name='job_relaunch'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/job_host_summaries/$', JobJobHostSummariesList.as_view(), name='job_job_host_summaries_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/job_events/$', JobJobEventsList.as_view(), name='job_job_events_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/activity_stream/$', JobActivityStreamList.as_view(), name='job_activity_stream_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/stdout/$', JobStdout.as_view(), name='job_stdout'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/notifications/$', JobNotificationsList.as_view(), name='job_notifications_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/labels/$', JobLabelList.as_view(), name='job_label_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/$', JobHostSummaryDetail.as_view(), name='job_host_summary_detail'),
|
||||||
|
]
|
||||||
|
|
||||||
|
__all__ = ['urls']
|
||||||
21
awx/api/urls/job_event.py
Normal file
21
awx/api/urls/job_event.py
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
# Copyright (c) 2017 Ansible, Inc.
|
||||||
|
# All Rights Reserved.
|
||||||
|
|
||||||
|
from django.conf.urls import url
|
||||||
|
|
||||||
|
from awx.api.views import (
|
||||||
|
JobEventList,
|
||||||
|
JobEventDetail,
|
||||||
|
JobEventChildrenList,
|
||||||
|
JobEventHostsList,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
urls = [
|
||||||
|
url(r'^$', JobEventList.as_view(), name='job_event_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/$', JobEventDetail.as_view(), name='job_event_detail'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/children/$', JobEventChildrenList.as_view(), name='job_event_children_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/hosts/$', JobEventHostsList.as_view(), name='job_event_hosts_list'),
|
||||||
|
]
|
||||||
|
|
||||||
|
__all__ = ['urls']
|
||||||
15
awx/api/urls/job_host_summary.py
Normal file
15
awx/api/urls/job_host_summary.py
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
# Copyright (c) 2017 Ansible, Inc.
|
||||||
|
# All Rights Reserved.
|
||||||
|
|
||||||
|
from django.conf.urls import url
|
||||||
|
|
||||||
|
from awx.api.views import (
|
||||||
|
JobHostSummaryDetail,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
urls = [
|
||||||
|
url(r'^(?P<pk>[0-9]+)/$', JobHostSummaryDetail.as_view(), name='job_host_summary_detail'),
|
||||||
|
]
|
||||||
|
|
||||||
|
__all__ = ['urls']
|
||||||
46
awx/api/urls/job_template.py
Normal file
46
awx/api/urls/job_template.py
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
# Copyright (c) 2017 Ansible, Inc.
|
||||||
|
# All Rights Reserved.
|
||||||
|
|
||||||
|
from django.conf.urls import url
|
||||||
|
|
||||||
|
from awx.api.views import (
|
||||||
|
JobTemplateList,
|
||||||
|
JobTemplateDetail,
|
||||||
|
JobTemplateLaunch,
|
||||||
|
JobTemplateJobsList,
|
||||||
|
JobTemplateCallback,
|
||||||
|
JobTemplateSchedulesList,
|
||||||
|
JobTemplateSurveySpec,
|
||||||
|
JobTemplateActivityStreamList,
|
||||||
|
JobTemplateNotificationTemplatesAnyList,
|
||||||
|
JobTemplateNotificationTemplatesErrorList,
|
||||||
|
JobTemplateNotificationTemplatesSuccessList,
|
||||||
|
JobTemplateInstanceGroupsList,
|
||||||
|
JobTemplateAccessList,
|
||||||
|
JobTemplateObjectRolesList,
|
||||||
|
JobTemplateLabelList,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
urls = [
|
||||||
|
url(r'^$', JobTemplateList.as_view(), name='job_template_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/$', JobTemplateDetail.as_view(), name='job_template_detail'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/launch/$', JobTemplateLaunch.as_view(), name='job_template_launch'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/jobs/$', JobTemplateJobsList.as_view(), name='job_template_jobs_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/callback/$', JobTemplateCallback.as_view(), name='job_template_callback'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/schedules/$', JobTemplateSchedulesList.as_view(), name='job_template_schedules_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/survey_spec/$', JobTemplateSurveySpec.as_view(), name='job_template_survey_spec'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/activity_stream/$', JobTemplateActivityStreamList.as_view(), name='job_template_activity_stream_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/notification_templates_any/$', JobTemplateNotificationTemplatesAnyList.as_view(),
|
||||||
|
name='job_template_notification_templates_any_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/notification_templates_error/$', JobTemplateNotificationTemplatesErrorList.as_view(),
|
||||||
|
name='job_template_notification_templates_error_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/notification_templates_success/$', JobTemplateNotificationTemplatesSuccessList.as_view(),
|
||||||
|
name='job_template_notification_templates_success_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/instance_groups/$', JobTemplateInstanceGroupsList.as_view(), name='job_template_instance_groups_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/access_list/$', JobTemplateAccessList.as_view(), name='job_template_access_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/object_roles/$', JobTemplateObjectRolesList.as_view(), name='job_template_object_roles_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/labels/$', JobTemplateLabelList.as_view(), name='job_template_label_list'),
|
||||||
|
]
|
||||||
|
|
||||||
|
__all__ = ['urls']
|
||||||
17
awx/api/urls/label.py
Normal file
17
awx/api/urls/label.py
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
# Copyright (c) 2017 Ansible, Inc.
|
||||||
|
# All Rights Reserved.
|
||||||
|
|
||||||
|
from django.conf.urls import url
|
||||||
|
|
||||||
|
from awx.api.views import (
|
||||||
|
LabelList,
|
||||||
|
LabelDetail,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
urls = [
|
||||||
|
url(r'^$', LabelList.as_view(), name='label_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/$', LabelDetail.as_view(), name='label_detail'),
|
||||||
|
]
|
||||||
|
|
||||||
|
__all__ = ['urls']
|
||||||
17
awx/api/urls/notification.py
Normal file
17
awx/api/urls/notification.py
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
# Copyright (c) 2017 Ansible, Inc.
|
||||||
|
# All Rights Reserved.
|
||||||
|
|
||||||
|
from django.conf.urls import url
|
||||||
|
|
||||||
|
from awx.api.views import (
|
||||||
|
NotificationList,
|
||||||
|
NotificationDetail,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
urls = [
|
||||||
|
url(r'^$', NotificationList.as_view(), name='notification_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/$', NotificationDetail.as_view(), name='notification_detail'),
|
||||||
|
]
|
||||||
|
|
||||||
|
__all__ = ['urls']
|
||||||
21
awx/api/urls/notification_template.py
Normal file
21
awx/api/urls/notification_template.py
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
# Copyright (c) 2017 Ansible, Inc.
|
||||||
|
# All Rights Reserved.
|
||||||
|
|
||||||
|
from django.conf.urls import url
|
||||||
|
|
||||||
|
from awx.api.views import (
|
||||||
|
NotificationTemplateList,
|
||||||
|
NotificationTemplateDetail,
|
||||||
|
NotificationTemplateTest,
|
||||||
|
NotificationTemplateNotificationList,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
urls = [
|
||||||
|
url(r'^$', NotificationTemplateList.as_view(), name='notification_template_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/$', NotificationTemplateDetail.as_view(), name='notification_template_detail'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/test/$', NotificationTemplateTest.as_view(), name='notification_template_test'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/notifications/$', NotificationTemplateNotificationList.as_view(), name='notification_template_notification_list'),
|
||||||
|
]
|
||||||
|
|
||||||
|
__all__ = ['urls']
|
||||||
50
awx/api/urls/organization.py
Normal file
50
awx/api/urls/organization.py
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
# Copyright (c) 2017 Ansible, Inc.
|
||||||
|
# All Rights Reserved.
|
||||||
|
|
||||||
|
from django.conf.urls import url
|
||||||
|
|
||||||
|
from awx.api.views import (
|
||||||
|
OrganizationList,
|
||||||
|
OrganizationDetail,
|
||||||
|
OrganizationUsersList,
|
||||||
|
OrganizationAdminsList,
|
||||||
|
OrganizationInventoriesList,
|
||||||
|
OrganizationProjectsList,
|
||||||
|
OrganizationWorkflowJobTemplatesList,
|
||||||
|
OrganizationTeamsList,
|
||||||
|
OrganizationCredentialList,
|
||||||
|
OrganizationActivityStreamList,
|
||||||
|
OrganizationNotificationTemplatesList,
|
||||||
|
OrganizationNotificationTemplatesAnyList,
|
||||||
|
OrganizationNotificationTemplatesErrorList,
|
||||||
|
OrganizationNotificationTemplatesSuccessList,
|
||||||
|
OrganizationInstanceGroupsList,
|
||||||
|
OrganizationObjectRolesList,
|
||||||
|
OrganizationAccessList,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
urls = [
|
||||||
|
url(r'^$', OrganizationList.as_view(), name='organization_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/$', OrganizationDetail.as_view(), name='organization_detail'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/users/$', OrganizationUsersList.as_view(), name='organization_users_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/admins/$', OrganizationAdminsList.as_view(), name='organization_admins_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/inventories/$', OrganizationInventoriesList.as_view(), name='organization_inventories_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/projects/$', OrganizationProjectsList.as_view(), name='organization_projects_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/workflow_job_templates/$', OrganizationWorkflowJobTemplatesList.as_view(), name='organization_workflow_job_templates_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/teams/$', OrganizationTeamsList.as_view(), name='organization_teams_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/credentials/$', OrganizationCredentialList.as_view(), name='organization_credential_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/activity_stream/$', OrganizationActivityStreamList.as_view(), name='organization_activity_stream_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/notification_templates/$', OrganizationNotificationTemplatesList.as_view(), name='organization_notification_templates_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/notification_templates_any/$', OrganizationNotificationTemplatesAnyList.as_view(),
|
||||||
|
name='organization_notification_templates_any_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/notification_templates_error/$', OrganizationNotificationTemplatesErrorList.as_view(),
|
||||||
|
name='organization_notification_templates_error_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/notification_templates_success/$', OrganizationNotificationTemplatesSuccessList.as_view(),
|
||||||
|
name='organization_notification_templates_success_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/instance_groups/$', OrganizationInstanceGroupsList.as_view(), name='organization_instance_groups_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/object_roles/$', OrganizationObjectRolesList.as_view(), name='organization_object_roles_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/access_list/$', OrganizationAccessList.as_view(), name='organization_access_list'),
|
||||||
|
]
|
||||||
|
|
||||||
|
__all__ = ['urls']
|
||||||
44
awx/api/urls/project.py
Normal file
44
awx/api/urls/project.py
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
# Copyright (c) 2017 Ansible, Inc.
|
||||||
|
# All Rights Reserved.
|
||||||
|
|
||||||
|
from django.conf.urls import url
|
||||||
|
|
||||||
|
from awx.api.views import (
|
||||||
|
ProjectList,
|
||||||
|
ProjectDetail,
|
||||||
|
ProjectPlaybooks,
|
||||||
|
ProjectInventories,
|
||||||
|
ProjectScmInventorySources,
|
||||||
|
ProjectTeamsList,
|
||||||
|
ProjectUpdateView,
|
||||||
|
ProjectUpdatesList,
|
||||||
|
ProjectActivityStreamList,
|
||||||
|
ProjectSchedulesList,
|
||||||
|
ProjectNotificationTemplatesAnyList,
|
||||||
|
ProjectNotificationTemplatesErrorList,
|
||||||
|
ProjectNotificationTemplatesSuccessList,
|
||||||
|
ProjectObjectRolesList,
|
||||||
|
ProjectAccessList,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
urls = [
|
||||||
|
url(r'^$', ProjectList.as_view(), name='project_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/$', ProjectDetail.as_view(), name='project_detail'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/playbooks/$', ProjectPlaybooks.as_view(), name='project_playbooks'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/inventories/$', ProjectInventories.as_view(), name='project_inventories'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/scm_inventory_sources/$', ProjectScmInventorySources.as_view(), name='project_scm_inventory_sources'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/teams/$', ProjectTeamsList.as_view(), name='project_teams_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/update/$', ProjectUpdateView.as_view(), name='project_update_view'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/project_updates/$', ProjectUpdatesList.as_view(), name='project_updates_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/activity_stream/$', ProjectActivityStreamList.as_view(), name='project_activity_stream_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/schedules/$', ProjectSchedulesList.as_view(), name='project_schedules_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/notification_templates_any/$', ProjectNotificationTemplatesAnyList.as_view(), name='project_notification_templates_any_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/notification_templates_error/$', ProjectNotificationTemplatesErrorList.as_view(), name='project_notification_templates_error_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/notification_templates_success/$', ProjectNotificationTemplatesSuccessList.as_view(),
|
||||||
|
name='project_notification_templates_success_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/object_roles/$', ProjectObjectRolesList.as_view(), name='project_object_roles_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/access_list/$', ProjectAccessList.as_view(), name='project_access_list'),
|
||||||
|
]
|
||||||
|
|
||||||
|
__all__ = ['urls']
|
||||||
25
awx/api/urls/project_update.py
Normal file
25
awx/api/urls/project_update.py
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
# Copyright (c) 2017 Ansible, Inc.
|
||||||
|
# All Rights Reserved.
|
||||||
|
|
||||||
|
from django.conf.urls import url
|
||||||
|
|
||||||
|
from awx.api.views import (
|
||||||
|
ProjectUpdateList,
|
||||||
|
ProjectUpdateDetail,
|
||||||
|
ProjectUpdateCancel,
|
||||||
|
ProjectUpdateStdout,
|
||||||
|
ProjectUpdateScmInventoryUpdates,
|
||||||
|
ProjectUpdateNotificationsList,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
urls = [
|
||||||
|
url(r'^$', ProjectUpdateList.as_view(), name='project_update_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/$', ProjectUpdateDetail.as_view(), name='project_update_detail'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/cancel/$', ProjectUpdateCancel.as_view(), name='project_update_cancel'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/stdout/$', ProjectUpdateStdout.as_view(), name='project_update_stdout'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/scm_inventory_updates/$', ProjectUpdateScmInventoryUpdates.as_view(), name='project_update_scm_inventory_updates'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/notifications/$', ProjectUpdateNotificationsList.as_view(), name='project_update_notifications_list'),
|
||||||
|
]
|
||||||
|
|
||||||
|
__all__ = ['urls']
|
||||||
25
awx/api/urls/role.py
Normal file
25
awx/api/urls/role.py
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
# Copyright (c) 2017 Ansible, Inc.
|
||||||
|
# All Rights Reserved.
|
||||||
|
|
||||||
|
from django.conf.urls import url
|
||||||
|
|
||||||
|
from awx.api.views import (
|
||||||
|
RoleList,
|
||||||
|
RoleDetail,
|
||||||
|
RoleUsersList,
|
||||||
|
RoleTeamsList,
|
||||||
|
RoleParentsList,
|
||||||
|
RoleChildrenList,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
urls = [
|
||||||
|
url(r'^$', RoleList.as_view(), name='role_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/$', RoleDetail.as_view(), name='role_detail'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/users/$', RoleUsersList.as_view(), name='role_users_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/teams/$', RoleTeamsList.as_view(), name='role_teams_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/parents/$', RoleParentsList.as_view(), name='role_parents_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/children/$', RoleChildrenList.as_view(), name='role_children_list'),
|
||||||
|
]
|
||||||
|
|
||||||
|
__all__ = ['urls']
|
||||||
19
awx/api/urls/schedule.py
Normal file
19
awx/api/urls/schedule.py
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
# Copyright (c) 2017 Ansible, Inc.
|
||||||
|
# All Rights Reserved.
|
||||||
|
|
||||||
|
from django.conf.urls import url
|
||||||
|
|
||||||
|
from awx.api.views import (
|
||||||
|
ScheduleList,
|
||||||
|
ScheduleDetail,
|
||||||
|
ScheduleUnifiedJobsList,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
urls = [
|
||||||
|
url(r'^$', ScheduleList.as_view(), name='schedule_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/$', ScheduleDetail.as_view(), name='schedule_detail'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/jobs/$', ScheduleUnifiedJobsList.as_view(), name='schedule_unified_jobs_list'),
|
||||||
|
]
|
||||||
|
|
||||||
|
__all__ = ['urls']
|
||||||
21
awx/api/urls/system_job.py
Normal file
21
awx/api/urls/system_job.py
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
# Copyright (c) 2017 Ansible, Inc.
|
||||||
|
# All Rights Reserved.
|
||||||
|
|
||||||
|
from django.conf.urls import url
|
||||||
|
|
||||||
|
from awx.api.views import (
|
||||||
|
SystemJobList,
|
||||||
|
SystemJobDetail,
|
||||||
|
SystemJobCancel,
|
||||||
|
SystemJobNotificationsList,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
urls = [
|
||||||
|
url(r'^$', SystemJobList.as_view(), name='system_job_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/$', SystemJobDetail.as_view(), name='system_job_detail'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/cancel/$', SystemJobCancel.as_view(), name='system_job_cancel'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/notifications/$', SystemJobNotificationsList.as_view(), name='system_job_notifications_list'),
|
||||||
|
]
|
||||||
|
|
||||||
|
__all__ = ['urls']
|
||||||
32
awx/api/urls/system_job_template.py
Normal file
32
awx/api/urls/system_job_template.py
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
# Copyright (c) 2017 Ansible, Inc.
|
||||||
|
# All Rights Reserved.
|
||||||
|
|
||||||
|
from django.conf.urls import url
|
||||||
|
|
||||||
|
from awx.api.views import (
|
||||||
|
SystemJobTemplateList,
|
||||||
|
SystemJobTemplateDetail,
|
||||||
|
SystemJobTemplateLaunch,
|
||||||
|
SystemJobTemplateJobsList,
|
||||||
|
SystemJobTemplateSchedulesList,
|
||||||
|
SystemJobTemplateNotificationTemplatesAnyList,
|
||||||
|
SystemJobTemplateNotificationTemplatesErrorList,
|
||||||
|
SystemJobTemplateNotificationTemplatesSuccessList,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
urls = [
|
||||||
|
url(r'^$', SystemJobTemplateList.as_view(), name='system_job_template_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/$', SystemJobTemplateDetail.as_view(), name='system_job_template_detail'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/launch/$', SystemJobTemplateLaunch.as_view(), name='system_job_template_launch'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/jobs/$', SystemJobTemplateJobsList.as_view(), name='system_job_template_jobs_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/schedules/$', SystemJobTemplateSchedulesList.as_view(), name='system_job_template_schedules_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/notification_templates_any/$', SystemJobTemplateNotificationTemplatesAnyList.as_view(),
|
||||||
|
name='system_job_template_notification_templates_any_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/notification_templates_error/$', SystemJobTemplateNotificationTemplatesErrorList.as_view(),
|
||||||
|
name='system_job_template_notification_templates_error_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/notification_templates_success/$', SystemJobTemplateNotificationTemplatesSuccessList.as_view(),
|
||||||
|
name='system_job_template_notification_templates_success_list'),
|
||||||
|
]
|
||||||
|
|
||||||
|
__all__ = ['urls']
|
||||||
31
awx/api/urls/team.py
Normal file
31
awx/api/urls/team.py
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
# Copyright (c) 2017 Ansible, Inc.
|
||||||
|
# All Rights Reserved.
|
||||||
|
|
||||||
|
from django.conf.urls import url
|
||||||
|
|
||||||
|
from awx.api.views import (
|
||||||
|
TeamList,
|
||||||
|
TeamDetail,
|
||||||
|
TeamProjectsList,
|
||||||
|
TeamUsersList,
|
||||||
|
TeamCredentialsList,
|
||||||
|
TeamRolesList,
|
||||||
|
TeamObjectRolesList,
|
||||||
|
TeamActivityStreamList,
|
||||||
|
TeamAccessList,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
urls = [
|
||||||
|
url(r'^$', TeamList.as_view(), name='team_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/$', TeamDetail.as_view(), name='team_detail'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/projects/$', TeamProjectsList.as_view(), name='team_projects_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/users/$', TeamUsersList.as_view(), name='team_users_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/credentials/$', TeamCredentialsList.as_view(), name='team_credentials_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/roles/$', TeamRolesList.as_view(), name='team_roles_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/object_roles/$', TeamObjectRolesList.as_view(), name='team_object_roles_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/activity_stream/$', TeamActivityStreamList.as_view(), name='team_activity_stream_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/access_list/$', TeamAccessList.as_view(), name='team_access_list'),
|
||||||
|
]
|
||||||
|
|
||||||
|
__all__ = ['urls']
|
||||||
119
awx/api/urls/urls.py
Normal file
119
awx/api/urls/urls.py
Normal file
@@ -0,0 +1,119 @@
|
|||||||
|
# Copyright (c) 2015 Ansible, Inc.
|
||||||
|
# All Rights Reserved.
|
||||||
|
|
||||||
|
from __future__ import absolute_import, unicode_literals
|
||||||
|
from django.conf.urls import include, url
|
||||||
|
|
||||||
|
from awx.api.views import (
|
||||||
|
ApiRootView,
|
||||||
|
ApiV1RootView,
|
||||||
|
ApiV2RootView,
|
||||||
|
ApiV1PingView,
|
||||||
|
ApiV1ConfigView,
|
||||||
|
AuthView,
|
||||||
|
AuthTokenView,
|
||||||
|
UserMeList,
|
||||||
|
DashboardView,
|
||||||
|
DashboardJobsGraphView,
|
||||||
|
UnifiedJobTemplateList,
|
||||||
|
UnifiedJobList,
|
||||||
|
HostAnsibleFactsDetail,
|
||||||
|
JobExtraCredentialsList,
|
||||||
|
JobTemplateExtraCredentialsList,
|
||||||
|
)
|
||||||
|
|
||||||
|
from .organization import urls as organization_urls
|
||||||
|
from .user import urls as user_urls
|
||||||
|
from .project import urls as project_urls
|
||||||
|
from .project_update import urls as project_update_urls
|
||||||
|
from .inventory import urls as inventory_urls
|
||||||
|
from .team import urls as team_urls
|
||||||
|
from .host import urls as host_urls
|
||||||
|
from .group import urls as group_urls
|
||||||
|
from .inventory_source import urls as inventory_source_urls
|
||||||
|
from .inventory_update import urls as inventory_update_urls
|
||||||
|
from .inventory_script import urls as inventory_script_urls
|
||||||
|
from .credential_type import urls as credential_type_urls
|
||||||
|
from .credential import urls as credential_urls
|
||||||
|
from .role import urls as role_urls
|
||||||
|
from .job_template import urls as job_template_urls
|
||||||
|
from .job import urls as job_urls
|
||||||
|
from .job_host_summary import urls as job_host_summary_urls
|
||||||
|
from .job_event import urls as job_event_urls
|
||||||
|
from .ad_hoc_command import urls as ad_hoc_command_urls
|
||||||
|
from .ad_hoc_command_event import urls as ad_hoc_command_event_urls
|
||||||
|
from .system_job_template import urls as system_job_template_urls
|
||||||
|
from .system_job import urls as system_job_urls
|
||||||
|
from .workflow_job_template import urls as workflow_job_template_urls
|
||||||
|
from .workflow_job import urls as workflow_job_urls
|
||||||
|
from .notification_template import urls as notification_template_urls
|
||||||
|
from .notification import urls as notification_urls
|
||||||
|
from .label import urls as label_urls
|
||||||
|
from .workflow_job_template_node import urls as workflow_job_template_node_urls
|
||||||
|
from .workflow_job_node import urls as workflow_job_node_urls
|
||||||
|
from .schedule import urls as schedule_urls
|
||||||
|
from .activity_stream import urls as activity_stream_urls
|
||||||
|
from .instance import urls as instance_urls
|
||||||
|
from .instance_group import urls as instance_group_urls
|
||||||
|
|
||||||
|
|
||||||
|
v1_urls = [
|
||||||
|
url(r'^$', ApiV1RootView.as_view(), name='api_v1_root_view'),
|
||||||
|
url(r'^ping/$', ApiV1PingView.as_view(), name='api_v1_ping_view'),
|
||||||
|
url(r'^config/$', ApiV1ConfigView.as_view(), name='api_v1_config_view'),
|
||||||
|
url(r'^auth/$', AuthView.as_view()),
|
||||||
|
url(r'^authtoken/$', AuthTokenView.as_view(), name='auth_token_view'),
|
||||||
|
url(r'^me/$', UserMeList.as_view(), name='user_me_list'),
|
||||||
|
url(r'^dashboard/$', DashboardView.as_view(), name='dashboard_view'),
|
||||||
|
url(r'^dashboard/graphs/jobs/$', DashboardJobsGraphView.as_view(), name='dashboard_jobs_graph_view'),
|
||||||
|
url(r'^settings/', include('awx.conf.urls')),
|
||||||
|
url(r'^instances/', include(instance_urls)),
|
||||||
|
url(r'^instance_groups/', include(instance_group_urls)),
|
||||||
|
url(r'^schedules/', include(schedule_urls)),
|
||||||
|
url(r'^organizations/', include(organization_urls)),
|
||||||
|
url(r'^users/', include(user_urls)),
|
||||||
|
url(r'^projects/', include(project_urls)),
|
||||||
|
url(r'^project_updates/', include(project_update_urls)),
|
||||||
|
url(r'^teams/', include(team_urls)),
|
||||||
|
url(r'^inventories/', include(inventory_urls)),
|
||||||
|
url(r'^hosts/', include(host_urls)),
|
||||||
|
url(r'^groups/', include(group_urls)),
|
||||||
|
url(r'^inventory_sources/', include(inventory_source_urls)),
|
||||||
|
url(r'^inventory_updates/', include(inventory_update_urls)),
|
||||||
|
url(r'^inventory_scripts/', include(inventory_script_urls)),
|
||||||
|
url(r'^credentials/', include(credential_urls)),
|
||||||
|
url(r'^roles/', include(role_urls)),
|
||||||
|
url(r'^job_templates/', include(job_template_urls)),
|
||||||
|
url(r'^jobs/', include(job_urls)),
|
||||||
|
url(r'^job_host_summaries/', include(job_host_summary_urls)),
|
||||||
|
url(r'^job_events/', include(job_event_urls)),
|
||||||
|
url(r'^ad_hoc_commands/', include(ad_hoc_command_urls)),
|
||||||
|
url(r'^ad_hoc_command_events/', include(ad_hoc_command_event_urls)),
|
||||||
|
url(r'^system_job_templates/', include(system_job_template_urls)),
|
||||||
|
url(r'^system_jobs/', include(system_job_urls)),
|
||||||
|
url(r'^notification_templates/', include(notification_template_urls)),
|
||||||
|
url(r'^notifications/', include(notification_urls)),
|
||||||
|
url(r'^workflow_job_templates/', include(workflow_job_template_urls)),
|
||||||
|
url(r'^workflow_jobs/', include(workflow_job_urls)),
|
||||||
|
url(r'^labels/', include(label_urls)),
|
||||||
|
url(r'^workflow_job_template_nodes/', include(workflow_job_template_node_urls)),
|
||||||
|
url(r'^workflow_job_nodes/', include(workflow_job_node_urls)),
|
||||||
|
url(r'^unified_job_templates/$', UnifiedJobTemplateList.as_view(), name='unified_job_template_list'),
|
||||||
|
url(r'^unified_jobs/$', UnifiedJobList.as_view(), name='unified_job_list'),
|
||||||
|
url(r'^activity_stream/', include(activity_stream_urls)),
|
||||||
|
]
|
||||||
|
|
||||||
|
v2_urls = [
|
||||||
|
url(r'^$', ApiV2RootView.as_view(), name='api_v2_root_view'),
|
||||||
|
url(r'^credential_types/', include(credential_type_urls)),
|
||||||
|
url(r'^hosts/(?P<pk>[0-9]+)/ansible_facts/$', HostAnsibleFactsDetail.as_view(), name='host_ansible_facts_detail'),
|
||||||
|
url(r'^jobs/(?P<pk>[0-9]+)/extra_credentials/$', JobExtraCredentialsList.as_view(), name='job_extra_credentials_list'),
|
||||||
|
url(r'^job_templates/(?P<pk>[0-9]+)/extra_credentials/$', JobTemplateExtraCredentialsList.as_view(), name='job_template_extra_credentials_list'),
|
||||||
|
]
|
||||||
|
|
||||||
|
app_name = 'api'
|
||||||
|
urlpatterns = [
|
||||||
|
url(r'^$', ApiRootView.as_view(), name='api_root_view'),
|
||||||
|
url(r'^(?P<version>(v2))/', include(v2_urls)),
|
||||||
|
url(r'^(?P<version>(v1|v2))/', include(v1_urls))
|
||||||
|
]
|
||||||
33
awx/api/urls/user.py
Normal file
33
awx/api/urls/user.py
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
# Copyright (c) 2017 Ansible, Inc.
|
||||||
|
# All Rights Reserved.
|
||||||
|
|
||||||
|
from django.conf.urls import url
|
||||||
|
|
||||||
|
from awx.api.views import (
|
||||||
|
UserList,
|
||||||
|
UserDetail,
|
||||||
|
UserTeamsList,
|
||||||
|
UserOrganizationsList,
|
||||||
|
UserAdminOfOrganizationsList,
|
||||||
|
UserProjectsList,
|
||||||
|
UserCredentialsList,
|
||||||
|
UserRolesList,
|
||||||
|
UserActivityStreamList,
|
||||||
|
UserAccessList,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
urls = [
|
||||||
|
url(r'^$', UserList.as_view(), name='user_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/$', UserDetail.as_view(), name='user_detail'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/teams/$', UserTeamsList.as_view(), name='user_teams_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/organizations/$', UserOrganizationsList.as_view(), name='user_organizations_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/admin_of_organizations/$', UserAdminOfOrganizationsList.as_view(), name='user_admin_of_organizations_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/projects/$', UserProjectsList.as_view(), name='user_projects_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/credentials/$', UserCredentialsList.as_view(), name='user_credentials_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/roles/$', UserRolesList.as_view(), name='user_roles_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/activity_stream/$', UserActivityStreamList.as_view(), name='user_activity_stream_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/access_list/$', UserAccessList.as_view(), name='user_access_list'),
|
||||||
|
]
|
||||||
|
|
||||||
|
__all__ = ['urls']
|
||||||
29
awx/api/urls/workflow_job.py
Normal file
29
awx/api/urls/workflow_job.py
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
# Copyright (c) 2017 Ansible, Inc.
|
||||||
|
# All Rights Reserved.
|
||||||
|
|
||||||
|
from django.conf.urls import url
|
||||||
|
|
||||||
|
from awx.api.views import (
|
||||||
|
WorkflowJobList,
|
||||||
|
WorkflowJobDetail,
|
||||||
|
WorkflowJobWorkflowNodesList,
|
||||||
|
WorkflowJobLabelList,
|
||||||
|
WorkflowJobCancel,
|
||||||
|
WorkflowJobRelaunch,
|
||||||
|
WorkflowJobNotificationsList,
|
||||||
|
WorkflowJobActivityStreamList,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
urls = [
|
||||||
|
url(r'^$', WorkflowJobList.as_view(), name='workflow_job_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/$', WorkflowJobDetail.as_view(), name='workflow_job_detail'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/workflow_nodes/$', WorkflowJobWorkflowNodesList.as_view(), name='workflow_job_workflow_nodes_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/labels/$', WorkflowJobLabelList.as_view(), name='workflow_job_label_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/cancel/$', WorkflowJobCancel.as_view(), name='workflow_job_cancel'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/relaunch/$', WorkflowJobRelaunch.as_view(), name='workflow_job_relaunch'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/notifications/$', WorkflowJobNotificationsList.as_view(), name='workflow_job_notifications_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/activity_stream/$', WorkflowJobActivityStreamList.as_view(), name='workflow_job_activity_stream_list'),
|
||||||
|
]
|
||||||
|
|
||||||
|
__all__ = ['urls']
|
||||||
23
awx/api/urls/workflow_job_node.py
Normal file
23
awx/api/urls/workflow_job_node.py
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
# Copyright (c) 2017 Ansible, Inc.
|
||||||
|
# All Rights Reserved.
|
||||||
|
|
||||||
|
from django.conf.urls import url
|
||||||
|
|
||||||
|
from awx.api.views import (
|
||||||
|
WorkflowJobNodeList,
|
||||||
|
WorkflowJobNodeDetail,
|
||||||
|
WorkflowJobNodeSuccessNodesList,
|
||||||
|
WorkflowJobNodeFailureNodesList,
|
||||||
|
WorkflowJobNodeAlwaysNodesList,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
urls = [
|
||||||
|
url(r'^$', WorkflowJobNodeList.as_view(), name='workflow_job_node_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/$', WorkflowJobNodeDetail.as_view(), name='workflow_job_node_detail'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/success_nodes/$', WorkflowJobNodeSuccessNodesList.as_view(), name='workflow_job_node_success_nodes_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/failure_nodes/$', WorkflowJobNodeFailureNodesList.as_view(), name='workflow_job_node_failure_nodes_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/always_nodes/$', WorkflowJobNodeAlwaysNodesList.as_view(), name='workflow_job_node_always_nodes_list'),
|
||||||
|
]
|
||||||
|
|
||||||
|
__all__ = ['urls']
|
||||||
46
awx/api/urls/workflow_job_template.py
Normal file
46
awx/api/urls/workflow_job_template.py
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
# Copyright (c) 2017 Ansible, Inc.
|
||||||
|
# All Rights Reserved.
|
||||||
|
|
||||||
|
from django.conf.urls import url
|
||||||
|
|
||||||
|
from awx.api.views import (
|
||||||
|
WorkflowJobTemplateList,
|
||||||
|
WorkflowJobTemplateDetail,
|
||||||
|
WorkflowJobTemplateJobsList,
|
||||||
|
WorkflowJobTemplateLaunch,
|
||||||
|
WorkflowJobTemplateCopy,
|
||||||
|
WorkflowJobTemplateSchedulesList,
|
||||||
|
WorkflowJobTemplateSurveySpec,
|
||||||
|
WorkflowJobTemplateWorkflowNodesList,
|
||||||
|
WorkflowJobTemplateActivityStreamList,
|
||||||
|
WorkflowJobTemplateNotificationTemplatesAnyList,
|
||||||
|
WorkflowJobTemplateNotificationTemplatesErrorList,
|
||||||
|
WorkflowJobTemplateNotificationTemplatesSuccessList,
|
||||||
|
WorkflowJobTemplateAccessList,
|
||||||
|
WorkflowJobTemplateObjectRolesList,
|
||||||
|
WorkflowJobTemplateLabelList,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
urls = [
|
||||||
|
url(r'^$', WorkflowJobTemplateList.as_view(), name='workflow_job_template_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/$', WorkflowJobTemplateDetail.as_view(), name='workflow_job_template_detail'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/workflow_jobs/$', WorkflowJobTemplateJobsList.as_view(), name='workflow_job_template_jobs_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/launch/$', WorkflowJobTemplateLaunch.as_view(), name='workflow_job_template_launch'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/copy/$', WorkflowJobTemplateCopy.as_view(), name='workflow_job_template_copy'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/schedules/$', WorkflowJobTemplateSchedulesList.as_view(), name='workflow_job_template_schedules_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/survey_spec/$', WorkflowJobTemplateSurveySpec.as_view(), name='workflow_job_template_survey_spec'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/workflow_nodes/$', WorkflowJobTemplateWorkflowNodesList.as_view(), name='workflow_job_template_workflow_nodes_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/activity_stream/$', WorkflowJobTemplateActivityStreamList.as_view(), name='workflow_job_template_activity_stream_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/notification_templates_any/$', WorkflowJobTemplateNotificationTemplatesAnyList.as_view(),
|
||||||
|
name='workflow_job_template_notification_templates_any_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/notification_templates_error/$', WorkflowJobTemplateNotificationTemplatesErrorList.as_view(),
|
||||||
|
name='workflow_job_template_notification_templates_error_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/notification_templates_success/$', WorkflowJobTemplateNotificationTemplatesSuccessList.as_view(),
|
||||||
|
name='workflow_job_template_notification_templates_success_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/access_list/$', WorkflowJobTemplateAccessList.as_view(), name='workflow_job_template_access_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/object_roles/$', WorkflowJobTemplateObjectRolesList.as_view(), name='workflow_job_template_object_roles_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/labels/$', WorkflowJobTemplateLabelList.as_view(), name='workflow_job_template_label_list'),
|
||||||
|
]
|
||||||
|
|
||||||
|
__all__ = ['urls']
|
||||||
23
awx/api/urls/workflow_job_template_node.py
Normal file
23
awx/api/urls/workflow_job_template_node.py
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
# Copyright (c) 2017 Ansible, Inc.
|
||||||
|
# All Rights Reserved.
|
||||||
|
|
||||||
|
from django.conf.urls import url
|
||||||
|
|
||||||
|
from awx.api.views import (
|
||||||
|
WorkflowJobTemplateNodeList,
|
||||||
|
WorkflowJobTemplateNodeDetail,
|
||||||
|
WorkflowJobTemplateNodeSuccessNodesList,
|
||||||
|
WorkflowJobTemplateNodeFailureNodesList,
|
||||||
|
WorkflowJobTemplateNodeAlwaysNodesList,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
urls = [
|
||||||
|
url(r'^$', WorkflowJobTemplateNodeList.as_view(), name='workflow_job_template_node_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/$', WorkflowJobTemplateNodeDetail.as_view(), name='workflow_job_template_node_detail'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/success_nodes/$', WorkflowJobTemplateNodeSuccessNodesList.as_view(), name='workflow_job_template_node_success_nodes_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/failure_nodes/$', WorkflowJobTemplateNodeFailureNodesList.as_view(), name='workflow_job_template_node_failure_nodes_list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/always_nodes/$', WorkflowJobTemplateNodeAlwaysNodesList.as_view(), name='workflow_job_template_node_always_nodes_list'),
|
||||||
|
]
|
||||||
|
|
||||||
|
__all__ = ['urls']
|
||||||
@@ -27,7 +27,6 @@ from django.utils.timezone import now
|
|||||||
from django.views.decorators.csrf import csrf_exempt
|
from django.views.decorators.csrf import csrf_exempt
|
||||||
from django.views.decorators.cache import never_cache
|
from django.views.decorators.cache import never_cache
|
||||||
from django.template.loader import render_to_string
|
from django.template.loader import render_to_string
|
||||||
from django.core.servers.basehttp import FileWrapper
|
|
||||||
from django.http import HttpResponse
|
from django.http import HttpResponse
|
||||||
from django.contrib.contenttypes.models import ContentType
|
from django.contrib.contenttypes.models import ContentType
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
@@ -53,7 +52,9 @@ import qsstats
|
|||||||
import ansiconv
|
import ansiconv
|
||||||
|
|
||||||
# Python Social Auth
|
# Python Social Auth
|
||||||
from social.backends.utils import load_backends
|
from social_core.backends.utils import load_backends
|
||||||
|
|
||||||
|
from wsgiref.util import FileWrapper
|
||||||
|
|
||||||
# AWX
|
# AWX
|
||||||
from awx.main.tasks import send_notifications
|
from awx.main.tasks import send_notifications
|
||||||
|
|||||||
23
awx/celery.py
Normal file
23
awx/celery.py
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
# Copyright (c) 2017 Ansible, Inc.
|
||||||
|
# All Rights Reserved.
|
||||||
|
|
||||||
|
from __future__ import absolute_import, unicode_literals
|
||||||
|
|
||||||
|
import os
|
||||||
|
from celery import Celery
|
||||||
|
|
||||||
|
|
||||||
|
try:
|
||||||
|
import awx.devonly # noqa
|
||||||
|
MODE = 'development'
|
||||||
|
except ImportError: # pragma: no cover
|
||||||
|
MODE = 'production'
|
||||||
|
|
||||||
|
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'awx.settings.%s' % MODE)
|
||||||
|
|
||||||
|
app = Celery('awx')
|
||||||
|
app.config_from_object('django.conf:settings', namespace='CELERY')
|
||||||
|
app.autodiscover_tasks()
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
app.start()
|
||||||
@@ -16,7 +16,7 @@ class SettingSerializer(BaseSerializer):
|
|||||||
class Meta:
|
class Meta:
|
||||||
model = Setting
|
model = Setting
|
||||||
fields = ('id', 'key', 'value')
|
fields = ('id', 'key', 'value')
|
||||||
readonly_fields = ('id', 'key', 'value')
|
read_only_fields = ('id', 'key', 'value')
|
||||||
|
|
||||||
def __init__(self, instance=None, data=serializers.empty, **kwargs):
|
def __init__(self, instance=None, data=serializers.empty, **kwargs):
|
||||||
if instance is None and data is not serializers.empty and 'key' in data:
|
if instance is None and data is not serializers.empty and 'key' in data:
|
||||||
|
|||||||
@@ -1,16 +1,17 @@
|
|||||||
# Copyright (c) 2016 Ansible, Inc.
|
# Copyright (c) 2016 Ansible, Inc.
|
||||||
# All Rights Reserved.
|
# All Rights Reserved.
|
||||||
|
|
||||||
# Django
|
|
||||||
from django.conf.urls import patterns
|
|
||||||
|
|
||||||
# Tower
|
from django.conf.urls import url
|
||||||
from awx.api.urls import url
|
from awx.conf.views import (
|
||||||
|
SettingCategoryList,
|
||||||
|
SettingSingletonDetail,
|
||||||
urlpatterns = patterns(
|
SettingLoggingTest,
|
||||||
'awx.conf.views',
|
|
||||||
url(r'^$', 'setting_category_list'),
|
|
||||||
url(r'^(?P<category_slug>[a-z0-9-]+)/$', 'setting_singleton_detail'),
|
|
||||||
url(r'^logging/test/$', 'setting_logging_test'),
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
urlpatterns = [
|
||||||
|
url(r'^$', SettingCategoryList.as_view(), name='setting_category_list'),
|
||||||
|
url(r'^(?P<category_slug>[a-z0-9-]+)/$', SettingSingletonDetail.as_view(), name='setting_singleton_detail'),
|
||||||
|
url(r'^logging/test/$', SettingLoggingTest.as_view(), name='setting_logging_test'),
|
||||||
|
]
|
||||||
|
|||||||
@@ -54,12 +54,12 @@ def get_object_from_data(field, Model, data, obj=None):
|
|||||||
# Calling method needs to deal with non-existence of key
|
# Calling method needs to deal with non-existence of key
|
||||||
raise ParseError(_("Required related field %s for permission check." % field))
|
raise ParseError(_("Required related field %s for permission check." % field))
|
||||||
|
|
||||||
if isinstance(raw_value, Model):
|
try:
|
||||||
return raw_value
|
if isinstance(raw_value, Model):
|
||||||
elif raw_value is None:
|
return raw_value
|
||||||
return None
|
elif raw_value is None:
|
||||||
else:
|
return None
|
||||||
try:
|
else:
|
||||||
new_pk = int(raw_value)
|
new_pk = int(raw_value)
|
||||||
# Avoid database query by comparing pk to model for similarity
|
# Avoid database query by comparing pk to model for similarity
|
||||||
if obj and new_pk == getattr(obj, '%s_id' % field, None):
|
if obj and new_pk == getattr(obj, '%s_id' % field, None):
|
||||||
@@ -67,8 +67,8 @@ def get_object_from_data(field, Model, data, obj=None):
|
|||||||
else:
|
else:
|
||||||
# Get the new resource from the database
|
# Get the new resource from the database
|
||||||
return get_object_or_400(Model, pk=new_pk)
|
return get_object_or_400(Model, pk=new_pk)
|
||||||
except (TypeError, ValueError):
|
except (TypeError, ValueError):
|
||||||
raise ParseError(_("Bad data found in related field %s." % field))
|
raise ParseError(_("Bad data found in related field %s." % field))
|
||||||
|
|
||||||
|
|
||||||
class StateConflict(ValidationError):
|
class StateConflict(ValidationError):
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ from channels.sessions import channel_session
|
|||||||
from channels.handler import AsgiRequest
|
from channels.handler import AsgiRequest
|
||||||
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.core.serializers.json import DjangoJSONEncoder
|
#from django.core.serializers.json import DjangoJSONEncoder
|
||||||
|
|
||||||
from django.contrib.auth.models import User
|
from django.contrib.auth.models import User
|
||||||
from awx.main.models.organization import AuthToken
|
from awx.main.models.organization import AuthToken
|
||||||
@@ -94,6 +94,8 @@ def ws_receive(message):
|
|||||||
|
|
||||||
def emit_channel_notification(group, payload):
|
def emit_channel_notification(group, payload):
|
||||||
try:
|
try:
|
||||||
Group(group).send({"text": json.dumps(payload, cls=DjangoJSONEncoder)})
|
# FIXME: Currently broken with asgi_rabbitmq as a ChannelLayer
|
||||||
|
#Group(group).send({"text": json.dumps(payload, cls=DjangoJSONEncoder)})
|
||||||
|
logger.warning("Group sending is currently disabled. Would have sent the following message\nChannel: {0}, Payload: {1}".format(group, payload))
|
||||||
except ValueError:
|
except ValueError:
|
||||||
logger.error("Invalid payload emitting channel {} on topic: {}".format(group, payload))
|
logger.error("Invalid payload emitting channel {} on topic: {}".format(group, payload))
|
||||||
|
|||||||
@@ -18,12 +18,12 @@ from django.db.models.signals import (
|
|||||||
)
|
)
|
||||||
from django.db.models.signals import m2m_changed
|
from django.db.models.signals import m2m_changed
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.db.models.fields.related import (
|
from django.db.models.fields.related import add_lazy_relation
|
||||||
add_lazy_relation,
|
from django.db.models.fields.related_descriptors import (
|
||||||
SingleRelatedObjectDescriptor,
|
ReverseOneToOneDescriptor,
|
||||||
ReverseSingleRelatedObjectDescriptor,
|
ForwardManyToOneDescriptor,
|
||||||
ManyRelatedObjectsDescriptor,
|
ManyToManyDescriptor,
|
||||||
ReverseManyRelatedObjectsDescriptor,
|
ReverseManyToOneDescriptor,
|
||||||
)
|
)
|
||||||
from django.utils.encoding import smart_text
|
from django.utils.encoding import smart_text
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
@@ -96,7 +96,7 @@ class JSONBField(upstream_JSONBField):
|
|||||||
# https://bitbucket.org/offline/django-annoying/src/a0de8b294db3/annoying/fields.py
|
# https://bitbucket.org/offline/django-annoying/src/a0de8b294db3/annoying/fields.py
|
||||||
|
|
||||||
|
|
||||||
class AutoSingleRelatedObjectDescriptor(SingleRelatedObjectDescriptor):
|
class AutoSingleRelatedObjectDescriptor(ReverseOneToOneDescriptor):
|
||||||
"""Descriptor for access to the object from its related class."""
|
"""Descriptor for access to the object from its related class."""
|
||||||
|
|
||||||
def __get__(self, instance, instance_type=None):
|
def __get__(self, instance, instance_type=None):
|
||||||
@@ -139,7 +139,7 @@ def resolve_role_field(obj, field):
|
|||||||
raise Exception(smart_text('{} refers to a {}, not a Role'.format(field, type(obj))))
|
raise Exception(smart_text('{} refers to a {}, not a Role'.format(field, type(obj))))
|
||||||
ret.append(obj.id)
|
ret.append(obj.id)
|
||||||
else:
|
else:
|
||||||
if type(obj) is ManyRelatedObjectsDescriptor:
|
if type(obj) is ManyToManyDescriptor:
|
||||||
for o in obj.all():
|
for o in obj.all():
|
||||||
ret += resolve_role_field(o, field_components[1])
|
ret += resolve_role_field(o, field_components[1])
|
||||||
else:
|
else:
|
||||||
@@ -179,7 +179,7 @@ def is_implicit_parent(parent_role, child_role):
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
class ImplicitRoleDescriptor(ReverseSingleRelatedObjectDescriptor):
|
class ImplicitRoleDescriptor(ForwardManyToOneDescriptor):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
@@ -230,18 +230,18 @@ class ImplicitRoleField(models.ForeignKey):
|
|||||||
field_name, sep, field_attr = field_name.partition('.')
|
field_name, sep, field_attr = field_name.partition('.')
|
||||||
field = getattr(cls, field_name)
|
field = getattr(cls, field_name)
|
||||||
|
|
||||||
if type(field) is ReverseManyRelatedObjectsDescriptor or \
|
if type(field) is ReverseManyToOneDescriptor or \
|
||||||
type(field) is ManyRelatedObjectsDescriptor:
|
type(field) is ManyToManyDescriptor:
|
||||||
|
|
||||||
if '.' in field_attr:
|
if '.' in field_attr:
|
||||||
raise Exception('Referencing deep roles through ManyToMany fields is unsupported.')
|
raise Exception('Referencing deep roles through ManyToMany fields is unsupported.')
|
||||||
|
|
||||||
if type(field) is ReverseManyRelatedObjectsDescriptor:
|
if type(field) is ReverseManyToOneDescriptor:
|
||||||
sender = field.through
|
sender = field.through
|
||||||
else:
|
else:
|
||||||
sender = field.related.through
|
sender = field.related.through
|
||||||
|
|
||||||
reverse = type(field) is ManyRelatedObjectsDescriptor
|
reverse = type(field) is ManyToManyDescriptor
|
||||||
m2m_changed.connect(self.m2m_update(field_attr, reverse), sender, weak=False)
|
m2m_changed.connect(self.m2m_update(field_attr, reverse), sender, weak=False)
|
||||||
|
|
||||||
def m2m_update(self, field_attr, _reverse):
|
def m2m_update(self, field_attr, _reverse):
|
||||||
|
|||||||
@@ -2,12 +2,12 @@
|
|||||||
# All Rights Reserved
|
# All Rights Reserved
|
||||||
|
|
||||||
from awx.main.utils import get_licenser
|
from awx.main.utils import get_licenser
|
||||||
from django.core.management.base import NoArgsCommand
|
from django.core.management.base import BaseCommand
|
||||||
|
|
||||||
|
|
||||||
class Command(NoArgsCommand):
|
class Command(BaseCommand):
|
||||||
"""Returns license type, e.g., 'enterprise', 'open', 'none'"""
|
"""Returns license type, e.g., 'enterprise', 'open', 'none'"""
|
||||||
|
|
||||||
def handle(self, **options):
|
def handle(self, *args, **options):
|
||||||
super(Command, self).__init__()
|
super(Command, self).__init__()
|
||||||
return get_licenser().validate().get('license_type', 'none')
|
return get_licenser().validate().get('license_type', 'none')
|
||||||
|
|||||||
@@ -4,29 +4,28 @@
|
|||||||
# Python
|
# Python
|
||||||
import datetime
|
import datetime
|
||||||
import logging
|
import logging
|
||||||
from optparse import make_option
|
|
||||||
|
|
||||||
# Django
|
# Django
|
||||||
from django.core.management.base import NoArgsCommand
|
from django.core.management.base import BaseCommand
|
||||||
from django.utils.timezone import now
|
from django.utils.timezone import now
|
||||||
|
|
||||||
# AWX
|
# AWX
|
||||||
from awx.main.models import ActivityStream
|
from awx.main.models import ActivityStream
|
||||||
|
|
||||||
|
|
||||||
class Command(NoArgsCommand):
|
class Command(BaseCommand):
|
||||||
'''
|
'''
|
||||||
Management command to purge old activity stream events.
|
Management command to purge old activity stream events.
|
||||||
'''
|
'''
|
||||||
|
|
||||||
help = 'Remove old activity stream events from the database'
|
help = 'Remove old activity stream events from the database'
|
||||||
|
|
||||||
option_list = NoArgsCommand.option_list + (
|
def add_arguments(self, parser):
|
||||||
make_option('--days', dest='days', type='int', default=90, metavar='N',
|
parser.add_argument('--days', dest='days', type='int', default=90, metavar='N',
|
||||||
help='Remove activity stream events more than N days old'),
|
help='Remove activity stream events more than N days old')
|
||||||
make_option('--dry-run', dest='dry_run', action='store_true',
|
parser.add_argument('--dry-run', dest='dry_run', action='store_true',
|
||||||
default=False, help='Dry run mode (show items that would '
|
default=False, help='Dry run mode (show items that would '
|
||||||
'be removed)'),)
|
'be removed)')
|
||||||
|
|
||||||
def init_logging(self):
|
def init_logging(self):
|
||||||
log_levels = dict(enumerate([logging.ERROR, logging.INFO,
|
log_levels = dict(enumerate([logging.ERROR, logging.INFO,
|
||||||
@@ -61,7 +60,7 @@ class Command(NoArgsCommand):
|
|||||||
n_deleted_items += len(pks_to_delete)
|
n_deleted_items += len(pks_to_delete)
|
||||||
self.logger.log(99, "Removed %d items", n_deleted_items)
|
self.logger.log(99, "Removed %d items", n_deleted_items)
|
||||||
|
|
||||||
def handle_noargs(self, **options):
|
def handle(self, *args, **options):
|
||||||
self.verbosity = int(options.get('verbosity', 1))
|
self.verbosity = int(options.get('verbosity', 1))
|
||||||
self.init_logging()
|
self.init_logging()
|
||||||
self.days = int(options.get('days', 30))
|
self.days = int(options.get('days', 30))
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
# Python
|
# Python
|
||||||
import re
|
import re
|
||||||
from dateutil.relativedelta import relativedelta
|
from dateutil.relativedelta import relativedelta
|
||||||
from optparse import make_option
|
|
||||||
|
|
||||||
# Django
|
# Django
|
||||||
from django.core.management.base import BaseCommand, CommandError
|
from django.core.management.base import BaseCommand, CommandError
|
||||||
@@ -93,19 +92,20 @@ class CleanupFacts(object):
|
|||||||
|
|
||||||
class Command(BaseCommand):
|
class Command(BaseCommand):
|
||||||
help = 'Cleanup facts. For each host older than the value specified, keep one fact scan for each time window (granularity).'
|
help = 'Cleanup facts. For each host older than the value specified, keep one fact scan for each time window (granularity).'
|
||||||
option_list = BaseCommand.option_list + (
|
|
||||||
make_option('--older_than',
|
def add_arguments(self, parser):
|
||||||
dest='older_than',
|
parser.add_argument('--older_than',
|
||||||
default='30d',
|
dest='older_than',
|
||||||
help='Specify the relative time to consider facts older than (w)eek (d)ay or (y)ear (i.e. 5d, 2w, 1y). Defaults to 30d.'),
|
default='30d',
|
||||||
make_option('--granularity',
|
help='Specify the relative time to consider facts older than (w)eek (d)ay or (y)ear (i.e. 5d, 2w, 1y). Defaults to 30d.')
|
||||||
dest='granularity',
|
parser.add_argument('--granularity',
|
||||||
default='1w',
|
dest='granularity',
|
||||||
help='Window duration to group same hosts by for deletion (w)eek (d)ay or (y)ear (i.e. 5d, 2w, 1y). Defaults to 1w.'),
|
default='1w',
|
||||||
make_option('--module',
|
help='Window duration to group same hosts by for deletion (w)eek (d)ay or (y)ear (i.e. 5d, 2w, 1y). Defaults to 1w.')
|
||||||
dest='module',
|
parser.add_argument('--module',
|
||||||
default=None,
|
dest='module',
|
||||||
help='Limit cleanup to a particular module.'),)
|
default=None,
|
||||||
|
help='Limit cleanup to a particular module.')
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super(Command, self).__init__()
|
super(Command, self).__init__()
|
||||||
|
|||||||
@@ -4,10 +4,9 @@
|
|||||||
# Python
|
# Python
|
||||||
import datetime
|
import datetime
|
||||||
import logging
|
import logging
|
||||||
from optparse import make_option
|
|
||||||
|
|
||||||
# Django
|
# Django
|
||||||
from django.core.management.base import NoArgsCommand, CommandError
|
from django.core.management.base import BaseCommand, CommandError
|
||||||
from django.db import transaction
|
from django.db import transaction
|
||||||
from django.utils.timezone import now
|
from django.utils.timezone import now
|
||||||
|
|
||||||
@@ -25,41 +24,40 @@ from awx.main.signals import ( # noqa
|
|||||||
from django.db.models.signals import post_save, post_delete, m2m_changed # noqa
|
from django.db.models.signals import post_save, post_delete, m2m_changed # noqa
|
||||||
|
|
||||||
|
|
||||||
class Command(NoArgsCommand):
|
class Command(BaseCommand):
|
||||||
'''
|
'''
|
||||||
Management command to cleanup old jobs and project updates.
|
Management command to cleanup old jobs and project updates.
|
||||||
'''
|
'''
|
||||||
|
|
||||||
help = 'Remove old jobs, project and inventory updates from the database.'
|
help = 'Remove old jobs, project and inventory updates from the database.'
|
||||||
|
|
||||||
option_list = NoArgsCommand.option_list + (
|
def add_arguments(self, parser):
|
||||||
make_option('--days', dest='days', type='int', default=90, metavar='N',
|
parser.add_argument('--days', dest='days', type='int', default=90, metavar='N',
|
||||||
help='Remove jobs/updates executed more than N days ago. Defaults to 90.'),
|
help='Remove jobs/updates executed more than N days ago. Defaults to 90.')
|
||||||
make_option('--dry-run', dest='dry_run', action='store_true',
|
parser.add_argument('--dry-run', dest='dry_run', action='store_true',
|
||||||
default=False, help='Dry run mode (show items that would '
|
default=False, help='Dry run mode (show items that would '
|
||||||
'be removed)'),
|
'be removed)')
|
||||||
make_option('--jobs', dest='only_jobs', action='store_true',
|
parser.add_argument('--jobs', dest='only_jobs', action='store_true',
|
||||||
default=False,
|
default=False,
|
||||||
help='Remove jobs'),
|
help='Remove jobs')
|
||||||
make_option('--ad-hoc-commands', dest='only_ad_hoc_commands',
|
parser.add_argument('--ad-hoc-commands', dest='only_ad_hoc_commands',
|
||||||
action='store_true', default=False,
|
action='store_true', default=False,
|
||||||
help='Remove ad hoc commands'),
|
help='Remove ad hoc commands')
|
||||||
make_option('--project-updates', dest='only_project_updates',
|
parser.add_argument('--project-updates', dest='only_project_updates',
|
||||||
action='store_true', default=False,
|
action='store_true', default=False,
|
||||||
help='Remove project updates'),
|
help='Remove project updates')
|
||||||
make_option('--inventory-updates', dest='only_inventory_updates',
|
parser.add_argument('--inventory-updates', dest='only_inventory_updates',
|
||||||
action='store_true', default=False,
|
action='store_true', default=False,
|
||||||
help='Remove inventory updates'),
|
help='Remove inventory updates')
|
||||||
make_option('--management-jobs', default=False,
|
parser.add_argument('--management-jobs', default=False,
|
||||||
action='store_true', dest='only_management_jobs',
|
action='store_true', dest='only_management_jobs',
|
||||||
help='Remove management jobs'),
|
help='Remove management jobs')
|
||||||
make_option('--notifications', dest='only_notifications',
|
parser.add_argument('--notifications', dest='only_notifications',
|
||||||
action='store_true', default=False,
|
action='store_true', default=False,
|
||||||
help='Remove notifications'),
|
help='Remove notifications')
|
||||||
make_option('--workflow-jobs', default=False,
|
parser.add_argument('--workflow-jobs', default=False,
|
||||||
action='store_true', dest='only_workflow_jobs',
|
action='store_true', dest='only_workflow_jobs',
|
||||||
help='Remove workflow jobs')
|
help='Remove workflow jobs')
|
||||||
)
|
|
||||||
|
|
||||||
def cleanup_jobs(self):
|
def cleanup_jobs(self):
|
||||||
#jobs_qs = Job.objects.exclude(status__in=('pending', 'running'))
|
#jobs_qs = Job.objects.exclude(status__in=('pending', 'running'))
|
||||||
@@ -223,7 +221,7 @@ class Command(NoArgsCommand):
|
|||||||
return skipped, deleted
|
return skipped, deleted
|
||||||
|
|
||||||
@transaction.atomic
|
@transaction.atomic
|
||||||
def handle_noargs(self, **options):
|
def handle(self, *args, **options):
|
||||||
self.verbosity = int(options.get('verbosity', 1))
|
self.verbosity = int(options.get('verbosity', 1))
|
||||||
self.init_logging()
|
self.init_logging()
|
||||||
self.days = int(options.get('days', 90))
|
self.days = int(options.get('days', 90))
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
# Copyright (c) 2016 Ansible, Inc.
|
# Copyright (c) 2016 Ansible, Inc.
|
||||||
# All Rights Reserved
|
# All Rights Reserved
|
||||||
|
|
||||||
from optparse import make_option
|
|
||||||
import subprocess
|
import subprocess
|
||||||
import warnings
|
import warnings
|
||||||
|
|
||||||
@@ -22,12 +21,11 @@ class Command(BaseCommand):
|
|||||||
'Specify `--hostname` to use this command.'
|
'Specify `--hostname` to use this command.'
|
||||||
)
|
)
|
||||||
|
|
||||||
option_list = BaseCommand.option_list + (
|
def add_arguments(self, parser):
|
||||||
make_option('--hostname', dest='hostname', type='string',
|
parser.add_argument('--hostname', dest='hostname', type=str,
|
||||||
help='Hostname used during provisioning'),
|
help='Hostname used during provisioning')
|
||||||
make_option('--name', dest='name', type='string',
|
parser.add_argument('--name', dest='name', type=str,
|
||||||
help='(PENDING DEPRECIATION) Hostname used during provisioning'),
|
help='(PENDING DEPRECIATION) Hostname used during provisioning')
|
||||||
)
|
|
||||||
|
|
||||||
@transaction.atomic
|
@transaction.atomic
|
||||||
def handle(self, *args, **options):
|
def handle(self, *args, **options):
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
# Python
|
# Python
|
||||||
import json
|
import json
|
||||||
import logging
|
import logging
|
||||||
from optparse import make_option
|
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
import subprocess
|
import subprocess
|
||||||
@@ -15,7 +14,7 @@ import shutil
|
|||||||
|
|
||||||
# Django
|
# Django
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.core.management.base import NoArgsCommand, CommandError
|
from django.core.management.base import BaseCommand, CommandError
|
||||||
from django.core.exceptions import ImproperlyConfigured
|
from django.core.exceptions import ImproperlyConfigured
|
||||||
from django.db import connection, transaction
|
from django.db import connection, transaction
|
||||||
from django.utils.encoding import smart_text
|
from django.utils.encoding import smart_text
|
||||||
@@ -251,7 +250,7 @@ def load_inventory_source(source, group_filter_re=None,
|
|||||||
return inventory.all_group
|
return inventory.all_group
|
||||||
|
|
||||||
|
|
||||||
class Command(NoArgsCommand):
|
class Command(BaseCommand):
|
||||||
'''
|
'''
|
||||||
Management command to import inventory from a directory, ini file, or
|
Management command to import inventory from a directory, ini file, or
|
||||||
dynamic inventory script.
|
dynamic inventory script.
|
||||||
@@ -259,50 +258,49 @@ class Command(NoArgsCommand):
|
|||||||
|
|
||||||
help = 'Import or sync external inventory sources'
|
help = 'Import or sync external inventory sources'
|
||||||
|
|
||||||
option_list = NoArgsCommand.option_list + (
|
def add_arguments(self, parser):
|
||||||
make_option('--inventory-name', dest='inventory_name', type='str',
|
parser.add_argument('--inventory-name', dest='inventory_name',
|
||||||
default=None, metavar='n',
|
type='str', default=None, metavar='n',
|
||||||
help='name of inventory to sync'),
|
help='name of inventory to sync')
|
||||||
make_option('--inventory-id', dest='inventory_id', type='int',
|
parser.add_argument('--inventory-id', dest='inventory_id', type='int',
|
||||||
default=None, metavar='i', help='id of inventory to sync'),
|
default=None, metavar='i',
|
||||||
make_option('--overwrite', dest='overwrite', action='store_true',
|
help='id of inventory to sync')
|
||||||
metavar="o", default=False,
|
parser.add_argument('--overwrite', dest='overwrite', action='store_true',
|
||||||
help='overwrite the destination hosts and groups'),
|
metavar="o", default=False,
|
||||||
make_option('--overwrite-vars', dest='overwrite_vars',
|
help='overwrite the destination hosts and groups')
|
||||||
action='store_true', metavar="V", default=False,
|
parser.add_argument('--overwrite-vars', dest='overwrite_vars',
|
||||||
help='overwrite (rather than merge) variables'),
|
action='store_true', metavar="V", default=False,
|
||||||
make_option('--keep-vars', dest='keep_vars', action='store_true',
|
help='overwrite (rather than merge) variables')
|
||||||
metavar="k", default=False,
|
parser.add_argument('--keep-vars', dest='keep_vars', action='store_true',
|
||||||
help='use database variables if set'),
|
metavar="k", default=False,
|
||||||
make_option('--custom', dest='custom', action='store_true',
|
help='use database variables if set')
|
||||||
metavar="c", default=False,
|
parser.add_argument('--custom', dest='custom', action='store_true',
|
||||||
help='this is a custom inventory script'),
|
metavar="c", default=False,
|
||||||
make_option('--source', dest='source', type='str', default=None,
|
help='this is a custom inventory script')
|
||||||
metavar='s', help='inventory directory, file, or script '
|
parser.add_argument('--source', dest='source', type='str', default=None,
|
||||||
'to load'),
|
metavar='s', help='inventory directory, file, or script to load')
|
||||||
make_option('--enabled-var', dest='enabled_var', type='str',
|
parser.add_argument('--enabled-var', dest='enabled_var', type='str',
|
||||||
default=None, metavar='v', help='host variable used to '
|
default=None, metavar='v', help='host variable used to '
|
||||||
'set/clear enabled flag when host is online/offline, may '
|
'set/clear enabled flag when host is online/offline, may '
|
||||||
'be specified as "foo.bar" to traverse nested dicts.'),
|
'be specified as "foo.bar" to traverse nested dicts.')
|
||||||
make_option('--enabled-value', dest='enabled_value', type='str',
|
parser.add_argument('--enabled-value', dest='enabled_value', type='str',
|
||||||
default=None, metavar='v', help='value of host variable '
|
default=None, metavar='v', help='value of host variable '
|
||||||
'specified by --enabled-var that indicates host is '
|
'specified by --enabled-var that indicates host is '
|
||||||
'enabled/online.'),
|
'enabled/online.')
|
||||||
make_option('--group-filter', dest='group_filter', type='str',
|
parser.add_argument('--group-filter', dest='group_filter', type='str',
|
||||||
default=None, metavar='regex', help='regular expression '
|
default=None, metavar='regex', help='regular expression '
|
||||||
'to filter group name(s); only matches are imported.'),
|
'to filter group name(s); only matches are imported.')
|
||||||
make_option('--host-filter', dest='host_filter', type='str',
|
parser.add_argument('--host-filter', dest='host_filter', type='str',
|
||||||
default=None, metavar='regex', help='regular expression '
|
default=None, metavar='regex', help='regular expression '
|
||||||
'to filter host name(s); only matches are imported.'),
|
'to filter host name(s); only matches are imported.')
|
||||||
make_option('--exclude-empty-groups', dest='exclude_empty_groups',
|
parser.add_argument('--exclude-empty-groups', dest='exclude_empty_groups',
|
||||||
action='store_true', default=False, help='when set, '
|
action='store_true', default=False, help='when set, '
|
||||||
'exclude all groups that have no child groups, hosts, or '
|
'exclude all groups that have no child groups, hosts, or '
|
||||||
'variables.'),
|
'variables.')
|
||||||
make_option('--instance-id-var', dest='instance_id_var', type='str',
|
parser.add_argument('--instance-id-var', dest='instance_id_var', type='str',
|
||||||
default=None, metavar='v', help='host variable that '
|
default=None, metavar='v', help='host variable that '
|
||||||
'specifies the unique, immutable instance ID, may be '
|
'specifies the unique, immutable instance ID, may be '
|
||||||
'specified as "foo.bar" to traverse nested dicts.'),
|
'specified as "foo.bar" to traverse nested dicts.')
|
||||||
)
|
|
||||||
|
|
||||||
def set_logging_level(self):
|
def set_logging_level(self):
|
||||||
log_levels = dict(enumerate([logging.WARNING, logging.INFO,
|
log_levels = dict(enumerate([logging.WARNING, logging.INFO,
|
||||||
@@ -927,7 +925,7 @@ class Command(NoArgsCommand):
|
|||||||
self.inventory_update.license_error = True
|
self.inventory_update.license_error = True
|
||||||
self.inventory_update.save(update_fields=['license_error'])
|
self.inventory_update.save(update_fields=['license_error'])
|
||||||
|
|
||||||
def handle_noargs(self, **options):
|
def handle(self, *args, **options):
|
||||||
self.verbosity = int(options.get('verbosity', 1))
|
self.verbosity = int(options.get('verbosity', 1))
|
||||||
self.set_logging_level()
|
self.set_logging_level()
|
||||||
self.inventory_name = options.get('inventory_name', None)
|
self.inventory_name = options.get('inventory_name', None)
|
||||||
|
|||||||
@@ -2,14 +2,14 @@
|
|||||||
# All Rights Reserved
|
# All Rights Reserved
|
||||||
|
|
||||||
from awx.main.models import Instance, InstanceGroup
|
from awx.main.models import Instance, InstanceGroup
|
||||||
from django.core.management.base import NoArgsCommand
|
from django.core.management.base import BaseCommand
|
||||||
|
|
||||||
|
|
||||||
class Command(NoArgsCommand):
|
class Command(BaseCommand):
|
||||||
"""List instances from the Tower database
|
"""List instances from the Tower database
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def handle(self, **options):
|
def handle(self, *args, **options):
|
||||||
super(Command, self).__init__()
|
super(Command, self).__init__()
|
||||||
|
|
||||||
for instance in Instance.objects.all():
|
for instance in Instance.objects.all():
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ from awx.main.models import Instance
|
|||||||
from awx.main.utils.pglock import advisory_lock
|
from awx.main.utils.pglock import advisory_lock
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
|
|
||||||
from optparse import make_option
|
|
||||||
from django.db import transaction
|
from django.db import transaction
|
||||||
from django.core.management.base import BaseCommand, CommandError
|
from django.core.management.base import BaseCommand, CommandError
|
||||||
|
|
||||||
@@ -21,10 +20,9 @@ class Command(BaseCommand):
|
|||||||
'Specify `--hostname` to use this command.'
|
'Specify `--hostname` to use this command.'
|
||||||
)
|
)
|
||||||
|
|
||||||
option_list = BaseCommand.option_list + (
|
def add_arguments(self, parser):
|
||||||
make_option('--hostname', dest='hostname', type='string',
|
parser.add_argument('--hostname', dest='hostname', type=str,
|
||||||
help='Hostname used during provisioning'),
|
help='Hostname used during provisioning')
|
||||||
)
|
|
||||||
|
|
||||||
def _register_hostname(self, hostname):
|
def _register_hostname(self, hostname):
|
||||||
if not hostname:
|
if not hostname:
|
||||||
|
|||||||
@@ -5,20 +5,18 @@ import sys
|
|||||||
from awx.main.utils.pglock import advisory_lock
|
from awx.main.utils.pglock import advisory_lock
|
||||||
from awx.main.models import Instance, InstanceGroup
|
from awx.main.models import Instance, InstanceGroup
|
||||||
|
|
||||||
from optparse import make_option
|
|
||||||
from django.core.management.base import BaseCommand, CommandError
|
from django.core.management.base import BaseCommand, CommandError
|
||||||
|
|
||||||
|
|
||||||
class Command(BaseCommand):
|
class Command(BaseCommand):
|
||||||
|
|
||||||
option_list = BaseCommand.option_list + (
|
def add_arguments(self, parser):
|
||||||
make_option('--queuename', dest='queuename', type='string',
|
parser.add_argument('--queuename', dest='queuename', type=str,
|
||||||
help='Queue to create/update'),
|
help='Queue to create/update')
|
||||||
make_option('--hostnames', dest='hostnames', type='string',
|
parser.add_argument('--hostnames', dest='hostnames', type=str,
|
||||||
help='Comma-Delimited Hosts to add to the Queue'),
|
help='Comma-Delimited Hosts to add to the Queue')
|
||||||
make_option('--controller', dest='controller', type='string', default='',
|
parser.add_argument('--controller', dest='controller', type=str,
|
||||||
help='The controlling group (makes this an isolated group)'),
|
default='', help='The controlling group (makes this an isolated group)')
|
||||||
)
|
|
||||||
|
|
||||||
def handle(self, **options):
|
def handle(self, **options):
|
||||||
queuename = options.get('queuename')
|
queuename = options.get('queuename')
|
||||||
|
|||||||
@@ -3,8 +3,6 @@
|
|||||||
import sys
|
import sys
|
||||||
|
|
||||||
from awx.main.models import Instance, InstanceGroup
|
from awx.main.models import Instance, InstanceGroup
|
||||||
|
|
||||||
from optparse import make_option
|
|
||||||
from django.core.management.base import BaseCommand, CommandError
|
from django.core.management.base import BaseCommand, CommandError
|
||||||
|
|
||||||
|
|
||||||
@@ -14,14 +12,13 @@ class Command(BaseCommand):
|
|||||||
"Remove an instance (specified by --hostname) from the specified queue (instance group).\n"
|
"Remove an instance (specified by --hostname) from the specified queue (instance group).\n"
|
||||||
"In order remove the queue, use the `unregister_queue` command.")
|
"In order remove the queue, use the `unregister_queue` command.")
|
||||||
|
|
||||||
option_list = BaseCommand.option_list + (
|
def add_arguments(self, parser):
|
||||||
make_option('--queuename', dest='queuename', type='string',
|
parser.add_argument('--queuename', dest='queuename', type=str,
|
||||||
help='Queue to be removed from'),
|
help='Queue to be removed from')
|
||||||
make_option('--hostname', dest='hostname', type='string',
|
parser.add_argument('--hostname', dest='hostname', type=str,
|
||||||
help='Host to remove from queue'),
|
help='Host to remove from queue')
|
||||||
)
|
|
||||||
|
|
||||||
def handle(self, **options):
|
def handle(self, *arg, **options):
|
||||||
if not options.get('queuename'):
|
if not options.get('queuename'):
|
||||||
raise CommandError('Must specify `--queuename` in order to use command.')
|
raise CommandError('Must specify `--queuename` in order to use command.')
|
||||||
ig = InstanceGroup.objects.filter(name=options.get('queuename'))
|
ig = InstanceGroup.objects.filter(name=options.get('queuename'))
|
||||||
@@ -36,4 +33,3 @@ class Command(BaseCommand):
|
|||||||
i = i.first()
|
i = i.first()
|
||||||
ig.instances.remove(i)
|
ig.instances.remove(i)
|
||||||
print("Instance removed from instance group")
|
print("Instance removed from instance group")
|
||||||
|
|
||||||
|
|||||||
@@ -4,10 +4,9 @@
|
|||||||
import sys
|
import sys
|
||||||
import time
|
import time
|
||||||
import json
|
import json
|
||||||
from optparse import make_option
|
|
||||||
|
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
from django.core.management.base import NoArgsCommand
|
from django.core.management.base import BaseCommand
|
||||||
|
|
||||||
from awx.main.models import (
|
from awx.main.models import (
|
||||||
UnifiedJob,
|
UnifiedJob,
|
||||||
@@ -162,18 +161,17 @@ class ReplayJobEvents():
|
|||||||
print(json.dumps(stats, indent=4, sort_keys=True))
|
print(json.dumps(stats, indent=4, sort_keys=True))
|
||||||
|
|
||||||
|
|
||||||
class Command(NoArgsCommand):
|
class Command(BaseCommand):
|
||||||
|
|
||||||
help = 'Replay job events over websockets ordered by created on date.'
|
help = 'Replay job events over websockets ordered by created on date.'
|
||||||
|
|
||||||
option_list = NoArgsCommand.option_list + (
|
def add_arguments(self, parser):
|
||||||
make_option('--job_id', dest='job_id', type='int', metavar='j',
|
parser.add_argument('--job_id', dest='job_id', type='int', metavar='j',
|
||||||
help='Id of the job to replay (job or adhoc)'),
|
help='Id of the job to replay (job or adhoc)')
|
||||||
make_option('--speed', dest='speed', type='int', metavar='s',
|
parser.add_argument('--speed', dest='speed', type='int', metavar='s',
|
||||||
help='Speedup factor.'),
|
help='Speedup factor.')
|
||||||
)
|
|
||||||
|
|
||||||
def handle_noargs(self, **options):
|
def handle(self, *args, **options):
|
||||||
job_id = options.get('job_id')
|
job_id = options.get('job_id')
|
||||||
speed = options.get('speed') or 1
|
speed = options.get('speed') or 1
|
||||||
verbosity = options.get('verbosity') or 0
|
verbosity = options.get('verbosity') or 0
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ from kombu.mixins import ConsumerMixin
|
|||||||
|
|
||||||
# Django
|
# Django
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.core.management.base import NoArgsCommand
|
from django.core.management.base import BaseCommand
|
||||||
from django.db import connection as django_connection
|
from django.db import connection as django_connection
|
||||||
from django.db import DatabaseError
|
from django.db import DatabaseError
|
||||||
from django.core.cache import cache as django_cache
|
from django.core.cache import cache as django_cache
|
||||||
@@ -147,7 +147,7 @@ class CallbackBrokerWorker(ConsumerMixin):
|
|||||||
logger.error('Detail: {}'.format(tb))
|
logger.error('Detail: {}'.format(tb))
|
||||||
|
|
||||||
|
|
||||||
class Command(NoArgsCommand):
|
class Command(BaseCommand):
|
||||||
'''
|
'''
|
||||||
Save Job Callback receiver (see awx.plugins.callbacks.job_event_callback)
|
Save Job Callback receiver (see awx.plugins.callbacks.job_event_callback)
|
||||||
Runs as a management command and receives job save events. It then hands
|
Runs as a management command and receives job save events. It then hands
|
||||||
@@ -155,8 +155,8 @@ class Command(NoArgsCommand):
|
|||||||
'''
|
'''
|
||||||
help = 'Launch the job callback receiver'
|
help = 'Launch the job callback receiver'
|
||||||
|
|
||||||
def handle_noargs(self, **options):
|
def handle(self, *arg, **options):
|
||||||
with Connection(settings.BROKER_URL) as conn:
|
with Connection(settings.CELERY_BROKER_URL) as conn:
|
||||||
try:
|
try:
|
||||||
worker = CallbackBrokerWorker(conn)
|
worker = CallbackBrokerWorker(conn)
|
||||||
worker.run()
|
worker.run()
|
||||||
|
|||||||
@@ -1,13 +1,11 @@
|
|||||||
# Copyright (c) 2015 Ansible, Inc.
|
# Copyright (c) 2015 Ansible, Inc.
|
||||||
# All Rights Reserved
|
# All Rights Reserved
|
||||||
|
|
||||||
from optparse import make_option
|
|
||||||
|
|
||||||
# Django
|
# Django
|
||||||
from django.core.management.base import BaseCommand
|
from django.core.management.base import BaseCommand
|
||||||
|
|
||||||
# AWX
|
# AWX
|
||||||
from awx.main.models import * # noqa
|
from awx.main.models import UnifiedJob
|
||||||
|
|
||||||
|
|
||||||
class Command(BaseCommand):
|
class Command(BaseCommand):
|
||||||
@@ -17,14 +15,13 @@ class Command(BaseCommand):
|
|||||||
|
|
||||||
help = 'Display some simple statistics'
|
help = 'Display some simple statistics'
|
||||||
|
|
||||||
option_list = BaseCommand.option_list + (
|
def add_arguments(self, parser):
|
||||||
make_option('--stat',
|
parser.add_argument('--stat',
|
||||||
action='store',
|
action='store',
|
||||||
dest='stat',
|
dest='stat',
|
||||||
type="string",
|
type="string",
|
||||||
default="jobs_running",
|
default="jobs_running",
|
||||||
help='Select which stat to get information for'),
|
help='Select which stat to get information for')
|
||||||
)
|
|
||||||
|
|
||||||
def job_stats(self, state):
|
def job_stats(self, state):
|
||||||
return UnifiedJob.objects.filter(status=state).count()
|
return UnifiedJob.objects.filter(status=state).count()
|
||||||
@@ -34,5 +31,3 @@ class Command(BaseCommand):
|
|||||||
self.stdout.write(str(self.job_stats(options['stat'][5:])))
|
self.stdout.write(str(self.job_stats(options['stat'][5:])))
|
||||||
else:
|
else:
|
||||||
self.stdout.write("Supported stats: jobs_{state}")
|
self.stdout.write("Supported stats: jobs_{state}")
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import sys
|
|||||||
from awx.main.utils.pglock import advisory_lock
|
from awx.main.utils.pglock import advisory_lock
|
||||||
from awx.main.models import InstanceGroup
|
from awx.main.models import InstanceGroup
|
||||||
|
|
||||||
from optparse import make_option
|
|
||||||
from django.db import transaction
|
from django.db import transaction
|
||||||
from django.core.management.base import BaseCommand, CommandError
|
from django.core.management.base import BaseCommand, CommandError
|
||||||
|
|
||||||
@@ -17,13 +16,12 @@ class Command(BaseCommand):
|
|||||||
"Instances inside of queue will continue to exist, \n"
|
"Instances inside of queue will continue to exist, \n"
|
||||||
"but jobs will no longer be processed by queue.")
|
"but jobs will no longer be processed by queue.")
|
||||||
|
|
||||||
option_list = BaseCommand.option_list + (
|
def add_arguments(self, parser):
|
||||||
make_option('--queuename', dest='queuename', type='string',
|
parser.add_argument('--queuename', dest='queuename', type=str,
|
||||||
help='Queue to create/update'),
|
help='Queue to create/update')
|
||||||
)
|
|
||||||
|
|
||||||
@transaction.atomic
|
@transaction.atomic
|
||||||
def handle(self, **options):
|
def handle(self, *args, **options):
|
||||||
queuename = options.get('queuename')
|
queuename = options.get('queuename')
|
||||||
if not queuename:
|
if not queuename:
|
||||||
raise CommandError('Must specify `--queuename` in order to use command.')
|
raise CommandError('Must specify `--queuename` in order to use command.')
|
||||||
|
|||||||
@@ -1,9 +1,6 @@
|
|||||||
# Copyright (c) 2016 Ansible, Inc.
|
# Copyright (c) 2016 Ansible, Inc.
|
||||||
# All Rights Reserved
|
# All Rights Reserved
|
||||||
|
|
||||||
# Python
|
|
||||||
from optparse import make_option
|
|
||||||
|
|
||||||
# Django
|
# Django
|
||||||
from django.core.management.base import BaseCommand
|
from django.core.management.base import BaseCommand
|
||||||
from django.core.management.base import CommandError
|
from django.core.management.base import CommandError
|
||||||
@@ -25,12 +22,11 @@ class UpdatePassword(object):
|
|||||||
|
|
||||||
|
|
||||||
class Command(BaseCommand):
|
class Command(BaseCommand):
|
||||||
option_list = BaseCommand.option_list + (
|
def add_arguments(self, parser):
|
||||||
make_option('--username', dest='username', action='store', type='string', default=None,
|
parser.add_argument('--username', dest='username', action='store', type=str, default=None,
|
||||||
help='username to change the password for'),
|
help='username to change the password for')
|
||||||
make_option('--password', dest='password', action='store', type='string', default=None,
|
parser.add_argument('--password', dest='password', action='store', type=str, default=None,
|
||||||
help='new password for user'),
|
help='new password for user')
|
||||||
)
|
|
||||||
|
|
||||||
def handle(self, *args, **options):
|
def handle(self, *args, **options):
|
||||||
if not options['username']:
|
if not options['username']:
|
||||||
@@ -43,5 +39,3 @@ class Command(BaseCommand):
|
|||||||
if res:
|
if res:
|
||||||
return "Password updated"
|
return "Password updated"
|
||||||
return "Password not updated"
|
return "Password not updated"
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ from django.contrib.contenttypes.models import ContentType
|
|||||||
from polymorphic.models import PolymorphicModel
|
from polymorphic.models import PolymorphicModel
|
||||||
|
|
||||||
# Django-Celery
|
# Django-Celery
|
||||||
from djcelery.models import TaskMeta
|
from django_celery_results.models import TaskResult
|
||||||
|
|
||||||
# AWX
|
# AWX
|
||||||
from awx.main.models.base import * # noqa
|
from awx.main.models.base import * # noqa
|
||||||
@@ -88,7 +88,7 @@ class UnifiedJobTemplate(PolymorphicModel, CommonModelNameNotUnique, Notificatio
|
|||||||
ALL_STATUS_CHOICES = OrderedDict(PROJECT_STATUS_CHOICES + INVENTORY_SOURCE_STATUS_CHOICES + JOB_TEMPLATE_STATUS_CHOICES + DEPRECATED_STATUS_CHOICES).items()
|
ALL_STATUS_CHOICES = OrderedDict(PROJECT_STATUS_CHOICES + INVENTORY_SOURCE_STATUS_CHOICES + JOB_TEMPLATE_STATUS_CHOICES + DEPRECATED_STATUS_CHOICES).items()
|
||||||
|
|
||||||
# NOTE: Working around a django-polymorphic issue: https://github.com/django-polymorphic/django-polymorphic/issues/229
|
# NOTE: Working around a django-polymorphic issue: https://github.com/django-polymorphic/django-polymorphic/issues/229
|
||||||
_base_manager = models.Manager()
|
base_manager_name = 'base_objects'
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
app_label = 'main'
|
app_label = 'main'
|
||||||
@@ -438,7 +438,7 @@ class UnifiedJob(PolymorphicModel, PasswordFieldsModel, CommonModelNameNotUnique
|
|||||||
PASSWORD_FIELDS = ('start_args',)
|
PASSWORD_FIELDS = ('start_args',)
|
||||||
|
|
||||||
# NOTE: Working around a django-polymorphic issue: https://github.com/django-polymorphic/django-polymorphic/issues/229
|
# NOTE: Working around a django-polymorphic issue: https://github.com/django-polymorphic/django-polymorphic/issues/229
|
||||||
_base_manager = models.Manager()
|
base_manager_name = 'base_objects'
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
app_label = 'main'
|
app_label = 'main'
|
||||||
@@ -872,8 +872,8 @@ class UnifiedJob(PolymorphicModel, PasswordFieldsModel, CommonModelNameNotUnique
|
|||||||
def celery_task(self):
|
def celery_task(self):
|
||||||
try:
|
try:
|
||||||
if self.celery_task_id:
|
if self.celery_task_id:
|
||||||
return TaskMeta.objects.get(task_id=self.celery_task_id)
|
return TaskResult.objects.get(task_id=self.celery_task_id)
|
||||||
except TaskMeta.DoesNotExist:
|
except TaskResult.DoesNotExist:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def get_passwords_needed_to_start(self):
|
def get_passwords_needed_to_start(self):
|
||||||
@@ -1100,7 +1100,7 @@ class UnifiedJob(PolymorphicModel, PasswordFieldsModel, CommonModelNameNotUnique
|
|||||||
cancel_fields.append('job_explanation')
|
cancel_fields.append('job_explanation')
|
||||||
self.save(update_fields=cancel_fields)
|
self.save(update_fields=cancel_fields)
|
||||||
self.websocket_emit_status("canceled")
|
self.websocket_emit_status("canceled")
|
||||||
if settings.BROKER_URL.startswith('amqp://'):
|
if settings.CELERY_BROKER_URL.startswith('amqp://'):
|
||||||
self._force_cancel()
|
self._force_cancel()
|
||||||
return self.cancel_flag
|
return self.cancel_flag
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ __all__ = ['CallbackQueueDispatcher']
|
|||||||
class CallbackQueueDispatcher(object):
|
class CallbackQueueDispatcher(object):
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.callback_connection = getattr(settings, 'BROKER_URL', None)
|
self.callback_connection = getattr(settings, 'CELERY_BROKER_URL', None)
|
||||||
self.connection_queue = getattr(settings, 'CALLBACK_QUEUE', '')
|
self.connection_queue = getattr(settings, 'CALLBACK_QUEUE', '')
|
||||||
self.connection = None
|
self.connection = None
|
||||||
self.exchange = None
|
self.exchange = None
|
||||||
|
|||||||
@@ -41,7 +41,8 @@ from awx.main import tasks as awx_tasks
|
|||||||
from awx.main.utils import decrypt_field
|
from awx.main.utils import decrypt_field
|
||||||
|
|
||||||
# Celery
|
# Celery
|
||||||
from celery.task.control import inspect
|
from awx import celery_app
|
||||||
|
from celery.app.control import Inspect
|
||||||
|
|
||||||
|
|
||||||
logger = logging.getLogger('awx.main.scheduler')
|
logger = logging.getLogger('awx.main.scheduler')
|
||||||
@@ -130,8 +131,8 @@ class TaskManager():
|
|||||||
}
|
}
|
||||||
'''
|
'''
|
||||||
def get_active_tasks(self):
|
def get_active_tasks(self):
|
||||||
inspector = inspect()
|
|
||||||
if not hasattr(settings, 'IGNORE_CELERY_INSPECTOR'):
|
if not hasattr(settings, 'IGNORE_CELERY_INSPECTOR'):
|
||||||
|
inspector = Inspect(app=celery_app)
|
||||||
active_task_queues = inspector.active()
|
active_task_queues = inspector.active()
|
||||||
else:
|
else:
|
||||||
logger.warn("Ignoring celery task inspector")
|
logger.warn("Ignoring celery task inspector")
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
import logging
|
import logging
|
||||||
|
|
||||||
# Celery
|
# Celery
|
||||||
from celery import Task, task
|
from celery import Task, shared_task
|
||||||
|
|
||||||
# AWX
|
# AWX
|
||||||
from awx.main.scheduler import TaskManager
|
from awx.main.scheduler import TaskManager
|
||||||
@@ -21,17 +21,17 @@ class LogErrorsTask(Task):
|
|||||||
super(LogErrorsTask, self).on_failure(exc, task_id, args, kwargs, einfo)
|
super(LogErrorsTask, self).on_failure(exc, task_id, args, kwargs, einfo)
|
||||||
|
|
||||||
|
|
||||||
@task
|
@shared_task
|
||||||
def run_job_launch(job_id):
|
def run_job_launch(job_id):
|
||||||
TaskManager().schedule()
|
TaskManager().schedule()
|
||||||
|
|
||||||
|
|
||||||
@task
|
@shared_task
|
||||||
def run_job_complete(job_id):
|
def run_job_complete(job_id):
|
||||||
TaskManager().schedule()
|
TaskManager().schedule()
|
||||||
|
|
||||||
|
|
||||||
@task(base=LogErrorsTask)
|
@shared_task(base=LogErrorsTask)
|
||||||
def run_task_manager():
|
def run_task_manager():
|
||||||
logger.debug("Running Tower task manager.")
|
logger.debug("Running Tower task manager.")
|
||||||
TaskManager().schedule()
|
TaskManager().schedule()
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ except Exception:
|
|||||||
psutil = None
|
psutil = None
|
||||||
|
|
||||||
# Celery
|
# Celery
|
||||||
from celery import Task, task
|
from celery import Task, shared_task
|
||||||
from celery.signals import celeryd_init, worker_process_init, worker_shutdown
|
from celery.signals import celeryd_init, worker_process_init, worker_shutdown
|
||||||
|
|
||||||
# Django
|
# Django
|
||||||
@@ -46,6 +46,7 @@ from crum import impersonate
|
|||||||
|
|
||||||
# AWX
|
# AWX
|
||||||
from awx import __version__ as awx_application_version
|
from awx import __version__ as awx_application_version
|
||||||
|
from awx import celery_app
|
||||||
from awx.main.constants import CLOUD_PROVIDERS, PRIVILEGE_ESCALATION_METHODS
|
from awx.main.constants import CLOUD_PROVIDERS, PRIVILEGE_ESCALATION_METHODS
|
||||||
from awx.main.models import * # noqa
|
from awx.main.models import * # noqa
|
||||||
from awx.main.models.unified_jobs import ACTIVE_STATES
|
from awx.main.models.unified_jobs import ACTIVE_STATES
|
||||||
@@ -131,7 +132,7 @@ def inform_cluster_of_shutdown(*args, **kwargs):
|
|||||||
logger.exception('Encountered problem with normal shutdown signal.')
|
logger.exception('Encountered problem with normal shutdown signal.')
|
||||||
|
|
||||||
|
|
||||||
@task(queue='tower_broadcast_all', bind=True, base=LogErrorsTask)
|
@shared_task(queue='tower_broadcast_all', bind=True, base=LogErrorsTask)
|
||||||
def handle_setting_changes(self, setting_keys):
|
def handle_setting_changes(self, setting_keys):
|
||||||
orig_len = len(setting_keys)
|
orig_len = len(setting_keys)
|
||||||
for i in range(orig_len):
|
for i in range(orig_len):
|
||||||
@@ -148,7 +149,7 @@ def handle_setting_changes(self, setting_keys):
|
|||||||
break
|
break
|
||||||
|
|
||||||
|
|
||||||
@task(queue='tower', base=LogErrorsTask)
|
@shared_task(queue='tower', base=LogErrorsTask)
|
||||||
def send_notifications(notification_list, job_id=None):
|
def send_notifications(notification_list, job_id=None):
|
||||||
if not isinstance(notification_list, list):
|
if not isinstance(notification_list, list):
|
||||||
raise TypeError("notification_list should be of type list")
|
raise TypeError("notification_list should be of type list")
|
||||||
@@ -172,7 +173,7 @@ def send_notifications(notification_list, job_id=None):
|
|||||||
notification.save()
|
notification.save()
|
||||||
|
|
||||||
|
|
||||||
@task(bind=True, queue='tower', base=LogErrorsTask)
|
@shared_task(bind=True, queue='tower', base=LogErrorsTask)
|
||||||
def run_administrative_checks(self):
|
def run_administrative_checks(self):
|
||||||
logger.warn("Running administrative checks.")
|
logger.warn("Running administrative checks.")
|
||||||
if not settings.TOWER_ADMIN_ALERTS:
|
if not settings.TOWER_ADMIN_ALERTS:
|
||||||
@@ -194,13 +195,13 @@ def run_administrative_checks(self):
|
|||||||
fail_silently=True)
|
fail_silently=True)
|
||||||
|
|
||||||
|
|
||||||
@task(bind=True, queue='tower', base=LogErrorsTask)
|
@shared_task(bind=True, queue='tower', base=LogErrorsTask)
|
||||||
def cleanup_authtokens(self):
|
def cleanup_authtokens(self):
|
||||||
logger.warn("Cleaning up expired authtokens.")
|
logger.warn("Cleaning up expired authtokens.")
|
||||||
AuthToken.objects.filter(expires__lt=now()).delete()
|
AuthToken.objects.filter(expires__lt=now()).delete()
|
||||||
|
|
||||||
|
|
||||||
@task(bind=True, base=LogErrorsTask)
|
@shared_task(bind=True, base=LogErrorsTask)
|
||||||
def purge_old_stdout_files(self):
|
def purge_old_stdout_files(self):
|
||||||
nowtime = time.time()
|
nowtime = time.time()
|
||||||
for f in os.listdir(settings.JOBOUTPUT_ROOT):
|
for f in os.listdir(settings.JOBOUTPUT_ROOT):
|
||||||
@@ -209,7 +210,7 @@ def purge_old_stdout_files(self):
|
|||||||
logger.info("Removing {}".format(os.path.join(settings.JOBOUTPUT_ROOT,f)))
|
logger.info("Removing {}".format(os.path.join(settings.JOBOUTPUT_ROOT,f)))
|
||||||
|
|
||||||
|
|
||||||
@task(bind=True, base=LogErrorsTask)
|
@shared_task(bind=True, base=LogErrorsTask)
|
||||||
def cluster_node_heartbeat(self):
|
def cluster_node_heartbeat(self):
|
||||||
logger.debug("Cluster node heartbeat task.")
|
logger.debug("Cluster node heartbeat task.")
|
||||||
nowtime = now()
|
nowtime = now()
|
||||||
@@ -262,7 +263,7 @@ def cluster_node_heartbeat(self):
|
|||||||
logger.exception('Error marking {} as lost'.format(other_inst.hostname))
|
logger.exception('Error marking {} as lost'.format(other_inst.hostname))
|
||||||
|
|
||||||
|
|
||||||
@task(bind=True, base=LogErrorsTask)
|
@shared_task(bind=True, base=LogErrorsTask)
|
||||||
def awx_isolated_heartbeat(self):
|
def awx_isolated_heartbeat(self):
|
||||||
local_hostname = settings.CLUSTER_HOST_ID
|
local_hostname = settings.CLUSTER_HOST_ID
|
||||||
logger.debug("Controlling node checking for any isolated management tasks.")
|
logger.debug("Controlling node checking for any isolated management tasks.")
|
||||||
@@ -286,7 +287,7 @@ def awx_isolated_heartbeat(self):
|
|||||||
isolated_manager.IsolatedManager.health_check(isolated_instance_qs, awx_application_version)
|
isolated_manager.IsolatedManager.health_check(isolated_instance_qs, awx_application_version)
|
||||||
|
|
||||||
|
|
||||||
@task(bind=True, queue='tower', base=LogErrorsTask)
|
@shared_task(bind=True, queue='tower', base=LogErrorsTask)
|
||||||
def awx_periodic_scheduler(self):
|
def awx_periodic_scheduler(self):
|
||||||
run_now = now()
|
run_now = now()
|
||||||
state = TowerScheduleState.get_solo()
|
state = TowerScheduleState.get_solo()
|
||||||
@@ -340,7 +341,7 @@ def _send_notification_templates(instance, status_str):
|
|||||||
job_id=instance.id)
|
job_id=instance.id)
|
||||||
|
|
||||||
|
|
||||||
@task(bind=True, queue='tower', base=LogErrorsTask)
|
@shared_task(bind=True, queue='tower', base=LogErrorsTask)
|
||||||
def handle_work_success(self, result, task_actual):
|
def handle_work_success(self, result, task_actual):
|
||||||
try:
|
try:
|
||||||
instance = UnifiedJob.get_instance_by_type(task_actual['type'], task_actual['id'])
|
instance = UnifiedJob.get_instance_by_type(task_actual['type'], task_actual['id'])
|
||||||
@@ -356,7 +357,7 @@ def handle_work_success(self, result, task_actual):
|
|||||||
run_job_complete.delay(instance.id)
|
run_job_complete.delay(instance.id)
|
||||||
|
|
||||||
|
|
||||||
@task(bind=True, queue='tower', base=LogErrorsTask)
|
@shared_task(bind=True, queue='tower', base=LogErrorsTask)
|
||||||
def handle_work_error(self, task_id, subtasks=None):
|
def handle_work_error(self, task_id, subtasks=None):
|
||||||
logger.debug('Executing error task id %s, subtasks: %s' % (str(self.request.id), str(subtasks)))
|
logger.debug('Executing error task id %s, subtasks: %s' % (str(self.request.id), str(subtasks)))
|
||||||
first_instance = None
|
first_instance = None
|
||||||
@@ -399,7 +400,7 @@ def handle_work_error(self, task_id, subtasks=None):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
@task(queue='tower', base=LogErrorsTask)
|
@shared_task(queue='tower', base=LogErrorsTask)
|
||||||
def update_inventory_computed_fields(inventory_id, should_update_hosts=True):
|
def update_inventory_computed_fields(inventory_id, should_update_hosts=True):
|
||||||
'''
|
'''
|
||||||
Signal handler and wrapper around inventory.update_computed_fields to
|
Signal handler and wrapper around inventory.update_computed_fields to
|
||||||
@@ -419,7 +420,7 @@ def update_inventory_computed_fields(inventory_id, should_update_hosts=True):
|
|||||||
raise
|
raise
|
||||||
|
|
||||||
|
|
||||||
@task(queue='tower', base=LogErrorsTask)
|
@shared_task(queue='tower', base=LogErrorsTask)
|
||||||
def update_host_smart_inventory_memberships():
|
def update_host_smart_inventory_memberships():
|
||||||
try:
|
try:
|
||||||
with transaction.atomic():
|
with transaction.atomic():
|
||||||
@@ -435,7 +436,7 @@ def update_host_smart_inventory_memberships():
|
|||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
@task(bind=True, queue='tower', base=LogErrorsTask, max_retries=5)
|
@shared_task(bind=True, queue='tower', base=LogErrorsTask, max_retries=5)
|
||||||
def delete_inventory(self, inventory_id, user_id):
|
def delete_inventory(self, inventory_id, user_id):
|
||||||
# Delete inventory as user
|
# Delete inventory as user
|
||||||
if user_id is None:
|
if user_id is None:
|
||||||
@@ -1003,7 +1004,7 @@ class RunJob(BaseTask):
|
|||||||
env['TOWER_HOST'] = settings.TOWER_URL_BASE
|
env['TOWER_HOST'] = settings.TOWER_URL_BASE
|
||||||
env['AWX_HOST'] = settings.TOWER_URL_BASE
|
env['AWX_HOST'] = settings.TOWER_URL_BASE
|
||||||
env['CALLBACK_QUEUE'] = settings.CALLBACK_QUEUE
|
env['CALLBACK_QUEUE'] = settings.CALLBACK_QUEUE
|
||||||
env['CALLBACK_CONNECTION'] = settings.BROKER_URL
|
env['CALLBACK_CONNECTION'] = settings.CELERY_BROKER_URL
|
||||||
env['CACHE'] = settings.CACHES['default']['LOCATION'] if 'LOCATION' in settings.CACHES['default'] else ''
|
env['CACHE'] = settings.CACHES['default']['LOCATION'] if 'LOCATION' in settings.CACHES['default'] else ''
|
||||||
if getattr(settings, 'JOB_CALLBACK_DEBUG', False):
|
if getattr(settings, 'JOB_CALLBACK_DEBUG', False):
|
||||||
env['JOB_CALLBACK_DEBUG'] = '2'
|
env['JOB_CALLBACK_DEBUG'] = '2'
|
||||||
@@ -2054,7 +2055,7 @@ class RunAdHocCommand(BaseTask):
|
|||||||
env['ANSIBLE_LOAD_CALLBACK_PLUGINS'] = '1'
|
env['ANSIBLE_LOAD_CALLBACK_PLUGINS'] = '1'
|
||||||
env['ANSIBLE_STDOUT_CALLBACK'] = 'minimal' # Hardcoded by Ansible for ad-hoc commands (either minimal or oneline).
|
env['ANSIBLE_STDOUT_CALLBACK'] = 'minimal' # Hardcoded by Ansible for ad-hoc commands (either minimal or oneline).
|
||||||
env['CALLBACK_QUEUE'] = settings.CALLBACK_QUEUE
|
env['CALLBACK_QUEUE'] = settings.CALLBACK_QUEUE
|
||||||
env['CALLBACK_CONNECTION'] = settings.BROKER_URL
|
env['CALLBACK_CONNECTION'] = settings.CELERY_BROKER_URL
|
||||||
env['ANSIBLE_SFTP_BATCH_MODE'] = 'False'
|
env['ANSIBLE_SFTP_BATCH_MODE'] = 'False'
|
||||||
env['CACHE'] = settings.CACHES['default']['LOCATION'] if 'LOCATION' in settings.CACHES['default'] else ''
|
env['CACHE'] = settings.CACHES['default']['LOCATION'] if 'LOCATION' in settings.CACHES['default'] else ''
|
||||||
if getattr(settings, 'JOB_CALLBACK_DEBUG', False):
|
if getattr(settings, 'JOB_CALLBACK_DEBUG', False):
|
||||||
@@ -2221,3 +2222,10 @@ class RunSystemJob(BaseTask):
|
|||||||
|
|
||||||
def build_cwd(self, instance, **kwargs):
|
def build_cwd(self, instance, **kwargs):
|
||||||
return settings.BASE_DIR
|
return settings.BASE_DIR
|
||||||
|
|
||||||
|
|
||||||
|
celery_app.register_task(RunJob())
|
||||||
|
celery_app.register_task(RunProjectUpdate())
|
||||||
|
celery_app.register_task(RunInventoryUpdate())
|
||||||
|
celery_app.register_task(RunAdHocCommand())
|
||||||
|
celery_app.register_task(RunSystemJob())
|
||||||
|
|||||||
@@ -132,7 +132,7 @@ class BaseTestMixin(MockCommonlySlowTestMixin):
|
|||||||
# Set flag so that task chain works with unit tests.
|
# Set flag so that task chain works with unit tests.
|
||||||
settings.CELERY_UNIT_TEST = True
|
settings.CELERY_UNIT_TEST = True
|
||||||
settings.SYSTEM_UUID='00000000-0000-0000-0000-000000000000'
|
settings.SYSTEM_UUID='00000000-0000-0000-0000-000000000000'
|
||||||
settings.BROKER_URL='redis://localhost:55672/'
|
settings.CELERY_BROKER_URL='redis://localhost:55672/'
|
||||||
settings.CALLBACK_QUEUE = 'callback_tasks_unit'
|
settings.CALLBACK_QUEUE = 'callback_tasks_unit'
|
||||||
|
|
||||||
# Disable socket notifications for unit tests.
|
# Disable socket notifications for unit tests.
|
||||||
|
|||||||
@@ -92,24 +92,21 @@ class TestJobTemplateCopyEdit:
|
|||||||
credential=None, ask_credential_on_launch=True,
|
credential=None, ask_credential_on_launch=True,
|
||||||
name='deploy-job-template'
|
name='deploy-job-template'
|
||||||
)
|
)
|
||||||
serializer = JobTemplateSerializer(jt_res)
|
serializer = JobTemplateSerializer(jt_res, context=self.fake_context(admin_user))
|
||||||
serializer.context = self.fake_context(admin_user)
|
|
||||||
response = serializer.to_representation(jt_res)
|
response = serializer.to_representation(jt_res)
|
||||||
assert not response['summary_fields']['user_capabilities']['copy']
|
assert not response['summary_fields']['user_capabilities']['copy']
|
||||||
assert response['summary_fields']['user_capabilities']['edit']
|
assert response['summary_fields']['user_capabilities']['edit']
|
||||||
|
|
||||||
def test_sys_admin_copy_edit(self, jt_copy_edit, admin_user):
|
def test_sys_admin_copy_edit(self, jt_copy_edit, admin_user):
|
||||||
"Absent a validation error, system admins can do everything"
|
"Absent a validation error, system admins can do everything"
|
||||||
serializer = JobTemplateSerializer(jt_copy_edit)
|
serializer = JobTemplateSerializer(jt_copy_edit, context=self.fake_context(admin_user))
|
||||||
serializer.context = self.fake_context(admin_user)
|
|
||||||
response = serializer.to_representation(jt_copy_edit)
|
response = serializer.to_representation(jt_copy_edit)
|
||||||
assert response['summary_fields']['user_capabilities']['copy']
|
assert response['summary_fields']['user_capabilities']['copy']
|
||||||
assert response['summary_fields']['user_capabilities']['edit']
|
assert response['summary_fields']['user_capabilities']['edit']
|
||||||
|
|
||||||
def test_org_admin_copy_edit(self, jt_copy_edit, org_admin):
|
def test_org_admin_copy_edit(self, jt_copy_edit, org_admin):
|
||||||
"Organization admins SHOULD be able to copy a JT firmly in their org"
|
"Organization admins SHOULD be able to copy a JT firmly in their org"
|
||||||
serializer = JobTemplateSerializer(jt_copy_edit)
|
serializer = JobTemplateSerializer(jt_copy_edit, context=self.fake_context(org_admin))
|
||||||
serializer.context = self.fake_context(org_admin)
|
|
||||||
response = serializer.to_representation(jt_copy_edit)
|
response = serializer.to_representation(jt_copy_edit)
|
||||||
assert response['summary_fields']['user_capabilities']['copy']
|
assert response['summary_fields']['user_capabilities']['copy']
|
||||||
assert response['summary_fields']['user_capabilities']['edit']
|
assert response['summary_fields']['user_capabilities']['edit']
|
||||||
@@ -125,8 +122,7 @@ class TestJobTemplateCopyEdit:
|
|||||||
jt_copy_edit.credential = machine_credential
|
jt_copy_edit.credential = machine_credential
|
||||||
jt_copy_edit.save()
|
jt_copy_edit.save()
|
||||||
|
|
||||||
serializer = JobTemplateSerializer(jt_copy_edit)
|
serializer = JobTemplateSerializer(jt_copy_edit, context=self.fake_context(org_admin))
|
||||||
serializer.context = self.fake_context(org_admin)
|
|
||||||
response = serializer.to_representation(jt_copy_edit)
|
response = serializer.to_representation(jt_copy_edit)
|
||||||
assert not response['summary_fields']['user_capabilities']['copy']
|
assert not response['summary_fields']['user_capabilities']['copy']
|
||||||
assert response['summary_fields']['user_capabilities']['edit']
|
assert response['summary_fields']['user_capabilities']['edit']
|
||||||
@@ -140,8 +136,7 @@ class TestJobTemplateCopyEdit:
|
|||||||
jt_copy_edit.admin_role.members.add(rando)
|
jt_copy_edit.admin_role.members.add(rando)
|
||||||
jt_copy_edit.save()
|
jt_copy_edit.save()
|
||||||
|
|
||||||
serializer = JobTemplateSerializer(jt_copy_edit)
|
serializer = JobTemplateSerializer(jt_copy_edit, context=self.fake_context(rando))
|
||||||
serializer.context = self.fake_context(rando)
|
|
||||||
response = serializer.to_representation(jt_copy_edit)
|
response = serializer.to_representation(jt_copy_edit)
|
||||||
assert not response['summary_fields']['user_capabilities']['copy']
|
assert not response['summary_fields']['user_capabilities']['copy']
|
||||||
assert response['summary_fields']['user_capabilities']['edit']
|
assert response['summary_fields']['user_capabilities']['edit']
|
||||||
@@ -155,8 +150,7 @@ class TestJobTemplateCopyEdit:
|
|||||||
jt_copy_edit.project.admin_role.members.add(rando)
|
jt_copy_edit.project.admin_role.members.add(rando)
|
||||||
jt_copy_edit.project.save()
|
jt_copy_edit.project.save()
|
||||||
|
|
||||||
serializer = JobTemplateSerializer(jt_copy_edit)
|
serializer = JobTemplateSerializer(jt_copy_edit, context=self.fake_context(rando))
|
||||||
serializer.context = self.fake_context(rando)
|
|
||||||
response = serializer.to_representation(jt_copy_edit)
|
response = serializer.to_representation(jt_copy_edit)
|
||||||
assert response['summary_fields']['user_capabilities']['copy']
|
assert response['summary_fields']['user_capabilities']['copy']
|
||||||
assert response['summary_fields']['user_capabilities']['edit']
|
assert response['summary_fields']['user_capabilities']['edit']
|
||||||
|
|||||||
@@ -39,8 +39,8 @@ def run_command(name, *args, **options):
|
|||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
"username,password,expected,changed", [
|
"username,password,expected,changed", [
|
||||||
('admin', 'dingleberry', 'Password updated\n', True),
|
('admin', 'dingleberry', 'Password updated', True),
|
||||||
('admin', 'admin', 'Password not updated\n', False),
|
('admin', 'admin', 'Password not updated', False),
|
||||||
(None, 'foo', 'username required', False),
|
(None, 'foo', 'username required', False),
|
||||||
('admin', None, 'password required', False),
|
('admin', None, 'password required', False),
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -92,7 +92,7 @@ class TestInvalidOptionsFunctional:
|
|||||||
cmd = inventory_import.Command()
|
cmd = inventory_import.Command()
|
||||||
with mock.patch('django.db.transaction.rollback'):
|
with mock.patch('django.db.transaction.rollback'):
|
||||||
with pytest.raises(IOError) as err:
|
with pytest.raises(IOError) as err:
|
||||||
cmd.handle_noargs(
|
cmd.handle(
|
||||||
inventory_id=inventory.id,
|
inventory_id=inventory.id,
|
||||||
source='/tmp/pytest-of-root/pytest-7/inv_files0-invalid')
|
source='/tmp/pytest-of-root/pytest-7/inv_files0-invalid')
|
||||||
assert 'Source does not exist' in err.value.message
|
assert 'Source does not exist' in err.value.message
|
||||||
@@ -100,14 +100,14 @@ class TestInvalidOptionsFunctional:
|
|||||||
def test_invalid_inventory_id(self):
|
def test_invalid_inventory_id(self):
|
||||||
cmd = inventory_import.Command()
|
cmd = inventory_import.Command()
|
||||||
with pytest.raises(CommandError) as err:
|
with pytest.raises(CommandError) as err:
|
||||||
cmd.handle_noargs(inventory_id=42, source='/notapath/shouldnotmatter')
|
cmd.handle(inventory_id=42, source='/notapath/shouldnotmatter')
|
||||||
assert 'id = 42' in err.value.message
|
assert 'id = 42' in err.value.message
|
||||||
assert 'cannot be found' in err.value.message
|
assert 'cannot be found' in err.value.message
|
||||||
|
|
||||||
def test_invalid_inventory_name(self):
|
def test_invalid_inventory_name(self):
|
||||||
cmd = inventory_import.Command()
|
cmd = inventory_import.Command()
|
||||||
with pytest.raises(CommandError) as err:
|
with pytest.raises(CommandError) as err:
|
||||||
cmd.handle_noargs(inventory_name='fooservers', source='/notapath/shouldnotmatter')
|
cmd.handle(inventory_name='fooservers', source='/notapath/shouldnotmatter')
|
||||||
assert 'name = fooservers' in err.value.message
|
assert 'name = fooservers' in err.value.message
|
||||||
assert 'cannot be found' in err.value.message
|
assert 'cannot be found' in err.value.message
|
||||||
|
|
||||||
@@ -122,7 +122,7 @@ class TestINIImports:
|
|||||||
@mock.patch.object(inventory_import.AnsibleInventoryLoader, 'load', mock.MagicMock(return_value=TEST_MEM_OBJECTS))
|
@mock.patch.object(inventory_import.AnsibleInventoryLoader, 'load', mock.MagicMock(return_value=TEST_MEM_OBJECTS))
|
||||||
def test_inventory_single_ini_import(self, inventory, capsys):
|
def test_inventory_single_ini_import(self, inventory, capsys):
|
||||||
cmd = inventory_import.Command()
|
cmd = inventory_import.Command()
|
||||||
r = cmd.handle_noargs(
|
r = cmd.handle(
|
||||||
inventory_id=inventory.pk, source=__file__,
|
inventory_id=inventory.pk, source=__file__,
|
||||||
method='backport')
|
method='backport')
|
||||||
out, err = capsys.readouterr()
|
out, err = capsys.readouterr()
|
||||||
@@ -192,7 +192,7 @@ class TestINIImports:
|
|||||||
)
|
)
|
||||||
def test_hostvars_are_saved(self, inventory):
|
def test_hostvars_are_saved(self, inventory):
|
||||||
cmd = inventory_import.Command()
|
cmd = inventory_import.Command()
|
||||||
cmd.handle_noargs(inventory_id=inventory.pk, source='doesnt matter')
|
cmd.handle(inventory_id=inventory.pk, source='doesnt matter')
|
||||||
assert inventory.hosts.count() == 1
|
assert inventory.hosts.count() == 1
|
||||||
h = inventory.hosts.all()[0]
|
h = inventory.hosts.all()[0]
|
||||||
assert h.name == 'foo'
|
assert h.name == 'foo'
|
||||||
@@ -219,4 +219,4 @@ class TestINIImports:
|
|||||||
)
|
)
|
||||||
def test_recursive_group_error(self, inventory):
|
def test_recursive_group_error(self, inventory):
|
||||||
cmd = inventory_import.Command()
|
cmd = inventory_import.Command()
|
||||||
cmd.handle_noargs(inventory_id=inventory.pk, source='doesnt matter')
|
cmd.handle(inventory_id=inventory.pk, source='doesnt matter')
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ def celery_memory_broker():
|
|||||||
|
|
||||||
Allows django signal code to execute without the need for redis
|
Allows django signal code to execute without the need for redis
|
||||||
'''
|
'''
|
||||||
settings.BROKER_URL='memory://localhost/'
|
settings.CELERY_BROKER_URL='memory://localhost/'
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ def test_get_roles_list_user(organization, inventory, team, get, user):
|
|||||||
'Users can see all roles they have access to, but not all roles'
|
'Users can see all roles they have access to, but not all roles'
|
||||||
this_user = user('user-test_get_roles_list_user')
|
this_user = user('user-test_get_roles_list_user')
|
||||||
organization.member_role.members.add(this_user)
|
organization.member_role.members.add(this_user)
|
||||||
custom_role = Role.objects.create(name='custom_role-test_get_roles_list_user')
|
custom_role = Role.objects.create(role_field='custom_role-test_get_roles_list_user')
|
||||||
organization.member_role.children.add(custom_role)
|
organization.member_role.children.add(custom_role)
|
||||||
|
|
||||||
url = reverse('api:role_list')
|
url = reverse('api:role_list')
|
||||||
@@ -128,7 +128,7 @@ def test_user_view_other_user_roles(organization, inventory, team, get, alice, b
|
|||||||
organization.member_role.members.add(alice)
|
organization.member_role.members.add(alice)
|
||||||
organization.admin_role.members.add(bob)
|
organization.admin_role.members.add(bob)
|
||||||
organization.member_role.members.add(bob)
|
organization.member_role.members.add(bob)
|
||||||
custom_role = Role.objects.create(name='custom_role-test_user_view_admin_roles_list')
|
custom_role = Role.objects.create(role_field='custom_role-test_user_view_admin_roles_list')
|
||||||
organization.member_role.children.add(custom_role)
|
organization.member_role.children.add(custom_role)
|
||||||
team.member_role.members.add(bob)
|
team.member_role.members.add(bob)
|
||||||
|
|
||||||
|
|||||||
@@ -125,11 +125,15 @@ class TestWorkflowJobTemplateNodeSerializerCharPrompts():
|
|||||||
serializer = WorkflowJobTemplateNodeSerializer()
|
serializer = WorkflowJobTemplateNodeSerializer()
|
||||||
node = WorkflowJobTemplateNode(pk=1)
|
node = WorkflowJobTemplateNode(pk=1)
|
||||||
node.char_prompts = {'limit': 'webservers'}
|
node.char_prompts = {'limit': 'webservers'}
|
||||||
serializer.instance = node
|
|
||||||
view = FakeView(node)
|
view = FakeView(node)
|
||||||
view.request = FakeRequest()
|
view.request = FakeRequest()
|
||||||
view.request.method = "PATCH"
|
view.request.method = "PATCH"
|
||||||
serializer.context = {'view': view}
|
|
||||||
|
serializer = WorkflowJobTemplateNodeSerializer()
|
||||||
|
serializer = WorkflowJobTemplateNodeSerializer(context={'view':view})
|
||||||
|
serializer.instance = node
|
||||||
|
|
||||||
return serializer
|
return serializer
|
||||||
|
|
||||||
def test_change_single_field(self, WFJT_serializer):
|
def test_change_single_field(self, WFJT_serializer):
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ from awx.api.views import (
|
|||||||
JobTemplateLabelList,
|
JobTemplateLabelList,
|
||||||
JobTemplateSurveySpec,
|
JobTemplateSurveySpec,
|
||||||
InventoryInventorySourcesUpdate,
|
InventoryInventorySourcesUpdate,
|
||||||
InventoryHostsList,
|
|
||||||
HostInsights,
|
HostInsights,
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -17,8 +16,6 @@ from awx.main.models import (
|
|||||||
Host,
|
Host,
|
||||||
)
|
)
|
||||||
|
|
||||||
from awx.main.managers import HostManager
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def mock_response_new(mocker):
|
def mock_response_new(mocker):
|
||||||
@@ -223,17 +220,3 @@ class TestHostInsights():
|
|||||||
|
|
||||||
assert resp.data['error'] == 'The Insights Credential for "inventory_name_here" was not found.'
|
assert resp.data['error'] == 'The Insights Credential for "inventory_name_here" was not found.'
|
||||||
assert resp.status_code == 404
|
assert resp.status_code == 404
|
||||||
|
|
||||||
|
|
||||||
class TestInventoryHostsList(object):
|
|
||||||
|
|
||||||
def test_host_list_smart_inventory(self, mocker):
|
|
||||||
Inventory = namedtuple('Inventory', ['kind', 'host_filter', 'hosts', 'organization_id'])
|
|
||||||
obj = Inventory(kind='smart', host_filter='localhost', hosts=HostManager(), organization_id=None)
|
|
||||||
obj.hosts.instance = obj
|
|
||||||
|
|
||||||
with mock.patch.object(InventoryHostsList, 'get_parent_object', return_value=obj):
|
|
||||||
with mock.patch('awx.main.utils.filters.SmartFilter.query_from_string') as mock_query:
|
|
||||||
view = InventoryHostsList()
|
|
||||||
view.get_queryset()
|
|
||||||
mock_query.assert_called_once_with('localhost')
|
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ class TestInvalidOptions:
|
|||||||
def test_invalid_options_no_options_specified(self):
|
def test_invalid_options_no_options_specified(self):
|
||||||
cmd = Command()
|
cmd = Command()
|
||||||
with pytest.raises(CommandError) as err:
|
with pytest.raises(CommandError) as err:
|
||||||
cmd.handle_noargs()
|
cmd.handle()
|
||||||
assert 'inventory-id' in err.value.message
|
assert 'inventory-id' in err.value.message
|
||||||
assert 'required' in err.value.message
|
assert 'required' in err.value.message
|
||||||
|
|
||||||
@@ -27,7 +27,7 @@ class TestInvalidOptions:
|
|||||||
# You can not specify both name and if of the inventory
|
# You can not specify both name and if of the inventory
|
||||||
cmd = Command()
|
cmd = Command()
|
||||||
with pytest.raises(CommandError) as err:
|
with pytest.raises(CommandError) as err:
|
||||||
cmd.handle_noargs(
|
cmd.handle(
|
||||||
inventory_id=42, inventory_name='my-inventory'
|
inventory_id=42, inventory_name='my-inventory'
|
||||||
)
|
)
|
||||||
assert 'inventory-id' in err.value.message
|
assert 'inventory-id' in err.value.message
|
||||||
@@ -37,7 +37,7 @@ class TestInvalidOptions:
|
|||||||
# You can't overwrite and keep_vars at the same time, that wouldn't make sense
|
# You can't overwrite and keep_vars at the same time, that wouldn't make sense
|
||||||
cmd = Command()
|
cmd = Command()
|
||||||
with pytest.raises(CommandError) as err:
|
with pytest.raises(CommandError) as err:
|
||||||
cmd.handle_noargs(
|
cmd.handle(
|
||||||
inventory_id=42, overwrite=True, keep_vars=True
|
inventory_id=42, overwrite=True, keep_vars=True
|
||||||
)
|
)
|
||||||
assert 'overwrite-vars' in err.value.message
|
assert 'overwrite-vars' in err.value.message
|
||||||
@@ -47,13 +47,13 @@ class TestInvalidOptions:
|
|||||||
# Need a source to import
|
# Need a source to import
|
||||||
cmd = Command()
|
cmd = Command()
|
||||||
with pytest.raises(CommandError) as err:
|
with pytest.raises(CommandError) as err:
|
||||||
cmd.handle_noargs(
|
cmd.handle(
|
||||||
inventory_id=42, overwrite=True, keep_vars=True
|
inventory_id=42, overwrite=True, keep_vars=True
|
||||||
)
|
)
|
||||||
assert 'overwrite-vars' in err.value.message
|
assert 'overwrite-vars' in err.value.message
|
||||||
assert 'exclusive' in err.value.message
|
assert 'exclusive' in err.value.message
|
||||||
with pytest.raises(CommandError) as err:
|
with pytest.raises(CommandError) as err:
|
||||||
cmd.handle_noargs(
|
cmd.handle(
|
||||||
inventory_id=42, overwrite_vars=True, keep_vars=True
|
inventory_id=42, overwrite_vars=True, keep_vars=True
|
||||||
)
|
)
|
||||||
assert 'overwrite-vars' in err.value.message
|
assert 'overwrite-vars' in err.value.message
|
||||||
@@ -62,7 +62,7 @@ class TestInvalidOptions:
|
|||||||
def test_invalid_options_missing_source(self):
|
def test_invalid_options_missing_source(self):
|
||||||
cmd = Command()
|
cmd = Command()
|
||||||
with pytest.raises(CommandError) as err:
|
with pytest.raises(CommandError) as err:
|
||||||
cmd.handle_noargs(inventory_id=42)
|
cmd.handle(inventory_id=42)
|
||||||
assert '--source' in err.value.message
|
assert '--source' in err.value.message
|
||||||
assert 'required' in err.value.message
|
assert 'required' in err.value.message
|
||||||
|
|
||||||
|
|||||||
@@ -1,103 +0,0 @@
|
|||||||
import pytest
|
|
||||||
import mock
|
|
||||||
|
|
||||||
from django.contrib.contenttypes.models import ContentType
|
|
||||||
|
|
||||||
from awx.main.models.rbac import (
|
|
||||||
Role,
|
|
||||||
ROLE_SINGLETON_SYSTEM_ADMINISTRATOR,
|
|
||||||
ROLE_SINGLETON_SYSTEM_AUDITOR
|
|
||||||
)
|
|
||||||
from awx.main.models import Organization, JobTemplate, Project
|
|
||||||
|
|
||||||
from awx.main.fields import (
|
|
||||||
ImplicitRoleField,
|
|
||||||
is_implicit_parent
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def apply_fake_roles(obj):
|
|
||||||
'''
|
|
||||||
Creates an un-saved role for all the implicit role fields on an object
|
|
||||||
'''
|
|
||||||
for fd in obj._meta.fields:
|
|
||||||
if not isinstance(fd, ImplicitRoleField):
|
|
||||||
continue
|
|
||||||
r = Role(role_field=fd.name)
|
|
||||||
setattr(obj, fd.name, r)
|
|
||||||
with mock.patch('django.contrib.contenttypes.fields.GenericForeignKey.get_content_type') as mck_ct:
|
|
||||||
mck_ct.return_value = ContentType(model=obj._meta.model_name)
|
|
||||||
r.content_object = obj
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
|
||||||
def system_administrator():
|
|
||||||
return Role(
|
|
||||||
role_field=ROLE_SINGLETON_SYSTEM_ADMINISTRATOR,
|
|
||||||
singleton_name=ROLE_SINGLETON_SYSTEM_ADMINISTRATOR
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
|
||||||
def system_auditor():
|
|
||||||
return Role(
|
|
||||||
role_field=ROLE_SINGLETON_SYSTEM_AUDITOR,
|
|
||||||
singleton_name=ROLE_SINGLETON_SYSTEM_AUDITOR
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
|
||||||
def organization():
|
|
||||||
o = Organization(name='unit-test-org')
|
|
||||||
apply_fake_roles(o)
|
|
||||||
return o
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
|
||||||
def project(organization):
|
|
||||||
p = Project(name='unit-test-proj', organization=organization)
|
|
||||||
apply_fake_roles(p)
|
|
||||||
return p
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
|
||||||
def job_template(project):
|
|
||||||
jt = JobTemplate(name='unit-test-jt', project=project)
|
|
||||||
apply_fake_roles(jt)
|
|
||||||
return jt
|
|
||||||
|
|
||||||
|
|
||||||
class TestIsImplicitParent:
|
|
||||||
'''
|
|
||||||
Tests to confirm that `is_implicit_parent` gives the right answers
|
|
||||||
'''
|
|
||||||
def test_sys_admin_implicit_parent(self, organization, system_administrator):
|
|
||||||
assert is_implicit_parent(
|
|
||||||
parent_role=system_administrator,
|
|
||||||
child_role=organization.admin_role
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def test_admin_is_parent_of_member_role(self, organization):
|
|
||||||
assert is_implicit_parent(
|
|
||||||
parent_role=organization.admin_role,
|
|
||||||
child_role=organization.member_role
|
|
||||||
)
|
|
||||||
|
|
||||||
def test_member_is_not_parent_of_admin_role(self, organization):
|
|
||||||
assert not is_implicit_parent(
|
|
||||||
parent_role=organization.member_role,
|
|
||||||
child_role=organization.admin_role
|
|
||||||
)
|
|
||||||
|
|
||||||
def test_second_level_implicit_parent_role(self, job_template, organization):
|
|
||||||
assert is_implicit_parent(
|
|
||||||
parent_role=organization.admin_role,
|
|
||||||
child_role=job_template.admin_role
|
|
||||||
)
|
|
||||||
|
|
||||||
def test_second_level_is_not_an_implicit_parent_role(self, job_template, organization):
|
|
||||||
assert not is_implicit_parent(
|
|
||||||
parent_role=organization.member_role,
|
|
||||||
child_role=job_template.admin_role
|
|
||||||
)
|
|
||||||
@@ -8,11 +8,11 @@ from datetime import timedelta
|
|||||||
('admin_checks', 'awx.main.tasks.run_administrative_checks'),
|
('admin_checks', 'awx.main.tasks.run_administrative_checks'),
|
||||||
('tower_scheduler', 'awx.main.tasks.awx_periodic_scheduler'),
|
('tower_scheduler', 'awx.main.tasks.awx_periodic_scheduler'),
|
||||||
])
|
])
|
||||||
def test_CELERYBEAT_SCHEDULE(mocker, job_name, function_path):
|
def test_CELERY_BEAT_SCHEDULE(mocker, job_name, function_path):
|
||||||
assert job_name in settings.CELERYBEAT_SCHEDULE
|
assert job_name in settings.CELERY_BEAT_SCHEDULE
|
||||||
assert 'schedule' in settings.CELERYBEAT_SCHEDULE[job_name]
|
assert 'schedule' in settings.CELERY_BEAT_SCHEDULE[job_name]
|
||||||
assert type(settings.CELERYBEAT_SCHEDULE[job_name]['schedule']) is timedelta
|
assert type(settings.CELERY_BEAT_SCHEDULE[job_name]['schedule']) is timedelta
|
||||||
assert settings.CELERYBEAT_SCHEDULE[job_name]['task'] == function_path
|
assert settings.CELERY_BEAT_SCHEDULE[job_name]['task'] == function_path
|
||||||
|
|
||||||
# Ensures that the function exists
|
# Ensures that the function exists
|
||||||
mocker.patch(function_path)
|
mocker.patch(function_path)
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ from awx.main.access import (
|
|||||||
from awx.conf.license import LicenseForbids
|
from awx.conf.license import LicenseForbids
|
||||||
from awx.main.models import (
|
from awx.main.models import (
|
||||||
Credential,
|
Credential,
|
||||||
|
CredentialType,
|
||||||
Inventory,
|
Inventory,
|
||||||
Project,
|
Project,
|
||||||
Role,
|
Role,
|
||||||
@@ -57,7 +58,7 @@ class TestRelatedFieldAccess:
|
|||||||
def test_new_with_bad_data(self, access, mocker):
|
def test_new_with_bad_data(self, access, mocker):
|
||||||
data = {'related': 3.1415}
|
data = {'related': 3.1415}
|
||||||
with pytest.raises(ParseError):
|
with pytest.raises(ParseError):
|
||||||
access.check_related('related', mocker.MagicMock, data)
|
access.check_related('related', mocker.MagicMock(), data)
|
||||||
|
|
||||||
def test_new_mandatory_fail(self, access, mocker):
|
def test_new_mandatory_fail(self, access, mocker):
|
||||||
access.user.is_superuser = False
|
access.user.is_superuser = False
|
||||||
@@ -118,10 +119,18 @@ class TestRelatedFieldAccess:
|
|||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def job_template_with_ids(job_template_factory):
|
def job_template_with_ids(job_template_factory):
|
||||||
# Create non-persisted objects with IDs to send to job_template_factory
|
# Create non-persisted objects with IDs to send to job_template_factory
|
||||||
credential = Credential(id=1, pk=1, name='testcred', kind='ssh')
|
ssh_type = CredentialType(kind='ssh')
|
||||||
net_cred = Credential(id=2, pk=2, name='testnetcred', kind='net')
|
credential = Credential(id=1, pk=1, name='testcred', credential_type=ssh_type)
|
||||||
cloud_cred = Credential(id=3, pk=3, name='testcloudcred', kind='aws')
|
|
||||||
vault_cred = Credential(id=4, pk=4, name='testnetcred', kind='vault')
|
net_type = CredentialType(kind='net')
|
||||||
|
net_cred = Credential(id=2, pk=2, name='testnetcred', credential_type=net_type)
|
||||||
|
|
||||||
|
cloud_type = CredentialType(kind='aws')
|
||||||
|
cloud_cred = Credential(id=3, pk=3, name='testcloudcred', credential_type=cloud_type)
|
||||||
|
|
||||||
|
vault_type = CredentialType(kind='vault')
|
||||||
|
vault_cred = Credential(id=4, pk=4, name='testnetcred', credential_type=vault_type)
|
||||||
|
|
||||||
inv = Inventory(id=11, pk=11, name='testinv')
|
inv = Inventory(id=11, pk=11, name='testinv')
|
||||||
proj = Project(id=14, pk=14, name='testproj')
|
proj = Project(id=14, pk=14, name='testproj')
|
||||||
|
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ class TestCleanupInconsistentCeleryTasks():
|
|||||||
logger_mock.error.assert_called_once_with("Task job 2 (failed) DB error in marking failed. Job possibly deleted.")
|
logger_mock.error.assert_called_once_with("Task job 2 (failed) DB error in marking failed. Job possibly deleted.")
|
||||||
|
|
||||||
@mock.patch.object(InstanceGroup.objects, 'prefetch_related', return_value=[])
|
@mock.patch.object(InstanceGroup.objects, 'prefetch_related', return_value=[])
|
||||||
@mock.patch('awx.main.scheduler.task_manager.inspect')
|
@mock.patch('awx.main.scheduler.task_manager.Inspect')
|
||||||
def test_multiple_active_instances_sanity_check(self, inspect_mock, *args):
|
def test_multiple_active_instances_sanity_check(self, inspect_mock, *args):
|
||||||
class MockInspector:
|
class MockInspector:
|
||||||
pass
|
pass
|
||||||
|
|||||||
@@ -174,6 +174,7 @@ def test_chain_generation(common_model_class_mock, common_model_name_not_unique_
|
|||||||
assert [x.model for x in zip(*settings_mock.NAMED_URL_GRAPH[model_3].adj_list)[1]] == [model_2]
|
assert [x.model for x in zip(*settings_mock.NAMED_URL_GRAPH[model_3].adj_list)[1]] == [model_2]
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.xfail(reason="new dynamic model in django 1.11")
|
||||||
def test_graph_generation(common_model_class_mock, common_model_name_not_unique_class_mock, settings_mock):
|
def test_graph_generation(common_model_class_mock, common_model_name_not_unique_class_mock, settings_mock):
|
||||||
"""
|
"""
|
||||||
Graph topology:
|
Graph topology:
|
||||||
@@ -250,6 +251,7 @@ def test_graph_generation(common_model_class_mock, common_model_name_not_unique_
|
|||||||
assert settings_mock.NAMED_URL_GRAPH[model_3_3].adj_list == []
|
assert settings_mock.NAMED_URL_GRAPH[model_3_3].adj_list == []
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.xfail(reason="new dynamic model in django 1.11")
|
||||||
def test_largest_graph_is_generated(common_model_name_not_unique_class_mock,
|
def test_largest_graph_is_generated(common_model_name_not_unique_class_mock,
|
||||||
common_model_class_mock, settings_mock):
|
common_model_class_mock, settings_mock):
|
||||||
"""
|
"""
|
||||||
@@ -321,6 +323,7 @@ def test_contenttype_being_ignored(common_model_name_not_unique_class_mock, sett
|
|||||||
assert settings_mock.NAMED_URL_GRAPH[model].adj_list == []
|
assert settings_mock.NAMED_URL_GRAPH[model].adj_list == []
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.xfail(reason="new dynamic model in django 1.11")
|
||||||
@pytest.mark.parametrize('input_, output', [
|
@pytest.mark.parametrize('input_, output', [
|
||||||
('alice++bob+foo++cat++dog', {
|
('alice++bob+foo++cat++dog', {
|
||||||
'name': 'alice',
|
'name': 'alice',
|
||||||
@@ -438,6 +441,7 @@ def test_unicode_decoding(common_model_class_mock, settings_mock):
|
|||||||
assert kwargs == {'name': u'我为我蛤续1s'}
|
assert kwargs == {'name': u'我为我蛤续1s'}
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.xfail(reason="new dynamic model in django 1.11")
|
||||||
def test_generate_named_url(common_model_name_not_unique_class_mock,
|
def test_generate_named_url(common_model_name_not_unique_class_mock,
|
||||||
common_model_class_mock, settings_mock):
|
common_model_class_mock, settings_mock):
|
||||||
"""
|
"""
|
||||||
|
|||||||
@@ -450,7 +450,7 @@ def copy_model_by_class(obj1, Class2, fields, kwargs):
|
|||||||
elif not isinstance(Class2._meta.get_field(field_name), (ForeignObjectRel, ManyToManyField)):
|
elif not isinstance(Class2._meta.get_field(field_name), (ForeignObjectRel, ManyToManyField)):
|
||||||
create_kwargs[field_name] = kwargs[field_name]
|
create_kwargs[field_name] = kwargs[field_name]
|
||||||
elif hasattr(obj1, field_name):
|
elif hasattr(obj1, field_name):
|
||||||
field_obj = obj1._meta.get_field_by_name(field_name)[0]
|
field_obj = obj1._meta.get_field(field_name)
|
||||||
if not isinstance(field_obj, ManyToManyField):
|
if not isinstance(field_obj, ManyToManyField):
|
||||||
create_kwargs[field_name] = getattr(obj1, field_name)
|
create_kwargs[field_name] = getattr(obj1, field_name)
|
||||||
|
|
||||||
@@ -471,7 +471,7 @@ def copy_m2m_relationships(obj1, obj2, fields, kwargs=None):
|
|||||||
'''
|
'''
|
||||||
for field_name in fields:
|
for field_name in fields:
|
||||||
if hasattr(obj1, field_name):
|
if hasattr(obj1, field_name):
|
||||||
field_obj = obj1._meta.get_field_by_name(field_name)[0]
|
field_obj = obj1._meta.get_field(field_name)
|
||||||
if isinstance(field_obj, ManyToManyField):
|
if isinstance(field_obj, ManyToManyField):
|
||||||
# Many to Many can be specified as field_name
|
# Many to Many can be specified as field_name
|
||||||
src_field_value = getattr(obj1, field_name)
|
src_field_value = getattr(obj1, field_name)
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ from django.db.migrations.loader import MigrationLoader
|
|||||||
from django.db import connection
|
from django.db import connection
|
||||||
|
|
||||||
# Python
|
# Python
|
||||||
|
from itertools import chain
|
||||||
import re
|
import re
|
||||||
|
|
||||||
|
|
||||||
@@ -20,3 +21,15 @@ def get_tower_migration_version():
|
|||||||
if migration_version > v:
|
if migration_version > v:
|
||||||
v = migration_version
|
v = migration_version
|
||||||
return v
|
return v
|
||||||
|
|
||||||
|
|
||||||
|
def get_all_field_names(model):
|
||||||
|
# Implements compatibility with _meta.get_all_field_names
|
||||||
|
# See: https://docs.djangoproject.com/en/1.11/ref/models/meta/#migrating-from-the-old-api
|
||||||
|
return list(set(chain.from_iterable(
|
||||||
|
(field.name, field.attname) if hasattr(field, 'attname') else (field.name,)
|
||||||
|
for field in model._meta.get_fields()
|
||||||
|
# For complete backwards compatibility, you may want to exclude
|
||||||
|
# GenericForeignKey from the results.
|
||||||
|
if not (field.many_to_one and field.related_model is None)
|
||||||
|
)))
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import os
|
|||||||
import re # noqa
|
import re # noqa
|
||||||
import sys
|
import sys
|
||||||
import ldap
|
import ldap
|
||||||
import djcelery
|
|
||||||
from datetime import timedelta
|
from datetime import timedelta
|
||||||
|
|
||||||
from kombu import Queue, Exchange
|
from kombu import Queue, Exchange
|
||||||
@@ -42,7 +41,6 @@ def IS_TESTING(argv=None):
|
|||||||
|
|
||||||
|
|
||||||
DEBUG = True
|
DEBUG = True
|
||||||
TEMPLATE_DEBUG = DEBUG
|
|
||||||
SQL_DEBUG = DEBUG
|
SQL_DEBUG = DEBUG
|
||||||
|
|
||||||
ADMINS = (
|
ADMINS = (
|
||||||
@@ -195,20 +193,37 @@ CSRF_COOKIE_SECURE = True
|
|||||||
# Limit CSRF cookies to browser sessions
|
# Limit CSRF cookies to browser sessions
|
||||||
CSRF_COOKIE_AGE = None
|
CSRF_COOKIE_AGE = None
|
||||||
|
|
||||||
TEMPLATE_CONTEXT_PROCESSORS = ( # NOQA
|
TEMPLATES = [
|
||||||
'django.contrib.auth.context_processors.auth',
|
{
|
||||||
'django.core.context_processors.debug',
|
'NAME': 'default',
|
||||||
'django.core.context_processors.i18n',
|
'BACKEND': 'django.template.backends.django.DjangoTemplates',
|
||||||
'django.core.context_processors.media',
|
'OPTIONS': {
|
||||||
'django.core.context_processors.static',
|
'debug': DEBUG,
|
||||||
'django.core.context_processors.tz',
|
'context_processors': [# NOQA
|
||||||
'django.contrib.messages.context_processors.messages',
|
'django.contrib.auth.context_processors.auth',
|
||||||
'django.core.context_processors.request',
|
'django.template.context_processors.debug',
|
||||||
'awx.ui.context_processors.settings',
|
'django.template.context_processors.request',
|
||||||
'awx.ui.context_processors.version',
|
'django.template.context_processors.i18n',
|
||||||
'social.apps.django_app.context_processors.backends',
|
'django.template.context_processors.media',
|
||||||
'social.apps.django_app.context_processors.login_redirect',
|
'django.template.context_processors.static',
|
||||||
)
|
'django.template.context_processors.tz',
|
||||||
|
'django.contrib.messages.context_processors.messages',
|
||||||
|
'awx.ui.context_processors.settings',
|
||||||
|
'awx.ui.context_processors.version',
|
||||||
|
'social_django.context_processors.backends',
|
||||||
|
'social_django.context_processors.login_redirect',
|
||||||
|
],
|
||||||
|
'loaders': [
|
||||||
|
'django.template.loaders.cached.Loader',
|
||||||
|
'django.template.loaders.filesystem.Loader',
|
||||||
|
'django.template.loaders.app_directories.Loader',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
'DIRS': [
|
||||||
|
os.path.join(BASE_DIR, 'templates'),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
MIDDLEWARE_CLASSES = ( # NOQA
|
MIDDLEWARE_CLASSES = ( # NOQA
|
||||||
'django.contrib.sessions.middleware.SessionMiddleware',
|
'django.contrib.sessions.middleware.SessionMiddleware',
|
||||||
@@ -217,6 +232,7 @@ MIDDLEWARE_CLASSES = ( # NOQA
|
|||||||
'django.middleware.csrf.CsrfViewMiddleware',
|
'django.middleware.csrf.CsrfViewMiddleware',
|
||||||
'django.contrib.auth.middleware.AuthenticationMiddleware',
|
'django.contrib.auth.middleware.AuthenticationMiddleware',
|
||||||
'django.contrib.messages.middleware.MessageMiddleware',
|
'django.contrib.messages.middleware.MessageMiddleware',
|
||||||
|
'debug_toolbar.middleware.DebugToolbarMiddleware',
|
||||||
'awx.main.middleware.ActivityStreamMiddleware',
|
'awx.main.middleware.ActivityStreamMiddleware',
|
||||||
'awx.sso.middleware.SocialAuthMiddleware',
|
'awx.sso.middleware.SocialAuthMiddleware',
|
||||||
'crum.CurrentRequestUserMiddleware',
|
'crum.CurrentRequestUserMiddleware',
|
||||||
@@ -224,16 +240,6 @@ MIDDLEWARE_CLASSES = ( # NOQA
|
|||||||
'awx.main.middleware.URLModificationMiddleware',
|
'awx.main.middleware.URLModificationMiddleware',
|
||||||
)
|
)
|
||||||
|
|
||||||
TEMPLATE_DIRS = (
|
|
||||||
os.path.join(BASE_DIR, 'templates'),
|
|
||||||
)
|
|
||||||
|
|
||||||
TEMPLATE_LOADERS = (
|
|
||||||
('django.template.loaders.cached.Loader', (
|
|
||||||
'django.template.loaders.filesystem.Loader',
|
|
||||||
'django.template.loaders.app_directories.Loader',
|
|
||||||
)),
|
|
||||||
)
|
|
||||||
|
|
||||||
ROOT_URLCONF = 'awx.urls'
|
ROOT_URLCONF = 'awx.urls'
|
||||||
|
|
||||||
@@ -248,12 +254,11 @@ INSTALLED_APPS = (
|
|||||||
'django.contrib.staticfiles',
|
'django.contrib.staticfiles',
|
||||||
'rest_framework',
|
'rest_framework',
|
||||||
'django_extensions',
|
'django_extensions',
|
||||||
'djcelery',
|
'django_celery_results',
|
||||||
'kombu.transport.django',
|
|
||||||
'channels',
|
'channels',
|
||||||
'polymorphic',
|
'polymorphic',
|
||||||
'taggit',
|
'taggit',
|
||||||
'social.apps.django_app.default',
|
'social_django',
|
||||||
'awx.conf',
|
'awx.conf',
|
||||||
'awx.main',
|
'awx.main',
|
||||||
'awx.api',
|
'awx.api',
|
||||||
@@ -302,11 +307,11 @@ AUTHENTICATION_BACKENDS = (
|
|||||||
'awx.sso.backends.LDAPBackend',
|
'awx.sso.backends.LDAPBackend',
|
||||||
'awx.sso.backends.RADIUSBackend',
|
'awx.sso.backends.RADIUSBackend',
|
||||||
'awx.sso.backends.TACACSPlusBackend',
|
'awx.sso.backends.TACACSPlusBackend',
|
||||||
'social.backends.google.GoogleOAuth2',
|
'social_core.backends.google.GoogleOAuth2',
|
||||||
'social.backends.github.GithubOAuth2',
|
'social_core.backends.github.GithubOAuth2',
|
||||||
'social.backends.github.GithubOrganizationOAuth2',
|
'social_core.backends.github.GithubOrganizationOAuth2',
|
||||||
'social.backends.github.GithubTeamOAuth2',
|
'social_core.backends.github.GithubTeamOAuth2',
|
||||||
'social.backends.azuread.AzureADOAuth2',
|
'social_core.backends.azuread.AzureADOAuth2',
|
||||||
'awx.sso.backends.SAMLAuth',
|
'awx.sso.backends.SAMLAuth',
|
||||||
'django.contrib.auth.backends.ModelBackend',
|
'django.contrib.auth.backends.ModelBackend',
|
||||||
)
|
)
|
||||||
@@ -410,41 +415,35 @@ DEVSERVER_DEFAULT_PORT = '8013'
|
|||||||
# Set default ports for live server tests.
|
# Set default ports for live server tests.
|
||||||
os.environ.setdefault('DJANGO_LIVE_TEST_SERVER_ADDRESS', 'localhost:9013-9199')
|
os.environ.setdefault('DJANGO_LIVE_TEST_SERVER_ADDRESS', 'localhost:9013-9199')
|
||||||
|
|
||||||
# Initialize Django-Celery.
|
CELERY_BROKER_URL = 'amqp://guest:guest@localhost:5672//'
|
||||||
djcelery.setup_loader()
|
|
||||||
|
|
||||||
BROKER_URL = 'amqp://guest:guest@localhost:5672//'
|
|
||||||
CELERY_EVENT_QUEUE_TTL = 5
|
CELERY_EVENT_QUEUE_TTL = 5
|
||||||
CELERY_DEFAULT_QUEUE = 'tower'
|
CELERY_TASK_DEFAULT_QUEUE = 'tower'
|
||||||
CELERY_TASK_SERIALIZER = 'json'
|
CELERY_TASK_SERIALIZER = 'json'
|
||||||
CELERY_RESULT_SERIALIZER = 'json'
|
CELERY_RESULT_SERIALIZER = 'json'
|
||||||
CELERY_ACCEPT_CONTENT = ['json']
|
CELERY_ACCEPT_CONTENT = ['json']
|
||||||
CELERY_TRACK_STARTED = True
|
CELERY_TASK_TRACK_STARTED = True
|
||||||
CELERYD_TASK_TIME_LIMIT = None
|
CELERY_TASK_TIME_LIMIT = None
|
||||||
CELERYD_TASK_SOFT_TIME_LIMIT = None
|
CELERY_TASK_SOFT_TIME_LIMIT = None
|
||||||
CELERYD_POOL_RESTARTS = True
|
CELERY_WORKER_POOL_RESTARTS = True
|
||||||
CELERYBEAT_SCHEDULER = 'celery.beat.PersistentScheduler'
|
CELERY_BEAT_SCHEDULER = 'celery.beat.PersistentScheduler'
|
||||||
CELERYBEAT_MAX_LOOP_INTERVAL = 60
|
CELERY_BEAT_MAX_LOOP_INTERVAL = 60
|
||||||
CELERY_RESULT_BACKEND = 'djcelery.backends.database:DatabaseBackend'
|
CELERY_RESULT_BACKEND = 'django-db'
|
||||||
CELERY_IMPORTS = ('awx.main.scheduler.tasks',)
|
CELERY_IMPORTS = ('awx.main.scheduler.tasks',)
|
||||||
CELERY_QUEUES = (
|
CELERY_TASK_QUEUES = (
|
||||||
Queue('default', Exchange('default'), routing_key='default'),
|
Queue('default', Exchange('default'), routing_key='default'),
|
||||||
Queue('tower', Exchange('tower'), routing_key='tower'),
|
Queue('tower', Exchange('tower'), routing_key='tower'),
|
||||||
Queue('tower_scheduler', Exchange('scheduler', type='topic'), routing_key='tower_scheduler.job.#', durable=False),
|
Queue('tower_scheduler', Exchange('scheduler', type='topic'), routing_key='tower_scheduler.job.#', durable=False),
|
||||||
Broadcast('tower_broadcast_all')
|
Broadcast('tower_broadcast_all')
|
||||||
)
|
)
|
||||||
CELERY_ROUTES = {'awx.main.scheduler.tasks.run_task_manager': {'queue': 'tower',
|
CELERY_TASK_ROUTES = {
|
||||||
'routing_key': 'tower'},
|
'awx.main.scheduler.tasks.run_task_manager': {'queue': 'tower', 'routing_key': 'tower'},
|
||||||
'awx.main.scheduler.tasks.run_job_launch': {'queue': 'tower_scheduler',
|
'awx.main.scheduler.tasks.run_job_launch': {'queue': 'tower_scheduler', 'routing_key': 'tower_scheduler.job.launch'},
|
||||||
'routing_key': 'tower_scheduler.job.launch'},
|
'awx.main.scheduler.tasks.run_job_complete': {'queue': 'tower_scheduler', 'routing_key': 'tower_scheduler.job.complete'},
|
||||||
'awx.main.scheduler.tasks.run_job_complete': {'queue': 'tower_scheduler',
|
'awx.main.tasks.cluster_node_heartbeat': {'queue': 'default', 'routing_key': 'cluster.heartbeat'},
|
||||||
'routing_key': 'tower_scheduler.job.complete'},
|
'awx.main.tasks.purge_old_stdout_files': {'queue': 'default', 'routing_key': 'cluster.heartbeat'},
|
||||||
'awx.main.tasks.cluster_node_heartbeat': {'queue': 'default',
|
}
|
||||||
'routing_key': 'cluster.heartbeat'},
|
|
||||||
'awx.main.tasks.purge_old_stdout_files': {'queue': 'default',
|
|
||||||
'routing_key': 'cluster.heartbeat'}}
|
|
||||||
|
|
||||||
CELERYBEAT_SCHEDULE = {
|
CELERY_BEAT_SCHEDULE = {
|
||||||
'tower_scheduler': {
|
'tower_scheduler': {
|
||||||
'task': 'awx.main.tasks.awx_periodic_scheduler',
|
'task': 'awx.main.tasks.awx_periodic_scheduler',
|
||||||
'schedule': timedelta(seconds=30),
|
'schedule': timedelta(seconds=30),
|
||||||
@@ -491,22 +490,22 @@ else:
|
|||||||
}
|
}
|
||||||
|
|
||||||
# Social Auth configuration.
|
# Social Auth configuration.
|
||||||
SOCIAL_AUTH_STRATEGY = 'awx.sso.strategies.django_strategy.AWXDjangoStrategy'
|
SOCIAL_AUTH_STRATEGY = 'social_django.strategy.DjangoStrategy'
|
||||||
SOCIAL_AUTH_STORAGE = 'social.apps.django_app.default.models.DjangoStorage'
|
SOCIAL_AUTH_STORAGE = 'social_django.models.DjangoStorage'
|
||||||
SOCIAL_AUTH_USER_MODEL = AUTH_USER_MODEL # noqa
|
SOCIAL_AUTH_USER_MODEL = AUTH_USER_MODEL # noqa
|
||||||
SOCIAL_AUTH_PIPELINE = (
|
SOCIAL_AUTH_PIPELINE = (
|
||||||
'social.pipeline.social_auth.social_details',
|
'social_core.pipeline.social_auth.social_details',
|
||||||
'social.pipeline.social_auth.social_uid',
|
'social_core.pipeline.social_auth.social_uid',
|
||||||
'social.pipeline.social_auth.auth_allowed',
|
'social_core.pipeline.social_auth.auth_allowed',
|
||||||
'social.pipeline.social_auth.social_user',
|
'social_core.pipeline.social_auth.social_user',
|
||||||
'social.pipeline.user.get_username',
|
'social_core.pipeline.user.get_username',
|
||||||
'social.pipeline.social_auth.associate_by_email',
|
'social_core.pipeline.social_auth.associate_by_email',
|
||||||
'social.pipeline.user.create_user',
|
'social_core.pipeline.user.create_user',
|
||||||
'awx.sso.pipeline.check_user_found_or_created',
|
'awx.sso.pipeline.check_user_found_or_created',
|
||||||
'social.pipeline.social_auth.associate_user',
|
'social_core.pipeline.social_auth.associate_user',
|
||||||
'social.pipeline.social_auth.load_extra_data',
|
'social_core.pipeline.social_auth.load_extra_data',
|
||||||
'awx.sso.pipeline.set_is_active_for_new_user',
|
'awx.sso.pipeline.set_is_active_for_new_user',
|
||||||
'social.pipeline.user.user_details',
|
'social_core.pipeline.user.user_details',
|
||||||
'awx.sso.pipeline.prevent_inactive_login',
|
'awx.sso.pipeline.prevent_inactive_login',
|
||||||
'awx.sso.pipeline.update_user_orgs',
|
'awx.sso.pipeline.update_user_orgs',
|
||||||
'awx.sso.pipeline.update_user_teams',
|
'awx.sso.pipeline.update_user_teams',
|
||||||
|
|||||||
@@ -39,13 +39,14 @@ SESSION_COOKIE_SECURE = False
|
|||||||
CSRF_COOKIE_SECURE = False
|
CSRF_COOKIE_SECURE = False
|
||||||
|
|
||||||
# Override django.template.loaders.cached.Loader in defaults.py
|
# Override django.template.loaders.cached.Loader in defaults.py
|
||||||
TEMPLATE_LOADERS = (
|
template = next((tpl_backend for tpl_backend in TEMPLATES if tpl_backend['NAME'] == 'default'), None) # noqa
|
||||||
|
template['OPTIONS']['loaders'] = (
|
||||||
'django.template.loaders.filesystem.Loader',
|
'django.template.loaders.filesystem.Loader',
|
||||||
'django.template.loaders.app_directories.Loader',
|
'django.template.loaders.app_directories.Loader',
|
||||||
)
|
)
|
||||||
|
|
||||||
# Disable capturing all SQL queries when running celeryd in development.
|
# Disable capturing all SQL queries when running celeryd in development.
|
||||||
if 'celeryd' in sys.argv:
|
if 'celery' in sys.argv:
|
||||||
SQL_DEBUG = False
|
SQL_DEBUG = False
|
||||||
|
|
||||||
CELERYD_HIJACK_ROOT_LOGGER = False
|
CELERYD_HIJACK_ROOT_LOGGER = False
|
||||||
@@ -123,11 +124,11 @@ except ImportError:
|
|||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
CLUSTER_HOST_ID = socket.gethostname()
|
CLUSTER_HOST_ID = socket.gethostname()
|
||||||
CELERY_ROUTES['awx.main.tasks.cluster_node_heartbeat'] = {'queue': CLUSTER_HOST_ID, 'routing_key': CLUSTER_HOST_ID}
|
CELERY_TASK_ROUTES['awx.main.tasks.cluster_node_heartbeat'] = {'queue': CLUSTER_HOST_ID, 'routing_key': CLUSTER_HOST_ID}
|
||||||
# Production only runs this schedule on controlling nodes
|
# Production only runs this schedule on controlling nodes
|
||||||
# but development will just run it on all nodes
|
# but development will just run it on all nodes
|
||||||
CELERY_ROUTES['awx.main.tasks.awx_isolated_heartbeat'] = {'queue': CLUSTER_HOST_ID, 'routing_key': CLUSTER_HOST_ID}
|
CELERY_TASK_ROUTES['awx.main.tasks.awx_isolated_heartbeat'] = {'queue': CLUSTER_HOST_ID, 'routing_key': CLUSTER_HOST_ID}
|
||||||
CELERYBEAT_SCHEDULE['isolated_heartbeat'] = {
|
CELERY_BEAT_SCHEDULE['isolated_heartbeat'] = {
|
||||||
'task': 'awx.main.tasks.awx_isolated_heartbeat',
|
'task': 'awx.main.tasks.awx_isolated_heartbeat',
|
||||||
'schedule': timedelta(seconds = AWX_ISOLATED_PERIODIC_CHECK),
|
'schedule': timedelta(seconds = AWX_ISOLATED_PERIODIC_CHECK),
|
||||||
'options': {'expires': AWX_ISOLATED_PERIODIC_CHECK * 2,}
|
'options': {'expires': AWX_ISOLATED_PERIODIC_CHECK * 2,}
|
||||||
@@ -135,7 +136,7 @@ CELERYBEAT_SCHEDULE['isolated_heartbeat'] = {
|
|||||||
|
|
||||||
# Supervisor service name dictionary used for programatic restart
|
# Supervisor service name dictionary used for programatic restart
|
||||||
SERVICE_NAME_DICT = {
|
SERVICE_NAME_DICT = {
|
||||||
"celery": "celeryd",
|
"celery": "celery",
|
||||||
"callback": "receiver",
|
"callback": "receiver",
|
||||||
"runworker": "channels",
|
"runworker": "channels",
|
||||||
"uwsgi": "uwsgi",
|
"uwsgi": "uwsgi",
|
||||||
|
|||||||
@@ -12,6 +12,8 @@
|
|||||||
# MISC PROJECT SETTINGS
|
# MISC PROJECT SETTINGS
|
||||||
###############################################################################
|
###############################################################################
|
||||||
import os
|
import os
|
||||||
|
import urllib
|
||||||
|
|
||||||
|
|
||||||
def patch_broken_pipe_error():
|
def patch_broken_pipe_error():
|
||||||
"""Monkey Patch BaseServer.handle_error to not write
|
"""Monkey Patch BaseServer.handle_error to not write
|
||||||
@@ -51,7 +53,7 @@ MANAGERS = ADMINS
|
|||||||
# Database settings to use PostgreSQL for development.
|
# Database settings to use PostgreSQL for development.
|
||||||
DATABASES = {
|
DATABASES = {
|
||||||
'default': {
|
'default': {
|
||||||
'ENGINE': 'transaction_hooks.backends.postgresql_psycopg2',
|
'ENGINE': 'django.db.backends.postgresql',
|
||||||
'NAME': 'awx-dev',
|
'NAME': 'awx-dev',
|
||||||
'USER': 'awx-dev',
|
'USER': 'awx-dev',
|
||||||
'PASSWORD': 'AWXsome1',
|
'PASSWORD': 'AWXsome1',
|
||||||
@@ -67,7 +69,7 @@ DATABASES = {
|
|||||||
if is_testing(sys.argv):
|
if is_testing(sys.argv):
|
||||||
DATABASES = {
|
DATABASES = {
|
||||||
'default': {
|
'default': {
|
||||||
'ENGINE': 'transaction_hooks.backends.sqlite3',
|
'ENGINE': 'django.db.backends.sqlite3',
|
||||||
'NAME': os.path.join(BASE_DIR, 'awx.sqlite3'),
|
'NAME': os.path.join(BASE_DIR, 'awx.sqlite3'),
|
||||||
'TEST': {
|
'TEST': {
|
||||||
# Test database cannot be :memory: for celery/inventory tests.
|
# Test database cannot be :memory: for celery/inventory tests.
|
||||||
@@ -79,15 +81,15 @@ if is_testing(sys.argv):
|
|||||||
MONGO_DB = 'system_tracking_test'
|
MONGO_DB = 'system_tracking_test'
|
||||||
|
|
||||||
# Celery AMQP configuration.
|
# Celery AMQP configuration.
|
||||||
BROKER_URL = "amqp://{}:{}@{}/{}".format(os.environ.get("RABBITMQ_USER"),
|
CELERY_BROKER_URL = "amqp://{}:{}@{}/{}".format(os.environ.get("RABBITMQ_USER"),
|
||||||
os.environ.get("RABBITMQ_PASS"),
|
os.environ.get("RABBITMQ_PASS"),
|
||||||
os.environ.get("RABBITMQ_HOST"),
|
os.environ.get("RABBITMQ_HOST"),
|
||||||
os.environ.get("RABBITMQ_VHOST"))
|
urllib.quote(os.environ.get("RABBITMQ_VHOST", "/"), safe=''))
|
||||||
|
|
||||||
CHANNEL_LAYERS = {
|
CHANNEL_LAYERS = {
|
||||||
'default': {'BACKEND': 'asgi_amqp.AMQPChannelLayer',
|
'default': {'BACKEND': 'asgi_rabbitmq.RabbitmqChannelLayer',
|
||||||
'ROUTING': 'awx.main.routing.channel_routing',
|
'ROUTING': 'awx.main.routing.channel_routing',
|
||||||
'CONFIG': {'url': BROKER_URL}}
|
'CONFIG': {'url': CELERY_BROKER_URL}}
|
||||||
}
|
}
|
||||||
|
|
||||||
# Mongo host configuration
|
# Mongo host configuration
|
||||||
@@ -114,7 +116,8 @@ SYSTEM_UUID = '00000000-0000-0000-0000-000000000000'
|
|||||||
# timezone as the operating system.
|
# timezone as the operating system.
|
||||||
# If running in a Windows environment this must be set to the same as your
|
# If running in a Windows environment this must be set to the same as your
|
||||||
# system time zone.
|
# system time zone.
|
||||||
TIME_ZONE = None
|
USE_TZ = True
|
||||||
|
TIME_ZONE = 'UTC'
|
||||||
|
|
||||||
# Language code for this installation. All choices can be found here:
|
# Language code for this installation. All choices can be found here:
|
||||||
# http://www.i18nguy.com/unicode/language-identifiers.html
|
# http://www.i18nguy.com/unicode/language-identifiers.html
|
||||||
@@ -191,7 +194,7 @@ EMAIL_SUBJECT_PREFIX = '[AWX] '
|
|||||||
LOGGING['handlers']['syslog'] = {
|
LOGGING['handlers']['syslog'] = {
|
||||||
'level': 'WARNING',
|
'level': 'WARNING',
|
||||||
'filters': ['require_debug_false'],
|
'filters': ['require_debug_false'],
|
||||||
'class': 'django.utils.log.NullHandler',
|
'class': 'logging.NullHandler',
|
||||||
'formatter': 'simple',
|
'formatter': 'simple',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -60,8 +60,8 @@ LOGGING['handlers']['rbac_migrations']['filename'] = '/var/log/tower/tower_rbac_
|
|||||||
|
|
||||||
# Supervisor service name dictionary used for programatic restart
|
# Supervisor service name dictionary used for programatic restart
|
||||||
SERVICE_NAME_DICT = {
|
SERVICE_NAME_DICT = {
|
||||||
"beat": "awx-celeryd-beat",
|
"beat": "awx-celery-beat",
|
||||||
"celery": "awx-celeryd",
|
"celery": "awx-celery",
|
||||||
"callback": "awx-callback-receiver",
|
"callback": "awx-callback-receiver",
|
||||||
"channels": "awx-channels-worker",
|
"channels": "awx-channels-worker",
|
||||||
"uwsgi": "awx-uwsgi",
|
"uwsgi": "awx-uwsgi",
|
||||||
|
|||||||
@@ -25,9 +25,9 @@ from radiusauth.backends import RADIUSBackend as BaseRADIUSBackend
|
|||||||
import tacacs_plus
|
import tacacs_plus
|
||||||
|
|
||||||
# social
|
# social
|
||||||
from social.backends.saml import OID_USERID
|
from social_core.backends.saml import OID_USERID
|
||||||
from social.backends.saml import SAMLAuth as BaseSAMLAuth
|
from social_core.backends.saml import SAMLAuth as BaseSAMLAuth
|
||||||
from social.backends.saml import SAMLIdentityProvider as BaseSAMLIdentityProvider
|
from social_core.backends.saml import SAMLIdentityProvider as BaseSAMLIdentityProvider
|
||||||
|
|
||||||
# Ansible Tower
|
# Ansible Tower
|
||||||
from awx.conf.license import feature_enabled
|
from awx.conf.license import feature_enabled
|
||||||
|
|||||||
@@ -13,9 +13,9 @@ from django.shortcuts import redirect
|
|||||||
from django.utils.timezone import now
|
from django.utils.timezone import now
|
||||||
|
|
||||||
# Python Social Auth
|
# Python Social Auth
|
||||||
from social.exceptions import SocialAuthBaseException
|
from social_core.exceptions import SocialAuthBaseException
|
||||||
from social.utils import social_logger
|
from social_core.utils import social_logger
|
||||||
from social.apps.django_app.middleware import SocialAuthExceptionMiddleware
|
from social_django.middleware import SocialAuthExceptionMiddleware
|
||||||
|
|
||||||
# Ansible Tower
|
# Ansible Tower
|
||||||
from awx.main.models import AuthToken
|
from awx.main.models import AuthToken
|
||||||
|
|||||||
@@ -1,2 +0,0 @@
|
|||||||
# Copyright (c) 2017 Ansible, Inc.
|
|
||||||
# All Rights Reserved.
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
# Copyright (c) 2017 Ansible, Inc.
|
|
||||||
# All Rights Reserved.
|
|
||||||
|
|
||||||
from social.strategies.django_strategy import DjangoStrategy
|
|
||||||
|
|
||||||
|
|
||||||
class AWXDjangoStrategy(DjangoStrategy):
|
|
||||||
"""A DjangoStrategy for python-social-auth containing
|
|
||||||
fixes and updates from social-app-django
|
|
||||||
|
|
||||||
TODO: Revert back to using the default DjangoStrategy after
|
|
||||||
we upgrade to social-core / social-app-django. We will also
|
|
||||||
want to ensure we update the SOCIAL_AUTH_STRATEGY setting.
|
|
||||||
"""
|
|
||||||
|
|
||||||
def request_port(self):
|
|
||||||
"""Port in use for this request
|
|
||||||
https://github.com/python-social-auth/social-app-django/blob/master/social_django/strategy.py#L76
|
|
||||||
"""
|
|
||||||
try: # django >= 1.9
|
|
||||||
return self.request.get_port()
|
|
||||||
except AttributeError: # django < 1.9
|
|
||||||
host_parts = self.request.get_host().split(':')
|
|
||||||
try:
|
|
||||||
return host_parts[1]
|
|
||||||
except IndexError:
|
|
||||||
return self.request.META['SERVER_PORT']
|
|
||||||
@@ -1,13 +1,19 @@
|
|||||||
# Copyright (c) 2015 Ansible, Inc.
|
# Copyright (c) 2015 Ansible, Inc.
|
||||||
# All Rights Reserved.
|
# All Rights Reserved.
|
||||||
|
|
||||||
# Django
|
from django.conf.urls import url
|
||||||
from django.conf.urls import patterns, url
|
from awx.sso.views import (
|
||||||
|
sso_complete,
|
||||||
urlpatterns = patterns(
|
sso_error,
|
||||||
'awx.sso.views',
|
sso_inactive,
|
||||||
url(r'^complete/$', 'sso_complete', name='sso_complete'),
|
saml_metadata,
|
||||||
url(r'^error/$', 'sso_error', name='sso_error'),
|
|
||||||
url(r'^inactive/$', 'sso_inactive', name='sso_inactive'),
|
|
||||||
url(r'^metadata/saml/$', 'saml_metadata', name='saml_metadata'),
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
app_name = 'sso'
|
||||||
|
urlpatterns = [
|
||||||
|
url(r'^complete/$', sso_complete, name='sso_complete'),
|
||||||
|
url(r'^error/$', sso_error, name='sso_error'),
|
||||||
|
url(r'^inactive/$', sso_inactive, name='sso_inactive'),
|
||||||
|
url(r'^metadata/saml/$', saml_metadata, name='saml_metadata'),
|
||||||
|
]
|
||||||
|
|||||||
@@ -79,7 +79,7 @@ sso_complete = CompleteView.as_view()
|
|||||||
class MetadataView(View):
|
class MetadataView(View):
|
||||||
|
|
||||||
def get(self, request, *args, **kwargs):
|
def get(self, request, *args, **kwargs):
|
||||||
from social.apps.django_app.utils import load_backend, load_strategy
|
from social_django.utils import load_backend, load_strategy
|
||||||
complete_url = reverse('social:complete', args=('saml', ))
|
complete_url = reverse('social:complete', args=('saml', ))
|
||||||
saml_backend = load_backend(
|
saml_backend = load_backend(
|
||||||
load_strategy(request),
|
load_strategy(request),
|
||||||
|
|||||||
@@ -1,270 +1,295 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
{# Copy of base.html from rest_framework with minor AWX change. #}
|
{# Copy of base.html from rest_framework with minor AWX change. #}
|
||||||
{% load staticfiles %}
|
{% load staticfiles %}
|
||||||
{% load rest_framework %}
|
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
|
{% load rest_framework %}
|
||||||
|
|
||||||
|
<!DOCTYPE html>
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
{% block head %}
|
{% block head %}
|
||||||
|
|
||||||
{% block meta %}
|
{% block meta %}
|
||||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
|
||||||
<meta name="robots" content="NONE,NOARCHIVE" />
|
<meta name="robots" content="NONE,NOARCHIVE" />
|
||||||
{% endblock %}
|
|
||||||
|
|
||||||
<title>{% block title %}Django REST framework{% endblock %}</title>
|
|
||||||
|
|
||||||
{% block style %}
|
|
||||||
{% block bootstrap_theme %}
|
|
||||||
<link rel="stylesheet" type="text/css" href="{% static "rest_framework/css/bootstrap.min.css" %}"/>
|
|
||||||
<link rel="stylesheet" type="text/css" href="{% static "rest_framework/css/bootstrap-tweaks.css" %}"/>
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
<link rel="stylesheet" type="text/css" href="{% static "rest_framework/css/prettify.css" %}"/>
|
<title>{% block title %}{% if name %}{{ name }} – {% endif %}Django REST framework{% endblock %}</title>
|
||||||
<link rel="stylesheet" type="text/css" href="{% static "rest_framework/css/default.css" %}"/>
|
|
||||||
{% endblock %}
|
|
||||||
|
|
||||||
{% endblock %}
|
{% block style %}
|
||||||
</head>
|
{% block bootstrap_theme %}
|
||||||
|
<link rel="stylesheet" type="text/css" href="{% static "rest_framework/css/bootstrap.min.css" %}"/>
|
||||||
|
<link rel="stylesheet" type="text/css" href="{% static "rest_framework/css/bootstrap-tweaks.css" %}"/>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
{% block body %}
|
<link rel="stylesheet" type="text/css" href="{% static "rest_framework/css/prettify.css" %}"/>
|
||||||
<body class="{% block bodyclass %}{% endblock %}">
|
<link rel="stylesheet" type="text/css" href="{% static "rest_framework/css/default.css" %}"/>
|
||||||
|
|
||||||
<div class="wrapper">
|
|
||||||
{% block navbar %}
|
|
||||||
<div class="navbar navbar-static-top {% block bootstrap_navbar_variant %}navbar-inverse{% endblock %}">
|
|
||||||
<div class="container">
|
|
||||||
<span>
|
|
||||||
{% block branding %}
|
|
||||||
<a class='navbar-brand' rel="nofollow" href='http://www.django-rest-framework.org'>
|
|
||||||
Django REST framework <span class="version">{{ version }}</span>
|
|
||||||
</a>
|
|
||||||
{% endblock %}
|
|
||||||
</span>
|
|
||||||
<ul class="nav navbar-nav pull-right">
|
|
||||||
{% block userlinks %}
|
|
||||||
{% if user.is_authenticated %}
|
|
||||||
{% optional_logout request user %}
|
|
||||||
{% else %}
|
|
||||||
{% optional_login request %}
|
|
||||||
{% endif %}
|
|
||||||
{% endblock %}
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% endblock %}
|
|
||||||
|
|
||||||
<div class="container">
|
|
||||||
{% block breadcrumbs %}
|
|
||||||
<ul class="breadcrumb">
|
|
||||||
{% for breadcrumb_name, breadcrumb_url in breadcrumblist %}
|
|
||||||
{% if forloop.last %}
|
|
||||||
<li class="active"><a href="{{ breadcrumb_url }}">{{ breadcrumb_name }}</a></li>
|
|
||||||
{% else %}
|
|
||||||
<li><a href="{{ breadcrumb_url }}">{{ breadcrumb_name }}</a></li>
|
|
||||||
{% endif %}
|
|
||||||
{% endfor %}
|
|
||||||
</ul>
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
<!-- Content -->
|
{% endblock %}
|
||||||
<div id="content">
|
</head>
|
||||||
|
|
||||||
{% if 'GET' in allowed_methods %}
|
{% block body %}
|
||||||
<form id="get-form" class="pull-right">
|
<body class="{% block bodyclass %}{% endblock %}">
|
||||||
<fieldset>
|
|
||||||
{% if api_settings.URL_FORMAT_OVERRIDE %}
|
|
||||||
<div class="btn-group format-selection">
|
|
||||||
<a class="btn btn-primary js-tooltip" href="{{ request.get_full_path }}" rel="nofollow" title="{% blocktrans %}Make a GET request on the {{ name }} resource{% endblocktrans %}">GET</a>
|
|
||||||
|
|
||||||
<button class="btn btn-primary dropdown-toggle js-tooltip" data-toggle="dropdown" title="{% trans 'Specify a format for the GET request' %}">
|
<div class="wrapper">
|
||||||
<span class="caret"></span>
|
{% block navbar %}
|
||||||
</button>
|
<div class="navbar navbar-static-top {% block bootstrap_navbar_variant %}navbar-inverse{% endblock %}"
|
||||||
<ul class="dropdown-menu">
|
role="navigation" aria-label="{% trans "navbar" %}">
|
||||||
{% for format in available_formats %}
|
<div class="container">
|
||||||
<li>
|
<span>
|
||||||
<a class="js-tooltip format-option" href="{% add_query_param request api_settings.URL_FORMAT_OVERRIDE format %}" rel="nofollow" title="{% blocktrans %}Make a GET request on the {{ name }} resource with the format set to `{{ format }}`{% endblocktrans %}">{{ format }}</a>
|
{% block branding %}
|
||||||
</li>
|
<a class='navbar-brand' rel="nofollow" href='http://www.django-rest-framework.org'>
|
||||||
{% endfor %}
|
Django REST framework
|
||||||
</ul>
|
</a>
|
||||||
</div>
|
|
||||||
{% else %}
|
|
||||||
<a class="btn btn-primary js-tooltip" href="{{ request.get_full_path }}" rel="nofollow" title="{% blocktrans %}Make a GET request on the {{ name }} resource{% endblocktrans %}">GET</a>
|
|
||||||
{% endif %}
|
|
||||||
</fieldset>
|
|
||||||
</form>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
{% if options_form %}
|
|
||||||
<form class="button-form" action="{{ request.get_full_path }}" data-method="OPTIONS">
|
|
||||||
<button class="btn btn-primary js-tooltip" title="{% blocktrans %}Make an OPTIONS request on the {{ name }} resource{% endblocktrans %}">OPTIONS</button>
|
|
||||||
</form>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
{% if delete_form %}
|
|
||||||
<form class="button-form" action="{{ request.get_full_path }}" data-method="DELETE">
|
|
||||||
<button class="btn btn-danger js-tooltip" title="{% blocktrans %}Make a DELETE request on the {{ name }} resource{% endblocktrans %}">DELETE</button>
|
|
||||||
</form>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
{% if filter_form %}
|
|
||||||
<button style="float: right; margin-right: 10px" data-toggle="modal" data-target="#filtersModal" class="btn btn-default">
|
|
||||||
<span class="glyphicon glyphicon-wrench" aria-hidden="true"></span>
|
|
||||||
{% trans "Filters" %}
|
|
||||||
</button>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
<div class="content-main">
|
|
||||||
<div class="page-header">
|
|
||||||
<h1>{{ name }}</h1>
|
|
||||||
</div>
|
|
||||||
<div style="float:left">
|
|
||||||
{% block description %}
|
|
||||||
{{ description }}
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
</div>
|
</span>
|
||||||
|
<ul class="nav navbar-nav pull-right">
|
||||||
|
{% block userlinks %}
|
||||||
|
{% if user.is_authenticated %}
|
||||||
|
{% optional_logout request user %}
|
||||||
|
{% else %}
|
||||||
|
{% optional_login request %}
|
||||||
|
{% endif %}
|
||||||
|
{% endblock %}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
{% if paginator %}
|
<div class="container">
|
||||||
<nav style="float: right">
|
{% block breadcrumbs %}
|
||||||
{% get_pagination_html paginator %}
|
<ul class="breadcrumb">
|
||||||
</nav>
|
{% for breadcrumb_name, breadcrumb_url in breadcrumblist %}
|
||||||
{% endif %}
|
{% if forloop.last %}
|
||||||
|
<li class="active"><a href="{{ breadcrumb_url }}">{{ breadcrumb_name }}</a></li>
|
||||||
|
{% else %}
|
||||||
|
<li><a href="{{ breadcrumb_url }}">{{ breadcrumb_name }}</a></li>
|
||||||
|
{% endif %}
|
||||||
|
{% empty %}
|
||||||
|
{% block breadcrumbs_empty %} {% endblock breadcrumbs_empty %}
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
<div class="request-info" style="clear: both" >
|
<!-- Content -->
|
||||||
<pre class="prettyprint"><b>{{ request.method }}</b> {{ request.get_full_path }}</pre>
|
<div id="content" role="main" aria-label="{% trans "content" %}">
|
||||||
</div>
|
{% block content %}
|
||||||
|
|
||||||
<div class="response-info">
|
<div class="region" aria-label="{% trans "request form" %}">
|
||||||
<pre class="prettyprint"><span class="meta nocode"><b>HTTP {{ response.status_code }} {{ response.status_text }}</b>{% autoescape off %}
|
{% if 'GET' in allowed_methods %}
|
||||||
{% for key, val in response_headers.items %}<b>{{ key }}:</b> <span class="lit">{{ val|break_long_headers|urlize_quoted_links }}</span>
|
<form id="get-form" class="pull-right">
|
||||||
{% endfor %}
|
<fieldset>
|
||||||
{# Original line below had the side effect of also escaping content: #}
|
{% if api_settings.URL_FORMAT_OVERRIDE %}
|
||||||
{# </span>{{ content|urlize_quoted_links }}</pre>{% endautoescape %} #}
|
<div class="btn-group format-selection">
|
||||||
{# For Ansible Tower, disable automatic URL creation and move content outside of autoescape off block. #}
|
<a class="btn btn-primary js-tooltip" href="{{ request.get_full_path }}" rel="nofollow" title="Make a GET request on the {{ name }} resource">GET</a>
|
||||||
{% endautoescape %}</span>{{ content }}</pre>
|
|
||||||
|
<button class="btn btn-primary dropdown-toggle js-tooltip" data-toggle="dropdown" title="Specify a format for the GET request">
|
||||||
|
<span class="caret"></span>
|
||||||
|
</button>
|
||||||
|
<ul class="dropdown-menu">
|
||||||
|
{% for format in available_formats %}
|
||||||
|
<li>
|
||||||
|
<a class="js-tooltip format-option" href="{% add_query_param request api_settings.URL_FORMAT_OVERRIDE format %}" rel="nofollow" title="Make a GET request on the {{ name }} resource with the format set to `{{ format }}`">{{ format }}</a>
|
||||||
|
</li>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
{% else %}
|
||||||
|
<a class="btn btn-primary js-tooltip" href="{{ request.get_full_path }}" rel="nofollow" title="Make a GET request on the {{ name }} resource">GET</a>
|
||||||
|
{% endif %}
|
||||||
|
</fieldset>
|
||||||
|
</form>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if options_form %}
|
||||||
|
<form class="button-form" action="{{ request.get_full_path }}" data-method="OPTIONS">
|
||||||
|
<button class="btn btn-primary js-tooltip" title="Make an OPTIONS request on the {{ name }} resource">OPTIONS</button>
|
||||||
|
</form>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if delete_form %}
|
||||||
|
<button class="btn btn-danger button-form js-tooltip" title="Make a DELETE request on the {{ name }} resource" data-toggle="modal" data-target="#deleteModal">DELETE</button>
|
||||||
|
|
||||||
|
<!-- Delete Modal -->
|
||||||
|
<div class="modal fade" id="deleteModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
|
||||||
|
<div class="modal-dialog">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-body">
|
||||||
|
<h4 class="text-center">Are you sure you want to delete this {{ name }}?</h4>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
|
||||||
|
<form class="button-form" action="{{ request.get_full_path }}" data-method="DELETE">
|
||||||
|
<button class="btn btn-danger">Delete</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if filter_form %}
|
||||||
|
<button style="float: right; margin-right: 10px" data-toggle="modal" data-target="#filtersModal" class="btn btn-default">
|
||||||
|
<span class="glyphicon glyphicon-wrench" aria-hidden="true"></span>
|
||||||
|
{% trans "Filters" %}
|
||||||
|
</button>
|
||||||
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% if display_edit_forms %}
|
<div class="content-main" role="main" aria-label="{% trans "main content" %}">
|
||||||
|
<div class="page-header">
|
||||||
|
<h1>{{ name }}</h1>
|
||||||
|
</div>
|
||||||
|
<div style="float:left">
|
||||||
|
{% block description %}
|
||||||
|
{{ description }}
|
||||||
|
{% endblock %}
|
||||||
|
</div>
|
||||||
|
|
||||||
{% if post_form or raw_data_post_form %}
|
{% if paginator %}
|
||||||
<div {% if post_form %}class="tabbable"{% endif %}>
|
<nav style="float: right">
|
||||||
{% if post_form %}
|
{% get_pagination_html paginator %}
|
||||||
<ul class="nav nav-tabs form-switcher">
|
</nav>
|
||||||
<li>
|
{% endif %}
|
||||||
<a name='html-tab' href="#post-object-form" data-toggle="tab">HTML form</a>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<a name='raw-tab' href="#post-generic-content-form" data-toggle="tab">Raw data</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
<div class="well tab-content">
|
<div class="request-info" style="clear: both" aria-label="{% trans "request info" %}">
|
||||||
|
<pre class="prettyprint"><b>{{ request.method }}</b> {{ request.get_full_path }}</pre>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="response-info" aria-label="{% trans "response info" %}">
|
||||||
|
<pre class="prettyprint"><span class="meta nocode"><b>HTTP {{ response.status_code }} {{ response.status_text }}</b>{% autoescape off %}{% for key, val in response_headers|items %}
|
||||||
|
<b>{{ key }}:</b> <span class="lit">{{ val|break_long_headers|urlize_quoted_links }}</span>{% endfor %}
|
||||||
|
{# Original line below had the side effect of also escaping content: #}
|
||||||
|
{# </span>{{ content|urlize_quoted_links }}</pre>{% endautoescape %} #}
|
||||||
|
{# For AWX, disable automatic URL creation and move content outside of autoescape off block. #}
|
||||||
|
{% endautoescape %}</span>{{ content }}</pre>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{% if display_edit_forms %}
|
||||||
|
{% if post_form or raw_data_post_form %}
|
||||||
|
<div {% if post_form %}class="tabbable"{% endif %}>
|
||||||
{% if post_form %}
|
{% if post_form %}
|
||||||
<div class="tab-pane" id="post-object-form">
|
<ul class="nav nav-tabs form-switcher">
|
||||||
{% with form=post_form %}
|
<li>
|
||||||
<form action="{{ request.get_full_path }}" method="POST" enctype="multipart/form-data" class="form-horizontal" novalidate>
|
<a name='html-tab' href="#post-object-form" data-toggle="tab">HTML form</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a name='raw-tab' href="#post-generic-content-form" data-toggle="tab">Raw data</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
<div class="well tab-content">
|
||||||
|
{% if post_form %}
|
||||||
|
<div class="tab-pane" id="post-object-form">
|
||||||
|
{% with form=post_form %}
|
||||||
|
<form action="{{ request.get_full_path }}" method="POST" enctype="multipart/form-data" class="form-horizontal" novalidate>
|
||||||
|
<fieldset>
|
||||||
|
{% csrf_token %}
|
||||||
|
{{ post_form }}
|
||||||
|
<div class="form-actions">
|
||||||
|
<button class="btn btn-primary" title="Make a POST request on the {{ name }} resource">POST</button>
|
||||||
|
</div>
|
||||||
|
</fieldset>
|
||||||
|
</form>
|
||||||
|
{% endwith %}
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
<div {% if post_form %}class="tab-pane"{% endif %} id="post-generic-content-form">
|
||||||
|
{% with form=raw_data_post_form %}
|
||||||
|
<form action="{{ request.get_full_path }}" method="POST" class="form-horizontal">
|
||||||
<fieldset>
|
<fieldset>
|
||||||
{% csrf_token %}
|
{% include "rest_framework/raw_data_form.html" %}
|
||||||
{{ post_form }}
|
|
||||||
<div class="form-actions">
|
<div class="form-actions">
|
||||||
<button class="btn btn-primary" title="{% blocktrans %}Make a POST request on the {{ name }} resource{% endblocktrans %}">POST</button>
|
<button class="btn btn-primary" title="Make a POST request on the {{ name }} resource">POST</button>
|
||||||
</div>
|
</div>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
</form>
|
</form>
|
||||||
{% endwith %}
|
{% endwith %}
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
<div {% if raw_data_post_form %}class="tab-pane"{% endif %} id="post-generic-content-form">
|
|
||||||
{% with form=raw_data_post_form %}
|
|
||||||
<form action="{{ request.get_full_path }}" method="POST" class="form-horizontal">
|
|
||||||
<fieldset>
|
|
||||||
{% include "rest_framework/raw_data_form.html" %}
|
|
||||||
<div class="form-actions">
|
|
||||||
<button class="btn btn-primary" title="{% blocktrans %}Make a POST request on the {{ name }} resource{% endblocktrans %}">POST</button>
|
|
||||||
</div>
|
|
||||||
</fieldset>
|
|
||||||
</form>
|
|
||||||
{% endwith %}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
{% endif %}
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
{% if put_form or raw_data_put_form or raw_data_patch_form %}
|
{% if put_form or raw_data_put_form or raw_data_patch_form %}
|
||||||
<div {% if put_form %}class="tabbable"{% endif %}>
|
<div {% if put_form %}class="tabbable"{% endif %}>
|
||||||
{% if put_form %}
|
|
||||||
<ul class="nav nav-tabs form-switcher">
|
|
||||||
<li>
|
|
||||||
<a name='html-tab' href="#put-object-form" data-toggle="tab">HTML form</a>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<a name='raw-tab' href="#put-generic-content-form" data-toggle="tab">Raw data</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
<div class="well tab-content">
|
|
||||||
{% if put_form %}
|
{% if put_form %}
|
||||||
<div class="tab-pane" id="put-object-form">
|
<ul class="nav nav-tabs form-switcher">
|
||||||
<form action="{{ request.get_full_path }}" data-method="PUT" enctype="multipart/form-data" class="form-horizontal" novalidate>
|
<li>
|
||||||
<fieldset>
|
<a name='html-tab' href="#put-object-form" data-toggle="tab">HTML form</a>
|
||||||
{{ put_form }}
|
</li>
|
||||||
<div class="form-actions">
|
<li>
|
||||||
<button class="btn btn-primary js-tooltip" title="{% blocktrans %}Make a PUT request on the {{ name }} resource{% endblocktrans %}">PUT</button>
|
<a name='raw-tab' href="#put-generic-content-form" data-toggle="tab">Raw data</a>
|
||||||
</div>
|
</li>
|
||||||
</fieldset>
|
</ul>
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
<div {% if put_form %}class="tab-pane"{% endif %} id="put-generic-content-form">
|
<div class="well tab-content">
|
||||||
{% with form=raw_data_put_or_patch_form %}
|
{% if put_form %}
|
||||||
<form action="{{ request.get_full_path }}" data-method="PUT" class="form-horizontal">
|
<div class="tab-pane" id="put-object-form">
|
||||||
<fieldset>
|
<form action="{{ request.get_full_path }}" data-method="PUT" enctype="multipart/form-data" class="form-horizontal" novalidate>
|
||||||
{% include "rest_framework/raw_data_form.html" %}
|
<fieldset>
|
||||||
<div class="form-actions">
|
{{ put_form }}
|
||||||
{% if raw_data_put_form %}
|
<div class="form-actions">
|
||||||
<button class="btn btn-primary js-tooltip" title="{% blocktrans %}Make a PUT request on the {{ name }} resource{% endblocktrans %}">PUT</button>
|
<button class="btn btn-primary js-tooltip" title="Make a PUT request on the {{ name }} resource">PUT</button>
|
||||||
{% endif %}
|
</div>
|
||||||
{% if raw_data_patch_form %}
|
</fieldset>
|
||||||
<button data-method="PATCH" class="btn btn-primary js-tooltip" title="{% blocktrans %}Make a PATCH request on the {{ name }} resource{% endblocktrans %}">PATCH</button>
|
</form>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
<div {% if put_form %}class="tab-pane"{% endif %} id="put-generic-content-form">
|
||||||
|
{% with form=raw_data_put_or_patch_form %}
|
||||||
|
<form action="{{ request.get_full_path }}" data-method="PUT" class="form-horizontal">
|
||||||
|
<fieldset>
|
||||||
|
{% include "rest_framework/raw_data_form.html" %}
|
||||||
|
<div class="form-actions">
|
||||||
|
{% if raw_data_put_form %}
|
||||||
|
<button class="btn btn-primary js-tooltip" title="Make a PUT request on the {{ name }} resource">PUT</button>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
{% if raw_data_patch_form %}
|
||||||
</fieldset>
|
<button data-method="PATCH" class="btn btn-primary js-tooltip" title="Make a PATCH request on the {{ name }} resource">PATCH</button>
|
||||||
</form>
|
{% endif %}
|
||||||
{% endwith %}
|
</div>
|
||||||
|
</fieldset>
|
||||||
|
</form>
|
||||||
|
{% endwith %}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
{% endif %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endif %}
|
{% endblock content %}
|
||||||
</div><!-- /.content -->
|
</div><!-- /.content -->
|
||||||
</div><!-- /.container -->
|
</div><!-- /.container -->
|
||||||
{# div#push added for Ansible Tower. #}
|
</div><!-- ./wrapper -->
|
||||||
<div id="push"></div>
|
|
||||||
</div><!-- ./wrapper -->
|
|
||||||
|
|
||||||
{% block script %}
|
{% if filter_form %}
|
||||||
<script src="{% static "rest_framework/js/jquery-1.11.3.min.js" %}"></script>
|
{{ filter_form }}
|
||||||
<script src="{% static "rest_framework/js/ajax-form.js" %}"></script>
|
{% endif %}
|
||||||
<script src="{% static "rest_framework/js/csrf.js" %}"></script>
|
|
||||||
<script src="{% static "rest_framework/js/bootstrap.min.js" %}"></script>
|
{% block script %}
|
||||||
<script src="{% static "rest_framework/js/prettify-min.js" %}"></script>
|
<script>
|
||||||
<script src="{% static "rest_framework/js/default.js" %}"></script>
|
window.drf = {
|
||||||
<script>
|
csrfHeaderName: "{{ csrf_header_name|default:'X-CSRFToken' }}",
|
||||||
|
csrfCookieName: "{{ csrf_cookie_name|default:'csrftoken' }}"
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
<script src="{% static "rest_framework/js/jquery-1.12.4.min.js" %}"></script>
|
||||||
|
<script src="{% static "rest_framework/js/ajax-form.js" %}"></script>
|
||||||
|
<script src="{% static "rest_framework/js/csrf.js" %}"></script>
|
||||||
|
<script src="{% static "rest_framework/js/bootstrap.min.js" %}"></script>
|
||||||
|
<script src="{% static "rest_framework/js/prettify-min.js" %}"></script>
|
||||||
|
<script src="{% static "rest_framework/js/default.js" %}"></script>
|
||||||
|
<script>
|
||||||
$(document).ready(function() {
|
$(document).ready(function() {
|
||||||
$('form').ajaxForm();
|
$('form').ajaxForm();
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
</body>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% if filter_form %}
|
|
||||||
{{ filter_form }}
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
</body>
|
|
||||||
{% endblock %}
|
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -1,11 +1,17 @@
|
|||||||
# Copyright (c) 2015 Ansible, Inc.
|
# Copyright (c) 2015 Ansible, Inc.
|
||||||
# All Rights Reserved.
|
# All Rights Reserved.
|
||||||
|
|
||||||
from django.conf import settings
|
from django.conf.urls import url
|
||||||
from django.conf.urls import *
|
from awx.ui.views import (
|
||||||
|
index,
|
||||||
urlpatterns = patterns('awx.ui.views',
|
portal_redirect,
|
||||||
url(r'^$', 'index', name='index'),
|
migrations_notran,
|
||||||
url(r'^migrations_notran/$', 'migrations_notran', name='migrations_notran'),
|
|
||||||
url(r'^portal/$', 'portal_redirect', name='portal_redirect'),
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
app_name = 'ui'
|
||||||
|
urlpatterns = [
|
||||||
|
url(r'^$', index, name='index'),
|
||||||
|
url(r'^migrations_notran/$', migrations_notran, name='migrations_notran'),
|
||||||
|
url(r'^portal/$', portal_redirect, name='portal_redirect'),
|
||||||
|
]
|
||||||
|
|||||||
36
awx/urls.py
36
awx/urls.py
@@ -1,25 +1,27 @@
|
|||||||
# Copyright (c) 2015 Ansible, Inc.
|
# Copyright (c) 2015 Ansible, Inc.
|
||||||
# All Rights Reserved.
|
# All Rights Reserved.
|
||||||
|
|
||||||
from django.conf.urls import url, patterns, include
|
from django.conf.urls import url, include
|
||||||
|
from awx.main.views import (
|
||||||
|
handle_400,
|
||||||
|
handle_403,
|
||||||
|
handle_404,
|
||||||
|
handle_500,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
urlpatterns = [
|
||||||
|
url(r'', include('awx.ui.urls', namespace='ui')),
|
||||||
|
url(r'^api/', include('awx.api.urls', namespace='api')),
|
||||||
|
url(r'^sso/', include('awx.sso.urls', namespace='sso')),
|
||||||
|
url(r'^sso/', include('social_django.urls', namespace='social')),
|
||||||
|
url(r'^(?:api/)?400.html$', handle_400),
|
||||||
|
url(r'^(?:api/)?403.html$', handle_403),
|
||||||
|
url(r'^(?:api/)?404.html$', handle_404),
|
||||||
|
url(r'^(?:api/)?500.html$', handle_500),
|
||||||
|
]
|
||||||
|
|
||||||
handler400 = 'awx.main.views.handle_400'
|
handler400 = 'awx.main.views.handle_400'
|
||||||
handler403 = 'awx.main.views.handle_403'
|
handler403 = 'awx.main.views.handle_403'
|
||||||
handler404 = 'awx.main.views.handle_404'
|
handler404 = 'awx.main.views.handle_404'
|
||||||
handler500 = 'awx.main.views.handle_500'
|
handler500 = 'awx.main.views.handle_500'
|
||||||
|
|
||||||
urlpatterns = patterns(
|
|
||||||
'',
|
|
||||||
url(r'', include('awx.ui.urls', namespace='ui', app_name='ui')),
|
|
||||||
url(r'^api/', include('awx.api.urls', namespace='api', app_name='api')),
|
|
||||||
url(r'^sso/', include('awx.sso.urls', namespace='sso', app_name='sso')),
|
|
||||||
url(r'^sso/', include('social.apps.django_app.urls', namespace='social')),
|
|
||||||
)
|
|
||||||
|
|
||||||
urlpatterns += patterns(
|
|
||||||
'awx.main.views',
|
|
||||||
url(r'^(?:api/)?400.html$', 'handle_400'),
|
|
||||||
url(r'^(?:api/)?403.html$', 'handle_403'),
|
|
||||||
url(r'^(?:api/)?404.html$', 'handle_404'),
|
|
||||||
url(r'^(?:api/)?500.html$', 'handle_500'),
|
|
||||||
)
|
|
||||||
|
|||||||
@@ -31,9 +31,9 @@ AWX_PROOT_ENABLED = False
|
|||||||
|
|
||||||
CLUSTER_HOST_ID = "awx"
|
CLUSTER_HOST_ID = "awx"
|
||||||
SYSTEM_UUID = '00000000-0000-0000-0000-000000000000'
|
SYSTEM_UUID = '00000000-0000-0000-0000-000000000000'
|
||||||
CELERY_QUEUES += (Queue(CLUSTER_HOST_ID, Exchange(CLUSTER_HOST_ID), routing_key=CLUSTER_HOST_ID),)
|
CELERY_TASK_QUEUES += (Queue(CLUSTER_HOST_ID, Exchange(CLUSTER_HOST_ID), routing_key=CLUSTER_HOST_ID),)
|
||||||
CELERY_ROUTES['awx.main.tasks.cluster_node_heartbeat'] = {'queue': CLUSTER_HOST_ID, 'routing_key': CLUSTER_HOST_ID}
|
CELERY_TASK_ROUTES['awx.main.tasks.cluster_node_heartbeat'] = {'queue': CLUSTER_HOST_ID, 'routing_key': CLUSTER_HOST_ID}
|
||||||
CELERY_ROUTES['awx.main.tasks.purge_old_stdout_files'] = {'queue': CLUSTER_HOST_ID, 'routing_key': CLUSTER_HOST_ID}
|
CELERY_TASK_ROUTES['awx.main.tasks.purge_old_stdout_files'] = {'queue': CLUSTER_HOST_ID, 'routing_key': CLUSTER_HOST_ID}
|
||||||
|
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
@@ -79,7 +79,7 @@ LOGGING['handlers']['management_playbooks'] = {'class': 'logging.NullHandler'}
|
|||||||
DATABASES = {
|
DATABASES = {
|
||||||
'default': {
|
'default': {
|
||||||
'ATOMIC_REQUESTS': True,
|
'ATOMIC_REQUESTS': True,
|
||||||
'ENGINE': 'transaction_hooks.backends.postgresql_psycopg2',
|
'ENGINE': 'django.db.backends.postgresql',
|
||||||
'NAME': os.getenv("DATABASE_NAME", None),
|
'NAME': os.getenv("DATABASE_NAME", None),
|
||||||
'USER': os.getenv("DATABASE_USER", None),
|
'USER': os.getenv("DATABASE_USER", None),
|
||||||
'PASSWORD': os.getenv("DATABASE_PASSWORD", None),
|
'PASSWORD': os.getenv("DATABASE_PASSWORD", None),
|
||||||
@@ -88,7 +88,7 @@ DATABASES = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BROKER_URL = 'amqp://{}:{}@{}:{}/{}'.format(
|
CELERY_BROKER_URL = 'amqp://{}:{}@{}:{}/{}'.format(
|
||||||
os.getenv("RABBITMQ_USER", None),
|
os.getenv("RABBITMQ_USER", None),
|
||||||
os.getenv("RABBITMQ_PASSWORD", None),
|
os.getenv("RABBITMQ_PASSWORD", None),
|
||||||
os.getenv("RABBITMQ_HOST", None),
|
os.getenv("RABBITMQ_HOST", None),
|
||||||
@@ -98,7 +98,7 @@ BROKER_URL = 'amqp://{}:{}@{}:{}/{}'.format(
|
|||||||
CHANNEL_LAYERS = {
|
CHANNEL_LAYERS = {
|
||||||
'default': {'BACKEND': 'asgi_amqp.AMQPChannelLayer',
|
'default': {'BACKEND': 'asgi_amqp.AMQPChannelLayer',
|
||||||
'ROUTING': 'awx.main.routing.channel_routing',
|
'ROUTING': 'awx.main.routing.channel_routing',
|
||||||
'CONFIG': {'url': BROKER_URL}}
|
'CONFIG': {'url': CELERY_BROKER_URL}}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ data:
|
|||||||
DATABASES = {
|
DATABASES = {
|
||||||
'default': {
|
'default': {
|
||||||
'ATOMIC_REQUESTS': True,
|
'ATOMIC_REQUESTS': True,
|
||||||
'ENGINE': 'transaction_hooks.backends.postgresql_psycopg2',
|
'ENGINE': 'django.db.backends.postgresql',
|
||||||
'NAME': "{{ pg_database }}",
|
'NAME': "{{ pg_database }}",
|
||||||
'USER': "{{ pg_username }}",
|
'USER': "{{ pg_username }}",
|
||||||
'PASSWORD': "{{ pg_password }}",
|
'PASSWORD': "{{ pg_password }}",
|
||||||
@@ -73,7 +73,7 @@ data:
|
|||||||
'PORT': "{{ pg_port }}",
|
'PORT': "{{ pg_port }}",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
BROKER_URL = 'amqp://{}:{}@{}:{}/{}'.format(
|
CELERY_BROKER_URL = 'amqp://{}:{}@{}:{}/{}'.format(
|
||||||
"awx",
|
"awx",
|
||||||
"abcdefg",
|
"abcdefg",
|
||||||
"localhost",
|
"localhost",
|
||||||
@@ -82,7 +82,7 @@ data:
|
|||||||
CHANNEL_LAYERS = {
|
CHANNEL_LAYERS = {
|
||||||
'default': {'BACKEND': 'asgi_amqp.AMQPChannelLayer',
|
'default': {'BACKEND': 'asgi_amqp.AMQPChannelLayer',
|
||||||
'ROUTING': 'awx.main.routing.channel_routing',
|
'ROUTING': 'awx.main.routing.channel_routing',
|
||||||
'CONFIG': {'url': BROKER_URL}}
|
'CONFIG': {'url': CELERY_BROKER_URL}}
|
||||||
}
|
}
|
||||||
CACHES = {
|
CACHES = {
|
||||||
'default': {
|
'default': {
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user