This commit is contained in:
matthewalanpenning 2021-07-31 15:44:58 -04:00
parent 471a830153
commit 3489a20e46
26 changed files with 5442 additions and 269 deletions

View file

@ -1,3 +1,11 @@
# 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.

View file

@ -1,5 +1,5 @@
# lxd-dashboard
LXDWARE is an open source LXD dashboard that provides a web-based user interface for controlling the entire LXD-based virtual infrastructure. Some of the features include:
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. Some of the features include:
- Connect and manage multiple LXD servers
- Create LXD container and virtual machine instances from either a form or JSON input
@ -12,7 +12,7 @@ LXDWARE is an open source LXD dashboard that provides a web-based user interface
- Create, edit, apply, and remove LXD profiles
- Create, edit, and delete networks, storage pools, storage volumes, and projects
- Switch between projects on an LXD host
- Interact with instances using web-based terminal console
- Interact with instances using web-based terminal
- Create and download backups of LXD instance to your local computer
- Create local users and groups
- Apply role based access control

View file

@ -19,9 +19,32 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
<!DOCTYPE html>
<html lang="en">
<body class="">
<p><strong>About</strong>: LXDWARE is an open source LXD dashboard that provides a web-based user interface for controlling the entire LXD-based virtual infrastructure.</p>
<p><strong>Version</strong>: 2.0.3</p>
<p><strong>License</strong>: AGPL-3.0</p>
<p><strong>URL</strong>: https://lxdware.com</p>
<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>
<strong>Version</strong>: <span id="versionNumber">v2.1.0</span> <br />
<strong>License</strong>: AGPL-3.0 <br />
<strong>URL</strong>: https://lxdware.com <br />
</p>
<div class="text-center">
<p class="text-primary" id="updateMessage"></p>
<button class="btn btn-primary" type="button" onclick="checkForNewerRelease()">Check for updates</button>
</div>
</body>
<script>
function checkForNewerRelease(){
var versionNumber = $("#versionNumber").text();
$.get("https://api.github.com/repos/lxdware/lxd-dashboard/releases", function( data ) {
console.log("Local version: " + versionNumber)
console.log("Latest GitHub version: " + data[0].tag_name);
if (data[0].tag_name == versionNumber){
$("#updateMessage").text("You are using the lastest release");
}
else {
$("#updateMessage").text("There is a newer release " + data[0].tag_name + " available");
}
});
}
</script>
</html>

View file

@ -229,7 +229,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" data-toggle="tooltip" data-html="true" title='Repository specific name. For example, ubuntu/20.04 and 20.04 would be used for the images and ubuntu repositories respectively'></i>
<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>
@ -239,6 +239,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
</select>
</div>
</div>
<div class="col-1">
<i class="far fa-sm fa-question-circle" title='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">
@ -249,6 +252,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
</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>

File diff suppressed because it is too large Load diff

View file

@ -231,17 +231,20 @@ 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-2 col-form-label text-right">Name: </label>
<div class="col-9">
<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="Enter name of instance" name="name">
<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-2 col-form-label text-right">Type:</label>
<div class="col-9 text-right">
<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>
@ -249,34 +252,43 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
</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-2 col-form-label text-right">Image: </label>
<div class="col-9">
<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-2 col-form-label text-right">Profile: </label>
<div class="col-9">
<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-2 col-form-label text-right">Instance Type: </label>
<div class="col-9">
<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="none" selected>none</option>
<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>
@ -444,17 +456,24 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
</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-2 col-form-label text-right">Location: </label>
<div class="col-9">
<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>

View file

@ -0,0 +1,569 @@
<!--
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"><a href="#" id="networkAclsBreadCrumb"></a></li>
<li class="breadcrumb-item active" aria-current="page" id="networkAclBreadCrumb"></li>
</ol>
</nav>
<div class="row">
<div class="col-12">
<!-- Egress Rules -->
<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>
<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>
</div>
</div>
<!-- Card Body -->
<div class="card-body">
<div class="table-responsive">
<table class="table" id="egressListTable" width="100%" cellspacing="0">
</table>
</div>
</div>
</div>
<!-- End Egress Rules -->
</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 &copy; 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 Traffic Rule Modal-->
<div class="modal fade" id="addTrafficRuleModal" 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">Add Traffic Rule</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">Action: </label>
<div class="col-7">
<div class="form-group">
<select id="actionTrafficRuleInput" onchange="" class="form-control" name="actionTrafficRuleInput">
<option value="allow">allow</option>
<option value="reject">reject</option>
<option value="drop">drop</option>
</select>
</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>
</div>
</div>
<div class="row">
<label class="col-3 col-form-label text-right">State: </label>
<div class="col-7">
<div class="form-group">
<select id="stateTrafficRuleInput" onchange="" class="form-control" name="stateTrafficRuleInput">
<option value="enabled">enabled</option>
<option value="disabled">disabled</option>
<option value="logged">logged</option>
</select>
</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>
</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="descriptionTrafficRuleInput" class="form-control" placeholder="" name="descriptionTrafficRuleInput">
</div>
</div>
<div class="col-1">
<i class="far fa-sm fa-question-circle" title='Enter in a description for this rule.'></i>
</div>
</div>
<div class="row">
<label class="col-3 col-form-label text-right">Source: </label>
<div class="col-7">
<div class="form-group">
<input type="text" id="sourceTrafficRuleInput" class="form-control" placeholder="" name="sourceTrafficRuleInput">
</div>
</div>
<div class="col-1">
<i class="far fa-sm fa-question-circle" title='Enter in a comma separated list of CIDR address, IP ranges, source ACL names, @external, or @internal. Leaving this unset will default to any.'></i>
</div>
</div>
<div class="row">
<label class="col-3 col-form-label text-right">Destination: </label>
<div class="col-7">
<div class="form-group">
<input type="text" id="destinationTrafficRuleInput" class="form-control" placeholder="" name="destinationTrafficRuleInput">
</div>
</div>
<div class="col-1">
<i class="far fa-sm fa-question-circle" title='Enter in a comma separated list of CIDR address, IP ranges, source ACL names, @external, or @internal. Leaving this unset will default to any.'></i>
</div>
</div>
<div class="row">
<label class="col-3 col-form-label text-right">Protocol: </label>
<div class="col-7">
<div class="form-group">
<select id="protocolTrafficRuleInput" onchange="" class="form-control" name="protocolTrafficRuleInput">
<option value="">(not set)</option>
<option value="icmp4">icmp4</option>
<option value="icmp6">icmp6</option>
<option value="tcp">tcp</option>
<option value="udp">udp</option>
</select>
</div>
</div>
<div class="col-1">
<i class="far fa-sm fa-question-circle" title='Select the traffic protocl for this rule. Leaving this unset will default to any.'></i>
</div>
</div>
<div class="row">
<label class="col-3 col-form-label text-right">Source Port: </label>
<div class="col-7">
<div class="form-group">
<input type="text" id="sourcePortTrafficRuleInput" class="form-control" placeholder="" name="sourcePortTrafficRuleInput">
</div>
</div>
<div class="col-1">
<i class="far fa-sm fa-question-circle" title='Used with TCP or UDP rules. Enter in a comma seperated list of ports or port ranges. Leaving this unset will default to any.'></i>
</div>
</div>
<div class="row">
<label class="col-3 col-form-label text-right">Destination Port: </label>
<div class="col-7">
<div class="form-group">
<input type="text" id="destinationPortTrafficRuleInput" class="form-control" placeholder="" name="destinationPortTrafficRuleInput">
</div>
</div>
<div class="col-1">
<i class="far fa-sm fa-question-circle" title='Used with TCP or UDP rules. Enter in a comma seperated list of ports or port ranges. Leaving this unset will default to any.'></i>
</div>
</div>
<div class="row">
<label class="col-3 col-form-label text-right">ICMP Type: </label>
<div class="col-7">
<div class="form-group">
<input type="text" id="icmpTypeTrafficRuleInput" class="form-control" placeholder="" name="icmpTypeTrafficRuleInput">
</div>
</div>
<div class="col-1">
<i class="far fa-sm fa-question-circle" title='Used with ICMP rules. Enter in an ICMP type number. Leaving this unset will default to any.'></i>
</div>
</div>
<div class="row">
<label class="col-3 col-form-label text-right">ICMP Code: </label>
<div class="col-7">
<div class="form-group">
<input type="text" id="icmpCodeTrafficRuleInput" class="form-control" placeholder="" name="icmpCodeTrafficRuleInput">
</div>
</div>
<div class="col-1">
<i class="far fa-sm fa-question-circle" title='Used with ICMP rules. Enter in an ICMP code number. Leaving this unset will default to any.'></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="addTrafficRule()" 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');
const networkAcl = urlParams.get('network_acl');
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'
}
});
$('#egressListTable').DataTable().ajax.reload(null, false);
}
function loadPageContent(){
//Display current logged in username
$("#username").load("./php/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",
columns: [
{},
{ title: "Action" },
{ title: "State" },
{ title: "Description" },
{ title: "Source" },
{ title: "Destination" },
{ title: "Protocol" },
{ title: "Source Port" },
{ title: "Destination Port" },
{ title: "ICMP Type" },
{ title: "ICMP Code" },
{ title: "Actions" }
],
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 addTrafficRule(){
var typeTrafficRuleInput = "egress";
var actionTrafficRuleInput = $("#actionTrafficRuleInput").val();
var stateTrafficRuleInput = $("#stateTrafficRuleInput").val();
var descriptionTrafficRuleInput = $("#descriptionTrafficRuleInput").val();
var sourceTrafficRuleInput = $("#sourceTrafficRuleInput").val();
var destinationTrafficRuleInput = $("#destinationTrafficRuleInput").val();
var protocolTrafficRuleInput = $("#protocolTrafficRuleInput").val();
var sourcePortTrafficRuleInput = $("#sourcePortTrafficRuleInput").val();
var destinationPortTrafficRuleInput = $("#destinationPortTrafficRuleInput").val();
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) {
//Sync operation type
var operationData = JSON.parse(data);
console.log(operationData);
if (operationData.error_code >= 400){
alert(operationData.error);
}
setTimeout(() => { reloadPageContent(); }, 1000);
});
}
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) {
//Sync 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));
$('#networkAclsBreadCrumb').text("network-acls");
$('#networkAclsBreadCrumb').attr("href", "network-acls.html?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName));
$('#networkAclBreadCrumb').text(networkAcl);
//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>

View file

@ -0,0 +1,569 @@
<!--
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"><a href="#" id="networkAclsBreadCrumb"></a></li>
<li class="breadcrumb-item active" aria-current="page" id="networkAclBreadCrumb"></li>
</ol>
</nav>
<div class="row">
<div class="col-12">
<!-- Ingress Rules -->
<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>
<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>
</div>
</div>
<!-- Card Body -->
<div class="card-body">
<div class="table-responsive">
<table class="table" id="ingressListTable" width="100%" cellspacing="0">
</table>
</div>
</div>
</div>
<!-- End Ingress Rules -->
</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 &copy; 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 Traffic Rule Modal-->
<div class="modal fade" id="addTrafficRuleModal" 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">Add Traffic Rule</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">Action: </label>
<div class="col-7">
<div class="form-group">
<select id="actionTrafficRuleInput" onchange="" class="form-control" name="actionTrafficRuleInput">
<option value="allow">allow</option>
<option value="reject">reject</option>
<option value="drop">drop</option>
</select>
</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>
</div>
</div>
<div class="row">
<label class="col-3 col-form-label text-right">State: </label>
<div class="col-7">
<div class="form-group">
<select id="stateTrafficRuleInput" onchange="" class="form-control" name="stateTrafficRuleInput">
<option value="enabled">enabled</option>
<option value="disabled">disabled</option>
<option value="logged">logged</option>
</select>
</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>
</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="descriptionTrafficRuleInput" class="form-control" placeholder="" name="descriptionTrafficRuleInput">
</div>
</div>
<div class="col-1">
<i class="far fa-sm fa-question-circle" title='Enter in a description for this rule.'></i>
</div>
</div>
<div class="row">
<label class="col-3 col-form-label text-right">Source: </label>
<div class="col-7">
<div class="form-group">
<input type="text" id="sourceTrafficRuleInput" class="form-control" placeholder="" name="sourceTrafficRuleInput">
</div>
</div>
<div class="col-1">
<i class="far fa-sm fa-question-circle" title='Enter in a comma separated list of CIDR address, IP ranges, source ACL names, @external, or @internal. Leaving this unset will default to any.'></i>
</div>
</div>
<div class="row">
<label class="col-3 col-form-label text-right">Destination: </label>
<div class="col-7">
<div class="form-group">
<input type="text" id="destinationTrafficRuleInput" class="form-control" placeholder="" name="destinationTrafficRuleInput">
</div>
</div>
<div class="col-1">
<i class="far fa-sm fa-question-circle" title='Enter in a comma separated list of CIDR address, IP ranges, source ACL names, @external, or @internal. Leaving this unset will default to any.'></i>
</div>
</div>
<div class="row">
<label class="col-3 col-form-label text-right">Protocol: </label>
<div class="col-7">
<div class="form-group">
<select id="protocolTrafficRuleInput" onchange="" class="form-control" name="protocolTrafficRuleInput">
<option value="">(not set)</option>
<option value="icmp4">icmp4</option>
<option value="icmp6">icmp6</option>
<option value="tcp">tcp</option>
<option value="udp">udp</option>
</select>
</div>
</div>
<div class="col-1">
<i class="far fa-sm fa-question-circle" title='Select the traffic protocl for this rule. Leaving this unset will default to any.'></i>
</div>
</div>
<div class="row">
<label class="col-3 col-form-label text-right">Source Port: </label>
<div class="col-7">
<div class="form-group">
<input type="text" id="sourcePortTrafficRuleInput" class="form-control" placeholder="" name="sourcePortTrafficRuleInput">
</div>
</div>
<div class="col-1">
<i class="far fa-sm fa-question-circle" title='Used with TCP or UDP rules. Enter in a comma seperated list of ports or port ranges. Leaving this unset will default to any.'></i>
</div>
</div>
<div class="row">
<label class="col-3 col-form-label text-right">Destination Port: </label>
<div class="col-7">
<div class="form-group">
<input type="text" id="destinationPortTrafficRuleInput" class="form-control" placeholder="" name="destinationPortTrafficRuleInput">
</div>
</div>
<div class="col-1">
<i class="far fa-sm fa-question-circle" title='Used with TCP or UDP rules. Enter in a comma seperated list of ports or port ranges. Leaving this unset will default to any.'></i>
</div>
</div>
<div class="row">
<label class="col-3 col-form-label text-right">ICMP Type: </label>
<div class="col-7">
<div class="form-group">
<input type="text" id="icmpTypeTrafficRuleInput" class="form-control" placeholder="" name="icmpTypeTrafficRuleInput">
</div>
</div>
<div class="col-1">
<i class="far fa-sm fa-question-circle" title='Used with ICMP rules. Enter in an ICMP type number. Leaving this unset will default to any.'></i>
</div>
</div>
<div class="row">
<label class="col-3 col-form-label text-right">ICMP Code: </label>
<div class="col-7">
<div class="form-group">
<input type="text" id="icmpCodeTrafficRuleInput" class="form-control" placeholder="" name="icmpCodeTrafficRuleInput">
</div>
</div>
<div class="col-1">
<i class="far fa-sm fa-question-circle" title='Used with ICMP rules. Enter in an ICMP code number. Leaving this unset will default to any.'></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="addTrafficRule()" 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');
const networkAcl = urlParams.get('network_acl');
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'
}
});
$('#ingressListTable').DataTable().ajax.reload(null, false);
}
function loadPageContent(){
//Display current logged in username
$("#username").load("./php/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",
columns: [
{},
{ title: "Action" },
{ title: "State" },
{ title: "Description" },
{ title: "Source" },
{ title: "Destination" },
{ title: "Protocol" },
{ title: "Source Port" },
{ title: "Destination Port" },
{ title: "ICMP Type" },
{ title: "ICMP Code" },
{ title: "Actions" }
],
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 addTrafficRule(){
var typeTrafficRuleInput = "ingress";
var actionTrafficRuleInput = $("#actionTrafficRuleInput").val();
var stateTrafficRuleInput = $("#stateTrafficRuleInput").val();
var descriptionTrafficRuleInput = $("#descriptionTrafficRuleInput").val();
var sourceTrafficRuleInput = $("#sourceTrafficRuleInput").val();
var destinationTrafficRuleInput = $("#destinationTrafficRuleInput").val();
var protocolTrafficRuleInput = $("#protocolTrafficRuleInput").val();
var sourcePortTrafficRuleInput = $("#sourcePortTrafficRuleInput").val();
var destinationPortTrafficRuleInput = $("#destinationPortTrafficRuleInput").val();
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) {
//Sync operation type
var operationData = JSON.parse(data);
console.log(operationData);
if (operationData.error_code >= 400){
alert(operationData.error);
}
setTimeout(() => { reloadPageContent(); }, 1000);
});
}
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) {
//Sync 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));
$('#networkAclsBreadCrumb').text("network-acls");
$('#networkAclsBreadCrumb').attr("href", "network-acls.html?remote=" + encodeURI(remoteId) + "&project=" + encodeURI(projectName));
$('#networkAclBreadCrumb').text(networkAcl);
//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>

View file

@ -234,18 +234,25 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
<label class="col-3 col-form-label text-right">Name: </label>
<div class="col-7">
<div class="form-group">
<input type="text" id="networkAclNameCreate" class="form-control" placeholder="Network ACL Name" name="network_acl_name">
<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>
</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="networkAclDescriptionCreate" class="form-control" placeholder="Enter Description" name="network_acl_description">
<input type="text" id="networkAclDescriptionCreate" class="form-control" placeholder="" name="network_acl_description">
</div>
</div>
<div class="col-1">
<i class="far fa-sm fa-question-circle" title='Enter a description for the Network ACL'></i>
</div>
</div>
<p class="text-center pt-2">Egress and Ingress rules can be defined once the Network ACL is created.</p>
<div class="modal-footer">
<button class="btn btn-secondary" type="button" data-dismiss="modal">Cancel</button>
<a class="btn btn-primary" href="#" onclick="createNetworkAclUsingForm()" data-dismiss="modal">Submit</a>
@ -321,6 +328,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
<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>
</div>
</div>
<input type="hidden" id ="networkAclToRename" name="networkAclToRename">
</div>
@ -437,8 +447,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
{},
{ title: "Name" },
{ title: "Description" },
{ title: "Ingress Configured" },
{ title: "Egress Configured" },
{ title: "Ingress Rules" },
{ title: "Egress Rules" },
{ title: "Used By" },
{ title: "Action" }
],

