diff --git a/awx/api/serializers.py b/awx/api/serializers.py index 5cc40b4e65..27002c2c52 100644 --- a/awx/api/serializers.py +++ b/awx/api/serializers.py @@ -2088,7 +2088,7 @@ class JobOptionsSerializer(LabelsListMixin, BaseSerializer): fields = ('*', 'job_type', 'inventory', 'project', 'playbook', 'credential', 'cloud_credential', 'network_credential', 'forks', 'limit', 'verbosity', 'extra_vars', 'job_tags', 'force_handlers', - 'skip_tags', 'start_at_task', 'timeout') + 'skip_tags', 'start_at_task', 'timeout', 'gather_facts',) def get_related(self, obj): res = super(JobOptionsSerializer, self).get_related(obj) diff --git a/awx/main/management/commands/run_fact_cache_receiver.py b/awx/main/management/commands/run_fact_cache_receiver.py index d4dd479090..418f5ac601 100644 --- a/awx/main/management/commands/run_fact_cache_receiver.py +++ b/awx/main/management/commands/run_fact_cache_receiver.py @@ -111,7 +111,7 @@ class FactBrokerWorker(ConsumerMixin): analytics_logger.info('Received message with fact data', extra=dict( module_name=module_name, facts_data=facts)) ret = fact_obj - else: + if job.gather_facts is True: host_obj.update_ansible_facts(module=module_name, facts=facts, timestamp=self.timestamp) message.ack() diff --git a/awx/main/migrations/0038_v320_release.py b/awx/main/migrations/0038_v320_release.py index 60c38009e2..4f46938a49 100644 --- a/awx/main/migrations/0038_v320_release.py +++ b/awx/main/migrations/0038_v320_release.py @@ -48,10 +48,21 @@ class Migration(migrations.Migration): name='ansible_facts', field=awx.main.fields.JSONBField(default={}, help_text='Arbitrary JSON structure of most recent ansible_facts, per-host.', blank=True), ), + migrations.AddField( + model_name='job', + name='gather_facts', + field=models.BooleanField(default=False), + ), + migrations.AddField( + model_name='jobtemplate', + name='gather_facts', + field=models.BooleanField(default=False), + ), migrations.RunSQL([("CREATE INDEX host_ansible_facts_default_gin ON %s USING gin" "(ansible_facts jsonb_path_ops);", [AsIs(Host._meta.db_table)])], [('DROP INDEX host_ansible_facts_default_gin;', None)]), + # SCM file-based inventories migrations.AddField( model_name='inventorysource', diff --git a/awx/main/models/fact.py b/awx/main/models/fact.py index 28ba767e3e..984cd9e985 100644 --- a/awx/main/models/fact.py +++ b/awx/main/models/fact.py @@ -7,7 +7,6 @@ from django.db import models from django.utils.translation import ugettext_lazy as _ from awx.main.fields import JSONBField -from awx.main.models import Host __all__ = ('Fact',) @@ -65,14 +64,6 @@ class Fact(models.Model): @staticmethod def add_fact(host_id, module, timestamp, facts): - try: - host = Host.objects.get(id=host_id) - except Host.DoesNotExist as e: - logger.warn("Host with id %s not found while trying to update latest fact set." % host_id) - raise e - - host.update_ansible_facts(module=module, facts=facts, timestamp=timestamp) - fact_obj = Fact.objects.create(host_id=host_id, module=module, timestamp=timestamp, facts=facts) fact_obj.save() return fact_obj diff --git a/awx/main/models/jobs.py b/awx/main/models/jobs.py index e9464d5ac2..219510a9fd 100644 --- a/awx/main/models/jobs.py +++ b/awx/main/models/jobs.py @@ -159,6 +159,9 @@ class JobOptions(BaseModel): blank=True, default=0, ) + gather_facts = models.BooleanField( + default=False, + ) extra_vars_dict = VarsDictProperty('extra_vars', True) @@ -261,7 +264,8 @@ class JobTemplate(UnifiedJobTemplate, JobOptions, SurveyJobTemplateMixin, Resour 'playbook', 'credential', 'cloud_credential', 'network_credential', 'forks', 'schedule', 'limit', 'verbosity', 'job_tags', 'extra_vars', 'launch_type', 'force_handlers', 'skip_tags', 'start_at_task', 'become_enabled', - 'labels', 'survey_passwords', 'allow_simultaneous', 'timeout'] + 'labels', 'survey_passwords', 'allow_simultaneous', 'timeout', + 'gather_facts',] def resource_validation_data(self): ''' diff --git a/awx/main/tasks.py b/awx/main/tasks.py index 4173b0134b..f5e4c3facb 100644 --- a/awx/main/tasks.py +++ b/awx/main/tasks.py @@ -944,11 +944,12 @@ class RunJob(BaseTask): env['ANSIBLE_NET_AUTH_PASS'] = decrypt_field(network_cred, 'authorize_password') # Set environment variables related to gathering facts from the cache - env['FACT_QUEUE'] = settings.FACT_QUEUE - env['ANSIBLE_LIBRARY'] = self.get_path_to('..', 'plugins', 'library') - env['ANSIBLE_CACHE_PLUGINS'] = self.get_path_to('..', 'plugins', 'fact_caching') - env['ANSIBLE_CACHE_PLUGIN'] = "tower" - env['ANSIBLE_CACHE_PLUGIN_CONNECTION'] = "tcp://127.0.0.1:%s" % str(settings.FACT_CACHE_PORT) + if job.job_type == PERM_INVENTORY_SCAN or job.gather_facts is True: + env['FACT_QUEUE'] = settings.FACT_QUEUE + env['ANSIBLE_LIBRARY'] = self.get_path_to('..', 'plugins', 'library') + env['ANSIBLE_CACHE_PLUGINS'] = self.get_path_to('..', 'plugins', 'fact_caching') + env['ANSIBLE_CACHE_PLUGIN'] = "tower" + env['ANSIBLE_CACHE_PLUGIN_CONNECTION'] = "tcp://127.0.0.1:%s" % str(settings.FACT_CACHE_PORT) return env def build_args(self, job, **kwargs):