|
2 | 2 |
|
3 | 3 | import json |
4 | 4 |
|
| 5 | +import click |
5 | 6 | from cmd2 import Cmd |
6 | 7 |
|
| 8 | +from stackdio.cli.mixins.blueprints import get_blueprint_id |
| 9 | +from stackdio.cli.utils import print_summary |
7 | 10 | from stackdio.client.exceptions import StackException |
8 | 11 |
|
9 | 12 |
|
| 13 | +@click.group() |
| 14 | +def stacks(): |
| 15 | + """ |
| 16 | + Perform actions on stacks |
| 17 | + """ |
| 18 | + pass |
| 19 | + |
| 20 | + |
| 21 | +@stacks.command(name='list') |
| 22 | +@click.pass_obj |
| 23 | +def list_stacks(obj): |
| 24 | + """ |
| 25 | + List all stacks |
| 26 | + """ |
| 27 | + client = obj['client'] |
| 28 | + |
| 29 | + click.echo('Getting stacks ... ') |
| 30 | + print_summary('Stack', client.list_stacks()) |
| 31 | + |
| 32 | + |
| 33 | +@stacks.command(name='launch') |
| 34 | +@click.pass_obj |
| 35 | +@click.argument('blueprint_title') |
| 36 | +@click.argument('stack_title') |
| 37 | +def launch_stack(obj, blueprint_title, stack_title): |
| 38 | + """ |
| 39 | + Launch a stack from a blueprint |
| 40 | + """ |
| 41 | + client = obj['client'] |
| 42 | + |
| 43 | + blueprint_id = get_blueprint_id(client, blueprint_title) |
| 44 | + |
| 45 | + click.echo('Launching stack "{0}" from blueprint "{1}"'.format(stack_title, |
| 46 | + blueprint_title)) |
| 47 | + |
| 48 | + stack_data = { |
| 49 | + 'blueprint': blueprint_id, |
| 50 | + 'title': stack_title, |
| 51 | + 'description': 'Launched from blueprint %s' % (blueprint_title), |
| 52 | + 'namespace': stack_title, |
| 53 | + } |
| 54 | + results = client.create_stack(stack_data) |
| 55 | + click.echo('Stack launch results:\n{0}'.format(results)) |
| 56 | + |
| 57 | + |
| 58 | +def get_stack_id(client, stack_title): |
| 59 | + found_stacks = client.search_stacks(title=stack_title) |
| 60 | + |
| 61 | + if len(found_stacks) == 0: |
| 62 | + raise click.Abort('Stack "{0}" does not exist'.format(stack_title)) |
| 63 | + elif len(found_stacks) > 1: |
| 64 | + raise click.Abort('Multiple stacks matching "{0}" were found'.format(stack_title)) |
| 65 | + else: |
| 66 | + return found_stacks[0]['id'] |
| 67 | + |
| 68 | + |
| 69 | +@stacks.command(name='history') |
| 70 | +@click.pass_obj |
| 71 | +@click.argument('stack_title') |
| 72 | +@click.option('-l', '--length', type=click.INT, default=20, help='The number of entries to show') |
| 73 | +def stack_history(obj, stack_title, length): |
| 74 | + """ |
| 75 | + Print recent history for a stack |
| 76 | + """ |
| 77 | + client = obj['client'] |
| 78 | + |
| 79 | + stack_id = get_stack_id(client, stack_title) |
| 80 | + history = client.get_stack_history(stack_id) |
| 81 | + for event in history[0:min(length, len(history))]: |
| 82 | + click.echo('[{created}] {level} // {event} // {status}'.format(**event)) |
| 83 | + |
| 84 | + |
10 | 85 | class StackMixin(Cmd): |
11 | 86 |
|
12 | 87 | STACK_ACTIONS = ["start", "stop", "launch_existing", "terminate", "provision", "custom"] |
@@ -57,67 +132,6 @@ def do_stacks(self, arg): |
57 | 132 | else: |
58 | 133 | print(USAGE) |
59 | 134 |
|
60 | | - def complete_stacks(self, text, line, begidx, endidx): |
61 | | - # not using line, begidx, or endidx, thus the following pylint disable |
62 | | - # pylint: disable=W0613 |
63 | | - return [i for i in self.STACK_COMMANDS if i.startswith(text)] |
64 | | - |
65 | | - def help_stacks(self): |
66 | | - print("Manage stacks.") |
67 | | - print("Sub-commands can be one of:\n\t{0}".format( |
68 | | - ", ".join(self.STACK_COMMANDS))) |
69 | | - print("Try 'stacks COMMAND' to get help on (most) sub-commands") |
70 | | - |
71 | | - def _list_stacks(self): |
72 | | - """List all running stacks""" |
73 | | - |
74 | | - print("Getting running stacks ... ") |
75 | | - stacks = self.stacks.list_stacks() |
76 | | - self._print_summary("Stack", stacks) |
77 | | - |
78 | | - def _launch_stack(self, args): |
79 | | - """Launch a stack from a blueprint. |
80 | | - Must provide blueprint name and stack name""" |
81 | | - |
82 | | - if len(args) != 2: |
83 | | - print("Usage: stacks launch BLUEPRINT_NAME STACK_NAME") |
84 | | - return |
85 | | - |
86 | | - blueprint_name = args[0] |
87 | | - stack_name = args[1] |
88 | | - |
89 | | - try: |
90 | | - blueprint_id = self.stacks.get_blueprint_id(blueprint_name) |
91 | | - except StackException: |
92 | | - print(self.colorize( |
93 | | - "Blueprint [{0}] does not exist".format(blueprint_name), |
94 | | - "red")) |
95 | | - return |
96 | | - |
97 | | - print("Launching stack [{0}] from blueprint [{1}]".format( |
98 | | - stack_name, blueprint_name)) |
99 | | - |
100 | | - stack_data = { |
101 | | - "blueprint": blueprint_id, |
102 | | - "title": stack_name, |
103 | | - "description": "Launched from blueprint %s" % (blueprint_name), |
104 | | - "namespace": stack_name, |
105 | | - "max_retries": 1, |
106 | | - } |
107 | | - results = self.stacks.create_stack(stack_data) |
108 | | - print("Stack launch results:\n{0}".format(results)) |
109 | | - |
110 | | - def _get_stack_id(self, stack_name): |
111 | | - """Validate that a stack exists""" |
112 | | - |
113 | | - try: |
114 | | - return self.stacks.get_stack_id(stack_name) |
115 | | - except StackException: |
116 | | - print(self.colorize( |
117 | | - "Stack [{0}] does not exist".format(stack_name), |
118 | | - "red")) |
119 | | - raise |
120 | | - |
121 | 135 | def _stack_action(self, args): |
122 | 136 | """Perform an action on a stack.""" |
123 | 137 |
|
@@ -165,19 +179,6 @@ def _stack_action(self, args): |
165 | 179 | results = self.stacks.do_stack_action(stack_id, action) |
166 | 180 | print("Stack action results:\n{0}".format(json.dumps(results, indent=3))) |
167 | 181 |
|
168 | | - def _stack_history(self, args): |
169 | | - """Print recent history for a stack""" |
170 | | - |
171 | | - NUM_EVENTS = 20 |
172 | | - if len(args) < 1: |
173 | | - print("Usage: stacks history STACK_NAME") |
174 | | - return |
175 | | - |
176 | | - stack_id = self._get_stack_id(args[0]) |
177 | | - history = self.stacks.get_stack_history(stack_id).get("results") |
178 | | - for event in history[0:min(NUM_EVENTS, len(history))]: |
179 | | - print("[{created}] {level} // {event} // {status}".format(**event)) |
180 | | - |
181 | 182 | def _stack_hostnames(self, args): |
182 | 183 | """Print hostnames for a stack""" |
183 | 184 |
|
|
0 commit comments