Skip to content

Commit

Permalink
CHE-2059 Add ssh view for workspace in UD
Browse files Browse the repository at this point in the history
- allow to view default ssh key for workspace
- allow to remove this default key
- allow to generate default key if not present

Change-Id: Ifca18aed416f91846cf1adeb2a6e32389df196d3
Signed-off-by: Florent BENOIT <fbenoit@codenvy.com>
  • Loading branch information
benoitf committed Nov 8, 2016
1 parent 44da57e commit 9852e54
Show file tree
Hide file tree
Showing 9 changed files with 434 additions and 1 deletion.
1 change: 1 addition & 0 deletions dashboard/src/app/index.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ initModule.run(['$rootScope', '$location', '$routeParams', 'routingRedirect', '$
$rootScope.showIDE = false;

workspaceDetailsService.addSection('Projects', '<workspace-details-projects></workspace-details-projects>', 'icon-ic_inbox_24px');
workspaceDetailsService.addSection('SSH', '<workspace-details-ssh></workspace-details-ssh>', 'icon-ic_vpn_key_24px');

// here only to create instances of these components
cheIdeFetcher;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
/*
* Copyright (c) 2015-2016 Codenvy, S.A.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Codenvy, S.A. - initial API and implementation
*/
import {CheWorkspace} from "../../../../components/api/che-workspace.factory";
import {CheNotification} from "../../../../components/notification/che-notification.factory";
import {CheSsh} from "../../../../components/api/che-ssh.factory";
'use strict';

/**
* @ngdoc controller
* @name workspace.details.controller:WorkspaceDetailsSSHCtrl
* @description This class is handling the controller for details of workspace : section ssh
* @author Florent Benoit
*/
export class WorkspaceDetailsSshCtrl {

/**
* Workspace.
*/
private cheWorkspace: CheWorkspace;

/**
* SSH.
*/
private cheSsh: CheSsh;

/**
* Notification.
*/
private cheNotification: CheNotification;

/**
* Material Design Dialog Service
*/
private $mdDialog: ng.material.IDialogService;

/**
* Angular Log service.
*/
private $log: ng.ILogService;

/**
* Angular Q service.
*/
private $q: ng.IQService;

private $timeout : ng.ITimeoutService;

private namespace : string;
private workspaceName : string;
private workspaceKey : string;
private workspace : any;
private workspaceId: string;

private sshKeyPair : any;

/**
* True if one machine has ssh agent enabled.
*/
private hasSSHAgents: boolean;

private machineSshAgents : Array<{agentEnabled : boolean, name: string}>;

/**
* Default constructor that is using resource
* @ngInject for Dependency injection
*/
constructor($route : ng.route.IRouteService, cheSsh: CheSsh, cheWorkspace: CheWorkspace, cheNotification, $mdDialog : ng.material.IDialogService, $log : ng.ILogService, $q : ng.IQService, $timeout : ng.ITimeoutService) {
this.cheWorkspace = cheWorkspace;
this.cheSsh = cheSsh;
this.cheNotification = cheNotification;
this.$mdDialog = $mdDialog;
this.$log = $log;
this.$q = $q;

this.machineSshAgents = new Array<>();
this.namespace = $route.current.params.namespace;
this.workspaceName = $route.current.params.workspaceName;
this.workspaceKey = this.namespace + ":" + this.workspaceName;

this.updateData();

}


updateData() {
this.hasSSHAgents = false;
this.workspace = this.cheWorkspace.getWorkspaceByName(this.namespace, this.workspaceName);
this.workspaceId = this.workspace.id;

// get ssh key
this.cheSsh.fetchKey("workspace", this.workspaceId).finally(() => {
this.sshKeyPair = this.cheSsh.getKey("workspace", this.workspaceId);

});

let defaultEnv : string = this.workspace.config.defaultEnv;
let machines : any = this.workspace.config.environments[defaultEnv].machines;
let machineNames : Array<string> = Object.keys(machines);
this.machineSshAgents.length = 0;
machineNames.forEach((machineName) => {
let enabled : boolean = machines[machineName].agents.indexOf("org.eclipse.che.ssh") >= 0;
let machineAgent = {agentEnabled : enabled, name: machineName};
this.machineSshAgents.push(machineAgent);
if (enabled) {
this.hasSSHAgents = true;
}
});

}

/**
* Remove the default workspace keypair
*/
removeDefaultKey() {
this.cheSsh.removeKey("workspace", this.workspaceId).then(
() => {this.$timeout( this.updateData(), 3000)}
);
}

/**
* Generate a new default workspace keypair
*/
generateDefaultKey() {
this.cheSsh.generateKey("workspace", this.workspaceId).then(() => {this.$timeout( this.updateData(), 3000)});
}



}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*
* Copyright (c) 2015-2016 Codenvy, S.A.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Codenvy, S.A. - initial API and implementation
*/
'use strict';

/**
* @ngdoc directive
* @name workspaces.details.directive:workspaceDetailsSSH
* @restrict E
* @element
*
* @description
* <workspace-details-ssh></workspace-ssh-ssh>` for displaying workspace ssh entry.
*
* @usage
* <workspace-details-ssh></workspace-details-ssh>
*
* @author Florent Benoit
*/
export class WorkspaceDetailsSsh {


restrict: string = 'E';
templateUrl: string = 'app/workspaces/workspace-details/workspace-ssh/workspace-details-ssh.html';

controller: string = 'WorkspaceDetailsSshCtrl';
controllerAs: string = 'workspaceDetailsSshCtrl';
bindToController: boolean = true;


/**
* Default constructor that is using resource
* @ngInject for Dependency injection
*/
constructor () {

}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
<!--
Copyright (c) 2015 Codenvy, S.A.
All rights reserved. This program and the accompanying materials
are made available under the terms of the Eclipse Public License v1.0
which accompanies this distribution, and is available at
http://www.eclipse.org/legal/epl-v10.html
Contributors:
Codenvy, S.A. - initial API and implementation
-->
<md-content flex class="workspace-ssh-content">

<div layout="row" flex class="workspace-ssh-content-invalid-notification" ng-if="workspaceDetailsSshCtrl.workspace.status !== 'RUNNING'">
<i class="fa fa-info-circle"></i>
<div>Workspace is not running. SSH connections are unavailable.</div>
</div>
<div layout="row" flex class="workspace-ssh-content-invalid-notification" ng-if="!workspaceDetailsSshCtrl.hasSSHAgents">
<i class="fa fa-info-circle"></i>
<div>SSH keys are configured but there is no SSH agent enabled on machines. SSH connections are unavailable.</div>
</div>

<che-label-container che-label-name="Default key" che-label-description="SSH keys are generated when workspaces are created. This key is placed in all workspace machines.">

<div layout="column" ng-if="workspaceDetailsSshCtrl.sshKeyPair">
<che-text-info che-label-name="Private key" che-text="workspaceDetailsSshCtrl.sshKeyPair.privateKey"
che-copy-clipboard="true"
class="workspace-ssh-content-private"></che-text-info>

<che-text-info che-label-name="Public key" che-text="workspaceDetailsSshCtrl.sshKeyPair.publicKey"
che-copy-clipboard="true"
class=""></che-text-info>

<che-button-danger che-button-title="Remove default SSH key"
ng-click="workspaceDetailsSshCtrl.removeDefaultKey()"></che-button-danger>
</div>

<div layout="column" ng-if="!workspaceDetailsSshCtrl.sshKeyPair">
<che-button-primary che-button-title="Generate"
ng-click="workspaceDetailsSshCtrl.generateDefaultKey()"></che-button-primary>
<span class="workspace-ssh-content-notice">This workspace does not have a generated SSH key. We can generate a new one here or you can add your own in the IDE.</span>
<span ng-if="workspaceDetailsSshCtrl.workspace.status === 'RUNNING'">Note: Workspace is currently in RUNNING state. It will require a restart of the workspace in order to be taken into account.</span>
</div>

</che-label-container>

<che-label-container che-label-name="SSH agent" che-label-description="Machines of workspaces with SSH agents. Agents can be enabled/disabled in runtime view.">

<che-list-header>
<div flex="100" layout="row" layout-align="start stretch" class="che-list-item-row">
<div layout="row" layout-align="start center">
</div>
<div flex hide-xs layout-gt-xs="row" layout-align="start center" class="che-list-item-details">
<che-list-header-column flex="30" che-column-title='MACHINE'></che-list-header-column>
<che-list-header-column flex="40" che-column-title='SSH ENABLED'></che-list-header-column>
</div>
</div>
</che-list-header>

<che-list flex>
<che-list-item ng-repeat="machine in workspaceDetailsSshCtrl.machineSshAgents">
<div flex="100" layout="row" layout-align="start stretch" class="agent-item-row">
<div flex layout-xs="column" layout-gt-xs="row" layout-align-gt-xs="start center" layout-align-xs="start start" class="che-list-item-details">
<div flex="30" class="che-agent-item-name">
<span>{{machine.name}}</span>
</div>
<div flex="40">
<div>
<md-checkbox ng-model="machine.agentEnabled"
ng-disabled="true"
aria-label="Agent">
</md-checkbox>
</div>
</div>
<div flex="30"></div>
</div>
</div>
</che-list-item>
</che-list>

</che-label-container>

</md-content>

Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
.workspace-ssh-content
margin 0
button
margin 0

.workspace-ssh-content
.che-text-info-mobile span, .che-text-info-desktop span
border-width 0
padding-bottom 20px

.che-text-info-mobile span label, .che-text-info-desktop span label
max-width 500px
word-wrap break-word
font-family Fixed, monospace
color $disabled-color

.che-text-info .copy-clipboard
margin-top 50px
margin-left 20px

.workspace-ssh-content-notice
padding-top 20px

.che-list-item-content *:not(.tooltip)
overflow visible

.che-list-header md-item
border none

.che-list-header-content > *
margin: 0

.che-list
margin: 0

.workspace-ssh-content-invalid-notification
background-color $invalid-color
color $error-color
padding: 5px
margin: 10px 0 10px 0

.fa
font-size 18px
padding-right 5px

.workspace-ssh-content .workspace-ssh-content-private .che-text-info-desktop span label
white-space pre
5 changes: 5 additions & 0 deletions dashboard/src/app/workspaces/workspaces-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ import {UsageChart} from './list-workspaces/workspace-item/usage-chart.directive
import {WorkspaceItemCtrl} from './list-workspaces/workspace-item/workspace-item.controller';
import {WorkspaceEditModeOverlay} from './workspace-edit-mode/workspace-edit-mode-overlay.directive';
import {WorkspaceEditModeToolbarButton} from './workspace-edit-mode/workspace-edit-mode-toolbar-button.directive';
import {WorkspaceDetailsSsh} from './workspace-details/workspace-ssh/workspace-details-ssh.directive';
import {WorkspaceDetailsSshCtrl} from './workspace-details/workspace-ssh/workspace-details-ssh.controller';
import {WorkspaceDetailsProjectsCtrl} from './workspace-details/workspace-projects/workspace-details-projects.controller';
import {WorkspaceDetailsService} from './workspace-details/workspace-details.service';
import {ExportWorkspaceController} from './workspace-details/export-workspace/export-workspace.controller';
Expand Down Expand Up @@ -83,6 +85,9 @@ export class WorkspacesConfig {

new CreateProjectStackLibrarySelectedStackFilter(register);

register.controller('WorkspaceDetailsSshCtrl', WorkspaceDetailsSshCtrl);
register.directive('workspaceDetailsSsh', WorkspaceDetailsSsh);

register.controller('ListWorkspacesCtrl', ListWorkspacesCtrl);
register.controller('WorkspaceDetailsController', WorkspaceDetailsController);
register.controller('WorkspaceStacksController', WorkspaceStacksController);
Expand Down
2 changes: 2 additions & 0 deletions dashboard/src/components/api/che-api-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import {CheRemote} from './remote/che-remote.factory';
import {CheOAuthProvider} from './che-o-auth-provider.factory';
import {CheEnvironmentRegistry} from './environment/che-environment-registry.factory';
import {CheAgent} from './che-agent.factory';
import {CheSsh} from './che-ssh.factory';
import {CheNamespaceRegistry} from './namespace/che-namespace-registry.factory';

export class ApiConfig {
Expand All @@ -54,6 +55,7 @@ export class ApiConfig {
register.factory('cheOAuthProvider', CheOAuthProvider);
register.factory('cheEnvironmentRegistry', CheEnvironmentRegistry);
register.factory('cheAgent', CheAgent);
register.factory('cheSsh', CheSsh);
register.factory('cheNamespaceRegistry', CheNamespaceRegistry);
}
}
Loading

0 comments on commit 9852e54

Please sign in to comment.