/
KurtosisClientContext.tsx
132 lines (117 loc) · 4.43 KB
/
KurtosisClientContext.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
import { Flex, Heading, Spinner } from "@chakra-ui/react";
import Cookies from "js-cookie";
import { assertDefined, isDefined, KurtosisAlert, stringifyError } from "kurtosis-ui-components";
import { createContext, PropsWithChildren, useContext, useEffect, useMemo, useState } from "react";
import { KURTOSIS_CLOUD_EM_PAGE, KURTOSIS_CLOUD_EM_URL } from "../constants";
import { AuthenticatedKurtosisClient } from "./AuthenticatedKurtosisClient";
import { KurtosisClient } from "./KurtosisClient";
import { LocalKurtosisClient } from "./LocalKurtosisClient";
type KurtosisClientContextState = {
client: KurtosisClient | null;
};
const KurtosisClientContext = createContext<KurtosisClientContextState>({ client: null });
export const KurtosisClientProvider = ({ children }: PropsWithChildren) => {
const [client, setClient] = useState<KurtosisClient>();
const [error, setError] = useState<string>();
const errorHandlingClient = useMemo(() => {
if (isDefined(client)) {
return new Proxy(client, {
get(target, prop: string | symbol) {
if (
prop === "getEnclaves" ||
prop === "getServices" ||
prop === "getStarlarkRun" ||
prop === "listFilesArtifactNamesAndUuids"
) {
return new Proxy(target[prop], {
apply: (target, thisArg, argumentsList) => {
const methodResult = Reflect.apply(target, thisArg, argumentsList) as ReturnType<typeof target>;
return methodResult.then((r) => {
if (r.isErr) {
console.error(r.error);
}
return r;
});
},
});
} else {
return Reflect.get(target, prop);
}
},
});
}
return undefined;
}, [client]);
useEffect(() => {
(async () => {
// If the pathname starts with /gateway` then we are trying to use an Authenticated client.
const path = window.location.pathname;
try {
setError(undefined);
let newClient: KurtosisClient | null = null;
if (path.startsWith("/gateway")) {
const pathConfigPattern = /\/gateway\/ips\/([^/]+)\/ports\/([^/]+)(\/|$)/;
const matches = path.match(pathConfigPattern);
if (!matches) {
throw Error(`Cannot configure an authenticated kurtosis client on this path: \`${path}\``);
}
const gatewayHost = matches[1];
const port = parseInt(matches[2]);
if (isNaN(port)) {
throw Error(`Port ${port} is not a number.`);
}
const jwtToken = Cookies.get("_kurtosis_jwt_token");
if (isDefined(jwtToken)) {
newClient = new AuthenticatedKurtosisClient(
`${gatewayHost}`,
jwtToken,
new URL(`${window.location.protocol}//${window.location.host}/${KURTOSIS_CLOUD_EM_PAGE}`),
new URL(`${window.location.protocol}//${window.location.host}${matches[0]}`),
);
} else {
window.location.href = KURTOSIS_CLOUD_EM_URL;
}
} else {
newClient = new LocalKurtosisClient();
}
if (isDefined(newClient)) {
const checkResp = await newClient.checkHealth();
if (checkResp.isErr) {
setError("Cannot reach the enclave manager backend - is the Enclave Manager API running and accessible?");
return;
}
setClient(newClient);
}
} catch (e: any) {
console.error(e);
setError(stringifyError(e));
}
})();
}, []);
if (errorHandlingClient) {
return (
<KurtosisClientContext.Provider value={{ client: errorHandlingClient }}>
{children}
</KurtosisClientContext.Provider>
);
} else {
return (
<Flex width="100%" direction="column" alignItems={"center"} gap={"1rem"} padding={"3rem"}>
{!isDefined(error) && (
<>
<Spinner size={"xl"} />
<Heading as={"h2"} fontSize={"2xl"}>
Connecting to enclave manager...
</Heading>
</>
)}
{isDefined(error) && <KurtosisAlert message={error} />}
</Flex>
);
}
};
export const useKurtosisClient = (): KurtosisClient => {
const { client } = useContext(KurtosisClientContext);
assertDefined(client, `useKurtosisClient used incorrectly - KurtosisClient is not currently available.`);
return client;
};