forgexa-cli 1.80.0__tar.gz → 1.81.0__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.
- {forgexa_cli-1.80.0 → forgexa_cli-1.81.0}/PKG-INFO +1 -1
- {forgexa_cli-1.80.0 → forgexa_cli-1.81.0}/forgexa_cli/__init__.py +1 -1
- {forgexa_cli-1.80.0 → forgexa_cli-1.81.0}/forgexa_cli/daemon.py +1 -1
- {forgexa_cli-1.80.0 → forgexa_cli-1.81.0}/forgexa_cli/observability_contract.py +20 -14
- {forgexa_cli-1.80.0 → forgexa_cli-1.81.0}/forgexa_cli/observability_evidence.py +3 -1
- {forgexa_cli-1.80.0 → forgexa_cli-1.81.0}/forgexa_cli.egg-info/PKG-INFO +1 -1
- {forgexa_cli-1.80.0 → forgexa_cli-1.81.0}/pyproject.toml +1 -1
- {forgexa_cli-1.80.0 → forgexa_cli-1.81.0}/README.md +0 -0
- {forgexa_cli-1.80.0 → forgexa_cli-1.81.0}/forgexa_cli/_build_config.py +0 -0
- {forgexa_cli-1.80.0 → forgexa_cli-1.81.0}/forgexa_cli/_local_bind.py +0 -0
- {forgexa_cli-1.80.0 → forgexa_cli-1.81.0}/forgexa_cli/agent_core.py +0 -0
- {forgexa_cli-1.80.0 → forgexa_cli-1.81.0}/forgexa_cli/autoupgrade.py +0 -0
- {forgexa_cli-1.80.0 → forgexa_cli-1.81.0}/forgexa_cli/aws_evidence.py +0 -0
- {forgexa_cli-1.80.0 → forgexa_cli-1.81.0}/forgexa_cli/aws_logs_evidence.py +0 -0
- {forgexa_cli-1.80.0 → forgexa_cli-1.81.0}/forgexa_cli/main.py +0 -0
- {forgexa_cli-1.80.0 → forgexa_cli-1.81.0}/forgexa_cli/py.typed +0 -0
- {forgexa_cli-1.80.0 → forgexa_cli-1.81.0}/forgexa_cli/runtime_evidence.py +0 -0
- {forgexa_cli-1.80.0 → forgexa_cli-1.81.0}/forgexa_cli/zcode_protocol.py +0 -0
- {forgexa_cli-1.80.0 → forgexa_cli-1.81.0}/forgexa_cli.egg-info/SOURCES.txt +0 -0
- {forgexa_cli-1.80.0 → forgexa_cli-1.81.0}/forgexa_cli.egg-info/dependency_links.txt +0 -0
- {forgexa_cli-1.80.0 → forgexa_cli-1.81.0}/forgexa_cli.egg-info/entry_points.txt +0 -0
- {forgexa_cli-1.80.0 → forgexa_cli-1.81.0}/forgexa_cli.egg-info/requires.txt +0 -0
- {forgexa_cli-1.80.0 → forgexa_cli-1.81.0}/forgexa_cli.egg-info/top_level.txt +0 -0
- {forgexa_cli-1.80.0 → forgexa_cli-1.81.0}/setup.cfg +0 -0
- {forgexa_cli-1.80.0 → forgexa_cli-1.81.0}/tests/test_auth_and_runtime_commands.py +0 -0
- {forgexa_cli-1.80.0 → forgexa_cli-1.81.0}/tests/test_autoupgrade.py +0 -0
- {forgexa_cli-1.80.0 → forgexa_cli-1.81.0}/tests/test_check_command.py +0 -0
- {forgexa_cli-1.80.0 → forgexa_cli-1.81.0}/tests/test_expiry_warnings_and_revoke.py +0 -0
- {forgexa_cli-1.80.0 → forgexa_cli-1.81.0}/tests/test_local_bind_commands.py +0 -0
- {forgexa_cli-1.80.0 → forgexa_cli-1.81.0}/tests/test_runtime_credentials.py +0 -0
- {forgexa_cli-1.80.0 → forgexa_cli-1.81.0}/tests/test_session_credentials.py +0 -0
- {forgexa_cli-1.80.0 → forgexa_cli-1.81.0}/tests/test_silent_install.py +0 -0
- {forgexa_cli-1.80.0 → forgexa_cli-1.81.0}/tests/test_upgrade_observability.py +0 -0
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
"""forgexa-cli — Forgexa command-line client."""
|
|
2
|
-
__version__ = "1.
|
|
2
|
+
__version__ = "1.81.0"
|
|
@@ -1234,7 +1234,7 @@ except (ImportError, ModuleNotFoundError):
|
|
|
1234
1234
|
# DAEMON_VERSION is the protocol/logic version of the daemon code.
|
|
1235
1235
|
# Kept in sync with pyproject.toml version via bump-version.sh.
|
|
1236
1236
|
# CLIENT_TYPE identifies which packaging/distribution this daemon runs in.
|
|
1237
|
-
DAEMON_VERSION = "1.
|
|
1237
|
+
DAEMON_VERSION = "1.81.0"
|
|
1238
1238
|
|
|
1239
1239
|
|
|
1240
1240
|
def _detect_client_type() -> str:
|
|
@@ -9,7 +9,6 @@ def _strict_zip(*iterables):
|
|
|
9
9
|
if any((item is missing for item in items)):
|
|
10
10
|
raise ValueError('zip() arguments have different lengths')
|
|
11
11
|
yield items
|
|
12
|
-
import pycountry
|
|
13
12
|
from pydantic import BaseModel
|
|
14
13
|
from pydantic import ConfigDict
|
|
15
14
|
import math
|
|
@@ -24,6 +23,7 @@ from pydantic import model_serializer
|
|
|
24
23
|
from pydantic import model_validator
|
|
25
24
|
import json
|
|
26
25
|
from datetime import datetime
|
|
26
|
+
_ISO_COUNTRY_CODES = frozenset(('AD', 'AE', 'AF', 'AG', 'AI', 'AL', 'AM', 'AO', 'AQ', 'AR', 'AS', 'AT', 'AU', 'AW', 'AX', 'AZ', 'BA', 'BB', 'BD', 'BE', 'BF', 'BG', 'BH', 'BI', 'BJ', 'BL', 'BM', 'BN', 'BO', 'BQ', 'BR', 'BS', 'BT', 'BV', 'BW', 'BY', 'BZ', 'CA', 'CC', 'CD', 'CF', 'CG', 'CH', 'CI', 'CK', 'CL', 'CM', 'CN', 'CO', 'CR', 'CU', 'CV', 'CW', 'CX', 'CY', 'CZ', 'DE', 'DJ', 'DK', 'DM', 'DO', 'DZ', 'EC', 'EE', 'EG', 'EH', 'ER', 'ES', 'ET', 'FI', 'FJ', 'FK', 'FM', 'FO', 'FR', 'GA', 'GB', 'GD', 'GE', 'GF', 'GG', 'GH', 'GI', 'GL', 'GM', 'GN', 'GP', 'GQ', 'GR', 'GS', 'GT', 'GU', 'GW', 'GY', 'HK', 'HM', 'HN', 'HR', 'HT', 'HU', 'ID', 'IE', 'IL', 'IM', 'IN', 'IO', 'IQ', 'IR', 'IS', 'IT', 'JE', 'JM', 'JO', 'JP', 'KE', 'KG', 'KH', 'KI', 'KM', 'KN', 'KP', 'KR', 'KW', 'KY', 'KZ', 'LA', 'LB', 'LC', 'LI', 'LK', 'LR', 'LS', 'LT', 'LU', 'LV', 'LY', 'MA', 'MC', 'MD', 'ME', 'MF', 'MG', 'MH', 'MK', 'ML', 'MM', 'MN', 'MO', 'MP', 'MQ', 'MR', 'MS', 'MT', 'MU', 'MV', 'MW', 'MX', 'MY', 'MZ', 'NA', 'NC', 'NE', 'NF', 'NG', 'NI', 'NL', 'NO', 'NP', 'NR', 'NU', 'NZ', 'OM', 'PA', 'PE', 'PF', 'PG', 'PH', 'PK', 'PL', 'PM', 'PN', 'PR', 'PS', 'PT', 'PW', 'PY', 'QA', 'RE', 'RO', 'RS', 'RU', 'RW', 'SA', 'SB', 'SC', 'SD', 'SE', 'SG', 'SH', 'SI', 'SJ', 'SK', 'SL', 'SM', 'SN', 'SO', 'SR', 'SS', 'ST', 'SV', 'SX', 'SY', 'SZ', 'TC', 'TD', 'TF', 'TG', 'TH', 'TJ', 'TK', 'TL', 'TM', 'TN', 'TO', 'TR', 'TT', 'TV', 'TW', 'TZ', 'UA', 'UG', 'UM', 'US', 'UY', 'UZ', 'VA', 'VC', 'VE', 'VG', 'VI', 'VN', 'VU', 'WF', 'WS', 'YE', 'YT', 'ZA', 'ZM', 'ZW'))
|
|
27
27
|
Provider = Literal['mpulse', 'newrelic']
|
|
28
28
|
ResultType = Literal['summary', 'table', 'timeseries', 'histogram', 'distribution', 'records', 'span', 'trace', 'metadata']
|
|
29
29
|
Identifier = Annotated[str, Field(min_length=1, max_length=256, pattern='^[A-Za-z0-9_.:/-]+$')]
|
|
@@ -38,7 +38,7 @@ def unique_values(values: list) -> list:
|
|
|
38
38
|
return values
|
|
39
39
|
|
|
40
40
|
def validate_country_code(country: str) -> str:
|
|
41
|
-
if len(country) != 2 or not country.isupper() or
|
|
41
|
+
if len(country) != 2 or not country.isupper() or country not in _ISO_COUNTRY_CODES:
|
|
42
42
|
raise ValueError('Invalid ISO country code')
|
|
43
43
|
return country
|
|
44
44
|
|
|
@@ -192,7 +192,7 @@ class ObservabilityOrigin(ObservabilityModel):
|
|
|
192
192
|
_validate_issuer = field_validator('issuer')(validate_issuer)
|
|
193
193
|
|
|
194
194
|
class ObservabilityCoverageWindow(ObservabilityWindow):
|
|
195
|
-
window_index: int = Field(default=0, ge=0, le=
|
|
195
|
+
window_index: int = Field(default=0, ge=0, le=119, strict=True)
|
|
196
196
|
|
|
197
197
|
class ObservabilitySource(ObservabilityModel):
|
|
198
198
|
source_id: Identifier
|
|
@@ -200,7 +200,7 @@ class ObservabilitySource(ObservabilityModel):
|
|
|
200
200
|
connection_id: Identifier
|
|
201
201
|
environment: Identifier
|
|
202
202
|
endpoint_region: Identifier
|
|
203
|
-
scope_precision: Literal['dedicated', 'filtered']
|
|
203
|
+
scope_precision: Literal['dedicated', 'filtered', 'account']
|
|
204
204
|
origin_scope_ids: list[Identifier] = Field(min_length=1, max_length=100)
|
|
205
205
|
market_codes: list[str] = Field(default_factory=list, max_length=20)
|
|
206
206
|
application_id: Union[Identifier, None] = None
|
|
@@ -251,12 +251,18 @@ class ObservabilitySafeParameters(ObservabilityModel):
|
|
|
251
251
|
limit: Union[int, None] = Field(default=None, ge=1, le=5000, strict=True)
|
|
252
252
|
interval_seconds: Union[int, None] = Field(default=None, ge=1, strict=True)
|
|
253
253
|
workload_ids: Union[list[Identifier], None] = Field(default=None, min_length=1, max_length=1)
|
|
254
|
+
time_bucket: Union[Literal['day'], None] = None
|
|
255
|
+
timezone: Union[str, None] = Field(default=None, max_length=128)
|
|
254
256
|
|
|
255
257
|
@model_serializer(mode='wrap')
|
|
256
258
|
def serialize_optional_workloads(self, handler):
|
|
257
259
|
value = handler(self)
|
|
258
260
|
if self.workload_ids is None:
|
|
259
261
|
value.pop('workload_ids', None)
|
|
262
|
+
if self.time_bucket is None:
|
|
263
|
+
value.pop('time_bucket', None)
|
|
264
|
+
if self.timezone is None:
|
|
265
|
+
value.pop('timezone', None)
|
|
260
266
|
return value
|
|
261
267
|
|
|
262
268
|
@field_validator('filters', mode='before')
|
|
@@ -319,7 +325,7 @@ class ObservabilityMetricValue(ObservabilityWindow):
|
|
|
319
325
|
target_ref: Union[Identifier, None] = None
|
|
320
326
|
scope_id: Identifier
|
|
321
327
|
workload_id: Union[Identifier, None] = None
|
|
322
|
-
window_index: int = Field(default=0, ge=0, le=
|
|
328
|
+
window_index: int = Field(default=0, ge=0, le=119, strict=True)
|
|
323
329
|
metric_id: Identifier
|
|
324
330
|
definition_version: int = Field(ge=1, strict=True)
|
|
325
331
|
data_type: Identifier
|
|
@@ -354,7 +360,7 @@ class ObservabilityRow(ObservabilityModel):
|
|
|
354
360
|
kind: Literal['row', 'metadata']
|
|
355
361
|
item_id: Identifier
|
|
356
362
|
target_ref: Identifier
|
|
357
|
-
window_index: int = Field(default=0, ge=0, le=
|
|
363
|
+
window_index: int = Field(default=0, ge=0, le=119, strict=True)
|
|
358
364
|
values: dict[Identifier, CellValue] = Field(min_length=1, max_length=50)
|
|
359
365
|
|
|
360
366
|
class ObservabilityTimeBucket(ObservabilityWindow):
|
|
@@ -367,7 +373,7 @@ class ObservabilitySeries(ObservabilityModel):
|
|
|
367
373
|
kind: Literal['series']
|
|
368
374
|
item_id: Identifier
|
|
369
375
|
target_ref: Identifier
|
|
370
|
-
window_index: int = Field(default=0, ge=0, le=
|
|
376
|
+
window_index: int = Field(default=0, ge=0, le=119, strict=True)
|
|
371
377
|
field_id: Identifier
|
|
372
378
|
dimensions: dict[Identifier, CellValue] = Field(default_factory=dict, max_length=10)
|
|
373
379
|
native_unit: str = Field(min_length=1, max_length=128)
|
|
@@ -399,7 +405,7 @@ class ObservabilityHistory(ObservabilityModel):
|
|
|
399
405
|
kind: Literal['history'] = 'history'
|
|
400
406
|
item_id: Identifier
|
|
401
407
|
target_ref: Identifier
|
|
402
|
-
window_index: int = Field(default=0, ge=0, le=
|
|
408
|
+
window_index: int = Field(default=0, ge=0, le=119, strict=True)
|
|
403
409
|
field_id: Identifier
|
|
404
410
|
axis: Literal['sample_index'] = 'sample_index'
|
|
405
411
|
data_timezone: Union[str, None] = Field(default=None, max_length=128)
|
|
@@ -449,7 +455,7 @@ class ObservabilityDistribution(ObservabilityModel):
|
|
|
449
455
|
kind: Literal['distribution']
|
|
450
456
|
item_id: Identifier
|
|
451
457
|
target_ref: Identifier
|
|
452
|
-
window_index: int = Field(default=0, ge=0, le=
|
|
458
|
+
window_index: int = Field(default=0, ge=0, le=119, strict=True)
|
|
453
459
|
field_id: Identifier
|
|
454
460
|
measurement_unit: str = Field(min_length=1, max_length=128)
|
|
455
461
|
native_unit: Union[str, None] = Field(default=None, min_length=1, max_length=128)
|
|
@@ -470,7 +476,7 @@ class ObservabilitySpan(ObservabilityModel):
|
|
|
470
476
|
kind: Literal['span']
|
|
471
477
|
item_id: Identifier
|
|
472
478
|
target_ref: Identifier
|
|
473
|
-
window_index: int = Field(default=0, ge=0, le=
|
|
479
|
+
window_index: int = Field(default=0, ge=0, le=119, strict=True)
|
|
474
480
|
trace_id: Identifier
|
|
475
481
|
span_id: Identifier
|
|
476
482
|
parent_span_id: Union[Identifier, None] = None
|
|
@@ -481,7 +487,7 @@ class ObservabilityRedactedItem(ObservabilityModel):
|
|
|
481
487
|
kind: Literal['redacted']
|
|
482
488
|
item_id: Identifier
|
|
483
489
|
target_ref: Identifier
|
|
484
|
-
window_index: int = Field(default=0, ge=0, le=
|
|
490
|
+
window_index: int = Field(default=0, ge=0, le=119, strict=True)
|
|
485
491
|
original_kind: Literal['metric', 'series', 'history', 'distribution', 'span']
|
|
486
492
|
value_scope: Literal['whole_field_structure']
|
|
487
493
|
quality: Union[ObservabilityMetricQuality, None] = None
|
|
@@ -523,7 +529,7 @@ class ObservabilitySnapshotPayload(ObservabilityModel):
|
|
|
523
529
|
scope: ObservabilityFrozenScope
|
|
524
530
|
sources: list[ObservabilitySource] = Field(min_length=1, max_length=100)
|
|
525
531
|
parameters: ObservabilitySafeParameters
|
|
526
|
-
requested_windows: list[ObservabilityWindow] = Field(min_length=1, max_length=
|
|
532
|
+
requested_windows: list[ObservabilityWindow] = Field(min_length=1, max_length=120)
|
|
527
533
|
actual_windows: list[ObservabilityCoverageWindow] = Field(default_factory=list, max_length=500)
|
|
528
534
|
columns: list[ObservabilityColumn] = Field(min_length=1, max_length=50)
|
|
529
535
|
data: list[DataItem] = Field(max_length=50000)
|
|
@@ -550,11 +556,11 @@ class ObservabilitySnapshotPayload(ObservabilityModel):
|
|
|
550
556
|
for country in source.market_codes:
|
|
551
557
|
validate_country_code(country)
|
|
552
558
|
if self.integration_type == 'mpulse':
|
|
553
|
-
if not source.application_id or source.account_id is not None or source.entity_guid:
|
|
559
|
+
if not source.application_id or source.account_id is not None or source.entity_guid or (source.scope_precision == 'account'):
|
|
554
560
|
raise ValueError('observability_source_identity_invalid')
|
|
555
561
|
if source.endpoint_region != 'mpulse.soasta.com':
|
|
556
562
|
raise ValueError('observability_source_region_invalid')
|
|
557
|
-
elif source.application_id or source.account_id is None or (not source.entity_guid):
|
|
563
|
+
elif source.application_id or source.account_id is None or (source.scope_precision != 'account' and (not source.entity_guid)):
|
|
558
564
|
raise ValueError('observability_source_identity_invalid')
|
|
559
565
|
elif source.endpoint_region not in {'US', 'EU', 'JP'}:
|
|
560
566
|
raise ValueError('observability_source_region_invalid')
|
|
@@ -26,7 +26,9 @@ def _contract():
|
|
|
26
26
|
f"{__package__}.observability_contract" if __package__ else "observability_contract"
|
|
27
27
|
)
|
|
28
28
|
serialization = module
|
|
29
|
-
except ImportError:
|
|
29
|
+
except ImportError as error:
|
|
30
|
+
if getattr(error, "name", None) in {"pydantic", "pydantic_core"}:
|
|
31
|
+
raise EvidenceError("observability_evidence_runtime_dependency_missing") from None
|
|
30
32
|
raise EvidenceError("observability_evidence_protocol_unsupported") from None
|
|
31
33
|
return (
|
|
32
34
|
module.ObservabilityEvidenceReference, module.ObservabilityAttachmentMetadata,
|
|
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
|