diff --git a/awx/main/conf.py b/awx/main/conf.py index c3a9c87173..69435953c7 100644 --- a/awx/main/conf.py +++ b/awx/main/conf.py @@ -473,10 +473,12 @@ register( register( 'LOG_AGGREGATOR_PROTOCOL', field_class=fields.ChoiceField, - choices=[('https', 'HTTPS'), ('tcp', 'TCP'), ('udp', 'UDP')], + choices=[('https', 'HTTPS/HTTP'), ('tcp', 'TCP'), ('udp', 'UDP')], default='https', label=_('Logging Aggregator Protocol'), - help_text=_('Protocol used to communicate with log aggregator.'), + help_text=_('Protocol used to communicate with log aggregator. ' + 'HTTPS/HTTP assumes HTTPS unless http:// is explicitly used in ' + 'the Logging Aggregator hostname.'), category=_('Logging'), category_slug='logging', ) diff --git a/awx/main/tests/unit/utils/test_handlers.py b/awx/main/tests/unit/utils/test_handlers.py index eb94727f21..9dd06189c0 100644 --- a/awx/main/tests/unit/utils/test_handlers.py +++ b/awx/main/tests/unit/utils/test_handlers.py @@ -22,8 +22,8 @@ from awx.main.utils.formatters import LogstashFormatter @pytest.fixture() -def http_adapter(): - class FakeHTTPAdapter(requests.adapters.HTTPAdapter): +def https_adapter(): + class FakeHTTPSAdapter(requests.adapters.HTTPAdapter): requests = [] status = 200 reason = None @@ -36,7 +36,7 @@ def http_adapter(): resp.request = request return resp - return FakeHTTPAdapter() + return FakeHTTPSAdapter() @pytest.fixture() @@ -194,17 +194,22 @@ def test_base_logging_handler_host_format(host, port, normalized, hostname_only) 'status, reason, exc', [(200, '200 OK', None), (404, 'Not Found', LoggingConnectivityException)] ) -def test_https_logging_handler_connectivity_test(http_adapter, status, reason, exc): - http_adapter.status = status - http_adapter.reason = reason +@pytest.mark.parametrize('protocol', ['http', 'https', None]) +def test_https_logging_handler_connectivity_test(https_adapter, status, reason, exc, protocol): + host = 'example.org' + if protocol: + host = '://'.join([protocol, host]) + https_adapter.status = status + https_adapter.reason = reason settings = LazySettings() settings.configure(**{ - 'LOG_AGGREGATOR_HOST': 'example.org', + 'LOG_AGGREGATOR_HOST': host, 'LOG_AGGREGATOR_PORT': 8080, 'LOG_AGGREGATOR_TYPE': 'logstash', 'LOG_AGGREGATOR_USERNAME': 'user', 'LOG_AGGREGATOR_PASSWORD': 'password', 'LOG_AGGREGATOR_LOGGERS': ['awx', 'activity_stream', 'job_events', 'system_tracking'], + 'LOG_AGGREGATOR_PROTOCOL': 'https', 'CLUSTER_HOST_ID': '', 'LOG_AGGREGATOR_TOWER_UUID': str(uuid4()), 'LOG_AGGREGATOR_LEVEL': 'DEBUG', @@ -214,7 +219,7 @@ def test_https_logging_handler_connectivity_test(http_adapter, status, reason, e def __init__(self, *args, **kwargs): super(FakeHTTPSHandler, self).__init__(*args, **kwargs) - self.session.mount('http://', http_adapter) + self.session.mount('{}://'.format(protocol or 'https'), https_adapter) def emit(self, record): return super(FakeHTTPSHandler, self).emit(record) @@ -270,17 +275,17 @@ def test_https_logging_handler_connection_error(connection_error_adapter, @pytest.mark.parametrize('message_type', ['logstash', 'splunk']) -def test_https_logging_handler_emit_without_cred(http_adapter, dummy_log_record, +def test_https_logging_handler_emit_without_cred(https_adapter, dummy_log_record, message_type): handler = HTTPSHandler(host='127.0.0.1', message_type=message_type) handler.setFormatter(LogstashFormatter()) - handler.session.mount('http://', http_adapter) + handler.session.mount('https://', https_adapter) async_futures = handler.emit(dummy_log_record) [future.result() for future in async_futures] - assert len(http_adapter.requests) == 1 - request = http_adapter.requests[0] - assert request.url == 'http://127.0.0.1/' + assert len(https_adapter.requests) == 1 + request = https_adapter.requests[0] + assert request.url == 'https://127.0.0.1/' assert request.method == 'POST' if message_type == 'logstash': @@ -291,32 +296,32 @@ def test_https_logging_handler_emit_without_cred(http_adapter, dummy_log_record, assert request.headers['Authorization'] == 'Splunk None' -def test_https_logging_handler_emit_logstash_with_creds(http_adapter, +def test_https_logging_handler_emit_logstash_with_creds(https_adapter, dummy_log_record): handler = HTTPSHandler(host='127.0.0.1', username='user', password='pass', message_type='logstash') handler.setFormatter(LogstashFormatter()) - handler.session.mount('http://', http_adapter) + handler.session.mount('https://', https_adapter) async_futures = handler.emit(dummy_log_record) [future.result() for future in async_futures] - assert len(http_adapter.requests) == 1 - request = http_adapter.requests[0] + assert len(https_adapter.requests) == 1 + request = https_adapter.requests[0] assert request.headers['Authorization'] == 'Basic %s' % base64.b64encode("user:pass") -def test_https_logging_handler_emit_splunk_with_creds(http_adapter, +def test_https_logging_handler_emit_splunk_with_creds(https_adapter, dummy_log_record): handler = HTTPSHandler(host='127.0.0.1', password='pass', message_type='splunk') handler.setFormatter(LogstashFormatter()) - handler.session.mount('http://', http_adapter) + handler.session.mount('https://', https_adapter) async_futures = handler.emit(dummy_log_record) [future.result() for future in async_futures] - assert len(http_adapter.requests) == 1 - request = http_adapter.requests[0] + assert len(https_adapter.requests) == 1 + request = https_adapter.requests[0] assert request.headers['Authorization'] == 'Splunk pass' diff --git a/awx/main/utils/handlers.py b/awx/main/utils/handlers.py index fcccf5d9b1..3972815dc5 100644 --- a/awx/main/utils/handlers.py +++ b/awx/main/utils/handlers.py @@ -203,7 +203,7 @@ class BaseHTTPSHandler(BaseHandler): https://docs.python.org/3/library/concurrent.futures.html#future-objects http://pythonhosted.org/futures/ """ - return self.session.post(self._get_host(scheme='http'), + return self.session.post(self._get_host(scheme='https'), **self._get_post_kwargs(payload)) diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index db33422427..9823025af6 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -73,6 +73,7 @@ * Disallowed using HTTP PUT/PATCH methods to modify existing jobs in Job Details API endpoint. * Changed the name of the session length setting from `AUTH_TOKEN_EXPIRATION` to `SESSION_COOKIE_AGE`. * Changed the name of the session length setting from `AUTH_TOKEN_PER_USER` to `SESSIONS_PER_USER`. +* External logging now defaults to HTTPS (instead of HTTP) *unless* http:// is explicitly specified in the log aggregator hostname [[#2048](https://github.com/ansible/awx/issues/2048)] 3.2.0 =====