octavia 15.0.0__py3-none-any.whl → 16.0.0__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.
- octavia/amphorae/backends/agent/api_server/keepalivedlvs.py +9 -0
- octavia/amphorae/backends/agent/api_server/loadbalancer.py +6 -6
- octavia/amphorae/backends/agent/api_server/plug.py +1 -1
- octavia/amphorae/backends/agent/api_server/util.py +35 -2
- octavia/amphorae/backends/health_daemon/status_message.py +1 -2
- octavia/amphorae/drivers/haproxy/rest_api_driver.py +12 -7
- octavia/api/drivers/amphora_driver/flavor_schema.py +5 -0
- octavia/api/drivers/noop_driver/driver.py +2 -1
- octavia/api/drivers/utils.py +12 -0
- octavia/api/root_controller.py +8 -2
- octavia/api/v2/controllers/base.py +8 -4
- octavia/api/v2/controllers/listener.py +12 -2
- octavia/api/v2/controllers/load_balancer.py +33 -1
- octavia/api/v2/controllers/member.py +58 -4
- octavia/api/v2/types/load_balancer.py +7 -1
- octavia/api/v2/types/member.py +3 -0
- octavia/common/base_taskflow.py +19 -10
- octavia/common/clients.py +8 -2
- octavia/common/config.py +17 -2
- octavia/common/constants.py +6 -0
- octavia/common/data_models.py +32 -2
- octavia/common/exceptions.py +5 -0
- octavia/common/utils.py +4 -1
- octavia/common/validate.py +16 -0
- octavia/compute/drivers/noop_driver/driver.py +30 -1
- octavia/controller/healthmanager/health_manager.py +7 -0
- octavia/controller/worker/v2/flows/amphora_flows.py +3 -5
- octavia/controller/worker/v2/flows/listener_flows.py +2 -1
- octavia/controller/worker/v2/flows/load_balancer_flows.py +38 -0
- octavia/controller/worker/v2/taskflow_jobboard_driver.py +34 -6
- octavia/controller/worker/v2/tasks/compute_tasks.py +9 -5
- octavia/controller/worker/v2/tasks/database_tasks.py +26 -6
- octavia/controller/worker/v2/tasks/network_tasks.py +118 -70
- octavia/db/base_models.py +29 -5
- octavia/db/migration/alembic_migrations/versions/3097e55493ae_add_sg_id_to_vip_table.py +39 -0
- octavia/db/migration/alembic_migrations/versions/8db7a6443785_add_member_vnic_type.py +36 -0
- octavia/db/migration/alembic_migrations/versions/fabf4983846b_add_member_port_table.py +40 -0
- octavia/db/models.py +43 -1
- octavia/db/repositories.py +88 -9
- octavia/network/base.py +29 -12
- octavia/network/data_models.py +2 -1
- octavia/network/drivers/neutron/allowed_address_pairs.py +55 -46
- octavia/network/drivers/neutron/base.py +28 -16
- octavia/network/drivers/neutron/utils.py +2 -2
- octavia/network/drivers/noop_driver/driver.py +150 -29
- octavia/policies/__init__.py +4 -0
- octavia/policies/advanced_rbac.py +95 -0
- octavia/policies/base.py +5 -101
- octavia/policies/keystone_default_roles.py +81 -0
- octavia/policies/loadbalancer.py +13 -0
- octavia/tests/common/constants.py +2 -1
- octavia/tests/common/sample_data_models.py +27 -14
- octavia/tests/functional/amphorae/backend/agent/api_server/test_server.py +5 -4
- octavia/tests/functional/api/drivers/driver_agent/test_driver_agent.py +2 -1
- octavia/tests/functional/api/v2/test_health_monitor.py +1 -1
- octavia/tests/functional/api/v2/test_l7policy.py +1 -1
- octavia/tests/functional/api/v2/test_listener.py +1 -1
- octavia/tests/functional/api/v2/test_load_balancer.py +150 -4
- octavia/tests/functional/api/v2/test_member.py +50 -0
- octavia/tests/functional/api/v2/test_pool.py +1 -1
- octavia/tests/functional/api/v2/test_quotas.py +5 -8
- octavia/tests/functional/db/base.py +6 -6
- octavia/tests/functional/db/test_models.py +124 -1
- octavia/tests/functional/db/test_repositories.py +237 -19
- octavia/tests/unit/amphorae/backends/agent/api_server/test_util.py +89 -1
- octavia/tests/unit/amphorae/drivers/haproxy/test_rest_api_driver_1_0.py +10 -7
- octavia/tests/unit/api/drivers/test_utils.py +6 -1
- octavia/tests/unit/certificates/generator/test_local.py +1 -1
- octavia/tests/unit/common/test_base_taskflow.py +4 -3
- octavia/tests/unit/compute/drivers/noop_driver/test_driver.py +28 -2
- octavia/tests/unit/controller/worker/v2/flows/test_load_balancer_flows.py +27 -1
- octavia/tests/unit/controller/worker/v2/tasks/test_database_tasks.py +28 -6
- octavia/tests/unit/controller/worker/v2/tasks/test_network_tasks.py +100 -79
- octavia/tests/unit/controller/worker/v2/test_taskflow_jobboard_driver.py +8 -0
- octavia/tests/unit/network/drivers/neutron/test_allowed_address_pairs.py +62 -45
- octavia/tests/unit/network/drivers/neutron/test_base.py +7 -7
- octavia/tests/unit/network/drivers/noop_driver/test_driver.py +55 -42
- {octavia-15.0.0.data → octavia-16.0.0.data}/data/share/octavia/diskimage-create/tox.ini +0 -1
- {octavia-15.0.0.dist-info → octavia-16.0.0.dist-info}/AUTHORS +3 -0
- octavia-16.0.0.dist-info/METADATA +156 -0
- {octavia-15.0.0.dist-info → octavia-16.0.0.dist-info}/RECORD +95 -90
- {octavia-15.0.0.dist-info → octavia-16.0.0.dist-info}/WHEEL +1 -1
- {octavia-15.0.0.dist-info → octavia-16.0.0.dist-info}/entry_points.txt +1 -1
- octavia-16.0.0.dist-info/pbr.json +1 -0
- octavia-15.0.0.dist-info/METADATA +0 -156
- octavia-15.0.0.dist-info/pbr.json +0 -1
- {octavia-15.0.0.data → octavia-16.0.0.data}/data/share/octavia/LICENSE +0 -0
- {octavia-15.0.0.data → octavia-16.0.0.data}/data/share/octavia/README.rst +0 -0
- {octavia-15.0.0.data → octavia-16.0.0.data}/data/share/octavia/diskimage-create/README.rst +0 -0
- {octavia-15.0.0.data → octavia-16.0.0.data}/data/share/octavia/diskimage-create/diskimage-create.sh +0 -0
- {octavia-15.0.0.data → octavia-16.0.0.data}/data/share/octavia/diskimage-create/image-tests.sh +0 -0
- {octavia-15.0.0.data → octavia-16.0.0.data}/data/share/octavia/diskimage-create/requirements.txt +0 -0
- {octavia-15.0.0.data → octavia-16.0.0.data}/data/share/octavia/diskimage-create/test-requirements.txt +0 -0
- {octavia-15.0.0.data → octavia-16.0.0.data}/data/share/octavia/diskimage-create/version.txt +0 -0
- {octavia-15.0.0.data → octavia-16.0.0.data}/scripts/octavia-wsgi +0 -0
- {octavia-15.0.0.dist-info → octavia-16.0.0.dist-info}/LICENSE +0 -0
- {octavia-15.0.0.dist-info → octavia-16.0.0.dist-info}/top_level.txt +0 -0
@@ -50,6 +50,9 @@ class SampleDriverDataModels:
|
|
50
50
|
self.pool_ca_container_ref = uuidutils.generate_uuid()
|
51
51
|
self.pool_crl_container_ref = uuidutils.generate_uuid()
|
52
52
|
|
53
|
+
self.vip_sg_ids = [uuidutils.generate_uuid(),
|
54
|
+
uuidutils.generate_uuid()]
|
55
|
+
|
53
56
|
self.pool1_id = uuidutils.generate_uuid()
|
54
57
|
self.pool2_id = uuidutils.generate_uuid()
|
55
58
|
|
@@ -145,7 +148,8 @@ class SampleDriverDataModels:
|
|
145
148
|
constants.CREATED_AT: self.created_at,
|
146
149
|
constants.UPDATED_AT: self.updated_at,
|
147
150
|
lib_consts.MONITOR_ADDRESS: '192.0.2.26',
|
148
|
-
lib_consts.MONITOR_PORT: 81
|
151
|
+
lib_consts.MONITOR_PORT: 81,
|
152
|
+
lib_consts.VNIC_TYPE: lib_consts.VNIC_TYPE_NORMAL}
|
149
153
|
|
150
154
|
self.test_member1_dict.update(self._common_test_dict)
|
151
155
|
|
@@ -154,6 +158,8 @@ class SampleDriverDataModels:
|
|
154
158
|
self.test_member2_dict[constants.IP_ADDRESS] = '192.0.2.17'
|
155
159
|
self.test_member2_dict[lib_consts.MONITOR_ADDRESS] = '192.0.2.27'
|
156
160
|
self.test_member2_dict[lib_consts.NAME] = 'member2'
|
161
|
+
self.test_member2_dict[
|
162
|
+
lib_consts.VNIC_TYPE] = lib_consts.VNIC_TYPE_DIRECT
|
157
163
|
|
158
164
|
self.test_member3_dict = copy.deepcopy(self.test_member1_dict)
|
159
165
|
self.test_member3_dict[lib_consts.ID] = self.member3_id
|
@@ -182,24 +188,28 @@ class SampleDriverDataModels:
|
|
182
188
|
self.db_pool1_members = [self.db_member1, self.db_member2]
|
183
189
|
self.db_pool2_members = [self.db_member3, self.db_member4]
|
184
190
|
|
185
|
-
self.provider_member1_dict = {
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
191
|
+
self.provider_member1_dict = {
|
192
|
+
lib_consts.ADDRESS: '192.0.2.16',
|
193
|
+
lib_consts.ADMIN_STATE_UP: True,
|
194
|
+
lib_consts.MEMBER_ID: self.member1_id,
|
195
|
+
lib_consts.MONITOR_ADDRESS: '192.0.2.26',
|
196
|
+
lib_consts.MONITOR_PORT: 81,
|
197
|
+
lib_consts.NAME: 'member1',
|
198
|
+
lib_consts.POOL_ID: self.pool1_id,
|
199
|
+
lib_consts.PROJECT_ID: self.project_id,
|
200
|
+
lib_consts.PROTOCOL_PORT: 80,
|
201
|
+
lib_consts.SUBNET_ID: self.subnet_id,
|
202
|
+
lib_consts.WEIGHT: 0,
|
203
|
+
lib_consts.BACKUP: False,
|
204
|
+
lib_consts.VNIC_TYPE: lib_consts.VNIC_TYPE_NORMAL}
|
197
205
|
|
198
206
|
self.provider_member2_dict = copy.deepcopy(self.provider_member1_dict)
|
199
207
|
self.provider_member2_dict[lib_consts.MEMBER_ID] = self.member2_id
|
200
208
|
self.provider_member2_dict[lib_consts.ADDRESS] = '192.0.2.17'
|
201
209
|
self.provider_member2_dict[lib_consts.MONITOR_ADDRESS] = '192.0.2.27'
|
202
210
|
self.provider_member2_dict[lib_consts.NAME] = 'member2'
|
211
|
+
self.provider_member2_dict[
|
212
|
+
lib_consts.VNIC_TYPE] = lib_consts.VNIC_TYPE_DIRECT
|
203
213
|
|
204
214
|
self.provider_member3_dict = copy.deepcopy(self.provider_member1_dict)
|
205
215
|
self.provider_member3_dict[lib_consts.MEMBER_ID] = self.member3_id
|
@@ -600,6 +610,7 @@ class SampleDriverDataModels:
|
|
600
610
|
constants.PORT_ID: self.port_id,
|
601
611
|
lib_consts.SUBNET_ID: self.subnet_id,
|
602
612
|
constants.QOS_POLICY_ID: self.qos_policy_id,
|
613
|
+
constants.SG_IDS: self.vip_sg_ids,
|
603
614
|
constants.OCTAVIA_OWNED: None}
|
604
615
|
|
605
616
|
self.provider_vip_dict = {
|
@@ -608,6 +619,7 @@ class SampleDriverDataModels:
|
|
608
619
|
lib_consts.VIP_PORT_ID: self.port_id,
|
609
620
|
lib_consts.VIP_SUBNET_ID: self.subnet_id,
|
610
621
|
lib_consts.VIP_QOS_POLICY_ID: self.qos_policy_id,
|
622
|
+
lib_consts.VIP_SG_IDS: self.vip_sg_ids,
|
611
623
|
constants.OCTAVIA_OWNED: None}
|
612
624
|
|
613
625
|
self.test_additional_vip_dict = {
|
@@ -627,7 +639,8 @@ class SampleDriverDataModels:
|
|
627
639
|
network_id=self.network_id,
|
628
640
|
port_id=self.port_id,
|
629
641
|
subnet_id=self.subnet_id,
|
630
|
-
qos_policy_id=self.qos_policy_id
|
642
|
+
qos_policy_id=self.qos_policy_id,
|
643
|
+
sg_ids=self.vip_sg_ids)
|
631
644
|
|
632
645
|
self.db_additional_vip = data_models.AdditionalVip(
|
633
646
|
ip_address=self.ip_address2,
|
@@ -12,6 +12,7 @@
|
|
12
12
|
# License for the specific language governing permissions and limitations
|
13
13
|
# under the License.
|
14
14
|
|
15
|
+
import hashlib
|
15
16
|
import os
|
16
17
|
import random
|
17
18
|
import socket
|
@@ -22,7 +23,6 @@ from unittest import mock
|
|
22
23
|
import fixtures
|
23
24
|
from oslo_config import fixture as oslo_fixture
|
24
25
|
from oslo_serialization import jsonutils
|
25
|
-
from oslo_utils.secretutils import md5
|
26
26
|
from oslo_utils import uuidutils
|
27
27
|
import webob
|
28
28
|
|
@@ -740,9 +740,10 @@ class TestServerTestCase(base.TestCase):
|
|
740
740
|
rv = self.centos_app.get('/' + api_server.VERSION +
|
741
741
|
'/loadbalancer/123/certificates/test.pem')
|
742
742
|
self.assertEqual(200, rv.status_code)
|
743
|
-
self.assertEqual(
|
744
|
-
|
745
|
-
|
743
|
+
self.assertEqual(
|
744
|
+
dict(md5sum=hashlib.md5(octavia_utils.b(CONTENT),
|
745
|
+
usedforsecurity=False).hexdigest()),
|
746
|
+
jsonutils.loads(rv.data.decode('utf-8')))
|
746
747
|
|
747
748
|
def test_ubuntu_upload_certificate_md5(self):
|
748
749
|
self._test_upload_certificate_md5(consts.UBUNTU)
|
@@ -503,7 +503,8 @@ class DriverAgentTest(base.OctaviaDBTestBase):
|
|
503
503
|
lib_consts.MONITOR_PORT,
|
504
504
|
lib_consts.SUBNET_ID,
|
505
505
|
lib_consts.WEIGHT,
|
506
|
-
lib_consts.BACKUP
|
506
|
+
lib_consts.BACKUP,
|
507
|
+
lib_consts.VNIC_TYPE):
|
507
508
|
self.assertEqual(provider_member_dict.get(key),
|
508
509
|
result_member_dict.get(key))
|
509
510
|
|
@@ -406,7 +406,7 @@ class TestHealthMonitor(base.BaseAPITest):
|
|
406
406
|
'is_admin_project': True,
|
407
407
|
'service_project_domain_id': None,
|
408
408
|
'service_project_id': None,
|
409
|
-
'roles': ['
|
409
|
+
'roles': ['admin'],
|
410
410
|
'user_id': None,
|
411
411
|
'is_admin': False,
|
412
412
|
'service_user_domain_id': None,
|
@@ -320,7 +320,7 @@ class TestL7Policy(base.BaseAPITest):
|
|
320
320
|
'is_admin_project': True,
|
321
321
|
'service_project_domain_id': None,
|
322
322
|
'service_project_id': None,
|
323
|
-
'roles': ['
|
323
|
+
'roles': ['admin'],
|
324
324
|
'user_id': None,
|
325
325
|
'is_admin': False,
|
326
326
|
'service_user_domain_id': None,
|
@@ -202,7 +202,7 @@ class TestListener(base.BaseAPITest):
|
|
202
202
|
'is_admin_project': True,
|
203
203
|
'service_project_domain_id': None,
|
204
204
|
'service_project_id': None,
|
205
|
-
'roles': ['
|
205
|
+
'roles': ['admin'],
|
206
206
|
'user_id': None,
|
207
207
|
'is_admin': False,
|
208
208
|
'service_user_domain_id': None,
|
@@ -1384,7 +1384,7 @@ class TestLoadBalancer(base.BaseAPITest):
|
|
1384
1384
|
'is_admin_project': True,
|
1385
1385
|
'service_project_domain_id': None,
|
1386
1386
|
'service_project_id': None,
|
1387
|
-
'roles': ['
|
1387
|
+
'roles': ['admin'],
|
1388
1388
|
'user_id': None,
|
1389
1389
|
'is_admin': False,
|
1390
1390
|
'service_user_domain_id': None,
|
@@ -2054,6 +2054,37 @@ class TestLoadBalancer(base.BaseAPITest):
|
|
2054
2054
|
self.put(self.LB_PATH.format(lb_id=lb_dict.get('id')),
|
2055
2055
|
lb_json, status=400)
|
2056
2056
|
|
2057
|
+
def test_update_with_sg_ids(self):
|
2058
|
+
project_id = uuidutils.generate_uuid()
|
2059
|
+
sg1_id = uuidutils.generate_uuid()
|
2060
|
+
sg2_id = uuidutils.generate_uuid()
|
2061
|
+
lb = self.create_load_balancer(uuidutils.generate_uuid(),
|
2062
|
+
name='lb1',
|
2063
|
+
project_id=project_id,
|
2064
|
+
vip_sg_ids=[sg1_id, sg2_id])
|
2065
|
+
lb_dict = lb.get(self.root_tag)
|
2066
|
+
lb_id = lb_dict.get('id')
|
2067
|
+
self.assertEqual(sorted([sg1_id, sg2_id]),
|
2068
|
+
sorted(lb_dict['vip_sg_ids']))
|
2069
|
+
self.set_lb_status(lb_dict.get('id'))
|
2070
|
+
|
2071
|
+
lb_json = self._build_body({'vip_sg_ids': [sg2_id]})
|
2072
|
+
self.put(self.LB_PATH.format(lb_id=lb_id),
|
2073
|
+
lb_json, status=200)
|
2074
|
+
self.set_lb_status(lb_dict.get('id'))
|
2075
|
+
response = self.get(self.LB_PATH.format(lb_id=lb_id))
|
2076
|
+
lb_dict = response.json.get(self.root_tag)
|
2077
|
+
self.assertEqual(sorted([sg2_id]),
|
2078
|
+
sorted(lb_dict['vip_sg_ids']))
|
2079
|
+
|
2080
|
+
lb_json = self._build_body({'vip_sg_ids': []})
|
2081
|
+
lb = self.put(self.LB_PATH.format(lb_id=lb_dict.get('id')),
|
2082
|
+
lb_json, status=200)
|
2083
|
+
self.set_lb_status(lb_dict.get('id'))
|
2084
|
+
response = self.get(self.LB_PATH.format(lb_id=lb_id))
|
2085
|
+
lb_dict = response.json.get(self.root_tag)
|
2086
|
+
self.assertEqual(0, len(lb_dict['vip_sg_ids']))
|
2087
|
+
|
2057
2088
|
def test_update_bad_lb_id(self):
|
2058
2089
|
path = self.LB_PATH.format(lb_id='SEAN-CONNERY')
|
2059
2090
|
self.put(path, body={}, status=404)
|
@@ -2503,7 +2534,7 @@ class TestLoadBalancer(base.BaseAPITest):
|
|
2503
2534
|
'is_admin_project': True,
|
2504
2535
|
'service_project_domain_id': None,
|
2505
2536
|
'service_project_id': None,
|
2506
|
-
'roles': ['
|
2537
|
+
'roles': ['admin'],
|
2507
2538
|
'user_id': None,
|
2508
2539
|
'is_admin': False,
|
2509
2540
|
'service_user_domain_id': None,
|
@@ -2735,8 +2766,13 @@ class TestLoadBalancerGraph(base.BaseAPITest):
|
|
2735
2766
|
expected_additional_vips = expected_graph.pop('additional_vips', [])
|
2736
2767
|
observed_additional_vips = observed_graph_copy.pop('additional_vips',
|
2737
2768
|
[])
|
2769
|
+
expected_vip_sg_ids = expected_graph.pop('vip_sg_ids', [])
|
2770
|
+
observed_vip_sg_ids = observed_graph_copy.pop('vip_sg_ids', [])
|
2738
2771
|
self.assertEqual(expected_graph, observed_graph_copy)
|
2739
2772
|
|
2773
|
+
self.assertEqual(sorted(expected_vip_sg_ids),
|
2774
|
+
sorted(observed_vip_sg_ids))
|
2775
|
+
|
2740
2776
|
self.assertEqual(len(expected_pools), len(observed_pools))
|
2741
2777
|
|
2742
2778
|
self.assertEqual(len(expected_listeners), len(observed_listeners))
|
@@ -2800,7 +2836,8 @@ class TestLoadBalancerGraph(base.BaseAPITest):
|
|
2800
2836
|
self.assertIn(observed_add_vip, expected_additional_vips)
|
2801
2837
|
|
2802
2838
|
def _get_lb_bodies(self, create_listeners, expected_listeners,
|
2803
|
-
create_pools=None, additional_vips=None
|
2839
|
+
create_pools=None, additional_vips=None,
|
2840
|
+
vip_sg_ids=None, flavor_id=None, sriov=False):
|
2804
2841
|
create_lb = {
|
2805
2842
|
'name': 'lb1',
|
2806
2843
|
'project_id': self._project_id,
|
@@ -2811,6 +2848,8 @@ class TestLoadBalancerGraph(base.BaseAPITest):
|
|
2811
2848
|
'listeners': create_listeners,
|
2812
2849
|
'pools': create_pools or []
|
2813
2850
|
}
|
2851
|
+
if vip_sg_ids:
|
2852
|
+
create_lb['vip_sg_ids'] = vip_sg_ids
|
2814
2853
|
if additional_vips:
|
2815
2854
|
create_lb.update({'additional_vips': additional_vips})
|
2816
2855
|
expected_lb = {
|
@@ -2830,7 +2869,13 @@ class TestLoadBalancerGraph(base.BaseAPITest):
|
|
2830
2869
|
'provider': 'noop_driver',
|
2831
2870
|
'tags': [],
|
2832
2871
|
'vip_vnic_type': constants.VNIC_TYPE_NORMAL,
|
2872
|
+
'vip_sg_ids': vip_sg_ids or [],
|
2833
2873
|
}
|
2874
|
+
if flavor_id:
|
2875
|
+
create_lb['flavor_id'] = flavor_id
|
2876
|
+
expected_lb['flavor_id'] = flavor_id
|
2877
|
+
if sriov:
|
2878
|
+
expected_lb['vip_vnic_type'] = constants.VNIC_TYPE_DIRECT
|
2834
2879
|
expected_lb.update(create_lb)
|
2835
2880
|
expected_lb['listeners'] = expected_listeners
|
2836
2881
|
expected_lb['pools'] = create_pools or []
|
@@ -3003,7 +3048,7 @@ class TestLoadBalancerGraph(base.BaseAPITest):
|
|
3003
3048
|
expected_pool['healthmonitor'] = expected_hm
|
3004
3049
|
return create_pool, expected_pool
|
3005
3050
|
|
3006
|
-
def _get_member_bodies(self, protocol_port=80):
|
3051
|
+
def _get_member_bodies(self, protocol_port=80, sriov=False):
|
3007
3052
|
create_member = {
|
3008
3053
|
'address': '10.0.0.1',
|
3009
3054
|
'protocol_port': protocol_port
|
@@ -3016,6 +3061,9 @@ class TestLoadBalancerGraph(base.BaseAPITest):
|
|
3016
3061
|
'project_id': self._project_id,
|
3017
3062
|
'tags': []
|
3018
3063
|
}
|
3064
|
+
if sriov:
|
3065
|
+
create_member[constants.REQUEST_SRIOV] = True
|
3066
|
+
expected_member[constants.VNIC_TYPE] = constants.VNIC_TYPE_DIRECT
|
3019
3067
|
expected_member.update(create_member)
|
3020
3068
|
return create_member, expected_member
|
3021
3069
|
|
@@ -3211,6 +3259,16 @@ class TestLoadBalancerGraph(base.BaseAPITest):
|
|
3211
3259
|
api_lb = response.json.get(self.root_tag)
|
3212
3260
|
self._assert_graphs_equal(expected_lb, api_lb)
|
3213
3261
|
|
3262
|
+
def test_with_sg_ids(self):
|
3263
|
+
create_lb, expected_lb = self._get_lb_bodies(
|
3264
|
+
[], [], vip_sg_ids=[uuidutils.generate_uuid(),
|
3265
|
+
uuidutils.generate_uuid()])
|
3266
|
+
|
3267
|
+
body = self._build_body(create_lb)
|
3268
|
+
response = self.post(self.LBS_PATH, body)
|
3269
|
+
api_lb = response.json.get(self.root_tag)
|
3270
|
+
self._assert_graphs_equal(expected_lb, api_lb)
|
3271
|
+
|
3214
3272
|
def test_with_one_listener(self):
|
3215
3273
|
create_listener, expected_listener = self._get_listener_bodies()
|
3216
3274
|
create_lb, expected_lb = self._get_lb_bodies([create_listener],
|
@@ -3220,6 +3278,53 @@ class TestLoadBalancerGraph(base.BaseAPITest):
|
|
3220
3278
|
api_lb = response.json.get(self.root_tag)
|
3221
3279
|
self._assert_graphs_equal(expected_lb, api_lb)
|
3222
3280
|
|
3281
|
+
def test_with_one_listener_sg_ids(self):
|
3282
|
+
create_listener, expected_listener = self._get_listener_bodies()
|
3283
|
+
create_lb, expected_lb = self._get_lb_bodies(
|
3284
|
+
[create_listener], [expected_listener],
|
3285
|
+
vip_sg_ids=[uuidutils.generate_uuid(),
|
3286
|
+
uuidutils.generate_uuid()])
|
3287
|
+
|
3288
|
+
body = self._build_body(create_lb)
|
3289
|
+
response = self.post(self.LBS_PATH, body)
|
3290
|
+
api_lb = response.json.get(self.root_tag)
|
3291
|
+
self._assert_graphs_equal(expected_lb, api_lb)
|
3292
|
+
|
3293
|
+
@mock.patch('octavia.api.v2.controllers.load_balancer.'
|
3294
|
+
'LoadBalancersController._apply_flavor_to_lb_dict',
|
3295
|
+
return_value={constants.SRIOV_VIP: True})
|
3296
|
+
def test_with_vip_vnic_type_direct_and_sg_ids(self, mock_flavor_dict):
|
3297
|
+
create_lb, expected_lb = self._get_lb_bodies(
|
3298
|
+
[], [],
|
3299
|
+
vip_sg_ids=[uuidutils.generate_uuid(),
|
3300
|
+
uuidutils.generate_uuid()])
|
3301
|
+
expected_lb[constants.VIP_VNIC_TYPE] = constants.VNIC_TYPE_DIRECT
|
3302
|
+
|
3303
|
+
body = self._build_body(create_lb)
|
3304
|
+
|
3305
|
+
response = self.post(self.LBS_PATH, body, status=400,
|
3306
|
+
expect_errors=True)
|
3307
|
+
error_text = response.json.get('faultstring')
|
3308
|
+
self.assertIn("VIP Security Groups are not allowed with VNIC "
|
3309
|
+
"direct type", error_text)
|
3310
|
+
|
3311
|
+
def test_with_one_listener_sg_ids_and_allowed_cidrs(self):
|
3312
|
+
allowed_cidrs = ['10.0.1.0/24']
|
3313
|
+
create_listener, expected_listener = self._get_listener_bodies(
|
3314
|
+
create_allowed_cidrs=allowed_cidrs,
|
3315
|
+
expected_allowed_cidrs=allowed_cidrs)
|
3316
|
+
create_lb, expected_lb = self._get_lb_bodies(
|
3317
|
+
[create_listener], [expected_listener],
|
3318
|
+
vip_sg_ids=[uuidutils.generate_uuid(),
|
3319
|
+
uuidutils.generate_uuid()])
|
3320
|
+
|
3321
|
+
body = self._build_body(create_lb)
|
3322
|
+
response = self.post(self.LBS_PATH, body, status=400,
|
3323
|
+
expect_errors=True)
|
3324
|
+
error_text = response.json.get('faultstring')
|
3325
|
+
self.assertIn("Allowed CIDRs are not allowed when using custom "
|
3326
|
+
"VIP Security Groups", error_text)
|
3327
|
+
|
3223
3328
|
def test_with_one_listener_with_default_timeouts(self):
|
3224
3329
|
self.conf = self.useFixture(oslo_fixture.Config(cfg.CONF))
|
3225
3330
|
self.conf.config(group='haproxy_amphora', timeout_client_data=20)
|
@@ -3299,6 +3404,47 @@ class TestLoadBalancerGraph(base.BaseAPITest):
|
|
3299
3404
|
api_lb = response.json.get(self.root_tag)
|
3300
3405
|
self._assert_graphs_equal(expected_lb, api_lb)
|
3301
3406
|
|
3407
|
+
def test_with_one_listener_one_member_sriov(self):
|
3408
|
+
flavor_profile = self.create_flavor_profile(
|
3409
|
+
'sriov-graph-create', 'noop_driver',
|
3410
|
+
f'{{"{constants.ALLOW_MEMBER_SRIOV}": true, '
|
3411
|
+
f'"{constants.SRIOV_VIP}": true}}')
|
3412
|
+
|
3413
|
+
flavor = self.create_flavor('sriov-graph-create', '',
|
3414
|
+
flavor_profile['id'], True)
|
3415
|
+
|
3416
|
+
create_member, expected_member = self._get_member_bodies(sriov=True)
|
3417
|
+
create_pool, expected_pool = self._get_pool_bodies(
|
3418
|
+
create_members=[create_member],
|
3419
|
+
expected_members=[expected_member])
|
3420
|
+
create_listener, expected_listener = self._get_listener_bodies(
|
3421
|
+
create_default_pool_name=create_pool['name'])
|
3422
|
+
create_lb, expected_lb = self._get_lb_bodies(
|
3423
|
+
create_listeners=[create_listener],
|
3424
|
+
expected_listeners=[expected_listener],
|
3425
|
+
create_pools=[create_pool], flavor_id=flavor['id'], sriov=True)
|
3426
|
+
body = self._build_body(create_lb)
|
3427
|
+
response = self.post(self.LBS_PATH, body)
|
3428
|
+
api_lb = response.json.get(self.root_tag)
|
3429
|
+
self._assert_graphs_equal(expected_lb, api_lb)
|
3430
|
+
|
3431
|
+
def test_with_one_listener_one_member_sriov_disabled(self):
|
3432
|
+
create_member, expected_member = self._get_member_bodies(sriov=True)
|
3433
|
+
create_pool, expected_pool = self._get_pool_bodies(
|
3434
|
+
create_members=[create_member],
|
3435
|
+
expected_members=[expected_member])
|
3436
|
+
create_listener, expected_listener = self._get_listener_bodies(
|
3437
|
+
create_default_pool_name=create_pool['name'])
|
3438
|
+
create_lb, expected_lb = self._get_lb_bodies(
|
3439
|
+
create_listeners=[create_listener],
|
3440
|
+
expected_listeners=[expected_listener],
|
3441
|
+
create_pools=[create_pool])
|
3442
|
+
body = self._build_body(create_lb)
|
3443
|
+
response = self.post(self.LBS_PATH, body, status=400)
|
3444
|
+
error_text = response.json.get('faultstring')
|
3445
|
+
self.assertIn('flavor does not allow SR-IOV member ports.',
|
3446
|
+
error_text)
|
3447
|
+
|
3302
3448
|
def test_with_one_listener_one_hm(self):
|
3303
3449
|
create_hm, expected_hm = self._get_hm_bodies()
|
3304
3450
|
create_pool, expected_pool = self._get_pool_bodies(
|
@@ -18,6 +18,7 @@ from octavia_lib.api.drivers import data_models as driver_dm
|
|
18
18
|
from oslo_config import cfg
|
19
19
|
from oslo_config import fixture as oslo_fixture
|
20
20
|
from oslo_utils import uuidutils
|
21
|
+
from sqlalchemy.orm import exc as sa_exception
|
21
22
|
|
22
23
|
from octavia.api.drivers import utils as driver_utils
|
23
24
|
from octavia.common import constants
|
@@ -623,6 +624,55 @@ class TestMember(base.BaseAPITest):
|
|
623
624
|
self.assertIn('Provider \'bad_driver\' reports error: broken',
|
624
625
|
response.get('faultstring'))
|
625
626
|
|
627
|
+
def test_create_with_sriov(self):
|
628
|
+
flavor_profile = self.create_flavor_profile(
|
629
|
+
'sriov-member-create', 'noop_driver',
|
630
|
+
f'{{"{constants.ALLOW_MEMBER_SRIOV}": true}}')
|
631
|
+
|
632
|
+
flavor = self.create_flavor('sriov-member-create', '',
|
633
|
+
flavor_profile['id'], True)
|
634
|
+
|
635
|
+
vip_subnet_id = uuidutils.generate_uuid()
|
636
|
+
lb = self.create_load_balancer(vip_subnet_id, flavor_id=flavor['id'])
|
637
|
+
lb_id = lb.get('loadbalancer').get('id')
|
638
|
+
self.set_lb_status(lb_id)
|
639
|
+
|
640
|
+
listener = self.create_listener(
|
641
|
+
constants.PROTOCOL_HTTP, 80,
|
642
|
+
lb_id=lb_id)
|
643
|
+
listener_id = listener.get('listener').get('id')
|
644
|
+
self.set_lb_status(lb_id)
|
645
|
+
|
646
|
+
pool_with_listener = self.create_pool(
|
647
|
+
lb_id, constants.PROTOCOL_HTTP,
|
648
|
+
constants.LB_ALGORITHM_ROUND_ROBIN, listener_id=listener_id)
|
649
|
+
pool_with_listener_id = pool_with_listener.get('pool').get('id')
|
650
|
+
self.set_lb_status(lb_id)
|
651
|
+
|
652
|
+
api_member = self.create_member(
|
653
|
+
pool_with_listener_id, '192.0.2.1',
|
654
|
+
80, request_sriov=True).get(self.root_tag)
|
655
|
+
self.assertEqual(constants.VNIC_TYPE_DIRECT,
|
656
|
+
api_member[constants.VNIC_TYPE])
|
657
|
+
|
658
|
+
def test_create_with_sriov_disabled(self):
|
659
|
+
# Test with no flavor enabling SR-IOV members
|
660
|
+
response = self.create_member(
|
661
|
+
self.pool_id, '192.0.2.1',
|
662
|
+
80, request_sriov=True, status=400)
|
663
|
+
self.assertIn('flavor does not allow SR-IOV member ports',
|
664
|
+
response.get('faultstring'))
|
665
|
+
|
666
|
+
@mock.patch('octavia.db.repositories.FlavorRepository.'
|
667
|
+
'get_flavor_metadata_dict')
|
668
|
+
def test_create_with_sriov_missing_flavor(self, mock_get_flavor):
|
669
|
+
mock_get_flavor.side_effect = sa_exception.NoResultFound()
|
670
|
+
response = self.create_member(
|
671
|
+
self.pool_id, '192.0.2.1',
|
672
|
+
80, request_sriov=True, status=400)
|
673
|
+
self.assertIn('flavor does not allow SR-IOV member ports',
|
674
|
+
response.get('faultstring'))
|
675
|
+
|
626
676
|
@mock.patch('octavia.api.drivers.driver_factory.get_driver')
|
627
677
|
@mock.patch('octavia.api.drivers.utils.call_provider')
|
628
678
|
def test_full_batch_members(self, mock_provider, mock_get_driver):
|
@@ -340,7 +340,7 @@ class TestPool(base.BaseAPITest):
|
|
340
340
|
'is_admin_project': True,
|
341
341
|
'service_project_domain_id': None,
|
342
342
|
'service_project_id': None,
|
343
|
-
'roles': ['
|
343
|
+
'roles': ['admin'],
|
344
344
|
'user_id': None,
|
345
345
|
'is_admin': False,
|
346
346
|
'service_user_domain_id': None,
|
@@ -298,7 +298,7 @@ class TestQuotas(base.BaseAPITest):
|
|
298
298
|
'is_admin_project': True,
|
299
299
|
'service_project_domain_id': None,
|
300
300
|
'service_project_id': None,
|
301
|
-
'roles': ['
|
301
|
+
'roles': ['admin'],
|
302
302
|
'user_id': None,
|
303
303
|
'is_admin': False,
|
304
304
|
'service_user_domain_id': None,
|
@@ -345,7 +345,7 @@ class TestQuotas(base.BaseAPITest):
|
|
345
345
|
'is_admin_project': True,
|
346
346
|
'service_project_domain_id': None,
|
347
347
|
'service_project_id': None,
|
348
|
-
'roles': ['
|
348
|
+
'roles': ['admin'],
|
349
349
|
'user_id': None,
|
350
350
|
'is_admin': False,
|
351
351
|
'service_user_domain_id': None,
|
@@ -485,11 +485,8 @@ class TestQuotas(base.BaseAPITest):
|
|
485
485
|
def test_get_Authorized_observer(self):
|
486
486
|
self._test_get_Authorized(['load-balancer_observer', 'reader'])
|
487
487
|
|
488
|
-
def test_get_Authorized_global_observer(self):
|
489
|
-
self._test_get_Authorized(['load-balancer_global_observer'])
|
490
|
-
|
491
488
|
def test_get_Authorized_quota_admin(self):
|
492
|
-
self._test_get_Authorized(['
|
489
|
+
self._test_get_Authorized(['admin'])
|
493
490
|
|
494
491
|
def _test_get_Authorized(self, roles):
|
495
492
|
project1_id = uuidutils.generate_uuid()
|
@@ -759,7 +756,7 @@ class TestQuotas(base.BaseAPITest):
|
|
759
756
|
'is_admin_project': True,
|
760
757
|
'service_project_domain_id': None,
|
761
758
|
'service_project_id': None,
|
762
|
-
'roles': ['
|
759
|
+
'roles': ['admin'],
|
763
760
|
'user_id': None,
|
764
761
|
'is_admin': False,
|
765
762
|
'service_user_domain_id': None,
|
@@ -871,7 +868,7 @@ class TestQuotas(base.BaseAPITest):
|
|
871
868
|
'is_admin_project': True,
|
872
869
|
'service_project_domain_id': None,
|
873
870
|
'service_project_id': None,
|
874
|
-
'roles': ['
|
871
|
+
'roles': ['admin'],
|
875
872
|
'user_id': None,
|
876
873
|
'is_admin': False,
|
877
874
|
'service_user_domain_id': None,
|
@@ -14,9 +14,8 @@
|
|
14
14
|
|
15
15
|
import os
|
16
16
|
|
17
|
-
from oslo_config import cfg
|
18
17
|
from oslo_config import fixture as oslo_fixture
|
19
|
-
from oslo_db.sqlalchemy import
|
18
|
+
from oslo_db.sqlalchemy import enginefacade
|
20
19
|
from oslotest import base as test_base
|
21
20
|
|
22
21
|
from octavia.common import config
|
@@ -71,10 +70,11 @@ class OctaviaDBTestBase(test_base.BaseTestCase):
|
|
71
70
|
# don't use the _FACADE singleton. Some tests will use in-memory
|
72
71
|
# sqlite, some will use a file backed sqlite.
|
73
72
|
if 'sqlite:///' in self.connection_string:
|
74
|
-
facade =
|
75
|
-
|
76
|
-
engine = facade.get_engine()
|
77
|
-
|
73
|
+
facade = enginefacade.transaction_context()
|
74
|
+
facade.configure(sqlite_fk=True, expire_on_commit=True)
|
75
|
+
engine = facade.writer.get_engine()
|
76
|
+
sessionmaker = facade.writer.get_sessionmaker()
|
77
|
+
session = sessionmaker()
|
78
78
|
self.facade = facade
|
79
79
|
else:
|
80
80
|
engine = db_api.get_engine()
|