octavia 12.0.0.0rc2__py3-none-any.whl → 13.0.0.0rc1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (193) hide show
  1. octavia/amphorae/backends/agent/api_server/osutils.py +1 -0
  2. octavia/amphorae/backends/agent/api_server/plug.py +21 -7
  3. octavia/amphorae/backends/agent/api_server/templates/amphora-netns.systemd.j2 +2 -2
  4. octavia/amphorae/backends/agent/api_server/util.py +21 -0
  5. octavia/amphorae/backends/health_daemon/health_daemon.py +9 -3
  6. octavia/amphorae/backends/health_daemon/health_sender.py +2 -0
  7. octavia/amphorae/backends/utils/interface.py +14 -6
  8. octavia/amphorae/backends/utils/interface_file.py +6 -3
  9. octavia/amphorae/backends/utils/keepalivedlvs_query.py +8 -9
  10. octavia/amphorae/drivers/driver_base.py +1 -2
  11. octavia/amphorae/drivers/haproxy/rest_api_driver.py +11 -25
  12. octavia/amphorae/drivers/health/heartbeat_udp.py +34 -24
  13. octavia/amphorae/drivers/keepalived/jinja/jinja_cfg.py +3 -12
  14. octavia/amphorae/drivers/noop_driver/driver.py +3 -5
  15. octavia/api/common/pagination.py +4 -4
  16. octavia/api/drivers/amphora_driver/v2/driver.py +11 -5
  17. octavia/api/drivers/driver_agent/driver_get.py +22 -14
  18. octavia/api/drivers/driver_agent/driver_updater.py +8 -4
  19. octavia/api/drivers/utils.py +4 -2
  20. octavia/api/healthcheck/healthcheck_plugins.py +4 -2
  21. octavia/api/root_controller.py +4 -1
  22. octavia/api/v2/controllers/amphora.py +35 -38
  23. octavia/api/v2/controllers/availability_zone_profiles.py +43 -33
  24. octavia/api/v2/controllers/availability_zones.py +22 -18
  25. octavia/api/v2/controllers/flavor_profiles.py +37 -28
  26. octavia/api/v2/controllers/flavors.py +19 -15
  27. octavia/api/v2/controllers/health_monitor.py +44 -33
  28. octavia/api/v2/controllers/l7policy.py +52 -40
  29. octavia/api/v2/controllers/l7rule.py +68 -55
  30. octavia/api/v2/controllers/listener.py +88 -61
  31. octavia/api/v2/controllers/load_balancer.py +52 -34
  32. octavia/api/v2/controllers/member.py +63 -52
  33. octavia/api/v2/controllers/pool.py +55 -42
  34. octavia/api/v2/controllers/quotas.py +5 -3
  35. octavia/api/v2/types/listener.py +15 -0
  36. octavia/cmd/octavia_worker.py +0 -3
  37. octavia/cmd/status.py +1 -4
  38. octavia/common/clients.py +25 -45
  39. octavia/common/config.py +64 -22
  40. octavia/common/constants.py +3 -2
  41. octavia/common/data_models.py +7 -1
  42. octavia/common/jinja/haproxy/combined_listeners/jinja_cfg.py +12 -1
  43. octavia/common/jinja/haproxy/combined_listeners/templates/macros.j2 +5 -2
  44. octavia/common/jinja/lvs/jinja_cfg.py +4 -2
  45. octavia/common/keystone.py +58 -5
  46. octavia/common/validate.py +35 -0
  47. octavia/compute/drivers/noop_driver/driver.py +6 -0
  48. octavia/controller/healthmanager/health_manager.py +3 -6
  49. octavia/controller/housekeeping/house_keeping.py +36 -37
  50. octavia/controller/worker/amphora_rate_limit.py +5 -4
  51. octavia/controller/worker/task_utils.py +57 -41
  52. octavia/controller/worker/v2/controller_worker.py +160 -103
  53. octavia/controller/worker/v2/flows/listener_flows.py +3 -0
  54. octavia/controller/worker/v2/flows/load_balancer_flows.py +9 -14
  55. octavia/controller/worker/v2/tasks/amphora_driver_tasks.py +152 -91
  56. octavia/controller/worker/v2/tasks/compute_tasks.py +4 -2
  57. octavia/controller/worker/v2/tasks/database_tasks.py +542 -400
  58. octavia/controller/worker/v2/tasks/network_tasks.py +119 -79
  59. octavia/db/api.py +26 -23
  60. octavia/db/base_models.py +2 -2
  61. octavia/db/healthcheck.py +2 -1
  62. octavia/db/migration/alembic_migrations/versions/632152d2d32e_add_http_strict_transport_security_.py +42 -0
  63. octavia/db/models.py +12 -2
  64. octavia/db/prepare.py +2 -0
  65. octavia/db/repositories.py +462 -482
  66. octavia/hacking/checks.py +1 -1
  67. octavia/network/base.py +0 -14
  68. octavia/network/drivers/neutron/allowed_address_pairs.py +92 -135
  69. octavia/network/drivers/neutron/base.py +65 -77
  70. octavia/network/drivers/neutron/utils.py +69 -85
  71. octavia/network/drivers/noop_driver/driver.py +0 -7
  72. octavia/statistics/drivers/update_db.py +10 -10
  73. octavia/tests/common/constants.py +91 -84
  74. octavia/tests/common/sample_data_models.py +13 -1
  75. octavia/tests/fixtures.py +32 -0
  76. octavia/tests/functional/amphorae/backend/agent/api_server/test_server.py +9 -10
  77. octavia/tests/functional/api/drivers/driver_agent/test_driver_agent.py +260 -15
  78. octavia/tests/functional/api/test_root_controller.py +3 -28
  79. octavia/tests/functional/api/v2/base.py +5 -3
  80. octavia/tests/functional/api/v2/test_amphora.py +18 -5
  81. octavia/tests/functional/api/v2/test_availability_zone_profiles.py +1 -0
  82. octavia/tests/functional/api/v2/test_listener.py +51 -19
  83. octavia/tests/functional/api/v2/test_load_balancer.py +10 -1
  84. octavia/tests/functional/db/base.py +31 -16
  85. octavia/tests/functional/db/test_models.py +27 -28
  86. octavia/tests/functional/db/test_repositories.py +407 -50
  87. octavia/tests/unit/amphorae/backends/agent/api_server/test_amphora_info.py +2 -0
  88. octavia/tests/unit/amphorae/backends/agent/api_server/test_osutils.py +1 -1
  89. octavia/tests/unit/amphorae/backends/agent/api_server/test_plug.py +54 -6
  90. octavia/tests/unit/amphorae/backends/agent/api_server/test_util.py +35 -0
  91. octavia/tests/unit/amphorae/backends/health_daemon/test_health_daemon.py +8 -0
  92. octavia/tests/unit/amphorae/backends/health_daemon/test_health_sender.py +18 -0
  93. octavia/tests/unit/amphorae/backends/utils/test_interface.py +81 -0
  94. octavia/tests/unit/amphorae/backends/utils/test_interface_file.py +2 -0
  95. octavia/tests/unit/amphorae/backends/utils/test_keepalivedlvs_query.py +129 -5
  96. octavia/tests/unit/amphorae/drivers/haproxy/test_rest_api_driver_1_0.py +42 -20
  97. octavia/tests/unit/amphorae/drivers/health/test_heartbeat_udp.py +18 -20
  98. octavia/tests/unit/amphorae/drivers/keepalived/jinja/test_jinja_cfg.py +4 -4
  99. octavia/tests/unit/amphorae/drivers/noop_driver/test_driver.py +4 -1
  100. octavia/tests/unit/api/drivers/driver_agent/test_driver_get.py +3 -3
  101. octavia/tests/unit/api/drivers/driver_agent/test_driver_updater.py +11 -13
  102. octavia/tests/unit/base.py +6 -0
  103. octavia/tests/unit/cmd/test_interface.py +2 -2
  104. octavia/tests/unit/cmd/test_status.py +2 -2
  105. octavia/tests/unit/common/jinja/haproxy/combined_listeners/test_jinja_cfg.py +152 -1
  106. octavia/tests/unit/common/sample_configs/sample_configs_combined.py +10 -3
  107. octavia/tests/unit/common/test_clients.py +0 -39
  108. octavia/tests/unit/common/test_keystone.py +54 -0
  109. octavia/tests/unit/common/test_validate.py +67 -0
  110. octavia/tests/unit/controller/healthmanager/test_health_manager.py +8 -22
  111. octavia/tests/unit/controller/housekeeping/test_house_keeping.py +3 -64
  112. octavia/tests/unit/controller/worker/test_amphora_rate_limit.py +1 -1
  113. octavia/tests/unit/controller/worker/test_task_utils.py +44 -24
  114. octavia/tests/unit/controller/worker/v2/flows/test_load_balancer_flows.py +0 -1
  115. octavia/tests/unit/controller/worker/v2/tasks/test_amphora_driver_tasks.py +49 -26
  116. octavia/tests/unit/controller/worker/v2/tasks/test_database_tasks.py +399 -196
  117. octavia/tests/unit/controller/worker/v2/tasks/test_database_tasks_quota.py +37 -64
  118. octavia/tests/unit/controller/worker/v2/tasks/test_network_tasks.py +3 -14
  119. octavia/tests/unit/controller/worker/v2/test_controller_worker.py +2 -2
  120. octavia/tests/unit/network/drivers/neutron/test_allowed_address_pairs.py +456 -561
  121. octavia/tests/unit/network/drivers/neutron/test_base.py +181 -194
  122. octavia/tests/unit/network/drivers/neutron/test_utils.py +14 -30
  123. octavia/tests/unit/statistics/drivers/test_update_db.py +7 -5
  124. {octavia-12.0.0.0rc2.data → octavia-13.0.0.0rc1.data}/data/share/octavia/README.rst +1 -1
  125. {octavia-12.0.0.0rc2.dist-info → octavia-13.0.0.0rc1.dist-info}/AUTHORS +4 -0
  126. {octavia-12.0.0.0rc2.dist-info → octavia-13.0.0.0rc1.dist-info}/METADATA +4 -4
  127. {octavia-12.0.0.0rc2.dist-info → octavia-13.0.0.0rc1.dist-info}/RECORD +141 -189
  128. {octavia-12.0.0.0rc2.dist-info → octavia-13.0.0.0rc1.dist-info}/entry_points.txt +1 -2
  129. octavia-13.0.0.0rc1.dist-info/pbr.json +1 -0
  130. octavia/api/drivers/amphora_driver/v1/__init__.py +0 -11
  131. octavia/api/drivers/amphora_driver/v1/driver.py +0 -547
  132. octavia/controller/queue/v1/__init__.py +0 -11
  133. octavia/controller/queue/v1/consumer.py +0 -64
  134. octavia/controller/queue/v1/endpoints.py +0 -160
  135. octavia/controller/worker/v1/__init__.py +0 -11
  136. octavia/controller/worker/v1/controller_worker.py +0 -1157
  137. octavia/controller/worker/v1/flows/__init__.py +0 -11
  138. octavia/controller/worker/v1/flows/amphora_flows.py +0 -610
  139. octavia/controller/worker/v1/flows/health_monitor_flows.py +0 -105
  140. octavia/controller/worker/v1/flows/l7policy_flows.py +0 -94
  141. octavia/controller/worker/v1/flows/l7rule_flows.py +0 -100
  142. octavia/controller/worker/v1/flows/listener_flows.py +0 -128
  143. octavia/controller/worker/v1/flows/load_balancer_flows.py +0 -692
  144. octavia/controller/worker/v1/flows/member_flows.py +0 -230
  145. octavia/controller/worker/v1/flows/pool_flows.py +0 -127
  146. octavia/controller/worker/v1/tasks/__init__.py +0 -11
  147. octavia/controller/worker/v1/tasks/amphora_driver_tasks.py +0 -453
  148. octavia/controller/worker/v1/tasks/cert_task.py +0 -51
  149. octavia/controller/worker/v1/tasks/compute_tasks.py +0 -335
  150. octavia/controller/worker/v1/tasks/database_tasks.py +0 -2756
  151. octavia/controller/worker/v1/tasks/lifecycle_tasks.py +0 -173
  152. octavia/controller/worker/v1/tasks/model_tasks.py +0 -41
  153. octavia/controller/worker/v1/tasks/network_tasks.py +0 -970
  154. octavia/controller/worker/v1/tasks/retry_tasks.py +0 -74
  155. octavia/tests/unit/api/drivers/amphora_driver/v1/__init__.py +0 -11
  156. octavia/tests/unit/api/drivers/amphora_driver/v1/test_driver.py +0 -824
  157. octavia/tests/unit/controller/queue/v1/__init__.py +0 -11
  158. octavia/tests/unit/controller/queue/v1/test_consumer.py +0 -61
  159. octavia/tests/unit/controller/queue/v1/test_endpoints.py +0 -189
  160. octavia/tests/unit/controller/worker/v1/__init__.py +0 -11
  161. octavia/tests/unit/controller/worker/v1/flows/__init__.py +0 -11
  162. octavia/tests/unit/controller/worker/v1/flows/test_amphora_flows.py +0 -474
  163. octavia/tests/unit/controller/worker/v1/flows/test_health_monitor_flows.py +0 -72
  164. octavia/tests/unit/controller/worker/v1/flows/test_l7policy_flows.py +0 -67
  165. octavia/tests/unit/controller/worker/v1/flows/test_l7rule_flows.py +0 -67
  166. octavia/tests/unit/controller/worker/v1/flows/test_listener_flows.py +0 -91
  167. octavia/tests/unit/controller/worker/v1/flows/test_load_balancer_flows.py +0 -431
  168. octavia/tests/unit/controller/worker/v1/flows/test_member_flows.py +0 -106
  169. octavia/tests/unit/controller/worker/v1/flows/test_pool_flows.py +0 -77
  170. octavia/tests/unit/controller/worker/v1/tasks/__init__.py +0 -11
  171. octavia/tests/unit/controller/worker/v1/tasks/test_amphora_driver_tasks.py +0 -792
  172. octavia/tests/unit/controller/worker/v1/tasks/test_cert_task.py +0 -46
  173. octavia/tests/unit/controller/worker/v1/tasks/test_compute_tasks.py +0 -634
  174. octavia/tests/unit/controller/worker/v1/tasks/test_database_tasks.py +0 -2615
  175. octavia/tests/unit/controller/worker/v1/tasks/test_database_tasks_quota.py +0 -415
  176. octavia/tests/unit/controller/worker/v1/tasks/test_lifecycle_tasks.py +0 -401
  177. octavia/tests/unit/controller/worker/v1/tasks/test_model_tasks.py +0 -44
  178. octavia/tests/unit/controller/worker/v1/tasks/test_network_tasks.py +0 -1788
  179. octavia/tests/unit/controller/worker/v1/tasks/test_retry_tasks.py +0 -47
  180. octavia/tests/unit/controller/worker/v1/test_controller_worker.py +0 -2096
  181. octavia-12.0.0.0rc2.dist-info/pbr.json +0 -1
  182. {octavia-12.0.0.0rc2.data → octavia-13.0.0.0rc1.data}/data/share/octavia/LICENSE +0 -0
  183. {octavia-12.0.0.0rc2.data → octavia-13.0.0.0rc1.data}/data/share/octavia/diskimage-create/README.rst +0 -0
  184. {octavia-12.0.0.0rc2.data → octavia-13.0.0.0rc1.data}/data/share/octavia/diskimage-create/diskimage-create.sh +0 -0
  185. {octavia-12.0.0.0rc2.data → octavia-13.0.0.0rc1.data}/data/share/octavia/diskimage-create/image-tests.sh +0 -0
  186. {octavia-12.0.0.0rc2.data → octavia-13.0.0.0rc1.data}/data/share/octavia/diskimage-create/requirements.txt +0 -0
  187. {octavia-12.0.0.0rc2.data → octavia-13.0.0.0rc1.data}/data/share/octavia/diskimage-create/test-requirements.txt +0 -0
  188. {octavia-12.0.0.0rc2.data → octavia-13.0.0.0rc1.data}/data/share/octavia/diskimage-create/tox.ini +0 -0
  189. {octavia-12.0.0.0rc2.data → octavia-13.0.0.0rc1.data}/data/share/octavia/diskimage-create/version.txt +0 -0
  190. {octavia-12.0.0.0rc2.data → octavia-13.0.0.0rc1.data}/scripts/octavia-wsgi +0 -0
  191. {octavia-12.0.0.0rc2.dist-info → octavia-13.0.0.0rc1.dist-info}/LICENSE +0 -0
  192. {octavia-12.0.0.0rc2.dist-info → octavia-13.0.0.0rc1.dist-info}/WHEEL +0 -0
  193. {octavia-12.0.0.0rc2.dist-info → octavia-13.0.0.0rc1.dist-info}/top_level.txt +0 -0
