Various updates for quantum integration.

This commit is contained in:
James Page 2012-12-03 11:17:36 +00:00
parent 14f36158b7
commit 488e41869d
8 changed files with 352 additions and 8 deletions

View File

@ -69,6 +69,38 @@ options:
.
This configuration only has context when used with
network-manager Quantum.
conf-ext-net:
type: string
default: "no"
description: Configure external network for quantum using
network configuration below. Only used when OpenvSwitch
plugin is configured.
ext-net-name:
type: string
default: ext_net
description: |
Name of external network configuration to create for
public access to instances/floating IP's.
ext-net-cidr:
type: string
default: 192.168.21.0/24
description: |
External network addressing
ext-net-gateway:
type: string
default: 192.168.21.1
description: |
IP of the public network gateway (i.e. external router)
pool-floating-start:
type: string
default: 192.168.21.130
description: |
Start of default floating IP range.
pool-floating-end:
type: string
default: 192.168.21.200
description: |
End of default floating IP range.
config-flags:
default: None
type: string

122
files/create_ext_net.py Executable file
View File

@ -0,0 +1,122 @@
#!/usr/bin/python
from quantumclient.v2_0 import client
import optparse
import os
import sys
import logging
usage = """Usage: %prog [options] ext_net_name
For example:
%prog -g 192.168.21.1 -c 192.168.21.0/25 \\
-f 192.168.21.100:192.168.21.200 ext_net
"""
if __name__ == '__main__':
parser = optparse.OptionParser(usage)
parser.add_option("-d", "--debug",
help="Enable debug logging",
dest="debug", action="store_true", default=False)
parser.add_option("-g", "--gateway",
help="Default gateway to use.",
dest="default_gateway", action="store", default=None)
parser.add_option("-c", "--cidr",
help="CIDR of external network.",
dest="cidr", action="store", default=None)
parser.add_option("-f", "--floating-range",
help="Range of floating IP's to use (separated by :).",
dest="floating_range", action="store", default=None)
(opts, args) = parser.parse_args()
if len(args) != 1:
parser.print_help()
sys.exit(1)
if opts.debug:
logging.basicConfig(level=logging.DEBUG)
else:
logging.basicConfig(level=logging.INFO)
net_name = args[0]
subnet_name = '{}_subnet'.format(net_name)
if (opts.floating_range):
(start_floating_ip, end_floating_ip) = opts.floating_range.split(':')
else:
start_floating_ip = None
end_floating_ip = None
quantum = client.Client(username=os.environ['OS_USERNAME'],
password=os.environ['OS_PASSWORD'],
tenant_name=os.environ['OS_TENANT_NAME'],
auth_url=os.environ['OS_AUTH_URL'])
networks = quantum.list_networks(name=net_name)
if len(networks['networks']) == 0:
logging.info('Configuring external bridge')
network_msg = {
'name': net_name,
'router:external': True
}
logging.info('Creating new external network definition: %s',
net_name)
network = quantum.create_network({'network': network_msg})['network']
logging.info('New external network created: %s', network['id'])
else:
logging.warning('Network %s already exists.', net_name)
network = networks['networks'][0]
subnets = quantum.list_subnets(name=subnet_name)
if len(subnets['subnets']) == 0:
subnet_msg = {
'name': subnet_name,
'network_id': network['id'],
'enable_dhcp': False,
'ip_version': 4
}
if opts.default_gateway:
subnet_msg['gateway_ip'] = opts.default_gateway
if opts.cidr:
subnet_msg['cidr'] = opts.cidr
if (start_floating_ip and end_floating_ip):
subnet_msg['allocation_pools'] = [
{
'start': start_floating_ip,
'end': end_floating_ip
}
]
logging.info('Creating new subnet for %s', net_name)
subnet = quantum.create_subnet({'subnet': subnet_msg})['subnet']
logging.info('New subnet created: %s', subnet['id'])
else:
logging.warning('Subnet %s already exists.', subnet_name)
subnet = subnets['subnets'][0]
routers = quantum.list_routers(name='provider-router')
if len(routers['routers']) == 0:
logging.info('Creating provider router for external network access')
router = quantum.create_router(
{'router': {'name': 'provider-router'}}
)['router']
logging.info('New router created: %s', (router['id']))
else:
logging.warning('Router provider-router already exists.')
router = routers['routers'][0]
ports = quantum.list_ports(device_owner='network:router_gateway',
network_id=network['id'])
if len(ports['ports']) == 0:
logging.info('Plugging router into ext_net')
router = \
quantum.add_gateway_router(
router=router['id'],
body={'network_id': network['id']}
)
logging.info('Router connected to %s', net_name)
else:
logging.warning('Router already connect to %s', net_name)

