Ejemplo n.º 1
0
    def ModifyInstance(self, *args, **kwargs):
        """This method is used by the MOF compiler only in the course of
        handling CIM_ERR_ALREADY_EXISTS after trying to create an instance.

        NOTE: It does NOT support the propertylist attribute that is part
        of the CIM/XML defintion of ModifyInstance and it requires that
        each created instance include the instance path which means that
        the MOF must include the instance alias on each created instance.
        """
        mod_inst = args[0] if args else kwargs['ModifiedInstance']
        if self.default_namespace not in self.instances:
            raise CIMError(
                CIM_ERR_INVALID_NAMESPACE,
                _format(
                    'ModifyInstance failed. No instance repo exists. '
                    'Use compiler instance alias to set path on '
                    'instance declaration. inst: {0!A}', mod_inst))

        if mod_inst.path not in self.instances[self.default_namespace]:
            raise CIMError(
                CIM_ERR_NOT_FOUND,
                _format(
                    'ModifyInstance failed. No instance exists. '
                    'Use compiler instance alias to set path on '
                    'instance declaration. inst: {0!A}', mod_inst))

        orig_instance = self.instances[self.default_namespace][mod_inst.path]
        orig_instance.update(mod_inst.properties)
        self.instances[self.default_namespace][mod_inst.path] = orig_instance
Ejemplo n.º 2
0
    def parseErrorAndResponse(self, data):
        """Parse returned XML for errors, then convert into
        appropriate Python objects."""
        try:
            xml = fromstring(data)
        except Exception:
            self.deferred.errback(
                CIMError(
                    0,
                    'Incorrect XML response for {0}'.format(self.classname)))
            return

        error = xml.find('.//ERROR')

        if error is not None:
            msg = error.get('DESCRIPTION')
            if msg and "context cannot be found" in msg:
                error.set(
                    "DESCRIPTION",
                    "Response is not complete for {} classname. "
                    "Please check zWBEMOperationTimeout and "
                    "zWBEMMaxObjectCount properties".format(self.classname))
        else:
            self.deferred.callback(self.parseResponse(xml))
            return

        try:
            code = int(error.attrib['CODE'])
        except ValueError:
            code = 0

        self.deferred.errback(CIMError(code, error.attrib['DESCRIPTION']))
Ejemplo n.º 3
0
    def _validate_qualifiers(qualifier_list, qual_repo, new_class, scope):
        """
        Validate a list of qualifiers against the Qualifier decl in the
        repository.

        1. Whether it is declared (can be obtained from the declContext).
        2. Whether it has the same type as the declaration.
        3. Whether the qualifier is valid for the given scope.
        4. Whether the qualifier can be overridden.
        5. Whether the qualifier should be propagated to the subclass.
        """
        for qname, qvalue in qualifier_list.items():
            if qname not in qual_repo:
                raise CIMError(
                    CIM_ERR_INVALID_PARAMETER,
                    _format(
                        "Qualifier {0!A} in new_class {1!A} in "
                        "CreateClass not in repository.", qname,
                        new_class.classname))
            q_decl = qual_repo[qname]
            if qvalue.type != q_decl.type:
                raise CIMError(
                    CIM_ERR_INVALID_PARAMETER,
                    _format(
                        "Qualifier {0!A} in new_class {1!A} override type "
                        "mismatch {2!A} with qualifier declaration {3!A}.",
                        qname, new_class.classname, qvalue.type, q_decl.type))
            if scope not in q_decl.scopes:
                raise CIMError(
                    CIM_ERR_INVALID_PARAMETER,
                    _format(
                        "Qualifier {0!A} in new class {1!A} scope {2!A} "
                        "invalid. Not in qualifier decl scopes {3}", qname,
                        new_class.classname, scope, q_decl.scopes))
