Skip to content

Commit

Permalink
Display internal addresses even when models are external
Browse files Browse the repository at this point in the history
  • Loading branch information
ppadti committed Oct 17, 2024
1 parent 3f41512 commit c8f8f0d
Show file tree
Hide file tree
Showing 4 changed files with 176 additions and 19 deletions.
8 changes: 8 additions & 0 deletions frontend/src/__tests__/cypress/cypress/pages/modelServing.ts
Original file line number Diff line number Diff line change
Expand Up @@ -311,6 +311,14 @@ class InferenceServiceRow extends TableRow {
findInternalServicePopover() {
return cy.findByTestId('internal-service-popover');
}

findExternalServiceButton() {
return this.find().findByTestId('internal-external-service-button');
}

findExternalServicePopover() {
return cy.findByTestId('external-service-popover');
}
}
class ServingPlatformCard extends Contextual<HTMLElement> {
findDeployModelButton() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -481,6 +481,10 @@ describe('Serving Runtime List', () => {
mockInferenceServiceK8sResource({
name: 'another-inference-service',
displayName: 'Another Inference Service',
statusPredictor: {
grpcUrl: 'grpc://modelmesh-serving.app:8033',
restUrl: 'http:///modelmesh-serving.app:8000',
},
deleted: true,
isModelMesh: true,
}),
Expand Down Expand Up @@ -548,6 +552,107 @@ describe('Serving Runtime List', () => {
.findInferenceServiceTableHeaderButton('Model name')
.should(be.sortDescending);
});

it('modelmesh inference endpoints when external route is enabled', () => {
initIntercepts({
projectEnableModelMesh: true,
disableKServeConfig: false,
disableModelMeshConfig: true,
inferenceServices: [
mockInferenceServiceK8sResource({
name: 'another-inference-service',
displayName: 'Another Inference Service',
statusPredictor: {
grpcUrl: 'grpc://modelmesh-serving.app:8033',
restUtl: 'http:///modelmesh-serving.app:8000',
},
deleted: true,
isModelMesh: true,
}),
],
});

projectDetails.visitSection('test-project', 'model-server');
modelServingSection
.getModelMeshRow('OVMS Model Serving')
.findDeployedModelExpansionButton()
.click();
const inferenceServiceRow = modelServingSection.getInferenceServiceRow(
'Another Inference Service',
);
inferenceServiceRow.findExternalServiceButton().click();
inferenceServiceRow
.findExternalServicePopover()
.findByText('Internal (can only be accessed from inside the cluster)')
.should('exist');
inferenceServiceRow
.findExternalServicePopover()
.findByText('grpc://modelmesh-serving.app:8033')
.should('exist');
inferenceServiceRow
.findExternalServicePopover()
.findByText('http:///modelmesh-serving.app:8000')
.should('exist');
inferenceServiceRow
.findExternalServicePopover()
.findByText('External (can be accessed from inside or outside the cluster)')
.should('exist');
inferenceServiceRow
.findExternalServicePopover()
.findByText('https://another-inference-service-test-project.apps.user.com/infer')
.should('exist');
});

it('modelmesh inference endpoints when external route is not enabled', () => {
initIntercepts({
projectEnableModelMesh: true,
disableKServeConfig: false,
disableModelMeshConfig: true,
inferenceServices: [
mockInferenceServiceK8sResource({
name: 'another-inference-service',
displayName: 'Another Inference Service',
statusPredictor: {
grpcUrl: 'grpc://modelmesh-serving.app:8033',
restUtl: 'http:///modelmesh-serving.app:8000',
},
deleted: true,
isModelMesh: true,
}),
],
servingRuntimes: [
mockServingRuntimeK8sResourceLegacy({}),
mockServingRuntimeK8sResource({
name: 'test-model',
namespace: 'test-project',
auth: true,
route: false,
}),
],
});

projectDetails.visitSection('test-project', 'model-server');
modelServingSection
.getModelMeshRow('OVMS Model Serving')
.findDeployedModelExpansionButton()
.click();
const inferenceServiceRow = modelServingSection.getInferenceServiceRow(
'Another Inference Service',
);
inferenceServiceRow.findInternalServiceButton().click();
inferenceServiceRow
.findInternalServicePopover()
.findByText('Internal (can only be accessed from inside the cluster)')
.should('exist');
inferenceServiceRow
.findInternalServicePopover()
.findByText('grpc://modelmesh-serving.app:8033')
.should('exist');
inferenceServiceRow
.findInternalServicePopover()
.findByText('http:///modelmesh-serving.app:8000')
.should('exist');
});
});

describe('KServe', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@ import * as React from 'react';
import {
Button,
ClipboardCopy,
ClipboardCopyVariant,
DescriptionList,
DescriptionListDescription,
DescriptionListGroup,
DescriptionListTerm,
Divider,
HelperText,
HelperTextItem,
Popover,
Expand Down Expand Up @@ -40,14 +46,15 @@ const InferenceServiceEndpoint: React.FC<InferenceServiceEndpointProps> = ({
return (
<Popover
data-testid="internal-service-popover"
headerContent="Internal Service can be accessed inside the cluster"
headerContent="Inference endpoints"
aria-label="Internal Service Info"
hasAutoWidth
bodyContent={
<InternalServicePopoverContent inferenceService={inferenceService} isKserve={isKserve} />
}
>
<Button data-testid="internal-service-button" isInline variant="link">
Internal Service
Endpoint details (internal)
</Button>
</Popover>
);
Expand All @@ -68,9 +75,38 @@ const InferenceServiceEndpoint: React.FC<InferenceServiceEndpointProps> = ({
}

return (
<ClipboardCopy hoverTip="Copy" clickTip="Copied" isReadOnly>
{isKserve ? routeLink : `${routeLink}/infer`}
</ClipboardCopy>
<Popover
data-testid="external-service-popover"
headerContent="Inference endpoints"
aria-label="External Service Info"
hasAutoWidth
bodyContent={
<InternalServicePopoverContent inferenceService={inferenceService} isKserve={isKserve} />
}
footerContent={
<DescriptionList>
<DescriptionListGroup>
<Divider />
<DescriptionListTerm>
External (can be accessed from inside or outside the cluster)
</DescriptionListTerm>
<DescriptionListDescription style={{ paddingLeft: 'var(--pf-v5-global--spacer--md)' }}>
<ClipboardCopy
hoverTip="Copy"
clickTip="Copied"
variant={ClipboardCopyVariant.inlineCompact}
>
{isKserve ? routeLink : `${routeLink}/infer`}
</ClipboardCopy>
</DescriptionListDescription>
</DescriptionListGroup>
</DescriptionList>
}
>
<Button data-testid="internal-external-service-button" isInline variant="link">
Endpoint details (internal and external)
</Button>
</Popover>
);
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
DescriptionListDescription,
DescriptionListGroup,
DescriptionListTerm,
ListItem,
} from '@patternfly/react-core';
import { InferenceServiceKind } from '~/k8sTypes';

Expand Down Expand Up @@ -47,20 +48,27 @@ const InternalServicePopoverContent: React.FC<InternalServicePopoverContentProps

return (
<DescriptionList isCompact>
{Object.entries(isInternalServiceEnabled).map(([route, value]) => (
<DescriptionListGroup key={route}>
<DescriptionListTerm>{route}</DescriptionListTerm>
<DescriptionListDescription>
<ClipboardCopy
hoverTip="Copy"
clickTip="Copied"
variant={ClipboardCopyVariant.inlineCompact}
>
{value}
</ClipboardCopy>
</DescriptionListDescription>
</DescriptionListGroup>
))}
<DescriptionListTerm>
Internal (can only be accessed from inside the cluster)
</DescriptionListTerm>
{Object.entries(isInternalServiceEnabled)
.slice(0, 2)
.map(([route, value]) => (
<DescriptionListGroup key={route}>
<DescriptionListTerm>
<ListItem>{route}</ListItem>
</DescriptionListTerm>
<DescriptionListDescription style={{ paddingLeft: 'var(--pf-v5-global--spacer--md)' }}>
<ClipboardCopy
hoverTip="Copy"
clickTip="Copied"
variant={ClipboardCopyVariant.inlineCompact}
>
{value}
</ClipboardCopy>
</DescriptionListDescription>
</DescriptionListGroup>
))}
</DescriptionList>
);
};
Expand Down

0 comments on commit c8f8f0d

Please sign in to comment.