outerbounds 0.3.87rc0__py3-none-any.whl → 0.3.88__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.
- outerbounds/command_groups/cli.py +1 -7
- outerbounds/utils/schema.py +2 -2
- {outerbounds-0.3.87rc0.dist-info → outerbounds-0.3.88.dist-info}/METADATA +4 -5
- {outerbounds-0.3.87rc0.dist-info → outerbounds-0.3.88.dist-info}/RECORD +6 -7
- outerbounds/command_groups/apps_cli.py +0 -511
- {outerbounds-0.3.87rc0.dist-info → outerbounds-0.3.88.dist-info}/WHEEL +0 -0
- {outerbounds-0.3.87rc0.dist-info → outerbounds-0.3.88.dist-info}/entry_points.txt +0 -0
@@ -2,17 +2,11 @@ from outerbounds._vendor import click
|
|
2
2
|
from . import local_setup_cli
|
3
3
|
from . import workstations_cli
|
4
4
|
from . import perimeters_cli
|
5
|
-
from . import apps_cli
|
6
5
|
|
7
6
|
|
8
7
|
@click.command(
|
9
8
|
cls=click.CommandCollection,
|
10
|
-
sources=[
|
11
|
-
local_setup_cli.cli,
|
12
|
-
workstations_cli.cli,
|
13
|
-
perimeters_cli.cli,
|
14
|
-
apps_cli.cli,
|
15
|
-
],
|
9
|
+
sources=[local_setup_cli.cli, workstations_cli.cli, perimeters_cli.cli],
|
16
10
|
)
|
17
11
|
def cli(**kwargs):
|
18
12
|
pass
|
outerbounds/utils/schema.py
CHANGED
@@ -59,14 +59,14 @@ class OuterboundsCommandResponse:
|
|
59
59
|
if step.status == OuterboundsCommandStatus.FAIL:
|
60
60
|
self.status = OuterboundsCommandStatus.FAIL
|
61
61
|
self._code = 500
|
62
|
-
self._message = "
|
62
|
+
self._message = "We found one or more errors with your installation."
|
63
63
|
elif (
|
64
64
|
step.status == OuterboundsCommandStatus.WARN
|
65
65
|
and self.status != OuterboundsCommandStatus.FAIL
|
66
66
|
):
|
67
67
|
self.status = OuterboundsCommandStatus.WARN
|
68
68
|
self._code = 200
|
69
|
-
self._message = "
|
69
|
+
self._message = "We found one or more warnings with your installation."
|
70
70
|
|
71
71
|
def as_dict(self):
|
72
72
|
self._data["steps"] = [step.as_dict() for step in self._steps]
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: outerbounds
|
3
|
-
Version: 0.3.
|
3
|
+
Version: 0.3.88
|
4
4
|
Summary: More Data Science, Less Administration
|
5
5
|
License: Proprietary
|
6
6
|
Keywords: data science,machine learning,MLOps
|
@@ -14,7 +14,6 @@ Classifier: Programming Language :: Python :: 3.8
|
|
14
14
|
Classifier: Programming Language :: Python :: 3.9
|
15
15
|
Classifier: Programming Language :: Python :: 3.10
|
16
16
|
Classifier: Programming Language :: Python :: 3.11
|
17
|
-
Provides-Extra: apps
|
18
17
|
Provides-Extra: azure
|
19
18
|
Provides-Extra: gcp
|
20
19
|
Requires-Dist: azure-identity (>=1.15.0,<2.0.0) ; extra == "azure"
|
@@ -25,9 +24,9 @@ Requires-Dist: google-api-core (>=2.16.1,<3.0.0) ; extra == "gcp"
|
|
25
24
|
Requires-Dist: google-auth (>=2.27.0,<3.0.0) ; extra == "gcp"
|
26
25
|
Requires-Dist: google-cloud-secret-manager (>=2.20.0,<3.0.0) ; extra == "gcp"
|
27
26
|
Requires-Dist: google-cloud-storage (>=2.14.0,<3.0.0) ; extra == "gcp"
|
28
|
-
Requires-Dist: ob-metaflow (==2.12.
|
29
|
-
Requires-Dist: ob-metaflow-extensions (==1.1.
|
30
|
-
Requires-Dist: ob-metaflow-stubs (==5.
|
27
|
+
Requires-Dist: ob-metaflow (==2.12.12.0)
|
28
|
+
Requires-Dist: ob-metaflow-extensions (==1.1.79)
|
29
|
+
Requires-Dist: ob-metaflow-stubs (==5.2)
|
31
30
|
Requires-Dist: opentelemetry-distro (==0.41b0)
|
32
31
|
Requires-Dist: opentelemetry-exporter-otlp-proto-http (==1.20.0)
|
33
32
|
Requires-Dist: opentelemetry-instrumentation-requests (==0.41b0)
|
@@ -41,17 +41,16 @@ outerbounds/_vendor/yaml/serializer.py,sha256=8wFZRy9SsQSktF_f9OOroroqsh4qVUe53r
|
|
41
41
|
outerbounds/_vendor/yaml/tokens.py,sha256=JBSu38wihGr4l73JwbfMA7Ks1-X84g8-NskTz7KwPmA,2578
|
42
42
|
outerbounds/cli_main.py,sha256=e9UMnPysmc7gbrimq2I4KfltggyU7pw59Cn9aEguVcU,74
|
43
43
|
outerbounds/command_groups/__init__.py,sha256=QPWtj5wDRTINDxVUL7XPqG3HoxHNvYOg08EnuSZB2Hc,21
|
44
|
-
outerbounds/command_groups/
|
45
|
-
outerbounds/command_groups/cli.py,sha256=3NyxnczfANtxKh-KnJHGWAEC5akdXux_hylfGXTs2A0,362
|
44
|
+
outerbounds/command_groups/cli.py,sha256=sorDdQvmTPqIwfvgtuNLILelimXu5CknFnWQFsYFGHs,286
|
46
45
|
outerbounds/command_groups/local_setup_cli.py,sha256=somQMeLgRSK8BAje2rN6LeY-lszXmwBpNLvDCk293h8,36554
|
47
46
|
outerbounds/command_groups/perimeters_cli.py,sha256=vU1LykO9T2Xj4Fn8hyhaCUR4q454q1aVoU4XhhrgAS4,12781
|
48
47
|
outerbounds/command_groups/workstations_cli.py,sha256=V5Jbj1cVb4IRllI7fOgNgL6OekRpuFDv6CEhDb4xC6w,22016
|
49
48
|
outerbounds/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
50
49
|
outerbounds/utils/kubeconfig.py,sha256=yvcyRXGR4AhQuqUDqmbGxEOHw5ixMFV0AZIDg1LI_Qo,7981
|
51
50
|
outerbounds/utils/metaflowconfig.py,sha256=Ja1eufYm4UANRNpk7qlxg_UUudToDOVCjaWg88N-xhQ,3538
|
52
|
-
outerbounds/utils/schema.py,sha256=
|
51
|
+
outerbounds/utils/schema.py,sha256=cNlgjmteLPbDzSEUSQDsq8txdhMGyezSmM83jU3aa0w,2329
|
53
52
|
outerbounds/vendor.py,sha256=gRLRJNXtZBeUpPEog0LOeIsl6GosaFFbCxUvR4bW6IQ,5093
|
54
|
-
outerbounds-0.3.
|
55
|
-
outerbounds-0.3.
|
56
|
-
outerbounds-0.3.
|
57
|
-
outerbounds-0.3.
|
53
|
+
outerbounds-0.3.88.dist-info/entry_points.txt,sha256=7ye0281PKlvqxu15rjw60zKg2pMsXI49_A8BmGqIqBw,47
|
54
|
+
outerbounds-0.3.88.dist-info/WHEEL,sha256=vVCvjcmxuUltf8cYhJ0sJMRDLr1XsPuxEId8YDzbyCY,88
|
55
|
+
outerbounds-0.3.88.dist-info/METADATA,sha256=Pg9IyVEEVQpR91fgtQL43o0fBVwNzGUBJ0GSprAT4DY,1632
|
56
|
+
outerbounds-0.3.88.dist-info/RECORD,,
|
@@ -1,511 +0,0 @@
|
|
1
|
-
import base64
|
2
|
-
import hashlib
|
3
|
-
import json
|
4
|
-
import os
|
5
|
-
import re
|
6
|
-
import subprocess
|
7
|
-
import sys
|
8
|
-
import zlib
|
9
|
-
from base64 import b64decode, b64encode
|
10
|
-
from importlib.machinery import PathFinder
|
11
|
-
from os import path
|
12
|
-
from pathlib import Path
|
13
|
-
from typing import Any, Callable, Dict, List
|
14
|
-
from outerbounds._vendor import click
|
15
|
-
import requests
|
16
|
-
from requests.exceptions import HTTPError
|
17
|
-
|
18
|
-
from ..utils import metaflowconfig
|
19
|
-
from ..utils.schema import (
|
20
|
-
CommandStatus,
|
21
|
-
OuterboundsCommandResponse,
|
22
|
-
OuterboundsCommandStatus,
|
23
|
-
)
|
24
|
-
|
25
|
-
|
26
|
-
@click.group()
|
27
|
-
def cli(**kwargs):
|
28
|
-
pass
|
29
|
-
|
30
|
-
|
31
|
-
@click.group(help="Manage perimeters")
|
32
|
-
def app(**kwargs):
|
33
|
-
pass
|
34
|
-
|
35
|
-
|
36
|
-
@app.command(help="Start an app using a port and a name")
|
37
|
-
@click.option(
|
38
|
-
"-d",
|
39
|
-
"--config-dir",
|
40
|
-
default=path.expanduser(os.environ.get("METAFLOW_HOME", "~/.metaflowconfig")),
|
41
|
-
help="Path to Metaflow configuration directory",
|
42
|
-
show_default=True,
|
43
|
-
)
|
44
|
-
@click.option(
|
45
|
-
"-p",
|
46
|
-
"--profile",
|
47
|
-
default=os.environ.get("METAFLOW_PROFILE", ""),
|
48
|
-
help="The named metaflow profile in which your workstation exists",
|
49
|
-
)
|
50
|
-
@click.option(
|
51
|
-
"--port",
|
52
|
-
required=True,
|
53
|
-
help="Port number where you want to start your app.",
|
54
|
-
type=int,
|
55
|
-
)
|
56
|
-
@click.option(
|
57
|
-
"--name",
|
58
|
-
required=True,
|
59
|
-
help="Name of your app",
|
60
|
-
type=str,
|
61
|
-
)
|
62
|
-
@click.option(
|
63
|
-
"-o",
|
64
|
-
"--output",
|
65
|
-
default="",
|
66
|
-
help="Show output in the specified format.",
|
67
|
-
type=click.Choice(["json", ""]),
|
68
|
-
)
|
69
|
-
def start(config_dir=None, profile=None, port=-1, name="", output=""):
|
70
|
-
start_app_response = OuterboundsCommandResponse()
|
71
|
-
|
72
|
-
validate_workstation_step = CommandStatus(
|
73
|
-
"ValidateRunningOnWorkstation",
|
74
|
-
OuterboundsCommandStatus.OK,
|
75
|
-
"Command is being run on a workstation.",
|
76
|
-
)
|
77
|
-
|
78
|
-
list_workstations_step = CommandStatus(
|
79
|
-
"ListWorkstations",
|
80
|
-
OuterboundsCommandStatus.OK,
|
81
|
-
"List of workstations fetched.",
|
82
|
-
)
|
83
|
-
|
84
|
-
validate_port_exists = CommandStatus(
|
85
|
-
"ValidatePortExists",
|
86
|
-
OuterboundsCommandStatus.OK,
|
87
|
-
"Port exists on workstation",
|
88
|
-
)
|
89
|
-
|
90
|
-
start_app_step = CommandStatus(
|
91
|
-
"StartApp",
|
92
|
-
OuterboundsCommandStatus.OK,
|
93
|
-
f"App {name} started on port {port}!",
|
94
|
-
)
|
95
|
-
|
96
|
-
if "WORKSTATION_ID" not in os.environ:
|
97
|
-
validate_workstation_step.update(
|
98
|
-
OuterboundsCommandStatus.FAIL,
|
99
|
-
"All outerbounds app commands can only be run from a workstation.",
|
100
|
-
"",
|
101
|
-
)
|
102
|
-
start_app_response.add_step(validate_workstation_step)
|
103
|
-
click.secho(
|
104
|
-
"All outerbounds app commands can only be run from a workstation.",
|
105
|
-
fg="red",
|
106
|
-
err=True,
|
107
|
-
)
|
108
|
-
|
109
|
-
if output == "json":
|
110
|
-
click.echo(json.dumps(start_app_response.as_dict(), indent=4))
|
111
|
-
return
|
112
|
-
|
113
|
-
try:
|
114
|
-
try:
|
115
|
-
metaflow_token = metaflowconfig.get_metaflow_token_from_config(
|
116
|
-
config_dir, profile
|
117
|
-
)
|
118
|
-
api_url = metaflowconfig.get_sanitized_url_from_config(
|
119
|
-
config_dir, profile, "OBP_API_SERVER"
|
120
|
-
)
|
121
|
-
|
122
|
-
workstations_response = requests.get(
|
123
|
-
f"{api_url}/v1/workstations", headers={"x-api-key": metaflow_token}
|
124
|
-
)
|
125
|
-
workstations_response.raise_for_status()
|
126
|
-
start_app_response.add_step(list_workstations_step)
|
127
|
-
except:
|
128
|
-
click.secho("Failed to list workstations!", fg="red", err=True)
|
129
|
-
list_workstations_step.update(
|
130
|
-
OuterboundsCommandStatus.FAIL, "Failed to list workstations!", ""
|
131
|
-
)
|
132
|
-
start_app_response.add_step(list_workstations_step)
|
133
|
-
if output == "json":
|
134
|
-
click.echo(json.dumps(start_app_response.as_dict(), indent=4))
|
135
|
-
return
|
136
|
-
|
137
|
-
workstations_json = workstations_response.json()["workstations"]
|
138
|
-
for workstation in workstations_json:
|
139
|
-
if workstation["instance_id"] == os.environ["WORKSTATION_ID"]:
|
140
|
-
if "named_ports" in workstation["spec"]:
|
141
|
-
for named_port in workstation["spec"]["named_ports"]:
|
142
|
-
if int(named_port["port"]) == port:
|
143
|
-
start_app_response.add_step(validate_port_exists)
|
144
|
-
if named_port["enabled"] and named_port["name"] == name:
|
145
|
-
click.secho(
|
146
|
-
f"App {name} started on port {port}!",
|
147
|
-
fg="green",
|
148
|
-
err=True,
|
149
|
-
)
|
150
|
-
start_app_response.add_step(start_app_step)
|
151
|
-
if output == "json":
|
152
|
-
click.echo(
|
153
|
-
json.dumps(
|
154
|
-
start_app_response.as_dict(), indent=4
|
155
|
-
)
|
156
|
-
)
|
157
|
-
return
|
158
|
-
else:
|
159
|
-
try:
|
160
|
-
response = requests.put(
|
161
|
-
f"{api_url}/v1/workstations/update/{os.environ['WORKSTATION_ID']}/namedports",
|
162
|
-
headers={"x-api-key": metaflow_token},
|
163
|
-
json={
|
164
|
-
"port": port,
|
165
|
-
"name": name,
|
166
|
-
"enabled": True,
|
167
|
-
},
|
168
|
-
)
|
169
|
-
|
170
|
-
response.raise_for_status()
|
171
|
-
click.secho(
|
172
|
-
f"App {name} started on port {port}!",
|
173
|
-
fg="green",
|
174
|
-
err=True,
|
175
|
-
)
|
176
|
-
except:
|
177
|
-
click.secho(
|
178
|
-
f"Failed to start app {name} on port {port}!",
|
179
|
-
fg="red",
|
180
|
-
err=True,
|
181
|
-
)
|
182
|
-
start_app_step.update(
|
183
|
-
OuterboundsCommandStatus.FAIL,
|
184
|
-
f"Failed to start app {name} on port {port}!",
|
185
|
-
"",
|
186
|
-
)
|
187
|
-
|
188
|
-
start_app_response.add_step(start_app_step)
|
189
|
-
if output == "json":
|
190
|
-
click.echo(
|
191
|
-
json.dumps(
|
192
|
-
start_app_response.as_dict(), indent=4
|
193
|
-
)
|
194
|
-
)
|
195
|
-
return
|
196
|
-
|
197
|
-
click.secho(
|
198
|
-
f"Port {port} not found on workstation {os.environ['WORKSTATION_ID']}",
|
199
|
-
fg="red",
|
200
|
-
err=True,
|
201
|
-
)
|
202
|
-
validate_port_exists.update(
|
203
|
-
OuterboundsCommandStatus.FAIL,
|
204
|
-
f"Port {port} not found on workstation {os.environ['WORKSTATION_ID']}",
|
205
|
-
"",
|
206
|
-
)
|
207
|
-
start_app_response.add_step(validate_port_exists)
|
208
|
-
if output == "json":
|
209
|
-
click.echo(json.dumps(start_app_response.as_dict(), indent=4))
|
210
|
-
except Exception as e:
|
211
|
-
click.secho(f"Failed to start app {name} on port {port}!", fg="red", err=True)
|
212
|
-
start_app_step.update(
|
213
|
-
OuterboundsCommandStatus.FAIL,
|
214
|
-
f"Failed to start app {name} on port {port}!",
|
215
|
-
"",
|
216
|
-
)
|
217
|
-
start_app_response.add_step(start_app_step)
|
218
|
-
if output == "json":
|
219
|
-
click.secho(json.dumps(start_app_response.as_dict(), indent=4))
|
220
|
-
|
221
|
-
|
222
|
-
@app.command(help="Stop an app using its port number")
|
223
|
-
@click.option(
|
224
|
-
"-d",
|
225
|
-
"--config-dir",
|
226
|
-
default=path.expanduser(os.environ.get("METAFLOW_HOME", "~/.metaflowconfig")),
|
227
|
-
help="Path to Metaflow configuration directory",
|
228
|
-
show_default=True,
|
229
|
-
)
|
230
|
-
@click.option(
|
231
|
-
"-p",
|
232
|
-
"--profile",
|
233
|
-
default=os.environ.get("METAFLOW_PROFILE", ""),
|
234
|
-
help="The named metaflow profile in which your workstation exists",
|
235
|
-
)
|
236
|
-
@click.option(
|
237
|
-
"--port",
|
238
|
-
required=True,
|
239
|
-
help="Port number where you want to start your app.",
|
240
|
-
type=int,
|
241
|
-
)
|
242
|
-
@click.option(
|
243
|
-
"-o",
|
244
|
-
"--output",
|
245
|
-
default="",
|
246
|
-
help="Show output in the specified format.",
|
247
|
-
type=click.Choice(["json", ""]),
|
248
|
-
)
|
249
|
-
def stop(config_dir=None, profile=None, port=-1, output=""):
|
250
|
-
stop_app_response = OuterboundsCommandResponse()
|
251
|
-
|
252
|
-
validate_workstation_step = CommandStatus(
|
253
|
-
"ValidateRunningOnWorkstation",
|
254
|
-
OuterboundsCommandStatus.OK,
|
255
|
-
"Command is being run on a workstation.",
|
256
|
-
)
|
257
|
-
|
258
|
-
list_workstations_step = CommandStatus(
|
259
|
-
"ListWorkstations",
|
260
|
-
OuterboundsCommandStatus.OK,
|
261
|
-
"List of workstations fetched.",
|
262
|
-
)
|
263
|
-
|
264
|
-
validate_port_exists = CommandStatus(
|
265
|
-
"ValidatePortExists",
|
266
|
-
OuterboundsCommandStatus.OK,
|
267
|
-
"Port exists on workstation",
|
268
|
-
)
|
269
|
-
|
270
|
-
stop_app_step = CommandStatus(
|
271
|
-
"StopApp",
|
272
|
-
OuterboundsCommandStatus.OK,
|
273
|
-
f"App stopped on port {port}!",
|
274
|
-
)
|
275
|
-
|
276
|
-
if "WORKSTATION_ID" not in os.environ:
|
277
|
-
validate_workstation_step.update(
|
278
|
-
OuterboundsCommandStatus.FAIL,
|
279
|
-
"All outerbounds app commands can only be run from a workstation.",
|
280
|
-
"",
|
281
|
-
)
|
282
|
-
stop_app_response.add_step(validate_workstation_step)
|
283
|
-
click.secho(
|
284
|
-
"All outerbounds app commands can only be run from a workstation.",
|
285
|
-
fg="red",
|
286
|
-
err=True,
|
287
|
-
)
|
288
|
-
|
289
|
-
if output == "json":
|
290
|
-
click.echo(json.dumps(stop_app_response.as_dict(), indent=4))
|
291
|
-
return
|
292
|
-
|
293
|
-
try:
|
294
|
-
try:
|
295
|
-
metaflow_token = metaflowconfig.get_metaflow_token_from_config(
|
296
|
-
config_dir, profile
|
297
|
-
)
|
298
|
-
api_url = metaflowconfig.get_sanitized_url_from_config(
|
299
|
-
config_dir, profile, "OBP_API_SERVER"
|
300
|
-
)
|
301
|
-
|
302
|
-
workstations_response = requests.get(
|
303
|
-
f"{api_url}/v1/workstations", headers={"x-api-key": metaflow_token}
|
304
|
-
)
|
305
|
-
workstations_response.raise_for_status()
|
306
|
-
stop_app_response.add_step(list_workstations_step)
|
307
|
-
except:
|
308
|
-
click.secho("Failed to list workstations!", fg="red", err=True)
|
309
|
-
list_workstations_step.update(
|
310
|
-
OuterboundsCommandStatus.FAIL, "Failed to list workstations!", ""
|
311
|
-
)
|
312
|
-
stop_app_response.add_step(list_workstations_step)
|
313
|
-
if output == "json":
|
314
|
-
click.echo(json.dumps(stop_app_response.as_dict(), indent=4))
|
315
|
-
return
|
316
|
-
|
317
|
-
workstations_json = workstations_response.json()["workstations"]
|
318
|
-
for workstation in workstations_json:
|
319
|
-
if workstation["instance_id"] == os.environ["WORKSTATION_ID"]:
|
320
|
-
if "named_ports" in workstation["spec"]:
|
321
|
-
for named_port in workstation["spec"]["named_ports"]:
|
322
|
-
if int(named_port["port"]) == port:
|
323
|
-
stop_app_response.add_step(validate_port_exists)
|
324
|
-
if not named_port["enabled"]:
|
325
|
-
click.secho(
|
326
|
-
f"App stopped on port {port}!", fg="green", err=True
|
327
|
-
)
|
328
|
-
stop_app_response.add_step(stop_app_step)
|
329
|
-
if output == "json":
|
330
|
-
click.echo(
|
331
|
-
json.dumps(
|
332
|
-
stop_app_response.as_dict(), indent=4
|
333
|
-
)
|
334
|
-
)
|
335
|
-
return
|
336
|
-
else:
|
337
|
-
try:
|
338
|
-
response = requests.put(
|
339
|
-
f"{api_url}/v1/workstations/update/{os.environ['WORKSTATION_ID']}/namedports",
|
340
|
-
headers={"x-api-key": metaflow_token},
|
341
|
-
json={
|
342
|
-
"port": port,
|
343
|
-
"name": named_port["name"],
|
344
|
-
"enabled": False,
|
345
|
-
},
|
346
|
-
)
|
347
|
-
response.raise_for_status()
|
348
|
-
click.secho(
|
349
|
-
f"App stopped on port {port}!",
|
350
|
-
fg="green",
|
351
|
-
err=True,
|
352
|
-
)
|
353
|
-
except:
|
354
|
-
click.secho(
|
355
|
-
f"Failed to stop app on port {port}!",
|
356
|
-
fg="red",
|
357
|
-
err=True,
|
358
|
-
)
|
359
|
-
stop_app_step.update(
|
360
|
-
OuterboundsCommandStatus.FAIL,
|
361
|
-
f"Failed to stop app on port {port}!",
|
362
|
-
"",
|
363
|
-
)
|
364
|
-
|
365
|
-
stop_app_response.add_step(stop_app_step)
|
366
|
-
if output == "json":
|
367
|
-
click.echo(
|
368
|
-
json.dumps(
|
369
|
-
stop_app_response.as_dict(), indent=4
|
370
|
-
)
|
371
|
-
)
|
372
|
-
return
|
373
|
-
|
374
|
-
click.secho(
|
375
|
-
f"Port {port} not found on workstation {os.environ['WORKSTATION_ID']}",
|
376
|
-
fg="red",
|
377
|
-
err=True,
|
378
|
-
)
|
379
|
-
validate_port_exists.update(
|
380
|
-
OuterboundsCommandStatus.FAIL,
|
381
|
-
f"Port {port} not found on workstation {os.environ['WORKSTATION_ID']}",
|
382
|
-
"",
|
383
|
-
)
|
384
|
-
stop_app_response.add_step(validate_port_exists)
|
385
|
-
if output == "json":
|
386
|
-
click.echo(json.dumps(stop_app_response.as_dict(), indent=4))
|
387
|
-
except Exception as e:
|
388
|
-
click.secho(f"Failed to stop app on port {port}!", fg="red", err=True)
|
389
|
-
stop_app_step.update(
|
390
|
-
OuterboundsCommandStatus.FAIL, f"Failed to stop on port {port}!", ""
|
391
|
-
)
|
392
|
-
stop_app_response.add_step(stop_app_step)
|
393
|
-
if output == "json":
|
394
|
-
click.echo(json.dumps(stop_app_response.as_dict(), indent=4))
|
395
|
-
|
396
|
-
|
397
|
-
@app.command(help="Stop an app using its port number")
|
398
|
-
@click.option(
|
399
|
-
"-d",
|
400
|
-
"--config-dir",
|
401
|
-
default=path.expanduser(os.environ.get("METAFLOW_HOME", "~/.metaflowconfig")),
|
402
|
-
help="Path to Metaflow configuration directory",
|
403
|
-
show_default=True,
|
404
|
-
)
|
405
|
-
@click.option(
|
406
|
-
"-p",
|
407
|
-
"--profile",
|
408
|
-
default=os.environ.get("METAFLOW_PROFILE", ""),
|
409
|
-
help="The named metaflow profile in which your workstation exists",
|
410
|
-
)
|
411
|
-
@click.option(
|
412
|
-
"-o",
|
413
|
-
"--output",
|
414
|
-
default="",
|
415
|
-
help="Show output in the specified format.",
|
416
|
-
type=click.Choice(["json", ""]),
|
417
|
-
)
|
418
|
-
def list(config_dir=None, profile=None, output=""):
|
419
|
-
list_app_response = OuterboundsCommandResponse()
|
420
|
-
|
421
|
-
validate_workstation_step = CommandStatus(
|
422
|
-
"ValidateRunningOnWorkstation",
|
423
|
-
OuterboundsCommandStatus.OK,
|
424
|
-
"Command is being run on a workstation.",
|
425
|
-
)
|
426
|
-
|
427
|
-
list_workstations_step = CommandStatus(
|
428
|
-
"ListWorkstations",
|
429
|
-
OuterboundsCommandStatus.OK,
|
430
|
-
"List of workstations fetched.",
|
431
|
-
)
|
432
|
-
|
433
|
-
if "WORKSTATION_ID" not in os.environ:
|
434
|
-
validate_workstation_step.update(
|
435
|
-
OuterboundsCommandStatus.FAIL,
|
436
|
-
"All outerbounds app commands can only be run from a workstation.",
|
437
|
-
"",
|
438
|
-
)
|
439
|
-
list_app_response.add_step(validate_workstation_step)
|
440
|
-
click.secho(
|
441
|
-
"All outerbounds app commands can only be run from a workstation.",
|
442
|
-
fg="red",
|
443
|
-
err=True,
|
444
|
-
)
|
445
|
-
|
446
|
-
if output == "json":
|
447
|
-
click.echo(json.dumps(list_app_response.as_dict(), indent=4))
|
448
|
-
return
|
449
|
-
|
450
|
-
try:
|
451
|
-
try:
|
452
|
-
metaflow_token = metaflowconfig.get_metaflow_token_from_config(
|
453
|
-
config_dir, profile
|
454
|
-
)
|
455
|
-
api_url = metaflowconfig.get_sanitized_url_from_config(
|
456
|
-
config_dir, profile, "OBP_API_SERVER"
|
457
|
-
)
|
458
|
-
|
459
|
-
workstations_response = requests.get(
|
460
|
-
f"{api_url}/v1/workstations", headers={"x-api-key": metaflow_token}
|
461
|
-
)
|
462
|
-
workstations_response.raise_for_status()
|
463
|
-
list_app_response.add_step(list_workstations_step)
|
464
|
-
except:
|
465
|
-
click.secho("Failed to list workstations!", fg="red", err=True)
|
466
|
-
list_workstations_step.update(
|
467
|
-
OuterboundsCommandStatus.FAIL, "Failed to list workstations!", ""
|
468
|
-
)
|
469
|
-
list_app_response.add_step(list_workstations_step)
|
470
|
-
if output == "json":
|
471
|
-
click.echo(json.dumps(list_app_response.as_dict(), indent=4))
|
472
|
-
return
|
473
|
-
|
474
|
-
workstations_json = workstations_response.json()["workstations"]
|
475
|
-
for workstation in workstations_json:
|
476
|
-
if workstation["instance_id"] == os.environ["WORKSTATION_ID"]:
|
477
|
-
if "named_ports" in workstation["spec"]:
|
478
|
-
for named_port in workstation["spec"]["named_ports"]:
|
479
|
-
if named_port["enabled"]:
|
480
|
-
click.secho(
|
481
|
-
f"App Name: {named_port['name']}", fg="green", err=True
|
482
|
-
)
|
483
|
-
click.secho(
|
484
|
-
f"App Port on Workstation: {named_port['port']}",
|
485
|
-
fg="green",
|
486
|
-
err=True,
|
487
|
-
)
|
488
|
-
click.secho(f"App Status: Deployed", fg="green", err=True)
|
489
|
-
click.secho(
|
490
|
-
f"App URL: {api_url.replace('api', 'ui')}/apps/{os.environ['WORKSTATION_ID']}/{named_port['name']}/",
|
491
|
-
fg="green",
|
492
|
-
err=True,
|
493
|
-
)
|
494
|
-
else:
|
495
|
-
click.secho(
|
496
|
-
f"App Port on Workstation: {named_port['port']}",
|
497
|
-
fg="yellow",
|
498
|
-
err=True,
|
499
|
-
)
|
500
|
-
click.secho(
|
501
|
-
f"App Status: Not Deployed", fg="yellow", err=True
|
502
|
-
)
|
503
|
-
|
504
|
-
click.echo("\n", err=True)
|
505
|
-
except Exception as e:
|
506
|
-
click.secho(f"Failed to list apps!", fg="red", err=True)
|
507
|
-
if output == "json":
|
508
|
-
click.echo(json.dumps(list_app_response.as_dict(), indent=4))
|
509
|
-
|
510
|
-
|
511
|
-
cli.add_command(app, name="app")
|
File without changes
|
File without changes
|