|
| 1 | +import argparse |
| 2 | + |
| 3 | +from dstack._internal.cli.commands import APIBaseCommand |
| 4 | +from dstack._internal.cli.services.completion import SecretNameCompleter |
| 5 | +from dstack._internal.cli.utils.common import ( |
| 6 | + confirm_ask, |
| 7 | + console, |
| 8 | +) |
| 9 | +from dstack._internal.cli.utils.secrets import print_secrets_table |
| 10 | + |
| 11 | + |
| 12 | +class SecretCommand(APIBaseCommand): |
| 13 | + NAME = "secret" |
| 14 | + DESCRIPTION = "Manage secrets" |
| 15 | + |
| 16 | + def _register(self): |
| 17 | + super()._register() |
| 18 | + self._parser.set_defaults(subfunc=self._list) |
| 19 | + subparsers = self._parser.add_subparsers(dest="action") |
| 20 | + |
| 21 | + list_parser = subparsers.add_parser( |
| 22 | + "list", help="List secrets", formatter_class=self._parser.formatter_class |
| 23 | + ) |
| 24 | + list_parser.set_defaults(subfunc=self._list) |
| 25 | + |
| 26 | + get_parser = subparsers.add_parser( |
| 27 | + "get", help="Get secret value", formatter_class=self._parser.formatter_class |
| 28 | + ) |
| 29 | + get_parser.add_argument( |
| 30 | + "name", |
| 31 | + help="The name of the secret", |
| 32 | + ).completer = SecretNameCompleter() |
| 33 | + get_parser.set_defaults(subfunc=self._get) |
| 34 | + |
| 35 | + set_parser = subparsers.add_parser( |
| 36 | + "set", help="Set secret", formatter_class=self._parser.formatter_class |
| 37 | + ) |
| 38 | + set_parser.add_argument( |
| 39 | + "name", |
| 40 | + help="The name of the secret", |
| 41 | + ) |
| 42 | + set_parser.add_argument( |
| 43 | + "value", |
| 44 | + help="The value of the secret", |
| 45 | + ) |
| 46 | + set_parser.set_defaults(subfunc=self._set) |
| 47 | + |
| 48 | + delete_parser = subparsers.add_parser( |
| 49 | + "delete", |
| 50 | + help="Delete secrets", |
| 51 | + formatter_class=self._parser.formatter_class, |
| 52 | + ) |
| 53 | + delete_parser.add_argument( |
| 54 | + "name", |
| 55 | + help="The name of the secret", |
| 56 | + ).completer = SecretNameCompleter() |
| 57 | + delete_parser.add_argument( |
| 58 | + "-y", "--yes", help="Don't ask for confirmation", action="store_true" |
| 59 | + ) |
| 60 | + delete_parser.set_defaults(subfunc=self._delete) |
| 61 | + |
| 62 | + def _command(self, args: argparse.Namespace): |
| 63 | + super()._command(args) |
| 64 | + args.subfunc(args) |
| 65 | + |
| 66 | + def _list(self, args: argparse.Namespace): |
| 67 | + secrets = self.api.client.secrets.list(self.api.project) |
| 68 | + print_secrets_table(secrets) |
| 69 | + |
| 70 | + def _get(self, args: argparse.Namespace): |
| 71 | + secret = self.api.client.secrets.get(self.api.project, name=args.name) |
| 72 | + print_secrets_table([secret]) |
| 73 | + |
| 74 | + def _set(self, args: argparse.Namespace): |
| 75 | + self.api.client.secrets.create_or_update( |
| 76 | + self.api.project, |
| 77 | + name=args.name, |
| 78 | + value=args.value, |
| 79 | + ) |
| 80 | + console.print("[grey58]OK[/]") |
| 81 | + |
| 82 | + def _delete(self, args: argparse.Namespace): |
| 83 | + if not args.yes and not confirm_ask(f"Delete the secret [code]{args.name}[/]?"): |
| 84 | + console.print("\nExiting...") |
| 85 | + return |
| 86 | + |
| 87 | + with console.status("Deleting secret..."): |
| 88 | + self.api.client.secrets.delete( |
| 89 | + project_name=self.api.project, |
| 90 | + names=[args.name], |
| 91 | + ) |
| 92 | + console.print("[grey58]OK[/]") |
0 commit comments