Skip to content

Commit d14f7a6

Browse files
authored
add Domain field to endpoint search and show (#1214)
1 parent a1ab925 commit d14f7a6

File tree

4 files changed

+54
-7
lines changed

4 files changed

+54
-7
lines changed
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
### Enhancements
2+
3+
* Add Domain field to default output of `globus endpoint search` and `globus endpoint show`

src/globus_cli/commands/endpoint/show.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,14 @@
55
from globus_cli.endpointish import Endpointish
66
from globus_cli.login_manager import LoginManager
77
from globus_cli.parsing import command, endpoint_id_arg
8+
from globus_cli.services.transfer import DOMAIN_FIELD
89
from globus_cli.termio import Field, display, formatters
910

1011
STANDARD_FIELDS = [
1112
Field("Display Name", "display_name"),
1213
Field("ID", "id"),
1314
Field("Owner", "owner_string"),
15+
DOMAIN_FIELD,
1416
Field("Description", "description", wrap_enabled=True),
1517
Field("Shareable", "shareable"),
1618
Field("Keywords", "keywords"),

src/globus_cli/services/transfer/__init__.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,46 @@ def parse(self, value: t.Any) -> str:
1818
return str(value[0] or value[1])
1919

2020

21+
class _DomainFormatter(formatters.StrFormatter):
22+
def parse(self, value: t.Any) -> str:
23+
if not isinstance(value, list) or len(value) != 2:
24+
raise ValueError("cannot parse domain from malformed data")
25+
26+
tlsftp_server, gcs_manager_url = value
27+
28+
# if tlsftp_server is present, this is a GCS collection
29+
# parse tlsftp_server in the format tlsftp://{domain}:{port}
30+
if tlsftp_server:
31+
assert isinstance(tlsftp_server, str)
32+
return tlsftp_server[len("tlsftp://") :].split(":")[0]
33+
34+
# if gcs_manager_url present, but not tlsftp_server, this is a GCS endpoint
35+
# parse gcs_manager_url in the format https://{domain}
36+
elif gcs_manager_url:
37+
assert isinstance(gcs_manager_url, str)
38+
return gcs_manager_url[len("https://") :]
39+
40+
# entity type with no domain
41+
else:
42+
return str(None)
43+
44+
45+
DOMAIN_FIELD = Field(
46+
"Domain", "[tlsftp_server, gcs_manager_url]", formatter=_DomainFormatter()
47+
)
48+
49+
2150
ENDPOINT_LIST_FIELDS = [
2251
Field("ID", "id"),
2352
Field("Owner", "owner_string"),
2453
Field("Display Name", "[display_name, canonical_name]", formatter=_NameFormatter()),
54+
DOMAIN_FIELD,
2555
]
2656

2757

2858
__all__ = (
2959
"ENDPOINT_LIST_FIELDS",
60+
"DOMAIN_FIELD",
3061
"CustomTransferClient",
3162
"RecursiveLsResponse",
3263
"iterable_response_to_dict",

tests/functional/endpoint/test_endpoint_search.py

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,13 @@ def _make_mapped_collection_search_result(
1515
endpoint_id: str,
1616
display_name: str,
1717
owner_string: str,
18+
manager_fqdn: str,
19+
collection_fqdn: str,
1820
) -> dict[str, t.Any]:
1921
# most of the fields are filled with dummy data
2022
# some of these values are pulled out here either to ensure their integrity
2123
# or to make them more visible to a reader
2224
username = "u_abcdefghijklmnop" # not a real b32 username
23-
manager_fqdn = "a0bc1.23de.data.globus.org"
24-
collection_fqdn = f"m-f45678.{manager_fqdn}"
2525

2626
data = {
2727
"DATA_TYPE": "endpoint",
@@ -123,6 +123,9 @@ def singular_search_response():
123123
endpoint_id = str(uuid.uuid4())
124124
display_name = "dummy result"
125125
owner_string = "globus@globus.org"
126+
manager_fqdn = "a0bc1.23de.data.globus.org"
127+
collection_fqdn = f"m-f45678.{manager_fqdn}"
128+
126129
return RegisteredResponse(
127130
service="transfer",
128131
path="/v0.10/endpoint_search",
@@ -131,11 +134,17 @@ def singular_search_response():
131134
"endpoint_id": endpoint_id,
132135
"display_name": display_name,
133136
"owner_string": owner_string,
137+
"collection_fqdn": collection_fqdn,
134138
},
135139
json={
136140
"DATA": [
137141
_make_mapped_collection_search_result(
138-
collection_id, endpoint_id, display_name, owner_string
142+
collection_id,
143+
endpoint_id,
144+
display_name,
145+
owner_string,
146+
manager_fqdn,
147+
collection_fqdn,
139148
)
140149
],
141150
"DATA_TYPE": "endpoint_list",
@@ -162,20 +171,22 @@ def test_search_shows_collection_id(run_line, singular_search_response):
162171
header_line, separator_line, data_line = lines
163172

164173
# the header line shows the field names in order
165-
header_row = re.split(r"\s+\|\s+", header_line)
166-
assert header_row == ["ID", "Owner", "Display Name"]
174+
header_row = [header.strip() for header in re.split(r"\s+\|\s+", header_line)]
175+
assert header_row == ["ID", "Owner", "Display Name", "Domain"]
167176
# the separator line is a series of dashes
177+
168178
separator_row = separator_line.split("-+-")
169-
assert len(separator_row) == 3
179+
assert len(separator_row) == 4
170180
for separator in separator_row:
171181
assert set(separator) == {"-"} # exactly one character is used
172182

173-
# the data row should have the collection ID, Owner, and Display Name
183+
# the data row should have the collection ID, Owner, Display Name, and Domain
174184
data_row = re.split(r"\s+\|\s+", data_line)
175185
assert data_row == [
176186
meta["collection_id"],
177187
meta["owner_string"],
178188
meta["display_name"],
189+
meta["collection_fqdn"],
179190
]
180191

181192
# final sanity check -- the endpoint ID for a mapped collection doesn't

0 commit comments

Comments
 (0)