@@ -123,7 +123,7 @@ class TestHaproxyAmphoraLoadBalancerDriverTest(base.TestCase):
123
123
  vip_subnet=network_models.Subnet(
124
124
  id=self.lb.vip.subnet_id,
125
125
  cidr=FAKE_VIP_SUBNET,
126
- host_routes=[]))
126
+ host_routes=[])).to_dict(recurse=True)
127
127
 
128
128
  @mock.patch('octavia.amphorae.drivers.haproxy.rest_api_driver.'
129
129
  'HaproxyAmphoraLoadBalancerDriver._process_secret')
@@ -167,7 +167,7 @@ class TestHaproxyAmphoraLoadBalancerDriverTest(base.TestCase):
167
167
  self.driver.clients[API_VERSION].upload_config.assert_not_called()
168
168
  self.driver.clients[API_VERSION].reload_listener.assert_not_called()
169
169
 
170
- @mock.patch('octavia.db.api.get_session')
170
+ @mock.patch('octavia.db.api.session')
171
171
  @mock.patch('octavia.db.repositories.ListenerRepository.update')
172
172
  @mock.patch('octavia.common.tls_utils.cert_parser.load_certificates_data')
173
173
  def test_update_amphora_listeners_bad_cert(
@@ -176,12 +176,13 @@ class TestHaproxyAmphoraLoadBalancerDriverTest(base.TestCase):
176
176
  mock_amphora.id = 'mock_amphora_id'
177
177
  mock_amphora.api_version = API_VERSION
178
178
 
179
- mock_get_session.return_value = 'fake_session'
179
+ mock_session = mock_get_session().begin().__enter__()
180
+
180
181
  mock_load_cert.side_effect = [Exception]
181
182
  self.driver.update_amphora_listeners(self.lb,
182
183
  mock_amphora, self.timeout_dict)
183
184
  mock_list_update.assert_called_once_with(
184
- 'fake_session', self.lb.listeners[0].id,
185
+ mock_session, self.lb.listeners[0].id,
185
186
  provisioning_status=constants.ERROR,
186
187
  operating_status=constants.ERROR)
187
188
  self.driver.jinja_combo.build_config.assert_not_called()
@@ -698,43 +699,64 @@ class TestHaproxyAmphoraLoadBalancerDriverTest(base.TestCase):
698
699
  self.assertIsNone(result)
699
700
 
700
701
  def test_post_vip_plug(self):
701
- amphorae_network_config = mock.MagicMock()
702
- amphorae_network_config.get().vip_subnet.cidr = FAKE_CIDR
703
- amphorae_network_config.get().vip_subnet.gateway_ip = FAKE_GATEWAY
704
- amphorae_network_config.get().vip_subnet.host_routes = self.host_routes
705
- amphorae_network_config.get().vip_subnet.to_dict.return_value = {
702
+ vip_subnet = mock.MagicMock()
703
+ vip_subnet.cidr = FAKE_CIDR
704
+ vip_subnet.gateway_ip = FAKE_GATEWAY
705
+ vip_subnet.host_routes = self.host_routes
706
+ vip_subnet.to_dict.return_value = {
706
707
  'cidr': FAKE_CIDR,
707
708
  'gateway_ip': FAKE_GATEWAY,
708
709
  'host_routes': [
709
710
  hr.to_dict(recurse=True)
710
711
  for hr in self.host_routes]
711
712
  }
713
+
714
+ amphorae_network_config = mock.MagicMock()
715
+ amphorae_network_config.get().vip_subnet = vip_subnet
712
716
  amphorae_network_config.get().vrrp_port = self.port
713
- self.driver.post_vip_plug(self.amp, self.lb, amphorae_network_config)
717
+ self.driver.post_vip_plug(self.amp, self.lb, amphorae_network_config,
718
+ self.port, vip_subnet,
719
+ additional_vip_data=[])
714
720
  self.driver.clients[API_VERSION].plug_vip.assert_called_once_with(
715
721
  self.amp, self.lb.vip.ip_address, self.subnet_info)
716
722
 
717
723
  def test_post_vip_plug_additional_vips(self):
718
- amphorae_network_config = mock.MagicMock()
719
- amphorae_network_config.get().vip_subnet.cidr = FAKE_CIDR
720
- amphorae_network_config.get().vip_subnet.gateway_ip = FAKE_GATEWAY
721
- amphorae_network_config.get().vip_subnet.host_routes = self.host_routes
722
- amphorae_network_config.get().vip_subnet.to_dict.return_value = {
724
+ vip_subnet = mock.MagicMock()
725
+ vip_subnet.cidr = FAKE_CIDR
726
+ vip_subnet.gateway_ip = FAKE_GATEWAY
727
+ vip_subnet.host_routes = self.host_routes
728
+ vip_subnet.to_dict.return_value = {
723
729
  'cidr': FAKE_CIDR,
724
730
  'gateway_ip': FAKE_GATEWAY,
725
731
  'host_routes': [
726
732
  hr.to_dict(recurse=True)
727
733
  for hr in self.host_routes]
728
734
  }
735
+
736
+ amphorae_network_config = mock.MagicMock()
737
+ amphorae_network_config.get().vip_subnet = vip_subnet
729
738
  amphorae_network_config.get().vrrp_port = self.port
739
+
740
+ vip1_subnet = mock.MagicMock()
741
+ vip1_subnet.cidr = mock.Mock()
742
+ vip1_subnet.gateway_ip = mock.Mock()
743
+ vip1_subnet.host_routes = self.host_routes
744
+ vip1_subnet.to_dict.return_value = {
745
+ 'cidr': vip1_subnet.cidr,
746
+ 'gateway_ip': vip1_subnet.gateway_ip,
747
+ 'host_routes': [
748
+ hr.to_dict(recurse=True)
749
+ for hr in self.host_routes]
750
+ }
730
751
  additional_vip1 = mock.MagicMock()
731
752
  additional_vip1.ip_address = mock.Mock()
732
- additional_vip1.subnet.cidr = mock.Mock()
733
- additional_vip1.subnet.gateway_ip = mock.Mock()
734
- additional_vip1.subnet.host_routes = self.host_routes
753
+ additional_vip1.subnet = vip1_subnet
735
754
  additional_vip_data = [additional_vip1]
736
- self.driver.post_vip_plug(self.amp, self.lb, amphorae_network_config,
737
- additional_vip_data=additional_vip_data)
755
+ self.driver.post_vip_plug(
756
+ self.amp, self.lb,
757
+ amphorae_network_config,
758
+ self.port, vip_subnet,
759
+ additional_vip_data=additional_vip_data)
738
760
  netinfo = self.subnet_info.copy()
739
761
  netinfo['additional_vips'] = [
740
762
  {
@@ -73,16 +73,6 @@ class TestHeartbeatUDP(base.TestCase):
73
73
  total_connections=random.randrange(1000000000),
74
74
  request_errors=random.randrange(1000000000),
75
75
  received_time=float(random.randrange(1000000000)))
76
- self.listener_stats_dict = {
77
- self.listener_id: {
78
- "request_errors": self.listener_stats.request_errors,
79
- "active_connections":
80
- self.listener_stats.active_connections,
81
- "total_connections": self.listener_stats.total_connections,
82
- "bytes_in": self.listener_stats.bytes_in,
83
- "bytes_out": self.listener_stats.bytes_out,
84
- }
85
- }
86
76
 
87
77
  @mock.patch('octavia.statistics.stats_base.update_stats_via_driver')
88
78
  def test_update_stats_v1(self, mock_stats_base):
@@ -130,11 +120,15 @@ class TestHeartbeatUDP(base.TestCase):
130
120
  "totconns": self.listener_stats.total_connections,
131
121
  "rx": self.listener_stats.bytes_in,
132
122
  "tx": self.listener_stats.bytes_out,
133
- },
134
- "pools": {
135
- "pool-id-1:{}".format(self.listener_id): {
136
- "status": constants.UP,
137
- "members": {"member-id-1": constants.ONLINE}
123
+ }
124
+ }
125
+ },
126
+ "pools": {
127
+ "pool-id-1:{}".format(self.listener_id): {
128
+ "status": constants.UP,
129
+ "members": {
130
+ "member-id-1": {
131
+ "status": constants.ONLINE
138
132
  }
139
133
  }
140
134
  }
@@ -162,11 +156,15 @@ class TestHeartbeatUDP(base.TestCase):
162
156
  "totconns": self.listener_stats.total_connections,
163
157
  "rx": self.listener_stats.bytes_in,
164
158
  "tx": self.listener_stats.bytes_out,
165
- },
166
- "pools": {
167
- "pool-id-1:{}".format(self.listener_id): {
168
- "status": constants.UP,
169
- "members": {"member-id-1": constants.ONLINE}
159
+ }
160
+ }
161
+ },
162
+ "pools": {
163
+ "pool-id-1:{}".format(self.listener_id): {
164
+ "status": constants.UP,
165
+ "members": {
166
+ "member-id-1": {
167
+ "status": constants.ONLINE
170
168
  }
171
169
  }
172
170
  }
@@ -267,7 +267,7 @@ class TestVRRPRestDriver(base.TestCase):
267
267
  mock_subnet.gateway_ip = '10.1.0.1'
268
268
  mock_subnet.host_routes = []
269
269
  amp_net_config = n_data_models.AmphoraNetworkConfig(
270
- vip_subnet=mock_subnet)
270
+ vip_subnet=mock_subnet).to_dict(recurse=True)
271
271
 
272
272
  config = self.templater.build_keepalived_config(
273
273
  self.lb, self.amphora1, amp_net_config)
@@ -279,7 +279,7 @@ class TestVRRPRestDriver(base.TestCase):
279
279
  mock_subnet.gateway_ip = '2001:db8::ff'
280
280
  mock_subnet.host_routes = []
281
281
  amp_net_config = n_data_models.AmphoraNetworkConfig(
282
- vip_subnet=mock_subnet)
282
+ vip_subnet=mock_subnet).to_dict(recurse=True)
283
283
 
