Added code for configurable multiple gateway interfaces.

This commit is contained in:
Bilal Ahmad 2015-09-10 03:41:10 -07:00
parent b954ff223d
commit 43b86fdff9
6 changed files with 40 additions and 28 deletions

View File

@ -36,7 +36,7 @@ This is an early access version of the PLUMgrid Gateway charm and it is not mean
Example Config
plumgrid-gateway:
external-interface: eth1
external-interfaces: '{"node01":"eth5,eth2","node02":"eth4,eth8"}'
install_sources: 'ppa:plumgrid-team/stable'
install_keys: 'null'
plumgrid-edge:
@ -54,7 +54,7 @@ Example Config
neutron-plugin: "plumgrid"
plumgrid-virtual-ip: "192.168.100.250"
The "external-interface" config parameter should be the interface that will provide external connectivity.
The "external-interfaces" config parameter should be the interfaces that will provide external connectivity on each of the gateway nodes. Should be provided as a json in a string with hostname and interface names.
Provide the source repo path for PLUMgrid Debs in 'install_sources' and the corresponding keys in 'install_keys'.
The virtual IP passed on in the neutron-api charm has to be same as the one passed in the plumgrid-director charm.

View File

@ -1,8 +1,10 @@
options:
external-interface:
default: eth1
external-interfaces:
default: '{"hostname":"eth1,eth2"}'
type: string
description: The interface that will provide external connectivity
description: |
One or multiple interfaces that will provide external connectivity on
each of the gateway nodes. Provided in form of json in a string.
lcm-ssh-key:
default: 'null'
type: string

View File

@ -7,7 +7,6 @@ from charmhelpers.core.hookenv import (
relation_ids,
related_units,
relation_get,
config,
)
from charmhelpers.contrib.openstack import context
@ -60,7 +59,6 @@ class PGGwContext(context.NeutronContext):
if not pg_ctxt:
return {}
conf = config()
pg_dir_ips = ''
pg_dir_settings = _pg_dir_settings()
single_ip = True
@ -73,12 +71,10 @@ class PGGwContext(context.NeutronContext):
pg_ctxt['local_ip'] = pg_dir_ips
unit_hostname = get_unit_hostname()
pg_ctxt['pg_hostname'] = unit_hostname
from pg_gw_utils import check_interface_type
interface_type = check_interface_type()
pg_ctxt['interface'] = interface_type
from pg_gw_utils import check_interface_type, get_gw_interfaces
pg_ctxt['interface'] = check_interface_type()
pg_ctxt['label'] = unit_hostname
pg_ctxt['fabric_mode'] = 'host'
pg_ctxt['ext_interface'] = conf['external-interface']
pg_ctxt['ext_interfaces'] = get_gw_interfaces()
return pg_ctxt

View File

@ -20,11 +20,13 @@ from collections import OrderedDict
from charmhelpers.contrib.openstack.utils import (
os_release,
)
from socket import gethostname as get_unit_hostname
import pg_gw_context
import subprocess
import time
import os
import re
import json
LXC_CONF = "/etc/libvirt/lxc.conf"
TEMPLATES = 'templates/'
@ -35,6 +37,7 @@ PG_HN_CONF = '%s/conf/etc/hostname' % PG_LXC_DATA_PATH
PG_HS_CONF = '%s/conf/etc/hosts' % PG_LXC_DATA_PATH
PG_IFCS_CONF = '%s/conf/pg/ifcs.conf' % PG_LXC_DATA_PATH
AUTH_KEY_PATH = '%s/root/.ssh/authorized_keys' % PG_LXC_DATA_PATH
IFC_LIST_GW = '/var/run/plumgrid/lxc/ifc_list_gateway'
SUDOERS_CONF = '/etc/sudoers.d/ifc_ctl_sudoers'
@ -103,6 +106,7 @@ def ensure_files():
write_file(SUDOERS_CONF,
"\nnova ALL=(root) NOPASSWD: /opt/pg/bin/ifc_ctl_pp *\n",
owner='root', group='root', perms=0o644)
_exec_cmd(cmd=['rm', '-f', IFC_LIST_GW])
def restart_pg():
@ -155,6 +159,23 @@ def check_interface_type():
return default_interface
def get_gw_interfaces():
'''
Gateway node can have multiple interfaces. This function parses json
provided in config to get all gateway interfaces for this node.
'''
node_interfaces = ['eth1']
try:
all_interfaces = json.loads(config('external-interfaces'))
except ValueError:
log("Invalid JSON")
return node_interfaces
hostname = get_unit_hostname()
if hostname in all_interfaces:
node_interfaces = all_interfaces[hostname].split(',')
return node_interfaces
def ensure_mtu():
'''
Ensures required MTU of the underlying networking of the node.

View File

@ -1,6 +1,7 @@
{{ interface }} = fabric_core host
{% if ext_interface -%}
{{ ext_interface }} = access_phys
{% if ext_interfaces -%}
{% for ip in ext_interfaces -%}
{{ ip }} = access_phys
{% endfor -%}
{% endif -%}

View File

@ -5,7 +5,6 @@ import pg_gw_utils as utils
import charmhelpers
TO_PATCH = [
'config',
'get_unit_hostname',
]
@ -22,8 +21,6 @@ class PGGwContextTest(CharmTestCase):
def setUp(self):
super(PGGwContextTest, self).setUp(context, TO_PATCH)
self.config.side_effect = self.test_config.get
self.test_config.set('external-interface', 'eth1')
def tearDown(self):
super(PGGwContextTest, self).tearDown()
@ -41,7 +38,9 @@ class PGGwContextTest(CharmTestCase):
@patch.object(charmhelpers.contrib.openstack.context,
'neutron_plugin_attribute')
@patch.object(utils, 'check_interface_type')
def test_neutroncc_context_api_rel(self, _int_type, _npa, _pg_dir_settings,
@patch.object(utils, 'get_gw_interfaces')
def test_neutroncc_context_api_rel(self, _gw_int, _int_type,
_npa, _pg_dir_settings,
_save_flag_file, _config_flag,
_unit_get, _unit_priv_ip, _config,
_is_clus, _https, _ens_pkgs):
@ -50,16 +49,8 @@ class PGGwContextTest(CharmTestCase):
return "neutron.randomdriver"
if section == "config":
return "neutron.randomconfig"
config = {'external-interface': "eth1"}
def mock_config(key=None):
if key:
return config.get(key)
return config
self.maxDiff = None
self.config.side_effect = mock_config
_npa.side_effect = mock_npa
_unit_get.return_value = '192.168.100.201'
_unit_priv_ip.return_value = '192.168.100.201'
@ -68,9 +59,10 @@ class PGGwContextTest(CharmTestCase):
_config_flag.return_value = False
_pg_dir_settings.return_value = {'pg_dir_ip': '192.168.100.201'}
_int_type.return_value = 'juju-br0'
_gw_int.return_value = ['eth1']
napi_ctxt = context.PGGwContext()
expect = {
'ext_interface': "eth1",
'ext_interfaces': ['eth1'],
'config': 'neutron.randomconfig',
'core_plugin': 'neutron.randomdriver',
'local_ip': 'pg_dir_ip',