5.0 Déployer deux instances Apache Debian 7 loadbalancées en quelques minutes avec CloudStack.

Pour cette configuration, vous devrez disposer des informations suivantes : Voici le script à utiliser pour le déploiement :

[Code]

<?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","<VOTRE CLEF API>");
	define("SECRETKEY","<VOTRE CLEF SECRETE>");
	//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 requete API 'listNetworks' ou l'interface pour lister les réseaux existants et déterminer le réseau voulu
		*/
		$vm01['conf']['networkid'] = "3eb11d44-562d-4217-9fe4-4c694b7085b8";
		
		/* UUID de l'offre de service (configuration matérielle) voulue.
		Utilisez la requete 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'] = "c6b89fea-1242-4f54-b15e-9d8ec8a0b7e8";
		
		/* UUID du modèle de systeme d'exploitation.
		Vous pouvez aussi utiliser la requete 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'] = "06239517-eb64-441a-ae71-7a0c6d3a057a";
		
		/* 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'] = "debianweb01";
		
		/* Donnees utilisateur a passer au processus de deploiement de l'instance.
		Ce parametre nous sert a envoyer une commande d'installation d'Apache a Puppet. */
		$vm01['conf']['userdata'] = 'puppet module install puppetlabs/apache && puppet apply -e "include apache" --verbose --debug';

	//Seconde instance :
	
		$vm02['conf']['networkid'] = "3eb11d44-562d-4217-9fe4-4c694b7085b8"; //Idem vm01
		$vm02['conf']['serviceofferingid'] = "c6b89fea-1242-4f54-b15e-9d8ec8a0b7e8"; //Idem vm01
		$vm02['conf']['templateid'] = "06239517-eb64-441a-ae71-7a0c6d3a057a"; //Idem vm01
		$vm02['conf']['hostname'] = "debianweb02";
		$vm02['conf']['userdata'] = 'puppet module install puppetlabs/apache && puppet apply -e "include apache" --verbose --debug';
		
/* ------------------------------ NE PLUS RIEN MODIFIER APRES CETTE LIGNE ----------------------------------- */
	$json_response = null;

	################################################
	# Récupération de l'ID de zone pour ce network #
	################################################
	// requete API
	$args['command'] = "listNetworks";

	// On reprend l'ID de réseau renseigné plus tôt
	$args['id'] = $vm01['conf']['networkid'];

	// Execution de la requete
	sendRequest($args, $json_response);

	// Stockage de l'ID de zone pour ce réseau
	$vm01['conf']['zoneid'] = $json_response['listnetworksresponse']["network"][0]['zoneid'];
	// Meme reseau pour les deux instances
	$vm02['conf']['zoneid'] = $json_response['listnetworksresponse']["network"][0]['zoneid'];

	// On réinitialise les variables utilisées pour l'envoi de requetes API
	unset($args);
		
	####################################
	# Création de la première instance #
	####################################
	
	// requete 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
	$args['userdata'] = $vm01['conf']['userdata']; //Userdata
	$args['userdata'] = base64_encode($vm01['conf']['userdata']); // Donnees utilisateur
	
	//Type de retour : JSON ou XML (par défaut : XML)
	$args['response'] = "json";
	
	// 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;
	
	//On cherche à récupérer le mot de passe de l'instance via 'queryAsyncJobResult'
	$args['command'] = "queryAsyncJobResult";
	$args['jobid'] = $json_response['deployvirtualmachineresponse']['jobid'];
	
	//Type de retour : JSON ou XML (par défaut : XML)
	$args['response'] = "json";
	
	// Initialisation du client API
	sendRequest($args, $json_response);
	
	// Indication du mot de passe de l'instance
	print($vm01['conf']['hostname']." - Mot de passe : ".$json_response['queryasyncjobresultresponse']['jobresult']['virtualmachine']['password']."\n");
	
	####################################
	# Création de la seconde instance #
	####################################
	
	// requete API
	$args['command'] = "deployVirtualMachine";
	$args['zoneid'] = $vm02['conf']['zoneid'];
	$args['serviceofferingid'] = $vm02['conf']['serviceofferingid'];
	$args['templateid'] = $vm02['conf']['templateid'];
	$args['networkids'] = $vm02['conf']['networkid'];
	$args['name'] = $vm02['conf']['hostname']; //Hostname
	$args['displayname'] = $args['name']; //Nom d'affichage
	$args['userdata'] = $vm02['conf']['userdata']; //Userdata
	$args['userdata'] = base64_encode($vm02['conf']['userdata']); // Donnees utilisateur
	
	//Type de retour : JSON ou XML (par défaut : XML)
	$args['response'] = "json";
	
	// 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
	$vm02['conf']['id'] = $json_response['deployvirtualmachineresponse']['id'];
	
	//On utilise la fonction de vérification des jobs asynchrones
	if(!checkJobs($jobs))
		exit;
	
	//On cherche à récupérer le mot de passe de l'instance via 'queryAsyncJobResult'
	$args['command'] = "queryAsyncJobResult";
	$args['jobid'] = $json_response['deployvirtualmachineresponse']['jobid'];
	
	//Type de retour : JSON ou XML (par défaut : XML)
	$args['response'] = "json";
	
	// Initialisation du client API
	sendRequest($args, $json_response);
	
	// Indication du mot de passe de l'instance
	print($vm02['conf']['hostname']." - Mot de passe : ".$json_response['queryasyncjobresultresponse']['jobresult']['virtualmachine']['password']."\n");
	
	######################################################
	# Récupération de l'id de l'adresse IP de ce network #
	######################################################
	// requete API
	$args['command'] = "listPublicIpAddresses";
	$args['associatednetworkid'] = $vm01['conf']['networkid'];

	// Execution de la requete
	sendRequest($args, $json_response);

	// Stockage de l'ID de l'adresse IP publique du réseau
	$publicIPid = $json_response['listpublicipaddressesresponse']["publicipaddress"][0]['id'];
	
	// Stockage de l'IP correspondante
	$vm01['conf']['publicIP'] = $json_response['listpublicipaddressesresponse']["publicipaddress"][0]['ipaddress'];

	// On réinitialise les variables utilisées pour l'envoi de requetes API
	unset($args);
		
