50afa71853
1.Upgrade pylint to 2.4.4, add exclusions to the tests, and fix some lint errors in the code 2. Fix user creation with GRANT in MySQL 8.0(Ubuntu Focal) In Ubuntu Bionic (18.04) mysql 5.7 version used to create the user implicitly when using using the GRANT. Ubuntu Focal (20.04) has mysql 8.0 and with mysql 8.0 there is no implicit user creation with GRANT. We need to create the user first before using GRANT command. See also commit I97b0dcbb88c6ef7c22e3c55970211bed792bbd0d 3. Remove fwaas from the zuul.yaml 4. Remove DB migration test which is failing ue to FWaaS migration with py38 5. Fix cover tests python version in .tox 6. fix requirememnts Change-Id: I22654a5d5ccaad3185ae3365a90afba1ce870695
166 lines
6.3 KiB
Python
166 lines
6.3 KiB
Python
# Copyright 2018 VMware, Inc.
|
|
#
|
|
# All Rights Reserved
|
|
#
|
|
# 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_config import cfg
|
|
from oslo_log import log as logging
|
|
|
|
from neutron_lib import constants as n_consts
|
|
from neutron_lib import exceptions as n_exc
|
|
from neutron_lib.plugins import directory
|
|
from neutron_lib.services.qos import constants as qos_consts
|
|
|
|
from vmware_nsx._i18n import _
|
|
from vmware_nsx.common import utils
|
|
|
|
LOG = logging.getLogger(__name__)
|
|
|
|
MAX_KBPS_MIN_VALUE = 1024
|
|
# The max limit is calculated so that the value sent to the backed will
|
|
# be smaller than 2**31
|
|
MAX_BURST_MAX_VALUE = int((2 ** 31 - 1) / 128)
|
|
|
|
|
|
class PolicyQosNotificationsHandler(object):
|
|
|
|
def __init__(self):
|
|
super(PolicyQosNotificationsHandler, self).__init__()
|
|
self._core_plugin = None
|
|
|
|
@property
|
|
def core_plugin(self):
|
|
if not self._core_plugin:
|
|
self._core_plugin = directory.get_plugin()
|
|
return self._core_plugin
|
|
|
|
@property
|
|
def _nsxpolicy(self):
|
|
return self.core_plugin.nsxpolicy
|
|
|
|
def _get_tags(self, context, policy):
|
|
policy_dict = {'id': policy.id, 'tenant_id': policy.tenant_id}
|
|
return self._nsxpolicy.build_v3_tags_payload(
|
|
policy_dict, resource_type='os-neutron-qos-id',
|
|
project_name=context.tenant_name)
|
|
|
|
def create_or_update_policy(self, context, policy):
|
|
policy_id = policy.id
|
|
tags = self._get_tags(context, policy)
|
|
pol_name = utils.get_name_and_uuid(policy.name or 'policy',
|
|
policy.id)
|
|
|
|
shapers = []
|
|
dscp = None
|
|
if (hasattr(policy, "rules")):
|
|
for rule in policy["rules"]:
|
|
if rule.rule_type == qos_consts.RULE_TYPE_BANDWIDTH_LIMIT:
|
|
# the NSX direction is opposite to the neutron one
|
|
is_ingress = rule.direction == n_consts.EGRESS_DIRECTION
|
|
shapers.append(self._get_shaper_from_rule(
|
|
rule, is_ingress=is_ingress))
|
|
elif rule.rule_type == qos_consts.RULE_TYPE_DSCP_MARKING:
|
|
dscp = self._get_dscp_from_rule(rule)
|
|
else:
|
|
LOG.warning("The NSX-Policy plugin does not support QoS "
|
|
"rule of type %s", rule.rule_type)
|
|
|
|
self._nsxpolicy.qos_profile.create_or_overwrite(
|
|
pol_name, profile_id=policy_id,
|
|
description=policy.get('description'),
|
|
dscp=dscp, shaper_configurations=shapers,
|
|
tags=tags)
|
|
|
|
def create_policy(self, context, policy):
|
|
return self.create_or_update_policy(context, policy)
|
|
|
|
def delete_policy(self, context, policy_id):
|
|
self._nsxpolicy.qos_profile.delete(policy_id)
|
|
|
|
def update_policy(self, context, policy_id, policy):
|
|
return self.create_or_update_policy(context, policy)
|
|
|
|
def _validate_bw_values(self, bw_rule):
|
|
"""Validate that the values are allowed by the NSX backend"""
|
|
# Validate the max bandwidth value minimum value
|
|
# (max value is above what neutron allows so no need to check it)
|
|
if (bw_rule.max_kbps < MAX_KBPS_MIN_VALUE):
|
|
msg = (_("Invalid input for max_kbps. "
|
|
"The minimal legal value is %s") % MAX_KBPS_MIN_VALUE)
|
|
LOG.error(msg)
|
|
raise n_exc.InvalidInput(error_message=msg)
|
|
|
|
# validate the burst size value max value
|
|
# (max value is 0, and neutron already validates this)
|
|
if (bw_rule.max_burst_kbps > MAX_BURST_MAX_VALUE):
|
|
msg = (_("Invalid input for burst_size. "
|
|
"The maximal legal value is %s") % MAX_BURST_MAX_VALUE)
|
|
LOG.error(msg)
|
|
raise n_exc.InvalidInput(error_message=msg)
|
|
|
|
def _get_shaper_from_rule(self, bw_rule, is_ingress=True):
|
|
"""Translate the neutron bandwidth_limit_rule values into the
|
|
NSX-lib Policy QoS shaper
|
|
"""
|
|
kwargs = {}
|
|
if is_ingress:
|
|
shaper = self._nsxpolicy.qos_profile.build_ingress_rate_limiter
|
|
else:
|
|
shaper = self._nsxpolicy.qos_profile.build_egress_rate_limiter
|
|
|
|
if bw_rule:
|
|
kwargs['enabled'] = True
|
|
|
|
# translate kbps -> bytes
|
|
kwargs['burst_size'] = int(bw_rule.max_burst_kbps) * 128
|
|
|
|
# value in kbps -> Mb/s
|
|
kwargs['average_bandwidth'] = int(
|
|
round(float(bw_rule.max_kbps) / 1024))
|
|
|
|
# peakBandwidth: a Multiplying on the average BW because the
|
|
# neutron qos configuration supports only 1 value
|
|
kwargs['peak_bandwidth'] = int(
|
|
round(kwargs['average_bandwidth'] *
|
|
cfg.CONF.NSX.qos_peak_bw_multiplier))
|
|
else:
|
|
kwargs['enabled'] = False
|
|
|
|
return shaper(**kwargs)
|
|
|
|
def _get_dscp_from_rule(self, dscp_rule):
|
|
"""Translate the neutron DSCP marking rule values into NSX-lib
|
|
Policy QoS Dscp object
|
|
"""
|
|
trusted = bool(not dscp_rule)
|
|
priority = dscp_rule.dscp_mark if dscp_rule else 0
|
|
return self._nsxpolicy.qos_profile.build_dscp(
|
|
trusted=trusted, priority=priority)
|
|
|
|
def update_policy_rules(self, context, policy_id, rules):
|
|
"""This handler will do all the updates through the create_or_update"""
|
|
pass
|
|
|
|
def validate_policy_rule(self, context, policy_id, rule):
|
|
"""Raise an exception if the rule values are not supported"""
|
|
if rule.rule_type == qos_consts.RULE_TYPE_BANDWIDTH_LIMIT:
|
|
self._validate_bw_values(rule)
|
|
elif rule.rule_type == qos_consts.RULE_TYPE_DSCP_MARKING:
|
|
pass
|
|
else:
|
|
msg = (_("The NSX-Policy plugin does not support QoS rule of type "
|
|
"%s") % rule.rule_type)
|
|
LOG.error(msg)
|
|
raise n_exc.InvalidInput(error_message=msg)
|