Add ability to see deleted and active records.
Fixes bug #900564 Changes `Context`.`read_deleted` from a bool to an enum string with values "yes" (can read deleted records), "no" (cannot read deleted records), and "only" (can only see deleted records, for backwards compatibility). Change-Id: Ic81db3664c33f23f751b73973782efb06fce90d9
This commit is contained in:
		@@ -1379,7 +1379,7 @@ class VsaCommands(object):
 | 
			
		||||
                raise
 | 
			
		||||
 | 
			
		||||
        is_admin = self.manager.is_admin(user_id)
 | 
			
		||||
        ctxt = context.RequestContext(user_id, project_id, is_admin)
 | 
			
		||||
        ctxt = context.RequestContext(user_id, project_id, is_admin=is_admin)
 | 
			
		||||
        if not is_admin and \
 | 
			
		||||
           not self.manager.is_project_member(user_id, project_id):
 | 
			
		||||
            msg = _("%(user_id)s must be an admin or a "
 | 
			
		||||
 
 | 
			
		||||
@@ -19,6 +19,7 @@
 | 
			
		||||
 | 
			
		||||
"""RequestContext: context for requests that persist through all of nova."""
 | 
			
		||||
 | 
			
		||||
import copy
 | 
			
		||||
import uuid
 | 
			
		||||
 | 
			
		||||
from nova import local
 | 
			
		||||
@@ -32,9 +33,14 @@ class RequestContext(object):
 | 
			
		||||
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    def __init__(self, user_id, project_id, is_admin=None, read_deleted=False,
 | 
			
		||||
    def __init__(self, user_id, project_id, is_admin=None, read_deleted="no",
 | 
			
		||||
                 roles=None, remote_address=None, timestamp=None,
 | 
			
		||||
                 request_id=None, auth_token=None, strategy='noauth'):
 | 
			
		||||
        """
 | 
			
		||||
        :param read_deleted: 'no' indicates deleted records are hidden, 'yes'
 | 
			
		||||
            indicates deleted records are visible, 'only' indicates that
 | 
			
		||||
            *only* deleted records are visible.
 | 
			
		||||
        """
 | 
			
		||||
        self.user_id = user_id
 | 
			
		||||
        self.project_id = project_id
 | 
			
		||||
        self.roles = roles or []
 | 
			
		||||
@@ -73,18 +79,17 @@ class RequestContext(object):
 | 
			
		||||
 | 
			
		||||
    def elevated(self, read_deleted=None):
 | 
			
		||||
        """Return a version of this context with admin flag set."""
 | 
			
		||||
        rd = self.read_deleted if read_deleted is None else read_deleted
 | 
			
		||||
        return RequestContext(user_id=self.user_id,
 | 
			
		||||
                              project_id=self.project_id,
 | 
			
		||||
                              is_admin=True,
 | 
			
		||||
                              read_deleted=rd,
 | 
			
		||||
                              roles=self.roles,
 | 
			
		||||
                              remote_address=self.remote_address,
 | 
			
		||||
                              timestamp=self.timestamp,
 | 
			
		||||
                              request_id=self.request_id,
 | 
			
		||||
                              auth_token=self.auth_token,
 | 
			
		||||
                              strategy=self.strategy)
 | 
			
		||||
        context = copy.copy(self)
 | 
			
		||||
        context.is_admin = True
 | 
			
		||||
 | 
			
		||||
        if read_deleted is not None:
 | 
			
		||||
            context.read_deleted = read_deleted
 | 
			
		||||
 | 
			
		||||
        return context
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def get_admin_context(read_deleted=False):
 | 
			
		||||
    return RequestContext(None, None, True, read_deleted)
 | 
			
		||||
def get_admin_context(read_deleted="no"):
 | 
			
		||||
    return RequestContext(user_id=None,
 | 
			
		||||
                          project_id=None,
 | 
			
		||||
                          is_admin=True,
 | 
			
		||||
                          read_deleted=read_deleted)
 | 
			
		||||
 
 | 
			
		||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -106,7 +106,7 @@ class CloudTestCase(test.TestCase):
 | 
			
		||||
        self.project_id = 'fake'
 | 
			
		||||
        self.context = context.RequestContext(self.user_id,
 | 
			
		||||
                                              self.project_id,
 | 
			
		||||
                                              True)
 | 
			
		||||
                                              is_admin=True)
 | 
			
		||||
 | 
			
		||||
        def fake_show(meh, context, id):
 | 
			
		||||
            return {'id': id,
 | 
			
		||||
@@ -1564,12 +1564,12 @@ class CloudTestCase(test.TestCase):
 | 
			
		||||
 | 
			
		||||
        self.cloud.terminate_instances(self.context, [ec2_instance_id])
 | 
			
		||||
 | 
			
		||||
        admin_ctxt = context.get_admin_context(read_deleted=False)
 | 
			
		||||
        admin_ctxt = context.get_admin_context(read_deleted="no")
 | 
			
		||||
        vol = db.volume_get(admin_ctxt, vol1['id'])
 | 
			
		||||
        self.assertFalse(vol['deleted'])
 | 
			
		||||
        db.volume_destroy(self.context, vol1['id'])
 | 
			
		||||
 | 
			
		||||
        admin_ctxt = context.get_admin_context(read_deleted=True)
 | 
			
		||||
        admin_ctxt = context.get_admin_context(read_deleted="only")
 | 
			
		||||
        vol = db.volume_get(admin_ctxt, vol2['id'])
 | 
			
		||||
        self.assertTrue(vol['deleted'])
 | 
			
		||||
 | 
			
		||||
@@ -1689,13 +1689,13 @@ class CloudTestCase(test.TestCase):
 | 
			
		||||
 | 
			
		||||
        self.cloud.terminate_instances(self.context, [ec2_instance_id])
 | 
			
		||||
 | 
			
		||||
        admin_ctxt = context.get_admin_context(read_deleted=False)
 | 
			
		||||
        admin_ctxt = context.get_admin_context(read_deleted="no")
 | 
			
		||||
        vol = db.volume_get(admin_ctxt, vol1_id)
 | 
			
		||||
        self._assert_volume_detached(vol)
 | 
			
		||||
        self.assertFalse(vol['deleted'])
 | 
			
		||||
        db.volume_destroy(self.context, vol1_id)
 | 
			
		||||
 | 
			
		||||
        admin_ctxt = context.get_admin_context(read_deleted=True)
 | 
			
		||||
        admin_ctxt = context.get_admin_context(read_deleted="only")
 | 
			
		||||
        vol = db.volume_get(admin_ctxt, vol2_id)
 | 
			
		||||
        self.assertTrue(vol['deleted'])
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -312,7 +312,7 @@ class SimpleDriverTestCase(test.TestCase):
 | 
			
		||||
                                   FLAGS.compute_manager)
 | 
			
		||||
        compute1.start()
 | 
			
		||||
        _create_instance()
 | 
			
		||||
        ctxt = context.RequestContext('fake', 'fake', False)
 | 
			
		||||
        ctxt = context.RequestContext('fake', 'fake', is_admin=False)
 | 
			
		||||
        global instance_uuids
 | 
			
		||||
        instance_uuids = []
 | 
			
		||||
        self.stubs.Set(SimpleScheduler,
 | 
			
		||||
 
 | 
			
		||||
@@ -52,7 +52,7 @@ class AdminApiTestCase(test.TestCase):
 | 
			
		||||
        self.project_id = 'admin'
 | 
			
		||||
        self.context = context.RequestContext(self.user_id,
 | 
			
		||||
                                              self.project_id,
 | 
			
		||||
                                              True)
 | 
			
		||||
                                              is_admin=True)
 | 
			
		||||
 | 
			
		||||
        def fake_show(meh, context, id):
 | 
			
		||||
            return {'id': 1, 'properties': {'kernel_id': 1, 'ramdisk_id': 1,
 | 
			
		||||
 
 | 
			
		||||
@@ -222,7 +222,7 @@ class ComputeTestCase(BaseTestCase):
 | 
			
		||||
        self.assertEqual(instance['deleted_at'], None)
 | 
			
		||||
        terminate = utils.utcnow()
 | 
			
		||||
        self.compute.terminate_instance(self.context, instance['uuid'])
 | 
			
		||||
        context = self.context.elevated(True)
 | 
			
		||||
        context = self.context.elevated(read_deleted="only")
 | 
			
		||||
        instance = db.instance_get_by_uuid(context, instance['uuid'])
 | 
			
		||||
        self.assert_(instance['launched_at'] < terminate)
 | 
			
		||||
        self.assert_(instance['deleted_at'] > terminate)
 | 
			
		||||
@@ -674,7 +674,7 @@ class ComputeTestCase(BaseTestCase):
 | 
			
		||||
        instance_uuid = instance['uuid']
 | 
			
		||||
        self.compute.run_instance(self.context, instance_uuid)
 | 
			
		||||
 | 
			
		||||
        non_admin_context = context.RequestContext(None, None, False, False)
 | 
			
		||||
        non_admin_context = context.RequestContext(None, None, is_admin=False)
 | 
			
		||||
 | 
			
		||||
        # decorator should return False (fail) with locked nonadmin context
 | 
			
		||||
        self.compute.lock_instance(self.context, instance_uuid)
 | 
			
		||||
@@ -1230,8 +1230,9 @@ class ComputeAPITestCase(BaseTestCase):
 | 
			
		||||
 | 
			
		||||
        try:
 | 
			
		||||
            db.security_group_destroy(self.context, group['id'])
 | 
			
		||||
            group = db.security_group_get(context.get_admin_context(
 | 
			
		||||
                                          read_deleted=True), group['id'])
 | 
			
		||||
            admin_deleted_context = context.get_admin_context(
 | 
			
		||||
                    read_deleted="only")
 | 
			
		||||
            group = db.security_group_get(admin_deleted_context, group['id'])
 | 
			
		||||
            self.assert_(len(group.instances) == 0)
 | 
			
		||||
        finally:
 | 
			
		||||
            db.instance_destroy(self.context, ref[0]['id'])
 | 
			
		||||
 
 | 
			
		||||
@@ -53,7 +53,7 @@ class QuotaTestCase(test.TestCase):
 | 
			
		||||
        self.project_id = 'admin'
 | 
			
		||||
        self.context = context.RequestContext(self.user_id,
 | 
			
		||||
                                              self.project_id,
 | 
			
		||||
                                              True)
 | 
			
		||||
                                              is_admin=True)
 | 
			
		||||
        orig_rpc_call = rpc.call
 | 
			
		||||
 | 
			
		||||
        def rpc_call_wrapper(context, topic, msg):
 | 
			
		||||
 
 | 
			
		||||
@@ -40,7 +40,7 @@ class VMWareAPIVMTestCase(test.TestCase):
 | 
			
		||||
 | 
			
		||||
    def setUp(self):
 | 
			
		||||
        super(VMWareAPIVMTestCase, self).setUp()
 | 
			
		||||
        self.context = context.RequestContext('fake', 'fake', False)
 | 
			
		||||
        self.context = context.RequestContext('fake', 'fake', is_admin=False)
 | 
			
		||||
        self.flags(vmwareapi_host_ip='test_url',
 | 
			
		||||
                   vmwareapi_host_username='test_username',
 | 
			
		||||
                   vmwareapi_host_password='test_pass')
 | 
			
		||||
 
 | 
			
		||||
@@ -129,8 +129,7 @@ def get_instance_id_from_name_label(name_label, template):
 | 
			
		||||
 | 
			
		||||
def find_orphaned_instances(session, verbose=False):
 | 
			
		||||
    """Find and return a list of orphaned instances."""
 | 
			
		||||
    ctxt = context.get_admin_context()
 | 
			
		||||
    ctxt.read_deleted = True
 | 
			
		||||
    ctxt = context.get_admin_context(read_deleted="only")
 | 
			
		||||
 | 
			
		||||
    orphaned_instances = []
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user