/*-------------------------------- Création des règles de sortie --------------------------------*/
	// On réinitialise les variables utilisées pour l'envoi de requetes 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 protocoles sont ICMP/UDP/TCP
	$args['protocol'] = "ICMP";
	// Définition du masque réseau qui nous permet d'autoriser certaines IPs,
	// 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 requete
	sendRequest($args, $json_response);

	// Traitement de la requete
	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 requetes API
	unset($args);
	
	##########################
	# Protocole HTTP sortant #
	##########################
	$args['command'] = "createEgressFirewallRule";
	$args['networkid'] = $vm01['conf']['networkid'];
	
	// Définition du protocole a filtrer ici TCP (utilisé par le protocole HTTP), les protocoles sont ICMP/UDP/TCP
	$args['protocol'] = "TCP";
	
	// Définition du masque réseau qui nous permet d'autoriser certaines IPs,
	// ici nous acceptons la connection vers toute les IP
	$args['cidrlist'] = "0.0.0.0/0";
	
	// Le port de début (port 80 port standard pour le HTTP)
	$args['startport'] = 80;
	
	// Le port de fin (port 80 port standard pour le HTTP)
	$args['endport'] = 80;
	
	// Execution de la requete
	sendRequest($args, $json_response);

	// Traitement de la requete
	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 requetes API
	unset($args);
	
	###########################
	# Protocole HTTPS sortant #
	###########################
	// requete API
	$args['command'] = "createEgressFirewallRule";
	$args['networkid'] = $vm01['conf']['networkid'];
	
	// Définition du protocole a filtrer ici TCP (utilisé par le protocole HTTPS), les protocoles sont ICMP/UDP/TCP
	$args['protocol'] = "TCP";
	
	// Définition du masque réseau qui nous permet d'autoriser certaines IPs,
	// ici nous acceptons la connection vers toute les IP
	$args['cidrlist'] = "0.0.0.0/0";
	
	// Le port de début (port 443 port standard pour le HTTPs)
	$args['startport'] = 443;
	
	// Le port de fin (port 443 port standard pour le HTTPs)
	$args['endport'] = 443;
	
	// Execution de la requete
	sendRequest($args, $json_response);

	// Traitement de la requete
	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 requetes API
	unset($args);

	##########################
	# Protocole FTP sortant #
	##########################
	$args['command'] = "createEgressFirewallRule";
	$args['networkid'] = $vm01['conf']['networkid'];
	
	// Définition du protocole a filtrer ici TCP (utilisé par le protocole FTP), les protocoles sont ICMP/UDP/TCP
	$args['protocol'] = "TCP";
	
	// Définition du masque réseau qui nous permet d'autoriser certaines IPs,
	// ici nous acceptons la connection vers toute les IP
	$args['cidrlist'] = "0.0.0.0/0";
	
	// Le port de début (port 21 port standard pour le HTTP)
	$args['startport'] = 21;
	
	// Le port de fin (port 21 port standard pour le HTTP)
	$args['endport'] = 21;
	
	// Execution de la requete
	
	sendRequest($args, $json_response);

	// Traitement de la requete
	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 requetes API
	unset($args);	
	
	#########################
	# Protocole DNS sortant #
	#########################
	// requete API
	$args['command'] = "createEgressFirewallRule";
	$args['networkid'] = $vm01['conf']['networkid'];
	
	// Définition du protocole a filtrer ici UDP (utilisé par le protocole DNS), les protocoles sont ICMP/UDP/TCP
	$args['protocol'] = "UDP";
	
	// Définition du masque réseau qui nous permet d'autoriser certaines IPs,
	// ici nous acceptons la connection vers toute les IP
	$args['cidrlist'] = "0.0.0.0/0";
	
	// Le port de début (port 443 port standard pour le HTTPs)
	$args['startport'] = 53;
	
	// Le port de fin (port 443 port standard pour le HTTPs)
	$args['endport'] = 53;
	
	// Execution de la requete
	sendRequest($args, $json_response);
	
	// Traitement de la requete
	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 requetes API
	unset($args);
	
	################################################################
	# Ouverture du port public pour le SSH de la première instance #
	################################################################
	// requete API
	$args['command'] = "createFirewallRule";
	$args['ipaddressid'] = $publicIPid;
	
	// Définition du protocole a filtrer ici TCP (utilisé par le protocole SSH), les protocoles sont ICMP/UDP/TCP
	$args['protocol'] = "TCP";
	
	// Définition du masque réseau qui nous permet d'autoriser certaines IPs,
	// ici nous acceptons 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 requete
	sendRequest($args, $json_response);
	
	// Traitement de la requete
	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 requetes API
	unset($args);
	
	###########################################################
	# Redirection de port pour le SSH de la première instance #
	###########################################################
	// requete API
	$args['command'] = "createPortForwardingRule";
	$args['ipaddressid'] = $publicIPid;
	$args['virtualmachineid'] = $vm01['conf']['id'];
	
	// Définition du protocole a filtrer ici TCP (utilisé par le protocole SSH), les protocoles 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 requete
	sendRequest($args, $json_response);
	
	// Traitement de la requete
	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 requetes API
	unset($args);
	
	if(!checkJobs($jobs))
			exit;
			
	################################################################
	# Ouverture du port public pour le SSH de la seconde instance #
	################################################################
	// requete API
	$args['command'] = "createFirewallRule";
	$args['ipaddressid'] = $publicIPid;
	
	// Définition du protocole a filtrer ici TCP (utilisé par le protocole SSH), les protocoles sont ICMP/UDP/TCP
	$args['protocol'] = "TCP";
	
	// Définition du masque réseau qui nous permet d'autoriser certaines IPs,
	// ici nous acceptons 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'] = 2223;
	
	// Le port de fin (port 2222 port qui sera plus tard rediriger vers le port 22(ssh) de votre VM)
	$args['endport'] = 2223;
	
	// Execution de la requete
	sendRequest($args, $json_response);
	
	// Traitement de la requete
	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 requetes API
	unset($args);
	
	###########################################################
	# Redirection de port pour le SSH de la seconde instance #
	###########################################################
	// requete API
	$args['command'] = "createPortForwardingRule";
	$args['ipaddressid'] = $publicIPid;
	$args['virtualmachineid'] = $vm02['conf']['id'];
	
	// Définition du protocole a filtrer ici TCP (utilisé par le protocole SSH), les protocoles 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'] = 2223;
	
	// Le SSH de votre VM
	$args['privateport'] = 22;
	
	// Execution de la requete
	sendRequest($args, $json_response);
	
	// Traitement de la requete
	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 requetes API
	unset($args);
	
	if(!checkJobs($jobs))
			exit;
	
	############################################################################
	# Creation de la règle de LoadBalancing entre les deux instances (port 80) #
	############################################################################
	
	// requete API
	$args['command'] = "createLoadBalancerRule";
	$args['algorithm'] = "leastconn"; // Algorithme de répartition de charge (Ici "Least Connections". Possibles : "Source" et "RoundRobin").
	$args['name'] = "Web"; //Nom de votre règle de loadbalancing.
	$args['privateport'] = "80"; // Port privé sur lequel tourne le service sur les deux instances.
	$args['publicport'] = "80"; // Port public, qui sera à l'écoute sur votre IP publique.
	$args['publicipid'] = $publicIPid; // IP publique sur laquelle créer la règle de LB.
	$args['openfirewall'] = 'true'; // Créer automatiquement la règle de pare-feu entrant correspondante.
	
	// Execution de la requete
	sendRequest($args, $json_response);
	
	// Traitement de la requete
	if(preg_match("/^[0-9a-f\-]+$/", $json_response['createloadbalancerruleresponse']['jobid']) > 0)
	{
		$jobs[] = $json_response['createloadbalancerruleresponse']['jobid'];
	}
	else{
		echo "ID de job non trouvé.\n";
	}
	
	// On réinitialise les variables utilisées pour l'envoi de requetes API
	unset($args);
	
	if(!checkJobs($jobs))
			exit;
	
	#############################################################
	# Assignation des instances membres du cluster loadbalancé. #
	#############################################################
	
	//Requete API pour récupérer l'id de la règle précedemment créée
	$args['command'] = "queryAsyncJobResult";
	$args['jobid'] = $json_response['createloadbalancerruleresponse']['jobid'];
	
	// Execution de la requete
	sendRequest($args, $json_response);
	
	$LBRuleID = $json_response['queryasyncjobresultresponse']['jobresult']['loadbalancer']['id'];
	
	//Requete API pour ajouter les instances au cluster LB
	
	$args['command'] = "assignToLoadBalancerRule";
	$args['id'] = $LBRuleID;
	$args['virtualmachineids'] = $vm01['conf']['id'].",".$vm02['conf']['id'];
	
	// Execution de la requete
	sendRequest($args, $json_response);
	
	// Traitement de la requete
	if(preg_match("/^[0-9a-f\-]+$/", $json_response['assigntoloadbalancerruleresponse']['jobid']) > 0)
	{
		$jobs[] = $json_response['assigntoloadbalancerruleresponse']['jobid'];
	}
	else{
		echo "ID de job non trouvé.\n";
	}
	
	// On réinitialise les variables utilisées pour l'envoi de requetes API
	unset($args);
	
	if(!checkJobs($jobs))
			exit;
			
	// Finalisation
	echo "D'ici environ 5 minutes, vous pourrez vous connecter à l'adresse http://".$vm01['conf']['publicIP']." qui est l'adresse \"loadbalancée\" entre vos deux instances web.\n";
	echo "A noter que l'IP pour accéder à vos instances en SSH est la même. Port 2222 pour la première et 2223 pour la seconde.\n";
	