143
files/create_tenant_net.py Executable file
View File

@ -0,0 +1,143 @@
#!/usr/bin/python
from quantumclient.v2_0 import client
from keystoneclient.v2_0 import client as ks_client
import optparse
import os
import sys
import logging
usage = """Usage: %prog [options] name cidr
For example:
%prog -t admin -r provider-router admin_net 10.5.5.0/24
will create a new network for the admin tenant called 'admin_net' with a
default gateway of 10.5.5.1 and a dhcp allocation range of
10.5.5.2->10.5.5.254
"""
if __name__ == '__main__':
parser = optparse.OptionParser(usage)
parser.add_option('-t', '--tenant',
help='Tenant name to create network for',
dest='tenant', action='store',
default=None)
parser.add_option('-s', '--shared',
help='Create a shared rather than private network',
dest='shared', action='store_true', default=False)
parser.add_option('-r', '--router',
help='Router to plug new network into',
dest='router', action='store', default=None)
parser.add_option("-d", "--debug",
help="Enable debug logging",
dest="debug", action="store_true", default=False)
parser.add_option("-D", "--disable-dhcp",
help="Disable dhcp on network",
dest="dhcp", action="store_false", default=True)
parser.add_option("-N", "--dns-nameservers",
help="Comma separated list of dns servers to use.",
dest="dns_servers", action="store", default=None)
(opts, args) = parser.parse_args()
if len(args) != 2:
parser.print_help()
sys.exit(1)
if opts.debug:
logging.basicConfig(level=logging.DEBUG)
else:
logging.basicConfig(level=logging.INFO)
net_name = args[0]
subnet_name = "{}_subnet".format(net_name)
cidr = args[1]
keystone = ks_client.Client(username=os.environ['OS_USERNAME'],
password=os.environ['OS_PASSWORD'],
tenant_name=os.environ['OS_TENANT_NAME'],
auth_url=os.environ['OS_AUTH_URL'])
quantum = client.Client(username=os.environ['OS_USERNAME'],
password=os.environ['OS_PASSWORD'],
tenant_name=os.environ['OS_TENANT_NAME'],
auth_url=os.environ['OS_AUTH_URL'])
# Resolve tenant id
tenant_id = None
for tenant in [t._info for t in keystone.tenants.list()]:
if (tenant['name'] ==
(opts.tenant or os.environ['OS_TENANT_NAME'])):
tenant_id = tenant['id']
break # Tenant ID found - stop looking
if not tenant_id:
logging.error("Unable to locate tenant id for %s.", opts.tenant)
sys.exit(1)
# Create network
networks = quantum.list_networks(name=net_name)
if len(networks['networks']) == 0:
logging.info('Creating network: %s',
net_name)
network_msg = {
'network': {
'name': net_name,
'shared': opts.shared,
'tenant_id': tenant_id
}
}
network = quantum.create_network(network_msg)['network']
else:
logging.warning('Network %s already exists.', net_name)
network = networks['networks'][0]
# Create subnet
subnets = quantum.list_subnets(name=subnet_name)
if len(subnets['subnets']) == 0:
logging.info('Creating subnet for %s',
net_name)
subnet_msg = {
'subnet': {
'name': subnet_name,
'network_id': network['id'],
'enable_dhcp': opts.dhcp,
'cidr': cidr,
'ip_version': 4,
'tenant_id': tenant_id
}
}
subnet = quantum.create_subnet(subnet_msg)['subnet']
else:
logging.warning('Subnet %s already exists.', subnet_name)
subnet = subnets['subnets'][0]
# Update dns_nameservers
if opts.dns_servers:
msg = {
'subnet': {
'dns_nameservers': opts.dns_servers.split(',')
}
}
logging.info('Updating dns_nameservers (%s) for subnet %s',
opts.dns_servers,
subnet_name)
quantum.update_subnet(subnet['id'], msg)
# Plug subnet into router if provided
if opts.router:
routers = quantum.list_routers(name=opts.router)
if len(routers['routers']) == 0:
logging.error('Unable to locate provider router %s', opts.router)
sys.exit(1)
else:
# Check to see if subnet already plugged into router
ports = quantum.list_ports(device_owner='network:router_interface',
network_id=network['id'])
if len(ports['ports']) == 0:
logging.info('Adding interface from %s to %s',
opts.router, subnet_name)
router = routers['routers'][0]
quantum.add_interface_router(router['id'],
{'subnet_id': subnet['id']})
else:
logging.warning('Router already connected to subnet')

