2016-01-24 02:30:03 +00:00
{{ -- Copyright ( c ) 2015 - 2016 Dane Everitt < dane @ daneeveritt . com > -- }}
2016-01-20 20:56:40 +00:00
2016-01-24 02:30:03 +00:00
{{ -- Permission is hereby granted , free of charge , to any person obtaining a copy -- }}
{{ -- of this software and associated documentation files ( the " Software " ), to deal -- }}
{{ -- in the Software without restriction , including without limitation the rights -- }}
{{ -- to use , copy , modify , merge , publish , distribute , sublicense , and / or sell -- }}
{{ -- copies of the Software , and to permit persons to whom the Software is -- }}
{{ -- furnished to do so , subject to the following conditions : -- }}
2016-01-20 20:56:40 +00:00
2016-01-24 02:30:03 +00:00
{{ -- The above copyright notice and this permission notice shall be included in all -- }}
{{ -- copies or substantial portions of the Software . -- }}
2016-01-20 20:56:40 +00:00
2016-01-24 02:30:03 +00:00
{{ -- THE SOFTWARE IS PROVIDED " AS IS " , WITHOUT WARRANTY OF ANY KIND , EXPRESS OR -- }}
{{ -- IMPLIED , INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY , -- }}
{{ -- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT . IN NO EVENT SHALL THE -- }}
{{ -- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM , DAMAGES OR OTHER -- }}
{{ -- LIABILITY , WHETHER IN AN ACTION OF CONTRACT , TORT OR OTHERWISE , ARISING FROM , -- }}
{{ -- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -- }}
{{ -- SOFTWARE . -- }}
2016-01-05 05:52:20 +00:00
@ extends ( 'layouts.admin' )
@ section ( 'title' )
Managing Node : {{ $node -> name }}
@ endsection
2016-01-05 23:31:25 +00:00
@ section ( 'scripts' )
@ parent
2016-10-03 17:18:48 +00:00
{ !! Theme :: js ( 'js/vendor/socketio/socket.io.min.js' ) !! }
2016-02-06 04:27:43 +00:00
{ !! Theme :: js ( 'js/bootstrap-notify.min.js' ) !! }
2016-10-30 04:06:55 +00:00
{ !! Theme :: js ( 'js/vendor/chartjs/chart.min.js' ) !! }
{ !! Theme :: js ( 'js/vendor/jquery/jquery-dateFormat.min.js' ) !! }
2016-01-05 23:31:25 +00:00
< script >
$ ( document ) . ready ( function () {
$ . notifyDefaults ({
placement : {
from : 'bottom' ,
align : 'right'
},
newest_on_top : true ,
delay : 2000 ,
animate : {
enter : 'animated fadeInUp' ,
exit : 'animated fadeOutDown'
}
});
});
</ script >
@ endsection
2016-01-05 05:52:20 +00:00
@ section ( 'content' )
< div class = " col-md-12 " >
< ul class = " breadcrumb " >
< li >< a href = " /admin " > Admin Control </ a ></ li >
< li >< a href = " /admin/nodes " > Nodes </ a ></ li >
< li class = " active " > {{ $node -> name }} </ li >
</ ul >
< ul class = " nav nav-tabs tabs_with_panel " id = " config_tabs " >
< li class = " active " >< a href = " #tab_about " data - toggle = " tab " > About </ a ></ li >
< li >< a href = " #tab_settings " data - toggle = " tab " > Settings </ a ></ li >
2016-01-05 23:31:25 +00:00
< li >< a href = " #tab_configuration " data - toggle = " tab " > Configuration </ a ></ li >
2016-01-05 05:52:20 +00:00
< li >< a href = " #tab_allocation " data - toggle = " tab " > Allocation </ a ></ li >
< li >< a href = " #tab_servers " data - toggle = " tab " > Servers </ a ></ li >
2016-01-10 21:59:19 +00:00
@ if ( count ( $servers ) === 0 ) < li >< a href = " #tab_delete " data - toggle = " tab " > Delete </ a ></ li >@ endif
2016-01-05 05:52:20 +00:00
</ ul >
< div class = " tab-content " >
< div class = " tab-pane active " id = " tab_about " >
< div class = " panel panel-default " >
< div class = " panel-heading " ></ div >
< div class = " panel-body " >
2016-01-05 23:31:25 +00:00
< table class = " table table-striped " style = " margin-bottom:0; " >
< tbody >
2016-11-26 23:23:10 +00:00
< tr >
< td > Daemon Version </ td >
2016-11-28 18:41:26 +00:00
< td >< code data - attr = " info-version " >< i class = " fa fa-refresh fa-fw fa-spin " ></ i ></ code > ( Latest : < code > {{ Version :: getDaemon () }} </ code > ) </ td >
2016-11-26 23:23:10 +00:00
</ tr >
< tr >
< td > System Information </ td >
< td data - attr = " info-system " >< i class = " fa fa-refresh fa-fw fa-spin " ></ i ></ td >
</ tr >
< tr >
< td > Total CPU Cores </ td >
< td data - attr = " info-cpus " >< i class = " fa fa-refresh fa-fw fa-spin " ></ i ></ td >
</ tr >
2016-01-05 23:31:25 +00:00
< tr >
< td > Total Servers </ td >
< td > {{ count ( $servers ) }} </ td >
</ tr >
< tr >
< td > Memory Allocated </ td >
2016-01-17 01:19:52 +00:00
< td >< strong class = " { { ( $stats->memory < ( $node->memory * .8)) ? 'text-success' : 'text-danger' }} " > {{ is_numeric ( $stats -> memory ) ? $stats -> memory : 0 }} MB </ strong > of
2016-01-05 23:31:25 +00:00
@ if ( ! is_null ( $node -> memory_overallocate ))
< abbr data - toggle = " tooltip " data - placement = " top " title = " Allows up to { { ( $node->memory * (1 + ( $node->memory_overallocate / 100)) - $node->memory ) }} MB over " > {{ $node -> memory }} </ abbr >
@ else
{{ $node -> memory }}
@ endif
MB
</ td >
</ tr >
< tr >
< td > Disk Allocated </ td >
2016-01-17 01:19:52 +00:00
< td >< strong class = " { { ( $stats->disk < ( $node->disk * .8)) ? 'text-success' : 'text-danger' }} " > {{ is_numeric ( $stats -> disk ) ? $stats -> disk : 0 }} MB </ strong > of
2016-01-05 23:31:25 +00:00
@ if ( ! is_null ( $node -> disk_overallocate ))
< abbr data - toggle = " tooltip " data - placement = " top " title = " Allows up to { { ( $node->disk * (1 + ( $node->disk_overallocate / 100)) - $node->disk ) }} MB over " > {{ $node -> disk }} </ abbr >
@ else
{{ $node -> disk }}
@ endif
MB
</ td >
</ tr >
</ tbody >
</ table >
</ div >
< div class = " panel-heading " style = " border-top: 1px solid #ddd; " ></ div >
< div class = " panel-body " >
< div class = " row " >
2016-10-30 04:06:55 +00:00
< canvas id = " chart_memory " style = " max-height:300px; " ></ canvas >
< canvas id = " chart_cpu " style = " max-height:300px; " ></ canvas >
2016-01-05 23:31:25 +00:00
</ div >
2016-01-05 05:52:20 +00:00
</ div >
</ div >
</ div >
< div class = " tab-pane " id = " tab_settings " >
2016-01-05 23:31:25 +00:00
< form method = " POST " action = " /admin/nodes/view/ { { $node->id }} " >
< div class = " panel panel-default " >
< div class = " panel-heading " ></ div >
< div class = " panel-body " >
< div class = " alert alert-warning " >
Changing some details below may require that you change the configuration file on the node as well as restart the daemon . They have been marked with < span class = " label label-warning " >< i class = " fa fa-power-off " ></ i ></ span > below .
</ div >
< div class = " row " >
< div class = " form-group col-md-6 " >
< label for = " name " class = " control-label " > Node Name </ label >
< div >
< input type = " text " autocomplete = " off " name = " name " class = " form-control " value = " { { old('name', $node->name ) }} " />
< p class = " text-muted " >< small > Character limits : < code > a - zA - Z0 - 9_ .-</ code > and < code > [ Space ] </ code > ( min 1 , max 100 characters ) .</ small ></ p >
</ div >
</ div >
< div class = " form-group col-md-4 " >
< label for = " name " class = " control-label " > Location </ label >
< div >
< select name = " location " class = " form-control " >
@ foreach ( $locations as $location )
< option value = " { { $location->id }} " {{ ( old ( 'location' , $node -> location ) === $location -> id ) ? 'checked' : '' }} > {{ $location -> long }} ({{ $location -> short }}) </ option >
@ endforeach
</ select >
</ div >
</ div >
< div class = " form-group col-md-2 " >
< label for = " public " class = " control-label " > Public < sup >< a data - toggle = " tooltip " data - placement = " top " title = " Allow automatic allocation to this Node? " > ? </ a ></ sup ></ label >
< div >
< input type = " radio " name = " public " value = " 1 " {{ ( old ( 'public' , $node -> public ) === '1' ) ? 'checked' : '' }} id = " public_1 " checked > < label for = " public_1 " style = " padding-left:5px; " > Yes </ label >< br />
< input type = " radio " name = " public " value = " 0 " {{ ( old ( 'public' , $node -> public ) === '0' ) ? 'checked' : '' }} id = " public_0 " > < label for = " public_0 " style = " padding-left:5px; " > No </ label >
</ div >
</ div >
</ div >
< div class = " row " >
< div class = " form-group col-md-6 " >
< label for = " fqdn " class = " control-label " > Fully Qualified Domain Name </ label >
< div >
< input type = " text " autocomplete = " off " name = " fqdn " class = " form-control " value = " { { old('fqdn', $node->fqdn ) }} " />
</ div >
2016-08-16 22:45:22 +00:00
< p class = " text-muted " >< small > Please enter domain name ( e . g < code > node . example . com </ code > ) to be used for connecting to the daemon . An IP address may only be used if you are not using SSL for this node .
2016-01-05 23:31:25 +00:00
< a tabindex = " 0 " data - toggle = " popover " data - trigger = " focus " title = " Why do I need a FQDN? " data - content = " In order to secure communications between your server and this node we use SSL. We cannot generate a SSL certificate for IP Addresses, and as such you will need to provide a FQDN. " > Why ? </ a >
</ small ></ p >
</ div >
< div class = " form-group col-md-6 " >
< label for = " scheme " class = " control-label " >< span class = " label label-warning " >< i class = " fa fa-power-off " ></ i ></ span > Secure Socket Layer </ label >
< div class = " row " style = " padding: 7px 0; " >
< div class = " col-xs-6 " >
< input type = " radio " name = " scheme " value = " https " id = " scheme_ssl " {{ ( old ( 'scheme' , $node -> scheme ) === 'https' ) ? 'checked' : '' }} /> < label for = " scheme_ssl " style = " padding-left: 5px; " > Enable HTTPS / SSL </ label >
</ div >
< div class = " col-xs-6 " >
< input type = " radio " name = " scheme " value = " http " id = " scheme_nossl " {{ ( old ( 'scheme' , $node -> scheme ) === 'http' ) ? 'checked' : '' }} /> < label for = " scheme_nossl " style = " padding-left: 5px; " > Disable HTTPS / SSL </ label >
</ div >
</ div >
< p class = " text-muted " >< small > You should always leave SSL enabled for nodes . Disabling SSL could allow a malicious user to intercept traffic between the panel and the daemon potentially exposing sensitive information .</ small ></ p >
</ div >
</ div >
</ div >
< div class = " panel-heading " style = " border-top: 1px solid #ddd; " ></ div >
< div class = " panel-body " >
< div class = " row " >
< div class = " form-group col-md-3 col-xs-6 " >
< label for = " memory " class = " control-label " > Total Memory </ label >
< div class = " input-group " >
2016-11-27 00:56:19 +00:00
< input type = " text " name = " memory " class = " form-control " data - multiplicator = " true " value = " { { old('memory', $node->memory ) }} " />
2016-01-05 23:31:25 +00:00
< span class = " input-group-addon " > MB </ span >
</ div >
</ div >
< div class = " form-group col-md-3 col-xs-6 " >
< label for = " memory_overallocate " class = " control-label " > Overallocate </ label >
< div class = " input-group " >
< input type = " text " name = " memory_overallocate " class = " form-control " value = " { { old('memory_overallocate', $node->memory_overallocate ) }} " />
< span class = " input-group-addon " >%</ span >
</ div >
</ div >
< div class = " form-group col-md-3 col-xs-6 " >
< label for = " disk " class = " control-label " > Disk Space </ label >
< div class = " input-group " >
2016-11-27 00:56:19 +00:00
< input type = " text " name = " disk " class = " form-control " data - multiplicator = " true " value = " { { old('disk', $node->disk ) }} " />
2016-01-05 23:31:25 +00:00
< span class = " input-group-addon " > MB </ span >
</ div >
</ div >
< div class = " form-group col-md-3 col-xs-6 " >
< label for = " disk_overallocate " class = " control-label " > Overallocate </ label >
< div class = " input-group " >
< input type = " text " name = " disk_overallocate " class = " form-control " value = " { { old('disk_overallocate', $node->disk_overallocate ) }} " />
< span class = " input-group-addon " >%</ span >
</ div >
</ div >
</ div >
< div class = " row " >
< div class = " col-md-12 " >
< p class = " text-muted " >< small > Enter the total amount of disk space and memory avaliable for new servers . If you would like to allow overallocation of disk space or memory enter the percentage that you want to allow . To disable checking for overallocation enter < code >- 1 </ code > into the field . Entering < code > 0 </ code > will prevent creating new servers if it would put the node over the limit .</ small ></ p >
</ div >
</ div >
</ div >
< div class = " panel-heading " style = " border-top: 1px solid #ddd; " ></ div >
2016-12-01 23:32:05 +00:00
< div class = " panel-body " >
< div class = " row " >
< div class = " form-group col-md-6 " >
< label for = " disk_overallocate " class = " control-label " > Maximum Web Upload Filesize </ label >
< div class = " input-group " >
< input type = " text " name = " upload_size " class = " form-control " value = " { { old('upload_size', $node->upload_size ) }} " />
< span class = " input-group-addon " > MB </ span >
</ div >
< p class = " text-muted " >< small > Enter the maximum size of files that can be uploaded through the web - based file manager .</ small ></ p >
</ div >
</ div >
</ div >
< div class = " panel-heading " style = " border-top: 1px solid #ddd; " ></ div >
2016-01-05 23:31:25 +00:00
< div class = " panel-body " >
< div class = " row " >
< div class = " col-xs-6 " >
< div class = " row " >
< div class = " form-group col-md-6 " >
< label for = " daemonListen " class = " control-label " >< span class = " label label-warning " >< i class = " fa fa-power-off " ></ i ></ span > Daemon Port </ label >
< div >
< input type = " text " name = " daemonListen " class = " form-control " value = " { { old('daemonListen', $node->daemonListen ) }} " />
</ div >
</ div >
< div class = " form-group col-md-6 " >
< label for = " daemonSFTP " class = " control-label " >< span class = " label label-warning " >< i class = " fa fa-power-off " ></ i ></ span > Daemon SFTP Port </ label >
< div >
< input type = " text " name = " daemonSFTP " class = " form-control " value = " { { old('daemonSFTP', $node->daemonSFTP ) }} " />
</ div >
</ div >
</ div >
< div class = " row " >
< div class = " col-md-12 " >
< p class = " text-muted " >< small > The daemon runs its own SFTP management container and does not use the SSHd process on the main physical server . < Strong > Do not use the same port that you have assigned for your physcial server ' s SSH process .</ strong ></ small ></ p >
</ div >
</ div >
</ div >
< div class = " col-xs-6 " >
< div class = " row " >
< div class = " form-group col-md-12 " >
2016-12-01 23:33:32 +00:00
< label for = " reset_secret " class = " control-label " > Reset Daemon Key </ label >
2016-01-05 23:31:25 +00:00
< div style = " padding: 7px 0; " >
< input type = " checkbox " name = " reset_secret " id = " reset_secret " /> Reset Daemon Master Key
</ div >
</ div >
< div class = " col-md-12 " >
< p class = " text-muted " >< small > Resetting the daemon master key will void any request coming from the old key . This key is used for all sensitive operations on the daemon including server creation and deletion . We suggest changing this key regularly for security .</ small ></ p >
</ div >
</ div >
</ div >
</ div >
</ div >
< div class = " panel-heading " style = " border-top: 1px solid #ddd; " ></ div >
< div class = " panel-body " >
< div class = " row " >
< div class = " col-md-12 " >
{ !! csrf_field () !! }
< input type = " submit " class = " btn btn-sm btn-primary " value = " Update Node Information " />
</ div >
</ div >
</ div >
</ div >
</ form >
</ div >
< div class = " tab-pane " id = " tab_configuration " >
2016-01-05 05:52:20 +00:00
< div class = " panel panel-default " >
< div class = " panel-heading " ></ div >
< div class = " panel-body " >
2017-01-15 00:36:47 +00:00
< div class = " col-md-8 " >
< p class = " text-muted small " > To simplify the configuration of nodes it is possible to fetch the config from the panel . A token is required for this process . The button below will generate a token and provide you with the commands necessary for automatic configuration of the node . Be aware that these tokens are only valid for 5 minutes .</ p >
2016-01-05 23:31:25 +00:00
</ div >
2017-01-15 00:36:47 +00:00
< div class = " col-md-4 text-center " >
< p >< button type = " button " id = " configTokenBtn " class = " btn btn-sm btn-primary " style = " width:100%; " > Generate Token </ button ></ p >
2017-01-07 17:27:19 +00:00
</ div >
2016-01-05 23:31:25 +00:00
< div class = " col-md-12 " >
2017-01-07 17:09:04 +00:00
< pre >< code > {{ $node -> getConfigurationAsJson ( true ) }} </ code ></ pre >
2016-01-05 23:31:25 +00:00
</ div >
2016-01-05 05:52:20 +00:00
</ div >
</ div >
</ div >
< div class = " tab-pane " id = " tab_allocation " >
< div class = " panel panel-default " >
< div class = " panel-heading " ></ div >
2016-01-10 05:38:16 +00:00
< div class = " panel-body " >
< h4 style = " margin-top:0; " > Allocate Additional Ports </ h4 >
< form action = " { { route('admin.nodes.post.allocations', $node->id ) }} " method = " POST " >
< div class = " row " id = " duplicate " >
< div class = " col-md-4 fuelux " >
2016-10-21 21:33:26 +00:00
< label for = " " class = " control-label " > IP Address or FQDN </ label >
2016-01-10 05:38:16 +00:00
< div class = " input-group input-append dropdown combobox allocationComboBox " data - initialize = " combobox " >
< input type = " text " name = " allocate_ip[] " class = " form-control pillbox_ip " style = " border-right:0; " >
< div class = " input-group-btn " >
< button type = " button " class = " btn btn-sm btn-primary dropdown-toggle " data - toggle = " dropdown " >< span class = " caret " ></ span ></ button >
< ul class = " dropdown-menu dropdown-menu-right " >
2016-09-30 21:12:36 +00:00
@ foreach ( $allocation_ips as $allocation )
< li data - action = " alloc_dropdown_val " data - value = " { { $allocation->ip }} " >< a href = " # " > {{ $allocation -> ip }} </ a ></ li >
2016-01-10 05:38:16 +00:00
@ endforeach
</ ul >
</ div >
</ div >
</ div >
< div class = " form-group col-md-7 col-xs-10 fuelux " >
< label for = " " class = " control-label " > Ports </ label >
< div class = " pillbox allocationPillbox " data - initialize = " pillbox " >
< ul class = " clearfix pill-group " >
< li class = " pillbox-input-wrap btn-group " >
< input type = " text " class = " form-control dropdown-toggle pillbox-add-item " placeholder = " add port " >
</ li >
</ ul >
</ div >
2016-09-30 21:12:36 +00:00
< p class = " text-muted " >< small > You < strong > must </ strong > enter a comma ( < code > , </ code > ) or press the enter key after each port or range that you enter . They should appear in a blue box .</ small ></ p >
2016-01-10 05:38:16 +00:00
< input name = " allocate_port[] " type = " hidden " class = " pillboxMain " />
</ div >
< div class = " form-group col-md-1 col-xs-2 " style = " margin-left: -10px; " >
< label for = " " class = " control-label " >& nbsp ; </ label >
< button class = " btn btn-danger btn-allocate-delete removeClone disabled " >< i class = " fa fa-close " ></ i ></ button >
</ div >
</ div >
< div class = " row " >
< div class = " col-md-12 " >
< hr />
{ !! csrf_field () !! }
< input type = " submit " class = " btn btn-sm btn-primary " value = " Add Ports " />
< button class = " btn btn-success btn-sm cloneElement " > Add More Rows </ button >
</ div >
</ div >
</ form >
</ div >
2016-09-30 01:34:20 +00:00
< div class = " panel-heading " style = " border-top: 1px solid #ddd; " ></ div >
< div class = " panel-body " >
< div class = " row " >
< table class = " table table-hover " style = " margin-bottom:0; " >
< thead style = " font-weight:bold; " >
< td > IP Address < i class = " fa fa-fw fa-minus-square " style = " font-weight:normal;color:#d9534f;cursor:pointer; " data - toggle = " modal " data - target = " #allocationModal " ></ i ></ td >
< td > IP Alias </ td >
< td > Port </ td >
< td > Assigned To </ td >
< td ></ td >
</ thead >
< tbody >
@ foreach ( $allocations as $allocation )
< tr >
< td class = " col-sm-3 align-middle " > {{ $allocation -> ip }} </ td >
< td class = " col-sm-3 align-middle " >
< input class = " form-control input-sm " type = " text " value = " { { $allocation->ip_alias }} " data - action = " set-alias " data - id = " { { $allocation->id }} " placeholder = " none " />
< span class = " input-loader " >< i class = " fa fa-refresh fa-spin fa-fw " ></ i ></ span >
</ td >
< td class = " col-sm-2 align-middle " > {{ $allocation -> port }} </ td >
< td class = " col-sm-3 align-middle " >@ if ( ! is_null ( $allocation -> assigned_to )) < a href = " { { route('admin.servers.view', $allocation->assigned_to ) }} " > {{ $allocation -> assigned_to_name }} </ a >@ endif </ td >
< td class = " col-sm-1 align-middle " >
@ if ( is_null ( $allocation -> assigned_to ))
< a href = " # " data - action = " deallocate " data - id = " { { $allocation->id }} " >< span class = " badge label-danger " >< i class = " fa fa-trash-o " ></ i ></ span ></ a >
@ else
< span class = " badge label-default " >< i class = " fa fa-trash-o " ></ i ></ span >
@ endif
</ td >
</ tr >
@ endforeach
</ tbody >
</ table >
< div class = " col-md-12 text-center " >
{{ $allocations -> appends ([ 'tab' => 'tab_allocation' ]) -> links () }}
</ div >
</ div >
</ div >
2016-01-05 05:52:20 +00:00
</ div >
</ div >
< div class = " tab-pane " id = " tab_servers " >
< div class = " panel panel-default " >
< div class = " panel-heading " ></ div >
< div class = " panel-body " >
< div class = " alert alert-info " >
2016-01-05 23:31:25 +00:00
The data below is live output from the daemon . CPU usage is displayed relative to the assigned CPU allocation . For example , if a server is assigned < code > 10 %</ code > and the CPU usage below displays < code > 90 %</ code > that means the server is using < code > 9 %</ code > of the total system CPU .
2016-01-05 05:52:20 +00:00
</ div >
< table class = " table table-striped " style = " margin-bottom: 0; " >
< thead >
< tr >
< th > Name </ th >
< th > Owner </ th >
< th > Service </ th >
< th class = " text-center " > Memory </ th >
< th class = " text-center " > Disk </ th >
< th class = " text-center " > CPU </ th >
< th class = " text-center " > Status </ th >
</ tr >
</ thead >
< tbody >
@ foreach ( $servers as $server )
< tr data - server = " { { $server->uuid }} " >
< td >< a href = " /admin/servers/view/ { { $server->id }} " > {{ $server -> name }} </ a ></ td >
< td >< a href = " /admin/users/view/ { { $server->owner }} " >< code > {{ $server -> a_ownerEmail }} </ a ></ a ></ td >
< td > {{ $server -> a_serviceName }} </ td >
2016-02-15 00:42:10 +00:00
< td class = " text-center " >< span data - action = " memory " >--</ span > / {{ $server -> memory === 0 ? '∞' : $server -> memory }} MB </ td >
2016-01-05 05:52:20 +00:00
< td class = " text-center " > {{ $server -> disk }} MB </ td >
< td class = " text-center " >< span data - action = " cpu " data - cpumax = " { { $server->cpu }} " >--</ span > %</ td >
< td class = " text-center " data - action = " status " >--</ td >
</ tr >
@ endforeach
</ tbody >
</ table >
< div class = " row " >
< div class = " col-md-12 text-center " > { !! $servers -> appends ([ 'tab' => 'tab_servers' ]) -> render () !! } </ div >
</ div >
</ div >
</ div >
</ div >
2016-01-10 21:59:19 +00:00
@ if ( count ( $servers ) === 0 )
< div class = " tab-pane " id = " tab_delete " >
< div class = " panel panel-default " >
< div class = " panel-heading " ></ div >
< div class = " panel-body " >
< div class = " row " >
< div class = " col-xs-4 text-center " >
< form action = " { { route('admin.nodes.delete', $node->id ) }} " method = " POST " id = " deleteNodeForm " >
{ !! method_field ( 'DELETE' ) !! }
{ !! csrf_field () !! }
2016-02-06 04:58:13 +00:00
< input type = " submit " value = " Delete Node " class = " btn btn-sm btn-danger " />
2016-01-10 21:59:19 +00:00
</ form >
</ div >
< div class = " col-xs-8 " >
< div class = " alert alert-danger " style = " margin-bottom:0; " > Deleting this node is a permanent action , it cannot be undone .</ div >
</ div >
</ div >
</ div >
2016-01-05 05:52:20 +00:00
</ div >
</ div >
2016-01-10 21:59:19 +00:00
@ endif
2016-01-05 05:52:20 +00:00
</ div >
2016-01-05 23:31:25 +00:00
< div class = " row " >
< div class = " col-xs-11 " id = " col11_setter " ></ div >
</ div >
2016-01-05 05:52:20 +00:00
</ div >
2016-09-30 01:34:20 +00:00
< div class = " modal fade " id = " allocationModal " tabindex = " -1 " role = " dialog " >
< div class = " modal-dialog " role = " document " >
< div class = " modal-content " >
< div class = " modal-header " >
< button type = " button " class = " close " data - dismiss = " modal " aria - label = " Close " >< span aria - hidden = " true " >& times ; </ span ></ button >
< h4 class = " modal-title " > Delete Allocations for IP Block </ h4 >
</ div >
< form action = " { { route('admin.nodes.view', $node->id ) }}/deallocate/block " method = " POST " >
< div class = " modal-body " >
< div class = " row " >
< div class = " col-md-12 " >
< select class = " form-control " name = " ip " >
2016-09-30 21:12:36 +00:00
@ foreach ( $allocation_ips as $allocation )
< option value = " { { $allocation->ip }} " > {{ $allocation -> ip }} </ option >
2016-09-30 01:34:20 +00:00
@ endforeach
</ select >
</ div >
</ div >
</ div >
< div class = " modal-footer " >
{{{ csrf_field () }}}
< button type = " button " class = " btn btn-default " data - dismiss = " modal " > Close </ button >
< button type = " submit " class = " btn btn-danger " > Delete Allocations </ button >
</ div >
</ form >
</ div >
</ div >
</ div >
2016-01-05 05:52:20 +00:00
< script >
$ ( document ) . ready ( function () {
$ ( '#sidebar_links' ) . find ( " a[href='/admin/nodes'] " ) . addClass ( 'active' );
2016-01-05 23:31:25 +00:00
$ ( '[data-toggle="tooltip"]' ) . tooltip ();
$ ( '[data-toggle="popover"]' ) . popover ({
placement : 'auto'
});
2016-01-05 05:52:20 +00:00
2016-01-10 21:59:19 +00:00
$ ( '#deleteNodeForm' ) . submit ( function ( event ) {
event . preventDefault ();
swal ({
type : 'warning' ,
title : 'Are You Sure?' ,
text : 'This will immediately delete this node, there is no undo.' ,
showCancelButton : true ,
allowOutsideClick : true ,
confirmButtonText : 'Delete' ,
confirmButtonColor : '#d9534f' ,
}, function () {
event . target . submit ();
});
});
2017-01-07 17:27:19 +00:00
$ ( '#configTokenBtn' ) . on ( 'click' , function ( event ) {
2017-01-08 14:21:02 +00:00
$ . getJSON ( '{{ route(' admin . nodes . configuration - token ', $node->id) }}' )
2017-01-07 17:27:19 +00:00
. done ( function ( data ) {
swal ({
type : 'success' ,
title : 'Token created.' ,
2017-01-15 00:36:47 +00:00
text : 'Your token will expire at ' + data . expires_at + '<br /><br />' +
2017-01-23 00:02:10 +00:00
'<p>To auto-configure your node run<br /><small><pre>npm run configure -- --panel-url {{ config(' app . url ') }} --token ' + data . token + '</pre></small></p>' ,
2017-01-07 17:27:19 +00:00
html : true
})
})
. fail ( function () {
swal ({
title : 'Error' ,
text : 'Something went wrong creating your token.' ,
type : 'error'
});
})
})
2016-01-10 05:38:16 +00:00
$ ( '.cloneElement' ) . on ( 'click' , function ( event ) {
event . preventDefault ();
var rnd = randomKey ( 10 );
2016-10-21 21:33:26 +00:00
var cloned = $ ( '#duplicate' ) . clone () . attr ( 'id' , rnd );
2016-01-10 05:38:16 +00:00
cloned . find ( '.allocationPillbox' ) . removeClass ( 'allocationPillbox' ) . addClass ( 'allocationPillbox_' + rnd );
cloned . find ( '.pillboxMain' ) . removeClass ( 'pillboxMain' ) . addClass ( 'pillbox_' + rnd );
2016-10-21 21:33:26 +00:00
cloned . find ( '.removeClone' ) . removeClass ( 'disabled' ) . attr ( 'data-parent' , rnd );
2016-01-10 05:38:16 +00:00
cloned . find ( '.pillbox_ip' ) . removeClass ( 'pillbox_ip' ) . addClass ( 'pillbox_ip_' + rnd );
cloned . insertAfter ( '#duplicate' );
$ ( '.allocationPillbox_' + rnd ) . pillbox ();
$ ( '.allocationPillbox_' + rnd ) . on ( 'added.fu.pillbox edited.fu.pillbox removed.fu.pillbox' , function pillboxChanged () {
$ ( '.pillbox_' + rnd ) . val ( JSON . stringify ( $ ( '.allocationPillbox_' + rnd ) . pillbox ( 'items' )));
});
2016-10-21 21:33:26 +00:00
$ ( '.removeClone' ) . unbind () . on ( 'click' , function ( event ) {
2016-01-10 05:38:16 +00:00
event . preventDefault ();
var element = $ ( this );
2016-10-21 21:33:26 +00:00
$ ( '#' + element . attr ( 'data-parent' )) . slideUp ( function () {
2016-01-10 05:38:16 +00:00
element . remove ();
2016-10-21 21:33:26 +00:00
$ ( '.pillbox_' + element . attr ( 'data-parent' )) . remove ();
$ ( '.pillbox_ip_' + element . attr ( 'data-parent' )) . remove ();
2016-01-10 05:38:16 +00:00
});
});
2016-10-21 21:33:26 +00:00
});
2016-01-10 05:38:16 +00:00
$ ( '.allocationPillbox' ) . pillbox ();
$ ( '.allocationComboBox' ) . combobox ();
$ ( '.allocationPillbox' ) . on ( 'added.fu.pillbox edited.fu.pillbox removed.fu.pillbox' , function pillboxChanged () {
$ ( '.pillboxMain' ) . val ( JSON . stringify ( $ ( '.allocationPillbox' ) . pillbox ( 'items' )));
});
2016-01-05 23:31:25 +00:00
var notifySocketError = false ;
var Status = {
0 : 'Off' ,
1 : 'On' ,
2 : 'Starting' ,
3 : 'Stopping'
};
// Main Socket Object
var socket = io ( '{{ $node->scheme }}://{{ $node->fqdn }}:{{ $node->daemonListen }}/stats/' , {
'query' : 'token={{ $node->daemonSecret }}'
});
// Socket Failed to Connect
socket . io . on ( 'connect_error' , function ( err ) {
if ( typeof notifySocketError !== 'object' ) {
notifySocketError = $ . notify ({
message : '{!! trans(' server . ajax . socket_error ') !!}'
}, {
type : 'danger' ,
delay : 0
2016-01-05 05:52:20 +00:00
});
2016-01-05 23:31:25 +00:00
}
});
// Connected to Socket Successfully
socket . on ( 'connect' , function () {
if ( notifySocketError !== false ) {
notifySocketError . close ();
notifySocketError = false ;
}
});
socket . on ( 'error' , function ( err ) {
console . error ( 'There was an error while attemping to connect to the websocket: ' + err + '\n\nPlease try loading this page again.' );
});
2016-10-30 04:06:55 +00:00
var ctc = $ ( '#chart_cpu' );
var timeLabels = [];
var cpuData = [];
var CPUChart = new Chart ( ctc , {
type : 'line' ,
data : {
labels : timeLabels ,
datasets : [
{
label : " Percent Use " ,
fill : false ,
lineTension : 0.03 ,
backgroundColor : " #00A1CB " ,
borderColor : " #00A1CB " ,
borderCapStyle : 'butt' ,
borderDash : [],
borderDashOffset : 0.0 ,
borderJoinStyle : 'miter' ,
pointBorderColor : " rgba(75,192,192,1) " ,
pointBackgroundColor : " #fff " ,
pointBorderWidth : 1 ,
pointHoverRadius : 5 ,
pointHoverBackgroundColor : " rgba(75,192,192,1) " ,
pointHoverBorderColor : " rgba(220,220,220,1) " ,
pointHoverBorderWidth : 2 ,
pointRadius : 1 ,
pointHitRadius : 10 ,
data : cpuData ,
spanGaps : false ,
}
]
},
options : {
title : {
display : true ,
text : 'CPU Usage (as Percent Total)'
},
legend : {
display : false ,
},
animation : {
duration : 1 ,
}
2016-10-21 21:37:47 +00:00
}
2016-10-30 04:06:55 +00:00
});
var ctm = $ ( '#chart_memory' );
var memoryData = [];
var MemoryChart = new Chart ( ctm , {
type : 'line' ,
data : {
labels : timeLabels ,
datasets : [
{
label : " Memory Use " ,
fill : false ,
lineTension : 0.03 ,
backgroundColor : " #01A4A4 " ,
borderColor : " #01A4A4 " ,
borderCapStyle : 'butt' ,
borderDash : [],
borderDashOffset : 0.0 ,
borderJoinStyle : 'miter' ,
pointBorderColor : " rgba(75,192,192,1) " ,
pointBackgroundColor : " #fff " ,
pointBorderWidth : 1 ,
pointHoverRadius : 5 ,
pointHoverBackgroundColor : " rgba(75,192,192,1) " ,
pointHoverBorderColor : " rgba(220,220,220,1) " ,
pointHoverBorderWidth : 2 ,
pointRadius : 1 ,
pointHitRadius : 10 ,
data : memoryData ,
spanGaps : false ,
}
]
},
options : {
title : {
display : true ,
text : 'Memory Usage (in Megabytes)'
},
legend : {
display : false ,
},
animation : {
duration : 1 ,
}
2016-10-21 21:37:47 +00:00
}
2016-10-30 04:06:55 +00:00
});
2016-10-21 21:37:47 +00:00
2016-10-30 04:06:55 +00:00
socket . on ( 'live-stats' , function ( data ) {
if ( cpuData . length > 10 ) {
cpuData . shift ();
memoryData . shift ();
timeLabels . shift ();
}
2016-10-21 21:37:47 +00:00
2016-10-30 04:06:55 +00:00
cpuData . push ( data . stats . cpu );
memoryData . push ( parseInt ( data . stats . memory / ( 1024 * 1024 )));
2016-10-21 21:37:47 +00:00
2016-10-30 04:06:55 +00:00
var m = new Date ();
2016-11-19 20:57:58 +00:00
timeLabels . push ( $ . format . date ( new Date (), 'HH:mm:ss' ));
2016-02-06 06:29:24 +00:00
2016-10-30 04:06:55 +00:00
CPUChart . update ();
MemoryChart . update ();
2016-01-05 23:31:25 +00:00
$ . each ( data . servers , function ( uuid , info ) {
var element = $ ( 'tr[data-server="' + uuid + '"]' );
element . find ( '[data-action="status"]' ) . html ( Status [ info . status ]);
if ( info . status !== 0 ) {
var cpuMax = element . find ( '[data-action="cpu"]' ) . data ( 'cpumax' );
var currentCpu = info . proc . cpu . total ;
if ( cpuMax !== 0 ) {
currentCpu = parseFloat ((( info . proc . cpu . total / cpuMax ) * 100 ) . toFixed ( 2 ) . toString ());
}
element . find ( '[data-action="memory"]' ) . html ( parseInt ( info . proc . memory . total / ( 1024 * 1024 )));
element . find ( '[data-action="cpu"]' ) . html ( currentCpu );
} else {
element . find ( '[data-action="memory"]' ) . html ( '--' );
element . find ( '[data-action="cpu"]' ) . html ( '--' );
}
2016-01-05 05:52:20 +00:00
});
2016-01-05 23:31:25 +00:00
});
2016-01-09 01:01:18 +00:00
$ ( 'span[data-action="delete"]' ) . hover ( function () {
$ ( this ) . find ( 'i' ) . css ( 'color' , '#d9534f' ) . removeClass ( 'fa-square-o' ) . addClass ( 'fa-minus-square' );
}, function () {
$ ( this ) . find ( 'i' ) . css ( 'color' , 'inherit' ) . addClass ( 'fa-square-o' ) . removeClass ( 'fa-minus-square' );
});
2016-09-30 01:34:20 +00:00
$ ( 'a[data-action="deallocate"]' ) . click ( function ( event ) {
2016-01-09 01:01:18 +00:00
event . preventDefault ();
var element = $ ( this );
2016-09-30 01:34:20 +00:00
var allocation = $ ( this ) . data ( 'id' );
2016-01-09 01:01:18 +00:00
swal ({
title : '' ,
2016-09-30 01:34:20 +00:00
text : 'Are you sure you want to delete this allocation?' ,
2016-01-09 01:01:18 +00:00
type : 'warning' ,
showCancelButton : true ,
allowOutsideClick : true ,
closeOnConfirm : false ,
confirmButtonText : 'Delete' ,
confirmButtonColor : '#d9534f' ,
showLoaderOnConfirm : true
}, function () {
$ . ajax ({
method : 'DELETE' ,
2016-09-30 01:34:20 +00:00
url : '{{ route(' admin . nodes . view ', $node->id) }}/deallocate/single/' + allocation ,
2016-01-09 01:01:18 +00:00
headers : {
'X-CSRF-TOKEN' : '{{ csrf_token() }}'
}
}) . done ( function ( data ) {
2016-09-30 01:34:20 +00:00
element . parent () . parent () . addClass ( 'warning' ) . delay ( 100 ) . fadeOut ();
2016-01-09 01:01:18 +00:00
swal ({
type : 'success' ,
title : 'Port Deleted!' ,
});
}) . fail ( function ( jqXHR ) {
console . error ( jqXHR );
swal ({
title : 'Whoops!' ,
text : jqXHR . responseJSON . error ,
type : 'error'
});
});
});
});
2016-09-30 01:34:20 +00:00
var typingTimer ;
$ ( 'input[data-action="set-alias"]' ) . keyup ( function () {
clearTimeout ( typingTimer );
$ ( this ) . parent () . removeClass ( 'has-error has-success' );
typingTimer = setTimeout ( sendAlias , 700 , $ ( this ));
});
var fadeTimers = [];
function sendAlias ( element ) {
element . parent () . find ( '.input-loader' ) . show ();
clearTimeout ( fadeTimers [ element . data ( 'id' )]);
$ . ajax ({
method : 'POST' ,
url : '{{ route(' admin . nodes . alias ', $node->id) }}' ,
headers : {
'X-CSRF-TOKEN' : '{{ csrf_token() }}'
},
data : {
alias : element . val (),
allocation : element . data ( 'id' )
}
}) . done ( function ( data ) {
element . parent () . addClass ( 'has-success' );
}) . fail ( function ( jqXHR ) {
console . error ( jqXHR );
element . parent () . addClass ( 'has-error' );
}) . always ( function () {
element . parent () . find ( '.input-loader' ) . hide ();
fadeTimers [ element . data ( 'id' )] = setTimeout ( clearHighlight , 2500 , element );
});
}
function clearHighlight ( element ) {
element . parent () . removeClass ( 'has-error has-success' );
}
2016-11-26 23:23:10 +00:00
( function getInformation () {
$ . ajax ({
method : 'GET' ,
url : '{{ $node->scheme }}://{{ $node->fqdn }}:{{ $node->daemonListen }}' ,
timeout : 5000 ,
headers : {
'X-Access-Token' : '{{ $node->daemonSecret }}'
},
}) . done ( function ( data ) {
$ ( '[data-attr="info-version"]' ) . html ( data . version );
$ ( '[data-attr="info-system"]' ) . html ( data . system . type + '(' + data . system . arch + ') <code>' + data . system . release + '</code>' );
$ ( '[data-attr="info-cpus"]' ) . html ( data . system . cpus );
}) . fail ( function ( jqXHR ) {
}) . always ( function () {
setTimeout ( getInformation , 10000 );
});
})();
2016-01-05 05:52:20 +00:00
});
</ script >
@ endsection