mirror of
https://salsa.debian.org/freeipa-team/freeipa.git
synced 2025-02-25 18:55:28 -06:00
schema: Add fingerprint and TTL
Calculate fingerprint for schema in deterministic way. Send fingerprint value together with schema. Send TTL with schema to inform client about caching interval. https://fedorahosted.org/freeipa/ticket/4739 Reviewed-By: Jan Cholasta <jcholast@redhat.com>
This commit is contained in:
parent
f85c347f4d
commit
034a111972
@ -7,6 +7,7 @@ import itertools
|
|||||||
import sys
|
import sys
|
||||||
|
|
||||||
import six
|
import six
|
||||||
|
import hashlib
|
||||||
|
|
||||||
from .baseldap import LDAPObject
|
from .baseldap import LDAPObject
|
||||||
from ipalib import errors
|
from ipalib import errors
|
||||||
@ -18,6 +19,10 @@ from ipalib.plugable import Registry
|
|||||||
from ipalib.text import _
|
from ipalib.text import _
|
||||||
from ipapython.version import API_VERSION
|
from ipapython.version import API_VERSION
|
||||||
|
|
||||||
|
# Schema TTL sent to clients in response to schema call.
|
||||||
|
# Number of seconds before client should check for schema update.
|
||||||
|
SCHEMA_TTL = 7*24*3600 # default: 7 days
|
||||||
|
|
||||||
__doc__ = _("""
|
__doc__ = _("""
|
||||||
API Schema
|
API Schema
|
||||||
""") + _("""
|
""") + _("""
|
||||||
@ -690,6 +695,33 @@ class output_find(BaseParamSearch):
|
|||||||
class schema(Command):
|
class schema(Command):
|
||||||
NO_CLI = True
|
NO_CLI = True
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _calculate_fingerprint(data):
|
||||||
|
"""
|
||||||
|
Returns fingerprint for schema
|
||||||
|
|
||||||
|
Behavior of this function can be changed at any time
|
||||||
|
given that it always generates identical fingerprint for
|
||||||
|
identical data (change in order of items in dict is
|
||||||
|
irelevant) and the risk of generating identical fingerprint
|
||||||
|
for different inputs is low.
|
||||||
|
"""
|
||||||
|
to_process = [data]
|
||||||
|
fingerprint = hashlib.sha1()
|
||||||
|
|
||||||
|
for entry in to_process:
|
||||||
|
if isinstance(entry, (list, tuple)):
|
||||||
|
for item in entry:
|
||||||
|
to_process.append(item)
|
||||||
|
elif isinstance(entry, dict):
|
||||||
|
for key in sorted(entry.keys()):
|
||||||
|
to_process.append(key)
|
||||||
|
to_process.append(entry[key])
|
||||||
|
else:
|
||||||
|
fingerprint.update(unicode(entry).encode('utf-8'))
|
||||||
|
|
||||||
|
return fingerprint.hexdigest()[:8]
|
||||||
|
|
||||||
def execute(self, *args, **kwargs):
|
def execute(self, *args, **kwargs):
|
||||||
commands = list(self.api.Object.command.search(**kwargs))
|
commands = list(self.api.Object.command.search(**kwargs))
|
||||||
for command in commands:
|
for command in commands:
|
||||||
@ -712,4 +744,8 @@ class schema(Command):
|
|||||||
schema['classes'] = classes
|
schema['classes'] = classes
|
||||||
schema['topics'] = topics
|
schema['topics'] = topics
|
||||||
|
|
||||||
|
schema_fp = self._calculate_fingerprint(schema)
|
||||||
|
schema['fingerprint'] = schema_fp
|
||||||
|
schema['ttl'] = SCHEMA_TTL
|
||||||
|
|
||||||
return dict(result=schema)
|
return dict(result=schema)
|
||||||
|
Loading…
Reference in New Issue
Block a user