Ejemplo n.º 4
0
    def CreateInstance(self, *args, **kwargs):
        """
        Create a CIM instance in the local repository of this class.
        This method is derived from the the same method in the pywbem
        mof compiler but modified to:
        1. Use a dictionary as the container for instances where the
           key is the path. This means that all instances must have a
           path component to be inserted into the repository. Normally
           the path component is built within the compiler by using the
           instance alias.
        2. Fail with a CIMError exception if the instance already exists
           in the repository.


        For a description of the parameters, see
        :meth:`pywbem.WBEMConnection.CreateInstance`.
        """
        namespace = self.default_namespace
        inst = args[0] if args else kwargs['NewInstance']

        # Get list of properties in class defined for this instance
        cln = inst.classname
        cls = self.GetClass(cln, IncludeQualifiers=True, LocalOnly=False)

        cls_key_properties = [
            p for p, v in cls.properties.items() if 'key' in v.qualifiers
        ]

        # Validate all key properties are in instance
        for pname in cls_key_properties:
            if pname not in inst.properties:
                raise CIMError(
                    CIM_ERR_INVALID_PARAMETER,
                    _format(
                        'CreateInstance failed. Key property {0!A}  in '
                        'class {1!A} but not in new_instance: {2!A}', pname,
                        cln, str(inst)))

        # Build path from instance and class
        if inst.path is None or not inst.path.keybindings:
            inst.path = CIMInstanceName.from_instance(
                cls, inst, namespace=self.default_namespace)

        # Exception if duplicate. NOTE: compiler overrides this with
        # modify instance.
        instance_store = self.repo.get_instance_store(namespace)
        if instance_store.exists(inst.path):
            raise CIMError(
                CIM_ERR_ALREADY_EXISTS,
                _format(
                    'CreateInstance failed. Instance with path {0!A} '
                    'already exists in mock repository', inst.path))
        try:
            # TODO: This should go through self.conn.CreateInstance
            instance_store.create(inst.path, inst)
        except KeyError:
            raise

        return inst.path
Ejemplo n.º 5
0
    def remove_namespace(self, namespace, verbose=False):
        """
        Remove a CIM namespace from the CIM repository.

        The namespace must exist in the CIM repository and must be empty.

        The Interop namespace cannot be removed from the CIM repository.

        Parameters:

          namespace (:term:`string`):
            The name of the CIM namespace in the CIM repository (case
            insensitive). Must not be `None`. Leading or trailing
            slash characters are ignored.

          verbose (:class:`py:bool`):
            Verbose mode: Print a message about the namespace deletion.

        Raises:

          ValueError: Namespace argument must not be None.
          :exc:`~pywbem.CIMError`:  CIM_ERR_NOT_FOUND if the namespace does
            not exist in the CIM repository.
          :exc:`~pywbem.CIMError`:  CIM_ERR_INVALID_NAMESPACE if the Interop
            namespace was specified.
          :exc:`~pywbem.CIMError`:  CIM_ERR_NAMESPACE_NOT_EMPTY if the
            namespace icontains objects.
          :exc:`~pywbem.CIMError`:  CIM_ERR_NAMESPACE_NOT_EMPTY if attempting
            to delete the default connection namespace.  This namespace cannot
            be deleted from the CIM repository
        """
        if namespace is None:
            raise ValueError("Namespace argument must not be None")

        namespace = namespace.strip('/')

        if namespace not in self.cimrepository.namespaces:
            raise CIMError(
                CIM_ERR_NOT_FOUND,
                _format(
                    "Namespace {0!A} does not exist in the CIM repository ",
                    namespace))

        if self.is_interop_namespace(namespace):
            raise CIMError(
                CIM_ERR_INVALID_NAMESPACE,
                _format(
                    "The Interop namespace {0!A} cannot be removed from "
                    "the CIM repository.", namespace))

        if verbose:
            print("Deleting namespace {} (in mock support)".format(namespace))
        try:
            self.cimrepository.remove_namespace(namespace)
        # KeyError cannot happen because existence was already verified
        except ValueError:
            raise CIMError(
                CIM_ERR_NAMESPACE_NOT_EMPTY,
                _format("Namespace {0!A} contains objects.", namespace))