File diff suppressed because it is too large Load diff

View file

@ -72,16 +72,22 @@ if (!isset($_SESSION)) {
-- updateImage
- /admin/php/lxd/instances-single.php
-- addInstanceDiskDevice
-- addInstanceNetworkDevice
-- addInstanceProxyDevice
-- displayInstanceInfo
-- displayInstanceStateInfo
-- establishInstanceWebSocketConsoleConnection
-- establishInstanceWebSocketExecConnection
-- listInstanceBackups
-- listInstanceDiskDevices
-- listInstanceInterfaces
-- listInstanceLogs
-- listInstanceNetworkDevices
-- listInstanceProfiles
-- listInstanceProxyDevices
-- listInstanceSnapshots
-- removeInstanceDevice
-- retrieveInstanceState
-- retrieveHostAndPort
-- updateInstanceBootConfiguration
@ -123,9 +129,14 @@ if (!isset($_SESSION)) {
-- updateInstanceInformation
- /admin/php/lxd/network-acls.php
-- addTrafficRule
-- createNetworkAclUsingForm
-- createNetworkAclUsingJSON
-- deleteEgressRule
-- deleteIngressRule
-- deleteNetworkAcl
-- listEgressRules
-- listIngressRules
-- listNetworkAcls
-- loadNetworkAcl
-- renameNetworkAcl
@ -136,6 +147,7 @@ if (!isset($_SESSION)) {
-- createNetworkUsingJSON
-- deleteNetwork
-- listNetworks
-- listNetworksForSelectOption
-- loadNetwork
-- renameNetwork
-- updateNetwork
@ -183,20 +195,18 @@ if (!isset($_SESSION)) {
-- listRemotes
-- listRemotesForTopNavigation
- /admin/php/lxd/simplestreams.php
-- addSimplestreams
-- deleteSimplestreams
-- listSimplestreams
-- listSimplestreamsForSelectOption
- /admin/php/lxd/storage-pools.php
-- createStoragePoolUsingForm
-- createStoragePoolUsingJSON
-- deleteStoragePool
-- listStoragePools
-- listStoragePoolsForSelectOption
-- loadStoragePool
-- updateStoragePool
@ -205,6 +215,7 @@ if (!isset($_SESSION)) {
-- createStorageVolumeUsingJSON
-- deleteStorageVolume
-- listStorageVolumes
-- listStorageVolumesForSelectOption
-- loadStorageVolume
-- updateStorageVolume
@ -274,16 +285,22 @@ function getControls($roles){
"loadImage",
"refreshImage",
"updateImage",
"addInstanceDiskDevice",
"addInstanceNetworkDevice",
"addInstanceProxyDevice",
"displayInstanceInfo",
"displayInstanceStateInfo",
"establishInstanceWebSocketConsoleConnection",
"establishInstanceWebSocketExecConnection",
"listInstanceBackups",
"listInstanceDiskDevices",
"listInstanceInterfaces",
"listInstanceLogs",
"listInstanceNetworkDevices",
"listInstanceProfiles",
"listInstanceProxyDevices",
"listInstanceSnapshots",
"removeInstanceDevice",
"retrieveInstanceState",
"retrieveHostAndPort",
"updateInstanceBootConfiguration",
@ -321,9 +338,14 @@ function getControls($roles){
"stopInstanceForcefully",
"unfreezeInstance",
"updateInstanceInformation",
"addTrafficRule",
"createNetworkAclUsingForm",
"createNetworkAclUsingJSON",
"deleteEgressRule",
"deleteIngressRule",
"deleteNetworkAcl",
"listEgressRules",
"listIngressRules",
"listNetworkAcls",
"loadNetworkAcl",
"renameNetworkAcl",
@ -332,6 +354,7 @@ function getControls($roles){
"createNetworkUsingJSON",
"deleteNetwork",
"listNetworks",
"listNetworksForSelectOption",
"loadNetwork",
"renameNetwork",
"updateNetwork",
@ -376,12 +399,14 @@ function getControls($roles){
"createStoragePoolUsingJSON",
"deleteStoragePool",
"listStoragePools",
"listStoragePoolsForSelectOption",
"loadStoragePool",
"updateStoragePool",
"createStorageVolumeUsingForm",
"createStorageVolumeUsingJSON",
"deleteStorageVolume",
"listStorageVolumes",
"listStorageVolumesForSelectOption",
"loadStorageVolume",
"updateStorageVolume"
);
@ -416,16 +441,22 @@ function getControls($roles){
"loadImage",
"refreshImage",
"updateImage",
"addInstanceDiskDevice",
"addInstanceNetworkDevice",
"addInstanceProxyDevice",
"displayInstanceInfo",
"displayInstanceStateInfo",
"establishInstanceWebSocketConsoleConnection",
"establishInstanceWebSocketExecConnection",
"listInstanceBackups",
"listInstanceDiskDevices",
"listInstanceInterfaces",
"listInstanceLogs",
"listInstanceNetworkDevices",
"listInstanceProfiles",
"listInstanceProxyDevices",
"listInstanceSnapshots",
"removeInstanceDevice",
"retrieveInstanceState",
"retrieveHostAndPort",
"updateInstanceBootConfiguration",
@ -463,9 +494,14 @@ function getControls($roles){
"stopInstanceForcefully",
"unfreezeInstance",
"updateInstanceInformation",
"addTrafficRule",
"createNetworkAclUsingForm",
"createNetworkAclUsingJSON",
"deleteEgressRule",
"deleteIngressRule",
"deleteNetworkAcl",
"listEgressRules",
"listIngressRules",
"listNetworkAcls",
"loadNetworkAcl",
"renameNetworkAcl",
@ -474,6 +510,7 @@ function getControls($roles){
"createNetworkUsingJSON",
"deleteNetwork",
"listNetworks",
"listNetworksForSelectOption",
"loadNetwork",
"renameNetwork",
"updateNetwork",
@ -518,12 +555,14 @@ function getControls($roles){
"createStoragePoolUsingJSON",
"deleteStoragePool",
"listStoragePools",
"listStoragePoolsForSelectOption",
"loadStoragePool",
"updateStoragePool",
"createStorageVolumeUsingForm",
"createStorageVolumeUsingJSON",
"deleteStorageVolume",
"listStorageVolumes",
"listStorageVolumesForSelectOption",
"loadStorageVolume",
"updateStorageVolume"
);
@ -555,6 +594,7 @@ function getControls($roles){
"establishInstanceWebSocketConsoleConnection",
"listInstanceBackups",
"listInstanceDiskDevices",
"listInstanceInterfaces",
"listInstanceLogs",
"listInstanceNetworkDevices",
"listInstanceProfiles",
@ -579,9 +619,12 @@ function getControls($roles){
"stopInstance",
"stopInstanceForcefully",
"unfreezeInstance",
"listEgressRules",
"listIngressRules",
"listNetworkAcls",
"loadNetworkAcl",
"listNetworks",
"listNetworksForSelectOption",
"loadNetwork",
"displayOperationStatus",
"listOperations",
@ -607,8 +650,10 @@ function getControls($roles){
"listSimplestreams",
"listSimplestreamsForSelectOption",
"listStoragePools",
"listStoragePoolsForSelectOption",
"loadStoragePool",
"listStorageVolumes",
"listStorageVolumesForSelectOption",
"loadStorageVolume"
);
$controls = array_merge($controls, $user_controls);
@ -636,6 +681,7 @@ function getControls($roles){
"displayInstanceStateInfo",
"listInstanceBackups",
"listInstanceDiskDevices",
"listInstanceInterfaces",
"listInstanceLogs",
"listInstanceNetworkDevices",
"listInstanceProfiles",
@ -649,9 +695,12 @@ function getControls($roles){
"listInstancesForSelectOption",
"loadInstanceInformation",
"loadInstanceLog",
"listEgressRules",
"listIngressRules",
"listNetworkAcls",
"loadNetworkAcl",
"listNetworks",
"listNetworksForSelectOption",
"loadNetwork",
"displayOperationStatus",
"listOperations",
@ -677,8 +726,10 @@ function getControls($roles){
"listSimplestreams",
"listSimplestreamsForSelectOption",
"listStoragePools",
"listStoragePoolsForSelectOption",
"loadStoragePool",
"listStorageVolumes",
"listStorageVolumesForSelectOption",
"loadStorageVolume"
);
$controls = array_merge($controls, $auditor_controls);

View file

@ -27,9 +27,74 @@ if (isset($_SESSION['username'])) {
//Declare and instantiate GET variables
$action = (isset($_GET['action'])) ? filter_var(urldecode($_GET['action']), FILTER_SANITIZE_STRING) : "";
$bind = (isset($_GET['bind'])) ? filter_var(urldecode($_GET['bind']), FILTER_SANITIZE_STRING) : "";
$boot_priority = (isset($_GET['boot_priority'])) ? filter_var(urldecode($_GET['boot_priority']), FILTER_SANITIZE_NUMBER_INT) : "";
$ceph_cluster_name = (isset($_GET['ceph_cluster_name'])) ? filter_var(urldecode($_GET['ceph_cluster_name']), FILTER_SANITIZE_STRING) : "";
$ceph_user_name = (isset($_GET['ceph_user_name'])) ? filter_var(urldecode($_GET['ceph_user_name']), FILTER_SANITIZE_STRING) : "";
$connect = (isset($_GET['connect'])) ? filter_var(urldecode($_GET['connect']), FILTER_SANITIZE_STRING) : "";
$gid = (isset($_GET['gid'])) ? filter_var(urldecode($_GET['gid']), FILTER_SANITIZE_NUMBER_INT) : "";
$gvrp = (isset($_GET['gvrp'])) ? filter_var(urldecode($_GET['gvrp']), FILTER_SANITIZE_STRING) : "";
$hwaddr = (isset($_GET['hwaddr'])) ? filter_var(urldecode($_GET['hwaddr']), FILTER_SANITIZE_STRING) : "";
$instance = (isset($_GET['instance'])) ? filter_var(urldecode($_GET['instance']), FILTER_SANITIZE_STRING) : "";
$interface_name = (isset($_GET['interface_name'])) ? filter_var(urldecode($_GET['interface_name']), FILTER_SANITIZE_STRING) : "";
$ipv4_address = (isset($_GET['ipv4_address'])) ? filter_var(urldecode($_GET['ipv4_address']), FILTER_SANITIZE_STRING) : "";
$ipv4_gateway = (isset($_GET['ipv4_gateway'])) ? filter_var(urldecode($_GET['ipv4_gateway']), FILTER_SANITIZE_STRING) : "";
$ipv4_host_address = (isset($_GET['ipv4_host_address'])) ? filter_var(urldecode($_GET['ipv4_host_address']), FILTER_SANITIZE_STRING) : "";
$ipv4_host_table = (isset($_GET['ipv4_host_table'])) ? filter_var(urldecode($_GET['ipv4_host_table']), FILTER_SANITIZE_NUMBER_INT) : "";
$ipv4_routes = (isset($_GET['ipv4_routes'])) ? filter_var(urldecode($_GET['ipv4_routes']), FILTER_SANITIZE_STRING) : "";
$ipv4_routes_external = (isset($_GET['ipv4_routes_external'])) ? filter_var(urldecode($_GET['ipv4_routes_external']), FILTER_SANITIZE_STRING) : "";
$ipv6_address = (isset($_GET['ipv6_address'])) ? filter_var(urldecode($_GET['ipv6_address']), FILTER_SANITIZE_STRING) : "";
$ipv6_gateway = (isset($_GET['ipv6_gateway'])) ? filter_var(urldecode($_GET['ipv6_gateway']), FILTER_SANITIZE_STRING) : "";
$ipv6_host_address = (isset($_GET['ipv6_host_address'])) ? filter_var(urldecode($_GET['ipv6_host_address']), FILTER_SANITIZE_STRING) : "";
$ipv6_host_table = (isset($_GET['ipv6_host_table'])) ? filter_var(urldecode($_GET['ipv6_host_table']), FILTER_SANITIZE_NUMBER_INT) : "";
$ipv6_routes = (isset($_GET['ipv6_routes'])) ? filter_var(urldecode($_GET['ipv6_routes']), FILTER_SANITIZE_STRING) : "";
$ipv6_routes_external = (isset($_GET['ipv6_routes_external'])) ? filter_var(urldecode($_GET['ipv6_routes_external']), FILTER_SANITIZE_STRING) : "";
$limits_ingress = (isset($_GET['limits_ingress'])) ? filter_var(urldecode($_GET['limits_ingress']), FILTER_SANITIZE_STRING) : "";
$limits_egress = (isset($_GET['limits_egress'])) ? filter_var(urldecode($_GET['limits_egress']), FILTER_SANITIZE_STRING) : "";
$limits_max = (isset($_GET['limits_max'])) ? filter_var(urldecode($_GET['limits_max']), FILTER_SANITIZE_STRING) : "";
$limits_read = (isset($_GET['limits_read'])) ? filter_var(urldecode($_GET['limits_read']), FILTER_SANITIZE_STRING) : "";
$limits_write = (isset($_GET['limits_write'])) ? filter_var(urldecode($_GET['limits_write']), FILTER_SANITIZE_STRING) : "";
$listen = (isset($_GET['listen'])) ? filter_var(urldecode($_GET['listen']), FILTER_SANITIZE_STRING) : "";
$maas_subnet_ipv4 = (isset($_GET['maas_subnet_ipv4'])) ? filter_var(urldecode($_GET['maas_subnet_ipv4']), FILTER_SANITIZE_STRING) : "";
$maas_subnet_ipv6 = (isset($_GET['maas_subnet_ipv6'])) ? filter_var(urldecode($_GET['maas_subnet_ipv6']), FILTER_SANITIZE_STRING) : "";
$mode = (isset($_GET['mode'])) ? filter_var(urldecode($_GET['mode']), FILTER_SANITIZE_NUMBER_INT) : "";
$mtu = (isset($_GET['mtu'])) ? filter_var(urldecode($_GET['mtu']), FILTER_SANITIZE_NUMBER_INT) : "";
$name = (isset($_GET['name'])) ? filter_var(urldecode($_GET['name']), FILTER_SANITIZE_STRING) : "";
$nat = (isset($_GET['nat'])) ? filter_var(urldecode($_GET['nat']), FILTER_SANITIZE_STRING) : "";
$network = (isset($_GET['network'])) ? filter_var(urldecode($_GET['network']), FILTER_SANITIZE_STRING) : "";
$nictype = (isset($_GET['nictype'])) ? filter_var(urldecode($_GET['nictype']), 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) : "";
$pool = (isset($_GET['pool'])) ? filter_var(urldecode($_GET['pool']), FILTER_SANITIZE_STRING) : "";
$source = (isset($_GET['source'])) ? filter_var(urldecode($_GET['source']), FILTER_SANITIZE_STRING) : "";
$parent = (isset($_GET['parent'])) ? filter_var(urldecode($_GET['parent']), FILTER_SANITIZE_STRING) : "";
$parent_type = (isset($_GET['parent_type'])) ? filter_var(urldecode($_GET['parent_type']), FILTER_SANITIZE_STRING) : "";
$path = (isset($_GET['path'])) ? filter_var(urldecode($_GET['path']), FILTER_SANITIZE_STRING) : "";
$propagation = (isset($_GET['propagation'])) ? filter_var(urldecode($_GET['propagation']), FILTER_SANITIZE_STRING) : "";
$property_set = (isset($_GET['property_set'])) ? filter_var(urldecode($_GET['property_set']), FILTER_SANITIZE_STRING) : "";
$proxy_protocol = (isset($_GET['proxy_protocol'])) ? filter_var(urldecode($_GET['proxy_protocol']), FILTER_SANITIZE_STRING) : "";
$required = (isset($_GET['required'])) ? filter_var(urldecode($_GET['required']), FILTER_SANITIZE_STRING) : "";
$read_only = (isset($_GET['read_only'])) ? filter_var(urldecode($_GET['read_only']), FILTER_SANITIZE_STRING) : "";
$size = (isset($_GET['size'])) ? filter_var(urldecode($_GET['size']), FILTER_SANITIZE_STRING) : "";
$size_state = (isset($_GET['size_state'])) ? filter_var(urldecode($_GET['size_state']), FILTER_SANITIZE_STRING) : "";
$raw_mount_options = (isset($_GET['raw_mount_options'])) ? filter_var(urldecode($_GET['raw_mount_options']), FILTER_SANITIZE_STRING) : "";
$recursive = (isset($_GET['recursive'])) ? filter_var(urldecode($_GET['recursive']), FILTER_SANITIZE_STRING) : "";
$security_acls = (isset($_GET['security_acls'])) ? filter_var(urldecode($_GET['security_acls']), FILTER_SANITIZE_STRING) : "";
$security_acls_default_egress_action = (isset($_GET['security_acls_default_egress_action'])) ? filter_var(urldecode($_GET['security_acls_default_egress_action']), FILTER_SANITIZE_STRING) : "";
$security_acls_default_egress_logged = (isset($_GET['security_acls_default_egress_logged'])) ? filter_var(urldecode($_GET['security_acls_default_egress_logged']), FILTER_SANITIZE_STRING) : "";
$security_acls_default_ingress_action = (isset($_GET['security_acls_default_ingress_action'])) ? filter_var(urldecode($_GET['security_acls_default_ingress_action']), FILTER_SANITIZE_STRING) : "";
$security_acls_default_ingress_logged = (isset($_GET['security_acls_default_ingress_logged'])) ? filter_var(urldecode($_GET['security_acls_default_ingress_logged']), FILTER_SANITIZE_STRING) : "";
$security_gid = (isset($_GET['security_gid'])) ? filter_var(urldecode($_GET['security_gid']), FILTER_SANITIZE_NUMBER_INT) : "";
$security_ipv4_filtering = (isset($_GET['security_ipv4_filtering'])) ? filter_var(urldecode($_GET['security_ipv4_filtering']), FILTER_SANITIZE_STRING) : "";
$security_ipv6_filtering = (isset($_GET['security_ipv6_filtering'])) ? filter_var(urldecode($_GET['security_ipv6_filtering']), FILTER_SANITIZE_STRING) : "";
$security_mac_filtering = (isset($_GET['security_mac_filtering'])) ? filter_var(urldecode($_GET['security_mac_filtering']), FILTER_SANITIZE_STRING) : "";
$security_port_isolation = (isset($_GET['security_port_isolation'])) ? filter_var(urldecode($_GET['security_port_isolation']), FILTER_SANITIZE_STRING) : "";
$security_uid = (isset($_GET['security_uid'])) ? filter_var(urldecode($_GET['security_uid']), FILTER_SANITIZE_NUMBER_INT) : "";
$shell = (isset($_GET['shell'])) ? filter_var(urldecode($_GET['shell']), FILTER_SANITIZE_STRING) : "";
$shift = (isset($_GET['shift'])) ? filter_var(urldecode($_GET['shift']), FILTER_SANITIZE_STRING) : "";
$uid = (isset($_GET['uid'])) ? filter_var(urldecode($_GET['uid']), FILTER_SANITIZE_NUMBER_INT) : "";
$vlan = (isset($_GET['vlan'])) ? filter_var(urldecode($_GET['vlan']), FILTER_SANITIZE_NUMBER_INT) : "";
$vlan_tagged = (isset($_GET['vlan_tagged'])) ? filter_var(urldecode($_GET['vlan_tagged']), FILTER_SANITIZE_NUMBER_INT) : "";
//Declare and instantiate POST variables
$boot_autostart = (isset($_POST['boot_autostart'])) ? filter_var(urldecode($_POST['boot_autostart']), FILTER_SANITIZE_STRING) : "";
@ -70,6 +135,301 @@ if (isset($_SESSION['username'])) {
$base_url = retrieveHostURL($remote);
switch ($action) {
case "addInstanceDiskDevice":
$url = $base_url . "/1.0/instances/" . $instance . "?project=" . $project;
$results = sendCurlRequest($action, "GET", $url);
$data = json_decode($results, true);
$data = $data['metadata'];
//Before applying PATCH, check to make sure device does not already exists.
if (isset($data['devices'][$name])){
echo '{"type": "error","error": "Unable to add new device. Device name already exists","error_code": 409,"metadata": {"error": "Unable to add new device. Device name already exists"}}';
}
else {
$url = $base_url . "/1.0/instances/" . $instance . "?project=" . $project;
$device_array = array();
$device_array['type'] = "disk";
$device_array['path'] = $path;
$device_array['source'] = $source;
if (!empty($pool)){ $device_array['pool'] = $pool;}
if (!empty($limits_read)){ $device_array['limits.read'] = $limits_read;}
if (!empty($limits_write)){ $device_array['limits.write'] = $limits_write;}
if (!empty($limits_max)){ $device_array['limits.max'] = $limits_max;}
if (!empty($required)){ $device_array['required'] = $required;}
if (!empty($read_only)){ $device_array['readonly'] = $read_only;}
if (!empty($size)){ $device_array['size'] = $size;}
if (!empty($size_state)){ $device_array['size.state'] = $size_state;}
if (!empty($recursive)){ $device_array['recursive'] = $recursive;}
if (!empty($propagation)){ $device_array['propagation'] = $propagation;}
if (!empty($shift)){ $device_array['shift'] = $shift;}
if (!empty($raw_mount_options)){ $device_array['raw.mount.options'] = $raw_mount_options;}
if (!empty($ceph_user_name)){ $device_array['ceph.user_name'] = $ceph_user_name;}
if (!empty($ceph_cluster_name)){ $device_array['ceph.cluster_name'] = $ceph_cluster_name;}
if (!empty($boot_priority)){ $device_array['boot.priority'] = $boot_priority;}
$device_json = json_encode($device_array);
$data = '{"devices": {"'.$name.'": '.$device_json.'}}';
$results = sendCurlRequest($action, "PATCH", $url, $data);
echo $results;
//Send event to accounting
$event = json_decode($results, true);
$object = $instance . " - " . $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;
case "addInstanceNetworkDevice":
$url = $base_url . "/1.0/instances/" . $instance . "?project=" . $project;
$results = sendCurlRequest($action, "GET", $url);
$data = json_decode($results, true);
$data = $data['metadata'];
//Before applying PATCH, check to make sure device does not already exists.
if (isset($data['devices'][$name])){
echo '{"type": "error","error": "Unable to add new device. Device name already exists","error_code": 409,"metadata": {"error": "Unable to add new device. Device name already exists"}}';
}
else {
$url = $base_url . "/1.0/instances/" . $instance . "?project=" . $project;
$device_array = array();
$device_array['type'] = "nic";
if ($property_set == "network"){
if ($parent_type == "bridge"){
$device_array['network'] = $network;
if (!empty($interface_name)){ $device_array['name'] = $interface_name;}
if (!empty($hwaddr)){ $device_array['hwaddr'] = $hwaddr;}
if (!empty($host_name)){ $device_array['host_name'] = $host_name;}
if (!empty($limits_ingress)){ $device_array['limits.ingress'] = $limits_ingress;}
if (!empty($limits_egress)){ $device_array['limits.egress'] = $limits_egress;}
if (!empty($limits_max)){ $device_array['limits.max'] = $limits_max;}
if (!empty($ipv4_address)){ $device_array['ipv4.address'] = $ipv4_address;}
if (!empty($ipv4_routes)){ $device_array['ipv4.routes'] = $ipv4_routes;}
if (!empty($ipv6_address)){ $device_array['ipv6.address'] = $ipv6_address;}
if (!empty($ipv6_routes)){ $device_array['ipv6.routes'] = $ipv6_routes;}
if (!empty($security_mac_filtering)){ $device_array['security.mac_filtering'] = $security_mac_filtering;}
if (!empty($security_ipv4_filtering)){ $device_array['security.ipv4_filtering'] = $security_ipv4_filtering;}
if (!empty($security_ipv6_filtering)){ $device_array['security.ipv6_filtering'] = $security_ipv6_filtering;}
if (!empty($boot_priority)){ $device_array['boot.priority'] = $boot_priority;}
if (!empty($vlan)){ $device_array['vlan'] = $vlan;}
if (!empty($vlan_tagged)){ $device_array['vlan.tagged'] = $vlan_tagged;}
if (!empty($security_port_isolation)){ $device_array['security.port_isolation'] = $security_port_isolation;}
}
if ($parent_type == "macvlan"){
$device_array['network'] = $network;
if (!empty($interface_name)){ $device_array['name'] = $interface_name;}
if (!empty($hwaddr)){ $device_array['hwaddr'] = $hwaddr;}
if (!empty($boot_priority)){ $device_array['boot.priority'] = $boot_priority;}
if (!empty($vlan)){ $device_array['vlan'] = $vlan;}
if (!empty($gvrp)){ $device_array['gvrp'] = $gvrp;}
}
if ($parent_type == "ovn"){
$device_array['network'] = $network;
if (!empty($interface_name)){ $device_array['name'] = $interface_name;}
if (!empty($host_name)){ $device_array['host_name'] = $host_name;}
if (!empty($hwaddr)){ $device_array['hwaddr'] = $hwaddr;}
if (!empty($ipv4_address)){ $device_array['ipv4.address'] = $ipv4_address;}
if (!empty($ipv6_address)){ $device_array['ipv6.address'] = $ipv6_address;}
if (!empty($ipv4_routes)){ $device_array['ipv4.routes'] = $ipv4_routes;}
if (!empty($ipv4_routes_external)){ $device_array['ipv4.routes.external'] = $ipv4_routes_external;}
if (!empty($ipv6_routes)){ $device_array['ipv6.routes'] = $ipv6_routes;}
if (!empty($ipv6_routes_external)){ $device_array['ipv6.routes.external'] = $ipv6_routes_external;}
if (!empty($boot_priority)){ $device_array['boot.priority'] = $boot_priority;}
if (!empty($security_acls)){ $device_array['security.acls'] = $security_acls;}
if (!empty($security_acls_default_ingress_action)){ $device_array['security.acls.default.ingress.action'] = $security_acls_default_ingress_action;}
if (!empty($security_acls_default_egress_action)){ $device_array['security.acls.default.egress.action'] = $security_acls_default_egress_action;}
if (!empty($security_acls_default_ingress_logged)){ $device_array['security.acls.default.ingress.logged'] = $security_acls_default_ingress_logged;}
if (!empty($security_acls_default_egress_logged)){ $device_array['security.acls.default.egress.logged'] = $security_acls_default_egress_logged;}
}
if ($parent_type == "sriov"){
$device_array['network'] = $network;
if (!empty($interface_name)){ $device_array['name'] = $interface_name;}
if (!empty($hwaddr)){ $device_array['hwaddr'] = $hwaddr;}
if (!empty($boot_priority)){ $device_array['boot.priority'] = $boot_priority;}
if (!empty($vlan)){ $device_array['vlan'] = $vlan;}
if (!empty($security_mac_filtering)){ $device_array['security.mac_filtering'] = $security_mac_filtering;}
}
}
if ($property_set == "nictype"){
$device_array['nictype'] = $nictype;
if ($nictype == "bridged"){
$device_array['parent'] = $parent;
if (!empty($interface_name)){ $device_array['name'] = $interface_name;}
if (!empty($mtu)){ $device_array['mtu'] = $mtu;}
if (!empty($hwaddr)){ $device_array['hwaddr'] = $hwaddr;}
if (!empty($host_name)){ $device_array['host_name'] = $host_name;}
if (!empty($limits_ingress)){ $device_array['limits.ingress'] = $limits_ingress;}
if (!empty($limits_egress)){ $device_array['limits.egress'] = $limits_egress;}
if (!empty($limits_max)){ $device_array['limits.max'] = $limits_max;}
if (!empty($ipv4_address)){ $device_array['ipv4.address'] = $ipv4_address;}
if (!empty($ipv4_routes)){ $device_array['ipv4.routes'] = $ipv4_routes;}
if (!empty($ipv6_address)){ $device_array['ipv6.address'] = $ipv6_address;}
if (!empty($ipv6_routes)){ $device_array['ipv6.routes'] = $ipv6_routes;}
if (!empty($security_mac_filtering)){ $device_array['security.mac_filtering'] = $security_mac_filtering;}
if (!empty($security_ipv4_filtering)){ $device_array['security.ipv4_filtering'] = $security_ipv4_filtering;}
if (!empty($security_ipv6_filtering)){ $device_array['security.ipv6_filtering'] = $security_ipv6_filtering;}
if (!empty($maas_subnet_ipv4)){ $device_array['maas.subnet.ipv4'] = $maas_subnet_ipv4;}
if (!empty($maas_subnet_ipv6)){ $device_array['maas.subnet.ipv6'] = $maas_subnet_ipv6;}
if (!empty($boot_priority)){ $device_array['boot.priority'] = $boot_priority;}
if (!empty($vlan)){ $device_array['vlan'] = $vlan;}
if (!empty($vlan_tagged)){ $device_array['vlan.tagged'] = $vlan_tagged;}
if (!empty($security_port_isolation)){ $device_array['security.port_isolation'] = $security_port_isolation;}
}
if ($nictype == "ipvlan"){
$device_array['parent'] = $parent;
if (!empty($interface_name)){ $device_array['name'] = $interface_name;}
if (!empty($mtu)){ $device_array['mtu'] = $mtu;}
if (!empty($mode)){ $device_array['mode'] = $mode;}
if (!empty($hwaddr)){ $device_array['hwaddr'] = $hwaddr;}
if (!empty($ipv4_address)){ $device_array['ipv4.address'] = $ipv4_address;}
if (!empty($ipv4_gateway)){ $device_array['ipv4.gateway'] = $ipv4_gateway;}
if (!empty($ipv4_host_table)){ $device_array['ipv4.host_table'] = $ipv4_host_table;}
if (!empty($ipv6_address)){ $device_array['ipv6.address'] = $ipv6_address;}
if (!empty($ipv6_gateway)){ $device_array['ipv6.gateway'] = $ipv6_gateway;}
if (!empty($ipv6_host_table)){ $device_array['ipv6.host_table'] = $ipv6_host_table;}
if (!empty($vlan)){ $device_array['vlan'] = $vlan;}
if (!empty($gvrp)){ $device_array['gvrp'] = $gvrp;}
}
if ($nictype == "macvlan"){
$device_array['parent'] = $parent;
if (!empty($interface_name)){ $device_array['name'] = $interface_name;}
if (!empty($mtu)){ $device_array['mtu'] = $mtu;}
if (!empty($hwaddr)){ $device_array['hwaddr'] = $hwaddr;}
if (!empty($maas_subnet_ipv4)){ $device_array['maas.subnet.ipv4'] = $maas_subnet_ipv4;}
if (!empty($maas_subnet_ipv6)){ $device_array['maas.subnet.ipv6'] = $maas_subnet_ipv6;}
if (!empty($boot_priority)){ $device_array['boot.priority'] = $boot_priority;}
if (!empty($vlan)){ $device_array['vlan'] = $vlan;}
if (!empty($gvrp)){ $device_array['gvrp'] = $gvrp;}
}
if ($nictype == "p2p"){
if (!empty($interface_name)){ $device_array['name'] = $interface_name;}
if (!empty($mtu)){ $device_array['mtu'] = $mtu;}
if (!empty($hwaddr)){ $device_array['hwaddr'] = $hwaddr;}
if (!empty($host_name)){ $device_array['host_name'] = $host_name;}
if (!empty($limits_ingress)){ $device_array['limits.ingress'] = $limits_ingress;}
if (!empty($limits_egress)){ $device_array['limits.egress'] = $limits_egress;}
if (!empty($limits_max)){ $device_array['limits.max'] = $limits_max;}
if (!empty($ipv4_routes)){ $device_array['ipv4.routes'] = $ipv4_routes;}
if (!empty($ipv6_routes)){ $device_array['ipv6.routes'] = $ipv6_routes;}
if (!empty($boot_priority)){ $device_array['boot.priority'] = $boot_priority;}
}
if ($nictype == "physical"){
$device_array['parent'] = $parent;
if (!empty($interface_name)){ $device_array['name'] = $interface_name;}
if (!empty($mtu)){ $device_array['mtu'] = $mtu;}
if (!empty($hwaddr)){ $device_array['hwaddr'] = $hwaddr;}
if (!empty($maas_subnet_ipv4)){ $device_array['maas.subnet.ipv4'] = $maas_subnet_ipv4;}
if (!empty($maas_subnet_ipv6)){ $device_array['maas.subnet.ipv6'] = $maas_subnet_ipv6;}
if (!empty($boot_priority)){ $device_array['boot.priority'] = $boot_priority;}
if (!empty($vlan)){ $device_array['vlan'] = $vlan;}
if (!empty($gvrp)){ $device_array['gvrp'] = $gvrp;}
}
if ($nictype == "routed"){
$device_array['parent'] = $parent;
if (!empty($interface_name)){ $device_array['name'] = $interface_name;}
if (!empty($mtu)){ $device_array['mtu'] = $mtu;}
if (!empty($hwaddr)){ $device_array['hwaddr'] = $hwaddr;}
if (!empty($host_name)){ $device_array['host_name'] = $host_name;}
if (!empty($limits_ingress)){ $device_array['limits.ingress'] = $limits_ingress;}
if (!empty($limits_egress)){ $device_array['limits.egress'] = $limits_egress;}
if (!empty($limits_max)){ $device_array['limits.max'] = $limits_max;}
if (!empty($ipv4_address)){ $device_array['ipv4.address'] = $ipv4_address;}
if (!empty($ipv4_gateway)){ $device_array['ipv4.gateway'] = $ipv4_gateway;}
if (!empty($ipv4_host_table)){ $device_array['ipv4.host_table'] = $ipv4_host_table;}
if (!empty($ipv4_host_address)){ $device_array['ipv4.host_address'] = $ipv4_host_address;}
if (!empty($ipv6_address)){ $device_array['ipv6.address'] = $ipv6_address;}
if (!empty($ipv6_gateway)){ $device_array['ipv6.gateway'] = $ipv6_gateway;}
if (!empty($ipv6_host_table)){ $device_array['ipv6.host_table'] = $ipv6_host_table;}
if (!empty($ipv6_host_address)){ $device_array['ipv6.host_address'] = $ipv6_host_address;}
if (!empty($vlan)){ $device_array['vlan'] = $vlan;}
if (!empty($gvrp)){ $device_array['gvrp'] = $gvrp;}
}
if ($nictype == "sriov"){
$device_array['parent'] = $parent;
if (!empty($interface_name)){ $device_array['name'] = $interface_name;}
if (!empty($mtu)){ $device_array['mtu'] = $mtu;}
if (!empty($hwaddr)){ $device_array['hwaddr'] = $hwaddr;}
if (!empty($maas_subnet_ipv4)){ $device_array['maas.subnet.ipv4'] = $maas_subnet_ipv4;}
if (!empty($maas_subnet_ipv6)){ $device_array['maas.subnet.ipv6'] = $maas_subnet_ipv6;}
if (!empty($boot_priority)){ $device_array['boot.priority'] = $boot_priority;}
if (!empty($vlan)){ $device_array['vlan'] = $vlan;}
if (!empty($security_mac_filtering)){ $device_array['security.mac_filtering'] = $security_mac_filtering;}
}
}
$device_json = json_encode($device_array);
$data = '{"devices": {"'.$name.'": '.$device_json.'}}';
$results = sendCurlRequest($action, "PATCH", $url, $data);
echo $results;
//Send event to accounting
$event = json_decode($results, true);
$object = $instance . " - " . $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;
case "addInstanceProxyDevice":
$url = $base_url . "/1.0/instances/" . $instance . "?project=" . $project;
$results = sendCurlRequest($action, "GET", $url);
$data = json_decode($results, true);
$data = $data['metadata'];
//Before applying PATCH, check to make sure device does not already exists.
if (isset($data['devices'][$name])){
echo '{"type": "error","error": "Unable to add new device. Device name already exists","error_code": 409,"metadata": {"error": "Unable to add new device. Device name already exists"}}';
}
else {
$url = $base_url . "/1.0/instances/" . $instance . "?project=" . $project;
$device_array = array();
$device_array['type'] = "proxy";
$device_array['listen'] = $listen;
$device_array['connect'] = $connect;
if (!empty($bind)){ $device_array['bind'] = $bind;}
if (!empty($uid)){ $device_array['uid'] = $uid;}
if (!empty($gid)){ $device_array['gid'] = $gid;}
if (!empty($mode)){ $device_array['mode'] = $mode;}
if (!empty($nat)){ $device_array['nat'] = $nat;}
if (!empty($proxy_protocol)){ $device_array['proxy_protocol'] = $proxy_protocol;}
if (!empty($security_uid)){ $device_array['security_uid'] = $security_uid;}
if (!empty($security_gid)){ $device_array['security_gid'] = $security_gid;}
$device_json = json_encode($device_array);
$data = '{"devices": {"'.$name.'": '.$device_json.'}}';
$results = sendCurlRequest($action, "PATCH", $url, $data);
echo $results;
//Send event to accounting
$event = json_decode($results, true);
$object = $instance . " - " . $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;
case "displayInstanceInfo":
$url = $base_url . "/1.0/instances/".$instance."?project=" . $project;
$results = sendCurlRequest($action, "GET", $url);
@ -265,10 +625,36 @@ if (isset($_SESSION['username'])) {
$results = sendCurlRequest($action, "POST", $url, $data);
$exec_api_data = json_decode($results, true);
$operation = $exec_api_data['operation']; //$operation = "/1.0/operations/d77f70b9-ae8d-4a47-9935-4d49d707f0aa";
$secret = $exec_api_data['metadata']['metadata']['fds']["0"]; //$secret = "64f5592ee1bc64b8b699e232371dd1286465bafa4a9e688ea7a9cc48f785e98e";
$operation = (isset($exec_api_data['operation'])) ? $exec_api_data['operation'] : ""; //$operation = "/1.0/operations/d77f70b9-ae8d-4a47-9935-4d49d707f0aa";
$secret = (isset($exec_api_data['metadata']['metadata']['fds']["0"])) ? $exec_api_data['metadata']['metadata']['fds']["0"] : ""; //$secret = "64f5592ee1bc64b8b699e232371dd1286465bafa4a9e688ea7a9cc48f785e98e";
$control = (isset($exec_api_data['metadata']['metadata']['fds']["control"])) ? $exec_api_data['metadata']['metadata']['fds']["control"] : ""; //used to close connection properly
$results = '{"operation": "'.$operation.'", "secret": "'.$secret.'"}';
$results = '{"operation": "'.$operation.'", "secret": "'.$secret.'", "control": "'.$control.'"}';
echo $results;
//Send event to accounting
$event = json_decode($results, true);
$object = $instance;
logEvent($action, $remote, $project, $object, '200', 'Ok');
break;
case "establishInstanceWebSocketExecConnection":
$url = $base_url . "/1.0/instances/".$instance."/exec?project=" . $project;
if ($shell == "sh"){
$data = '{ "command": ["/bin/sh"], "wait-for-websocket": true, "environment":{"HOME": "/root", "TERM": "xterm", "USER": "root"}, "interactive": true}';
}
else {
$data = '{ "command": ["/bin/bash"], "wait-for-websocket": true, "environment":{"HOME": "/root", "TERM": "xterm", "USER": "root"}, "interactive": true}';
}
$results = sendCurlRequest($action, "POST", $url, $data);
$exec_api_data = json_decode($results, true);
$operation = (isset($exec_api_data['operation'])) ? $exec_api_data['operation'] : ""; //$operation = "/1.0/operations/d77f70b9-ae8d-4a47-9935-4d49d707f0aa";
$secret = (isset($exec_api_data['metadata']['metadata']['fds']["0"])) ? $exec_api_data['metadata']['metadata']['fds']["0"] : ""; //$secret = "64f5592ee1bc64b8b699e232371dd1286465bafa4a9e688ea7a9cc48f785e98e";
$control = (isset($exec_api_data['metadata']['metadata']['fds']["control"])) ? $exec_api_data['metadata']['metadata']['fds']["control"] : ""; //used to close connection properly
$results = '{"operation": "'.$operation.'", "secret": "'.$secret.'", "control": "'.$control.'"}';
echo $results;
//Send event to accounting
@ -396,13 +782,14 @@ if (isset($_SESSION['username'])) {
$url = $base_url . "/1.0/instances/" . $instance . "?project=" . $project;
$results = sendCurlRequest($action, "GET", $url);
$results = json_decode($results, true);
$device_names = (isset($results['metadata']['expanded_devices'])) ? $results['metadata']['expanded_devices'] : [];
$device_names = (isset($results['metadata']['devices'])) ? $results['metadata']['devices'] : [];
$expanded_device_names = (isset($results['metadata']['expanded_devices'])) ? $results['metadata']['expanded_devices'] : [];
$i = 0;
echo '{ "data": [';
//Loop through the expanded devices
foreach ($device_names as $device_name => $device_data){
foreach ($expanded_device_names as $expanded_device_name => $device_data){
$disk_path = (isset($device_data['path'])) ? $device_data['path'] : "";
$disk_type = $device_data['type'];
$disk_usage = "";
@ -413,7 +800,7 @@ if (isset($_SESSION['username'])) {
//Determine if there is usage data available for disk device
foreach ($disk_names as $disk_name => $disk_data){
if ($device_name == $disk_name){
if ($expanded_device_name == $disk_name){
$disk_usage = $disk_data['usage']/1024/1024;
$disk_unit = "MB";
if ($disk_usage >= 1024){
@ -439,11 +826,17 @@ if (isset($_SESSION['username'])) {
echo "<i class='fas fa-hdd fa-lg' style='color:#4e73df'></i>";
echo '",';
echo '"' . htmlentities($device_name) . '",';
echo '"' . htmlentities($expanded_device_name) . '",';
echo '"' . htmlentities($disk_path) . '",';
echo '"' . htmlentities($disk_usage) . " " . $disk_unit . '",';
echo '"' . htmlentities($disk_type) . '"';
echo '"' . htmlentities($disk_type) . '",';
echo '"';
if (array_key_exists($expanded_device_name, $device_names)){
echo "<a href='#' onclick=removeInstanceDevice('".$expanded_device_name."')><i class='fas fa-trash-alt fa-lg' style='color:#ddd' title='Remove' aria-hidden='true'></i></a>";
}
echo '"';
echo " ]";
}
@ -453,45 +846,7 @@ if (isset($_SESSION['username'])) {
echo " ]}";
break;
case "listInstanceLogs":
$url = $base_url . "/1.0/instances/" . $instance . "/logs?project=" . $project;
$results = sendCurlRequest($action, "GET", $url);
$results = json_decode($results, true);
$instance_logs = (isset($results['metadata'])) ? $results['metadata'] : [];
$i = 0;
echo '{ "data": [';
foreach ($instance_logs as $instance_log){
if ($i > 0){
echo ",";
}
$i++;
echo "[ ";
echo '"' . "<i class='fas fa-history fa-lg' style='color:#4e73df'></i>" . '",';
echo '"' . htmlentities($instance_log) . '",';
echo '"';
echo "<a href='#' onclick=loadInstanceLog('".$instance_log."')><i class='fas fa-file fa-lg' style='color:#ddd' title='Display' aria-hidden='true'></i></a>";
echo " &nbsp ";
echo "<a href='#' onclick=deleteInstanceLog('".$instance_log."')><i class='fas fa-trash-alt fa-lg' style='color:#ddd' title='Delete' aria-hidden='true'></i></a>";
echo '"';
echo " ]";
}
echo " ]}";
break;
case "listInstanceNetworkDevices":
case "listInstanceInterfaces":
$url = $base_url . "/1.0/instances/" . $instance . "/state?recursion=1&project=" . $project;
$results = sendCurlRequest($action, "GET", $url);
$results = json_decode($results, true);
@ -553,6 +908,93 @@ if (isset($_SESSION['username'])) {
break;
case "listInstanceLogs":
$url = $base_url . "/1.0/instances/" . $instance . "/logs?project=" . $project;
$results = sendCurlRequest($action, "GET", $url);
$results = json_decode($results, true);
$instance_logs = (isset($results['metadata'])) ? $results['metadata'] : [];
$i = 0;
echo '{ "data": [';
foreach ($instance_logs as $instance_log){
if ($i > 0){
echo ",";
}
$i++;
echo "[ ";
echo '"' . "<i class='fas fa-history fa-lg' style='color:#4e73df'></i>" . '",';
echo '"' . htmlentities($instance_log) . '",';
echo '"';
echo "<a href='#' onclick=loadInstanceLog('".$instance_log."')><i class='fas fa-file fa-lg' style='color:#ddd' title='Display' aria-hidden='true'></i></a>";
echo " &nbsp ";
echo "<a href='#' onclick=deleteInstanceLog('".$instance_log."')><i class='fas fa-trash-alt fa-lg' style='color:#ddd' title='Delete' aria-hidden='true'></i></a>";
echo '"';
echo " ]";
}
echo " ]}";
break;
case "listInstanceNetworkDevices":
$url = $base_url . "/1.0/instances/" . $instance . "?project=" . $project;
$results = sendCurlRequest($action, "GET", $url);
$results = json_decode($results, true);
$device_names = (isset($results['metadata']['devices'])) ? $results['metadata']['devices'] : [];
$expanded_device_names = (isset($results['metadata']['expanded_devices'])) ? $results['metadata']['expanded_devices'] : [];
$i = 0;
echo '{ "data": [';
foreach ($expanded_device_names as $expanded_device_name => $device_data){
if ($device_data['type'] == "nic"){
$device_data_nictype = (isset($device_data['nictype'])) ? htmlentities($device_data['nictype']) : "";
$device_data_parent = (isset($device_data['parent'])) ? htmlentities($device_data['parent']) : "";
$device_data_network = (isset($device_data['network'])) ? htmlentities($device_data['network']) : "";
$device_data_name = (isset($device_data['name'])) ? htmlentities($device_data['name']) : "";
if ($i > 0){
echo ",";
}
$i++;
echo "[ ";
echo '"' . "<i class='fas fa-exchange-alt fa-lg' style='color:#4e73df'></i>" . '",';
echo '"' . htmlentities($expanded_device_name) . '",';
echo '"' . $device_data_nictype . '",';
echo '"' . $device_data_parent . '",';
echo '"' . $device_data_network . '",';
echo '"' . $device_data_name . '",';
echo '"';
if (array_key_exists($expanded_device_name, $device_names)){
echo "<a href='#' onclick=removeInstanceDevice('".$expanded_device_name."')><i class='fas fa-trash-alt fa-lg' style='color:#ddd' title='Remove' aria-hidden='true'></i></a>";
}
echo '"';
echo " ]";
}
}
echo " ]}";
break;
case "listInstanceProfiles":
$url = $base_url . "/1.0/instances/" . $instance . "?project=" . $project;
$results = sendCurlRequest($action, "GET", $url);
@ -605,14 +1047,19 @@ if (isset($_SESSION['username'])) {
$url = $base_url . "/1.0/instances/" . $instance . "?project=" . $project;
$results = sendCurlRequest($action, "GET", $url);
$results = json_decode($results, true);
$device_names = (isset($results['metadata']['expanded_devices'])) ? $results['metadata']['expanded_devices'] : [];
$device_names = (isset($results['metadata']['devices'])) ? $results['metadata']['devices'] : [];
$expanded_device_names = (isset($results['metadata']['expanded_devices'])) ? $results['metadata']['expanded_devices'] : [];
$i = 0;
echo '{ "data": [';
foreach ($device_names as $device_name => $device_data){
foreach ($expanded_device_names as $expanded_device_name => $device_data){
if ($device_data['type'] == "proxy"){
$device_data_connect = (isset($device_data['connect'])) ? htmlentities($device_data['connect']) : "";
$device_data_listen = (isset($device_data['listen'])) ? htmlentities($device_data['listen']) : "";
$device_data_type = (isset($device_data['type'])) ? htmlentities($device_data['type']) : "";
if ($i > 0){
echo ",";
}
@ -622,10 +1069,16 @@ if (isset($_SESSION['username'])) {
echo '"' . "<i class='fas fa-exchange-alt fa-lg' style='color:#4e73df'></i>" . '",';
echo '"' . htmlentities($device_name) . '",';
echo '"' . htmlentities($device_data['connect']) . '",';
echo '"' . htmlentities($device_data['listen']) . '",';
echo '"' . htmlentities($device_data['type']) . '"';
echo '"' . htmlentities($expanded_device_name) . '",';
echo '"' . $device_data_connect . '",';
echo '"' . $device_data_listen . '",';
echo '"' . $device_data_type . '",';
echo '"';
if (array_key_exists($expanded_device_name, $device_names)){
echo "<a href='#' onclick=removeInstanceDevice('".$expanded_device_name."')><i class='fas fa-trash-alt fa-lg' style='color:#ddd' title='Remove' aria-hidden='true'></i></a>";
}
echo '"';
echo " ]";
@ -710,6 +1163,35 @@ if (isset($_SESSION['username'])) {
echo " ]}";
break;
case "removeInstanceDevice":
$url = $base_url . "/1.0/instances/" . $instance . "?project=" . $project;
$results = sendCurlRequest($action, "GET", $url);
$data = json_decode($results, true);
$data = $data['metadata'];
if (isset($data['devices'][$name])){
unset($data['devices'][$name]);
if (empty($data['devices'])){
unset($data['devices']);
}
$data = json_encode($data);
$url = $base_url . "/1.0/instances/" . $instance . "?project=" . $project;
$results = sendCurlRequest($action, "PUT", $url, $data);
echo $results;
//Send event to accounting
$event = json_decode($results, true);
$object = $instance . " - " . $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;
case "retrieveInstanceState":
$url = $base_url . "/1.0/instances/" . $instance . "/state?project=" . $project;
$results = sendCurlRequest($action, "GET", $url);

View file

@ -192,10 +192,6 @@ if (isset($_SESSION['username'])) {
break;
case "createInstanceUsingForm":
//None is not a valid instance type, change it to "" if none is selected.
if ($instance_type == "none"){
$instance_type = "";
}
//If location == none let LXD determine where the instance is created
if ($location == "none"){
$url = $base_url . "/1.0/instances?project=" . $project;

View file

@ -28,12 +28,23 @@ if (isset($_SESSION['username'])) {
//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) : "";
$destination = (isset($_GET['destination'])) ? filter_var(urldecode($_GET['destination']), FILTER_SANITIZE_STRING) : "";
$destination_port = (isset($_GET['destination_port'])) ? filter_var(urldecode($_GET['destination_port']), FILTER_SANITIZE_STRING) : "";
$icmp_code = (isset($_GET['icmp_code'])) ? filter_var(urldecode($_GET['icmp_code']), FILTER_SANITIZE_STRING) : "";
$icmp_type = (isset($_GET['icmp_type'])) ? filter_var(urldecode($_GET['icmp_type']), FILTER_SANITIZE_STRING) : "";
$name = (isset($_GET['name'])) ? filter_var(urldecode($_GET['name']), FILTER_SANITIZE_STRING) : "";
$network_acl = (isset($_GET['network_acl'])) ? filter_var(urldecode($_GET['network_acl']), FILTER_SANITIZE_STRING) : "";
$project = (isset($_GET['project'])) ? filter_var(urldecode($_GET['project']), FILTER_SANITIZE_STRING) : "";
$protocol = (isset($_GET['protocol'])) ? filter_var(urldecode($_GET['protocol']), FILTER_SANITIZE_STRING) : "";
$remote = (isset($_GET['remote'])) ? filter_var(urldecode($_GET['remote']), FILTER_SANITIZE_NUMBER_INT) : "";
$repo = (isset($_GET['repo'])) ? filter_var(urldecode($_GET['repo']), FILTER_SANITIZE_STRING) : "";
$rule = (isset($_GET['rule'])) ? filter_var(urldecode($_GET['rule']), FILTER_SANITIZE_NUMBER_INT) : "";
$state = (isset($_GET['state'])) ? filter_var(urldecode($_GET['state']), FILTER_SANITIZE_STRING) : "";
$source = (isset($_GET['source'])) ? filter_var(urldecode($_GET['source']), FILTER_SANITIZE_STRING) : "";
$source_port = (isset($_GET['source_port'])) ? filter_var(urldecode($_GET['source_port']), FILTER_SANITIZE_STRING) : "";
$traffic_action = (isset($_GET['traffic_action'])) ? filter_var(urldecode($_GET['traffic_action']), FILTER_SANITIZE_STRING) : "";
$type = (isset($_GET['type'])) ? filter_var(urldecode($_GET['type']), FILTER_SANITIZE_STRING) : "";
//Declare and instantiate POST variables
$json = (isset($_POST['json'])) ? $_POST['json'] : "";
@ -52,6 +63,61 @@ if (isset($_SESSION['username'])) {
//Run the matching action
switch ($action) {
case "addTrafficRule":
$url = $base_url . "/1.0/network-acls/" . $network_acl . "?project=" . $project;
$results = sendCurlRequest($action, "GET", $url);
$data = json_decode($results, true);
$data = $data['metadata'];
if (empty($data['config'])){
unset($data['config']);
}
if ($type == "egress"){
$count = count($data['egress']);
$data['egress'][$count]['action'] = $traffic_action;
$data['egress'][$count]['state'] = $state;
$data['egress'][$count]['description'] = $description;
$data['egress'][$count]['source'] = $source;
$data['egress'][$count]['destination'] = $destination;
$data['egress'][$count]['protocol'] = $protocol;
$data['egress'][$count]['source_port'] = $source_port;
$data['egress'][$count]['destination_port'] = $destination_port;
$data['egress'][$count]['icmp_type'] = $icmp_type;
$data['egress'][$count]['icmp_code'] = $icmp_code;
}
elseif ($type == "ingress"){
$count = count($data['ingress']);
$data['ingress'][$count]['action'] = $traffic_action;
$data['ingress'][$count]['state'] = $state;
$data['ingress'][$count]['description'] = $description;
$data['ingress'][$count]['source'] = $source;
$data['ingress'][$count]['destination'] = $destination;
$data['ingress'][$count]['protocol'] = $protocol;
$data['ingress'][$count]['source_port'] = $source_port;
$data['ingress'][$count]['destination_port'] = $destination_port;
$data['ingress'][$count]['icmp_type'] = $icmp_type;
$data['ingress'][$count]['icmp_code'] = $icmp_code;
}
else {
$data = "";
}
$data = json_encode($data);
$results = sendCurlRequest($action, "PUT", $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;
case "createNetworkAclUsingForm":
$url = $base_url . "/1.0/network-acls?project=" . $project;
$data = '{"description": "'.$description.'", "name": "'.$name.'"}';
@ -86,6 +152,74 @@ if (isset($_SESSION['username'])) {
}
break;
case "deleteEgressRule":
$url = $base_url . "/1.0/network-acls/" . $network_acl . "?project=" . $project;
$results = sendCurlRequest($action, "GET", $url);
$data = json_decode($results, true);
$data = $data['metadata'];
//Remove rule from Egress array
unset($data['egress'][$rule]);
//Remove array indexes so that JSON encode works properly
$data['egress'] = array_values($data['egress']);
$data['ingress'] = array_values($data['ingress']);
if (empty($data['config'])){
unset($data['config']);
}
//Encode the data back to JSON
$data = json_encode($data);
$results = sendCurlRequest($action, "PUT", $url, $data);
echo $data;
//Send event to accounting
$event = json_decode($results, true);
$object = $network_acl;
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;
case "deleteIngressRule":
$url = $base_url . "/1.0/network-acls/" . $network_acl . "?project=" . $project;
$results = sendCurlRequest($action, "GET", $url);
$data = json_decode($results, true);
$data = $data['metadata'];
//Remove rule from Ingress array
unset($data['ingress'][$rule]);
//Remove array indexes so that JSON encode works properly
$data['egress'] = array_values($data['egress']);
$data['ingress'] = array_values($data['ingress']);
if (empty($data['config'])){
unset($data['config']);
}
//Encode the data back to JSON
$data = json_encode($data);
$results = sendCurlRequest($action, "PUT", $url, $data);
echo $data;
//Send event to accounting
$event = json_decode($results, true);
$object = $network_acl;
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;
case "deleteNetworkAcl":
$url = $base_url . "/1.0/network-acls/" . $network_acl . "?project=" . $project;
$results = sendCurlRequest($action, "DELETE", $url);
@ -102,6 +236,119 @@ if (isset($_SESSION['username'])) {
}
break;
case "listEgressRules":
if (validateAuthorization($action)) {
$url = $base_url . "/1.0/network-acls/" . $network_acl . "?project=" . $project;
$results = sendCurlRequest($action, "GET", $url);
$results = json_decode($results, true);
$egress_rules = (isset($results['metadata']['egress'])) ? $results['metadata']['egress'] : [];
$i = 0;
echo '{ "data": [';
foreach ($egress_rules as $egress_rule){
$egress_rule_action = (isset($egress_rule['action'])) ? htmlentities($egress_rule['action']) : "";
$egress_rule_state = (isset($egress_rule['state'])) ? htmlentities($egress_rule['state']) : "";
$egress_rule_description = (isset($egress_rule['description'])) ? htmlentities($egress_rule['description']) : "";
$egress_rule_source = (isset($egress_rule['source'])) ? htmlentities($egress_rule['source']) : "";
$egress_rule_destination = (isset($egress_rule['destination'])) ? htmlentities($egress_rule['destination']) : "";
$egress_rule_protocol = (isset($egress_rule['protocol'])) ? htmlentities($egress_rule['protocol']) : "";
$egress_rule_source_port = (isset($egress_rule['source_port'])) ? htmlentities($egress_rule['source_port']) : "";
$egress_rule_destination_port = (isset($egress_rule['destination_port'])) ? htmlentities($egress_rule['destination_port']) : "";
$egress_rule_icmp_type = (isset($egress_rule['icmp_type'])) ? htmlentities($egress_rule['icmp_type']) : "";
$egress_rule_icmp_code = (isset($egress_rule['icmp_code'])) ? htmlentities($egress_rule['icmp_code']) : "";
if ($i > 0){
echo ",";
}
echo "[ ";
echo '"' . "<i class='fas fa-shield-alt fa-lg' style='color:#4e73df'></i>" . '",';
echo '"' . $egress_rule_action . '",';
echo '"' . $egress_rule_state . '",';
echo '"' . $egress_rule_description . '",';
echo '"' . $egress_rule_source . '",';
echo '"' . $egress_rule_destination . '",';
echo '"' . $egress_rule_protocol . '",';
echo '"' . $egress_rule_source_port . '",';
echo '"' . $egress_rule_destination_port . '",';
echo '"' . $egress_rule_icmp_type . '",';
echo '"' . $egress_rule_icmp_code . '",';
echo '"';
echo "<a href='#' onclick=deleteEgressRule('".$i."')><i class='fas fa-trash-alt fa-lg' style='color:#ddd' title='Delete' aria-hidden='true'></i></a>";
echo '"';
echo " ]";
$i++;
}
echo " ]}";
}
else {
echo '{ "data": [] }';
}
break;
case "listIngressRules":
if (validateAuthorization($action)) {
$url = $base_url . "/1.0/network-acls/" . $network_acl . "?project=" . $project;
$results = sendCurlRequest($action, "GET", $url);
$results = json_decode($results, true);
$ingress_rules = (isset($results['metadata']['ingress'])) ? $results['metadata']['ingress'] : [];
$i = 0;
echo '{ "data": [';
foreach ($ingress_rules as $ingress_rule){
$ingress_rule_action = (isset($ingress_rule['action'])) ? htmlentities($ingress_rule['action']) : "";
$ingress_rule_state = (isset($ingress_rule['state'])) ? htmlentities($ingress_rule['state']) : "";
$ingress_rule_description = (isset($ingress_rule['description'])) ? htmlentities($ingress_rule['description']) : "";
$ingress_rule_source = (isset($ingress_rule['source'])) ? htmlentities($ingress_rule['source']) : "";
$ingress_rule_destination = (isset($ingress_rule['destination'])) ? htmlentities($ingress_rule['destination']) : "";
$ingress_rule_protocol = (isset($ingress_rule['protocol'])) ? htmlentities($ingress_rule['protocol']) : "";
$ingress_rule_source_port = (isset($ingress_rule['source_port'])) ? htmlentities($ingress_rule['source_port']) : "";
$ingress_rule_destination_port = (isset($ingress_rule['destination_port'])) ? htmlentities($ingress_rule['destination_port']) : "";
$ingress_rule_icmp_type = (isset($ingress_rule['icmp_type'])) ? htmlentities($ingress_rule['icmp_type']) : "";
$ingress_rule_icmp_code = (isset($ingress_rule['icmp_code'])) ? htmlentities($ingress_rule['icmp_code']) : "";
if ($i > 0){
echo ",";
}
echo "[ ";
echo '"' . "<i class='fas fa-shield-alt fa-lg' style='color:#4e73df'></i>" . '",';
echo '"' . $ingress_rule_action . '",';
echo '"' . $ingress_rule_state . '",';
echo '"' . $ingress_rule_description . '",';
echo '"' . $ingress_rule_source . '",';
echo '"' . $ingress_rule_destination . '",';
echo '"' . $ingress_rule_protocol . '",';
echo '"' . $ingress_rule_source_port . '",';
echo '"' . $ingress_rule_destination_port . '",';
echo '"' . $ingress_rule_icmp_type . '",';
echo '"' . $ingress_rule_icmp_code . '",';
echo '"';
echo "<a href='#' onclick=deleteIngressRule('".$i."')><i class='fas fa-trash-alt fa-lg' style='color:#ddd' title='Delete' aria-hidden='true'></i></a>";
echo '"';
echo " ]";
$i++;
}
echo " ]}";
}
else {
echo '{ "data": [] }';
}
break;
case "listNetworkAcls":
if (validateAuthorization($action)) {
$url = $base_url . "/1.0/network-acls?recursion=1&project=" . $project;
@ -113,8 +360,9 @@ if (isset($_SESSION['username'])) {
echo '{ "data": [';
foreach ($network_acls as $network_acl){
$network_acl_name = (isset($network_acl['name'])) ? htmlentities($network_acl['name']) : "";
if ($network_acl['name'] == "")
if ($network_acl_name == "")
continue;
if ($i > 0){
@ -124,25 +372,24 @@ if (isset($_SESSION['username'])) {
echo "[ ";
echo '"' . "<i class='fas fa-shield-alt fa-lg' style='color:#4e73df'></i>" . '",';
echo '"' . htmlentities($network_acl['name']) . '",';
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']) . '",';
if (empty($network_acl['ingress'])){
echo '"false",';
}
else {
echo '"true",';
}
if (empty($network_acl['egress'])){
echo '"false",';
}
else {
echo '"true",';
}
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){

View file

@ -27,13 +27,62 @@ if (isset($_SESSION['username'])) {
//Declare and instantiate GET variables
$action = (isset($_GET['action'])) ? filter_var(urldecode($_GET['action']), FILTER_SANITIZE_STRING) : "";
$bridge_driver = (isset($_GET['bridge_driver'])) ? filter_var(urldecode($_GET['bridge_driver']), FILTER_SANITIZE_STRING) : "";
$bridge_external_interfaces = (isset($_GET['bridge_external_interfaces'])) ? filter_var(urldecode($_GET['bridge_external_interfaces']), FILTER_SANITIZE_STRING) : "";
$bridge_hwaddr = (isset($_GET['bridge_hwaddr'])) ? filter_var(urldecode($_GET['bridge_hwaddr']), FILTER_SANITIZE_STRING) : "";
$bridge_mode = (isset($_GET['bridge_mode'])) ? filter_var(urldecode($_GET['bridge_mode']), FILTER_SANITIZE_STRING) : "";
$bridge_mtu = (isset($_GET['bridge_mtu'])) ? filter_var(urldecode($_GET['bridge_mtu']), FILTER_SANITIZE_STRING) : "";
$description = (isset($_GET['description'])) ? filter_var(urldecode($_GET['description']), FILTER_SANITIZE_STRING) : "";
$dns_domain = (isset($_GET['dns_domain'])) ? filter_var(urldecode($_GET['dns_domain']), FILTER_SANITIZE_STRING) : "";
$dns_mode = (isset($_GET['dns_mode'])) ? filter_var(urldecode($_GET['dns_mode']), FILTER_SANITIZE_STRING) : "";
$dns_nameservers = (isset($_GET['dns_nameservers'])) ? filter_var(urldecode($_GET['dns_nameservers']), FILTER_SANITIZE_STRING) : "";
$dns_search = (isset($_GET['dns_search'])) ? filter_var(urldecode($_GET['dns_search']), FILTER_SANITIZE_STRING) : "";
$fan_overlay_subnet = (isset($_GET['fan_overlay_subnet'])) ? filter_var(urldecode($_GET['fan_overlay_subnet']), FILTER_SANITIZE_STRING) : "";
$fan_type = (isset($_GET['fan_type'])) ? filter_var(urldecode($_GET['fan_type']), FILTER_SANITIZE_STRING) : "";
$fan_underlay_subnet = (isset($_GET['fan_underlay_subnet'])) ? filter_var(urldecode($_GET['fan_underlay_subnet']), FILTER_SANITIZE_STRING) : "";
$ipv4_address = (isset($_GET['ipv4_address'])) ? filter_var(urldecode($_GET['ipv4_address']), FILTER_SANITIZE_STRING) : "";
$ipv4_dhcp = (isset($_GET['ipv4_dhcp'])) ? filter_var(urldecode($_GET['ipv4_dhcp']), FILTER_SANITIZE_STRING) : "";
$ipv4_dhcp_expiry = (isset($_GET['ipv4_dhcp_expiry'])) ? filter_var(urldecode($_GET['ipv4_dhcp_expiry']), FILTER_SANITIZE_STRING) : "";
$ipv4_dhcp_gateway = (isset($_GET['ipv4_dhcp_gateway'])) ? filter_var(urldecode($_GET['ipv4_dhcp_gateway']), FILTER_SANITIZE_STRING) : "";
$ipv4_dhcp_ranges = (isset($_GET['ipv4_dhcp_ranges'])) ? filter_var(urldecode($_GET['ipv4_dhcp_ranges']), FILTER_SANITIZE_STRING) : "";
$ipv4_firewall = (isset($_GET['ipv4_firewall'])) ? filter_var(urldecode($_GET['ipv4_firewall']), FILTER_SANITIZE_STRING) : "";
$ipv4_gateway = (isset($_GET['ipv4_gateway'])) ? filter_var(urldecode($_GET['ipv4_gateway']), FILTER_SANITIZE_STRING) : "";
$ipv4_nat = (isset($_GET['ipv4_nat'])) ? filter_var(urldecode($_GET['ipv4_nat']), FILTER_SANITIZE_STRING) : "";
$ipv4_nat_address = (isset($_GET['ipv4_nat_address'])) ? filter_var(urldecode($_GET['ipv4_nat_address']), FILTER_SANITIZE_STRING) : "";
$ipv4_nat_order = (isset($_GET['ipv4_nat_order'])) ? filter_var(urldecode($_GET['ipv4_nat_order']), FILTER_SANITIZE_STRING) : "";
$ipv4_ovn_ranges = (isset($_GET['ipv4_ovn_ranges'])) ? filter_var(urldecode($_GET['ipv4_ovn_ranges']), FILTER_SANITIZE_STRING) : "";
$ipv4_routes = (isset($_GET['ipv4_routes'])) ? filter_var(urldecode($_GET['ipv4_routes']), FILTER_SANITIZE_STRING) : "";
$ipv4_routes_anycast = (isset($_GET['ipv4_routes_anycast'])) ? filter_var(urldecode($_GET['ipv4_routes_anycast']), FILTER_SANITIZE_STRING) : "";
$ipv4_routing = (isset($_GET['ipv4_routing'])) ? filter_var(urldecode($_GET['ipv4_routing']), FILTER_SANITIZE_STRING) : "";
$ipv6_address = (isset($_GET['ipv6_address'])) ? filter_var(urldecode($_GET['ipv6_address']), FILTER_SANITIZE_STRING) : "";
$ipv6_dhcp = (isset($_GET['ipv6_dhcp'])) ? filter_var(urldecode($_GET['ipv6_dhcp']), FILTER_SANITIZE_STRING) : "";
$ipv6_dhcp_expiry = (isset($_GET['ipv6_dhcp_expiry'])) ? filter_var(urldecode($_GET['ipv6_dhcp_expiry']), FILTER_SANITIZE_STRING) : "";
$ipv6_dhcp_ranges = (isset($_GET['ipv6_dhcp_ranges'])) ? filter_var(urldecode($_GET['ipv6_dhcp_ranges']), FILTER_SANITIZE_STRING) : "";
$ipv6_dhcp_stateful = (isset($_GET['ipv6_dhcp_stateful'])) ? filter_var(urldecode($_GET['ipv6_dhcp_stateful']), FILTER_SANITIZE_STRING) : "";
$ipv6_firewall = (isset($_GET['ipv6_firewall'])) ? filter_var(urldecode($_GET['ipv6_firewall']), FILTER_SANITIZE_STRING) : "";
$ipv6_gateway = (isset($_GET['ipv6_gateway'])) ? filter_var(urldecode($_GET['ipv6_gateway']), FILTER_SANITIZE_STRING) : "";
$ipv6_nat = (isset($_GET['ipv6_nat'])) ? filter_var(urldecode($_GET['ipv6_nat']), FILTER_SANITIZE_STRING) : "";
$ipv6_nat_address = (isset($_GET['ipv6_nat_address'])) ? filter_var(urldecode($_GET['ipv6_nat_address']), FILTER_SANITIZE_STRING) : "";
$ipv6_nat_order = (isset($_GET['ipv6_nat_order'])) ? filter_var(urldecode($_GET['ipv6_nat_order']), FILTER_SANITIZE_STRING) : "";
$ipv6_ovn_ranges = (isset($_GET['ipv6_ovn_ranges'])) ? filter_var(urldecode($_GET['ipv6_ovn_ranges']), FILTER_SANITIZE_STRING) : "";
$ipv6_routes = (isset($_GET['ipv6_routes'])) ? filter_var(urldecode($_GET['ipv6_routes']), FILTER_SANITIZE_STRING) : "";
$ipv6_routes_anycast = (isset($_GET['ipv6_routes_anycast'])) ? filter_var(urldecode($_GET['ipv6_routes_anycast']), FILTER_SANITIZE_STRING) : "";
$ipv6_routing = (isset($_GET['ipv6_routing'])) ? filter_var(urldecode($_GET['ipv6_routing']), FILTER_SANITIZE_STRING) : "";
$maas_subnet_ipv4 = (isset($_GET['maas_subnet_ipv4'])) ? filter_var(urldecode($_GET['maas_subnet_ipv4']), FILTER_SANITIZE_STRING) : "";
$maas_subnet_ipv6 = (isset($_GET['maas_subnet_ipv6'])) ? filter_var(urldecode($_GET['maas_subnet_ipv6']), FILTER_SANITIZE_STRING) : "";
$managed_only = (isset($_GET['managed_only'])) ? filter_var(urldecode($_GET['managed_only']), FILTER_SANITIZE_STRING) : "";
$mtu = (isset($_GET['mtu'])) ? filter_var(urldecode($_GET['mtu']), FILTER_SANITIZE_STRING) : "";
$name = (isset($_GET['name'])) ? filter_var(urldecode($_GET['name']), FILTER_SANITIZE_STRING) : "";
$network = (isset($_GET['network'])) ? filter_var(urldecode($_GET['network']), FILTER_SANITIZE_STRING) : "";
$ovn_ingress_mode = (isset($_GET['ovn_ingress_mode'])) ? filter_var(urldecode($_GET['ovn_ingress_mode']), FILTER_SANITIZE_STRING) : "";
$parent = (isset($_GET['parent'])) ? filter_var(urldecode($_GET['parent']), FILTER_SANITIZE_STRING) : "";
$project = (isset($_GET['project'])) ? filter_var(urldecode($_GET['project']), FILTER_SANITIZE_STRING) : "";
$raw_dnsmasq = (isset($_GET['raw_dnsmasq'])) ? filter_var(urldecode($_GET['raw_dnsmasq']), FILTER_SANITIZE_STRING) : "";
$remote = (isset($_GET['remote'])) ? filter_var(urldecode($_GET['remote']), FILTER_SANITIZE_NUMBER_INT) : "";
$repo = (isset($_GET['repo'])) ? filter_var(urldecode($_GET['repo']), FILTER_SANITIZE_STRING) : "";
$type = (isset($_GET['type'])) ? filter_var(urldecode($_GET['type']), FILTER_SANITIZE_STRING) : "";
$vlan = (isset($_GET['vlan'])) ? filter_var(urldecode($_GET['vlan']), FILTER_SANITIZE_STRING) : "";
//Declare and instantiate POST variables
$json = (isset($_POST['json'])) ? $_POST['json'] : "";
@ -54,7 +103,93 @@ if (isset($_SESSION['username'])) {
case "createNetworkUsingForm":
$url = $base_url . "/1.0/networks?project=" . $project;
$data = '{"description": "'.$description.'", "name": "'.$name.'"}';
$device_array = array();
$device_array['name'] = $name;
$device_array['type'] = $type;
$device_array['description'] = $description;
if ($type == "bridge"){
if (!empty($bridge_driver)){ $device_array['config']['bridge.driver'] = $bridge_driver;}
if (!empty($bridge_external_interfaces)){ $device_array['config']['bridge.external_interfaces'] = $bridge_external_interfaces;}
if (!empty($bridge_hwaddr)){ $device_array['config']['bridge.hwaddr'] = $bridge_hwaddr;}
if (!empty($bridge_mode)){ $device_array['config']['bridge.mode'] = $bridge_mode;}
if (!empty($bridge_mtu)){ $device_array['config']['bridge.mtu'] = $bridge_mtu;}
if (!empty($dns_domain)){ $device_array['config']['dns.domain'] = $dns_domain;}
if (!empty($dns_mode)){ $device_array['config']['dns.mode'] = $dns_mode;}
if (!empty($dns_search)){ $device_array['config']['dns.search'] = $dns_search;}
if (!empty($fan_overlay_subnet)){ $device_array['config']['fan.overlay_subnet'] = $fan_overlay_subnet;}
if (!empty($fan_type)){ $device_array['config']['fan.type'] = $fan_type;}
if (!empty($fan_underlay_subnet)){ $device_array['config']['fan.underlay_subnet'] = $fan_underlay_subnet;}
if (!empty($ipv4_address)){ $device_array['config']['ipv4.address'] = $ipv4_address;}
if (!empty($ipv4_dhcp)){ $device_array['config']['ipv4.dhcp'] = $ipv4_dhcp;}
if (!empty($ipv4_dhcp_expiry)){ $device_array['config']['ipv4.dhcp.expiry'] = $ipv4_dhcp_expiry;}
if (!empty($ipv4_dhcp_gateway)){ $device_array['config']['ipv4.dhcp.gateway'] = $ipv4_dhcp_gateway;}
if (!empty($ipv4_dhcp_ranges)){ $device_array['config']['ipv4.dhcp.ranges'] = $ipv4_dhcp_ranges;}
if (!empty($ipv4_firewall)){ $device_array['config']['ipv4.firewall'] = $ipv4_firewall;}
if (!empty($ipv4_nat_address)){ $device_array['config']['ipv4.nat.address'] = $ipv4_nat_address;}
if (!empty($ipv4_nat)){ $device_array['config']['ipv4.nat'] = $ipv4_nat;}
if (!empty($ipv4_nat_order)){ $device_array['config']['ipv4.nat.order'] = $ipv4_nat_order;}
if (!empty($ipv4_ovn_ranges)){ $device_array['config']['ipv4.ovn.ranges'] = $ipv4_ovn_ranges;}
if (!empty($ipv4_routes)){ $device_array['config']['ipv4.routes'] = $ipv4_routes;}
if (!empty($ipv4_routing)){ $device_array['config']['ipv4.routing'] = $ipv4_routing;}
if (!empty($ipv6_address)){ $device_array['config']['ipv6.address'] = $ipv6_address;}
if (!empty($ipv6_dhcp)){ $device_array['config']['ipv6.dhcp'] = $ipv6_dhcp;}
if (!empty($ipv6_dhcp_expiry)){ $device_array['config']['ipv6.dhcp.expiry'] = $ipv6_dhcp_expiry;}
if (!empty($ipv6_dhcp_ranges)){ $device_array['config']['ipv6.dhcp.ranges'] = $ipv6_dhcp_ranges;}
if (!empty($ipv6_dhcp_stateful)){ $device_array['config']['ipv6.dhcp.stateful'] = $ipv6_dhcp_stateful;}
if (!empty($ipv6_firewall)){ $device_array['config']['ipv6.firewall'] = $ipv6_firewall;}
if (!empty($ipv6_nat_address)){ $device_array['config']['ipv6.nat.address'] = $ipv6_nat_address;}
if (!empty($ipv6_nat)){ $device_array['config']['ipv6.nat'] = $ipv6_nat;}
if (!empty($ipv6_nat_order)){ $device_array['config']['ipv6.nat.order'] = $ipv6_nat_order;}
if (!empty($ipv6_ovn_ranges)){ $device_array['config']['ipv6.ovn.ranges'] = $ipv6_ovn_ranges;}
if (!empty($ipv6_routes)){ $device_array['config']['ipv6.routes'] = $ipv6_routes;}
if (!empty($ipv6_routing)){ $device_array['config']['ipv6.routing'] = $ipv6_routing;}
if (!empty($maas_subnet_ipv4)){ $device_array['config']['maas.subnet.ipv4'] = $maas_subnet_ipv4;}
if (!empty($maas_subnet_ipv6)){ $device_array['config']['maas.subnet.ipv6'] = $maas_subnet_ipv6;}
if (!empty($raw_dnsmasq)){ $device_array['config']['raw.dnsmasq'] = $raw_dnsmasq;}
}
if ($type == "macvlan" || $type == "sriov"){
if (!empty($maas_subnet_ipv4)){ $device_array['config']['maas.subnet.ipv4'] = $maas_subnet_ipv4;}
if (!empty($maas_subnet_ipv6)){ $device_array['config']['maas.subnet.ipv6'] = $maas_subnet_ipv6;}
if (!empty($mtu)){ $device_array['config']['mtu'] = $mtu;}
if (!empty($parent)){ $device_array['config']['parent'] = $parent;}
if (!empty($vlan)){ $device_array['config']['vlan'] = $vlan;}
}
if ($type == "ovn"){
if (!empty($bridge_hwaddr)){ $device_array['config']['bridge.hwaddr'] = $bridge_hwaddr;}
if (!empty($bridge_mtu)){ $device_array['config']['bridge.mtu'] = $bridge_mtu;}
if (!empty($dns_domain)){ $device_array['config']['dns.domain'] = $dns_domain;}
if (!empty($dns_search)){ $device_array['config']['dns.search'] = $dns_search;}
if (!empty($ipv4_address)){ $device_array['config']['ipv4.address'] = $ipv4_address;}
if (!empty($ipv4_dhcp)){ $device_array['config']['ipv4.dhcp'] = $ipv4_dhcp;}
if (!empty($ipv4_nat)){ $device_array['config']['ipv4.nat'] = $ipv4_nat;}
if (!empty($ipv6_address)){ $device_array['config']['ipv6.address'] = $ipv6_address;}
if (!empty($ipv6_dhcp)){ $device_array['config']['ipv6.dhcp'] = $ipv6_dhcp;}
if (!empty($ipv6_dhcp_stateful)){ $device_array['config']['ipv6.dhcp.stateful'] = $ipv6_dhcp_stateful;}
if (!empty($ipv6_nat)){ $device_array['config']['ipv6.nat'] = $ipv6_nat;}
if (!empty($network)){ $device_array['config']['network'] = $network;}
}
if ($type == "physical"){
if (!empty($maas_subnet_ipv4)){ $device_array['config']['maas.subnet.ipv4'] = $maas_subnet_ipv4;}
if (!empty($maas_subnet_ipv6)){ $device_array['config']['maas.subnet.ipv6'] = $maas_subnet_ipv6;}
if (!empty($mtu)){ $device_array['config']['mtu'] = $mtu;}
if (!empty($parent)){ $device_array['config']['parent'] = $parent;}
if (!empty($vlan)){ $device_array['config']['vlan'] = $vlan;}
if (!empty($ipv4_gateway)){ $device_array['config']['ipv4.gateway'] = $ipv4_gateway;}
if (!empty($ipv4_ovn_ranges)){ $device_array['config']['ipv4.ovn.ranges'] = $ipv4_ovn_ranges;}
if (!empty($ipv4_routes)){ $device_array['config']['ipv4.routes'] = $ipv4_routes;}
if (!empty($ipv4_routes_anycast)){ $device_array['config']['ipv4.routes.anycast'] = $ipv4_routes_anycast;}
if (!empty($ipv6_gateway)){ $device_array['config']['ipv6.gateway'] = $ipv6_gateway;}
if (!empty($ipv6_ovn_ranges)){ $device_array['config']['ipv6.ovn.ranges'] = $ipv6_ovn_ranges;}
if (!empty($ipv6_routes)){ $device_array['config']['ipv6.routes'] = $ipv6_routes;}
if (!empty($ipv6_routes_anycast)){ $device_array['config']['ipv6.routes.anycast'] = $ipv6_routes_anycast;}
if (!empty($dns_nameservers)){ $device_array['config']['dns.nameservers'] = $dns_nameservers;}
if (!empty($ovn_ingress_mode)){ $device_array['config']['ovn.ingress_mode'] = $ovn_ingress_mode;}
}
$data = json_encode($device_array);
$results = sendCurlRequest($action, "POST", $url, $data);
echo $results;
@ -174,6 +309,40 @@ if (isset($_SESSION['username'])) {
}
break;
case "listNetworksForSelectOption":
if (validateAuthorization($action)) {
$url = $base_url . "/1.0/networks?recursion=1&project=" . $project;
$results = sendCurlRequest($action, "GET", $url);
$results = json_decode($results, true);
$networks = (isset($results['metadata'])) ? $results['metadata'] : [];
$i = 0;
foreach ($networks as $network){
if ($managed_only == "true"){
if ($type != ""){
if ($network['managed'] == "true" && $network['type'] == $type){
echo '<option value="' . $network['name'] . '">' . htmlentities($network['name']) . '</option>';
$i++;
}
}
else{
if ($network['managed'] == "true"){
echo '<option value="' . $network['name'] . '">' . htmlentities($network['name']) . '</option>';
$i++;
}
}
}
else {
echo '<option value="' . $network['name'] . '">' . htmlentities($network['name']) . '</option>';
$i++;
}
}
if ($i == 0){
echo '<option value="">(No networks available)</option>';
}
}
break;
case "loadNetwork":
$url = $base_url . "/1.0/networks/" . $network . "?project=" . $project;
$results = sendCurlRequest($action, "GET", $url);

View file

@ -148,7 +148,7 @@ if (isset($_SESSION['username'])) {
if (!empty($operations_data['failure'])){
foreach ($operations_data['failure'] as $failed_task){
$results = htmlentities($failed_task['description']) . " Error: " . htmlentities($failed_task['err']);
$results = $failed_task['description'] . " Error: " . $failed_task['err'];
}
}

View file

@ -194,6 +194,26 @@ if (isset($_SESSION['username'])) {
}
break;
case "listStoragePoolsForSelectOption":
if (validateAuthorization($action)) {
$url = $base_url . "/1.0/storage-pools?recursion=1&project=" . $project;
$results = sendCurlRequest($action, "GET", $url);
$results = json_decode($results, true);
$storage_pools = (isset($results['metadata'])) ? $results['metadata'] : [];
echo '<option value="">(not set)</option>';
foreach ($storage_pools as $storage_pool){
if ($storage_pool['name'] == "")
continue;
echo '<option value="' . $storage_pool['name'] . '">' . htmlentities($storage_pool['name']) . '</option>';
}
}
break;
case "loadStoragePool":
$url = $base_url . "/1.0/storage-pools/" . $storage_pool . "?project=" . $project;
$results = sendCurlRequest($action, "GET", $url);

View file

@ -158,6 +158,24 @@ if (isset($_SESSION['username'])) {
echo '{ "data": [] }';
}
break;
case "listStorageVolumesForSelectOption":
if (validateAuthorization($action)) {
$url = $base_url . "/1.0/storage-pools/" . $pool . "/volumes?recursion=1&project=" . $project;
$results = sendCurlRequest($action, "GET", $url);
$results = json_decode($results, true);
$storage_volumes = (isset($results['metadata'])) ? $results['metadata'] : [];
foreach ($storage_volumes as $storage_volume){
if ($storage_volume['name'] == "")
continue;
echo '<option value="' . $storage_volume['name'] . '">' . htmlentities($storage_volume['name']) . '</option>';
}
}
break;
case "loadStorageVolume":
$url = $base_url . "/1.0/storage-pools/" . $storage_pool . "/volumes/" . $name . "?project=" . $project;

View file

@ -234,17 +234,23 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
<label class="col-3 col-form-label text-right">Name: </label>
<div class="col-7">
<div class="form-group">
<input type="text" id="profileNameCreate" class="form-control" placeholder="Profile Name" name="profile_name">
<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>
</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="profileDescriptionCreate" class="form-control" placeholder="Enter Description" name="profile_description">
<input type="text" id="profileDescriptionCreate" class="form-control" placeholder="" name="profile_description">
</div>
</div>
<div class="col-1">
<i class="far fa-sm fa-question-circle" title='Enter in a description for the profile.'></i>
</div>
</div>
<div class="modal-footer">
<button class="btn btn-secondary" type="button" data-dismiss="modal">Cancel</button>
@ -321,6 +327,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
<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>
</div>
</div>
<input type="hidden" id ="profileToRename" name="profileToRename">
</div>

View file

@ -220,12 +220,15 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
</div>
<div class="modal-body">
<div class="row">
<label class="col-2 col-form-label text-right">Name: </label>
<div class="col-9">
<label class="col-3 col-form-label text-right">Name: </label>
<div class="col-7">
<div class="form-group text-right">
<input type="text" class="form-control" id="projectNameInput" required="required" placeholder="Project Name" name="name">
<input type="text" class="form-control" id="projectNameInput" 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 the project.'></i>
</div>
</div>
</div>
<div class="modal-footer">
@ -284,6 +287,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
<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>
</div>
</div>
<input type="hidden" id ="projectToRename" name="projectToRename">
</div>

View file

@ -229,7 +229,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" title='IP address or FQDN of the LXD server'></i>
<i class="far fa-sm fa-question-circle text-danger" title='(Required) - Enter in the IP address or FQDN of the LXD server'></i>
</div>
</div>
@ -241,7 +241,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" title='Default LXD port is 8443'></i>
<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>
</div>
</div>
@ -253,7 +253,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" title='Friendly name for the LXD server'></i>
<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>
@ -285,11 +285,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
<pre id="instructionsClientCert"></pre>
</p>
<p>Import the certificate file on your remote LXD server by running the command:<br />
<code style="color: #ff0000;">lxc config trust add lxdware.crt</code>
<code class="text-danger">lxc config trust add lxdware.crt</code>
</p>
<p>
For LXD hosts that are not part of a cluster, use the following command to listen for incoming connections:<br />
<code style="color: #ff0000;">lxc config set core.https_address [::]</code>
<code class="text-danger">lxc config set core.https_address [::]</code>
</p>
</div>
</div>

View file

@ -246,47 +246,62 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
<div class="row">
<label class="col-3 col-form-label text-right">Username: </label>
<div class="col-8">
<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-8">
<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-8">
<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-8">
<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-8">
<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-->
@ -312,12 +327,15 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
<div class="row">
<label class="col-3 col-form-label text-right">Group:</label>
<div class="col-8 text-right">
<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">
@ -345,12 +363,15 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
<div class="row">
<label class="col-3 col-form-label text-right">Group:</label>
<div class="col-8 text-right">
<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">
@ -398,20 +419,26 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
<div class="row">
<label class="col-3 col-form-label text-right">Name: </label>
<div class="col-8">
<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-8">
<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-->
@ -437,12 +464,15 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
<div class="row">
<label class="col-3 col-form-label text-right">Role:</label>
<div class="col-8 text-right">
<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">
@ -470,12 +500,15 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
<div class="row">
<label class="col-3 col-form-label text-right">Role:</label>
<div class="col-8 text-right">
<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">

View file

@ -185,7 +185,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
$('#projectsIcon').css('color','#fff');
}
if (location.pathname == "/network-acls.html"){
if (location.pathname == "/network-acls.html" || location.pathname == "/network-acls-egress.html" || location.pathname == "/network-acls-ingress.html"){
$('#networkAclsSpan').css('color','#fff');
$('#networkAclsIcon').css('color','#fff');
}

View file

@ -221,21 +221,27 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
<div class="modal-body">
<div class="row">
<label class="col-2 col-form-label text-right">URL: </label>
<div class="col-9">
<label class="col-3 col-form-label text-right">URL: </label>
<div class="col-7">
<div class="form-group">
<input type="text" class="form-control" id="hostInput" required="required" placeholder="URL" name="host">
<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>
</div>
</div>
<div class="row">
<label class="col-2 col-form-label text-right">Alias: </label>
<div class="col-9">
<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="aliasInput" placeholder="Alias" name="alias">
<input type="text" class="form-control" id="aliasInput" placeholder="" name="alias">
</div>
</div>
<div class="col-1">
<i class="far fa-sm fa-question-circle" title='Enter in an alias that will be used to select the simplestreams location when downloading an image.'></i>
</div>
</div>
</div> <!-- End Modal Body-->

View file

@ -234,29 +234,38 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
<label class="col-3 col-form-label text-right">Name: </label>
<div class="col-7">
<div class="form-group">
<input type="text" id="storagePoolNameCreate" class="form-control" placeholder="Storage Pool Name" name="storage_pool_name">
<input type="text" id="storagePoolNameCreate" 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>
</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="storagePoolDescriptionCreate" class="form-control" placeholder="Enter Description" name="storage_pool_description">
<input type="text" id="storagePoolDescriptionCreate" class="form-control" placeholder="" name="storage_pool_description">
</div>
</div>
<div class="col-1">
<i class="far fa-sm fa-question-circle" title='Enter in a description for the storage pool.'></i>
</div>
</div>
<div class="row">
<label class="col-3 col-form-label text-right">Size (GB): </label>
<div class="col-4">
<div class="col-7">
<div class="form-group">
<input type="number" id="storagePoolSizeCreate" class="form-control" name="storage_pool_size">
</div>
</div>
<div class="col-1">
<i class="far fa-sm fa-question-circle text-danger" title='(Required) - Enter in the size in GB of the storage pool.'></i>
</div>
</div>
<div class="row">
<label class="col-3 col-form-label text-right">Driver: </label>
<div class="col-4">
<div class="col-7">
<div class="form-group">
<select id="storagePoolDriverCreate" class="form-control" name="storage_pool_driver">
<option value="btrfs">btrfs</option>
@ -267,6 +276,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
</select>
</div>
</div>
<div class="col-1">
<i class="far fa-sm fa-question-circle text-danger" title='(Required) - Select the storage pool driver.'></i>
</div>
</div>
<div class="modal-footer">
<button class="btn btn-secondary" type="button" data-dismiss="modal">Cancel</button>

View file

@ -235,9 +235,12 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
<label class="col-3 col-form-label text-right">Name: </label>
<div class="col-7">
<div class="form-group">
<input type="text" id="storageVolumeNameCreate" class="form-control" placeholder="Storage Volume Name" name="storage_volume_name">
<input type="text" id="storageVolumeNameCreate" 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>
</div>
</div>
<div class="row">
<label class="col-3 col-form-label text-right">Content Type: </label>
@ -249,14 +252,20 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
</select>
</div>
</div>
<div class="col-1">
<i class="far fa-sm fa-question-circle text-danger" title='(Required) - Select the content type.'></i>
</div>
</div>
<div class="row">
<label class="col-3 col-form-label text-right">Size (GB): </label>
<div class="col-4">
<div class="col-7">
<div class="form-group">
<input type="number" id="storageVolumeSizeCreate" class="form-control" value="10" name="storage_volume_size">
</div>
</div>
<div class="col-1">
<i class="far fa-sm fa-question-circle text-danger" title='(Required) - Enter in the size in GB for the storage volume..'></i>
</div>
</div>
<div class="modal-footer">
<button class="btn btn-secondary" type="button" data-dismiss="modal">Cancel</button>