Massive import web manager
11
code/web/www/pages/dbconf.php
Normal file
|
@ -0,0 +1,11 @@
|
|||
<?php
|
||||
//DATABASE CONNECTION VARIABLES
|
||||
$host = "localhost"; // Host name
|
||||
$username = "eyeprox"; // Mysql username
|
||||
$password = "definir_ici_un_mot_de_passe"; // Mysql password
|
||||
$db_name = "eyeprox"; // Database name
|
||||
|
||||
$tbl_prefix = "";
|
||||
$tbl_nodes = $tbl_prefix."nodes";
|
||||
$tbl_logs = $tbl_prefix."logs";
|
||||
|
BIN
code/web/www/pages/images/configuration_13194.png
Normal file
After Width: | Height: | Size: 28 KiB |
BIN
code/web/www/pages/images/details_close.png
Normal file
After Width: | Height: | Size: 686 B |
BIN
code/web/www/pages/images/details_open.png
Normal file
After Width: | Height: | Size: 709 B |
BIN
code/web/www/pages/images/fb-lien-420.png
Executable file
After Width: | Height: | Size: 10 KiB |
BIN
code/web/www/pages/images/icon-load.gif
Executable file
After Width: | Height: | Size: 5.4 KiB |
BIN
code/web/www/pages/images/nongrata_off.png
Normal file
After Width: | Height: | Size: 1.3 KiB |
BIN
code/web/www/pages/images/nongrata_on.jpg
Normal file
After Width: | Height: | Size: 24 KiB |
BIN
code/web/www/pages/images/nongrata_on.png
Normal file
After Width: | Height: | Size: 1 KiB |
8
code/web/www/pages/includes/footer.php
Executable file
|
@ -0,0 +1,8 @@
|
|||
|
||||
</div>
|
||||
|
||||
<!-- <center> VM viewer and management center (VM-VMC) -- V0.1 by Tlams</center> -->
|
||||
<center> PCM - Proxmox Central Management -- V0.1 by Tlams</center>
|
||||
</body>
|
||||
|
||||
</html>
|
215
code/web/www/pages/includes/header.php
Executable file
|
@ -0,0 +1,215 @@
|
|||
<?php
|
||||
require(dirname(__DIR__).'/requires/configs.php');
|
||||
require(dirname(__DIR__).'/requires/functions.php');
|
||||
|
||||
|
||||
//SESSION
|
||||
session_start();
|
||||
if (!isset($_SESSION['uid']) && ($useldap == true)) {
|
||||
header("location:login.php");
|
||||
die();
|
||||
}
|
||||
|
||||
|
||||
// GEN HTML LIST Dates
|
||||
$html = new API_Gen_HTML;
|
||||
$q = new API_GET_INFO;
|
||||
$html_dates = [];
|
||||
$lastdate = "";
|
||||
|
||||
if(!empty($_POST['date']))
|
||||
{
|
||||
$html_dates = $html->List_Dates($_POST['date']);
|
||||
$lastdate = $_POST['date'];
|
||||
}
|
||||
else
|
||||
{
|
||||
$html_dates = $html->List_Dates();
|
||||
$lastdate = json_decode($q->GET_Dates("last"), true)['value'];
|
||||
}
|
||||
|
||||
//$html_groups = $html->List_Groups($lastdate);
|
||||
?>
|
||||
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta name="description" content="">
|
||||
<meta name="author" content="">
|
||||
|
||||
<title>PCM</title>
|
||||
|
||||
<!-- Bootstrap Core CSS -->
|
||||
<link href="../css/jquery-ui.css" rel="stylesheet">
|
||||
|
||||
<!-- Bootstrap Core CSS -->
|
||||
<link href="../css/style.css" rel="stylesheet">
|
||||
|
||||
<!-- Bootstrap Core CSS -->
|
||||
<link href="../vendor/bootstrap/css/bootstrap.css" rel="stylesheet">
|
||||
<link href="../vendor/bootstrap-select/css/bootstrap-select.css" rel="stylesheet">
|
||||
|
||||
<!-- MetisMenu CSS -->
|
||||
<link href="../vendor/metisMenu/metisMenu.min.css" rel="stylesheet">
|
||||
|
||||
<!-- DataTables CSS -->
|
||||
<link href="../vendor/datatables-plugins/dataTables.bootstrap.css" rel="stylesheet">
|
||||
|
||||
<!-- DataTables Responsive CSS -->
|
||||
<link href="../vendor/datatables-responsive/dataTables.responsive.css" rel="stylesheet">
|
||||
|
||||
<!-- Custom CSS -->
|
||||
<link href="../dist/css/sb-admin-2.css" rel="stylesheet">
|
||||
|
||||
<!-- Custom Fonts -->
|
||||
<link href="../vendor/font-awesome/css/font-awesome.min.css" rel="stylesheet" type="text/css">
|
||||
|
||||
<!-- jQuery -->
|
||||
<script src="../js/jquery-1.12.3.js"></script>
|
||||
<script src="../js/jquery-ui.js"></script>
|
||||
|
||||
<!-- Bootstrap Core JavaScript -->
|
||||
<script src="../vendor/bootstrap/js/bootstrap.min.js"></script>
|
||||
<script src="../vendor/bootstrap-select/js/bootstrap-select.js"></script>
|
||||
|
||||
|
||||
<!-- Metis Menu Plugin JavaScript -->
|
||||
<script src="../vendor/metisMenu/metisMenu.min.js"></script>
|
||||
|
||||
<!-- DataTables JavaScript -->
|
||||
<script src="../vendor/datatables/js/jquery.dataTables.min.js"></script>
|
||||
<script src="../vendor/datatables-plugins/dataTables.bootstrap.min.js"></script>
|
||||
<script src="../vendor/datatables-responsive/dataTables.responsive.js"></script>
|
||||
|
||||
<!-- Morris Charts JavaScript -->
|
||||
<script src="../vendor/raphael/raphael.min.js"></script>
|
||||
<script src="../vendor/morrisjs/morris.min.js"></script>
|
||||
|
||||
<!-- Custom Theme JavaScript -->
|
||||
<script src="../dist/js/sb-admin-2.js"></script>
|
||||
|
||||
<!-- Include the plugin's CSS and JS: -->
|
||||
<script type="text/javascript" src="../vendor/bootstrap-multisltc/js/bootstrap-multiselect.js"></script>
|
||||
<link rel="stylesheet" href="../vendor/bootstrap-multisltc/css/bootstrap-multiselect.css" type="text/css"/>
|
||||
|
||||
<!-- Main -->
|
||||
<script src="js/main.js"></script>
|
||||
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="wrapper">
|
||||
|
||||
<!-- Navigation -->
|
||||
<nav class="navbar navbar-default navbar-static-top" role="navigation" style="margin-bottom: 0">
|
||||
<div class="navbar-header">
|
||||
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
|
||||
<span class="sr-only">Toggle navigation</span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
</button>
|
||||
<a class="navbar-brand" href="index.php">PCM V0.1</a>
|
||||
|
||||
<form method="POST" class="navbar-brand" action="" style="margin-top: -7px">
|
||||
<?php echo $html_dates; ?> <INPUT type="submit" class="btn btn-default pull-right" value="OK">
|
||||
</form>
|
||||
</div>
|
||||
<!-- /.navbar-header -->
|
||||
|
||||
<ul class="nav navbar-top-links navbar-right">
|
||||
<?php
|
||||
if ($useldap == true)
|
||||
{
|
||||
echo "Welcome ".$_SESSION['uid'];
|
||||
}
|
||||
else
|
||||
echo "Welcome guest !";
|
||||
?>
|
||||
|
||||
<!-- /.dropdown -->
|
||||
<li class="dropdown">
|
||||
<a class="dropdown-toggle" data-toggle="dropdown" href="#">
|
||||
<i class="fa fa-user fa-fw"></i> <i class="fa fa-caret-down"></i>
|
||||
</a>
|
||||
<?php
|
||||
if ($useldap == true)
|
||||
{
|
||||
echo '
|
||||
<ul class="dropdown-menu dropdown-user">
|
||||
<li><a href="login.php?logout="><i class="fa fa-sign-out fa-fw"></i> Logout</a></li>
|
||||
</ul>
|
||||
';
|
||||
}
|
||||
?>
|
||||
|
||||
<!-- /.dropdown-user -->
|
||||
</li>
|
||||
<!-- /.dropdown -->
|
||||
</ul>
|
||||
<!-- /.navbar-top-links -->
|
||||
|
||||
<div class="navbar-default sidebar" role="navigation">
|
||||
<div class="sidebar-nav navbar-collapse">
|
||||
<ul class="nav" id="side-menu">
|
||||
<!--
|
||||
<li class="sidebar-search">
|
||||
<div class="input-group custom-search-form">
|
||||
<input type="text" class="form-control" placeholder="Search...">
|
||||
<span class="input-group-btn">
|
||||
<button class="btn btn-default" type="button">
|
||||
<i class="fa fa-search"></i>
|
||||
</button>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
</li>
|
||||
-->
|
||||
|
||||
|
||||
<li>
|
||||
<a href="index.php"><i class="fa fa-dashboard fa-fw"></i> Dashboard</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="vmalloc.php"><i class="fa fa-street-view fa-fw"></i>VM Allocation</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="vms.php"><i class="fa fa-table fa-fw"></i>VMs</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="nodes.php"><i class="fa fa-table fa-fw"></i>Hypervisors</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="storages.php"><i class="fa fa-table fa-fw"></i>Storages</a>
|
||||
</li>
|
||||
|
||||
|
||||
|
||||
<li>
|
||||
<a href="#"><i class="fa fa-sitemap fa-fw"></i> Groups <span class="fa arrow"></span></a>
|
||||
<ul class="nav nav-second-level">
|
||||
<?php // echo $html_groups; ?>
|
||||
</ul>
|
||||
<!-- /.nav-second-level -->
|
||||
</li>
|
||||
|
||||
|
||||
<li>
|
||||
<a href="informations.php"><i class="fa fa-info fa-fw"></i>Informations</a>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
<!-- /.sidebar-collapse -->
|
||||
</div>
|
||||
<!-- /.navbar-static-side -->
|
||||
</nav>
|
132
code/web/www/pages/index.php
Executable file
|
@ -0,0 +1,132 @@
|
|||
<?php
|
||||
include(dirname(__DIR__).'/pages/includes/header.php');
|
||||
?>
|
||||
<div id="page-wrapper">
|
||||
<div class="row">
|
||||
<div class="col-lg-12">
|
||||
<h1 class="page-header">General Dashboard</h1>
|
||||
</div>
|
||||
<div class="col-lg-12" id="List_Dates">
|
||||
|
||||
</div>
|
||||
<!-- /.col-lg-12 -->
|
||||
</div>
|
||||
<!-- /.row -->
|
||||
<div class="row">
|
||||
<div class="col-lg-12">
|
||||
<div class="panel panel-default">
|
||||
|
||||
<!--
|
||||
|
||||
<div class="col-lg-3 col-md-6">
|
||||
<div class="panel panel-green">
|
||||
<div class="panel-heading">
|
||||
<div class="row">
|
||||
<div class="col-xs-3">
|
||||
<i class="fa fa-tasks fa-5x"></i>
|
||||
</div>
|
||||
<div class="col-xs-9 text-right">
|
||||
<div class="huge">12</div>
|
||||
<div>Nodes in your insfrastucture</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<a href="#">
|
||||
<div class="panel-footer">
|
||||
<span class="pull-left">View Details</span>
|
||||
<span class="pull-right"><i class="fa fa-arrow-circle-right"></i></span>
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-lg-3 col-md-6">
|
||||
<div class="panel panel-green">
|
||||
<div class="panel-heading">
|
||||
<div class="row">
|
||||
<div class="col-xs-3">
|
||||
<i class="fa fa-tasks fa-5x"></i>
|
||||
</div>
|
||||
<div class="col-xs-9 text-right">
|
||||
<div class="huge">12</div>
|
||||
<div>VMs in your insfrastucture</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<a href="#">
|
||||
<div class="panel-footer">
|
||||
<span class="pull-left">View Details</span>
|
||||
<span class="pull-right"><i class="fa fa-arrow-circle-right"></i></span>
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="col-lg-3 col-md-6">
|
||||
<div class="panel panel-green">
|
||||
<div class="panel-heading">
|
||||
<div class="row">
|
||||
<div class="col-xs-3">
|
||||
<i class="fa fa-tasks fa-5x"></i>
|
||||
</div>
|
||||
<div class="col-xs-9 text-right">
|
||||
<div class="huge">12</div>
|
||||
<div>New Tasks!</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<a href="#">
|
||||
<div class="panel-footer">
|
||||
<span class="pull-left">View Details</span>
|
||||
<span class="pull-right"><i class="fa fa-arrow-circle-right"></i></span>
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-lg-3 col-md-6">
|
||||
<div class="panel panel-green">
|
||||
<div class="panel-heading">
|
||||
<div class="row">
|
||||
<div class="col-xs-3">
|
||||
<i class="fa fa-tasks fa-5x"></i>
|
||||
</div>
|
||||
<div class="col-xs-9 text-right">
|
||||
<div class="huge">12</div>
|
||||
<div>New Tasks!</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<a href="#">
|
||||
<div class="panel-footer">
|
||||
<span class="pull-left">View Details</span>
|
||||
<span class="pull-right"><i class="fa fa-arrow-circle-right"></i></span>
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<h3>Clusters may be dead</h3>
|
||||
<div id="clusterdead" style="height: 300px;"></div>
|
||||
</div>
|
||||
<div class="col-md-12">
|
||||
<h3>Hypervisors ressources critical</h3>
|
||||
<div id="hypfull" style="height: 300px;"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
-->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
include(dirname(__DIR__).'/pages/includes/footer.php');
|
||||
?>
|
303
code/web/www/pages/js/main.js
Executable file
|
@ -0,0 +1,303 @@
|
|||
/**
|
||||
* Created by tlams on 10/11/16.
|
||||
*/
|
||||
|
||||
$(document).ready(function()
|
||||
{
|
||||
/* MAC ADDR Tooltip */
|
||||
$('[data-toggle="tooltip"]').tooltip({
|
||||
'selector': '',
|
||||
'placement': 'left',
|
||||
'container':'body'
|
||||
});
|
||||
|
||||
/* ARRAY CONFIGURATION */
|
||||
$('#dataTables-storages').DataTable( {
|
||||
"lengthMenu": [[10, 25, 50, 100, -1], [10, 25, 50, 100, "all"]],
|
||||
"paging": true,
|
||||
"searching": true,
|
||||
"ordering": true,
|
||||
"info": true,
|
||||
|
||||
responsive: {
|
||||
details: {
|
||||
type: 'inline',
|
||||
target: 'tr'
|
||||
}
|
||||
},
|
||||
columnDefs: [ {
|
||||
className: 'control',
|
||||
orderable: false,
|
||||
targets: 0
|
||||
} ],
|
||||
order: [ 1, 'asc' ]
|
||||
} );
|
||||
|
||||
|
||||
$('#dataTables-cluster').DataTable( {
|
||||
"lengthMenu": [[10, 25, 50, 100, -1], [10, 25, 50, 100, "all"]],
|
||||
"paging": true,
|
||||
"searching": true,
|
||||
"ordering": true,
|
||||
"info": true,
|
||||
|
||||
responsive: {
|
||||
details: {
|
||||
type: 'inline',
|
||||
target: 'tr'
|
||||
}
|
||||
},
|
||||
columnDefs: [ {
|
||||
className: 'control',
|
||||
orderable: false,
|
||||
targets: 0
|
||||
} ],
|
||||
order: [ 1, 'asc' ]
|
||||
} );
|
||||
|
||||
|
||||
$('#dataTables-hypervisors').DataTable( {
|
||||
"lengthMenu": [[25, 50, 100, 500, -1], [25, 50, 100, 500, "all"]],
|
||||
"paging": true,
|
||||
"searching": true,
|
||||
"ordering": true,
|
||||
"info": true,
|
||||
|
||||
responsive: {
|
||||
details: {
|
||||
type: 'inline',
|
||||
target: 'tr'
|
||||
}
|
||||
},
|
||||
|
||||
columnDefs: [ {
|
||||
className: 'control',
|
||||
orderable: false,
|
||||
targets: 0
|
||||
}
|
||||
],
|
||||
order: [ 1, 'asc' ]
|
||||
} );
|
||||
|
||||
|
||||
$('#dataTables-hypervisor').DataTable( {
|
||||
"paging": false,
|
||||
"searching": false,
|
||||
"ordering": false,
|
||||
"info": true,
|
||||
|
||||
responsive: {
|
||||
details: {
|
||||
type: 'inline',
|
||||
target: 'tr'
|
||||
}
|
||||
},
|
||||
columnDefs: [ {
|
||||
className: 'control',
|
||||
orderable: false,
|
||||
targets: 0
|
||||
} ],
|
||||
order: [ 2, 'asc' ]
|
||||
} );
|
||||
|
||||
|
||||
|
||||
$('.dataTables-vm').DataTable({
|
||||
"lengthMenu": [[25, 50, 100, 500, -1], [25, 50, 100, 500, "all"]],
|
||||
"paging": true,
|
||||
"searching": true,
|
||||
"ordering": true,
|
||||
"info": true,
|
||||
"pagingType": "simple_numbers",
|
||||
|
||||
responsive: {
|
||||
details: {
|
||||
type: 'column',
|
||||
target: 'tr'
|
||||
}
|
||||
},
|
||||
columnDefs: [ {
|
||||
className: 'control',
|
||||
orderable: false,
|
||||
targets: 0
|
||||
} ],
|
||||
order: [ 1, 'asc' ]
|
||||
} );
|
||||
|
||||
$( function()
|
||||
{
|
||||
|
||||
/* VM GESTION */
|
||||
var dialog, form,
|
||||
name = $( "#name" ),
|
||||
password = $( "#password" ),
|
||||
allFields = $( [] ).add( name ).add( password );
|
||||
|
||||
function sendrequest() {
|
||||
// J'initialise le variable box
|
||||
var box = $('.result');
|
||||
|
||||
var action = $( "#action" );
|
||||
var vmid = $( "#vmid" );
|
||||
var node = $( "#node" );
|
||||
var commandinfo = "The status available in the table is not dynamically update, you must wait the next cron rotate. <br /> You can play the status command to have an updated informations";
|
||||
box.html('<center> <img src="images/icon-load.gif" height="60" width="60"></center>');
|
||||
$('.selectaction').prop('selectedIndex',0);
|
||||
// Je définis ma requête ajax
|
||||
$.ajax({
|
||||
|
||||
// Adresse à laquelle la requête est envoyée
|
||||
url: 'requires/pveaction.php',
|
||||
type : 'POST',
|
||||
data : 'user=' + name.val() + '&password=' + password.val() + '&action=' + action.val() + '&vmid=' + vmid.val() + '&node=' + node.val(),
|
||||
// Le délai maximun en millisecondes de traitement de la demande
|
||||
timeout: 32000,
|
||||
|
||||
// La fonction à apeller si la requête aboutie
|
||||
success: function (data) {
|
||||
// Je charge les données dans box
|
||||
box.html('<div class="alert alert-info"> <strong>Command return: </strong> '+data+' <br /> '+ commandinfo +'</div>');
|
||||
},
|
||||
|
||||
// La fonction à appeler si la requête n'a pas abouti
|
||||
error: function() {
|
||||
// J'affiche un message d'erreur
|
||||
box.html('<div class="alert alert-danger"> <strong>Error: </strong> Command failed, try again or contact an true admin. </div>');
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
dialog.dialog( "close" );
|
||||
$("html, body").animate({ scrollTop: $(document).height() }, "slow");
|
||||
}
|
||||
|
||||
dialog = $( "#dialog-form" ).dialog({
|
||||
autoOpen: false,
|
||||
height: 250,
|
||||
width: 350,
|
||||
modal: true,
|
||||
resizable: false,
|
||||
buttons: {
|
||||
"Send": sendrequest,
|
||||
Cancel: function() {
|
||||
dialog.dialog( "close" );
|
||||
}
|
||||
},
|
||||
close: function() {
|
||||
form[ 0 ].reset();
|
||||
allFields.removeClass( "ui-state-error" );
|
||||
$('.selectaction').prop('selectedIndex',0);
|
||||
}
|
||||
});
|
||||
|
||||
form = dialog.find( "form" ).on( "submit", function( event ) {
|
||||
event.preventDefault();
|
||||
sendrequest();
|
||||
|
||||
});
|
||||
|
||||
$('.dataTables-vm').on('change', '.selectaction',function() {
|
||||
var jsonout = JSON.parse(this.value.replace(/'/g, '"'));
|
||||
if (jsonout["action"] != "none") {
|
||||
|
||||
$('#action').val(jsonout["action"]);
|
||||
$('#vmid').val(jsonout["vmid"]);
|
||||
$('#node').val(jsonout["node"]);
|
||||
dialog.dialog( "open" );
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
||||
/* NODE NON GRATA */
|
||||
|
||||
function nongrataswitch(node, action) {
|
||||
// J'initialise le variable box
|
||||
var box = $('.result');
|
||||
var commandinfo = "This information will be automatic applied in the next update.";
|
||||
box.html('<center> <img src="images/icon-load.gif" height="60" width="60"></center>');
|
||||
var divid = '#'+node;
|
||||
// Je définis ma requête ajax
|
||||
$.ajax({
|
||||
|
||||
// Adresse à laquelle la requête est envoyée
|
||||
url: 'requires/pcmaction.php',
|
||||
type : 'POST',
|
||||
data : 'node=' + node + '&action=' + action,
|
||||
// Le délai maximun en millisecondes de traitement de la demande
|
||||
timeout: 32000,
|
||||
|
||||
// La fonction à apeller si la requête aboutie
|
||||
success: function (data) {
|
||||
// Je charge les données dans box
|
||||
box.html('<div class="alert alert-info"> <strong>information: </strong>' + commandinfo);
|
||||
|
||||
if (data == "sw_OFF")
|
||||
$(divid).html('<a class="nongratalink" data-toggle="tooltip" title="Switch to non grata" id="'+node+'" action="sw_OFF" node="'+node+'" href="#" > <img src="images/nongrata_off.png" alt="Nongrataimg" style="width:16px;height:16px;"/></a>');
|
||||
else if (data == "sw_ON")
|
||||
$(divid).html('<a class="nongratalink" data-toggle="tooltip" title="Switch to grata" id="'+node+'" action="sw_ON" node="'+node+'" href="#" > <img src="images/nongrata_on.png" alt="Nongrataimg" style="width:16px;height:16px;"/></a>');
|
||||
else
|
||||
$(divid).html(':(');
|
||||
},
|
||||
|
||||
// La fonction à appeler si la requête n'a pas abouti
|
||||
error: function() {
|
||||
// J'affiche un message d'erreur
|
||||
box.html('<div class="alert alert-danger"> <strong>Error: </strong> Command failed, try again or contact an administrator. </div>');
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
dialog.dialog( "close" );
|
||||
}
|
||||
|
||||
$('.nongratalink').click(function() {
|
||||
var node = $(this).attr('node');
|
||||
var action = $(this).attr('action');
|
||||
nongrataswitch(node, action);
|
||||
return false; // return false so the browser will not scroll your page
|
||||
});
|
||||
/* NEWVM -- SEARCH NODES */
|
||||
|
||||
form = dialog.find( "form" ).on( "submit", function( event ) {
|
||||
event.preventDefault();
|
||||
sendrequest();
|
||||
|
||||
});
|
||||
|
||||
function newvm() {
|
||||
// J'initialise le variable box
|
||||
var box = $('#result');
|
||||
var cpu = $( "#cpu" );
|
||||
var ram = $( "#ram" );
|
||||
var disk = $( "#disk" );
|
||||
var cluster = $( "#enableClickableOptGroups" );
|
||||
|
||||
box.html('<center> <img src="images/icon-load.gif" height="60" width="60"> <br>Please wait... can take more than 1 minute</center> ');
|
||||
$.ajax({
|
||||
|
||||
// Adresse à laquelle la requête est envoyée
|
||||
url: 'requires/newvm.php',
|
||||
type : 'POST',
|
||||
data : 'cpu=' + cpu.val() + '&ram=' + ram.val() + '&disk=' + disk.val() + '&cluster=' + cluster.val(),
|
||||
// Le délai maximun en millisecondes de traitement de la demande
|
||||
timeout: 500000,
|
||||
|
||||
// La fonction à apeller si la requête aboutie
|
||||
success: function (data) {
|
||||
// Je charge les données dans box
|
||||
box.html(data);
|
||||
},
|
||||
|
||||
// La fonction à appeler si la requête n'a pas abouti
|
||||
error: function() {
|
||||
// J'affiche un message d'erreur
|
||||
box.html('<div class="alert alert-danger"> <strong>Error: </strong> Command failed, try again or contact an admin. </div>');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
$("#buttonnewvm").click(newvm);
|
||||
|
||||
});
|
||||
} );
|
56
code/web/www/pages/nodes.php
Executable file
|
@ -0,0 +1,56 @@
|
|||
<?php
|
||||
include(dirname(__DIR__).'/pages/includes/header.php');
|
||||
$html_HYPs = $html->List_HYPs($lastdate);
|
||||
|
||||
?>
|
||||
<div id="page-wrapper">
|
||||
<div class="row">
|
||||
<div class="col-lg-12">
|
||||
<h1 class="page-header">HYPERVISORS</h1>
|
||||
</div>
|
||||
<div class="col-lg-12" id="List_Dates">
|
||||
|
||||
|
||||
</div>
|
||||
<!-- /.col-lg-12 -->
|
||||
</div>
|
||||
<!-- /.row -->
|
||||
<div class="row">
|
||||
<div class="col-lg-12">
|
||||
<div class="panel panel-default">
|
||||
<!-- /.panel-heading -->
|
||||
<div class="panel-body" >
|
||||
|
||||
<table width="100%" class="table table-striped table-bordered table-hover" id="dataTables-hypervisors" >
|
||||
<thead class="thead-inverse">
|
||||
<tr>
|
||||
<th></th>
|
||||
<th data-priority="1">Cluster</th>
|
||||
<th data-priority="1">Name</th>
|
||||
<th data-priority="1">RAM(Used)</th>
|
||||
<th data-priority="1">RAM(Alloc/Total)</th>
|
||||
<th data-priority="1">CPU(Alloc/Total)</th>
|
||||
<th data-priority="1">STO(Used)*</th>
|
||||
<th data-priority="1">STO(Alloc/Total)</th>
|
||||
<th data-priority="1">Load</th>
|
||||
<th data-priority="1">Uptime</th>
|
||||
<th data-priority="1">Eligibility*</th>
|
||||
<th class="none" >Swap (used/total)</th>
|
||||
<th class="none" >PVE Version</th>
|
||||
<th class="none" >Kernel</th>
|
||||
<th class="none" >CPU - Informations</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<?php echo $html_HYPs; ?>
|
||||
</table>
|
||||
</div>
|
||||
<div id="result"></div>
|
||||
* The storage used is the largest.<br/>
|
||||
* This is a score to evaluate the eligibility to receive news VM. Lower score are the best.
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
include(dirname(__DIR__).'/pages/includes/footer.php');
|
||||
?>
|
15
code/web/www/pages/requires/configs.php
Executable file
|
@ -0,0 +1,15 @@
|
|||
<?php
|
||||
// Site
|
||||
$LANG = "EN";
|
||||
|
||||
//URL Site
|
||||
$baseurl = "http://www.eyeprox.lan";
|
||||
|
||||
|
||||
$sto_regx_status = false; // false = default on the size
|
||||
$sto_regx = "/((^VMs)|(!VG)).+/i"; // if not found, use size
|
||||
|
||||
$non_grata_weight = 1000;
|
||||
|
||||
$useldap = False;
|
||||
|
583
code/web/www/pages/requires/functions.php
Executable file
|
@ -0,0 +1,583 @@
|
|||
<?php
|
||||
|
||||
class API_GET_INFO
|
||||
{
|
||||
|
||||
public function GET_Dates($select="all")
|
||||
{
|
||||
$dates = curl("api/v1/static/dates/".$select);
|
||||
return $dates;
|
||||
}
|
||||
|
||||
public function GET_clusters_conf($cluster=null)
|
||||
{
|
||||
$cluster_conf = curl("api/v1/administration/cluster/".$cluster);
|
||||
return $cluster_conf;
|
||||
}
|
||||
|
||||
public function GET_qemu($date, $cluster=null, $node=null, $vmid= null)
|
||||
{
|
||||
|
||||
$qemu = curl("api/v1/static/instances/".$date."/");
|
||||
return $qemu;
|
||||
}
|
||||
|
||||
public function GET_hyp($date, $cluster=null, $node=null)
|
||||
{
|
||||
$nodes = curl("api/v1/static/nodes/".$date."/");
|
||||
return $nodes;
|
||||
}
|
||||
|
||||
public function GET_sto($date, $node = null, $storage = null)
|
||||
{
|
||||
|
||||
$storages = curl("api/v1/static/storages/".$date."/");
|
||||
return $storages;
|
||||
}
|
||||
|
||||
public function GET_Groups($date, $group = null)
|
||||
{
|
||||
if (!empty($group))
|
||||
$groups = curl($date."/groups/".$group);
|
||||
else
|
||||
$groups = curl($date."/groups/");
|
||||
|
||||
return $groups;
|
||||
}
|
||||
|
||||
public function GET_Disk($date, $cluster = null, $node = null)
|
||||
{
|
||||
$disks = curl("api/v1/static/disks/".$date."/".$cluster."/".$node."/");
|
||||
return $disks;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class API_Gen_HTML
|
||||
{
|
||||
|
||||
var $sto_regx; // regex ou size
|
||||
var $sto_regx_status;
|
||||
|
||||
public function View_VM($node, $search)
|
||||
{
|
||||
$d = new API_GET_INFO;
|
||||
$dates = $d->GET_Dates();
|
||||
$array = json_decode($dates, true);
|
||||
$result = array();
|
||||
foreach ($array as $keydate => $value)
|
||||
{
|
||||
$vm = $d->GET_qemu($keydate, $node, $search);
|
||||
$array = json_decode($vm, true);
|
||||
$array['cpu'] = $array['cpu']*100;
|
||||
$array['mem'] = $array['mem'] / (1024 * 1024);
|
||||
$array['timestamp'] = $array['timestamp'] * 1000;
|
||||
$array['netout'] = $array['netout'] / (1024 * 1024);
|
||||
$array['netin'] = $array['netin'] / (1024 * 1024);
|
||||
$result[] = $array;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
||||
public function List_Groups($timestamp = "")
|
||||
{
|
||||
$d = new API_GET_INFO;
|
||||
$groups = $d->GET_Groups($timestamp);
|
||||
$html = '';
|
||||
|
||||
$arr_groups = json_decode($groups, true);
|
||||
|
||||
|
||||
foreach ($arr_groups as $group)
|
||||
{
|
||||
$clusters = $d->GET_Groups($timestamp, $group);
|
||||
|
||||
$arr_clusters = json_decode($clusters, true);
|
||||
sort($arr_clusters);
|
||||
|
||||
reset($arr_clusters);
|
||||
if (!empty($group))
|
||||
{
|
||||
$html = $html.'<li><a href="#">'.$group.'<span class="fa arrow"></span></a>';
|
||||
$html = $html.'<ul class="nav nav-third-level">';
|
||||
foreach ($arr_clusters as $cluster)
|
||||
{
|
||||
$cluster = (object) $cluster;
|
||||
$html = $html.'<li><a href="cluster.php?cluster='.$cluster->cluster.'">'.$cluster->cluster.'</a></li>';
|
||||
}
|
||||
$html = $html.'</ul></li>';
|
||||
}
|
||||
else {
|
||||
$html = $html.'<li><a href="#">'.$group.'<span class="fa arrow"></span></a>';
|
||||
$html = $html.'<ul class="nav nav-second-level"></ul></li>';
|
||||
}
|
||||
}
|
||||
$html = $html.'';
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
|
||||
public function List_Dates($timestamp = "")
|
||||
{
|
||||
$d = new API_GET_INFO;
|
||||
$dates = $d->GET_Dates();
|
||||
$dates_list = json_decode($dates, true)['value'];
|
||||
arsort($dates_list);
|
||||
|
||||
$html = '<select id="List-Dates" name="date" class="selectpicker selectdate show-tick">';
|
||||
|
||||
foreach ($dates_list as $key => $value)
|
||||
{
|
||||
$date = (object) $value;
|
||||
if (intval($timestamp) == intval($date->date))
|
||||
$html = $html.'<option value='.$date->date.' selected="selected">'.date('m/d/Y H:i', $date->date).'</option>';
|
||||
else
|
||||
$html = $html.'<option value='.$date->date.'>'.date('m/d/Y H:i', $date->date).'</option>';
|
||||
}
|
||||
$html = $html.'</select>';
|
||||
return $html;
|
||||
}
|
||||
|
||||
|
||||
public function List_VMs($date, $node=null)
|
||||
{
|
||||
$html = '';
|
||||
$d = new API_GET_INFO;
|
||||
$vms_list = json_decode($d->GET_qemu($date), true)['value'];
|
||||
|
||||
|
||||
foreach ($vms_list as $qemu)
|
||||
{
|
||||
$qemu = (object) $qemu;
|
||||
$macs = "";
|
||||
$clusters_info = json_decode($d->GET_clusters_conf($qemu->cluster), true)['value'][0];
|
||||
$clusters_info = (object) $clusters_info;
|
||||
|
||||
foreach($qemu->macaddr as $mac) { $macs = $mac.",".$macs ; }
|
||||
$html = $html.'
|
||||
<tr>
|
||||
<td></td>
|
||||
<td>'.$qemu->cluster.'</td>
|
||||
<td><a href="node.php?hyp='.$qemu->node.'&date='.$date.'"> '.$qemu->node.'</a>
|
||||
|
||||
<a data-toggle="tooltip" title="External Link: https://'.$clusters_info->url.':'.$clusters_info->port.'" href="https://'.$clusters_info->url.':'.$clusters_info->port.'/#v1:0:=qemu%2F'.$qemu->vmid.':4::::::" target="_blank"> <img src="images/fb-lien-420.png" alt="ExternalProxmoxLink" style="width:20px;height:20px;"></a></td>
|
||||
<td><a href="vm.php?hyp='.$qemu->node.'&id='.$qemu->vmid.'&date='.$date.'"> '.$qemu->name.'</a></td>
|
||||
|
||||
|
||||
<td>'.$qemu->vmid.'</td>
|
||||
<td data-order="'.$qemu->maxmem.'">'.formatBytes(round($qemu->maxmem)).'</td>
|
||||
<td>'.$qemu->cpus.'</td>
|
||||
<td>xx GB</td>
|
||||
<td id="wrapper-mac"> <a data-toggle="tooltip" data-html="true" title="'.str_replace(",", "<br/>", $macs).'">'.$macs.'</a></td>
|
||||
<td>'.secondsToDays($qemu->uptime).'</td>
|
||||
<td>'.$qemu->status.'</td>
|
||||
<td>
|
||||
<select class="selectaction" data-width="auto" >
|
||||
<option value="{\'node\':\''.$qemu->node.'\',\'vmid\':\''.$qemu->vmid.'\',\'action\':\'none\'} ">Choice </option>
|
||||
<optgroup label="No unavailability risk">
|
||||
<option value="{\'node\':\''.$qemu->node.'\',\'vmid\':\''.$qemu->vmid.'\',\'action\':\'status\'}">Status</option>
|
||||
<option value="{\'node\':\''.$qemu->node.'\',\'vmid\':\''.$qemu->vmid.'\',\'action\':\'start\'} ">Start</option>
|
||||
</optgroup>
|
||||
<optgroup label="Hight unavailability risk">
|
||||
<option value="{\'node\':\''.$qemu->node.'\',\'vmid\':\''.$qemu->vmid.'\',\'action\':\'stop\'} ">Stop</option>
|
||||
<option value="{\'node\':\''.$qemu->node.'\',\'vmid\':\''.$qemu->vmid.'\',\'action\':\'shutdown\'} ">Shutdown</option>
|
||||
<option value="{\'node\':\''.$qemu->node.'\',\'vmid\':\''.$qemu->vmid.'\',\'action\':\'reset\'} ">Reset</option>
|
||||
</optgroup>
|
||||
<optgroup label="Others">
|
||||
<option disabled value="{\'node\':\''.$qemu->node.'\',\'vmid\':\''.$qemu->vmid.'\',\'action\':\'migration\'} ">Migration</option>
|
||||
</optgroup>
|
||||
</select>
|
||||
<!-- <img src="images/configuration_13194.png" alt="ExternalProxmoxLink" style="width:30px;height:30px;"> --> </td>
|
||||
</tr>';
|
||||
}
|
||||
return $html;
|
||||
}
|
||||
|
||||
public function List_HYPs($date, $cluster = null)
|
||||
{
|
||||
require(dirname(__DIR__).'/requires/configs.php');
|
||||
//$m = new REQUESTS_MYSQL;
|
||||
//$non_grata = $m->non_grata_select();
|
||||
|
||||
|
||||
$q = new API_GET_INFO;
|
||||
$nodes = json_decode($q->GET_hyp($date, $cluster), true)['value'];
|
||||
arsort($nodes);
|
||||
|
||||
$row_non_grata = [];
|
||||
|
||||
/*
|
||||
foreach ($non_grata as $rows) {
|
||||
$row_non_grata[] = $rows->name;
|
||||
}
|
||||
*/
|
||||
|
||||
$html = '';
|
||||
|
||||
foreach ($nodes as $node)
|
||||
{
|
||||
$node = (object) $node;
|
||||
|
||||
$sto_info = json_decode($q->GET_sto($date, $node->cluster, $node->name), true)['value'];
|
||||
|
||||
if ($this->sto_regx_status == true)
|
||||
{
|
||||
foreach ($sto_info as $sto)
|
||||
{
|
||||
$sto = (object)$sto;
|
||||
if (preg_match($this->sto_regx, $sto->storage))
|
||||
{
|
||||
$sto_el = $sto->storage;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if($sto_el == "" or $this->sto_regx_status == false)
|
||||
{
|
||||
foreach ($sto_info as $sto) {
|
||||
$sto = (object)$sto;
|
||||
$sto_new = $sto->total;
|
||||
if ($sto_new > $sto_max) {
|
||||
$sto_max = $sto_new;
|
||||
$sto_el = $sto->storage;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$sto_el_node = json_decode($q->GET_sto($date, $node->cluster, $node->name, $sto_el), true)['value'][0];
|
||||
$sto_el_node = (object) $sto_el_node;
|
||||
|
||||
|
||||
$clusters_info = json_decode($q->GET_clusters_conf($node->cluster), true)['value'][0];
|
||||
$clusters_info = (object) $clusters_info;
|
||||
|
||||
$ram_use_percent = round(($node->memory['used']/$node->memory['total'])*100);
|
||||
$ram_alloc_percent = round(($node->totalallocram/$node->memory['total'])*100);
|
||||
$cpu_alloc_percent = round(($node->totalalloccpu/$node->cpuinfo['cpus'])*100);
|
||||
$disk_use_percent = round((100/$sto_el_node->total)*$sto_el_node->used);
|
||||
$disk_alloc_percent = round(($sto_el_node->totalallocdisk/$sto_el_node->total)*100); // revoir param 1
|
||||
$load_percent = round($node->load*100);
|
||||
|
||||
$eligibility = eligibility($ram_use_percent, $ram_alloc_percent, $cpu_alloc_percent, $disk_use_percent, $disk_alloc_percent, $load_percent);
|
||||
|
||||
|
||||
if (in_array($node->name, $row_non_grata)) {
|
||||
$grata = '<a class="nongratalink" data-toggle="tooltip" title="Switch to grata" id="'.$node->node.'" action="sw_ON" node="'.$node->name.'" href="#" > <img src="images/nongrata_on.png" alt="Nongrataimg" style="width:16px;height:16px;"></a>';
|
||||
$eligibility = round($eligibility + $non_grata_weight);
|
||||
}
|
||||
else{
|
||||
$grata = '<a class="nongratalink" data-toggle="tooltip" title="Switch to non grata" id="'.$node->node.'" action="sw_OFF" node="'.$node->name.'" href="#" > <img src="images/nongrata_off.png" alt="Nongrataimg" style="width:16px;height:16px;"></a>';
|
||||
}
|
||||
|
||||
|
||||
$html = $html.'
|
||||
<tr>
|
||||
<td></td>
|
||||
<td>'.$node->cluster.'</td>
|
||||
<td>
|
||||
<a href="node.php?hyp='.$node->node.'&date='.$date.'"> '.$node->node.'</a>
|
||||
<a data-toggle="tooltip" title="External Link: https://'.$clusters_info->url.':'.$clusters_info->port.'" href="https://'.$clusters_info->url.':'.$clusters_info->port.'/#v1:0:=node%2F'.$node->name.':4:5:::::" target="_blank"> <img src="images/fb-lien-420.png" alt="ExternalProxmoxLink" style="width:20px;height:20px;"></a>
|
||||
'.$grata.'
|
||||
</td>
|
||||
<td style="color:'.testcolor("ram_use", $ram_use_percent).'" data-order="'.$ram_use_percent.'">'.formatBytes($node->memory['used']).' ('.$ram_use_percent.'%)</td>
|
||||
<td style="color:'.testcolor("ram_alloc", $ram_alloc_percent).'" data-order="'.$ram_alloc_percent.'">'.formatBytes($node->totalallocram).'/'.formatBytes($node->memory['total']).' ('.$ram_alloc_percent.'%)</td>
|
||||
<td style="color:'.testcolor("cpu_alloc", $cpu_alloc_percent).'" data-order="'.$cpu_alloc_percent.'">'.$node->totalalloccpu.'/'.$node->maxcpu.' ('.$cpu_alloc_percent.'%)</td>
|
||||
<td style="color:'.testcolor("disk_use", $disk_use_percent).'" data-order="'.$sto_el_node->used.'">'.formatBytes($sto_el_node->used).'('.$disk_use_percent.'% - '.$sto_el.')</td>
|
||||
<td style="color:'.testcolor("disk_alloc", $disk_alloc_percent).'" data-order="'.$sto_el_node->used.'">'.formatBytes($sto_el_node->totalallocdisk).'/'.formatBytes($sto_el_node->total).' ('.$disk_alloc_percent.'%) </td>
|
||||
<td style="color:'.testcolor("cpu_use", $load_percent).'" >'.$load_percent.'%</td>
|
||||
<td data-order="'.secondsToDays($node->uptime).'">'.secondsToDays($node->uptime).'d</td>
|
||||
<td>'.$eligibility.'</td>
|
||||
|
||||
|
||||
<td>'.formatBytes($node->swap['used']).'/'.formatBytes($node->swap['total']).'</td>
|
||||
<td>'.$node->pveversion.'</td>
|
||||
<td>'.$node->kversion.'</td>
|
||||
<td>'.$node->cpuinfo['model'].'</td>
|
||||
</tr>
|
||||
';
|
||||
}
|
||||
return $html;
|
||||
}
|
||||
|
||||
|
||||
public function List_STO($date, $node=null, $sto=null)
|
||||
{
|
||||
|
||||
$q = new API_GET_INFO;
|
||||
$stos_list = json_decode($q->GET_sto($date), true)['value'];
|
||||
$html = '';
|
||||
|
||||
foreach ($stos_list as $sto)
|
||||
{
|
||||
$sto = (object) $sto;
|
||||
|
||||
$clusters_info = json_decode($q->GET_clusters_conf($sto->cluster), true)['value'][0];
|
||||
$clusters_info = (object) $clusters_info;
|
||||
|
||||
try {
|
||||
$stoavail = round(($sto->avail * 100 ) / $sto->total);
|
||||
$stoused = round(100 - ($sto->avail * 100) / $sto->total);
|
||||
$disk_alloc_percent = round(($sto->totalallocdisk/$sto->total) * 100);
|
||||
} catch (Exception $e) {
|
||||
$stoavail = 'Not available';
|
||||
$stoused = 'Not available';
|
||||
$disk_alloc_percent = 'Not available';
|
||||
}
|
||||
|
||||
$htmldisk = '<table class="display nowrap responsive table table-striped table-bordered table-hover">
|
||||
<thead class="thead-inverse">
|
||||
<tr>
|
||||
<th>Type</th>
|
||||
<th>Vol.id</th>
|
||||
<th>Size</th>
|
||||
</tr>
|
||||
</thead>';
|
||||
|
||||
$disklists = json_decode($q->GET_Disk($date, $sto->cluster, $sto->node), true)['value'];
|
||||
|
||||
foreach ($disklists as $disklist) {
|
||||
$disklist = (object) $disklist;
|
||||
if ($disklist->storage == $sto->storage)
|
||||
$htmldisk = $htmldisk.' <tr><td>'.$disklist->content.'</td> <td>'.$disklist->volid.'</td> <td>'.formatBytes($disklist->size).'</td></tr>';
|
||||
}
|
||||
$htmldisk = $htmldisk.'</table>';
|
||||
|
||||
$html = $html.'
|
||||
<tr>
|
||||
<td></td>
|
||||
<td> <a href="node.php?hyp='.$sto->node.'&date='.$date.'"> '.$sto->node.'</a> <a data-toggle="tooltip" title="External Link: https://'.$clusters_info->url.':'.$clusters_info->port.'" href="https://'.$clusters_info->url.':'.$clusters_info->port.'/#v1:0:=storage%2F'.$sto->node.'%2F'.$sto->storage.':4::::::" target="_blank"> <img src="images/fb-lien-420.png" alt="ExternalProxmoxLink" style="width:20px;height:20px;"></a> </td>
|
||||
<td> '.$sto->storage.'</td>
|
||||
<td data-order="'.$sto->total.'"> '.formatBytes($sto->total).'</td>
|
||||
<td data-order="'.$sto->totalalloc.'"> '.formatBytes($sto->totalallocdisk).' ('.$disk_alloc_percent.'%)</td>
|
||||
<td data-order="'.$sto->avail.'"> '.formatBytes($sto->avail).' ('.$stoavail.'%)</td>
|
||||
<td data-order="'.$sto->used.'"> '.formatBytes($sto->used).' ('.$stoused.'%)</td>
|
||||
<td> '.$htmldisk.' </td>
|
||||
</tr>';
|
||||
}
|
||||
return $html;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
function testcolor($type, $value)
|
||||
{
|
||||
|
||||
// charges points in percents
|
||||
$cpu_low = 30; // less than
|
||||
$cpu_height = 60 ; // more than
|
||||
|
||||
$cpu_low_alloc = 100; // less than
|
||||
$cpu_height_alloc = 200 ; // more than
|
||||
|
||||
$ram_low = 50; // less than
|
||||
$ram_height = 75 ; // more than
|
||||
|
||||
$ram_low_alloc = 75; // less than
|
||||
$ram_height_alloc = 110 ; // more than
|
||||
|
||||
$disk_low = 50; // less than
|
||||
$disk_height = 70 ; // more than
|
||||
|
||||
$disk_low_alloc = 90; // less than
|
||||
$disk_height_alloc = 190 ; // more than
|
||||
|
||||
$color = "";
|
||||
|
||||
$l_color = '#088A08'; // Green
|
||||
$m_color = '#DF7401'; // Yellow
|
||||
$h_color = '#B40404'; // Red
|
||||
|
||||
$array_calc = array(
|
||||
"ram_alloc" => array("low" => $ram_low_alloc, "height" =>$ram_height_alloc),
|
||||
"ram_use" => array("low" => $ram_low, "height" => $ram_height),
|
||||
"disk_use" => array("low" => $disk_low, "height" => $disk_height),
|
||||
"disk_alloc" => array("low" => $disk_low_alloc, "height" => $disk_height_alloc),
|
||||
"cpu_alloc" => array("low" => $cpu_low_alloc, "height" => $cpu_height_alloc),
|
||||
"cpu_use" => array("low" => $cpu_low, "height" => $cpu_height)
|
||||
);
|
||||
|
||||
if($value < $array_calc[$type]["low"])
|
||||
$color = $l_color;
|
||||
elseif (($array_calc[$type]["low"] <= $value ) and ($value < $array_calc[$type]["height"]))
|
||||
$color = $m_color;
|
||||
elseif ($value >= $array_calc[$type]["height"])
|
||||
$color = $h_color;
|
||||
|
||||
|
||||
return $color;
|
||||
}
|
||||
|
||||
function testvalue($val, $min, $max) {
|
||||
return ($val >= $min && $val <= $max);
|
||||
}
|
||||
|
||||
|
||||
class DbConn
|
||||
{
|
||||
public $conn;
|
||||
public function __construct()
|
||||
{
|
||||
require(dirname(__DIR__).'/dbconf.php');
|
||||
$this->host = $host; // Host name
|
||||
$this->username = $username; // Mysql username
|
||||
$this->password = $password; // Mysql password
|
||||
$this->db_name = $db_name; // Database name
|
||||
$this->tbl_logs = $tbl_logs;
|
||||
$this->tbl_nodes = $tbl_nodes;
|
||||
try {
|
||||
// Connect to server and select database.
|
||||
$this->conn = new PDO('mysql:host=' . $host . ';dbname=' . $db_name . ';charset=utf8', $username, $password);
|
||||
$this->conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
||||
|
||||
} catch (\Exception $e) {
|
||||
error_log("Database connection error:".$e);
|
||||
die('Database connection error');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class REQUESTS_MYSQL
|
||||
{
|
||||
|
||||
function non_grata_select()
|
||||
{
|
||||
try {
|
||||
$db = new DbConn;
|
||||
$tbl_nodes = $db->tbl_nodes;
|
||||
$stmt = $db->conn->prepare("SELECT `name` FROM ".$tbl_nodes." WHERE `status` = 1");
|
||||
$stmt->execute();
|
||||
$result = $stmt->fetchAll(PDO::FETCH_OBJ);
|
||||
return $result;
|
||||
} catch (PDOException $e) {
|
||||
$err = "Error: " . $e->getMessage();
|
||||
}
|
||||
|
||||
//Determines returned value ('true' or error code)
|
||||
$resp = ($err == '') ? 'true' : $err;
|
||||
return $resp;
|
||||
}
|
||||
|
||||
function non_grata_update($node, $value)
|
||||
{
|
||||
try {
|
||||
$db = new DbConn;
|
||||
$tbl_nodes = $db->tbl_nodes;
|
||||
$stmt = $db->conn->prepare("REPLACE INTO ".$tbl_nodes."(`name`, `status`) VALUES ('".$node."','".$value."')");
|
||||
$stmt->execute();
|
||||
$result = $stmt->fetchAll(PDO::FETCH_OBJ);
|
||||
return $result;
|
||||
} catch (PDOException $e) {
|
||||
$err = "Error: " . $e->getMessage();
|
||||
}
|
||||
//Determines returned value ('true' or error code)
|
||||
$resp = ($err == '') ? 'true' : $err;
|
||||
return $resp;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function eligibility($ram_use, $ram_alloc, $cpu_alloc, $disk_use, $disk_alloc, $load) // data in percent !!! // ' .$sto->total - $sto->avail - $sto->used.'
|
||||
{
|
||||
$coef_ram_use = 4;
|
||||
$coef_ram_alloc = 3;
|
||||
$coef_cpu_alloc = 2;
|
||||
$coef_disk_use = 4;
|
||||
$coef_disk_alloc = 3;
|
||||
$coef_load = 3;
|
||||
|
||||
$coef_total = $coef_ram_use + $coef_ram_alloc + $coef_cpu_alloc + $coef_disk_use + $coef_disk_alloc + $coef_load;
|
||||
$calc = 0 - ($ram_use * $coef_ram_use) - ($ram_alloc * $coef_ram_alloc) - ($cpu_alloc * $coef_cpu_alloc) - ($disk_use * $coef_disk_use) - ($disk_alloc * $coef_disk_alloc) - ($load * $coef_load);
|
||||
$calc = $calc / $coef_total;
|
||||
$calc = $calc / 10;
|
||||
|
||||
return round($calc*-1,1);
|
||||
}
|
||||
|
||||
|
||||
function curl($url, $ip="127.0.0.1", $port="8080", $type="GET", $fieldsjson="")
|
||||
{
|
||||
|
||||
$url = "http://".$ip.":".$port."/".$url;
|
||||
$ch = curl_init();
|
||||
|
||||
if($type == "POST")
|
||||
{
|
||||
curl_setopt($ch,CURLOPT_POST, count($fieldsjson));
|
||||
curl_setopt($ch,CURLOPT_POSTFIELDS, $fieldsjson);
|
||||
}
|
||||
|
||||
curl_setopt($ch, CURLOPT_URL, $url);
|
||||
curl_setopt($ch, CURLOPT_HEADER, false);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
|
||||
|
||||
$data = curl_exec($ch);
|
||||
curl_close($ch);
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
|
||||
function secondsToDays($seconds)
|
||||
{
|
||||
// extract hours
|
||||
$days = floor($seconds / 86400);
|
||||
return $days;
|
||||
}
|
||||
|
||||
function secondsToTime($seconds)
|
||||
{
|
||||
// extract hours
|
||||
$hours = floor($seconds / (60 * 60));
|
||||
|
||||
// extract minutes
|
||||
$divisor_for_minutes = $seconds % (60 * 60);
|
||||
$minutes = floor($divisor_for_minutes / 60);
|
||||
|
||||
// extract the remaining seconds
|
||||
$divisor_for_seconds = $divisor_for_minutes % 60;
|
||||
$seconds = ceil($divisor_for_seconds);
|
||||
|
||||
// return the final array
|
||||
$obj = array(
|
||||
"h" => (int) $hours,
|
||||
"m" => (int) $minutes,
|
||||
"s" => (int) $seconds,
|
||||
);
|
||||
return $obj;
|
||||
}
|
||||
|
||||
function formatBytes($bytes, $precision = 2) {
|
||||
$kilobyte = 1024;
|
||||
$megabyte = $kilobyte * 1024;
|
||||
$gigabyte = $megabyte * 1024;
|
||||
$terabyte = $gigabyte * 1024;
|
||||
|
||||
if (($bytes >= 0) && ($bytes < $kilobyte)) {
|
||||
return $bytes . ' B';
|
||||
|
||||
} elseif (($bytes >= $kilobyte) && ($bytes < $megabyte)) {
|
||||
return round($bytes / $kilobyte, $precision) . ' KB';
|
||||
|
||||
} elseif (($bytes >= $megabyte) && ($bytes < $gigabyte)) {
|
||||
return round($bytes / $megabyte, $precision) . ' MB';
|
||||
|
||||
} elseif (($bytes >= $gigabyte) && ($bytes < $terabyte)) {
|
||||
return round($bytes / $gigabyte, $precision) . ' GB';
|
||||
|
||||
} elseif ($bytes >= $terabyte) {
|
||||
return round($bytes / $terabyte, $precision) . ' TB';
|
||||
} else {
|
||||
return $bytes . ' B';
|
||||
}
|
||||
}
|
75
code/web/www/pages/vms.php
Executable file
|
@ -0,0 +1,75 @@
|
|||
<?php
|
||||
|
||||
include(dirname(__DIR__).'/pages/includes/header.php');
|
||||
|
||||
|
||||
$html_VMs = $html->List_VMs($lastdate);
|
||||
|
||||
?>
|
||||
<div id="page-wrapper">
|
||||
<div class="row">
|
||||
<div class="col-lg-12">
|
||||
<h1 class="page-header">VM list</h1>
|
||||
</div>
|
||||
<div class="col-lg-12" id="List_Dates">
|
||||
|
||||
|
||||
</div>
|
||||
<!-- /.col-lg-12 -->
|
||||
</div>
|
||||
<!-- /.row -->
|
||||
<div class="row">
|
||||
<div class="col-lg-12">
|
||||
<div class="panel panel-default">
|
||||
|
||||
<!-- /.panel-heading -->
|
||||
<div class="result"></div>
|
||||
<div class="panel-body" >
|
||||
|
||||
<table width="100%" class="display nowrap table table-striped table-bordered table-hover dataTables-vm">
|
||||
<thead class="thead-inverse">
|
||||
<tr>
|
||||
<th></th>
|
||||
<th data-priority="1">Cluster</th>
|
||||
<th data-priority="1">Node</th>
|
||||
<th data-priority="1">Name</th>
|
||||
<th data-priority="1">vmid</th>
|
||||
<th data-priority="1">RAM</th>
|
||||
<th data-priority="1">CPU </th>
|
||||
<th data-priority="1">Disk</th>
|
||||
<th data-priority="1">Macs</th>
|
||||
<th data-priority="1">Uptime</th>
|
||||
<th data-priority="1">Status</th>
|
||||
<th data-priority="0">Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<?php echo $html_VMs; ?>
|
||||
</table>
|
||||
</div>
|
||||
<div class="result"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- /#wrapper -->
|
||||
<div id="dialog-form" title="/!\ VM ACTION /!\" style="background-color: #8c8c8c;z-index: 3;">
|
||||
<p class="validateTips">Proxmox authentification required.</p>
|
||||
<form>
|
||||
<fieldset>
|
||||
<label for="name">Username:</label>
|
||||
<input type="text" name="name" id="name" value="root@pam" class="text ui-widget-content ui-corner-all">
|
||||
<br />
|
||||
<label for="password">Password:</label>
|
||||
<input type="password" name="password" id="password" value="" class="text ui-widget-content ui-corner-all">
|
||||
|
||||
<input type="hidden" name="action" id="action" value="">
|
||||
<input type="hidden" name="vmid" id="vmid" value="">
|
||||
<input type="hidden" name="node" id="node" value="">
|
||||
<input type="submit" tabindex="-1" style="position:absolute; top:-1000px">
|
||||
</fieldset>
|
||||
</form>
|
||||
</div>
|
||||
<?php
|
||||
include(dirname(__DIR__).'/pages/includes/footer.php');
|
||||
?>
|