Skip to content

Commit f2614b6

Browse files
author
wg102
committed
feat: Add validation for mounted pvc
1 parent 0e116fd commit f2614b6

File tree

3 files changed

+42
-7
lines changed

3 files changed

+42
-7
lines changed

frontend/src/app/resource-form/volume/volume.component.ts

Lines changed: 40 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
import { Component, OnInit, Input, OnDestroy } from "@angular/core";
2-
import { FormGroup, Validators } from "@angular/forms";
2+
import { FormGroup, Validators, ValidatorFn, AbstractControl } from "@angular/forms";
33
import { Volume } from "src/app/utils/types";
44
import { Subscription } from "rxjs";
5-
import {TranslateService} from "@ngx-translate/core";
5+
import { TranslateService } from "@ngx-translate/core";
6+
import { NamespaceService } from "src/app/services/namespace.service";
7+
import { KubernetesService } from "src/app/services/kubernetes.service";
68

79
@Component({
810
selector: "app-volume",
@@ -12,6 +14,7 @@ import {TranslateService} from "@ngx-translate/core";
1214
export class VolumeComponent implements OnInit, OnDestroy {
1315
private _notebookName = "";
1416
private _defaultStorageClass: boolean;
17+
private mountedVolumes: Set<string> = new Set<string>();
1518

1619
currentPVC: Volume;
1720
existingPVCs: Set<string> = new Set();
@@ -101,14 +104,21 @@ export class VolumeComponent implements OnInit, OnDestroy {
101104
}
102105

103106
// ----- Component Functions -----
104-
constructor(private translate: TranslateService) {}
107+
constructor(
108+
private translate: TranslateService,
109+
private k8s: KubernetesService,
110+
private ns: NamespaceService) { }
105111

106112
ngOnInit() {
107113
this.volume
108114
.get("name")
109-
.setValidators([Validators.required, Validators.pattern(/^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$/)]);
110-
111-
this.subscriptions.add(
115+
.setValidators([
116+
Validators.required,
117+
this.isMountedValidator(),
118+
Validators.pattern(/^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$/)
119+
]);
120+
121+
this.subscriptions.add(
112122
this.volume.get("type").valueChanges.subscribe((type: string) => {
113123
this.setVolumeType(type);
114124
})
@@ -122,6 +132,18 @@ export class VolumeComponent implements OnInit, OnDestroy {
122132
this.updateVolInputFields();
123133
})
124134
);
135+
136+
// Get the list of mounted volumes of the existing Notebooks in the selected Namespace
137+
this.subscriptions.add(
138+
this.ns.getSelectedNamespace().subscribe(ns => {
139+
this.k8s.getResource(ns).subscribe(notebooks => {
140+
this.mountedVolumes.clear();
141+
notebooks.map(nb => nb.volumes.map(v => {
142+
this.mountedVolumes.add(v)
143+
}));
144+
});
145+
})
146+
);
125147
}
126148

127149
ngOnDestroy() {
@@ -166,12 +188,23 @@ export class VolumeComponent implements OnInit, OnDestroy {
166188

167189
showNameError() {
168190
const volumeName = this.volume.get("name");
169-
191+
170192
if (volumeName.hasError("required")) {
171193
return this.translate.instant("volume.errorNameRequired");
172194
}
173195
if (volumeName.hasError("pattern")) {
174196
return this.translate.instant("volume.errorNamePattern");
175197
}
198+
if (volumeName.hasError("isMounted")) {
199+
return this.translate.instant("volume.errorMountedVolume");
200+
}
201+
}
202+
203+
//Method that disables selecting a mounted pvc
204+
private isMountedValidator(): ValidatorFn {
205+
return (control: AbstractControl): { [key: string]: any } => {
206+
const exists = this.mountedVolumes.has(control.value);
207+
return exists ? { isMounted: true } : null;
208+
};
176209
}
177210
}

frontend/src/assets/i18n/en.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@
126126
"lblName": "Name",
127127
"errorNameRequired": "The volume name can't be empty",
128128
"errorNamePattern": "The volume name can only contain lowercase alphanumeric characters, '-' or '.', and must start and end with an alphanumeric character",
129+
"errorMountedVolume":"The volume is already mounted to another notebook and cannot be currently selected",
129130
"lblSize": "Size",
130131
"lblMode": "Mode",
131132
"optReadWriteOnce": "ReadWriteOnce",

frontend/src/assets/i18n/fr.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@
127127
"lblName": "Nom",
128128
"errorNameRequired": "Le nom du volume ne peut pas être vide",
129129
"errorNamePattern": "Le nom du volume ne peut contenir que des caractères alphanumériques en minuscule, '-' ou '.', et doit commencer et se terminer par un caractères alphanumériques",
130+
"errorMountedVolume":"Le volume est déjà monté sur un autre bloc note et ne peut être sélectionné actuellement",
130131
"lblSize": "Taille",
131132
"lblMode": "Mode",
132133
"optReadWriteOnce": "ReadWriteOnce",

0 commit comments

Comments
 (0)