Add client list filter functionality

Exposes the secret_type, created, updated, expiration, and sort as
filters for listing secrets.

Change-Id: I583f27f91cb3c6bdb23438dff6b539407b4005ed
Depends-On: I95b5390ef24a754f66ccdb9ccde34cd0820b02fd
This commit is contained in:
Kaitlin Farr 2016-11-11 16:45:32 -05:00
parent ab2684f5d0
commit 8254828e64
2 changed files with 211 additions and 2 deletions

View File

@ -537,19 +537,37 @@ class SecretManager(base.BaseEntityManager):
raise ValueError('secret_ref is required.')
self._api.delete(secret_ref)
def list(self, limit=10, offset=0, name=None, algorithm=None,
mode=None, bits=0):
def list(self, limit=10, offset=0, name=None, algorithm=None, mode=None,
bits=0, secret_type=None, created=None, updated=None,
expiration=None, sort=None):
"""List Secrets for the project
This method uses the limit and offset parameters for paging,
and also supports filtering.
The time filters (created, updated, and expiration) are expected to
be an ISO 8601 formatted string, which can be prefixed with comparison
operators: 'gt:' (greater-than), 'gte:' (greater-than-or-equal), 'lt:'
(less-than), or 'lte': (less-than-or-equal).
:param limit: Max number of secrets returned
:param offset: Offset secrets to begin list
:param name: Name filter for the list
:param algorithm: Algorithm filter for the list
:param mode: Mode filter for the list
:param bits: Bits filter for the list
:param secret_type: Secret type filter for the list
:param created: Created time filter for the list, an ISO 8601 format
string, optionally prefixed with 'gt:', 'gte:', 'lt:', or 'lte:'
:param updated: Updated time filter for the list, an ISO 8601 format
string, optionally prefixed with 'gt:', 'gte:', 'lt:', or 'lte:'
:param expiration: Expiration time filter for the list, an ISO 8601
format string, optionally prefixed with 'gt:', 'gte:', 'lt:',
or 'lte:'
:param sort: Determines the sorted order of the returned list, a
string of comma-separated sort keys ('created', 'expiration',
'mode', 'name', 'secret_type', 'status', or 'updated') with a
direction appended (':asc' or ':desc') to each key
:returns: list of Secret objects that satisfy the provided filter
criteria.
:rtype: list
@ -568,6 +586,16 @@ class SecretManager(base.BaseEntityManager):
params['mode'] = mode
if bits > 0:
params['bits'] = bits
if secret_type:
params['secret_type'] = secret_type
if created:
params['created'] = created
if updated:
params['updated'] = updated
if expiration:
params['expiration'] = expiration
if sort:
params['sort'] = sort
response = self._api.get(self._entity, params=params)

View File

@ -14,7 +14,9 @@
# limitations under the License.
import base64
import datetime
import sys
import time
from barbicanclient import exceptions
from functionaltests.client import base
@ -767,3 +769,182 @@ class SecretsTestCase(base.TestCase):
resp = self.barbicanclient.secrets.get(secret_ref)
self.assertEqual("ACTIVE", resp.status)
self.assertEqual(secret_type, resp.secret_type)
@utils.parameterized_dataset({
'query_by_name': {
'secret_1_dict': dict(name="name1"),
'secret_2_dict': dict(name="name2"),
'query_dict': dict(name="name1")
},
'query_by_algorithm': {
'secret_1_dict': dict(algorithm="algorithm1"),
'secret_2_dict': dict(algorithm="algorithm2"),
'query_dict': dict(algorithm="algorithm1")
},
'query_by_mode': {
'secret_1_dict': dict(mode="mode1"),
'secret_2_dict': dict(mode="mode2"),
'query_dict': dict(mode="mode1")
},
'query_by_bit_length': {
'secret_1_dict': dict(bit_length=1024),
'secret_2_dict': dict(bit_length=2048),
'query_dict': dict(bits=1024)
},
'query_by_secret_type': {
'secret_1_dict': dict(secret_type='opaque'),
'secret_2_dict': dict(secret_type='symmetric'),
'query_dict': dict(secret_type='opaque')
},
})
@testcase.attr('positive')
def test_secret_list_with_filter(self, secret_1_dict, secret_2_dict,
query_dict):
secret_1 = self.barbicanclient.secrets.create(**secret_1_dict)
secret_1_ref = self.cleanup.add_entity(secret_1)
self.assertIsNotNone(secret_1_ref)
secret_2 = self.barbicanclient.secrets.create(**secret_2_dict)
secret_2_ref = self.cleanup.add_entity(secret_2)
self.assertIsNotNone(secret_2_ref)
secret_list = self.barbicanclient.secrets.list(**query_dict)
self.assertEqual(1, len(secret_list))
@utils.parameterized_dataset({
'query_by_name': {
'secret_1_dict': dict(name="name1"),
'secret_2_dict': dict(name="name2"),
'sort': 'name'
},
'query_by_algorithm': {
'secret_1_dict': dict(algorithm="algorithm1"),
'secret_2_dict': dict(algorithm="algorithm2"),
'sort': 'algorithm'
},
'query_by_mode': {
'secret_1_dict': dict(mode="mode1"),
'secret_2_dict': dict(mode="mode2"),
'sort': 'mode'
},
'query_by_bit_length': {
'secret_1_dict': dict(bit_length=1024),
'secret_2_dict': dict(bit_length=2048),
'sort': 'bit_length'
},
'query_by_secret_type': {
'secret_1_dict': dict(secret_type='opaque'),
'secret_2_dict': dict(secret_type='symmetric'),
'sort': 'secret_type'
},
})
@testcase.attr('positive')
def test_secret_list_with_sort(self, secret_1_dict, secret_2_dict, sort):
secret_1 = self.barbicanclient.secrets.create(**secret_1_dict)
secret_1_ref = self.cleanup.add_entity(secret_1)
self.assertIsNotNone(secret_1_ref)
secret_2 = self.barbicanclient.secrets.create(**secret_2_dict)
secret_2_ref = self.cleanup.add_entity(secret_2)
self.assertIsNotNone(secret_2_ref)
query_dict = {'sort': sort + ":asc"}
secret_list = self.barbicanclient.secrets.list(**query_dict)
self.assertEqual(2, len(secret_list))
self.assertEqual(secret_1_ref, secret_list[0].secret_ref)
query_dict = {'sort': sort + ":desc"}
secret_list = self.barbicanclient.secrets.list(**query_dict)
self.assertEqual(2, len(secret_list))
self.assertEqual(secret_2_ref, secret_list[0].secret_ref)
@utils.parameterized_dataset({
'created': {
'date_type': 'created',
},
'updated': {
'date_type': 'updated',
},
'expiration': {
'date_type': 'expiration',
},
})
@testcase.attr('positive')
def test_secret_list_with_date_filter(self, date_type):
now = datetime.datetime.utcnow()
expiration_1 = (now + datetime.timedelta(days=3)).isoformat()
expiration_2 = (now + datetime.timedelta(days=5)).isoformat()
secret_1 = self.barbicanclient.secrets.create(expiration=expiration_1)
secret_1_ref = self.cleanup.add_entity(secret_1)
self.assertIsNotNone(secret_1_ref)
payload = "gF6+lLoF3ohA9aPRpt+6bQ=="
self.barbicanclient.secrets.update(secret_1_ref, payload)
time.sleep(1)
secret_2 = self.barbicanclient.secrets.create(expiration=expiration_2)
secret_2_ref = self.cleanup.add_entity(secret_2)
self.assertIsNotNone(secret_2_ref)
time_to_search_1 = getattr(secret_1, date_type).isoformat()
time_to_search_2 = getattr(secret_2, date_type).isoformat()
# Search for secrets with secret 1's time
query_dict = {date_type: time_to_search_1}
secret_list = self.barbicanclient.secrets.list(**query_dict)
self.assertEqual(1, len(secret_list))
self.assertEqual(secret_1_ref, secret_list[0].secret_ref)
# Search for secrets with time < secret 2, i.e. secret 1
query_dict = {date_type: 'lt:' + time_to_search_2}
secret_list = self.barbicanclient.secrets.list(**query_dict)
self.assertEqual(1, len(secret_list))
self.assertEqual(secret_1_ref, secret_list[0].secret_ref)
# Search for secrets with time < secret 1, i.e. none
query_dict = {date_type: 'lt:' + time_to_search_1}
secret_list = self.barbicanclient.secrets.list(**query_dict)
self.assertEqual(0, len(secret_list))
# Search for secrets with time <= secret 2, i.e. both secrets
query_dict = {date_type: 'lte:' + time_to_search_2}
secret_list = self.barbicanclient.secrets.list(**query_dict)
self.assertEqual(2, len(secret_list))
# Search for secrets with time > secret 1, i.e. secret 2
query_dict = {date_type: 'gt:' + time_to_search_1}
secret_list = self.barbicanclient.secrets.list(**query_dict)
self.assertEqual(1, len(secret_list))
self.assertEqual(secret_2_ref, secret_list[0].secret_ref)
# Search for secrets with time > secret 2, i.e. none
query_dict = {date_type: 'gt:' + time_to_search_2}
secret_list = self.barbicanclient.secrets.list(**query_dict)
self.assertEqual(0, len(secret_list))
# Search for secrets with time >= secret 1, i.e. both secrets
query_dict = {date_type: 'gte:' + time_to_search_1}
secret_list = self.barbicanclient.secrets.list(**query_dict)
self.assertEqual(2, len(secret_list))
# Sort secrets by date
query_dict = {'sort': date_type + ":asc"}
secret_list = self.barbicanclient.secrets.list(**query_dict)
self.assertEqual(2, len(secret_list))
self.assertEqual(secret_1_ref, secret_list[0].secret_ref)
# Sort secrets by date
query_dict = {'sort': date_type + ":desc"}
secret_list = self.barbicanclient.secrets.list(**query_dict)
self.assertEqual(2, len(secret_list))
self.assertEqual(secret_2_ref, secret_list[0].secret_ref)