Use FQDN when registering agents with Neutron

The change of behaviour will only affect newly installed
deployments on OpenStack Train and onwards.

Also set upper constraint for ``python-cinderclient`` in the
functional test requirements as it relies on the v1 client
which has been removed.  We will not fix this in Amulet, charm
pending migration to the Zaza framework.

Related-Bug: #1839300
Needed-By: Ia73ed6b76fc7f18014d4fa913397cc069e51ff07
Change-Id: Iee73164358745628a4b8658614608bc872771fd1
This commit is contained in:
Frode Nordahl 2019-09-15 21:42:23 +02:00
parent a3bc56aeb7
commit 31e2aabb03
No known key found for this signature in database
GPG Key ID: 6A5D59A3BA48373F
7 changed files with 121 additions and 5 deletions

View File

@ -15,6 +15,7 @@
import collections
import glob
import os
import socket
import uuid
from pci import PCINetDevices
from charmhelpers.core.hookenv import (
@ -35,7 +36,10 @@ from charmhelpers.contrib.openstack.utils import (
config_flags_parser,
get_host_ip,
)
from charmhelpers.contrib.network.ip import get_address_in_network
from charmhelpers.contrib.network.ip import (
get_address_in_network,
get_relation_ip,
)
from charmhelpers.contrib.openstack.context import (
OSContextGenerator,
NeutronAPIContext,
@ -584,3 +588,28 @@ class APIIdentityServiceContext(context.IdentityServiceContext):
if ctxt['region']:
return ctxt
return ctxt
class HostIPContext(context.OSContextGenerator):
def __call__(self):
ctxt = {}
# Use the address used in the neutron-plugin subordinate relation
host_ip = get_relation_ip('neutron-plugin')
# the contents of the Neutron ``host`` configuration option is
# referenced throughout a OpenStack deployment, an example being
# Neutron port bindings. It's value should not change after a
# individual units initial deployment.
#
# We do want to migrate to using FQDNs so we enable this for new
# installations.
db = kv()
if db.get('install_version', 0) >= 1910 and host_ip:
fqdn = socket.getfqdn(host_ip)
if '.' in fqdn:
# only populate the value if getfqdn() is able to find an
# actual FQDN for this host. If not, we revert back to
# not setting the configuration option and use Neutron's
# default behaviour.
ctxt['host'] = fqdn
return ctxt

View File

@ -43,6 +43,8 @@ from charmhelpers.core.host import (
is_container,
)
from charmhelpers.core.unitdata import kv
from neutron_ovs_utils import (
DHCP_PACKAGES,
DVR_PACKAGES,
@ -74,10 +76,14 @@ hooks = Hooks()
CONFIGS = register_configs()
@hooks.hook()
@hooks.hook('install.real')
def install():
install_packages()
db = kv()
db.set('install_version', 1910)
db.flush()
# NOTE(wolsen): Do NOT add restart_on_change decorator without consideration
# for the implications of modifications to the /etc/default/openvswitch-switch.

View File

@ -162,7 +162,9 @@ BASE_RESOURCE_MAP = OrderedDict([
['neutron-plugin', 'neutron-control']),
context.AMQPContext(ssl_dir=NEUTRON_CONF_DIR),
context.ZeroMQContext(),
context.NotificationDriverContext()],
context.NotificationDriverContext(),
neutron_ovs_context.HostIPContext(),
],
}),
(ML2_CONF, {
'services': ['neutron-plugin-openvswitch-agent'],

View File

@ -0,0 +1,52 @@
# stein
###############################################################################
# [ WARNING ]
# Configuration file maintained by Juju. Local changes may be overwritten.
# Config managed by neutron-openvswitch charm
# Service restart triggered by remote application: {{ restart_trigger }}
# {{ restart_trigger_neutron }}
###############################################################################
[DEFAULT]
verbose = {{ verbose }}
debug = {{ debug }}
use_syslog = {{ use_syslog }}
state_path = /var/lib/neutron
bind_host = 0.0.0.0
bind_port = 9696
{% if network_device_mtu -%}
network_device_mtu = {{ network_device_mtu }}
{% endif -%}
{% if core_plugin -%}
core_plugin = {{ core_plugin }}
{% endif -%}
{% if transport_url %}
transport_url = {{ transport_url }}
{% endif %}
{% if host -%}
host = {{ host }}
{% endif -%}
api_paste_config = /etc/neutron/api-paste.ini
auth_strategy = keystone
rpc_response_timeout = {{ rpc_response_timeout }}
{% include "section-zeromq" %}
{% include "section-oslo-messaging-rabbit-ocata" %}
{% include "section-oslo-notifications" %}
[QUOTAS]
[DEFAULT_SERVICETYPE]
[AGENT]
root_helper = sudo neutron-rootwrap /etc/neutron/rootwrap.conf
report_interval = {{ report_interval }}
[keystone_authtoken]
signing_dir = /var/lib/neutron/keystone-signing
[oslo_concurrency]
lock_path = $state_path/lock

View File

@ -12,7 +12,7 @@ requests>=2.18.4
amulet>=1.14.3,<2.0;python_version=='2.7'
bundletester>=0.6.1,<1.0;python_version=='2.7'
python-ceilometerclient>=1.5.0
python-cinderclient>=1.4.0
python-cinderclient>=1.4.0,<5.0.0
python-glanceclient>=1.1.0
python-heatclient>=0.8.0
python-keystoneclient>=1.7.1

View File

@ -941,3 +941,25 @@ class TestFirewallDriver(CharmTestCase):
self.lsb_release.return_value = _LSB_RELEASE_XENIAL
self.assertEqual(context._get_firewall_driver(ctxt),
context.IPTABLES_HYBRID)
class TestHostIPContext(CharmTestCase):
def setUp(self):
super(TestHostIPContext, self).setUp(context, TO_PATCH)
self.config.side_effect = self.test_config.get
@patch.object(context.socket, 'getfqdn')
@patch.object(context, 'kv')
@patch.object(context, 'get_relation_ip')
def test_host_ip_context(self, _get_relation_ip, _kv, _getfqdn):
_kv.return_value = {'install_version': 0}
_getfqdn.return_value = 'some'
ctxt = context.HostIPContext()
self.assertDictEqual({}, ctxt())
_getfqdn.return_value = 'some.hostname'
ctxt = context.HostIPContext()
self.assertDictEqual({}, ctxt())
_kv.return_value = {'install_version': 1910}
ctxt = context.HostIPContext()
self.assertDictEqual({'host': 'some.hostname'}, ctxt())

View File

@ -71,9 +71,14 @@ class NeutronOVSHooksTests(CharmTestCase):
hooks.hooks.execute([
'hooks/{}'.format(hookname)])
def test_install_hook(self):
@patch.object(hooks, 'kv')
def test_install_hook(self, _kv):
fake_dict = MagicMock()
_kv.return_value = fake_dict
self._call_hook('install')
self.install_packages.assert_called_with()
_kv.assert_called_once_with()
fake_dict.set.assert_called_once_with('install_version', 1910)
@patch('neutron_ovs_hooks.enable_sriov', MagicMock(return_value=False))
@patch.object(hooks, 'restart_map')