Update for Python 3 execution
Refactor codebase and unit tests to default to execution under Python 3. Drop install shim as Python 3 is always present >= trusty. Drop legacy dhcp and network reassignment code from charm as a) this relies on a py3 neutronclient (not supported on older releases) and b) this function was superceeded by the ha-legacy-mode and then neutron router and network HA built in functionality. Use charmhelper provided get_host_ip as this superceeds the in charm version of this function. Change-Id: I0b28bf0851d44e85b1e856cbd97b71099faa76ae
This commit is contained in:
parent
a461b618b4
commit
b63f8687f9
1
.gitignore
vendored
1
.gitignore
vendored
@ -13,3 +13,4 @@ wily
|
|||||||
xenial
|
xenial
|
||||||
.unit-state.db
|
.unit-state.db
|
||||||
func-results.json
|
func-results.json
|
||||||
|
__pycache__
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#!/usr/bin/python
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#!/usr/bin/python
|
#!/usr/bin/env python3
|
||||||
import sys
|
import sys
|
||||||
import traceback
|
import traceback
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#!/usr/bin/python
|
#!/usr/bin/env python3
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
sys.path.append('hooks/')
|
sys.path.append('hooks/')
|
||||||
|
@ -1,20 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
# Wrapper to deal with newer Ubuntu versions that don't have py2 installed
|
|
||||||
# by default.
|
|
||||||
|
|
||||||
declare -a DEPS=('apt' 'netaddr' 'netifaces' 'pip' 'yaml')
|
|
||||||
|
|
||||||
check_and_install() {
|
|
||||||
pkg="${1}-${2}"
|
|
||||||
if ! dpkg -s ${pkg} 2>&1 > /dev/null; then
|
|
||||||
apt-get -y install ${pkg}
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
PYTHON="python"
|
|
||||||
|
|
||||||
for dep in ${DEPS[@]}; do
|
|
||||||
check_and_install ${PYTHON} ${dep}
|
|
||||||
done
|
|
||||||
|
|
||||||
exec ./hooks/install.real
|
|
1
hooks/install
Symbolic link
1
hooks/install
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
neutron_hooks.py
|
@ -1 +0,0 @@
|
|||||||
neutron_hooks.py
|
|
@ -1,16 +1,11 @@
|
|||||||
# vim: set ts=4:et
|
# vim: set ts=4:et
|
||||||
import os
|
import os
|
||||||
import uuid
|
import uuid
|
||||||
import socket
|
|
||||||
from charmhelpers.core.hookenv import (
|
from charmhelpers.core.hookenv import (
|
||||||
config,
|
config,
|
||||||
unit_get,
|
unit_get,
|
||||||
cached,
|
|
||||||
network_get_primary_address,
|
network_get_primary_address,
|
||||||
)
|
)
|
||||||
from charmhelpers.fetch import (
|
|
||||||
apt_install,
|
|
||||||
)
|
|
||||||
from charmhelpers.contrib.openstack.context import (
|
from charmhelpers.contrib.openstack.context import (
|
||||||
OSContextGenerator,
|
OSContextGenerator,
|
||||||
NeutronAPIContext,
|
NeutronAPIContext,
|
||||||
@ -21,6 +16,7 @@ from charmhelpers.contrib.hahelpers.cluster import(
|
|||||||
)
|
)
|
||||||
from charmhelpers.contrib.network.ip import (
|
from charmhelpers.contrib.network.ip import (
|
||||||
get_address_in_network,
|
get_address_in_network,
|
||||||
|
get_host_ip,
|
||||||
)
|
)
|
||||||
|
|
||||||
NEUTRON_ML2_PLUGIN = "ml2"
|
NEUTRON_ML2_PLUGIN = "ml2"
|
||||||
@ -149,24 +145,6 @@ class NeutronGatewayContext(NeutronAPIContext):
|
|||||||
return ctxt
|
return ctxt
|
||||||
|
|
||||||
|
|
||||||
@cached
|
|
||||||
def get_host_ip(hostname=None):
|
|
||||||
try:
|
|
||||||
import dns.resolver
|
|
||||||
except ImportError:
|
|
||||||
apt_install('python-dnspython', fatal=True)
|
|
||||||
import dns.resolver
|
|
||||||
hostname = hostname or unit_get('private-address')
|
|
||||||
try:
|
|
||||||
# Test to see if already an IPv4 address
|
|
||||||
socket.inet_aton(hostname)
|
|
||||||
return hostname
|
|
||||||
except socket.error:
|
|
||||||
answers = dns.resolver.query(hostname, 'A')
|
|
||||||
if answers:
|
|
||||||
return answers[0].address
|
|
||||||
|
|
||||||
|
|
||||||
SHARED_SECRET = "/etc/{}/secret.txt"
|
SHARED_SECRET = "/etc/{}/secret.txt"
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#!/usr/bin/python
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
from base64 import b64decode
|
from base64 import b64decode
|
||||||
|
|
||||||
@ -25,7 +25,6 @@ from charmhelpers.core.host import (
|
|||||||
)
|
)
|
||||||
from charmhelpers.contrib.hahelpers.cluster import(
|
from charmhelpers.contrib.hahelpers.cluster import(
|
||||||
get_hacluster_config,
|
get_hacluster_config,
|
||||||
eligible_leader
|
|
||||||
)
|
)
|
||||||
from charmhelpers.contrib.hahelpers.apache import(
|
from charmhelpers.contrib.hahelpers.apache import(
|
||||||
install_ca_cert
|
install_ca_cert
|
||||||
@ -64,7 +63,6 @@ from neutron_utils import (
|
|||||||
remove_legacy_ha_files,
|
remove_legacy_ha_files,
|
||||||
install_legacy_ha_files,
|
install_legacy_ha_files,
|
||||||
cleanup_ovs_netns,
|
cleanup_ovs_netns,
|
||||||
reassign_agent_resources,
|
|
||||||
stop_neutron_ha_monitor_daemon,
|
stop_neutron_ha_monitor_daemon,
|
||||||
use_l3ha,
|
use_l3ha,
|
||||||
NEUTRON_COMMON,
|
NEUTRON_COMMON,
|
||||||
@ -77,7 +75,7 @@ hooks = Hooks()
|
|||||||
CONFIGS = register_configs()
|
CONFIGS = register_configs()
|
||||||
|
|
||||||
|
|
||||||
@hooks.hook('install.real')
|
@hooks.hook('install')
|
||||||
@harden()
|
@harden()
|
||||||
def install():
|
def install():
|
||||||
status_set('maintenance', 'Executing pre-install')
|
status_set('maintenance', 'Executing pre-install')
|
||||||
@ -260,9 +258,6 @@ def cluster_departed():
|
|||||||
log('Unable to re-assign agent resources for failed nodes with n1kv',
|
log('Unable to re-assign agent resources for failed nodes with n1kv',
|
||||||
level=WARNING)
|
level=WARNING)
|
||||||
return
|
return
|
||||||
if not config('ha-legacy-mode') and eligible_leader(None):
|
|
||||||
reassign_agent_resources()
|
|
||||||
CONFIGS.write_all()
|
|
||||||
|
|
||||||
|
|
||||||
@hooks.hook('cluster-relation-broken')
|
@hooks.hook('cluster-relation-broken')
|
||||||
|
@ -23,8 +23,6 @@ from charmhelpers.core.hookenv import (
|
|||||||
INFO,
|
INFO,
|
||||||
ERROR,
|
ERROR,
|
||||||
config,
|
config,
|
||||||
relations_of_type,
|
|
||||||
unit_private_ip,
|
|
||||||
is_relation_made,
|
is_relation_made,
|
||||||
relation_ids,
|
relation_ids,
|
||||||
)
|
)
|
||||||
@ -51,7 +49,6 @@ from charmhelpers.contrib.openstack.utils import (
|
|||||||
git_install_requested,
|
git_install_requested,
|
||||||
git_pip_venv_dir,
|
git_pip_venv_dir,
|
||||||
git_src_dir,
|
git_src_dir,
|
||||||
get_hostname,
|
|
||||||
make_assess_status_func,
|
make_assess_status_func,
|
||||||
os_release,
|
os_release,
|
||||||
pause_unit,
|
pause_unit,
|
||||||
@ -683,7 +680,7 @@ def stop_services():
|
|||||||
plugin = config('plugin')
|
plugin = config('plugin')
|
||||||
config_files = resolve_config_files(plugin, release)
|
config_files = resolve_config_files(plugin, release)
|
||||||
svcs = set()
|
svcs = set()
|
||||||
for ctxt in config_files[config('plugin')].itervalues():
|
for ctxt in config_files[config('plugin')].values():
|
||||||
for svc in ctxt['services']:
|
for svc in ctxt['services']:
|
||||||
svcs.add(remap_service(svc))
|
svcs.add(remap_service(svc))
|
||||||
for svc in svcs:
|
for svc in svcs:
|
||||||
@ -705,7 +702,7 @@ def restart_map(release=None):
|
|||||||
config_files = resolve_config_files(plugin, release)
|
config_files = resolve_config_files(plugin, release)
|
||||||
_map = {}
|
_map = {}
|
||||||
enable_vpn_agent = 'neutron-vpn-agent' in get_packages()
|
enable_vpn_agent = 'neutron-vpn-agent' in get_packages()
|
||||||
for f, ctxt in config_files[plugin].iteritems():
|
for f, ctxt in config_files[plugin].items():
|
||||||
svcs = set()
|
svcs = set()
|
||||||
for svc in ctxt['services']:
|
for svc in ctxt['services']:
|
||||||
svcs.add(remap_service(svc))
|
svcs.add(remap_service(svc))
|
||||||
@ -725,90 +722,6 @@ def restart_map(release=None):
|
|||||||
INT_BRIDGE = "br-int"
|
INT_BRIDGE = "br-int"
|
||||||
EXT_BRIDGE = "br-ex"
|
EXT_BRIDGE = "br-ex"
|
||||||
|
|
||||||
DHCP_AGENT = "DHCP Agent"
|
|
||||||
L3_AGENT = "L3 Agent"
|
|
||||||
|
|
||||||
|
|
||||||
# TODO: make work with neutron
|
|
||||||
def reassign_agent_resources():
|
|
||||||
''' Use agent scheduler API to detect down agents and re-schedule '''
|
|
||||||
env = NetworkServiceContext()()
|
|
||||||
if not env:
|
|
||||||
log('Unable to re-assign resources at this time')
|
|
||||||
return
|
|
||||||
try:
|
|
||||||
from quantumclient.v2_0 import client
|
|
||||||
except ImportError:
|
|
||||||
''' Try to import neutronclient instead for havana+ '''
|
|
||||||
from neutronclient.v2_0 import client
|
|
||||||
|
|
||||||
auth_url = '%(auth_protocol)s://%(keystone_host)s:%(auth_port)s/v2.0' % env
|
|
||||||
quantum = client.Client(username=env['service_username'],
|
|
||||||
password=env['service_password'],
|
|
||||||
tenant_name=env['service_tenant'],
|
|
||||||
auth_url=auth_url,
|
|
||||||
region_name=env['region'])
|
|
||||||
|
|
||||||
partner_gateways = [unit_private_ip().split('.')[0]]
|
|
||||||
for partner_gateway in relations_of_type(reltype='cluster'):
|
|
||||||
gateway_hostname = get_hostname(partner_gateway['private-address'])
|
|
||||||
partner_gateways.append(gateway_hostname.partition('.')[0])
|
|
||||||
|
|
||||||
agents = quantum.list_agents(agent_type=DHCP_AGENT)
|
|
||||||
dhcp_agents = []
|
|
||||||
l3_agents = []
|
|
||||||
networks = {}
|
|
||||||
for agent in agents['agents']:
|
|
||||||
if not agent['alive']:
|
|
||||||
log('DHCP Agent %s down' % agent['id'])
|
|
||||||
for network in \
|
|
||||||
quantum.list_networks_on_dhcp_agent(
|
|
||||||
agent['id'])['networks']:
|
|
||||||
networks[network['id']] = agent['id']
|
|
||||||
else:
|
|
||||||
if agent['host'].partition('.')[0] in partner_gateways:
|
|
||||||
dhcp_agents.append(agent['id'])
|
|
||||||
|
|
||||||
agents = quantum.list_agents(agent_type=L3_AGENT)
|
|
||||||
routers = {}
|
|
||||||
for agent in agents['agents']:
|
|
||||||
if not agent['alive']:
|
|
||||||
log('L3 Agent %s down' % agent['id'])
|
|
||||||
for router in \
|
|
||||||
quantum.list_routers_on_l3_agent(
|
|
||||||
agent['id'])['routers']:
|
|
||||||
routers[router['id']] = agent['id']
|
|
||||||
else:
|
|
||||||
if agent['host'].split('.')[0] in partner_gateways:
|
|
||||||
l3_agents.append(agent['id'])
|
|
||||||
|
|
||||||
if len(dhcp_agents) == 0 or len(l3_agents) == 0:
|
|
||||||
log('Unable to relocate resources, there are %s dhcp_agents and %s \
|
|
||||||
l3_agents in this cluster' % (len(dhcp_agents), len(l3_agents)))
|
|
||||||
return
|
|
||||||
|
|
||||||
index = 0
|
|
||||||
for router_id in routers:
|
|
||||||
agent = index % len(l3_agents)
|
|
||||||
log('Moving router %s from %s to %s' %
|
|
||||||
(router_id, routers[router_id], l3_agents[agent]))
|
|
||||||
quantum.remove_router_from_l3_agent(l3_agent=routers[router_id],
|
|
||||||
router_id=router_id)
|
|
||||||
quantum.add_router_to_l3_agent(l3_agent=l3_agents[agent],
|
|
||||||
body={'router_id': router_id})
|
|
||||||
index += 1
|
|
||||||
|
|
||||||
index = 0
|
|
||||||
for network_id in networks:
|
|
||||||
agent = index % len(dhcp_agents)
|
|
||||||
log('Moving network %s from %s to %s' %
|
|
||||||
(network_id, networks[network_id], dhcp_agents[agent]))
|
|
||||||
quantum.remove_network_from_dhcp_agent(dhcp_agent=networks[network_id],
|
|
||||||
network_id=network_id)
|
|
||||||
quantum.add_network_to_dhcp_agent(dhcp_agent=dhcp_agents[agent],
|
|
||||||
body={'network_id': network_id})
|
|
||||||
index += 1
|
|
||||||
|
|
||||||
|
|
||||||
def services():
|
def services():
|
||||||
''' Returns a list of services associate with this charm '''
|
''' Returns a list of services associate with this charm '''
|
||||||
@ -862,12 +775,12 @@ def configure_ovs():
|
|||||||
|
|
||||||
portmaps = DataPortContext()()
|
portmaps = DataPortContext()()
|
||||||
bridgemaps = parse_bridge_mappings(config('bridge-mappings'))
|
bridgemaps = parse_bridge_mappings(config('bridge-mappings'))
|
||||||
for provider, br in bridgemaps.iteritems():
|
for br in bridgemaps.values():
|
||||||
add_bridge(br)
|
add_bridge(br)
|
||||||
if not portmaps:
|
if not portmaps:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
for port, _br in portmaps.iteritems():
|
for port, _br in portmaps.items():
|
||||||
if _br == br:
|
if _br == br:
|
||||||
add_bridge_port(br, port, promisc=True)
|
add_bridge_port(br, port, promisc=True)
|
||||||
|
|
||||||
@ -908,13 +821,13 @@ def remove_file(path):
|
|||||||
|
|
||||||
|
|
||||||
def install_legacy_ha_files(force=False):
|
def install_legacy_ha_files(force=False):
|
||||||
for f, p in LEGACY_FILES_MAP.iteritems():
|
for f, p in LEGACY_FILES_MAP.items():
|
||||||
srcfile = os.path.join(LEGACY_HA_TEMPLATE_FILES, f)
|
srcfile = os.path.join(LEGACY_HA_TEMPLATE_FILES, f)
|
||||||
copy_file(srcfile, p['path'], p.get('permissions', None), force=force)
|
copy_file(srcfile, p['path'], p.get('permissions', None), force=force)
|
||||||
|
|
||||||
|
|
||||||
def remove_legacy_ha_files():
|
def remove_legacy_ha_files():
|
||||||
for f, p in LEGACY_FILES_MAP.iteritems():
|
for f, p in LEGACY_FILES_MAP.items():
|
||||||
remove_file(os.path.join(p['path'], f))
|
remove_file(os.path.join(p['path'], f))
|
||||||
|
|
||||||
|
|
||||||
|
@ -5,12 +5,12 @@ coverage>=3.6
|
|||||||
mock>=1.2
|
mock>=1.2
|
||||||
flake8>=2.2.4,<=2.4.1
|
flake8>=2.2.4,<=2.4.1
|
||||||
os-testr>=0.4.1
|
os-testr>=0.4.1
|
||||||
charm-tools>=2.0.0
|
charm-tools>=2.0.0;python_version=='2.7'
|
||||||
requests==2.6.0
|
requests==2.6.0
|
||||||
# BEGIN: Amulet OpenStack Charm Helper Requirements
|
# BEGIN: Amulet OpenStack Charm Helper Requirements
|
||||||
# Liberty client lower constraints
|
# Liberty client lower constraints
|
||||||
amulet>=1.14.3,<2.0
|
amulet>=1.14.3,<2.0;python_version=='2.7'
|
||||||
bundletester>=0.6.1,<1.0
|
bundletester>=0.6.1,<1.0;python_version=='2.7'
|
||||||
python-ceilometerclient>=1.5.0
|
python-ceilometerclient>=1.5.0
|
||||||
python-cinderclient>=1.4.0
|
python-cinderclient>=1.4.0
|
||||||
python-glanceclient>=1.1.0
|
python-glanceclient>=1.1.0
|
||||||
|
3
tox.ini
3
tox.ini
@ -2,7 +2,7 @@
|
|||||||
# This file is managed centrally by release-tools and should not be modified
|
# This file is managed centrally by release-tools and should not be modified
|
||||||
# within individual charm repos.
|
# within individual charm repos.
|
||||||
[tox]
|
[tox]
|
||||||
envlist = pep8,py27
|
envlist = pep8,py27,py35
|
||||||
skipsdist = True
|
skipsdist = True
|
||||||
|
|
||||||
[testenv]
|
[testenv]
|
||||||
@ -20,6 +20,7 @@ passenv = HOME TERM AMULET_* CS_API_*
|
|||||||
basepython = python2.7
|
basepython = python2.7
|
||||||
deps = -r{toxinidir}/requirements.txt
|
deps = -r{toxinidir}/requirements.txt
|
||||||
-r{toxinidir}/test-requirements.txt
|
-r{toxinidir}/test-requirements.txt
|
||||||
|
commands = /bin/true
|
||||||
|
|
||||||
[testenv:py35]
|
[testenv:py35]
|
||||||
basepython = python3.5
|
basepython = python3.5
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import sys
|
import sys
|
||||||
|
|
||||||
|
sys.path.append('unit_tests')
|
||||||
sys.path.append('actions')
|
sys.path.append('actions')
|
||||||
sys.path.append('hooks')
|
sys.path.append('hooks')
|
||||||
|
@ -1,18 +1,19 @@
|
|||||||
|
|
||||||
|
import io
|
||||||
|
|
||||||
|
from contextlib import contextmanager
|
||||||
|
|
||||||
from mock import (
|
from mock import (
|
||||||
Mock,
|
|
||||||
MagicMock,
|
MagicMock,
|
||||||
patch
|
patch
|
||||||
)
|
)
|
||||||
import neutron_contexts
|
import neutron_contexts
|
||||||
import sys
|
|
||||||
from contextlib import contextmanager
|
|
||||||
|
|
||||||
from test_utils import (
|
from test_utils import (
|
||||||
CharmTestCase
|
CharmTestCase
|
||||||
)
|
)
|
||||||
|
|
||||||
TO_PATCH = [
|
TO_PATCH = [
|
||||||
'apt_install',
|
|
||||||
'config',
|
'config',
|
||||||
'eligible_leader',
|
'eligible_leader',
|
||||||
'unit_get',
|
'unit_get',
|
||||||
@ -27,14 +28,14 @@ def patch_open():
|
|||||||
|
|
||||||
Yields the mock for "open" and "file", respectively.'''
|
Yields the mock for "open" and "file", respectively.'''
|
||||||
mock_open = MagicMock(spec=open)
|
mock_open = MagicMock(spec=open)
|
||||||
mock_file = MagicMock(spec=file)
|
mock_file = MagicMock(spec=io.FileIO)
|
||||||
|
|
||||||
@contextmanager
|
@contextmanager
|
||||||
def stub_open(*args, **kwargs):
|
def stub_open(*args, **kwargs):
|
||||||
mock_open(*args, **kwargs)
|
mock_open(*args, **kwargs)
|
||||||
yield mock_file
|
yield mock_file
|
||||||
|
|
||||||
with patch('__builtin__.open', stub_open):
|
with patch('builtins.open', stub_open):
|
||||||
yield mock_open, mock_file
|
yield mock_open, mock_file
|
||||||
|
|
||||||
|
|
||||||
@ -323,54 +324,6 @@ class TestSharedSecret(CharmTestCase):
|
|||||||
neutron_contexts.SHARED_SECRET.format('neutron'), 'r')
|
neutron_contexts.SHARED_SECRET.format('neutron'), 'r')
|
||||||
|
|
||||||
|
|
||||||
class TestHostIP(CharmTestCase):
|
|
||||||
|
|
||||||
def setUp(self):
|
|
||||||
super(TestHostIP, self).setUp(neutron_contexts,
|
|
||||||
TO_PATCH)
|
|
||||||
self.config.side_effect = self.test_config.get
|
|
||||||
self.network_get_primary_address.side_effect = NotImplementedError
|
|
||||||
# Save and inject
|
|
||||||
self.mods = {'dns': None, 'dns.resolver': None}
|
|
||||||
for mod in self.mods:
|
|
||||||
if mod not in sys.modules:
|
|
||||||
sys.modules[mod] = Mock()
|
|
||||||
else:
|
|
||||||
del self.mods[mod]
|
|
||||||
|
|
||||||
def tearDown(self):
|
|
||||||
super(TestHostIP, self).tearDown()
|
|
||||||
# Cleanup
|
|
||||||
for mod in self.mods.keys():
|
|
||||||
del sys.modules[mod]
|
|
||||||
|
|
||||||
def test_get_host_ip_already_ip(self):
|
|
||||||
self.assertEqual(neutron_contexts.get_host_ip('10.5.0.1'),
|
|
||||||
'10.5.0.1')
|
|
||||||
|
|
||||||
def test_get_host_ip_noarg(self):
|
|
||||||
self.unit_get.return_value = "10.5.0.1"
|
|
||||||
self.assertEqual(neutron_contexts.get_host_ip(),
|
|
||||||
'10.5.0.1')
|
|
||||||
|
|
||||||
@patch('dns.resolver.query')
|
|
||||||
def test_get_host_ip_hostname_unresolvable(self, _query):
|
|
||||||
class NXDOMAIN(Exception):
|
|
||||||
pass
|
|
||||||
_query.side_effect = NXDOMAIN()
|
|
||||||
self.assertRaises(NXDOMAIN, neutron_contexts.get_host_ip,
|
|
||||||
'missing.example.com')
|
|
||||||
|
|
||||||
@patch('dns.resolver.query')
|
|
||||||
def test_get_host_ip_hostname_resolvable(self, _query):
|
|
||||||
data = MagicMock()
|
|
||||||
data.address = '10.5.0.1'
|
|
||||||
_query.return_value = [data]
|
|
||||||
self.assertEqual(neutron_contexts.get_host_ip('myhost.example.com'),
|
|
||||||
'10.5.0.1')
|
|
||||||
_query.assert_called_with('myhost.example.com', 'A')
|
|
||||||
|
|
||||||
|
|
||||||
class TestMisc(CharmTestCase):
|
class TestMisc(CharmTestCase):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
@ -83,7 +83,7 @@ class TestQuantumHooks(CharmTestCase):
|
|||||||
self.valid_plugin.return_value = True
|
self.valid_plugin.return_value = True
|
||||||
_pkgs = ['foo', 'bar']
|
_pkgs = ['foo', 'bar']
|
||||||
self.filter_installed_packages.return_value = _pkgs
|
self.filter_installed_packages.return_value = _pkgs
|
||||||
self._call_hook('install.real')
|
self._call_hook('install')
|
||||||
self.configure_installation_source.assert_called_with(
|
self.configure_installation_source.assert_called_with(
|
||||||
'cloud:precise-havana'
|
'cloud:precise-havana'
|
||||||
)
|
)
|
||||||
@ -99,7 +99,7 @@ class TestQuantumHooks(CharmTestCase):
|
|||||||
|
|
||||||
def test_install_hook_precise_nocloudarchive(self):
|
def test_install_hook_precise_nocloudarchive(self):
|
||||||
self.test_config.set('openstack-origin', 'distro')
|
self.test_config.set('openstack-origin', 'distro')
|
||||||
self._call_hook('install.real')
|
self._call_hook('install')
|
||||||
self.configure_installation_source.assert_called_with(
|
self.configure_installation_source.assert_called_with(
|
||||||
'cloud:precise-icehouse'
|
'cloud:precise-icehouse'
|
||||||
)
|
)
|
||||||
@ -107,7 +107,7 @@ class TestQuantumHooks(CharmTestCase):
|
|||||||
@patch('sys.exit')
|
@patch('sys.exit')
|
||||||
def test_install_hook_invalid_plugin(self, _exit):
|
def test_install_hook_invalid_plugin(self, _exit):
|
||||||
self.valid_plugin.return_value = False
|
self.valid_plugin.return_value = False
|
||||||
self._call_hook('install.real')
|
self._call_hook('install')
|
||||||
self.assertTrue(self.log.called)
|
self.assertTrue(self.log.called)
|
||||||
_exit.assert_called_with(1)
|
_exit.assert_called_with(1)
|
||||||
|
|
||||||
@ -132,7 +132,7 @@ class TestQuantumHooks(CharmTestCase):
|
|||||||
projects_yaml = yaml.dump(openstack_origin_git)
|
projects_yaml = yaml.dump(openstack_origin_git)
|
||||||
self.test_config.set('openstack-origin', repo)
|
self.test_config.set('openstack-origin', repo)
|
||||||
self.test_config.set('openstack-origin-git', projects_yaml)
|
self.test_config.set('openstack-origin-git', projects_yaml)
|
||||||
self._call_hook('install.real')
|
self._call_hook('install')
|
||||||
self.configure_installation_source.assert_called_with(
|
self.configure_installation_source.assert_called_with(
|
||||||
'cloud:trusty-juno'
|
'cloud:trusty-juno'
|
||||||
)
|
)
|
||||||
|
@ -1,5 +1,3 @@
|
|||||||
import collections
|
|
||||||
|
|
||||||
from mock import MagicMock, call, patch, ANY
|
from mock import MagicMock, call, patch, ANY
|
||||||
|
|
||||||
import charmhelpers.core.hookenv as hookenv
|
import charmhelpers.core.hookenv as hookenv
|
||||||
@ -31,8 +29,6 @@ TO_PATCH = [
|
|||||||
'service_running',
|
'service_running',
|
||||||
'NetworkServiceContext',
|
'NetworkServiceContext',
|
||||||
'ExternalPortContext',
|
'ExternalPortContext',
|
||||||
'unit_private_ip',
|
|
||||||
'relations_of_type',
|
|
||||||
'render',
|
'render',
|
||||||
'service_stop',
|
'service_stop',
|
||||||
'determine_dkms_package',
|
'determine_dkms_package',
|
||||||
@ -58,20 +54,11 @@ openstack_origin_git = \
|
|||||||
|
|
||||||
class TestNeutronUtils(CharmTestCase):
|
class TestNeutronUtils(CharmTestCase):
|
||||||
|
|
||||||
def assertDictEqual(self, d1, d2, msg=None): # assertEqual uses for dicts
|
|
||||||
for k, v1 in d1.iteritems():
|
|
||||||
self.assertIn(k, d2, msg)
|
|
||||||
v2 = d2[k]
|
|
||||||
if(isinstance(v1, collections.Iterable) and
|
|
||||||
not isinstance(v1, basestring)):
|
|
||||||
self.assertItemsEqual(v1, v2, msg)
|
|
||||||
else:
|
|
||||||
self.assertEqual(v1, v2, msg)
|
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
super(TestNeutronUtils, self).setUp(neutron_utils, TO_PATCH)
|
super(TestNeutronUtils, self).setUp(neutron_utils, TO_PATCH)
|
||||||
self.headers_package.return_value = 'linux-headers-2.6.18'
|
self.headers_package.return_value = 'linux-headers-2.6.18'
|
||||||
self._set_distrib_codename('trusty')
|
self._set_distrib_codename('trusty')
|
||||||
|
self.maxDiff = None
|
||||||
|
|
||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
# Reset cached cache
|
# Reset cached cache
|
||||||
@ -286,7 +273,7 @@ class TestNeutronUtils(CharmTestCase):
|
|||||||
])
|
])
|
||||||
calls = [call('br1', 'eth0.100', promisc=True),
|
calls = [call('br1', 'eth0.100', promisc=True),
|
||||||
call('br1', 'eth0.200', promisc=True)]
|
call('br1', 'eth0.200', promisc=True)]
|
||||||
self.add_bridge_port.assert_has_calls(calls)
|
self.add_bridge_port.assert_has_calls(calls, any_order=True)
|
||||||
|
|
||||||
@patch.object(neutron_utils, 'register_configs')
|
@patch.object(neutron_utils, 'register_configs')
|
||||||
@patch('charmhelpers.contrib.openstack.templating.OSConfigRenderer')
|
@patch('charmhelpers.contrib.openstack.templating.OSConfigRenderer')
|
||||||
@ -373,12 +360,12 @@ class TestNeutronUtils(CharmTestCase):
|
|||||||
mock_get_packages.return_value = ['neutron-vpn-agent']
|
mock_get_packages.return_value = ['neutron-vpn-agent']
|
||||||
self.os_release.return_value = 'icehouse'
|
self.os_release.return_value = 'icehouse'
|
||||||
ex_map = {
|
ex_map = {
|
||||||
neutron_utils.NEUTRON_CONF: ['neutron-dhcp-agent',
|
neutron_utils.NEUTRON_CONF: ['neutron-lbaas-agent',
|
||||||
'neutron-metadata-agent',
|
|
||||||
'neutron-plugin-openvswitch-agent',
|
'neutron-plugin-openvswitch-agent',
|
||||||
|
'neutron-vpn-agent',
|
||||||
|
'neutron-dhcp-agent',
|
||||||
'neutron-metering-agent',
|
'neutron-metering-agent',
|
||||||
'neutron-lbaas-agent',
|
'neutron-metadata-agent'],
|
||||||
'neutron-vpn-agent'],
|
|
||||||
neutron_utils.NEUTRON_DNSMASQ_CONF: ['neutron-dhcp-agent'],
|
neutron_utils.NEUTRON_DNSMASQ_CONF: ['neutron-dhcp-agent'],
|
||||||
neutron_utils.NEUTRON_LBAAS_AGENT_CONF:
|
neutron_utils.NEUTRON_LBAAS_AGENT_CONF:
|
||||||
['neutron-lbaas-agent'],
|
['neutron-lbaas-agent'],
|
||||||
@ -409,8 +396,7 @@ class TestNeutronUtils(CharmTestCase):
|
|||||||
neutron_utils.NOVA_API_METADATA_AA_PROFILE_PATH:
|
neutron_utils.NOVA_API_METADATA_AA_PROFILE_PATH:
|
||||||
['nova-api-metadata'],
|
['nova-api-metadata'],
|
||||||
}
|
}
|
||||||
|
self.assertEqual(neutron_utils.restart_map(), ex_map)
|
||||||
self.assertDictEqual(neutron_utils.restart_map(), ex_map)
|
|
||||||
|
|
||||||
@patch.object(neutron_utils, 'get_packages')
|
@patch.object(neutron_utils, 'get_packages')
|
||||||
def test_restart_map_ovs_mitaka(self, mock_get_packages):
|
def test_restart_map_ovs_mitaka(self, mock_get_packages):
|
||||||
@ -418,12 +404,12 @@ class TestNeutronUtils(CharmTestCase):
|
|||||||
mock_get_packages.return_value = ['neutron-vpn-agent']
|
mock_get_packages.return_value = ['neutron-vpn-agent']
|
||||||
self.os_release.return_value = 'mitaka'
|
self.os_release.return_value = 'mitaka'
|
||||||
ex_map = {
|
ex_map = {
|
||||||
neutron_utils.NEUTRON_CONF: ['neutron-dhcp-agent',
|
neutron_utils.NEUTRON_CONF: ['neutron-lbaas-agent',
|
||||||
'neutron-metadata-agent',
|
'neutron-vpn-agent',
|
||||||
'neutron-openvswitch-agent',
|
'neutron-dhcp-agent',
|
||||||
'neutron-metering-agent',
|
'neutron-metering-agent',
|
||||||
'neutron-lbaas-agent',
|
'neutron-metadata-agent',
|
||||||
'neutron-vpn-agent'],
|
'neutron-openvswitch-agent'],
|
||||||
neutron_utils.NEUTRON_DNSMASQ_CONF: ['neutron-dhcp-agent'],
|
neutron_utils.NEUTRON_DNSMASQ_CONF: ['neutron-dhcp-agent'],
|
||||||
neutron_utils.NEUTRON_LBAAS_AGENT_CONF:
|
neutron_utils.NEUTRON_LBAAS_AGENT_CONF:
|
||||||
['neutron-lbaas-agent'],
|
['neutron-lbaas-agent'],
|
||||||
@ -453,7 +439,7 @@ class TestNeutronUtils(CharmTestCase):
|
|||||||
neutron_utils.NOVA_API_METADATA_AA_PROFILE_PATH:
|
neutron_utils.NOVA_API_METADATA_AA_PROFILE_PATH:
|
||||||
['nova-api-metadata'],
|
['nova-api-metadata'],
|
||||||
}
|
}
|
||||||
self.assertEqual(ex_map, neutron_utils.restart_map())
|
self.assertEqual(neutron_utils.restart_map(), ex_map)
|
||||||
|
|
||||||
@patch.object(neutron_utils, 'get_packages')
|
@patch.object(neutron_utils, 'get_packages')
|
||||||
def test_restart_map_ovs_newton(self, mock_get_packages):
|
def test_restart_map_ovs_newton(self, mock_get_packages):
|
||||||
@ -461,12 +447,12 @@ class TestNeutronUtils(CharmTestCase):
|
|||||||
mock_get_packages.return_value = ['neutron-vpn-agent']
|
mock_get_packages.return_value = ['neutron-vpn-agent']
|
||||||
self.os_release.return_value = 'newton'
|
self.os_release.return_value = 'newton'
|
||||||
ex_map = {
|
ex_map = {
|
||||||
neutron_utils.NEUTRON_CONF: ['neutron-dhcp-agent',
|
neutron_utils.NEUTRON_CONF: ['neutron-vpn-agent',
|
||||||
'neutron-metadata-agent',
|
|
||||||
'neutron-openvswitch-agent',
|
|
||||||
'neutron-metering-agent',
|
|
||||||
'neutron-lbaasv2-agent',
|
'neutron-lbaasv2-agent',
|
||||||
'neutron-vpn-agent'],
|
'neutron-dhcp-agent',
|
||||||
|
'neutron-metering-agent',
|
||||||
|
'neutron-metadata-agent',
|
||||||
|
'neutron-openvswitch-agent'],
|
||||||
neutron_utils.NEUTRON_DNSMASQ_CONF: ['neutron-dhcp-agent'],
|
neutron_utils.NEUTRON_DNSMASQ_CONF: ['neutron-dhcp-agent'],
|
||||||
neutron_utils.NEUTRON_LBAAS_AGENT_CONF:
|
neutron_utils.NEUTRON_LBAAS_AGENT_CONF:
|
||||||
['neutron-lbaasv2-agent'],
|
['neutron-lbaasv2-agent'],
|
||||||
@ -483,8 +469,20 @@ class TestNeutronUtils(CharmTestCase):
|
|||||||
neutron_utils.NOVA_CONF: ['nova-api-metadata'],
|
neutron_utils.NOVA_CONF: ['nova-api-metadata'],
|
||||||
neutron_utils.EXT_PORT_CONF: ['ext-port'],
|
neutron_utils.EXT_PORT_CONF: ['ext-port'],
|
||||||
neutron_utils.PHY_NIC_MTU_CONF: ['os-charm-phy-nic-mtu'],
|
neutron_utils.PHY_NIC_MTU_CONF: ['os-charm-phy-nic-mtu'],
|
||||||
|
neutron_utils.NEUTRON_DHCP_AA_PROFILE_PATH: ['neutron-dhcp-agent'],
|
||||||
|
neutron_utils.NEUTRON_OVS_AA_PROFILE_PATH:
|
||||||
|
['neutron-openvswitch-agent'],
|
||||||
|
neutron_utils.NEUTRON_L3_AA_PROFILE_PATH: ['neutron-vpn-agent'],
|
||||||
|
neutron_utils.NEUTRON_LBAASV2_AA_PROFILE_PATH:
|
||||||
|
['neutron-lbaasv2-agent'],
|
||||||
|
neutron_utils.NEUTRON_METADATA_AA_PROFILE_PATH:
|
||||||
|
['neutron-metadata-agent'],
|
||||||
|
neutron_utils.NEUTRON_METERING_AA_PROFILE_PATH:
|
||||||
|
['neutron-metering-agent'],
|
||||||
|
neutron_utils.NOVA_API_METADATA_AA_PROFILE_PATH:
|
||||||
|
['nova-api-metadata'],
|
||||||
}
|
}
|
||||||
self.assertEqual(ex_map, neutron_utils.restart_map())
|
self.assertEqual(neutron_utils.restart_map(), ex_map)
|
||||||
|
|
||||||
@patch.object(neutron_utils, 'get_packages')
|
@patch.object(neutron_utils, 'get_packages')
|
||||||
def test_restart_map_ovs_post_trusty(self, mock_get_packages):
|
def test_restart_map_ovs_post_trusty(self, mock_get_packages):
|
||||||
@ -493,7 +491,7 @@ class TestNeutronUtils(CharmTestCase):
|
|||||||
mock_get_packages.return_value = ['neutron-l3-agent']
|
mock_get_packages.return_value = ['neutron-l3-agent']
|
||||||
self.os_release.return_value = 'diablo'
|
self.os_release.return_value = 'diablo'
|
||||||
rmap = neutron_utils.restart_map()
|
rmap = neutron_utils.restart_map()
|
||||||
for services in rmap.itervalues():
|
for services in rmap.values():
|
||||||
self.assertFalse('neutron-vpn-agent' in services)
|
self.assertFalse('neutron-vpn-agent' in services)
|
||||||
|
|
||||||
@patch.object(neutron_utils, 'get_packages')
|
@patch.object(neutron_utils, 'get_packages')
|
||||||
@ -502,11 +500,11 @@ class TestNeutronUtils(CharmTestCase):
|
|||||||
mock_get_packages.return_value = ['neutron-vpn-agent']
|
mock_get_packages.return_value = ['neutron-vpn-agent']
|
||||||
self.os_release.return_value = 'icehouse'
|
self.os_release.return_value = 'icehouse'
|
||||||
ex_map = {
|
ex_map = {
|
||||||
neutron_utils.NEUTRON_CONF: ['neutron-dhcp-agent',
|
neutron_utils.NEUTRON_CONF: ['neutron-lbaas-agent',
|
||||||
'neutron-metadata-agent',
|
'neutron-vpn-agent',
|
||||||
|
'neutron-dhcp-agent',
|
||||||
'neutron-metering-agent',
|
'neutron-metering-agent',
|
||||||
'neutron-lbaas-agent',
|
'neutron-metadata-agent'],
|
||||||
'neutron-vpn-agent'],
|
|
||||||
neutron_utils.NEUTRON_DNSMASQ_CONF: ['neutron-dhcp-agent'],
|
neutron_utils.NEUTRON_DNSMASQ_CONF: ['neutron-dhcp-agent'],
|
||||||
neutron_utils.NEUTRON_LBAAS_AGENT_CONF:
|
neutron_utils.NEUTRON_LBAAS_AGENT_CONF:
|
||||||
['neutron-lbaas-agent'],
|
['neutron-lbaas-agent'],
|
||||||
@ -522,7 +520,6 @@ class TestNeutronUtils(CharmTestCase):
|
|||||||
neutron_utils.EXT_PORT_CONF: ['ext-port'],
|
neutron_utils.EXT_PORT_CONF: ['ext-port'],
|
||||||
neutron_utils.PHY_NIC_MTU_CONF: ['os-charm-phy-nic-mtu'],
|
neutron_utils.PHY_NIC_MTU_CONF: ['os-charm-phy-nic-mtu'],
|
||||||
neutron_utils.NEUTRON_DHCP_AA_PROFILE_PATH: ['neutron-dhcp-agent'],
|
neutron_utils.NEUTRON_DHCP_AA_PROFILE_PATH: ['neutron-dhcp-agent'],
|
||||||
neutron_utils.NEUTRON_L3_AA_PROFILE_PATH: ['neutron-vpn-agent'],
|
|
||||||
neutron_utils.NEUTRON_LBAAS_AA_PROFILE_PATH:
|
neutron_utils.NEUTRON_LBAAS_AA_PROFILE_PATH:
|
||||||
['neutron-lbaas-agent'],
|
['neutron-lbaas-agent'],
|
||||||
neutron_utils.NEUTRON_METADATA_AA_PROFILE_PATH:
|
neutron_utils.NEUTRON_METADATA_AA_PROFILE_PATH:
|
||||||
@ -533,7 +530,7 @@ class TestNeutronUtils(CharmTestCase):
|
|||||||
['nova-api-metadata'],
|
['nova-api-metadata'],
|
||||||
}
|
}
|
||||||
|
|
||||||
self.assertDictEqual(neutron_utils.restart_map(), ex_map)
|
self.assertEqual(neutron_utils.restart_map(), ex_map)
|
||||||
|
|
||||||
@patch.object(neutron_utils, 'get_packages')
|
@patch.object(neutron_utils, 'get_packages')
|
||||||
def test_restart_map_ovs_odl_newton(self, mock_get_packages):
|
def test_restart_map_ovs_odl_newton(self, mock_get_packages):
|
||||||
@ -541,11 +538,11 @@ class TestNeutronUtils(CharmTestCase):
|
|||||||
mock_get_packages.return_value = ['neutron-vpn-agent']
|
mock_get_packages.return_value = ['neutron-vpn-agent']
|
||||||
self.os_release.return_value = 'newton'
|
self.os_release.return_value = 'newton'
|
||||||
ex_map = {
|
ex_map = {
|
||||||
neutron_utils.NEUTRON_CONF: ['neutron-dhcp-agent',
|
neutron_utils.NEUTRON_CONF: ['neutron-vpn-agent',
|
||||||
'neutron-metadata-agent',
|
|
||||||
'neutron-metering-agent',
|
|
||||||
'neutron-lbaasv2-agent',
|
'neutron-lbaasv2-agent',
|
||||||
'neutron-vpn-agent'],
|
'neutron-dhcp-agent',
|
||||||
|
'neutron-metering-agent',
|
||||||
|
'neutron-metadata-agent'],
|
||||||
neutron_utils.NEUTRON_DNSMASQ_CONF: ['neutron-dhcp-agent'],
|
neutron_utils.NEUTRON_DNSMASQ_CONF: ['neutron-dhcp-agent'],
|
||||||
neutron_utils.NEUTRON_LBAAS_AGENT_CONF:
|
neutron_utils.NEUTRON_LBAAS_AGENT_CONF:
|
||||||
['neutron-lbaasv2-agent'],
|
['neutron-lbaasv2-agent'],
|
||||||
@ -561,7 +558,6 @@ class TestNeutronUtils(CharmTestCase):
|
|||||||
neutron_utils.EXT_PORT_CONF: ['ext-port'],
|
neutron_utils.EXT_PORT_CONF: ['ext-port'],
|
||||||
neutron_utils.PHY_NIC_MTU_CONF: ['os-charm-phy-nic-mtu'],
|
neutron_utils.PHY_NIC_MTU_CONF: ['os-charm-phy-nic-mtu'],
|
||||||
neutron_utils.NEUTRON_DHCP_AA_PROFILE_PATH: ['neutron-dhcp-agent'],
|
neutron_utils.NEUTRON_DHCP_AA_PROFILE_PATH: ['neutron-dhcp-agent'],
|
||||||
neutron_utils.NEUTRON_L3_AA_PROFILE_PATH: ['neutron-vpn-agent'],
|
|
||||||
neutron_utils.NEUTRON_LBAASV2_AA_PROFILE_PATH:
|
neutron_utils.NEUTRON_LBAASV2_AA_PROFILE_PATH:
|
||||||
['neutron-lbaasv2-agent'],
|
['neutron-lbaasv2-agent'],
|
||||||
neutron_utils.NEUTRON_METADATA_AA_PROFILE_PATH:
|
neutron_utils.NEUTRON_METADATA_AA_PROFILE_PATH:
|
||||||
@ -746,125 +742,6 @@ class DummyExternalPortContext():
|
|||||||
def __call__(self):
|
def __call__(self):
|
||||||
return self.return_value
|
return self.return_value
|
||||||
|
|
||||||
agents_all_alive = {
|
|
||||||
'DHCP Agent': {
|
|
||||||
'agents': [
|
|
||||||
{'alive': True,
|
|
||||||
'host': 'cluster1-machine1.internal',
|
|
||||||
'id': '3e3550f2-38cc-11e3-9617-3c970e8b1cf7'},
|
|
||||||
{'alive': True,
|
|
||||||
'host': 'cluster1-machine2.internal',
|
|
||||||
'id': '53d6eefc-38cc-11e3-b3c8-3c970e8b1cf7'},
|
|
||||||
{'alive': True,
|
|
||||||
'host': 'cluster2-machine1.internal',
|
|
||||||
'id': '92b8b6bc-38ce-11e3-8537-3c970e8b1cf7'},
|
|
||||||
{'alive': True,
|
|
||||||
'host': 'cluster2-machine3.internal',
|
|
||||||
'id': 'ebdcc950-51c8-11e3-a804-1c6f65b044df'},
|
|
||||||
]
|
|
||||||
},
|
|
||||||
'L3 Agent': {
|
|
||||||
'agents': [
|
|
||||||
{'alive': True,
|
|
||||||
'host': 'cluster1-machine1.internal',
|
|
||||||
'id': '7128198e-38ce-11e3-ba78-3c970e8b1cf7'},
|
|
||||||
{'alive': True,
|
|
||||||
'host': 'cluster1-machine2.internal',
|
|
||||||
'id': '72453824-38ce-11e3-938e-3c970e8b1cf7'},
|
|
||||||
{'alive': True,
|
|
||||||
'host': 'cluster2-machine1.internal',
|
|
||||||
'id': '84a04126-38ce-11e3-9449-3c970e8b1cf7'},
|
|
||||||
{'alive': True,
|
|
||||||
'host': 'cluster2-machine3.internal',
|
|
||||||
'id': '00f4268a-51c9-11e3-9177-1c6f65b044df'},
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
agents_some_dead_cl1 = {
|
|
||||||
'DHCP Agent': {
|
|
||||||
'agents': [
|
|
||||||
{'alive': False,
|
|
||||||
'host': 'cluster1-machine1.internal',
|
|
||||||
'id': '3e3550f2-38cc-11e3-9617-3c970e8b1cf7'},
|
|
||||||
{'alive': True,
|
|
||||||
'host': 'cluster2-machine1.internal',
|
|
||||||
'id': '53d6eefc-38cc-11e3-b3c8-3c970e8b1cf7'},
|
|
||||||
{'alive': True,
|
|
||||||
'host': 'cluster2-machine2.internal',
|
|
||||||
'id': '92b8b6bc-38ce-11e3-8537-3c970e8b1cf7'},
|
|
||||||
{'alive': True,
|
|
||||||
'host': 'cluster2-machine3.internal',
|
|
||||||
'id': 'ebdcc950-51c8-11e3-a804-1c6f65b044df'},
|
|
||||||
]
|
|
||||||
},
|
|
||||||
'L3 Agent': {
|
|
||||||
'agents': [
|
|
||||||
{'alive': False,
|
|
||||||
'host': 'cluster1-machine1.internal',
|
|
||||||
'id': '7128198e-38ce-11e3-ba78-3c970e8b1cf7'},
|
|
||||||
{'alive': True,
|
|
||||||
'host': 'cluster2-machine1.internal',
|
|
||||||
'id': '72453824-38ce-11e3-938e-3c970e8b1cf7'},
|
|
||||||
{'alive': True,
|
|
||||||
'host': 'cluster2-machine2.internal',
|
|
||||||
'id': '84a04126-38ce-11e3-9449-3c970e8b1cf7'},
|
|
||||||
{'alive': True,
|
|
||||||
'host': 'cluster2-machine3.internal',
|
|
||||||
'id': '00f4268a-51c9-11e3-9177-1c6f65b044df'},
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
agents_some_dead_cl2 = {
|
|
||||||
'DHCP Agent': {
|
|
||||||
'agents': [
|
|
||||||
{'alive': True,
|
|
||||||
'host': 'cluster1-machine1.internal',
|
|
||||||
'id': '3e3550f2-38cc-11e3-9617-3c970e8b1cf7'},
|
|
||||||
{'alive': True,
|
|
||||||
'host': 'cluster2-machine1.internal',
|
|
||||||
'id': '53d6eefc-38cc-11e3-b3c8-3c970e8b1cf7'},
|
|
||||||
{'alive': False,
|
|
||||||
'host': 'cluster2-machine2.internal',
|
|
||||||
'id': '92b8b6bc-38ce-11e3-8537-3c970e8b1cf7'},
|
|
||||||
{'alive': True,
|
|
||||||
'host': 'cluster2-machine3.internal',
|
|
||||||
'id': 'ebdcc950-51c8-11e3-a804-1c6f65b044df'},
|
|
||||||
]
|
|
||||||
},
|
|
||||||
'L3 Agent': {
|
|
||||||
'agents': [
|
|
||||||
{'alive': True,
|
|
||||||
'host': 'cluster1-machine1.internal',
|
|
||||||
'id': '7128198e-38ce-11e3-ba78-3c970e8b1cf7'},
|
|
||||||
{'alive': True,
|
|
||||||
'host': 'cluster2-machine1.internal',
|
|
||||||
'id': '72453824-38ce-11e3-938e-3c970e8b1cf7'},
|
|
||||||
{'alive': False,
|
|
||||||
'host': 'cluster2-machine2.internal',
|
|
||||||
'id': '84a04126-38ce-11e3-9449-3c970e8b1cf7'},
|
|
||||||
{'alive': True,
|
|
||||||
'host': 'cluster2-machine3.internal',
|
|
||||||
'id': '00f4268a-51c9-11e3-9177-1c6f65b044df'},
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
dhcp_agent_networks = {
|
|
||||||
'networks': [
|
|
||||||
{'id': 'foo'},
|
|
||||||
{'id': 'bar'}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
l3_agent_routers = {
|
|
||||||
'routers': [
|
|
||||||
{'id': 'baz'},
|
|
||||||
{'id': 'bong'}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
cluster1 = ['cluster1-machine1.internal']
|
cluster1 = ['cluster1-machine1.internal']
|
||||||
cluster2 = ['cluster2-machine1.internal', 'cluster2-machine2.internal'
|
cluster2 = ['cluster2-machine1.internal', 'cluster2-machine2.internal'
|
||||||
'cluster2-machine3.internal']
|
'cluster2-machine3.internal']
|
||||||
@ -882,86 +759,6 @@ class TestNeutronAgentReallocation(CharmTestCase):
|
|||||||
# Reset cached cache
|
# Reset cached cache
|
||||||
hookenv.cache = {}
|
hookenv.cache = {}
|
||||||
|
|
||||||
def test_no_network_context(self):
|
|
||||||
self.NetworkServiceContext.return_value = \
|
|
||||||
DummyNetworkServiceContext(return_value=None)
|
|
||||||
neutron_utils.reassign_agent_resources()
|
|
||||||
self.assertTrue(self.log.called)
|
|
||||||
|
|
||||||
@patch('neutronclient.v2_0.client.Client')
|
|
||||||
def test_no_down_agents(self, _client):
|
|
||||||
self.NetworkServiceContext.return_value = \
|
|
||||||
DummyNetworkServiceContext(return_value=network_context)
|
|
||||||
dummy_client = MagicMock()
|
|
||||||
dummy_client.list_agents.side_effect = agents_all_alive.itervalues()
|
|
||||||
_client.return_value = dummy_client
|
|
||||||
neutron_utils.reassign_agent_resources()
|
|
||||||
dummy_client.add_router_to_l3_agent.assert_not_called()
|
|
||||||
dummy_client.remove_router_from_l3_agent.assert_not_called()
|
|
||||||
dummy_client.add_network_to_dhcp_agent.assert_not_called()
|
|
||||||
dummy_client.remove_network_from_dhcp_agent.assert_not_called()
|
|
||||||
|
|
||||||
@patch('neutronclient.v2_0.client.Client')
|
|
||||||
def test_agents_down_relocation_required(self, _client):
|
|
||||||
self.NetworkServiceContext.return_value = \
|
|
||||||
DummyNetworkServiceContext(return_value=network_context)
|
|
||||||
dummy_client = MagicMock()
|
|
||||||
dummy_client.list_agents.side_effect = \
|
|
||||||
agents_some_dead_cl2.itervalues()
|
|
||||||
dummy_client.list_networks_on_dhcp_agent.return_value = \
|
|
||||||
dhcp_agent_networks
|
|
||||||
dummy_client.list_routers_on_l3_agent.return_value = \
|
|
||||||
l3_agent_routers
|
|
||||||
_client.return_value = dummy_client
|
|
||||||
self.unit_private_ip.return_value = 'cluster2-machine1.internal'
|
|
||||||
self.relations_of_type.return_value = \
|
|
||||||
[{'private-address': 'cluster2-machine3.internal'}]
|
|
||||||
neutron_utils.reassign_agent_resources()
|
|
||||||
|
|
||||||
# Ensure routers removed from dead l3 agent
|
|
||||||
dummy_client.remove_router_from_l3_agent.assert_has_calls(
|
|
||||||
[call(l3_agent='84a04126-38ce-11e3-9449-3c970e8b1cf7',
|
|
||||||
router_id='bong'),
|
|
||||||
call(l3_agent='84a04126-38ce-11e3-9449-3c970e8b1cf7',
|
|
||||||
router_id='baz')], any_order=True)
|
|
||||||
# and re-assigned across the remaining two live agents
|
|
||||||
dummy_client.add_router_to_l3_agent.assert_has_calls(
|
|
||||||
[call(l3_agent='00f4268a-51c9-11e3-9177-1c6f65b044df',
|
|
||||||
body={'router_id': 'baz'}),
|
|
||||||
call(l3_agent='72453824-38ce-11e3-938e-3c970e8b1cf7',
|
|
||||||
body={'router_id': 'bong'})], any_order=True)
|
|
||||||
# Ensure networks removed from dead dhcp agent
|
|
||||||
dummy_client.remove_network_from_dhcp_agent.assert_has_calls(
|
|
||||||
[call(dhcp_agent='92b8b6bc-38ce-11e3-8537-3c970e8b1cf7',
|
|
||||||
network_id='foo'),
|
|
||||||
call(dhcp_agent='92b8b6bc-38ce-11e3-8537-3c970e8b1cf7',
|
|
||||||
network_id='bar')], any_order=True)
|
|
||||||
# and re-assigned across the remaining two live agents
|
|
||||||
dummy_client.add_network_to_dhcp_agent.assert_has_calls(
|
|
||||||
[call(dhcp_agent='53d6eefc-38cc-11e3-b3c8-3c970e8b1cf7',
|
|
||||||
body={'network_id': 'foo'}),
|
|
||||||
call(dhcp_agent='ebdcc950-51c8-11e3-a804-1c6f65b044df',
|
|
||||||
body={'network_id': 'bar'})], any_order=True)
|
|
||||||
|
|
||||||
@patch('neutronclient.v2_0.client.Client')
|
|
||||||
def test_agents_down_relocation_impossible(self, _client):
|
|
||||||
self.NetworkServiceContext.return_value = \
|
|
||||||
DummyNetworkServiceContext(return_value=network_context)
|
|
||||||
dummy_client = MagicMock()
|
|
||||||
dummy_client.list_agents.side_effect = \
|
|
||||||
agents_some_dead_cl1.itervalues()
|
|
||||||
dummy_client.list_networks_on_dhcp_agent.return_value = \
|
|
||||||
dhcp_agent_networks
|
|
||||||
dummy_client.list_routers_on_l3_agent.return_value = \
|
|
||||||
l3_agent_routers
|
|
||||||
_client.return_value = dummy_client
|
|
||||||
self.unit_private_ip.return_value = 'cluster1-machine1.internal'
|
|
||||||
self.relations_of_type.return_value = []
|
|
||||||
neutron_utils.reassign_agent_resources()
|
|
||||||
self.assertTrue(self.log.called)
|
|
||||||
assert not dummy_client.remove_router_from_l3_agent.called
|
|
||||||
assert not dummy_client.remove_network_from_dhcp_agent.called
|
|
||||||
|
|
||||||
@patch.object(neutron_utils, 'git_install_requested')
|
@patch.object(neutron_utils, 'git_install_requested')
|
||||||
@patch.object(neutron_utils, 'git_clone_and_install')
|
@patch.object(neutron_utils, 'git_clone_and_install')
|
||||||
@patch.object(neutron_utils, 'git_post_install')
|
@patch.object(neutron_utils, 'git_post_install')
|
||||||
@ -1002,62 +799,62 @@ class TestNeutronAgentReallocation(CharmTestCase):
|
|||||||
self.assertEqual(add_user_to_group.call_args_list, expected)
|
self.assertEqual(add_user_to_group.call_args_list, expected)
|
||||||
expected = [
|
expected = [
|
||||||
call('/etc/neutron', owner='neutron',
|
call('/etc/neutron', owner='neutron',
|
||||||
group='neutron', perms=0755, force=False),
|
group='neutron', perms=0o755, force=False),
|
||||||
call('/etc/neutron/rootwrap.d', owner='neutron',
|
call('/etc/neutron/rootwrap.d', owner='neutron',
|
||||||
group='neutron', perms=0755, force=False),
|
group='neutron', perms=0o755, force=False),
|
||||||
call('/etc/neutron/plugins', owner='neutron',
|
call('/etc/neutron/plugins', owner='neutron',
|
||||||
group='neutron', perms=0755, force=False),
|
group='neutron', perms=0o755, force=False),
|
||||||
call('/etc/nova', owner='neutron',
|
call('/etc/nova', owner='neutron',
|
||||||
group='neutron', perms=0755, force=False),
|
group='neutron', perms=0o755, force=False),
|
||||||
call('/var/lib/neutron', owner='neutron',
|
call('/var/lib/neutron', owner='neutron',
|
||||||
group='neutron', perms=0755, force=False),
|
group='neutron', perms=0o755, force=False),
|
||||||
call('/var/lib/neutron/lock', owner='neutron',
|
call('/var/lib/neutron/lock', owner='neutron',
|
||||||
group='neutron', perms=0755, force=False),
|
group='neutron', perms=0o755, force=False),
|
||||||
call('/var/log/neutron', owner='neutron',
|
call('/var/log/neutron', owner='neutron',
|
||||||
group='neutron', perms=0755, force=False),
|
group='neutron', perms=0o755, force=False),
|
||||||
call('/var/lib/nova', owner='neutron',
|
call('/var/lib/nova', owner='neutron',
|
||||||
group='neutron', perms=0755, force=False),
|
group='neutron', perms=0o755, force=False),
|
||||||
call('/var/log/nova', owner='neutron',
|
call('/var/log/nova', owner='neutron',
|
||||||
group='neutron', perms=0755, force=False),
|
group='neutron', perms=0o755, force=False),
|
||||||
]
|
]
|
||||||
self.assertEqual(mkdir.call_args_list, expected)
|
self.assertEqual(mkdir.call_args_list, expected)
|
||||||
expected = [
|
expected = [
|
||||||
call('/var/log/neutron/bigswitch-agent.log', '', owner='neutron',
|
call('/var/log/neutron/bigswitch-agent.log', '', owner='neutron',
|
||||||
group='neutron', perms=0644),
|
group='neutron', perms=0o644),
|
||||||
call('/var/log/neutron/dhcp-agent.log', '', owner='neutron',
|
call('/var/log/neutron/dhcp-agent.log', '', owner='neutron',
|
||||||
group='neutron', perms=0644),
|
group='neutron', perms=0o644),
|
||||||
call('/var/log/neutron/l3-agent.log', '', owner='neutron',
|
call('/var/log/neutron/l3-agent.log', '', owner='neutron',
|
||||||
group='neutron', perms=0644),
|
group='neutron', perms=0o644),
|
||||||
call('/var/log/neutron/lbaas-agent.log', '', owner='neutron',
|
call('/var/log/neutron/lbaas-agent.log', '', owner='neutron',
|
||||||
group='neutron', perms=0644),
|
group='neutron', perms=0o644),
|
||||||
call('/var/log/neutron/ibm-agent.log', '', owner='neutron',
|
call('/var/log/neutron/ibm-agent.log', '', owner='neutron',
|
||||||
group='neutron', perms=0644),
|
group='neutron', perms=0o644),
|
||||||
call('/var/log/neutron/linuxbridge-agent.log', '', owner='neutron',
|
call('/var/log/neutron/linuxbridge-agent.log', '', owner='neutron',
|
||||||
group='neutron', perms=0644),
|
group='neutron', perms=0o644),
|
||||||
call('/var/log/neutron/metadata-agent.log', '', owner='neutron',
|
call('/var/log/neutron/metadata-agent.log', '', owner='neutron',
|
||||||
group='neutron', perms=0644),
|
group='neutron', perms=0o644),
|
||||||
call('/var/log/neutron/metering_agent.log', '', owner='neutron',
|
call('/var/log/neutron/metering_agent.log', '', owner='neutron',
|
||||||
group='neutron', perms=0644),
|
group='neutron', perms=0o644),
|
||||||
call('/var/log/neutron/mlnx-agent.log', '', owner='neutron',
|
call('/var/log/neutron/mlnx-agent.log', '', owner='neutron',
|
||||||
group='neutron', perms=0644),
|
group='neutron', perms=0o644),
|
||||||
call('/var/log/neutron/nec-agent.log', '', owner='neutron',
|
call('/var/log/neutron/nec-agent.log', '', owner='neutron',
|
||||||
group='neutron', perms=0644),
|
group='neutron', perms=0o644),
|
||||||
call('/var/log/neutron/nvsd-agent.log', '', owner='neutron',
|
call('/var/log/neutron/nvsd-agent.log', '', owner='neutron',
|
||||||
group='neutron', perms=0644),
|
group='neutron', perms=0o644),
|
||||||
call('/var/log/neutron/openflow-agent.log', '', owner='neutron',
|
call('/var/log/neutron/openflow-agent.log', '', owner='neutron',
|
||||||
group='neutron', perms=0644),
|
group='neutron', perms=0o644),
|
||||||
call('/var/log/neutron/openvswitch-agent.log', '', owner='neutron',
|
call('/var/log/neutron/openvswitch-agent.log', '', owner='neutron',
|
||||||
group='neutron', perms=0644),
|
group='neutron', perms=0o644),
|
||||||
call('/var/log/neutron/ovs-cleanup.log', '', owner='neutron',
|
call('/var/log/neutron/ovs-cleanup.log', '', owner='neutron',
|
||||||
group='neutron', perms=0644),
|
group='neutron', perms=0o644),
|
||||||
call('/var/log/neutron/ryu-agent.log', '', owner='neutron',
|
call('/var/log/neutron/ryu-agent.log', '', owner='neutron',
|
||||||
group='neutron', perms=0644),
|
group='neutron', perms=0o644),
|
||||||
call('/var/log/neutron/server.log', '', owner='neutron',
|
call('/var/log/neutron/server.log', '', owner='neutron',
|
||||||
group='neutron', perms=0644),
|
group='neutron', perms=0o644),
|
||||||
call('/var/log/neutron/sriov-agent.log', '', owner='neutron',
|
call('/var/log/neutron/sriov-agent.log', '', owner='neutron',
|
||||||
group='neutron', perms=0644),
|
group='neutron', perms=0o644),
|
||||||
call('/var/log/neutron/vpn_agent.log', '', owner='neutron',
|
call('/var/log/neutron/vpn_agent.log', '', owner='neutron',
|
||||||
group='neutron', perms=0644),
|
group='neutron', perms=0o644),
|
||||||
]
|
]
|
||||||
self.assertEqual(write_file.call_args_list, expected)
|
self.assertEqual(write_file.call_args_list, expected)
|
||||||
|
|
||||||
|
@ -36,7 +36,7 @@ def get_default_config():
|
|||||||
'''
|
'''
|
||||||
default_config = {}
|
default_config = {}
|
||||||
config = load_config()
|
config = load_config()
|
||||||
for k, v in config.iteritems():
|
for k, v in config.items():
|
||||||
if 'default' in v:
|
if 'default' in v:
|
||||||
default_config[k] = v['default']
|
default_config[k] = v['default']
|
||||||
else:
|
else:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user