def test_get_address_in_network_with_none(self, popen): fallback = '10.10.10.10' self.assertEqual(fallback, net_ip.get_address_in_network(None, fallback)) self.assertEqual(None, net_ip.get_address_in_network(None)) self.assertRaises(ValueError, self._test_get_address_in_network, None, None, fatal=True)
def get_listening(self, listen=['0.0.0.0']): """Returns a list of addresses SSH can list on Turns input into a sensible list of IPs SSH can listen on. Input must be a python list of interface names, IPs and/or CIDRs. :param listen: list of IPs, CIDRs, interface names :returns: list of IPs available on the host """ if listen == ['0.0.0.0']: return listen value = [] for network in listen: try: ip = get_address_in_network(network=network, fatal=True) except ValueError: if is_ip(network): ip = network else: try: ip = get_iface_addr(iface=network, fatal=False)[0] except IndexError: continue value.append(ip) if value == []: return ['0.0.0.0'] return value
def update_peers(self, cluster): for addr_type in os_ip.ADDRESS_MAP.keys(): cidr = self.config.get(os_ip.ADDRESS_MAP[addr_type]['config']) laddr = ch_ip.get_address_in_network(cidr) if laddr: cluster.set_address(os_ip.ADDRESS_MAP[addr_type]['binding'], laddr)
def resolve_address(endpoint_type=PUBLIC): resolved_address = None if is_clustered(): if config(_address_map[endpoint_type]['config']) is None: # Assume vip is simple and pass back directly resolved_address = config('vip') else: for vip in config('vip').split(): if is_address_in_network( config(_address_map[endpoint_type]['config']), vip): resolved_address = vip else: if config('prefer-ipv6'): fallback_addr = get_ipv6_addr() else: fallback_addr = unit_get(_address_map[endpoint_type]['fallback']) resolved_address = get_address_in_network( config(_address_map[endpoint_type]['config']), fallback_addr) if resolved_address is None: raise ValueError('Unable to resolve a suitable IP address' ' based on charm state and configuration') else: return resolved_address
def get_received_info(self): neighbors = [] for relation in self.relations: for unit in relation.units: if not ('asn' in unit.received and 'extra_bindings' in unit.received): ch_core.hookenv.log( 'Skip get_received_info() ' 'relation incomplete...', level=ch_core.hookenv.DEBUG) continue links = [] for addrinfo in unit.received['extra_bindings']: # filter list of networks to those we have interfaces # configured for ip = ch_net_ip.get_address_in_network(addrinfo['cidr']) if ip: links.append({ 'local': ip, 'remote': addrinfo['address'], 'cidr': addrinfo['cidr'] }) ch_core.hookenv.log("links: '{}'".format(links)) neighbors.append({ 'asn': unit.received['asn'], 'links': links, 'relation_id': relation.relation_id, 'remote_unit_name': unit.unit_name, }) return neighbors
def get_network_addresses(self): """For each network configured, return corresponding address and vip (if available). Returns a list of tuples of the form: [(address_in_net_a, vip_in_net_a), (address_in_net_b, vip_in_net_b), ...] or, if no vip(s) available: [(address_in_net_a, address_in_net_a), (address_in_net_b, address_in_net_b), ...] """ addresses = [] for net_type in ADDRESS_TYPES: net_cfg_opt = os_ip.ADDRESS_MAP[net_type]['config'].replace( '-', '_') config_cidr = getattr(self, net_cfg_opt, None) addr = ch_ip.get_address_in_network( config_cidr, hookenv.unit_get('private-address')) addresses.append( (addr, os_ip.resolve_address(endpoint_type=net_type))) return sorted(addresses)
def calico_ctxt(self): calico_ctxt = super(CalicoPluginContext, self).calico_ctxt() if not calico_ctxt: return {} conf = config() calico_ctxt['local_ip'] = \ get_address_in_network(config('os-data-network'), get_host_ip(unit_get('private-address'))) calico_ctxt['neutron_security_groups'] = self.neutron_security_groups calico_ctxt['use_syslog'] = conf['use-syslog'] calico_ctxt['verbose'] = conf['verbose'] calico_ctxt['debug'] = conf['debug'] calico_ctxt['peer_ips'] = [] calico_ctxt['peer_ips6'] = [] # Our BGP peers are either route reflectors or our cluster peers. # Prefer route reflectors. calico_ctxt['peer_ips'] = self.addrs_from_relation( 'bgp-route-reflector') calico_ctxt['peer_ips6'] = self.addrs_from_relation( 'bgp-route-reflector', ip_version=6) if not calico_ctxt['peer_ips']: calico_ctxt['peer_ips'] = self.addrs_from_relation('cluster') if not calico_ctxt['peer_ips6']: calico_ctxt['peer_ips6'] = self.addrs_from_relation('cluster', ip_version=6) return calico_ctxt
def get_network_addresses(self): """For each network configured, return corresponding address and vip (if available). Returns a list of tuples of the form: [(address_in_net_a, vip_in_net_a), (address_in_net_b, vip_in_net_b), ...] or, if no vip(s) available: [(address_in_net_a, address_in_net_a), (address_in_net_b, address_in_net_b), ...] """ addresses = [] for net_type in ADDRESS_TYPES: net_cfg_opt = os_ip.ADDRESS_MAP[net_type]['config'].replace('-', '_') config_cidr = getattr(self, net_cfg_opt, None) addr = ch_ip.get_address_in_network( config_cidr, hookenv.unit_get('private-address')) addresses.append( (addr, os_ip.resolve_address(endpoint_type=net_type))) return sorted(addresses)
def get_unit_ip(config_override=AMQP_OVERRIDE_CONFIG, interface=AMQP_INTERFACE): """Return this unit's IP. Future proof to allow for network spaces or other more complex addresss selection. @param config_override: string name of the config option for network override. Default to amqp-network @param interface: string name of the relation. Default to amqp. @raises Exception if prefer-ipv6 is configured but IPv6 unsupported. @returns IPv6 or IPv4 address """ fallback = get_host_ip(unit_get('private-address')) if config('prefer-ipv6'): assert_charm_supports_ipv6() return get_ipv6_addr()[0] elif config(config_override): # NOTE(jamespage) # override private-address settings if access-network is # configured and an appropriate network interface is # configured. return get_address_in_network(config(config_override), fallback) else: # NOTE(jamespage) # Try using network spaces if access-network is not # configured, fallback to private address if not # supported try: return network_get_primary_address(interface) except NotImplementedError: return fallback
def local_network_split_addresses(self): """Map of local units addresses for each address type NOTE: This excludes private-address @return dict of backends and networks for local unit e.g. {'this_unit_admin_addr': { 'backends': { 'this_unit-1': 'this_unit_admin_addr'}, 'network': 'this_unit_admin_addr/admin_netmask'}, 'this_unit_internal_addr': { 'backends': { 'this_unit-1': 'this_unit_internal_addr'}, 'network': 'this_unit_internal_addr/internal_netmask'}, 'this_unit_public_addr': { 'backends': { 'this_unit-1': 'this_unit_public_addr'}, 'network': 'this_unit_public_addr/public_netmask'}} """ config = hookenv.config() _cluster_hosts = {} for addr_type in ADDRESS_TYPES: cfg_opt = os_ip.ADDRESS_MAP[addr_type]['config'] laddr = ch_ip.get_address_in_network(config.get(cfg_opt)) if laddr: netmask = ch_ip.get_netmask_for_address(laddr) _cluster_hosts[laddr] = { 'network': "{}/{}".format(laddr, netmask), 'backends': {self.local_unit_name: laddr}} return _cluster_hosts
def cluster_joined(): relation_settings = {} if config('prefer-ipv6'): addr = get_ipv6_addr(exc_list=[config('vip')])[0] relation_settings = { 'private-address': addr, 'hostname': socket.gethostname() } cluster_network = config('cluster-network') if cluster_network: cluster_addr = get_address_in_network(cluster_network, fatal=True) relation_settings['cluster-address'] = cluster_addr else: try: cluster_addr = network_get_primary_address('cluster') relation_settings['cluster-address'] = cluster_addr except NotImplementedError: # NOTE(jamespage): skip - fallback to previous behaviour pass log("Setting cluster relation: '%s'" % (relation_settings), level=INFO) relation_set(relation_settings=relation_settings) # Ensure all new peers are aware cluster_state_uuid = relation_get('bootstrap-uuid', unit=local_unit()) if cluster_state_uuid: notify_bootstrapped(cluster_rid=relation_id(), cluster_uuid=cluster_state_uuid)
def local_network_split_addresses(self): """Map of local units addresses for each address type NOTE: This excludes private-address @return dict of backends and networks for local unit e.g. {'this_unit_admin_addr': { 'backends': { 'this_unit-1': 'this_unit_admin_addr'}, 'network': 'this_unit_admin_addr/admin_netmask'}, 'this_unit_internal_addr': { 'backends': { 'this_unit-1': 'this_unit_internal_addr'}, 'network': 'this_unit_internal_addr/internal_netmask'}, 'this_unit_public_addr': { 'backends': { 'this_unit-1': 'this_unit_public_addr'}, 'network': 'this_unit_public_addr/public_netmask'}} """ config = hookenv.config() _cluster_hosts = {} for addr_type in ADDRESS_TYPES: cfg_opt = os_ip.ADDRESS_MAP[addr_type]['config'] laddr = ch_ip.get_address_in_network(config.get(cfg_opt)) if laddr: netmask = ch_ip.get_netmask_for_address(laddr) _cluster_hosts[laddr] = { 'network': "{}/{}".format(laddr, netmask), 'backends': { self.local_unit_name: laddr } } return _cluster_hosts
def get_db_host(client_hostname): """Get address of local database host. If an access-network has been configured, expect selected address to be on that network. If none can be found, revert to primary address. If vip(s) are configured, chooses first available. """ vips = config('vip').split() if config('vip') else [] access_network = config('access-network') if access_network: client_ip = get_host_ip(client_hostname) if is_address_in_network(access_network, client_ip): if is_clustered(): for vip in vips: if is_address_in_network(access_network, vip): return vip log("Unable to identify a VIP in the access-network '%s'" % (access_network), level=WARNING) else: return get_address_in_network(access_network) else: log("Client address '%s' not in access-network '%s'" % (client_ip, access_network), level=WARNING) if is_clustered() and vips: return vips[0] # NOTE on private network if config('prefer-ipv6'): return get_ipv6_addr(exc_list=vips)[0] return unit_get('private-address')
def ovs_ctxt(self): # In addition to generating config context, ensure the OVS service # is running and the OVS bridge exists. Also need to ensure # local_ip points to actual IP, not hostname. ovs_ctxt = super(OVSPluginContext, self).ovs_ctxt() if not ovs_ctxt: return {} conf = config() fallback = get_host_ip(unit_get('private-address')) if config('os-data-network'): # NOTE: prefer any existing use of config based networking ovs_ctxt['local_ip'] = \ get_address_in_network(config('os-data-network'), fallback) else: # NOTE: test out network-spaces support, then fallback try: ovs_ctxt['local_ip'] = get_host_ip( network_get_primary_address('data') ) except NotImplementedError: ovs_ctxt['local_ip'] = fallback neutron_api_settings = NeutronAPIContext()() ovs_ctxt['neutron_security_groups'] = self.neutron_security_groups ovs_ctxt['l2_population'] = neutron_api_settings['l2_population'] ovs_ctxt['distributed_routing'] = neutron_api_settings['enable_dvr'] ovs_ctxt['overlay_network_type'] = \ neutron_api_settings['overlay_network_type'] # TODO: We need to sort out the syslog and debug/verbose options as a # general context helper ovs_ctxt['use_syslog'] = conf['use-syslog'] ovs_ctxt['verbose'] = conf['verbose'] ovs_ctxt['debug'] = conf['debug'] ovs_ctxt['prevent_arp_spoofing'] = conf['prevent-arp-spoofing'] ovs_ctxt['enable_dpdk'] = conf['enable-dpdk'] net_dev_mtu = neutron_api_settings.get('network_device_mtu') if net_dev_mtu: # neutron.conf ovs_ctxt['network_device_mtu'] = net_dev_mtu # ml2 conf ovs_ctxt['veth_mtu'] = net_dev_mtu mappings = config('bridge-mappings') if mappings: ovs_ctxt['bridge_mappings'] = ','.join(mappings.split()) flat_providers = config('flat-network-providers') if flat_providers: ovs_ctxt['network_providers'] = ','.join(flat_providers.split()) vlan_ranges = config('vlan-ranges') if vlan_ranges: ovs_ctxt['vlan_ranges'] = ','.join(vlan_ranges.split()) return ovs_ctxt
def __call__(self): api_settings = super(NeutronGatewayContext, self).__call__() ctxt = { 'shared_secret': get_shared_secret(), 'core_plugin': core_plugin(), 'plugin': config('plugin'), 'debug': config('debug'), 'verbose': config('verbose'), 'instance_mtu': config('instance-mtu'), 'l2_population': api_settings['l2_population'], 'enable_dvr': api_settings['enable_dvr'], 'enable_l3ha': api_settings['enable_l3ha'], 'overlay_network_type': api_settings['overlay_network_type'], 'enable_metadata_network': config('enable-metadata-network'), 'enable_isolated_metadata': config('enable-isolated-metadata'), } fallback = get_host_ip(unit_get('private-address')) if config('os-data-network'): # NOTE: prefer any existing use of config based networking ctxt['local_ip'] = \ get_address_in_network(config('os-data-network'), fallback) else: # NOTE: test out network-spaces support, then fallback try: ctxt['local_ip'] = get_host_ip( network_get_primary_address('data')) except NotImplementedError: ctxt['local_ip'] = fallback mappings = config('bridge-mappings') if mappings: ctxt['bridge_mappings'] = ','.join(mappings.split()) flat_providers = config('flat-network-providers') if flat_providers: ctxt['network_providers'] = ','.join(flat_providers.split()) vlan_ranges = config('vlan-ranges') if vlan_ranges: ctxt['vlan_ranges'] = ','.join(vlan_ranges.split()) dnsmasq_flags = config('dnsmasq-flags') if dnsmasq_flags: ctxt['dnsmasq_flags'] = config_flags_parser(dnsmasq_flags) net_dev_mtu = api_settings['network_device_mtu'] if net_dev_mtu: ctxt['network_device_mtu'] = net_dev_mtu ctxt['veth_mtu'] = net_dev_mtu # Override user supplied config for these plugins as these settings are # mandatory if ctxt['plugin'] in ['nvp', 'nsx', 'n1kv']: ctxt['enable_metadata_network'] = True ctxt['enable_isolated_metadata'] = True return ctxt
def update_peers(self, cluster): for addr_type in os_ip.ADDRESS_MAP.keys(): cidr = self.config.get(os_ip.ADDRESS_MAP[addr_type]['config']) laddr = ch_ip.get_address_in_network(cidr) if laddr: cluster.set_address( os_ip.ADDRESS_MAP[addr_type]['binding'], laddr)
def get_control_network_ip(control_network=None): network = control_network if not network: network = config.get("control-network") ip = get_address_in_network(network) if network else None if not ip: ip = iface_addr(VROUTER_INTERFACE)["addr"] return ip
def _test_get_address_in_network(self, expect_ip_addr, network, fallback=None, fatal=False): def side_effect(iface): return DUMMY_ADDRESSES[iface] with mock.patch.object(netifaces, 'interfaces') as interfaces: interfaces.return_value = sorted(DUMMY_ADDRESSES.keys()) with mock.patch.object(netifaces, 'ifaddresses') as ifaddresses: ifaddresses.side_effect = side_effect if not fatal: self.assertEqual(expect_ip_addr, net_ip.get_address_in_network(network, fallback, fatal)) else: net_ip.get_address_in_network(network, fallback, fatal)
def get_db_host(client_hostname, interface='shared-db'): """Get address of local database host. If an access-network has been configured, expect selected address to be on that network. If none can be found, revert to primary address. If network spaces are supported (Juju >= 2.0), use network-get to retrieve the network binding for the interface. If vip(s) are configured, chooses first available. """ vips = config('vip').split() if config('vip') else [] dns_ha = config('dns-ha') access_network = config('access-network') client_ip = get_host_ip(client_hostname) if is_clustered() and dns_ha: log("Using DNS HA hostname: {}".format(config('os-access-hostname'))) return config('os-access-hostname') elif access_network: if is_address_in_network(access_network, client_ip): if is_clustered(): for vip in vips: if is_address_in_network(access_network, vip): return vip log("Unable to identify a VIP in the access-network '%s'" % (access_network), level=WARNING) else: return get_address_in_network(access_network) else: log("Client address '%s' not in access-network '%s'" % (client_ip, access_network), level=WARNING) else: try: # NOTE(jamespage) # Try to use network spaces to resolve binding for # interface, and to resolve the VIP associated with # the binding if provided. interface_binding = network_get_primary_address(interface) if is_clustered() and vips: interface_cidr = resolve_network_cidr(interface_binding) for vip in vips: if is_address_in_network(interface_cidr, vip): return vip return interface_binding except NotImplementedError: # NOTE(jamespage): skip - fallback to previous behaviour pass if is_clustered() and vips: return vips[0] # NOTE on private network if config('prefer-ipv6'): return get_ipv6_addr(exc_list=vips)[0] return unit_get('private-address')
def ovs_ctxt(self): # In addition to generating config context, ensure the OVS service # is running and the OVS bridge exists. Also need to ensure # local_ip points to actual IP, not hostname. ovs_ctxt = super(OVSPluginContext, self).ovs_ctxt() if not ovs_ctxt: return {} conf = config() fallback = get_host_ip(unit_get('private-address')) if config('os-data-network'): # NOTE: prefer any existing use of config based networking ovs_ctxt['local_ip'] = \ get_address_in_network(config('os-data-network'), fallback) else: # NOTE: test out network-spaces support, then fallback try: ovs_ctxt['local_ip'] = get_host_ip( network_get_primary_address('data')) except NotImplementedError: ovs_ctxt['local_ip'] = fallback neutron_api_settings = NeutronAPIContext()() ovs_ctxt['neutron_security_groups'] = self.neutron_security_groups ovs_ctxt['l2_population'] = neutron_api_settings['l2_population'] ovs_ctxt['distributed_routing'] = neutron_api_settings['enable_dvr'] ovs_ctxt['overlay_network_type'] = \ neutron_api_settings['overlay_network_type'] # TODO: We need to sort out the syslog and debug/verbose options as a # general context helper ovs_ctxt['use_syslog'] = conf['use-syslog'] ovs_ctxt['verbose'] = conf['verbose'] ovs_ctxt['debug'] = conf['debug'] ovs_ctxt['prevent_arp_spoofing'] = conf['prevent-arp-spoofing'] ovs_ctxt['enable_dpdk'] = conf['enable-dpdk'] net_dev_mtu = neutron_api_settings.get('network_device_mtu') if net_dev_mtu: # neutron.conf ovs_ctxt['network_device_mtu'] = net_dev_mtu # ml2 conf ovs_ctxt['veth_mtu'] = net_dev_mtu mappings = config('bridge-mappings') if mappings: ovs_ctxt['bridge_mappings'] = ','.join(mappings.split()) flat_providers = config('flat-network-providers') if flat_providers: ovs_ctxt['network_providers'] = ','.join(flat_providers.split()) vlan_ranges = config('vlan-ranges') if vlan_ranges: ovs_ctxt['vlan_ranges'] = ','.join(vlan_ranges.split()) return ovs_ctxt
def get_networks(config_opt='ceph-public-network'): """Get all configured networks from provided config option. If public network(s) are provided, go through them and return those for which we have an address configured. """ networks = config(config_opt) if networks: networks = networks.split() return [n for n in networks if get_address_in_network(n)] return []
def get_local_ip(): fallback = get_host_ip(unit_get('private-address')) if config('os-data-network'): # NOTE: prefer any existing use of config based networking local_ip = get_address_in_network(config('os-data-network'), fallback) else: # NOTE: test out network-spaces support, then fallback try: local_ip = get_host_ip(network_get_primary_address('data')) except NotImplementedError: local_ip = fallback return local_ip
def cluster_joined(relation_id=None): for addr_type in ADDRESS_TYPES: address = get_address_in_network( config('os-{}-network'.format(addr_type))) if address: relation_set( relation_id=relation_id, relation_settings={'{}-address'.format(addr_type): address}) if config('prefer-ipv6'): private_addr = get_ipv6_addr(exc_list=[config('vip')])[0] relation_set(relation_id=relation_id, relation_settings={'private-address': private_addr})
def setup_database(database): """Send request designate accounts and dbs""" hostname = None if database.access_network(): hostname = ip.get_address_in_network(database.access_network()) database.configure('designate', 'designate', prefix='designate', hostname=hostname) database.configure('dpm', 'dpm', prefix='dpm', hostname=hostname) if database.base_data_complete(): reactive.set_state('shared-db.setup')
def __call__(self): api_settings = super(NeutronGatewayContext, self).__call__() ctxt = { 'shared_secret': get_shared_secret(), 'core_plugin': core_plugin(), 'plugin': config('plugin'), 'debug': config('debug'), 'verbose': config('verbose'), 'instance_mtu': config('instance-mtu'), 'l2_population': api_settings['l2_population'], 'enable_dvr': api_settings['enable_dvr'], 'enable_l3ha': api_settings['enable_l3ha'], 'overlay_network_type': api_settings['overlay_network_type'], } fallback = get_host_ip(unit_get('private-address')) if config('os-data-network'): # NOTE: prefer any existing use of config based networking ctxt['local_ip'] = \ get_address_in_network(config('os-data-network'), fallback) else: # NOTE: test out network-spaces support, then fallback try: ctxt['local_ip'] = get_host_ip( network_get_primary_address('data') ) except NotImplementedError: ctxt['local_ip'] = fallback mappings = config('bridge-mappings') if mappings: ctxt['bridge_mappings'] = ','.join(mappings.split()) flat_providers = config('flat-network-providers') if flat_providers: ctxt['network_providers'] = ','.join(flat_providers.split()) vlan_ranges = config('vlan-ranges') if vlan_ranges: ctxt['vlan_ranges'] = ','.join(vlan_ranges.split()) dnsmasq_flags = config('dnsmasq-flags') if dnsmasq_flags: ctxt['dnsmasq_flags'] = config_flags_parser(dnsmasq_flags) net_dev_mtu = api_settings['network_device_mtu'] if net_dev_mtu: ctxt['network_device_mtu'] = net_dev_mtu ctxt['veth_mtu'] = net_dev_mtu return ctxt
def get_db_host(client_hostname, interface='shared-db'): """Get address of local database host. If an access-network has been configured, expect selected address to be on that network. If none can be found, revert to primary address. If network spaces are supported (Juju >= 2.0), use network-get to retrieve the network binding for the interface. If vip(s) are configured, chooses first available. """ vips = config('vip').split() if config('vip') else [] access_network = config('access-network') client_ip = get_host_ip(client_hostname) if access_network: if is_address_in_network(access_network, client_ip): if is_clustered(): for vip in vips: if is_address_in_network(access_network, vip): return vip log("Unable to identify a VIP in the access-network '%s'" % (access_network), level=WARNING) else: return get_address_in_network(access_network) else: log("Client address '%s' not in access-network '%s'" % (client_ip, access_network), level=WARNING) else: try: # NOTE(jamespage) # Try to use network spaces to resolve binding for # interface, and to resolve the VIP associated with # the binding if provided. interface_binding = network_get_primary_address(interface) if is_clustered() and vips: interface_cidr = resolve_network_cidr(interface_binding) for vip in vips: if is_address_in_network(interface_cidr, vip): return vip return interface_binding except NotImplementedError: # NOTE(jamespage): skip - fallback to previous behaviour pass if is_clustered() and vips: return vips[0] # NOTE on private network if config('prefer-ipv6'): return get_ipv6_addr(exc_list=vips)[0] return unit_get('private-address')
def odl_node_registration(controller=None): """ Register node with ODL if not registered already """ if controller and controller.connection(): odl = ODL.ODLConfig(**controller.connection()) device_name = gethostname() if odl.is_device_registered(device_name): log('{} is already registered in odl'.format(device_name)) else: local_ip = get_address_in_network(config('os-data-network'), unit_private_ip()) log('Registering {} ({}) in odl'.format( device_name, local_ip)) odl.odl_register_node(device_name, local_ip)
def cluster_joined(relation_id=None): for addr_type in ADDRESS_TYPES: netaddr_cfg = 'os-{}-network'.format(addr_type) address = get_address_in_network(config(netaddr_cfg)) if address: settings = {'{}-address'.format(addr_type): address} relation_set(relation_id=relation_id, relation_settings=settings) if config('prefer-ipv6'): private_addr = get_ipv6_addr(exc_list=[config('vip')])[0] relation_set(relation_id=relation_id, relation_settings={'private-address': private_addr}) else: private_addr = unit_get('private-address')
def get_local_ip(): fallback = get_host_ip(unit_get('private-address')) if config('os-data-network'): # NOTE: prefer any existing use of config based networking local_ip = get_address_in_network( config('os-data-network'), fallback) else: # NOTE: test out network-spaces support, then fallback try: local_ip = get_host_ip(network_get_primary_address('data')) except NotImplementedError: local_ip = fallback return local_ip
def __call__(self): self.database = self.database or config('database') self.user = self.user or config('database-user') if None in [self.database, self.user]: log( "Could not generate shared_db context. Missing required charm " "config options. (database name and user)", level=ERROR) raise OSContextError ctxt = {} # NOTE(jamespage) if mysql charm provides a network upon which # access to the database should be made, reconfigure relation # with the service units local address and defer execution access_network = relation_get('access-network') if access_network is not None: if self.relation_prefix is not None: hostname_key = "{}_hostname".format(self.relation_prefix) else: hostname_key = "hostname" access_hostname = get_address_in_network( access_network, unit_get('private-address')) set_hostname = relation_get(attribute=hostname_key, unit=local_unit()) if set_hostname != access_hostname: relation_set(relation_settings={hostname_key: access_hostname}) return None # Defer any further hook execution for now.... password_setting = 'password' if self.relation_prefix: password_setting = self.relation_prefix + '_password' for rid in relation_ids(self.interfaces[0]): self.related = True for unit in related_units(rid): rdata = relation_get(rid=rid, unit=unit) host = rdata.get('db_host') host = format_ipv6_addr(host) or host ctxt = { 'database_host': host, 'database': self.database, 'database_user': self.user, 'database_password': rdata.get(password_setting), 'database_type': 'mysql' } if self.context_complete(ctxt): db_ssl(rdata, ctxt, self.ssl_dir) return ctxt return {}
def cluster_joined(rid=None): settings = {} for addr_type in ADDRESS_TYPES: address = get_address_in_network( config('os-{}-network'.format(addr_type))) if address: settings['{}-address'.format(addr_type)] = address if config('prefer-ipv6'): private_addr = get_ipv6_addr(exc_list=[config('vip')])[0] settings['private-address'] = private_addr relation_set(relation_id=rid, **settings)
def listen(self, cidr=None, port=None): port = port or self.IPERF_BASE_PORT if cidr: bind_addreess = ch_ip.get_address_in_network(cidr) else: bind_addreess = ( hookenv.network_get('magpie') ['bind-addresses'][0]['addresses'][0]['address'] ) cmd = ( "iperf -s -m -fm --port " + str(port) + " -B " + bind_addreess + " | tee " + self.iperf_out + " &" ) os.system(cmd)
def get_ip(): network = config.get("control-network") if network: # try to get ip from CIDR try: return get_address_in_network(network) except Exception: pass # try to get ip from interface name try: return get_iface_addr(network)[0] except Exception: pass return _get_default_ip()
def get_cluster_hosts(): hosts_map = {} if config('cluster-network'): hostname = get_address_in_network(config('cluster-network'), fatal=True) else: try: hostname = network_get_primary_address('cluster') except NotImplementedError: # NOTE(jamespage): skip - fallback to previous behaviour hostname = get_host_ip() # We need to add this localhost dns name to /etc/hosts along with peer # hosts to ensure percona gets consistently resolved addresses. if config('prefer-ipv6'): addr = get_ipv6_addr(exc_list=[config('vip')], fatal=True)[0] hosts_map = {addr: hostname} hosts = [hostname] for relid in relation_ids('cluster'): for unit in related_units(relid): rdata = relation_get(unit=unit, rid=relid) # NOTE(dosaboy): see LP: #1599447 cluster_address = rdata.get('cluster-address', rdata.get('private-address')) if config('prefer-ipv6'): hostname = rdata.get('hostname') if not hostname or hostname in hosts: log("(unit=%s) Ignoring hostname '%s' provided by cluster " "relation for addr %s" % (unit, hostname, cluster_address), level=DEBUG) continue else: log("(unit=%s) hostname '%s' provided by cluster relation " "for addr %s" % (unit, hostname, cluster_address), level=DEBUG) hosts_map[cluster_address] = hostname hosts.append(hostname) else: hosts.append(get_host_ip(cluster_address)) if hosts_map: update_hosts_file(hosts_map) return hosts
def __call__(self): if isinstance(self.external_ports, basestring): self.external_ports = [self.external_ports] if (not self.external_ports or not https()): return {} self.configure_ca() self.enable_modules() ctxt = { 'namespace': self.service_namespace, 'endpoints': [], 'ext_ports': [] } for cn in self.canonical_names(): self.configure_cert(cn) addresses = [] vips = [] if config('vip'): vips = config('vip').split() for network_type in ['os-internal-network', 'os-admin-network', 'os-public-network']: address = get_address_in_network(config(network_type), unit_get('private-address')) if len(vips) > 0 and is_clustered(): for vip in vips: if is_address_in_network(config(network_type), vip): addresses.append((address, vip)) break elif is_clustered(): addresses.append((address, config('vip'))) else: addresses.append((address, address)) for address, endpoint in set(addresses): for api_port in self.external_ports: ext_port = determine_apache_port(api_port) int_port = determine_api_port(api_port) portmap = (address, endpoint, int(ext_port), int(int_port)) ctxt['endpoints'].append(portmap) ctxt['ext_ports'].append(int(ext_port)) ctxt['ext_ports'] = list(set(ctxt['ext_ports'])) return ctxt
def __call__(self): self.database = self.database or config('database') self.user = self.user or config('database-user') if None in [self.database, self.user]: log("Could not generate shared_db context. Missing required charm " "config options. (database name and user)", level=ERROR) raise OSContextError ctxt = {} # NOTE(jamespage) if mysql charm provides a network upon which # access to the database should be made, reconfigure relation # with the service units local address and defer execution access_network = relation_get('access-network') if access_network is not None: if self.relation_prefix is not None: hostname_key = "{}_hostname".format(self.relation_prefix) else: hostname_key = "hostname" access_hostname = get_address_in_network(access_network, unit_get('private-address')) set_hostname = relation_get(attribute=hostname_key, unit=local_unit()) if set_hostname != access_hostname: relation_set(relation_settings={hostname_key: access_hostname}) return None # Defer any further hook execution for now.... password_setting = 'password' if self.relation_prefix: password_setting = self.relation_prefix + '_password' for rid in relation_ids(self.interfaces[0]): self.related = True for unit in related_units(rid): rdata = relation_get(rid=rid, unit=unit) host = rdata.get('db_host') host = format_ipv6_addr(host) or host ctxt = { 'database_host': host, 'database': self.database, 'database_user': self.user, 'database_password': rdata.get(password_setting), 'database_type': 'mysql' } if self.context_complete(ctxt): db_ssl(rdata, ctxt, self.ssl_dir) return ctxt return {}
def get_ip(config_param="control-network", fallback=None): network = config.get(config_param) if network: # try to get ip from CIDR try: ip = get_address_in_network(network, fatal=True) return ip except Exception: pass # try to get ip from interface name try: return get_iface_addr(network, fatal=True)[0] except Exception: pass return fallback if fallback else _get_default_ip()
def configure_openvswitch(onos_ovsdb): db = kv() # NOTE(jamespage): Check connection string as well # broken/departed seems busted right now if db.get('installed') and onos_ovsdb.connection_string(): log("Configuring OpenvSwitch with ONOS controller: %s" % onos_ovsdb.connection_string()) # log("onos prepare compute br-ex,onos_port1,onos_port2.") # ports = config('ext-port') # print 'external port is ' + ports # shutil.copy("files/onos_pre.sh", "/") # check_call("sh /onos_pre.sh " + ports,shell=True) local_ip = get_address_in_network(config('os-data-network'), unit_private_ip()) ovs.set_manager(onos_ovsdb.connection_string()) status_set('active', 'Open vSwitch configured and ready')
def ovs_ctxt(self): # In addition to generating config context, ensure the OVS service # is running and the OVS bridge exists. Also need to ensure # local_ip points to actual IP, not hostname. ovs_ctxt = super(NeutronComputeContext, self).ovs_ctxt() if not ovs_ctxt: return {} if config('manage-neutron-plugin-legacy-mode'): self._ensure_packages() self._ensure_bridge() ovs_ctxt['local_ip'] = \ get_address_in_network(config('os-data-network'), get_host_ip(unit_get('private-address'))) return ovs_ctxt
def cluster_joined(): unison.ssh_authorized_peers(user=SSH_USER, group="juju_keystone", peer_interface="cluster", ensure_local_user=True) settings = {} for addr_type in ADDRESS_TYPES: address = get_address_in_network(config("os-{}-network".format(addr_type))) if address: settings["{}-address".format(addr_type)] = address if config("prefer-ipv6"): private_addr = get_ipv6_addr(exc_list=[config("vip")])[0] settings["private-address"] = private_addr relation_set(relation_settings=settings) send_ssl_sync_request()
def configure_openvswitch(odl_ovsdb): db = kv() # NOTE(jamespage): Check connection string as well # broken/departed seems busted right now if db.get('installed') and odl_ovsdb.connection_string(): log("Configuring OpenvSwitch with ODL OVSDB controller: %s" % odl_ovsdb.connection_string()) local_ip = get_address_in_network(config('os-data-network'), unit_private_ip()) ovs.set_config('local_ip', local_ip) ovs.set_config('controller-ips', odl_ovsdb.private_address(), table='external_ids') ovs.set_config('host-id', gethostname(), table='external_ids') ovs.set_manager(odl_ovsdb.connection_string()) status_set('active', 'Open vSwitch configured and ready')
def add_network_split_addresses(self): """Populate cluster_hosts with addresses of this unit and its peers on each address type @return None """ for addr_type in ADDRESS_TYPES: cfg_opt = os_ip.ADDRESS_MAP[addr_type]['config'] laddr = ch_ip.get_address_in_network(self.config.get(cfg_opt)) if laddr: self.cluster_hosts[laddr] = \ self.local_network_split_addresses()[laddr] key = '{}-address'.format( os_ip.ADDRESS_MAP[addr_type]['binding']) for _unit, _laddr in self.relation.ip_map(address_key=key): if _laddr: self.cluster_hosts[laddr]['backends'][_unit] = _laddr
def internal_addresses(self): """Return list of internal addresses of this unit and peers Return list of internal addresses of this unit and peers. If no internal address cidr has been set return private addresses. @return list [ip1, ip2, ...] """ cfg_opt = os_ip.ADDRESS_MAP[os_ip.INTERNAL]['config'] int_net = self.config.get(cfg_opt) laddr = ch_ip.get_address_in_network(int_net) or self.local_address try: hosts = sorted(list( self.cluster_hosts[laddr]['backends'].values())) except KeyError: hosts = [laddr] return hosts
def resolve_address(endpoint_type=PUBLIC): """Return unit address depending on net config. If unit is clustered with vip(s) and has net splits defined, return vip on correct network. If clustered with no nets defined, return primary vip. If not clustered, return unit address ensuring address is on configured net split if one is configured. :param endpoint_type: Network endpoing type """ resolved_address = _get_address_override(endpoint_type) if resolved_address: return resolved_address vips = config('vip') if vips: vips = vips.split() net_type = ADDRESS_MAP[endpoint_type]['config'] net_addr = config(net_type) net_fallback = ADDRESS_MAP[endpoint_type]['fallback'] clustered = is_clustered() if clustered: if not net_addr: # If no net-splits defined, we expect a single vip resolved_address = vips[0] else: for vip in vips: if is_address_in_network(net_addr, vip): resolved_address = vip break else: if config('prefer-ipv6'): fallback_addr = get_ipv6_addr(exc_list=vips)[0] else: fallback_addr = unit_get(net_fallback) resolved_address = get_address_in_network(net_addr, fallback_addr) if resolved_address is None: raise ValueError("Unable to resolve a suitable IP address based on " "charm state and configuration. (net_type=%s, " "clustered=%s)" % (net_type, clustered)) return resolved_address
def __call__(self): api_settings = super(NeutronGatewayContext, self).__call__() ctxt = { 'shared_secret': get_shared_secret(), 'local_ip': get_address_in_network(config('os-data-network'), get_host_ip(unit_get('private-address'))), 'core_plugin': core_plugin(), 'plugin': config('plugin'), 'debug': config('debug'), 'verbose': config('verbose'), 'instance_mtu': config('instance-mtu'), 'l2_population': api_settings['l2_population'], 'enable_dvr': api_settings['enable_dvr'], 'enable_l3ha': api_settings['enable_l3ha'], 'overlay_network_type': api_settings['overlay_network_type'], } mappings = config('bridge-mappings') if mappings: ctxt['bridge_mappings'] = ','.join(mappings.split()) flat_providers = config('flat-network-providers') if flat_providers: ctxt['network_providers'] = ','.join(flat_providers.split()) vlan_ranges = config('vlan-ranges') if vlan_ranges: ctxt['vlan_ranges'] = ','.join(vlan_ranges.split()) net_dev_mtu = api_settings['network_device_mtu'] if net_dev_mtu: ctxt['network_device_mtu'] = net_dev_mtu ctxt['veth_mtu'] = net_dev_mtu return ctxt
def get_cluster_host_ip(): """Get the this host's IP address for use with percona cluster peers @returns IP to pass to cluster peers """ cluster_network = config('cluster-network') if cluster_network: cluster_addr = get_address_in_network(cluster_network, fatal=True) else: try: cluster_addr = network_get_primary_address('cluster') except NotImplementedError: # NOTE(jamespage): fallback to previous behaviour cluster_addr = resolve_hostname_to_ip(unit_get('private-address')) return cluster_addr
def internal_addresses(self): """Return list of internal addresses of this unit and peers Return list of internal addresses of this unit and peers. If no internal address cidr has been set return private addresses. @return list [ip1, ip2, ...] """ cfg_opt = os_ip.ADDRESS_MAP[os_ip.INTERNAL]['config'] int_net = self.config.get(cfg_opt) laddr = ch_ip.get_address_in_network(int_net) or self.local_address try: hosts = sorted( list(self.cluster_hosts[laddr]['backends'].values())) except KeyError: hosts = [laddr] return hosts
def __call__(self): ''' Builds half a context for the haproxy template, which describes all peers to be included in the cluster. Each charm needs to include its own context generator that describes the port mapping. ''' if not relation_ids('cluster'): return {} cluster_hosts = {} l_unit = local_unit().replace('/', '-') if config('prefer-ipv6'): addr = get_ipv6_addr() else: addr = unit_get('private-address') cluster_hosts[l_unit] = get_address_in_network(config('os-internal-network'), addr) for rid in relation_ids('cluster'): for unit in related_units(rid): _unit = unit.replace('/', '-') addr = relation_get('private-address', rid=rid, unit=unit) cluster_hosts[_unit] = addr ctxt = { 'units': cluster_hosts, } if config('prefer-ipv6'): ctxt['local_host'] = 'ip6-localhost' ctxt['haproxy_host'] = '::' ctxt['stat_port'] = ':::8888' else: ctxt['local_host'] = '127.0.0.1' ctxt['haproxy_host'] = '0.0.0.0' ctxt['stat_port'] = ':8888' if len(cluster_hosts.keys()) > 1: # Enable haproxy when we have enough peers. log('Ensuring haproxy enabled in /etc/default/haproxy.') with open('/etc/default/haproxy', 'w') as out: out.write('ENABLED=1\n') return ctxt log('HAProxy context is incomplete, this unit has no peers.') return {}
def ovs_ctxt(self): # In addition to generating config context, ensure the OVS service # is running and the OVS bridge exists. Also need to ensure # local_ip points to actual IP, not hostname. ovs_ctxt = super(OVSPluginContext, self).ovs_ctxt() if not ovs_ctxt: return {} conf = config() ovs_ctxt['local_ip'] = \ get_address_in_network(config('os-data-network'), get_host_ip(unit_get('private-address'))) neutron_api_settings = NeutronAPIContext()() ovs_ctxt['neutron_security_groups'] = self.neutron_security_groups ovs_ctxt['l2_population'] = neutron_api_settings['l2_population'] ovs_ctxt['distributed_routing'] = neutron_api_settings['enable_dvr'] ovs_ctxt['overlay_network_type'] = \ neutron_api_settings['overlay_network_type'] # TODO: We need to sort out the syslog and debug/verbose options as a # general context helper ovs_ctxt['use_syslog'] = conf['use-syslog'] ovs_ctxt['verbose'] = conf['verbose'] ovs_ctxt['debug'] = conf['debug'] net_dev_mtu = neutron_api_settings.get('network_device_mtu') if net_dev_mtu: # neutron.conf ovs_ctxt['network_device_mtu'] = net_dev_mtu # ml2 conf ovs_ctxt['veth_mtu'] = net_dev_mtu mappings = config('bridge-mappings') if mappings: ovs_ctxt['bridge_mappings'] = ','.join(mappings.split()) flat_providers = config('flat-network-providers') if flat_providers: ovs_ctxt['network_providers'] = ','.join(flat_providers.split()) vlan_ranges = config('vlan-ranges') if vlan_ranges: ovs_ctxt['vlan_ranges'] = ','.join(vlan_ranges.split()) return ovs_ctxt
def get_network_addresses(self): """For each network configured, return corresponding address and vip (if available). Returns a list of tuples of the form: [(address_in_net_a, vip_in_net_a), (address_in_net_b, vip_in_net_b), ...] or, if no vip(s) available: [(address_in_net_a, address_in_net_a), (address_in_net_b, address_in_net_b), ...] """ addresses = [] if config('vip'): vips = config('vip').split() else: vips = [] for net_type in ['os-internal-network', 'os-admin-network', 'os-public-network']: addr = get_address_in_network(config(net_type), unit_get('private-address')) if len(vips) > 1 and is_clustered(): if not config(net_type): log("Multiple networks configured but net_type " "is None (%s)." % net_type, level=WARNING) continue for vip in vips: if is_address_in_network(config(net_type), vip): addresses.append((addr, vip)) break elif is_clustered() and config('vip'): addresses.append((addr, config('vip'))) else: addresses.append((addr, addr)) return sorted(addresses)
def get_cluster_host_ip(): """Get the this host's IP address for use with percona cluster peers @returns IP to pass to cluster peers """ cluster_network = config('cluster-network') if cluster_network: cluster_addr = get_address_in_network(cluster_network, fatal=True) else: try: cluster_addr = network_get_primary_address('cluster') except NotImplementedError: # NOTE(jamespage): fallback to previous behaviour cluster_addr = resolve_hostname_to_ip( unit_get('private-address') ) return cluster_addr
def cluster_joined(relation_id=None): for addr_type in ADDRESS_TYPES: address = get_address_in_network( config('os-{}-network'.format(addr_type)) ) if address: relation_set( relation_id=relation_id, relation_settings={'{}-address'.format(addr_type): address} ) # Only do if this is fired by cluster rel if not relation_id: check_db_initialised() if config('prefer-ipv6'): private_addr = get_ipv6_addr(exc_list=[config('vip')])[0] relation_set(relation_id=relation_id, relation_settings={'private-address': private_addr})
def __call__(self): api_settings = super(NeutronGatewayContext, self).__call__() ctxt = { 'shared_secret': get_shared_secret(), 'local_ip': get_address_in_network(config('os-data-network'), get_host_ip(unit_get('private-address'))), 'core_plugin': core_plugin(), 'plugin': config('plugin'), 'debug': config('debug'), 'verbose': config('verbose'), 'instance_mtu': config('instance-mtu'), 'l2_population': api_settings['l2_population'], 'enable_dvr': api_settings['enable_dvr'], 'enable_l3ha': api_settings['enable_l3ha'], 'overlay_network_type': api_settings['overlay_network_type'], } mappings = config('bridge-mappings') if mappings: ctxt['bridge_mappings'] = ','.join(mappings.split()) flat_providers = config('flat-network-providers') if flat_providers: ctxt['network_providers'] = ','.join(flat_providers.split()) vlan_ranges = config('vlan-ranges') if vlan_ranges: ctxt['vlan_ranges'] = ','.join(vlan_ranges.split()) dnsmasq_flags = config('dnsmasq-flags') if dnsmasq_flags: ctxt['dnsmasq_flags'] = config_flags_parser(dnsmasq_flags) net_dev_mtu = api_settings['network_device_mtu'] if net_dev_mtu: ctxt['network_device_mtu'] = net_dev_mtu ctxt['veth_mtu'] = net_dev_mtu return ctxt
def get_network_addrs(config_opt): """Get all configured public networks addresses. If public network(s) are provided, go through them and return the addresses we have configured on any of those networks. """ addrs = [] networks = config(config_opt) if networks: networks = networks.split() addrs = [get_address_in_network(n) for n in networks] addrs = [a for a in addrs if a] if not addrs: if networks: msg = ("Could not find an address on any of '%s' - resolve this " "error to retry" % (networks)) status_set('blocked', msg) raise Exception(msg) else: return [get_host_ip()] return addrs
def calico_ctxt(self): calico_ctxt = super(CalicoPluginContext, self).calico_ctxt() if not calico_ctxt: return {} conf = config() calico_ctxt['local_ip'] = \ get_address_in_network(config('os-data-network'), get_host_ip(unit_get('private-address'))) calico_ctxt['neutron_security_groups'] = self.neutron_security_groups calico_ctxt['use_syslog'] = conf['use-syslog'] calico_ctxt['verbose'] = conf['verbose'] calico_ctxt['debug'] = conf['debug'] calico_ctxt['peer_ips'] = [] calico_ctxt['peer_ips6'] = [] # Our BGP peers are either route reflectors or our cluster peers. # Prefer route reflectors. calico_ctxt['peer_ips'] = self.addrs_from_relation( 'bgp-route-reflector' ) calico_ctxt['peer_ips6'] = self.addrs_from_relation( 'bgp-route-reflector', ip_version=6 ) if not calico_ctxt['peer_ips']: calico_ctxt['peer_ips'] = self.addrs_from_relation('cluster') if not calico_ctxt['peer_ips6']: calico_ctxt['peer_ips6'] = self.addrs_from_relation( 'cluster', ip_version=6 ) return calico_ctxt