Beispiel #1
0
    def get_target_version(cls):
        """Returns the target version for this object.

        This is the version in which the object should be manipulated, e.g.
        sent over the wire via RPC or saved in the DB.

        :returns: if pinned, returns the version of this object corresponding
                  to the pin. Otherwise, returns the version of the object.
        :raises: ovo_exception.IncompatibleObjectVersion
        """
        pin = CONF.pin_release_version
        if not pin:
            return cls.VERSION

        version_manifest = versions.RELEASE_MAPPING[pin]['objects']
        pinned_version = version_manifest.get(cls.obj_name())
        if pinned_version:
            pinned_version = pinned_version[0]
            if not versionutils.is_compatible(pinned_version,
                                              cls.VERSION):
                LOG.error(
                    'For object "%(objname)s", the target version '
                    '"%(target)s" is not compatible with its supported '
                    'version "%(support)s". The value ("%(pin)s") of the '
                    '"pin_release_version" configuration option may be '
                    'incorrect.',
                    {'objname': cls.obj_name(), 'target': pinned_version,
                     'support': cls.VERSION, 'pin': pin})
                raise ovo_exception.IncompatibleObjectVersion(
                    objname=cls.obj_name(), objver=pinned_version,
                    supported=cls.VERSION)
            return pinned_version

        return cls.VERSION
Beispiel #2
0
 def obj_make_compatible(self, primitive, target_version):
     LOG.info('%s(): caller(): %s', log_utils.get_fname(1),
              log_utils.get_fname(2))
     _target_version = versionutils.convert_version_to_tuple(target_version)
     if _target_version < (1, 3):
         raise exception.IncompatibleObjectVersion(
             objver=target_version, objtype=self.__class__.__name__)
Beispiel #3
0
 def obj_make_compatible(self, primitive, target_version):
     _target_version = versionutils.convert_version_to_tuple(target_version)
     if _target_version >= (1, 1):
         if primitive['mtu'] is None:
             # mtu will not be nullable after
             raise exception.IncompatibleObjectVersion(
                 objver=target_version, objname=self.__class__.__name__)
Beispiel #4
0
 def obj_make_compatible(self, primitive, target_version):
     _target_version = versionutils.convert_version_to_tuple(target_version)
     if _target_version < (1, 3) and 'direction' in primitive:
         direction = primitive.pop('direction')
         if direction == constants.INGRESS_DIRECTION:
             raise exception.IncompatibleObjectVersion(
                 objver=target_version, objtype="QosBandwidthLimitRule")
    def obj_class_from_name(cls, objname, objver):
        """Returns a class from the registry based on a name and version."""
        if objname not in VersionedObjectRegistry.obj_classes():
            LOG.error(
                _LE('Unable to instantiate unregistered object type '
                    '%(objtype)s'), dict(objtype=objname))
            raise exception.UnsupportedObjectError(objtype=objname)

        # NOTE(comstud): If there's not an exact match, return the highest
        # compatible version. The objects stored in the class are sorted
        # such that highest version is first, so only set compatible_match
        # once below.
        compatible_match = None

        for objclass in VersionedObjectRegistry.obj_classes()[objname]:
            if objclass.VERSION == objver:
                return objclass
            if (not compatible_match
                    and vutils.is_compatible(objver, objclass.VERSION)):
                compatible_match = objclass

        if compatible_match:
            return compatible_match

        # As mentioned above, latest version is always first in the list.
        latest_ver = VersionedObjectRegistry.obj_classes()[objname][0].VERSION
        raise exception.IncompatibleObjectVersion(objname=objname,
                                                  objver=objver,
                                                  supported=latest_ver)