Ejemplo n.º 6
0
    def add_namespace(self, namespace, verbose=False):
        """
        Add a CIM namespace to the CIM repository.

        The namespace must not yet exist in the CIM repository and the
        repository can contain only one Interop namespace.

        An Interop namespace can be added with this method, if an Interop
        namespace does not yet exist in the CIM repository.

        Parameters:

          namespace (:term:`string`):
            The name of the CIM namespace in the CIM repository. Must not be
            `None`. Any leading or trailing slash characters are removed before
            the string is used to define the namespace name.

          verbose (:class:`py:bool`):
            Verbose mode: Print a message about the namespace creation.

        Raises:

          ValueError: Namespace argument must not be None.
          :exc:`~pywbem.CIMError`: CIM_ERR_ALREADY_EXISTS if the namespace
            already exists in the CIM repository.
          :exc:`~pywbem.CIMError`: CIM_ERR_ALREADY_EXISTS if the namespace
            is one of the possible Interop namespace names and an interop
            namespace already exists in the CIM repository.
        """

        if namespace is None:
            raise ValueError("Namespace argument must not be None")

        namespace = namespace.strip('/')  # Just for appearance in exc messages

        # Cannot add more than one of the possible Interop namespace names
        if self.is_interop_namespace(namespace):
            if self.find_interop_namespace():
                raise CIMError(
                    CIM_ERR_ALREADY_EXISTS,
                    _format(
                        "An Interop namespace {0!A} already exists in the "
                        "CIM repository. {1!A} cannot be added. ",
                        self.find_interop_namespace(), namespace))
        if verbose:
            print("Creating namespace {} (in mock support)".format(namespace))
        try:
            self.cimrepository.add_namespace(namespace)
        except ValueError:
            raise CIMError(
                CIM_ERR_ALREADY_EXISTS,
                _format(
                    "Namespace {0!A} already exists in the CIM repository ",
                    namespace))
Ejemplo n.º 7
0
    def _validate_qualifiers(qualifiers, qualifier_store, new_class, scope):
        """
        Validate a list of qualifiers against the Qualifier decl in the
        repository.

        1. Whether it is declared (can be obtained from the declContext).
        2. Whether it has the same type as the declaration.
        3. Whether the qualifier is valid for the given scope.
        4. Whether the qualifier can be overridden.
        5. Whether the qualifier should be propagated to the subclass.

        Parameters:

          qualifiers: (:class:`py:dict` or `NocaseDict`_):
             Qualifiers to validate

          qualifier_store ():

          new_class (:class:`~pywbem.CIMClass`):
            The class being validated

        scope (:term:`string`):
            The scope defined for the object containing the qualifiers.
            May be 'CLASS', 'PROPERTY', 'METHOD', 'PARAMETER'

        """
        for qname, qual in qualifiers.items():
            if not qualifier_store.object_exists(qname):
                raise CIMError(
                    CIM_ERR_INVALID_PARAMETER,
                    _format("Qualifier {0!A} used in new class {1!A} "
                            "has no qualifier declaration in repository.",
                            qname, new_class.classname))
            q_decl = qualifier_store.get(qname)
            if qual.type != q_decl.type:
                raise CIMError(
                    CIM_ERR_INVALID_PARAMETER,
                    _format("Qualifier {0!A} used in new class {1!A} has "
                            "invalid type {2!A} (Qualifier declaration type: "
                            "{3!A}).",
                            qname, new_class.classname, qual.type,
                            q_decl.type))

            # Test for valid scope for this object type ot qualdecl ANY
            if not q_decl.scopes[scope] and not q_decl.scopes['ANY']:
                raise CIMError(
                    CIM_ERR_INVALID_PARAMETER,
                    _format("Qualifier {0!A} in new class {1!A} is used in "
                            "invalid scope: {2!A}. (QualifierDeclaration "
                            "scopes: ({3})",
                            qname, new_class.classname, scope,
                            ", ".join(
                                [s for s, v in q_decl.scopes.items() if v])))
