mirror of
https://github.com/ansible/awx.git
synced 2026-01-11 10:00:01 -03:30
AC-505 Initial inventory import models and API support.
This commit is contained in:
parent
44c6bca6f0
commit
b7d907ed49
@ -427,6 +427,45 @@ class GroupAccess(BaseAccess):
|
||||
return False
|
||||
return True
|
||||
|
||||
class InventorySourceAccess(BaseAccess):
|
||||
'''
|
||||
I can see inventory sources whenever I can see their group.
|
||||
I can change inventory sources whenever I can change their group.
|
||||
'''
|
||||
|
||||
model = InventorySource
|
||||
|
||||
def get_queryset(self):
|
||||
qs = self.model.objects.filter(active=True).distinct()
|
||||
qs = qs.select_related('created_by', 'group')
|
||||
groups_qs = self.user.get_queryset(Group)
|
||||
return qs.filter(group__in=groups_qs)
|
||||
|
||||
def can_read(self, obj):
|
||||
return obj and self.user.can_access(Group, 'read', obj.group)
|
||||
|
||||
def can_add(self, data):
|
||||
# Automatically created from group.
|
||||
return False
|
||||
|
||||
def can_change(self, obj, data):
|
||||
# Checks for admin or change permission on group.
|
||||
return obj and self.user.can_access(Group, 'change', obj.group, None)
|
||||
|
||||
class InventoryUpdateAccess(BaseAccess):
|
||||
'''
|
||||
I can see inventory updates when I can see the inventory source.
|
||||
I can change inventory updates whenever I can change their source.
|
||||
'''
|
||||
|
||||
model = InventoryUpdate
|
||||
|
||||
def get_queryset(self):
|
||||
qs = InventoryUpdate.objects.filter(active=True).distinct()
|
||||
qs = qs.select_related('created_by', 'group')
|
||||
inventory_sources_qs = self.user.get_queryset(InventorySource)
|
||||
return qs.filter(inventory_source__in=inventory_sources_qs)
|
||||
|
||||
class CredentialAccess(BaseAccess):
|
||||
'''
|
||||
I can see credentials when:
|
||||
@ -970,6 +1009,8 @@ register_access(Organization, OrganizationAccess)
|
||||
register_access(Inventory, InventoryAccess)
|
||||
register_access(Host, HostAccess)
|
||||
register_access(Group, GroupAccess)
|
||||
register_access(InventorySource, InventorySourceAccess)
|
||||
register_access(InventoryUpdate, InventoryUpdateAccess)
|
||||
register_access(Credential, CredentialAccess)
|
||||
register_access(Team, TeamAccess)
|
||||
register_access(Project, ProjectAccess)
|
||||
|
||||
@ -53,6 +53,7 @@ class APIView(views.APIView):
|
||||
return {
|
||||
'docstring': type(self).__doc__ or '',
|
||||
'new_in_13': getattr(self, 'new_in_13', False),
|
||||
'new_in_14': getattr(self, 'new_in_14', False),
|
||||
}
|
||||
|
||||
def get_description(self, html=False):
|
||||
|
||||
430
awx/main/migrations/0016_v14_changes.py
Normal file
430
awx/main/migrations/0016_v14_changes.py
Normal file
@ -0,0 +1,430 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
import datetime
|
||||
from south.db import db
|
||||
from south.v2 import SchemaMigration
|
||||
from django.db import models
|
||||
|
||||
|
||||
class Migration(SchemaMigration):
|
||||
|
||||
def forwards(self, orm):
|
||||
# Adding model 'InventoryUpdate'
|
||||
db.create_table(u'main_inventoryupdate', (
|
||||
(u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
|
||||
('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)),
|
||||
('modified', self.gf('django.db.models.fields.DateTimeField')(default=datetime.datetime.now, auto_now=True, blank=True)),
|
||||
('created_by', self.gf('django.db.models.fields.related.ForeignKey')(default=None, related_name="{'class': 'inventoryupdate', 'app_label': 'main'}(class)s_created+", null=True, on_delete=models.SET_NULL, to=orm['auth.User'])),
|
||||
('modified_by', self.gf('django.db.models.fields.related.ForeignKey')(default=None, related_name="{'class': 'inventoryupdate', 'app_label': 'main'}(class)s_modified+", null=True, on_delete=models.SET_NULL, to=orm['auth.User'])),
|
||||
('active', self.gf('django.db.models.fields.BooleanField')(default=True)),
|
||||
('inventory_source', self.gf('django.db.models.fields.related.ForeignKey')(related_name='inventory_updates', to=orm['main.InventorySource'])),
|
||||
('cancel_flag', self.gf('django.db.models.fields.BooleanField')(default=False)),
|
||||
('status', self.gf('django.db.models.fields.CharField')(default='new', max_length=20)),
|
||||
('failed', self.gf('django.db.models.fields.BooleanField')(default=False)),
|
||||
('job_args', self.gf('django.db.models.fields.TextField')(default='', blank=True)),
|
||||
('job_cwd', self.gf('django.db.models.fields.CharField')(default='', max_length=1024, blank=True)),
|
||||
('job_env', self.gf('jsonfield.fields.JSONField')(default={}, blank=True)),
|
||||
('result_stdout', self.gf('django.db.models.fields.TextField')(default='', blank=True)),
|
||||
('result_traceback', self.gf('django.db.models.fields.TextField')(default='', blank=True)),
|
||||
('celery_task_id', self.gf('django.db.models.fields.CharField')(default='', max_length=100, blank=True)),
|
||||
))
|
||||
db.send_create_signal('main', ['InventoryUpdate'])
|
||||
|
||||
# Adding model 'InventorySource'
|
||||
db.create_table(u'main_inventorysource', (
|
||||
(u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
|
||||
('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)),
|
||||
('modified', self.gf('django.db.models.fields.DateTimeField')(default=datetime.datetime.now, auto_now=True, blank=True)),
|
||||
('created_by', self.gf('django.db.models.fields.related.ForeignKey')(default=None, related_name="{'class': 'inventorysource', 'app_label': u'main'}(class)s_created+", null=True, on_delete=models.SET_NULL, to=orm['auth.User'])),
|
||||
('modified_by', self.gf('django.db.models.fields.related.ForeignKey')(default=None, related_name="{'class': 'inventorysource', 'app_label': u'main'}(class)s_modified+", null=True, on_delete=models.SET_NULL, to=orm['auth.User'])),
|
||||
('active', self.gf('django.db.models.fields.BooleanField')(default=True)),
|
||||
('group', self.gf('awx.main.fields.AutoOneToOneField')(related_name='inventory_source', unique=True, to=orm['main.Group'])),
|
||||
('source', self.gf('django.db.models.fields.CharField')(default='', max_length=32, blank=True)),
|
||||
('source_path', self.gf('django.db.models.fields.CharField')(default='', max_length=1024, blank=True)),
|
||||
('source_env', self.gf('django.db.models.fields.TextField')(default='', blank=True)),
|
||||
('source_username', self.gf('django.db.models.fields.CharField')(default='', max_length=1024, blank=True)),
|
||||
('source_password', self.gf('django.db.models.fields.CharField')(default='', max_length=1024, blank=True)),
|
||||
('source_regions', self.gf('django.db.models.fields.CharField')(default='', max_length=1024, blank=True)),
|
||||
('source_tags', self.gf('django.db.models.fields.CharField')(default='', max_length=1024, blank=True)),
|
||||
('overwrite_hosts', self.gf('django.db.models.fields.BooleanField')(default=False)),
|
||||
('overwrite_vars', self.gf('django.db.models.fields.BooleanField')(default=False)),
|
||||
('keep_vars', self.gf('django.db.models.fields.BooleanField')(default=False)),
|
||||
('update_on_launch', self.gf('django.db.models.fields.BooleanField')(default=False)),
|
||||
('current_update', self.gf('django.db.models.fields.related.ForeignKey')(default=None, related_name='inventory_source_as_current_update+', null=True, to=orm['main.InventoryUpdate'])),
|
||||
('last_update', self.gf('django.db.models.fields.related.ForeignKey')(default=None, related_name='inventory_source_as_last_update+', null=True, to=orm['main.InventoryUpdate'])),
|
||||
('last_update_failed', self.gf('django.db.models.fields.BooleanField')(default=False)),
|
||||
('last_updated', self.gf('django.db.models.fields.DateTimeField')(default=None, null=True)),
|
||||
('status', self.gf('django.db.models.fields.CharField')(default='none', max_length=32, null=True)),
|
||||
))
|
||||
db.send_create_signal(u'main', ['InventorySource'])
|
||||
|
||||
|
||||
def backwards(self, orm):
|
||||
# Deleting model 'InventoryUpdate'
|
||||
db.delete_table(u'main_inventoryupdate')
|
||||
|
||||
# Deleting model 'InventorySource'
|
||||
db.delete_table(u'main_inventorysource')
|
||||
|
||||
|
||||
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'})
|
||||
},
|
||||
u'main.authtoken': {
|
||||
'Meta': {'object_name': 'AuthToken'},
|
||||
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
|
||||
'expires': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
|
||||
'key': ('django.db.models.fields.CharField', [], {'max_length': '40', 'primary_key': 'True'}),
|
||||
'modified': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
|
||||
'request_hash': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '40', 'blank': 'True'}),
|
||||
'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'auth_tokens'", 'to': u"orm['auth.User']"})
|
||||
},
|
||||
'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', [], {'default': 'None', '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'}),
|
||||
'modified': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now', 'auto_now': 'True', 'blank': 'True'}),
|
||||
'modified_by': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'related_name': '"{\'class\': \'credential\', \'app_label\': \'main\'}(class)s_modified+"', 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': u"orm['auth.User']"}),
|
||||
'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', [], {'default': 'None', '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'}),
|
||||
'has_active_failures': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||
'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']"}),
|
||||
'modified': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now', 'auto_now': 'True', 'blank': 'True'}),
|
||||
'modified_by': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'related_name': '"{\'class\': \'group\', \'app_label\': \'main\'}(class)s_modified+"', 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': u"orm['auth.User']"}),
|
||||
'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', [], {'default': 'None', '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'}),
|
||||
'has_active_failures': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||
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'}),
|
||||
'modified': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now', 'auto_now': 'True', 'blank': 'True'}),
|
||||
'modified_by': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'related_name': '"{\'class\': \'host\', \'app_label\': \'main\'}(class)s_modified+"', 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': u"orm['auth.User']"}),
|
||||
'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', [], {'default': 'None', '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'}),
|
||||
'has_active_failures': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'modified': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now', 'auto_now': 'True', 'blank': 'True'}),
|
||||
'modified_by': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'related_name': '"{\'class\': \'inventory\', \'app_label\': \'main\'}(class)s_modified+"', 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': u"orm['auth.User']"}),
|
||||
'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']"}),
|
||||
'variables': ('django.db.models.fields.TextField', [], {'default': "''", 'null': 'True', 'blank': 'True'})
|
||||
},
|
||||
u'main.inventorysource': {
|
||||
'Meta': {'object_name': 'InventorySource'},
|
||||
'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', [], {'default': 'None', 'related_name': '"{\'class\': \'inventorysource\', \'app_label\': u\'main\'}(class)s_created+"', 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': u"orm['auth.User']"}),
|
||||
'current_update': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'related_name': "'inventory_source_as_current_update+'", 'null': 'True', 'to': "orm['main.InventoryUpdate']"}),
|
||||
'description': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}),
|
||||
'group': ('awx.main.fields.AutoOneToOneField', [], {'related_name': "'inventory_source'", 'unique': 'True', 'to': "orm['main.Group']"}),
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'keep_vars': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||
'last_update': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'related_name': "'inventory_source_as_last_update+'", 'null': 'True', 'to': "orm['main.InventoryUpdate']"}),
|
||||
'last_update_failed': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||
'last_updated': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}),
|
||||
'modified': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now', 'auto_now': 'True', 'blank': 'True'}),
|
||||
'modified_by': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'related_name': '"{\'class\': \'inventorysource\', \'app_label\': u\'main\'}(class)s_modified+"', 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': u"orm['auth.User']"}),
|
||||
'overwrite_hosts': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||
'overwrite_vars': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||
'source': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '32', 'blank': 'True'}),
|
||||
'source_env': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}),
|
||||
'source_password': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '1024', 'blank': 'True'}),
|
||||
'source_path': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '1024', 'blank': 'True'}),
|
||||
'source_regions': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '1024', 'blank': 'True'}),
|
||||
'source_tags': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '1024', 'blank': 'True'}),
|
||||
'source_username': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '1024', 'blank': 'True'}),
|
||||
'status': ('django.db.models.fields.CharField', [], {'default': "'none'", 'max_length': '32', 'null': 'True'}),
|
||||
'update_on_launch': ('django.db.models.fields.BooleanField', [], {'default': 'False'})
|
||||
},
|
||||
'main.inventoryupdate': {
|
||||
'Meta': {'object_name': 'InventoryUpdate'},
|
||||
'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', [], {'default': 'None', 'related_name': '"{\'class\': \'inventoryupdate\', \'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'}),
|
||||
'failed': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'inventory_source': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'inventory_updates'", 'to': u"orm['main.InventorySource']"}),
|
||||
'job_args': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}),
|
||||
'job_cwd': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '1024', 'blank': 'True'}),
|
||||
'job_env': ('jsonfield.fields.JSONField', [], {'default': '{}', 'blank': 'True'}),
|
||||
'modified': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now', 'auto_now': 'True', 'blank': 'True'}),
|
||||
'modified_by': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'related_name': '"{\'class\': \'inventoryupdate\', \'app_label\': \'main\'}(class)s_modified+"', 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': u"orm['auth.User']"}),
|
||||
'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'})
|
||||
},
|
||||
'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', [], {'default': 'None', '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.TextField', [], {'default': "''", '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'}),
|
||||
'launch_type': ('django.db.models.fields.CharField', [], {'default': "'manual'", 'max_length': '20'}),
|
||||
'limit': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '1024', 'blank': 'True'}),
|
||||
'modified': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now', 'auto_now': 'True', 'blank': 'True'}),
|
||||
'modified_by': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'related_name': '"{\'class\': \'job\', \'app_label\': \'main\'}(class)s_modified+"', 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': u"orm['auth.User']"}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'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'},
|
||||
'changed': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||
'created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now', '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']"}),
|
||||
'modified': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now', 'auto_now': 'True', 'blank': 'True'}),
|
||||
'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'}),
|
||||
'created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now', 'auto_now_add': 'True', 'blank': 'True'}),
|
||||
'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']"}),
|
||||
'modified': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now', 'auto_now': 'True', 'blank': 'True'}),
|
||||
'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', [], {'default': 'None', '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'}),
|
||||
'modified': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now', 'auto_now': 'True', 'blank': 'True'}),
|
||||
'modified_by': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'related_name': '"{\'class\': \'jobtemplate\', \'app_label\': \'main\'}(class)s_modified+"', 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': u"orm['auth.User']"}),
|
||||
'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', [], {'default': 'None', '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'}),
|
||||
'modified': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now', 'auto_now': 'True', 'blank': 'True'}),
|
||||
'modified_by': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'related_name': '"{\'class\': \'organization\', \'app_label\': \'main\'}(class)s_modified+"', 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': u"orm['auth.User']"}),
|
||||
'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', [], {'default': 'None', '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']"}),
|
||||
'modified': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now', 'auto_now': 'True', 'blank': 'True'}),
|
||||
'modified_by': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'related_name': '"{\'class\': \'permission\', \'app_label\': \'main\'}(class)s_modified+"', 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': u"orm['auth.User']"}),
|
||||
'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.profile': {
|
||||
'Meta': {'object_name': 'Profile'},
|
||||
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'ldap_dn': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '1024'}),
|
||||
'modified': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
|
||||
'user': ('awx.main.fields.AutoOneToOneField', [], {'related_name': "'profile'", 'unique': 'True', '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', [], {'default': 'None', 'related_name': '"{\'class\': \'project\', \'app_label\': u\'main\'}(class)s_created+"', 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': u"orm['auth.User']"}),
|
||||
'current_update': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'related_name': "'project_as_current_update+'", 'null': 'True', 'to': "orm['main.ProjectUpdate']"}),
|
||||
'description': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}),
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'last_update': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'related_name': "'project_as_last_update+'", 'null': 'True', 'to': "orm['main.ProjectUpdate']"}),
|
||||
'last_update_failed': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||
'last_updated': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}),
|
||||
'local_path': ('django.db.models.fields.CharField', [], {'max_length': '1024', 'blank': 'True'}),
|
||||
'modified': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now', 'auto_now': 'True', 'blank': 'True'}),
|
||||
'modified_by': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'related_name': '"{\'class\': \'project\', \'app_label\': u\'main\'}(class)s_modified+"', 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': u"orm['auth.User']"}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '512'}),
|
||||
'scm_branch': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '256', 'null': 'True', 'blank': 'True'}),
|
||||
'scm_clean': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||
'scm_delete_on_next_update': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||
'scm_delete_on_update': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||
'scm_key_data': ('django.db.models.fields.TextField', [], {'default': "''", 'null': 'True', 'blank': 'True'}),
|
||||
'scm_key_unlock': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '1024', 'null': 'True', 'blank': 'True'}),
|
||||
'scm_password': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '1024', 'null': 'True', 'blank': 'True'}),
|
||||
'scm_type': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '8', 'null': 'True', 'blank': 'True'}),
|
||||
'scm_update_on_launch': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||
'scm_url': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '1024', 'null': 'True', 'blank': 'True'}),
|
||||
'scm_username': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '256', 'null': 'True', 'blank': 'True'}),
|
||||
'status': ('django.db.models.fields.CharField', [], {'default': "'ok'", 'max_length': '32', 'null': 'True'})
|
||||
},
|
||||
'main.projectupdate': {
|
||||
'Meta': {'object_name': 'ProjectUpdate'},
|
||||
'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', [], {'default': 'None', 'related_name': '"{\'class\': \'projectupdate\', \'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'}),
|
||||
'failed': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'job_args': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}),
|
||||
'job_cwd': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '1024', 'blank': 'True'}),
|
||||
'job_env': ('jsonfield.fields.JSONField', [], {'default': '{}', 'blank': 'True'}),
|
||||
'modified': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now', 'auto_now': 'True', 'blank': 'True'}),
|
||||
'modified_by': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'related_name': '"{\'class\': \'projectupdate\', \'app_label\': \'main\'}(class)s_modified+"', 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': u"orm['auth.User']"}),
|
||||
'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'project_updates'", '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'})
|
||||
},
|
||||
'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', [], {'default': 'None', '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'}),
|
||||
'modified': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now', 'auto_now': 'True', 'blank': 'True'}),
|
||||
'modified_by': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'related_name': '"{\'class\': \'team\', \'app_label\': \'main\'}(class)s_modified+"', 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': u"orm['auth.User']"}),
|
||||
'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']
|
||||
@ -40,8 +40,8 @@ from awx.main.utils import encrypt_field, decrypt_field
|
||||
|
||||
__all__ = ['PrimordialModel', 'Organization', 'Team', 'Project',
|
||||
'ProjectUpdate', 'Credential', 'Inventory', 'Host', 'Group',
|
||||
'Permission', 'JobTemplate', 'Job', 'JobHostSummary', 'JobEvent',
|
||||
'AuthToken',
|
||||
'InventorySource', 'InventoryUpdate', 'Permission', 'JobTemplate',
|
||||
'Job', 'JobHostSummary', 'JobEvent', 'AuthToken',
|
||||
'PERM_INVENTORY_ADMIN', 'PERM_INVENTORY_READ',
|
||||
'PERM_INVENTORY_WRITE', 'PERM_INVENTORY_DEPLOY',
|
||||
'PERM_INVENTORY_CHECK', 'JOB_STATUS_CHOICES']
|
||||
@ -254,6 +254,14 @@ class Host(CommonModelNameNotUnique):
|
||||
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+')
|
||||
has_active_failures = models.BooleanField(default=False, editable=False)
|
||||
|
||||
# FIXME: Track which inventory source(s) created this host.
|
||||
#inventory_sources = models.ManyToManyField(
|
||||
# 'InventorySource',
|
||||
# related_name='synced_hosts',
|
||||
# blank=True,
|
||||
# editable=False,
|
||||
#)
|
||||
|
||||
def __unicode__(self):
|
||||
return self.name
|
||||
|
||||
@ -317,6 +325,14 @@ class Group(CommonModelNameNotUnique):
|
||||
hosts = models.ManyToManyField('Host', related_name='groups', blank=True)
|
||||
has_active_failures = models.BooleanField(default=False, editable=False)
|
||||
|
||||
# FIXME: Track which inventory source(s) created this group.
|
||||
#inventory_sources = models.ManyToManyField(
|
||||
# 'InventorySource',
|
||||
# related_name='synced_groups',
|
||||
# blank=True,
|
||||
# editable=False,
|
||||
#)
|
||||
|
||||
def __unicode__(self):
|
||||
return self.name
|
||||
|
||||
@ -407,6 +423,341 @@ class Group(CommonModelNameNotUnique):
|
||||
def job_events(self):
|
||||
return JobEvent.objects.filter(host__in=self.all_hosts)
|
||||
|
||||
class InventorySource(PrimordialModel):
|
||||
|
||||
# FIXME: Track inventory source for import via management command?
|
||||
|
||||
SOURCE_CHOICES = [
|
||||
('file', _('Local File or Script')),
|
||||
('rackspace', _('Rackspace Cloud Servers')),
|
||||
('ec2', _('Amazon EC2')),
|
||||
]
|
||||
|
||||
PASSWORD_FIELDS = ('source_password',)
|
||||
|
||||
INVENTORY_SOURCE_STATUS_CHOICES = [
|
||||
('none', _('No External Source')),
|
||||
('never updated', _('Never Updated')),
|
||||
('updating', _('Updating')),
|
||||
('failed', _('Failed')),
|
||||
('successful', _('Successful')),
|
||||
]
|
||||
|
||||
group = AutoOneToOneField(
|
||||
'Group',
|
||||
related_name='inventory_source',
|
||||
editable=False,
|
||||
)
|
||||
source = models.CharField(
|
||||
max_length=32,
|
||||
choices=SOURCE_CHOICES,
|
||||
blank=True,
|
||||
default='',
|
||||
)
|
||||
source_path = models.CharField(
|
||||
max_length=1024,
|
||||
blank=True,
|
||||
default='',
|
||||
)
|
||||
source_env = models.TextField(
|
||||
blank=True,
|
||||
default='',
|
||||
)
|
||||
source_username = models.CharField(
|
||||
max_length=1024,
|
||||
blank=True,
|
||||
default='',
|
||||
)
|
||||
source_password = models.CharField(
|
||||
max_length=1024,
|
||||
blank=True,
|
||||
default='',
|
||||
)
|
||||
source_regions = models.CharField(
|
||||
max_length=1024,
|
||||
blank=True,
|
||||
default='',
|
||||
)
|
||||
source_tags = models.CharField(
|
||||
max_length=1024,
|
||||
blank=True,
|
||||
default='',
|
||||
)
|
||||
overwrite_hosts = models.BooleanField(
|
||||
default=False,
|
||||
)
|
||||
overwrite_vars = models.BooleanField(
|
||||
default=False,
|
||||
)
|
||||
keep_vars = models.BooleanField(
|
||||
default=False,
|
||||
)
|
||||
update_on_launch = models.BooleanField(
|
||||
default=False,
|
||||
)
|
||||
current_update = models.ForeignKey(
|
||||
'InventoryUpdate',
|
||||
null=True,
|
||||
default=None,
|
||||
editable=False,
|
||||
related_name='inventory_source_as_current_update+',
|
||||
)
|
||||
last_update = models.ForeignKey(
|
||||
'InventoryUpdate',
|
||||
null=True,
|
||||
default=None,
|
||||
editable=False,
|
||||
related_name='inventory_source_as_last_update+',
|
||||
)
|
||||
last_update_failed = models.BooleanField(
|
||||
default=False,
|
||||
editable=False,
|
||||
)
|
||||
last_updated = models.DateTimeField(
|
||||
null=True,
|
||||
default=None,
|
||||
editable=False,
|
||||
)
|
||||
status = models.CharField(
|
||||
max_length=32,
|
||||
choices=INVENTORY_SOURCE_STATUS_CHOICES,
|
||||
default='none',
|
||||
editable=False,
|
||||
null=True,
|
||||
)
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
new_instance = not bool(self.pk)
|
||||
# If update_fields has been specified, add our field names to it,
|
||||
# if it hasn't been specified, then we're just doing a normal save.
|
||||
update_fields = kwargs.get('update_fields', [])
|
||||
# When first saving to the database, don't store any password field
|
||||
# values, but instead save them until after the instance is created.
|
||||
if new_instance:
|
||||
for field in self.PASSWORD_FIELDS:
|
||||
value = getattr(self, field, '')
|
||||
setattr(self, '_saved_%s' % field, value)
|
||||
setattr(self, field, '')
|
||||
# Otherwise, store encrypted values to the database.
|
||||
else:
|
||||
for field in self.PASSWORD_FIELDS:
|
||||
encrypted = encrypt_field(self, field, True)
|
||||
if getattr(self, field) != encrypted:
|
||||
setattr(self, field, encrypted)
|
||||
if field not in update_fields:
|
||||
update_fields.append(field)
|
||||
# Update status and last_updated fields.
|
||||
updated_fields = self.set_status_and_last_updated(save=False)
|
||||
for field in updated_fields:
|
||||
if field not in update_fields:
|
||||
update_fields.append(field)
|
||||
# Do the actual save.
|
||||
super(InventorySource, self).save(*args, **kwargs)
|
||||
# After saving a new instance for the first time (to get a primary
|
||||
# key), set the password fields and save again.
|
||||
if new_instance:
|
||||
update_fields=[]
|
||||
for field in self.PASSWORD_FIELDS:
|
||||
saved_value = getattr(self, '_saved_%s' % field, '')
|
||||
if getattr(self, field) != saved_value:
|
||||
setattr(self, field, saved_value)
|
||||
update_fields.append(field)
|
||||
if update_fields:
|
||||
self.save(update_fields=update_fields)
|
||||
|
||||
@property
|
||||
def needs_source_password(self):
|
||||
return self.source and self.source_password == 'ASK'
|
||||
|
||||
@property
|
||||
def source_passwords_needed(self):
|
||||
needed = []
|
||||
for field in ('source_password',):
|
||||
if getattr(self, 'needs_%s' % field):
|
||||
needed.append(field)
|
||||
return needed
|
||||
|
||||
def set_status_and_last_updated(self, save=True):
|
||||
# Determine current status.
|
||||
if self.source:
|
||||
if self.current_update:
|
||||
status = 'updating'
|
||||
elif not self.last_update:
|
||||
status = 'never updated'
|
||||
elif self.last_update_failed:
|
||||
status = 'failed'
|
||||
else:
|
||||
status = 'successful'
|
||||
else:
|
||||
status = 'none'
|
||||
# Determine current last_updated timestamp.
|
||||
last_updated = None
|
||||
if self.source and self.last_update:
|
||||
last_updated = self.last_update.modified
|
||||
# Update values if changed.
|
||||
update_fields = []
|
||||
if self.status != status:
|
||||
self.status = status
|
||||
update_fields.append('status')
|
||||
if self.last_updated != last_updated:
|
||||
self.last_updated = last_updated
|
||||
update_fields.append('last_updated')
|
||||
if save and update_fields:
|
||||
self.save(update_fields=update_fields)
|
||||
return update_fields
|
||||
|
||||
@property
|
||||
def can_update(self):
|
||||
# FIXME: Prevent update when another one is active!
|
||||
return bool(self.source)
|
||||
|
||||
def update(self, **kwargs):
|
||||
if self.can_update:
|
||||
needed = self.source_passwords_needed
|
||||
opts = dict([(field, kwargs.get(field, '')) for field in needed])
|
||||
if not all(opts.values()):
|
||||
return
|
||||
inventory_update = self.inventory_updates.create()
|
||||
inventory_update.start(**opts)
|
||||
return inventory_update
|
||||
|
||||
def get_absolute_url(self):
|
||||
return reverse('main:inventory_source_detail', args=(self.pk,))
|
||||
|
||||
class InventoryUpdate(PrimordialModel):
|
||||
'''
|
||||
Internal job for tracking inventory updates from external sources.
|
||||
'''
|
||||
|
||||
class Meta:
|
||||
app_label = 'main'
|
||||
|
||||
inventory_source = models.ForeignKey(
|
||||
'InventorySource',
|
||||
related_name='inventory_updates',
|
||||
on_delete=models.CASCADE,
|
||||
editable=False,
|
||||
)
|
||||
cancel_flag = models.BooleanField(
|
||||
blank=True,
|
||||
default=False,
|
||||
editable=False,
|
||||
)
|
||||
status = models.CharField(
|
||||
max_length=20,
|
||||
choices=JOB_STATUS_CHOICES,
|
||||
default='new',
|
||||
editable=False,
|
||||
)
|
||||
failed = models.BooleanField(
|
||||
default=False,
|
||||
editable=False,
|
||||
)
|
||||
job_args = models.TextField(
|
||||
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='',
|
||||
editable=False,
|
||||
)
|
||||
result_traceback = models.TextField(
|
||||
blank=True,
|
||||
default='',
|
||||
editable=False,
|
||||
)
|
||||
celery_task_id = models.CharField(
|
||||
max_length=100,
|
||||
blank=True,
|
||||
default='',
|
||||
editable=False,
|
||||
)
|
||||
|
||||
def __unicode__(self):
|
||||
return u'%s-%s-%s' % (self.created, self.id, self.status)
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
# Get status before save...
|
||||
status_before = self.status or 'new'
|
||||
if self.pk:
|
||||
inventory_update_before = InventoryUpdate.objects.get(pk=self.pk)
|
||||
if inventory_update_before.status != self.status:
|
||||
status_before = inventory_update_before.status
|
||||
self.failed = bool(self.status in ('failed', 'error', 'canceled'))
|
||||
super(InventoryUpdate, self).save(*args, **kwargs)
|
||||
# If status changed, update inventory.
|
||||
if self.status != status_before:
|
||||
if self.status in ('pending', 'waiting', 'running'):
|
||||
inventory_source = self.inventory_source
|
||||
if inventory_source.current_update != self:
|
||||
inventory_source.current_update = self
|
||||
inventory_source.save(update_fields=['current_update'])
|
||||
elif self.status in ('successful', 'failed', 'error', 'canceled'):
|
||||
inventory_source = self.inventory_source
|
||||
if inventory_source.current_update == self:
|
||||
inventory_source.current_update = None
|
||||
inventory_source.last_update = self
|
||||
inventory_source.last_update_failed = self.failed
|
||||
inventory_source.save(update_fields=['current_update', 'last_update',
|
||||
'last_update_failed'])
|
||||
|
||||
def get_absolute_url(self):
|
||||
return reverse('main:inventory_update_detail', args=(self.pk,))
|
||||
|
||||
@property
|
||||
def celery_task(self):
|
||||
try:
|
||||
if self.celery_task_id:
|
||||
return TaskMeta.objects.get(task_id=self.celery_task_id)
|
||||
except TaskMeta.DoesNotExist:
|
||||
pass
|
||||
|
||||
@property
|
||||
def can_start(self):
|
||||
return bool(self.status == 'new')
|
||||
|
||||
def start(self, **kwargs):
|
||||
from awx.main.tasks import RunInventoryUpdate
|
||||
needed = self.inventory_source.source_passwords_needed
|
||||
opts = dict([(field, kwargs.get(field, '')) for field in needed])
|
||||
if not all(opts.values()):
|
||||
return False
|
||||
self.status = 'pending'
|
||||
self.save(update_fields=['status'])
|
||||
task_result = RunInventoryUpdate().delay(self.pk, **opts)
|
||||
# Reload inventory update from database so we don't clobber results
|
||||
# from RunInventoryUpdate (mainly from tests when using Django 1.4.x).
|
||||
inventory_update = InventoryUpdate.objects.get(pk=self.pk)
|
||||
# The TaskMeta instance in the database isn't created until the worker
|
||||
# starts processing the task, so we can only store the task ID here.
|
||||
inventory_update.celery_task_id = task_result.task_id
|
||||
inventory_update.save(update_fields=['celery_task_id'])
|
||||
return True
|
||||
|
||||
@property
|
||||
def can_cancel(self):
|
||||
return bool(self.status in ('pending', 'waiting', 'running'))
|
||||
|
||||
def cancel(self):
|
||||
if self.can_cancel:
|
||||
if not self.cancel_flag:
|
||||
self.cancel_flag = True
|
||||
self.save(update_fields=['cancel_flag'])
|
||||
return self.cancel_flag
|
||||
|
||||
class Credential(CommonModelNameNotUnique):
|
||||
'''
|
||||
A credential contains information about how to talk to a remote set of hosts
|
||||
|
||||
@ -488,6 +488,7 @@ class GroupSerializer(BaseSerializerWithVariables):
|
||||
inventory = reverse('main:inventory_detail', args=(obj.inventory.pk,)),
|
||||
job_events = reverse('main:group_job_events_list', args=(obj.pk,)),
|
||||
job_host_summaries = reverse('main:group_job_host_summaries_list', args=(obj.pk,)),
|
||||
inventory_source = reverse('main:inventory_source_detail', args=(obj.inventory_source.pk,)),
|
||||
))
|
||||
return res
|
||||
|
||||
@ -541,6 +542,67 @@ class GroupVariableDataSerializer(BaseVariableDataSerializer):
|
||||
model = Group
|
||||
fields = ('variables',)
|
||||
|
||||
class InventorySourceSerializer(BaseSerializer):
|
||||
|
||||
source_password = serializers.WritableField(required=False, default='')
|
||||
|
||||
class Meta:
|
||||
model = InventorySource
|
||||
fields = ('id', 'url', 'related', 'summary_fields', 'created',
|
||||
'modified', 'group', 'source', 'source_path', 'source_env',
|
||||
'source_username', 'source_password', 'source_regions',
|
||||
'source_tags', 'overwrite_hosts', 'overwrite_vars',
|
||||
'keep_vars', 'update_on_launch', 'last_update_failed',
|
||||
'status', 'last_updated')
|
||||
|
||||
def to_native(self, obj):
|
||||
ret = super(InventorySourceSerializer, self).to_native(obj)
|
||||
# Replace the actual encrypted value with the string $encrypted$.
|
||||
for field in InventorySource.PASSWORD_FIELDS:
|
||||
if field in ret and unicode(ret[field]).startswith('$encrypted$'):
|
||||
ret[field] = '$encrypted$'
|
||||
return ret
|
||||
|
||||
def restore_object(self, attrs, instance=None):
|
||||
# If the value sent to the API startswith $encrypted$, ignore it.
|
||||
for field in InventorySource.PASSWORD_FIELDS:
|
||||
if unicode(attrs.get(field, '')).startswith('$encrypted$'):
|
||||
attrs.pop(field, None)
|
||||
instance = super(InventorySourceSerializer, self).restore_object(attrs, instance)
|
||||
return instance
|
||||
|
||||
def get_related(self, obj):
|
||||
res = super(InventorySourceSerializer, self).get_related(obj)
|
||||
res.update(dict(
|
||||
group = reverse('main:group_detail', args=(obj.group.pk,)),
|
||||
update = reverse('main:inventory_source_update_view', args=(obj.pk,)),
|
||||
inventory_updates = reverse('main:inventory_source_updates_list', args=(obj.pk,)),
|
||||
))
|
||||
if obj.current_update:
|
||||
res['current_update'] = reverse('main:inventory_update_detail',
|
||||
args=(obj.current_update.pk,))
|
||||
if obj.last_update:
|
||||
res['last_update'] = reverse('main:inventory_update_detail',
|
||||
args=(obj.last_update.pk,))
|
||||
return res
|
||||
|
||||
class InventoryUpdateSerializer(BaseSerializer):
|
||||
|
||||
class Meta:
|
||||
model = InventoryUpdate
|
||||
fields = ('id', 'url', 'related', 'summary_fields', 'created',
|
||||
'modified', 'inventory_source', 'status', 'failed',
|
||||
'result_stdout', 'result_traceback', 'job_args', 'job_cwd',
|
||||
'job_env')
|
||||
|
||||
def get_related(self, obj):
|
||||
res = super(InventoryUpdateSerializer, self).get_related(obj)
|
||||
res.update(dict(
|
||||
inventory_source = reverse('main:inventory_source_detail', args=(obj.inventory_source.pk,)),
|
||||
cancel = reverse('main:inventory_update_cancel', args=(obj.pk,)),
|
||||
))
|
||||
return res
|
||||
|
||||
class TeamSerializer(BaseSerializer):
|
||||
|
||||
class Meta:
|
||||
|
||||
@ -27,10 +27,10 @@ from django.conf import settings
|
||||
from django.utils.timezone import now
|
||||
|
||||
# AWX
|
||||
from awx.main.models import Job, ProjectUpdate
|
||||
from awx.main.models import Job, ProjectUpdate, InventoryUpdate
|
||||
from awx.main.utils import get_ansible_version, decrypt_field, update_scm_url
|
||||
|
||||
__all__ = ['RunJob', 'RunProjectUpdate']
|
||||
__all__ = ['RunJob', 'RunProjectUpdate', 'RunInventoryImport']
|
||||
|
||||
logger = logging.getLogger('awx.main.tasks')
|
||||
|
||||
@ -231,12 +231,12 @@ class BaseTask(Task):
|
||||
Run the job/task using ansible-playbook and capture its output.
|
||||
'''
|
||||
instance = self.update_model(pk)
|
||||
if not self.pre_run_check(instance, **kwargs):
|
||||
return
|
||||
instance = self.update_model(pk, status='running')
|
||||
status, stdout, tb = 'error', '', ''
|
||||
output_replacements = []
|
||||
try:
|
||||
if not self.pre_run_check(instance, **kwargs):
|
||||
return
|
||||
instance = self.update_model(pk, status='running')
|
||||
kwargs['ssh_key_path'] = self.build_ssh_key_path(instance, **kwargs)
|
||||
kwargs['passwords'] = self.build_passwords(instance, **kwargs)
|
||||
args = self.build_args(instance, **kwargs)
|
||||
@ -322,7 +322,8 @@ class RunJob(BaseTask):
|
||||
# it doesn't make sense to rely on ansible-playbook's default of using
|
||||
# the current user.
|
||||
ssh_username = ssh_username or 'root'
|
||||
inventory_script = self.get_path_to('..', 'scripts', 'inventory.py')
|
||||
inventory_script = self.get_path_to('..', 'plugins', 'inventory',
|
||||
'awx.py')
|
||||
args = ['ansible-playbook', '-i', inventory_script]
|
||||
if job.job_type == 'check':
|
||||
args.append('--check')
|
||||
@ -622,3 +623,26 @@ class RunProjectUpdate(BaseTask):
|
||||
return False
|
||||
else:
|
||||
return False
|
||||
|
||||
class RunInventoryUpdate(BaseTask):
|
||||
|
||||
name = 'run_inventory_update'
|
||||
model = InventoryUpdate
|
||||
|
||||
def build_env(self, inventory_update, **kwargs):
|
||||
'''
|
||||
Build environment dictionary for inventory import.
|
||||
'''
|
||||
env = super(RunInventoryUpdate, self).build_env(inventory_update, **kwargs)
|
||||
# FIXME
|
||||
return env
|
||||
|
||||
def build_args(self, inventory_update, **kwargs):
|
||||
'''
|
||||
Build command line argument list for running inventory import.
|
||||
'''
|
||||
# FIXME
|
||||
return ['echo', 'FIXME']
|
||||
|
||||
def build_cwd(self, inventory_update, **kwargs):
|
||||
return self.get_path_to('..', 'plugins', 'inventory')
|
||||
|
||||
@ -575,8 +575,8 @@ class InventoryImportTest(BaseCommandMixin, BaseLiveServerTest):
|
||||
#os.environ.setdefault('REST_API_TOKEN',
|
||||
# self.super_django_user.auth_token.key)
|
||||
os.environ['INVENTORY_ID'] = str(old_inv.pk)
|
||||
source = os.path.join(os.path.dirname(__file__), '..', '..', 'scripts',
|
||||
'inventory.py')
|
||||
source = os.path.join(os.path.dirname(__file__), '..', '..', 'plugins',
|
||||
'inventory', 'awx.py')
|
||||
result, stdout, stderr = self.run_command('inventory_import',
|
||||
inventory_id=new_inv.pk,
|
||||
source=source)
|
||||
|
||||
@ -130,8 +130,8 @@ class InventoryScriptTest(BaseScriptTest):
|
||||
os.environ.setdefault('REST_API_URL', rest_api_url)
|
||||
#os.environ.setdefault('REST_API_TOKEN',
|
||||
# self.super_django_user.auth_token.key)
|
||||
name = os.path.join(os.path.dirname(__file__), '..', '..', 'scripts',
|
||||
'inventory.py')
|
||||
name = os.path.join(os.path.dirname(__file__), '..', '..', 'plugins',
|
||||
'inventory', 'awx.py')
|
||||
return self.run_script(name, *args, **options)
|
||||
|
||||
def test_without_inventory_id(self):
|
||||
|
||||
@ -86,6 +86,17 @@ group_urls = patterns('awx.main.views',
|
||||
url(r'^(?P<pk>[0-9]+)/job_host_summaries/$', 'group_job_host_summaries_list'),
|
||||
)
|
||||
|
||||
inventory_source_urls = patterns('awx.main.views',
|
||||
url(r'^(?P<pk>[0-9]+)/$', 'inventory_source_detail'),
|
||||
url(r'^(?P<pk>[0-9]+)/update/$', 'inventory_source_update_view'),
|
||||
url(r'^(?P<pk>[0-9]+)/inventory_updates/$', 'inventory_source_updates_list'),
|
||||
)
|
||||
|
||||
inventory_update_urls = patterns('awx.main.views',
|
||||
url(r'^(?P<pk>[0-9]+)/$', 'inventory_update_detail'),
|
||||
url(r'^(?P<pk>[0-9]+)/cancel/$', 'inventory_update_cancel'),
|
||||
)
|
||||
|
||||
credential_urls = patterns('awx.main.views',
|
||||
url(r'^$', 'credential_list'),
|
||||
url(r'^(?P<pk>[0-9]+)/$', 'credential_detail'),
|
||||
@ -136,6 +147,8 @@ v1_urls = patterns('awx.main.views',
|
||||
url(r'^inventories/', include(inventory_urls)),
|
||||
url(r'^hosts/', include(host_urls)),
|
||||
url(r'^groups/', include(group_urls)),
|
||||
url(r'^inventory_sources/', include(inventory_source_urls)),
|
||||
url(r'^inventory_updates/', include(inventory_update_urls)),
|
||||
url(r'^credentials/', include(credential_urls)),
|
||||
url(r'^permissions/', include(permission_urls)),
|
||||
url(r'^job_templates/', include(job_template_urls)),
|
||||
|
||||
@ -680,6 +680,74 @@ class InventoryTreeView(RetrieveAPIView):
|
||||
})
|
||||
return d
|
||||
|
||||
class InventorySourceDetail(RetrieveUpdateAPIView):
|
||||
|
||||
model = InventorySource
|
||||
serializer_class = InventorySourceSerializer
|
||||
new_in_14 = True
|
||||
|
||||
class InventorySourceUpdatesList(SubListAPIView):
|
||||
|
||||
model = InventoryUpdate
|
||||
serializer_class = InventoryUpdateSerializer
|
||||
parent_model = InventorySource
|
||||
relationship = 'inventory_updates'
|
||||
new_in_14 = True
|
||||
|
||||
class InventorySourceUpdateView(GenericAPIView):
|
||||
|
||||
model = InventorySource
|
||||
new_in_14 = True
|
||||
|
||||
def get(self, request, *args, **kwargs):
|
||||
obj = self.get_object()
|
||||
data = dict(
|
||||
can_update=obj.can_update,
|
||||
)
|
||||
if obj.source:
|
||||
data['passwords_needed_to_update'] = obj.source_passwords_needed
|
||||
return Response(data)
|
||||
|
||||
def post(self, request, *args, **kwargs):
|
||||
obj = self.get_object()
|
||||
if obj.can_update:
|
||||
inventory_update = obj.update(**request.DATA)
|
||||
if not inventory_update:
|
||||
data = dict(passwords_needed_to_update=obj.source_passwords_needed)
|
||||
return Response(data, status=status.HTTP_400_BAD_REQUEST)
|
||||
else:
|
||||
headers = {'Location': inventory_update.get_absolute_url()}
|
||||
return Response(status=status.HTTP_202_ACCEPTED, headers=headers)
|
||||
else:
|
||||
return self.http_method_not_allowed(request, *args, **kwargs)
|
||||
|
||||
class InventoryUpdateDetail(RetrieveAPIView):
|
||||
|
||||
model = InventoryUpdate
|
||||
serializer_class = InventoryUpdateSerializer
|
||||
new_in_14 = True
|
||||
|
||||
class InventoryUpdateCancel(GenericAPIView):
|
||||
|
||||
model = InventoryUpdate
|
||||
is_job_cancel = True
|
||||
new_in_14 = True
|
||||
|
||||
def get(self, request, *args, **kwargs):
|
||||
obj = self.get_object()
|
||||
data = dict(
|
||||
can_cancel=obj.can_cancel,
|
||||
)
|
||||
return Response(data)
|
||||
|
||||
def post(self, request, *args, **kwargs):
|
||||
obj = self.get_object()
|
||||
if obj.can_cancel:
|
||||
result = obj.cancel()
|
||||
return Response(status=status.HTTP_202_ACCEPTED)
|
||||
else:
|
||||
return self.http_method_not_allowed(request, *args, **kwargs)
|
||||
|
||||
class JobTemplateList(ListCreateAPIView):
|
||||
|
||||
model = JobTemplate
|
||||
|
||||
@ -45,9 +45,10 @@ try:
|
||||
except ImportError:
|
||||
# If running from an AWX installation, use the local version of requests if
|
||||
# if cannot be found globally.
|
||||
local_site_packages = os.path.join(os.path.dirname(__file__), '..', 'lib',
|
||||
'site-packages')
|
||||
sys.path.insert(0, local_site_packages)
|
||||
local_site_packages = os.path.join(os.path.dirname(__file__), '..', '..',
|
||||
'lib', 'site-packages')
|
||||
if os.path.exists(local_site_packages):
|
||||
sys.path.insert(0, local_site_packages)
|
||||
import requests
|
||||
|
||||
class TokenAuth(requests.auth.AuthBase):
|
||||
@ -121,9 +122,6 @@ class InventoryScript(object):
|
||||
except Exception, e:
|
||||
# Always return an empty hash on stdout, even when an error occurs.
|
||||
sys.stdout.write(json.dumps({}))
|
||||
#print >> file(os.path.join(os.path.dirname(__file__), 'foo.log'), 'a'), repr(e)
|
||||
#if hasattr(e, 'response'):
|
||||
# print >> file(os.path.join(os.path.dirname(__file__), 'foo.log'), 'a'), e.response.content
|
||||
if self.options.get('traceback', False):
|
||||
raise
|
||||
sys.stderr.write(str(e) + '\n')
|
||||
Loading…
x
Reference in New Issue
Block a user