-
Notifications
You must be signed in to change notification settings - Fork 29
Change order of credential path and read_external_sources and more #28
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Codecov Report
@@ Coverage Diff @@
## next #28 +/- ##
==========================================
- Coverage 98.18% 98.15% -0.04%
==========================================
Files 16 16
Lines 497 488 -9
==========================================
- Hits 488 479 -9
Misses 9 9
Continue to review full report at Codecov.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Left a few comments that will need changes...
ibm_cloud_sdk_core/utils.py
Outdated
authenticator = None | ||
config = read_external_sources(service_name) | ||
if config: | ||
authenticator = contruct_authenticator(config) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/contruct/construct/
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, "construct_authenticator" could probably be private since it should only be called from inside the get_authenticator_from_environment public method.
ibm_cloud_sdk_core/base_service.py
Outdated
@@ -65,7 +65,7 @@ def __init__(self, | |||
|
|||
if display_name: | |||
service_name = display_name.replace(' ', '_').lower() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we also need to replace '-' with '_' in the service_name value. Some values for the vcap services name have -'s in them.
ibm_cloud_sdk_core/utils.py
Outdated
@@ -100,16 +111,16 @@ def read_from_credential_file(service_name, separator='='): | |||
# File path specified by an env variable | |||
credential_file_path = getenv('IBM_CREDENTIALS_FILE') | |||
|
|||
# Home directory | |||
# Top-level of the project directory |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is actually the "Current working directory", right?
ibm_cloud_sdk_core/utils.py
Outdated
@@ -125,15 +136,15 @@ def read_from_credential_file(service_name, separator='='): | |||
return config | |||
|
|||
def _parse_key_and_update_config(config, service_name, key, value): | |||
if service_name in key: | |||
if key.startswith(service_name): | |||
index = key.find('_') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think this works if the service_name contains an "_" does it???
You can see the logic that's used by the java core in CredentialUtils.parseCredentials()
, to parse a line from either a credential file or an env var setting, which looks like this:
serviceName = serviceName.toUpperCase().replaceAll("-", "_") + "_";
...
if (key.startsWith(serviceName)) {
String credentialName = key.substring(serviceName.length());
...
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This will work as before calling the _parse_key_and_update_config
, the calling function perform's the replace
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The service_name passed into _parse_key_and_update_config
could have an "_" in it, so this code fragment won't work:
if key.startswith(service_name):
index = key.find('_')
if index != -1:
config[key[index + 1:]] = value
If this code is processing a key of "personality_insights_url", you'd end up with a config map with this entry:
"insights_url" --> <url value>
Right?
Please add a test that includes a multi-word service name and you will find out exactly what happens.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ahaaa I see that the truncation happening here! Good catch! 👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
More changes needed.
ibm_cloud_sdk_core/utils.py
Outdated
@@ -125,15 +136,15 @@ def read_from_credential_file(service_name, separator='='): | |||
return config | |||
|
|||
def _parse_key_and_update_config(config, service_name, key, value): | |||
if service_name in key: | |||
if key.startswith(service_name): | |||
index = key.find('_') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The service_name passed into _parse_key_and_update_config
could have an "_" in it, so this code fragment won't work:
if key.startswith(service_name):
index = key.find('_')
if index != -1:
config[key[index + 1:]] = value
If this code is processing a key of "personality_insights_url", you'd end up with a config map with this entry:
"insights_url" --> <url value>
Right?
Please add a test that includes a multi-word service name and you will find out exactly what happens.
resources/ibm-credentials-iam.env
Outdated
WATSON_AUTH_TYPE=iam | ||
WATSON_URL=https://gateway-s.watsonplatform.net/watson/api | ||
WATSON_DISABLE_SSL=False |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add some test properties that include a multi-word service name, rather than just "WATSON".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Erika can you add these tests properties?
@padamstx addressed the multi word service name issue. |
if display_name: | ||
service_name = display_name.replace(' ', '_').lower() | ||
config = read_from_env_variables(service_name) | ||
if config.get('url'): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
setting of client properties go in the generated service classes
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Getting closer, but more changes needed
ibm_cloud_sdk_core/utils.py
Outdated
if service_name in key: | ||
index = key.find('_') | ||
service_name = service_name.replace(' ', '_').replace('-', '_').lower() | ||
key = key.replace(' ', '_').replace('-', '_').lower() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You shouldn't need to replace any characters in key
as that is either a cred file property or an environment variable name.
Also, instead of folding service_name
to lowercase, you could fold it to upper case when using it to parse property names from a credential file or environment variables and then just leave key
alone. The credential file properties and environment variables should already be in upper case.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But for consistency isn't it better to have the key and service_name both converted?
What if a user has a environment variable like IBM-WATSON_USERNAME
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If the user doesn't follow the conventions, there's not much we can do about that. My opinion is that we shouldn't be changing the configuration data (cred file properties/env variables/VCAP_SERVICES) that the user has defined.
ibm_cloud_sdk_core/utils.py
Outdated
service_name = service_name.replace(' ', '_').replace('-', '_').lower() | ||
key = key.replace(' ', '_').replace('-', '_').lower() | ||
if key.startswith(service_name): | ||
index = key.find(service_name) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
since we entered this block because key
starts with service_name
, you shouldn't need to do a find at all, right?
since the key starts with the service_name the index should always be 0 (or 1, whatever index the first character has).
Please see the logic in the CredentialUtils.parseCredentials() function:
https://github.com/IBM/java-sdk-core/blob/e3d5330b0d9e2ef9cf084cb7c6aa97d6ae4f1fb4/src/main/java/com/ibm/cloud/sdk/core/util/CredentialUtils.java#L352
Specifically this:
serviceName = serviceName.toUpperCase().replaceAll("-", "_") + "_";
...
if (key.startsWith(serviceName)) {
String credentialName = key.substring(serviceName.length());
Note that this function changes the serviceName value to do the character replacement AND adds a "_"
on the end so that the updated value of serviceName (e.g. PERSONALITY_INSIGHTS_
) will serve as the actual "prefix" that we'd expect to see in property and env variable names. Because we add the trailing "_"
on the end, there's no +1
needed when we compute the length of serviceName.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agree that I don't need to use find to get index, but how can we guarantee that the key would always be uppercase? I would prefer we transform both so that we perform the correct string matching
ibm_cloud_sdk_core/utils.py
Outdated
|
||
def read_from_vcap_services(service_name): | ||
service_name = service_name.replace(' ', '_').lower() | ||
service_name = service_name.replace(' ', '_').replace('-', '_').lower() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When we get config info from VCAP_SERVICES, we should not do any transformations on service_name
at all.
This is because the exact service name is configured in the API definition and is inserted into the generated code and should be used as-is. So, a vcap services name obtained from the API definition of personality-insights
is the exact string that we'd expect to find within VCAP_SERVICES.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I perform the key conversion here: https://github.com/IBM/python-sdk-core/pull/28/files#diff-7048c45d573bb78c4bac9b0291b4e065R152 so that when service_name = personality-insights
and vcap name is personality-insights
would both be converted to personality_insights
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why? All you need to do is compare the "as-is" service_name as it was generated in the service and compare it with the outer-most map key within the VCAP_SERVICES json object. By trying to do all these extra, unnecessary transformations, you're actually accepting a different "language" than the other cores.
ibm_cloud_sdk_core/utils.py
Outdated
if service_name in key: | ||
index = key.find('_') | ||
service_name = service_name.replace(' ', '_').replace('-', '_').lower() | ||
key = key.replace(' ', '_').replace('-', '_').lower() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If the user doesn't follow the conventions, there's not much we can do about that. My opinion is that we shouldn't be changing the configuration data (cred file properties/env variables/VCAP_SERVICES) that the user has defined.
ibm_cloud_sdk_core/utils.py
Outdated
|
||
def read_from_vcap_services(service_name): | ||
service_name = service_name.replace(' ', '_').lower() | ||
service_name = service_name.replace(' ', '_').replace('-', '_').lower() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why? All you need to do is compare the "as-is" service_name as it was generated in the service and compare it with the outer-most map key within the VCAP_SERVICES json object. By trying to do all these extra, unnecessary transformations, you're actually accepting a different "language" than the other cores.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good. I left one comment as a potential to-do item for when we implement the service config feature. One other future to-do item might be add a test involving VCAP_SERVICES for the "ibm-watson" service, but that can wait until we implement the service config feature I think.
def contruct_authenticator(config): | ||
auth_type = config.get('auth_type').lower() if config.get('auth_type') else 'iam' | ||
def _construct_authenticator(config): | ||
auth_type = config.get('AUTH_TYPE').lower() if config.get('AUTH_TYPE') else 'iam' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I didn't comment on this before, and I don't think we need to change anything right now, but... when we implement the service config feature, it might be good to define constants for the various config properties rather than use the literal strings like this.
🎉 This PR is included in version 1.0.0 🎉 The release is available on GitHub release Your semantic-release bot 📦🚀 |
This PR does the following:
disable_ssl
andurl
were read only from env, so like rest of the sdk's separated aread_external_sources
related to https://github.ibm.com/Watson/developer-experience/issues/7521