Add all tenants support for checkpoints listing

Change-Id: Ic02a60a0eec1e7d3b0ca7b1a355a5d62d5c0046c
Implements: bp checkpoint-all-tenants
This commit is contained in:
jiaopengju 2018-11-18 19:46:47 +08:00
parent 0a756778ed
commit abab99c0eb
8 changed files with 134 additions and 25 deletions

View File

@ -311,7 +311,8 @@ class ProvidersController(wsgi.Controller):
if filters is None:
filters = {}
all_tenants = utils.get_bool_param(
'all_tenants', filters) and context.is_admin
try:
if limit is not None:
limit = int(limit)
@ -325,12 +326,16 @@ class ProvidersController(wsgi.Controller):
if filters:
LOG.debug("Searching by: %s.", six.text_type(filters))
if all_tenants:
del filters['all_tenants']
checkpoints = self.protection_api.list_checkpoints(
context, provider_id, marker, limit,
sort_keys=sort_keys,
sort_dirs=sort_dirs,
filters=filters,
offset=offset)
offset=offset,
all_tenants=all_tenants
)
LOG.info("Get all checkpoints completed successfully.")
return checkpoints

View File

@ -52,7 +52,7 @@ class API(base.Base):
)
def list_checkpoints(self, context, provider_id, marker, limit,
sort_keys, sort_dirs, filters, offset):
sort_keys, sort_dirs, filters, offset, all_tenants):
return self.protection_rpcapi.list_checkpoints(
context,
provider_id,
@ -60,7 +60,8 @@ class API(base.Base):
limit,
sort_keys,
sort_dirs,
filters
filters,
all_tenants
)
def list_protectable_types(self, context):

View File

@ -303,9 +303,49 @@ class CheckpointCollection(object):
self._checkpoints_section = bank.get_sub_section("/checkpoints")
self._indices_section = bank.get_sub_section("/indices")
@staticmethod
def _get_prefix_and_marker_by_provider(provider_id, project_id, marker,
marker_checkpoint, all_tenants):
if all_tenants:
prefix = "/by-provider/%s/" % provider_id
marker = "/%s/%s" % (
marker_checkpoint["project_id"], marker) if marker else marker
else:
prefix = "/by-provider/%s/%s/" % (provider_id, project_id)
marker = "/%s" % marker if marker else marker
return prefix, marker
@staticmethod
def _get_prefix_and_marker_by_plan(plan_id, project_id, marker,
marker_checkpoint, all_tenants):
if all_tenants:
prefix = "/by-plan/%s/" % plan_id
marker = "/%s/%s/%s" % (
marker_checkpoint["project_id"],
marker_checkpoint["created_at"], marker) if marker else marker
else:
prefix = "/by-plan/%s/%s/" % (plan_id, project_id)
marker = "/%s/%s" % (
marker_checkpoint["created_at"], marker) if marker else marker
return prefix, marker
@staticmethod
def _get_prefix_and_marker_by_date(project_id, marker, marker_checkpoint,
all_tenants):
prefix = "/by-date/"
if all_tenants:
marker = "/%s/%s/%s" % (
marker_checkpoint["created_at"],
marker_checkpoint["project_id"], marker) if marker else marker
else:
marker = "/%s/%s/%s" % (
marker_checkpoint["created_at"], project_id,
marker) if marker else marker
return prefix, marker
def list_ids(self, project_id, provider_id, limit=None, marker=None,
plan_id=None, start_date=None, end_date=None, sort_dir=None,
context=None):
context=None, all_tenants=False):
marker_checkpoint = None
if marker is not None:
checkpoint_section = self._checkpoints_section.get_sub_section(
@ -319,25 +359,22 @@ class CheckpointCollection(object):
end_date = timeutils.utcnow()
if plan_id is None and start_date is None:
prefix = "/by-provider/%s/%s/" % (provider_id, project_id)
if marker is not None:
marker = "/%s" % marker
prefix, marker = self._get_prefix_and_marker_by_provider(
provider_id, project_id, marker,
marker_checkpoint, all_tenants)
elif plan_id is not None:
prefix = "/by-plan/%s/%s/" % (plan_id, project_id)
if marker is not None:
date = marker_checkpoint["created_at"]
marker = "/%s/%s" % (date, marker)
prefix, marker = self._get_prefix_and_marker_by_plan(
plan_id, project_id, marker, marker_checkpoint, all_tenants)
else:
prefix = "/by-date/"
if marker is not None:
date = marker_checkpoint["created_at"]
marker = "/%s/%s/%s" % (date, project_id, marker)
prefix, marker = self._get_prefix_and_marker_by_date(
project_id, marker, marker_checkpoint, all_tenants)
return self._list_ids(project_id, prefix, limit, marker, start_date,
end_date, sort_dir, context=context)
end_date, sort_dir, context=context,
all_tenants=all_tenants)
def _list_ids(self, project_id, prefix, limit, marker, start_date,
end_date, sort_dir, context=None):
end_date, sort_dir, context=None, all_tenants=False):
if start_date is None:
return [key[key.find("@") + 1:]
for key in self._indices_section.list_objects(
@ -359,7 +396,8 @@ class CheckpointCollection(object):
key.split("/")[date_cursor], "%Y-%m-%d")
checkpoint_project_id = key.split("/")[project_id_cursor]
if start_date <= date <= end_date and (
checkpoint_project_id == project_id):
all_tenants or (
checkpoint_project_id == project_id)):
ids.append(key[key.find("@") + 1:])
if limit is not None and len(ids) == limit:
return ids