284
284
  config = self.templater.build_keepalived_config(
285
285
  self.lbv6, self.amphora1v6, amp_net_config)
@@ -302,7 +302,7 @@ class TestVRRPRestDriver(base.TestCase):
302
302
  )
303
303
  amp_net_config = n_data_models.AmphoraNetworkConfig(
304
304
  vip_subnet=mock_subnet1,
305
- additional_vip_data=[additional_vip])
305
+ additional_vip_data=[additional_vip]).to_dict(recurse=True)
306
306
 
307
307
  config = self.templater.build_keepalived_config(
308
308
  self.lb, self.amphora1, amp_net_config)
@@ -315,7 +315,7 @@ class TestVRRPRestDriver(base.TestCase):
315
315
  )
316
316
  amp_net_config = n_data_models.AmphoraNetworkConfig(
317
317
  vip_subnet=mock_subnet2,
318
- additional_vip_data=[additional_vip])
318
+ additional_vip_data=[additional_vip]).to_dict(recurse=True)
319
319
 
320
320
  config = self.templater.build_keepalived_config(
321
321
  self.lbv6, self.amphora1v6, amp_net_config)
@@ -123,8 +123,11 @@ class TestNoopAmphoraLoadBalancerDriver(base.TestCase):
123
123
  self.amphora.id, self.port.id)])