View File

@ -53,7 +53,6 @@ function configure_network_manager {
"Quantum")
set_or_update "network_api_class" "nova.network.quantumv2.api.API"
set_or_update "quantum_auth_strategy" "keystone"
set_or_update "quantum_url" "http://$(unit-get private-address):9696"
set_or_update "core_plugin" "$QUANTUM_CORE_PLUGIN" "$QUANTUM_CONF"
set_or_update "bind_host" "$(unit-get private-address)" "$QUANTUM_CONF"
if [ "$QUANTUM_PLUGIN" == "ovs" ]; then

View File

@ -47,3 +47,19 @@ if [[ -e $CHARM_DIR/lib/nova/nova-common ]] ; then
else
juju-log "Couldn't load $CHARM_DIR/lib/nova/nova-common" && exit 1
fi
function configure_quantum_networking {
if [ "$(config-get conf-ext-net)" != "no" ] &&
[ "$QUANTUM_PLUGIN" == "ovs" ] &&
[ -f /etc/quantum/novarc ] &&
[ -n "$(relation-ids shared-db)" ]; then
juju-log "Configuring external networking for quantum"
# Use helper to create external network gateway
# and router using generated credentials
. /etc/quantum/novarc
quantum-ext-net -g $(config-get ext-net-gateway) \
-c $(config-get ext-net-cidr) \
-f $(config-get pool-floating-start):$(config-get pool-floating-end) \
$(config-get ext-net-name)
fi
}

View File

