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.
Files changed (113) hide show
  1. {proximl-0.5.5/proximl.egg-info → proximl-0.5.7}/PKG-INFO +1 -1
  2. {proximl-0.5.5 → proximl-0.5.7}/proximl/__init__.py +1 -1
  3. {proximl-0.5.5 → proximl-0.5.7}/proximl/checkpoints.py +25 -25
  4. {proximl-0.5.5 → proximl-0.5.7}/proximl/cli/cloudbender/__init__.py +2 -1
  5. proximl-0.5.5/proximl/cli/cloudbender/reservation.py → proximl-0.5.7/proximl/cli/cloudbender/data_connector.py +45 -45
  6. proximl-0.5.7/proximl/cli/cloudbender/service.py +146 -0
  7. {proximl-0.5.5 → proximl-0.5.7}/proximl/cli/project.py +10 -15
  8. {proximl-0.5.5 → proximl-0.5.7}/proximl/cloudbender/cloudbender.py +4 -2
  9. proximl-0.5.5/proximl/cloudbender/reservations.py → proximl-0.5.7/proximl/cloudbender/data_connectors.py +24 -38
  10. proximl-0.5.7/proximl/cloudbender/services.py +179 -0
  11. {proximl-0.5.5 → proximl-0.5.7}/proximl/datasets.py +19 -8
  12. {proximl-0.5.5 → proximl-0.5.7}/proximl/jobs.py +13 -6
  13. {proximl-0.5.5 → proximl-0.5.7}/proximl/models.py +22 -19
  14. {proximl-0.5.5 → proximl-0.5.7}/proximl/projects.py +72 -31
  15. {proximl-0.5.5 → proximl-0.5.7}/proximl/volumes.py +9 -2
  16. {proximl-0.5.5 → proximl-0.5.7/proximl.egg-info}/PKG-INFO +1 -1
  17. {proximl-0.5.5 → proximl-0.5.7}/proximl.egg-info/SOURCES.txt +7 -4
  18. {proximl-0.5.5 → proximl-0.5.7}/pyproject.toml +2 -1
  19. {proximl-0.5.5 → proximl-0.5.7}/tests/integration/test_jobs_integration.py +13 -0
  20. proximl-0.5.7/tests/unit/cli/cloudbender/test_cli_service_unit.py +34 -0
  21. {proximl-0.5.5 → proximl-0.5.7}/tests/unit/cli/test_cli_project_unit.py +5 -9
  22. proximl-0.5.7/tests/unit/cloudbender/test_data_connectors_unit.py +176 -0
  23. proximl-0.5.7/tests/unit/cloudbender/test_services_unit.py +167 -0
  24. {proximl-0.5.5 → proximl-0.5.7}/tests/unit/conftest.py +13 -13
  25. {proximl-0.5.5 → proximl-0.5.7}/tests/unit/test_projects_unit.py +77 -51
  26. proximl-0.5.5/tests/unit/cli/cloudbender/test_cli_reservation_unit.py +0 -38
  27. proximl-0.5.5/tests/unit/cloudbender/test_reservations_unit.py +0 -173
  28. {proximl-0.5.5 → proximl-0.5.7}/LICENSE +0 -0
  29. {proximl-0.5.5 → proximl-0.5.7}/README.md +0 -0
  30. {proximl-0.5.5 → proximl-0.5.7}/examples/__init__.py +0 -0
  31. {proximl-0.5.5 → proximl-0.5.7}/examples/create_dataset_and_training_job.py +0 -0
  32. {proximl-0.5.5 → proximl-0.5.7}/examples/local_storage.py +0 -0
  33. {proximl-0.5.5 → proximl-0.5.7}/examples/training_inference_pipeline.py +0 -0
  34. {proximl-0.5.5 → proximl-0.5.7}/proximl/__main__.py +0 -0
  35. {proximl-0.5.5 → proximl-0.5.7}/proximl/auth.py +0 -0
  36. {proximl-0.5.5 → proximl-0.5.7}/proximl/cli/__init__.py +0 -0
  37. {proximl-0.5.5 → proximl-0.5.7}/proximl/cli/checkpoint.py +0 -0
  38. {proximl-0.5.5 → proximl-0.5.7}/proximl/cli/cloudbender/datastore.py +0 -0
  39. {proximl-0.5.5 → proximl-0.5.7}/proximl/cli/cloudbender/device.py +0 -0
  40. {proximl-0.5.5 → proximl-0.5.7}/proximl/cli/cloudbender/node.py +0 -0
  41. {proximl-0.5.5 → proximl-0.5.7}/proximl/cli/cloudbender/provider.py +0 -0
  42. {proximl-0.5.5 → proximl-0.5.7}/proximl/cli/cloudbender/region.py +0 -0
  43. {proximl-0.5.5 → proximl-0.5.7}/proximl/cli/connection.py +0 -0
  44. {proximl-0.5.5 → proximl-0.5.7}/proximl/cli/dataset.py +0 -0
  45. {proximl-0.5.5 → proximl-0.5.7}/proximl/cli/environment.py +0 -0
  46. {proximl-0.5.5 → proximl-0.5.7}/proximl/cli/gpu.py +0 -0
  47. {proximl-0.5.5 → proximl-0.5.7}/proximl/cli/job/__init__.py +0 -0
  48. {proximl-0.5.5 → proximl-0.5.7}/proximl/cli/job/create.py +0 -0
  49. {proximl-0.5.5 → proximl-0.5.7}/proximl/cli/model.py +0 -0
  50. {proximl-0.5.5 → proximl-0.5.7}/proximl/cli/volume.py +0 -0
  51. {proximl-0.5.5 → proximl-0.5.7}/proximl/cloudbender/__init__.py +0 -0
  52. {proximl-0.5.5 → proximl-0.5.7}/proximl/cloudbender/datastores.py +0 -0
  53. {proximl-0.5.5 → proximl-0.5.7}/proximl/cloudbender/device_configs.py +0 -0
  54. {proximl-0.5.5 → proximl-0.5.7}/proximl/cloudbender/devices.py +0 -0
  55. {proximl-0.5.5 → proximl-0.5.7}/proximl/cloudbender/nodes.py +0 -0
  56. {proximl-0.5.5 → proximl-0.5.7}/proximl/cloudbender/providers.py +0 -0
  57. {proximl-0.5.5 → proximl-0.5.7}/proximl/cloudbender/regions.py +0 -0
  58. {proximl-0.5.5 → proximl-0.5.7}/proximl/connections.py +0 -0
  59. {proximl-0.5.5 → proximl-0.5.7}/proximl/environments.py +0 -0
  60. {proximl-0.5.5 → proximl-0.5.7}/proximl/exceptions.py +0 -0
  61. {proximl-0.5.5 → proximl-0.5.7}/proximl/gpu_types.py +0 -0
  62. {proximl-0.5.5 → proximl-0.5.7}/proximl/proximl.py +0 -0
  63. {proximl-0.5.5 → proximl-0.5.7}/proximl.egg-info/dependency_links.txt +0 -0
  64. {proximl-0.5.5 → proximl-0.5.7}/proximl.egg-info/entry_points.txt +0 -0
  65. {proximl-0.5.5 → proximl-0.5.7}/proximl.egg-info/requires.txt +0 -0
  66. {proximl-0.5.5 → proximl-0.5.7}/proximl.egg-info/top_level.txt +0 -0
  67. {proximl-0.5.5 → proximl-0.5.7}/setup.cfg +0 -0
  68. {proximl-0.5.5 → proximl-0.5.7}/setup.py +0 -0
  69. {proximl-0.5.5 → proximl-0.5.7}/tests/integration/__init__.py +0 -0
  70. {proximl-0.5.5 → proximl-0.5.7}/tests/integration/cloudbender/__init__.py +0 -0
  71. {proximl-0.5.5 → proximl-0.5.7}/tests/integration/cloudbender/test_providers_integration.py +0 -0
  72. {proximl-0.5.5 → proximl-0.5.7}/tests/integration/conftest.py +0 -0
  73. {proximl-0.5.5 → proximl-0.5.7}/tests/integration/test_checkpoints_integration.py +0 -0
  74. {proximl-0.5.5 → proximl-0.5.7}/tests/integration/test_datasets_integration.py +0 -0
  75. {proximl-0.5.5 → proximl-0.5.7}/tests/integration/test_environments_integration.py +0 -0
  76. {proximl-0.5.5 → proximl-0.5.7}/tests/integration/test_gpu_types_integration.py +0 -0
  77. {proximl-0.5.5 → proximl-0.5.7}/tests/integration/test_models_integration.py +0 -0
  78. {proximl-0.5.5 → proximl-0.5.7}/tests/integration/test_projects_integration.py +0 -0
  79. {proximl-0.5.5 → proximl-0.5.7}/tests/integration/test_volumes_integration.py +0 -0
  80. {proximl-0.5.5 → proximl-0.5.7}/tests/unit/__init__.py +0 -0
  81. {proximl-0.5.5 → proximl-0.5.7}/tests/unit/cli/__init__.py +0 -0
  82. {proximl-0.5.5 → proximl-0.5.7}/tests/unit/cli/cloudbender/__init__.py +0 -0
  83. {proximl-0.5.5 → proximl-0.5.7}/tests/unit/cli/cloudbender/test_cli_datastore_unit.py +0 -0
  84. {proximl-0.5.5 → proximl-0.5.7}/tests/unit/cli/cloudbender/test_cli_device_unit.py +0 -0
  85. {proximl-0.5.5 → proximl-0.5.7}/tests/unit/cli/cloudbender/test_cli_node_unit.py +0 -0
  86. {proximl-0.5.5 → proximl-0.5.7}/tests/unit/cli/cloudbender/test_cli_provider_unit.py +0 -0
  87. {proximl-0.5.5 → proximl-0.5.7}/tests/unit/cli/cloudbender/test_cli_region_unit.py +0 -0
  88. {proximl-0.5.5 → proximl-0.5.7}/tests/unit/cli/conftest.py +0 -0
  89. {proximl-0.5.5 → proximl-0.5.7}/tests/unit/cli/test_cli_checkpoint_unit.py +0 -0
  90. {proximl-0.5.5 → proximl-0.5.7}/tests/unit/cli/test_cli_datasets_unit.py +0 -0
  91. {proximl-0.5.5 → proximl-0.5.7}/tests/unit/cli/test_cli_environment_unit.py +0 -0
  92. {proximl-0.5.5 → proximl-0.5.7}/tests/unit/cli/test_cli_gpu_unit.py +0 -0
  93. {proximl-0.5.5 → proximl-0.5.7}/tests/unit/cli/test_cli_job_unit.py +0 -0
  94. {proximl-0.5.5 → proximl-0.5.7}/tests/unit/cli/test_cli_model_unit.py +0 -0
  95. {proximl-0.5.5 → proximl-0.5.7}/tests/unit/cli/test_cli_volume_unit.py +0 -0
  96. {proximl-0.5.5 → proximl-0.5.7}/tests/unit/cloudbender/__init__.py +0 -0
  97. {proximl-0.5.5 → proximl-0.5.7}/tests/unit/cloudbender/test_datastores_unit.py +0 -0
  98. {proximl-0.5.5 → proximl-0.5.7}/tests/unit/cloudbender/test_device_configs_unit.py +0 -0
  99. {proximl-0.5.5 → proximl-0.5.7}/tests/unit/cloudbender/test_devices_unit.py +0 -0
  100. {proximl-0.5.5 → proximl-0.5.7}/tests/unit/cloudbender/test_nodes_unit.py +0 -0
  101. {proximl-0.5.5 → proximl-0.5.7}/tests/unit/cloudbender/test_providers_unit.py +0 -0
  102. {proximl-0.5.5 → proximl-0.5.7}/tests/unit/cloudbender/test_regions_unit.py +0 -0
  103. {proximl-0.5.5 → proximl-0.5.7}/tests/unit/test_auth.py +0 -0
  104. {proximl-0.5.5 → proximl-0.5.7}/tests/unit/test_checkpoints_unit.py +0 -0
  105. {proximl-0.5.5 → proximl-0.5.7}/tests/unit/test_connections_unit.py +0 -0
  106. {proximl-0.5.5 → proximl-0.5.7}/tests/unit/test_datasets_unit.py +0 -0
  107. {proximl-0.5.5 → proximl-0.5.7}/tests/unit/test_environments_unit.py +0 -0
  108. {proximl-0.5.5 → proximl-0.5.7}/tests/unit/test_exceptions.py +0 -0
  109. {proximl-0.5.5 → proximl-0.5.7}/tests/unit/test_gpu_types_unit.py +0 -0
  110. {proximl-0.5.5 → proximl-0.5.7}/tests/unit/test_jobs_unit.py +0 -0
  111. {proximl-0.5.5 → proximl-0.5.7}/tests/unit/test_models_unit.py +0 -0
  112. {proximl-0.5.5 → proximl-0.5.7}/tests/unit/test_proximl.py +0 -0
  113. {proximl-0.5.5 → proximl-0.5.7}/tests/unit/test_volumes_unit.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: proximl
