Exemple #1
0
    def patch(self, flavor_uuid, patch):
        """Update a flavor.

        :param flavor_uuid: the uuid of the flavor to be updated.
        :param flavor: a json PATCH document to apply to this flavor.
        """

        db_flavor = objects.Flavor.get(pecan.request.context, flavor_uuid)

        try:
            flavor = Flavor(
                **api_utils.apply_jsonpatch(db_flavor.as_dict(), patch))

        except api_utils.JSONPATCH_EXCEPTIONS as e:
            raise exception.PatchError(patch=patch, reason=e)

        # Update only the fields that have changed
        for field in objects.Flavor.fields:
            try:
                patch_val = getattr(flavor, field)
            except AttributeError:
                # Ignore fields that aren't exposed in the API
                continue
            if patch_val == wtypes.Unset:
                patch_val = None
            if db_flavor[field] != patch_val:
                db_flavor[field] = patch_val

        db_flavor.save()

        return Flavor.convert_with_links(db_flavor)
Exemple #2
0
    def patch(self, server_uuid, patch):
        """Update a server.

        :param server_uuid: UUID of a server.
        :param patch: a json PATCH document to apply to this server.
        """
        db_server = self._resource or self._get_resource(server_uuid)
        try:
            server = Server(
                **api_utils.apply_jsonpatch(db_server.as_dict(), patch))

        except api_utils.JSONPATCH_EXCEPTIONS as e:
            raise exception.PatchError(patch=patch, reason=e)

        # Update only the fields that have changed
        for field in objects.Server.fields:
            if field == 'nics':
                continue
            try:
                patch_val = getattr(server, field)
            except AttributeError:
                # Ignore fields that aren't exposed in the API
                continue
            if patch_val == wtypes.Unset:
                patch_val = None
            if db_server[field] != patch_val:
                db_server[field] = patch_val

        db_server.save()

        return Server.convert_with_links(db_server.as_dict())
Exemple #3
0
    def patch(self, aggregate_uuid, patch):
        """Update an aggregate.

        :param aggregate_uuid: the uuid of the aggregate to be updated.
        :param aggregate: a json PATCH document to apply to this aggregate.
        """

        db_aggregate = objects.Aggregate.get(pecan.request.context,
                                             aggregate_uuid)

        try:
            aggregate = Aggregate(
                **api_utils.apply_jsonpatch(db_aggregate.as_dict(), patch))

        except api_utils.JSONPATCH_EXCEPTIONS as e:
            raise exception.PatchError(patch=patch, reason=e)

        # Check whether it is safe to update metadata
        self._is_safe_to_update_metadata(patch, db_aggregate['uuid'])

        # Update only the fields that have changed
        for field in objects.Aggregate.fields:
            try:
                patch_val = getattr(aggregate, field)
            except AttributeError:
                # Ignore fields that aren't exposed in the API
                continue
            if patch_val == wtypes.Unset:
                patch_val = None
            if db_aggregate[field] != patch_val:
                db_aggregate[field] = patch_val

        db_aggregate.save()

        return Aggregate.convert_with_links(db_aggregate)
Exemple #4
0
    def patch(self, aggregate_uuid, patch):
        """Update an aggregate.

        :param aggregate_uuid: the uuid of the aggregate to be updated.
        :param aggregate: a json PATCH document to apply to this aggregate.
        """

        db_aggregate = objects.Aggregate.get(pecan.request.context,
                                             aggregate_uuid)

        try:
            aggregate = Aggregate(
                **api_utils.apply_jsonpatch(db_aggregate.as_dict(), patch))

        except api_utils.JSONPATCH_EXCEPTIONS as e:
            raise exception.PatchError(patch=patch, reason=e)

        # Check if this tries to change availability zone
        az_changed = False
        for patch_dict in patch:
            if patch_dict['path'] == '/metadata/availability_zone' \
                    and patch_dict['op'] != 'remove':
                az_changed = True
                break

        # Update only the fields that have changed
        for field in objects.Aggregate.fields:
            try:
                patch_val = getattr(aggregate, field)
            except AttributeError:
                # Ignore fields that aren't exposed in the API
                continue
            if patch_val == wtypes.Unset:
                patch_val = None
            if db_aggregate[field] != patch_val:
                db_aggregate[field] = patch_val

                if field == 'metadata' and az_changed:
                    if not patch_val['availability_zone']:
                        msg = _("Aggregate %s does not support empty named "
                                "availability zone") % aggregate.name
                        raise wsme.exc.ClientSideError(
                            msg, status_code=http_client.BAD_REQUEST)

                    # ensure it's safe to update availability_zone
                    aggregates = objects.AggregateList.get_by_metadata_key(
                        pecan.request.context, 'availability_zone')
                    nodes = pecan.request.engine_api.list_aggregate_nodes(
                        pecan.request.context, db_aggregate['uuid'])
                    filtered_aggs = []
                    for agg in aggregates:
                        agg_nodes = \
                            pecan.request.engine_api.list_aggregate_nodes(
                                pecan.request.context, agg.uuid)
                        for node in agg_nodes['nodes']:
                            if node in nodes['nodes']:
                                filtered_aggs.append(agg)
                                break

                    new_az = patch_val['availability_zone']
                    conflict_azs = [
                        agg.metadata['availability_zone']
                        for agg in filtered_aggs
                        if agg.metadata['availability_zone'] != new_az
                        and agg.uuid != db_aggregate['uuid']
                    ]
                    if conflict_azs:
                        msg = _("One or more nodes already in different "
                                "availability zone(s) %s") % conflict_azs
                        raise wsme.exc.ClientSideError(
                            msg, status_code=http_client.BAD_REQUEST)

        db_aggregate.save()

        return Aggregate.convert_with_links(db_aggregate)