Skip to content

Commit d438ade

Browse files
committed
fix: silently ignore missing configuration file
While attempting to read configuration properties from the config file specified via ${IBM_CREDENTIALS_FILE}, the read_external_sources() function should silently ignore an error if the file doesn't exist, and then proceed to the next step of the config algorithm. This was not working correctly, but this commit fixes that.
1 parent d6238b1 commit d438ade

File tree

4 files changed

+66
-17
lines changed

4 files changed

+66
-17
lines changed

Authentication.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ export EXAMPLE_SERVICE_PASSWORD=mypassword
4848
```
4949
Application code:
5050
```python
51-
from ibm_cloud_sdk_core.authenticators import get_authenticator_from_environment
51+
from ibm_cloud_sdk_core import get_authenticator_from_environment
5252

5353
authenticator = get_authenticator_from_environment('example_service')
5454
service = ExampleService(authenticator=authenticator)
@@ -80,7 +80,7 @@ export EXAMPLE_SERVICE_BEARER_TOKEN=<the bearer token value>
8080
```
8181
Application code:
8282
```python
83-
from ibm_cloud_sdk_core.authenticators import get_authenticator_from_environment
83+
from ibm_cloud_sdk_core import get_authenticator_from_environment
8484

8585
authenticator = get_authenticator_from_environment('example_service')
8686
service = ExampleService(authenticator=authenticator)
@@ -133,7 +133,7 @@ export EXAMPLE_SERVICE_APIKEY=myapikey
133133
```
134134
Application code:
135135
```python
136-
from ibm_cloud_sdk_core.authenticators import get_authenticator_from_environment
136+
from ibm_cloud_sdk_core import get_authenticator_from_environment
137137

138138
authenticator = get_authenticator_from_environment('example_service')
139139
service = ExampleService(authenticator=authenticator)
@@ -179,7 +179,7 @@ export EXAMPLE_SERVICE_URL=https://mycp4dhost.com/
179179
```
180180
Application code:
181181
```python
182-
from ibm_cloud_sdk_core.authenticators import get_authenticator_from_environment
182+
from ibm_cloud_sdk_core import get_authenticator_from_environment
183183

184184
authenticator = get_authenticator_from_environment('example_service')
185185
service = ExampleService(authenticator=authenticator)
@@ -203,7 +203,7 @@ export EXAMPLE_SERVICE_AUTH_TYPE=noauth
203203
```
204204
Application code:
205205
```python
206-
from ibm_cloud_sdk_core.authenticators import get_authenticator_from_environment
206+
from ibm_cloud_sdk_core import get_authenticator_from_environment
207207

208208
authenticator = get_authenticator_from_environment('example_service')
209209
service = ExampleService(authenticator=authenticator)

Makefile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44

55
setup: deps dev_deps install_project
66

7+
all: setup test-unit lint
8+
79
deps:
810
python -m pip install --upgrade pip
911
python -m pip install -r requirements.txt

ibm_cloud_sdk_core/utils.py

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# coding: utf-8
22

3-
# Copyright 2019 IBM All Rights Reserved.
3+
# Copyright 2019, 2021 IBM All Rights Reserved.
44
#
55
# Licensed under the Apache License, Version 2.0 (the "License");
66
# you may not use this file except in compliance with the License.
@@ -234,31 +234,36 @@ def __read_from_credential_file(service_name: str,
234234
"""
235235
default_credentials_file_name = 'ibm-credentials.env'
236236

237-
# File path specified by an env variable
237+
# 1. ${IBM_CREDENTIALS_FILE}
238238
credential_file_path = getenv('IBM_CREDENTIALS_FILE')
239239

240-
# Current working directory
240+
# 2. <current-working-directory>/ibm-credentials.env
241241
if credential_file_path is None:
242242
file_path = join(getcwd(), default_credentials_file_name)
243243
if isfile(file_path):
244244
credential_file_path = file_path
245245

246-
# Home directory
246+
# 3. <user-home-directory>/ibm-credentials.env
247247
if credential_file_path is None:
248248
file_path = join(expanduser('~'), default_credentials_file_name)
249249
if isfile(file_path):
250250
credential_file_path = file_path
251251

252252
config = {}
253253
if credential_file_path is not None:
254-
with open(credential_file_path, 'r') as fobj:
255-
for line in fobj:
256-
key_val = line.strip().split(separator, 1)
257-
if len(key_val) == 2:
258-
key = key_val[0]
259-
value = key_val[1]
260-
_parse_key_and_update_config(config, service_name, key,
261-
value)
254+
try:
255+
with open(credential_file_path, 'r') as fobj:
256+
for line in fobj:
257+
key_val = line.strip().split(separator, 1)
258+
if len(key_val) == 2:
259+
key = key_val[0]
260+
value = key_val[1]
261+
_parse_key_and_update_config(config, service_name, key,
262+
value)
263+
except OSError:
264+
# just absorb the exception and make sure we return an empty response
265+
config = {}
266+
262267
return config
263268

264269

test/test_utils.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,28 @@
11
# 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+
218
import os
319
import datetime
420

521
from typing import Optional
622
from ibm_cloud_sdk_core import string_to_datetime, datetime_to_string, get_authenticator_from_environment
723
from ibm_cloud_sdk_core import string_to_date, date_to_string
824
from ibm_cloud_sdk_core import convert_model, convert_list
25+
from ibm_cloud_sdk_core import read_external_sources
926
from ibm_cloud_sdk_core.authenticators import BasicAuthenticator, IAMAuthenticator
1027

1128

@@ -375,3 +392,28 @@ def test_multi_word_service_name():
375392
assert authenticator is not None
376393
assert authenticator.token_manager.apikey == '5678efgh'
377394
del os.environ['PERSONALITY_INSIGHTS_APIKEY']
395+
396+
397+
def test_read_external_sources_1():
398+
# Set IBM_CREDENTIALS_FILE to a non-existent file (should be silently ignored).
399+
bad_file_path = os.path.join(os.path.dirname(__file__), 'NOT_A_FILE')
400+
os.environ['IBM_CREDENTIALS_FILE'] = bad_file_path
401+
402+
# This env var should take precendence since the config file wasn't found.
403+
os.environ['SERVICE_1_URL'] = 'https://good-url.com'
404+
405+
config = read_external_sources('service_1')
406+
assert config.get('URL') == 'https://good-url.com'
407+
408+
409+
def test_read_external_sources_2():
410+
# The config file should take precedence over the env variable.
411+
config_file = os.path.join(os.path.dirname(__file__),
412+
'../resources/ibm-credentials.env')
413+
os.environ['IBM_CREDENTIALS_FILE'] = config_file
414+
415+
# This should be ignored since IBM_CREDENTIALS_FILE points to a valid file.
416+
os.environ['SERVICE_1_URL'] = 'wrong-url'
417+
418+
config = read_external_sources('service_1')
419+
assert config.get('URL') == 'service1.com/api'

0 commit comments

Comments
 (0)