3
- Version: 0.5.5
3
+ Version: 0.5.7
4
4
  Summary: proxiML client SDK and command line utilities
5
5
  Home-page: https://github.com/proxiML/python-sdk
6
6
  Author: proxiML
@@ -13,5 +13,5 @@ logging.basicConfig(
13
13
  logger = logging.getLogger(__name__)
14
14
 
15
15
 
16
- __version__ = "0.5.5"
16
+ __version__ = "0.5.7"
17
17
  __all__ = "ProxiML"
@@ -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
- .get("client")
128
- .get("ssh_port"),
129
- input_path=self._checkpoint.get("source_uri")
130
- if self.status in ["new", "downloading"]
131
- else None,
132
- output_path=self._checkpoint.get("output_uri")
133
- if self.status == "exporting"
134
- else None,
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
- if self.status == status:
234
- return
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.reservation import reservation
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 reservation(config):
9
- """proxiML CloudBender reservation commands."""
8
+ def data_connector(config):
9
+ """proxiML CloudBender data connector commands."""
10
10
  pass
11
11
 
12
12
 
13
- @reservation.command()
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 reservations for.",
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 reservations."""
30
+ """List data connectors."""
31
31
  data = [
32
- ["ID", "NAME", "TYPE", "RESOURCE", "HOSTNAME"],
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
- reservations = config.proximl.run(
43
- config.proximl.client.cloudbender.reservations.list(
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 reservation in reservations:
46
+ for data_connector in data_connectors:
49
47
  data.append(
50
48
  [
51
- reservation.id,
52
- reservation.name,
53
- reservation.type,
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} {: >9.8} {: >29.28}"
62
- "".format(*row),
57
+ "{: >37.36} {: >29.28} {: >9.8}" "".format(*row),
63
58
  file=config.stdout,
64
59
  )
65
60
 
66
61
 
67
- @reservation.command()
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 reservation in.",
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
- "port",
82
+ "custom",
88
83
  ],
89
84
  case_sensitive=False,
90
85
  ),
91
86
  required=True,
92
- help="The type of reservation to create.",
87
+ help="The type of data connector to create.",
93
88
  )
94
89
  @click.option(
95
- "--hostname",
96
- "-h",
90
+ "--protocol",
91
+ "-r",
97
92
  type=click.STRING,
98
- required=True,
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
- "--resource",
103
- "-r",
96
+ "--port-range",
97
+ "-p",
104
98
  type=click.STRING,
105
- required=True,
106
- help="The resource to reserve",
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, hostname, resource, name):
109
+ def create(config, provider, region, type, protocol, port_range, cidr, name):
111
110
  """
112
- Creates a reservation.
111
+ Creates a data_connector.
113
112
  """
114
113
  return config.proximl.run(
115
- config.proximl.client.cloudbender.reservations.create(
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
- @reservation.command()
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 reservation from.",
139
+ help="The region ID to remove the data_connector from.",
140
140
  )
141
- @click.argument("reservation", type=click.STRING)
141
+ @click.argument("data_connector", type=click.STRING)
142
142
  @pass_config
143
- def remove(config, provider, region, reservation):
143
+ def remove(config, provider, region, data_connector):
144
144
  """
145
- Remove a reservation.
145
+ Remove a data_connector.
146
146
 
147
- RESERVATION may be specified by name or ID, but ID is preferred.
147
+ DATASTORE may be specified by name or ID, but ID is preferred.
148
148
  """
149
- reservations = config.proximl.run(
150
- config.proximl.client.cloudbender.reservations.list(
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(reservation, reservations)
155
+ found = search_by_id_name(data_connector, data_connectors)
156
156
  if None is found:
157
- raise click.UsageError("Cannot find specified reservation.")
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 list_reservations(config):
119
- """List project reservations."""
118
+ def list_services(config):
119
+ """List project services."""
120
120
  data = [
121
- ["ID", "NAME", "TYPE", "RESOURCE", "HOSTNAME", "REGION_UUID"],
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
- reservations = config.proximl.run(project.list_reservations())
133
+ services = config.proximl.run(project.list_services())
136
134
 
137
- for reservation in reservations:
135
+ for service in services:
138
136
  data.append(
139
137
  [
140
- reservation.id,
141
- reservation.name,
142
- reservation.type,
143
- reservation.resource,
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} {: >8.6} {: >15.13} {: >30.28} {: >38.36}"
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 .reservations import Reservations
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.reservations = Reservations(proximl)
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 Reservations(object):
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}/reservation/{id}",
11
+ f"/provider/{provider_uuid}/region/{region_uuid}/data_connector/{id}",
12
12
  "GET",
13
13
  kwargs,
14
14
  )
15
- return Reservation(self.proximl, **resp)
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}/reservation",
19
+ f"/provider/{provider_uuid}/region/{region_uuid}/data_connector",
20
20
  "GET",
21
21
  kwargs,
22
22
  )
23
- reservations = [
24
- Reservation(self.proximl, **reservation) for reservation in resp
23
+ data_connectors = [
24
+ DataConnector(self.proximl, **data_connector) for data_connector in resp
25
25
  ]
26
- return reservations
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 Reservation {name}")
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}/reservation",
44
+ f"/provider/{provider_uuid}/region/{region_uuid}/data_connector",
49
45
  "POST",
50
46
  None,
51
47
  payload,
52
48
  )
53
- reservation = Reservation(self.proximl, **resp)
54
- logging.info(f"Created Reservation {name} with id {reservation.id}")
55
- return reservation
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}/reservation/{id}",
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 Reservation:
61
+ class DataConnector:
66
62
  def __init__(self, proximl, **kwargs):
67
63
  self.proximl = proximl
68
- self._reservation = kwargs
69
- self._id = self._reservation.get("reservation_id")
70
- self._provider_uuid = self._reservation.get("provider_uuid")
71
- self._region_uuid = self._reservation.get("region_uuid")
72
- self._type = self._reservation.get("type")
73
- self._name = self._reservation.get("name")
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._reservation.items()})
92
+ return json.dumps({k: v for k, v in self._data_connector.items()})
107
93
 
108
94
  def __repr__(self):
109
- return f"Reservation( proximl , **{self._reservation.__repr__()})"
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}/reservation/{self._id}",
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}/reservation/{self._id}",
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)