ibm-cloud-sdk-core 3.20.5__tar.gz → 3.20.6__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {ibm_cloud_sdk_core-3.20.5/ibm_cloud_sdk_core.egg-info → ibm_cloud_sdk_core-3.20.6}/PKG-INFO +2 -2
- {ibm_cloud_sdk_core-3.20.5 → ibm_cloud_sdk_core-3.20.6}/README.md +1 -1
- ibm_cloud_sdk_core-3.20.6/ibm_cloud_sdk_core/authenticators/__init__.py +44 -0
- ibm_cloud_sdk_core-3.20.6/ibm_cloud_sdk_core/authenticators/authenticator.py +58 -0
- ibm_cloud_sdk_core-3.20.6/ibm_cloud_sdk_core/authenticators/basic_authenticator.py +83 -0
- ibm_cloud_sdk_core-3.20.6/ibm_cloud_sdk_core/authenticators/bearer_token_authenticator.py +80 -0
- ibm_cloud_sdk_core-3.20.6/ibm_cloud_sdk_core/authenticators/container_authenticator.py +150 -0
- ibm_cloud_sdk_core-3.20.6/ibm_cloud_sdk_core/authenticators/cp4d_authenticator.py +165 -0
- ibm_cloud_sdk_core-3.20.6/ibm_cloud_sdk_core/authenticators/iam_authenticator.py +110 -0
- ibm_cloud_sdk_core-3.20.6/ibm_cloud_sdk_core/authenticators/iam_request_based_authenticator.py +114 -0
- ibm_cloud_sdk_core-3.20.6/ibm_cloud_sdk_core/authenticators/mcsp_authenticator.py +130 -0
- ibm_cloud_sdk_core-3.20.6/ibm_cloud_sdk_core/authenticators/no_auth_authenticator.py +31 -0
- ibm_cloud_sdk_core-3.20.6/ibm_cloud_sdk_core/authenticators/vpc_instance_authenticator.py +121 -0
- ibm_cloud_sdk_core-3.20.6/ibm_cloud_sdk_core/token_managers/__init__.py +15 -0
- ibm_cloud_sdk_core-3.20.6/ibm_cloud_sdk_core/token_managers/container_token_manager.py +201 -0
- ibm_cloud_sdk_core-3.20.6/ibm_cloud_sdk_core/token_managers/cp4d_token_manager.py +124 -0
- ibm_cloud_sdk_core-3.20.6/ibm_cloud_sdk_core/token_managers/iam_request_based_token_manager.py +192 -0
- ibm_cloud_sdk_core-3.20.6/ibm_cloud_sdk_core/token_managers/iam_token_manager.py +93 -0
- ibm_cloud_sdk_core-3.20.6/ibm_cloud_sdk_core/token_managers/jwt_token_manager.py +91 -0
- ibm_cloud_sdk_core-3.20.6/ibm_cloud_sdk_core/token_managers/mcsp_token_manager.py +102 -0
- ibm_cloud_sdk_core-3.20.6/ibm_cloud_sdk_core/token_managers/token_manager.py +209 -0
- ibm_cloud_sdk_core-3.20.6/ibm_cloud_sdk_core/token_managers/vpc_instance_token_manager.py +175 -0
- ibm_cloud_sdk_core-3.20.6/ibm_cloud_sdk_core/version.py +1 -0
- {ibm_cloud_sdk_core-3.20.5 → ibm_cloud_sdk_core-3.20.6/ibm_cloud_sdk_core.egg-info}/PKG-INFO +2 -2
- ibm_cloud_sdk_core-3.20.6/ibm_cloud_sdk_core.egg-info/SOURCES.txt +59 -0
- {ibm_cloud_sdk_core-3.20.5 → ibm_cloud_sdk_core-3.20.6}/pyproject.toml +2 -2
- ibm_cloud_sdk_core-3.20.5/ibm_cloud_sdk_core/version.py +0 -1
- ibm_cloud_sdk_core-3.20.5/ibm_cloud_sdk_core.egg-info/SOURCES.txt +0 -39
- {ibm_cloud_sdk_core-3.20.5 → ibm_cloud_sdk_core-3.20.6}/LICENSE +0 -0
- {ibm_cloud_sdk_core-3.20.5 → ibm_cloud_sdk_core-3.20.6}/MANIFEST.in +0 -0
- {ibm_cloud_sdk_core-3.20.5 → ibm_cloud_sdk_core-3.20.6}/ibm_cloud_sdk_core/__init__.py +0 -0
- {ibm_cloud_sdk_core-3.20.5 → ibm_cloud_sdk_core-3.20.6}/ibm_cloud_sdk_core/api_exception.py +0 -0
- {ibm_cloud_sdk_core-3.20.5 → ibm_cloud_sdk_core-3.20.6}/ibm_cloud_sdk_core/base_service.py +0 -0
- {ibm_cloud_sdk_core-3.20.5 → ibm_cloud_sdk_core-3.20.6}/ibm_cloud_sdk_core/detailed_response.py +0 -0
- {ibm_cloud_sdk_core-3.20.5 → ibm_cloud_sdk_core-3.20.6}/ibm_cloud_sdk_core/get_authenticator.py +0 -0
- {ibm_cloud_sdk_core-3.20.5 → ibm_cloud_sdk_core-3.20.6}/ibm_cloud_sdk_core/http_adapter.py +0 -0
- {ibm_cloud_sdk_core-3.20.5 → ibm_cloud_sdk_core-3.20.6}/ibm_cloud_sdk_core/private_helpers.py +0 -0
- {ibm_cloud_sdk_core-3.20.5 → ibm_cloud_sdk_core-3.20.6}/ibm_cloud_sdk_core/utils.py +0 -0
- {ibm_cloud_sdk_core-3.20.5 → ibm_cloud_sdk_core-3.20.6}/ibm_cloud_sdk_core.egg-info/dependency_links.txt +0 -0
- {ibm_cloud_sdk_core-3.20.5 → ibm_cloud_sdk_core-3.20.6}/ibm_cloud_sdk_core.egg-info/requires.txt +0 -0
- {ibm_cloud_sdk_core-3.20.5 → ibm_cloud_sdk_core-3.20.6}/ibm_cloud_sdk_core.egg-info/top_level.txt +0 -0
- {ibm_cloud_sdk_core-3.20.5 → ibm_cloud_sdk_core-3.20.6}/setup.cfg +0 -0
- {ibm_cloud_sdk_core-3.20.5 → ibm_cloud_sdk_core-3.20.6}/test/test_api_exception.py +0 -0
- {ibm_cloud_sdk_core-3.20.5 → ibm_cloud_sdk_core-3.20.6}/test/test_authenticator.py +0 -0
- {ibm_cloud_sdk_core-3.20.5 → ibm_cloud_sdk_core-3.20.6}/test/test_base_service.py +0 -0
- {ibm_cloud_sdk_core-3.20.5 → ibm_cloud_sdk_core-3.20.6}/test/test_basic_authenticator.py +0 -0
- {ibm_cloud_sdk_core-3.20.5 → ibm_cloud_sdk_core-3.20.6}/test/test_bearer_authenticator.py +0 -0
- {ibm_cloud_sdk_core-3.20.5 → ibm_cloud_sdk_core-3.20.6}/test/test_container_authenticator.py +0 -0
- {ibm_cloud_sdk_core-3.20.5 → ibm_cloud_sdk_core-3.20.6}/test/test_container_token_manager.py +0 -0
- {ibm_cloud_sdk_core-3.20.5 → ibm_cloud_sdk_core-3.20.6}/test/test_cp4d_authenticator.py +0 -0
- {ibm_cloud_sdk_core-3.20.5 → ibm_cloud_sdk_core-3.20.6}/test/test_cp4d_token_manager.py +0 -0
- {ibm_cloud_sdk_core-3.20.5 → ibm_cloud_sdk_core-3.20.6}/test/test_detailed_response.py +0 -0
- {ibm_cloud_sdk_core-3.20.5 → ibm_cloud_sdk_core-3.20.6}/test/test_http_adapter.py +0 -0
- {ibm_cloud_sdk_core-3.20.5 → ibm_cloud_sdk_core-3.20.6}/test/test_iam_authenticator.py +0 -0
- {ibm_cloud_sdk_core-3.20.5 → ibm_cloud_sdk_core-3.20.6}/test/test_iam_token_manager.py +0 -0
- {ibm_cloud_sdk_core-3.20.5 → ibm_cloud_sdk_core-3.20.6}/test/test_jwt_token_manager.py +0 -0
- {ibm_cloud_sdk_core-3.20.5 → ibm_cloud_sdk_core-3.20.6}/test/test_mcsp_authenticator.py +0 -0
- {ibm_cloud_sdk_core-3.20.5 → ibm_cloud_sdk_core-3.20.6}/test/test_mcsp_token_manager.py +0 -0
- {ibm_cloud_sdk_core-3.20.5 → ibm_cloud_sdk_core-3.20.6}/test/test_no_auth_authenticator.py +0 -0
- {ibm_cloud_sdk_core-3.20.5 → ibm_cloud_sdk_core-3.20.6}/test/test_token_manager.py +0 -0
- {ibm_cloud_sdk_core-3.20.5 → ibm_cloud_sdk_core-3.20.6}/test/test_utils.py +0 -0
- {ibm_cloud_sdk_core-3.20.5 → ibm_cloud_sdk_core-3.20.6}/test/test_vpc_instance_authenticator.py +0 -0
- {ibm_cloud_sdk_core-3.20.5 → ibm_cloud_sdk_core-3.20.6}/test/test_vpc_instance_token_manager.py +0 -0
{ibm_cloud_sdk_core-3.20.5/ibm_cloud_sdk_core.egg-info → ibm_cloud_sdk_core-3.20.6}/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: ibm-cloud-sdk-core
|
|
3
|
-
Version: 3.20.
|
|
3
|
+
Version: 3.20.6
|
|
4
4
|
Summary: Core library used by SDKs for IBM Cloud Services
|
|
5
5
|
Author-email: IBM <devxsdk@us.ibm.com>
|
|
6
6
|
Project-URL: Repository, https://github.com/IBM/python-sdk-core
|
|
@@ -49,7 +49,7 @@ Requires-Dist: twine; extra == "publish"
|
|
|
49
49
|
[](https://cla-assistant.io/ibm/python-sdk-core)
|
|
50
50
|
[](https://github.com/semantic-release/semantic-release)
|
|
51
51
|
|
|
52
|
-
# IBM Python SDK Core Version 3.20.
|
|
52
|
+
# IBM Python SDK Core Version 3.20.6
|
|
53
53
|
This project contains core functionality required by Python code generated by the IBM Cloud OpenAPI SDK Generator
|
|
54
54
|
(openapi-sdkgen).
|
|
55
55
|
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
[](https://cla-assistant.io/ibm/python-sdk-core)
|
|
5
5
|
[](https://github.com/semantic-release/semantic-release)
|
|
6
6
|
|
|
7
|
-
# IBM Python SDK Core Version 3.20.
|
|
7
|
+
# IBM Python SDK Core Version 3.20.6
|
|
8
8
|
This project contains core functionality required by Python code generated by the IBM Cloud OpenAPI SDK Generator
|
|
9
9
|
(openapi-sdkgen).
|
|
10
10
|
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# coding: utf-8
|
|
2
|
+
|
|
3
|
+
# Copyright 2019 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
|
+
"""The ibm_cloud_sdk_core project supports the following types of authentication:
|
|
17
|
+
|
|
18
|
+
Basic Authentication
|
|
19
|
+
Bearer Token
|
|
20
|
+
Identity and Access Management (IAM)
|
|
21
|
+
Cloud Pak for Data
|
|
22
|
+
No Authentication
|
|
23
|
+
|
|
24
|
+
The authentication types that are appropriate for a particular service may vary from service to service.
|
|
25
|
+
Each authentication type is implemented as an Authenticator for consumption by a service.
|
|
26
|
+
|
|
27
|
+
classes:
|
|
28
|
+
Authenticator: Abstract Base Class. Implement this interface to provide custom authentication schemes to services.
|
|
29
|
+
BasicAuthenticator: Authenticator for passing supplied basic authentication information to service endpoint.
|
|
30
|
+
BearerTokenAuthenticator: Authenticator for passing supplied bearer token to service endpoint.
|
|
31
|
+
CloudPakForDataAuthenticator: Authenticator for passing CP4D authentication information to service endpoint.
|
|
32
|
+
IAMAuthenticator: Authenticator for passing IAM authentication information to service endpoint.
|
|
33
|
+
NoAuthAuthenticator: Performs no authentication. Useful for testing purposes.
|
|
34
|
+
"""
|
|
35
|
+
|
|
36
|
+
from .authenticator import Authenticator
|
|
37
|
+
from .basic_authenticator import BasicAuthenticator
|
|
38
|
+
from .bearer_token_authenticator import BearerTokenAuthenticator
|
|
39
|
+
from .container_authenticator import ContainerAuthenticator
|
|
40
|
+
from .cp4d_authenticator import CloudPakForDataAuthenticator
|
|
41
|
+
from .iam_authenticator import IAMAuthenticator
|
|
42
|
+
from .vpc_instance_authenticator import VPCInstanceAuthenticator
|
|
43
|
+
from .no_auth_authenticator import NoAuthAuthenticator
|
|
44
|
+
from .mcsp_authenticator import MCSPAuthenticator
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# coding: utf-8
|
|
2
|
+
|
|
3
|
+
# Copyright 2019, 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 abc import ABC, abstractmethod
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class Authenticator(ABC):
|
|
21
|
+
"""This interface defines the common methods and constants associated with an Authenticator implementation."""
|
|
22
|
+
|
|
23
|
+
# Constants representing the various authenticator types.
|
|
24
|
+
AUTHTYPE_BASIC = 'basic'
|
|
25
|
+
AUTHTYPE_BEARERTOKEN = 'bearerToken'
|
|
26
|
+
AUTHTYPE_IAM = 'iam'
|
|
27
|
+
AUTHTYPE_CONTAINER = 'container'
|
|
28
|
+
AUTHTYPE_CP4D = 'cp4d'
|
|
29
|
+
AUTHTYPE_VPC = 'vpc'
|
|
30
|
+
AUTHTYPE_NOAUTH = 'noAuth'
|
|
31
|
+
AUTHTYPE_MCSP = 'mcsp'
|
|
32
|
+
AUTHTYPE_UNKNOWN = 'unknown'
|
|
33
|
+
|
|
34
|
+
@abstractmethod
|
|
35
|
+
def authenticate(self, req: dict) -> None:
|
|
36
|
+
"""Perform the necessary authentication steps for the specified request.
|
|
37
|
+
|
|
38
|
+
Attributes:
|
|
39
|
+
req (dict): Will be modified to contain the appropriate authentication information.
|
|
40
|
+
|
|
41
|
+
To be implemented by subclasses.
|
|
42
|
+
"""
|
|
43
|
+
pass
|
|
44
|
+
|
|
45
|
+
@abstractmethod
|
|
46
|
+
def validate(self) -> None:
|
|
47
|
+
"""Validates the current set of configuration information in the Authenticator.
|
|
48
|
+
|
|
49
|
+
Raises:
|
|
50
|
+
ValueError: The configuration information is not valid for service operations.
|
|
51
|
+
|
|
52
|
+
To be implemented by subclasses.
|
|
53
|
+
"""
|
|
54
|
+
pass
|
|
55
|
+
|
|
56
|
+
def authentication_type(self) -> str:
|
|
57
|
+
"""Returns the authenticator's type. This method should be overridden by each authenticator implementation."""
|
|
58
|
+
return self.AUTHTYPE_UNKNOWN
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
# coding: utf-8
|
|
2
|
+
|
|
3
|
+
# Copyright 2019 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
|
+
import base64
|
|
18
|
+
from requests import Request
|
|
19
|
+
|
|
20
|
+
from .authenticator import Authenticator
|
|
21
|
+
from ..utils import has_bad_first_or_last_char
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class BasicAuthenticator(Authenticator):
|
|
25
|
+
"""The BasicAuthenticator is used to add basic authentication information to requests.
|
|
26
|
+
|
|
27
|
+
Basic Authorization will be sent as an Authorization header in the form:
|
|
28
|
+
|
|
29
|
+
Authorization: Basic <encoded username and password>
|
|
30
|
+
|
|
31
|
+
Args:
|
|
32
|
+
username: User-supplied username for basic auth.
|
|
33
|
+
password: User-supplied password for basic auth.
|
|
34
|
+
|
|
35
|
+
Raises:
|
|
36
|
+
ValueError: The username or password is not specified or contains invalid characters.
|
|
37
|
+
"""
|
|
38
|
+
|
|
39
|
+
def __init__(self, username: str, password: str) -> None:
|
|
40
|
+
self.username = username
|
|
41
|
+
self.password = password
|
|
42
|
+
self.validate()
|
|
43
|
+
self.authorization_header = self.__construct_basic_auth_header()
|
|
44
|
+
|
|
45
|
+
def authentication_type(self) -> str:
|
|
46
|
+
"""Returns this authenticator's type ('basic')."""
|
|
47
|
+
return Authenticator.AUTHTYPE_BASIC
|
|
48
|
+
|
|
49
|
+
def validate(self) -> None:
|
|
50
|
+
"""Validate username and password.
|
|
51
|
+
|
|
52
|
+
Ensure the username and password are valid for service operations.
|
|
53
|
+
|
|
54
|
+
Raises:
|
|
55
|
+
ValueError: The username and/or password is not valid for service operations.
|
|
56
|
+
"""
|
|
57
|
+
if self.username is None or self.password is None:
|
|
58
|
+
raise ValueError('The username and password shouldn\'t be None.')
|
|
59
|
+
|
|
60
|
+
if has_bad_first_or_last_char(self.username) or has_bad_first_or_last_char(self.password):
|
|
61
|
+
raise ValueError(
|
|
62
|
+
'The username and password shouldn\'t start or end with curly brackets or quotes. '
|
|
63
|
+
'Please remove any surrounding {, }, or \" characters.'
|
|
64
|
+
)
|
|
65
|
+
|
|
66
|
+
def __construct_basic_auth_header(self) -> str:
|
|
67
|
+
authstring = "{0}:{1}".format(self.username, self.password)
|
|
68
|
+
base64_authorization = base64.b64encode(authstring.encode('utf-8')).decode('utf-8')
|
|
69
|
+
return 'Basic {0}'.format(base64_authorization)
|
|
70
|
+
|
|
71
|
+
def authenticate(self, req: Request) -> None:
|
|
72
|
+
"""Add basic authentication information to a request.
|
|
73
|
+
|
|
74
|
+
Basic Authorization will be added to the request's headers in the form:
|
|
75
|
+
|
|
76
|
+
Authorization: Basic <encoded username and password>
|
|
77
|
+
|
|
78
|
+
Args:
|
|
79
|
+
req: The request to add basic auth information to. Must contain a key to a dictionary
|
|
80
|
+
called headers.
|
|
81
|
+
"""
|
|
82
|
+
headers = req.get('headers')
|
|
83
|
+
headers['Authorization'] = self.authorization_header
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
# coding: utf-8
|
|
2
|
+
|
|
3
|
+
# Copyright 2019 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 requests import Request
|
|
18
|
+
|
|
19
|
+
from .authenticator import Authenticator
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class BearerTokenAuthenticator(Authenticator):
|
|
23
|
+
"""The BearerTokenAuthenticator will add a user-supplied bearer token
|
|
24
|
+
to requests.
|
|
25
|
+
|
|
26
|
+
The bearer token will be sent as an Authorization header in the form:
|
|
27
|
+
|
|
28
|
+
Authorization: Bearer <bearer-token>
|
|
29
|
+
|
|
30
|
+
Args:
|
|
31
|
+
bearer_token: The user supplied bearer token.
|
|
32
|
+
|
|
33
|
+
Raises:
|
|
34
|
+
ValueError: Bearer token is none.
|
|
35
|
+
"""
|
|
36
|
+
|
|
37
|
+
def __init__(self, bearer_token: str) -> None:
|
|
38
|
+
self.bearer_token = bearer_token
|
|
39
|
+
self.validate()
|
|
40
|
+
|
|
41
|
+
def authentication_type(self) -> str:
|
|
42
|
+
"""Returns this authenticator's type ('bearertoken')."""
|
|
43
|
+
return Authenticator.AUTHTYPE_BEARERTOKEN
|
|
44
|
+
|
|
45
|
+
def validate(self) -> None:
|
|
46
|
+
"""Validate the bearer token.
|
|
47
|
+
|
|
48
|
+
Ensures the bearer token is valid for service operations.
|
|
49
|
+
|
|
50
|
+
Raises:
|
|
51
|
+
ValueError: The bearer token is not valid for service operations.
|
|
52
|
+
"""
|
|
53
|
+
if self.bearer_token is None:
|
|
54
|
+
raise ValueError('The bearer token shouldn\'t be None.')
|
|
55
|
+
|
|
56
|
+
def authenticate(self, req: Request) -> None:
|
|
57
|
+
"""Adds bearer authentication information to the request.
|
|
58
|
+
|
|
59
|
+
The bearer token will be added to the request's headers in the form:
|
|
60
|
+
|
|
61
|
+
Authorization: Bearer <bearer-token>
|
|
62
|
+
|
|
63
|
+
Args:
|
|
64
|
+
req: The request to add bearer authentication information to. Must contain a key to a dictionary
|
|
65
|
+
called headers.
|
|
66
|
+
"""
|
|
67
|
+
headers = req.get('headers')
|
|
68
|
+
headers['Authorization'] = 'Bearer {0}'.format(self.bearer_token)
|
|
69
|
+
|
|
70
|
+
def set_bearer_token(self, bearer_token: str) -> None:
|
|
71
|
+
"""Set a new bearer token to be sent in subsequent service operations.
|
|
72
|
+
|
|
73
|
+
Args:
|
|
74
|
+
bearer_token: The bearer token that will be sent in service requests.
|
|
75
|
+
|
|
76
|
+
Raises:
|
|
77
|
+
ValueError: The bearer token is not valid for service operations.
|
|
78
|
+
"""
|
|
79
|
+
self.bearer_token = bearer_token
|
|
80
|
+
self.validate()
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
# coding: utf-8
|
|
2
|
+
|
|
3
|
+
# Copyright 2021 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 .iam_request_based_authenticator import IAMRequestBasedAuthenticator
|
|
20
|
+
from ..token_managers.container_token_manager import ContainerTokenManager
|
|
21
|
+
from .authenticator import Authenticator
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class ContainerAuthenticator(IAMRequestBasedAuthenticator):
|
|
25
|
+
"""ContainerAuthenticator implements an IAM-based authentication schema where by it
|
|
26
|
+
retrieves a "compute resource token" from the local compute resource (VM)
|
|
27
|
+
and uses that to obtain an IAM access token by invoking the IAM "get token" operation with grant-type=cr-token.
|
|
28
|
+
The resulting IAM access token is then added to outbound requests in an Authorization header of the form:
|
|
29
|
+
|
|
30
|
+
Authorization: Bearer <access-token>
|
|
31
|
+
|
|
32
|
+
Args:
|
|
33
|
+
cr_token_filename: The name of the file containing the injected CR token value
|
|
34
|
+
(applies to IKS-managed compute resources). Defaults to "/var/run/secrets/tokens/vault-token".
|
|
35
|
+
iam_profile_name: The name of the linked trusted IAM profile to be used when obtaining the IAM access token
|
|
36
|
+
(a CR token might map to multiple IAM profiles).
|
|
37
|
+
One of iam_profile_name or iam_profile_id must be specified.
|
|
38
|
+
Defaults to None.
|
|
39
|
+
iam_profile_id: The id of the linked trusted IAM profile to be used when obtaining the IAM access token
|
|
40
|
+
(a CR token might map to multiple IAM profiles).
|
|
41
|
+
One of iam_profile_name or iam_profile_id must be specified.
|
|
42
|
+
Defaults to None.
|
|
43
|
+
url: The URL representing the IAM token service endpoint. If not specified, a suitable default value is used.
|
|
44
|
+
client_id: The client_id and client_secret fields are used to form
|
|
45
|
+
a "basic" authorization header for IAM token requests. Defaults to None.
|
|
46
|
+
client_secret: The client_id and client_secret fields are used to form
|
|
47
|
+
a "basic" authorization header for IAM token requests. Defaults to None.
|
|
48
|
+
disable_ssl_verification: A flag that indicates whether verification of
|
|
49
|
+
the server's SSL certificate should be disabled or not. Defaults to False.
|
|
50
|
+
headers: Default headers to be sent with every IAM token request. Defaults to None.
|
|
51
|
+
proxies: Dictionary for mapping request protocol to proxy URL. Defaults to None.
|
|
52
|
+
proxies.http (optional): The proxy endpoint to use for HTTP requests.
|
|
53
|
+
proxies.https (optional): The proxy endpoint to use for HTTPS requests.
|
|
54
|
+
scope: The "scope" to use when fetching the bearer token from the IAM token server.
|
|
55
|
+
This can be used to obtain an access token with a specific scope.
|
|
56
|
+
|
|
57
|
+
Attributes:
|
|
58
|
+
token_manager (ContainerTokenManager): Retrieves and manages IAM tokens
|
|
59
|
+
from the endpoint specified by the url.
|
|
60
|
+
|
|
61
|
+
Raises:
|
|
62
|
+
TypeError: The `disable_ssl_verification` is not a bool.
|
|
63
|
+
ValueError: Neither of iam_profile_name or iam_profile_idk are set,
|
|
64
|
+
or client_id, and/or client_secret are not valid for IAM token requests.
|
|
65
|
+
"""
|
|
66
|
+
|
|
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:
|
|
80
|
+
# Check the type of `disable_ssl_verification`. Must be a bool.
|
|
81
|
+
if not isinstance(disable_ssl_verification, bool):
|
|
82
|
+
raise TypeError('disable_ssl_verification must be a bool')
|
|
83
|
+
|
|
84
|
+
self.token_manager = ContainerTokenManager(
|
|
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
|
+
)
|
|
96
|
+
|
|
97
|
+
self.validate()
|
|
98
|
+
|
|
99
|
+
def authentication_type(self) -> str:
|
|
100
|
+
"""Returns this authenticator's type ('container')."""
|
|
101
|
+
return Authenticator.AUTHTYPE_CONTAINER
|
|
102
|
+
|
|
103
|
+
def validate(self) -> None:
|
|
104
|
+
"""Validates the iam_profile_name, iam_profile_id, client_id, and client_secret for IAM token requests.
|
|
105
|
+
|
|
106
|
+
Ensure that one of the iam_profile_name or iam_profile_id are specified. Additionally, ensure
|
|
107
|
+
both of the client_id and client_secret are set if either of them are defined.
|
|
108
|
+
|
|
109
|
+
Raises:
|
|
110
|
+
ValueError: Neither of iam_profile_name or iam_profile_idk are set,
|
|
111
|
+
or client_id, and/or client_secret are not valid for IAM token requests.
|
|
112
|
+
"""
|
|
113
|
+
super().validate()
|
|
114
|
+
|
|
115
|
+
if not self.token_manager.iam_profile_name and not self.token_manager.iam_profile_id:
|
|
116
|
+
raise ValueError('At least one of iam_profile_name or iam_profile_id must be specified.')
|
|
117
|
+
|
|
118
|
+
def set_cr_token_filename(self, cr_token_filename: str) -> None:
|
|
119
|
+
"""Set the location of the compute resource token on the local filesystem.
|
|
120
|
+
|
|
121
|
+
Args:
|
|
122
|
+
cr_token_filename: path to the compute resource token
|
|
123
|
+
"""
|
|
124
|
+
self.token_manager.cr_token_filename = cr_token_filename
|
|
125
|
+
|
|
126
|
+
def set_iam_profile_name(self, iam_profile_name: str) -> None:
|
|
127
|
+
"""Set the name of the IAM profile.
|
|
128
|
+
|
|
129
|
+
Args:
|
|
130
|
+
iam_profile_name: name of the linked trusted IAM profile to be used when obtaining the IAM access token
|
|
131
|
+
|
|
132
|
+
Raises:
|
|
133
|
+
ValueError: Neither of iam_profile_name or iam_profile_idk are set,
|
|
134
|
+
or client_id, and/or client_secret are not valid for IAM token requests.
|
|
135
|
+
"""
|
|
136
|
+
self.token_manager.iam_profile_name = iam_profile_name
|
|
137
|
+
self.validate()
|
|
138
|
+
|
|
139
|
+
def set_iam_profile_id(self, iam_profile_id: str) -> None:
|
|
140
|
+
"""Set the id of the IAM profile.
|
|
141
|
+
|
|
142
|
+
Args:
|
|
143
|
+
iam_profile_id: id of the linked trusted IAM profile to be used when obtaining the IAM access token
|
|
144
|
+
|
|
145
|
+
Raises:
|
|
146
|
+
ValueError: Neither of iam_profile_name or iam_profile_idk are set,
|
|
147
|
+
or client_id, and/or client_secret are not valid for IAM token requests.
|
|
148
|
+
"""
|
|
149
|
+
self.token_manager.iam_profile_id = iam_profile_id
|
|
150
|
+
self.validate()
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
# coding: utf-8
|
|
2
|
+
|
|
3
|
+
# Copyright 2019 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.cp4d_token_manager import CP4DTokenManager
|
|
23
|
+
from ..utils import has_bad_first_or_last_char
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class CloudPakForDataAuthenticator(Authenticator):
|
|
27
|
+
"""The CloudPakForDataAuthenticator utilizes a username and password pair to
|
|
28
|
+
obtain a suitable bearer token, and adds it requests.
|
|
29
|
+
|
|
30
|
+
The bearer token will be sent as an Authorization header in the form:
|
|
31
|
+
|
|
32
|
+
Authorization: Bearer <bearer-token>
|
|
33
|
+
|
|
34
|
+
Keyword Args:
|
|
35
|
+
username: The username used to obtain a bearer token [required].
|
|
36
|
+
password: The password used to obtain a bearer token [required if apikey not specified].
|
|
37
|
+
url: The URL representing the Cloud Pak for Data token service endpoint [required].
|
|
38
|
+
apikey: The API key used to obtain a bearer token [required if password not specified].
|
|
39
|
+
disable_ssl_verification: A flag that indicates whether verification of the server's SSL
|
|
40
|
+
certificate should be disabled or not. Defaults to False.
|
|
41
|
+
headers: Default headers to be sent with every CP4D token request. Defaults to None.
|
|
42
|
+
proxies: Dictionary for mapping request protocol to proxy URL.
|
|
43
|
+
proxies.http (optional): The proxy endpoint to use for HTTP requests.
|
|
44
|
+
proxies.https (optional): The proxy endpoint to use for HTTPS requests.
|
|
45
|
+
verify (optional): The path to the certificate to use for HTTPS requests.
|
|
46
|
+
|
|
47
|
+
Attributes:
|
|
48
|
+
token_manager (CP4DTokenManager): Retrieves and manages CP4D tokens from the endpoint specified by the url.
|
|
49
|
+
|
|
50
|
+
Raises:
|
|
51
|
+
TypeError: The `disable_ssl_verification` is not a bool.
|
|
52
|
+
ValueError: The username, password/apikey, and/or url are not valid for CP4D token requests.
|
|
53
|
+
"""
|
|
54
|
+
|
|
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:
|
|
67
|
+
# Check the type of `disable_ssl_verification`. Must be a bool.
|
|
68
|
+
if not isinstance(disable_ssl_verification, bool):
|
|
69
|
+
raise TypeError('disable_ssl_verification must be a bool')
|
|
70
|
+
|
|
71
|
+
self.token_manager = CP4DTokenManager(
|
|
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
|
+
)
|
|
81
|
+
|
|
82
|
+
self.validate()
|
|
83
|
+
|
|
84
|
+
def authentication_type(self) -> str:
|
|
85
|
+
"""Returns this authenticator's type ('cp4d')."""
|
|
86
|
+
return Authenticator.AUTHTYPE_CP4D
|
|
87
|
+
|
|
88
|
+
def validate(self) -> None:
|
|
89
|
+
"""Validate username, password, and url for token requests.
|
|
90
|
+
|
|
91
|
+
Ensures the username, password, and url are not None. Additionally, ensures they do not contain invalid
|
|
92
|
+
characters.
|
|
93
|
+
|
|
94
|
+
Raises:
|
|
95
|
+
ValueError: The username, password, and/or url are not valid for token requests.
|
|
96
|
+
"""
|
|
97
|
+
if self.token_manager.username is None:
|
|
98
|
+
raise ValueError('The username shouldn\'t be None.')
|
|
99
|
+
|
|
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.')
|
|
104
|
+
|
|
105
|
+
if self.token_manager.url is None:
|
|
106
|
+
raise ValueError('The url shouldn\'t be None.')
|
|
107
|
+
|
|
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
|
+
):
|
|
111
|
+
raise ValueError(
|
|
112
|
+
'The username and password shouldn\'t start or end with curly brackets or quotes. '
|
|
113
|
+
'Please remove any surrounding {, }, or \" characters.'
|
|
114
|
+
)
|
|
115
|
+
|
|
116
|
+
if has_bad_first_or_last_char(self.token_manager.url):
|
|
117
|
+
raise ValueError(
|
|
118
|
+
'The url shouldn\'t start or end with curly brackets or quotes. '
|
|
119
|
+
'Please remove any surrounding {, }, or \" characters.'
|
|
120
|
+
)
|
|
121
|
+
|
|
122
|
+
def authenticate(self, req: Request) -> None:
|
|
123
|
+
"""Adds CP4D authentication information to the request.
|
|
124
|
+
|
|
125
|
+
The CP4D bearer token will be added to the request's headers in the form:
|
|
126
|
+
|
|
127
|
+
Authorization: Bearer <bearer-token>
|
|
128
|
+
|
|
129
|
+
Args:
|
|
130
|
+
req: The request to add CP4D authentication information to. Must contain a key to a dictionary
|
|
131
|
+
called headers.
|
|
132
|
+
"""
|
|
133
|
+
headers = req.get('headers')
|
|
134
|
+
bearer_token = self.token_manager.get_token()
|
|
135
|
+
headers['Authorization'] = 'Bearer {0}'.format(bearer_token)
|
|
136
|
+
|
|
137
|
+
def set_disable_ssl_verification(self, status: bool = False) -> None:
|
|
138
|
+
"""Set the flag that indicates whether verification of the server's SSL certificate should be
|
|
139
|
+
disabled or not. Defaults to False.
|
|
140
|
+
|
|
141
|
+
Args:
|
|
142
|
+
status: Set to true in order to disable SSL certificate verification. Defaults to False.
|
|
143
|
+
|
|
144
|
+
Raises:
|
|
145
|
+
TypeError: The `status` is not a bool.
|
|
146
|
+
"""
|
|
147
|
+
self.token_manager.set_disable_ssl_verification(status)
|
|
148
|
+
|
|
149
|
+
def set_headers(self, headers: Dict[str, str]) -> None:
|
|
150
|
+
"""Default headers to be sent with every CP4D token request.
|
|
151
|
+
|
|
152
|
+
Args:
|
|
153
|
+
headers: The headers to be sent with every CP4D token request.
|
|
154
|
+
"""
|
|
155
|
+
self.token_manager.set_headers(headers)
|
|
156
|
+
|
|
157
|
+
def set_proxies(self, proxies: Dict[str, str]) -> None:
|
|
158
|
+
"""Sets the proxies the token manager will use to communicate with CP4D on behalf of the host.
|
|
159
|
+
|
|
160
|
+
Args:
|
|
161
|
+
proxies: Dictionary for mapping request protocol to proxy URL.
|
|
162
|
+
proxies.http (optional): The proxy endpoint to use for HTTP requests.
|
|
163
|
+
proxies.https (optional): The proxy endpoint to use for HTTPS requests.
|
|
164
|
+
"""
|
|
165
|
+
self.token_manager.set_proxies(proxies)
|