proximl 0.5.6__py3-none-any.whl → 0.5.7__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.
@@ -0,0 +1,159 @@
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 data_connector(config):
9
+ """proxiML CloudBender data connector commands."""
10
+ pass
11
+
12
+
13
+ @data_connector.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 data connectors for.",
27
+ )
28
+ @pass_config
29
+ def list(config, provider, region):
30
+ """List data connectors."""
31
+ data = [
32
+ ["ID", "NAME", "TYPE"],
33
+ [
34
+ "-" * 80,
35
+ "-" * 80,
36
+ "-" * 80,
37
+ ],
38
+ ]
39
+
40
+ data_connectors = config.proximl.run(
41
+ config.proximl.client.cloudbender.data_connectors.list(
42
+ provider_uuid=provider, region_uuid=region
43
+ )
44
+ )
45
+
46
+ for data_connector in data_connectors:
47
+ data.append(
48
+ [
49
+ data_connector.id,
50
+ data_connector.name,
51
+ data_connector.type,
52
+ ]
53
+ )
54
+
55
+ for row in data:
56
+ click.echo(
57
+ "{: >37.36} {: >29.28} {: >9.8}" "".format(*row),
58
+ file=config.stdout,
59
+ )
60
+
61
+
62
+ @data_connector.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 data_connector in.",
76
+ )
77
+ @click.option(
78
+ "--type",
79
+ "-t",
80
+ type=click.Choice(
81
+ [
82
+ "custom",
83
+ ],
84
+ case_sensitive=False,
85
+ ),
86
+ required=True,
87
+ help="The type of data connector to create.",
88
+ )
89
+ @click.option(
90
+ "--protocol",
91
+ "-r",
92
+ type=click.STRING,
93
+ help="The transport protocol of the data connector",
94
+ )
95
+ @click.option(
96
+ "--port-range",
97
+ "-p",
98
+ type=click.STRING,
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",
106
+ )
107
+ @click.argument("name", type=click.STRING, required=True)
108
+ @pass_config
109
+ def create(config, provider, region, type, protocol, port_range, cidr, name):
110
+ """
111
+ Creates a data_connector.
112
+ """
113
+ return config.proximl.run(
114
+ config.proximl.client.cloudbender.data_connectors.create(
115
+ provider_uuid=provider,
116
+ region_uuid=region,
117
+ name=name,
118
+ type=type,
119
+ protocol=protocol,
120
+ port_range=port_range,
121
+ cidr=cidr,
122
+ )
123
+ )
124
+
125
+
126
+ @data_connector.command()
127
+ @click.option(
128
+ "--provider",
129
+ "-p",
130
+ type=click.STRING,
131
+ required=True,
132
+ help="The provider ID of the region.",
133
+ )
134
+ @click.option(
135
+ "--region",
136
+ "-r",
137
+ type=click.STRING,
138
+ required=True,
139
+ help="The region ID to remove the data_connector from.",
140
+ )
141
+ @click.argument("data_connector", type=click.STRING)
142
+ @pass_config
143
+ def remove(config, provider, region, data_connector):
144
+ """
145
+ Remove a data_connector.
146
+
147
+ DATASTORE may be specified by name or ID, but ID is preferred.
148
+ """
149
+ data_connectors = config.proximl.run(
150
+ config.proximl.client.cloudbender.data_connectors.list(
151
+ provider_uuid=provider, region_uuid=region
152
+ )
153
+ )
154
+
155
+ found = search_by_id_name(data_connector, data_connectors)
156
+ if None is found:
157
+ raise click.UsageError("Cannot find specified data_connector.")
158
+
159
+ return config.proximl.run(found.remove())
@@ -0,0 +1,112 @@
1
+ import json
2
+ import logging
3
+
4
+
5
+ class DataConnectors(object):
6
+ def __init__(self, proximl):
7
+ self.proximl = proximl
8
+
9
+ async def get(self, provider_uuid, region_uuid, id, **kwargs):
10
+ resp = await self.proximl._query(
11
+ f"/provider/{provider_uuid}/region/{region_uuid}/data_connector/{id}",
12
+ "GET",
13
+ kwargs,
14
+ )
15
+ return DataConnector(self.proximl, **resp)
16
+
17
+ async def list(self, provider_uuid, region_uuid, **kwargs):
18
+ resp = await self.proximl._query(
19
+ f"/provider/{provider_uuid}/region/{region_uuid}/data_connector",
20
+ "GET",
21
+ kwargs,
22
+ )
23
+ data_connectors = [
24
+ DataConnector(self.proximl, **data_connector) for data_connector in resp
25
+ ]
26
+ return data_connectors
27
+
28
+ async def create(
29
+ self,
30
+ provider_uuid,
31
+ region_uuid,
32
+ name,
33
+ type,
34
+ **kwargs,
35
+ ):
36
+ logging.info(f"Creating Data Connector {name}")
37
+ data = dict(
38
+ name=name,
39
+ type=type,
40
+ **kwargs,
41
+ )
42
+ payload = {k: v for k, v in data.items() if v is not None}
43
+ resp = await self.proximl._query(
44
+ f"/provider/{provider_uuid}/region/{region_uuid}/data_connector",
45
+ "POST",
46
+ None,
47
+ payload,
48
+ )
49
+ data_connector = DataConnector(self.proximl, **resp)
50
+ logging.info(f"Created Data Connector {name} with id {data_connector.id}")
51
+ return data_connector
52
+
53
+ async def remove(self, provider_uuid, region_uuid, id, **kwargs):
54
+ await self.proximl._query(
55
+ f"/provider/{provider_uuid}/region/{region_uuid}/data_connector/{id}",
56
+ "DELETE",
57
+ kwargs,
58
+ )
59
+
60
+
61
+ class DataConnector:
62
+ def __init__(self, proximl, **kwargs):
63
+ self.proximl = proximl
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")
70
+
71
+ @property
72
+ def id(self) -> str:
73
+ return self._id
74
+
75
+ @property
76
+ def provider_uuid(self) -> str:
77
+ return self._provider_uuid
78
+
79
+ @property
80
+ def region_uuid(self) -> str:
81
+ return self._region_uuid
82
+
83
+ @property
84
+ def type(self) -> str:
85
+ return self._type
86
+
87
+ @property
88
+ def name(self) -> str:
89
+ return self._name
90
+
91
+ def __str__(self):
92
+ return json.dumps({k: v for k, v in self._data_connector.items()})
93
+
94
+ def __repr__(self):
95
+ return f"DataConnector( proximl , **{self._data_connector.__repr__()})"
96
+
97
+ def __bool__(self):
98
+ return bool(self._id)
99
+
100
+ async def remove(self):
101
+ await self.proximl._query(
102
+ f"/provider/{self._provider_uuid}/region/{self._region_uuid}/data_connector/{self._id}",
103
+ "DELETE",
104
+ )
105
+
106
+ async def refresh(self):
107
+ resp = await self.proximl._query(
108
+ f"/provider/{self._provider_uuid}/region/{self._region_uuid}/data_connector/{self._id}",
109
+ "GET",
110
+ )
111
+ self.__init__(self.proximl, **resp)
112
+ return self
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: proximl
3
- Version: 0.5.6
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
@@ -26,6 +26,7 @@ proximl/cli/model.py,sha256=xdjveIaRPK7MdfrnFygPEuwYRJRW9VqheZ-11XnXDcE,6111
26
26
  proximl/cli/project.py,sha256=Er1twSiWQSAKir-hBIT9fRo2fc_UGqFoIJOwwjQGmlo,3522
