Align Octavia API to n-lbaasv2 for L7Rules

The endpoint are as follows:

- /v2.0/lbaas/l7policies/
- /v2.0/l7policies/

GET all - /<policy-id>/l7rules/
GET one - /<policy-id>/l7rules/<rule-id>
POST - /<policy-id>/l7rules/ {<body>}
PUT - /<policy-id>/l7rules/<rule-id> {<body>}
DELETE - /<policy-id>/l7rules/<rule-id>

Partially Closes-Bug: #1616701
Co-Authored-By: Shashank Kumar Shankar <shashank.kumar.shankar@intel.com>
Co-Authored-By: Adam Harwell <flux.adam@gmail.com>

Change-Id: I247988a2ea19a92f827756504a0ee46679bbc53b
This commit is contained in:
Sindhu Devale 2016-12-02 20:08:33 +00:00 committed by Adam Harwell
parent c9daa3ff6e
commit fd5c800ff9
23 changed files with 1157 additions and 61 deletions

View File

@ -103,6 +103,12 @@ class BaseController(rest.RestController):
data_models.LoadBalancer, id)
return lb.project_id
def _get_l7policy_project_id(self, session, id):
"""Get the project_id of the load balancer from the database."""
l7policy = self._get_db_obj(session, self.repositories.l7policy,
data_models.LoadBalancer, id)
return l7policy.project_id
def _get_default_quotas(self, project_id):
"""Gets the project's default quotas."""
quotas = data_models.Quotas(

View File

@ -21,8 +21,8 @@ import pecan
from wsme import types as wtypes
from wsmeext import pecan as wsme_pecan
from octavia.api.v1.controllers import l7rule
from octavia.api.v2.controllers import base
from octavia.api.v2.controllers import l7rule
from octavia.api.v2.types import l7policy as l7policy_types
from octavia.common import constants
from octavia.common import data_models
@ -262,18 +262,13 @@ class L7PolicyController(base.BaseController):
which controller, if any, should control be passed.
"""
context = pecan.request.context.get('octavia_context')
db_l7policy = self._get_db_l7policy(context.session, l7policy_id)
load_balancer_id, listener_id = self._get_listener_and_loadbalancer_id(
db_l7policy)
if l7policy_id and len(remainder) and remainder[0] == 'l7rules':
if l7policy_id and len(remainder) and remainder[0] == 'rules':
remainder = remainder[1:]
db_l7policy = self.repositories.l7policy.get(
context.session, id=l7policy_id)
if not db_l7policy:
LOG.info(_LI("L7Policy %s not found."), l7policy_id)
raise exceptions.NotFound(
resource=data_models.L7Policy._name(), id=l7policy_id)
resource='L7Policy', id=l7policy_id)
return l7rule.L7RuleController(
load_balancer_id=load_balancer_id,
listener_id=listener_id,
l7policy_id=db_l7policy.id), remainder

View File

@ -0,0 +1,229 @@
# Copyright 2016 Blue Box, an IBM Company
#
# 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.
import logging
from oslo_db import exception as odb_exceptions
from oslo_utils import excutils
import pecan
from wsme import types as wtypes
from wsmeext import pecan as wsme_pecan
from octavia.api.v2.controllers import base
from octavia.api.v2.types import l7rule as l7rule_types
from octavia.common import constants
from octavia.common import data_models
from octavia.common import exceptions
from octavia.common import validate
from octavia.db import api as db_api
from octavia.db import prepare as db_prepare
from octavia.i18n import _LI
LOG = logging.getLogger(__name__)
class L7RuleController(base.BaseController):
def __init__(self, l7policy_id):
super(L7RuleController, self).__init__()
self.l7policy_id = l7policy_id
self.handler = self.handler.l7rule
@wsme_pecan.wsexpose(l7rule_types.L7RuleRootResponse, wtypes.text)
def get(self, id):
"""Gets a single l7rule's details."""
context = pecan.request.context.get('octavia_context')
db_l7rule = self._get_db_l7rule(context.session, id)
result = self._convert_db_to_type(db_l7rule,
l7rule_types.L7RuleResponse)
return l7rule_types.L7RuleRootResponse(rule=result)
@wsme_pecan.wsexpose(l7rule_types.L7RulesRootResponse, wtypes.text)
def get_all(self):
"""Lists all l7rules of a l7policy."""
context = pecan.request.context.get('octavia_context')
db_l7rules = self.repositories.l7rule.get_all(
context.session, l7policy_id=self.l7policy_id)
result = self._convert_db_to_type(db_l7rules,
[l7rule_types.L7RuleResponse])
return l7rule_types.L7RulesRootResponse(rules=result)
def _test_lb_listener_policy_statuses(self, session):
"""Verify load balancer is in a mutable state."""
l7policy = self._get_db_l7policy(session, self.l7policy_id)
listener_id = l7policy.listener_id
load_balancer_id = l7policy.listener.load_balancer_id
if not self.repositories.test_and_set_lb_and_listeners_prov_status(
session, load_balancer_id,
constants.PENDING_UPDATE, constants.PENDING_UPDATE,
listener_ids=[listener_id], l7policy_id=self.l7policy_id):
LOG.info(_LI("L7Rule cannot be created or modified because the "
"Load Balancer is in an immutable state"))
raise exceptions.ImmutableObject(resource='Load Balancer',
id=load_balancer_id)
def _check_l7policy_max_rules(self, session):
"""Checks to make sure the L7Policy doesn't have too many rules."""
count = self.repositories.l7rule.count(
session, l7policy_id=self.l7policy_id)
if count >= constants.MAX_L7RULES_PER_L7POLICY:
raise exceptions.TooManyL7RulesOnL7Policy(id=self.l7policy_id)
def _reset_lb_listener_policy_statuses(self, session):
# Setting LB + listeners back to active because this should be a
# recoverable error
l7policy = self._get_db_l7policy(session, self.l7policy_id)
listener_id = l7policy.listener_id
load_balancer_id = l7policy.listener.load_balancer_id
self.repositories.load_balancer.update(
session, load_balancer_id,
provisioning_status=constants.ACTIVE)
self.repositories.listener.update(
session, listener_id,
provisioning_status=constants.ACTIVE)
self.repositories.l7policy.update(
session, self.l7policy_id,
provisioning_status=constants.ACTIVE)
def _validate_create_l7rule(self, lock_session, l7rule_dict):
try:
return self.repositories.l7rule.create(lock_session, **l7rule_dict)
except odb_exceptions.DBDuplicateEntry as de:
if ['id'] == de.columns:
raise exceptions.IDAlreadyExists()
except odb_exceptions.DBError as de:
# TODO(blogan): will have to do separate validation protocol
# before creation or update since the exception messages
# do not give any information as to what constraint failed
raise exceptions.InvalidOption(value='', option='')
def _send_l7rule_to_handler(self, session, db_l7rule):
try:
LOG.info(_LI("Sending Creation of L7Rule %s to handler"),
db_l7rule.id)
self.handler.create(db_l7rule)
except Exception:
with excutils.save_and_reraise_exception(
reraise=False), db_api.get_lock_session() as lock_session:
self._reset_lb_listener_policy_statuses(lock_session)
# L7Rule now goes to ERROR
self.repositories.l7rule.update(
lock_session, db_l7rule.id,
provisioning_status=constants.ERROR)
db_l7rule = self._get_db_l7rule(session, db_l7rule.id)
result = self._convert_db_to_type(db_l7rule,
l7rule_types.L7RuleResponse)
return l7rule_types.L7RuleRootResponse(rule=result)
@wsme_pecan.wsexpose(l7rule_types.L7RuleRootResponse,
body=l7rule_types.L7RuleRootPOST, status_code=201)
def post(self, rule_):
"""Creates a l7rule on an l7policy."""
l7rule = rule_.rule
try:
validate.l7rule_data(l7rule)
except Exception as e:
raise exceptions.L7RuleValidation(error=e)
context = pecan.request.context.get('octavia_context')
l7rule.project_id = self._get_l7policy_project_id(context.session,
self.l7policy_id)
self._check_l7policy_max_rules(context.session)
lock_session = db_api.get_session(autocommit=False)
if self.repositories.check_quota_met(
context.session,
lock_session,
data_models.L7Rule,
l7rule.project_id):
lock_session.rollback()
raise exceptions.QuotaException
l7rule_dict = db_prepare.create_l7rule(
l7rule.to_dict(render_unsets=True), self.l7policy_id)
try:
self._test_lb_listener_policy_statuses(context.session)
db_l7rule = self._validate_create_l7rule(lock_session, l7rule_dict)
lock_session.commit()
except Exception:
with excutils.save_and_reraise_exception():
lock_session.rollback()
return self._send_l7rule_to_handler(context.session, db_l7rule)
@wsme_pecan.wsexpose(l7rule_types.L7RuleRootResponse,
wtypes.text, body=l7rule_types.L7RuleRootPUT,
status_code=200)
def put(self, id, l7rule_):
"""Updates a l7rule."""
l7rule = l7rule_.rule
context = pecan.request.context.get('octavia_context')
db_l7rule = self._get_db_l7rule(context.session, id)
new_l7rule = db_l7rule.to_dict()
new_l7rule.update(l7rule.to_dict())
new_l7rule = data_models.L7Rule.from_dict(new_l7rule)
try:
validate.l7rule_data(new_l7rule)
except Exception as e:
raise exceptions.L7RuleValidation(error=e)
self._test_lb_listener_policy_statuses(context.session)
self.repositories.l7rule.update(
context.session, db_l7rule.id,
provisioning_status=constants.PENDING_UPDATE)
try:
LOG.info(_LI("Sending Update of L7Rule %s to handler"), id)
self.handler.update(db_l7rule, l7rule)
except Exception:
with excutils.save_and_reraise_exception(
reraise=False), db_api.get_lock_session() as lock_session:
self._reset_lb_listener_policy_statuses(lock_session)
# L7Rule now goes to ERROR
self.repositories.l7rule.update(
lock_session, db_l7rule.id,
provisioning_status=constants.ERROR)
db_l7rule = self._get_db_l7rule(context.session, id)
result = self._convert_db_to_type(db_l7rule,
l7rule_types.L7RuleResponse)
return l7rule_types.L7RuleRootResponse(rule=result)
@wsme_pecan.wsexpose(None, wtypes.text, status_code=204)
def delete(self, id):
"""Deletes a l7rule."""
context = pecan.request.context.get('octavia_context')
db_l7rule = self._get_db_l7rule(context.session, id)
self._test_lb_listener_policy_statuses(context.session)
self.repositories.l7rule.update(
context.session, db_l7rule.id,
provisioning_status=constants.PENDING_DELETE)
try:
LOG.info(_LI("Sending Deletion of L7Rule %s to handler"),
db_l7rule.id)
self.handler.delete(db_l7rule)
except Exception:
with excutils.save_and_reraise_exception(
reraise=False), db_api.get_lock_session() as lock_session:
self._reset_lb_listener_policy_statuses(lock_session)
# L7Rule now goes to ERROR
self.repositories.l7rule.update(
lock_session, db_l7rule.id,
provisioning_status=constants.ERROR)
db_l7rule = self.repositories.l7rule.get(context.session, id=id)
result = self._convert_db_to_type(db_l7rule,
l7rule_types.L7RuleResponse)
return l7rule_types.L7RuleRootResponse(rule=result)

View File

@ -168,8 +168,7 @@ class MembersController(base.BaseController):
try:
self._test_lb_and_listener_and_pool_statuses(lock_session)
db_member = self._validate_create_member(
lock_session, member_dict)
db_member = self._validate_create_member(lock_session, member_dict)
lock_session.commit()
except Exception:
with excutils.save_and_reraise_exception():

View File

@ -0,0 +1,99 @@
# Copyright 2016 Blue Box, an IBM Company
#
# 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.
from wsme import types as wtypes
from octavia.api.common import types
from octavia.common import constants
class BaseL7Type(types.BaseType):
_type_to_model_map = {'admin_state_up': 'enabled'}
class L7RuleResponse(BaseL7Type):
"""Defines which attributes are to be shown on any response."""
id = wtypes.wsattr(wtypes.UuidType())
type = wtypes.wsattr(wtypes.StringType())
compare_type = wtypes.wsattr(wtypes.StringType())
key = wtypes.wsattr(wtypes.StringType())
value = wtypes.wsattr(wtypes.StringType())
invert = wtypes.wsattr(bool)
provisioning_status = wtypes.wsattr(wtypes.StringType())
operating_status = wtypes.wsattr(wtypes.StringType())
created_at = wtypes.wsattr(wtypes.datetime.datetime)
updated_at = wtypes.wsattr(wtypes.datetime.datetime)
# TODO(johnsom) Remove after deprecation (R series)
project_id = wtypes.wsattr(wtypes.StringType())
# TODO(johnsom) Remove after deprecation (R series)
tenant_id = wtypes.wsattr(wtypes.StringType())
admin_state_up = wtypes.wsattr(bool)
@classmethod
def from_data_model(cls, data_model, children=False):
rule = super(L7RuleResponse, cls).from_data_model(
data_model, children=children)
rule.tenant_id = data_model.project_id
return rule
class L7RuleRootResponse(types.BaseType):
rule = wtypes.wsattr(L7RuleResponse)
class L7RulesRootResponse(types.BaseType):
rules = wtypes.wsattr([L7RuleResponse])
class L7RulePOST(BaseL7Type):
"""Defines mandatory and optional attributes of a POST request."""
type = wtypes.wsattr(
wtypes.Enum(str,
*constants.SUPPORTED_L7RULE_TYPES),
mandatory=True)
compare_type = wtypes.wsattr(
wtypes.Enum(str,
*constants.SUPPORTED_L7RULE_COMPARE_TYPES),
mandatory=True)
key = wtypes.wsattr(wtypes.StringType(max_length=255))
value = wtypes.wsattr(wtypes.StringType(max_length=255), mandatory=True)
invert = wtypes.wsattr(bool, default=False)
admin_state_up = wtypes.wsattr(bool, default=True)
# TODO(johnsom) Remove after deprecation (R series)
project_id = wtypes.wsattr(wtypes.StringType(max_length=36))
# TODO(johnsom) Remove after deprecation (R series)
tenant_id = wtypes.wsattr(wtypes.StringType(max_length=36))
class L7RuleRootPOST(types.BaseType):
rule = wtypes.wsattr(L7RulePOST)
class L7RulePUT(BaseL7Type):
"""Defines attributes that are acceptable of a PUT request."""
type = wtypes.wsattr(
wtypes.Enum(str,
*constants.SUPPORTED_L7RULE_TYPES))
compare_type = wtypes.wsattr(
wtypes.Enum(str,
*constants.SUPPORTED_L7RULE_COMPARE_TYPES))
key = wtypes.wsattr(wtypes.StringType(max_length=255))
value = wtypes.wsattr(wtypes.StringType(max_length=255))
invert = wtypes.wsattr(bool)
admin_state_up = wtypes.wsattr(bool)
class L7RuleRootPUT(types.BaseType):
rule = wtypes.wsattr(L7RulePUT)

View File

@ -72,9 +72,9 @@ class MemberPOST(BaseMemberType):
minimum=constants.MIN_WEIGHT, maximum=constants.MAX_WEIGHT), default=1)
subnet_id = wtypes.wsattr(wtypes.UuidType())
# TODO(johnsom) Remove after deprecation (R series)
project_id = wtypes.wsattr(wtypes.StringType())
project_id = wtypes.wsattr(wtypes.StringType(max_length=36))
# TODO(johnsom) Remove after deprecation (R series)
tenant_id = wtypes.wsattr(wtypes.StringType())
tenant_id = wtypes.wsattr(wtypes.StringType(max_length=36))
class MemberRootPOST(types.BaseType):

