From 0370c9b71c6e175fb915cc1cbce5ed058ea98c70 Mon Sep 17 00:00:00 2001 From: Juntao Wang Date: Mon, 25 Sep 2023 15:39:31 -0400 Subject: [PATCH] Show alert when external route is set while token is not set for model server --- .../modelServing/ServingRuntimeList.spec.ts | 33 ++++++++++++++++ .../ManageServingRuntimeModal.tsx | 38 +++++++++++++++++-- .../ServingRuntimeTokenSection.tsx | 15 -------- 3 files changed, 67 insertions(+), 19 deletions(-) diff --git a/frontend/src/__tests__/integration/pages/modelServing/ServingRuntimeList.spec.ts b/frontend/src/__tests__/integration/pages/modelServing/ServingRuntimeList.spec.ts index 486bc8233c..d3460a52d0 100644 --- a/frontend/src/__tests__/integration/pages/modelServing/ServingRuntimeList.spec.ts +++ b/frontend/src/__tests__/integration/pages/modelServing/ServingRuntimeList.spec.ts @@ -75,3 +75,36 @@ test('Legacy Serving Runtime', async ({ page }) => { await expect(firstRow).toHaveClass('pf-m-expanded'); await expect(secondRow).not.toHaveClass('pf-m-expanded'); }); + +test('Add server', async ({ page }) => { + await page.goto( + './iframe.html?args=&id=tests-integration-pages-modelserving-servingruntimelist--list-available-models&viewMode=story', + ); + + // wait for page to load + await page.waitForSelector('text=Add server'); + + await page.getByRole('button', { name: 'Add server', exact: true }).click(); + + // test that you can not submit on empty + await expect(page.getByRole('button', { name: 'Add', exact: true })).toBeDisabled(); + + // test filling in minimum required fields + await page.getByLabel('Model server name *').fill('Test Name'); + await page.locator('#serving-runtime-template-selection').click(); + await page.getByRole('menuitem', { name: 'New OVMS Server' }).click(); + await expect(page.getByRole('button', { name: 'Add', exact: true })).toBeEnabled(); + + // test the if the alert is visible when route is external while token is not set + await expect(page.locator('#external-route-no-token-alert')).toBeHidden(); + // external route, no token, show alert + await page.getByLabel('Make deployed models available through an external route').click(); + await expect(page.locator('#alt-form-checkbox-auth')).toBeChecked(); + await expect(page.locator('#external-route-no-token-alert')).toBeHidden(); + // external route, set token, hide alert + await page.getByLabel('Require token authentication').click(); + await expect(page.locator('#external-route-no-token-alert')).toBeVisible(); + // internal route, set token, show alert + await page.getByLabel('Make deployed models available through an external route').click(); + await expect(page.locator('#external-route-no-token-alert')).toBeHidden(); +}); diff --git a/frontend/src/pages/modelServing/screens/projects/ServingRuntimeModal/ManageServingRuntimeModal.tsx b/frontend/src/pages/modelServing/screens/projects/ServingRuntimeModal/ManageServingRuntimeModal.tsx index ec99407ebf..2585954040 100644 --- a/frontend/src/pages/modelServing/screens/projects/ServingRuntimeModal/ManageServingRuntimeModal.tsx +++ b/frontend/src/pages/modelServing/screens/projects/ServingRuntimeModal/ManageServingRuntimeModal.tsx @@ -7,10 +7,12 @@ import { FormGroup, FormSection, Modal, + Popover, Stack, StackItem, } from '@patternfly/react-core'; import { EitherOrNone } from '@openshift/dynamic-plugin-sdk'; +import { HelpIcon } from '@patternfly/react-icons'; import { isGpuDisabled, useCreateServingRuntimeObject, @@ -80,7 +82,7 @@ const ManageServingRuntimeModal: React.FC = ({ const namespace = currentProject.metadata.name; - const [allowCreate, rbacLoaded] = useAccessReview({ + const [allowCreate] = useAccessReview({ ...accessReviewResource, namespace, }); @@ -96,7 +98,7 @@ const ManageServingRuntimeModal: React.FC = ({ const inputValueValid = customServingRuntimesEnabled ? baseInputValueValid && createData.name && servingRuntimeTemplateNameValid : baseInputValueValid; - const canCreate = !actionInProgress && !tokenErrors && inputValueValid && rbacLoaded; + const canCreate = !actionInProgress && !tokenErrors && inputValueValid; const servingRuntimeSelected = React.useMemo( () => @@ -273,6 +275,19 @@ const ManageServingRuntimeModal: React.FC = ({ setAcceleratorState={setAcceleratorState} /> + {!allowCreate && ( + + + + + + )} @@ -281,7 +296,13 @@ const ManageServingRuntimeModal: React.FC = ({ id="alt-form-checkbox-route" name="alt-form-checkbox-route" isChecked={createData.externalRoute} - onChange={(check) => setCreateData('externalRoute', check)} + isDisabled={!allowCreate} + onChange={(check) => { + setCreateData('externalRoute', check); + if (check && allowCreate) { + setCreateData('tokenAuth', check); + } + }} /> @@ -291,9 +312,18 @@ const ManageServingRuntimeModal: React.FC = ({ data={createData} setData={setCreateData} allowCreate={allowCreate} - rbacLoaded={rbacLoaded} /> + {createData.externalRoute && !createData.tokenAuth && ( + + + + )} diff --git a/frontend/src/pages/modelServing/screens/projects/ServingRuntimeModal/ServingRuntimeTokenSection.tsx b/frontend/src/pages/modelServing/screens/projects/ServingRuntimeModal/ServingRuntimeTokenSection.tsx index baf749568d..17be3134fd 100644 --- a/frontend/src/pages/modelServing/screens/projects/ServingRuntimeModal/ServingRuntimeTokenSection.tsx +++ b/frontend/src/pages/modelServing/screens/projects/ServingRuntimeModal/ServingRuntimeTokenSection.tsx @@ -6,7 +6,6 @@ import { FormGroup, FormSection, getUniqueId, - Skeleton, Stack, StackItem, } from '@patternfly/react-core'; @@ -20,14 +19,12 @@ type ServingRuntimeTokenSectionProps = { data: CreatingServingRuntimeObject; setData: UpdateObjectAtPropAndValue; allowCreate: boolean; - rbacLoaded: boolean; }; const ServingRuntimeTokenSection: React.FC = ({ data, setData, allowCreate, - rbacLoaded, }) => { const createNewToken = () => { const name = 'default-name'; @@ -43,10 +40,6 @@ const ServingRuntimeTokenSection: React.FC = ({ ]); }; - if (!rbacLoaded) { - return ; - } - return ( @@ -65,14 +58,6 @@ const ServingRuntimeTokenSection: React.FC = ({ /> - {!allowCreate && ( - - )} - {data.tokenAuth && (