Ejemplo n.º 8
0
    def DeleteInstance(self, InstanceName):
        # pylint: disable=invalid-name
        """
        Dispatcher for the DeleteInstance provider method.

        This method performs validations and if successful, routes the provider
        method call either to a registered provider, or to the default provider.
        """

        # Verify the input parameter types (type errors have already been
        # raised during checks in the WBEMConnection operation).
        assert isinstance(InstanceName, CIMInstanceName)

        # Verify that the namespace exists in the CIM repository.
        namespace = InstanceName.namespace
        self.validate_namespace(namespace)

        class_store = self.cimrepository.get_class_store(namespace)
        instance_store = self.cimrepository.get_instance_store(namespace)

        # Verify that the creation class of the instance to be deleted exists
        # in the CIM repository.
        if not class_store.object_exists(InstanceName.classname):
            raise CIMError(
                CIM_ERR_INVALID_CLASS,
                _format(
                    "Creation class {0!A} of instance to be deleted does "
                    "not exist in namespace {1!A} of the CIM repository.",
                    InstanceName.classname, namespace))

        # Verify that the instance to be deleted exists in the CIM repository.
        if not instance_store.object_exists(InstanceName):
            raise CIMError(
                CIM_ERR_NOT_FOUND,
                _format(
                    "Instance to be deleted does not exist in the CIM "
                    "repository: {0!A}", InstanceName))

        # Determine the provider to be used. Note that a registered provider
        # always has all provider methods for the provider type, either
        # implemented or inherited.
        provider = self.provider_registry.get_registered_provider(
            namespace, 'instance-write', InstanceName.classname)
        if not provider:
            provider = self.default_instance_write_provider

        # Call the provider method.
        result = provider.DeleteInstance(InstanceName)

        # Verify provider method result.
        assert result is None
Ejemplo n.º 9
0
    def CreateInstance(self, *args, **kwargs):
        """
        Create a CIM instance in the local repository of this class.
        This method is derived from the the same method in the pywbem
        mof compiler but modified to:
        1. Use a dictionary as the container for instances where the
           key is the path. This means that all instances must have a
           path component to be inserted into the repository. Normally
           the path component is built within the compiler by using the
           instance alias.
        2. Fail with a CIMError exception if the instance already exists
           in the repository.
           TODO: Determine if the logic should be to fail or replace.
           See pywbem issue #1890


        For a description of the parameters, see
        :meth:`pywbem.WBEMConnection.CreateInstance`.
        """

        inst = args[0] if args else kwargs['NewInstance']

        # TODO build path if does not exist. For now simply abort
        # NOTE: compiler does not build path unless the instance alias is
        # defined for the instance
        if inst.path is None or not inst.path.keybindings:
            raise CIMError(
                CIM_ERR_FAILED,
                _format(
                    'CreateInstance failed. No path in new_instance or '
                    'keybindings in path. ',
                    'Use compiler instance alias to set path on '
                    'instance declaration. inst: {0!A}', inst))

        if self.default_namespace not in self.instances:
            self.instances[self.default_namespace] = {}

        if inst.path in self.instances[self.default_namespace]:
            raise CIMError(
                CIM_ERR_ALREADY_EXISTS,
                _format(
                    'CreateInstance failed. Instance with path {0!A} '
                    'already exists in mock repository', inst.path))
        try:
            self.instances[self.default_namespace][inst.path] = inst
        except KeyError:
            self.instances[self.default_namespace] = {}
            self.instances[self.default_namespace][inst.path] = inst

        return inst.path
Ejemplo n.º 10
0
    def validate_no_subscription(self, instance_name):
        """
        Validate that no subscriptions exist containing reference to this
        instance.

        Parameters:

          instance_name (:class:`~pywbem.CIMInstanceName`)
            Instance name of the target instance. The class must be either
            the filter class or the listener destination class

        Returns:
          Returns if there are no corresponding subscriptions.
        """
        # If a subscription exists containing this ListenerDestination,
        # reject delete
        if self.conn.ReferenceNames(instance_name,
                                    ResultClass=SUBSCRIPTION_CLASSNAME):
            # DSP1054 1.2 defines CIM error is raised by the server
            # in that case; we simulate it.
            raise CIMError(CIM_ERR_FAILED,
                           _format(
                               "The instance {0} is referenced by "
                               "subscriptions.", instance_name),
                           conn_id=self.conn.conn_id)
