Skip to content

Commit 7b2fa54

Browse files
authored
Merge pull request #53 from bartoval/fix_error_access_token
access token error show loading loop
2 parents 8456d60 + ac2fba0 commit 7b2fa54

File tree

7 files changed

+44
-67
lines changed

7 files changed

+44
-67
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ This plugin for Openshift installs a tab in **Projects** -> **< project name >**
1919

2020
To install the dynamic plugin, follow these steps:
2121

22-
- **Authenticate with your cluster:**, then run the following command in the directory containing your `manifest.json` file.
22+
- **Authenticate with your cluster:**, then run the following command in the directory containing your `manifest.yaml` file.
2323

2424
```shell
2525
kubectl apply -f manifest.yaml

__tests__/DeploymentNetworkConsoleButton.spec.tsx

Lines changed: 0 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -37,19 +37,6 @@ const defaultMutationMock = {
3737
error: null
3838
};
3939

40-
type ResourceOptions = { name?: string; selector?: { matchLabels?: Record<string, string> } };
41-
42-
const loadedResourceMock = (resourceName: string) => (options: ResourceOptions) => {
43-
if (options.name === resourceName) {
44-
return [{ spec: { host: 'example.com', port: { targetPort: '8080' } } }, false, undefined];
45-
}
46-
if (options.selector?.matchLabels?.['app.kubernetes.io/name'] === 'network-observer') {
47-
return [{ status: { phase: 'Running' } }, false, undefined];
48-
}
49-
50-
return [undefined, false, undefined];
51-
};
52-
5340
const BUTTON_LABELS = {
5441
deploy: 'Deploy the Network Console',
5542
open: 'Open the Network Console',
@@ -72,15 +59,6 @@ describe('DeploymentNetworkConsoleButton', () => {
7259
expect(screen.getByText(BUTTON_LABELS.deploy)).toBeInTheDocument();
7360
});
7461

75-
it('renders the open and delete buttons when loaded', () => {
76-
mockUseK8sWatchResource.mockImplementation(loadedResourceMock('network-observer'));
77-
mockUseMutationImpl.mockReturnValue(defaultMutationMock);
78-
79-
render(<DeploymentNetworkConsoleButton />);
80-
expect(screen.getByText(BUTTON_LABELS.open)).toBeInTheDocument();
81-
expect(screen.getByText(BUTTON_LABELS.delete)).toBeInTheDocument();
82-
});
83-
8462
it('calls the create mutation when the deploy button is clicked', () => {
8563
const mutateMock = vi.fn();
8664
mockUseK8sWatchResource.mockReturnValue([undefined, false, undefined]);
@@ -90,30 +68,4 @@ describe('DeploymentNetworkConsoleButton', () => {
9068
fireEvent.click(screen.getByText(BUTTON_LABELS.deploy));
9169
expect(mutateMock).toHaveBeenCalled();
9270
});
93-
94-
it('calls the delete mutation when the delete button is clicked and calls onSuccess', () => {
95-
const mutateMock = vi.fn();
96-
let onSuccessCallback: (() => void) | undefined;
97-
98-
mockUseK8sWatchResource.mockImplementation(loadedResourceMock('network-observer'));
99-
mockUseMutationImpl.mockImplementation(({ onSuccess }) => {
100-
onSuccessCallback = onSuccess;
101-
102-
return { ...defaultMutationMock, mutate: mutateMock };
103-
});
104-
105-
render(<DeploymentNetworkConsoleButton />);
106-
fireEvent.click(screen.getByText(BUTTON_LABELS.delete));
107-
expect(mutateMock).toHaveBeenCalled();
108-
109-
onSuccessCallback?.();
110-
});
111-
112-
it('updates URL when route data changes', () => {
113-
mockUseK8sWatchResource.mockImplementation(loadedResourceMock('network-observer'));
114-
mockUseMutationImpl.mockReturnValue(defaultMutationMock);
115-
116-
render(<DeploymentNetworkConsoleButton />);
117-
expect(screen.getByText(BUTTON_LABELS.open)).toBeInTheDocument();
118-
});
11971
});

src/console/deployment/Deployment.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
"spec": {
2828
"containers": [
2929
{
30-
"image": "quay.io/skupper/network-observer:v2-latest",
30+
"image": "quay.io/skupper/network-observer:v2-dev",
3131
"imagePullPolicy": "Always",
3232
"name": "network-observer",
3333
"args": [

src/console/pages/components/DeploymentNetworkConsoleButton.tsx

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ const DeploymentNetworkConsoleButton = function () {
5151
const watchResource = {
5252
groupVersionKind,
5353
namespace: NamespaceManager.getNamespace(),
54-
isList: false,
54+
isList: true,
5555
name: ROUTE
5656
};
5757

@@ -64,7 +64,7 @@ const DeploymentNetworkConsoleButton = function () {
6464
}
6565
};
6666

67-
const [data] = useK8sWatchResource<RouteResource>(watchResource);
67+
const [route] = useK8sWatchResource<RouteResource[]>(watchResource);
6868
const [deployment] = useK8sWatchResource<PodResource>(watchResourcePod);
6969

7070
const mutationCreate = useMutation({
@@ -85,13 +85,15 @@ const DeploymentNetworkConsoleButton = function () {
8585
const handleDeleteConsole = async () => {
8686
mutationDelete.mutate();
8787
};
88-
8988
useEffect(() => {
89+
console.log('route', route);
90+
const data = route?.find((r) => r.metadata?.name?.includes(ROUTE));
91+
9092
if (data?.spec?.host && data?.spec?.port?.targetPort) {
9193
const newUrl = data?.spec?.host ? `${data?.spec?.port?.targetPort}://${data?.spec?.host}` : undefined;
9294
setUrl(newUrl);
9395
}
94-
}, [data?.spec?.host, data?.spec?.port?.targetPort]);
96+
}, [route]);
9597

