Add function for adding DNS HA resources
Add ability for charms to request DNS entries to be managed by hacluster via the hacluster interface. Change-Id: Id51f7553c806a62bbcb49c114fe48c6471642c10 Partial-Bug: #1727376 Depends-On: I1a6cdeffa3aa8657b957ba68cd09face27f93b27
This commit is contained in:
parent
575d729487
commit
cc03973a35
|
@ -2,12 +2,14 @@ import base64
|
|||
import contextlib
|
||||
import os
|
||||
import random
|
||||
import re
|
||||
import shutil
|
||||
import string
|
||||
import subprocess
|
||||
|
||||
import charmhelpers.contrib.network.ip as ch_ip
|
||||
import charmhelpers.contrib.openstack.utils as os_utils
|
||||
import charmhelpers.contrib.openstack.ha as os_ha
|
||||
import charmhelpers.core.hookenv as hookenv
|
||||
import charmhelpers.core.host as ch_host
|
||||
import charmhelpers.fetch as fetch
|
||||
|
@ -29,6 +31,7 @@ import charms_openstack.ip as os_ip
|
|||
VIP_KEY = "vip"
|
||||
CIDR_KEY = "vip_cidr"
|
||||
IFACE_KEY = "vip_iface"
|
||||
DNSHA_KEY = "dns-ha"
|
||||
APACHE_SSL_VHOST = '/etc/apache2/sites-available/openstack_https_frontend.conf'
|
||||
SYSTEM_CA_CERTS = '/etc/ssl/certs/ca-certificates.crt'
|
||||
SNAP_CA_CERTS = '/var/snap/{}/common/etc/ssl/certs/ca-certificates.crt'
|
||||
|
@ -421,6 +424,7 @@ class HAOpenStackCharm(OpenStackAPICharm):
|
|||
RESOURCE_TYPES = {
|
||||
'vips': self._add_ha_vips_config,
|
||||
'haproxy': self._add_ha_haproxy_config,
|
||||
'dnsha': self._add_dnsha_config,
|
||||
}
|
||||
if self.ha_resources:
|
||||
for res_type in self.ha_resources:
|
||||
|
@ -432,7 +436,9 @@ class HAOpenStackCharm(OpenStackAPICharm):
|
|||
|
||||
@param hacluster instance of interface class HAClusterRequires
|
||||
"""
|
||||
for vip in self.config.get(VIP_KEY, '').split():
|
||||
if not self.config.get(VIP_KEY):
|
||||
return
|
||||
for vip in self.config[VIP_KEY].split():
|
||||
iface = (ch_ip.get_iface_for_address(vip) or
|
||||
self.config.get(IFACE_KEY))
|
||||
netmask = (ch_ip.get_netmask_for_address(vip) or
|
||||
|
@ -447,6 +453,41 @@ class HAOpenStackCharm(OpenStackAPICharm):
|
|||
"""
|
||||
hacluster.add_init_service(self.name, 'haproxy')
|
||||
|
||||
def _add_dnsha_config(self, hacluster):
|
||||
"""Add a DNSHA object to self.resources
|
||||
|
||||
@param hacluster instance of interface class HAClusterRequires
|
||||
"""
|
||||
if not self.config.get(DNSHA_KEY):
|
||||
return
|
||||
settings = ['os-admin-hostname', 'os-internal-hostname',
|
||||
'os-public-hostname', 'os-access-hostname']
|
||||
|
||||
for setting in settings:
|
||||
hostname = self.config.get(setting)
|
||||
if hostname is None:
|
||||
hookenv.log(
|
||||
'DNS HA: Hostname setting {} is None. Ignoring.'.format(
|
||||
setting),
|
||||
hookenv.DEBUG)
|
||||
continue
|
||||
m = re.search('os-(.+?)-hostname', setting)
|
||||
if m:
|
||||
endpoint_type = m.group(1)
|
||||
# resolve_address's ADDRESS_MAP uses 'int' not 'internal'
|
||||
if endpoint_type == 'internal':
|
||||
endpoint_type = 'int'
|
||||
else:
|
||||
msg = (
|
||||
'Unexpected DNS hostname setting: {}. Cannot determine '
|
||||
'endpoint_type name'.format(setting))
|
||||
hookenv.status_set('blocked', msg)
|
||||
raise os_ha.DNSHAException(msg)
|
||||
ip = os_ip.resolve_address(
|
||||
endpoint_type=endpoint_type,
|
||||
override=False)
|
||||
hacluster.add_dnsha(self.name, ip, hostname, endpoint_type)
|
||||
|
||||
def set_haproxy_stat_password(self):
|
||||
"""Set a stats password for accessing haproxy statistics"""
|
||||
if not self.get_state('haproxy.stat.password'):
|
||||
|
|
|
@ -28,6 +28,8 @@ sys.modules['charmhelpers.core.templating'] = charmhelpers.core.templating
|
|||
sys.modules['charmhelpers.core.unitdata'] = charmhelpers.core.unitdata
|
||||
sys.modules['charmhelpers.contrib'] = charmhelpers.contrib
|
||||
sys.modules['charmhelpers.contrib.openstack'] = charmhelpers.contrib.openstack
|
||||
sys.modules['charmhelpers.contrib.openstack.ha'] = (
|
||||
charmhelpers.contrib.openstack.ha)
|
||||
sys.modules['charmhelpers.contrib.openstack.utils'] = (
|
||||
charmhelpers.contrib.openstack.utils)
|
||||
sys.modules['charmhelpers.contrib.openstack.templating'] = (
|
||||
|
|
|
@ -479,6 +479,13 @@ class TestHAOpenStackCharm(BaseOpenStackCharmTest):
|
|||
mock.call('myservice', 'vip2', 'user_iface', 'user_cidr')]
|
||||
interface_mock.add_vip.assert_has_calls(calls)
|
||||
|
||||
def test__add_ha_vips_config_novip(self):
|
||||
config = {'vip': None}
|
||||
self.patch_target('config', new=config)
|
||||
interface_mock = mock.Mock()
|
||||
self.target._add_ha_vips_config(interface_mock)
|
||||
self.assertFalse(interface_mock.add_vip.called)
|
||||
|
||||
def test__add_ha_haproxy_config(self):
|
||||
self.patch_target('name', new='myservice')
|
||||
interface_mock = mock.Mock()
|
||||
|
@ -487,6 +494,82 @@ class TestHAOpenStackCharm(BaseOpenStackCharmTest):
|
|||
'myservice',
|
||||
'haproxy')
|
||||
|
||||
def test__add_dnsha_config_single_dns_entry(self):
|
||||
config = {
|
||||
'dns-ha': True,
|
||||
'os-admin-hostname': 'myservice-admin.maas'}
|
||||
self.patch_target('config', new=config)
|
||||
self.patch_target('name', new='myservice')
|
||||
self.patch_object(chm.os_ip, 'resolve_address', '10.0.0.10')
|
||||
interface_mock = mock.Mock()
|
||||
self.target._add_dnsha_config(interface_mock)
|
||||
interface_mock.add_dnsha.assert_called_once_with(
|
||||
'myservice',
|
||||
'10.0.0.10',
|
||||
'myservice-admin.maas',
|
||||
'admin')
|
||||
|
||||
def test__add_dnsha_config_multi_dns_entries(self):
|
||||
config = {
|
||||
'dns-ha': True,
|
||||
'os-public-hostname': 'myservice-public.maas',
|
||||
'os-admin-hostname': 'myservice-admin.maas'}
|
||||
addr = {
|
||||
'public': '10.10.0.10',
|
||||
'admin': '10.0.0.10'}
|
||||
self.patch_target('config', new=config)
|
||||
self.patch_target('name', new='myservice')
|
||||
self.patch_object(
|
||||
chm.os_ip,
|
||||
'resolve_address',
|
||||
new=lambda endpoint_type, override=False: addr[endpoint_type])
|
||||
interface_mock = mock.Mock()
|
||||
self.target._add_dnsha_config(interface_mock)
|
||||
calls = [
|
||||
mock.call(
|
||||
'myservice',
|
||||
'10.0.0.10',
|
||||
'myservice-admin.maas',
|
||||
'admin'),
|
||||
mock.call(
|
||||
'myservice',
|
||||
'10.10.0.10',
|
||||
'myservice-public.maas',
|
||||
'public')]
|
||||
interface_mock.add_dnsha.assert_has_calls(calls)
|
||||
|
||||
def test__add_dnsha_config_single_internal_dns_entry(self):
|
||||
config = {
|
||||
'dns-ha': True,
|
||||
'os-internal-hostname': 'myservice-internal.maas'}
|
||||
self.patch_target('config', new=config)
|
||||
self.patch_target('name', new='myservice')
|
||||
self.patch_object(chm.os_ip, 'resolve_address', '10.0.0.10')
|
||||
interface_mock = mock.Mock()
|
||||
self.target._add_dnsha_config(interface_mock)
|
||||
interface_mock.add_dnsha.assert_called_once_with(
|
||||
'myservice',
|
||||
'10.0.0.10',
|
||||
'myservice-internal.maas',
|
||||
'int')
|
||||
|
||||
def test__add_dnsha_config_dns_ha_false(self):
|
||||
config = {
|
||||
'os-internal-hostname': 'myservice-internal.maas'
|
||||
}
|
||||
self.patch_target('config', new=config)
|
||||
interface_mock = mock.Mock()
|
||||
self.target._add_dnsha_config(interface_mock)
|
||||
self.assertFalse(interface_mock.add_dnsha.called)
|
||||
config['dns-ha'] = None
|
||||
interface_mock.reset_mock()
|
||||
self.target._add_dnsha_config(interface_mock)
|
||||
self.assertFalse(interface_mock.add_dnsha.called)
|
||||
config['dns-ha'] = False
|
||||
interface_mock.reset_mock()
|
||||
self.target._add_dnsha_config(interface_mock)
|
||||
self.assertFalse(interface_mock.add_dnsha.called)
|
||||
|
||||
def test_set_haproxy_stat_password(self):
|
||||
self.patch_object(chm.reactive.bus, 'get_state')
|
||||
self.patch_object(chm.reactive.bus, 'set_state')
|
||||
|
|
Loading…
Reference in New Issue