mirror of
https://github.com/ansible/awx.git
synced 2026-05-09 18:37:36 -02: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:
@@ -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())
|
||||
|
||||
Reference in New Issue
Block a user