[freyes,r=hopem]
Install python-memcache, configure nova.conf adding the key memcached_servers when a relationship with memcached service is established. If multiple units of memcached are available, all of them are used i.e. memcached_servers = host1:port1,host2:port,host3:port3 To secure memcached access this relies in the memcached charm ability to use iptables rules to only allow access to related machines. Closes-Bug: 1386271
This commit is contained in:
commit
c42017fe2c
1
hooks/memcache-relation-broken
Symbolic link
1
hooks/memcache-relation-broken
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
nova_cc_hooks.py
|
1
hooks/memcache-relation-changed
Symbolic link
1
hooks/memcache-relation-changed
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
nova_cc_hooks.py
|
1
hooks/memcache-relation-departed
Symbolic link
1
hooks/memcache-relation-departed
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
nova_cc_hooks.py
|
1
hooks/memcache-relation-joined
Symbolic link
1
hooks/memcache-relation-joined
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
nova_cc_hooks.py
|
@ -6,6 +6,7 @@ from charmhelpers.core.hookenv import (
|
|||||||
ERROR,
|
ERROR,
|
||||||
unit_get,
|
unit_get,
|
||||||
related_units,
|
related_units,
|
||||||
|
relations_for_id,
|
||||||
relation_get,
|
relation_get,
|
||||||
)
|
)
|
||||||
from charmhelpers.fetch import (
|
from charmhelpers.fetch import (
|
||||||
@ -299,3 +300,24 @@ class NovaIPv6Context(context.BindHostContext):
|
|||||||
ctxt = super(NovaIPv6Context, self).__call__()
|
ctxt = super(NovaIPv6Context, self).__call__()
|
||||||
ctxt['use_ipv6'] = config('prefer-ipv6')
|
ctxt['use_ipv6'] = config('prefer-ipv6')
|
||||||
return ctxt
|
return ctxt
|
||||||
|
|
||||||
|
|
||||||
|
class InstanceConsoleContext(context.OSContextGenerator):
|
||||||
|
interfaces = []
|
||||||
|
|
||||||
|
def __call__(self):
|
||||||
|
ctxt = {}
|
||||||
|
servers = []
|
||||||
|
try:
|
||||||
|
for rid in relation_ids('memcache'):
|
||||||
|
for rel in relations_for_id(rid):
|
||||||
|
priv_addr = rel['private-address']
|
||||||
|
# Format it as IPv6 address if needed
|
||||||
|
priv_addr = format_ipv6_addr(priv_addr) or priv_addr
|
||||||
|
servers.append("%s:%s" % (priv_addr, rel['port']))
|
||||||
|
except Exception as ex:
|
||||||
|
log("Could not get memcache servers: %s" % (ex), level='WARNING')
|
||||||
|
servers = []
|
||||||
|
|
||||||
|
ctxt['memcached_servers'] = ','.join(servers)
|
||||||
|
return ctxt
|
||||||
|
@ -849,6 +849,15 @@ def neutron_api_relation_broken():
|
|||||||
quantum_joined(rid=rid)
|
quantum_joined(rid=rid)
|
||||||
|
|
||||||
|
|
||||||
|
@hooks.hook('memcache-relation-joined',
|
||||||
|
'memcache-relation-departed',
|
||||||
|
'memcache-relation-changed',
|
||||||
|
'memcache-relation-broken')
|
||||||
|
@restart_on_change(restart_map())
|
||||||
|
def memcached_joined():
|
||||||
|
CONFIGS.write(NOVA_CONF)
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
try:
|
try:
|
||||||
hooks.execute(sys.argv)
|
hooks.execute(sys.argv)
|
||||||
|
@ -69,6 +69,7 @@ BASE_PACKAGES = [
|
|||||||
'python-psutil',
|
'python-psutil',
|
||||||
'python-six',
|
'python-six',
|
||||||
'uuid',
|
'uuid',
|
||||||
|
'python-memcache',
|
||||||
]
|
]
|
||||||
|
|
||||||
BASE_SERVICES = [
|
BASE_SERVICES = [
|
||||||
@ -124,7 +125,8 @@ BASE_RESOURCE_MAP = OrderedDict([
|
|||||||
nova_cc_context.VolumeServiceContext(),
|
nova_cc_context.VolumeServiceContext(),
|
||||||
nova_cc_context.NovaIPv6Context(),
|
nova_cc_context.NovaIPv6Context(),
|
||||||
nova_cc_context.NeutronCCContext(),
|
nova_cc_context.NeutronCCContext(),
|
||||||
nova_cc_context.NovaConfigContext()],
|
nova_cc_context.NovaConfigContext(),
|
||||||
|
nova_cc_context.InstanceConsoleContext()],
|
||||||
}),
|
}),
|
||||||
(NOVA_API_PASTE, {
|
(NOVA_API_PASTE, {
|
||||||
'services': [s for s in BASE_SERVICES if 'api' in s],
|
'services': [s for s in BASE_SERVICES if 'api' in s],
|
||||||
|
@ -40,6 +40,8 @@ requires:
|
|||||||
nova-vmware:
|
nova-vmware:
|
||||||
interface: nova-vmware
|
interface: nova-vmware
|
||||||
scope: container
|
scope: container
|
||||||
|
memcache:
|
||||||
|
interface: memcache
|
||||||
peers:
|
peers:
|
||||||
cluster:
|
cluster:
|
||||||
interface: nova-ha
|
interface: nova-ha
|
||||||
|
@ -21,6 +21,11 @@ volumes_path=/var/lib/nova/volumes
|
|||||||
enabled_apis=ec2,osapi_compute,metadata
|
enabled_apis=ec2,osapi_compute,metadata
|
||||||
auth_strategy=keystone
|
auth_strategy=keystone
|
||||||
compute_driver=libvirt.LibvirtDriver
|
compute_driver=libvirt.LibvirtDriver
|
||||||
|
|
||||||
|
{% if memcached_servers %}
|
||||||
|
memcached_servers = {{ memcached_servers }}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
{% if keystone_ec2_url -%}
|
{% if keystone_ec2_url -%}
|
||||||
keystone_ec2_url = {{ keystone_ec2_url }}
|
keystone_ec2_url = {{ keystone_ec2_url }}
|
||||||
{% endif -%}
|
{% endif -%}
|
||||||
|
@ -20,6 +20,11 @@ volumes_path=/var/lib/nova/volumes
|
|||||||
enabled_apis=ec2,osapi_compute,metadata
|
enabled_apis=ec2,osapi_compute,metadata
|
||||||
auth_strategy=keystone
|
auth_strategy=keystone
|
||||||
compute_driver=libvirt.LibvirtDriver
|
compute_driver=libvirt.LibvirtDriver
|
||||||
|
|
||||||
|
{% if memcached_servers %}
|
||||||
|
memcached_servers = {{ memcached_servers }}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
{% if keystone_ec2_url -%}
|
{% if keystone_ec2_url -%}
|
||||||
keystone_ec2_url = {{ keystone_ec2_url }}
|
keystone_ec2_url = {{ keystone_ec2_url }}
|
||||||
{% endif -%}
|
{% endif -%}
|
||||||
|
@ -27,6 +27,10 @@ cpu_allocation_ratio = {{ cpu_allocation_ratio }}
|
|||||||
use_syslog={{ use_syslog }}
|
use_syslog={{ use_syslog }}
|
||||||
my_ip = {{ host_ip }}
|
my_ip = {{ host_ip }}
|
||||||
|
|
||||||
|
{% if memcached_servers %}
|
||||||
|
memcached_servers = {{ memcached_servers }}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
{% if keystone_ec2_url -%}
|
{% if keystone_ec2_url -%}
|
||||||
keystone_ec2_url = {{ keystone_ec2_url }}
|
keystone_ec2_url = {{ keystone_ec2_url }}
|
||||||
{% endif -%}
|
{% endif -%}
|
||||||
|
@ -38,6 +38,10 @@ ram_allocation_ratio = {{ ram_allocation_ratio }}
|
|||||||
use_syslog={{ use_syslog }}
|
use_syslog={{ use_syslog }}
|
||||||
my_ip = {{ host_ip }}
|
my_ip = {{ host_ip }}
|
||||||
|
|
||||||
|
{% if memcached_servers %}
|
||||||
|
memcached_servers = {{ memcached_servers }}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
{% if keystone_ec2_url -%}
|
{% if keystone_ec2_url -%}
|
||||||
keystone_ec2_url = {{ keystone_ec2_url }}
|
keystone_ec2_url = {{ keystone_ec2_url }}
|
||||||
{% endif -%}
|
{% endif -%}
|
||||||
|
87
unit_tests/test_nova_cc_contexts.py
Normal file
87
unit_tests/test_nova_cc_contexts.py
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
from __future__ import print_function
|
||||||
|
|
||||||
|
import mock
|
||||||
|
|
||||||
|
#####
|
||||||
|
# NOTE(freyes): this is a workaround to patch config() function imported by
|
||||||
|
# nova_cc_utils before it gets a reference to the actual config() provided by
|
||||||
|
# hookenv module.
|
||||||
|
from charmhelpers.core import hookenv
|
||||||
|
_conf = hookenv.config
|
||||||
|
hookenv.config = mock.MagicMock()
|
||||||
|
import nova_cc_utils as _utils
|
||||||
|
# this assert is a double check + to avoid pep8 warning
|
||||||
|
assert _utils.config == hookenv.config
|
||||||
|
hookenv.config = _conf
|
||||||
|
#####
|
||||||
|
|
||||||
|
import nova_cc_context as context
|
||||||
|
|
||||||
|
from charmhelpers.contrib.openstack import utils
|
||||||
|
|
||||||
|
from test_utils import CharmTestCase
|
||||||
|
|
||||||
|
|
||||||
|
TO_PATCH = [
|
||||||
|
'apt_install',
|
||||||
|
'filter_installed_packages',
|
||||||
|
'relation_ids',
|
||||||
|
'relation_get',
|
||||||
|
'related_units',
|
||||||
|
'config',
|
||||||
|
'log',
|
||||||
|
'unit_get',
|
||||||
|
'relations_for_id',
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
def fake_log(msg, level=None):
|
||||||
|
level = level or 'INFO'
|
||||||
|
print('[juju test log (%s)] %s' % (level, msg))
|
||||||
|
|
||||||
|
|
||||||
|
class NovaComputeContextTests(CharmTestCase):
|
||||||
|
def setUp(self):
|
||||||
|
super(NovaComputeContextTests, self).setUp(context, TO_PATCH)
|
||||||
|
self.relation_get.side_effect = self.test_relation.get
|
||||||
|
self.config.side_effect = self.test_config.get
|
||||||
|
self.log.side_effect = fake_log
|
||||||
|
|
||||||
|
@mock.patch.object(utils, 'os_release')
|
||||||
|
@mock.patch('charmhelpers.contrib.network.ip.log')
|
||||||
|
def test_instance_console_context_without_memcache(self, os_release, log_):
|
||||||
|
self.unit_get.return_value = '127.0.0.1'
|
||||||
|
self.relation_ids.return_value = 'cache:0'
|
||||||
|
self.related_units.return_value = 'memcached/0'
|
||||||
|
instance_console = context.InstanceConsoleContext()
|
||||||
|
os_release.return_value = 'icehouse'
|
||||||
|
self.assertEqual({'memcached_servers': ''},
|
||||||
|
instance_console())
|
||||||
|
|
||||||
|
@mock.patch.object(utils, 'os_release')
|
||||||
|
@mock.patch('charmhelpers.contrib.network.ip.log')
|
||||||
|
def test_instance_console_context_with_memcache(self, os_release, log_):
|
||||||
|
self.check_instance_console_context_with_memcache(os_release,
|
||||||
|
'127.0.1.1',
|
||||||
|
'127.0.1.1')
|
||||||
|
|
||||||
|
@mock.patch.object(utils, 'os_release')
|
||||||
|
@mock.patch('charmhelpers.contrib.network.ip.log')
|
||||||
|
def test_instance_console_context_with_memcache_ipv6(self, os_release,
|
||||||
|
log_):
|
||||||
|
self.check_instance_console_context_with_memcache(os_release, '::1',
|
||||||
|
'[::1]')
|
||||||
|
|
||||||
|
def check_instance_console_context_with_memcache(self, os_release, ip,
|
||||||
|
formated_ip):
|
||||||
|
memcached_servers = [{'private-address': formated_ip,
|
||||||
|
'port': '11211'}]
|
||||||
|
self.unit_get.return_value = ip
|
||||||
|
self.relation_ids.return_value = ['cache:0']
|
||||||
|
self.relations_for_id.return_value = memcached_servers
|
||||||
|
self.related_units.return_value = 'memcached/0'
|
||||||
|
instance_console = context.InstanceConsoleContext()
|
||||||
|
os_release.return_value = 'icehouse'
|
||||||
|
self.maxDiff = None
|
||||||
|
self.assertEqual({'memcached_servers': "%s:11211" % (formated_ip, )},
|
||||||
|
instance_console())
|
@ -1,6 +1,7 @@
|
|||||||
from mock import MagicMock, patch, call
|
from mock import MagicMock, patch, call
|
||||||
from test_utils import CharmTestCase, patch_open
|
from test_utils import CharmTestCase, patch_open
|
||||||
import os
|
import os
|
||||||
|
|
||||||
with patch('charmhelpers.core.hookenv.config') as config:
|
with patch('charmhelpers.core.hookenv.config') as config:
|
||||||
config.return_value = 'neutron'
|
config.return_value = 'neutron'
|
||||||
import nova_cc_utils as utils
|
import nova_cc_utils as utils
|
||||||
|
Loading…
Reference in New Issue
Block a user