asarfaty 50afa71853 Fix broken Victoria branch
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
2020-09-21 15:31:18 +02:00

214 lines
9.2 KiB
Python

# Copyright 2019 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.
import sys
import netaddr
from oslo_log import log as logging
from neutron_lib.api.definitions import allowedaddresspairs as addr_apidef
from neutron_lib.api.definitions import provider_net as pnet
from neutron_lib.api import validators
from neutron_lib.callbacks import registry
from neutron_lib import constants as nl_constants
from neutron_lib import context as n_context
from vmware_nsx.common import nsxv_constants
from vmware_nsx.common import utils as c_utils
from vmware_nsx.services.lbaas.nsx_v3.implementation import lb_utils
from vmware_nsx.services.lbaas.octavia import constants as oct_const
from vmware_nsx.shell.admin.plugins.common import constants
from vmware_nsx.shell.admin.plugins.common import utils as admin_utils
from vmware_nsx.shell.admin.plugins.nsxv.resources import utils
from vmware_nsx.shell import resources as shell
from vmware_nsxlib.v3 import nsx_constants as nsxlib_consts
LOG = logging.getLogger(__name__)
@admin_utils.output_header
def validate_config_for_migration(resource, event, trigger, **kwargs):
"""Validate the nsxv configuration before migration to nsx-t"""
transit_networks = ["100.64.0.0/16"]
if kwargs.get('property'):
# input validation
properties = admin_utils.parse_multi_keyval_opt(kwargs['property'])
transit_network = properties.get('transit-network')
if transit_network:
transit_networks = [transit_network]
# Max number of allowed address pairs (allowing 3 for fixed ips)
num_allowed_addr_pairs = nsxlib_consts.NUM_ALLOWED_IP_ADDRESSES - 3
admin_context = n_context.get_admin_context()
n_errors = 0
with utils.NsxVPluginWrapper() as plugin:
# Ports validations:
ports = plugin.get_ports(admin_context)
for port in ports:
net_id = port['network_id']
# Too many address pairs in a port
address_pairs = port.get(addr_apidef.ADDRESS_PAIRS)
if len(address_pairs) > num_allowed_addr_pairs:
n_errors = n_errors + 1
LOG.error("%s allowed address pairs for port %s. Only %s are "
"allowed.",
len(address_pairs), port['id'],
num_allowed_addr_pairs)
# Compute port on external network
if (port.get('device_owner', '').startswith(
nl_constants.DEVICE_OWNER_COMPUTE_PREFIX) and
plugin._network_is_external(admin_context, net_id)):
n_errors = n_errors + 1
LOG.error("Compute port %s on external network %s is not "
"allowed.", port['id'], net_id)
# Networks & subnets validations:
networks = plugin.get_networks(admin_context)
for net in networks:
# skip internal networks
if net['project_id'] == nsxv_constants.INTERNAL_TENANT_ID:
continue
# VXLAN or portgroup provider networks
net_type = net.get(pnet.NETWORK_TYPE)
if (net_type == c_utils.NsxVNetworkTypes.VXLAN or
net_type == c_utils.NsxVNetworkTypes.PORTGROUP):
n_errors = n_errors + 1
LOG.error("Network %s of type %s is not supported.",
net['id'], net_type)
subnets = plugin._get_subnets_by_network(admin_context, net['id'])
n_dhcp_subnets = 0
# Multiple DHCP subnets per network
for subnet in subnets:
if subnet['enable_dhcp']:
n_dhcp_subnets = n_dhcp_subnets + 1
if n_dhcp_subnets > 1:
n_errors = n_errors + 1
LOG.error("Network %s has %s dhcp subnets. Only 1 is allowed.",
net['id'], n_dhcp_subnets)
# Subnets overlapping with the transit network
for subnet in subnets:
# get the subnet IPs
if ('allocation_pools' in subnet and
validators.is_attr_set(subnet['allocation_pools'])):
# use the pools instead of the cidr
subnet_networks = [
netaddr.IPRange(pool.get('start'), pool.get('end'))
for pool in subnet.get('allocation_pools')]
else:
cidr = subnet.get('cidr')
if not validators.is_attr_set(cidr):
return
subnet_networks = [netaddr.IPNetwork(subnet['cidr'])]
for subnet_net in subnet_networks:
if (netaddr.IPSet(subnet_net) &
netaddr.IPSet(transit_networks)):
n_errors = n_errors + 1
LOG.error("Subnet %s overlaps with the transit "
"network ips: %s.",
subnet['id'], transit_networks)
# Network attached to multiple routers
intf_ports = plugin._get_network_interface_ports(
admin_context, net['id'])
if len(intf_ports) > 1:
n_errors = n_errors + 1
LOG.error("Network %s has interfaces on multiple routers. "
"Only 1 is allowed.", net['id'])
# Routers validations:
routers = plugin.get_routers(admin_context)
for router in routers:
# Interface subnets overlap with the GW subnet
gw_subnets = plugin._find_router_gw_subnets(admin_context, router)
gw_cidrs = [subnet['cidr'] for subnet in gw_subnets]
gw_ip_set = netaddr.IPSet(gw_cidrs)
if_cidrs = plugin._find_router_subnets_cidrs(
admin_context, router['id'])
if_ip_set = netaddr.IPSet(if_cidrs)
if gw_ip_set & if_ip_set:
n_errors = n_errors + 1
LOG.error("Interface network of router %s cannot overlap with "
"router GW network", router['id'])
# TODO(asarfaty): missing validations:
# - Vlan provider network with the same VLAN tag as the uplink
# profile tag used in the relevant transport node
# (cannot check this without access to the T manager)
# Octavia loadbalancers validation:
filters = {'device_owner': [nl_constants.DEVICE_OWNER_LOADBALANCERV2,
oct_const.DEVICE_OWNER_OCTAVIA]}
lb_ports = plugin.get_ports(admin_context, filters=filters)
lb_routers = []
for port in lb_ports:
fixed_ips = port.get('fixed_ips', [])
if fixed_ips:
subnet_id = fixed_ips[0]['subnet_id']
network = lb_utils.get_network_from_subnet(
admin_context, plugin, subnet_id)
router_id = lb_utils.get_router_from_network(
admin_context, plugin, subnet_id)
# Loadbalancer vip subnet must be connected to a router or
# belong to an external network
if (not router_id and network and
not network.get('router:external')):
n_errors = n_errors + 1
LOG.error("Loadbalancer %s subnet %s is not external "
"nor connected to a router.",
port.get('device_id'), subnet_id)
# Multiple loadbalancers on the same router cannot be supported
if router_id in lb_routers:
n_errors = n_errors + 1
LOG.error("Router %s has multiple loadbalancers which is "
"not supported.", router_id)
else:
lb_routers.append(router_id)
# TODO(asarfaty): Multiple listeners on the same pool is not
# supported, but currently the admin utility has no access to this
# information from octavia
# TODO(asarfaty): Member on external subnet must have fip as ip,
# but currently the admin utility has no access to this information
# from octavia
# General validations:
# TODO(asarfaty): multiple transport zones (migrator limitation)?
if n_errors > 0:
plural = n_errors > 1
LOG.error("The NSX-V plugin configuration is not ready to be "
"migrated to NSX-T. %s error%s found.", n_errors,
's were' if plural else ' was')
sys.exit(n_errors)
LOG.info("The NSX-V plugin configuration is ready to be migrated to "
"NSX-T.")
registry.subscribe(validate_config_for_migration,
constants.NSX_MIGRATE_V_T,
shell.Operations.VALIDATE.value)