Ejemplo n.º 11
0
def test_cimerror_2(status_tuple, conn_info):
    # pylint: disable=redefined-outer-name
    """
    Test CIMError exception class with status_code and description as input.
    """

    status_code, status_code_name = status_tuple
    conn_id_kwarg, exp_conn_str = conn_info

    invalid_code_name = 'Invalid status code %s' % status_code
    input_desc = 'foo'

    exc = CIMError(status_code, input_desc, **conn_id_kwarg)

    assert exc.status_code == status_code
    assert exc.status_description == input_desc
    if status_code_name is None:
        assert exc.status_code_name == invalid_code_name
    else:
        assert exc.status_code_name == status_code_name

    assert exc.args[0] == exc.status_code
    assert exc.args[1] == input_desc
    assert exc.args[2] is None
    assert len(exc.args) == 3

    _assert_connection(exc, conn_id_kwarg, exp_conn_str)
    _assert_subscription(exc)
Ejemplo n.º 12
0
    def _getResultParams(result):
        """Common processing for pull results to separate
           end-of-sequence, enum-context, and entities in IRETURNVALUE.
           Returns tuple of entities in IRETURNVALUE, end_of_sequence,
           and enumeration_context)
        """
        end_of_sequence = False
        enumeration_context = None

        sequence = result.get('EndOfSequence')
        if sequence and isinstance(sequence, six.string_types) and \
                        sequence.lower() in ['true', 'false']:  # noqa: E125
            end_of_sequence = sequence.lower() == 'true'

        context = result.get('EnumerationContext')
        if context and isinstance(context, six.string_types):  # noqa: E125
            enumeration_context = context

        rtn_objects = result.get('IRETURNVALUE') or []

        if not sequence or not context:
            raise CIMError(CIM_ERR_INVALID_PARAMETER,
                           "EndOfSequence or EnumerationContext required")

        # convert enum context if eos is True
        # Otherwise, returns tuple of enumeration context and namespace
        rtn_ctxt = None if end_of_sequence else enumeration_context

        if rtn_ctxt:
            return (rtn_objects, end_of_sequence, rtn_ctxt)
        else:
            return rtn_objects
Ejemplo n.º 13
0
    def validate_namespace(self, namespace):
        """
        Validates that a namespace is defined in the CIM repository.
        Returns only if namespace is valid. Otherwise it generates an
        exception.

        Parameters:

          namespace (:term:`string`):
            The name of the CIM namespace in the CIM repository (case
            insensitive). Must not be `None`. Any leading or trailing
            slash characters are ignored.

        Raises:

            :exc:`~pywbem.CIMError`: (CIM_ERR_INVALID_NAMESPACE)
              Namespace does not exist.
        """
        try:
            self.cimrepository.validate_namespace(namespace)
        except KeyError:
            raise CIMError(
                CIM_ERR_INVALID_NAMESPACE,
                _format("Namespace does not exist in CIM repository: {0!A}",
                        namespace))
Ejemplo n.º 14
0
    def DeleteQualifier(self, *args, **kwargs):
        """This method is only invoked by :meth:`rollback` (on the underlying
        repository), and never by the MOF compiler, and is therefore not
        implemented."""

        raise CIMError(CIM_ERR_FAILED,
                       'This should not happen!',
                       conn_id=self.conn_id)
Ejemplo n.º 15
0
    def handleEndHeaders(self):
        """Check whether the status was OK and raise an error if not
        using previously saved header information."""

        if self.status != '200':

            if not hasattr(self, 'cimerror') or \
               not hasattr(self, 'errordetail'):

                self.factory.deferred.errback(
                    CIMError(0, 'HTTP error %s: %s' %
                             (self.status, self.message)))

            else:

                self.factory.deferred.errback(
                    CIMError(0, '%s: %s' % (cimerror, errordetail)))
Ejemplo n.º 16
0
 def ModifyInstance(self, modified_instance, IncludeQualifiers=None):
     """
     Modification of CIM_Namespace instance not allowed
     """
     raise CIMError(
         CIM_ERR_NOT_SUPPORTED,
         _format("Modification of {0} instances is not allowed: "
                 "{1!A}", NAMESPACE_CLASSNAME, modified_instance.path))