@ -18,7 +18,7 @@ function install_hook {
DEBIAN_FRONTEND=noninteractive apt-get -y \
install --no-install-recommends $PACKAGES || exit 1
configure_network_manager $(config-get network-manager)
configure_network_manager $NET_MANAGER
# Configure any flags specified in deployment config
set_config_flags
@ -35,9 +35,18 @@ function install_hook {
open-port 9696
fi
# Helpers for creating external and tenant networks
cp files/create_ext_net.py /usr/bin/quantum-ext-net
cp files/create_tenant_net.py /usr/bin/quantum-tenant-net
service_ctl all stop
}
function upgrade_charm {
install_hook
service_ctl all start
}
function config_changed {
# Determine whether or not we should do an upgrade, based on whether or not
@ -54,6 +63,11 @@ function config_changed {
fi
set_config_flags
if [ "$NET_MANAGER" == "Quantum" ]; then
configure_quantum_networking
fi
service_ctl all restart
}
@ -136,6 +150,9 @@ function db_changed {
service_ctl all stop
/usr/bin/nova-manage db sync
service_ctl all start
if [ "$NET_MANAGER" == "Quantum" ]; then
configure_quantum_networking
fi
trigger_remote_service_restarts
}
@ -232,21 +249,34 @@ function keystone_changed {
set_or_update "admin_user" "$service_username" "$API_CONF"
set_or_update "admin_password" "$service_password" "$API_CONF"
if [ "$(config-get network-manager)" == "Quantum" ]; then
if [ "$NET_MANAGER" == "Quantum" ]; then
# Configure Nova for quantum
keystone_url="http://${keystone_host}:${auth_port}/v2.0"
set_or_update "quantum_url" "http://$(unit-get private-address):9696"
set_or_update "quantum_admin_tenant_name" "${service_tenant}"
set_or_update "quantum_admin_username" "${service_username}"
set_or_update "quantum_admin_password" "${service_password}"
set_or_update "quantum_admin_auth_url" "http://${keystone_host}:${auth_port}/v2.0"
set_or_update "quantum_admin_auth_url" "${keystone_url}"
# Configure API server for quantum
set_or_update "admin_tenant_name" "$service_tenant" "$QUANTUM_API_CONF" "filter:authtoken"
set_or_update "admin_user" "$service_username" "$QUANTUM_API_CONF" "filter:authtoken"
set_or_update "admin_password" "$service_password" "$QUANTUM_API_CONF" "filter:authtoken"
set_or_update "auth_host" "$keystone_host" "$QUANTUM_API_CONF" "filter:authtoken"
set_or_update "auth_port" "$auth_port" "$QUANTUM_API_CONF" "filter:authtoken"
# Save a local copy of the credentials for later use
cat > /etc/quantum/novarc << EOF
export OS_USERNAME=${service_username}
export OS_PASSWORD=${service_password}
export OS_TENANT_NAME=${service_tenant}
export OS_AUTH_URL=${keystone_url}
EOF
fi
service_ctl all restart
if [ "$NET_MANAGER" == "Quantum" ]; then
configure_quantum_networking
fi
}
volume_joined() {
@ -287,7 +317,7 @@ compute_joined() {
rids=$(relation-ids identity-service)
for rid in $rids; do
for unit in $(relation-list -r $rid); do
keystone_host=$(relation-get -r $rid keystone_host $unit)
keystone_host=$(relation-get -r $rid auth_host $unit)
if [ -n "$keystone_host" ]; then
relation-set \
keystone_host=$keystone_host \
@ -300,7 +330,6 @@ compute_joined() {
done
relation-set quantum_host=$(unit-get private-address)
fi
relation-set ec2_host=$(unit-get private-address)
}
quantum_joined() {
@ -308,7 +337,7 @@ quantum_joined() {
rids=$(relation-ids identity-service)
for rid in $rids; do
for unit in $(relation-list -r $rid); do
keystone_host=$(relation-get -r $rid keystone_host $unit)
keystone_host=$(relation-get -r $rid auth_host $unit)
if [ -n "$keystone_host" ]; then
relation-set \
keystone_host=$keystone_host \
@ -320,6 +349,7 @@ quantum_joined() {
fi
done
done
relation-set quantum_host=$(unit-get private-address)
}
arg0=$(basename $0)
@ -327,6 +357,7 @@ case $arg0 in
"start"|"stop") service_ctl all $arg0 ;;
"install") install_hook ;;
"config-changed") config_changed ;;
"upgrade-charm") upgrade_charm ;;
"amqp-relation-joined") amqp_joined ;;
"amqp-relation-changed") amqp_changed ;;
"shared-db-relation-joined") db_joined ;;

1
hooks/upgrade-charm Symbolic link
View File

@ -0,0 +1 @@
nova-cloud-controller-relations

View File

@ -1 +1 @@
149
164