9698
const loaded = deployment?.status?.phase === POD_LOADED_STATUS && url;
9799

src/console/pages/components/forms/LinkForm/Footer.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,15 +59,15 @@ export const Footer: FC<FooterProps> = function ({ onCancel, onSubmit }) {
5959
});
6060

6161
const handleSubmit = useCallback(() => {
62-
if (!fileContent) {
62+
if (!fileContent || !name) {
6363
setValidated(t('Fill out all required fields before continuing'));
6464

6565
return;
6666
}
6767

6868
try {
6969
const JsonFile = parse(fileContent) as AccessGrantCrdResponse;
70-
const { metadata, status } = JsonFile;
70+
const { status } = JsonFile;
7171

7272
if (!status) {
7373
setValidated(t('Invalid Grant format'));
@@ -77,7 +77,7 @@ export const Footer: FC<FooterProps> = function ({ onCancel, onSubmit }) {
7777

7878
const data: AccessTokenCrdParams = createAccessTokenRequest({
7979
metadata: {
80-
name: name || metadata.name
80+
name
8181
},
8282
spec: {
8383
linkCost: Number(cost),

src/console/pages/components/forms/LinkForm/FormPage.tsx

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,10 @@ import { useCallback, FormEvent } from 'react';
33
import { I18nNamespace } from '@config/config';
44
import { Form, FormGroup, TextInput, FileUpload, DropEvent } from '@patternfly/react-core';
55
import { useTranslation } from 'react-i18next';
6+
import { parse } from 'yaml';
67

78
import { useLinkForm } from './hooks/useLinkForm';
9+
import { AccessGrantCrdResponse } from '../../../../interfaces/CRD_AccessGrant';
810

911
export const FormPage = function () {
1012
const { t } = useTranslation(I18nNamespace);
@@ -22,7 +24,13 @@ export const FormPage = function () {
2224

2325
const handleFileContentChange = useCallback(
2426
(_: DropEvent, value: string) => {
27+
const JsonFile = parse(value) as AccessGrantCrdResponse;
28+
const { metadata } = JsonFile;
2529
dispatch({ type: 'SET_FILE_CONTENT', payload: value });
30+
31+
if (metadata?.name) {
32+
dispatch({ type: 'SET_NAME', payload: metadata.name });
33+
}
2634
},
2735
[dispatch]
2836
);
@@ -59,7 +67,7 @@ export const FormPage = function () {
5967
/>
6068
</FormGroup>
6169

62-
<FormGroup label={t('Name')} fieldId="form-name-input">
70+
<FormGroup isRequired label={t('Name')} fieldId="form-name-input">
6371
<TextInput
6472
isRequired
6573
data-testid="simple-form-name-01"

src/console/pages/components/forms/LinkForm/SummaryPage.tsx

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ export const SummaryPage = function () {
2121

2222
const [isLoading, setIsLoading] = useState(true);
2323

24-
const { data: accessTokens } = useWatchedSkupperResource({
24+
const { data: accessTokens, error: accessTokenError } = useWatchedSkupperResource({
2525
kind: 'AccessToken',
2626
isList: false,
2727
name: name || fileName
@@ -36,11 +36,19 @@ export const SummaryPage = function () {
3636
const hasError =
3737
accessToken?.status?.status === 'Error' ||
3838
(accessToken?.status?.status && link?.status?.status && link?.status?.status === 'Error');
39-
const errorMessage = link?.status?.status || accessToken?.status?.status;
39+
const errorMessage = link?.status?.status || accessToken?.status?.message;
4040

4141
useEffect(() => {
42-
if (!hasStatus) {
43-
return;
42+
if (accessTokenError) {
43+
setIsLoading(false);
44+
setExternalLoading(false);
45+
setValidated('Generic error');
46+
}
47+
48+
if (hasError) {
49+
setIsLoading(false);
50+
setExternalLoading(false);
51+
setValidated(errorMessage);
4452
}
4553

4654
if (isConfigured) {
@@ -51,12 +59,19 @@ export const SummaryPage = function () {
5159
return;
5260
}
5361

54-
if (hasError) {
55-
setIsLoading(false);
56-
setExternalLoading(false);
57-
setValidated(errorMessage);
62+
if (!hasStatus) {
63+
return;
5864
}
59-
}, [setValidated, setIsLoading, setExternalLoading, isConfigured, hasError, hasStatus, errorMessage]);
65+
}, [
66+
setValidated,
67+
setIsLoading,
68+
setExternalLoading,
69+
accessTokenError,
70+
isConfigured,
71+
hasError,
72+
hasStatus,
73+
errorMessage
74+
]);
6075

6176
if (isLoading) {
6277
return (

0 commit comments

Comments
 (0)