vantage-cli 0.1.1__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.
Files changed (46) hide show
  1. vantage_cli/__init__.py +131 -0
  2. vantage_cli/apps/__init__.py +22 -0
  3. vantage_cli/apps/common.py +78 -0
  4. vantage_cli/apps/juju_localhost/__init__.py +17 -0
  5. vantage_cli/apps/juju_localhost/app.py +255 -0
  6. vantage_cli/apps/juju_localhost/bundle_yaml.py +143 -0
  7. vantage_cli/apps/microk8s/README.md +47 -0
  8. vantage_cli/apps/microk8s/__init__.py +3 -0
  9. vantage_cli/apps/microk8s/app.py +301 -0
  10. vantage_cli/apps/multipass_singlenode/__init__.py +12 -0
  11. vantage_cli/apps/multipass_singlenode/app.py +173 -0
  12. vantage_cli/apps/templates.py +178 -0
  13. vantage_cli/auth.py +429 -0
  14. vantage_cli/cache.py +143 -0
  15. vantage_cli/client.py +84 -0
  16. vantage_cli/command_base.py +63 -0
  17. vantage_cli/commands/__init__.py +1 -0
  18. vantage_cli/commands/clouds/__init__.py +20 -0
  19. vantage_cli/commands/clouds/add.py +81 -0
  20. vantage_cli/commands/clouds/delete.py +61 -0
  21. vantage_cli/commands/clouds/render.py +146 -0
  22. vantage_cli/commands/clouds/update.py +97 -0
  23. vantage_cli/commands/clusters/__init__.py +27 -0
  24. vantage_cli/commands/clusters/create.py +270 -0
  25. vantage_cli/commands/clusters/delete.py +101 -0
  26. vantage_cli/commands/clusters/get.py +30 -0
  27. vantage_cli/commands/clusters/list.py +84 -0
  28. vantage_cli/commands/clusters/render.py +233 -0
  29. vantage_cli/commands/clusters/schema.py +31 -0
  30. vantage_cli/commands/clusters/utils.py +248 -0
  31. vantage_cli/commands/profile/__init__.py +30 -0
  32. vantage_cli/commands/profile/crud.py +529 -0
  33. vantage_cli/commands/profile/render.py +55 -0
  34. vantage_cli/config.py +161 -0
  35. vantage_cli/constants.py +40 -0
  36. vantage_cli/exceptions.py +127 -0
  37. vantage_cli/format.py +39 -0
  38. vantage_cli/gql_client.py +655 -0
  39. vantage_cli/main.py +303 -0
  40. vantage_cli/render.py +56 -0
  41. vantage_cli/schemas.py +48 -0
  42. vantage_cli/time_loop.py +124 -0
  43. vantage_cli-0.1.1.dist-info/METADATA +30 -0
  44. vantage_cli-0.1.1.dist-info/RECORD +46 -0
  45. vantage_cli-0.1.1.dist-info/WHEEL +4 -0
  46. vantage_cli-0.1.1.dist-info/entry_points.txt +2 -0
