IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)

Déploiement et configuration réseau d'une instance CloudStack

CloudStack est un logiciel de cloud computing open source pour la création, la gestion et le déploiement de services de cloud d'infrastructure. Il utilise des hyperviseurs existants tels que KVM, vSphere, XenServer et / XCP pour la virtualisation. En plus de sa propre API, CloudStack prend également en charge les Amazon Web Services. Voici une série de tests effectués par Ikoula sur ce logiciel.

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

Article lu   fois.

L'auteur

Liens sociaux

Viadeo Twitter Facebook Share on Google+   

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 système 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 présence 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 protocoles sont ICMP/UDP/TCP  
            $args['protocol'] = "ICMP";  
            // Définition du masque réseau qui nous permet d'autoriser certaines IP,  
            // ici nous acceptons "le ping" vers toutes les IP  
            $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 certaines IP,  
            // ici nous acceptons la connexion vers toutes 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 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 protocoles sont ICMP/UDP/TCP  
            $args['protocol'] = "TCP";  
            // Définition du masque réseau qui nous permet d'autoriser certaines IP,  
            // ici nous acceptons la connexion vers toutes 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 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 protocoles sont ICMP/UDP/TCP  
            $args['protocol'] = "UDP";  
            // Définition du masque réseau qui nous permet d'autoriser certaines IP,  
            // ici nous acceptons la connexion vers toutes 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 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 certaines IP,  
            // ici nous acceptons la connexion vers toutes les IP  
            $args['cidrlist'] = "0.0.0.0/0";  
            // Le port de début (port 2222 port qui sera plus tard redirigé vers le port 22(ssh) de votre VM)  
            $args['startport'] = 2222;  
            // Le port de fin (port 2222 port qui sera plus tard redirigé 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 lequel vous allez initialiser la connexion 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 occurrences 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 à 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 vérification la tâche 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)

Vous avez aimé ce tutoriel ? Alors partagez-le en cliquant sur les boutons suivants : Viadeo Twitter Facebook Share on Google+   

Copyright © 2013 Ikoula. Aucune reproduction, même partielle, ne peut être faite de ce site ni de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.