NSXv3: Fix L7 rule create/delete base on latest API

The platform side finalized the API for LbRule including
LbRuleAction, LbRuleCondition and LbRuleMatchType. Also it enforces
LB rule deletion that the rule cannot be deleted with if it is
still attached to a virtual server. This patch fix these based on
platform changes.

Change-Id: Id3709c480eb92a7d369851248f302267da0a64ef
This commit is contained in:
Tong Liu 2017-09-06 14:26:38 -07:00
parent 7455e59106
commit 2c55108ef4
4 changed files with 51 additions and 31 deletions

View File

@ -93,6 +93,8 @@ LB_STATS_MAP = {'active_connections': 'current_sessions',
LB_SELECT_POOL_ACTION = 'LbSelectPoolAction'
LB_HTTP_REDIRECT_ACTION = 'LbHttpRedirectAction'
LB_REJECT_ACTION = 'LbHttpRejectAction'
LB_HTTP_REDIRECT_STATUS = '301'
LB_HTTP_REJECT_STATUS = '501'
LR_ROUTER_TYPE = 'os-neutron-router-id'
LR_PORT_TYPE = 'os-neutron-rport-id'
DEFAULT_LB_SIZE = 'SMALL'

View File

@ -18,7 +18,9 @@ from oslo_log import helpers as log_helpers
from oslo_log import log as logging
from vmware_nsx._i18n import _
from vmware_nsx.db import db as nsx_db
from vmware_nsx.services.lbaas import base_mgr
from vmware_nsxlib.v3 import exceptions as nsxlib_exc
LOG = logging.getLogger(__name__)
@ -50,4 +52,30 @@ class EdgeL7PolicyManager(base_mgr.Nsxv3LoadbalancerBaseManager):
@log_helpers.log_method_call
def delete(self, context, policy):
self._l7policy_action(context, policy, 'delete', delete=True)
lb_id = policy.listener.loadbalancer_id
vs_client = self.core_plugin.nsxlib.load_balancer.virtual_server
rule_client = self.core_plugin.nsxlib.load_balancer.rule
for rule in policy.rules:
binding = nsx_db.get_nsx_lbaas_l7rule_binding(
context.session, lb_id, policy.id, rule.id)
if binding:
vs_id = binding['lb_vs_id']
rule_id = binding['lb_rule_id']
try:
# Update virtual server to remove lb rule
vs_client.remove_rule(vs_id, rule_id)
rule_client.delete(rule_id)
except nsxlib_exc.ResourceNotFound:
LOG.warning('LB rule %(rule)s is not found on NSX',
{'rule': rule_id})
except nsxlib_exc.ManagerError:
self.lbv2_driver.l7policy.failed_completion(
context, policy)
msg = (_('Failed to delete lb rule: %(rule)s') %
{'rule': rule.id})
raise n_exc.BadRequest(resource='lbaas-l7rule-delete',
msg=msg)
nsx_db.delete_nsx_lbaas_l7rule_binding(
context.session, lb_id, policy.id, rule.id)
self.lbv2_driver.l7policy.successful_completion(
context, policy, delete=True)

View File

@ -93,9 +93,11 @@ class EdgeL7RuleManager(base_mgr.Nsxv3LoadbalancerBaseManager):
msg=msg)
elif l7policy.action == lb_const.L7_POLICY_ACTION_REDIRECT_TO_URL:
actions = [{'type': lb_const.LB_HTTP_REDIRECT_ACTION,
'redirect_rul': l7policy.redirect_url}]
'redirect_status': lb_const.LB_HTTP_REDIRECT_STATUS,
'redirect_url': l7policy.redirect_url}]
elif l7policy.action == lb_const.L7_POLICY_ACTION_REJECT:
actions = [{'type': lb_const.LB_REJECT_ACTION}]
actions = [{'type': lb_const.LB_REJECT_ACTION,
'reply_status': lb_const.LB_HTTP_REJECT_STATUS}]
else:
msg = (_('Invalid l7policy action: %(action)s') %
{'action': l7policy.action})
@ -179,24 +181,7 @@ class EdgeL7RuleManager(base_mgr.Nsxv3LoadbalancerBaseManager):
vs_id = binding['lb_vs_id']
rule_id = binding['lb_rule_id']
try:
rule_client.delete(rule_id)
except nsx_exc.NsxResourceNotFound:
msg = (_("LB rule cannot be found on nsx: %(rule)s") %
{'rule': rule_id})
raise n_exc.BadRequest(resource='lbaas-l7rule-delete',
msg=msg)
except nsxlib_exc.ManagerError:
self.lbv2_driver.l7rule.failed_completion(context,
rule)
msg = (_('Failed to delete lb rule: %(rule)s') %
{'rule': rule.id})
raise n_exc.BadRequest(resource='lbaas-l7rule-delete',
msg=msg)
try:
lb_vs = vs_client.get(vs_id)
if 'rule_ids' in lb_vs and rule_id in lb_vs['rule_ids']:
lb_vs['rule_ids'].remove(rule_id)
vs_client.update(vs_id, lb_vs)
vs_client.remove_rule(vs_id, rule_id)
except nsx_exc.NsxResourceNotFound:
msg = (_("virtual server cannot be found on nsx: %(vs)s") %
{'vs': vs_id})
@ -209,9 +194,19 @@ class EdgeL7RuleManager(base_mgr.Nsxv3LoadbalancerBaseManager):
'%(vs)s') % {'rule': rule_id, 'vs': vs_id})
raise n_exc.BadRequest(resource='lbaas-l7rule-delete',
msg=msg)
try:
rule_client.delete(rule_id)
except nsx_exc.NsxResourceNotFound:
LOG.warning("LB rule cannot be found on nsx: %(rule)s",
{'rule': rule_id})
except nsxlib_exc.ManagerError:
self.lbv2_driver.l7rule.failed_completion(context,
rule)
msg = (_('Failed to delete lb rule: %(rule)s') %
{'rule': rule.id})
raise n_exc.BadRequest(resource='lbaas-l7rule-delete',
msg=msg)
nsx_db.delete_nsx_lbaas_l7rule_binding(
context.session, lb_id, rule.l7policy_id, rule.id)
self.lbv2_driver.l7rule.successful_completion(context, rule,
delete=True)