vantage_cli/main.py ADDED
@@ -0,0 +1,303 @@
1
+ # © 2025 Vantage Compute, Inc. All rights reserved.
2
+ # Confidential and proprietary. Unauthorized use prohibited.
3
+ """Main typer app for vantage-cli."""
4
+
5
+ import datetime
6
+ import sys
7
+ from typing import Optional
8
+
9
+ import typer
10
+ from jose import jwt
11
+ from loguru import logger
12
+ from rich import print_json
13
+ from rich.console import Console
14
+ from rich.panel import Panel
15
+ from rich.table import Table
16
+ from typing_extensions import Annotated
17
+
18
+ from vantage_cli import AsyncTyper
19
+ from vantage_cli.apps import apps_app
20
+ from vantage_cli.auth import extract_persona, fetch_auth_tokens, is_token_expired
21
+ from vantage_cli.cache import clear_token_cache, load_tokens_from_cache, with_cache
22
+ from vantage_cli.client import attach_client
23
+ from vantage_cli.commands.clouds import clouds_app
24
+ from vantage_cli.commands.clusters import cluster_app
25
+ from vantage_cli.commands.profile import profile_app
26
+ from vantage_cli.config import (
27
+ attach_settings,
28
+ clear_settings,
29
+ ensure_default_profile_exists,
30
+ get_active_profile,
31
+ )
32
+ from vantage_cli.exceptions import handle_abort
33
+ from vantage_cli.schemas import CliContext, Persona, TokenSet
34
+
35
+ app = AsyncTyper(
36
+ name="Vantage CLI",
37
+ add_completion=True,
38
+ context_settings={
39
+ "allow_extra_args": True,
40
+ "allow_interspersed_args": True,
41
+ "max_content_width": 120,
42
+ },
43
+ )
44
+
45
+ app.add_typer(clouds_app, name="clouds")
46
+ app.add_typer(cluster_app, name="clusters")
47
+ app.add_typer(profile_app, name="profile")
48
+ app.add_typer(apps_app, name="apps")
49
+
50
+
51
+ def setup_logging(verbose: bool = False):
52
+ """Configure logging based on verbosity level."""
53
+ logger.remove()
54
+
55
+ if verbose:
56
+ logger.add(sys.stdout, level="DEBUG")
57
+
58
+ logger.debug("Logging initialized")
59
+
60
+
61
+ @app.callback()
62
+ def main(
63
+ ctx: typer.Context,
64
+ verbose: Annotated[
65
+ bool, typer.Option("--verbose", "-v", help="Enable verbose output")
66
+ ] = False,
67
+ profile: Annotated[
68
+ Optional[str], typer.Option("--profile", "-p", help="Specify the profile to use")
69
+ ] = None,
70
+ json: Annotated[bool, typer.Option("--json", "-j", help="Output in JSON format")] = False,
71
+ ):
72
+ """Handle global options for the application."""
73
+ if ctx.invoked_subcommand is None:
74
+ console = Console()
75
+ console.print("No command provided. Please check [bold magenta]usage[/bold magenta]")
76
+ raise typer.Exit()
77
+
78
+ ensure_default_profile_exists()
79
+
80
+ # Use explicit profile if provided, otherwise get the active profile
81
+ active_profile = profile if profile is not None else get_active_profile()
82
+
83
+ setup_logging(verbose=verbose)
84
+
85
+ cli_ctx = CliContext(profile=active_profile, verbose=verbose, json_output=json)
86
+ ctx.obj = cli_ctx
87
+
88
+
89
+ def _check_existing_login(profile: str) -> Optional[str]:
90
+ """Check if user is already logged in with a valid token.
91
+
92
+ Returns:
93
+ Email of logged in user if valid token exists, None otherwise
94
+ """
95
+ try:
96
+ # Try to load tokens from cache
97
+ token_set = load_tokens_from_cache(profile)
98
+
99
+ # Check if access token is valid (not expired)
100
+ if token_set.access_token and not is_token_expired(token_set.access_token):
101
+ # Extract email from token for display
102
+ try:
103
+ persona = extract_persona(profile, token_set)
104
+ return persona.identity_data.email
105
+ except Exception as e:
106
+ logger.debug(f"Could not extract persona from existing token: {e}")
107
+ return None
108
+
109
+ except Exception as e:
110
+ # Token cache doesn't exist or other error - user not logged in
111
+ logger.debug(f"No valid existing login found: {e}")
112
+ return None
113
+
114
+ return None
115
+
116
+
117
+ @app.command()
118
+ @handle_abort
119
+ @with_cache
120
+ @attach_settings
121
+ @attach_client
122
+ async def login(ctx: typer.Context):
123
+ """Authenticate against the Vantage CLI by obtaining an authentication token."""
124
+ # Check if user is already logged in with a valid token
125
+ existing_email = _check_existing_login(ctx.obj.profile)
126
+ if existing_email:
127
+ console = Console()
128
+ console.print()
129
+ console.print(
130
+ Panel(
131
+ f"Profile: [bold]{ctx.obj.profile}[/bold]\n\n"
132
+ f"✅ Valid token already exists for user: [bold cyan]{existing_email}[/bold cyan]\n\n"
133
+ f"If you want to generate a new token, please run '[bold magenta]vantage logout[/bold magenta]' first.",
134
+ title="[green]Already Authenticated[/green]",
135
+ border_style="green",
136
+ )
137
+ )
138
+ console.print()
139
+ return
140
+
141
+ token_set: TokenSet = await fetch_auth_tokens(ctx.obj)
142
+ persona: Persona = extract_persona(ctx.obj.profile, token_set)
143
+ console = Console()
144
+ console.print()
145
+ console.print(
146
+ Panel(
147
+ f"Profile: [bold]{ctx.obj.profile}[/bold]\n\n"
148
+ f"✅ Successful authentication: [bold cyan]{persona.identity_data.email}[/bold cyan]\n\n"
149
+ "You can now use the CLI to interact with Vantage Compute platform.",
150
+ title="[green]Successful Authentication[/green]",
151
+ border_style="green",
152
+ )
153
+ )
154
+ console.print()
155
+
156
+
157
+ @app.command()
158
+ @handle_abort
159
+ @with_cache
160
+ async def logout(ctx: typer.Context):
161
+ """Log out of the vantage-cli and clear saved user credentials."""
162
+ existing_email = _check_existing_login(ctx.obj.profile)
163
+ if existing_email:
164
+ console = Console()
165
+ console.print()
166
+ console.print(
167
+ Panel(
168
+ f"Profile: [bold]{ctx.obj.profile}[/bold]\n\n"
169
+ f"✅ [bold]User:[/bold] {existing_email}\n\n"
170
+ f"Please run '[bold magenta]vantage login[/bold magenta]' to log back in.",
171
+ title="[green]Successfully Signed Out[/green]",
172
+ border_style="green",
173
+ )
174
+ )
175
+ console.print()
176
+ clear_token_cache(ctx.obj.profile)
177
+
178
+
179
+ @app.command()
180
+ @with_cache
181
+ @attach_settings
182
+ async def whoami(ctx: typer.Context):
183
+ """Display information about the currently authenticated user."""
184
+ # Get the JSON output preference from context
185
+ json_output = getattr(ctx.obj, "json_output", False)
186
+
187
+ try:
188
+ # Extract persona from cached tokens
189
+ persona: Persona = extract_persona(ctx.obj.profile)
190
+
191
+ token_info = {}
192
+ try:
193
+ token_data = jwt.decode(
194
+ persona.token_set.access_token,
195
+ "", # Empty key is acceptable when verify_signature is False
196
+ options={
197
+ "verify_signature": False,
198
+ "verify_aud": False,
199
+ "verify_exp": False, # Don't verify expiration for display
200
+ },
201
+ )
202
+
203
+ # Extract additional fields if available
204
+ if "exp" in token_data:
205
+ exp_timestamp = token_data["exp"]
206
+ exp_datetime = datetime.datetime.fromtimestamp(exp_timestamp)
207
+ token_info["token_expires_at"] = exp_datetime.isoformat()
208
+ token_info["token_expired"] = exp_datetime < datetime.datetime.now()
209
+
210
+ if "iat" in token_data:
211
+ iat_timestamp = token_data["iat"]
212
+ iat_datetime = datetime.datetime.fromtimestamp(iat_timestamp)
213
+ token_info["token_issued_at"] = iat_datetime.isoformat()
214
+
215
+ if "sub" in token_data:
216
+ token_info["user_id"] = token_data["sub"]
217
+
218
+ if "name" in token_data:
219
+ token_info["name"] = token_data["name"]
220
+
221
+ except Exception as e:
222
+ logger.debug(f"Could not decode token for additional info: {e}")
223
+
224
+ # Prepare user information
225
+ user_info = {
226
+ "email": persona.identity_data.email,
227
+ "client_id": persona.identity_data.client_id,
228
+ "profile": ctx.obj.profile,
229
+ "logged_in": True,
230
+ **token_info,
231
+ }
232
+
233
+ if json_output:
234
+ print_json(data=user_info)
235
+ else:
236
+ console = Console()
237
+ console.print()
238
+
239
+ # Create a table for user information
240
+ table = Table(
241
+ title="Current User Information", show_header=True, header_style="bold white"
242
+ )
243
+
244
+ table.add_column("Property", style="bold cyan")
245
+ table.add_column("Value", style="white")
246
+
247
+ table.add_row("Email", user_info["email"] or "Not available")
248
+ table.add_row("Client ID", user_info["client_id"])
249
+ table.add_row("Profile", user_info["profile"])
250
+
251
+ if "name" in user_info:
252
+ table.add_row("Name", user_info["name"])
253
+
254
+ if "user_id" in user_info:
255
+ table.add_row("User ID", user_info["user_id"])
256
+
257
+ if "token_issued_at" in user_info:
258
+ table.add_row("Token Issued", user_info["token_issued_at"])
259
+
260
+ if "token_expires_at" in user_info:
261
+ exp_status = "❌ Expired" if user_info.get("token_expired", False) else "✅ Valid"
262
+ table.add_row("Token Expires", f"{user_info['token_expires_at']} ({exp_status})")
263
+
264
+ table.add_row("Status", "✅ Logged in")
265
+
266
+ console.print(table)
267
+ console.print()
268
+
269
+ except Exception as e:
270
+ logger.error(f"Failed to get user information: {str(e)}")
271
+
272
+ error_info = {
273
+ "logged_in": False,
274
+ "error": "Not authenticated or token expired",
275
+ "profile": ctx.obj.profile,
276
+ "message": "Please run 'vantage login' to authenticate",
277
+ }
278
+
279
+ if json_output:
280
+ print_json(data=error_info)
281
+ else:
282
+ console = Console()
283
+ console.print()
284
+ console.print(
285
+ Panel(
286
+ "❌ Not authenticated or token expired\n\n"
287
+ f"Current profile: [bold]{ctx.obj.profile}[/bold]\n"
288
+ f"Please run [bold]vantage login[/bold] to authenticate",
289
+ title="[red]Authentication Required[/red]",
290
+ border_style="red",
291
+ )
292
+ )
293
+ console.print()
294
+
295
+
296
+ @app.command()
297
+ async def clear_config():
298
+ """Clear all user tokens and config."""
299
+ clear_settings()
300
+
301
+
302
+ if __name__ == "__main__":
303
+ app()
vantage_cli/render.py ADDED
@@ -0,0 +1,56 @@
1
+ # © 2025 Vantage Compute, Inc. All rights reserved.
2
+ # Confidential and proprietary. Unauthorized use prohibited.
3
+ """Rendering utilities for CLI output."""
4
+
5
+ from typing import Any, Dict
6
+
7
+ import snick
8
+ from rich.console import Console
9
+ from rich.panel import Panel
10
+
11
+
12
+ class StyleMapper:
13
+ """Provide a mapper that can set Rich styles for rendered output of data tables.
14
+
15
+ Similar to jobbergate-cli's StyleMapper, this class provides a way to define
16
+ styles that should be applied to columns of tables.
17
+ """
18
+
19
+ def __init__(self, **colors: str):
20
+ """Initialize the StyleMapper with color mappings."""
21
+ self.colors = colors
22
+
23
+ def map_style(self, column: str) -> Dict[str, Any]:
24
+ """Map a column name to the style that should be used to render it."""
25
+ color = self.colors.get(column, "white")
26
+ return {
27
+ "style": color,
28
+ "header_style": f"bold {color}",
29
+ }
30
+
31
+
32
+ def render_quick_start_guide() -> None:
33
+ """Render quick start guide for the CLI."""
34
+ """Render a quick start guide panel similar to jobbergate-cli's demo."""
35
+ message = snick.dedent(
36
+ """
37
+ • To view cluster details, use the command: vantage clusters get
38
+
39
+ • To create a new cluster, use the command: vantage clusters create --help
40
+
41
+ • For more information on any command run it with the --help option.
42
+
43
+ • To check all the available commands, refer to: vantage --help
44
+ """
45
+ ).strip()
46
+
47
+ console = Console()
48
+ panel = Panel(
49
+ message,
50
+ title="[bold magenta]Quick Start Guide for Vantage-CLI[/bold magenta]",
51
+ border_style="blue",
52
+ expand=False,
53
+ )
54
+
55
+ console.print()
56
+ console.print(panel)
vantage_cli/schemas.py ADDED
@@ -0,0 +1,48 @@
1
+ """Data models and schemas for the Vantage CLI."""
2
+
3
+ from typing import Optional
4
+
5
+ import httpx
6
+ from pydantic import BaseModel
7
+
8
+ from vantage_cli.config import Settings
9
+
10
+
11
+ class TokenSet(BaseModel):
12
+ """OAuth token set containing access and refresh tokens."""
13
+
14
+ access_token: str
15
+ refresh_token: Optional[str] = None
16
+
17
+
18
+ class IdentityData(BaseModel):
19
+ """User identity information extracted from tokens."""
20
+
21
+ client_id: str
22
+ email: Optional[str] = None
23
+
24
+
25
+ class Persona(BaseModel):
26
+ """User persona combining token set and identity data."""
27
+
28
+ token_set: TokenSet
29
+ identity_data: IdentityData
30
+
31
+
32
+ class DeviceCodeData(BaseModel):
33
+ """OAuth device code flow data."""
34
+
35
+ device_code: str
36
+ verification_uri_complete: str
37
+ interval: int
38
+
39
+
40
+ class CliContext(BaseModel, arbitrary_types_allowed=True):
41
+ """CLI context for command execution."""
42
+
43
+ profile: str = "default"
44
+ verbose: bool = False
45
+ json_output: bool = False
46
+ persona: Optional[Persona] = None
47
+ client: Optional[httpx.AsyncClient] = None
48
+ settings: Optional[Settings] = None
@@ -0,0 +1,124 @@
1
+ """Time-based loop utilities for the Vantage CLI."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from dataclasses import dataclass
6
+
7
+ import pendulum
8
+ from rich.progress import Progress
9
+
10
+ from vantage_cli.exceptions import VantageCliError
11
+
12
+
13
+ @dataclass
14
+ class Tick:
15
+ """Represents a single tick in a time loop with timing information."""
16
+
17
+ counter: int
18
+ elapsed: pendulum.Duration
19
+ total_elapsed: pendulum.Duration
20
+
21
+
22
+ class TimeLoop:
23
+ """Time-based loop with progress tracking and duration management."""
24
+
25
+ advent: pendulum.DateTime | None
26
+ moment: pendulum.DateTime | None
27
+ last_moment: pendulum.DateTime | None
28
+ counter: int
29
+ progress: Progress | None
30
+ duration: pendulum.Duration
31
+ message: str
32
+ color: str
33
+
34
+ def __init__(
35
+ self,
36
+ duration: pendulum.Duration | int,
37
+ message: str = "Processing",
38
+ color: str = "green",
39
+ ):
40
+ self.advent = None
41
+ self.moment = None
42
+ self.last_moment = None
43
+ self.counter = 0
44
+ self.progress = None
45
+ if isinstance(duration, int):
46
+ VantageCliError.require_condition(
47
+ duration > 0,
48
+ "The duration must be a positive integer",
49
+ )
50
+ self.duration = pendulum.duration(seconds=duration)
51
+ else:
52
+ self.duration = duration
53
+ self.message = message
54
+ self.color = color
55
+
56
+ def __del__(self):
57
+ """Explicitly clear the progress meter if the time-loop is destroyed."""
58
+ self.clear()
59
+
60
+ def __iter__(self) -> "TimeLoop":
61
+ """Start the iterator.
62
+
63
+ Creates and starts the progress meter
64
+ """
65
+ now = pendulum.now()
66
+ self.advent = now
67
+ self.last_moment = now
68
+ self.moment = now
69
+ self.counter = 0
70
+ self.progress = Progress()
71
+ self.progress.add_task(
72
+ f"[{self.color}]{self.message}...",
73
+ total=self.duration.total_seconds(),
74
+ )
75
+ self.progress.start()
76
+ return self
77
+
78
+ def __next__(self) -> Tick:
79
+ """Iterate the time loop and return a tick.
80
+
81
+ If the duration is complete, clear the progress meter and stop iteration.
82
+ """
83
+ progress: Progress = VantageCliError.enforce_defined(
84
+ self.progress,
85
+ "Progress bar has not been initialized...this should not happen",
86
+ )
87
+
88
+ self.counter += 1
89
+ self.last_moment = self.moment
90
+ self.moment = pendulum.now()
91
+ if self.moment is not None and self.last_moment is not None:
92
+ elapsed: pendulum.Duration = self.moment - self.last_moment
93
+ else:
94
+ elapsed = pendulum.duration(seconds=0)
95
+ if self.moment is not None and self.advent is not None:
96
+ total_elapsed: pendulum.Duration = self.moment - self.advent
97
+ else:
98
+ total_elapsed = pendulum.duration(seconds=0)
99
+
100
+ for task_id in progress.task_ids:
101
+ progress.advance(task_id, elapsed.total_seconds())
102
+
103
+ if progress.finished:
104
+ self.clear()
105
+ raise StopIteration
106
+
107
+ return Tick(
108
+ counter=self.counter,
109
+ elapsed=elapsed,
110
+ total_elapsed=total_elapsed,
111
+ )
112
+
113
+ def clear(self):
114
+ """Clear the time-loop.
115
+
116
+ Stops the progress meter (if set) and reset moments, counter, progress meter.
117
+ """
118
+ if self.progress is not None:
119
+ self.progress.stop()
120
+ self.counter = 0
121
+ self.progress = None
122
+ now = pendulum.now()
123
+ self.moment = now
124
+ self.last_moment = now
@@ -0,0 +1,30 @@
1
+ Metadata-Version: 2.4
2
+ Name: vantage-cli
3
+ Version: 0.1.1
4
+ Summary: The Vantage Compute CLI.
5
+ Author-email: jamesbeedy <james@vantagecompute.ai>
6
+ License: MIT
7
+ Requires-Python: >=3.12
8
+ Requires-Dist: aiohttp>=3.8.0
9
+ Requires-Dist: anyio>=3.6.0
10
+ Requires-Dist: gql>=4.0.0
11
+ Requires-Dist: httpx>=0.28.1
12
+ Requires-Dist: juju~=3.6
13
+ Requires-Dist: loguru>=0.7.3
14
+ Requires-Dist: pendulum>=3.1.0
15
+ Requires-Dist: py-buzz>=7.3
16
+ Requires-Dist: pydantic>=2.11
17
+ Requires-Dist: python-jose[cryptography]>=3.5.0
18
+ Requires-Dist: requests-toolbelt>=0.10.0
19
+ Requires-Dist: rich>=14.1.0
20
+ Requires-Dist: ruamel-yaml
21
+ Requires-Dist: snick>=2.1
22
+ Requires-Dist: typer>=0.17.4
23
+ Provides-Extra: dev
24
+ Requires-Dist: black; extra == 'dev'
25
+ Requires-Dist: codespell; extra == 'dev'
26
+ Requires-Dist: coverage[toml]~=7.8; extra == 'dev'
27
+ Requires-Dist: pyright; extra == 'dev'
28
+ Requires-Dist: pytest-asyncio>=0.21.0; extra == 'dev'
29
+ Requires-Dist: pytest>=7.0.0; extra == 'dev'
30
+ Requires-Dist: ruff; extra == 'dev'
@@ -0,0 +1,46 @@
1
+ vantage_cli/__init__.py,sha256=sQo96C0Qwkyufu_5N8rpUiG7b6KAG4Xl0USrgEJ1rj4,4676
2
+ vantage_cli/auth.py,sha256=zi1xnNYnxXkcVCY4tCatcLE1q3qukX3HOFbrZoGv8Ag,15430
3
+ vantage_cli/cache.py,sha256=N8goumBtDLcQge2RmJHxyauiCL1aK_5eCXlWtL9OqpQ,5394
4
+ vantage_cli/client.py,sha256=07vp-1GGS2aV3kRQHl5deIMWNdgkjGz7rohGtxeyCiI,2689
5
+ vantage_cli/command_base.py,sha256=_Ln81IHLxXUsJZtWJBx6q10JXrLjhLgNfA0Vs-3-Tfg,2466
6
+ vantage_cli/config.py,sha256=UouRz1DcmawAuTqxkMyiPJk_ioRZ1NPC0fNwugCp5X8,5913
7
+ vantage_cli/constants.py,sha256=7dwKUX4aOG0smpqdS2JjtxiqHo1kFGf59PG1Sxezx-4,1627
8
+ vantage_cli/exceptions.py,sha256=3g21lMxR7mU-L32c911rGIUZPwqQkYvkyUlHedd2fcE,3355
9
+ vantage_cli/format.py,sha256=0H09Nio9wl890cq3dpNbmihqPf6A5_nItPqFFc_5Xp4,1057
10
+ vantage_cli/gql_client.py,sha256=bBt7keOC4isRJz_U59KgoCHsvzWgv9KIToMI-RSc3j4,23972
11
+ vantage_cli/main.py,sha256=SmFXF882depC0Qht2szJeVORu0b6Veb0iVLTXLkfbjk,10215
12
+ vantage_cli/render.py,sha256=3S_2vvDo-EijdEGlh95ddFNkSOg8r7PG1czyXUSeRow,1723
13
+ vantage_cli/schemas.py,sha256=sbpicXKBGpJW4BdEv6lYUZb-dA77QU5VZboWK7lb6A8,1079
14
+ vantage_cli/time_loop.py,sha256=pGb1Q3XI3sEGl-Ha0dsvQ_rTc3TpRje6e5WLqr2WXLw,3569
15
+ vantage_cli/apps/__init__.py,sha256=Xn3XwDeXMnUjaMecYcIJimFWWpi_2yNOoMQoJ0MmmhI,733
16
+ vantage_cli/apps/common.py,sha256=Ul_S2rzMAVGS5yNL2DT8F_euwjRQt13awZLi8qPUxas,2108
17
+ vantage_cli/apps/templates.py,sha256=2dXZqrGFzfV2ZTAlNncObRJkyuO6U95gsqlDBDc-UbI,7457
18
+ vantage_cli/apps/juju_localhost/__init__.py,sha256=HpKfUMSAMugjw9kGegoJMZ8Il-5LBL9c_-i4BiwU7xc,431
19
+ vantage_cli/apps/juju_localhost/app.py,sha256=C2KS7hOOWRAiRZ1ussI2AurkkouOuX_ArRV0SK2ltjk,10297
20
+ vantage_cli/apps/juju_localhost/bundle_yaml.py,sha256=bMyJ3cVDDPOKxiu5FhotF9gh_CywABVW-W2Y2S8waRI,4850
21
+ vantage_cli/apps/microk8s/README.md,sha256=Ud4wWx35FqeESHI7mWTduTM4b5RmCAbrNwAfg6jBgIo,2244
22
+ vantage_cli/apps/microk8s/__init__.py,sha256=uwEWzxy-vzVRmYgqlpo7s2AxtHQl3XY7ZPRvkvkK10Y,194
23
+ vantage_cli/apps/microk8s/app.py,sha256=AaLYpcZ0DuvcI_F56-slvujZJvPJ9hJfnHtrxuMJRYU,9535
24
+ vantage_cli/apps/multipass_singlenode/__init__.py,sha256=Z03IriK9S9cRYNTNDWkR25SgUYhthMTIIb4I1kdHpSU,312
25
+ vantage_cli/apps/multipass_singlenode/app.py,sha256=KDGhfC24rH5Mz1D6ZuZbVF0wq3nXR2pcd7xsrq36IxQ,6712
26
+ vantage_cli/commands/__init__.py,sha256=yZI-TkoUYDiVop1cs0_WHyb7eWeuw5C2rBJHSNo-uPM,35
27
+ vantage_cli/commands/clouds/__init__.py,sha256=Xf0K3BcWDJ4x3D5FLfcb0QCrg7tYXG2Bk0LfXKenpqA,597
28
+ vantage_cli/commands/clouds/add.py,sha256=5t-Xes2BFzoLuwEZ7-Zcb4YtkzriH2aceeGeSe61nq0,2597
29
+ vantage_cli/commands/clouds/delete.py,sha256=GyYfRoXD03lUQKABWe1KovOiCdVoBPFC-8y6ca_SNtg,2023
30
+ vantage_cli/commands/clouds/render.py,sha256=ibAlets-2CJXvqjIPI8c65qrWCeOuZa9pYg-WZjzEHc,4526
31
+ vantage_cli/commands/clouds/update.py,sha256=F3ksM0bSJjc7rqdGplN98AdRjclM4VddisvnRnyVzW8,3094
32
+ vantage_cli/commands/clusters/__init__.py,sha256=VPvUVKq9jTvbQEf-L06jWqX8wc4_qYb8Pe2azLCT8Pc,857
33
+ vantage_cli/commands/clusters/create.py,sha256=PhtxEivP4pzzrOKtPWWBW6uDCffqZ84ychpBJcj57-c,9503
34
+ vantage_cli/commands/clusters/delete.py,sha256=c41jbC4uLj1Ynr6iltUtqz-TNFJrTOQzcgJ6a61O-BY,3564
35
+ vantage_cli/commands/clusters/get.py,sha256=s_KRkHFAEqxZIcH88D48-C-eUKnCxsIFSB4ALrBboc4,1128
36
+ vantage_cli/commands/clusters/list.py,sha256=k3oLpzHog011nJzCbePd38xPwvyl5DwjmXPD8rnpFRs,2649
37
+ vantage_cli/commands/clusters/render.py,sha256=UVeTalX7CkkDgedwrcH8xIO-Dmm324-8DyT1kp_sGdA,7282
38
+ vantage_cli/commands/clusters/schema.py,sha256=nbH4byz3Zn_8YNIfmzjnOc3viqlxIUb37ALsEMqDf-I,712
39
+ vantage_cli/commands/clusters/utils.py,sha256=bBZD7epv_VVy8oOQkaPYm0ADes9_JQJduzipDyJzlmQ,9194
40
+ vantage_cli/commands/profile/__init__.py,sha256=064lGji7Qu84v2wrVzuhlBQVeWvPWEgbo7Ola30I4mg,938
41
+ vantage_cli/commands/profile/crud.py,sha256=IJCiV_JA9xTNNW5kdtAim4G6Od2ywAYFzyjYRgVfALk,18876
42
+ vantage_cli/commands/profile/render.py,sha256=RWldJrdkvvhgXUfvXf872nFgAReOLmZ2wYtIqWop8-w,1852
43
+ vantage_cli-0.1.1.dist-info/METADATA,sha256=FfMNZJ4oPdcXqcL11AixW6aIB_lOfP-XhuMbzDH7eQA,955
44
+ vantage_cli-0.1.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
45
+ vantage_cli-0.1.1.dist-info/entry_points.txt,sha256=TCUnwMb93FDfzPeFna1pxXxeE7Yi-F3JOLHW-oXo6jg,49
46
+ vantage_cli-0.1.1.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.27.0
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ vantage = vantage_cli.main:app