summaryrefslogtreecommitdiffstats
path: root/src/python
diff options
context:
space:
mode:
authorMichal Minar <miminar@redhat.com>2013-10-31 12:36:15 +0100
committerMichal Minar <miminar@redhat.com>2013-10-31 13:24:02 +0100
commitefd855b04e8c93d3ff14b4ea90e54fe21d7db2c4 (patch)
treeb3243957f05b89c556f776719cb6f37d26a4d6fc /src/python
parente639b9b9129562fbe9568d07a2c63f8437dbf48b (diff)
downloadopenlmi-providers-efd855b04e8c93d3ff14b4ea90e54fe21d7db2c4.tar.gz
openlmi-providers-efd855b04e8c93d3ff14b4ea90e54fe21d7db2c4.tar.xz
openlmi-providers-efd855b04e8c93d3ff14b4ea90e54fe21d7db2c4.zip
python: solve ComputerSystem issues
Added ComputerSystem module to lmi.providers with convenience functions allowing to obtain instance from CIMOM and check for its correctness when inspecting client's input. Also removed obsoleted system_name property out of BaseConfiguration class.
Diffstat (limited to 'src/python')
-rw-r--r--src/python/lmi/base/BaseConfiguration.py10
-rw-r--r--src/python/lmi/providers/ComputerSystem.py154
-rw-r--r--src/python/lmi/providers/__init__.py19
3 files changed, 177 insertions, 6 deletions
diff --git a/src/python/lmi/base/BaseConfiguration.py b/src/python/lmi/base/BaseConfiguration.py
index 8333cca..baabcc6 100644
--- a/src/python/lmi/base/BaseConfiguration.py
+++ b/src/python/lmi/base/BaseConfiguration.py
@@ -72,6 +72,10 @@ class BaseConfiguration(Singleton):
There should be only one instance of this class.
"""
+ #: Allow to access global configuration object also from lmi.providers
+ #: subpackage where ``get_instance()`` can not be used.
+ #: This variable shall be set in ``__init__()`` method.
+ INSTANCE = None
CONFIG_DIRECTORY_TEMPLATE_TOPLEVEL = '/etc/openlmi/'
CONFIG_DIRECTORY_TEMPLATE_PROVIDER = '/etc/openlmi/%(provider_prefix)s/'
CONFIG_FILE_PATH_TEMPLATE_TOPLEVEL = \
@@ -152,6 +156,7 @@ class BaseConfiguration(Singleton):
self.config = ConfigParser.SafeConfigParser(
defaults=self.default_options())
self.load()
+ BaseConfiguration.INSTANCE = self
def add_listener(self, callback):
"""
@@ -199,11 +204,6 @@ class BaseConfiguration(Singleton):
return self.config.get('CIM', 'SystemClassName')
@property
- def system_name(self):
- """ Return SystemName of OpenLMI provider. """
- return socket.getfqdn()
-
- @property
def logging_level(self):
""" Return name of logging level in lower case. """
return self.config.get('Log', 'Level').lower()
diff --git a/src/python/lmi/providers/ComputerSystem.py b/src/python/lmi/providers/ComputerSystem.py
new file mode 100644
index 0000000..0b347f8
--- /dev/null
+++ b/src/python/lmi/providers/ComputerSystem.py
@@ -0,0 +1,154 @@
+# -*- encoding: utf-8 -*-
+# Software Management Providers
+#
+# Copyright (C) 2012-2013 Red Hat, Inc. All rights reserved.
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"""
+Just a common functionality related to associated class ``CIM_ComputerSystem``.
+"""
+
+import pywbem
+
+from lmi.base.BaseConfiguration import BaseConfiguration
+from lmi.providers import cmpi_logging
+from lmi.software import util
+
+class UninitializedError(Exception):
+ """
+ Raised when the initialization parameter is not passed to function upon
+ its first invocation.
+ """
+ pass
+
+class NotInstrumentedError(Exception):
+ """
+ Raised when some CIM class is not instrumented in current *CIMOM*.
+ """
+ pass
+
+@cmpi_logging.trace_function
+def get_path(env=None):
+ """
+ Get the instance name of preferred computer system. Instance is cached,
+ so the broker is accessed just upon the first invocation. Confiruation
+ instance must be instantiated before this function is called.
+
+ :param ProviderEnvironment env: Provider environment, taken from CIMOM
+ callback (e.g. ``get_providers()``). It's needed just upon the first
+ invocation.
+ :returns: Instance of ``CIM_ComputerSystem``. Exact subclass is defined
+ in configuration file.
+ :rtype: :py:class:`pywbem.CIMInstanceName`
+ """
+ if not hasattr(get_path, '_instance'):
+ if env is None:
+ raise UninitializedError("get_computer_system_path() needs to be"
+ " given environment object at first invocation")
+ inames = [ i for i in env.get_cimom_handle().EnumerateInstanceNames(
+ "root/cimv2",
+ BaseConfiguration.INSTANCE.system_class_name) ]
+ if len(inames) < 1:
+ raise NotInstrumentedError("CIM_ComputerSystem class is not"
+ " instrumented or EnumerateInstanceNames() operation"
+ " is not supported")
+ get_path._instance = inames[0]
+ return get_path._instance.copy()
+
+@cmpi_logging.trace_function
+def get_system_name(env=None):
+ """
+ Get the name of system contained in a ``Name`` property of instance of
+ ``CIM_ComputerSystem``.
+
+ :param ProviderEnvironment env: Provider environment, taken from CIMOM
+ callback (e.g. ``get_providers()``). It's needed only upon a
+ first invocation of this function or
+ :py:func:`get_computer_system_path`.
+ :returns: Name of computer system.
+ :rtype: string
+ """
+ return get_path(env)["Name"]
+
+@cmpi_logging.trace_function
+def check_path(env, system, prop_name):
+ """
+ Checks instance name of ``CIM_ComputerSystem``. If the object path matches
+ this computer system, ``True`` is returned. Exception is raised otherwise.
+ Especially useful when checking arguments of instance's method taking
+ reference to computer system an argument.
+
+ :param system: Instance name of computer system to check.
+ :type system: :py:class:`pywbem.CIMInstanceName`
+ :param string prop_name: Name of argument or property referring to the object
+ path being checked. This is used in exception messages upon
+ unsuccessful checks.
+ :returns: ``True``
+ :rtype: boolean
+ """
+ if not isinstance(system, pywbem.CIMInstanceName):
+ raise pywbem.CIMError(pywbem.CIM_ERR_INVALID_PARAMETER,
+ "\"%s\" must be a CIMInstanceName" % prop_name)
+ our_system = get_path(env)
+ ch = env.get_cimom_handle()
+ if system.namespace != our_system.namespace:
+ raise pywbem.CIMError(pywbem.CIM_ERR_NOT_FOUND,
+ 'Namespace of "%s" does not match "%s"' % (
+ prop_name, our_system.namespace))
+ if not ch.is_subclass(our_system.namespace,
+ sub=system.classname,
+ super="CIM_ComputerSystem"):
+ raise pywbem.CIMError(pywbem.CIM_ERR_NOT_FOUND,
+ "Class of \"%s\" must be a sublass of %s" % (
+ prop_name, our_system.classname))
+ if not 'CreationClassName' in system or not 'Name' in system:
+ raise pywbem.CIMError(pywbem.CIM_ERR_NOT_FOUND,
+ "\"%s\" is missing one of keys", prop_name)
+ if not ch.is_subclass(our_system.namespace,
+ sub=system['CreationClassName'],
+ super="CIM_ComputerSystem"):
+ raise pywbem.CIMError(pywbem.CIM_ERR_NOT_FOUND,
+ "CreationClassName of \"%s\" must be a sublass of %s" % (
+ prop_name, our_system.classname))
+ if not util.is_this_system(system['Name']):
+ raise pywbem.CIMError(pywbem.CIM_ERR_NOT_FOUND,
+ "Name of \"%s\" does not match \"%s\"" % (
+ prop_name, our_system['Name']))
+ return True
+
+@cmpi_logging.trace_function
+def check_path_property(env, op, prop_name):
+ """
+ This checks, whether the object path contains correct instance name of
+ ``CIM_ComputerSystem`` corresponding to this system. If not, an exception
+ is raised.
+
+ Example usage in ``get_instance()`` method of provider: ::
+
+ # body of get_instance() method of some association class having
+ # *System* property referring to an instance of *CIM_ComputerSystem*.
+ ComputerSystem.check_path_property(env, model, "System")
+
+ :param op: Object path to check.
+ :param string prop_name: Name of property referring to the object path being
+ checked. This is used in exception messages when check is unsuccessful.
+ :returns: ``True``
+ :rtype: boolean
+ """
+ if not prop_name in op:
+ raise pywbem.CIMError(pywbem.CIM_ERR_INVALID_PARAMETER,
+ "Missing %s key property!" % prop_name)
+ return check_path(env, op[prop_name], prop_name)
+
diff --git a/src/python/lmi/providers/__init__.py b/src/python/lmi/providers/__init__.py
index baebcdb..7aec342 100644
--- a/src/python/lmi/providers/__init__.py
+++ b/src/python/lmi/providers/__init__.py
@@ -18,10 +18,13 @@
#
# Authors: Michal Minar <miminar@redhat.com>
#
-
"""
Common utilities for OpenLMI python providers.
"""
+
+import socket
+from lmi.base.BaseConfiguration import BaseConfiguration
+
def parse_instance_id(instance_id, classname=None):
"""
Parse InstanceID, check it has LMI:<classname>:<ID> format and return
@@ -40,3 +43,17 @@ def parse_instance_id(instance_id, classname=None):
if classname and real_classname.lower() != classname.lower():
return None
return parts[2]
+
+def is_this_system(system_name):
+ """
+ Return ``True`` if given *system_name* matches the hostname of currently
+ running system.
+
+ Global configuration object must be initialized before calling this
+ function.
+
+ :rtype: boolean
+ """
+ return ( socket.gethostbyaddr(system_name)[0]
+ == socket.gethostbyaddr(
+ BaseConfiguration.INSTANCE.system_class_name)[0])