Merge "Update manila plugin to support IPv6"

This commit is contained in:
Zuul 2018-01-25 02:10:27 +00:00 committed by Gerrit Code Review
commit a0a2220419
9 changed files with 252 additions and 10 deletions

View File

@ -319,6 +319,7 @@
- openstack-infra/devstack-gate
- openstack/manila
- openstack/manila-tempest-plugin
- openstack/neutron-dynamic-routing
- openstack/python-manilaclient
- openstack/tempest

View File

@ -78,6 +78,7 @@ RUN_MANILA_HOST_ASSISTED_MIGRATION_TESTS=${RUN_MANILA_HOST_ASSISTED_MIGRATION_TE
RUN_MANILA_DRIVER_ASSISTED_MIGRATION_TESTS=${RUN_MANILA_DRIVER_ASSISTED_MIGRATION_TESTS:-False}
RUN_MANILA_MOUNT_SNAPSHOT_TESTS=${RUN_MANILA_MOUNT_SNAPSHOT_TESTS:-False}
RUN_MANILA_MIGRATION_WITH_PRESERVE_SNAPSHOTS_TESTS=${RUN_MANILA_MIGRATION_WITH_PRESERVE_SNAPSHOTS_TESTS:-False}
RUN_MANILA_IPV6_TESTS=${RUN_MANILA_IPV6_TESTS:-False}
MANILA_CONF=${MANILA_CONF:-/etc/manila/manila.conf}
@ -316,18 +317,43 @@ export OS_USER_DOMAIN_NAME=$ADMIN_DOMAIN_NAME
source $BASE/new/manila/contrib/ci/common.sh
manila_wait_for_drivers_init $MANILA_CONF
# (aovchinnikov): extra rules are needed to allow instances talk to host.
sudo iptables -N manila-nfs
sudo iptables -I INPUT 1 -j manila-nfs
TCP_PORTS=(2049 111 32803 892 875 662)
UDP_PORTS=(111 32769 892 875 662)
for port in ${TCP_PORTS[*]}; do
sudo iptables -A manila-nfs -m tcp -p tcp --dport $port -j ACCEPT
done
for port in ${UDP_PORTS[*]}; do
sudo iptables -A manila-nfs -m udp -p udp --dport $port -j ACCEPT
for ipcmd in iptables ip6tables; do
# (aovchinnikov): extra rules are needed to allow instances talk to host.
sudo $ipcmd -N manila-nfs
sudo $ipcmd -I INPUT 1 -j manila-nfs
for port in ${TCP_PORTS[*]}; do
sudo $ipcmd -A manila-nfs -m tcp -p tcp --dport $port -j ACCEPT
done
for port in ${UDP_PORTS[*]}; do
sudo $ipcmd -A manila-nfs -m udp -p udp --dport $port -j ACCEPT
done
done
source $BASE/new/devstack/openrc admin admin
public_net_id=$(openstack network list --name $PUBLIC_NETWORK_NAME -f value -c ID )
iniset $TEMPEST_CONFIG network public_network_id $public_net_id
# Now that all plugins are loaded, setup BGP here
if [ $(trueorfalse False MANILA_SETUP_IPV6) == True ]; then
neutron bgp-speaker-create --ip-version 6 --local-as 100 bgpspeaker
neutron bgp-speaker-network-add bgpspeaker $PUBLIC_NETWORK_NAME
neutron bgp-peer-create --peer-ip ::1 --remote-as 200 bgppeer
neutron bgp-speaker-peer-add bgpspeaker bgppeer
fi
# Set config to run IPv6 tests according to env var
iniset $TEMPEST_CONFIG share run_ipv6_tests $RUN_MANILA_IPV6_TESTS
if ! [[ -z "$OVERRIDE_IP_FOR_NFS_ACCESS" ]]; then
# Set config to use specified IP as access rule on NFS scenario tests
# in order to workaround multiple NATs between the VMs and the storage
# controller
iniset $TEMPEST_CONFIG share override_ip_for_nfs_access $OVERRIDE_IP_FOR_NFS_ACCESS
fi
echo "Running tempest manila test suites"
sudo -H -u $USER tox -eall -- $MANILA_TESTS --concurrency=$MANILA_TEMPEST_CONCURRENCY
RETVAL=$?

View File

@ -174,6 +174,16 @@ echo "TEMPEST_USE_TEST_ACCOUNTS=True" >> $localconf
echo "TEMPEST_ALLOW_TENANT_ISOLATION=False" >> $localconf
echo "TEMPEST_CONCURRENCY=${MANILA_TEMPEST_CONCURRENCY:-8}" >> $localconf
MANILA_SETUP_IPV6=${MANILA_SETUP_IPV6:-False}
echo "MANILA_SETUP_IPV6=${MANILA_SETUP_IPV6}" >> $localconf
if [[ "$MANILA_SETUP_IPV6" == True ]]; then
# When setting up proper IPv6 networks, we should do it ourselves so we can
# use Neutron Dynamic Routing plugin with address scopes instead of the
# regular Neutron DevStack configuration.
echo "NEUTRON_CREATE_INITIAL_NETWORKS=False" >> $localconf
echo "IP_VERSION=4+6" >> $localconf
fi
if [[ "$DRIVER" == "generic"* ]]; then
echo -e '[[post-config|${NOVA_CONF:-/etc/nova/nova.conf}]]\n[DEFAULT]\nquota_instances=30\n' >> $localconf
echo -e '[[post-config|${NEUTRON_CONF:-/etc/neutron/neutron.conf}]]\n[DEFAULT]\nmax_fixed_ips_per_port=100\n' >> $localconf

View File

@ -1,3 +1,5 @@
#!/bin/bash
# Plugin file for enabling manila services
# ----------------------------------------
@ -938,6 +940,115 @@ function install_libraries {
fi
}
function setup_ipv6 {
# save IPv6 default route to add back later after enabling forwarding
local default_route=$(ip -6 route | grep default | cut -d ' ' -f1,2,3,4,5)
# make sure those system values are set
sudo sysctl -w net.ipv6.conf.lo.disable_ipv6=0
sudo sysctl -w net.ipv6.conf.all.accept_ra=2
sudo sysctl -w net.ipv6.conf.all.forwarding=1
# Disable in-band as our communication is only internal
sudo ovs-vsctl set Bridge $PUBLIC_BRIDGE other_config:disable-in-band=true
# Create address scopes and subnet pools
neutron address-scope-create --shared scope-v4 4
neutron address-scope-create --shared scope-v6 6
openstack subnet pool create $SUBNETPOOL_NAME_V4 --default-prefix-length $SUBNETPOOL_SIZE_V4 --pool-prefix $SUBNETPOOL_PREFIX_V4 --address-scope scope-v4 --default --share
openstack subnet pool create $SUBNETPOOL_NAME_V6 --default-prefix-length $SUBNETPOOL_SIZE_V6 --pool-prefix $SUBNETPOOL_PREFIX_V6 --address-scope scope-v6 --default --share
# Create example private network and router
openstack router create $Q_ROUTER_NAME
openstack network create $PRIVATE_NETWORK_NAME
openstack subnet create --ip-version 6 --use-default-subnet-pool --ipv6-address-mode $IPV6_ADDRESS_MODE --ipv6-ra-mode $IPV6_RA_MODE --network $PRIVATE_NETWORK_NAME $IPV6_PRIVATE_SUBNET_NAME
openstack subnet create --ip-version 4 --use-default-subnet-pool --network $PRIVATE_NETWORK_NAME $PRIVATE_SUBNET_NAME
openstack router add subnet $Q_ROUTER_NAME $IPV6_PRIVATE_SUBNET_NAME
openstack router add subnet $Q_ROUTER_NAME $PRIVATE_SUBNET_NAME
# Create public network
openstack network create $PUBLIC_NETWORK_NAME --external --default --provider-network-type flat --provider-physical-network $PUBLIC_PHYSICAL_NETWORK
local public_gateway_ipv6=$(openstack subnet create $IPV6_PUBLIC_SUBNET_NAME --ip-version 6 --network $PUBLIC_NETWORK_NAME --subnet-pool $SUBNETPOOL_NAME_V6 --no-dhcp -c gateway_ip -f value)
local public_gateway_ipv4=$(openstack subnet create $PUBLIC_SUBNET_NAME --ip-version 4 --network $PUBLIC_NETWORK_NAME --subnet-range $FLOATING_RANGE --no-dhcp -c gateway_ip -f value)
# Set router to use public network
openstack router set --external-gateway $PUBLIC_NETWORK_NAME $Q_ROUTER_NAME
# Configure interfaces due to NEUTRON_CREATE_INITIAL_NETWORKS=False
local ipv4_cidr_len=${FLOATING_RANGE#*/}
sudo ip -6 addr add "$public_gateway_ipv6"/$SUBNETPOOL_SIZE_V6 dev $PUBLIC_BRIDGE
sudo ip addr add $PUBLIC_NETWORK_GATEWAY/"$ipv4_cidr_len" dev $PUBLIC_BRIDGE
# Enabling interface is needed due to NEUTRON_CREATE_INITIAL_NETWORKS=False
sudo ip link set $PUBLIC_BRIDGE up
if [ "$SHARE_DRIVER" == "manila.share.drivers.lvm.LVMShareDriver" ]; then
for backend_name in ${MANILA_ENABLED_BACKENDS//,/ }; do
iniset $MANILA_CONF $backend_name lvm_share_export_ips $public_gateway_ipv4,$public_gateway_ipv6
done
iniset $MANILA_CONF DEFAULT data_node_access_ip $public_gateway_ipv4
fi
# install Quagga for setting up the host routes dynamically
install_package quagga
# set Quagga daemons
(
echo "zebra=yes"
echo "bgpd=yes"
echo "ospfd=no"
echo "ospf6d=no"
echo "ripd=no"
echo "ripngd=no"
echo "isisd=no"
echo "babeld=no"
) | sudo tee /etc/quagga/daemons > /dev/null
# set Quagga zebra.conf
(
echo "hostname dsvm"
echo "password openstack"
echo "log file /var/log/quagga/zebra.log"
) | sudo tee /etc/quagga/zebra.conf > /dev/null
# set Quagga bgpd.conf
(
echo "log file /var/log/quagga/bgpd.log"
echo "bgp multiple-instance"
echo "router bgp 200"
echo " bgp router-id 1.2.3.4"
echo " neighbor ::1 remote-as 100"
echo " neighbor ::1 passive"
echo " address-family ipv6"
echo " neighbor ::1 activate"
echo "line vty"
echo "debug bgp events"
echo "debug bgp filters"
echo "debug bgp fsm"
echo "debug bgp keepalives"
echo "debug bgp updates"
) | sudo tee /etc/quagga/bgpd.conf > /dev/null
if is_ubuntu; then
sudo systemctl enable quagga
sudo systemctl restart quagga
else
# Disable SELinux rule that conflicts with Zebra
sudo setsebool -P zebra_write_config 1
sudo systemctl enable zebra
sudo systemctl enable bgpd
sudo systemctl restart zebra
sudo systemctl restart bgpd
fi
# add default IPv6 route back
if ! [[ -z $default_route ]]; then
sudo ip -6 route add $default_route
fi
}
# Main dispatcher
if [[ "$1" == "stack" && "$2" == "install" ]]; then
echo_summary "Installing Manila Client"
@ -991,6 +1102,11 @@ elif [[ "$1" == "stack" && "$2" == "extra" ]]; then
echo_summary "Configure Samba server"
configure_samba
echo_summary "Configuring IPv6"
if [ $(trueorfalse False MANILA_SETUP_IPV6) == True ]; then
setup_ipv6
fi
echo_summary "Starting Manila API"
start_manila_api

View File

@ -199,6 +199,9 @@ else
TEMPEST_PLUGINS=$MANILA_TEMPEST_PLUGIN_PATH
fi
# Manila IPv6 Setup flag
MANILA_SETUP_IPV6=${MANILA_SETUP_IPV6:=False}
# Enable manila services
# ----------------------
# We have to add Manila to enabled services for screen_it to work

View File

@ -27,6 +27,7 @@ from oslo_log import log
from manila import exception
from manila.i18n import _
from manila import network
from manila.share import utils as share_utils
from manila import utils
LOG = log.getLogger(__name__)
@ -627,8 +628,13 @@ class ShareDriver(object):
# NOTE(ganso): If drivers want to override the export_location IP,
# they can do so using this configuration. This method can also be
# overridden if necessary.
# NOTE(ganso): The data service needs to be improved to
# support IPv4 + IPv6. Until then we will support only IPv4.
path = next((x['path'] for x in share_instance['export_locations']
if x['is_admin_only']), None)
if (x['is_admin_only']) and
share_utils.is_proper_ipv4_export_location(
x['path'],
share_instance['share_proto'].lower())), None)
if not path:
path = share_instance['export_locations'][0]['path']
return path

View File

@ -152,3 +152,16 @@ def _usage_from_share(share_ref, share_instance_ref, **extra_usage_info):
def get_recent_db_migration_id():
return migration.version()
def is_proper_ipv4_export_location(export, protocol):
"""Verifies if the export location is in proper IPv4 format."""
export = export.replace('[', '').replace(']', '')
if protocol == 'nfs' and ':/' in export:
ip = export.split(':/')[0]
elif protocol == 'cifs' and export.startswith(r'\\'):
ip = export.split('\\')[2]
else:
# TODO(ganso): proper handling of other protocols is pending
ip = export.split(':')[0] if ':' in export else export.split('/')[0]
return utils.is_valid_ip_address(ip, 4)

View File

@ -16,6 +16,7 @@
"""Tests For miscellaneous util methods used with share."""
import ddt
import mock
from manila.common import constants
@ -23,6 +24,7 @@ from manila.share import utils as share_utils
from manila import test
@ddt.ddt
class ShareUtilsTestCase(test.TestCase):
def test_extract_host_without_pool(self):
host = 'Host@Backend'
@ -162,6 +164,69 @@ class ShareUtilsTestCase(test.TestCase):
replica = share_utils.get_active_replica(replica_list)
self.assertIsNone(replica)
@ddt.data({'exp': '172.24.5.1:/my_export_location', 'proto': 'nfs',
'expected': True},
{'exp': '\\\\172.24.5.1\\foo\\bar', 'proto': 'cifs',
'expected': True},
{'exp': 'fad0:88:133:/my_export_location', 'proto': 'nfs',
'expected': False},
{'exp': '\\\\fad0:88::133\\foo\\bar', 'proto': 'cifs',
'expected': False},
{'exp': 'fd01::1:/my_export_location', 'proto': 'nfs',
'expected': False},
{'exp': '\\\\[fd01::1]\\foo\\bar', 'proto': 'cifs',
'expected': False},
{'exp': '[fad0:88::133]:/my_export_location', 'proto': 'nfs',
'expected': False},
{'exp': '\\\\[fad0:88::133]\\foo\\bar', 'proto': 'cifs',
'expected': False},
{'exp': '[fd01::1]:/my_export_location', 'proto': 'nfs',
'expected': False},
{'exp': '\\\\fad0-88--133.ipv6-literal.net\\foo\\bar',
'proto': 'cifs', 'expected': False},
{'exp': '172.24.5.1:8080/my_export_location', 'proto': 'other',
'expected': True},
{'exp': '172.24.5.1:8080:/my_export_location', 'proto': 'other',
'expected': True},
{'exp': '172.24.5.1:/my_export_location', 'proto': 'other',
'expected': True},
{'exp': '172.24.5.1/my_export_location', 'proto': 'other',
'expected': True},
{'exp': '172.24.5.1/my_export_location', 'proto': 'nfs',
'expected': True},
{'exp': 'fd01::1:8080/my_export_location', 'proto': 'other',
'expected': False},
{'exp': 'fd01::1/my_export_location', 'proto': 'other',
'expected': False},
{'exp': 'fd01::1:8080:/my_export_location', 'proto': 'other',
'expected': False},
{'exp': 'fd01::1:/my_export_location', 'proto': 'other',
'expected': False},
{'exp': '555.555.555.555:/my_export_location', 'proto': 'other',
'expected': False},
{'exp': '555.555.555.555:/my_export_location', 'proto': 'nfs',
'expected': False},
{'exp': '555.555.555.555/my_export_location', 'proto': 'other',
'expected': False},
{'exp': '555.5.5.555:8080/my_export_location', 'proto': 'other',
'expected': False},
{'exp': '555.55.5.55:8080:/my_export_location', 'proto': 'other',
'expected': False},
{'exp': '[172.24.5.1]:/my_export_location', 'proto': 'nfs',
'expected': True},
{'exp': '172.24.5.1/my_export_location', 'proto': 'other',
'expected': True},
{'exp': '172.24.5.1\\foo\\bar', 'proto': 'cifs',
'expected': False},
{'exp': '\\172.24.5.1\\foo\\bar', 'proto': 'cifs',
'expected': False},
{'exp': '\\\\172.24.5.1\\foo\\bar', 'proto': 'other',
'expected': False})
@ddt.unpack
def test_is_proper_ipv4_export_location(self, exp, proto, expected):
result = share_utils.is_proper_ipv4_export_location(exp, proto)
self.assertEqual(expected, result)
class NotifyUsageTestCase(test.TestCase):
@mock.patch('manila.share.utils._usage_from_share')

View File

@ -39,6 +39,7 @@
[[local|localrc]]
SKIP_EPEL_INSTALL=True
enable_plugin manila git://git.openstack.org/openstack/manila
enable_plugin neutron-dynamic-routing git://git.openstack.org/openstack/neutron-dynamic-routing
EOF
executable: /bin/bash
@ -52,6 +53,7 @@
export PYTHONUNBUFFERED=true
export DEVSTACK_GATE_NEUTRON=1
export DEVSTACK_PROJECT_FROM_GIT="python-manilaclient"
# Basic services needed for minimal job
OVERRIDE_ENABLED_SERVICES=key,mysql,rabbit,tempest
if [ "lvm" == "lvm" ]; then
@ -71,7 +73,7 @@
# Keep localrc to be able to set some vars in pre_test_hook
export KEEP_LOCALRC=1
export PROJECTS="openstack/manila-tempest-plugin $PROJECTS"
export PROJECTS="openstack/manila-tempest-plugin openstack/neutron-dynamic-routing $PROJECTS"
function pre_test_hook {
# 'dhss' - acronym for 'Driver Handles Share Servers',