Resync https helpers

This commit is contained in:
James Page 2014-09-29 15:07:37 +01:00
parent a5cd0bdf96
commit e01355ae1e
7 changed files with 126 additions and 133 deletions

View File

@ -1,4 +1,4 @@
branch: lp:charm-helpers branch: lp:~james-page/charm-helpers/multiple-https-networks
destination: hooks/charmhelpers destination: hooks/charmhelpers
include: include:
- core - core

View File

@ -1,6 +1,3 @@
from bzrlib.branch import Branch
import os
import re
from charmhelpers.contrib.amulet.deployment import ( from charmhelpers.contrib.amulet.deployment import (
AmuletDeployment AmuletDeployment
) )
@ -19,41 +16,11 @@ class OpenStackAmuletDeployment(AmuletDeployment):
self.openstack = openstack self.openstack = openstack
self.source = source self.source = source
def _is_dev_branch(self):
"""Determine if branch being tested is a dev (i.e. next) branch."""
branch = Branch.open(os.getcwd())
parent = branch.get_parent()
pattern = re.compile("^.*/next/$")
if (pattern.match(parent)):
return True
else:
return False
def _determine_branch_locations(self, other_services):
"""Determine the branch locations for the other services.
If the branch being tested is a dev branch, then determine the
development branch locations for the other services. Otherwise,
the default charm store branches will be used."""
name = 0
if self._is_dev_branch():
updated_services = []
for svc in other_services:
if svc[name] in ['mysql', 'mongodb', 'rabbitmq-server']:
location = 'lp:charms/{}'.format(svc[name])
else:
temp = 'lp:~openstack-charmers/charms/trusty/{}/next'
location = temp.format(svc[name])
updated_services.append(svc + (location,))
other_services = updated_services
return other_services
def _add_services(self, this_service, other_services): def _add_services(self, this_service, other_services):
"""Add services to the deployment and set openstack-origin/source.""" """Add services to the deployment and set openstack-origin."""
name = 0
other_services = self._determine_branch_locations(other_services)
super(OpenStackAmuletDeployment, self)._add_services(this_service, super(OpenStackAmuletDeployment, self)._add_services(this_service,
other_services) other_services)
name = 0
services = other_services services = other_services
services.append(this_service) services.append(this_service)
use_source = ['mysql', 'mongodb', 'rabbitmq-server', 'ceph'] use_source = ['mysql', 'mongodb', 'rabbitmq-server', 'ceph']

View File

@ -187,16 +187,15 @@ class OpenStackAmuletUtils(AmuletUtils):
f = opener.open("http://download.cirros-cloud.net/version/released") f = opener.open("http://download.cirros-cloud.net/version/released")
version = f.read().strip() version = f.read().strip()
cirros_img = "cirros-{}-x86_64-disk.img".format(version) cirros_img = "tests/cirros-{}-x86_64-disk.img".format(version)
local_path = os.path.join('tests', cirros_img)
if not os.path.exists(local_path): if not os.path.exists(cirros_img):
cirros_url = "http://{}/{}/{}".format("download.cirros-cloud.net", cirros_url = "http://{}/{}/{}".format("download.cirros-cloud.net",
version, cirros_img) version, cirros_img)
opener.retrieve(cirros_url, local_path) opener.retrieve(cirros_url, cirros_img)
f.close() f.close()
with open(local_path) as f: with open(cirros_img) as f:
image = glance.images.create(name=image_name, is_public=True, image = glance.images.create(name=image_name, is_public=True,
disk_format='qcow2', disk_format='qcow2',
container_format='bare', data=f) container_format='bare', data=f)

View File

