From: John Mulligan Date: Mon, 13 May 2024 21:10:36 +0000 (-0400) Subject: mgr/smb: add find_in_store function to config_store.py X-Git-Tag: v20.0.0~1489^2~15 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=fd6d4a77c85218e6f37167e05c603a3a9d91a4a9;p=ceph.git mgr/smb: add find_in_store function to config_store.py 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 --- diff --git a/src/pybind/mgr/smb/config_store.py b/src/pybind/mgr/smb/config_store.py index 742c23f6436..38548df5d5e 100644 --- a/src/pybind/mgr/smb/config_store.py +++ b/src/pybind/mgr/smb/config_store.py @@ -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