From 62192dba3ac97e90b9840e09f2e0c93c92ac5a62 Mon Sep 17 00:00:00 2001 From: sapd Date: Sun, 9 Sep 2018 22:30:58 +0700 Subject: [PATCH] Support REDIRECT_PREFIX action for L7Policy Currently, Octavia only support three actions for L7Policy, in this patch we will implement new action for L7Policy. Story: 2003700 Change-Id: Ie99591ede097b566294ebdb673c460442dd6d942 --- api-ref/source/parameters.yaml | 14 ++++++ .../v2/examples/l7policies-list-response.json | 1 + .../v2/examples/l7policy-create-response.json | 1 + .../v2/examples/l7policy-show-response.json | 1 + .../v2/examples/l7policy-update-response.json | 1 + api-ref/source/v2/l7policy.inc | 6 +++ doc/source/user/guides/l7-cookbook.rst | 2 +- octavia/api/drivers/data_models.py | 3 +- octavia/api/v1/types/l7policy.py | 3 ++ octavia/api/v2/types/l7policy.py | 4 ++ octavia/common/constants.py | 4 +- octavia/common/data_models.py | 3 +- octavia/common/jinja/haproxy/jinja_cfg.py | 1 + .../common/jinja/haproxy/templates/macros.j2 | 3 ++ octavia/common/validate.py | 22 +++++++-- ...ed6_add_l7policy_action_redirect_prefix.py | 49 +++++++++++++++++++ octavia/db/models.py | 3 ++ octavia/db/repositories.py | 7 +++ .../functional/api/v1/test_load_balancer.py | 1 + .../functional/api/v2/test_load_balancer.py | 1 + .../unit/api/drivers/sample_data_models.py | 24 +++++---- .../common/jinja/haproxy/test_jinja_cfg.py | 6 +++ .../common/sample_configs/sample_configs.py | 31 ++++++++++-- ...port-redirect-prefix-7f8b289aee04fe99.yaml | 3 ++ 24 files changed, 173 insertions(+), 21 deletions(-) create mode 100644 octavia/db/migration/alembic_migrations/versions/55874a4ceed6_add_l7policy_action_redirect_prefix.py create mode 100644 releasenotes/notes/support-redirect-prefix-7f8b289aee04fe99.yaml diff --git a/api-ref/source/parameters.yaml b/api-ref/source/parameters.yaml index cd594d209c..552d32615c 100644 --- a/api-ref/source/parameters.yaml +++ b/api-ref/source/parameters.yaml @@ -523,6 +523,20 @@ l7policy-redirect-pool_id-optional: in: body required: false type: uuid +l7policy-redirect-prefix: + description: | + Requests matching this policy will be redirected to this Prefix URL. + Only valid if ``action`` is ``REDIRECT_PREFIX``. + in: body + required: true + type: string +l7policy-redirect-prefix-optional: + description: | + Requests matching this policy will be redirected to this Prefix URL. + Only valid if ``action`` is ``REDIRECT_PREFIX``. + in: body + required: false + type: string l7policy-redirect-url: description: | Requests matching this policy will be redirected to this URL. diff --git a/api-ref/source/v2/examples/l7policies-list-response.json b/api-ref/source/v2/examples/l7policies-list-response.json index b7f628d902..23054a15dc 100644 --- a/api-ref/source/v2/examples/l7policies-list-response.json +++ b/api-ref/source/v2/examples/l7policies-list-response.json @@ -13,6 +13,7 @@ "provisioning_status": "ACTIVE", "updated_at": "2017-06-24T23:30:05", "redirect_pool_id": null, + "redirect_prefix": null, "redirect_url": "http://www.example.com", "action": "REDIRECT_TO_URL", "position": 1, diff --git a/api-ref/source/v2/examples/l7policy-create-response.json b/api-ref/source/v2/examples/l7policy-create-response.json index bf34fd263e..9e033615dd 100644 --- a/api-ref/source/v2/examples/l7policy-create-response.json +++ b/api-ref/source/v2/examples/l7policy-create-response.json @@ -13,6 +13,7 @@ "provisioning_status": "PENDING_CREATE", "updated_at": "2017-06-24T23:30:05", "redirect_pool_id": null, + "redirect_prefix": null, "redirect_url": "http://www.example.com", "action": "REDIRECT_TO_URL", "position": 1, diff --git a/api-ref/source/v2/examples/l7policy-show-response.json b/api-ref/source/v2/examples/l7policy-show-response.json index 54342b7c91..c3b482fdf2 100644 --- a/api-ref/source/v2/examples/l7policy-show-response.json +++ b/api-ref/source/v2/examples/l7policy-show-response.json @@ -13,6 +13,7 @@ "provisioning_status": "ACTIVE", "updated_at": "2017-06-24T23:30:05", "redirect_pool_id": null, + "redirect_prefix": null, "redirect_url": "http://www.example.com", "action": "REDIRECT_TO_URL", "position": 1, diff --git a/api-ref/source/v2/examples/l7policy-update-response.json b/api-ref/source/v2/examples/l7policy-update-response.json index 7f67b6c628..b6516efb10 100644 --- a/api-ref/source/v2/examples/l7policy-update-response.json +++ b/api-ref/source/v2/examples/l7policy-update-response.json @@ -13,6 +13,7 @@ "provisioning_status": "PENDING_UPDATE", "updated_at": "2017-06-24T23:30:05", "redirect_pool_id": null, + "redirect_prefix": null, "redirect_url": "http://www.example.com", "action": "REDIRECT_TO_URL", "position": 1, diff --git a/api-ref/source/v2/l7policy.inc b/api-ref/source/v2/l7policy.inc index 65a4345312..57ef705e50 100644 --- a/api-ref/source/v2/l7policy.inc +++ b/api-ref/source/v2/l7policy.inc @@ -57,6 +57,7 @@ Response Parameters - project_id: project_id - provisioning_status: provisioning_status - redirect_pool_id: l7policy-redirect-pool_id + - redirect_prefix: l7policy-redirect-prefix - redirect_url: l7policy-redirect-url - rules: l7policy-rule-ids - updated_at: updated_at @@ -139,6 +140,7 @@ Request - position: l7policy-position-optional - project_id: project_id-optional - redirect_pool_id: l7policy-redirect-pool_id-optional + - redirect_prefix: l7policy-redirect-prefix-optional - redirect_url: l7policy-redirect-url-optional Request Example @@ -170,6 +172,7 @@ Response Parameters - project_id: project_id - provisioning_status: provisioning_status - redirect_pool_id: l7policy-redirect-pool_id + - redirect_prefix: l7policy-redirect-prefix - redirect_url: l7policy-redirect-url - rules: l7policy-rule-ids - updated_at: updated_at @@ -235,6 +238,7 @@ Response Parameters - project_id: project_id - provisioning_status: provisioning_status - redirect_pool_id: l7policy-redirect-pool_id + - redirect_prefix: l7policy-redirect-prefix - redirect_url: l7policy-redirect-url - rules: l7policy-rule-ids - updated_at: updated_at @@ -290,6 +294,7 @@ Request - name: name-optional - position: l7policy-position-optional - redirect_pool_id: l7policy-redirect-pool_id-optional + - redirect_prefix: l7policy-redirect-prefix-optional - redirect_url: l7policy-redirect-url-optional Request Example @@ -321,6 +326,7 @@ Response Parameters - project_id: project_id - provisioning_status: provisioning_status - redirect_pool_id: l7policy-redirect-pool_id + - redirect_prefix: l7policy-redirect-prefix - redirect_url: l7policy-redirect-url - rules: l7policy-rule-ids - updated_at: updated_at diff --git a/doc/source/user/guides/l7-cookbook.rst b/doc/source/user/guides/l7-cookbook.rst index c572d5e1be..d5da60a1c4 100644 --- a/doc/source/user/guides/l7-cookbook.rst +++ b/doc/source/user/guides/l7-cookbook.rst @@ -60,7 +60,7 @@ Redirect *http://www.example.com/* to *https://www.example.com/* .. code-block:: bash openstack loadbalancer listener create --name http_listener --protocol HTTP --protocol-port 80 lb1 - openstack loadbalancer l7policy create --action REDIRECT_TO_URL --redirect-url https://www.example.com/ --name policy1 http_listener + openstack loadbalancer l7policy create --action REDIRECT_PREFIX --redirect-prefix https://www.example.com/ --name policy1 http_listener openstack loadbalancer l7rule create --compare-type STARTS_WITH --type PATH --value / policy1 diff --git a/octavia/api/drivers/data_models.py b/octavia/api/drivers/data_models.py index 5ac6b26c46..8829ce42cf 100644 --- a/octavia/api/drivers/data_models.py +++ b/octavia/api/drivers/data_models.py @@ -220,7 +220,7 @@ class L7Policy(BaseDataModel): def __init__(self, action=Unset, admin_state_up=Unset, description=Unset, l7policy_id=Unset, listener_id=Unset, name=Unset, position=Unset, redirect_pool_id=Unset, redirect_url=Unset, - rules=Unset): + rules=Unset, redirect_prefix=Unset): self.action = action self.admin_state_up = admin_state_up @@ -232,6 +232,7 @@ class L7Policy(BaseDataModel): self.redirect_pool_id = redirect_pool_id self.redirect_url = redirect_url self.rules = rules + self.redirect_prefix = redirect_prefix class L7Rule(BaseDataModel): diff --git a/octavia/api/v1/types/l7policy.py b/octavia/api/v1/types/l7policy.py index aff09d364e..62ed26d9e4 100644 --- a/octavia/api/v1/types/l7policy.py +++ b/octavia/api/v1/types/l7policy.py @@ -29,6 +29,7 @@ class L7PolicyResponse(base.BaseType): action = wtypes.wsattr(wtypes.StringType()) redirect_pool_id = wtypes.wsattr(wtypes.UuidType()) redirect_url = wtypes.wsattr(wtypes.StringType()) + redirect_prefix = wtypes.wsattr(wtypes.StringType()) position = wtypes.wsattr(wtypes.IntegerType()) l7rules = wtypes.wsattr([l7rule.L7RuleResponse]) redirect_pool = wtypes.wsattr(pool.PoolResponse) @@ -66,6 +67,7 @@ class L7PolicyPOST(base.BaseType): mandatory=True) redirect_pool_id = wtypes.wsattr(wtypes.UuidType()) redirect_url = wtypes.wsattr(base.URLType()) + redirect_prefix = wtypes.wsattr(base.URLType()) position = wtypes.wsattr(wtypes.IntegerType(), default=constants.MAX_POLICY_POSITION) redirect_pool = wtypes.wsattr(pool.PoolPOST) @@ -81,4 +83,5 @@ class L7PolicyPUT(base.BaseType): wtypes.Enum(str, *constants.SUPPORTED_L7POLICY_ACTIONS)) redirect_pool_id = wtypes.wsattr(wtypes.UuidType()) redirect_url = wtypes.wsattr(base.URLType()) + redirect_prefix = wtypes.wsattr(base.URLType()) position = wtypes.wsattr(wtypes.IntegerType()) diff --git a/octavia/api/v2/types/l7policy.py b/octavia/api/v2/types/l7policy.py index e91c6db4ed..3f068476b8 100644 --- a/octavia/api/v2/types/l7policy.py +++ b/octavia/api/v2/types/l7policy.py @@ -38,6 +38,7 @@ class L7PolicyResponse(BaseL7PolicyType): listener_id = wtypes.wsattr(wtypes.UuidType()) redirect_pool_id = wtypes.wsattr(wtypes.UuidType()) redirect_url = wtypes.wsattr(wtypes.StringType()) + redirect_prefix = wtypes.wsattr(wtypes.StringType()) position = wtypes.wsattr(wtypes.IntegerType()) rules = wtypes.wsattr([types.IdOnlyType]) created_at = wtypes.wsattr(wtypes.datetime.datetime) @@ -86,6 +87,7 @@ class L7PolicyPOST(BaseL7PolicyType): mandatory=True) redirect_pool_id = wtypes.wsattr(wtypes.UuidType()) redirect_url = wtypes.wsattr(types.URLType()) + redirect_prefix = wtypes.wsattr(types.URLType()) position = wtypes.wsattr(wtypes.IntegerType( minimum=constants.MIN_POLICY_POSITION, maximum=constants.MAX_POLICY_POSITION), @@ -107,6 +109,7 @@ class L7PolicyPUT(BaseL7PolicyType): wtypes.Enum(str, *constants.SUPPORTED_L7POLICY_ACTIONS)) redirect_pool_id = wtypes.wsattr(wtypes.UuidType()) redirect_url = wtypes.wsattr(types.URLType()) + redirect_prefix = wtypes.wsattr(types.URLType()) position = wtypes.wsattr(wtypes.IntegerType( minimum=constants.MIN_POLICY_POSITION, maximum=constants.MAX_POLICY_POSITION)) @@ -126,6 +129,7 @@ class L7PolicySingleCreate(BaseL7PolicyType): mandatory=True) redirect_pool = wtypes.wsattr(pool.PoolSingleCreate) redirect_url = wtypes.wsattr(types.URLType()) + redirect_prefix = wtypes.wsattr(types.URLType()) position = wtypes.wsattr(wtypes.IntegerType( minimum=constants.MIN_POLICY_POSITION, maximum=constants.MAX_POLICY_POSITION), diff --git a/octavia/common/constants.py b/octavia/common/constants.py index 627d01e401..4ef56a8a33 100644 --- a/octavia/common/constants.py +++ b/octavia/common/constants.py @@ -161,9 +161,11 @@ SUPPORTED_L7RULE_COMPARE_TYPES = (L7RULE_COMPARE_TYPE_REGEX, L7POLICY_ACTION_REJECT = 'REJECT' L7POLICY_ACTION_REDIRECT_TO_URL = 'REDIRECT_TO_URL' L7POLICY_ACTION_REDIRECT_TO_POOL = 'REDIRECT_TO_POOL' +L7POLICY_ACTION_REDIRECT_PREFIX = 'REDIRECT_PREFIX' SUPPORTED_L7POLICY_ACTIONS = (L7POLICY_ACTION_REJECT, L7POLICY_ACTION_REDIRECT_TO_URL, - L7POLICY_ACTION_REDIRECT_TO_POOL) + L7POLICY_ACTION_REDIRECT_TO_POOL, + L7POLICY_ACTION_REDIRECT_PREFIX) MIN_POLICY_POSITION = 1 # Largest a 32-bit integer can be, which is a limitation diff --git a/octavia/common/data_models.py b/octavia/common/data_models.py index 318ec73634..b864f3a79a 100644 --- a/octavia/common/data_models.py +++ b/octavia/common/data_models.py @@ -592,7 +592,7 @@ class L7Policy(BaseDataModel): position=None, listener=None, redirect_pool=None, enabled=None, l7rules=None, provisioning_status=None, operating_status=None, project_id=None, created_at=None, - updated_at=None): + updated_at=None, redirect_prefix=None): self.id = id self.name = name self.description = description @@ -610,6 +610,7 @@ class L7Policy(BaseDataModel): self.project_id = project_id self.created_at = created_at self.updated_at = updated_at + self.redirect_prefix = redirect_prefix def _conditionally_remove_pool_links(self, pool): """Removes links to the given pool from parent objects. diff --git a/octavia/common/jinja/haproxy/jinja_cfg.py b/octavia/common/jinja/haproxy/jinja_cfg.py index a988a4577b..7f2b01ef4a 100644 --- a/octavia/common/jinja/haproxy/jinja_cfg.py +++ b/octavia/common/jinja/haproxy/jinja_cfg.py @@ -308,6 +308,7 @@ class JinjaTemplater(object): 'id': l7policy.id, 'action': l7policy.action, 'redirect_url': l7policy.redirect_url, + 'redirect_prefix': l7policy.redirect_prefix, 'enabled': l7policy.enabled } if l7policy.redirect_pool: diff --git a/octavia/common/jinja/haproxy/templates/macros.j2 b/octavia/common/jinja/haproxy/templates/macros.j2 index f74954609a..7af8cb32a8 100644 --- a/octavia/common/jinja/haproxy/templates/macros.j2 +++ b/octavia/common/jinja/haproxy/templates/macros.j2 @@ -106,6 +106,9 @@ bind {{ lb_vip_address }}:{{ listener.protocol_port }} {{ {% elif l7policy.action == constants.L7POLICY_ACTION_REDIRECT_TO_POOL and l7policy.redirect_pool.enabled %} use_backend {{ l7policy.redirect_pool.id }} if{{ l7rule_list_macro( l7policy) }} + {% elif l7policy.action == constants.L7POLICY_ACTION_REDIRECT_PREFIX %} + redirect prefix {{ l7policy.redirect_prefix }} if{{ l7rule_list_macro( + l7policy) }} {% endif %} {% endmacro %} diff --git a/octavia/common/validate.py b/octavia/common/validate.py index 7db6d3a0e3..f6d245cc07 100644 --- a/octavia/common/validate.py +++ b/octavia/common/validate.py @@ -194,29 +194,43 @@ def sanitize_l7policy_api_args(l7policy, create=False): raise exceptions.InvalidL7PolicyArgs( msg='redirect_pool_id or redirect_pool must not be None') l7policy.update({'redirect_url': None}) + elif l7policy['action'] == constants.L7POLICY_ACTION_REDIRECT_PREFIX: + if not l7policy.get('redirect_prefix'): + raise exceptions.InvalidL7PolicyArgs( + msg='redirect_prefix must not be None') else: raise exceptions.InvalidL7PolicyAction( action=l7policy['action']) - if ((l7policy.get('redirect_pool_id') or - l7policy.get('redirect_pool')) and l7policy.get('redirect_url')): + if ((l7policy.get('redirect_pool_id') or l7policy.get('redirect_pool')) and + (l7policy.get('redirect_url') or l7policy.get('redirect_prefix'))): raise exceptions.InvalidL7PolicyArgs( - msg='Cannot specify redirect_pool_id and redirect_url ' - 'at the same time') + msg='Cannot specify redirect_pool_id and redirect_url or ' + 'redirect_prefix at the same time') if l7policy.get('redirect_pool_id'): l7policy.update({ 'action': constants.L7POLICY_ACTION_REDIRECT_TO_POOL}) l7policy.update({'redirect_url': None}) l7policy.pop('redirect_pool', None) + l7policy.update({'redirect_prefix': None}) if l7policy.get('redirect_pool'): l7policy.update({ 'action': constants.L7POLICY_ACTION_REDIRECT_TO_POOL}) l7policy.update({'redirect_url': None}) l7policy.pop('redirect_pool_id', None) + l7policy.update({'redirect_prefix': None}) if l7policy.get('redirect_url'): url(l7policy['redirect_url']) l7policy.update({ 'action': constants.L7POLICY_ACTION_REDIRECT_TO_URL}) l7policy.update({'redirect_pool_id': None}) + l7policy.update({'redirect_prefix': None}) + l7policy.pop('redirect_pool', None) + if l7policy.get('redirect_prefix'): + url(l7policy['redirect_prefix']) + l7policy.update({ + 'action': constants.L7POLICY_ACTION_REDIRECT_PREFIX}) + l7policy.update({'redirect_pool_id': None}) + l7policy.update({'redirect_url': None}) l7policy.pop('redirect_pool', None) # If we are creating, we need an action at this point diff --git a/octavia/db/migration/alembic_migrations/versions/55874a4ceed6_add_l7policy_action_redirect_prefix.py b/octavia/db/migration/alembic_migrations/versions/55874a4ceed6_add_l7policy_action_redirect_prefix.py new file mode 100644 index 0000000000..81e4acff15 --- /dev/null +++ b/octavia/db/migration/alembic_migrations/versions/55874a4ceed6_add_l7policy_action_redirect_prefix.py @@ -0,0 +1,49 @@ +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# + +"""add l7policy action redirect prefix + +Revision ID: 55874a4ceed6 +Revises: 76aacf2e176c +Create Date: 2018-09-09 20:35:38.780054 + +""" + +from alembic import op +import sqlalchemy as sa +from sqlalchemy import sql + +# revision identifiers, used by Alembic. +revision = '55874a4ceed6' +down_revision = '76aacf2e176c' + + +def upgrade(): + # Add collumn redirect_prefix + op.add_column( + u'l7policy', + sa.Column(u'redirect_prefix', sa.String(255), nullable=True) + ) + insert_table = sql.table( + u'l7policy_action', + sql.column(u'name', sa.String), + sql.column(u'description', sa.String) + ) + + op.bulk_insert( + insert_table, + [ + {'name': 'REDIRECT_PREFIX'} + ] + ) diff --git a/octavia/db/models.py b/octavia/db/models.py index ed46951a8d..5b1bd6fe3c 100644 --- a/octavia/db/models.py +++ b/octavia/db/models.py @@ -621,6 +621,9 @@ class L7Policy(base_models.BASE, base_models.IdMixin, base_models.ProjectMixin, redirect_url = sa.Column( sa.String(255), nullable=True) + redirect_prefix = sa.Column( + sa.String(255), + nullable=True) position = sa.Column(sa.Integer, nullable=False) enabled = sa.Column(sa.Boolean(), nullable=False) listener = orm.relationship("Listener", uselist=False, diff --git a/octavia/db/repositories.py b/octavia/db/repositories.py index c86c87a751..7494d4e41d 100644 --- a/octavia/db/repositories.py +++ b/octavia/db/repositories.py @@ -1589,12 +1589,19 @@ class L7PolicyRepository(BaseRepository): if l7policy.action == consts.L7POLICY_ACTION_REJECT: model_kwargs.update(redirect_url=None) model_kwargs.update(redirect_pool_id=None) + model_kwargs.update(redirect_prefix=None) elif (l7policy.action == consts.L7POLICY_ACTION_REDIRECT_TO_URL): model_kwargs.update(redirect_pool_id=None) + model_kwargs.update(redirect_prefix=None) elif (l7policy.action == consts.L7POLICY_ACTION_REDIRECT_TO_POOL): model_kwargs.update(redirect_url=None) + model_kwargs.update(redirect_prefix=None) + elif (l7policy.action == + consts.L7POLICY_ACTION_REDIRECT_PREFIX): + model_kwargs.update(redirect_url=None) + model_kwargs.update(redirect_pool_id=None) l7policy_db.update(model_kwargs) diff --git a/octavia/tests/functional/api/v1/test_load_balancer.py b/octavia/tests/functional/api/v1/test_load_balancer.py index 63715472cd..fe791c47d8 100644 --- a/octavia/tests/functional/api/v1/test_load_balancer.py +++ b/octavia/tests/functional/api/v1/test_load_balancer.py @@ -684,6 +684,7 @@ class TestLoadBalancerGraph(base.BaseAPITest): 'name': None, 'description': None, 'redirect_url': None, + 'redirect_prefix': None, 'l7rules': [] } expected_l7policy.update(create_l7policy) diff --git a/octavia/tests/functional/api/v2/test_load_balancer.py b/octavia/tests/functional/api/v2/test_load_balancer.py index 037b2d6e41..3dec0c2b6c 100644 --- a/octavia/tests/functional/api/v2/test_load_balancer.py +++ b/octavia/tests/functional/api/v2/test_load_balancer.py @@ -2256,6 +2256,7 @@ class TestLoadBalancerGraph(base.BaseAPITest): 'name': '', 'description': '', 'redirect_url': None, + 'redirect_prefix': None, 'rules': [], 'project_id': self._project_id, 'provisioning_status': constants.PENDING_CREATE, diff --git a/octavia/tests/unit/api/drivers/sample_data_models.py b/octavia/tests/unit/api/drivers/sample_data_models.py index cbb685648b..70a5a9be29 100644 --- a/octavia/tests/unit/api/drivers/sample_data_models.py +++ b/octavia/tests/unit/api/drivers/sample_data_models.py @@ -301,6 +301,7 @@ class SampleDriverDataModels(object): 'action': 'go', 'redirect_pool_id': self.pool1_id, 'redirect_url': '/index.html', + 'redirect_prefix': 'https://example.com/', 'position': 1, 'listener': None, 'redirect_pool': None, @@ -323,16 +324,19 @@ class SampleDriverDataModels(object): self.db_l7policies = [self.db_l7policy1, self.db_l7policy2] - self.provider_l7policy1_dict = {'action': 'go', - 'admin_state_up': True, - 'description': 'L7policy 1', - 'l7policy_id': self.l7policy1_id, - 'listener_id': self.listener1_id, - 'name': 'l7policy_1', - 'position': 1, - 'redirect_pool_id': self.pool1_id, - 'redirect_url': '/index.html', - 'rules': self.provider_l7rules_dicts} + self.provider_l7policy1_dict = { + 'action': 'go', + 'admin_state_up': True, + 'description': 'L7policy 1', + 'l7policy_id': self.l7policy1_id, + 'listener_id': self.listener1_id, + 'name': 'l7policy_1', + 'position': 1, + 'redirect_pool_id': self.pool1_id, + 'redirect_url': '/index.html', + 'redirect_prefix': 'https://example.com/', + 'rules': self.provider_l7rules_dicts + } self.provider_l7policy2_dict = copy.deepcopy( self.provider_l7policy1_dict) diff --git a/octavia/tests/unit/common/jinja/haproxy/test_jinja_cfg.py b/octavia/tests/unit/common/jinja/haproxy/test_jinja_cfg.py index 37c3e41ed8..773ac8f969 100644 --- a/octavia/tests/unit/common/jinja/haproxy/test_jinja_cfg.py +++ b/octavia/tests/unit/common/jinja/haproxy/test_jinja_cfg.py @@ -623,6 +623,12 @@ class TestHaproxyCfg(base.TestCase): ".example.com\n" " http-request deny if sample_l7rule_id_4 " "sample_l7rule_id_5\n" + " acl sample_l7rule_id_2 req.hdr(Some-header) -m sub " + "This\\ string\\\\\\ with\\ stuff\n" + " acl sample_l7rule_id_3 req.cook(some-cookie) -m reg " + "this.*|that\n" + " redirect prefix https://example.com if " + "!sample_l7rule_id_2 sample_l7rule_id_3\n" " default_backend sample_pool_id_1\n" " timeout client 50000\n\n").format( maxconn=constants.HAPROXY_MAX_MAXCONN) diff --git a/octavia/tests/unit/common/sample_configs/sample_configs.py b/octavia/tests/unit/common/sample_configs/sample_configs.py index 41d2477009..649f26be3d 100644 --- a/octavia/tests/unit/common/sample_configs/sample_configs.py +++ b/octavia/tests/unit/common/sample_configs/sample_configs.py @@ -192,6 +192,7 @@ RET_L7POLICY_1 = { 'action': constants.L7POLICY_ACTION_REDIRECT_TO_POOL, 'redirect_pool': RET_POOL_2, 'redirect_url': None, + 'redirect_prefix': None, 'enabled': True, 'l7rules': [RET_L7RULE_1]} @@ -200,6 +201,7 @@ RET_L7POLICY_2 = { 'action': constants.L7POLICY_ACTION_REDIRECT_TO_URL, 'redirect_pool': None, 'redirect_url': 'http://www.example.com', + 'redirect_prefix': None, 'enabled': True, 'l7rules': [RET_L7RULE_2, RET_L7RULE_3]} @@ -208,6 +210,7 @@ RET_L7POLICY_3 = { 'action': constants.L7POLICY_ACTION_REJECT, 'redirect_pool': None, 'redirect_url': None, + 'redirect_prefix': None, 'enabled': True, 'l7rules': [RET_L7RULE_4, RET_L7RULE_5]} @@ -216,6 +219,7 @@ RET_L7POLICY_4 = { 'action': constants.L7POLICY_ACTION_REJECT, 'redirect_pool': None, 'redirect_url': None, + 'redirect_prefix': None, 'enabled': True, 'l7rules': []} @@ -224,6 +228,7 @@ RET_L7POLICY_5 = { 'action': constants.L7POLICY_ACTION_REJECT, 'redirect_pool': None, 'redirect_url': None, + 'redirect_prefix': None, 'enabled': False, 'l7rules': [RET_L7RULE_5]} @@ -232,9 +237,19 @@ RET_L7POLICY_6 = { 'action': constants.L7POLICY_ACTION_REJECT, 'redirect_pool': None, 'redirect_url': None, + 'redirect_prefix': None, 'enabled': True, 'l7rules': []} +RET_L7POLICY_7 = { + 'id': 'sample_l7policy_id_7', + 'action': constants.L7POLICY_ACTION_REDIRECT_PREFIX, + 'redirect_pool': None, + 'redirect_url': None, + 'redirect_prefix': 'https://example.com', + 'enabled': True, + 'l7rules': [RET_L7RULE_2, RET_L7RULE_3]} + RET_LISTENER = { 'id': 'sample_listener_id_1', 'protocol_port': '80', @@ -267,7 +282,8 @@ RET_LISTENER_L7 = { 'topology': 'SINGLE', 'pools': [RET_POOL_1, RET_POOL_2], 'l7policies': [RET_L7POLICY_1, RET_L7POLICY_2, RET_L7POLICY_3, - RET_L7POLICY_4, RET_L7POLICY_5, RET_L7POLICY_6], + RET_L7POLICY_4, RET_L7POLICY_5, RET_L7POLICY_6, + RET_L7POLICY_7], 'enabled': True, 'insert_headers': {}, 'timeout_client_data': 50000, @@ -527,7 +543,8 @@ def sample_listener_tuple(proto=None, monitor=True, alloc_default_pool=True, sample_l7policy_tuple('sample_l7policy_id_3', sample_policy=3), sample_l7policy_tuple('sample_l7policy_id_4', sample_policy=4), sample_l7policy_tuple('sample_l7policy_id_5', sample_policy=5), - sample_l7policy_tuple('sample_l7policy_id_6', sample_policy=6)] + sample_l7policy_tuple('sample_l7policy_id_6', sample_policy=6), + sample_l7policy_tuple('sample_l7policy_id_7', sample_policy=7)] else: pools = [ sample_pool_tuple( @@ -733,10 +750,12 @@ def sample_health_monitor_tuple(proto='HTTP', sample_hm=1): def sample_l7policy_tuple(id, action=constants.L7POLICY_ACTION_REJECT, redirect_pool=None, redirect_url=None, + redirect_prefix=None, enabled=True, sample_policy=1): in_l7policy = collections.namedtuple('l7policy', 'id, action, redirect_pool, ' - 'redirect_url, l7rules, enabled') + 'redirect_url, redirect_prefix, ' + 'l7rules, enabled') l7rules = [] if sample_policy == 1: action = constants.L7POLICY_ACTION_REDIRECT_TO_POOL @@ -760,11 +779,17 @@ def sample_l7policy_tuple(id, elif sample_policy == 6: action = constants.L7POLICY_ACTION_REJECT l7rules = [sample_l7rule_tuple('sample_l7rule_id_6', sample_rule=6)] + elif sample_policy == 7: + action = constants.L7POLICY_ACTION_REDIRECT_PREFIX + redirect_prefix = 'https://example.com' + l7rules = [sample_l7rule_tuple('sample_l7rule_id_2', sample_rule=2), + sample_l7rule_tuple('sample_l7rule_id_3', sample_rule=3)] return in_l7policy( id=id, action=action, redirect_pool=redirect_pool, redirect_url=redirect_url, + redirect_prefix=redirect_prefix, l7rules=l7rules, enabled=enabled) diff --git a/releasenotes/notes/support-redirect-prefix-7f8b289aee04fe99.yaml b/releasenotes/notes/support-redirect-prefix-7f8b289aee04fe99.yaml new file mode 100644 index 0000000000..bd6980e98a --- /dev/null +++ b/releasenotes/notes/support-redirect-prefix-7f8b289aee04fe99.yaml @@ -0,0 +1,3 @@ +--- +features: + - Support REDIRECT_PREFIX action for L7Policy