Beispiel #6
0
    def obj_make_compatible(self, primitive, target_version):
        def filter_rules(obj_names, rules):
            return [rule for rule in rules if
                    rule['versioned_object.name'] in obj_names]

        _target_version = versionutils.convert_version_to_tuple(target_version)
        names = []
        if _target_version >= (1, 0):
            names.append(rule_obj_impl.QosBandwidthLimitRule.obj_name())
        if _target_version >= (1, 1):
            names.append(rule_obj_impl.QosDscpMarkingRule.obj_name())
        if _target_version >= (1, 2):
            names.append(rule_obj_impl.QosMinimumBandwidthRule.obj_name())
        if 'rules' in primitive and names:
            primitive['rules'] = filter_rules(names, primitive['rules'])

        if _target_version < (1, 3):
            standard_fields = ['revision_number', 'created_at', 'updated_at']
            for f in standard_fields:
                primitive.pop(f)
            if primitive['description'] is None:
                # description was not nullable before
                raise exception.IncompatibleObjectVersion(
                    objver=target_version, objname='QoSPolicy')

        if _target_version < (1, 4):
            primitive['tenant_id'] = primitive.pop('project_id')
Beispiel #7
0
 def obj_make_compatible(self, primitive, target_version):
     LOG.info('%s(): caller(): %s', log_utils.get_fname(1), log_utils.get_fname(2))
     _target_version = versionutils.convert_version_to_tuple(target_version)
     if _target_version >= (1, 1):
         if primitive['mtu'] is None:
             # mtu will not be nullable after
             raise exception.IncompatibleObjectVersion(
                 objver=target_version, objname=self.__class__.__name__)
Beispiel #8
0
    def _from_db_object(context, obj, db_object, fields=None):
        """Converts a database entity to a formal object.

        This always converts the database entity to the latest version
        of the object. Note that the latest version is available at
        object.__class__.VERSION. object.VERSION is the version of this
        particular object instance; it is possible that it is not the latest
        version.

        :param context: security context
        :param obj: An object of the class.
        :param db_object: A DB entity of the object
        :param fields: list of fields to set on obj from values from db_object.
        :return: The object of the class with the database entity added
        :raises: ovo_exception.IncompatibleObjectVersion
        """
        objname = obj.obj_name()
        db_version = db_object['version']

        if db_version is None:
            # NOTE(rloo): This can only happen if the DB is corrupt or this
            # is the conductor object. (Because the rest of the objects will
            # all have their DB version set properly.)
            # TODO(rloo): This entire if clause can be deleted in Rocky
            # since the dbsync online migration populates all the conductor
            # versions and it must be run to completion before upgrading to
            # Rocky.
            db_version = versions.RELEASE_MAPPING['pike']['objects'].get(
                objname, ['1.0'])[0]

        if not versionutils.is_compatible(db_version, obj.__class__.VERSION):
            raise ovo_exception.IncompatibleObjectVersion(
                objname=objname, objver=db_version,
                supported=obj.__class__.VERSION)

        obj._set_from_db_object(context, db_object, fields)

        obj._context = context

        # NOTE(rloo). We now have obj, a versioned object that corresponds to
        # its DB representation. A versioned object has an internal attribute
        # ._changed_fields; this is a list of changed fields -- used, e.g.,
        # when saving the object to the DB (only those changed fields are
        # saved to the DB). The obj.obj_reset_changes() clears this list
        # since we didn't actually make any modifications to the object that
        # we want saved later.
        obj.obj_reset_changes()

        if db_version != obj.__class__.VERSION:
            # convert to the latest version
            obj.VERSION = db_version
            obj.convert_to_version(obj.__class__.VERSION,
                                   remove_unavailable_fields=False)

        return obj
Beispiel #9
0
    def obj_make_compatible(self, primitive, target_version):
        def filter_rules(obj_names, rules):
            return [
                rule for rule in rules
                if rule['versioned_object.name'] in obj_names
            ]

        def filter_ingress_bandwidth_limit_rules(rules):
            bwlimit_obj_name = rule_obj_impl.QosBandwidthLimitRule.obj_name()
            filtered_rules = []
            for rule in rules:
                if rule['versioned_object.name'] == bwlimit_obj_name:
                    direction = rule['versioned_object.data'].get("direction")
                    if direction == n_const.EGRESS_DIRECTION:
                        rule['versioned_object.data'].pop('direction')
                        filtered_rules.append(rule)
                else:
                    filtered_rules.append(rule)
            return filtered_rules

        _target_version = versionutils.convert_version_to_tuple(target_version)
        names = []
        if _target_version >= (1, 0):
            names.append(rule_obj_impl.QosBandwidthLimitRule.obj_name())
        if _target_version >= (1, 1):
            names.append(rule_obj_impl.QosDscpMarkingRule.obj_name())
        if _target_version >= (1, 2):
            names.append(rule_obj_impl.QosMinimumBandwidthRule.obj_name())
        if 'rules' in primitive and names:
            primitive['rules'] = filter_rules(names, primitive['rules'])

        if _target_version < (1, 3):
            standard_fields = ['revision_number', 'created_at', 'updated_at']
            for f in standard_fields:
                primitive.pop(f)
            if primitive['description'] is None:
                # description was not nullable before
                raise exception.IncompatibleObjectVersion(
                    objver=target_version, objname='QoSPolicy')

        if _target_version < (1, 4):
            primitive['tenant_id'] = primitive.pop('project_id')

        if _target_version < (1, 5):
            if 'rules' in primitive:
                primitive['rules'] = filter_ingress_bandwidth_limit_rules(
                    primitive['rules'])

        if _target_version < (1, 6):
            primitive.pop('is_default', None)