View File

@ -369,7 +369,8 @@ class ProtectionManager(manager.Manager):
exception.CheckpointNotFound,
exception.BankListObjectsFailed)
def list_checkpoints(self, context, provider_id, marker=None, limit=None,
sort_keys=None, sort_dirs=None, filters=None):
sort_keys=None, sort_dirs=None, filters=None,
all_tenants=False):
LOG.info("Starting list checkpoints. provider_id:%s", provider_id)
plan_id = filters.get("plan_id", None)
start_date = None
@ -380,13 +381,14 @@ class ProtectionManager(manager.Manager):
if filters.get("end_date", None):
end_date = datetime.strptime(
filters.get("end_date"), "%Y-%m-%d")
sort_dir = None if sort_dirs is None else sort_dirs[0]
provider = self.provider_registry.show_provider(provider_id)
project_id = context.project_id
checkpoint_ids = provider.list_checkpoints(
project_id, provider_id, limit=limit, marker=marker,
plan_id=plan_id, start_date=start_date, end_date=end_date,
sort_dir=sort_dir, context=context)
sort_dir=sort_dir, context=context, all_tenants=all_tenants)
checkpoints = []
for checkpoint_id in checkpoint_ids:
checkpoint = provider.get_checkpoint(checkpoint_id,

View File

@ -150,12 +150,14 @@ class PluggableProtectionProvider(object):
def list_checkpoints(self, project_id, provider_id, limit=None,
marker=None, plan_id=None, start_date=None,
end_date=None, sort_dir=None, context=None):
end_date=None, sort_dir=None, context=None,
all_tenants=False):
checkpoint_collection = self.get_checkpoint_collection()
return checkpoint_collection.list_ids(
project_id=project_id, provider_id=provider_id, limit=limit,
marker=marker, plan_id=plan_id, start_date=start_date,
end_date=end_date, sort_dir=sort_dir, context=context)
end_date=end_date, sort_dir=sort_dir, context=context,
all_tenants=all_tenants)
class ProviderRegistry(object):

View File

@ -92,7 +92,7 @@ class ProtectionAPI(object):
def list_checkpoints(self, ctxt, provider_id, marker=None,
limit=None, sort_keys=None,
sort_dirs=None, filters=None):
sort_dirs=None, filters=None, all_tenants=False):
cctxt = self.client.prepare(version='1.0')
return cctxt.call(
ctxt,
@ -102,7 +102,9 @@ class ProtectionAPI(object):
limit=limit,
sort_keys=sort_keys,
sort_dirs=sort_dirs,
filters=filters)
filters=filters,
all_tenants=all_tenants
)
def list_protectable_types(self, ctxt):
cctxt = self.client.prepare(version='1.0')

