Compare commits
21 commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
31f878a586 | ||
![]() |
2c2acd2c4c | ||
![]() |
74b2a1ab3f | ||
![]() |
dfffdb7efe | ||
![]() |
7dd0561e41 | ||
![]() |
031554e100 | ||
![]() |
c538f09a3a | ||
![]() |
229a085075 | ||
![]() |
9f7c3f6e46 | ||
![]() |
426b3eb451 | ||
![]() |
58d60ae1a6 | ||
![]() |
6d38fe8da9 | ||
![]() |
bf5a33664a | ||
![]() |
db310f6afd | ||
![]() |
28730dbea1 | ||
![]() |
fbff359d99 | ||
![]() |
426f632ba5 | ||
![]() |
2f4e458d44 | ||
![]() |
22732a6504 | ||
![]() |
b782fbb2cb | ||
![]() |
2c40dd5743 |
65
CHANGELOG.md
|
@ -1,25 +1,50 @@
|
|||
# v2.2.0
|
||||
- Feature: Additional configuration properties have been added to the web form for creating Storage Pools and Storage Volumes, including clustered servers
|
||||
- Feature: Additional configuration properties have been added to the web form for creating Projects
|
||||
- Feature: Added cluster configuration to the creation of networks from form entries
|
||||
- Feature: Filtered the default view of Storage Volumes to show only custom type storage volumes by default and provided link to remove this filter
|
||||
# v3.8.0
|
||||
- Added a check for a null config in storage pools
|
||||
- Added image token cleanup with downloading images while in a cluster
|
||||
|
||||
# v2.1.0
|
||||
- Feature: Users can now add network, disk, and proxy devices directly to an instance from a form
|
||||
- Feature: Users can now remove network, disk, and proxy devices from an instance using the dashboard
|
||||
- Feature: Additional configuration properties have been added to the web form for creating Networks
|
||||
- Feature: Users can add/remove Network ACL egress/ingress rules using the dashboard
|
||||
- Feature: The Exec terminal experience has been added to instances
|
||||
- Feature: Users can click on the "Check for updates" button in the About modal to get a version status
|
||||
|
||||
# v2.0.3
|
||||
- Bug Fix: Continuing the bug fix from previous version, used float type casting for memory variables on remote-single page rather than letting PHP automatically deciding on variable type.
|
||||
# v3.7.0
|
||||
- Set console/exec terminal height to 25 rows because xterm.js defaults to 24 and lxd defaults to 25 there was a single row mismatch
|
||||
- Added qemu.conf to virtual machine configuration options
|
||||
- Changed cloud-init user data to use POST method rather than GET
|
||||
- Merged pull request improving websocket close on exec/console websockets
|
||||
- Added check for empty storage pool source configuration array item
|
||||
|
||||
# v2.0.2
|
||||
- Bug Fix: Replaced PHP round() function with number_format() to force the format of two decimal places on instance-single and remote-single pages.
|
||||
# v3.6.0
|
||||
- Merged pull request adding cloud init user data option for new containers via form
|
||||
- Fixed typo preventing OS version number from showing in remotes-single.php page, under LXD Information
|
||||
|
||||
# v2.0.1
|
||||
- Bug Fix: Added strtolower() when comparing if cluster member is fully operational. Both "Fully operational" and "fully operational" messages now result to true when providing a list of cluster members to migrate an instance to.
|
||||
# v3.5.0
|
||||
- Updated container image catalog based on results from from https://us.lxd.images
|
||||
- Merged pull request updating MySQL statements for auto increment and now time
|
||||
|
||||
# v2.0.0
|
||||
- initial release of the LXDWARE LXD dashboard version 2.0.0
|
||||
# v3.4.0
|
||||
- Added additional delete option for powered-off instances on the containers and virtual machines pages
|
||||
- Fixed bug in populating both profile and cluster member options in drop-down box for virtual machine configurations
|
||||
- Added verification for numeric values in instance memory gauge display
|
||||
|
||||
# v3.3.0
|
||||
- Updated PDO try-catch exception for PHP 8
|
||||
- Created recursive PHP in_array for SQLite Pragma array search in PHP 8
|
||||
- Improved handling of external port for remotes
|
||||
- Fixed bug with scope of curl variables
|
||||
|
||||
# v3.2.0
|
||||
- added removal confirmation of remote hosts
|
||||
- added preference choices for logging and logs page
|
||||
- added preferences for custom page refresh rates
|
||||
- added preferences for custom API connection and operation timeout
|
||||
- improved CPU gauge, changing from top to /proc/stat readings
|
||||
- improved handling connection to unresponsive remote hosts
|
||||
- fixed bug with adding hosts due to data type
|
||||
|
||||
# v3.1.0
|
||||
- improved performance of page loads
|
||||
- updated instance backups to include a filesize of exported files
|
||||
- updated exporting backup image to using a script to spawn it off into a background process
|
||||
- updated remote host table header
|
||||
- updated link to display all volume types on storage volumes page
|
||||
- reduced curl connection timeout
|
||||
|
||||
# v3.0.0
|
||||
- initial release of the LXDWARE LXD dashboard version 3.0.0
|
3
default
|
@ -2,7 +2,7 @@ server {
|
|||
listen 80 default_server;
|
||||
listen [::]:80 default_server;
|
||||
root /var/www/html/lxd-dashboard;
|
||||
index index.html;
|
||||
index index.php index.html;
|
||||
server_name _;
|
||||
|
||||
location / {
|
||||
|
@ -13,6 +13,7 @@ server {
|
|||
#include snippets/fastcgi-php.conf;
|
||||
#fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
|
||||
fastcgi_pass unix:/run/php/php7.4-fpm.sock;
|
||||
#fastcgi_pass unix:/run/php/php8.1-fpm.sock;
|
||||
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
|
||||
include fastcgi_params;
|
||||
include snippets/fastcgi-php.conf;
|
||||
|
|
|
@ -1,27 +1,192 @@
|
|||
.bg-dark {
|
||||
background-color: #262626 !important;
|
||||
background-size: cover;
|
||||
}
|
||||
background-color: #262626 !important;
|
||||
background-size: cover;
|
||||
}
|
||||
|
||||
.btn-danger {
|
||||
color: #fff;
|
||||
background-color: #ff0000;
|
||||
border-color: #ff0000;
|
||||
}
|
||||
.btn-danger {
|
||||
color: #fff;
|
||||
background-color: #ff0000;
|
||||
border-color: #ff0000;
|
||||
}
|
||||
|
||||
.text-danger {
|
||||
color: #ff0000 !important;
|
||||
}
|
||||
.text-danger {
|
||||
color: #ff0000 !important;
|
||||
}
|
||||
|
||||
|
||||
code {
|
||||
font-size: 87.5%;
|
||||
color: #ff0000 !important;
|
||||
word-break: break-word;
|
||||
}
|
||||
code {
|
||||
font-size: 87.5%;
|
||||
color: #ff0000 !important;
|
||||
word-break: break-word;
|
||||
}
|
||||
|
||||
.sidebar.toggled .nav-item .nav-link {
|
||||
text-align: center;
|
||||
padding: 0.5rem 1rem;
|
||||
width: 6.5rem;
|
||||
.sidebar.toggled .nav-item .nav-link {
|
||||
text-align: center;
|
||||
padding: 0.5rem 1rem;
|
||||
width: 6.5rem;
|
||||
}
|
||||
|
||||
.sidebar .nav-item .nav-link {
|
||||
display: block;
|
||||
width: 100%;
|
||||
text-align: left;
|
||||
padding: 0.8rem 1rem;
|
||||
width: 14rem;
|
||||
}
|
||||
|
||||
|
||||
.pb-6,
|
||||
.py-6 {
|
||||
padding-bottom: 6rem !important;
|
||||
}
|
||||
|
||||
.sidebar-divider-right {
|
||||
border-right: 1px solid #444 !important;
|
||||
}
|
||||
|
||||
.btn-xs, .btn-group-xs > .btn {
|
||||
padding: 0.25rem 0.5rem;
|
||||
font-size: 0.7rem;
|
||||
line-height: .7;
|
||||
border-radius: 0.2rem;
|
||||
}
|
||||
|
||||
.progress-circle {
|
||||
width: 150px;
|
||||
height: 150px;
|
||||
background: none;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.progress-circle::after {
|
||||
content: "";
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: 50%;
|
||||
border: 12px solid #eee;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.progress-circle>span {
|
||||
width: 50%;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.progress-circle .progress-circle-left {
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.progress-circle .progress-circle-bar {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: none;
|
||||
border-width: 12px;
|
||||
border-style: solid;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
.progress-circle .progress-circle-left .progress-circle-bar {
|
||||
left: 100%;
|
||||
border-top-right-radius: 80px;
|
||||
border-bottom-right-radius: 80px;
|
||||
border-left: 0;
|
||||
-webkit-transform-origin: center left;
|
||||
transform-origin: center left;
|
||||
}
|
||||
|
||||
.progress-circle .progress-circle-right {
|
||||
right: 0;
|
||||
}
|
||||
|
||||
.progress-circle .progress-circle-right .progress-circle-bar {
|
||||
left: -100%;
|
||||
border-top-left-radius: 80px;
|
||||
border-bottom-left-radius: 80px;
|
||||
border-right: 0;
|
||||
-webkit-transform-origin: center right;
|
||||
transform-origin: center right;
|
||||
}
|
||||
|
||||
.progress-circle .progress-circle-value {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
.progress-circle-xs {
|
||||
width: 75px;
|
||||
height: 75px;
|
||||
background: none;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.progress-circle-xs::after {
|
||||
content: "";
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: 50%;
|
||||
border: 4px solid #eee;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.progress-circle-xs>span {
|
||||
width: 50%;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.progress-circle-xs .progress-circle-left-xs {
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.progress-circle-xs .progress-circle-bar-xs {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: none;
|
||||
border-width: 4px;
|
||||
border-style: solid;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
.progress-circle-xs .progress-circle-left-xs .progress-circle-bar-xs {
|
||||
left: 100%;
|
||||
border-top-right-radius: 80px;
|
||||
border-bottom-right-radius: 80px;
|
||||
border-left: 0;
|
||||
-webkit-transform-origin: center left;
|
||||
transform-origin: center left;
|
||||
}
|
||||
|
||||
.progress-circle-xs .progress-circle-right-xs {
|
||||
right: 0;
|
||||
}
|
||||
|
||||
.progress-circle-xs .progress-circle-right-xs .progress-circle-bar-xs {
|
||||
left: -100%;
|
||||
border-top-left-radius: 80px;
|
||||
border-bottom-left-radius: 80px;
|
||||
border-right: 0;
|
||||
-webkit-transform-origin: center right;
|
||||
transform-origin: center right;
|
||||
}
|
||||
|
||||
.progress-circle-xs .progress-circle-value-xs {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
}
|
|
@ -22,10 +22,20 @@ if (!isset($_SESSION)) {
|
|||
session_start();
|
||||
}
|
||||
|
||||
//Require code from lxd-dashboard/php/config/db.php
|
||||
//Require code from lxd-dashboard/backend/config/db.php
|
||||
require_once('../config/db.php');
|
||||
|
||||
function logEvent($action, $remote, $project, $object, $status_code, $message){
|
||||
//Will be used in future releases with remote database option
|
||||
function logEvent($action, $remote, $project, $object, $status_code, $message, $user_id = 0){
|
||||
$logs_enabled_value = retrievePreference("logs_enabled");
|
||||
|
||||
if ($logs_enabled_value == 'true'){
|
||||
$hostname = gethostname();
|
||||
|
||||
if ($user_id == 0){
|
||||
$user_id = (!empty($_SESSION['user_id'])) ? $_SESSION['user_id'] : 0;
|
||||
}
|
||||
|
||||
$event_added = addLogEvent($action, $remote, $project, $object, $status_code, $message, $hostname, $user_id);
|
||||
}
|
||||
}
|
||||
?>
|
184
lxd-dashboard/backend/aaa/authentication.php
Normal file
|
@ -0,0 +1,184 @@
|
|||
<?php
|
||||
/*
|
||||
LXDWARE LXD Dashboard - A web-based interface for managing LXD servers
|
||||
Copyright (C) 2020-2021 LXDWARE.COM
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
//Start session if not already started
|
||||
if (!isset($_SESSION)) {
|
||||
session_start();
|
||||
}
|
||||
|
||||
//Declare and instantiate GET variables
|
||||
$action = (isset($_GET['action'])) ? filter_var(urldecode($_GET['action']), FILTER_SANITIZE_STRING) : "";
|
||||
$project = (isset($_GET['project'])) ? filter_var(urldecode($_GET['project']), FILTER_SANITIZE_STRING) : "";
|
||||
$remote = (isset($_GET['remote'])) ? filter_var(urldecode($_GET['remote']), FILTER_SANITIZE_NUMBER_INT) : "";
|
||||
|
||||
//Declare and instantiate POST variables
|
||||
$username = (isset($_POST['username'])) ? filter_var(urldecode($_POST['username']), FILTER_SANITIZE_STRING) : "";
|
||||
$password = (isset($_POST['password'])) ? filter_var(urldecode($_POST['password']), FILTER_SANITIZE_STRING) : "";
|
||||
|
||||
//Require code from lxd-dashboard/backend/config/db.php
|
||||
require_once('../config/db.php');
|
||||
|
||||
//Require code from lxd-dashboard/backend/aaa/authorization.php
|
||||
require_once('../aaa/authorization.php');
|
||||
|
||||
//Require code from lxd-dashboard/backend/aaa/accounting.php
|
||||
require_once('../aaa/accounting.php');
|
||||
|
||||
//Run the matching action
|
||||
switch ($action) {
|
||||
|
||||
case "authenticateUser":
|
||||
//Determine user info from database
|
||||
foreach (retrieveUserRecord($username) as $record){
|
||||
$user_id = $record['id'];
|
||||
$passwd_hash = $record['passwd_hash'];
|
||||
}
|
||||
|
||||
//Verify password matches existing database passwd_hash
|
||||
if (password_verify($password, $passwd_hash)) {
|
||||
|
||||
//Store username and user_id in SESSION variable
|
||||
$_SESSION['username'] = $username;
|
||||
$_SESSION['user_id'] = $user_id;
|
||||
|
||||
//Get all the roles that the user belongs to
|
||||
$roles = array();
|
||||
foreach (retrieveUserRoles($user_id) as $role){
|
||||
array_push($roles, $role['name']);
|
||||
}
|
||||
|
||||
//Make sure array only has unique values
|
||||
$roles = array_unique($roles);
|
||||
|
||||
//Get array of contols based on the user's roles
|
||||
$controls = getControls($roles);
|
||||
|
||||
//Store user's controls in a SESSION array
|
||||
$_SESSION['controls'] = $controls;
|
||||
|
||||
//Store preference values in SESSION array
|
||||
$preferences = retrieveTableRows("lxd_preferences");
|
||||
foreach ($preferences as $preference){
|
||||
//API Preferences
|
||||
if ($preference['name'] == "get_connection_timeout")
|
||||
$_SESSION['get_connection_timeout'] = $preference['value'];
|
||||
if ($preference['name'] == "get_operation_timeout")
|
||||
$_SESSION['get_operation_timeout'] = $preference['value'];
|
||||
if ($preference['name'] == "post_connection_timeout")
|
||||
$_SESSION['post_connection_timeout'] = $preference['value'];
|
||||
if ($preference['name'] == "post_operation_timeout")
|
||||
$_SESSION['post_operation_timeout'] = $preference['value'];
|
||||
if ($preference['name'] == "patch_connection_timeout")
|
||||
$_SESSION['patch_connection_timeout'] = $preference['value'];
|
||||
if ($preference['name'] == "patch_operation_timeout")
|
||||
$_SESSION['patch_operation_timeout'] = $preference['value'];
|
||||
if ($preference['name'] == "put_connection_timeout")
|
||||
$_SESSION['put_connection_timeout'] = $preference['value'];
|
||||
if ($preference['name'] == "put_operation_timeout")
|
||||
$_SESSION['put_operation_timeout'] = $preference['value'];
|
||||
if ($preference['name'] == "delete_connection_timeout")
|
||||
$_SESSION['delete_connection_timeout'] = $preference['value'];
|
||||
if ($preference['name'] == "delete_operation_timeout")
|
||||
$_SESSION['delete_operation_timeout'] = $preference['value'];
|
||||
//Page Refresh Preferences
|
||||
if ($preference['name'] == "certificates_page_rate")
|
||||
$_SESSION['certificates_page_rate'] = $preference['value'];
|
||||
if ($preference['name'] == "cluster_members_page_rate")
|
||||
$_SESSION['cluster_members_page_rate'] = $preference['value'];
|
||||
if ($preference['name'] == "containers_page_rate")
|
||||
$_SESSION['containers_page_rate'] = $preference['value'];
|
||||
if ($preference['name'] == "containers_single_page_rate")
|
||||
$_SESSION['containers_single_page_rate'] = $preference['value'];
|
||||
if ($preference['name'] == "images_page_rate")
|
||||
$_SESSION['images_page_rate'] = $preference['value'];
|
||||
if ($preference['name'] == "logs_page_rate")
|
||||
$_SESSION['logs_page_rate'] = $preference['value'];
|
||||
if ($preference['name'] == "network_acls_page_rate")
|
||||
$_SESSION['network_acls_page_rate'] = $preference['value'];
|
||||
if ($preference['name'] == "networks_page_rate")
|
||||
$_SESSION['networks_page_rate'] = $preference['value'];
|
||||
if ($preference['name'] == "operations_page_rate")
|
||||
$_SESSION['operations_page_rate'] = $preference['value'];
|
||||
if ($preference['name'] == "profiles_page_rate")
|
||||
$_SESSION['profiles_page_rate'] = $preference['value'];
|
||||
if ($preference['name'] == "projects_page_rate")
|
||||
$_SESSION['projects_page_rate'] = $preference['value'];
|
||||
if ($preference['name'] == "remotes_single_page_rate")
|
||||
$_SESSION['remotes_single_page_rate'] = $preference['value'];
|
||||
if ($preference['name'] == "remotes_page_rate")
|
||||
$_SESSION['remotes_page_rate'] = $preference['value'];
|
||||
if ($preference['name'] == "simplestreams_page_rate")
|
||||
$_SESSION['simplestreams_page_rate'] = $preference['value'];
|
||||
if ($preference['name'] == "storage_pools_page_rate")
|
||||
$_SESSION['storage_pools_page_rate'] = $preference['value'];
|
||||
if ($preference['name'] == "storage_volumes_page_rate")
|
||||
$_SESSION['storage_volumes_page_rate'] = $preference['value'];
|
||||
if ($preference['name'] == "virtual_machines_page_rate")
|
||||
$_SESSION['virtual_machines_page_rate'] = $preference['value'];
|
||||
if ($preference['name'] == "virtual_machines_single_page_rate")
|
||||
$_SESSION['virtual_machines_single_page_rate'] = $preference['value'];
|
||||
}
|
||||
|
||||
$results = '{"status": "Ok", "status_code": 200, "metadata": "{}"}';
|
||||
}
|
||||
else {
|
||||
//Return 401 Unauthorized despite it technically being unauthenticated
|
||||
$results = '{"status": "Unauthorized", "status_code": 401, "metadata": {"error": "Incorrect username or password"}}';
|
||||
}
|
||||
|
||||
echo $results;
|
||||
|
||||
//Send event to accounting
|
||||
$event = json_decode($results, true);
|
||||
$object = $username;
|
||||
logEvent($action, $remote, $project, $object, $event['status_code'], $event['status']);
|
||||
|
||||
break;
|
||||
|
||||
case "deauthenticateUser":
|
||||
$username = $_SESSION['username'];
|
||||
$user_id = $_SESSION['user_id'];
|
||||
//Clear the SESSION variables
|
||||
$_SESSION = array();
|
||||
if (session_destroy())
|
||||
$results = '{"status": "Ok", "status_code": 200, "metadata": "{}"}';
|
||||
|
||||
echo $results;
|
||||
|
||||
//Send event to accounting
|
||||
$event = json_decode($results, true);
|
||||
$object = $username;
|
||||
logEvent($action, $remote, $project, $object, $event['status_code'], $event['status'], $user_id);
|
||||
|
||||
break;
|
||||
|
||||
case "validateAuthentication":
|
||||
if (isset($_SESSION['username'])){
|
||||
echo '{"status": "Ok", "status_code": 200, "metadata": "{}"}';
|
||||
}
|
||||
else {
|
||||
echo '{"status": "Unauthorized", "status_code": 401, "metadata": {"error": "Failed authentication validation"}}';
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
echo "LXDWARE";
|
||||
}
|
||||
|
||||
?>
|
86
lxd-dashboard/backend/admin/logs.php
Normal file
|
@ -0,0 +1,86 @@
|
|||
<?php
|
||||
/*
|
||||
LXDWARE LXD Dashboard - A web-based interface for managing LXD servers
|
||||
Copyright (C) 2020-2021 LXDWARE.COM
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
//Start session if not already started
|
||||
if (!isset($_SESSION)) {
|
||||
session_start();
|
||||
}
|
||||
|
||||
//Declare and instantiate GET variables
|
||||
$action = (isset($_GET['action'])) ? filter_var(urldecode($_GET['action']), FILTER_SANITIZE_STRING) : "";
|
||||
|
||||
//Require code from lxd-dashboard/backend/config/db.php
|
||||
require_once('../config/db.php');
|
||||
|
||||
//Require code from lxd-dashboard/backend/aaa/accounting.php
|
||||
require_once('../aaa/accounting.php');
|
||||
|
||||
if (isset($_SESSION['username'])) {
|
||||
|
||||
require_once('../aaa/authorization.php');
|
||||
|
||||
//Run the matching action
|
||||
switch ($action) {
|
||||
|
||||
case "listLogEvents":
|
||||
$logs_retrieval = intval(retrievePreference("logs_retrieval"));
|
||||
if ($logs_retrieval < 1){
|
||||
$logs_retrieval = 100;
|
||||
}
|
||||
|
||||
$rows = retrieveTableRows('lxd_logs', $logs_retrieval);
|
||||
|
||||
$i = 0;
|
||||
echo '{ "data": [';
|
||||
|
||||
foreach ($rows as $row){
|
||||
|
||||
if ($i > 0){
|
||||
echo ",";
|
||||
}
|
||||
$i++;
|
||||
|
||||
echo "[ ";
|
||||
|
||||
echo '"';
|
||||
echo "<i class='fas fa-history fa-lg' style='color:#4e73df'></i>";
|
||||
echo '",';
|
||||
|
||||
echo '"' . htmlentities($row['id']) . '",';
|
||||
echo '"' . htmlentities($row['control']) . '",';
|
||||
echo '"' . htmlentities($row['remote_id']) . '",';
|
||||
echo '"' . htmlentities($row['project']) . '",';
|
||||
echo '"' . htmlentities($row['object']) . '",';
|
||||
echo '"' . htmlentities($row['status_code']) . '",';
|
||||
echo '"' . htmlentities($row['message']) . '",';
|
||||
echo '"' . htmlentities($row['hostname']) . '",';
|
||||
echo '"' . htmlentities($row['user_id']) . '",';
|
||||
echo '"' . htmlentities($row['date']) . '"';
|
||||
|
||||
echo " ]";
|
||||
}
|
||||
|
||||
echo " ]}";
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
779
lxd-dashboard/backend/admin/settings.php
Normal file
|
@ -0,0 +1,779 @@
|
|||
<?php
|
||||
/*
|
||||
LXDWARE LXD Dashboard - A web-based interface for managing LXD servers
|
||||
Copyright (C) 2020-2021 LXDWARE.COM
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
//Start session if not already started
|
||||
if (!isset($_SESSION)) {
|
||||
session_start();
|
||||
}
|
||||
|
||||
//Declare and instantiate GET variables
|
||||
$action = (isset($_GET['action'])) ? filter_var(urldecode($_GET['action']), FILTER_SANITIZE_STRING) : "";
|
||||
$certificates_page_rate = (isset($_GET['certificates_page_rate'])) ? filter_var(urldecode($_GET['certificates_page_rate']), FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION) : "5";
|
||||
$cluster_members_page_rate = (isset($_GET['cluster_members_page_rate'])) ? filter_var(urldecode($_GET['cluster_members_page_rate']), FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION) : "5";
|
||||
$containers_page_rate = (isset($_GET['containers_page_rate'])) ? filter_var(urldecode($_GET['containers_page_rate']), FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION) : "5";
|
||||
$containers_single_page_rate = (isset($_GET['containers_single_page_rate'])) ? filter_var(urldecode($_GET['containers_single_page_rate']), FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION) : "5";
|
||||
$delete_connection_timeout = (isset($_GET['delete_connection_timeout'])) ? filter_var(urldecode($_GET['delete_connection_timeout']), FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION) : "5";
|
||||
$delete_operation_timeout = (isset($_GET['delete_operation_timeout'])) ? filter_var(urldecode($_GET['delete_operation_timeout']), FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION) : "5";
|
||||
$description = (isset($_GET['description'])) ? filter_var(urldecode($_GET['description']), FILTER_SANITIZE_STRING) : "";
|
||||
$get_connection_timeout = (isset($_GET['get_connection_timeout'])) ? filter_var(urldecode($_GET['get_connection_timeout']), FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION) : "2";
|
||||
$get_operation_timeout = (isset($_GET['get_operation_timeout'])) ? filter_var(urldecode($_GET['get_operation_timeout']), FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION) : "5";
|
||||
$images_page_rate = (isset($_GET['images_page_rate'])) ? filter_var(urldecode($_GET['images_page_rate']), FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION) : "5";
|
||||
$logs_enabled_status = (isset($_GET['logs_enabled_status'])) ? filter_var(urldecode($_GET['logs_enabled_status']), FILTER_SANITIZE_STRING) : "";
|
||||
$logs_page_rate = (isset($_GET['logs_page_rate'])) ? filter_var(urldecode($_GET['logs_page_rate']), FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION) : "5";
|
||||
$logs_retrieval_number = (isset($_GET['logs_retrieval_number'])) ? filter_var(urldecode($_GET['logs_retrieval_number']), FILTER_SANITIZE_NUMBER_INT) : "";
|
||||
$id = (isset($_GET['id'])) ? filter_var(urldecode($_GET['id']), FILTER_SANITIZE_NUMBER_INT) : "";
|
||||
$group_id = (isset($_GET['group_id'])) ? filter_var(urldecode($_GET['group_id']), FILTER_SANITIZE_NUMBER_INT) : "";
|
||||
$name = (isset($_GET['name'])) ? filter_var(urldecode($_GET['name']), FILTER_SANITIZE_STRING) : "";
|
||||
$network_acls_page_rate = (isset($_GET['network_acls_page_rate'])) ? filter_var(urldecode($_GET['network_acls_page_rate']), FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION) : "5";
|
||||
$networks_page_rate = (isset($_GET['networks_page_rate'])) ? filter_var(urldecode($_GET['networks_page_rate']), FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION) : "5";
|
||||
$operations_page_rate = (isset($_GET['operations_page_rate'])) ? filter_var(urldecode($_GET['operations_page_rate']), FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION) : "5";
|
||||
$patch_connection_timeout = (isset($_GET['patch_connection_timeout'])) ? filter_var(urldecode($_GET['patch_connection_timeout']), FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION) : "5";
|
||||
$patch_operation_timeout = (isset($_GET['patch_operation_timeout'])) ? filter_var(urldecode($_GET['patch_operation_timeout']), FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION) : "5";
|
||||
$post_connection_timeout = (isset($_GET['post_connection_timeout'])) ? filter_var(urldecode($_GET['post_connection_timeout']), FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION) : "5";
|
||||
$post_operation_timeout = (isset($_GET['post_operation_timeout'])) ? filter_var(urldecode($_GET['post_operation_timeout']), FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION) : "5";
|
||||
$profiles_page_rate = (isset($_GET['profiles_page_rate'])) ? filter_var(urldecode($_GET['profiles_page_rate']), FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION) : "5";
|
||||
$project = (isset($_GET['project'])) ? filter_var(urldecode($_GET['project']), FILTER_SANITIZE_STRING) : "";
|
||||
$projects_page_rate = (isset($_GET['projects_page_rate'])) ? filter_var(urldecode($_GET['projects_page_rate']), FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION) : "5";
|
||||
$put_connection_timeout = (isset($_GET['put_connection_timeout'])) ? filter_var(urldecode($_GET['put_connection_timeout']), FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION) : "5";
|
||||
$put_operation_timeout = (isset($_GET['put_operation_timeout'])) ? filter_var(urldecode($_GET['put_operation_timeout']), FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION) : "5";
|
||||
$remote = (isset($_GET['remote'])) ? filter_var(urldecode($_GET['remote']), FILTER_SANITIZE_NUMBER_INT) : "";
|
||||
$remotes_single_page_rate = (isset($_GET['remotes_single_page_rate'])) ? filter_var(urldecode($_GET['remotes_single_page_rate']), FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION) : "5";
|
||||
$remotes_page_rate = (isset($_GET['remotes_page_rate'])) ? filter_var(urldecode($_GET['remotes_page_rate']), FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION) : "5";
|
||||
$role_id = (isset($_GET['role_id'])) ? filter_var(urldecode($_GET['role_id']), FILTER_SANITIZE_NUMBER_INT) : "";
|
||||
$simplestreams_page_rate = (isset($_GET['simplestreams_page_rate'])) ? filter_var(urldecode($_GET['simplestreams_page_rate']), FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION) : "5";
|
||||
$storage_pools_page_rate = (isset($_GET['storage_pools_page_rate'])) ? filter_var(urldecode($_GET['storage_pools_page_rate']), FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION) : "5";
|
||||
$storage_volumes_page_rate = (isset($_GET['storage_volumes_page_rate'])) ? filter_var(urldecode($_GET['storage_volumes_page_rate']), FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION) : "5";
|
||||
$virtual_machines_page_rate = (isset($_GET['virtual_machines_page_rate'])) ? filter_var(urldecode($_GET['virtual_machines_page_rate']), FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION) : "5";
|
||||
$virtual_machines_single_page_rate = (isset($_GET['virtual_machines_single_page_rate'])) ? filter_var(urldecode($_GET['virtual_machines_single_page_rate']), FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION) : "5";
|
||||
|
||||
//Declare and instantiate POST variables
|
||||
$email = (isset($_POST['email'])) ? filter_var(urldecode($_POST['email']), FILTER_SANITIZE_STRING) : "";
|
||||
$first_name = (isset($_POST['first_name'])) ? filter_var(urldecode($_POST['first_name']), FILTER_SANITIZE_STRING) : "";
|
||||
$last_name = (isset($_POST['last_name'])) ? filter_var(urldecode($_POST['last_name']), FILTER_SANITIZE_STRING) : "";
|
||||
$password = (isset($_POST['password'])) ? $_POST['password'] : "";
|
||||
$username = (isset($_POST['username'])) ? filter_var(urldecode($_POST['username']), FILTER_SANITIZE_STRING) : "";
|
||||
|
||||
//Require code from lxd-dashboard/backend/config/db.php
|
||||
require_once('../config/db.php');
|
||||
|
||||
//Require code from lxd-dashboard/backend/aaa/accounting.php
|
||||
require_once('../aaa/accounting.php');
|
||||
|
||||
if (isset($_SESSION['username'])) {
|
||||
|
||||
require_once('../aaa/authorization.php');
|
||||
|
||||
//Run the matching action
|
||||
switch ($action) {
|
||||
|
||||
case "addRoleToGroup":
|
||||
if (validateAuthorization($action)) {
|
||||
$record_added = addGroupRoleMapping($id, $role_id);
|
||||
|
||||
if ($record_added)
|
||||
$results = '{"status": "Ok", "status_code": 200, "metadata": {"status": "Record added"}}';
|
||||
else
|
||||
$results = '{"status": "Bad Request", "status_code": 400, "metadata": {"error": "Unable to add the record to the database"}}';
|
||||
|
||||
}
|
||||
else {
|
||||
$results = '{"status": "Forbidden", "status_code": 403, "metadata": {"error": "You are not authorized to execute this action"}}';
|
||||
}
|
||||
|
||||
echo $results;
|
||||
|
||||
//Send event to accounting
|
||||
$event = json_decode($results, true);
|
||||
$object = $id . " - " . $role_id;
|
||||
logEvent($action, $remote, $project, $object, $event['status_code'], $event['status']);
|
||||
|
||||
break;
|
||||
|
||||
case "addUserToGroup":
|
||||
if (validateAuthorization($action)) {
|
||||
$record_added = addUserGroupMapping($id, $group_id);
|
||||
|
||||
if ($record_added)
|
||||
$results = '{"status": "Ok", "status_code": 200, "metadata": {"status": "Record added"}}';
|
||||
else
|
||||
$results = '{"status": "Bad Request", "status_code": 400, "metadata": {"error": "Unable to add the record to the database"}}';
|
||||
|
||||
}
|
||||
else {
|
||||
$results = '{"status": "Forbidden", "status_code": 403, "metadata": {"error": "You are not authorized to execute this action"}}';
|
||||
}
|
||||
|
||||
echo $results;
|
||||
|
||||
//Send event to accounting
|
||||
$event = json_decode($results, true);
|
||||
$object = $id . " - " . $group_id;
|
||||
logEvent($action, $remote, $project, $object, $event['status_code'], $event['status']);
|
||||
|
||||
break;
|
||||
|
||||
case "createGroup":
|
||||
if (validateAuthorization($action)) {
|
||||
$record_added = addGroup($name, $description);
|
||||
|
||||
if($record_added){
|
||||
$results = '{"status": "Ok", "status_code": 200, "metadata": "{}"}';
|
||||
$group_id = retrieveGroupId($name);
|
||||
}
|
||||
else {
|
||||
$results = '{"status": "Bad Request", "status_code": 400, "metadata": {"error": "Unable to add the record to the database"}}';
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
$results = '{"status": "Forbidden", "status_code": 403, "metadata": {"error": "You are not authorized to execute this action"}}';
|
||||
}
|
||||
|
||||
echo $results;
|
||||
|
||||
//Send event to accounting
|
||||
$event = json_decode($results, true);
|
||||
$object = $group_id . " - " . $name;
|
||||
logEvent($action, $remote, $project, $object, $event['status_code'], $event['status']);
|
||||
|
||||
break;
|
||||
|
||||
case "createUser":
|
||||
if (validateAuthorization($action)) {
|
||||
//Test to verify username and password both have a value
|
||||
if (!empty($username) && !empty($password)) {
|
||||
|
||||
//Hash and salt password with bcrypt
|
||||
$passwd_hash = password_hash($password, PASSWORD_BCRYPT);
|
||||
|
||||
if(isFirstUser()){
|
||||
$record_added = addUser($username, $first_name, $last_name, $passwd_hash, $email);
|
||||
|
||||
if($record_added){
|
||||
$user_id = retrieveUserId($username);
|
||||
$group_id = retrieveGroupId('admin');
|
||||
addUserGroupMapping($user_id, $group_id);
|
||||
}
|
||||
$results = '{"status": "Ok", "status_code": 200, "metadata": "{}"}';
|
||||
}
|
||||
else {
|
||||
$record_added = addUser($username, $first_name, $last_name, $passwd_hash, $email);
|
||||
|
||||
if($record_added){
|
||||
$user_id = retrieveUserId($username);
|
||||
$group_id = retrieveGroupId('auditor');
|
||||
|
||||
if($group_id){
|
||||
addUserGroupMapping($user_id, $group_id);
|
||||
}
|
||||
|
||||
$results = '{"status": "Ok", "status_code": 200, "metadata": "{}"}';
|
||||
}
|
||||
else {
|
||||
$results = '{"status": "Bad Request", "status_code": 400, "metadata": {"error": "Unable to add the record to the database"}}';
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
else {
|
||||
$results = '{"status": "Bad Request", "status_code": 400, "metadata": {"error": "Both a username and password must be supplied"}}';
|
||||
}
|
||||
}
|
||||
else {
|
||||
$results = '{"status": "Forbidden", "status_code": 403, "metadata": {"error": "You are not authorized to execute this action"}}';
|
||||
}
|
||||
|
||||
echo $results;
|
||||
|
||||
//Send event to accounting
|
||||
$event = json_decode($results, true);
|
||||
$object = $user_id . " - " . $username;
|
||||
logEvent($action, $remote, $project, $object, $event['status_code'], $event['status']);
|
||||
|
||||
break;
|
||||
|
||||
case "deleteGroup":
|
||||
if (validateAuthorization($action)) {
|
||||
$record_removed = deleteGroup($id);
|
||||
|
||||
if ($record_removed)
|
||||
$results = '{"status": "Ok", "status_code": 200, "metadata": {"status": "Record removed"}}';
|
||||
else
|
||||
$results = '{"status": "Bad Request", "status_code": 400, "metadata": {"error": "Unable to remove record from database"}}';
|
||||
|
||||
}
|
||||
else {
|
||||
$results = '{"status": "Forbidden", "status_code": 403, "metadata": {"error": "You are not authorized to execute this action"}}';
|
||||
}
|
||||
|
||||
echo $results;
|
||||
|
||||
//Send event to accounting
|
||||
$event = json_decode($results, true);
|
||||
$object = $id;
|
||||
logEvent($action, $remote, $project, $object, $event['status_code'], $event['status']);
|
||||
|
||||
break;
|
||||
|
||||
case "deleteUser":
|
||||
if (validateAuthorization($action)) {
|
||||
$record_removed = deleteUser($id);
|
||||
|
||||
if ($record_removed)
|
||||
$results = '{"status": "Ok", "status_code": 200, "metadata": {"status": "Record removed"}}';
|
||||
else
|
||||
$results = '{"status": "Bad Request", "status_code": 400, "metadata": {"error": "Unable to remove record from database"}}';
|
||||
|
||||
}
|
||||
else {
|
||||
$results = '{"status": "Forbidden", "status_code": 403, "metadata": {"error": "You are not authorized to execute this action"}}';
|
||||
}
|
||||
|
||||
echo $results;
|
||||
|
||||
//Send event to accounting
|
||||
$event = json_decode($results, true);
|
||||
$object = $id;
|
||||
logEvent($action, $remote, $project, $object, $event['status_code'], $event['status']);
|
||||
|
||||
break;
|
||||
|
||||
case "displayUsername":
|
||||
echo htmlentities($_SESSION['username']);
|
||||
break;
|
||||
|
||||
case "listGroups":
|
||||
if (validateAuthorization($action)) {
|
||||
$rows = retrieveTableRows('lxd_groups');
|
||||
|
||||
$i = 0;
|
||||
echo '{ "data": [';
|
||||
|
||||
foreach ($rows as $row){
|
||||
|
||||
$roles = retrieveGroupRoles($row['id']);
|
||||
$users = retrieveGroupUsers($row['id']);
|
||||
|
||||
if ($i > 0){
|
||||
echo ",";
|
||||
}
|
||||
$i++;
|
||||
|
||||
echo "[ ";
|
||||
echo '"';
|
||||
echo "<i class='fas fa-users fa-lg' style='color:#4e73df'></i>";
|
||||
echo '",';
|
||||
echo '"' . htmlentities($row['name']) . '",';
|
||||
echo '"' . htmlentities($row['description']) . '",';
|
||||
|
||||
echo '"';
|
||||
$ii = 0;
|
||||
foreach ($roles as $role){
|
||||
if ($ii > 0){
|
||||
echo ", ";
|
||||
}
|
||||
$ii++;
|
||||
echo htmlentities($role['name']);
|
||||
}
|
||||
echo '",';
|
||||
|
||||
echo '"';
|
||||
echo "<a href='#' onclick='loadAddRoleModal(".$row['id'].")'><i class='fas fa-plus fa-lg' style='color:#ddd' title='Add Role' aria-hidden='true'></i></a>";
|
||||
echo '   ';
|
||||
echo "<a href='#' onclick='loadRemoveRoleModal(".$row['id'].")'><i class='fas fa-minus fa-lg' style='color:#ddd' title='Remove Role' aria-hidden='true'></i></a>";
|
||||
echo '   ';
|
||||
echo "<a href='#' onclick='loadDeleteGroupModal(".$row['id'].")'><i class='fas fa-trash-alt fa-lg' style='color:#ddd' title='Delete Group' aria-hidden='true'></i></a>";
|
||||
echo '"';
|
||||
|
||||
echo " ]";
|
||||
}
|
||||
|
||||
echo " ]}";
|
||||
}
|
||||
else {
|
||||
echo '{ "data": [] }';
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case "listGroupsAssignedToUserForSelect":
|
||||
if (validateAuthorization($action)) {
|
||||
$groups = retrieveUserGroups($id);
|
||||
foreach ($groups as $group){
|
||||
echo '<option value="' . $group['id'] . '">' . htmlentities($group['name']) . '</option>';
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case "listGroupsNotAssignedToUserForSelect":
|
||||
if (validateAuthorization($action)) {
|
||||
$groups = retrieveTableRows('lxd_groups');
|
||||
$user_groups = retrieveUserGroups($id);
|
||||
|
||||
foreach ($groups as $group){
|
||||
|
||||
$group_belongs_to_user = false;
|
||||
|
||||
foreach ($user_groups as $user_group){
|
||||
if ($user_group['name'] == $group['name']){
|
||||
$group_belongs_to_user = true;
|
||||
}
|
||||
}
|
||||
|
||||
if(!$group_belongs_to_user){
|
||||
echo '<option value="' . $group['id'] . '">' . htmlentities($group['name']) . '</option>';
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case "listRolesAssignedToGroupForSelect":
|
||||
if (validateAuthorization($action)) {
|
||||
$roles = retrieveGroupRoles($id);
|
||||
foreach ($roles as $role){
|
||||
echo '<option value="' . $role['id'] . '">' . htmlentities($role['name']) . '</option>';
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case "listRolesNotAssignedToGroupForSelect":
|
||||
if (validateAuthorization($action)) {
|
||||
$roles = retrieveDefaultRoles();
|
||||
|
||||
$group_roles = retrieveGroupRoles($id);
|
||||
|
||||
foreach ($roles as $role){
|
||||
|
||||
$role_belongs_to_group = false;
|
||||
|
||||
foreach ($group_roles as $group_role){
|
||||
if ($group_role['name'] == $role['name']){
|
||||
$role_belongs_to_group = true;
|
||||
}
|
||||
}
|
||||
|
||||
if(!$role_belongs_to_group){
|
||||
echo '<option value="' . $role['id'] . '">' . htmlentities($role['name']) . '</option>';
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case "listUsers":
|
||||
if (validateAuthorization($action)) {
|
||||
$rows = retrieveTableRows('lxd_users');
|
||||
|
||||
$i = 0;
|
||||
echo '{ "data": [';
|
||||
|
||||
foreach ($rows as $row){
|
||||
|
||||
$groups = retrieveUserGroups($row['id']);
|
||||
|
||||
if ($i > 0){
|
||||
echo ",";
|
||||
}
|
||||
$i++;
|
||||
|
||||
echo "[ ";
|
||||
|
||||
echo '"';
|
||||
echo "<a href='user-profile.php?user=".$row['id']."'><i class='fas fa-user fa-lg' style='color:#4e73df'></i> </a>";
|
||||
echo '",';
|
||||
|
||||
echo '"';
|
||||
echo "<a href='user-profile.php?user=".$row['id']."'> ".htmlentities($row['username'])."</a>";
|
||||
echo '",';
|
||||
|
||||
echo '"' . htmlentities($row['email']) . '",';
|
||||
echo '"' . htmlentities($row['type']) . '",';
|
||||
|
||||
echo '"';
|
||||
$ii = 0;
|
||||
foreach ($groups as $group){
|
||||
if ($ii > 0){
|
||||
echo ", ";
|
||||
}
|
||||
$ii++;
|
||||
echo htmlentities($group['name']);
|
||||
}
|
||||
echo '",';
|
||||
|
||||
echo '"';
|
||||
echo "<a href='#' onclick='loadAddGroupModal(".$row['id'].")'><i class='fas fa-plus fa-lg' style='color:#ddd' title='Add Group' aria-hidden='true'></i></a>";
|
||||
echo '   ';
|
||||
echo "<a href='#' onclick='loadRemoveGroupModal(".$row['id'].")'><i class='fas fa-minus fa-lg' style='color:#ddd' title='Remove Group' aria-hidden='true'></i></a>";
|
||||
echo '   ';
|
||||
echo "<a href='#' onclick='loadDeleteUserModal(".$row['id'].")'><i class='fas fa-trash-alt fa-lg' style='color:#ddd' title='Delete User' aria-hidden='true'></i></a>";
|
||||
echo '"';
|
||||
|
||||
echo " ]";
|
||||
}
|
||||
|
||||
echo " ]}";
|
||||
}
|
||||
else {
|
||||
echo '{ "data": [] }';
|
||||
}
|
||||
break;
|
||||
|
||||
case "retrieveCurlTimeoutValues":
|
||||
//Retrieve SESSION variables and return JSON
|
||||
$arr = array();
|
||||
$arr['get_connection_timeout'] = $_SESSION['get_connection_timeout'];
|
||||
$arr['get_operation_timeout'] = $_SESSION['get_operation_timeout'];
|
||||
$arr['post_connection_timeout'] = $_SESSION['post_connection_timeout'];
|
||||
$arr['post_operation_timeout'] = $_SESSION['post_operation_timeout'];
|
||||
$arr['patch_connection_timeout'] = $_SESSION['patch_connection_timeout'];
|
||||
$arr['patch_operation_timeout'] = $_SESSION['patch_operation_timeout'];
|
||||
$arr['put_connection_timeout'] = $_SESSION['put_connection_timeout'];
|
||||
$arr['put_operation_timeout'] = $_SESSION['put_operation_timeout'];
|
||||
$arr['delete_connection_timeout'] = $_SESSION['delete_connection_timeout'];
|
||||
$arr['delete_operation_timeout'] = $_SESSION['delete_operation_timeout'];
|
||||
echo json_encode($arr);
|
||||
break;
|
||||
|
||||
case "retrieveLogPreferences":
|
||||
$arr = array();
|
||||
$arr['logs_enabled'] = retrievePreference("logs_enabled");
|
||||
$arr['logs_retrieval'] = intval(retrievePreference("logs_retrieval"));
|
||||
echo json_encode($arr);
|
||||
break;
|
||||
|
||||
case "retrievePageRefreshRateValues":
|
||||
//Retrieve SESSION variables and return JSON
|
||||
$arr = array();
|
||||
$arr['certificates_page_rate'] = $_SESSION['certificates_page_rate'];
|
||||
$arr['cluster_members_page_rate'] = $_SESSION['cluster_members_page_rate'];
|
||||
$arr['containers_page_rate'] = $_SESSION['containers_page_rate'];
|
||||
$arr['containers_single_page_rate'] = $_SESSION['containers_single_page_rate'];
|
||||
$arr['images_page_rate'] = $_SESSION['images_page_rate'];
|
||||
$arr['logs_page_rate'] = $_SESSION['logs_page_rate'];
|
||||
$arr['network_acls_page_rate'] = $_SESSION['network_acls_page_rate'];
|
||||
$arr['networks_page_rate'] = $_SESSION['networks_page_rate'];
|
||||
$arr['operations_page_rate'] = $_SESSION['operations_page_rate'];
|
||||
$arr['profiles_page_rate'] = $_SESSION['profiles_page_rate'];
|
||||
$arr['projects_page_rate'] = $_SESSION['projects_page_rate'];
|
||||
$arr['remotes_single_page_rate'] = $_SESSION['remotes_single_page_rate'];
|
||||
$arr['remotes_page_rate'] = $_SESSION['remotes_page_rate'];
|
||||
$arr['simplestreams_page_rate'] = $_SESSION['simplestreams_page_rate'];
|
||||
$arr['storage_pools_page_rate'] = $_SESSION['storage_pools_page_rate'];
|
||||
$arr['storage_volumes_page_rate'] = $_SESSION['storage_volumes_page_rate'];
|
||||
$arr['virtual_machines_page_rate'] = $_SESSION['virtual_machines_page_rate'];
|
||||
$arr['virtual_machines_single_page_rate'] = $_SESSION['virtual_machines_single_page_rate'];
|
||||
echo json_encode($arr);
|
||||
break;
|
||||
|
||||
case "removeGroupFromUser":
|
||||
if (validateAuthorization($action)) {
|
||||
$record_removed = deleteUserGroupMapping($id, $group_id);
|
||||
|
||||
if ($record_removed)
|
||||
$results = '{"status": "Ok", "status_code": 200, "metadata": {"status": "Record removed"}}';
|
||||
else
|
||||
$results = '{"status": "Bad Request", "status_code": 400, "metadata": {"error": "Unable to remove record from database"}}';
|
||||
|
||||
}
|
||||
else {
|
||||
$results = '{"status": "Forbidden", "status_code": 403, "metadata": {"error": "You are not authorized to execute this action"}}';
|
||||
}
|
||||
|
||||
echo $results;
|
||||
|
||||
//Send event to accounting
|
||||
$event = json_decode($results, true);
|
||||
$object = $id . " - " . $group_id;
|
||||
logEvent($action, $remote, $project, $object, $event['status_code'], $event['status']);
|
||||
|
||||
break;
|
||||
|
||||
case "removeRoleFromGroup":
|
||||
if (validateAuthorization($action)) {
|
||||
$record_removed = deleteGroupRoleMapping($id, $role_id);
|
||||
|
||||
if ($record_removed)
|
||||
$results = '{"status": "Ok", "status_code": 200, "metadata": {"status": "Record removed"}}';
|
||||
else
|
||||
$results = '{"status": "Bad Request", "status_code": 400, "metadata": {"error": "Unable to remove record from database"}}';
|
||||
|
||||
}
|
||||
else {
|
||||
$results = '{"status": "Forbidden", "status_code": 403, "metadata": {"error": "You are not authorized to execute this action"}}';
|
||||
}
|
||||
|
||||
echo $results;
|
||||
|
||||
//Send event to accounting
|
||||
$event = json_decode($results, true);
|
||||
$object = $id . " - " . $role_id;
|
||||
logEvent($action, $remote, $project, $object, $event['status_code'], $event['status']);
|
||||
|
||||
break;
|
||||
|
||||
case "updateLogPreferences":
|
||||
if (validateAuthorization($action)) {
|
||||
if ($logs_enabled_status == "true" || $logs_enabled_status == "false"){
|
||||
$logs_enabled_status_updated = updatePreference("logs_enabled", $logs_enabled_status);
|
||||
}
|
||||
|
||||
if (is_numeric($logs_retrieval_number) && $logs_retrieval_number >= 1){
|
||||
$logs_retrieval_number_updated = updatePreference("logs_retrieval", $logs_retrieval_number);
|
||||
}
|
||||
|
||||
if ($logs_enabled_status_updated && $logs_retrieval_number_updated)
|
||||
$results = '{"status": "Ok", "status_code": 200, "metadata": {"status": "Record added"}}';
|
||||
else
|
||||
$results = '{"status": "Bad Request", "status_code": 400, "metadata": {"error": "There was an error while updating the lxd_preferences table"}}';
|
||||
|
||||
}
|
||||
else {
|
||||
$results = '{"status": "Forbidden", "status_code": 403, "metadata": {"error": "You are not authorized to execute this action"}}';
|
||||
}
|
||||
|
||||
echo $results;
|
||||
|
||||
//Send event to accounting
|
||||
$event = json_decode($results, true);
|
||||
$object = "";
|
||||
logEvent($action, $remote, $project, $object, $event['status_code'], $event['status']);
|
||||
|
||||
break;
|
||||
|
||||
case "updateOutboundRequestPreferences":
|
||||
if (validateAuthorization($action)) {
|
||||
|
||||
if (is_numeric($get_connection_timeout) && $get_connection_timeout >= 1)
|
||||
$get_connection_timeout_updated = updatePreference("get_connection_timeout", $get_connection_timeout);
|
||||
if ($get_connection_timeout_updated)
|
||||
$_SESSION['get_connection_timeout'] = $get_connection_timeout;
|
||||
|
||||
if (is_numeric($get_operation_timeout) && $get_operation_timeout >= 1)
|
||||
$get_operation_timeout_updated = updatePreference("get_operation_timeout", $get_operation_timeout);
|
||||
if ($get_operation_timeout_updated)
|
||||
$_SESSION['get_operation_timeout'] = $get_operation_timeout;
|
||||
|
||||
if (is_numeric($post_connection_timeout) && $post_connection_timeout >= 1)
|
||||
$post_connection_timeout_updated = updatePreference("post_connection_timeout", $post_connection_timeout);
|
||||
if ($post_connection_timeout_updated)
|
||||
$_SESSION['post_connection_timeout'] = $post_connection_timeout;
|
||||
|
||||
if (is_numeric($post_operation_timeout) && $post_operation_timeout >= 1)
|
||||
$post_operation_timeout_updated = updatePreference("post_operation_timeout", $post_operation_timeout);
|
||||
if ($post_operation_timeout_updated)
|
||||
$_SESSION['post_operation_timeout'] = $post_operation_timeout;
|
||||
|
||||
if (is_numeric($patch_connection_timeout) && $patch_connection_timeout >= 1)
|
||||
$patch_connection_timeout_updated = updatePreference("patch_connection_timeout", $patch_connection_timeout);
|
||||
if ($patch_connection_timeout_updated)
|
||||
$_SESSION['patch_connection_timeout'] = $patch_connection_timeout;
|
||||
|
||||
if (is_numeric($patch_operation_timeout) && $patch_operation_timeout >= 1)
|
||||
$patch_operation_timeout_updated = updatePreference("patch_operation_timeout", $patch_operation_timeout);
|
||||
if ($patch_operation_timeout_updated)
|
||||
$_SESSION['patch_operation_timeout'] = $patch_operation_timeout;
|
||||
|
||||
if (is_numeric($put_connection_timeout) && $put_connection_timeout >= 1)
|
||||
$put_connection_timeout_updated = updatePreference("put_connection_timeout", $put_connection_timeout);
|
||||
if ($put_connection_timeout_updated)
|
||||
$_SESSION['put_connection_timeout'] = $put_connection_timeout;
|
||||
|
||||
if (is_numeric($put_operation_timeout) && $put_operation_timeout >= 1)
|
||||
$put_operation_timeout_updated = updatePreference("put_operation_timeout", $put_operation_timeout);
|
||||
if ($put_operation_timeout_updated)
|
||||
$_SESSION['put_operation_timeout'] = $put_operation_timeout;
|
||||
|
||||
if (is_numeric($delete_connection_timeout) && $delete_connection_timeout >= 1)
|
||||
$delete_connection_timeout_updated = updatePreference("delete_connection_timeout", $delete_connection_timeout);
|
||||
if ($delete_connection_timeout_updated)
|
||||
$_SESSION['delete_connection_timeout'] = $delete_connection_timeout;
|
||||
|
||||
if (is_numeric($delete_operation_timeout) && $delete_operation_timeout >= 1)
|
||||
$delete_operation_timeout_updated = updatePreference("delete_operation_timeout", $delete_operation_timeout);
|
||||
if ($delete_operation_timeout_updated)
|
||||
$_SESSION['delete_operation_timeout'] = $delete_operation_timeout;
|
||||
|
||||
|
||||
if ($get_connection_timeout_updated && $get_operation_timeout_updated && $post_connection_timeout_updated && $post_operation_timeout_updated && $patch_connection_timeout_updated && $patch_operation_timeout_updated && $put_connection_timeout_updated && $put_operation_timeout_updated && $delete_connection_timeout_updated && $delete_operation_timeout_updated)
|
||||
$results = '{"status": "Ok", "status_code": 200, "metadata": {"status": "Record added"}}';
|
||||
else
|
||||
$results = '{"status": "Bad Request", "status_code": 400, "metadata": {"error": "There was an error while updating the lxd_preferences table"}}';
|
||||
|
||||
}
|
||||
else {
|
||||
$results = '{"status": "Forbidden", "status_code": 403, "metadata": {"error": "You are not authorized to execute this action"}}';
|
||||
}
|
||||
|
||||
echo $results;
|
||||
|
||||
//Send event to accounting
|
||||
$event = json_decode($results, true);
|
||||
$object = "";
|
||||
logEvent($action, $remote, $project, $object, $event['status_code'], $event['status']);
|
||||
break;
|
||||
|
||||
case "updateRefreshRatePreferences":
|
||||
if (validateAuthorization($action)) {
|
||||
|
||||
if (is_numeric($certificates_page_rate) && $certificates_page_rate >= 1)
|
||||
$certificates_page_rate_updated = updatePreference("certificates_page_rate", $certificates_page_rate);
|
||||
if ($certificates_page_rate_updated)
|
||||
$_SESSION['certificates_page_rate'] = $certificates_page_rate;
|
||||
|
||||
if (is_numeric($cluster_members_page_rate) && $cluster_members_page_rate >= 1)
|
||||
$cluster_members_page_rate_updated = updatePreference("cluster_members_page_rate", $cluster_members_page_rate);
|
||||
if ($cluster_members_page_rate_updated)
|
||||
$_SESSION['cluster_members_page_rate'] = $cluster_members_page_rate;
|
||||
|
||||
if (is_numeric($containers_page_rate) && $containers_page_rate >= 1)
|
||||
$containers_page_rate_updated = updatePreference("containers_page_rate", $containers_page_rate);
|
||||
if ($containers_page_rate_updated)
|
||||
$_SESSION['containers_page_rate'] = $containers_page_rate;
|
||||
|
||||
if (is_numeric($containers_single_page_rate) && $containers_single_page_rate >= 1)
|
||||
$containers_single_page_rate_updated = updatePreference("containers_single_page_rate", $containers_single_page_rate);
|
||||
if ($containers_single_page_rate_updated )
|
||||
$_SESSION['containers_single_page_rate'] = $containers_single_page_rate;
|
||||
|
||||
if (is_numeric($images_page_rate) && $images_page_rate >= 1)
|
||||
$images_page_rate_updated = updatePreference("images_page_rate", $images_page_rate);
|
||||
if ($images_page_rate_updated)
|
||||
$_SESSION['images_page_rate'] = $images_page_rate;
|
||||
|
||||
if (is_numeric($logs_page_rate) && $logs_page_rate >= 1)
|
||||
$logs_page_rate_updated = updatePreference("logs_page_rate", $logs_page_rate);
|
||||
if ($logs_page_rate_updated)
|
||||
$_SESSION['logs_page_rate'] = $logs_page_rate;
|
||||
|
||||
if (is_numeric($network_acls_page_rate) && $network_acls_page_rate >= 1)
|
||||
$network_acls_page_rate_updated = updatePreference("network_acls_page_rate", $network_acls_page_rate);
|
||||
if ($network_acls_page_rate_updated)
|
||||
$_SESSION['network_acls_page_rate'] = $network_acls_page_rate;
|
||||
|
||||
if (is_numeric($networks_page_rate) && $networks_page_rate >= 1)
|
||||
$networks_page_rate_updated = updatePreference("networks_page_rate", $networks_page_rate);
|
||||
if ($networks_page_rate_updated)
|
||||
$_SESSION['networks_page_rate'] = $networks_page_rate;
|
||||
|
||||
if (is_numeric($operations_page_rate) && $operations_page_rate >= 1)
|
||||
$operations_page_rate_updated = updatePreference("operations_page_rate", $operations_page_rate);
|
||||
if ($operations_page_rate_updated)
|
||||
$_SESSION['operations_page_rate'] = $operations_page_rate;
|
||||
|
||||
if (is_numeric($profiles_page_rate) && $profiles_page_rate >= 1)
|
||||
$profiles_page_rate_updated = updatePreference("profiles_page_rate", $profiles_page_rate);
|
||||
if ($profiles_page_rate_updated)
|
||||
$_SESSION['profiles_page_rate'] = $profiles_page_rate;
|
||||
|
||||
if (is_numeric($projects_page_rate) && $projects_page_rate >= 1)
|
||||
$projects_page_rate_updated = updatePreference("projects_page_rate", $projects_page_rate);
|
||||
if ($projects_page_rate_updated)
|
||||
$_SESSION['projects_page_rate'] = $projects_page_rate;
|
||||
|
||||
if (is_numeric($remotes_single_page_rate) && $remotes_single_page_rate >= 1)
|
||||
$remotes_single_page_rate_updated = updatePreference("remotes_single_page_rate", $remotes_single_page_rate);
|
||||
if ($remotes_single_page_rate_updated)
|
||||
$_SESSION['remotes_single_page_rate'] = $remotes_single_page_rate;
|
||||
|
||||
if (is_numeric($remotes_page_rate) && $remotes_page_rate >= 1)
|
||||
$remotes_page_rate_updated = updatePreference("remotes_page_rate", $remotes_page_rate);
|
||||
if ($remotes_page_rate_updated)
|
||||
$_SESSION['remotes_page_rate'] = $remotes_page_rate;
|
||||
|
||||
if (is_numeric($simplestreams_page_rate) && $simplestreams_page_rate >= 1)
|
||||
$simplestreams_page_rate_updated = updatePreference("simplestreams_page_rate", $simplestreams_page_rate);
|
||||
if ($simplestreams_page_rate_updated)
|
||||
$_SESSION['simplestreams_page_rate'] = $simplestreams_page_rate;
|
||||
|
||||
if (is_numeric($storage_pools_page_rate) && $storage_pools_page_rate >= 1)
|
||||
$storage_pools_page_rate_updated = updatePreference("storage_pools_page_rate", $storage_pools_page_rate);
|
||||
if ($storage_pools_page_rate_updated)
|
||||
$_SESSION['storage_pools_page_rate'] = $storage_pools_page_rate;
|
||||
|
||||
if (is_numeric($storage_volumes_page_rate) && $storage_volumes_page_rate >= 1)
|
||||
$storage_volumes_page_rate_updated = updatePreference("storage_volumes_page_rate", $storage_volumes_page_rate);
|
||||
if ($storage_volumes_page_rate_updated)
|
||||
$_SESSION['storage_volumes_page_rate'] = $storage_volumes_page_rate;
|
||||
|
||||
if (is_numeric($virtual_machines_page_rate) && $virtual_machines_page_rate >= 1)
|
||||
$virtual_machines_page_rate_updated = updatePreference("virtual_machines_page_rate", $virtual_machines_page_rate);
|
||||
if ($virtual_machines_page_rate_updated)
|
||||
$_SESSION['virtual_machines_page_rate'] = $virtual_machines_page_rate;
|
||||
|
||||
if (is_numeric($virtual_machines_single_page_rate) && $virtual_machines_single_page_rate >= 1)
|
||||
$virtual_machines_single_page_rate_updated = updatePreference("virtual_machines_single_page_rate", $virtual_machines_single_page_rate);
|
||||
if ($virtual_machines_single_page_rate_updated)
|
||||
$_SESSION['virtual_machines_single_page_rate'] = $virtual_machines_single_page_rate;
|
||||
|
||||
|
||||
if ($certificates_page_rate_updated && $cluster_members_page_rate_updated && $containers_page_rate_updated && $containers_single_page_rate_updated && $images_page_rate_updated && $logs_page_rate_updated && $network_acls_page_rate_updated && $networks_page_rate_updated && $operations_page_rate_updated && $profiles_page_rate_updated && $projects_page_rate_updated && $remotes_single_page_rate_updated && $remotes_page_rate_updated && $simplestreams_page_rate_updated && $storage_pools_page_rate_updated && $storage_volumes_page_rate_updated && $virtual_machines_page_rate_updated && $virtual_machines_single_page_rate_updated)
|
||||
$results = '{"status": "Ok", "status_code": 200, "metadata": {"status": "Record added"}}';
|
||||
else
|
||||
$results = '{"status": "Bad Request", "status_code": 400, "metadata": {"error": "There was an error while updating the lxd_preferences table"}}';
|
||||
|
||||
}
|
||||
else {
|
||||
$results = '{"status": "Forbidden", "status_code": 403, "metadata": {"error": "You are not authorized to execute this action"}}';
|
||||
}
|
||||
|
||||
echo $results;
|
||||
|
||||
//Send event to accounting
|
||||
$event = json_decode($results, true);
|
||||
$object = "";
|
||||
logEvent($action, $remote, $project, $object, $event['status_code'], $event['status']);
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
switch ($action) {
|
||||
case "createUser":
|
||||
//Test to verify username and password both have a value
|
||||
if (!empty($username) && !empty($password)) {
|
||||
|
||||
//Hash and salt password with bcrypt
|
||||
$passwd_hash = password_hash($password, PASSWORD_BCRYPT);
|
||||
|
||||
if(isFirstUser()){
|
||||
$record_added = addUser($username, $first_name, $last_name, $passwd_hash, $email);
|
||||
|
||||
if($record_added){
|
||||
$user_id = retrieveUserId($username);
|
||||
$group_id = retrieveGroupId('admin');
|
||||
addUserGroupMapping($user_id, $group_id);
|
||||
}
|
||||
$results = '{"status": "Ok", "status_code": 200, "metadata": "{}"}';
|
||||
}
|
||||
else {
|
||||
$results = '{"status": "Bad Request", "status_code": 400, "metadata": {"error": "User was not added as there are already existing user accounts"}}';
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
$results = '{"status": "Bad Request", "status_code": 400, "metadata": {"error": "Must supply both a username and password"}}';
|
||||
}
|
||||
|
||||
echo $results;
|
||||
break;
|
||||
}
|
||||
}
|
||||
?>
|
|
@ -34,10 +34,10 @@ $remote = (isset($_GET['remote'])) ? filter_var(urldecode($_GET['remote']), FILT
|
|||
//Declare and instantiate POST variables
|
||||
$password = (isset($_POST['password'])) ? $_POST['password'] : "";
|
||||
|
||||
//Require code from lxd-dashboard/php/config/db.php
|
||||
//Require code from lxd-dashboard/backend/config/db.php
|
||||
require_once('../config/db.php');
|
||||
|
||||
//Require code from lxd-dashboard/php/aaa/accounting.php
|
||||
//Require code from lxd-dashboard/backend/aaa/accounting.php
|
||||
require_once('../aaa/accounting.php');
|
||||
|
||||
if (isset($_SESSION['username'])) {
|
|
@ -1,4 +1,5 @@
|
|||
<!--
|
||||
<?php
|
||||
/*
|
||||
LXDWARE LXD Dashboard - A web-based interface for managing LXD servers
|
||||
Copyright (C) 2020-2021 LXDWARE.COM
|
||||
|
||||
|
@ -14,17 +15,42 @@ GNU Affero General Public License for more details.
|
|||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
-->
|
||||
*/
|
||||
|
||||
//Start session if not already started
|
||||
if (!isset($_SESSION)) {
|
||||
session_start();
|
||||
}
|
||||
|
||||
|
||||
if (isset($_SESSION['username'])) {
|
||||
|
||||
//Include db_config.php file
|
||||
include_once('/var/lxdware/data/db_config.php');
|
||||
|
||||
switch (DB_TYPE) {
|
||||
case "sqlite":
|
||||
$database_type = "SQLite";
|
||||
break;
|
||||
case "mysql":
|
||||
$database_type = "MySQL";
|
||||
break;
|
||||
}
|
||||
?>
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<body class="">
|
||||
<p>This open source LXD dashboard is developed by LXDWARE and provides a web-based user interface capable of managing multiple LXD servers from a single location.</p>
|
||||
<p>The open source LXD Dashboard is developed by LXDWARE and provides a web-based user interface capable of managing multiple LXD servers from a single location.</p>
|
||||
<p>
|
||||
<strong>Version</strong>: <span id="versionNumber">v2.2.0</span> <br />
|
||||
<strong>Version</strong>: <span id="versionNumber">v3.8.0</span> <br />
|
||||
<strong>License</strong>: AGPL-3.0 <br />
|
||||
<strong>URL</strong>: https://lxdware.com <br />
|
||||
</p>
|
||||
</p>
|
||||
<p>
|
||||
<strong>Hostname</strong>: <?php echo gethostname(); ?> <br />
|
||||
<strong>Database Type</strong>: <?php echo $database_type ?>
|
||||
</p>
|
||||
|
||||
<div class="text-center">
|
||||
<p class="text-primary" id="updateMessage"></p>
|
||||
|
@ -47,4 +73,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
});
|
||||
}
|
||||
</script>
|
||||
</html>
|
||||
</html>
|
||||
|
||||
<?php
|
||||
}
|
||||
?>
|
151
lxd-dashboard/backend/config/cert.php
Normal file
|
@ -0,0 +1,151 @@
|
|||
<?php
|
||||
/*
|
||||
LXDWARE LXD Dashboard - A web-based interface for managing LXD servers
|
||||
Copyright (C) 2020-2021 LXDWARE.COM
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
//Start session if not already started
|
||||
if (!isset($_SESSION)) {
|
||||
session_start();
|
||||
}
|
||||
|
||||
function createCertificate($certificateFilename, $numberofDays = 3650){
|
||||
//Only create the certificate if it does not already exist
|
||||
if (!file_exists('/var/lxdware/data/lxd/'.$certificateFilename.'.crt')){
|
||||
$subject = array(
|
||||
"commonName" => "LXDWARE",
|
||||
);
|
||||
|
||||
//Generate a new private (and public) key pair
|
||||
$private_key = openssl_pkey_new(array(
|
||||
"private_key_type" => OPENSSL_KEYTYPE_EC,
|
||||
"curve_name" => 'secp384r1',
|
||||
));
|
||||
|
||||
//Generate a certificate signing request
|
||||
$csr = openssl_csr_new($subject, $private_key);
|
||||
|
||||
//Generate self-signed EC cert
|
||||
$x509 = openssl_csr_sign($csr, null, $private_key, $numberofDays);
|
||||
openssl_x509_export_to_file($x509, '/var/lxdware/data/lxd/'.$certificateFilename.'.crt');
|
||||
openssl_pkey_export_to_file($private_key, '/var/lxdware/data/lxd/'.$certificateFilename.'.key');
|
||||
|
||||
//Change permissions to lock down private key
|
||||
chmod('/var/lxdware/data/lxd/'.$certificateFilename.'.key',0600);
|
||||
}
|
||||
}
|
||||
|
||||
//Create default client.crt certificate if it does not already exist, ensuring that it is always available to the system, even if deleted.
|
||||
createCertificate('client');
|
||||
|
||||
if (isset($_SESSION['username'])) {
|
||||
|
||||
//Declare and instantiate GET variables
|
||||
$action = (isset($_GET['action'])) ? filter_var(urldecode($_GET['action']), FILTER_SANITIZE_STRING) : "";
|
||||
$name = (isset($_GET['name'])) ? filter_var(urldecode($_GET['name']), FILTER_SANITIZE_STRING) : "";
|
||||
$days = (isset($_GET['days'])) ? filter_var(urldecode($_GET['days']), FILTER_SANITIZE_NUMBER_INT) : "3650";
|
||||
|
||||
require_once('../aaa/authorization.php');
|
||||
|
||||
//Run the matching action
|
||||
switch ($action) {
|
||||
case "createCertificateFiles":
|
||||
if (validateAuthorization($action)) {
|
||||
if (!empty($name)){
|
||||
if (!file_exists('/var/lxdware/data/lxd/'.$name.'.crt')){
|
||||
createCertificate($name, $days);
|
||||
if (file_exists('/var/lxdware/data/lxd/'.$name.'.crt') && file_exists('/var/lxdware/data/lxd/'.$name.'.key'))
|
||||
echo '{"status": "Ok", "status_code": 200, "metadata": {"status": "Certificate files created"}}';
|
||||
else
|
||||
echo '{"status": "Bad Request", "status_code": 400, "metadata": {"error": "Unable to create all certificate files"}}';
|
||||
}
|
||||
else {
|
||||
echo '{"status": "Bad Request", "status_code": 400, "metadata": {"error": "A certificate by that name already exists"}}';
|
||||
}
|
||||
}
|
||||
else {
|
||||
echo '{"status": "Bad Request", "status_code": 400, "metadata": {"error": "A certificate name must be supplied"}}';
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case "deleteCertificateFiles":
|
||||
if (validateAuthorization($action)) {
|
||||
if (!empty($name)){
|
||||
unlink('/var/lxdware/data/lxd/'.$name.'.crt');
|
||||
unlink('/var/lxdware/data/lxd/'.$name.'.key');
|
||||
}
|
||||
|
||||
if (file_exists('/var/lxdware/data/lxd/'.$name.'.crt') || file_exists('/var/lxdware/data/lxd/'.$name.'.key'))
|
||||
echo '{"status": "Bad Request", "status_code": 400, "metadata": {"error": "Unable to remove all certificate files"}}';
|
||||
else
|
||||
echo '{"status": "Ok", "status_code": 200, "metadata": {"status": "Certificate files removed"}}';
|
||||
|
||||
if ($name == 'client'){
|
||||
createCertificate('client');
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case "listCertificateFiles":
|
||||
if (validateAuthorization($action)) {
|
||||
$i = 0;
|
||||
echo '{ "data": [';
|
||||
|
||||
foreach (glob("/var/lxdware/data/lxd/*.crt") as $filename) {
|
||||
|
||||
$data = openssl_x509_parse(file_get_contents($filename));
|
||||
$validFrom = date('Y-m-d H:i:s', $data['validFrom_time_t']);
|
||||
$validTo = date('Y-m-d H:i:s', $data['validTo_time_t']);
|
||||
|
||||
if ($i > 0){
|
||||
echo ",";
|
||||
}
|
||||
$i++;
|
||||
|
||||
echo "[ ";
|
||||
echo '"';
|
||||
echo "<i class='fas fa-wallet fa-lg' style='color:#4e73df'></i>";
|
||||
echo '",';
|
||||
echo '"' . htmlentities(basename($filename)) . '",';
|
||||
echo '"' . htmlentities($data['issuer']['CN']) . '",';
|
||||
echo '"' . htmlentities($validFrom) . '",';
|
||||
echo '"' . htmlentities($validTo) . '",';
|
||||
|
||||
echo '"';
|
||||
echo "<a href='#' onclick=loadDeleteCertModal('".basename($filename, ".crt")."')><i class='fas fa-trash-alt fa-lg' style='color:#ddd' title='Delete Certificate' aria-hidden='true'></i></a>";
|
||||
echo '"';
|
||||
|
||||
echo " ]";
|
||||
}
|
||||
|
||||
echo " ]}";
|
||||
}
|
||||
break;
|
||||
|
||||
case "viewCertificate":
|
||||
if (validateAuthorization($action)) {
|
||||
$results = shell_exec("cat /var/lxdware/data/lxd/client.crt");
|
||||
echo htmlentities($results);
|
||||
}
|
||||
else {
|
||||
echo "You are not authorized to view the certificate";
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
|
@ -17,13 +17,35 @@ You should have received a copy of the GNU Affero General Public License
|
|||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
//Require code from lxd-dashboard/php/aaa/authorization.php
|
||||
//Start session if not already started
|
||||
if (!isset($_SESSION)) {
|
||||
session_start();
|
||||
}
|
||||
|
||||
//Require code from lxd-dashboard/backend/aaa/authorization.php
|
||||
require_once('../aaa/authorization.php');
|
||||
|
||||
//Require code from lxd-dashboard/backend/config/db.php
|
||||
require_once('../config/db.php');
|
||||
|
||||
|
||||
|
||||
function sendCurlRequest($request_action, $request_type, $request_url, $request_data = "{}"){
|
||||
$cert = "/var/lxdware/data/lxd/client.crt";
|
||||
$key = "/var/lxdware/data/lxd/client.key";
|
||||
|
||||
//Set required variables
|
||||
$get_connection_timeout = (isset($_SESSION['get_connection_timeout'])) ? $_SESSION['get_connection_timeout'] : 3;
|
||||
$get_operation_timeout = (isset($_SESSION['get_operation_timeout'])) ? $_SESSION['get_operation_timeout'] : 5;
|
||||
$post_connection_timeout = (isset($_SESSION['post_connection_timeout'])) ? $_SESSION['post_connection_timeout'] : 3;
|
||||
$post_operation_timeout = (isset($_SESSION['post_operation_timeout'])) ? $_SESSION['post_operation_timeout'] : 5;
|
||||
$patch_connection_timeout = (isset($_SESSION['patch_connection_timeout'])) ? $_SESSION['patch_connection_timeout'] : 3;
|
||||
$patch_operation_timeout = (isset($_SESSION['patch_operation_timeout'])) ? $_SESSION['patch_operation_timeout'] : 5;
|
||||
$put_connection_timeout = (isset($_SESSION['put_connection_timeout'])) ? $_SESSION['put_connection_timeout'] : 3;
|
||||
$put_operation_timeout = (isset($_SESSION['put_operation_timeout'])) ? $_SESSION['put_operation_timeout'] : 5;
|
||||
$delete_connection_timeout = (isset($_SESSION['delete_connection_timeout'])) ? $_SESSION['delete_connection_timeout'] : 3;
|
||||
$delete_operation_timeout = (isset($_SESSION['delete_operation_timeout'])) ? $_SESSION['delete_operation_timeout'] : 5;
|
||||
|
||||
if (validateAuthorization($request_action)) {
|
||||
switch ($request_type) {
|
||||
case "GET":
|
||||
|
@ -32,8 +54,8 @@ function sendCurlRequest($request_action, $request_type, $request_url, $request_
|
|||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($ch, CURLOPT_SSLCERT, $cert);
|
||||
curl_setopt($ch, CURLOPT_SSLKEY, $key);
|
||||
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 3);
|
||||
curl_setopt($ch, CURLOPT_TIMEOUT, 5);
|
||||
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $get_connection_timeout);
|
||||
curl_setopt($ch, CURLOPT_TIMEOUT, $get_operation_timeout);
|
||||
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "GET");
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type:application/json'));
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
|
||||
|
@ -55,8 +77,8 @@ function sendCurlRequest($request_action, $request_type, $request_url, $request_
|
|||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($ch, CURLOPT_SSLCERT, $cert);
|
||||
curl_setopt($ch, CURLOPT_SSLKEY, $key);
|
||||
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 3);
|
||||
curl_setopt($ch, CURLOPT_TIMEOUT, 5);
|
||||
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $post_connection_timeout);
|
||||
curl_setopt($ch, CURLOPT_TIMEOUT, $post_operation_timeout);
|
||||
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, $request_data);
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type:application/json'));
|
||||
|
@ -78,8 +100,8 @@ function sendCurlRequest($request_action, $request_type, $request_url, $request_
|
|||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($ch, CURLOPT_SSLCERT, $cert);
|
||||
curl_setopt($ch, CURLOPT_SSLKEY, $key);
|
||||
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 3);
|
||||
curl_setopt($ch, CURLOPT_TIMEOUT, 5);
|
||||
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $put_connection_timeout);
|
||||
curl_setopt($ch, CURLOPT_TIMEOUT, $put_operation_timeout);
|
||||
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "PUT");
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, $request_data);
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type:application/json'));
|
||||
|
@ -101,8 +123,8 @@ function sendCurlRequest($request_action, $request_type, $request_url, $request_
|
|||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($ch, CURLOPT_SSLCERT, $cert);
|
||||
curl_setopt($ch, CURLOPT_SSLKEY, $key);
|
||||
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 3);
|
||||
curl_setopt($ch, CURLOPT_TIMEOUT, 5);
|
||||
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $patch_connection_timeout);
|
||||
curl_setopt($ch, CURLOPT_TIMEOUT, $patch_operation_timeout);
|
||||
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "PATCH");
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, $request_data);
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type:application/json'));
|
||||
|
@ -124,8 +146,8 @@ function sendCurlRequest($request_action, $request_type, $request_url, $request_
|
|||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($ch, CURLOPT_SSLCERT, $cert);
|
||||
curl_setopt($ch, CURLOPT_SSLKEY, $key);
|
||||
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 3);
|
||||
curl_setopt($ch, CURLOPT_TIMEOUT, 5);
|
||||
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $delete_connection_timeout);
|
||||
curl_setopt($ch, CURLOPT_TIMEOUT, $delete_operation_timeout);
|
||||
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "DELETE");
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type:application/json'));
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
|
1678
lxd-dashboard/backend/config/db.php
Normal file
|
@ -27,7 +27,7 @@ $database_user = (isset($_GET['database_user'])) ? filter_var(urldecode($_GET['d
|
|||
//Declare and instantiate POST variables
|
||||
$database_password = (isset($_POST['database_password'])) ? filter_var(urldecode($_POST['database_password']), FILTER_SANITIZE_STRING) : "";
|
||||
|
||||
//Require code from lxd-dashboard/php/config/db.php
|
||||
//Require code from lxd-dashboard/backend/config/db.php
|
||||
require_once('../config/db.php');
|
||||
|
||||
switch ($action) {
|
|
@ -36,13 +36,13 @@ if (isset($_SESSION['username'])) {
|
|||
$certificate = (isset($_POST['certificate'])) ? $_POST['certificate'] : "";
|
||||
$json = (isset($_POST['json'])) ? $_POST['json'] : "";
|
||||
|
||||
//Require code from lxd-dashboard/php/config/curl.php
|
||||
//Require code from lxd-dashboard/backend/config/curl.php
|
||||
require_once('../config/curl.php');
|
||||
|
||||
//Require code from lxd-dashboard/php/config/db.php
|
||||
//Require code from lxd-dashboard/backend/config/db.php
|
||||
require_once('../config/db.php');
|
||||
|
||||
//Require code from lxd-dashboard/php/aaa/accounting.php
|
||||
//Require code from lxd-dashboard/backend/aaa/accounting.php
|
||||
require_once('../aaa/accounting.php');
|
||||
|
||||
//Query database for remote host record
|
||||
|
@ -116,32 +116,36 @@ if (isset($_SESSION['username'])) {
|
|||
|
||||
echo '{ "data": [';
|
||||
|
||||
foreach ($certificates as $certificate){
|
||||
if ($i > 0){
|
||||
echo ",";
|
||||
}
|
||||
$i++;
|
||||
if ($results['status_code'] == "200"){
|
||||
|
||||
foreach ($certificates as $certificate){
|
||||
if ($i > 0){
|
||||
echo ",";
|
||||
}
|
||||
$i++;
|
||||
|
||||
echo "[ ";
|
||||
echo "[ ";
|
||||
|
||||
echo '"';
|
||||
echo "<i class='fas fa-wallet fa-lg' style='color:#4e73df'></i>";
|
||||
echo '",';
|
||||
|
||||
echo '"';
|
||||
echo htmlentities($certificate['name']);
|
||||
echo '",';
|
||||
|
||||
echo '"' . htmlentities($certificate['type']) . '",';
|
||||
echo '"' . htmlentities($certificate['fingerprint']) . '",';
|
||||
|
||||
echo '"';
|
||||
echo "<a href='#' onclick=loadCertificateJson('".$certificate['fingerprint']."')><i class='fas fa-edit fa-lg' style='color:#ddd' title='Edit' aria-hidden='true'></i></a>";
|
||||
echo "   ";
|
||||
echo "<a href='#' onclick=deleteCertificate('".$certificate['fingerprint']."')><i class='fas fa-trash-alt fa-lg' style='color:#ddd' title='Delete' aria-hidden='true'></i></a>";
|
||||
echo '"';
|
||||
|
||||
echo " ]";
|
||||
}
|
||||
|
||||
echo '"';
|
||||
echo "<i class='fas fa-wallet fa-lg' style='color:#4e73df'></i>";
|
||||
echo '",';
|
||||
|
||||
echo '"';
|
||||
echo htmlentities($certificate['name']);
|
||||
echo '",';
|
||||
|
||||
echo '"' . htmlentities($certificate['type']) . '",';
|
||||
echo '"' . htmlentities($certificate['fingerprint']) . '",';
|
||||
|
||||
echo '"';
|
||||
echo "<a href='#' onclick=loadCertificateJson('".$certificate['fingerprint']."')><i class='fas fa-edit fa-lg' style='color:#ddd' title='Edit' aria-hidden='true'></i></a>";
|
||||
echo "   ";
|
||||
echo "<a href='#' onclick=deleteCertificate('".$certificate['fingerprint']."')><i class='fas fa-trash-alt fa-lg' style='color:#ddd' title='Delete' aria-hidden='true'></i></a>";
|
||||
echo '"';
|
||||
|
||||
echo " ]";
|
||||
}
|
||||
|
||||
echo " ]}";
|
|
@ -33,13 +33,13 @@ if (isset($_SESSION['username'])) {
|
|||
$project = (isset($_GET['project'])) ? filter_var(urldecode($_GET['project']), FILTER_SANITIZE_STRING) : "";
|
||||
$remote = (isset($_GET['remote'])) ? filter_var(urldecode($_GET['remote']), FILTER_SANITIZE_NUMBER_INT) : "";
|
||||
|
||||
//Require code from lxd-dashboard/php/config/curl.php
|
||||
//Require code from lxd-dashboard/backend/config/curl.php
|
||||
require_once('../config/curl.php');
|
||||
|
||||
//Require code from lxd-dashboard/php/config/db.php
|
||||
//Require code from lxd-dashboard/backend/config/db.php
|
||||
require_once('../config/db.php');
|
||||
|
||||
//Require code from lxd-dashboard/php/aaa/accounting.php
|
||||
//Require code from lxd-dashboard/backend/aaa/accounting.php
|
||||
require_once('../aaa/accounting.php');
|
||||
|
||||
//Query database for remote host record
|
||||
|
@ -88,33 +88,37 @@ if (isset($_SESSION['username'])) {
|
|||
|
||||
$i = 0;
|
||||
|
||||
foreach ($members as $member){
|
||||
if ($results['status_code'] == "200"){
|
||||
|
||||
foreach ($members as $member){
|
||||
|
||||
$database_status = ($member['database']) ? "true" : "false";
|
||||
$database_status = ($member['database']) ? "true" : "false";
|
||||
|
||||
if ($i > 0){
|
||||
echo ",";
|
||||
}
|
||||
$i++;
|
||||
if ($i > 0){
|
||||
echo ",";
|
||||
}
|
||||
$i++;
|
||||
|
||||
echo "[ ";
|
||||
echo "[ ";
|
||||
|
||||
echo '"';
|
||||
echo "<i class='fas fa-layer-group fa-lg' style='color:#4e73df'></i>";
|
||||
echo '",';
|
||||
echo '"';
|
||||
echo "<i class='fas fa-layer-group fa-lg' style='color:#4e73df'></i>";
|
||||
echo '",';
|
||||
|
||||
echo '"' . htmlentities($member['server_name']) . '",';
|
||||
echo '"' . htmlentities($member['url']) . '",';
|
||||
echo '"' . $database_status . '",';
|
||||
echo '"' . htmlentities($member['status']) . '",';
|
||||
echo '"' . htmlentities($member['message']) . '",';
|
||||
echo '"' . htmlentities($member['server_name']) . '",';
|
||||
echo '"' . htmlentities($member['url']) . '",';
|
||||
echo '"' . $database_status . '",';
|
||||
echo '"' . htmlentities($member['status']) . '",';
|
||||
echo '"' . htmlentities($member['message']) . '",';
|
||||
|
||||
echo '"';
|
||||
echo "<a href='#' onclick=loadDeleteClusterMemberModal('".$member['server_name']."')> <i class='fas fa-trash-alt fa-lg' style='color:#ddd' title='Delete' aria-hidden='true'></i> </a>";
|
||||
echo '"';
|
||||
echo '"';
|
||||
echo "<a href='#' onclick=loadDeleteClusterMemberModal('".$member['server_name']."')> <i class='fas fa-trash-alt fa-lg' style='color:#ddd' title='Delete' aria-hidden='true'></i> </a>";
|
||||
echo '"';
|
||||
|
||||
echo " ]";
|
||||
echo " ]";
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
1477
lxd-dashboard/backend/lxd/containers-single.php
Normal file
1079
lxd-dashboard/backend/lxd/containers.php
Normal file
|
@ -37,13 +37,13 @@ if (isset($_SESSION['username'])) {
|
|||
//Declare and instantiate POST variables
|
||||
$json = (isset($_POST['json'])) ? $_POST['json'] : "";
|
||||
|
||||
//Require code from lxd-dashboard/php/config/curl.php
|
||||
//Require code from lxd-dashboard/backend/config/curl.php
|
||||
require_once('../config/curl.php');
|
||||
|
||||
//Require code from lxd-dashboard/php/config/db.php
|
||||
//Require code from lxd-dashboard/backend/config/db.php
|
||||
require_once('../config/db.php');
|
||||
|
||||
//Require code from lxd-dashboard/php/aaa/accounting.php
|
||||
//Require code from lxd-dashboard/backend/aaa/accounting.php
|
||||
require_once('../aaa/accounting.php');
|
||||
|
||||
//Query database for remote host record
|
||||
|
@ -93,35 +93,39 @@ if (isset($_SESSION['username'])) {
|
|||
|
||||
$i = 0;
|
||||
echo '{ "data": [';
|
||||
|
||||
if ($results['status_code'] == "200"){
|
||||
|
||||
foreach ($images as $image){
|
||||
foreach ($images as $image){
|
||||
|
||||
if ($image['fingerprint'] == "")
|
||||
continue;
|
||||
if ($image['fingerprint'] == "")
|
||||
continue;
|
||||
|
||||
if ($i > 0){
|
||||
echo ",";
|
||||
if ($i > 0){
|
||||
echo ",";
|
||||
}
|
||||
$i++;
|
||||
|
||||
echo "[ ";
|
||||
|
||||
echo '"' . "<i class='fas fa-box-open fa-lg' style='color:#4e73df'></i>" . '",';
|
||||
echo '"' . htmlentities($image['properties']['description']) . '",';
|
||||
echo '"' . htmlentities($image['fingerprint']) . '",';
|
||||
echo '"' . htmlentities($image['type']) . '",';
|
||||
echo '"' . htmlentities(number_format($image['size'] / 1048576, 2)) . ' MiB",';
|
||||
|
||||
echo '"';
|
||||
echo "<a href='#' onclick=refreshImage('".$image['fingerprint']."')><i class='fas fa-sync-alt fa-lg' style='color:#ddd' title='Refresh' aria-hidden='true'></i></a>";
|
||||
echo "   ";
|
||||
echo "<a href='#' onclick=loadImageJson('".$image['fingerprint']."')><i class='fas fa-edit fa-lg' style='color:#ddd' title='Edit' aria-hidden='true'></i></a>";
|
||||
echo "   ";
|
||||
echo "<a href='#' onclick=deleteImage('".$image['fingerprint']."')><i class='fas fa-trash-alt fa-lg' style='color:#ddd' title='Delete' aria-hidden='true'></i></a>";
|
||||
echo '"';
|
||||
|
||||
echo " ]";
|
||||
|
||||
}
|
||||
$i++;
|
||||
|
||||
echo "[ ";
|
||||
|
||||
echo '"' . "<i class='fas fa-box-open fa-lg' style='color:#4e73df'></i>" . '",';
|
||||
echo '"' . htmlentities($image['properties']['description']) . '",';
|
||||
echo '"' . htmlentities($image['fingerprint']) . '",';
|
||||
echo '"' . htmlentities($image['type']) . '",';
|
||||
echo '"' . htmlentities(number_format($image['size'] / 1048576, 2)) . ' MB",';
|
||||
|
||||
echo '"';
|
||||
echo "<a href='#' onclick=refreshImage('".$image['fingerprint']."')><i class='fas fa-sync-alt fa-lg' style='color:#ddd' title='Refresh' aria-hidden='true'></i></a>";
|
||||
echo "   ";
|
||||
echo "<a href='#' onclick=loadImageJson('".$image['fingerprint']."')><i class='fas fa-edit fa-lg' style='color:#ddd' title='Edit' aria-hidden='true'></i></a>";
|
||||
echo "   ";
|
||||
echo "<a href='#' onclick=deleteImage('".$image['fingerprint']."')><i class='fas fa-trash-alt fa-lg' style='color:#ddd' title='Delete' aria-hidden='true'></i></a>";
|
||||
echo '"';
|
||||
|
||||
echo " ]";
|
||||
|
||||
|
||||
}
|
||||
|
||||
echo " ]}";
|
||||
|
@ -140,9 +144,15 @@ if (isset($_SESSION['username'])) {
|
|||
echo '<option value="none">none</option>';
|
||||
|
||||
foreach ($images as $image){
|
||||
if ($image_type == "virtual-machine"){
|
||||
if ($image['fingerprint'] == "" || $image['type'] != $image_type)
|
||||
continue;
|
||||
}
|
||||
else {
|
||||
if ($image['fingerprint'] == "" || $image['type'] == "virtual-machine")
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($image['fingerprint'] == "" || $image['type'] != $image_type)
|
||||
continue;
|
||||
|
||||
echo '<option value="' . $image['fingerprint'] . '">' . htmlentities($image['properties']['description']) . '</option>';
|
||||
|
|
@ -48,13 +48,13 @@ if (isset($_SESSION['username'])) {
|
|||
//Declare and instantiate POST variables
|
||||
$json = (isset($_POST['json'])) ? $_POST['json'] : "";
|
||||
|
||||
//Require code from lxd-dashboard/php/config/curl.php
|
||||
//Require code from lxd-dashboard/backend/config/curl.php
|
||||
require_once('../config/curl.php');
|
||||
|
||||
//Require code from lxd-dashboard/php/config/db.php
|
||||
//Require code from lxd-dashboard/backend/config/db.php
|
||||
require_once('../config/db.php');
|
||||
|
||||
//Require code from lxd-dashboard/php/aaa/accounting.php
|
||||
//Require code from lxd-dashboard/backend/aaa/accounting.php
|
||||
require_once('../aaa/accounting.php');
|
||||
|
||||
//Query database for remote host record
|
||||
|
@ -359,59 +359,63 @@ if (isset($_SESSION['username'])) {
|
|||
$i = 0;
|
||||
echo '{ "data": [';
|
||||
|
||||
foreach ($network_acls as $network_acl){
|
||||
$network_acl_name = (isset($network_acl['name'])) ? htmlentities($network_acl['name']) : "";
|
||||
|
||||
if ($network_acl_name == "")
|
||||
continue;
|
||||
if ($results['status_code'] == "200"){
|
||||
|
||||
if ($i > 0){
|
||||
echo ",";
|
||||
}
|
||||
$i++;
|
||||
foreach ($network_acls as $network_acl){
|
||||
$network_acl_name = (isset($network_acl['name'])) ? htmlentities($network_acl['name']) : "";
|
||||
|
||||
if ($network_acl_name == "")
|
||||
continue;
|
||||
|
||||
echo "[ ";
|
||||
|
||||
echo '"';
|
||||
echo "<i class='fas fa-shield-alt fa-lg' style='color:#4e73df'></i>";
|
||||
echo '",';
|
||||
|
||||
echo '"';
|
||||
echo $network_acl_name;
|
||||
echo '",';
|
||||
|
||||
echo '"' . htmlentities($network_acl['description']) . '",';
|
||||
|
||||
echo '"';
|
||||
echo "<a href='network-acls-ingress.html?network_acl=".$network_acl['name']."&remote=".$remote."&project=".$project."'>".count($network_acl['ingress'])."</a>";
|
||||
echo '",';
|
||||
|
||||
echo '"';
|
||||
echo "<a href='network-acls-egress.html?network_acl=".$network_acl['name']."&remote=".$remote."&project=".$project."'>".count($network_acl['egress'])."</a>";
|
||||
echo '",';
|
||||
|
||||
$used_by = "";
|
||||
$ii = 0;
|
||||
foreach($network_acl['used_by'] as $network){
|
||||
if ($ii > 0){
|
||||
$used_by .= ", ";
|
||||
if ($i > 0){
|
||||
echo ",";
|
||||
}
|
||||
$ii++;
|
||||
$used_by .= $network;
|
||||
$i++;
|
||||
|
||||
echo "[ ";
|
||||
|
||||
echo '"';
|
||||
echo "<i class='fas fa-shield-alt fa-lg' style='color:#4e73df'></i>";
|
||||
echo '",';
|
||||
|
||||
echo '"';
|
||||
echo $network_acl_name;
|
||||
echo '",';
|
||||
|
||||
echo '"' . htmlentities($network_acl['description']) . '",';
|
||||
|
||||
echo '"';
|
||||
echo "<a href='network-acls-ingress.php?network_acl=".$network_acl['name']."&remote=".$remote."&project=".$project."'>".count($network_acl['ingress'])."</a>";
|
||||
echo '",';
|
||||
|
||||
echo '"';
|
||||
echo "<a href='network-acls-egress.php?network_acl=".$network_acl['name']."&remote=".$remote."&project=".$project."'>".count($network_acl['egress'])."</a>";
|
||||
echo '",';
|
||||
|
||||
$used_by = "";
|
||||
$ii = 0;
|
||||
foreach($network_acl['used_by'] as $network){
|
||||
if ($ii > 0){
|
||||
$used_by .= ", ";
|
||||
}
|
||||
$ii++;
|
||||
$used_by .= $network;
|
||||
}
|
||||
|
||||
echo '"' . htmlentities($used_by) . '",';
|
||||
|
||||
echo '"';
|
||||
echo "<a href='#' onclick=loadNetworkAclJson('".$network_acl['name']."')><i class='fas fa-edit fa-lg' style='color:#ddd' title='Edit' aria-hidden='true'></i></a>";
|
||||
echo "   ";
|
||||
echo "<a href='#' onclick=loadRenameNetworkAcl('".$network_acl['name']."')><i class='fas fa-tag fa-lg' style='color:#ddd' title='Rename' aria-hidden='true'></i></a>";
|
||||
echo "   ";
|
||||
echo "<a href='#' onclick=deleteNetworkAcl('".$network_acl['name']."')><i class='fas fa-trash-alt fa-lg' style='color:#ddd' title='Delete' aria-hidden='true'></i></a>";
|
||||
echo '"';
|
||||
|
||||
echo " ]";
|
||||
|
||||
}
|
||||
|
||||
echo '"' . htmlentities($used_by) . '",';
|
||||
|
||||
echo '"';
|
||||
echo "<a href='#' onclick=loadNetworkAclJson('".$network_acl['name']."')><i class='fas fa-edit fa-lg' style='color:#ddd' title='Edit' aria-hidden='true'></i></a>";
|
||||
echo "   ";
|
||||
echo "<a href='#' onclick=loadRenameNetworkAcl('".$network_acl['name']."')><i class='fas fa-tag fa-lg' style='color:#ddd' title='Rename' aria-hidden='true'></i></a>";
|
||||
echo "   ";
|
||||
echo "<a href='#' onclick=deleteNetworkAcl('".$network_acl['name']."')><i class='fas fa-trash-alt fa-lg' style='color:#ddd' title='Delete' aria-hidden='true'></i></a>";
|
||||
echo '"';
|
||||
|
||||
echo " ]";
|
||||
|
||||
}
|
||||
|
||||
echo " ]}";
|
|
@ -86,13 +86,13 @@ if (isset($_SESSION['username'])) {
|
|||
//Declare and instantiate POST variables
|
||||
$json = (isset($_POST['json'])) ? $_POST['json'] : "";
|
||||
|
||||
//Require code from lxd-dashboard/php/config/curl.php
|
||||
//Require code from lxd-dashboard/backend/config/curl.php
|
||||
require_once('../config/curl.php');
|
||||
|
||||
//Require code from lxd-dashboard/php/config/db.php
|
||||
//Require code from lxd-dashboard/backend/config/db.php
|
||||
require_once('../config/db.php');
|
||||
|
||||
//Require code from lxd-dashboard/php/aaa/accounting.php
|
||||
//Require code from lxd-dashboard/backend/aaa/accounting.php
|
||||
require_once('../aaa/accounting.php');
|
||||
|
||||
//Query database for remote host record
|
||||
|
@ -348,9 +348,70 @@ if (isset($_SESSION['username'])) {
|
|||
break;
|
||||
|
||||
case "createNetworkUsingJSON":
|
||||
$url = $base_url . "/1.0/networks?project=" . $project;
|
||||
$data = $json;
|
||||
$results = sendCurlRequest($action, "POST", $url, $data);
|
||||
|
||||
//Check to see if host is part of a cluster. Clusted hosts need network created first on each of the hosts
|
||||
$url = $base_url . "/1.0/cluster";
|
||||
$remote_data = sendCurlRequest($action, "GET", $url);
|
||||
$remote_data = json_decode($remote_data, true);
|
||||
$cluster_status = $remote_data['metadata'];
|
||||
|
||||
if ($cluster_status['enabled'] == true){
|
||||
//Get a list of cluster members
|
||||
$url = $base_url . "/1.0/cluster/members?recursion=1";
|
||||
$cluster_api_data = sendCurlRequest($action, "GET", $url);
|
||||
$cluster_api_data = json_decode($cluster_api_data, true);
|
||||
$cluster_api_data = $cluster_api_data['metadata'];
|
||||
|
||||
//Setup Network data for REST API
|
||||
$target_json_array = json_decode($json, true);
|
||||
|
||||
//Setup Network data for REST API
|
||||
$target_device_array = array();
|
||||
$target_device_array['config'] = new ArrayObject();
|
||||
$target_device_array['name'] = $target_json_array['name'];
|
||||
$target_device_array['type'] = $target_json_array['type'];
|
||||
$target_device_array['description'] = $target_json_array['description'];
|
||||
|
||||
if ($target_device_array['type'] == "bridge"){
|
||||
if (!empty($target_json_array['config']['bridge.external_interfaces'])){ $target_device_array['config']['bridge.external_interfaces'] = $target_json_array['config']['bridge.external_interfaces'];}
|
||||
}
|
||||
if ($target_device_array['type'] == "macvlan" || $target_device_array['type'] == "sriov"){
|
||||
if (!empty($target_json_array['config']['parent'])){ $target_device_array['config']['parent'] = $target_json_array['config']['parent'];}
|
||||
}
|
||||
|
||||
if ($target_device_array['type'] == "ovn"){
|
||||
}
|
||||
|
||||
if ($target_device_array['type'] == "physical"){
|
||||
if (!empty($target_json_array['config']['parent'])){ $target_device_array['config']['parent'] = $target_json_array['config']['parent'];}
|
||||
}
|
||||
|
||||
$target_data = json_encode($target_device_array);
|
||||
|
||||
//Loop through each cluster member to create the network, this will put the network in pending status
|
||||
foreach ($cluster_api_data as $cluster_data){
|
||||
$url = $base_url . "/1.0/networks?project=" . $project . "&target=".$cluster_data['server_name'];
|
||||
$results = sendCurlRequest($action, "POST", $url, $target_data);
|
||||
}
|
||||
|
||||
//Now lets create the network without target config options, moving the pending status to created
|
||||
$url = $base_url . "/1.0/networks?project=" . $project;
|
||||
|
||||
//Setup Network data for REST API
|
||||
$device_array = json_decode($json, true);
|
||||
unset($device_array['config']['bridge.external_interfaces']);
|
||||
unset($device_array['config']['parent']);
|
||||
|
||||
$data = json_encode($device_array);
|
||||
$results = sendCurlRequest($action, "POST", $url, $data);
|
||||
|
||||
}
|
||||
else {
|
||||
$url = $base_url . "/1.0/networks?project=" . $project;
|
||||
$data = $json;
|
||||
$results = sendCurlRequest($action, "POST", $url, $data);
|
||||
}
|
||||
|
||||
echo $results;
|
||||
|
||||
//Send event to accounting
|
||||
|
@ -390,61 +451,65 @@ if (isset($_SESSION['username'])) {
|
|||
$i = 0;
|
||||
echo '{ "data": [';
|
||||
|
||||
foreach ($networks as $network){
|
||||
|
||||
if ($network['name'] == "")
|
||||
continue;
|
||||
if ($results['status_code'] == "200"){
|
||||
|
||||
$network_data_managed = ($network['managed']) ? "true" : "false";
|
||||
foreach ($networks as $network){
|
||||
|
||||
if ($network['name'] == "")
|
||||
continue;
|
||||
|
||||
//This array key is not availabe on unmanaged network devices
|
||||
if (isset($network['config']['ipv4.address']))
|
||||
$ipv4 = $network['config']['ipv4.address'];
|
||||
else
|
||||
$ipv4 = "";
|
||||
$network_data_managed = ($network['managed']) ? "true" : "false";
|
||||
|
||||
//This array key is not available on unmanaged network devices
|
||||
if (isset($network['config']['ipv6.address']))
|
||||
$ipv6 = $network['config']['ipv6.address'];
|
||||
else
|
||||
$ipv6 = "";
|
||||
//This array key is not availabe on unmanaged network devices
|
||||
if (isset($network['config']['ipv4.address']))
|
||||
$ipv4 = $network['config']['ipv4.address'];
|
||||
else
|
||||
$ipv4 = "";
|
||||
|
||||
//This array key is not available on unmanaged network devices
|
||||
if (isset($network['config']['ipv6.address']))
|
||||
$ipv6 = $network['config']['ipv6.address'];
|
||||
else
|
||||
$ipv6 = "";
|
||||
|
||||
if ($i > 0){
|
||||
echo ",";
|
||||
}
|
||||
$i++;
|
||||
|
||||
echo "[ ";
|
||||
|
||||
if ($network['managed'] == "true"){
|
||||
echo '"' . "<i class='fas fa-network-wired fa-lg' style='color:#4e73df'></i>" . '",';
|
||||
echo '"' . htmlentities($network['name']) . '",';
|
||||
}
|
||||
else {
|
||||
echo '"' . "<i class='fas fa-network-wired fa-lg' style='color:#ddd'></i>" . '",';
|
||||
echo '"' . htmlentities($network['name']) . '",';
|
||||
}
|
||||
|
||||
echo '"' . htmlentities($network['description']) . '",';
|
||||
echo '"' . htmlentities($ipv4) . '",';
|
||||
echo '"' . htmlentities($ipv6) . '",';
|
||||
echo '"' . htmlentities($network['type']) . '",';
|
||||
echo '"' . htmlentities($network_data_managed) . '",';
|
||||
|
||||
echo '"';
|
||||
if ($network['managed'] == "true"){
|
||||
echo "<a href='#' onclick=loadNetworkJson('".$network['name']."')><i class='fas fa-edit fa-lg' style='color:#ddd' title='Edit' aria-hidden='true'></i></a>";
|
||||
echo "   ";
|
||||
echo "<a href='#' onclick=loadRenameNetwork('".$network['name']."')><i class='fas fa-tag fa-lg' style='color:#ddd' title='Rename' aria-hidden='true'></i></a>";
|
||||
echo "   ";
|
||||
echo "<a href='#' onclick=deleteNetwork('".$network['name']."')><i class='fas fa-trash-alt fa-lg' style='color:#ddd' title='Delete' aria-hidden='true'></i></a>";
|
||||
}
|
||||
echo '"';
|
||||
|
||||
echo " ]";
|
||||
|
||||
if ($i > 0){
|
||||
echo ",";
|
||||
}
|
||||
$i++;
|
||||
|
||||
echo "[ ";
|
||||
|
||||
if ($network['managed'] == "true"){
|
||||
echo '"' . "<i class='fas fa-network-wired fa-lg' style='color:#4e73df'></i>" . '",';
|
||||
echo '"' . htmlentities($network['name']) . '",';
|
||||
}
|
||||
else {
|
||||
echo '"' . "<i class='fas fa-network-wired fa-lg' style='color:#ddd'></i>" . '",';
|
||||
echo '"' . htmlentities($network['name']) . '",';
|
||||
}
|
||||
|
||||
echo '"' . htmlentities($network['description']) . '",';
|
||||
echo '"' . htmlentities($ipv4) . '",';
|
||||
echo '"' . htmlentities($ipv6) . '",';
|
||||
echo '"' . htmlentities($network['type']) . '",';
|
||||
echo '"' . htmlentities($network_data_managed) . '",';
|
||||
|
||||
echo '"';
|
||||
if ($network['managed'] == "true"){
|
||||
echo "<a href='#' onclick=loadNetworkJson('".$network['name']."')><i class='fas fa-edit fa-lg' style='color:#ddd' title='Edit' aria-hidden='true'></i></a>";
|
||||
echo "   ";
|
||||
echo "<a href='#' onclick=loadRenameNetwork('".$network['name']."')><i class='fas fa-tag fa-lg' style='color:#ddd' title='Rename' aria-hidden='true'></i></a>";
|
||||
echo "   ";
|
||||
echo "<a href='#' onclick=deleteNetwork('".$network['name']."')><i class='fas fa-trash-alt fa-lg' style='color:#ddd' title='Delete' aria-hidden='true'></i></a>";
|
||||
}
|
||||
echo '"';
|
||||
|
||||
echo " ]";
|
||||
|
||||
}
|
||||
|
||||
|
||||
echo " ]}";
|
||||
}
|
||||
else {
|
|
@ -34,13 +34,13 @@ if (isset($_SESSION['username'])) {
|
|||
//Instantiate the POST variable
|
||||
$json = (isset($_POST['json'])) ? $_POST['json'] : "";
|
||||
|
||||
//Require code from lxd-dashboard/php/config/curl.php
|
||||
//Require code from lxd-dashboard/backend/config/curl.php
|
||||
require_once('../config/curl.php');
|
||||
|
||||
//Require code from lxd-dashboard/php/config/db.php
|
||||
//Require code from lxd-dashboard/backend/config/db.php
|
||||
require_once('../config/db.php');
|
||||
|
||||
//Require code from lxd-dashboard/php/aaa/accounting.php
|
||||
//Require code from lxd-dashboard/backend/aaa/accounting.php
|
||||
require_once('../aaa/accounting.php');
|
||||
|
||||
//Query database for remote host record
|
||||
|
@ -77,7 +77,9 @@ if (isset($_SESSION['username'])) {
|
|||
|
||||
if (!empty($operations_data['running'])){
|
||||
foreach ($operations_data['running'] as $running_task){
|
||||
$results = $running_task['description'];
|
||||
//This is annoyingly showing when using exec terminal, will look to build indicator for when someone is executing a command on instance page instead
|
||||
if ($running_task['description'] != "Executing command")
|
||||
$results = $running_task['description'];
|
||||
|
||||
if (isset($running_task['resources']['instances'][0])) {
|
||||
$instance = basename($running_task['resources']['instances'][0]);
|
||||
|
@ -115,8 +117,8 @@ if (isset($_SESSION['username'])) {
|
|||
$results .= " " . htmlentities($running_task['metadata']['download_progress']);
|
||||
break;
|
||||
case "Executing command":
|
||||
if (isset($running_task['metadata']['command'][0]))
|
||||
$results = "Executing " . htmlentities($running_task['metadata']['command'][0]) . " command on " . htmlentities($instance);
|
||||
//if (isset($running_task['metadata']['command'][0]))
|
||||
//$results = "Executing " . htmlentities($running_task['metadata']['command'][0]) . " command on " . htmlentities($instance);
|
||||
break;
|
||||
case "Freezing instance":
|
||||
$results .= " " . $instance;
|
||||
|
@ -142,13 +144,21 @@ if (isset($_SESSION['username'])) {
|
|||
case "Updating instance":
|
||||
$results .= " " . $instance;
|
||||
break;
|
||||
case "Image download token":
|
||||
#Remove image tokens left over from image downloads when in a cluster
|
||||
if ($running_task['may_cancel'] == true){
|
||||
$url = $base_url . "/1.0/operations/" . $running_task['id'];
|
||||
$results = sendCurlRequest($action, "DELETE", $url);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($operations_data['failure'])){
|
||||
foreach ($operations_data['failure'] as $failed_task){
|
||||
$results = $failed_task['description'] . " Error: " . $failed_task['err'];
|
||||
if ($failed_task['description'] != "Executing command") //This is to prevent error message when VM is starting up due to CPU and Mem stats
|
||||
$results = $failed_task['description'] . " Error: " . $failed_task['err'];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -166,50 +176,55 @@ if (isset($_SESSION['username'])) {
|
|||
$i = 0;
|
||||
echo '{ "data": [';
|
||||
|
||||
foreach ($operations_dict as $operations){
|
||||
if ($results['status_code'] == "200"){
|
||||
|
||||
foreach ($operations as $operation){
|
||||
foreach ($operations_dict as $operations){
|
||||
|
||||
if ($i > 0){
|
||||
echo ",";
|
||||
}
|
||||
$i++;
|
||||
|
||||
echo "[ ";
|
||||
echo '"';
|
||||
echo "<a href='#' onclick=loadOperationJson('".$operation['id']."')> <i class='fas fa-exchange-alt fa-lg' style='color:#4e73df'></i> </a>";
|
||||
echo '",';
|
||||
foreach ($operations as $operation){
|
||||
|
||||
echo '"';
|
||||
echo "<a href='#' onclick=loadOperationJson('".$operation['id']."')>".htmlentities($operation['id'])."</a>";
|
||||
echo '",';
|
||||
|
||||
echo '"' . htmlentities($operation['class']) . '",';
|
||||
echo '"' . htmlentities($operation['description']) . '",';
|
||||
echo '"' . htmlentities($operation['status']) . '",';
|
||||
echo '"' . htmlentities($operation['created_at']) . '",';
|
||||
|
||||
if($operation['may_cancel']){
|
||||
$may_cancel = "true";
|
||||
echo '"' . htmlentities($may_cancel) . '",';
|
||||
if ($i > 0){
|
||||
echo ",";
|
||||
}
|
||||
$i++;
|
||||
|
||||
echo "[ ";
|
||||
echo '"';
|
||||
echo "<a href='#' onclick=loadOperationJson('".$operation['id']."')> <i class='fas fa-exchange-alt fa-lg' style='color:#4e73df'></i> </a>";
|
||||
echo '",';
|
||||
|
||||
echo '"';
|
||||
echo "<a href='#' onclick=deleteOperation('".$operation['id']."')> <i class='fas fa-trash-alt fa-lg' style='color:#ddd' title='Delete' aria-hidden='true'></i> </a>";
|
||||
echo '"';
|
||||
}
|
||||
echo "<a href='#' onclick=loadOperationJson('".$operation['id']."')>".htmlentities($operation['id'])."</a>";
|
||||
echo '",';
|
||||
|
||||
echo '"' . htmlentities($operation['class']) . '",';
|
||||
echo '"' . htmlentities($operation['description']) . '",';
|
||||
echo '"' . htmlentities($operation['status']) . '",';
|
||||
echo '"' . htmlentities($operation['created_at']) . '",';
|
||||
|
||||
if($operation['may_cancel']){
|
||||
$may_cancel = "true";
|
||||
echo '"' . htmlentities($may_cancel) . '",';
|
||||
|
||||
echo '"';
|
||||
echo "<a href='#' onclick=deleteOperation('".$operation['id']."')> <i class='fas fa-trash-alt fa-lg' style='color:#ddd' title='Delete' aria-hidden='true'></i> </a>";
|
||||
echo '"';
|
||||
}
|
||||
|
||||
else{
|
||||
$may_cancel = "false";
|
||||
echo '"' . htmlentities($may_cancel) . '",';
|
||||
echo '" ';
|
||||
echo ' "';
|
||||
}
|
||||
|
||||
else{
|
||||
$may_cancel = "false";
|
||||
echo '"' . htmlentities($may_cancel) . '",';
|
||||
echo '" ';
|
||||
echo ' "';
|
||||
echo " ]";
|
||||
|
||||
}
|
||||
|
||||
echo " ]";
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
echo " ]}";
|
||||
}
|
||||
else {
|
|
@ -37,13 +37,13 @@ if (isset($_SESSION['username'])) {
|
|||
//Declare and instantiate POST variables
|
||||
$json = (isset($_POST['json'])) ? $_POST['json'] : "";
|
||||
|
||||
//Require code from lxd-dashboard/php/config/curl.php
|
||||
//Require code from lxd-dashboard/backend/config/curl.php
|
||||
require_once('../config/curl.php');
|
||||
|
||||
//Require code from lxd-dashboard/php/config/db.php
|
||||
//Require code from lxd-dashboard/backend/config/db.php
|
||||
require_once('../config/db.php');
|
||||
|
||||
//Require code from lxd-dashboard/php/aaa/accounting.php
|
||||
//Require code from lxd-dashboard/backend/aaa/accounting.php
|
||||
require_once('../aaa/accounting.php');
|
||||
|
||||
//Query database for remote host record
|
||||
|
@ -112,40 +112,44 @@ if (isset($_SESSION['username'])) {
|
|||
$i = 0;
|
||||
echo '{ "data": [';
|
||||
|
||||
foreach ($profiles as $profile){
|
||||
if ($results['status_code'] == "200"){
|
||||
|
||||
if ($profile['name'] == "")
|
||||
continue;
|
||||
|
||||
if ($i > 0){
|
||||
echo ",";
|
||||
}
|
||||
$i++;
|
||||
foreach ($profiles as $profile){
|
||||
|
||||
echo "[ ";
|
||||
echo '"' . "<i class='fas fa-money-check' style='color:#4e73df'></i>" . '",';
|
||||
echo '"' . htmlentities($profile['name']) . '",';
|
||||
echo '"' . htmlentities($profile['description']) . '",';
|
||||
|
||||
echo '"';
|
||||
$ii = 0;
|
||||
foreach($profile['devices'] as $device=>$value){
|
||||
if ($ii > 0)
|
||||
echo ", ";
|
||||
echo htmlentities($device);
|
||||
$ii++;
|
||||
if ($profile['name'] == "")
|
||||
continue;
|
||||
|
||||
if ($i > 0){
|
||||
echo ",";
|
||||
}
|
||||
echo '",';
|
||||
$i++;
|
||||
|
||||
echo '"';
|
||||
echo "<a href='#' onclick=loadProfileJson('".$profile['name']."')><i class='fas fa-edit fa-lg' style='color:#ddd' title='Edit' aria-hidden='true'></i></a>";
|
||||
echo "   ";
|
||||
echo "<a href='#' onclick=loadRenameProfile('".$profile['name']."')><i class='fas fa-tag fa-lg' style='color:#ddd' title='Rename' aria-hidden='true'></i></a>";
|
||||
echo "   ";
|
||||
echo "<a href='#' onclick=deleteProfile('".$profile['name']."')><i class='fas fa-trash-alt fa-lg' style='color:#ddd' title='Delete' aria-hidden='true'></i></a>";
|
||||
echo '"';
|
||||
echo "[ ";
|
||||
echo '"' . "<i class='fas fa-money-check' style='color:#4e73df'></i>" . '",';
|
||||
echo '"' . htmlentities($profile['name']) . '",';
|
||||
echo '"' . htmlentities($profile['description']) . '",';
|
||||
|
||||
echo " ]";
|
||||
echo '"';
|
||||
$ii = 0;
|
||||
foreach($profile['devices'] as $device=>$value){
|
||||
if ($ii > 0)
|
||||
echo ", ";
|
||||
echo htmlentities($device);
|
||||
$ii++;
|
||||
}
|
||||
echo '",';
|
||||
|
||||
echo '"';
|
||||
echo "<a href='#' onclick=loadProfileJson('".$profile['name']."')><i class='fas fa-edit fa-lg' style='color:#ddd' title='Edit' aria-hidden='true'></i></a>";
|
||||
echo "   ";
|
||||
echo "<a href='#' onclick=loadRenameProfile('".$profile['name']."')><i class='fas fa-tag fa-lg' style='color:#ddd' title='Rename' aria-hidden='true'></i></a>";
|
||||
echo "   ";
|
||||
echo "<a href='#' onclick=deleteProfile('".$profile['name']."')><i class='fas fa-trash-alt fa-lg' style='color:#ddd' title='Delete' aria-hidden='true'></i></a>";
|
||||
echo '"';
|
||||
|
||||
echo " ]";
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -76,13 +76,13 @@ if (isset($_SESSION['username'])) {
|
|||
//Set the url when switching projects from the dropdown menu
|
||||
$return_url = strtok($_SERVER["HTTP_REFERER"], '?');
|
||||
|
||||
//Require code from lxd-dashboard/php/config/curl.php
|
||||
//Require code from lxd-dashboard/backend/config/curl.php
|
||||
require_once('../config/curl.php');
|
||||
|
||||
//Require code from lxd-dashboard/php/config/db.php
|
||||
//Require code from lxd-dashboard/backend/config/db.php
|
||||
require_once('../config/db.php');
|
||||
|
||||
//Require code from lxd-dashboard/php/aaa/accounting.php
|
||||
//Require code from lxd-dashboard/backend/aaa/accounting.php
|
||||
require_once('../aaa/accounting.php');
|
||||
|
||||
//Query database for remote host record
|
||||
|
@ -197,43 +197,47 @@ if (isset($_SESSION['username'])) {
|
|||
$i = 0;
|
||||
echo '{ "data": [';
|
||||
|
||||
foreach ($projects as $project_data){
|
||||
if ($results['status_code'] == "200"){
|
||||
|
||||
$features_images = (isset($project_data['config']['features.images'])) ? htmlentities($project_data['config']['features.images']) : "true";
|
||||
$features_networks = (isset($project_data['config']['features.networks'])) ? htmlentities($project_data['config']['features.networks']) : "false";
|
||||
$features_profiles = (isset($project_data['config']['features.profiles'])) ? htmlentities($project_data['config']['features.profiles']) : "true";
|
||||
$features_storage_volumes = (isset($project_data['config']['features.storage.volumes'])) ? htmlentities($project_data['config']['features.storage.volumes']) : "true";
|
||||
|
||||
if ($i > 0){
|
||||
echo ",";
|
||||
foreach ($projects as $project_data){
|
||||
|
||||
$features_images = (isset($project_data['config']['features.images'])) ? htmlentities($project_data['config']['features.images']) : "true";
|
||||
$features_networks = (isset($project_data['config']['features.networks'])) ? htmlentities($project_data['config']['features.networks']) : "false";
|
||||
$features_profiles = (isset($project_data['config']['features.profiles'])) ? htmlentities($project_data['config']['features.profiles']) : "true";
|
||||
$features_storage_volumes = (isset($project_data['config']['features.storage.volumes'])) ? htmlentities($project_data['config']['features.storage.volumes']) : "true";
|
||||
|
||||
if ($i > 0){
|
||||
echo ",";
|
||||
}
|
||||
$i++;
|
||||
|
||||
echo "[ ";
|
||||
echo '"';
|
||||
echo "<a href='remotes-single.php?remote=".$remote."&project=".$project_data['name'] ."'><i class='fas fa-chart-bar fa-lg' style='color:#4e73df'></i> </a>";
|
||||
echo '",';
|
||||
|
||||
echo '"';
|
||||
echo "<a href='remotes-single.php?remote=".$remote."&project=".$project_data['name'] ."'> ".htmlentities($project_data['name']) ."</a>";
|
||||
echo '",';
|
||||
|
||||
echo '"' . htmlentities($project_data['description']) . '",';
|
||||
echo '"' . $features_images . '",';
|
||||
echo '"' . $features_networks . '",';
|
||||
echo '"' . $features_profiles . '",';
|
||||
echo '"' . $features_storage_volumes . '",';
|
||||
|
||||
echo '"';
|
||||
echo "<a href='#' onclick=loadProjectJson('".$project_data['name']."')><i class='fas fa-edit fa-lg' style='color:#ddd' title='Edit' aria-hidden='true'></i></a>";
|
||||
echo "   ";
|
||||
echo "<a href='#' onclick=loadRenameProject('".$project_data['name']."')><i class='fas fa-tag fa-lg' style='color:#ddd' title='Rename' aria-hidden='true'></i></a>";
|
||||
echo "   ";
|
||||
echo "<a href='#' onclick=deleteProject('".$project_data['name']."')><i class='fas fa-trash-alt fa-lg' style='color:#ddd' title='Delete' aria-hidden='true'></i></a>";
|
||||
echo '"';
|
||||
|
||||
echo " ]";
|
||||
|
||||
}
|
||||
$i++;
|
||||
|
||||
echo "[ ";
|
||||
echo '"';
|
||||
echo "<a href='remotes-single.html?remote=".$remote."&project=".$project_data['name'] ."'><i class='fas fa-chart-bar fa-lg' style='color:#4e73df'></i> </a>";
|
||||
echo '",';
|
||||
|
||||
echo '"';
|
||||
echo "<a href='remotes-single.html?remote=".$remote."&project=".$project_data['name'] ."'> ".htmlentities($project_data['name']) ."</a>";
|
||||
echo '",';
|
||||
|
||||
echo '"' . htmlentities($project_data['description']) . '",';
|
||||
echo '"' . $features_images . '",';
|
||||
echo '"' . $features_networks . '",';
|
||||
echo '"' . $features_profiles . '",';
|
||||
echo '"' . $features_storage_volumes . '",';
|
||||
|
||||
echo '"';
|
||||
echo "<a href='#' onclick=loadProjectJson('".$project_data['name']."')><i class='fas fa-edit fa-lg' style='color:#ddd' title='Edit' aria-hidden='true'></i></a>";
|
||||
echo "   ";
|
||||
echo "<a href='#' onclick=loadRenameProject('".$project_data['name']."')><i class='fas fa-tag fa-lg' style='color:#ddd' title='Rename' aria-hidden='true'></i></a>";
|
||||
echo "   ";
|
||||
echo "<a href='#' onclick=deleteProject('".$project_data['name']."')><i class='fas fa-trash-alt fa-lg' style='color:#ddd' title='Delete' aria-hidden='true'></i></a>";
|
||||
echo '"';
|
||||
|
||||
echo " ]";
|
||||
|
||||
|
||||
}
|
||||
|
||||
echo " ]}";
|
||||
|
@ -243,34 +247,29 @@ if (isset($_SESSION['username'])) {
|
|||
}
|
||||
break;
|
||||
|
||||
case "listProjectsForTopNavigation":
|
||||
case "listProjectsForSelectOption":
|
||||
$url = $base_url . "/1.0/projects?recursion=1";
|
||||
$results = sendCurlRequest($action, "GET", $url);
|
||||
$results = json_decode($results, true);
|
||||
$projects = (isset($results['metadata'])) ? $results['metadata'] : [];
|
||||
|
||||
echo '<a class="nav-link dropdown-toggle" href="#" id="userDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">';
|
||||
echo '<i class="fas fa-chart-bar mr-2 text-gray-600"></i>';
|
||||
echo '<span class="mr-2 d-none d-lg-inline text-gray-600">Project: <font class="text-primary">'. htmlentities($project) . '</font></span>';
|
||||
echo '</a>';
|
||||
echo '<!-- Dropdown - User Information -->';
|
||||
echo '<div class="dropdown-menu dropdown-menu-right shadow animated--grow-in" aria-labelledby="userDropdown">';
|
||||
|
||||
foreach ($projects as $project_data){
|
||||
|
||||
if ($project_data['name'] == $project)
|
||||
echo '<a class="dropdown-item" href="'.$return_url.'?remote=' . $remote . '&project=' . $project_data['name'] . '"><i class="fas fa-chart-bar fa-sm fa-fw mr-2 text-gray-900"></i><strong>' . htmlentities($project_data['name']) . '</strong></a>';
|
||||
echo '<option value="' . $return_url . '?remote=' . $remote . '&project=' . $project_data['name'] . '" selected>' . htmlentities($project_data['name']) . '</option>';
|
||||
else {
|
||||
if (basename($return_url) == "instance.html")
|
||||
echo '<a class="dropdown-item" href="instances.html?remote=' . $remote . '&project=' . $project_data['name'] . '"><i class="fas fa-chart-bar fa-sm fa-fw mr-2 text-gray-600"></i>' . htmlentities($project_data['name']) . '</a>';
|
||||
elseif (basename($return_url) == "storage-volumes.html")
|
||||
echo '<a class="dropdown-item" href="storage-pools.html?remote=' . $remote . '&project=' . $project_data['name'] . '"><i class="fas fa-chart-bar fa-sm fa-fw mr-2 text-gray-600"></i>' . htmlentities($project_data['name']) . '</a>';
|
||||
if (basename($return_url) == "virtual-machines-single.php")
|
||||
echo '<option value="virtual-machines.php?remote=' . $remote . '&project=' . $project_data['name'] . '" >' . htmlentities($project_data['name']) . '</option>';
|
||||
elseif (basename($return_url) == "containers-single.php")
|
||||
echo '<option value="containers.php?remote=' . $remote . '&project=' . $project_data['name'] . '" >' . htmlentities($project_data['name']) . '</option>';
|
||||
elseif (basename($return_url) == "network-acls-egress.php" || basename($return_url) == "network-acls-ingress.php")
|
||||
echo '<option value="network-acls.php?remote=' . $remote . '&project=' . $project_data['name'] . '" >' . htmlentities($project_data['name']) . '</option>';
|
||||
elseif (basename($return_url) == "storage-volumes.php")
|
||||
echo '<option value="storage-pools.php?remote=' . $remote . '&project=' . $project_data['name'] . '" >' . htmlentities($project_data['name']) . '</option>';
|
||||
else
|
||||
echo '<a class="dropdown-item" href="'.$return_url.'?remote=' . $remote . '&project=' . $project_data['name'] . '"><i class="fas fa-chart-bar fa-sm fa-fw mr-2 text-gray-600"></i>' . htmlentities($project_data['name']) . '</a>';
|
||||
echo '<option value="'.$return_url.'?remote=' . $remote . '&project=' . $project_data['name'] . '" >' . htmlentities($project_data['name']) . '</option>';
|
||||
}
|
||||
}
|
||||
|
||||
echo '</div>';
|
||||
break;
|
||||
|
||||
case "loadProject":
|
|
@ -28,7 +28,7 @@ if (isset($_SESSION['username'])) {
|
|||
//Declare and instantiate GET variables
|
||||
$remote = (isset($_GET['remote'])) ? filter_var(urldecode($_GET['remote']), FILTER_SANITIZE_NUMBER_INT) : "";
|
||||
|
||||
//Require code from lxd-dashboard/php/config/db.php
|
||||
//Require code from lxd-dashboard/backend/config/db.php
|
||||
require_once('../config/db.php');
|
||||
|
||||
$alias = retrieveHostAlias($remote);
|
|
@ -30,10 +30,10 @@ if (isset($_SESSION['username'])) {
|
|||
$project = (isset($_GET['project'])) ? filter_var(urldecode($_GET['project']), FILTER_SANITIZE_STRING) : "";
|
||||
$remote = (isset($_GET['remote'])) ? filter_var(urldecode($_GET['remote']), FILTER_SANITIZE_NUMBER_INT) : "";
|
||||
|
||||
//Require code from lxd-dashboard/php/config/curl.php
|
||||
//Require code from lxd-dashboard/backend/config/curl.php
|
||||
require_once('../config/curl.php');
|
||||
|
||||
//Require code from lxd-dashboard/php/config/db.php
|
||||
//Require code from lxd-dashboard/backend/config/db.php
|
||||
require_once('../config/db.php');
|
||||
|
||||
//Query database for remote host record
|
||||
|
@ -83,6 +83,31 @@ if (isset($_SESSION['username'])) {
|
|||
echo json_encode($arr);
|
||||
break;
|
||||
|
||||
case "displayContainerInfo":
|
||||
$arr = array();
|
||||
|
||||
//Instance Stats
|
||||
$url = $base_url. "/1.0/containers?recursion=2&project=" . $project;
|
||||
$instance_api_data = sendCurlRequest($action, "GET", $url);
|
||||
$instance_api_data = json_decode($instance_api_data, true);
|
||||
$instances = (isset($instance_api_data['metadata'])) ? $instance_api_data['metadata'] : [];
|
||||
|
||||
$running_instances = 0;
|
||||
$total_instances = 0;
|
||||
|
||||
foreach ($instances as $instance){
|
||||
if ($instance['state']['status'] == "Running"){
|
||||
$running_instances++;
|
||||
}
|
||||
$total_instances++;
|
||||
}
|
||||
|
||||
$arr['runningContainers'] = $running_instances;
|
||||
$arr['totalContainers'] = $total_instances;
|
||||
|
||||
echo json_encode($arr);
|
||||
break;
|
||||
|
||||
case "displayImageInfo":
|
||||
$arr = array();
|
||||
|
||||
|
@ -242,14 +267,14 @@ if (isset($_SESSION['username'])) {
|
|||
|
||||
//Format memory values
|
||||
if ($memory_total < 1073741824) {
|
||||
$memory_total = number_format($memory_total/1024/1024, 2); //total amount of memory available in MB
|
||||
$memory_used = number_format($memory_used/1024/1024, 2); //current amount of memory used in MB
|
||||
$memory_unit = "MB";
|
||||
$memory_total = number_format($memory_total/1024/1024, 2); //total amount of memory available in MiB
|
||||
$memory_used = number_format($memory_used/1024/1024, 2); //current amount of memory used in MiB
|
||||
$memory_unit = "MiB";
|
||||
}
|
||||
else {
|
||||
$memory_total = number_format($memory_total/1024/1024/1024, 2); //total amount of memory available in GB
|
||||
$memory_used = number_format($memory_used/1024/1024/1024, 2); //current amount of memory used in GB
|
||||
$memory_unit = "GB";
|
||||
$memory_total = number_format($memory_total/1024/1024/1024, 2); //total amount of memory available in GiB
|
||||
$memory_used = number_format($memory_used/1024/1024/1024, 2); //current amount of memory used in GiB
|
||||
$memory_unit = "GiB";
|
||||
}
|
||||
|
||||
$arr['memoryTotal'] = $memory_total;
|
||||
|
@ -258,7 +283,36 @@ if (isset($_SESSION['username'])) {
|
|||
echo json_encode($arr);
|
||||
break;
|
||||
|
||||
case "displayVirtualMachineInfo":
|
||||
$arr = array();
|
||||
|
||||
//Instance Stats
|
||||
$url = $base_url. "/1.0/virtual-machines?recursion=2&project=" . $project;
|
||||
$instance_api_data = sendCurlRequest($action, "GET", $url);
|
||||
$instance_api_data = json_decode($instance_api_data, true);
|
||||
$instances = (isset($instance_api_data['metadata'])) ? $instance_api_data['metadata'] : [];
|
||||
|
||||
$running_instances = 0;
|
||||
$total_instances = 0;
|
||||
|
||||
foreach ($instances as $instance){
|
||||
if ($instance['state']['status'] == "Running"){
|
||||
$running_instances++;
|
||||
}
|
||||
$total_instances++;
|
||||
}
|
||||
|
||||
$arr['runningVirtualMachines'] = $running_instances;
|
||||
$arr['totalVirtualMachines'] = $total_instances;
|
||||
|
||||
echo json_encode($arr);
|
||||
break;
|
||||
|
||||
case "validateRemoteConnection":
|
||||
$url = $base_url. "/1.0";
|
||||
$results = sendCurlRequest($action, "GET", $url);
|
||||
echo $results;
|
||||
break;
|
||||
|
||||
}
|
||||
|
|
@ -28,19 +28,22 @@ if (isset($_SESSION['username'])) {
|
|||
//Declare and instantiate GET variables
|
||||
$action = (isset($_GET['action'])) ? filter_var(urldecode($_GET['action']), FILTER_SANITIZE_STRING) : "";
|
||||
$alias = (isset($_GET['alias'])) ? filter_var(urldecode($_GET['alias']), FILTER_SANITIZE_STRING) : "";
|
||||
$external_host = (isset($_GET['external_host'])) ? filter_var(urldecode($_GET['external_host']), FILTER_SANITIZE_STRING) : "";
|
||||
$external_port = (isset($_GET['external_port'])) ? filter_var(urldecode($_GET['external_port']), FILTER_SANITIZE_NUMBER_INT) : "";
|
||||
$host = (isset($_GET['host'])) ? filter_var(urldecode($_GET['host']), FILTER_SANITIZE_STRING) : "";
|
||||
$id = (isset($_GET['id'])) ? filter_var(urldecode($_GET['id']), FILTER_SANITIZE_NUMBER_INT) : "";
|
||||
$port = (isset($_GET['port'])) ? filter_var(urldecode($_GET['port']), FILTER_SANITIZE_NUMBER_INT) : "8443";
|
||||
$project = (isset($_GET['project'])) ? filter_var(urldecode($_GET['project']), FILTER_SANITIZE_STRING) : "";
|
||||
$remote = (isset($_GET['remote'])) ? filter_var(urldecode($_GET['remote']), FILTER_SANITIZE_NUMBER_INT) : "";
|
||||
|
||||
|
||||
//Require code from lxd-dashboard/php/config/curl.php
|
||||
//Require code from lxd-dashboard/backend/config/curl.php
|
||||
require_once('../config/curl.php');
|
||||
|
||||
//Require code from lxd-dashboard/php/config/db.php
|
||||
//Require code from lxd-dashboard/backend/config/db.php
|
||||
require_once('../config/db.php');
|
||||
|
||||
//Require code from lxd-dashboard/php/aaa/accounting.php
|
||||
//Require code from lxd-dashboard/backend/aaa/accounting.php
|
||||
require_once('../aaa/accounting.php');
|
||||
|
||||
//Run the matching action
|
||||
|
@ -63,8 +66,7 @@ if (isset($_SESSION['username'])) {
|
|||
$data_auth = (isset($data['metadata']['auth'])) ? $data['metadata']['auth'] : "";
|
||||
|
||||
if ($data_auth == "trusted"){
|
||||
|
||||
$record_added = addHost($host, $port, $alias);
|
||||
$record_added = addHost($host, $port, $alias, $external_host, $external_port);
|
||||
|
||||
if ($record_added)
|
||||
$results = '{"status": "Ok", "status_code": 200, "metadata": {"status": "Record added"}}';
|
||||
|
@ -121,6 +123,12 @@ if (isset($_SESSION['username'])) {
|
|||
logEvent($action, $remote, $project, $object, $event['status_code'], $event['status']);
|
||||
break;
|
||||
|
||||
case "retrieveRemoteInfo":
|
||||
$results = retrieveHostInfo($id);
|
||||
$results = json_encode($results);
|
||||
echo $results;
|
||||
break;
|
||||
|
||||
case "listRemotes":
|
||||
if (validateAuthorization($action)) {
|
||||
$rows = retrieveTableRows('lxd_hosts');
|
||||
|
@ -138,19 +146,31 @@ if (isset($_SESSION['username'])) {
|
|||
echo "[ ";
|
||||
|
||||
echo '"';
|
||||
echo "<a href='remotes-single.html?remote=" . $row['id'] . "&project=default'> <i class='fas fa-server fa-lg' style='color:#4e73df'></i> </a>";
|
||||
echo "<a href='remotes-single.php?remote=" . $row['id'] . "&project=default'> <i class='fas fa-server fa-lg' style='color:#4e73df'></i> </a>";
|
||||
echo '",';
|
||||
|
||||
echo '"';
|
||||
echo "<a href='remotes-single.html?remote=" . $row['id'] . "&project=default'>".htmlentities($row['host'])."</a>";
|
||||
echo "<a href='remotes-single.php?remote=" . $row['id'] . "&project=default'>".htmlentities($row['host'])."</a>";
|
||||
echo '",';
|
||||
|
||||
echo '"' . htmlentities($row['port']) . '",';
|
||||
echo '"' . htmlentities($row['alias']) . '",';
|
||||
echo '"' . htmlentities($row['external_host']) . '",';
|
||||
|
||||
// 0 is a valid interger value for the database but a reserved unusable port for TCP/UDP
|
||||
if ($row['external_port'] == 0) {
|
||||
echo '"",';
|
||||
}
|
||||
else {
|
||||
echo '"' . htmlentities($row['external_port']) . '",';
|
||||
}
|
||||
|
||||
echo '"' . htmlentities($row['protocol']) . '",';
|
||||
|
||||
echo '"';
|
||||
echo "<a href='#' onclick=deleteRemote('".$row['id']."')><i class='fas fa-trash-alt fa-lg' style='color:#ddd' title='Delete' aria-hidden='true'></i></a>";
|
||||
echo "<a href='#' onclick=editRemote('".$row['id']."')><i class='fas fa-edit fa-lg' style='color:#ddd' title='Edit' aria-hidden='true'></i></a>";
|
||||
echo "   ";
|
||||
echo "<a href='#' onclick=confirmDeleteRemote('".$row['id']."')><i class='fas fa-trash-alt fa-lg' style='color:#ddd' title='Delete' aria-hidden='true'></i></a>";
|
||||
echo '"';
|
||||
|
||||
echo " ]";
|
||||
|
@ -164,7 +184,7 @@ if (isset($_SESSION['username'])) {
|
|||
}
|
||||
break;
|
||||
|
||||
case "listRemotesForTopNavigation":
|
||||
case "listRemotesForSelectOption":
|
||||
if (validateAuthorization($action)) {
|
||||
$alias = retrieveHostAlias($remote);
|
||||
$hostname = retrieveHostName($remote);
|
||||
|
@ -173,34 +193,85 @@ if (isset($_SESSION['username'])) {
|
|||
$display_name = $alias;
|
||||
else
|
||||
$display_name = $hostname;
|
||||
|
||||
echo '<a class="nav-link dropdown-toggle" href="#" id="userDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">';
|
||||
echo '<i class="fas fa-server mr-2 text-gray-600"></i>';
|
||||
echo '<span class="mr-2 d-none d-lg-inline text-gray-600">Host: <font class="text-primary">'. htmlentities($display_name) . '</font></span>';
|
||||
echo '</a>';
|
||||
echo '<!-- Dropdown - User Information -->';
|
||||
echo '<div class="dropdown-menu dropdown-menu-right shadow animated--grow-in" aria-labelledby="userDropdown">';
|
||||
|
||||
|
||||
//Query database for remote host records
|
||||
$rows = retrieveTableRows('lxd_hosts');
|
||||
|
||||
foreach ($rows as $row){
|
||||
|
||||
if ($row['alias'] != "")
|
||||
$display_name2 = $row['alias'];
|
||||
else
|
||||
$display_name2 = $row['host'];
|
||||
|
||||
if ($row['id'] == $remote)
|
||||
echo '<a class="dropdown-item" href="remotes-single.html?remote=' . $row['id'] . '&project=' . $project . '"><i class="fas fa-server fa-sm fa-fw mr-2 text-gray-900"></i><strong>' . htmlentities($display_name2) . '</strong></a>';
|
||||
echo '<option value="remotes-single.php?remote=' . $row['id'] . '&project=' .$project . '" selected>' . htmlentities($display_name2) . '</option>';
|
||||
else
|
||||
echo '<a class="dropdown-item" href="remotes-single.html?remote=' . $row['id'] . '&project=default"><i class="fas fa-server fa-sm fa-fw mr-2 text-gray-600"></i>' . htmlentities($display_name2) . '</a>';
|
||||
|
||||
echo '<option value="remotes-single.php?remote=' . $row['id'] . '&project=' .$project . '">' . htmlentities($display_name2) . '</option>';
|
||||
}
|
||||
echo '</div>';
|
||||
}
|
||||
break;
|
||||
|
||||
case "loadRemote":
|
||||
if (validateAuthorization($action)) {
|
||||
$results = retrieveHostInfo($remote);
|
||||
$results = json_encode($results);
|
||||
echo $results;
|
||||
}
|
||||
break;
|
||||
|
||||
case "updateRemote":
|
||||
if (validateAuthorization($action)) {
|
||||
|
||||
if (filter_var($host, FILTER_VALIDATE_IP) || filter_var($host, FILTER_VALIDATE_DOMAIN))
|
||||
$valid_domain = true;
|
||||
|
||||
if (filter_var($port, FILTER_VALIDATE_INT))
|
||||
$valid_port = true;
|
||||
|
||||
if ($valid_domain && $valid_port){
|
||||
$url = "https://" . $host . ":" . $port . "/1.0";
|
||||
$results = sendCurlRequest($action, "GET", $url);
|
||||
|
||||
$data = json_decode($results, true);
|
||||
$data_auth = (isset($data['metadata']['auth'])) ? $data['metadata']['auth'] : "";
|
||||
|
||||
if ($data_auth == "trusted"){
|
||||
|
||||
$record_updated = updateHost($remote, $host, $port, $alias, $external_host, $external_port);
|
||||
|
||||
if ($record_updated)
|
||||
$results = '{"status": "Ok", "status_code": 200, "metadata": {"status": "Record added"}}';
|
||||
else
|
||||
$results = '{"status": "Bad Request", "status_code": 400, "metadata": {"error": "Error adding record to database"}}';
|
||||
|
||||
}
|
||||
else {
|
||||
if ($data_auth == "untrusted"){
|
||||
$results = '{"status": "Unauthorized", "status_code": 401, "metadata": {"error": "Remote host connection is not trusted"}}';
|
||||
}
|
||||
else {
|
||||
$results = '{"status": "Bad Request", "status_code": 400, "metadata": {"error": "Unable to connect to remote host"}}';
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
$results = '{"status": "Bad Request", "status_code": 400, "metadata": {"error": "Invalid host or port"}}';
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
$results = '{"status": "Forbidden", "status_code": 403, "metadata": {"error": "You are not authorized to execute this action"}}';
|
||||
}
|
||||
|
||||
echo $results;
|
||||
|
||||
//Send event to accounting
|
||||
$event = json_decode($results, true);
|
||||
$object = $host . ":" . $port;
|
||||
logEvent($action, $remote, $project, $object, $event['status_code'], $event['status']);
|
||||
break;
|
||||
|
||||
default:
|
||||
echo '{"status": "Bad Request", "status_code": 400, "metadata": {"err": "Unable to execute action on remote host", "status_code": "400"}}';
|
||||
}
|
30
lxd-dashboard/backend/lxd/scripts/curl-export-file.php
Normal file
|
@ -0,0 +1,30 @@
|
|||
#!/usr/bin/php
|
||||
<?php
|
||||
|
||||
if (!isset($_SERVER['REQUEST_METHOD'])) {
|
||||
//Capture command-line arguments
|
||||
$file = $argv[1];
|
||||
$url = $argv[2];
|
||||
$cert = $argv[3];
|
||||
$key = $argv[4];
|
||||
|
||||
$fp = fopen($file, "w+");
|
||||
|
||||
$ch = curl_init();
|
||||
curl_setopt($ch, CURLOPT_URL, $url);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($ch, CURLOPT_FILE, $fp);
|
||||
curl_setopt($ch, CURLOPT_SSLCERT, $cert);
|
||||
curl_setopt($ch, CURLOPT_SSLKEY, $key);
|
||||
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 3);
|
||||
curl_setopt($ch, CURLOPT_TIMEOUT, 0);
|
||||
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "GET");
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type:application/json'));
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
|
||||
$results = curl_exec($ch);
|
||||
curl_close($ch);
|
||||
fclose($fp);
|
||||
}
|
||||
|
||||
?>
|
|
@ -33,13 +33,13 @@ if (isset($_SESSION['username'])) {
|
|||
$project = (isset($_GET['project'])) ? filter_var(urldecode($_GET['project']), FILTER_SANITIZE_STRING) : "";
|
||||
$remote = (isset($_GET['remote'])) ? filter_var(urldecode($_GET['remote']), FILTER_SANITIZE_NUMBER_INT) : "";
|
||||
|
||||
//Require code from lxd-dashboard/php/config/curl.php
|
||||
//Require code from lxd-dashboard/backend/config/curl.php
|
||||
require_once('../config/curl.php');
|
||||
|
||||
//Require code from lxd-dashboard/php/config/db.php
|
||||
//Require code from lxd-dashboard/backend/config/db.php
|
||||
require_once('../config/db.php');
|
||||
|
||||
//Require code from lxd-dashboard/php/aaa/accounting.php
|
||||
//Require code from lxd-dashboard/backend/aaa/accounting.php
|
||||
require_once('../aaa/accounting.php');
|
||||
|
||||
//Run the matching action
|
|
@ -69,13 +69,13 @@ if (isset($_SESSION['username'])) {
|
|||
//Declare and instantiate POST variables
|
||||
$json = (isset($_POST['json'])) ? $_POST['json'] : "";
|
||||
|
||||
//Require code from lxd-dashboard/php/config/curl.php
|
||||
//Require code from lxd-dashboard/backend/config/curl.php
|
||||
require_once('../config/curl.php');
|
||||
|
||||
//Require code from lxd-dashboard/php/config/db.php
|
||||
//Require code from lxd-dashboard/backend/config/db.php
|
||||
require_once('../config/db.php');
|
||||
|
||||
//Require code from lxd-dashboard/php/aaa/accounting.php
|
||||
//Require code from lxd-dashboard/backend/aaa/accounting.php
|
||||
require_once('../aaa/accounting.php');
|
||||
|
||||
//Query database for remote host record
|
||||
|
@ -325,9 +325,70 @@ if (isset($_SESSION['username'])) {
|
|||
break;
|
||||
|
||||
case "createStoragePoolUsingJSON":
|
||||
$url = $base_url . "/1.0/storage-pools?project=" . $project;
|
||||
$data = $json;
|
||||
$results = sendCurlRequest($action, "POST", $url, $data);
|
||||
|
||||
//Check to see if host is part of a cluster. Clusted hosts need storage pool created first on each of the hosts
|
||||
$url = $base_url . "/1.0/cluster";
|
||||
$remote_data = sendCurlRequest($action, "GET", $url);
|
||||
$remote_data = json_decode($remote_data, true);
|
||||
$cluster_status = $remote_data['metadata'];
|
||||
|
||||
if ($cluster_status['enabled'] == true){
|
||||
//Get a list of cluster members
|
||||
$url = $base_url . "/1.0/cluster/members?recursion=1";
|
||||
$cluster_api_data = sendCurlRequest($action, "GET", $url);
|
||||
$cluster_api_data = json_decode($cluster_api_data, true);
|
||||
$cluster_api_data = $cluster_api_data['metadata'];
|
||||
|
||||
//Setup Storage Pool data for REST API
|
||||
$target_json_array = json_decode($json, true);
|
||||
|
||||
//Setup Storage Pool data for REST API
|
||||
$target_device_array = array();
|
||||
$target_device_array['config'] = new ArrayObject();
|
||||
$target_device_array['name'] = $target_json_array['name'];
|
||||
$target_device_array['description'] = $target_json_array['description'];
|
||||
$target_device_array['driver'] = $target_json_array['driver'];
|
||||
if (!empty($target_json_array['config']['source'])){ $target_device_array['config']['source'] = $target_json_array['config']['source'];}
|
||||
|
||||
if ($target_device_array['driver'] == "btrfs"){
|
||||
if (!empty($target_json_array['config']['size'])){ $target_device_array['config']['size'] = $target_json_array['config']['size'];}
|
||||
}
|
||||
|
||||
if ($target_device_array['driver'] == "lvm"){
|
||||
if (!empty($target_json_array['config']['size'])){ $target_device_array['config']['size'] = $target_json_array['config']['size'];}
|
||||
}
|
||||
|
||||
if ($target_device_array['driver'] == "zfs"){
|
||||
if (!empty($target_json_array['config']['size'])){ $target_device_array['config']['size'] = $target_json_array['config']['size'];}
|
||||
if (!empty($target_json_array['config']['zfs.pool_name'])){ $target_device_array['config']['zfs.pool_name'] = $target_json_array['config']['zfs.pool_name'];}
|
||||
}
|
||||
|
||||
$target_data = json_encode($target_device_array);
|
||||
|
||||
//Loop through each cluster member to create the storage pool, this will put the storage volume in pending status
|
||||
foreach ($cluster_api_data as $cluster_data){
|
||||
$url = $base_url . "/1.0/storage-pools?project=" . $project . "&target=".$cluster_data['server_name'];
|
||||
$results = sendCurlRequest($action, "POST", $url, $target_data);
|
||||
}
|
||||
|
||||
//Now lets create the storage pool without target config options, moving the pending status to created
|
||||
$url = $base_url . "/1.0/storage-pools?project=" . $project;
|
||||
|
||||
//Setup Storage Pool data for REST API
|
||||
$device_array = json_decode($json, true);
|
||||
unset($device_array['config']['source']);
|
||||
unset($device_array['config']['size']);
|
||||
unset($device_array['config']['zfs.pool_name']);
|
||||
|
||||
$data = json_encode($device_array);
|
||||
$results = sendCurlRequest($action, "POST", $url, $data);
|
||||
}
|
||||
else {
|
||||
$url = $base_url . "/1.0/storage-pools?project=" . $project;
|
||||
$data = $json;
|
||||
$results = sendCurlRequest($action, "POST", $url, $data);
|
||||
}
|
||||
|
||||
echo $results;
|
||||
|
||||
//Send event to accounting
|
||||
|
@ -367,39 +428,50 @@ if (isset($_SESSION['username'])) {
|
|||
$i = 0;
|
||||
echo '{ "data": [';
|
||||
|
||||
foreach ($storage_pools as $storage_pool){
|
||||
|
||||
if ($storage_pool['name'] == "")
|
||||
continue;
|
||||
|
||||
if ($i > 0){
|
||||
echo ",";
|
||||
if ($results['status_code'] == "200"){
|
||||
|
||||
foreach ($storage_pools as $storage_pool){
|
||||
|
||||
if ($storage_pool['name'] == "")
|
||||
continue;
|
||||
|
||||
if ($i > 0){
|
||||
echo ",";
|
||||
}
|
||||
$i++;
|
||||
|
||||
echo "[ ";
|
||||
echo '"';
|
||||
echo "<a href='storage-volumes.php?pool=".$storage_pool['name']."&remote=".$remote."&project=".$project."&type=custom'><i class='fas fa-hdd fa-lg' style='color:#4e73df'></i> </a>";
|
||||
echo '",';
|
||||
|
||||
echo '"';
|
||||
echo "<a href='storage-volumes.php?pool=".$storage_pool['name']."&remote=".$remote."&project=".$project."&type=custom'> ".htmlentities($storage_pool['name'])."</a>";
|
||||
echo '",';
|
||||
|
||||
echo '"' . htmlentities($storage_pool['description']) . '",';
|
||||
echo '"' . htmlentities($storage_pool['driver']) . '",';
|
||||
echo '"' . htmlentities($storage_pool['status']) . '",';
|
||||
|
||||
if(isset($storage_pool['config']) && array_key_exists('source', $storage_pool['config']))
|
||||
$storage_pool_source = (isset($storage_pool['config']['source'])) ? $storage_pool['config']['source'] : "N/A";
|
||||
else
|
||||
$storage_pool_source = "N/A";
|
||||
echo '"' . htmlentities($storage_pool_source) . '",';
|
||||
|
||||
$storage_pool_size = (isset($storage_pool['config']['size'])) ? $storage_pool['config']['size'] : "N/A";
|
||||
echo '"' . htmlentities($storage_pool_size) . '",';
|
||||
|
||||
echo '"';
|
||||
echo "<a href='#' onclick=loadStoragePoolJson('".$storage_pool['name']."')><i class='fas fa-edit fa-lg' style='color:#ddd' title='Edit' aria-hidden='true'></i></a>";
|
||||
echo "   ";
|
||||
echo "<a href='#' onclick=deleteStoragePool('".$storage_pool['name']."')><i class='fas fa-trash-alt fa-lg' style='color:#ddd' title='Delete' aria-hidden='true'></i></a>";
|
||||
echo '"';
|
||||
|
||||
echo " ]";
|
||||
|
||||
}
|
||||
$i++;
|
||||
|
||||
echo "[ ";
|
||||
echo '"';
|
||||
echo "<a href='storage-volumes.html?pool=".$storage_pool['name']."&remote=".$remote."&project=".$project."&type=custom'><i class='fas fa-hdd fa-lg' style='color:#4e73df'></i> </a>";
|
||||
echo '",';
|
||||
|
||||
echo '"';
|
||||
echo "<a href='storage-volumes.html?pool=".$storage_pool['name']."&remote=".$remote."&project=".$project."&type=custom'> ".htmlentities($storage_pool['name'])."</a>";
|
||||
echo '",';
|
||||
|
||||
echo '"' . htmlentities($storage_pool['description']) . '",';
|
||||
echo '"' . htmlentities($storage_pool['driver']) . '",';
|
||||
echo '"' . htmlentities($storage_pool['status']) . '",';
|
||||
echo '"' . htmlentities($storage_pool['config']['source']) . '",';
|
||||
echo '"' . htmlentities($storage_pool['config']['size']) . '",';
|
||||
|
||||
echo '"';
|
||||
echo "<a href='#' onclick=loadStoragePoolJson('".$storage_pool['name']."')><i class='fas fa-edit fa-lg' style='color:#ddd' title='Edit' aria-hidden='true'></i></a>";
|
||||
echo "   ";
|
||||
echo "<a href='#' onclick=deleteStoragePool('".$storage_pool['name']."')><i class='fas fa-trash-alt fa-lg' style='color:#ddd' title='Delete' aria-hidden='true'></i></a>";
|
||||
echo '"';
|
||||
|
||||
echo " ]";
|
||||
|
||||
|
||||
}
|
||||
|
||||
echo " ]}";
|
|
@ -50,13 +50,13 @@ if (isset($_SESSION['username'])) {
|
|||
//Declare and instantiate POST variables
|
||||
$json = (isset($_POST['json'])) ? $_POST['json'] : "";
|
||||
|
||||
//Require code from lxd-dashboard/php/config/curl.php
|
||||
//Require code from lxd-dashboard/backend/config/curl.php
|
||||
require_once('../config/curl.php');
|
||||
|
||||
//Require code from lxd-dashboard/php/config/db.php
|
||||
//Require code from lxd-dashboard/backend/config/db.php
|
||||
require_once('../config/db.php');
|
||||
|
||||
//Require code from lxd-dashboard/php/aaa/accounting.php
|
||||
//Require code from lxd-dashboard/backend/aaa/accounting.php
|
||||
require_once('../aaa/accounting.php');
|
||||
|
||||
//Query database for remote host record
|
||||
|
@ -144,42 +144,46 @@ if (isset($_SESSION['username'])) {
|
|||
$i = 0;
|
||||
echo '{ "data": [';
|
||||
|
||||
foreach ($storage_volumes as $storage_volume){
|
||||
|
||||
if ($type == "custom" && $storage_volume['type'] != $type)
|
||||
continue;
|
||||
if ($results['status_code'] == "200"){
|
||||
|
||||
foreach ($storage_volumes as $storage_volume){
|
||||
|
||||
if ($type == "custom" && $storage_volume['type'] != $type)
|
||||
continue;
|
||||
|
||||
if ($i > 0){
|
||||
echo ",";
|
||||
}
|
||||
$i++;
|
||||
|
||||
echo "[ ";
|
||||
echo '"';
|
||||
echo "<i class='fas fa-hdd fa-lg' style='color:#4e73df'></i>";
|
||||
echo '",';
|
||||
echo '"' . htmlentities($storage_volume['name']) . '",';
|
||||
echo '"' . htmlentities($storage_volume['type']) . '",';
|
||||
echo '"' . htmlentities($storage_volume['location']) . '",';
|
||||
echo '"' . htmlentities($storage_volume['content_type']) . '",';
|
||||
|
||||
echo '"';
|
||||
$ii = 0;
|
||||
foreach ($storage_volume['used_by'] as $item){
|
||||
if ($ii >= 1)
|
||||
echo ", ";
|
||||
$ii++;
|
||||
echo htmlentities($item);
|
||||
}
|
||||
echo '",';
|
||||
|
||||
echo '"';
|
||||
echo "<a href='#' onclick=loadStorageVolumeJson('".$storage_volume['type']."/".$storage_volume['name']."')><i class='fas fa-edit fa-lg' style='color:#ddd' title='Edit' aria-hidden='true'></i></a>";
|
||||
echo "   ";
|
||||
echo "<a href='#' onclick=deleteStorageVolume('".$storage_volume['type']."/".$storage_volume['name']."')><i class='fas fa-trash-alt fa-lg' style='color:#ddd' title='Delete' aria-hidden='true'></i></a>";
|
||||
echo '"';
|
||||
|
||||
echo " ]";
|
||||
|
||||
if ($i > 0){
|
||||
echo ",";
|
||||
}
|
||||
$i++;
|
||||
|
||||
echo "[ ";
|
||||
echo '"';
|
||||
echo "<i class='fas fa-hdd fa-lg' style='color:#4e73df'></i>";
|
||||
echo '",';
|
||||
echo '"' . htmlentities($storage_volume['name']) . '",';
|
||||
echo '"' . htmlentities($storage_volume['type']) . '",';
|
||||
echo '"' . htmlentities($storage_volume['location']) . '",';
|
||||
echo '"' . htmlentities($storage_volume['content_type']) . '",';
|
||||
|
||||
echo '"';
|
||||
$ii = 0;
|
||||
foreach ($storage_volume['used_by'] as $item){
|
||||
if ($ii >= 1)
|
||||
echo ", ";
|
||||
$ii++;
|
||||
echo htmlentities($item);
|
||||
}
|
||||
echo '",';
|
||||
|
||||
echo '"';
|
||||
echo "<a href='#' onclick=loadStorageVolumeJson('".$storage_volume['type']."/".$storage_volume['name']."')><i class='fas fa-edit fa-lg' style='color:#ddd' title='Edit' aria-hidden='true'></i></a>";
|
||||
echo "   ";
|
||||
echo "<a href='#' onclick=deleteStorageVolume('".$storage_volume['type']."/".$storage_volume['name']."')><i class='fas fa-trash-alt fa-lg' style='color:#ddd' title='Delete' aria-hidden='true'></i></a>";
|
||||
echo '"';
|
||||
|
||||
echo " ]";
|
||||
|
||||
}
|
||||
|
|
@ -47,16 +47,40 @@ if (isset($_SESSION['username'])) {
|
|||
$optimized_storage = (isset($_GET['optimized_storage'])) ? filter_var(urldecode($_GET['optimized_storage']), FILTER_SANITIZE_STRING) : "";
|
||||
$compression_algorithm = (isset($_GET['compression_algorithm'])) ? filter_var(urldecode($_GET['compression_algorithm']), FILTER_SANITIZE_STRING) : "";
|
||||
|
||||
$boot_autostart = (isset($_GET['boot_autostart'])) ? filter_var(urldecode($_GET['boot_autostart']), FILTER_SANITIZE_STRING) : "";
|
||||
$boot_autostart_delay = (isset($_GET['boot_autostart_delay'])) ? filter_var(urldecode($_GET['boot_autostart_delay']), FILTER_SANITIZE_STRING) : "";
|
||||
$boot_autostart_priority = (isset($_GET['boot_autostart_priority'])) ? filter_var(urldecode($_GET['boot_autostart_priority']), FILTER_SANITIZE_STRING) : "";
|
||||
$boot_host_shutdown_timeout = (isset($_GET['boot_host_shutdown_timeout'])) ? filter_var(urldecode($_GET['boot_host_shutdown_timeout']), FILTER_SANITIZE_STRING) : "";
|
||||
$boot_stop_priority = (isset($_GET['boot_stop_priority'])) ? filter_var(urldecode($_GET['boot_stop_priority']), FILTER_SANITIZE_STRING) : "";
|
||||
$cluster_evacuate = (isset($_GET['cluster_evacuate'])) ? filter_var(urldecode($_GET['cluster_evacuate']), FILTER_SANITIZE_STRING) : "";
|
||||
$limits_cpu = (isset($_GET['limits_cpu'])) ? filter_var(urldecode($_GET['limits_cpu']), FILTER_SANITIZE_STRING) : "";
|
||||
$limits_disk_priority = (isset($_GET['limits_disk_priority'])) ? filter_var(urldecode($_GET['limits_disk_priority']), FILTER_SANITIZE_STRING) : "";
|
||||
$limits_memory = (isset($_GET['limits_memory'])) ? filter_var(urldecode($_GET['limits_memory']), FILTER_SANITIZE_STRING) : "";
|
||||
$limits_memory_hugepages = (isset($_GET['limits_memory_hugepages'])) ? filter_var(urldecode($_GET['limits_memory_hugepages']), FILTER_SANITIZE_STRING) : "";
|
||||
$limits_network_priority = (isset($_GET['limits_network_priority'])) ? filter_var(urldecode($_GET['limits_network_priority']), FILTER_SANITIZE_STRING) : "";
|
||||
$migration_stateful = (isset($_GET['migration_stateful'])) ? filter_var(urldecode($_GET['migration_stateful']), FILTER_SANITIZE_STRING) : "";
|
||||
$raw_apparmor = (isset($_GET['raw_apparmor'])) ? filter_var(urldecode($_GET['raw_apparmor']), FILTER_SANITIZE_STRING) : "";
|
||||
$raw_qemu = (isset($_GET['raw_qemu'])) ? filter_var(urldecode($_GET['raw_qemu']), FILTER_SANITIZE_STRING) : "";
|
||||
$raw_qemu_conf = (isset($_GET['raw_qemu_conf'])) ? filter_var(urldecode($_GET['raw_qemu_conf']), FILTER_SANITIZE_STRING) : "";
|
||||
$security_devlxd = (isset($_GET['security_devlxd'])) ? filter_var(urldecode($_GET['security_devlxd']), FILTER_SANITIZE_STRING) : "";
|
||||
$security_protection_delete = (isset($_GET['security_protection_delete'])) ? filter_var(urldecode($_GET['security_protection_delete']), FILTER_SANITIZE_STRING) : "";
|
||||
$security_secureboot = (isset($_GET['security_secureboot'])) ? filter_var(urldecode($_GET['security_secureboot']), FILTER_SANITIZE_STRING) : "";
|
||||
$snapshots_schedule = (isset($_GET['snapshots_schedule'])) ? filter_var(urldecode($_GET['snapshots_schedule']), FILTER_SANITIZE_STRING) : "";
|
||||
$snapshots_schedule_stopped = (isset($_GET['snapshots_schedule_stopped'])) ? filter_var(urldecode($_GET['snapshots_schedule_stopped']), FILTER_SANITIZE_STRING) : "";
|
||||
$snapshots_pattern = (isset($_GET['snapshots_pattern'])) ? filter_var(urldecode($_GET['snapshots_pattern']), FILTER_SANITIZE_STRING) : "";
|
||||
$snapshots_expiry = (isset($_GET['snapshots_expiry'])) ? filter_var(urldecode($_GET['snapshots_expiry']), FILTER_SANITIZE_STRING) : "";
|
||||
|
||||
|
||||
//Declare and instantiate POST variables
|
||||
$json = (isset($_POST['json'])) ? $_POST['json'] : "";
|
||||
|
||||
//Require code from lxd-dashboard/php/config/curl.php
|
||||
//Require code from lxd-dashboard/backend/config/curl.php
|
||||
require_once('../config/curl.php');
|
||||
|
||||
//Require code from lxd-dashboard/php/config/db.php
|
||||
//Require code from lxd-dashboard/backend/config/db.php
|
||||
require_once('../config/db.php');
|
||||
|
||||
//Require code from lxd-dashboard/php/aaa/accounting.php
|
||||
//Require code from lxd-dashboard/backend/aaa/accounting.php
|
||||
require_once('../aaa/accounting.php');
|
||||
|
||||
//Query database for remote host record
|
||||
|
@ -69,9 +93,10 @@ if (isset($_SESSION['username'])) {
|
|||
$url = $base_url . "/1.0/instances/" . $instance . "?project=" . $project;
|
||||
$results = sendCurlRequest($action, "GET", $url);
|
||||
$data = json_decode($results, true);
|
||||
$description = $data['metadata']['description'];
|
||||
$data = $data['metadata']['profiles'];
|
||||
array_push($data, $name);
|
||||
$data = '{"profiles":' . json_encode($data) . '}';
|
||||
$data = '{"description":"'.$description.'", "profiles":' . json_encode($data) . '}';
|
||||
$results = sendCurlRequest($action, "PATCH", $url, $data);
|
||||
echo $results;
|
||||
|
||||
|
@ -199,14 +224,52 @@ if (isset($_SESSION['username'])) {
|
|||
else {
|
||||
$url = $base_url . "/1.0/instances?target=" . $location . "&project=" . $project;
|
||||
}
|
||||
//If fingerprint == none create an empty instance
|
||||
if ($fingerprint == "none") {
|
||||
$data = '{"name":"' . $name . '", "profiles": ["'. $profile . '"], "type": "' . $type . '", "instance_type": "' . $instance_type . '", "source": {"type": "none"} }';
|
||||
|
||||
$instance_array = array();
|
||||
|
||||
$instance_array['name'] = $name;
|
||||
$instance_array['description'] = $description;
|
||||
$instance_array['profiles'] = array();
|
||||
array_push($instance_array['profiles'], $profile);
|
||||
$instance_array['type'] = "virtual-machine";
|
||||
$instance_array['instance_type'] = $instance_type;
|
||||
|
||||
if ($fingerprint == "none"){
|
||||
$instance_array['source']['type'] = "none";
|
||||
}
|
||||
else {
|
||||
$data = '{"name":"' . $name . '", "profiles": ["'. $profile . '"], "type": "' . $type . '", "instance_type": "' . $instance_type . '", "source": {"type": "image", "fingerprint": "' . $fingerprint . '"} }';
|
||||
$instance_array['source']['type'] = "image";
|
||||
$instance_array['source']['fingerprint'] = $fingerprint;
|
||||
}
|
||||
|
||||
$instance_array['config'] = new ArrayObject();
|
||||
|
||||
if (!empty($boot_autostart)){ $instance_array['config']['boot.autostart'] = $boot_autostart;}
|
||||
if (!empty($boot_autostart_delay)){ $instance_array['config']['boot.autostart.delay'] = $boot_autostart_delay;}
|
||||
if (!empty($boot_autostart_priority)){ $instance_array['config']['boot.autostart.priority'] = $boot_autostart_priority;}
|
||||
if (!empty($boot_host_shutdown_timeout)){ $instance_array['config']['boot.host_shutdown_timeout'] = $boot_host_shutdown_timeout;}
|
||||
if (!empty($boot_stop_priority)){ $instance_array['config']['boot.stop.priority'] = $boot_stop_priority;}
|
||||
if (!empty($cluster_evacuate)){ $instance_array['config']['cluster.evacuate'] = $cluster_evacuate;}
|
||||
if (!empty($limits_cpu)){ $instance_array['config']['limits.cpu'] = $limits_cpu;}
|
||||
if (!empty($limits_disk_priority)){ $instance_array['config']['limits.disk.priority'] = $limits_disk_priority;}
|
||||
if (!empty($limits_memory)){ $instance_array['config']['limits.memory'] = $limits_memory;}
|
||||
if (!empty($limits_memory_hugepages)){ $instance_array['config']['limits.memory.hugepages'] = $limits_memory_hugepages;}
|
||||
if (!empty($limits_network_priority)){ $instance_array['config']['limits.network.priority'] = $limits_network_priority;}
|
||||
if (!empty($migration_stateful)){ $instance_array['config']['migration.stateful'] = $migration_stateful;}
|
||||
if (!empty($raw_apparmor)){ $instance_array['config']['raw.apparmor'] = $raw_apparmor;}
|
||||
if (!empty($raw_qemu)){ $instance_array['config']['raw.qemu'] = $raw_qemu;}
|
||||
if (!empty($raw_qemu_conf)){ $instance_array['config']['raw.qemu.conf'] = $raw_qemu_conf;}
|
||||
if (!empty($security_devlxd)){ $instance_array['config']['security.devlxd'] = $security_devlxd;}
|
||||
if (!empty($security_protection_delete)){ $instance_array['config']['security.protection.delete'] = $security_protection_delete;}
|
||||
if (!empty($security_secureboot)){ $instance_array['config']['security.secureboot'] = $security_secureboot;}
|
||||
if (!empty($snapshots_schedule)){ $instance_array['config']['snapshots.schedule'] = $snapshots_schedule;}
|
||||
if (!empty($snapshots_schedule_stopped)){ $instance_array['config']['snapshots.schedule.stopped'] = $snapshots_schedule_stopped;}
|
||||
if (!empty($snapshots_pattern)){ $instance_array['config']['snapshots.pattern'] = $snapshots_pattern;}
|
||||
if (!empty($snapshots_expiry)){ $instance_array['config']['snapshots.expiry'] = $snapshots_expiry;}
|
||||
|
||||
$data = json_encode($instance_array);
|
||||
$results = sendCurlRequest($action, "POST", $url, $data);
|
||||
|
||||
echo $results;
|
||||
|
||||
//Send event to accounting
|
||||
|
@ -237,7 +300,7 @@ if (isset($_SESSION['username'])) {
|
|||
}
|
||||
break;
|
||||
|
||||
case "deleteInstance":
|
||||
case "deleteInstance":
|
||||
$url = $base_url . "/1.0/instances/" . $instance . "?project=" . $project;
|
||||
$results = sendCurlRequest($action, "DELETE", $url);
|
||||
echo $results;
|
||||
|
@ -308,6 +371,7 @@ if (isset($_SESSION['username'])) {
|
|||
$url = $base_url . "/1.0/instances/" . $instance . "?project=" . $project;
|
||||
$results = sendCurlRequest($action, "GET", $url);
|
||||
$data = json_decode($results, true);
|
||||
$description = $data['metadata']['description'];
|
||||
$data = $data['metadata']['profiles'];
|
||||
$i = 0;
|
||||
foreach ($data as $element){
|
||||
|
@ -316,7 +380,7 @@ if (isset($_SESSION['username'])) {
|
|||
}
|
||||
$i++;
|
||||
}
|
||||
$data = '{"profiles":' . json_encode($data) . '}';
|
||||
$data = '{"description":"'.$description.'", "profiles":' . json_encode($data) . '}';
|
||||
$results = sendCurlRequest($action, "PATCH", $url, $data);
|
||||
echo $results;
|
||||
|
||||
|
@ -380,23 +444,10 @@ if (isset($_SESSION['username'])) {
|
|||
}
|
||||
|
||||
$url = $base_url . "/1.0/instances/" . $instance . "/backups/" . $name . "/export?project=" . $project;
|
||||
$fp = fopen($file, "w+");
|
||||
|
||||
$ch = curl_init();
|
||||
curl_setopt($ch, CURLOPT_URL, $url);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($ch, CURLOPT_FILE, $fp);
|
||||
curl_setopt($ch, CURLOPT_SSLCERT, $cert);
|
||||
curl_setopt($ch, CURLOPT_SSLKEY, $key);
|
||||
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 3);
|
||||
curl_setopt($ch, CURLOPT_TIMEOUT, 5);
|
||||
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "GET");
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type:application/json'));
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
|
||||
$results = curl_exec($ch);
|
||||
curl_close($ch);
|
||||
fclose($fp);
|
||||
//Calling a script to execute the export. This will run in a seperate process so that it doesn't block other PHP requests from completing
|
||||
$results = exec("php ./scripts/curl-export-file.php $file $url $cert $key > /dev/null &");
|
||||
|
||||
if ($results == false){
|
||||
$results = '{"status": "Bad Request", "status_code": 400, "metadata": {"err": "Unable to execute action on remote host", "status_code": "400"}}';
|
||||
}
|
||||
|
@ -436,7 +487,7 @@ if (isset($_SESSION['username'])) {
|
|||
|
||||
case "listInstances":
|
||||
if (validateAuthorization($action)) {
|
||||
$url = $base_url . "/1.0/instances?recursion=2&project=" . $project;
|
||||
$url = $base_url . "/1.0/virtual-machines?recursion=2&project=" . $project;
|
||||
$results = sendCurlRequest($action, "GET", $url);
|
||||
$results = json_decode($results, true);
|
||||
$instance_api_data = (isset($results['metadata'])) ? $results['metadata'] : [];
|
||||
|
@ -444,131 +495,139 @@ if (isset($_SESSION['username'])) {
|
|||
$i = 0;
|
||||
echo '{ "data": [';
|
||||
|
||||
foreach ($instance_api_data as $instance_data){
|
||||
if ($results['status_code'] == "200"){
|
||||
|
||||
if ($instance_data['name'] == "")
|
||||
continue;
|
||||
foreach ($instance_api_data as $instance_data){
|
||||
|
||||
if ($i > 0){
|
||||
echo ",";
|
||||
}
|
||||
$i++;
|
||||
if ($instance_data['name'] == "")
|
||||
continue;
|
||||
|
||||
echo "[ ";
|
||||
if ($instance_data['status'] == "Running"){
|
||||
if ($i > 0){
|
||||
echo ",";
|
||||
}
|
||||
$i++;
|
||||
|
||||
echo "[ ";
|
||||
if ($instance_data['status'] == "Running"){
|
||||
echo '"';
|
||||
echo "<a href='virtual-machines-single.php?instance=".$instance_data['name']."&remote=".$remote."&project=".$project."'><i class='fas fa-cube fa-lg' style='color:#4e73df'></i> </a>";
|
||||
echo '",';
|
||||
|
||||
echo '"';
|
||||
echo "<a href='virtual-machines-single.php?instance=".$instance_data['name']."&remote=".$remote."&project=".$project."'> ".htmlentities($instance_data['name'])."</a>";
|
||||
echo '",';
|
||||
}
|
||||
else {
|
||||
echo '"';
|
||||
echo "<a href='virtual-machines-single.php?instance=".$instance_data['name']."&remote=".$remote."&project=".$project."'><i class='fas fa-cube fa-lg' style='color:#ddd'></i> </a>";
|
||||
echo '",';
|
||||
|
||||
echo '"';
|
||||
echo "<a href='virtual-machines-single.php?instance=".$instance_data['name']."&remote=".$remote."&project=".$project."'> ".htmlentities($instance_data['name'])."</a>";
|
||||
echo '",';
|
||||
}
|
||||
|
||||
echo '"';
|
||||
echo "<a href='instances-single.html?instance=".$instance_data['name']."&remote=".$remote."&project=".$project."'><i class='fas fa-cube fa-lg' style='color:#4e73df'></i> </a>";
|
||||
if (isset($instance_data['config']['image.os']))
|
||||
echo htmlentities($instance_data['config']['image.os']);
|
||||
else
|
||||
echo "";
|
||||
echo '",';
|
||||
|
||||
echo '"' . htmlentities($instance_data['location']) . '",';
|
||||
|
||||
//IPv4
|
||||
echo '"';
|
||||
echo "<a href='instances-single.html?instance=".$instance_data['name']."&remote=".$remote."&project=".$project."'> ".htmlentities($instance_data['name'])."</a>";
|
||||
echo '",';
|
||||
}
|
||||
else {
|
||||
echo '"';
|
||||
echo "<a href='instances-single.html?instance=".$instance_data['name']."&remote=".$remote."&project=".$project."'><i class='fas fa-cube fa-lg' style='color:#ddd'></i> </a>";
|
||||
if (isset($instance_data['state']['network'])){
|
||||
foreach ($instance_data['state']['network'] as $nic => $nic_properties){
|
||||
foreach ($nic_properties['addresses'] as $nic_address){
|
||||
if ($nic_address['family'] == "inet" && $nic_address['scope'] == "global"){
|
||||
echo htmlentities($nic_address['address']) . " (" . htmlentities($nic) . ")<br />";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
echo '",';
|
||||
|
||||
//IPv6
|
||||
echo '"';
|
||||
echo "<a href='instances-single.html?instance=".$instance_data['name']."&remote=".$remote."&project=".$project."'> ".htmlentities($instance_data['name'])."</a>";
|
||||
if (isset($instance_data['state']['network'])){
|
||||
foreach ($instance_data['state']['network'] as $nic => $nic_properties){
|
||||
foreach ($nic_properties['addresses'] as $nic_address){
|
||||
if ($nic_address['family'] == "inet6" && $nic_address['scope'] == "global"){
|
||||
echo htmlentities($nic_address['address']) . " (" . htmlentities($nic) . ")<br />";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
echo '",';
|
||||
|
||||
//Convert the memory usage to an appropriate unit
|
||||
if ($instance_data['state']['memory']['usage'] < 1073741824){
|
||||
$memory = number_format($instance_data['state']['memory']['usage']/1024/1024, 2);
|
||||
$memory_unit = "MiB";
|
||||
}
|
||||
else {
|
||||
$memory = number_format($instance_data['state']['memory']['usage']/1024/1024/1024, 2);
|
||||
$memory_unit = "GiB";
|
||||
}
|
||||
|
||||
echo '"' . htmlentities($memory) . " " . $memory_unit . '",';
|
||||
|
||||
//When first created, the root disk usage is not set for brief second causing a PHP Notice in error log for Undefined index: root
|
||||
if (isset($instance_data['state']['disk']['root']['usage'])){
|
||||
//Convert the storage usage to an approprate unit
|
||||
if ($instance_data['state']['disk']['root']['usage'] < 1073741824){
|
||||
$disk_total = number_format($instance_data['state']['disk']['root']['usage']/1024/1024,2);
|
||||
$disk_unit = "MiB";
|
||||
}
|
||||
if ($instance_data['state']['disk']['root']['usage'] >= 1073741824 && $instance_data['state']['disk']['root']['usage'] < 1099511627776) {
|
||||
$disk_total = number_format($instance_data['state']['disk']['root']['usage']/1024/1024/1024,2);
|
||||
$disk_unit = "GiB";
|
||||
}
|
||||
if ($instance_data['state']['disk']['root']['usage'] >= 1099511627776){
|
||||
$disk_total = number_format($instance_data['state']['disk']['root']['usage']/1024/1024/1024/1024,2);
|
||||
$disk_unit = "TiB";
|
||||
}
|
||||
}
|
||||
else {
|
||||
$disk_total = "N/A";
|
||||
$disk_unit = "";
|
||||
}
|
||||
|
||||
echo '"' . htmlentities($disk_total) . " " . $disk_unit . '",';
|
||||
echo '"' . htmlentities($instance_data['status']) . '",';
|
||||
|
||||
switch ($instance_data['status']) {
|
||||
case "Running":
|
||||
echo '"';
|
||||
echo "<a href='#' onclick=stopInstance('".$instance_data['name']."')> <i class='fas fa-stop fa-lg' style='color:#cdcdcd' title='Stop' aria-hidden='true'></i> </a>";
|
||||
echo "   ";
|
||||
echo "<a href='#'><i class='fas fa-trash-alt fa-lg' style='color:#ededed' title='Delete (disabled)' aria-hidden='true'></i></a>";
|
||||
echo '"';
|
||||
break;
|
||||
case "Frozen":
|
||||
echo '"';
|
||||
echo "<a href='#' onclick=unfreezeInstance('".$instance_data['name']."')> <i class='fas fa-pause fa-lg' style='color:#cdcdcd' title='Unfreeze' aria-hidden='true'></i> </a>";
|
||||
echo "   ";
|
||||
echo "<a href='#'><i class='fas fa-trash-alt fa-lg' style='color:#ededed' title='Delete (disabled)' aria-hidden='true'></i></a>";
|
||||
echo '"';
|
||||
break;
|
||||
case "Stopped":
|
||||
echo '"';
|
||||
echo "<a href='#' onclick=startInstance('".$instance_data['name']."')> <i class='fas fa-play fa-lg' style='color:#cdcdcd' title='Start' aria-hidden='true'></i> </a>";
|
||||
echo "   ";
|
||||
echo "<a href='#' onclick=confirmDeleteInstance('".$instance_data['name']."')><i class='fas fa-trash-alt fa-lg' style='color:#cdcdcd' title='Delete' aria-hidden='true'></i></a>";
|
||||
echo '"';
|
||||
break;
|
||||
default:
|
||||
echo '" "';
|
||||
}
|
||||
|
||||
echo " ]";
|
||||
|
||||
}
|
||||
|
||||
echo '"';
|
||||
if (isset($instance_data['config']['image.os']))
|
||||
echo htmlentities($instance_data['config']['image.os']);
|
||||
else
|
||||
echo "";
|
||||
echo '",';
|
||||
|
||||
echo '"' . htmlentities($instance_data['location']) . '",';
|
||||
|
||||
//IPv4
|
||||
echo '"';
|
||||
if (isset($instance_data['state']['network'])){
|
||||
foreach ($instance_data['state']['network'] as $nic => $nic_properties){
|
||||
foreach ($nic_properties['addresses'] as $nic_address){
|
||||
if ($nic_address['family'] == "inet" && $nic_address['scope'] == "global"){
|
||||
echo htmlentities($nic_address['address']) . " (" . htmlentities($nic) . ")<br />";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
echo '",';
|
||||
|
||||
//IPv6
|
||||
echo '"';
|
||||
if (isset($instance_data['state']['network'])){
|
||||
foreach ($instance_data['state']['network'] as $nic => $nic_properties){
|
||||
foreach ($nic_properties['addresses'] as $nic_address){
|
||||
if ($nic_address['family'] == "inet6" && $nic_address['scope'] == "global"){
|
||||
echo htmlentities($nic_address['address']) . " (" . htmlentities($nic) . ")<br />";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
echo '",';
|
||||
|
||||
echo '"' . htmlentities($instance_data['type']) . '",';
|
||||
|
||||
//Convert the memory usage to an appropriate unit
|
||||
if ($instance_data['state']['memory']['usage'] < 1073741824){
|
||||
$memory = number_format($instance_data['state']['memory']['usage']/1024/1024, 2);
|
||||
$memory_unit = "MB";
|
||||
}
|
||||
else {
|
||||
$memory = number_format($instance_data['state']['memory']['usage']/1024/1024/1024, 2);
|
||||
$memory_unit = "GB";
|
||||
}
|
||||
|
||||
echo '"' . htmlentities($memory) . " " . $memory_unit . '",';
|
||||
|
||||
//When first created, the root disk usage is not set for brief second causing a PHP Notice in error log for Undefined index: root
|
||||
if (isset($instance_data['state']['disk']['root']['usage'])){
|
||||
//Convert the storage usage to an approprate unit
|
||||
if ($instance_data['state']['disk']['root']['usage'] < 1073741824){
|
||||
$disk_total = number_format($instance_data['state']['disk']['root']['usage']/1024/1024,2);
|
||||
$disk_unit = "MB";
|
||||
}
|
||||
if ($instance_data['state']['disk']['root']['usage'] >= 1073741824 && $instance_data['state']['disk']['root']['usage'] < 1099511627776) {
|
||||
$disk_total = number_format($instance_data['state']['disk']['root']['usage']/1024/1024/1024,2);
|
||||
$disk_unit = "GB";
|
||||
}
|
||||
if ($instance_data['state']['disk']['root']['usage'] >= 1099511627776){
|
||||
$disk_total = number_format($instance_data['state']['disk']['root']['usage']/1024/1024/1024/1024,2);
|
||||
$disk_unit = "TB";
|
||||
}
|
||||
}
|
||||
else {
|
||||
$disk_total = 0.00;
|
||||
$disk_unit = "MB";
|
||||
}
|
||||
|
||||
echo '"' . htmlentities($disk_total) . " " . $disk_unit . '",';
|
||||
echo '"' . htmlentities($instance_data['status']) . '",';
|
||||
|
||||
switch ($instance_data['status']) {
|
||||
case "Running":
|
||||
echo '"';
|
||||
echo "<a href='#' onclick=stopInstance('".$instance_data['name']."')> <i class='fas fa-stop fa-lg' style='color:#ddd' title='Stop' aria-hidden='true'></i> </a>";
|
||||
echo '"';
|
||||
break;
|
||||
case "Frozen":
|
||||
echo '"';
|
||||
echo "<a href='#' onclick=unfreezeInstance('".$instance_data['name']."')> <i class='fas fa-pause fa-lg' style='color:#ddd' title='Unfreeze' aria-hidden='true'></i> </a>";
|
||||
echo '"';
|
||||
break;
|
||||
case "Stopped":
|
||||
echo '"';
|
||||
echo "<a href='#' onclick=startInstance('".$instance_data['name']."')> <i class='fas fa-play fa-lg' style='color:#ddd' title='Start' aria-hidden='true'></i> </a>";
|
||||
echo '"';
|
||||
break;
|
||||
default:
|
||||
echo '" "';
|
||||
}
|
||||
|
||||
echo " ]";
|
||||
|
||||
}
|
||||
|
||||
echo " ]}";
|
||||
|
@ -579,7 +638,7 @@ if (isset($_SESSION['username'])) {
|
|||
break;
|
||||
|
||||
case "listInstancesForSelectOption":
|
||||
$url = $base_url . "/1.0/instances?recursion=1&project=" . $project;
|
||||
$url = $base_url . "/1.0/virtual-machines?recursion=1&project=" . $project;
|
||||
$results = sendCurlRequest($action, "GET", $url);
|
||||
$results = json_decode($results, true);
|
||||
$instance_api_data = (isset($results['metadata'])) ? $results['metadata'] : [];
|
||||
|
@ -814,6 +873,73 @@ if (isset($_SESSION['username'])) {
|
|||
}
|
||||
break;
|
||||
|
||||
case "updateInstanceUsingForm":
|
||||
|
||||
$url = $base_url . "/1.0/instances/" . $instance . "?project=" . $project;
|
||||
|
||||
//Retrieve existing instance config settings
|
||||
$results = sendCurlRequest($action, "GET", $url);
|
||||
$existing_array = json_decode($results, true);
|
||||
$existing_array = $existing_array['metadata'];
|
||||
|
||||
//Create array of new config settings
|
||||
$instance_array = array();
|
||||
$instance_array['description'] = $description;
|
||||
$instance_array['config'] = new ArrayObject();
|
||||
|
||||
$instance_array['config']['boot.autostart'] = $boot_autostart;
|
||||
$instance_array['config']['boot.autostart.delay'] = $boot_autostart_delay;
|
||||
$instance_array['config']['boot.autostart.priority'] = $boot_autostart_priority;
|
||||
$instance_array['config']['boot.host_shutdown_timeout'] = $boot_host_shutdown_timeout;
|
||||
$instance_array['config']['boot.stop.priority'] = $boot_stop_priority;
|
||||
$instance_array['config']['cluster.evacuate'] = $cluster_evacuate;
|
||||
$instance_array['config']['limits.cpu'] = $limits_cpu;
|
||||
$instance_array['config']['limits.disk.priority'] = $limits_disk_priority;
|
||||
$instance_array['config']['limits.memory'] = $limits_memory;
|
||||
$instance_array['config']['limits.memory.hugepages'] = $limits_memory_hugepages;
|
||||
$instance_array['config']['limits.network.priority'] = $limits_network_priority;
|
||||
$instance_array['config']['migration.stateful'] = $migration_stateful;
|
||||
$instance_array['config']['raw.apparmor'] = $raw_apparmor;
|
||||
$instance_array['config']['raw.qemu'] = $raw_qemu;
|
||||
$instance_array['config']['raw.qemu.conf'] = $raw_qemu_conf;
|
||||
$instance_array['config']['security.devlxd'] = $security_devlxd;
|
||||
$instance_array['config']['security.protection.delete'] = $security_protection_delete;
|
||||
$instance_array['config']['security.secureboot'] = $security_secureboot;
|
||||
$instance_array['config']['snapshots.schedule'] = $snapshots_schedule;
|
||||
$instance_array['config']['snapshots.schedule.stopped'] = $snapshots_schedule_stopped;
|
||||
$instance_array['config']['snapshots.pattern'] = $snapshots_pattern;
|
||||
$instance_array['config']['snapshots.expiry'] = $snapshots_expiry;
|
||||
|
||||
//Create new array based on changes between existing and new configs
|
||||
$new_array = array();
|
||||
$new_array['description'] = $description;
|
||||
$new_array['config'] = new ArrayObject();
|
||||
|
||||
foreach ($instance_array['config'] as $key => $val) {
|
||||
if (!isset($existing_array['config'][$key])){
|
||||
$existing_array['config'][$key] = "";
|
||||
}
|
||||
if ($instance_array['config'][$key] != $existing_array['config'][$key]){
|
||||
$new_array['config'][$key] = $instance_array['config'][$key];
|
||||
}
|
||||
}
|
||||
|
||||
$data = json_encode($new_array);
|
||||
$results = sendCurlRequest($action, "PATCH", $url, $data);
|
||||
|
||||
echo $results;
|
||||
|
||||
//Send event to accounting
|
||||
$event = json_decode($results, true);
|
||||
$object = $name;
|
||||
if ($event['error_code'] == 0){
|
||||
logEvent($action, $remote, $project, $object, $event['status_code'], $event['status']);
|
||||
}
|
||||
else {
|
||||
logEvent($action, $remote, $project, $object, $event['error_code'], $event['error']);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
$results = '{"status": "Bad Request", "status_code": 400, "metadata": {"err": "Unable to execute action on remote host", "status_code": "400"}}';
|
||||
echo $results;
|
|
@ -37,7 +37,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
|
||||
<!-- Custom styles for this template-->
|
||||
<link href="vendor/sb-admin-2/css/sb-admin-2.css" rel="stylesheet">
|
||||
<link href="assets/css/style.css" rel="stylesheet">
|
||||
<link href="assets/css/style.css?version=3.0" rel="stylesheet">
|
||||
|
||||
<!-- Custom styles for this page -->
|
||||
<link href="vendor/datatables/dataTables.bootstrap4.min.css" rel="stylesheet">
|
||||
|
@ -50,7 +50,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
<div id="wrapper">
|
||||
|
||||
<!-- Sidebar -->
|
||||
<ul class="navbar-nav bg-dark sidebar sidebar-dark accordion" id="accordionSidebar">
|
||||
<ul class="navbar-nav bg-dark sidebar sidebar-dark accordion sidebar-divider-right" id="accordionSidebar">
|
||||
|
||||
<div id="sidebarLinks"></div>
|
||||
|
||||
|
@ -59,12 +59,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
|
||||
<!-- Sidebar Toggler (Sidebar) -->
|
||||
<div class="text-center d-none d-md-inline">
|
||||
<button class="rounded-circle border-0" id="sidebarToggle"></button>
|
||||
<button class="rounded-circle border-0" id="sidebarToggle" onclick="setSidebarToggleValue()"></button>
|
||||
</div>
|
||||
</ul>
|
||||
<!-- End of Sidebar -->
|
||||
|
||||
|
||||
<!-- Content Wrapper -->
|
||||
<div id="content-wrapper" class="d-flex flex-column">
|
||||
|
||||
|
@ -79,36 +78,43 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
<i class="fa fa-bars"></i>
|
||||
</button>
|
||||
|
||||
|
||||
<!-- Topbar Notification -->
|
||||
<div class="d-none d-sm-inline-block form-inline mr-auto ml-md-3 my-2 my-md-0 mw-100 navbar-search">
|
||||
<ul class="navbar-nav ml-auto">
|
||||
|
||||
<li>
|
||||
<div class="nav-item spinner-border m-3" role="status" style="display:none;" id="spinner">
|
||||
<span class="nav-item sr-only">Loading...</span>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li class="nav-item dropdown no-arrow" id="notificationArea" style="display: none;">
|
||||
<div class="nav-link dropdown-toggle">
|
||||
<span id="notification" class="mr-2 d-none d-lg-inline text-gray-600">Notification</span>
|
||||
<span id="notification" class="mr-2 d-none d-lg-inline text-danger">Notification</span>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- Topbar Navbar -->
|
||||
<ul class="navbar-nav ml-auto">
|
||||
|
||||
<li class="nav-item dropdown" id="remoteListNav">
|
||||
<li class="nav-item dropdown">
|
||||
<label class="h6 mt-4 mr-2 ml-4">Host: </label>
|
||||
</li>
|
||||
<li class="nav-item dropdown">
|
||||
<div class="input-group mt-3">
|
||||
<select class="form-control" id="remoteListNav" style="width:150px;" onchange="location = this.value;">
|
||||
</select>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li class="nav-item dropdown" id="projectListNav">
|
||||
<li class="nav-item dropdown">
|
||||
<label class="h6 mt-4 mr-2 ml-4">Project: </label>
|
||||
</li>
|
||||
<li class="nav-item dropdown">
|
||||
<div class="input-group mt-3">
|
||||
<select class="form-control" id="projectListNav" style="width:150px;" onchange="location = this.value;">
|
||||
</select>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<!-- Nav Divider -->
|
||||
<div class="topbar-divider d-none d-sm-block"></div>
|
||||
|
||||
<!-- Nav Item - User Information -->
|
||||
|
@ -119,14 +125,18 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
</a>
|
||||
<!-- Dropdown - User Information -->
|
||||
<div class="dropdown-menu dropdown-menu-right shadow animated--grow-in" aria-labelledby="userDropdown">
|
||||
<a class="dropdown-item" href="user-profile.html">
|
||||
<a class="dropdown-item" href="user-profile.php">
|
||||
<i class="fas fa-user fa-sm fa-fw mr-2 text-gray-400"></i>
|
||||
Profile
|
||||
</a>
|
||||
<a class="dropdown-item" href="settings.html">
|
||||
<a class="dropdown-item" href="settings.php">
|
||||
<i class="fas fa-cog fa-sm fa-fw mr-2 text-gray-400"></i>
|
||||
Settings
|
||||
</a>
|
||||
<a class="dropdown-item" href="logs.php">
|
||||
<i class="fas fa-history fa-sm fa-fw mr-2 text-gray-400"></i>
|
||||
Logs
|
||||
</a>
|
||||
<a class="dropdown-item" href="#" data-toggle="modal" data-target="#aboutModal">
|
||||
<i class="fas fa-info-circle fa-sm fa-fw mr-2 text-gray-400"></i>
|
||||
About
|
||||
|
@ -147,25 +157,48 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
<!-- Begin Page Content -->
|
||||
<div class="container-fluid">
|
||||
|
||||
<!-- BreadCrumb -->
|
||||
<nav aria-label="breadcrumb">
|
||||
<ol class="breadcrumb">
|
||||
<li class="breadcrumb-item"><a href="#" id="remoteBreadCrumb"></a></li>
|
||||
<li class="breadcrumb-item active" aria-current="page" id="certificatesBreadCrumb"></li>
|
||||
</ol>
|
||||
</nav>
|
||||
<header class="page-header page-header-dark bg-gradient-primary-to-secondary">
|
||||
<div class="container-xl px-4">
|
||||
<div class="page-header-content pt-4">
|
||||
<div class="row align-items-center justify-content-between mt-n5 ml-n5 mr-n5 bg-dark pb-6">
|
||||
<div class="col-auto mt-4 ml-3">
|
||||
<div class="page-header-subtitle">
|
||||
<a href="#" id="remoteBreadCrumb"></a>
|
||||
</div>
|
||||
<h2 class="page-header-title mt-2">
|
||||
CERTIFICATES
|
||||
</h2>
|
||||
<div class="page-header-subtitle">
|
||||
Add and manage trusted certificates on the remote host
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-xl-auto mt-4">
|
||||
<div class="input-group input-group-joined border-0" style="width: 14rem">
|
||||
<span class="input-group-text bg-transparent border-0">
|
||||
<a class="btn btn-outline-primary" href="#" data-toggle="modal" data-target="#addCertificateModal" title="New Certificate" aria-hidden="true">
|
||||
<i class="fas fa-plus fa-sm fa-fw"></i> Certificate
|
||||
</a>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<div class="row">
|
||||
<div class="row mt-n5 ml-2 mr-2">
|
||||
|
||||
<div class="col-12">
|
||||
<div class="col-12 mt-n3">
|
||||
<!-- Certificate List -->
|
||||
<div class="card shadow mb-4">
|
||||
<!-- Card Header - Dropdown -->
|
||||
<div class="card-header py-3 d-flex flex-row align-items-center justify-content-between">
|
||||
<h6 class="m-0 font-weight-bold text-primary">Certificates</h6>
|
||||
<h6 class="m-0 font-weight-bold">
|
||||
<span class="ml-1">Certificates</span>
|
||||
</h6>
|
||||
<div class="dropdown no-arrow">
|
||||
<a class="dropdown-toggle mr-2" href="#" data-toggle="modal" data-target="#addCertificateModal" title="New Certificate" aria-hidden="true">
|
||||
<i class="fas fa-plus fa-sm fa-fw"></i> Certificate</a>
|
||||
<a class="dropdown-toggle mr-2" href="#" onclick="reloadPageContent()" title="Refresh" aria-hidden="true">
|
||||
<i class="fa fa-sync fa-1x fa-fw"></i></a>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Card Body -->
|
||||
|
@ -191,7 +224,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
<footer class="sticky-footer bg-white">
|
||||
<div class="container my-auto">
|
||||
<div class="copyright text-center my-auto">
|
||||
<span>Copyright © lxdware.com 2021</span>
|
||||
<span>Copyright © LXDWARE 2020 - Present</span>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
|
@ -210,7 +243,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
|
||||
<!-- Add Certificate Modal-->
|
||||
<div class="modal fade" id="addCertificateModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog modal-lg" role="document">
|
||||
<div class="modal-dialog modal-xl" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="exampleModalLabel">Add Certificate</h5>
|
||||
|
@ -229,25 +262,33 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
</ul>
|
||||
<div class="tab-content" id="myTabContent">
|
||||
<div class="tab-pane fade show active" id="form" role="tabpanel" aria-labelledby="form-tab">
|
||||
<br />
|
||||
<div class="row">
|
||||
<label class="col-2 col-form-label text-right">Name: </label>
|
||||
<div class="col-10">
|
||||
|
||||
<div class="row mt-4">
|
||||
<label class="col-2 col-form-label text-right">Name: <span class="text-danger">*</span> </label>
|
||||
<div class="col-8">
|
||||
<div class="form-group">
|
||||
<input type="text" id="certificateNameCreate" class="form-control" name="certificate_name">
|
||||
<input type="text" id="certificateNameCreate" class="form-control" required="required" placeholder="">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-1">
|
||||
<i class="far fa-sm fa-question-circle" title='Enter in a name for this certificate'></i>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<label class="col-2 col-form-label text-right">Certificate: </label>
|
||||
<div class="col-10">
|
||||
<label class="col-2 col-form-label text-right">Certificate: <span class="text-danger">*</span> </label>
|
||||
<div class="col-8">
|
||||
<div class="form-group">
|
||||
<pre>
|
||||
<textarea id="certificateCreate" class="form-control" name="certificate" rows="14" style="font-size: .9rem;"></textarea>
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-1">
|
||||
<i class="far fa-sm fa-question-circle" title='Paste in certificate contents'></i>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="modal-footer">
|
||||
<button class="btn btn-secondary" type="button" data-dismiss="modal">Cancel</button>
|
||||
<a class="btn btn-primary" href="#" onclick="addCertificateUsingForm()" data-dismiss="modal">Submit</a>
|
||||
|
@ -351,60 +392,66 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
const remoteId = urlParams.get('remote');
|
||||
const projectName = urlParams.get('project');
|
||||
var certificateToUpdate = "";
|
||||
var reloadTime = 5000;
|
||||
|
||||
function logout(){
|
||||
$.get("./php/aaa/authentication.php?action=deauthenticateUser", function (data) {
|
||||
$.get("./backend/aaa/authentication.php?action=deauthenticateUser", function (data) {
|
||||
operationData = JSON.parse(data);
|
||||
console.log(operationData);
|
||||
if (operationData.status_code == 200) {
|
||||
window.location = './index.html'
|
||||
window.location.href = './index.php'
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function operationStatusCheck(){
|
||||
clearTimeout(operationTimeout);
|
||||
//check to see if there are any running operations
|
||||
$.get("./php/lxd/operations.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&action=displayOperationStatus", function (data) {
|
||||
$.get("./backend/lxd/operations.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&action=displayOperationStatus", function (data) {
|
||||
//Check to see if we have running operations
|
||||
if (data){
|
||||
//Display spinner and notification area if there are running tasks
|
||||
$('#spinner').show();
|
||||
if (data) {
|
||||
//Display notification area if there are running tasks
|
||||
$('#notificationArea').show();
|
||||
$('#notification').text(data);
|
||||
//Set the page to check operations again in 1 second
|
||||
setTimeout(() => { operationStatusCheck(); }, 1000);
|
||||
$('#notification').text("Notice: " + data);
|
||||
//Set the page to check operations again in 2 seconds
|
||||
operationTimeout = setTimeout(() => { operationStatusCheck(); }, 2000);
|
||||
}
|
||||
else {
|
||||
//Hide spinner and notification area if no running tasks
|
||||
$('#spinner').hide();
|
||||
//Hide notification area if no running tasks
|
||||
$('#notificationArea').hide();
|
||||
$('#notification').text("");
|
||||
//Set the page to check operations again in 3 seconds
|
||||
setTimeout(() => { operationStatusCheck(); }, 3000);
|
||||
//Set the page to check operations again in 4 seconds
|
||||
operationTimeout = setTimeout(() => { operationStatusCheck(); }, 4000);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function reloadPageContent(){
|
||||
|
||||
clearTimeout(pageReloadTimeout);
|
||||
|
||||
//Check Authorization
|
||||
$.get("./php/aaa/authentication.php?action=validateAuthentication", function (data) {
|
||||
$.get("./backend/aaa/authentication.php?action=validateAuthentication", function (data) {
|
||||
operationData = JSON.parse(data);
|
||||
if (operationData.status_code != 200) {
|
||||
console.log(operationData);
|
||||
window.location = './index.html'
|
||||
window.location.href = './index.php'
|
||||
}
|
||||
});
|
||||
|
||||
$('#certificateListTable').DataTable().ajax.reload(null, false);
|
||||
|
||||
//Set reload page content
|
||||
pageReloadTimeout = setTimeout(() => { reloadPageContent(); }, reloadTime);
|
||||
}
|
||||
|
||||
function loadPageContent(){
|
||||
|
||||
//Display current logged in username
|
||||
$("#username").load("./php/admin/settings.php?action=displayUsername");
|
||||
$("#username").load("./backend/admin/settings.php?action=displayUsername");
|
||||
|
||||
$('#certificateListTable').DataTable( {
|
||||
ajax: "./php/lxd/certificates.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&action=listCertificates",
|
||||
ajax: "./backend/lxd/certificates.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&action=listCertificates",
|
||||
columns: [
|
||||
{},
|
||||
{ title: "Name" },
|
||||
|
@ -419,10 +466,16 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
});
|
||||
|
||||
//Check for any running operations
|
||||
operationStatusCheck();
|
||||
operationTimeout = setTimeout(() => { operationStatusCheck(); }, 1000);
|
||||
|
||||
//Set reload page content
|
||||
$.get("./backend/admin/settings.php?action=retrievePageRefreshRateValues", function (data) {
|
||||
operationData = JSON.parse(data);
|
||||
if (operationData.certificates_page_rate >= 1)
|
||||
reloadTime = operationData.certificates_page_rate * 1000;
|
||||
pageReloadTimeout = setTimeout(() => { reloadPageContent(); }, reloadTime);
|
||||
});
|
||||
|
||||
//Set the page content to reload in 5 seconds
|
||||
setInterval(() => { reloadPageContent(); }, 5000);
|
||||
}
|
||||
|
||||
function addCertificateUsingForm(){
|
||||
|
@ -430,7 +483,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
var certificateCreate = $("#certificateCreate").val();
|
||||
certificateCreate = certificateCreate.replace(/\n|\r/g, "\\n");
|
||||
console.log("Info: adding certificate");
|
||||
$.post("./php/lxd/certificates.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&name=" + encodeURI(certificateNameCreate) + "&action=addCertificateUsingForm", {certificate: certificateCreate}, function (data) {
|
||||
$.post("./backend/lxd/certificates.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&name=" + encodeURI(certificateNameCreate) + "&action=addCertificateUsingForm", {certificate: certificateCreate}, function (data) {
|
||||
//Sync operation type
|
||||
var operationData = JSON.parse(data);
|
||||
console.log(operationData);
|
||||
|
@ -444,7 +497,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
function addCertificateUsingJSON(){
|
||||
var certificateCreateJSON = $("#jsonCreateInput").val();
|
||||
console.log("Info: adding certificate");
|
||||
$.post("./php/lxd/certificates.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&action=addCertificateUsingJSON", {json: certificateCreateJSON}, function (data) {
|
||||
$.post("./backend/lxd/certificates.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&action=addCertificateUsingJSON", {json: certificateCreateJSON}, function (data) {
|
||||
//Sync operation type
|
||||
var operationData = JSON.parse(data);
|
||||
console.log(operationData);
|
||||
|
@ -458,7 +511,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
function loadCertificateJson(certificateToLoad){
|
||||
console.log("Info: locading certificate " + certificateToLoad);
|
||||
certificateToUpdate = certificateToLoad;
|
||||
$.get("./php/lxd/certificates.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&fingerprint=" + encodeURI(certificateToLoad) + "&action=loadCertificate", function (data) {
|
||||
$.get("./backend/lxd/certificates.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&fingerprint=" + encodeURI(certificateToLoad) + "&action=loadCertificate", function (data) {
|
||||
//Sync operation type
|
||||
var operationData = JSON.parse(data);
|
||||
console.log(operationData);
|
||||
|
@ -474,7 +527,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
function updateCertificate(){
|
||||
var certificateUpdateJSON = $("#jsonEditInput").val();
|
||||
console.log("Info: updating certificate " + certificateToUpdate);
|
||||
$.post("./php/lxd/certificates.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&fingerprint=" + encodeURI(certificateToUpdate) + "&action=updateCertificate", {json: certificateUpdateJSON}, function (data) {
|
||||
$.post("./backend/lxd/certificates.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&fingerprint=" + encodeURI(certificateToUpdate) + "&action=updateCertificate", {json: certificateUpdateJSON}, function (data) {
|
||||
//Sync operation type
|
||||
var operationData = JSON.parse(data);
|
||||
console.log(operationData);
|
||||
|
@ -487,7 +540,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
|
||||
function deleteCertificate(certificateToDelete){
|
||||
console.log("Info: deleting certificate " + certificateToDelete);
|
||||
$.get("./php/lxd/certificates.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&fingerprint=" + encodeURI(certificateToDelete) + "&action=deleteCertificate", function (data) {
|
||||
$.get("./backend/lxd/certificates.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&fingerprint=" + encodeURI(certificateToDelete) + "&action=deleteCertificate", function (data) {
|
||||
//Sync operation type
|
||||
var operationData = JSON.parse(data);
|
||||
console.log(operationData);
|
||||
|
@ -498,33 +551,64 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
});
|
||||
}
|
||||
|
||||
function setSidebarToggleValue(){
|
||||
sidebarState = localStorage.getItem('sidebarState');
|
||||
if (sidebarState == "collapsed"){
|
||||
localStorage.setItem('sidebarState','expanded');
|
||||
}
|
||||
else {
|
||||
localStorage.setItem('sidebarState','collapsed');
|
||||
}
|
||||
}
|
||||
|
||||
function applySidebarToggleValue() {
|
||||
sidebarState = localStorage.getItem('sidebarState');
|
||||
if (sidebarState == "collapsed"){
|
||||
$("body").toggleClass("sidebar-toggled"),
|
||||
$(".sidebar").toggleClass("toggled"),
|
||||
$(".sidebar").hasClass("toggled") && $(".sidebar .collapse").collapse("hide")
|
||||
}
|
||||
}
|
||||
|
||||
applySidebarToggleValue();
|
||||
|
||||
$(document).ready(function(){
|
||||
|
||||
//Check Authorization
|
||||
$.get("./php/aaa/authentication.php?action=validateAuthentication", function (data) {
|
||||
$.get("./backend/aaa/authentication.php?action=validateAuthentication", function (data) {
|
||||
operationData = JSON.parse(data);
|
||||
if (operationData.status_code != 200) {
|
||||
console.log(operationData);
|
||||
window.location = './index.html'
|
||||
window.location.href = './index.php'
|
||||
}
|
||||
});
|
||||
|
||||
//Load in the sidebar
|
||||
$("#sidebarLinks").load("./sidebar.html");
|
||||
//Load in the sidebar
|
||||
$("#sidebarLinks").load("./sidebar.php?version=3.0");
|
||||
|
||||
//Setup Page Breadcrumb Links/Information
|
||||
$('#remoteBreadCrumb').load("./php/lxd/remote-breadcrumb.php?remote=" + encodeURI(remoteId));
|
||||
$('#remoteBreadCrumb').attr("href", "remotes-single.html?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName));
|
||||
$('#certificatesBreadCrumb').text("certificates");
|
||||
$('#remoteBreadCrumb').load("./backend/lxd/remote-breadcrumb.php?remote=" + encodeURI(remoteId));
|
||||
$('#remoteBreadCrumb').attr("href", "remotes-single.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName));
|
||||
|
||||
//Load the card contents
|
||||
loadPageContent();
|
||||
//Validate remote host connection returns 200 status
|
||||
$.get("./backend/lxd/remotes-single.php?remote=" + encodeURI(remoteId) + "&action=validateRemoteConnection", function (data) {
|
||||
operationData = JSON.parse(data);
|
||||
console.log(operationData);
|
||||
if (operationData.status_code == 200) {
|
||||
//Set top navbar dropdowns
|
||||
$("#remoteListNav").load("./backend/lxd/remotes.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&action=listRemotesForSelectOption");
|
||||
$("#projectListNav").load("./backend/lxd/projects.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&action=listProjectsForSelectOption");
|
||||
|
||||
$("#remoteListNav").load("./php/lxd/remotes.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&action=listRemotesForTopNavigation");
|
||||
$("#projectListNav").load("./php/lxd/projects.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&action=listProjectsForTopNavigation");
|
||||
//Load Page Content
|
||||
loadPageContent();
|
||||
}
|
||||
else {
|
||||
alert("Unable to connect to remote host. HTTP status code: " + operationData.status_code);
|
||||
}
|
||||
});
|
||||
|
||||
//Load the about info for the about modal
|
||||
$.get("./about.html", function (data) {
|
||||
$.get("./backend/config/about.php", function (data) {
|
||||
$("#about").html(data);
|
||||
});
|
||||
|
|
@ -37,7 +37,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
|
||||
<!-- Custom styles for this template-->
|
||||
<link href="vendor/sb-admin-2/css/sb-admin-2.css" rel="stylesheet">
|
||||
<link href="assets/css/style.css" rel="stylesheet">
|
||||
<link href="assets/css/style.css?version=3.0" rel="stylesheet">
|
||||
|
||||
<!-- Custom styles for this page -->
|
||||
<link href="vendor/datatables/dataTables.bootstrap4.min.css" rel="stylesheet">
|
||||
|
@ -50,7 +50,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
<div id="wrapper">
|
||||
|
||||
<!-- Sidebar -->
|
||||
<ul class="navbar-nav bg-dark sidebar sidebar-dark accordion" id="accordionSidebar">
|
||||
<ul class="navbar-nav bg-dark sidebar sidebar-dark accordion sidebar-divider-right" id="accordionSidebar">
|
||||
|
||||
<div id="sidebarLinks"></div>
|
||||
|
||||
|
@ -59,12 +59,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
|
||||
<!-- Sidebar Toggler (Sidebar) -->
|
||||
<div class="text-center d-none d-md-inline">
|
||||
<button class="rounded-circle border-0" id="sidebarToggle"></button>
|
||||
<button class="rounded-circle border-0" id="sidebarToggle" onclick="setSidebarToggleValue()"></button>
|
||||
</div>
|
||||
</ul>
|
||||
<!-- End of Sidebar -->
|
||||
|
||||
|
||||
<!-- Content Wrapper -->
|
||||
<div id="content-wrapper" class="d-flex flex-column">
|
||||
|
||||
|
@ -79,36 +78,43 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
<i class="fa fa-bars"></i>
|
||||
</button>
|
||||
|
||||
|
||||
<!-- Topbar Notification -->
|
||||
<div class="d-none d-sm-inline-block form-inline mr-auto ml-md-3 my-2 my-md-0 mw-100 navbar-search">
|
||||
<ul class="navbar-nav ml-auto">
|
||||
|
||||
<li>
|
||||
<div class="nav-item spinner-border m-3" role="status" style="display:none;" id="spinner">
|
||||
<span class="nav-item sr-only">Loading...</span>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li class="nav-item dropdown no-arrow" id="notificationArea" style="display: none;">
|
||||
<div class="nav-link dropdown-toggle">
|
||||
<span id="notification" class="mr-2 d-none d-lg-inline text-gray-600">Notification</span>
|
||||
<span id="notification" class="mr-2 d-none d-lg-inline text-danger">Notification</span>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- Topbar Navbar -->
|
||||
<ul class="navbar-nav ml-auto">
|
||||
|
||||
<li class="nav-item dropdown" id="remoteListNav">
|
||||
<li class="nav-item dropdown">
|
||||
<label class="h6 mt-4 mr-2 ml-4">Host: </label>
|
||||
</li>
|
||||
<li class="nav-item dropdown">
|
||||
<div class="input-group mt-3">
|
||||
<select class="form-control" id="remoteListNav" style="width:150px;" onchange="location = this.value;">
|
||||
</select>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li class="nav-item dropdown" id="projectListNav">
|
||||
<li class="nav-item dropdown">
|
||||
<label class="h6 mt-4 mr-2 ml-4">Project: </label>
|
||||
</li>
|
||||
<li class="nav-item dropdown">
|
||||
<div class="input-group mt-3">
|
||||
<select class="form-control" id="projectListNav" style="width:150px;" onchange="location = this.value;">
|
||||
</select>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<!-- Nav Divider -->
|
||||
<div class="topbar-divider d-none d-sm-block"></div>
|
||||
|
||||
<!-- Nav Item - User Information -->
|
||||
|
@ -119,14 +125,18 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
</a>
|
||||
<!-- Dropdown - User Information -->
|
||||
<div class="dropdown-menu dropdown-menu-right shadow animated--grow-in" aria-labelledby="userDropdown">
|
||||
<a class="dropdown-item" href="user-profile.html">
|
||||
<a class="dropdown-item" href="user-profile.php">
|
||||
<i class="fas fa-user fa-sm fa-fw mr-2 text-gray-400"></i>
|
||||
Profile
|
||||
</a>
|
||||
<a class="dropdown-item" href="settings.html">
|
||||
<a class="dropdown-item" href="settings.php">
|
||||
<i class="fas fa-cog fa-sm fa-fw mr-2 text-gray-400"></i>
|
||||
Settings
|
||||
</a>
|
||||
<a class="dropdown-item" href="logs.php">
|
||||
<i class="fas fa-history fa-sm fa-fw mr-2 text-gray-400"></i>
|
||||
Logs
|
||||
</a>
|
||||
<a class="dropdown-item" href="#" data-toggle="modal" data-target="#aboutModal">
|
||||
<i class="fas fa-info-circle fa-sm fa-fw mr-2 text-gray-400"></i>
|
||||
About
|
||||
|
@ -147,23 +157,45 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
<!-- Begin Page Content -->
|
||||
<div class="container-fluid">
|
||||
|
||||
<!-- BreadCrumb -->
|
||||
<nav aria-label="breadcrumb">
|
||||
<ol class="breadcrumb">
|
||||
<li class="breadcrumb-item"><a href="#" id="remoteBreadCrumb"></a></li>
|
||||
<li class="breadcrumb-item active" aria-current="page" id="clusterMembersBreadCrumb"></li>
|
||||
</ol>
|
||||
</nav>
|
||||
<header class="page-header page-header-dark bg-gradient-primary-to-secondary">
|
||||
<div class="container-xl px-4">
|
||||
<div class="page-header-content pt-4">
|
||||
<div class="row align-items-center justify-content-between mt-n5 ml-n5 mr-n5 bg-dark pb-6">
|
||||
<div class="col-auto mt-4 ml-3">
|
||||
<div class="page-header-subtitle">
|
||||
<a href="#" id="remoteBreadCrumb"></a>
|
||||
</div>
|
||||
<h2 class="page-header-title mt-2">
|
||||
CLUSTER MEMBERS
|
||||
</h2>
|
||||
<div class="page-header-subtitle">
|
||||
Manage members included in the LXD cluster
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-xl-auto mt-4">
|
||||
<div class="input-group input-group-joined border-0" style="width: 14rem">
|
||||
<span class="input-group-text bg-transparent border-0">
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<div class="row">
|
||||
<div class="row mt-n5 ml-2 mr-2">
|
||||
|
||||
<div class="col-12">
|
||||
<!-- Cluster Members List -->
|
||||
<div class="col-12 mt-n3">
|
||||
<!-- Cluster Member List -->
|
||||
<div class="card shadow mb-4">
|
||||
<!-- Card Header - Dropdown -->
|
||||
<div class="card-header py-3 d-flex flex-row align-items-center justify-content-between">
|
||||
<h6 class="m-0 font-weight-bold text-primary">Cluster Members</h6>
|
||||
<h6 class="m-0 font-weight-bold">
|
||||
<span class="ml-1">Cluster Members</span>
|
||||
</h6>
|
||||
<div class="dropdown no-arrow">
|
||||
<a class="dropdown-toggle mr-2" href="#" onclick="reloadPageContent()" title="Refresh" aria-hidden="true">
|
||||
<i class="fa fa-sync fa-1x fa-fw"></i></a>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Card Body -->
|
||||
|
@ -174,7 +206,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- End Cluster Members List -->
|
||||
<!-- End Cluster Member List -->
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
@ -189,7 +221,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
<footer class="sticky-footer bg-white">
|
||||
<div class="container my-auto">
|
||||
<div class="copyright text-center my-auto">
|
||||
<span>Copyright © lxdware.com 2021</span>
|
||||
<span>Copyright © LXDWARE 2020 - Present</span>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
|
@ -281,60 +313,66 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
const urlParams = new URLSearchParams(queryString);
|
||||
const remoteId = urlParams.get('remote');
|
||||
const projectName = urlParams.get('project');
|
||||
var reloadTime = 5000;
|
||||
|
||||
function logout(){
|
||||
$.get("./php/aaa/authentication.php?action=deauthenticateUser", function (data) {
|
||||
$.get("./backend/aaa/authentication.php?action=deauthenticateUser", function (data) {
|
||||
operationData = JSON.parse(data);
|
||||
console.log(operationData);
|
||||
if (operationData.status_code == 200) {
|
||||
window.location = './index.html'
|
||||
window.location.href = './index.php'
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function operationStatusCheck(){
|
||||
clearTimeout(operationTimeout);
|
||||
//check to see if there are any running operations
|
||||
$.get("./php/lxd/operations.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&action=displayOperationStatus", function (data) {
|
||||
$.get("./backend/lxd/operations.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&action=displayOperationStatus", function (data) {
|
||||
//Check to see if we have running operations
|
||||
if (data){
|
||||
//Display spinner and notification area if there are running tasks
|
||||
$('#spinner').show();
|
||||
if (data) {
|
||||
//Display notification area if there are running tasks
|
||||
$('#notificationArea').show();
|
||||
$('#notification').text(data);
|
||||
//Set the page to check operations again in 1 second
|
||||
setTimeout(() => { operationStatusCheck(); }, 1000);
|
||||
$('#notification').text("Notice: " + data);
|
||||
//Set the page to check operations again in 2 seconds
|
||||
operationTimeout = setTimeout(() => { operationStatusCheck(); }, 2000);
|
||||
}
|
||||
else {
|
||||
//Hide spinner and notification area if no running tasks
|
||||
$('#spinner').hide();
|
||||
//Hide notification area if no running tasks
|
||||
$('#notificationArea').hide();
|
||||
$('#notification').text("");
|
||||
//Set the page to check operations again in 3 seconds
|
||||
setTimeout(() => { operationStatusCheck(); }, 3000);
|
||||
//Set the page to check operations again in 4 seconds
|
||||
operationTimeout = setTimeout(() => { operationStatusCheck(); }, 4000);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function reloadPageContent() {
|
||||
|
||||
clearTimeout(pageReloadTimeout);
|
||||
|
||||
//Check Authorization
|
||||
$.get("./php/aaa/authentication.php?action=validateAuthentication", function (data) {
|
||||
$.get("./backend/aaa/authentication.php?action=validateAuthentication", function (data) {
|
||||
operationData = JSON.parse(data);
|
||||
if (operationData.status_code != 200) {
|
||||
console.log(operationData);
|
||||
window.location = './index.html'
|
||||
window.location.href = './index.php'
|
||||
}
|
||||
});
|
||||
|
||||
$('#clusterMemberListTable').DataTable().ajax.reload(null, false);
|
||||
|
||||
//Set reload page content
|
||||
pageReloadTimeout = setTimeout(() => { reloadPageContent(); }, reloadTime);
|
||||
}
|
||||
|
||||
function loadPageContent(){
|
||||
|
||||
//Display current logged in username
|
||||
$("#username").load("./php/admin/settings.php?action=displayUsername");
|
||||
$("#username").load("./backend/admin/settings.php?action=displayUsername");
|
||||
|
||||
$('#clusterMemberListTable').DataTable( {
|
||||
ajax: "./php/lxd/cluster-members.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&action=listClusterMembers",
|
||||
ajax: "./backend/lxd/cluster-members.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&action=listClusterMembers",
|
||||
columns: [
|
||||
{},
|
||||
{ title: "Server Name" },
|
||||
|
@ -351,10 +389,16 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
});
|
||||
|
||||
//Check for any running operations
|
||||
operationStatusCheck();
|
||||
operationTimeout = setTimeout(() => { operationStatusCheck(); }, 1000);
|
||||
|
||||
//Set the page content to reload in 5 seconds
|
||||
setInterval(() => { reloadPageContent(); }, 5000);
|
||||
//Set reload page content
|
||||
$.get("./backend/admin/settings.php?action=retrievePageRefreshRateValues", function (data) {
|
||||
operationData = JSON.parse(data);
|
||||
if (operationData.cluster_members_page_rate >= 1)
|
||||
reloadTime = operationData.cluster_members_page_rate * 1000;
|
||||
pageReloadTimeout = setTimeout(() => { reloadPageContent(); }, reloadTime);
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
function loadDeleteClusterMemberModal(clusterMember){
|
||||
|
@ -370,7 +414,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
forceDeleteCheck = "true";
|
||||
}
|
||||
console.log("Info: deleting cluster member " + memberToDelete);
|
||||
$.get("./php/lxd/cluster-members.php?remote=" + encodeURI(remoteId) + "&name=" + encodeURI(memberToDelete) + "&force=" + encodeURI(forceDeleteCheck) + "&action=deleteClusterMember", function (data) {
|
||||
$.get("./backend/lxd/cluster-members.php?remote=" + encodeURI(remoteId) + "&name=" + encodeURI(memberToDelete) + "&force=" + encodeURI(forceDeleteCheck) + "&action=deleteClusterMember", function (data) {
|
||||
//Async operation type
|
||||
var operationData = JSON.parse(data);
|
||||
console.log(operationData);
|
||||
|
@ -382,33 +426,64 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
});
|
||||
}
|
||||
|
||||
function setSidebarToggleValue(){
|
||||
sidebarState = localStorage.getItem('sidebarState');
|
||||
if (sidebarState == "collapsed"){
|
||||
localStorage.setItem('sidebarState','expanded');
|
||||
}
|
||||
else {
|
||||
localStorage.setItem('sidebarState','collapsed');
|
||||
}
|
||||
}
|
||||
|
||||
function applySidebarToggleValue() {
|
||||
sidebarState = localStorage.getItem('sidebarState');
|
||||
if (sidebarState == "collapsed"){
|
||||
$("body").toggleClass("sidebar-toggled"),
|
||||
$(".sidebar").toggleClass("toggled"),
|
||||
$(".sidebar").hasClass("toggled") && $(".sidebar .collapse").collapse("hide")
|
||||
}
|
||||
}
|
||||
|
||||
applySidebarToggleValue();
|
||||
|
||||
$(document).ready(function(){
|
||||
|
||||
//Check Authorization
|
||||
$.get("./php/aaa/authentication.php?action=validateAuthentication", function (data) {
|
||||
$.get("./backend/aaa/authentication.php?action=validateAuthentication", function (data) {
|
||||
operationData = JSON.parse(data);
|
||||
if (operationData.status_code != 200) {
|
||||
console.log(operationData);
|
||||
window.location = './index.html'
|
||||
window.location.href = './index.php'
|
||||
}
|
||||
});
|
||||
|
||||
//Load in the sidebar
|
||||
$("#sidebarLinks").load("./sidebar.html");
|
||||
$("#sidebarLinks").load("./sidebar.php?version=3.0");
|
||||
|
||||
//Setup Page Breadcrumb Links/Information
|
||||
$('#remoteBreadCrumb').load("./php/lxd/remote-breadcrumb.php?remote=" + encodeURI(remoteId));
|
||||
$('#remoteBreadCrumb').attr("href", "remotes-single.html?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName));
|
||||
$('#clusterMembersBreadCrumb').text("cluster-members");
|
||||
$('#remoteBreadCrumb').load("./backend/lxd/remote-breadcrumb.php?remote=" + encodeURI(remoteId));
|
||||
$('#remoteBreadCrumb').attr("href", "remotes-single.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName));
|
||||
|
||||
//Load the card contents
|
||||
loadPageContent();
|
||||
//Validate remote host connection returns 200 status
|
||||
$.get("./backend/lxd/remotes-single.php?remote=" + encodeURI(remoteId) + "&action=validateRemoteConnection", function (data) {
|
||||
operationData = JSON.parse(data);
|
||||
console.log(operationData);
|
||||
if (operationData.status_code == 200) {
|
||||
//Set top navbar dropdowns
|
||||
$("#remoteListNav").load("./backend/lxd/remotes.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&action=listRemotesForSelectOption");
|
||||
$("#projectListNav").load("./backend/lxd/projects.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&action=listProjectsForSelectOption");
|
||||
|
||||
//Load Page Content
|
||||
loadPageContent();
|
||||
}
|
||||
else {
|
||||
alert("Unable to connect to remote host. HTTP status code: " + operationData.status_code);
|
||||
}
|
||||
});
|
||||
|
||||
$("#remoteListNav").load("./php/lxd/remotes.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&action=listRemotesForTopNavigation");
|
||||
$("#projectListNav").load("./php/lxd/projects.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&action=listProjectsForTopNavigation");
|
||||
|
||||
//Load the about info for the about modal
|
||||
$.get("./about.html", function (data) {
|
||||
$.get("./backend/config/about.php", function (data) {
|
||||
$("#about").html(data);
|
||||
});
|
||||
|
6017
lxd-dashboard/containers-single.php
Normal file
1746
lxd-dashboard/containers.php
Normal file
|
@ -1,547 +0,0 @@
|
|||
<!--
|
||||
LXDWARE LXD Dashboard - A web-based interface for managing LXD servers
|
||||
Copyright (C) 2020-2021 LXDWARE.COM
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
-->
|
||||
|
||||
<!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, shrink-to-fit=no">
|
||||
<meta name="description" content="">
|
||||
<meta name="author" content="">
|
||||
|
||||
<link rel="icon" type="image/png" href="assets/images/logo-light.svg">
|
||||
|
||||
<title>LXD Dashboard</title>
|
||||
|
||||
<!-- Custom fonts for this template-->
|
||||
<link href="vendor/fontawesome-free/css/all.min.css" rel="stylesheet" type="text/css">
|
||||
<link href="vendor/fonts/nunito.css" rel="stylesheet">
|
||||
|
||||
<!-- Custom styles for this template-->
|
||||
<link href="vendor/sb-admin-2/css/sb-admin-2.css" rel="stylesheet">
|
||||
<link href="assets/css/style.css" rel="stylesheet">
|
||||
|
||||
<!-- Custom styles for this page -->
|
||||
<link href="vendor/datatables/dataTables.bootstrap4.min.css" rel="stylesheet">
|
||||
|
||||
</head>
|
||||
|
||||
<body id="page-top">
|
||||
|
||||
<!-- Page Wrapper -->
|
||||
<div id="wrapper">
|
||||
|
||||
<!-- Sidebar -->
|
||||
<ul class="navbar-nav bg-dark sidebar sidebar-dark accordion" id="accordionSidebar">
|
||||
|
||||
<div id="sidebarLinks"></div>
|
||||
|
||||
<!-- Divider -->
|
||||
<hr class="sidebar-divider d-none d-md-block">
|
||||
|
||||
<!-- Sidebar Toggler (Sidebar) -->
|
||||
<div class="text-center d-none d-md-inline">
|
||||
<button class="rounded-circle border-0" id="sidebarToggle"></button>
|
||||
</div>
|
||||
</ul>
|
||||
<!-- End of Sidebar -->
|
||||
|
||||
|
||||
<!-- Content Wrapper -->
|
||||
<div id="content-wrapper" class="d-flex flex-column">
|
||||
|
||||
<!-- Main Content -->
|
||||
<div id="content">
|
||||
|
||||
<!-- Topbar -->
|
||||
<nav class="navbar navbar-expand navbar-light bg-white topbar mb-4 static-top shadow">
|
||||
|
||||
<!-- Sidebar Toggle (Topbar) -->
|
||||
<button id="sidebarToggleTop" class="btn btn-link d-md-none rounded-circle mr-3">
|
||||
<i class="fa fa-bars"></i>
|
||||
</button>
|
||||
|
||||
|
||||
<!-- Topbar Notification -->
|
||||
<div class="d-none d-sm-inline-block form-inline mr-auto ml-md-3 my-2 my-md-0 mw-100 navbar-search">
|
||||
<ul class="navbar-nav ml-auto">
|
||||
|
||||
<li>
|
||||
<div class="nav-item spinner-border m-3" role="status" style="display:none;" id="spinner">
|
||||
<span class="nav-item sr-only">Loading...</span>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li class="nav-item dropdown no-arrow" id="notificationArea" style="display: none;">
|
||||
<div class="nav-link dropdown-toggle">
|
||||
<span id="notification" class="mr-2 d-none d-lg-inline text-gray-600">Notification</span>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- Topbar Navbar -->
|
||||
<ul class="navbar-nav ml-auto">
|
||||
|
||||
<li class="nav-item dropdown" id="remoteListNav">
|
||||
</li>
|
||||
|
||||
<li class="nav-item dropdown" id="projectListNav">
|
||||
</li>
|
||||
|
||||
<div class="topbar-divider d-none d-sm-block"></div>
|
||||
|
||||
<!-- Nav Item - User Information -->
|
||||
<li class="nav-item dropdown no-arrow">
|
||||
<a class="nav-link dropdown-toggle" href="#" id="userDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
<i class="fas fa-user-circle fa-1x fa-fw mr-2 text-gray-600"></i>
|
||||
<span id="username" class="mr-2 d-none d-lg-inline text-gray-600"></span>
|
||||
</a>
|
||||
<!-- Dropdown - User Information -->
|
||||
<div class="dropdown-menu dropdown-menu-right shadow animated--grow-in" aria-labelledby="userDropdown">
|
||||
<a class="dropdown-item" href="user-profile.html">
|
||||
<i class="fas fa-user fa-sm fa-fw mr-2 text-gray-400"></i>
|
||||
Profile
|
||||
</a>
|
||||
<a class="dropdown-item" href="settings.html">
|
||||
<i class="fas fa-cog fa-sm fa-fw mr-2 text-gray-400"></i>
|
||||
Settings
|
||||
</a>
|
||||
<a class="dropdown-item" href="#" data-toggle="modal" data-target="#aboutModal">
|
||||
<i class="fas fa-info-circle fa-sm fa-fw mr-2 text-gray-400"></i>
|
||||
About
|
||||
</a>
|
||||
<div class="dropdown-divider"></div>
|
||||
<a class="dropdown-item" href="#" onclick="logout()">
|
||||
<i class="fas fa-sign-out-alt fa-sm fa-fw mr-2 text-gray-400"></i>
|
||||
Logout
|
||||
</a>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
|
||||
</nav>
|
||||
<!-- End of Topbar -->
|
||||
|
||||
<!-- Begin Page Content -->
|
||||
<div class="container-fluid">
|
||||
|
||||
<!-- BreadCrumb -->
|
||||
<nav aria-label="breadcrumb">
|
||||
<ol class="breadcrumb">
|
||||
<li class="breadcrumb-item"><a href="#" id="remoteBreadCrumb"></a></li>
|
||||
<li class="breadcrumb-item active" aria-current="page" id="imagesBreadCrumb"></li>
|
||||
</ol>
|
||||
</nav>
|
||||
|
||||
<div class="row">
|
||||
|
||||
<div class="col-12">
|
||||
<!-- Image List -->
|
||||
<div class="card shadow mb-4">
|
||||
<!-- Card Header - Dropdown -->
|
||||
<div class="card-header py-3 d-flex flex-row align-items-center justify-content-between">
|
||||
<h6 class="m-0 font-weight-bold text-primary">Images</h6>
|
||||
<div class="dropdown no-arrow">
|
||||
<a class="dropdown-toggle mr-2" href="#" data-toggle="modal" data-target="#downloadImageModal" title="Download Image" aria-hidden="true">
|
||||
<i class="fas fa-plus fa-sm fa-fw"></i> Image</a>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Card Body -->
|
||||
<div class="card-body">
|
||||
<div class="table-responsive">
|
||||
<table class="table" id="imageListTable" width="100%" cellspacing="0">
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- End Image List -->
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<!-- /.container-fluid -->
|
||||
|
||||
</div>
|
||||
<!-- End of Main Content -->
|
||||
|
||||
<!-- Footer -->
|
||||
<footer class="sticky-footer bg-white">
|
||||
<div class="container my-auto">
|
||||
<div class="copyright text-center my-auto">
|
||||
<span>Copyright © lxdware.com 2021</span>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
<!-- End of Footer -->
|
||||
|
||||
</div>
|
||||
<!-- End of Content Wrapper -->
|
||||
|
||||
</div>
|
||||
<!-- End of Page Wrapper -->
|
||||
|
||||
<!-- Scroll to Top Button-->
|
||||
<a class="scroll-to-top rounded" href="#page-top">
|
||||
<i class="fas fa-angle-up"></i>
|
||||
</a>
|
||||
|
||||
|
||||
<!-- Download Image Modal-->
|
||||
<div class="modal fade" id="downloadImageModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="exampleModalLabel">Download Image</h5>
|
||||
<button class="close" type="button" data-dismiss="modal" aria-label="Close">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
|
||||
<div class="row">
|
||||
<label class="col-3 col-form-label text-right">Image/Alias: </label>
|
||||
<div class="col-7">
|
||||
<div class="form-group">
|
||||
<input type="text" class="form-control" id="imageNameInput" required="required" placeholder="" name="image">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-1">
|
||||
<i class="far fa-sm fa-question-circle text-danger" data-toggle="tooltip" data-html="true" title='(Required) - Enter in the repository specific name. For example, ubuntu/20.04 would be used for the images repository and simply 20.04 would be used for the ubuntu repositories.'></i>
|
||||
</div>
|
||||
|
||||
<label class="col-3 col-form-label text-right">Repository:</label>
|
||||
<div class="col-7 text-right">
|
||||
<div class="form-group">
|
||||
<select id="selectRepoInput" class="form-control" name="repo">
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-1">
|
||||
<i class="far fa-sm fa-question-circle text-danger" title='(Required) - Select a repository from the configured simplestreams.'></i>
|
||||
</div>
|
||||
|
||||
<label class="col-3 col-form-label text-right">Image Type:</label>
|
||||
<div class="col-7 text-right">
|
||||
<div class="form-group">
|
||||
<select id="selectTypeInput" class="form-control" name="image_type">
|
||||
<option value="container" selected>container</option>
|
||||
<option value="virtual-machine">virtual-machine</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-1">
|
||||
<i class="far fa-sm fa-question-circle" title='Select whether to download a container based image or virtual machine. Default: container'></i>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button class="btn btn-secondary" type="button" data-dismiss="modal">Cancel</button>
|
||||
<a class="btn btn-primary" href="#" onclick="downloadImage()" data-dismiss="modal">Ok</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Edit Image Modal-->
|
||||
<div class="modal fade" id="editImageModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog modal-lg" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="exampleModalLabel">Edit Image</h5>
|
||||
<button class="close" type="button" data-dismiss="modal" aria-label="Close">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="row">
|
||||
<label class="col-12 col-form-label" id="imageNameEditInput"></label>
|
||||
<div class="col-12">
|
||||
<div class="form-group text-right">
|
||||
<pre>
|
||||
<textarea name="json" class="form-control" id="jsonEditInput" rows="16" ></textarea>
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button class="btn btn-secondary" type="button" data-dismiss="modal">Cancel</button>
|
||||
<a class="btn btn-primary" href="#" onclick="updateImage()" data-dismiss="modal">Submit</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- About Modal-->
|
||||
<div class="modal fade" id="aboutModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="exampleModalLabel">About</h5>
|
||||
<button class="close" type="button" data-dismiss="modal" aria-label="Close">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<div id="about"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button class="btn btn-secondary" type="button" data-dismiss="modal">Dismiss</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Bootstrap core JavaScript-->
|
||||
<script src="vendor/jquery/jquery.min.js"></script>
|
||||
<script src="vendor/bootstrap/js/bootstrap.bundle.min.js"></script>
|
||||
|
||||
<!-- Core plugin JavaScript-->
|
||||
<script src="vendor/jquery-easing/jquery.easing.min.js"></script>
|
||||
|
||||
<!-- Custom scripts for all pages-->
|
||||
<script src="vendor/sb-admin-2/js/sb-admin-2.min.js"></script>
|
||||
|
||||
<!-- Page level plugins -->
|
||||
<script src="vendor/datatables/jquery.dataTables.min.js"></script>
|
||||
<script src="vendor/datatables/dataTables.bootstrap4.min.js"></script>
|
||||
|
||||
</body>
|
||||
|
||||
<script>
|
||||
const queryString = window.location.search;
|
||||
const urlParams = new URLSearchParams(queryString);
|
||||
const remoteId = urlParams.get('remote');
|
||||
const projectName = urlParams.get('project');
|
||||
var selectList = "";
|
||||
var imageToUpdate = "";
|
||||
|
||||
function logout(){
|
||||
$.get("./php/aaa/authentication.php?action=deauthenticateUser", function (data) {
|
||||
operationData = JSON.parse(data);
|
||||
console.log(operationData);
|
||||
if (operationData.status_code == 200) {
|
||||
window.location = './index.html'
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function operationStatusCheck(){
|
||||
//check to see if there are any running operations
|
||||
$.get("./php/lxd/operations.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&action=displayOperationStatus", function (data) {
|
||||
//Check to see if we have running operations
|
||||
if (data){
|
||||
//Display spinner and notification area if there are running tasks
|
||||
$('#spinner').show();
|
||||
$('#notificationArea').show();
|
||||
$('#notification').text(data);
|
||||
//Set the page to check operations again in 1 second
|
||||
setTimeout(() => { operationStatusCheck(); }, 1000);
|
||||
}
|
||||
else {
|
||||
//Hide spinner and notification area if no running tasks
|
||||
$('#spinner').hide();
|
||||
$('#notificationArea').hide();
|
||||
$('#notification').text("");
|
||||
//Set the page to check operations again in 3 seconds
|
||||
setTimeout(() => { operationStatusCheck(); }, 3000);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function reloadPageContent() {
|
||||
|
||||
//Check Authorization
|
||||
$.get("./php/aaa/authentication.php?action=validateAuthentication", function (data) {
|
||||
operationData = JSON.parse(data);
|
||||
if (operationData.status_code != 200) {
|
||||
console.log(operationData);
|
||||
window.location = './index.html'
|
||||
}
|
||||
});
|
||||
|
||||
$('#imageListTable').DataTable().ajax.reload(null, false);
|
||||
|
||||
//Load the select List for Download Image Modal
|
||||
$.get("./php/lxd/simplestreams.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&action=listSimplestreamsForSelectOption", function (data) {
|
||||
if (selectList != data){
|
||||
$("#selectRepoInput").html(data);
|
||||
selectList = data;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function loadPageContent(){
|
||||
|
||||
//Display current logged in username
|
||||
$("#username").load("./php/admin/settings.php?action=displayUsername");
|
||||
|
||||
$('#imageListTable').DataTable( {
|
||||
ajax: "./php/lxd/images.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&action=listImages",
|
||||
columns: [
|
||||
{},
|
||||
{ title: "Description" },
|
||||
{ title: "Fingerprint" },
|
||||
{ title: "Type" },
|
||||
{ title: "Size" },
|
||||
{ title: "Action" }
|
||||
],
|
||||
order: [],
|
||||
columnDefs: [
|
||||
{ targets: 0, orderable: false, width: "25px" }
|
||||
]
|
||||
});
|
||||
|
||||
//Load the select List for Download Image Modal
|
||||
$.get("./php/lxd/simplestreams.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&action=listSimplestreamsForSelectOption", function (data) {
|
||||
if (selectList != data){
|
||||
$("#selectRepoInput").html(data);
|
||||
selectList = data;
|
||||
}
|
||||
});
|
||||
|
||||
//Check for any running operations
|
||||
operationStatusCheck();
|
||||
|
||||
//Set the page content to reload in 5 seconds
|
||||
setInterval(() => { reloadPageContent(); }, 5000);
|
||||
}
|
||||
|
||||
function refreshImage(imageFingerprint){
|
||||
console.log("Info: refreshing image " + imageFingerprint);
|
||||
$.get("./php/lxd/images.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&fingerprint=" + encodeURI(imageFingerprint) + "&action=refreshImage", function (data) {
|
||||
//Async operation type
|
||||
var operationData = JSON.parse(data);
|
||||
console.log(operationData);
|
||||
if (operationData.error_code >= 400){
|
||||
alert(operationData.error);
|
||||
}
|
||||
operationStatusCheck();
|
||||
setTimeout(() => { reloadPageContent(); }, 1000);
|
||||
});
|
||||
}
|
||||
|
||||
function deleteImage(imageFingerprint){
|
||||
console.log("Info: deleting image " + imageFingerprint);
|
||||
$.get("./php/lxd/images.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&fingerprint=" + encodeURI(imageFingerprint) + "&action=deleteImage", function (data) {
|
||||
//Async operation type
|
||||
var operationData = JSON.parse(data);
|
||||
console.log(operationData);
|
||||
if (operationData.error_code >= 400){
|
||||
alert(operationData.error);
|
||||
}
|
||||
operationStatusCheck();
|
||||
setTimeout(() => { reloadPageContent(); }, 1000);
|
||||
});
|
||||
}
|
||||
|
||||
function downloadImage(){
|
||||
var imageName = $("#imageNameInput").val();
|
||||
var repoName = $("#selectRepoInput").val();
|
||||
var imageType = $("#selectTypeInput").val();
|
||||
console.log("Info: downloading image " + imageName + " from " + repoName);
|
||||
$.get("./php/lxd/images.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&image=" + encodeURI(imageName) + "&repo=" + encodeURI(repoName) + "&image_type=" + encodeURI(imageType) + "&action=downloadImage", function (data) {
|
||||
//Async operation type
|
||||
var operationData = JSON.parse(data);
|
||||
console.log(operationData);
|
||||
if (operationData.error_code >= 400){
|
||||
alert(operationData.error);
|
||||
}
|
||||
operationStatusCheck();
|
||||
setTimeout(() => { reloadPageContent(); }, 1000);
|
||||
});
|
||||
}
|
||||
|
||||
function loadImageJson(imageToLoad){
|
||||
console.log("Info: loading image " + imageToLoad);
|
||||
imageToUpdate = imageToLoad;
|
||||
$.get("./php/lxd/images.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&fingerprint=" + encodeURI(imageToLoad) + "&action=loadImage", function (data) {
|
||||
//Sync operation type
|
||||
var operationData = JSON.parse(data);
|
||||
console.log(operationData);
|
||||
if (operationData.error_code >= 400){
|
||||
alert(operationData.error);
|
||||
}
|
||||
$("#imageNameEditInput").text("Fingerprint: " + imageToLoad);
|
||||
$("#jsonEditInput").val(JSON.stringify(operationData.metadata, null, 2));
|
||||
$("#editImageModal").modal('show');
|
||||
});
|
||||
}
|
||||
|
||||
function updateImage(){
|
||||
var imageUpdateJSON = $("#jsonEditInput").val();
|
||||
console.log("Info: updating image " + imageToUpdate);
|
||||
$.post("./php/lxd/images.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&fingerprint=" + encodeURI(imageToUpdate) + "&action=updateImage", {json: imageUpdateJSON}, function (data) {
|
||||
//Sync operation type
|
||||
var operationData = JSON.parse(data);
|
||||
console.log(operationData);
|
||||
if (operationData.error_code >= 400){
|
||||
alert(operationData.error);
|
||||
}
|
||||
setTimeout(() => { reloadPageContent(); }, 1000);
|
||||
});
|
||||
}
|
||||
|
||||
$(document).ready(function(){
|
||||
|
||||
//Check Authorization
|
||||
$.get("./php/aaa/authentication.php?action=validateAuthentication", function (data) {
|
||||
operationData = JSON.parse(data);
|
||||
if (operationData.status_code != 200) {
|
||||
console.log(operationData);
|
||||
window.location = './index.html'
|
||||
}
|
||||
});
|
||||
|
||||
//Load in the sidebar
|
||||
$("#sidebarLinks").load("./sidebar.html");
|
||||
|
||||
//Setup Page Breadcrumb Links/Information
|
||||
$('#remoteBreadCrumb').load("./php/lxd/remote-breadcrumb.php?remote=" + encodeURI(remoteId));
|
||||
$('#remoteBreadCrumb').attr("href", "remotes-single.html?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName));
|
||||
$('#imagesBreadCrumb').text("images");
|
||||
|
||||
//Load the card contents
|
||||
loadPageContent();
|
||||
|
||||
$("#remoteListNav").load("./php/lxd/remotes.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&action=listRemotesForTopNavigation");
|
||||
$("#projectListNav").load("./php/lxd/projects.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&action=listProjectsForTopNavigation");
|
||||
|
||||
//Load the about info for the about modal
|
||||
$.get("./about.html", function (data) {
|
||||
$("#about").html(data);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
</html>
|
1203
lxd-dashboard/images.php
Normal file
|
@ -1,212 +1,6 @@
|
|||
<!--
|
||||
LXDWARE LXD Dashboard - A web-based interface for managing LXD servers
|
||||
Copyright (C) 2020-2021 LXDWARE.COM
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
-->
|
||||
|
||||
<!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, shrink-to-fit=no">
|
||||
<meta name="description" content="">
|
||||
<meta name="author" content="">
|
||||
|
||||
<link rel="icon" type="image/png" href="assets/images/logo-light.svg">
|
||||
|
||||
<title>LXD Dashboard</title>
|
||||
|
||||
<!-- Custom fonts for this template-->
|
||||
<link href="vendor/fontawesome-free/css/all.min.css" rel="stylesheet" type="text/css">
|
||||
<link href="vendor/fonts/nunito.css" rel="stylesheet">
|
||||
|
||||
<!-- Custom styles for this template-->
|
||||
<link href="vendor/sb-admin-2/css/sb-admin-2.css" rel="stylesheet">
|
||||
<link href="assets/css/style.css" rel="stylesheet">
|
||||
|
||||
<style>
|
||||
body {
|
||||
background-image: url('assets/images/logo-bg.svg') !important;
|
||||
background-position: center center !important;
|
||||
background-size: 100% auto !important;
|
||||
background-repeat: no-repeat;
|
||||
background-attachment: fixed;
|
||||
}
|
||||
</style>
|
||||
|
||||
</head>
|
||||
|
||||
<body class="bg-dark">
|
||||
|
||||
<div class="container">
|
||||
|
||||
<!-- Outer Row -->
|
||||
<div class="row justify-content-center">
|
||||
|
||||
<div class="col-xl-10 col-lg-12 col-md-9">
|
||||
|
||||
<div class="card o-hidden border-0 shadow-lg my-5">
|
||||
<div class="card-body p-0">
|
||||
<!-- Nested Row within Card Body -->
|
||||
<div class="row">
|
||||
<div class="col-lg-5 d-none d-lg-block border-right">
|
||||
|
||||
<div class="pt-5">
|
||||
<div class="text-center">
|
||||
<img src="assets/images/logo-light.svg" width="50px" style="vertical-align: bottom !important;">
|
||||
<span class="h1 text-gray-900"><strong>LXDWARE</strong></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="pt-5">
|
||||
<div class="pl-4">
|
||||
<p class="h5 text-gray-900">Manage remote LXD servers with this open source LXD dashboard.</p>
|
||||
<p class="h5 text-gray-900 pt-3">For instructions on using the dashboard, visit <a href="https://lxdware.com" target="_blank">https://lxdware.com</a>.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="col-lg-7 align-self-center">
|
||||
<div class="p-5">
|
||||
<form class="user" id="loginForm" onsubmit="return false">
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<!-- Bootstrap core JavaScript-->
|
||||
<script src="vendor/jquery/jquery.min.js"></script>
|
||||
<script src="vendor/bootstrap/js/bootstrap.bundle.min.js"></script>
|
||||
|
||||
<!-- Core plugin JavaScript-->
|
||||
<script src="vendor/jquery-easing/jquery.easing.min.js"></script>
|
||||
|
||||
<!-- Custom scripts for all pages-->
|
||||
<script src="vendor/sb-admin-2/js/sb-admin-2.min.js"></script>
|
||||
|
||||
</body>
|
||||
|
||||
<script>
|
||||
function changeDatabaseInput(){
|
||||
if ($("#registerDatabaseTypeInput").val() == 'sqlite'){
|
||||
$("#registerDatabaseHostDiv").hide();
|
||||
$("#registerDatabaseNameDiv").hide();
|
||||
$("#registerDatabaseUserDiv").hide();
|
||||
$("#registerDatabasePasswordDiv").hide();
|
||||
}
|
||||
else {
|
||||
$("#registerDatabaseHostDiv").show();
|
||||
$("#registerDatabaseNameDiv").show();
|
||||
$("#registerDatabaseUserDiv").show();
|
||||
$("#registerDatabasePasswordDiv").show();
|
||||
}
|
||||
}
|
||||
|
||||
function registerUser(){
|
||||
var registerUsernameInput = $("#registerUsernameInput").val();
|
||||
var registerEmailInput = $("#registerEmailInput").val();
|
||||
var registerPasswordInput = $("#registerPasswordInput").val();
|
||||
var registerRepeatPasswordInput = $("#registerRepeatPasswordInput").val();
|
||||
var registerDatabaseTypeInput = $("#registerDatabaseTypeInput").val();
|
||||
var registerDatabaseHostInput = $("#registerDatabaseHostInput").val();
|
||||
var registerDatabaseNameInput = $("#registerDatabaseNameInput").val();
|
||||
var registerDatabaseUserInput = $("#registerDatabaseUserInput").val();
|
||||
var registerDatabasePasswordInput = $("#registerDatabasePasswordInput").val();
|
||||
|
||||
if (registerPasswordInput == registerRepeatPasswordInput){
|
||||
console.log("Info: setting up database");
|
||||
$.post('./php/config/login.php?database_type=' + registerDatabaseTypeInput + '&database_host=' + registerDatabaseHostInput + '&database_name=' + registerDatabaseNameInput + '&database_user=' + registerDatabaseUserInput + '&action=writeDatabaseConfig', {database_password: registerDatabasePasswordInput}, function (data) {
|
||||
console.log(data);
|
||||
var operationData = JSON.parse(data);
|
||||
console.log(operationData);
|
||||
if (operationData.status_code == 200) {
|
||||
console.log("Info: registering user " + registerUsernameInput);
|
||||
$.post('./php/admin/settings.php?action=createUser', {username: registerUsernameInput, password: registerPasswordInput, email: registerEmailInput}, function (data) {
|
||||
var operationData = JSON.parse(data);
|
||||
console.log(operationData);
|
||||
if (operationData.status_code == 200) {
|
||||
location.reload();
|
||||
}
|
||||
if (operationData.status_code >= 400) {
|
||||
console.log(operationData);
|
||||
alert(operationData.metadata.error);
|
||||
location.reload();
|
||||
}
|
||||
});
|
||||
}
|
||||
if (operationData.status_code >= 400) {
|
||||
console.log(operationData);
|
||||
alert(operationData.metadata.error);
|
||||
}
|
||||
});
|
||||
}
|
||||
else {
|
||||
alert("Your passwords did not match, try again");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
function loginUser(){
|
||||
var loginUsernameInput = $("#loginUsernameInput").val();
|
||||
var loginPasswordInput = $("#loginPasswordInput").val();
|
||||
console.log("Info: logging in user " + loginUsernameInput);
|
||||
$.post('./php/aaa/authentication.php?action=authenticateUser', {username: loginUsernameInput, password: loginPasswordInput}, function (data) {
|
||||
var operationData = JSON.parse(data);
|
||||
console.log(operationData);
|
||||
if (operationData.status_code == 200) {
|
||||
window.location = './remotes.html';
|
||||
}
|
||||
if (operationData.status_code == 401) {
|
||||
console.log(operationData);
|
||||
alert(operationData.metadata.error);
|
||||
}
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
$(document).ready(function(){
|
||||
|
||||
//Check if already authorized
|
||||
$.get("./php/aaa/authentication.php?action=validateAuthentication", function (data) {
|
||||
operationData = JSON.parse(data);
|
||||
if (operationData.status_code == 200) {
|
||||
console.log(operationData);
|
||||
window.location = './remotes.html'
|
||||
}
|
||||
});
|
||||
|
||||
$("#loginForm").load( "./php/config/login.php?action=loadLoginForm", function() {
|
||||
$("#loginUsernameInput").focus();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
</html>
|
||||
<script>
|
||||
window.location.replace("index.php");
|
||||
</script>
|
||||
</html>
|
||||
|
|
214
lxd-dashboard/index.php
Normal file
|
@ -0,0 +1,214 @@
|
|||
<!--
|
||||
LXDWARE LXD Dashboard - A web-based interface for managing LXD servers
|
||||
Copyright (C) 2020-2021 LXDWARE.COM
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
-->
|
||||
|
||||
<!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, shrink-to-fit=no">
|
||||
<meta http-equiv="Cache-control" content="no-cache">
|
||||
<meta http-equiv="Expires" content="-1">
|
||||
<meta name="description" content="">
|
||||
<meta name="author" content="">
|
||||
|
||||
<link rel="icon" type="image/png" href="assets/images/logo-light.svg">
|
||||
|
||||
<title>LXD Dashboard</title>
|
||||
|
||||
<!-- Custom fonts for this template-->
|
||||
<link href="vendor/fontawesome-free/css/all.min.css" rel="stylesheet" type="text/css">
|
||||
<link href="vendor/fonts/nunito.css" rel="stylesheet">
|
||||
|
||||
<!-- Custom styles for this template-->
|
||||
<link href="vendor/sb-admin-2/css/sb-admin-2.css" rel="stylesheet">
|
||||
<link href="assets/css/style.css?version=3.0" rel="stylesheet">
|
||||
|
||||
<style>
|
||||
body {
|
||||
background-image: url('assets/images/logo-bg.svg') !important;
|
||||
background-position: center center !important;
|
||||
background-size: 100% auto !important;
|
||||
background-repeat: no-repeat;
|
||||
background-attachment: fixed;
|
||||
}
|
||||
</style>
|
||||
|
||||
</head>
|
||||
|
||||
<body class="bg-dark">
|
||||
|
||||
<div class="container">
|
||||
|
||||
<!-- Outer Row -->
|
||||
<div class="row justify-content-center">
|
||||
|
||||
<div class="col-xl-10 col-lg-12 col-md-9">
|
||||
|
||||
<div class="card o-hidden border-0 shadow-lg my-5">
|
||||
<div class="card-body p-0">
|
||||
<!-- Nested Row within Card Body -->
|
||||
<div class="row">
|
||||
<div class="col-lg-5 d-none d-lg-block border-right">
|
||||
|
||||
<div class="pt-5">
|
||||
<div class="text-center">
|
||||
<img src="assets/images/logo-light.svg" width="50px" style="vertical-align: bottom !important;">
|
||||
<span class="h1 text-gray-900"><strong>LXDWARE</strong></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="pt-5">
|
||||
<div class="pl-4">
|
||||
<p class="h5 text-gray-900">Manage remote LXD servers with this open source LXD dashboard.</p>
|
||||
<p class="h5 text-gray-900 pt-3">For instructions on using the LXD Dashboard, visit <a href="https://lxdware.com" target="_blank">https://lxdware.com</a>.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="col-lg-7 align-self-center">
|
||||
<div class="p-5">
|
||||
<form class="user" id="loginForm" onsubmit="return false">
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<!-- Bootstrap core JavaScript-->
|
||||
<script src="vendor/jquery/jquery.min.js"></script>
|
||||
<script src="vendor/bootstrap/js/bootstrap.bundle.min.js"></script>
|
||||
|
||||
<!-- Core plugin JavaScript-->
|
||||
<script src="vendor/jquery-easing/jquery.easing.min.js"></script>
|
||||
|
||||
<!-- Custom scripts for all pages-->
|
||||
<script src="vendor/sb-admin-2/js/sb-admin-2.min.js"></script>
|
||||
|
||||
</body>
|
||||
|
||||
<script>
|
||||
function changeDatabaseInput(){
|
||||
if ($("#registerDatabaseTypeInput").val() == 'sqlite'){
|
||||
$("#registerDatabaseHostDiv").hide();
|
||||
$("#registerDatabaseNameDiv").hide();
|
||||
$("#registerDatabaseUserDiv").hide();
|
||||
$("#registerDatabasePasswordDiv").hide();
|
||||
}
|
||||
else {
|
||||
$("#registerDatabaseHostDiv").show();
|
||||
$("#registerDatabaseNameDiv").show();
|
||||
$("#registerDatabaseUserDiv").show();
|
||||
$("#registerDatabasePasswordDiv").show();
|
||||
}
|
||||
}
|
||||
|
||||
function registerUser(){
|
||||
var registerUsernameInput = $("#registerUsernameInput").val();
|
||||
var registerEmailInput = $("#registerEmailInput").val();
|
||||
var registerPasswordInput = $("#registerPasswordInput").val();
|
||||
var registerRepeatPasswordInput = $("#registerRepeatPasswordInput").val();
|
||||
var registerDatabaseTypeInput = $("#registerDatabaseTypeInput").val();
|
||||
var registerDatabaseHostInput = $("#registerDatabaseHostInput").val();
|
||||
var registerDatabaseNameInput = $("#registerDatabaseNameInput").val();
|
||||
var registerDatabaseUserInput = $("#registerDatabaseUserInput").val();
|
||||
var registerDatabasePasswordInput = $("#registerDatabasePasswordInput").val();
|
||||
|
||||
if (registerUsernameInput.length > 0 && registerPasswordInput == registerRepeatPasswordInput){
|
||||
console.log("Info: setting up database");
|
||||
$.post('./backend/config/login.php?database_type=' + registerDatabaseTypeInput + '&database_host=' + registerDatabaseHostInput + '&database_name=' + registerDatabaseNameInput + '&database_user=' + registerDatabaseUserInput + '&action=writeDatabaseConfig', {database_password: registerDatabasePasswordInput}, function (data) {
|
||||
console.log(data);
|
||||
var operationData = JSON.parse(data);
|
||||
console.log(operationData);
|
||||
if (operationData.status_code == 200) {
|
||||
console.log("Info: registering user " + registerUsernameInput);
|
||||
$.post('./backend/admin/settings.php?action=createUser', {username: registerUsernameInput, password: registerPasswordInput, email: registerEmailInput}, function (data) {
|
||||
var operationData = JSON.parse(data);
|
||||
console.log(operationData);
|
||||
if (operationData.status_code == 200) {
|
||||
location.reload();
|
||||
}
|
||||
if (operationData.status_code >= 400) {
|
||||
console.log(operationData);
|
||||
alert(operationData.metadata.error);
|
||||
location.reload();
|
||||
}
|
||||
});
|
||||
}
|
||||
if (operationData.status_code >= 400) {
|
||||
console.log(operationData);
|
||||
alert(operationData.metadata.error);
|
||||
}
|
||||
});
|
||||
}
|
||||
else {
|
||||
alert("Your passwords did not match, try again");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
function loginUser(){
|
||||
var loginUsernameInput = $("#loginUsernameInput").val();
|
||||
var loginPasswordInput = $("#loginPasswordInput").val();
|
||||
console.log("Info: logging in user " + loginUsernameInput);
|
||||
$.post('./backend/aaa/authentication.php?action=authenticateUser', {username: loginUsernameInput, password: loginPasswordInput}, function (data) {
|
||||
var operationData = JSON.parse(data);
|
||||
console.log(operationData);
|
||||
if (operationData.status_code == 200) {
|
||||
window.location.href = './remotes.php';
|
||||
}
|
||||
if (operationData.status_code == 401) {
|
||||
console.log(operationData);
|
||||
alert(operationData.metadata.error);
|
||||
}
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
$(document).ready(function(){
|
||||
|
||||
//Check if already authorized
|
||||
$.get("./backend/aaa/authentication.php?action=validateAuthentication", function (data) {
|
||||
operationData = JSON.parse(data);
|
||||
if (operationData.status_code == 200) {
|
||||
console.log(operationData);
|
||||
window.location.href = './remotes.php'
|
||||
}
|
||||
});
|
||||
|
||||
$("#loginForm").load( "./backend/config/login.php?action=loadLoginForm", function() {
|
||||
$("#loginUsernameInput").focus();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
</html>
|
|
@ -1,752 +0,0 @@
|
|||
<!--
|
||||
LXDWARE LXD Dashboard - A web-based interface for managing LXD servers
|
||||
Copyright (C) 2020-2021 LXDWARE.COM
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
-->
|
||||
|
||||
<!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, shrink-to-fit=no">
|
||||
<meta name="description" content="">
|
||||
<meta name="author" content="">
|
||||
|
||||
<link rel="icon" type="image/png" href="assets/images/logo-light.svg">
|
||||
|
||||
<title>LXD Dashboard</title>
|
||||
|
||||
<!-- Custom fonts for this template-->
|
||||
<link href="vendor/fontawesome-free/css/all.min.css" rel="stylesheet" type="text/css">
|
||||
<link href="vendor/fonts/nunito.css" rel="stylesheet">
|
||||
|
||||
<!-- Custom styles for this template-->
|
||||
<link href="vendor/sb-admin-2/css/sb-admin-2.css" rel="stylesheet">
|
||||
<link href="assets/css/style.css" rel="stylesheet">
|
||||
|
||||
<!-- Custom styles for this page -->
|
||||
<link href="vendor/datatables/dataTables.bootstrap4.min.css" rel="stylesheet">
|
||||
|
||||
</head>
|
||||
|
||||
<body id="page-top">
|
||||
|
||||
<!-- Page Wrapper -->
|
||||
<div id="wrapper">
|
||||
|
||||
<!-- Sidebar -->
|
||||
<ul class="navbar-nav bg-dark sidebar sidebar-dark accordion" id="accordionSidebar">
|
||||
|
||||
<div id="sidebarLinks"></div>
|
||||
|
||||
<!-- Divider -->
|
||||
<hr class="sidebar-divider d-none d-md-block">
|
||||
|
||||
<!-- Sidebar Toggler (Sidebar) -->
|
||||
<div class="text-center d-none d-md-inline">
|
||||
<button class="rounded-circle border-0" id="sidebarToggle"></button>
|
||||
</div>
|
||||
</ul>
|
||||
<!-- End of Sidebar -->
|
||||
|
||||
|
||||
<!-- Content Wrapper -->
|
||||
<div id="content-wrapper" class="d-flex flex-column">
|
||||
|
||||
<!-- Main Content -->
|
||||
<div id="content">
|
||||
|
||||
<!-- Topbar -->
|
||||
<nav class="navbar navbar-expand navbar-light bg-white topbar mb-4 static-top shadow">
|
||||
|
||||
<!-- Sidebar Toggle (Topbar) -->
|
||||
<button id="sidebarToggleTop" class="btn btn-link d-md-none rounded-circle mr-3">
|
||||
<i class="fa fa-bars"></i>
|
||||
</button>
|
||||
|
||||
|
||||
<!-- Topbar Notification -->
|
||||
<div class="d-none d-sm-inline-block form-inline mr-auto ml-md-3 my-2 my-md-0 mw-100 navbar-search">
|
||||
<ul class="navbar-nav ml-auto">
|
||||
|
||||
<li>
|
||||
<div class="nav-item spinner-border m-3" role="status" style="display:none;" id="spinner">
|
||||
<span class="nav-item sr-only">Loading...</span>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li class="nav-item dropdown no-arrow" id="notificationArea" style="display: none;">
|
||||
<div class="nav-link dropdown-toggle">
|
||||
<span id="notification" class="mr-2 d-none d-lg-inline text-gray-600">Notification</span>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- Topbar Navbar -->
|
||||
<ul class="navbar-nav ml-auto">
|
||||
|
||||
<li class="nav-item dropdown" id="remoteListNav">
|
||||
</li>
|
||||
|
||||
<li class="nav-item dropdown" id="projectListNav">
|
||||
</li>
|
||||
|
||||
<div class="topbar-divider d-none d-sm-block"></div>
|
||||
|
||||
<!-- Nav Item - User Information -->
|
||||
<li class="nav-item dropdown no-arrow">
|
||||
<a class="nav-link dropdown-toggle" href="#" id="userDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
<i class="fas fa-user-circle fa-1x fa-fw mr-2 text-gray-600"></i>
|
||||
<span id="username" class="mr-2 d-none d-lg-inline text-gray-600"></span>
|
||||
</a>
|
||||
<!-- Dropdown - User Information -->
|
||||
<div class="dropdown-menu dropdown-menu-right shadow animated--grow-in" aria-labelledby="userDropdown">
|
||||
<a class="dropdown-item" href="user-profile.html">
|
||||
<i class="fas fa-user fa-sm fa-fw mr-2 text-gray-400"></i>
|
||||
Profile
|
||||
</a>
|
||||
<a class="dropdown-item" href="settings.html">
|
||||
<i class="fas fa-cog fa-sm fa-fw mr-2 text-gray-400"></i>
|
||||
Settings
|
||||
</a>
|
||||
<a class="dropdown-item" href="#" data-toggle="modal" data-target="#aboutModal">
|
||||
<i class="fas fa-info-circle fa-sm fa-fw mr-2 text-gray-400"></i>
|
||||
About
|
||||
</a>
|
||||
<div class="dropdown-divider"></div>
|
||||
<a class="dropdown-item" href="#" onclick="logout()">
|
||||
<i class="fas fa-sign-out-alt fa-sm fa-fw mr-2 text-gray-400"></i>
|
||||
Logout
|
||||
</a>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
|
||||
</nav>
|
||||
<!-- End of Topbar -->
|
||||
|
||||
<!-- Begin Page Content -->
|
||||
<div class="container-fluid">
|
||||
|
||||
<!-- BreadCrumb -->
|
||||
<nav aria-label="breadcrumb">
|
||||
<ol class="breadcrumb">
|
||||
<li class="breadcrumb-item"><a href="#" id="remoteBreadCrumb"></a></li>
|
||||
<li class="breadcrumb-item active" aria-current="page" id="instancesBreadCrumb"></li>
|
||||
</ol>
|
||||
</nav>
|
||||
|
||||
<div class="row">
|
||||
|
||||
<div class="col-12">
|
||||
<!-- Instance List -->
|
||||
<div class="card shadow mb-4">
|
||||
<!-- Card Header - Dropdown -->
|
||||
<div class="card-header py-3 d-flex flex-row align-items-center justify-content-between">
|
||||
<h6 class="m-0 font-weight-bold text-primary">Instances</h6>
|
||||
<div class="dropdown no-arrow">
|
||||
<a class="dropdown-toggle mr-2" href="#" data-toggle="modal" data-target="#createInstanceModal" title="New Instance" aria-hidden="true">
|
||||
<i class="fas fa-plus fa-sm fa-fw"></i> Instance</a>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Card Body -->
|
||||
<div class="card-body">
|
||||
<div class="table-responsive">
|
||||
<table class="table" id="instanceListTable" width="100%" cellspacing="0">
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- End Instance List -->
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<!-- /.container-fluid -->
|
||||
|
||||
</div>
|
||||
<!-- End of Main Content -->
|
||||
|
||||
<!-- Footer -->
|
||||
<footer class="sticky-footer bg-white">
|
||||
<div class="container my-auto">
|
||||
<div class="copyright text-center my-auto">
|
||||
<span>Copyright © lxdware.com 2021</span>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
<!-- End of Footer -->
|
||||
|
||||
</div>
|
||||
<!-- End of Content Wrapper -->
|
||||
|
||||
</div>
|
||||
<!-- End of Page Wrapper -->
|
||||
|
||||
<!-- Scroll to Top Button-->
|
||||
<a class="scroll-to-top rounded" href="#page-top">
|
||||
<i class="fas fa-angle-up"></i>
|
||||
</a>
|
||||
|
||||
<!-- Create Instance Modal-->
|
||||
<div class="modal fade" id="createInstanceModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog modal-lg" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="exampleModalLabel">Create Instance</h5>
|
||||
<button class="close" type="button" data-dismiss="modal" aria-label="Close">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<ul class="nav nav-tabs" id="myTab" role="tablist">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link active" id="form-tab" data-toggle="tab" href="#form" role="tab" aria-controls="form" aria-selected="true">Form</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" id="json-tab" data-toggle="tab" href="#json" role="tab" aria-controls="json" aria-selected="false">JSON</a>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="tab-content" id="myTabContent">
|
||||
<div class="tab-pane fade show active" id="form" role="tabpanel" aria-labelledby="form-tab">
|
||||
<br />
|
||||
<div class="row">
|
||||
<label class="col-3 col-form-label text-right">Name: </label>
|
||||
<div class="col-7">
|
||||
<div class="form-group">
|
||||
<input type="text" id="instanceNameInput" class="form-control" required="required" placeholder="" name="name">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-1">
|
||||
<i class="far fa-sm fa-question-circle text-danger" title='(Required) - Enter in a name for this instance.'></i>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<label class="col-3 col-form-label text-right">Type:</label>
|
||||
<div class="col-7 text-right">
|
||||
<div class="form-group">
|
||||
<select id="selectTypeInput" onchange="changeImageInput()" class="form-control" name="type">
|
||||
<option value="container" selected>container</option>
|
||||
<option value="virtual-machine">virtual-machine</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-1">
|
||||
<i class="far fa-sm fa-question-circle" title='Select which instance type to create, container or virtual machine. Default: container'></i>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<label class="col-3 col-form-label text-right">Image: </label>
|
||||
<div class="col-7">
|
||||
<div class="form-group">
|
||||
<select id="selectImageInput" class="form-control" name="fingerprint">
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-1">
|
||||
<i class="far fa-sm fa-question-circle" title='Select a downloaded image to use to build the instance.'></i>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<label class="col-3 col-form-label text-right">Profile: </label>
|
||||
<div class="col-7">
|
||||
<div class="form-group">
|
||||
<select id="selectProfileInput" class="form-control" name="profile">
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-1">
|
||||
<i class="far fa-sm fa-question-circle" title='Select the initial profile to attach to this instance. Additional profiles can be attached after the instance is created. Default: default'></i>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<label class="col-3 col-form-label text-right">Instance Type: </label>
|
||||
<div class="col-7">
|
||||
<div class="form-group">
|
||||
<select id="selectInstanceTypeInput" class="form-control" name="instance_type">
|
||||
<option value="" selected>(not set)</option>
|
||||
<option disabled>--- AWS Instance Types ---</option>
|
||||
<option value="aws:c1.medium">c1.medium</option>
|
||||
<option value="aws:c1.xlarge">c1.xlarge</option>
|
||||
<option value="aws:c3.2xlarge">c3.2xlarge</option>
|
||||
<option value="aws:c3.4xlarge">c3.4xlarge</option>
|
||||
<option value="aws:c3.8xlarge">c3.8xlarge</option>
|
||||
<option value="aws:c3.large">c3.large</option>
|
||||
<option value="aws:c3.xlarge">c3.xlarge</option>
|
||||
<option value="aws:c4.2xlarge">c4.2xlarge</option>
|
||||
<option value="aws:c4.4xlarge">c4.4xlarge</option>
|
||||
<option value="aws:c4.8xlarge">c4.8xlarge</option>
|
||||
<option value="aws:c4.large">c4.large</option>
|
||||
<option value="aws:c4.xlarge">c4.xlarge</option>
|
||||
<option value="aws:c5.large">c5.large</option>
|
||||
<option value="aws:c5.xlarge">c5.xlarge</option>
|
||||
<option value="aws:c5.2xlarge">c5.2xlarge</option>
|
||||
<option value="aws:c5.4xlarge">c5.4xlarge</option>
|
||||
<option value="aws:c5.9xlarge">c5.9xlarge</option>
|
||||
<option value="aws:c5.18xlarge">c5.18xlarge</option>
|
||||
<option value="aws:cc2.8xlarge">cc2.8xlarge</option>
|
||||
<option value="aws:cg1.4xlarge">cg1.4xlarge</option>
|
||||
<option value="aws:cr1.8xlarge">cr1.8xlarge</option>
|
||||
<option value="aws:d2.xlarge">d2.xlarge</option>
|
||||
<option value="aws:d2.2xlarge">d2.2xlarge</option>
|
||||
<option value="aws:d2.4xlarge">d2.4xlarge</option>
|
||||
<option value="aws:d2.8xlarge">d2.8xlarge</option>
|
||||
<option value="aws:f1.2xlarge">f1.2xlarge</option>
|
||||
<option value="aws:f1.16xlarge">f1.16xlarge</option>
|
||||
<option value="aws:g2.2xlarge">g2.2xlarge</option>
|
||||
<option value="aws:g2.8xlarge">g2.8xlarge</option>
|
||||
<option value="aws:g3.4xlarge">g3.4xlarge</option>
|
||||
<option value="aws:g3.8xlarge">g3.8xlarge</option>
|
||||
<option value="aws:g3.16xlarge">g3.16xlarge</option>
|
||||
<option value="aws:hi1.4xlarge">hi1.4xlarge</option>
|
||||
<option value="aws:hs1.8xlarge">hs1.8xlarge</option>
|
||||
<option value="aws:i2.xlarge">i2.xlarge</option>
|
||||
<option value="aws:i2.2xlarge">i2.2xlarge</option>
|
||||
<option value="aws:i2.4xlarge">i2.4xlarge</option>
|
||||
<option value="aws:i2.8xlarge">i2.8xlarge</option>
|
||||
<option value="aws:i3.large">i3.large</option>
|
||||
<option value="aws:i3.xlarge">i3.xlarge</option>
|
||||
<option value="aws:i3.2xlarge">i3.2xlarge</option>
|
||||
<option value="aws:i3.4xlarge">i3.4xlarge</option>
|
||||
<option value="aws:i3.8xlarge">i3.8xlarge</option>
|
||||
<option value="aws:i3.16xlarge">i3.16xlarge</option>
|
||||
<option value="aws:m1.small">m1.small</option>
|
||||
<option value="aws:m1.medium">m1.medium</option>
|
||||
<option value="aws:m1.large">m1.large</option>
|
||||
<option value="aws:m1.xlarge">m1.xlarge</option>
|
||||
<option value="aws:m2.xlarge">m2.xlarge</option>
|
||||
<option value="aws:m2.2xlarge">m2.2xlarge</option>
|
||||
<option value="aws:m2.4xlarge">m2.4xlarge</option>
|
||||
<option value="aws:m3.medium">m3.medium</option>
|
||||
<option value="aws:m3.large">m3.large</option>
|
||||
<option value="aws:m3.xlarge">m3.xlarge</option>
|
||||
<option value="aws:m3.2xlarge">m3.2xlarge</option>
|
||||
<option value="aws:m4.large">m4.large</option>
|
||||
<option value="aws:m4.xlarge">m4.xlarge</option>
|
||||
<option value="aws:m4.2xlarge">m4.2xlarge</option>
|
||||
<option value="aws:m4.4xlarge">m4.4xlarge</option>
|
||||
<option value="aws:m4.10xlarge">m4.10xlarge</option>
|
||||
<option value="aws:m4.16xlarge">m4.16xlarge</option>
|
||||
<option value="aws:p2.xlarge">p2.xlarge</option>
|
||||
<option value="aws:p2.8xlarge">p2.8xlarge</option>
|
||||
<option value="aws:p2.16xlarge">p2.16xlarge</option>
|
||||
<option value="aws:r3.large">r3.large</option>
|
||||
<option value="aws:r3.xlarge">r3.xlarge</option>
|
||||
<option value="aws:r3.2xlarge">r3.2xlarge</option>
|
||||
<option value="aws:r3.4xlarge">r3.4xlarge</option>
|
||||
<option value="aws:r3.8xlarge">r3.8xlarge</option>
|
||||
<option value="aws:r4.large">r4.large</option>
|
||||
<option value="aws:r4.xlarge">r4.xlarge</option>
|
||||
<option value="aws:r4.2xlarge">r4.2xlarge</option>
|
||||
<option value="aws:r4.4xlarge">r4.4xlarge</option>
|
||||
<option value="aws:r4.8xlarge">r4.8xlarge</option>
|
||||
<option value="aws:r4.16xlarge">r4.16xlarge</option>
|
||||
<option value="aws:t1.micro">t1.micro</option>
|
||||
<option value="aws:t2.nano">t2.nano</option>
|
||||
<option value="aws:t2.micro">t2.micro</option>
|
||||
<option value="aws:t2.small">t2.small</option>
|
||||
<option value="aws:t2.medium">t2.medium</option>
|
||||
<option value="aws:t2.large">t2.large</option>
|
||||
<option value="aws:t2.xlarge">t2.xlarge</option>
|
||||
<option value="aws:t2.2xlarge">t2.2xlarge</option>
|
||||
<option value="aws:t3.nano">t3.nano</option>
|
||||
<option value="aws:t3.micro">t3.micro</option>
|
||||
<option value="aws:t3.small">t3.small</option>
|
||||
<option value="aws:t3.medium">t3.medium</option>
|
||||
<option value="aws:t3.large">t3.large</option>
|
||||
<option value="aws:t3.xlarge">t3.xlarge</option>
|
||||
<option value="aws:t3.2xlarge">t3.2xlarge</option>
|
||||
<option value="aws:x1.16xlarge">x1.16xlarge</option>
|
||||
<option value="aws:x1.32xlarge">x1.32xlarge</option>
|
||||
<option disabled>--- Azure Instance Types ---</option>
|
||||
<option value="azure:A5">A5</option>
|
||||
<option value="azure:A6">A6</option>
|
||||
<option value="azure:A7">A7</option>
|
||||
<option value="azure:A8">A8</option>
|
||||
<option value="azure:A9">A9</option>
|
||||
<option value="azure:A10">A10</option>
|
||||
<option value="azure:A11">A11</option>
|
||||
<option value="azure:ExtraSmall">ExtraSmall</option>
|
||||
<option value="azure:Small">Small</option>
|
||||
<option value="azure:Medium">Medium</option>
|
||||
<option value="azure:Large">Large</option>
|
||||
<option value="azure:ExtraLarge">ExtraLarge</option>
|
||||
<option value="azure:Standard_A1_v2">Standard_A1_v2</option>
|
||||
<option value="azure:Standard_A2m_v2">Standard_A2m_v2</option>
|
||||
<option value="azure:Standard_A2_v2">Standard_A2_v2</option>
|
||||
<option value="azure:Standard_A4m_v2">Standard_A4m_v2</option>
|
||||
<option value="azure:Standard_A4_v2">Standard_A4_v2</option>
|
||||
<option value="azure:Standard_A8m_v2">Standard_A8m_v2</option>
|
||||
<option value="azure:Standard_A8_v2">Standard_A8_v2</option>
|
||||
<option value="azure:Standard_D1">Standard_D1</option>
|
||||
<option value="azure:Standard_D1_v2">Standard_D1_v2</option>
|
||||
<option value="azure:Standard_D2">Standard_D2</option>
|
||||
<option value="azure:Standard_D2_v2">Standard_D2_v2</option>
|
||||
<option value="azure:Standard_D3">Standard_D3</option>
|
||||
<option value="azure:Standard_D3_v2">Standard_D3_v2</option>
|
||||
<option value="azure:Standard_D4">Standard_D4</option>
|
||||
<option value="azure:Standard_D4_v2">Standard_D4_v2</option>
|
||||
<option value="azure:Standard_D5_v2">Standard_D5_v2</option>
|
||||
<option value="azure:Standard_D11">Standard_D11</option>
|
||||
<option value="azure:Standard_D11_v2">Standard_D11_v2</option>
|
||||
<option value="azure:Standard_D12">Standard_D12</option>
|
||||
<option value="azure:Standard_D12_v2">Standard_D12_v2</option>
|
||||
<option value="azure:Standard_D13">Standard_D13</option>
|
||||
<option value="azure:Standard_D13_v2">Standard_D13_v2</option>
|
||||
<option value="azure:Standard_D14">Standard_D14</option>
|
||||
<option value="azure:Standard_D14_v2">Standard_D14_v2</option>
|
||||
<option value="azure:Standard_D15_v2">Standard_D15_v2</option>
|
||||
<option value="azure:Standard_G1">Standard_G1</option>
|
||||
<option value="azure:Standard_G2">Standard_G2</option>
|
||||
<option value="azure:Standard_G3">Standard_G3</option>
|
||||
<option value="azure:Standard_G4">Standard_G4</option>
|
||||
<option value="azure:Standard_G5">Standard_G5</option>
|
||||
<option value="azure:Standard_H8">Standard_H8</option>
|
||||
<option value="azure:Standard_H8m">Standard_H8m</option>
|
||||
<option value="azure:Standard_H16">Standard_H16</option>
|
||||
<option value="azure:Standard_H16m">Standard_H16m</option>
|
||||
<option value="azure:Standard_H16mr">Standard_H16mr</option>
|
||||
<option value="azure:Standard_H16r">Standard_H16r</option>
|
||||
<option disabled>--- GCE Instance Types ---</option>
|
||||
<option value="gce:f1-micro">f1-micro</option>
|
||||
<option value="gce:g1-small">g1-small</option>
|
||||
<option value="gce:n1-highcpu-2">n1-highcpu-2</option>
|
||||
<option value="gce:n1-highcpu-4">n1-highcpu-4</option>
|
||||
<option value="gce:n1-highcpu-8">n1-highcpu-8</option>
|
||||
<option value="gce:n1-highcpu-16">n1-highcpu-16</option>
|
||||
<option value="gce:n1-highcpu-32">n1-highcpu-32</option>
|
||||
<option value="gce:n1-highcpu-64">n1-highcpu-64</option>
|
||||
<option value="gce:n1-highmem-2">n1-highmem-2</option>
|
||||
<option value="gce:n1-highmem-4">n1-highmem-4</option>
|
||||
<option value="gce:n1-highmem-8">n1-highmem-8</option>
|
||||
<option value="gce:n1-highmem-16">n1-highmem-16</option>
|
||||
<option value="gce:n1-highmem-32">n1-highmem-32</option>
|
||||
<option value="gce:n1-highmem-64">n1-highmem-64</option>
|
||||
<option value="gce:n1-standard-1">n1-standard-1</option>
|
||||
<option value="gce:n1-standard-2">n1-standard-2</option>
|
||||
<option value="gce:n1-standard-4">n1-standard-4</option>
|
||||
<option value="gce:n1-standard-8">n1-standard-8</option>
|
||||
<option value="gce:n1-standard-16">n1-standard-16</option>
|
||||
<option value="gce:n1-standard-32">n1-standard-32</option>
|
||||
<option value="gce:n1-standard-64">n1-standard-64</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-1">
|
||||
<i class="far fa-sm fa-question-circle" title='Select from a variety of preconfigured instance configurations. Default: (not set)'></i>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<label class="col-3 col-form-label text-right">Location: </label>
|
||||
<div class="col-7">
|
||||
<div class="form-group">
|
||||
<select id="selectLocationInput" class="form-control" name="location">
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-1">
|
||||
<i class="far fa-sm fa-question-circle" title='Select the LXD cluster member to deploy this instance on. Default: none'></i>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="modal-footer">
|
||||
<button class="btn btn-secondary" type="button" data-dismiss="modal">Cancel</button>
|
||||
<a class="btn btn-primary" href="#" onclick="createInstanceUsingForm()" data-dismiss="modal">Ok</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tab-pane fade" id="json" role="tabpanel" aria-labelledby="json-tab">
|
||||
<br />
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<div class="form-group text-right">
|
||||
<pre>
|
||||
<textarea name="json" class="form-control" id="jsonCreateInput" rows="16" placeholder="Enter JSON data"></textarea>
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button class="btn btn-secondary" type="button" data-dismiss="modal">Cancel</button>
|
||||
<a class="btn btn-primary" href="#" onclick="createInstanceUsingJSON()" data-dismiss="modal">Submit</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- About Modal-->
|
||||
<div class="modal fade" id="aboutModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="exampleModalLabel">About</h5>
|
||||
<button class="close" type="button" data-dismiss="modal" aria-label="Close">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<div id="about"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button class="btn btn-secondary" type="button" data-dismiss="modal">Dismiss</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Bootstrap core JavaScript-->
|
||||
<script src="vendor/jquery/jquery.min.js"></script>
|
||||
<script src="vendor/bootstrap/js/bootstrap.bundle.min.js"></script>
|
||||
|
||||
<!-- Core plugin JavaScript-->
|
||||
<script src="vendor/jquery-easing/jquery.easing.min.js"></script>
|
||||
|
||||
<!-- Custom scripts for all pages-->
|
||||
<script src="vendor/sb-admin-2/js/sb-admin-2.min.js"></script>
|
||||
|
||||
<!-- Page level plugins -->
|
||||
<script src="vendor/datatables/jquery.dataTables.min.js"></script>
|
||||
<script src="vendor/datatables/dataTables.bootstrap4.min.js"></script>
|
||||
|
||||
</body>
|
||||
|
||||
<script>
|
||||
const queryString = window.location.search;
|
||||
const urlParams = new URLSearchParams(queryString);
|
||||
const remoteId = urlParams.get('remote');
|
||||
const projectName = urlParams.get('project');
|
||||
|
||||
function logout(){
|
||||
$.get("./php/aaa/authentication.php?action=deauthenticateUser", function (data) {
|
||||
operationData = JSON.parse(data);
|
||||
console.log(operationData);
|
||||
if (operationData.status_code == 200) {
|
||||
window.location = './index.html'
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function operationStatusCheck(){
|
||||
//check to see if there are any running operations
|
||||
$.get("./php/lxd/operations.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&action=displayOperationStatus", function (data) {
|
||||
//Check to see if we have running operations
|
||||
if (data) {
|
||||
//Display spinner and notification area if there are running tasks
|
||||
$('#spinner').show();
|
||||
$('#notificationArea').show();
|
||||
$('#notification').text(data);
|
||||
//Set the page to check operations again in 1 second
|
||||
setTimeout(() => { operationStatusCheck(); }, 1000);
|
||||
}
|
||||
else {
|
||||
//Hide spinner and notification area if no running tasks
|
||||
$('#spinner').hide();
|
||||
$('#notificationArea').hide();
|
||||
$('#notification').text("");
|
||||
//Set the page to check operations again in 3 seconds
|
||||
setTimeout(() => { operationStatusCheck(); }, 3000);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function reloadPageContent(){
|
||||
|
||||
//Check Authorization
|
||||
$.get("./php/aaa/authentication.php?action=validateAuthentication", function (data) {
|
||||
operationData = JSON.parse(data);
|
||||
if (operationData.status_code != 200) {
|
||||
console.log(operationData);
|
||||
window.location = './index.html'
|
||||
}
|
||||
});
|
||||
|
||||
$('#instanceListTable').DataTable().ajax.reload(null, false);
|
||||
}
|
||||
|
||||
function loadPageContent(){
|
||||
|
||||
//Display current logged in username
|
||||
$("#username").load("./php/admin/settings.php?action=displayUsername");
|
||||
|
||||
$('#instanceListTable').DataTable( {
|
||||
ajax: "./php/lxd/instances.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&action=listInstances",
|
||||
columns: [
|
||||
{},
|
||||
{ title: "Name" },
|
||||
{ title: "OS" },
|
||||
{ title: "Location" },
|
||||
{ title: "IPv4" },
|
||||
{ title: "IPv6" },
|
||||
{ title: "Type" },
|
||||
{ title: "Memory" },
|
||||
{ title: "Root Disk" },
|
||||
{ title: "Status" },
|
||||
{ title: "Action" }
|
||||
],
|
||||
order: [],
|
||||
columnDefs: [
|
||||
{ targets: 0, orderable: false, width: "25px" }
|
||||
]
|
||||
});
|
||||
|
||||
//Check for any running operations
|
||||
operationStatusCheck();
|
||||
|
||||
//Set the page content to reload in 5 seconds
|
||||
setInterval(() => { reloadPageContent(); }, 5000);
|
||||
}
|
||||
|
||||
function createInstanceUsingForm(){
|
||||
var instanceName = $("#instanceNameInput").val();
|
||||
var profileName = $("#selectProfileInput").val();
|
||||
var fingerprint = $("#selectImageInput").val();
|
||||
var type = $("#selectTypeInput").val();
|
||||
var instanceType = $("#selectInstanceTypeInput").val();
|
||||
var location = $("#selectLocationInput").val();
|
||||
console.log("Info: creating instance " + instanceName);
|
||||
$.get("./php/lxd/instances.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&name=" + encodeURI(instanceName) + "&profile=" + encodeURI(profileName) + "&fingerprint=" + encodeURI(fingerprint) + "&type=" + encodeURI(type) + "&instance_type=" + encodeURI(instanceType) + "&location=" + encodeURI(location) + "&action=createInstanceUsingForm", function (data) {
|
||||
//Sync type
|
||||
var operationData = JSON.parse(data);
|
||||
console.log(operationData);
|
||||
if (operationData.error_code >= 400){
|
||||
alert(operationData.error);
|
||||
}
|
||||
setTimeout(() => { reloadPageContent(); }, 1000);
|
||||
});
|
||||
}
|
||||
|
||||
function createInstanceUsingJSON(){
|
||||
var instanceCreateJSON = $("#jsonCreateInput").val();
|
||||
console.log("Info: creating instance");
|
||||
$.post("./php/lxd/instances.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&action=createInstanceUsingJSON", {json: instanceCreateJSON}, function (data) {
|
||||
//Sync type
|
||||
var operationData = JSON.parse(data);
|
||||
console.log(operationData);
|
||||
if (operationData.error_code >= 400){
|
||||
alert(operationData.error);
|
||||
}
|
||||
setTimeout(() => { reloadPageContent(); }, 1000);
|
||||
});
|
||||
}
|
||||
|
||||
function startInstance(instanceName){
|
||||
console.log("Info: starting instance " + instanceName);
|
||||
$.get("./php/lxd/instances.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&instance=" + encodeURI(instanceName) + "&action=startInstance", function (data) {
|
||||
//Async type
|
||||
var operationData = JSON.parse(data);
|
||||
console.log(operationData);
|
||||
if (operationData.error_code >= 400){
|
||||
alert(operationData.error);
|
||||
}
|
||||
operationStatusCheck();
|
||||
setTimeout(() => { reloadPageContent(); }, 1000);
|
||||
});
|
||||
}
|
||||
|
||||
function stopInstance(instanceName){
|
||||
console.log("Info: stopping instance " + instanceName);
|
||||
$.get("./php/lxd/instances.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&instance=" + encodeURI(instanceName) + "&action=stopInstance", function (data) {
|
||||
//Async type
|
||||
var operationData = JSON.parse(data);
|
||||
console.log(operationData);
|
||||
if (operationData.error_code >= 400){
|
||||
alert(operationData.error);
|
||||
}
|
||||
operationStatusCheck();
|
||||
setTimeout(() => { reloadPageContent(); }, 1000);
|
||||
});
|
||||
}
|
||||
|
||||
function unfreezeInstance(instanceName){
|
||||
console.log("Info: unfreezing instance " + instanceName);
|
||||
$.get("./php/lxd/instances.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&instance=" + encodeURI(instanceName) + "&action=unfreezeInstance", function (data) {
|
||||
//Async type
|
||||
var operationData = JSON.parse(data);
|
||||
console.log(operationData);
|
||||
if (operationData.error_code >= 400){
|
||||
alert(operationData.error);
|
||||
}
|
||||
operationStatusCheck();
|
||||
setTimeout(() => { reloadPageContent(); }, 1000);
|
||||
});
|
||||
}
|
||||
|
||||
//If use creates a new instance load the images based on container or virtual-machine selection
|
||||
function changeImageInput(){
|
||||
var imageType = $("#selectTypeInput").val();
|
||||
$("#selectImageInput").load("./php/lxd/images.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&image_type=" + encodeURI(imageType) + "&action=listImagesForSelectOption");
|
||||
}
|
||||
|
||||
$(document).ready(function(){
|
||||
|
||||
//Check Authorization
|
||||
$.get("./php/aaa/authentication.php?action=validateAuthentication", function (data) {
|
||||
operationData = JSON.parse(data);
|
||||
if (operationData.status_code != 200) {
|
||||
console.log(operationData);
|
||||
window.location = './index.html'
|
||||
}
|
||||
});
|
||||
|
||||
//Load in the sidebar
|
||||
$("#sidebarLinks").load("./sidebar.html");
|
||||
|
||||
//Setup Page Breadcrumb Links/Information
|
||||
$('#remoteBreadCrumb').load("./php/lxd/remote-breadcrumb.php?remote=" + encodeURI(remoteId));
|
||||
$('#remoteBreadCrumb').attr("href", "remotes-single.html?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName));
|
||||
$('#instancesBreadCrumb').text("instances");
|
||||
|
||||
//Load the card contents
|
||||
loadPageContent();
|
||||
|
||||
$("#remoteListNav").load("./php/lxd/remotes.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&action=listRemotesForTopNavigation");
|
||||
$("#projectListNav").load("./php/lxd/projects.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&action=listProjectsForTopNavigation");
|
||||
|
||||
//Load the about info for the about modal
|
||||
$.get("./about.html", function (data) {
|
||||
$("#about").html(data);
|
||||
});
|
||||
|
||||
//Populate the select options fields used in modals
|
||||
$("#selectProfileInput").load("./php/lxd/profiles.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&action=listProfilesForSelectOption");
|
||||
$("#selectLocationInput").load("./php/lxd/cluster-members.php?remote=" + encodeURI(remoteId) + "&include_none=true&action=listClusterMembersForSelectOption");
|
||||
|
||||
//Populate initial list of images available for container
|
||||
changeImageInput();
|
||||
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
</html>
|
378
lxd-dashboard/logs.php
Normal file
|
@ -0,0 +1,378 @@
|
|||
<!--
|
||||
LXDWARE LXD Dashboard - A web-based interface for managing LXD servers
|
||||
Copyright (C) 2020-2021 LXDWARE.COM
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
-->
|
||||
|
||||
<!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, shrink-to-fit=no">
|
||||
<meta name="description" content="">
|
||||
<meta name="author" content="">
|
||||
|
||||
<link rel="icon" type="image/png" href="assets/images/logo-light.svg">
|
||||
|
||||
<title>LXD Dashboard</title>
|
||||
|
||||
<!-- Custom fonts for this template-->
|
||||
<link href="vendor/fontawesome-free/css/all.min.css" rel="stylesheet" type="text/css">
|
||||
<link href="vendor/fonts/nunito.css" rel="stylesheet">
|
||||
|
||||
<!-- Custom styles for this template-->
|
||||
<link href="vendor/sb-admin-2/css/sb-admin-2.css" rel="stylesheet">
|
||||
<link href="assets/css/style.css?version=3.0" rel="stylesheet">
|
||||
|
||||
<!-- Custom styles for this page -->
|
||||
<link href="vendor/datatables/dataTables.bootstrap4.min.css" rel="stylesheet">
|
||||
|
||||
</head>
|
||||
|
||||
<body id="page-top">
|
||||
|
||||
<!-- Page Wrapper -->
|
||||
<div id="wrapper">
|
||||
|
||||
<!-- Sidebar -->
|
||||
<ul class="navbar-nav bg-dark sidebar sidebar-dark accordion sidebar-divider-right" id="accordionSidebar">
|
||||
|
||||
<!-- Sidebar - Brand -->
|
||||
<a class="sidebar-brand d-flex align-items-center justify-content-center" href="index.php">
|
||||
<div class="sidebar-brand-icon rotate-n-0">
|
||||
<img src="assets/images/logo-dark.svg" style="width: 2rem;"></img>
|
||||
<!-- <i class="fas fa-cube" style="width: 2rem;"></i> -->
|
||||
</div>
|
||||
<div class="sidebar-brand-text mx-3">LXDWARE</div>
|
||||
</a>
|
||||
|
||||
<!-- Divider -->
|
||||
<hr class="sidebar-divider">
|
||||
|
||||
<!-- Nav Item - Dashboard -->
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="remotes.php">
|
||||
<i class="fas fa-fw fa-server"></i>
|
||||
<span>Hosts</span></a>
|
||||
</li>
|
||||
|
||||
<!-- Divider -->
|
||||
<hr class="sidebar-divider d-none d-md-block">
|
||||
|
||||
<!-- Sidebar Toggler (Sidebar) -->
|
||||
<div class="text-center d-none d-md-inline">
|
||||
<button class="rounded-circle border-0" id="sidebarToggle" onclick="setSidebarToggleValue()"></button>
|
||||
</div>
|
||||
</ul>
|
||||
<!-- End of Sidebar -->
|
||||
|
||||
<!-- Content Wrapper -->
|
||||
<div id="content-wrapper" class="d-flex flex-column">
|
||||
|
||||
<!-- Main Content -->
|
||||
<div id="content">
|
||||
|
||||
<!-- Topbar -->
|
||||
<nav class="navbar navbar-expand navbar-light bg-white topbar mb-4 static-top shadow">
|
||||
|
||||
<!-- Sidebar Toggle (Topbar) -->
|
||||
<button id="sidebarToggleTop" class="btn btn-link d-md-none rounded-circle mr-3">
|
||||
<i class="fa fa-bars"></i>
|
||||
</button>
|
||||
|
||||
<!-- Topbar Navbar -->
|
||||
<ul class="navbar-nav ml-auto">
|
||||
|
||||
<div class="topbar-divider d-none d-sm-block"></div>
|
||||
|
||||
<!-- Nav Item - User Information -->
|
||||
<li class="nav-item dropdown no-arrow">
|
||||
<a class="nav-link dropdown-toggle" href="#" id="userDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
<i class="fas fa-user-circle fa-1x fa-fw mr-2 text-gray-600"></i>
|
||||
<span id="username" class="mr-2 d-none d-lg-inline text-gray-600"></span>
|
||||
</a>
|
||||
<!-- Dropdown - User Information -->
|
||||
<div class="dropdown-menu dropdown-menu-right shadow animated--grow-in" aria-labelledby="userDropdown">
|
||||
<a class="dropdown-item" href="user-profile.php">
|
||||
<i class="fas fa-user fa-sm fa-fw mr-2 text-gray-400"></i>
|
||||
Profile
|
||||
</a>
|
||||
<a class="dropdown-item" href="settings.php">
|
||||
<i class="fas fa-cog fa-sm fa-fw mr-2 text-gray-400"></i>
|
||||
Settings
|
||||
</a>
|
||||
<a class="dropdown-item" href="logs.php">
|
||||
<i class="fas fa-history fa-sm fa-fw mr-2 text-gray-400"></i>
|
||||
Logs
|
||||
</a>
|
||||
<a class="dropdown-item" href="#" data-toggle="modal" data-target="#aboutModal">
|
||||
<i class="fas fa-info-circle fa-sm fa-fw mr-2 text-gray-400"></i>
|
||||
About
|
||||
</a>
|
||||
<div class="dropdown-divider"></div>
|
||||
<a class="dropdown-item" href="#" onclick="logout()">
|
||||
<i class="fas fa-sign-out-alt fa-sm fa-fw mr-2 text-gray-400"></i>
|
||||
Logout
|
||||
</a>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
|
||||
</nav>
|
||||
<!-- End of Topbar -->
|
||||
|
||||
<!-- Begin Page Content -->
|
||||
<div class="container-fluid">
|
||||
|
||||
<header class="page-header page-header-dark bg-gradient-primary-to-secondary">
|
||||
<div class="container-xl px-4">
|
||||
<div class="page-header-content pt-4">
|
||||
<div class="row align-items-center justify-content-between mt-n5 ml-n5 mr-n5 bg-dark pb-6">
|
||||
<div class="col-auto mt-4 ml-3">
|
||||
<div class="page-header-subtitle">
|
||||
<span id="remoteBreadCrumb">LXD Dashboard</span>
|
||||
</div>
|
||||
<h2 class="page-header-title mt-2">
|
||||
LOGS
|
||||
</h2>
|
||||
<div class="page-header-subtitle">
|
||||
View LXD Dashboard event logs
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-xl-auto mt-4">
|
||||
<div class="input-group input-group-joined border-0" style="width: 14rem">
|
||||
<span class="input-group-text bg-transparent border-0">
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<div class="row mt-n5 ml-2 mr-2">
|
||||
|
||||
<div class="col-12 mt-n3">
|
||||
<!-- Logs List -->
|
||||
<div class="card shadow mb-4">
|
||||
<!-- Card Header - Dropdown -->
|
||||
<div class="card-header py-3 d-flex flex-row align-items-center justify-content-between">
|
||||
<h6 class="m-0 font-weight-bold">
|
||||
<span class="ml-1">Logs</span>
|
||||
</h6>
|
||||
<div class="dropdown no-arrow">
|
||||
<a class="dropdown-toggle mr-2" href="#" onclick="reloadPageContent()" title="Refresh" aria-hidden="true">
|
||||
<i class="fa fa-sync fa-1x fa-fw"></i></a>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Card Body -->
|
||||
<div class="card-body">
|
||||
<div class="table-responsive">
|
||||
<table class="table" id="eventLogTable" width="100%" cellspacing="0">
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- End Logs List -->
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<!-- /.container-fluid -->
|
||||
|
||||
</div>
|
||||
<!-- End of Main Content -->
|
||||
|
||||
<!-- Footer -->
|
||||
<footer class="sticky-footer bg-white">
|
||||
<div class="container my-auto">
|
||||
<div class="copyright text-center my-auto">
|
||||
<span>Copyright © LXDWARE 2020 - Present</span>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
<!-- End of Footer -->
|
||||
|
||||
</div>
|
||||
<!-- End of Content Wrapper -->
|
||||
|
||||
</div>
|
||||
<!-- End of Page Wrapper -->
|
||||
|
||||
<!-- Scroll to Top Button-->
|
||||
<a class="scroll-to-top rounded" href="#page-top">
|
||||
<i class="fas fa-angle-up"></i>
|
||||
</a>
|
||||
|
||||
<!-- About Modal-->
|
||||
<div class="modal fade" id="aboutModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="exampleModalLabel">About</h5>
|
||||
<button class="close" type="button" data-dismiss="modal" aria-label="Close">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<div id="about"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button class="btn btn-secondary" type="button" data-dismiss="modal">Dismiss</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Bootstrap core JavaScript-->
|
||||
<script src="vendor/jquery/jquery.min.js"></script>
|
||||
<script src="vendor/bootstrap/js/bootstrap.bundle.min.js"></script>
|
||||
|
||||
<!-- Core plugin JavaScript-->
|
||||
<script src="vendor/jquery-easing/jquery.easing.min.js"></script>
|
||||
|
||||
<!-- Custom scripts for all pages-->
|
||||
<script src="vendor/sb-admin-2/js/sb-admin-2.min.js"></script>
|
||||
|
||||
<!-- Page level plugins -->
|
||||
<script src="vendor/datatables/jquery.dataTables.min.js"></script>
|
||||
<script src="vendor/datatables/dataTables.bootstrap4.min.js"></script>
|
||||
|
||||
</body>
|
||||
|
||||
<script>
|
||||
var reloadTime = 5000;
|
||||
|
||||
function logout(){
|
||||
$.get("./backend/aaa/authentication.php?action=deauthenticateUser", function (data) {
|
||||
operationData = JSON.parse(data);
|
||||
console.log(operationData);
|
||||
if (operationData.status_code == 200) {
|
||||
window.location.href = './index.php'
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function reloadPageContent() {
|
||||
|
||||
clearTimeout(pageReloadTimeout);
|
||||
|
||||
//Check Authorization
|
||||
$.get("./backend/aaa/authentication.php?action=validateAuthentication", function (data) {
|
||||
operationData = JSON.parse(data);
|
||||
if (operationData.status_code != 200) {
|
||||
console.log(operationData);
|
||||
window.location.href = './index.php'
|
||||
}
|
||||
});
|
||||
|
||||
$('#eventLogTable').DataTable().ajax.reload(null, false);
|
||||
|
||||
//Set reload page content
|
||||
pageReloadTimeout = setTimeout(() => { reloadPageContent(); }, reloadTime);
|
||||
}
|
||||
|
||||
function loadPageContent(){
|
||||
|
||||
//Display current logged in username
|
||||
$("#username").load("./backend/admin/settings.php?action=displayUsername");
|
||||
|
||||
$('#eventLogTable').DataTable( {
|
||||
ajax: "./backend/admin/logs.php?action=listLogEvents",
|
||||
columns: [
|
||||
{},
|
||||
{ title: "ID" },
|
||||
{ title: "Control" },
|
||||
{ title: "RemoteID" },
|
||||
{ title: "Project" },
|
||||
{ title: "Object" },
|
||||
{ title: "Status Code" },
|
||||
{ title: "Message" },
|
||||
{ title: "Hostname" },
|
||||
{ title: "UserID" },
|
||||
{ title: "Date" }
|
||||
],
|
||||
order: [1, "desc" ],
|
||||
columnDefs: [
|
||||
{ targets: 0, orderable: false, width: "25px" }
|
||||
]
|
||||
});
|
||||
|
||||
//Set reload page content
|
||||
$.get("./backend/admin/settings.php?action=retrievePageRefreshRateValues", function (data) {
|
||||
operationData = JSON.parse(data);
|
||||
if (operationData.logs_page_rate >= 1)
|
||||
reloadTime = operationData.logs_page_rate * 1000;
|
||||
pageReloadTimeout = setTimeout(() => { reloadPageContent(); }, reloadTime);
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
function setSidebarToggleValue(){
|
||||
sidebarState = localStorage.getItem('sidebarState');
|
||||
if (sidebarState == "collapsed"){
|
||||
localStorage.setItem('sidebarState','expanded');
|
||||
}
|
||||
else {
|
||||
localStorage.setItem('sidebarState','collapsed');
|
||||
}
|
||||
}
|
||||
|
||||
function applySidebarToggleValue() {
|
||||
sidebarState = localStorage.getItem('sidebarState');
|
||||
if (sidebarState == "collapsed"){
|
||||
$("body").toggleClass("sidebar-toggled"),
|
||||
$(".sidebar").toggleClass("toggled"),
|
||||
$(".sidebar").hasClass("toggled") && $(".sidebar .collapse").collapse("hide")
|
||||
}
|
||||
}
|
||||
|
||||
applySidebarToggleValue();
|
||||
|
||||
$(document).ready(function(){
|
||||
|
||||
//Check Authorization
|
||||
$.get("./backend/aaa/authentication.php?action=validateAuthentication", function (data) {
|
||||
operationData = JSON.parse(data);
|
||||
if (operationData.status_code != 200) {
|
||||
console.log(operationData);
|
||||
window.location.href = './index.php'
|
||||
}
|
||||
});
|
||||
|
||||
//Load the card contents
|
||||
loadPageContent();
|
||||
|
||||
//Load the about info for the about modal
|
||||
$.get("./backend/config/about.php", function (data) {
|
||||
$("#about").html(data);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
</html>
|
|
@ -37,7 +37,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
|
||||
<!-- Custom styles for this template-->
|
||||
<link href="vendor/sb-admin-2/css/sb-admin-2.css" rel="stylesheet">
|
||||
<link href="assets/css/style.css" rel="stylesheet">
|
||||
<link href="assets/css/style.css?version=3.0" rel="stylesheet">
|
||||
|
||||
<!-- Custom styles for this page -->
|
||||
<link href="vendor/datatables/dataTables.bootstrap4.min.css" rel="stylesheet">
|
||||
|
@ -50,7 +50,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
<div id="wrapper">
|
||||
|
||||
<!-- Sidebar -->
|
||||
<ul class="navbar-nav bg-dark sidebar sidebar-dark accordion" id="accordionSidebar">
|
||||
<ul class="navbar-nav bg-dark sidebar sidebar-dark accordion sidebar-divider-right" id="accordionSidebar">
|
||||
|
||||
<div id="sidebarLinks"></div>
|
||||
|
||||
|
@ -59,12 +59,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
|
||||
<!-- Sidebar Toggler (Sidebar) -->
|
||||
<div class="text-center d-none d-md-inline">
|
||||
<button class="rounded-circle border-0" id="sidebarToggle"></button>
|
||||
<button class="rounded-circle border-0" id="sidebarToggle" onclick="setSidebarToggleValue()"></button>
|
||||
</div>
|
||||
</ul>
|
||||
<!-- End of Sidebar -->
|
||||
|
||||
|
||||
<!-- Content Wrapper -->
|
||||
<div id="content-wrapper" class="d-flex flex-column">
|
||||
|
||||
|
@ -79,37 +78,31 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
<i class="fa fa-bars"></i>
|
||||
</button>
|
||||
|
||||
<!-- Topbar Navbar -->
|
||||
<ul class="navbar-nav ml-auto">
|
||||
|
||||
<!-- Topbar Notification -->
|
||||
<div class="d-none d-sm-inline-block form-inline mr-auto ml-md-3 my-2 my-md-0 mw-100 navbar-search">
|
||||
<ul class="navbar-nav ml-auto">
|
||||
<li class="nav-item dropdown">
|
||||
<label class="h6 mt-4 mr-2 ml-4">Host: </label>
|
||||
</li>
|
||||
<li class="nav-item dropdown">
|
||||
<div class="input-group mt-3">
|
||||
<select class="form-control" id="remoteListNav" style="width:150px;" onchange="location = this.value;">
|
||||
</select>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<div class="nav-item spinner-border m-3" role="status" style="display:none;" id="spinner">
|
||||
<span class="nav-item sr-only">Loading...</span>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li class="nav-item dropdown no-arrow" id="notificationArea" style="display: none;">
|
||||
<div class="nav-link dropdown-toggle">
|
||||
<span id="notification" class="mr-2 d-none d-lg-inline text-gray-600">Notification</span>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
<li class="nav-item dropdown">
|
||||
<label class="h6 mt-4 mr-2 ml-4">Project: </label>
|
||||
</li>
|
||||
<li class="nav-item dropdown">
|
||||
<div class="input-group mt-3">
|
||||
<select class="form-control" id="projectListNav" style="width:150px;" onchange="location = this.value;">
|
||||
</select>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
|
||||
<!-- Topbar Navbar -->
|
||||
<ul class="navbar-nav ml-auto">
|
||||
|
||||
<li class="nav-item dropdown" id="remoteListNav">
|
||||
</li>
|
||||
|
||||
<li class="nav-item dropdown" id="projectListNav">
|
||||
</li>
|
||||
|
||||
<div class="topbar-divider d-none d-sm-block"></div>
|
||||
<!-- Nav Divider -->
|
||||
<div class="topbar-divider d-none d-sm-block"></div>
|
||||
|
||||
<!-- Nav Item - User Information -->
|
||||
<li class="nav-item dropdown no-arrow">
|
||||
|
@ -119,14 +112,18 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
</a>
|
||||
<!-- Dropdown - User Information -->
|
||||
<div class="dropdown-menu dropdown-menu-right shadow animated--grow-in" aria-labelledby="userDropdown">
|
||||
<a class="dropdown-item" href="user-profile.html">
|
||||
<a class="dropdown-item" href="user-profile.php">
|
||||
<i class="fas fa-user fa-sm fa-fw mr-2 text-gray-400"></i>
|
||||
Profile
|
||||
</a>
|
||||
<a class="dropdown-item" href="settings.html">
|
||||
<a class="dropdown-item" href="settings.php">
|
||||
<i class="fas fa-cog fa-sm fa-fw mr-2 text-gray-400"></i>
|
||||
Settings
|
||||
</a>
|
||||
<a class="dropdown-item" href="logs.php">
|
||||
<i class="fas fa-history fa-sm fa-fw mr-2 text-gray-400"></i>
|
||||
Logs
|
||||
</a>
|
||||
<a class="dropdown-item" href="#" data-toggle="modal" data-target="#aboutModal">
|
||||
<i class="fas fa-info-circle fa-sm fa-fw mr-2 text-gray-400"></i>
|
||||
About
|
||||
|
@ -147,26 +144,50 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
<!-- Begin Page Content -->
|
||||
<div class="container-fluid">
|
||||
|
||||
<!-- BreadCrumb -->
|
||||
<nav aria-label="breadcrumb">
|
||||
<ol class="breadcrumb">
|
||||
<li class="breadcrumb-item"><a href="#" id="remoteBreadCrumb"></a></li>
|
||||
<li class="breadcrumb-item"><a href="#" id="networkAclsBreadCrumb"></a></li>
|
||||
<li class="breadcrumb-item active" aria-current="page" id="networkAclBreadCrumb"></li>
|
||||
</ol>
|
||||
</nav>
|
||||
<header class="page-header page-header-dark bg-gradient-primary-to-secondary">
|
||||
<div class="container-xl px-4">
|
||||
<div class="page-header-content pt-4">
|
||||
<div class="row align-items-center justify-content-between mt-n5 ml-n5 mr-n5 bg-dark pb-6">
|
||||
<div class="col-auto mt-4 ml-3">
|
||||
<div class="page-header-subtitle">
|
||||
<a href="#" id="remoteBreadCrumb"></a>
|
||||
/
|
||||
<a href="#" id="networkAclsBreadCrumb"></a>
|
||||
</div>
|
||||
<h2 class="page-header-title mt-2">
|
||||
<span id="networkAclBreadCrumb"></span> - Egress Rules
|
||||
</h2>
|
||||
<div class="page-header-subtitle">
|
||||
Create and manage network egress rules
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-xl-auto mt-4">
|
||||
<div class="input-group input-group-joined border-0" style="width: 14rem">
|
||||
<span class="input-group-text bg-transparent border-0">
|
||||
<a class="btn btn-outline-primary" href="#" data-toggle="modal" data-target="#addTrafficRuleModal" title="Add Traffic Rule" aria-hidden="true">
|
||||
<i class="fas fa-plus fa-sm fa-fw"></i> Rule
|
||||
</a>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<div class="row">
|
||||
<div class="row mt-n5 ml-2 mr-2">
|
||||
|
||||
<div class="col-12">
|
||||
<!-- Egress Rules -->
|
||||
<div class="col-12 mt-n3">
|
||||
<!-- Egress Rules List -->
|
||||
<div class="card shadow mb-4">
|
||||
<!-- Card Header - Dropdown -->
|
||||
<div class="card-header py-3 d-flex flex-row align-items-center justify-content-between">
|
||||
<h6 class="m-0 font-weight-bold text-primary">Egress Rules</h6>
|
||||
<h6 class="m-0 font-weight-bold">
|
||||
<span class="ml-1">Egress Rules</span>
|
||||
</h6>
|
||||
<div class="dropdown no-arrow">
|
||||
<a class="dropdown-toggle mr-2" href="#" data-toggle="modal" data-target="#addTrafficRuleModal" title="Add Traffic Rule" aria-hidden="true">
|
||||
<i class="fas fa-plus fa-sm fa-fw"></i> Rule</a>
|
||||
<a class="dropdown-toggle mr-2" href="#" onclick="reloadPageContent()" title="Refresh" aria-hidden="true">
|
||||
<i class="fa fa-sync fa-1x fa-fw"></i></a>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Card Body -->
|
||||
|
@ -177,7 +198,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- End Egress Rules -->
|
||||
<!-- End Egress Rules List -->
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
@ -192,7 +213,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
<footer class="sticky-footer bg-white">
|
||||
<div class="container my-auto">
|
||||
<div class="copyright text-center my-auto">
|
||||
<span>Copyright © lxdware.com 2021</span>
|
||||
<span>Copyright © LXDWARE 2020 - Present</span>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
|
@ -222,7 +243,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
<div class="modal-body">
|
||||
|
||||
<div class="row">
|
||||
<label class="col-3 col-form-label text-right">Action: </label>
|
||||
<label class="col-3 col-form-label text-right">Action: <span class="text-danger">*</span></label>
|
||||
<div class="col-7">
|
||||
<div class="form-group">
|
||||
<select id="actionTrafficRuleInput" onchange="" class="form-control" name="actionTrafficRuleInput">
|
||||
|
@ -233,12 +254,12 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
</div>
|
||||
</div>
|
||||
<div class="col-1">
|
||||
<i class="far fa-sm fa-question-circle text-danger" title='(Required) - Select the action to be applied to this rule.'></i>
|
||||
<i class="far fa-sm fa-question-circle" title='(Required) - Select the action to be applied to this rule.'></i>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<label class="col-3 col-form-label text-right">State: </label>
|
||||
<label class="col-3 col-form-label text-right">State: <span class="text-danger">*</span></label>
|
||||
<div class="col-7">
|
||||
<div class="form-group">
|
||||
<select id="stateTrafficRuleInput" onchange="" class="form-control" name="stateTrafficRuleInput">
|
||||
|
@ -249,7 +270,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
</div>
|
||||
</div>
|
||||
<div class="col-1">
|
||||
<i class="far fa-sm fa-question-circle text-danger" title='(Required) - Select the state to be applied to this rule.'></i>
|
||||
<i class="far fa-sm fa-question-circle" title='(Required) - Select the state to be applied to this rule.'></i>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -410,61 +431,66 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
const remoteId = urlParams.get('remote');
|
||||
const projectName = urlParams.get('project');
|
||||
const networkAcl = urlParams.get('network_acl');
|
||||
var reloadTime = 5000;
|
||||
|
||||
function logout(){
|
||||
$.get("./php/aaa/authentication.php?action=deauthenticateUser", function (data) {
|
||||
$.get("./backend/aaa/authentication.php?action=deauthenticateUser", function (data) {
|
||||
operationData = JSON.parse(data);
|
||||
console.log(operationData);
|
||||
if (operationData.status_code == 200) {
|
||||
window.location = './index.html'
|
||||
window.location.href = './index.php'
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function operationStatusCheck(){
|
||||
clearTimeout(operationTimeout);
|
||||
//check to see if there are any running operations
|
||||
$.get("./php/lxd/operations.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&action=displayOperationStatus", function (data) {
|
||||
$.get("./backend/lxd/operations.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&action=displayOperationStatus", function (data) {
|
||||
//Check to see if we have running operations
|
||||
if (data){
|
||||
//Display spinner and notification area if there are running tasks
|
||||
$('#spinner').show();
|
||||
if (data) {
|
||||
//Display notification area if there are running tasks
|
||||
$('#notificationArea').show();
|
||||
$('#notification').text(data);
|
||||
//Set the page to check operations again in 1 second
|
||||
setTimeout(() => { operationStatusCheck(); }, 1000);
|
||||
$('#notification').text("Notice: " + data);
|
||||
//Set the page to check operations again in 2 seconds
|
||||
operationTimeout = setTimeout(() => { operationStatusCheck(); }, 2000);
|
||||
}
|
||||
else {
|
||||
//Hide spinner and notification area if no running tasks
|
||||
$('#spinner').hide();
|
||||
//Hide notification area if no running tasks
|
||||
$('#notificationArea').hide();
|
||||
$('#notification').text("");
|
||||
//Set the page to check operations again in 3 seconds
|
||||
setTimeout(() => { operationStatusCheck(); }, 3000);
|
||||
//Set the page to check operations again in 4 seconds
|
||||
operationTimeout = setTimeout(() => { operationStatusCheck(); }, 4000);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function reloadPageContent() {
|
||||
|
||||
clearTimeout(pageReloadTimeout);
|
||||
|
||||
//Check Authorization
|
||||
$.get("./php/aaa/authentication.php?action=validateAuthentication", function (data) {
|
||||
$.get("./backend/aaa/authentication.php?action=validateAuthentication", function (data) {
|
||||
operationData = JSON.parse(data);
|
||||
if (operationData.status_code != 200) {
|
||||
console.log(operationData);
|
||||
window.location = './index.html'
|
||||
window.location.href = './index.php'
|
||||
}
|
||||
});
|
||||
|
||||
$('#egressListTable').DataTable().ajax.reload(null, false);
|
||||
|
||||
//Set reload page content
|
||||
pageReloadTimeout = setTimeout(() => { reloadPageContent(); }, reloadTime);
|
||||
}
|
||||
|
||||
function loadPageContent(){
|
||||
|
||||
//Display current logged in username
|
||||
$("#username").load("./php/admin/settings.php?action=displayUsername");
|
||||
$("#username").load("./backend/admin/settings.php?action=displayUsername");
|
||||
|
||||
$('#egressListTable').DataTable( {
|
||||
ajax: "./php/lxd/network-acls.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&network_acl=" + encodeURI(networkAcl) + "&action=listEgressRules",
|
||||
ajax: "./backend/lxd/network-acls.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&network_acl=" + encodeURI(networkAcl) + "&action=listEgressRules",
|
||||
columns: [
|
||||
{},
|
||||
{ title: "Action" },
|
||||
|
@ -486,10 +512,16 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
});
|
||||
|
||||
//Check for any running operations
|
||||
operationStatusCheck();
|
||||
operationTimeout = setTimeout(() => { operationStatusCheck(); }, 1000);
|
||||
|
||||
//Set reload page content
|
||||
$.get("./backend/admin/settings.php?action=retrievePageRefreshRateValues", function (data) {
|
||||
operationData = JSON.parse(data);
|
||||
if (operationData.network_acls_page_rate >= 1)
|
||||
reloadTime = operationData.network_acls_page_rate * 1000;
|
||||
pageReloadTimeout = setTimeout(() => { reloadPageContent(); }, reloadTime);
|
||||
});
|
||||
|
||||
//Set the page content to reload in 5 seconds
|
||||
setInterval(() => { reloadPageContent(); }, 5000);
|
||||
}
|
||||
|
||||
function addTrafficRule(){
|
||||
|
@ -505,7 +537,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
var icmpTypeTrafficRuleInput = $("#icmpTypeTrafficRuleInput").val();
|
||||
var icmpCodeTrafficRuleInput = $("#icmpCodeTrafficRuleInput").val();
|
||||
console.log("Info: adding " + typeTrafficRuleInput + " rule ");
|
||||
$.get("./php/lxd/network-acls.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&network_acl=" + encodeURI(networkAcl) + "&type=" + encodeURI(typeTrafficRuleInput) + "&traffic_action=" + encodeURI(actionTrafficRuleInput) + "&state=" + encodeURI(stateTrafficRuleInput) + "&description=" + encodeURI(descriptionTrafficRuleInput) + "&source=" + encodeURI(sourceTrafficRuleInput) + "&destination=" + encodeURI(destinationTrafficRuleInput) + "&protocol=" + encodeURI(protocolTrafficRuleInput) + "&source_port=" + encodeURI(sourcePortTrafficRuleInput) + "&destination_port=" + encodeURI(destinationPortTrafficRuleInput) + "&icmp_type=" + encodeURI(icmpTypeTrafficRuleInput) + "&icmp_code=" + encodeURI(icmpCodeTrafficRuleInput) + "&action=addTrafficRule", function (data) {
|
||||
$.get("./backend/lxd/network-acls.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&network_acl=" + encodeURI(networkAcl) + "&type=" + encodeURI(typeTrafficRuleInput) + "&traffic_action=" + encodeURI(actionTrafficRuleInput) + "&state=" + encodeURI(stateTrafficRuleInput) + "&description=" + encodeURI(descriptionTrafficRuleInput) + "&source=" + encodeURI(sourceTrafficRuleInput) + "&destination=" + encodeURI(destinationTrafficRuleInput) + "&protocol=" + encodeURI(protocolTrafficRuleInput) + "&source_port=" + encodeURI(sourcePortTrafficRuleInput) + "&destination_port=" + encodeURI(destinationPortTrafficRuleInput) + "&icmp_type=" + encodeURI(icmpTypeTrafficRuleInput) + "&icmp_code=" + encodeURI(icmpCodeTrafficRuleInput) + "&action=addTrafficRule", function (data) {
|
||||
//Sync operation type
|
||||
var operationData = JSON.parse(data);
|
||||
console.log(operationData);
|
||||
|
@ -518,7 +550,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
|
||||
function deleteEgressRule(egressRuleToDelete){
|
||||
console.log("Info: deleting egress rule " + egressRuleToDelete);
|
||||
$.get("./php/lxd/network-acls.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&network_acl=" + encodeURI(networkAcl) + "&rule=" + encodeURI(egressRuleToDelete) + "&action=deleteEgressRule", function (data) {
|
||||
$.get("./backend/lxd/network-acls.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&network_acl=" + encodeURI(networkAcl) + "&rule=" + encodeURI(egressRuleToDelete) + "&action=deleteEgressRule", function (data) {
|
||||
//Sync type
|
||||
var operationData = JSON.parse(data);
|
||||
console.log(operationData);
|
||||
|
@ -529,36 +561,67 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
});
|
||||
}
|
||||
|
||||
function setSidebarToggleValue(){
|
||||
sidebarState = localStorage.getItem('sidebarState');
|
||||
if (sidebarState == "collapsed"){
|
||||
localStorage.setItem('sidebarState','expanded');
|
||||
}
|
||||
else {
|
||||
localStorage.setItem('sidebarState','collapsed');
|
||||
}
|
||||
}
|
||||
|
||||
function applySidebarToggleValue() {
|
||||
sidebarState = localStorage.getItem('sidebarState');
|
||||
if (sidebarState == "collapsed"){
|
||||
$("body").toggleClass("sidebar-toggled"),
|
||||
$(".sidebar").toggleClass("toggled"),
|
||||
$(".sidebar").hasClass("toggled") && $(".sidebar .collapse").collapse("hide")
|
||||
}
|
||||
}
|
||||
|
||||
applySidebarToggleValue();
|
||||
|
||||
$(document).ready(function(){
|
||||
|
||||
//Check Authorization
|
||||
$.get("./php/aaa/authentication.php?action=validateAuthentication", function (data) {
|
||||
$.get("./backend/aaa/authentication.php?action=validateAuthentication", function (data) {
|
||||
operationData = JSON.parse(data);
|
||||
if (operationData.status_code != 200) {
|
||||
console.log(operationData);
|
||||
window.location = './index.html'
|
||||
window.location.href = './index.php'
|
||||
}
|
||||
});
|
||||
|
||||
//Load in the sidebar
|
||||
$("#sidebarLinks").load("./sidebar.html");
|
||||
$("#sidebarLinks").load("./sidebar.php?version=3.0");
|
||||
|
||||
//Setup Page Breadcrumb Links/Information
|
||||
$('#remoteBreadCrumb').load("./php/lxd/remote-breadcrumb.php?remote=" + encodeURI(remoteId));
|
||||
$('#remoteBreadCrumb').attr("href", "remotes-single.html?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName));
|
||||
$('#remoteBreadCrumb').load("./backend/lxd/remote-breadcrumb.php?remote=" + encodeURI(remoteId));
|
||||
$('#remoteBreadCrumb').attr("href", "remotes-single.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName));
|
||||
$('#networkAclsBreadCrumb').text("network-acls");
|
||||
$('#networkAclsBreadCrumb').attr("href", "network-acls.html?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName));
|
||||
$('#networkAclsBreadCrumb').attr("href", "network-acls.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName));
|
||||
$('#networkAclBreadCrumb').text(networkAcl);
|
||||
|
||||
//Load the card contents
|
||||
loadPageContent();
|
||||
//Validate remote host connection returns 200 status
|
||||
$.get("./backend/lxd/remotes-single.php?remote=" + encodeURI(remoteId) + "&action=validateRemoteConnection", function (data) {
|
||||
operationData = JSON.parse(data);
|
||||
console.log(operationData);
|
||||
if (operationData.status_code == 200) {
|
||||
//Set top navbar dropdowns
|
||||
$("#remoteListNav").load("./backend/lxd/remotes.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&action=listRemotesForSelectOption");
|
||||
$("#projectListNav").load("./backend/lxd/projects.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&action=listProjectsForSelectOption");
|
||||
|
||||
//Load Page Content
|
||||
loadPageContent();
|
||||
}
|
||||
else {
|
||||
alert("Unable to connect to remote host. HTTP status code: " + operationData.status_code);
|
||||
}
|
||||
});
|
||||
|
||||
$("#remoteListNav").load("./php/lxd/remotes.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&action=listRemotesForTopNavigation");
|
||||
$("#projectListNav").load("./php/lxd/projects.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&action=listProjectsForTopNavigation");
|
||||
|
||||
//Load the about info for the about modal
|
||||
$.get("./about.html", function (data) {
|
||||
$.get("./backend/config/about.php", function (data) {
|
||||
$("#about").html(data);
|
||||
});
|
||||
|
|
@ -37,7 +37,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
|
||||
<!-- Custom styles for this template-->
|
||||
<link href="vendor/sb-admin-2/css/sb-admin-2.css" rel="stylesheet">
|
||||
<link href="assets/css/style.css" rel="stylesheet">
|
||||
<link href="assets/css/style.css?version=3.0" rel="stylesheet">
|
||||
|
||||
<!-- Custom styles for this page -->
|
||||
<link href="vendor/datatables/dataTables.bootstrap4.min.css" rel="stylesheet">
|
||||
|
@ -50,7 +50,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
<div id="wrapper">
|
||||
|
||||
<!-- Sidebar -->
|
||||
<ul class="navbar-nav bg-dark sidebar sidebar-dark accordion" id="accordionSidebar">
|
||||
<ul class="navbar-nav bg-dark sidebar sidebar-dark accordion sidebar-divider-right" id="accordionSidebar">
|
||||
|
||||
<div id="sidebarLinks"></div>
|
||||
|
||||
|
@ -59,12 +59,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
|
||||
<!-- Sidebar Toggler (Sidebar) -->
|
||||
<div class="text-center d-none d-md-inline">
|
||||
<button class="rounded-circle border-0" id="sidebarToggle"></button>
|
||||
<button class="rounded-circle border-0" id="sidebarToggle" onclick="setSidebarToggleValue()"></button>
|
||||
</div>
|
||||
</ul>
|
||||
<!-- End of Sidebar -->
|
||||
|
||||
|
||||
<!-- Content Wrapper -->
|
||||
<div id="content-wrapper" class="d-flex flex-column">
|
||||
|
||||
|
@ -79,37 +78,31 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
<i class="fa fa-bars"></i>
|
||||
</button>
|
||||
|
||||
<!-- Topbar Navbar -->
|
||||
<ul class="navbar-nav ml-auto">
|
||||
|
||||
<!-- Topbar Notification -->
|
||||
<div class="d-none d-sm-inline-block form-inline mr-auto ml-md-3 my-2 my-md-0 mw-100 navbar-search">
|
||||
<ul class="navbar-nav ml-auto">
|
||||
<li class="nav-item dropdown">
|
||||
<label class="h6 mt-4 mr-2 ml-4">Host: </label>
|
||||
</li>
|
||||
<li class="nav-item dropdown">
|
||||
<div class="input-group mt-3">
|
||||
<select class="form-control" id="remoteListNav" style="width:150px;" onchange="location = this.value;">
|
||||
</select>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<div class="nav-item spinner-border m-3" role="status" style="display:none;" id="spinner">
|
||||
<span class="nav-item sr-only">Loading...</span>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li class="nav-item dropdown no-arrow" id="notificationArea" style="display: none;">
|
||||
<div class="nav-link dropdown-toggle">
|
||||
<span id="notification" class="mr-2 d-none d-lg-inline text-gray-600">Notification</span>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
<li class="nav-item dropdown">
|
||||
<label class="h6 mt-4 mr-2 ml-4">Project: </label>
|
||||
</li>
|
||||
<li class="nav-item dropdown">
|
||||
<div class="input-group mt-3">
|
||||
<select class="form-control" id="projectListNav" style="width:150px;" onchange="location = this.value;">
|
||||
</select>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
|
||||
<!-- Topbar Navbar -->
|
||||
<ul class="navbar-nav ml-auto">
|
||||
|
||||
<li class="nav-item dropdown" id="remoteListNav">
|
||||
</li>
|
||||
|
||||
<li class="nav-item dropdown" id="projectListNav">
|
||||
</li>
|
||||
|
||||
<div class="topbar-divider d-none d-sm-block"></div>
|
||||
<!-- Nav Divider -->
|
||||
<div class="topbar-divider d-none d-sm-block"></div>
|
||||
|
||||
<!-- Nav Item - User Information -->
|
||||
<li class="nav-item dropdown no-arrow">
|
||||
|
@ -119,14 +112,18 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
</a>
|
||||
<!-- Dropdown - User Information -->
|
||||
<div class="dropdown-menu dropdown-menu-right shadow animated--grow-in" aria-labelledby="userDropdown">
|
||||
<a class="dropdown-item" href="user-profile.html">
|
||||
<a class="dropdown-item" href="user-profile.php">
|
||||
<i class="fas fa-user fa-sm fa-fw mr-2 text-gray-400"></i>
|
||||
Profile
|
||||
</a>
|
||||
<a class="dropdown-item" href="settings.html">
|
||||
<a class="dropdown-item" href="settings.php">
|
||||
<i class="fas fa-cog fa-sm fa-fw mr-2 text-gray-400"></i>
|
||||
Settings
|
||||
</a>
|
||||
<a class="dropdown-item" href="logs.php">
|
||||
<i class="fas fa-history fa-sm fa-fw mr-2 text-gray-400"></i>
|
||||
Logs
|
||||
</a>
|
||||
<a class="dropdown-item" href="#" data-toggle="modal" data-target="#aboutModal">
|
||||
<i class="fas fa-info-circle fa-sm fa-fw mr-2 text-gray-400"></i>
|
||||
About
|
||||
|
@ -147,26 +144,50 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
<!-- Begin Page Content -->
|
||||
<div class="container-fluid">
|
||||
|
||||
<!-- BreadCrumb -->
|
||||
<nav aria-label="breadcrumb">
|
||||
<ol class="breadcrumb">
|
||||
<li class="breadcrumb-item"><a href="#" id="remoteBreadCrumb"></a></li>
|
||||
<li class="breadcrumb-item"><a href="#" id="networkAclsBreadCrumb"></a></li>
|
||||
<li class="breadcrumb-item active" aria-current="page" id="networkAclBreadCrumb"></li>
|
||||
</ol>
|
||||
</nav>
|
||||
<header class="page-header page-header-dark bg-gradient-primary-to-secondary">
|
||||
<div class="container-xl px-4">
|
||||
<div class="page-header-content pt-4">
|
||||
<div class="row align-items-center justify-content-between mt-n5 ml-n5 mr-n5 bg-dark pb-6">
|
||||
<div class="col-auto mt-4 ml-3">
|
||||
<div class="page-header-subtitle">
|
||||
<a href="#" id="remoteBreadCrumb"></a>
|
||||
/
|
||||
<a href="#" id="networkAclsBreadCrumb"></a>
|
||||
</div>
|
||||
<h2 class="page-header-title mt-2">
|
||||
<span id="networkAclBreadCrumb"></span> - Ingress Rules
|
||||
</h2>
|
||||
<div class="page-header-subtitle">
|
||||
Create and manage network ingress rules
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-xl-auto mt-4">
|
||||
<div class="input-group input-group-joined border-0" style="width: 14rem">
|
||||
<span class="input-group-text bg-transparent border-0">
|
||||
<a class="btn btn-outline-primary" href="#" data-toggle="modal" data-target="#addTrafficRuleModal" title="Add Traffic Rule" aria-hidden="true">
|
||||
<i class="fas fa-plus fa-sm fa-fw"></i> Rule
|
||||
</a>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<div class="row">
|
||||
<div class="row mt-n5 ml-2 mr-2">
|
||||
|
||||
<div class="col-12">
|
||||
<!-- Ingress Rules -->
|
||||
<div class="col-12 mt-n3">
|
||||
<!-- Ingress Rules List -->
|
||||
<div class="card shadow mb-4">
|
||||
<!-- Card Header - Dropdown -->
|
||||
<div class="card-header py-3 d-flex flex-row align-items-center justify-content-between">
|
||||
<h6 class="m-0 font-weight-bold text-primary">Ingress Rules</h6>
|
||||
<h6 class="m-0 font-weight-bold">
|
||||
<span class="ml-1">Ingress Rules</span>
|
||||
</h6>
|
||||
<div class="dropdown no-arrow">
|
||||
<a class="dropdown-toggle mr-2" href="#" data-toggle="modal" data-target="#addTrafficRuleModal" title="Add Traffic Rule" aria-hidden="true">
|
||||
<i class="fas fa-plus fa-sm fa-fw"></i> Rule</a>
|
||||
<a class="dropdown-toggle mr-2" href="#" onclick="reloadPageContent()" title="Refresh" aria-hidden="true">
|
||||
<i class="fa fa-sync fa-1x fa-fw"></i></a>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Card Body -->
|
||||
|
@ -177,7 +198,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- End Ingress Rules -->
|
||||
<!-- End Ingress Rules List -->
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
@ -192,7 +213,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
<footer class="sticky-footer bg-white">
|
||||
<div class="container my-auto">
|
||||
<div class="copyright text-center my-auto">
|
||||
<span>Copyright © lxdware.com 2021</span>
|
||||
<span>Copyright © LXDWARE 2020 - Present</span>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
|
@ -222,7 +243,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
<div class="modal-body">
|
||||
|
||||
<div class="row">
|
||||
<label class="col-3 col-form-label text-right">Action: </label>
|
||||
<label class="col-3 col-form-label text-right">Action: <span class="text-danger">*</span></label>
|
||||
<div class="col-7">
|
||||
<div class="form-group">
|
||||
<select id="actionTrafficRuleInput" onchange="" class="form-control" name="actionTrafficRuleInput">
|
||||
|
@ -233,12 +254,12 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
</div>
|
||||
</div>
|
||||
<div class="col-1">
|
||||
<i class="far fa-sm fa-question-circle text-danger" title='(Required) - Select the action to be applied to this rule.'></i>
|
||||
<i class="far fa-sm fa-question-circle" title='(Required) - Select the action to be applied to this rule.'></i>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<label class="col-3 col-form-label text-right">State: </label>
|
||||
<label class="col-3 col-form-label text-right">State: <span class="text-danger">*</span></label>
|
||||
<div class="col-7">
|
||||
<div class="form-group">
|
||||
<select id="stateTrafficRuleInput" onchange="" class="form-control" name="stateTrafficRuleInput">
|
||||
|
@ -249,7 +270,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
</div>
|
||||
</div>
|
||||
<div class="col-1">
|
||||
<i class="far fa-sm fa-question-circle text-danger" title='(Required) - Select the state to be applied to this rule.'></i>
|
||||
<i class="far fa-sm fa-question-circle" title='(Required) - Select the state to be applied to this rule.'></i>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -410,61 +431,66 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
const remoteId = urlParams.get('remote');
|
||||
const projectName = urlParams.get('project');
|
||||
const networkAcl = urlParams.get('network_acl');
|
||||
var reloadTime = 5000;
|
||||
|
||||
function logout(){
|
||||
$.get("./php/aaa/authentication.php?action=deauthenticateUser", function (data) {
|
||||
$.get("./backend/aaa/authentication.php?action=deauthenticateUser", function (data) {
|
||||
operationData = JSON.parse(data);
|
||||
console.log(operationData);
|
||||
if (operationData.status_code == 200) {
|
||||
window.location = './index.html'
|
||||
window.location.href = './index.php'
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function operationStatusCheck(){
|
||||
clearTimeout(operationTimeout);
|
||||
//check to see if there are any running operations
|
||||
$.get("./php/lxd/operations.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&action=displayOperationStatus", function (data) {
|
||||
$.get("./backend/lxd/operations.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&action=displayOperationStatus", function (data) {
|
||||
//Check to see if we have running operations
|
||||
if (data){
|
||||
//Display spinner and notification area if there are running tasks
|
||||
$('#spinner').show();
|
||||
if (data) {
|
||||
//Display notification area if there are running tasks
|
||||
$('#notificationArea').show();
|
||||
$('#notification').text(data);
|
||||
//Set the page to check operations again in 1 second
|
||||
setTimeout(() => { operationStatusCheck(); }, 1000);
|
||||
$('#notification').text("Notice: " + data);
|
||||
//Set the page to check operations again in 2 seconds
|
||||
operationTimeout = setTimeout(() => { operationStatusCheck(); }, 2000);
|
||||
}
|
||||
else {
|
||||
//Hide spinner and notification area if no running tasks
|
||||
$('#spinner').hide();
|
||||
//Hide notification area if no running tasks
|
||||
$('#notificationArea').hide();
|
||||
$('#notification').text("");
|
||||
//Set the page to check operations again in 3 seconds
|
||||
setTimeout(() => { operationStatusCheck(); }, 3000);
|
||||
//Set the page to check operations again in 4 seconds
|
||||
operationTimeout = setTimeout(() => { operationStatusCheck(); }, 4000);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function reloadPageContent() {
|
||||
|
||||
clearTimeout(pageReloadTimeout);
|
||||
|
||||
//Check Authorization
|
||||
$.get("./php/aaa/authentication.php?action=validateAuthentication", function (data) {
|
||||
$.get("./backend/aaa/authentication.php?action=validateAuthentication", function (data) {
|
||||
operationData = JSON.parse(data);
|
||||
if (operationData.status_code != 200) {
|
||||
console.log(operationData);
|
||||
window.location = './index.html'
|
||||
window.location.href = './index.php'
|
||||
}
|
||||
});
|
||||
|
||||
$('#ingressListTable').DataTable().ajax.reload(null, false);
|
||||
|
||||
//Set reload page content
|
||||
pageReloadTimeout = setTimeout(() => { reloadPageContent(); }, reloadTime);
|
||||
}
|
||||
|
||||
function loadPageContent(){
|
||||
|
||||
//Display current logged in username
|
||||
$("#username").load("./php/admin/settings.php?action=displayUsername");
|
||||
$("#username").load("./backend/admin/settings.php?action=displayUsername");
|
||||
|
||||
$('#ingressListTable').DataTable( {
|
||||
ajax: "./php/lxd/network-acls.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&network_acl=" + encodeURI(networkAcl) + "&action=listIngressRules",
|
||||
ajax: "./backend/lxd/network-acls.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&network_acl=" + encodeURI(networkAcl) + "&action=listIngressRules",
|
||||
columns: [
|
||||
{},
|
||||
{ title: "Action" },
|
||||
|
@ -486,10 +512,16 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
});
|
||||
|
||||
//Check for any running operations
|
||||
operationStatusCheck();
|
||||
operationTimeout = setTimeout(() => { operationStatusCheck(); }, 1000);
|
||||
|
||||
//Set reload page content
|
||||
$.get("./backend/admin/settings.php?action=retrievePageRefreshRateValues", function (data) {
|
||||
operationData = JSON.parse(data);
|
||||
if (operationData.network_acls_page_rate >= 1)
|
||||
reloadTime = operationData.network_acls_page_rate * 1000;
|
||||
pageReloadTimeout = setTimeout(() => { reloadPageContent(); }, reloadTime);
|
||||
});
|
||||
|
||||
//Set the page content to reload in 5 seconds
|
||||
setInterval(() => { reloadPageContent(); }, 5000);
|
||||
}
|
||||
|
||||
function addTrafficRule(){
|
||||
|
@ -505,7 +537,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
var icmpTypeTrafficRuleInput = $("#icmpTypeTrafficRuleInput").val();
|
||||
var icmpCodeTrafficRuleInput = $("#icmpCodeTrafficRuleInput").val();
|
||||
console.log("Info: adding " + typeTrafficRuleInput + " rule ");
|
||||
$.get("./php/lxd/network-acls.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&network_acl=" + encodeURI(networkAcl) + "&type=" + encodeURI(typeTrafficRuleInput) + "&traffic_action=" + encodeURI(actionTrafficRuleInput) + "&state=" + encodeURI(stateTrafficRuleInput) + "&description=" + encodeURI(descriptionTrafficRuleInput) + "&source=" + encodeURI(sourceTrafficRuleInput) + "&destination=" + encodeURI(destinationTrafficRuleInput) + "&protocol=" + encodeURI(protocolTrafficRuleInput) + "&source_port=" + encodeURI(sourcePortTrafficRuleInput) + "&destination_port=" + encodeURI(destinationPortTrafficRuleInput) + "&icmp_type=" + encodeURI(icmpTypeTrafficRuleInput) + "&icmp_code=" + encodeURI(icmpCodeTrafficRuleInput) + "&action=addTrafficRule", function (data) {
|
||||
$.get("./backend/lxd/network-acls.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&network_acl=" + encodeURI(networkAcl) + "&type=" + encodeURI(typeTrafficRuleInput) + "&traffic_action=" + encodeURI(actionTrafficRuleInput) + "&state=" + encodeURI(stateTrafficRuleInput) + "&description=" + encodeURI(descriptionTrafficRuleInput) + "&source=" + encodeURI(sourceTrafficRuleInput) + "&destination=" + encodeURI(destinationTrafficRuleInput) + "&protocol=" + encodeURI(protocolTrafficRuleInput) + "&source_port=" + encodeURI(sourcePortTrafficRuleInput) + "&destination_port=" + encodeURI(destinationPortTrafficRuleInput) + "&icmp_type=" + encodeURI(icmpTypeTrafficRuleInput) + "&icmp_code=" + encodeURI(icmpCodeTrafficRuleInput) + "&action=addTrafficRule", function (data) {
|
||||
//Sync operation type
|
||||
var operationData = JSON.parse(data);
|
||||
console.log(operationData);
|
||||
|
@ -518,7 +550,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
|
||||
function deleteIngressRule(ingressRuleToDelete){
|
||||
console.log("Info: deleting ingress rule " + ingressRuleToDelete);
|
||||
$.get("./php/lxd/network-acls.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&network_acl=" + encodeURI(networkAcl) + "&rule=" + encodeURI(ingressRuleToDelete) + "&action=deleteIngressRule", function (data) {
|
||||
$.get("./backend/lxd/network-acls.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&network_acl=" + encodeURI(networkAcl) + "&rule=" + encodeURI(ingressRuleToDelete) + "&action=deleteIngressRule", function (data) {
|
||||
//Sync type
|
||||
var operationData = JSON.parse(data);
|
||||
console.log(operationData);
|
||||
|
@ -529,36 +561,67 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
});
|
||||
}
|
||||
|
||||
function setSidebarToggleValue(){
|
||||
sidebarState = localStorage.getItem('sidebarState');
|
||||
if (sidebarState == "collapsed"){
|
||||
localStorage.setItem('sidebarState','expanded');
|
||||
}
|
||||
else {
|
||||
localStorage.setItem('sidebarState','collapsed');
|
||||
}
|
||||
}
|
||||
|
||||
function applySidebarToggleValue() {
|
||||
sidebarState = localStorage.getItem('sidebarState');
|
||||
if (sidebarState == "collapsed"){
|
||||
$("body").toggleClass("sidebar-toggled"),
|
||||
$(".sidebar").toggleClass("toggled"),
|
||||
$(".sidebar").hasClass("toggled") && $(".sidebar .collapse").collapse("hide")
|
||||
}
|
||||
}
|
||||
|
||||
applySidebarToggleValue();
|
||||
|
||||
$(document).ready(function(){
|
||||
|
||||
//Check Authorization
|
||||
$.get("./php/aaa/authentication.php?action=validateAuthentication", function (data) {
|
||||
$.get("./backend/aaa/authentication.php?action=validateAuthentication", function (data) {
|
||||
operationData = JSON.parse(data);
|
||||
if (operationData.status_code != 200) {
|
||||
console.log(operationData);
|
||||
window.location = './index.html'
|
||||
window.location.href = './index.php'
|
||||
}
|
||||
});
|
||||
|
||||
//Load in the sidebar
|
||||
$("#sidebarLinks").load("./sidebar.html");
|
||||
$("#sidebarLinks").load("./sidebar.php?version=3.0");
|
||||
|
||||
//Setup Page Breadcrumb Links/Information
|
||||
$('#remoteBreadCrumb').load("./php/lxd/remote-breadcrumb.php?remote=" + encodeURI(remoteId));
|
||||
$('#remoteBreadCrumb').attr("href", "remotes-single.html?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName));
|
||||
$('#remoteBreadCrumb').load("./backend/lxd/remote-breadcrumb.php?remote=" + encodeURI(remoteId));
|
||||
$('#remoteBreadCrumb').attr("href", "remotes-single.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName));
|
||||
$('#networkAclsBreadCrumb').text("network-acls");
|
||||
$('#networkAclsBreadCrumb').attr("href", "network-acls.html?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName));
|
||||
$('#networkAclsBreadCrumb').attr("href", "network-acls.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName));
|
||||
$('#networkAclBreadCrumb').text(networkAcl);
|
||||
|
||||
//Load the card contents
|
||||
loadPageContent();
|
||||
//Validate remote host connection returns 200 status
|
||||
$.get("./backend/lxd/remotes-single.php?remote=" + encodeURI(remoteId) + "&action=validateRemoteConnection", function (data) {
|
||||
operationData = JSON.parse(data);
|
||||
console.log(operationData);
|
||||
if (operationData.status_code == 200) {
|
||||
//Set top navbar dropdowns
|
||||
$("#remoteListNav").load("./backend/lxd/remotes.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&action=listRemotesForSelectOption");
|
||||
$("#projectListNav").load("./backend/lxd/projects.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&action=listProjectsForSelectOption");
|
||||
|
||||
//Load Page Content
|
||||
loadPageContent();
|
||||
}
|
||||
else {
|
||||
alert("Unable to connect to remote host. HTTP status code: " + operationData.status_code);
|
||||
}
|
||||
});
|
||||
|
||||
$("#remoteListNav").load("./php/lxd/remotes.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&action=listRemotesForTopNavigation");
|
||||
$("#projectListNav").load("./php/lxd/projects.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&action=listProjectsForTopNavigation");
|
||||
|
||||
//Load the about info for the about modal
|
||||
$.get("./about.html", function (data) {
|
||||
$.get("./backend/config/about.php", function (data) {
|
||||
$("#about").html(data);
|
||||
});
|
||||
|
|
@ -37,7 +37,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
|
||||
<!-- Custom styles for this template-->
|
||||
<link href="vendor/sb-admin-2/css/sb-admin-2.css" rel="stylesheet">
|
||||
<link href="assets/css/style.css" rel="stylesheet">
|
||||
<link href="assets/css/style.css?version=3.0" rel="stylesheet">
|
||||
|
||||
<!-- Custom styles for this page -->
|
||||
<link href="vendor/datatables/dataTables.bootstrap4.min.css" rel="stylesheet">
|
||||
|
@ -50,7 +50,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
<div id="wrapper">
|
||||
|
||||
<!-- Sidebar -->
|
||||
<ul class="navbar-nav bg-dark sidebar sidebar-dark accordion" id="accordionSidebar">
|
||||
<ul class="navbar-nav bg-dark sidebar sidebar-dark accordion sidebar-divider-right" id="accordionSidebar">
|
||||
|
||||
<div id="sidebarLinks"></div>
|
||||
|
||||
|
@ -59,7 +59,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
|
||||
<!-- Sidebar Toggler (Sidebar) -->
|
||||
<div class="text-center d-none d-md-inline">
|
||||
<button class="rounded-circle border-0" id="sidebarToggle"></button>
|
||||
<button class="rounded-circle border-0" id="sidebarToggle" onclick="setSidebarToggleValue()"></button>
|
||||
</div>
|
||||
</ul>
|
||||
<!-- End of Sidebar -->
|
||||
|
@ -79,37 +79,44 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
<i class="fa fa-bars"></i>
|
||||
</button>
|
||||
|
||||
|
||||
<!-- Topbar Notification -->
|
||||
<div class="d-none d-sm-inline-block form-inline mr-auto ml-md-3 my-2 my-md-0 mw-100 navbar-search">
|
||||
<!-- Topbar Notification -->
|
||||
<div class="d-none d-sm-inline-block form-inline mr-auto ml-md-3 my-2 my-md-0 mw-100 navbar-search">
|
||||
<ul class="navbar-nav ml-auto">
|
||||
|
||||
<li>
|
||||
<div class="nav-item spinner-border m-3" role="status" style="display:none;" id="spinner">
|
||||
<span class="nav-item sr-only">Loading...</span>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li class="nav-item dropdown no-arrow" id="notificationArea" style="display: none;">
|
||||
<div class="nav-link dropdown-toggle">
|
||||
<span id="notification" class="mr-2 d-none d-lg-inline text-gray-600">Notification</span>
|
||||
<span id="notification" class="mr-2 d-none d-lg-inline text-danger">Notification</span>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<!-- Topbar Navbar -->
|
||||
<ul class="navbar-nav ml-auto">
|
||||
|
||||
<!-- Topbar Navbar -->
|
||||
<ul class="navbar-nav ml-auto">
|
||||
<li class="nav-item dropdown">
|
||||
<label class="h6 mt-4 mr-2 ml-4">Host: </label>
|
||||
</li>
|
||||
<li class="nav-item dropdown">
|
||||
<div class="input-group mt-3">
|
||||
<select class="form-control" id="remoteListNav" style="width:150px;" onchange="location = this.value;">
|
||||
</select>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li class="nav-item dropdown" id="remoteListNav">
|
||||
</li>
|
||||
<li class="nav-item dropdown">
|
||||
<label class="h6 mt-4 mr-2 ml-4">Project: </label>
|
||||
</li>
|
||||
<li class="nav-item dropdown">
|
||||
<div class="input-group mt-3">
|
||||
<select class="form-control" id="projectListNav" style="width:150px;" onchange="location = this.value;">
|
||||
</select>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li class="nav-item dropdown" id="projectListNav">
|
||||
</li>
|
||||
|
||||
<div class="topbar-divider d-none d-sm-block"></div>
|
||||
<!-- Nav Divider -->
|
||||
<div class="topbar-divider d-none d-sm-block"></div>
|
||||
|
||||
<!-- Nav Item - User Information -->
|
||||
<li class="nav-item dropdown no-arrow">
|
||||
|
@ -119,14 +126,18 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
</a>
|
||||
<!-- Dropdown - User Information -->
|
||||
<div class="dropdown-menu dropdown-menu-right shadow animated--grow-in" aria-labelledby="userDropdown">
|
||||
<a class="dropdown-item" href="user-profile.html">
|
||||
<a class="dropdown-item" href="user-profile.php">
|
||||
<i class="fas fa-user fa-sm fa-fw mr-2 text-gray-400"></i>
|
||||
Profile
|
||||
</a>
|
||||
<a class="dropdown-item" href="settings.html">
|
||||
<a class="dropdown-item" href="settings.php">
|
||||
<i class="fas fa-cog fa-sm fa-fw mr-2 text-gray-400"></i>
|
||||
Settings
|
||||
</a>
|
||||
<a class="dropdown-item" href="logs.php">
|
||||
<i class="fas fa-history fa-sm fa-fw mr-2 text-gray-400"></i>
|
||||
Logs
|
||||
</a>
|
||||
<a class="dropdown-item" href="#" data-toggle="modal" data-target="#aboutModal">
|
||||
<i class="fas fa-info-circle fa-sm fa-fw mr-2 text-gray-400"></i>
|
||||
About
|
||||
|
@ -147,25 +158,48 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
<!-- Begin Page Content -->
|
||||
<div class="container-fluid">
|
||||
|
||||
<!-- BreadCrumb -->
|
||||
<nav aria-label="breadcrumb">
|
||||
<ol class="breadcrumb">
|
||||
<li class="breadcrumb-item"><a href="#" id="remoteBreadCrumb"></a></li>
|
||||
<li class="breadcrumb-item active" aria-current="page" id="networkAclsBreadCrumb"></li>
|
||||
</ol>
|
||||
</nav>
|
||||
<header class="page-header page-header-dark bg-gradient-primary-to-secondary">
|
||||
<div class="container-xl px-4">
|
||||
<div class="page-header-content pt-4">
|
||||
<div class="row align-items-center justify-content-between mt-n5 ml-n5 mr-n5 bg-dark pb-6">
|
||||
<div class="col-auto mt-4 ml-3">
|
||||
<div class="page-header-subtitle">
|
||||
<a href="#" id="remoteBreadCrumb"></a>
|
||||
</div>
|
||||
<h2 class="page-header-title mt-2">
|
||||
NETWORK ACLS
|
||||
</h2>
|
||||
<div class="page-header-subtitle">
|
||||
Create and manage network access control lists
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-xl-auto mt-4">
|
||||
<div class="input-group input-group-joined border-0" style="width: 14rem">
|
||||
<span class="input-group-text bg-transparent border-0">
|
||||
<a class="btn btn-outline-primary" href="#" data-toggle="modal" data-target="#createNetworkAclModal" title="New Network ACL" aria-hidden="true">
|
||||
<i class="fas fa-plus fa-sm fa-fw"></i> Network ACL
|
||||
</a>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<div class="row">
|
||||
<div class="row mt-n5 ml-2 mr-2">
|
||||
|
||||
<div class="col-12">
|
||||
<div class="col-12 mt-n3">
|
||||
<!-- Network ACL List -->
|
||||
<div class="card shadow mb-4">
|
||||
<!-- Card Header - Dropdown -->
|
||||
<div class="card-header py-3 d-flex flex-row align-items-center justify-content-between">
|
||||
<h6 class="m-0 font-weight-bold text-primary">Network ACLs</h6>
|
||||
<h6 class="m-0 font-weight-bold">
|
||||
<span class="ml-1">Network ACLs</span>
|
||||
</h6>
|
||||
<div class="dropdown no-arrow">
|
||||
<a class="dropdown-toggle mr-2" href="#" data-toggle="modal" data-target="#createNetworkAclModal" title="New Network ACL" aria-hidden="true">
|
||||
<i class="fas fa-plus fa-sm fa-fw"></i> Network ACL</a>
|
||||
<a class="dropdown-toggle mr-2" href="#" onclick="reloadPageContent()" title="Refresh" aria-hidden="true">
|
||||
<i class="fa fa-sync fa-1x fa-fw"></i></a>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Card Body -->
|
||||
|
@ -191,7 +225,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
<footer class="sticky-footer bg-white">
|
||||
<div class="container my-auto">
|
||||
<div class="copyright text-center my-auto">
|
||||
<span>Copyright © lxdware.com 2021</span>
|
||||
<span>Copyright © LXDWARE 2020 - Present</span>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
|
@ -231,14 +265,14 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
<div class="tab-pane fade show active" id="form" role="tabpanel" aria-labelledby="form-tab">
|
||||
<br />
|
||||
<div class="row">
|
||||
<label class="col-3 col-form-label text-right">Name: </label>
|
||||
<label class="col-3 col-form-label text-right">Name: <span class="text-danger">*</span></label>
|
||||
<div class="col-7">
|
||||
<div class="form-group">
|
||||
<input type="text" id="networkAclNameCreate" class="form-control" placeholder="" name="network_acl_name">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-1">
|
||||
<i class="far fa-sm fa-question-circle text-danger" title='(Required) - Enter a name for the Network ACL'></i>
|
||||
<i class="far fa-sm fa-question-circle" title='(Required) - Enter a name for the Network ACL'></i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
|
@ -322,14 +356,14 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="row">
|
||||
<label class="col-3 col-form-label text-right" id="newNetworkAclNameLabel">Name:</label>
|
||||
<label class="col-3 col-form-label text-right" id="newNetworkAclNameLabel">Name: <span class="text-danger">*</span></label>
|
||||
<div class="col-7">
|
||||
<div class="form-group">
|
||||
<input type="text" id="newNetworkAclName" class="form-control" placeholder="">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-1">
|
||||
<i class="far fa-sm fa-question-circle text-danger" title='(Required) - Enter in a new name for the Network ACL'></i>
|
||||
<i class="far fa-sm fa-question-circle" title='(Required) - Enter in a new name for the Network ACL'></i>
|
||||
</div>
|
||||
</div>
|
||||
<input type="hidden" id ="networkAclToRename" name="networkAclToRename">
|
||||
|
@ -388,61 +422,66 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
const remoteId = urlParams.get('remote');
|
||||
const projectName = urlParams.get('project');
|
||||
var networkAclToUpdate = "";
|
||||
var reloadTime = 5000;
|
||||
|
||||
function logout(){
|
||||
$.get("./php/aaa/authentication.php?action=deauthenticateUser", function (data) {
|
||||
$.get("./backend/aaa/authentication.php?action=deauthenticateUser", function (data) {
|
||||
operationData = JSON.parse(data);
|
||||
console.log(operationData);
|
||||
if (operationData.status_code == 200) {
|
||||
window.location = './index.html'
|
||||
window.location.href = './index.php'
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function operationStatusCheck(){
|
||||
clearTimeout(operationTimeout);
|
||||
//check to see if there are any running operations
|
||||
$.get("./php/lxd/operations.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&action=displayOperationStatus", function (data) {
|
||||
$.get("./backend/lxd/operations.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&action=displayOperationStatus", function (data) {
|
||||
//Check to see if we have running operations
|
||||
if (data){
|
||||
//Display spinner and notification area if there are running tasks
|
||||
$('#spinner').show();
|
||||
if (data) {
|
||||
//Display notification area if there are running tasks
|
||||
$('#notificationArea').show();
|
||||
$('#notification').text(data);
|
||||
//Set the page to check operations again in 1 second
|
||||
setTimeout(() => { operationStatusCheck(); }, 1000);
|
||||
$('#notification').text("Notice: " + data);
|
||||
//Set the page to check operations again in 2 seconds
|
||||
operationTimeout = setTimeout(() => { operationStatusCheck(); }, 2000);
|
||||
}
|
||||
else {
|
||||
//Hide spinner and notification area if no running tasks
|
||||
$('#spinner').hide();
|
||||
//Hide notification area if no running tasks
|
||||
$('#notificationArea').hide();
|
||||
$('#notification').text("");
|
||||
//Set the page to check operations again in 3 seconds
|
||||
setTimeout(() => { operationStatusCheck(); }, 3000);
|
||||
//Set the page to check operations again in 4 seconds
|
||||
operationTimeout = setTimeout(() => { operationStatusCheck(); }, 4000);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function reloadPageContent() {
|
||||
|
||||
clearTimeout(pageReloadTimeout);
|
||||
|
||||
//Check Authorization
|
||||
$.get("./php/aaa/authentication.php?action=validateAuthentication", function (data) {
|
||||
$.get("./backend/aaa/authentication.php?action=validateAuthentication", function (data) {
|
||||
operationData = JSON.parse(data);
|
||||
if (operationData.status_code != 200) {
|
||||
console.log(operationData);
|
||||
window.location = './index.html'
|
||||
window.location.href = './index.php'
|
||||
}
|
||||
});
|
||||
|
||||
$('#networkAclListTable').DataTable().ajax.reload(null, false);
|
||||
|
||||
//Set reload page content
|
||||
pageReloadTimeout = setTimeout(() => { reloadPageContent(); }, reloadTime);
|
||||
}
|
||||
|
||||
function loadPageContent(){
|
||||
|
||||
//Display current logged in username
|
||||
$("#username").load("./php/admin/settings.php?action=displayUsername");
|
||||
$("#username").load("./backend/admin/settings.php?action=displayUsername");
|
||||
|
||||
$('#networkAclListTable').DataTable( {
|
||||
ajax: "./php/lxd/network-acls.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&action=listNetworkAcls",
|
||||
ajax: "./backend/lxd/network-acls.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&action=listNetworkAcls",
|
||||
columns: [
|
||||
{},
|
||||
{ title: "Name" },
|
||||
|
@ -459,17 +498,23 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
});
|
||||
|
||||
//Check for any running operations
|
||||
operationStatusCheck();
|
||||
operationTimeout = setTimeout(() => { operationStatusCheck(); }, 1000);
|
||||
|
||||
//Set reload page content
|
||||
$.get("./backend/admin/settings.php?action=retrievePageRefreshRateValues", function (data) {
|
||||
operationData = JSON.parse(data);
|
||||
if (operationData.network_acls_page_rate >= 1)
|
||||
reloadTime = operationData.network_acls_page_rate * 1000;
|
||||
pageReloadTimeout = setTimeout(() => { reloadPageContent(); }, reloadTime);
|
||||
});
|
||||
|
||||
//Set the page content to reload in 5 seconds
|
||||
setInterval(() => { reloadPageContent(); }, 5000);
|
||||
}
|
||||
|
||||
function createNetworkAclUsingForm(){
|
||||
var networkAclNameCreate = $("#networkAclNameCreate").val();
|
||||
var networkAclDescriptionCreate = $("#networkAclDescriptionCreate").val();
|
||||
console.log("Info: creating network acl");
|
||||
$.get("./php/lxd/network-acls.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&name=" + encodeURI(networkAclNameCreate) + "&description=" + encodeURI(networkAclDescriptionCreate) + "&action=createNetworkAclUsingForm", function (data) {
|
||||
$.get("./backend/lxd/network-acls.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&name=" + encodeURI(networkAclNameCreate) + "&description=" + encodeURI(networkAclDescriptionCreate) + "&action=createNetworkAclUsingForm", function (data) {
|
||||
//Async type
|
||||
var operationData = JSON.parse(data);
|
||||
console.log(operationData);
|
||||
|
@ -484,7 +529,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
function createNetworkAclUsingJSON(){
|
||||
var networkAclCreateJSON = $("#jsonCreateInput").val();
|
||||
console.log("Info: creating network acl");
|
||||
$.post("./php/lxd/network-acls.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&action=createNetworkAclUsingJSON", {json: networkAclCreateJSON}, function (data) {
|
||||
$.post("./backend/lxd/network-acls.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&action=createNetworkAclUsingJSON", {json: networkAclCreateJSON}, function (data) {
|
||||
//Async type
|
||||
var operationData = JSON.parse(data);
|
||||
console.log(operationData);
|
||||
|
@ -496,11 +541,10 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
});
|
||||
}
|
||||
|
||||
//Called by Edit action, loads JSON data of network acl
|
||||
function loadNetworkAclJson(networkAclToLoad){
|
||||
console.log("Info: loading network acl " + networkAclToLoad);
|
||||
networkAclToUpdate = networkAclToLoad;
|
||||
$.get("./php/lxd/network-acls.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&network_acl=" + encodeURI(networkAclToLoad) + "&action=loadNetworkAcl", function (data) {
|
||||
$.get("./backend/lxd/network-acls.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&network_acl=" + encodeURI(networkAclToLoad) + "&action=loadNetworkAcl", function (data) {
|
||||
//Sync type
|
||||
var operationData = JSON.parse(data);
|
||||
console.log(operationData);
|
||||
|
@ -523,7 +567,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
function updateNetworkAcl(){
|
||||
var networkAclUpdateJSON = $("#jsonEditInput").val();
|
||||
console.log("Info: updating network acl " + networkAclToUpdate);
|
||||
$.post("./php/lxd/network-acls.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&network_acl=" + encodeURI(networkAclToUpdate) + "&action=updateNetworkAcl", {json: networkAclUpdateJSON}, function (data) {
|
||||
$.post("./backend/lxd/network-acls.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&network_acl=" + encodeURI(networkAclToUpdate) + "&action=updateNetworkAcl", {json: networkAclUpdateJSON}, function (data) {
|
||||
//Sync type
|
||||
var operationData = JSON.parse(data);
|
||||
console.log(operationData);
|
||||
|
@ -538,7 +582,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
var networkAclName = $("#newNetworkAclName").val();
|
||||
var networkAcl = $("#networkAclToRename").val();
|
||||
console.log("Info: renaming network acl " + networkAcl);
|
||||
$.get("./php/lxd/network-acls.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&network_acl=" + encodeURI(networkAcl) + "&name=" + encodeURI(networkAclName) + "&action=renameNetworkAcl", function (data) {
|
||||
$.get("./backend/lxd/network-acls.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&network_acl=" + encodeURI(networkAcl) + "&name=" + encodeURI(networkAclName) + "&action=renameNetworkAcl", function (data) {
|
||||
//Sync operation type
|
||||
var operationData = JSON.parse(data);
|
||||
console.log(operationData);
|
||||
|
@ -551,7 +595,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
|
||||
function deleteNetworkAcl(networkAclToDelete){
|
||||
console.log("Info: deleting network acl " + networkAclToDelete);
|
||||
$.get("./php/lxd/network-acls.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&network_acl=" + encodeURI(networkAclToDelete) + "&action=deleteNetworkAcl", function (data) {
|
||||
$.get("./backend/lxd/network-acls.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&network_acl=" + encodeURI(networkAclToDelete) + "&action=deleteNetworkAcl", function (data) {
|
||||
//Sync type
|
||||
var operationData = JSON.parse(data);
|
||||
console.log(operationData);
|
||||
|
@ -562,33 +606,64 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
});
|
||||
}
|
||||
|
||||
function setSidebarToggleValue(){
|
||||
sidebarState = localStorage.getItem('sidebarState');
|
||||
if (sidebarState == "collapsed"){
|
||||
localStorage.setItem('sidebarState','expanded');
|
||||
}
|
||||
else {
|
||||
localStorage.setItem('sidebarState','collapsed');
|
||||
}
|
||||
}
|
||||
|
||||
function applySidebarToggleValue() {
|
||||
sidebarState = localStorage.getItem('sidebarState');
|
||||
if (sidebarState == "collapsed"){
|
||||
$("body").toggleClass("sidebar-toggled"),
|
||||
$(".sidebar").toggleClass("toggled"),
|
||||
$(".sidebar").hasClass("toggled") && $(".sidebar .collapse").collapse("hide")
|
||||
}
|
||||
}
|
||||
|
||||
applySidebarToggleValue();
|
||||
|
||||
$(document).ready(function(){
|
||||
|
||||
//Check Authorization
|
||||
$.get("./php/aaa/authentication.php?action=validateAuthentication", function (data) {
|
||||
$.get("./backend/aaa/authentication.php?action=validateAuthentication", function (data) {
|
||||
operationData = JSON.parse(data);
|
||||
if (operationData.status_code != 200) {
|
||||
console.log(operationData);
|
||||
window.location = './index.html'
|
||||
window.location.href = './index.php'
|
||||
}
|
||||
});
|
||||
|
||||
//Load in the sidebar
|
||||
$("#sidebarLinks").load("./sidebar.html");
|
||||
$("#sidebarLinks").load("./sidebar.php?version=3.0");
|
||||
|
||||
//Setup Page Breadcrumb Links/Information
|
||||
$('#remoteBreadCrumb').load("./php/lxd/remote-breadcrumb.php?remote=" + encodeURI(remoteId));
|
||||
$('#remoteBreadCrumb').attr("href", "remotes-single.html?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName));
|
||||
$('#networkAclsBreadCrumb').text("network-acls");
|
||||
$('#remoteBreadCrumb').load("./backend/lxd/remote-breadcrumb.php?remote=" + encodeURI(remoteId));
|
||||
$('#remoteBreadCrumb').attr("href", "remotes-single.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName));
|
||||
|
||||
//Validate remote host connection returns 200 status
|
||||
$.get("./backend/lxd/remotes-single.php?remote=" + encodeURI(remoteId) + "&action=validateRemoteConnection", function (data) {
|
||||
operationData = JSON.parse(data);
|
||||
console.log(operationData);
|
||||
if (operationData.status_code == 200) {
|
||||
//Set top navbar dropdowns
|
||||
$("#remoteListNav").load("./backend/lxd/remotes.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&action=listRemotesForSelectOption");
|
||||
$("#projectListNav").load("./backend/lxd/projects.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&action=listProjectsForSelectOption");
|
||||
|
||||
//Load the card contents
|
||||
loadPageContent();
|
||||
|
||||
$("#remoteListNav").load("./php/lxd/remotes.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&action=listRemotesForTopNavigation");
|
||||
$("#projectListNav").load("./php/lxd/projects.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&action=listProjectsForTopNavigation");
|
||||
//Load Page Content
|
||||
loadPageContent();
|
||||
}
|
||||
else {
|
||||
alert("Unable to connect to remote host. HTTP status code: " + operationData.status_code);
|
||||
}
|
||||
});
|
||||
|
||||
//Load the about info for the about modal
|
||||
$.get("./about.html", function (data) {
|
||||
$.get("./backend/config/about.php", function (data) {
|
||||
$("#about").html(data);
|
||||
});
|
||||
|
|
@ -37,7 +37,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
|
||||
<!-- Custom styles for this template-->
|
||||
<link href="vendor/sb-admin-2/css/sb-admin-2.css" rel="stylesheet">
|
||||
<link href="assets/css/style.css" rel="stylesheet">
|
||||
<link href="assets/css/style.css?version=3.0" rel="stylesheet">
|
||||
|
||||
<!-- Custom styles for this page -->
|
||||
<link href="vendor/datatables/dataTables.bootstrap4.min.css" rel="stylesheet">
|
||||
|
@ -50,7 +50,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
<div id="wrapper">
|
||||
|
||||
<!-- Sidebar -->
|
||||
<ul class="navbar-nav bg-dark sidebar sidebar-dark accordion" id="accordionSidebar">
|
||||
<ul class="navbar-nav bg-dark sidebar sidebar-dark accordion sidebar-divider-right" id="accordionSidebar">
|
||||
|
||||
<div id="sidebarLinks"></div>
|
||||
|
||||
|
@ -59,12 +59,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
|
||||
<!-- Sidebar Toggler (Sidebar) -->
|
||||
<div class="text-center d-none d-md-inline">
|
||||
<button class="rounded-circle border-0" id="sidebarToggle"></button>
|
||||
<button class="rounded-circle border-0" id="sidebarToggle" onclick="setSidebarToggleValue()"></button>
|
||||
</div>
|
||||
</ul>
|
||||
<!-- End of Sidebar -->
|
||||
|
||||
|
||||
<!-- Content Wrapper -->
|
||||
<div id="content-wrapper" class="d-flex flex-column">
|
||||
|
||||
|
@ -79,37 +78,44 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
<i class="fa fa-bars"></i>
|
||||
</button>
|
||||
|
||||
|
||||
<!-- Topbar Notification -->
|
||||
<div class="d-none d-sm-inline-block form-inline mr-auto ml-md-3 my-2 my-md-0 mw-100 navbar-search">
|
||||
<ul class="navbar-nav ml-auto">
|
||||
|
||||
<li>
|
||||
<div class="nav-item spinner-border m-3" role="status" style="display:none;" id="spinner">
|
||||
<span class="nav-item sr-only">Loading...</span>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li class="nav-item dropdown no-arrow" id="notificationArea" style="display: none;">
|
||||
<div class="nav-link dropdown-toggle">
|
||||
<span id="notification" class="mr-2 d-none d-lg-inline text-gray-600">Notification</span>
|
||||
<span id="notification" class="mr-2 d-none d-lg-inline text-danger">Notification</span>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<!-- Topbar Navbar -->
|
||||
<ul class="navbar-nav ml-auto">
|
||||
|
||||
<!-- Topbar Navbar -->
|
||||
<ul class="navbar-nav ml-auto">
|
||||
<li class="nav-item dropdown">
|
||||
<label class="h6 mt-4 mr-2 ml-4">Host: </label>
|
||||
</li>
|
||||
<li class="nav-item dropdown">
|
||||
<div class="input-group mt-3">
|
||||
<select class="form-control" id="remoteListNav" style="width:150px;" onchange="location = this.value;">
|
||||
</select>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li class="nav-item dropdown" id="remoteListNav">
|
||||
</li>
|
||||
<li class="nav-item dropdown">
|
||||
<label class="h6 mt-4 mr-2 ml-4">Project: </label>
|
||||
</li>
|
||||
<li class="nav-item dropdown">
|
||||
<div class="input-group mt-3">
|
||||
<select class="form-control" id="projectListNav" style="width:150px;" onchange="location = this.value;">
|
||||
</select>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li class="nav-item dropdown" id="projectListNav">
|
||||
</li>
|
||||
|
||||
<div class="topbar-divider d-none d-sm-block"></div>
|
||||
<!-- Nav Divider -->
|
||||
<div class="topbar-divider d-none d-sm-block"></div>
|
||||
|
||||
<!-- Nav Item - User Information -->
|
||||
<li class="nav-item dropdown no-arrow">
|
||||
|
@ -119,14 +125,18 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
</a>
|
||||
<!-- Dropdown - User Information -->
|
||||
<div class="dropdown-menu dropdown-menu-right shadow animated--grow-in" aria-labelledby="userDropdown">
|
||||
<a class="dropdown-item" href="user-profile.html">
|
||||
<a class="dropdown-item" href="user-profile.php">
|
||||
<i class="fas fa-user fa-sm fa-fw mr-2 text-gray-400"></i>
|
||||
Profile
|
||||
</a>
|
||||
<a class="dropdown-item" href="settings.html">
|
||||
<a class="dropdown-item" href="settings.php">
|
||||
<i class="fas fa-cog fa-sm fa-fw mr-2 text-gray-400"></i>
|
||||
Settings
|
||||
</a>
|
||||
<a class="dropdown-item" href="logs.php">
|
||||
<i class="fas fa-history fa-sm fa-fw mr-2 text-gray-400"></i>
|
||||
Logs
|
||||
</a>
|
||||
<a class="dropdown-item" href="#" data-toggle="modal" data-target="#aboutModal">
|
||||
<i class="fas fa-info-circle fa-sm fa-fw mr-2 text-gray-400"></i>
|
||||
About
|
||||
|
@ -147,25 +157,48 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
<!-- Begin Page Content -->
|
||||
<div class="container-fluid">
|
||||
|
||||
<!-- BreadCrumb -->
|
||||
<nav aria-label="breadcrumb">
|
||||
<ol class="breadcrumb">
|
||||
<li class="breadcrumb-item"><a href="#" id="remoteBreadCrumb"></a></li>
|
||||
<li class="breadcrumb-item active" aria-current="page" id="networksBreadCrumb"></li>
|
||||
</ol>
|
||||
</nav>
|
||||
<header class="page-header page-header-dark bg-gradient-primary-to-secondary">
|
||||
<div class="container-xl px-4">
|
||||
<div class="page-header-content pt-4">
|
||||
<div class="row align-items-center justify-content-between mt-n5 ml-n5 mr-n5 bg-dark pb-6">
|
||||
<div class="col-auto mt-4 ml-3">
|
||||
<div class="page-header-subtitle">
|
||||
<a href="#" id="remoteBreadCrumb"></a>
|
||||
</div>
|
||||
<h2 class="page-header-title mt-2">
|
||||
NETWORKS
|
||||
</h2>
|
||||
<div class="page-header-subtitle">
|
||||
Create and manage LXD networks
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-xl-auto mt-4">
|
||||
<div class="input-group input-group-joined border-0" style="width: 14rem">
|
||||
<span class="input-group-text bg-transparent border-0">
|
||||
<a class="btn btn-outline-primary" href="#" onclick="loadCreateNetworkModal()" title="New Network" aria-hidden="true">
|
||||
<i class="fas fa-plus fa-sm fa-fw"></i> Network
|
||||
</a>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<div class="row">
|
||||
<div class="row mt-n5 ml-2 mr-2">
|
||||
|
||||
<div class="col-12">
|
||||
<div class="col-12 mt-n3">
|
||||
<!-- Network List -->
|
||||
<div class="card shadow mb-4">
|
||||
<!-- Card Header - Dropdown -->
|
||||
<div class="card-header py-3 d-flex flex-row align-items-center justify-content-between">
|
||||
<h6 class="m-0 font-weight-bold text-primary">Networks</h6>
|
||||
<h6 class="m-0 font-weight-bold">
|
||||
<span class="ml-1">Networks</span>
|
||||
</h6>
|
||||
<div class="dropdown no-arrow">
|
||||
<a class="dropdown-toggle mr-2" href="#" onclick="loadCreateNetworkModal()" title="New Network" aria-hidden="true">
|
||||
<i class="fas fa-plus fa-sm fa-fw"></i> Network</a>
|
||||
<a class="dropdown-toggle mr-2" href="#" onclick="reloadPageContent()" title="Refresh" aria-hidden="true">
|
||||
<i class="fa fa-sync fa-1x fa-fw"></i></a>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Card Body -->
|
||||
|
@ -191,7 +224,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
<footer class="sticky-footer bg-white">
|
||||
<div class="container my-auto">
|
||||
<div class="copyright text-center my-auto">
|
||||
<span>Copyright © lxdware.com 2021</span>
|
||||
<span>Copyright © LXDWARE 2020 - Present</span>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
|
@ -208,7 +241,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
<i class="fas fa-angle-up"></i>
|
||||
</a>
|
||||
|
||||
|
||||
<!-- Create Network Modal-->
|
||||
<div class="modal fade" id="createNetworkModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog modal-lg" role="document">
|
||||
|
@ -232,18 +264,18 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
<div class="tab-pane fade show active" id="form" role="tabpanel" aria-labelledby="form-tab">
|
||||
<div class="modal-body">
|
||||
<div class="row">
|
||||
<label class="col-3 col-form-label text-right">Name: </label>
|
||||
<label class="col-3 col-form-label text-right">Name: <span class="text-danger">*</span></label>
|
||||
<div class="col-7">
|
||||
<div class="form-group">
|
||||
<input type="text" id="networkNameInput" class="form-control" placeholder="" name="networkNameInput">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-1">
|
||||
<i class="far fa-sm fa-question-circle text-danger" title='(Required) - Enter the name of this network.'></i>
|
||||
<i class="far fa-sm fa-question-circle" title='(Required) - Enter the name of this network.'></i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<label class="col-3 col-form-label text-right">Network Type: </label>
|
||||
<label class="col-3 col-form-label text-right">Network Type: <span class="text-danger">*</span></label>
|
||||
<div class="col-7">
|
||||
<div class="form-group">
|
||||
<select id="networkTypeInput" onchange="changeNetworkTypeInput()" class="form-control" name="networkTypeInput">
|
||||
|
@ -256,11 +288,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
</div>
|
||||
</div>
|
||||
<div class="col-1">
|
||||
<i class="far fa-sm fa-question-circle text-danger" title='(Required) - Select the type of network. Default: bridge'></i>
|
||||
<i class="far fa-sm fa-question-circle" title='(Required) - Select the type of network. Default: bridge'></i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row" id="networkParentRow" style="display: none;">
|
||||
<label class="col-3 col-form-label text-right">Parent: </label>
|
||||
<label class="col-3 col-form-label text-right">Parent: <span class="text-danger">*</span></label>
|
||||
<div class="col-7">
|
||||
<div class="form-group">
|
||||
<select id="networkParentInput" onchange="" class="form-control" name="networkParentInput">
|
||||
|
@ -268,11 +300,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
</div>
|
||||
</div>
|
||||
<div class="col-1">
|
||||
<i class="far fa-sm fa-question-circle text-danger" title='(Required) - Select the parent interface to create the network on'></i>
|
||||
<i class="far fa-sm fa-question-circle" title='(Required) - Select the parent interface to create the network on'></i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row" id="networkNetworkRow" style="display: none;">
|
||||
<label class="col-3 col-form-label text-right">Network: </label>
|
||||
<label class="col-3 col-form-label text-right">Network: <span class="text-danger">*</span></label>
|
||||
<div class="col-7">
|
||||
<div class="form-group">
|
||||
<select id="networkNetworkInput" onchange="" class="form-control" name="networkNetworkInput">
|
||||
|
@ -280,7 +312,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
</div>
|
||||
</div>
|
||||
<div class="col-1">
|
||||
<i class="far fa-sm fa-question-circle text-danger" title='(Required) - Select the uplink network interface for external connections.'></i>
|
||||
<i class="far fa-sm fa-question-circle" title='(Required) - Select the uplink network interface for external connections.'></i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
|
@ -955,14 +987,14 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="row">
|
||||
<label class="col-3 col-form-label text-right" id="newNetworkNameLabel">Name:</label>
|
||||
<label class="col-3 col-form-label text-right" id="newNetworkNameLabel">Name: <span class="text-danger">*</span></label>
|
||||
<div class="col-7">
|
||||
<div class="form-group">
|
||||
<input type="text" id="newNetworkName" class="form-control" placeholder="">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-1">
|
||||
<i class="far fa-sm fa-question-circle text-danger" title='(Required) - Enter in a new name for the network.'></i>
|
||||
<i class="far fa-sm fa-question-circle" title='(Required) - Enter in a new name for the network.'></i>
|
||||
</div>
|
||||
</div>
|
||||
<input type="hidden" id ="networkToRename" name="networkToRename">
|
||||
|
@ -1021,61 +1053,66 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
const remoteId = urlParams.get('remote');
|
||||
const projectName = urlParams.get('project');
|
||||
var networkToUpdate = "";
|
||||
var reloadTime = 5000;
|
||||
|
||||
function logout(){
|
||||
$.get("./php/aaa/authentication.php?action=deauthenticateUser", function (data) {
|
||||
$.get("./backend/aaa/authentication.php?action=deauthenticateUser", function (data) {
|
||||
operationData = JSON.parse(data);
|
||||
console.log(operationData);
|
||||
if (operationData.status_code == 200) {
|
||||
window.location = './index.html'
|
||||
window.location.href = './index.php'
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function operationStatusCheck(){
|
||||
clearTimeout(operationTimeout);
|
||||
//check to see if there are any running operations
|
||||
$.get("./php/lxd/operations.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&action=displayOperationStatus", function (data) {
|
||||
$.get("./backend/lxd/operations.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&action=displayOperationStatus", function (data) {
|
||||
//Check to see if we have running operations
|
||||
if (data){
|
||||
//Display spinner and notification area if there are running tasks
|
||||
$('#spinner').show();
|
||||
if (data) {
|
||||
//Display notification area if there are running tasks
|
||||
$('#notificationArea').show();
|
||||
$('#notification').text(data);
|
||||
//Set the page to check operations again in 1 second
|
||||
setTimeout(() => { operationStatusCheck(); }, 1000);
|
||||
$('#notification').text("Notice: " + data);
|
||||
//Set the page to check operations again in 2 seconds
|
||||
operationTimeout = setTimeout(() => { operationStatusCheck(); }, 2000);
|
||||
}
|
||||
else {
|
||||
//Hide spinner and notification area if no running tasks
|
||||
$('#spinner').hide();
|
||||
//Hide notification area if no running tasks
|
||||
$('#notificationArea').hide();
|
||||
$('#notification').text("");
|
||||
//Set the page to check operations again in 3 seconds
|
||||
setTimeout(() => { operationStatusCheck(); }, 3000);
|
||||
//Set the page to check operations again in 4 seconds
|
||||
operationTimeout = setTimeout(() => { operationStatusCheck(); }, 4000);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function reloadPageContent() {
|
||||
|
||||
clearTimeout(pageReloadTimeout);
|
||||
|
||||
//Check Authorization
|
||||
$.get("./php/aaa/authentication.php?action=validateAuthentication", function (data) {
|
||||
$.get("./backend/aaa/authentication.php?action=validateAuthentication", function (data) {
|
||||
operationData = JSON.parse(data);
|
||||
if (operationData.status_code != 200) {
|
||||
console.log(operationData);
|
||||
window.location = './index.html'
|
||||
window.location.href = './index.php'
|
||||
}
|
||||
});
|
||||
|
||||
$('#networkListTable').DataTable().ajax.reload(null, false);
|
||||
|
||||
//Set reload page content
|
||||
pageReloadTimeout = setTimeout(() => { reloadPageContent(); }, reloadTime);
|
||||
}
|
||||
|
||||
function loadPageContent(){
|
||||
|
||||
//Display current logged in username
|
||||
$("#username").load("./php/admin/settings.php?action=displayUsername");
|
||||
$("#username").load("./backend/admin/settings.php?action=displayUsername");
|
||||
|
||||
$('#networkListTable').DataTable( {
|
||||
ajax: "./php/lxd/networks.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&action=listNetworks",
|
||||
ajax: "./backend/lxd/networks.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&action=listNetworks",
|
||||
columns: [
|
||||
{},
|
||||
{ title: "Name" },
|
||||
|
@ -1093,10 +1130,16 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
});
|
||||
|
||||
//Check for any running operations
|
||||
operationStatusCheck();
|
||||
operationTimeout = setTimeout(() => { operationStatusCheck(); }, 1000);
|
||||
|
||||
//Set reload page content
|
||||
$.get("./backend/admin/settings.php?action=retrievePageRefreshRateValues", function (data) {
|
||||
operationData = JSON.parse(data);
|
||||
if (operationData.networks_page_rate >= 1)
|
||||
reloadTime = operationData.networks_page_rate * 1000;
|
||||
pageReloadTimeout = setTimeout(() => { reloadPageContent(); }, reloadTime);
|
||||
});
|
||||
|
||||
//Set the page content to reload in 5 seconds
|
||||
setInterval(() => { reloadPageContent(); }, 5000);
|
||||
}
|
||||
|
||||
function createNetworkUsingForm(){
|
||||
|
@ -1153,7 +1196,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
var networkOvnIngressModeInput = $("#networkOvnIngressModeInput").val();
|
||||
|
||||
console.log("Info: creating network");
|
||||
$.get("./php/lxd/networks.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) +
|
||||
$.get("./backend/lxd/networks.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) +
|
||||
"&name=" + encodeURI(networkNameInput) +
|
||||
"&type=" + encodeURI(networkTypeInput) +
|
||||
"&description=" + encodeURI(networkDescriptionInput) +
|
||||
|
@ -1220,7 +1263,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
function createNetworkUsingJSON(){
|
||||
var networkCreateJSON = $("#jsonCreateInput").val();
|
||||
console.log("Info: creating network");
|
||||
$.post("./php/lxd/networks.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&action=createNetworkUsingJSON", {json: networkCreateJSON}, function (data) {
|
||||
$.post("./backend/lxd/networks.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&action=createNetworkUsingJSON", {json: networkCreateJSON}, function (data) {
|
||||
//Async type
|
||||
var operationData = JSON.parse(data);
|
||||
console.log(operationData);
|
||||
|
@ -1232,11 +1275,10 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
});
|
||||
}
|
||||
|
||||
//Called by Edit action, loads JSON data of network
|
||||
function loadNetworkJson(networkToLoad){
|
||||
console.log("Info: loading network " + networkToLoad);
|
||||
networkToUpdate = networkToLoad;
|
||||
$.get("./php/lxd/networks.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&network=" + encodeURI(networkToLoad) + "&action=loadNetwork", function (data) {
|
||||
$.get("./backend/lxd/networks.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&network=" + encodeURI(networkToLoad) + "&action=loadNetwork", function (data) {
|
||||
//Sync type
|
||||
var operationData = JSON.parse(data);
|
||||
console.log(operationData);
|
||||
|
@ -1259,7 +1301,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
function updateNetwork(){
|
||||
var networkUpdateJSON = $("#jsonEditInput").val();
|
||||
console.log("Info: updating network " + networkToUpdate);
|
||||
$.post("./php/lxd/networks.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&network=" + encodeURI(networkToUpdate) + "&action=updateNetwork", {json: networkUpdateJSON}, function (data) {
|
||||
$.post("./backend/lxd/networks.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&network=" + encodeURI(networkToUpdate) + "&action=updateNetwork", {json: networkUpdateJSON}, function (data) {
|
||||
//Sync type
|
||||
var operationData = JSON.parse(data);
|
||||
console.log(operationData);
|
||||
|
@ -1274,7 +1316,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
var networkName = $("#newNetworkName").val();
|
||||
var network = $("#networkToRename").val();
|
||||
console.log("Info: renaming network " + network);
|
||||
$.get("./php/lxd/networks.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&network=" + encodeURI(network) + "&name=" + encodeURI(networkName) + "&action=renameNetwork", function (data) {
|
||||
$.get("./backend/lxd/networks.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&network=" + encodeURI(network) + "&name=" + encodeURI(networkName) + "&action=renameNetwork", function (data) {
|
||||
//Sync operation type
|
||||
var operationData = JSON.parse(data);
|
||||
console.log(operationData);
|
||||
|
@ -1287,7 +1329,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
|
||||
function deleteNetwork(networkToDelete){
|
||||
console.log("Info: deleting network " + networkToDelete);
|
||||
$.get("./php/lxd/networks.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&network=" + encodeURI(networkToDelete) + "&action=deleteNetwork", function (data) {
|
||||
$.get("./backend/lxd/networks.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&network=" + encodeURI(networkToDelete) + "&action=deleteNetwork", function (data) {
|
||||
//Sync type
|
||||
var operationData = JSON.parse(data);
|
||||
console.log(operationData);
|
||||
|
@ -1300,8 +1342,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
|
||||
function loadCreateNetworkModal(){
|
||||
console.log("Info: loading create network modal");
|
||||
$("#networkParentInput").load("./php/lxd/networks.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&action=listNetworksForSelectOption");
|
||||
$("#networkNetworkInput").load("./php/lxd/networks.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&managed_only=true" + "&action=listNetworksForSelectOption");
|
||||
$("#networkParentInput").load("./backend/lxd/networks.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&action=listNetworksForSelectOption");
|
||||
$("#networkNetworkInput").load("./backend/lxd/networks.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&managed_only=true" + "&action=listNetworksForSelectOption");
|
||||
changeNetworkTypeInput();
|
||||
$("#createNetworkModal").modal('show');
|
||||
}
|
||||
|
@ -1511,33 +1553,64 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
}
|
||||
}
|
||||
|
||||
function setSidebarToggleValue(){
|
||||
sidebarState = localStorage.getItem('sidebarState');
|
||||
if (sidebarState == "collapsed"){
|
||||
localStorage.setItem('sidebarState','expanded');
|
||||
}
|
||||
else {
|
||||
localStorage.setItem('sidebarState','collapsed');
|
||||
}
|
||||
}
|
||||
|
||||
function applySidebarToggleValue() {
|
||||
sidebarState = localStorage.getItem('sidebarState');
|
||||
if (sidebarState == "collapsed"){
|
||||
$("body").toggleClass("sidebar-toggled"),
|
||||
$(".sidebar").toggleClass("toggled"),
|
||||
$(".sidebar").hasClass("toggled") && $(".sidebar .collapse").collapse("hide")
|
||||
}
|
||||
}
|
||||
|
||||
applySidebarToggleValue();
|
||||
|
||||
$(document).ready(function(){
|
||||
|
||||
//Check Authorization
|
||||
$.get("./php/aaa/authentication.php?action=validateAuthentication", function (data) {
|
||||
$.get("./backend/aaa/authentication.php?action=validateAuthentication", function (data) {
|
||||
operationData = JSON.parse(data);
|
||||
if (operationData.status_code != 200) {
|
||||
console.log(operationData);
|
||||
window.location = './index.html'
|
||||
window.location.href = './index.php'
|
||||
}
|
||||
});
|
||||
|
||||
//Load in the sidebar
|
||||
$("#sidebarLinks").load("./sidebar.html");
|
||||
$("#sidebarLinks").load("./sidebar.php?version=3.0");
|
||||
|
||||
//Setup Page Breadcrumb Links/Information
|
||||
$('#remoteBreadCrumb').load("./php/lxd/remote-breadcrumb.php?remote=" + encodeURI(remoteId));
|
||||
$('#remoteBreadCrumb').attr("href", "remotes-single.html?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName));
|
||||
$('#networksBreadCrumb').text("networks");
|
||||
$('#remoteBreadCrumb').load("./backend/lxd/remote-breadcrumb.php?remote=" + encodeURI(remoteId));
|
||||
$('#remoteBreadCrumb').attr("href", "remotes-single.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName));
|
||||
|
||||
//Load the card contents
|
||||
loadPageContent();
|
||||
//Validate remote host connection returns 200 status
|
||||
$.get("./backend/lxd/remotes-single.php?remote=" + encodeURI(remoteId) + "&action=validateRemoteConnection", function (data) {
|
||||
operationData = JSON.parse(data);
|
||||
console.log(operationData);
|
||||
if (operationData.status_code == 200) {
|
||||
//Set top navbar dropdowns
|
||||
$("#remoteListNav").load("./backend/lxd/remotes.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&action=listRemotesForSelectOption");
|
||||
$("#projectListNav").load("./backend/lxd/projects.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&action=listProjectsForSelectOption");
|
||||
|
||||
//Load Page Content
|
||||
loadPageContent();
|
||||
}
|
||||
else {
|
||||
alert("Unable to connect to remote host. HTTP status code: " + operationData.status_code);
|
||||
}
|
||||
});
|
||||
|
||||
$("#remoteListNav").load("./php/lxd/remotes.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&action=listRemotesForTopNavigation");
|
||||
$("#projectListNav").load("./php/lxd/projects.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&action=listProjectsForTopNavigation");
|
||||
|
||||
//Load the about info for the about modal
|
||||
$.get("./about.html", function (data) {
|
||||
$.get("./backend/config/about.php", function (data) {
|
||||
$("#about").html(data);
|
||||
});
|
||||
|
|
@ -37,7 +37,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
|
||||
<!-- Custom styles for this template-->
|
||||
<link href="vendor/sb-admin-2/css/sb-admin-2.css" rel="stylesheet">
|
||||
<link href="assets/css/style.css" rel="stylesheet">
|
||||
<link href="assets/css/style.css?version=3.0" rel="stylesheet">
|
||||
|
||||
<!-- Custom styles for this page -->
|
||||
<link href="vendor/datatables/dataTables.bootstrap4.min.css" rel="stylesheet">
|
||||
|
@ -50,7 +50,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
<div id="wrapper">
|
||||
|
||||
<!-- Sidebar -->
|
||||
<ul class="navbar-nav bg-dark sidebar sidebar-dark accordion" id="accordionSidebar">
|
||||
<ul class="navbar-nav bg-dark sidebar sidebar-dark accordion sidebar-divider-right" id="accordionSidebar">
|
||||
|
||||
<div id="sidebarLinks"></div>
|
||||
|
||||
|
@ -59,7 +59,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
|
||||
<!-- Sidebar Toggler (Sidebar) -->
|
||||
<div class="text-center d-none d-md-inline">
|
||||
<button class="rounded-circle border-0" id="sidebarToggle"></button>
|
||||
<button class="rounded-circle border-0" id="sidebarToggle" onclick="setSidebarToggleValue()"></button>
|
||||
</div>
|
||||
</ul>
|
||||
<!-- End of Sidebar -->
|
||||
|
@ -79,36 +79,43 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
<i class="fa fa-bars"></i>
|
||||
</button>
|
||||
|
||||
|
||||
<!-- Topbar Notification -->
|
||||
<div class="d-none d-sm-inline-block form-inline mr-auto ml-md-3 my-2 my-md-0 mw-100 navbar-search">
|
||||
<ul class="navbar-nav ml-auto">
|
||||
|
||||
<li>
|
||||
<div class="nav-item spinner-border m-3" role="status" style="display:none;" id="spinner">
|
||||
<span class="nav-item sr-only">Loading...</span>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li class="nav-item dropdown no-arrow" id="notificationArea" style="display: none;">
|
||||
<div class="nav-link dropdown-toggle">
|
||||
<span id="notification" class="mr-2 d-none d-lg-inline text-gray-600">Notification</span>
|
||||
<span id="notification" class="mr-2 d-none d-lg-inline text-danger">Notification</span>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- Topbar Navbar -->
|
||||
<ul class="navbar-nav ml-auto">
|
||||
|
||||
<li class="nav-item dropdown" id="remoteListNav">
|
||||
<li class="nav-item dropdown">
|
||||
<label class="h6 mt-4 mr-2 ml-4">Host: </label>
|
||||
</li>
|
||||
<li class="nav-item dropdown">
|
||||
<div class="input-group mt-3">
|
||||
<select class="form-control" id="remoteListNav" style="width:150px;" onchange="location = this.value;">
|
||||
</select>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li class="nav-item dropdown" id="projectListNav">
|
||||
<li class="nav-item dropdown">
|
||||
<label class="h6 mt-4 mr-2 ml-4">Project: </label>
|
||||
</li>
|
||||
<li class="nav-item dropdown">
|
||||
<div class="input-group mt-3">
|
||||
<select class="form-control" id="projectListNav" style="width:150px;" onchange="location = this.value;">
|
||||
</select>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<!-- Nav Divider -->
|
||||
<div class="topbar-divider d-none d-sm-block"></div>
|
||||
|
||||
<!-- Nav Item - User Information -->
|
||||
|
@ -119,14 +126,18 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
</a>
|
||||
<!-- Dropdown - User Information -->
|
||||
<div class="dropdown-menu dropdown-menu-right shadow animated--grow-in" aria-labelledby="userDropdown">
|
||||
<a class="dropdown-item" href="user-profile.html">
|
||||
<a class="dropdown-item" href="user-profile.php">
|
||||
<i class="fas fa-user fa-sm fa-fw mr-2 text-gray-400"></i>
|
||||
Profile
|
||||
</a>
|
||||
<a class="dropdown-item" href="settings.html">
|
||||
<a class="dropdown-item" href="settings.php">
|
||||
<i class="fas fa-cog fa-sm fa-fw mr-2 text-gray-400"></i>
|
||||
Settings
|
||||
</a>
|
||||
<a class="dropdown-item" href="logs.php">
|
||||
<i class="fas fa-history fa-sm fa-fw mr-2 text-gray-400"></i>
|
||||
Logs
|
||||
</a>
|
||||
<a class="dropdown-item" href="#" data-toggle="modal" data-target="#aboutModal">
|
||||
<i class="fas fa-info-circle fa-sm fa-fw mr-2 text-gray-400"></i>
|
||||
About
|
||||
|
@ -147,23 +158,45 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
<!-- Begin Page Content -->
|
||||
<div class="container-fluid">
|
||||
|
||||
<!-- BreadCrumb -->
|
||||
<nav aria-label="breadcrumb">
|
||||
<ol class="breadcrumb">
|
||||
<li class="breadcrumb-item"><a href="#" id="remoteBreadCrumb"></a></li>
|
||||
<li class="breadcrumb-item active" aria-current="page" id="operationsBreadCrumb"></li>
|
||||
</ol>
|
||||
</nav>
|
||||
<header class="page-header page-header-dark bg-gradient-primary-to-secondary">
|
||||
<div class="container-xl px-4">
|
||||
<div class="page-header-content pt-4">
|
||||
<div class="row align-items-center justify-content-between mt-n5 ml-n5 mr-n5 bg-dark pb-6">
|
||||
<div class="col-auto mt-4 ml-3">
|
||||
<div class="page-header-subtitle">
|
||||
<a href="#" id="remoteBreadCrumb"></a>
|
||||
</div>
|
||||
<h2 class="page-header-title mt-2">
|
||||
OPERATIONS
|
||||
</h2>
|
||||
<div class="page-header-subtitle">
|
||||
Manage LXD host operations
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-xl-auto mt-4">
|
||||
<div class="input-group input-group-joined border-0" style="width: 14rem">
|
||||
<span class="input-group-text bg-transparent border-0">
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<div class="row">
|
||||
<div class="row mt-n5 ml-2 mr-2">
|
||||
|
||||
<div class="col-12">
|
||||
<div class="col-12 mt-n3">
|
||||
<!-- Operations List -->
|
||||
<div class="card shadow mb-4">
|
||||
<!-- Card Header - Dropdown -->
|
||||
<div class="card-header py-3 d-flex flex-row align-items-center justify-content-between">
|
||||
<h6 class="m-0 font-weight-bold text-primary">Operations</h6>
|
||||
<h6 class="m-0 font-weight-bold">
|
||||
<span class="ml-1">Operations</span>
|
||||
</h6>
|
||||
<div class="dropdown no-arrow">
|
||||
<a class="dropdown-toggle mr-2" href="#" onclick="reloadPageContent()" title="Refresh" aria-hidden="true">
|
||||
<i class="fa fa-sync fa-1x fa-fw"></i></a>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Card Body -->
|
||||
|
@ -189,7 +222,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
<footer class="sticky-footer bg-white">
|
||||
<div class="container my-auto">
|
||||
<div class="copyright text-center my-auto">
|
||||
<span>Copyright © lxdware.com 2021</span>
|
||||
<span>Copyright © LXDWARE 2020 - Present</span>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
|
@ -280,61 +313,66 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
const urlParams = new URLSearchParams(queryString);
|
||||
const remoteId = urlParams.get('remote');
|
||||
const projectName = urlParams.get('project');
|
||||
var reloadTime = 3000;
|
||||
|
||||
function logout(){
|
||||
$.get("./php/aaa/authentication.php?action=deauthenticateUser", function (data) {
|
||||
$.get("./backend/aaa/authentication.php?action=deauthenticateUser", function (data) {
|
||||
operationData = JSON.parse(data);
|
||||
console.log(operationData);
|
||||
if (operationData.status_code == 200) {
|
||||
window.location = './index.html'
|
||||
window.location.href = './index.php'
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function operationStatusCheck(){
|
||||
clearTimeout(operationTimeout);
|
||||
//check to see if there are any running operations
|
||||
$.get("./php/lxd/operations.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&action=displayOperationStatus", function (data) {
|
||||
$.get("./backend/lxd/operations.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&action=displayOperationStatus", function (data) {
|
||||
//Check to see if we have running operations
|
||||
if (data){
|
||||
//Display spinner and notification area if there are running tasks
|
||||
$('#spinner').show();
|
||||
if (data) {
|
||||
//Display notification area if there are running tasks
|
||||
$('#notificationArea').show();
|
||||
$('#notification').text(data);
|
||||
//Set the page to check operations again in 1 second
|
||||
setTimeout(() => { operationStatusCheck(); }, 1000);
|
||||
$('#notification').text("Notice: " + data);
|
||||
//Set the page to check operations again in 2 seconds
|
||||
operationTimeout = setTimeout(() => { operationStatusCheck(); }, 2000);
|
||||
}
|
||||
else {
|
||||
//Hide spinner and notification area if no running tasks
|
||||
$('#spinner').hide();
|
||||
//Hide notification area if no running tasks
|
||||
$('#notificationArea').hide();
|
||||
$('#notification').text("");
|
||||
//Set the page to check operations again in 3 seconds
|
||||
setTimeout(() => { operationStatusCheck(); }, 3000);
|
||||
//Set the page to check operations again in 4 seconds
|
||||
operationTimeout = setTimeout(() => { operationStatusCheck(); }, 4000);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function reloadPageContent(){
|
||||
|
||||
clearTimeout(pageReloadTimeout);
|
||||
|
||||
//Check Authorization
|
||||
$.get("./php/aaa/authentication.php?action=validateAuthentication", function (data) {
|
||||
$.get("./backend/aaa/authentication.php?action=validateAuthentication", function (data) {
|
||||
operationData = JSON.parse(data);
|
||||
if (operationData.status_code != 200) {
|
||||
console.log(operationData);
|
||||
window.location = './index.html'
|
||||
window.location.href = './index.php'
|
||||
}
|
||||
});
|
||||
|
||||
$('#operationListTable').DataTable().ajax.reload(null, false);
|
||||
|
||||
//Set reload page content
|
||||
pageReloadTimeout = setTimeout(() => { reloadPageContent(); }, reloadTime);
|
||||
}
|
||||
|
||||
function loadPageContent(){
|
||||
|
||||
//Display current logged in username
|
||||
$("#username").load("./php/admin/settings.php?action=displayUsername");
|
||||
$("#username").load("./backend/admin/settings.php?action=displayUsername");
|
||||
|
||||
$('#operationListTable').DataTable( {
|
||||
ajax: "./php/lxd/operations.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&action=listOperations",
|
||||
ajax: "./backend/lxd/operations.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&action=listOperations",
|
||||
columns: [
|
||||
{},
|
||||
{ title: "ID" },
|
||||
|
@ -352,15 +390,21 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
});
|
||||
|
||||
//Check for any running operations
|
||||
operationStatusCheck();
|
||||
operationTimeout = setTimeout(() => { operationStatusCheck(); }, 1000);
|
||||
|
||||
//Set reload page content
|
||||
$.get("./backend/admin/settings.php?action=retrievePageRefreshRateValues", function (data) {
|
||||
operationData = JSON.parse(data);
|
||||
if (operationData.operations_page_rate >= 1)
|
||||
reloadTime = operationData.operations_page_rate * 1000;
|
||||
pageReloadTimeout = setTimeout(() => { reloadPageContent(); }, reloadTime);
|
||||
});
|
||||
|
||||
//Set the page content to reload in 3 seconds
|
||||
setInterval(() => { reloadPageContent(); }, 3000);
|
||||
}
|
||||
|
||||
function loadOperationJson(operationToLoad){
|
||||
console.log("Info: loading operation " + operationToLoad);
|
||||
$.get("./php/lxd/operations.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&operation=" + encodeURI(operationToLoad) + "&action=loadOperation", function (data) {
|
||||
$.get("./backend/lxd/operations.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&operation=" + encodeURI(operationToLoad) + "&action=loadOperation", function (data) {
|
||||
//Sync type
|
||||
var operationData = JSON.parse(data);
|
||||
console.log(operationData);
|
||||
|
@ -375,7 +419,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
|
||||
function deleteOperation(operationToDelete){
|
||||
console.log("Info: deleting operation " + operationToDelete);
|
||||
$.get("./php/lxd/operations.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&operation=" + encodeURI(operationToDelete) + "&action=deleteOperation", function (data) {
|
||||
$.get("./backend/lxd/operations.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&operation=" + encodeURI(operationToDelete) + "&action=deleteOperation", function (data) {
|
||||
//Sync type
|
||||
var operationData = JSON.parse(data);
|
||||
console.log(operationData);
|
||||
|
@ -386,33 +430,64 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
});
|
||||
}
|
||||
|
||||
function setSidebarToggleValue(){
|
||||
sidebarState = localStorage.getItem('sidebarState');
|
||||
if (sidebarState == "collapsed"){
|
||||
localStorage.setItem('sidebarState','expanded');
|
||||
}
|
||||
else {
|
||||
localStorage.setItem('sidebarState','collapsed');
|
||||
}
|
||||
}
|
||||
|
||||
function applySidebarToggleValue() {
|
||||
sidebarState = localStorage.getItem('sidebarState');
|
||||
if (sidebarState == "collapsed"){
|
||||
$("body").toggleClass("sidebar-toggled"),
|
||||
$(".sidebar").toggleClass("toggled"),
|
||||
$(".sidebar").hasClass("toggled") && $(".sidebar .collapse").collapse("hide")
|
||||
}
|
||||
}
|
||||
|
||||
applySidebarToggleValue();
|
||||
|
||||
$(document).ready(function(){
|
||||
|
||||
//Check Authorization
|
||||
$.get("./php/aaa/authentication.php?action=validateAuthentication", function (data) {
|
||||
$.get("./backend/aaa/authentication.php?action=validateAuthentication", function (data) {
|
||||
operationData = JSON.parse(data);
|
||||
if (operationData.status_code != 200) {
|
||||
console.log(operationData);
|
||||
window.location = './index.html'
|
||||
window.location.href = './index.php'
|
||||
}
|
||||
});
|
||||
|
||||
//Load in the sidebar
|
||||
$("#sidebarLinks").load("./sidebar.html");
|
||||
$("#sidebarLinks").load("./sidebar.php?version=3.0");
|
||||
|
||||
//Setup Page Breadcrumb Links/Information
|
||||
$('#remoteBreadCrumb').load("./php/lxd/remote-breadcrumb.php?remote=" + encodeURI(remoteId));
|
||||
$('#remoteBreadCrumb').attr("href", "remotes-single.html?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName));
|
||||
$('#operationsBreadCrumb').text("operations");
|
||||
$('#remoteBreadCrumb').load("./backend/lxd/remote-breadcrumb.php?remote=" + encodeURI(remoteId));
|
||||
$('#remoteBreadCrumb').attr("href", "remotes-single.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName));
|
||||
|
||||
//Load the card contents
|
||||
loadPageContent();
|
||||
//Validate remote host connection returns 200 status
|
||||
$.get("./backend/lxd/remotes-single.php?remote=" + encodeURI(remoteId) + "&action=validateRemoteConnection", function (data) {
|
||||
operationData = JSON.parse(data);
|
||||
console.log(operationData);
|
||||
if (operationData.status_code == 200) {
|
||||
//Set top navbar dropdowns
|
||||
$("#remoteListNav").load("./backend/lxd/remotes.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&action=listRemotesForSelectOption");
|
||||
$("#projectListNav").load("./backend/lxd/projects.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&action=listProjectsForSelectOption");
|
||||
|
||||
//Load Page Content
|
||||
loadPageContent();
|
||||
}
|
||||
else {
|
||||
alert("Unable to connect to remote host. HTTP status code: " + operationData.status_code);
|
||||
}
|
||||
});
|
||||
|
||||
$("#remoteListNav").load("./php/lxd/remotes.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&action=listRemotesForTopNavigation");
|
||||
$("#projectListNav").load("./php/lxd/projects.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&action=listProjectsForTopNavigation");
|
||||
|
||||
//Load the about info for the about modal
|
||||
$.get("./about.html", function (data) {
|
||||
$.get("./backend/config/about.php", function (data) {
|
||||
$("#about").html(data);
|
||||
});
|
||||
|
|
@ -1,120 +0,0 @@
|
|||
<?php
|
||||
/*
|
||||
LXDWARE LXD Dashboard - A web-based interface for managing LXD servers
|
||||
Copyright (C) 2020-2021 LXDWARE.COM
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
//Start session if not already started
|
||||
if (!isset($_SESSION)) {
|
||||
session_start();
|
||||
}
|
||||
|
||||
//Declare and instantiate GET variables
|
||||
$action = (isset($_GET['action'])) ? filter_var(urldecode($_GET['action']), FILTER_SANITIZE_STRING) : "";
|
||||
$project = (isset($_GET['project'])) ? filter_var(urldecode($_GET['project']), FILTER_SANITIZE_STRING) : "";
|
||||
$remote = (isset($_GET['remote'])) ? filter_var(urldecode($_GET['remote']), FILTER_SANITIZE_NUMBER_INT) : "";
|
||||
|
||||
//Declare and instantiate POST variables
|
||||
$username = (isset($_POST['username'])) ? filter_var(urldecode($_POST['username']), FILTER_SANITIZE_STRING) : "";
|
||||
$password = (isset($_POST['password'])) ? filter_var(urldecode($_POST['password']), FILTER_SANITIZE_STRING) : "";
|
||||
|
||||
//Require code from lxd-dashboard/php/config/db.php
|
||||
require_once('../config/db.php');
|
||||
|
||||
//Require code from lxd-dashboard/php/aaa/authorization.php
|
||||
require_once('../aaa/authorization.php');
|
||||
|
||||
//Require code from lxd-dashboard/php/aaa/accounting.php
|
||||
require_once('../aaa/accounting.php');
|
||||
|
||||
//Run the matching action
|
||||
switch ($action) {
|
||||
|
||||
case "authenticateUser":
|
||||
//Determine user info from database
|
||||
foreach (retrieveUserRecord($username) as $record){
|
||||
$user_id = $record['id'];
|
||||
$passwd_hash = $record['passwd_hash'];
|
||||
}
|
||||
|
||||
//Verify password matches existing database passwd_hash
|
||||
if (password_verify($password, $passwd_hash)) {
|
||||
|
||||
//Store username and user_id in SESSION variable
|
||||
$_SESSION['username'] = $username;
|
||||
$_SESSION['user_id'] = $user_id;
|
||||
|
||||
//Get all the roles that the user belongs to
|
||||
$roles = array();
|
||||
foreach (retrieveUserRoles($user_id) as $role){
|
||||
array_push($roles, $role['name']);
|
||||
}
|
||||
|
||||
//Make sure array only has unique values
|
||||
$roles = array_unique($roles);
|
||||
|
||||
//Get array of contols based on the user's roles
|
||||
$controls = getControls($roles);
|
||||
|
||||
//Store user's controls in a SESSION array
|
||||
$_SESSION['controls'] = $controls;
|
||||
|
||||
$results = '{"status": "Ok", "status_code": 200, "metadata": "{}"}';
|
||||
}
|
||||
else {
|
||||
//Return 401 Unauthorized despite it technically being unauthenticated
|
||||
$results = '{"status": "Unauthorized", "status_code": 401, "metadata": {"error": "Incorrect username or password"}}';
|
||||
}
|
||||
|
||||
echo $results;
|
||||
|
||||
//Send event to accounting
|
||||
$event = json_decode($results, true);
|
||||
$object = $username;
|
||||
logEvent($action, $remote, $project, $object, $event['status_code'], $event['status']);
|
||||
|
||||
break;
|
||||
|
||||
case "deauthenticateUser":
|
||||
$username = $_SESSION['username'];
|
||||
//Clear the SESSION variables
|
||||
$_SESSION = array();
|
||||
if (session_destroy())
|
||||
$results = '{"status": "Ok", "status_code": 200, "metadata": "{}"}';
|
||||
|
||||
echo $results;
|
||||
|
||||
//Send event to accounting
|
||||
$event = json_decode($results, true);
|
||||
$object = $username;
|
||||
logEvent($action, $remote, $project, $object, $event['status_code'], $event['status']);
|
||||
|
||||
break;
|
||||
|
||||
case "validateAuthentication":
|
||||
if (isset($_SESSION['username'])){
|
||||
echo '{"status": "Ok", "status_code": 200, "metadata": "{}"}';
|
||||
}
|
||||
else {
|
||||
echo '{"status": "Unauthorized", "status_code": 401, "metadata": {"error": "Failed authentication validation"}}';
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
echo "LXDWARE";
|
||||
}
|
||||
|
||||
?>
|
|
@ -1,489 +0,0 @@
|
|||
<?php
|
||||
/*
|
||||
LXDWARE LXD Dashboard - A web-based interface for managing LXD servers
|
||||
Copyright (C) 2020-2021 LXDWARE.COM
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
//Start session if not already started
|
||||
if (!isset($_SESSION)) {
|
||||
session_start();
|
||||
}
|
||||
|
||||
//Declare and instantiate GET variables
|
||||
$action = (isset($_GET['action'])) ? filter_var(urldecode($_GET['action']), FILTER_SANITIZE_STRING) : "";
|
||||
$description = (isset($_GET['description'])) ? filter_var(urldecode($_GET['description']), FILTER_SANITIZE_STRING) : "";
|
||||
$id = (isset($_GET['id'])) ? filter_var(urldecode($_GET['id']), FILTER_SANITIZE_NUMBER_INT) : "";
|
||||
$group_id = (isset($_GET['group_id'])) ? filter_var(urldecode($_GET['group_id']), FILTER_SANITIZE_NUMBER_INT) : "";
|
||||
$name = (isset($_GET['name'])) ? filter_var(urldecode($_GET['name']), FILTER_SANITIZE_STRING) : "";
|
||||
$project = (isset($_GET['project'])) ? filter_var(urldecode($_GET['project']), FILTER_SANITIZE_STRING) : "";
|
||||
$remote = (isset($_GET['remote'])) ? filter_var(urldecode($_GET['remote']), FILTER_SANITIZE_NUMBER_INT) : "";
|
||||
$role_id = (isset($_GET['role_id'])) ? filter_var(urldecode($_GET['role_id']), FILTER_SANITIZE_NUMBER_INT) : "";
|
||||
|
||||
//Declare and instantiate POST variables
|
||||
$email = (isset($_POST['email'])) ? filter_var(urldecode($_POST['email']), FILTER_SANITIZE_STRING) : "";
|
||||
$first_name = (isset($_POST['first_name'])) ? filter_var(urldecode($_POST['first_name']), FILTER_SANITIZE_STRING) : "";
|
||||
$last_name = (isset($_POST['last_name'])) ? filter_var(urldecode($_POST['last_name']), FILTER_SANITIZE_STRING) : "";
|
||||
$password = (isset($_POST['password'])) ? $_POST['password'] : "";
|
||||
$username = (isset($_POST['username'])) ? filter_var(urldecode($_POST['username']), FILTER_SANITIZE_STRING) : "";
|
||||
|
||||
//Require code from lxd-dashboard/php/config/db.php
|
||||
require_once('../config/db.php');
|
||||
|
||||
//Require code from lxd-dashboard/php/aaa/accounting.php
|
||||
require_once('../aaa/accounting.php');
|
||||
|
||||
if (isset($_SESSION['username'])) {
|
||||
|
||||
require_once('../aaa/authorization.php');
|
||||
|
||||
//Run the matching action
|
||||
switch ($action) {
|
||||
|
||||
case "addRoleToGroup":
|
||||
if (validateAuthorization($action)) {
|
||||
$record_added = addGroupRoleMapping($id, $role_id);
|
||||
|
||||
if ($record_added)
|
||||
$results = '{"status": "Ok", "status_code": 200, "metadata": {"status": "Record added"}}';
|
||||
else
|
||||
$results = '{"status": "Bad Request", "status_code": 400, "metadata": {"error": "Unable to add the record to the database"}}';
|
||||
|
||||
}
|
||||
else {
|
||||
$results = '{"status": "Forbidden", "status_code": 403, "metadata": {"error": "You are not authorized to execute this action"}}';
|
||||
}
|
||||
|
||||
echo $results;
|
||||
|
||||
//Send event to accounting
|
||||
$event = json_decode($results, true);
|
||||
$object = $id . " - " . $role_id;
|
||||
logEvent($action, $remote, $project, $object, $event['status_code'], $event['status']);
|
||||
|
||||
break;
|
||||
|
||||
case "addUserToGroup":
|
||||
if (validateAuthorization($action)) {
|
||||
$record_added = addUserGroupMapping($id, $group_id);
|
||||
|
||||
if ($record_added)
|
||||
$results = '{"status": "Ok", "status_code": 200, "metadata": {"status": "Record added"}}';
|
||||
else
|
||||
$results = '{"status": "Bad Request", "status_code": 400, "metadata": {"error": "Unable to add the record to the database"}}';
|
||||
|
||||
}
|
||||
else {
|
||||
$results = '{"status": "Forbidden", "status_code": 403, "metadata": {"error": "You are not authorized to execute this action"}}';
|
||||
}
|
||||
|
||||
echo $results;
|
||||
|
||||
//Send event to accounting
|
||||
$event = json_decode($results, true);
|
||||
$object = $id . " - " . $group_id;
|
||||
logEvent($action, $remote, $project, $object, $event['status_code'], $event['status']);
|
||||
|
||||
break;
|
||||
|
||||
case "createGroup":
|
||||
if (validateAuthorization($action)) {
|
||||
$record_added = addGroup($name, $description);
|
||||
|
||||
if($record_added){
|
||||
$results = '{"status": "Ok", "status_code": 200, "metadata": "{}"}';
|
||||
$group_id = retrieveGroupId($name);
|
||||
}
|
||||
else {
|
||||
$results = '{"status": "Bad Request", "status_code": 400, "metadata": {"error": "Unable to add the record to the database"}}';
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
$results = '{"status": "Forbidden", "status_code": 403, "metadata": {"error": "You are not authorized to execute this action"}}';
|
||||
}
|
||||
|
||||
echo $results;
|
||||
|
||||
//Send event to accounting
|
||||
$event = json_decode($results, true);
|
||||
$object = $group_id . " - " . $name;
|
||||
logEvent($action, $remote, $project, $object, $event['status_code'], $event['status']);
|
||||
|
||||
break;
|
||||
|
||||
case "createUser":
|
||||
if (validateAuthorization($action)) {
|
||||
//Test to verify username and password both have a value
|
||||
if (!empty($username) && !empty($password)) {
|
||||
|
||||
//Hash and salt password with bcrypt
|
||||
$passwd_hash = password_hash($password, PASSWORD_BCRYPT);
|
||||
|
||||
if(isFirstUser()){
|
||||
$record_added = addUser($username, $first_name, $last_name, $passwd_hash, $email);
|
||||
|
||||
if($record_added){
|
||||
$user_id = retrieveUserId($username);
|
||||
$group_id = retrieveGroupId('admin');
|
||||
addUserGroupMapping($user_id, $group_id);
|
||||
}
|
||||
$results = '{"status": "Ok", "status_code": 200, "metadata": "{}"}';
|
||||
}
|
||||
else {
|
||||
$record_added = addUser($username, $first_name, $last_name, $passwd_hash, $email);
|
||||
|
||||
if($record_added){
|
||||
$user_id = retrieveUserId($username);
|
||||
$group_id = retrieveGroupId('auditor');
|
||||
|
||||
if($group_id){
|
||||
addUserGroupMapping($user_id, $group_id);
|
||||
}
|
||||
|
||||
$results = '{"status": "Ok", "status_code": 200, "metadata": "{}"}';
|
||||
}
|
||||
else {
|
||||
$results = '{"status": "Bad Request", "status_code": 400, "metadata": {"error": "Unable to add the record to the database"}}';
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
else {
|
||||
$results = '{"status": "Bad Request", "status_code": 400, "metadata": {"error": "Both a username and password must be supplied"}}';
|
||||
}
|
||||
}
|
||||
else {
|
||||
$results = '{"status": "Forbidden", "status_code": 403, "metadata": {"error": "You are not authorized to execute this action"}}';
|
||||
}
|
||||
|
||||
echo $results;
|
||||
|
||||
//Send event to accounting
|
||||
$event = json_decode($results, true);
|
||||
$object = $user_id . " - " . $username;
|
||||
logEvent($action, $remote, $project, $object, $event['status_code'], $event['status']);
|
||||
|
||||
break;
|
||||
|
||||
case "deleteGroup":
|
||||
if (validateAuthorization($action)) {
|
||||
$record_removed = deleteGroup($id);
|
||||
|
||||
if ($record_removed)
|
||||
$results = '{"status": "Ok", "status_code": 200, "metadata": {"status": "Record removed"}}';
|
||||
else
|
||||
$results = '{"status": "Bad Request", "status_code": 400, "metadata": {"error": "Unable to remove record from database"}}';
|
||||
|
||||
}
|
||||
else {
|
||||
$results = '{"status": "Forbidden", "status_code": 403, "metadata": {"error": "You are not authorized to execute this action"}}';
|
||||
}
|
||||
|
||||
echo $results;
|
||||
|
||||
//Send event to accounting
|
||||
$event = json_decode($results, true);
|
||||
$object = $id;
|
||||
logEvent($action, $remote, $project, $object, $event['status_code'], $event['status']);
|
||||
|
||||
break;
|
||||
|
||||
case "deleteUser":
|
||||
if (validateAuthorization($action)) {
|
||||
$record_removed = deleteUser($id);
|
||||
|
||||
if ($record_removed)
|
||||
$results = '{"status": "Ok", "status_code": 200, "metadata": {"status": "Record removed"}}';
|
||||
else
|
||||
$results = '{"status": "Bad Request", "status_code": 400, "metadata": {"error": "Unable to remove record from database"}}';
|
||||
|
||||
}
|
||||
else {
|
||||
$results = '{"status": "Forbidden", "status_code": 403, "metadata": {"error": "You are not authorized to execute this action"}}';
|
||||
}
|
||||
|
||||
echo $results;
|
||||
|
||||
//Send event to accounting
|
||||
$event = json_decode($results, true);
|
||||
$object = $id;
|
||||
logEvent($action, $remote, $project, $object, $event['status_code'], $event['status']);
|
||||
|
||||
break;
|
||||
|
||||
case "displayUsername":
|
||||
echo htmlentities($_SESSION['username']);
|
||||
break;
|
||||
|
||||
case "listGroups":
|
||||
if (validateAuthorization($action)) {
|
||||
$rows = retrieveTableRows('lxd_groups');
|
||||
|
||||
$i = 0;
|
||||
echo '{ "data": [';
|
||||
|
||||
foreach ($rows as $row){
|
||||
|
||||
$roles = retrieveGroupRoles($row['id']);
|
||||
$users = retrieveGroupUsers($row['id']);
|
||||
|
||||
if ($i > 0){
|
||||
echo ",";
|
||||
}
|
||||
$i++;
|
||||
|
||||
echo "[ ";
|
||||
echo '"';
|
||||
echo "<i class='fas fa-users fa-lg' style='color:#4e73df'></i>";
|
||||
echo '",';
|
||||
echo '"' . htmlentities($row['name']) . '",';
|
||||
echo '"' . htmlentities($row['description']) . '",';
|
||||
|
||||
echo '"';
|
||||
$ii = 0;
|
||||
foreach ($roles as $role){
|
||||
if ($ii > 0){
|
||||
echo ", ";
|
||||
}
|
||||
$ii++;
|
||||
echo htmlentities($role['name']);
|
||||
}
|
||||
echo '",';
|
||||
|
||||
echo '"';
|
||||
echo "<a href='#' onclick='loadAddRoleModal(".$row['id'].")'><i class='fas fa-plus fa-lg' style='color:#ddd' title='Add Role' aria-hidden='true'></i></a>";
|
||||
echo '   ';
|
||||
echo "<a href='#' onclick='loadRemoveRoleModal(".$row['id'].")'><i class='fas fa-minus fa-lg' style='color:#ddd' title='Remove Role' aria-hidden='true'></i></a>";
|
||||
echo '   ';
|
||||
echo "<a href='#' onclick='loadDeleteGroupModal(".$row['id'].")'><i class='fas fa-trash-alt fa-lg' style='color:#ddd' title='Delete Group' aria-hidden='true'></i></a>";
|
||||
echo '"';
|
||||
|
||||
echo " ]";
|
||||
}
|
||||
|
||||
echo " ]}";
|
||||
}
|
||||
else {
|
||||
echo '{ "data": [] }';
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case "listGroupsAssignedToUserForSelect":
|
||||
if (validateAuthorization($action)) {
|
||||
$groups = retrieveUserGroups($id);
|
||||
foreach ($groups as $group){
|
||||
echo '<option value="' . $group['id'] . '">' . htmlentities($group['name']) . '</option>';
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case "listGroupsNotAssignedToUserForSelect":
|
||||
if (validateAuthorization($action)) {
|
||||
$groups = retrieveTableRows('lxd_groups');
|
||||
$user_groups = retrieveUserGroups($id);
|
||||
|
||||
foreach ($groups as $group){
|
||||
|
||||
$group_belongs_to_user = false;
|
||||
|
||||
foreach ($user_groups as $user_group){
|
||||
if ($user_group['name'] == $group['name']){
|
||||
$group_belongs_to_user = true;
|
||||
}
|
||||
}
|
||||
|
||||
if(!$group_belongs_to_user){
|
||||
echo '<option value="' . $group['id'] . '">' . htmlentities($group['name']) . '</option>';
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case "listRolesAssignedToGroupForSelect":
|
||||
if (validateAuthorization($action)) {
|
||||
$roles = retrieveGroupRoles($id);
|
||||
foreach ($roles as $role){
|
||||
echo '<option value="' . $role['id'] . '">' . htmlentities($role['name']) . '</option>';
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case "listRolesNotAssignedToGroupForSelect":
|
||||
if (validateAuthorization($action)) {
|
||||
$roles = retrieveDefaultRoles();
|
||||
|
||||
$group_roles = retrieveGroupRoles($id);
|
||||
|
||||
foreach ($roles as $role){
|
||||
|
||||
$role_belongs_to_group = false;
|
||||
|
||||
foreach ($group_roles as $group_role){
|
||||
if ($group_role['name'] == $role['name']){
|
||||
$role_belongs_to_group = true;
|
||||
}
|
||||
}
|
||||
|
||||
if(!$role_belongs_to_group){
|
||||
echo '<option value="' . $role['id'] . '">' . htmlentities($role['name']) . '</option>';
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case "listUsers":
|
||||
if (validateAuthorization($action)) {
|
||||
$rows = retrieveTableRows('lxd_users');
|
||||
|
||||
$i = 0;
|
||||
echo '{ "data": [';
|
||||
|
||||
foreach ($rows as $row){
|
||||
|
||||
$groups = retrieveUserGroups($row['id']);
|
||||
|
||||
if ($i > 0){
|
||||
echo ",";
|
||||
}
|
||||
$i++;
|
||||
|
||||
echo "[ ";
|
||||
|
||||
echo '"';
|
||||
echo "<a href='user-profile.html?user=".$row['id']."'><i class='fas fa-user fa-lg' style='color:#4e73df'></i> </a>";
|
||||
echo '",';
|
||||
|
||||
echo '"';
|
||||
echo "<a href='user-profile.html?user=".$row['id']."'> ".htmlentities($row['username'])."</a>";
|
||||
echo '",';
|
||||
|
||||
echo '"' . htmlentities($row['email']) . '",';
|
||||
echo '"' . htmlentities($row['type']) . '",';
|
||||
|
||||
echo '"';
|
||||
$ii = 0;
|
||||
foreach ($groups as $group){
|
||||
if ($ii > 0){
|
||||
echo ", ";
|
||||
}
|
||||
$ii++;
|
||||
echo htmlentities($group['name']);
|
||||
}
|
||||
echo '",';
|
||||
|
||||
echo '"';
|
||||
echo "<a href='#' onclick='loadAddGroupModal(".$row['id'].")'><i class='fas fa-plus fa-lg' style='color:#ddd' title='Add Group' aria-hidden='true'></i></a>";
|
||||
echo '   ';
|
||||
echo "<a href='#' onclick='loadRemoveGroupModal(".$row['id'].")'><i class='fas fa-minus fa-lg' style='color:#ddd' title='Remove Group' aria-hidden='true'></i></a>";
|
||||
echo '   ';
|
||||
echo "<a href='#' onclick='loadDeleteUserModal(".$row['id'].")'><i class='fas fa-trash-alt fa-lg' style='color:#ddd' title='Delete User' aria-hidden='true'></i></a>";
|
||||
echo '"';
|
||||
|
||||
echo " ]";
|
||||
}
|
||||
|
||||
echo " ]}";
|
||||
}
|
||||
else {
|
||||
echo '{ "data": [] }';
|
||||
}
|
||||
break;
|
||||
|
||||
case "removeGroupFromUser":
|
||||
if (validateAuthorization($action)) {
|
||||
$record_removed = deleteUserGroupMapping($id, $group_id);
|
||||
|
||||
if ($record_removed)
|
||||
$results = '{"status": "Ok", "status_code": 200, "metadata": {"status": "Record removed"}}';
|
||||
else
|
||||
$results = '{"status": "Bad Request", "status_code": 400, "metadata": {"error": "Unable to remove record from database"}}';
|
||||
|
||||
}
|
||||
else {
|
||||
$results = '{"status": "Forbidden", "status_code": 403, "metadata": {"error": "You are not authorized to execute this action"}}';
|
||||
}
|
||||
|
||||
echo $results;
|
||||
|
||||
//Send event to accounting
|
||||
$event = json_decode($results, true);
|
||||
$object = $id . " - " . $group_id;
|
||||
logEvent($action, $remote, $project, $object, $event['status_code'], $event['status']);
|
||||
|
||||
break;
|
||||
|
||||
case "removeRoleFromGroup":
|
||||
if (validateAuthorization($action)) {
|
||||
$record_removed = deleteGroupRoleMapping($id, $role_id);
|
||||
|
||||
if ($record_removed)
|
||||
$results = '{"status": "Ok", "status_code": 200, "metadata": {"status": "Record removed"}}';
|
||||
else
|
||||
$results = '{"status": "Bad Request", "status_code": 400, "metadata": {"error": "Unable to remove record from database"}}';
|
||||
|
||||
}
|
||||
else {
|
||||
$results = '{"status": "Forbidden", "status_code": 403, "metadata": {"error": "You are not authorized to execute this action"}}';
|
||||
}
|
||||
|
||||
echo $results;
|
||||
|
||||
//Send event to accounting
|
||||
$event = json_decode($results, true);
|
||||
$object = $id . " - " . $role_id;
|
||||
logEvent($action, $remote, $project, $object, $event['status_code'], $event['status']);
|
||||
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
switch ($action) {
|
||||
case "createUser":
|
||||
//Test to verify username and password both have a value
|
||||
if (!empty($username) && !empty($password)) {
|
||||
|
||||
//Hash and salt password with bcrypt
|
||||
$passwd_hash = password_hash($password, PASSWORD_BCRYPT);
|
||||
|
||||
if(isFirstUser()){
|
||||
$record_added = addUser($username, $first_name, $last_name, $passwd_hash, $email);
|
||||
|
||||
if($record_added){
|
||||
$user_id = retrieveUserId($username);
|
||||
$group_id = retrieveGroupId('admin');
|
||||
addUserGroupMapping($user_id, $group_id);
|
||||
}
|
||||
$results = '{"status": "Ok", "status_code": 200, "metadata": "{}"}';
|
||||
}
|
||||
else {
|
||||
$results = '{"status": "Bad Request", "status_code": 400, "metadata": {"error": "User was not added as there are already existing user accounts"}}';
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
$results = '{"status": "Bad Request", "status_code": 400, "metadata": {"error": "Must supply both a username and password"}}';
|
||||
}
|
||||
|
||||
echo $results;
|
||||
break;
|
||||
}
|
||||
}
|
||||
?>
|
|
@ -1,70 +0,0 @@
|
|||
<?php
|
||||
/*
|
||||
LXDWARE LXD Dashboard - A web-based interface for managing LXD servers
|
||||
Copyright (C) 2020-2021 LXDWARE.COM
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
//Start session if not already started
|
||||
if (!isset($_SESSION)) {
|
||||
session_start();
|
||||
}
|
||||
|
||||
//Create Certificate if it does not already exist
|
||||
if (!file_exists('/var/lxdware/data/lxd/client.crt')){
|
||||
$subject = array(
|
||||
"commonName" => "LXDWARE",
|
||||
);
|
||||
|
||||
//Generate a new private (and public) key pair
|
||||
$private_key = openssl_pkey_new(array(
|
||||
"private_key_type" => OPENSSL_KEYTYPE_EC,
|
||||
"curve_name" => 'secp384r1',
|
||||
));
|
||||
|
||||
//Generate a certificate signing request
|
||||
$csr = openssl_csr_new($subject, $private_key);
|
||||
|
||||
//Generate self-signed EC cert
|
||||
$x509 = openssl_csr_sign($csr, null, $private_key, $days=3650);
|
||||
openssl_x509_export_to_file($x509, '/var/lxdware/data/lxd/client.crt');
|
||||
openssl_pkey_export_to_file($private_key, '/var/lxdware/data/lxd/client.key');
|
||||
|
||||
//Change permissions on private key
|
||||
chmod('/var/lxdware/data/lxd/client.key',0600);
|
||||
}
|
||||
|
||||
if (isset($_SESSION['username'])) {
|
||||
|
||||
//Declare and instantiate GET variables
|
||||
$action = (isset($_GET['action'])) ? filter_var(urldecode($_GET['action']), FILTER_SANITIZE_STRING) : "";
|
||||
|
||||
require_once('../aaa/authorization.php');
|
||||
|
||||
//Run the matching action
|
||||
switch ($action) {
|
||||
case "viewCertificate":
|
||||
if (validateAuthorization($action)) {
|
||||
$results = shell_exec("cat /var/lxdware/data/lxd/client.crt");
|
||||
echo htmlentities($results);
|
||||
}
|
||||
else {
|
||||
echo "You are not authorized to view the certificate";
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
|
@ -1,878 +0,0 @@
|
|||
<?php
|
||||
/*
|
||||
LXDWARE LXD Dashboard - A web-based interface for managing LXD servers
|
||||
Copyright (C) 2020-2021 LXDWARE.COM
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
//Start session if not already started
|
||||
if (!isset($_SESSION)) {
|
||||
session_start();
|
||||
}
|
||||
|
||||
function establishDatabaseConnection(){
|
||||
|
||||
//Require db_config.php file
|
||||
require_once('/var/lxdware/data/db_config.php');
|
||||
|
||||
switch (DB_TYPE) {
|
||||
case "sqlite":
|
||||
$_SESSION['db_type'] = "SQLite";
|
||||
$conn = new PDO('sqlite:/var/lxdware/data/sqlite/lxdware.sqlite');
|
||||
break;
|
||||
}
|
||||
|
||||
return $conn;
|
||||
}
|
||||
|
||||
/*
|
||||
===================================================================================
|
||||
Initialize Table Functions
|
||||
===================================================================================
|
||||
*/
|
||||
function initializeEventsTable(){
|
||||
$db = establishDatabaseConnection();
|
||||
|
||||
if ($_SESSION['db_type'] == "SQLite"){
|
||||
$db->exec('CREATE TABLE IF NOT EXISTS lxd_events (id INTEGER PRIMARY KEY AUTOINCREMENT, control TEXT, remote_id INTEGER, project TEXT, object TEXT, status_code INT, message TEXT, hostname TEXT, user_id INT, date DATETIME)');
|
||||
}
|
||||
|
||||
$db = null;
|
||||
}
|
||||
|
||||
function initializeHostsTable(){
|
||||
$db = establishDatabaseConnection();
|
||||
|
||||
if ($_SESSION['db_type'] == "SQLite"){
|
||||
$db->exec('CREATE TABLE IF NOT EXISTS lxd_hosts (id INTEGER PRIMARY KEY AUTOINCREMENT, host TEXT NOT NULL, port INTEGER NOT NULL, alias TEXT, protocol TEXT, user_id INTEGER)');
|
||||
|
||||
//If needed, upgrade database table schema from LXD Dashboard version 1.x.x to 2.x.x
|
||||
$stmt = $db->query("PRAGMA table_info(lxd_hosts)");
|
||||
$results = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
if (!in_array('user_id', $results)){
|
||||
$stmt = $db->query("ALTER TABLE lxd_hosts ADD COLUMN user_id INTEGER");
|
||||
$stmt = $db->query("UPDATE lxd_hosts SET user_id = 0");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
$db = null;
|
||||
}
|
||||
|
||||
function initializeGroupsRolesMappingTable(){
|
||||
$db = establishDatabaseConnection();
|
||||
|
||||
if ($_SESSION['db_type'] == "SQLite"){
|
||||
$db->exec('CREATE TABLE IF NOT EXISTS lxd_groups_roles_mapping (id INTEGER PRIMARY KEY AUTOINCREMENT, group_id INTEGER NOT NULL, role_id INTEGER NOT NULL)');
|
||||
}
|
||||
|
||||
//Map admin group to ADMIN role
|
||||
$group_id = retrieveGroupId('admin');
|
||||
$role_id = retrieveRoleId('ADMIN');
|
||||
$stmt = $db->prepare('INSERT INTO lxd_groups_roles_mapping (group_id, role_id) VALUES (:group_id, :role_id)');
|
||||
$stmt->bindValue(':group_id', $group_id, PDO::PARAM_INT);
|
||||
$stmt->bindValue(':role_id', $role_id, PDO::PARAM_INT);
|
||||
$stmt->execute();
|
||||
$return_val = $stmt->fetchColumn();
|
||||
|
||||
//Map operator group to OPERATOR role
|
||||
$group_id = retrieveGroupId('operator');
|
||||
$role_id = retrieveRoleId('OPERATOR');
|
||||
$stmt = $db->prepare('INSERT INTO lxd_groups_roles_mapping (group_id, role_id) VALUES (:group_id, :role_id)');
|
||||
$stmt->bindValue(':group_id', $group_id, PDO::PARAM_INT);
|
||||
$stmt->bindValue(':role_id', $role_id, PDO::PARAM_INT);
|
||||
$stmt->execute();
|
||||
$return_val = $stmt->fetchColumn();
|
||||
|
||||
//Map user group to USER role
|
||||
$group_id = retrieveGroupId('user');
|
||||
$role_id = retrieveRoleId('USER');
|
||||
$stmt = $db->prepare('INSERT INTO lxd_groups_roles_mapping (group_id, role_id) VALUES (:group_id, :role_id)');
|
||||
$stmt->bindValue(':group_id', $group_id, PDO::PARAM_INT);
|
||||
$stmt->bindValue(':role_id', $role_id, PDO::PARAM_INT);
|
||||
$stmt->execute();
|
||||
$return_val = $stmt->fetchColumn();
|
||||
|
||||
//Map auditor group to AUDITOR role
|
||||
$group_id = retrieveGroupId('auditor');
|
||||
$role_id = retrieveRoleId('AUDITOR');
|
||||
$stmt = $db->prepare('INSERT INTO lxd_groups_roles_mapping (group_id, role_id) VALUES (:group_id, :role_id)');
|
||||
$stmt->bindValue(':group_id', $group_id, PDO::PARAM_INT);
|
||||
$stmt->bindValue(':role_id', $role_id, PDO::PARAM_INT);
|
||||
$stmt->execute();
|
||||
$return_val = $stmt->fetchColumn();
|
||||
|
||||
$db = null;
|
||||
}
|
||||
|
||||
function initializeGroupsTable(){
|
||||
$db = establishDatabaseConnection();
|
||||
|
||||
if ($_SESSION['db_type'] == "SQLite"){
|
||||
$db->exec('CREATE TABLE IF NOT EXISTS lxd_groups (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL UNIQUE, description TEXT)');
|
||||
}
|
||||
|
||||
$adminGroupExists = false;
|
||||
$operatorGroupExists = false;
|
||||
$userGroupExists = false;
|
||||
$auditorGroupExists = false;
|
||||
|
||||
$rows = $db->query('SELECT * FROM lxd_groups');
|
||||
foreach ($rows as $row){
|
||||
if ($row['name'] == "admin")
|
||||
$adminGroupExists = true;
|
||||
|
||||
if ($row['name'] == "operator")
|
||||
$operatorGroupExists = true;
|
||||
|
||||
if ($row['name'] == "user")
|
||||
$userGroupExists = true;
|
||||
|
||||
if ($row['name'] == "auditor")
|
||||
$auditorGroupExists = true;
|
||||
}
|
||||
|
||||
if (!$adminGroupExists){
|
||||
$db->exec('INSERT INTO lxd_groups (name, description) VALUES ("admin", "Default group granting users the ADMIN role permissions")');
|
||||
}
|
||||
|
||||
if (!$operatorGroupExists){
|
||||
$db->exec('INSERT INTO lxd_groups (name, description) VALUES ("operator", "Default group granting users the OPERATOR role permissions")');
|
||||
}
|
||||
|
||||
if (!$userGroupExists){
|
||||
$db->exec('INSERT INTO lxd_groups (name, description) VALUES ("user", "Default group granting users the USER role permissions")');
|
||||
}
|
||||
|
||||
if (!$auditorGroupExists){
|
||||
$db->exec('INSERT INTO lxd_groups (name, description) VALUES ("auditor", "Default group granting users the AUDITOR role permissions")');
|
||||
}
|
||||
|
||||
$db = null;
|
||||
}
|
||||
|
||||
function initializeRolesTable(){
|
||||
$db = establishDatabaseConnection();
|
||||
|
||||
if ($_SESSION['db_type'] == "SQLite"){
|
||||
$db->exec('CREATE TABLE IF NOT EXISTS lxd_roles (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL UNIQUE, description TEXT)');
|
||||
}
|
||||
|
||||
//Default Roles
|
||||
$adminRoleExists = false;
|
||||
$operatorRoleExists = false;
|
||||
$userRoleExists = false;
|
||||
$auditorRoleExists = false;
|
||||
|
||||
//Extended Roles
|
||||
$certificateOperatorRoleExists = false;
|
||||
$clusterMemeberOperatorRoleExists = false;
|
||||
$imageOperatorRoleExists = false;
|
||||
$instanceOperatorRoleExists = false;
|
||||
$networkOperatorRoleExists = false;
|
||||
$operationOperatorRoleExists = false;
|
||||
$profileOperatorRoleExists = false;
|
||||
$projectOperatorRoleExists = false;
|
||||
$remoteOperatorRoleExists = false;
|
||||
$simplestreamsOperatorRoleExists = false;
|
||||
$storagePoolOperatorRoleExists = false;
|
||||
$storageVolumeOperatorRoleExists = false;
|
||||
|
||||
$rows = $db->query('SELECT * from lxd_roles');
|
||||
foreach ($rows as $row){
|
||||
//Default Roles
|
||||
if ($row['name'] == "ADMIN")
|
||||
$adminRoleExists = true;
|
||||
|
||||
if ($row['name'] == "OPERATOR")
|
||||
$operatorRoleExists = true;
|
||||
|
||||
if ($row['name'] == "USER")
|
||||
$userRoleExists = true;
|
||||
|
||||
if ($row['name'] == "AUDITOR")
|
||||
$auditorRoleExists = true;
|
||||
|
||||
//Extended Roles
|
||||
if ($row['name'] == "CERTIFICATE_OPERATOR")
|
||||
$certificateOperatorRoleExists = true;
|
||||
|
||||
if ($row['name'] == "CLUSTER_MEMBER_OPERATOR")
|
||||
$clusterMemeberOperatorRoleExists = true;
|
||||
|
||||
if ($row['name'] == "IMAGE_OPERATOR")
|
||||
$imageOperatorRoleExists = true;
|
||||
|
||||
if ($row['name'] == "INSTANCE_OPERATOR")
|
||||
$instanceOperatorRoleExists = true;
|
||||
|
||||
if ($row['name'] == "NETWORK_OPERATOR")
|
||||
$networkOperatorRoleExists = true;
|
||||
|
||||
if ($row['name'] == "OPERATION_OPERATOR")
|
||||
$operationOperatorRoleExists = true;
|
||||
|
||||
if ($row['name'] == "PROFILE_OPERATOR")
|
||||
$profileOperatorRoleExists = true;
|
||||
|
||||
if ($row['name'] == "PROJECT_OPERATOR")
|
||||
$projectOperatorRoleExists = true;
|
||||
|
||||
if ($row['name'] == "REMOTE_OPERATOR")
|
||||
$remoteOperatorRoleExists = true;
|
||||
|
||||
if ($row['name'] == "SIMPLESTREAMS_OPERATOR")
|
||||
$simplestreamsOperatorRoleExists = true;
|
||||
|
||||
if ($row['name'] == "STORAGE_POOL_OPERATOR")
|
||||
$storagePoolOperatorRoleExists = true;
|
||||
|
||||
if ($row['name'] == "STORAGE_VOLUME_OPERATOR")
|
||||
$storageVolumeOperatorRoleExists = true;
|
||||
}
|
||||
|
||||
//Default Roles
|
||||
if (!$adminRoleExists){
|
||||
$db->exec('INSERT INTO lxd_roles (name, description) VALUES ("ADMIN", "Administer users, groups, and all LXD services")');
|
||||
}
|
||||
|
||||
if (!$operatorRoleExists){
|
||||
$db->exec('INSERT INTO lxd_roles (name, description) VALUES ("OPERATOR", "Administer all LXD services")');
|
||||
}
|
||||
|
||||
if (!$userRoleExists){
|
||||
$db->exec('INSERT INTO lxd_roles (name, description) VALUES ("USER", "Perform basic lifecycle tasks of instances")');
|
||||
}
|
||||
|
||||
if (!$auditorRoleExists){
|
||||
$db->exec('INSERT INTO lxd_roles (name, description) VALUES ("AUDITOR", "View resources")');
|
||||
}
|
||||
|
||||
//Extended Roles
|
||||
if (!$certificateOperatorRoleExists){
|
||||
$db->exec('INSERT INTO lxd_roles (name, description) VALUES ("CERTIFICATE_OPERATOR", "Permissions include adding, deleting, and updating certificates")');
|
||||
}
|
||||
|
||||
if (!$clusterMemeberOperatorRoleExists){
|
||||
$db->exec('INSERT INTO lxd_roles (name, description) VALUES ("CLUSTER_MEMBER_OPERATOR", "Permissions include removing cluster members")');
|
||||
}
|
||||
|
||||
if (!$imageOperatorRoleExists){
|
||||
$db->exec('INSERT INTO lxd_roles (name, description) VALUES ("IMAGE_OPERATOR", "Permissions include downloading, editing, and deleteing images")');
|
||||
}
|
||||
|
||||
if (!$instanceOperatorRoleExists){
|
||||
$db->exec('INSERT INTO lxd_roles (name, description) VALUES ("INSTANCE_OPERATOR", "Permissions include creating, deleting, and updating instances")');
|
||||
}
|
||||
|
||||
if (!$networkOperatorRoleExists){
|
||||
$db->exec('INSERT INTO lxd_roles (name, description) VALUES ("NETWORK_OPERATOR", "Permissions include creating, deleting, and updating networks and network ACLs")');
|
||||
}
|
||||
|
||||
if (!$operationOperatorRoleExists){
|
||||
$db->exec('INSERT INTO lxd_roles (name, description) VALUES ("OPERATION_OPERATOR", "Permissions include deleting operations")');
|
||||
}
|
||||
|
||||
if (!$profileOperatorRoleExists){
|
||||
$db->exec('INSERT INTO lxd_roles (name, description) VALUES ("PROFILE_OPERATOR", "Permissions include creating, deleting, and updating profiles")');
|
||||
}
|
||||
|
||||
if (!$projectOperatorRoleExists){
|
||||
$db->exec('INSERT INTO lxd_roles (name, description) VALUES ("PROJECT_OPERATOR", "Permissions include creating, deleting, and updating projects")');
|
||||
}
|
||||
|
||||
if (!$remoteOperatorRoleExists){
|
||||
$db->exec('INSERT INTO lxd_roles (name, description) VALUES ("REMOTE_OPERATOR", "Permissions include adding and removing remote LXD hosts")');
|
||||
}
|
||||
|
||||
if (!$simplestreamsOperatorRoleExists){
|
||||
$db->exec('INSERT INTO lxd_roles (name, description) VALUES ("SIMPLESTREAMS_OPERATOR", "Permissions include adding and removing remote Simplestreams hosts")');
|
||||
}
|
||||
|
||||
if (!$storagePoolOperatorRoleExists){
|
||||
$db->exec('INSERT INTO lxd_roles (name, description) VALUES ("STORAGE_POOL_OPERATOR", "Permissions include creating, deleting, and updating storage pools")');
|
||||
}
|
||||
|
||||
if (!$storageVolumeOperatorRoleExists){
|
||||
$db->exec('INSERT INTO lxd_roles (name, description) VALUES ("STORAGE_VOLUME_OPERATOR", "Permissions include creating, deleting, and updating storge volumes")');
|
||||
}
|
||||
|
||||
$db = null;
|
||||
}
|
||||
|
||||
function initializeSimplestreamsTable(){
|
||||
$db = establishDatabaseConnection();
|
||||
|
||||
if ($_SESSION['db_type'] == "SQLite"){
|
||||
$db->exec('CREATE TABLE IF NOT EXISTS lxd_simplestreams (id INTEGER PRIMARY KEY AUTOINCREMENT, host TEXT NOT NULL, alias TEXT, protocol TEXT, user_id INTEGER)');
|
||||
|
||||
//If needed, upgrade database table schema from LXD Dashboard version 1.x.x to 2.x.x
|
||||
$stmt = $db->query("PRAGMA table_info(lxd_simplestreams)");
|
||||
$results = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
if (!in_array('user_id', $results)){
|
||||
$stmt = $db->query("ALTER TABLE lxd_simplestreams ADD COLUMN user_id INTEGER");
|
||||
$stmt = $db->query("UPDATE lxd_simplestreams SET user_id = 0");
|
||||
}
|
||||
}
|
||||
|
||||
$imagesSimplestreamsExists = false;
|
||||
$ubuntuSimplestreamsExists = false;
|
||||
$ubuntuDailySimplestreamsExists = false;
|
||||
|
||||
$rows = $db->query('SELECT * FROM lxd_simplestreams');
|
||||
foreach ($rows as $row){
|
||||
if ($row['host'] == "https://images.linuxcontainers.org")
|
||||
$imagesSimplestreamsExists = true;
|
||||
|
||||
if ($row['host'] == "https://cloud-images.ubuntu.com/releases")
|
||||
$ubuntuSimplestreamsExists = true;
|
||||
|
||||
if ($row['host'] == "https://cloud-images.ubuntu.com/daily")
|
||||
$ubuntuDailySimplestreamsExists = true;
|
||||
}
|
||||
|
||||
if (!$imagesSimplestreamsExists){
|
||||
$db->exec('INSERT INTO lxd_simplestreams (host, alias, protocol, user_id) VALUES ("https://images.linuxcontainers.org", "images", "simplestreams", 0)');
|
||||
}
|
||||
|
||||
if (!$ubuntuSimplestreamsExists){
|
||||
$db->exec('INSERT INTO lxd_simplestreams (host, alias, protocol, user_id) VALUES ("https://cloud-images.ubuntu.com/releases", "ubuntu", "simplestreams", 0)');
|
||||
}
|
||||
|
||||
if (!$ubuntuDailySimplestreamsExists){
|
||||
$db->exec('INSERT INTO lxd_simplestreams (host, alias, protocol, user_id) VALUES ("https://cloud-images.ubuntu.com/daily", "ubuntu-daily", "simplestreams", 0)');
|
||||
}
|
||||
|
||||
$db = null;
|
||||
|
||||
}
|
||||
|
||||
function initializeUsersGroupsMappingTable(){
|
||||
$db = establishDatabaseConnection();
|
||||
|
||||
if ($_SESSION['db_type'] == "SQLite"){
|
||||
$db->exec('CREATE TABLE IF NOT EXISTS lxd_users_groups_mapping (id INTEGER PRIMARY KEY AUTOINCREMENT, user_id INTEGER NOT NULL, group_id INTEGER NOT NULL)');
|
||||
}
|
||||
|
||||
$db = null;
|
||||
}
|
||||
|
||||
function initializeUsersTable(){
|
||||
$db = establishDatabaseConnection();
|
||||
|
||||
if ($_SESSION['db_type'] == "SQLite"){
|
||||
$db->exec('CREATE TABLE IF NOT EXISTS lxd_users (id INTEGER PRIMARY KEY AUTOINCREMENT, username TEXT NOT NULL UNIQUE, first_name TEXT, last_name TEXT, passwd_hash TEXT NOT NULL, email TEXT, type TEXT)');
|
||||
}
|
||||
|
||||
$db = null;
|
||||
}
|
||||
|
||||
function initializeAllTables(){
|
||||
initializeUsersTable();
|
||||
initializeGroupsTable();
|
||||
initializeRolesTable();
|
||||
initializeHostsTable();
|
||||
initializeSimplestreamsTable();
|
||||
initializeUsersGroupsMappingTable();
|
||||
initializeGroupsRolesMappingTable();
|
||||
initializeEventsTable();
|
||||
}
|
||||
/*
|
||||
===================================================================================
|
||||
Add Record to Table Functions
|
||||
===================================================================================
|
||||
*/
|
||||
|
||||
|
||||
function addEvent($control, $remote_id, $project, $object, $status_code, $message, $hostname, $user_id){
|
||||
$db = establishDatabaseConnection();
|
||||
|
||||
try{
|
||||
$stmt = $db->prepare("INSERT INTO lxd_events (control, remote_id, project, object, status_code, message, hostname, user_id, date) VALUES (:control, :remote_id, :project, :object, :status_code, :message, :hostname, :user_id, datetime('now'))");
|
||||
$stmt->bindValue(':control', $control, PDO::PARAM_STR);
|
||||
$stmt->bindValue(':remote_id', $remote_id, PDO::PARAM_INT);
|
||||
$stmt->bindValue(':project', $project, PDO::PARAM_STR);
|
||||
$stmt->bindValue(':object', $object, PDO::PARAM_STR);
|
||||
$stmt->bindValue(':status_code', $status_code, PDO::PARAM_INT);
|
||||
$stmt->bindValue(':message', $message, PDO::PARAM_STR);
|
||||
$stmt->bindValue(':hostname', $hostname, PDO::PARAM_STR);
|
||||
$stmt->bindValue(':user_id', $user_id, PDO::PARAM_INT);
|
||||
$stmt->execute();
|
||||
}
|
||||
catch (\Error $e) {
|
||||
initializeAllTables();
|
||||
$stmt = $db->prepare("INSERT INTO lxd_events (control, remote_id, project, object, status_code, message, hostname, user_id, date) VALUES (:control, :remote_id, :project, :object, :status_code, :message, :hostname, :user_id, datetime('now'))");
|
||||
$stmt->bindValue(':control', $control, PDO::PARAM_STR);
|
||||
$stmt->bindValue(':remote_id', $remote_id, PDO::PARAM_INT);
|
||||
$stmt->bindValue(':project', $project, PDO::PARAM_STR);
|
||||
$stmt->bindValue(':object', $object, PDO::PARAM_STR);
|
||||
$stmt->bindValue(':status_code', $status_code, PDO::PARAM_INT);
|
||||
$stmt->bindValue(':message', $message, PDO::PARAM_STR);
|
||||
$stmt->bindValue(':hostname', $hostname, PDO::PARAM_STR);
|
||||
$stmt->bindValue(':user_id', $user_id, PDO::PARAM_INT);
|
||||
$stmt->execute();
|
||||
}
|
||||
|
||||
$db = null;
|
||||
return $stmt;
|
||||
}
|
||||
|
||||
function addHost($host, $port, $alias){
|
||||
$db = establishDatabaseConnection();
|
||||
|
||||
$stmt = $db->prepare('INSERT INTO lxd_hosts (host, port, alias, protocol, user_id) VALUES (:host, :port, :alias, "lxd", :user_id)');
|
||||
$stmt->bindValue(':host', $host, PDO::PARAM_STR);
|
||||
$stmt->bindValue(':port', $port, PDO::PARAM_INT);
|
||||
$stmt->bindValue(':alias', $alias, PDO::PARAM_STR);
|
||||
$stmt->bindValue(':user_id', $_SESSION['user_id'], PDO::PARAM_INT);
|
||||
$stmt->execute();
|
||||
$db = null;
|
||||
return $stmt;
|
||||
}
|
||||
|
||||
function addSimplestreams($host, $alias){
|
||||
$db = establishDatabaseConnection();
|
||||
|
||||
$stmt = $db->prepare('INSERT INTO lxd_simplestreams (host, alias, protocol, user_id) VALUES (:host, :alias, "simplestreams", :user_id)');
|
||||
$stmt->bindValue(':host', $host, PDO::PARAM_STR);
|
||||
$stmt->bindValue(':alias', $alias, PDO::PARAM_STR);
|
||||
$stmt->bindValue(':user_id', $_SESSION['user_id'], PDO::PARAM_INT);
|
||||
$stmt->execute();
|
||||
$db = null;
|
||||
return $stmt;
|
||||
}
|
||||
|
||||
function addUser($username, $first_name, $last_name, $passwd_hash, $email){
|
||||
$db = establishDatabaseConnection();
|
||||
|
||||
$stmt = $db->prepare('INSERT INTO lxd_users (username, first_name, last_name, passwd_hash, email, type) VALUES (:username, :first_name, :last_name, :passwd_hash, :email, "local")');
|
||||
$stmt->bindValue(':username', $username, PDO::PARAM_STR);
|
||||
$stmt->bindValue(':first_name', $first_name, PDO::PARAM_STR);
|
||||
$stmt->bindValue(':last_name', $last_name, PDO::PARAM_STR);
|
||||
$stmt->bindValue(':passwd_hash', $passwd_hash, PDO::PARAM_STR);
|
||||
$stmt->bindValue(':email', $email, PDO::PARAM_STR);
|
||||
$stmt->execute();
|
||||
$db = null;
|
||||
return $stmt;
|
||||
}
|
||||
|
||||
function addGroup($name, $description){
|
||||
$db = establishDatabaseConnection();
|
||||
|
||||
$stmt = $db->prepare('INSERT INTO lxd_groups (name, description) VALUES (:name, :description)');
|
||||
$stmt->bindValue(':name', $name, PDO::PARAM_STR);
|
||||
$stmt->bindValue(':description', $description, PDO::PARAM_STR);
|
||||
$stmt->execute();
|
||||
$db = null;
|
||||
return $stmt;
|
||||
}
|
||||
|
||||
function addUserGroupMapping($user_id, $group_id) {
|
||||
$db = establishDatabaseConnection();
|
||||
|
||||
$stmt = $db->prepare('INSERT INTO lxd_users_groups_mapping (user_id, group_id) VALUES (:user_id, :group_id)');
|
||||
$stmt->bindValue(':user_id', $user_id, PDO::PARAM_INT);
|
||||
$stmt->bindValue(':group_id', $group_id, PDO::PARAM_INT);
|
||||
$stmt->execute();
|
||||
$db = null;
|
||||
return $stmt;
|
||||
}
|
||||
|
||||
function addGroupRoleMapping($group_id, $role_id) {
|
||||
$db = establishDatabaseConnection();
|
||||
|
||||
$stmt = $db->prepare('INSERT INTO lxd_groups_roles_mapping (group_id, role_id) VALUES (:group_id, :role_id)');
|
||||
$stmt->bindValue(':group_id', $group_id, PDO::PARAM_INT);
|
||||
$stmt->bindValue(':role_id', $role_id, PDO::PARAM_INT);
|
||||
$stmt->execute();
|
||||
$db = null;
|
||||
return $stmt;
|
||||
}
|
||||
|
||||
/*
|
||||
===================================================================================
|
||||
Delete Record from Table Functions
|
||||
===================================================================================
|
||||
*/
|
||||
|
||||
function deleteHost($id){
|
||||
$db = establishDatabaseConnection();
|
||||
$stmt = $db->prepare('DELETE FROM lxd_hosts WHERE id = :id');
|
||||
$stmt->bindValue(':id', $id, PDO::PARAM_INT);
|
||||
$stmt->execute();
|
||||
$db = null;
|
||||
return $stmt;
|
||||
}
|
||||
|
||||
function deleteSimplestreams($id){
|
||||
$db = establishDatabaseConnection();
|
||||
$stmt = $db->prepare('DELETE FROM lxd_simplestreams WHERE id = :id');
|
||||
$stmt->bindValue(':id', $id, PDO::PARAM_INT);
|
||||
$stmt->execute();
|
||||
$db = null;
|
||||
return $stmt;
|
||||
}
|
||||
|
||||
function deleteUser($id){
|
||||
$db = establishDatabaseConnection();
|
||||
$stmt = $db->prepare('DELETE FROM lxd_users WHERE id = :id');
|
||||
$stmt->bindValue(':id', $id, PDO::PARAM_INT);
|
||||
$stmt->execute();
|
||||
|
||||
$stmt = $db->prepare('DELETE FROM lxd_users_groups_mapping WHERE user_id = :id');
|
||||
$stmt->bindValue(':id', $id, PDO::PARAM_INT);
|
||||
$stmt->execute();
|
||||
|
||||
$db = null;
|
||||
return $stmt;
|
||||
}
|
||||
|
||||
function deleteGroup($id){
|
||||
$db = establishDatabaseConnection();
|
||||
$stmt = $db->prepare('DELETE FROM lxd_groups WHERE id = :id');
|
||||
$stmt->bindValue(':id', $id, PDO::PARAM_INT);
|
||||
$stmt->execute();
|
||||
|
||||
$stmt = $db->prepare('DELETE FROM lxd_groups_roles_mapping WHERE group_id = :id');
|
||||
$stmt->bindValue(':id', $id, PDO::PARAM_INT);
|
||||
$stmt->execute();
|
||||
|
||||
$stmt = $db->prepare('DELETE FROM lxd_users_groups_mapping WHERE group_id = :id');
|
||||
$stmt->bindValue(':id', $id, PDO::PARAM_INT);
|
||||
$stmt->execute();
|
||||
|
||||
$db = null;
|
||||
return $stmt;
|
||||
}
|
||||
|
||||
function deleteUserGroupMapping($user_id, $group_id) {
|
||||
$db = establishDatabaseConnection();
|
||||
|
||||
$stmt = $db->prepare('DELETE FROM lxd_users_groups_mapping WHERE user_id = :user_id AND group_id = :group_id');
|
||||
$stmt->bindValue(':user_id', $user_id, PDO::PARAM_INT);
|
||||
$stmt->bindValue(':group_id', $group_id, PDO::PARAM_INT);
|
||||
$stmt->execute();
|
||||
$db = null;
|
||||
return $stmt;
|
||||
}
|
||||
|
||||
function deleteGroupRoleMapping($group_id, $role_id) {
|
||||
$db = establishDatabaseConnection();
|
||||
|
||||
$stmt = $db->prepare('DELETE FROM lxd_groups_roles_mapping WHERE group_id = :group_id AND role_id = :role_id');
|
||||
$stmt->bindValue(':group_id', $group_id, PDO::PARAM_INT);
|
||||
$stmt->bindValue(':role_id', $role_id, PDO::PARAM_INT);
|
||||
$stmt->execute();
|
||||
$db = null;
|
||||
return $stmt;
|
||||
}
|
||||
|
||||
/*
|
||||
===================================================================================
|
||||
Retrieve Values from Table Functions
|
||||
===================================================================================
|
||||
*/
|
||||
|
||||
function retrieveGroupId($name){
|
||||
$db = establishDatabaseConnection();
|
||||
$stmt = $db->prepare('SELECT id FROM lxd_groups WHERE name = :name LIMIT 1');
|
||||
$stmt->bindValue(':name', $name, PDO::PARAM_STR);
|
||||
$stmt->execute();
|
||||
$return_val = $stmt->fetchColumn();
|
||||
$db = null;
|
||||
return $return_val;
|
||||
}
|
||||
|
||||
function retrieveGroupRoles($group_id){
|
||||
$db = establishDatabaseConnection();
|
||||
$stmt = $db->prepare('SELECT lxd_roles.id, lxd_roles.name FROM lxd_roles, lxd_groups, lxd_groups_roles_mapping WHERE lxd_groups.id = lxd_groups_roles_mapping.group_id AND lxd_roles.id = lxd_groups_roles_mapping.role_id AND lxd_groups.id = :group_id');
|
||||
$stmt->bindValue(':group_id', $group_id, PDO::PARAM_INT);
|
||||
$stmt->execute();
|
||||
$return_val = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
$db = null;
|
||||
return $return_val;
|
||||
}
|
||||
|
||||
function retrieveGroupUsers($group_id){
|
||||
$db = establishDatabaseConnection();
|
||||
$stmt = $db->prepare('SELECT DISTINCT lxd_users.username FROM lxd_users, lxd_groups, lxd_users_groups_mapping WHERE lxd_users.id = lxd_users_groups_mapping.user_id AND lxd_groups.id = lxd_users_groups_mapping.group_id AND lxd_groups.id = :group_id');
|
||||
$stmt->bindValue(':group_id', $group_id, PDO::PARAM_INT);
|
||||
$stmt->execute();
|
||||
$return_val = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
$db = null;
|
||||
return $return_val;
|
||||
}
|
||||
|
||||
function retrieveRoleId($name){
|
||||
$db = establishDatabaseConnection();
|
||||
$stmt = $db->prepare('SELECT id FROM lxd_roles WHERE name = :name LIMIT 1');
|
||||
$stmt->bindValue(':name', $name, PDO::PARAM_STR);
|
||||
$stmt->execute();
|
||||
$return_val = $stmt->fetchColumn();
|
||||
$db = null;
|
||||
return $return_val;
|
||||
}
|
||||
|
||||
function retrieveDefaultRoles(){
|
||||
$db = establishDatabaseConnection();
|
||||
|
||||
$stmt = $db->prepare('SELECT * FROM lxd_roles WHERE name IN ("ADMIN", "OPERATOR", "USER", "AUDITOR")');
|
||||
|
||||
try {
|
||||
$stmt->execute();
|
||||
}
|
||||
catch (\Error $e) {
|
||||
initializeAllTables();
|
||||
$stmt->execute();
|
||||
}
|
||||
|
||||
$return_val = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
$db = null;
|
||||
return $return_val;
|
||||
}
|
||||
|
||||
function retrieveUserGroups($user_id){
|
||||
$db = establishDatabaseConnection();
|
||||
$stmt = $db->prepare('SELECT lxd_groups.id, lxd_groups.name FROM lxd_users, lxd_groups, lxd_users_groups_mapping WHERE lxd_users.id = lxd_users_groups_mapping.user_id AND lxd_groups.id = lxd_users_groups_mapping.group_id AND lxd_users.id = :user_id');
|
||||
$stmt->bindValue(':user_id', $user_id, PDO::PARAM_INT);
|
||||
$stmt->execute();
|
||||
$return_val = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
$db = null;
|
||||
return $return_val;
|
||||
}
|
||||
|
||||
function retrieveUserId($username){
|
||||
$db = establishDatabaseConnection();
|
||||
$stmt = $db->prepare('SELECT id FROM lxd_users WHERE username = :username LIMIT 1');
|
||||
$stmt->bindValue(':username', $username, PDO::PARAM_STR);
|
||||
$stmt->execute();
|
||||
$return_val = $stmt->fetchColumn();
|
||||
$db = null;
|
||||
return $return_val;
|
||||
}
|
||||
|
||||
function retrieveUserDetails($user_id){
|
||||
$db = establishDatabaseConnection();
|
||||
$stmt = $db->prepare('SELECT * FROM lxd_users WHERE id = :id LIMIT 1');
|
||||
$stmt->bindValue(':id', $user_id, PDO::PARAM_INT);
|
||||
$stmt->execute();
|
||||
$return_val = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
$db = null;
|
||||
return $return_val;
|
||||
}
|
||||
|
||||
function retrieveUserRecord($username){
|
||||
$db = establishDatabaseConnection();
|
||||
$stmt = $db->prepare('SELECT * FROM lxd_users WHERE username = :username LIMIT 1');
|
||||
$stmt->bindValue(':username', $username, PDO::PARAM_STR);
|
||||
$stmt->execute();
|
||||
$return_val = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
$db = null;
|
||||
return $return_val;
|
||||
}
|
||||
|
||||
function retrieveUserRoles($user_id){
|
||||
$db = establishDatabaseConnection();
|
||||
$stmt = $db->prepare('SELECT DISTINCT lxd_roles.name FROM lxd_roles, lxd_groups_roles_mapping, lxd_users_groups_mapping WHERE lxd_roles.id = lxd_groups_roles_mapping.role_id AND lxd_groups_roles_mapping.group_id = lxd_users_groups_mapping.group_id AND lxd_users_groups_mapping.user_id = :user_id');
|
||||
$stmt->bindValue(':user_id', $user_id, PDO::PARAM_INT);
|
||||
$stmt->execute();
|
||||
$return_val = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
$db = null;
|
||||
return $return_val;
|
||||
}
|
||||
|
||||
function retrieveHostURL($remote_id){
|
||||
$db = establishDatabaseConnection();
|
||||
|
||||
$stmt = $db->prepare('SELECT * FROM lxd_hosts WHERE id = :id LIMIT 1;');
|
||||
$stmt->bindValue(':id', $remote_id, PDO::PARAM_INT);
|
||||
$stmt->execute();
|
||||
$rows = $stmt->fetchAll();
|
||||
|
||||
$base_url = "";
|
||||
foreach ($rows as $row){
|
||||
$base_url = "https://" . $row['host'] . ":" . $row['port'];
|
||||
}
|
||||
|
||||
return $base_url;
|
||||
}
|
||||
|
||||
function retrieveHostName($remote_id){
|
||||
$db = establishDatabaseConnection();
|
||||
|
||||
$stmt = $db->prepare('SELECT * FROM lxd_hosts WHERE id = :id LIMIT 1;');
|
||||
$stmt->bindValue(':id', $remote_id, PDO::PARAM_INT);
|
||||
$stmt->execute();
|
||||
$rows = $stmt->fetchAll();
|
||||
|
||||
$hostname = "";
|
||||
foreach ($rows as $row){
|
||||
$hostname = $row['host'];
|
||||
}
|
||||
|
||||
return $hostname;
|
||||
}
|
||||
|
||||
function retrieveHostPort($remote_id){
|
||||
$db = establishDatabaseConnection();
|
||||
|
||||
$stmt = $db->prepare('SELECT * FROM lxd_hosts WHERE id = :id LIMIT 1;');
|
||||
$stmt->bindValue(':id', $remote_id, PDO::PARAM_INT);
|
||||
$stmt->execute();
|
||||
$rows = $stmt->fetchAll();
|
||||
|
||||
$port = "";
|
||||
foreach ($rows as $row){
|
||||
$port = $row['port'];
|
||||
}
|
||||
|
||||
return $port;
|
||||
}
|
||||
|
||||
function retrieveHostAlias($remote_id){
|
||||
$db = establishDatabaseConnection();
|
||||
|
||||
$stmt = $db->prepare('SELECT * FROM lxd_hosts WHERE id = :id LIMIT 1;');
|
||||
$stmt->bindValue(':id', $remote_id, PDO::PARAM_INT);
|
||||
$stmt->execute();
|
||||
$rows = $stmt->fetchAll();
|
||||
|
||||
$alias = "";
|
||||
foreach ($rows as $row){
|
||||
$alias = $row['alias'];
|
||||
}
|
||||
|
||||
return $alias;
|
||||
}
|
||||
|
||||
function retrieveTableRows($table){
|
||||
$db = establishDatabaseConnection();
|
||||
|
||||
switch ($table){
|
||||
case "lxd_hosts":
|
||||
$stmt = $db->prepare('SELECT * FROM lxd_hosts');
|
||||
break;
|
||||
|
||||
case "lxd_groups":
|
||||
$stmt = $db->prepare('SELECT * FROM lxd_groups');
|
||||
break;
|
||||
|
||||
case "lxd_roles":
|
||||
$stmt = $db->prepare('SELECT * FROM lxd_roles');
|
||||
break;
|
||||
|
||||
case "lxd_simplestreams":
|
||||
$stmt = $db->prepare('SELECT * FROM lxd_simplestreams');
|
||||
break;
|
||||
|
||||
case "lxd_users":
|
||||
$stmt = $db->prepare('SELECT * FROM lxd_users');
|
||||
break;
|
||||
|
||||
default:
|
||||
$stmt = "";
|
||||
}
|
||||
/*
|
||||
The tables are first initialized at the login screen before the first user registers an account.
|
||||
If new tables are added in later releases this will rerun the initialization on failure creating
|
||||
any new tables that are added to the initializeAllTables() function.
|
||||
*/
|
||||
try {
|
||||
$stmt->execute();
|
||||
}
|
||||
catch (\Error $e) {
|
||||
initializeAllTables();
|
||||
$stmt->execute();
|
||||
}
|
||||
|
||||
$return_val = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
$db = null;
|
||||
return $return_val;
|
||||
}
|
||||
|
||||
/*
|
||||
===================================================================================
|
||||
Update Record in Table Functions
|
||||
===================================================================================
|
||||
*/
|
||||
|
||||
function updateUserAccount($id, $first_name, $last_name, $email){
|
||||
$db = establishDatabaseConnection();
|
||||
|
||||
$stmt = $db->prepare('UPDATE lxd_users SET first_name = :first_name, last_name = :last_name, email = :email WHERE id = :id');
|
||||
$stmt->bindValue(':id', $id, PDO::PARAM_INT);
|
||||
$stmt->bindValue(':first_name', $first_name, PDO::PARAM_STR);
|
||||
$stmt->bindValue(':last_name', $last_name, PDO::PARAM_STR);
|
||||
$stmt->bindValue(':email', $email, PDO::PARAM_STR);
|
||||
$stmt->execute();
|
||||
$db = null;
|
||||
return $stmt;
|
||||
}
|
||||
|
||||
function updateUserPassword($id, $passwd_hash){
|
||||
$db = establishDatabaseConnection();
|
||||
|
||||
$stmt = $db->prepare('UPDATE lxd_users SET passwd_hash = :passwd_hash WHERE id = :id');
|
||||
$stmt->bindValue(':id', $id, PDO::PARAM_INT);
|
||||
$stmt->bindValue(':passwd_hash', $passwd_hash, PDO::PARAM_STR);
|
||||
$stmt->execute();
|
||||
$db = null;
|
||||
return $stmt;
|
||||
}
|
||||
|
||||
/*
|
||||
===================================================================================
|
||||
Misc Database Functions
|
||||
===================================================================================
|
||||
*/
|
||||
|
||||
function isFirstUser(){
|
||||
$db = establishDatabaseConnection();
|
||||
|
||||
/*
|
||||
The very first time at login page it will request this function to determine if the user
|
||||
should be presented with a login or registration form. If table does not yet exist it will cause
|
||||
an error. The catch will initialize all the tables and query the users table again.
|
||||
*/
|
||||
try {
|
||||
$db_results = $db->query('SELECT COUNT(*) from lxd_users');
|
||||
$count = $db_results->fetchColumn();
|
||||
}
|
||||
catch (\Error $e) {
|
||||
initializeAllTables();
|
||||
$db_results = $db->query('SELECT COUNT(*) from lxd_users');
|
||||
$count = $db_results->fetchColumn();
|
||||
}
|
||||
|
||||
//Determine if there are any existing records
|
||||
if ($count == 0)
|
||||
$return_val = true;
|
||||
else
|
||||
$return_val = false;
|
||||
|
||||
$db = null;
|
||||
return $return_val;
|
||||
}
|
||||
|
||||
function retrieveDatabaseTypes(){
|
||||
|
||||
$datbase_types = array(
|
||||
'sqlite'
|
||||
);
|
||||
|
||||
return $datbase_types;
|
||||
}
|
||||
|
||||
?>
|
|
@ -37,7 +37,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
|
||||
<!-- Custom styles for this template-->
|
||||
<link href="vendor/sb-admin-2/css/sb-admin-2.css" rel="stylesheet">
|
||||
<link href="assets/css/style.css" rel="stylesheet">
|
||||
<link href="assets/css/style.css?version=3.0" rel="stylesheet">
|
||||
|
||||
<!-- Custom styles for this page -->
|
||||
<link href="vendor/datatables/dataTables.bootstrap4.min.css" rel="stylesheet">
|
||||
|
@ -50,7 +50,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
<div id="wrapper">
|
||||
|
||||
<!-- Sidebar -->
|
||||
<ul class="navbar-nav bg-dark sidebar sidebar-dark accordion" id="accordionSidebar">
|
||||
<ul class="navbar-nav bg-dark sidebar sidebar-dark accordion sidebar-divider-right" id="accordionSidebar">
|
||||
|
||||
<div id="sidebarLinks"></div>
|
||||
|
||||
|
@ -59,12 +59,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
|
||||
<!-- Sidebar Toggler (Sidebar) -->
|
||||
<div class="text-center d-none d-md-inline">
|
||||
<button class="rounded-circle border-0" id="sidebarToggle"></button>
|
||||
<button class="rounded-circle border-0" id="sidebarToggle" onclick="setSidebarToggleValue()"></button>
|
||||
</div>
|
||||
</ul>
|
||||
<!-- End of Sidebar -->
|
||||
|
||||
|
||||
<!-- Content Wrapper -->
|
||||
<div id="content-wrapper" class="d-flex flex-column">
|
||||
|
||||
|
@ -79,36 +78,43 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
<i class="fa fa-bars"></i>
|
||||
</button>
|
||||
|
||||
|
||||
<!-- Topbar Notification -->
|
||||
<div class="d-none d-sm-inline-block form-inline mr-auto ml-md-3 my-2 my-md-0 mw-100 navbar-search">
|
||||
<ul class="navbar-nav ml-auto">
|
||||
|
||||
<li>
|
||||
<div class="nav-item spinner-border m-3" role="status" style="display:none;" id="spinner">
|
||||
<span class="nav-item sr-only">Loading...</span>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li class="nav-item dropdown no-arrow" id="notificationArea" style="display: none;">
|
||||
<div class="nav-link dropdown-toggle">
|
||||
<span id="notification" class="mr-2 d-none d-lg-inline text-gray-600">Notification</span>
|
||||
<span id="notification" class="mr-2 d-none d-lg-inline text-danger">Notification</span>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<!-- Topbar Navbar -->
|
||||
<ul class="navbar-nav ml-auto">
|
||||
|
||||
<!-- Topbar Navbar -->
|
||||
<ul class="navbar-nav ml-auto">
|
||||
|
||||
<li class="nav-item dropdown" id="remoteListNav">
|
||||
<li class="nav-item dropdown">
|
||||
<label class="h6 mt-4 mr-2 ml-4">Host: </label>
|
||||
</li>
|
||||
<li class="nav-item dropdown">
|
||||
<div class="input-group mt-3">
|
||||
<select class="form-control" id="remoteListNav" style="width:150px;" onchange="location = this.value;">
|
||||
</select>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li class="nav-item dropdown" id="projectListNav">
|
||||
<li class="nav-item dropdown">
|
||||
<label class="h6 mt-4 mr-2 ml-4">Project: </label>
|
||||
</li>
|
||||
<li class="nav-item dropdown">
|
||||
<div class="input-group mt-3">
|
||||
<select class="form-control" id="projectListNav" style="width:150px;" onchange="location = this.value;">
|
||||
</select>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<!-- Nav Divider -->
|
||||
<div class="topbar-divider d-none d-sm-block"></div>
|
||||
|
||||
<!-- Nav Item - User Information -->
|
||||
|
@ -119,14 +125,18 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
</a>
|
||||
<!-- Dropdown - User Information -->
|
||||
<div class="dropdown-menu dropdown-menu-right shadow animated--grow-in" aria-labelledby="userDropdown">
|
||||
<a class="dropdown-item" href="user-profile.html">
|
||||
<a class="dropdown-item" href="user-profile.php">
|
||||
<i class="fas fa-user fa-sm fa-fw mr-2 text-gray-400"></i>
|
||||
Profile
|
||||
</a>
|
||||
<a class="dropdown-item" href="settings.html">
|
||||
<a class="dropdown-item" href="settings.php">
|
||||
<i class="fas fa-cog fa-sm fa-fw mr-2 text-gray-400"></i>
|
||||
Settings
|
||||
</a>
|
||||
<a class="dropdown-item" href="logs.php">
|
||||
<i class="fas fa-history fa-sm fa-fw mr-2 text-gray-400"></i>
|
||||
Logs
|
||||
</a>
|
||||
<a class="dropdown-item" href="#" data-toggle="modal" data-target="#aboutModal">
|
||||
<i class="fas fa-info-circle fa-sm fa-fw mr-2 text-gray-400"></i>
|
||||
About
|
||||
|
@ -147,25 +157,48 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
<!-- Begin Page Content -->
|
||||
<div class="container-fluid">
|
||||
|
||||
<!-- BreadCrumb -->
|
||||
<nav aria-label="breadcrumb">
|
||||
<ol class="breadcrumb">
|
||||
<li class="breadcrumb-item"><a href="#" id="remoteBreadCrumb"></a></li>
|
||||
<li class="breadcrumb-item active" aria-current="page" id="profilesBreadCrumb"></li>
|
||||
</ol>
|
||||
</nav>
|
||||
<header class="page-header page-header-dark bg-gradient-primary-to-secondary">
|
||||
<div class="container-xl px-4">
|
||||
<div class="page-header-content pt-4">
|
||||
<div class="row align-items-center justify-content-between mt-n5 ml-n5 mr-n5 bg-dark pb-6">
|
||||
<div class="col-auto mt-4 ml-3">
|
||||
<div class="page-header-subtitle">
|
||||
<a href="#" id="remoteBreadCrumb"></a>
|
||||
</div>
|
||||
<h2 class="page-header-title mt-2">
|
||||
PROFILES
|
||||
</h2>
|
||||
<div class="page-header-subtitle">
|
||||
Create and manage instance profiles
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-xl-auto mt-4">
|
||||
<div class="input-group input-group-joined border-0" style="width: 14rem">
|
||||
<span class="input-group-text bg-transparent border-0">
|
||||
<a class="btn btn-outline-primary" href="#" data-toggle="modal" data-target="#createProfileModal" title="New Profile" aria-hidden="true">
|
||||
<i class="fas fa-plus fa-sm fa-fw"></i> Profile
|
||||
</a>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<div class="row">
|
||||
<div class="row mt-n5 ml-2 mr-2">
|
||||
|
||||
<div class="col-12">
|
||||
<!-- Profile List -->
|
||||
<div class="col-12 mt-n3">
|
||||
<!-- Image List -->
|
||||
<div class="card shadow mb-4">
|
||||
<!-- Card Header - Dropdown -->
|
||||
<div class="card-header py-3 d-flex flex-row align-items-center justify-content-between">
|
||||
<h6 class="m-0 font-weight-bold text-primary">Profiles</h6>
|
||||
<h6 class="m-0 font-weight-bold">
|
||||
<span class="ml-1">Profiles</span>
|
||||
</h6>
|
||||
<div class="dropdown no-arrow">
|
||||
<a class="dropdown-toggle mr-2" href="#" data-toggle="modal" data-target="#createProfileModal" title="New Profile" aria-hidden="true">
|
||||
<i class="fas fa-plus fa-sm fa-fw"></i> Profile</a>
|
||||
<a class="dropdown-toggle mr-2" href="#" onclick="reloadPageContent()" title="Refresh" aria-hidden="true">
|
||||
<i class="fa fa-sync fa-1x fa-fw"></i></a>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Card Body -->
|
||||
|
@ -176,7 +209,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- End Profile List -->
|
||||
<!-- End Image List -->
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
@ -191,7 +224,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
<footer class="sticky-footer bg-white">
|
||||
<div class="container my-auto">
|
||||
<div class="copyright text-center my-auto">
|
||||
<span>Copyright © lxdware.com 2021</span>
|
||||
<span>Copyright © LXDWARE 2020 - Present</span>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
|
@ -231,14 +264,14 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
<div class="tab-pane fade show active" id="form" role="tabpanel" aria-labelledby="form-tab">
|
||||
<br />
|
||||
<div class="row">
|
||||
<label class="col-3 col-form-label text-right">Name: </label>
|
||||
<label class="col-3 col-form-label text-right">Name: <span class="text-danger">*</span></label>
|
||||
<div class="col-7">
|
||||
<div class="form-group">
|
||||
<input type="text" id="profileNameCreate" class="form-control" placeholder="" name="profile_name">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-1">
|
||||
<i class="far fa-sm fa-question-circle text-danger" title='(Required) - Enter in a name for the profile.'></i>
|
||||
<i class="far fa-sm fa-question-circle" title='(Required) - Enter in a name for the profile.'></i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
|
@ -321,14 +354,14 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="row">
|
||||
<label class="col-3 col-form-label text-right" id="newProfileNameLabel">Name:</label>
|
||||
<label class="col-3 col-form-label text-right" id="newProfileNameLabel">Name: <span class="text-danger">*</span></label>
|
||||
<div class="col-7">
|
||||
<div class="form-group">
|
||||
<input type="text" id="newProfileName" class="form-control" placeholder="">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-1">
|
||||
<i class="far fa-sm fa-question-circle text-danger" title='(Required) - Enter in a new name for the profile.'></i>
|
||||
<i class="far fa-sm fa-question-circle" title='(Required) - Enter in a new name for the profile.'></i>
|
||||
</div>
|
||||
</div>
|
||||
<input type="hidden" id ="profileToRename" name="profileToRename">
|
||||
|
@ -387,61 +420,66 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
const remoteId = urlParams.get('remote');
|
||||
const projectName = urlParams.get('project');
|
||||
var profileToUpdate = "";
|
||||
var reloadTime = 5000;
|
||||
|
||||
function logout(){
|
||||
$.get("./php/aaa/authentication.php?action=deauthenticateUser", function (data) {
|
||||
$.get("./backend/aaa/authentication.php?action=deauthenticateUser", function (data) {
|
||||
operationData = JSON.parse(data);
|
||||
console.log(operationData);
|
||||
if (operationData.status_code == 200) {
|
||||
window.location = './index.html'
|
||||
window.location.href = './index.php'
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function operationStatusCheck(){
|
||||
clearTimeout(operationTimeout);
|
||||
//check to see if there are any running operations
|
||||
$.get("./php/lxd/operations.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&action=displayOperationStatus", function (data) {
|
||||
$.get("./backend/lxd/operations.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&action=displayOperationStatus", function (data) {
|
||||
//Check to see if we have running operations
|
||||
if (data){
|
||||
//Display spinner and notification area if there are running tasks
|
||||
$('#spinner').show();
|
||||
if (data) {
|
||||
//Display notification area if there are running tasks
|
||||
$('#notificationArea').show();
|
||||
$('#notification').text(data);
|
||||
//Set the page to check operations again in 1 second
|
||||
setTimeout(() => { operationStatusCheck(); }, 1000);
|
||||
$('#notification').text("Notice: " + data);
|
||||
//Set the page to check operations again in 2 seconds
|
||||
operationTimeout = setTimeout(() => { operationStatusCheck(); }, 2000);
|
||||
}
|
||||
else {
|
||||
//Hide spinner and notification area if no running tasks
|
||||
$('#spinner').hide();
|
||||
//Hide notification area if no running tasks
|
||||
$('#notificationArea').hide();
|
||||
$('#notification').text("");
|
||||
//Set the page to check operations again in 3 seconds
|
||||
setTimeout(() => { operationStatusCheck(); }, 3000);
|
||||
//Set the page to check operations again in 4 seconds
|
||||
operationTimeout = setTimeout(() => { operationStatusCheck(); }, 4000);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function reloadPageContent(){
|
||||
|
||||
clearTimeout(pageReloadTimeout);
|
||||
|
||||
//Check Authorization
|
||||
$.get("./php/aaa/authentication.php?action=validateAuthentication", function (data) {
|
||||
$.get("./backend/aaa/authentication.php?action=validateAuthentication", function (data) {
|
||||
operationData = JSON.parse(data);
|
||||
if (operationData.status_code != 200) {
|
||||
console.log(operationData);
|
||||
window.location = './index.html'
|
||||
window.location.href = './index.php'
|
||||
}
|
||||
});
|
||||
|
||||
$('#profileListTable').DataTable().ajax.reload(null, false);
|
||||
|
||||
//Set reload page content
|
||||
pageReloadTimeout = setTimeout(() => { reloadPageContent(); }, reloadTime);
|
||||
}
|
||||
|
||||
function loadPageContent(){
|
||||
|
||||
//Display current logged in username
|
||||
$("#username").load("./php/admin/settings.php?action=displayUsername");
|
||||
$("#username").load("./backend/admin/settings.php?action=displayUsername");
|
||||
|
||||
$('#profileListTable').DataTable( {
|
||||
ajax: "./php/lxd/profiles.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&action=listProfiles",
|
||||
ajax: "./backend/lxd/profiles.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&action=listProfiles",
|
||||
columns: [
|
||||
{},
|
||||
{ title: "Name" },
|
||||
|
@ -456,17 +494,23 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
});
|
||||
|
||||
//Check for any running operations
|
||||
operationStatusCheck();
|
||||
operationTimeout = setTimeout(() => { operationStatusCheck(); }, 1000);
|
||||
|
||||
//Set reload page content
|
||||
$.get("./backend/admin/settings.php?action=retrievePageRefreshRateValues", function (data) {
|
||||
operationData = JSON.parse(data);
|
||||
if (operationData.profiles_page_rate >= 1)
|
||||
reloadTime = operationData.profiles_page_rate * 1000;
|
||||
pageReloadTimeout = setTimeout(() => { reloadPageContent(); }, reloadTime);
|
||||
});
|
||||
|
||||
//Set the page content to reload in 5 seconds
|
||||
setInterval(() => { reloadPageContent(); }, 5000);
|
||||
}
|
||||
|
||||
function createProfileUsingForm(){
|
||||
var profileNameCreate = $("#profileNameCreate").val();
|
||||
var profileDescriptionCreate = $("#profileDescriptionCreate").val();
|
||||
console.log("Info: creating profile");
|
||||
$.get("./php/lxd/profiles.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&name=" + encodeURI(profileNameCreate) + "&description=" + encodeURI(profileDescriptionCreate) + "&action=createProfileUsingForm", function (data) {
|
||||
$.get("./backend/lxd/profiles.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&name=" + encodeURI(profileNameCreate) + "&description=" + encodeURI(profileDescriptionCreate) + "&action=createProfileUsingForm", function (data) {
|
||||
//Sync operation type
|
||||
var operationData = JSON.parse(data);
|
||||
console.log(operationData);
|
||||
|
@ -480,7 +524,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
function createProfileUsingJSON(){
|
||||
var profileCreateJSON = $("#jsonCreateInput").val();
|
||||
console.log("Info: creating profile");
|
||||
$.post("./php/lxd/profiles.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&action=createProfileUsingJSON", {json: profileCreateJSON}, function (data) {
|
||||
$.post("./backend/lxd/profiles.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&action=createProfileUsingJSON", {json: profileCreateJSON}, function (data) {
|
||||
//Sync operation type
|
||||
var operationData = JSON.parse(data);
|
||||
console.log(operationData);
|
||||
|
@ -494,7 +538,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
function loadProfileJson(profileToLoad){
|
||||
console.log("Info: loading profile " + profileToLoad);
|
||||
profileToUpdate = profileToLoad;
|
||||
$.get("./php/lxd/profiles.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&profile=" + encodeURI(profileToLoad) + "&action=loadProfile", function (data) {
|
||||
$.get("./backend/lxd/profiles.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&profile=" + encodeURI(profileToLoad) + "&action=loadProfile", function (data) {
|
||||
//Sync operation type
|
||||
var operationData = JSON.parse(data);
|
||||
console.log(operationData);
|
||||
|
@ -517,7 +561,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
function updateProfile(){
|
||||
var profileUpdateJSON = $("#jsonEditInput").val();
|
||||
console.log("Info: updating profile " + profileToUpdate);
|
||||
$.post("./php/lxd/profiles.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&profile=" + encodeURI(profileToUpdate) + "&action=updateProfile", {json: profileUpdateJSON}, function (data) {
|
||||
$.post("./backend/lxd/profiles.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&profile=" + encodeURI(profileToUpdate) + "&action=updateProfile", {json: profileUpdateJSON}, function (data) {
|
||||
//Sync operation type
|
||||
var operationData = JSON.parse(data);
|
||||
console.log(operationData);
|
||||
|
@ -532,7 +576,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
var profileName = $("#newProfileName").val();
|
||||
var profile = $("#profileToRename").val();
|
||||
console.log("Info: renaming profile " + profile);
|
||||
$.get("./php/lxd/profiles.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&profile=" + encodeURI(profile) + "&name=" + encodeURI(profileName) + "&action=renameProfile", function (data) {
|
||||
$.get("./backend/lxd/profiles.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&profile=" + encodeURI(profile) + "&name=" + encodeURI(profileName) + "&action=renameProfile", function (data) {
|
||||
//Sync operation type
|
||||
var operationData = JSON.parse(data);
|
||||
console.log(operationData);
|
||||
|
@ -545,7 +589,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
|
||||
function deleteProfile(profileToDelete){
|
||||
console.log("Info: deleting profile " + profileToDelete);
|
||||
$.get("./php/lxd/profiles.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&profile=" + encodeURI(profileToDelete) + "&action=deleteProfile", function (data) {
|
||||
$.get("./backend/lxd/profiles.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&profile=" + encodeURI(profileToDelete) + "&action=deleteProfile", function (data) {
|
||||
//Sync operation type
|
||||
var operationData = JSON.parse(data);
|
||||
console.log(operationData);
|
||||
|
@ -556,33 +600,64 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
});
|
||||
}
|
||||
|
||||
function setSidebarToggleValue(){
|
||||
sidebarState = localStorage.getItem('sidebarState');
|
||||
if (sidebarState == "collapsed"){
|
||||
localStorage.setItem('sidebarState','expanded');
|
||||
}
|
||||
else {
|
||||
localStorage.setItem('sidebarState','collapsed');
|
||||
}
|
||||
}
|
||||
|
||||
function applySidebarToggleValue() {
|
||||
sidebarState = localStorage.getItem('sidebarState');
|
||||
if (sidebarState == "collapsed"){
|
||||
$("body").toggleClass("sidebar-toggled"),
|
||||
$(".sidebar").toggleClass("toggled"),
|
||||
$(".sidebar").hasClass("toggled") && $(".sidebar .collapse").collapse("hide")
|
||||
}
|
||||
}
|
||||
|
||||
applySidebarToggleValue();
|
||||
|
||||
$(document).ready(function(){
|
||||
|
||||
//Check Authorization
|
||||
$.get("./php/aaa/authentication.php?action=validateAuthentication", function (data) {
|
||||
$.get("./backend/aaa/authentication.php?action=validateAuthentication", function (data) {
|
||||
operationData = JSON.parse(data);
|
||||
if (operationData.status_code != 200) {
|
||||
console.log(operationData);
|
||||
window.location = './index.html'
|
||||
window.location.href = './index.php'
|
||||
}
|
||||
});
|
||||
|
||||
//Load in the sidebar
|
||||
$("#sidebarLinks").load("./sidebar.html");
|
||||
$("#sidebarLinks").load("./sidebar.php?version=3.0");
|
||||
|
||||
//Setup Page Breadcrumb Links/Information
|
||||
$('#remoteBreadCrumb').load("./php/lxd/remote-breadcrumb.php?remote=" + encodeURI(remoteId));
|
||||
$('#remoteBreadCrumb').attr("href", "remotes-single.html?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName));
|
||||
$('#profilesBreadCrumb').text("profiles");
|
||||
$('#remoteBreadCrumb').load("./backend/lxd/remote-breadcrumb.php?remote=" + encodeURI(remoteId));
|
||||
$('#remoteBreadCrumb').attr("href", "remotes-single.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName));
|
||||
|
||||
//Load the card contents
|
||||
loadPageContent();
|
||||
//Validate remote host connection returns 200 status
|
||||
$.get("./backend/lxd/remotes-single.php?remote=" + encodeURI(remoteId) + "&action=validateRemoteConnection", function (data) {
|
||||
operationData = JSON.parse(data);
|
||||
console.log(operationData);
|
||||
if (operationData.status_code == 200) {
|
||||
//Set top navbar dropdowns
|
||||
$("#remoteListNav").load("./backend/lxd/remotes.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&action=listRemotesForSelectOption");
|
||||
$("#projectListNav").load("./backend/lxd/projects.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&action=listProjectsForSelectOption");
|
||||
|
||||
//Load Page Content
|
||||
loadPageContent();
|
||||
}
|
||||
else {
|
||||
alert("Unable to connect to remote host. HTTP status code: " + operationData.status_code);
|
||||
}
|
||||
});
|
||||
|
||||
$("#remoteListNav").load("./php/lxd/remotes.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&action=listRemotesForTopNavigation");
|
||||
$("#projectListNav").load("./php/lxd/projects.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&action=listProjectsForTopNavigation");
|
||||
|
||||
//Load the about info for the about modal
|
||||
$.get("./about.html", function (data) {
|
||||
$.get("./backend/config/about.php", function (data) {
|
||||
$("#about").html(data);
|
||||
});
|
||||
|
|
@ -37,7 +37,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
|
||||
<!-- Custom styles for this template-->
|
||||
<link href="vendor/sb-admin-2/css/sb-admin-2.css" rel="stylesheet">
|
||||
<link href="assets/css/style.css" rel="stylesheet">
|
||||
<link href="assets/css/style.css?version=3.0" rel="stylesheet">
|
||||
|
||||
<!-- Custom styles for this page -->
|
||||
<link href="vendor/datatables/dataTables.bootstrap4.min.css" rel="stylesheet">
|
||||
|
@ -50,7 +50,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
<div id="wrapper">
|
||||
|
||||
<!-- Sidebar -->
|
||||
<ul class="navbar-nav bg-dark sidebar sidebar-dark accordion" id="accordionSidebar">
|
||||
<ul class="navbar-nav bg-dark sidebar sidebar-dark accordion sidebar-divider-right" id="accordionSidebar">
|
||||
|
||||
<div id="sidebarLinks"></div>
|
||||
|
||||
|
@ -59,12 +59,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
|
||||
<!-- Sidebar Toggler (Sidebar) -->
|
||||
<div class="text-center d-none d-md-inline">
|
||||
<button class="rounded-circle border-0" id="sidebarToggle"></button>
|
||||
<button class="rounded-circle border-0" id="sidebarToggle" onclick="setSidebarToggleValue()"></button>
|
||||
</div>
|
||||
</ul>
|
||||
<!-- End of Sidebar -->
|
||||
|
||||
|
||||
<!-- Content Wrapper -->
|
||||
<div id="content-wrapper" class="d-flex flex-column">
|
||||
|
||||
|
@ -79,36 +78,43 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
<i class="fa fa-bars"></i>
|
||||
</button>
|
||||
|
||||
|
||||
<!-- Topbar Notification -->
|
||||
<div class="d-none d-sm-inline-block form-inline mr-auto ml-md-3 my-2 my-md-0 mw-100 navbar-search">
|
||||
<ul class="navbar-nav ml-auto">
|
||||
|
||||
<li>
|
||||
<div class="nav-item spinner-border m-3" role="status" style="display:none;" id="spinner">
|
||||
<span class="nav-item sr-only">Loading...</span>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li class="nav-item dropdown no-arrow" id="notificationArea" style="display: none;">
|
||||
<div class="nav-link dropdown-toggle">
|
||||
<span id="notification" class="mr-2 d-none d-lg-inline text-gray-600">Notification</span>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- Topbar Navbar -->
|
||||
<!-- Topbar Notification -->
|
||||
<div class="d-none d-sm-inline-block form-inline mr-auto ml-md-3 my-2 my-md-0 mw-100 navbar-search">
|
||||
<ul class="navbar-nav ml-auto">
|
||||
|
||||
<li class="nav-item dropdown" id="remoteListNav">
|
||||
<li class="nav-item dropdown no-arrow" id="notificationArea" style="display: none;">
|
||||
<div class="nav-link dropdown-toggle">
|
||||
<span id="notification" class="mr-2 d-none d-lg-inline text-danger">Notification</span>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<!-- Topbar Navbar -->
|
||||
<ul class="navbar-nav ml-auto">
|
||||
|
||||
<li class="nav-item dropdown">
|
||||
<label class="h6 mt-4 mr-2 ml-4">Host: </label>
|
||||
</li>
|
||||
<li class="nav-item dropdown">
|
||||
<div class="input-group mt-3">
|
||||
<select class="form-control" id="remoteListNav" style="width:150px;" onchange="location = this.value;">
|
||||
</select>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li class="nav-item dropdown" id="projectListNav">
|
||||
<li class="nav-item dropdown">
|
||||
<label class="h6 mt-4 mr-2 ml-4">Project: </label>
|
||||
</li>
|
||||
<li class="nav-item dropdown">
|
||||
<div class="input-group mt-3">
|
||||
<select class="form-control" id="projectListNav" style="width:150px;" onchange="location = this.value;">
|
||||
</select>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<!-- Nav Divider -->
|
||||
<div class="topbar-divider d-none d-sm-block"></div>
|
||||
|
||||
<!-- Nav Item - User Information -->
|
||||
|
@ -119,14 +125,18 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
</a>
|
||||
<!-- Dropdown - User Information -->
|
||||
<div class="dropdown-menu dropdown-menu-right shadow animated--grow-in" aria-labelledby="userDropdown">
|
||||
<a class="dropdown-item" href="user-profile.html">
|
||||
<a class="dropdown-item" href="user-profile.php">
|
||||
<i class="fas fa-user fa-sm fa-fw mr-2 text-gray-400"></i>
|
||||
Profile
|
||||
</a>
|
||||
<a class="dropdown-item" href="settings.html">
|
||||
<a class="dropdown-item" href="settings.php">
|
||||
<i class="fas fa-cog fa-sm fa-fw mr-2 text-gray-400"></i>
|
||||
Settings
|
||||
</a>
|
||||
<a class="dropdown-item" href="logs.php">
|
||||
<i class="fas fa-history fa-sm fa-fw mr-2 text-gray-400"></i>
|
||||
Logs
|
||||
</a>
|
||||
<a class="dropdown-item" href="#" data-toggle="modal" data-target="#aboutModal">
|
||||
<i class="fas fa-info-circle fa-sm fa-fw mr-2 text-gray-400"></i>
|
||||
About
|
||||
|
@ -147,25 +157,48 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
<!-- Begin Page Content -->
|
||||
<div class="container-fluid">
|
||||
|
||||
<!-- BreadCrumb -->
|
||||
<nav aria-label="breadcrumb">
|
||||
<ol class="breadcrumb">
|
||||
<li class="breadcrumb-item"><a href="#" id="remoteBreadCrumb"></a></li>
|
||||
<li class="breadcrumb-item active" aria-current="page" id="projectsBreadCrumb"></li>
|
||||
</ol>
|
||||
</nav>
|
||||
<header class="page-header page-header-dark bg-gradient-primary-to-secondary">
|
||||
<div class="container-xl px-4">
|
||||
<div class="page-header-content pt-4">
|
||||
<div class="row align-items-center justify-content-between mt-n5 ml-n5 mr-n5 bg-dark pb-6">
|
||||
<div class="col-auto mt-4 ml-3">
|
||||
<div class="page-header-subtitle">
|
||||
<a href="#" id="remoteBreadCrumb"></a>
|
||||
</div>
|
||||
<h2 class="page-header-title mt-2">
|
||||
PROJECTS
|
||||
</h2>
|
||||
<div class="page-header-subtitle">
|
||||
Create and manage projects
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-xl-auto mt-4">
|
||||
<div class="input-group input-group-joined border-0" style="width: 14rem">
|
||||
<span class="input-group-text bg-transparent border-0">
|
||||
<a class="btn btn-outline-primary" href="#" data-toggle="modal" data-target="#createProjectModal" title="New Project" aria-hidden="true">
|
||||
<i class="fas fa-plus fa-sm fa-fw"></i> Project
|
||||
</a>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<div class="row">
|
||||
<div class="row mt-n5 ml-2 mr-2">
|
||||
|
||||
<div class="col-12">
|
||||
<div class="col-12 mt-n3">
|
||||
<!-- Project List -->
|
||||
<div class="card shadow mb-4">
|
||||
<!-- Card Header - Dropdown -->
|
||||
<div class="card-header py-3 d-flex flex-row align-items-center justify-content-between">
|
||||
<h6 class="m-0 font-weight-bold text-primary">Projects</h6>
|
||||
<h6 class="m-0 font-weight-bold">
|
||||
<span class="ml-1">Projects</span>
|
||||
</h6>
|
||||
<div class="dropdown no-arrow">
|
||||
<a class="dropdown-toggle mr-2" href="#" data-toggle="modal" data-target="#createProjectModal" title="New Project" aria-hidden="true">
|
||||
<i class="fas fa-plus fa-sm fa-fw"></i> Project</a>
|
||||
<a class="dropdown-toggle mr-2" href="#" onclick="reloadPageContent()" title="Refresh" aria-hidden="true">
|
||||
<i class="fa fa-sync fa-1x fa-fw"></i></a>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Card Body -->
|
||||
|
@ -191,7 +224,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
<footer class="sticky-footer bg-white">
|
||||
<div class="container my-auto">
|
||||
<div class="copyright text-center my-auto">
|
||||
<span>Copyright © lxdware.com 2021</span>
|
||||
<span>Copyright © LXDWARE 2020 - Present</span>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
|
@ -235,14 +268,14 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
<br />
|
||||
|
||||
<div class="row">
|
||||
<label class="col-3 col-form-label text-right">Name: </label>
|
||||
<label class="col-3 col-form-label text-right">Name: <span class="text-danger">*</span></label>
|
||||
<div class="col-7">
|
||||
<div class="form-group text-right">
|
||||
<input type="text" class="form-control" id="projectNameInput" required="required" placeholder="" name="projectNameInput">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-1">
|
||||
<i class="far fa-sm fa-question-circle text-danger" title='(Required) - Enter in a name for the project.'></i>
|
||||
<i class="far fa-sm fa-question-circle" title='(Required) - Enter in a name for the project.'></i>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -909,14 +942,14 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="row">
|
||||
<label class="col-3 col-form-label text-right" id="newProjectNameLabel">Name:</label>
|
||||
<label class="col-3 col-form-label text-right" id="newProjectNameLabel">Name: <span class="text-danger">*</span></label>
|
||||
<div class="col-7">
|
||||
<div class="form-group">
|
||||
<input type="text" id="newProjectName" class="form-control" placeholder="">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-1">
|
||||
<i class="far fa-sm fa-question-circle text-danger" title='Enter in a new name for the project.'></i>
|
||||
<i class="far fa-sm fa-question-circle" title='Enter in a new name for the project.'></i>
|
||||
</div>
|
||||
</div>
|
||||
<input type="hidden" id ="projectToRename" name="projectToRename">
|
||||
|
@ -975,61 +1008,66 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
const remoteId = urlParams.get('remote');
|
||||
const projectName = urlParams.get('project');
|
||||
var projectToUpdate = "";
|
||||
var reloadTime = 5000;
|
||||
|
||||
function logout(){
|
||||
$.get("./php/aaa/authentication.php?action=deauthenticateUser", function (data) {
|
||||
$.get("./backend/aaa/authentication.php?action=deauthenticateUser", function (data) {
|
||||
operationData = JSON.parse(data);
|
||||
console.log(operationData);
|
||||
if (operationData.status_code == 200) {
|
||||
window.location = './index.html'
|
||||
window.location.href = './index.php'
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function operationStatusCheck(){
|
||||
clearTimeout(operationTimeout);
|
||||
//check to see if there are any running operations
|
||||
$.get("./php/lxd/operations.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&action=displayOperationStatus", function (data) {
|
||||
$.get("./backend/lxd/operations.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&action=displayOperationStatus", function (data) {
|
||||
//Check to see if we have running operations
|
||||
if (data){
|
||||
//Display spinner and notification area if there are running tasks
|
||||
$('#spinner').show();
|
||||
if (data) {
|
||||
//Display notification area if there are running tasks
|
||||
$('#notificationArea').show();
|
||||
$('#notification').text(data);
|
||||
//Set the page to check operations again in 1 second
|
||||
setTimeout(() => { operationStatusCheck(); }, 1000);
|
||||
$('#notification').text("Notice: " + data);
|
||||
//Set the page to check operations again in 2 seconds
|
||||
operationTimeout = setTimeout(() => { operationStatusCheck(); }, 2000);
|
||||
}
|
||||
else {
|
||||
//Hide spinner and notification area if no running tasks
|
||||
$('#spinner').hide();
|
||||
//Hide notification area if no running tasks
|
||||
$('#notificationArea').hide();
|
||||
$('#notification').text("");
|
||||
//Set the page to check operations again in 3 seconds
|
||||
setTimeout(() => { operationStatusCheck(); }, 3000);
|
||||
//Set the page to check operations again in 4 seconds
|
||||
operationTimeout = setTimeout(() => { operationStatusCheck(); }, 4000);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function reloadPageContent(){
|
||||
|
||||
clearTimeout(pageReloadTimeout);
|
||||
|
||||
//Check Authorization
|
||||
$.get("./php/aaa/authentication.php?action=validateAuthentication", function (data) {
|
||||
$.get("./backend/aaa/authentication.php?action=validateAuthentication", function (data) {
|
||||
operationData = JSON.parse(data);
|
||||
if (operationData.status_code != 200) {
|
||||
console.log(operationData);
|
||||
window.location = './index.html'
|
||||
window.location.href = './index.php'
|
||||
}
|
||||
});
|
||||
|
||||
$('#projectListTable').DataTable().ajax.reload(null, false);
|
||||
|
||||
//Set reload page content
|
||||
pageReloadTimeout = setTimeout(() => { reloadPageContent(); }, reloadTime);
|
||||
}
|
||||
|
||||
function loadPageContent(){
|
||||
|
||||
//Display current logged in username
|
||||
$("#username").load("./php/admin/settings.php?action=displayUsername");
|
||||
$("#username").load("./backend/admin/settings.php?action=displayUsername");
|
||||
|
||||
$('#projectListTable').DataTable( {
|
||||
ajax: "./php/lxd/projects.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&action=listProjects",
|
||||
ajax: "./backend/lxd/projects.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&action=listProjects",
|
||||
columns: [
|
||||
{},
|
||||
{ title: "Name" },
|
||||
|
@ -1047,10 +1085,16 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
});
|
||||
|
||||
//Check for any running operations
|
||||
operationStatusCheck();
|
||||
operationTimeout = setTimeout(() => { operationStatusCheck(); }, 1000);
|
||||
|
||||
//Set reload page content
|
||||
$.get("./backend/admin/settings.php?action=retrievePageRefreshRateValues", function (data) {
|
||||
operationData = JSON.parse(data);
|
||||
if (operationData.projects_page_rate >= 1)
|
||||
reloadTime = operationData.projects_page_rate * 1000;
|
||||
pageReloadTimeout = setTimeout(() => { reloadPageContent(); }, reloadTime);
|
||||
});
|
||||
|
||||
//Set the page content to reload in 5 seconds
|
||||
setInterval(() => { reloadPageContent(); }, 5000);
|
||||
}
|
||||
|
||||
function createProjectUsingForm(){
|
||||
|
@ -1096,7 +1140,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
var projectRestrictedVirtualMachinesLowlevelInput = $("#projectRestrictedVirtualMachinesLowlevelInput").val();
|
||||
|
||||
console.log("Info: creating project " + projectNameInput);
|
||||
$.get("./php/lxd/projects.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) +
|
||||
$.get("./backend/lxd/projects.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) +
|
||||
"&name=" + encodeURI(projectNameInput) +
|
||||
"&description=" + encodeURI(projectDescriptionInput) +
|
||||
"&features_images=" + encodeURI(projectFeaturesImagesInput) +
|
||||
|
@ -1151,7 +1195,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
function createProjectUsingJSON(){
|
||||
var projectCreateJSON = $("#jsonCreateInput").val();
|
||||
console.log("Info: creating project");
|
||||
$.post("./php/lxd/projects.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&action=createProjectUsingJSON", {json: projectCreateJSON}, function (data) {
|
||||
$.post("./backend/lxd/projects.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&action=createProjectUsingJSON", {json: projectCreateJSON}, function (data) {
|
||||
//Sync operation type
|
||||
var operationData = JSON.parse(data);
|
||||
console.log(operationData);
|
||||
|
@ -1165,7 +1209,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
function loadProjectJson(projectToLoad){
|
||||
console.log("Info: loading project " + projectToLoad);
|
||||
projectToUpdate = projectToLoad;
|
||||
$.get("./php/lxd/projects.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&name=" + encodeURI(projectToLoad) + "&action=loadProject", function (data) {
|
||||
$.get("./backend/lxd/projects.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&name=" + encodeURI(projectToLoad) + "&action=loadProject", function (data) {
|
||||
//Sync operation type
|
||||
var operationData = JSON.parse(data);
|
||||
console.log(operationData);
|
||||
|
@ -1188,7 +1232,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
function updateProject(){
|
||||
var projectUpdateJSON = $("#jsonInput").val();
|
||||
console.log("Info: updating project " + projectToUpdate);
|
||||
$.post("./php/lxd/projects.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectToUpdate) + "&action=updateProject",{json: projectUpdateJSON}, function (data) {
|
||||
$.post("./backend/lxd/projects.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectToUpdate) + "&action=updateProject",{json: projectUpdateJSON}, function (data) {
|
||||
//Sync operation type
|
||||
var operationData = JSON.parse(data);
|
||||
console.log(operationData);
|
||||
|
@ -1203,7 +1247,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
var projectNewName = $("#newProjectName").val();
|
||||
var projectToRename = $("#projectToRename").val();
|
||||
console.log("Info: renaming project " + projectToRename);
|
||||
$.get("./php/lxd/projects.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectToRename) + "&name=" + encodeURI(projectNewName) + "&action=renameProject", function (data) {
|
||||
$.get("./backend/lxd/projects.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectToRename) + "&name=" + encodeURI(projectNewName) + "&action=renameProject", function (data) {
|
||||
//Sync operation type
|
||||
var operationData = JSON.parse(data);
|
||||
console.log(operationData);
|
||||
|
@ -1216,7 +1260,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
|
||||
function deleteProject(projectToDelete){
|
||||
console.log("Info: deleting project " + projectToDelete);
|
||||
$.get("./php/lxd/projects.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&name=" + encodeURI(projectToDelete) + "&action=deleteProject", function (data) {
|
||||
$.get("./backend/lxd/projects.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&name=" + encodeURI(projectToDelete) + "&action=deleteProject", function (data) {
|
||||
//Sync operation type
|
||||
var operationData = JSON.parse(data);
|
||||
console.log(operationData);
|
||||
|
@ -1274,33 +1318,64 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
}
|
||||
}
|
||||
|
||||
function setSidebarToggleValue(){
|
||||
sidebarState = localStorage.getItem('sidebarState');
|
||||
if (sidebarState == "collapsed"){
|
||||
localStorage.setItem('sidebarState','expanded');
|
||||
}
|
||||
else {
|
||||
localStorage.setItem('sidebarState','collapsed');
|
||||
}
|
||||
}
|
||||
|
||||
function applySidebarToggleValue() {
|
||||
sidebarState = localStorage.getItem('sidebarState');
|
||||
if (sidebarState == "collapsed"){
|
||||
$("body").toggleClass("sidebar-toggled"),
|
||||
$(".sidebar").toggleClass("toggled"),
|
||||
$(".sidebar").hasClass("toggled") && $(".sidebar .collapse").collapse("hide")
|
||||
}
|
||||
}
|
||||
|
||||
applySidebarToggleValue();
|
||||
|
||||
$(document).ready(function(){
|
||||
|
||||
//Check Authorization
|
||||
$.get("./php/aaa/authentication.php?action=validateAuthentication", function (data) {
|
||||
$.get("./backend/aaa/authentication.php?action=validateAuthentication", function (data) {
|
||||
operationData = JSON.parse(data);
|
||||
if (operationData.status_code != 200) {
|
||||
console.log(operationData);
|
||||
window.location = './index.html'
|
||||
window.location.href = './index.php'
|
||||
}
|
||||
});
|
||||
|
||||
//Load in the sidebar
|
||||
$("#sidebarLinks").load("./sidebar.html");
|
||||
$("#sidebarLinks").load("./sidebar.php?version=3.0");
|
||||
|
||||
//Setup Page Breadcrumb Links/Information
|
||||
$('#remoteBreadCrumb').load("./php/lxd/remote-breadcrumb.php?remote=" + encodeURI(remoteId));
|
||||
$('#remoteBreadCrumb').attr("href", "remotes-single.html?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName));
|
||||
$('#projectsBreadCrumb').text("projects");
|
||||
$('#remoteBreadCrumb').load("./backend/lxd/remote-breadcrumb.php?remote=" + encodeURI(remoteId));
|
||||
$('#remoteBreadCrumb').attr("href", "remotes-single.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName));
|
||||
|
||||
//Load the card contents
|
||||
loadPageContent();
|
||||
//Validate remote host connection returns 200 status
|
||||
$.get("./backend/lxd/remotes-single.php?remote=" + encodeURI(remoteId) + "&action=validateRemoteConnection", function (data) {
|
||||
operationData = JSON.parse(data);
|
||||
console.log(operationData);
|
||||
if (operationData.status_code == 200) {
|
||||
//Set top navbar dropdowns
|
||||
$("#remoteListNav").load("./backend/lxd/remotes.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&action=listRemotesForSelectOption");
|
||||
$("#projectListNav").load("./backend/lxd/projects.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&action=listProjectsForSelectOption");
|
||||
|
||||
$("#remoteListNav").load("./php/lxd/remotes.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&action=listRemotesForTopNavigation");
|
||||
$("#projectListNav").load("./php/lxd/projects.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&action=listProjectsForTopNavigation");
|
||||
//Load Page Content
|
||||
loadPageContent();
|
||||
}
|
||||
else {
|
||||
alert("Unable to connect to remote host. HTTP status code: " + operationData.status_code);
|
||||
}
|
||||
});
|
||||
|
||||
//Load the about info for the about modal
|
||||
$.get("./about.html", function (data) {
|
||||
$.get("./backend/config/about.php", function (data) {
|
||||
$("#about").html(data);
|
||||
});
|
||||
|
|
@ -1,797 +0,0 @@
|
|||
<!--
|
||||
LXDWARE LXD Dashboard - A web-based interface for managing LXD servers
|
||||
Copyright (C) 2020-2021 LXDWARE.COM
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
-->
|
||||
|
||||
<!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, shrink-to-fit=no">
|
||||
<meta name="description" content="">
|
||||
<meta name="author" content="">
|
||||
|
||||
<link rel="icon" type="image/png" href="assets/images/logo-light.svg">
|
||||
|
||||
<title>LXD Dashboard</title>
|
||||
|
||||
<!-- Custom fonts for this template-->
|
||||
<link href="vendor/fontawesome-free/css/all.min.css" rel="stylesheet" type="text/css">
|
||||
<link href="vendor/fonts/nunito.css" rel="stylesheet">
|
||||
|
||||
<!-- Custom styles for this template-->
|
||||
<link href="vendor/sb-admin-2/css/sb-admin-2.css" rel="stylesheet">
|
||||
<link href="assets/css/style.css" rel="stylesheet">
|
||||
|
||||
</head>
|
||||
|
||||
<body id="page-top">
|
||||
|
||||
<!-- Page Wrapper -->
|
||||
<div id="wrapper">
|
||||
|
||||
<!-- Sidebar -->
|
||||
<ul class="navbar-nav bg-dark sidebar sidebar-dark accordion" id="accordionSidebar">
|
||||
|
||||
<div id="sidebarLinks"></div>
|
||||
|
||||
<!-- Divider -->
|
||||
<hr class="sidebar-divider d-none d-md-block">
|
||||
|
||||
<!-- Sidebar Toggler (Sidebar) -->
|
||||
<div class="text-center d-none d-md-inline">
|
||||
<button class="rounded-circle border-0" id="sidebarToggle"></button>
|
||||
</div>
|
||||
</ul>
|
||||
<!-- End of Sidebar -->
|
||||
|
||||
|
||||
<!-- Content Wrapper -->
|
||||
<div id="content-wrapper" class="d-flex flex-column">
|
||||
|
||||
<!-- Main Content -->
|
||||
<div id="content">
|
||||
|
||||
<!-- Topbar -->
|
||||
<nav class="navbar navbar-expand navbar-light bg-white topbar mb-4 static-top shadow">
|
||||
|
||||
<!-- Sidebar Toggle (Topbar) -->
|
||||
<button id="sidebarToggleTop" class="btn btn-link d-md-none rounded-circle mr-3">
|
||||
<i class="fa fa-bars"></i>
|
||||
</button>
|
||||
|
||||
|
||||
<!-- Topbar Notification -->
|
||||
<div class="d-none d-sm-inline-block form-inline mr-auto ml-md-3 my-2 my-md-0 mw-100 navbar-search">
|
||||
<ul class="navbar-nav ml-auto">
|
||||
|
||||
<li>
|
||||
<div class="nav-item spinner-border m-3" role="status" style="display:none;" id="spinner">
|
||||
<span class="nav-item sr-only">Loading...</span>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li class="nav-item dropdown no-arrow" id="notificationArea" style="display: none;">
|
||||
<div class="nav-link dropdown-toggle">
|
||||
<span id="notification" class="mr-2 d-none d-lg-inline text-gray-600">Notification</span>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- Topbar Navbar -->
|
||||
<ul class="navbar-nav ml-auto">
|
||||
|
||||
<li class="nav-item dropdown" id="remoteListNav">
|
||||
</li>
|
||||
|
||||
<li class="nav-item dropdown" id="projectListNav">
|
||||
</li>
|
||||
|
||||
<div class="topbar-divider d-none d-sm-block"></div>
|
||||
|
||||
<!-- Nav Item - User Information -->
|
||||
<li class="nav-item dropdown no-arrow">
|
||||
<a class="nav-link dropdown-toggle" href="#" id="userDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
<i class="fas fa-user-circle fa-1x fa-fw mr-2 text-gray-600"></i>
|
||||
<span id="username" class="mr-2 d-none d-lg-inline text-gray-600"></span>
|
||||
</a>
|
||||
<!-- Dropdown - User Information -->
|
||||
<div class="dropdown-menu dropdown-menu-right shadow animated--grow-in" aria-labelledby="userDropdown">
|
||||
<a class="dropdown-item" href="user-profile.html">
|
||||
<i class="fas fa-user fa-sm fa-fw mr-2 text-gray-400"></i>
|
||||
Profile
|
||||
</a>
|
||||
<a class="dropdown-item" href="settings.html">
|
||||
<i class="fas fa-cog fa-sm fa-fw mr-2 text-gray-400"></i>
|
||||
Settings
|
||||
</a>
|
||||
<a class="dropdown-item" href="#" data-toggle="modal" data-target="#aboutModal">
|
||||
<i class="fas fa-info-circle fa-sm fa-fw mr-2 text-gray-400"></i>
|
||||
About
|
||||
</a>
|
||||
<div class="dropdown-divider"></div>
|
||||
<a class="dropdown-item" href="#" onclick="logout()">
|
||||
<i class="fas fa-sign-out-alt fa-sm fa-fw mr-2 text-gray-400"></i>
|
||||
Logout
|
||||
</a>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
|
||||
</nav>
|
||||
<!-- End of Topbar -->
|
||||
|
||||
<!-- Begin Page Content -->
|
||||
<div class="container-fluid">
|
||||
|
||||
<!-- BreadCrumb -->
|
||||
<nav aria-label="breadcrumb">
|
||||
<ol class="breadcrumb">
|
||||
<li class="breadcrumb-item active" aria-current="page" id="remoteBreadCrumb"></li>
|
||||
</ol>
|
||||
</nav>
|
||||
|
||||
<div class="col-12">
|
||||
|
||||
<div class="row">
|
||||
|
||||
<div class="col-sm-12 col-md-6 col-xl-4 py-2 mb-4">
|
||||
<div class="card border-left-primary shadow h-100">
|
||||
<a href="#" class="stretched-link" id="instancesLink"></a>
|
||||
<div class="card-body">
|
||||
<div class="row no-gutters align-items-center">
|
||||
<div class="col-5">
|
||||
<div class="text-xs font-weight-bold text-primary text-uppercase mb-1">
|
||||
Instances
|
||||
</div>
|
||||
<div class="h5 mb-0 font-weight-bold text-gray-600 align-middle">
|
||||
<i class="fas fa-cube fa-1x mr-2 text-primary"></i>
|
||||
<span id="runningInstances">0</span> / <span id="totalInstances">0</span> running
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-7">
|
||||
<div class="progress progress-sm mr-2">
|
||||
<div class="progress-bar bg-info" role="progressbar" id="instancePercentageProgressBar" style="width: 0%" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-sm-12 col-md-6 col-xl-4 py-2 mb-4">
|
||||
<div class="card border-left-primary shadow h-100">
|
||||
<a href="#" class="stretched-link" id="clusterMembersLink"></a>
|
||||
<div class="card-body">
|
||||
<div class="row no-gutters align-items-center">
|
||||
<div class="col-5">
|
||||
<div class="text-xs font-weight-bold text-primary text-uppercase mb-1">
|
||||
Cluster Members
|
||||
</div>
|
||||
<div class="h5 mb-0 font-weight-bold text-gray-600 align-middle">
|
||||
<i class="fas fa-layer-group fa-1x mr-2 text-primary"></i>
|
||||
<span id="onlineClusterMembers">0</span> / <span id="totalClusterMembers">0</span> online
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-7">
|
||||
<div class="progress progress-sm mr-2">
|
||||
<div class="progress-bar bg-info" role="progressbar" id="clusterPercentageProgressBar" style="width: 0%" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-sm-12 col-md-6 col-xl-4 py-2 mb-4">
|
||||
<div class="card border-left-primary shadow h-100">
|
||||
<div class="card-body">
|
||||
<div class="row no-gutters align-items-center">
|
||||
<div class="col-5">
|
||||
<div class="text-xs font-weight-bold text-primary text-uppercase mb-1">
|
||||
Host Memory
|
||||
</div>
|
||||
<div class="h5 mb-0 font-weight-bold text-gray-600 align-middle">
|
||||
<i class="fas fa-memory fa-1x mr-2 text-primary"></i>
|
||||
<span id="memoryPercentage">0</span>%
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-7">
|
||||
<div class="progress progress-sm mr-2">
|
||||
<div class="progress-bar bg-info" role="progressbar" id="memoryPercentageProgressBar" style="width: 0%" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-sm-6 col-lg-4 col-xl-2 py-2 mb-4">
|
||||
<div class="card shadow h-100">
|
||||
<a href="#" class="stretched-link" id="imagesLink"></a>
|
||||
<div class="card-body">
|
||||
<div class="row no-gutters align-items-center">
|
||||
<div class="col-7">
|
||||
<div class="text-xs font-weight-bold text-primary text-uppercase mb-1">
|
||||
Images
|
||||
</div>
|
||||
<div class="h5 mb-0 font-weight-bold text-gray-600 align-middle">
|
||||
<span id="totalImages">0</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-5">
|
||||
<i class="fas fa-box-open fa-3x text-gray-200"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-sm-6 col-lg-4 col-xl-2 py-2 mb-4">
|
||||
<div class="card shadow h-100">
|
||||
<a href="#" class="stretched-link" id="profilesLink"></a>
|
||||
<div class="card-body">
|
||||
<div class="row no-gutters align-items-center">
|
||||
<div class="col-7">
|
||||
<div class="text-xs font-weight-bold text-primary text-uppercase mb-1">
|
||||
Profiles
|
||||
</div>
|
||||
<div class="h5 mb-0 font-weight-bold text-gray-600 align-middle">
|
||||
<span id="totalProfiles">0</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-5">
|
||||
<i class="fas fa-money-check fa-3x text-gray-200"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-sm-6 col-lg-4 col-xl-2 py-2 mb-4">
|
||||
<div class="card shadow h-100">
|
||||
<a href="#" class="stretched-link" id="networksLink"></a>
|
||||
<div class="card-body">
|
||||
<div class="row no-gutters align-items-center">
|
||||
<div class="col-7">
|
||||
<div class="text-xs font-weight-bold text-primary text-uppercase mb-1">
|
||||
Networks
|
||||
</div>
|
||||
<div class="h5 mb-0 font-weight-bold text-gray-600 align-middle">
|
||||
<span id="totalNetworks">0</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-5">
|
||||
<i class="fas fa-network-wired fa-3x text-gray-200"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-sm-6 col-lg-4 col-xl-2 py-2 mb-4">
|
||||
<div class="card shadow h-100">
|
||||
<a href="#" class="stretched-link" id="storagePoolsLink"></a>
|
||||
<div class="card-body">
|
||||
<div class="row no-gutters align-items-center">
|
||||
<div class="col-7">
|
||||
<div class="text-xs font-weight-bold text-primary text-uppercase mb-1">
|
||||
Storage Pools
|
||||
</div>
|
||||
<div class="h5 mb-0 font-weight-bold text-gray-600 align-middle">
|
||||
<span id="totalStoragePools">0</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-5">
|
||||
<i class="fas fa-hdd fa-3x text-gray-200"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-sm-6 col-lg-4 col-xl-2 py-2 mb-4">
|
||||
<div class="card shadow h-100">
|
||||
<a href="#" class="stretched-link" id="projectsLink"></a>
|
||||
<div class="card-body">
|
||||
<div class="row no-gutters align-items-center">
|
||||
<div class="col-7">
|
||||
<div class="text-xs font-weight-bold text-primary text-uppercase mb-1">
|
||||
Projects
|
||||
</div>
|
||||
<div class="h5 mb-0 font-weight-bold text-gray-600 align-middle">
|
||||
<span id="totalProjects">0</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-5">
|
||||
<i class="fas fa-chart-bar fa-3x text-gray-200"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-sm-6 col-lg-4 col-xl-2 py-2 mb-4">
|
||||
<div class="card shadow h-100">
|
||||
<a href="#" class="stretched-link" id="networkAclsLink"></a>
|
||||
<div class="card-body">
|
||||
<div class="row no-gutters align-items-center">
|
||||
<div class="col-7">
|
||||
<div class="text-xs font-weight-bold text-primary text-uppercase mb-1">
|
||||
Network ACLs
|
||||
</div>
|
||||
<div class="h5 mb-0 font-weight-bold text-gray-600 align-middle">
|
||||
<span id="totalNetworkAcls">0</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-5">
|
||||
<i class="fas fa-shield-alt fa-3x text-gray-200"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-sm-12 col-md-6 mb-4">
|
||||
<div class="card shadow h-100">
|
||||
<div class="card-header py-3 d-flex flex-row align-items-center justify-content-between">
|
||||
<h6 class="m-0 font-weight-bold text-primary">LXD Information</h6>
|
||||
</div>
|
||||
<!-- Card Body -->
|
||||
<div class="card-body">
|
||||
<strong>Operating System</strong>: <span id="osName"></span> <span id="osVersion"></span><br />
|
||||
<strong>LXD Version</strong>: <span id="serverVersion"></span><br />
|
||||
<strong>Hostname</strong>: <span id="serverName"></span><br />
|
||||
<strong>Kernel</strong>: <span id="kernel"></span> <span id="kernelArchitecture"></span><br />
|
||||
<strong>Firewall</strong>: <span id="firewall"></span><br />
|
||||
<br />
|
||||
<strong>Driver</strong>: <span id="driver"></span><br />
|
||||
<strong>Driver Version</strong>: <span id="driverVersion"></span><br />
|
||||
<br />
|
||||
<strong>Storage Type</strong>: <span id="storage"></span><br />
|
||||
<strong>Storage Version</strong>: <span id="storageVersion"></span><br />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-sm-12 col-md-6 mb-4">
|
||||
<div class="card shadow h-100">
|
||||
<div class="card-header py-3 d-flex flex-row align-items-center justify-content-between">
|
||||
<h6 class="m-0 font-weight-bold text-primary">Resource Information</h6>
|
||||
</div>
|
||||
<!-- Card Body -->
|
||||
<div class="card-body">
|
||||
<strong>System Vendor</strong>: <span id="systemVendor"></span> <br />
|
||||
<strong>System Product</strong>: <span id="systemProduct"></span> <br />
|
||||
<strong>Total Memory</strong>: <span id="memoryTotal"></span><span id="memoryUnit"></span><br />
|
||||
<br />
|
||||
<strong>CPU Information</strong>:
|
||||
<ul>
|
||||
<li><strong>Architecture</strong>: <span id="architecture"></span> </li>
|
||||
<li><strong>CPU Count</strong>: <span id="cpus"></span> </li>
|
||||
<li><strong>Socket</strong>: <span id="sockets"></span> </li>
|
||||
<ul id="socketList"></ul>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-sm-12 col-md-7 mb-4">
|
||||
<div class="card shadow h-100">
|
||||
<div class="card-header py-3 d-flex flex-row align-items-center justify-content-between">
|
||||
<h6 class="m-0 font-weight-bold text-primary">Disk Storage Information</h6>
|
||||
</div>
|
||||
<!-- Card Body -->
|
||||
<div class="card-body">
|
||||
<table class="table">
|
||||
<thead>
|
||||
<th>ID</th>
|
||||
<th>Model</th>
|
||||
<th>Type</th>
|
||||
<th>Size</th>
|
||||
</thead>
|
||||
<tbody id="diskList"></tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-sm-12 col-md-5 mb-4">
|
||||
<div class="card shadow h-100">
|
||||
<div class="card-header py-3 d-flex flex-row align-items-center justify-content-between">
|
||||
<h6 class="m-0 font-weight-bold text-primary">IP Addresses Information</h6>
|
||||
</div>
|
||||
<!-- Card Body -->
|
||||
<div class="card-body">
|
||||
<strong>Addresses</strong>: <br />
|
||||
<ul id="addressList"></ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
<!-- /.container-fluid -->
|
||||
</div>
|
||||
<!-- End of Main Content -->
|
||||
|
||||
<!-- Footer -->
|
||||
<footer class="sticky-footer bg-white">
|
||||
<div class="container my-auto">
|
||||
<div class="copyright text-center my-auto">
|
||||
<span>Copyright © lxdware.com 2021</span>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
<!-- End of Footer -->
|
||||
|
||||
</div>
|
||||
<!-- End of Content Wrapper -->
|
||||
|
||||
</div>
|
||||
<!-- End of Page Wrapper -->
|
||||
|
||||
<!-- Scroll to Top Button-->
|
||||
<a class="scroll-to-top rounded" href="#page-top">
|
||||
<i class="fas fa-angle-up"></i>
|
||||
</a>
|
||||
|
||||
<!-- About Modal-->
|
||||
<div class="modal fade" id="aboutModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="exampleModalLabel">About</h5>
|
||||
<button class="close" type="button" data-dismiss="modal" aria-label="Close">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<div id="about"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button class="btn btn-secondary" type="button" data-dismiss="modal">Dismiss</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Bootstrap core JavaScript-->
|
||||
<script src="vendor/jquery/jquery.min.js"></script>
|
||||
<script src="vendor/bootstrap/js/bootstrap.bundle.min.js"></script>
|
||||
|
||||
<!-- Core plugin JavaScript-->
|
||||
<script src="vendor/jquery-easing/jquery.easing.min.js"></script>
|
||||
|
||||
<!-- Custom scripts for all pages-->
|
||||
<script src="vendor/sb-admin-2/js/sb-admin-2.min.js"></script>
|
||||
|
||||
<!-- Page level plugins -->
|
||||
|
||||
|
||||
|
||||
</body>
|
||||
|
||||
<script>
|
||||
const queryString = window.location.search;
|
||||
const urlParams = new URLSearchParams(queryString);
|
||||
const remoteId = urlParams.get('remote');
|
||||
const projectName = urlParams.get('project');
|
||||
|
||||
function logout(){
|
||||
$.get("./php/aaa/authentication.php?action=deauthenticateUser", function (data) {
|
||||
operationData = JSON.parse(data);
|
||||
console.log(operationData);
|
||||
if (operationData.status_code == 200) {
|
||||
window.location = './index.html'
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function operationStatusCheck(){
|
||||
//check to see if there are any running operations
|
||||
$.get("./php/lxd/operations.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&action=displayOperationStatus", function (data) {
|
||||
//Check to see if we have running operations
|
||||
if (data){
|
||||
//Display spinner and notification area if there are running tasks
|
||||
$('#spinner').show();
|
||||
$('#notificationArea').show();
|
||||
$('#notification').text(data);
|
||||
//Set the page to check operations again in 1 second
|
||||
setTimeout(() => { operationStatusCheck(); }, 1000);
|
||||
}
|
||||
else {
|
||||
//Hide spinner and notification area if no running tasks
|
||||
$('#spinner').hide();
|
||||
$('#notificationArea').hide();
|
||||
$('#notification').text("");
|
||||
//Set the page to check operations again in 3 seconds
|
||||
setTimeout(() => { operationStatusCheck(); }, 3000);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function reloadPageContent() {
|
||||
|
||||
//Check Authorization
|
||||
$.get("./php/aaa/authentication.php?action=validateAuthentication", function (data) {
|
||||
operationData = JSON.parse(data);
|
||||
if (operationData.status_code != 200) {
|
||||
console.log(operationData);
|
||||
window.location = './index.html'
|
||||
}
|
||||
});
|
||||
|
||||
//Resource Info
|
||||
$.get("./php/lxd/remotes-single.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&action=displaySysInfo", function (data) {
|
||||
stats = JSON.parse(data);
|
||||
$("#memoryPercentage").text(stats.memoryPercentage);
|
||||
$("#memoryPercentageProgressBar").css("width", stats.memoryPercentage + "%")
|
||||
});
|
||||
|
||||
//Instance Info
|
||||
$.get("./php/lxd/remotes-single.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&action=displayInstanceInfo", function (data) {
|
||||
stats = JSON.parse(data);
|
||||
$("#runningInstances").text(stats.runningInstances);
|
||||
$("#totalInstances").text(stats.totalInstances);
|
||||
instancePercentage = stats.runningInstances / stats.totalInstances * 100
|
||||
$("#instancePercentageProgressBar").css("width", instancePercentage + "%")
|
||||
});
|
||||
|
||||
//Cluster Member Info
|
||||
$.get("./php/lxd/remotes-single.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&action=displayClusterInfo", function (data) {
|
||||
stats = JSON.parse(data);
|
||||
$("#onlineClusterMembers").text(stats.onlineClusterMembers);
|
||||
$("#totalClusterMembers").text(stats.totalClusterMembers);
|
||||
clusterPercentage = stats.onlineClusterMembers / stats.totalClusterMembers * 100
|
||||
$("#clusterPercentageProgressBar").css("width", clusterPercentage + "%")
|
||||
});
|
||||
|
||||
//Image Info
|
||||
$.get("./php/lxd/remotes-single.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&action=displayImageInfo", function (data) {
|
||||
stats = JSON.parse(data);
|
||||
$("#totalImages").text(stats.totalImages);
|
||||
});
|
||||
|
||||
//Network Info
|
||||
$.get("./php/lxd/remotes-single.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&action=displayNetworkInfo", function (data) {
|
||||
stats = JSON.parse(data);
|
||||
$("#totalNetworks").text(stats.totalNetworks);
|
||||
});
|
||||
|
||||
//Network ACL Info
|
||||
$.get("./php/lxd/remotes-single.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&action=displayNetworkAclInfo", function (data) {
|
||||
stats = JSON.parse(data);
|
||||
$("#totalNetworkAcls").text(stats.totalNetworkAcls);
|
||||
});
|
||||
|
||||
//Profile Info
|
||||
$.get("./php/lxd/remotes-single.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&action=displayProfileInfo", function (data) {
|
||||
stats = JSON.parse(data);
|
||||
$("#totalProfiles").text(stats.totalProfiles);
|
||||
});
|
||||
|
||||
//Project Info
|
||||
$.get("./php/lxd/remotes-single.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&action=displayProjectInfo", function (data) {
|
||||
stats = JSON.parse(data);
|
||||
$("#totalProjects").text(stats.totalProjects);
|
||||
});
|
||||
|
||||
//Storage Pool Info
|
||||
$.get("./php/lxd/remotes-single.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&action=displayStorageInfo", function (data) {
|
||||
stats = JSON.parse(data);
|
||||
$("#totalStoragePools").text(stats.totalStoragePools);
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
function loadPageContent(){
|
||||
|
||||
//Display current logged in username
|
||||
$("#username").load("./php/admin/settings.php?action=displayUsername");
|
||||
|
||||
$("#sidebarLinks").load("./sidebar.html");
|
||||
|
||||
$('#remoteBreadCrumb').load("./php/lxd/remote-breadcrumb.php?remote=" + encodeURI(remoteId));
|
||||
|
||||
|
||||
//Resource Info
|
||||
$.get("./php/lxd/remotes-single.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&action=displaySysInfo", function (data) {
|
||||
stats = JSON.parse(data);
|
||||
|
||||
$("#systemVendor").text(stats.systemVendor);
|
||||
$("#systemProduct").text(stats.systemProduct);
|
||||
$("#architecture").text(stats.architecture);
|
||||
$("#cpus").text(stats.cpus);
|
||||
$("#memoryTotal").text(stats.memoryTotal);
|
||||
$("#memoryUnit").text(stats.memoryUnit);
|
||||
|
||||
$("#memoryPercentage").text(stats.memoryPercentage);
|
||||
$("#memoryPercentageProgressBar").css("width", stats.memoryPercentage + "%")
|
||||
|
||||
sockets = stats.sockets;
|
||||
sockets.forEach(element => {
|
||||
$("#socketList").append('<li>Socket '+element.socket+': '+element.name+'</li>');
|
||||
});
|
||||
|
||||
disks = stats.storageDisks;
|
||||
disks.forEach(element => {
|
||||
if (element.type == "cdrom"){
|
||||
return;
|
||||
}
|
||||
tableRow = '<tr>';
|
||||
tableRow += '<td>'+element.id+'</td>';
|
||||
tableRow += '<td>'+element.model+'</td>';
|
||||
tableRow += '<td>'+element.type+'</td>';
|
||||
if (element.size < 1099511627776){
|
||||
diskTotal = Math.round(element.size/1024/1024/1024 * 100) / 100;
|
||||
diskUnit = "GB";
|
||||
}
|
||||
else {
|
||||
diskTotal = Math.round(element.size/1024/1024/1024/1024 * 100) / 100;
|
||||
diskUnit = "TB";
|
||||
}
|
||||
tableRow += '<td>'+diskTotal + ' ' +diskUnit +'</td>';
|
||||
tableRow += '</tr>';
|
||||
$('#diskList').append(tableRow);
|
||||
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
//LXD Info
|
||||
$.get("./php/lxd/remotes-single.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&action=displayLxdInfo", function (data) {
|
||||
stats = JSON.parse(data);
|
||||
|
||||
$("#driver").text(stats.driver);
|
||||
$("#driverVersion").text(stats.driverVersion);
|
||||
$("#firewall").text(stats.firewall);
|
||||
$("#kernel").text(stats.kernel);
|
||||
$("#kernelArchitecture").text(stats.kernelArchitecture);
|
||||
$("#kernelVersion").text(stats.kernelVersion);
|
||||
$("#osName").text(stats.osName);
|
||||
$("#osVersion").css("width", stats.osVersion)
|
||||
|
||||
$("#serverVersion").text(stats.serverVersion);
|
||||
|
||||
$("#serverName").text(stats.serverName);
|
||||
$("#storage").text(stats.storage);
|
||||
$("#storageVersion").text(stats.storageVersion);
|
||||
|
||||
addresses = stats.addresses;
|
||||
addresses.forEach(element => {
|
||||
$("#addressList").append('<li>'+element+'</li>');
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
//Instance Info
|
||||
$.get("./php/lxd/remotes-single.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&action=displayInstanceInfo", function (data) {
|
||||
stats = JSON.parse(data);
|
||||
$("#runningInstances").text(stats.runningInstances);
|
||||
$("#totalInstances").text(stats.totalInstances);
|
||||
instancePercentage = stats.runningInstances / stats.totalInstances * 100
|
||||
$("#instancePercentageProgressBar").css("width", instancePercentage + "%")
|
||||
});
|
||||
|
||||
//Cluster Member Info
|
||||
$.get("./php/lxd/remotes-single.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&action=displayClusterInfo", function (data) {
|
||||
stats = JSON.parse(data);
|
||||
$("#onlineClusterMembers").text(stats.onlineClusterMembers);
|
||||
$("#totalClusterMembers").text(stats.totalClusterMembers);
|
||||
clusterPercentage = stats.onlineClusterMembers / stats.totalClusterMembers * 100
|
||||
$("#clusterPercentageProgressBar").css("width", clusterPercentage + "%")
|
||||
});
|
||||
|
||||
//Image Info
|
||||
$.get("./php/lxd/remotes-single.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&action=displayImageInfo", function (data) {
|
||||
stats = JSON.parse(data);
|
||||
$("#totalImages").text(stats.totalImages);
|
||||
});
|
||||
|
||||
//Network Info
|
||||
$.get("./php/lxd/remotes-single.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&action=displayNetworkInfo", function (data) {
|
||||
stats = JSON.parse(data);
|
||||
$("#totalNetworks").text(stats.totalNetworks);
|
||||
});
|
||||
|
||||
//Network ACL Info
|
||||
$.get("./php/lxd/remotes-single.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&action=displayNetworkAclInfo", function (data) {
|
||||
stats = JSON.parse(data);
|
||||
$("#totalNetworkAcls").text(stats.totalNetworkAcls);
|
||||
});
|
||||
|
||||
//Profile Info
|
||||
$.get("./php/lxd/remotes-single.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&action=displayProfileInfo", function (data) {
|
||||
stats = JSON.parse(data);
|
||||
$("#totalProfiles").text(stats.totalProfiles);
|
||||
});
|
||||
|
||||
//Project Info
|
||||
$.get("./php/lxd/remotes-single.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&action=displayProjectInfo", function (data) {
|
||||
stats = JSON.parse(data);
|
||||
$("#totalProjects").text(stats.totalProjects);
|
||||
});
|
||||
|
||||
//Storage Pool Info
|
||||
$.get("./php/lxd/remotes-single.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&action=displayStorageInfo", function (data) {
|
||||
stats = JSON.parse(data);
|
||||
$("#totalStoragePools").text(stats.totalStoragePools);
|
||||
});
|
||||
|
||||
//Check for any running operations
|
||||
operationStatusCheck();
|
||||
|
||||
//Set the page content to reload in 10 seconds
|
||||
setInterval(() => { reloadPageContent(); }, 10000);
|
||||
}
|
||||
|
||||
$(document).ready(function(){
|
||||
|
||||
//Check Authorization
|
||||
$.get("./php/aaa/authentication.php?action=validateAuthentication", function (data) {
|
||||
operationData = JSON.parse(data);
|
||||
if (operationData.status_code != 200) {
|
||||
console.log(operationData);
|
||||
window.location = './index.html'
|
||||
}
|
||||
});
|
||||
|
||||
$("#remoteListNav").load("./php/lxd/remotes.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&action=listRemotesForTopNavigation");
|
||||
$("#projectListNav").load("./php/lxd/projects.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&action=listProjectsForTopNavigation");
|
||||
|
||||
//Load Page Content
|
||||
loadPageContent();
|
||||
|
||||
//Set hyperlink references for cards
|
||||
$("#instancesLink").attr("href", "instances.html?remote="+remoteId+"&project="+projectName)
|
||||
$("#clusterMembersLink").attr("href", "cluster-members.html?remote="+remoteId+"&project="+projectName)
|
||||
$("#imagesLink").attr("href", "images.html?remote="+remoteId+"&project="+projectName)
|
||||
$("#profilesLink").attr("href", "profiles.html?remote="+remoteId+"&project="+projectName)
|
||||
$("#networksLink").attr("href", "networks.html?remote="+remoteId+"&project="+projectName)
|
||||
$("#storagePoolsLink").attr("href", "storage-pools.html?remote="+remoteId+"&project="+projectName)
|
||||
$("#projectsLink").attr("href", "projects.html?remote="+remoteId+"&project="+projectName)
|
||||
$("#networkAclsLink").attr("href", "network-acls.html?remote="+remoteId+"&project="+projectName)
|
||||
|
||||
//Load the about info for the about modal
|
||||
$.get("./about.html", function (data) {
|
||||
$("#about").html(data);
|
||||
});
|
||||
|
||||
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
</html>
|
1022
lxd-dashboard/remotes-single.php
Normal file
|
@ -37,7 +37,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
|
||||
<!-- Custom styles for this template-->
|
||||
<link href="vendor/sb-admin-2/css/sb-admin-2.css" rel="stylesheet">
|
||||
<link href="assets/css/style.css" rel="stylesheet">
|
||||
<link href="assets/css/style.css?version=3.0" rel="stylesheet">
|
||||
|
||||
<!-- Custom styles for this page -->
|
||||
<link href="vendor/datatables/dataTables.bootstrap4.min.css" rel="stylesheet">
|
||||
|
@ -50,10 +50,10 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
<div id="wrapper">
|
||||
|
||||
<!-- Sidebar -->
|
||||
<ul class="navbar-nav bg-dark sidebar sidebar-dark accordion" id="accordionSidebar">
|
||||
<ul class="navbar-nav bg-dark sidebar sidebar-dark accordion sidebar-divider-right" id="accordionSidebar">
|
||||
|
||||
<!-- Sidebar - Brand -->
|
||||
<a class="sidebar-brand d-flex align-items-center justify-content-center" href="index.html">
|
||||
<a class="sidebar-brand d-flex align-items-center justify-content-center" href="index.php">
|
||||
<div class="sidebar-brand-icon rotate-n-0">
|
||||
<img src="assets/images/logo-dark.svg" style="width: 2rem;"></img>
|
||||
<!-- <i class="fas fa-cube" style="width: 2rem;"></i> -->
|
||||
|
@ -66,7 +66,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
|
||||
<!-- Nav Item - Dashboard -->
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="remotes.html">
|
||||
<a class="nav-link" href="remotes.php">
|
||||
<i class="fas fa-fw fa-server"></i>
|
||||
<span>Hosts</span></a>
|
||||
</li>
|
||||
|
@ -76,12 +76,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
|
||||
<!-- Sidebar Toggler (Sidebar) -->
|
||||
<div class="text-center d-none d-md-inline">
|
||||
<button class="rounded-circle border-0" id="sidebarToggle"></button>
|
||||
<button class="rounded-circle border-0" id="sidebarToggle" onclick="setSidebarToggleValue()"></button>
|
||||
</div>
|
||||
</ul>
|
||||
<!-- End of Sidebar -->
|
||||
|
||||
|
||||
<!-- Content Wrapper -->
|
||||
<div id="content-wrapper" class="d-flex flex-column">
|
||||
|
||||
|
@ -96,8 +95,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
<i class="fa fa-bars"></i>
|
||||
</button>
|
||||
|
||||
|
||||
|
||||
<!-- Topbar Navbar -->
|
||||
<ul class="navbar-nav ml-auto">
|
||||
|
||||
|
@ -111,14 +108,18 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
</a>
|
||||
<!-- Dropdown - User Information -->
|
||||
<div class="dropdown-menu dropdown-menu-right shadow animated--grow-in" aria-labelledby="userDropdown">
|
||||
<a class="dropdown-item" href="user-profile.html">
|
||||
<a class="dropdown-item" href="user-profile.php">
|
||||
<i class="fas fa-user fa-sm fa-fw mr-2 text-gray-400"></i>
|
||||
Profile
|
||||
</a>
|
||||
<a class="dropdown-item" href="settings.html">
|
||||
<a class="dropdown-item" href="settings.php">
|
||||
<i class="fas fa-cog fa-sm fa-fw mr-2 text-gray-400"></i>
|
||||
Settings
|
||||
</a>
|
||||
<a class="dropdown-item" href="logs.php">
|
||||
<i class="fas fa-history fa-sm fa-fw mr-2 text-gray-400"></i>
|
||||
Logs
|
||||
</a>
|
||||
<a class="dropdown-item" href="#" data-toggle="modal" data-target="#aboutModal">
|
||||
<i class="fas fa-info-circle fa-sm fa-fw mr-2 text-gray-400"></i>
|
||||
About
|
||||
|
@ -139,43 +140,65 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
<!-- Begin Page Content -->
|
||||
<div class="container-fluid">
|
||||
|
||||
<!-- Page Heading -->
|
||||
<div class="d-sm-flex align-items-center justify-content-between mb-4">
|
||||
<h1 class="h5 mb-0 text-gray-800">REMOTE HOSTS</h1>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<!-- LXD Host List -->
|
||||
|
||||
<div class="card shadow mb-4">
|
||||
<!-- Card Header - Dropdown -->
|
||||
<div class="card-header py-3 d-flex flex-row align-items-center justify-content-between">
|
||||
<h6 class="m-0 font-weight-bold text-primary">LXD Hosts</h6>
|
||||
<div class="dropdown no-arrow">
|
||||
<a class="dropdown-toggle mr-3" href="#" data-toggle="modal" data-target="#clientCertModal">
|
||||
View Certificate</a>
|
||||
<a class="dropdown-toggle mr-3" href="#" data-toggle="modal" data-target="#addLxdModal">
|
||||
Add Host</a>
|
||||
<header class="page-header page-header-dark bg-gradient-primary-to-secondary">
|
||||
<div class="container-xl px-4">
|
||||
<div class="page-header-content pt-4">
|
||||
<div class="row align-items-center justify-content-between mt-n5 ml-n5 mr-n5 bg-dark pb-6">
|
||||
<div class="col-auto mt-4 ml-3">
|
||||
<div class="page-header-subtitle">
|
||||
<span id="remoteBreadCrumb">LXD Dashboard</span>
|
||||
</div>
|
||||
<h2 class="page-header-title mt-2">
|
||||
REMOTE HOSTS
|
||||
</h2>
|
||||
<div class="page-header-subtitle">
|
||||
Add and manage remote LXD host servers
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Card Body -->
|
||||
<div class="card-body">
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<div class="table-responsive">
|
||||
<table class="table" id="lxdListTable" width="100%" cellspacing="0">
|
||||
</table>
|
||||
</div>
|
||||
<div class="col-12 col-xl-auto mt-4">
|
||||
<div class="input-group input-group-joined border-0" style="width: 26rem">
|
||||
<span class="input-group-text bg-transparent border-0">
|
||||
<a class="btn btn-outline-primary mr-3" href="#" data-toggle="modal" data-target="#clientCertModal" title="View Certificate" aria-hidden="true">
|
||||
View Certificate
|
||||
</a>
|
||||
<a class="btn btn-outline-primary" href="#" data-toggle="modal" data-target="#addLxdModal" title="Add Host" aria-hidden="true">
|
||||
<i class="fas fa-plus fa-sm fa-fw"></i> Add Host
|
||||
</a>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- End LXD Host List -->
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<div class="row mt-n5 ml-2 mr-2">
|
||||
|
||||
<div class="col-12 mt-n3">
|
||||
<!-- Remote Host List -->
|
||||
<div class="card shadow mb-4">
|
||||
<!-- Card Header - Dropdown -->
|
||||
<div class="card-header py-3 d-flex flex-row align-items-center justify-content-between">
|
||||
<h6 class="m-0 font-weight-bold">
|
||||
<span class="ml-1">Hosts</span>
|
||||
</h6>
|
||||
<div class="dropdown no-arrow">
|
||||
<a class="dropdown-toggle mr-2" href="#" onclick="reloadPageContent()" title="Refresh" aria-hidden="true">
|
||||
<i class="fa fa-sync fa-1x fa-fw"></i></a>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Card Body -->
|
||||
<div class="card-body">
|
||||
<div class="table-responsive">
|
||||
<table class="table" id="lxdListTable" width="100%" cellspacing="0">
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- End Remote Host List -->
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<!-- /.container-fluid -->
|
||||
|
@ -188,7 +211,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
<footer class="sticky-footer bg-white">
|
||||
<div class="container my-auto">
|
||||
<div class="copyright text-center my-auto">
|
||||
<span>Copyright © lxdware.com 2021</span>
|
||||
<span>Copyright © LXDWARE 2020 - Present</span>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
|
@ -205,7 +228,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
<i class="fas fa-angle-up"></i>
|
||||
</a>
|
||||
|
||||
<!-- Remote Host Modal-->
|
||||
<!-- Add Remote Host Modal-->
|
||||
<div class="modal fade" id="addLxdModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog modal-lg" role="document">
|
||||
<div class="modal-content">
|
||||
|
@ -222,26 +245,26 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
</p>
|
||||
|
||||
<div class="row">
|
||||
<label class="col-3 col-form-label text-right">Address: </label>
|
||||
<label class="col-3 col-form-label text-right">Address: <span class="text-danger">*</span></label>
|
||||
<div class="col-7">
|
||||
<div class="form-group">
|
||||
<input type="text" class="form-control" id="hostInput" required="required" name="host">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-1">
|
||||
<i class="far fa-sm fa-question-circle text-danger" title='(Required) - Enter in the IP address or FQDN of the LXD server'></i>
|
||||
<i class="far fa-sm fa-question-circle" title='(Required) - Enter in the IP address or FQDN of the LXD server'></i>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<label class="col-3 col-form-label text-right">Port: </label>
|
||||
<label class="col-3 col-form-label text-right">Port: <span class="text-danger">*</span></label>
|
||||
<div class="col-7">
|
||||
<div class="form-group">
|
||||
<input type="number" class="form-control" id="portInput" required="required" value="8443" name="port">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-1">
|
||||
<i class="far fa-sm fa-question-circle text-danger" title='(Required) - Enter in the listening network port to connect to the LXD server. Default: 8443'></i>
|
||||
<i class="far fa-sm fa-question-circle" title='(Required) - Enter in the listening network port to connect to the LXD server. Default: 8443'></i>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -257,6 +280,30 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<label class="col-3 col-form-label text-right">External Address: </label>
|
||||
<div class="col-7">
|
||||
<div class="form-group">
|
||||
<input type="text" class="form-control" id="externalHostInput" required="required" name="host">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-1">
|
||||
<i class="far fa-sm fa-question-circle" title='Enter in the IP address or FQDN of the LXD server used for making remote websocket connections. If empty, the host address will be used.'></i>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<label class="col-3 col-form-label text-right">External Port: </label>
|
||||
<div class="col-7">
|
||||
<div class="form-group">
|
||||
<input type="number" class="form-control" id="externalPortInput" required="required" name="port">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-1">
|
||||
<i class="far fa-sm fa-question-circle" title='Enter in the listening network port to connect to the LXD server used for making remote websocket connections. If empty, the host port will be used.'></i>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div> <!-- End Modal Body-->
|
||||
<div class="modal-footer">
|
||||
<button class="btn btn-secondary" type="button" data-dismiss="modal">Cancel</button>
|
||||
|
@ -266,6 +313,89 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Edit Remote Host Modal-->
|
||||
<div class="modal fade" id="editLxdHost" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog modal-lg" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="exampleModalLabel">Edit LXD Host</h5>
|
||||
<button class="close" type="button" data-dismiss="modal" aria-label="Close">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
|
||||
<div class="row">
|
||||
<label class="col-3 col-form-label text-right">Address: <span class="text-danger">*</span></label>
|
||||
<div class="col-7">
|
||||
<div class="form-group">
|
||||
<input type="text" class="form-control" id="hostEditInput" required="required" name="host">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-1">
|
||||
<i class="far fa-sm fa-question-circle" title='(Required) - Enter in the IP address or FQDN of the LXD server'></i>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<label class="col-3 col-form-label text-right">Port: <span class="text-danger">*</span></label>
|
||||
<div class="col-7">
|
||||
<div class="form-group">
|
||||
<input type="number" class="form-control" id="portEditInput" required="required" value="8443" name="port">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-1">
|
||||
<i class="far fa-sm fa-question-circle" title='(Required) - Enter in the listening network port to connect to the LXD server. Default: 8443'></i>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<label class="col-3 col-form-label text-right">Alias: </label>
|
||||
<div class="col-7">
|
||||
<div class="form-group">
|
||||
<input type="text" class="form-control" id="aliasEditInput" name="alias">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-1">
|
||||
<i class="far fa-sm fa-question-circle" title='Enter in a friendly name to identify the LXD server in the dashboard.'></i>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<label class="col-3 col-form-label text-right">External Address: </label>
|
||||
<div class="col-7">
|
||||
<div class="form-group">
|
||||
<input type="text" class="form-control" id="externalHostEditInput" required="required" name="host">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-1">
|
||||
<i class="far fa-sm fa-question-circle" title='Enter in the IP address or FQDN of the LXD server used for making remote websocket connections. If empty, the host address will be used.'></i>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<label class="col-3 col-form-label text-right">External Port: </label>
|
||||
<div class="col-7">
|
||||
<div class="form-group">
|
||||
<input type="number" class="form-control" id="externalPortEditInput" required="required" name="port">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-1">
|
||||
<i class="far fa-sm fa-question-circle" title='Enter in the listening network port to connect to the LXD server used for making remote websocket connections. If empty, the host port will be used.'></i>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<input type="hidden" id="idEditInput">
|
||||
|
||||
</div> <!-- End Modal Body-->
|
||||
<div class="modal-footer">
|
||||
<button class="btn btn-secondary" type="button" data-dismiss="modal">Cancel</button>
|
||||
<a class="btn btn-primary" href="#" onclick="updateRemote()" data-dismiss="modal">Submit</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Instructions Modal-->
|
||||
<div class="modal fade" id="instructionsModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog modal-lg" role="document">
|
||||
|
@ -314,7 +444,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
<div class="modal-body">
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<pre><div id="clientCert"></div></pre>
|
||||
<pre><div class="pl-5" id="clientCert"></div></pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -386,43 +516,51 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
|
||||
|
||||
<script>
|
||||
var reloadTime = 5000;
|
||||
|
||||
function logout(){
|
||||
$.get("./php/aaa/authentication.php?action=deauthenticateUser", function (data) {
|
||||
function logout(){
|
||||
$.get("./backend/aaa/authentication.php?action=deauthenticateUser", function (data) {
|
||||
operationData = JSON.parse(data);
|
||||
console.log(operationData);
|
||||
if (operationData.status_code == 200) {
|
||||
window.location = './index.html'
|
||||
window.location.href = './index.php'
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function reloadPageContent() {
|
||||
|
||||
clearTimeout(pageReloadTimeout);
|
||||
|
||||
//Check Authorization
|
||||
$.get("./php/aaa/authentication.php?action=validateAuthentication", function (data) {
|
||||
$.get("./backend/aaa/authentication.php?action=validateAuthentication", function (data) {
|
||||
operationData = JSON.parse(data);
|
||||
if (operationData.status_code != 200) {
|
||||
console.log(operationData);
|
||||
window.location = './index.html'
|
||||
window.location.href = './index.php'
|
||||
}
|
||||
});
|
||||
|
||||
$('#lxdListTable').DataTable().ajax.reload(null, false);
|
||||
|
||||
//Set reload page content
|
||||
pageReloadTimeout = setTimeout(() => { reloadPageContent(); }, reloadTime);
|
||||
}
|
||||
|
||||
function loadPageContent(){
|
||||
|
||||
//Display current logged in username
|
||||
$("#username").load("./php/admin/settings.php?action=displayUsername");
|
||||
$("#username").load("./backend/admin/settings.php?action=displayUsername");
|
||||
|
||||
$('#lxdListTable').DataTable( {
|
||||
ajax: "./php/lxd/remotes.php?action=listRemotes",
|
||||
ajax: "./backend/lxd/remotes.php?action=listRemotes",
|
||||
columns: [
|
||||
{},
|
||||
{ title: "Host" },
|
||||
{ title: "Port" },
|
||||
{ title: "Alias" },
|
||||
{ title: "External Address" },
|
||||
{ title: "External Port" },
|
||||
{ title: "Protocol" },
|
||||
{ title: "Action" }
|
||||
],
|
||||
|
@ -433,12 +571,17 @@ function logout(){
|
|||
});
|
||||
|
||||
//Load the basic info for the certificate
|
||||
$.get("./php/config/cert.php?action=viewCertificate", function (data) {
|
||||
$.get("./backend/config/cert.php?action=viewCertificate", function (data) {
|
||||
$("#clientCert").html(data);
|
||||
});
|
||||
|
||||
//Set the page content to reload in 5 seconds
|
||||
setInterval(() => { reloadPageContent(); }, 5000);
|
||||
//Set reload page content
|
||||
$.get("./backend/admin/settings.php?action=retrievePageRefreshRateValues", function (data) {
|
||||
operationData = JSON.parse(data);
|
||||
if (operationData.remotes_page_rate >= 1)
|
||||
reloadTime = operationData.remotes_page_rate * 1000;
|
||||
pageReloadTimeout = setTimeout(() => { reloadPageContent(); }, reloadTime);
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
@ -447,7 +590,12 @@ function logout(){
|
|||
var portNumber = $("#portInput").val();
|
||||
var aliasName = $("#aliasInput").val();
|
||||
console.log("Info: adding remote host " + hostName + ":" + portNumber);
|
||||
$.get("./php/lxd/remotes.php?host=" + encodeURI(hostName) + "&port=" + encodeURI(portNumber) + "&alias=" + encodeURI(aliasName) + "&action=addRemote", function (data) {
|
||||
$.get("./backend/lxd/remotes.php?host=" + encodeURI(hostName) +
|
||||
"&port=" + encodeURI(portNumber) +
|
||||
"&alias=" + encodeURI(aliasName) +
|
||||
"&external_host=" + encodeURI($("#externalHostInput").val()) +
|
||||
"&external_port=" + encodeURI($("#externalPortInput").val()) +
|
||||
"&action=addRemote", function (data) {
|
||||
operationData = JSON.parse(data);
|
||||
console.log(operationData);
|
||||
if (operationData.status_code >= 400){
|
||||
|
@ -457,9 +605,20 @@ function logout(){
|
|||
});
|
||||
}
|
||||
|
||||
function confirmDeleteRemote(remoteID){
|
||||
console.log("Info: confirming removal of remote host, id number " + remoteID);
|
||||
$.get("./backend/lxd/remotes.php?id=" + encodeURI(remoteID) + "&action=retrieveRemoteInfo", function (data) {
|
||||
operationData = JSON.parse(data);
|
||||
if (confirm("Are you sure you want to remove host " + operationData.host + "?") == true) {
|
||||
deleteRemote(remoteID);
|
||||
}
|
||||
reloadPageContent();
|
||||
});
|
||||
}
|
||||
|
||||
function deleteRemote(remoteID){
|
||||
console.log("Info: removing remote host, id number " + remoteID);
|
||||
$.get("./php/lxd/remotes.php?id=" + encodeURI(remoteID) + "&action=deleteRemote", function (data) {
|
||||
$.get("./backend/lxd/remotes.php?id=" + encodeURI(remoteID) + "&action=deleteRemote", function (data) {
|
||||
operationData = JSON.parse(data);
|
||||
console.log(operationData);
|
||||
if (operationData.status_code >= 400){
|
||||
|
@ -470,20 +629,79 @@ function logout(){
|
|||
}
|
||||
|
||||
function loadInstructionsModal(){
|
||||
$.get("./php/config/cert.php?action=viewCertificate", function (data) {
|
||||
$.get("./backend/config/cert.php?action=viewCertificate", function (data) {
|
||||
$("#instructionsClientCert").html(data);
|
||||
$("#instructionsModal").modal('show');
|
||||
});
|
||||
}
|
||||
|
||||
function editRemote(id){
|
||||
console.log("Info: loading edit host " + id);
|
||||
$.get("./backend/lxd/remotes.php?remote=" + encodeURI(id) + "&action=loadRemote", function (data) {
|
||||
operationData = JSON.parse(data);
|
||||
console.log(operationData);
|
||||
|
||||
// 0 is a valid interger value for the database but a reserved unusable port for TCP/UDP
|
||||
if (operationData.external_port == 0) { operationData.external_port = ""; };
|
||||
|
||||
$("#idEditInput").val(operationData.id);
|
||||
$("#hostEditInput").val(operationData.host);
|
||||
$("#portEditInput").val(operationData.port);
|
||||
$("#aliasEditInput").val(operationData.alias);
|
||||
$("#externalHostEditInput").val(operationData.external_host);
|
||||
$("#externalPortEditInput").val(operationData.external_port);
|
||||
$("#editLxdHost").modal('show');
|
||||
});
|
||||
}
|
||||
|
||||
function updateRemote(){
|
||||
id = $("#idEditInput").val();
|
||||
console.log("Info: updating host " + id);
|
||||
$.get("./backend/lxd/remotes.php?remote=" + encodeURI(id) +
|
||||
"&host=" + encodeURI($("#hostEditInput").val()) +
|
||||
"&port=" + encodeURI($("#portEditInput").val()) +
|
||||
"&alias=" + encodeURI($("#aliasEditInput").val()) +
|
||||
"&external_host=" + encodeURI($("#externalHostEditInput").val()) +
|
||||
"&external_port=" + encodeURI($("#externalPortEditInput").val()) +
|
||||
"&action=updateRemote", function (data) {
|
||||
operationData = JSON.parse(data);
|
||||
console.log(operationData);
|
||||
if (operationData.status_code >= 400){
|
||||
alert(operationData.metadata.error);
|
||||
}
|
||||
setTimeout(() => { reloadPageContent(); }, 1000);
|
||||
});
|
||||
}
|
||||
|
||||
function setSidebarToggleValue(){
|
||||
sidebarState = localStorage.getItem('sidebarState');
|
||||
if (sidebarState == "collapsed"){
|
||||
localStorage.setItem('sidebarState','expanded');
|
||||
}
|
||||
else {
|
||||
localStorage.setItem('sidebarState','collapsed');
|
||||
}
|
||||
}
|
||||
|
||||
function applySidebarToggleValue() {
|
||||
sidebarState = localStorage.getItem('sidebarState');
|
||||
if (sidebarState == "collapsed"){
|
||||
$("body").toggleClass("sidebar-toggled"),
|
||||
$(".sidebar").toggleClass("toggled"),
|
||||
$(".sidebar").hasClass("toggled") && $(".sidebar .collapse").collapse("hide")
|
||||
}
|
||||
}
|
||||
|
||||
applySidebarToggleValue();
|
||||
|
||||
$(document).ready(function(){
|
||||
|
||||
//Check Authorization
|
||||
$.get("./php/aaa/authentication.php?action=validateAuthentication", function (data) {
|
||||
$.get("./backend/aaa/authentication.php?action=validateAuthentication", function (data) {
|
||||
operationData = JSON.parse(data);
|
||||
if (operationData.status_code != 200) {
|
||||
console.log(operationData);
|
||||
window.location = './index.html'
|
||||
window.location.href = './index.php'
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -491,7 +709,7 @@ function logout(){
|
|||
loadPageContent();
|
||||
|
||||
//Load the about info for the about modal
|
||||
$.get("./about.html", function (data) {
|
||||
$.get("./backend/config/about.php", function (data) {
|
||||
$("#about").html(data);
|
||||
});
|
||||
|
|
@ -1,822 +0,0 @@
|
|||
<!--
|
||||
LXDWARE LXD Dashboard - A web-based interface for managing LXD servers
|
||||
Copyright (C) 2020-2021 LXDWARE.COM
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
-->
|
||||
|
||||
<!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, shrink-to-fit=no">
|
||||
<meta name="description" content="">
|
||||
<meta name="author" content="">
|
||||
|
||||
<link rel="icon" type="image/png" href="assets/images/logo-light.svg">
|
||||
|
||||
<title>LXD Dashboard</title>
|
||||
|
||||
<!-- Custom fonts for this template-->
|
||||
<link href="vendor/fontawesome-free/css/all.min.css" rel="stylesheet" type="text/css">
|
||||
<link href="vendor/fonts/nunito.css" rel="stylesheet">
|
||||
|
||||
<!-- Custom styles for this template-->
|
||||
<link href="vendor/sb-admin-2/css/sb-admin-2.css" rel="stylesheet">
|
||||
<link href="assets/css/style.css" rel="stylesheet">
|
||||
|
||||
<!-- Custom styles for this page -->
|
||||
<link href="vendor/datatables/dataTables.bootstrap4.min.css" rel="stylesheet">
|
||||
|
||||
</head>
|
||||
|
||||
<body id="page-top">
|
||||
|
||||
<!-- Page Wrapper -->
|
||||
<div id="wrapper">
|
||||
|
||||
<!-- Sidebar -->
|
||||
<ul class="navbar-nav bg-dark sidebar sidebar-dark accordion" id="accordionSidebar">
|
||||
|
||||
<!-- Sidebar - Brand -->
|
||||
<a class="sidebar-brand d-flex align-items-center justify-content-center" href="index.html">
|
||||
<div class="sidebar-brand-icon rotate-n-0">
|
||||
<img src="assets/images/logo-dark.svg" style="width: 2rem;"></img>
|
||||
<!-- <i class="fas fa-cube" style="width: 2rem;"></i> -->
|
||||
</div>
|
||||
<div class="sidebar-brand-text mx-3">LXDWARE</div>
|
||||
</a>
|
||||
|
||||
<!-- Divider -->
|
||||
<hr class="sidebar-divider">
|
||||
|
||||
<!-- Nav Item - Dashboard -->
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="remotes.html">
|
||||
<i class="fas fa-fw fa-server"></i>
|
||||
<span>Hosts</span></a>
|
||||
</li>
|
||||
|
||||
<!-- Divider -->
|
||||
<hr class="sidebar-divider d-none d-md-block">
|
||||
|
||||
<!-- Sidebar Toggler (Sidebar) -->
|
||||
<div class="text-center d-none d-md-inline">
|
||||
<button class="rounded-circle border-0" id="sidebarToggle"></button>
|
||||
</div>
|
||||
</ul>
|
||||
<!-- End of Sidebar -->
|
||||
|
||||
|
||||
<!-- Content Wrapper -->
|
||||
<div id="content-wrapper" class="d-flex flex-column">
|
||||
|
||||
<!-- Main Content -->
|
||||
<div id="content">
|
||||
|
||||
<!-- Topbar -->
|
||||
<nav class="navbar navbar-expand navbar-light bg-white topbar mb-4 static-top shadow">
|
||||
|
||||
<!-- Sidebar Toggle (Topbar) -->
|
||||
<button id="sidebarToggleTop" class="btn btn-link d-md-none rounded-circle mr-3">
|
||||
<i class="fa fa-bars"></i>
|
||||
</button>
|
||||
|
||||
<!-- Topbar Navbar -->
|
||||
<ul class="navbar-nav ml-auto">
|
||||
|
||||
<div class="topbar-divider d-none d-sm-block"></div>
|
||||
|
||||
<!-- Nav Item - User Information -->
|
||||
<li class="nav-item dropdown no-arrow">
|
||||
<a class="nav-link dropdown-toggle" href="#" id="userDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
<i class="fas fa-user-circle fa-1x fa-fw mr-2 text-gray-600"></i>
|
||||
<span id="username" class="mr-2 d-none d-lg-inline text-gray-600"></span>
|
||||
</a>
|
||||
<!-- Dropdown - User Information -->
|
||||
<div class="dropdown-menu dropdown-menu-right shadow animated--grow-in" aria-labelledby="userDropdown">
|
||||
<a class="dropdown-item" href="user-profile.html">
|
||||
<i class="fas fa-user fa-sm fa-fw mr-2 text-gray-400"></i>
|
||||
Profile
|
||||
</a>
|
||||
<a class="dropdown-item" href="settings.html">
|
||||
<i class="fas fa-cog fa-sm fa-fw mr-2 text-gray-400"></i>
|
||||
Settings
|
||||
</a>
|
||||
<a class="dropdown-item" href="#" data-toggle="modal" data-target="#aboutModal">
|
||||
<i class="fas fa-info-circle fa-sm fa-fw mr-2 text-gray-400"></i>
|
||||
About
|
||||
</a>
|
||||
<div class="dropdown-divider"></div>
|
||||
<a class="dropdown-item" href="#" onclick="logout()">
|
||||
<i class="fas fa-sign-out-alt fa-sm fa-fw mr-2 text-gray-400"></i>
|
||||
Logout
|
||||
</a>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
|
||||
</nav>
|
||||
<!-- End of Topbar -->
|
||||
|
||||
<!-- Begin Page Content -->
|
||||
<div class="container-fluid">
|
||||
|
||||
<!-- Page Heading -->
|
||||
<div class="d-sm-flex align-items-center justify-content-between">
|
||||
<h1 class="h5 mb-0 text-gray-800">SETTINGS</h1>
|
||||
</div>
|
||||
|
||||
<div class="col-12">
|
||||
|
||||
<div class="row">
|
||||
|
||||
<div class="col-2 border-right mt-5">
|
||||
<div class="nav flex-column nav-pills" id="v-pills-tab" role="tablist" aria-orientation="vertical">
|
||||
<a class="nav-link active" id="v-pills-users-tab" data-toggle="pill" href="#v-pills-users" role="tab" aria-controls="v-pills-users" aria-selected="false">Users</a>
|
||||
<a class="nav-link" id="v-pills-groups-tab" data-toggle="pill" href="#v-pills-groups" role="tab" aria-controls="v-pills-groups" aria-selected="false">Groups</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-10">
|
||||
<div class="tab-content" id="v-pills-tabContent">
|
||||
<div class="tab-pane fade show active" id="v-pills-users" role="tabpanel" aria-labelledby="v-pills-users-tab">
|
||||
<!-- Users List -->
|
||||
<div class="card border-light mb-4">
|
||||
<!-- Card Header - Dropdown -->
|
||||
<div class="card-header py-3 d-flex flex-row align-items-center justify-content-between">
|
||||
<h6 class="m-0 font-weight-bold text-primary">Users</h6>
|
||||
<div class="dropdown no-arrow">
|
||||
<a class="dropdown-toggle mr-2" href="#" data-toggle="modal" data-target="#createUserModal" title="New User" aria-hidden="true">
|
||||
<i class="fas fa-plus fa-sm fa-fw"></i> User</a>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Card Body -->
|
||||
<div class="card-body">
|
||||
<div class="table-responsive">
|
||||
<table class="table" id="userListTable" width="100%" cellspacing="0">
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- End Users List -->
|
||||
</div>
|
||||
<div class="tab-pane fade" id="v-pills-groups" role="tabpanel" aria-labelledby="v-pills-groups-tab">
|
||||
<!-- Groups List -->
|
||||
<div class="card border-light mb-4">
|
||||
<!-- Card Header - Dropdown -->
|
||||
<div class="card-header py-3 d-flex flex-row align-items-center justify-content-between">
|
||||
<h6 class="m-0 font-weight-bold text-primary">Groups</h6>
|
||||
<div class="dropdown no-arrow">
|
||||
<a class="dropdown-toggle mr-2" href="#" data-toggle="modal" data-target="#createGroupModal" title="New Group" aria-hidden="true">
|
||||
<i class="fas fa-plus fa-sm fa-fw"></i> Group</a>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Card Body -->
|
||||
<div class="card-body">
|
||||
<div class="table-responsive">
|
||||
<table class="table" id="groupListTable" width="100%" cellspacing="0">
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- End Groups List -->
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<!-- /.container-fluid -->
|
||||
|
||||
</div>
|
||||
<!-- End of Main Content -->
|
||||
|
||||
<!-- Footer -->
|
||||
<footer class="sticky-footer bg-white">
|
||||
<div class="container my-auto">
|
||||
<div class="copyright text-center my-auto">
|
||||
<span>Copyright © lxdware.com 2021</span>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
<!-- End of Footer -->
|
||||
|
||||
</div>
|
||||
<!-- End of Content Wrapper -->
|
||||
|
||||
</div>
|
||||
<!-- End of Page Wrapper -->
|
||||
|
||||
<!-- Scroll to Top Button-->
|
||||
<a class="scroll-to-top rounded" href="#page-top">
|
||||
<i class="fas fa-angle-up"></i>
|
||||
</a>
|
||||
|
||||
<!-- Add User Modal-->
|
||||
<div class="modal fade" id="createUserModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="exampleModalLabel">Create User</h5>
|
||||
<button class="close" type="button" data-dismiss="modal" aria-label="Close">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
|
||||
<div class="row">
|
||||
<label class="col-3 col-form-label text-right">Username: </label>
|
||||
<div class="col-7">
|
||||
<div class="form-group">
|
||||
<input type="text" id="usernameInput" class="form-control" required="required" placeholder="" name="usernameInput">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-1">
|
||||
<i class="far fa-sm fa-question-circle text-danger" title='(Required) - Enter in a username for the user.'></i>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<label class="col-3 col-form-label text-right">Password: </label>
|
||||
<div class="col-7">
|
||||
<div class="form-group">
|
||||
<input type="password" id="passwordInput" class="form-control" required="required" placeholder="" name="passwordInput">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-1">
|
||||
<i class="far fa-sm fa-question-circle text-danger" title='(Required) - Enter in a password for the user.'></i>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<label class="col-3 col-form-label text-right">First Name: </label>
|
||||
<div class="col-7">
|
||||
<div class="form-group">
|
||||
<input type="text" id="firstNameInput" class="form-control" placeholder="" name="firstNameInput">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-1">
|
||||
<i class="far fa-sm fa-question-circle" title='Enter in the firstname of the user.'></i>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<label class="col-3 col-form-label text-right">Last Name: </label>
|
||||
<div class="col-7">
|
||||
<div class="form-group">
|
||||
<input type="text" id="lastNameInput" class="form-control" placeholder="" name="lastNameInput">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-1">
|
||||
<i class="far fa-sm fa-question-circle" title='Enter in the lastname of the user.'></i>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<label class="col-3 col-form-label text-right">Email: </label>
|
||||
<div class="col-7">
|
||||
<div class="form-group">
|
||||
<input type="text" id="emailInput" class="form-control" required="required" placeholder="" name="emailInput">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-1">
|
||||
<i class="far fa-sm fa-question-circle" title='Enter in the email address of the user.'></i>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div> <!-- End Modal Body-->
|
||||
<div class="modal-footer">
|
||||
<button class="btn btn-secondary" type="button" data-dismiss="modal">Cancel</button>
|
||||
<a class="btn btn-primary" href="#" onclick="createUser()" data-dismiss="modal">Submit</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Add Group Modal-->
|
||||
<div class="modal fade" id="addGroupModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="exampleModalLabel">Add Group</h5>
|
||||
<button class="close" type="button" data-dismiss="modal" aria-label="Close">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
|
||||
<div class="row">
|
||||
<label class="col-3 col-form-label text-right">Group:</label>
|
||||
<div class="col-7 text-right">
|
||||
<div class="form-group">
|
||||
<select id="groupIdForAddGroupInput" class="form-control" name="groupIdForAddGroupInput">
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-1">
|
||||
<i class="far fa-sm fa-question-circle" title='Select the group to add.'></i>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<input type="hidden" id="userIdForAddGroupInput" name="userIdForAddGroupInput">
|
||||
|
||||
</div> <!-- End Modal Body-->
|
||||
<div class="modal-footer">
|
||||
<button class="btn btn-secondary" type="button" data-dismiss="modal">Cancel</button>
|
||||
<a class="btn btn-primary" href="#" onclick="addGroup()" data-dismiss="modal">Submit</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Remove Group Modal-->
|
||||
<div class="modal fade" id="removeGroupModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="exampleModalLabel">Remove Group</h5>
|
||||
<button class="close" type="button" data-dismiss="modal" aria-label="Close">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
|
||||
<div class="row">
|
||||
<label class="col-3 col-form-label text-right">Group:</label>
|
||||
<div class="col-7 text-right">
|
||||
<div class="form-group">
|
||||
<select id="groupIdForRemoveGroupInput" class="form-control" name="groupIdForRemoveGroupInput">
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-1">
|
||||
<i class="far fa-sm fa-question-circle" title='Select the group to remove.'></i>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<input type="hidden" id="userIdForRemoveGroupInput" name="userIdForRemoveGroupInput">
|
||||
|
||||
</div> <!-- End Modal Body-->
|
||||
<div class="modal-footer">
|
||||
<button class="btn btn-secondary" type="button" data-dismiss="modal">Cancel</button>
|
||||
<a class="btn btn-primary" href="#" onclick="removeGroup()" data-dismiss="modal">Submit</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Delete User Modal-->
|
||||
<div class="modal fade" id="deleteUserModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="exampleModalLabel">Delete User</h5>
|
||||
<button class="close" type="button" data-dismiss="modal" aria-label="Close">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="modal-body">Are you sure you want to delete this user?</div>
|
||||
<input type="hidden" id="userIdForDeleteUserInput" name="userIdForDeleteUserInput">
|
||||
<div class="modal-footer">
|
||||
<button class="btn btn-secondary" type="button" data-dismiss="modal">Cancel</button>
|
||||
<a class="btn btn-primary" href="#" onclick="deleteUser()" data-dismiss="modal">Yes</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Create Group Modal-->
|
||||
<div class="modal fade" id="createGroupModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="exampleModalLabel">Create Group</h5>
|
||||
<button class="close" type="button" data-dismiss="modal" aria-label="Close">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
|
||||
<div class="row">
|
||||
<label class="col-3 col-form-label text-right">Name: </label>
|
||||
<div class="col-7">
|
||||
<div class="form-group">
|
||||
<input type="text" id="nameInput" class="form-control" required="required" placeholder="" name="nameInput">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-1">
|
||||
<i class="far fa-sm fa-question-circle text-danger" title='(Required) - Enter in a name for the group.'></i>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<label class="col-3 col-form-label text-right">Description </label>
|
||||
<div class="col-7">
|
||||
<div class="form-group">
|
||||
<input type="text" id="descriptionInput" class="form-control" required="required" placeholder="" name="descriptionInput">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-1">
|
||||
<i class="far fa-sm fa-question-circle" title='Enter in a description for the group.'></i>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div> <!-- End Modal Body-->
|
||||
<div class="modal-footer">
|
||||
<button class="btn btn-secondary" type="button" data-dismiss="modal">Cancel</button>
|
||||
<a class="btn btn-primary" href="#" onclick="createGroup()" data-dismiss="modal">Submit</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Add Role Modal-->
|
||||
<div class="modal fade" id="addRoleModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="exampleModalLabel">Add Role</h5>
|
||||
<button class="close" type="button" data-dismiss="modal" aria-label="Close">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
|
||||
<div class="row">
|
||||
<label class="col-3 col-form-label text-right">Role:</label>
|
||||
<div class="col-7 text-right">
|
||||
<div class="form-group">
|
||||
<select id="roleIdForAddRoleInput" class="form-control" name="roleIdForAddRoleInput">
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-1">
|
||||
<i class="far fa-sm fa-question-circle" title='Select the role to add.'></i>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<input type="hidden" id="groupIdForAddRoleInput" name="groupIdForAddRoleInput">
|
||||
|
||||
</div> <!-- End Modal Body-->
|
||||
<div class="modal-footer">
|
||||
<button class="btn btn-secondary" type="button" data-dismiss="modal">Cancel</button>
|
||||
<a class="btn btn-primary" href="#" onclick="addRole()" data-dismiss="modal">Submit</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Remove Role Modal-->
|
||||
<div class="modal fade" id="removeRoleModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="exampleModalLabel">Remove Role</h5>
|
||||
<button class="close" type="button" data-dismiss="modal" aria-label="Close">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
|
||||
<div class="row">
|
||||
<label class="col-3 col-form-label text-right">Role:</label>
|
||||
<div class="col-7 text-right">
|
||||
<div class="form-group">
|
||||
<select id="roleIdForRemoveRoleInput" class="form-control" name="roleIdForRemoveRoleInput">
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-1">
|
||||
<i class="far fa-sm fa-question-circle" title='Select the role to remove.'></i>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<input type="hidden" id="groupIdForRemoveRoleInput" name="groupIdForRemoveRoleInput">
|
||||
|
||||
</div> <!-- End Modal Body-->
|
||||
<div class="modal-footer">
|
||||
<button class="btn btn-secondary" type="button" data-dismiss="modal">Cancel</button>
|
||||
<a class="btn btn-primary" href="#" onclick="removeRole()" data-dismiss="modal">Submit</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Delete Group Modal-->
|
||||
<div class="modal fade" id="deleteGroupModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="exampleModalLabel">Delete Group</h5>
|
||||
<button class="close" type="button" data-dismiss="modal" aria-label="Close">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="modal-body">Are you sure you want to delete this group?</div>
|
||||
<input type="hidden" id="groupIdForDeleteGroupInput" name="groupIdForDeleteGroupInput">
|
||||
<div class="modal-footer">
|
||||
<button class="btn btn-secondary" type="button" data-dismiss="modal">Cancel</button>
|
||||
<a class="btn btn-primary" href="#" onclick="deleteGroup()" data-dismiss="modal">Yes</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- About Modal-->
|
||||
<div class="modal fade" id="aboutModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="exampleModalLabel">About</h5>
|
||||
<button class="close" type="button" data-dismiss="modal" aria-label="Close">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<div id="about"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button class="btn btn-secondary" type="button" data-dismiss="modal">Dismiss</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Bootstrap core JavaScript-->
|
||||
<script src="vendor/jquery/jquery.min.js"></script>
|
||||
<script src="vendor/bootstrap/js/bootstrap.bundle.min.js"></script>
|
||||
|
||||
<!-- Core plugin JavaScript-->
|
||||
<script src="vendor/jquery-easing/jquery.easing.min.js"></script>
|
||||
|
||||
<!-- Custom scripts for all pages-->
|
||||
<script src="vendor/sb-admin-2/js/sb-admin-2.min.js"></script>
|
||||
|
||||
<!-- Page level plugins -->
|
||||
<script src="vendor/datatables/jquery.dataTables.min.js"></script>
|
||||
<script src="vendor/datatables/dataTables.bootstrap4.min.js"></script>
|
||||
|
||||
</body>
|
||||
|
||||
<script>
|
||||
|
||||
function logout(){
|
||||
$.get("./php/aaa/authentication.php?action=deauthenticateUser", function (data) {
|
||||
operationData = JSON.parse(data);
|
||||
console.log(operationData);
|
||||
if (operationData.status_code == 200) {
|
||||
window.location = './index.html'
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function reloadPageContent() {
|
||||
|
||||
//Check Authorization
|
||||
$.get("./php/aaa/authentication.php?action=validateAuthentication", function (data) {
|
||||
operationData = JSON.parse(data);
|
||||
if (operationData.status_code != 200) {
|
||||
console.log(operationData);
|
||||
window.location = './index.html'
|
||||
}
|
||||
});
|
||||
|
||||
$('#userListTable').DataTable().ajax.reload(null, false);
|
||||
$('#groupListTable').DataTable().ajax.reload(null, false);
|
||||
}
|
||||
|
||||
function loadPageContent(){
|
||||
|
||||
//Display current logged in username
|
||||
$("#username").load("./php/admin/settings.php?action=displayUsername");
|
||||
|
||||
$('#userListTable').DataTable( {
|
||||
ajax: "./php/admin/settings.php?action=listUsers",
|
||||
columns: [
|
||||
{},
|
||||
{ title: "Username" },
|
||||
{ title: "Email" },
|
||||
{ title: "Account Type" },
|
||||
{ title: "Groups" },
|
||||
{ title: "Action" }
|
||||
],
|
||||
order: [],
|
||||
columnDefs: [
|
||||
{ targets: 0, orderable: false, width: "25px" }
|
||||
]
|
||||
});
|
||||
|
||||
$('#groupListTable').DataTable( {
|
||||
ajax: "./php/admin/settings.php?action=listGroups",
|
||||
columns: [
|
||||
{},
|
||||
{ title: "Name" },
|
||||
{ title: "Description" },
|
||||
{ title: "Roles" },
|
||||
{ title: "Action" }
|
||||
],
|
||||
order: [],
|
||||
columnDefs: [
|
||||
{ targets: 0, orderable: false, width: "25px" }
|
||||
]
|
||||
});
|
||||
|
||||
//Set the page content to reload in 10 seconds
|
||||
setInterval(() => { reloadPageContent(); }, 10000);
|
||||
}
|
||||
|
||||
function createUser(){
|
||||
var usernameInput = $("#usernameInput").val();
|
||||
var passwordInput = $("#passwordInput").val();
|
||||
var firstNameInput = $("#firstNameInput").val();
|
||||
var lastNameInput = $("#lastNameInput").val();
|
||||
var emailInput = $("#emailInput").val();
|
||||
console.log("Info: creating user " + usernameInput);
|
||||
$.post('./php/admin/settings.php?action=createUser', {username: usernameInput, password: passwordInput, first_name: firstNameInput, last_name: lastNameInput, email: emailInput}, function (data) {
|
||||
var operationData = JSON.parse(data);
|
||||
console.log(operationData);
|
||||
if (operationData.status_code >= 400) {
|
||||
alert(operationData.metadata.error);
|
||||
}
|
||||
setTimeout(() => { reloadPageContent(); }, 1000)
|
||||
});
|
||||
}
|
||||
|
||||
function deleteUser(){
|
||||
var userIdForDeleteUserInput = $("#userIdForDeleteUserInput").val();
|
||||
console.log("Info: deleting user, id: " + userIdForDeleteUserInput);
|
||||
$.get("./php/admin/settings.php?id=" + encodeURI(userIdForDeleteUserInput) + "&action=deleteUser", function (data) {
|
||||
operationData = JSON.parse(data);
|
||||
console.log(operationData);
|
||||
if (operationData.status_code >= 400){
|
||||
alert(operationData.metadata.error);
|
||||
}
|
||||
setTimeout(() => { reloadPageContent(); }, 1000);
|
||||
});
|
||||
}
|
||||
|
||||
function addGroup(){
|
||||
var userIdForAddGroupInput = $("#userIdForAddGroupInput").val();
|
||||
var groupIdForAddGroupInput = $("#groupIdForAddGroupInput").val();
|
||||
console.log("Info: adding group to user");
|
||||
$.get("./php/admin/settings.php?id=" + encodeURI(userIdForAddGroupInput) + "&group_id=" + encodeURI(groupIdForAddGroupInput) + "&action=addUserToGroup", function (data) {
|
||||
operationData = JSON.parse(data);
|
||||
console.log(operationData);
|
||||
if (operationData.status_code >= 400){
|
||||
alert(operationData.metadata.error);
|
||||
}
|
||||
setTimeout(() => { reloadPageContent(); }, 1000);
|
||||
});
|
||||
}
|
||||
|
||||
function removeGroup(){
|
||||
var userIdForRemoveGroupInput = $("#userIdForRemoveGroupInput").val();
|
||||
var groupIdForRemoveGroupInput = $("#groupIdForRemoveGroupInput").val();
|
||||
console.log("Info: removing group from user");
|
||||
$.get("./php/admin/settings.php?id=" + encodeURI(userIdForRemoveGroupInput) + "&group_id=" + encodeURI(groupIdForRemoveGroupInput) + "&action=removeGroupFromUser", function (data) {
|
||||
operationData = JSON.parse(data);
|
||||
console.log(operationData);
|
||||
if (operationData.status_code >= 400){
|
||||
alert(operationData.metadata.error);
|
||||
}
|
||||
setTimeout(() => { reloadPageContent(); }, 1000);
|
||||
});
|
||||
}
|
||||
|
||||
function loadAddGroupModal(userId){
|
||||
$("#groupIdForAddGroupInput").load("./php/admin/settings.php?id=" + userId + "&action=listGroupsNotAssignedToUserForSelect");
|
||||
$("#userIdForAddGroupInput").val(userId);
|
||||
$("#addGroupModal").modal('show');
|
||||
}
|
||||
|
||||
function loadRemoveGroupModal(userId){
|
||||
$("#groupIdForRemoveGroupInput").load("./php/admin/settings.php?id=" + userId + "&action=listGroupsAssignedToUserForSelect");
|
||||
$("#userIdForRemoveGroupInput").val(userId);
|
||||
$("#removeGroupModal").modal('show');
|
||||
}
|
||||
|
||||
function loadDeleteUserModal(userId){
|
||||
$("#userIdForDeleteUserInput").val(userId);
|
||||
$("#deleteUserModal").modal('show');
|
||||
}
|
||||
|
||||
function createGroup(){
|
||||
var nameInput = $("#nameInput").val();
|
||||
var descriptionInput = $("#descriptionInput").val();
|
||||
console.log("Info: adding group " + nameInput);
|
||||
$.get("./php/admin/settings.php?name=" + encodeURI(nameInput) + "&description=" + encodeURI(descriptionInput) + "&action=createGroup", function (data) {
|
||||
operationData = JSON.parse(data);
|
||||
console.log(operationData);
|
||||
if (operationData.status_code >= 400){
|
||||
alert(operationData.metadata.error);
|
||||
}
|
||||
setTimeout(() => { reloadPageContent(); }, 1000);
|
||||
});
|
||||
}
|
||||
|
||||
function deleteGroup(){
|
||||
var groupIdForDeleteGroupInput = $("#groupIdForDeleteGroupInput").val();
|
||||
console.log("Info: deleting group, id " + groupIdForDeleteGroupInput);
|
||||
$.get("./php/admin/settings.php?id=" + encodeURI(groupIdForDeleteGroupInput) + "&action=deleteGroup", function (data) {
|
||||
operationData = JSON.parse(data);
|
||||
console.log(operationData);
|
||||
if (operationData.status_code >= 400){
|
||||
alert(operationData.metadata.error);
|
||||
}
|
||||
setTimeout(() => { reloadPageContent(); }, 1000);
|
||||
});
|
||||
}
|
||||
|
||||
function addRole(){
|
||||
var groupIdForAddRoleInput = $("#groupIdForAddRoleInput").val();
|
||||
var roleIdForAddRoleInput = $("#roleIdForAddRoleInput").val();
|
||||
console.log("Info: adding role to group");
|
||||
$.get("./php/admin/settings.php?id=" + encodeURI(groupIdForAddRoleInput) + "&role_id=" + encodeURI(roleIdForAddRoleInput) + "&action=addRoleToGroup", function (data) {
|
||||
operationData = JSON.parse(data);
|
||||
console.log(operationData);
|
||||
if (operationData.status_code >= 400){
|
||||
alert(operationData.metadata.error);
|
||||
}
|
||||
setTimeout(() => { reloadPageContent(); }, 1000);
|
||||
});
|
||||
}
|
||||
|
||||
function removeRole(){
|
||||
var groupIdForRemoveRoleInput = $("#groupIdForRemoveRoleInput").val();
|
||||
var roleIdForRemoveRoleInput = $("#roleIdForRemoveRoleInput").val();
|
||||
console.log("Info: removing role from group");
|
||||
$.get("./php/admin/settings.php?id=" + encodeURI(groupIdForRemoveRoleInput) + "&role_id=" + encodeURI(roleIdForRemoveRoleInput) + "&action=removeRoleFromGroup", function (data) {
|
||||
operationData = JSON.parse(data);
|
||||
console.log(operationData);
|
||||
if (operationData.status_code >= 400){
|
||||
alert(operationData.metadata.error);
|
||||
}
|
||||
setTimeout(() => { reloadPageContent(); }, 1000);
|
||||
});
|
||||
}
|
||||
|
||||
function loadAddRoleModal(groupId){
|
||||
$("#roleIdForAddRoleInput").load("./php/admin/settings.php?id=" + groupId + "&action=listRolesNotAssignedToGroupForSelect");
|
||||
$("#groupIdForAddRoleInput").val(groupId);
|
||||
$("#addRoleModal").modal('show');
|
||||
}
|
||||
|
||||
function loadRemoveRoleModal(groupId){
|
||||
$("#roleIdForRemoveRoleInput").load("./php/admin/settings.php?id=" + groupId + "&action=listRolesAssignedToGroupForSelect");
|
||||
$("#groupIdForRemoveRoleInput").val(groupId);
|
||||
$("#removeRoleModal").modal('show');
|
||||
}
|
||||
|
||||
function loadDeleteGroupModal(groupId){
|
||||
$("#groupIdForDeleteGroupInput").val(groupId);
|
||||
$("#deleteGroupModal").modal('show');
|
||||
}
|
||||
|
||||
$(document).ready(function(){
|
||||
|
||||
//Check Authorization
|
||||
$.get("./php/aaa/authentication.php?action=validateAuthentication", function (data) {
|
||||
operationData = JSON.parse(data);
|
||||
if (operationData.status_code != 200) {
|
||||
console.log(operationData);
|
||||
window.location = './index.html'
|
||||
}
|
||||
});
|
||||
|
||||
//Load the card contents
|
||||
loadPageContent();
|
||||
|
||||
//Load the about info for the about modal
|
||||
$.get("./about.html", function (data) {
|
||||
$("#about").html(data);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
</html>
|
1579
lxd-dashboard/settings.php
Normal file
|
@ -17,7 +17,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
-->
|
||||
|
||||
<!-- Sidebar - Brand -->
|
||||
<a class="sidebar-brand d-flex align-items-center justify-content-center" href="remotes.html">
|
||||
<a class="sidebar-brand d-flex align-items-center justify-content-center" href="remotes.php">
|
||||
<div class="sidebar-brand-icon rotate-n-0">
|
||||
<img src="assets/images/logo-dark.svg" style="width: 2rem;"></img>
|
||||
<!-- <i class="fas fa-cube" style="width: 2rem;"></i> -->
|
||||
|
@ -31,7 +31,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
<div id="hosts">
|
||||
<!-- Nav Item - Hosts -->
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="remotes.html">
|
||||
<a class="nav-link" href="remotes.php">
|
||||
<i class="fas fa-fw fa-server"></i>
|
||||
<span>Hosts</span></a>
|
||||
</li>
|
||||
|
@ -41,11 +41,18 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
<hr class="sidebar-divider">
|
||||
|
||||
<div id="main">
|
||||
<!-- Nav Item - Instances -->
|
||||
<!-- Nav Item - Containers -->
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" id="instancesLinkSidebar" href="#">
|
||||
<i id="instancesIcon" class="fas fa-fw fa-cube"></i>
|
||||
<span id="instancesSpan">Instances</span></a>
|
||||
<a class="nav-link" id="containersLinkSidebar" href="#">
|
||||
<i id="containersIcon" class="fas fa-fw fa-cube"></i>
|
||||
<span id="containersSpan">Containers</span></a>
|
||||
</li>
|
||||
|
||||
<!-- Nav Item - Containers -->
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" id="virtualMachinesLinkSidebar" href="#">
|
||||
<i id="virtualMachinesIcon" class="fas fa-fw fa-cube"></i>
|
||||
<span id="virtualMachinesSpan">Virtual Machines</span></a>
|
||||
</li>
|
||||
|
||||
<!-- Nav Item - Images -->
|
||||
|
@ -136,71 +143,77 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
|
||||
|
||||
<script>
|
||||
$("#instancesLinkSidebar").attr("href", "instances.html?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName));
|
||||
$("#imagesLinkSidebar").attr("href", "images.html?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName));
|
||||
$("#profilesLinkSidebar").attr("href", "profiles.html?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName));
|
||||
$("#networksLinkSidebar").attr("href", "networks.html?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName));
|
||||
$("#storagePoolsLinkSidebar").attr("href", "storage-pools.html?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName));
|
||||
$("#containersLinkSidebar").attr("href", "containers.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName));
|
||||
$("#virtualMachinesLinkSidebar").attr("href", "virtual-machines.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName));
|
||||
$("#imagesLinkSidebar").attr("href", "images.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName));
|
||||
$("#profilesLinkSidebar").attr("href", "profiles.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName));
|
||||
$("#networksLinkSidebar").attr("href", "networks.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName));
|
||||
$("#storagePoolsLinkSidebar").attr("href", "storage-pools.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName));
|
||||
|
||||
$("#clusterLinkSidebar").attr("href", "cluster-members.html?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName));
|
||||
$("#projectsLinkSidebar").attr("href", "projects.html?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName));
|
||||
$("#networkAclsLinkSidebar").attr("href", "network-acls.html?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName));
|
||||
$("#operationsLinkSidebar").attr("href", "operations.html?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName));
|
||||
$("#certificatesLinkSidebar").attr("href", "certificates.html?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName));
|
||||
$("#clusterLinkSidebar").attr("href", "cluster-members.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName));
|
||||
$("#projectsLinkSidebar").attr("href", "projects.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName));
|
||||
$("#networkAclsLinkSidebar").attr("href", "network-acls.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName));
|
||||
$("#operationsLinkSidebar").attr("href", "operations.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName));
|
||||
$("#certificatesLinkSidebar").attr("href", "certificates.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName));
|
||||
|
||||
$("#simplestreamsLinkSidebar").attr("href", "simplestreams.html?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName));
|
||||
$("#simplestreamsLinkSidebar").attr("href", "simplestreams.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName));
|
||||
|
||||
if (location.pathname == "/instances.html" || location.pathname == "/instance.html"){
|
||||
$('#instancesSpan').css('color','#fff');
|
||||
$('#instancesIcon').css('color','#fff');
|
||||
if (location.pathname == "/containers.php" || location.pathname == "/containers-single.php"){
|
||||
$('#containersSpan').css('color','#fff');
|
||||
$('#containersIcon').css('color','#fff');
|
||||
}
|
||||
|
||||
if (location.pathname == "/images.html"){
|
||||
if (location.pathname == "/virtual-machines.php" || location.pathname == "/virtual-machines-single.php"){
|
||||
$('#virtualMachinesSpan').css('color','#fff');
|
||||
$('#virtualMachinesIcon').css('color','#fff');
|
||||
}
|
||||
|
||||
if (location.pathname == "/images.php"){
|
||||
$('#imagesSpan').css('color','#fff');
|
||||
$('#imagesIcon').css('color','#fff');
|
||||
}
|
||||
|
||||
if (location.pathname == "/profiles.html"){
|
||||
if (location.pathname == "/profiles.php"){
|
||||
$('#profilesSpan').css('color','#fff');
|
||||
$('#profilesIcon').css('color','#fff');
|
||||
}
|
||||
|
||||
if (location.pathname == "/networks.html"){
|
||||
if (location.pathname == "/networks.php"){
|
||||
$('#networksSpan').css('color','#fff');
|
||||
$('#networksIcon').css('color','#fff');
|
||||
}
|
||||
|
||||
if (location.pathname == "/storage-pools.html" || location.pathname == "/storage-volumes.html"){
|
||||
if (location.pathname == "/storage-pools.php" || location.pathname == "/storage-volumes.php"){
|
||||
$('#storagePoolsSpan').css('color','#fff');
|
||||
$('#storagePoolsIcon').css('color','#fff');
|
||||
}
|
||||
|
||||
if (location.pathname == "/cluster-members.html"){
|
||||
if (location.pathname == "/cluster-members.php"){
|
||||
$('#cluterSpan').css('color','#fff');
|
||||
$('#clusterIcon').css('color','#fff');
|
||||
}
|
||||
|
||||
if (location.pathname == "/projects.html"){
|
||||
if (location.pathname == "/projects.php"){
|
||||
$('#projectsSpan').css('color','#fff');
|
||||
$('#projectsIcon').css('color','#fff');
|
||||
}
|
||||
|
||||
if (location.pathname == "/network-acls.html" || location.pathname == "/network-acls-egress.html" || location.pathname == "/network-acls-ingress.html"){
|
||||
if (location.pathname == "/network-acls.php" || location.pathname == "/network-acls-egress.php" || location.pathname == "/network-acls-ingress.php"){
|
||||
$('#networkAclsSpan').css('color','#fff');
|
||||
$('#networkAclsIcon').css('color','#fff');
|
||||
}
|
||||
|
||||
if (location.pathname == "/operations.html"){
|
||||
if (location.pathname == "/operations.php"){
|
||||
$('#operationsSpan').css('color','#fff');
|
||||
$('#operationsIcon').css('color','#fff');
|
||||
}
|
||||
|
||||
if (location.pathname == "/certificates.html"){
|
||||
if (location.pathname == "/certificates.php"){
|
||||
$('#certificatesSpan').css('color','#fff');
|
||||
$('#certificatesIcon').css('color','#fff');
|
||||
}
|
||||
|
||||
if (location.pathname == "/simplestreams.html"){
|
||||
if (location.pathname == "/simplestreams.php"){
|
||||
$('#simplestreamsSpan').css('color','#fff');
|
||||
$('#simplestreamsIcon').css('color','#fff');
|
||||
}
|
|
@ -37,7 +37,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
|
||||
<!-- Custom styles for this template-->
|
||||
<link href="vendor/sb-admin-2/css/sb-admin-2.css" rel="stylesheet">
|
||||
<link href="assets/css/style.css" rel="stylesheet">
|
||||
<link href="assets/css/style.css?version=3.0" rel="stylesheet">
|
||||
|
||||
<!-- Custom styles for this page -->
|
||||
<link href="vendor/datatables/dataTables.bootstrap4.min.css" rel="stylesheet">
|
||||
|
@ -50,7 +50,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
<div id="wrapper">
|
||||
|
||||
<!-- Sidebar -->
|
||||
<ul class="navbar-nav bg-dark sidebar sidebar-dark accordion" id="accordionSidebar">
|
||||
<ul class="navbar-nav bg-dark sidebar sidebar-dark accordion sidebar-divider-right" id="accordionSidebar">
|
||||
|
||||
<div id="sidebarLinks"></div>
|
||||
|
||||
|
@ -59,12 +59,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
|
||||
<!-- Sidebar Toggler (Sidebar) -->
|
||||
<div class="text-center d-none d-md-inline">
|
||||
<button class="rounded-circle border-0" id="sidebarToggle"></button>
|
||||
<button class="rounded-circle border-0" id="sidebarToggle" onclick="setSidebarToggleValue()"></button>
|
||||
</div>
|
||||
</ul>
|
||||
<!-- End of Sidebar -->
|
||||
|
||||
|
||||
<!-- Content Wrapper -->
|
||||
<div id="content-wrapper" class="d-flex flex-column">
|
||||
|
||||
|
@ -79,36 +78,43 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
<i class="fa fa-bars"></i>
|
||||
</button>
|
||||
|
||||
|
||||
<!-- Topbar Notification -->
|
||||
<div class="d-none d-sm-inline-block form-inline mr-auto ml-md-3 my-2 my-md-0 mw-100 navbar-search">
|
||||
<ul class="navbar-nav ml-auto">
|
||||
|
||||
<li>
|
||||
<div class="nav-item spinner-border m-3" role="status" style="display:none;" id="spinner">
|
||||
<span class="nav-item sr-only">Loading...</span>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li class="nav-item dropdown no-arrow" id="notificationArea" style="display: none;">
|
||||
<div class="nav-link dropdown-toggle">
|
||||
<span id="notification" class="mr-2 d-none d-lg-inline text-gray-600">Notification</span>
|
||||
<span id="notification" class="mr-2 d-none d-lg-inline text-danger">Notification</span>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- Topbar Navbar -->
|
||||
<ul class="navbar-nav ml-auto">
|
||||
|
||||
<li class="nav-item dropdown" id="remoteListNav">
|
||||
<li class="nav-item dropdown">
|
||||
<label class="h6 mt-4 mr-2 ml-4">Host: </label>
|
||||
</li>
|
||||
<li class="nav-item dropdown">
|
||||
<div class="input-group mt-3">
|
||||
<select class="form-control" id="remoteListNav" style="width:150px;" onchange="location = this.value;">
|
||||
</select>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li class="nav-item dropdown" id="projectListNav">
|
||||
<li class="nav-item dropdown">
|
||||
<label class="h6 mt-4 mr-2 ml-4">Project: </label>
|
||||
</li>
|
||||
<li class="nav-item dropdown">
|
||||
<div class="input-group mt-3">
|
||||
<select class="form-control" id="projectListNav" style="width:150px;" onchange="location = this.value;">
|
||||
</select>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<!-- Nav Divider -->
|
||||
<div class="topbar-divider d-none d-sm-block"></div>
|
||||
|
||||
<!-- Nav Item - User Information -->
|
||||
|
@ -119,14 +125,18 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
</a>
|
||||
<!-- Dropdown - User Information -->
|
||||
<div class="dropdown-menu dropdown-menu-right shadow animated--grow-in" aria-labelledby="userDropdown">
|
||||
<a class="dropdown-item" href="user-profile.html">
|
||||
<a class="dropdown-item" href="user-profile.php">
|
||||
<i class="fas fa-user fa-sm fa-fw mr-2 text-gray-400"></i>
|
||||
Profile
|
||||
</a>
|
||||
<a class="dropdown-item" href="settings.html">
|
||||
<a class="dropdown-item" href="settings.php">
|
||||
<i class="fas fa-cog fa-sm fa-fw mr-2 text-gray-400"></i>
|
||||
Settings
|
||||
</a>
|
||||
<a class="dropdown-item" href="logs.php">
|
||||
<i class="fas fa-history fa-sm fa-fw mr-2 text-gray-400"></i>
|
||||
Logs
|
||||
</a>
|
||||
<a class="dropdown-item" href="#" data-toggle="modal" data-target="#aboutModal">
|
||||
<i class="fas fa-info-circle fa-sm fa-fw mr-2 text-gray-400"></i>
|
||||
About
|
||||
|
@ -147,25 +157,48 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
<!-- Begin Page Content -->
|
||||
<div class="container-fluid">
|
||||
|
||||
<!-- BreadCrumb -->
|
||||
<nav aria-label="breadcrumb">
|
||||
<ol class="breadcrumb">
|
||||
<li class="breadcrumb-item"><a href="#" id="remoteBreadCrumb"></a></li>
|
||||
<li class="breadcrumb-item active" aria-current="page" id="simplestreamsBreadCrumb"></li>
|
||||
</ol>
|
||||
</nav>
|
||||
<header class="page-header page-header-dark bg-gradient-primary-to-secondary">
|
||||
<div class="container-xl px-4">
|
||||
<div class="page-header-content pt-4">
|
||||
<div class="row align-items-center justify-content-between mt-n5 ml-n5 mr-n5 bg-dark pb-6">
|
||||
<div class="col-auto mt-4 ml-3">
|
||||
<div class="page-header-subtitle">
|
||||
<a href="#" id="remoteBreadCrumb"></a>
|
||||
</div>
|
||||
<h2 class="page-header-title mt-2">
|
||||
SIMPLESTREAMS
|
||||
</h2>
|
||||
<div class="page-header-subtitle">
|
||||
Add and manage simplestreams image repositories
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-xl-auto mt-4">
|
||||
<div class="input-group input-group-joined border-0" style="width: 14rem">
|
||||
<span class="input-group-text bg-transparent border-0">
|
||||
<a class="btn btn-outline-primary" href="#" data-toggle="modal" data-target="#addSimplestreamsModal" title="New Simplestreams Host" aria-hidden="true">
|
||||
<i class="fas fa-plus fa-sm fa-fw"></i> Simplestreams Host
|
||||
</a>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<div class="row">
|
||||
<div class="row mt-n5 ml-2 mr-2">
|
||||
|
||||
<div class="col-12">
|
||||
<div class="col-12 mt-n3">
|
||||
<!-- Simplestreams List -->
|
||||
<div class="card shadow mb-4">
|
||||
<!-- Card Header - Dropdown -->
|
||||
<div class="card-header py-3 d-flex flex-row align-items-center justify-content-between">
|
||||
<h6 class="m-0 font-weight-bold text-primary">Simplestreams</h6>
|
||||
<h6 class="m-0 font-weight-bold">
|
||||
<span class="ml-1">Simplestreams</span>
|
||||
</h6>
|
||||
<div class="dropdown no-arrow">
|
||||
<a class="dropdown-toggle mr-2" href="#" data-toggle="modal" data-target="#addSimplestreamsModal" title="New Simplestreams Host" aria-hidden="true">
|
||||
<i class="fas fa-plus fa-sm fa-fw"></i> Simplestreams Host</a>
|
||||
<a class="dropdown-toggle mr-2" href="#" onclick="reloadPageContent()" title="Refresh" aria-hidden="true">
|
||||
<i class="fa fa-sync fa-1x fa-fw"></i></a>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Card Body -->
|
||||
|
@ -191,7 +224,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
<footer class="sticky-footer bg-white">
|
||||
<div class="container my-auto">
|
||||
<div class="copyright text-center my-auto">
|
||||
<span>Copyright © lxdware.com 2021</span>
|
||||
<span>Copyright © LXDWARE 2020 - Present</span>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
|
@ -221,14 +254,14 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
<div class="modal-body">
|
||||
|
||||
<div class="row">
|
||||
<label class="col-3 col-form-label text-right">URL: </label>
|
||||
<label class="col-3 col-form-label text-right">URL: <span class="text-danger">*</span></label>
|
||||
<div class="col-7">
|
||||
<div class="form-group">
|
||||
<input type="text" class="form-control" id="hostInput" required="required" placeholder="" name="host">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-1">
|
||||
<i class="far fa-sm fa-question-circle text-danger" title='(Required) - Enter in the URL of the simplestreams server. For example, https://images.linuxcontainers.org'></i>
|
||||
<i class="far fa-sm fa-question-circle" title='(Required) - Enter in the URL of the simplestreams server. For example, https://images.linuxcontainers.org'></i>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -298,61 +331,66 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
const urlParams = new URLSearchParams(queryString);
|
||||
const remoteId = urlParams.get('remote');
|
||||
const projectName = urlParams.get('project');
|
||||
var reloadTime = 5000;
|
||||
|
||||
function logout(){
|
||||
$.get("./php/aaa/authentication.php?action=deauthenticateUser", function (data) {
|
||||
$.get("./backend/aaa/authentication.php?action=deauthenticateUser", function (data) {
|
||||
operationData = JSON.parse(data);
|
||||
console.log(operationData);
|
||||
if (operationData.status_code == 200) {
|
||||
window.location = './index.html'
|
||||
window.location.href = './index.php'
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function operationStatusCheck(){
|
||||
clearTimeout(operationTimeout);
|
||||
//check to see if there are any running operations
|
||||
$.get("./php/lxd/operations.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&action=displayOperationStatus", function (data) {
|
||||
$.get("./backend/lxd/operations.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&action=displayOperationStatus", function (data) {
|
||||
//Check to see if we have running operations
|
||||
if (data){
|
||||
//Display spinner and notification area if there are running tasks
|
||||
$('#spinner').show();
|
||||
if (data) {
|
||||
//Display notification area if there are running tasks
|
||||
$('#notificationArea').show();
|
||||
$('#notification').text(data);
|
||||
//Set the page to check operations again in 1 second
|
||||
setTimeout(() => { operationStatusCheck(); }, 1000);
|
||||
$('#notification').text("Notice: " + data);
|
||||
//Set the page to check operations again in 2 seconds
|
||||
operationTimeout = setTimeout(() => { operationStatusCheck(); }, 2000);
|
||||
}
|
||||
else {
|
||||
//Hide spinner and notification area if no running tasks
|
||||
$('#spinner').hide();
|
||||
//Hide notification area if no running tasks
|
||||
$('#notificationArea').hide();
|
||||
$('#notification').text("");
|
||||
//Set the page to check operations again in 3 seconds
|
||||
setTimeout(() => { operationStatusCheck(); }, 3000);
|
||||
//Set the page to check operations again in 4 seconds
|
||||
operationTimeout = setTimeout(() => { operationStatusCheck(); }, 4000);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function reloadPageContent() {
|
||||
|
||||
clearTimeout(pageReloadTimeout);
|
||||
|
||||
//Check Authorization
|
||||
$.get("./php/aaa/authentication.php?action=validateAuthentication", function (data) {
|
||||
$.get("./backend/aaa/authentication.php?action=validateAuthentication", function (data) {
|
||||
operationData = JSON.parse(data);
|
||||
if (operationData.status_code != 200) {
|
||||
console.log(operationData);
|
||||
window.location = './index.html'
|
||||
window.location.href = './index.php'
|
||||
}
|
||||
});
|
||||
|
||||
$('#simplestreamsListTable').DataTable().ajax.reload(null, false);
|
||||
|
||||
//Set reload page content
|
||||
pageReloadTimeout = setTimeout(() => { reloadPageContent(); }, reloadTime);
|
||||
}
|
||||
|
||||
function loadPageContent(){
|
||||
|
||||
//Display current logged in username
|
||||
$("#username").load("./php/admin/settings.php?action=displayUsername");
|
||||
$("#username").load("./backend/admin/settings.php?action=displayUsername");
|
||||
|
||||
$('#simplestreamsListTable').DataTable( {
|
||||
ajax: "./php/lxd/simplestreams.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&action=listSimplestreams",
|
||||
ajax: "./backend/lxd/simplestreams.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&action=listSimplestreams",
|
||||
columns: [
|
||||
{},
|
||||
{ title: "Host" },
|
||||
|
@ -367,17 +405,23 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
});
|
||||
|
||||
//Check for any running operations
|
||||
operationStatusCheck();
|
||||
operationTimeout = setTimeout(() => { operationStatusCheck(); }, 1000);
|
||||
|
||||
//Set reload page content
|
||||
$.get("./backend/admin/settings.php?action=retrievePageRefreshRateValues", function (data) {
|
||||
operationData = JSON.parse(data);
|
||||
if (operationData.simplestreams_page_rate >= 1)
|
||||
reloadTime = operationData.simplestreams_page_rate * 1000;
|
||||
pageReloadTimeout = setTimeout(() => { reloadPageContent(); }, reloadTime);
|
||||
});
|
||||
|
||||
//Set the page content to reload in 5 seconds
|
||||
setInterval(() => { reloadPageContent(); }, 5000);
|
||||
}
|
||||
|
||||
function addSimplestreams(){
|
||||
var hostName = $("#hostInput").val();
|
||||
var aliasName = $("#aliasInput").val();
|
||||
console.log("Info: adding simplestreams host " + hostName);
|
||||
$.get("./php/lxd/simplestreams.php?host=" + encodeURI(hostName) + "&alias=" + encodeURI(aliasName) + "&action=addSimplestreams", function (data) {
|
||||
$.get("./backend/lxd/simplestreams.php?host=" + encodeURI(hostName) + "&alias=" + encodeURI(aliasName) + "&action=addSimplestreams", function (data) {
|
||||
operationData = JSON.parse(data);
|
||||
console.log(operationData);
|
||||
if (operationData.status_code >= 400){
|
||||
|
@ -389,7 +433,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
|
||||
function deleteSimplestreams(simplestreamsID){
|
||||
console.log("Info: removing simplesteams host, id " + simplestreamsID);
|
||||
$.get("./php/lxd/simplestreams.php?id=" + encodeURI(simplestreamsID) + "&action=deleteSimplestreams", function (data) {
|
||||
$.get("./backend/lxd/simplestreams.php?id=" + encodeURI(simplestreamsID) + "&action=deleteSimplestreams", function (data) {
|
||||
operationData = JSON.parse(data);
|
||||
console.log(operationData);
|
||||
if (operationData.status_code >= 400){
|
||||
|
@ -399,34 +443,64 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
});
|
||||
}
|
||||
|
||||
function setSidebarToggleValue(){
|
||||
sidebarState = localStorage.getItem('sidebarState');
|
||||
if (sidebarState == "collapsed"){
|
||||
localStorage.setItem('sidebarState','expanded');
|
||||
}
|
||||
else {
|
||||
localStorage.setItem('sidebarState','collapsed');
|
||||
}
|
||||
}
|
||||
|
||||
function applySidebarToggleValue() {
|
||||
sidebarState = localStorage.getItem('sidebarState');
|
||||
if (sidebarState == "collapsed"){
|
||||
$("body").toggleClass("sidebar-toggled"),
|
||||
$(".sidebar").toggleClass("toggled"),
|
||||
$(".sidebar").hasClass("toggled") && $(".sidebar .collapse").collapse("hide")
|
||||
}
|
||||
}
|
||||
|
||||
applySidebarToggleValue();
|
||||
|
||||
$(document).ready(function(){
|
||||
|
||||
//Check Authorization
|
||||
$.get("./php/aaa/authentication.php?action=validateAuthentication", function (data) {
|
||||
$.get("./backend/aaa/authentication.php?action=validateAuthentication", function (data) {
|
||||
operationData = JSON.parse(data);
|
||||
if (operationData.status_code != 200) {
|
||||
console.log(operationData);
|
||||
window.location = './index.html'
|
||||
window.location.href = './index.php'
|
||||
}
|
||||
});
|
||||
|
||||
//Load in the sidebar
|
||||
$("#sidebarLinks").load("./sidebar.html");
|
||||
$("#sidebarLinks").load("./sidebar.php?version=3.0");
|
||||
|
||||
//Setup Page Breadcrumb Links/Information
|
||||
$('#remoteBreadCrumb').load("./php/lxd/remote-breadcrumb.php?remote=" + encodeURI(remoteId));
|
||||
$('#remoteBreadCrumb').attr("href", "remotes-single.html?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName));
|
||||
$('#simplestreamsBreadCrumb').text("simplestreams");
|
||||
$('#remoteBreadCrumb').load("./backend/lxd/remote-breadcrumb.php?remote=" + encodeURI(remoteId));
|
||||
$('#remoteBreadCrumb').attr("href", "remotes-single.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName));
|
||||
|
||||
//Load the card contents
|
||||
loadPageContent();
|
||||
//Validate remote host connection returns 200 status
|
||||
$.get("./backend/lxd/remotes-single.php?remote=" + encodeURI(remoteId) + "&action=validateRemoteConnection", function (data) {
|
||||
operationData = JSON.parse(data);
|
||||
console.log(operationData);
|
||||
if (operationData.status_code == 200) {
|
||||
//Set top navbar dropdowns
|
||||
$("#remoteListNav").load("./backend/lxd/remotes.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&action=listRemotesForSelectOption");
|
||||
$("#projectListNav").load("./backend/lxd/projects.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&action=listProjectsForSelectOption");
|
||||
|
||||
$("#remoteListNav").load("./php/lxd/remotes.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&action=listRemotesForTopNavigation");
|
||||
$("#projectListNav").load("./php/lxd/projects.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&action=listProjectsForTopNavigation");
|
||||
//Load Page Content
|
||||
loadPageContent();
|
||||
}
|
||||
else {
|
||||
alert("Unable to connect to remote host. HTTP status code: " + operationData.status_code);
|
||||
}
|
||||
});
|
||||
|
||||
//Load the about info for the about modal
|
||||
$.get("./about.html", function (data) {
|
||||
$.get("./backend/config/about.php", function (data) {
|
||||
$("#about").html(data);
|
||||
});
|
||||
|
|
@ -37,7 +37,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
|
||||
<!-- Custom styles for this template-->
|
||||
<link href="vendor/sb-admin-2/css/sb-admin-2.css" rel="stylesheet">
|
||||
<link href="assets/css/style.css" rel="stylesheet">
|
||||
<link href="assets/css/style.css?version=3.0" rel="stylesheet">
|
||||
|
||||
<!-- Custom styles for this page -->
|
||||
<link href="vendor/datatables/dataTables.bootstrap4.min.css" rel="stylesheet">
|
||||
|
@ -50,7 +50,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
<div id="wrapper">
|
||||
|
||||
<!-- Sidebar -->
|
||||
<ul class="navbar-nav bg-dark sidebar sidebar-dark accordion" id="accordionSidebar">
|
||||
<ul class="navbar-nav bg-dark sidebar sidebar-dark accordion sidebar-divider-right" id="accordionSidebar">
|
||||
|
||||
<div id="sidebarLinks"></div>
|
||||
|
||||
|
@ -59,12 +59,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
|
||||
<!-- Sidebar Toggler (Sidebar) -->
|
||||
<div class="text-center d-none d-md-inline">
|
||||
<button class="rounded-circle border-0" id="sidebarToggle"></button>
|
||||
<button class="rounded-circle border-0" id="sidebarToggle" onclick="setSidebarToggleValue()"></button>
|
||||
</div>
|
||||
</ul>
|
||||
<!-- End of Sidebar -->
|
||||
|
||||
|
||||
<!-- Content Wrapper -->
|
||||
<div id="content-wrapper" class="d-flex flex-column">
|
||||
|
||||
|
@ -79,36 +78,43 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
<i class="fa fa-bars"></i>
|
||||
</button>
|
||||
|
||||
|
||||
<!-- Topbar Notification -->
|
||||
<div class="d-none d-sm-inline-block form-inline mr-auto ml-md-3 my-2 my-md-0 mw-100 navbar-search">
|
||||
<ul class="navbar-nav ml-auto">
|
||||
|
||||
<li>
|
||||
<div class="nav-item spinner-border m-3" role="status" style="display:none;" id="spinner">
|
||||
<span class="nav-item sr-only">Loading...</span>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li class="nav-item dropdown no-arrow" id="notificationArea" style="display: none;">
|
||||
<div class="nav-link dropdown-toggle">
|
||||
<span id="notification" class="mr-2 d-none d-lg-inline text-gray-600">Notification</span>
|
||||
<span id="notification" class="mr-2 d-none d-lg-inline text-danger">Notification</span>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- Topbar Navbar -->
|
||||
<ul class="navbar-nav ml-auto">
|
||||
|
||||
<li class="nav-item dropdown" id="remoteListNav">
|
||||
<li class="nav-item dropdown">
|
||||
<label class="h6 mt-4 mr-2 ml-4">Host: </label>
|
||||
</li>
|
||||
<li class="nav-item dropdown">
|
||||
<div class="input-group mt-3">
|
||||
<select class="form-control" id="remoteListNav" style="width:150px;" onchange="location = this.value;">
|
||||
</select>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li class="nav-item dropdown" id="projectListNav">
|
||||
<li class="nav-item dropdown">
|
||||
<label class="h6 mt-4 mr-2 ml-4">Project: </label>
|
||||
</li>
|
||||
<li class="nav-item dropdown">
|
||||
<div class="input-group mt-3">
|
||||
<select class="form-control" id="projectListNav" style="width:150px;" onchange="location = this.value;">
|
||||
</select>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<!-- Nav Divider -->
|
||||
<div class="topbar-divider d-none d-sm-block"></div>
|
||||
|
||||
<!-- Nav Item - User Information -->
|
||||
|
@ -119,14 +125,18 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
</a>
|
||||
<!-- Dropdown - User Information -->
|
||||
<div class="dropdown-menu dropdown-menu-right shadow animated--grow-in" aria-labelledby="userDropdown">
|
||||
<a class="dropdown-item" href="user-profile.html">
|
||||
<a class="dropdown-item" href="user-profile.php">
|
||||
<i class="fas fa-user fa-sm fa-fw mr-2 text-gray-400"></i>
|
||||
Profile
|
||||
</a>
|
||||
<a class="dropdown-item" href="settings.html">
|
||||
<a class="dropdown-item" href="settings.php">
|
||||
<i class="fas fa-cog fa-sm fa-fw mr-2 text-gray-400"></i>
|
||||
Settings
|
||||
</a>
|
||||
<a class="dropdown-item" href="logs.php">
|
||||
<i class="fas fa-history fa-sm fa-fw mr-2 text-gray-400"></i>
|
||||
Logs
|
||||
</a>
|
||||
<a class="dropdown-item" href="#" data-toggle="modal" data-target="#aboutModal">
|
||||
<i class="fas fa-info-circle fa-sm fa-fw mr-2 text-gray-400"></i>
|
||||
About
|
||||
|
@ -147,25 +157,48 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
<!-- Begin Page Content -->
|
||||
<div class="container-fluid">
|
||||
|
||||
<!-- BreadCrumb -->
|
||||
<nav aria-label="breadcrumb">
|
||||
<ol class="breadcrumb">
|
||||
<li class="breadcrumb-item"><a href="#" id="remoteBreadCrumb"></a></li>
|
||||
<li class="breadcrumb-item active" aria-current="page" id="storagePoolsBreadCrumb"></li>
|
||||
</ol>
|
||||
</nav>
|
||||
<header class="page-header page-header-dark bg-gradient-primary-to-secondary">
|
||||
<div class="container-xl px-4">
|
||||
<div class="page-header-content pt-4">
|
||||
<div class="row align-items-center justify-content-between mt-n5 ml-n5 mr-n5 bg-dark pb-6">
|
||||
<div class="col-auto mt-4 ml-3">
|
||||
<div class="page-header-subtitle">
|
||||
<a href="#" id="remoteBreadCrumb"></a>
|
||||
</div>
|
||||
<h2 class="page-header-title mt-2">
|
||||
STORAGE POOLS
|
||||
</h2>
|
||||
<div class="page-header-subtitle">
|
||||
Create and manage LXD storage pools
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-xl-auto mt-4">
|
||||
<div class="input-group input-group-joined border-0" style="width: 14rem">
|
||||
<span class="input-group-text bg-transparent border-0">
|
||||
<a class="btn btn-outline-primary" href="#" onclick="loadCreateStoragePoolModal()" title="New Storage Pool" aria-hidden="true">
|
||||
<i class="fas fa-plus fa-sm fa-fw"></i> Storge Pool
|
||||
</a>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<div class="row">
|
||||
<div class="row mt-n5 ml-2 mr-2">
|
||||
|
||||
<div class="col-12">
|
||||
<div class="col-12 mt-n3">
|
||||
<!-- Storage Pool List -->
|
||||
<div class="card shadow mb-4">
|
||||
<!-- Card Header - Dropdown -->
|
||||
<div class="card-header py-3 d-flex flex-row align-items-center justify-content-between">
|
||||
<h6 class="m-0 font-weight-bold text-primary">Storage Pools</h6>
|
||||
<h6 class="m-0 font-weight-bold">
|
||||
<span class="ml-1">Storage Pools</span>
|
||||
</h6>
|
||||
<div class="dropdown no-arrow">
|
||||
<a class="dropdown-toggle mr-2" href="#" onclick="loadCreateStoragePoolModal()" title="New Storage Pool" aria-hidden="true">
|
||||
<i class="fas fa-plus fa-sm fa-fw"></i> Storage Pool</a>
|
||||
<a class="dropdown-toggle mr-2" href="#" onclick="reloadPageContent()" title="Refresh" aria-hidden="true">
|
||||
<i class="fa fa-sync fa-1x fa-fw"></i></a>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Card Body -->
|
||||
|
@ -191,7 +224,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
<footer class="sticky-footer bg-white">
|
||||
<div class="container my-auto">
|
||||
<div class="copyright text-center my-auto">
|
||||
<span>Copyright © lxdware.com 2021</span>
|
||||
<span>Copyright © LXDWARE 2020 - Present</span>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
|
@ -231,14 +264,14 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
<div class="tab-pane fade show active" id="form" role="tabpanel" aria-labelledby="form-tab">
|
||||
<br />
|
||||
<div class="row">
|
||||
<label class="col-3 col-form-label text-right">Name: </label>
|
||||
<label class="col-3 col-form-label text-right">Name: <span class="text-danger">*</span></label>
|
||||
<div class="col-7">
|
||||
<div class="form-group">
|
||||
<input type="text" id="storagePoolNameInput" class="form-control" placeholder="" name="storage_pool_name">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-1">
|
||||
<i class="far fa-sm fa-question-circle text-danger" title='(Required) - Enter in the name of the storage pool.'></i>
|
||||
<i class="far fa-sm fa-question-circle" title='(Required) - Enter in the name of the storage pool.'></i>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -255,7 +288,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
</div>
|
||||
|
||||
<div class="row">
|
||||
<label class="col-3 col-form-label text-right">Driver: </label>
|
||||
<label class="col-3 col-form-label text-right">Driver: <span class="text-danger">*</span></label>
|
||||
<div class="col-7">
|
||||
<div class="form-group">
|
||||
<select id="storagePoolDriverInput" class="form-control" onclick="changeStoragePoolDriverInput()"name="storage_pool_driver">
|
||||
|
@ -269,7 +302,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
</div>
|
||||
</div>
|
||||
<div class="col-1">
|
||||
<i class="far fa-sm fa-question-circle text-danger" title='(Required) - Select the storage pool driver.'></i>
|
||||
<i class="far fa-sm fa-question-circle" title='(Required) - Select the storage pool driver.'></i>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -798,61 +831,66 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
const remoteId = urlParams.get('remote');
|
||||
const projectName = urlParams.get('project');
|
||||
var storagePoolToUpdate = "";
|
||||
var reloadTime = 5000;
|
||||
|
||||
function logout(){
|
||||
$.get("./php/aaa/authentication.php?action=deauthenticateUser", function (data) {
|
||||
$.get("./backend/aaa/authentication.php?action=deauthenticateUser", function (data) {
|
||||
operationData = JSON.parse(data);
|
||||
console.log(operationData);
|
||||
if (operationData.status_code == 200) {
|
||||
window.location = './index.html'
|
||||
window.location.href = './index.php'
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function operationStatusCheck(){
|
||||
clearTimeout(operationTimeout);
|
||||
//check to see if there are any running operations
|
||||
$.get("./php/lxd/operations.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&action=displayOperationStatus", function (data) {
|
||||
$.get("./backend/lxd/operations.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&action=displayOperationStatus", function (data) {
|
||||
//Check to see if we have running operations
|
||||
if (data){
|
||||
//Display spinner and notification area if there are running tasks
|
||||
$('#spinner').show();
|
||||
if (data) {
|
||||
//Display notification area if there are running tasks
|
||||
$('#notificationArea').show();
|
||||
$('#notification').text(data);
|
||||
//Set the page to check operations again in 1 second
|
||||
setTimeout(() => { operationStatusCheck(); }, 1000);
|
||||
$('#notification').text("Notice: " + data);
|
||||
//Set the page to check operations again in 2 seconds
|
||||
operationTimeout = setTimeout(() => { operationStatusCheck(); }, 2000);
|
||||
}
|
||||
else {
|
||||
//Hide spinner and notification area if no running tasks
|
||||
$('#spinner').hide();
|
||||
//Hide notification area if no running tasks
|
||||
$('#notificationArea').hide();
|
||||
$('#notification').text("");
|
||||
//Set the page to check operations again in 3 seconds
|
||||
setTimeout(() => { operationStatusCheck(); }, 3000);
|
||||
//Set the page to check operations again in 4 seconds
|
||||
operationTimeout = setTimeout(() => { operationStatusCheck(); }, 4000);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function reloadPageContent() {
|
||||
|
||||
clearTimeout(pageReloadTimeout);
|
||||
|
||||
//Check Authorization
|
||||
$.get("./php/aaa/authentication.php?action=validateAuthentication", function (data) {
|
||||
$.get("./backend/aaa/authentication.php?action=validateAuthentication", function (data) {
|
||||
operationData = JSON.parse(data);
|
||||
if (operationData.status_code != 200) {
|
||||
console.log(operationData);
|
||||
window.location = './index.html'
|
||||
window.location.href = './index.php'
|
||||
}
|
||||
});
|
||||
|
||||
$('#storagePoolListTable').DataTable().ajax.reload(null, false);
|
||||
|
||||
//Set reload page content
|
||||
pageReloadTimeout = setTimeout(() => { reloadPageContent(); }, reloadTime);
|
||||
}
|
||||
|
||||
function loadPageContent(){
|
||||
|
||||
//Display current logged in username
|
||||
$("#username").load("./php/admin/settings.php?action=displayUsername");
|
||||
$("#username").load("./backend/admin/settings.php?action=displayUsername");
|
||||
|
||||
$('#storagePoolListTable').DataTable( {
|
||||
ajax: "./php/lxd/storage-pools.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&action=listStoragePools",
|
||||
ajax: "./backend/lxd/storage-pools.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&action=listStoragePools",
|
||||
columns: [
|
||||
{},
|
||||
{ title: "Name" },
|
||||
|
@ -870,16 +908,22 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
});
|
||||
|
||||
//Check for any running operations
|
||||
operationStatusCheck();
|
||||
operationTimeout = setTimeout(() => { operationStatusCheck(); }, 1000);
|
||||
|
||||
//Set reload page content
|
||||
$.get("./backend/admin/settings.php?action=retrievePageRefreshRateValues", function (data) {
|
||||
operationData = JSON.parse(data);
|
||||
if (operationData.storage_pools_page_rate >= 1)
|
||||
reloadTime = operationData.storage_pools_page_rate * 1000;
|
||||
pageReloadTimeout = setTimeout(() => { reloadPageContent(); }, reloadTime);
|
||||
});
|
||||
|
||||
//Set the page content to reload in 5 seconds
|
||||
setInterval(() => { reloadPageContent(); }, 5000);
|
||||
}
|
||||
|
||||
function createStoragePoolUsingJSON(){
|
||||
var storagePoolCreateJSON = $("#jsonCreateInput").val();
|
||||
console.log("Info: creating storage pool");
|
||||
$.post("./php/lxd/storage-pools.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&action=createStoragePoolUsingJSON", {json: storagePoolCreateJSON}, function (data) {
|
||||
$.post("./backend/lxd/storage-pools.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&action=createStoragePoolUsingJSON", {json: storagePoolCreateJSON}, function (data) {
|
||||
//Sync operation type
|
||||
var operationData = JSON.parse(data);
|
||||
console.log(operationData);
|
||||
|
@ -928,7 +972,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
var storagePoolZfsPoolNameInput = $("#storagePoolZfsPoolNameInput").val();
|
||||
|
||||
console.log("Info: creating storage pool");
|
||||
$.get("./php/lxd/storage-pools.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) +
|
||||
$.get("./backend/lxd/storage-pools.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) +
|
||||
"&name=" + encodeURI(storagePoolNameInput) +
|
||||
"&description=" + encodeURI(storagePoolDescriptionInput) +
|
||||
"&size=" + encodeURI(storagePoolSizeInput) +
|
||||
|
@ -979,7 +1023,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
function loadStoragePoolJson(storagePoolToLoad){
|
||||
console.log("Info: loading storage pool " + storagePoolToLoad);
|
||||
storagePoolToUpdate = storagePoolToLoad;
|
||||
$.get("./php/lxd/storage-pools.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&storage_pool=" + encodeURI(storagePoolToLoad) + "&action=loadStoragePool", function (data) {
|
||||
$.get("./backend/lxd/storage-pools.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&storage_pool=" + encodeURI(storagePoolToLoad) + "&action=loadStoragePool", function (data) {
|
||||
//Sync operation type
|
||||
var operationData = JSON.parse(data);
|
||||
console.log(operationData);
|
||||
|
@ -995,7 +1039,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
function updateStoragePool(){
|
||||
var storagePoolUpdateJSON = $("#jsonEditInput").val();
|
||||
console.log("Info: updating storage pool " + storagePoolToUpdate);
|
||||
$.post("./php/lxd/storage-pools.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&storage_pool=" + encodeURI(storagePoolToUpdate) + "&action=updateStoragePool", {json: storagePoolUpdateJSON}, function (data) {
|
||||
$.post("./backend/lxd/storage-pools.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&storage_pool=" + encodeURI(storagePoolToUpdate) + "&action=updateStoragePool", {json: storagePoolUpdateJSON}, function (data) {
|
||||
//Sync operation type
|
||||
var operationData = JSON.parse(data);
|
||||
console.log(operationData);
|
||||
|
@ -1008,7 +1052,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
|
||||
function deleteStoragePool(storagePoolToDelete){
|
||||
console.log("Info: deleting storage pool " + storagePoolToDelete);
|
||||
$.get("./php/lxd/storage-pools.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&storage_pool=" + encodeURI(storagePoolToDelete) + "&action=deleteStoragePool", function (data) {
|
||||
$.get("./backend/lxd/storage-pools.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&storage_pool=" + encodeURI(storagePoolToDelete) + "&action=deleteStoragePool", function (data) {
|
||||
//Sync operation type
|
||||
var operationData = JSON.parse(data);
|
||||
console.log(operationData);
|
||||
|
@ -1233,33 +1277,64 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
}
|
||||
}
|
||||
|
||||
function setSidebarToggleValue(){
|
||||
sidebarState = localStorage.getItem('sidebarState');
|
||||
if (sidebarState == "collapsed"){
|
||||
localStorage.setItem('sidebarState','expanded');
|
||||
}
|
||||
else {
|
||||
localStorage.setItem('sidebarState','collapsed');
|
||||
}
|
||||
}
|
||||
|
||||
function applySidebarToggleValue() {
|
||||
sidebarState = localStorage.getItem('sidebarState');
|
||||
if (sidebarState == "collapsed"){
|
||||
$("body").toggleClass("sidebar-toggled"),
|
||||
$(".sidebar").toggleClass("toggled"),
|
||||
$(".sidebar").hasClass("toggled") && $(".sidebar .collapse").collapse("hide")
|
||||
}
|
||||
}
|
||||
|
||||
applySidebarToggleValue();
|
||||
|
||||
$(document).ready(function(){
|
||||
|
||||
//Check Authorization
|
||||
$.get("./php/aaa/authentication.php?action=validateAuthentication", function (data) {
|
||||
$.get("./backend/aaa/authentication.php?action=validateAuthentication", function (data) {
|
||||
operationData = JSON.parse(data);
|
||||
if (operationData.status_code != 200) {
|
||||
console.log(operationData);
|
||||
window.location = './index.html'
|
||||
window.location.href = './index.php'
|
||||
}
|
||||
});
|
||||
|
||||
//Load in the sidebar
|
||||
$("#sidebarLinks").load("./sidebar.html");
|
||||
//Load in the sidebar
|
||||
$("#sidebarLinks").load("./sidebar.php?version=3.0");
|
||||
|
||||
//Setup Page Breadcrumb Links/Information
|
||||
$('#remoteBreadCrumb').load("./php/lxd/remote-breadcrumb.php?remote=" + encodeURI(remoteId));
|
||||
$('#remoteBreadCrumb').attr("href", "remotes-single.html?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName));
|
||||
$('#storagePoolsBreadCrumb').text("storage-pools");
|
||||
|
||||
//Load the card contents
|
||||
loadPageContent();
|
||||
|
||||
$("#remoteListNav").load("./php/lxd/remotes.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&action=listRemotesForTopNavigation");
|
||||
$("#projectListNav").load("./php/lxd/projects.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&action=listProjectsForTopNavigation");
|
||||
$('#remoteBreadCrumb').load("./backend/lxd/remote-breadcrumb.php?remote=" + encodeURI(remoteId));
|
||||
$('#remoteBreadCrumb').attr("href", "remotes-single.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName));
|
||||
|
||||
//Validate remote host connection returns 200 status
|
||||
$.get("./backend/lxd/remotes-single.php?remote=" + encodeURI(remoteId) + "&action=validateRemoteConnection", function (data) {
|
||||
operationData = JSON.parse(data);
|
||||
console.log(operationData);
|
||||
if (operationData.status_code == 200) {
|
||||
//Set top navbar dropdowns
|
||||
$("#remoteListNav").load("./backend/lxd/remotes.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&action=listRemotesForSelectOption");
|
||||
$("#projectListNav").load("./backend/lxd/projects.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&action=listProjectsForSelectOption");
|
||||
|
||||
//Load Page Content
|
||||
loadPageContent();
|
||||
}
|
||||
else {
|
||||
alert("Unable to connect to remote host. HTTP status code: " + operationData.status_code);
|
||||
}
|
||||
});
|
||||
|
||||
//Load the about info for the about modal
|
||||
$.get("./about.html", function (data) {
|
||||
$.get("./backend/config/about.php", function (data) {
|
||||
$("#about").html(data);
|
||||
});
|
||||
|
|
@ -37,7 +37,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
|
||||
<!-- Custom styles for this template-->
|
||||
<link href="vendor/sb-admin-2/css/sb-admin-2.css" rel="stylesheet">
|
||||
<link href="assets/css/style.css" rel="stylesheet">
|
||||
<link href="assets/css/style.css?version=3.0" rel="stylesheet">
|
||||
|
||||
<!-- Custom styles for this page -->
|
||||
<link href="vendor/datatables/dataTables.bootstrap4.min.css" rel="stylesheet">
|
||||
|
@ -50,7 +50,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
<div id="wrapper">
|
||||
|
||||
<!-- Sidebar -->
|
||||
<ul class="navbar-nav bg-dark sidebar sidebar-dark accordion" id="accordionSidebar">
|
||||
<ul class="navbar-nav bg-dark sidebar sidebar-dark accordion sidebar-divider-right" id="accordionSidebar">
|
||||
|
||||
<div id="sidebarLinks"></div>
|
||||
|
||||
|
@ -59,12 +59,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
|
||||
<!-- Sidebar Toggler (Sidebar) -->
|
||||
<div class="text-center d-none d-md-inline">
|
||||
<button class="rounded-circle border-0" id="sidebarToggle"></button>
|
||||
<button class="rounded-circle border-0" id="sidebarToggle" onclick="setSidebarToggleValue()"></button>
|
||||
</div>
|
||||
</ul>
|
||||
<!-- End of Sidebar -->
|
||||
|
||||
|
||||
<!-- Content Wrapper -->
|
||||
<div id="content-wrapper" class="d-flex flex-column">
|
||||
|
||||
|
@ -79,36 +78,43 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
<i class="fa fa-bars"></i>
|
||||
</button>
|
||||
|
||||
|
||||
<!-- Topbar Notification -->
|
||||
<div class="d-none d-sm-inline-block form-inline mr-auto ml-md-3 my-2 my-md-0 mw-100 navbar-search">
|
||||
<!-- Topbar Notification -->
|
||||
<div class="d-none d-sm-inline-block form-inline mr-auto ml-md-3 my-2 my-md-0 mw-100 navbar-search">
|
||||
<ul class="navbar-nav ml-auto">
|
||||
|
||||
<li>
|
||||
<div class="nav-item spinner-border m-3" role="status" style="display:none;" id="spinner">
|
||||
<span class="nav-item sr-only">Loading...</span>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li class="nav-item dropdown no-arrow" id="notificationArea" style="display: none;">
|
||||
<div class="nav-link dropdown-toggle">
|
||||
<span id="notification" class="mr-2 d-none d-lg-inline text-gray-600">Notification</span>
|
||||
<span id="notification" class="mr-2 d-none d-lg-inline text-danger">Notification</span>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- Topbar Navbar -->
|
||||
<ul class="navbar-nav ml-auto">
|
||||
|
||||
<li class="nav-item dropdown" id="remoteListNav">
|
||||
<li class="nav-item dropdown">
|
||||
<label class="h6 mt-4 mr-2 ml-4">Host: </label>
|
||||
</li>
|
||||
<li class="nav-item dropdown">
|
||||
<div class="input-group mt-3">
|
||||
<select class="form-control" id="remoteListNav" style="width:150px;" onchange="location = this.value;">
|
||||
</select>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li class="nav-item dropdown" id="projectListNav">
|
||||
<li class="nav-item dropdown">
|
||||
<label class="h6 mt-4 mr-2 ml-4">Project: </label>
|
||||
</li>
|
||||
<li class="nav-item dropdown">
|
||||
<div class="input-group mt-3">
|
||||
<select class="form-control" id="projectListNav" style="width:150px;" onchange="location = this.value;">
|
||||
</select>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<!-- Nav Divider -->
|
||||
<div class="topbar-divider d-none d-sm-block"></div>
|
||||
|
||||
<!-- Nav Item - User Information -->
|
||||
|
@ -119,14 +125,18 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
</a>
|
||||
<!-- Dropdown - User Information -->
|
||||
<div class="dropdown-menu dropdown-menu-right shadow animated--grow-in" aria-labelledby="userDropdown">
|
||||
<a class="dropdown-item" href="user-profile.html">
|
||||
<a class="dropdown-item" href="user-profile.php">
|
||||
<i class="fas fa-user fa-sm fa-fw mr-2 text-gray-400"></i>
|
||||
Profile
|
||||
</a>
|
||||
<a class="dropdown-item" href="settings.html">
|
||||
<a class="dropdown-item" href="settings.php">
|
||||
<i class="fas fa-cog fa-sm fa-fw mr-2 text-gray-400"></i>
|
||||
Settings
|
||||
</a>
|
||||
<a class="dropdown-item" href="logs.php">
|
||||
<i class="fas fa-history fa-sm fa-fw mr-2 text-gray-400"></i>
|
||||
Logs
|
||||
</a>
|
||||
<a class="dropdown-item" href="#" data-toggle="modal" data-target="#aboutModal">
|
||||
<i class="fas fa-info-circle fa-sm fa-fw mr-2 text-gray-400"></i>
|
||||
About
|
||||
|
@ -147,26 +157,50 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
<!-- Begin Page Content -->
|
||||
<div class="container-fluid">
|
||||
|
||||
<!-- BreadCrumb -->
|
||||
<nav aria-label="breadcrumb">
|
||||
<ol class="breadcrumb">
|
||||
<li class="breadcrumb-item"><a href="#" id="remoteBreadCrumb"></a></li>
|
||||
<li class="breadcrumb-item"><a href="#" id="storagePoolsBreadCrumb"></a></li>
|
||||
<li class="breadcrumb-item active" aria-current="page" id="storageVolumesBreadCrumb"></li>
|
||||
</ol>
|
||||
</nav>
|
||||
<header class="page-header page-header-dark bg-gradient-primary-to-secondary">
|
||||
<div class="container-xl px-4">
|
||||
<div class="page-header-content pt-4">
|
||||
<div class="row align-items-center justify-content-between mt-n5 ml-n5 mr-n5 bg-dark pb-6">
|
||||
<div class="col-auto mt-4 ml-3">
|
||||
<div class="page-header-subtitle">
|
||||
<a href="#" id="remoteBreadCrumb"></a>
|
||||
/
|
||||
<a href="#" id="storagePoolsBreadCrumb"></a>
|
||||
</div>
|
||||
<h2 class="page-header-title mt-2">
|
||||
STORAGE VOLUMES
|
||||
</h2>
|
||||
<div class="page-header-subtitle">
|
||||
Create and manage LXD storage volumes
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-xl-auto mt-4">
|
||||
<div class="input-group input-group-joined border-0" style="width: 14rem">
|
||||
<span class="input-group-text bg-transparent border-0">
|
||||
<a class="btn btn-outline-primary" href="#" data-toggle="modal" data-target="#createStorageVolumeModal" title="New Storage Volume" aria-hidden="true">
|
||||
<i class="fas fa-plus fa-sm fa-fw"></i> Storage Volume
|
||||
</a>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<div class="row">
|
||||
<div class="row mt-n5 ml-2 mr-2">
|
||||
|
||||
<div class="col-12">
|
||||
<div class="col-12 mt-n3">
|
||||
<!-- Storage Volume List -->
|
||||
<div class="card shadow mb-4">
|
||||
<!-- Card Header - Dropdown -->
|
||||
<div class="card-header py-3 d-flex flex-row align-items-center justify-content-between">
|
||||
<h6 class="m-0 font-weight-bold text-primary">Storage Volumes</h6>
|
||||
<h6 class="m-0 font-weight-bold">
|
||||
<span class="ml-1">Storage Volumes</span>
|
||||
</h6>
|
||||
<div class="dropdown no-arrow">
|
||||
<a class="dropdown-toggle mr-2" href="#" data-toggle="modal" data-target="#createStorageVolumeModal" title="New Storage Volume" aria-hidden="true">
|
||||
<i class="fas fa-plus fa-sm fa-fw"></i> Storage Volume</a>
|
||||
<a class="dropdown-toggle mr-2" href="#" onclick="reloadPageContent()" title="Refresh" aria-hidden="true">
|
||||
<i class="fa fa-sync fa-1x fa-fw"></i></a>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Card Body -->
|
||||
|
@ -180,7 +214,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- End Storage Volume List -->
|
||||
<!-- End Storeage Volume List -->
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
@ -195,7 +229,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
<footer class="sticky-footer bg-white">
|
||||
<div class="container my-auto">
|
||||
<div class="copyright text-center my-auto">
|
||||
<span>Copyright © lxdware.com 2021</span>
|
||||
<span>Copyright © LXDWARE 2020 - Present</span>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
|
@ -235,18 +269,18 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
<div class="tab-pane fade show active" id="form" role="tabpanel" aria-labelledby="form-tab">
|
||||
<br />
|
||||
<div class="row">
|
||||
<label class="col-3 col-form-label text-right">Name: </label>
|
||||
<label class="col-3 col-form-label text-right">Name: <span class="text-danger">*</span></label>
|
||||
<div class="col-7">
|
||||
<div class="form-group">
|
||||
<input type="text" id="storageVolumeNameInput" class="form-control" placeholder="" name="storage_volume_name">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-1">
|
||||
<i class="far fa-sm fa-question-circle text-danger" title='(Required) - Enter in the name of the storage volume.'></i>
|
||||
<i class="far fa-sm fa-question-circle" title='(Required) - Enter in the name of the storage volume.'></i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<label class="col-3 col-form-label text-right">Content Type: </label>
|
||||
<label class="col-3 col-form-label text-right">Content Type: <span class="text-danger">*</span></label>
|
||||
<div class="col-7">
|
||||
<div class="form-group">
|
||||
<select id="storageVolumeContentTypeInput" class="form-control" name="content_type">
|
||||
|
@ -256,7 +290,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
</div>
|
||||
</div>
|
||||
<div class="col-1">
|
||||
<i class="far fa-sm fa-question-circle text-danger" title='(Required) - Select the content type.'></i>
|
||||
<i class="far fa-sm fa-question-circle" title='(Required) - Select the content type.'></i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
|
@ -536,62 +570,67 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
const projectName = urlParams.get('project');
|
||||
const storagePoolName = urlParams.get('pool');
|
||||
var storageVolumeToUpdate = "";
|
||||
var volumeType = urlParams.get('type');
|
||||
var volumeType = urlParams.get('type');
|
||||
var reloadTime = 5000;
|
||||
|
||||
function logout(){
|
||||
$.get("./php/aaa/authentication.php?action=deauthenticateUser", function (data) {
|
||||
$.get("./backend/aaa/authentication.php?action=deauthenticateUser", function (data) {
|
||||
operationData = JSON.parse(data);
|
||||
console.log(operationData);
|
||||
if (operationData.status_code == 200) {
|
||||
window.location = './index.html'
|
||||
window.location.href = './index.php'
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function operationStatusCheck(){
|
||||
clearTimeout(operationTimeout);
|
||||
//check to see if there are any running operations
|
||||
$.get("./php/lxd/operations.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&action=displayOperationStatus", function (data) {
|
||||
$.get("./backend/lxd/operations.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&action=displayOperationStatus", function (data) {
|
||||
//Check to see if we have running operations
|
||||
if (data){
|
||||
//Display spinner and notification area if there are running tasks
|
||||
$('#spinner').show();
|
||||
if (data) {
|
||||
//Display notification area if there are running tasks
|
||||
$('#notificationArea').show();
|
||||
$('#notification').text(data);
|
||||
//Set the page to check operations again in 1 second
|
||||
setTimeout(() => { operationStatusCheck(); }, 1000);
|
||||
$('#notification').text("Notice: " + data);
|
||||
//Set the page to check operations again in 2 seconds
|
||||
operationTimeout = setTimeout(() => { operationStatusCheck(); }, 2000);
|
||||
}
|
||||
else {
|
||||
//Hide spinner and notification area if no running tasks
|
||||
$('#spinner').hide();
|
||||
//Hide notification area if no running tasks
|
||||
$('#notificationArea').hide();
|
||||
$('#notification').text("");
|
||||
//Set the page to check operations again in 3 seconds
|
||||
setTimeout(() => { operationStatusCheck(); }, 3000);
|
||||
//Set the page to check operations again in 4 seconds
|
||||
operationTimeout = setTimeout(() => { operationStatusCheck(); }, 4000);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function reloadPageContent(){
|
||||
|
||||
clearTimeout(pageReloadTimeout);
|
||||
|
||||
//Check Authorization
|
||||
$.get("./php/aaa/authentication.php?action=validateAuthentication", function (data) {
|
||||
$.get("./backend/aaa/authentication.php?action=validateAuthentication", function (data) {
|
||||
operationData = JSON.parse(data);
|
||||
if (operationData.status_code != 200) {
|
||||
console.log(operationData);
|
||||
window.location = './index.html'
|
||||
window.location.href = './index.php'
|
||||
}
|
||||
});
|
||||
|
||||
$('#storageVolumeListTable').DataTable().ajax.reload(null, false);
|
||||
|
||||
//Set reload page content
|
||||
pageReloadTimeout = setTimeout(() => { reloadPageContent(); }, reloadTime);
|
||||
}
|
||||
|
||||
function loadPageContent(){
|
||||
|
||||
//Display current logged in username
|
||||
$("#username").load("./php/admin/settings.php?action=displayUsername");
|
||||
$("#username").load("./backend/admin/settings.php?action=displayUsername");
|
||||
|
||||
$('#storageVolumeListTable').DataTable( {
|
||||
ajax: "./php/lxd/storage-volumes.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&pool=" + encodeURI(storagePoolName) + "&type=" + encodeURI(volumeType) + "&action=listStorageVolumes",
|
||||
ajax: "./backend/lxd/storage-volumes.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&pool=" + encodeURI(storagePoolName) + "&type=" + encodeURI(volumeType) + "&action=listStorageVolumes",
|
||||
columns: [
|
||||
{},
|
||||
{ title: "Name" },
|
||||
|
@ -608,10 +647,16 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
});
|
||||
|
||||
//Check for any running operations
|
||||
operationStatusCheck();
|
||||
operationTimeout = setTimeout(() => { operationStatusCheck(); }, 1000);
|
||||
|
||||
//Set reload page content
|
||||
$.get("./backend/admin/settings.php?action=retrievePageRefreshRateValues", function (data) {
|
||||
operationData = JSON.parse(data);
|
||||
if (operationData.storage_volumes_page_rate >= 1)
|
||||
reloadTime = operationData.storage_volumes_page_rate * 1000;
|
||||
pageReloadTimeout = setTimeout(() => { reloadPageContent(); }, reloadTime);
|
||||
});
|
||||
|
||||
//Set the page content to reload in 5 seconds
|
||||
setInterval(() => { reloadPageContent(); }, 5000);
|
||||
}
|
||||
|
||||
function createStorageVolumeUsingForm(){
|
||||
|
@ -632,7 +677,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
var storageVolumeZfsUseRefquotaInput = $("#storageVolumeZfsUseRefquotaInput").val();
|
||||
|
||||
console.log("Info: creating storage volume " + storageVolumeNameInput + " in " + storagePoolName);
|
||||
$.get("./php/lxd/storage-volumes.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) +
|
||||
$.get("./backend/lxd/storage-volumes.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) +
|
||||
"&name=" + encodeURI(storageVolumeNameInput) +
|
||||
"&content_type=" + encodeURI(storageVolumeContentTypeInput) +
|
||||
"&size=" + encodeURI(storageVolumeSizeInput) +
|
||||
|
@ -665,7 +710,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
function createStorageVolumeUsingJSON(){
|
||||
var storageVolumeCreateJSON = $("#jsonCreateInput").val();
|
||||
console.log("Info: creating storage volume");
|
||||
$.post("./php/lxd/storage-volumes.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&storage_pool=" + encodeURI(storagePoolName) + "&action=createStorageVolumeUsingJSON", {json: storageVolumeCreateJSON}, function (data) {
|
||||
$.post("./backend/lxd/storage-volumes.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&storage_pool=" + encodeURI(storagePoolName) + "&action=createStorageVolumeUsingJSON", {json: storageVolumeCreateJSON}, function (data) {
|
||||
//Sync operation type
|
||||
var operationData = JSON.parse(data);
|
||||
console.log(operationData);
|
||||
|
@ -679,7 +724,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
function loadStorageVolumeJson(storageVolumeToLoad){
|
||||
console.log("Info: loading storage volume " + storageVolumeToLoad);
|
||||
storageVolumeToUpdate = storageVolumeToLoad;
|
||||
$.get("./php/lxd/storage-volumes.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&name=" + encodeURI(storageVolumeToLoad) + "&storage_pool=" + encodeURI(storagePoolName) + "&action=loadStorageVolume", function (data) {
|
||||
$.get("./backend/lxd/storage-volumes.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&name=" + encodeURI(storageVolumeToLoad) + "&storage_pool=" + encodeURI(storagePoolName) + "&action=loadStorageVolume", function (data) {
|
||||
//Sync operation type
|
||||
var operationData = JSON.parse(data);
|
||||
console.log(operationData);
|
||||
|
@ -695,7 +740,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
function updateStorageVolume(){
|
||||
var storageVolumeUpdateJSON = $("#jsonEditInput").val();
|
||||
console.log("Info: updating storage volume " + storageVolumeToUpdate);
|
||||
$.post("./php/lxd/storage-volumes.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&name=" + encodeURI(storageVolumeToUpdate) + "&storage_pool=" + encodeURI(storagePoolName) + "&action=updateStorageVolume", {json: storageVolumeUpdateJSON}, function (data) {
|
||||
$.post("./backend/lxd/storage-volumes.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&name=" + encodeURI(storageVolumeToUpdate) + "&storage_pool=" + encodeURI(storagePoolName) + "&action=updateStorageVolume", {json: storageVolumeUpdateJSON}, function (data) {
|
||||
//Sync operation type
|
||||
var operationData = JSON.parse(data);
|
||||
console.log(operationData);
|
||||
|
@ -708,7 +753,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
|
||||
function deleteStorageVolume(storageVolumeToDelete){
|
||||
console.log("Info: deleting storage volume " + storageVolumeToDelete);
|
||||
$.get("./php/lxd/storage-volumes.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&name=" + encodeURI(storageVolumeToDelete) + "&storage_pool=" + encodeURI(storagePoolName) + "&action=deleteStorageVolume", function (data) {
|
||||
$.get("./backend/lxd/storage-volumes.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&name=" + encodeURI(storageVolumeToDelete) + "&storage_pool=" + encodeURI(storagePoolName) + "&action=deleteStorageVolume", function (data) {
|
||||
//Sync operation type
|
||||
var operationData = JSON.parse(data);
|
||||
console.log(operationData);
|
||||
|
@ -719,35 +764,66 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
});
|
||||
}
|
||||
|
||||
function setSidebarToggleValue(){
|
||||
sidebarState = localStorage.getItem('sidebarState');
|
||||
if (sidebarState == "collapsed"){
|
||||
localStorage.setItem('sidebarState','expanded');
|
||||
}
|
||||
else {
|
||||
localStorage.setItem('sidebarState','collapsed');
|
||||
}
|
||||
}
|
||||
|
||||
function applySidebarToggleValue() {
|
||||
sidebarState = localStorage.getItem('sidebarState');
|
||||
if (sidebarState == "collapsed"){
|
||||
$("body").toggleClass("sidebar-toggled"),
|
||||
$(".sidebar").toggleClass("toggled"),
|
||||
$(".sidebar").hasClass("toggled") && $(".sidebar .collapse").collapse("hide")
|
||||
}
|
||||
}
|
||||
|
||||
applySidebarToggleValue();
|
||||
|
||||
$(document).ready(function(){
|
||||
|
||||
//Check Authorization
|
||||
$.get("./php/aaa/authentication.php?action=validateAuthentication", function (data) {
|
||||
$.get("./backend/aaa/authentication.php?action=validateAuthentication", function (data) {
|
||||
operationData = JSON.parse(data);
|
||||
if (operationData.status_code != 200) {
|
||||
console.log(operationData);
|
||||
window.location = './index.html'
|
||||
window.location.href = './index.php'
|
||||
}
|
||||
});
|
||||
|
||||
//Load in the sidebar
|
||||
$("#sidebarLinks").load("./sidebar.html");
|
||||
$("#sidebarLinks").load("./sidebar.php?version=3.0");
|
||||
|
||||
//Setup Page Breadcrumb Links/Information
|
||||
$('#remoteBreadCrumb').load("./php/lxd/remote-breadcrumb.php?remote=" + encodeURI(remoteId));
|
||||
$('#remoteBreadCrumb').attr("href", "remotes-single.html?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName));
|
||||
$('#storagePoolsBreadCrumb').text("storage-pools");
|
||||
$('#storagePoolsBreadCrumb').attr("href", "storage-pools.html?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName));
|
||||
$('#storageVolumesBreadCrumb').text(storagePoolName);
|
||||
$('#remoteBreadCrumb').load("./backend/lxd/remote-breadcrumb.php?remote=" + encodeURI(remoteId));
|
||||
$('#remoteBreadCrumb').attr("href", "remotes-single.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName));
|
||||
$('#storagePoolsBreadCrumb').text("Storage Pools");
|
||||
$('#storagePoolsBreadCrumb').attr("href", "storage-pools.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName));
|
||||
|
||||
//Load the card contents
|
||||
loadPageContent();
|
||||
//Validate remote host connection returns 200 status
|
||||
$.get("./backend/lxd/remotes-single.php?remote=" + encodeURI(remoteId) + "&action=validateRemoteConnection", function (data) {
|
||||
operationData = JSON.parse(data);
|
||||
console.log(operationData);
|
||||
if (operationData.status_code == 200) {
|
||||
//Set top navbar dropdowns
|
||||
$("#remoteListNav").load("./backend/lxd/remotes.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&action=listRemotesForSelectOption");
|
||||
$("#projectListNav").load("./backend/lxd/projects.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&action=listProjectsForSelectOption");
|
||||
|
||||
$("#remoteListNav").load("./php/lxd/remotes.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&action=listRemotesForTopNavigation");
|
||||
$("#projectListNav").load("./php/lxd/projects.php?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName) + "&action=listProjectsForTopNavigation");
|
||||
//Load Page Content
|
||||
loadPageContent();
|
||||
}
|
||||
else {
|
||||
alert("Unable to connect to remote host. HTTP status code: " + operationData.status_code);
|
||||
}
|
||||
});
|
||||
|
||||
//Load the about info for the about modal
|
||||
$.get("./about.html", function (data) {
|
||||
$.get("./backend/config/about.php", function (data) {
|
||||
$("#about").html(data);
|
||||
});
|
||||
|
||||
|
@ -756,7 +832,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
$('#allVolumeTypesLink').hide()
|
||||
}
|
||||
else{
|
||||
$('#allVolumeTypesLink').attr("href", "storage-volumes.html?pool=" + encodeURI(storagePoolName) + "&remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName));
|
||||
$('#allVolumeTypesLink').attr("href", "storage-volumes.php?pool=" + encodeURI(storagePoolName) + "&remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName));
|
||||
$('#allVolumeTypesLink').show()
|
||||
}
|
||||
|
|
@ -37,7 +37,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
|
||||
<!-- Custom styles for this template-->
|
||||
<link href="vendor/sb-admin-2/css/sb-admin-2.css" rel="stylesheet">
|
||||
<link href="assets/css/style.css" rel="stylesheet">
|
||||
<link href="assets/css/style.css?version=3.0" rel="stylesheet">
|
||||
|
||||
</head>
|
||||
|
||||
|
@ -47,10 +47,10 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
<div id="wrapper">
|
||||
|
||||
<!-- Sidebar -->
|
||||
<ul class="navbar-nav bg-dark sidebar sidebar-dark accordion" id="accordionSidebar">
|
||||
<ul class="navbar-nav bg-dark sidebar sidebar-dark accordion sidebar-divider-right" id="accordionSidebar">
|
||||
|
||||
<!-- Sidebar - Brand -->
|
||||
<a class="sidebar-brand d-flex align-items-center justify-content-center" href="index.html">
|
||||
<a class="sidebar-brand d-flex align-items-center justify-content-center" href="index.php">
|
||||
<div class="sidebar-brand-icon rotate-n-0">
|
||||
<img src="assets/images/logo-dark.svg" style="width: 2rem;"></img>
|
||||
<!-- <i class="fas fa-cube" style="width: 2rem;"></i> -->
|
||||
|
@ -63,7 +63,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
|
||||
<!-- Nav Item - Dashboard -->
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="remotes.html">
|
||||
<a class="nav-link" href="remotes.php">
|
||||
<i class="fas fa-fw fa-server"></i>
|
||||
<span>Hosts</span></a>
|
||||
</li>
|
||||
|
@ -73,7 +73,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
|
||||
<!-- Sidebar Toggler (Sidebar) -->
|
||||
<div class="text-center d-none d-md-inline">
|
||||
<button class="rounded-circle border-0" id="sidebarToggle"></button>
|
||||
<button class="rounded-circle border-0" id="sidebarToggle" onclick="setSidebarToggleValue()"></button>
|
||||
</div>
|
||||
</ul>
|
||||
<!-- End of Sidebar -->
|
||||
|
@ -106,14 +106,18 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
</a>
|
||||
<!-- Dropdown - User Information -->
|
||||
<div class="dropdown-menu dropdown-menu-right shadow animated--grow-in" aria-labelledby="userDropdown">
|
||||
<a class="dropdown-item" href="user-profile.html">
|
||||
<a class="dropdown-item" href="user-profile.php">
|
||||
<i class="fas fa-user fa-sm fa-fw mr-2 text-gray-400"></i>
|
||||
Profile
|
||||
</a>
|
||||
<a class="dropdown-item" href="settings.html">
|
||||
<a class="dropdown-item" href="settings.php">
|
||||
<i class="fas fa-cog fa-sm fa-fw mr-2 text-gray-400"></i>
|
||||
Settings
|
||||
</a>
|
||||
<a class="dropdown-item" href="logs.php">
|
||||
<i class="fas fa-history fa-sm fa-fw mr-2 text-gray-400"></i>
|
||||
Logs
|
||||
</a>
|
||||
<a class="dropdown-item" href="#" data-toggle="modal" data-target="#aboutModal">
|
||||
<i class="fas fa-info-circle fa-sm fa-fw mr-2 text-gray-400"></i>
|
||||
About
|
||||
|
@ -134,33 +138,54 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
<!-- Begin Page Content -->
|
||||
<div class="container-fluid">
|
||||
|
||||
<!-- Page Heading -->
|
||||
<div class="d-sm-flex align-items-center justify-content-between">
|
||||
<h1 class="h5 mb-0 text-gray-800">USER PROFILE</h1>
|
||||
</div>
|
||||
|
||||
<div class="col-12">
|
||||
|
||||
<div class="row">
|
||||
|
||||
<div class="col-2 border-right mt-5">
|
||||
<div class="nav flex-column nav-pills" id="v-pills-tab" role="tablist" aria-orientation="vertical">
|
||||
<a class="nav-link active" id="v-pills-account-tab" data-toggle="pill" href="#v-pills-account" role="tab" aria-controls="v-pills-account" aria-selected="false">Account</a>
|
||||
<a class="nav-link" id="v-pills-password-tab" data-toggle="pill" href="#v-pills-password" role="tab" aria-controls="v-pills-password" aria-selected="false">Password</a>
|
||||
<header class="page-header page-header-dark bg-gradient-primary-to-secondary">
|
||||
<div class="container-xl px-4">
|
||||
<div class="page-header-content pt-4">
|
||||
<div class="row align-items-center justify-content-between mt-n5 ml-n5 mr-n5 bg-dark pb-6">
|
||||
<div class="col-auto mt-4 ml-3">
|
||||
<div class="page-header-subtitle">
|
||||
<span id="remoteBreadCrumb">LXD Dashboard</span>
|
||||
</div>
|
||||
<h2 class="page-header-title mt-2">
|
||||
USER PROFILE
|
||||
</h2>
|
||||
<div class="page-header-subtitle">
|
||||
Edit user profile
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-xl-auto mt-4">
|
||||
<div class="input-group input-group-joined border-0" style="width: 14rem">
|
||||
<span class="input-group-text bg-transparent border-0">
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<div class="col-10">
|
||||
<div class="tab-content" id="v-pills-tabContent">
|
||||
<div class="tab-pane fade show active" id="v-pills-account" role="tabpanel" aria-labelledby="v-pills-account-tab">
|
||||
<!-- Account Information -->
|
||||
<div class="card border-light mb-4">
|
||||
<!-- Card Header - Dropdown -->
|
||||
<div class="card-header py-3 d-flex flex-row align-items-center justify-content-between">
|
||||
<h6 class="m-0 font-weight-bold text-primary">Account Information</h6>
|
||||
</div>
|
||||
<!-- Card Body -->
|
||||
<div class="card-body">
|
||||
<div class="row mt-n5 ml-2 mr-2">
|
||||
|
||||
<div class="col-12 mt-n3">
|
||||
|
||||
<div class="card shadow mb-4">
|
||||
<!-- Card Header - Dropdown -->
|
||||
<div class="card-header py-3 d-flex flex-row align-items-center justify-content-between">
|
||||
<h6 class="m-0 font-weight-bold text-primary">
|
||||
<ul class="nav nav-pills card-header-pills" id="cardPill" role="tablist">
|
||||
<li class="nav-item"><a class="nav-link active" id="nav-account-tab" href="#nav-account" data-toggle="pill" role="tab" aria-controls="nav-account" aria-selected="true">Account</a></li>
|
||||
<li class="nav-item"><a class="nav-link" id="nav-password-tab" href="#nav-password" data-toggle="pill" role="tab" aria-controls="nav-password" aria-selected="false">Password</a></li>
|
||||
</ul>
|
||||
</h6>
|
||||
</div>
|
||||
<!-- Card Body -->
|
||||
<div class="card-body">
|
||||
<div class="col-12">
|
||||
|
||||
<div class="tab-content" id="nav-tabContent">
|
||||
|
||||
<div class="tab-pane fade show active" id="nav-account" role="tabpanel" aria-labelledby="nav-account-tab">
|
||||
<!-- Profile Form -->
|
||||
<div class="row">
|
||||
<label class="col-2 col-form-label text-right">Username:</label>
|
||||
<div class="col-4">
|
||||
|
@ -213,21 +238,10 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- End Profile Form-->
|
||||
</div>
|
||||
</div>
|
||||
<!-- End Account Information -->
|
||||
</div>
|
||||
<div class="tab-pane fade" id="v-pills-password" role="tabpanel" aria-labelledby="v-pills-password-tab">
|
||||
<!-- Password Reset -->
|
||||
<div class="card border-light mb-4">
|
||||
<!-- Card Header - Dropdown -->
|
||||
<div class="card-header py-3 d-flex flex-row align-items-center justify-content-between">
|
||||
<h6 class="m-0 font-weight-bold text-primary">Password Reset</h6>
|
||||
</div>
|
||||
<!-- Card Body -->
|
||||
<div class="card-body">
|
||||
|
||||
<div class="tab-pane fade" id="nav-password" role="tabpanel" aria-labelledby="nav-password-tab">
|
||||
<!-- Password Reset Form -->
|
||||
<div class="row">
|
||||
<label class="col-2 col-form-label text-right">New Password:</label>
|
||||
<div class="col-4">
|
||||
|
@ -253,10 +267,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- End Password Reset Form -->
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<!-- End Password Reset -->
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -275,7 +290,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
<footer class="sticky-footer bg-white">
|
||||
<div class="container my-auto">
|
||||
<div class="copyright text-center my-auto">
|
||||
<span>Copyright © lxdware.com 2021</span>
|
||||
<span>Copyright © LXDWARE 2020 - Present</span>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
|
@ -334,11 +349,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
var userId = urlParams.get('user');
|
||||
|
||||
function logout(){
|
||||
$.get("./php/aaa/authentication.php?action=deauthenticateUser", function (data) {
|
||||
$.get("./backend/aaa/authentication.php?action=deauthenticateUser", function (data) {
|
||||
operationData = JSON.parse(data);
|
||||
console.log(operationData);
|
||||
if (operationData.status_code == 200) {
|
||||
window.location = './index.html'
|
||||
window.location.href = './index.php'
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -346,10 +361,10 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
function loadPageContent(){
|
||||
|
||||
//Display current logged in username
|
||||
$("#username").load("./php/admin/settings.php?action=displayUsername");
|
||||
$("#username").load("./backend/admin/settings.php?action=displayUsername");
|
||||
|
||||
if (userId) {
|
||||
$.get("./php/admin/user-profile.php?id=" + userId + "&action=retrieveUserDetails", function (data) {
|
||||
$.get("./backend/admin/user-profile.php?id=" + userId + "&action=retrieveUserDetails", function (data) {
|
||||
operationData = JSON.parse(data);
|
||||
$("#usernameInput").val(operationData.username);
|
||||
$("#firstNameInput").val(operationData.firstName);
|
||||
|
@ -359,10 +374,10 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
});
|
||||
}
|
||||
else {
|
||||
$.get("./php/admin/user-profile.php?action=retrieveUserId", function (data) {
|
||||
$.get("./backend/admin/user-profile.php?action=retrieveUserId", function (data) {
|
||||
operationData = JSON.parse(data);
|
||||
userId = operationData.id
|
||||
$.get("./php/admin/user-profile.php?id=" + userId + "&action=retrieveUserDetails", function (data) {
|
||||
$.get("./backend/admin/user-profile.php?id=" + userId + "&action=retrieveUserDetails", function (data) {
|
||||
operationData = JSON.parse(data);
|
||||
$("#usernameInput").val(operationData.username);
|
||||
$("#firstNameInput").val(operationData.firstName);
|
||||
|
@ -380,7 +395,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
var lastNameInput = $("#lastNameInput").val();
|
||||
var emailInput = $("#emailInput").val();
|
||||
console.log("Info: updating user account for " + usernameInput);
|
||||
$.get("./php/admin/user-profile.php?id=" + userId + "&first_name=" + firstNameInput + "&last_name=" + lastNameInput + "&email=" + emailInput + "&action=updateUserAccount", function (data) {
|
||||
$.get("./backend/admin/user-profile.php?id=" + userId + "&first_name=" + firstNameInput + "&last_name=" + lastNameInput + "&email=" + emailInput + "&action=updateUserAccount", function (data) {
|
||||
var operationData = JSON.parse(data);
|
||||
console.log(operationData);
|
||||
if (operationData.status_code >= 400) {
|
||||
|
@ -397,7 +412,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
var confirmPasswordInput = $("#confirmPasswordInput").val();
|
||||
if (newPasswordInput == confirmPasswordInput){
|
||||
console.log("Info: updating user password for user id " + userId );
|
||||
$.post("./php/admin/user-profile.php?id=" + userId + "&action=updateUserPassword", {password: newPasswordInput}, function (data) {
|
||||
$.post("./backend/admin/user-profile.php?id=" + userId + "&action=updateUserPassword", {password: newPasswordInput}, function (data) {
|
||||
var operationData = JSON.parse(data);
|
||||
console.log(operationData);
|
||||
if (operationData.status_code >= 400) {
|
||||
|
@ -414,17 +429,37 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
alert("Your passwords did not match, try again");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
function setSidebarToggleValue(){
|
||||
sidebarState = localStorage.getItem('sidebarState');
|
||||
if (sidebarState == "collapsed"){
|
||||
localStorage.setItem('sidebarState','expanded');
|
||||
}
|
||||
else {
|
||||
localStorage.setItem('sidebarState','collapsed');
|
||||
}
|
||||
}
|
||||
|
||||
function applySidebarToggleValue() {
|
||||
sidebarState = localStorage.getItem('sidebarState');
|
||||
if (sidebarState == "collapsed"){
|
||||
$("body").toggleClass("sidebar-toggled"),
|
||||
$(".sidebar").toggleClass("toggled"),
|
||||
$(".sidebar").hasClass("toggled") && $(".sidebar .collapse").collapse("hide")
|
||||
}
|
||||
}
|
||||
|
||||
applySidebarToggleValue();
|
||||
|
||||
$(document).ready(function(){
|
||||
|
||||
//Check Authorization
|
||||
$.get("./php/aaa/authentication.php?action=validateAuthentication", function (data) {
|
||||
$.get("./backend/aaa/authentication.php?action=validateAuthentication", function (data) {
|
||||
operationData = JSON.parse(data);
|
||||
if (operationData.status_code != 200) {
|
||||
console.log(operationData);
|
||||
window.location = './index.html'
|
||||
window.location.href = './index.php'
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -432,7 +467,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
loadPageContent();
|
||||
|
||||
//Load the about info for the about modal
|
||||
$.get("./about.html", function (data) {
|
||||
$.get("./backend/config/about.php", function (data) {
|
||||
$("#about").html(data);
|
||||
});
|
||||
|
BIN
lxd-dashboard/vendor/images/alpine.png
vendored
Normal file
After Width: | Height: | Size: 2.6 KiB |
BIN
lxd-dashboard/vendor/images/archlinux.png
vendored
Normal file
After Width: | Height: | Size: 15 KiB |
BIN
lxd-dashboard/vendor/images/centos.png
vendored
Normal file
After Width: | Height: | Size: 18 KiB |
BIN
lxd-dashboard/vendor/images/debian.png
vendored
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
lxd-dashboard/vendor/images/fedora.png
vendored
Normal file
After Width: | Height: | Size: 16 KiB |
BIN
lxd-dashboard/vendor/images/gentoo.png
vendored
Normal file
After Width: | Height: | Size: 1.1 MiB |
BIN
lxd-dashboard/vendor/images/kali.png
vendored
Normal file
After Width: | Height: | Size: 8.7 KiB |
BIN
lxd-dashboard/vendor/images/opensuse.png
vendored
Normal file
After Width: | Height: | Size: 16 KiB |
BIN
lxd-dashboard/vendor/images/openwrt.png
vendored
Normal file
After Width: | Height: | Size: 12 KiB |
BIN
lxd-dashboard/vendor/images/ubuntu.png
vendored
Normal file
After Width: | Height: | Size: 13 KiB |