Example #1
0
def get_server_external_ipv4(cloud, server):
    if cloud.has_service('network'):
        try:
            # Search a fixed IP attached to an external net. Unfortunately
            # Neutron ports don't have a 'floating_ips' attribute
            server_ports = cloud.search_ports(
                filters={'device_id': server.id})
            ext_nets = cloud.search_networks(filters={'router:external': True})
        except Exception as e:
            log.debug(
                "Something went wrong talking to neutron API: "
                "'{msg}'. Trying with Nova.".format(msg=str(e)))
            # Fall-through, trying with Nova
        else:
            for net in ext_nets:
                for port in server_ports:
                    if net['id'] == port['network_id']:
                        for ip in port['fixed_ips']:
                            if _utils.is_ipv4(ip['ip_address']):
                                return ip['ip_address']
            # The server doesn't have an interface on an external network so it
            # can either have a floating IP or have no way to be reached from
            # outside the cloud.
            # Fall-through, trying with Nova

    # The cloud doesn't support Neutron or Neutron can't be contacted. The
    # server might have fixed addresses that are reachable from outside the
    # cloud (e.g. Rax) or have plain ol' floating IPs

    # Try to get an address from a network named 'public'
    ext_ip = get_server_ip(server, key_name='public')
    if ext_ip is not None:
        return ext_ip

    # Try to find a globally routable IP address
    for interfaces in server.addresses.values():
        for interface in interfaces:
            if _utils.is_ipv4(interface['addr']) and \
                    _utils.is_globally_routable_ipv4(interface['addr']):
                return interface['addr']

    # Last, try to get a floating IP address
    ext_ip = get_server_ip(server, ext_tag='floating')
    if ext_ip is not None:
        return ext_ip

    return None
Example #2
0
def get_server_private_ip(server, cloud=None):
    """Find the private IP address

    If Neutron is available, search for a port on a network where
    `router:external` is False and `shared` is False. This combination
    indicates a private network with private IP addresses. This port should
    have the private IP.

    If Neutron is not available, or something goes wrong communicating with it,
    as a fallback, try the list of addresses associated with the server dict,
    looking for an IP type tagged as 'fixed' in the network named 'private'.

    Last resort, ignore the IP type and just look for an IP on the 'private'
    network (e.g., Rackspace).
    """
    if cloud and cloud.has_service('network'):
        try:
            server_ports = cloud.search_ports(
                filters={'device_id': server['id']})
            nets = cloud.search_networks(filters={
                'router:external': False,
                'shared': False
            })
        except Exception as e:
            log.debug("Something went wrong talking to neutron API: "
                      "'{msg}'. Trying with Nova.".format(msg=str(e)))
        else:
            for net in nets:
                for port in server_ports:
                    if net['id'] == port['network_id']:
                        for ip in port['fixed_ips']:
                            if _utils.is_ipv4(ip['ip_address']):
                                return ip['ip_address']

    ip = get_server_ip(server, ext_tag='fixed', key_name='private')
    if ip:
        return ip

    # Last resort, and Rackspace
    return get_server_ip(server, key_name='private')
Example #3
0
def get_server_private_ip(server, cloud=None):
    """Find the private IP address

    If Neutron is available, search for a port on a network where
    `router:external` is False and `shared` is False. This combination
    indicates a private network with private IP addresses. This port should
    have the private IP.

    If Neutron is not available, or something goes wrong communicating with it,
    as a fallback, try the list of addresses associated with the server dict,
    looking for an IP type tagged as 'fixed' in the network named 'private'.

    Last resort, ignore the IP type and just look for an IP on the 'private'
    network (e.g., Rackspace).
    """
    if cloud and cloud.has_service('network'):
        try:
            server_ports = cloud.search_ports(
                filters={'device_id': server['id']})
            nets = cloud.search_networks(
                filters={'router:external': False, 'shared': False})
        except Exception as e:
            log.debug(
                "Something went wrong talking to neutron API: "
                "'{msg}'. Trying with Nova.".format(msg=str(e)))
        else:
            for net in nets:
                for port in server_ports:
                    if net['id'] == port['network_id']:
                        for ip in port['fixed_ips']:
                            if _utils.is_ipv4(ip['ip_address']):
                                return ip['ip_address']

    ip = get_server_ip(server, ext_tag='fixed', key_name='private')
    if ip:
        return ip

    # Last resort, and Rackspace
    return get_server_ip(server, key_name='private')
Example #4
0
def get_server_external_ipv4(cloud, server):
    """Find an externally routable IP for the server.

    There are 5 different scenarios we have to account for:

    * Cloud has externally routable IP from neutron but neutron APIs don't
      work (only info available is in nova server record) (rackspace)
    * Cloud has externally routable IP from neutron (runabove, ovh)
    * Cloud has externally routable IP from neutron AND supports optional
      private tenant networks (vexxhost, unitedstack)
    * Cloud only has private tenant network provided by neutron and requires
      floating-ip for external routing (dreamhost, hp)
    * Cloud only has private tenant network provided by nova-network and
      requires floating-ip for external routing (auro)

    :param cloud: the cloud we're working with
    :param server: the server dict from which we want to get an IPv4 address
    :return: a string containing the IPv4 address or None
    """

    if server['accessIPv4']:
        return server['accessIPv4']
    if cloud.has_service('network'):
        try:
            # Search a fixed IP attached to an external net. Unfortunately
            # Neutron ports don't have a 'floating_ips' attribute
            server_ports = cloud.search_ports(
                filters={'device_id': server.id})
            ext_nets = cloud.search_networks(filters={'router:external': True})
        except Exception as e:
            log.debug(
                "Something went wrong talking to neutron API: "
                "'{msg}'. Trying with Nova.".format(msg=str(e)))
            # Fall-through, trying with Nova
        else:
            for net in ext_nets:
                for port in server_ports:
                    if net['id'] == port['network_id']:
                        for ip in port['fixed_ips']:
                            if _utils.is_ipv4(ip['ip_address']):
                                return ip['ip_address']
            # The server doesn't have an interface on an external network so it
            # can either have a floating IP or have no way to be reached from
            # outside the cloud.
            # Fall-through, trying with Nova

    # The cloud doesn't support Neutron or Neutron can't be contacted. The
    # server might have fixed addresses that are reachable from outside the
    # cloud (e.g. Rax) or have plain ol' floating IPs

    # Try to get an address from a network named 'public'
    ext_ip = get_server_ip(server, key_name='public')
    if ext_ip is not None:
        return ext_ip

    # Try to find a globally routable IP address
    for interfaces in server.addresses.values():
        for interface in interfaces:
            if _utils.is_ipv4(interface['addr']) and \
                    _utils.is_globally_routable_ipv4(interface['addr']):
                return interface['addr']

    # Last, try to get a floating IP address
    ext_ip = get_server_ip(server, ext_tag='floating')
    if ext_ip is not None:
        return ext_ip

    return None