Beispiel #10
0
 def obj_make_compatible(self, primitive, target_version):
     def filter_rules(obj_names, rules):
         return [rule for rule in rules if
                 rule['versioned_object.name'] in obj_names]
     _target_version = versionutils.convert_version_to_tuple(target_version)
     if _target_version < (1, 8):
         raise exception.IncompatibleObjectVersion(
             objver=target_version, objname=self.__class__.__name__)
     names = [
         rule_obj_impl.QosBandwidthLimitRule.obj_name(),
         rule_obj_impl.QosDscpMarkingRule.obj_name(),
         rule_obj_impl.QosMinimumBandwidthRule.obj_name(),
     ]
     if _target_version >= (1, 9):
         names.append(rule_obj_impl.QosPacketRateLimitRule.obj_name())
     if 'rules' in primitive and names:
         primitive['rules'] = filter_rules(names, primitive['rules'])
Beispiel #11
0
    def _from_db_object(context, obj, db_object, fields=None):
        """Converts a database entity to a formal object.

        This always converts the database entity to the latest version
        of the object. Note that the latest version is available at
        object.__class__.VERSION. object.VERSION is the version of this
        particular object instance; it is possible that it is not the latest
        version.

        :param context: security context
        :param obj: An object of the class.
        :param db_object: A DB entity of the object
        :param fields: list of fields to set on obj from values from db_object.
        :return: The object of the class with the database entity added
        :raises: ovo_exception.IncompatibleObjectVersion
        """
        objname = obj.obj_name()
        db_version = db_object['version']

        if not versionutils.is_compatible(db_version, obj.__class__.VERSION):
            raise ovo_exception.IncompatibleObjectVersion(
                objname=objname,
                objver=db_version,
                supported=obj.__class__.VERSION)

        obj._set_from_db_object(context, db_object, fields)

        obj._context = context

        # NOTE(rloo). We now have obj, a versioned object that corresponds to
        # its DB representation. A versioned object has an internal attribute
        # ._changed_fields; this is a list of changed fields -- used, e.g.,
        # when saving the object to the DB (only those changed fields are
        # saved to the DB). The obj.obj_reset_changes() clears this list
        # since we didn't actually make any modifications to the object that
        # we want saved later.
        obj.obj_reset_changes()

        if db_version != obj.__class__.VERSION:
            # convert to the latest version
            obj.VERSION = db_version
            obj.convert_to_version(obj.__class__.VERSION,
                                   remove_unavailable_fields=False)

        return obj
Beispiel #12
0
    def obj_class_from_name(cls, objname, objver):
        """Returns a class from the registry based on a name and version."""
        # NOTE(slaweq): it is override method
        # oslo_versionedobjects.base.VersionedObject.obj_class_from_name
        # We need to override it to use Neutron's objects registry class
        # (NeutronObjectRegistry) instead of original VersionedObjectRegistry
        # class from oslo_versionedobjects
        # This is necessary to avoid clash in naming objects between Neutron
        # and e.g. os-vif (for example Route or Subnet objects are used in
        # both)
        if objname not in NeutronObjectRegistry.obj_classes():
            LOG.error('Unable to instantiate unregistered object type '
                      '%(objtype)s', dict(objtype=objname))
            raise obj_exception.UnsupportedObjectError(objtype=objname)

        # NOTE(comstud): If there's not an exact match, return the highest
        # compatible version. The objects stored in the class are sorted
        # such that highest version is first, so only set compatible_match
        # once below.
        compatible_match = None

        for objclass in NeutronObjectRegistry.obj_classes()[objname]:
            if objclass.VERSION == objver:
                return objclass
            if (not compatible_match and
                    versionutils.is_compatible(objver, objclass.VERSION)):
                compatible_match = objclass

        if compatible_match:
            return compatible_match

        # As mentioned above, latest version is always first in the list.
        latest_ver = (
            NeutronObjectRegistry.obj_classes()[objname][0].VERSION)
        raise obj_exception.IncompatibleObjectVersion(objname=objname,
                                                      objver=objver,
                                                      supported=latest_ver)
