Commit eef0cde5 authored by Lukas Burgey's avatar Lukas Burgey

Add deployment of multiple ssh keys

parent f8714215
...@@ -17,6 +17,8 @@ import { MatDialogModule } from '@angular/material/dialog'; ...@@ -17,6 +17,8 @@ import { MatDialogModule } from '@angular/material/dialog';
import {MatFormFieldModule} from '@angular/material/form-field'; import {MatFormFieldModule} from '@angular/material/form-field';
import {MatSelectModule} from '@angular/material/select'; import {MatSelectModule} from '@angular/material/select';
import {MatInputModule} from '@angular/material/input'; import {MatInputModule} from '@angular/material/input';
import {MatCheckboxModule} from '@angular/material/checkbox';
import { CookieService } from 'ngx-cookie-service'; import { CookieService } from 'ngx-cookie-service';
...@@ -73,6 +75,7 @@ const routes = [ ...@@ -73,6 +75,7 @@ const routes = [
MatFormFieldModule, MatFormFieldModule,
MatSelectModule, MatSelectModule,
MatInputModule, MatInputModule,
MatCheckboxModule,
], ],
providers: [ providers: [
CookieService, CookieService,
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
<h4>Services</h4> <h4>Services</h4>
<div *ngIf="userService.state.services.length > 0"> <div *ngIf="userService.state.services.length > 0">
<mat-accordion> <mat-accordion>
<app-service *ngFor="let service of userService.state.services" <app-service *ngFor="let service of userService.state.services"
[serviceData]="service"></app-service> [serviceData]="service"></app-service>
</mat-accordion> </mat-accordion>
</div> </div>
...@@ -11,12 +11,3 @@ ...@@ -11,12 +11,3 @@
This is due services requiring users to be member of a certain group. This is due services requiring users to be member of a certain group.
</p> </p>
</div> </div>
<!--
<div style="margin-top: 100px">
{{ userService.state | json }}
</div>
<div style="margin-top: 100px">
{{ userService.user | json }}
</div>
-->
...@@ -19,16 +19,14 @@ ...@@ -19,16 +19,14 @@
</ul> </ul>
<mat-action-row> <mat-action-row>
<span style="padding-right: 20px;"> <span style="margin-right: 15px">
<mat-form-field> Deployed keys:
<mat-select placeholder="SSH Public Key" [(ngModel)]="sshKeyName"> </span><br/>
<mat-option *ngFor="let key of userService.user.ssh_keys" [value]="key.name"> <mat-checkbox *ngFor="let key of userService.user.ssh_keys"
{{ key.name }} style="margin-right: 10px"
</mat-option> [checked]="isDeployed(key)"
</mat-select> (change)="deploymentChange(key)">
</mat-form-field> {{ key.name }}
</span> </mat-checkbox>
<button mat-raised-button color="primary" [disabled]="requestDisabled()" (click)="request()">Request deployment</button>
</mat-action-row> </mat-action-row>
</mat-expansion-panel> </mat-expansion-panel>
import { Component, OnInit, Input } from '@angular/core'; import { Component, OnInit, Input } from '@angular/core';
import { MatCheckboxChange } from '@angular/material/checkbox';
import { SnackBarService } from '../snackbar.service';
import { UserService } from '../user.service'; import { UserService } from '../user.service';
@Component({ @Component({
...@@ -10,22 +10,41 @@ import { UserService } from '../user.service'; ...@@ -10,22 +10,41 @@ import { UserService } from '../user.service';
}) })
export class ServiceComponent implements OnInit { export class ServiceComponent implements OnInit {
@Input() serviceData: any; @Input() serviceData: any;
sshKeyName = '';
constructor( constructor(
public userService: UserService, public userService: UserService,
public snackBar: SnackBarService,
) { ) {
} }
ngOnInit() { ngOnInit() {
} }
public request() { public getDeployment() {
this.snackBar.open('Requesting with key ' + this.sshKeyName); const deployment = this.userService.user.deployments.find(
d => {
return d.service.name === this.serviceData.name;
}
);
return deployment;
} }
public requestDisabled(): boolean { public isDeployed(key): boolean {
return this.sshKeyName === ''; const deployment = this.getDeployment();
if (deployment) {
return deployment.ssh_keys.some(k => {
return k.name === key.name;
});
}
return false;
}
public deploymentChange(key) {
console.log('changing', key);
if (!this.isDeployed(key)) {
this.userService.addDeployment(this.serviceData.name, key.name);
} else {
this.userService.removeDeployment(this.serviceData.name, key.name);
}
} }
} }
...@@ -24,12 +24,18 @@ interface Service { ...@@ -24,12 +24,18 @@ interface Service {
name: string; name: string;
} }
interface Deployment {
service: Service;
ssh_keys: SSHKey[];
}
interface User { interface User {
sub: string; sub: string;
email: string; email: string;
username: string; username: string;
groups: Group[]; groups: Group[];
ssh_keys: SSHKey[]; ssh_keys: SSHKey[];
deployments: Deployment[];
} }
interface State { interface State {
...@@ -55,6 +61,7 @@ export class UserService { ...@@ -55,6 +61,7 @@ export class UserService {
public user: User; public user: User;
public sshKeyData: MatTableDataSource<any>; public sshKeyData: MatTableDataSource<any>;
public userInfoData: MatTableDataSource<any>; public userInfoData: MatTableDataSource<any>;
public services: Service[];
constructor( constructor(
...@@ -86,7 +93,6 @@ export class UserService { ...@@ -86,7 +93,6 @@ export class UserService {
public errorStatus(): Observable<boolean> { public errorStatus(): Observable<boolean> {
return this.activatedRoute.params.map( return this.activatedRoute.params.map(
(params) => { (params) => {
console.log('params', params);
if ('error' in params) { if ('error' in params) {
this.snackBar.open('Backend error: ' + params['error']); this.snackBar.open('Backend error: ' + params['error']);
return false; return false;
...@@ -121,41 +127,46 @@ export class UserService { ...@@ -121,41 +127,46 @@ export class UserService {
); );
} }
public updateData(data: any) {
if (!this.loggedIn && data.logged_in) {
this.snackBar.open('Logged in');
}
this.loggedIn = data.logged_in;
if (!this.state) {
this.state = data.state;
}
this.user = data.user;
if (this.user) {
// build sshKeyData
if ('ssh_keys' in this.user) {
this.sshKeyData = new MatTableDataSource(this.user.ssh_keys);
} else {
this.sshKeyData = null;
}
// build userInfoData
const userInfoList = [];
for (const key of ['sub', 'email']) {
userInfoList.push({name: key, info: this.user[key]});
}
this.userInfoData = new MatTableDataSource(userInfoList);
} else {
this.sshKeyData = null;
this.userInfoData = null;
}
this.logState();
}
public update() { public update() {
this.http this.http
.get('/backend/api/state/') .get('/backend/api/state/')
.subscribe( .subscribe(
(data: StateAPIUser) => { (data: StateAPIUser) => {
if (!this.loggedIn && data.logged_in) { this.updateData(data);
this.snackBar.open('Logged in');
}
this.loggedIn = data.logged_in;
this.state = data.state;
this.user = data.user;
if (this.user) {
// build sshKeyData
if ('ssh_keys' in this.user) {
this.sshKeyData = new MatTableDataSource(this.user.ssh_keys);
} else {
this.sshKeyData = null;
}
// build userInfoData
const userInfoList = [];
for (const key of ['sub', 'email']) {
userInfoList.push({name: key, info: this.user[key]});
}
this.userInfoData = new MatTableDataSource(userInfoList);
} else {
this.sshKeyData = null;
this.userInfoData = null;
}
this.logState();
}, },
(err: HttpErrorResponse) => { (err: HttpErrorResponse) => {
console.log('Error', err); console.log('Error', err);
...@@ -180,12 +191,12 @@ export class UserService { ...@@ -180,12 +191,12 @@ export class UserService {
}; };
return this.http.post('/backend/api/sshkey/', body).subscribe( return this.http.post('/backend/api/sshkey/', body).subscribe(
data => { data => {
this.update(); this.updateData(data);
}, },
(err) => { (err) => {
this.snackBar.open('Error uploading key'); this.snackBar.open('Error uploading key');
console.log(err); console.log(err);
return Observable.of('Error uploading key'); this.update();
} }
); );
} }
...@@ -197,11 +208,50 @@ export class UserService { ...@@ -197,11 +208,50 @@ export class UserService {
}; };
return this.http.post('/backend/api/sshkey/', body).subscribe( return this.http.post('/backend/api/sshkey/', body).subscribe(
(data) => { (data) => {
this.update(); this.updateData(data);
}, },
(err) => { (err) => {
this.snackBar.open('Error deleting key'); this.snackBar.open('Error deleting key');
console.log(err); console.log(err);
this.update();
}
);
}
public addDeployment(serviceName: string, keyName: string) {
const body = {
'type': 'add',
'key': keyName,
'service': serviceName,
};
return this.http.post('/backend/api/deployments/', body).subscribe(
(data) => {
this.snackBar.open('Deployed key ' + keyName);
this.updateData(data);
},
(err) => {
this.snackBar.open('Error deploying key ' + keyName);
console.log(err);
this.update();
}
);
}
public removeDeployment(serviceName: string, keyName: string) {
const body = {
'type': 'remove',
'key': keyName,
'service': serviceName,
};
return this.http.post('/backend/api/deployments/', body).subscribe(
(data) => {
this.snackBar.open('Withdrew key ' + keyName);
this.updateData(data);
},
(err) => {
this.snackBar.open('Error withdrawing key ' + keyName);
console.log(err);
this.update();
} }
); );
} }
......
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