Skip to content

Conversation

ljstrnadiii
Copy link
Contributor

What does this PR do?

Adds support for https://docs.aws.amazon.com/sdkref/latest/guide/feature-process-credentials.html.

Please note I am not a C++ developer and solely used copilot. Happy to close this in favor of a better implementation or receive guidance on how to get this in if this is a feature GDAL would like to incorporate 🙏.

What are related issues/pull requests?

Tasklist

  • AI (Copilot or something similar) supported my development of this PR
  • Make sure code is correctly formatted (cf pre-commit configuration)
  • Add test case(s)
  • Add documentation
  • Updated Python API documentation (swig/include/python/docs/)
  • Review
  • Adjust for comments
  • All CI builds and checks have passed
  • ADD YOUR TASKS HERE

Environment

Provide environment details, if relevant:

  • OS:
  • Compiler:

get or refresh

port/cpl_aws: support process_credentials
@jiayuasu
Copy link

@Kontinuation Can you take a look?

Comment on lines +1779 to +1781
CPLError(CE_Failure, CPLE_AppDefined,
"Failed to execute credential_process: %s",
osCredentialProcess.c_str());

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we include VSIStrerror(errno) in the error message to show the reason why popen failed?

CPLStringList aosOptions;
aosOptions.SetNameValue("TIMEOUT", "30");

FILE *fp = popen(osCredentialProcess.c_str(), "r");

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we use CPL-family functions in cpl_spawn.h such as CPLPipeRead for multi-platform compatibility instead of directly calling POSIX API here?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes please use CPLSpawn(). You'll need to tokenize the command line using CSLTokenizeString2(osCredetialsProcess.c_str(), " ", CSLT_HONOURSTRINGS)

Comment on lines +1846 to +1858
if (osSessionToken.empty())
{
CPLError(CE_Failure, CPLE_AppDefined,
"credential_process did not return required SessionToken");
return false;
}

if (osExpiration.empty())
{
CPLError(CE_Failure, CPLE_AppDefined,
"credential_process did not return required Expiration");
return false;
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are these required fields? At least Expiration is not required according to https://docs.aws.amazon.com/sdkref/latest/guide/feature-process-credentials.html#feature-process-credentials-output

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point. I'll handle the optional case.

}

// Release mutex before calling external process
oHolder.~CPLMutexHolder();

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A common practice is to use CPLMutexHolderD and wrap everything in critical section using a proper lexical scope.

CPLStringList aosOptions;
aosOptions.SetNameValue("TIMEOUT", "30");

FILE *fp = popen(osCredentialProcess.c_str(), "r");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes please use CPLSpawn(). You'll need to tokenize the command line using CSLTokenizeString2(osCredetialsProcess.c_str(), " ", CSLT_HONOURSTRINGS)

return true;
}

if (!osCredentialProcess.empty())
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this block should likely be moved in the above scope before the return true at line 2157. And it should call GetCredentialsFromProcess() insead of GetOrRefreshTemporaryCredentialsForProcess(), and it should return false if GetCredentialsFromProcess() returns false

Comment on lines +2499 to +2531
// First, check if we have a cached credential_process command
std::string osCredentialProcess;
{
CPLMutexHolder oHolder(&ghMutex);
osCredentialProcess = gosCredentialProcessCommand;
}

// If no cached command, re-read config files to get the credential_process setting
if (osCredentialProcess.empty())
{
std::string osSecretAccessKey, osAccessKeyId, osSessionToken,
osRegion;
std::string osCredentials, osRoleArn, osSourceProfile, osExternalId;
std::string osMFASerial, osRoleSessionName, osWebIdentityTokenFile;
std::string osSSOStartURL, osSSOAccountID, osSSORoleName,
osSSOSession;

if (GetConfigurationFromAWSConfigFiles(
osPathForOption, nullptr, osSecretAccessKey, osAccessKeyId,
osSessionToken, osRegion, osCredentials, osRoleArn,
osSourceProfile, osExternalId, osMFASerial,
osRoleSessionName, osWebIdentityTokenFile, osSSOStartURL,
osSSOAccountID, osSSORoleName, osSSOSession,
osCredentialProcess))
{
// Cache the command for future use
CPLMutexHolder oHolder(&ghMutex);
gosCredentialProcessCommand = osCredentialProcess;
}
}

// Now use the cached refresh mechanism
if (!osCredentialProcess.empty())
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe all of his should be deleted, so as to be "symetric" with the other credential soures

echo '{"AccessKeyId":"AWS_ACCESS_KEY_ID","SecretAccessKey":"AWS_SECRET_ACCESS_KEY","SessionToken":"session_token","Expiration":"2025-01-01T12:00:00Z"}'
"""

with tempfile.NamedTemporaryFile(mode="w", suffix=".sh", delete=False) as f:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

instead of a shell script, you could use a python script to be platform independent, and use something like "credential_process = {sys.executable} {script_path}" in the aws_config file

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants