<commit_before>#
#

# Copyright (C) 2010, 2011, 2012 Google Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# 1. Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
# IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.


"""Ganeti network utility module.

This module holds functions that can be used in both daemons (all) and
the command line scripts.

"""


import errno
import os
import re
import socket
import struct
import IN
import logging

from ganeti import constants
from ganeti import errors
from ganeti import utils
from ganeti import vcluster

# Structure definition for getsockopt(SOL_SOCKET, SO_PEERCRED, ...):
# struct ucred { pid_t pid; uid_t uid; gid_t gid; };
#
# The GNU C Library defines gid_t and uid_t to be "unsigned int" and
# pid_t to "int".
#
# IEEE Std 1003.1-2008:
# "nlink_t, uid_t, gid_t, and id_t shall be integer types"
# "blksize_t, pid_t, and ssize_t shall be signed integer types"
_STRUCT_UCRED = "iII"
_STRUCT_UCRED_SIZE = struct.calcsize(_STRUCT_UCRED)

# Workaround a bug in some linux distributions that don't define SO_PEERCRED
try:
  # pylint: disable=E1101
  _SO_PEERCRED = IN.SO_PEERCRED
except AttributeError:
  _SO_PEERCRED = 17

# Regexes used to find IP addresses in the output of ip.
_IP_RE_TEXT = r"[.:a-z0-9]+"      # separate for testing purposes
_IP_FAMILY_RE = re.compile(r"(?P<family>inet6?)\s+(?P<ip>%s)/" % _IP_RE_TEXT,
                           re.IGNORECASE)

# Dict used to convert from a string representing an IP family to an IP
# version
_NAME_TO_IP_VER = {
  "inet": constants.IP4_VERSION,
  "inet6": constants.IP6_VERSION,
  }


def _GetIpAddressesFromIpOutput(ip_output):
  """Parses the output of the ip command and retrieves the IP addresses and
  version.

  @param ip_output: string containing the output of the ip command;
  @rtype: dict; (int, list)
  @return: a dict having as keys the IP versions and as values the
           corresponding list of addresses found in the IP output.

  """
  addr = dict((i, []) for i in _NAME_TO_IP_VER.values())

  for row in ip_output.splitlines():
    match = _IP_FAMILY_RE.search(row)
    if match and IPAddress.IsValid(match.group("ip")):
      addr[_NAME_TO_IP_VER[match.group("family")]].append(match.group("ip"))

  return addr


def GetSocketCredentials(sock):
  """Returns the credentials of the foreign process connected to a socket.

  @param sock: Unix socket
  @rtype: tuple; (number, number, number)
  @return: The PID, UID and GID of the connected foreign process.

  """
  peercred = sock.getsockopt(socket.SOL_SOCKET, _SO_PEERCRED,
                             _STRUCT_UCRED_SIZE)
  return struct.unpack(_STRUCT_UCRED, peercred)


def IsValidInterface(ifname):
  """Validate an interface name.

  @type ifname: string
  @param ifname: Name of the network interface
  @return: boolean indicating whether the interface name is valid or not.

  """
  return os.path.exists(utils.PathJoin("/sys/class/net", ifname))


def GetInterfaceIpAddresses(ifname):
  """Returns the IP addresses associated to the interface.

  @type ifname: string
  @param ifname: Name of the network interface
  @return: A dict having for keys the IP version (either
           L{constants.IP4_VERSION} or L{constants.IP6_VERSION}) and for
           values the lists of IP addresses of the respective version
           associated to the interface

  """
  result = utils.RunCmd([constants.IP_COMMAND_PATH, "-o", "addr", "show",
                         ifname])

  if result.failed:
    logging.error("Error running the ip command while getting the IP"
                  " addresses of %s", ifname)
    return None

  return _GetIpAddressesFromIpOutput(result.output)