124
124
 
125
125
  def test_post_vip_plug(self):
126
+ port = network_models.Port(id=uuidutils.generate_uuid())
127
+ subnet = network_models.Subnet(id=uuidutils.generate_uuid())
126
128
  self.driver.post_vip_plug(self.amphora, self.load_balancer,
127
- self.amphorae_net_configs)
129
+ self.amphorae_net_configs,
130
+ port, subnet)
128
131
  expected_method_and_args = (self.load_balancer.id,
129
132
  self.amphorae_net_configs,
130
133
  'post_vip_plug')
@@ -27,7 +27,7 @@ class TestDriverGet(base.TestCase):
27
27
  @mock.patch('octavia.db.api.get_session')
28
28
  def _test_process_get_object(self, object_name, mock_object_repo,
29
29
  mock_object_to_provider, mock_get_session):
30
- mock_get_session.return_value = 'bogus_session'
30
+ mock_get_session.return_value = mock.MagicMock()
31
31
  object_repo_mock = mock.MagicMock()
32
32
  mock_object_repo.return_value = object_repo_mock
33
33
  db_object_mock = mock.MagicMock()
@@ -47,7 +47,7 @@ class TestDriverGet(base.TestCase):
47
47
 
48
48
  mock_object_repo.assert_called_once_with()
