Repository : http://git.fedorahosted.org/cgit/cura-tools.git
On branch : openlmi-tools-lmiwbem
commit b96f3ac9caf4f558922c51a43e1a8c0a9d36eaf7 Author: Peter Hatina phatina@redhat.com Date: Fri Jun 27 15:22:26 2014 +0200
allow root and pegasus members to connect via Unix socket
cli/lmi/shell/LMICIMXMLClient.py | 40 +++++++++------------ cli/lmi/shell/LMIConnection.py | 71 ++++++++++++++++++++++++++------------ cli/lmi/shell/LMIUtil.py | 19 ++++++++++ 3 files changed, 85 insertions(+), 45 deletions(-)
diff --git a/cli/lmi/shell/LMICIMXMLClient.py b/cli/lmi/shell/LMICIMXMLClient.py index ba51b8d..a7c24c0 100644 --- a/cli/lmi/shell/LMICIMXMLClient.py +++ b/cli/lmi/shell/LMICIMXMLClient.py @@ -25,6 +25,7 @@ from lmi.shell.LMIUtil import lmi_raise_or_dump_exception from lmi.shell.LMIUtil import lmi_get_use_exceptions from lmi.shell.LMIUtil import lmi_set_use_exceptions from lmi.shell.LMIUtil import lmi_instance_to_path +from lmi.shell.LMIUtil import lmi_is_localhost
from lmi.shell.LMIDecorators import lmi_process_cim_exceptions from lmi.shell.LMIDecorators import lmi_process_cim_exceptions_rval @@ -34,17 +35,6 @@ from lmi.shell.LMIExceptions import ConnectionError from lmi.shell.LMIExceptions import LMIFilterError
-LOCALHOST_VARIANTS = ( - "localhost", - "localhost.localdomain", - "localhost4", - "localhost4.localdomain4", - "localhost6", - "localhost6.localdomain6", - "127.0.0.1", - "::1", -) - def filter_kwargs(**kwargs): return {k: v for k, v in kwargs.iteritems() if v is not None}
@@ -65,16 +55,19 @@ class LMICIMXMLClient(object): QUERY_LANG_CQL = "DMTF:CQL" QUERY_LANG_WQL = "WQL"
+ # Unix sockets used by TOG-Pegasus, SFCB or OpenWBEM. + PEGASUS_SOCKET = "/var/run/tog-pegasus/cimxml.socket" + def __init__(self, uri, username="", password="", verify_server_cert=True, key_file=None, cert_file=None): - if not uri.startswith("http://") and \ - not uri.startswith("https://"): - uri = "https://" + uri self._uri = uri + if not self._uri.startswith("http://") and \ + not self._uri.startswith("https://"): + self._uri = "https://" + uri
# Parse CIMOM URI - _, hostname, _, _, username_, password_ = lmi_parse_uri(uri) + _, hostname, _, path, username_, password_ = lmi_parse_uri(self._uri) if username_ is not None: username = username_ password = password_ @@ -85,14 +78,13 @@ class LMICIMXMLClient(object): "key_file": key_file }
- # If we are running as root and the scheme has not been explicitly set, - # we will use the local UNIX socket for higher performance (and skip - # authentication). - connect_locally = os.getuid() == 0 and \ - uri in LOCALHOST_VARIANTS and \ - parse_res.path != "/wsman" and \ - os.path.exists("/var/run/tog-pegasus/cimxml.socket") and \ - not username and not password + # If we are connecting to localhost without username or certificate + # set, we will use the local UNIX socket for higher performance (and + # skip authentication). + connect_locally = lmi_is_localhost(uri) and \ + path != "/wsman" and \ + not username and not password and \ + not cert_file and not key_file
if HAVE_LMIWBEM: # LMIWBEM @@ -127,6 +119,7 @@ class LMICIMXMLClient(object): self.disconnect() del self._cliconn
+ @lmi_process_cim_exceptions(False) def connect(self): """ Connects to CIMOM. @@ -135,6 +128,7 @@ class LMICIMXMLClient(object): """ if HAVE_LMIWBEM: self._cliconn.connect() + return LMIReturnValue(rval=True)
def disconnect(self): """ diff --git a/cli/lmi/shell/LMIConnection.py b/cli/lmi/shell/LMIConnection.py index f763ff9..7ab9e2c 100644 --- a/cli/lmi/shell/LMIConnection.py +++ b/cli/lmi/shell/LMIConnection.py @@ -16,6 +16,7 @@ import os import sys import atexit +import getpass import readline import urlparse
@@ -41,6 +42,7 @@ from lmi.shell.LMIExceptions import LMINamespaceNotFound from lmi.shell.LMIShellLogger import lmi_get_logger
from lmi.shell.LMIUtil import lmi_raise_or_dump_exception +from lmi.shell.LMIUtil import lmi_is_localhost
logger = lmi_get_logger()
@@ -54,38 +56,34 @@ def __lmi_raw_input(prompt, use_echo=True): :returns: input string :raises: :py:exc:`EOFError` """ - if not sys.stdout.isatty() and sys.stderr.isatty(): + if not sys.stderr.isatty() and not sys.stdout.isatty(): + logger.warn( + "Both stdout and stderr are detached from terminal, " + "using stdout for prompt") + elif not sys.stdout.isatty() and sys.stderr.isatty(): # read the input with prompt printed to stderr - def get_input(prompt): - sys.stderr.write(prompt) - return raw_input() stream = sys.stderr else: # read the input with prompt printed to stdout - # NOTE: raw_input uses stdout only if the readline module is imported - get_input = raw_input stream = sys.stdout - if not sys.stderr.isatty() and not sys.stdout.isatty(): - logger.warn( - "Both stdout and stderr are detached from terminal, " - "using stdout for prompt") - if not use_echo: - os.system("stty -echo") + + # Define input function + if use_echo: + def get_input(prompt): + return raw_input(prompt) + else: + def get_input(prompt): + return getpass.getpass(prompt, stream) + try: result = get_input(prompt) except EOFError, e: - if not use_echo: - os.system("stty echo") stream.write("\n") return None except KeyboardInterrupt, e: - if not use_echo: - os.system("stty echo") raise e - if not use_echo: - os.system("stty echo") - stream.write("\n") - if result: + + if result and use_echo: cur_hist_len = readline.get_current_history_length() if cur_hist_len > 1: readline.remove_history_item(cur_hist_len - 1) @@ -133,6 +131,30 @@ def connect(uri, username="", password="", interactive=False, use_cache=True, """ connection = None
+ if lmi_is_localhost(uri) and \ + not username and not password and \ + not cert_file and not key_file: + try: + # Try to get socket's permissions. If we can talk to TOG-Pegasus, + # stat() will return stat buf; OSError will be raised otherwise. + os.stat("/var/run/tog-pegasus/cimxml.socket") + + connection = LMIConnection( + uri, interactive=interactive, use_cache=use_cache) + + # Verify the connection + rval, _, errorstr = connection.connect() + if not rval: + logger.warning("Can't connect via Unix socket") + del connection + else: + logger.info("Connected via Unix socket") + return connection + except OSError, e: + # It is fine not to do anything here. User will be prompted for + # necessary credentials, if necessary. + pass + if interactive and not key_file and not cert_file: try: if not username: @@ -150,6 +172,7 @@ def connect(uri, username="", password="", interactive=False, use_cache=True, use_cache=use_cache, key_file=key_file, cert_file=cert_file, verify_server_cert=verify_server_cert)
+ # Verify the connection rval, _, errorstr = connection.connect()
if not rval: @@ -336,9 +359,13 @@ class LMIConnection(object): error string. :rtype: :py:class:`LMIReturnValue` """ - self._client.connect() + # Connect to CIMOM. We may fail before the actual "dummy" request is + # sent. This only applies for LMIWBEM. + rval, _, errorstr = self._client.connect() + if not rval: + return LMIReturnValue(rval=False, errorstr=errorstr)
- # Perform "dummy" request to check connection and credentials + # Perform "dummy" request to check the connection and credentials. return self._client.dummy()
def disconnect(self): diff --git a/cli/lmi/shell/LMIUtil.py b/cli/lmi/shell/LMIUtil.py index 18ad377..ed59851 100644 --- a/cli/lmi/shell/LMIUtil.py +++ b/cli/lmi/shell/LMIUtil.py @@ -23,6 +23,17 @@ from lmi.shell import wbem
from lmi.shell.LMIObjectFactory import LMIObjectFactory
+LOCALHOST_VARIANTS = ( + "localhost", + "localhost.localdomain", + "localhost4", + "localhost4.localdomain4", + "localhost6", + "localhost6.localdomain6", + "127.0.0.1", + "::1", +) +
# By default, the LMIShell does not use exceptions; LMIReturnValue # is used instead (with proper error string). @@ -488,3 +499,11 @@ def lmi_instance_to_path(instance): return instance.wrapped_object raise TypeError( "instance has to be wbem.CIMInstance(Name) or LMIInstance(Name)") + +def lmi_is_localhost(uri): + """ + Helper function, which returns True, if URI points to localhost. + + :param str uri: URI to check + """ + return uri in LOCALHOST_VARIANTS
cura-tools-devel@lists.fedorahosted.org