onex-cli 1.10.2__tar.gz → 1.10.3__tar.gz
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.
- {onex_cli-1.10.2/onex_cli.egg-info → onex_cli-1.10.3}/PKG-INFO +1 -1
- {onex_cli-1.10.2 → onex_cli-1.10.3}/onex/__init__.py +1 -1
- {onex_cli-1.10.2 → onex_cli-1.10.3}/onex/mcp/server.py +82 -44
- {onex_cli-1.10.2 → onex_cli-1.10.3/onex_cli.egg-info}/PKG-INFO +1 -1
- {onex_cli-1.10.2 → onex_cli-1.10.3}/CHANGELOG.md +0 -0
- {onex_cli-1.10.2 → onex_cli-1.10.3}/LICENSE +0 -0
- {onex_cli-1.10.2 → onex_cli-1.10.3}/MANIFEST.in +0 -0
- {onex_cli-1.10.2 → onex_cli-1.10.3}/README.md +0 -0
- {onex_cli-1.10.2 → onex_cli-1.10.3}/onex/__main__.py +0 -0
- {onex_cli-1.10.2 → onex_cli-1.10.3}/onex/commands/__init__.py +0 -0
- {onex_cli-1.10.2 → onex_cli-1.10.3}/onex/commands/create.py +0 -0
- {onex_cli-1.10.2 → onex_cli-1.10.3}/onex/commands/create_e2e.py +0 -0
- {onex_cli-1.10.2 → onex_cli-1.10.3}/onex/commands/debug.py +0 -0
- {onex_cli-1.10.2 → onex_cli-1.10.3}/onex/commands/deploy.py +0 -0
- {onex_cli-1.10.2 → onex_cli-1.10.3}/onex/commands/dev.py +0 -0
- {onex_cli-1.10.2 → onex_cli-1.10.3}/onex/commands/env.py +0 -0
- {onex_cli-1.10.2 → onex_cli-1.10.3}/onex/commands/es.py +0 -0
- {onex_cli-1.10.2 → onex_cli-1.10.3}/onex/commands/init.py +0 -0
- {onex_cli-1.10.2 → onex_cli-1.10.3}/onex/commands/invoke.py +0 -0
- {onex_cli-1.10.2 → onex_cli-1.10.3}/onex/commands/login.py +0 -0
- {onex_cli-1.10.2 → onex_cli-1.10.3}/onex/commands/logout.py +0 -0
- {onex_cli-1.10.2 → onex_cli-1.10.3}/onex/commands/logs.py +0 -0
- {onex_cli-1.10.2 → onex_cli-1.10.3}/onex/commands/mcp.py +0 -0
- {onex_cli-1.10.2 → onex_cli-1.10.3}/onex/commands/platform.py +0 -0
- {onex_cli-1.10.2 → onex_cli-1.10.3}/onex/commands/provision.py +0 -0
- {onex_cli-1.10.2 → onex_cli-1.10.3}/onex/commands/reload.py +0 -0
- {onex_cli-1.10.2 → onex_cli-1.10.3}/onex/commands/replay.py +0 -0
- {onex_cli-1.10.2 → onex_cli-1.10.3}/onex/commands/status.py +0 -0
- {onex_cli-1.10.2 → onex_cli-1.10.3}/onex/commands/switch.py +0 -0
- {onex_cli-1.10.2 → onex_cli-1.10.3}/onex/commands/test.py +0 -0
- {onex_cli-1.10.2 → onex_cli-1.10.3}/onex/commands/trace.py +0 -0
- {onex_cli-1.10.2 → onex_cli-1.10.3}/onex/commands/undeploy.py +0 -0
- {onex_cli-1.10.2 → onex_cli-1.10.3}/onex/commands/validate.py +0 -0
- {onex_cli-1.10.2 → onex_cli-1.10.3}/onex/commands/vpn.py +0 -0
- {onex_cli-1.10.2 → onex_cli-1.10.3}/onex/config.py +0 -0
- {onex_cli-1.10.2 → onex_cli-1.10.3}/onex/mcp/__init__.py +0 -0
- {onex_cli-1.10.2 → onex_cli-1.10.3}/onex/mcp/tools/__init__.py +0 -0
- {onex_cli-1.10.2 → onex_cli-1.10.3}/onex/runtime/__init__.py +0 -0
- {onex_cli-1.10.2 → onex_cli-1.10.3}/onex/runtime/local_runtime.py +0 -0
- {onex_cli-1.10.2 → onex_cli-1.10.3}/onex/schema/__init__.py +0 -0
- {onex_cli-1.10.2 → onex_cli-1.10.3}/onex/schema/service_descriptor.py +0 -0
- {onex_cli-1.10.2 → onex_cli-1.10.3}/onex/schema/validator.py +0 -0
- {onex_cli-1.10.2 → onex_cli-1.10.3}/onex/templates/crud-service/README.md.j2 +0 -0
- {onex_cli-1.10.2 → onex_cli-1.10.3}/onex/templates/crud-service/__init__.py.j2 +0 -0
- {onex_cli-1.10.2 → onex_cli-1.10.3}/onex/templates/crud-service/service.yml.j2 +0 -0
- {onex_cli-1.10.2 → onex_cli-1.10.3}/onex/templates/crud-service/src/__init__.py.j2 +0 -0
- {onex_cli-1.10.2 → onex_cli-1.10.3}/onex/templates/crud-service/src/apis/__init__.py.j2 +0 -0
- {onex_cli-1.10.2 → onex_cli-1.10.3}/onex/templates/crud-service/src/models/__init__.py.j2 +0 -0
- {onex_cli-1.10.2 → onex_cli-1.10.3}/onex/templates/crud-service/src/models/schemas.py.j2 +0 -0
- {onex_cli-1.10.2 → onex_cli-1.10.3}/onex/templates/crud-service/src/repositories/__init__.py.j2 +0 -0
- {onex_cli-1.10.2 → onex_cli-1.10.3}/onex/templates/crud-service/src/services/__init__.py.j2 +0 -0
- {onex_cli-1.10.2 → onex_cli-1.10.3}/onex/templates/e2e/data_service.yml.j2 +0 -0
- {onex_cli-1.10.2 → onex_cli-1.10.3}/onex/templates/e2e/test_service_e2e.py.j2 +0 -0
- {onex_cli-1.10.2 → onex_cli-1.10.3}/onex/templates/event-driven/README.md.j2 +0 -0
- {onex_cli-1.10.2 → onex_cli-1.10.3}/onex/templates/event-driven/__init__.py.j2 +0 -0
- {onex_cli-1.10.2 → onex_cli-1.10.3}/onex/templates/event-driven/service.yml.j2 +0 -0
- {onex_cli-1.10.2 → onex_cli-1.10.3}/onex/templates/event-driven/src/__init__.py.j2 +0 -0
- {onex_cli-1.10.2 → onex_cli-1.10.3}/onex/templates/event-driven/src/triggers/__init__.py.j2 +0 -0
- {onex_cli-1.10.2 → onex_cli-1.10.3}/onex/templates/event-driven/src/triggers/events.py.j2 +0 -0
- {onex_cli-1.10.2 → onex_cli-1.10.3}/onex/templates/event-driven/src/triggers/schedules.py.j2 +0 -0
- {onex_cli-1.10.2 → onex_cli-1.10.3}/onex/templates/go-minimal/README.md.j2 +0 -0
- {onex_cli-1.10.2 → onex_cli-1.10.3}/onex/templates/go-minimal/go.mod.j2 +0 -0
- {onex_cli-1.10.2 → onex_cli-1.10.3}/onex/templates/go-minimal/main.go.j2 +0 -0
- {onex_cli-1.10.2 → onex_cli-1.10.3}/onex/templates/go-minimal/service.yml.j2 +0 -0
- {onex_cli-1.10.2 → onex_cli-1.10.3}/onex/templates/go-rest-api/README.md.j2 +0 -0
- {onex_cli-1.10.2 → onex_cli-1.10.3}/onex/templates/go-rest-api/go.mod.j2 +0 -0
- {onex_cli-1.10.2 → onex_cli-1.10.3}/onex/templates/go-rest-api/handlers/items.go.j2 +0 -0
- {onex_cli-1.10.2 → onex_cli-1.10.3}/onex/templates/go-rest-api/main.go.j2 +0 -0
- {onex_cli-1.10.2 → onex_cli-1.10.3}/onex/templates/go-rest-api/service.yml.j2 +0 -0
- {onex_cli-1.10.2 → onex_cli-1.10.3}/onex/templates/minimal/README.md.j2 +0 -0
- {onex_cli-1.10.2 → onex_cli-1.10.3}/onex/templates/minimal/__init__.py.j2 +0 -0
- {onex_cli-1.10.2 → onex_cli-1.10.3}/onex/templates/minimal/service.yml.j2 +0 -0
- {onex_cli-1.10.2 → onex_cli-1.10.3}/onex/templates/minimal/src/__init__.py.j2 +0 -0
- {onex_cli-1.10.2 → onex_cli-1.10.3}/onex/templates/minimal/src/apis/__init__.py.j2 +0 -0
- {onex_cli-1.10.2 → onex_cli-1.10.3}/onex/templates/minimal/src/apis/hello.py.j2 +0 -0
- {onex_cli-1.10.2 → onex_cli-1.10.3}/onex/templates/rest-api/README.md.j2 +0 -0
- {onex_cli-1.10.2 → onex_cli-1.10.3}/onex/templates/rest-api/__init__.py.j2 +0 -0
- {onex_cli-1.10.2 → onex_cli-1.10.3}/onex/templates/rest-api/service.yml.j2 +0 -0
- {onex_cli-1.10.2 → onex_cli-1.10.3}/onex/templates/rest-api/src/__init__.py.j2 +0 -0
- {onex_cli-1.10.2 → onex_cli-1.10.3}/onex/templates/rest-api/src/apis/__init__.py.j2 +0 -0
- {onex_cli-1.10.2 → onex_cli-1.10.3}/onex/templates/rest-api/src/apis/handlers.py.j2 +0 -0
- {onex_cli-1.10.2 → onex_cli-1.10.3}/onex/utils/__init__.py +0 -0
- {onex_cli-1.10.2 → onex_cli-1.10.3}/onex/utils/auth.py +0 -0
- {onex_cli-1.10.2 → onex_cli-1.10.3}/onex/utils/crypto.py +0 -0
- {onex_cli-1.10.2 → onex_cli-1.10.3}/onex/utils/email.py +0 -0
- {onex_cli-1.10.2 → onex_cli-1.10.3}/onex/utils/helpers.py +0 -0
- {onex_cli-1.10.2 → onex_cli-1.10.3}/onex/vpn/__init__.py +0 -0
- {onex_cli-1.10.2 → onex_cli-1.10.3}/onex/vpn/platform_detector.py +0 -0
- {onex_cli-1.10.2 → onex_cli-1.10.3}/onex/vpn/setup_vpn.py +0 -0
- {onex_cli-1.10.2 → onex_cli-1.10.3}/onex/vpn/wireguard_manager.py +0 -0
- {onex_cli-1.10.2 → onex_cli-1.10.3}/onex_cli.egg-info/SOURCES.txt +0 -0
- {onex_cli-1.10.2 → onex_cli-1.10.3}/onex_cli.egg-info/dependency_links.txt +0 -0
- {onex_cli-1.10.2 → onex_cli-1.10.3}/onex_cli.egg-info/entry_points.txt +0 -0
- {onex_cli-1.10.2 → onex_cli-1.10.3}/onex_cli.egg-info/requires.txt +0 -0
- {onex_cli-1.10.2 → onex_cli-1.10.3}/onex_cli.egg-info/top_level.txt +0 -0
- {onex_cli-1.10.2 → onex_cli-1.10.3}/setup.cfg +0 -0
- {onex_cli-1.10.2 → onex_cli-1.10.3}/setup.py +0 -0
- {onex_cli-1.10.2 → onex_cli-1.10.3}/tests/test_mcp_logs_e2e.py +0 -0
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
# OneXEOS Services CLI
|
|
2
|
-
__version__ = "1.10.
|
|
2
|
+
__version__ = "1.10.3"
|
|
@@ -425,45 +425,88 @@ async def onex_trace(
|
|
|
425
425
|
platform_url = _get_platform_url(env)
|
|
426
426
|
|
|
427
427
|
try:
|
|
428
|
-
#
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
resp = await _authenticated_request(
|
|
433
|
-
'get',
|
|
434
|
-
f"{platform_url}/_internal/trace/{trace_id}",
|
|
435
|
-
env,
|
|
436
|
-
timeout=15
|
|
437
|
-
)
|
|
438
|
-
if resp.status_code != 503 or attempt == 1:
|
|
439
|
-
break
|
|
440
|
-
import asyncio
|
|
441
|
-
await asyncio.sleep(2)
|
|
442
|
-
except httpx.TimeoutException:
|
|
443
|
-
if attempt == 1:
|
|
444
|
-
return f"Request timed out connecting to {platform_url} after retries"
|
|
445
|
-
import asyncio
|
|
446
|
-
await asyncio.sleep(2)
|
|
447
|
-
|
|
448
|
-
if resp is None:
|
|
449
|
-
return f"Request timed out connecting to {platform_url}"
|
|
428
|
+
# Query Loki directly — bypasses gateway auth and its internal Loki timeout
|
|
429
|
+
from urllib.parse import urlparse
|
|
430
|
+
parsed = urlparse(platform_url)
|
|
431
|
+
loki_url = f"http://{parsed.hostname}:3100"
|
|
450
432
|
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
433
|
+
from datetime import datetime, timedelta
|
|
434
|
+
now = datetime.now()
|
|
435
|
+
start_ns = int((now - timedelta(hours=24)).timestamp() * 1e9)
|
|
436
|
+
end_ns = int(now.timestamp() * 1e9)
|
|
437
|
+
query = f'{{trace_id="{trace_id}"}}'
|
|
455
438
|
|
|
456
|
-
|
|
457
|
-
|
|
439
|
+
async with httpx.AsyncClient(timeout=10) as client:
|
|
440
|
+
resp = await client.get(
|
|
441
|
+
f"{loki_url}/loki/api/v1/query_range",
|
|
442
|
+
params={
|
|
443
|
+
'query': query,
|
|
444
|
+
'start': str(start_ns),
|
|
445
|
+
'end': str(end_ns),
|
|
446
|
+
'limit': 1000
|
|
447
|
+
}
|
|
448
|
+
)
|
|
458
449
|
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
450
|
+
if resp.status_code != 200:
|
|
451
|
+
return f"Loki query failed: HTTP {resp.status_code}"
|
|
452
|
+
|
|
453
|
+
loki_data = resp.json()
|
|
454
|
+
if loki_data.get('status') != 'success':
|
|
455
|
+
return f"Loki query failed: {loki_data}"
|
|
456
|
+
|
|
457
|
+
# Parse Loki results into timeline format
|
|
458
|
+
results = loki_data.get('data', {}).get('result', [])
|
|
459
|
+
timeline = []
|
|
460
|
+
for result in results:
|
|
461
|
+
stream = result.get('stream', {})
|
|
462
|
+
for value in result.get('values', []):
|
|
463
|
+
timestamp_ns, log_line = value
|
|
464
|
+
try:
|
|
465
|
+
log_data = json.loads(log_line)
|
|
466
|
+
except Exception:
|
|
467
|
+
log_data = {'message': log_line}
|
|
468
|
+
|
|
469
|
+
component = stream.get('component') or stream.get('service') or log_data.get('service') or 'unknown'
|
|
470
|
+
log_event = stream.get('log_event') or stream.get('event', '')
|
|
471
|
+
method = stream.get('method', log_data.get('method', ''))
|
|
472
|
+
path = stream.get('path', log_data.get('path', ''))
|
|
473
|
+
message = log_data.get('message', log_line)
|
|
474
|
+
status_code = log_data.get('status_code')
|
|
475
|
+
duration_ms = log_data.get('duration_ms') or log_data.get('execution_time_ms')
|
|
476
|
+
error = log_data.get('error')
|
|
477
|
+
if not error and message and ' | ' in message:
|
|
478
|
+
error = message.split(' | ', 1)[1]
|
|
479
|
+
|
|
480
|
+
timeline.append({
|
|
481
|
+
'timestamp': int(timestamp_ns) // 1000000,
|
|
482
|
+
'component': component,
|
|
483
|
+
'level': stream.get('level', log_data.get('level', 'INFO')).upper(),
|
|
484
|
+
'event': log_data.get('event', log_event),
|
|
485
|
+
'message': message,
|
|
486
|
+
'method': method,
|
|
487
|
+
'path': path,
|
|
488
|
+
'status_code': status_code,
|
|
489
|
+
'duration_ms': duration_ms,
|
|
490
|
+
'error': error,
|
|
491
|
+
'data': log_data,
|
|
492
|
+
})
|
|
493
|
+
|
|
494
|
+
timeline.sort(key=lambda x: x['timestamp'])
|
|
495
|
+
total_logs = len(timeline)
|
|
496
|
+
|
|
497
|
+
data = {'trace_id': trace_id, 'total_logs': total_logs, 'timeline': timeline}
|
|
498
|
+
|
|
499
|
+
if json_output:
|
|
500
|
+
return json.dumps(data, indent=2)
|
|
501
|
+
|
|
502
|
+
if total_logs == 0:
|
|
503
|
+
return (
|
|
504
|
+
f"No logs found for trace_id: {trace_id}\n"
|
|
505
|
+
"This could mean:\n"
|
|
506
|
+
" - Request hasn't been processed yet\n"
|
|
507
|
+
" - Trace_id is incorrect\n"
|
|
508
|
+
" - Logs have expired (older than 24 hours)"
|
|
509
|
+
)
|
|
467
510
|
|
|
468
511
|
# Extract request metadata from first/last logs
|
|
469
512
|
req_method = ''
|
|
@@ -590,15 +633,10 @@ async def onex_trace(
|
|
|
590
633
|
|
|
591
634
|
return "\n".join(lines)
|
|
592
635
|
|
|
593
|
-
elif resp.status_code == 401:
|
|
594
|
-
return f"Authentication failed. Run: onex login --env {env}"
|
|
595
|
-
elif resp.status_code == 503:
|
|
596
|
-
return "Loki service unavailable. Make sure observability stack is running."
|
|
597
|
-
else:
|
|
598
|
-
return f"Failed to query trace: HTTP {resp.status_code}"
|
|
599
|
-
|
|
600
636
|
except httpx.ConnectError:
|
|
601
|
-
return f"Cannot connect to
|
|
637
|
+
return f"Cannot connect to Loki at {loki_url}. Make sure observability stack is running."
|
|
638
|
+
except httpx.TimeoutException:
|
|
639
|
+
return f"Loki query timed out at {loki_url}. Loki may be overloaded."
|
|
602
640
|
except Exception as e:
|
|
603
641
|
return f"Error querying trace: {e}"
|
|
604
642
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{onex_cli-1.10.2 → onex_cli-1.10.3}/onex/templates/crud-service/src/repositories/__init__.py.j2
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{onex_cli-1.10.2 → onex_cli-1.10.3}/onex/templates/event-driven/src/triggers/schedules.py.j2
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|