Merge "Move ubuntu jobs to focal"
diff --git a/octavia_tempest_plugin/tests/scenario/v2/test_traffic_ops.py b/octavia_tempest_plugin/tests/scenario/v2/test_traffic_ops.py
index 356327b..9a43b35 100644
--- a/octavia_tempest_plugin/tests/scenario/v2/test_traffic_ops.py
+++ b/octavia_tempest_plugin/tests/scenario/v2/test_traffic_ops.py
@@ -15,6 +15,7 @@
import datetime
import ipaddress
import shlex
+import socket
import testtools
import time
@@ -90,7 +91,8 @@
@classmethod
def _listener_pool_create(cls, protocol, protocol_port,
- pool_algorithm=const.LB_ALGORITHM_ROUND_ROBIN):
+ pool_algorithm=const.LB_ALGORITHM_ROUND_ROBIN,
+ insert_headers_dic=None):
if (protocol == const.UDP and
not cls.mem_listener_client.is_version_supported(
cls.api_version, '2.1')):
@@ -112,6 +114,10 @@
# haproxy process and use haproxy>=1.8:
const.CONNECTION_LIMIT: 200,
}
+
+ if insert_headers_dic:
+ listener_kwargs[const.INSERT_HEADERS] = insert_headers_dic
+
listener = cls.mem_listener_client.create_listener(**listener_kwargs)
waiters.wait_for_status(cls.mem_lb_client.show_loadbalancer,
@@ -1322,3 +1328,70 @@
protocol_port)
self.assertConsistentResponse(
(None, None), url_for_vip, repeat=3, expect_connection_error=True)
+
+ @decorators.idempotent_id('d3a28e76-76bc-11eb-a7c3-74e5f9e2a801')
+ def test_insert_headers(self):
+ # Create listener, enable insert of "X_FORWARDED_FOR" HTTP header
+ listener_port = 102
+ listener_id, pool_id = self._listener_pool_create(
+ const.HTTP, listener_port, insert_headers_dic={
+ const.X_FORWARDED_FOR: "true"})
+ self._test_basic_traffic(
+ const.HTTP, listener_port, listener_id, pool_id)
+
+ # Initiate HTTP traffic
+ test_url = 'http://{}:{}/request'.format(
+ self.lb_vip_address, listener_port)
+ data = self.validate_URL_response(test_url)
+ LOG.info('Received payload is: {}'.format(data))
+
+ # Detect source IP that is used to create TCP socket toward LB_VIP.
+ try:
+ s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+ s.connect((self.lb_vip_address, listener_port))
+ client_source_ip = s.getsockname()[0]
+ s.close()
+ except Exception:
+ LOG.exception('Failed to initiate TCP socket toward LB_VIP')
+ raise Exception('LB_VIP is not available')
+
+ # Function needed to parse the received payload from backend.
+ # Returns dictionary of relevant headers if found.
+ def _data_parser(payload, relevant_headers):
+ retrieved_headers = {}
+ for line in payload.split('\n'):
+ try:
+ key, value = line.split(': ', 1)
+ except ValueError:
+ continue
+ if key in relevant_headers:
+ retrieved_headers[key] = value.lower()
+ return retrieved_headers
+
+ # Make sure that "X_FORWARDED_FOR" header was inserted with
+ # expected IP (client_source_ip). Should present in data.
+ expected_headers = {const.X_FORWARDED_FOR: client_source_ip}
+ received_headers = _data_parser(data, expected_headers)
+ self.assertEqual(expected_headers, received_headers)
+
+ # Update listener to insert: "X_FORWARDED_PORT" and
+ # "X_FORWARDED_PROTO"type headers.
+ listener_kwargs = {
+ const.LISTENER_ID: listener_id,
+ const.INSERT_HEADERS: {
+ const.X_FORWARDED_PORT: "true",
+ const.X_FORWARDED_PROTO: "true"}}
+ self.mem_listener_client.update_listener(**listener_kwargs)
+ waiters.wait_for_status(self.mem_lb_client.show_loadbalancer,
+ self.lb_id, const.PROVISIONING_STATUS,
+ const.ACTIVE,
+ CONF.load_balancer.check_interval,
+ CONF.load_balancer.check_timeout)
+
+ # Initiate HTTP traffic
+ data = self.validate_URL_response(test_url)
+ LOG.info('Received payload is: {}'.format(data))
+ expected_headers = {const.X_FORWARDED_PORT: '{}'.format(
+ listener_port), const.X_FORWARDED_PROTO: const.HTTP.lower()}
+ received_headers = _data_parser(data, expected_headers)
+ self.assertEqual(expected_headers, received_headers)