pltr-cli 0.11.0__py3-none-any.whl → 0.12.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.
- pltr/__init__.py +1 -1
- pltr/cli.py +16 -0
- pltr/commands/admin.py +553 -9
- pltr/commands/aip_agents.py +333 -0
- pltr/commands/connectivity.py +309 -1
- pltr/commands/cp.py +103 -0
- pltr/commands/dataset.py +104 -4
- pltr/commands/mediasets.py +176 -0
- pltr/commands/ontology.py +44 -13
- pltr/commands/orchestration.py +167 -11
- pltr/commands/project.py +249 -0
- pltr/commands/resource.py +452 -0
- pltr/commands/sql.py +54 -7
- pltr/commands/third_party_applications.py +82 -0
- pltr/services/admin.py +318 -1
- pltr/services/aip_agents.py +147 -0
- pltr/services/base.py +104 -1
- pltr/services/connectivity.py +139 -0
- pltr/services/copy.py +391 -0
- pltr/services/dataset.py +75 -1
- pltr/services/mediasets.py +144 -9
- pltr/services/ontology.py +48 -1
- pltr/services/orchestration.py +133 -1
- pltr/services/project.py +136 -0
- pltr/services/resource.py +227 -0
- pltr/services/sql.py +44 -20
- pltr/services/third_party_applications.py +53 -0
- pltr/utils/formatting.py +195 -1
- pltr/utils/pagination.py +325 -0
- {pltr_cli-0.11.0.dist-info → pltr_cli-0.12.0.dist-info}/METADATA +5 -3
- pltr_cli-0.12.0.dist-info/RECORD +62 -0
- {pltr_cli-0.11.0.dist-info → pltr_cli-0.12.0.dist-info}/WHEEL +1 -1
- pltr_cli-0.11.0.dist-info/RECORD +0 -55
- {pltr_cli-0.11.0.dist-info → pltr_cli-0.12.0.dist-info}/entry_points.txt +0 -0
- {pltr_cli-0.11.0.dist-info → pltr_cli-0.12.0.dist-info}/licenses/LICENSE +0 -0
pltr/__init__.py
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
__version__ = "0.
|
|
1
|
+
__version__ = "0.12.0"
|
pltr/cli.py
CHANGED
|
@@ -24,7 +24,10 @@ from pltr.commands import (
|
|
|
24
24
|
alias,
|
|
25
25
|
mediasets,
|
|
26
26
|
connectivity,
|
|
27
|
+
third_party_applications,
|
|
28
|
+
aip_agents,
|
|
27
29
|
)
|
|
30
|
+
from pltr.commands.cp import cp_command
|
|
28
31
|
|
|
29
32
|
app = typer.Typer(
|
|
30
33
|
name="pltr",
|
|
@@ -54,6 +57,16 @@ app.add_typer(
|
|
|
54
57
|
app.add_typer(
|
|
55
58
|
connectivity.app, name="connectivity", help="Manage connections and data imports"
|
|
56
59
|
)
|
|
60
|
+
app.add_typer(
|
|
61
|
+
third_party_applications.app,
|
|
62
|
+
name="third-party-apps",
|
|
63
|
+
help="Manage third-party applications",
|
|
64
|
+
)
|
|
65
|
+
app.add_typer(
|
|
66
|
+
aip_agents.app,
|
|
67
|
+
name="aip-agents",
|
|
68
|
+
help="Manage AIP Agents, sessions, and versions",
|
|
69
|
+
)
|
|
57
70
|
app.add_typer(
|
|
58
71
|
admin.app,
|
|
59
72
|
name="admin",
|
|
@@ -62,6 +75,9 @@ app.add_typer(
|
|
|
62
75
|
app.add_typer(shell.shell_app, name="shell", help="Interactive shell mode")
|
|
63
76
|
app.add_typer(completion.app, name="completion", help="Manage shell completions")
|
|
64
77
|
app.add_typer(alias.app, name="alias", help="Manage command aliases")
|
|
78
|
+
app.command("cp", help="Copy datasets or folders into another Compass folder")(
|
|
79
|
+
cp_command
|
|
80
|
+
)
|
|
65
81
|
|
|
66
82
|
|
|
67
83
|
def version_callback(value: bool):
|
pltr/commands/admin.py
CHANGED
|
@@ -4,7 +4,7 @@ Provides commands for user, group, role, and organization management.
|
|
|
4
4
|
"""
|
|
5
5
|
|
|
6
6
|
from pathlib import Path
|
|
7
|
-
from typing import Optional
|
|
7
|
+
from typing import List, Optional
|
|
8
8
|
|
|
9
9
|
import typer
|
|
10
10
|
from rich.console import Console
|
|
@@ -12,6 +12,7 @@ from rich.console import Console
|
|
|
12
12
|
from ..services.admin import AdminService
|
|
13
13
|
from ..utils.formatting import OutputFormatter
|
|
14
14
|
from ..utils.progress import SpinnerProgressTracker
|
|
15
|
+
from ..utils.pagination import PaginationConfig
|
|
15
16
|
|
|
16
17
|
# Create the main admin app
|
|
17
18
|
app = typer.Typer(
|
|
@@ -23,12 +24,14 @@ user_app = typer.Typer(name="user", help="User management operations")
|
|
|
23
24
|
group_app = typer.Typer(name="group", help="Group management operations")
|
|
24
25
|
role_app = typer.Typer(name="role", help="Role management operations")
|
|
25
26
|
org_app = typer.Typer(name="org", help="Organization management operations")
|
|
27
|
+
marking_app = typer.Typer(name="marking", help="Marking management operations")
|
|
26
28
|
|
|
27
29
|
# Add sub-apps to main admin app
|
|
28
30
|
app.add_typer(user_app, name="user")
|
|
29
31
|
app.add_typer(group_app, name="group")
|
|
30
32
|
app.add_typer(role_app, name="role")
|
|
31
33
|
app.add_typer(org_app, name="org")
|
|
34
|
+
app.add_typer(marking_app, name="marking")
|
|
32
35
|
|
|
33
36
|
|
|
34
37
|
# User Management Commands
|
|
@@ -44,28 +47,60 @@ def list_users(
|
|
|
44
47
|
None, "--output", help="Save results to file"
|
|
45
48
|
),
|
|
46
49
|
page_size: Optional[int] = typer.Option(
|
|
47
|
-
None, "--page-size", help="Number of users per page"
|
|
50
|
+
None, "--page-size", help="Number of users per page (default: from settings)"
|
|
51
|
+
),
|
|
52
|
+
max_pages: Optional[int] = typer.Option(
|
|
53
|
+
1, "--max-pages", help="Maximum number of pages to fetch (default: 1)"
|
|
48
54
|
),
|
|
49
55
|
page_token: Optional[str] = typer.Option(
|
|
50
|
-
None, "--page-token", help="
|
|
56
|
+
None, "--page-token", help="Page token to resume from previous response"
|
|
57
|
+
),
|
|
58
|
+
all: bool = typer.Option(
|
|
59
|
+
False, "--all", help="Fetch all available pages (overrides --max-pages)"
|
|
51
60
|
),
|
|
52
61
|
) -> None:
|
|
53
|
-
"""
|
|
62
|
+
"""
|
|
63
|
+
List users in the organization with pagination support.
|
|
64
|
+
|
|
65
|
+
By default, fetches only the first page of results. Use --all to fetch all users,
|
|
66
|
+
or --max-pages to control how many pages to fetch.
|
|
67
|
+
|
|
68
|
+
Examples:
|
|
69
|
+
# List first page of users (default)
|
|
70
|
+
pltr admin user list
|
|
71
|
+
|
|
72
|
+
# List all users
|
|
73
|
+
pltr admin user list --all
|
|
74
|
+
|
|
75
|
+
# List first 3 pages
|
|
76
|
+
pltr admin user list --max-pages 3
|
|
77
|
+
|
|
78
|
+
# Resume from a specific page
|
|
79
|
+
pltr admin user list --page-token abc123
|
|
80
|
+
"""
|
|
54
81
|
console = Console()
|
|
55
82
|
formatter = OutputFormatter()
|
|
56
83
|
|
|
57
84
|
try:
|
|
58
85
|
service = AdminService(profile=profile)
|
|
59
86
|
|
|
87
|
+
# Create pagination config
|
|
88
|
+
config = PaginationConfig(
|
|
89
|
+
page_size=page_size,
|
|
90
|
+
max_pages=max_pages,
|
|
91
|
+
page_token=page_token,
|
|
92
|
+
fetch_all=all,
|
|
93
|
+
)
|
|
94
|
+
|
|
60
95
|
with SpinnerProgressTracker().track_spinner("Fetching users..."):
|
|
61
|
-
result = service.
|
|
96
|
+
result = service.list_users_paginated(config)
|
|
62
97
|
|
|
63
|
-
# Format and display results
|
|
98
|
+
# Format and display paginated results
|
|
64
99
|
if output_file:
|
|
65
|
-
formatter.
|
|
66
|
-
console.print(f"Results saved to {output_file}")
|
|
100
|
+
formatter.format_paginated_output(result, output_format, str(output_file))
|
|
101
|
+
console.print(f"[green]Results saved to {output_file}[/green]")
|
|
67
102
|
else:
|
|
68
|
-
formatter.
|
|
103
|
+
formatter.format_paginated_output(result, output_format)
|
|
69
104
|
|
|
70
105
|
except Exception as e:
|
|
71
106
|
console.print(f"[red]Error:[/red] {e}")
|
|
@@ -258,6 +293,78 @@ def revoke_user_tokens(
|
|
|
258
293
|
raise typer.Exit(code=1)
|
|
259
294
|
|
|
260
295
|
|
|
296
|
+
@user_app.command("delete")
|
|
297
|
+
def delete_user(
|
|
298
|
+
user_id: str = typer.Argument(..., help="User ID or RID"),
|
|
299
|
+
profile: Optional[str] = typer.Option(
|
|
300
|
+
None, "--profile", help="Auth profile to use"
|
|
301
|
+
),
|
|
302
|
+
confirm: bool = typer.Option(False, "--confirm", help="Skip confirmation prompt"),
|
|
303
|
+
) -> None:
|
|
304
|
+
"""Delete a specific user."""
|
|
305
|
+
console = Console()
|
|
306
|
+
|
|
307
|
+
# Confirmation prompt
|
|
308
|
+
if not confirm:
|
|
309
|
+
user_confirm = typer.confirm(f"Are you sure you want to delete user {user_id}?")
|
|
310
|
+
if not user_confirm:
|
|
311
|
+
console.print("Operation cancelled.")
|
|
312
|
+
return
|
|
313
|
+
|
|
314
|
+
try:
|
|
315
|
+
service = AdminService(profile=profile)
|
|
316
|
+
|
|
317
|
+
with SpinnerProgressTracker().track_spinner(f"Deleting user {user_id}..."):
|
|
318
|
+
result = service.delete_user(user_id)
|
|
319
|
+
|
|
320
|
+
console.print(f"[green]{result['message']}[/green]")
|
|
321
|
+
|
|
322
|
+
except Exception as e:
|
|
323
|
+
console.print(f"[red]Error:[/red] {e}")
|
|
324
|
+
raise typer.Exit(code=1)
|
|
325
|
+
|
|
326
|
+
|
|
327
|
+
@user_app.command("batch-get")
|
|
328
|
+
def batch_get_users(
|
|
329
|
+
user_ids: List[str] = typer.Argument(
|
|
330
|
+
..., help="User IDs or RIDs (space-separated, max 500)"
|
|
331
|
+
),
|
|
332
|
+
profile: Optional[str] = typer.Option(
|
|
333
|
+
None, "--profile", help="Auth profile to use"
|
|
334
|
+
),
|
|
335
|
+
output_format: str = typer.Option(
|
|
336
|
+
"table", "--format", help="Output format (table, json, csv)"
|
|
337
|
+
),
|
|
338
|
+
output_file: Optional[Path] = typer.Option(
|
|
339
|
+
None, "--output", help="Save results to file"
|
|
340
|
+
),
|
|
341
|
+
) -> None:
|
|
342
|
+
"""Batch retrieve multiple users (max 500)."""
|
|
343
|
+
console = Console()
|
|
344
|
+
formatter = OutputFormatter()
|
|
345
|
+
|
|
346
|
+
try:
|
|
347
|
+
service = AdminService(profile=profile)
|
|
348
|
+
|
|
349
|
+
with SpinnerProgressTracker().track_spinner(
|
|
350
|
+
f"Fetching {len(user_ids)} users..."
|
|
351
|
+
):
|
|
352
|
+
result = service.get_batch_users(user_ids)
|
|
353
|
+
|
|
354
|
+
if output_file:
|
|
355
|
+
formatter.save_to_file(result, output_file, output_format)
|
|
356
|
+
console.print(f"Results saved to {output_file}")
|
|
357
|
+
else:
|
|
358
|
+
formatter.display(result, output_format)
|
|
359
|
+
|
|
360
|
+
except ValueError as e:
|
|
361
|
+
console.print(f"[red]Error:[/red] {e}")
|
|
362
|
+
raise typer.Exit(code=1)
|
|
363
|
+
except Exception as e:
|
|
364
|
+
console.print(f"[red]Error:[/red] {e}")
|
|
365
|
+
raise typer.Exit(code=1)
|
|
366
|
+
|
|
367
|
+
|
|
261
368
|
# Group Management Commands
|
|
262
369
|
@group_app.command("list")
|
|
263
370
|
def list_groups(
|
|
@@ -456,6 +563,47 @@ def delete_group(
|
|
|
456
563
|
raise typer.Exit(code=1)
|
|
457
564
|
|
|
458
565
|
|
|
566
|
+
@group_app.command("batch-get")
|
|
567
|
+
def batch_get_groups(
|
|
568
|
+
group_ids: List[str] = typer.Argument(
|
|
569
|
+
..., help="Group IDs or RIDs (space-separated, max 500)"
|
|
570
|
+
),
|
|
571
|
+
profile: Optional[str] = typer.Option(
|
|
572
|
+
None, "--profile", help="Auth profile to use"
|
|
573
|
+
),
|
|
574
|
+
output_format: str = typer.Option(
|
|
575
|
+
"table", "--format", help="Output format (table, json, csv)"
|
|
576
|
+
),
|
|
577
|
+
output_file: Optional[Path] = typer.Option(
|
|
578
|
+
None, "--output", help="Save results to file"
|
|
579
|
+
),
|
|
580
|
+
) -> None:
|
|
581
|
+
"""Batch retrieve multiple groups (max 500)."""
|
|
582
|
+
console = Console()
|
|
583
|
+
formatter = OutputFormatter()
|
|
584
|
+
|
|
585
|
+
try:
|
|
586
|
+
service = AdminService(profile=profile)
|
|
587
|
+
|
|
588
|
+
with SpinnerProgressTracker().track_spinner(
|
|
589
|
+
f"Fetching {len(group_ids)} groups..."
|
|
590
|
+
):
|
|
591
|
+
result = service.get_batch_groups(group_ids)
|
|
592
|
+
|
|
593
|
+
if output_file:
|
|
594
|
+
formatter.save_to_file(result, output_file, output_format)
|
|
595
|
+
console.print(f"Results saved to {output_file}")
|
|
596
|
+
else:
|
|
597
|
+
formatter.display(result, output_format)
|
|
598
|
+
|
|
599
|
+
except ValueError as e:
|
|
600
|
+
console.print(f"[red]Error:[/red] {e}")
|
|
601
|
+
raise typer.Exit(code=1)
|
|
602
|
+
except Exception as e:
|
|
603
|
+
console.print(f"[red]Error:[/red] {e}")
|
|
604
|
+
raise typer.Exit(code=1)
|
|
605
|
+
|
|
606
|
+
|
|
459
607
|
# Role Management Commands
|
|
460
608
|
@role_app.command("get")
|
|
461
609
|
def get_role(
|
|
@@ -492,6 +640,47 @@ def get_role(
|
|
|
492
640
|
raise typer.Exit(code=1)
|
|
493
641
|
|
|
494
642
|
|
|
643
|
+
@role_app.command("batch-get")
|
|
644
|
+
def batch_get_roles(
|
|
645
|
+
role_ids: List[str] = typer.Argument(
|
|
646
|
+
..., help="Role IDs or RIDs (space-separated, max 500)"
|
|
647
|
+
),
|
|
648
|
+
profile: Optional[str] = typer.Option(
|
|
649
|
+
None, "--profile", help="Auth profile to use"
|
|
650
|
+
),
|
|
651
|
+
output_format: str = typer.Option(
|
|
652
|
+
"table", "--format", help="Output format (table, json, csv)"
|
|
653
|
+
),
|
|
654
|
+
output_file: Optional[Path] = typer.Option(
|
|
655
|
+
None, "--output", help="Save results to file"
|
|
656
|
+
),
|
|
657
|
+
) -> None:
|
|
658
|
+
"""Batch retrieve multiple roles (max 500)."""
|
|
659
|
+
console = Console()
|
|
660
|
+
formatter = OutputFormatter()
|
|
661
|
+
|
|
662
|
+
try:
|
|
663
|
+
service = AdminService(profile=profile)
|
|
664
|
+
|
|
665
|
+
with SpinnerProgressTracker().track_spinner(
|
|
666
|
+
f"Fetching {len(role_ids)} roles..."
|
|
667
|
+
):
|
|
668
|
+
result = service.get_batch_roles(role_ids)
|
|
669
|
+
|
|
670
|
+
if output_file:
|
|
671
|
+
formatter.save_to_file(result, output_file, output_format)
|
|
672
|
+
console.print(f"Results saved to {output_file}")
|
|
673
|
+
else:
|
|
674
|
+
formatter.display(result, output_format)
|
|
675
|
+
|
|
676
|
+
except ValueError as e:
|
|
677
|
+
console.print(f"[red]Error:[/red] {e}")
|
|
678
|
+
raise typer.Exit(code=1)
|
|
679
|
+
except Exception as e:
|
|
680
|
+
console.print(f"[red]Error:[/red] {e}")
|
|
681
|
+
raise typer.Exit(code=1)
|
|
682
|
+
|
|
683
|
+
|
|
495
684
|
# Organization Management Commands
|
|
496
685
|
@org_app.command("get")
|
|
497
686
|
def get_organization(
|
|
@@ -528,3 +717,358 @@ def get_organization(
|
|
|
528
717
|
except Exception as e:
|
|
529
718
|
console.print(f"[red]Error:[/red] {e}")
|
|
530
719
|
raise typer.Exit(code=1)
|
|
720
|
+
|
|
721
|
+
|
|
722
|
+
@org_app.command("create")
|
|
723
|
+
def create_organization(
|
|
724
|
+
name: str = typer.Argument(..., help="Organization name"),
|
|
725
|
+
enrollment_rid: str = typer.Option(..., "--enrollment-rid", help="Enrollment RID"),
|
|
726
|
+
profile: Optional[str] = typer.Option(
|
|
727
|
+
None, "--profile", help="Auth profile to use"
|
|
728
|
+
),
|
|
729
|
+
admin_ids: Optional[List[str]] = typer.Option(
|
|
730
|
+
None, "--admin-id", help="Admin user IDs (can specify multiple)"
|
|
731
|
+
),
|
|
732
|
+
output_format: str = typer.Option(
|
|
733
|
+
"table", "--format", help="Output format (table, json, csv)"
|
|
734
|
+
),
|
|
735
|
+
output_file: Optional[Path] = typer.Option(
|
|
736
|
+
None, "--output", help="Save results to file"
|
|
737
|
+
),
|
|
738
|
+
) -> None:
|
|
739
|
+
"""Create a new organization."""
|
|
740
|
+
console = Console()
|
|
741
|
+
formatter = OutputFormatter()
|
|
742
|
+
|
|
743
|
+
try:
|
|
744
|
+
service = AdminService(profile=profile)
|
|
745
|
+
|
|
746
|
+
with SpinnerProgressTracker().track_spinner(
|
|
747
|
+
f"Creating organization '{name}'..."
|
|
748
|
+
):
|
|
749
|
+
result = service.create_organization(
|
|
750
|
+
name=name, enrollment_rid=enrollment_rid, admin_ids=admin_ids
|
|
751
|
+
)
|
|
752
|
+
|
|
753
|
+
if output_file:
|
|
754
|
+
formatter.save_to_file(result, output_file, output_format)
|
|
755
|
+
console.print(f"Results saved to {output_file}")
|
|
756
|
+
else:
|
|
757
|
+
formatter.display(result, output_format)
|
|
758
|
+
console.print(f"[green]Organization '{name}' created successfully[/green]")
|
|
759
|
+
|
|
760
|
+
except Exception as e:
|
|
761
|
+
console.print(f"[red]Error:[/red] {e}")
|
|
762
|
+
raise typer.Exit(code=1)
|
|
763
|
+
|
|
764
|
+
|
|
765
|
+
@org_app.command("replace")
|
|
766
|
+
def replace_organization(
|
|
767
|
+
organization_rid: str = typer.Argument(..., help="Organization RID"),
|
|
768
|
+
name: str = typer.Argument(..., help="New organization name"),
|
|
769
|
+
profile: Optional[str] = typer.Option(
|
|
770
|
+
None, "--profile", help="Auth profile to use"
|
|
771
|
+
),
|
|
772
|
+
description: Optional[str] = typer.Option(
|
|
773
|
+
None, "--description", help="New organization description"
|
|
774
|
+
),
|
|
775
|
+
output_format: str = typer.Option(
|
|
776
|
+
"table", "--format", help="Output format (table, json, csv)"
|
|
777
|
+
),
|
|
778
|
+
output_file: Optional[Path] = typer.Option(
|
|
779
|
+
None, "--output", help="Save results to file"
|
|
780
|
+
),
|
|
781
|
+
confirm: bool = typer.Option(False, "--confirm", help="Skip confirmation prompt"),
|
|
782
|
+
) -> None:
|
|
783
|
+
"""Replace/update an existing organization."""
|
|
784
|
+
console = Console()
|
|
785
|
+
formatter = OutputFormatter()
|
|
786
|
+
|
|
787
|
+
if not confirm:
|
|
788
|
+
user_confirm = typer.confirm(
|
|
789
|
+
f"Are you sure you want to replace organization {organization_rid}?"
|
|
790
|
+
)
|
|
791
|
+
if not user_confirm:
|
|
792
|
+
console.print("Operation cancelled.")
|
|
793
|
+
return
|
|
794
|
+
|
|
795
|
+
try:
|
|
796
|
+
service = AdminService(profile=profile)
|
|
797
|
+
|
|
798
|
+
with SpinnerProgressTracker().track_spinner(
|
|
799
|
+
f"Replacing organization {organization_rid}..."
|
|
800
|
+
):
|
|
801
|
+
result = service.replace_organization(
|
|
802
|
+
organization_rid=organization_rid, name=name, description=description
|
|
803
|
+
)
|
|
804
|
+
|
|
805
|
+
if output_file:
|
|
806
|
+
formatter.save_to_file(result, output_file, output_format)
|
|
807
|
+
console.print(f"Results saved to {output_file}")
|
|
808
|
+
else:
|
|
809
|
+
formatter.display(result, output_format)
|
|
810
|
+
console.print(
|
|
811
|
+
f"[green]Organization '{organization_rid}' replaced successfully[/green]"
|
|
812
|
+
)
|
|
813
|
+
|
|
814
|
+
except Exception as e:
|
|
815
|
+
console.print(f"[red]Error:[/red] {e}")
|
|
816
|
+
raise typer.Exit(code=1)
|
|
817
|
+
|
|
818
|
+
|
|
819
|
+
@org_app.command("available-roles")
|
|
820
|
+
def list_available_roles(
|
|
821
|
+
organization_rid: str = typer.Argument(..., help="Organization RID"),
|
|
822
|
+
profile: Optional[str] = typer.Option(
|
|
823
|
+
None, "--profile", help="Auth profile to use"
|
|
824
|
+
),
|
|
825
|
+
output_format: str = typer.Option(
|
|
826
|
+
"table", "--format", help="Output format (table, json, csv)"
|
|
827
|
+
),
|
|
828
|
+
output_file: Optional[Path] = typer.Option(
|
|
829
|
+
None, "--output", help="Save results to file"
|
|
830
|
+
),
|
|
831
|
+
page_size: Optional[int] = typer.Option(
|
|
832
|
+
None, "--page-size", help="Number of roles per page"
|
|
833
|
+
),
|
|
834
|
+
page_token: Optional[str] = typer.Option(
|
|
835
|
+
None, "--page-token", help="Pagination token from previous response"
|
|
836
|
+
),
|
|
837
|
+
) -> None:
|
|
838
|
+
"""List available roles for an organization."""
|
|
839
|
+
console = Console()
|
|
840
|
+
formatter = OutputFormatter()
|
|
841
|
+
|
|
842
|
+
try:
|
|
843
|
+
service = AdminService(profile=profile)
|
|
844
|
+
|
|
845
|
+
with SpinnerProgressTracker().track_spinner(
|
|
846
|
+
f"Fetching available roles for organization {organization_rid}..."
|
|
847
|
+
):
|
|
848
|
+
result = service.list_available_roles(
|
|
849
|
+
organization_rid, page_size=page_size, page_token=page_token
|
|
850
|
+
)
|
|
851
|
+
|
|
852
|
+
if output_file:
|
|
853
|
+
formatter.save_to_file(result, output_file, output_format)
|
|
854
|
+
console.print(f"Results saved to {output_file}")
|
|
855
|
+
else:
|
|
856
|
+
formatter.display(result, output_format)
|
|
857
|
+
|
|
858
|
+
except Exception as e:
|
|
859
|
+
console.print(f"[red]Error:[/red] {e}")
|
|
860
|
+
raise typer.Exit(code=1)
|
|
861
|
+
|
|
862
|
+
|
|
863
|
+
# Marking Management Commands
|
|
864
|
+
@marking_app.command("list")
|
|
865
|
+
def list_markings(
|
|
866
|
+
profile: Optional[str] = typer.Option(
|
|
867
|
+
None, "--profile", help="Auth profile to use"
|
|
868
|
+
),
|
|
869
|
+
output_format: str = typer.Option(
|
|
870
|
+
"table", "--format", help="Output format (table, json, csv)"
|
|
871
|
+
),
|
|
872
|
+
output_file: Optional[Path] = typer.Option(
|
|
873
|
+
None, "--output", help="Save results to file"
|
|
874
|
+
),
|
|
875
|
+
page_size: Optional[int] = typer.Option(
|
|
876
|
+
None, "--page-size", help="Number of markings per page"
|
|
877
|
+
),
|
|
878
|
+
page_token: Optional[str] = typer.Option(
|
|
879
|
+
None, "--page-token", help="Pagination token from previous response"
|
|
880
|
+
),
|
|
881
|
+
) -> None:
|
|
882
|
+
"""List all markings."""
|
|
883
|
+
console = Console()
|
|
884
|
+
formatter = OutputFormatter()
|
|
885
|
+
|
|
886
|
+
try:
|
|
887
|
+
service = AdminService(profile=profile)
|
|
888
|
+
|
|
889
|
+
with SpinnerProgressTracker().track_spinner("Fetching markings..."):
|
|
890
|
+
result = service.list_markings(page_size=page_size, page_token=page_token)
|
|
891
|
+
|
|
892
|
+
if output_file:
|
|
893
|
+
formatter.save_to_file(result, output_file, output_format)
|
|
894
|
+
console.print(f"Results saved to {output_file}")
|
|
895
|
+
else:
|
|
896
|
+
formatter.display(result, output_format)
|
|
897
|
+
|
|
898
|
+
except Exception as e:
|
|
899
|
+
console.print(f"[red]Error:[/red] {e}")
|
|
900
|
+
raise typer.Exit(code=1)
|
|
901
|
+
|
|
902
|
+
|
|
903
|
+
@marking_app.command("get")
|
|
904
|
+
def get_marking(
|
|
905
|
+
marking_id: str = typer.Argument(..., help="Marking ID"),
|
|
906
|
+
profile: Optional[str] = typer.Option(
|
|
907
|
+
None, "--profile", help="Auth profile to use"
|
|
908
|
+
),
|
|
909
|
+
output_format: str = typer.Option(
|
|
910
|
+
"table", "--format", help="Output format (table, json, csv)"
|
|
911
|
+
),
|
|
912
|
+
output_file: Optional[Path] = typer.Option(
|
|
913
|
+
None, "--output", help="Save results to file"
|
|
914
|
+
),
|
|
915
|
+
) -> None:
|
|
916
|
+
"""Get information about a specific marking."""
|
|
917
|
+
console = Console()
|
|
918
|
+
formatter = OutputFormatter()
|
|
919
|
+
|
|
920
|
+
try:
|
|
921
|
+
service = AdminService(profile=profile)
|
|
922
|
+
|
|
923
|
+
with SpinnerProgressTracker().track_spinner(
|
|
924
|
+
f"Fetching marking {marking_id}..."
|
|
925
|
+
):
|
|
926
|
+
result = service.get_marking(marking_id)
|
|
927
|
+
|
|
928
|
+
if output_file:
|
|
929
|
+
formatter.save_to_file(result, output_file, output_format)
|
|
930
|
+
console.print(f"Results saved to {output_file}")
|
|
931
|
+
else:
|
|
932
|
+
formatter.display(result, output_format)
|
|
933
|
+
|
|
934
|
+
except Exception as e:
|
|
935
|
+
console.print(f"[red]Error:[/red] {e}")
|
|
936
|
+
raise typer.Exit(code=1)
|
|
937
|
+
|
|
938
|
+
|
|
939
|
+
@marking_app.command("batch-get")
|
|
940
|
+
def batch_get_markings(
|
|
941
|
+
marking_ids: List[str] = typer.Argument(
|
|
942
|
+
..., help="Marking IDs (space-separated, max 500)"
|
|
943
|
+
),
|
|
944
|
+
profile: Optional[str] = typer.Option(
|
|
945
|
+
None, "--profile", help="Auth profile to use"
|
|
946
|
+
),
|
|
947
|
+
output_format: str = typer.Option(
|
|
948
|
+
"table", "--format", help="Output format (table, json, csv)"
|
|
949
|
+
),
|
|
950
|
+
output_file: Optional[Path] = typer.Option(
|
|
951
|
+
None, "--output", help="Save results to file"
|
|
952
|
+
),
|
|
953
|
+
) -> None:
|
|
954
|
+
"""Batch retrieve multiple markings (max 500)."""
|
|
955
|
+
console = Console()
|
|
956
|
+
formatter = OutputFormatter()
|
|
957
|
+
|
|
958
|
+
try:
|
|
959
|
+
service = AdminService(profile=profile)
|
|
960
|
+
|
|
961
|
+
with SpinnerProgressTracker().track_spinner(
|
|
962
|
+
f"Fetching {len(marking_ids)} markings..."
|
|
963
|
+
):
|
|
964
|
+
result = service.get_batch_markings(marking_ids)
|
|
965
|
+
|
|
966
|
+
if output_file:
|
|
967
|
+
formatter.save_to_file(result, output_file, output_format)
|
|
968
|
+
console.print(f"Results saved to {output_file}")
|
|
969
|
+
else:
|
|
970
|
+
formatter.display(result, output_format)
|
|
971
|
+
|
|
972
|
+
except ValueError as e:
|
|
973
|
+
console.print(f"[red]Error:[/red] {e}")
|
|
974
|
+
raise typer.Exit(code=1)
|
|
975
|
+
except Exception as e:
|
|
976
|
+
console.print(f"[red]Error:[/red] {e}")
|
|
977
|
+
raise typer.Exit(code=1)
|
|
978
|
+
|
|
979
|
+
|
|
980
|
+
@marking_app.command("create")
|
|
981
|
+
def create_marking(
|
|
982
|
+
name: str = typer.Argument(..., help="Marking name"),
|
|
983
|
+
profile: Optional[str] = typer.Option(
|
|
984
|
+
None, "--profile", help="Auth profile to use"
|
|
985
|
+
),
|
|
986
|
+
description: Optional[str] = typer.Option(
|
|
987
|
+
None, "--description", help="Marking description"
|
|
988
|
+
),
|
|
989
|
+
category_id: Optional[str] = typer.Option(
|
|
990
|
+
None, "--category-id", help="Category ID for the marking"
|
|
991
|
+
),
|
|
992
|
+
output_format: str = typer.Option(
|
|
993
|
+
"table", "--format", help="Output format (table, json, csv)"
|
|
994
|
+
),
|
|
995
|
+
output_file: Optional[Path] = typer.Option(
|
|
996
|
+
None, "--output", help="Save results to file"
|
|
997
|
+
),
|
|
998
|
+
) -> None:
|
|
999
|
+
"""Create a new marking."""
|
|
1000
|
+
console = Console()
|
|
1001
|
+
formatter = OutputFormatter()
|
|
1002
|
+
|
|
1003
|
+
try:
|
|
1004
|
+
service = AdminService(profile=profile)
|
|
1005
|
+
|
|
1006
|
+
with SpinnerProgressTracker().track_spinner(f"Creating marking '{name}'..."):
|
|
1007
|
+
result = service.create_marking(
|
|
1008
|
+
name=name, description=description, category_id=category_id
|
|
1009
|
+
)
|
|
1010
|
+
|
|
1011
|
+
if output_file:
|
|
1012
|
+
formatter.save_to_file(result, output_file, output_format)
|
|
1013
|
+
console.print(f"Results saved to {output_file}")
|
|
1014
|
+
else:
|
|
1015
|
+
formatter.display(result, output_format)
|
|
1016
|
+
console.print(f"[green]Marking '{name}' created successfully[/green]")
|
|
1017
|
+
|
|
1018
|
+
except Exception as e:
|
|
1019
|
+
console.print(f"[red]Error:[/red] {e}")
|
|
1020
|
+
raise typer.Exit(code=1)
|
|
1021
|
+
|
|
1022
|
+
|
|
1023
|
+
@marking_app.command("replace")
|
|
1024
|
+
def replace_marking(
|
|
1025
|
+
marking_id: str = typer.Argument(..., help="Marking ID"),
|
|
1026
|
+
name: str = typer.Argument(..., help="New marking name"),
|
|
1027
|
+
profile: Optional[str] = typer.Option(
|
|
1028
|
+
None, "--profile", help="Auth profile to use"
|
|
1029
|
+
),
|
|
1030
|
+
description: Optional[str] = typer.Option(
|
|
1031
|
+
None, "--description", help="New marking description"
|
|
1032
|
+
),
|
|
1033
|
+
output_format: str = typer.Option(
|
|
1034
|
+
"table", "--format", help="Output format (table, json, csv)"
|
|
1035
|
+
),
|
|
1036
|
+
output_file: Optional[Path] = typer.Option(
|
|
1037
|
+
None, "--output", help="Save results to file"
|
|
1038
|
+
),
|
|
1039
|
+
confirm: bool = typer.Option(False, "--confirm", help="Skip confirmation prompt"),
|
|
1040
|
+
) -> None:
|
|
1041
|
+
"""Replace/update an existing marking."""
|
|
1042
|
+
console = Console()
|
|
1043
|
+
formatter = OutputFormatter()
|
|
1044
|
+
|
|
1045
|
+
if not confirm:
|
|
1046
|
+
user_confirm = typer.confirm(
|
|
1047
|
+
f"Are you sure you want to replace marking {marking_id}?"
|
|
1048
|
+
)
|
|
1049
|
+
if not user_confirm:
|
|
1050
|
+
console.print("Operation cancelled.")
|
|
1051
|
+
return
|
|
1052
|
+
|
|
1053
|
+
try:
|
|
1054
|
+
service = AdminService(profile=profile)
|
|
1055
|
+
|
|
1056
|
+
with SpinnerProgressTracker().track_spinner(
|
|
1057
|
+
f"Replacing marking {marking_id}..."
|
|
1058
|
+
):
|
|
1059
|
+
result = service.replace_marking(
|
|
1060
|
+
marking_id=marking_id, name=name, description=description
|
|
1061
|
+
)
|
|
1062
|
+
|
|
1063
|
+
if output_file:
|
|
1064
|
+
formatter.save_to_file(result, output_file, output_format)
|
|
1065
|
+
console.print(f"Results saved to {output_file}")
|
|
1066
|
+
else:
|
|
1067
|
+
formatter.display(result, output_format)
|
|
1068
|
+
console.print(
|
|
1069
|
+
f"[green]Marking '{marking_id}' replaced successfully[/green]"
|
|
1070
|
+
)
|
|
1071
|
+
|
|
1072
|
+
except Exception as e:
|
|
1073
|
+
console.print(f"[red]Error:[/red] {e}")
|
|
1074
|
+
raise typer.Exit(code=1)
|