ibm-cloud-sdk-core 3.15.0__py3-none-any.whl → 3.20.6__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.
- ibm_cloud_sdk_core/__init__.py +1 -0
- ibm_cloud_sdk_core/api_exception.py +18 -4
- ibm_cloud_sdk_core/authenticators/__init__.py +1 -0
- ibm_cloud_sdk_core/authenticators/authenticator.py +3 -3
- ibm_cloud_sdk_core/authenticators/basic_authenticator.py +5 -6
- ibm_cloud_sdk_core/authenticators/bearer_token_authenticator.py +1 -1
- ibm_cloud_sdk_core/authenticators/container_authenticator.py +25 -16
- ibm_cloud_sdk_core/authenticators/cp4d_authenticator.py +34 -20
- ibm_cloud_sdk_core/authenticators/iam_authenticator.py +22 -13
- ibm_cloud_sdk_core/authenticators/iam_request_based_authenticator.py +5 -7
- ibm_cloud_sdk_core/authenticators/mcsp_authenticator.py +130 -0
- ibm_cloud_sdk_core/authenticators/vpc_instance_authenticator.py +7 -10
- ibm_cloud_sdk_core/base_service.py +113 -92
- ibm_cloud_sdk_core/detailed_response.py +21 -15
- ibm_cloud_sdk_core/get_authenticator.py +28 -16
- ibm_cloud_sdk_core/http_adapter.py +28 -0
- ibm_cloud_sdk_core/private_helpers.py +34 -0
- ibm_cloud_sdk_core/token_managers/container_token_manager.py +61 -30
- ibm_cloud_sdk_core/token_managers/cp4d_token_manager.py +34 -21
- ibm_cloud_sdk_core/token_managers/iam_request_based_token_manager.py +43 -20
- ibm_cloud_sdk_core/token_managers/iam_token_manager.py +24 -13
- ibm_cloud_sdk_core/token_managers/jwt_token_manager.py +3 -16
- ibm_cloud_sdk_core/token_managers/mcsp_token_manager.py +102 -0
- ibm_cloud_sdk_core/token_managers/token_manager.py +13 -23
- ibm_cloud_sdk_core/token_managers/vpc_instance_token_manager.py +33 -13
- ibm_cloud_sdk_core/utils.py +126 -32
- ibm_cloud_sdk_core/version.py +1 -1
- {ibm_cloud_sdk_core-3.15.0.dist-info → ibm_cloud_sdk_core-3.20.6.dist-info}/METADATA +39 -30
- ibm_cloud_sdk_core-3.20.6.dist-info/RECORD +34 -0
- {ibm_cloud_sdk_core-3.15.0.dist-info → ibm_cloud_sdk_core-3.20.6.dist-info}/WHEEL +1 -1
- ibm_cloud_sdk_core-3.20.6.dist-info/top_level.txt +1 -0
- ibm_cloud_sdk_core-3.15.0.dist-info/RECORD +0 -52
- ibm_cloud_sdk_core-3.15.0.dist-info/top_level.txt +0 -3
- ibm_cloud_sdk_core-3.15.0.dist-info/zip-safe +0 -1
- test/__init__.py +0 -0
- test/test_api_exception.py +0 -73
- test/test_authenticator.py +0 -21
- test/test_base_service.py +0 -925
- test/test_basic_authenticator.py +0 -36
- test/test_bearer_authenticator.py +0 -28
- test/test_container_authenticator.py +0 -105
- test/test_container_token_manager.py +0 -283
- test/test_cp4d_authenticator.py +0 -171
- test/test_cp4d_token_manager.py +0 -56
- test/test_detailed_response.py +0 -57
- test/test_iam_authenticator.py +0 -157
- test/test_iam_token_manager.py +0 -362
- test/test_jwt_token_manager.py +0 -109
- test/test_no_auth_authenticator.py +0 -15
- test/test_token_manager.py +0 -84
- test/test_utils.py +0 -634
- test/test_vpc_instance_authenticator.py +0 -66
- test/test_vpc_instance_token_manager.py +0 -266
- test_integration/__init__.py +0 -0
- test_integration/test_cp4d_authenticator_integration.py +0 -45
- {ibm_cloud_sdk_core-3.15.0.dist-info → ibm_cloud_sdk_core-3.20.6.dist-info}/LICENSE +0 -0
test/test_utils.py
DELETED
|
@@ -1,634 +0,0 @@
|
|
|
1
|
-
# pylint: disable=missing-docstring
|
|
2
|
-
# coding: utf-8
|
|
3
|
-
|
|
4
|
-
# Copyright 2019, 2021 IBM All Rights Reserved.
|
|
5
|
-
#
|
|
6
|
-
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
7
|
-
# you may not use this file except in compliance with the License.
|
|
8
|
-
# You may obtain a copy of the License at
|
|
9
|
-
#
|
|
10
|
-
# http://www.apache.org/licenses/LICENSE-2.0
|
|
11
|
-
#
|
|
12
|
-
# Unless required by applicable law or agreed to in writing, software
|
|
13
|
-
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
14
|
-
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
15
|
-
# See the License for the specific language governing permissions and
|
|
16
|
-
# limitations under the License.
|
|
17
|
-
|
|
18
|
-
import datetime
|
|
19
|
-
import os
|
|
20
|
-
from typing import Optional
|
|
21
|
-
|
|
22
|
-
import pytest
|
|
23
|
-
|
|
24
|
-
from ibm_cloud_sdk_core import string_to_datetime, datetime_to_string, get_authenticator_from_environment
|
|
25
|
-
from ibm_cloud_sdk_core import string_to_datetime_list, datetime_to_string_list
|
|
26
|
-
from ibm_cloud_sdk_core import string_to_date, date_to_string
|
|
27
|
-
from ibm_cloud_sdk_core import convert_model, convert_list
|
|
28
|
-
from ibm_cloud_sdk_core import get_query_param
|
|
29
|
-
from ibm_cloud_sdk_core import read_external_sources
|
|
30
|
-
from ibm_cloud_sdk_core.authenticators import Authenticator, BasicAuthenticator, IAMAuthenticator
|
|
31
|
-
from ibm_cloud_sdk_core.utils import strip_extra_slashes
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
def datetime_test(datestr: str, expected: str):
|
|
35
|
-
dt_value = string_to_datetime(datestr)
|
|
36
|
-
assert dt_value is not None
|
|
37
|
-
actual = datetime_to_string(dt_value)
|
|
38
|
-
assert actual == expected
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
def test_datetime():
|
|
42
|
-
# RFC 3339 with various flavors of tz-offset
|
|
43
|
-
datetime_test('2016-06-20T04:25:16.218Z', '2016-06-20T04:25:16.218000Z')
|
|
44
|
-
datetime_test('2016-06-20T04:25:16.218+0000',
|
|
45
|
-
'2016-06-20T04:25:16.218000Z')
|
|
46
|
-
datetime_test('2016-06-20T04:25:16.218+00', '2016-06-20T04:25:16.218000Z')
|
|
47
|
-
datetime_test('2016-06-20T04:25:16.218-0000',
|
|
48
|
-
'2016-06-20T04:25:16.218000Z')
|
|
49
|
-
datetime_test('2016-06-20T04:25:16.218-00', '2016-06-20T04:25:16.218000Z')
|
|
50
|
-
datetime_test('2016-06-20T00:25:16.218-0400',
|
|
51
|
-
'2016-06-20T04:25:16.218000Z')
|
|
52
|
-
datetime_test('2016-06-20T00:25:16.218-04', '2016-06-20T04:25:16.218000Z')
|
|
53
|
-
datetime_test('2016-06-20T07:25:16.218+0300',
|
|
54
|
-
'2016-06-20T04:25:16.218000Z')
|
|
55
|
-
datetime_test('2016-06-20T07:25:16.218+03', '2016-06-20T04:25:16.218000Z')
|
|
56
|
-
datetime_test('2016-06-20T04:25:16Z', '2016-06-20T04:25:16Z')
|
|
57
|
-
datetime_test('2016-06-20T04:25:16+0000', '2016-06-20T04:25:16Z')
|
|
58
|
-
datetime_test('2016-06-20T04:25:16-0000', '2016-06-20T04:25:16Z')
|
|
59
|
-
datetime_test('2016-06-20T01:25:16-0300', '2016-06-20T04:25:16Z')
|
|
60
|
-
datetime_test('2016-06-20T01:25:16-03:00', '2016-06-20T04:25:16Z')
|
|
61
|
-
datetime_test('2016-06-20T08:55:16+04:30', '2016-06-20T04:25:16Z')
|
|
62
|
-
datetime_test('2016-06-20T16:25:16+12:00', '2016-06-20T04:25:16Z')
|
|
63
|
-
|
|
64
|
-
# RFC 3339 with nanoseconds for the Catalog-Managements of the world.
|
|
65
|
-
datetime_test('2020-03-12T10:52:12.866305005-04:00',
|
|
66
|
-
'2020-03-12T14:52:12.866305Z')
|
|
67
|
-
datetime_test('2020-03-12T10:52:12.866305005Z',
|
|
68
|
-
'2020-03-12T10:52:12.866305Z')
|
|
69
|
-
datetime_test('2020-03-12T10:52:12.866305005+02:30',
|
|
70
|
-
'2020-03-12T08:22:12.866305Z')
|
|
71
|
-
datetime_test('2020-03-12T10:52:12.866305Z', '2020-03-12T10:52:12.866305Z')
|
|
72
|
-
|
|
73
|
-
# UTC datetime with no TZ.
|
|
74
|
-
datetime_test('2016-06-20T04:25:16.218', '2016-06-20T04:25:16.218000Z')
|
|
75
|
-
datetime_test('2016-06-20T04:25:16', '2016-06-20T04:25:16Z')
|
|
76
|
-
|
|
77
|
-
# Dialog datetime.
|
|
78
|
-
datetime_test('2016-06-20 04:25:16', '2016-06-20T04:25:16Z')
|
|
79
|
-
|
|
80
|
-
# IAM Identity Service.
|
|
81
|
-
datetime_test('2020-11-10T12:28+0000', '2020-11-10T12:28:00Z')
|
|
82
|
-
datetime_test('2020-11-10T07:28-0500', '2020-11-10T12:28:00Z')
|
|
83
|
-
datetime_test('2020-11-10T12:28Z', '2020-11-10T12:28:00Z')
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
def test_string_to_datetime():
|
|
87
|
-
# If the specified string does not include a timezone, it is assumed to be UTC
|
|
88
|
-
date = string_to_datetime('2017-03-06 16:00:04.159338')
|
|
89
|
-
assert date.day == 6
|
|
90
|
-
assert date.hour == 16
|
|
91
|
-
assert date.tzinfo.utcoffset(None) == datetime.timezone.utc.utcoffset(None)
|
|
92
|
-
# Test date string with TZ specified as '+xxxx'
|
|
93
|
-
date = string_to_datetime('2017-03-06 16:00:04.159338+0600')
|
|
94
|
-
assert date.day == 6
|
|
95
|
-
assert date.hour == 16
|
|
96
|
-
assert date.tzinfo.utcoffset(None).total_seconds() == 6 * 60 * 60
|
|
97
|
-
# Test date string with TZ specified as 'Z'
|
|
98
|
-
date = string_to_datetime('2017-03-06 16:00:04.159338Z')
|
|
99
|
-
assert date.day == 6
|
|
100
|
-
assert date.hour == 16
|
|
101
|
-
assert date.tzinfo.utcoffset(None) == datetime.timezone.utc.utcoffset(None)
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
def test_datetime_to_string():
|
|
105
|
-
# If specified date is None, return None
|
|
106
|
-
assert datetime_to_string(None) is None
|
|
107
|
-
# If the specified date is "naive", it is interpreted as a UTC date
|
|
108
|
-
date = datetime.datetime(2017, 3, 6, 16, 0, 4, 159338)
|
|
109
|
-
res = datetime_to_string(date)
|
|
110
|
-
assert res == '2017-03-06T16:00:04.159338Z'
|
|
111
|
-
# Test date with UTC timezone
|
|
112
|
-
date = datetime.datetime(2017, 3, 6, 16, 0, 4, 159338,
|
|
113
|
-
datetime.timezone.utc)
|
|
114
|
-
res = datetime_to_string(date)
|
|
115
|
-
assert res == '2017-03-06T16:00:04.159338Z'
|
|
116
|
-
# Test date with non-UTC timezone
|
|
117
|
-
tzn = datetime.timezone(datetime.timedelta(hours=-6))
|
|
118
|
-
date = datetime.datetime(2017, 3, 6, 10, 0, 4, 159338, tzn)
|
|
119
|
-
res = datetime_to_string(date)
|
|
120
|
-
assert res == '2017-03-06T16:00:04.159338Z'
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
def test_string_to_datetime_list():
|
|
124
|
-
# Assert ValueError is raised for invalid argument type
|
|
125
|
-
with pytest.raises(ValueError):
|
|
126
|
-
string_to_datetime_list(None)
|
|
127
|
-
# If the specified string does not include a timezone, it is assumed to be UTC
|
|
128
|
-
date_list = string_to_datetime_list(['2017-03-06 16:00:04.159338'])
|
|
129
|
-
assert date_list[0].day == 6
|
|
130
|
-
assert date_list[0].hour == 16
|
|
131
|
-
assert date_list[0].tzinfo.utcoffset(
|
|
132
|
-
None) == datetime.timezone.utc.utcoffset(None)
|
|
133
|
-
# Test date string with TZ specified as '+xxxx'
|
|
134
|
-
date_list = string_to_datetime_list(['2017-03-06 16:00:04.159338+0600'])
|
|
135
|
-
assert date_list[0].day == 6
|
|
136
|
-
assert date_list[0].hour == 16
|
|
137
|
-
assert date_list[0].tzinfo.utcoffset(None).total_seconds() == 6 * 60 * 60
|
|
138
|
-
# Test date string with TZ specified as 'Z'
|
|
139
|
-
date_list = string_to_datetime_list(['2017-03-06 16:00:04.159338Z'])
|
|
140
|
-
assert date_list[0].day == 6
|
|
141
|
-
assert date_list[0].hour == 16
|
|
142
|
-
assert date_list[0].tzinfo.utcoffset(
|
|
143
|
-
None) == datetime.timezone.utc.utcoffset(None)
|
|
144
|
-
# Test multiple datetimes in a list
|
|
145
|
-
date_list = string_to_datetime_list(
|
|
146
|
-
['2017-03-06 16:00:04.159338', '2017-03-07 17:00:04.159338'])
|
|
147
|
-
assert date_list[0].day == 6
|
|
148
|
-
assert date_list[0].hour == 16
|
|
149
|
-
assert date_list[0].tzinfo.utcoffset(
|
|
150
|
-
None) == datetime.timezone.utc.utcoffset(None)
|
|
151
|
-
assert date_list[1].day == 7
|
|
152
|
-
assert date_list[1].hour == 17
|
|
153
|
-
assert date_list[1].tzinfo.utcoffset(
|
|
154
|
-
None) == datetime.timezone.utc.utcoffset(None)
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
def test_datetime_to_string_list():
|
|
158
|
-
# Assert ValueError is raised for invalid argument type
|
|
159
|
-
with pytest.raises(ValueError):
|
|
160
|
-
datetime_to_string_list(None)
|
|
161
|
-
# If specified datetime list item is None, return list of None
|
|
162
|
-
assert datetime_to_string_list([None]) == [None]
|
|
163
|
-
# If specified datetime list is empty, return empty list
|
|
164
|
-
assert not datetime_to_string_list([])
|
|
165
|
-
# If the specified date list item is "naive", it is interpreted as a UTC date
|
|
166
|
-
date_list = [datetime.datetime(2017, 3, 6, 16, 0, 4, 159338)]
|
|
167
|
-
res = datetime_to_string_list(date_list)
|
|
168
|
-
assert res == ['2017-03-06T16:00:04.159338Z']
|
|
169
|
-
# Test date list item with UTC timezone
|
|
170
|
-
date_list = [datetime.datetime(2017, 3, 6, 16, 0, 4, 159338,
|
|
171
|
-
datetime.timezone.utc)]
|
|
172
|
-
res = datetime_to_string_list(date_list)
|
|
173
|
-
assert res == ['2017-03-06T16:00:04.159338Z']
|
|
174
|
-
# Test date list item with non-UTC timezone
|
|
175
|
-
tzn = datetime.timezone(datetime.timedelta(hours=-6))
|
|
176
|
-
date_list = [datetime.datetime(2017, 3, 6, 10, 0, 4, 159338, tzn)]
|
|
177
|
-
res = datetime_to_string_list(date_list)
|
|
178
|
-
assert res == ['2017-03-06T16:00:04.159338Z']
|
|
179
|
-
# Test specified date list with multiple items
|
|
180
|
-
date_list = [datetime.datetime(2017, 3, 6, 16, 0, 4, 159338),
|
|
181
|
-
datetime.datetime(2017, 3, 6, 16, 0, 4, 159338,
|
|
182
|
-
datetime.timezone.utc)]
|
|
183
|
-
res = datetime_to_string_list(date_list)
|
|
184
|
-
assert res == ['2017-03-06T16:00:04.159338Z',
|
|
185
|
-
'2017-03-06T16:00:04.159338Z']
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
def test_date_conversion():
|
|
189
|
-
date = string_to_date('2017-03-06')
|
|
190
|
-
assert date.day == 6
|
|
191
|
-
res = date_to_string(date)
|
|
192
|
-
assert res == '2017-03-06'
|
|
193
|
-
assert date_to_string(None) is None
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
def test_get_query_param():
|
|
197
|
-
# Relative URL
|
|
198
|
-
next_url = '/api/v1/offerings?start=foo&limit=10'
|
|
199
|
-
page_token = get_query_param(next_url, 'start')
|
|
200
|
-
assert page_token == 'foo'
|
|
201
|
-
# Absolute URL
|
|
202
|
-
next_url = 'https://acme.com/api/v1/offerings?start=bar&limit=10'
|
|
203
|
-
page_token = get_query_param(next_url, 'start')
|
|
204
|
-
assert page_token == 'bar'
|
|
205
|
-
# Missing param
|
|
206
|
-
next_url = 'https://acme.com/api/v1/offerings?start=bar&limit=10'
|
|
207
|
-
page_token = get_query_param(next_url, 'token')
|
|
208
|
-
assert page_token is None
|
|
209
|
-
# No URL
|
|
210
|
-
page_token = get_query_param(None, 'start')
|
|
211
|
-
assert page_token is None
|
|
212
|
-
# Empty URL
|
|
213
|
-
page_token = get_query_param('', 'start')
|
|
214
|
-
assert page_token is None
|
|
215
|
-
# No query string
|
|
216
|
-
next_url = '/api/v1/offerings'
|
|
217
|
-
page_token = get_query_param(next_url, 'start')
|
|
218
|
-
assert page_token is None
|
|
219
|
-
# Bad query string
|
|
220
|
-
next_url = '/api/v1/offerings?start%XXfoo'
|
|
221
|
-
with pytest.raises(ValueError):
|
|
222
|
-
page_token = get_query_param(next_url, 'start')
|
|
223
|
-
# Duplicate param
|
|
224
|
-
next_url = '/api/v1/offerings?start=foo&start=bar&limit=10'
|
|
225
|
-
page_token = get_query_param(next_url, 'start')
|
|
226
|
-
assert page_token == 'foo'
|
|
227
|
-
# Bad URL - since the behavior for this case varies based on the version of Python
|
|
228
|
-
# we allow _either_ a ValueError or that the illegal chars are just ignored
|
|
229
|
-
next_url = 'https://foo.bar\u2100/api/v1/offerings?start=foo'
|
|
230
|
-
try:
|
|
231
|
-
page_token = get_query_param(next_url, 'start')
|
|
232
|
-
assert page_token == 'foo'
|
|
233
|
-
except ValueError:
|
|
234
|
-
# This is okay.
|
|
235
|
-
pass
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
def test_convert_model():
|
|
239
|
-
class MockModel:
|
|
240
|
-
def __init__(self, xyz: Optional[str] = None) -> None:
|
|
241
|
-
self.xyz = xyz
|
|
242
|
-
|
|
243
|
-
def to_dict(self) -> dict:
|
|
244
|
-
_dict = {}
|
|
245
|
-
if hasattr(self, 'xyz') and self.xyz is not None:
|
|
246
|
-
_dict['xyz'] = self.xyz
|
|
247
|
-
return _dict
|
|
248
|
-
|
|
249
|
-
@classmethod
|
|
250
|
-
def from_dict(cls, _dict):
|
|
251
|
-
pass
|
|
252
|
-
|
|
253
|
-
mock1 = MockModel('foo')
|
|
254
|
-
mock1_dict = convert_model(mock1)
|
|
255
|
-
assert mock1_dict == {'xyz': 'foo'}
|
|
256
|
-
|
|
257
|
-
mock2 = {'foo': 'bar', 'baz': 'qux'}
|
|
258
|
-
mock2_dict = convert_model(mock2)
|
|
259
|
-
assert mock2_dict == mock2
|
|
260
|
-
|
|
261
|
-
mock3 = 'this is not a model'
|
|
262
|
-
mock3_dict = convert_model(mock3)
|
|
263
|
-
assert mock3_dict == mock3
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
def test_convert_list():
|
|
267
|
-
temp = ['default', '123']
|
|
268
|
-
res_str = convert_list(temp)
|
|
269
|
-
assert res_str == 'default,123'
|
|
270
|
-
|
|
271
|
-
mock2 = 'default,123'
|
|
272
|
-
mock2_str = convert_list(mock2)
|
|
273
|
-
assert mock2_str == mock2
|
|
274
|
-
|
|
275
|
-
mock3 = {'not': 'a list'}
|
|
276
|
-
mock3_str = convert_list(mock3)
|
|
277
|
-
assert mock3_str == mock3
|
|
278
|
-
|
|
279
|
-
mock4 = ['not', 0, 'list of str']
|
|
280
|
-
mock4_str = convert_list(mock4)
|
|
281
|
-
assert mock4_str == mock4
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
# pylint: disable=too-many-statements
|
|
285
|
-
def test_get_authenticator_from_credential_file():
|
|
286
|
-
file_path = os.path.join(os.path.dirname(__file__),
|
|
287
|
-
'../resources/ibm-credentials-iam.env')
|
|
288
|
-
os.environ['IBM_CREDENTIALS_FILE'] = file_path
|
|
289
|
-
authenticator = get_authenticator_from_environment('ibm watson')
|
|
290
|
-
assert authenticator is not None
|
|
291
|
-
assert authenticator.authentication_type() == Authenticator.AUTHTYPE_IAM
|
|
292
|
-
assert authenticator.token_manager.apikey == '5678efgh'
|
|
293
|
-
assert authenticator.token_manager.url == 'https://iam.cloud.ibm.com'
|
|
294
|
-
assert authenticator.token_manager.client_id is None
|
|
295
|
-
assert authenticator.token_manager.client_secret is None
|
|
296
|
-
assert authenticator.token_manager.disable_ssl_verification is False
|
|
297
|
-
assert authenticator.token_manager.scope is None
|
|
298
|
-
del os.environ['IBM_CREDENTIALS_FILE']
|
|
299
|
-
|
|
300
|
-
file_path = os.path.join(os.path.dirname(__file__),
|
|
301
|
-
'../resources/ibm-credentials-basic.env')
|
|
302
|
-
os.environ['IBM_CREDENTIALS_FILE'] = file_path
|
|
303
|
-
authenticator = get_authenticator_from_environment('watson')
|
|
304
|
-
assert authenticator is not None
|
|
305
|
-
assert authenticator.authentication_type() == Authenticator.AUTHTYPE_BASIC
|
|
306
|
-
assert authenticator.username == 'my_username'
|
|
307
|
-
del os.environ['IBM_CREDENTIALS_FILE']
|
|
308
|
-
|
|
309
|
-
file_path = os.path.join(os.path.dirname(__file__),
|
|
310
|
-
'../resources/ibm-credentials-container.env')
|
|
311
|
-
os.environ['IBM_CREDENTIALS_FILE'] = file_path
|
|
312
|
-
authenticator = get_authenticator_from_environment('service 1')
|
|
313
|
-
assert authenticator is not None
|
|
314
|
-
assert authenticator.authentication_type() == Authenticator.AUTHTYPE_CONTAINER
|
|
315
|
-
assert authenticator.token_manager.cr_token_filename == 'crtoken.txt'
|
|
316
|
-
assert authenticator.token_manager.iam_profile_name == 'iam-user-123'
|
|
317
|
-
assert authenticator.token_manager.iam_profile_id == 'iam-id-123'
|
|
318
|
-
assert authenticator.token_manager.url == 'https://iamhost/iam/api'
|
|
319
|
-
assert authenticator.token_manager.scope == 'scope1'
|
|
320
|
-
assert authenticator.token_manager.client_id == 'iam-client-123'
|
|
321
|
-
assert authenticator.token_manager.client_secret == 'iam-secret-123'
|
|
322
|
-
assert authenticator.token_manager.disable_ssl_verification is True
|
|
323
|
-
|
|
324
|
-
authenticator = get_authenticator_from_environment('service 2')
|
|
325
|
-
assert authenticator is not None
|
|
326
|
-
assert authenticator.authentication_type() == Authenticator.AUTHTYPE_CONTAINER
|
|
327
|
-
assert authenticator.token_manager.cr_token_filename is None
|
|
328
|
-
assert authenticator.token_manager.iam_profile_name == 'iam-user-123'
|
|
329
|
-
assert authenticator.token_manager.iam_profile_id is None
|
|
330
|
-
assert authenticator.token_manager.url == 'https://iam.cloud.ibm.com'
|
|
331
|
-
assert authenticator.token_manager.scope is None
|
|
332
|
-
assert authenticator.token_manager.client_id is None
|
|
333
|
-
assert authenticator.token_manager.client_secret is None
|
|
334
|
-
assert authenticator.token_manager.disable_ssl_verification is False
|
|
335
|
-
del os.environ['IBM_CREDENTIALS_FILE']
|
|
336
|
-
|
|
337
|
-
file_path = os.path.join(os.path.dirname(__file__),
|
|
338
|
-
'../resources/ibm-credentials-cp4d.env')
|
|
339
|
-
os.environ['IBM_CREDENTIALS_FILE'] = file_path
|
|
340
|
-
authenticator = get_authenticator_from_environment('watson')
|
|
341
|
-
assert authenticator is not None
|
|
342
|
-
assert authenticator.authentication_type() == Authenticator.AUTHTYPE_CP4D
|
|
343
|
-
assert authenticator.token_manager.username == 'my_username'
|
|
344
|
-
assert authenticator.token_manager.password == 'my_password'
|
|
345
|
-
assert authenticator.token_manager.url == 'https://my_url/v1/authorize'
|
|
346
|
-
assert authenticator.token_manager.apikey is None
|
|
347
|
-
assert authenticator.token_manager.disable_ssl_verification is False
|
|
348
|
-
del os.environ['IBM_CREDENTIALS_FILE']
|
|
349
|
-
|
|
350
|
-
file_path = os.path.join(os.path.dirname(__file__),
|
|
351
|
-
'../resources/ibm-credentials-no-auth.env')
|
|
352
|
-
os.environ['IBM_CREDENTIALS_FILE'] = file_path
|
|
353
|
-
authenticator = get_authenticator_from_environment('watson')
|
|
354
|
-
assert authenticator is not None
|
|
355
|
-
assert authenticator.authentication_type() == Authenticator.AUTHTYPE_NOAUTH
|
|
356
|
-
del os.environ['IBM_CREDENTIALS_FILE']
|
|
357
|
-
|
|
358
|
-
file_path = os.path.join(os.path.dirname(__file__),
|
|
359
|
-
'../resources/ibm-credentials-bearer.env')
|
|
360
|
-
os.environ['IBM_CREDENTIALS_FILE'] = file_path
|
|
361
|
-
authenticator = get_authenticator_from_environment('watson')
|
|
362
|
-
assert authenticator is not None
|
|
363
|
-
assert authenticator.authentication_type() == Authenticator.AUTHTYPE_BEARERTOKEN
|
|
364
|
-
assert authenticator.bearer_token is not None
|
|
365
|
-
del os.environ['IBM_CREDENTIALS_FILE']
|
|
366
|
-
|
|
367
|
-
file_path = os.path.join(os.path.dirname(__file__),
|
|
368
|
-
'../resources/ibm-credentials.env')
|
|
369
|
-
os.environ['IBM_CREDENTIALS_FILE'] = file_path
|
|
370
|
-
authenticator = get_authenticator_from_environment('service_1')
|
|
371
|
-
assert authenticator is not None
|
|
372
|
-
assert authenticator.authentication_type() == Authenticator.AUTHTYPE_IAM
|
|
373
|
-
assert authenticator.token_manager.apikey == 'V4HXmoUtMjohnsnow=KotN'
|
|
374
|
-
assert authenticator.token_manager.client_id == 'somefake========id'
|
|
375
|
-
assert authenticator.token_manager.client_secret == '==my-client-secret=='
|
|
376
|
-
assert authenticator.token_manager.url == 'https://iamhost/iam/api='
|
|
377
|
-
assert authenticator.token_manager.scope is None
|
|
378
|
-
del os.environ['IBM_CREDENTIALS_FILE']
|
|
379
|
-
|
|
380
|
-
file_path = os.path.join(os.path.dirname(__file__),
|
|
381
|
-
'../resources/ibm-credentials-vpc.env')
|
|
382
|
-
os.environ['IBM_CREDENTIALS_FILE'] = file_path
|
|
383
|
-
authenticator = get_authenticator_from_environment('service1')
|
|
384
|
-
assert authenticator is not None
|
|
385
|
-
assert authenticator.authentication_type() == Authenticator.AUTHTYPE_VPC
|
|
386
|
-
assert authenticator.token_manager.iam_profile_crn is None
|
|
387
|
-
assert authenticator.token_manager.iam_profile_id is None
|
|
388
|
-
assert authenticator.token_manager.url == 'http://169.254.169.254'
|
|
389
|
-
|
|
390
|
-
file_path = os.path.join(os.path.dirname(__file__),
|
|
391
|
-
'../resources/ibm-credentials-vpc.env')
|
|
392
|
-
os.environ['IBM_CREDENTIALS_FILE'] = file_path
|
|
393
|
-
authenticator = get_authenticator_from_environment('service2')
|
|
394
|
-
assert authenticator is not None
|
|
395
|
-
assert authenticator.authentication_type() == Authenticator.AUTHTYPE_VPC
|
|
396
|
-
assert authenticator.token_manager.iam_profile_crn == 'crn:iam-profile1'
|
|
397
|
-
assert authenticator.token_manager.iam_profile_id is None
|
|
398
|
-
assert authenticator.token_manager.url == 'http://vpc.imds.com/api'
|
|
399
|
-
|
|
400
|
-
file_path = os.path.join(os.path.dirname(__file__),
|
|
401
|
-
'../resources/ibm-credentials-vpc.env')
|
|
402
|
-
os.environ['IBM_CREDENTIALS_FILE'] = file_path
|
|
403
|
-
authenticator = get_authenticator_from_environment('service3')
|
|
404
|
-
assert authenticator is not None
|
|
405
|
-
assert authenticator.authentication_type() == Authenticator.AUTHTYPE_VPC
|
|
406
|
-
assert authenticator.token_manager.iam_profile_crn is None
|
|
407
|
-
assert authenticator.token_manager.iam_profile_id == 'iam-profile1-id'
|
|
408
|
-
assert authenticator.token_manager.url == 'http://169.254.169.254'
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
def test_get_authenticator_from_credential_file_scope():
|
|
412
|
-
file_path = os.path.join(os.path.dirname(__file__),
|
|
413
|
-
'../resources/ibm-credentials.env')
|
|
414
|
-
os.environ['IBM_CREDENTIALS_FILE'] = file_path
|
|
415
|
-
authenticator = get_authenticator_from_environment('service_2')
|
|
416
|
-
assert authenticator is not None
|
|
417
|
-
assert authenticator.authentication_type() == Authenticator.AUTHTYPE_IAM
|
|
418
|
-
assert authenticator.token_manager.apikey == 'V4HXmoUtMjohnsnow=KotN'
|
|
419
|
-
assert authenticator.token_manager.client_id == 'somefake========id'
|
|
420
|
-
assert authenticator.token_manager.client_secret == '==my-client-secret=='
|
|
421
|
-
assert authenticator.token_manager.url == 'https://iamhost/iam/api='
|
|
422
|
-
assert authenticator.token_manager.scope == 'A B C D'
|
|
423
|
-
del os.environ['IBM_CREDENTIALS_FILE']
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
def test_get_authenticator_from_env_variables():
|
|
427
|
-
os.environ['TEST_APIKEY'] = '5678efgh'
|
|
428
|
-
authenticator = get_authenticator_from_environment('test')
|
|
429
|
-
assert authenticator is not None
|
|
430
|
-
assert authenticator.authentication_type() == Authenticator.AUTHTYPE_IAM
|
|
431
|
-
assert authenticator.token_manager.apikey == '5678efgh'
|
|
432
|
-
del os.environ['TEST_APIKEY']
|
|
433
|
-
|
|
434
|
-
os.environ['TEST_IAM_PROFILE_ID'] = 'iam-profile-id1'
|
|
435
|
-
authenticator = get_authenticator_from_environment('test')
|
|
436
|
-
assert authenticator is not None
|
|
437
|
-
assert authenticator.authentication_type() == Authenticator.AUTHTYPE_CONTAINER
|
|
438
|
-
assert authenticator.token_manager.iam_profile_id == 'iam-profile-id1'
|
|
439
|
-
del os.environ['TEST_IAM_PROFILE_ID']
|
|
440
|
-
|
|
441
|
-
os.environ['SERVICE_1_APIKEY'] = 'V4HXmoUtMjohnsnow=KotN'
|
|
442
|
-
authenticator = get_authenticator_from_environment('service_1')
|
|
443
|
-
assert authenticator is not None
|
|
444
|
-
assert authenticator.authentication_type() == Authenticator.AUTHTYPE_IAM
|
|
445
|
-
assert authenticator.token_manager.apikey == 'V4HXmoUtMjohnsnow=KotN'
|
|
446
|
-
del os.environ['SERVICE_1_APIKEY']
|
|
447
|
-
|
|
448
|
-
os.environ['SERVICE_2_APIKEY'] = 'johnsnow'
|
|
449
|
-
os.environ['SERVICE_2_SCOPE'] = 'A B C D'
|
|
450
|
-
authenticator = get_authenticator_from_environment('service_2')
|
|
451
|
-
assert authenticator is not None
|
|
452
|
-
assert authenticator.token_manager.apikey == 'johnsnow'
|
|
453
|
-
assert authenticator.token_manager.scope == 'A B C D'
|
|
454
|
-
del os.environ['SERVICE_2_APIKEY']
|
|
455
|
-
del os.environ['SERVICE_2_SCOPE']
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
def test_vcap_credentials():
|
|
459
|
-
vcap_services = '{"test":[{"credentials":{ \
|
|
460
|
-
"url":"https://gateway.watsonplatform.net/compare-comply/api",\
|
|
461
|
-
"username":"bogus username", \
|
|
462
|
-
"password":"bogus password"}}]}'
|
|
463
|
-
|
|
464
|
-
os.environ['VCAP_SERVICES'] = vcap_services
|
|
465
|
-
authenticator = get_authenticator_from_environment('test')
|
|
466
|
-
assert isinstance(authenticator, BasicAuthenticator)
|
|
467
|
-
assert authenticator.authentication_type() == Authenticator.AUTHTYPE_BASIC
|
|
468
|
-
assert authenticator.username == 'bogus username'
|
|
469
|
-
assert authenticator.password == 'bogus password'
|
|
470
|
-
del os.environ['VCAP_SERVICES']
|
|
471
|
-
|
|
472
|
-
vcap_services = '{"test":[{"credentials":{ \
|
|
473
|
-
"url":"https://gateway.watsonplatform.net/compare-comply/api",\
|
|
474
|
-
"apikey":"bogus apikey"}}]}'
|
|
475
|
-
|
|
476
|
-
os.environ['VCAP_SERVICES'] = vcap_services
|
|
477
|
-
authenticator = get_authenticator_from_environment('test')
|
|
478
|
-
assert isinstance(authenticator, IAMAuthenticator)
|
|
479
|
-
assert authenticator.authentication_type() == Authenticator.AUTHTYPE_IAM
|
|
480
|
-
assert authenticator.token_manager.apikey == 'bogus apikey'
|
|
481
|
-
del os.environ['VCAP_SERVICES']
|
|
482
|
-
|
|
483
|
-
vcap_services = '{"test":[{"credentials":{ \
|
|
484
|
-
"url":"https://gateway.watsonplatform.net/compare-comply/api",\
|
|
485
|
-
"iam_apikey":"bogus apikey"}}]}'
|
|
486
|
-
|
|
487
|
-
os.environ['VCAP_SERVICES'] = vcap_services
|
|
488
|
-
authenticator = get_authenticator_from_environment('test')
|
|
489
|
-
assert isinstance(authenticator, IAMAuthenticator)
|
|
490
|
-
assert authenticator.authentication_type() == Authenticator.AUTHTYPE_IAM
|
|
491
|
-
assert authenticator.token_manager.apikey == 'bogus apikey'
|
|
492
|
-
del os.environ['VCAP_SERVICES']
|
|
493
|
-
|
|
494
|
-
vcap_services = '{"test":[{"name": "testname",\
|
|
495
|
-
"credentials":{ \
|
|
496
|
-
"url":"https://gateway.watsonplatform.net/compare-comply/api",\
|
|
497
|
-
"username":"bogus username", \
|
|
498
|
-
"password":"bogus password"}}]}'
|
|
499
|
-
|
|
500
|
-
os.environ['VCAP_SERVICES'] = vcap_services
|
|
501
|
-
authenticator = get_authenticator_from_environment('testname')
|
|
502
|
-
assert isinstance(authenticator, BasicAuthenticator)
|
|
503
|
-
assert authenticator.authentication_type() == Authenticator.AUTHTYPE_BASIC
|
|
504
|
-
assert authenticator.username == 'bogus username'
|
|
505
|
-
assert authenticator.password == 'bogus password'
|
|
506
|
-
del os.environ['VCAP_SERVICES']
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
def test_vcap_credentials_2():
|
|
510
|
-
vcap_services = '{\
|
|
511
|
-
"test":[{"name": "testname",\
|
|
512
|
-
"credentials":{ \
|
|
513
|
-
"url":"https://gateway.watsonplatform.net/compare-comply/api",\
|
|
514
|
-
"username":"bogus username2", \
|
|
515
|
-
"password":"bogus password2"}},\
|
|
516
|
-
{"name": "othertestname",\
|
|
517
|
-
"credentials":{ \
|
|
518
|
-
"url":"https://gateway.watsonplatform.net/compare-comply/api",\
|
|
519
|
-
"username":"bogus username3", \
|
|
520
|
-
"password":"bogus password3"}}],\
|
|
521
|
-
"testname":[{"name": "nottestname",\
|
|
522
|
-
"credentials":{ \
|
|
523
|
-
"url":"https://gateway.watsonplatform.net/compare-comply/api",\
|
|
524
|
-
"username":"bogus username", \
|
|
525
|
-
"password":"bogus password"}}],\
|
|
526
|
-
"equals_sign_test":[{"name": "equals_sign_test",\
|
|
527
|
-
"credentials":{ \
|
|
528
|
-
"iam_apikey": "V4HXmoUtMjohnsnow=KotN",\
|
|
529
|
-
"iam_apikey_description": "Auto generated apikey...",\
|
|
530
|
-
"iam_apikey_name": "auto-generated-apikey-111-222-333",\
|
|
531
|
-
"iam_role_crn": "crn:v1:bluemix:public:iam::::serviceRole:Manager",\
|
|
532
|
-
"iam_serviceid_crn": "crn:v1:staging:public:iam-identity::a/::serviceid:ServiceID-1234",\
|
|
533
|
-
"url": "https://gateway.watsonplatform.net/testService",\
|
|
534
|
-
"auth_url": "https://iamhost/iam/api="}}]}'
|
|
535
|
-
|
|
536
|
-
os.environ['VCAP_SERVICES'] = vcap_services
|
|
537
|
-
authenticator = get_authenticator_from_environment('testname')
|
|
538
|
-
assert isinstance(authenticator, BasicAuthenticator)
|
|
539
|
-
assert authenticator.username == 'bogus username2'
|
|
540
|
-
assert authenticator.password == 'bogus password2'
|
|
541
|
-
|
|
542
|
-
authenticator = get_authenticator_from_environment('equals_sign_test')
|
|
543
|
-
assert isinstance(authenticator, IAMAuthenticator)
|
|
544
|
-
assert authenticator.token_manager.apikey == 'V4HXmoUtMjohnsnow=KotN'
|
|
545
|
-
del os.environ['VCAP_SERVICES']
|
|
546
|
-
|
|
547
|
-
vcap_services = '{"test":[{\
|
|
548
|
-
"credentials":{ \
|
|
549
|
-
"url":"https://gateway.watsonplatform.net/compare-comply/api",\
|
|
550
|
-
"username":"bogus username", \
|
|
551
|
-
"password":"bogus password"}},\
|
|
552
|
-
{"credentials":{ \
|
|
553
|
-
"url":"https://gateway.watsonplatform.net/compare-comply/api",\
|
|
554
|
-
"username":"bogus username2", \
|
|
555
|
-
"password":"bogus password2"}}\
|
|
556
|
-
]}'
|
|
557
|
-
|
|
558
|
-
os.environ['VCAP_SERVICES'] = vcap_services
|
|
559
|
-
authenticator = get_authenticator_from_environment('test')
|
|
560
|
-
assert isinstance(authenticator, BasicAuthenticator)
|
|
561
|
-
assert authenticator.username == 'bogus username'
|
|
562
|
-
assert authenticator.password == 'bogus password'
|
|
563
|
-
del os.environ['VCAP_SERVICES']
|
|
564
|
-
|
|
565
|
-
vcap_services = '{"first":[],\
|
|
566
|
-
"test":[{"credentials":{ \
|
|
567
|
-
"url":"https://gateway.watsonplatform.net/compare-comply/api",\
|
|
568
|
-
"username":"bogus username", \
|
|
569
|
-
"password":"bogus password"}}],\
|
|
570
|
-
"last":[]}'
|
|
571
|
-
|
|
572
|
-
os.environ['VCAP_SERVICES'] = vcap_services
|
|
573
|
-
authenticator = get_authenticator_from_environment('test')
|
|
574
|
-
assert isinstance(authenticator, BasicAuthenticator)
|
|
575
|
-
assert authenticator.username == 'bogus username'
|
|
576
|
-
assert authenticator.password == 'bogus password'
|
|
577
|
-
del os.environ['VCAP_SERVICES']
|
|
578
|
-
|
|
579
|
-
vcap_services = '{"test":[],\
|
|
580
|
-
"last":[]}'
|
|
581
|
-
|
|
582
|
-
os.environ['VCAP_SERVICES'] = vcap_services
|
|
583
|
-
authenticator = get_authenticator_from_environment('test')
|
|
584
|
-
assert authenticator is None
|
|
585
|
-
del os.environ['VCAP_SERVICES']
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
def test_multi_word_service_name():
|
|
589
|
-
os.environ['PERSONALITY_INSIGHTS_APIKEY'] = '5678efgh'
|
|
590
|
-
authenticator = get_authenticator_from_environment('personality-insights')
|
|
591
|
-
assert authenticator is not None
|
|
592
|
-
assert authenticator.authentication_type() == Authenticator.AUTHTYPE_IAM
|
|
593
|
-
assert authenticator.token_manager.apikey == '5678efgh'
|
|
594
|
-
del os.environ['PERSONALITY_INSIGHTS_APIKEY']
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
def test_read_external_sources_1():
|
|
598
|
-
# Set IBM_CREDENTIALS_FILE to a non-existent file (should be silently ignored).
|
|
599
|
-
bad_file_path = os.path.join(os.path.dirname(__file__), 'NOT_A_FILE')
|
|
600
|
-
os.environ['IBM_CREDENTIALS_FILE'] = bad_file_path
|
|
601
|
-
|
|
602
|
-
# This env var should take precendence since the config file wasn't found.
|
|
603
|
-
os.environ['SERVICE_1_URL'] = 'https://good-url.com'
|
|
604
|
-
|
|
605
|
-
config = read_external_sources('service_1')
|
|
606
|
-
assert config.get('URL') == 'https://good-url.com'
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
def test_read_external_sources_2():
|
|
610
|
-
# The config file should take precedence over the env variable.
|
|
611
|
-
config_file = os.path.join(os.path.dirname(__file__),
|
|
612
|
-
'../resources/ibm-credentials.env')
|
|
613
|
-
os.environ['IBM_CREDENTIALS_FILE'] = config_file
|
|
614
|
-
|
|
615
|
-
# This should be ignored since IBM_CREDENTIALS_FILE points to a valid file.
|
|
616
|
-
os.environ['SERVICE_1_URL'] = 'wrong-url'
|
|
617
|
-
|
|
618
|
-
config = read_external_sources('service_1')
|
|
619
|
-
assert config.get('URL') == 'service1.com/api'
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
def test_strip_extra_slashes():
|
|
623
|
-
assert strip_extra_slashes('') == ''
|
|
624
|
-
assert strip_extra_slashes('//') == '/'
|
|
625
|
-
assert strip_extra_slashes('/////') == '/'
|
|
626
|
-
assert strip_extra_slashes('https://host') == 'https://host'
|
|
627
|
-
assert strip_extra_slashes('https://host/') == 'https://host/'
|
|
628
|
-
assert strip_extra_slashes('https://host//') == 'https://host/'
|
|
629
|
-
assert strip_extra_slashes('https://host/path') == 'https://host/path'
|
|
630
|
-
assert strip_extra_slashes('https://host/path/') == 'https://host/path/'
|
|
631
|
-
assert strip_extra_slashes('https://host/path//') == 'https://host/path/'
|
|
632
|
-
assert strip_extra_slashes('https://host//path//') == 'https://host//path/'
|
|
633
|
-
assert strip_extra_slashes(
|
|
634
|
-
'https://host//path//////////') == 'https://host//path/'
|