diff --git a/awx/api/serializers.py b/awx/api/serializers.py
index 236ece70e8..571edf57a9 100644
--- a/awx/api/serializers.py
+++ b/awx/api/serializers.py
@@ -3884,15 +3884,23 @@ class ProjectUpdateEventSerializer(JobEventSerializer):
return UriCleaner.remove_sensitive(obj.stdout)
def get_event_data(self, obj):
- try:
- return json.loads(
- UriCleaner.remove_sensitive(
- json.dumps(obj.event_data)
+ # the project update playbook uses the git, hg, or svn modules
+ # to clone repositories, and those modules are prone to printing
+ # raw SCM URLs in their stdout (which *could* contain passwords)
+ # attempt to detect and filter HTTP basic auth passwords in the stdout
+ # of these types of events
+ if obj.event_data.get('task_action') in ('git', 'hg', 'svn'):
+ try:
+ return json.loads(
+ UriCleaner.remove_sensitive(
+ json.dumps(obj.event_data)
+ )
)
- )
- except Exception:
- logger.exception("Failed to sanitize event_data")
- return {}
+ except Exception:
+ logger.exception("Failed to sanitize event_data")
+ return {}
+ else:
+ return obj.event_data
class AdHocCommandEventSerializer(BaseSerializer):
diff --git a/awx/main/dispatch/worker/base.py b/awx/main/dispatch/worker/base.py
index 74d2a6a6c3..b0611676fa 100644
--- a/awx/main/dispatch/worker/base.py
+++ b/awx/main/dispatch/worker/base.py
@@ -8,6 +8,7 @@ import sys
import redis
import json
import psycopg2
+import time
from uuid import UUID
from queue import Empty as QueueEmpty
@@ -116,18 +117,23 @@ class AWXConsumerRedis(AWXConsumerBase):
super(AWXConsumerRedis, self).run(*args, **kwargs)
self.worker.on_start()
- queue = redis.Redis.from_url(settings.BROKER_URL)
+ time_to_sleep = 1
while True:
- try:
- res = queue.blpop(self.queues)
- res = json.loads(res[1])
- self.process_task(res)
- except redis.exceptions.RedisError:
- logger.exception("encountered an error communicating with redis")
- except (json.JSONDecodeError, KeyError):
- logger.exception("failed to decode JSON message from redis")
- if self.should_stop:
- return
+ queue = redis.Redis.from_url(settings.BROKER_URL)
+ while True:
+ try:
+ res = queue.blpop(self.queues)
+ time_to_sleep = 1
+ res = json.loads(res[1])
+ self.process_task(res)
+ except redis.exceptions.RedisError:
+ time_to_sleep = min(time_to_sleep * 2, 30)
+ logger.exception(f"encountered an error communicating with redis. Reconnect attempt in {time_to_sleep} seconds")
+ time.sleep(time_to_sleep)
+ except (json.JSONDecodeError, KeyError):
+ logger.exception("failed to decode JSON message from redis")
+ if self.should_stop:
+ return
class AWXConsumerPG(AWXConsumerBase):
diff --git a/awx/main/tasks.py b/awx/main/tasks.py
index 0fe0e9035f..32a125aad6 100644
--- a/awx/main/tasks.py
+++ b/awx/main/tasks.py
@@ -1232,10 +1232,12 @@ class BaseTask(object):
# this is a _little_ expensive to filter
# with regex, but project updates don't have many events,
# so it *should* have a negligible performance impact
+ task = event_data.get('event_data', {}).get('task_action')
try:
- event_data_json = json.dumps(event_data)
- event_data_json = UriCleaner.remove_sensitive(event_data_json)
- event_data = json.loads(event_data_json)
+ if task in ('git', 'hg', 'svn'):
+ event_data_json = json.dumps(event_data)
+ event_data_json = UriCleaner.remove_sensitive(event_data_json)
+ event_data = json.loads(event_data_json)
except json.JSONDecodeError:
pass
diff --git a/awx/ui/client/src/inventories-hosts/inventories/related/sources/sources.form.js b/awx/ui/client/src/inventories-hosts/inventories/related/sources/sources.form.js
index 1423f881f2..2dda6bf73d 100644
--- a/awx/ui/client/src/inventories-hosts/inventories/related/sources/sources.form.js
+++ b/awx/ui/client/src/inventories-hosts/inventories/related/sources/sources.form.js
@@ -263,8 +263,8 @@ export default ['NotificationsList', 'i18n', function(NotificationsList, i18n){
dataTitle: i18n._("Source Variables"),
dataPlacement: 'right',
awPopOver: i18n._(`Override variables found in openstack.yml and used by the inventory update script. For an example variable configuration
-
- view openstack.yml in the Ansible github repo. Enter inventory variables using either JSON or YAML syntax. Use the radio button to toggle between the two. Refer to the Ansible Tower documentation for example syntax.`),
+
+ view openstack.yml in the Openstack github repo. Enter inventory variables using either JSON or YAML syntax. Use the radio button to toggle between the two. Refer to the Ansible Tower documentation for example syntax.`),
dataContainer: 'body',
subForm: 'sourceSubForm'
},
@@ -280,8 +280,8 @@ export default ['NotificationsList', 'i18n', function(NotificationsList, i18n){
dataTitle: i18n._("Source Variables"),
dataPlacement: 'right',
awPopOver: i18n._(`Override variables found in cloudforms.ini and used by the inventory update script. For an example variable configuration
-
- view cloudforms.ini in the Ansible github repo. Enter inventory variables using either JSON or YAML syntax. Use the radio button to toggle between the two. Refer to the Ansible Tower documentation for example syntax.`),
+
+ view cloudforms.ini in the Ansible Collections github repo. Enter inventory variables using either JSON or YAML syntax. Use the radio button to toggle between the two. Refer to the Ansible Tower documentation for example syntax.`),
dataContainer: 'body',
subForm: 'sourceSubForm'
},
@@ -297,8 +297,8 @@ export default ['NotificationsList', 'i18n', function(NotificationsList, i18n){
dataTitle: i18n._("Source Variables"),
dataPlacement: 'right',
awPopOver: i18n._(`Override variables found in foreman.ini and used by the inventory update script. For an example variable configuration
-
- view foreman.ini in the Ansible github repo. Enter inventory variables using either JSON or YAML syntax. Use the radio button to toggle between the two. Refer to the Ansible Tower documentation for example syntax.`),
+
+ view foreman.ini in the Ansible Collections github repo. Enter inventory variables using either JSON or YAML syntax. Use the radio button to toggle between the two. Refer to the Ansible Tower documentation for example syntax.`),
dataContainer: 'body',
subForm: 'sourceSubForm'
},