Skip to content

Commit c2964ae

Browse files
phlogistonjohnmergify[bot]
authored andcommitted
sambacc: add get_object method to rados handler class
Add a method for getting a RADOSObjectRef based on a uri-like string, similar to the `rados_open` method that exists to support the urllib functionality. This includes a small refactor of the uri/url parsing so that it can be shared for both `get_object` and `rados_open`. Note that get_object advertises returning RADOSObjectRef so that special specific-to-rados APIs can be used easily. Signed-off-by: John Mulligan <[email protected]>
1 parent e84938a commit c2964ae

File tree

1 file changed

+46
-5
lines changed

1 file changed

+46
-5
lines changed

sambacc/rados_opener.py

Lines changed: 46 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -63,19 +63,60 @@ class _RADOSHandler(urllib.request.BaseHandler):
6363
_interface: typing.Optional[_RADOSInterface] = None
6464

6565
def rados_open(self, req: urllib.request.Request) -> typing.IO:
66+
"""Open a rados-style url. Called from urllib."""
6667
if self._interface is None:
6768
raise RADOSUnsupported()
68-
if req.selector.startswith("mon-config-key:"):
69-
return _get_mon_config_key(
70-
self._interface, req.selector.split(":", 1)[1]
71-
)
69+
rinfo = self._parse_req(req)
70+
if rinfo.get("subtype") == "mon-config-key":
71+
return _get_mon_config_key(self._interface, rinfo["path"])
72+
return RADOSObjectRef(
73+
self._interface, rinfo["pool"], rinfo["ns"], rinfo["key"]
74+
)
75+
76+
def get_object(
77+
self, uri: str, *, must_exist: bool = False
78+
) -> RADOSObjectRef:
79+
"""Return a rados object reference for the given rados uri. The uri
80+
must refer to a rados object only as the RADOSObjectRef can do various
81+
rados-y things, more than an IO requires.
82+
"""
83+
if self._interface is None:
84+
raise RADOSUnsupported()
85+
rinfo = self._parse_req(urllib.request.Request(uri))
86+
if rinfo.get("type") != "rados":
87+
raise ValueError("only rados URI values supported")
88+
if rinfo.get("subtype") == "mon-config-key":
89+
raise ValueError("only rados object URI values supported")
90+
return RADOSObjectRef(
91+
self._interface,
92+
rinfo["pool"],
93+
rinfo["ns"],
94+
rinfo["key"],
95+
must_exist=must_exist,
96+
)
97+
98+
def _parse_req(self, req: urllib.request.Request) -> dict[str, str]:
99+
"""Parse a urlib request into useful components."""
100+
subtype = "mon-config-key"
101+
if req.selector.startswith(subtype + ":"):
102+
return {
103+
"type": req.type,
104+
"subtype": subtype,
105+
"path": req.selector.split(":", 1)[1],
106+
}
72107
sel = req.selector.lstrip("/")
73108
if req.host:
74109
pool = req.host
75110
ns, key = sel.split("/", 1)
76111
else:
77112
pool, ns, key = sel.split("/", 2)
78-
return _RADOSResponse(self._interface, pool, ns, key)
113+
return {
114+
"type": req.type,
115+
"subtype": "object",
116+
"pool": pool,
117+
"ns": ns,
118+
"key": key,
119+
}
79120

80121

81122
# it's quite annoying to have a read-only typing.IO we're forced to

0 commit comments

Comments
 (0)