airbyte-internal-ops 0.9.1__py3-none-any.whl → 0.10.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {airbyte_internal_ops-0.9.1.dist-info → airbyte_internal_ops-0.10.0.dist-info}/METADATA +1 -1
- {airbyte_internal_ops-0.9.1.dist-info → airbyte_internal_ops-0.10.0.dist-info}/RECORD +13 -11
- airbyte_ops_mcp/airbyte_repo/progressive_rollout.py +279 -0
- airbyte_ops_mcp/cli/local.py +118 -0
- airbyte_ops_mcp/cloud_admin/api_client.py +336 -0
- airbyte_ops_mcp/cloud_admin/models.py +99 -0
- airbyte_ops_mcp/mcp/connector_rollout.py +779 -0
- airbyte_ops_mcp/mcp/prod_db_queries.py +227 -0
- airbyte_ops_mcp/mcp/server.py +2 -0
- airbyte_ops_mcp/prod_db_access/queries.py +144 -0
- airbyte_ops_mcp/prod_db_access/sql.py +298 -0
- {airbyte_internal_ops-0.9.1.dist-info → airbyte_internal_ops-0.10.0.dist-info}/WHEEL +0 -0
- {airbyte_internal_ops-0.9.1.dist-info → airbyte_internal_ops-0.10.0.dist-info}/entry_points.txt +0 -0
|
@@ -23,6 +23,7 @@ from airbyte_ops_mcp.prod_db_access.queries import (
|
|
|
23
23
|
query_connections_by_connector,
|
|
24
24
|
query_connections_by_destination_connector,
|
|
25
25
|
query_connections_by_stream,
|
|
26
|
+
query_connector_rollouts,
|
|
26
27
|
query_connector_versions,
|
|
27
28
|
query_dataplanes_list,
|
|
28
29
|
query_destination_connection_stats,
|
|
@@ -1272,6 +1273,232 @@ def query_prod_connector_connection_stats(
|
|
|
1272
1273
|
)
|
|
1273
1274
|
|
|
1274
1275
|
|
|
1276
|
+
# =============================================================================
|
|
1277
|
+
# Connector Rollout Models and Tools
|
|
1278
|
+
# =============================================================================
|
|
1279
|
+
|
|
1280
|
+
|
|
1281
|
+
class ConnectorRolloutInfo(BaseModel):
|
|
1282
|
+
"""Information about a connector rollout."""
|
|
1283
|
+
|
|
1284
|
+
rollout_id: str = Field(description="The rollout UUID")
|
|
1285
|
+
actor_definition_id: str = Field(description="The connector definition UUID")
|
|
1286
|
+
state: str = Field(
|
|
1287
|
+
description="Rollout state: initialized, workflow_started, in_progress, "
|
|
1288
|
+
"paused, finalizing, succeeded, errored, failed_rolled_back, canceled"
|
|
1289
|
+
)
|
|
1290
|
+
initial_rollout_pct: int | None = Field(
|
|
1291
|
+
default=None, description="Initial rollout percentage"
|
|
1292
|
+
)
|
|
1293
|
+
current_target_rollout_pct: int | None = Field(
|
|
1294
|
+
default=None, description="Current target rollout percentage"
|
|
1295
|
+
)
|
|
1296
|
+
final_target_rollout_pct: int | None = Field(
|
|
1297
|
+
default=None, description="Final target rollout percentage"
|
|
1298
|
+
)
|
|
1299
|
+
has_breaking_changes: bool = Field(
|
|
1300
|
+
description="Whether the RC has breaking changes"
|
|
1301
|
+
)
|
|
1302
|
+
max_step_wait_time_mins: int | None = Field(
|
|
1303
|
+
default=None, description="Maximum wait time between rollout steps in minutes"
|
|
1304
|
+
)
|
|
1305
|
+
rollout_strategy: str | None = Field(
|
|
1306
|
+
default=None, description="Rollout strategy: manual, automated, overridden"
|
|
1307
|
+
)
|
|
1308
|
+
workflow_run_id: str | None = Field(
|
|
1309
|
+
default=None, description="Temporal workflow run ID"
|
|
1310
|
+
)
|
|
1311
|
+
error_msg: str | None = Field(default=None, description="Error message if errored")
|
|
1312
|
+
failed_reason: str | None = Field(
|
|
1313
|
+
default=None, description="Reason for failure if failed"
|
|
1314
|
+
)
|
|
1315
|
+
paused_reason: str | None = Field(
|
|
1316
|
+
default=None, description="Reason for pause if paused"
|
|
1317
|
+
)
|
|
1318
|
+
tag: str | None = Field(default=None, description="Optional tag for the rollout")
|
|
1319
|
+
created_at: datetime | None = Field(
|
|
1320
|
+
default=None, description="When the rollout was created"
|
|
1321
|
+
)
|
|
1322
|
+
updated_at: datetime | None = Field(
|
|
1323
|
+
default=None, description="When the rollout was last updated"
|
|
1324
|
+
)
|
|
1325
|
+
completed_at: datetime | None = Field(
|
|
1326
|
+
default=None, description="When the rollout completed (if terminal)"
|
|
1327
|
+
)
|
|
1328
|
+
expires_at: datetime | None = Field(
|
|
1329
|
+
default=None, description="When the rollout expires"
|
|
1330
|
+
)
|
|
1331
|
+
rc_docker_image_tag: str | None = Field(
|
|
1332
|
+
default=None, description="Docker image tag of the release candidate"
|
|
1333
|
+
)
|
|
1334
|
+
rc_docker_repository: str | None = Field(
|
|
1335
|
+
default=None, description="Docker repository of the release candidate"
|
|
1336
|
+
)
|
|
1337
|
+
initial_docker_image_tag: str | None = Field(
|
|
1338
|
+
default=None, description="Docker image tag of the initial version"
|
|
1339
|
+
)
|
|
1340
|
+
initial_docker_repository: str | None = Field(
|
|
1341
|
+
default=None, description="Docker repository of the initial version"
|
|
1342
|
+
)
|
|
1343
|
+
|
|
1344
|
+
|
|
1345
|
+
def _row_to_connector_rollout_info(row: dict[str, Any]) -> ConnectorRolloutInfo:
|
|
1346
|
+
"""Convert a database row to a ConnectorRolloutInfo model."""
|
|
1347
|
+
return ConnectorRolloutInfo(
|
|
1348
|
+
rollout_id=str(row["rollout_id"]),
|
|
1349
|
+
actor_definition_id=str(row["actor_definition_id"]),
|
|
1350
|
+
state=row["state"],
|
|
1351
|
+
initial_rollout_pct=row.get("initial_rollout_pct"),
|
|
1352
|
+
current_target_rollout_pct=row.get("current_target_rollout_pct"),
|
|
1353
|
+
final_target_rollout_pct=row.get("final_target_rollout_pct"),
|
|
1354
|
+
has_breaking_changes=row["has_breaking_changes"],
|
|
1355
|
+
max_step_wait_time_mins=row.get("max_step_wait_time_mins"),
|
|
1356
|
+
rollout_strategy=row.get("rollout_strategy"),
|
|
1357
|
+
workflow_run_id=row.get("workflow_run_id"),
|
|
1358
|
+
error_msg=row.get("error_msg"),
|
|
1359
|
+
failed_reason=row.get("failed_reason"),
|
|
1360
|
+
paused_reason=row.get("paused_reason"),
|
|
1361
|
+
tag=row.get("tag"),
|
|
1362
|
+
created_at=row.get("created_at"),
|
|
1363
|
+
updated_at=row.get("updated_at"),
|
|
1364
|
+
completed_at=row.get("completed_at"),
|
|
1365
|
+
expires_at=row.get("expires_at"),
|
|
1366
|
+
rc_docker_image_tag=row.get("rc_docker_image_tag"),
|
|
1367
|
+
rc_docker_repository=row.get("rc_docker_repository"),
|
|
1368
|
+
initial_docker_image_tag=row.get("initial_docker_image_tag"),
|
|
1369
|
+
initial_docker_repository=row.get("initial_docker_repository"),
|
|
1370
|
+
)
|
|
1371
|
+
|
|
1372
|
+
|
|
1373
|
+
@mcp_tool(
|
|
1374
|
+
read_only=True,
|
|
1375
|
+
idempotent=True,
|
|
1376
|
+
)
|
|
1377
|
+
def query_prod_connector_rollouts(
|
|
1378
|
+
actor_definition_id: Annotated[
|
|
1379
|
+
str | None,
|
|
1380
|
+
Field(description="Connector definition UUID to filter by (optional)"),
|
|
1381
|
+
] = None,
|
|
1382
|
+
rollout_id: Annotated[
|
|
1383
|
+
str | None,
|
|
1384
|
+
Field(description="Specific rollout UUID to look up (optional)"),
|
|
1385
|
+
] = None,
|
|
1386
|
+
active_only: Annotated[
|
|
1387
|
+
bool,
|
|
1388
|
+
Field(description="If true, only return active (non-terminal) rollouts"),
|
|
1389
|
+
] = False,
|
|
1390
|
+
limit: Annotated[
|
|
1391
|
+
int,
|
|
1392
|
+
Field(description="Maximum number of results (default: 100)"),
|
|
1393
|
+
] = 100,
|
|
1394
|
+
) -> list[ConnectorRolloutInfo]:
|
|
1395
|
+
"""Query connector rollouts with flexible filtering.
|
|
1396
|
+
|
|
1397
|
+
Returns rollouts based on the provided filters. If no filters are specified,
|
|
1398
|
+
returns all active rollouts. Useful for monitoring rollout status and history.
|
|
1399
|
+
|
|
1400
|
+
Filter behavior:
|
|
1401
|
+
- rollout_id: Returns that specific rollout (ignores other filters)
|
|
1402
|
+
- active_only: Returns only active (non-terminal) rollouts
|
|
1403
|
+
- actor_definition_id: Returns rollouts for that specific connector
|
|
1404
|
+
- No filters: Returns all active rollouts (same as active_only=True)
|
|
1405
|
+
"""
|
|
1406
|
+
rows = query_connector_rollouts(
|
|
1407
|
+
actor_definition_id=actor_definition_id,
|
|
1408
|
+
rollout_id=rollout_id,
|
|
1409
|
+
active_only=active_only,
|
|
1410
|
+
limit=limit,
|
|
1411
|
+
)
|
|
1412
|
+
return [_row_to_connector_rollout_info(row) for row in rows]
|
|
1413
|
+
|
|
1414
|
+
|
|
1415
|
+
class RolloutMonitoringStats(BaseModel):
|
|
1416
|
+
"""Aggregate monitoring stats for a connector rollout."""
|
|
1417
|
+
|
|
1418
|
+
rollout_id: str = Field(description="Rollout UUID")
|
|
1419
|
+
actor_definition_id: str = Field(description="Connector definition UUID")
|
|
1420
|
+
num_actors: int = Field(description="Total actors using this connector")
|
|
1421
|
+
num_actors_pinned: int = Field(
|
|
1422
|
+
description="Actors with any version pin (eligible or already pinned)"
|
|
1423
|
+
)
|
|
1424
|
+
num_pinned_to_rollout: int = Field(
|
|
1425
|
+
description="Actors specifically pinned to this rollout"
|
|
1426
|
+
)
|
|
1427
|
+
|
|
1428
|
+
|
|
1429
|
+
class RolloutActorSyncStats(BaseModel):
|
|
1430
|
+
"""Per-actor sync stats for a rollout."""
|
|
1431
|
+
|
|
1432
|
+
actor_id: str = Field(description="Actor UUID")
|
|
1433
|
+
num_succeeded: int = Field(description="Number of successful syncs")
|
|
1434
|
+
num_failed: int = Field(description="Number of failed syncs")
|
|
1435
|
+
num_connections: int = Field(description="Number of connections using this actor")
|
|
1436
|
+
|
|
1437
|
+
|
|
1438
|
+
class RolloutMonitoringResult(BaseModel):
|
|
1439
|
+
"""Complete monitoring result for a rollout."""
|
|
1440
|
+
|
|
1441
|
+
aggregate_stats: RolloutMonitoringStats = Field(
|
|
1442
|
+
description="Aggregate counts for the rollout"
|
|
1443
|
+
)
|
|
1444
|
+
actor_stats: list[RolloutActorSyncStats] = Field(
|
|
1445
|
+
description="Per-actor sync stats for actors pinned to the rollout"
|
|
1446
|
+
)
|
|
1447
|
+
|
|
1448
|
+
|
|
1449
|
+
@mcp_tool(
|
|
1450
|
+
read_only=True,
|
|
1451
|
+
idempotent=True,
|
|
1452
|
+
)
|
|
1453
|
+
def query_prod_rollout_monitoring_stats(
|
|
1454
|
+
rollout_id: Annotated[
|
|
1455
|
+
str,
|
|
1456
|
+
Field(description="Rollout UUID to get monitoring stats for"),
|
|
1457
|
+
],
|
|
1458
|
+
days_back: Annotated[
|
|
1459
|
+
int,
|
|
1460
|
+
Field(description="Number of days to look back for sync stats (default: 7)"),
|
|
1461
|
+
] = 7,
|
|
1462
|
+
) -> RolloutMonitoringResult:
|
|
1463
|
+
"""Get monitoring stats for a connector rollout.
|
|
1464
|
+
|
|
1465
|
+
Returns aggregate counts (total actors, pinned actors, rollout-pinned actors)
|
|
1466
|
+
and per-actor sync stats (succeeded, failed, connections) for actors
|
|
1467
|
+
participating in the rollout. This replaces the Retool rollout monitoring UI.
|
|
1468
|
+
"""
|
|
1469
|
+
from airbyte_ops_mcp.prod_db_access.queries import (
|
|
1470
|
+
query_rollout_actor_sync_stats,
|
|
1471
|
+
query_rollout_monitoring_stats,
|
|
1472
|
+
)
|
|
1473
|
+
|
|
1474
|
+
agg_stats = query_rollout_monitoring_stats(rollout_id=rollout_id)
|
|
1475
|
+
if agg_stats is None:
|
|
1476
|
+
raise ValueError(f"Rollout not found: {rollout_id}")
|
|
1477
|
+
|
|
1478
|
+
actor_stats = query_rollout_actor_sync_stats(
|
|
1479
|
+
rollout_id=rollout_id, days_back=days_back
|
|
1480
|
+
)
|
|
1481
|
+
|
|
1482
|
+
return RolloutMonitoringResult(
|
|
1483
|
+
aggregate_stats=RolloutMonitoringStats(
|
|
1484
|
+
rollout_id=str(agg_stats["rollout_id"]),
|
|
1485
|
+
actor_definition_id=str(agg_stats["actor_definition_id"]),
|
|
1486
|
+
num_actors=agg_stats["num_actors"] or 0,
|
|
1487
|
+
num_actors_pinned=agg_stats["num_actors_pinned"] or 0,
|
|
1488
|
+
num_pinned_to_rollout=agg_stats["num_pinned_to_rollout"] or 0,
|
|
1489
|
+
),
|
|
1490
|
+
actor_stats=[
|
|
1491
|
+
RolloutActorSyncStats(
|
|
1492
|
+
actor_id=str(row["actor_id"]),
|
|
1493
|
+
num_succeeded=row["num_succeeded"] or 0,
|
|
1494
|
+
num_failed=row["num_failed"] or 0,
|
|
1495
|
+
num_connections=row["num_connections"] or 0,
|
|
1496
|
+
)
|
|
1497
|
+
for row in actor_stats
|
|
1498
|
+
],
|
|
1499
|
+
)
|
|
1500
|
+
|
|
1501
|
+
|
|
1275
1502
|
def register_prod_db_query_tools(app: FastMCP) -> None:
|
|
1276
1503
|
"""Register prod DB query tools with the FastMCP app."""
|
|
1277
1504
|
register_mcp_tools(app, mcp_module=__name__)
|
airbyte_ops_mcp/mcp/server.py
CHANGED
|
@@ -33,6 +33,7 @@ from airbyte_ops_mcp.mcp._guidance import MCP_SERVER_INSTRUCTIONS
|
|
|
33
33
|
from airbyte_ops_mcp.mcp.cloud_connector_versions import (
|
|
34
34
|
register_cloud_connector_version_tools,
|
|
35
35
|
)
|
|
36
|
+
from airbyte_ops_mcp.mcp.connector_rollout import register_connector_rollout_tools
|
|
36
37
|
from airbyte_ops_mcp.mcp.gcp_logs import register_gcp_logs_tools
|
|
37
38
|
from airbyte_ops_mcp.mcp.github_actions import register_github_actions_tools
|
|
38
39
|
from airbyte_ops_mcp.mcp.github_repo_ops import register_github_repo_ops_tools
|
|
@@ -117,6 +118,7 @@ def register_server_assets(app: FastMCP) -> None:
|
|
|
117
118
|
register_github_actions_tools(app)
|
|
118
119
|
register_prerelease_tools(app)
|
|
119
120
|
register_cloud_connector_version_tools(app)
|
|
121
|
+
register_connector_rollout_tools(app)
|
|
120
122
|
register_prod_db_query_tools(app)
|
|
121
123
|
register_gcp_logs_tools(app)
|
|
122
124
|
register_prompts(app)
|
|
@@ -19,6 +19,8 @@ from google.cloud import secretmanager
|
|
|
19
19
|
from airbyte_ops_mcp.gcp_auth import get_secret_manager_client
|
|
20
20
|
from airbyte_ops_mcp.prod_db_access.db_engine import get_pool
|
|
21
21
|
from airbyte_ops_mcp.prod_db_access.sql import (
|
|
22
|
+
SELECT_ACTIVE_CONNECTOR_ROLLOUTS,
|
|
23
|
+
SELECT_ACTIVE_CONNECTOR_ROLLOUTS_BY_DEFINITION,
|
|
22
24
|
SELECT_ACTORS_PINNED_TO_VERSION,
|
|
23
25
|
SELECT_CONNECTIONS_BY_CONNECTOR,
|
|
24
26
|
SELECT_CONNECTIONS_BY_CONNECTOR_AND_ORG,
|
|
@@ -26,6 +28,8 @@ from airbyte_ops_mcp.prod_db_access.sql import (
|
|
|
26
28
|
SELECT_CONNECTIONS_BY_DESTINATION_CONNECTOR_AND_ORG,
|
|
27
29
|
SELECT_CONNECTIONS_BY_SOURCE_CONNECTOR_AND_STREAM,
|
|
28
30
|
SELECT_CONNECTIONS_BY_SOURCE_CONNECTOR_AND_STREAM_AND_ORG,
|
|
31
|
+
SELECT_CONNECTOR_ROLLOUT_BY_ID,
|
|
32
|
+
SELECT_CONNECTOR_ROLLOUTS,
|
|
29
33
|
SELECT_CONNECTOR_VERSIONS,
|
|
30
34
|
SELECT_DATAPLANES_LIST,
|
|
31
35
|
SELECT_DESTINATION_CONNECTION_STATS,
|
|
@@ -38,6 +42,8 @@ from airbyte_ops_mcp.prod_db_access.sql import (
|
|
|
38
42
|
SELECT_RECENT_SUCCESSFUL_SYNCS_FOR_SOURCE_CONNECTOR,
|
|
39
43
|
SELECT_RECENT_SYNCS_FOR_DESTINATION_CONNECTOR,
|
|
40
44
|
SELECT_RECENT_SYNCS_FOR_SOURCE_CONNECTOR,
|
|
45
|
+
SELECT_ROLLOUT_ACTOR_SYNC_STATS,
|
|
46
|
+
SELECT_ROLLOUT_AGGREGATE_STATS,
|
|
41
47
|
SELECT_SOURCE_CONNECTION_STATS,
|
|
42
48
|
SELECT_SUCCESSFUL_SYNCS_FOR_VERSION,
|
|
43
49
|
SELECT_SYNC_RESULTS_FOR_VERSION,
|
|
@@ -616,3 +622,141 @@ def query_connections_by_stream(
|
|
|
616
622
|
query_name="SELECT_CONNECTIONS_BY_SOURCE_CONNECTOR_AND_STREAM_AND_ORG",
|
|
617
623
|
gsm_client=gsm_client,
|
|
618
624
|
)
|
|
625
|
+
|
|
626
|
+
|
|
627
|
+
def query_connector_rollouts(
|
|
628
|
+
actor_definition_id: str | None = None,
|
|
629
|
+
rollout_id: str | None = None,
|
|
630
|
+
active_only: bool = False,
|
|
631
|
+
limit: int = 100,
|
|
632
|
+
*,
|
|
633
|
+
gsm_client: secretmanager.SecretManagerServiceClient | None = None,
|
|
634
|
+
) -> list[dict[str, Any]]:
|
|
635
|
+
"""Query connector rollouts with flexible filtering.
|
|
636
|
+
|
|
637
|
+
This is the unified query function for connector rollouts. Based on the
|
|
638
|
+
arguments provided, it will:
|
|
639
|
+
- If rollout_id is provided: Return that specific rollout (as a single-item list)
|
|
640
|
+
- If active_only is True AND actor_definition_id is provided: Return active rollouts for that connector
|
|
641
|
+
- If active_only is True: Return all active (non-terminal) rollouts
|
|
642
|
+
- If actor_definition_id is provided: Return all rollouts for that connector (including terminal)
|
|
643
|
+
- Otherwise: Return all active rollouts (up to limit)
|
|
644
|
+
|
|
645
|
+
Args:
|
|
646
|
+
actor_definition_id: Optional connector definition UUID to filter by
|
|
647
|
+
rollout_id: Optional specific rollout UUID to look up
|
|
648
|
+
active_only: If True, only return active (non-terminal) rollouts
|
|
649
|
+
limit: Maximum number of results (default: 100)
|
|
650
|
+
gsm_client: GCP Secret Manager client. If None, a new client will be instantiated.
|
|
651
|
+
|
|
652
|
+
Returns:
|
|
653
|
+
List of rollout records with version details
|
|
654
|
+
"""
|
|
655
|
+
if rollout_id is not None:
|
|
656
|
+
rows = _run_sql_query(
|
|
657
|
+
SELECT_CONNECTOR_ROLLOUT_BY_ID,
|
|
658
|
+
parameters={"rollout_id": rollout_id},
|
|
659
|
+
query_name="SELECT_CONNECTOR_ROLLOUT_BY_ID",
|
|
660
|
+
gsm_client=gsm_client,
|
|
661
|
+
)
|
|
662
|
+
return rows
|
|
663
|
+
|
|
664
|
+
# Handle active_only with optional actor_definition_id filter
|
|
665
|
+
if active_only:
|
|
666
|
+
if actor_definition_id is not None:
|
|
667
|
+
# Filter by both active states AND actor_definition_id
|
|
668
|
+
return _run_sql_query(
|
|
669
|
+
SELECT_ACTIVE_CONNECTOR_ROLLOUTS_BY_DEFINITION,
|
|
670
|
+
parameters={
|
|
671
|
+
"actor_definition_id": actor_definition_id,
|
|
672
|
+
"limit": limit,
|
|
673
|
+
},
|
|
674
|
+
query_name="SELECT_ACTIVE_CONNECTOR_ROLLOUTS_BY_DEFINITION",
|
|
675
|
+
gsm_client=gsm_client,
|
|
676
|
+
)
|
|
677
|
+
# Only active filter, no actor_definition_id
|
|
678
|
+
return _run_sql_query(
|
|
679
|
+
SELECT_ACTIVE_CONNECTOR_ROLLOUTS,
|
|
680
|
+
parameters={"limit": limit},
|
|
681
|
+
query_name="SELECT_ACTIVE_CONNECTOR_ROLLOUTS",
|
|
682
|
+
gsm_client=gsm_client,
|
|
683
|
+
)
|
|
684
|
+
|
|
685
|
+
# Not active_only, but filter by actor_definition_id (all states)
|
|
686
|
+
if actor_definition_id is not None:
|
|
687
|
+
return _run_sql_query(
|
|
688
|
+
SELECT_CONNECTOR_ROLLOUTS,
|
|
689
|
+
parameters={
|
|
690
|
+
"actor_definition_id": actor_definition_id,
|
|
691
|
+
"limit": limit,
|
|
692
|
+
},
|
|
693
|
+
query_name="SELECT_CONNECTOR_ROLLOUTS",
|
|
694
|
+
gsm_client=gsm_client,
|
|
695
|
+
)
|
|
696
|
+
|
|
697
|
+
# Default: return active rollouts if no filters specified
|
|
698
|
+
return _run_sql_query(
|
|
699
|
+
SELECT_ACTIVE_CONNECTOR_ROLLOUTS,
|
|
700
|
+
parameters={"limit": limit},
|
|
701
|
+
query_name="SELECT_ACTIVE_CONNECTOR_ROLLOUTS",
|
|
702
|
+
gsm_client=gsm_client,
|
|
703
|
+
)
|
|
704
|
+
|
|
705
|
+
|
|
706
|
+
def query_rollout_monitoring_stats(
|
|
707
|
+
rollout_id: str,
|
|
708
|
+
*,
|
|
709
|
+
gsm_client: secretmanager.SecretManagerServiceClient | None = None,
|
|
710
|
+
) -> dict[str, Any] | None:
|
|
711
|
+
"""Query aggregate monitoring stats for a rollout.
|
|
712
|
+
|
|
713
|
+
Returns counts of total actors, actors with any pin, and actors pinned
|
|
714
|
+
specifically to this rollout.
|
|
715
|
+
|
|
716
|
+
Args:
|
|
717
|
+
rollout_id: Rollout UUID to get stats for
|
|
718
|
+
gsm_client: GCP Secret Manager client. If None, a new client will be instantiated.
|
|
719
|
+
|
|
720
|
+
Returns:
|
|
721
|
+
Dict with rollout_id, actor_definition_id, num_actors, num_actors_pinned,
|
|
722
|
+
num_pinned_to_rollout, or None if rollout not found
|
|
723
|
+
"""
|
|
724
|
+
rows = _run_sql_query(
|
|
725
|
+
SELECT_ROLLOUT_AGGREGATE_STATS,
|
|
726
|
+
parameters={"rollout_id": rollout_id},
|
|
727
|
+
query_name="SELECT_ROLLOUT_AGGREGATE_STATS",
|
|
728
|
+
gsm_client=gsm_client,
|
|
729
|
+
)
|
|
730
|
+
# The SQL query uses scalar subqueries that always return one row,
|
|
731
|
+
# but with NULL values if the rollout doesn't exist
|
|
732
|
+
if rows and rows[0].get("rollout_id") is not None:
|
|
733
|
+
return rows[0]
|
|
734
|
+
return None
|
|
735
|
+
|
|
736
|
+
|
|
737
|
+
def query_rollout_actor_sync_stats(
|
|
738
|
+
rollout_id: str,
|
|
739
|
+
days_back: int = 7,
|
|
740
|
+
*,
|
|
741
|
+
gsm_client: secretmanager.SecretManagerServiceClient | None = None,
|
|
742
|
+
) -> list[dict[str, Any]]:
|
|
743
|
+
"""Query per-actor sync stats for actors pinned to a rollout.
|
|
744
|
+
|
|
745
|
+
Returns succeeded/failed job counts and connection counts for each actor
|
|
746
|
+
that is pinned to the specified rollout.
|
|
747
|
+
|
|
748
|
+
Args:
|
|
749
|
+
rollout_id: Rollout UUID to get actor stats for
|
|
750
|
+
days_back: Number of days to look back for job stats (default: 7)
|
|
751
|
+
gsm_client: GCP Secret Manager client. If None, a new client will be instantiated.
|
|
752
|
+
|
|
753
|
+
Returns:
|
|
754
|
+
List of dicts with actor_id, num_succeeded, num_failed, num_connections
|
|
755
|
+
"""
|
|
756
|
+
cutoff_date = datetime.now(timezone.utc) - timedelta(days=days_back)
|
|
757
|
+
return _run_sql_query(
|
|
758
|
+
SELECT_ROLLOUT_ACTOR_SYNC_STATS,
|
|
759
|
+
parameters={"rollout_id": rollout_id, "cutoff_date": cutoff_date},
|
|
760
|
+
query_name="SELECT_ROLLOUT_ACTOR_SYNC_STATS",
|
|
761
|
+
gsm_client=gsm_client,
|
|
762
|
+
)
|