27
27
  proximl/cli/volume.py,sha256=uyIrKov4zwCjyLyZrEJYoEbIkS0zdU3xSyWZk2BM1kA,6246
28
28
  proximl/cli/cloudbender/__init__.py,sha256=vxj62MyM3sC9h8M4ii3szH4s9JvEhicOQ0D0m7eNwPA,534
29
+ proximl/cli/cloudbender/data_connector.py,sha256=D5xbUzpUGpn_NN-NZQ9vSxOZY610c1LsoBC40DkPwkw,3606
29
30
  proximl/cli/cloudbender/datastore.py,sha256=_vQOj-NfrL_nj4HfxNJL63TJZjLgfDyztRLyaRU58v8,3478
30
31
  proximl/cli/cloudbender/device.py,sha256=FdQZPESP6YBfUSzXq1Byu7eNMKi59qSOICONK-TEljI,3453
31
32
  proximl/cli/cloudbender/node.py,sha256=xxzj68YvpRey2vZQasgYTnwv3x7TnwpuPSSf8Ma5a54,3843
@@ -37,6 +38,7 @@ proximl/cli/job/__init__.py,sha256=s8mU2PvCWDcv4gGT3EmjHn8MIZlXBAoayoZKmnKpXnY,6
37
38
  proximl/cli/job/create.py,sha256=sGvbenY0yxvxHo-FZVbdw8FaZx5D4ekTCjD7P4YHG4g,34288
