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)
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())
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)
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)