Ejemplo n.º 17
0
    def EnumerateInstanceNames(self, *args, **kwargs):
        """This method is used by the MOF compiler only when it creates a
        namespace in the course of handling CIM_ERR_NAMESPACE_NOT_FOUND.
        Because the operations of this class silently create every namespace
        that is needed and never return that error, this method is never
        called, and is therefore not implemented.
        """

        raise CIMError(CIM_ERR_FAILED,
                       'This should not happen!',
                       conn_id=self.conn_id)
Ejemplo n.º 18
0
 def parameter_is_interop(self, ns, classname):
     # pylint: disable=no-self-use
     """
     Test if the parameter provided in ns is the interop namespace
     """
     if not self.is_interop_namespace(ns):
         raise CIMError(
             CIM_ERR_INVALID_PARAMETER,
             _format(
                 "Cannot create instance of class {0!A} in namespace {1!A}: "
                 "The namespace is not an Interop namespace. "
                 "Valid Interop namespaces are: {2!A}", classname, ns,
                 ", ".join(self.interop_namespace_names)))
Ejemplo n.º 19
0
 def _test_qualifier_decl(qualifier, qualifier_store, namespace):
     """
     Test that qualifier is in repo and valid.
     """
     if qualifier_store is None:
         return
     if not qualifier_store.exists(qualifier.name):
         raise CIMError(
             CIM_ERR_INVALID_PARAMETER,
             _format(
                 "Qualifier declaration {0!A} required by CreateClass "
                 "not found in namespace {1!A}.", qualifier.name,
                 namespace))
Ejemplo n.º 20
0
    def DeleteInstance(self, InstanceName):
        """
        Delete an instance of the CIM_Namespace class in an Interop namespace
        of the CIM repository, and in addition delete the namespace represented
        by it in the CIM repository.

        See `~pywbem_mock.InstanceWriteProvider.CreateInstance` for
        documentation of validation and description of input parameters, noting
        extra conditions for this provider as described below:

        The namespace to be deleted must be empty and must not be the Interop
        namespace.

        Parameters:

          InstanceName: (:class:`~pywbem.CIMInstanceName`):
            The keybinding `Name` must exist; it defines the namespace to be
            deleted.

        Raises:

          :exc:`~pywbem.CIMError`: (CIM_ERR_INVALID_PARAMETER)
          :exc:`~pywbem.CIMError`: (CIM_ERR_NAMESPACE_NOT_EMPTY)
        """

        # The provider dispatcher ensures that provider methods are only called
        # for the registered classes.
        # And this provider sets only a single class, not a list.
        assert InstanceName.classname.lower() == \
            CIMNamespaceProvider.provider_classnames.lower()

        remove_namespace = InstanceName.keybindings['Name']

        if self.is_interop_namespace(remove_namespace):
            raise CIMError(
                CIM_ERR_INVALID_PARAMETER,
                _format(
                    "Cannot delete instance {0!A} from the CIM repository: "
                    "This instance represents the Interop namespace {1!A} "
                    "which must not be deleted.", InstanceName,
                    remove_namespace))

        # Delete the namespace from the CIM repository.
        # This call verifies that the namespace is empty and raises
        # CIMError(CIM_ERR_NAMESPACE_NOT_EMPTY) if not empty.
        self.remove_namespace(remove_namespace)

        # Delete the instance from the CIM repository
        instance_store = self.cimrepository.get_instance_store(
            InstanceName.namespace)
        instance_store.delete(InstanceName)
Ejemplo n.º 21
0
 def _test_qualifier_decl(qualifier, qualifier_repo, namespace):
     """
     Test that qualifier is in repo and valid.
     For for conn_lite, ignore this test
     """
     if qualifier_repo is None:
         return
     if qualifier.name not in qualifier_repo:
         raise CIMError(
             CIM_ERR_INVALID_PARAMETER,
             _format(
                 "Qualifier declaration {0!A} required by CreateClass "
                 "not found in namespace {1!A}.", qualifier.name,
                 namespace))
