mirror of
https://github.com/ansible/awx.git
synced 2026-03-05 02:31:03 -03:30
Merge pull request #276 from chrismeyersfsu/fix-fact_inventory_relationship
associate scan runs with a particular inventory host
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
# All Rights Reserved
|
||||
|
||||
from mongoengine.base import BaseField
|
||||
from mongoengine import Document, DateTimeField, ReferenceField, StringField
|
||||
from mongoengine import Document, DateTimeField, ReferenceField, StringField, IntField
|
||||
from awx.fact.utils.dbtransform import KeyTransform
|
||||
|
||||
key_transform = KeyTransform([('.', '\uff0E'), ('$', '\uff04')])
|
||||
@@ -22,22 +22,17 @@ class TransformField(BaseField):
|
||||
|
||||
class FactHost(Document):
|
||||
hostname = StringField(max_length=100, required=True, unique=True)
|
||||
inventory_id = IntField(required=True)
|
||||
|
||||
# TODO: Consider using hashed index on hostname. django-mongo may not support this but
|
||||
# executing raw js will
|
||||
meta = {
|
||||
'indexes': [
|
||||
'hostname'
|
||||
'hostname',
|
||||
'inventory_id'
|
||||
]
|
||||
}
|
||||
|
||||
@staticmethod
|
||||
def get_host_id(hostname):
|
||||
host = FactHost.objects.get(hostname=hostname)
|
||||
if host:
|
||||
return host.id
|
||||
return None
|
||||
|
||||
class Fact(Document):
|
||||
timestamp = DateTimeField(required=True)
|
||||
host = ReferenceField(FactHost, required=True)
|
||||
@@ -49,7 +44,7 @@ class Fact(Document):
|
||||
meta = {
|
||||
'indexes': [
|
||||
'-timestamp',
|
||||
'host'
|
||||
'host',
|
||||
]
|
||||
}
|
||||
|
||||
@@ -65,9 +60,9 @@ class Fact(Document):
|
||||
# If module not specified then filter query may return more than 1 result.
|
||||
# Thus, the resulting facts must somehow be unioned/concated/ or kept as an array.
|
||||
@staticmethod
|
||||
def get_host_version(hostname, timestamp, module):
|
||||
def get_host_version(hostname, inventory_id, timestamp, module):
|
||||
try:
|
||||
host = FactHost.objects.get(hostname=hostname)
|
||||
host = FactHost.objects.get(hostname=hostname, inventory_id=inventory_id)
|
||||
except FactHost.DoesNotExist:
|
||||
return None
|
||||
|
||||
@@ -86,9 +81,9 @@ class Fact(Document):
|
||||
return None
|
||||
|
||||
@staticmethod
|
||||
def get_host_timeline(hostname, module):
|
||||
def get_host_timeline(hostname, inventory_id, module):
|
||||
try:
|
||||
host = FactHost.objects.get(hostname=hostname)
|
||||
host = FactHost.objects.get(hostname=hostname, inventory_id=inventory_id)
|
||||
except FactHost.DoesNotExist:
|
||||
return None
|
||||
|
||||
@@ -99,6 +94,7 @@ class Fact(Document):
|
||||
|
||||
return FactVersion.objects.filter(**kv).order_by("-timestamp").values_list('timestamp')
|
||||
|
||||
# FIXME: single facts no longer works with the addition of the inventory_id field to the FactHost document
|
||||
@staticmethod
|
||||
def get_single_facts(hostnames, fact_key, fact_value, timestamp, module):
|
||||
kv = {
|
||||
|
||||
@@ -93,11 +93,13 @@ class BaseFactTestMixin(MongoDBRequired):
|
||||
class BaseFactTest(BaseFactTestMixin, MongoDBRequired):
|
||||
pass
|
||||
|
||||
# TODO: for now, we relate all hosts to a single inventory
|
||||
class FactScanBuilder(object):
|
||||
|
||||
def __init__(self):
|
||||
self.facts_data = {}
|
||||
self.hostname_data = []
|
||||
self.inventory_id = 1
|
||||
|
||||
self.host_objs = []
|
||||
self.fact_objs = []
|
||||
@@ -124,7 +126,7 @@ class FactScanBuilder(object):
|
||||
if len(self.hostname_data) == 0:
|
||||
self.hostname_data = ['hostname_%s' % i for i in range(0, host_count)]
|
||||
|
||||
self.host_objs = [FactHost(hostname=hostname).save() for hostname in self.hostname_data]
|
||||
self.host_objs = [FactHost(hostname=hostname, inventory_id=self.inventory_id).save() for hostname in self.hostname_data]
|
||||
|
||||
for i in range(0, scan_count):
|
||||
scan = {}
|
||||
@@ -186,6 +188,12 @@ class FactScanBuilder(object):
|
||||
|
||||
return [self.host_objs[i].hostname for i in range(index_start, index_end)]
|
||||
|
||||
def get_inventory_id(self):
|
||||
return self.inventory_id
|
||||
|
||||
def set_inventory_id(self, inventory_id):
|
||||
self.inventory_id = inventory_id
|
||||
|
||||
def get_host(self, index):
|
||||
return self.host_objs[index]
|
||||
|
||||
|
||||
@@ -16,19 +16,20 @@ __all__ = ['FactHostTest', 'FactTest', 'FactGetHostVersionTest', 'FactGetHostTim
|
||||
|
||||
class FactHostTest(BaseFactTest):
|
||||
def test_create_host(self):
|
||||
host = FactHost(hostname='hosty')
|
||||
host = FactHost(hostname='hosty', inventory_id=1)
|
||||
host.save()
|
||||
|
||||
host = FactHost.objects.get(hostname='hosty')
|
||||
host = FactHost.objects.get(hostname='hosty', inventory_id=1)
|
||||
self.assertIsNotNone(host, "Host added but not found")
|
||||
self.assertEqual('hosty', host.hostname, "Gotten record hostname does not match expected hostname")
|
||||
self.assertEqual(1, host.inventory_id, "Gotten record inventory_id does not match expected inventory_id")
|
||||
|
||||
# Ensure an error is raised for .get() that doesn't match a record.
|
||||
def test_get_host_id_no_result(self):
|
||||
host = FactHost(hostname='hosty')
|
||||
host = FactHost(hostname='hosty', inventory_id=1)
|
||||
host.save()
|
||||
|
||||
self.assertRaises(FactHost.DoesNotExist, FactHost.objects.get, hostname='doesnotexist')
|
||||
self.assertRaises(FactHost.DoesNotExist, FactHost.objects.get, hostname='doesnotexist', inventory_id=1)
|
||||
|
||||
class FactTest(BaseFactTest):
|
||||
def setUp(self):
|
||||
@@ -36,7 +37,7 @@ class FactTest(BaseFactTest):
|
||||
|
||||
def test_add_fact(self):
|
||||
timestamp = now().replace(microsecond=0)
|
||||
host = FactHost(hostname="hosty").save()
|
||||
host = FactHost(hostname="hosty", inventory_id=1).save()
|
||||
(f_obj, v_obj) = Fact.add_fact(host=host, timestamp=timestamp, module='packages', fact=TEST_FACT_PACKAGES)
|
||||
f = Fact.objects.get(id=f_obj.id)
|
||||
v = FactVersion.objects.get(id=v_obj.id)
|
||||
@@ -65,20 +66,20 @@ class FactGetHostVersionTest(BaseFactTest):
|
||||
|
||||
def test_get_host_version_exact_timestamp(self):
|
||||
fact_known = self.builder.get_scan(0, 'packages')[0]
|
||||
fact = Fact.get_host_version(hostname=self.builder.get_hostname(0), timestamp=self.builder.get_timestamp(0), module='packages')
|
||||
fact = Fact.get_host_version(hostname=self.builder.get_hostname(0), inventory_id=self.builder.get_inventory_id(), timestamp=self.builder.get_timestamp(0), module='packages')
|
||||
self.assertIsNotNone(fact)
|
||||
self.assertEqual(fact_known, fact)
|
||||
|
||||
def test_get_host_version_lte_timestamp(self):
|
||||
timestamp = self.builder.get_timestamp(0) + relativedelta(days=1)
|
||||
fact_known = self.builder.get_scan(0, 'packages')[0]
|
||||
fact = Fact.get_host_version(hostname=self.builder.get_hostname(0), timestamp=timestamp, module='packages')
|
||||
fact = Fact.get_host_version(hostname=self.builder.get_hostname(0), inventory_id=self.builder.get_inventory_id(), timestamp=timestamp, module='packages')
|
||||
self.assertIsNotNone(fact)
|
||||
self.assertEqual(fact_known, fact)
|
||||
|
||||
def test_get_host_version_none(self):
|
||||
timestamp = self.builder.get_timestamp(0) - relativedelta(years=20)
|
||||
fact = Fact.get_host_version(hostname=self.builder.get_hostname(0), timestamp=timestamp, module='packages')
|
||||
fact = Fact.get_host_version(hostname=self.builder.get_hostname(0), inventory_id=self.builder.get_inventory_id(), timestamp=timestamp, module='packages')
|
||||
self.assertIsNone(fact)
|
||||
|
||||
class FactGetHostTimelineTest(BaseFactTest):
|
||||
@@ -89,7 +90,7 @@ class FactGetHostTimelineTest(BaseFactTest):
|
||||
self.builder.build(scan_count=20, host_count=1)
|
||||
|
||||
def test_get_host_timeline_ok(self):
|
||||
timestamps = Fact.get_host_timeline(hostname=self.builder.get_hostname(0), module='packages')
|
||||
timestamps = Fact.get_host_timeline(hostname=self.builder.get_hostname(0), inventory_id=self.builder.get_inventory_id(), module='packages')
|
||||
self.assertIsNotNone(timestamps)
|
||||
self.assertEqual(len(timestamps), self.builder.get_scan_count())
|
||||
for i in range(0, self.builder.get_scan_count()):
|
||||
|
||||
@@ -62,12 +62,12 @@ class FactTransformTest(BaseFactTest):
|
||||
self.timestamp = datetime.now().replace(microsecond=0)
|
||||
|
||||
def setup_create_fact_dot(self):
|
||||
self.host = FactHost(hostname='hosty').save()
|
||||
self.host = FactHost(hostname='hosty', inventory_id=1).save()
|
||||
self.f = Fact(timestamp=self.timestamp, module='packages', fact=TEST_FACT_PACKAGES_WITH_DOTS, host=self.host)
|
||||
self.f.save()
|
||||
|
||||
def setup_create_fact_dollar(self):
|
||||
self.host = FactHost(hostname='hosty').save()
|
||||
self.host = FactHost(hostname='hosty', inventory_id=1).save()
|
||||
self.f = Fact(timestamp=self.timestamp, module='packages', fact=TEST_FACT_PACKAGES_WITH_DOLLARS, host=self.host)
|
||||
self.f.save()
|
||||
|
||||
@@ -85,7 +85,7 @@ class FactTransformTest(BaseFactTest):
|
||||
def test_fact_with_dot_serialized_pymongo(self):
|
||||
#self.setup_create_fact_dot()
|
||||
|
||||
host = FactHost(hostname='hosty').save()
|
||||
host = FactHost(hostname='hosty', inventory_id=1).save()
|
||||
f = self.db['fact'].insert({
|
||||
'hostname': 'hosty',
|
||||
'fact': TEST_FACT_PACKAGES_WITH_DOTS,
|
||||
|
||||
Reference in New Issue
Block a user