Exemplo n.º 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
Exemplo n.º 2
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