Skip to content

Commit

Permalink
fix(ContainerAuthenticator): add sa-token as default CR token filename (
Browse files Browse the repository at this point in the history
#165)

This commit adds support for a second default CR token filename.
If the user doesn't specify a CR token filename, the authenticator will
first try '/var/run/secrets/tokens/vault-token', and then
'/var/run/secrets/tokens/sa-token' in that order.

Signed-off-by: Phil Adams <[email protected]>
  • Loading branch information
padamstx authored May 22, 2023
1 parent 2307cb9 commit 7c6bd0f
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 17 deletions.
3 changes: 2 additions & 1 deletion Authentication.md
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,8 @@ The IAM access token is added to each outbound request in the `Authorization` he
### Properties

- cr_token_filename: (optional) The name of the file containing the injected CR token value.
If not specified, then `/var/run/secrets/tokens/vault-token` is used as the default value.
If not specified, then the authenticator will first try `/var/run/secrets/tokens/vault-token`
and then `/var/run/secrets/tokens/sa-token` as the default value (first file found is used).
The application must have `read` permissions on the file containing the CR token value.

- iam_profile_name: (optional) The name of the linked trusted IAM profile to be used when obtaining the
Expand Down
48 changes: 34 additions & 14 deletions ibm_cloud_sdk_core/token_managers/container_token_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,8 @@ class ContainerTokenManager(IAMRequestBasedTokenManager):
This can be used to obtain an access token with a specific scope.
"""

DEFAULT_CR_TOKEN_FILENAME = '/var/run/secrets/tokens/vault-token'
DEFAULT_CR_TOKEN_FILENAME1 = '/var/run/secrets/tokens/vault-token'
DEFAULT_CR_TOKEN_FILENAME2 = '/var/run/secrets/tokens/sa-token'

def __init__(
self,
Expand Down Expand Up @@ -115,24 +116,26 @@ def retrieve_cr_token(self) -> str:
"""Retrieves the CR token for the current compute resource by reading it from the local file system.
Raises:
Exception: Cannot retrieve the compute resource token from.
Exception: Error retrieving the compute resource token.
Returns:
A string which contains the compute resource token.
"""
cr_token_filename = self.cr_token_filename if self.cr_token_filename else self.DEFAULT_CR_TOKEN_FILENAME

logger.debug('Attempting to read CR token from file: %s', cr_token_filename)

try:
with open(cr_token_filename, 'r', encoding='utf-8') as file:
cr_token = file.read()
cr_token = None
if self.cr_token_filename:
# If the user specified a filename, then use that.
cr_token = self.read_file(self.cr_token_filename)
else:
# If the user didn't specify a filename, then try our two defaults.
try:
cr_token = self.read_file(self.DEFAULT_CR_TOKEN_FILENAME1)
except:
cr_token = self.read_file(self.DEFAULT_CR_TOKEN_FILENAME2)
return cr_token
except Exception as ex:
# pylint: disable=broad-exception-raised
raise Exception(
'Unable to retrieve the CR token value from file {}: {}'.format(cr_token_filename, ex)
) from None
raise Exception('Unable to retrieve the CR token: {}'.format(ex)) from None

def request_token(self) -> dict:
"""Retrieves a CR token value from the current compute resource,
Expand All @@ -141,11 +144,9 @@ def request_token(self) -> dict:
Returns:
A dictionary containing the bearer token to be subsequently used service requests.
"""
# Retrieve the CR token for this compute resource.
cr_token = self.retrieve_cr_token()

# Set the request payload.
self.request_payload['cr_token'] = cr_token
self.request_payload['cr_token'] = self.retrieve_cr_token()

if self.iam_profile_id:
self.request_payload['profile_id'] = self.iam_profile_id
Expand Down Expand Up @@ -177,3 +178,22 @@ def set_iam_profile_id(self, iam_profile_id: str) -> None:
iam_profile_id: id of the linked trusted IAM profile to be used when obtaining the IAM access token
"""
self.iam_profile_id = iam_profile_id

def read_file(self, filename: str) -> str:
"""Read in the specified file and return the contents as a string.
Args:
filename: the name of the file to read
Returns:
The contents of the file as a string.
Raises:
Exception: An error occured reading the file.
"""
try:
logger.debug('Attempting to read CR token from file: %s', filename)
with open(filename, 'r', encoding='utf-8') as file:
cr_token = file.read()
logger.debug('Successfully read CR token from file: %s', filename)
return cr_token
except Exception as ex:
# pylint: disable=broad-exception-raised
raise Exception('Error reading CR token from file {}: {}'.format(filename, ex)) from None
4 changes: 2 additions & 2 deletions test/test_container_token_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ def test_retrieve_cr_token_fail():

assert (
str(err.value)
== 'Unable to retrieve the CR token value from file bogus-cr-token-file: [Errno 2] No such file or directory: \'bogus-cr-token-file\''
== 'Unable to retrieve the CR token: Error reading CR token from file bogus-cr-token-file: [Errno 2] No such file or directory: \'bogus-cr-token-file\''
)


Expand Down Expand Up @@ -236,7 +236,7 @@ def test_authenticate_fail_no_cr_token():

assert (
str(err.value)
== 'Unable to retrieve the CR token value from file bogus-cr-token-file: [Errno 2] No such file or directory: \'bogus-cr-token-file\''
== 'Unable to retrieve the CR token: Error reading CR token from file bogus-cr-token-file: [Errno 2] No such file or directory: \'bogus-cr-token-file\''
)


Expand Down

0 comments on commit 7c6bd0f

Please sign in to comment.