Rebase on trunk helpers
This commit is contained in:
parent
62dd6aa7dd
commit
32e85a148f
@ -1,4 +1,4 @@
|
||||
branch: lp:~james-page/charm-helpers/network-splits
|
||||
branch: lp:charm-helpers
|
||||
destination: hooks/charmhelpers
|
||||
include:
|
||||
- core
|
||||
|
@ -146,12 +146,12 @@ def get_hacluster_config():
|
||||
Obtains all relevant configuration from charm configuration required
|
||||
for initiating a relation to hacluster:
|
||||
|
||||
ha-bindiface, ha-mcastport, vip, vip_iface, vip_cidr
|
||||
ha-bindiface, ha-mcastport, vip
|
||||
|
||||
returns: dict: A dict containing settings keyed by setting name.
|
||||
raises: HAIncompleteConfig if settings are missing.
|
||||
'''
|
||||
settings = ['ha-bindiface', 'ha-mcastport', 'vip', 'vip_iface', 'vip_cidr']
|
||||
settings = ['ha-bindiface', 'ha-mcastport', 'vip']
|
||||
conf = {}
|
||||
for setting in settings:
|
||||
conf[setting] = config_get(setting)
|
||||
@ -163,7 +163,7 @@ def get_hacluster_config():
|
||||
return conf
|
||||
|
||||
|
||||
def canonical_url(configs, vip_setting='vip', address=None):
|
||||
def canonical_url(configs, vip_setting='vip'):
|
||||
'''
|
||||
Returns the correct HTTP URL to this host given the state of HTTPS
|
||||
configuration and hacluster.
|
||||
@ -180,5 +180,5 @@ def canonical_url(configs, vip_setting='vip', address=None):
|
||||
if is_clustered():
|
||||
addr = config_get(vip_setting)
|
||||
else:
|
||||
addr = address or unit_get('private-address')
|
||||
addr = unit_get('private-address')
|
||||
return '%s://%s' % (scheme, addr)
|
||||
|
@ -1,5 +1,7 @@
|
||||
import sys
|
||||
|
||||
from functools import partial
|
||||
|
||||
from charmhelpers.fetch import apt_install
|
||||
from charmhelpers.core.hookenv import (
|
||||
ERROR, log,
|
||||
@ -28,7 +30,7 @@ def _validate_cidr(network):
|
||||
|
||||
def get_address_in_network(network, fallback=None, fatal=False):
|
||||
"""
|
||||
Get an IPv4 address within the network from the host.
|
||||
Get an IPv4 or IPv6 address within the network from the host.
|
||||
|
||||
:param network (str): CIDR presentation format. For example,
|
||||
'192.168.1.0/24'.
|
||||
@ -51,14 +53,22 @@ def get_address_in_network(network, fallback=None, fatal=False):
|
||||
not_found_error_out()
|
||||
|
||||
_validate_cidr(network)
|
||||
network = netaddr.IPNetwork(network)
|
||||
for iface in netifaces.interfaces():
|
||||
addresses = netifaces.ifaddresses(iface)
|
||||
if netifaces.AF_INET in addresses:
|
||||
if network.version == 4 and netifaces.AF_INET in addresses:
|
||||
addr = addresses[netifaces.AF_INET][0]['addr']
|
||||
netmask = addresses[netifaces.AF_INET][0]['netmask']
|
||||
cidr = netaddr.IPNetwork("%s/%s" % (addr, netmask))
|
||||
if cidr in netaddr.IPNetwork(network):
|
||||
if cidr in network:
|
||||
return str(cidr.ip)
|
||||
if network.version == 6 and netifaces.AF_INET6 in addresses:
|
||||
for addr in addresses[netifaces.AF_INET6]:
|
||||
if not addr['addr'].startswith('fe80'):
|
||||
cidr = netaddr.IPNetwork("%s/%s" % (addr['addr'],
|
||||
addr['netmask']))
|
||||
if cidr in network:
|
||||
return str(cidr.ip)
|
||||
|
||||
if fallback is not None:
|
||||
return fallback
|
||||
@ -69,6 +79,17 @@ def get_address_in_network(network, fallback=None, fatal=False):
|
||||
return None
|
||||
|
||||
|
||||
def is_ipv6(address):
|
||||
'''Determine whether provided address is IPv6 or not'''
|
||||
try:
|
||||
address = netaddr.IPAddress(address)
|
||||
except netaddr.AddrFormatError:
|
||||
# probably a hostname - so not an address at all!
|
||||
return False
|
||||
else:
|
||||
return address.version == 6
|
||||
|
||||
|
||||
def is_address_in_network(network, address):
|
||||
"""
|
||||
Determine whether the provided address is within a network range.
|
||||
@ -93,3 +114,43 @@ def is_address_in_network(network, address):
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
|
||||
def _get_for_address(address, key):
|
||||
"""Retrieve an attribute of or the physical interface that
|
||||
the IP address provided could be bound to.
|
||||
|
||||
:param address (str): An individual IPv4 or IPv6 address without a net
|
||||
mask or subnet prefix. For example, '192.168.1.1'.
|
||||
:param key: 'iface' for the physical interface name or an attribute
|
||||
of the configured interface, for example 'netmask'.
|
||||
:returns str: Requested attribute or None if address is not bindable.
|
||||
"""
|
||||
address = netaddr.IPAddress(address)
|
||||
for iface in netifaces.interfaces():
|
||||
addresses = netifaces.ifaddresses(iface)
|
||||
if address.version == 4 and netifaces.AF_INET in addresses:
|
||||
addr = addresses[netifaces.AF_INET][0]['addr']
|
||||
netmask = addresses[netifaces.AF_INET][0]['netmask']
|
||||
cidr = netaddr.IPNetwork("%s/%s" % (addr, netmask))
|
||||
if address in cidr:
|
||||
if key == 'iface':
|
||||
return iface
|
||||
else:
|
||||
return addresses[netifaces.AF_INET][0][key]
|
||||
if address.version == 6 and netifaces.AF_INET6 in addresses:
|
||||
for addr in addresses[netifaces.AF_INET6]:
|
||||
if not addr['addr'].startswith('fe80'):
|
||||
cidr = netaddr.IPNetwork("%s/%s" % (addr['addr'],
|
||||
addr['netmask']))
|
||||
if address in cidr:
|
||||
if key == 'iface':
|
||||
return iface
|
||||
else:
|
||||
return addr[key]
|
||||
return None
|
||||
|
||||
|
||||
get_iface_for_address = partial(_get_for_address, key='iface')
|
||||
|
||||
get_netmask_for_address = partial(_get_for_address, key='netmask')
|
||||
|
@ -21,12 +21,16 @@ def del_bridge(name):
|
||||
subprocess.check_call(["ovs-vsctl", "--", "--if-exists", "del-br", name])
|
||||
|
||||
|
||||
def add_bridge_port(name, port):
|
||||
def add_bridge_port(name, port, promisc=False):
|
||||
''' Add a port to the named openvswitch bridge '''
|
||||
log('Adding port {} to bridge {}'.format(port, name))
|
||||
subprocess.check_call(["ovs-vsctl", "--", "--may-exist", "add-port",
|
||||
name, port])
|
||||
subprocess.check_call(["ip", "link", "set", port, "up"])
|
||||
if promisc:
|
||||
subprocess.check_call(["ip", "link", "set", port, "promisc", "on"])
|
||||
else:
|
||||
subprocess.check_call(["ip", "link", "set", port, "promisc", "off"])
|
||||
|
||||
|
||||
def del_bridge_port(name, port):
|
||||
@ -35,6 +39,7 @@ def del_bridge_port(name, port):
|
||||
subprocess.check_call(["ovs-vsctl", "--", "--if-exists", "del-port",
|
||||
name, port])
|
||||
subprocess.check_call(["ip", "link", "set", port, "down"])
|
||||
subprocess.check_call(["ip", "link", "set", port, "promisc", "off"])
|
||||
|
||||
|
||||
def set_manager(manager):
|
||||
|
@ -25,6 +25,7 @@ from charmhelpers.core.hookenv import (
|
||||
unit_get,
|
||||
unit_private_ip,
|
||||
ERROR,
|
||||
INFO
|
||||
)
|
||||
|
||||
from charmhelpers.contrib.hahelpers.cluster import (
|
||||
@ -148,7 +149,7 @@ class SharedDBContext(OSContextGenerator):
|
||||
if self.relation_prefix is not None:
|
||||
hostname_key = "{}_hostname".format(self.relation_prefix)
|
||||
else:
|
||||
hostname_key = "hostname"
|
||||
hostname_key = "hostname"
|
||||
access_hostname = get_address_in_network(access_network,
|
||||
unit_get('private-address'))
|
||||
set_hostname = relation_get(attribute=hostname_key,
|
||||
@ -400,7 +401,9 @@ class HAProxyContext(OSContextGenerator):
|
||||
|
||||
cluster_hosts = {}
|
||||
l_unit = local_unit().replace('/', '-')
|
||||
cluster_hosts[l_unit] = unit_get('private-address')
|
||||
cluster_hosts[l_unit] = \
|
||||
get_address_in_network(config('os-internal-network'),
|
||||
unit_get('private-address'))
|
||||
|
||||
for rid in relation_ids('cluster'):
|
||||
for unit in related_units(rid):
|
||||
@ -712,7 +715,7 @@ class SubordinateConfigContext(OSContextGenerator):
|
||||
self.interface = interface
|
||||
|
||||
def __call__(self):
|
||||
ctxt = {}
|
||||
ctxt = {'sections': {}}
|
||||
for rid in relation_ids(self.interface):
|
||||
for unit in related_units(rid):
|
||||
sub_config = relation_get('subordinate_configuration',
|
||||
@ -738,10 +741,14 @@ class SubordinateConfigContext(OSContextGenerator):
|
||||
|
||||
sub_config = sub_config[self.config_file]
|
||||
for k, v in sub_config.iteritems():
|
||||
ctxt[k] = v
|
||||
if k == 'sections':
|
||||
for section, config_dict in v.iteritems():
|
||||
log("adding section '%s'" % (section))
|
||||
ctxt[k][section] = config_dict
|
||||
else:
|
||||
ctxt[k] = v
|
||||
|
||||
if not ctxt:
|
||||
ctxt['sections'] = {}
|
||||
log("%d section(s) found" % (len(ctxt['sections'])), level=INFO)
|
||||
|
||||
return ctxt
|
||||
|
||||
|
@ -1,25 +0,0 @@
|
||||
|
||||
from netaddr import IPAddress, IPNetwork
|
||||
|
||||
class VIPConfiguration():
|
||||
|
||||
def __init__(self, configuration):
|
||||
self.vip = []
|
||||
for vip in configuration.split():
|
||||
self.vips.append(IPAddress(vip))
|
||||
|
||||
def getVIP(self, network):
|
||||
''' Determine the VIP for the provided network
|
||||
:network str: CIDR presented network, e.g. 192.168.1.1/24
|
||||
:returns str: IP address of VIP in provided network or None
|
||||
'''
|
||||
network = IPNetwork(network)
|
||||
for vip in self.vips:
|
||||
if vip in network:
|
||||
return str(vip)
|
||||
return None
|
||||
|
||||
def getNIC(self, network):
|
||||
''' Determine the physical network interface in use
|
||||
for the specified network'''
|
||||
|
@ -322,6 +322,10 @@ def cmp_pkgrevno(package, revno, pkgcache=None):
|
||||
import apt_pkg
|
||||
if not pkgcache:
|
||||
apt_pkg.init()
|
||||
# Force Apt to build its cache in memory. That way we avoid race
|
||||
# conditions with other applications building the cache in the same
|
||||
# place.
|
||||
apt_pkg.config.set("Dir::Cache::pkgcache", "")
|
||||
pkgcache = apt_pkg.Cache()
|
||||
pkg = pkgcache[package]
|
||||
return apt_pkg.version_compare(pkg.current_ver.ver_str, revno)
|
||||
|
Loading…
Reference in New Issue
Block a user