@ -52,7 +52,8 @@ from charmhelpers.contrib.openstack.neutron import (
from charmhelpers.contrib.network.ip import ( from charmhelpers.contrib.network.ip import (
get_address_in_network, get_address_in_network,
get_ipv6_addr, get_ipv6_addr,
is_address_in_network is_address_in_network,
get_netmask_for_address
) )
CA_CERT_PATH = '/usr/local/share/ca-certificates/keystone_juju_ca_cert.crt' CA_CERT_PATH = '/usr/local/share/ca-certificates/keystone_juju_ca_cert.crt'
@ -396,6 +397,9 @@ class CephContext(OSContextGenerator):
return ctxt return ctxt
ADDRESS_TYPES = ['admin', 'internal', 'public']
class HAProxyContext(OSContextGenerator): class HAProxyContext(OSContextGenerator):
interfaces = ['cluster'] interfaces = ['cluster']
@ -408,30 +412,57 @@ class HAProxyContext(OSContextGenerator):
if not relation_ids('cluster'): if not relation_ids('cluster'):
return {} return {}
cluster_hosts = {}
l_unit = local_unit().replace('/', '-') l_unit = local_unit().replace('/', '-')
if config('prefer-ipv6'): if config('prefer-ipv6'):
addr = get_ipv6_addr() addr = get_ipv6_addr()
else: else:
addr = unit_get('private-address') addr = unit_get('private-address')
cluster_hosts[l_unit] = get_address_in_network(config('os-internal-network'),
addr)
for rid in relation_ids('cluster'): cluster_hosts = {}
for unit in related_units(rid):
_unit = unit.replace('/', '-') # NOTE(jamespage): build out map of configured network endpoints
addr = relation_get('private-address', rid=rid, unit=unit) # and associated backends
cluster_hosts[_unit] = addr for addr_type in ADDRESS_TYPES:
laddr = get_address_in_network(
config('os-{}-network'.format(addr_type)))
if laddr:
cluster_hosts[laddr] = {}
cluster_hosts[laddr]['network'] = "{}/{}".format(
laddr,
get_netmask_for_address(laddr)
)
cluster_hosts[laddr]['backends'] = {}
cluster_hosts[laddr]['backends'][l_unit] = laddr
for rid in relation_ids('cluster'):
for unit in related_units(rid):
_unit = unit.replace('/', '-')
_laddr = relation_get('{}-address'.format(addr_type),
rid=rid, unit=unit)
if _laddr:
cluster_hosts[laddr]['backends'][_unit] = _laddr
# NOTE(jamespage) no split configurations found, just use
# private addresses
if len(cluster_hosts) < 1:
cluster_hosts[addr] = {}
cluster_hosts[addr]['network'] = "{}/{}".format(
addr,
get_netmask_for_address(addr)
)
cluster_hosts[addr]['backends'] = {}
cluster_hosts[addr]['backends'][l_unit] = addr
for rid in relation_ids('cluster'):
for unit in related_units(rid):
_unit = unit.replace('/', '-')
_laddr = relation_get('private-address',
rid=rid, unit=unit)
if _laddr:
cluster_hosts[addr]['backends'][_unit] = _laddr
ctxt = { ctxt = {
'units': cluster_hosts, 'frontends': cluster_hosts,
} }
if config('haproxy-server-timeout'):
ctxt['haproxy_server_timeout'] = config('haproxy-server-timeout')
if config('haproxy-client-timeout'):
ctxt['haproxy_client_timeout'] = config('haproxy-client-timeout')
if config('prefer-ipv6'): if config('prefer-ipv6'):
ctxt['local_host'] = 'ip6-localhost' ctxt['local_host'] = 'ip6-localhost'
ctxt['haproxy_host'] = '::' ctxt['haproxy_host'] = '::'
@ -441,12 +472,13 @@ class HAProxyContext(OSContextGenerator):
ctxt['haproxy_host'] = '0.0.0.0' ctxt['haproxy_host'] = '0.0.0.0'
ctxt['stat_port'] = ':8888' ctxt['stat_port'] = ':8888'
if len(cluster_hosts.keys()) > 1: for frontend in cluster_hosts:
# Enable haproxy when we have enough peers. if len(cluster_hosts[frontend]['backends']) > 1:
log('Ensuring haproxy enabled in /etc/default/haproxy.') # Enable haproxy when we have enough peers.
with open('/etc/default/haproxy', 'w') as out: log('Ensuring haproxy enabled in /etc/default/haproxy.')
out.write('ENABLED=1\n') with open('/etc/default/haproxy', 'w') as out:
return ctxt out.write('ENABLED=1\n')
return ctxt
log('HAProxy context is incomplete, this unit has no peers.') log('HAProxy context is incomplete, this unit has no peers.')
return {} return {}
@ -708,22 +740,22 @@ class NeutronContext(OSContextGenerator):
class OSConfigFlagContext(OSContextGenerator): class OSConfigFlagContext(OSContextGenerator):
""" """
Responsible for adding user-defined config-flags in charm config to a Responsible for adding user-defined config-flags in charm config to a
template context. template context.
NOTE: the value of config-flags may be a comma-separated list of NOTE: the value of config-flags may be a comma-separated list of
key=value pairs and some Openstack config files support key=value pairs and some Openstack config files support
comma-separated lists as values. comma-separated lists as values.
""" """
def __call__(self): def __call__(self):
config_flags = config('config-flags') config_flags = config('config-flags')
if not config_flags: if not config_flags:
return {} return {}
flags = config_flags_parser(config_flags) flags = config_flags_parser(config_flags)
return {'user_config_flags': flags} return {'user_config_flags': flags}
class SubordinateConfigContext(OSContextGenerator): class SubordinateConfigContext(OSContextGenerator):

View File

@ -14,17 +14,8 @@ defaults
retries 3 retries 3
timeout queue 1000 timeout queue 1000
timeout connect 1000 timeout connect 1000
{% if haproxy_client_timeout -%}
timeout client {{ haproxy_client_timeout }}
{% else -%}
timeout client 30000 timeout client 30000
{% endif -%}
{% if haproxy_server_timeout -%}
timeout server {{ haproxy_server_timeout }}
{% else -%}
timeout server 30000 timeout server 30000
{% endif -%}
listen stats {{ stat_port }} listen stats {{ stat_port }}
mode http mode http
@ -34,17 +25,21 @@ listen stats {{ stat_port }}
stats uri / stats uri /
stats auth admin:password stats auth admin:password
{% if units -%} {% if frontends -%}
{% for service, ports in service_ports.iteritems() -%} {% for service, ports in service_ports.iteritems() -%}
listen {{ service }}_ipv4 0.0.0.0:{{ ports[0] }} frontend tcp-in_{{ service }}
balance roundrobin bind *:{{ ports[0] }}
{% for unit, address in units.iteritems() -%} bind :::{{ ports[0] }}
server {{ unit }} {{ address }}:{{ ports[1] }} check {% for frontend in frontends -%}
acl net_{{ frontend }} dst {{ frontends[frontend]['network'] }}
use_backend {{ service }}_{{ frontend }} if net_{{ frontend }}
{% endfor %} {% endfor %}
listen {{ service }}_ipv6 :::{{ ports[0] }} {% for frontend in frontends -%}
balance roundrobin backend {{ service }}_{{ frontend }}
{% for unit, address in units.iteritems() -%} balance leastconn
{% for unit, address in frontends[frontend]['backends'].iteritems() -%}
server {{ unit }} {{ address }}:{{ ports[1] }} check server {{ unit }} {{ address }}:{{ ports[1] }} check
{% endfor %} {% endfor %}
{% endfor -%} {% endfor -%}
{% endfor -%}
{% endif -%} {% endif -%}

View File

@ -25,25 +25,30 @@ class AmuletDeployment(object):
Add services to the deployment where this_service is the local charm Add services to the deployment where this_service is the local charm
that we're testing and other_services are the other services that that we're testing and other_services are the other services that
are being used in the amulet tests. are being used in the local amulet tests.
""" """
name, units, location = range(3) if this_service['name'] != os.path.basename(os.getcwd()):
s = this_service['name']
if this_service[name] != os.path.basename(os.getcwd()):
s = this_service[name]
msg = "The charm's root directory name needs to be {}".format(s) msg = "The charm's root directory name needs to be {}".format(s)
amulet.raise_status(amulet.FAIL, msg=msg) amulet.raise_status(amulet.FAIL, msg=msg)
self.d.add(this_service[name], units=this_service[units]) if 'units' not in this_service:
this_service['units'] = 1
self.d.add(this_service['name'], units=this_service['units'])
for svc in other_services: for svc in other_services:
if len(svc) > 2: if 'location' in svc:
branch_location = svc[location] branch_location = svc['location']
elif self.series: elif self.series:
branch_location = 'cs:{}/{}'.format(self.series, svc[name]), branch_location = 'cs:{}/{}'.format(self.series, svc['name']),
else: else:
branch_location = None branch_location = None
self.d.add(svc[name], charm=branch_location, units=svc[units])
if 'units' not in svc:
svc['units'] = 1
self.d.add(svc['name'], charm=branch_location, units=svc['units'])
def _add_relations(self, relations): def _add_relations(self, relations):
"""Add all of the relations for the services.""" """Add all of the relations for the services."""

View File

@ -1,6 +1,3 @@
from bzrlib.branch import Branch
import os
import re
from charmhelpers.contrib.amulet.deployment import ( from charmhelpers.contrib.amulet.deployment import (
AmuletDeployment AmuletDeployment
) )
@ -13,62 +10,60 @@ class OpenStackAmuletDeployment(AmuletDeployment):
that is specifically for use by OpenStack charms. that is specifically for use by OpenStack charms.
""" """
def __init__(self, series=None, openstack=None, source=None): def __init__(self, series=None, openstack=None, source=None, stable=True):
"""Initialize the deployment environment.""" """Initialize the deployment environment."""
super(OpenStackAmuletDeployment, self).__init__(series) super(OpenStackAmuletDeployment, self).__init__(series)
self.openstack = openstack self.openstack = openstack
self.source = source self.source = source
self.stable = stable
def _is_dev_branch(self): # Note(coreycb): this needs to be changed when new next branches come out.
"""Determine if branch being tested is a dev (i.e. next) branch.""" self.current_next = "trusty"
branch = Branch.open(os.getcwd())
parent = branch.get_parent()
pattern = re.compile("^.*/next/$")
if (pattern.match(parent)):
return True
else:
return False
def _determine_branch_locations(self, other_services): def _determine_branch_locations(self, other_services):
"""Determine the branch locations for the other services. """Determine the branch locations for the other services.
If the branch being tested is a dev branch, then determine the Determine if the local branch being tested is derived from its
development branch locations for the other services. Otherwise, stable or next (dev) branch, and based on this, use the corresonding
the default charm store branches will be used.""" stable or next branches for the other_services."""
name = 0 base_charms = ['mysql', 'mongodb', 'rabbitmq-server']
if self._is_dev_branch():
updated_services = [] if self.stable:
for svc in other_services: for svc in other_services:
if svc[name] in ['mysql', 'mongodb', 'rabbitmq-server']: temp = 'lp:charms/{}'
location = 'lp:charms/{}'.format(svc[name]) svc['location'] = temp.format(svc['name'])
else:
for svc in other_services:
if svc['name'] in base_charms:
temp = 'lp:charms/{}'
svc['location'] = temp.format(svc['name'])
else: else:
temp = 'lp:~openstack-charmers/charms/trusty/{}/next' temp = 'lp:~openstack-charmers/charms/{}/{}/next'
location = temp.format(svc[name]) svc['location'] = temp.format(self.current_next,
updated_services.append(svc + (location,)) svc['name'])
other_services = updated_services
return other_services return other_services
def _add_services(self, this_service, other_services): def _add_services(self, this_service, other_services):
"""Add services to the deployment and set openstack-origin/source.""" """Add services to the deployment and set openstack-origin/source."""
name = 0
other_services = self._determine_branch_locations(other_services) other_services = self._determine_branch_locations(other_services)
super(OpenStackAmuletDeployment, self)._add_services(this_service, super(OpenStackAmuletDeployment, self)._add_services(this_service,
other_services) other_services)
services = other_services services = other_services
services.append(this_service) services.append(this_service)
use_source = ['mysql', 'mongodb', 'rabbitmq-server', 'ceph'] use_source = ['mysql', 'mongodb', 'rabbitmq-server', 'ceph']
if self.openstack: if self.openstack:
for svc in services: for svc in services:
if svc[name] not in use_source: if svc['name'] not in use_source:
config = {'openstack-origin': self.openstack} config = {'openstack-origin': self.openstack}
self.d.configure(svc[name], config) self.d.configure(svc['name'], config)
if self.source: if self.source:
for svc in services: for svc in services:
if svc[name] in use_source: if svc['name'] in use_source:
config = {'source': self.source} config = {'source': self.source}
self.d.configure(svc[name], config) self.d.configure(svc['name'], config)
def _configure_services(self, configs): def _configure_services(self, configs):
"""Configure all of the services.""" """Configure all of the services."""