38
39
  proximl/cloudbender/__init__.py,sha256=iE29obtC0_9f0IhRvHQcG5aY58fVhVYipTakpjAhdss,64
39
40
  proximl/cloudbender/cloudbender.py,sha256=E1_MyOhl-Fq5gr6vitCdI34_f24Pa5cg9YrFXIXPwg8,634
41
+ proximl/cloudbender/data_connectors.py,sha256=urhmaAi4TBR-6L1CD2qS7SG3Dcwo9hOi8Gx613MzKVU,3297
40
42
  proximl/cloudbender/datastores.py,sha256=RzwJnoVs8gn_WpUJxF6MZ1dTQogUVX0B25ALQ26QOmE,3506
41
43
  proximl/cloudbender/device_configs.py,sha256=VkiF8MXHfsEWEwdgNeioT8dnEAXkY3_Z1r3L3UlZK_E,3399
42
44
  proximl/cloudbender/devices.py,sha256=vHooaOw2k2Tf99FJHnVZTgggqCTYJg7rq46aUPW0k8M,5660
@@ -88,7 +90,9 @@ tests/unit/cli/cloudbender/test_cli_node_unit.py,sha256=uh1Nt0ewk0v81iN5wCyBPzSX
88
90
  tests/unit/cli/cloudbender/test_cli_provider_unit.py,sha256=jCnFnqZuLzuDx9u3kLyjT83nBDWKn7LDCz6ErzCce1g,781
89
91
  tests/unit/cli/cloudbender/test_cli_region_unit.py,sha256=mEAU0z_gKDM-e5J_V8igXmiU4qjrOfzJJRtKRNWdeBs,1262
90
92
  tests/unit/cli/cloudbender/test_cli_reservation_unit.py,sha256=Lcr-xeNVAtVLHllQnjyFOs9CI62iOseu2vVFGynnLks,1407
93
+ tests/unit/cli/cloudbender/test_cli_service_unit.py,sha256=7gFaD-Ox22Gevvk6Sn8zGNp_k3jemwgDX3Yqx8yYN3I,1311
91
94
  tests/unit/cloudbender/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
95
+ tests/unit/cloudbender/test_data_connectors_unit.py,sha256=ZCnI9Gr2RAcpHiPZ5t2kakjzJhhF5_S7XkBCPGyYd8k,5783
92
96
  tests/unit/cloudbender/test_datastores_unit.py,sha256=pZPLwfWl1ZDR1WYaRjDYflv5UfHhTxOvLzXJ-LdG_as,5398
