I. Déploiement de l'API :

 
Sélectionnez
<?php
			// Liste complète des appels possibles : http://download.cloud.com/releases/3.0.6/api_3.0.6/TOC_User.html
 
			################################
			# Paramètres généraux de l'API #
			################################
 
			// Renseignez ici votre clef API ainsi que votre clef secrète
			// Nous conseillons de déporter cette information au sein d'un autre fichier PHP dont on restreindra l'accès
			define("APIKEY","d1Ii4ON33yqUahgtlsjnzK0o7QXNzXZONZKcW_rDcOV4jln48b5ujsSvU-mo9KsoLbp631VyCI4fLb3u176JZg");
			define("SECRETKEY","fBenapO2hjOd3Vaj-NDmrekTIK85B8Jl_m8wFld4gi0XvLXy4w0iJz-2srztoVqkGVoblT25DyG4709gibo_TA");
 
			//On définit l'URL d'appel de l'API (ou 'EndPoint')
			define("ENDPOINT","https://cloudstack.ikoula.com/client/api");
 
			#############################################################
			# Paramètres utilisateur de configuration d(es) instance(s) #
			#############################################################
 
			//Première instance :  
			/* UUID(s) du réseau auquel sera connectée votre instance.  
			Utilisez la requête API 'listNetworks' ou l'interface pour lister les réseaux existants et déterminer le réseau voulu  
			*/  
			$vm01['conf']['networkid'] = "&lt;ID DU RESEAU QUE VOUS SOUHAITEZ UTILISER>";  
			/* UUID de l'offre de service (configuration matérielle) voulue.  
			Utilisez la requête API 'listServiceOfferings' pour lister les offres existantes.  
			Actuellement :  
			- m1.small : c6b89fea-1242-4f54-b15e-9d8ec8a0b7e8  
			- m1.medium : 8dae8be9-5dae-4f81-89d1-b171f25ef3fd  
			- m1.large : d2b2e7b9-4ffa-419e-9ef1-6d413f08deab  
			- m1.extralarge : 1412009f-0e89-4cfc-a681-1cda0631094b  
			*/  
			$vm01['conf']['serviceofferingid'] = "&lt;ID DE L'OFFRE DE SERVICE A UTILISER>";  
			/* UUID du modèle de systeme d'exploitation.  
			Vous pouvez aussi utiliser la requête API 'listTemplates' pour lister les modèles existants.  
			Dans notre exemple nous allons nous baser sur le template 'Debian 7 - Minimal - 64bits'  
			*/  
			$vm01['conf']['templateid'] = "6d5b069b-4268-4c7c-810f-2793c2ac44fb";  
			/* Nom de votre choix pour l'instance (Nom de la machine et d'affichage dans l'interface)  
			Caractères alphanumériques uniquement. Ce nom doit être unique au sein de votre réseau. */  
			$vm01['conf']['hostname'] = "&lt;NOM DE VOTRE INSTANCE>";  
			/* ------------------------------ NE PLUS RIEN MODIFIER APRES CETTE LIGNE ----------------------------------- */  
			$json_response = null;  
 
			################################################  
			# Récupération de l'ID de zone pour ce network #  
			################################################  
 
			// Requête API  
			$args['command'] = "listNetworks";  
			// On reprend l'ID de réseau renseigné plus tôt  
			$args['id'] = $vm01['conf']['networkid'];  
			// Execution de la requête  
			sendRequest($args, $json_response);  
			// Stockage de l'ID de zone pour ce réseau  
			$vm01['conf']['zoneid'] = $json_response['listnetworksresponse']["network"][0]['zoneid'];  
			// On réinitialise les variables utilisées pour l'envoi de requêtes API  
			unset($args);  
 
			######################################################  
			# Récupération de l'id de l'adresse IP de ce network #  
			######################################################  
 
			// Requête API  
			$args['command'] = "listPublicIpAddresses";  
			$args['associatednetworkid'] = $vm01['conf']['networkid'];  
			// Execution de la requête  
			sendRequest($args, $json_response);  
			// Stockage de l'ID de l'adresse IP publique du réseau  
			$vm01['conf']['publicIPid'] = $json_response['listpublicipaddressesresponse']["publicipaddress"][0]['id'];  
			// On réinitialise les variables utilisées pour l'envoi de requêtes API  
			unset($args);  
 
			####################################  
			# Création de la première instance #  
			####################################  
 
			// Requête API  
			$args['command'] = "deployVirtualMachine";  
			$args['zoneid'] = $vm01['conf']['zoneid'];  
			$args['serviceofferingid'] = $vm01['conf']['serviceofferingid'];  
			$args['templateid'] = $vm01['conf']['templateid'];  
			$args['networkids'] = $vm01['conf']['networkid'];  
			$args['name'] = $vm01['conf']['hostname']; //Hostname  
			$args['displayname'] = $args['name']; //Nom d'affichage  
			//Type de retour : JSON ou XML (par défaut : XML)  
			$args['response'] = "json";  
			//On réinitialise les variables avant l'appel API  
			// Initialisation du client API  
			sendRequest($args, $json_response);  
			//On vérifie la presence d'un Job  
			if(preg_match("/^[0-9a-f\-]+$/", $json_response['deployvirtualmachineresponse']['jobid']) > 0)  
			{  
			$jobs[] = $json_response['deployvirtualmachineresponse']['jobid'];  
			}  
			else{  
			echo "ID de job non trouvé.\n";  
			}  
			//On mémorise la correspondance name/id de l'instance au sein d'un tableau  
			$vm01['conf']['id'] = $json_response['deployvirtualmachineresponse']['id'];  
			//On utilise la fonction de vérification des jobs asynchrones  
			if(!checkJobs($jobs))  
			exit;  
			/*-------------------------------- Création des règles de sortie --------------------------------*/  
			// On réinitialise les variables utilisées pour l'envoi de requêtes API  
			unset($args);  
 
			################  
			# Ping sortant #  
			################  
 
			$args['command'] = "createEgressFirewallRule";  
			$args['networkid'] = $vm01['conf']['networkid'];  
			// Définition du protocole a filtrer ici ICMP (utiliser pour les ping), les protocole sont ICMP/UDP/TCP  
			$args['protocol'] = "ICMP";  
			// Définition du masque réseau qui nous permet d'autoriser certainne IP,  
			// ici nous acceptons "le ping" vers toute les IPs  
			$args['cidrlist'] = "0.0.0.0/0";  
			// On définit le type ICMP le code 8 et une demande d'ECHO (echo-request) cela permet le ping  
			$args['icmptype'] = 8;  
			// On définit le code ICMP le code 0 doit être défini à 0 pour l'utilisation du type 8 pour l'ICMP  
			$args['icmpcode'] = 0;  
			// Execution de la requête  
			sendRequest($args, $json_response);  
			// Traitement de la requête  
			if(preg_match("/^[0-9a-f\-]+$/", $json_response['createegressfirewallruleresponse']['jobid']) > 0)  
			{  
			$jobs[] = $json_response['createegressfirewallruleresponse']['jobid'];  
			}  
			else{  
			echo "ID de job non trouvé.\n";  
			}  
			if(!checkJobs($jobs))  
			exit;  
			// On réinitialise les variables utilisées pour l'envoi de requêtes API  
			unset($args);  
 
			##########################  
			# Protocole HTTP sortant #  
			##########################  
 
			$args['command'] = "createEgressFirewallRule";  
			$args['networkid'] = $vm01['conf']['networkid'];  
			// Définition du protocole a filtrer ici TCP (utiliser par le protocole HTTP), les protocole sont ICMP/UDP/TCP  
			$args['protocol'] = "TCP";  
			// Définition du masque réseau qui nous permet d'autoriser certainne IP,  
			// ici nous accepton la connection vers toute les IP  
			$args['cidrlist'] = "0.0.0.0/0";  
			// Le port de début (port 80 port standart pour le HTTP)  
			$args['startport'] = 80;  
			// Le port de fin (port 80 port standart pour le HTTP)  
			$args['endport'] = 80;  
			// Execution de la requête  
			sendRequest($args, $json_response);  
			// Traitement de la requête  
			if(preg_match("/^[0-9a-f\-]+$/", $json_response['createegressfirewallruleresponse']['jobid']) > 0)  
			{  
			$jobs[] = $json_response['createegressfirewallruleresponse']['jobid'];  
			}  
			else{  
			echo "ID de job non trouvé.\n";  
			}  
			// On réinitialise les variables utilisées pour l'envoi de requêtes API  
			unset($args);  
 
			###########################  
			# Protocole HTTPS sortant #  
			###########################  
 
			// Requête API  
			$args['command'] = "createEgressFirewallRule";  
			$args['networkid'] = $vm01['conf']['networkid'];  
			// Définition du protocole a filtrer ici TCP (utiliser par le protocole HTTPS), les protocole sont ICMP/UDP/TCP  
			$args['protocol'] = "TCP";  
			// Définition du masque réseau qui nous permet d'autoriser certainne IP,  
			// ici nous accepton la connection vers toute les IP  
			$args['cidrlist'] = "0.0.0.0/0";  
			// Le port de début (port 443 port standart pour le HTTPs)  
			$args['startport'] = 443;  
			// Le port de fin (port 443 port standart pour le HTTPs)  
			$args['endport'] = 443;  
			// Execution de la requête  
			sendRequest($args, $json_response);  
			// Traitement de la requête  
			if(preg_match("/^[0-9a-f\-]+$/", $json_response['createegressfirewallruleresponse']['jobid']) > 0)  
			{  
			$jobs[] = $json_response['createegressfirewallruleresponse']['jobid'];  
			}  
			else{  
			echo "ID de job non trouvé.\n";  
			}  
			// On réinitialise les variables utilisées pour l'envoi de requêtes API  
			unset($args);  
 
			#########################  
			# Protocole DNS sortant #  
			#########################  
 
			// Requête API  
			$args['command'] = "createEgressFirewallRule";  
			$args['networkid'] = $vm01['conf']['networkid'];  
			// Définition du protocole a filtrer ici UDP (utiliser par le protocole DNS), les protocole sont ICMP/UDP/TCP  
			$args['protocol'] = "UDP";  
			// Définition du masque réseau qui nous permet d'autoriser certainne IP,  
			// ici nous accepton la connection vers toute les IP  
			$args['cidrlist'] = "0.0.0.0/0";  
			// Le port de début (port 443 port standart pour le HTTPs)  
			$args['startport'] = 53;  
			// Le port de fin (port 443 port standart pour le HTTPs)  
			$args['endport'] = 53;  
			// Execution de la requête  
			sendRequest($args, $json_response);  
			// Traitement de la requête  
			if(preg_match("/^[0-9a-f\-]+$/", $json_response['createegressfirewallruleresponse']['jobid']) > 0)  
			{  
			$jobs[] = $json_response['createegressfirewallruleresponse']['jobid'];  
			}  
			else{  
			echo "ID de job non trouvé.\n";  
			}  
			// On réinitialise les variables utilisées pour l'envoi de requêtes API  
			unset($args);  
 
			########################################  
			# Ouverture du port public pour le SSH #  
			########################################  
 
			// Requête API  
			$args['command'] = "createFirewallRule";  
			$args['ipaddressid'] = $vm01['conf']['publicIPid'];  
			// Définition du protocole a filtrer ici TCP (utiliser par le protocole SSH), les protocole sont ICMP/UDP/TCP  
			$args['protocol'] = "TCP";  
			// Définition du masque réseau qui nous permet d'autoriser certainne IP,  
			// ici nous accepton la connection vers toute les IP  
			$args['cidrlist'] = "0.0.0.0/0";  
			// Le port de début (port 2222 port qui sera plus tard rediriger vers le port 22(ssh) de votre VM)  
			$args['startport'] = 2222;  
			// Le port de fin (port 2222 port qui sera plus tard rediriger vers le port 22(ssh) de votre VM)  
			$args['endport'] = 2222;  
			// Execution de la requête  
			sendRequest($args, $json_response);  
			// Traitement de la requête  
			if(preg_match("/^[0-9a-f\-]+$/", $json_response['createfirewallruleresponse']['jobid']) > 0)  
			{  
			$jobs[] = $json_response['createfirewallruleresponse']['jobid'];  
			}  
			else{  
			echo "ID de job non trouvé.\n";  
			}  
			// On réinitialise les variables utilisées pour l'envoi de requêtes API  
			unset($args);  
 
			###################################  
			# Redirection de port pour le SSH #  
			###################################  
 
			// Requête API  
			$args['command'] = "createPortForwardingRule";  
			$args['ipaddressid'] = $vm01['conf']['publicIPid'];  
			$args['virtualmachineid'] = $vm01['conf']['id'];  
			// Définition du protocole a filtrer ici TCP (utiliser par le protocole SSH), les protocole sont ICMP/UDP/TCP  
			$args['protocol'] = "TCP";  
			// Le Port public sur lequels vous allez initialiser la connection et définie plus tôt comme ouvert  
			$args['publicport'] = 2222;  
			// Le SSH de votre VM  
			$args['privateport'] = 22;  
			// Execution de la requête  
			sendRequest($args, $json_response);  
			// Traitement de la requête  
			if(preg_match("/^[0-9a-f\-]+$/", $json_response['createportforwardingruleresponse']['jobid']) > 0)  
			{  
			$jobs[] = $json_response['createportforwardingruleresponse']['jobid'];  
			}  
			else{  
			echo "ID de job non trouvé.\n";  
			}  
			// On réinitialise les variables utilisées pour l'envoi de requêtes API  
			unset($args);  
			if(!checkJobs($jobs))  
			exit;  
			/*-----------------------------------------------------------------------------------------------------------*/  
 
			#############  
			# Fonctions #  
			#############  
 
			//Fonction de gestion d'erreur(s) API  
			function apiErrorCheck($json_response)  
			{  
			if(is_array($json_response))  
			{  
			$key = array_keys($json_response);  
			if(isset($json_response['errorcode']))  
			{  
			echo "ERREUR : ".$json_response['errorcode']." - ".$json_response['errortext']."\n";  
			exit;  
			}  
			if(isset($json_response['errorcode']) || (isset($key[0]) &amp;&amp; isset($json_response[$key[0]]['errorcode'])))  
			{  
			echo "ERREUR : ".$json_response[$key[0]]['errorcode']." - ".$json_response[$key[0]]['errortext']."\n";  
			exit;  
			}  
			}  
			else  
			{  
			echo "ERREUR : PARAMETRE INVALIDE";  
			exit;  
			}  
			}  
			//Fonction d'envoi de requête à l'API  
			function sendRequest($args, &amp;$json_response)  
			{  
			$json_response = null;  
			// Clef API  
			$args['apikey'] = APIKEY;  
			$args['response'] = "json";  
			//On classe les paramètres  
			ksort($args);  
			// On construit la requête HTTP basée sur les paramètres contenus dans $args  
			$query = http_build_query($args);  
			// On s'assure de bien remplacer toutes les occurences de '+' par des ' '  
			$query = str_replace("+", " ", $query);  
			//On utilise la clef secrète et un algorithme HMAC SHA-1 sur la requête pour encoder la signature  
			$hash = hash_hmac("SHA1", strtolower($query), SECRETKEY, true);  
			$base64encoded = base64_encode($hash);  
			$signature = urlencode($base64encoded);  
 
			// Construction de la requête finale sous la forme 'URL API + Requête API et paramètres + Signature'  
			$query .= "&amp;signature=" . $signature;  
			// $jobs = null;  
			// Initialisation du client API  
			try  
			{  
 
			//Construction de la requête  
			$httpRequest = new HttpRequest();  
			$httpRequest->setMethod(HTTP_METH_POST);  
			$httpRequest->setUrl(ENDPOINT . "?" . $query);  
			// Envoi de la requête au serveur :  
			$httpRequest->send();  
			// Récupération du retour de l'API  
			$response = $httpRequest->getResponseData();  
			// retour de la réponse  
			$json_response = json_decode($response['body'], true);  
			apiErrorCheck($json_response);  
			}  
			catch (Exception $e)  
			{  
			echo "Probleme lors de l'envoi de la requête. ERREUR=".$e->getMessage();  
			exit;  
			}  
			}  
 
			//Fonction de vérification des jobs asynchrones  
			function checkJobs($jobs)  
			{  
			$json_response = null;  
			$error_msg = "";  
			if(is_array($jobs) &amp;&amp; count($jobs) > 0)  
			{  
			// La tâche est asynchrone, on doit donc régulièrement vérifier les tâches avec une sécurité  
			$secu = 0;  
			// On indexe les tâches  
			$ij = 0;  
 
			// Tant qu'il y a des tâches asynchrones non-terminées dans la pile de vérification, on boucle et on vérifie le statut  
			while(count($jobs) > 0 &amp;&amp; $secu &lt; 100)  
			{  
			try  
			{  
 
			//On interroge le statut de la tâche asynchrone  
			// http://download.cloud.com/releases/3.0.6/api_3.0.6/root_admin/queryAsyncJobResult.html  
			$args['apikey'] = APIKEY;  
			$args['command'] = "queryAsyncJobResult";  
			$args['jobid'] = $jobs[$ij];  
			$args['response'] = "json";  
			$json_response = null;  
			sendRequest($args, $json_response);  
			if(is_array($json_response['queryasyncjobresultresponse']))  
			{  
			// Si OK...  
			if($json_response['queryasyncjobresultresponse']['jobstatus'] == 1)  
			{  
 
			// ...On retire simplement la tâche du tableau a surveiller  
			//return("JOB OK\n");  
			array_splice($jobs, $ij, 1);  
			}  
			// Sinon...  
			elseif($json_response['queryasyncjobresultresponse']['jobstatus'] == 2)  
			{  
 
			//...On mémorise l'erreur et on retire la tâche du tableau à surveiller  
			//return("JOB ERREUR\n");  
			array_splice($jobs, $ij, 1);  
			$error_msg .= "ERREUR ! RESULT_CODE=".$json_response['queryasyncjobresultresponse']['jobresultcode'];  
			}  
 
			// Cette tâche est encore en cours, on passe à la suivante et on temporise  
			elseif($json_response['queryasyncjobresultresponse']['jobstatus'] == 0)  
			{  
 
			// Tâche suivante  
			$ij++;  
			// Temporisation entre chaque interrogation pour ne pas charger inutilement l'API  
			sleep(5);  
			}  
			}  
			}  
			catch(Exception $e)  
			{  
			$error_msg .= "EXCEPTION Lors de la verification la tache asynchrone. JOB_UUID:"
			.$jobs[$ij]." ERREUR=".$e->getMessage()." \n";  
			}  
 
			// Si l'index arrive en bout de tableau, on le réinitialise
			if($ij == count($jobs))  
			{  
			$ij = 0;
			$secu++;
			}  
			}  
			if($error_msg)
			{  
			echo "ERRORS:".$error_msg."\n";
			return false;  
			}  
			return true;  
			}  
			echo "No job\n";  
			return false;  
			}  
			?>

II. Remerciements Developpez

L'équipe Cloud Computing tient à remercier Ikoula pour la rédaction de ce tutoriel.

Nos remerciements à Wiztricks pour sa relecture technique et à Zoom61 pour sa gabarisation.

N'hésitez pas à commenter cet article ! Commentez Donner une note à l'article (5)