Ejemplo n.º 22
0
    def _validate_qualifiers(qualifier_list, qualifier_store, new_class,
                             scope):
        """
        Validate a list of qualifiers against the Qualifier decl in the
        repository.

        1. Whether it is declared (can be obtained from the declContext).
        2. Whether it has the same type as the declaration.
        3. Whether the qualifier is valid for the given scope.
        4. Whether the qualifier can be overridden.
        5. Whether the qualifier should be propagated to the subclass.
        """
        for qname, qvalue in qualifier_list.items():
            if not qualifier_store.exists(qname):
                raise CIMError(
                    CIM_ERR_INVALID_PARAMETER,
                    _format(
                        "Qualifier {0!A} used in new class {1!A} "
                        "has no qualifier declaration in repository.", qname,
                        new_class.classname))
            q_decl = qualifier_store.get(qname)
            if qvalue.type != q_decl.type:
                raise CIMError(
                    CIM_ERR_INVALID_PARAMETER,
                    _format(
                        "Qualifier {0!A} used in new class {1!A} has "
                        "invalid type {2!A} (Qualifier declaration type: "
                        "{3!A}).", qname, new_class.classname, qvalue.type,
                        q_decl.type))
            if scope not in q_decl.scopes and 'ANY' not in q_decl.scopes:
                raise CIMError(
                    CIM_ERR_INVALID_PARAMETER,
                    _format(
                        "Qualifier {0!A} in new class {1!A} is used in "
                        "invalid scope {2!A} (Qualifier declaration "
                        "scopes: {3})", qname, new_class.classname, scope,
                        q_decl.scopes))
Ejemplo n.º 23
0
    def CreateInstance(self, *args, **kwargs):
        """
        Create a CIM instance in the connected client.

        This method:

        1. Validates properties and the class
        2. Sets the instance path to None to assuming that the
           conn.CreateInstance creates a complete path.
        3. Passes the NewInstance to conn.CreateInstance (the client
           that is connected to a repository)

        For a description of the parameters, see
        :meth:`pywbem.WBEMConnection.CreateInstance`.
        """

        inst = args[0] if args else kwargs['NewInstance']

        ns = kwargs.get('namespace', self.default_namespace)

        # Get list of properties in class defined for this instance
        cln = inst.classname
        cls = self.GetClass(cln, namespace=ns, IncludeQualifiers=True,
                            LocalOnly=False)

        cls_key_properties = [p for p, v in cls.properties.items()
                              if 'key' in v.qualifiers]

        # Validate all key properties are in instance
        for pname in cls_key_properties:
            if pname not in inst.properties:
                raise CIMError(
                    CIM_ERR_INVALID_PARAMETER,
                    _format('CreateInstance failed. Key property {0!A}  in '
                            'class {1!A} but not in new_instance: {2!A}',
                            pname, cln, str(inst)))

        # Insure inst.path is empty before calling CreateInstance so that
        # the path is built by CreateInstance. This is logical because
        # the mock environment always requires a complete path to insert
        # an instance into the repository.
        inst.path = None

        try:
            path = self.conn.CreateInstance(inst, namespace=ns)
        except KeyError:  # pylint: disable=try-except-raise
            raise
        return path
Ejemplo n.º 24
0
 def validate_required_properties_exist(self, new_instance, namespace,
                                        required_properties):
     # pylint: disable=no-self-use
     """
     Validate that the properties in required_properties list do exist
     in the new_instance
     """
     for pn in required_properties:
         if pn not in new_instance:
             raise CIMError(
                 CIM_ERR_INVALID_PARAMETER,
                 _format(
                     "Cannot create instance of class {0!A} in "
                     "namespace {1!A}: "
                     "Missing required property {2!A} in new_instance",
                     new_instance.classname, namespace, pn))
Ejemplo n.º 25
0
    def parseErrorAndResponse(self, data):
        """Parse returned XML for errors, then convert into
        appropriate Python objects."""

        xml = fromstring(data)
        error = xml.find('.//ERROR')

        if error is None:
            self.deferred.callback(self.parseResponse(xml))
            return

        try:
            code = int(error.attrib['CODE'])
        except ValueError:
            code = 0

        self.deferred.errback(CIMError(code, error.attrib['DESCRIPTION']))
