proximl 0.5.5__tar.gz → 0.5.7__tar.gz
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.
- {proximl-0.5.5/proximl.egg-info → proximl-0.5.7}/PKG-INFO +1 -1
- {proximl-0.5.5 → proximl-0.5.7}/proximl/__init__.py +1 -1
- {proximl-0.5.5 → proximl-0.5.7}/proximl/checkpoints.py +25 -25
- {proximl-0.5.5 → proximl-0.5.7}/proximl/cli/cloudbender/__init__.py +2 -1
- proximl-0.5.5/proximl/cli/cloudbender/reservation.py → proximl-0.5.7/proximl/cli/cloudbender/data_connector.py +45 -45
- proximl-0.5.7/proximl/cli/cloudbender/service.py +146 -0
- {proximl-0.5.5 → proximl-0.5.7}/proximl/cli/project.py +10 -15
- {proximl-0.5.5 → proximl-0.5.7}/proximl/cloudbender/cloudbender.py +4 -2
- proximl-0.5.5/proximl/cloudbender/reservations.py → proximl-0.5.7/proximl/cloudbender/data_connectors.py +24 -38
- proximl-0.5.7/proximl/cloudbender/services.py +179 -0
- {proximl-0.5.5 → proximl-0.5.7}/proximl/datasets.py +19 -8
- {proximl-0.5.5 → proximl-0.5.7}/proximl/jobs.py +13 -6
- {proximl-0.5.5 → proximl-0.5.7}/proximl/models.py +22 -19
- {proximl-0.5.5 → proximl-0.5.7}/proximl/projects.py +72 -31
- {proximl-0.5.5 → proximl-0.5.7}/proximl/volumes.py +9 -2
- {proximl-0.5.5 → proximl-0.5.7/proximl.egg-info}/PKG-INFO +1 -1
- {proximl-0.5.5 → proximl-0.5.7}/proximl.egg-info/SOURCES.txt +7 -4
- {proximl-0.5.5 → proximl-0.5.7}/pyproject.toml +2 -1
- {proximl-0.5.5 → proximl-0.5.7}/tests/integration/test_jobs_integration.py +13 -0
- proximl-0.5.7/tests/unit/cli/cloudbender/test_cli_service_unit.py +34 -0
- {proximl-0.5.5 → proximl-0.5.7}/tests/unit/cli/test_cli_project_unit.py +5 -9
- proximl-0.5.7/tests/unit/cloudbender/test_data_connectors_unit.py +176 -0
- proximl-0.5.7/tests/unit/cloudbender/test_services_unit.py +167 -0
- {proximl-0.5.5 → proximl-0.5.7}/tests/unit/conftest.py +13 -13
- {proximl-0.5.5 → proximl-0.5.7}/tests/unit/test_projects_unit.py +77 -51
- proximl-0.5.5/tests/unit/cli/cloudbender/test_cli_reservation_unit.py +0 -38
- proximl-0.5.5/tests/unit/cloudbender/test_reservations_unit.py +0 -173
- {proximl-0.5.5 → proximl-0.5.7}/LICENSE +0 -0
- {proximl-0.5.5 → proximl-0.5.7}/README.md +0 -0
- {proximl-0.5.5 → proximl-0.5.7}/examples/__init__.py +0 -0
- {proximl-0.5.5 → proximl-0.5.7}/examples/create_dataset_and_training_job.py +0 -0
- {proximl-0.5.5 → proximl-0.5.7}/examples/local_storage.py +0 -0
- {proximl-0.5.5 → proximl-0.5.7}/examples/training_inference_pipeline.py +0 -0
- {proximl-0.5.5 → proximl-0.5.7}/proximl/__main__.py +0 -0
- {proximl-0.5.5 → proximl-0.5.7}/proximl/auth.py +0 -0
- {proximl-0.5.5 → proximl-0.5.7}/proximl/cli/__init__.py +0 -0
- {proximl-0.5.5 → proximl-0.5.7}/proximl/cli/checkpoint.py +0 -0
- {proximl-0.5.5 → proximl-0.5.7}/proximl/cli/cloudbender/datastore.py +0 -0
- {proximl-0.5.5 → proximl-0.5.7}/proximl/cli/cloudbender/device.py +0 -0
- {proximl-0.5.5 → proximl-0.5.7}/proximl/cli/cloudbender/node.py +0 -0
- {proximl-0.5.5 → proximl-0.5.7}/proximl/cli/cloudbender/provider.py +0 -0
- {proximl-0.5.5 → proximl-0.5.7}/proximl/cli/cloudbender/region.py +0 -0
- {proximl-0.5.5 → proximl-0.5.7}/proximl/cli/connection.py +0 -0
- {proximl-0.5.5 → proximl-0.5.7}/proximl/cli/dataset.py +0 -0
- {proximl-0.5.5 → proximl-0.5.7}/proximl/cli/environment.py +0 -0
- {proximl-0.5.5 → proximl-0.5.7}/proximl/cli/gpu.py +0 -0
- {proximl-0.5.5 → proximl-0.5.7}/proximl/cli/job/__init__.py +0 -0
- {proximl-0.5.5 → proximl-0.5.7}/proximl/cli/job/create.py +0 -0
- {proximl-0.5.5 → proximl-0.5.7}/proximl/cli/model.py +0 -0
- {proximl-0.5.5 → proximl-0.5.7}/proximl/cli/volume.py +0 -0
- {proximl-0.5.5 → proximl-0.5.7}/proximl/cloudbender/__init__.py +0 -0
- {proximl-0.5.5 → proximl-0.5.7}/proximl/cloudbender/datastores.py +0 -0
- {proximl-0.5.5 → proximl-0.5.7}/proximl/cloudbender/device_configs.py +0 -0
- {proximl-0.5.5 → proximl-0.5.7}/proximl/cloudbender/devices.py +0 -0
- {proximl-0.5.5 → proximl-0.5.7}/proximl/cloudbender/nodes.py +0 -0
- {proximl-0.5.5 → proximl-0.5.7}/proximl/cloudbender/providers.py +0 -0
- {proximl-0.5.5 → proximl-0.5.7}/proximl/cloudbender/regions.py +0 -0
- {proximl-0.5.5 → proximl-0.5.7}/proximl/connections.py +0 -0
- {proximl-0.5.5 → proximl-0.5.7}/proximl/environments.py +0 -0
- {proximl-0.5.5 → proximl-0.5.7}/proximl/exceptions.py +0 -0
- {proximl-0.5.5 → proximl-0.5.7}/proximl/gpu_types.py +0 -0
- {proximl-0.5.5 → proximl-0.5.7}/proximl/proximl.py +0 -0
- {proximl-0.5.5 → proximl-0.5.7}/proximl.egg-info/dependency_links.txt +0 -0
- {proximl-0.5.5 → proximl-0.5.7}/proximl.egg-info/entry_points.txt +0 -0
- {proximl-0.5.5 → proximl-0.5.7}/proximl.egg-info/requires.txt +0 -0
- {proximl-0.5.5 → proximl-0.5.7}/proximl.egg-info/top_level.txt +0 -0
- {proximl-0.5.5 → proximl-0.5.7}/setup.cfg +0 -0
- {proximl-0.5.5 → proximl-0.5.7}/setup.py +0 -0
- {proximl-0.5.5 → proximl-0.5.7}/tests/integration/__init__.py +0 -0
- {proximl-0.5.5 → proximl-0.5.7}/tests/integration/cloudbender/__init__.py +0 -0
- {proximl-0.5.5 → proximl-0.5.7}/tests/integration/cloudbender/test_providers_integration.py +0 -0
- {proximl-0.5.5 → proximl-0.5.7}/tests/integration/conftest.py +0 -0
- {proximl-0.5.5 → proximl-0.5.7}/tests/integration/test_checkpoints_integration.py +0 -0
- {proximl-0.5.5 → proximl-0.5.7}/tests/integration/test_datasets_integration.py +0 -0
- {proximl-0.5.5 → proximl-0.5.7}/tests/integration/test_environments_integration.py +0 -0
- {proximl-0.5.5 → proximl-0.5.7}/tests/integration/test_gpu_types_integration.py +0 -0
- {proximl-0.5.5 → proximl-0.5.7}/tests/integration/test_models_integration.py +0 -0
- {proximl-0.5.5 → proximl-0.5.7}/tests/integration/test_projects_integration.py +0 -0
- {proximl-0.5.5 → proximl-0.5.7}/tests/integration/test_volumes_integration.py +0 -0
- {proximl-0.5.5 → proximl-0.5.7}/tests/unit/__init__.py +0 -0
- {proximl-0.5.5 → proximl-0.5.7}/tests/unit/cli/__init__.py +0 -0
- {proximl-0.5.5 → proximl-0.5.7}/tests/unit/cli/cloudbender/__init__.py +0 -0
- {proximl-0.5.5 → proximl-0.5.7}/tests/unit/cli/cloudbender/test_cli_datastore_unit.py +0 -0
- {proximl-0.5.5 → proximl-0.5.7}/tests/unit/cli/cloudbender/test_cli_device_unit.py +0 -0
- {proximl-0.5.5 → proximl-0.5.7}/tests/unit/cli/cloudbender/test_cli_node_unit.py +0 -0
- {proximl-0.5.5 → proximl-0.5.7}/tests/unit/cli/cloudbender/test_cli_provider_unit.py +0 -0
- {proximl-0.5.5 → proximl-0.5.7}/tests/unit/cli/cloudbender/test_cli_region_unit.py +0 -0
- {proximl-0.5.5 → proximl-0.5.7}/tests/unit/cli/conftest.py +0 -0
- {proximl-0.5.5 → proximl-0.5.7}/tests/unit/cli/test_cli_checkpoint_unit.py +0 -0
- {proximl-0.5.5 → proximl-0.5.7}/tests/unit/cli/test_cli_datasets_unit.py +0 -0
- {proximl-0.5.5 → proximl-0.5.7}/tests/unit/cli/test_cli_environment_unit.py +0 -0
- {proximl-0.5.5 → proximl-0.5.7}/tests/unit/cli/test_cli_gpu_unit.py +0 -0
- {proximl-0.5.5 → proximl-0.5.7}/tests/unit/cli/test_cli_job_unit.py +0 -0
- {proximl-0.5.5 → proximl-0.5.7}/tests/unit/cli/test_cli_model_unit.py +0 -0
- {proximl-0.5.5 → proximl-0.5.7}/tests/unit/cli/test_cli_volume_unit.py +0 -0
- {proximl-0.5.5 → proximl-0.5.7}/tests/unit/cloudbender/__init__.py +0 -0
- {proximl-0.5.5 → proximl-0.5.7}/tests/unit/cloudbender/test_datastores_unit.py +0 -0
- {proximl-0.5.5 → proximl-0.5.7}/tests/unit/cloudbender/test_device_configs_unit.py +0 -0
- {proximl-0.5.5 → proximl-0.5.7}/tests/unit/cloudbender/test_devices_unit.py +0 -0
- {proximl-0.5.5 → proximl-0.5.7}/tests/unit/cloudbender/test_nodes_unit.py +0 -0
- {proximl-0.5.5 → proximl-0.5.7}/tests/unit/cloudbender/test_providers_unit.py +0 -0
- {proximl-0.5.5 → proximl-0.5.7}/tests/unit/cloudbender/test_regions_unit.py +0 -0
- {proximl-0.5.5 → proximl-0.5.7}/tests/unit/test_auth.py +0 -0
- {proximl-0.5.5 → proximl-0.5.7}/tests/unit/test_checkpoints_unit.py +0 -0
- {proximl-0.5.5 → proximl-0.5.7}/tests/unit/test_connections_unit.py +0 -0
- {proximl-0.5.5 → proximl-0.5.7}/tests/unit/test_datasets_unit.py +0 -0
- {proximl-0.5.5 → proximl-0.5.7}/tests/unit/test_environments_unit.py +0 -0
- {proximl-0.5.5 → proximl-0.5.7}/tests/unit/test_exceptions.py +0 -0
- {proximl-0.5.5 → proximl-0.5.7}/tests/unit/test_gpu_types_unit.py +0 -0
- {proximl-0.5.5 → proximl-0.5.7}/tests/unit/test_jobs_unit.py +0 -0
- {proximl-0.5.5 → proximl-0.5.7}/tests/unit/test_models_unit.py +0 -0
- {proximl-0.5.5 → proximl-0.5.7}/tests/unit/test_proximl.py +0 -0
- {proximl-0.5.5 → proximl-0.5.7}/tests/unit/test_volumes_unit.py +0 -0
|
@@ -23,9 +23,7 @@ class Checkpoints(object):
|
|
|
23
23
|
|
|
24
24
|
async def list(self, **kwargs):
|
|
25
25
|
resp = await self.proximl._query(f"/checkpoint", "GET", kwargs)
|
|
26
|
-
checkpoints = [
|
|
27
|
-
Checkpoint(self.proximl, **checkpoint) for checkpoint in resp
|
|
28
|
-
]
|
|
26
|
+
checkpoints = [Checkpoint(self.proximl, **checkpoint) for checkpoint in resp]
|
|
29
27
|
return checkpoints
|
|
30
28
|
|
|
31
29
|
async def list_public(self, **kwargs):
|
|
@@ -39,8 +37,7 @@ class Checkpoints(object):
|
|
|
39
37
|
source_type=source_type,
|
|
40
38
|
source_uri=source_uri,
|
|
41
39
|
source_options=kwargs.get("source_options"),
|
|
42
|
-
project_uuid=kwargs.get("project_uuid")
|
|
43
|
-
or self.proximl.active_project,
|
|
40
|
+
project_uuid=kwargs.get("project_uuid") or self.proximl.active_project,
|
|
44
41
|
)
|
|
45
42
|
payload = {k: v for k, v in data.items() if v is not None}
|
|
46
43
|
logging.info(f"Creating Checkpoint {name}")
|
|
@@ -60,9 +57,7 @@ class Checkpoint:
|
|
|
60
57
|
def __init__(self, proximl, **kwargs):
|
|
61
58
|
self.proximl = proximl
|
|
62
59
|
self._checkpoint = kwargs
|
|
63
|
-
self._id = self._checkpoint.get(
|
|
64
|
-
"id", self._checkpoint.get("checkpoint_uuid")
|
|
65
|
-
)
|
|
60
|
+
self._id = self._checkpoint.get("id", self._checkpoint.get("checkpoint_uuid"))
|
|
66
61
|
self._status = self._checkpoint.get("status")
|
|
67
62
|
self._name = self._checkpoint.get("name")
|
|
68
63
|
self._size = self._checkpoint.get("size")
|
|
@@ -123,15 +118,17 @@ class Checkpoint:
|
|
|
123
118
|
entity_type="checkpoint",
|
|
124
119
|
project_uuid=self._checkpoint.get("project_uuid"),
|
|
125
120
|
cidr=self._checkpoint.get("vpn").get("cidr"),
|
|
126
|
-
ssh_port=self._checkpoint.get("vpn")
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
output_path=
|
|
133
|
-
|
|
134
|
-
|
|
121
|
+
ssh_port=self._checkpoint.get("vpn").get("client").get("ssh_port"),
|
|
122
|
+
input_path=(
|
|
123
|
+
self._checkpoint.get("source_uri")
|
|
124
|
+
if self.status in ["new", "downloading"]
|
|
125
|
+
else None
|
|
126
|
+
),
|
|
127
|
+
output_path=(
|
|
128
|
+
self._checkpoint.get("output_uri")
|
|
129
|
+
if self.status == "exporting"
|
|
130
|
+
else None
|
|
131
|
+
),
|
|
135
132
|
)
|
|
136
133
|
else:
|
|
137
134
|
details = dict()
|
|
@@ -195,9 +192,7 @@ class Checkpoint:
|
|
|
195
192
|
if msg_handler:
|
|
196
193
|
msg_handler(data)
|
|
197
194
|
else:
|
|
198
|
-
timestamp = datetime.fromtimestamp(
|
|
199
|
-
int(data.get("time")) / 1000
|
|
200
|
-
)
|
|
195
|
+
timestamp = datetime.fromtimestamp(int(data.get("time")) / 1000)
|
|
201
196
|
print(
|
|
202
197
|
f"{timestamp.strftime('%m/%d/%Y, %H:%M:%S')}: {data.get('msg').rstrip()}"
|
|
203
198
|
)
|
|
@@ -224,19 +219,24 @@ class Checkpoint:
|
|
|
224
219
|
return self
|
|
225
220
|
|
|
226
221
|
async def wait_for(self, status, timeout=300):
|
|
222
|
+
if self.status == status:
|
|
223
|
+
return
|
|
227
224
|
valid_statuses = ["downloading", "ready", "archived"]
|
|
228
225
|
if not status in valid_statuses:
|
|
229
226
|
raise SpecificationError(
|
|
230
227
|
"status",
|
|
231
228
|
f"Invalid wait_for status {status}. Valid statuses are: {valid_statuses}",
|
|
232
229
|
)
|
|
233
|
-
|
|
234
|
-
|
|
230
|
+
|
|
231
|
+
MAX_TIMEOUT = 24 * 60 * 60
|
|
232
|
+
if timeout > MAX_TIMEOUT:
|
|
233
|
+
raise SpecificationError(
|
|
234
|
+
"timeout",
|
|
235
|
+
f"timeout must be less than {MAX_TIMEOUT} seconds.",
|
|
236
|
+
)
|
|
235
237
|
POLL_INTERVAL_MIN = 5
|
|
236
238
|
POLL_INTERVAL_MAX = 60
|
|
237
|
-
POLL_INTERVAL = max(
|
|
238
|
-
min(timeout / 60, POLL_INTERVAL_MAX), POLL_INTERVAL_MIN
|
|
239
|
-
)
|
|
239
|
+
POLL_INTERVAL = max(min(timeout / 60, POLL_INTERVAL_MAX), POLL_INTERVAL_MIN)
|
|
240
240
|
retry_count = math.ceil(timeout / POLL_INTERVAL)
|
|
241
241
|
count = 0
|
|
242
242
|
while count < retry_count:
|
|
@@ -15,4 +15,5 @@ from proximl.cli.cloudbender.region import region
|
|
|
15
15
|
from proximl.cli.cloudbender.node import node
|
|
16
16
|
from proximl.cli.cloudbender.device import device
|
|
17
17
|
from proximl.cli.cloudbender.datastore import datastore
|
|
18
|
-
from proximl.cli.cloudbender.
|
|
18
|
+
from proximl.cli.cloudbender.data_connector import data_connector
|
|
19
|
+
from proximl.cli.cloudbender.service import service
|
|
@@ -5,12 +5,12 @@ from proximl.cli.cloudbender import cloudbender
|
|
|
5
5
|
|
|
6
6
|
@cloudbender.group()
|
|
7
7
|
@pass_config
|
|
8
|
-
def
|
|
9
|
-
"""proxiML CloudBender
|
|
8
|
+
def data_connector(config):
|
|
9
|
+
"""proxiML CloudBender data connector commands."""
|
|
10
10
|
pass
|
|
11
11
|
|
|
12
12
|
|
|
13
|
-
@
|
|
13
|
+
@data_connector.command()
|
|
14
14
|
@click.option(
|
|
15
15
|
"--provider",
|
|
16
16
|
"-p",
|
|
@@ -23,48 +23,43 @@ def reservation(config):
|
|
|
23
23
|
"-r",
|
|
24
24
|
type=click.STRING,
|
|
25
25
|
required=True,
|
|
26
|
-
help="The region ID to list
|
|
26
|
+
help="The region ID to list data connectors for.",
|
|
27
27
|
)
|
|
28
28
|
@pass_config
|
|
29
29
|
def list(config, provider, region):
|
|
30
|
-
"""List
|
|
30
|
+
"""List data connectors."""
|
|
31
31
|
data = [
|
|
32
|
-
["ID", "NAME", "TYPE"
|
|
32
|
+
["ID", "NAME", "TYPE"],
|
|
33
33
|
[
|
|
34
34
|
"-" * 80,
|
|
35
35
|
"-" * 80,
|
|
36
36
|
"-" * 80,
|
|
37
|
-
"-" * 80,
|
|
38
|
-
"-" * 80,
|
|
39
37
|
],
|
|
40
38
|
]
|
|
41
39
|
|
|
42
|
-
|
|
43
|
-
config.proximl.client.cloudbender.
|
|
40
|
+
data_connectors = config.proximl.run(
|
|
41
|
+
config.proximl.client.cloudbender.data_connectors.list(
|
|
44
42
|
provider_uuid=provider, region_uuid=region
|
|
45
43
|
)
|
|
46
44
|
)
|
|
47
45
|
|
|
48
|
-
for
|
|
46
|
+
for data_connector in data_connectors:
|
|
49
47
|
data.append(
|
|
50
48
|
[
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
reservation.resource,
|
|
55
|
-
reservation.hostname,
|
|
49
|
+
data_connector.id,
|
|
50
|
+
data_connector.name,
|
|
51
|
+
data_connector.type,
|
|
56
52
|
]
|
|
57
53
|
)
|
|
58
54
|
|
|
59
55
|
for row in data:
|
|
60
56
|
click.echo(
|
|
61
|
-
"{: >37.36} {: >29.28} {: >9.8}
|
|
62
|
-
"".format(*row),
|
|
57
|
+
"{: >37.36} {: >29.28} {: >9.8}" "".format(*row),
|
|
63
58
|
file=config.stdout,
|
|
64
59
|
)
|
|
65
60
|
|
|
66
61
|
|
|
67
|
-
@
|
|
62
|
+
@data_connector.command()
|
|
68
63
|
@click.option(
|
|
69
64
|
"--provider",
|
|
70
65
|
"-p",
|
|
@@ -77,53 +72,58 @@ def list(config, provider, region):
|
|
|
77
72
|
"-r",
|
|
78
73
|
type=click.STRING,
|
|
79
74
|
required=True,
|
|
80
|
-
help="The region ID to create the
|
|
75
|
+
help="The region ID to create the data_connector in.",
|
|
81
76
|
)
|
|
82
77
|
@click.option(
|
|
83
78
|
"--type",
|
|
84
79
|
"-t",
|
|
85
80
|
type=click.Choice(
|
|
86
81
|
[
|
|
87
|
-
"
|
|
82
|
+
"custom",
|
|
88
83
|
],
|
|
89
84
|
case_sensitive=False,
|
|
90
85
|
),
|
|
91
86
|
required=True,
|
|
92
|
-
help="The type of
|
|
87
|
+
help="The type of data connector to create.",
|
|
93
88
|
)
|
|
94
89
|
@click.option(
|
|
95
|
-
"--
|
|
96
|
-
"-
|
|
90
|
+
"--protocol",
|
|
91
|
+
"-r",
|
|
97
92
|
type=click.STRING,
|
|
98
|
-
|
|
99
|
-
help="The hostname to make the reservation on",
|
|
93
|
+
help="The transport protocol of the data connector",
|
|
100
94
|
)
|
|
101
95
|
@click.option(
|
|
102
|
-
"--
|
|
103
|
-
"-
|
|
96
|
+
"--port-range",
|
|
97
|
+
"-p",
|
|
104
98
|
type=click.STRING,
|
|
105
|
-
|
|
106
|
-
|
|
99
|
+
help="The port range of the data connector",
|
|
100
|
+
)
|
|
101
|
+
@click.option(
|
|
102
|
+
"--cidr",
|
|
103
|
+
"-i",
|
|
104
|
+
type=click.STRING,
|
|
105
|
+
help="The IP range to allow in CIDR notation",
|
|
107
106
|
)
|
|
108
107
|
@click.argument("name", type=click.STRING, required=True)
|
|
109
108
|
@pass_config
|
|
110
|
-
def create(config, provider, region, type,
|
|
109
|
+
def create(config, provider, region, type, protocol, port_range, cidr, name):
|
|
111
110
|
"""
|
|
112
|
-
Creates a
|
|
111
|
+
Creates a data_connector.
|
|
113
112
|
"""
|
|
114
113
|
return config.proximl.run(
|
|
115
|
-
config.proximl.client.cloudbender.
|
|
114
|
+
config.proximl.client.cloudbender.data_connectors.create(
|
|
116
115
|
provider_uuid=provider,
|
|
117
116
|
region_uuid=region,
|
|
118
117
|
name=name,
|
|
119
|
-
hostname=hostname,
|
|
120
|
-
resource=resource,
|
|
121
118
|
type=type,
|
|
119
|
+
protocol=protocol,
|
|
120
|
+
port_range=port_range,
|
|
121
|
+
cidr=cidr,
|
|
122
122
|
)
|
|
123
123
|
)
|
|
124
124
|
|
|
125
125
|
|
|
126
|
-
@
|
|
126
|
+
@data_connector.command()
|
|
127
127
|
@click.option(
|
|
128
128
|
"--provider",
|
|
129
129
|
"-p",
|
|
@@ -136,24 +136,24 @@ def create(config, provider, region, type, hostname, resource, name):
|
|
|
136
136
|
"-r",
|
|
137
137
|
type=click.STRING,
|
|
138
138
|
required=True,
|
|
139
|
-
help="The region ID to remove the
|
|
139
|
+
help="The region ID to remove the data_connector from.",
|
|
140
140
|
)
|
|
141
|
-
@click.argument("
|
|
141
|
+
@click.argument("data_connector", type=click.STRING)
|
|
142
142
|
@pass_config
|
|
143
|
-
def remove(config, provider, region,
|
|
143
|
+
def remove(config, provider, region, data_connector):
|
|
144
144
|
"""
|
|
145
|
-
Remove a
|
|
145
|
+
Remove a data_connector.
|
|
146
146
|
|
|
147
|
-
|
|
147
|
+
DATASTORE may be specified by name or ID, but ID is preferred.
|
|
148
148
|
"""
|
|
149
|
-
|
|
150
|
-
config.proximl.client.cloudbender.
|
|
149
|
+
data_connectors = config.proximl.run(
|
|
150
|
+
config.proximl.client.cloudbender.data_connectors.list(
|
|
151
151
|
provider_uuid=provider, region_uuid=region
|
|
152
152
|
)
|
|
153
153
|
)
|
|
154
154
|
|
|
155
|
-
found = search_by_id_name(
|
|
155
|
+
found = search_by_id_name(data_connector, data_connectors)
|
|
156
156
|
if None is found:
|
|
157
|
-
raise click.UsageError("Cannot find specified
|
|
157
|
+
raise click.UsageError("Cannot find specified data_connector.")
|
|
158
158
|
|
|
159
159
|
return config.proximl.run(found.remove())
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
import click
|
|
2
|
+
from proximl.cli import cli, pass_config, search_by_id_name
|
|
3
|
+
from proximl.cli.cloudbender import cloudbender
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
@cloudbender.group()
|
|
7
|
+
@pass_config
|
|
8
|
+
def service(config):
|
|
9
|
+
"""proxiML CloudBender service commands."""
|
|
10
|
+
pass
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
@service.command()
|
|
14
|
+
@click.option(
|
|
15
|
+
"--provider",
|
|
16
|
+
"-p",
|
|
17
|
+
type=click.STRING,
|
|
18
|
+
required=True,
|
|
19
|
+
help="The provider ID of the region.",
|
|
20
|
+
)
|
|
21
|
+
@click.option(
|
|
22
|
+
"--region",
|
|
23
|
+
"-r",
|
|
24
|
+
type=click.STRING,
|
|
25
|
+
required=True,
|
|
26
|
+
help="The region ID to list services for.",
|
|
27
|
+
)
|
|
28
|
+
@pass_config
|
|
29
|
+
def list(config, provider, region):
|
|
30
|
+
"""List services."""
|
|
31
|
+
data = [
|
|
32
|
+
["ID", "NAME", "HOSTNAME"],
|
|
33
|
+
[
|
|
34
|
+
"-" * 80,
|
|
35
|
+
"-" * 80,
|
|
36
|
+
"-" * 80,
|
|
37
|
+
],
|
|
38
|
+
]
|
|
39
|
+
|
|
40
|
+
services = config.proximl.run(
|
|
41
|
+
config.proximl.client.cloudbender.services.list(
|
|
42
|
+
provider_uuid=provider, region_uuid=region
|
|
43
|
+
)
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
for service in services:
|
|
47
|
+
data.append(
|
|
48
|
+
[
|
|
49
|
+
service.id,
|
|
50
|
+
service.name,
|
|
51
|
+
service.hostname,
|
|
52
|
+
]
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
for row in data:
|
|
56
|
+
click.echo(
|
|
57
|
+
"{: >25.24} {: >29.28} {: >40.39}" "".format(*row),
|
|
58
|
+
file=config.stdout,
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
@service.command()
|
|
63
|
+
@click.option(
|
|
64
|
+
"--provider",
|
|
65
|
+
"-p",
|
|
66
|
+
type=click.STRING,
|
|
67
|
+
required=True,
|
|
68
|
+
help="The provider ID of the region.",
|
|
69
|
+
)
|
|
70
|
+
@click.option(
|
|
71
|
+
"--region",
|
|
72
|
+
"-r",
|
|
73
|
+
type=click.STRING,
|
|
74
|
+
required=True,
|
|
75
|
+
help="The region ID to create the service in.",
|
|
76
|
+
)
|
|
77
|
+
@click.option(
|
|
78
|
+
"--type",
|
|
79
|
+
"-t",
|
|
80
|
+
type=click.Choice(
|
|
81
|
+
[
|
|
82
|
+
"https",
|
|
83
|
+
"tcp",
|
|
84
|
+
"udp",
|
|
85
|
+
],
|
|
86
|
+
),
|
|
87
|
+
required=True,
|
|
88
|
+
help="The type of regional service.",
|
|
89
|
+
)
|
|
90
|
+
@click.option(
|
|
91
|
+
"--public/--no-public",
|
|
92
|
+
default=True,
|
|
93
|
+
show_default=True,
|
|
94
|
+
help="Service should be accessible from the public internet.",
|
|
95
|
+
)
|
|
96
|
+
@click.argument("name", type=click.STRING, required=True)
|
|
97
|
+
@pass_config
|
|
98
|
+
def create(config, provider, region, type, public, name):
|
|
99
|
+
"""
|
|
100
|
+
Creates a service.
|
|
101
|
+
"""
|
|
102
|
+
return config.proximl.run(
|
|
103
|
+
config.proximl.client.cloudbender.services.create(
|
|
104
|
+
provider_uuid=provider,
|
|
105
|
+
region_uuid=region,
|
|
106
|
+
name=name,
|
|
107
|
+
type=type,
|
|
108
|
+
public=public,
|
|
109
|
+
)
|
|
110
|
+
)
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
@service.command()
|
|
114
|
+
@click.option(
|
|
115
|
+
"--provider",
|
|
116
|
+
"-p",
|
|
117
|
+
type=click.STRING,
|
|
118
|
+
required=True,
|
|
119
|
+
help="The provider ID of the region.",
|
|
120
|
+
)
|
|
121
|
+
@click.option(
|
|
122
|
+
"--region",
|
|
123
|
+
"-r",
|
|
124
|
+
type=click.STRING,
|
|
125
|
+
required=True,
|
|
126
|
+
help="The region ID to remove the service from.",
|
|
127
|
+
)
|
|
128
|
+
@click.argument("service", type=click.STRING)
|
|
129
|
+
@pass_config
|
|
130
|
+
def remove(config, provider, region, service):
|
|
131
|
+
"""
|
|
132
|
+
Remove a service.
|
|
133
|
+
|
|
134
|
+
RESERVATION may be specified by name or ID, but ID is preferred.
|
|
135
|
+
"""
|
|
136
|
+
services = config.proximl.run(
|
|
137
|
+
config.proximl.client.cloudbender.services.list(
|
|
138
|
+
provider_uuid=provider, region_uuid=region
|
|
139
|
+
)
|
|
140
|
+
)
|
|
141
|
+
|
|
142
|
+
found = search_by_id_name(service, services)
|
|
143
|
+
if None is found:
|
|
144
|
+
raise click.UsageError("Cannot find specified service.")
|
|
145
|
+
|
|
146
|
+
return config.proximl.run(found.remove())
|
|
@@ -115,40 +115,35 @@ def list_datastores(config):
|
|
|
115
115
|
|
|
116
116
|
@project.command()
|
|
117
117
|
@pass_config
|
|
118
|
-
def
|
|
119
|
-
"""List project
|
|
118
|
+
def list_services(config):
|
|
119
|
+
"""List project services."""
|
|
120
120
|
data = [
|
|
121
|
-
["ID", "NAME", "
|
|
121
|
+
["ID", "NAME", "HOSTNAME", "REGION_UUID"],
|
|
122
122
|
[
|
|
123
123
|
"-" * 80,
|
|
124
124
|
"-" * 80,
|
|
125
125
|
"-" * 80,
|
|
126
126
|
"-" * 80,
|
|
127
|
-
"-" * 80,
|
|
128
|
-
"-" * 80,
|
|
129
127
|
],
|
|
130
128
|
]
|
|
131
129
|
project = config.proximl.run(
|
|
132
130
|
config.proximl.client.projects.get(config.proximl.client.project)
|
|
133
131
|
)
|
|
134
132
|
|
|
135
|
-
|
|
133
|
+
services = config.proximl.run(project.list_services())
|
|
136
134
|
|
|
137
|
-
for
|
|
135
|
+
for service in services:
|
|
138
136
|
data.append(
|
|
139
137
|
[
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
reservation.hostname,
|
|
145
|
-
reservation.region_uuid,
|
|
138
|
+
service.id,
|
|
139
|
+
service.name,
|
|
140
|
+
service.hostname,
|
|
141
|
+
service.region_uuid,
|
|
146
142
|
]
|
|
147
143
|
)
|
|
148
144
|
|
|
149
145
|
for row in data:
|
|
150
146
|
click.echo(
|
|
151
|
-
"{: >38.36} {: >30.28} {: >
|
|
152
|
-
"".format(*row),
|
|
147
|
+
"{: >38.36} {: >30.28} {: >30.28} {: >38.36}" "".format(*row),
|
|
153
148
|
file=config.stdout,
|
|
154
149
|
)
|
|
@@ -3,7 +3,8 @@ from .regions import Regions
|
|
|
3
3
|
from .nodes import Nodes
|
|
4
4
|
from .devices import Devices
|
|
5
5
|
from .datastores import Datastores
|
|
6
|
-
from .
|
|
6
|
+
from .data_connectors import DataConnectors
|
|
7
|
+
from .services import Services
|
|
7
8
|
from .device_configs import DeviceConfigs
|
|
8
9
|
|
|
9
10
|
|
|
@@ -15,5 +16,6 @@ class Cloudbender(object):
|
|
|
15
16
|
self.nodes = Nodes(proximl)
|
|
16
17
|
self.devices = Devices(proximl)
|
|
17
18
|
self.datastores = Datastores(proximl)
|
|
18
|
-
self.
|
|
19
|
+
self.data_connectors = DataConnectors(proximl)
|
|
20
|
+
self.services = Services(proximl)
|
|
19
21
|
self.device_configs = DeviceConfigs(proximl)
|
|
@@ -2,28 +2,28 @@ import json
|
|
|
2
2
|
import logging
|
|
3
3
|
|
|
4
4
|
|
|
5
|
-
class
|
|
5
|
+
class DataConnectors(object):
|
|
6
6
|
def __init__(self, proximl):
|
|
7
7
|
self.proximl = proximl
|
|
8
8
|
|
|
9
9
|
async def get(self, provider_uuid, region_uuid, id, **kwargs):
|
|
10
10
|
resp = await self.proximl._query(
|
|
11
|
-
f"/provider/{provider_uuid}/region/{region_uuid}/
|
|
11
|
+
f"/provider/{provider_uuid}/region/{region_uuid}/data_connector/{id}",
|
|
12
12
|
"GET",
|
|
13
13
|
kwargs,
|
|
14
14
|
)
|
|
15
|
-
return
|
|
15
|
+
return DataConnector(self.proximl, **resp)
|
|
16
16
|
|
|
17
17
|
async def list(self, provider_uuid, region_uuid, **kwargs):
|
|
18
18
|
resp = await self.proximl._query(
|
|
19
|
-
f"/provider/{provider_uuid}/region/{region_uuid}/
|
|
19
|
+
f"/provider/{provider_uuid}/region/{region_uuid}/data_connector",
|
|
20
20
|
"GET",
|
|
21
21
|
kwargs,
|
|
22
22
|
)
|
|
23
|
-
|
|
24
|
-
|
|
23
|
+
data_connectors = [
|
|
24
|
+
DataConnector(self.proximl, **data_connector) for data_connector in resp
|
|
25
25
|
]
|
|
26
|
-
return
|
|
26
|
+
return data_connectors
|
|
27
27
|
|
|
28
28
|
async def create(
|
|
29
29
|
self,
|
|
@@ -31,48 +31,42 @@ class Reservations(object):
|
|
|
31
31
|
region_uuid,
|
|
32
32
|
name,
|
|
33
33
|
type,
|
|
34
|
-
resource,
|
|
35
|
-
hostname,
|
|
36
34
|
**kwargs,
|
|
37
35
|
):
|
|
38
|
-
logging.info(f"Creating
|
|
36
|
+
logging.info(f"Creating Data Connector {name}")
|
|
39
37
|
data = dict(
|
|
40
38
|
name=name,
|
|
41
39
|
type=type,
|
|
42
|
-
resource=resource,
|
|
43
|
-
hostname=hostname,
|
|
44
40
|
**kwargs,
|
|
45
41
|
)
|
|
46
42
|
payload = {k: v for k, v in data.items() if v is not None}
|
|
47
43
|
resp = await self.proximl._query(
|
|
48
|
-
f"/provider/{provider_uuid}/region/{region_uuid}/
|
|
44
|
+
f"/provider/{provider_uuid}/region/{region_uuid}/data_connector",
|
|
49
45
|
"POST",
|
|
50
46
|
None,
|
|
51
47
|
payload,
|
|
52
48
|
)
|
|
53
|
-
|
|
54
|
-
logging.info(f"Created
|
|
55
|
-
return
|
|
49
|
+
data_connector = DataConnector(self.proximl, **resp)
|
|
50
|
+
logging.info(f"Created Data Connector {name} with id {data_connector.id}")
|
|
51
|
+
return data_connector
|
|
56
52
|
|
|
57
53
|
async def remove(self, provider_uuid, region_uuid, id, **kwargs):
|
|
58
54
|
await self.proximl._query(
|
|
59
|
-
f"/provider/{provider_uuid}/region/{region_uuid}/
|
|
55
|
+
f"/provider/{provider_uuid}/region/{region_uuid}/data_connector/{id}",
|
|
60
56
|
"DELETE",
|
|
61
57
|
kwargs,
|
|
62
58
|
)
|
|
63
59
|
|
|
64
60
|
|
|
65
|
-
class
|
|
61
|
+
class DataConnector:
|
|
66
62
|
def __init__(self, proximl, **kwargs):
|
|
67
63
|
self.proximl = proximl
|
|
68
|
-
self.
|
|
69
|
-
self._id = self.
|
|
70
|
-
self._provider_uuid = self.
|
|
71
|
-
self._region_uuid = self.
|
|
72
|
-
self._type = self.
|
|
73
|
-
self._name = self.
|
|
74
|
-
self._resource = self._reservation.get("resource")
|
|
75
|
-
self._hostname = self._reservation.get("hostname")
|
|
64
|
+
self._data_connector = kwargs
|
|
65
|
+
self._id = self._data_connector.get("connector_id")
|
|
66
|
+
self._provider_uuid = self._data_connector.get("provider_uuid")
|
|
67
|
+
self._region_uuid = self._data_connector.get("region_uuid")
|
|
68
|
+
self._type = self._data_connector.get("type")
|
|
69
|
+
self._name = self._data_connector.get("name")
|
|
76
70
|
|
|
77
71
|
@property
|
|
78
72
|
def id(self) -> str:
|
|
@@ -94,32 +88,24 @@ class Reservation:
|
|
|
94
88
|
def name(self) -> str:
|
|
95
89
|
return self._name
|
|
96
90
|
|
|
97
|
-
@property
|
|
98
|
-
def resource(self) -> str:
|
|
99
|
-
return self._resource
|
|
100
|
-
|
|
101
|
-
@property
|
|
102
|
-
def hostname(self) -> str:
|
|
103
|
-
return self._hostname
|
|
104
|
-
|
|
105
91
|
def __str__(self):
|
|
106
|
-
return json.dumps({k: v for k, v in self.
|
|
92
|
+
return json.dumps({k: v for k, v in self._data_connector.items()})
|
|
107
93
|
|
|
108
94
|
def __repr__(self):
|
|
109
|
-
return f"
|
|
95
|
+
return f"DataConnector( proximl , **{self._data_connector.__repr__()})"
|
|
110
96
|
|
|
111
97
|
def __bool__(self):
|
|
112
98
|
return bool(self._id)
|
|
113
99
|
|
|
114
100
|
async def remove(self):
|
|
115
101
|
await self.proximl._query(
|
|
116
|
-
f"/provider/{self._provider_uuid}/region/{self._region_uuid}/
|
|
102
|
+
f"/provider/{self._provider_uuid}/region/{self._region_uuid}/data_connector/{self._id}",
|
|
117
103
|
"DELETE",
|
|
118
104
|
)
|
|
119
105
|
|
|
120
106
|
async def refresh(self):
|
|
121
107
|
resp = await self.proximl._query(
|
|
122
|
-
f"/provider/{self._provider_uuid}/region/{self._region_uuid}/
|
|
108
|
+
f"/provider/{self._provider_uuid}/region/{self._region_uuid}/data_connector/{self._id}",
|
|
123
109
|
"GET",
|
|
124
110
|
)
|
|
125
111
|
self.__init__(self.proximl, **resp)
|