def GetHostname(name=None, family=None):
  """Returns a Hostname object.

  @type name: str
  @param name: hostname or None
  @type family: int
  @param family: AF_INET | AF_INET6 | None
  @rtype: L{Hostname}
  @return: Hostname object
  @raise errors.OpPrereqError: in case of errors in resolving

  """
  try:
    return Hostname(name=name, family=family)
  except errors.ResolverError, err:<commit_msg>netutils: use correct syntax of iproute2 when getting ip address (#26)<commit_after>#
#

# Copyright (C) 2010, 2011, 2012 Google Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# 1. Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
# IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.


"""Ganeti network utility module.

This module holds functions that can be used in both daemons (all) and
the command line scripts.

"""


import errno
import os
import re
import socket
import struct
import IN
import logging

from ganeti import constants
from ganeti import errors
from ganeti import utils
from ganeti import vcluster

# Structure definition for getsockopt(SOL_SOCKET, SO_PEERCRED, ...):
# struct ucred { pid_t pid; uid_t uid; gid_t gid; };
#
# The GNU C Library defines gid_t and uid_t to be "unsigned int" and
# pid_t to "int".
#
# IEEE Std 1003.1-2008:
# "nlink_t, uid_t, gid_t, and id_t shall be integer types"
# "blksize_t, pid_t, and ssize_t shall be signed integer types"
_STRUCT_UCRED = "iII"
_STRUCT_UCRED_SIZE = struct.calcsize(_STRUCT_UCRED)

# Workaround a bug in some linux distributions that don't define SO_PEERCRED
try:
  # pylint: disable=E1101
  _SO_PEERCRED = IN.SO_PEERCRED
except AttributeError:
  _SO_PEERCRED = 17

# Regexes used to find IP addresses in the output of ip.
_IP_RE_TEXT = r"[.:a-z0-9]+"      # separate for testing purposes
_IP_FAMILY_RE = re.compile(r"(?P<family>inet6?)\s+(?P<ip>%s)/" % _IP_RE_TEXT,
                           re.IGNORECASE)

# Dict used to convert from a string representing an IP family to an IP
# version
_NAME_TO_IP_VER = {
  "inet": constants.IP4_VERSION,
  "inet6": constants.IP6_VERSION,
  }


def _GetIpAddressesFromIpOutput(ip_output):
  """Parses the output of the ip command and retrieves the IP addresses and
  version.

  @param ip_output: string containing the output of the ip command;
  @rtype: dict; (int, list)
  @return: a dict having as keys the IP versions and as values the
           corresponding list of addresses found in the IP output.

  """
  addr = dict((i, []) for i in _NAME_TO_IP_VER.values())

  for row in ip_output.splitlines():
    match = _IP_FAMILY_RE.search(row)
    if match and IPAddress.IsValid(match.group("ip")):
      addr[_NAME_TO_IP_VER[match.group("family")]].append(match.group("ip"))

  return addr


def GetSocketCredentials(sock):
  """Returns the credentials of the foreign process connected to a socket.

  @param sock: Unix socket
  @rtype: tuple; (number, number, number)
  @return: The PID, UID and GID of the connected foreign process.

  """
  peercred = sock.getsockopt(socket.SOL_SOCKET, _SO_PEERCRED,
                             _STRUCT_UCRED_SIZE)
  return struct.unpack(_STRUCT_UCRED, peercred)


def IsValidInterface(ifname):
  """Validate an interface name.

  @type ifname: string
  @param ifname: Name of the network interface
  @return: boolean indicating whether the interface name is valid or not.

  """
  return os.path.exists(utils.PathJoin("/sys/class/net", ifname))


def GetInterfaceIpAddresses(ifname):
  """Returns the IP addresses associated to the interface.

  @type ifname: string
  @param ifname: Name of the network interface
  @return: A dict having for keys the IP version (either
           L{constants.IP4_VERSION} or L{constants.IP6_VERSION}) and for
           values the lists of IP addresses of the respective version
           associated to the interface

  """
  result = utils.RunCmd([constants.IP_COMMAND_PATH, "-o", "addr", "show",
                         "dev", ifname])

  if result.failed:
    logging.error("Error running the ip command while getting the IP"
                  " addresses of %s", ifname)
    return None

  return _GetIpAddressesFromIpOutput(result.output)


def GetHostname(name=None, family=None):
  """Returns a Hostname object.

  @type name: str
  @param name: hostname or None
  @type family: int
  @param family: AF_INET | AF_INET6 | None
  @rtype: L{Hostname}
  @return: Hostname object
  @raise errors.OpPrereqError: in case of errors in resolving

  """
  try:
    return Hostname(name=name, family=family)
  except errors.ResolverError, err:
{'fraction_non_alphanumeric': 0.080430230344565, 'fraction_numerical': 0.007519512659432705, 'mean_word_length': 3.9514608859566445, 'pattern_counts': {'":': 4, '<': 7, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5897199', 'n_tokens_mistral': 3308, 'n_tokens_neox': 3110, 'n_words': 1250}