Skip to content

Commit

Permalink
Hide advanced features behind config flags (#320)
Browse files Browse the repository at this point in the history
* Hide some of the more advanced features behind environment variables

* Fix default login path

* Show Console by default

* Added showLogs and showConfig flags

* Remove unused envvar

* fix bad merge

* Remove debug variable
  • Loading branch information
bodom0015 authored Jun 10, 2020
1 parent 842e66d commit 8bb830c
Show file tree
Hide file tree
Showing 9 changed files with 83 additions and 37 deletions.
18 changes: 17 additions & 1 deletion gui/ConfigModule.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,22 @@ angular
* Make lodash available for injection into controllers
*/
.constant('_', window._)

/**
* Toggles for hiding the more advanced UI features
*/
.constant('AdvancedFeatures', {
showConsole: true,
showEditService: false,
showRemoveService: false,
showCreateSpec: false,
showImportSpec: false,
showFileManager: false,
showServiceHelpIcon: false,
showLogs: false,
showConfig: false,
})

/**
* The back-up (default) administrator e-mail to use for support,
* in case the /api/contact endpoint is unavailable
Expand Down Expand Up @@ -46,7 +62,7 @@ angular
.constant('EditSpecPathSuffix', '/store/edit/:specKey/')

// Navigate here when clicking "Sign In"
.constant('SigninUrl', 'https://www.local.ndslabs.org/oauth2/authorize')
.constant('SigninUrl', 'https://www.local.ndslabs.org/login/')

/**
* The name of the product to display in the UI and the URL to link to when clicked
Expand Down
8 changes: 8 additions & 0 deletions gui/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,14 @@ ENV APISERVER_HOST="localhost" \
APISERVER_PATH="/api" \
APISERVER_SECURE="true" \
ANALYTICS_ACCOUNT="" \
SHOW_CONSOLE="true" \
SHOW_CONFIG="false" \
SHOW_LOGS="false" \
SHOW_IMPORT_SPEC="false" \
SHOW_CREATE_SPEC="false" \
SHOW_FILE_MANAGER="false" \
SHOW_EDIT_SERVICE="false" \
SHOW_SVC_HELP_ICON="false" \
SUPPORT_EMAIL="[email protected]"

# Expose port 3000 for ExpressJS
Expand Down
6 changes: 4 additions & 2 deletions gui/dashboard/catalog/CatalogController.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,12 @@ angular
* @see https://opensource.ncsa.illinois.edu/confluence/display/~lambert8/3.%29+Controllers%2C+Scopes%2C+and+Partial+Views
*/
.controller('CatalogController', [ '$scope', '$filter', '$interval', '$uibModal', '$location', '$log', '_', 'Analytics', 'NdsLabsApi', 'Project', 'Stack', 'Stacks',
'StackService', 'Specs', 'clipboard', 'Vocabulary', 'RandomPassword', 'AuthInfo', 'ProductName', 'ApiUri', 'DashboardAppPath', 'HomePathSuffix',
function($scope, $filter, $interval, $uibModal, $location, $log, _, Analytics, NdsLabsApi, Project, Stack, Stacks, StackService, Specs, clipboard, Vocabulary, RandomPassword, AuthInfo, ProductName, ApiUri, DashboardAppPath, HomePathSuffix) {
'StackService', 'Specs', 'clipboard', 'Vocabulary', 'RandomPassword', 'AuthInfo', 'ProductName', 'ApiUri', 'DashboardAppPath', 'HomePathSuffix', 'AdvancedFeatures',
function($scope, $filter, $interval, $uibModal, $location, $log, _, Analytics, NdsLabsApi, Project, Stack, Stacks, StackService, Specs, clipboard, Vocabulary, RandomPassword, AuthInfo, ProductName, ApiUri, DashboardAppPath, HomePathSuffix, AdvancedFeatures) {
"use strict";

$scope.showCreateSpec = AdvancedFeatures.showCreateSpec;
$scope.showImportSpec = AdvancedFeatures.showImportSpec;
$scope.productName = ProductName;

$scope.tags = { all: [], selected: [] };
Expand Down
4 changes: 2 additions & 2 deletions gui/dashboard/catalog/catalog.html
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,11 @@ <h3>Applications</h3>
</button>
</div>
<div class="input-group-btn">
<button id="importApplicationBtn" type="button" class="btn btn-secondary" ng-click="openImport()" style="border-radius:0;">
<button id="importApplicationBtn" ng-if="showImportSpec" type="button" class="btn btn-secondary" ng-click="openImport()" style="border-radius:0;">
<i class="fa fa-fw fa-upload"></i> Import
</button>
</div>
<div class="input-group-btn">
<div class="input-group-btn" ng-if="showCreateSpec">
<a id="createApplicationBtn" type="button" class="btn btn-primary" href="/dashboard/store/add">
<i class="fa fa-fw fa-plus"></i> Create
</a>
Expand Down
14 changes: 9 additions & 5 deletions gui/dashboard/dashboard/DashboardController.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,20 @@ angular
* @author lambert8
* @see https://opensource.ncsa.illinois.edu/confluence/display/~lambert8/3.%29+Controllers%2C+Scopes%2C+and+Partial+Views
*/
.controller('DashboardController', [ '$scope', 'Loading', '$log', '$routeParams', '$location', '$interval', '$q', '$window', '$filter', '$uibModal', '_', 'Analytics', 'Project', 'RandomPassword', 'Stack', 'Stacks', 'Specs', 'AutoRefresh', 'AuthInfo',
'StackService', 'NdsLabsApi', 'ProductName', 'FileManager', 'QuickStart',
function($scope, Loading, $log, $routeParams, $location, $interval, $q, $window, $filter, $uibModal, _, Analytics, Project, RandomPassword, Stack, Stacks, Specs, AutoRefresh, AuthInfo, StackService, NdsLabsApi,
ProductName, FileManager, QuickStart) {
.controller('DashboardController', [ '$scope', 'Loading', '$log', '$routeParams', '$location', '$interval', '$q', '$window', '$filter', '$uibModal', '_', 'Analytics', 'Project', 'RandomPassword', 'Stack', 'Stacks', 'Specs', 'AutoRefresh', 'AuthInfo', 'StackService', 'NdsLabsApi', 'ProductName', 'FileManager', 'QuickStart', 'AdvancedFeatures',
function($scope, Loading, $log, $routeParams, $location, $interval, $q, $window, $filter, $uibModal, _, Analytics, Project, RandomPassword, Stack, Stacks, Specs, AutoRefresh, AuthInfo, StackService, NdsLabsApi, ProductName, FileManager, QuickStart, AdvancedFeatures) {
"use strict";

if ($routeParams.quickstart) {
QuickStart.get($routeParams.quickstart).launch();
}


$scope.showRemoveService = AdvancedFeatures.showRemoveService;
$scope.showServiceHelpIcon = AdvancedFeatures.showServiceHelpIcon;
$scope.showEditService = AdvancedFeatures.showEditService;
$scope.showConsole = AdvancedFeatures.showConsole;
$scope.showConfigColumn = AdvancedFeatures.showConfig;
$scope.showLogsColumn = AdvancedFeatures.showLogs;
$scope.fileManager = FileManager;

$scope.productName = ProductName;
Expand Down
52 changes: 28 additions & 24 deletions gui/dashboard/dashboard/dashboard.html
Original file line number Diff line number Diff line change
Expand Up @@ -79,24 +79,21 @@ <h4>
<!-- Application Services -->
<div class="row">
<div class="col-sm-12">

<!-- List off our stack's services here -->
<div class="table-responsive">
<table class="table table-striped table-hover">
<thead>
<tr>
<td width="15%" class="text-center"><strong>Status</strong></td>
<td width="20%"><strong>Name</strong></td>
<td width="20%" tooltip-append-to-body="true" uib-tooltip="A unique identifier for each part of an application instance"><strong>ID</strong></td>
<td width="10%" class="text-center" tooltip-append-to-body="true" uib-tooltip="Advanced user terminal, allowing for arbitrary console commands"><strong>Console</strong></td>
<td width="10%" class="text-center" tooltip-append-to-body="true" uib-tooltip="{{ (stack.status === 'stopped' ? 'Edit' : 'View') + ' the configuration for part of an application' }}">
<strong ng-if="stack.status !== 'stopped'">Config</strong>
<strong ng-if="stack.status === 'stopped'">Edit</strong>
</td>
<td width="10%" class="text-center" tooltip-append-to-body="true" uib-tooltip="{{ (stack.status === 'stopped' ? 'Remove an optional ' : 'View the logs for ') + 'part of an application' }}">
<strong ng-if="stack.status !== 'stopped'">Logs</strong>
<strong ng-if="stack.status === 'stopped'">Remove</strong>
</td>
<td width="10%" class="text-center" tooltip-append-to-body="true" uib-tooltip="Additional instructions or documentation for a part of an application"><strong>Help</strong></td>
<td><strong>Name</strong></td>
<td tooltip-append-to-body="true" uib-tooltip="A unique identifier for each part of an application instance"><strong>ID</strong></td>
<td width="5%" class="text-center" ng-if="showConsole" tooltip-append-to-body="true" uib-tooltip="Advanced user terminal, allowing for arbitrary console commands"><strong>Console</strong></td>
<td width="5%" class="text-center" ng-if="showEditService && stack.status === 'stopped'" tooltip-append-to-body="true" uib-tooltip="Edit the configuration for part of an application"><strong>Edit</strong></td>
<td width="5%" class="text-center" ng-if="showConfigColumn && stack.status !== 'stopped'" tooltip-append-to-body="true" uib-tooltip="View the configuration for part of an application"><strong >Config</strong></td>
<td width="5%" class="text-center" ng-if="showLogsColumn && stack.status !== 'stopped'" tooltip-append-to-body="true" uib-tooltip="View the logs for part of an application"><strong >Logs</strong></td>
<td width="5%" class="text-center" ng-if="showRemoveService && stack.status === 'stopped'" tooltip-append-to-body="true" uib-tooltip="Remove an optional part of an application"><strong>Remove</strong></td>
<td width="5%" class="text-center" ng-if="showServiceHelpIcon" tooltip-append-to-body="true" uib-tooltip="Additional instructions or documentation for a part of an application"><strong>Help</strong></td>
</tr>
</thead>
<tbody>
Expand All @@ -116,8 +113,8 @@ <h4>
</td>

<!-- The Name of the Running Service and link to endpoint, if applicable -->
<td tooltip-append-to-body="true" uib-tooltip="A friendly label for this application instance">
{{ svc.service | specProperty:'label' }}
<td>
<span tooltip-append-to-body="true" uib-tooltip="A friendly label for this application instance">{{ svc.service | specProperty:'label' }}</span>

<a class="btn btn-link btn-sm" ng-repeat="endpt in svc.endpoints track by endpt.port" id="endpointLink"
tooltip-append-to-body="true" uib-tooltip="Navigate to {{ svc.service | capitalize }} port {{ endpt.port }}"
Expand All @@ -134,40 +131,47 @@ <h4>
<td tooltip-append-to-body="true" uib-tooltip="A unique identifier for this part of the application instance"><span id="serviceIdText">{{ svc.id }}</span></td>

<!-- Console -->
<td class="text-center" tooltip-append-to-body="true" uib-tooltip="{{ (stack.status === 'stopped' ? 'The application must be launched before the Console can be accessed' : 'Advanced user terminal, allowing for arbitrary console commands') }}">
<td class="text-center" ng-if="showConsole" tooltip-append-to-body="true" uib-tooltip="{{ (stack.status === 'stopped' ? 'The application must be launched before the Console can be accessed' : 'Advanced user terminal, allowing for arbitrary console commands') }}">
<a id="consoleBtn"
ga-track-event="['application', 'console', svc.service, 1, true]"
type="button" class="btn btn-default btn-xs" target="_blank" ng-href="/dashboard/home/{{ stack.id }}/console/{{ svc.service }}"
ng-disabled="svc.status !== 'ready'">
<i class="fa fa-terminal"></i>
</a>
</td>

<!-- Edit Config buttons -->
<td class="text-center" ng-if="showEditService" tooltip-append-to-body="true" uib-tooltip="Edit the configuration for this part of the application">

<!-- View/Edit Config buttons -->
<td class="text-center" tooltip-append-to-body="true" uib-tooltip="{{ (stack.status === 'stopped' ? 'View' : 'Edit') + ' the configuration for this part of the application' }}">
<!-- ng-click="showConfig(svc)" -->
<a id="editServiceBtn" type="button" class="btn btn-default btn-xs" ng-href="/dashboard/home/{{ stack.id }}/edit/{{ svc.service }}"
ng-if="stack.status === 'stopped'" ga-track-event="['application', 'edit', svc.service, 1, true]">
<i class="fa fa-wrench"></i>
</a>

</td>

<!-- View Config buttons -->
<td class="text-center" ng-if="showConfigColumn && stack.status !== 'stopped'">
<button id="viewConfigBtn" type="button" class="btn btn-default btn-xs" ng-click="showConfig(svc)"
ng-if="stack.status !== 'stopped' && (!_.isEmpty(svc.config) || svc.endpoints.length > 0)">
ng-if="!_.isEmpty(svc.config) || svc.endpoints.length > 0">
<i class="fa fa-puzzle-piece"></i>
</button>
</td>

<!-- View Logs of Running Service, or Remove Stopped Service -->
<td class="text-center">
<td class="text-center" ng-if="showLogsColumn && stack.status !== 'stopped'">
<!-- View logs button -->
<button type="button" class="btn btn-xs btn-default" id="viewLogsBtn"
uib-tooltip="View the logs for this part of the application instance"
ng-if="stack.status !== 'stopped'" tooltip-append-to-body="true"
tooltip-append-to-body="true"
ng-disabled="stack.status === 'stopped'" tooltip-placement="left" ng-click="showLogs(svc)">
<i class="fa fa-fw fa-file-text" ng-class="{ 'animated faa-vertical': stack.status === 'starting' && (svc.status === 'waiting' || svc.status === 'starting') }"></i>
</button>

<!-- Remove service from stack button -->
</td>

<!-- Remove optional service from stack -->
<td class="text-center" ng-if="showRemoveService && stack.status === 'stopped'">
<button type="button" ng-disabled="stack.services | isRecursivelyRequired:svc" id="removeBtn"
uib-tooltip="Remove this optional part from this application instance"
ng-if="stack.status === 'stopped' && svc.service !== stack.key && !_.find((stack.key | requirements), [ 'key', svc.service ])"
Expand All @@ -178,7 +182,7 @@ <h4>
</td>

<!-- Help Link -->
<td class="text-center"><a id="helpLink" tooltip-append-to-body="true" uib-tooltip="Additional instructions or documentation for a part of an application" ng-if="svc.service | specProperty:'info'" ng-href="{{ svc.service | specProperty:'info' }}" target="_blank" ga-track-event="['application', 'help', svc.service, 1, true]"><i class="fa fa-fw fa-question-circle"></i></a></td>
<td class="text-center" ng-if="showServiceHelpIcon"><a id="helpLink" tooltip-append-to-body="true" uib-tooltip="Additional instructions or documentation for a part of an application" ng-if="svc.service | specProperty:'info'" ng-href="{{ svc.service | specProperty:'info' }}" target="_blank" ga-track-event="['application', 'help', svc.service, 1, true]"><i class="fa fa-fw fa-question-circle"></i></a></td>
</tr>

<!-- Add an artificial row (if necessary) for optional services -->
Expand All @@ -200,7 +204,7 @@ <h4>

<td colspan="4">{{ stack.selectedOption | specProperty:'description' }}</td>

<td class="text-center">
<td class="text-center" ng-if="showServiceHelpIcon">
<a id="addServiceHelpLink" ng-if="stack.selectedOption | specProperty:'info'" ng-href="{{ stack.selectedOption | specProperty:'info' }}" target="_blank">
<i class="fa fa-fw fa-question-circle"></i>
</a>
Expand Down
11 changes: 11 additions & 0 deletions gui/entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,16 @@
# Substitute the ANALYTICS_ACCOUNT passed in by "docker run -e" or kubernetes
/bin/sed -i -e "s#^\.constant('GaAccount', .*)#.constant('GaAccount', '${ANALYTICS_ACCOUNT}')#" "$BASEDIR/ConfigModule.js"

# In lieu of actual user management, some instance-wide flags to toggle the more advanced features
/bin/sed -i -e "s#^\showConfig: .*,#showConfig: ${SHOW_CONFIG:-false},#" "$BASEDIR/ConfigModule.js"
/bin/sed -i -e "s#^\showLogs: .*,#showLogs: ${SHOW_LOGS:-false},#" "$BASEDIR/ConfigModule.js"
/bin/sed -i -e "s#^\showConsole: .*,#showConsole: ${SHOW_CONSOLE:-true},#" "$BASEDIR/ConfigModule.js"
/bin/sed -i -e "s#^\showEditService: .*,#showEditService: ${SHOW_EDIT_SERVICE:-false},#" "$BASEDIR/ConfigModule.js"
/bin/sed -i -e "s#^\showRemoveService: .*,#showRemoveService: ${SHOW_REMOVE_SERVICE:-false},#" "$BASEDIR/ConfigModule.js"
/bin/sed -i -e "s#^\showServiceHelpIcon: .*,#showServiceHelpIcon: ${SHOW_SERVICE_HELP_ICON:-false},#" "$BASEDIR/ConfigModule.js"
/bin/sed -i -e "s#^\showCreateSpec: .*,#showCreateSpec: ${SHOW_CREATE_SPEC:-false},#" "$BASEDIR/ConfigModule.js"
/bin/sed -i -e "s#^\showImportSpec: .*,#showImportSpec: ${SHOW_IMPORT_SPEC:-false},#" "$BASEDIR/ConfigModule.js"
/bin/sed -i -e "s#^\showFileManager: .*,#showFileManager: ${SHOW_FILE_MANAGER:-false},#" "$BASEDIR/ConfigModule.js"

# Start ExpressJS
node server.js
5 changes: 3 additions & 2 deletions gui/shared/navbar/NavbarController.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ angular
* @author lambert8
* @see https://opensource.ncsa.illinois.edu/confluence/display/~lambert8/3.%29+Controllers%2C+Scopes%2C+and+Partial+Views
*/
.controller('NavbarController', [ '$scope', '$rootScope', '$window', '$location', '$cookies', 'Project', 'AuthInfo', 'ProductName', 'ProductUrl', 'HelpLinks', 'FileManager', 'AutoRefresh', 'ReturnRoute', 'CookieOptions', 'SigninUrl',
function($scope, $rootScope, $window, $location, $cookies, Project, AuthInfo, ProductName, ProductUrl, HelpLinks, FileManager, AutoRefresh, ReturnRoute, CookieOptions, SigninUrl) {
.controller('NavbarController', [ '$scope', '$rootScope', '$window', '$location', '$cookies', 'Project', 'AuthInfo', 'ProductName', 'ProductUrl', 'HelpLinks', 'FileManager', 'AutoRefresh', 'ReturnRoute', 'CookieOptions', 'SigninUrl', 'AdvancedFeatures',
function($scope, $rootScope, $window, $location, $cookies, Project, AuthInfo, ProductName, ProductUrl, HelpLinks, FileManager, AutoRefresh, ReturnRoute, CookieOptions, SigninUrl, AdvancedFeatures) {
"use strict"

// Enable JS dropdowns on the navbar
Expand Down Expand Up @@ -59,6 +59,7 @@ angular
$scope.signinLink = $scope.enableOAuth ? SigninUrl : '/login/' + ($rootScope.rd ? 'rd=' : '');
$scope.helpLinks = HelpLinks;

$scope.showFileManager = AdvancedFeatures.showFileManager;
$scope.fileManager = FileManager;
$scope.launchingFileManager = FileManager.busy;
$scope.$watch('fileManager.busy', function(newValue, oldValue) {
Expand Down
2 changes: 1 addition & 1 deletion gui/shared/navbar/navbar.html
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
</li>

<!-- Then draw our Manage Files button -->
<li>
<li ng-if="showFileManager">
<a id="filesNav" type="button" ng-click="fileManager.launch()">
<i class="fa fa-fw" ng-class="{ 'fa-spinner fa-pulse': launchingFileManager, 'fa-files-o': !launchingFileManager }"></i> Files
</a>
Expand Down

0 comments on commit 8bb830c

Please sign in to comment.