mirror of
https://github.com/ansible/awx.git
synced 2026-01-11 10:00:01 -03:30
* Adding API_400_ERROR_LOG_FORMAT setting * Adding functional tests for API_400_ERROR_LOG_FORMAT Co-authored-by: nixocio <nixocio@gmail.com>
This commit is contained in:
parent
60831cae88
commit
e63ce9ed08
@ -44,6 +44,7 @@ from awx.main.views import ApiErrorView
|
||||
from awx.api.serializers import ResourceAccessListElementSerializer, CopySerializer, UserSerializer
|
||||
from awx.api.versioning import URLPathVersioning
|
||||
from awx.api.metadata import SublistAttachDetatchMetadata, Metadata
|
||||
from awx.conf import settings_registry
|
||||
|
||||
__all__ = [
|
||||
'APIView',
|
||||
@ -208,12 +209,20 @@ class APIView(views.APIView):
|
||||
return response
|
||||
|
||||
if response.status_code >= 400:
|
||||
status_msg = "status %s received by user %s attempting to access %s from %s" % (
|
||||
response.status_code,
|
||||
request.user,
|
||||
request.path,
|
||||
request.META.get('REMOTE_ADDR', None),
|
||||
)
|
||||
msg_data = {
|
||||
'status_code': response.status_code,
|
||||
'user_name': request.user,
|
||||
'url_path': request.path,
|
||||
'remote_addr': request.META.get('REMOTE_ADDR', None),
|
||||
'error': response.data.get('error', response.status_text),
|
||||
}
|
||||
try:
|
||||
status_msg = getattr(settings, 'API_400_ERROR_LOG_FORMAT').format(**msg_data)
|
||||
except Exception as e:
|
||||
if getattr(settings, 'API_400_ERROR_LOG_FORMAT', None):
|
||||
logger.error("Unable to format API_400_ERROR_LOG_FORMAT setting, defaulting log message: {}".format(e))
|
||||
status_msg = settings_registry.get_setting_field('API_400_ERROR_LOG_FORMAT').get_default().format(**msg_data)
|
||||
|
||||
if hasattr(self, '__init_request_error__'):
|
||||
response = self.handle_exception(self.__init_request_error__)
|
||||
if response.status_code == 401:
|
||||
@ -221,6 +230,7 @@ class APIView(views.APIView):
|
||||
logger.info(status_msg)
|
||||
else:
|
||||
logger.warning(status_msg)
|
||||
|
||||
response = super(APIView, self).finalize_response(request, response, *args, **kwargs)
|
||||
time_started = getattr(self, 'time_started', None)
|
||||
response['X-API-Product-Version'] = get_awx_version()
|
||||
|
||||
@ -674,6 +674,24 @@ register(
|
||||
category=_('Logging'),
|
||||
category_slug='logging',
|
||||
)
|
||||
register(
|
||||
'API_400_ERROR_LOG_FORMAT',
|
||||
field_class=fields.CharField,
|
||||
default='status {status_code} received by user {user_name} attempting to access {url_path} from {remote_addr}',
|
||||
label=_('Log Format For API 4XX Errors'),
|
||||
help_text=_(
|
||||
'The format of logged messages when an API 4XX error occurs, '
|
||||
'the following variables will be substituted: \n'
|
||||
'status_code - The HTTP status code of the error\n'
|
||||
'user_name - The user name attempting to use the API\n'
|
||||
'url_path - The URL path to the API endpoint called\n'
|
||||
'remote_addr - The remote address seen for the user\n'
|
||||
'error - The error set by the api endpoint\n'
|
||||
'Variables need to be in the format {<variable name>}.'
|
||||
),
|
||||
category=_('Logging'),
|
||||
category_slug='logging',
|
||||
)
|
||||
|
||||
|
||||
register(
|
||||
|
||||
26
awx/main/tests/functional/test_api_generics.py
Normal file
26
awx/main/tests/functional/test_api_generics.py
Normal file
@ -0,0 +1,26 @@
|
||||
import pytest
|
||||
|
||||
from django.test.utils import override_settings
|
||||
from awx.api.versioning import reverse
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_change_400_error_log(caplog, post, admin_user):
|
||||
with override_settings(API_400_ERROR_LOG_FORMAT='Test'):
|
||||
post(url=reverse('api:setting_logging_test'), data={}, user=admin_user, expect=409)
|
||||
assert 'Test' in caplog.text
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_bad_400_error_log(caplog, post, admin_user):
|
||||
with override_settings(API_400_ERROR_LOG_FORMAT="Not good {junk}"):
|
||||
post(url=reverse('api:setting_logging_test'), data={}, user=admin_user, expect=409)
|
||||
assert "Unable to format API_400_ERROR_LOG_FORMAT setting, defaulting log message: 'junk'" in caplog.text
|
||||
assert 'status 409 received by user admin attempting to access /api/v2/settings/logging/test/ from 127.0.0.1' in caplog.text
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_custom_400_error_log(caplog, post, admin_user):
|
||||
with override_settings(API_400_ERROR_LOG_FORMAT="{status_code} {error}"):
|
||||
post(url=reverse('api:setting_logging_test'), data={}, user=admin_user, expect=409)
|
||||
assert '409 Logging not enabled' in caplog.text
|
||||
@ -761,6 +761,7 @@ LOG_AGGREGATOR_MAX_DISK_USAGE_GB = 1
|
||||
LOG_AGGREGATOR_MAX_DISK_USAGE_PATH = '/var/lib/awx'
|
||||
LOG_AGGREGATOR_RSYSLOGD_DEBUG = False
|
||||
LOG_AGGREGATOR_RSYSLOGD_ERROR_LOG_FILE = '/var/log/tower/rsyslog.err'
|
||||
API_400_ERROR_LOG_FORMAT = 'status {status_code} received by user {user_name} attempting to access {url_path} from {remote_addr}'
|
||||
|
||||
# The number of retry attempts for websocket session establishment
|
||||
# If you're encountering issues establishing websockets in a cluster,
|
||||
|
||||
@ -32,6 +32,8 @@ SettingsAPI.readCategory.mockResolvedValue({
|
||||
LOG_AGGREGATOR_MAX_DISK_USAGE_GB: 1,
|
||||
LOG_AGGREGATOR_MAX_DISK_USAGE_PATH: '/var/lib/awx',
|
||||
LOG_AGGREGATOR_RSYSLOGD_DEBUG: false,
|
||||
API_400_ERROR_LOG_FORMAT:
|
||||
'status {status_code} received by user {user_name} attempting to access {url_path} from {remote_addr}',
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@ -42,7 +42,8 @@ function LoggingDetail() {
|
||||
'LOG_AGGREGATOR_TCP_TIMEOUT',
|
||||
'LOG_AGGREGATOR_TYPE',
|
||||
'LOG_AGGREGATOR_USERNAME',
|
||||
'LOG_AGGREGATOR_VERIFY_CERT'
|
||||
'LOG_AGGREGATOR_VERIFY_CERT',
|
||||
'API_400_ERROR_LOG_FORMAT'
|
||||
);
|
||||
|
||||
const mergedData = {};
|
||||
|
||||
@ -59,6 +59,7 @@ describe('<LoggingDetail />', () => {
|
||||
assertDetail(wrapper, 'Logging Aggregator Protocol', 'https');
|
||||
assertDetail(wrapper, 'TCP Connection Timeout', '5 seconds');
|
||||
assertDetail(wrapper, 'Logging Aggregator Level Threshold', 'INFO');
|
||||
assertDetail(wrapper, 'Log Format For API 4XX Errors', 'Test Log Line');
|
||||
assertDetail(
|
||||
wrapper,
|
||||
'Enable/disable HTTPS certificate verification',
|
||||
|
||||
@ -8,7 +8,7 @@ import { CardBody } from 'components/Card';
|
||||
import ContentError from 'components/ContentError';
|
||||
import ContentLoading from 'components/ContentLoading';
|
||||
import { FormSubmitError } from 'components/FormField';
|
||||
import { FormColumnLayout } from 'components/FormLayout';
|
||||
import { FormColumnLayout, FormFullWidthLayout } from 'components/FormLayout';
|
||||
import { useSettings } from 'contexts/Settings';
|
||||
import useModal from 'hooks/useModal';
|
||||
import useRequest from 'hooks/useRequest';
|
||||
@ -71,6 +71,7 @@ function LoggingEdit() {
|
||||
LOG_AGGREGATOR_LOGGERS: formatJson(form.LOG_AGGREGATOR_LOGGERS),
|
||||
LOG_AGGREGATOR_HOST: form.LOG_AGGREGATOR_HOST || null,
|
||||
LOG_AGGREGATOR_TYPE: form.LOG_AGGREGATOR_TYPE || null,
|
||||
API_400_ERROR_LOG_FORMAT: form.API_400_ERROR_LOG_FORMAT || null,
|
||||
});
|
||||
};
|
||||
|
||||
@ -196,6 +197,12 @@ function LoggingEdit() {
|
||||
name="LOG_AGGREGATOR_LOGGERS"
|
||||
config={logging.LOG_AGGREGATOR_LOGGERS}
|
||||
/>
|
||||
<FormFullWidthLayout>
|
||||
<InputField
|
||||
name="API_400_ERROR_LOG_FORMAT"
|
||||
config={logging.API_400_ERROR_LOG_FORMAT}
|
||||
/>
|
||||
</FormFullWidthLayout>
|
||||
{submitError && <FormSubmitError error={submitError} />}
|
||||
{revertError && <FormSubmitError error={revertError} />}
|
||||
<RevertFormActionGroup
|
||||
|
||||
@ -34,6 +34,8 @@ const mockSettings = {
|
||||
LOG_AGGREGATOR_MAX_DISK_USAGE_GB: 1,
|
||||
LOG_AGGREGATOR_MAX_DISK_USAGE_PATH: '/var/lib/awx',
|
||||
LOG_AGGREGATOR_RSYSLOGD_DEBUG: false,
|
||||
API_400_ERROR_LOG_FORMAT:
|
||||
'status {status_code} received by user {user_name} attempting to access {url_path} from {remote_addr}',
|
||||
};
|
||||
|
||||
describe('<LoggingEdit />', () => {
|
||||
|
||||
@ -564,6 +564,15 @@
|
||||
"category_slug": "logging",
|
||||
"default": false
|
||||
},
|
||||
"API_400_ERROR_LOG_FORMAT": {
|
||||
"type": "string",
|
||||
"required": false,
|
||||
"label": "Log Format For API 4XX Errors",
|
||||
"help_text": "The format of logged messages when an API 4XX error occurs, the following variables will be substituted: \nstatus_code - The HTTP status code of the error\nuser_name - The user name attempting to use the API\nurl_path - The URL path to the API endpoint called\nremote_addr - The remote address seen for the user\nerror - The error set by the api endpoint\nVariables need to be in the format {<variable name>}.",
|
||||
"category": "Logging",
|
||||
"category_slug": "logging",
|
||||
"default": "status {status_code} received by user {user_name} attempting to access {url_path} from {remote_addr}"
|
||||
},
|
||||
"AUTOMATION_ANALYTICS_LAST_GATHER": {
|
||||
"type": "datetime",
|
||||
"required": true,
|
||||
@ -4221,6 +4230,15 @@
|
||||
"category_slug": "logging",
|
||||
"defined_in_file": false
|
||||
},
|
||||
"API_400_ERROR_LOG_FORMAT": {
|
||||
"type": "string",
|
||||
"required": false,
|
||||
"label": "Log Format For API 4XX Errors",
|
||||
"help_text": "The format of logged messages when an API 4XX error occurs, the following variables will be substituted: \nstatus_code - The HTTP status code of the error\nuser_name - The user name attempting to use the API\nurl_path - The URL path to the API endpoint called\nremote_addr - The remote address seen for the user\nerror - The error set by the api endpoint\nVariables need to be in the format {<variable name>}.",
|
||||
"category": "Logging",
|
||||
"category_slug": "logging",
|
||||
"default": "status {status_code} received by user {user_name} attempting to access {url_path} from {remote_addr}"
|
||||
},
|
||||
"AUTOMATION_ANALYTICS_LAST_GATHER": {
|
||||
"type": "datetime",
|
||||
"label": "Last gather date for Insights for Ansible Automation Platform.",
|
||||
@ -6329,7 +6347,7 @@
|
||||
},
|
||||
"SOCIAL_AUTH_SAML_USER_FLAGS_BY_ATTR": {
|
||||
"type": "nested object",
|
||||
"label": "SAML User Flags Attribute Mapping",
|
||||
"label": "SAML User Flags Attribute Mapping",
|
||||
"help_text": "Used to map super users and system auditors from SAML.",
|
||||
"category": "SAML",
|
||||
"category_slug": "saml",
|
||||
|
||||
@ -70,6 +70,7 @@
|
||||
"LOG_AGGREGATOR_MAX_DISK_USAGE_GB":1,
|
||||
"LOG_AGGREGATOR_MAX_DISK_USAGE_PATH":"/var/lib/awx",
|
||||
"LOG_AGGREGATOR_RSYSLOGD_DEBUG":false,
|
||||
"API_400_ERROR_LOG_FORMAT":"status {status_code} received by user {user_name} attempting to access {url_path} from {remote_addr}",
|
||||
"AUTOMATION_ANALYTICS_LAST_GATHER":null,
|
||||
"AUTOMATION_ANALYTICS_GATHER_INTERVAL":14400,
|
||||
"SESSION_COOKIE_AGE":1800,
|
||||
|
||||
@ -17,5 +17,6 @@
|
||||
"LOG_AGGREGATOR_LEVEL": "INFO",
|
||||
"LOG_AGGREGATOR_MAX_DISK_USAGE_GB": 1,
|
||||
"LOG_AGGREGATOR_MAX_DISK_USAGE_PATH": "/var/lib/awx",
|
||||
"LOG_AGGREGATOR_RSYSLOGD_DEBUG": false
|
||||
}
|
||||
"LOG_AGGREGATOR_RSYSLOGD_DEBUG": false,
|
||||
"API_400_ERROR_LOG_FORMAT": "Test Log Line"
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user