View File

@ -656,23 +656,18 @@ class TestEdgeLbaasV2L7Rule(BaseTestEdgeLbaasV2):
def test_delete_pool_without_members(self):
with mock.patch.object(nsx_db, 'get_nsx_lbaas_l7rule_binding',
) as mock_get_l7rule_binding, \
mock.patch.object(self.vs_client, 'remove_rule'
) as mock_remove_rule, \
mock.patch.object(self.rule_client, 'delete',
) as mock_delete_rule, \
mock.patch.object(self.vs_client, 'get',
) as mock_get_vs, \
mock.patch.object(self.vs_client, 'update',
) as mock_update_vs, \
mock.patch.object(nsx_db, 'delete_nsx_lbaas_l7rule_binding',
) as mock_delete_l7rule_binding:
mock_get_l7rule_binding.return_value = L7RULE_BINDING
mock_get_vs.return_value = {'id': LB_VS_ID,
'rule_ids': [LB_RULE_ID]}
self.edge_driver.l7rule.delete(self.context, self.l7rule)
mock_remove_rule.assert_called_with(LB_VS_ID, LB_RULE_ID)
mock_delete_rule.assert_called_with(LB_RULE_ID)
mock_update_vs.assert_called_with(LB_VS_ID, {'id': LB_VS_ID,
'rule_ids': []})
mock_delete_l7rule_binding.assert_called_with(
self.context.session, LB_ID, L7POLICY_ID, L7RULE_ID)