View File

@ -517,9 +517,10 @@ class AmphoraHealth(BaseDataModel):
class L7Rule(BaseDataModel):
def __init__(self, id=None, l7policy_id=None, type=None,
def __init__(self, id=None, l7policy_id=None, type=None, enabled=None,
compare_type=None, key=None, value=None, l7policy=None,
invert=False, provisioning_status=None):
invert=False, provisioning_status=None, operating_status=None,
project_id=None, created_at=None, updated_at=None):
self.id = id
self.l7policy_id = l7policy_id
self.type = type
@ -529,6 +530,11 @@ class L7Rule(BaseDataModel):
self.l7policy = l7policy
self.invert = invert
self.provisioning_status = provisioning_status
self.operating_status = operating_status
self.project_id = project_id
self.created_at = created_at
self.updated_at = updated_at
self.enabled = enabled
def delete(self):
if len(self.l7policy.l7rules) == 1:

View File

@ -237,7 +237,7 @@ class InvalidRegex(OctaviaException):
class InvalidL7Rule(OctaviaException):
message = _('Invalid L7 Rule: $(msg)s')
message = _('Invalid L7 Rule: %(msg)s')
class ServerGroupObjectCreateException(OctaviaException):

View File

@ -311,7 +311,8 @@ class JinjaTemplater(object):
l7policy.redirect_pool)
else:
ret_value['redirect_pool'] = None
l7rules = [self._transform_l7rule(x) for x in l7policy.l7rules]
l7rules = [self._transform_l7rule(x) for x in l7policy.l7rules
if x.enabled]
ret_value['l7rules'] = l7rules
return ret_value
@ -326,7 +327,8 @@ class JinjaTemplater(object):
'compare_type': l7rule.compare_type,
'key': l7rule.key,
'value': self._escape_haproxy_config_string(l7rule.value),
'invert': l7rule.invert
'invert': l7rule.invert,
'enabled': l7rule.enabled
}
@staticmethod

View File

