diff --git a/clean.sh b/clean.sh index 1176134da6..0641bffcf8 100755 --- a/clean.sh +++ b/clean.sh @@ -49,6 +49,7 @@ source $TOP_DIR/lib/nova source $TOP_DIR/lib/cinder source $TOP_DIR/lib/swift source $TOP_DIR/lib/heat +source $TOP_DIR/lib/neutron source $TOP_DIR/lib/neutron-legacy set -o xtrace diff --git a/exercises/boot_from_volume.sh b/exercises/boot_from_volume.sh index 54098594ff..84ac08f017 100755 --- a/exercises/boot_from_volume.sh +++ b/exercises/boot_from_volume.sh @@ -32,6 +32,7 @@ source $TOP_DIR/functions # Import project functions source $TOP_DIR/lib/cinder +source $TOP_DIR/lib/neutron source $TOP_DIR/lib/neutron-legacy # Import configuration diff --git a/exercises/floating_ips.sh b/exercises/floating_ips.sh index 4b72a0073f..485208ba30 100755 --- a/exercises/floating_ips.sh +++ b/exercises/floating_ips.sh @@ -31,6 +31,7 @@ source $TOP_DIR/functions source $TOP_DIR/openrc # Import project functions +source $TOP_DIR/lib/neutron source $TOP_DIR/lib/neutron-legacy # Import exercise configuration diff --git a/exercises/neutron-adv-test.sh b/exercises/neutron-adv-test.sh index a3128a8d71..81150061ca 100755 --- a/exercises/neutron-adv-test.sh +++ b/exercises/neutron-adv-test.sh @@ -37,6 +37,7 @@ source $TOP_DIR/functions source $TOP_DIR/openrc # Import neutron functions +source $TOP_DIR/lib/neutron source $TOP_DIR/lib/neutron-legacy # If neutron is not enabled we exit with exitcode 55, which means exercise is skipped. diff --git a/exercises/volumes.sh b/exercises/volumes.sh index f95c81fdf1..0de1226fee 100755 --- a/exercises/volumes.sh +++ b/exercises/volumes.sh @@ -32,6 +32,7 @@ source $TOP_DIR/openrc # Import project functions source $TOP_DIR/lib/cinder +source $TOP_DIR/lib/neutron source $TOP_DIR/lib/neutron-legacy # Import exercise configuration diff --git a/lib/neutron b/lib/neutron new file mode 100644 index 0000000000..51c3a006c7 --- /dev/null +++ b/lib/neutron @@ -0,0 +1,556 @@ +#!/bin/bash +# +# lib/neutron +# Install and start **Neutron** network services + +# Dependencies: +# +# ``functions`` file +# ``DEST`` must be defined + +# ``stack.sh`` calls the entry points in this order: +# +# - is_XXXX_enabled +# - install_XXXX +# - configure_XXXX +# - init_XXXX +# - start_XXXX +# - stop_XXXX +# - cleanup_XXXX + +# Save trace setting +XTRACE=$(set +o | grep xtrace) +set +o xtrace + +# Defaults +# -------- + +# Set up default directories +GITDIR["python-neutronclient"]=$DEST/python-neutronclient + +NEUTRON_AGENT=${NEUTRON_AGENT:-openvswitch} +NEUTRON_DIR=$DEST/neutron +NEUTRON_AUTH_CACHE_DIR=${NEUTRON_AUTH_CACHE_DIR:-/var/cache/neutron} + +NEUTRON_BIN_DIR=$(get_python_exec_prefix) +NEUTRON_DHCP_BINARY="neutron-dhcp-agent" + +NEUTRON_CONF_DIR=/etc/neutron +NEUTRON_CONF=$NEUTRON_CONF_DIR/neutron.conf +NEUTRON_META_CONF=$NEUTRON_CONF_DIR/metadata_agent.ini + +NEUTRON_DHCP_CONF=$NEUTRON_CONF_DIR/dhcp_agent.ini +NEUTRON_L3_CONF=$NEUTRON_CONF_DIR/l3_agent.ini +NEUTRON_AGENT_CONF=$NEUTRON_CONF_DIR/ + +NEUTRON_STATE_PATH=${NEUTRON_STATE_PATH:=$DATA_DIR/neutron} +NEUTRON_AUTH_CACHE_DIR=${NEUTRON_AUTH_CACHE_DIR:-/var/cache/neutron} + +# By default, use the ML2 plugin +NEUTRON_PLUGIN=${NEUTRON_PLUGIN:-ml2} +NEUTRON_PLUGIN_CONF_FILENAME=${NEUTRON_PLUGIN_CONF_FILENAME:-ml2_conf.ini} +NEUTRON_PLUGIN_CONF_PATH=$NEUTRON_CONF_DIR/plugins/$NEUTRON_PLUGIN +NEUTRON_PLUGIN_CONF=$NEUTRON_PLUGIN_CONF_PATH/$NEUTRON_PLUGIN_CONF_FILENAME + +NEUTRON_AGENT_BINARY=${NEUTRON_AGENT_BINARY:-neutron-$NEUTRON_AGENT-agent} +NEUTRON_L3_BINARY=${NEUTRON_L3_BINARY:-neutron-l3-agent} +NEUTRON_META_BINARY=${NEUTRON_META_BINARY:-neutron-metadata-agent} + +# Public facing bits +if is_ssl_enabled_service "neutron" || is_service_enabled tls-proxy; then + NEUTRON_SERVICE_PROTOCOL="https" +fi +NEUTRON_SERVICE_HOST=${NEUTRON_SERVICE_HOST:-$SERVICE_HOST} +NEUTRON_SERVICE_PORT=${NEUTRON_SERVICE_PORT:-9696} +NEUTRON_SERVICE_PORT_INT=${NEUTRON_SERVICE_PORT_INT:-19696} +NEUTRON_SERVICE_PROTOCOL=${NEUTRON_SERVICE_PROTOCOL:-$SERVICE_PROTOCOL} + +NEUTRON_AUTH_STRATEGY=${NEUTRON_AUTH_STRATEGY:-keystone} +NEUTRON_ROOTWRAP=$(get_rootwrap_location neutron) +NEUTRON_ROOTWRAP_CONF_FILE=$NEUTRON_CONF_DIR/rootwrap.conf +NEUTRON_ROOTWRAP_DAEMON_CMD="sudo $NEUTRON_ROOTWRAP-daemon $NEUTRON_ROOTWRAP_CONF_FILE" + +# Add all enabled config files to a single config arg +NEUTRON_CONFIG_ARG=${NEUTRON_CONFIG_ARG:-""} + +# Functions +# --------- + +# Test if any Neutron services are enabled +# is_neutron_enabled +function is_neutron_enabled { + [[ ,${ENABLED_SERVICES} =~ ,"neutron-" || ,${ENABLED_SERVICES} =~ ,"q-" ]] && return 0 + return 1 +} + +# Test if any Neutron services are enabled +# is_neutron_enabled +function is_neutron_legacy_enabled { + [[ ,${ENABLED_SERVICES} =~ ,"q-" ]] && return 0 + return 1 +} + +# cleanup_neutron() - Remove residual data files, anything left over from previous +# runs that a clean run would need to clean up +function cleanup_neutron_new { + source $TOP_DIR/lib/neutron_plugins/${NEUTRON_AGENT}_agent + if is_neutron_ovs_base_plugin; then + neutron_ovs_base_cleanup + fi + + if [[ $NEUTRON_AGENT == "linuxbridge" ]]; then + neutron_lb_cleanup + fi + # delete all namespaces created by neutron + for ns in $(sudo ip netns list | grep -o -E '(qdhcp|qrouter|qlbaas|fip|snat)-[0-9a-f-]*'); do + sudo ip netns delete ${ns} + done +} + +# configure_neutron() - Set config files, create data dirs, etc +function configure_neutron_new { + sudo install -d -o $STACK_USER $NEUTRON_CONF_DIR + + (cd $NEUTRON_DIR && exec ./tools/generate_config_file_samples.sh) + + cp $NEUTRON_DIR/etc/neutron.conf.sample $NEUTRON_CONF + + configure_neutron_rootwrap + + mkdir -p $NEUTRON_PLUGIN_CONF_PATH + + cp $NEUTRON_DIR/etc/neutron/plugins/$NEUTRON_PLUGIN/$NEUTRON_PLUGIN_CONF_FILENAME.sample $NEUTRON_PLUGIN_CONF + + iniset $NEUTRON_CONF database connection `database_connection_url neutron` + iniset $NEUTRON_CONF DEFAULT state_path $NEUTRON_STATE_PATH + iniset $NEUTRON_CONF oslo_concurrency lock_path $NEUTRON_STATE_PATH/lock + iniset $NEUTRON_CONF DEFAULT use_syslog $SYSLOG + + # Neutron API server & Neutron plugin + if is_service_enabled neutron-api; then + local policy_file=$NEUTRON_CONF_DIR/policy.json + cp $NEUTRON_DIR/etc/policy.json $policy_file + # Allow neutron user to administer neutron to match neutron account + sed -i 's/"context_is_admin": "role:admin"/"context_is_admin": "role:admin or user_name:neutron"/g' $policy_file + + cp $NEUTRON_DIR/etc/api-paste.ini $NEUTRON_CONF_DIR/api-paste.ini + + iniset $NEUTRON_CONF DEFAULT core_plugin ml2 + + iniset $NEUTRON_CONF DEFAULT verbose True + iniset $NEUTRON_CONF DEFAULT debug $ENABLE_DEBUG_LOG_LEVEL + iniset $NEUTRON_CONF DEFAULT policy_file $policy_file + iniset $NEUTRON_CONF DEFAULT allow_overlapping_ips True + + iniset $NEUTRON_CONF DEFAULT auth_strategy $NEUTRON_AUTH_STRATEGY + configure_auth_token_middleware $NEUTRON_CONF neutron $NEUTRON_AUTH_CACHE_DIR keystone_authtoken + + # Configuration for neutron notifations to nova. + iniset $NEUTRON_CONF DEFAULT notify_nova_on_port_status_changes $Q_NOTIFY_NOVA_PORT_STATUS_CHANGES + iniset $NEUTRON_CONF DEFAULT notify_nova_on_port_data_changes $Q_NOTIFY_NOVA_PORT_DATA_CHANGES + + iniset $NEUTRON_CONF nova auth_type password + iniset $NEUTRON_CONF nova auth_url "$KEYSTONE_SERVICE_PROTOCOL://$KEYSTONE_SERVICE_HOST:$KEYSTONE_AUTH_PORT/v3" + iniset $NEUTRON_CONF nova username nova + iniset $NEUTRON_CONF nova password $SERVICE_PASSWORD + iniset $NEUTRON_CONF nova user_domain_id default + iniset $NEUTRON_CONF nova project_name $SERVICE_TENANT_NAME + iniset $NEUTRON_CONF nova project_domain_id default + iniset $NEUTRON_CONF nova region_name $REGION_NAME + + # Configure VXLAN + # TODO(sc68cal) not hardcode? + iniset $NEUTRON_PLUGIN_CONF ml2 tenant_network_types vxlan + iniset $NEUTRON_PLUGIN_CONF ml2 type_drivers vxlan + iniset $NEUTRON_PLUGIN_CONF ml2 mechanism_drivers openvswitch,linuxbridge + iniset $NEUTRON_PLUGIN_CONF ml2_type_vxlan vni_ranges 1001:2000 + fi + + # Neutron OVS or LB agent + if is_service_enabled neutron-agent; then + iniset $NEUTRON_PLUGIN_CONF agent tunnel_types vxlan + + # Configure the neutron agent + if [[ $NEUTRON_AGENT == "linuxbridge" ]]; then + iniset $NEUTRON_PLUGIN_CONF securitygroup iptables + iniset $NEUTRON_PLUGIN_CONF vxlan local_ip $HOST_IP + else + iniset $NEUTRON_PLUGIN_CONF securitygroup iptables_hybrid + iniset $NEUTRON_PLUGIN_CONF ovs local_ip $HOST_IP + fi + fi + + # DHCP Agent + if is_service_enabled neutron-dhcp; then + cp $NEUTRON_DIR/etc/dhcp_agent.ini.sample $NEUTRON_DHCP_CONF + + iniset $NEUTRON_DHCP_CONF DEFAULT verbose True + iniset $NEUTRON_DHCP_CONF DEFAULT debug True + iniset $NEUTRON_DHCP_CONF agent root_helper_daemon "$NEUTRON_ROOTWRAP_DAEMON_CMD" + iniset $NEUTRON_DHCP_CONF DEFAULT interface_driver $NEUTRON_AGENT + neutron_plugin_configure_dhcp_agent $NEUTRON_DHCP_CONF + fi + + if is_service_enabled neutron-l3; then + cp $NEUTRON_DIR/etc/l3_agent.ini.sample $NEUTRON_L3_CONF + iniset $NEUTRON_L3_CONF DEFAULT interface_driver $NEUTRON_AGENT + iniset $NEUTRON_CONF DEFAULT service_plugins router + iniset $NEUTRON_L3_CONF agent root_helper_daemon "$NEUTRON_ROOTWRAP_DAEMON_CMD" + iniset $NEUTRON_L3_CONF DEFAULT debug True + iniset $NEUTRON_L3_CONF DEFAULT verbose True + neutron_plugin_configure_l3_agent $NEUTRON_L3_CONF + fi + + # Metadata + if is_service_enabled neutron-meta; then + cp $NEUTRON_DIR/etc/metadata_agent.ini.sample $NEUTRON_META_CONF + + iniset $NEUTRON_META_CONF DEFAULT verbose True + iniset $NEUTRON_META_CONF DEFAULT debug $ENABLE_DEBUG_LOG_LEVEL + iniset $NEUTRON_META_CONF DEFAULT nova_metadata_ip $SERVICE_HOST + iniset $NEUTRON_META_CONF agent root_helper_daemon "$NEUTRON_ROOTWRAP_DAEMON_CMD" + + # TODO(dtroyer): remove the v2.0 hard code below + iniset $NEUTRON_META_CONF DEFAULT auth_url $KEYSTONE_SERVICE_URI/v2.0 + configure_auth_token_middleware $NEUTRON_META_CONF neutron $NEUTRON_AUTH_CACHE_DIR DEFAULT + fi + + # Format logging + if [ "$LOG_COLOR" == "True" ] && [ "$SYSLOG" == "False" ]; then + setup_colorized_logging $NEUTRON_CONF DEFAULT project_id + else + # Show user_name and project_name by default + iniset $NEUTRON_CONF DEFAULT logging_context_format_string "%(asctime)s.%(msecs)03d %(levelname)s %(name)s [%(request_id)s %(user_name)s %(project_name)s] %(instance)s%(message)s" + fi + + if is_service_enabled tls-proxy; then + # Set the service port for a proxy to take the original + iniset $NEUTRON_CONF DEFAULT bind_port "$NEUTRON_SERVICE_PORT_INT" + fi + + if is_ssl_enabled_service "nova"; then + iniset $NEUTRON_CONF nova cafile $SSL_BUNDLE_FILE + fi + + if is_ssl_enabled_service "neutron"; then + ensure_certificates NEUTRON + + iniset $NEUTRON_CONF DEFAULT use_ssl True + iniset $NEUTRON_CONF DEFAULT ssl_cert_file "$NEUTRON_SSL_CERT" + iniset $NEUTRON_CONF DEFAULT ssl_key_file "$NEUTRON_SSL_KEY" + fi + +} + +# configure_neutron_rootwrap() - configure Neutron's rootwrap +function configure_neutron_rootwrap { + # Set the paths of certain binaries + neutron_rootwrap=$(get_rootwrap_location neutron) + + # Specify ``rootwrap.conf`` as first parameter to neutron-rootwrap + local rootwrap_sudoer_cmd="${neutron_rootwrap} $NEUTRON_CONF_DIR/rootwrap.conf" + + # Deploy new rootwrap filters files (owned by root). + # Wipe any existing rootwrap.d files first + if [[ -d $NEUTRON_CONF_DIR/rootwrap.d ]]; then + sudo rm -rf $NEUTRON_CONF_DIR/rootwrap.d + fi + + # Deploy filters to /etc/neutron/rootwrap.d + sudo install -d -o root -g root -m 755 $NEUTRON_CONF_DIR/rootwrap.d + sudo install -o root -g root -m 644 $NEUTRON_DIR/etc/neutron/rootwrap.d/*.filters $NEUTRON_CONF_DIR/rootwrap.d + + # Set up ``rootwrap.conf``, pointing to ``$NEUTRON_CONF_DIR/rootwrap.d`` + sudo install -o root -g root -m 644 $NEUTRON_DIR/etc/rootwrap.conf $NEUTRON_CONF_DIR + sudo sed -e "s:^filters_path=.*$:filters_path=$NEUTRON_CONF_DIR/rootwrap.d:" -i $NEUTRON_CONF_DIR/rootwrap.conf + + # Set up the rootwrap sudoers for Neutron + tempfile=`mktemp` + echo "$STACK_USER ALL=(root) NOPASSWD: $rootwrap_sudoer_cmd *" >$tempfile + chmod 0440 $tempfile + sudo chown root:root $tempfile + sudo mv $tempfile /etc/sudoers.d/neutron-rootwrap +} + +# Make Neutron-required changes to nova.conf +function configure_neutron_nova_new { + iniset $NOVA_CONF DEFAULT use_neutron True + iniset $NOVA_CONF neutron auth_type "password" + iniset $NOVA_CONF neutron auth_url "$KEYSTONE_SERVICE_PROTOCOL://$KEYSTONE_SERVICE_HOST:$KEYSTONE_AUTH_PORT/v3" + iniset $NOVA_CONF neutron username neutron + iniset $NOVA_CONF neutron password "$SERVICE_PASSWORD" + iniset $NOVA_CONF neutron user_domain_name "Default" + iniset $NOVA_CONF neutron project_name "$SERVICE_TENANT_NAME" + iniset $NOVA_CONF neutron project_domain_name "Default" + iniset $NOVA_CONF neutron auth_strategy $NEUTRON_AUTH_STRATEGY + iniset $NOVA_CONF neutron region_name "$REGION_NAME" + iniset $NOVA_CONF neutron url $NEUTRON_SERVICE_PROTOCOL://$NEUTRON_SERVICE_HOST:$NEUTRON_SERVICE_PORT + + iniset $NOVA_CONF DEFAULT firewall_driver nova.virt.firewall.NoopFirewallDriver + + if is_service_enabled neutron-meta; then + iniset $NOVA_CONF neutron service_metadata_proxy "True" + fi + +} + +# Tenant User Roles +# ------------------------------------------------------------------ +# service neutron admin # if enabled + +# create_neutron_accounts() - Create required service accounts +function create_neutron_accounts_new { + if [[ "$ENABLED_SERVICES" =~ "neutron-api" ]]; then + + create_service_user "neutron" + + neutron_service=$(get_or_create_service "neutron" \ + "network" "Neutron Service") + get_or_create_endpoint $neutron_service \ + "$REGION_NAME" \ + "$NEUTRON_SERVICE_PROTOCOL://$NEUTRON_SERVICE_HOST:$NEUTRON_SERVICE_PORT/" \ + "$NEUTRON_SERVICE_PROTOCOL://$NEUTRON_SERVICE_HOST:$NEUTRON_SERVICE_PORT/" \ + "$NEUTRON_SERVICE_PROTOCOL://$NEUTRON_SERVICE_HOST:$NEUTRON_SERVICE_PORT/" + fi +} + +# create_neutron_cache_dir() - Part of the init_neutron() process +function create_neutron_cache_dir { + # Create cache dir + sudo install -d -o $STACK_USER $NEUTRON_AUTH_CACHE_DIR + rm -f $NEUTRON_AUTH_CACHE_DIR/* +} + +# init_neutron() - Initialize databases, etc. +function init_neutron_new { + + recreate_database neutron + + # Run Neutron db migrations + $NEUTRON_BIN_DIR/neutron-db-manage $NEUTRON_CONFIG_ARG upgrade heads + + create_neutron_cache_dir +} + +# install_neutron() - Collect source and prepare +function install_neutron_new { + git_clone $NEUTRON_REPO $NEUTRON_DIR $NEUTRON_BRANCH + setup_develop $NEUTRON_DIR + + # Install neutron-lib from git so we make sure we're testing + # the latest code. + if use_library_from_git "neutron-lib"; then + git_clone_by_name "neutron-lib" + setup_dev_lib "neutron-lib" + fi + + # L3 service requires radvd + if is_service_enabled neutron-l3; then + install_package radvd + fi + + if is_service_enabled neutron-agent neutron-dhcp neutron-l3; then + #TODO(sc68cal) - kind of ugly + source $TOP_DIR/lib/neutron_plugins/${NEUTRON_AGENT}_agent + neutron_plugin_install_agent_packages + fi + +} + +# install_neutronclient() - Collect source and prepare +function install_neutronclient { + if use_library_from_git "python-neutronclient"; then + git_clone_by_name "python-neutronclient" + setup_dev_lib "python-neutronclient" + sudo install -D -m 0644 -o $STACK_USER {${GITDIR["python-neutronclient"]}/tools/,/etc/bash_completion.d/}neutron.bash_completion + fi +} + +# start_neutron_api() - Start the API process ahead of other things +function start_neutron_api { + local service_port=$NEUTRON_SERVICE_PORT + local service_protocol=$NEUTRON_SERVICE_PROTOCOL + if is_service_enabled tls-proxy; then + service_port=$NEUTRON_SERVICE_PORT_INT + service_protocol="http" + fi + + # Start the Neutron service + # TODO(sc68cal) Stop hard coding this + run_process neutron-api "$NEUTRON_BIN_DIR/neutron-server --config-file $NEUTRON_CONF --config-file $NEUTRON_PLUGIN_CONF" + + if is_ssl_enabled_service "neutron"; then + ssl_ca="--ca-certificate=${SSL_BUNDLE_FILE}" + local testcmd="wget ${ssl_ca} --no-proxy -q -O- $service_protocol://$NEUTRON_SERVICE_HOST:$service_port" + test_with_retry "$testcmd" "Neutron did not start" $SERVICE_TIMEOUT + else + if ! wait_for_service $SERVICE_TIMEOUT $service_protocol://$NEUTRON_SERVICE_HOST:$service_port; then + die $LINENO "neutron-api did not start" + fi + fi + + + # Start proxy if enabled + if is_service_enabled tls-proxy; then + start_tls_proxy '*' $NEUTRON_SERVICE_PORT $NEUTRON_SERVICE_HOST $NEUTRON_SERVICE_PORT_INT & + fi +} + +# start_neutron() - Start running processes, including screen +function start_neutron_new { + _set_config_files + + # Start up the neutron agents if enabled + # TODO(sc68cal) Make this pluggable so different DevStack plugins for different Neutron plugins + # can resolve the $NEUTRON_AGENT_BINARY + if is_service_enabled neutron-agent; then + run_process neutron-agent "$NEUTRON_BIN_DIR/$NEUTRON_AGENT_BINARY $NEUTRON_CONFIG_ARG" + fi + if is_service_enabled neutron-dhcp; then + neutron_plugin_configure_dhcp_agent $NEUTRON_DHCP_CONF + run_process neutron-dhcp "$NEUTRON_BIN_DIR/$NEUTRON_DHCP_BINARY $NEUTRON_CONFIG_ARG" + fi + if is_service_enabled neutron-l3; then + run_process neutron-l3 "$NEUTRON_BIN_DIR/$NEUTRON_L3_BINARY $NEUTRON_CONFIG_ARG" + # XXX(sc68cal) - Here's where plugins can wire up their own networks instead + # of the code in lib/neutron_plugins/services/l3 + if type -p neutron_plugin_create_initial_networks > /dev/null; then + neutron_plugin_create_initial_networks + else + # XXX(sc68cal) Load up the built in Neutron networking code and build a topology + source $TOP_DIR/lib/neutron_plugins/services/l3 + # Create the networks using servic + create_neutron_initial_network + fi + fi + if is_service_enabled neutron-meta; then + run_process neutron-meta "$NEUTRON_BIN_DIR/$NEUTRON_META_BINARY $NEUTRON_CONFIG_ARG" + fi +} + +# stop_neutron() - Stop running processes (non-screen) +function stop_neutron_new { + for serv in neutron-api neutron-agent neutron-l3; do + stop_process $serv + done + + if is_service_enabled neutron-dhcp; then + stop_process neutron-dhcp + pid=$(ps aux | awk '/[d]nsmasq.+interface=(tap|ns-)/ { print $2 }') + [ ! -z "$pid" ] && sudo kill -9 $pid + fi + + if is_service_enabled neutron-meta; then + sudo pkill -9 -f neutron-ns-metadata-proxy || : + stop_process neutron-meta + fi +} + +# Compile the lost of enabled config files +function _set_config_files { + + #TODO(sc68cal) - see if we can clean up this and only + # pass in config files that make sense for certain agents + if is_service_enabled neutron-api; then + NEUTRON_CONFIG_ARG+=" --config-file $NEUTRON_CONF" + fi + + #TODO(sc68cal) OVS and LB agent uses settings in NEUTRON_PLUGIN_CONF (ml2_conf.ini) but others may not + if is_service_enabled neutron-agent; then + NEUTRON_CONFIG_ARG+=" --config-file $NEUTRON_PLUGIN_CONF" + fi + + if is_service_enabled neutron-dhcp; then + NEUTRON_CONFIG_ARG+=" --config-file $NEUTRON_DHCP_CONF" + fi + + if is_service_enabled neutron-l3; then + NEUTRON_CONFIG_ARG+=" --config-file $NEUTRON_L3_CONF" + fi + + if is_service_enabled neutron-meta; then + NEUTRON_CONFIG_ARG+=" --config-file $NEUTRON_META_CONF" + fi + +} + +# Dispatch functions +# These are needed for compatibility between the old and new implementations +# where there are function name overlaps. These will be removed when +# neutron-legacy is removed. +# TODO(sc68cal) Remove when neutron-legacy is no more. +function cleanup_neutron { + if is_neutron_legacy_enabled; then + # Call back to old function + cleanup_mutnauq "$@" + else + cleanup_neutron_new "$@" + fi +} + +function configure_neutron { + if is_neutron_legacy_enabled; then + # Call back to old function + configure_mutnauq "$@" + else + configure_neutron_new "$@" + fi +} + +function configure_neutron_nova { + if is_neutron_legacy_enabled; then + # Call back to old function + create_nova_conf_neutron "$@" + else + configure_neutron_nova_new "$@" + fi +} + +function create_neutron_accounts { + if is_neutron_legacy_enabled; then + # Call back to old function + create_mutnauq_accounts "$@" + else + create_neutron_accounts_new "$@" + fi +} + +function init_neutron { + if is_neutron_legacy_enabled; then + # Call back to old function + init_mutnauq "$@" + else + init_neutron_new "$@" + fi +} + +function install_neutron { + if is_neutron_legacy_enabled; then + # Call back to old function + install_mutnauq "$@" + else + install_neutron_new "$@" + fi +} + +function start_neutron { + if is_neutron_legacy_enabled; then + # Call back to old function + start_mutnauq_l2_agent "$@" + start_mutnauq_other_agents "$@" + else + start_neutron_new "$@" + fi +} + +function stop_neutron { + if is_neutron_legacy_enabled; then + # Call back to old function + stop_mutnauq "$@" + else + stop_neutron_new "$@" + fi +} + +# Restore xtrace +$XTRACE diff --git a/lib/neutron-legacy b/lib/neutron-legacy index 4aa63890bd..7ebc2e2b3c 100644 --- a/lib/neutron-legacy +++ b/lib/neutron-legacy @@ -61,45 +61,12 @@ # Neutron Network Configuration # ----------------------------- -# Subnet IP version -IP_VERSION=${IP_VERSION:-"4+6"} -# Validate IP_VERSION -if [[ $IP_VERSION != "4" ]] && [[ $IP_VERSION != "6" ]] && [[ $IP_VERSION != "4+6" ]]; then - die $LINENO "IP_VERSION must be either 4, 6, or 4+6" -fi -# Gateway and subnet defaults, in case they are not customized in localrc -NETWORK_GATEWAY=${NETWORK_GATEWAY:-10.0.0.1} -PUBLIC_NETWORK_GATEWAY=${PUBLIC_NETWORK_GATEWAY:-172.24.4.1} -PRIVATE_SUBNET_NAME=${PRIVATE_SUBNET_NAME:-"private-subnet"} -PUBLIC_SUBNET_NAME=${PUBLIC_SUBNET_NAME:-"public-subnet"} - -# Subnetpool defaults -SUBNETPOOL_NAME=${SUBNETPOOL_NAME:-"shared-default-subnetpool"} - -SUBNETPOOL_PREFIX_V4=${SUBNETPOOL_PREFIX_V4:-10.0.0.0/8} -SUBNETPOOL_PREFIX_V6=${SUBNETPOOL_PREFIX_V6:-2001:db8:8000::/48} - -SUBNETPOOL_SIZE_V4=${SUBNETPOOL_SIZE_V4:-24} -SUBNETPOOL_SIZE_V6=${SUBNETPOOL_SIZE_V6:-64} if is_ssl_enabled_service "neutron" || is_service_enabled tls-proxy; then Q_PROTOCOL="https" fi -# Generate 40-bit IPv6 Global ID to comply with RFC 4193 -IPV6_GLOBAL_ID=`uuidgen | sed s/-//g | cut -c 23- | sed -e "s/\(..\)\(....\)\(....\)/\1:\2:\3/"` - -# IPv6 gateway and subnet defaults, in case they are not customized in localrc -IPV6_RA_MODE=${IPV6_RA_MODE:-slaac} -IPV6_ADDRESS_MODE=${IPV6_ADDRESS_MODE:-slaac} -IPV6_PUBLIC_SUBNET_NAME=${IPV6_PUBLIC_SUBNET_NAME:-ipv6-public-subnet} -IPV6_PRIVATE_SUBNET_NAME=${IPV6_PRIVATE_SUBNET_NAME:-ipv6-private-subnet} -FIXED_RANGE_V6=${FIXED_RANGE_V6:-fd$IPV6_GLOBAL_ID::/64} -IPV6_PRIVATE_NETWORK_GATEWAY=${IPV6_PRIVATE_NETWORK_GATEWAY:-fd$IPV6_GLOBAL_ID::1} -IPV6_PUBLIC_RANGE=${IPV6_PUBLIC_RANGE:-2001:db8::/64} -IPV6_PUBLIC_NETWORK_GATEWAY=${IPV6_PUBLIC_NETWORK_GATEWAY:-2001:db8::2} -IPV6_ROUTER_GW_IP=${IPV6_ROUTER_GW_IP:-2001:db8::1} # Set up default directories GITDIR["python-neutronclient"]=$DEST/python-neutronclient @@ -171,56 +138,6 @@ Q_NOTIFY_NOVA_PORT_STATUS_CHANGES=${Q_NOTIFY_NOVA_PORT_STATUS_CHANGES:-True} Q_NOTIFY_NOVA_PORT_DATA_CHANGES=${Q_NOTIFY_NOVA_PORT_DATA_CHANGES:-True} VIF_PLUGGING_IS_FATAL=${VIF_PLUGGING_IS_FATAL:-True} VIF_PLUGGING_TIMEOUT=${VIF_PLUGGING_TIMEOUT:-300} -# Specify if the initial private and external networks should be created -NEUTRON_CREATE_INITIAL_NETWORKS=${NEUTRON_CREATE_INITIAL_NETWORKS:-True} - -## Provider Network Information -PROVIDER_SUBNET_NAME=${PROVIDER_SUBNET_NAME:-"provider_net"} -IPV6_PROVIDER_SUBNET_NAME=${IPV6_PROVIDER_SUBNET_NAME:-"provider_net_v6"} -IPV6_PROVIDER_FIXED_RANGE=${IPV6_PROVIDER_FIXED_RANGE:-} -IPV6_PROVIDER_NETWORK_GATEWAY=${IPV6_PROVIDER_NETWORK_GATEWAY:-} - -# Define the public bridge that will transmit traffic from VMs to the -# physical network - used by both the OVS and Linux Bridge drivers. -PUBLIC_BRIDGE=${PUBLIC_BRIDGE:-br-ex} - -# Use flat providernet for public network -# -# If Q_USE_PROVIDERNET_FOR_PUBLIC=True, use a flat provider network -# for external interface of neutron l3-agent. In that case, -# PUBLIC_PHYSICAL_NETWORK specifies provider:physical_network value -# used for the network. In case of ofagent, you should add the -# corresponding entry to your OFAGENT_PHYSICAL_INTERFACE_MAPPINGS. -# For openvswitch agent, you should add the corresponding entry to -# your OVS_BRIDGE_MAPPINGS. -# -# eg. (ofagent) -# Q_USE_PROVIDERNET_FOR_PUBLIC=True -# Q_USE_PUBLIC_VETH=True -# PUBLIC_PHYSICAL_NETWORK=public -# OFAGENT_PHYSICAL_INTERFACE_MAPPINGS=public:veth-pub-int -# -# eg. (openvswitch agent) -# Q_USE_PROVIDERNET_FOR_PUBLIC=True -# PUBLIC_PHYSICAL_NETWORK=public -# OVS_BRIDGE_MAPPINGS=public:br-ex -Q_USE_PROVIDERNET_FOR_PUBLIC=${Q_USE_PROVIDERNET_FOR_PUBLIC:-False} -PUBLIC_PHYSICAL_NETWORK=${PUBLIC_PHYSICAL_NETWORK:-public} - -# If Q_USE_PUBLIC_VETH=True, create and use a veth pair instead of -# PUBLIC_BRIDGE. This is intended to be used with -# Q_USE_PROVIDERNET_FOR_PUBLIC=True. -Q_USE_PUBLIC_VETH=${Q_USE_PUBLIC_VETH:-False} -Q_PUBLIC_VETH_EX=${Q_PUBLIC_VETH_EX:-veth-pub-ex} -Q_PUBLIC_VETH_INT=${Q_PUBLIC_VETH_INT:-veth-pub-int} - -# The next two variables are configured by plugin -# e.g. _configure_neutron_l3_agent or lib/neutron_plugins/* -# -# The plugin supports L3. -Q_L3_ENABLED=${Q_L3_ENABLED:-False} -# L3 routers exist per tenant -Q_L3_ROUTER_PER_TENANT=${Q_L3_ROUTER_PER_TENANT:-True} # List of config file names in addition to the main plugin config file # See _configure_neutron_common() for details about setting it up @@ -354,6 +271,9 @@ source $TOP_DIR/lib/neutron_plugins/services/metering # --------------------------------- source $TOP_DIR/lib/neutron_plugins/services/firewall +# L3 Service functions +source $TOP_DIR/lib/neutron_plugins/services/l3 + # Use security group or not if has_neutron_plugin_security_group; then Q_USE_SECGROUP=${Q_USE_SECGROUP:-True} @@ -400,16 +320,9 @@ function determine_config_files { echo "$opts" } -# Test if any Neutron services are enabled -# is_neutron_enabled -function is_neutron_enabled { - [[ ,${ENABLED_SERVICES} =~ ,"q-" ]] && return 0 - return 1 -} - -# configure_neutron() +# configure_mutnauq() # Set common config for all neutron server and agents. -function configure_neutron { +function configure_mutnauq { _configure_neutron_common iniset_rpc_backend neutron $NEUTRON_CONF @@ -482,21 +395,14 @@ function create_nova_conf_neutron { iniset $NOVA_CONF DEFAULT vif_plugging_timeout "$VIF_PLUGGING_TIMEOUT" } -# create_neutron_cache_dir() - Part of the _neutron_setup_keystone() process -function create_neutron_cache_dir { - # Create cache dir - sudo install -d -o $STACK_USER $NEUTRON_AUTH_CACHE_DIR - rm -f $NEUTRON_AUTH_CACHE_DIR/* -} - -# create_neutron_accounts() - Set up common required neutron accounts +# create_mutnauq_accounts() - Set up common required neutron accounts # Tenant User Roles # ------------------------------------------------------------------ # service neutron admin # if enabled # Migrated from keystone_data.sh -function create_neutron_accounts { +function create_mutnauq_accounts { if [[ "$ENABLED_SERVICES" =~ "q-svc" ]]; then create_service_user "neutron" @@ -511,107 +417,15 @@ function create_neutron_accounts { fi } -function create_neutron_initial_network { - local project_id - project_id=$(openstack project list | grep " demo " | get_field 1) - die_if_not_set $LINENO project_id "Failure retrieving project_id for demo" - - # Allow drivers that need to create an initial network to do so here - if type -p neutron_plugin_create_initial_network_profile > /dev/null; then - neutron_plugin_create_initial_network_profile $PHYSICAL_NETWORK - fi - - if is_provider_network; then - die_if_not_set $LINENO PHYSICAL_NETWORK "You must specify the PHYSICAL_NETWORK" - die_if_not_set $LINENO PROVIDER_NETWORK_TYPE "You must specify the PROVIDER_NETWORK_TYPE" - NET_ID=$(neutron --os-cloud devstack-admin --os-region "$REGION_NAME" net-create $PHYSICAL_NETWORK --tenant_id $project_id --provider:network_type $PROVIDER_NETWORK_TYPE --provider:physical_network "$PHYSICAL_NETWORK" ${SEGMENTATION_ID:+--provider:segmentation_id $SEGMENTATION_ID} --shared | grep ' id ' | get_field 2) - die_if_not_set $LINENO NET_ID "Failure creating NET_ID for $PHYSICAL_NETWORK $project_id" - - if [[ "$IP_VERSION" =~ 4.* ]]; then - SUBNET_ID=$(neutron --os-cloud devstack-admin --os-region "$REGION_NAME" subnet-create --tenant_id $project_id --ip_version 4 ${ALLOCATION_POOL:+--allocation-pool $ALLOCATION_POOL} --name $PROVIDER_SUBNET_NAME --gateway $NETWORK_GATEWAY $NET_ID $FIXED_RANGE | grep ' id ' | get_field 2) - die_if_not_set $LINENO SUBNET_ID "Failure creating SUBNET_ID for $PROVIDER_SUBNET_NAME $project_id" - fi - - if [[ "$IP_VERSION" =~ .*6 ]] && [[ -n "$IPV6_PROVIDER_FIXED_RANGE" ]] && [[ -n "$IPV6_PROVIDER_NETWORK_GATEWAY" ]]; then - SUBNET_V6_ID=$(neutron --os-cloud devstack-admin --os-region "$REGION_NAME" subnet-create --tenant_id $project_id --ip_version 6 --ipv6-address-mode $IPV6_ADDRESS_MODE --gateway $IPV6_PROVIDER_NETWORK_GATEWAY --name $IPV6_PROVIDER_SUBNET_NAME $NET_ID $IPV6_PROVIDER_FIXED_RANGE | grep 'id' | get_field 2) - die_if_not_set $LINENO SUBNET_V6_ID "Failure creating SUBNET_V6_ID for $IPV6_PROVIDER_SUBNET_NAME $project_id" - fi - - if [[ $Q_AGENT == "openvswitch" ]]; then - sudo ip link set $OVS_PHYSICAL_BRIDGE up - sudo ip link set br-int up - sudo ip link set $PUBLIC_INTERFACE up - fi - else - NET_ID=$(neutron --os-cloud devstack-admin --os-region "$REGION_NAME" net-create --tenant-id $project_id "$PRIVATE_NETWORK_NAME" | grep ' id ' | get_field 2) - die_if_not_set $LINENO NET_ID "Failure creating NET_ID for $PRIVATE_NETWORK_NAME $project_id" - - if [[ "$IP_VERSION" =~ 4.* ]]; then - # Create IPv4 private subnet - SUBNET_ID=$(_neutron_create_private_subnet_v4 $project_id) - fi - - if [[ "$IP_VERSION" =~ .*6 ]]; then - # Create IPv6 private subnet - IPV6_SUBNET_ID=$(_neutron_create_private_subnet_v6 $project_id) - fi - fi - - AUTO_ALLOCATE_EXT=$(neutron --os-cloud devstack-admin --os-region "$REGION_NAME" ext-list | grep 'auto-allocated-topology' | get_field 1) - SUBNETPOOL_EXT=$(neutron --os-cloud devstack-admin --os-region "$REGION_NAME" ext-list | grep 'subnet_allocation' | get_field 1) - if [[ "$Q_L3_ENABLED" == "True" ]]; then - # Create a router, and add the private subnet as one of its interfaces - if [[ "$Q_L3_ROUTER_PER_TENANT" == "True" ]]; then - # create a tenant-owned router. - ROUTER_ID=$(neutron --os-cloud devstack-admin --os-region "$REGION_NAME" router-create --tenant-id $project_id $Q_ROUTER_NAME | grep ' id ' | get_field 2) - die_if_not_set $LINENO ROUTER_ID "Failure creating ROUTER_ID for $project_id $Q_ROUTER_NAME" - else - # Plugin only supports creating a single router, which should be admin owned. - ROUTER_ID=$(neutron --os-cloud devstack-admin --os-region "$REGION_NAME" router-create $Q_ROUTER_NAME | grep ' id ' | get_field 2) - die_if_not_set $LINENO ROUTER_ID "Failure creating ROUTER_ID for $Q_ROUTER_NAME" - fi - - # if the extension is available, then mark the external - # network as default, and provision default subnetpools - EXTERNAL_NETWORK_FLAGS="--router:external" - if [[ -n $AUTO_ALLOCATE_EXT && -n $SUBNETPOOL_EXT ]]; then - EXTERNAL_NETWORK_FLAGS="$EXTERNAL_NETWORK_FLAGS --is-default" - if [[ "$IP_VERSION" =~ 4.* ]]; then - SUBNETPOOL_V4_ID=$(neutron --os-cloud devstack-admin --os-region "$REGION_NAME" subnetpool-create $SUBNETPOOL_NAME --default-prefixlen $SUBNETPOOL_SIZE_V4 --pool-prefix $SUBNETPOOL_PREFIX_V4 --shared --is-default=True | grep ' id ' | get_field 2) - fi - if [[ "$IP_VERSION" =~ .*6 ]]; then - SUBNETPOOL_V6_ID=$(neutron --os-cloud devstack-admin --os-region "$REGION_NAME" subnetpool-create $SUBNETPOOL_NAME --default-prefixlen $SUBNETPOOL_SIZE_V6 --pool-prefix $SUBNETPOOL_PREFIX_V6 --shared --is-default=True | grep ' id ' | get_field 2) - fi - fi - # Create an external network, and a subnet. Configure the external network as router gw - if [ "$Q_USE_PROVIDERNET_FOR_PUBLIC" = "True" ]; then - EXT_NET_ID=$(neutron --os-cloud devstack-admin --os-region "$REGION_NAME" net-create "$PUBLIC_NETWORK_NAME" -- $EXTERNAL_NETWORK_FLAGS --provider:network_type=flat --provider:physical_network=${PUBLIC_PHYSICAL_NETWORK} | grep ' id ' | get_field 2) - else - EXT_NET_ID=$(neutron --os-cloud devstack-admin --os-region "$REGION_NAME" net-create "$PUBLIC_NETWORK_NAME" -- $EXTERNAL_NETWORK_FLAGS | grep ' id ' | get_field 2) - fi - die_if_not_set $LINENO EXT_NET_ID "Failure creating EXT_NET_ID for $PUBLIC_NETWORK_NAME" - - if [[ "$IP_VERSION" =~ 4.* ]]; then - # Configure router for IPv4 public access - _neutron_configure_router_v4 - fi - - if [[ "$IP_VERSION" =~ .*6 ]]; then - # Configure router for IPv6 public access - _neutron_configure_router_v6 - fi - fi -} - -# init_neutron() - Initialize databases, etc. -function init_neutron { +# init_mutnauq() - Initialize databases, etc. +function init_mutnauq { recreate_database $Q_DB_NAME # Run Neutron db migrations $NEUTRON_BIN_DIR/neutron-db-manage --config-file $NEUTRON_CONF --config-file /$Q_PLUGIN_CONF_FILE upgrade head } -# install_neutron() - Collect source and prepare -function install_neutron { +# install_mutnauq() - Collect source and prepare +function install_mutnauq { # Install neutron-lib from git so we make sure we're testing # the latest code. if use_library_from_git "neutron-lib"; then @@ -649,15 +463,6 @@ function install_neutron { fi } -# install_neutronclient() - Collect source and prepare -function install_neutronclient { - if use_library_from_git "python-neutronclient"; then - git_clone_by_name "python-neutronclient" - setup_dev_lib "python-neutronclient" - sudo install -D -m 0644 -o $STACK_USER {${GITDIR["python-neutronclient"]}/tools/,/etc/bash_completion.d/}neutron.bash_completion - fi -} - # install_neutron_agent_packages() - Collect source and prepare function install_neutron_agent_packages { # radvd doesn't come with the OS. Install it if the l3 service is enabled. @@ -704,7 +509,7 @@ function start_neutron_service_and_check { # Control of the l2 agent is separated out to make it easier to test partial # upgrades (everything upgraded except the L2 agent) -function start_neutron_l2_agent { +function start_mutnauq_l2_agent { run_process q-agt "$AGENT_BINARY --config-file $NEUTRON_CONF --config-file /$Q_PLUGIN_CONF_FILE" if is_provider_network && [[ $Q_AGENT == "openvswitch" ]]; then @@ -722,7 +527,7 @@ function start_neutron_l2_agent { fi } -function start_neutron_other_agents { +function start_mutnauq_other_agents { run_process q-dhcp "$AGENT_DHCP_BINARY --config-file $NEUTRON_CONF --config-file=$Q_DHCP_CONF_FILE" if is_service_enabled neutron-vpnaas; then @@ -744,15 +549,16 @@ function start_neutron_other_agents { # Start running processes, including screen function start_neutron_agents { # Start up the neutron agents if enabled - start_neutron_l2_agent - start_neutron_other_agents + start_mutnauq_l2_agent + start_mutnauq_other_agents } -function stop_neutron_l2_agent { +function stop_mutnauq_l2_agent { stop_process q-agt } -function stop_neutron_other { +# stop_mutnauq_other() - Stop running processes (non-screen) +function stop_mutnauq_other { if is_service_enabled q-dhcp; then stop_process q-dhcp pid=$(ps aux | awk '/[d]nsmasq.+interface=(tap|ns-)/ { print $2 }') @@ -787,9 +593,9 @@ function stop_neutron_other { } # stop_neutron() - Stop running processes (non-screen) -function stop_neutron { - stop_neutron_other - stop_neutron_l2_agent +function stop_mutnauq { + stop_mutnauq_other + stop_mutnauq_l2_agent } # _move_neutron_addresses_route() - Move the primary IP to the OVS bridge @@ -842,9 +648,9 @@ function _move_neutron_addresses_route { fi } -# cleanup_neutron() - Remove residual data files, anything left over from previous +# cleanup_mutnauq() - Remove residual data files, anything left over from previous # runs that a clean run would need to clean up -function cleanup_neutron { +function cleanup_mutnauq { if [[ -n "$OVS_PHYSICAL_BRIDGE" ]]; then _move_neutron_addresses_route "$OVS_PHYSICAL_BRIDGE" "$PUBLIC_INTERFACE" False True "inet" @@ -1031,27 +837,6 @@ function _configure_neutron_dhcp_agent { neutron_plugin_configure_dhcp_agent } -function _configure_neutron_l3_agent { - Q_L3_ENABLED=True - - cp $NEUTRON_DIR/etc/l3_agent.ini.sample $Q_L3_CONF_FILE - - iniset $Q_L3_CONF_FILE DEFAULT debug $ENABLE_DEBUG_LOG_LEVEL - iniset $Q_L3_CONF_FILE AGENT root_helper "$Q_RR_COMMAND" - if [[ "$Q_USE_ROOTWRAP_DAEMON" == "True" ]]; then - iniset $Q_L3_CONF_FILE AGENT root_helper_daemon "$Q_RR_DAEMON_COMMAND" - fi - - _neutron_setup_interface_driver $Q_L3_CONF_FILE - - neutron_plugin_configure_l3_agent - - _move_neutron_addresses_route "$PUBLIC_INTERFACE" "$OVS_PHYSICAL_BRIDGE" True False "inet" - - if [[ $(ip -f inet6 a s dev "$PUBLIC_INTERFACE" | grep -c 'global') != 0 ]]; then - _move_neutron_addresses_route "$PUBLIC_INTERFACE" "$OVS_PHYSICAL_BRIDGE" False False "inet6" - fi -} function _configure_neutron_metadata_agent { cp $NEUTRON_DIR/etc/metadata_agent.ini.sample $Q_META_CONF_FILE @@ -1226,164 +1011,6 @@ function _neutron_setup_interface_driver { neutron_plugin_setup_interface_driver $1 } - -# Create private IPv4 subnet -function _neutron_create_private_subnet_v4 { - local project_id=$1 - local subnet_params="--tenant-id $project_id " - subnet_params+="--ip_version 4 " - subnet_params+="--gateway $NETWORK_GATEWAY " - subnet_params+="--name $PRIVATE_SUBNET_NAME " - subnet_params+="$NET_ID $FIXED_RANGE" - local subnet_id - subnet_id=$(neutron --os-cloud devstack-admin --os-region "$REGION_NAME" subnet-create $subnet_params | grep ' id ' | get_field 2) - die_if_not_set $LINENO subnet_id "Failure creating private IPv4 subnet for $project_id" - echo $subnet_id -} - -# Create private IPv6 subnet -function _neutron_create_private_subnet_v6 { - local project_id=$1 - die_if_not_set $LINENO IPV6_RA_MODE "IPV6 RA Mode not set" - die_if_not_set $LINENO IPV6_ADDRESS_MODE "IPV6 Address Mode not set" - local ipv6_modes="--ipv6-ra-mode $IPV6_RA_MODE --ipv6-address-mode $IPV6_ADDRESS_MODE" - local subnet_params="--tenant-id $project_id " - subnet_params+="--ip_version 6 " - subnet_params+="--gateway $IPV6_PRIVATE_NETWORK_GATEWAY " - subnet_params+="--name $IPV6_PRIVATE_SUBNET_NAME " - subnet_params+="$NET_ID $FIXED_RANGE_V6 $ipv6_modes" - local ipv6_subnet_id - ipv6_subnet_id=$(neutron --os-cloud devstack-admin --os-region "$REGION_NAME" subnet-create $subnet_params | grep ' id ' | get_field 2) - die_if_not_set $LINENO ipv6_subnet_id "Failure creating private IPv6 subnet for $project_id" - echo $ipv6_subnet_id -} - -# Create public IPv4 subnet -function _neutron_create_public_subnet_v4 { - local subnet_params+="--ip_version 4 " - subnet_params+="${Q_FLOATING_ALLOCATION_POOL:+--allocation-pool $Q_FLOATING_ALLOCATION_POOL} " - subnet_params+="--gateway $PUBLIC_NETWORK_GATEWAY " - subnet_params+="--name $PUBLIC_SUBNET_NAME " - subnet_params+="$EXT_NET_ID $FLOATING_RANGE " - subnet_params+="-- --enable_dhcp=False" - local id_and_ext_gw_ip - id_and_ext_gw_ip=$(neutron --os-cloud devstack-admin --os-region "$REGION_NAME" subnet-create $subnet_params | grep -e 'gateway_ip' -e ' id ') - die_if_not_set $LINENO id_and_ext_gw_ip "Failure creating public IPv4 subnet" - echo $id_and_ext_gw_ip -} - -# Create public IPv6 subnet -function _neutron_create_public_subnet_v6 { - local subnet_params="--ip_version 6 " - subnet_params+="--gateway $IPV6_PUBLIC_NETWORK_GATEWAY " - subnet_params+="--name $IPV6_PUBLIC_SUBNET_NAME " - subnet_params+="$EXT_NET_ID $IPV6_PUBLIC_RANGE " - subnet_params+="-- --enable_dhcp=False" - local ipv6_id_and_ext_gw_ip - ipv6_id_and_ext_gw_ip=$(neutron --os-cloud devstack-admin --os-region "$REGION_NAME" subnet-create $subnet_params | grep -e 'gateway_ip' -e ' id ') - die_if_not_set $LINENO ipv6_id_and_ext_gw_ip "Failure creating an IPv6 public subnet" - echo $ipv6_id_and_ext_gw_ip -} - -# Configure neutron router for IPv4 public access -function _neutron_configure_router_v4 { - neutron --os-cloud devstack-admin --os-region "$REGION_NAME" router-interface-add $ROUTER_ID $SUBNET_ID - # Create a public subnet on the external network - local id_and_ext_gw_ip - id_and_ext_gw_ip=$(_neutron_create_public_subnet_v4 $EXT_NET_ID) - local ext_gw_ip - ext_gw_ip=$(echo $id_and_ext_gw_ip | get_field 2) - PUB_SUBNET_ID=$(echo $id_and_ext_gw_ip | get_field 5) - # Configure the external network as the default router gateway - neutron --os-cloud devstack-admin --os-region "$REGION_NAME" router-gateway-set $ROUTER_ID $EXT_NET_ID - - # This logic is specific to using the l3-agent for layer 3 - if is_service_enabled q-l3; then - # Configure and enable public bridge - local ext_gw_interface="none" - if is_neutron_ovs_base_plugin; then - ext_gw_interface=$(_neutron_get_ext_gw_interface) - elif [[ "$Q_AGENT" = "linuxbridge" ]]; then - # Search for the brq device the neutron router and network for $FIXED_RANGE - # will be using. - # e.x. brq3592e767-da for NET_ID 3592e767-da66-4bcb-9bec-cdb03cd96102 - ext_gw_interface=brq${EXT_NET_ID:0:11} - fi - if [[ "$ext_gw_interface" != "none" ]]; then - local cidr_len=${FLOATING_RANGE#*/} - local testcmd="ip -o link | grep -q $ext_gw_interface" - test_with_retry "$testcmd" "$ext_gw_interface creation failed" - if [[ $(ip addr show dev $ext_gw_interface | grep -c $ext_gw_ip) == 0 && ( $Q_USE_PROVIDERNET_FOR_PUBLIC == "False" || $Q_USE_PUBLIC_VETH == "True" ) ]]; then - sudo ip addr add $ext_gw_ip/$cidr_len dev $ext_gw_interface - sudo ip link set $ext_gw_interface up - fi - ROUTER_GW_IP=$(neutron --os-cloud devstack-admin --os-region "$REGION_NAME" port-list -c fixed_ips -c device_owner | grep router_gateway | awk -F'ip_address' '{ print $2 }' | cut -f3 -d\" | tr '\n' ' ') - die_if_not_set $LINENO ROUTER_GW_IP "Failure retrieving ROUTER_GW_IP" - sudo ip route replace $FIXED_RANGE via $ROUTER_GW_IP - fi - _neutron_set_router_id - fi -} - -# Configure neutron router for IPv6 public access -function _neutron_configure_router_v6 { - neutron --os-cloud devstack-admin --os-region "$REGION_NAME" router-interface-add $ROUTER_ID $IPV6_SUBNET_ID - # Create a public subnet on the external network - local ipv6_id_and_ext_gw_ip - ipv6_id_and_ext_gw_ip=$(_neutron_create_public_subnet_v6 $EXT_NET_ID) - local ipv6_ext_gw_ip - ipv6_ext_gw_ip=$(echo $ipv6_id_and_ext_gw_ip | get_field 2) - local ipv6_pub_subnet_id - ipv6_pub_subnet_id=$(echo $ipv6_id_and_ext_gw_ip | get_field 5) - - # If the external network has not already been set as the default router - # gateway when configuring an IPv4 public subnet, do so now - if [[ "$IP_VERSION" == "6" ]]; then - neutron --os-cloud devstack-admin --os-region "$REGION_NAME" router-gateway-set $ROUTER_ID $EXT_NET_ID - fi - - # This logic is specific to using the l3-agent for layer 3 - if is_service_enabled q-l3; then - # Ensure IPv6 forwarding is enabled on the host - sudo sysctl -w net.ipv6.conf.all.forwarding=1 - # Configure and enable public bridge - # Override global IPV6_ROUTER_GW_IP with the true value from neutron - IPV6_ROUTER_GW_IP=$(neutron --os-cloud devstack-admin --os-region "$REGION_NAME" port-list -c fixed_ips | grep $ipv6_pub_subnet_id | awk -F'ip_address' '{ print $2 }' | cut -f3 -d\" | tr '\n' ' ') - die_if_not_set $LINENO IPV6_ROUTER_GW_IP "Failure retrieving IPV6_ROUTER_GW_IP" - - if is_neutron_ovs_base_plugin; then - local ext_gw_interface - ext_gw_interface=$(_neutron_get_ext_gw_interface) - local ipv6_cidr_len=${IPV6_PUBLIC_RANGE#*/} - - # Configure interface for public bridge - sudo ip -6 addr add $ipv6_ext_gw_ip/$ipv6_cidr_len dev $ext_gw_interface - sudo ip -6 route replace $FIXED_RANGE_V6 via $IPV6_ROUTER_GW_IP dev $ext_gw_interface - fi - _neutron_set_router_id - fi -} - -# Explicitly set router id in l3 agent configuration -function _neutron_set_router_id { - if [[ "$Q_L3_ROUTER_PER_TENANT" == "False" ]]; then - iniset $Q_L3_CONF_FILE DEFAULT router_id $ROUTER_ID - fi -} - -# Get ext_gw_interface depending on value of Q_USE_PUBLIC_VETH -function _neutron_get_ext_gw_interface { - if [[ "$Q_USE_PUBLIC_VETH" == "True" ]]; then - echo $Q_PUBLIC_VETH_EX - else - # Disable in-band as we are going to use local port - # to communicate with VMs - sudo ovs-vsctl set Bridge $PUBLIC_BRIDGE \ - other_config:disable-in-band=true - echo $PUBLIC_BRIDGE - fi -} - # Functions for Neutron Exercises #-------------------------------- @@ -1485,14 +1112,6 @@ function check_neutron_third_party_integration { _neutron_third_party_do check } -function is_provider_network { - if [ "$Q_USE_PROVIDER_NETWORKING" == "True" ] && [ "$Q_L3_ENABLED" == "False" ]; then - return 0 - fi - return 1 -} - - # Restore xtrace $_XTRACE_NEUTRON diff --git a/lib/neutron_plugins/linuxbridge_agent b/lib/neutron_plugins/linuxbridge_agent index 096722b096..0a066354ca 100644 --- a/lib/neutron_plugins/linuxbridge_agent +++ b/lib/neutron_plugins/linuxbridge_agent @@ -43,13 +43,15 @@ function neutron_plugin_configure_debug_command { } function neutron_plugin_configure_dhcp_agent { - iniset $Q_DHCP_CONF_FILE DEFAULT dhcp_agent_manager neutron.agent.dhcp_agent.DhcpAgentWithStateReport + local conf_file=$1 + iniset $conf_file DEFAULT dhcp_agent_manager neutron.agent.dhcp_agent.DhcpAgentWithStateReport } function neutron_plugin_configure_l3_agent { + local conf_file=$1 sudo brctl addbr $PUBLIC_BRIDGE - iniset $Q_L3_CONF_FILE DEFAULT external_network_bridge - iniset $Q_L3_CONF_FILE DEFAULT l3_agent_manager neutron.agent.l3_agent.L3NATAgentWithStateReport + iniset $conf_file DEFAULT external_network_bridge + iniset $conf_file DEFAULT l3_agent_manager neutron.agent.l3_agent.L3NATAgentWithStateReport } function neutron_plugin_configure_plugin_agent { diff --git a/lib/neutron_plugins/openvswitch_agent b/lib/neutron_plugins/openvswitch_agent index aba2587ea4..69e38f4df1 100644 --- a/lib/neutron_plugins/openvswitch_agent +++ b/lib/neutron_plugins/openvswitch_agent @@ -28,12 +28,14 @@ function neutron_plugin_configure_debug_command { } function neutron_plugin_configure_dhcp_agent { - iniset $Q_DHCP_CONF_FILE DEFAULT dhcp_agent_manager neutron.agent.dhcp_agent.DhcpAgentWithStateReport + local conf_file=$1 + iniset $conf_file DEFAULT dhcp_agent_manager neutron.agent.dhcp_agent.DhcpAgentWithStateReport } function neutron_plugin_configure_l3_agent { + local conf_file=$1 _neutron_ovs_base_configure_l3_agent - iniset $Q_L3_CONF_FILE DEFAULT l3_agent_manager neutron.agent.l3_agent.L3NATAgentWithStateReport + iniset $conf_file DEFAULT l3_agent_manager neutron.agent.l3_agent.L3NATAgentWithStateReport } function neutron_plugin_configure_plugin_agent { diff --git a/lib/neutron_plugins/services/l3 b/lib/neutron_plugins/services/l3 new file mode 100644 index 0000000000..177dc1f028 --- /dev/null +++ b/lib/neutron_plugins/services/l3 @@ -0,0 +1,366 @@ +#!/bin/bash +# Subnet IP version +IP_VERSION=${IP_VERSION:-"4+6"} +# Validate IP_VERSION +if [[ $IP_VERSION != "4" ]] && [[ $IP_VERSION != "6" ]] && [[ $IP_VERSION != "4+6" ]]; then + die $LINENO "IP_VERSION must be either 4, 6, or 4+6" +fi +# Specify if the initial private and external networks should be created +NEUTRON_CREATE_INITIAL_NETWORKS=${NEUTRON_CREATE_INITIAL_NETWORKS:-True} + +## Provider Network Information +PROVIDER_SUBNET_NAME=${PROVIDER_SUBNET_NAME:-"provider_net"} +IPV6_PROVIDER_SUBNET_NAME=${IPV6_PROVIDER_SUBNET_NAME:-"provider_net_v6"} +IPV6_PROVIDER_FIXED_RANGE=${IPV6_PROVIDER_FIXED_RANGE:-} +IPV6_PROVIDER_NETWORK_GATEWAY=${IPV6_PROVIDER_NETWORK_GATEWAY:-} + +PUBLIC_BRIDGE=${PUBLIC_BRIDGE:-br-ex} + +# If Q_USE_PUBLIC_VETH=True, create and use a veth pair instead of +# PUBLIC_BRIDGE. This is intended to be used with +# Q_USE_PROVIDERNET_FOR_PUBLIC=True. +Q_USE_PUBLIC_VETH=${Q_USE_PUBLIC_VETH:-False} +Q_PUBLIC_VETH_EX=${Q_PUBLIC_VETH_EX:-veth-pub-ex} +Q_PUBLIC_VETH_INT=${Q_PUBLIC_VETH_INT:-veth-pub-int} + +# The next two variables are configured by plugin +# e.g. _configure_neutron_l3_agent or lib/neutron_plugins/* +# +# The plugin supports L3. +Q_L3_ENABLED=${Q_L3_ENABLED:-True} +# L3 routers exist per tenant +Q_L3_ROUTER_PER_TENANT=${Q_L3_ROUTER_PER_TENANT:-True} + + +# Use flat providernet for public network +# +# If Q_USE_PROVIDERNET_FOR_PUBLIC=True, use a flat provider network +# for external interface of neutron l3-agent. In that case, +# PUBLIC_PHYSICAL_NETWORK specifies provider:physical_network value +# used for the network. In case of ofagent, you should add the +# corresponding entry to your OFAGENT_PHYSICAL_INTERFACE_MAPPINGS. +# For openvswitch agent, you should add the corresponding entry to +# your OVS_BRIDGE_MAPPINGS. +# +# eg. (ofagent) +# Q_USE_PROVIDERNET_FOR_PUBLIC=True +# Q_USE_PUBLIC_VETH=True +# PUBLIC_PHYSICAL_NETWORK=public +# OFAGENT_PHYSICAL_INTERFACE_MAPPINGS=public:veth-pub-int +# +# eg. (openvswitch agent) +# Q_USE_PROVIDERNET_FOR_PUBLIC=True +# PUBLIC_PHYSICAL_NETWORK=public +# OVS_BRIDGE_MAPPINGS=public:br-ex +Q_USE_PROVIDERNET_FOR_PUBLIC=${Q_USE_PROVIDERNET_FOR_PUBLIC:-False} +PUBLIC_PHYSICAL_NETWORK=${PUBLIC_PHYSICAL_NETWORK:-public} + +# Generate 40-bit IPv6 Global ID to comply with RFC 4193 +IPV6_GLOBAL_ID=`uuidgen | sed s/-//g | cut -c 23- | sed -e "s/\(..\)\(....\)\(....\)/\1:\2:\3/"` + +# IPv6 gateway and subnet defaults, in case they are not customized in localrc +IPV6_RA_MODE=${IPV6_RA_MODE:-slaac} +IPV6_ADDRESS_MODE=${IPV6_ADDRESS_MODE:-slaac} +IPV6_PUBLIC_SUBNET_NAME=${IPV6_PUBLIC_SUBNET_NAME:-ipv6-public-subnet} +IPV6_PRIVATE_SUBNET_NAME=${IPV6_PRIVATE_SUBNET_NAME:-ipv6-private-subnet} +FIXED_RANGE_V6=${FIXED_RANGE_V6:-fd$IPV6_GLOBAL_ID::/64} +IPV6_PRIVATE_NETWORK_GATEWAY=${IPV6_PRIVATE_NETWORK_GATEWAY:-fd$IPV6_GLOBAL_ID::1} +IPV6_PUBLIC_RANGE=${IPV6_PUBLIC_RANGE:-2001:db8::/64} +IPV6_PUBLIC_NETWORK_GATEWAY=${IPV6_PUBLIC_NETWORK_GATEWAY:-2001:db8::2} +IPV6_ROUTER_GW_IP=${IPV6_ROUTER_GW_IP:-2001:db8::1} + +# Gateway and subnet defaults, in case they are not customized in localrc +NETWORK_GATEWAY=${NETWORK_GATEWAY:-10.0.0.1} +PUBLIC_NETWORK_GATEWAY=${PUBLIC_NETWORK_GATEWAY:-172.24.4.1} +PRIVATE_SUBNET_NAME=${PRIVATE_SUBNET_NAME:-"private-subnet"} +PUBLIC_SUBNET_NAME=${PUBLIC_SUBNET_NAME:-"public-subnet"} + +# Subnetpool defaults +SUBNETPOOL_NAME=${SUBNETPOOL_NAME:-"shared-default-subnetpool"} + +SUBNETPOOL_PREFIX_V4=${SUBNETPOOL_PREFIX_V4:-10.0.0.0/8} +SUBNETPOOL_PREFIX_V6=${SUBNETPOOL_PREFIX_V6:-2001:db8:8000::/48} + +SUBNETPOOL_SIZE_V4=${SUBNETPOOL_SIZE_V4:-24} +SUBNETPOOL_SIZE_V6=${SUBNETPOOL_SIZE_V6:-64} + +function _determine_config_l3 { + local opts="--config-file $NEUTRON_CONF --config-file=$Q_L3_CONF_FILE" + echo "$opts" +} + +function _configure_neutron_l3_agent { + local cfg_file + Q_L3_ENABLED=True + + cp $NEUTRON_DIR/etc/l3_agent.ini.sample $Q_L3_CONF_FILE + + iniset $Q_L3_CONF_FILE DEFAULT verbose True + iniset $Q_L3_CONF_FILE DEFAULT debug $ENABLE_DEBUG_LOG_LEVEL + iniset $Q_L3_CONF_FILE DEFAULT use_namespaces $Q_USE_NAMESPACE + iniset $Q_L3_CONF_FILE DEFAULT root_helper "$Q_RR_COMMAND" + if [[ "$Q_USE_ROOTWRAP_DAEMON" == "True" ]]; then + iniset $Q_L3_CONF_FILE agent root_helper_daemon "$Q_RR_DAEMON_COMMAND" + fi + + _neutron_setup_interface_driver $Q_L3_CONF_FILE + + neutron_plugin_configure_l3_agent + + if [[ $(ip -f inet a s dev "$PUBLIC_INTERFACE" | grep -c 'global') != 0 ]]; then + _move_neutron_addresses_route "$PUBLIC_INTERFACE" "$OVS_PHYSICAL_BRIDGE" True "inet" + fi + + if [[ $(ip -f inet6 a s dev "$PUBLIC_INTERFACE" | grep -c 'global') != 0 ]]; then + _move_neutron_addresses_route "$PUBLIC_INTERFACE" "$OVS_PHYSICAL_BRIDGE" False "inet6" + fi +} + +# Explicitly set router id in l3 agent configuration +function _neutron_set_router_id { + if [[ "$Q_L3_ROUTER_PER_TENANT" == "False" ]]; then + iniset $Q_L3_CONF_FILE DEFAULT router_id $ROUTER_ID + fi +} + +# Get ext_gw_interface depending on value of Q_USE_PUBLIC_VETH +function _neutron_get_ext_gw_interface { + if [[ "$Q_USE_PUBLIC_VETH" == "True" ]]; then + echo $Q_PUBLIC_VETH_EX + else + # Disable in-band as we are going to use local port + # to communicate with VMs + sudo ovs-vsctl set Bridge $PUBLIC_BRIDGE \ + other_config:disable-in-band=true + echo $PUBLIC_BRIDGE + fi +} + +function create_neutron_initial_network { + local project_id + project_id=$(openstack project list | grep " demo " | get_field 1) + die_if_not_set $LINENO project_id "Failure retrieving project_id for demo" + + # Allow drivers that need to create an initial network to do so here + if type -p neutron_plugin_create_initial_network_profile > /dev/null; then + neutron_plugin_create_initial_network_profile $PHYSICAL_NETWORK + fi + + if is_provider_network; then + die_if_not_set $LINENO PHYSICAL_NETWORK "You must specify the PHYSICAL_NETWORK" + die_if_not_set $LINENO PROVIDER_NETWORK_TYPE "You must specify the PROVIDER_NETWORK_TYPE" + NET_ID=$(neutron --os-cloud devstack-admin --os-region "$REGION_NAME" net-create $PHYSICAL_NETWORK --tenant_id $project_id --provider:network_type $PROVIDER_NETWORK_TYPE --provider:physical_network "$PHYSICAL_NETWORK" ${SEGMENTATION_ID:+--provider:segmentation_id $SEGMENTATION_ID} --shared | grep ' id ' | get_field 2) + die_if_not_set $LINENO NET_ID "Failure creating NET_ID for $PHYSICAL_NETWORK $project_id" + + if [[ "$IP_VERSION" =~ 4.* ]]; then + SUBNET_ID=$(neutron --os-cloud devstack-admin --os-region "$REGION_NAME" subnet-create --tenant_id $project_id --ip_version 4 ${ALLOCATION_POOL:+--allocation-pool $ALLOCATION_POOL} --name $PROVIDER_SUBNET_NAME --gateway $NETWORK_GATEWAY $NET_ID $FIXED_RANGE | grep ' id ' | get_field 2) + die_if_not_set $LINENO SUBNET_ID "Failure creating SUBNET_ID for $PROVIDER_SUBNET_NAME $project_id" + fi + + if [[ "$IP_VERSION" =~ .*6 ]] && [[ -n "$IPV6_PROVIDER_FIXED_RANGE" ]] && [[ -n "$IPV6_PROVIDER_NETWORK_GATEWAY" ]]; then + SUBNET_V6_ID=$(neutron --os-cloud devstack-admin --os-region "$REGION_NAME" subnet-create --tenant_id $project_id --ip_version 6 --ipv6-address-mode $IPV6_ADDRESS_MODE --gateway $IPV6_PROVIDER_NETWORK_GATEWAY --name $IPV6_PROVIDER_SUBNET_NAME $NET_ID $IPV6_PROVIDER_FIXED_RANGE | grep 'id' | get_field 2) + die_if_not_set $LINENO SUBNET_V6_ID "Failure creating SUBNET_V6_ID for $IPV6_PROVIDER_SUBNET_NAME $project_id" + fi + + if [[ $Q_AGENT == "openvswitch" ]]; then + sudo ip link set $OVS_PHYSICAL_BRIDGE up + sudo ip link set br-int up + sudo ip link set $PUBLIC_INTERFACE up + fi + else + NET_ID=$(neutron --os-cloud devstack-admin --os-region "$REGION_NAME" net-create --tenant-id $project_id "$PRIVATE_NETWORK_NAME" | grep ' id ' | get_field 2) + die_if_not_set $LINENO NET_ID "Failure creating NET_ID for $PRIVATE_NETWORK_NAME $project_id" + + if [[ "$IP_VERSION" =~ 4.* ]]; then + # Create IPv4 private subnet + SUBNET_ID=$(_neutron_create_private_subnet_v4 $project_id) + fi + + if [[ "$IP_VERSION" =~ .*6 ]]; then + # Create IPv6 private subnet + IPV6_SUBNET_ID=$(_neutron_create_private_subnet_v6 $project_id) + fi + fi + + AUTO_ALLOCATE_EXT=$(neutron --os-cloud devstack-admin --os-region "$REGION_NAME" ext-list | grep 'auto-allocated-topology' | get_field 1) + SUBNETPOOL_EXT=$(neutron --os-cloud devstack-admin --os-region "$REGION_NAME" ext-list | grep 'subnet_allocation' | get_field 1) + if [[ "$Q_L3_ENABLED" == "True" ]]; then + # Create a router, and add the private subnet as one of its interfaces + if [[ "$Q_L3_ROUTER_PER_TENANT" == "True" ]]; then + # create a tenant-owned router. + ROUTER_ID=$(neutron --os-cloud devstack-admin --os-region "$REGION_NAME" router-create --tenant-id $project_id $Q_ROUTER_NAME | grep ' id ' | get_field 2) + die_if_not_set $LINENO ROUTER_ID "Failure creating ROUTER_ID for $project_id $Q_ROUTER_NAME" + else + # Plugin only supports creating a single router, which should be admin owned. + ROUTER_ID=$(neutron --os-cloud devstack-admin --os-region "$REGION_NAME" router-create $Q_ROUTER_NAME | grep ' id ' | get_field 2) + die_if_not_set $LINENO ROUTER_ID "Failure creating ROUTER_ID for $Q_ROUTER_NAME" + fi + + # if the extension is available, then mark the external + # network as default, and provision default subnetpools + EXTERNAL_NETWORK_FLAGS="--router:external" + if [[ -n $AUTO_ALLOCATE_EXT && -n $SUBNETPOOL_EXT ]]; then + EXTERNAL_NETWORK_FLAGS="$EXTERNAL_NETWORK_FLAGS --is-default" + if [[ "$IP_VERSION" =~ 4.* ]]; then + SUBNETPOOL_V4_ID=$(neutron --os-cloud devstack-admin --os-region "$REGION_NAME" subnetpool-create $SUBNETPOOL_NAME --default-prefixlen $SUBNETPOOL_SIZE_V4 --pool-prefix $SUBNETPOOL_PREFIX_V4 --shared --is-default=True | grep ' id ' | get_field 2) + fi + if [[ "$IP_VERSION" =~ .*6 ]]; then + SUBNETPOOL_V6_ID=$(neutron --os-cloud devstack-admin --os-region "$REGION_NAME" subnetpool-create $SUBNETPOOL_NAME --default-prefixlen $SUBNETPOOL_SIZE_V6 --pool-prefix $SUBNETPOOL_PREFIX_V6 --shared --is-default=True | grep ' id ' | get_field 2) + fi + fi + # Create an external network, and a subnet. Configure the external network as router gw + if [ "$Q_USE_PROVIDERNET_FOR_PUBLIC" = "True" ]; then + EXT_NET_ID=$(neutron --os-cloud devstack-admin --os-region "$REGION_NAME" net-create "$PUBLIC_NETWORK_NAME" -- $EXTERNAL_NETWORK_FLAGS --provider:network_type=flat --provider:physical_network=${PUBLIC_PHYSICAL_NETWORK} | grep ' id ' | get_field 2) + else + EXT_NET_ID=$(neutron --os-cloud devstack-admin --os-region "$REGION_NAME" net-create "$PUBLIC_NETWORK_NAME" -- $EXTERNAL_NETWORK_FLAGS | grep ' id ' | get_field 2) + fi + die_if_not_set $LINENO EXT_NET_ID "Failure creating EXT_NET_ID for $PUBLIC_NETWORK_NAME" + + if [[ "$IP_VERSION" =~ 4.* ]]; then + # Configure router for IPv4 public access + _neutron_configure_router_v4 + fi + + if [[ "$IP_VERSION" =~ .*6 ]]; then + # Configure router for IPv6 public access + _neutron_configure_router_v6 + fi + fi +} + +# Create private IPv4 subnet +function _neutron_create_private_subnet_v4 { + local project_id=$1 + local subnet_params="--tenant-id $project_id " + subnet_params+="--ip_version 4 " + subnet_params+="--gateway $NETWORK_GATEWAY " + subnet_params+="--name $PRIVATE_SUBNET_NAME " + subnet_params+="$NET_ID $FIXED_RANGE" + local subnet_id + subnet_id=$(neutron --os-cloud devstack-admin --os-region "$REGION_NAME" subnet-create $subnet_params | grep ' id ' | get_field 2) + die_if_not_set $LINENO subnet_id "Failure creating private IPv4 subnet for $project_id" + echo $subnet_id +} + +# Create private IPv6 subnet +function _neutron_create_private_subnet_v6 { + local project_id=$1 + die_if_not_set $LINENO IPV6_RA_MODE "IPV6 RA Mode not set" + die_if_not_set $LINENO IPV6_ADDRESS_MODE "IPV6 Address Mode not set" + local ipv6_modes="--ipv6-ra-mode $IPV6_RA_MODE --ipv6-address-mode $IPV6_ADDRESS_MODE" + local subnet_params="--tenant-id $project_id " + subnet_params+="--ip_version 6 " + subnet_params+="--gateway $IPV6_PRIVATE_NETWORK_GATEWAY " + subnet_params+="--name $IPV6_PRIVATE_SUBNET_NAME " + subnet_params+="$NET_ID $FIXED_RANGE_V6 $ipv6_modes" + local ipv6_subnet_id + ipv6_subnet_id=$(neutron --os-cloud devstack-admin --os-region "$REGION_NAME" subnet-create $subnet_params | grep ' id ' | get_field 2) + die_if_not_set $LINENO ipv6_subnet_id "Failure creating private IPv6 subnet for $project_id" + echo $ipv6_subnet_id +} + +# Create public IPv4 subnet +function _neutron_create_public_subnet_v4 { + local subnet_params+="--ip_version 4 " + subnet_params+="${Q_FLOATING_ALLOCATION_POOL:+--allocation-pool $Q_FLOATING_ALLOCATION_POOL} " + subnet_params+="--gateway $PUBLIC_NETWORK_GATEWAY " + subnet_params+="--name $PUBLIC_SUBNET_NAME " + subnet_params+="$EXT_NET_ID $FLOATING_RANGE " + subnet_params+="-- --enable_dhcp=False" + local id_and_ext_gw_ip + id_and_ext_gw_ip=$(neutron --os-cloud devstack-admin --os-region "$REGION_NAME" subnet-create $subnet_params | grep -e 'gateway_ip' -e ' id ') + die_if_not_set $LINENO id_and_ext_gw_ip "Failure creating public IPv4 subnet" + echo $id_and_ext_gw_ip +} + +# Create public IPv6 subnet +function _neutron_create_public_subnet_v6 { + local subnet_params="--ip_version 6 " + subnet_params+="--gateway $IPV6_PUBLIC_NETWORK_GATEWAY " + subnet_params+="--name $IPV6_PUBLIC_SUBNET_NAME " + subnet_params+="$EXT_NET_ID $IPV6_PUBLIC_RANGE " + subnet_params+="-- --enable_dhcp=False" + local ipv6_id_and_ext_gw_ip + ipv6_id_and_ext_gw_ip=$(neutron --os-cloud devstack-admin --os-region "$REGION_NAME" subnet-create $subnet_params | grep -e 'gateway_ip' -e ' id ') + die_if_not_set $LINENO ipv6_id_and_ext_gw_ip "Failure creating an IPv6 public subnet" + echo $ipv6_id_and_ext_gw_ip +} + +# Configure neutron router for IPv4 public access +function _neutron_configure_router_v4 { + neutron --os-cloud devstack-admin --os-region "$REGION_NAME" router-interface-add $ROUTER_ID $SUBNET_ID + # Create a public subnet on the external network + local id_and_ext_gw_ip + id_and_ext_gw_ip=$(_neutron_create_public_subnet_v4 $EXT_NET_ID) + local ext_gw_ip + ext_gw_ip=$(echo $id_and_ext_gw_ip | get_field 2) + PUB_SUBNET_ID=$(echo $id_and_ext_gw_ip | get_field 5) + # Configure the external network as the default router gateway + neutron --os-cloud devstack-admin --os-region "$REGION_NAME" router-gateway-set $ROUTER_ID $EXT_NET_ID + + # This logic is specific to using the l3-agent for layer 3 + if is_service_enabled q-l3; then + # Configure and enable public bridge + local ext_gw_interface="none" + if is_neutron_ovs_base_plugin; then + ext_gw_interface=$(_neutron_get_ext_gw_interface) + elif [[ "$Q_AGENT" = "linuxbridge" ]]; then + # Search for the brq device the neutron router and network for $FIXED_RANGE + # will be using. + # e.x. brq3592e767-da for NET_ID 3592e767-da66-4bcb-9bec-cdb03cd96102 + ext_gw_interface=brq${EXT_NET_ID:0:11} + fi + if [[ "$ext_gw_interface" != "none" ]]; then + local cidr_len=${FLOATING_RANGE#*/} + local testcmd="ip -o link | grep -q $ext_gw_interface" + test_with_retry "$testcmd" "$ext_gw_interface creation failed" + if [[ $(ip addr show dev $ext_gw_interface | grep -c $ext_gw_ip) == 0 && ( $Q_USE_PROVIDERNET_FOR_PUBLIC == "False" || $Q_USE_PUBLIC_VETH == "True" ) ]]; then + sudo ip addr add $ext_gw_ip/$cidr_len dev $ext_gw_interface + sudo ip link set $ext_gw_interface up + fi + ROUTER_GW_IP=$(neutron --os-cloud devstack-admin --os-region "$REGION_NAME" port-list -c fixed_ips -c device_owner | grep router_gateway | awk -F'ip_address' '{ print $2 }' | cut -f3 -d\" | tr '\n' ' ') + die_if_not_set $LINENO ROUTER_GW_IP "Failure retrieving ROUTER_GW_IP" + sudo ip route replace $FIXED_RANGE via $ROUTER_GW_IP + fi + _neutron_set_router_id + fi +} + +# Configure neutron router for IPv6 public access +function _neutron_configure_router_v6 { + neutron --os-cloud devstack-admin --os-region "$REGION_NAME" router-interface-add $ROUTER_ID $IPV6_SUBNET_ID + # Create a public subnet on the external network + local ipv6_id_and_ext_gw_ip + ipv6_id_and_ext_gw_ip=$(_neutron_create_public_subnet_v6 $EXT_NET_ID) + local ipv6_ext_gw_ip + ipv6_ext_gw_ip=$(echo $ipv6_id_and_ext_gw_ip | get_field 2) + local ipv6_pub_subnet_id + ipv6_pub_subnet_id=$(echo $ipv6_id_and_ext_gw_ip | get_field 5) + + # If the external network has not already been set as the default router + # gateway when configuring an IPv4 public subnet, do so now + if [[ "$IP_VERSION" == "6" ]]; then + neutron --os-cloud devstack-admin --os-region "$REGION_NAME" router-gateway-set $ROUTER_ID $EXT_NET_ID + fi + + # This logic is specific to using the l3-agent for layer 3 + if is_service_enabled q-l3; then + # Ensure IPv6 forwarding is enabled on the host + sudo sysctl -w net.ipv6.conf.all.forwarding=1 + # Configure and enable public bridge + # Override global IPV6_ROUTER_GW_IP with the true value from neutron + IPV6_ROUTER_GW_IP=$(neutron --os-cloud devstack-admin --os-region "$REGION_NAME" port-list -c fixed_ips | grep $ipv6_pub_subnet_id | awk -F'ip_address' '{ print $2 }' | cut -f3 -d\" | tr '\n' ' ') + die_if_not_set $LINENO IPV6_ROUTER_GW_IP "Failure retrieving IPV6_ROUTER_GW_IP" + + if is_neutron_ovs_base_plugin; then + local ext_gw_interface + ext_gw_interface=$(_neutron_get_ext_gw_interface) + local ipv6_cidr_len=${IPV6_PUBLIC_RANGE#*/} + + # Configure interface for public bridge + sudo ip -6 addr add $ipv6_ext_gw_ip/$ipv6_cidr_len dev $ext_gw_interface + sudo ip -6 route replace $FIXED_RANGE_V6 via $IPV6_ROUTER_GW_IP dev $ext_gw_interface + fi + _neutron_set_router_id + fi +} diff --git a/lib/template b/lib/template index 08d10bbf71..b92fb40483 100644 --- a/lib/template +++ b/lib/template @@ -35,8 +35,8 @@ XXXX_DIR=$DEST/XXXX XXX_CONF_DIR=/etc/XXXX -# Entry Points -# ------------ +# Functions +# --------- # Test if any XXXX services are enabled # is_XXXX_enabled @@ -62,6 +62,11 @@ function configure_XXXX { : } +# create_XXXX_accounts() - Create required service accounts +function create_XXXX_accounts { + : +} + # init_XXXX() - Initialize databases, etc. function init_XXXX { # clean up from previous (possibly aborted) runs diff --git a/stack.sh b/stack.sh index 87f85dbb1b..44ca0cbff9 100755 --- a/stack.sh +++ b/stack.sh @@ -558,6 +558,7 @@ source $TOP_DIR/lib/nova source $TOP_DIR/lib/cinder source $TOP_DIR/lib/swift source $TOP_DIR/lib/heat +source $TOP_DIR/lib/neutron source $TOP_DIR/lib/neutron-legacy source $TOP_DIR/lib/ldap source $TOP_DIR/lib/dstat @@ -1074,7 +1075,7 @@ if is_service_enabled neutron; then configure_neutron # Run init_neutron only on the node hosting the Neutron API server - if is_service_enabled $DATABASE_BACKENDS && is_service_enabled q-svc; then + if is_service_enabled $DATABASE_BACKENDS && is_service_enabled neutron; then init_neutron fi fi @@ -1141,7 +1142,7 @@ if is_service_enabled nova; then # Additional Nova configuration that is dependent on other services if is_service_enabled neutron; then - create_nova_conf_neutron + configure_neutron_nova elif is_service_enabled n-net; then create_nova_conf_nova_network fi @@ -1218,7 +1219,11 @@ if is_service_enabled n-api; then start_nova_api fi -if is_service_enabled q-svc; then +if is_service_enabled neutron-api; then + echo_summary "Starting Neutron" + start_neutron_api + # check_neutron_third_party_integration +elif is_service_enabled q-svc; then echo_summary "Starting Neutron" start_neutron_service_and_check check_neutron_third_party_integration @@ -1239,7 +1244,7 @@ elif is_service_enabled $DATABASE_BACKENDS && is_service_enabled n-net; then fi if is_service_enabled neutron; then - start_neutron_agents + start_neutron fi # Once neutron agents are started setup initial network elements if is_service_enabled q-svc && [[ "$NEUTRON_CREATE_INITIAL_NETWORKS" == "True" ]]; then @@ -1247,6 +1252,7 @@ if is_service_enabled q-svc && [[ "$NEUTRON_CREATE_INITIAL_NETWORKS" == "True" ] create_neutron_initial_network setup_neutron_debug fi + if is_service_enabled nova; then echo_summary "Starting Nova" start_nova diff --git a/unstack.sh b/unstack.sh index 83703ec28a..a69b2187ce 100755 --- a/unstack.sh +++ b/unstack.sh @@ -66,6 +66,7 @@ source $TOP_DIR/lib/nova source $TOP_DIR/lib/cinder source $TOP_DIR/lib/swift source $TOP_DIR/lib/heat +source $TOP_DIR/lib/neutron source $TOP_DIR/lib/neutron-legacy source $TOP_DIR/lib/ldap source $TOP_DIR/lib/dstat