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
|
destination: hooks/charmhelpers
|
||||||
include:
|
include:
|
||||||
- core
|
- core
|
||||||
|
@ -146,12 +146,12 @@ def get_hacluster_config():
|
|||||||
Obtains all relevant configuration from charm configuration required
|
Obtains all relevant configuration from charm configuration required
|
||||||
for initiating a relation to hacluster:
|
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.
|
returns: dict: A dict containing settings keyed by setting name.
|
||||||
raises: HAIncompleteConfig if settings are missing.
|
raises: HAIncompleteConfig if settings are missing.
|
||||||
'''
|
'''
|
||||||
settings = ['ha-bindiface', 'ha-mcastport', 'vip', 'vip_iface', 'vip_cidr']
|
settings = ['ha-bindiface', 'ha-mcastport', 'vip']
|
||||||
conf = {}
|
conf = {}
|
||||||
for setting in settings:
|
for setting in settings:
|
||||||
conf[setting] = config_get(setting)
|
conf[setting] = config_get(setting)
|
||||||
@ -163,7 +163,7 @@ def get_hacluster_config():
|
|||||||
return conf
|
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
|
Returns the correct HTTP URL to this host given the state of HTTPS
|
||||||
configuration and hacluster.
|
configuration and hacluster.
|
||||||
@ -180,5 +180,5 @@ def canonical_url(configs, vip_setting='vip', address=None):
|
|||||||
if is_clustered():
|
if is_clustered():
|
||||||
addr = config_get(vip_setting)
|
addr = config_get(vip_setting)
|
||||||
else:
|
else:
|
||||||
addr = address or unit_get('private-address')
|
addr = unit_get('private-address')
|
||||||
return '%s://%s' % (scheme, addr)
|
return '%s://%s' % (scheme, addr)
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
import sys
|
import sys
|
||||||
|
|
||||||
|
from functools import partial
|
||||||
|
|
||||||
from charmhelpers.fetch import apt_install
|
from charmhelpers.fetch import apt_install
|
||||||
from charmhelpers.core.hookenv import (
|
from charmhelpers.core.hookenv import (
|
||||||
ERROR, log,
|
ERROR, log,
|
||||||
@ -28,7 +30,7 @@ def _validate_cidr(network):
|
|||||||
|
|
||||||
def get_address_in_network(network, fallback=None, fatal=False):
|
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,
|
:param network (str): CIDR presentation format. For example,
|
||||||
'192.168.1.0/24'.
|
'192.168.1.0/24'.
|
||||||
@ -51,14 +53,22 @@ def get_address_in_network(network, fallback=None, fatal=False):
|
|||||||
not_found_error_out()
|
not_found_error_out()
|
||||||
|
|
||||||
_validate_cidr(network)
|
_validate_cidr(network)
|
||||||
|
network = netaddr.IPNetwork(network)
|
||||||
for iface in netifaces.interfaces():
|
for iface in netifaces.interfaces():
|
||||||
addresses = netifaces.ifaddresses(iface)
|
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']
|
addr = addresses[netifaces.AF_INET][0]['addr']
|
||||||
netmask = addresses[netifaces.AF_INET][0]['netmask']
|
netmask = addresses[netifaces.AF_INET][0]['netmask']
|
||||||
cidr = netaddr.IPNetwork("%s/%s" % (addr, netmask))
|
cidr = netaddr.IPNetwork("%s/%s" % (addr, netmask))
|
||||||
if cidr in netaddr.IPNetwork(network):
|
if cidr in network:
|
||||||
return str(cidr.ip)
|
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:
|
if fallback is not None:
|
||||||
return fallback
|
return fallback
|
||||||
@ -69,6 +79,17 @@ def get_address_in_network(network, fallback=None, fatal=False):
|
|||||||
return None
|
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):
|
def is_address_in_network(network, address):
|
||||||
"""
|
"""
|
||||||
Determine whether the provided address is within a network range.
|
Determine whether the provided address is within a network range.
|
||||||
@ -93,3 +114,43 @@ def is_address_in_network(network, address):
|
|||||||
return True
|
return True
|
||||||
else:
|
else:
|
||||||
return False
|
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])
|
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 '''
|
''' Add a port to the named openvswitch bridge '''
|
||||||
log('Adding port {} to bridge {}'.format(port, name))
|
log('Adding port {} to bridge {}'.format(port, name))
|
||||||
subprocess.check_call(["ovs-vsctl", "--", "--may-exist", "add-port",
|
subprocess.check_call(["ovs-vsctl", "--", "--may-exist", "add-port",
|
||||||
name, port])
|
name, port])
|
||||||
subprocess.check_call(["ip", "link", "set", port, "up"])
|
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):
|
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",
|
subprocess.check_call(["ovs-vsctl", "--", "--if-exists", "del-port",
|
||||||
name, port])
|
name, port])
|
||||||
subprocess.check_call(["ip", "link", "set", port, "down"])
|
subprocess.check_call(["ip", "link", "set", port, "down"])
|
||||||
|
subprocess.check_call(["ip", "link", "set", port, "promisc", "off"])
|
||||||
|
|
||||||
|
|
||||||
def set_manager(manager):
|
def set_manager(manager):
|
||||||
|
@ -25,6 +25,7 @@ from charmhelpers.core.hookenv import (
|
|||||||
unit_get,
|
unit_get,
|
||||||
unit_private_ip,
|
unit_private_ip,
|
||||||
ERROR,
|
ERROR,
|
||||||
|
INFO
|
||||||
)
|
)
|
||||||
|
|
||||||
from charmhelpers.contrib.hahelpers.cluster import (
|
from charmhelpers.contrib.hahelpers.cluster import (
|
||||||
@ -400,7 +401,9 @@ class HAProxyContext(OSContextGenerator):
|
|||||||
|
|
||||||
cluster_hosts = {}
|
cluster_hosts = {}
|
||||||
l_unit = local_unit().replace('/', '-')
|
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 rid in relation_ids('cluster'):
|
||||||
for unit in related_units(rid):
|
for unit in related_units(rid):
|
||||||
@ -712,7 +715,7 @@ class SubordinateConfigContext(OSContextGenerator):
|
|||||||
self.interface = interface
|
self.interface = interface
|
||||||
|
|
||||||
def __call__(self):
|
def __call__(self):
|
||||||
ctxt = {}
|
ctxt = {'sections': {}}
|
||||||
for rid in relation_ids(self.interface):
|
for rid in relation_ids(self.interface):
|
||||||
for unit in related_units(rid):
|
for unit in related_units(rid):
|
||||||
sub_config = relation_get('subordinate_configuration',
|
sub_config = relation_get('subordinate_configuration',
|
||||||
@ -738,10 +741,14 @@ class SubordinateConfigContext(OSContextGenerator):
|
|||||||
|
|
||||||
sub_config = sub_config[self.config_file]
|
sub_config = sub_config[self.config_file]
|
||||||
for k, v in sub_config.iteritems():
|
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:
|
log("%d section(s) found" % (len(ctxt['sections'])), level=INFO)
|
||||||
ctxt['sections'] = {}
|
|
||||||
|
|
||||||
return ctxt
|
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
|
import apt_pkg
|
||||||
if not pkgcache:
|
if not pkgcache:
|
||||||
apt_pkg.init()
|
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()
|
pkgcache = apt_pkg.Cache()
|
||||||
pkg = pkgcache[package]
|
pkg = pkgcache[package]
|
||||||
return apt_pkg.version_compare(pkg.current_ver.ver_str, revno)
|
return apt_pkg.version_compare(pkg.current_ver.ver_str, revno)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user