@ -1854,9 +1854,11 @@ class MarkL7RuleActiveInDB(BaseDatabaseTask):
LOG.debug("Mark ACTIVE in DB for l7rule id: %s",
l7rule.id)
op_status = constants.ONLINE if l7rule.enabled else constants.OFFLINE
self.l7rule_repo.update(db_apis.get_session(),
l7rule.id,
provisioning_status=constants.ACTIVE)
provisioning_status=constants.ACTIVE,
operating_status=op_status)
def revert(self, l7rule, *args, **kwargs):
"""Mark the l7rule as broken

View File

@ -0,0 +1,69 @@
# Copyright 2017 GoDaddy
#
# 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.
"""modernize l7rule
Revision ID: d85ca7258d21
Revises: 034b2dc2f3e0
Create Date: 2017-04-04 06:26:55.287198
"""
from alembic import op
import sqlalchemy as sa
from octavia.common import constants
# revision identifiers, used by Alembic.
revision = 'd85ca7258d21'
down_revision = '034b2dc2f3e0'
def upgrade():
# Add timing data
op.add_column(
u'l7rule',
sa.Column(u'created_at', sa.DateTime(), nullable=True)
)
op.add_column(
u'l7rule',
sa.Column(u'updated_at', sa.DateTime(), nullable=True)
)
# Add project_id
op.add_column(
u'l7rule',
sa.Column(u'project_id', sa.String(36), nullable=True)
)
# Add enabled
op.add_column(
u'l7rule',
sa.Column(u'enabled', sa.Boolean(), nullable=False)
)
# Add new operating_status column, setting existing rows to ONLINE
op.add_column(
u'l7rule',
sa.Column(u'operating_status', sa.String(16),
nullable=False, server_default=constants.ONLINE)
)
# Remove the default, as we don't actually want one
op.alter_column(u'l7rule', u'operating_status',
existing_type=sa.String(16), server_default=None)
# Add the foreign key for operating_status_name
op.create_foreign_key(
u'fk_l7rule_operating_status_name', u'l7rule',
u'operating_status', [u'operating_status'], [u'name']
)

View File

@ -177,6 +177,11 @@ class Member(base_models.BASE, base_models.IdMixin, base_models.ProjectMixin,
ip_address = sa.Column('ip_address', sa.String(64), nullable=False)
protocol_port = sa.Column(sa.Integer, nullable=False)
weight = sa.Column(sa.Integer, nullable=True)
provisioning_status = sa.Column(
sa.String(16),
sa.ForeignKey("provisioning_status.name",
name="fk_member_provisioning_status_name"),
nullable=False)
operating_status = sa.Column(
sa.String(16),
sa.ForeignKey("operating_status.name",
@ -186,11 +191,6 @@ class Member(base_models.BASE, base_models.IdMixin, base_models.ProjectMixin,
pool = orm.relationship("Pool", backref=orm.backref("members",
uselist=True,
cascade="delete"))
provisioning_status = sa.Column(
sa.String(16),
sa.ForeignKey("provisioning_status.name",
name="fk_member_provisioning_status_name"),
nullable=True)
class HealthMonitor(base_models.BASE, base_models.IdMixin,
@ -245,6 +245,11 @@ class Pool(base_models.BASE, base_models.IdMixin, base_models.ProjectMixin,
sa.String(255),
sa.ForeignKey("algorithm.name", name="fk_pool_algorithm_name"),
nullable=False)
provisioning_status = sa.Column(
sa.String(16),
sa.ForeignKey("provisioning_status.name",
name="fk_pool_provisioning_status_name"),
nullable=False)
operating_status = sa.Column(
sa.String(16),
sa.ForeignKey("operating_status.name",
@ -259,11 +264,6 @@ class Pool(base_models.BASE, base_models.IdMixin, base_models.ProjectMixin,
backref=orm.backref("pools",
uselist=True,
cascade="delete"))
provisioning_status = sa.Column(
sa.String(16),
sa.ForeignKey("provisioning_status.name",
name="fk_pool_provisioning_status_name"),
nullable=True)
# This property should be a unique list of any listeners that reference
# this pool as its default_pool and any listeners referenced by enabled
@ -494,7 +494,8 @@ class AmphoraHealth(base_models.BASE):
busy = sa.Column(sa.Boolean(), default=False, nullable=False)
class L7Rule(base_models.BASE, base_models.IdMixin):
class L7Rule(base_models.BASE, base_models.IdMixin, base_models.ProjectMixin,
models.TimestampMixin):
__data_model__ = data_models.L7Rule
@ -519,6 +520,7 @@ class L7Rule(base_models.BASE, base_models.IdMixin):
key = sa.Column(sa.String(255), nullable=True)
value = sa.Column(sa.String(255), nullable=False)
invert = sa.Column(sa.Boolean(), default=False, nullable=False)
enabled = sa.Column(sa.Boolean(), nullable=False)
l7policy = orm.relationship("L7Policy", uselist=False,
backref=orm.backref("l7rules",
uselist=True,
@ -527,7 +529,12 @@ class L7Rule(base_models.BASE, base_models.IdMixin):
sa.String(16),
sa.ForeignKey("provisioning_status.name",
name="fk_l7rule_provisioning_status_name"),
nullable=True)
nullable=False)
operating_status = sa.Column(
sa.String(16),
sa.ForeignKey("operating_status.name",
name="fk_l7rule_operating_status_name"),
nullable=False)
class L7Policy(base_models.BASE, base_models.IdMixin, base_models.ProjectMixin,

View File

@ -129,9 +129,13 @@ def create_l7policy(l7policy_dict, lb_id, listener_id):
def create_l7rule(l7rule_dict, l7policy_id):
l7rule_dict['provisioning_status'] = constants.PENDING_CREATE
l7rule_dict['operating_status'] = constants.OFFLINE
if not l7rule_dict.get('id'):
l7rule_dict['id'] = uuidutils.generate_uuid()
l7rule_dict['l7policy_id'] = l7policy_id
if 'enabled' not in l7rule_dict:
l7rule_dict['enabled'] = True
return l7rule_dict

View File

@ -219,7 +219,8 @@ class Repositories(object):
lb_prov_status,
listener_prov_status,
listener_ids=None,
pool_id=None):
pool_id=None,
l7policy_id=None):
"""Tests and sets a load balancer and listener provisioning status.
Puts a lock on the load balancer table to check the status of a
@ -236,6 +237,8 @@ class Repositories(object):
(only use this when relevant to the operation)
:param pool_id: ID of the Pool to check and lock (only use this when
relevant to the operation)
:param l7policy_id: ID of the L7Policy to check and lock (only use this
when relevant to the operation)
:returns: bool
"""
listener_ids = listener_ids or []
@ -251,6 +254,9 @@ class Repositories(object):
if pool_id:
self.pool.update(session, pool_id,
provisioning_status=lb_prov_status)
if l7policy_id:
self.l7policy.update(session, l7policy_id,
provisioning_status=lb_prov_status)
return success
def check_quota_met(self, session, lock_session, _class, project_id):

View File

@ -56,7 +56,7 @@ class BaseAPITest(base_db_test.OctaviaDBTestBase):
# /lbaas/l7policies
L7POLICIES_PATH = '/l7policies'
L7POLICY_PATH = L7POLICIES_PATH + '/{l7policy_id}'
L7RULES_PATH = L7POLICY_PATH + '/l7rules'
L7RULES_PATH = L7POLICY_PATH + '/rules'
L7RULE_PATH = L7RULES_PATH + '/{l7rule_id}'
def setUp(self):
@ -71,6 +71,7 @@ class BaseAPITest(base_db_test.OctaviaDBTestBase):
self.pool_repo = repositories.PoolRepository()
self.member_repo = repositories.MemberRepository()
self.l7policy_repo = repositories.L7PolicyRepository()
self.l7rule_repo = repositories.L7RuleRepository()
self.amphora_repo = repositories.AmphoraRepository()
patcher = mock.patch('octavia.api.handlers.controller_simulator.'
'handler.SimulatedControllerHandler')
@ -260,7 +261,7 @@ class BaseAPITest(base_db_test.OctaviaDBTestBase):
value, **optionals):
req_dict = {'type': type, 'compare_type': compare_type, 'value': value}
req_dict.update(optionals)
body = {'l7rule': req_dict}
body = {'rule': req_dict}
path = self.L7RULES_PATH.format(l7policy_id=l7policy_id)
response = self.post(path, body)
return response.json
@ -284,9 +285,25 @@ class BaseAPITest(base_db_test.OctaviaDBTestBase):
lb_l7policies = self.l7policy_repo.get_all(db_api.get_session(),
listener_id=listener.id)
for l7policy in lb_l7policies:
if autodetect and (l7policy.provisioning_status ==
constants.PENDING_DELETE):
l7policy_prov = constants.DELETED
else:
l7policy_prov = prov_status
self.l7policy_repo.update(db_api.get_session(), l7policy.id,
provisioning_status=listener_prov,
provisioning_status=l7policy_prov,
operating_status=op_status)
l7rules = self.l7rule_repo.get_all(db_api.get_session(),
l7policy_id=l7policy.id)
for l7rule in l7rules:
if autodetect and (l7rule.provisioning_status ==
constants.PENDING_DELETE):
l7rule_prov = constants.DELETED
else:
l7rule_prov = prov_status
self.l7rule_repo.update(db_api.get_session(), l7rule.id,
provisioning_status=l7rule_prov,
operating_status=op_status)
lb_pools = self.pool_repo.get_all(db_api.get_session(),
load_balancer_id=lb_id)
for pool in lb_pools:
@ -389,18 +406,29 @@ class BaseAPITest(base_db_test.OctaviaDBTestBase):
self.assertEqual(operating_status,
api_l7policy.get('operating_status'))
def assert_correct_l7rule_status(self, provisioning_status,
operating_status, l7policy_id, l7rule_id):
api_l7rule = self.get(self.L7RULE_PATH.format(
l7policy_id=l7policy_id, l7rule_id=l7rule_id)).json.get('rule')
self.assertEqual(provisioning_status,
api_l7rule.get('provisioning_status'))
self.assertEqual(operating_status,
api_l7rule.get('operating_status'))
def assert_correct_status(self, lb_id=None, listener_id=None, pool_id=None,
member_id=None, l7policy_id=None,
member_id=None, l7policy_id=None, l7rule_id=None,
lb_prov_status=constants.ACTIVE,
listener_prov_status=constants.ACTIVE,
pool_prov_status=constants.ACTIVE,
member_prov_status=constants.ACTIVE,
l7policy_prov_status=constants.ACTIVE,
l7rule_prov_status=constants.ACTIVE,
lb_op_status=constants.ONLINE,
listener_op_status=constants.ONLINE,
pool_op_status=constants.ONLINE,
member_op_status=constants.ONLINE,
l7policy_op_status=constants.ONLINE):
l7policy_op_status=constants.ONLINE,
l7rule_op_status=constants.ONLINE):
if lb_id:
self.assert_correct_lb_status(lb_prov_status, lb_op_status, lb_id)
if listener_id:
@ -415,3 +443,6 @@ class BaseAPITest(base_db_test.OctaviaDBTestBase):
if l7policy_id:
self.assert_correct_l7policy_status(
l7policy_prov_status, l7policy_op_status, l7policy_id)
if l7rule_id:
self.assert_correct_l7rule_status(
l7rule_prov_status, l7rule_op_status, l7policy_id, l7rule_id)

View File

@ -285,6 +285,14 @@ class TestL7Policy(base.BaseAPITest):
l7policy_prov_status=constants.ERROR,
l7policy_op_status=constants.OFFLINE)
def test_create_over_quota(self):
self.check_quota_met_true_mock.start()
self.addCleanup(self.check_quota_met_true_mock.stop)
l7policy = {'listener_id': self.listener_id,
'action': constants.L7POLICY_ACTION_REDIRECT_TO_URL,
'redirect_url': 'http://a.com'}
self.post(self.L7POLICIES_PATH, self._build_body(l7policy), status=403)
def test_update(self):
api_l7policy = self.create_l7policy(self.listener_id,
constants.L7POLICY_ACTION_REJECT,

View File

@ -0,0 +1,445 @@
# Copyright 2016 Blue Box, an IBM Company
#
# 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.
from oslo_utils import uuidutils
from octavia.common import constants
from octavia.tests.functional.api.v2 import base
class TestL7Rule(base.BaseAPITest):
root_tag = 'rule'
root_tag_list = 'rules'
root_tag_links = 'rules_links'
def setUp(self):
super(TestL7Rule, self).setUp()
self.lb = self.create_load_balancer(uuidutils.generate_uuid())
self.lb_id = self.lb.get('loadbalancer').get('id')
self.set_lb_status(self.lb_id)
self.listener = self.create_listener(
constants.PROTOCOL_HTTP, 80, lb_id=self.lb_id)
self.listener_id = self.listener.get('listener').get('id')
self.set_lb_status(self.lb_id)
self.l7policy = self.create_l7policy(
self.listener_id, constants.L7POLICY_ACTION_REJECT)
self.l7policy_id = self.l7policy.get('l7policy').get('id')
self.set_lb_status(self.lb_id)
self.l7rules_path = self.L7RULES_PATH.format(
l7policy_id=self.l7policy_id)
self.l7rule_path = self.l7rules_path + '/{l7rule_id}'
def test_get(self):
l7rule = self.create_l7rule(
self.l7policy_id, constants.L7RULE_TYPE_PATH,
constants.L7RULE_COMPARE_TYPE_STARTS_WITH,
'/api').get(self.root_tag)
response = self.get(self.l7rule_path.format(
l7rule_id=l7rule.get('id'))).json.get(self.root_tag)
self.assertEqual(l7rule, response)
def test_get_bad_parent_policy(self):
bad_path = (self.L7RULES_PATH.format(
lb_id=self.lb_id, listener_id=self.listener_id,
l7policy_id=uuidutils.generate_uuid()) + '/' +
uuidutils.generate_uuid())
self.get(bad_path, status=404)
def test_bad_get(self):
self.get(self.l7rule_path.format(
l7rule_id=uuidutils.generate_uuid()), status=404)
def test_get_all(self):
api_l7r_a = self.create_l7rule(
self.l7policy_id, constants.L7RULE_TYPE_PATH,
constants.L7RULE_COMPARE_TYPE_STARTS_WITH,
'/api').get(self.root_tag)
self.set_lb_status(self.lb_id)
api_l7r_b = self.create_l7rule(
self.l7policy_id, constants.L7RULE_TYPE_COOKIE,
constants.L7RULE_COMPARE_TYPE_CONTAINS, 'some-value',
key='some-cookie').get(self.root_tag)
self.set_lb_status(self.lb_id)
rules = self.get(self.l7rules_path).json.get(self.root_tag_list)
self.assertIsInstance(rules, list)
self.assertEqual(2, len(rules))
rule_id_types = [(r.get('id'), r.get('type')) for r in rules]
self.assertIn((api_l7r_a.get('id'), api_l7r_a.get('type')),
rule_id_types)
self.assertIn((api_l7r_b.get('id'), api_l7r_b.get('type')),
rule_id_types)
def test_empty_get_all(self):
response = self.get(self.l7rules_path).json.get(self.root_tag_list)
self.assertIsInstance(response, list)
self.assertEqual(0, len(response))
def test_create_host_name_rule(self):
api_l7rule = self.create_l7rule(
self.l7policy_id, constants.L7RULE_TYPE_HOST_NAME,
constants.L7RULE_COMPARE_TYPE_EQUAL_TO,
'www.example.com').get(self.root_tag)
self.assertEqual(constants.L7RULE_TYPE_HOST_NAME,
api_l7rule.get('type'))
self.assertEqual(constants.L7RULE_COMPARE_TYPE_EQUAL_TO,
api_l7rule.get('compare_type'))
self.assertEqual('www.example.com', api_l7rule.get('value'))
self.assertIsNone(api_l7rule.get('key'))
self.assertFalse(api_l7rule.get('invert'))
self.assert_correct_status(
lb_id=self.lb_id, listener_id=self.listener_id,
l7policy_id=self.l7policy_id, l7rule_id=api_l7rule.get('id'),
lb_prov_status=constants.PENDING_UPDATE,
listener_prov_status=constants.PENDING_UPDATE,
l7policy_prov_status=constants.PENDING_UPDATE,
l7rule_prov_status=constants.PENDING_CREATE,
l7rule_op_status=constants.OFFLINE)
def test_create_path_rule(self):
api_l7rule = self.create_l7rule(
self.l7policy_id, constants.L7RULE_TYPE_PATH,
constants.L7RULE_COMPARE_TYPE_STARTS_WITH, '/api',
invert=True).get(self.root_tag)
self.assertEqual(constants.L7RULE_TYPE_PATH, api_l7rule.get('type'))
self.assertEqual(constants.L7RULE_COMPARE_TYPE_STARTS_WITH,
api_l7rule.get('compare_type'))
self.assertEqual('/api', api_l7rule.get('value'))
self.assertIsNone(api_l7rule.get('key'))
self.assertTrue(api_l7rule.get('invert'))
self.assert_correct_status(
lb_id=self.lb_id, listener_id=self.listener_id,
l7policy_id=self.l7policy_id, l7rule_id=api_l7rule.get('id'),
lb_prov_status=constants.PENDING_UPDATE,
listener_prov_status=constants.PENDING_UPDATE,
l7policy_prov_status=constants.PENDING_UPDATE,
l7rule_prov_status=constants.PENDING_CREATE,
l7rule_op_status=constants.OFFLINE)
def test_create_file_type_rule(self):
api_l7rule = self.create_l7rule(
self.l7policy_id, constants.L7RULE_TYPE_FILE_TYPE,
constants.L7RULE_COMPARE_TYPE_REGEX, 'jpg|png').get(self.root_tag)
self.assertEqual(constants.L7RULE_TYPE_FILE_TYPE,
api_l7rule.get('type'))
self.assertEqual(constants.L7RULE_COMPARE_TYPE_REGEX,
api_l7rule.get('compare_type'))
self.assertEqual('jpg|png', api_l7rule.get('value'))
self.assertIsNone(api_l7rule.get('key'))
self.assertFalse(api_l7rule.get('invert'))
self.assert_correct_status(
lb_id=self.lb_id, listener_id=self.listener_id,
l7policy_id=self.l7policy_id, l7rule_id=api_l7rule.get('id'),
lb_prov_status=constants.PENDING_UPDATE,
listener_prov_status=constants.PENDING_UPDATE,
l7policy_prov_status=constants.PENDING_UPDATE,
l7rule_prov_status=constants.PENDING_CREATE,
l7rule_op_status=constants.OFFLINE)
def test_create_header_rule(self):
api_l7rule = self.create_l7rule(
self.l7policy_id, constants.L7RULE_TYPE_HEADER,
constants.L7RULE_COMPARE_TYPE_ENDS_WITH, '"some string"',
key='Some-header').get(self.root_tag)
self.assertEqual(constants.L7RULE_TYPE_HEADER, api_l7rule.get('type'))
self.assertEqual(constants.L7RULE_COMPARE_TYPE_ENDS_WITH,
api_l7rule.get('compare_type'))
self.assertEqual('"some string"', api_l7rule.get('value'))
self.assertEqual('Some-header', api_l7rule.get('key'))
self.assertFalse(api_l7rule.get('invert'))
self.assert_correct_status(
lb_id=self.lb_id, listener_id=self.listener_id,
l7policy_id=self.l7policy_id, l7rule_id=api_l7rule.get('id'),
lb_prov_status=constants.PENDING_UPDATE,
listener_prov_status=constants.PENDING_UPDATE,
l7policy_prov_status=constants.PENDING_UPDATE,
l7rule_prov_status=constants.PENDING_CREATE,
l7rule_op_status=constants.OFFLINE)
def test_create_cookie_rule(self):
api_l7rule = self.create_l7rule(
self.l7policy_id, constants.L7RULE_TYPE_COOKIE,
constants.L7RULE_COMPARE_TYPE_CONTAINS, 'some-value',
key='some-cookie').get(self.root_tag)
self.assertEqual(constants.L7RULE_TYPE_COOKIE, api_l7rule.get('type'))
self.assertEqual(constants.L7RULE_COMPARE_TYPE_CONTAINS,
api_l7rule.get('compare_type'))
self.assertEqual('some-value', api_l7rule.get('value'))
self.assertEqual('some-cookie', api_l7rule.get('key'))
self.assertFalse(api_l7rule.get('invert'))
self.assert_correct_status(
lb_id=self.lb_id, listener_id=self.listener_id,
l7policy_id=self.l7policy_id, l7rule_id=api_l7rule.get('id'),
lb_prov_status=constants.PENDING_UPDATE,
listener_prov_status=constants.PENDING_UPDATE,
l7policy_prov_status=constants.PENDING_UPDATE,
l7rule_prov_status=constants.PENDING_CREATE,
l7rule_op_status=constants.OFFLINE)
def test_create_too_many_rules(self):
for i in range(0, constants.MAX_L7RULES_PER_L7POLICY):
self.create_l7rule(
self.l7policy_id, constants.L7RULE_TYPE_PATH,
constants.L7RULE_COMPARE_TYPE_STARTS_WITH,
'/api').get(self.root_tag)
self.set_lb_status(self.lb_id)
body = {'type': constants.L7RULE_TYPE_PATH,
'compare_type': constants.L7RULE_COMPARE_TYPE_STARTS_WITH,
'value': '/api'}
self.post(self.l7rules_path, self._build_body(body), status=409)
def test_bad_create(self):
l7rule = {'name': 'test1'}
self.post(self.l7rules_path, self._build_body(l7rule), status=400)
def test_bad_create_host_name_rule(self):
l7rule = {'type': constants.L7RULE_TYPE_HOST_NAME,
'compare_type': constants.L7RULE_COMPARE_TYPE_STARTS_WITH}
self.post(self.l7rules_path, self._build_body(l7rule), status=400)
def test_bad_create_path_rule(self):
l7rule = {'type': constants.L7RULE_TYPE_PATH,
'compare_type': constants.L7RULE_COMPARE_TYPE_REGEX,
'value': 'bad string\\'}
self.post(self.l7rules_path, self._build_body(l7rule), status=400)
def test_bad_create_file_type_rule(self):
l7rule = {'type': constants.L7RULE_TYPE_FILE_TYPE,
'compare_type': constants.L7RULE_COMPARE_TYPE_STARTS_WITH,
'value': 'png'}
self.post(self.l7rules_path, self._build_body(l7rule), status=400)
def test_bad_create_header_rule(self):
l7rule = {'type': constants.L7RULE_TYPE_HEADER,
'compare_type': constants.L7RULE_COMPARE_TYPE_CONTAINS,
'value': 'some-string'}
self.post(self.l7rules_path, self._build_body(l7rule), status=400)
def test_bad_create_cookie_rule(self):
l7rule = {'type': constants.L7RULE_TYPE_COOKIE,
'compare_type': constants.L7RULE_COMPARE_TYPE_EQUAL_TO,
'key': 'bad cookie name',
'value': 'some-string'}
self.post(self.l7rules_path, self._build_body(l7rule), status=400)
def test_create_with_bad_handler(self):
self.handler_mock().l7rule.create.side_effect = Exception()
api_l7rule = self.create_l7rule(
self.l7policy_id, constants.L7RULE_TYPE_PATH,
constants.L7RULE_COMPARE_TYPE_STARTS_WITH,
'/api').get(self.root_tag)
self.assert_correct_status(
lb_id=self.lb_id, listener_id=self.listener_id,
l7policy_id=self.l7policy_id, l7rule_id=api_l7rule.get('id'),
l7rule_prov_status=constants.ERROR,
l7rule_op_status=constants.OFFLINE)
def test_create_over_quota(self):
self.check_quota_met_true_mock.start()
self.addCleanup(self.check_quota_met_true_mock.stop)
body = {'type': constants.L7RULE_TYPE_PATH,
'compare_type': constants.L7RULE_COMPARE_TYPE_STARTS_WITH,
'value': '/api'}
self.post(self.l7rules_path, self._build_body(body), status=403)
def test_update(self):
api_l7rule = self.create_l7rule(
self.l7policy_id, constants.L7RULE_TYPE_PATH,
constants.L7RULE_COMPARE_TYPE_STARTS_WITH,
'/api').get(self.root_tag)
self.set_lb_status(self.lb_id)
new_l7rule = {'value': '/images'}
response = self.put(self.l7rule_path.format(
l7rule_id=api_l7rule.get('id')),
self._build_body(new_l7rule)).json.get(self.root_tag)
self.assertEqual('/api', response.get('value'))
self.assert_correct_status(
lb_id=self.lb_id, listener_id=self.listener_id,
l7policy_id=self.l7policy_id, l7rule_id=api_l7rule.get('id'),
lb_prov_status=constants.PENDING_UPDATE,
listener_prov_status=constants.PENDING_UPDATE,
l7policy_prov_status=constants.PENDING_UPDATE,
l7rule_prov_status=constants.PENDING_UPDATE)
def test_bad_update(self):
l7rule = self.create_l7rule(
self.l7policy_id, constants.L7RULE_TYPE_PATH,
constants.L7RULE_COMPARE_TYPE_STARTS_WITH,
'/api').get(self.root_tag)
new_l7rule = {'type': 'bad type'}
self.put(self.l7rule_path.format(l7rule_id=l7rule.get('id')),
self._build_body(new_l7rule), status=400)
def test_update_with_bad_handler(self):
api_l7rule = self.create_l7rule(
self.l7policy_id, constants.L7RULE_TYPE_PATH,
constants.L7RULE_COMPARE_TYPE_STARTS_WITH,
'/api').get(self.root_tag)
self.set_lb_status(self.lb_id)
new_l7rule = {'value': '/images'}
self.handler_mock().l7rule.update.side_effect = Exception()
self.put(self.l7rule_path.format(
l7rule_id=api_l7rule.get('id')), self._build_body(new_l7rule))
self.assert_correct_status(
lb_id=self.lb_id, listener_id=self.listener_id,
l7policy_id=self.l7policy_id, l7rule_id=api_l7rule.get('id'),
l7rule_prov_status=constants.ERROR)
def test_update_with_invalid_rule(self):
api_l7rule = self.create_l7rule(
self.l7policy_id, constants.L7RULE_TYPE_PATH,
constants.L7RULE_COMPARE_TYPE_STARTS_WITH,
'/api').get(self.root_tag)
self.set_lb_status(self.lb_id)
new_l7rule = {'compare_type': constants.L7RULE_COMPARE_TYPE_REGEX,
'value': 'bad string\\'}
self.put(self.l7rule_path.format(
l7rule_id=api_l7rule.get('id')), self._build_body(new_l7rule),
status=400)
self.assert_correct_status(
lb_id=self.lb_id, listener_id=self.listener_id,
l7policy_id=self.l7policy_id, l7rule_id=api_l7rule.get('id'),
l7rule_prov_status=constants.ACTIVE)
def test_delete(self):
api_l7rule = self.create_l7rule(
self.l7policy_id, constants.L7RULE_TYPE_PATH,
constants.L7RULE_COMPARE_TYPE_STARTS_WITH,
'/api').get(self.root_tag)
self.set_lb_status(self.lb_id)
# Set status to ACTIVE/ONLINE because set_lb_status did it in the db
api_l7rule['provisioning_status'] = constants.ACTIVE
api_l7rule['operating_status'] = constants.ONLINE
api_l7rule.pop('updated_at')
response = self.get(self.l7rule_path.format(
l7rule_id=api_l7rule.get('id'))).json.get(self.root_tag)
response.pop('updated_at')
self.assertEqual(api_l7rule, response)
self.delete(self.l7rule_path.format(l7rule_id=api_l7rule.get('id')))
self.assert_correct_status(
lb_id=self.lb_id, listener_id=self.listener_id,
l7policy_id=self.l7policy_id, l7rule_id=api_l7rule.get('id'),
lb_prov_status=constants.PENDING_UPDATE,
listener_prov_status=constants.PENDING_UPDATE,
l7policy_prov_status=constants.PENDING_UPDATE,
l7rule_prov_status=constants.PENDING_DELETE)
self.set_lb_status(self.lb_id)
def test_bad_delete(self):
self.delete(self.l7rule_path.format(
l7rule_id=uuidutils.generate_uuid()), status=404)
def test_delete_with_bad_handler(self):
api_l7rule = self.create_l7rule(
self.l7policy_id, constants.L7RULE_TYPE_PATH,
constants.L7RULE_COMPARE_TYPE_STARTS_WITH,
'/api').get(self.root_tag)
self.set_lb_status(self.lb_id)
# Set status to ACTIVE/ONLINE because set_lb_status did it in the db
api_l7rule['provisioning_status'] = constants.ACTIVE
api_l7rule['operating_status'] = constants.ONLINE
response = self.get(self.l7rule_path.format(
l7rule_id=api_l7rule.get('id'))).json.get(self.root_tag)
self.assertIsNone(api_l7rule.pop('updated_at'))
self.assertIsNotNone(response.pop('updated_at'))
self.assertEqual(api_l7rule, response)
self.handler_mock().l7rule.delete.side_effect = Exception()
self.delete(self.l7rule_path.format(l7rule_id=api_l7rule.get('id')))
self.assert_correct_status(
lb_id=self.lb_id, listener_id=self.listener_id,
l7policy_id=self.l7policy_id, l7rule_id=api_l7rule.get('id'),
l7rule_prov_status=constants.ERROR)
def test_create_when_lb_pending_update(self):
self.create_l7rule(
self.l7policy_id, constants.L7RULE_TYPE_PATH,
constants.L7RULE_COMPARE_TYPE_STARTS_WITH,
'/api').get(self.root_tag)
self.set_lb_status(self.lb_id)
self.put(self.LB_PATH.format(lb_id=self.lb_id),
body={'loadbalancer': {'name': 'test_name_change'}})
new_l7rule = {'type': constants.L7RULE_TYPE_PATH,
'compare_type': constants.L7RULE_COMPARE_TYPE_EQUAL_TO,
'value': '/api'}
self.post(self.l7rules_path, body=self._build_body(new_l7rule),
status=409)
def test_update_when_lb_pending_update(self):
l7rule = self.create_l7rule(
self.l7policy_id, constants.L7RULE_TYPE_PATH,
constants.L7RULE_COMPARE_TYPE_STARTS_WITH,
'/api').get(self.root_tag)
self.set_lb_status(self.lb_id)
self.put(self.LB_PATH.format(lb_id=self.lb_id),
body={'loadbalancer': {'name': 'test_name_change'}})
new_l7rule = {'type': constants.L7RULE_TYPE_HOST_NAME,
'compare_type': constants.L7RULE_COMPARE_TYPE_REGEX,
'value': '.*.example.com'}
self.put(self.l7rule_path.format(l7rule_id=l7rule.get('id')),
body=self._build_body(new_l7rule), status=409)
def test_delete_when_lb_pending_update(self):
l7rule = self.create_l7rule(
self.l7policy_id, constants.L7RULE_TYPE_PATH,
constants.L7RULE_COMPARE_TYPE_STARTS_WITH,
'/api').get(self.root_tag)
self.set_lb_status(self.lb_id)
self.put(self.LB_PATH.format(lb_id=self.lb_id),
body={'loadbalancer': {'name': 'test_name_change'}})
self.delete(self.l7rule_path.format(l7rule_id=l7rule.get('id')),
status=409)
def test_create_when_lb_pending_delete(self):
self.create_l7rule(
self.l7policy_id, constants.L7RULE_TYPE_PATH,
constants.L7RULE_COMPARE_TYPE_STARTS_WITH,
'/api').get(self.root_tag)
self.set_lb_status(self.lb_id)
self.delete(self.LB_PATH.format(lb_id=self.lb_id))
new_l7rule = {'type': constants.L7RULE_TYPE_HEADER,
'compare_type':
constants.L7RULE_COMPARE_TYPE_STARTS_WITH,
'value': 'some-string',
'key': 'Some-header'}
self.post(self.l7rules_path, body=self._build_body(new_l7rule),
status=409)
def test_update_when_lb_pending_delete(self):
l7rule = self.create_l7rule(
self.l7policy_id, constants.L7RULE_TYPE_PATH,
constants.L7RULE_COMPARE_TYPE_STARTS_WITH,
'/api').get(self.root_tag)
self.set_lb_status(self.lb_id)
self.delete(self.LB_PATH.format(lb_id=self.lb_id))
new_l7rule = {'type': constants.L7RULE_TYPE_COOKIE,
'compare_type':
constants.L7RULE_COMPARE_TYPE_ENDS_WITH,
'value': 'some-string',
'key': 'some-cookie'}
self.put(self.l7rule_path.format(l7rule_id=l7rule.get('id')),
body=self._build_body(new_l7rule), status=409)
def test_delete_when_lb_pending_delete(self):
l7rule = self.create_l7rule(
self.l7policy_id, constants.L7RULE_TYPE_PATH,
constants.L7RULE_COMPARE_TYPE_STARTS_WITH,
'/api').get(self.root_tag)
self.set_lb_status(self.lb_id)
self.delete(self.LB_PATH.format(lb_id=self.lb_id))
self.delete(self.l7rule_path.format(l7rule_id=l7rule.get('id')),
status=409)

View File

@ -67,6 +67,7 @@ class ModelTestMixin(object):
'id': self.FAKE_UUID_1,
'protocol': constants.PROTOCOL_HTTP,
'lb_algorithm': constants.LB_ALGORITHM_LEAST_CONNECTIONS,
'provisioning_status': constants.ACTIVE,
'operating_status': constants.ONLINE,
'enabled': True}
kwargs.update(overrides)
@ -98,6 +99,7 @@ class ModelTestMixin(object):
'pool_id': pool_id,
'ip_address': '10.0.0.1',
'protocol_port': 80,
'provisioning_status': constants.ACTIVE,
'operating_status': constants.ONLINE,
'enabled': True}
kwargs.update(overrides)
@ -150,8 +152,8 @@ class ModelTestMixin(object):
'listener_id': listener_id,
'action': constants.L7POLICY_ACTION_REJECT,
'position': 1,
'provisioning_status': constants.PENDING_CREATE,
'operating_status': constants.OFFLINE,
'provisioning_status': constants.ACTIVE,
'operating_status': constants.ONLINE,
'enabled': True}
kwargs.update(overrides)
return self._insert(session, models.L7Policy, kwargs)
@ -161,7 +163,10 @@ class ModelTestMixin(object):
'l7policy_id': l7policy_id,
'type': constants.L7RULE_TYPE_PATH,
'compare_type': constants.L7RULE_COMPARE_TYPE_STARTS_WITH,
'value': '/api'}
'value': '/api',
'provisioning_status': constants.ACTIVE,
'operating_status': constants.ONLINE,
'enabled': True}
kwargs.update(overrides)
return self._insert(session, models.L7Rule, kwargs)

View File

@ -155,7 +155,7 @@ class AllRepositoriesTest(base.OctaviaDBTestBase):
'enabled': True, 'operating_status': constants.ONLINE,
'project_id': uuidutils.generate_uuid(),
'id': uuidutils.generate_uuid(),
'provisioning_status': None}
'provisioning_status': constants.ACTIVE}
pool_dm = self.repos.create_pool_on_load_balancer(
self.session, pool, listener_id=self.listener.id)
pool_dm_dict = pool_dm.to_dict()
@ -180,7 +180,7 @@ class AllRepositoriesTest(base.OctaviaDBTestBase):
'enabled': True, 'operating_status': constants.ONLINE,
'project_id': uuidutils.generate_uuid(),
'id': uuidutils.generate_uuid(),
'provisioning_status': None}
'provisioning_status': constants.ACTIVE}
sp = {'type': constants.SESSION_PERSISTENCE_HTTP_COOKIE,
'cookie_name': 'cookie_monster',
'pool_id': pool['id']}
@ -216,7 +216,7 @@ class AllRepositoriesTest(base.OctaviaDBTestBase):
'enabled': True, 'operating_status': constants.ONLINE,
'project_id': uuidutils.generate_uuid(),
'id': uuidutils.generate_uuid(),
'provisioning_status': None}
'provisioning_status': constants.ACTIVE}
pool_dm = self.repos.create_pool_on_load_balancer(
self.session, pool, listener_id=self.listener.id)
update_pool = {'protocol': constants.PROTOCOL_TCP, 'name': 'up_pool'}
@ -243,7 +243,7 @@ class AllRepositoriesTest(base.OctaviaDBTestBase):
'enabled': True, 'operating_status': constants.ONLINE,
'project_id': uuidutils.generate_uuid(),
'id': uuidutils.generate_uuid(),
'provisioning_status': None}
'provisioning_status': constants.ACTIVE}
sp = {'type': constants.SESSION_PERSISTENCE_HTTP_COOKIE,
'cookie_name': 'cookie_monster',
'pool_id': pool['id']}
@ -278,6 +278,7 @@ class AllRepositoriesTest(base.OctaviaDBTestBase):
'description': 'desc1',
'lb_algorithm': constants.LB_ALGORITHM_ROUND_ROBIN,
'enabled': True, 'operating_status': constants.ONLINE,
'provisioning_status': constants.ACTIVE,
'project_id': uuidutils.generate_uuid(),
'id': uuidutils.generate_uuid()}
pool_dm = self.repos.create_pool_on_load_balancer(
@ -299,6 +300,7 @@ class AllRepositoriesTest(base.OctaviaDBTestBase):
'description': 'desc1',
'lb_algorithm': constants.LB_ALGORITHM_ROUND_ROBIN,
'enabled': True, 'operating_status': constants.ONLINE,
'provisioning_status': constants.ACTIVE,
'project_id': uuidutils.generate_uuid(),
'id': uuidutils.generate_uuid()}
pool_dm = self.repos.create_pool_on_load_balancer(
@ -314,6 +316,7 @@ class AllRepositoriesTest(base.OctaviaDBTestBase):
'description': 'desc1',
'lb_algorithm': constants.LB_ALGORITHM_ROUND_ROBIN,
'enabled': True, 'operating_status': constants.ONLINE,
'provisioning_status': constants.PENDING_CREATE,
'project_id': uuidutils.generate_uuid(),
'id': uuidutils.generate_uuid()}
sp = {'type': constants.SESSION_PERSISTENCE_HTTP_COOKIE,
@ -333,6 +336,7 @@ class AllRepositoriesTest(base.OctaviaDBTestBase):
member = {'project_id': project_id, 'ip_address': '11.0.0.1',
'protocol_port': 80, 'enabled': True,
'operating_status': constants.ONLINE,
'provisioning_status': constants.PENDING_CREATE,
'id': uuidutils.generate_uuid()}
health_monitor = {'type': constants.HEALTH_MONITOR_HTTP, 'delay': 1,
'timeout': 1, 'fall_threshold': 1,
@ -343,6 +347,7 @@ class AllRepositoriesTest(base.OctaviaDBTestBase):
'description': 'desc1', 'listener_id': None,
'lb_algorithm': constants.LB_ALGORITHM_ROUND_ROBIN,
'enabled': True, 'operating_status': constants.ONLINE,
'provisioning_status': constants.PENDING_CREATE,
'project_id': project_id, 'members': [member],
'health_monitor': health_monitor, 'session_persistence': sp,
'id': uuidutils.generate_uuid()}
@ -351,7 +356,10 @@ class AllRepositoriesTest(base.OctaviaDBTestBase):
health_monitor['pool_id'] = pool.get('id')
l7rule = {'type': constants.L7RULE_TYPE_HOST_NAME,
'compare_type': constants.L7RULE_COMPARE_TYPE_EQUAL_TO,
'value': 'localhost'}
'operating_status': constants.ONLINE,
'provisioning_status': constants.PENDING_CREATE,
'value': 'localhost',
'enabled': True}
r_health_monitor = {'type': constants.HEALTH_MONITOR_HTTP, 'delay': 1,
'timeout': 1, 'fall_threshold': 1,
'rise_threshold': 1, 'enabled': True}
@ -359,6 +367,7 @@ class AllRepositoriesTest(base.OctaviaDBTestBase):
'description': 'desc1', 'project_id': project_id,
'lb_algorithm': constants.LB_ALGORITHM_ROUND_ROBIN,
'enabled': True, 'operating_status': constants.ONLINE,
'provisioning_status': constants.PENDING_CREATE,
'id': uuidutils.generate_uuid(),
'health_monitor': r_health_monitor}
l7policy = {'name': 'l7policy1', 'enabled': True,
@ -1814,6 +1823,7 @@ class PoolRepositoryTest(BaseRepositoryTest):
self.session, id=pool_id, project_id=project_id, name="pool_test",
description="pool_description", protocol=constants.PROTOCOL_HTTP,
lb_algorithm=constants.LB_ALGORITHM_ROUND_ROBIN,
provisioning_status=constants.ACTIVE,
operating_status=constants.ONLINE, enabled=True)
return pool
@ -1869,6 +1879,7 @@ class PoolRepositoryTest(BaseRepositoryTest):
pool_id=pool.id,
ip_address="10.0.0.1",
protocol_port=80, enabled=True,
provisioning_status=constants.ACTIVE,
operating_status=constants.ONLINE)
new_pool = self.pool_repo.get(self.session, id=pool.id)
self.assertEqual(1, len(new_pool.members))
@ -1917,6 +1928,7 @@ class PoolRepositoryTest(BaseRepositoryTest):
pool_id=pool.id,
ip_address="10.0.0.1",
protocol_port=80,
provisioning_status=constants.ACTIVE,
operating_status=constants.ONLINE,
enabled=True)
sp = self.sp_repo.create(
@ -1946,6 +1958,7 @@ class MemberRepositoryTest(BaseRepositoryTest):
name="pool_test", description="pool_description",
protocol=constants.PROTOCOL_HTTP,
lb_algorithm=constants.LB_ALGORITHM_ROUND_ROBIN,
provisioning_status=constants.ACTIVE,
operating_status=constants.ONLINE, enabled=True)
def create_member(self, member_id, project_id, pool_id, ip_address):
@ -1955,6 +1968,7 @@ class MemberRepositoryTest(BaseRepositoryTest):
ip_address=ip_address,
protocol_port=80,
operating_status=constants.ONLINE,
provisioning_status=constants.ACTIVE,
enabled=True)
return member
@ -2017,6 +2031,7 @@ class SessionPersistenceRepositoryTest(BaseRepositoryTest):
name="pool_test", description="pool_description",
protocol=constants.PROTOCOL_HTTP,
lb_algorithm=constants.LB_ALGORITHM_ROUND_ROBIN,
provisioning_status=constants.ACTIVE,
operating_status=constants.ONLINE, enabled=True)
def create_session_persistence(self, pool_id):
@ -2169,6 +2184,7 @@ class TestListenerRepositoryTest(BaseRepositoryTest):
name="pool_test", description="pool_description",
protocol=constants.PROTOCOL_HTTP,
lb_algorithm=constants.LB_ALGORITHM_ROUND_ROBIN,
provisioning_status=constants.ACTIVE,
operating_status=constants.ONLINE, enabled=True,
load_balancer_id=load_balancer2.id)
self.assertRaises(exceptions.NotFound, self.create_listener,
@ -2237,6 +2253,7 @@ class TestListenerRepositoryTest(BaseRepositoryTest):
name="pool_test", description="pool_description",
protocol=constants.PROTOCOL_HTTP,
lb_algorithm=constants.LB_ALGORITHM_ROUND_ROBIN,
provisioning_status=constants.ACTIVE,
operating_status=constants.ONLINE, enabled=True,
load_balancer_id=self.load_balancer.id)
listener = self.create_listener(self.FAKE_UUID_1, 80,
@ -2255,6 +2272,7 @@ class TestListenerRepositoryTest(BaseRepositoryTest):
name="pool_test", description="pool_description",
protocol=constants.PROTOCOL_HTTP,
lb_algorithm=constants.LB_ALGORITHM_ROUND_ROBIN,
provisioning_status=constants.ACTIVE,
operating_status=constants.ONLINE, enabled=True,
load_balancer_id=self.load_balancer.id)
listener = self.create_listener(self.FAKE_UUID_1, 80,
@ -2288,6 +2306,7 @@ class TestListenerRepositoryTest(BaseRepositoryTest):
name="pool_test", description="pool_description",
protocol=constants.PROTOCOL_HTTP,
lb_algorithm=constants.LB_ALGORITHM_ROUND_ROBIN,
provisioning_status=constants.ACTIVE,
operating_status=constants.ONLINE, enabled=True,
load_balancer_id=self.load_balancer.id)
listener = self.create_listener(self.FAKE_UUID_1, 80,
@ -2431,6 +2450,7 @@ class HealthMonitorRepositoryTest(BaseRepositoryTest):
name="pool_test", description="pool_description",
protocol=constants.PROTOCOL_HTTP,
lb_algorithm=constants.LB_ALGORITHM_ROUND_ROBIN,
provisioning_status=constants.ACTIVE,
operating_status=constants.ONLINE, enabled=True)
def create_health_monitor(self, pool_id):
@ -3142,6 +3162,7 @@ class L7PolicyRepositoryTest(BaseRepositoryTest):
name="pool_test", description="pool_description",
protocol=constants.PROTOCOL_HTTP,
lb_algorithm=constants.LB_ALGORITHM_ROUND_ROBIN,
provisioning_status=constants.ACTIVE,
operating_status=constants.ONLINE, enabled=True)
return pool
@ -3160,10 +3181,12 @@ class L7PolicyRepositoryTest(BaseRepositoryTest):
def create_l7rule(self, l7rule_id, l7policy_id,
type=constants.L7RULE_TYPE_PATH,
compare_type=constants.L7RULE_COMPARE_TYPE_STARTS_WITH,
key=None, value="/api"):
key=None, value="/api", enabled=True):
l7rule = self.l7rule_repo.create(
self.session, id=l7rule_id, l7policy_id=l7policy_id,
type=type, compare_type=compare_type, key=key, value=value)
type=type, compare_type=compare_type, key=key, value=value,
operating_status=constants.ONLINE, enabled=enabled,
provisioning_status=constants.ACTIVE)
return l7rule
def test_get(self):
@ -3366,7 +3389,7 @@ class L7PolicyRepositoryTest(BaseRepositoryTest):
pool = self.create_pool(uuidutils.generate_uuid())
l7policy = self.create_l7policy(uuidutils.generate_uuid(),
listener.id, 1,
redirect_pool_id=pool.id)
redirect_pool_id=pool.id,)
l7rule = self.create_l7rule(uuidutils.generate_uuid(), l7policy.id)
new_l7policy = self.l7policy_repo.get(self.session, id=l7policy.id)
new_l7rule = self.l7rule_repo.get(self.session, id=l7rule.id)
@ -3504,6 +3527,7 @@ class L7PolicyRepositoryTest(BaseRepositoryTest):
project_id=bad_lb.project_id,
protocol=constants.PROTOCOL_HTTP,
lb_algorithm=constants.LB_ALGORITHM_ROUND_ROBIN,
provisioning_status=constants.ACTIVE,
operating_status=constants.ONLINE, enabled=True)
self.assertRaises(exceptions.NotFound, self.create_l7policy,
uuidutils.generate_uuid(), self.listener.id, 1,
@ -3537,11 +3561,12 @@ class L7RuleRepositoryTest(BaseRepositoryTest):
def create_l7rule(self, l7rule_id, l7policy_id,
type=constants.L7RULE_TYPE_PATH,
compare_type=constants.L7RULE_COMPARE_TYPE_STARTS_WITH,
key=None, value="/api", invert=False):
key=None, value="/api", invert=False, enabled=True):
l7rule = self.l7rule_repo.create(
self.session, id=l7rule_id, l7policy_id=l7policy_id,
type=type, compare_type=compare_type, key=key, value=value,
invert=invert)
invert=invert, provisioning_status=constants.ACTIVE,
operating_status=constants.ONLINE, enabled=enabled)
return l7rule
def test_get(self):
@ -3589,7 +3614,10 @@ class L7RuleRepositoryTest(BaseRepositoryTest):
self.session, id=None, l7policy_id=self.l7policy.id,
type=constants.L7RULE_TYPE_PATH,
compare_type=constants.L7RULE_COMPARE_TYPE_CONTAINS,
value='something')
provisioning_status=constants.ACTIVE,
operating_status=constants.ONLINE,
value='something',
enabled=True)
new_l7rule = self.l7rule_repo.get(self.session, id=l7rule.id)
self.assertIsNotNone(l7rule.id)
self.assertEqual(self.l7policy.id, new_l7rule.l7policy_id)

View File

@ -0,0 +1,109 @@
# Copyright 2016 Blue Box, an IBM Company
#
# 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.
from wsme import exc
from wsme.rest import json as wsme_json
from wsme import types as wsme_types
from octavia.api.v1.types import l7rule as l7rule_type
from octavia.common import constants
from octavia.tests.unit.api.common import base
class TestL7RulePOST(base.BaseTypesTest):
_type = l7rule_type.L7RulePOST
def test_l7rule(self):
body = {"type": constants.L7RULE_TYPE_PATH,
"compare_type": constants.L7RULE_COMPARE_TYPE_STARTS_WITH,
"value": "/api"}
l7rule = wsme_json.fromjson(self._type, body)
self.assertEqual(wsme_types.Unset, l7rule.key)
self.assertFalse(l7rule.invert)
def test_type_mandatory(self):
body = {"compare_type": constants.L7RULE_COMPARE_TYPE_STARTS_WITH,
"value": "/api"}
self.assertRaises(exc.InvalidInput, wsme_json.fromjson, self._type,
body)
def test_compare_type_mandatory(self):
body = {"type": constants.L7RULE_TYPE_PATH,
"value": "/api"}
self.assertRaises(exc.InvalidInput, wsme_json.fromjson, self._type,
body)
def test_value_mandatory(self):
body = {"type": constants.L7RULE_TYPE_PATH,
"compare_type": constants.L7RULE_COMPARE_TYPE_STARTS_WITH}
self.assertRaises(exc.InvalidInput, wsme_json.fromjson, self._type,
body)
def test_invalid_type(self):
body = {"type": "notvalid",
"compare_type": constants.L7RULE_COMPARE_TYPE_STARTS_WITH,
"value": "/api"}
self.assertRaises(exc.InvalidInput, wsme_json.fromjson, self._type,
body)
def test_invalid_compare_type(self):
body = {"type": constants.L7RULE_TYPE_PATH,
"compare_type": "notvalid",
"value": "/api"}
self.assertRaises(exc.InvalidInput, wsme_json.fromjson, self._type,
body)
def test_invalid_invert(self):
body = {"type": constants.L7RULE_TYPE_PATH,
"compare_type": constants.L7RULE_COMPARE_TYPE_STARTS_WITH,
"value": "/api",
"invert": "notvalid"}
self.assertRaises(ValueError, wsme_json.fromjson, self._type,
body)
class TestL7RulePUT(base.BaseTypesTest):
_type = l7rule_type.L7RulePUT
def test_l7rule(self):
body = {"type": constants.L7RULE_TYPE_PATH,
"compare_type": constants.L7RULE_COMPARE_TYPE_STARTS_WITH,
"value": "/api"}
l7rule = wsme_json.fromjson(self._type, body)
self.assertEqual(wsme_types.Unset, l7rule.key)
self.assertFalse(l7rule.invert)
def test_invalid_type(self):
body = {"type": "notvalid",
"compare_type": constants.L7RULE_COMPARE_TYPE_STARTS_WITH,
"value": "/api"}
self.assertRaises(exc.InvalidInput, wsme_json.fromjson, self._type,
body)
def test_invalid_compare_type(self):
body = {"type": constants.L7RULE_TYPE_PATH,
"compare_type": "notvalid",
"value": "/api"}
self.assertRaises(exc.InvalidInput, wsme_json.fromjson, self._type,
body)
def test_invalid_invert(self):
body = {"type": constants.L7RULE_TYPE_PATH,
"compare_type": constants.L7RULE_COMPARE_TYPE_STARTS_WITH,
"value": "/api",
"invert": "notvalid"}
self.assertRaises(ValueError, wsme_json.fromjson, self._type,
body)

View File

@ -438,6 +438,12 @@ class TestHaproxyCfg(base.TestCase):
ret = self.jinja_cfg._transform_l7policy(in_l7policy)
self.assertEqual(sample_configs.RET_L7POLICY_2, ret)
def test_transform_l7policy_disabled_rule(self):
in_l7policy = sample_configs.sample_l7policy_tuple(
'sample_l7policy_id_6', sample_policy=6)
ret = self.jinja_cfg._transform_l7policy(in_l7policy)
self.assertEqual(sample_configs.RET_L7POLICY_6, ret)
def test_escape_haproxy_config_string(self):
self.assertEqual(self.jinja_cfg._escape_haproxy_config_string(
'string_with_none'), 'string_with_none')

View File

@ -127,7 +127,8 @@ RET_L7RULE_1 = {
'compare_type': constants.L7RULE_COMPARE_TYPE_STARTS_WITH,
'key': None,
'value': '/api',
'invert': False}
'invert': False,
'enabled': True}
RET_L7RULE_2 = {
'id': 'sample_l7rule_id_2',
@ -135,7 +136,8 @@ RET_L7RULE_2 = {
'compare_type': constants.L7RULE_COMPARE_TYPE_CONTAINS,
'key': 'Some-header',
'value': 'This\\ string\\\\\\ with\\ stuff',
'invert': True}
'invert': True,
'enabled': True}
RET_L7RULE_3 = {
'id': 'sample_l7rule_id_3',
@ -143,7 +145,8 @@ RET_L7RULE_3 = {
'compare_type': constants.L7RULE_COMPARE_TYPE_REGEX,
'key': 'some-cookie',
'value': 'this.*|that',
'invert': False}
'invert': False,
'enabled': True}
RET_L7RULE_4 = {
'id': 'sample_l7rule_id_4',
@ -151,7 +154,8 @@ RET_L7RULE_4 = {
'compare_type': constants.L7RULE_COMPARE_TYPE_EQUAL_TO,
'key': None,
'value': 'jpg',
'invert': False}
'invert': False,
'enabled': True}
RET_L7RULE_5 = {
'id': 'sample_l7rule_id_5',
@ -159,7 +163,17 @@ RET_L7RULE_5 = {
'compare_type': constants.L7RULE_COMPARE_TYPE_ENDS_WITH,
'key': None,
'value': '.example.com',
'invert': False}
'invert': False,
'enabled': True}
RET_L7RULE_6 = {
'id': 'sample_l7rule_id_6',
'type': constants.L7RULE_TYPE_HOST_NAME,
'compare_type': constants.L7RULE_COMPARE_TYPE_ENDS_WITH,
'key': None,
'value': '.example.com',
'invert': False,
'enabled': False}
RET_L7POLICY_1 = {
'id': 'sample_l7policy_id_1',
@ -201,6 +215,14 @@ RET_L7POLICY_5 = {
'enabled': False,
'l7rules': [RET_L7RULE_5]}
RET_L7POLICY_6 = {
'id': 'sample_l7policy_id_6',
'action': constants.L7POLICY_ACTION_REJECT,
'redirect_pool': None,
'redirect_url': None,
'enabled': True,
'l7rules': []}
RET_LISTENER = {
'id': 'sample_listener_id_1',
'protocol_port': '80',
@ -228,7 +250,7 @@ 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_4, RET_L7POLICY_5, RET_L7POLICY_6],
'enabled': True,
'insert_headers': {}}
@ -404,7 +426,8 @@ def sample_listener_tuple(proto=None, monitor=True, persistence=True,
sample_l7policy_tuple('sample_l7policy_id_2', sample_policy=2),
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_5', sample_policy=5),
sample_l7policy_tuple('sample_l7policy_id_6', sample_policy=6)]
else:
pools = [
sample_pool_tuple(
@ -560,6 +583,7 @@ def sample_l7policy_tuple(id,
in_l7policy = collections.namedtuple('l7policy',
'id, action, redirect_pool, '
'redirect_url, l7rules, enabled')
l7rules = []
if sample_policy == 1:
action = constants.L7POLICY_ACTION_REDIRECT_TO_POOL
redirect_pool = sample_pool_tuple(sample_pool=2)
@ -575,11 +599,13 @@ def sample_l7policy_tuple(id,
sample_l7rule_tuple('sample_l7rule_id_5', sample_rule=5)]
elif sample_policy == 4:
action = constants.L7POLICY_ACTION_REJECT
l7rules = []
elif sample_policy == 5:
action = constants.L7POLICY_ACTION_REJECT
enabled = False
l7rules = [sample_l7rule_tuple('sample_l7rule_id_5', sample_rule=5)]
elif sample_policy == 6:
action = constants.L7POLICY_ACTION_REJECT
l7rules = [sample_l7rule_tuple('sample_l7rule_id_6', sample_rule=6)]
return in_l7policy(
id=id,
action=action,
@ -595,41 +621,54 @@ def sample_l7rule_tuple(id,
key=None,
value='/api',
invert=False,
enabled=True,
sample_rule=1):
in_l7rule = collections.namedtuple('l7rule',
'id, type, compare_type, '
'key, value, invert')
'key, value, invert, enabled')
if sample_rule == 2:
type = constants.L7RULE_TYPE_HEADER
compare_type = constants.L7RULE_COMPARE_TYPE_CONTAINS
key = 'Some-header'
value = 'This string\\ with stuff'
invert = True
enabled = True
if sample_rule == 3:
type = constants.L7RULE_TYPE_COOKIE
compare_type = constants.L7RULE_COMPARE_TYPE_REGEX
key = 'some-cookie'
value = 'this.*|that'
invert = False
enabled = True
if sample_rule == 4:
type = constants.L7RULE_TYPE_FILE_TYPE
compare_type = constants.L7RULE_COMPARE_TYPE_EQUAL_TO
key = None
value = 'jpg'
invert = False
enabled = True
if sample_rule == 5:
type = constants.L7RULE_TYPE_HOST_NAME
compare_type = constants.L7RULE_COMPARE_TYPE_ENDS_WITH
key = None
value = '.example.com'
invert = False
enabled = True
if sample_rule == 6:
type = constants.L7RULE_TYPE_HOST_NAME
compare_type = constants.L7RULE_COMPARE_TYPE_ENDS_WITH
key = None
value = '.example.com'
invert = False
enabled = False
return in_l7rule(
id=id,
type=type,
compare_type=compare_type,
key=key,
value=value,
invert=invert)
invert=invert,
enabled=enabled)
def sample_base_expected_config(frontend=None, backend=None, peers=None):

View File

@ -2027,7 +2027,8 @@ class TestDatabaseTasks(base.TestCase):
mock_l7rule_repo_update.assert_called_once_with(
'TEST',
L7RULE_ID,
provisioning_status=constants.ACTIVE)
provisioning_status=constants.ACTIVE,
operating_status=constants.ONLINE)
# Test the revert
mock_l7rule_repo_update.reset_mock()