Commit db947c60 authored by Lukas Burgey's avatar Lukas Burgey

Adapt again to changes at the backend

parent adf608dd
...@@ -5,7 +5,7 @@ if ! which npm &>/dev/null; ...@@ -5,7 +5,7 @@ if ! which npm &>/dev/null;
then then
echo 'Please install node.js 10.x' echo 'Please install node.js 10.x'
else else
npm install npm install
npm audit fix npm audit fix
./node_modules/@angular/cli/bin/ng build --prod ./node_modules/@angular/cli/bin/ng build --prod
......
<div class="mat-typography"> <div class="mat-typography">
<h2>Credentials</h2> <h2>Credentials</h2>
<p> <p>
You can access the service {{ service.name }} at {{ service.site[0].name }} using your SSH Key {{ stateItem.key.name }}. You can access the service {{ service.name }} at {{ service.site[0].name }} using one of your credentials.
</p> </p>
<div *ngIf="credentialCount > 0"> <div *ngIf="credentialCount > 0">
<p> <p>
......
...@@ -2,13 +2,13 @@ ...@@ -2,13 +2,13 @@
<h2>Deployment State</h2> <h2>Deployment State</h2>
<div [ngSwitch]="stateItem.state"> <div [ngSwitch]="stateItem.state">
<p *ngSwitchCase="'failed'"> <p *ngSwitchCase="'failed'">
The deployment of key {{ stateItem.key.name }} failed: The deployment of your credentials failed:
</p> </p>
<p *ngSwitchCase="'rejected'"> <p *ngSwitchCase="'rejected'">
The deployment of key {{ stateItem.key.name }} was rejected: The deployment of your credentials was rejected:
</p> </p>
<p *ngSwitchDefault> <p *ngSwitchDefault>
The deployment of key {{ stateItem.key.name }} has unknown state: The deployment of your credentials has unknown state:
</p> </p>
</div> </div>
<p> <p>
......
...@@ -28,21 +28,26 @@ export class ServiceComponent implements OnInit { ...@@ -28,21 +28,26 @@ export class ServiceComponent implements OnInit {
} }
public isDeployed(key: t.SSHKeyRef): boolean { public isDeployed(key: t.SSHKeyRef): boolean {
/* TODO
if (this.deployment) { if (this.deployment) {
return this.deployment.ssh_keys.some(k => { return this.deployment.ssh_keys.some(k => {
return k.id === key.id; return k.id === key.id;
}); });
} }
*/
return false; return false;
} }
public taskItem(site: t.Site, key: t.SSHKeyRef): t.DeploymentStateItem { public taskItem(site: t.Site, key: t.SSHKeyRef): t.DeploymentStateItem {
if (this.deployment) { if (this.deployment) {
const deploymentState = null;
/*
const deploymentState = this.deployment.states.find( const deploymentState = this.deployment.states.find(
state => { state => {
return state.key.id === key.id return state.key.id === key.id
} }
); );
*/
if (deploymentState) { if (deploymentState) {
return deploymentState.state_items.find( return deploymentState.state_items.find(
item => { item => {
......
...@@ -57,48 +57,42 @@ interface JSONObject { ...@@ -57,48 +57,42 @@ interface JSONObject {
[key: string]: string; [key: string]: string;
} }
// corresponds to NewDeploymentStateItem in the backend
export interface DeploymentStateItem { export interface DeploymentStateItem {
id: number; id: number;
service: Service | undefined;
group: Group | undefined;
services: Service[];
site: Site; site: Site;
state: string; state: string;
questionnaire: JSONObject; questionnaire: JSONObject;
credentials: JSONObject; credentials: JSONObject;
key: SSHKeyRef;
service: Service;
services: Service[];
group: Group;
message: string; message: string;
} }
export interface DeploymentState {
id: number; // corresponds to NewDeployment in the backend
service: Service;
services: Service[];
group: Group;
key: SSHKeyRef;
state_items: DeploymentStateItem[];
}
export interface Deployment { export interface Deployment {
id: number; id: number;
service: Service; service: Service | undefined;
group: number | undefined; // the group id
services: Service[]; services: Service[];
group: number; // the group id
ssh_keys: SSHKeyRef[];
states: DeploymentState[];
sites: Site[]; sites: Site[];
state_items: DeploymentStateItem[];
state: string
state_target: string
} }
export interface User { export interface User {
id: number;
profile_name: string; profile_name: string;
userinfo: any; userinfo: any;
ssh_keys: SSHKey[]; ssh_keys: SSHKey[];
services: Service[]; services: Service[];
id: number;
groups: Group[]; groups: Group[];
} }
export interface UserState { export interface UserState {
deployments: Deployment[]; deployments: Deployment[];
deployment_states: DeploymentState[];
deployment_state_items: DeploymentStateItem[]; deployment_state_items: DeploymentStateItem[];
} }
......
...@@ -47,7 +47,7 @@ export class UserService { ...@@ -47,7 +47,7 @@ export class UserService {
const stompConfig: StompConfig = { const stompConfig: StompConfig = {
// Which server? // Which server?
url: 'wss://hdf-portal.data.kit.edu/ws', url: 'wss://'+window.location.host+'/ws',
// Headers // Headers
// Typical keys: login, passcode, host // Typical keys: login, passcode, host
...@@ -62,8 +62,8 @@ export class UserService { ...@@ -62,8 +62,8 @@ export class UserService {
heartbeat_out: 20000, // Typical value 20000 - every 20 seconds heartbeat_out: 20000, // Typical value 20000 - every 20 seconds
// Wait in milliseconds before attempting auto reconnect // Wait in milliseconds before attempting auto reconnect
// Set to 0 to disable // Set to 0 to disable
// Typical value 5000 (5 seconds) // Typical value 15000 (15 seconds)
reconnect_delay: 5000, reconnect_delay: 15000,
// Will log diagnostics on console // Will log diagnostics on console
debug: false, debug: false,
...@@ -195,8 +195,13 @@ export class UserService { ...@@ -195,8 +195,13 @@ export class UserService {
); );
} }
public getServices(group: t.Group): t.Service[] | undefined { public getServices(group: t.Group): t.Service[] {
return this.groupMap.get(group.name); let s = this.groupMap.get(group.name);
if (s == undefined) {
return []
} else {
return s
}
} }
private getDeploymentByGroup(group: t.Group): t.Deployment | undefined { private getDeploymentByGroup(group: t.Group): t.Deployment | undefined {
...@@ -296,7 +301,7 @@ export class UserService { ...@@ -296,7 +301,7 @@ export class UserService {
public login(idp: t.IdP) { public login(idp: t.IdP) {
this.setIdPPreference(idp); this.setIdPPreference(idp);
window.location.href = 'https://hdf-portal.data.kit.edu/backend/auth/v1/request'; window.location.href = '/backend/auth/v1/request';
} }
public logout() { public logout() {
......
<mat-expansion-panel> <mat-expansion-panel>
<mat-expansion-panel-header> <mat-expansion-panel-header>
<mat-panel-title style="min-width: 100px;">{{ group.name }}</mat-panel-title> <mat-panel-title style="min-width: 100px;">{{ group.name }}</mat-panel-title>
<!--
<mat-panel-description>VO "{{ group.name }}" (Group ID: {{ group.id }})</mat-panel-description>
-->
</mat-expansion-panel-header> </mat-expansion-panel-header>
<div *ngIf="deploymentMapped()">
<div [ngSwitch]="deployment.state_target">
<span *ngSwitchCase="'not_deployed'">
You currently did not request access to services of this VO.
</span>
<span *ngSwitchCase="'deployed'">
You requested access to services of this VO.
</span>
</div>
</div>
<p *ngIf="!deploymentMapped()">
No deployment is currently mapped to this VO.
</p>
<div *ngIf="userService.getServices(group).length > 0; then serviceList else noServiceList"></div> <div *ngIf="userService.getServices(group).length > 0; then serviceList else noServiceList"></div>
<ng-template #serviceList> <ng-template #serviceList>
<p> <p>
...@@ -13,24 +23,17 @@ ...@@ -13,24 +23,17 @@
<table style="margin-bottom: 30px; margin: auto;"> <table style="margin-bottom: 30px; margin: auto;">
<thead> <thead>
<tr> <tr>
<td></td> <td style="min-width: 100px;">Site</td>
<td></td> <td style="min-width: 100px;">Service</td>
<td>SSH Keys</td> <td style="min-width: 100px;">State</td>
</tr> <td style="min-width: 100px;">Message</td>
<tr>
<td style="min-width: 150px;">Site</td>
<td style="min-width: 150px;">Service</td>
<td *ngFor="let key of userService.user.ssh_keys" style="min-width: 100px;">
{{key.name}}
</td>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<ng-container *ngFor="let site of sites()"> <ng-container *ngFor="let site of sites()">
<tr *ngFor="let service of servicesBySite(site);" style="height: 42px;"> <tr *ngFor="let service of servicesBySite(site);" style="height: 42px;">
<td> <td>
<span style="margin-right: 10px;" matTooltip="Site {{ site.name }} provides the service {{ service.name }} for members of <span style="margin-right: 10px;" matTooltip="Site {{ site.name }} provides the service {{ service.name }} for members of {{ group.name }}">
{{ group.name }}">
<mat-icon>account_balance</mat-icon> <mat-icon>account_balance</mat-icon>
{{ site.name }} {{ site.name }}
</span> </span>
...@@ -41,48 +44,39 @@ ...@@ -41,48 +44,39 @@
{{ service.name }} {{ service.name }}
</span> </span>
</td> </td>
<td *ngFor="let key of userService.user.ssh_keys"> <td>
<span [ngSwitch]="taskState(site, key)" class="childs-inline"> <span [ngSwitch]="stateItem(service, site)?.state" class="childs-inline">
<!-- states with actions --> <button *ngSwitchCase="'deployed'" (click)="dialog.openCredentials(service, stateItem(service, site))" mat-button mat-icon-button matTooltip="The credentials are deployed for the service {{ service.name }}. Click to see details.">
<button *ngSwitchCase="'deployed'" mat-button mat-icon-button
(click)="dialog.openCredentials(service, taskItem(site, key))"
matTooltip="The key {{ key.name }} is deployed for the service {{ service.name }}. Click to see details.">
<mat-icon>call_made</mat-icon> <mat-icon>call_made</mat-icon>
</button> </button>
<button *ngSwitchCase="'questionnaire'" mat-button mat-icon-button <button *ngSwitchCase="'questionnaire'" (click)="dialog.openQuestionnaire(stateItem(service, site))" mat-button mat-icon-buttonmatTooltip="This site needs more data to deploy the keys. Please click to submit the data.">
(click)="dialog.openQuestionnaire(taskItem(site, key))"
matTooltip="This site needs more data to deploy the keys. Please click to submit the data.">
<mat-icon>warning</mat-icon> <mat-icon>warning</mat-icon>
</button> </button>
<!-- states without actions --> <span *ngSwitchCase="'deployment_pending'" mat-icon-button matTooltip="Waiting for the deployment of the credentials to the site {{ site.name }}">
<span *ngSwitchCase="'deployment_pending'" mat-icon-button matTooltip="Waiting for the deployment of the key {{
key.name }} to the site {{ site.name }}">
<mat-progress-spinner diameter="24" mode="indeterminate"></mat-progress-spinner> <mat-progress-spinner diameter="24" mode="indeterminate"></mat-progress-spinner>
</span> </span>
<span *ngSwitchCase="'removal_pending'" mat-icon-button matTooltip="Waiting for the removal of the key {{ key.name }} <span *ngSwitchCase="'removal_pending'" mat-icon-button matTooltip="Waiting for the removal of the credentials from the site {{ site.name }}">
from the site {{ site.name }}">
<mat-progress-spinner diameter="24" mode="indeterminate"></mat-progress-spinner> <mat-progress-spinner diameter="24" mode="indeterminate"></mat-progress-spinner>
</span> </span>
<button *ngSwitchCase="'not_deployed'" mat-icon-button <button *ngSwitchCase="'not_deployed'" mat-icon-button matTooltip="The credentials are not deployed for the service {{ service.name }}.">
matTooltip="The key {{ key.name }} is not deployed for the service {{ service.name }}.">
<mat-icon>call_received</mat-icon> <mat-icon>call_received</mat-icon>
</button> </button>
<button *ngSwitchCase="'failed'" mat-icon-button <button *ngSwitchCase="'failed'" (click)="dialog.openMessage(stateItem(service, site))" mat-icon-button matTooltip="Site {{ site.name }} failed to deploy the credentials. The deployment will be retried. Click for details.">
matTooltip="Site {{ site.name }} failed to deploy the key {{ key.name }}. The deployment will be retried. Click for details."
(click)="dialog.openMessage(taskItem(site, key))">
<mat-icon>error</mat-icon> <mat-icon>error</mat-icon>
</button> </button>
<button *ngSwitchCase="'rejected'" mat-icon-button matTooltip="Site {{ site.name }} rejected the deployment of the key {{ key.name }}. Click for details." <button *ngSwitchCase="'rejected'" (click)="dialog.openMessage(stateItem(service, site))" mat-icon-button matTooltip="Site {{ site.name }} rejected the deployment of the credentials. Click for details.">
(click)="dialog.openMessage(taskItem(site, key))">
<mat-icon>error</mat-icon> <mat-icon>error</mat-icon>
</button> </button>
<!-- if we have no deployment -> assume state == not_deployed --> <button *ngSwitchDefault mat-icon-button matTooltip="Access to this service was never requested.">
<button *ngSwitchDefault mat-icon-button matTooltip="The key {{ key.name }} was never deployed to the site {{ site.name }}.">
<mat-icon>call_received</mat-icon> <mat-icon>call_received</mat-icon>
</button> </button>
</span> </span>
</td> </td>
<td>
<p>
{{ stateItem(service, site)?.message }}
</p>
</td>
</tr> </tr>
</ng-container> </ng-container>
</tbody> </tbody>
...@@ -95,20 +89,16 @@ ...@@ -95,20 +89,16 @@
</p> </p>
</ng-template> </ng-template>
<mat-action-row> <mat-action-row>
<div *ngIf="userService.user.ssh_keys.length > 0; then boxes else upload"></div> <div [ngSwitch]="deployment?.state_target">
<ng-template #boxes> <button *ngSwitchCase="'not_deployed'" mat-raised-button color="accent" matTooltip="TODO" (click)="changeDeployment('add')">
<span style="margin-right: 15px;"> Deploy credentials to services of VO {{ group.name }}
Please select SSH Keys to deploy: </button>
</span> <button *ngSwitchCase="'deployed'" mat-raised-button color="accent" matTooltip="TODO" (click)="changeDeployment('remove')">
<mat-checkbox *ngFor="let key of userService.user.ssh_keys" [checked]="isDeployed(key)" (change)="deploymentChange(key)"> Remove credentials from services of VO {{ group.name }}
{{ key.name }} </button>
</mat-checkbox> <button *ngSwitchDefault mat-raised-button color="accent" matTooltip="TODO" (click)="changeDeployment('add')">
</ng-template> Deploy credentials to future services of VO {{ group.name }}
<ng-template #upload> </button>
<span style="margin-right: 15px;"> </div>
Please upload an SSH Key to use this service:
</span>
<button mat-icon-button (click)="dialog.openSshKeys()"><mat-icon>vpn_key</mat-icon></button>
</ng-template>
</mat-action-row> </mat-action-row>
</mat-expansion-panel> </mat-expansion-panel>
...@@ -13,7 +13,7 @@ import * as t from '../types/types.module'; ...@@ -13,7 +13,7 @@ import * as t from '../types/types.module';
export class VoComponent implements OnInit { export class VoComponent implements OnInit {
@Input() group: t.Group; @Input() group: t.Group;
@Input() deployment: t.Deployment; @Input() deployment: t.Deployment | undefined;
constructor( constructor(
public userService: UserService, public userService: UserService,
...@@ -24,10 +24,12 @@ export class VoComponent implements OnInit { ...@@ -24,10 +24,12 @@ export class VoComponent implements OnInit {
ngOnInit() { ngOnInit() {
} }
public deploymentMapped(): boolean {
return this.deployment != undefined;
}
public sites(): t.Site[] { public sites(): t.Site[] {
if (this.deployment) {
return this.deployment.sites;
}
return this.userService.getServices(this.group).map( return this.userService.getServices(this.group).map(
(s: t.Service) => { (s: t.Service) => {
if (s.site.length == 1) { if (s.site.length == 1) {
...@@ -62,37 +64,20 @@ export class VoComponent implements OnInit { ...@@ -62,37 +64,20 @@ export class VoComponent implements OnInit {
return this.userService.getServices(this.group); return this.userService.getServices(this.group);
} }
public taskItem(site: t.Site, key: t.SSHKeyRef): t.DeploymentStateItem { public stateItem(service: t.Service, site: t.Site): t.DeploymentStateItem | undefined {
if (this.deployment == undefined) { if (!this.deploymentMapped()) {
return undefined; return undefined;
} }
return this.deployment.state_items.find(
const deploymentState = this.deployment.states.find( item => {
state => { return item.service.id === service.id && item.service.site.some( s => { return s.id === s.id; });
return state.key.id === key.id
} }
); );
if (deploymentState) {
return deploymentState.state_items.find(
item => {
return item.site.id === site.id
}
);
}
}
public taskState(site: t.Site, key: t.SSHKeyRef): string {
let item = this.taskItem(site, key);
if (item) {
return item.state;
}
return "unknown";
} }
public changeDeployment(key: t.SSHKeyRef, action: string) { public changeDeployment(action: string) {
const body = { const body = {
'type': action, 'type': action,
'key': key.id,
'group': this.group.id, 'group': this.group.id,
}; };
return this.http.post('/backend/api/deployments', body).subscribe( return this.http.post('/backend/api/deployments', body).subscribe(
...@@ -106,23 +91,4 @@ export class VoComponent implements OnInit { ...@@ -106,23 +91,4 @@ export class VoComponent implements OnInit {
} }
); );
} }
public isDeployed(key: t.SSHKeyRef): boolean {
if (this.deployment == undefined) {
return false;
}
return this.deployment.ssh_keys.some(k => {
return k.id === key.id;
});
}
public deploymentChange(key: t.SSHKeyRef) {
if (!this.isDeployed(key)) {
this.changeDeployment(key, 'add');
} else {
this.changeDeployment(key, 'remove');
}
}
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment