X-Git-Url: https://code.grnet.gr/git/ganeti-local/blobdiff_plain/b705c7a61b3e3ba5d6a93c83380b66c4b1fd7890..2492231f7381ce33f2164322f799c84b2d7cceef:/lib/netutils.py?ds=sidebyside diff --git a/lib/netutils.py b/lib/netutils.py index edbebb4..fc864eb 100644 --- a/lib/netutils.py +++ b/lib/netutils.py @@ -71,7 +71,7 @@ def GetHostname(name=None, family=None): @param family: AF_INET | AF_INET6 | None @rtype: L{Hostname} @return: Hostname object - @raise: errors.OpPrereqError + @raise errors.OpPrereqError: in case of errors in resolving """ try: @@ -85,6 +85,8 @@ class Hostname: """Class implementing resolver and hostname functionality. """ + _VALID_NAME_RE = re.compile("^[a-z0-9._-]{1,255}$") + def __init__(self, name=None, family=None): """Initialize the host name object. @@ -96,20 +98,32 @@ class Hostname: @param name: hostname or None """ - if name is None: - name = self.GetSysName() - - self.name = self.GetNormalizedName(name) + self.name = self.GetNormalizedName(self.GetFqdn(name)) self.ip = self.GetIP(self.name, family=family) + @classmethod + def GetSysName(cls): + """Legacy method the get the current system's name. + + """ + return cls.GetFqdn() + @staticmethod - def GetSysName(): - """Return the current system's name. + def GetFqdn(hostname=None): + """Return fqdn. - This is simply a wrapper over C{socket.gethostname()}. + If hostname is None the system's fqdn is returned. + + @type hostname: str + @param hostname: name to be fqdn'ed + @rtype: str + @return: fqdn of given name, if it exists, unmodified name otherwise """ - return socket.gethostname() + if hostname is None: + return socket.getfqdn() + else: + return socket.getfqdn(hostname) @staticmethod def GetIP(hostname, family=None): @@ -130,7 +144,7 @@ class Hostname: if family in (socket.AF_INET, socket.AF_INET6): result = socket.getaddrinfo(hostname, None, family) else: - result = socket.getaddrinfo(hostname, None, socket.AF_INET) + result = socket.getaddrinfo(hostname, None) except (socket.gaierror, socket.herror, socket.error), err: # hostname not found in DNS, or other socket exception in the # (code, description format) @@ -139,10 +153,13 @@ class Hostname: # getaddrinfo() returns a list of 5-tupes (family, socktype, proto, # canonname, sockaddr). We return the first tuple's first address in # sockaddr - return result[0][4][0] + try: + return result[0][4][0] + except IndexError, err: + raise errors.ResolverError("Unknown error in getaddrinfo(): %s" % err) - @staticmethod - def GetNormalizedName(hostname): + @classmethod + def GetNormalizedName(cls, hostname): """Validate and normalize the given hostname. @attention: the validation is a bit more relaxed than the standards @@ -150,9 +167,8 @@ class Hostname: @raise errors.OpPrereqError: when the name is not valid """ - valid_name_re = re.compile("^[a-z0-9._-]{1,255}$") hostname = hostname.lower() - if (not valid_name_re.match(hostname) or + if (not cls._VALID_NAME_RE.match(hostname) or # double-dots, meaning empty label ".." in hostname or # empty initial label @@ -171,7 +187,7 @@ def TcpPing(target, port, timeout=10, live_port_needed=False, source=None): to it. @type target: str - @param target: the IP or hostname to ping + @param target: the IP to ping @type port: int @param port: the port to connect to @type timeout: int @@ -409,7 +425,7 @@ class IP4Address(IPAddress): """Get integer value of IPv4 address. @type address: str - @param: IPv6 address + @param address: IPv6 address @rtype: int @return: integer value of given IP address @@ -449,7 +465,7 @@ class IP6Address(IPAddress): """Get integer value of IPv6 address. @type address: str - @param: IPv6 address + @param address: IPv6 address @rtype: int @return: integer value of given IP address @@ -472,3 +488,36 @@ class IP6Address(IPAddress): address_int = (address_int << 16) + int(part or '0', 16) return address_int + + +def FormatAddress(address, family=None): + """Format a socket address + + @type address: family specific (usually tuple) + @param address: address, as reported by this class + @type family: integer + @param family: socket family (one of socket.AF_*) or None + + """ + if family is None: + try: + family = IPAddress.GetAddressFamily(address[0]) + except errors.IPAddressError: + raise errors.ParameterError(address) + + if family == socket.AF_UNIX and len(address) == 3: + return "pid=%s, uid=%s, gid=%s" % address + + if family in (socket.AF_INET, socket.AF_INET6) and len(address) == 2: + host, port = address + if family == socket.AF_INET6: + res = "[%s]" % host + else: + res = host + + if port is not None: + res += ":%s" % port + + return res + + raise errors.ParameterError(family, address)