Beispiel #13
0
 def obj_make_compatible(self, primitive, target_version):
     _target_version = versionutils.convert_version_to_tuple(target_version)
     if _target_version < (1, 2):
         raise exception.IncompatibleObjectVersion(
             objver=target_version, objname="QosMinimumBandwidthRule")
Beispiel #14
0
 def obj_make_compatible(self, primitive, target_version):
     _target_version = versionutils.convert_version_to_tuple(target_version)
     if _target_version < (1, 1):
         raise exception.IncompatibleObjectVersion(
             objver=target_version, objname="QosDscpMarkingRule")
Beispiel #15
0
 def obj_make_compatible(self, primitive, target_version):
     _target_version = versionutils.convert_version_to_tuple(target_version)
     if _target_version < (1, 3):
         raise exception.IncompatibleObjectVersion(
             objver=target_version, objtype=self.__class__.__name__)
Beispiel #16
0
    def _from_db_object(context, obj, db_object, fields=None):
        """Converts a database entity to a formal object.

        This always converts the database entity to the latest version
        of the object. Note that the latest version is available at
        object.__class__.VERSION. object.VERSION is the version of this
        particular object instance; it is possible that it is not the latest
        version.

        :param context: security context
        :param obj: An object of the class.
        :param db_object: A DB entity of the object
        :param fields: list of fields to set on obj from values from db_object.
        :return: The object of the class with the database entity added
        :raises: ovo_exception.IncompatibleObjectVersion
        """
        objname = obj.obj_name()
        db_version = db_object['version']

        if db_version is None:
            # NOTE(rloo): This can only happen after we've updated the DB
            # tables to include the 'version' column but haven't saved the
            # object to the DB since the new column was added. This column is
            # added in the Pike cycle, so if the version isn't set, use the
            # version associated with the most recent release, i.e. '8.0'.
            # The objects and RPC versions haven't changed between '8.0' and
            # Ocata, which is why it is fine to use Ocata.
            # Furthermore, if this is a new object that did not exist in the
            # most recent release, we assume it is version 1.0.
            # TODO(rloo): This entire if clause can be deleted in Queens
            # since the dbsync online migration populates all the versions
            # and it must be run to completion before upgrading to Queens.
            db_version = versions.RELEASE_MAPPING['ocata']['objects'].get(
                objname, '1.0')

        if not versionutils.is_compatible(db_version, obj.__class__.VERSION):
            raise ovo_exception.IncompatibleObjectVersion(
                objname=objname,
                objver=db_version,
                supported=obj.__class__.VERSION)

        obj._set_from_db_object(context, db_object, fields)

        obj._context = context

        # NOTE(rloo). We now have obj, a versioned object that corresponds to
        # its DB representation. A versioned object has an internal attribute
        # ._changed_fields; this is a list of changed fields -- used, e.g.,
        # when saving the object to the DB (only those changed fields are
        # saved to the DB). The obj.obj_reset_changes() clears this list
        # since we didn't actually make any modifications to the object that
        # we want saved later.
        obj.obj_reset_changes()

        if db_version != obj.__class__.VERSION:
            # convert to the latest version
            obj.convert_to_version(obj.__class__.VERSION)
            if obj.get_target_version() == db_version:
                # pinned, so no need to keep these changes (we'll end up
                # converting back to db_version if obj is saved)
                obj.obj_reset_changes()
            else:
                # keep these changes around because they are needed
                # when/if saving to the DB in the latest version
                pass

        return obj