ciocore 6.3.2rc1__py2.py3-none-any.whl → 6.4.0__py2.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.
Potentially problematic release.
This version of ciocore might be problematic. Click here for more details.
- ciocore/VERSION +1 -1
- ciocore/__about__.py +3 -20
- ciocore/api_client.py +116 -236
- ciocore/cli/__init__.py +3 -0
- ciocore/cli/conductor.py +206 -0
- ciocore/config.py +44 -50
- ciocore/data.py +131 -85
- ciocore/downloader.py +64 -46
- ciocore/hardware_set.py +99 -326
- ciocore/package_environment.py +74 -48
- ciocore/package_tree.py +377 -300
- ciocore/uploader/_uploader.py +2 -6
- ciocore-6.4.0.data/scripts/conductor +19 -0
- ciocore-6.4.0.data/scripts/conductor.bat +13 -0
- {ciocore-6.3.2rc1.dist-info → ciocore-6.4.0.dist-info}/METADATA +12 -35
- ciocore-6.4.0.dist-info/RECORD +51 -0
- {ciocore-6.3.2rc1.dist-info → ciocore-6.4.0.dist-info}/WHEEL +1 -1
- tests/instance_type_fixtures.py +9 -43
- tests/mocks/api_client_mock.py +31 -0
- tests/test_hardware_set.py +4 -50
- ciocore/cli.py +0 -336
- ciocore/dev_inst_tagger.py +0 -120
- ciocore/docsite/404.html +0 -723
- ciocore/docsite/apidoc/api_client/index.html +0 -2590
- ciocore/docsite/apidoc/apidoc/index.html +0 -868
- ciocore/docsite/apidoc/config/index.html +0 -1562
- ciocore/docsite/apidoc/data/index.html +0 -1550
- ciocore/docsite/apidoc/hardware_set/index.html +0 -2324
- ciocore/docsite/apidoc/package_environment/index.html +0 -1430
- ciocore/docsite/apidoc/package_tree/index.html +0 -2310
- ciocore/docsite/assets/_mkdocstrings.css +0 -16
- ciocore/docsite/assets/images/favicon.png +0 -0
- ciocore/docsite/assets/javascripts/bundle.4e31edb1.min.js +0 -29
- ciocore/docsite/assets/javascripts/bundle.4e31edb1.min.js.map +0 -8
- ciocore/docsite/assets/javascripts/lunr/min/lunr.ar.min.js +0 -1
- ciocore/docsite/assets/javascripts/lunr/min/lunr.da.min.js +0 -18
- ciocore/docsite/assets/javascripts/lunr/min/lunr.de.min.js +0 -18
- ciocore/docsite/assets/javascripts/lunr/min/lunr.du.min.js +0 -18
- ciocore/docsite/assets/javascripts/lunr/min/lunr.es.min.js +0 -18
- ciocore/docsite/assets/javascripts/lunr/min/lunr.fi.min.js +0 -18
- ciocore/docsite/assets/javascripts/lunr/min/lunr.fr.min.js +0 -18
- ciocore/docsite/assets/javascripts/lunr/min/lunr.hi.min.js +0 -1
- ciocore/docsite/assets/javascripts/lunr/min/lunr.hu.min.js +0 -18
- ciocore/docsite/assets/javascripts/lunr/min/lunr.hy.min.js +0 -1
- ciocore/docsite/assets/javascripts/lunr/min/lunr.it.min.js +0 -18
- ciocore/docsite/assets/javascripts/lunr/min/lunr.ja.min.js +0 -1
- ciocore/docsite/assets/javascripts/lunr/min/lunr.jp.min.js +0 -1
- ciocore/docsite/assets/javascripts/lunr/min/lunr.kn.min.js +0 -1
- ciocore/docsite/assets/javascripts/lunr/min/lunr.ko.min.js +0 -1
- ciocore/docsite/assets/javascripts/lunr/min/lunr.multi.min.js +0 -1
- ciocore/docsite/assets/javascripts/lunr/min/lunr.nl.min.js +0 -18
- ciocore/docsite/assets/javascripts/lunr/min/lunr.no.min.js +0 -18
- ciocore/docsite/assets/javascripts/lunr/min/lunr.pt.min.js +0 -18
- ciocore/docsite/assets/javascripts/lunr/min/lunr.ro.min.js +0 -18
- ciocore/docsite/assets/javascripts/lunr/min/lunr.ru.min.js +0 -18
- ciocore/docsite/assets/javascripts/lunr/min/lunr.sa.min.js +0 -1
- ciocore/docsite/assets/javascripts/lunr/min/lunr.stemmer.support.min.js +0 -1
- ciocore/docsite/assets/javascripts/lunr/min/lunr.sv.min.js +0 -18
- ciocore/docsite/assets/javascripts/lunr/min/lunr.ta.min.js +0 -1
- ciocore/docsite/assets/javascripts/lunr/min/lunr.te.min.js +0 -1
- ciocore/docsite/assets/javascripts/lunr/min/lunr.th.min.js +0 -1
- ciocore/docsite/assets/javascripts/lunr/min/lunr.tr.min.js +0 -18
- ciocore/docsite/assets/javascripts/lunr/min/lunr.vi.min.js +0 -1
- ciocore/docsite/assets/javascripts/lunr/min/lunr.zh.min.js +0 -1
- ciocore/docsite/assets/javascripts/lunr/tinyseg.js +0 -206
- ciocore/docsite/assets/javascripts/lunr/wordcut.js +0 -6708
- ciocore/docsite/assets/javascripts/workers/search.dfff1995.min.js +0 -42
- ciocore/docsite/assets/javascripts/workers/search.dfff1995.min.js.map +0 -8
- ciocore/docsite/assets/stylesheets/main.83068744.min.css +0 -1
- ciocore/docsite/assets/stylesheets/main.83068744.min.css.map +0 -1
- ciocore/docsite/assets/stylesheets/palette.ecc896b0.min.css +0 -1
- ciocore/docsite/assets/stylesheets/palette.ecc896b0.min.css.map +0 -1
- ciocore/docsite/cmdline/docs/index.html +0 -834
- ciocore/docsite/cmdline/downloader/index.html +0 -897
- ciocore/docsite/cmdline/packages/index.html +0 -841
- ciocore/docsite/cmdline/uploader/index.html +0 -950
- ciocore/docsite/how-to-guides/index.html +0 -831
- ciocore/docsite/index.html +0 -853
- ciocore/docsite/logo.png +0 -0
- ciocore/docsite/objects.inv +0 -0
- ciocore/docsite/search/search_index.json +0 -1
- ciocore/docsite/sitemap.xml +0 -3
- ciocore/docsite/sitemap.xml.gz +0 -0
- ciocore/docsite/stylesheets/extra.css +0 -26
- ciocore/docsite/stylesheets/tables.css +0 -170
- ciocore/package_query.py +0 -171
- ciocore-6.3.2rc1.dist-info/RECORD +0 -115
- ciocore-6.3.2rc1.dist-info/entry_points.txt +0 -2
- tests/test_cli.py +0 -161
- tests/test_downloader.py +0 -56
- {ciocore-6.3.2rc1.dist-info → ciocore-6.4.0.dist-info}/top_level.txt +0 -0
ciocore/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
6.
|
|
1
|
+
6.4.0
|
ciocore/__about__.py
CHANGED
|
@@ -2,26 +2,9 @@ import os
|
|
|
2
2
|
|
|
3
3
|
__all__ = ["__version__"]
|
|
4
4
|
|
|
5
|
-
# Get the version from the VERSION file
|
|
6
|
-
# The VERSION file may be in the current directory or (in dev) one directory up
|
|
7
|
-
|
|
8
5
|
try:
|
|
9
|
-
with open(
|
|
10
|
-
os.path.join(os.path.abspath(os.path.dirname(__file__)), "VERSION"),
|
|
11
|
-
"r",
|
|
12
|
-
encoding="utf-8",
|
|
13
|
-
) as version_file:
|
|
6
|
+
with open(os.path.join(os.path.abspath(os.path.dirname(__file__)), 'VERSION')) as version_file:
|
|
14
7
|
__version__ = version_file.read().strip()
|
|
15
|
-
|
|
8
|
+
|
|
16
9
|
except IOError:
|
|
17
|
-
|
|
18
|
-
with open(
|
|
19
|
-
os.path.join(
|
|
20
|
-
os.path.abspath(os.path.dirname(os.path.dirname(__file__))), "VERSION"
|
|
21
|
-
),
|
|
22
|
-
"r",
|
|
23
|
-
encoding="utf-8",
|
|
24
|
-
) as version_file:
|
|
25
|
-
__version__ = version_file.read().strip()
|
|
26
|
-
except IOError:
|
|
27
|
-
__version__ = "dev"
|
|
10
|
+
__version__ = 'dev'
|
ciocore/api_client.py
CHANGED
|
@@ -1,7 +1,3 @@
|
|
|
1
|
-
"""
|
|
2
|
-
The api_client module is used to make requests to the Conductor API.
|
|
3
|
-
"""
|
|
4
|
-
|
|
5
1
|
import base64
|
|
6
2
|
import importlib
|
|
7
3
|
import json
|
|
@@ -18,7 +14,7 @@ try:
|
|
|
18
14
|
from urllib import parse
|
|
19
15
|
except ImportError:
|
|
20
16
|
import urlparse as parse
|
|
21
|
-
|
|
17
|
+
|
|
22
18
|
import ciocore
|
|
23
19
|
|
|
24
20
|
from ciocore import config
|
|
@@ -44,28 +40,45 @@ except AttributeError:
|
|
|
44
40
|
)
|
|
45
41
|
|
|
46
42
|
|
|
43
|
+
|
|
47
44
|
# TODO: appspot_dot_com_cert = os.path.join(common.base_dir(),'auth','appspot_dot_com_cert2') load
|
|
48
45
|
# appspot.com cert into requests lib verify = appspot_dot_com_cert
|
|
49
46
|
|
|
50
47
|
|
|
51
48
|
class ApiClient:
|
|
52
|
-
"""
|
|
53
|
-
The ApiClient class is a wrapper around the requests library that handles authentication and retries.
|
|
54
|
-
"""
|
|
55
|
-
|
|
56
49
|
http_verbs = ["PUT", "POST", "GET", "DELETE", "HEAD", "PATCH"]
|
|
57
|
-
|
|
50
|
+
|
|
58
51
|
USER_AGENT_TEMPLATE = "client {client_name}/{client_version} (ciocore {ciocore_version}; {runtime} {runtime_version}; {platform} {platform_details}; {hostname} {pid}; {python_path})"
|
|
59
52
|
USER_AGENT_MAX_PATH_LENGTH = 1024
|
|
60
|
-
|
|
53
|
+
|
|
61
54
|
user_agent_header = None
|
|
62
55
|
|
|
63
56
|
def __init__(self):
|
|
64
|
-
"""
|
|
65
|
-
Initialize the ApiClient object.
|
|
66
|
-
"""
|
|
67
57
|
logger.debug("")
|
|
68
58
|
|
|
59
|
+
def _make_request(self, verb, conductor_url, headers, params, data, raise_on_error=True):
|
|
60
|
+
response = requests.request(
|
|
61
|
+
method=verb, url=conductor_url, headers=headers, params=params, data=data
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
logger.debug("verb: %s", verb)
|
|
65
|
+
logger.debug("conductor_url: %s", conductor_url)
|
|
66
|
+
logger.debug("headers: %s", headers)
|
|
67
|
+
logger.debug("params: %s", params)
|
|
68
|
+
logger.debug("data: %s", data)
|
|
69
|
+
|
|
70
|
+
# If we get 300s/400s debug out the response. TODO(lws): REMOVE THIS
|
|
71
|
+
if response.status_code and 300 <= response.status_code < 500:
|
|
72
|
+
logger.debug("***** ERROR!! *****")
|
|
73
|
+
logger.debug("Reason: %s" % response.reason)
|
|
74
|
+
logger.debug("Text: %s" % response.text)
|
|
75
|
+
|
|
76
|
+
# trigger an exception to be raised for 4XX or 5XX http responses
|
|
77
|
+
if raise_on_error:
|
|
78
|
+
response.raise_for_status()
|
|
79
|
+
|
|
80
|
+
return response
|
|
81
|
+
|
|
69
82
|
def make_prepared_request(
|
|
70
83
|
self,
|
|
71
84
|
verb,
|
|
@@ -79,31 +92,30 @@ class ApiClient:
|
|
|
79
92
|
raise_on_error=True,
|
|
80
93
|
tries=5,
|
|
81
94
|
):
|
|
95
|
+
|
|
82
96
|
"""
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
raise_on_error (bool): Whether or not to raise an exception if the request fails.
|
|
106
|
-
tries (int): The number of times to retry the request.
|
|
97
|
+
Primarily used to removed enforced headers by requests.Request. Requests 2.x will add
|
|
98
|
+
Transfer-Encoding: chunked with file like object that is 0 bytes, causing s3 failures (501)
|
|
99
|
+
- https://github.com/psf/requests/issues/4215#issuecomment-319521235
|
|
100
|
+
|
|
101
|
+
To get around this bug make_prepared_request has functionality to remove the enforced header
|
|
102
|
+
that would occur when using requests.request(...). Requests 3.x resolves this issue, when
|
|
103
|
+
client is built to use Requests 3.x this function can be deprecated.
|
|
104
|
+
|
|
105
|
+
args:
|
|
106
|
+
verb: (str) of HTTP verbs
|
|
107
|
+
url: (str) url
|
|
108
|
+
headers: (dict)
|
|
109
|
+
params: (dict)
|
|
110
|
+
json: (dict)
|
|
111
|
+
data: (varies)
|
|
112
|
+
stream: (bool)
|
|
113
|
+
remove_headers_list: list of headers to remove i.e ["Transfer-Encoding"]
|
|
114
|
+
raise_on_error: (bool)
|
|
115
|
+
tries: (int) number of attempts to perform request
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
return: request.Response
|
|
107
119
|
"""
|
|
108
120
|
|
|
109
121
|
req = requests.Request(
|
|
@@ -121,11 +133,9 @@ class ApiClient:
|
|
|
121
133
|
prepped.headers.pop(header, None)
|
|
122
134
|
|
|
123
135
|
# Create a retry wrapper function
|
|
124
|
-
retry_wrapper = common.DecRetry(
|
|
125
|
-
retry_exceptions=CONNECTION_EXCEPTIONS, tries=tries
|
|
126
|
-
)
|
|
136
|
+
retry_wrapper = common.DecRetry(retry_exceptions=CONNECTION_EXCEPTIONS, tries=tries)
|
|
127
137
|
|
|
128
|
-
# requests sessions potentially not thread-safe, but need to removed enforced
|
|
138
|
+
# requests sessions potentially not thread-safe, but need to potentially removed enforced
|
|
129
139
|
# headers by using a prepared request.create which can only be done through an
|
|
130
140
|
# request.Session object. Create Session object per call of make_prepared_request, it will
|
|
131
141
|
# not benefit from connection pooling reuse. https://github.com/psf/requests/issues/1871
|
|
@@ -158,24 +168,10 @@ class ApiClient:
|
|
|
158
168
|
conductor_url=None,
|
|
159
169
|
raise_on_error=True,
|
|
160
170
|
tries=5,
|
|
161
|
-
use_api_key=False
|
|
171
|
+
use_api_key=False
|
|
162
172
|
):
|
|
163
173
|
"""
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
Args:
|
|
167
|
-
uri_path (str): The path to the resource to request.
|
|
168
|
-
headers (dict): A dictionary of headers to send with the request.
|
|
169
|
-
params (dict): A dictionary of query parameters to send with the request.
|
|
170
|
-
data (dict): A dictionary of data to send with the request.
|
|
171
|
-
verb (str): The HTTP verb to use.
|
|
172
|
-
conductor_url (str): The Conductor URL.
|
|
173
|
-
raise_on_error (bool): Whether or not to raise an exception if the request fails.
|
|
174
|
-
tries (int): The number of times to retry the request.
|
|
175
|
-
use`_api_key (bool): Whether or not to use the API key for authentication.
|
|
176
|
-
|
|
177
|
-
Returns:
|
|
178
|
-
tuple(str, int): The response text and status code.
|
|
174
|
+
verb: PUT, POST, GET, DELETE, HEAD, PATCH
|
|
179
175
|
"""
|
|
180
176
|
cfg = config.config().config
|
|
181
177
|
# TODO: set Content Content-Type to json if data arg
|
|
@@ -188,10 +184,10 @@ class ApiClient:
|
|
|
188
184
|
raise Exception("Error: Could not get conductor credentials!")
|
|
189
185
|
|
|
190
186
|
headers["Authorization"] = "Bearer %s" % bearer_token
|
|
191
|
-
|
|
187
|
+
|
|
192
188
|
if not ApiClient.user_agent_header:
|
|
193
189
|
self.register_client("ciocore")
|
|
194
|
-
|
|
190
|
+
|
|
195
191
|
headers["User-Agent"] = ApiClient.user_agent_header
|
|
196
192
|
|
|
197
193
|
# Construct URL
|
|
@@ -207,9 +203,7 @@ class ApiClient:
|
|
|
207
203
|
assert verb in self.http_verbs, "Invalid http verb: %s" % verb
|
|
208
204
|
|
|
209
205
|
# Create a retry wrapper function
|
|
210
|
-
retry_wrapper = common.DecRetry(
|
|
211
|
-
retry_exceptions=CONNECTION_EXCEPTIONS, tries=tries
|
|
212
|
-
)
|
|
206
|
+
retry_wrapper = common.DecRetry(retry_exceptions=CONNECTION_EXCEPTIONS, tries=tries)
|
|
213
207
|
|
|
214
208
|
# wrap the request function with the retry wrapper
|
|
215
209
|
wrapped_func = retry_wrapper(self._make_request)
|
|
@@ -220,155 +214,99 @@ class ApiClient:
|
|
|
220
214
|
)
|
|
221
215
|
|
|
222
216
|
return response.text, response.status_code
|
|
223
|
-
|
|
217
|
+
|
|
224
218
|
@classmethod
|
|
225
219
|
def _get_user_agent_header(cls, client_name, client_version=None):
|
|
226
|
-
|
|
227
|
-
Generates the http User Agent header that includes helpful debug info.
|
|
228
|
-
|
|
220
|
+
'''
|
|
221
|
+
Generates the http User Agent header that includes helpful debug info.
|
|
222
|
+
|
|
229
223
|
The final component is the path to the python executable (MD5 hex).
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
224
|
+
|
|
225
|
+
ex: 'ciomaya/0.3.7 (ciocore 4.3.2; python 3.9.5; linux 3.10.0-1160.53.1.el7.x86_64; 0ee7123c2365d7a0d126de5a70f19727)'
|
|
226
|
+
|
|
234
227
|
:param client_name: The name of the client to be used in the header. If it's importable it
|
|
235
228
|
will be queried for its __version__ (unless client_version is supplied)
|
|
236
229
|
:type client_name: str
|
|
237
|
-
|
|
230
|
+
|
|
238
231
|
:param client_version: The version to use in the header if client_name can't be queried for
|
|
239
232
|
__version__ (or it needs to be overridden)
|
|
240
233
|
:type client_version: str [default = None]
|
|
241
|
-
|
|
234
|
+
|
|
242
235
|
:return: The value for the User Agent header
|
|
243
|
-
:rtype: str
|
|
244
|
-
|
|
245
|
-
|
|
236
|
+
:rtype: str
|
|
237
|
+
'''
|
|
238
|
+
|
|
246
239
|
try:
|
|
247
240
|
client_module = importlib.import_module(client_name)
|
|
248
|
-
|
|
241
|
+
|
|
249
242
|
except ImportError:
|
|
250
|
-
logger.warning(
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
client_version = "unknown"
|
|
254
|
-
|
|
243
|
+
logger.warning("Unable to import module '{}'. Won't query for version details.")
|
|
244
|
+
client_version = 'unknown'
|
|
245
|
+
|
|
255
246
|
if not client_version:
|
|
256
247
|
try:
|
|
257
248
|
client_version = client_module.__version__
|
|
258
|
-
|
|
249
|
+
|
|
259
250
|
except AttributeError:
|
|
260
|
-
logger.warning(
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
client_version = "unknown"
|
|
264
|
-
|
|
251
|
+
logger.warning("Module '{}' has no __version__ attribute. Setting version to 'N/A' in the user agent")
|
|
252
|
+
client_version = 'unknown'
|
|
253
|
+
|
|
265
254
|
ciocore_version = ciocore.__version__
|
|
266
|
-
|
|
255
|
+
|
|
267
256
|
python_path = sys.executable
|
|
268
|
-
|
|
257
|
+
|
|
269
258
|
# If the length of the path is longer than allowed, truncate the middle
|
|
270
259
|
if len(python_path) > cls.USER_AGENT_MAX_PATH_LENGTH:
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
260
|
+
|
|
261
|
+
first_half = int(cls.USER_AGENT_MAX_PATH_LENGTH/2)
|
|
262
|
+
second_half = len(python_path) - int(cls.USER_AGENT_MAX_PATH_LENGTH/2)
|
|
263
|
+
|
|
274
264
|
print(first_half, second_half)
|
|
275
|
-
python_path = "{}...{}".format(
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
python_path_encoded = base64.b64encode(python_path.encode("utf-8")).decode(
|
|
280
|
-
"utf-8"
|
|
281
|
-
)
|
|
282
|
-
|
|
265
|
+
python_path = "{}...{}".format(python_path[0:first_half], python_path[second_half:-1])
|
|
266
|
+
|
|
267
|
+
python_path_encoded = base64.b64encode(python_path.encode('utf-8')).decode('utf-8')
|
|
268
|
+
|
|
283
269
|
if platform.system() == "Linux":
|
|
284
270
|
platform_details = platform.release()
|
|
285
|
-
|
|
271
|
+
|
|
286
272
|
elif platform.system() == "Windows":
|
|
287
273
|
platform_details = platform.version()
|
|
288
|
-
|
|
274
|
+
|
|
289
275
|
elif platform.system() == "Darwin":
|
|
290
276
|
platform_details = platform.mac_ver()[0]
|
|
291
|
-
|
|
277
|
+
|
|
292
278
|
else:
|
|
293
279
|
raise ValueError("Unrecognized platform '{}'".format(platform.release()))
|
|
294
|
-
|
|
295
|
-
pid = base64.b64encode(str(os.getpid()).encode(
|
|
296
|
-
hostname = base64.b64encode(socket.gethostname().encode(
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
python_path=python_path_encoded,
|
|
311
|
-
)
|
|
312
|
-
|
|
280
|
+
|
|
281
|
+
pid = base64.b64encode(str(os.getpid()).encode('utf-8')).decode('utf-8')
|
|
282
|
+
hostname = base64.b64encode(socket.gethostname().encode('utf-8')).decode('utf-8')
|
|
283
|
+
|
|
284
|
+
return cls.USER_AGENT_TEMPLATE.format(client_name=client_name,
|
|
285
|
+
client_version=client_version,
|
|
286
|
+
ciocore_version=ciocore_version,
|
|
287
|
+
runtime='python',
|
|
288
|
+
runtime_version=platform.python_version(),
|
|
289
|
+
platform=sys.platform,
|
|
290
|
+
platform_details=platform_details,
|
|
291
|
+
pid=pid,
|
|
292
|
+
hostname=hostname,
|
|
293
|
+
python_path=python_path_encoded
|
|
294
|
+
)
|
|
295
|
+
|
|
313
296
|
@classmethod
|
|
314
297
|
def register_client(cls, client_name, client_version=None):
|
|
315
298
|
cls.user_agent_header = cls._get_user_agent_header(client_name, client_version)
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
def _make_request(
|
|
319
|
-
self, verb, conductor_url, headers, params, data, raise_on_error=True
|
|
320
|
-
):
|
|
321
|
-
"""
|
|
322
|
-
Make a request to the Conductor API.
|
|
323
|
-
|
|
324
|
-
Args:
|
|
325
|
-
verb (str): The HTTP verb to use.
|
|
326
|
-
conductor_url (str): The URL to make the request to.
|
|
327
|
-
headers (dict): A dictionary of headers to send with the request.
|
|
328
|
-
params (dict): A dictionary of query parameters to send with the request.
|
|
329
|
-
data (dict): A dictionary of data to send with the request.
|
|
330
|
-
raise_on_error (bool): Whether or not to raise an exception if the request fails.
|
|
331
|
-
"""
|
|
332
|
-
|
|
333
|
-
response = requests.request(
|
|
334
|
-
method=verb, url=conductor_url, headers=headers, params=params, data=data
|
|
335
|
-
)
|
|
336
|
-
|
|
337
|
-
logger.debug("verb: %s", verb)
|
|
338
|
-
logger.debug("conductor_url: %s", conductor_url)
|
|
339
|
-
logger.debug("headers: %s", headers)
|
|
340
|
-
logger.debug("params: %s", params)
|
|
341
|
-
logger.debug("data: %s", data)
|
|
342
|
-
|
|
343
|
-
# If we get 300s/400s debug out the response. TODO(lws): REMOVE THIS
|
|
344
|
-
if response.status_code and 300 <= response.status_code < 500:
|
|
345
|
-
logger.debug("***** ERROR!! *****")
|
|
346
|
-
logger.debug("Reason: %s" % response.reason)
|
|
347
|
-
logger.debug("Text: %s" % response.text)
|
|
348
|
-
|
|
349
|
-
# trigger an exception to be raised for 4XX or 5XX http responses
|
|
350
|
-
if raise_on_error:
|
|
351
|
-
response.raise_for_status()
|
|
352
|
-
|
|
353
|
-
return response
|
|
354
|
-
|
|
299
|
+
|
|
300
|
+
|
|
355
301
|
|
|
356
302
|
def read_conductor_credentials(use_api_key=False):
|
|
357
303
|
"""
|
|
358
|
-
Read the conductor credentials file.
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
the user or the API key
|
|
362
|
-
|
|
363
|
-
If the credentials file doesn't exist, or is
|
|
364
|
-
expired, or is from a different domain, we try to fetch a new one in the API key scenario or
|
|
365
|
-
prompt the user to log in.
|
|
366
|
-
|
|
367
|
-
Args:
|
|
368
|
-
use_api_key (bool): Whether or not to try to use the API key
|
|
304
|
+
Read the conductor credentials file, if it exists. This will contain a bearer token from either
|
|
305
|
+
the user or the API key (if that's desired). If the credentials file doesn't exist, or is
|
|
306
|
+
expired, or is from a different domain, try and fetch a new one in the API key scenario or
|
|
307
|
+
prompt the user to log in. Args: use_api_key: Whether or not to use the API key
|
|
369
308
|
|
|
370
|
-
Returns:
|
|
371
|
-
A Bearer token in the event of a success or None.
|
|
309
|
+
Returns: A Bearer token in the event of a success or None if things couldn't get figured out
|
|
372
310
|
|
|
373
311
|
"""
|
|
374
312
|
|
|
@@ -428,15 +366,6 @@ def read_conductor_credentials(use_api_key=False):
|
|
|
428
366
|
|
|
429
367
|
|
|
430
368
|
def get_api_key_bearer_token(creds_file=None):
|
|
431
|
-
"""
|
|
432
|
-
Get a bearer token from the API key.
|
|
433
|
-
|
|
434
|
-
Args:
|
|
435
|
-
creds_file (str): The path to the credentials file. If not provided, the bearer token will not be written to disk.
|
|
436
|
-
|
|
437
|
-
Returns:
|
|
438
|
-
A dictionary containing the bearer token and other information.
|
|
439
|
-
"""
|
|
440
369
|
cfg = config.config().config
|
|
441
370
|
url = "{}/api/oauth_jwt".format(cfg["url"])
|
|
442
371
|
response = requests.get(
|
|
@@ -469,15 +398,7 @@ def get_api_key_bearer_token(creds_file=None):
|
|
|
469
398
|
|
|
470
399
|
|
|
471
400
|
def get_creds_path(api_key=False):
|
|
472
|
-
|
|
473
|
-
Get the path to the credentials file.
|
|
474
|
-
|
|
475
|
-
Args:
|
|
476
|
-
api_key (bool): Whether or not to use the API key.
|
|
477
|
-
|
|
478
|
-
Returns:
|
|
479
|
-
str: The path to the credentials file.
|
|
480
|
-
"""
|
|
401
|
+
|
|
481
402
|
creds_dir = os.path.join(os.path.expanduser("~"), ".config", "conductor")
|
|
482
403
|
if api_key:
|
|
483
404
|
creds_file = os.path.join(creds_dir, "api_key_credentials")
|
|
@@ -490,24 +411,12 @@ def get_bearer_token(refresh=False):
|
|
|
490
411
|
"""
|
|
491
412
|
Return the bearer token.
|
|
492
413
|
|
|
493
|
-
Args:
|
|
494
|
-
refresh (bool): Whether or not to refresh the token.
|
|
495
|
-
|
|
496
414
|
TODO: Thread safe multiproc caching, like it used to be pre-python3.7.
|
|
497
415
|
"""
|
|
498
416
|
return read_conductor_credentials(True)
|
|
499
417
|
|
|
500
418
|
|
|
501
419
|
def creds_same_domain(creds):
|
|
502
|
-
"""
|
|
503
|
-
Check if the creds are for the same domain as the config.
|
|
504
|
-
|
|
505
|
-
Args:
|
|
506
|
-
creds (dict): The credentials dictionary.
|
|
507
|
-
|
|
508
|
-
Returns:
|
|
509
|
-
bool: Whether or not the creds are for the same domain as the config.
|
|
510
|
-
"""
|
|
511
420
|
cfg = config.config().config
|
|
512
421
|
"""Ensure the creds file refers to the domain in config"""
|
|
513
422
|
token = creds.get("access_token")
|
|
@@ -525,12 +434,6 @@ def creds_same_domain(creds):
|
|
|
525
434
|
def account_id_from_jwt(token):
|
|
526
435
|
"""
|
|
527
436
|
Fetch the accounts id from a jwt token value.
|
|
528
|
-
|
|
529
|
-
Args:
|
|
530
|
-
token (str): The jwt token.
|
|
531
|
-
|
|
532
|
-
Returns:
|
|
533
|
-
str: The account id.
|
|
534
437
|
"""
|
|
535
438
|
payload = jwt.decode(token, verify=False)
|
|
536
439
|
return payload.get("account")
|
|
@@ -539,12 +442,6 @@ def account_id_from_jwt(token):
|
|
|
539
442
|
def account_name_from_jwt(token):
|
|
540
443
|
"""
|
|
541
444
|
Fetch the accounts name from a jwt token value.
|
|
542
|
-
|
|
543
|
-
Args:
|
|
544
|
-
token (str): The jwt token.
|
|
545
|
-
|
|
546
|
-
Returns:
|
|
547
|
-
str: The account name.
|
|
548
445
|
"""
|
|
549
446
|
cfg = config.config().config
|
|
550
447
|
account_id = account_id_from_jwt(token)
|
|
@@ -560,12 +457,6 @@ def account_name_from_jwt(token):
|
|
|
560
457
|
def request_instance_types(as_dict=False):
|
|
561
458
|
"""
|
|
562
459
|
Get the list of available instances types.
|
|
563
|
-
|
|
564
|
-
Args:
|
|
565
|
-
as_dict (bool): Whether or not to return the instance types as a dictionary.
|
|
566
|
-
|
|
567
|
-
Returns:
|
|
568
|
-
list: The list of instance types.
|
|
569
460
|
"""
|
|
570
461
|
api = ApiClient()
|
|
571
462
|
response, response_code = api.make_request(
|
|
@@ -580,21 +471,13 @@ def request_instance_types(as_dict=False):
|
|
|
580
471
|
logger.debug("Found available instance types: %s", instance_types)
|
|
581
472
|
|
|
582
473
|
if as_dict:
|
|
583
|
-
return dict(
|
|
584
|
-
[(instance["description"], instance) for instance in instance_types]
|
|
585
|
-
)
|
|
474
|
+
return dict([(instance["description"], instance) for instance in instance_types])
|
|
586
475
|
return instance_types
|
|
587
476
|
|
|
588
477
|
|
|
589
478
|
def request_projects(statuses=("active",)):
|
|
590
479
|
"""
|
|
591
|
-
Query Conductor for all client Projects that are in the given
|
|
592
|
-
|
|
593
|
-
Args:
|
|
594
|
-
statuses (tuple): The statuses to filter for.
|
|
595
|
-
|
|
596
|
-
Returns:
|
|
597
|
-
list: The list of project names.
|
|
480
|
+
Query Conductor for all client Projects that are in the given state(s)
|
|
598
481
|
"""
|
|
599
482
|
api = ApiClient()
|
|
600
483
|
|
|
@@ -623,9 +506,6 @@ def request_projects(statuses=("active",)):
|
|
|
623
506
|
def request_software_packages():
|
|
624
507
|
"""
|
|
625
508
|
Query Conductor for all software packages for the currently available sidecar.
|
|
626
|
-
|
|
627
|
-
Returns:
|
|
628
|
-
list: The list of software packages.
|
|
629
509
|
"""
|
|
630
510
|
api = ApiClient()
|
|
631
511
|
|
ciocore/cli/__init__.py
ADDED