Refactored into quantum gateway
This commit is contained in:
parent
e578fd74f5
commit
be10baf149
@ -6,6 +6,5 @@
|
|||||||
<pydev_property name="org.python.pydev.PYTHON_PROJECT_INTERPRETER">Default</pydev_property>
|
<pydev_property name="org.python.pydev.PYTHON_PROJECT_INTERPRETER">Default</pydev_property>
|
||||||
<pydev_pathproperty name="org.python.pydev.PROJECT_SOURCE_PATH">
|
<pydev_pathproperty name="org.python.pydev.PROJECT_SOURCE_PATH">
|
||||||
<path>/quantum/hooks</path>
|
<path>/quantum/hooks</path>
|
||||||
<path>/quantum/files</path>
|
|
||||||
</pydev_pathproperty>
|
</pydev_pathproperty>
|
||||||
</pydev_project>
|
</pydev_project>
|
||||||
|
87
README.md
87
README.md
@ -3,9 +3,9 @@ Overview
|
|||||||
|
|
||||||
Quantum provides flexible software defined networking (SDN) for OpenStack.
|
Quantum provides flexible software defined networking (SDN) for OpenStack.
|
||||||
|
|
||||||
This charm is designed to be used in conjunction with the 'quantum-agent'
|
This charm is designed to be used in conjunction with the rest of the OpenStack
|
||||||
charm (and the rest of the OpenStack related charms in the charm store) to
|
related charms in the charm store) to virtualized the network that Nova Compute
|
||||||
virtualized the network that Nova Compute instances plug into.
|
instances plug into.
|
||||||
|
|
||||||
Its designed as a replacement for nova-network; however it does not yet
|
Its designed as a replacement for nova-network; however it does not yet
|
||||||
support all of the features as nova-network (such as multihost) so may not
|
support all of the features as nova-network (such as multihost) so may not
|
||||||
@ -14,8 +14,8 @@ be suitable for all.
|
|||||||
Quantum supports a rich plugin/extension framework for propriety networking
|
Quantum supports a rich plugin/extension framework for propriety networking
|
||||||
solutions and supports (in core) Nicira NVP, NEC, Cisco and others...
|
solutions and supports (in core) Nicira NVP, NEC, Cisco and others...
|
||||||
|
|
||||||
The charm currently only supports the fully free OpenvSwitch plugin and
|
The Openstack charms currently only support the fully free OpenvSwitch plugin
|
||||||
implements the 'Provider Router with Private Networks' use case.
|
and implements the 'Provider Router with Private Networks' use case.
|
||||||
|
|
||||||
See the upstream [Quantum documentation](http://docs.openstack.org/trunk/openstack-network/admin/content/use_cases_single_router.html)
|
See the upstream [Quantum documentation](http://docs.openstack.org/trunk/openstack-network/admin/content/use_cases_single_router.html)
|
||||||
for more details.
|
for more details.
|
||||||
@ -24,70 +24,32 @@ for more details.
|
|||||||
Usage
|
Usage
|
||||||
-----
|
-----
|
||||||
|
|
||||||
Assumming that you have already deployed OpenStack using Juju, Quantum can be
|
In order to use Quantum with Openstack, you will need to deploy the
|
||||||
added to the mix:
|
nova-compute and nova-cloud-controller charms with the network-manager
|
||||||
|
configuration set to 'Quantum':
|
||||||
|
|
||||||
juju deploy quantum
|
nova-compute:
|
||||||
juju add-relation quantum mysql
|
network-manager: Quantum
|
||||||
juju add-relation quantum rabbitmq-server
|
nova-cloud-controller:
|
||||||
juju add-relation keystone
|
network-manager: Quantum
|
||||||
juju add-relation nova-cloud-controller
|
|
||||||
|
|
||||||
This will setup a Quantum API server and the DHCP and L3 routing agents on the
|
This decision must be made prior to deploying Openstack with Juju as
|
||||||
deployed servce unit. ATM it does not support multiple units (WIP).
|
Quantum is deployed baked into these charms from install onwards:
|
||||||
|
|
||||||
To then integrate Quantum with nova-compute do:
|
juju deploy --config config.yaml nova-compute
|
||||||
|
juju deploy --config config.yaml nova-cloud-controller
|
||||||
|
juju add-relation nova-compute nova-cloud-controller
|
||||||
|
|
||||||
juju deploy quantum-agent
|
The Quantum Gateway can then be added to the deploying:
|
||||||
juju add-relation quantum-agent mysql
|
|
||||||
juju add-relation quantum-agent rabbitmq-server
|
|
||||||
juju add-relation quantum-agent nova-compute
|
|
||||||
|
|
||||||
All of the units supporting nova-compute will now be reconfigured to support
|
juju deploy quantum-gateway
|
||||||
use of Quantum instead of nova-network.
|
juju add-relation quantum-gateway mysql
|
||||||
|
juju add-relation quantum-gateway rabbitmq-server
|
||||||
|
juju add-relation quantum-gateway nova-cloud-controller
|
||||||
|
|
||||||
Configuration
|
The gateway provides two key services; L3 network routing and DHCP services.
|
||||||
-------------
|
|
||||||
|
|
||||||
External Network Configuration
|
These are both required in a fully functional Quantum Openstack deployment.
|
||||||
==============================
|
|
||||||
|
|
||||||
The quantum charm supports a number of configuration options; at a minimum you
|
|
||||||
will need to specify the external network configuration for you environment.
|
|
||||||
These are used to configure the 'external network' in quantum which provides
|
|
||||||
outbound public network access from tenant private networks and handles the
|
|
||||||
allocation of floating IP's for inbound public network access.
|
|
||||||
|
|
||||||
You will also need to provide the 'ext-port' configuration element; this should
|
|
||||||
be the port on the server which should be used for routing external/public
|
|
||||||
network traffic. This does of course mean that you need a server with more than
|
|
||||||
one network interface to deploy the quantum charm.
|
|
||||||
|
|
||||||
Example minimal configuration:
|
|
||||||
|
|
||||||
quantum:
|
|
||||||
ext-port: eth1
|
|
||||||
conf-ext-net: yes
|
|
||||||
ext-net-cidr: 192.168.21.0/24
|
|
||||||
ext-net-gateway: 192.168.21.1
|
|
||||||
pool-floating-start: 192.168.21.130
|
|
||||||
pool-floating-end: 192.168.21.200
|
|
||||||
|
|
||||||
The IP addresses above are for illustrative purposes only; in a real environment
|
|
||||||
these would be configured with actual routable public addresses.
|
|
||||||
|
|
||||||
Tenant Network Configuration
|
|
||||||
============================
|
|
||||||
|
|
||||||
The quantum charm provides a helper script for creating tenant networks:
|
|
||||||
|
|
||||||
quantum-net-create -t admin -r provider-router \
|
|
||||||
-N 192.168.21.1 adminnet 10.5.5.0/24
|
|
||||||
|
|
||||||
will create a new network for the admin tenant called 'adminnet' with a
|
|
||||||
default gateway of 10.5.5.1, a DNS nameserver at 192.168.21.1 and a dhcp
|
|
||||||
allocation range of 10.5.5.2 to 10.5.5.254; external network access is
|
|
||||||
provided through the 'provider-router' (created by the charm itself).
|
|
||||||
|
|
||||||
TODO
|
TODO
|
||||||
----
|
----
|
||||||
@ -96,4 +58,3 @@ TODO
|
|||||||
* Support VLAN in addition to GRE+OpenFlow for L2 separation.
|
* Support VLAN in addition to GRE+OpenFlow for L2 separation.
|
||||||
* High Avaliability.
|
* High Avaliability.
|
||||||
* Support for propriety plugins for Quantum.
|
* Support for propriety plugins for Quantum.
|
||||||
|
|
||||||
|
51
config.yaml
51
config.yaml
@ -18,55 +18,12 @@ options:
|
|||||||
default: RegionOne
|
default: RegionOne
|
||||||
description: |
|
description: |
|
||||||
OpenStack region that this quantum service supports.
|
OpenStack region that this quantum service supports.
|
||||||
conf-ext-net:
|
openstack-origin:
|
||||||
type: string
|
|
||||||
description: Configure external network for quantum using
|
|
||||||
network configuration below.
|
|
||||||
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-gw-ip:
|
|
||||||
type: string
|
|
||||||
description: |
|
|
||||||
IP address to assign to external bridge for external network
|
|
||||||
access. Only use this when configuraing a single instance
|
|
||||||
quantum gateway deployment.
|
|
||||||
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.
|
|
||||||
source:
|
|
||||||
type: string
|
type: string
|
||||||
description: |
|
description: |
|
||||||
Optional configuration to support use of additional sources such as:
|
Optional configuration to support use of additional sources such as:
|
||||||
.
|
.
|
||||||
- ppa:myteam/ppa
|
- ppa:myteam/ppa
|
||||||
- cloud:precise-proposed/folsom
|
- cloud:precise-folsom/proposed
|
||||||
- http://my.archive.com/ubuntu main
|
- cloud:precise-folsom
|
||||||
.
|
- deb http://my.archive.com/ubuntu main|KEYID
|
||||||
The last option should be used in conjunction with the key configuration
|
|
||||||
option.
|
|
||||||
key:
|
|
||||||
type: string
|
|
||||||
description: |
|
|
||||||
Key ID to import to the apt keyring to support use with arbitary source
|
|
||||||
configuration from outside of Launchpad archives or PPA's.
|
|
||||||
|
@ -1,143 +0,0 @@
|
|||||||
#!/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')
|
|
@ -4,15 +4,13 @@ import utils
|
|||||||
import sys
|
import sys
|
||||||
import quantum_utils as qutils
|
import quantum_utils as qutils
|
||||||
import os
|
import os
|
||||||
import shutil
|
|
||||||
|
|
||||||
PLUGIN = utils.config_get('plugin')
|
PLUGIN = utils.config_get('plugin')
|
||||||
|
|
||||||
|
|
||||||
def install():
|
def install():
|
||||||
utils.configure_source()
|
utils.configure_source()
|
||||||
shutil.copy('files/create_tenant_net.py', '/usr/bin/quantum-net-create')
|
if PLUGIN in qutils.GATEWAY_PKGS.keys():
|
||||||
if PLUGIN in qutils.PLUGIN_PKGS.keys():
|
|
||||||
if PLUGIN == qutils.OVS:
|
if PLUGIN == qutils.OVS:
|
||||||
# Install OVS DKMS first to ensure that the ovs module
|
# Install OVS DKMS first to ensure that the ovs module
|
||||||
# loaded supports GRE tunnels
|
# loaded supports GRE tunnels
|
||||||
@ -24,12 +22,10 @@ def install():
|
|||||||
|
|
||||||
|
|
||||||
def config_changed():
|
def config_changed():
|
||||||
if PLUGIN in qutils.PLUGIN_PKGS.keys():
|
if PLUGIN in qutils.GATEWAY_PKGS.keys():
|
||||||
render_api_paste_conf()
|
|
||||||
render_quantum_conf()
|
render_quantum_conf()
|
||||||
render_plugin_conf()
|
render_plugin_conf()
|
||||||
render_l3_agent_conf()
|
render_l3_agent_conf()
|
||||||
render_novarc()
|
|
||||||
if PLUGIN == qutils.OVS:
|
if PLUGIN == qutils.OVS:
|
||||||
qutils.add_bridge(qutils.INT_BRIDGE)
|
qutils.add_bridge(qutils.INT_BRIDGE)
|
||||||
qutils.add_bridge(qutils.EXT_BRIDGE)
|
qutils.add_bridge(qutils.EXT_BRIDGE)
|
||||||
@ -42,31 +38,6 @@ def config_changed():
|
|||||||
'Please provide a valid plugin config')
|
'Please provide a valid plugin config')
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
configure_networking()
|
|
||||||
|
|
||||||
|
|
||||||
def configure_networking():
|
|
||||||
keystone_conf = get_keystone_conf()
|
|
||||||
db_conf = get_db_conf()
|
|
||||||
if (utils.config_get('conf-ext-net') and
|
|
||||||
keystone_conf and
|
|
||||||
db_conf):
|
|
||||||
qutils.configure_ext_net(
|
|
||||||
username=keystone_conf['service_username'],
|
|
||||||
password=keystone_conf['service_password'],
|
|
||||||
tenant=keystone_conf['service_tenant'],
|
|
||||||
url="http://{}:{}/v2.0/".format(
|
|
||||||
keystone_conf['keystone_host'],
|
|
||||||
keystone_conf['auth_port']
|
|
||||||
),
|
|
||||||
ext_net_name=utils.config_get('ext-net-name'),
|
|
||||||
gateway_ip=utils.config_get('ext-gw-ip'),
|
|
||||||
default_gateway=utils.config_get('ext-net-gateway'),
|
|
||||||
cidr=utils.config_get('ext-net-cidr'),
|
|
||||||
start_floating_ip=utils.config_get('pool-floating-start'),
|
|
||||||
end_floating_ip=utils.config_get('pool-floating-end')
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def upgrade_charm():
|
def upgrade_charm():
|
||||||
install()
|
install()
|
||||||
@ -85,25 +56,6 @@ def render_l3_agent_conf():
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def render_api_paste_conf():
|
|
||||||
context = get_keystone_conf()
|
|
||||||
if (context and
|
|
||||||
os.path.exists(qutils.QUANTUM_API_CONF)):
|
|
||||||
with open(qutils.QUANTUM_API_CONF, "w") as conf:
|
|
||||||
conf.write(utils.render_template(
|
|
||||||
os.path.basename(qutils.QUANTUM_API_CONF),
|
|
||||||
context
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def render_novarc():
|
|
||||||
context = get_keystone_conf()
|
|
||||||
if context:
|
|
||||||
with open('/etc/quantum/novarc', "w") as conf:
|
|
||||||
conf.write(utils.render_template('novarc', context))
|
|
||||||
|
|
||||||
|
|
||||||
def render_quantum_conf():
|
def render_quantum_conf():
|
||||||
context = get_rabbit_conf()
|
context = get_rabbit_conf()
|
||||||
if (context and
|
if (context and
|
||||||
@ -132,31 +84,12 @@ def render_plugin_conf():
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def keystone_joined():
|
|
||||||
url = "http://{}:9696/".format(utils.unit_get('private-address'))
|
|
||||||
utils.relation_set(service=qutils.KEYSTONE_SERVICE,
|
|
||||||
region=utils.config_get('region'),
|
|
||||||
public_url=url,
|
|
||||||
admin_url=url,
|
|
||||||
internal_url=url)
|
|
||||||
|
|
||||||
|
|
||||||
def keystone_changed():
|
|
||||||
render_l3_agent_conf()
|
|
||||||
render_api_paste_conf()
|
|
||||||
render_novarc()
|
|
||||||
utils.restart(*qutils.GATEWAY_AGENTS[PLUGIN])
|
|
||||||
notify_agents()
|
|
||||||
configure_networking()
|
|
||||||
|
|
||||||
|
|
||||||
def get_keystone_conf():
|
def get_keystone_conf():
|
||||||
for relid in utils.relation_ids('identity-service'):
|
for relid in utils.relation_ids('quantum-network-service'):
|
||||||
for unit in utils.relation_list(relid):
|
for unit in utils.relation_list(relid):
|
||||||
conf = {
|
conf = {
|
||||||
"keystone_host": utils.relation_get('private-address',
|
"keystone_host": utils.relation_get('keystone_host',
|
||||||
unit, relid),
|
unit, relid),
|
||||||
"token": utils.relation_get('admin_token', unit, relid),
|
|
||||||
"service_port": utils.relation_get('service_port',
|
"service_port": utils.relation_get('service_port',
|
||||||
unit, relid),
|
unit, relid),
|
||||||
"auth_port": utils.relation_get('auth_port', unit, relid),
|
"auth_port": utils.relation_get('auth_port', unit, relid),
|
||||||
@ -181,7 +114,6 @@ def db_joined():
|
|||||||
def db_changed():
|
def db_changed():
|
||||||
render_plugin_conf()
|
render_plugin_conf()
|
||||||
utils.restart(*qutils.GATEWAY_AGENTS[PLUGIN])
|
utils.restart(*qutils.GATEWAY_AGENTS[PLUGIN])
|
||||||
configure_networking()
|
|
||||||
|
|
||||||
|
|
||||||
def get_db_conf():
|
def get_db_conf():
|
||||||
@ -226,33 +158,20 @@ def get_rabbit_conf():
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
def nm_joined():
|
def nm_changed():
|
||||||
keystone_conf = get_keystone_conf()
|
render_l3_agent_conf()
|
||||||
if keystone_conf:
|
utils.restart(*qutils.GATEWAY_AGENTS[PLUGIN])
|
||||||
utils.relation_set(**keystone_conf) # IGNORE:W0142
|
|
||||||
utils.relation_set(plugin=PLUGIN)
|
|
||||||
|
|
||||||
|
|
||||||
def notify_agents():
|
|
||||||
keystone_conf = get_keystone_conf()
|
|
||||||
if keystone_conf:
|
|
||||||
for relid in utils.relation_ids('quantum-network-service'):
|
|
||||||
utils.relation_set(rid=relid, # IGNORE:W0142
|
|
||||||
plugin=PLUGIN,
|
|
||||||
**keystone_conf)
|
|
||||||
|
|
||||||
|
|
||||||
utils.do_hooks({
|
utils.do_hooks({
|
||||||
"install": install,
|
"install": install,
|
||||||
"config-changed": config_changed,
|
"config-changed": config_changed,
|
||||||
"upgrade-charm": upgrade_charm,
|
"upgrade-charm": upgrade_charm,
|
||||||
"identity-service-relation-joined": keystone_joined,
|
|
||||||
"identity-service-relation-changed": keystone_changed,
|
|
||||||
"shared-db-relation-joined": db_joined,
|
"shared-db-relation-joined": db_joined,
|
||||||
"shared-db-relation-changed": db_changed,
|
"shared-db-relation-changed": db_changed,
|
||||||
"amqp-relation-joined": amqp_joined,
|
"amqp-relation-joined": amqp_joined,
|
||||||
"amqp-relation-changed": amqp_changed,
|
"amqp-relation-changed": amqp_changed,
|
||||||
"quantum-network-service-relation-joined": nm_joined,
|
"quantum-network-service-relation-changed": nm_changed,
|
||||||
})
|
})
|
||||||
|
|
||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
|
@ -1 +0,0 @@
|
|||||||
hooks.py
|
|
@ -1 +0,0 @@
|
|||||||
hooks.py
|
|
@ -1,12 +1,6 @@
|
|||||||
import subprocess
|
import subprocess
|
||||||
import shutil
|
from utils import juju_log as log
|
||||||
from utils import juju_log as log, install, start, stop
|
|
||||||
|
|
||||||
try:
|
|
||||||
from quantumclient.v2_0 import client
|
|
||||||
except ImportError:
|
|
||||||
install('python-quantumclient')
|
|
||||||
from quantumclient.v2_0 import client
|
|
||||||
|
|
||||||
OVS = "ovs"
|
OVS = "ovs"
|
||||||
NVP = "nvp"
|
NVP = "nvp"
|
||||||
@ -31,11 +25,9 @@ PLUGIN_CONF = {
|
|||||||
|
|
||||||
GATEWAY_PKGS = {
|
GATEWAY_PKGS = {
|
||||||
OVS: [
|
OVS: [
|
||||||
"quantum-plugin-openvswitch",
|
|
||||||
"quantum-plugin-openvswitch-agent",
|
"quantum-plugin-openvswitch-agent",
|
||||||
"quantum-l3-agent",
|
"quantum-l3-agent",
|
||||||
"quantum-dhcp-agent",
|
"quantum-dhcp-agent",
|
||||||
'quantum-server',
|
|
||||||
'python-mysqldb'
|
'python-mysqldb'
|
||||||
],
|
],
|
||||||
NVP: [
|
NVP: [
|
||||||
@ -43,22 +35,9 @@ GATEWAY_PKGS = {
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
PLUGIN_PKGS = {
|
|
||||||
OVS: [
|
|
||||||
"quantum-plugin-openvswitch-agent"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
PLUGIN_AGENT = {
|
|
||||||
OVS: [
|
|
||||||
"quantum-plugin-openvswitch-agent"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
GATEWAY_AGENTS = {
|
GATEWAY_AGENTS = {
|
||||||
OVS: [
|
OVS: [
|
||||||
"quantum-plugin-openvswitch-agent",
|
"quantum-plugin-openvswitch-agent",
|
||||||
"quantum-server",
|
|
||||||
"quantum-l3-agent",
|
"quantum-l3-agent",
|
||||||
"quantum-dhcp-agent"
|
"quantum-dhcp-agent"
|
||||||
]
|
]
|
||||||
@ -70,12 +49,14 @@ KEYSTONE_SERVICE = "quantum"
|
|||||||
|
|
||||||
QUANTUM_CONF = "/etc/quantum/quantum.conf"
|
QUANTUM_CONF = "/etc/quantum/quantum.conf"
|
||||||
L3_AGENT_CONF = "/etc/quantum/l3_agent.ini"
|
L3_AGENT_CONF = "/etc/quantum/l3_agent.ini"
|
||||||
QUANTUM_API_CONF = "/etc/quantum/api-paste.ini"
|
|
||||||
DHCP_AGENT_CONF = "/etc/quantum/dhcp_agent.ini"
|
DHCP_AGENT_CONF = "/etc/quantum/dhcp_agent.ini"
|
||||||
|
|
||||||
RABBIT_USER = "nova"
|
RABBIT_USER = "nova"
|
||||||
RABBIT_VHOST = "nova"
|
RABBIT_VHOST = "nova"
|
||||||
|
|
||||||
|
INT_BRIDGE = "br-int"
|
||||||
|
EXT_BRIDGE = "br-ex"
|
||||||
|
|
||||||
|
|
||||||
def add_bridge(name):
|
def add_bridge(name):
|
||||||
status = subprocess.check_output(["ovs-vsctl", "show"])
|
status = subprocess.check_output(["ovs-vsctl", "show"])
|
||||||
@ -109,104 +90,3 @@ def del_bridge_port(name, port):
|
|||||||
'Deleting port {} from bridge {}'.format(port, name))
|
'Deleting port {} from bridge {}'.format(port, name))
|
||||||
subprocess.check_call(["ovs-vsctl", "del-port", name, port])
|
subprocess.check_call(["ovs-vsctl", "del-port", name, port])
|
||||||
subprocess.check_call(["ip", "link", "set", port, "down"])
|
subprocess.check_call(["ip", "link", "set", port, "down"])
|
||||||
|
|
||||||
|
|
||||||
QEMU_CONF = '/etc/libvirt/qemu.conf'
|
|
||||||
|
|
||||||
|
|
||||||
def configure_libvirt():
|
|
||||||
log('INFO',
|
|
||||||
'Configuring default permissions in libvirt-bin')
|
|
||||||
shutil.copyfile('files/qemu.conf',
|
|
||||||
QEMU_CONF)
|
|
||||||
stop('libvirt-bin')
|
|
||||||
start('libvirt-bin')
|
|
||||||
|
|
||||||
|
|
||||||
EXT_BRIDGE = 'br-ex'
|
|
||||||
INT_BRIDGE = 'br-int'
|
|
||||||
|
|
||||||
|
|
||||||
def configure_ext_net(username,
|
|
||||||
password,
|
|
||||||
tenant,
|
|
||||||
url,
|
|
||||||
ext_net_name,
|
|
||||||
gateway_ip,
|
|
||||||
default_gateway,
|
|
||||||
cidr,
|
|
||||||
start_floating_ip,
|
|
||||||
end_floating_ip):
|
|
||||||
|
|
||||||
ext_net_len = cidr.split('/')[1]
|
|
||||||
quantum = client.Client(username=username,
|
|
||||||
password=password,
|
|
||||||
tenant_name=tenant,
|
|
||||||
auth_url=url)
|
|
||||||
|
|
||||||
networks = quantum.list_networks(name=ext_net_name)
|
|
||||||
if len(networks['networks']) == 0:
|
|
||||||
log('INFO',
|
|
||||||
'Configuring external bridge')
|
|
||||||
network_msg = {
|
|
||||||
'network': {
|
|
||||||
'name': ext_net_name,
|
|
||||||
'router:external': True
|
|
||||||
}
|
|
||||||
}
|
|
||||||
log('INFO',
|
|
||||||
'Creating new external network definition: {}'
|
|
||||||
.format(ext_net_name))
|
|
||||||
network = quantum.create_network(network_msg)
|
|
||||||
log('INFO',
|
|
||||||
'New external network created: {}'
|
|
||||||
.format(network['network']['id']))
|
|
||||||
|
|
||||||
subnet_msg = {
|
|
||||||
'subnet': {
|
|
||||||
'name': '{}_subnet'.format(ext_net_name),
|
|
||||||
'network_id': network['network']['id'],
|
|
||||||
'enable_dhcp': False,
|
|
||||||
'gateway_ip': default_gateway,
|
|
||||||
'cidr': cidr,
|
|
||||||
'ip_version': 4,
|
|
||||||
'allocation_pools': [
|
|
||||||
{
|
|
||||||
'start': start_floating_ip,
|
|
||||||
'end': end_floating_ip
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
log('INFO',
|
|
||||||
'Creating new subnet for {}'.format(ext_net_name))
|
|
||||||
subnet = quantum.create_subnet(subnet_msg)
|
|
||||||
log('INFO',
|
|
||||||
'New subnet created: {}'.format(subnet['subnet']['id']))
|
|
||||||
|
|
||||||
log('INFO',
|
|
||||||
'Creating provider router for external network access')
|
|
||||||
router = quantum.create_router({'router': {'name': 'provider-router'}})
|
|
||||||
log('INFO',
|
|
||||||
'New router created: {}'.format(router['router']['id']))
|
|
||||||
|
|
||||||
log('INFO',
|
|
||||||
'Plugging router into ext_net')
|
|
||||||
router = \
|
|
||||||
quantum.add_gateway_router(
|
|
||||||
router=router['router']['id'],
|
|
||||||
body={'network_id': network['network']['id']}
|
|
||||||
)
|
|
||||||
log('INFO',
|
|
||||||
'Router connected to ext_net')
|
|
||||||
|
|
||||||
if gateway_ip:
|
|
||||||
log('INFO',
|
|
||||||
'Configuring external bridge connectivity')
|
|
||||||
subprocess.check_call(['ip', 'addr', 'flush',
|
|
||||||
'dev', EXT_BRIDGE])
|
|
||||||
subprocess.check_call(['ip', 'addr', 'add',
|
|
||||||
'{}/{}'.format(gateway_ip, ext_net_len),
|
|
||||||
'dev', EXT_BRIDGE])
|
|
||||||
subprocess.check_call(['ip', 'link', 'set',
|
|
||||||
EXT_BRIDGE, 'up'])
|
|
||||||
|
@ -62,9 +62,15 @@ CLOUD_ARCHIVE = \
|
|||||||
deb http://ubuntu-cloud.archive.canonical.com/ubuntu {} main
|
deb http://ubuntu-cloud.archive.canonical.com/ubuntu {} main
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
CLOUD_ARCHIVE_POCKETS = {
|
||||||
|
'folsom': 'precise-updates/folsom',
|
||||||
|
'folsom/updates': 'precise-updates/folsom',
|
||||||
|
'folsom/proposed': 'precise-proposed/folsom'
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
def configure_source():
|
def configure_source():
|
||||||
source = str(config_get('source'))
|
source = str(config_get('openstack-origin'))
|
||||||
if not source:
|
if not source:
|
||||||
return
|
return
|
||||||
if source.startswith('ppa:'):
|
if source.startswith('ppa:'):
|
||||||
@ -77,18 +83,22 @@ def configure_source():
|
|||||||
install('ubuntu-cloud-keyring')
|
install('ubuntu-cloud-keyring')
|
||||||
pocket = source.split(':')[1]
|
pocket = source.split(':')[1]
|
||||||
with open('/etc/apt/sources.list.d/cloud-archive.list', 'w') as apt:
|
with open('/etc/apt/sources.list.d/cloud-archive.list', 'w') as apt:
|
||||||
apt.write(CLOUD_ARCHIVE.format(pocket))
|
apt.write(CLOUD_ARCHIVE.format(CLOUD_ARCHIVE_POCKETS[pocket]))
|
||||||
if source.startswith('http:'):
|
if source.startswith('deb'):
|
||||||
with open('/etc/apt/sources.list.d/quantum.list', 'w') as apt:
|
l = len(source.split('|'))
|
||||||
apt.write("deb " + source + "\n")
|
if l == 2:
|
||||||
key = config_get('key')
|
(apt_line, key) = source.split('|')
|
||||||
if key:
|
|
||||||
cmd = [
|
cmd = [
|
||||||
'apt-key',
|
'apt-key',
|
||||||
'adv', '--keyserver keyserver.ubuntu.com',
|
'adv', '--keyserver keyserver.ubuntu.com',
|
||||||
'--recv-keys', key
|
'--recv-keys', key
|
||||||
]
|
]
|
||||||
subprocess.check_call(cmd)
|
subprocess.check_call(cmd)
|
||||||
|
elif l == 1:
|
||||||
|
apt_line = source
|
||||||
|
|
||||||
|
with open('/etc/apt/sources.list.d/quantum.list', 'w') as apt:
|
||||||
|
apt.write(apt_line + "\n")
|
||||||
cmd = [
|
cmd = [
|
||||||
'apt-get',
|
'apt-get',
|
||||||
'update'
|
'update'
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
name: quantum
|
name: quantum-gateway
|
||||||
summary: Virtual Networking for OpenStack
|
summary: Virtual Networking for OpenStack - Quantum Gateway
|
||||||
maintainer: James Page <james.page@ubuntu.com>
|
maintainer: James Page <james.page@ubuntu.com>
|
||||||
description: |
|
description: |
|
||||||
Quantum is a virtual network service for Openstack, and a part of
|
Quantum is a virtual network service for Openstack, and a part of
|
||||||
@ -10,6 +10,9 @@ description: |
|
|||||||
from Nova VMs). The Quantum API supports extensions to provide
|
from Nova VMs). The Quantum API supports extensions to provide
|
||||||
advanced network capabilities (e.g., QoS, ACLs, network monitoring,
|
advanced network capabilities (e.g., QoS, ACLs, network monitoring,
|
||||||
etc.)
|
etc.)
|
||||||
|
.
|
||||||
|
This charm provides central Quantum networking services as part
|
||||||
|
of a Quantum based Openstack deployment
|
||||||
provides:
|
provides:
|
||||||
quantum-network-service:
|
quantum-network-service:
|
||||||
interface: quantum
|
interface: quantum
|
||||||
@ -17,6 +20,4 @@ requires:
|
|||||||
shared-db:
|
shared-db:
|
||||||
interface: mysql-shared
|
interface: mysql-shared
|
||||||
amqp:
|
amqp:
|
||||||
interface: rabbitmq
|
interface: rabbitmq
|
||||||
identity-service:
|
|
||||||
interface: keystone
|
|
@ -1,4 +0,0 @@
|
|||||||
export OS_USERNAME={{ service_username }}
|
|
||||||
export OS_PASSWORD={{ service_password }}
|
|
||||||
export OS_TENANT_NAME={{ service_tenant }}
|
|
||||||
export OS_AUTH_URL=http://{{ keystone_host }}:{{ auth_port }}/v2.0/
|
|
Loading…
x
Reference in New Issue
Block a user