93
97
  tests/unit/cloudbender/test_device_configs_unit.py,sha256=wBDnTfrP6yl0K_jWcNU2ADR6iHoe1sRzMpvNfs_dwXs,5714
94
98
  tests/unit/cloudbender/test_devices_unit.py,sha256=C2YTnfIpHlxdidgfbTnlzl72r5O7kqKStQUhWcTTXDg,9103
@@ -97,9 +101,9 @@ tests/unit/cloudbender/test_providers_unit.py,sha256=y63VCqHXb4Yu8sh0kW30-ojRvv9
97
101
  tests/unit/cloudbender/test_regions_unit.py,sha256=9bvP268gpNyygjh1IEpSSiUt2aP6okv7QOsV1XoaIS0,6299
98
102
  tests/unit/cloudbender/test_reservations_unit.py,sha256=ICuFT5sexnLvS7taoC18yQYuDZHpBRrNuCj3Uq_Arwo,5624
99
103
  tests/unit/cloudbender/test_services_unit.py,sha256=iYaQpyCXDg77GQEIhmgiVwKX83jyvIf-4-4oya5WA_o,5043
100
- proximl-0.5.6.dist-info/LICENSE,sha256=ADFxLEZDxKY0j4MdyUd5GNuhQ18rnWH5rOz1ZG7yiOA,1069
101
- proximl-0.5.6.dist-info/METADATA,sha256=wS2y66puGjq7ZkG2GsyFIJWCiSjbDiA5uUdA8PzlIqw,7344
102
- proximl-0.5.6.dist-info/WHEEL,sha256=pkctZYzUS4AYVn6dJ-7367OJZivF2e8RA9b_ZBjif18,92
103
- proximl-0.5.6.dist-info/entry_points.txt,sha256=HmI311IIabkZReMCXu-nGbvIEW-KfaduAOyfiSqt5SY,63
104
- proximl-0.5.6.dist-info/top_level.txt,sha256=-TWqc9tAaxmWmW4c7uYsmzPEYUIoh6z02xxqPbv7Kys,23
105
- proximl-0.5.6.dist-info/RECORD,,
104
+ proximl-0.5.7.dist-info/LICENSE,sha256=ADFxLEZDxKY0j4MdyUd5GNuhQ18rnWH5rOz1ZG7yiOA,1069
105
+ proximl-0.5.7.dist-info/METADATA,sha256=PK4Sh7VrHGIj1QOJWKHtkpXFguLXrKfOgFk8gW80PYw,7344
106
+ proximl-0.5.7.dist-info/WHEEL,sha256=pkctZYzUS4AYVn6dJ-7367OJZivF2e8RA9b_ZBjif18,92
107
+ proximl-0.5.7.dist-info/entry_points.txt,sha256=HmI311IIabkZReMCXu-nGbvIEW-KfaduAOyfiSqt5SY,63
108
+ proximl-0.5.7.dist-info/top_level.txt,sha256=-TWqc9tAaxmWmW4c7uYsmzPEYUIoh6z02xxqPbv7Kys,23
109
+ proximl-0.5.7.dist-info/RECORD,,
@@ -0,0 +1,34 @@
1
+ import re
2
+ import json
3
+ import click
4
+ from unittest.mock import AsyncMock, patch
5
+ from pytest import mark, fixture, raises
6
+
7
+ pytestmark = [mark.cli, mark.unit, mark.cloudbender, mark.services]
8
+
9
+ from proximl.cli.cloudbender import service as specimen
10
+ from proximl.cloudbender.services import Service
11
+
12
+
13
+ def test_list(runner, mock_services):
14
+ with patch("proximl.cli.ProxiML", new=AsyncMock) as mock_proximl:
15
+ mock_proximl.cloudbender = AsyncMock()
16
+ mock_proximl.cloudbender.services = AsyncMock()
17
+ mock_proximl.cloudbender.services.list = AsyncMock(return_value=mock_services)
18
+ result = runner.invoke(
19
+ specimen,
20
+ args=["list", "--provider=prov-id-1", "--region=reg-id-1"],
21
+ )
22
+ assert result.exit_code == 0
23
+ mock_proximl.cloudbender.services.list.assert_called_once_with(
24
+ provider_uuid="prov-id-1", region_uuid="reg-id-1"
25
+ )
26
+
27
+
28
+ def test_list_no_provider(runner, mock_services):
29
+ with patch("proximl.cli.ProxiML", new=AsyncMock) as mock_proximl:
30
+ mock_proximl.cloudbender = AsyncMock()
31
+ mock_proximl.cloudbender.services = AsyncMock()
32
+ mock_proximl.cloudbender.services.list = AsyncMock(return_value=mock_services)
33
+ result = runner.invoke(specimen, ["list"])
34
+ assert result.exit_code != 0
@@ -0,0 +1,176 @@
1
+ import re
2
+ import json
3
+ import logging
4
+ from unittest.mock import AsyncMock, patch
5
+ from pytest import mark, fixture, raises
6
+ from aiohttp import WSMessage, WSMsgType
7
+
8
+ import proximl.cloudbender.data_connectors as specimen
9
+ from proximl.exceptions import (
10
+ ApiError,
11
+ SpecificationError,
12
+ ProxiMLException,
13
+ )
14
+
15
+ pytestmark = [mark.sdk, mark.unit, mark.cloudbender, mark.data_connectors]
16
+
17
+
18
+ @fixture
19
+ def data_connectors(mock_proximl):
20
+ yield specimen.DataConnectors(mock_proximl)
21
+
22
+
23
+ @fixture
24
+ def data_connector(mock_proximl):
25
+ yield specimen.DataConnector(
26
+ mock_proximl,
27
+ provider_uuid="1",
28
+ region_uuid="a",
29
+ connector_id="x",
30
+ name="On-Prem Data Connector",
31
+ type="custom",
32
+ cidr="192.168.0.50/32",
33
+ port="443",
34
+ protocol="tcp",
35
+ )
36
+
37
+
38
+ class RegionsTests:
39
+ @mark.asyncio
40
+ async def test_get_data_connector(
41
+ self,
42
+ data_connectors,
43
+ mock_proximl,
44
+ ):
45
+ api_response = dict()
46
+ mock_proximl._query = AsyncMock(return_value=api_response)
47
+ await data_connectors.get("1234", "5687", "91011")
48
+ mock_proximl._query.assert_called_once_with(
49
+ "/provider/1234/region/5687/data_connector/91011", "GET", {}
50
+ )
51
+
52
+ @mark.asyncio
53
+ async def test_list_data_connectors(
54
+ self,
55
+ data_connectors,
56
+ mock_proximl,
57
+ ):
58
+ api_response = dict()
59
+ mock_proximl._query = AsyncMock(return_value=api_response)
60
+ await data_connectors.list("1234", "5687")
61
+ mock_proximl._query.assert_called_once_with(
62
+ "/provider/1234/region/5687/data_connector", "GET", {}
63
+ )
64
+
65
+ @mark.asyncio
66
+ async def test_remove_data_connector(
67
+ self,
68
+ data_connectors,
69
+ mock_proximl,
70
+ ):
71
+ api_response = dict()
72
+ mock_proximl._query = AsyncMock(return_value=api_response)
73
+ await data_connectors.remove("1234", "4567", "8910")
74
+ mock_proximl._query.assert_called_once_with(
75
+ "/provider/1234/region/4567/data_connector/8910", "DELETE", {}
76
+ )
77
+
78
+ @mark.asyncio
79
+ async def test_create_data_connector(self, data_connectors, mock_proximl):
80
+ requested_config = dict(
81
+ provider_uuid="provider-id-1",
82
+ region_uuid="region-id-1",
83
+ name="On-Prem DataConnector",
84
+ type="custom",
85
+ cidr="192.168.0.50/32",
86
+ port="443",
87
+ protocol="tcp",
88
+ )
89
+ expected_payload = dict(
90
+ name="On-Prem DataConnector",
91
+ type="custom",
92
+ cidr="192.168.0.50/32",
93
+ port="443",
94
+ protocol="tcp",
95
+ )
96
+ api_response = {
97
+ "provider_uuid": "provider-id-1",
98
+ "region_uuid": "region-id-1",
99
+ "connector_id": "connector-id-1",
100
+ "name": "On-Prem DataConnector",
101
+ "type": "custom",
102
+ "cidr": "192.168.0.50/32",
103
+ "port": "443",
104
+ "protocol": "tcp",
105
+ "createdAt": "2020-12-31T23:59:59.000Z",
106
+ }
107
+
108
+ mock_proximl._query = AsyncMock(return_value=api_response)
109
+ response = await data_connectors.create(**requested_config)
110
+ mock_proximl._query.assert_called_once_with(
111
+ "/provider/provider-id-1/region/region-id-1/data_connector",
112
+ "POST",
113
+ None,
114
+ expected_payload,
115
+ )
116
+ assert response.id == "connector-id-1"
117
+
118
+
119
+ class DataConnectorTests:
120
+ def test_data_connector_properties(self, data_connector):
121
+ assert isinstance(data_connector.id, str)
122
+ assert isinstance(data_connector.provider_uuid, str)
123
+ assert isinstance(data_connector.region_uuid, str)
124
+ assert isinstance(data_connector.type, str)
125
+ assert isinstance(data_connector.name, str)
126
+
127
+ def test_data_connector_str(self, data_connector):
128
+ string = str(data_connector)
129
+ regex = r"^{.*\"connector_id\": \"" + data_connector.id + r"\".*}$"
130
+ assert isinstance(string, str)
131
+ assert re.match(regex, string)
132
+
133
+ def test_data_connector_repr(self, data_connector):
134
+ string = repr(data_connector)
135
+ regex = (
136
+ r"^DataConnector\( proximl , \*\*{.*'connector_id': '"
137
+ + data_connector.id
138
+ + r"'.*}\)$"
139
+ )
140
+ assert isinstance(string, str)
141
+ assert re.match(regex, string)
142
+
143
+ def test_data_connector_bool(self, data_connector, mock_proximl):
144
+ empty_data_connector = specimen.DataConnector(mock_proximl)
145
+ assert bool(data_connector)
146
+ assert not bool(empty_data_connector)
147
+
148
+ @mark.asyncio
149
+ async def test_data_connector_remove(self, data_connector, mock_proximl):
150
+ api_response = dict()
151
+ mock_proximl._query = AsyncMock(return_value=api_response)
152
+ await data_connector.remove()
153
+ mock_proximl._query.assert_called_once_with(
154
+ "/provider/1/region/a/data_connector/x", "DELETE"
155
+ )
156
+
157
+ @mark.asyncio
158
+ async def test_data_connector_refresh(self, data_connector, mock_proximl):
159
+ api_response = {
160
+ "provider_uuid": "provider-id-1",
161
+ "region_uuid": "region-id-1",
162
+ "connector_id": "connector-id-1",
163
+ "name": "On-Prem DataConnector",
164
+ "type": "custom",
165
+ "cidr": "192.168.0.50/32",
166
+ "port": "443",
167
+ "protocol": "tcp",
168
+ "createdAt": "2020-12-31T23:59:59.000Z",
169
+ }
170
+ mock_proximl._query = AsyncMock(return_value=api_response)
171
+ response = await data_connector.refresh()
172
+ mock_proximl._query.assert_called_once_with(
173
+ f"/provider/1/region/a/data_connector/x", "GET"
174
+ )
175
+ assert data_connector.id == "connector-id-1"
176
+ assert response.id == "connector-id-1"