Skip to main content

Código clase PHP para acceder al API de Proxmox

Ejemplo de login y llamadas al API de Proxmox con PHP y Laravel

<?php namespace App\Classes\VPS\Proxmox;

// ######################################################################
// Eduardo Taboada 2021
// 
// ######################################################################


use Illuminate\Support\Facades\DB;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\URL;
use Illuminate\Routing\UrlGenerator;

class Proxmox
{

    private $hostname;
    private $port;
    private $username;
    private $password;
    private $realm;
    private $ch;
    public $logintime;

    private $storages;
    private $proxmox;
    private $nodes;
  
    static private $headers = [
      CURLOPT_RETURNTRANSFER => true,
      CURLOPT_SSL_VERIFYHOST => 0,
      CURLOPT_SSL_VERIFYPEER => false,
      CURLOPT_VERBOSE => false,
      CURLOPT_HTTPHEADER => [ 'Transfer-Encoding: ' ]
    ];
  
    public function __construct($hostname, $username, $password, $realm = pam, $port = 8006) {
      $this->hostname = $hostname;
      $this->port = $port;
      $this->username = $username;
      $this->password = $password;
      $this->realm = $realm;
  
      $this->ch = curl_init();
  
      curl_setopt_array($this->ch, self::$headers);
  
      $this->login();

      $this->nodes = $this->request("/nodes");
    }
  
    public function login() {
      $result = $this->request('/access/ticket', "POST", [
        'username' => $this->username,
        'password' => $this->password,
        'realm' => $this->realm,
      ]);
        
      curl_setopt_array($this->ch, [
        CURLOPT_COOKIE => "PVEAuthCookie=".$result->ticket,
        CURLOPT_HTTPHEADER => array_merge(self::$headers[CURLOPT_HTTPHEADER], ['CSRFPreventionToken: '.$result->CSRFPreventionToken])
      ]);
        
      $this->logintime = microtime(true);
    }
  
    private function getUrl() {
      return 'https://' . $this->hostname . ':' . $this->port . '/api2/json';
    }
  
    public function request($actionpath, $method = "GET", $params = []) {
  
      $options = [
        CURLOPT_URL => $this->getUrl().$actionpath."?".http_build_query($params),
        CURLOPT_POST => null,
        CURLOPT_CUSTOMREQUEST => null,
  
      ];

      if ($method === "POST")
        $options[CURLOPT_POST] = true;
  
      if ($method === "PUT")
        $options[CURLOPT_CUSTOMREQUEST] = "PUT";
      
      curl_setopt_array($this->ch, $options);
      //echo  http_build_query($params);
      $result = curl_exec($this->ch);
      $error = curl_error($this->ch);
      //echo $error;
      //var_dump($error);
      $info = curl_getinfo($this->ch);
  
      if ($error !== "") {
        throw new Exception($error);
      }
  
      if ($info['http_code'] === 401) {
        throw new Exception('Invalid username or password');
      }
  
      if ($result===false) {
        throw new Exception('Error - No result');
      }
      
      return json_decode($result)->data;
  
    }

// ######################################################################    
// ######################################################################
    //NODE FUNCTIONS AND CLUSTER FUNCTIONS
// ######################################################################
// ######################################################################    


    public function getNodes(){
        return $this->request("/nodes");
    }

    public function getStatus($node) {
      return $this->request("/nodes/$node/status");
    }
  
    public function getNode($name) {
      $nodesD = $this->getNodes();
      foreach ($nodesD as $node)
        if ($node->node === $name) return $node;
      return false;
    }

    public function getNextID(){
      return $this->request("/cluster/nextid");
      
    }
    
    public function getClusterStatus(){
      return $this->request("/cluster/status");
      
    }
   
// ######################################################################
// ######################################################################  
    //VIRTUAL MACHINE LIST 
// ######################################################################
// ######################################################################  

    public function virtualMachines($running=false) {

      $allVm = $this->request("/cluster/resources", "GET", ["type" => "vm"]);
  
      $result = array();
  
      foreach ($allVm as $vm) {
        //if ($vm->type!=="qemu") continue;
        if ($running && $vm->status!=="running") continue;
        $result[$vm->vmid] = $vm;
      }
  
      ksort($result);
  
      return $result;
    }

    
    public function virtualMachinesKVM($running=false) {

      $allVm = $this->request("/cluster/resources", "GET", ["type" => "vm"]);
  
      $result = array();
  
      foreach ($allVm as $vm) {
        if ($vm->type!=="qemu") continue;
        if ($running && $vm->status!=="running") continue;
        $result[$vm->vmid] = $vm;
      }
  
      ksort($result);
  
      return $result;
    }