View File

@ -47,6 +47,23 @@ class CheckpointCollectionTest(base.TestCase):
self.assertEqual(set(collection.list_ids(
project_id=project_id, provider_id=provider_id)), result)
def test_list_checkpoints_with_all_tenants(self):
collection = self._create_test_collection()
plan_1 = fake_protection_plan()
plan_1["id"] = "fake_plan_id_1"
plan_1["project_id"] = "fake_project_id_1"
provider_id_1 = plan_1['provider_id']
checkpoints_plan_1 = {collection.create(plan_1).id for i in range(10)}
plan_2 = fake_protection_plan()
plan_2["id"] = "fake_plan_id_2"
plan_2["project_id"] = "fake_project_id_2"
checkpoints_plan_2 = {collection.create(plan_2).id for i in range(10)}
checkpoints_plan_1.update(checkpoints_plan_2)
self.assertEqual(set(collection.list_ids(
project_id="fake_project_id_1", provider_id=provider_id_1,
all_tenants=True)), checkpoints_plan_1)
def test_list_checkpoints_by_plan_id(self):
collection = self._create_test_collection()
plan_1 = fake_protection_plan()
@ -69,6 +86,21 @@ class CheckpointCollectionTest(base.TestCase):
project_id="fake_project_id_2", provider_id=provider_id_2,
plan_id="fake_plan_id_2")), checkpoints_plan_2)
def test_list_checkpoints_by_plan_with_all_tenants(self):
collection = self._create_test_collection()
plan_1 = fake_protection_plan()
plan_1["id"] = "fake_plan_id_1"
plan_1["project_id"] = "fake_project_id_1"
provider_id_1 = plan_1['provider_id']
checkpoints_plan_1 = {collection.create(plan_1).id for i in range(10)}
plan_1["project_id"] = "fake_project_id_2"
checkpoints_plan_2 = {collection.create(plan_1).id for i in range(10)}
checkpoints_plan_2.update(checkpoints_plan_1)
self.assertEqual(set(collection.list_ids(
project_id="fake_project_id_1", provider_id=provider_id_1,
plan_id='fake_plan_id_1',
all_tenants=True)), checkpoints_plan_2)
def test_list_checkpoints_by_plan_id_and_filter_by_start_date(self):
collection = self._create_test_collection()
date1 = datetime.strptime("2018-11-12", "%Y-%m-%d")
@ -135,6 +167,29 @@ class CheckpointCollectionTest(base.TestCase):
end_date=date2)),
checkpoints_date_2)
def test_list_checkpoints_by_date_with_all_tenants(self):
collection = self._create_test_collection()
date1 = datetime.strptime("2018-11-15", "%Y-%m-%d")
timeutils.utcnow = mock.MagicMock()
timeutils.utcnow.return_value = date1
plan_1 = fake_protection_plan()
plan_1["id"] = "fake_plan_id_1"
plan_1["project_id"] = "fake_project_id_1"
provider_id_1 = plan_1['provider_id']
checkpoints_1 = {collection.create(plan_1).id for i in range(10)}
date2 = datetime.strptime("2018-11-17", "%Y-%m-%d")
timeutils.utcnow = mock.MagicMock()
timeutils.utcnow.return_value = date2
plan_1["id"] = "fake_plan_id_2"
plan_1["project_id"] = "fake_project_id_2"
checkpoints_2 = {collection.create(plan_1).id for i in range(10)}
checkpoints_2.update(checkpoints_1)
self.assertEqual(set(collection.list_ids(
project_id="fake_project_id_1", provider_id=provider_id_1,
start_date=date1,
all_tenants=True)), checkpoints_2)
def test_list_checkpoints_by_date_with_marker(self):
collection = self._create_test_collection()
date = datetime.strptime("2018-11-12", "%Y-%m-%d")

View File

@ -0,0 +1,4 @@
---
features:
- |
Add support for listing checkpoints by admin with all_tenants.