Skip to content
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

enhancement: user agent 2.1 #3001

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 35 additions & 10 deletions src/AwsClient.php
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,7 @@ public function __construct(array $args)
if (isset($args['with_resolved'])) {
$args['with_resolved']($config);
}
$this->addUserAgentMiddleware($config);
}

public function getHandlerList()
Expand Down Expand Up @@ -449,7 +450,7 @@ private function addSignatureMiddleware(array $args)
}

$resolver = static function (
CommandInterface $c
CommandInterface $command
) use (
$api,
$provider,
Expand All @@ -460,17 +461,17 @@ private function addSignatureMiddleware(array $args)
$signingRegionSet
) {
if (!$configuredSignatureVersion) {
if (!empty($c['@context']['signing_region'])) {
$region = $c['@context']['signing_region'];
if (!empty($command['@context']['signing_region'])) {
$region = $command['@context']['signing_region'];
}
if (!empty($c['@context']['signing_service'])) {
$name = $c['@context']['signing_service'];
if (!empty($command['@context']['signing_service'])) {
$name = $command['@context']['signing_service'];
}
if (!empty($c['@context']['signature_version'])) {
$signatureVersion = $c['@context']['signature_version'];
if (!empty($command['@context']['signature_version'])) {
$signatureVersion = $command['@context']['signature_version'];
}

$authType = $api->getOperation($c->getName())['authtype'];
$authType = $api->getOperation($command->getName())['authtype'];
switch ($authType){
case 'none':
$signatureVersion = 'anonymous';
Expand All @@ -485,15 +486,21 @@ private function addSignatureMiddleware(array $args)
}

if ($signatureVersion === 'v4a') {
$commandSigningRegionSet = !empty($c['@context']['signing_region_set'])
? implode(', ', $c['@context']['signing_region_set'])
$commandSigningRegionSet = !empty($command['@context']['signing_region_set'])
? implode(', ', $command['@context']['signing_region_set'])
: null;

$region = $signingRegionSet
?? $commandSigningRegionSet
?? $region;
}

// Capture signature metric
$command->getMetricsBuilder()->identifyMetricByValueAndAppend(
'signature',
$signatureVersion
);

return SignatureProvider::resolve($provider, $signatureVersion, $name, $region);
};
$this->handlerList->appendSign(
Expand Down Expand Up @@ -611,6 +618,24 @@ private function addEndpointV2Middleware()
);
}

/**
* Appends the user agent middleware.
* This middleware MUST be appended after the
* signature middleware `addSignatureMiddleware`,
* so that metrics around signatures are properly
* captured.
*
* @param $args
* @return void
*/
private function addUserAgentMiddleware($args)
{
$this->getHandlerList()->appendSign(
UserAgentMiddleware::wrap($args),
'user-agent'
);
}

/**
* Retrieves client context param definition from service model,
* creates mapping of client context param names with client-provided
Expand Down
84 changes: 1 addition & 83 deletions src/ClientResolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -980,66 +980,8 @@ public static function _default_app_id(array $args)

public static function _apply_user_agent($inputUserAgent, array &$args, HandlerList $list)
yenfryherrerafeliz marked this conversation as resolved.
Show resolved Hide resolved
{
// Add SDK version
$userAgent = ['aws-sdk-php/' . Sdk::VERSION];

// User Agent Metadata
$userAgent[] = 'ua/2.0';

// If on HHVM add the HHVM version
if (defined('HHVM_VERSION')) {
$userAgent []= 'HHVM/' . HHVM_VERSION;
}

// Add OS version
$disabledFunctions = explode(',', ini_get('disable_functions'));
if (function_exists('php_uname')
&& !in_array('php_uname', $disabledFunctions, true)
) {
$osName = "OS/" . php_uname('s') . '#' . php_uname('r');
if (!empty($osName)) {
$userAgent []= $osName;
}
}

// Add the language version
$userAgent []= 'lang/php#' . phpversion();

// Add exec environment if present
if ($executionEnvironment = getenv('AWS_EXECUTION_ENV')) {
$userAgent []= $executionEnvironment;
}

// Add endpoint discovery if set
if (isset($args['endpoint_discovery'])) {
if (($args['endpoint_discovery'] instanceof \Aws\EndpointDiscovery\Configuration
&& $args['endpoint_discovery']->isEnabled())
) {
$userAgent []= 'cfg/endpoint-discovery';
} elseif (is_array($args['endpoint_discovery'])
&& isset($args['endpoint_discovery']['enabled'])
&& $args['endpoint_discovery']['enabled']
) {
$userAgent []= 'cfg/endpoint-discovery';
}
}

// Add retry mode if set
if (isset($args['retries'])) {
if ($args['retries'] instanceof \Aws\Retry\Configuration) {
$userAgent []= 'cfg/retry-mode#' . $args["retries"]->getMode();
} elseif (is_array($args['retries'])
&& isset($args["retries"]["mode"])
) {
$userAgent []= 'cfg/retry-mode#' . $args["retries"]["mode"];
}
}

// AppID Metadata
if (!empty($args['app_id'])) {
$userAgent[] = 'app/' . $args['app_id'];
}

$userAgent = [];
// Add the input to the end
if ($inputUserAgent){
if (!is_array($inputUserAgent)) {
Expand All @@ -1050,30 +992,6 @@ public static function _apply_user_agent($inputUserAgent, array &$args, HandlerL
}

$args['ua_append'] = $userAgent;

$list->appendBuild(static function (callable $handler) use ($userAgent) {
return function (
CommandInterface $command,
RequestInterface $request
) use ($handler, $userAgent) {
return $handler(
$command,
$request->withHeader(
'X-Amz-User-Agent',
implode(' ', array_merge(
$userAgent,
$request->getHeader('X-Amz-User-Agent')
))
)->withHeader(
'User-Agent',
implode(' ', array_merge(
$userAgent,
$request->getHeader('User-Agent')
))
)
);
};
});
}

public static function _apply_endpoint($value, array &$args, HandlerList $list)
Expand Down
25 changes: 23 additions & 2 deletions src/Command.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,12 @@ class Command implements CommandInterface
/** @var HandlerList */
private $handlerList;

/** @var Array */
/** @var array */
private $authSchemes;

/** @var MetricsBuilder */
private $metricsBuilder;

/**
* Accepts an associative array of command options, including:
*
Expand All @@ -26,7 +29,12 @@ class Command implements CommandInterface
* @param array $args Arguments to pass to the command
* @param HandlerList $list Handler list
*/
public function __construct($name, array $args = [], ?HandlerList $list = null)
public function __construct(
$name,
array $args = [],
?HandlerList $list = null,
?MetricsBuilder $metricsBuilder = null
)
{
$this->name = $name;
$this->data = $args;
Expand All @@ -38,6 +46,7 @@ public function __construct($name, array $args = [], ?HandlerList $list = null)
if (!isset($this->data['@context'])) {
$this->data['@context'] = [];
}
$this->metricsBuilder = $metricsBuilder ?: new MetricsBuilder();
}

public function __clone()
Expand Down Expand Up @@ -110,4 +119,16 @@ public function get($name)
{
return $this[$name];
}

/**
* Returns the metrics builder instance tied up to this command.
*
* @internal
*
* @return MetricsBuilder
*/
public function getMetricsBuilder(): MetricsBuilder
{
return $this->metricsBuilder;
}
}
5 changes: 4 additions & 1 deletion src/Credentials/AssumeRoleCredentialProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,10 @@ public function __invoke()
$client = $this->client;
return $client->assumeRoleAsync($this->assumeRoleParams)
->then(function (Result $result) {
return $this->client->createCredentials($result);
return $this->client->createCredentials(
$result,
CredentialSources::STS_ASSUME_ROLE
);
})->otherwise(function (\RuntimeException $exception) {
throw new CredentialsException(
"Error in retrieving assume role credentials.",
Expand Down
24 changes: 14 additions & 10 deletions src/Credentials/AssumeRoleWithWebIdentityCredentialProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,17 @@ class AssumeRoleWithWebIdentityCredentialProvider

/** @var integer */
private $tokenFileReadAttempts;
/** @var string */
private $source;

/**
* The constructor attempts to load config from environment variables.
* If not set, the following config options are used:
* - WebIdentityTokenFile: full path of token filename
* - RoleArn: arn of role to be assumed
* - SessionName: (optional) set by SDK if not provided
* - source: To identify if the provider was sourced by a profile or
* from environment definition. Default will be `sts_web_id_token`.
*
* @param array $config Configuration options
* @throws \InvalidArgumentException
Expand All @@ -66,15 +70,9 @@ public function __construct(array $config = [])
$this->retries = (int) getenv(self::ENV_RETRIES) ?: (isset($config['retries']) ? $config['retries'] : 3);
$this->authenticationAttempts = 0;
$this->tokenFileReadAttempts = 0;

$this->session = isset($config['SessionName'])
? $config['SessionName']
: 'aws-sdk-php-' . round(microtime(true) * 1000);

$region = isset($config['region'])
? $config['region']
: 'us-east-1';

$this->session = $config['SessionName']
?? 'aws-sdk-php-' . round(microtime(true) * 1000);
$region = $config['region'] ?? 'us-east-1';
if (isset($config['client'])) {
$this->client = $config['client'];
} else {
Expand All @@ -84,6 +82,9 @@ public function __construct(array $config = [])
'version' => 'latest'
]);
}

$this->source = $config['source']
?? CredentialSources::STS_WEB_ID_TOKEN;
}

/**
Expand Down Expand Up @@ -160,7 +161,10 @@ public function __invoke()
$this->authenticationAttempts++;
}

yield $this->client->createCredentials($result);
yield $this->client->createCredentials(
$result,
$this->source
);
});
}
}
26 changes: 18 additions & 8 deletions src/Credentials/CredentialProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -302,7 +302,8 @@ public static function env()
$secret,
$token,
null,
$accountId
$accountId,
CredentialSources::ENVIRONMENT
)
);
}
Expand Down Expand Up @@ -417,7 +418,8 @@ public static function assumeRoleWithWebIdentityCredentialProvider(array $config
'WebIdentityTokenFile' => $tokenFromEnv,
'SessionName' => $sessionName,
'client' => $stsClient,
'region' => $region
'region' => $region,
'source' => CredentialSources::ENVIRONMENT_STS_WEB_ID_TOKEN
]);

return $provider();
Expand Down Expand Up @@ -446,7 +448,8 @@ public static function assumeRoleWithWebIdentityCredentialProvider(array $config
'WebIdentityTokenFile' => $profile['web_identity_token_file'],
'SessionName' => $sessionName,
'client' => $stsClient,
'region' => $region
'region' => $region,
'source' => CredentialSources::PROFILE_STS_WEB_ID_TOKEN
]);

return $provider();
Expand Down Expand Up @@ -553,7 +556,8 @@ public static function ini($profile = null, $filename = null, array $config = []
$data[$profile]['aws_secret_access_key'],
$data[$profile]['aws_session_token'],
null,
!empty($data[$profile]['aws_account_id']) ? $data[$profile]['aws_account_id'] : null
$data[$profile]['aws_account_id'] ?? null,
CredentialSources::PROFILE
)
);
};
Expand Down Expand Up @@ -641,7 +645,8 @@ public static function process($profile = null, $filename = null)
$processData['SecretAccessKey'],
$processData['SessionToken'],
$expires,
$accountId
$accountId,
CredentialSources::PROFILE_PROCESS
)
);
};
Expand Down Expand Up @@ -724,7 +729,10 @@ private static function loadRoleProfile(
'RoleArn' => $roleArn,
'RoleSessionName' => $roleSessionName
]);
$credentials = $stsClient->createCredentials($result);
$credentials = $stsClient->createCredentials(
$result,
CredentialSources::STS_ASSUME_ROLE
);

return Promise\Create::promiseFor($credentials);
}
Expand Down Expand Up @@ -918,7 +926,8 @@ private static function getSsoCredentials($profiles, $ssoProfileName, $filename,
$ssoCredentials['secretAccessKey'],
$ssoCredentials['sessionToken'],
$expiration,
$ssoProfile['sso_account_id']
$ssoProfile['sso_account_id'],
CredentialSources::PROFILE_SSO
)
);
}
Expand Down Expand Up @@ -978,7 +987,8 @@ private static function getSsoCredentialsLegacy($profiles, $ssoProfileName, $fil
$ssoCredentials['secretAccessKey'],
$ssoCredentials['sessionToken'],
$expiration,
$ssoProfile['sso_account_id']
$ssoProfile['sso_account_id'],
CredentialSources::PROFILE_SSO_LEGACY
)
);
}
Expand Down
Loading