/*-----------------------------------------------------------------------------------------------------------*/
	
	#############
	# 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]) && 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 requete à l'API
	function sendRequest($args, &$json_response)
	{
		$json_response = null;
		// Clef API
		$args['apikey'] = APIKEY;
		$args['response'] = "json";
		//On classe les paramètres
		ksort($args);
		// On construit la requete 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 '%20'
		$query = str_replace("+", "%20", $query);
		//On utilise la clef secrète et un algorithme HMAC SHA-1 sur la requete pour encoder la signature
		$hash = hash_hmac("SHA1",  strtolower($query), SECRETKEY, true);
		$base64encoded = base64_encode($hash);
		$signature = urlencode($base64encoded);

		// Construction de la requete finale sous la forme 'URL API + requete API et paramètres + Signature'
		$query .= "&signature=" . $signature;

		// $jobs = null;
		
		// Initialisation du client API
		try
		{
			//Construction de la requete
			$httpRequest = new HttpRequest();
			$httpRequest->setMethod(HTTP_METH_POST);
			$httpRequest->setUrl(ENDPOINT . "?" . $query);
			
			// Envoi de la requete 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 requete. ERREUR=".$e->getMessage();
			exit;
		}
	}
	
	//Fonction de vérification des jobs asynchrones
	function checkJobs($jobs)
	{
		$json_response = null;
		$error_msg = "";
		if(is_array($jobs) && 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 && $secu < 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;
	}
?>

Après avoir renseigné les paramètres demandés au début du script et l’avoir exécuté, voici ce qui sera effectué :
  • Déploiement de deux instances Debian 7 (de type « m1.small »)
  • Installation de l’environnement Apache au sein de cette instance via Puppet.
  • Création des règles sortantes nécessaires dans le pare-feu CloudStack : Ping ; FTP ; DNS ; ICMP ; http ; HTTPS
  • Création d’une règle entrante et de translation nécessaires dans le pare-feu CloudStack : SSH (pour chaque instance)
  • Création d’une règle de loadbalancing entre l’adresse IP publique et le port 80 des deux instances Apache privées.
Environ 5 minutes après l’exécution du script, vous pourrez vous connecter à l’adresse indiquée par ce dernier afin de tester le fonctionnement de la répartition de charge.


Ajouter un commentaire