152 lines
4.8 KiB
PHP
Executable File
152 lines
4.8 KiB
PHP
Executable File
<?php
|
|
/**
|
|
* Huawei Cloud API Library
|
|
* Authentification AK/SK officielle
|
|
*/
|
|
|
|
class HuaweiCloudAPI {
|
|
private $ak;
|
|
private $sk;
|
|
private $region;
|
|
private $projectId;
|
|
|
|
public function __construct($ak, $sk, $region, $projectId) {
|
|
$this->ak = $ak;
|
|
$this->sk = $sk;
|
|
$this->region = $region;
|
|
$this->projectId = $projectId;
|
|
}
|
|
|
|
private function sign($method, $url, $headers, $body = '') {
|
|
$parsedUrl = parse_url($url);
|
|
$host = $parsedUrl['host'];
|
|
$path = $parsedUrl['path'] ?? '/';
|
|
$query = $parsedUrl['query'] ?? '';
|
|
|
|
$time = gmdate('Ymd\THis\Z');
|
|
$date = gmdate('Ymd');
|
|
|
|
// Ajouter les headers requis
|
|
$headers['Host'] = $host;
|
|
$headers['X-Sdk-Date'] = $time;
|
|
|
|
// Trier les headers
|
|
ksort($headers);
|
|
|
|
// Construire les headers canoniques
|
|
$canonicalHeaders = '';
|
|
$signedHeaders = [];
|
|
foreach ($headers as $key => $value) {
|
|
$lowerKey = strtolower($key);
|
|
$canonicalHeaders .= $lowerKey . ':' . trim($value) . "\n";
|
|
$signedHeaders[] = $lowerKey;
|
|
}
|
|
$signedHeadersStr = implode(';', $signedHeaders);
|
|
|
|
// Hash du body
|
|
$hashedPayload = hash('sha256', $body);
|
|
|
|
// Requête canonique
|
|
$canonicalRequest = $method . "\n" .
|
|
$path . "\n" .
|
|
$query . "\n" .
|
|
$canonicalHeaders . "\n" .
|
|
$signedHeadersStr . "\n" .
|
|
$hashedPayload;
|
|
|
|
// String to sign
|
|
$algorithm = 'SDK-HMAC-SHA256';
|
|
$hashedCanonicalRequest = hash('sha256', $canonicalRequest);
|
|
$stringToSign = $algorithm . "\n" . $time . "\n" . $hashedCanonicalRequest;
|
|
|
|
// Calculer la signature
|
|
$signature = hash_hmac('sha256', $stringToSign, $this->sk);
|
|
|
|
// Construire l'en-tête Authorization
|
|
$authorization = $algorithm . ' ' .
|
|
'Access=' . $this->ak . ', ' .
|
|
'SignedHeaders=' . $signedHeadersStr . ', ' .
|
|
'Signature=' . $signature;
|
|
|
|
$headers['Authorization'] = $authorization;
|
|
|
|
return $headers;
|
|
}
|
|
|
|
public function call($service, $method, $endpoint, $data = null) {
|
|
$host = "$service.{$this->region}.myhuaweicloud.com";
|
|
$url = "https://$host$endpoint";
|
|
$body = $data ? json_encode($data) : '';
|
|
|
|
$headers = [
|
|
'Content-Type' => 'application/json'
|
|
];
|
|
|
|
$signedHeaders = $this->sign($method, $url, $headers, $body);
|
|
|
|
$curlHeaders = [];
|
|
foreach ($signedHeaders as $key => $value) {
|
|
$curlHeaders[] = "$key: $value";
|
|
}
|
|
|
|
$ch = curl_init();
|
|
curl_setopt($ch, CURLOPT_URL, $url);
|
|
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
|
curl_setopt($ch, CURLOPT_HTTPHEADER, $curlHeaders);
|
|
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
|
|
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
|
|
|
|
if ($method === 'POST') {
|
|
curl_setopt($ch, CURLOPT_POST, true);
|
|
curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
|
|
}
|
|
|
|
$response = curl_exec($ch);
|
|
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
|
$error = curl_error($ch);
|
|
curl_close($ch);
|
|
|
|
return [
|
|
'code' => $httpCode,
|
|
'body' => json_decode($response, true),
|
|
'raw' => $response,
|
|
'error' => $error
|
|
];
|
|
}
|
|
|
|
public function listVPCs() {
|
|
return $this->call('vpc', 'GET', "/v1/{$this->projectId}/vpcs");
|
|
}
|
|
|
|
public function listSubnets() {
|
|
return $this->call('vpc', 'GET', "/v1/{$this->projectId}/subnets");
|
|
}
|
|
|
|
public function listSecurityGroups() {
|
|
return $this->call('vpc', 'GET', "/v1/{$this->projectId}/security-groups");
|
|
}
|
|
|
|
public function listFlavors() {
|
|
return $this->call('ecs', 'GET', "/v1/{$this->projectId}/cloudservers/flavors");
|
|
}
|
|
|
|
public function createServer($name, $flavorId, $imageId, $vpcId, $subnetId, $securityGroupId, $password) {
|
|
$data = [
|
|
'server' => [
|
|
'name' => $name,
|
|
'flavorRef' => $flavorId,
|
|
'imageRef' => $imageId,
|
|
'vpcid' => $vpcId,
|
|
'nics' => [['subnet_id' => $subnetId]],
|
|
'security_groups' => [['id' => $securityGroupId]],
|
|
'root_volume' => ['volumetype' => 'SSD', 'size' => 40],
|
|
'adminPass' => $password,
|
|
'availability_zone' => $this->region . 'a',
|
|
'count' => 1
|
|
]
|
|
];
|
|
return $this->call('ecs', 'POST', "/v1/{$this->projectId}/cloudservers", $data);
|
|
}
|
|
}
|
|
|