Skip to content

Commit

Permalink
added downloading of a file from a vm (#661)
Browse files Browse the repository at this point in the history
* added downloading of a file from a vm
  • Loading branch information
sei-aschlackman authored May 22, 2024
1 parent 98022d0 commit fc64edf
Show file tree
Hide file tree
Showing 35 changed files with 14,340 additions and 10,911 deletions.
21,724 changes: 12,036 additions & 9,688 deletions package-lock.json

Large diffs are not rendered by default.

8 changes: 7 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@
"name": "player.vm.console.ui",
"version": "3.0.5",
"license": "MIT",
"config": {
"openapiArgs": "--additional-properties ngVersion=17 --additional-properties modelPropertyNaming=original --type-mappings=DateTime=string",
"deleteGeneratedCommand": "rimraf src/app/generated/vm-api/"
},
"scripts": {
"ng": "ng",
"start": "ng serve",
Expand All @@ -10,7 +14,7 @@
"lint": "ng lint",
"e2e": "ng e2e",
"swagger:gen": "curl --insecure http://localhost:4302/swagger/v1/swagger.json --output swagger.json && node_modules/@openapitools/openapi-generator-cli/bin/openapi-generator generate -i ./swagger.json -g typescript-angular -o src/app/generated/vm-api --additional-properties ngVersion=9.1 --additional-properties useRxJS6=true --additional-properties modelPropertyNaming=original",
"swagger:gen-win": "docker run --rm -v %CD%:/local openapitools/openapi-generator-cli:v4.3.1 generate -i http://host.docker.internal:4302/swagger/v1/swagger.json?format=openapi -g typescript-angular -o /local/src/app/generated/vm-api --additional-properties ngVersion=9.1 --additional-properties useRxJS6=true --additional-properties modelPropertyNaming=original --type-mappings=DateTime=Date"
"swagger:gen-docker": "cross-var $npm_package_config_deleteGeneratedCommand && cross-env-shell docker run --rm -v $INIT_CWD:/local openapitools/openapi-generator-cli:v6.2.0 generate -i http://host.docker.internal:4302/swagger/v1/swagger.json?format=openapi -g typescript-angular -o /local/src/app/generated/vm-api $npm_package_config_openapiArgs"
},
"private": true,
"dependencies": {
Expand Down Expand Up @@ -51,6 +55,8 @@
"@types/jquery": "^3.5.6",
"@types/node": "^16.18.74",
"codelyzer": "^6.0.2",
"cross-env": "^7.0.3",
"cross-var": "^1.1.0",
"jasmine-core": "^3.8.0",
"jasmine-spec-reporter": "^7.0.0",
"karma": "^6.3.4",
Expand Down
17 changes: 16 additions & 1 deletion src/app/components/options-bar/options-bar.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,22 @@
"
matTooltipPosition="after"
>
Send File to VM
Send File To VM
</span>
</button>
<button
*ngIf="isAdmin$ | async"
mat-menu-item
(click)="downloadFileFromVm()"
[disabled]="!uploadEnabled || uploading"
>
<span
[matTooltip]="
uploadEnabled ? '' : 'VM Credentials must be entered'
"
matTooltipPosition="after"
>
Download File From VM
</span>
</button>
<!-- mount ISO -->
Expand Down
29 changes: 26 additions & 3 deletions src/app/components/options-bar/options-bar.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import { MatSnackBar } from '@angular/material/snack-bar';
import { ActivatedRoute } from '@angular/router';
import { ComnSettingsService } from '@cmusei/crucible-common';
import { Observable, Subject } from 'rxjs';
import { take, takeUntil } from 'rxjs/operators';
import { map, take, takeUntil, tap } from 'rxjs/operators';
import { VsphereVirtualMachine } from '../../generated/vm-api';
import { NotificationData } from '../../models/notification/notification-model';
import { IsoResult } from '../../models/vm/iso-result';
Expand All @@ -27,7 +27,7 @@ import { DialogService } from '../../services/dialog/dialog.service';
import { NotificationService } from '../../services/notification/notification.service';
import { SignalRService } from '../../services/signalr/signalr.service';
import { VsphereService } from '../../state/vsphere/vsphere.service';
import { AsyncPipe } from '@angular/common';
import { AsyncPipe, NgIf } from '@angular/common';
import { MatTooltip } from '@angular/material/tooltip';
import { MatIcon } from '@angular/material/icon';
import { MatMenuTrigger, MatMenu, MatMenuItem } from '@angular/material/menu';
Expand Down Expand Up @@ -72,6 +72,7 @@ export class KeysPipe implements PipeTransform {
KeysPipe,
MatSlideToggleModule,
MatLabel,
NgIf,
],
})
export class OptionsBarComponent implements OnInit, OnDestroy {
Expand All @@ -97,6 +98,7 @@ export class OptionsBarComponent implements OnInit, OnDestroy {
vmResolutionsOptions: VmResolution[];
showConnectedUsers = false;
currentVmUsers$: Observable<string[]>;
isAdmin$: Observable<boolean>;
private copyTryCount: number;
private destroy$ = new Subject();

Expand Down Expand Up @@ -146,6 +148,10 @@ export class OptionsBarComponent implements OnInit, OnDestroy {
this.vsphereService.vmResolution
.pipe(takeUntil(this.destroy$))
.subscribe((res) => (this.currentVmContainerResolution = res));

this.isAdmin$ = this.vmService
.getVmPermissions(this.vmId)
.pipe(map((x) => x.includes('ViewAdmin')));
}

ngOnDestroy() {
Expand Down Expand Up @@ -286,8 +292,9 @@ export class OptionsBarComponent implements OnInit, OnDestroy {
}
}
this.vsphereService.verifyCredentials(this.vmId).subscribe(
(response) => {
() => {
this.uploadEnabled = true;
this.dialogService.message('Credentials Verified', '');
},
(error: HttpErrorResponse) => {
// error.error.title contains the relevant message
Expand Down Expand Up @@ -337,6 +344,22 @@ export class OptionsBarComponent implements OnInit, OnDestroy {
);
}

downloadFileFromVm() {
this.dialogService
.getFileUploadInfo('Download File Settings', {
data: { showCredentials: false },
})
.subscribe((enteredInfo) => {
const filePath = enteredInfo['filepath'];
this.vsphereService.getVmFileUrl(this.vmId, filePath).subscribe((x) => {
const link = document.createElement('a');
link.href = x.url;
link.download = x.fileName;
link.click();
});
});
}

startIsoMount() {
// refresh the iso list
this.retrievingIsos = true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,23 +7,25 @@ <h1 mat-dialog-title>{{ title }}</h1>
<form (ngSubmit)="done()">
<div class="d-flex flex-column align-items-center">
<mat-form-field>
<mat-label>Destination File Path</mat-label>
<mat-label>File Path</mat-label>
<input matInput tabIndex="1" name="filepath" [(ngModel)]="filepath" />
</mat-form-field>
<mat-form-field>
<mat-label>VM Username</mat-label>
<input matInput tabIndex="2" name="username" [(ngModel)]="username" />
</mat-form-field>
<mat-form-field>
<mat-label>VM Password</mat-label>
<input
matInput
type="password"
tabIndex="3"
name="password"
[(ngModel)]="password"
/>
</mat-form-field>
<ng-container *ngIf="showCredentials">
<mat-form-field>
<mat-label>VM Username</mat-label>
<input matInput tabIndex="2" name="username" [(ngModel)]="username" />
</mat-form-field>
<mat-form-field>
<mat-label>VM Password</mat-label>
<input
matInput
type="password"
tabIndex="3"
name="password"
[(ngModel)]="password"
/>
</mat-form-field>
</ng-container>
</div>
<mat-dialog-actions class="justify-content-around">
<button mat-stroked-button (click)="close()" tabIndex="4">Cancel</button>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { MatButton } from '@angular/material/button';
import { MatInput } from '@angular/material/input';
import { MatFormField, MatLabel } from '@angular/material/form-field';
import { FormsModule } from '@angular/forms';
import { NgIf } from '@angular/common';

@Component({
selector: 'file-upload-info-dialog',
Expand All @@ -25,6 +26,7 @@ import { FormsModule } from '@angular/forms';
MatInput,
MatDialogActions,
MatButton,
NgIf,
],
})
export class FileUploadInfoDialogComponent {
Expand All @@ -33,10 +35,15 @@ export class FileUploadInfoDialogComponent {
public password = '';
public filepath = '';

public showCredentials = true;

constructor(
@Inject(MAT_DIALOG_DATA) data,
private dialogRef: MatDialogRef<FileUploadInfoDialogComponent>,
) {
if (data?.showCredentials != null) {
this.showCredentials = data.showCredentials;
}
this.dialogRef.disableClose = true;
}

Expand Down
3 changes: 0 additions & 3 deletions src/app/generated/vm-api/.openapi-generator-ignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
// Copyright 2021 Carnegie Mellon University. All Rights Reserved.
// Released under a MIT (SEI)-style license. See LICENSE.md in the project root for license information.

# OpenAPI Generator Ignore
# Generated by openapi-generator https://github.com/openapitools/openapi-generator

Expand Down
59 changes: 59 additions & 0 deletions src/app/generated/vm-api/.openapi-generator/FILES
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
.gitignore
.openapi-generator-ignore
README.md
api.module.ts
api/api.ts
api/callbacks.service.ts
api/file.service.ts
api/health.service.ts
api/proxmox.service.ts
api/vmUsageLoggingSession.service.ts
api/vms.service.ts
api/vsphere.service.ts
configuration.ts
encoder.ts
git_push.sh
index.ts
model/bulkPowerOperation.ts
model/bulkPowerOperationResponse.ts
model/changeVsphereVirtualMachineNetwork.ts
model/consoleConnectionInfo.ts
model/coordinate.ts
model/coordinateCreateForm.ts
model/createVmUsageLoggingSessionCommand.ts
model/editVmUsageLoggingSessionCommand.ts
model/eventType.ts
model/fileVmUrlResponse.ts
model/getFileUrlVsphereVirtualMachine.ts
model/healthStatus.ts
model/isoFile.ts
model/isoResult.ts
model/models.ts
model/mountVsphereIso.ts
model/nicOptions.ts
model/permissions.ts
model/powerState.ts
model/problemDetails.ts
model/proxmoxConsole.ts
model/proxmoxVmInfo.ts
model/proxmoxVmType.ts
model/setVsphereVirtualMachineResolution.ts
model/simpleTeam.ts
model/teamIsoResult.ts
model/validateVsphereVirtualMachineCredentials.ts
model/virtualMachineToolsStatus.ts
model/vm.ts
model/vmCreateForm.ts
model/vmMap.ts
model/vmMapCreateForm.ts
model/vmMapUpdateForm.ts
model/vmType.ts
model/vmUpdateForm.ts
model/vmUsageLoggingSession.ts
model/vmUsageReport.ts
model/vmUser.ts
model/vmUserTeam.ts
model/vsphereVirtualMachine.ts
model/webhookEvent.ts
param.ts
variables.ts
2 changes: 1 addition & 1 deletion src/app/generated/vm-api/.openapi-generator/VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
4.3.1
6.2.0
39 changes: 30 additions & 9 deletions src/app/generated/vm-api/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ npm run build

### publishing

First build the package then run ```npm publish```
First build the package then run ```npm publish dist``` (don't forget to specify the `dist` folder!)

### consuming

Expand All @@ -25,14 +25,14 @@ npm install @ --save
_without publishing (not recommended):_

```
npm install PATH_TO_GENERATED_PACKAGE/-.tgz --save
npm install PATH_TO_GENERATED_PACKAGE/dist.tgz --save
```

_It's important to take the tgz file, otherwise you'll get trouble with links on windows_

_using `npm link`:_

In PATH_TO_GENERATED_PACKAGE:
In PATH_TO_GENERATED_PACKAGE/dist:
```
npm link
```
Expand All @@ -57,7 +57,6 @@ In your Angular project:
import { ApiModule } from '';
import { HttpClientModule } from '@angular/common/http';
@NgModule({
imports: [
ApiModule,
Expand All @@ -76,7 +75,7 @@ export class AppModule {}
// configuring providers
import { ApiModule, Configuration, ConfigurationParameters } from '';
export function apiConfigFactory (): Configuration => {
export function apiConfigFactory (): Configuration {
const params: ConfigurationParameters = {
// set configuration parameters here.
}
Expand Down Expand Up @@ -121,7 +120,7 @@ export class AppModule {}
import { DefaultApi } from '';
export class AppComponent {
constructor(private apiGateway: DefaultApi) { }
constructor(private apiGateway: DefaultApi) { }
}
```

Expand All @@ -137,7 +136,6 @@ import { ApiModule } from 'my-api-path';
import { ApiModule as OtherApiModule } from 'my-other-api-path';
import { HttpClientModule } from '@angular/common/http';
@NgModule({
imports: [
ApiModule,
Expand All @@ -154,7 +152,7 @@ export class AppModule {


### Set service base path
If different than the generated base path, during app bootstrap, you can provide the base path to your service.
If different than the generated base path, during app bootstrap, you can provide the base path to your service.

```
import { BASE_PATH } from '';
Expand Down Expand Up @@ -202,4 +200,27 @@ import { environment } from '../environments/environment';
bootstrap: [ AppComponent ]
})
export class AppModule { }
```
```

### Customizing path parameter encoding

Without further customization, only [path-parameters][parameter-locations-url] of [style][style-values-url] 'simple'
and Dates for format 'date-time' are encoded correctly.

Other styles (e.g. "matrix") are not that easy to encode
and thus are best delegated to other libraries (e.g.: [@honoluluhenk/http-param-expander]).

To implement your own parameter encoding (or call another library),
pass an arrow-function or method-reference to the `encodeParam` property of the Configuration-object
(see [General Usage](#general-usage) above).

Example value for use in your Configuration-Provider:
```typescript
new Configuration({
encodeParam: (param: Param) => myFancyParamEncoder(param),
})
```

[parameter-locations-url]: https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#parameter-locations
[style-values-url]: https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#style-values
[@honoluluhenk/http-param-expander]: https://www.npmjs.com/package/@honoluluhenk/http-param-expander
1 change: 0 additions & 1 deletion src/app/generated/vm-api/api.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import { NgModule, ModuleWithProviders, SkipSelf, Optional } from '@angular/core
import { Configuration } from './configuration';
import { HttpClient } from '@angular/common/http';


import { CallbacksService } from './api/callbacks.service';
import { FileService } from './api/file.service';
import { HealthService } from './api/health.service';
Expand Down
Loading

0 comments on commit fc64edf

Please sign in to comment.