Adding 'date' for trust_flush
This patch adds functionality to purge expired and soft-deleted trusts older than the given date. Change-Id: I0bd47e57f8650182e38b4f70e04cb53338fce474 Related-Bug: #1473292
This commit is contained in:
parent
f4e052b8bf
commit
7e42d333c7
@ -59,7 +59,19 @@ The delegation parameters are:
|
|||||||
Removing Expired Trusts
|
Removing Expired Trusts
|
||||||
===========================================================
|
===========================================================
|
||||||
|
|
||||||
In the SQL trust stores expired trusts are not automatically
|
In the SQL trust stores expired and soft deleted trusts, that are not
|
||||||
removed. These trusts can be removed with::
|
automatically removed. These trusts can be removed with::
|
||||||
|
|
||||||
$ keystone-manage trust_flush
|
$ keystone-manage trust_flush [options]
|
||||||
|
|
||||||
|
OPTIONS (optional):
|
||||||
|
|
||||||
|
--project-id <string>:
|
||||||
|
To purge trusts of given project-id.
|
||||||
|
--trustor-user-id <string>:
|
||||||
|
To purge trusts of given trustor-id.
|
||||||
|
--trustee-user-id <string>:
|
||||||
|
To purge trusts of given trustee-id.
|
||||||
|
--date <string>:
|
||||||
|
To purge trusts older than date. If no date is supplied
|
||||||
|
keystone-manage will use the system clock time at runtime.
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
from __future__ import absolute_import
|
from __future__ import absolute_import
|
||||||
from __future__ import print_function
|
from __future__ import print_function
|
||||||
|
|
||||||
|
import datetime
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
import uuid
|
import uuid
|
||||||
@ -685,24 +686,48 @@ class TrustFlush(BaseApp):
|
|||||||
parser = super(TrustFlush, cls).add_argument_parser(subparsers)
|
parser = super(TrustFlush, cls).add_argument_parser(subparsers)
|
||||||
|
|
||||||
parser.add_argument('--project-id', default=None,
|
parser.add_argument('--project-id', default=None,
|
||||||
help=('The id of the project of which the expired '
|
help=('The id of the project of which the '
|
||||||
|
'expired or non-expired soft-deleted '
|
||||||
'trusts is to be purged'))
|
'trusts is to be purged'))
|
||||||
parser.add_argument('--trustor-user-id', default=None,
|
parser.add_argument('--trustor-user-id', default=None,
|
||||||
help=('The id of the trustor of which the expired '
|
help=('The id of the trustor of which the '
|
||||||
|
'expired or non-expired soft-deleted '
|
||||||
'trusts is to be purged'))
|
'trusts is to be purged'))
|
||||||
parser.add_argument('--trustee-user-id', default=None,
|
parser.add_argument('--trustee-user-id', default=None,
|
||||||
help=('The id of the trustee of which the expired '
|
help=('The id of the trustee of which the '
|
||||||
|
'expired or non-expired soft-deleted '
|
||||||
'trusts is to be purged'))
|
'trusts is to be purged'))
|
||||||
|
parser.add_argument('--date', default=datetime.datetime.utcnow(),
|
||||||
|
help=('The date of which the expired or '
|
||||||
|
'non-expired soft-deleted trusts older '
|
||||||
|
'than that will be purged. The format of '
|
||||||
|
'the date to be "DD-MM-YYYY". If no date '
|
||||||
|
'is supplied keystone-manage will use the '
|
||||||
|
'system clock time at runtime'))
|
||||||
return parser
|
return parser
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def main(cls):
|
def main(cls):
|
||||||
drivers = backends.load_backends()
|
drivers = backends.load_backends()
|
||||||
trust_manager = drivers['trust_api']
|
trust_manager = drivers['trust_api']
|
||||||
|
if CONF.command.date:
|
||||||
|
if not isinstance(CONF.command.date, datetime.datetime):
|
||||||
|
try:
|
||||||
|
CONF.command.date = datetime.datetime.strptime(
|
||||||
|
CONF.command.date, '%d-%m-%Y')
|
||||||
|
except KeyError:
|
||||||
|
raise ValueError("'%s'Invalid input for date, should be "
|
||||||
|
"DD-MM-YYYY", CONF.command.date)
|
||||||
|
else:
|
||||||
|
LOG.info("No date is supplied, keystone-manage will use the "
|
||||||
|
"system clock time at runtime ")
|
||||||
|
|
||||||
trust_manager.flush_expired_and_soft_deleted_trusts(
|
trust_manager.flush_expired_and_soft_deleted_trusts(
|
||||||
project_id=CONF.command.project_id,
|
project_id=CONF.command.project_id,
|
||||||
trustor_user_id=CONF.command.trustor_user_id,
|
trustor_user_id=CONF.command.trustor_user_id,
|
||||||
trustee_user_id=CONF.command.trustee_user_id)
|
trustee_user_id=CONF.command.trustee_user_id,
|
||||||
|
date=CONF.command.date
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class MappingPurge(BaseApp):
|
class MappingPurge(BaseApp):
|
||||||
|
@ -1652,6 +1652,7 @@ class TestTrustFlush(unit.SQLDriverOverrides, unit.BaseTestCase):
|
|||||||
self.project_id = parent.command_project_id
|
self.project_id = parent.command_project_id
|
||||||
self.trustor_user_id = parent.command_trustor_user_id
|
self.trustor_user_id = parent.command_trustor_user_id
|
||||||
self.trustee_user_id = parent.command_trustee_user_id
|
self.trustee_user_id = parent.command_trustee_user_id
|
||||||
|
self.date = parent.command_date
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
# Set up preset cli options and a parser
|
# Set up preset cli options and a parser
|
||||||
@ -1674,6 +1675,7 @@ class TestTrustFlush(unit.SQLDriverOverrides, unit.BaseTestCase):
|
|||||||
self.command_project_id = None
|
self.command_project_id = None
|
||||||
self.command_trustor_user_id = None
|
self.command_trustor_user_id = None
|
||||||
self.command_trustee_user_id = None
|
self.command_trustee_user_id = None
|
||||||
|
self.command_date = datetime.datetime.utcnow()
|
||||||
self.useFixture(fixtures.MockPatchObject(
|
self.useFixture(fixtures.MockPatchObject(
|
||||||
CONF, 'command', self.FakeConfCommand(self)))
|
CONF, 'command', self.FakeConfCommand(self)))
|
||||||
|
|
||||||
@ -1687,6 +1689,26 @@ class TestTrustFlush(unit.SQLDriverOverrides, unit.BaseTestCase):
|
|||||||
trust = cli.TrustFlush()
|
trust = cli.TrustFlush()
|
||||||
trust.main()
|
trust.main()
|
||||||
|
|
||||||
|
def test_trust_flush_with_invalid_date(self):
|
||||||
|
self.command_project_id = None
|
||||||
|
self.command_trustor_user_id = None
|
||||||
|
self.command_trustee_user_id = None
|
||||||
|
self.command_date = '4/10/92'
|
||||||
|
self.useFixture(fixtures.MockPatchObject(
|
||||||
|
CONF, 'command', self.FakeConfCommand(self)))
|
||||||
|
|
||||||
|
def fake_load_backends():
|
||||||
|
return dict(
|
||||||
|
trust_api=keystone.trust.core.Manager())
|
||||||
|
|
||||||
|
self.useFixture(fixtures.MockPatch(
|
||||||
|
'keystone.server.backends.load_backends',
|
||||||
|
side_effect=fake_load_backends))
|
||||||
|
# Clear backend dependencies, since cli loads these manually
|
||||||
|
provider_api.ProviderAPIs._clear_registry_instances()
|
||||||
|
trust = cli.TrustFlush()
|
||||||
|
self.assertRaises(ValueError, trust.main)
|
||||||
|
|
||||||
|
|
||||||
class TestMappingEngineTester(unit.BaseTestCase):
|
class TestMappingEngineTester(unit.BaseTestCase):
|
||||||
|
|
||||||
|
@ -206,7 +206,8 @@ class TrustTests(object):
|
|||||||
trust_ref2, roles)
|
trust_ref2, roles)
|
||||||
self.assertIsNotNone(trust_data)
|
self.assertIsNotNone(trust_data)
|
||||||
|
|
||||||
PROVIDERS.trust_api.flush_expired_and_soft_deleted_trusts()
|
PROVIDERS.trust_api.flush_expired_and_soft_deleted_trusts(
|
||||||
|
date=datetime.datetime.utcnow())
|
||||||
trusts = self.trust_api.list_trusts()
|
trusts = self.trust_api.list_trusts()
|
||||||
self.assertEqual(len(trusts), 1)
|
self.assertEqual(len(trusts), 1)
|
||||||
self.assertEqual(trust_ref2['id'], trusts[0]['id'])
|
self.assertEqual(trust_ref2['id'], trusts[0]['id'])
|
||||||
@ -236,7 +237,8 @@ class TrustTests(object):
|
|||||||
PROVIDERS.trust_api.flush_expired_and_soft_deleted_trusts(
|
PROVIDERS.trust_api.flush_expired_and_soft_deleted_trusts(
|
||||||
project_id=self.tenant_bar['id'],
|
project_id=self.tenant_bar['id'],
|
||||||
trustor_user_id=self.user_foo['id'],
|
trustor_user_id=self.user_foo['id'],
|
||||||
trustee_user_id=self.user_two['id'])
|
trustee_user_id=self.user_two['id'],
|
||||||
|
date=datetime.datetime.utcnow())
|
||||||
trusts = self.trust_api.list_trusts()
|
trusts = self.trust_api.list_trusts()
|
||||||
self.assertEqual(len(trusts), 1)
|
self.assertEqual(len(trusts), 1)
|
||||||
self.assertEqual(trust_ref1['id'], trusts[0]['id'])
|
self.assertEqual(trust_ref1['id'], trusts[0]['id'])
|
||||||
@ -265,7 +267,8 @@ class TrustTests(object):
|
|||||||
|
|
||||||
PROVIDERS.trust_api.flush_expired_and_soft_deleted_trusts(
|
PROVIDERS.trust_api.flush_expired_and_soft_deleted_trusts(
|
||||||
trustor_user_id=self.user_foo['id'],
|
trustor_user_id=self.user_foo['id'],
|
||||||
trustee_user_id=self.user_two['id'])
|
trustee_user_id=self.user_two['id'],
|
||||||
|
date=datetime.datetime.utcnow())
|
||||||
trusts = self.trust_api.list_trusts()
|
trusts = self.trust_api.list_trusts()
|
||||||
self.assertEqual(len(trusts), 1)
|
self.assertEqual(len(trusts), 1)
|
||||||
self.assertEqual(trust_ref2['id'], trusts[0]['id'])
|
self.assertEqual(trust_ref2['id'], trusts[0]['id'])
|
||||||
@ -294,7 +297,8 @@ class TrustTests(object):
|
|||||||
|
|
||||||
PROVIDERS.trust_api.flush_expired_and_soft_deleted_trusts(
|
PROVIDERS.trust_api.flush_expired_and_soft_deleted_trusts(
|
||||||
project_id=self.tenant_bar['id'],
|
project_id=self.tenant_bar['id'],
|
||||||
trustee_user_id=self.user_two['id'])
|
trustee_user_id=self.user_two['id'],
|
||||||
|
date=datetime.datetime.utcnow())
|
||||||
trusts = self.trust_api.list_trusts()
|
trusts = self.trust_api.list_trusts()
|
||||||
self.assertEqual(len(trusts), 1)
|
self.assertEqual(len(trusts), 1)
|
||||||
self.assertEqual(trust_ref2['id'], trusts[0]['id'])
|
self.assertEqual(trust_ref2['id'], trusts[0]['id'])
|
||||||
@ -323,7 +327,8 @@ class TrustTests(object):
|
|||||||
|
|
||||||
PROVIDERS.trust_api.flush_expired_and_soft_deleted_trusts(
|
PROVIDERS.trust_api.flush_expired_and_soft_deleted_trusts(
|
||||||
project_id=self.tenant_bar['id'],
|
project_id=self.tenant_bar['id'],
|
||||||
trustor_user_id=self.user_foo['id'])
|
trustor_user_id=self.user_foo['id'],
|
||||||
|
date=datetime.datetime.utcnow())
|
||||||
trusts = self.trust_api.list_trusts()
|
trusts = self.trust_api.list_trusts()
|
||||||
self.assertEqual(len(trusts), 1)
|
self.assertEqual(len(trusts), 1)
|
||||||
self.assertEqual(trust_ref2['id'], trusts[0]['id'])
|
self.assertEqual(trust_ref2['id'], trusts[0]['id'])
|
||||||
@ -351,7 +356,8 @@ class TrustTests(object):
|
|||||||
self.assertIsNotNone(trust_data)
|
self.assertIsNotNone(trust_data)
|
||||||
|
|
||||||
PROVIDERS.trust_api.flush_expired_and_soft_deleted_trusts(
|
PROVIDERS.trust_api.flush_expired_and_soft_deleted_trusts(
|
||||||
project_id=self.tenant_bar['id'])
|
project_id=self.tenant_bar['id'],
|
||||||
|
date=datetime.datetime.utcnow())
|
||||||
trusts = self.trust_api.list_trusts()
|
trusts = self.trust_api.list_trusts()
|
||||||
self.assertEqual(len(trusts), 1)
|
self.assertEqual(len(trusts), 1)
|
||||||
self.assertEqual(trust_ref2['id'], trusts[0]['id'])
|
self.assertEqual(trust_ref2['id'], trusts[0]['id'])
|
||||||
@ -378,7 +384,8 @@ class TrustTests(object):
|
|||||||
trust_ref2, roles)
|
trust_ref2, roles)
|
||||||
self.assertIsNotNone(trust_data)
|
self.assertIsNotNone(trust_data)
|
||||||
PROVIDERS.trust_api.flush_expired_and_soft_deleted_trusts(
|
PROVIDERS.trust_api.flush_expired_and_soft_deleted_trusts(
|
||||||
trustee_user_id=self.user_two['id'])
|
trustee_user_id=self.user_two['id'],
|
||||||
|
date=datetime.datetime.utcnow())
|
||||||
trusts = self.trust_api.list_trusts()
|
trusts = self.trust_api.list_trusts()
|
||||||
self.assertEqual(len(trusts), 1)
|
self.assertEqual(len(trusts), 1)
|
||||||
self.assertEqual(trust_ref2['id'], trusts[0]['id'])
|
self.assertEqual(trust_ref2['id'], trusts[0]['id'])
|
||||||
@ -406,7 +413,8 @@ class TrustTests(object):
|
|||||||
self.assertIsNotNone(trust_data)
|
self.assertIsNotNone(trust_data)
|
||||||
|
|
||||||
PROVIDERS.trust_api.flush_expired_and_soft_deleted_trusts(
|
PROVIDERS.trust_api.flush_expired_and_soft_deleted_trusts(
|
||||||
trustor_user_id=self.user_foo['id'])
|
trustor_user_id=self.user_foo['id'],
|
||||||
|
date=datetime.datetime.utcnow())
|
||||||
trusts = self.trust_api.list_trusts()
|
trusts = self.trust_api.list_trusts()
|
||||||
self.assertEqual(len(trusts), 1)
|
self.assertEqual(len(trusts), 1)
|
||||||
self.assertEqual(trust_ref2['id'], trusts[0]['id'])
|
self.assertEqual(trust_ref2['id'], trusts[0]['id'])
|
||||||
@ -434,7 +442,8 @@ class TrustTests(object):
|
|||||||
self.assertIsNotNone(trust_data)
|
self.assertIsNotNone(trust_data)
|
||||||
PROVIDERS.trust_api.delete_trust(trust_ref2['id'])
|
PROVIDERS.trust_api.delete_trust(trust_ref2['id'])
|
||||||
|
|
||||||
PROVIDERS.trust_api.flush_expired_and_soft_deleted_trusts()
|
PROVIDERS.trust_api.flush_expired_and_soft_deleted_trusts(
|
||||||
|
date=datetime.datetime.utcnow())
|
||||||
trusts = self.trust_api.list_trusts()
|
trusts = self.trust_api.list_trusts()
|
||||||
self.assertEqual(len(trusts), 1)
|
self.assertEqual(len(trusts), 1)
|
||||||
self.assertEqual(trust_ref1['id'], trusts[0]['id'])
|
self.assertEqual(trust_ref1['id'], trusts[0]['id'])
|
||||||
@ -469,6 +478,44 @@ class TrustTests(object):
|
|||||||
trust_ref3, roles)
|
trust_ref3, roles)
|
||||||
self.assertIsNotNone(trust_data)
|
self.assertIsNotNone(trust_data)
|
||||||
|
|
||||||
PROVIDERS.trust_api.flush_expired_and_soft_deleted_trusts()
|
PROVIDERS.trust_api.flush_expired_and_soft_deleted_trusts(
|
||||||
|
date=datetime.datetime.utcnow())
|
||||||
trusts = self.trust_api.list_trusts()
|
trusts = self.trust_api.list_trusts()
|
||||||
self.assertEqual(len(trusts), 2)
|
self.assertEqual(len(trusts), 2)
|
||||||
|
|
||||||
|
def test_flush_expired_trusts_with_date(self):
|
||||||
|
roles = [{"id": "member"},
|
||||||
|
{"id": "other"},
|
||||||
|
{"id": "browser"}]
|
||||||
|
trust_ref1 = core.new_trust_ref(
|
||||||
|
self.user_foo['id'], self.user_two['id'],
|
||||||
|
project_id=self.tenant_bar['id'])
|
||||||
|
trust_ref1['expires_at'] = \
|
||||||
|
timeutils.utcnow() + datetime.timedelta(minutes=10)
|
||||||
|
trust_ref2 = core.new_trust_ref(
|
||||||
|
self.user_two['id'], self.user_two['id'],
|
||||||
|
project_id=self.tenant_bar['id'])
|
||||||
|
trust_ref2['expires_at'] = \
|
||||||
|
timeutils.utcnow() + datetime.timedelta(minutes=30)
|
||||||
|
trust_ref3 = core.new_trust_ref(
|
||||||
|
self.user_two['id'], self.user_foo['id'],
|
||||||
|
project_id=self.tenant_bar['id'])
|
||||||
|
trust_ref3['expires_at'] = \
|
||||||
|
timeutils.utcnow() - datetime.timedelta(minutes=30)
|
||||||
|
|
||||||
|
trust_data = PROVIDERS.trust_api.create_trust(trust_ref1['id'],
|
||||||
|
trust_ref1, roles)
|
||||||
|
self.assertIsNotNone(trust_data)
|
||||||
|
trust_data = PROVIDERS.trust_api.create_trust(trust_ref2['id'],
|
||||||
|
trust_ref2, roles)
|
||||||
|
self.assertIsNotNone(trust_data)
|
||||||
|
trust_data = PROVIDERS.trust_api.create_trust(trust_ref3['id'],
|
||||||
|
trust_ref3, roles)
|
||||||
|
self.assertIsNotNone(trust_data)
|
||||||
|
fake_date = timeutils.utcnow() + datetime.timedelta(minutes=15)
|
||||||
|
PROVIDERS.trust_api.flush_expired_and_soft_deleted_trusts(
|
||||||
|
date=fake_date
|
||||||
|
)
|
||||||
|
trusts = self.trust_api.list_trusts()
|
||||||
|
self.assertEqual(len(trusts), 1)
|
||||||
|
self.assertEqual(trust_ref2['id'], trusts[0]['id'])
|
||||||
|
@ -193,15 +193,15 @@ class Trust(base.TrustDriverBase):
|
|||||||
|
|
||||||
def flush_expired_and_soft_deleted_trusts(self, project_id=None,
|
def flush_expired_and_soft_deleted_trusts(self, project_id=None,
|
||||||
trustor_user_id=None,
|
trustor_user_id=None,
|
||||||
trustee_user_id=None):
|
trustee_user_id=None,
|
||||||
|
date=None):
|
||||||
with sql.session_for_write() as session:
|
with sql.session_for_write() as session:
|
||||||
query = session.query(TrustModel)
|
query = session.query(TrustModel)
|
||||||
query = query.\
|
query = query.\
|
||||||
filter(sqlalchemy.or_(TrustModel.deleted_at.isnot(None),
|
filter(sqlalchemy.or_(TrustModel.deleted_at.isnot(None),
|
||||||
sqlalchemy.and_(
|
sqlalchemy.and_(
|
||||||
TrustModel.expires_at.isnot(None),
|
TrustModel.expires_at.isnot(None),
|
||||||
TrustModel.expires_at <
|
TrustModel.expires_at < date)))
|
||||||
timeutils.utcnow())))
|
|
||||||
if project_id:
|
if project_id:
|
||||||
query = query.filter_by(project_id=project_id)
|
query = query.filter_by(project_id=project_id)
|
||||||
if trustor_user_id:
|
if trustor_user_id:
|
||||||
|
@ -11,11 +11,13 @@ feature:
|
|||||||
|
|
||||||
$ keystone-manage trust-flush [Options]
|
$ keystone-manage trust-flush [Options]
|
||||||
|
|
||||||
Options:
|
Options (optional):
|
||||||
|
|
||||||
project-id <string>: To purge trusts of given project-id.
|
--project-id <string>: To purge trusts of given project-id.
|
||||||
trustor-user-id <string>: To purge trusts of given trustor-id.
|
--trustor-user-id <string>: To purge trusts of given trustor-id.
|
||||||
trustee-user-id <string>: To purge trusts of given trustee-id.
|
--trustee-user-id <string>: To purge trusts of given trustee-id.
|
||||||
|
--date <string>: To purge trusts older than date. It will purge trusts older than
|
||||||
|
current if date not given.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user