49
49
  object_repo_mock.get.assert_called_once_with(
50
- 'bogus_session', id=object_id, show_deleted=False)
50
+ mock_get_session(), id=object_id, show_deleted=False)
51
51
  mock_object_to_provider.assert_called_once_with(db_object_mock)
52
52
  self.assertEqual(ref_prov_dict, result)
53
53
 
@@ -61,7 +61,7 @@ class TestDriverGet(base.TestCase):
61
61
 
62
62
  mock_object_repo.assert_called_once_with()
63
63
  object_repo_mock.get.assert_called_once_with(
64
- 'bogus_session', id=object_id, show_deleted=False)
64
+ mock_get_session(), id=object_id, show_deleted=False)
65
65
  mock_object_to_provider.assert_not_called()
66
66
  self.assertEqual({}, result)
67
67
 
@@ -39,7 +39,7 @@ class TestDriverUpdater(base.TestCase):
39
39
  mock_pool_repo, mock_l7r_repo, mock_l7p_repo, mock_list_repo,
40
40
  mock_lb_repo):
41
41
  super().setUp()
42
- self.mock_session = "FAKE_DB_SESSION"
42
+ self.mock_session = mock.MagicMock()
43
43
  mock_get_session.return_value = self.mock_session
44
44
 
45
45
  member_mock = mock.MagicMock()
@@ -98,34 +98,32 @@ class TestDriverUpdater(base.TestCase):
98
98
  @mock.patch('octavia.db.repositories.Repositories.decrement_quota')
99
99
  @mock.patch('octavia.db.api.get_session')
100
100
  def test_decrement_quota(self, mock_get_session, mock_dec_quota):
101
- mock_session = mock.MagicMock()
102
- mock_get_session.return_value = mock_session
103
101
  mock_dec_quota.side_effect = [mock.DEFAULT,
104
102
  exceptions.OctaviaException('Boom')]
105
103
 
106
104
  self.driver_updater._decrement_quota(self.mock_lb_repo,
107
105
  'FakeName', self.lb_id)
108
106
  mock_dec_quota.assert_called_once_with(
109
- mock_session, self.mock_lb_repo.model_class.__data_model__,
107
+ self.mock_session, self.mock_lb_repo.model_class.__data_model__,
110
108
  self.lb_project_id)
111
- mock_session.commit.assert_called_once()
112
- mock_session.rollback.assert_not_called()
109
+ self.mock_session.commit.assert_called_once()
110
+ self.mock_session.rollback.assert_not_called()
113
111
 
114
112
  # Test exception path
115
113
  mock_dec_quota.reset_mock()
116
- mock_session.reset_mock()
114
+ self.mock_session.reset_mock()
117
115
  self.assertRaises(exceptions.OctaviaException,
118
116
  self.driver_updater._decrement_quota,
119
117
  self.mock_lb_repo, 'FakeName', self.lb_id)
120
118
  mock_dec_quota.assert_called_once_with(
121
- mock_session, self.mock_lb_repo.model_class.__data_model__,
119
+ self.mock_session, self.mock_lb_repo.model_class.__data_model__,
122
120
  self.lb_project_id)
123
- mock_session.commit.assert_not_called()
124
- mock_session.rollback.assert_called_once()
121
+ self.mock_session.commit.assert_not_called()
122
+ self.mock_session.rollback.assert_called_once()
125
123
 
