add ecs ram authorization support

This commit is contained in:
York.GU 2020-02-21 21:30:32 +08:00
parent 397afbfa4f
commit 31e32529e0
2 changed files with 39 additions and 2 deletions

View File

@ -19,4 +19,5 @@ return [
'group' => env('ALIYUN_ACM_GROUP', 'DEFAULT_GROUP'), 'group' => env('ALIYUN_ACM_GROUP', 'DEFAULT_GROUP'),
'access_key' => env('ALIYUN_ACM_AK', ''), 'access_key' => env('ALIYUN_ACM_AK', ''),
'secret_key' => env('ALIYUN_ACM_SK', ''), 'secret_key' => env('ALIYUN_ACM_SK', ''),
'ecs_ram_role' => env('ALIYUN_ACM_RAM_ROLE', ''),
]; ];

View File

@ -47,10 +47,12 @@ class Client implements ClientInterface
*/ */
private $servers; private $servers;
private $cachedSecurityCredentials = [];
public function __construct(ContainerInterface $container) public function __construct(ContainerInterface $container)
{ {
/** /**
* @var GuzzleClientFactory $clientFactory * @var GuzzleClientFactory
*/ */
$clientFactory = $container->get(GuzzleClientFactory::class); $clientFactory = $container->get(GuzzleClientFactory::class);
$this->client = $clientFactory->create(); $this->client = $clientFactory->create();
@ -72,6 +74,16 @@ class Client implements ClientInterface
$group = $this->config->get('aliyun_acm.group', 'DEFAULT_GROUP'); $group = $this->config->get('aliyun_acm.group', 'DEFAULT_GROUP');
$accessKey = $this->config->get('aliyun_acm.access_key', ''); $accessKey = $this->config->get('aliyun_acm.access_key', '');
$secretKey = $this->config->get('aliyun_acm.secret_key', ''); $secretKey = $this->config->get('aliyun_acm.secret_key', '');
$ecsRamRole = $this->config->get('aliyun_acm.ecs_ram_role', '');
$securityToken = null;
if (empty($accessKey) && ! empty($ecsRamRole)) {
$securityCredentials = $this->getSecurityCredentialsWithEcsRamRole($ecsRamRole);
if (! empty($securityCredentials)) {
$accessKey = $securityCredentials['AccessKeyId'];
$secretKey = $securityCredentials['AccessKeySecret'];
$securityToken = $securityCredentials['SecurityToken'];
}
}
// Sign // Sign
$timestamp = round(microtime(true) * 1000); $timestamp = round(microtime(true) * 1000);
@ -94,7 +106,8 @@ class Client implements ClientInterface
'Spas-AccessKey' => $accessKey, 'Spas-AccessKey' => $accessKey,
'timeStamp' => $timestamp, 'timeStamp' => $timestamp,
'Spas-Signature' => $sign, 'Spas-Signature' => $sign,
'Content-Type' => 'application/x-www-form-urlencoded; charset=utf-8' 'Spas-SecurityToken' => $securityToken ?? '',
'Content-Type' => 'application/x-www-form-urlencoded; charset=utf-8',
], ],
'query' => [ 'query' => [
'tenant' => $namespace, 'tenant' => $namespace,
@ -115,4 +128,27 @@ class Client implements ClientInterface
return []; return [];
} }
} }
/**
* get ECS RAM authorization.
* @see https://help.aliyun.com/document_detail/72013.html
*/
private function getSecurityCredentialsWithEcsRamRole(string $ecsRamRole): ?array
{
$securityCredentials = $this->cachedSecurityCredentials[$ecsRamRole] ?? null;
if (! empty($securityCredentials) && time() > strtotime($securityCredentials['Expiration']) - 60) {
$securityCredentials = null;
}
if (empty($securityCredentials)) {
$response = $this->client->get('http://100.100.100.200/latest/meta-data/ram/security-credentials/' . $ecsRamRole);
if ($response->getStatusCode() !== 200) {
throw new RuntimeException('Get config failed from Aliyun ACM.');
}
$securityCredentials = Json::decode($response->getBody()->getContents());
if (! empty($securityCredentials)) {
$this->cachedSecurityCredentials[$ecsRamRole] = $securityCredentials;
}
}
return $securityCredentials;
}
} }