ibm-cloud-sdk-core 3.16.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 +2 -1
- 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 +33 -21
- 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 +107 -91
- 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 +30 -22
- 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 +121 -46
- ibm_cloud_sdk_core/version.py +1 -1
- {ibm_cloud_sdk_core-3.16.0.dist-info → ibm_cloud_sdk_core-3.20.6.dist-info}/METADATA +40 -28
- ibm_cloud_sdk_core-3.20.6.dist-info/RECORD +34 -0
- {ibm_cloud_sdk_core-3.16.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.16.0.dist-info/RECORD +0 -52
- ibm_cloud_sdk_core-3.16.0.dist-info/top_level.txt +0 -3
- ibm_cloud_sdk_core-3.16.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 -933
- 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.16.0.dist-info → ibm_cloud_sdk_core-3.20.6.dist-info}/LICENSE +0 -0
ibm_cloud_sdk_core/__init__.py
CHANGED
|
@@ -43,6 +43,7 @@ from .token_managers.jwt_token_manager import JWTTokenManager
|
|
|
43
43
|
from .token_managers.cp4d_token_manager import CP4DTokenManager
|
|
44
44
|
from .token_managers.container_token_manager import ContainerTokenManager
|
|
45
45
|
from .token_managers.vpc_instance_token_manager import VPCInstanceTokenManager
|
|
46
|
+
from .token_managers.mcsp_token_manager import MCSPTokenManager
|
|
46
47
|
from .api_exception import ApiException
|
|
47
48
|
from .utils import datetime_to_string, string_to_datetime, read_external_sources
|
|
48
49
|
from .utils import datetime_to_string_list, string_to_datetime_list
|
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
# See the License for the specific language governing permissions and
|
|
15
15
|
# limitations under the License.
|
|
16
16
|
|
|
17
|
+
import warnings
|
|
17
18
|
from http import HTTPStatus
|
|
18
19
|
from typing import Optional
|
|
19
20
|
|
|
@@ -39,24 +40,37 @@ class ApiException(Exception):
|
|
|
39
40
|
# Call the base class constructor with the parameters it needs
|
|
40
41
|
super().__init__(message)
|
|
41
42
|
self.message = message
|
|
42
|
-
self.
|
|
43
|
+
self.status_code = code
|
|
43
44
|
self.http_response = http_response
|
|
44
45
|
self.global_transaction_id = None
|
|
45
46
|
if http_response is not None:
|
|
46
47
|
self.global_transaction_id = http_response.headers.get('X-Global-Transaction-ID')
|
|
47
48
|
self.message = self.message if self.message else self._get_error_message(http_response)
|
|
48
49
|
|
|
50
|
+
# pylint: disable=fixme
|
|
51
|
+
# TODO: delete this by the end of 2024.
|
|
52
|
+
@property
|
|
53
|
+
def code(self):
|
|
54
|
+
"""The old `code` property with a deprecation warning."""
|
|
55
|
+
|
|
56
|
+
warnings.warn(
|
|
57
|
+
'Using the `code` attribute on the `ApiException` is deprecated and '
|
|
58
|
+
'will be removed in the future. Use `status_code` instead.',
|
|
59
|
+
DeprecationWarning,
|
|
60
|
+
)
|
|
61
|
+
return self.status_code
|
|
62
|
+
|
|
49
63
|
def __str__(self) -> str:
|
|
50
|
-
msg = 'Error: ' + str(self.message) + ',
|
|
64
|
+
msg = 'Error: ' + str(self.message) + ', Status code: ' + str(self.status_code)
|
|
51
65
|
if self.global_transaction_id is not None:
|
|
52
66
|
msg += ' , X-global-transaction-id: ' + str(self.global_transaction_id)
|
|
53
|
-
return
|
|
67
|
+
return msg
|
|
54
68
|
|
|
55
69
|
@staticmethod
|
|
56
70
|
def _get_error_message(response: Response) -> str:
|
|
57
71
|
error_message = 'Unknown error'
|
|
58
72
|
try:
|
|
59
|
-
error_json = response.json()
|
|
73
|
+
error_json = response.json(strict=False)
|
|
60
74
|
if 'errors' in error_json:
|
|
61
75
|
if isinstance(error_json['errors'], list):
|
|
62
76
|
err = error_json['errors'][0]
|
|
@@ -41,3 +41,4 @@ from .cp4d_authenticator import CloudPakForDataAuthenticator
|
|
|
41
41
|
from .iam_authenticator import IAMAuthenticator
|
|
42
42
|
from .vpc_instance_authenticator import VPCInstanceAuthenticator
|
|
43
43
|
from .no_auth_authenticator import NoAuthAuthenticator
|
|
44
|
+
from .mcsp_authenticator import MCSPAuthenticator
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# coding: utf-8
|
|
2
2
|
|
|
3
|
-
# Copyright 2019 IBM All Rights Reserved.
|
|
3
|
+
# Copyright 2019, 2023 IBM All Rights Reserved.
|
|
4
4
|
#
|
|
5
5
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
6
|
# you may not use this file except in compliance with the License.
|
|
@@ -28,6 +28,7 @@ class Authenticator(ABC):
|
|
|
28
28
|
AUTHTYPE_CP4D = 'cp4d'
|
|
29
29
|
AUTHTYPE_VPC = 'vpc'
|
|
30
30
|
AUTHTYPE_NOAUTH = 'noAuth'
|
|
31
|
+
AUTHTYPE_MCSP = 'mcsp'
|
|
31
32
|
AUTHTYPE_UNKNOWN = 'unknown'
|
|
32
33
|
|
|
33
34
|
@abstractmethod
|
|
@@ -57,16 +57,15 @@ class BasicAuthenticator(Authenticator):
|
|
|
57
57
|
if self.username is None or self.password is None:
|
|
58
58
|
raise ValueError('The username and password shouldn\'t be None.')
|
|
59
59
|
|
|
60
|
-
if has_bad_first_or_last_char(
|
|
61
|
-
self.username) or has_bad_first_or_last_char(self.password):
|
|
60
|
+
if has_bad_first_or_last_char(self.username) or has_bad_first_or_last_char(self.password):
|
|
62
61
|
raise ValueError(
|
|
63
62
|
'The username and password shouldn\'t start or end with curly brackets or quotes. '
|
|
64
|
-
'Please remove any surrounding {, }, or \" characters.'
|
|
63
|
+
'Please remove any surrounding {, }, or \" characters.'
|
|
64
|
+
)
|
|
65
65
|
|
|
66
66
|
def __construct_basic_auth_header(self) -> str:
|
|
67
67
|
authstring = "{0}:{1}".format(self.username, self.password)
|
|
68
|
-
base64_authorization = base64.b64encode(
|
|
69
|
-
authstring.encode('utf-8')).decode('utf-8')
|
|
68
|
+
base64_authorization = base64.b64encode(authstring.encode('utf-8')).decode('utf-8')
|
|
70
69
|
return 'Basic {0}'.format(base64_authorization)
|
|
71
70
|
|
|
72
71
|
def authenticate(self, req: Request) -> None:
|
|
@@ -77,7 +76,7 @@ class BasicAuthenticator(Authenticator):
|
|
|
77
76
|
Authorization: Basic <encoded username and password>
|
|
78
77
|
|
|
79
78
|
Args:
|
|
80
|
-
req: The request to add basic auth information
|
|
79
|
+
req: The request to add basic auth information to. Must contain a key to a dictionary
|
|
81
80
|
called headers.
|
|
82
81
|
"""
|
|
83
82
|
headers = req.get('headers')
|
|
@@ -61,7 +61,7 @@ class BearerTokenAuthenticator(Authenticator):
|
|
|
61
61
|
Authorization: Bearer <bearer-token>
|
|
62
62
|
|
|
63
63
|
Args:
|
|
64
|
-
req: The request to add bearer authentication information
|
|
64
|
+
req: The request to add bearer authentication information to. Must contain a key to a dictionary
|
|
65
65
|
called headers.
|
|
66
66
|
"""
|
|
67
67
|
headers = req.get('headers')
|
|
@@ -64,25 +64,35 @@ class ContainerAuthenticator(IAMRequestBasedAuthenticator):
|
|
|
64
64
|
or client_id, and/or client_secret are not valid for IAM token requests.
|
|
65
65
|
"""
|
|
66
66
|
|
|
67
|
-
def __init__(
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
67
|
+
def __init__(
|
|
68
|
+
self,
|
|
69
|
+
cr_token_filename: Optional[str] = None,
|
|
70
|
+
iam_profile_name: Optional[str] = None,
|
|
71
|
+
iam_profile_id: Optional[str] = None,
|
|
72
|
+
url: Optional[str] = None,
|
|
73
|
+
client_id: Optional[str] = None,
|
|
74
|
+
client_secret: Optional[str] = None,
|
|
75
|
+
disable_ssl_verification: bool = False,
|
|
76
|
+
scope: Optional[str] = None,
|
|
77
|
+
proxies: Optional[Dict[str, str]] = None,
|
|
78
|
+
headers: Optional[Dict[str, str]] = None,
|
|
79
|
+
) -> None:
|
|
78
80
|
# Check the type of `disable_ssl_verification`. Must be a bool.
|
|
79
81
|
if not isinstance(disable_ssl_verification, bool):
|
|
80
82
|
raise TypeError('disable_ssl_verification must be a bool')
|
|
81
83
|
|
|
82
84
|
self.token_manager = ContainerTokenManager(
|
|
83
|
-
cr_token_filename=cr_token_filename,
|
|
84
|
-
|
|
85
|
-
|
|
85
|
+
cr_token_filename=cr_token_filename,
|
|
86
|
+
iam_profile_name=iam_profile_name,
|
|
87
|
+
iam_profile_id=iam_profile_id,
|
|
88
|
+
url=url,
|
|
89
|
+
client_id=client_id,
|
|
90
|
+
client_secret=client_secret,
|
|
91
|
+
disable_ssl_verification=disable_ssl_verification,
|
|
92
|
+
scope=scope,
|
|
93
|
+
proxies=proxies,
|
|
94
|
+
headers=headers,
|
|
95
|
+
)
|
|
86
96
|
|
|
87
97
|
self.validate()
|
|
88
98
|
|
|
@@ -103,8 +113,7 @@ class ContainerAuthenticator(IAMRequestBasedAuthenticator):
|
|
|
103
113
|
super().validate()
|
|
104
114
|
|
|
105
115
|
if not self.token_manager.iam_profile_name and not self.token_manager.iam_profile_id:
|
|
106
|
-
raise ValueError(
|
|
107
|
-
'At least one of iam_profile_name or iam_profile_id must be specified.')
|
|
116
|
+
raise ValueError('At least one of iam_profile_name or iam_profile_id must be specified.')
|
|
108
117
|
|
|
109
118
|
def set_cr_token_filename(self, cr_token_filename: str) -> None:
|
|
110
119
|
"""Set the location of the compute resource token on the local filesystem.
|
|
@@ -52,23 +52,32 @@ class CloudPakForDataAuthenticator(Authenticator):
|
|
|
52
52
|
ValueError: The username, password/apikey, and/or url are not valid for CP4D token requests.
|
|
53
53
|
"""
|
|
54
54
|
|
|
55
|
-
def __init__(
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
55
|
+
def __init__(
|
|
56
|
+
self,
|
|
57
|
+
username: str = None,
|
|
58
|
+
password: str = None,
|
|
59
|
+
url: str = None,
|
|
60
|
+
*,
|
|
61
|
+
apikey: str = None,
|
|
62
|
+
disable_ssl_verification: bool = False,
|
|
63
|
+
headers: Optional[Dict[str, str]] = None,
|
|
64
|
+
proxies: Optional[Dict[str, str]] = None,
|
|
65
|
+
verify: Optional[str] = None,
|
|
66
|
+
) -> None:
|
|
65
67
|
# Check the type of `disable_ssl_verification`. Must be a bool.
|
|
66
68
|
if not isinstance(disable_ssl_verification, bool):
|
|
67
69
|
raise TypeError('disable_ssl_verification must be a bool')
|
|
68
70
|
|
|
69
71
|
self.token_manager = CP4DTokenManager(
|
|
70
|
-
username=username,
|
|
71
|
-
|
|
72
|
+
username=username,
|
|
73
|
+
password=password,
|
|
74
|
+
apikey=apikey,
|
|
75
|
+
url=url,
|
|
76
|
+
disable_ssl_verification=disable_ssl_verification,
|
|
77
|
+
headers=headers,
|
|
78
|
+
proxies=proxies,
|
|
79
|
+
verify=verify,
|
|
80
|
+
)
|
|
72
81
|
|
|
73
82
|
self.validate()
|
|
74
83
|
|
|
@@ -88,24 +97,27 @@ class CloudPakForDataAuthenticator(Authenticator):
|
|
|
88
97
|
if self.token_manager.username is None:
|
|
89
98
|
raise ValueError('The username shouldn\'t be None.')
|
|
90
99
|
|
|
91
|
-
if (
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
100
|
+
if (self.token_manager.password is None and self.token_manager.apikey is None) or (
|
|
101
|
+
self.token_manager.password is not None and self.token_manager.apikey is not None
|
|
102
|
+
):
|
|
103
|
+
raise ValueError('Exactly one of `apikey` or `password` must be specified.')
|
|
95
104
|
|
|
96
105
|
if self.token_manager.url is None:
|
|
97
106
|
raise ValueError('The url shouldn\'t be None.')
|
|
98
107
|
|
|
99
|
-
if has_bad_first_or_last_char(
|
|
100
|
-
|
|
108
|
+
if has_bad_first_or_last_char(self.token_manager.username) or has_bad_first_or_last_char(
|
|
109
|
+
self.token_manager.password
|
|
110
|
+
):
|
|
101
111
|
raise ValueError(
|
|
102
112
|
'The username and password shouldn\'t start or end with curly brackets or quotes. '
|
|
103
|
-
'Please remove any surrounding {, }, or \" characters.'
|
|
113
|
+
'Please remove any surrounding {, }, or \" characters.'
|
|
114
|
+
)
|
|
104
115
|
|
|
105
116
|
if has_bad_first_or_last_char(self.token_manager.url):
|
|
106
117
|
raise ValueError(
|
|
107
118
|
'The url shouldn\'t start or end with curly brackets or quotes. '
|
|
108
|
-
'Please remove any surrounding {, }, or \" characters.'
|
|
119
|
+
'Please remove any surrounding {, }, or \" characters.'
|
|
120
|
+
)
|
|
109
121
|
|
|
110
122
|
def authenticate(self, req: Request) -> None:
|
|
111
123
|
"""Adds CP4D authentication information to the request.
|
|
@@ -115,7 +127,7 @@ class CloudPakForDataAuthenticator(Authenticator):
|
|
|
115
127
|
Authorization: Bearer <bearer-token>
|
|
116
128
|
|
|
117
129
|
Args:
|
|
118
|
-
req: The request to add CP4D authentication information
|
|
130
|
+
req: The request to add CP4D authentication information to. Must contain a key to a dictionary
|
|
119
131
|
called headers.
|
|
120
132
|
"""
|
|
121
133
|
headers = req.get('headers')
|
|
@@ -56,24 +56,32 @@ class IAMAuthenticator(IAMRequestBasedAuthenticator):
|
|
|
56
56
|
ValueError: The apikey, client_id, and/or client_secret are not valid for IAM token requests.
|
|
57
57
|
"""
|
|
58
58
|
|
|
59
|
-
def __init__(
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
59
|
+
def __init__(
|
|
60
|
+
self,
|
|
61
|
+
apikey: str,
|
|
62
|
+
*,
|
|
63
|
+
url: Optional[str] = None,
|
|
64
|
+
client_id: Optional[str] = None,
|
|
65
|
+
client_secret: Optional[str] = None,
|
|
66
|
+
disable_ssl_verification: bool = False,
|
|
67
|
+
headers: Optional[Dict[str, str]] = None,
|
|
68
|
+
proxies: Optional[Dict[str, str]] = None,
|
|
69
|
+
scope: Optional[str] = None,
|
|
70
|
+
) -> None:
|
|
69
71
|
# Check the type of `disable_ssl_verification`. Must be a bool.
|
|
70
72
|
if not isinstance(disable_ssl_verification, bool):
|
|
71
73
|
raise TypeError('disable_ssl_verification must be a bool')
|
|
72
74
|
|
|
73
75
|
self.token_manager = IAMTokenManager(
|
|
74
|
-
apikey,
|
|
76
|
+
apikey,
|
|
77
|
+
url=url,
|
|
78
|
+
client_id=client_id,
|
|
79
|
+
client_secret=client_secret,
|
|
75
80
|
disable_ssl_verification=disable_ssl_verification,
|
|
76
|
-
headers=headers,
|
|
81
|
+
headers=headers,
|
|
82
|
+
proxies=proxies,
|
|
83
|
+
scope=scope,
|
|
84
|
+
)
|
|
77
85
|
|
|
78
86
|
self.validate()
|
|
79
87
|
|
|
@@ -98,4 +106,5 @@ class IAMAuthenticator(IAMRequestBasedAuthenticator):
|
|
|
98
106
|
if has_bad_first_or_last_char(self.token_manager.apikey):
|
|
99
107
|
raise ValueError(
|
|
100
108
|
'The apikey shouldn\'t start or end with curly brackets or quotes. '
|
|
101
|
-
'Please remove any surrounding {, }, or \" characters.'
|
|
109
|
+
'Please remove any surrounding {, }, or \" characters.'
|
|
110
|
+
)
|
|
@@ -41,12 +41,10 @@ class IAMRequestBasedAuthenticator(Authenticator):
|
|
|
41
41
|
Raises:
|
|
42
42
|
ValueError: The client_id, and/or client_secret are not valid for IAM token requests.
|
|
43
43
|
"""
|
|
44
|
-
if (self.token_manager.client_id and
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
raise ValueError(
|
|
49
|
-
'Both client_id and client_secret should be initialized.')
|
|
44
|
+
if (self.token_manager.client_id and not self.token_manager.client_secret) or (
|
|
45
|
+
not self.token_manager.client_id and self.token_manager.client_secret
|
|
46
|
+
):
|
|
47
|
+
raise ValueError('Both client_id and client_secret should be initialized.')
|
|
50
48
|
|
|
51
49
|
def authenticate(self, req: Request) -> None:
|
|
52
50
|
"""Adds IAM authentication information to the request.
|
|
@@ -56,7 +54,7 @@ class IAMRequestBasedAuthenticator(Authenticator):
|
|
|
56
54
|
Authorization: Bearer <bearer-token>
|
|
57
55
|
|
|
58
56
|
Args:
|
|
59
|
-
req: The request to add IAM authentication information
|
|
57
|
+
req: The request to add IAM authentication information to. Must contain a key to a dictionary
|
|
60
58
|
called headers.
|
|
61
59
|
"""
|
|
62
60
|
headers = req.get('headers')
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
# coding: utf-8
|
|
2
|
+
|
|
3
|
+
# Copyright 2023 IBM All Rights Reserved.
|
|
4
|
+
#
|
|
5
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
# you may not use this file except in compliance with the License.
|
|
7
|
+
# You may obtain a copy of the License at
|
|
8
|
+
#
|
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
#
|
|
11
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
# See the License for the specific language governing permissions and
|
|
15
|
+
# limitations under the License.
|
|
16
|
+
|
|
17
|
+
from typing import Dict, Optional
|
|
18
|
+
|
|
19
|
+
from requests import Request
|
|
20
|
+
|
|
21
|
+
from .authenticator import Authenticator
|
|
22
|
+
from ..token_managers.mcsp_token_manager import MCSPTokenManager
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class MCSPAuthenticator(Authenticator):
|
|
26
|
+
"""The MCSPAuthenticator uses an apikey to obtain an access token from the MCSP token server.
|
|
27
|
+
When the access token expires, a new access token is obtained from the token server.
|
|
28
|
+
The access token will be added to outbound requests via the Authorization header
|
|
29
|
+
of the form: "Authorization: Bearer <access-token>"
|
|
30
|
+
|
|
31
|
+
Keyword Args:
|
|
32
|
+
url: The base endpoint URL for the MCSP token service [required].
|
|
33
|
+
apikey: The API key used to obtain an access token [required].
|
|
34
|
+
disable_ssl_verification: A flag that indicates whether verification of the server's SSL
|
|
35
|
+
certificate should be disabled or not. Defaults to False.
|
|
36
|
+
headers: Default headers to be sent with every MCSP token request. Defaults to None.
|
|
37
|
+
proxies: Dictionary for mapping request protocol to proxy URL.
|
|
38
|
+
proxies.http (optional): The proxy endpoint to use for HTTP requests.
|
|
39
|
+
proxies.https (optional): The proxy endpoint to use for HTTPS requests.
|
|
40
|
+
|
|
41
|
+
Attributes:
|
|
42
|
+
token_manager (MCSPTokenManager): Retrieves and manages MCSP tokens from the endpoint specified by the url.
|
|
43
|
+
|
|
44
|
+
Raises:
|
|
45
|
+
TypeError: The `disable_ssl_verification` is not a bool.
|
|
46
|
+
ValueError: The apikey and/or url are not valid for MCSP token exchange requests.
|
|
47
|
+
"""
|
|
48
|
+
|
|
49
|
+
def __init__(
|
|
50
|
+
self,
|
|
51
|
+
apikey: str,
|
|
52
|
+
url: str,
|
|
53
|
+
*,
|
|
54
|
+
disable_ssl_verification: bool = False,
|
|
55
|
+
headers: Optional[Dict[str, str]] = None,
|
|
56
|
+
proxies: Optional[Dict[str, str]] = None,
|
|
57
|
+
) -> None:
|
|
58
|
+
# Check the type of `disable_ssl_verification`. Must be a bool.
|
|
59
|
+
if not isinstance(disable_ssl_verification, bool):
|
|
60
|
+
raise TypeError('disable_ssl_verification must be a bool')
|
|
61
|
+
|
|
62
|
+
self.token_manager = MCSPTokenManager(
|
|
63
|
+
apikey=apikey,
|
|
64
|
+
url=url,
|
|
65
|
+
disable_ssl_verification=disable_ssl_verification,
|
|
66
|
+
headers=headers,
|
|
67
|
+
proxies=proxies,
|
|
68
|
+
)
|
|
69
|
+
|
|
70
|
+
self.validate()
|
|
71
|
+
|
|
72
|
+
def authentication_type(self) -> str:
|
|
73
|
+
"""Returns this authenticator's type ('mcsp')."""
|
|
74
|
+
return Authenticator.AUTHTYPE_MCSP
|
|
75
|
+
|
|
76
|
+
def validate(self) -> None:
|
|
77
|
+
"""Validate apikey and url for token requests.
|
|
78
|
+
|
|
79
|
+
Raises:
|
|
80
|
+
ValueError: The apikey and/or url are not valid for token requests.
|
|
81
|
+
"""
|
|
82
|
+
if self.token_manager.apikey is None:
|
|
83
|
+
raise ValueError('The apikey shouldn\'t be None.')
|
|
84
|
+
|
|
85
|
+
if self.token_manager.url is None:
|
|
86
|
+
raise ValueError('The url shouldn\'t be None.')
|
|
87
|
+
|
|
88
|
+
def authenticate(self, req: Request) -> None:
|
|
89
|
+
"""Adds MCSP authentication information to the request.
|
|
90
|
+
|
|
91
|
+
The MCSP bearer token will be added to the request's headers in the form:
|
|
92
|
+
Authorization: Bearer <bearer-token>
|
|
93
|
+
|
|
94
|
+
Args:
|
|
95
|
+
req: The request to add MCSP authentication information to. Must contain a key to a dictionary
|
|
96
|
+
called headers.
|
|
97
|
+
"""
|
|
98
|
+
headers = req.get('headers')
|
|
99
|
+
bearer_token = self.token_manager.get_token()
|
|
100
|
+
headers['Authorization'] = 'Bearer {0}'.format(bearer_token)
|
|
101
|
+
|
|
102
|
+
def set_disable_ssl_verification(self, status: bool = False) -> None:
|
|
103
|
+
"""Set the flag that indicates whether verification of the server's SSL certificate should be
|
|
104
|
+
disabled or not. Defaults to False.
|
|
105
|
+
|
|
106
|
+
Args:
|
|
107
|
+
status: Set to true in order to disable SSL certificate verification. Defaults to False.
|
|
108
|
+
|
|
109
|
+
Raises:
|
|
110
|
+
TypeError: The `status` is not a bool.
|
|
111
|
+
"""
|
|
112
|
+
self.token_manager.set_disable_ssl_verification(status)
|
|
113
|
+
|
|
114
|
+
def set_headers(self, headers: Dict[str, str]) -> None:
|
|
115
|
+
"""Default headers to be sent with every MCSP token request.
|
|
116
|
+
|
|
117
|
+
Args:
|
|
118
|
+
headers: The headers to be sent with every MCSP token request.
|
|
119
|
+
"""
|
|
120
|
+
self.token_manager.set_headers(headers)
|
|
121
|
+
|
|
122
|
+
def set_proxies(self, proxies: Dict[str, str]) -> None:
|
|
123
|
+
"""Sets the proxies the token manager will use to communicate with MCSP on behalf of the host.
|
|
124
|
+
|
|
125
|
+
Args:
|
|
126
|
+
proxies: Dictionary for mapping request protocol to proxy URL.
|
|
127
|
+
proxies.http (optional): The proxy endpoint to use for HTTP requests.
|
|
128
|
+
proxies.https (optional): The proxy endpoint to use for HTTPS requests.
|
|
129
|
+
"""
|
|
130
|
+
self.token_manager.set_proxies(proxies)
|
|
@@ -53,16 +53,15 @@ class VPCInstanceAuthenticator(Authenticator):
|
|
|
53
53
|
|
|
54
54
|
DEFAULT_IMS_ENDPOINT = 'http://169.254.169.254'
|
|
55
55
|
|
|
56
|
-
def __init__(
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
url: Optional[str] = None) -> None:
|
|
60
|
-
|
|
56
|
+
def __init__(
|
|
57
|
+
self, iam_profile_crn: Optional[str] = None, iam_profile_id: Optional[str] = None, url: Optional[str] = None
|
|
58
|
+
) -> None:
|
|
61
59
|
if not url:
|
|
62
60
|
url = self.DEFAULT_IMS_ENDPOINT
|
|
63
61
|
|
|
64
62
|
self.token_manager = VPCInstanceTokenManager(
|
|
65
|
-
url=url, iam_profile_crn=iam_profile_crn, iam_profile_id=iam_profile_id
|
|
63
|
+
url=url, iam_profile_crn=iam_profile_crn, iam_profile_id=iam_profile_id
|
|
64
|
+
)
|
|
66
65
|
|
|
67
66
|
self.validate()
|
|
68
67
|
|
|
@@ -74,8 +73,7 @@ class VPCInstanceAuthenticator(Authenticator):
|
|
|
74
73
|
super().validate()
|
|
75
74
|
|
|
76
75
|
if self.token_manager.iam_profile_crn and self.token_manager.iam_profile_id:
|
|
77
|
-
raise ValueError(
|
|
78
|
-
'At most one of "iam_profile_id" or "iam_profile_crn" may be specified.')
|
|
76
|
+
raise ValueError('At most one of "iam_profile_id" or "iam_profile_crn" may be specified.')
|
|
79
77
|
|
|
80
78
|
def authenticate(self, req: Request) -> None:
|
|
81
79
|
"""Adds IAM authentication information to the request.
|
|
@@ -85,14 +83,13 @@ class VPCInstanceAuthenticator(Authenticator):
|
|
|
85
83
|
Authorization: Bearer <bearer-token>
|
|
86
84
|
|
|
87
85
|
Args:
|
|
88
|
-
req: The request to add IAM authentication information
|
|
86
|
+
req: The request to add IAM authentication information to. Must contain a key to a dictionary
|
|
89
87
|
called headers.
|
|
90
88
|
"""
|
|
91
89
|
headers = req.get('headers')
|
|
92
90
|
bearer_token = self.token_manager.get_token()
|
|
93
91
|
headers['Authorization'] = 'Bearer {0}'.format(bearer_token)
|
|
94
92
|
|
|
95
|
-
|
|
96
93
|
def set_iam_profile_crn(self, iam_profile_crn: str) -> None:
|
|
97
94
|
"""Sets CRN of the IAM profile.
|
|
98
95
|
|