    public function virtualMachinesLXC($running=false) {

      $allVm = $this->request("/cluster/resources", "GET", ["type" => "vm"]);
  
      $result = array();
  
      foreach ($allVm as $vm) {
        if ($vm->type!=="lxc") continue;
        if ($running && $vm->status!=="running") continue;
        $result[$vm->vmid] = $vm;
      }
  
      ksort($result);
  
      return $result;
    }

    public function getConfig($vm) {
      return $this->request("/nodes/{$vm->node}/{$vm->type}/{$vm->id}/config");
      //return $this->request("/nodes/hv101/106/config");
    }

    public function GetVMStatus($vm){
      return $this->request("/nodes/{$vm->node}/{$vm->type}/{$vm->id}/status/current");
    }

    public function GetVM_rrd($vm){
      return $this->request("/nodes/{$vm->node}/{$vm->type}/{$vm->id}/status/current","GET",["ds"=>"memused","node" =>$vm->node,"timeframe"=>"day","vmid"=>$vm->id]);
    }
  
    public function GetVM_rrd_Data($vm){
      return $this->request("/nodes/{$vm->node}/{$vm->type}/{$vm->id}/rrddata", "GET",["node" =>$vm->node,"timeframe"=>"day","vmid"=>$vm->id]);
    }

// ######################################################################
// ######################################################################  
    // VIRTUAL MACHINE OPERATIONS
// ######################################################################
// ######################################################################      

    public function ConsoleVm($vm) {
      $this->request("/nodes/{$vm->node}/{$vm->type}/{$vm->id}/vncwebsocket?port=5900&vncticket=", "POST");
    }


    public function startVm($vm) {
      $this->request("/nodes/{$vm->node}/{$vm->type}/{$vm->id}/status/start", "POST");
    }


    public function stopVm($vm) {
      $this->request("/nodes/{$vm->node}/{$vm->type}/{$vm->id}/status/stop", "POST");
    }

    public function shutdownVM($vm) {
      $this->request("/nodes/{$vm->node}/{$vm->type}/{$vm->id}/status/shutdown", "POST");
    }


    public function suspendVM($vm) {
      $this->request("/nodes/{$vm->node}/{$vm->type}/{$vm->id}/status/suspend", "POST");
    }

    public function rebootVM($vm) {
      $this->request("/nodes/{$vm->node}/{$vm->type}/{$vm->id}/status/reboot", "POST");
    }


// ######################################################################
// ######################################################################  
    // VIRTUAL MACHINE PROVISION
// ######################################################################
// ######################################################################  

    public function createVM($vmconfig){
      return $this->request("/nodes/{$vmconfig['node']}/qemu/", "POST", $vmconfig);
    }



// ######################################################################
// ######################################################################  
    // VIRTUAL MACHINE CONFIGURATION
// ######################################################################
// ######################################################################  



// ######################################################################
// ######################################################################      
    // STORAGE FUNCTIONS
// ######################################################################
// ######################################################################     


    public function getStorage(){
      return $this->request("/storage","GET");
    }

    public function getStorageISO($storage){
      echo "/nodes/{storage->node}/storage/{storage->vol}/content";
      return $this->request("/nodes/{$storage->node}/storage/{$storage->vol}/content"," GET");
    }

    public function getISOS(){
      
    }

    public function getStorageISO_OLD() {

      $allVm = $this->request("/cluster/resources", "GET", ["type" => "storage"]);
  
      //$result = array();
  
      foreach ($allVm as $vm) {
        if ($vm->content!=="iso") continue;
        //if ($running && $vm->status!=="running") continue;
        $result[$vm->storage] = $vm;
      }
  
      ksort($result);
      $result = $allVm;
      return $result;
    }



// ######################################################################
// ######################################################################      
    // CEPH FUNCTIONS
// ######################################################################
// ######################################################################        

public function getCephStatus(){
  return $this->request("/cluster/ceph/status");
}



    //CONSOLE FUNCTIONS
}

Ejemplo de la llamada a la clase. El Realm será pam en el caso de autenticación Linux o pve para autenticación Proxmox

<?php



// ######################################################################
//  Eduardo Taboada 2021
// ######################################################################

namespace App\Http\Controllers\Admin\Vps;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
use Illuminate\Foundation\Bus\DispatchesJobs;
use Illuminate\Foundation\Validation\ValidatesRequests;
use Illuminate\Routing\Controller as BaseController;
use Illuminate\Http\Request;

use App\Classes\VPS\Proxmox\Proxmox;

$ProxmoxVar = new Proxmox($hostname,$username,$password,$realm,$port);
$node_list = $ProxmoxVar->getNodes();
?>