|
@@ -8,8 +8,9 @@ import { PorterUrl } from "shared/routing";
|
|
|
|
|
|
|
|
import Chart from "./Chart";
|
|
import Chart from "./Chart";
|
|
|
import Loading from "components/Loading";
|
|
import Loading from "components/Loading";
|
|
|
|
|
+import { useWebsockets } from "shared/hooks/useWebsockets";
|
|
|
|
|
|
|
|
-type PropsType = {
|
|
|
|
|
|
|
+type Props = {
|
|
|
currentCluster: ClusterType;
|
|
currentCluster: ClusterType;
|
|
|
namespace: string;
|
|
namespace: string;
|
|
|
// TODO Convert to enum
|
|
// TODO Convert to enum
|
|
@@ -17,19 +18,21 @@ type PropsType = {
|
|
|
currentView: PorterUrl;
|
|
currentView: PorterUrl;
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
-const ChartList: React.FunctionComponent<PropsType> = ({
|
|
|
|
|
|
|
+const ChartList: React.FunctionComponent<Props> = ({
|
|
|
namespace,
|
|
namespace,
|
|
|
sortType,
|
|
sortType,
|
|
|
currentView,
|
|
currentView,
|
|
|
}) => {
|
|
}) => {
|
|
|
|
|
+ const {
|
|
|
|
|
+ newWebsocket,
|
|
|
|
|
+ openWebsocket,
|
|
|
|
|
+ closeWebsocket,
|
|
|
|
|
+ closeAllWebsockets,
|
|
|
|
|
+ } = useWebsockets();
|
|
|
const [charts, setCharts] = useState<ChartType[]>([]);
|
|
const [charts, setCharts] = useState<ChartType[]>([]);
|
|
|
- const [chartLookupTable, setChartLookupTable] = useState<
|
|
|
|
|
- Record<string, string>
|
|
|
|
|
- >({});
|
|
|
|
|
const [controllers, setControllers] = useState<
|
|
const [controllers, setControllers] = useState<
|
|
|
Record<string, Record<string, any>>
|
|
Record<string, Record<string, any>>
|
|
|
>({});
|
|
>({});
|
|
|
- const [websockets, setWebsockets] = useState<WebSocket[]>([]);
|
|
|
|
|
const [isLoading, setIsLoading] = useState(false);
|
|
const [isLoading, setIsLoading] = useState(false);
|
|
|
const [isError, setIsError] = useState(false);
|
|
const [isError, setIsError] = useState(false);
|
|
|
|
|
|
|
@@ -97,106 +100,45 @@ const ChartList: React.FunctionComponent<PropsType> = ({
|
|
|
console.log(error);
|
|
console.log(error);
|
|
|
context.setCurrentError(JSON.stringify(error));
|
|
context.setCurrentError(JSON.stringify(error));
|
|
|
setIsError(true);
|
|
setIsError(true);
|
|
|
- } finally {
|
|
|
|
|
- setIsLoading(false);
|
|
|
|
|
}
|
|
}
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
const setupWebsocket = (kind: string) => {
|
|
const setupWebsocket = (kind: string) => {
|
|
|
let { currentCluster, currentProject } = context;
|
|
let { currentCluster, currentProject } = context;
|
|
|
- let protocol = window.location.protocol == "https:" ? "wss" : "ws";
|
|
|
|
|
-
|
|
|
|
|
- let ws = new WebSocket(
|
|
|
|
|
- `${protocol}://${window.location.host}/api/projects/${currentProject.id}/k8s/${kind}/status?cluster_id=${currentCluster.id}`
|
|
|
|
|
- );
|
|
|
|
|
- ws.onopen = () => {
|
|
|
|
|
- console.log("connected to websocket");
|
|
|
|
|
- };
|
|
|
|
|
-
|
|
|
|
|
- ws.onmessage = (evt: MessageEvent) => {
|
|
|
|
|
- let event = JSON.parse(evt.data);
|
|
|
|
|
- let object = event.Object;
|
|
|
|
|
- object.metadata.kind = event.Kind;
|
|
|
|
|
- let chartKey = chartLookupTable[object.metadata.uid];
|
|
|
|
|
-
|
|
|
|
|
- // ignore if updated object does not belong to any chart in the list.
|
|
|
|
|
- if (!chartKey) {
|
|
|
|
|
- return;
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ const apiPath = `/api/projects/${currentProject.id}/k8s/${kind}/status?cluster_id=${currentCluster.id}`;
|
|
|
|
|
|
|
|
- let chartControllers = controllers[chartKey];
|
|
|
|
|
- chartControllers[object.metadata.uid] = object;
|
|
|
|
|
|
|
+ const wsConfig = {
|
|
|
|
|
+ onopen: () => {
|
|
|
|
|
+ console.log("connected to websocket");
|
|
|
|
|
+ },
|
|
|
|
|
+ onmessage: (evt: MessageEvent) => {
|
|
|
|
|
+ let event = JSON.parse(evt.data);
|
|
|
|
|
+ let object = event.Object;
|
|
|
|
|
+ object.metadata.kind = event.Kind;
|
|
|
|
|
|
|
|
- setControllers((oldControllers) => ({
|
|
|
|
|
- ...oldControllers,
|
|
|
|
|
- [chartKey]: chartControllers,
|
|
|
|
|
- }));
|
|
|
|
|
- };
|
|
|
|
|
-
|
|
|
|
|
- ws.onclose = () => {
|
|
|
|
|
- console.log("closing websocket");
|
|
|
|
|
|
|
+ setControllers((oldControllers) => ({
|
|
|
|
|
+ ...oldControllers,
|
|
|
|
|
+ [object.metadata.uid]: object,
|
|
|
|
|
+ }));
|
|
|
|
|
+ },
|
|
|
|
|
+ onclose: () => {
|
|
|
|
|
+ console.log("closing websocket");
|
|
|
|
|
+ },
|
|
|
|
|
+ onerror: (err: ErrorEvent) => {
|
|
|
|
|
+ console.log(err);
|
|
|
|
|
+ closeWebsocket(kind);
|
|
|
|
|
+ },
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
- ws.onerror = (err: ErrorEvent) => {
|
|
|
|
|
- console.log(err);
|
|
|
|
|
- ws.close();
|
|
|
|
|
- };
|
|
|
|
|
|
|
+ newWebsocket(kind, apiPath, wsConfig);
|
|
|
|
|
|
|
|
- return ws;
|
|
|
|
|
|
|
+ openWebsocket(kind);
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
const setControllerWebsockets = (controllers: any[]) => {
|
|
const setControllerWebsockets = (controllers: any[]) => {
|
|
|
- let websockets = controllers.map((kind: string) => {
|
|
|
|
|
|
|
+ controllers.map((kind: string) => {
|
|
|
return setupWebsocket(kind);
|
|
return setupWebsocket(kind);
|
|
|
});
|
|
});
|
|
|
- setWebsockets(websockets);
|
|
|
|
|
- };
|
|
|
|
|
-
|
|
|
|
|
- const getControllerForChart = async (chart: ChartType) => {
|
|
|
|
|
- try {
|
|
|
|
|
- const { currentCluster, currentProject } = context;
|
|
|
|
|
- const res = await api.getChartControllers(
|
|
|
|
|
- "<token>",
|
|
|
|
|
- {
|
|
|
|
|
- namespace: chart.namespace,
|
|
|
|
|
- cluster_id: currentCluster.id,
|
|
|
|
|
- storage: StorageType.Secret,
|
|
|
|
|
- },
|
|
|
|
|
- {
|
|
|
|
|
- id: currentProject.id,
|
|
|
|
|
- name: chart.name,
|
|
|
|
|
- revision: chart.version,
|
|
|
|
|
- }
|
|
|
|
|
- );
|
|
|
|
|
-
|
|
|
|
|
- let chartControllers = {} as Record<string, Record<string, any>>;
|
|
|
|
|
-
|
|
|
|
|
- res.data.forEach((c: any) => {
|
|
|
|
|
- c.metadata.kind = c.kind;
|
|
|
|
|
- chartControllers[c.metadata.uid] = c;
|
|
|
|
|
- });
|
|
|
|
|
-
|
|
|
|
|
- res.data.forEach(async (c: any) => {
|
|
|
|
|
- setChartLookupTable((oldChartLookupTable) => ({
|
|
|
|
|
- ...oldChartLookupTable,
|
|
|
|
|
- [c.metadata.uid]: `${chart.namespace}-${chart.name}`,
|
|
|
|
|
- }));
|
|
|
|
|
- setControllers((oldControllers) => ({
|
|
|
|
|
- ...oldControllers,
|
|
|
|
|
- [`${chart.namespace}-${chart.name}`]: chartControllers,
|
|
|
|
|
- }));
|
|
|
|
|
- });
|
|
|
|
|
- } catch (error) {
|
|
|
|
|
- context.setCurrentError(JSON.stringify(error));
|
|
|
|
|
- }
|
|
|
|
|
- };
|
|
|
|
|
-
|
|
|
|
|
- const getControllers = (charts: any[]) => {
|
|
|
|
|
- charts.forEach(async (chart: any) => {
|
|
|
|
|
- // don't retrieve controllers for chart that failed to even deploy.
|
|
|
|
|
- if (chart.info.status == "failed") return;
|
|
|
|
|
- await getControllerForChart(chart);
|
|
|
|
|
- });
|
|
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
// Setup basic websockets on start
|
|
// Setup basic websockets on start
|
|
@@ -207,18 +149,11 @@ const ChartList: React.FunctionComponent<PropsType> = ({
|
|
|
"daemonset",
|
|
"daemonset",
|
|
|
"replicaset",
|
|
"replicaset",
|
|
|
]);
|
|
]);
|
|
|
- }, []);
|
|
|
|
|
|
|
|
|
|
- // Close Websockets on unmount
|
|
|
|
|
- useEffect(() => {
|
|
|
|
|
return () => {
|
|
return () => {
|
|
|
- if (websockets.length) {
|
|
|
|
|
- websockets.forEach((ws) => {
|
|
|
|
|
- ws.close();
|
|
|
|
|
- });
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ closeAllWebsockets();
|
|
|
};
|
|
};
|
|
|
- }, [websockets]);
|
|
|
|
|
|
|
+ }, []);
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
useEffect(() => {
|
|
|
let isSubscribed = true;
|
|
let isSubscribed = true;
|
|
@@ -227,7 +162,7 @@ const ChartList: React.FunctionComponent<PropsType> = ({
|
|
|
updateCharts().then((charts) => {
|
|
updateCharts().then((charts) => {
|
|
|
if (isSubscribed) {
|
|
if (isSubscribed) {
|
|
|
setCharts(charts);
|
|
setCharts(charts);
|
|
|
- getControllers(charts);
|
|
|
|
|
|
|
+ setIsLoading(false);
|
|
|
}
|
|
}
|
|
|
});
|
|
});
|
|
|
}
|
|
}
|
|
@@ -262,10 +197,7 @@ const ChartList: React.FunctionComponent<PropsType> = ({
|
|
|
<Chart
|
|
<Chart
|
|
|
key={`${chart.namespace}-${chart.name}`}
|
|
key={`${chart.namespace}-${chart.name}`}
|
|
|
chart={chart}
|
|
chart={chart}
|
|
|
- controllers={
|
|
|
|
|
- controllers[`${chart.namespace}-${chart.name}`] ||
|
|
|
|
|
- ({} as Record<string, any>)
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ controllers={controllers || {}}
|
|
|
/>
|
|
/>
|
|
|
);
|
|
);
|
|
|
});
|
|
});
|