126
124
  # Test already deleted path
127
125
  mock_dec_quota.reset_mock()
128
- mock_session.reset_mock()
126
+ self.mock_session.reset_mock()
129
127
  # Create a local mock LB and LB_repo for this test
130
128
  mock_lb = mock.MagicMock()
131
129
  mock_lb.id = self.lb_id
@@ -136,8 +134,8 @@ class TestDriverUpdater(base.TestCase):
136
134
  self.driver_updater._decrement_quota(mock_lb_repo,
137
135
  'FakeName', self.lb_id)
138
136
  mock_dec_quota.assert_not_called()
139
- mock_session.commit.assert_not_called()
140
- mock_session.rollback.assert_called_once()
137
+ self.mock_session.commit.assert_not_called()
138
+ self.mock_session.rollback.assert_called_once()
141
139
 
142
140
  @mock.patch('octavia.api.drivers.driver_agent.driver_updater.'
143
141
  'DriverUpdater._decrement_quota')
@@ -25,6 +25,8 @@ from octavia.common import rpc
25
25
  # needed for tests to function when run independently:
26
26
  from octavia.common import config # noqa: F401
27
27
 
28
+ from octavia.tests import fixtures as oc_fixtures
29
+
28
30
 
29
31
  class TestCase(testtools.TestCase):
30
32
 
@@ -34,6 +36,8 @@ class TestCase(testtools.TestCase):
34
36
  self.addCleanup(mock.patch.stopall)
35
37
  self.addCleanup(self.clean_caches)
36
38
 
39
+ self.warning_fixture = self.useFixture(oc_fixtures.WarningsFixture())
40
+
37
41
  def clean_caches(self):
38
42
  clients.NovaAuth.nova_client = None
39
43
  clients.NeutronAuth.neutron_client = None
@@ -44,6 +48,8 @@ class TestRpc(testtools.TestCase):
44
48
  super().__init__(*args, **kwargs)
45
49
  self._buses = {}
46
50
 
51
+ self.warning_fixture = self.useFixture(oc_fixtures.WarningsFixture())
52
+
47
53
  def _fake_create_transport(self, url):
48
54
  if url not in self._buses:
49
55
  self._buses[url] = messaging.get_rpc_transport(
@@ -23,8 +23,8 @@ class TestInterfaceCMD(base.TestCase):
23
23
  def setUp(self):
24
24
  super().setUp()
25
25
 
26
- self.interface1 = interface_file.InterfaceFile("eth1")
27
- self.interface2 = interface_file.InterfaceFile("eth2")
26
+ self.interface1 = interface_file.InterfaceFile("eth1", if_type="type1")
27
+ self.interface2 = interface_file.InterfaceFile("eth2", if_type="type2")
28
28
 
29
29
  def test_interfaces_find(self):
30
30
  controller = mock.Mock()
@@ -32,8 +32,8 @@ class TestUpgradeChecks(base.TestCase):
32
32
  def test__check_amphorav2_not_enabled(self):
33
33
  self.conf = self.useFixture(oslo_fixture.Config(cfg.CONF))
34
34
  self.conf.config(group='api_settings',
35
- default_provider_driver=constants.AMPHORA,
36
- enabled_provider_drivers={constants.AMPHORA: "Test"})
35
+ default_provider_driver='other_provider',
36
+ enabled_provider_drivers={'other_provider': "Test"})
37
37
  check_result = self.cmd._check_amphorav2()
38
38
  self.assertEqual(
39
39
  Code.SUCCESS, check_result.code)
