pltr-cli 0.1.2__py3-none-any.whl → 0.2.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/__main__.py +28 -0
- pltr/cli.py +19 -1
- pltr/commands/admin.py +530 -0
- pltr/commands/completion.py +383 -0
- pltr/commands/dataset.py +20 -3
- pltr/commands/ontology.py +508 -0
- pltr/commands/shell.py +126 -0
- pltr/commands/sql.py +358 -0
- pltr/commands/verify.py +2 -1
- pltr/services/__init__.py +4 -0
- pltr/services/admin.py +314 -0
- pltr/services/ontology.py +443 -0
- pltr/services/sql.py +340 -0
- pltr/utils/completion.py +170 -0
- pltr/utils/formatting.py +208 -0
- pltr/utils/progress.py +1 -1
- pltr_cli-0.2.0.dist-info/METADATA +280 -0
- pltr_cli-0.2.0.dist-info/RECORD +38 -0
- pltr_cli-0.1.2.dist-info/METADATA +0 -203
- pltr_cli-0.1.2.dist-info/RECORD +0 -28
- {pltr_cli-0.1.2.dist-info → pltr_cli-0.2.0.dist-info}/WHEEL +0 -0
- {pltr_cli-0.1.2.dist-info → pltr_cli-0.2.0.dist-info}/entry_points.txt +0 -0
- {pltr_cli-0.1.2.dist-info → pltr_cli-0.2.0.dist-info}/licenses/LICENSE +0 -0
pltr/__main__.py
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"""Main entry point for pltr CLI."""
|
|
2
|
+
|
|
3
|
+
import os
|
|
4
|
+
import sys
|
|
5
|
+
|
|
6
|
+
# Handle shell completion before importing the main app
|
|
7
|
+
if "_PLTR_COMPLETE" in os.environ:
|
|
8
|
+
# Import Click's completion handling
|
|
9
|
+
from click.shell_completion import shell_complete
|
|
10
|
+
import typer
|
|
11
|
+
from pltr.cli import app
|
|
12
|
+
|
|
13
|
+
# Convert Typer app to Click command
|
|
14
|
+
click_app = typer.main.get_command(app)
|
|
15
|
+
|
|
16
|
+
# Get the completion instruction from environment
|
|
17
|
+
complete_var = "_PLTR_COMPLETE"
|
|
18
|
+
instruction = os.environ.get(complete_var, "")
|
|
19
|
+
|
|
20
|
+
# Run Click's completion
|
|
21
|
+
exit_code = shell_complete(click_app, {}, "pltr", complete_var, instruction)
|
|
22
|
+
sys.exit(exit_code)
|
|
23
|
+
|
|
24
|
+
# Normal CLI execution
|
|
25
|
+
from pltr.cli import app
|
|
26
|
+
|
|
27
|
+
if __name__ == "__main__":
|
|
28
|
+
app()
|
pltr/cli.py
CHANGED
|
@@ -6,7 +6,16 @@ import typer
|
|
|
6
6
|
from typing_extensions import Annotated
|
|
7
7
|
|
|
8
8
|
from pltr import __version__
|
|
9
|
-
from pltr.commands import
|
|
9
|
+
from pltr.commands import (
|
|
10
|
+
configure,
|
|
11
|
+
verify,
|
|
12
|
+
dataset,
|
|
13
|
+
ontology,
|
|
14
|
+
sql,
|
|
15
|
+
admin,
|
|
16
|
+
shell,
|
|
17
|
+
completion,
|
|
18
|
+
)
|
|
10
19
|
|
|
11
20
|
app = typer.Typer(
|
|
12
21
|
name="pltr",
|
|
@@ -18,6 +27,15 @@ app = typer.Typer(
|
|
|
18
27
|
app.add_typer(configure.app, name="configure", help="Manage authentication profiles")
|
|
19
28
|
app.add_typer(verify.app, name="verify", help="Verify authentication")
|
|
20
29
|
app.add_typer(dataset.app, name="dataset", help="Manage datasets")
|
|
30
|
+
app.add_typer(ontology.app, name="ontology", help="Ontology operations")
|
|
31
|
+
app.add_typer(sql.app, name="sql", help="Execute SQL queries")
|
|
32
|
+
app.add_typer(
|
|
33
|
+
admin.app,
|
|
34
|
+
name="admin",
|
|
35
|
+
help="Admin operations for user, group, and organization management",
|
|
36
|
+
)
|
|
37
|
+
app.add_typer(shell.shell_app, name="shell", help="Interactive shell mode")
|
|
38
|
+
app.add_typer(completion.app, name="completion", help="Manage shell completions")
|
|
21
39
|
|
|
22
40
|
|
|
23
41
|
def version_callback(value: bool):
|
pltr/commands/admin.py
ADDED
|
@@ -0,0 +1,530 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Admin commands for the pltr CLI.
|
|
3
|
+
Provides commands for user, group, role, and organization management.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
from typing import Optional
|
|
8
|
+
|
|
9
|
+
import typer
|
|
10
|
+
from rich.console import Console
|
|
11
|
+
|
|
12
|
+
from ..services.admin import AdminService
|
|
13
|
+
from ..utils.formatting import OutputFormatter
|
|
14
|
+
from ..utils.progress import SpinnerProgressTracker
|
|
15
|
+
|
|
16
|
+
# Create the main admin app
|
|
17
|
+
app = typer.Typer(
|
|
18
|
+
name="admin", help="Admin operations for user, group, and organization management"
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
# Create sub-apps for different admin categories
|
|
22
|
+
user_app = typer.Typer(name="user", help="User management operations")
|
|
23
|
+
group_app = typer.Typer(name="group", help="Group management operations")
|
|
24
|
+
role_app = typer.Typer(name="role", help="Role management operations")
|
|
25
|
+
org_app = typer.Typer(name="org", help="Organization management operations")
|
|
26
|
+
|
|
27
|
+
# Add sub-apps to main admin app
|
|
28
|
+
app.add_typer(user_app, name="user")
|
|
29
|
+
app.add_typer(group_app, name="group")
|
|
30
|
+
app.add_typer(role_app, name="role")
|
|
31
|
+
app.add_typer(org_app, name="org")
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
# User Management Commands
|
|
35
|
+
@user_app.command("list")
|
|
36
|
+
def list_users(
|
|
37
|
+
profile: Optional[str] = typer.Option(
|
|
38
|
+
None, "--profile", help="Auth profile to use"
|
|
39
|
+
),
|
|
40
|
+
output_format: str = typer.Option(
|
|
41
|
+
"table", "--format", help="Output format (table, json, csv)"
|
|
42
|
+
),
|
|
43
|
+
output_file: Optional[Path] = typer.Option(
|
|
44
|
+
None, "--output", help="Save results to file"
|
|
45
|
+
),
|
|
46
|
+
page_size: Optional[int] = typer.Option(
|
|
47
|
+
None, "--page-size", help="Number of users per page"
|
|
48
|
+
),
|
|
49
|
+
page_token: Optional[str] = typer.Option(
|
|
50
|
+
None, "--page-token", help="Pagination token from previous response"
|
|
51
|
+
),
|
|
52
|
+
) -> None:
|
|
53
|
+
"""List all users in the organization."""
|
|
54
|
+
console = Console()
|
|
55
|
+
formatter = OutputFormatter()
|
|
56
|
+
|
|
57
|
+
try:
|
|
58
|
+
service = AdminService(profile=profile)
|
|
59
|
+
|
|
60
|
+
with SpinnerProgressTracker().track_spinner("Fetching users..."):
|
|
61
|
+
result = service.list_users(page_size=page_size, page_token=page_token)
|
|
62
|
+
|
|
63
|
+
# Format and display results
|
|
64
|
+
if output_file:
|
|
65
|
+
formatter.save_to_file(result, output_file, output_format)
|
|
66
|
+
console.print(f"Results saved to {output_file}")
|
|
67
|
+
else:
|
|
68
|
+
formatter.display(result, output_format)
|
|
69
|
+
|
|
70
|
+
except Exception as e:
|
|
71
|
+
console.print(f"[red]Error:[/red] {e}")
|
|
72
|
+
raise typer.Exit(code=1)
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
@user_app.command("get")
|
|
76
|
+
def get_user(
|
|
77
|
+
user_id: str = typer.Argument(..., help="User ID or RID"),
|
|
78
|
+
profile: Optional[str] = typer.Option(
|
|
79
|
+
None, "--profile", help="Auth profile to use"
|
|
80
|
+
),
|
|
81
|
+
output_format: str = typer.Option(
|
|
82
|
+
"table", "--format", help="Output format (table, json, csv)"
|
|
83
|
+
),
|
|
84
|
+
output_file: Optional[Path] = typer.Option(
|
|
85
|
+
None, "--output", help="Save results to file"
|
|
86
|
+
),
|
|
87
|
+
) -> None:
|
|
88
|
+
"""Get information about a specific user."""
|
|
89
|
+
console = Console()
|
|
90
|
+
formatter = OutputFormatter()
|
|
91
|
+
|
|
92
|
+
try:
|
|
93
|
+
service = AdminService(profile=profile)
|
|
94
|
+
|
|
95
|
+
with SpinnerProgressTracker().track_spinner(f"Fetching user {user_id}..."):
|
|
96
|
+
result = service.get_user(user_id)
|
|
97
|
+
|
|
98
|
+
# Format and display results
|
|
99
|
+
if output_file:
|
|
100
|
+
formatter.save_to_file(result, output_file, output_format)
|
|
101
|
+
console.print(f"Results saved to {output_file}")
|
|
102
|
+
else:
|
|
103
|
+
formatter.display(result, output_format)
|
|
104
|
+
|
|
105
|
+
except Exception as e:
|
|
106
|
+
console.print(f"[red]Error:[/red] {e}")
|
|
107
|
+
raise typer.Exit(code=1)
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
@user_app.command("current")
|
|
111
|
+
def get_current_user(
|
|
112
|
+
profile: Optional[str] = typer.Option(
|
|
113
|
+
None, "--profile", help="Auth profile to use"
|
|
114
|
+
),
|
|
115
|
+
output_format: str = typer.Option(
|
|
116
|
+
"table", "--format", help="Output format (table, json, csv)"
|
|
117
|
+
),
|
|
118
|
+
output_file: Optional[Path] = typer.Option(
|
|
119
|
+
None, "--output", help="Save results to file"
|
|
120
|
+
),
|
|
121
|
+
) -> None:
|
|
122
|
+
"""Get information about the current authenticated user."""
|
|
123
|
+
console = Console()
|
|
124
|
+
formatter = OutputFormatter()
|
|
125
|
+
|
|
126
|
+
try:
|
|
127
|
+
service = AdminService(profile=profile)
|
|
128
|
+
|
|
129
|
+
with SpinnerProgressTracker().track_spinner("Fetching current user info..."):
|
|
130
|
+
result = service.get_current_user()
|
|
131
|
+
|
|
132
|
+
# Format and display results
|
|
133
|
+
if output_file:
|
|
134
|
+
formatter.save_to_file(result, output_file, output_format)
|
|
135
|
+
console.print(f"Results saved to {output_file}")
|
|
136
|
+
else:
|
|
137
|
+
formatter.display(result, output_format)
|
|
138
|
+
|
|
139
|
+
except Exception as e:
|
|
140
|
+
console.print(f"[red]Error:[/red] {e}")
|
|
141
|
+
raise typer.Exit(code=1)
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
@user_app.command("search")
|
|
145
|
+
def search_users(
|
|
146
|
+
query: str = typer.Argument(..., help="Search query string"),
|
|
147
|
+
profile: Optional[str] = typer.Option(
|
|
148
|
+
None, "--profile", help="Auth profile to use"
|
|
149
|
+
),
|
|
150
|
+
output_format: str = typer.Option(
|
|
151
|
+
"table", "--format", help="Output format (table, json, csv)"
|
|
152
|
+
),
|
|
153
|
+
output_file: Optional[Path] = typer.Option(
|
|
154
|
+
None, "--output", help="Save results to file"
|
|
155
|
+
),
|
|
156
|
+
page_size: Optional[int] = typer.Option(
|
|
157
|
+
None, "--page-size", help="Number of users per page"
|
|
158
|
+
),
|
|
159
|
+
page_token: Optional[str] = typer.Option(
|
|
160
|
+
None, "--page-token", help="Pagination token from previous response"
|
|
161
|
+
),
|
|
162
|
+
) -> None:
|
|
163
|
+
"""Search for users by query string."""
|
|
164
|
+
console = Console()
|
|
165
|
+
formatter = OutputFormatter()
|
|
166
|
+
|
|
167
|
+
try:
|
|
168
|
+
service = AdminService(profile=profile)
|
|
169
|
+
|
|
170
|
+
with SpinnerProgressTracker().track_spinner(
|
|
171
|
+
f"Searching users for '{query}'..."
|
|
172
|
+
):
|
|
173
|
+
result = service.search_users(
|
|
174
|
+
query=query, page_size=page_size, page_token=page_token
|
|
175
|
+
)
|
|
176
|
+
|
|
177
|
+
# Format and display results
|
|
178
|
+
if output_file:
|
|
179
|
+
formatter.save_to_file(result, output_file, output_format)
|
|
180
|
+
console.print(f"Results saved to {output_file}")
|
|
181
|
+
else:
|
|
182
|
+
formatter.display(result, output_format)
|
|
183
|
+
|
|
184
|
+
except Exception as e:
|
|
185
|
+
console.print(f"[red]Error:[/red] {e}")
|
|
186
|
+
raise typer.Exit(code=1)
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
@user_app.command("markings")
|
|
190
|
+
def get_user_markings(
|
|
191
|
+
user_id: str = typer.Argument(..., help="User ID or RID"),
|
|
192
|
+
profile: Optional[str] = typer.Option(
|
|
193
|
+
None, "--profile", help="Auth profile to use"
|
|
194
|
+
),
|
|
195
|
+
output_format: str = typer.Option(
|
|
196
|
+
"table", "--format", help="Output format (table, json, csv)"
|
|
197
|
+
),
|
|
198
|
+
output_file: Optional[Path] = typer.Option(
|
|
199
|
+
None, "--output", help="Save results to file"
|
|
200
|
+
),
|
|
201
|
+
) -> None:
|
|
202
|
+
"""Get markings/permissions for a specific user."""
|
|
203
|
+
console = Console()
|
|
204
|
+
formatter = OutputFormatter()
|
|
205
|
+
|
|
206
|
+
try:
|
|
207
|
+
service = AdminService(profile=profile)
|
|
208
|
+
|
|
209
|
+
with SpinnerProgressTracker().track_spinner(
|
|
210
|
+
f"Fetching markings for user {user_id}..."
|
|
211
|
+
):
|
|
212
|
+
result = service.get_user_markings(user_id)
|
|
213
|
+
|
|
214
|
+
# Format and display results
|
|
215
|
+
if output_file:
|
|
216
|
+
formatter.save_to_file(result, output_file, output_format)
|
|
217
|
+
console.print(f"Results saved to {output_file}")
|
|
218
|
+
else:
|
|
219
|
+
formatter.display(result, output_format)
|
|
220
|
+
|
|
221
|
+
except Exception as e:
|
|
222
|
+
console.print(f"[red]Error:[/red] {e}")
|
|
223
|
+
raise typer.Exit(code=1)
|
|
224
|
+
|
|
225
|
+
|
|
226
|
+
@user_app.command("revoke-tokens")
|
|
227
|
+
def revoke_user_tokens(
|
|
228
|
+
user_id: str = typer.Argument(..., help="User ID or RID"),
|
|
229
|
+
profile: Optional[str] = typer.Option(
|
|
230
|
+
None, "--profile", help="Auth profile to use"
|
|
231
|
+
),
|
|
232
|
+
confirm: bool = typer.Option(False, "--confirm", help="Skip confirmation prompt"),
|
|
233
|
+
) -> None:
|
|
234
|
+
"""Revoke all tokens for a specific user."""
|
|
235
|
+
console = Console()
|
|
236
|
+
|
|
237
|
+
# Confirmation prompt
|
|
238
|
+
if not confirm:
|
|
239
|
+
user_confirm = typer.confirm(
|
|
240
|
+
f"Are you sure you want to revoke all tokens for user {user_id}?"
|
|
241
|
+
)
|
|
242
|
+
if not user_confirm:
|
|
243
|
+
console.print("Operation cancelled.")
|
|
244
|
+
return
|
|
245
|
+
|
|
246
|
+
try:
|
|
247
|
+
service = AdminService(profile=profile)
|
|
248
|
+
|
|
249
|
+
with SpinnerProgressTracker().track_spinner(
|
|
250
|
+
f"Revoking tokens for user {user_id}..."
|
|
251
|
+
):
|
|
252
|
+
result = service.revoke_user_tokens(user_id)
|
|
253
|
+
|
|
254
|
+
console.print(f"[green]{result['message']}[/green]")
|
|
255
|
+
|
|
256
|
+
except Exception as e:
|
|
257
|
+
console.print(f"[red]Error:[/red] {e}")
|
|
258
|
+
raise typer.Exit(code=1)
|
|
259
|
+
|
|
260
|
+
|
|
261
|
+
# Group Management Commands
|
|
262
|
+
@group_app.command("list")
|
|
263
|
+
def list_groups(
|
|
264
|
+
profile: Optional[str] = typer.Option(
|
|
265
|
+
None, "--profile", help="Auth profile to use"
|
|
266
|
+
),
|
|
267
|
+
output_format: str = typer.Option(
|
|
268
|
+
"table", "--format", help="Output format (table, json, csv)"
|
|
269
|
+
),
|
|
270
|
+
output_file: Optional[Path] = typer.Option(
|
|
271
|
+
None, "--output", help="Save results to file"
|
|
272
|
+
),
|
|
273
|
+
page_size: Optional[int] = typer.Option(
|
|
274
|
+
None, "--page-size", help="Number of groups per page"
|
|
275
|
+
),
|
|
276
|
+
page_token: Optional[str] = typer.Option(
|
|
277
|
+
None, "--page-token", help="Pagination token from previous response"
|
|
278
|
+
),
|
|
279
|
+
) -> None:
|
|
280
|
+
"""List all groups in the organization."""
|
|
281
|
+
console = Console()
|
|
282
|
+
formatter = OutputFormatter()
|
|
283
|
+
|
|
284
|
+
try:
|
|
285
|
+
service = AdminService(profile=profile)
|
|
286
|
+
|
|
287
|
+
with SpinnerProgressTracker().track_spinner("Fetching groups..."):
|
|
288
|
+
result = service.list_groups(page_size=page_size, page_token=page_token)
|
|
289
|
+
|
|
290
|
+
# Format and display results
|
|
291
|
+
if output_file:
|
|
292
|
+
formatter.save_to_file(result, output_file, output_format)
|
|
293
|
+
console.print(f"Results saved to {output_file}")
|
|
294
|
+
else:
|
|
295
|
+
formatter.display(result, output_format)
|
|
296
|
+
|
|
297
|
+
except Exception as e:
|
|
298
|
+
console.print(f"[red]Error:[/red] {e}")
|
|
299
|
+
raise typer.Exit(code=1)
|
|
300
|
+
|
|
301
|
+
|
|
302
|
+
@group_app.command("get")
|
|
303
|
+
def get_group(
|
|
304
|
+
group_id: str = typer.Argument(..., help="Group ID or RID"),
|
|
305
|
+
profile: Optional[str] = typer.Option(
|
|
306
|
+
None, "--profile", help="Auth profile to use"
|
|
307
|
+
),
|
|
308
|
+
output_format: str = typer.Option(
|
|
309
|
+
"table", "--format", help="Output format (table, json, csv)"
|
|
310
|
+
),
|
|
311
|
+
output_file: Optional[Path] = typer.Option(
|
|
312
|
+
None, "--output", help="Save results to file"
|
|
313
|
+
),
|
|
314
|
+
) -> None:
|
|
315
|
+
"""Get information about a specific group."""
|
|
316
|
+
console = Console()
|
|
317
|
+
formatter = OutputFormatter()
|
|
318
|
+
|
|
319
|
+
try:
|
|
320
|
+
service = AdminService(profile=profile)
|
|
321
|
+
|
|
322
|
+
with SpinnerProgressTracker().track_spinner(f"Fetching group {group_id}..."):
|
|
323
|
+
result = service.get_group(group_id)
|
|
324
|
+
|
|
325
|
+
# Format and display results
|
|
326
|
+
if output_file:
|
|
327
|
+
formatter.save_to_file(result, output_file, output_format)
|
|
328
|
+
console.print(f"Results saved to {output_file}")
|
|
329
|
+
else:
|
|
330
|
+
formatter.display(result, output_format)
|
|
331
|
+
|
|
332
|
+
except Exception as e:
|
|
333
|
+
console.print(f"[red]Error:[/red] {e}")
|
|
334
|
+
raise typer.Exit(code=1)
|
|
335
|
+
|
|
336
|
+
|
|
337
|
+
@group_app.command("search")
|
|
338
|
+
def search_groups(
|
|
339
|
+
query: str = typer.Argument(..., help="Search query string"),
|
|
340
|
+
profile: Optional[str] = typer.Option(
|
|
341
|
+
None, "--profile", help="Auth profile to use"
|
|
342
|
+
),
|
|
343
|
+
output_format: str = typer.Option(
|
|
344
|
+
"table", "--format", help="Output format (table, json, csv)"
|
|
345
|
+
),
|
|
346
|
+
output_file: Optional[Path] = typer.Option(
|
|
347
|
+
None, "--output", help="Save results to file"
|
|
348
|
+
),
|
|
349
|
+
page_size: Optional[int] = typer.Option(
|
|
350
|
+
None, "--page-size", help="Number of groups per page"
|
|
351
|
+
),
|
|
352
|
+
page_token: Optional[str] = typer.Option(
|
|
353
|
+
None, "--page-token", help="Pagination token from previous response"
|
|
354
|
+
),
|
|
355
|
+
) -> None:
|
|
356
|
+
"""Search for groups by query string."""
|
|
357
|
+
console = Console()
|
|
358
|
+
formatter = OutputFormatter()
|
|
359
|
+
|
|
360
|
+
try:
|
|
361
|
+
service = AdminService(profile=profile)
|
|
362
|
+
|
|
363
|
+
with SpinnerProgressTracker().track_spinner(
|
|
364
|
+
f"Searching groups for '{query}'..."
|
|
365
|
+
):
|
|
366
|
+
result = service.search_groups(
|
|
367
|
+
query=query, page_size=page_size, page_token=page_token
|
|
368
|
+
)
|
|
369
|
+
|
|
370
|
+
# Format and display results
|
|
371
|
+
if output_file:
|
|
372
|
+
formatter.save_to_file(result, output_file, output_format)
|
|
373
|
+
console.print(f"Results saved to {output_file}")
|
|
374
|
+
else:
|
|
375
|
+
formatter.display(result, output_format)
|
|
376
|
+
|
|
377
|
+
except Exception as e:
|
|
378
|
+
console.print(f"[red]Error:[/red] {e}")
|
|
379
|
+
raise typer.Exit(code=1)
|
|
380
|
+
|
|
381
|
+
|
|
382
|
+
@group_app.command("create")
|
|
383
|
+
def create_group(
|
|
384
|
+
name: str = typer.Argument(..., help="Group name"),
|
|
385
|
+
profile: Optional[str] = typer.Option(
|
|
386
|
+
None, "--profile", help="Auth profile to use"
|
|
387
|
+
),
|
|
388
|
+
description: Optional[str] = typer.Option(
|
|
389
|
+
None, "--description", help="Group description"
|
|
390
|
+
),
|
|
391
|
+
organization_rid: Optional[str] = typer.Option(
|
|
392
|
+
None, "--org-rid", help="Organization RID"
|
|
393
|
+
),
|
|
394
|
+
output_format: str = typer.Option(
|
|
395
|
+
"table", "--format", help="Output format (table, json, csv)"
|
|
396
|
+
),
|
|
397
|
+
output_file: Optional[Path] = typer.Option(
|
|
398
|
+
None, "--output", help="Save results to file"
|
|
399
|
+
),
|
|
400
|
+
) -> None:
|
|
401
|
+
"""Create a new group."""
|
|
402
|
+
console = Console()
|
|
403
|
+
formatter = OutputFormatter()
|
|
404
|
+
|
|
405
|
+
try:
|
|
406
|
+
service = AdminService(profile=profile)
|
|
407
|
+
|
|
408
|
+
with SpinnerProgressTracker().track_spinner(f"Creating group '{name}'..."):
|
|
409
|
+
result = service.create_group(
|
|
410
|
+
name=name, description=description, organization_rid=organization_rid
|
|
411
|
+
)
|
|
412
|
+
|
|
413
|
+
# Format and display results
|
|
414
|
+
if output_file:
|
|
415
|
+
formatter.save_to_file(result, output_file, output_format)
|
|
416
|
+
console.print(f"Results saved to {output_file}")
|
|
417
|
+
else:
|
|
418
|
+
formatter.display(result, output_format)
|
|
419
|
+
console.print(f"[green]Group '{name}' created successfully[/green]")
|
|
420
|
+
|
|
421
|
+
except Exception as e:
|
|
422
|
+
console.print(f"[red]Error:[/red] {e}")
|
|
423
|
+
raise typer.Exit(code=1)
|
|
424
|
+
|
|
425
|
+
|
|
426
|
+
@group_app.command("delete")
|
|
427
|
+
def delete_group(
|
|
428
|
+
group_id: str = typer.Argument(..., help="Group ID or RID"),
|
|
429
|
+
profile: Optional[str] = typer.Option(
|
|
430
|
+
None, "--profile", help="Auth profile to use"
|
|
431
|
+
),
|
|
432
|
+
confirm: bool = typer.Option(False, "--confirm", help="Skip confirmation prompt"),
|
|
433
|
+
) -> None:
|
|
434
|
+
"""Delete a specific group."""
|
|
435
|
+
console = Console()
|
|
436
|
+
|
|
437
|
+
# Confirmation prompt
|
|
438
|
+
if not confirm:
|
|
439
|
+
user_confirm = typer.confirm(
|
|
440
|
+
f"Are you sure you want to delete group {group_id}?"
|
|
441
|
+
)
|
|
442
|
+
if not user_confirm:
|
|
443
|
+
console.print("Operation cancelled.")
|
|
444
|
+
return
|
|
445
|
+
|
|
446
|
+
try:
|
|
447
|
+
service = AdminService(profile=profile)
|
|
448
|
+
|
|
449
|
+
with SpinnerProgressTracker().track_spinner(f"Deleting group {group_id}..."):
|
|
450
|
+
result = service.delete_group(group_id)
|
|
451
|
+
|
|
452
|
+
console.print(f"[green]{result['message']}[/green]")
|
|
453
|
+
|
|
454
|
+
except Exception as e:
|
|
455
|
+
console.print(f"[red]Error:[/red] {e}")
|
|
456
|
+
raise typer.Exit(code=1)
|
|
457
|
+
|
|
458
|
+
|
|
459
|
+
# Role Management Commands
|
|
460
|
+
@role_app.command("get")
|
|
461
|
+
def get_role(
|
|
462
|
+
role_id: str = typer.Argument(..., help="Role ID or RID"),
|
|
463
|
+
profile: Optional[str] = typer.Option(
|
|
464
|
+
None, "--profile", help="Auth profile to use"
|
|
465
|
+
),
|
|
466
|
+
output_format: str = typer.Option(
|
|
467
|
+
"table", "--format", help="Output format (table, json, csv)"
|
|
468
|
+
),
|
|
469
|
+
output_file: Optional[Path] = typer.Option(
|
|
470
|
+
None, "--output", help="Save results to file"
|
|
471
|
+
),
|
|
472
|
+
) -> None:
|
|
473
|
+
"""Get information about a specific role."""
|
|
474
|
+
console = Console()
|
|
475
|
+
formatter = OutputFormatter()
|
|
476
|
+
|
|
477
|
+
try:
|
|
478
|
+
service = AdminService(profile=profile)
|
|
479
|
+
|
|
480
|
+
with SpinnerProgressTracker().track_spinner(f"Fetching role {role_id}..."):
|
|
481
|
+
result = service.get_role(role_id)
|
|
482
|
+
|
|
483
|
+
# Format and display results
|
|
484
|
+
if output_file:
|
|
485
|
+
formatter.save_to_file(result, output_file, output_format)
|
|
486
|
+
console.print(f"Results saved to {output_file}")
|
|
487
|
+
else:
|
|
488
|
+
formatter.display(result, output_format)
|
|
489
|
+
|
|
490
|
+
except Exception as e:
|
|
491
|
+
console.print(f"[red]Error:[/red] {e}")
|
|
492
|
+
raise typer.Exit(code=1)
|
|
493
|
+
|
|
494
|
+
|
|
495
|
+
# Organization Management Commands
|
|
496
|
+
@org_app.command("get")
|
|
497
|
+
def get_organization(
|
|
498
|
+
organization_id: str = typer.Argument(..., help="Organization ID or RID"),
|
|
499
|
+
profile: Optional[str] = typer.Option(
|
|
500
|
+
None, "--profile", help="Auth profile to use"
|
|
501
|
+
),
|
|
502
|
+
output_format: str = typer.Option(
|
|
503
|
+
"table", "--format", help="Output format (table, json, csv)"
|
|
504
|
+
),
|
|
505
|
+
output_file: Optional[Path] = typer.Option(
|
|
506
|
+
None, "--output", help="Save results to file"
|
|
507
|
+
),
|
|
508
|
+
) -> None:
|
|
509
|
+
"""Get information about a specific organization."""
|
|
510
|
+
console = Console()
|
|
511
|
+
formatter = OutputFormatter()
|
|
512
|
+
|
|
513
|
+
try:
|
|
514
|
+
service = AdminService(profile=profile)
|
|
515
|
+
|
|
516
|
+
with SpinnerProgressTracker().track_spinner(
|
|
517
|
+
f"Fetching organization {organization_id}..."
|
|
518
|
+
):
|
|
519
|
+
result = service.get_organization(organization_id)
|
|
520
|
+
|
|
521
|
+
# Format and display results
|
|
522
|
+
if output_file:
|
|
523
|
+
formatter.save_to_file(result, output_file, output_format)
|
|
524
|
+
console.print(f"Results saved to {output_file}")
|
|
525
|
+
else:
|
|
526
|
+
formatter.display(result, output_format)
|
|
527
|
+
|
|
528
|
+
except Exception as e:
|
|
529
|
+
console.print(f"[red]Error:[/red] {e}")
|
|
530
|
+
raise typer.Exit(code=1)
|