Ejemplo n.º 26
0
    def __init__(self, cimrepository):
        """
        Parameters:

          cimrepository (:class:`~pywbem_mock.BaseRepository` or subclass):
            Defines the CIM repository to be used by the provider.
        """
        super(CIMNamespaceProvider, self).__init__(cimrepository)

        if not self.find_interop_namespace():
            raise CIMError(
                CIM_ERR_INVALID_PARAMETER,
                _format(
                    "Cannot create namespace provider (for class {0}): "
                    "No Interop namespace exists in the CIM repository. "
                    "Valid Interop namespaces are: {1}", NAMESPACE_CLASSNAME,
                    ", ".join(self.interop_namespace_names)))

        self.installed = False  # test if provider previously installed.
Ejemplo n.º 27
0
def test_cimerror_3(status_tuple, error_instances, conn_info):
    # pylint: disable=redefined-outer-name
    """
    Test CIMError exception class with status_code and instances as input.
    """

    status_code, status_code_name = status_tuple
    conn_id_kwarg, exp_conn_str = conn_info

    exc = CIMError(status_code, instances=error_instances, **conn_id_kwarg)

    assert exc.status_code == status_code
    if status_code_name is not None:
        assert exc.status_code_name == status_code_name

    assert exc.args[2] == error_instances
    assert len(exc.args) == 3

    _assert_connection(exc, conn_id_kwarg, exp_conn_str)
    _assert_subscription(exc)
Ejemplo n.º 28
0
    def __init__(self, cimrepository):
        """
        Parameters:

          cimrepository (:class:`~pywbem_mock.BaseRepository` or subclass):
            Defines the CIM repository to be used by the provider.
        """
        super(CIMIndicationSubscriptionProvider, self).__init__(cimrepository)

        if not self.find_interop_namespace():
            raise CIMError(
                CIM_ERR_INVALID_PARAMETER,
                _format(
                    "Cannot create indication subscription provider for "
                    "class: {0}. "
                    "No Interop namespace exists in the CIM repository. "
                    "Valid Interop namespaces are: {1}", FILTER_CLASSNAME,
                    ", ".join(self.interop_namespace_names)))

        self.installed = False  # test if provider previously installed.
        self.conn = None
Ejemplo n.º 29
0
def test_cimerror_1(status_tuple):  # pylint: disable=redefined-outer-name
    """Test cimerror"""
    status_code = status_tuple[0]
    status_code_name = status_tuple[1]

    invalid_code_name = 'Invalid status code %s' % status_code
    invalid_code_desc = 'Invalid status code %s' % status_code

    exc = CIMError(status_code)

    assert exc.status_code == status_code
    if status_code_name is None:
        assert exc.status_description == invalid_code_desc
        assert exc.status_code_name == invalid_code_name
    else:
        assert isinstance(exc.status_description, six.string_types)
        assert exc.status_code_name == status_code_name

    assert exc.args[0] == exc.status_code
    assert exc.args[1] is None
    assert len(exc.args) == 2

    _assert_subscription(exc)
Ejemplo n.º 30
0
    def GetClass(self, *args, **kwargs):
        """Retrieve a CIM class from the local repository of this class.

        For a description of the parameters, see
        :meth:`pywbem.WBEMConnection.GetClass`.
        """
        cname = args[0] if args else kwargs['ClassName']

        try:
            cc = self.classes[self.default_namespace][cname]
        except KeyError:
            if self.conn is None:
                ce = CIMError(CIM_ERR_NOT_FOUND, cname)
                raise ce
            cc = self.conn.GetClass(*args, **kwargs)
            try:
                self.classes[self.default_namespace][cc.classname] = cc
            except KeyError:
                self.classes[self.default_namespace] = \
                    NocaseDict({cc.classname: cc})

        if 'LocalOnly' in kwargs and not kwargs['LocalOnly']:
            if cc.superclass:
                try:
                    del kwargs['ClassName']
                except KeyError:
                    pass
                if args:
                    args = args[1:]
                super_ = self.GetClass(cc.superclass, *args, **kwargs)
                for prop in super_.properties.values():
                    if prop.name not in cc.properties:
                        cc.properties[prop.name] = prop
                for meth in super_.methods.values():
                    if meth.name not in cc.methods:
                        cc.methods[meth.name] = meth
        return cc