Skip to content

Commit e0c4f1c

Browse files
authored
Buzz/stream events (#1247)
1 parent 20df7ec commit e0c4f1c

File tree

6 files changed

+109
-1
lines changed

6 files changed

+109
-1
lines changed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
2+
### Enhancements
3+
4+
* Added a command to show tunnel events

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ classifiers = [
2828
]
2929
requires-python = ">=3.9"
3030
dependencies = [
31-
"globus-sdk==4.3.1",
31+
"globus-sdk==4.4.0",
3232
"click>=8.1.4,<8.4",
3333
"jmespath==1.1.0",
3434
"packaging>=17.0",

src/globus_cli/commands/streams/tunnel/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
"list": (".list", "list_tunnel_command"),
1111
"show": (".show", "show_tunnel_command"),
1212
"stop": (".stop", "stop_tunnel_command"),
13+
"events": (".events", "events_command"),
1314
},
1415
)
1516
def tunnel_command() -> None:
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
from __future__ import annotations
2+
3+
import uuid
4+
5+
import click
6+
7+
from globus_cli.login_manager import LoginManager
8+
from globus_cli.parsing import command
9+
from globus_cli.termio import Field, display
10+
11+
TUNNEL_EVENT_LIST_FIELDS = [
12+
Field("Code", "attributes.code"),
13+
Field("Error", "attributes.is_error"),
14+
Field("Details", "attributes.details"),
15+
Field("Time", "attributes.time"),
16+
]
17+
18+
19+
@command("events", short_help="List tunnel events.")
20+
@click.argument("tunnel_id", metavar="TUNNEL_ID", type=click.UUID)
21+
@LoginManager.requires_login("auth", "transfer")
22+
def events_command(
23+
login_manager: LoginManager,
24+
*,
25+
tunnel_id: uuid.UUID,
26+
) -> None:
27+
"""
28+
Show the events that have occurred on the tunnel.
29+
"""
30+
tunnel_client = login_manager.get_transfer_client()
31+
res = tunnel_client.get_tunnel_events(tunnel_id)
32+
display(
33+
res,
34+
text_mode=display.TABLE,
35+
fields=TUNNEL_EVENT_LIST_FIELDS,
36+
response_key="data",
37+
)

tests/files/api_fixtures/tunnel_operations.yaml

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,3 +147,48 @@ transfer:
147147
"request_id": "yDZD2RwPk"
148148
}
149149
}
150+
151+
- path: /v2/tunnels/689dcb43-cdbe-46bb-9a59-dad71091a247/events
152+
method: GET
153+
json:
154+
{
155+
"data": [
156+
{
157+
"type": "TunnelEvent",
158+
"id": 2768,
159+
"attributes": {
160+
"code": "STARTED",
161+
"is_error": false,
162+
"description": "started",
163+
"details": "Attempting tunnel establishment",
164+
"time": "2026-02-12T21:59:01.857473"
165+
}
166+
},
167+
{
168+
"type": "TunnelEvent",
169+
"id": 2769,
170+
"attributes": {
171+
"code": "TUNNEL_ACTIVE",
172+
"is_error": false,
173+
"description": "tunnel is active",
174+
"details": "Tunnel has been established",
175+
"time": "2026-02-12T21:59:02.876253"
176+
}
177+
},
178+
{
179+
"type": "TunnelEvent",
180+
"id": 2777,
181+
"attributes": {
182+
"code": "TUNNEL_STOPPED",
183+
"is_error": false,
184+
"description": "tunnel has been stopped",
185+
"details": "Tunnel stopped as requested.",
186+
"time": "2026-02-12T22:12:03.655877"
187+
}
188+
}
189+
],
190+
"links": null,
191+
"meta": {
192+
"request_id": "8eZwBInC5"
193+
}
194+
}

tests/functional/streams/test_tunnels.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,3 +80,24 @@ def test_tunnel_update(run_line, output_format):
8080

8181
sent_data = json.loads(get_last_request().body)
8282
assert sent_data["data"]["attributes"]["label"] == meta["display_name"]
83+
84+
85+
@pytest.mark.parametrize("output_format", ["json", "text"])
86+
def test_tunnel_events(run_line, output_format):
87+
meta = load_response_set("cli.tunnel_operations").metadata
88+
result = run_line(
89+
[
90+
"globus",
91+
"streams",
92+
"tunnel",
93+
"events",
94+
meta["tunnel_id"],
95+
"-F",
96+
output_format,
97+
]
98+
)
99+
if output_format == "json":
100+
res = json.loads(result.output)
101+
assert res["data"][0]["type"] == "TunnelEvent"
102+
else:
103+
assert "Code" in result.output

0 commit comments

Comments
 (0)