def finish_deployment_modification(self, modification_id):
        modification = self.sm.get_deployment_modification(modification_id)

        if modification.status in models.DeploymentModification.END_STATES:
            raise manager_exceptions.DeploymentModificationAlreadyEndedError(
                'Cannot finish deployment modification: {0}. It is already in'
                ' {1} status.'.format(modification_id, modification.status))

        modified_nodes = modification.modified_nodes
        for node_id, modified_node in modified_nodes.items():
            self.sm.update_node(modification.deployment_id,
                                node_id,
                                number_of_instances=modified_node['instances'])
        node_instances = modification.node_instances
        for node_instance in node_instances['removed_and_related']:
            if node_instance.get('modification') == 'removed':
                self.sm.delete_node_instance(node_instance['id'])
            else:
                removed_relationship_target_ids = set([
                    rel['target_id'] for rel in node_instance['relationships']
                ])
                current = self.sm.get_node_instance(node_instance['id'])
                new_relationships = [
                    rel for rel in current.relationships
                    if rel['target_id'] not in removed_relationship_target_ids
                ]
                self.sm.update_node_instance(
                    models.DeploymentNodeInstance(
                        id=node_instance['id'],
                        relationships=new_relationships,
                        version=current.version,
                        node_id=None,
                        host_id=None,
                        deployment_id=None,
                        state=None,
                        runtime_properties=None))

        now = str(datetime.now())
        self.sm.update_deployment_modification(
            models.DeploymentModification(
                id=modification_id,
                status=models.DeploymentModification.FINISHED,
                ended_at=now,
                created_at=None,
                deployment_id=None,
                modified_nodes=None,
                node_instances=None,
                context=None))

        return models.DeploymentModification(
            id=modification_id,
            status=models.DeploymentModification.FINISHED,
            ended_at=None,
            created_at=None,
            deployment_id=None,
            modified_nodes=None,
            node_instances=None,
            context=None)
    def rollback_deployment_modification(self, modification_id):
        modification = self.sm.get_deployment_modification(modification_id)

        if modification.status in models.DeploymentModification.END_STATES:
            raise manager_exceptions.DeploymentModificationAlreadyEndedError(
                'Cannot rollback deployment modification: {0}. It is already '
                'in {1} status.'.format(modification_id, modification.status))
        deplyment_id_filter = self.create_filters_dict(
            deployment_id=modification.deployment_id)
        node_instances = self.sm.get_node_instances(
            filters=deplyment_id_filter).items
        modification.node_instances['before_rollback'] = [
            instance.to_dict() for instance in node_instances
        ]
        for instance in node_instances:
            self.sm.delete_node_instance(instance.id)
        for instance in modification.node_instances['before_modification']:
            self.sm.put_node_instance(
                models.DeploymentNodeInstance(**instance))
        nodes_num_instances = {
            node.id: node
            for node in self.sm.get_nodes(
                filters=deplyment_id_filter,
                include=['id', 'number_of_instances']).items
        }
        for node_id, modified_node in modification.modified_nodes.items():
            self.sm.update_node(
                modification.deployment_id,
                node_id,
                planned_number_of_instances=nodes_num_instances[node_id].
                number_of_instances)

        now = str(datetime.now())
        self.sm.update_deployment_modification(
            models.DeploymentModification(
                id=modification_id,
                status=models.DeploymentModification.ROLLEDBACK,
                ended_at=now,
                created_at=None,
                deployment_id=None,
                modified_nodes=None,
                node_instances=modification.node_instances,
                context=None))

        return models.DeploymentModification(
            id=modification_id,
            status=models.DeploymentModification.ROLLEDBACK,
            ended_at=None,
            created_at=None,
            deployment_id=None,
            modified_nodes=None,
            node_instances=None,
            context=None)