]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mgr/smb: add find_in_store function to config_store.py
authorJohn Mulligan <jmulligan@redhat.com>
Mon, 13 May 2024 21:10:36 +0000 (17:10 -0400)
committerJohn Mulligan <jmulligan@redhat.com>
Sat, 6 Jul 2024 14:00:18 +0000 (10:00 -0400)
Add a new `find_in_store` function to the config store module. This
function can be called on any store to search for a particular object
using the FindParams, with an exact match of the subset of keys & values
in the dict. If the store is a FindingConfigStore this operation may be
able to be done more efficiently but we always can fall back to the
simple approach of reading in every object from the store & namespace.

Signed-off-by: John Mulligan <jmulligan@redhat.com>
src/pybind/mgr/smb/config_store.py

index 742c23f6436cef7c4c2f67adfc648ded19dae980..38548df5d5e2ee621cd4f83942f07716ab646c73 100644 (file)
@@ -1,6 +1,6 @@
 from typing import Collection, Dict, Iterator, Optional
 
-from .proto import ConfigEntry, EntryKey, Simplified
+from .proto import ConfigEntry, ConfigStore, EntryKey, FindParams, Simplified
 
 
 class MemConfigEntry:
@@ -140,3 +140,40 @@ class ObjectCachingEntry:
     @property
     def full_key(self) -> EntryKey:
         return self._base.full_key
+
+
+def find_in_store(
+    store: ConfigStore, ns: str, params: FindParams
+) -> Collection[ConfigEntry]:
+    """Given a ConfigStore and namespace within that store, search the stored
+    objects for matching parameters. Params is a dict that will be compared to
+    the same keys/attributes of the objects being searched. Only exact matches
+    will be returned.
+    If the store implements the FindingConfigStore protocol the operation
+    of finding
+    """
+    # is it a FindingConfigStore?
+    _find_entries = getattr(store, 'find_entries', None)
+    if _find_entries:
+        try:
+            return _find_entries(ns, params)
+        except NotImplementedError:
+            # Allow the store to reject any of the ns/params/whatnot with a
+            # NotImplementedError even if it implements the find_entries
+            # function. This will fall back to the simple-but-slow approach of
+            # deserializing and examining every object.
+            pass
+    return _find_in_store(store, ns, params)
+
+
+def _find_in_store(
+    store: ConfigStore, ns: str, params: FindParams
+) -> Collection[ConfigEntry]:
+    """Fallback mode for find_in_store."""
+    found = []
+    for sub_key in store.contents(ns):
+        entry = store[(ns, sub_key)]
+        obj = entry.get()
+        if all(obj[pkey] == pval for pkey, pval in params.items()):
+            found.append(ObjectCachingEntry(entry, obj=obj))
+    return found