mirror of
https://github.com/ansible/awx.git
synced 2026-01-11 01:57:35 -03:30
Numerous model-related updates and supporing changes, including:
- Add variables field on Host/Group models and remove separate VariableData model. - Add data migrations for existing variable data. - Update views, serializers and tests to keep roughly the same API interface for variable data. - Add has_active_failures properties on Group/Host models to provide indication of last job status. - Add job_tags field on JobTemplate/Job models to specify tags to ansible-playbook. - Add host_config_key field to JobTemplate model for use by empheral hosts. - Add job_args, job_cwd and job_env fields to Job model to capture more info from running the job. - Add failed flag on JobHostSummary model. - Add play/task fields on JobEvent model to capture new context variables from callback. - Add parent field on JobEvent model to capture hierarchy of job events. - Add hosts field on JobEvent model to capture all hosts associated with the event (especially useful for parent events in the hierarchy). - Removed existing Tag model, replace with django-taggit instead. - Removed existing AuditLog model, replacement TBD.
This commit is contained in:
parent
7b0bbff376
commit
cba55a061a
21
Makefile
21
Makefile
@ -1,4 +1,4 @@
|
||||
release = ansibleworks-1.2b1
|
||||
RELEASE = ansibleworks-1.2b2
|
||||
|
||||
clean:
|
||||
rm -rf build *.egg-info
|
||||
@ -81,16 +81,15 @@ release_build:
|
||||
release_ball: clean
|
||||
make release_build
|
||||
(cd ../ansible-doc; make)
|
||||
-(rm -rf $(release))
|
||||
mkdir -p $(release)/dist
|
||||
-(rm -rf $(RELEASE))
|
||||
mkdir -p $(RELEASE)/dist
|
||||
cp -a dist/* $(release)/dist
|
||||
mkdir -p $(release)/setup
|
||||
cp -a setup/* $(release)/setup
|
||||
mkdir -p $(release)/docs
|
||||
cp -a ../ansible-doc/*.pdf $(release)/docs
|
||||
tar -cvf $(release)-all.tar $(release)
|
||||
mkdir -p $(RELEASE)/setup
|
||||
cp -a setup/* $(RELEASE)/setup
|
||||
mkdir -p $(RELEASE)/docs
|
||||
cp -a ../ansible-doc/*.pdf $(RELEASE)/docs
|
||||
tar -cvf $(RELEASE)-all.tar $(RELEASE)
|
||||
|
||||
clean:
|
||||
release_clean:
|
||||
-(rm *.tar)
|
||||
-(rm -rf ($release))
|
||||
|
||||
-(rm -rf ($RELEASE))
|
||||
|
||||
@ -139,18 +139,6 @@ class UserAccess(BaseAccess):
|
||||
return bool(self.user.is_superuser or
|
||||
obj.organizations.filter(admins__in=[self.user]).count())
|
||||
|
||||
class TagAccess(BaseAccess):
|
||||
|
||||
model = Tag
|
||||
|
||||
def can_read(self, obj):
|
||||
# anybody can read tags, we won't show much detail other than the names
|
||||
return True
|
||||
|
||||
def can_add(self, data):
|
||||
# anybody can make up tags
|
||||
return True
|
||||
|
||||
class OrganizationAccess(BaseAccess):
|
||||
|
||||
model = Organization
|
||||
@ -259,6 +247,11 @@ class HostAccess(BaseAccess):
|
||||
# Checks for admin or change permission on inventory.
|
||||
return check_user_access(self.user, Inventory, 'change', inventory, None)
|
||||
|
||||
def can_change(self, obj, data):
|
||||
# Checks for admin or change permission on inventory, controls whether
|
||||
# the user can edit variable data.
|
||||
return check_user_access(self.user, Inventory, 'change', obj.inventory, None)
|
||||
|
||||
class GroupAccess(BaseAccess):
|
||||
|
||||
model = Group
|
||||
@ -275,34 +268,9 @@ class GroupAccess(BaseAccess):
|
||||
|
||||
def can_change(self, obj, data):
|
||||
# Checks for admin or change permission on inventory, controls whether
|
||||
# the user can attach subgroups
|
||||
# the user can attach subgroups or edit variable data.
|
||||
return check_user_access(self.user, Inventory, 'change', obj.inventory, None)
|
||||
|
||||
class VariableDataAccess(BaseAccess):
|
||||
|
||||
model = VariableData
|
||||
|
||||
def can_read(self, obj):
|
||||
if obj.host:
|
||||
inventory = obj.host.inventory
|
||||
elif obj.group:
|
||||
inventory = obj.group.inventory
|
||||
else:
|
||||
return False
|
||||
return check_user_access(self.user, Inventory, 'read', inventory)
|
||||
|
||||
def can_change(self, obj, data):
|
||||
if obj.host:
|
||||
inventory = obj.host.inventory
|
||||
elif obj.group:
|
||||
inventory = obj.group.inventory
|
||||
else:
|
||||
return False
|
||||
return check_user_access(self.user, Inventory, 'change', inventory)
|
||||
|
||||
def can_delete(self, obj):
|
||||
return False
|
||||
|
||||
class CredentialAccess(BaseAccess):
|
||||
|
||||
model = Credential
|
||||
@ -538,12 +506,10 @@ class JobEventAccess(BaseAccess):
|
||||
model = JobEvent
|
||||
|
||||
register_access(User, UserAccess)
|
||||
register_access(Tag, TagAccess)
|
||||
register_access(Organization, OrganizationAccess)
|
||||
register_access(Inventory, InventoryAccess)
|
||||
register_access(Host, HostAccess)
|
||||
register_access(Group, GroupAccess)
|
||||
register_access(VariableData, VariableDataAccess)
|
||||
register_access(Credential, CredentialAccess)
|
||||
register_access(Team, TeamAccess)
|
||||
register_access(Project, ProjectAccess)
|
||||
|
||||
@ -58,25 +58,23 @@ class OrganizationAdmin(BaseModelAdmin):
|
||||
(_('Members'), {'fields': ('users', 'admins',)}),
|
||||
(_('Projects'), {'fields': ('projects',)}),
|
||||
(_('Tags'), {'fields': ('tags',)}),
|
||||
(_('Audit Trail'), {'fields': ('created', 'created_by',
|
||||
'audit_trail',)}),
|
||||
(_('Audit'), {'fields': ('created', 'created_by',)}),
|
||||
)
|
||||
readonly_fields = ('created', 'created_by', 'audit_trail')
|
||||
filter_horizontal = ('users', 'admins', 'projects', 'tags')
|
||||
readonly_fields = ('created', 'created_by')
|
||||
filter_horizontal = ('users', 'admins', 'projects')
|
||||
|
||||
class InventoryHostInline(admin.StackedInline):
|
||||
|
||||
model = Host
|
||||
extra = 0
|
||||
fields = ('name', 'description', 'active', 'tags')
|
||||
filter_horizontal = ('tags',)
|
||||
|
||||
class InventoryGroupInline(admin.StackedInline):
|
||||
|
||||
model = Group
|
||||
extra = 0
|
||||
fields = ('name', 'description', 'active', 'parents', 'hosts', 'tags')
|
||||
filter_horizontal = ('parents', 'hosts', 'tags')
|
||||
filter_horizontal = ('parents', 'hosts')
|
||||
|
||||
class InventoryAdmin(BaseModelAdmin):
|
||||
|
||||
@ -85,15 +83,14 @@ class InventoryAdmin(BaseModelAdmin):
|
||||
fieldsets = (
|
||||
(None, {'fields': (('name', 'active'), 'organization', 'description',)}),
|
||||
(_('Tags'), {'fields': ('tags',)}),
|
||||
(_('Audit Trail'), {'fields': ('created', 'created_by', 'audit_trail',)}),
|
||||
(_('Audit'), {'fields': ('created', 'created_by',)}),
|
||||
)
|
||||
readonly_fields = ('created', 'created_by', 'audit_trail')
|
||||
filter_horizontal = ('tags',)
|
||||
readonly_fields = ('created', 'created_by')
|
||||
inlines = [InventoryHostInline, InventoryGroupInline]
|
||||
|
||||
class TagAdmin(BaseModelAdmin):
|
||||
|
||||
list_display = ('name',)
|
||||
#class TagAdmin(BaseModelAdmin):
|
||||
#
|
||||
# list_display = ('name',)
|
||||
|
||||
#class AuditTrailAdmin(admin.ModelAdmin):
|
||||
#
|
||||
@ -101,13 +98,6 @@ class TagAdmin(BaseModelAdmin):
|
||||
# not currently on model, so disabling for now.
|
||||
# filter_horizontal = ('tags',)
|
||||
|
||||
class VariableDataInline(admin.StackedInline):
|
||||
|
||||
model = VariableData
|
||||
extra = 0
|
||||
max_num = 1
|
||||
# FIXME: Doesn't yet work as inline due to the way the OneToOne field is
|
||||
# defined.
|
||||
|
||||
class JobHostSummaryInline(admin.TabularInline):
|
||||
|
||||
@ -136,9 +126,9 @@ class JobEventInline(admin.StackedInline):
|
||||
class JobHostSummaryInlineForHost(JobHostSummaryInline):
|
||||
|
||||
fields = ('job', 'changed', 'dark', 'failures', 'ok', 'processed',
|
||||
'skipped')
|
||||
'skipped', 'failed')
|
||||
readonly_fields = ('job', 'changed', 'dark', 'failures', 'ok', 'processed',
|
||||
'skipped')
|
||||
'skipped', 'failed')
|
||||
|
||||
class JobEventInlineForHost(JobEventInline):
|
||||
|
||||
@ -149,17 +139,15 @@ class HostAdmin(BaseModelAdmin):
|
||||
|
||||
list_display = ('name', 'inventory', 'description', 'active')
|
||||
list_filter = ('inventory', 'active')
|
||||
#form = HostAdminForm
|
||||
fieldsets = (
|
||||
(None, {'fields': (('name', 'active'), 'inventory', 'description', 'variable_data',
|
||||
(None, {'fields': (('name', 'active'), 'inventory', 'description',
|
||||
'variables',
|
||||
)}),
|
||||
(_('Tags'), {'fields': ('tags',)}),
|
||||
(_('Audit Trail'), {'fields': ('created', 'created_by', 'audit_trail',)}),
|
||||
(_('Audit'), {'fields': ('created', 'created_by',)}),
|
||||
)
|
||||
readonly_fields = ('created', 'created_by', 'audit_trail')
|
||||
filter_horizontal = ('tags',)
|
||||
readonly_fields = ('created', 'created_by')
|
||||
# FIXME: Edit reverse of many to many for groups.
|
||||
#inlines = [VariableDataInline]
|
||||
inlines = [JobHostSummaryInlineForHost, JobEventInlineForHost]
|
||||
|
||||
class GroupAdmin(BaseModelAdmin):
|
||||
@ -167,18 +155,12 @@ class GroupAdmin(BaseModelAdmin):
|
||||
list_display = ('name', 'description', 'active')
|
||||
fieldsets = (
|
||||
(None, {'fields': (('name', 'active'), 'inventory', 'description',
|
||||
'parents')}),
|
||||
'parents', 'variables')}),
|
||||
(_('Tags'), {'fields': ('tags',)}),
|
||||
(_('Audit Trail'), {'fields': ('created', 'created_by', 'audit_trail',)}),
|
||||
(_('Audit'), {'fields': ('created', 'created_by',)}),
|
||||
)
|
||||
readonly_fields = ('created', 'created_by', 'audit_trail')
|
||||
filter_horizontal = ('parents', 'hosts', 'tags')
|
||||
#inlines = [VariableDataInline]
|
||||
|
||||
class VariableDataAdmin(BaseModelAdmin):
|
||||
|
||||
list_display = ('name', 'description', 'active')
|
||||
filter_horizontal = ('tags',)
|
||||
readonly_fields = ('created', 'created_by')
|
||||
filter_horizontal = ('parents', 'hosts')
|
||||
|
||||
class CredentialAdmin(BaseModelAdmin):
|
||||
|
||||
@ -187,16 +169,15 @@ class CredentialAdmin(BaseModelAdmin):
|
||||
(_('Auth Info'), {'fields': (('ssh_username', 'ssh_password'),
|
||||
'ssh_key_data', 'ssh_key_unlock',
|
||||
('sudo_username', 'sudo_password'))}),
|
||||
#(_('Tags'), {'fields': ('tags',)}),
|
||||
(_('Audit Trail'), {'fields': ('created', 'created_by', 'audit_trail',)}),
|
||||
(_('Tags'), {'fields': ('tags',)}),
|
||||
(_('Audit'), {'fields': ('created', 'created_by',)}),
|
||||
)
|
||||
readonly_fields = ('created', 'created_by', 'audit_trail')
|
||||
filter_horizontal = ('tags',)
|
||||
readonly_fields = ('created', 'created_by')
|
||||
|
||||
class TeamAdmin(BaseModelAdmin):
|
||||
|
||||
list_display = ('name', 'description', 'active')
|
||||
filter_horizontal = ('projects', 'users', 'tags')
|
||||
filter_horizontal = ('projects', 'users')
|
||||
|
||||
class ProjectAdmin(BaseModelAdmin):
|
||||
|
||||
@ -205,11 +186,9 @@ class ProjectAdmin(BaseModelAdmin):
|
||||
(None, {'fields': (('name', 'active'), 'description', 'local_path',
|
||||
'get_playbooks_display')}),
|
||||
(_('Tags'), {'fields': ('tags',)}),
|
||||
(_('Audit Trail'), {'fields': ('created', 'created_by', 'audit_trail',)}),
|
||||
(_('Audit'), {'fields': ('created', 'created_by',)}),
|
||||
)
|
||||
readonly_fields = ('created', 'created_by', 'audit_trail',
|
||||
'get_playbooks_display')
|
||||
filter_horizontal = ('tags',)
|
||||
readonly_fields = ('created', 'created_by', 'get_playbooks_display')
|
||||
form = ProjectAdminForm
|
||||
|
||||
def get_playbooks_display(self, obj):
|
||||
@ -221,7 +200,6 @@ class ProjectAdmin(BaseModelAdmin):
|
||||
class PermissionAdmin(BaseModelAdmin):
|
||||
|
||||
list_display = ('name', 'description', 'active')
|
||||
filter_horizontal = ('tags',)
|
||||
|
||||
class JobTemplateAdmin(BaseModelAdmin):
|
||||
|
||||
@ -232,17 +210,15 @@ class JobTemplateAdmin(BaseModelAdmin):
|
||||
'get_create_link_display', 'get_jobs_link_display')}),
|
||||
(_('Job Parameters'), {'fields': ('inventory', 'project', 'playbook',
|
||||
'credential', 'job_type')}),
|
||||
(_('More Options'), {'fields': ('forks', 'limit',
|
||||
'verbosity', 'extra_vars'),
|
||||
(_('More Options'), {'fields': ('forks', 'limit', 'verbosity',
|
||||
'extra_vars', 'job_tags', 'host_config_key'),
|
||||
'classes': ('collapse',)}),
|
||||
#(_('Tags'), {'fields': ('tags',)}),
|
||||
(_('Audit Trail'), {'fields': ('created', 'created_by',
|
||||
'audit_trail',)}),
|
||||
(_('Tags'), {'fields': ('tags',)}),
|
||||
(_('Audit'), {'fields': ('created', 'created_by',)}),
|
||||
)
|
||||
readonly_fields = ('created', 'created_by', 'audit_trail',
|
||||
'get_create_link_display', 'get_jobs_link_display')
|
||||
readonly_fields = ('created', 'created_by', 'get_create_link_display',
|
||||
'get_jobs_link_display')
|
||||
form = JobTemplateAdminForm
|
||||
#filter_horizontal = ('tags',)
|
||||
|
||||
def get_create_link_display(self, obj):
|
||||
if not obj or not obj.pk:
|
||||
@ -272,6 +248,8 @@ class JobTemplateAdmin(BaseModelAdmin):
|
||||
create_opts['verbosity'] = obj.verbosity
|
||||
if obj.extra_vars:
|
||||
create_opts['extra_vars'] = obj.extra_vars
|
||||
if obj.job_tags:
|
||||
create_opts['job_tags'] = obj.job_tags
|
||||
create_url += '?%s' % urllib.urlencode(create_opts)
|
||||
return format_html('<a href="{0}">{1}</a>', create_url, 'Create Job')
|
||||
get_create_link_display.short_description = _('Create Job')
|
||||
@ -291,9 +269,9 @@ class JobTemplateAdmin(BaseModelAdmin):
|
||||
class JobHostSummaryInlineForJob(JobHostSummaryInline):
|
||||
|
||||
fields = ('host', 'changed', 'dark', 'failures', 'ok', 'processed',
|
||||
'skipped')
|
||||
'skipped', 'failed')
|
||||
readonly_fields = ('host', 'changed', 'dark', 'failures', 'ok',
|
||||
'processed', 'skipped')
|
||||
'processed', 'skipped', 'failed')
|
||||
|
||||
class JobEventInlineForJob(JobEventInline):
|
||||
|
||||
@ -310,13 +288,12 @@ class JobAdmin(BaseModelAdmin):
|
||||
(_('Job Parameters'), {'fields': ('inventory', 'project', 'playbook',
|
||||
'credential', 'job_type')}),
|
||||
(_('More Options'), {'fields': ('forks', 'limit', 'verbosity',
|
||||
'extra_vars'),
|
||||
'extra_vars', 'job_tags'),
|
||||
'classes': ('collapse',)}),
|
||||
(_('Start Job'), {'fields': ('start_job', 'ssh_password',
|
||||
'sudo_password', 'ssh_key_unlock')}),
|
||||
#(_('Tags'), {'fields': ('tags',)}),
|
||||
(_('Audit Trail'), {'fields': ('created', 'created_by',
|
||||
'audit_trail',)}),
|
||||
(_('Tags'), {'fields': ('tags',)}),
|
||||
(_('Audit'), {'fields': ('created', 'created_by',)}),
|
||||
(_('Job Status'), {'fields': (('status', 'failed', 'cancel_job'),
|
||||
'get_result_stdout_display',
|
||||
'get_result_traceback_display',
|
||||
@ -325,8 +302,7 @@ class JobAdmin(BaseModelAdmin):
|
||||
readonly_fields = ('status', 'failed', 'get_job_template_display',
|
||||
'get_result_stdout_display',
|
||||
'get_result_traceback_display', 'celery_task_id',
|
||||
'created', 'created_by', 'audit_trail',)
|
||||
filter_horizontal = ('tags',)
|
||||
'created', 'created_by')
|
||||
form = JobAdminForm
|
||||
inlines = [JobHostSummaryInlineForJob, JobEventInlineForJob]
|
||||
|
||||
@ -336,7 +312,7 @@ class JobAdmin(BaseModelAdmin):
|
||||
ro_fields.extend(['name', 'description', 'job_template',
|
||||
'inventory', 'project', 'playbook', 'credential',
|
||||
'job_type', 'forks', 'limit',
|
||||
'verbosity', 'extra_vars'])
|
||||
'verbosity', 'extra_vars', 'job_tags'])
|
||||
return ro_fields
|
||||
|
||||
def get_fieldsets(self, request, obj=None):
|
||||
@ -386,16 +362,13 @@ class JobAdmin(BaseModelAdmin):
|
||||
get_result_traceback_display.short_description = _('Traceback')
|
||||
get_result_traceback_display.allow_tags = True
|
||||
|
||||
|
||||
# FIXME: Add the rest of the models...
|
||||
|
||||
admin.site.register(Organization, OrganizationAdmin)
|
||||
admin.site.register(Inventory, InventoryAdmin)
|
||||
admin.site.register(Tag, TagAdmin)
|
||||
#admin.site.register(Tag, TagAdmin)
|
||||
#admin.site.register(AuditTrail, AuditTrailAdmin)
|
||||
admin.site.register(Host, HostAdmin)
|
||||
admin.site.register(Group, GroupAdmin)
|
||||
admin.site.register(VariableData, VariableDataAdmin)
|
||||
#admin.site.register(VariableData, VariableDataAdmin)
|
||||
admin.site.register(Team, TeamAdmin)
|
||||
admin.site.register(Project, ProjectAdmin)
|
||||
admin.site.register(Credential, CredentialAdmin)
|
||||
|
||||
@ -214,7 +214,7 @@ class BaseSubList(BaseList):
|
||||
class BaseDetail(generics.RetrieveUpdateDestroyAPIView):
|
||||
|
||||
def pre_save(self, obj):
|
||||
if type(obj) not in [ User, Tag, AuditTrail ]:
|
||||
if type(obj) not in [ User ]:
|
||||
obj.created_by = self.request.user
|
||||
|
||||
def destroy(self, request, *args, **kwargs):
|
||||
@ -247,73 +247,3 @@ class BaseDetail(generics.RetrieveUpdateDestroyAPIView):
|
||||
def put_filter(self, request, *args, **kwargs):
|
||||
''' scrub any fields the user cannot/should not put, based on user context. This runs after read-only serialization filtering '''
|
||||
pass
|
||||
|
||||
class VariableBaseDetail(BaseDetail):
|
||||
'''
|
||||
an object that is always 1 to 1 with the foreign key of another object
|
||||
and does not have it's own key, such as HostVariableDetail
|
||||
'''
|
||||
|
||||
def destroy(self, request, *args, **kwargs):
|
||||
raise PermissionDenied()
|
||||
|
||||
def put(self, request, *args, **kwargs):
|
||||
# FIXME: lots of overlap between put and get here, need to refactor
|
||||
|
||||
through_obj = self.__class__.parent_model.objects.get(pk=kwargs['pk'])
|
||||
|
||||
#has_permission = Inventory._has_permission_types(request.user, through_obj.inventory, PERMISSION_TYPES_ALLOWING_INVENTORY_WRITE)
|
||||
#if not has_permission:
|
||||
# raise PermissionDenied()
|
||||
if not check_user_access(request.user, Inventory, 'change', through_obj.inventory, None):
|
||||
raise PermissionDenied
|
||||
|
||||
this_object = None
|
||||
|
||||
if hasattr(request.DATA, 'dict'):
|
||||
data = request.DATA.dict()
|
||||
else:
|
||||
data = request.DATA
|
||||
|
||||
try:
|
||||
this_object = getattr(through_obj, self.__class__.reverse_relationship, None)
|
||||
except:
|
||||
pass
|
||||
|
||||
if this_object is None:
|
||||
this_object = self.__class__.model.objects.create(data=python_json.dumps(data))
|
||||
else:
|
||||
this_object.data = python_json.dumps(data)
|
||||
this_object.save()
|
||||
setattr(through_obj, self.__class__.reverse_relationship, this_object)
|
||||
through_obj.save()
|
||||
|
||||
return Response(status=status.HTTP_200_OK, data=python_json.loads(this_object.data))
|
||||
|
||||
|
||||
def get(self, request, *args, **kwargs):
|
||||
|
||||
# if null, recreate a blank object
|
||||
through_obj = self.__class__.parent_model.objects.get(pk=kwargs['pk'])
|
||||
this_object = None
|
||||
|
||||
try:
|
||||
this_object = getattr(through_obj, self.__class__.reverse_relationship, None)
|
||||
except Exception, e:
|
||||
pass
|
||||
|
||||
if this_object is None:
|
||||
new_args = {}
|
||||
new_args['data'] = python_json.dumps(dict())
|
||||
this_object = self.__class__.model.objects.create(**new_args)
|
||||
setattr(through_obj, self.__class__.reverse_relationship, this_object)
|
||||
through_obj.save()
|
||||
|
||||
#has_permission = Inventory._has_permission_types(request.user, through_obj.inventory, PERMISSION_TYPES_ALLOWING_INVENTORY_WRITE)
|
||||
#if not has_permission:
|
||||
# raise PermissionDenied()
|
||||
if not check_user_access(request.user, Inventory, 'read', through_obj.inventory):
|
||||
raise PermissionDenied
|
||||
|
||||
return Response(status=status.HTTP_200_OK, data=python_json.loads(this_object.data))
|
||||
|
||||
|
||||
@ -29,46 +29,6 @@ class PlaybookSelect(forms.Select):
|
||||
opt = opt.replace('">', '" class="project-%s">' % obj.project.pk)
|
||||
return opt
|
||||
|
||||
class HostAdminForm(forms.ModelForm):
|
||||
|
||||
class Meta:
|
||||
model = Host
|
||||
|
||||
vdata = JSONFormField(label=_('Variable data'), required=False, widget=forms.Textarea(attrs={'class': 'vLargeTextField'}))
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(HostAdminForm, self).__init__(*args, **kwargs)
|
||||
if self.instance.variable_data:
|
||||
print repr(self.instance.variable_data.data)
|
||||
self.initial['vdata'] = self.instance.variable_data.data
|
||||
|
||||
def save(self, commit=True):
|
||||
instance = super(HostAdminForm, self).save(commit=commit)
|
||||
save_m2m = getattr(self, 'save_m2m', lambda: None)
|
||||
vdata = self.cleaned_data.get('vdata', '')
|
||||
def new_save_m2m():
|
||||
save_m2m()
|
||||
if not instance.variable_data:
|
||||
instance.variable_data = VariableData.objects.create(data=vdata)
|
||||
instance.save()
|
||||
else:
|
||||
variable_data = instance.variable_data
|
||||
# FIXME!!!
|
||||
#variable_data.data = vdata
|
||||
#variable_data.save()
|
||||
if commit:
|
||||
new_save_m2m()
|
||||
else:
|
||||
self.save_m2m = new_save_m2m
|
||||
return instance
|
||||
|
||||
class GroupForm(forms.ModelForm):
|
||||
|
||||
class Meta:
|
||||
model = Host
|
||||
|
||||
variable_data = JSONFormField(required=False, widget=forms.Textarea(attrs={'class': 'vLargeTextField'}))
|
||||
|
||||
class ProjectAdminForm(forms.ModelForm):
|
||||
'''Custom admin form for Projects.'''
|
||||
|
||||
|
||||
@ -8,6 +8,7 @@ from optparse import make_option
|
||||
import os
|
||||
import sys
|
||||
from django.core.management.base import NoArgsCommand, CommandError
|
||||
from django.db import transaction
|
||||
|
||||
class Command(NoArgsCommand):
|
||||
'''
|
||||
@ -30,12 +31,13 @@ class Command(NoArgsCommand):
|
||||
help='JSON-formatted callback event data'),
|
||||
)
|
||||
|
||||
@transaction.commit_on_success
|
||||
def handle_noargs(self, **options):
|
||||
from ansibleworks.main.models import Job, JobEvent
|
||||
event_type = options.get('event_type', None)
|
||||
if not event_type:
|
||||
raise CommandError('No event specified')
|
||||
if event_type not in [x[0] for x in JobEvent.EVENT_TYPES]:
|
||||
if event_type not in [x[0] for x in JobEvent.EVENT_CHOICES]:
|
||||
raise CommandError('Unsupported event')
|
||||
event_data_file = options.get('event_data_file', None)
|
||||
event_data_json = options.get('event_data_json', None)
|
||||
|
||||
@ -32,8 +32,8 @@ class Command(NoArgsCommand):
|
||||
'hosts': list(group.hosts.values_list('name', flat=True)),
|
||||
'children': list(group.children.values_list('name', flat=True)),
|
||||
}
|
||||
if group.variable_data is not None:
|
||||
group_info['vars'] = json.loads(group.variable_data.data)
|
||||
if group.variables:
|
||||
group_info['vars'] = group.variables_dict
|
||||
|
||||
group_info = dict(filter(lambda x: bool(x[1]), group_info.items()))
|
||||
if group_info.keys() in ([], ['hosts']):
|
||||
@ -51,8 +51,8 @@ class Command(NoArgsCommand):
|
||||
except Host.DoesNotExist:
|
||||
raise CommandError('Host %s not found in the given inventory' % hostname)
|
||||
hostvars = {}
|
||||
if host.variable_data is not None:
|
||||
hostvars = json.loads(host.variable_data.data)
|
||||
if host.variables:
|
||||
hostvars = host.variables_dict
|
||||
self.stdout.write(json.dumps(hostvars, indent=indent))
|
||||
|
||||
def handle_noargs(self, **options):
|
||||
|
||||
664
ansibleworks/main/migrations/0002_v12b2_changes.py
Normal file
664
ansibleworks/main/migrations/0002_v12b2_changes.py
Normal file
@ -0,0 +1,664 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
import datetime
|
||||
from south.db import db
|
||||
from south.v2 import SchemaMigration
|
||||
from django.db import models
|
||||
|
||||
|
||||
class Migration(SchemaMigration):
|
||||
'''
|
||||
Schema migration for AnsibleWorks 1.2-b2 release.
|
||||
- Adds variables field on Host and Group models.
|
||||
- Adds job_tags and host_config_key fields on JobTemplate.
|
||||
- Adds job_tags, job_args, job_cwd, job_env fields on Job.
|
||||
- Adds failed field on JobHostSummary.
|
||||
- Adds play, task, parent and hosts fields on JobEvent.
|
||||
|
||||
NOTE: This migration has been manually edited!
|
||||
'''
|
||||
|
||||
def forwards(self, orm):
|
||||
|
||||
# Adding field 'Host.variables'
|
||||
db.add_column(u'main_host', 'variables',
|
||||
self.gf('django.db.models.fields.TextField')(default='', blank=True, null=True),
|
||||
keep_default=False)
|
||||
|
||||
# Adding field 'Group.variables'
|
||||
db.add_column(u'main_group', 'variables',
|
||||
self.gf('django.db.models.fields.TextField')(default='', blank=True, null=True),
|
||||
keep_default=False)
|
||||
|
||||
# Adding field 'JobTemplate.job_tags'
|
||||
db.add_column(u'main_jobtemplate', 'job_tags',
|
||||
self.gf('django.db.models.fields.CharField')(default='', max_length=1024, null=True, blank=True),
|
||||
keep_default=False)
|
||||
|
||||
# Adding field 'JobTemplate.host_config_key'
|
||||
db.add_column(u'main_jobtemplate', 'host_config_key',
|
||||
self.gf('django.db.models.fields.CharField')(default='', max_length=1024, blank=True, null=True),
|
||||
keep_default=False)
|
||||
|
||||
# Adding field 'Job.job_tags'
|
||||
db.add_column(u'main_job', 'job_tags',
|
||||
self.gf('django.db.models.fields.CharField')(default='', max_length=1024, null=True, blank=True),
|
||||
keep_default=False)
|
||||
|
||||
# Adding field 'Job.job_args'
|
||||
db.add_column(u'main_job', 'job_args',
|
||||
self.gf('django.db.models.fields.CharField')(default='', max_length=1024, null=True, blank=True),
|
||||
keep_default=False)
|
||||
|
||||
# Adding field 'Job.job_cwd'
|
||||
db.add_column(u'main_job', 'job_cwd',
|
||||
self.gf('django.db.models.fields.CharField')(default='', max_length=1024, null=True, blank=True),
|
||||
keep_default=False)
|
||||
|
||||
# Adding field 'Job.job_env'
|
||||
db.add_column(u'main_job', 'job_env',
|
||||
self.gf('jsonfield.fields.JSONField')(default={}, null=True, blank=True),
|
||||
keep_default=False)
|
||||
|
||||
# Adding field 'JobHostSummary.failed'
|
||||
db.add_column(u'main_jobhostsummary', 'failed',
|
||||
self.gf('django.db.models.fields.BooleanField')(default=False),
|
||||
keep_default=False)
|
||||
|
||||
# Adding field 'JobEvent.play'
|
||||
db.add_column(u'main_jobevent', 'play',
|
||||
self.gf('django.db.models.fields.CharField')(default='', max_length=1024, blank=True, null=True),
|
||||
keep_default=False)
|
||||
|
||||
# Adding field 'JobEvent.task'
|
||||
db.add_column(u'main_jobevent', 'task',
|
||||
self.gf('django.db.models.fields.CharField')(default='', max_length=1024, blank=True, null=True),
|
||||
keep_default=False)
|
||||
|
||||
# Adding field 'JobEvent.parent'
|
||||
db.add_column(u'main_jobevent', 'parent',
|
||||
self.gf('django.db.models.fields.related.ForeignKey')(related_name='children', on_delete=models.SET_NULL, default=None, to=orm['main.JobEvent'], blank=True, null=True),
|
||||
keep_default=False)
|
||||
|
||||
# Adding M2M table for field hosts on 'JobEvent'
|
||||
m2m_table_name = db.shorten_name(u'main_jobevent_hosts')
|
||||
db.create_table(m2m_table_name, (
|
||||
('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
|
||||
('jobevent', models.ForeignKey(orm['main.jobevent'], null=False)),
|
||||
('host', models.ForeignKey(orm['main.host'], null=False))
|
||||
))
|
||||
db.create_unique(m2m_table_name, ['jobevent_id', 'host_id'])
|
||||
|
||||
# Removing M2M table for field tags on 'Job'
|
||||
db.delete_table(db.shorten_name(u'main_job_tags'))
|
||||
|
||||
# Removing M2M table for field audit_trail on 'Job'
|
||||
db.delete_table(db.shorten_name(u'main_job_audit_trail'))
|
||||
|
||||
# Removing M2M table for field tags on 'Inventory'
|
||||
db.delete_table(db.shorten_name(u'main_inventory_tags'))
|
||||
|
||||
# Removing M2M table for field audit_trail on 'Inventory'
|
||||
db.delete_table(db.shorten_name(u'main_inventory_audit_trail'))
|
||||
|
||||
# Removing M2M table for field tags on 'Host'
|
||||
db.delete_table(db.shorten_name(u'main_host_tags'))
|
||||
|
||||
# Removing M2M table for field audit_trail on 'Host'
|
||||
db.delete_table(db.shorten_name(u'main_host_audit_trail'))
|
||||
|
||||
# Removing M2M table for field tags on 'Group'
|
||||
db.delete_table(db.shorten_name(u'main_group_tags'))
|
||||
|
||||
# Removing M2M table for field audit_trail on 'Group'
|
||||
db.delete_table(db.shorten_name(u'main_group_audit_trail'))
|
||||
|
||||
# Removing M2M table for field audit_trail on 'Credential'
|
||||
db.delete_table(db.shorten_name(u'main_credential_audit_trail'))
|
||||
|
||||
# Removing M2M table for field tags on 'Credential'
|
||||
db.delete_table(db.shorten_name(u'main_credential_tags'))
|
||||
|
||||
# Removing M2M table for field tags on 'JobTemplate'
|
||||
db.delete_table(db.shorten_name(u'main_jobtemplate_tags'))
|
||||
|
||||
# Removing M2M table for field audit_trail on 'JobTemplate'
|
||||
db.delete_table(db.shorten_name(u'main_jobtemplate_audit_trail'))
|
||||
|
||||
# Removing M2M table for field tags on 'Team'
|
||||
db.delete_table(db.shorten_name(u'main_team_tags'))
|
||||
|
||||
# Removing M2M table for field audit_trail on 'Team'
|
||||
db.delete_table(db.shorten_name(u'main_team_audit_trail'))
|
||||
|
||||
# Removing M2M table for field tags on 'Project'
|
||||
db.delete_table(db.shorten_name(u'main_project_tags'))
|
||||
|
||||
# Removing M2M table for field audit_trail on 'Project'
|
||||
db.delete_table(db.shorten_name(u'main_project_audit_trail'))
|
||||
|
||||
# Removing M2M table for field tags on 'Permission'
|
||||
db.delete_table(db.shorten_name(u'main_permission_tags'))
|
||||
|
||||
# Removing M2M table for field audit_trail on 'Permission'
|
||||
db.delete_table(db.shorten_name(u'main_permission_audit_trail'))
|
||||
|
||||
# Removing M2M table for field tags on 'VariableData'
|
||||
db.delete_table(db.shorten_name(u'main_variabledata_tags'))
|
||||
|
||||
# Removing M2M table for field audit_trail on 'VariableData'
|
||||
db.delete_table(db.shorten_name(u'main_variabledata_audit_trail'))
|
||||
|
||||
# Removing M2M table for field tags on 'Organization'
|
||||
db.delete_table(db.shorten_name(u'main_organization_tags'))
|
||||
|
||||
# Removing M2M table for field audit_trail on 'Organization'
|
||||
db.delete_table(db.shorten_name(u'main_organization_audit_trail'))
|
||||
|
||||
# Deleting model 'Tag'
|
||||
db.delete_table(u'main_tag')
|
||||
|
||||
# Deleting model 'AuditTrail'
|
||||
db.delete_table(u'main_audittrail')
|
||||
|
||||
def backwards(self, orm):
|
||||
|
||||
# Deleting field 'Host.variables'
|
||||
db.delete_column(u'main_host', 'variables')
|
||||
|
||||
# Deleting field 'Group.variables'
|
||||
db.delete_column(u'main_group', 'variables')
|
||||
|
||||
# Deleting field 'JobTemplate.job_tags'
|
||||
db.delete_column(u'main_jobtemplate', 'job_tags')
|
||||
|
||||
# Deleting field 'JobTemplate.host_config_key'
|
||||
db.delete_column(u'main_jobtemplate', 'host_config_key')
|
||||
|
||||
# Deleting field 'Job.job_tags'
|
||||
db.delete_column(u'main_job', 'job_tags')
|
||||
|
||||
# Deleting field 'Job.job_args'
|
||||
db.delete_column(u'main_job', 'job_args')
|
||||
|
||||
# Deleting field 'Job.job_cwd'
|
||||
db.delete_column(u'main_job', 'job_cwd')
|
||||
|
||||
# Deleting field 'Job.job_env'
|
||||
db.delete_column(u'main_job', 'job_env')
|
||||
|
||||
# Deleting field 'JobHostSummary.failed'
|
||||
db.delete_column(u'main_jobhostsummary', 'failed')
|
||||
|
||||
# Deleting field 'JobEvent.play'
|
||||
db.delete_column(u'main_jobevent', 'play')
|
||||
|
||||
# Deleting field 'JobEvent.task'
|
||||
db.delete_column(u'main_jobevent', 'task')
|
||||
|
||||
# Deleting field 'JobEvent.parent'
|
||||
db.delete_column(u'main_jobevent', 'parent_id')
|
||||
|
||||
# Removing M2M table for field hosts on 'JobEvent'
|
||||
db.delete_table(db.shorten_name(u'main_jobevent_hosts'))
|
||||
|
||||
# Adding model 'AuditTrail'
|
||||
db.create_table(u'main_audittrail', (
|
||||
('comment', self.gf('django.db.models.fields.TextField')()),
|
||||
('modified_by', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['auth.User'], null=True, on_delete=models.SET_NULL, blank=True)),
|
||||
('delta', self.gf('django.db.models.fields.TextField')()),
|
||||
('tag', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['main.Tag'], null=True, on_delete=models.SET_NULL, blank=True)),
|
||||
('detail', self.gf('django.db.models.fields.TextField')()),
|
||||
('resource_type', self.gf('django.db.models.fields.CharField')(max_length=64)),
|
||||
(u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
|
||||
))
|
||||
db.send_create_signal('main', ['AuditTrail'])
|
||||
|
||||
# Adding model 'Tag'
|
||||
db.create_table(u'main_tag', (
|
||||
(u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
|
||||
('name', self.gf('django.db.models.fields.CharField')(max_length=512)),
|
||||
))
|
||||
db.send_create_signal('main', ['Tag'])
|
||||
|
||||
# Adding M2M table for field tags on 'Job'
|
||||
m2m_table_name = db.shorten_name(u'main_job_tags')
|
||||
db.create_table(m2m_table_name, (
|
||||
('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
|
||||
('job', models.ForeignKey(orm['main.job'], null=False)),
|
||||
('tag', models.ForeignKey(orm['main.tag'], null=False))
|
||||
))
|
||||
db.create_unique(m2m_table_name, ['job_id', 'tag_id'])
|
||||
|
||||
# Adding M2M table for field audit_trail on 'Job'
|
||||
m2m_table_name = db.shorten_name(u'main_job_audit_trail')
|
||||
db.create_table(m2m_table_name, (
|
||||
('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
|
||||
('job', models.ForeignKey(orm['main.job'], null=False)),
|
||||
('audittrail', models.ForeignKey(orm['main.audittrail'], null=False))
|
||||
))
|
||||
db.create_unique(m2m_table_name, ['job_id', 'audittrail_id'])
|
||||
|
||||
# Adding M2M table for field tags on 'Inventory'
|
||||
m2m_table_name = db.shorten_name(u'main_inventory_tags')
|
||||
db.create_table(m2m_table_name, (
|
||||
('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
|
||||
('inventory', models.ForeignKey(orm['main.inventory'], null=False)),
|
||||
('tag', models.ForeignKey(orm['main.tag'], null=False))
|
||||
))
|
||||
db.create_unique(m2m_table_name, ['inventory_id', 'tag_id'])
|
||||
|
||||
# Adding M2M table for field audit_trail on 'Inventory'
|
||||
m2m_table_name = db.shorten_name(u'main_inventory_audit_trail')
|
||||
db.create_table(m2m_table_name, (
|
||||
('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
|
||||
('inventory', models.ForeignKey(orm['main.inventory'], null=False)),
|
||||
('audittrail', models.ForeignKey(orm['main.audittrail'], null=False))
|
||||
))
|
||||
db.create_unique(m2m_table_name, ['inventory_id', 'audittrail_id'])
|
||||
|
||||
# Adding M2M table for field tags on 'Host'
|
||||
m2m_table_name = db.shorten_name(u'main_host_tags')
|
||||
db.create_table(m2m_table_name, (
|
||||
('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
|
||||
('host', models.ForeignKey(orm['main.host'], null=False)),
|
||||
('tag', models.ForeignKey(orm['main.tag'], null=False))
|
||||
))
|
||||
db.create_unique(m2m_table_name, ['host_id', 'tag_id'])
|
||||
|
||||
# Adding M2M table for field audit_trail on 'Host'
|
||||
m2m_table_name = db.shorten_name(u'main_host_audit_trail')
|
||||
db.create_table(m2m_table_name, (
|
||||
('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
|
||||
('host', models.ForeignKey(orm['main.host'], null=False)),
|
||||
('audittrail', models.ForeignKey(orm['main.audittrail'], null=False))
|
||||
))
|
||||
db.create_unique(m2m_table_name, ['host_id', 'audittrail_id'])
|
||||
|
||||
# Adding M2M table for field tags on 'Group'
|
||||
m2m_table_name = db.shorten_name(u'main_group_tags')
|
||||
db.create_table(m2m_table_name, (
|
||||
('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
|
||||
('group', models.ForeignKey(orm['main.group'], null=False)),
|
||||
('tag', models.ForeignKey(orm['main.tag'], null=False))
|
||||
))
|
||||
db.create_unique(m2m_table_name, ['group_id', 'tag_id'])
|
||||
|
||||
# Adding M2M table for field audit_trail on 'Group'
|
||||
m2m_table_name = db.shorten_name(u'main_group_audit_trail')
|
||||
db.create_table(m2m_table_name, (
|
||||
('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
|
||||
('group', models.ForeignKey(orm['main.group'], null=False)),
|
||||
('audittrail', models.ForeignKey(orm['main.audittrail'], null=False))
|
||||
))
|
||||
db.create_unique(m2m_table_name, ['group_id', 'audittrail_id'])
|
||||
|
||||
# Adding M2M table for field audit_trail on 'Credential'
|
||||
m2m_table_name = db.shorten_name(u'main_credential_audit_trail')
|
||||
db.create_table(m2m_table_name, (
|
||||
('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
|
||||
('credential', models.ForeignKey(orm['main.credential'], null=False)),
|
||||
('audittrail', models.ForeignKey(orm['main.audittrail'], null=False))
|
||||
))
|
||||
db.create_unique(m2m_table_name, ['credential_id', 'audittrail_id'])
|
||||
|
||||
# Adding M2M table for field tags on 'Credential'
|
||||
m2m_table_name = db.shorten_name(u'main_credential_tags')
|
||||
db.create_table(m2m_table_name, (
|
||||
('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
|
||||
('credential', models.ForeignKey(orm['main.credential'], null=False)),
|
||||
('tag', models.ForeignKey(orm['main.tag'], null=False))
|
||||
))
|
||||
db.create_unique(m2m_table_name, ['credential_id', 'tag_id'])
|
||||
|
||||
# Adding M2M table for field tags on 'JobTemplate'
|
||||
m2m_table_name = db.shorten_name(u'main_jobtemplate_tags')
|
||||
db.create_table(m2m_table_name, (
|
||||
('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
|
||||
('jobtemplate', models.ForeignKey(orm['main.jobtemplate'], null=False)),
|
||||
('tag', models.ForeignKey(orm['main.tag'], null=False))
|
||||
))
|
||||
db.create_unique(m2m_table_name, ['jobtemplate_id', 'tag_id'])
|
||||
|
||||
# Adding M2M table for field audit_trail on 'JobTemplate'
|
||||
m2m_table_name = db.shorten_name(u'main_jobtemplate_audit_trail')
|
||||
db.create_table(m2m_table_name, (
|
||||
('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
|
||||
('jobtemplate', models.ForeignKey(orm['main.jobtemplate'], null=False)),
|
||||
('audittrail', models.ForeignKey(orm['main.audittrail'], null=False))
|
||||
))
|
||||
db.create_unique(m2m_table_name, ['jobtemplate_id', 'audittrail_id'])
|
||||
|
||||
# Adding M2M table for field tags on 'Team'
|
||||
m2m_table_name = db.shorten_name(u'main_team_tags')
|
||||
db.create_table(m2m_table_name, (
|
||||
('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
|
||||
('team', models.ForeignKey(orm['main.team'], null=False)),
|
||||
('tag', models.ForeignKey(orm['main.tag'], null=False))
|
||||
))
|
||||
db.create_unique(m2m_table_name, ['team_id', 'tag_id'])
|
||||
|
||||
# Adding M2M table for field audit_trail on 'Team'
|
||||
m2m_table_name = db.shorten_name(u'main_team_audit_trail')
|
||||
db.create_table(m2m_table_name, (
|
||||
('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
|
||||
('team', models.ForeignKey(orm['main.team'], null=False)),
|
||||
('audittrail', models.ForeignKey(orm['main.audittrail'], null=False))
|
||||
))
|
||||
db.create_unique(m2m_table_name, ['team_id', 'audittrail_id'])
|
||||
|
||||
# Adding M2M table for field tags on 'Project'
|
||||
m2m_table_name = db.shorten_name(u'main_project_tags')
|
||||
db.create_table(m2m_table_name, (
|
||||
('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
|
||||
('project', models.ForeignKey(orm[u'main.project'], null=False)),
|
||||
('tag', models.ForeignKey(orm['main.tag'], null=False))
|
||||
))
|
||||
db.create_unique(m2m_table_name, ['project_id', 'tag_id'])
|
||||
|
||||
# Adding M2M table for field audit_trail on 'Project'
|
||||
m2m_table_name = db.shorten_name(u'main_project_audit_trail')
|
||||
db.create_table(m2m_table_name, (
|
||||
('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
|
||||
('project', models.ForeignKey(orm[u'main.project'], null=False)),
|
||||
('audittrail', models.ForeignKey(orm['main.audittrail'], null=False))
|
||||
))
|
||||
db.create_unique(m2m_table_name, ['project_id', 'audittrail_id'])
|
||||
|
||||
# Adding M2M table for field tags on 'Permission'
|
||||
m2m_table_name = db.shorten_name(u'main_permission_tags')
|
||||
db.create_table(m2m_table_name, (
|
||||
('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
|
||||
('permission', models.ForeignKey(orm['main.permission'], null=False)),
|
||||
('tag', models.ForeignKey(orm['main.tag'], null=False))
|
||||
))
|
||||
db.create_unique(m2m_table_name, ['permission_id', 'tag_id'])
|
||||
|
||||
# Adding M2M table for field audit_trail on 'Permission'
|
||||
m2m_table_name = db.shorten_name(u'main_permission_audit_trail')
|
||||
db.create_table(m2m_table_name, (
|
||||
('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
|
||||
('permission', models.ForeignKey(orm['main.permission'], null=False)),
|
||||
('audittrail', models.ForeignKey(orm['main.audittrail'], null=False))
|
||||
))
|
||||
db.create_unique(m2m_table_name, ['permission_id', 'audittrail_id'])
|
||||
|
||||
# Adding M2M table for field tags on 'VariableData'
|
||||
m2m_table_name = db.shorten_name(u'main_variabledata_tags')
|
||||
db.create_table(m2m_table_name, (
|
||||
('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
|
||||
('variabledata', models.ForeignKey(orm['main.variabledata'], null=False)),
|
||||
('tag', models.ForeignKey(orm['main.tag'], null=False))
|
||||
))
|
||||
db.create_unique(m2m_table_name, ['variabledata_id', 'tag_id'])
|
||||
|
||||
# Adding M2M table for field audit_trail on 'VariableData'
|
||||
m2m_table_name = db.shorten_name(u'main_variabledata_audit_trail')
|
||||
db.create_table(m2m_table_name, (
|
||||
('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
|
||||
('variabledata', models.ForeignKey(orm['main.variabledata'], null=False)),
|
||||
('audittrail', models.ForeignKey(orm['main.audittrail'], null=False))
|
||||
))
|
||||
db.create_unique(m2m_table_name, ['variabledata_id', 'audittrail_id'])
|
||||
|
||||
# Adding M2M table for field tags on 'Organization'
|
||||
m2m_table_name = db.shorten_name(u'main_organization_tags')
|
||||
db.create_table(m2m_table_name, (
|
||||
('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
|
||||
('organization', models.ForeignKey(orm['main.organization'], null=False)),
|
||||
('tag', models.ForeignKey(orm['main.tag'], null=False))
|
||||
))
|
||||
db.create_unique(m2m_table_name, ['organization_id', 'tag_id'])
|
||||
|
||||
# Adding M2M table for field audit_trail on 'Organization'
|
||||
m2m_table_name = db.shorten_name(u'main_organization_audit_trail')
|
||||
db.create_table(m2m_table_name, (
|
||||
('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
|
||||
('organization', models.ForeignKey(orm['main.organization'], null=False)),
|
||||
('audittrail', models.ForeignKey(orm['main.audittrail'], null=False))
|
||||
))
|
||||
db.create_unique(m2m_table_name, ['organization_id', 'audittrail_id'])
|
||||
|
||||
|
||||
models = {
|
||||
u'auth.group': {
|
||||
'Meta': {'object_name': 'Group'},
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
|
||||
'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
|
||||
},
|
||||
u'auth.permission': {
|
||||
'Meta': {'ordering': "(u'content_type__app_label', u'content_type__model', u'codename')", 'unique_together': "((u'content_type', u'codename'),)", 'object_name': 'Permission'},
|
||||
'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
|
||||
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contenttypes.ContentType']"}),
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
|
||||
},
|
||||
u'auth.user': {
|
||||
'Meta': {'object_name': 'User'},
|
||||
'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
|
||||
'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
|
||||
'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
|
||||
'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
|
||||
'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||
'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||
'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
|
||||
'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
|
||||
'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
|
||||
'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
|
||||
'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
|
||||
},
|
||||
u'contenttypes.contenttype': {
|
||||
'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
|
||||
'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
|
||||
},
|
||||
'main.credential': {
|
||||
'Meta': {'object_name': 'Credential'},
|
||||
'active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
|
||||
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
|
||||
'created_by': ('django.db.models.fields.related.ForeignKey', [], {'related_name': '"{\'class\': \'credential\', \'app_label\': \'main\'}(class)s_created"', 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': u"orm['auth.User']"}),
|
||||
'description': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}),
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '512'}),
|
||||
'ssh_key_data': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}),
|
||||
'ssh_key_unlock': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '1024', 'blank': 'True'}),
|
||||
'ssh_password': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '1024', 'blank': 'True'}),
|
||||
'ssh_username': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '1024', 'blank': 'True'}),
|
||||
'sudo_password': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '1024', 'blank': 'True'}),
|
||||
'sudo_username': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '1024', 'blank': 'True'}),
|
||||
'team': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'credentials'", 'on_delete': 'models.SET_NULL', 'default': 'None', 'to': "orm['main.Team']", 'blank': 'True', 'null': 'True'}),
|
||||
'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'credentials'", 'on_delete': 'models.SET_NULL', 'default': 'None', 'to': u"orm['auth.User']", 'blank': 'True', 'null': 'True'})
|
||||
},
|
||||
'main.group': {
|
||||
'Meta': {'unique_together': "(('name', 'inventory'),)", 'object_name': 'Group'},
|
||||
'active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
|
||||
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
|
||||
'created_by': ('django.db.models.fields.related.ForeignKey', [], {'related_name': '"{\'class\': \'group\', \'app_label\': \'main\'}(class)s_created"', 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': u"orm['auth.User']"}),
|
||||
'description': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}),
|
||||
'hosts': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'groups'", 'blank': 'True', 'to': "orm['main.Host']"}),
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'inventory': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'groups'", 'to': "orm['main.Inventory']"}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '512'}),
|
||||
'parents': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'children'", 'blank': 'True', 'to': "orm['main.Group']"}),
|
||||
'variables': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True', 'null': 'True'}),
|
||||
'variable_data': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'group'", 'unique': 'True', 'on_delete': 'models.SET_NULL', 'default': 'None', 'to': "orm['main.VariableData']", 'blank': 'True', 'null': 'True'})
|
||||
},
|
||||
'main.host': {
|
||||
'Meta': {'unique_together': "(('name', 'inventory'),)", 'object_name': 'Host'},
|
||||
'active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
|
||||
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
|
||||
'created_by': ('django.db.models.fields.related.ForeignKey', [], {'related_name': '"{\'class\': \'host\', \'app_label\': \'main\'}(class)s_created"', 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': u"orm['auth.User']"}),
|
||||
'description': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}),
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'inventory': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'hosts'", 'to': "orm['main.Inventory']"}),
|
||||
'last_job': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'hosts_as_last_job+'", 'on_delete': 'models.SET_NULL', 'default': 'None', 'to': "orm['main.Job']", 'blank': 'True', 'null': 'True'}),
|
||||
'last_job_host_summary': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'hosts_as_last_job_summary+'", 'on_delete': 'models.SET_NULL', 'default': 'None', 'to': u"orm['main.JobHostSummary']", 'blank': 'True', 'null': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '512'}),
|
||||
'variables': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True', 'null': 'True'}),
|
||||
'variable_data': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'host'", 'unique': 'True', 'on_delete': 'models.SET_NULL', 'default': 'None', 'to': "orm['main.VariableData']", 'blank': 'True', 'null': 'True'})
|
||||
},
|
||||
'main.inventory': {
|
||||
'Meta': {'unique_together': "(('name', 'organization'),)", 'object_name': 'Inventory'},
|
||||
'active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
|
||||
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
|
||||
'created_by': ('django.db.models.fields.related.ForeignKey', [], {'related_name': '"{\'class\': \'inventory\', \'app_label\': \'main\'}(class)s_created"', 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': u"orm['auth.User']"}),
|
||||
'description': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}),
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '512'}),
|
||||
'organization': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'inventories'", 'to': "orm['main.Organization']"})
|
||||
},
|
||||
'main.job': {
|
||||
'Meta': {'object_name': 'Job'},
|
||||
'active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
|
||||
'cancel_flag': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||
'celery_task_id': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '100', 'blank': 'True'}),
|
||||
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
|
||||
'created_by': ('django.db.models.fields.related.ForeignKey', [], {'related_name': '"{\'class\': \'job\', \'app_label\': \'main\'}(class)s_created"', 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': u"orm['auth.User']"}),
|
||||
'credential': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'jobs'", 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': "orm['main.Credential']"}),
|
||||
'description': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}),
|
||||
'extra_vars': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}),
|
||||
'failed': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||
'forks': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0', 'blank': 'True'}),
|
||||
'hosts': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'jobs'", 'blank': 'True', 'through': u"orm['main.JobHostSummary']", 'to': "orm['main.Host']"}),
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'inventory': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'jobs'", 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': "orm['main.Inventory']"}),
|
||||
'job_args': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '1024', 'null': 'True', 'blank': 'True'}),
|
||||
'job_cwd': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '1024', 'null': 'True', 'blank': 'True'}),
|
||||
'job_env': ('jsonfield.fields.JSONField', [], {'default': '{}', 'null': 'True', 'blank': 'True'}),
|
||||
'job_tags': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '1024', 'null': 'True', 'blank': 'True'}),
|
||||
'job_template': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'jobs'", 'on_delete': 'models.SET_NULL', 'default': 'None', 'to': "orm['main.JobTemplate']", 'blank': 'True', 'null': 'True'}),
|
||||
'job_type': ('django.db.models.fields.CharField', [], {'max_length': '64'}),
|
||||
'limit': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '1024', 'blank': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '512'}),
|
||||
'playbook': ('django.db.models.fields.CharField', [], {'max_length': '1024'}),
|
||||
'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'jobs'", 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': u"orm['main.Project']"}),
|
||||
'result_stdout': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}),
|
||||
'result_traceback': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}),
|
||||
'status': ('django.db.models.fields.CharField', [], {'default': "'new'", 'max_length': '20'}),
|
||||
'verbosity': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0', 'blank': 'True'})
|
||||
},
|
||||
'main.jobevent': {
|
||||
'Meta': {'ordering': "('pk',)", 'object_name': 'JobEvent'},
|
||||
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
|
||||
'event': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
|
||||
'event_data': ('jsonfield.fields.JSONField', [], {'default': '{}', 'blank': 'True'}),
|
||||
'failed': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||
'host': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'job_events'", 'on_delete': 'models.SET_NULL', 'default': 'None', 'to': "orm['main.Host']", 'blank': 'True', 'null': 'True'}),
|
||||
'hosts': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'job_events'", 'blank': 'True', 'to': "orm['main.Host']"}),
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'job': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'job_events'", 'to': "orm['main.Job']"}),
|
||||
'parent': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'children'", 'on_delete': 'models.SET_NULL', 'default': 'None', 'to': "orm['main.JobEvent']", 'blank': 'True', 'null': 'True'}),
|
||||
'play': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '1024', 'blank': 'True', 'null': 'True'}),
|
||||
'task': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '1024', 'blank': 'True', 'null': 'True'})
|
||||
},
|
||||
u'main.jobhostsummary': {
|
||||
'Meta': {'ordering': "('-pk',)", 'unique_together': "[('job', 'host')]", 'object_name': 'JobHostSummary'},
|
||||
'changed': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}),
|
||||
'dark': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}),
|
||||
'failed': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||
'failures': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}),
|
||||
'host': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'job_host_summaries'", 'to': "orm['main.Host']"}),
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'job': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'job_host_summaries'", 'to': "orm['main.Job']"}),
|
||||
'ok': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}),
|
||||
'processed': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}),
|
||||
'skipped': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'})
|
||||
},
|
||||
'main.jobtemplate': {
|
||||
'Meta': {'object_name': 'JobTemplate'},
|
||||
'active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
|
||||
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
|
||||
'created_by': ('django.db.models.fields.related.ForeignKey', [], {'related_name': '"{\'class\': \'jobtemplate\', \'app_label\': \'main\'}(class)s_created"', 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': u"orm['auth.User']"}),
|
||||
'credential': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'job_templates'", 'on_delete': 'models.SET_NULL', 'default': 'None', 'to': "orm['main.Credential']", 'blank': 'True', 'null': 'True'}),
|
||||
'description': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}),
|
||||
'extra_vars': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}),
|
||||
'forks': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0', 'blank': 'True'}),
|
||||
'host_config_key': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '1024', 'blank': 'True', 'null': 'True'}),
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'inventory': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'job_templates'", 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': "orm['main.Inventory']"}),
|
||||
'job_tags': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '1024', 'null': 'True', 'blank': 'True'}),
|
||||
'job_type': ('django.db.models.fields.CharField', [], {'max_length': '64'}),
|
||||
'limit': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '1024', 'blank': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '512'}),
|
||||
'playbook': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '1024'}),
|
||||
'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'job_templates'", 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': u"orm['main.Project']"}),
|
||||
'verbosity': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0', 'blank': 'True'})
|
||||
},
|
||||
'main.organization': {
|
||||
'Meta': {'object_name': 'Organization'},
|
||||
'active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
|
||||
'admins': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'admin_of_organizations'", 'blank': 'True', 'to': u"orm['auth.User']"}),
|
||||
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
|
||||
'created_by': ('django.db.models.fields.related.ForeignKey', [], {'related_name': '"{\'class\': \'organization\', \'app_label\': \'main\'}(class)s_created"', 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': u"orm['auth.User']"}),
|
||||
'description': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}),
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '512'}),
|
||||
'projects': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'organizations'", 'blank': 'True', 'to': u"orm['main.Project']"}),
|
||||
'users': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'organizations'", 'blank': 'True', 'to': u"orm['auth.User']"})
|
||||
},
|
||||
'main.permission': {
|
||||
'Meta': {'object_name': 'Permission'},
|
||||
'active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
|
||||
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
|
||||
'created_by': ('django.db.models.fields.related.ForeignKey', [], {'related_name': '"{\'class\': \'permission\', \'app_label\': \'main\'}(class)s_created"', 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': u"orm['auth.User']"}),
|
||||
'description': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}),
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'inventory': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'permissions'", 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': "orm['main.Inventory']"}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '512'}),
|
||||
'permission_type': ('django.db.models.fields.CharField', [], {'max_length': '64'}),
|
||||
'project': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'permissions'", 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': u"orm['main.Project']"}),
|
||||
'team': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'permissions'", 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': "orm['main.Team']"}),
|
||||
'user': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'permissions'", 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': u"orm['auth.User']"})
|
||||
},
|
||||
u'main.project': {
|
||||
'Meta': {'object_name': 'Project'},
|
||||
'active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
|
||||
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
|
||||
'created_by': ('django.db.models.fields.related.ForeignKey', [], {'related_name': '"{\'class\': \'project\', \'app_label\': u\'main\'}(class)s_created"', 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': u"orm['auth.User']"}),
|
||||
'description': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}),
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'local_path': ('django.db.models.fields.CharField', [], {'max_length': '1024'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '512'})
|
||||
},
|
||||
'main.team': {
|
||||
'Meta': {'object_name': 'Team'},
|
||||
'active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
|
||||
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
|
||||
'created_by': ('django.db.models.fields.related.ForeignKey', [], {'related_name': '"{\'class\': \'team\', \'app_label\': \'main\'}(class)s_created"', 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': u"orm['auth.User']"}),
|
||||
'description': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}),
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '512'}),
|
||||
'organization': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'teams'", 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': "orm['main.Organization']"}),
|
||||
'projects': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'teams'", 'blank': 'True', 'to': u"orm['main.Project']"}),
|
||||
'users': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'teams'", 'blank': 'True', 'to': u"orm['auth.User']"})
|
||||
},
|
||||
'main.variabledata': {
|
||||
'Meta': {'object_name': 'VariableData'},
|
||||
'active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
|
||||
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
|
||||
'created_by': ('django.db.models.fields.related.ForeignKey', [], {'related_name': '"{\'class\': \'variabledata\', \'app_label\': \'main\'}(class)s_created"', 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': u"orm['auth.User']"}),
|
||||
'data': ('django.db.models.fields.TextField', [], {'default': "''"}),
|
||||
'description': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}),
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '512'})
|
||||
},
|
||||
u'taggit.tag': {
|
||||
'Meta': {'object_name': 'Tag'},
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '100'}),
|
||||
'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '100'})
|
||||
},
|
||||
u'taggit.taggeditem': {
|
||||
'Meta': {'object_name': 'TaggedItem'},
|
||||
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "u'taggit_taggeditem_tagged_items'", 'to': u"orm['contenttypes.ContentType']"}),
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'object_id': ('django.db.models.fields.IntegerField', [], {'db_index': 'True'}),
|
||||
'tag': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "u'taggit_taggeditem_items'", 'to': u"orm['taggit.Tag']"})
|
||||
}
|
||||
}
|
||||
|
||||
complete_apps = ['main']
|
||||
387
ansibleworks/main/migrations/0003_v12b2_changes.py
Normal file
387
ansibleworks/main/migrations/0003_v12b2_changes.py
Normal file
@ -0,0 +1,387 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
import datetime
|
||||
from south.db import db
|
||||
from south.v2 import DataMigration
|
||||
from django.db import models
|
||||
|
||||
|
||||
class Migration(DataMigration):
|
||||
'''
|
||||
Data migration for AnsibleWorks 1.2-b2 release.
|
||||
- Update variables from VariableData.data for Host and Group models.
|
||||
- Update new char/text field values to be empty string if they are null.
|
||||
- Update failed flag for existing JobHostSummary models.
|
||||
- Update parent field for existing JobEvent models.
|
||||
- Update hosts for existing JobEvent models.
|
||||
'''
|
||||
|
||||
def forwards(self, orm):
|
||||
|
||||
for host in orm.Host.objects.all():
|
||||
if host.variable_data:
|
||||
host.variables = host.variable_data.data
|
||||
else:
|
||||
host.variables = ''
|
||||
host.save()
|
||||
|
||||
for group in orm.Group.objects.all():
|
||||
if group.variable_data:
|
||||
group.variables = group.variable_data.data
|
||||
else:
|
||||
group.variables = ''
|
||||
group.save()
|
||||
|
||||
for job_template in orm.JobTemplate.objects.all():
|
||||
changed = False
|
||||
if job_template.host_config_key is None:
|
||||
job_template.host_config_key = ''
|
||||
changed = True
|
||||
if job_template.job_tags is None:
|
||||
job_template.job_tags = ''
|
||||
changed = True
|
||||
if changed:
|
||||
job_template.save()
|
||||
|
||||
for job in orm.Job.objects.all():
|
||||
changed = False
|
||||
if job.job_tags is None:
|
||||
job.job_tags = ''
|
||||
changed = True
|
||||
if job.job_args is None:
|
||||
job.job_args = ''
|
||||
changed = True
|
||||
if job.job_cwd is None:
|
||||
job.job_cwd = ''
|
||||
changed = True
|
||||
if job.job_env is None:
|
||||
job.job_env = ''
|
||||
changed = True
|
||||
if changed:
|
||||
job.save()
|
||||
|
||||
for job_host_summary in orm.JobHostSummary.objects.all():
|
||||
if job_host_summary.failures or job_host_summary.dark:
|
||||
job_host_summary.failed = True
|
||||
job_host_summary.save()
|
||||
|
||||
for job_event in orm.JobEvent.objects.all():
|
||||
job_event.play = job_event.event_data.get('play', '')
|
||||
job_event.task = job_event.event_data.get('task', '')
|
||||
job_event.parent = None
|
||||
parent_events = set()
|
||||
if job_event.event in ('playbook_on_play_start',
|
||||
'playbook_on_stats',
|
||||
'playbook_on_vars_prompt'):
|
||||
parent_events.add('playbook_on_start')
|
||||
elif job_event.event in ('playbook_on_notify', 'playbook_on_setup',
|
||||
'playbook_on_task_start',
|
||||
'playbook_on_no_hosts_matched',
|
||||
'playbook_on_no_hosts_remaining',
|
||||
'playbook_on_import_for_host',
|
||||
'playbook_on_not_import_for_host'):
|
||||
parent_events.add('playbook_on_play_start')
|
||||
elif job_event.event.startswith('runner_on_'):
|
||||
parent_events.add('playbook_on_setup')
|
||||
parent_events.add('playbook_on_task_start')
|
||||
if parent_events:
|
||||
try:
|
||||
qs = job_event.job.job_events.all()
|
||||
qs = qs.filter(pk__lt=job_event.pk,
|
||||
event__in=parent_events)
|
||||
job_event.parent = qs.order_by('-pk')[0]
|
||||
except IndexError:
|
||||
pass
|
||||
job_event.save()
|
||||
|
||||
def update_job_event_hosts(orm, job_event, extra_hosts=None):
|
||||
extra_hosts = extra_hosts or []
|
||||
hostnames = set()
|
||||
if job_event.event_data.get('host', ''):
|
||||
hostnames.add(job_event.event_data['host'])
|
||||
if job_event.event == 'playbook_on_stats':
|
||||
try:
|
||||
for v in job_event.event_data.values():
|
||||
hostnames.update(v.keys())
|
||||
except AttributeError:
|
||||
pass
|
||||
if job_event.host:
|
||||
job_event.hosts.add(job_event.host)
|
||||
for hostname in hostnames:
|
||||
try:
|
||||
host = job_event.job.inventory.hosts.get(name=hostname)
|
||||
except orm.Host.DoesNotExist:
|
||||
continue
|
||||
job_event.hosts.add(host)
|
||||
for host in extra_hosts:
|
||||
job_event.hosts.add(host)
|
||||
if job_event.parent:
|
||||
update_job_event_hosts(orm, job_event.parent,
|
||||
job_event.hosts.all())
|
||||
|
||||
for job_event in orm.JobEvent.objects.all():
|
||||
update_job_event_hosts(orm, job_event)
|
||||
|
||||
def backwards(self, orm):
|
||||
|
||||
for host in orm.Host.objects.all():
|
||||
if host.variable_data:
|
||||
variable_data = host.variable_data
|
||||
variable_data.data = host.variables
|
||||
variable_data.save()
|
||||
else:
|
||||
host.variable_data = orm.VariableData.objects.create(data=host.variables)
|
||||
host.save()
|
||||
|
||||
for group in orm.Group.objects.all():
|
||||
if group.variable_data:
|
||||
variable_data = group.variable_data
|
||||
variable_data.data = group.variables
|
||||
variable_data.save()
|
||||
else:
|
||||
group.variable_data = orm.VariableData.objects.create(data=group.variables)
|
||||
group.save()
|
||||
|
||||
models = {
|
||||
u'auth.group': {
|
||||
'Meta': {'object_name': 'Group'},
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
|
||||
'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
|
||||
},
|
||||
u'auth.permission': {
|
||||
'Meta': {'ordering': "(u'content_type__app_label', u'content_type__model', u'codename')", 'unique_together': "((u'content_type', u'codename'),)", 'object_name': 'Permission'},
|
||||
'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
|
||||
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contenttypes.ContentType']"}),
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
|
||||
},
|
||||
u'auth.user': {
|
||||
'Meta': {'object_name': 'User'},
|
||||
'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
|
||||
'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
|
||||
'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
|
||||
'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
|
||||
'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||
'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||
'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
|
||||
'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
|
||||
'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
|
||||
'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
|
||||
'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
|
||||
},
|
||||
u'contenttypes.contenttype': {
|
||||
'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
|
||||
'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
|
||||
},
|
||||
'main.credential': {
|
||||
'Meta': {'object_name': 'Credential'},
|
||||
'active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
|
||||
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
|
||||
'created_by': ('django.db.models.fields.related.ForeignKey', [], {'related_name': '"{\'class\': \'credential\', \'app_label\': \'main\'}(class)s_created"', 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': u"orm['auth.User']"}),
|
||||
'description': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}),
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '512'}),
|
||||
'ssh_key_data': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}),
|
||||
'ssh_key_unlock': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '1024', 'blank': 'True'}),
|
||||
'ssh_password': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '1024', 'blank': 'True'}),
|
||||
'ssh_username': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '1024', 'blank': 'True'}),
|
||||
'sudo_password': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '1024', 'blank': 'True'}),
|
||||
'sudo_username': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '1024', 'blank': 'True'}),
|
||||
'team': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'credentials'", 'on_delete': 'models.SET_NULL', 'default': 'None', 'to': "orm['main.Team']", 'blank': 'True', 'null': 'True'}),
|
||||
'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'credentials'", 'on_delete': 'models.SET_NULL', 'default': 'None', 'to': u"orm['auth.User']", 'blank': 'True', 'null': 'True'})
|
||||
},
|
||||
'main.group': {
|
||||
'Meta': {'unique_together': "(('name', 'inventory'),)", 'object_name': 'Group'},
|
||||
'active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
|
||||
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
|
||||
'created_by': ('django.db.models.fields.related.ForeignKey', [], {'related_name': '"{\'class\': \'group\', \'app_label\': \'main\'}(class)s_created"', 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': u"orm['auth.User']"}),
|
||||
'description': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}),
|
||||
'hosts': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'groups'", 'blank': 'True', 'to': "orm['main.Host']"}),
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'inventory': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'groups'", 'to': "orm['main.Inventory']"}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '512'}),
|
||||
'parents': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'children'", 'blank': 'True', 'to': "orm['main.Group']"}),
|
||||
'variable_data': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'group'", 'unique': 'True', 'on_delete': 'models.SET_NULL', 'default': 'None', 'to': "orm['main.VariableData']", 'blank': 'True', 'null': 'True'}),
|
||||
'variables': ('django.db.models.fields.TextField', [], {'default': "''", 'null': 'True', 'blank': 'True'})
|
||||
},
|
||||
'main.host': {
|
||||
'Meta': {'unique_together': "(('name', 'inventory'),)", 'object_name': 'Host'},
|
||||
'active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
|
||||
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
|
||||
'created_by': ('django.db.models.fields.related.ForeignKey', [], {'related_name': '"{\'class\': \'host\', \'app_label\': \'main\'}(class)s_created"', 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': u"orm['auth.User']"}),
|
||||
'description': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}),
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'inventory': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'hosts'", 'to': "orm['main.Inventory']"}),
|
||||
'last_job': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'hosts_as_last_job+'", 'on_delete': 'models.SET_NULL', 'default': 'None', 'to': "orm['main.Job']", 'blank': 'True', 'null': 'True'}),
|
||||
'last_job_host_summary': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'hosts_as_last_job_summary+'", 'on_delete': 'models.SET_NULL', 'default': 'None', 'to': u"orm['main.JobHostSummary']", 'blank': 'True', 'null': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '512'}),
|
||||
'variable_data': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'host'", 'unique': 'True', 'on_delete': 'models.SET_NULL', 'default': 'None', 'to': "orm['main.VariableData']", 'blank': 'True', 'null': 'True'}),
|
||||
'variables': ('django.db.models.fields.TextField', [], {'default': "''", 'null': 'True', 'blank': 'True'})
|
||||
},
|
||||
'main.inventory': {
|
||||
'Meta': {'unique_together': "(('name', 'organization'),)", 'object_name': 'Inventory'},
|
||||
'active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
|
||||
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
|
||||
'created_by': ('django.db.models.fields.related.ForeignKey', [], {'related_name': '"{\'class\': \'inventory\', \'app_label\': \'main\'}(class)s_created"', 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': u"orm['auth.User']"}),
|
||||
'description': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}),
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '512'}),
|
||||
'organization': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'inventories'", 'to': "orm['main.Organization']"})
|
||||
},
|
||||
'main.job': {
|
||||
'Meta': {'object_name': 'Job'},
|
||||
'active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
|
||||
'cancel_flag': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||
'celery_task_id': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '100', 'blank': 'True'}),
|
||||
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
|
||||
'created_by': ('django.db.models.fields.related.ForeignKey', [], {'related_name': '"{\'class\': \'job\', \'app_label\': \'main\'}(class)s_created"', 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': u"orm['auth.User']"}),
|
||||
'credential': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'jobs'", 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': "orm['main.Credential']"}),
|
||||
'description': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}),
|
||||
'extra_vars': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}),
|
||||
'failed': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||
'forks': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0', 'blank': 'True'}),
|
||||
'hosts': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'jobs'", 'blank': 'True', 'through': u"orm['main.JobHostSummary']", 'to': "orm['main.Host']"}),
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'inventory': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'jobs'", 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': "orm['main.Inventory']"}),
|
||||
'job_args': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '1024', 'null': 'True', 'blank': 'True'}),
|
||||
'job_cwd': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '1024', 'null': 'True', 'blank': 'True'}),
|
||||
'job_env': ('jsonfield.fields.JSONField', [], {'default': '{}', 'null': 'True', 'blank': 'True'}),
|
||||
'job_tags': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '1024', 'null': 'True', 'blank': 'True'}),
|
||||
'job_template': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'jobs'", 'on_delete': 'models.SET_NULL', 'default': 'None', 'to': "orm['main.JobTemplate']", 'blank': 'True', 'null': 'True'}),
|
||||
'job_type': ('django.db.models.fields.CharField', [], {'max_length': '64'}),
|
||||
'limit': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '1024', 'blank': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '512'}),
|
||||
'playbook': ('django.db.models.fields.CharField', [], {'max_length': '1024'}),
|
||||
'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'jobs'", 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': u"orm['main.Project']"}),
|
||||
'result_stdout': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}),
|
||||
'result_traceback': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}),
|
||||
'status': ('django.db.models.fields.CharField', [], {'default': "'new'", 'max_length': '20'}),
|
||||
'verbosity': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0', 'blank': 'True'})
|
||||
},
|
||||
'main.jobevent': {
|
||||
'Meta': {'ordering': "('pk',)", 'object_name': 'JobEvent'},
|
||||
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
|
||||
'event': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
|
||||
'event_data': ('jsonfield.fields.JSONField', [], {'default': '{}', 'blank': 'True'}),
|
||||
'failed': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||
'host': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'job_events'", 'on_delete': 'models.SET_NULL', 'default': 'None', 'to': "orm['main.Host']", 'blank': 'True', 'null': 'True'}),
|
||||
'hosts': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'job_events'", 'blank': 'True', 'to': "orm['main.Host']"}),
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'job': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'job_events'", 'to': "orm['main.Job']"}),
|
||||
'parent': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'children'", 'on_delete': 'models.SET_NULL', 'default': 'None', 'to': "orm['main.JobEvent']", 'blank': 'True', 'null': 'True'}),
|
||||
'play': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '1024', 'null': 'True', 'blank': 'True'}),
|
||||
'task': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '1024', 'null': 'True', 'blank': 'True'})
|
||||
},
|
||||
u'main.jobhostsummary': {
|
||||
'Meta': {'ordering': "('-pk',)", 'unique_together': "[('job', 'host')]", 'object_name': 'JobHostSummary'},
|
||||
'changed': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}),
|
||||
'dark': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}),
|
||||
'failed': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||
'failures': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}),
|
||||
'host': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'job_host_summaries'", 'to': "orm['main.Host']"}),
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'job': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'job_host_summaries'", 'to': "orm['main.Job']"}),
|
||||
'ok': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}),
|
||||
'processed': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}),
|
||||
'skipped': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'})
|
||||
},
|
||||
'main.jobtemplate': {
|
||||
'Meta': {'object_name': 'JobTemplate'},
|
||||
'active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
|
||||
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
|
||||
'created_by': ('django.db.models.fields.related.ForeignKey', [], {'related_name': '"{\'class\': \'jobtemplate\', \'app_label\': \'main\'}(class)s_created"', 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': u"orm['auth.User']"}),
|
||||
'credential': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'job_templates'", 'on_delete': 'models.SET_NULL', 'default': 'None', 'to': "orm['main.Credential']", 'blank': 'True', 'null': 'True'}),
|
||||
'description': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}),
|
||||
'extra_vars': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}),
|
||||
'forks': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0', 'blank': 'True'}),
|
||||
'host_config_key': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '1024', 'null': 'True', 'blank': 'True'}),
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'inventory': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'job_templates'", 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': "orm['main.Inventory']"}),
|
||||
'job_tags': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '1024', 'null': 'True', 'blank': 'True'}),
|
||||
'job_type': ('django.db.models.fields.CharField', [], {'max_length': '64'}),
|
||||
'limit': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '1024', 'blank': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '512'}),
|
||||
'playbook': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '1024'}),
|
||||
'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'job_templates'", 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': u"orm['main.Project']"}),
|
||||
'verbosity': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0', 'blank': 'True'})
|
||||
},
|
||||
'main.organization': {
|
||||
'Meta': {'object_name': 'Organization'},
|
||||
'active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
|
||||
'admins': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'admin_of_organizations'", 'blank': 'True', 'to': u"orm['auth.User']"}),
|
||||
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
|
||||
'created_by': ('django.db.models.fields.related.ForeignKey', [], {'related_name': '"{\'class\': \'organization\', \'app_label\': \'main\'}(class)s_created"', 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': u"orm['auth.User']"}),
|
||||
'description': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}),
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '512'}),
|
||||
'projects': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'organizations'", 'blank': 'True', 'to': u"orm['main.Project']"}),
|
||||
'users': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'organizations'", 'blank': 'True', 'to': u"orm['auth.User']"})
|
||||
},
|
||||
'main.permission': {
|
||||
'Meta': {'object_name': 'Permission'},
|
||||
'active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
|
||||
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
|
||||
'created_by': ('django.db.models.fields.related.ForeignKey', [], {'related_name': '"{\'class\': \'permission\', \'app_label\': \'main\'}(class)s_created"', 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': u"orm['auth.User']"}),
|
||||
'description': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}),
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'inventory': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'permissions'", 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': "orm['main.Inventory']"}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '512'}),
|
||||
'permission_type': ('django.db.models.fields.CharField', [], {'max_length': '64'}),
|
||||
'project': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'permissions'", 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': u"orm['main.Project']"}),
|
||||
'team': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'permissions'", 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': "orm['main.Team']"}),
|
||||
'user': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'permissions'", 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': u"orm['auth.User']"})
|
||||
},
|
||||
u'main.project': {
|
||||
'Meta': {'object_name': 'Project'},
|
||||
'active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
|
||||
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
|
||||
'created_by': ('django.db.models.fields.related.ForeignKey', [], {'related_name': '"{\'class\': \'project\', \'app_label\': u\'main\'}(class)s_created"', 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': u"orm['auth.User']"}),
|
||||
'description': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}),
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'local_path': ('django.db.models.fields.CharField', [], {'max_length': '1024'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '512'})
|
||||
},
|
||||
'main.team': {
|
||||
'Meta': {'object_name': 'Team'},
|
||||
'active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
|
||||
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
|
||||
'created_by': ('django.db.models.fields.related.ForeignKey', [], {'related_name': '"{\'class\': \'team\', \'app_label\': \'main\'}(class)s_created"', 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': u"orm['auth.User']"}),
|
||||
'description': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}),
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '512'}),
|
||||
'organization': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'teams'", 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': "orm['main.Organization']"}),
|
||||
'projects': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'teams'", 'blank': 'True', 'to': u"orm['main.Project']"}),
|
||||
'users': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'teams'", 'blank': 'True', 'to': u"orm['auth.User']"})
|
||||
},
|
||||
'main.variabledata': {
|
||||
'Meta': {'object_name': 'VariableData'},
|
||||
'active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
|
||||
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
|
||||
'created_by': ('django.db.models.fields.related.ForeignKey', [], {'related_name': '"{\'class\': \'variabledata\', \'app_label\': \'main\'}(class)s_created"', 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': u"orm['auth.User']"}),
|
||||
'data': ('django.db.models.fields.TextField', [], {'default': "''"}),
|
||||
'description': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}),
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '512'})
|
||||
},
|
||||
u'taggit.tag': {
|
||||
'Meta': {'object_name': 'Tag'},
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '100'}),
|
||||
'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '100'})
|
||||
},
|
||||
u'taggit.taggeditem': {
|
||||
'Meta': {'object_name': 'TaggedItem'},
|
||||
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "u'taggit_taggeditem_tagged_items'", 'to': u"orm['contenttypes.ContentType']"}),
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'object_id': ('django.db.models.fields.IntegerField', [], {'db_index': 'True'}),
|
||||
'tag': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "u'taggit_taggeditem_items'", 'to': u"orm['taggit.Tag']"})
|
||||
}
|
||||
}
|
||||
|
||||
complete_apps = ['main']
|
||||
symmetrical = True
|
||||
343
ansibleworks/main/migrations/0004_v12b2_changes.py
Normal file
343
ansibleworks/main/migrations/0004_v12b2_changes.py
Normal file
@ -0,0 +1,343 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
import datetime
|
||||
from south.db import db
|
||||
from south.v2 import SchemaMigration
|
||||
from django.db import models
|
||||
|
||||
|
||||
class Migration(SchemaMigration):
|
||||
'''
|
||||
Schema migration for AnsibleWorks 1.2-b2 release.
|
||||
- Remove variable_data field on Host and Group models.
|
||||
- Remove VariableData model.
|
||||
- Remove null=True on new char fields previously added.
|
||||
|
||||
NOTE: This migration has been manually edited!
|
||||
'''
|
||||
|
||||
def forwards(self, orm):
|
||||
|
||||
# Changing field 'Job.job_cwd'
|
||||
db.alter_column(u'main_job', 'job_cwd', self.gf('django.db.models.fields.CharField')(max_length=1024))
|
||||
|
||||
# Changing field 'Job.job_tags'
|
||||
db.alter_column(u'main_job', 'job_tags', self.gf('django.db.models.fields.CharField')(max_length=1024))
|
||||
|
||||
# Changing field 'Job.job_env'
|
||||
db.alter_column(u'main_job', 'job_env', self.gf('jsonfield.fields.JSONField')())
|
||||
|
||||
# Changing field 'Job.job_args'
|
||||
db.alter_column(u'main_job', 'job_args', self.gf('django.db.models.fields.CharField')(max_length=1024))
|
||||
|
||||
# Deleting field 'Host.variable_data'
|
||||
db.delete_column(u'main_host', 'variable_data_id')
|
||||
|
||||
# Changing field 'Host.variables'
|
||||
db.alter_column(u'main_host', 'variables', self.gf('django.db.models.fields.TextField')())
|
||||
|
||||
# Deleting field 'Group.variable_data'
|
||||
db.delete_column(u'main_group', 'variable_data_id')
|
||||
|
||||
# Changing field 'Group.variables'
|
||||
db.alter_column(u'main_group', 'variables', self.gf('django.db.models.fields.TextField')())
|
||||
|
||||
# Changing field 'JobTemplate.job_tags'
|
||||
db.alter_column(u'main_jobtemplate', 'job_tags', self.gf('django.db.models.fields.CharField')(max_length=1024))
|
||||
|
||||
# Changing field 'JobTemplate.host_config_key'
|
||||
db.alter_column(u'main_jobtemplate', 'host_config_key', self.gf('django.db.models.fields.CharField')(max_length=1024))
|
||||
|
||||
# Changing field 'JobEvent.play'
|
||||
db.alter_column(u'main_jobevent', 'play', self.gf('django.db.models.fields.CharField')(max_length=1024))
|
||||
|
||||
# Changing field 'JobEvent.task'
|
||||
db.alter_column(u'main_jobevent', 'task', self.gf('django.db.models.fields.CharField')(max_length=1024))
|
||||
|
||||
# Deleting model 'VariableData'
|
||||
db.delete_table(u'main_variabledata')
|
||||
|
||||
def backwards(self, orm):
|
||||
|
||||
# Adding model 'VariableData'
|
||||
db.create_table(u'main_variabledata', (
|
||||
('description', self.gf('django.db.models.fields.TextField')(default='', blank=True)),
|
||||
('created', self.gf('django.db.models.fields.DateTimeField')(auto_now_add=True, blank=True)),
|
||||
('active', self.gf('django.db.models.fields.BooleanField')(default=True)),
|
||||
('data', self.gf('django.db.models.fields.TextField')(default='')),
|
||||
(u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
|
||||
('created_by', self.gf('django.db.models.fields.related.ForeignKey')(related_name="{'class': 'variabledata', 'app_label': 'main'}(class)s_created", null=True, on_delete=models.SET_NULL, to=orm['auth.User'])),
|
||||
('name', self.gf('django.db.models.fields.CharField')(max_length=512)),
|
||||
))
|
||||
db.send_create_signal('main', ['VariableData'])
|
||||
|
||||
# Changing field 'Job.job_cwd'
|
||||
db.alter_column(u'main_job', 'job_cwd', self.gf('django.db.models.fields.CharField')(max_length=1024, null=True))
|
||||
|
||||
# Changing field 'Job.job_tags'
|
||||
db.alter_column(u'main_job', 'job_tags', self.gf('django.db.models.fields.CharField')(max_length=1024, null=True))
|
||||
|
||||
# Changing field 'Job.job_env'
|
||||
db.alter_column(u'main_job', 'job_env', self.gf('jsonfield.fields.JSONField')(null=True))
|
||||
|
||||
# Changing field 'Job.job_args'
|
||||
db.alter_column(u'main_job', 'job_args', self.gf('django.db.models.fields.CharField')(max_length=1024, null=True))
|
||||
|
||||
# Adding field 'Host.variable_data'
|
||||
db.add_column(u'main_host', 'variable_data',
|
||||
self.gf('django.db.models.fields.related.OneToOneField')(related_name='host', null=True, on_delete=models.SET_NULL, default=None, to=orm['main.VariableData'], blank=True, unique=True),
|
||||
keep_default=False)
|
||||
|
||||
# Changing field 'Host.variables'
|
||||
db.alter_column(u'main_host', 'variables', self.gf('django.db.models.fields.TextField')(null=True))
|
||||
|
||||
# Adding field 'Group.variable_data'
|
||||
db.add_column(u'main_group', 'variable_data',
|
||||
self.gf('django.db.models.fields.related.OneToOneField')(related_name='group', null=True, on_delete=models.SET_NULL, default=None, to=orm['main.VariableData'], blank=True, unique=True),
|
||||
keep_default=False)
|
||||
|
||||
# Changing field 'Group.variables'
|
||||
db.alter_column(u'main_group', 'variables', self.gf('django.db.models.fields.TextField')(null=True))
|
||||
|
||||
# Changing field 'JobTemplate.job_tags'
|
||||
db.alter_column(u'main_jobtemplate', 'job_tags', self.gf('django.db.models.fields.CharField')(max_length=1024, null=True))
|
||||
|
||||
# Changing field 'JobTemplate.host_config_key'
|
||||
db.alter_column(u'main_jobtemplate', 'host_config_key', self.gf('django.db.models.fields.CharField')(max_length=1024, null=True))
|
||||
|
||||
# Changing field 'JobEvent.play'
|
||||
db.alter_column(u'main_jobevent', 'play', self.gf('django.db.models.fields.CharField')(max_length=1024, null=True))
|
||||
|
||||
# Changing field 'JobEvent.task'
|
||||
db.alter_column(u'main_jobevent', 'task', self.gf('django.db.models.fields.CharField')(max_length=1024, null=True))
|
||||
|
||||
models = {
|
||||
u'auth.group': {
|
||||
'Meta': {'object_name': 'Group'},
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
|
||||
'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
|
||||
},
|
||||
u'auth.permission': {
|
||||
'Meta': {'ordering': "(u'content_type__app_label', u'content_type__model', u'codename')", 'unique_together': "((u'content_type', u'codename'),)", 'object_name': 'Permission'},
|
||||
'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
|
||||
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contenttypes.ContentType']"}),
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
|
||||
},
|
||||
u'auth.user': {
|
||||
'Meta': {'object_name': 'User'},
|
||||
'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
|
||||
'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
|
||||
'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
|
||||
'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
|
||||
'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||
'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||
'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
|
||||
'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
|
||||
'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
|
||||
'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
|
||||
'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
|
||||
},
|
||||
u'contenttypes.contenttype': {
|
||||
'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
|
||||
'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
|
||||
},
|
||||
'main.credential': {
|
||||
'Meta': {'object_name': 'Credential'},
|
||||
'active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
|
||||
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
|
||||
'created_by': ('django.db.models.fields.related.ForeignKey', [], {'related_name': '"{\'class\': \'credential\', \'app_label\': \'main\'}(class)s_created"', 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': u"orm['auth.User']"}),
|
||||
'description': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}),
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '512'}),
|
||||
'ssh_key_data': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}),
|
||||
'ssh_key_unlock': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '1024', 'blank': 'True'}),
|
||||
'ssh_password': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '1024', 'blank': 'True'}),
|
||||
'ssh_username': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '1024', 'blank': 'True'}),
|
||||
'sudo_password': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '1024', 'blank': 'True'}),
|
||||
'sudo_username': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '1024', 'blank': 'True'}),
|
||||
'team': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'credentials'", 'on_delete': 'models.SET_NULL', 'default': 'None', 'to': "orm['main.Team']", 'blank': 'True', 'null': 'True'}),
|
||||
'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'credentials'", 'on_delete': 'models.SET_NULL', 'default': 'None', 'to': u"orm['auth.User']", 'blank': 'True', 'null': 'True'})
|
||||
},
|
||||
'main.group': {
|
||||
'Meta': {'unique_together': "(('name', 'inventory'),)", 'object_name': 'Group'},
|
||||
'active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
|
||||
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
|
||||
'created_by': ('django.db.models.fields.related.ForeignKey', [], {'related_name': '"{\'class\': \'group\', \'app_label\': \'main\'}(class)s_created"', 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': u"orm['auth.User']"}),
|
||||
'description': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}),
|
||||
'hosts': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'groups'", 'blank': 'True', 'to': "orm['main.Host']"}),
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'inventory': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'groups'", 'to': "orm['main.Inventory']"}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '512'}),
|
||||
'parents': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'children'", 'blank': 'True', 'to': "orm['main.Group']"}),
|
||||
'variables': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'})
|
||||
},
|
||||
'main.host': {
|
||||
'Meta': {'unique_together': "(('name', 'inventory'),)", 'object_name': 'Host'},
|
||||
'active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
|
||||
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
|
||||
'created_by': ('django.db.models.fields.related.ForeignKey', [], {'related_name': '"{\'class\': \'host\', \'app_label\': \'main\'}(class)s_created"', 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': u"orm['auth.User']"}),
|
||||
'description': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}),
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'inventory': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'hosts'", 'to': "orm['main.Inventory']"}),
|
||||
'last_job': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'hosts_as_last_job+'", 'on_delete': 'models.SET_NULL', 'default': 'None', 'to': "orm['main.Job']", 'blank': 'True', 'null': 'True'}),
|
||||
'last_job_host_summary': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'hosts_as_last_job_summary+'", 'on_delete': 'models.SET_NULL', 'default': 'None', 'to': u"orm['main.JobHostSummary']", 'blank': 'True', 'null': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '512'}),
|
||||
'variables': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'})
|
||||
},
|
||||
'main.inventory': {
|
||||
'Meta': {'unique_together': "(('name', 'organization'),)", 'object_name': 'Inventory'},
|
||||
'active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
|
||||
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
|
||||
'created_by': ('django.db.models.fields.related.ForeignKey', [], {'related_name': '"{\'class\': \'inventory\', \'app_label\': \'main\'}(class)s_created"', 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': u"orm['auth.User']"}),
|
||||
'description': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}),
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '512'}),
|
||||
'organization': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'inventories'", 'to': "orm['main.Organization']"})
|
||||
},
|
||||
'main.job': {
|
||||
'Meta': {'object_name': 'Job'},
|
||||
'active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
|
||||
'cancel_flag': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||
'celery_task_id': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '100', 'blank': 'True'}),
|
||||
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
|
||||
'created_by': ('django.db.models.fields.related.ForeignKey', [], {'related_name': '"{\'class\': \'job\', \'app_label\': \'main\'}(class)s_created"', 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': u"orm['auth.User']"}),
|
||||
'credential': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'jobs'", 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': "orm['main.Credential']"}),
|
||||
'description': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}),
|
||||
'extra_vars': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}),
|
||||
'failed': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||
'forks': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0', 'blank': 'True'}),
|
||||
'hosts': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'jobs'", 'blank': 'True', 'through': u"orm['main.JobHostSummary']", 'to': "orm['main.Host']"}),
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'inventory': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'jobs'", 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': "orm['main.Inventory']"}),
|
||||
'job_args': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '1024', 'blank': 'True'}),
|
||||
'job_cwd': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '1024', 'blank': 'True'}),
|
||||
'job_env': ('jsonfield.fields.JSONField', [], {'default': '{}', 'blank': 'True'}),
|
||||
'job_tags': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '1024', 'blank': 'True'}),
|
||||
'job_template': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'jobs'", 'on_delete': 'models.SET_NULL', 'default': 'None', 'to': "orm['main.JobTemplate']", 'blank': 'True', 'null': 'True'}),
|
||||
'job_type': ('django.db.models.fields.CharField', [], {'max_length': '64'}),
|
||||
'limit': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '1024', 'blank': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '512'}),
|
||||
'playbook': ('django.db.models.fields.CharField', [], {'max_length': '1024'}),
|
||||
'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'jobs'", 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': u"orm['main.Project']"}),
|
||||
'result_stdout': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}),
|
||||
'result_traceback': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}),
|
||||
'status': ('django.db.models.fields.CharField', [], {'default': "'new'", 'max_length': '20'}),
|
||||
'verbosity': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0', 'blank': 'True'})
|
||||
},
|
||||
'main.jobevent': {
|
||||
'Meta': {'ordering': "('pk',)", 'object_name': 'JobEvent'},
|
||||
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
|
||||
'event': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
|
||||
'event_data': ('jsonfield.fields.JSONField', [], {'default': '{}', 'blank': 'True'}),
|
||||
'failed': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||
'host': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'job_events_as_primary_host'", 'on_delete': 'models.SET_NULL', 'default': 'None', 'to': "orm['main.Host']", 'blank': 'True', 'null': 'True'}),
|
||||
'hosts': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'job_events'", 'blank': 'True', 'to': "orm['main.Host']"}),
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'job': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'job_events'", 'to': "orm['main.Job']"}),
|
||||
'parent': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'children'", 'on_delete': 'models.SET_NULL', 'default': 'None', 'to': "orm['main.JobEvent']", 'blank': 'True', 'null': 'True'}),
|
||||
'play': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '1024', 'blank': 'True'}),
|
||||
'task': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '1024', 'blank': 'True'})
|
||||
},
|
||||
u'main.jobhostsummary': {
|
||||
'Meta': {'ordering': "('-pk',)", 'unique_together': "[('job', 'host')]", 'object_name': 'JobHostSummary'},
|
||||
'changed': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}),
|
||||
'dark': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}),
|
||||
'failed': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||
'failures': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}),
|
||||
'host': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'job_host_summaries'", 'to': "orm['main.Host']"}),
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'job': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'job_host_summaries'", 'to': "orm['main.Job']"}),
|
||||
'ok': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}),
|
||||
'processed': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}),
|
||||
'skipped': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'})
|
||||
},
|
||||
'main.jobtemplate': {
|
||||
'Meta': {'object_name': 'JobTemplate'},
|
||||
'active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
|
||||
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
|
||||
'created_by': ('django.db.models.fields.related.ForeignKey', [], {'related_name': '"{\'class\': \'jobtemplate\', \'app_label\': \'main\'}(class)s_created"', 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': u"orm['auth.User']"}),
|
||||
'credential': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'job_templates'", 'on_delete': 'models.SET_NULL', 'default': 'None', 'to': "orm['main.Credential']", 'blank': 'True', 'null': 'True'}),
|
||||
'description': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}),
|
||||
'extra_vars': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}),
|
||||
'forks': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0', 'blank': 'True'}),
|
||||
'host_config_key': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '1024', 'blank': 'True'}),
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'inventory': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'job_templates'", 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': "orm['main.Inventory']"}),
|
||||
'job_tags': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '1024', 'blank': 'True'}),
|
||||
'job_type': ('django.db.models.fields.CharField', [], {'max_length': '64'}),
|
||||
'limit': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '1024', 'blank': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '512'}),
|
||||
'playbook': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '1024'}),
|
||||
'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'job_templates'", 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': u"orm['main.Project']"}),
|
||||
'verbosity': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0', 'blank': 'True'})
|
||||
},
|
||||
'main.organization': {
|
||||
'Meta': {'object_name': 'Organization'},
|
||||
'active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
|
||||
'admins': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'admin_of_organizations'", 'blank': 'True', 'to': u"orm['auth.User']"}),
|
||||
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
|
||||
'created_by': ('django.db.models.fields.related.ForeignKey', [], {'related_name': '"{\'class\': \'organization\', \'app_label\': \'main\'}(class)s_created"', 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': u"orm['auth.User']"}),
|
||||
'description': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}),
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '512'}),
|
||||
'projects': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'organizations'", 'blank': 'True', 'to': u"orm['main.Project']"}),
|
||||
'users': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'organizations'", 'blank': 'True', 'to': u"orm['auth.User']"})
|
||||
},
|
||||
'main.permission': {
|
||||
'Meta': {'object_name': 'Permission'},
|
||||
'active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
|
||||
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
|
||||
'created_by': ('django.db.models.fields.related.ForeignKey', [], {'related_name': '"{\'class\': \'permission\', \'app_label\': \'main\'}(class)s_created"', 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': u"orm['auth.User']"}),
|
||||
'description': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}),
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'inventory': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'permissions'", 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': "orm['main.Inventory']"}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '512'}),
|
||||
'permission_type': ('django.db.models.fields.CharField', [], {'max_length': '64'}),
|
||||
'project': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'permissions'", 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': u"orm['main.Project']"}),
|
||||
'team': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'permissions'", 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': "orm['main.Team']"}),
|
||||
'user': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'permissions'", 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': u"orm['auth.User']"})
|
||||
},
|
||||
u'main.project': {
|
||||
'Meta': {'object_name': 'Project'},
|
||||
'active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
|
||||
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
|
||||
'created_by': ('django.db.models.fields.related.ForeignKey', [], {'related_name': '"{\'class\': \'project\', \'app_label\': u\'main\'}(class)s_created"', 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': u"orm['auth.User']"}),
|
||||
'description': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}),
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'local_path': ('django.db.models.fields.CharField', [], {'max_length': '1024'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '512'})
|
||||
},
|
||||
'main.team': {
|
||||
'Meta': {'object_name': 'Team'},
|
||||
'active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
|
||||
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
|
||||
'created_by': ('django.db.models.fields.related.ForeignKey', [], {'related_name': '"{\'class\': \'team\', \'app_label\': \'main\'}(class)s_created"', 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': u"orm['auth.User']"}),
|
||||
'description': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}),
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '512'}),
|
||||
'organization': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'teams'", 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': "orm['main.Organization']"}),
|
||||
'projects': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'teams'", 'blank': 'True', 'to': u"orm['main.Project']"}),
|
||||
'users': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'teams'", 'blank': 'True', 'to': u"orm['auth.User']"})
|
||||
},
|
||||
u'taggit.tag': {
|
||||
'Meta': {'object_name': 'Tag'},
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '100'}),
|
||||
'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '100'})
|
||||
},
|
||||
u'taggit.taggeditem': {
|
||||
'Meta': {'object_name': 'TaggedItem'},
|
||||
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "u'taggit_taggeditem_tagged_items'", 'to': u"orm['contenttypes.ContentType']"}),
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'object_id': ('django.db.models.fields.IntegerField', [], {'db_index': 'True'}),
|
||||
'tag': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "u'taggit_taggeditem_items'", 'to': u"orm['taggit.Tag']"})
|
||||
}
|
||||
}
|
||||
|
||||
complete_apps = ['main']
|
||||
@ -1,6 +1,7 @@
|
||||
# Copyright (c) 2013 AnsibleWorks, Inc.
|
||||
# All Rights Reserved.
|
||||
|
||||
import json
|
||||
import os
|
||||
import shlex
|
||||
from django.conf import settings
|
||||
@ -13,6 +14,7 @@ from django.core.urlresolvers import reverse
|
||||
from django.contrib.auth.models import User
|
||||
from django.utils.timezone import now
|
||||
from jsonfield import JSONField
|
||||
from taggit.managers import TaggableManager
|
||||
from djcelery.models import TaskMeta
|
||||
from rest_framework.authtoken.models import Token
|
||||
import yaml
|
||||
@ -108,10 +110,10 @@ class PrimordialModel(models.Model):
|
||||
description = models.TextField(blank=True, default='')
|
||||
created_by = models.ForeignKey('auth.User', on_delete=SET_NULL, null=True, related_name='%s(class)s_created', editable=False) # not blank=False on purpose for admin!
|
||||
created = models.DateTimeField(auto_now_add=True)
|
||||
tags = models.ManyToManyField('Tag', related_name='%(class)s_by_tag', blank=True)
|
||||
audit_trail = models.ManyToManyField('AuditTrail', related_name='%(class)s_by_audit_trail', blank=True)
|
||||
active = models.BooleanField(default=True)
|
||||
|
||||
tags = TaggableManager(blank=True)
|
||||
|
||||
def __unicode__(self):
|
||||
return unicode("%s-%s"% (self.name, self.id))
|
||||
|
||||
@ -131,39 +133,6 @@ class CommonModelNameNotUnique(PrimordialModel):
|
||||
|
||||
name = models.CharField(max_length=512, unique=False)
|
||||
|
||||
class Tag(models.Model):
|
||||
'''
|
||||
any type of object can be given a search tag
|
||||
'''
|
||||
|
||||
class Meta:
|
||||
app_label = 'main'
|
||||
|
||||
name = models.CharField(max_length=512)
|
||||
|
||||
def __unicode__(self):
|
||||
return unicode(self.name)
|
||||
|
||||
def get_absolute_url(self):
|
||||
return reverse('main:tags_detail', args=(self.pk,))
|
||||
|
||||
class AuditTrail(models.Model):
|
||||
'''
|
||||
changing any object records the change
|
||||
'''
|
||||
|
||||
class Meta:
|
||||
app_label = 'main'
|
||||
|
||||
resource_type = models.CharField(max_length=64)
|
||||
modified_by = models.ForeignKey('auth.User', on_delete=SET_NULL, null=True, blank=True)
|
||||
delta = models.TextField() # FIXME: switch to JSONField
|
||||
detail = models.TextField()
|
||||
comment = models.TextField()
|
||||
|
||||
# FIXME: this looks like this should be a ManyToMany
|
||||
tag = models.ForeignKey('Tag', on_delete=SET_NULL, null=True, blank=True)
|
||||
|
||||
class Organization(CommonModel):
|
||||
'''
|
||||
organizations are the basic unit of multi-tenancy divisions
|
||||
@ -206,7 +175,7 @@ class Host(CommonModelNameNotUnique):
|
||||
app_label = 'main'
|
||||
unique_together = (("name", "inventory"),)
|
||||
|
||||
variable_data = models.OneToOneField('VariableData', null=True, default=None, blank=True, on_delete=SET_NULL, related_name='host')
|
||||
variables = models.TextField(blank=True, default='')
|
||||
inventory = models.ForeignKey('Inventory', null=False, related_name='hosts')
|
||||
last_job = models.ForeignKey('Job', blank=True, null=True, default=None, on_delete=models.SET_NULL, related_name='hosts_as_last_job+')
|
||||
last_job_host_summary = models.ForeignKey('JobHostSummary', blank=True, null=True, default=None, on_delete=models.SET_NULL, related_name='hosts_as_last_job_summary+')
|
||||
@ -217,13 +186,37 @@ class Host(CommonModelNameNotUnique):
|
||||
def get_absolute_url(self):
|
||||
return reverse('main:hosts_detail', args=(self.pk,))
|
||||
|
||||
@property
|
||||
def variables_dict(self):
|
||||
# FIXME: Add YAML support.
|
||||
return json.loads(self.variables or '{}')
|
||||
|
||||
@property
|
||||
def all_groups(self):
|
||||
'''
|
||||
Return all groups of which this host is a member, avoiding infinite
|
||||
recursion in the case of cyclical group relations.
|
||||
'''
|
||||
qs = self.groups.distinct()
|
||||
for group in self.groups.all():
|
||||
qs = qs | group.all_parents
|
||||
return qs
|
||||
|
||||
@property
|
||||
def has_active_failures(self):
|
||||
return self.last_job_host_summary and self.last_job_host_summary.failed
|
||||
|
||||
# Use .job_host_summaries.all() to get jobs affecting this host.
|
||||
# Use .job_events.all() to get events affecting this host.
|
||||
# Use .job_host_summaries.order_by('-pk')[0] to get the last result.
|
||||
|
||||
# To get all hosts with active failures:
|
||||
# Host.objects.filter(last_job_host_summary__failed=True)
|
||||
|
||||
class Group(CommonModelNameNotUnique):
|
||||
'''
|
||||
A group of managed nodes. May belong to multiple groups
|
||||
A group containing managed hosts. A group or host may belong to multiple
|
||||
groups.
|
||||
'''
|
||||
|
||||
class Meta:
|
||||
@ -231,8 +224,9 @@ class Group(CommonModelNameNotUnique):
|
||||
unique_together = (("name", "inventory"),)
|
||||
|
||||
inventory = models.ForeignKey('Inventory', null=False, related_name='groups')
|
||||
# Can also be thought of as: parents == member_of, children == members
|
||||
parents = models.ManyToManyField('self', symmetrical=False, related_name='children', blank=True)
|
||||
variable_data = models.OneToOneField('VariableData', null=True, default=None, blank=True, on_delete=SET_NULL, related_name='group')
|
||||
variables = models.TextField(blank=True, default='')
|
||||
hosts = models.ManyToManyField('Host', related_name='groups', blank=True)
|
||||
|
||||
def __unicode__(self):
|
||||
@ -242,12 +236,60 @@ class Group(CommonModelNameNotUnique):
|
||||
return reverse('main:groups_detail', args=(self.pk,))
|
||||
|
||||
@property
|
||||
def all_hosts(self):
|
||||
qs = self.hosts.distinct()
|
||||
for group in self.children.exclude(pk=self.pk):
|
||||
qs = qs | group.all_hosts
|
||||
def variables_dict(self):
|
||||
# FIXME: Add YAML support.
|
||||
return json.loads(self.variables or '{}')
|
||||
|
||||
def get_all_parents(self, except_pks=None):
|
||||
'''
|
||||
Return all parents of this group recursively, avoiding infinite
|
||||
recursion in the case of cyclical relations. The group itself will be
|
||||
excluded unless there is a cycle leading back to it.
|
||||
'''
|
||||
except_pks = except_pks or set()
|
||||
except_pks.add(self.pk)
|
||||
qs = self.parents.distinct()
|
||||
for group in self.parents.exclude(pk__in=except_pks):
|
||||
qs = qs | group.get_all_parents(except_pks)
|
||||
return qs
|
||||
|
||||
@property
|
||||
def all_parents(self):
|
||||
return self.get_all_parents()
|
||||
|
||||
def get_all_children(self, except_pks=None):
|
||||
'''
|
||||
Return all children of this group recursively, avoiding infinite
|
||||
recursion in the case of cyclical relations. The group itself will be
|
||||
excluded unless there is a cycle leading back to it.
|
||||
'''
|
||||
except_pks = except_pks or set()
|
||||
except_pks.add(self.pk)
|
||||
qs = self.children.distinct()
|
||||
for group in self.children.exclude(pk__in=except_pks):
|
||||
qs = qs | group.get_all_children(except_pks)
|
||||
return qs
|
||||
|
||||
@property
|
||||
def all_children(self):
|
||||
return self.get_all_children()
|
||||
|
||||
def get_all_hosts(self, except_group_pks=None):
|
||||
'''
|
||||
Return all hosts associated with this group or any of its children,
|
||||
avoiding infinite recursion in the case of cyclical group relations.
|
||||
'''
|
||||
except_group_pks = except_group_pks or set()
|
||||
except_group_pks.add(self.pk)
|
||||
qs = self.hosts.distinct()
|
||||
for group in self.children.exclude(pk__in=except_group_pks):
|
||||
qs = qs | group.get_all_hosts(except_group_pks)
|
||||
return qs
|
||||
|
||||
@property
|
||||
def all_hosts(self):
|
||||
return self.get_all_hosts()
|
||||
|
||||
@property
|
||||
def job_host_summaries(self):
|
||||
return JobHostSummary.objects.filter(host__in=self.all_hosts)
|
||||
@ -256,27 +298,9 @@ class Group(CommonModelNameNotUnique):
|
||||
def job_events(self):
|
||||
return JobEvent.objects.filter(host__in=self.all_hosts)
|
||||
|
||||
# FIXME: audit nullables
|
||||
# FIXME: audit cascades
|
||||
|
||||
class VariableData(CommonModelNameNotUnique):
|
||||
'''
|
||||
A set of host or group variables
|
||||
'''
|
||||
|
||||
class Meta:
|
||||
app_label = 'main'
|
||||
verbose_name_plural = _('variable data')
|
||||
|
||||
#host = models.OneToOneField('Host', null=True, default=None, blank=True, on_delete=SET_NULL, related_name='variable_data')
|
||||
#group = models.OneToOneField('Group', null=True, default=None, blank=True, on_delete=SET_NULL, related_name='variable_data')
|
||||
data = models.TextField(default='')
|
||||
|
||||
def __unicode__(self):
|
||||
return '%s = %s' % (self.name, self.data)
|
||||
|
||||
def get_absolute_url(self):
|
||||
return reverse('main:variable_detail', args=(self.pk,))
|
||||
@property
|
||||
def has_active_failures(self):
|
||||
return bool(self.all_hosts.filter(last_job_host_summary__failed=True).count())
|
||||
|
||||
class Credential(CommonModelNameNotUnique):
|
||||
'''
|
||||
@ -537,6 +561,16 @@ class JobTemplate(CommonModel):
|
||||
blank=True,
|
||||
default='',
|
||||
)
|
||||
job_tags = models.CharField(
|
||||
max_length=1024,
|
||||
blank=True,
|
||||
default='',
|
||||
)
|
||||
host_config_key = models.CharField(
|
||||
max_length=1024,
|
||||
blank=True,
|
||||
default='',
|
||||
)
|
||||
|
||||
def create_job(self, **kwargs):
|
||||
'''
|
||||
@ -555,6 +589,7 @@ class JobTemplate(CommonModel):
|
||||
kwargs.setdefault('limit', self.limit)
|
||||
kwargs.setdefault('verbosity', self.verbosity)
|
||||
kwargs.setdefault('extra_vars', self.extra_vars)
|
||||
kwargs.setdefault('job_tags', self.job_tags)
|
||||
job = Job(**kwargs)
|
||||
if save_job:
|
||||
job.save()
|
||||
@ -633,6 +668,11 @@ class Job(CommonModel):
|
||||
blank=True,
|
||||
default='',
|
||||
)
|
||||
job_tags = models.CharField(
|
||||
max_length=1024,
|
||||
blank=True,
|
||||
default='',
|
||||
)
|
||||
cancel_flag = models.BooleanField(
|
||||
blank=True,
|
||||
default=False,
|
||||
@ -647,6 +687,23 @@ class Job(CommonModel):
|
||||
default=False,
|
||||
editable=False,
|
||||
)
|
||||
job_args = models.CharField(
|
||||
max_length=1024,
|
||||
blank=True,
|
||||
default='',
|
||||
editable=False,
|
||||
)
|
||||
job_cwd = models.CharField(
|
||||
max_length=1024,
|
||||
blank=True,
|
||||
default='',
|
||||
editable=False,
|
||||
)
|
||||
job_env = JSONField(
|
||||
blank=True,
|
||||
default={},
|
||||
editable=False,
|
||||
)
|
||||
result_stdout = models.TextField(
|
||||
blank=True,
|
||||
default='',
|
||||
@ -797,6 +854,7 @@ class JobHostSummary(models.Model):
|
||||
ok = models.PositiveIntegerField(default=0)
|
||||
processed = models.PositiveIntegerField(default=0)
|
||||
skipped = models.PositiveIntegerField(default=0)
|
||||
failed = models.BooleanField(default=False)
|
||||
|
||||
def __unicode__(self):
|
||||
return '%s changed=%d dark=%d failures=%d ok=%d processed=%d skipped=%s' % \
|
||||
@ -807,6 +865,7 @@ class JobHostSummary(models.Model):
|
||||
return reverse('main:job_host_summary_detail', args=(self.pk,))
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
self.failed = bool(self.dark or self.failures)
|
||||
super(JobHostSummary, self).save(*args, **kwargs)
|
||||
self.update_host_last_job_summary()
|
||||
|
||||
@ -826,33 +885,58 @@ class JobEvent(models.Model):
|
||||
An event/message logged from the callback when running a job.
|
||||
'''
|
||||
|
||||
EVENT_TYPES = [
|
||||
('runner_on_failed', _('Runner on Failed')),
|
||||
('runner_on_ok', _('Runner on OK')),
|
||||
('runner_on_error', _('Runner on Error')),
|
||||
('runner_on_skipped', _('Runner on Skipped')),
|
||||
('runner_on_unreachable', _('Runner on Unreachable')),
|
||||
('runner_on_no_hosts', _('Runner on No Hosts')),
|
||||
('runner_on_async_poll', _('Runner on Async Poll')),
|
||||
('runner_on_async_ok', _('Runner on Async OK')),
|
||||
('runner_on_async_failed', _('Runner on Async Failed')),
|
||||
('playbook_on_start', _('Playbook on Start')),
|
||||
('playbook_on_notify', _('Playbook on Notify')),
|
||||
('playbook_on_task_start', _('Playbook on Task Start')),
|
||||
('playbook_on_vars_prompt', _('Playbook on Vars Prompt')),
|
||||
('playbook_on_setup', _('Playbook on Setup')),
|
||||
('playbook_on_import_for_host', _('Playbook on Import for Host')),
|
||||
('playbook_on_not_import_for_host', _('Playbook on Not Import for Host')),
|
||||
('playbook_on_play_start', _('Playbook on Play Start')),
|
||||
('playbook_on_stats', _('Playbook on Stats')),
|
||||
]
|
||||
# Playbook events will be structured to form the following hierarchy:
|
||||
# - playbook_on_start (once for each playbook file)
|
||||
# - playbook_on_vars_prompt (for each play, but before play starts, we
|
||||
# currently don't handle responding to these prompts)
|
||||
# - playbook_on_play_start
|
||||
# - playbook_on_import_for_host
|
||||
# - playbook_on_not_import_for_host
|
||||
# - playbook_on_no_hosts_matched
|
||||
# - playbook_on_no_hosts_remaining
|
||||
# - playbook_on_setup
|
||||
# - runner_on*
|
||||
# - playbook_on_task_start
|
||||
# - runner_on_failed
|
||||
# - runner_on_ok
|
||||
# - runner_on_error
|
||||
# - runner_on_skipped
|
||||
# - runner_on_unreachable
|
||||
# - runner_on_no_hosts
|
||||
# - runner_on_async_poll
|
||||
# - runner_on_async_ok
|
||||
# - runner_on_async_failed
|
||||
# - runner_on_file_diff
|
||||
# - playbook_on_notify
|
||||
# - playbook_on_stats
|
||||
|
||||
FAILED_EVENTS = [
|
||||
'runner_on_failed',
|
||||
'runner_on_error',
|
||||
'runner_on_unreachable',
|
||||
'runner_on_async_failed',
|
||||
EVENT_TYPES = [
|
||||
# (level, event, verbose name, failed)
|
||||
(3, 'runner_on_failed', _('Runner on Failed'), True),
|
||||
(3, 'runner_on_ok', _('Runner on OK'), False),
|
||||
(3, 'runner_on_error', _('Runner on Error'), True),
|
||||
(3, 'runner_on_skipped', _('Runner on Skipped'), False),
|
||||
(3, 'runner_on_unreachable', _('Runner on Unreachable'), True),
|
||||
(3, 'runner_on_no_hosts', _('Runner on No Hosts'), False),
|
||||
(3, 'runner_on_async_poll', _('Runner on Async Poll'), False),
|
||||
(3, 'runner_on_async_ok', _('Runner on Async OK'), False),
|
||||
(3, 'runner_on_async_failed', _('Runner on Async Failed'), True),
|
||||
(3, 'runner_on_file_diff', _('Runner on File Diff'), False),
|
||||
(0, 'playbook_on_start', _('Playbook on Start'), False),
|
||||
(2, 'playbook_on_notify', _('Playbook on Notify'), False),
|
||||
(2, 'playbook_on_no_hosts_matched', _('Playbook on No Hosts Matched'), False),
|
||||
(2, 'playbook_on_no_hosts_remaining', _('Playbook on No Hosts Remaining'), False),
|
||||
(2, 'playbook_on_task_start', _('Playbook on Task Start'), False),
|
||||
(1, 'playbook_on_vars_prompt', _('Playbook on Vars Prompt'), False),
|
||||
(2, 'playbook_on_setup', _('Playbook on Setup'), False),
|
||||
(2, 'playbook_on_import_for_host', _('Playbook on Import for Host'), False),
|
||||
(2, 'playbook_on_not_import_for_host', _('Playbook on Not Import for Host'), False),
|
||||
(1, 'playbook_on_play_start', _('Playbook on Play Start'), False),
|
||||
(1, 'playbook_on_stats', _('Playbook on Stats'), False),
|
||||
]
|
||||
FAILED_EVENTS = [x[1] for x in EVENT_TYPES if x[3]]
|
||||
EVENT_CHOICES = [(x[1], x[2]) for x in EVENT_TYPES]
|
||||
LEVEL_FOR_EVENT = dict([(x[1], x[0]) for x in EVENT_TYPES])
|
||||
|
||||
class Meta:
|
||||
app_label = 'main'
|
||||
@ -868,7 +952,7 @@ class JobEvent(models.Model):
|
||||
)
|
||||
event = models.CharField(
|
||||
max_length=100,
|
||||
choices=EVENT_TYPES,
|
||||
choices=EVENT_CHOICES,
|
||||
)
|
||||
event_data = JSONField(
|
||||
blank=True,
|
||||
@ -878,9 +962,32 @@ class JobEvent(models.Model):
|
||||
default=False,
|
||||
)
|
||||
host = models.ForeignKey(
|
||||
'Host',
|
||||
related_name='job_events_as_primary_host',
|
||||
blank=True,
|
||||
null=True,
|
||||
default=None,
|
||||
on_delete=models.SET_NULL,
|
||||
)
|
||||
hosts = models.ManyToManyField(
|
||||
'Host',
|
||||
related_name='job_events',
|
||||
blank=True,
|
||||
)
|
||||
play = models.CharField(
|
||||
max_length=1024,
|
||||
blank=True,
|
||||
default='',
|
||||
)
|
||||
task = models.CharField(
|
||||
max_length=1024,
|
||||
blank=True,
|
||||
default='',
|
||||
)
|
||||
parent = models.ForeignKey(
|
||||
'self',
|
||||
related_name='children',
|
||||
blank=True,
|
||||
null=True,
|
||||
default=None,
|
||||
on_delete=models.SET_NULL,
|
||||
@ -892,25 +999,72 @@ class JobEvent(models.Model):
|
||||
def __unicode__(self):
|
||||
return u'%s @ %s' % (self.get_event_display(), self.created.isoformat())
|
||||
|
||||
@property
|
||||
def event_level(self):
|
||||
return self.LEVEL_FOR_EVENT.get(self.event, 0)
|
||||
|
||||
def _find_parent(self):
|
||||
parent_events = set()
|
||||
if self.event in ('playbook_on_play_start', 'playbook_on_stats',
|
||||
'playbook_on_vars_prompt'):
|
||||
parent_events.add('playbook_on_start')
|
||||
elif self.event in ('playbook_on_notify', 'playbook_on_setup',
|
||||
'playbook_on_task_start',
|
||||
'playbook_on_no_hosts_matched',
|
||||
'playbook_on_no_hosts_remaining',
|
||||
'playbook_on_import_for_host',
|
||||
'playbook_on_not_import_for_host'):
|
||||
parent_events.add('playbook_on_play_start')
|
||||
elif self.event.startswith('runner_on_'):
|
||||
parent_events.add('playbook_on_setup')
|
||||
parent_events.add('playbook_on_task_start')
|
||||
if parent_events:
|
||||
try:
|
||||
qs = self.job.job_events.all()
|
||||
if self.pk:
|
||||
qs = qs.filter(pk__lt=self.pk, event__in=parent_events)
|
||||
else:
|
||||
qs = qs.filter(event__in=parent_events)
|
||||
return qs.order_by('-pk')[0]
|
||||
except IndexError:
|
||||
pass
|
||||
return None
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
self.failed = bool(self.event in self.FAILED_EVENTS)
|
||||
try:
|
||||
if not self.host and self.event_data.get('host', ''):
|
||||
self.host = self.job.inventory.hosts.get(name=self.event_data['host'])
|
||||
except (Host.DoesNotExist, AttributeError):
|
||||
pass
|
||||
self.failed = bool(self.event in self.FAILED_EVENTS)
|
||||
self.play = self.event_data.get('play', '')
|
||||
self.task = self.event_data.get('task', '')
|
||||
self.parent = self._find_parent()
|
||||
super(JobEvent, self).save(*args, **kwargs)
|
||||
self.update_hosts()
|
||||
self.update_host_summary_from_stats()
|
||||
self.update_host_last_job()
|
||||
|
||||
def update_host_last_job(self):
|
||||
if self.host:
|
||||
update_fields = []
|
||||
if self.host.last_job != self.job:
|
||||
self.host.last_job = self.job
|
||||
update_fields.append('last_job')
|
||||
if update_fields:
|
||||
self.host.save(update_fields=update_fields)
|
||||
def update_hosts(self, extra_hosts=None):
|
||||
extra_hosts = extra_hosts or []
|
||||
hostnames = set()
|
||||
if self.event_data.get('host', ''):
|
||||
hostnames.add(self.event_data['host'])
|
||||
if self.event == 'playbook_on_stats':
|
||||
try:
|
||||
for v in self.event_data.values():
|
||||
hostnames.update(v.keys())
|
||||
except AttributeError: # In case event_data or v isn't a dict.
|
||||
pass
|
||||
for hostname in hostnames:
|
||||
try:
|
||||
host = self.job.inventory.hosts.get(name=hostname)
|
||||
except Host.DoesNotExist:
|
||||
continue
|
||||
self.hosts.add(host)
|
||||
for host in extra_hosts:
|
||||
self.hosts.add(host)
|
||||
if self.parent:
|
||||
self.parent.update_hosts(self.hosts.all())
|
||||
|
||||
def update_host_summary_from_stats(self):
|
||||
if self.event != 'playbook_on_stats':
|
||||
|
||||
@ -46,8 +46,12 @@ class CustomRbac(permissions.BasePermission):
|
||||
if not obj:
|
||||
return True # FIXME: For some reason this needs to return True
|
||||
# because it is first called with obj=None?
|
||||
return check_user_access(request.user, view.model, 'change', obj,
|
||||
request.DATA)
|
||||
if getattr(view, 'is_variable_data', False):
|
||||
return check_user_access(request.user, view.model, 'change', obj,
|
||||
{'variables': request.DATA})
|
||||
else:
|
||||
return check_user_access(request.user, view.model, 'change', obj,
|
||||
request.DATA)
|
||||
|
||||
def _check_delete_permissions(self, request, view, obj=None):
|
||||
if not obj:
|
||||
|
||||
@ -1,6 +1,9 @@
|
||||
# Copyright (c) 2013 AnsibleWorks, Inc.
|
||||
# All Rights Reserved.
|
||||
|
||||
# Python
|
||||
import json
|
||||
|
||||
# Django
|
||||
from django.contrib.auth.models import User
|
||||
from django.core.urlresolvers import reverse
|
||||
@ -126,28 +129,16 @@ class OrganizationSerializer(BaseSerializer):
|
||||
def get_related(self, obj):
|
||||
res = super(OrganizationSerializer, self).get_related(obj)
|
||||
res.update(dict(
|
||||
audit_trail = reverse('main:organizations_audit_trail_list', args=(obj.pk,)),
|
||||
#audit_trail = reverse('main:organizations_audit_trail_list', args=(obj.pk,)),
|
||||
projects = reverse('main:organizations_projects_list', args=(obj.pk,)),
|
||||
inventories = reverse('main:organizations_inventories_list', args=(obj.pk,)),
|
||||
users = reverse('main:organizations_users_list', args=(obj.pk,)),
|
||||
admins = reverse('main:organizations_admins_list', args=(obj.pk,)),
|
||||
tags = reverse('main:organizations_tags_list', args=(obj.pk,)),
|
||||
#tags = reverse('main:organizations_tags_list', args=(obj.pk,)),
|
||||
teams = reverse('main:organizations_teams_list', args=(obj.pk,)),
|
||||
))
|
||||
return res
|
||||
|
||||
class AuditTrailSerializer(BaseSerializer):
|
||||
|
||||
class Meta:
|
||||
model = AuditTrail
|
||||
fields = ('url', 'id', 'modified_by', 'delta', 'detail', 'comment')
|
||||
|
||||
def get_related(self, obj):
|
||||
res = super(AuditTrailSerializer, self).get_related(obj)
|
||||
if obj.modified_by:
|
||||
res['modified_by'] = reverse('main:users_detail', args=(obj.modified_by.pk,))
|
||||
return res
|
||||
|
||||
class ProjectSerializer(BaseSerializer):
|
||||
|
||||
playbooks = serializers.Field(source='playbooks')
|
||||
@ -197,9 +188,11 @@ class InventorySerializer(BaseSerializer):
|
||||
|
||||
class HostSerializer(BaseSerializer):
|
||||
|
||||
has_active_failures = serializers.Field(source='has_active_failures')
|
||||
|
||||
class Meta:
|
||||
model = Host
|
||||
fields = BASE_FIELDS + ('inventory',)
|
||||
fields = BASE_FIELDS + ('inventory', 'variables', 'has_active_failures')
|
||||
|
||||
def get_related(self, obj):
|
||||
res = super(HostSerializer, self).get_related(obj)
|
||||
@ -218,9 +211,11 @@ class HostSerializer(BaseSerializer):
|
||||
|
||||
class GroupSerializer(BaseSerializer):
|
||||
|
||||
has_active_failures = serializers.Field(source='has_active_failures')
|
||||
|
||||
class Meta:
|
||||
model = Group
|
||||
fields = BASE_FIELDS + ('inventory',)
|
||||
fields = BASE_FIELDS + ('inventory', 'variables', 'has_active_failures')
|
||||
|
||||
def get_related(self, obj):
|
||||
res = super(GroupSerializer, self).get_related(obj)
|
||||
@ -235,6 +230,28 @@ class GroupSerializer(BaseSerializer):
|
||||
))
|
||||
return res
|
||||
|
||||
class BaseVariableDataSerializer(BaseSerializer):
|
||||
|
||||
def to_native(self, obj):
|
||||
ret = super(BaseVariableDataSerializer, self).to_native(obj)
|
||||
return json.loads(ret.get('variables', '') or '{}')
|
||||
|
||||
def from_native(self, data, files):
|
||||
data = {'variables': json.dumps(data)}
|
||||
return super(BaseVariableDataSerializer, self).from_native(data, files)
|
||||
|
||||
class HostVariableDataSerializer(BaseVariableDataSerializer):
|
||||
|
||||
class Meta:
|
||||
model = Host
|
||||
fields = ('variables',)
|
||||
|
||||
class GroupVariableDataSerializer(BaseVariableDataSerializer):
|
||||
|
||||
class Meta:
|
||||
model = Group
|
||||
fields = ('variables',)
|
||||
|
||||
class TeamSerializer(BaseSerializer):
|
||||
|
||||
class Meta:
|
||||
@ -319,42 +336,13 @@ class UserSerializer(BaseSerializer):
|
||||
))
|
||||
return res
|
||||
|
||||
class TagSerializer(BaseSerializer):
|
||||
|
||||
class Meta:
|
||||
model = Tag
|
||||
fields = ('id', 'url', 'name')
|
||||
|
||||
def get_related(self, obj):
|
||||
res = super(TagSerializer, self).get_related(obj)
|
||||
res.pop('created_by', None)
|
||||
return res
|
||||
|
||||
class VariableDataSerializer(BaseSerializer):
|
||||
|
||||
class Meta:
|
||||
model = VariableData
|
||||
fields = BASE_FIELDS + ('data',)
|
||||
|
||||
def get_related(self, obj):
|
||||
res = super(VariableDataSerializer, self).get_related(obj)
|
||||
try:
|
||||
res['host'] = reverse('main:hosts_detail', args=(obj.host.pk,))
|
||||
except Host.DoesNotExist:
|
||||
pass
|
||||
try:
|
||||
res['group'] = reverse('main:groups_detail', args=(obj.group.pk,))
|
||||
except Group.DoesNotExist:
|
||||
pass
|
||||
return res
|
||||
|
||||
class JobTemplateSerializer(BaseSerializer):
|
||||
|
||||
class Meta:
|
||||
model = JobTemplate
|
||||
fields = BASE_FIELDS + ('job_type', 'inventory', 'project', 'playbook',
|
||||
'credential', 'forks', 'limit', 'verbosity',
|
||||
'extra_vars')
|
||||
'extra_vars', 'job_tags')
|
||||
|
||||
def get_related(self, obj):
|
||||
res = super(JobTemplateSerializer, self).get_related(obj)
|
||||
@ -383,7 +371,7 @@ class JobSerializer(BaseSerializer):
|
||||
fields = BASE_FIELDS + ('job_template', 'job_type', 'inventory',
|
||||
'project', 'playbook', 'credential',
|
||||
'forks', 'limit', 'verbosity', 'extra_vars',
|
||||
'status', 'failed', 'result_stdout',
|
||||
'job_tags', 'status', 'failed', 'result_stdout',
|
||||
'result_traceback',
|
||||
'passwords_needed_to_start')
|
||||
|
||||
@ -424,6 +412,7 @@ class JobSerializer(BaseSerializer):
|
||||
data.setdefault('limit', job_template.limit)
|
||||
data.setdefault('verbosity', job_template.verbosity)
|
||||
data.setdefault('extra_vars', job_template.extra_vars)
|
||||
data.setdefault('job_tags', job_template.job_tags)
|
||||
return super(JobSerializer, self).from_native(data, files)
|
||||
|
||||
class JobHostSummarySerializer(BaseSerializer):
|
||||
@ -431,7 +420,8 @@ class JobHostSummarySerializer(BaseSerializer):
|
||||
class Meta:
|
||||
model = JobHostSummary
|
||||
fields = ('id', 'url', 'job', 'host', 'summary_fields', 'related',
|
||||
'changed', 'dark', 'failures', 'ok', 'processed', 'skipped')
|
||||
'changed', 'dark', 'failures', 'ok', 'processed', 'skipped',
|
||||
'failed')
|
||||
|
||||
def get_related(self, obj):
|
||||
res = super(JobHostSummarySerializer, self).get_related(obj)
|
||||
|
||||
@ -124,6 +124,8 @@ class RunJob(Task):
|
||||
args.append('-%s' % ('v' * min(3, job.verbosity)))
|
||||
if job.extra_vars:
|
||||
args.extend(['-e', job.extra_vars])
|
||||
if job.job_tags:
|
||||
args.extend(['-t', job.job_tags])
|
||||
args.append(job.playbook) # relative path to project.local_path
|
||||
ssh_key_path = kwargs.get('ssh_key_path', '')
|
||||
if ssh_key_path:
|
||||
@ -192,6 +194,8 @@ class RunJob(Task):
|
||||
raise RuntimeError('project local_path %s cannot be found' %
|
||||
project.local_path)
|
||||
env = self.build_env(job, **kwargs)
|
||||
job = self.update_job(job_pk, job_args=args, job_cwd=cwd,
|
||||
job_env=env)
|
||||
status, stdout = self.run_pexpect(job_pk, args, cwd, env,
|
||||
kwargs['passwords'])
|
||||
except Exception:
|
||||
|
||||
@ -111,23 +111,23 @@ class AcomInventoryTest(BaseCommandTest):
|
||||
hosts = []
|
||||
for x in xrange(10):
|
||||
if n > 0:
|
||||
variable_data = VariableData.objects.create(data=json.dumps({'ho': 'hum-%d' % x}))
|
||||
variables = json.dumps({'ho': 'hum-%d' % x})
|
||||
else:
|
||||
variable_data = None
|
||||
variables = ''
|
||||
host = inventory.hosts.create(name='host-%02d-%02d.example.com' % (n, x),
|
||||
inventory=inventory,
|
||||
variable_data=variable_data)
|
||||
variables=variables)
|
||||
hosts.append(host)
|
||||
self.hosts.extend(hosts)
|
||||
groups = []
|
||||
for x in xrange(5):
|
||||
if n > 0:
|
||||
variable_data = VariableData.objects.create(data=json.dumps({'gee': 'whiz-%d' % x}))
|
||||
variables = json.dumps({'gee': 'whiz-%d' % x})
|
||||
else:
|
||||
variable_data = None
|
||||
variables = ''
|
||||
group = inventory.groups.create(name='group-%d' % x,
|
||||
inventory=inventory,
|
||||
variable_data=variable_data)
|
||||
variables=variables)
|
||||
groups.append(group)
|
||||
group.hosts.add(hosts[x])
|
||||
group.hosts.add(hosts[x + 5])
|
||||
@ -184,9 +184,9 @@ class AcomInventoryTest(BaseCommandTest):
|
||||
group = inventory.groups.get(name=k)
|
||||
self.assertEqual(set(v.get('hosts', [])),
|
||||
set(group.hosts.values_list('name', flat=True)))
|
||||
if group.variable_data:
|
||||
if group.variables:
|
||||
self.assertEqual(v.get('vars', {}),
|
||||
json.loads(group.variable_data.data))
|
||||
json.loads(group.variables))
|
||||
if k == 'group-3':
|
||||
self.assertEqual(set(v.get('children', [])),
|
||||
set(group.children.values_list('name', flat=True)))
|
||||
@ -211,7 +211,7 @@ class AcomInventoryTest(BaseCommandTest):
|
||||
host=host.name)
|
||||
self.assertEqual(result, None)
|
||||
data = json.loads(stdout)
|
||||
self.assertEqual(data, json.loads(host.variable_data.data))
|
||||
self.assertEqual(data, json.loads(host.variables))
|
||||
|
||||
def test_invalid_host(self):
|
||||
# Valid host, but not part of the specified inventory.
|
||||
|
||||
@ -250,7 +250,7 @@ class InventoryTest(BaseTest):
|
||||
# attempting to get a variable object creates it, even though it does not already exist
|
||||
vdata_url = "/api/v1/hosts/%s/variable_data/" % (added_by_collection_a['id'])
|
||||
got = self.get(vdata_url, expect=200, auth=self.get_super_credentials())
|
||||
self.assertEquals(got, dict())
|
||||
self.assertEquals(got, {})
|
||||
|
||||
# super user can create variable objects
|
||||
# an org admin can create variable objects (defers to inventory permissions)
|
||||
@ -267,16 +267,16 @@ class InventoryTest(BaseTest):
|
||||
self.put(vdata_url, data=vars_a, expect=403, auth=self.get_nobody_credentials())
|
||||
|
||||
# a normal user with inventory write permissions can edit variable objects
|
||||
vdata_url = "/api/v1/hosts/1/variable_data/"
|
||||
got = self.put(vdata_url, data=vars_b, expect=200, auth=self.get_normal_credentials())
|
||||
self.assertEquals(got, vars_b)
|
||||
#vdata_url = "/api/v1/hosts/1/variable_data/"
|
||||
#got = self.put(vdata_url, data=vars_b, expect=200, auth=self.get_normal_credentials())
|
||||
#self.assertEquals(got, vars_b)
|
||||
|
||||
# this URL is not one end users will use, but is what you get back from a put
|
||||
# as a result, it also needs to be access controlled and working. You will not
|
||||
# be able to put to it.
|
||||
backend_url = '/api/v1/variable_data/1/'
|
||||
got = self.get(backend_url, expect=200, auth=self.get_normal_credentials())
|
||||
got = self.put(backend_url, data=dict(), expect=403, auth=self.get_super_credentials())
|
||||
#backend_url = '/api/v1/variable_data/1/'
|
||||
#got = self.get(backend_url, expect=200, auth=self.get_normal_credentials())
|
||||
#got = self.put(backend_url, data=dict(), expect=403, auth=self.get_super_credentials())
|
||||
|
||||
###################################################
|
||||
# VARIABLES -> GROUPS
|
||||
@ -443,7 +443,96 @@ class InventoryTest(BaseTest):
|
||||
# on a group resource, I can see related resources for variables, inventories, and children
|
||||
# and these work
|
||||
|
||||
|
||||
|
||||
|
||||
def test_group_parents_and_children(self):
|
||||
# Test for various levels of group parent/child relations, with hosts,
|
||||
# to verify that helper properties return the correct querysets.
|
||||
|
||||
# Group A is parent of B, B is parent of C, C is parent of D. Group E
|
||||
# is part of the inventory, but outside of the ABCD tree.
|
||||
g_a = self.inventory_a.groups.create(name='A')
|
||||
g_b = self.inventory_a.groups.create(name='B')
|
||||
g_b.parents.add(g_a)
|
||||
g_c = self.inventory_a.groups.create(name='C')
|
||||
g_c.parents.add(g_b)
|
||||
g_d = self.inventory_a.groups.create(name='D')
|
||||
g_d.parents.add(g_c)
|
||||
g_e = self.inventory_a.groups.create(name='E')
|
||||
# Each group "X" contains one host "x".
|
||||
h_a = self.inventory_a.hosts.create(name='a')
|
||||
h_a.groups.add(g_a)
|
||||
h_b = self.inventory_a.hosts.create(name='b')
|
||||
h_b.groups.add(g_b)
|
||||
h_c = self.inventory_a.hosts.create(name='c')
|
||||
h_c.groups.add(g_c)
|
||||
h_d = self.inventory_a.hosts.create(name='d')
|
||||
h_d.groups.add(g_d)
|
||||
h_e = self.inventory_a.hosts.create(name='e')
|
||||
h_e.groups.add(g_e)
|
||||
# Test all_children property on groups.
|
||||
self.assertEqual(set(g_a.all_children.values_list('pk', flat=True)),
|
||||
set([g_b.pk, g_c.pk, g_d.pk]))
|
||||
self.assertEqual(set(g_b.all_children.values_list('pk', flat=True)),
|
||||
set([g_c.pk, g_d.pk]))
|
||||
self.assertEqual(set(g_c.all_children.values_list('pk', flat=True)),
|
||||
set([g_d.pk]))
|
||||
self.assertEqual(set(g_d.all_children.values_list('pk', flat=True)),
|
||||
set([]))
|
||||
self.assertEqual(set(g_e.all_children.values_list('pk', flat=True)),
|
||||
set([]))
|
||||
# Test all_parents property on groups.
|
||||
self.assertEqual(set(g_a.all_parents.values_list('pk', flat=True)),
|
||||
set([]))
|
||||
self.assertEqual(set(g_b.all_parents.values_list('pk', flat=True)),
|
||||
set([g_a.pk]))
|
||||
self.assertEqual(set(g_c.all_parents.values_list('pk', flat=True)),
|
||||
set([g_a.pk, g_b.pk]))
|
||||
self.assertEqual(set(g_d.all_parents.values_list('pk', flat=True)),
|
||||
set([g_a.pk, g_b.pk, g_c.pk]))
|
||||
self.assertEqual(set(g_e.all_parents.values_list('pk', flat=True)),
|
||||
set([]))
|
||||
# Test all_hosts property on groups.
|
||||
self.assertEqual(set(g_a.all_hosts.values_list('pk', flat=True)),
|
||||
set([h_a.pk, h_b.pk, h_c.pk, h_d.pk]))
|
||||
self.assertEqual(set(g_b.all_hosts.values_list('pk', flat=True)),
|
||||
set([h_b.pk, h_c.pk, h_d.pk]))
|
||||
self.assertEqual(set(g_c.all_hosts.values_list('pk', flat=True)),
|
||||
set([h_c.pk, h_d.pk]))
|
||||
self.assertEqual(set(g_d.all_hosts.values_list('pk', flat=True)),
|
||||
set([h_d.pk]))
|
||||
self.assertEqual(set(g_e.all_hosts.values_list('pk', flat=True)),
|
||||
set([h_e.pk]))
|
||||
# Test all_groups property on hosts.
|
||||
self.assertEqual(set(h_a.all_groups.values_list('pk', flat=True)),
|
||||
set([g_a.pk]))
|
||||
self.assertEqual(set(h_b.all_groups.values_list('pk', flat=True)),
|
||||
set([g_a.pk, g_b.pk]))
|
||||
self.assertEqual(set(h_c.all_groups.values_list('pk', flat=True)),
|
||||
set([g_a.pk, g_b.pk, g_c.pk]))
|
||||
self.assertEqual(set(h_d.all_groups.values_list('pk', flat=True)),
|
||||
set([g_a.pk, g_b.pk, g_c.pk, g_d.pk]))
|
||||
self.assertEqual(set(h_e.all_groups.values_list('pk', flat=True)),
|
||||
set([g_e.pk]))
|
||||
# Now create a circular relationship from D back to A.
|
||||
g_a.parents.add(g_d)
|
||||
# All groups "ABCD" should be parents of each other, and children of
|
||||
# each other, and contain all hosts "abcd".
|
||||
for g in [g_a, g_b, g_c, g_d]:
|
||||
self.assertEqual(set(g.all_children.values_list('pk', flat=True)),
|
||||
set([g_a.pk, g_b.pk, g_c.pk, g_d.pk]))
|
||||
self.assertEqual(set(g.all_parents.values_list('pk', flat=True)),
|
||||
set([g_a.pk, g_b.pk, g_c.pk, g_d.pk]))
|
||||
self.assertEqual(set(g.all_hosts.values_list('pk', flat=True)),
|
||||
set([h_a.pk, h_b.pk, h_c.pk, h_d.pk]))
|
||||
# All hosts "abcd" should be members of all groups "ABCD".
|
||||
for h in [h_a, h_b, h_c, h_d]:
|
||||
self.assertEqual(set(h.all_groups.values_list('pk', flat=True)),
|
||||
set([g_a.pk, g_b.pk, g_c.pk, g_d.pk]))
|
||||
# Group E and host e should not be affected.
|
||||
self.assertEqual(set(g_e.all_children.values_list('pk', flat=True)),
|
||||
set([]))
|
||||
self.assertEqual(set(g_e.all_parents.values_list('pk', flat=True)),
|
||||
set([]))
|
||||
self.assertEqual(set(g_e.all_hosts.values_list('pk', flat=True)),
|
||||
set([h_e.pk]))
|
||||
self.assertEqual(set(h_e.all_groups.values_list('pk', flat=True)),
|
||||
set([g_e.pk]))
|
||||
|
||||
@ -779,7 +779,8 @@ class JobStartCancelTest(BaseJobTestMixin, django.test.TransactionTestCase):
|
||||
self.assertFalse(response['passwords_needed_to_start'])
|
||||
response = self.post(url, {}, expect=202)
|
||||
job = Job.objects.get(pk=job.pk)
|
||||
self.assertEqual(job.status, 'successful')
|
||||
self.assertEqual(job.status, 'successful',
|
||||
job.result_stdout)
|
||||
else:
|
||||
self.assertFalse(response['can_start'])
|
||||
response = self.post(url, {}, expect=405)
|
||||
|
||||
@ -79,7 +79,7 @@ class OrganizationsTest(BaseTest):
|
||||
|
||||
# check that the related URL functionality works
|
||||
related = response['results'][0]['related']
|
||||
for x in [ 'audit_trail', 'projects', 'users', 'admins', 'tags' ]:
|
||||
for x in ['projects', 'users', 'admins']:
|
||||
self.assertTrue(x in related and related[x].endswith("/%s/" % x), "looking for %s in related" % x)
|
||||
|
||||
# normal credentials == 200, get only organizations of which user is a member
|
||||
@ -163,7 +163,8 @@ class OrganizationsTest(BaseTest):
|
||||
org1_users = self.get(org1_users_url, expect=200, auth=self.get_super_credentials())
|
||||
self.assertEquals(org1_users['count'], 1)
|
||||
|
||||
def test_get_item_subobjects_tags(self):
|
||||
def _test_get_item_subobjects_tags(self):
|
||||
# FIXME: Update to support taggit!
|
||||
|
||||
# put some tags on the org
|
||||
org1 = Organization.objects.get(pk=2)
|
||||
@ -181,7 +182,8 @@ class OrganizationsTest(BaseTest):
|
||||
self.assertEquals(org1_tags['count'], 2)
|
||||
org1_tags = self.get(org1_tags_url, expect=403, auth=self.get_other_credentials())
|
||||
|
||||
def test_get_item_subobjects_audit_trail(self):
|
||||
def _test_get_item_subobjects_audit_trail(self):
|
||||
# FIXME: Update to support whatever audit trail framework is used.
|
||||
url = '/api/v1/organizations/2/audit_trail/'
|
||||
self.get(url, expect=200, auth=self.get_normal_credentials())
|
||||
# FIXME: verify that some audit trail records are auto-created on save AND post
|
||||
@ -291,7 +293,8 @@ class OrganizationsTest(BaseTest):
|
||||
admins = self.get(url, expect=200, auth=self.get_normal_credentials())
|
||||
self.assertEqual(admins['count'], 1)
|
||||
|
||||
def test_post_item_subobjects_tags(self):
|
||||
def _test_post_item_subobjects_tags(self):
|
||||
# FIXME: Update to support taggit!
|
||||
|
||||
tag = Tag.objects.create(name='blippy')
|
||||
url = '/api/v1/organizations/2/tags/'
|
||||
@ -305,7 +308,8 @@ class OrganizationsTest(BaseTest):
|
||||
tags = self.get(url, expect=200, auth=self.get_normal_credentials())
|
||||
self.assertEqual(tags['count'], 0)
|
||||
|
||||
def test_post_item_subobjects_audit_trail(self):
|
||||
def _test_post_item_subobjects_audit_trail(self):
|
||||
# FIXME: Update to support whatever audit trail framework is used.
|
||||
# audit trails are system things, and no user can post to them.
|
||||
url = '/api/v1/organizations/2/audit_trail/'
|
||||
self.post(url, dict(id=1), expect=405, auth=self.get_super_credentials())
|
||||
|
||||
@ -13,12 +13,10 @@ def url(regex, view, kwargs=None, name=None, prefix=''):
|
||||
organizations_urls = patterns('ansibleworks.main.views',
|
||||
url(r'^$', 'organizations_list'),
|
||||
url(r'^(?P<pk>[0-9]+)/$', 'organizations_detail'),
|
||||
url(r'^(?P<pk>[0-9]+)/audit_trail/$', 'organizations_audit_trail_list'),
|
||||
url(r'^(?P<pk>[0-9]+)/users/$', 'organizations_users_list'),
|
||||
url(r'^(?P<pk>[0-9]+)/admins/$', 'organizations_admins_list'),
|
||||
url(r'^(?P<pk>[0-9]+)/inventories/$', 'organizations_inventories_list'),
|
||||
url(r'^(?P<pk>[0-9]+)/projects/$', 'organizations_projects_list'),
|
||||
url(r'^(?P<pk>[0-9]+)/tags/$', 'organizations_tags_list'),
|
||||
url(r'^(?P<pk>[0-9]+)/teams/$', 'organizations_teams_list'),
|
||||
)
|
||||
|
||||
@ -40,12 +38,6 @@ projects_urls = patterns('ansibleworks.main.views',
|
||||
url(r'^(?P<pk>[0-9]+)/organizations/$', 'projects_organizations_list'),
|
||||
)
|
||||
|
||||
audit_trails_urls = patterns('ansibleworks.main.views',
|
||||
#url(r'^$', 'audit_trails_list'),
|
||||
#url(r'^(?P<pk>[0-9]+)/$', 'audit_trails_detail'),
|
||||
# ... and ./audit_trails/ on all resources
|
||||
)
|
||||
|
||||
teams_urls = patterns('ansibleworks.main.views',
|
||||
url(r'^$', 'teams_list'),
|
||||
url(r'^(?P<pk>[0-9]+)/$', 'teams_detail'),
|
||||
@ -82,11 +74,6 @@ groups_urls = patterns('ansibleworks.main.views',
|
||||
url(r'^(?P<pk>[0-9]+)/job_host_summaries/$', 'group_job_host_summary_list'),
|
||||
)
|
||||
|
||||
variable_data_urls = patterns('ansibleworks.main.views',
|
||||
url(r'^(?P<pk>[0-9]+)/$', 'variable_detail'),
|
||||
# See also variable_data resources on hosts/groups.
|
||||
)
|
||||
|
||||
credentials_urls = patterns('ansibleworks.main.views',
|
||||
url(r'^$', 'credentials_list'),
|
||||
url(r'^(?P<pk>[0-9]+)/$', 'credentials_detail'),
|
||||
@ -125,11 +112,6 @@ job_events_urls = patterns('ansibleworks.main.views',
|
||||
url(r'^(?P<pk>[0-9]+)/$', 'job_event_detail'),
|
||||
)
|
||||
|
||||
tags_urls = patterns('ansibleworks.main.views',
|
||||
url(r'^(?P<pk>[0-9]+)/$', 'tags_detail'),
|
||||
# ... and tag relations on all resources
|
||||
)
|
||||
|
||||
v1_urls = patterns('ansibleworks.main.views',
|
||||
url(r'^$', 'api_v1_root_view'),
|
||||
url(r'^authtoken/$', 'auth_token_view'),
|
||||
@ -137,19 +119,16 @@ v1_urls = patterns('ansibleworks.main.views',
|
||||
url(r'^organizations/', include(organizations_urls)),
|
||||
url(r'^users/', include(users_urls)),
|
||||
url(r'^projects/', include(projects_urls)),
|
||||
url(r'^audit_trails/', include(audit_trails_urls)),
|
||||
url(r'^teams/', include(teams_urls)),
|
||||
url(r'^inventories/', include(inventory_urls)),
|
||||
url(r'^hosts/', include(hosts_urls)),
|
||||
url(r'^groups/', include(groups_urls)),
|
||||
url(r'^variable_data/', include(variable_data_urls)),
|
||||
url(r'^credentials/', include(credentials_urls)),
|
||||
url(r'^permissions/', include(permissions_urls)),
|
||||
url(r'^job_templates/', include(job_templates_urls)),
|
||||
url(r'^jobs/', include(jobs_urls)),
|
||||
url(r'^job_host_summaries/', include(job_host_summary_urls)),
|
||||
url(r'^job_events/', include(job_events_urls)),
|
||||
url(r'^tags/', include(tags_urls)),
|
||||
)
|
||||
|
||||
urlpatterns = patterns('ansibleworks.main.views',
|
||||
|
||||
@ -133,23 +133,6 @@ class OrganizationsDetail(BaseDetail):
|
||||
serializer_class = OrganizationSerializer
|
||||
permission_classes = (CustomRbac,)
|
||||
|
||||
class OrganizationsAuditTrailList(BaseSubList):
|
||||
|
||||
model = AuditTrail
|
||||
serializer_class = AuditTrailSerializer
|
||||
permission_classes = (CustomRbac,)
|
||||
parent_model = Organization
|
||||
relationship = 'audit_trail'
|
||||
postable = False
|
||||
|
||||
def get_queryset(self):
|
||||
''' to list tags in the organization, I must be a superuser or org admin '''
|
||||
organization = Organization.objects.get(pk=self.kwargs['pk'])
|
||||
if not (self.request.user.is_superuser or self.request.user in organization.admins.all()):
|
||||
# FIXME: use: organization.can_user_administrate(...) ?
|
||||
raise PermissionDenied()
|
||||
return AuditTrail.objects.filter(organization_by_audit_trail__in = [ organization ])
|
||||
|
||||
class OrganizationsInventoriesList(BaseSubList):
|
||||
|
||||
model = Inventory
|
||||
@ -221,25 +204,6 @@ class OrganizationsProjectsList(BaseSubList):
|
||||
raise PermissionDenied()
|
||||
return Project.objects.filter(organizations__in = [ organization ])
|
||||
|
||||
class OrganizationsTagsList(BaseSubList):
|
||||
|
||||
model = Tag
|
||||
serializer_class = TagSerializer
|
||||
permission_classes = (CustomRbac,)
|
||||
parent_model = Organization # for sub list
|
||||
relationship = 'tags' # " "
|
||||
postable = True
|
||||
inject_primary_key_on_post_as = 'organization'
|
||||
filter_fields = ('name',)
|
||||
|
||||
def get_queryset(self):
|
||||
''' to list tags in the organization, I must be a superuser or org admin '''
|
||||
organization = Organization.objects.get(pk=self.kwargs['pk'])
|
||||
if not (self.request.user.is_superuser or self.request.user in organization.admins.all()):
|
||||
# FIXME: use: organization.can_user_administrate(...) ?
|
||||
raise PermissionDenied()
|
||||
return Tag.objects.filter(organization_by_tag__in = [ organization ])
|
||||
|
||||
class OrganizationsTeamsList(BaseSubList):
|
||||
|
||||
model = Team
|
||||
@ -433,12 +397,6 @@ class ProjectsOrganizationsList(BaseSubList):
|
||||
raise PermissionDenied()
|
||||
return Organization.objects.filter(projects__in = [ project ])
|
||||
|
||||
class TagsDetail(BaseDetail):
|
||||
|
||||
model = Tag
|
||||
serializer_class = TagSerializer
|
||||
permission_classes = (CustomRbac,)
|
||||
|
||||
class UsersList(BaseList):
|
||||
|
||||
model = User
|
||||
@ -889,32 +847,19 @@ class InventoryRootGroupsList(BaseSubList):
|
||||
all_ids = base.values_list('id', flat=True)
|
||||
return base.exclude(parents__pk__in = all_ids)
|
||||
|
||||
class GroupsVariableDetail(VariableBaseDetail):
|
||||
class HostsVariableDetail(BaseDetail):
|
||||
|
||||
model = VariableData
|
||||
serializer_class = VariableDataSerializer
|
||||
model = Host
|
||||
serializer_class = HostVariableDataSerializer
|
||||
permission_classes = (CustomRbac,)
|
||||
parent_model = Group
|
||||
reverse_relationship = 'variable_data'
|
||||
relationship = 'group'
|
||||
is_variable_data = True # Special flag for RBAC
|
||||
|
||||
class HostsVariableDetail(VariableBaseDetail):
|
||||
class GroupsVariableDetail(BaseDetail):
|
||||
|
||||
model = VariableData
|
||||
serializer_class = VariableDataSerializer
|
||||
model = Group
|
||||
serializer_class = GroupVariableDataSerializer
|
||||
permission_classes = (CustomRbac,)
|
||||
parent_model = Host
|
||||
reverse_relationship = 'variable_data'
|
||||
relationship = 'host'
|
||||
|
||||
class VariableDetail(BaseDetail):
|
||||
|
||||
model = VariableData
|
||||
serializer_class = VariableDataSerializer
|
||||
permission_classes = (CustomRbac,)
|
||||
|
||||
def put(self, request, *args, **kwargs):
|
||||
raise PermissionDenied()
|
||||
is_variable_data = True # Special flag for RBAC
|
||||
|
||||
class JobTemplateList(BaseList):
|
||||
|
||||
|
||||
@ -39,10 +39,31 @@ class CallbackModule(object):
|
||||
Callback module for logging ansible-playbook events to the database.
|
||||
'''
|
||||
|
||||
# These events should never have an associated play.
|
||||
EVENTS_WITHOUT_PLAY = [
|
||||
'playbook_on_start',
|
||||
'playbook_on_stats',
|
||||
]
|
||||
# These events should never have an associated task.
|
||||
EVENTS_WITHOUT_TASK = EVENTS_WITHOUT_PLAY + [
|
||||
'playbook_on_setup',
|
||||
'playbook_on_notify',
|
||||
'playbook_on_import_for_host',
|
||||
'playbook_on_not_import_for_host',
|
||||
'playbook_on_no_hosts_matched',
|
||||
'playbook_on_no_hosts_remaining',
|
||||
]
|
||||
|
||||
def __init__(self):
|
||||
self.callback_script = os.getenv('ACOM_CALLBACK_EVENT_SCRIPT')
|
||||
|
||||
def _log_event(self, event, **event_data):
|
||||
play = getattr(getattr(self, 'play', None), 'name', '')
|
||||
if play and event not in self.EVENTS_WITHOUT_PLAY:
|
||||
event_data['play'] = play
|
||||
task = getattr(getattr(self, 'task', None), 'name', '')
|
||||
if task and event not in self.EVENTS_WITHOUT_TASK:
|
||||
event_data['task'] = task
|
||||
event_data_json = json.dumps(event_data)
|
||||
cmdline = [self.callback_script, '-e', event, '-d', event_data_json]
|
||||
subprocess.check_call(cmdline)
|
||||
@ -79,11 +100,20 @@ class CallbackModule(object):
|
||||
def runner_on_async_failed(self, host, res, jid):
|
||||
self._log_event('runner_on_async_failed', host=host, res=res, jid=jid)
|
||||
|
||||
def runner_on_file_diff(self, host, diff):
|
||||
self._log_event('runner_on_file_diff', host=host, diff=diff)
|
||||
|
||||
def playbook_on_start(self):
|
||||
self._log_event('playbook_on_start')
|
||||
|
||||
def playbook_on_notify(self, host, handler):
|
||||
self._log_event('playbook_on_notify')
|
||||
self._log_event('playbook_on_notify', host=host, handler=handler)
|
||||
|
||||
def playbook_on_no_hosts_matched(self):
|
||||
self._log_event('playbook_on_no_hosts_matched')
|
||||
|
||||
def playbook_on_no_hosts_remaining(self):
|
||||
self._log_event('playbook_on_no_hosts_remaining')
|
||||
|
||||
def playbook_on_task_start(self, name, is_conditional):
|
||||
self._log_event('playbook_on_task_start', name=name,
|
||||
|
||||
@ -29,9 +29,9 @@ REST_FRAMEWORK = {
|
||||
'PAGINATE_BY': 25,
|
||||
'PAGINATE_BY_PARAM': 'page_size',
|
||||
'DEFAULT_AUTHENTICATION_CLASSES': (
|
||||
'rest_framework.authentication.TokenAuthentication',
|
||||
'rest_framework.authentication.BasicAuthentication',
|
||||
'rest_framework.authentication.SessionAuthentication',
|
||||
'rest_framework.authentication.TokenAuthentication',
|
||||
)
|
||||
}
|
||||
|
||||
@ -137,6 +137,7 @@ INSTALLED_APPS = (
|
||||
'django_extensions',
|
||||
'djcelery',
|
||||
'kombu.transport.django',
|
||||
'taggit',
|
||||
'ansibleworks.main',
|
||||
'ansibleworks.ui',
|
||||
)
|
||||
|
||||
@ -7,6 +7,7 @@ django-devserver
|
||||
django-extensions
|
||||
django-filter
|
||||
django-jsonfield
|
||||
django-taggit
|
||||
djangorestframework
|
||||
ipython
|
||||
markdown
|
||||
|
||||
4
setup.py
4
setup.py
@ -26,10 +26,10 @@ setup(
|
||||
install_requires=[
|
||||
'Django>=1.5',
|
||||
'django-celery',
|
||||
'django-devserver',
|
||||
'django-extensions',
|
||||
'django-filter',
|
||||
'django-jsonfield',
|
||||
'django-taggit',
|
||||
'djangorestframework',
|
||||
'pexpect',
|
||||
'python-dateutil',
|
||||
@ -40,10 +40,10 @@ setup(
|
||||
#tests_require=[
|
||||
# 'Django>=1.5',
|
||||
# 'django-celery',
|
||||
# 'django-devserver',
|
||||
# 'django-extensions',
|
||||
# 'django-filter',
|
||||
# 'django-jsonfield',
|
||||
# 'django-taggit',
|
||||
# 'django-setuptest',
|
||||
# 'djangorestframework',
|
||||
# 'pexpect',
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user