Skip to content

Commit 56d7480

Browse files
feat: Fetch resource from manager (#3875)
* Fetch resource from manager * Take status from latest condition * Compare resolved types of status * Correction * Correct style for badge
1 parent 71e7a87 commit 56d7480

File tree

3 files changed

+138
-4
lines changed

3 files changed

+138
-4
lines changed

src/components/KymaModules/components/ModuleStatus.tsx

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,22 @@ import { StatusBadge } from 'shared/components/StatusBadge/StatusBadge';
22
import { useModuleStatus } from '../support';
33

44
export const resolveType = (status: string) => {
5+
if (typeof status !== 'string') {
6+
return 'None';
7+
}
8+
59
switch (status) {
10+
case 'Initial':
11+
case 'Pending':
12+
case 'Available':
13+
case 'Released':
14+
return 'Information';
615
case 'Ready':
16+
case 'Bound':
17+
case 'Running':
18+
case 'Success':
19+
case 'Succeeded':
20+
case 'Ok':
721
return 'Positive';
822
case 'Processing':
923
case 'Deleting':
@@ -12,7 +26,10 @@ export const resolveType = (status: string) => {
1226
return 'None';
1327
case 'Warning':
1428
return 'Critical';
29+
case 'Failed':
1530
case 'Error':
31+
case 'Failure':
32+
case 'Invalid':
1633
return 'Negative';
1734
default:
1835
return 'None';

src/components/KymaModules/components/ModulesListRows.tsx

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,10 @@ import {
44
findModuleTemplate,
55
KymaResourceType,
66
ModuleTemplateListType,
7+
ModuleTemplateStatus,
78
ModuleTemplateType,
9+
resolveInstallationStateName,
10+
useGetManagerStatus,
811
} from '../support';
912
import { EMPTY_TEXT_PLACEHOLDER } from 'shared/constants';
1013
import { useTranslation } from 'react-i18next';
@@ -74,6 +77,10 @@ export const ModulesListRows = ({
7477
resource?.version,
7578
);
7679

80+
const { data: managerResourceState } = useGetManagerStatus(
81+
currentModuleTemplate?.spec?.manager,
82+
);
83+
7784
if (
7885
moduleStatus &&
7986
!moduleStatus.resource &&
@@ -99,7 +106,7 @@ export const ModulesListRows = ({
99106

100107
const currentModuleReleaseMeta = findModuleReleaseMeta(resource.name);
101108

102-
const isChannelOverriden =
109+
const isChannelOverridden =
103110
kymaResource?.spec?.modules?.[moduleIndex]?.channel !== undefined;
104111

105112
return [
@@ -122,6 +129,16 @@ export const ModulesListRows = ({
122129
{t('kyma-modules.beta')}
123130
</Tag>
124131
) : null}
132+
{moduleStatus?.state === ModuleTemplateStatus.Unmanaged && (
133+
<Tag
134+
className="sap-margin-begin-tiny"
135+
hideStateIcon
136+
colorScheme="5"
137+
design="Set2"
138+
>
139+
{moduleStatus.state}
140+
</Tag>
141+
)}
125142
</>,
126143
// Namespace
127144
moduleStatus?.resource?.metadata?.namespace || EMPTY_TEXT_PLACEHOLDER,
@@ -131,7 +148,7 @@ export const ModulesListRows = ({
131148
? moduleStatus?.channel
132149
: kymaResource?.spec?.modules?.[moduleIndex]?.channel ||
133150
kymaResource?.spec?.channel}
134-
{isChannelOverriden ? (
151+
{isChannelOverridden ? (
135152
<Tag
136153
hideStateIcon
137154
design="Set2"
@@ -155,7 +172,11 @@ export const ModulesListRows = ({
155172
type={resolveType(moduleStatus?.state ?? '')}
156173
tooltipContent={moduleStatus?.message}
157174
>
158-
{moduleStatus?.state || 'Unknown'}
175+
{resolveInstallationStateName(
176+
moduleStatus?.state,
177+
!!currentModuleTemplate?.spec?.manager,
178+
managerResourceState,
179+
)}
159180
</StatusBadge>,
160181
// Documentation
161182
moduleDocs ? (

src/components/KymaModules/support.ts

Lines changed: 97 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,27 @@ import React, { useEffect, useState } from 'react';
33

44
import { useFetch } from 'shared/hooks/BackendAPI/useFetch';
55
import { ColumnLayoutState } from 'state/columnLayoutAtom';
6+
import { resolveType } from './components/ModuleStatus';
7+
8+
export const enum ModuleTemplateStatus {
9+
Ready = 'Ready',
10+
Processing = 'Processing',
11+
Deleting = 'Deleting',
12+
Unknown = 'Unknown',
13+
Unmanaged = 'Unmanaged',
14+
Warning = 'Warning',
15+
Error = 'Error',
16+
NotInstalled = 'Not installed',
17+
}
18+
19+
type ConditionType = {
20+
lastTransitionTime: string;
21+
lastUpdateTime: string;
22+
message: string;
23+
reason: string;
24+
status: string;
25+
type: string;
26+
};
627

728
export type KymaResourceSpecModuleType = {
829
name: string;
@@ -105,7 +126,7 @@ export function useGetAllModulesStatuses(modules: any[]) {
105126
const status = (await response.json())?.status;
106127
return {
107128
key: resource?.metadata?.name ?? resource?.name,
108-
status: status?.state || 'Unknown',
129+
status: status?.state || ModuleTemplateStatus.Unknown,
109130
};
110131
} catch (e) {
111132
return {
@@ -152,6 +173,14 @@ export const findModuleSpec = (
152173
);
153174
};
154175

176+
type ModuleManagerType = {
177+
name: string;
178+
namespace: string;
179+
group: string;
180+
version: string;
181+
kind: string;
182+
};
183+
155184
export type ModuleTemplateType = {
156185
metadata: {
157186
name: string;
@@ -167,6 +196,7 @@ export type ModuleTemplateType = {
167196
info?: {
168197
documentation?: string;
169198
};
199+
manager: ModuleManagerType;
170200
};
171201
};
172202

@@ -244,3 +274,69 @@ export const checkSelectedModule = (
244274
}
245275
return false;
246276
};
277+
278+
export function useGetManagerStatus(manager?: ModuleManagerType) {
279+
const fetch = useFetch();
280+
const [data, setData] = useState<any>(ModuleTemplateStatus.Unknown);
281+
const [error, setError] = useState<Error | null>(null);
282+
283+
useEffect(() => {
284+
if (manager) {
285+
const path = getResourcePath({
286+
apiVersion: `${manager?.group}/${manager?.version}`,
287+
kind: manager?.kind,
288+
metadata: {
289+
name: manager?.name,
290+
namespace: manager?.namespace,
291+
},
292+
} as KymaResourceType);
293+
async function fetchResource() {
294+
try {
295+
const response = await fetch({ relativeUrl: path });
296+
const status = (await response.json())?.status;
297+
const latest = status?.conditions
298+
?.filter((condition: ConditionType) => condition?.status === 'True')
299+
?.reduce(
300+
(acc: ConditionType, condition: ConditionType) =>
301+
new Date(acc?.lastUpdateTime).getTime() >
302+
new Date(condition?.lastUpdateTime).getTime()
303+
? acc
304+
: condition,
305+
{},
306+
);
307+
if (latest?.type) {
308+
setData(latest.type);
309+
}
310+
} catch (error) {
311+
if (error instanceof Error) {
312+
setError(error);
313+
}
314+
}
315+
}
316+
317+
fetchResource();
318+
}
319+
// eslint-disable-next-line react-hooks/exhaustive-deps
320+
}, [manager]);
321+
322+
return { data, error };
323+
}
324+
325+
export const resolveInstallationStateName = (
326+
state?: string,
327+
managerExists?: boolean,
328+
managerResourceState?: string,
329+
) => {
330+
if (state === ModuleTemplateStatus.Unmanaged && !managerExists) {
331+
return ModuleTemplateStatus.NotInstalled;
332+
}
333+
334+
if (state === ModuleTemplateStatus.Unmanaged && managerExists) {
335+
if (resolveType(state) !== resolveType(managerResourceState ?? '')) {
336+
return ModuleTemplateStatus.Processing;
337+
}
338+
return managerResourceState || ModuleTemplateStatus.Unknown;
339+
}
340+
341+
return state || ModuleTemplateStatus.Unknown;
342+
};

0 commit comments

Comments
 (0)