This is an automated email from the ASF dual-hosted git repository. pingsutw pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/submarine.git
The following commit(s) were added to refs/heads/master by this push: new 1682df2 SUBMARINE-965. Users should not have the privilege to create experiments in different namespaces 1682df2 is described below commit 1682df28328462a8aafd6ef544dbf00a696b1a89 Author: Kai-Hsun Chen <b03901...@ntu.edu.tw> AuthorDate: Mon Aug 9 23:05:20 2021 +0800 SUBMARINE-965. Users should not have the privilege to create experiments in different namespaces ### What is this PR for? In our multi-tenant architecture, users only can create experiments in their namespaces, but the Submarine workbench enables users to specify namespaces. ![截圖 2021-08-08 上午10 17 13](https://user-images.githubusercontent.com/20109646/128638163-c3d30a53-5e21-4460-b2a3-3ded61d49d6e.png) This patch aims to ### What type of PR is it? [Bug Fix] ### Todos 1. Remove the function `public void setNamespace(String namespace)` in ExperimentMeta.java 2. Update experiment RESTful API (remove the field "namespace" in the JSON file) 3. Add a test case to make sure whether the experiment is in the namespace specified by `ENV_NAMESPACE`. ### What is the Jira issue? https://issues.apache.org/jira/browse/SUBMARINE-965 ### How should this be tested? **Test1** * Step1: Use submarine-operator to create a submarine service in the namespace "submarine-user-test" * Step2: Create an experiment, and check whether the experiment is in the namespace "submarine-user-test" rather than "default". <img width="1439" alt="截圖 2021-08-08 下午11 57 35" src="https://user-images.githubusercontent.com/20109646/128640083-61ffc46d-fc26-4f22-8769-8202092c6574.png"> **Test2** * Remove the field "namespace" in the Submarine workbench ### Screenshots (if appropriate) <img width="1439" alt="截圖 2021-08-08 下午11 57 35" src="https://user-images.githubusercontent.com/20109646/128640083-61ffc46d-fc26-4f22-8769-8202092c6574.png"> <img width="994" alt="截圖 2021-08-09 上午1 19 46" src="https://user-images.githubusercontent.com/20109646/128640160-58a94857-346d-4ce9-8d14-97edeb4de26e.png"> ### Questions: * Do the license files need updating? No * Are there breaking changes for older versions? No * Does this need new documentation? No Author: Kai-Hsun Chen <b03901...@ntu.edu.tw> Signed-off-by: Kevin <pings...@apache.org> Closes #702 from kevin85421/test_yaml_entity and squashes the following commits: 4b375c4b [Kai-Hsun Chen] Update testcase 256b2579 [Kai-Hsun Chen] Add comment 9d1cddb7 [Kai-Hsun Chen] Add comment 90b0a114 [Kai-Hsun Chen] Refactor 973dacee [Kai-Hsun Chen] Refactor b4eb4be1 [Kai-Hsun Chen] Refactor 61f74f7a [Kai-Hsun Chen] Weird 6f936569 [Kai-Hsun Chen] Fix 30fcd589 [Kai-Hsun Chen] Fix 3e7b8163 [Kai-Hsun Chen] test --- .github/workflows/master.yml | 1 + .../org/apache/submarine/server/api/spec/ExperimentMeta.java | 11 +++++++++-- .../apache/submarine/server/rest/ExperimentRestApiTest.java | 4 +--- .../workbench-web/src/app/interfaces/experiment-spec.ts | 1 - .../experiment-customized-form.component.html | 10 ---------- .../experiment-customized-form.component.ts | 11 ----------- .../experiment-predefined-form.component.ts | 2 -- .../template-home/template-form/template-form.component.ts | 2 -- 8 files changed, 11 insertions(+), 31 deletions(-) diff --git a/.github/workflows/master.yml b/.github/workflows/master.yml index 3f3248b..e8e2344 100644 --- a/.github/workflows/master.yml +++ b/.github/workflows/master.yml @@ -172,6 +172,7 @@ jobs: TEST_MODULES: "-pl :submarine-test-k8s" run: | echo ">>> mvn ${TEST_FLAG} ${TEST_MODULES} ${PROFILE} -B" + mvn install -DskipTests mvn ${TEST_FLAG} ${TEST_MODULES} ${PROFILE} -B - name: Failure status run: | diff --git a/submarine-server/server-api/src/main/java/org/apache/submarine/server/api/spec/ExperimentMeta.java b/submarine-server/server-api/src/main/java/org/apache/submarine/server/api/spec/ExperimentMeta.java index 67af93d..1d6003a 100644 --- a/submarine-server/server-api/src/main/java/org/apache/submarine/server/api/spec/ExperimentMeta.java +++ b/submarine-server/server-api/src/main/java/org/apache/submarine/server/api/spec/ExperimentMeta.java @@ -40,7 +40,13 @@ public class ExperimentMeta { private List<String> tags = new ArrayList<>(); public ExperimentMeta() { - + namespace = "default"; + /* The environment variable "ENV_NAMESPACE" will be set by submarine-operator. Hence, + * if the user creates Submarine with Helm, the variable "namespace" will always be "default". + */ + if (System.getenv("ENV_NAMESPACE") != null) { + namespace = System.getenv("ENV_NAMESPACE"); + } } /** @@ -88,7 +94,8 @@ public class ExperimentMeta { * @param namespace namespace */ public void setNamespace(String namespace) { - this.namespace = namespace; + // TODO(kevin85421): Remove the function + return; } public String getFramework() { diff --git a/submarine-server/server-core/src/test/java/org/apache/submarine/server/rest/ExperimentRestApiTest.java b/submarine-server/server-core/src/test/java/org/apache/submarine/server/rest/ExperimentRestApiTest.java index 38be2cc..2dc9e0d 100644 --- a/submarine-server/server-core/src/test/java/org/apache/submarine/server/rest/ExperimentRestApiTest.java +++ b/submarine-server/server-core/src/test/java/org/apache/submarine/server/rest/ExperimentRestApiTest.java @@ -75,7 +75,6 @@ public class ExperimentRestApiTest { private static final String experimentStatus = "Succeeded"; private static final String metaName = "foo"; private static final String metaFramework = "TensorFlow"; - private static final String metaNamespace = "fooNamespace"; private static final String dockerImage = "continuumio/anaconda3"; private static final String kernelSpecName = "team_default_python_3"; private static final List<String> kernelChannels = Arrays.asList("defaults", "anaconda"); @@ -117,7 +116,6 @@ public class ExperimentRestApiTest { kernelSpec.setPipDependencies(kernelPipDependencies); meta.setName(metaName); meta.setFramework(metaFramework); - meta.setNamespace(metaNamespace); environmentSpec.setDockerImage(dockerImage); environmentSpec.setKernelSpec(kernelSpec); experimentSpec.setMeta(meta); @@ -224,7 +222,7 @@ public class ExperimentRestApiTest { assertEquals(experimentFinishedTime, experiment.getFinishedTime()); assertEquals(metaName, experiment.getSpec().getMeta().getName()); assertEquals(metaFramework, experiment.getSpec().getMeta().getFramework()); - assertEquals(metaNamespace, experiment.getSpec().getMeta().getNamespace()); + assertEquals("default", experiment.getSpec().getMeta().getNamespace()); assertEquals(dockerImage, experiment.getSpec().getEnvironment().getDockerImage()); assertEquals(kernelChannels, experiment.getSpec().getEnvironment().getKernelSpec().getChannels()); assertEquals(kernelSpecName, experiment.getSpec().getEnvironment().getKernelSpec().getName()); diff --git a/submarine-workbench/workbench-web/src/app/interfaces/experiment-spec.ts b/submarine-workbench/workbench-web/src/app/interfaces/experiment-spec.ts index 4686974..dbc7a18 100644 --- a/submarine-workbench/workbench-web/src/app/interfaces/experiment-spec.ts +++ b/submarine-workbench/workbench-web/src/app/interfaces/experiment-spec.ts @@ -20,7 +20,6 @@ export interface ExperimentMeta { name: string; description?: string; - namespace: string; framework: string; cmd: string; envVars?: { diff --git a/submarine-workbench/workbench-web/src/app/pages/workbench/experiment/experiment-home/experiment-form/experiment-customized-form/experiment-customized-form.component.html b/submarine-workbench/workbench-web/src/app/pages/workbench/experiment/experiment-home/experiment-form/experiment-customized-form/experiment-customized-form.component.html index 4c29168..ebd1726 100644 --- a/submarine-workbench/workbench-web/src/app/pages/workbench/experiment/experiment-home/experiment-form/experiment-customized-form/experiment-customized-form.component.html +++ b/submarine-workbench/workbench-web/src/app/pages/workbench/experiment/experiment-home/experiment-form/experiment-customized-form/experiment-customized-form.component.html @@ -102,15 +102,6 @@ </button> </div> <div *ngIf="ADVANCED" class="single-field-group"> - <label for="namespace"> - <span class="red-star">*</span> - Namespace - </label> - <nz-select formControlName="namespace" id="namespace"> - <nz-option *ngFor="let namespace of nameSpaceList" [nzValue]="namespace" [nzLabel]="namespace"></nz-option> - </nz-select> - </div> - <div *ngIf="ADVANCED" class="single-field-group"> <label for="git-repo">Git repository</label> <nz-input-group [nzSuffix]="suffixTemplateInfo"> <input @@ -273,7 +264,6 @@ <div *ngSwitchCase="2" id="previewPage"> <nz-descriptions nzTitle="{{ jobTypes }}" nzBordered [nzColumn]="{ xxl: 2, xl: 2, lg: 2, md: 2, sm: 2, xs: 1 }"> <nz-descriptions-item nzTitle="Name">{{ finalExperimentSpec.meta.name }}</nz-descriptions-item> - <nz-descriptions-item nzTitle="Namespace">{{ finalExperimentSpec.meta.namespace }}</nz-descriptions-item> <nz-descriptions-item nzTitle="Command" [nzSpan]="2"> {{ finalExperimentSpec.meta.cmd }} </nz-descriptions-item> diff --git a/submarine-workbench/workbench-web/src/app/pages/workbench/experiment/experiment-home/experiment-form/experiment-customized-form/experiment-customized-form.component.ts b/submarine-workbench/workbench-web/src/app/pages/workbench/experiment/experiment-home/experiment-form/experiment-customized-form/experiment-customized-form.component.ts index 0560c9b..67ca65a 100644 --- a/submarine-workbench/workbench-web/src/app/pages/workbench/experiment/experiment-home/experiment-form/experiment-customized-form/experiment-customized-form.component.ts +++ b/submarine-workbench/workbench-web/src/app/pages/workbench/experiment/experiment-home/experiment-form/experiment-customized-form/experiment-customized-form.component.ts @@ -47,10 +47,6 @@ export class ExperimentCustomizedFormComponent implements OnInit, OnDestroy { step: number = 0; subscriptions: Subscription[] = []; - // TODO: Fetch all namespaces from submarine server - defaultNameSpace = 'default'; - nameSpaceList = [this.defaultNameSpace, 'submarine']; - // TODO: Fetch all images from submarine server imageIndex = 0; defaultImage = 'apache/submarine:tf-mnist-with-summaries-1.0'; @@ -90,7 +86,6 @@ export class ExperimentCustomizedFormComponent implements OnInit, OnDestroy { this.experiment = new FormGroup({ experimentName: new FormControl(null, [Validators.pattern('[a-zA-Z0-9][a-zA-Z0-9\-]*'), Validators.required]), description: new FormControl(null, [Validators.required]), - namespace: new FormControl(this.defaultNameSpace, [Validators.required]), cmd: new FormControl('', [Validators.required]), image: new FormControl(this.defaultImage, [Validators.required]), envs: new FormArray([], [this.experimentValidatorService.nameValidatorFactory('key')]), @@ -156,9 +151,6 @@ export class ExperimentCustomizedFormComponent implements OnInit, OnDestroy { get description() { return this.experiment.get('description'); } - get namespace() { - return this.experiment.get('namespace'); - } get cmd() { return this.experiment.get('cmd'); } @@ -189,7 +181,6 @@ export class ExperimentCustomizedFormComponent implements OnInit, OnDestroy { if (this.step === 0) { this.experimentFormService.btnStatusChange( this.experimentName.invalid || - this.namespace.invalid || this.cmd.invalid || this.image.invalid || this.envs.invalid @@ -323,7 +314,6 @@ export class ExperimentCustomizedFormComponent implements OnInit, OnDestroy { // Construct the spec const meta: ExperimentMeta = { name: this.experimentName.value.toLowerCase(), - namespace: this.namespace.value, framework: this.framework === 'Standalone' ? 'Tensorflow' : this.framework, cmd: this.cmd.value, envVars: {} @@ -404,7 +394,6 @@ export class ExperimentCustomizedFormComponent implements OnInit, OnDestroy { cloneExperiment(spec: ExperimentSpec) { this.description.setValue(spec.meta.description); - this.namespace.setValue(spec.meta.namespace); this.cmd.setValue(spec.meta.cmd); this.image.setValue(spec.environment.image); if (this.imageList.indexOf(spec.environment.image) === -1) { diff --git a/submarine-workbench/workbench-web/src/app/pages/workbench/experiment/experiment-home/experiment-form/experiment-predefined-form/experiment-predefined-form.component.ts b/submarine-workbench/workbench-web/src/app/pages/workbench/experiment/experiment-home/experiment-form/experiment-predefined-form/experiment-predefined-form.component.ts index 5a1864f..a8f2bae 100644 --- a/submarine-workbench/workbench-web/src/app/pages/workbench/experiment/experiment-home/experiment-form/experiment-predefined-form/experiment-predefined-form.component.ts +++ b/submarine-workbench/workbench-web/src/app/pages/workbench/experiment/experiment-home/experiment-form/experiment-predefined-form/experiment-predefined-form.component.ts @@ -34,7 +34,6 @@ interface ParsedTemplate { value: string; }[]; experimentName: string; - experimentNamespace: string; experimentCommand: string; experimentImage: string; experimentVars: string; @@ -130,7 +129,6 @@ export class ExperimentPredefinedFormComponent implements OnInit, OnDestroy { let template: ParsedTemplate = { templateParams: item.experimentTemplateSpec.parameters.filter((item) => !item.name.startsWith('spec.')), experimentName: item.experimentTemplateSpec.experimentSpec.meta.name, - experimentNamespace: item.experimentTemplateSpec.experimentSpec.meta.namespace, experimentCommand: item.experimentTemplateSpec.experimentSpec.meta.cmd, experimentImage: item.experimentTemplateSpec.experimentSpec.environment.image, experimentVars: JSON.stringify(item.experimentTemplateSpec.experimentSpec.meta.envVars), diff --git a/submarine-workbench/workbench-web/src/app/pages/workbench/template/template-home/template-form/template-form.component.ts b/submarine-workbench/workbench-web/src/app/pages/workbench/template/template-home/template-form/template-form.component.ts index da0585b..218c50f 100644 --- a/submarine-workbench/workbench-web/src/app/pages/workbench/template/template-home/template-form/template-form.component.ts +++ b/submarine-workbench/workbench-web/src/app/pages/workbench/template/template-home/template-form/template-form.component.ts @@ -54,7 +54,6 @@ export class TemplateFormComponent implements OnInit { MEMORY_UNITS = ['M', 'G']; AUTHOR = 'admin'; - NAMESPACE = 'default'; constructor( private experimentValidatorService: ExperimentValidatorService, @@ -254,7 +253,6 @@ export class TemplateFormComponent implements OnInit { name: this.defaultExperimentName, envVars: envVars, framework: this.framework, - namespace: this.NAMESPACE, }, spec: specs, environment: { --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@submarine.apache.org For additional commands, e-mail: dev-h...@submarine.apache.org