@@ -49,6 +49,8 @@ class TestHaproxyCfg(base.TestCase):
49
49
  fe = ("frontend sample_listener_id_1\n"
50
50
  " maxconn {maxconn}\n"
51
51
  " redirect scheme https if !{{ ssl_fc }}\n"
52
+ " http-response set-header Strict-Transport-Security "
53
+ "\"max-age=10000000; includeSubDomains; preload;\"\n"
52
54
  " bind 10.0.0.2:443 "
53
55
  "ssl crt-list {crt_list} "
54
56
  "ca-file /var/lib/octavia/certs/sample_loadbalancer_id_1/"
@@ -107,6 +109,8 @@ class TestHaproxyCfg(base.TestCase):
107
109
  fe = ("frontend sample_listener_id_1\n"
108
110
  " maxconn {maxconn}\n"
109
111
  " redirect scheme https if !{{ ssl_fc }}\n"
112
+ " http-response set-header Strict-Transport-Security "
113
+ "\"max-age=10000000; includeSubDomains; preload;\"\n"
110
114
  " bind 10.0.0.2:443 ssl crt-list {crt_list}"
111
115
  " ciphers {ciphers} no-sslv3 no-tlsv10 no-tlsv11 alpn {alpn}\n"
112
116
  " mode http\n"
@@ -158,6 +162,8 @@ class TestHaproxyCfg(base.TestCase):
158
162
  fe = ("frontend sample_listener_id_1\n"
159
163
  " maxconn {maxconn}\n"
160
164
  " redirect scheme https if !{{ ssl_fc }}\n"
165
+ " http-response set-header Strict-Transport-Security "
166
+ "\"max-age=10000000; includeSubDomains; preload;\"\n"
161
167
  " bind 10.0.0.2:443 ssl crt-list {crt_list} "
162
168
  "no-sslv3 no-tlsv10 no-tlsv11 alpn {alpn}\n"
163
169
  " mode http\n"
@@ -208,6 +214,8 @@ class TestHaproxyCfg(base.TestCase):
208
214
  fe = ("frontend sample_listener_id_1\n"
209
215
  " maxconn {maxconn}\n"
210
216
  " redirect scheme https if !{{ ssl_fc }}\n"
217
+ " http-response set-header Strict-Transport-Security "
218
+ "\"max-age=10000000; includeSubDomains; preload;\"\n"
211
219
  " bind 10.0.0.2:443 "
212
220
  "ssl crt-list {crt_list} "
213
221
  "ca-file /var/lib/octavia/certs/sample_loadbalancer_id_1/"
@@ -266,6 +274,8 @@ class TestHaproxyCfg(base.TestCase):
266
274
  fe = ("frontend sample_listener_id_1\n"
267
275
  " maxconn {maxconn}\n"
268
276
  " redirect scheme https if !{{ ssl_fc }}\n"
277
+ " http-response set-header Strict-Transport-Security "
278
+ "\"max-age=10000000; includeSubDomains; preload;\"\n"
269
279
  " bind 10.0.0.2:443 ssl crt-list {crt_list} "
270
280
  "alpn {alpn}\n"
271
281
  " mode http\n"
@@ -318,6 +328,8 @@ class TestHaproxyCfg(base.TestCase):
318
328
  fe = ("frontend sample_listener_id_1\n"
319
329
  " maxconn {maxconn}\n"
320
330
  " redirect scheme https if !{{ ssl_fc }}\n"
331
+ " http-response set-header Strict-Transport-Security "
332
+ "\"max-age=10000000; includeSubDomains; preload;\"\n"
321
333
  " bind 10.0.0.2:443 ssl crt-list {crt_list} "
322
334
  "ciphers {ciphers} no-sslv3 no-tlsv10 no-tlsv11 alpn {alpn}\n"
323
335
  " mode http\n"
@@ -370,6 +382,8 @@ class TestHaproxyCfg(base.TestCase):
370
382
  fe = ("frontend sample_listener_id_1\n"
371
383
  " maxconn {maxconn}\n"
372
384
  " redirect scheme https if !{{ ssl_fc }}\n"
385
+ " http-response set-header Strict-Transport-Security "
386
+ "\"max-age=10000000; includeSubDomains; preload;\"\n"
373
387
  " bind 10.0.0.2:443 ssl crt-list {crt_list} "
374
388
  "ciphers {ciphers} no-sslv3 no-tlsv10 no-tlsv11\n"
375
389
  " mode http\n"
@@ -412,6 +426,119 @@ class TestHaproxyCfg(base.TestCase):
412
426
  frontend=fe, backend=be),
413
427
  rendered_obj)
414
428
 
429
+ def test_render_template_tls_no_alpn_hsts_max_age_only(self):
430
+ conf = self.useFixture(oslo_fixture.Config(cfg.CONF))
431
+ conf.config(group="haproxy_amphora", base_cert_dir='/fake_cert_dir')
432
+ FAKE_CRT_LIST_FILENAME = os.path.join(
433
+ CONF.haproxy_amphora.base_cert_dir,
434
+ 'sample_loadbalancer_id_1/sample_listener_id_1.pem')
435
+ fe = ("frontend sample_listener_id_1\n"
436
+ " maxconn {maxconn}\n"
437
+ " redirect scheme https if !{{ ssl_fc }}\n"
438
+ " http-response set-header Strict-Transport-Security "
439
+ "\"max-age=10000000;\"\n"
440
+ " bind 10.0.0.2:443 ssl crt-list {crt_list} "
441
+ "ciphers {ciphers} no-sslv3 no-tlsv10 no-tlsv11\n"
442
+ " mode http\n"
443
+ " default_backend sample_pool_id_1:sample_listener_id_1\n"
444
+ " timeout client 50000\n").format(
445
+ maxconn=constants.HAPROXY_DEFAULT_MAXCONN,
446
+ crt_list=FAKE_CRT_LIST_FILENAME,
447
+ ciphers=constants.CIPHERS_OWASP_SUITE_B)
448
+ be = ("backend sample_pool_id_1:sample_listener_id_1\n"
449
+ " mode http\n"
450
+ " balance roundrobin\n"
451
+ " cookie SRV insert indirect nocache\n"
452
+ " timeout check 31s\n"
453
+ " option httpchk GET /index.html HTTP/1.0\\r\\n\n"
454
+ " http-check expect rstatus 418\n"
455
+ " fullconn {maxconn}\n"
456
+ " option allbackups\n"
457
+ " timeout connect 5000\n"
458
+ " timeout server 50000\n"
459
+ " server sample_member_id_1 10.0.0.99:82 "
460
+ "weight 13 check inter 30s fall 3 rise 2 "
461
+ "cookie sample_member_id_1\n"
462
+ " server sample_member_id_2 10.0.0.98:82 "
463
+ "weight 13 check inter 30s fall 3 rise 2 "
464
+ "cookie sample_member_id_2\n\n").format(
465
+ maxconn=constants.HAPROXY_DEFAULT_MAXCONN)
466
+ rendered_obj = self.jinja_cfg.render_loadbalancer_obj(
467
+ sample_configs_combined.sample_amphora_tuple(),
468
+ [sample_configs_combined.sample_listener_tuple(
469
+ proto='TERMINATED_HTTPS', tls=True,
470
+ alpn_protocols=None, hsts_include_subdomains=False,
471
+ hsts_preload=False)],
472
+ tls_certs={'cont_id_1':
473
+ sample_configs_combined.sample_tls_container_tuple(
474
+ id='tls_container_id',
475
+ certificate='ImAalsdkfjCert',
476
+ private_key='ImAsdlfksdjPrivateKey',
477
+ primary_cn="FakeCN")})
478
+ self.assertEqual(
479
+ sample_configs_combined.sample_base_expected_config(
480
+ frontend=fe, backend=be),
481
+ rendered_obj)
482
+
483
+ def test_render_template_tls_no_hsts(self):
484
+ conf = self.useFixture(oslo_fixture.Config(cfg.CONF))
485
+ conf.config(group="haproxy_amphora", base_cert_dir='/fake_cert_dir')
486
+ FAKE_CRT_LIST_FILENAME = os.path.join(
487
+ CONF.haproxy_amphora.base_cert_dir,
488
+ 'sample_loadbalancer_id_1/sample_listener_id_1.pem')
489
+ fe = ("frontend sample_listener_id_1\n"
490
+ " maxconn {maxconn}\n"
491
+ " redirect scheme https if !{{ ssl_fc }}\n"
492
+ " bind 10.0.0.2:443 "
493
+ "ssl crt-list {crt_list} "
494
+ "ca-file /var/lib/octavia/certs/sample_loadbalancer_id_1/"
495
+ "client_ca.pem verify required crl-file /var/lib/octavia/"
496
+ "certs/sample_loadbalancer_id_1/SHA_ID.pem ciphers {ciphers} "
497
+ "no-sslv3 no-tlsv10 no-tlsv11 alpn {alpn}\n"
498
+ " mode http\n"
499
+ " default_backend sample_pool_id_1:sample_listener_id_1\n"
500
+ " timeout client 50000\n").format(
501
+ maxconn=constants.HAPROXY_DEFAULT_MAXCONN,
502
+ crt_list=FAKE_CRT_LIST_FILENAME,
503
+ ciphers=constants.CIPHERS_OWASP_SUITE_B,
504
+ alpn=",".join(constants.AMPHORA_SUPPORTED_ALPN_PROTOCOLS))
505
+ be = ("backend sample_pool_id_1:sample_listener_id_1\n"
506
+ " mode http\n"
507
+ " balance roundrobin\n"
508
+ " cookie SRV insert indirect nocache\n"
509
+ " timeout check 31s\n"
510
+ " option httpchk GET /index.html HTTP/1.0\\r\\n\n"
511
+ " http-check expect rstatus 418\n"
512
+ " fullconn {maxconn}\n"
513
+ " option allbackups\n"
514
+ " timeout connect 5000\n"
515
+ " timeout server 50000\n"
516
+ " server sample_member_id_1 10.0.0.99:82 "
517
+ "weight 13 check inter 30s fall 3 rise 2 "
518
+ "cookie sample_member_id_1\n"
519
+ " server sample_member_id_2 10.0.0.98:82 "
520
+ "weight 13 check inter 30s fall 3 rise 2 cookie "
521
+ "sample_member_id_2\n\n").format(
522
+ maxconn=constants.HAPROXY_DEFAULT_MAXCONN)
523
+ tls_tupe = {'cont_id_1':
524
+ sample_configs_combined.sample_tls_container_tuple(
525
+ id='tls_container_id',
526
+ certificate='imaCert1', private_key='imaPrivateKey1',
527
+ primary_cn='FakeCN'),
528
+ 'cont_id_ca': 'client_ca.pem',
529
+ 'cont_id_crl': 'SHA_ID.pem'}
530
+ rendered_obj = self.jinja_cfg.render_loadbalancer_obj(
531
+ sample_configs_combined.sample_amphora_tuple(),
532
+ [sample_configs_combined.sample_listener_tuple(
533
+ proto='TERMINATED_HTTPS', tls=True, sni=True,
534
+ client_ca_cert=True, client_crl_cert=True,
535
+ hsts_max_age=None)],
536
+ tls_tupe)
537
+ self.assertEqual(
538
+ sample_configs_combined.sample_base_expected_config(
539
+ frontend=fe, backend=be),
540
+ rendered_obj)
541
+
415
542
  def test_render_template_http(self):
416
543
  be = ("backend sample_pool_id_1:sample_listener_id_1\n"
417
544
  " mode http\n"
@@ -922,7 +1049,7 @@ class TestHaproxyCfg(base.TestCase):
922
1049
  be = ("backend sample_pool_id_1:sample_listener_id_1\n"
923
1050
  " mode http\n"
924
1051
  " balance roundrobin\n"
925
- " stick-table type ip size 10k\n"
1052
+ " stick-table type ipv6 size 10k\n"
926
1053
  " stick on src\n"
927
1054
  " timeout check 31s\n"
928
1055
  " option httpchk GET /index.html HTTP/1.0\\r\\n\n"
@@ -1559,6 +1686,28 @@ class TestHaproxyCfg(base.TestCase):
1559
1686
  self.assertLess(ret['global_connection_limit'],
1560
1687
  connection_limit_sum)
1561
1688
 
1689
+ def test_transform_with_disabled_listeners(self):
1690
+ in_amphora = sample_configs_combined.sample_amphora_tuple()
1691
+
1692
+ in_listeners = []
1693
+
1694
+ connection_limit_sum = 0
1695
+
1696
+ in_listener = (
1697
+ sample_configs_combined.sample_listener_tuple())
1698
+ connection_limit_sum += constants.HAPROXY_DEFAULT_MAXCONN
1699
+ in_listeners.append(in_listener)
1700
+
1701
+ disabled_listener = (
1702
+ sample_configs_combined.sample_listener_tuple(enabled=False))
1703
+ in_listeners.append(disabled_listener)
1704
+
1705
+ ret = self.jinja_cfg._transform_loadbalancer(
1706
+ in_amphora, in_listeners[0].load_balancer,
1707
+ in_listeners, None, {})
1708
+ self.assertEqual(ret['global_connection_limit'],
1709
+ connection_limit_sum)
1710
+
1562
1711
  def test_transform_amphora(self):
1563
1712
  in_amphora = sample_configs_combined.sample_amphora_tuple()
1564
1713
  ret = self.jinja_cfg._transform_amphora(in_amphora, {})
@@ -1758,6 +1907,8 @@ class TestHaproxyCfg(base.TestCase):
1758
1907
  fe = ("frontend sample_listener_id_1\n"
1759
1908
  " maxconn {maxconn}\n"
1760
1909
  " redirect scheme https if !{{ ssl_fc }}\n"
1910
+ " http-response set-header Strict-Transport-Security "
1911
+ "\"max-age=10000000; includeSubDomains; preload;\"\n"
1761
1912
  " bind 10.0.0.2:443 ciphers {ciphers} "
1762
1913
  "no-sslv3 no-tlsv10 no-tlsv11 alpn {alpn}\n"
1763
1914
  " mode http\n"
@@ -707,7 +707,9 @@ def sample_listener_tuple(proto=None, monitor=True, alloc_default_pool=True,
707
707
  backend_alpn_protocols=constants.
708
708
  AMPHORA_SUPPORTED_ALPN_PROTOCOLS,
709
709
  include_pools=True,
710
- additional_vips=False):
710
+ additional_vips=False,
711
+ hsts_max_age=10_000_000,
712
+ hsts_include_subdomains=True, hsts_preload=True):
711
713
  proto = 'HTTP' if proto is None else proto
712
714
  if be_proto is None:
713
715
  be_proto = 'HTTP' if proto == 'TERMINATED_HTTPS' else proto
@@ -731,7 +733,9 @@ def sample_listener_tuple(proto=None, monitor=True, alloc_default_pool=True,
731
733
  'timeout_tcp_inspect, client_ca_tls_certificate_id, '
732
734
  'client_ca_tls_certificate, client_authentication, '
733
735
  'client_crl_container_id, provisioning_status, '
734
- 'tls_ciphers, tls_versions, alpn_protocols')
736
+ 'tls_ciphers, tls_versions, alpn_protocols, '
737
+ 'hsts_max_age, hsts_include_subdomains, hsts_preload'
738
+ )
735
739
  if l7:
736
740
  pools = [
737
741
  sample_pool_tuple(
@@ -859,7 +863,10 @@ def sample_listener_tuple(proto=None, monitor=True, alloc_default_pool=True,
859
863
  provisioning_status=provisioning_status,
860
864
  tls_ciphers=tls_ciphers,
861
865
  tls_versions=tls_versions,
862
- alpn_protocols=alpn_protocols
866
+ alpn_protocols=alpn_protocols,
867
+ hsts_max_age=hsts_max_age,
868
+ hsts_include_subdomains=hsts_include_subdomains,
869
+ hsts_preload=hsts_preload,
863
870
  )
864
871
  if recursive_nest:
865
872
  listener.load_balancer.listeners.append(listener)