Skip to content

Commit 44ae850

Browse files
Zuulopenstack-gerrit
authored andcommitted
Merge "api: Log correct client IP if load balancer in use"
2 parents a698362 + 375a845 commit 44ae850

File tree

2 files changed

+33
-2
lines changed

2 files changed

+33
-2
lines changed

nova/api/openstack/requestlog.py

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@
2121

2222
from nova.api.openstack import wsgi
2323
from nova.api import wsgi as base_wsgi
24+
import nova.conf
25+
26+
CONF = nova.conf.CONF
2427

2528
# TODO(sdague) maybe we can use a better name here for the logger
2629
LOG = logging.getLogger(__name__)
@@ -65,8 +68,17 @@ def _log_req(self, req, res, start):
6568
# wsgi stack, res is going to be an empty dict for the
6669
# fallback logging. So never count on it having attributes.
6770
status = getattr(res, "status", "500 Error").split(None, 1)[0]
71+
72+
remote_address = req.environ.get('REMOTE_ADDR', '-')
73+
74+
# If the API is configured to treat the X-Forwarded-For header as the
75+
# canonical remote address, use its value instead.
76+
if CONF.api.use_forwarded_for:
77+
remote_address = req.environ.get(
78+
'HTTP_X_FORWARDED_FOR', remote_address)
79+
6880
data = {
69-
'REMOTE_ADDR': req.environ.get('REMOTE_ADDR', '-'),
81+
'REMOTE_ADDR': remote_address,
7082
'REQUEST_METHOD': req.environ['REQUEST_METHOD'],
7183
'REQUEST_URI': self._get_uri(req.environ),
7284
'status': status,

nova/tests/unit/api/openstack/test_requestlog.py

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ def test_logs_requests(self, emit):
5858
"""
5959

6060
emit.return_value = True
61-
self.useFixture(fixtures.ConfFixture())
61+
conf = self.useFixture(fixtures.ConfFixture()).conf
6262
self.useFixture(fixtures.RPCFixture('nova.test'))
6363
api = self.useFixture(fixtures.OSAPIFixture()).api
6464

@@ -73,6 +73,25 @@ def test_logs_requests(self, emit):
7373
'"GET /" status: 200 len: %s' % content_length)
7474
self.assertIn(log1, self.stdlog.logger.output)
7575

76+
# Verify handling of X-Forwarded-For header, example: load balancer.
77+
# First, try without setting CONF.api.use_forwarded_for, it should not
78+
# use the header value.
79+
headers = {'X-Forwarded-For': '1.2.3.4'}
80+
resp = api.api_request('/', strip_version=True, headers=headers)
81+
content_length = resp.headers['content-length']
82+
log2 = ('INFO [nova.api.openstack.requestlog] 127.0.0.1 '
83+
'"GET /" status: 200 len: %s' % content_length)
84+
self.assertIn(log2, self.stdlog.logger.output)
85+
86+
# Now set CONF.api.use_forwarded_for, it should use the header value.
87+
conf.set_override('use_forwarded_for', True, 'api')
88+
headers = {'X-Forwarded-For': '1.2.3.4'}
89+
resp = api.api_request('/', strip_version=True, headers=headers)
90+
content_length = resp.headers['content-length']
91+
log3 = ('INFO [nova.api.openstack.requestlog] 1.2.3.4 '
92+
'"GET /" status: 200 len: %s' % content_length)
93+
self.assertIn(log3, self.stdlog.logger.output)
94+
7695
@mock.patch('nova.api.openstack.requestlog.RequestLog._should_emit')
7796
def test_logs_mv(self, emit):
7897
"""Ensure logs register microversion if passed.

0 commit comments

Comments
 (0)