@replicated/portal-components 0.0.1 → 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/components/metadata/registry.json +109 -3
- package/components/metadata/registry.md +53 -3
- package/dist/actions/index.d.mts +590 -2
- package/dist/actions/index.d.ts +590 -2
- package/dist/actions/index.js +1931 -0
- package/dist/actions/index.js.map +1 -1
- package/dist/airgap-instances.d.mts +26 -0
- package/dist/airgap-instances.d.ts +26 -0
- package/dist/airgap-instances.js +354 -0
- package/dist/airgap-instances.js.map +1 -0
- package/dist/error-page.d.mts +14 -0
- package/dist/error-page.d.ts +14 -0
- package/dist/error-page.js +153 -0
- package/dist/error-page.js.map +1 -0
- package/dist/error.d.mts +15 -0
- package/dist/error.d.ts +15 -0
- package/dist/error.js +144 -0
- package/dist/error.js.map +1 -0
- package/dist/esm/actions/index.js +1892 -1
- package/dist/esm/actions/index.js.map +1 -1
- package/dist/esm/airgap-instances.js +352 -0
- package/dist/esm/airgap-instances.js.map +1 -0
- package/dist/esm/error-page.js +151 -0
- package/dist/esm/error-page.js.map +1 -0
- package/dist/esm/error.js +142 -0
- package/dist/esm/error.js.map +1 -0
- package/dist/esm/helm-install-wizard.js +1007 -0
- package/dist/esm/helm-install-wizard.js.map +1 -0
- package/dist/esm/index.js +2240 -82
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/install-actions.js +746 -0
- package/dist/esm/install-actions.js.map +1 -0
- package/dist/esm/install-card.js +115 -0
- package/dist/esm/install-card.js.map +1 -0
- package/dist/esm/install-targets.js +48 -0
- package/dist/esm/install-targets.js.map +1 -0
- package/dist/esm/instance-card.js +197 -0
- package/dist/esm/instance-card.js.map +1 -0
- package/dist/esm/join-team.js +218 -0
- package/dist/esm/join-team.js.map +1 -0
- package/dist/esm/license-card.js +131 -0
- package/dist/esm/license-card.js.map +1 -0
- package/dist/esm/license-details.js +667 -0
- package/dist/esm/license-details.js.map +1 -0
- package/dist/esm/linux-install-wizard.js +1083 -0
- package/dist/esm/linux-install-wizard.js.map +1 -0
- package/dist/esm/login.js +261 -0
- package/dist/esm/login.js.map +1 -0
- package/dist/esm/online-instance-list.js +287 -0
- package/dist/esm/online-instance-list.js.map +1 -0
- package/dist/esm/pending-installations.js +235 -0
- package/dist/esm/pending-installations.js.map +1 -0
- package/dist/esm/release-history-panel.js +100 -0
- package/dist/esm/release-history-panel.js.map +1 -0
- package/dist/esm/release-notes-card.js +23 -0
- package/dist/esm/release-notes-card.js.map +1 -0
- package/dist/esm/security-card.js +700 -0
- package/dist/esm/security-card.js.map +1 -0
- package/dist/esm/support-bundle-collection-card.js +170 -0
- package/dist/esm/support-bundle-collection-card.js.map +1 -0
- package/dist/esm/support-bundles-card.js +306 -0
- package/dist/esm/support-bundles-card.js.map +1 -0
- package/dist/esm/support-card.js +305 -0
- package/dist/esm/support-card.js.map +1 -0
- package/dist/esm/team-selection.js +117 -0
- package/dist/esm/team-selection.js.map +1 -0
- package/dist/esm/team-settings-card.js +78 -0
- package/dist/esm/team-settings-card.js.map +1 -0
- package/dist/esm/team-settings.js +136 -0
- package/dist/esm/team-settings.js.map +1 -0
- package/dist/esm/top-nav-user-menu.js +173 -0
- package/dist/esm/top-nav-user-menu.js.map +1 -0
- package/dist/esm/top-nav.js +398 -0
- package/dist/esm/top-nav.js.map +1 -0
- package/dist/esm/update-layout.js +405 -0
- package/dist/esm/update-layout.js.map +1 -0
- package/dist/esm/updates-card.js +85 -0
- package/dist/esm/updates-card.js.map +1 -0
- package/dist/esm/upload-support-bundle-modal.js +143 -0
- package/dist/esm/upload-support-bundle-modal.js.map +1 -0
- package/dist/esm/user-settings-card.js +21 -0
- package/dist/esm/user-settings-card.js.map +1 -0
- package/dist/esm/user-settings.js +368 -0
- package/dist/esm/user-settings.js.map +1 -0
- package/dist/esm/utils/index.js +170 -0
- package/dist/esm/utils/index.js.map +1 -0
- package/dist/helm-install-wizard.d.mts +38 -0
- package/dist/helm-install-wizard.d.ts +38 -0
- package/dist/helm-install-wizard.js +1011 -0
- package/dist/helm-install-wizard.js.map +1 -0
- package/dist/index.d.mts +11 -20
- package/dist/index.d.ts +11 -20
- package/dist/index.js +2266 -81
- package/dist/index.js.map +1 -1
- package/dist/install-B19AaKF_.d.mts +233 -0
- package/dist/install-Bi1qJ8Bu.d.ts +233 -0
- package/dist/install-actions.d.mts +141 -0
- package/dist/install-actions.d.ts +141 -0
- package/dist/install-actions.js +765 -0
- package/dist/install-actions.js.map +1 -0
- package/dist/install-card.d.mts +15 -0
- package/dist/install-card.d.ts +15 -0
- package/dist/install-card.js +117 -0
- package/dist/install-card.js.map +1 -0
- package/dist/install-targets.d.mts +19 -0
- package/dist/install-targets.d.ts +19 -0
- package/dist/install-targets.js +50 -0
- package/dist/install-targets.js.map +1 -0
- package/dist/instance-card.d.mts +22 -0
- package/dist/instance-card.d.ts +22 -0
- package/dist/instance-card.js +199 -0
- package/dist/instance-card.js.map +1 -0
- package/dist/join-team.d.mts +30 -0
- package/dist/join-team.d.ts +30 -0
- package/dist/join-team.js +220 -0
- package/dist/join-team.js.map +1 -0
- package/dist/license-card.d.mts +15 -0
- package/dist/license-card.d.ts +15 -0
- package/dist/license-card.js +133 -0
- package/dist/license-card.js.map +1 -0
- package/dist/license-details.d.mts +10 -0
- package/dist/license-details.d.ts +10 -0
- package/dist/license-details.js +669 -0
- package/dist/license-details.js.map +1 -0
- package/dist/linux-install-wizard.d.mts +66 -0
- package/dist/linux-install-wizard.d.ts +66 -0
- package/dist/linux-install-wizard.js +1093 -0
- package/dist/linux-install-wizard.js.map +1 -0
- package/dist/login.d.mts +37 -0
- package/dist/login.d.ts +37 -0
- package/dist/login.js +263 -0
- package/dist/login.js.map +1 -0
- package/dist/online-instance-list.d.mts +22 -0
- package/dist/online-instance-list.d.ts +22 -0
- package/dist/online-instance-list.js +289 -0
- package/dist/online-instance-list.js.map +1 -0
- package/dist/pending-installations.d.mts +15 -0
- package/dist/pending-installations.d.ts +15 -0
- package/dist/pending-installations.js +237 -0
- package/dist/pending-installations.js.map +1 -0
- package/dist/release-history-panel.d.mts +22 -0
- package/dist/release-history-panel.d.ts +22 -0
- package/dist/release-history-panel.js +102 -0
- package/dist/release-history-panel.js.map +1 -0
- package/dist/release-notes-card.d.mts +13 -0
- package/dist/release-notes-card.d.ts +13 -0
- package/dist/release-notes-card.js +25 -0
- package/dist/release-notes-card.js.map +1 -0
- package/dist/security-card.d.mts +73 -0
- package/dist/security-card.d.ts +73 -0
- package/dist/security-card.js +702 -0
- package/dist/security-card.js.map +1 -0
- package/dist/styles.css +1885 -191
- package/dist/support-bundle-collection-card.d.mts +20 -0
- package/dist/support-bundle-collection-card.d.ts +20 -0
- package/dist/support-bundle-collection-card.js +172 -0
- package/dist/support-bundle-collection-card.js.map +1 -0
- package/dist/support-bundles-card.d.mts +19 -0
- package/dist/support-bundles-card.d.ts +19 -0
- package/dist/support-bundles-card.js +308 -0
- package/dist/support-bundles-card.js.map +1 -0
- package/dist/support-card.d.mts +8 -0
- package/dist/support-card.d.ts +8 -0
- package/dist/support-card.js +307 -0
- package/dist/support-card.js.map +1 -0
- package/dist/team-selection.d.mts +23 -0
- package/dist/team-selection.d.ts +23 -0
- package/dist/team-selection.js +119 -0
- package/dist/team-selection.js.map +1 -0
- package/dist/team-settings-card-Dq1d9b5c.d.mts +14 -0
- package/dist/team-settings-card-Dq1d9b5c.d.ts +14 -0
- package/dist/team-settings-card.d.mts +2 -0
- package/dist/team-settings-card.d.ts +2 -0
- package/dist/team-settings-card.js +80 -0
- package/dist/team-settings-card.js.map +1 -0
- package/dist/team-settings.d.mts +25 -0
- package/dist/team-settings.d.ts +25 -0
- package/dist/team-settings.js +138 -0
- package/dist/team-settings.js.map +1 -0
- package/dist/top-nav-0mb1K_H0.d.mts +32 -0
- package/dist/top-nav-0mb1K_H0.d.ts +32 -0
- package/dist/top-nav-user-menu.d.mts +18 -0
- package/dist/top-nav-user-menu.d.ts +18 -0
- package/dist/top-nav-user-menu.js +175 -0
- package/dist/top-nav-user-menu.js.map +1 -0
- package/dist/top-nav.d.mts +3 -0
- package/dist/top-nav.d.ts +3 -0
- package/dist/top-nav.js +400 -0
- package/dist/top-nav.js.map +1 -0
- package/dist/update-layout.d.mts +12 -0
- package/dist/update-layout.d.ts +12 -0
- package/dist/update-layout.js +407 -0
- package/dist/update-layout.js.map +1 -0
- package/dist/updates-card-BbubBrVR.d.mts +18 -0
- package/dist/updates-card-BbubBrVR.d.ts +18 -0
- package/dist/updates-card.d.mts +2 -0
- package/dist/updates-card.d.ts +2 -0
- package/dist/updates-card.js +87 -0
- package/dist/updates-card.js.map +1 -0
- package/dist/upload-support-bundle-modal.d.mts +19 -0
- package/dist/upload-support-bundle-modal.d.ts +19 -0
- package/dist/upload-support-bundle-modal.js +145 -0
- package/dist/upload-support-bundle-modal.js.map +1 -0
- package/dist/user-settings-card.d.mts +8 -0
- package/dist/user-settings-card.d.ts +8 -0
- package/dist/user-settings-card.js +23 -0
- package/dist/user-settings-card.js.map +1 -0
- package/dist/user-settings.d.mts +47 -0
- package/dist/user-settings.d.ts +47 -0
- package/dist/user-settings.js +370 -0
- package/dist/user-settings.js.map +1 -0
- package/dist/utils/index.d.mts +70 -0
- package/dist/utils/index.d.ts +70 -0
- package/dist/utils/index.js +177 -0
- package/dist/utils/index.js.map +1 -0
- package/package.json +163 -3
|
@@ -0,0 +1,1007 @@
|
|
|
1
|
+
import { cache, useState, useRef, useEffect, useMemo, useCallback } from 'react';
|
|
2
|
+
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Enterprise Portal Components
|
|
6
|
+
* This file is generated by tsup. Do not edit manually.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
var navigateTo = (href) => {
|
|
10
|
+
if (typeof window !== "undefined") {
|
|
11
|
+
window.location.assign(href);
|
|
12
|
+
}
|
|
13
|
+
};
|
|
14
|
+
var HELM_INSTALL_SERVICE_ACCOUNT_KEY = "helm_install_service_account";
|
|
15
|
+
var HELM_INSTALL_OPTIONS_KEY = "helm_install_options";
|
|
16
|
+
var K8S_DISTRIBUTIONS = [
|
|
17
|
+
{ value: "vanilla", label: "Vanilla Kubernetes" },
|
|
18
|
+
{ value: "openshift", label: "OpenShift" },
|
|
19
|
+
{ value: "rancher", label: "Rancher" },
|
|
20
|
+
{ value: "aks", label: "Azure AKS" },
|
|
21
|
+
{ value: "eks", label: "Amazon EKS" },
|
|
22
|
+
{ value: "gke", label: "Google GKE" }
|
|
23
|
+
];
|
|
24
|
+
var copyToClipboard = async (text) => {
|
|
25
|
+
try {
|
|
26
|
+
await navigator.clipboard.writeText(text);
|
|
27
|
+
return true;
|
|
28
|
+
} catch {
|
|
29
|
+
return false;
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
var CodeBlock = ({
|
|
33
|
+
command,
|
|
34
|
+
className = ""
|
|
35
|
+
}) => {
|
|
36
|
+
const [copied, setCopied] = useState(false);
|
|
37
|
+
const handleCopy = async () => {
|
|
38
|
+
const success = await copyToClipboard(command);
|
|
39
|
+
if (success) {
|
|
40
|
+
setCopied(true);
|
|
41
|
+
setTimeout(() => setCopied(false), 2e3);
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
return /* @__PURE__ */ jsxs("div", { className: `group relative min-w-0 ${className}`, children: [
|
|
45
|
+
/* @__PURE__ */ jsx("pre", { className: "overflow-x-auto rounded-lg bg-gray-900 p-4 text-sm text-gray-100", children: /* @__PURE__ */ jsx("code", { className: "block", children: command }) }),
|
|
46
|
+
/* @__PURE__ */ jsx(
|
|
47
|
+
"button",
|
|
48
|
+
{
|
|
49
|
+
type: "button",
|
|
50
|
+
onClick: handleCopy,
|
|
51
|
+
className: "absolute right-2 top-2 rounded bg-gray-700 p-1.5 text-gray-300 opacity-0 transition hover:bg-gray-600 hover:text-white group-hover:opacity-100",
|
|
52
|
+
"aria-label": "Copy to clipboard",
|
|
53
|
+
children: copied ? /* @__PURE__ */ jsx("svg", { className: "h-4 w-4", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M5 13l4 4L19 7" }) }) : /* @__PURE__ */ jsx("svg", { className: "h-4 w-4", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z" }) })
|
|
54
|
+
}
|
|
55
|
+
)
|
|
56
|
+
] });
|
|
57
|
+
};
|
|
58
|
+
var StepIndicator = ({ step }) => /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-center gap-3", children: [
|
|
59
|
+
/* @__PURE__ */ jsx(
|
|
60
|
+
"div",
|
|
61
|
+
{
|
|
62
|
+
className: `flex h-10 w-10 items-center justify-center rounded-full border-2 ${step > 1 ? "border-gray-900 bg-gray-900 text-white" : "border-indigo-500"}`,
|
|
63
|
+
children: step > 1 ? /* @__PURE__ */ jsx(
|
|
64
|
+
"svg",
|
|
65
|
+
{
|
|
66
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
67
|
+
viewBox: "0 0 16 16",
|
|
68
|
+
className: "h-3.5 w-3.5",
|
|
69
|
+
fill: "none",
|
|
70
|
+
stroke: "currentColor",
|
|
71
|
+
strokeWidth: "2",
|
|
72
|
+
children: /* @__PURE__ */ jsx("path", { d: "m3.5 8 3 3 6-6" })
|
|
73
|
+
}
|
|
74
|
+
) : /* @__PURE__ */ jsx("span", { className: "h-2.5 w-2.5 rounded-full bg-indigo-500" })
|
|
75
|
+
}
|
|
76
|
+
),
|
|
77
|
+
/* @__PURE__ */ jsx("div", { className: `h-0.5 w-12 ${step > 1 ? "bg-gray-900" : "bg-gray-200"}` }),
|
|
78
|
+
/* @__PURE__ */ jsx(
|
|
79
|
+
"div",
|
|
80
|
+
{
|
|
81
|
+
className: `flex h-10 w-10 items-center justify-center rounded-full border-2 ${step === 2 ? "border-gray-900" : "border-gray-200"}`,
|
|
82
|
+
children: step === 2 ? /* @__PURE__ */ jsx("span", { className: "h-2.5 w-2.5 rounded-full bg-gray-900" }) : null
|
|
83
|
+
}
|
|
84
|
+
)
|
|
85
|
+
] });
|
|
86
|
+
var VersionDropdown = ({
|
|
87
|
+
releases,
|
|
88
|
+
selectedRelease,
|
|
89
|
+
onSelect,
|
|
90
|
+
isLoading,
|
|
91
|
+
isLoadingInstructions,
|
|
92
|
+
error
|
|
93
|
+
}) => {
|
|
94
|
+
if (isLoading) {
|
|
95
|
+
return /* @__PURE__ */ jsxs("div", { className: "ml-8 flex items-center gap-2 text-sm text-gray-500", children: [
|
|
96
|
+
/* @__PURE__ */ jsx("div", { className: "h-4 w-4 animate-spin rounded-full border-2 border-gray-300 border-t-indigo-500" }),
|
|
97
|
+
"Loading versions..."
|
|
98
|
+
] });
|
|
99
|
+
}
|
|
100
|
+
if (error) {
|
|
101
|
+
return /* @__PURE__ */ jsxs("div", { className: "ml-8 text-sm text-rose-600", children: [
|
|
102
|
+
"Failed to load versions: ",
|
|
103
|
+
error
|
|
104
|
+
] });
|
|
105
|
+
}
|
|
106
|
+
if (releases.length === 0) {
|
|
107
|
+
return /* @__PURE__ */ jsx("p", { className: "ml-8 text-sm text-gray-500", children: "There are no Helm charts in this release." });
|
|
108
|
+
}
|
|
109
|
+
return /* @__PURE__ */ jsxs("div", { className: "ml-8 space-y-2", children: [
|
|
110
|
+
/* @__PURE__ */ jsxs("label", { className: "flex items-center gap-2 text-sm text-gray-600", children: [
|
|
111
|
+
"App Version",
|
|
112
|
+
isLoadingInstructions && /* @__PURE__ */ jsx("span", { className: "inline-block h-4 w-4 animate-spin rounded-full border-2 border-gray-300 border-t-indigo-500" })
|
|
113
|
+
] }),
|
|
114
|
+
/* @__PURE__ */ jsx(
|
|
115
|
+
"select",
|
|
116
|
+
{
|
|
117
|
+
value: selectedRelease?.channelSequence ?? "",
|
|
118
|
+
onChange: (e) => {
|
|
119
|
+
const sequence = parseInt(e.target.value, 10);
|
|
120
|
+
const release = releases.find((r) => r.channelSequence === sequence);
|
|
121
|
+
if (release) {
|
|
122
|
+
onSelect(release);
|
|
123
|
+
}
|
|
124
|
+
},
|
|
125
|
+
className: "portal-select w-full",
|
|
126
|
+
children: releases.map((release) => /* @__PURE__ */ jsxs("option", { value: release.channelSequence, children: [
|
|
127
|
+
release.versionLabel || `Sequence ${release.channelSequence}`,
|
|
128
|
+
release.channelName ? ` (${release.channelName})` : ""
|
|
129
|
+
] }, release.channelSequence))
|
|
130
|
+
}
|
|
131
|
+
)
|
|
132
|
+
] });
|
|
133
|
+
};
|
|
134
|
+
var CheckIcon = () => /* @__PURE__ */ jsx("svg", { className: "h-4 w-4", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", strokeWidth: 2.5, children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M5 13l4 4L19 7" }) });
|
|
135
|
+
var parsePartialRegistryCommands = (commands) => {
|
|
136
|
+
const pullCommands = [];
|
|
137
|
+
const filesToTransfer = [];
|
|
138
|
+
const installCommands = [];
|
|
139
|
+
let section = "pull";
|
|
140
|
+
for (const cmd of commands) {
|
|
141
|
+
if (cmd.startsWith("# Transfer the following files")) {
|
|
142
|
+
section = "files";
|
|
143
|
+
continue;
|
|
144
|
+
}
|
|
145
|
+
if (cmd.startsWith("# - ")) {
|
|
146
|
+
filesToTransfer.push(cmd.replace("# - ", ""));
|
|
147
|
+
continue;
|
|
148
|
+
}
|
|
149
|
+
if (cmd.startsWith("helm install") || cmd.startsWith("helm upgrade")) {
|
|
150
|
+
section = "install";
|
|
151
|
+
installCommands.push(cmd);
|
|
152
|
+
continue;
|
|
153
|
+
}
|
|
154
|
+
if (section === "pull" && cmd.startsWith("helm pull")) {
|
|
155
|
+
pullCommands.push(cmd);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
return { pullCommands, filesToTransfer, installCommands };
|
|
159
|
+
};
|
|
160
|
+
var InstallationInstructions = ({
|
|
161
|
+
instructions,
|
|
162
|
+
isLoading,
|
|
163
|
+
completedSteps = {},
|
|
164
|
+
registryAccess = "online",
|
|
165
|
+
networkAvailability = "online"
|
|
166
|
+
}) => {
|
|
167
|
+
if (isLoading && !instructions?.steps?.length) {
|
|
168
|
+
return /* @__PURE__ */ jsx("div", { className: "space-y-4", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 text-sm text-gray-500", children: [
|
|
169
|
+
/* @__PURE__ */ jsx("div", { className: "h-4 w-4 animate-spin rounded-full border-2 border-gray-300 border-t-indigo-500" }),
|
|
170
|
+
"Loading instructions..."
|
|
171
|
+
] }) });
|
|
172
|
+
}
|
|
173
|
+
if (!instructions?.steps?.length) {
|
|
174
|
+
return null;
|
|
175
|
+
}
|
|
176
|
+
const completableStepNames = ["export_credentials", "install_chart"];
|
|
177
|
+
const stepOffset = networkAvailability === "airgap" ? 3 : 2;
|
|
178
|
+
return /* @__PURE__ */ jsx("div", { className: `min-w-0 space-y-4 transition-opacity duration-150 ${isLoading ? "opacity-60" : ""}`, children: /* @__PURE__ */ jsx("ol", { className: "min-w-0 space-y-6 text-sm text-gray-700", children: instructions.steps.map((step, index) => {
|
|
179
|
+
const canComplete = step.maybe_completed || completableStepNames.includes(step.step_name);
|
|
180
|
+
const isCompleted = canComplete && completedSteps[step.step_name];
|
|
181
|
+
const isPartialInstallChart = registryAccess === "partial" && step.step_name === "install_chart";
|
|
182
|
+
return /* @__PURE__ */ jsxs("li", { className: "space-y-2", children: [
|
|
183
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
184
|
+
/* @__PURE__ */ jsx("span", { className: "flex h-6 w-6 items-center justify-center rounded-full bg-indigo-100 font-semibold text-indigo-500", children: index + stepOffset }),
|
|
185
|
+
/* @__PURE__ */ jsx("span", { className: "font-medium text-gray-900", children: step.title }),
|
|
186
|
+
canComplete && /* @__PURE__ */ jsx(
|
|
187
|
+
"span",
|
|
188
|
+
{
|
|
189
|
+
className: `flex h-5 w-5 items-center justify-center rounded-full ${isCompleted ? "bg-green-500 text-white" : "bg-gray-200 text-gray-400"}`,
|
|
190
|
+
children: /* @__PURE__ */ jsx(CheckIcon, {})
|
|
191
|
+
}
|
|
192
|
+
),
|
|
193
|
+
isCompleted && /* @__PURE__ */ jsx("span", { className: "text-xs text-green-600", children: "Completed" })
|
|
194
|
+
] }),
|
|
195
|
+
step.description && /* @__PURE__ */ jsx("p", { className: "ml-8 text-gray-500", children: step.description }),
|
|
196
|
+
isPartialInstallChart && step.commands.length > 0 ? (() => {
|
|
197
|
+
const { pullCommands, filesToTransfer, installCommands } = parsePartialRegistryCommands(step.commands);
|
|
198
|
+
return /* @__PURE__ */ jsxs("div", { className: "ml-8 space-y-4", children: [
|
|
199
|
+
pullCommands.length > 0 && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
200
|
+
/* @__PURE__ */ jsx("p", { className: "text-gray-600", children: "On workstation with registry access:" }),
|
|
201
|
+
/* @__PURE__ */ jsx(CodeBlock, { command: pullCommands.join("\n") })
|
|
202
|
+
] }),
|
|
203
|
+
filesToTransfer.length > 0 && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
204
|
+
/* @__PURE__ */ jsx("p", { className: "text-gray-600", children: "Transfer the following files to machine with cluster access:" }),
|
|
205
|
+
/* @__PURE__ */ jsx(CodeBlock, { command: filesToTransfer.join("\n") })
|
|
206
|
+
] }),
|
|
207
|
+
installCommands.length > 0 && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
208
|
+
/* @__PURE__ */ jsx("p", { className: "text-gray-600", children: "On machine with cluster access:" }),
|
|
209
|
+
/* @__PURE__ */ jsx(CodeBlock, { command: installCommands.join("\n") })
|
|
210
|
+
] })
|
|
211
|
+
] });
|
|
212
|
+
})() : step.commands.length > 0 ? /* @__PURE__ */ jsx(CodeBlock, { command: step.commands.join("\n"), className: "ml-8 mt-2" }) : null
|
|
213
|
+
] }, step.step_number);
|
|
214
|
+
}) }) });
|
|
215
|
+
};
|
|
216
|
+
var HelmInstallWizard = ({
|
|
217
|
+
token,
|
|
218
|
+
createServiceAccountAction,
|
|
219
|
+
fetchChannelReleasesAction,
|
|
220
|
+
createInstallOptionsAction,
|
|
221
|
+
getInstallOptionsAction,
|
|
222
|
+
updateInstallOptionsAction,
|
|
223
|
+
onStepChange,
|
|
224
|
+
onInstallOptionsIdChange,
|
|
225
|
+
initialStep,
|
|
226
|
+
initialInstallOptionsId,
|
|
227
|
+
initialInstallOptionsData,
|
|
228
|
+
initialChannelReleases
|
|
229
|
+
}) => {
|
|
230
|
+
const [step, setStep] = useState(initialStep ?? 1);
|
|
231
|
+
const [instanceName, setInstanceName] = useState(initialInstallOptionsData?.instance_name ?? "");
|
|
232
|
+
const [kubernetesDistribution, setKubernetesDistribution] = useState(
|
|
233
|
+
initialInstallOptionsData?.kubernetes_distribution ?? "vanilla"
|
|
234
|
+
);
|
|
235
|
+
const [networkAvailability, setNetworkAvailability] = useState(
|
|
236
|
+
initialInstallOptionsData?.network_availability ?? "online"
|
|
237
|
+
);
|
|
238
|
+
const [registryAccess, setRegistryAccess] = useState(
|
|
239
|
+
initialInstallOptionsData?.registry_availability ?? "online"
|
|
240
|
+
);
|
|
241
|
+
const [showErrors, setShowErrors] = useState(false);
|
|
242
|
+
const [isCreatingServiceAccount, setIsCreatingServiceAccount] = useState(false);
|
|
243
|
+
const [apiError, setApiError] = useState(null);
|
|
244
|
+
const [installOptionsId, setInstallOptionsId] = useState(initialInstallOptionsId ?? null);
|
|
245
|
+
const [serviceAccountId, setServiceAccountId] = useState(initialInstallOptionsData?.service_account_id ?? null);
|
|
246
|
+
const [originalInstanceName, setOriginalInstanceName] = useState(initialInstallOptionsData?.instance_name ?? null);
|
|
247
|
+
const [releases, setReleases] = useState(initialChannelReleases ?? []);
|
|
248
|
+
const [selectedRelease, setSelectedRelease] = useState(() => {
|
|
249
|
+
if (initialInstallOptionsData?.channel_id && initialInstallOptionsData?.channel_release_sequence && initialChannelReleases) {
|
|
250
|
+
return initialChannelReleases.find(
|
|
251
|
+
(r) => r.channelId === initialInstallOptionsData.channel_id && r.channelSequence === initialInstallOptionsData.channel_release_sequence
|
|
252
|
+
) ?? null;
|
|
253
|
+
}
|
|
254
|
+
return null;
|
|
255
|
+
});
|
|
256
|
+
const [isLoadingReleases, setIsLoadingReleases] = useState(false);
|
|
257
|
+
const [releasesError, setReleasesError] = useState(null);
|
|
258
|
+
const [instructions, setInstructions] = useState(initialInstallOptionsData?.instructions ?? null);
|
|
259
|
+
const [isLoadingInstructions, setIsLoadingInstructions] = useState(false);
|
|
260
|
+
const [inputRegistryHostname, setInputRegistryHostname] = useState("");
|
|
261
|
+
const [privateRegistryHostname, setPrivateRegistryHostname] = useState("");
|
|
262
|
+
const registryDebounceRef = useRef(null);
|
|
263
|
+
const [completedSteps, setCompletedSteps] = useState({});
|
|
264
|
+
const hasInitializedFromProps = useRef(!!initialInstallOptionsData);
|
|
265
|
+
useEffect(() => {
|
|
266
|
+
if (hasInitializedFromProps.current || !initialInstallOptionsData) {
|
|
267
|
+
return;
|
|
268
|
+
}
|
|
269
|
+
hasInitializedFromProps.current = true;
|
|
270
|
+
if (initialInstallOptionsData.instance_name) {
|
|
271
|
+
setInstanceName(initialInstallOptionsData.instance_name);
|
|
272
|
+
setOriginalInstanceName(initialInstallOptionsData.instance_name);
|
|
273
|
+
}
|
|
274
|
+
if (initialInstallOptionsData.kubernetes_distribution) {
|
|
275
|
+
setKubernetesDistribution(initialInstallOptionsData.kubernetes_distribution);
|
|
276
|
+
}
|
|
277
|
+
if (initialInstallOptionsData.network_availability) {
|
|
278
|
+
setNetworkAvailability(initialInstallOptionsData.network_availability);
|
|
279
|
+
}
|
|
280
|
+
if (initialInstallOptionsData.registry_availability) {
|
|
281
|
+
setRegistryAccess(initialInstallOptionsData.registry_availability);
|
|
282
|
+
}
|
|
283
|
+
if (initialInstallOptionsData.service_account_id) {
|
|
284
|
+
setServiceAccountId(initialInstallOptionsData.service_account_id);
|
|
285
|
+
}
|
|
286
|
+
if (initialInstallOptionsData.instructions) {
|
|
287
|
+
setInstructions(initialInstallOptionsData.instructions);
|
|
288
|
+
}
|
|
289
|
+
}, [initialInstallOptionsData]);
|
|
290
|
+
const hasLoadedReleases = useRef(!!initialChannelReleases?.length);
|
|
291
|
+
const hasResumedInstallation = useRef(!!initialInstallOptionsData);
|
|
292
|
+
const helmReleases = useMemo(() => {
|
|
293
|
+
return releases.filter((r) => r.installationTypes?.helm);
|
|
294
|
+
}, [releases]);
|
|
295
|
+
const prevInitialStepRef = useRef(initialStep);
|
|
296
|
+
useEffect(() => {
|
|
297
|
+
if (initialStep !== void 0 && initialStep !== prevInitialStepRef.current) {
|
|
298
|
+
setStep(initialStep);
|
|
299
|
+
}
|
|
300
|
+
prevInitialStepRef.current = initialStep;
|
|
301
|
+
}, [initialStep]);
|
|
302
|
+
useEffect(() => {
|
|
303
|
+
onStepChange?.(step);
|
|
304
|
+
}, [step, onStepChange]);
|
|
305
|
+
const prevInstallOptionsIdRef = useRef(installOptionsId);
|
|
306
|
+
useEffect(() => {
|
|
307
|
+
if (installOptionsId !== prevInstallOptionsIdRef.current) {
|
|
308
|
+
prevInstallOptionsIdRef.current = installOptionsId;
|
|
309
|
+
onInstallOptionsIdChange?.(installOptionsId);
|
|
310
|
+
}
|
|
311
|
+
}, [installOptionsId, onInstallOptionsIdChange]);
|
|
312
|
+
useEffect(() => {
|
|
313
|
+
if (step !== 2 || !fetchChannelReleasesAction || hasLoadedReleases.current) {
|
|
314
|
+
return;
|
|
315
|
+
}
|
|
316
|
+
const loadReleases = async () => {
|
|
317
|
+
setIsLoadingReleases(true);
|
|
318
|
+
setReleasesError(null);
|
|
319
|
+
try {
|
|
320
|
+
const result = await fetchChannelReleasesAction(token);
|
|
321
|
+
setReleases(result.channelReleases || []);
|
|
322
|
+
hasLoadedReleases.current = true;
|
|
323
|
+
const helmReleasesFiltered = (result.channelReleases || []).filter(
|
|
324
|
+
(r) => r.installationTypes?.helm
|
|
325
|
+
);
|
|
326
|
+
const firstRelease = helmReleasesFiltered[0];
|
|
327
|
+
if (firstRelease && !selectedRelease) {
|
|
328
|
+
setSelectedRelease(firstRelease);
|
|
329
|
+
}
|
|
330
|
+
} catch (error) {
|
|
331
|
+
console.error("[helm-install-wizard] Failed to load releases", error);
|
|
332
|
+
setReleasesError(error instanceof Error ? error.message : "Failed to load releases");
|
|
333
|
+
} finally {
|
|
334
|
+
setIsLoadingReleases(false);
|
|
335
|
+
}
|
|
336
|
+
};
|
|
337
|
+
loadReleases();
|
|
338
|
+
}, [step, token, fetchChannelReleasesAction, selectedRelease]);
|
|
339
|
+
const hasAutoSelectedRelease = useRef(false);
|
|
340
|
+
useEffect(() => {
|
|
341
|
+
if (hasAutoSelectedRelease.current || selectedRelease) {
|
|
342
|
+
return;
|
|
343
|
+
}
|
|
344
|
+
const firstRelease = helmReleases[0];
|
|
345
|
+
if (step === 2 && firstRelease) {
|
|
346
|
+
setSelectedRelease(firstRelease);
|
|
347
|
+
hasAutoSelectedRelease.current = true;
|
|
348
|
+
}
|
|
349
|
+
}, [step, helmReleases, selectedRelease]);
|
|
350
|
+
const lastReleaseUpdateRef = useRef({
|
|
351
|
+
channelId: initialInstallOptionsData?.channel_id,
|
|
352
|
+
sequence: initialInstallOptionsData?.channel_release_sequence
|
|
353
|
+
});
|
|
354
|
+
useEffect(() => {
|
|
355
|
+
if (!selectedRelease || !installOptionsId || !updateInstallOptionsAction) {
|
|
356
|
+
return;
|
|
357
|
+
}
|
|
358
|
+
const channelId = selectedRelease.channelId;
|
|
359
|
+
const sequence = selectedRelease.channelSequence;
|
|
360
|
+
if (lastReleaseUpdateRef.current.channelId === channelId && lastReleaseUpdateRef.current.sequence === sequence) {
|
|
361
|
+
return;
|
|
362
|
+
}
|
|
363
|
+
const updateOptions = async () => {
|
|
364
|
+
setIsLoadingInstructions(true);
|
|
365
|
+
try {
|
|
366
|
+
const result = await updateInstallOptionsAction({
|
|
367
|
+
token,
|
|
368
|
+
installOptionsId,
|
|
369
|
+
channelId,
|
|
370
|
+
channelReleaseSequence: sequence,
|
|
371
|
+
networkAvailability,
|
|
372
|
+
registryAvailability: registryAccess,
|
|
373
|
+
includeInstructions: true,
|
|
374
|
+
privateRegistryHostname: privateRegistryHostname || void 0
|
|
375
|
+
});
|
|
376
|
+
lastReleaseUpdateRef.current = { channelId, sequence };
|
|
377
|
+
if (result.instructions) {
|
|
378
|
+
setInstructions(result.instructions);
|
|
379
|
+
}
|
|
380
|
+
} catch (error) {
|
|
381
|
+
console.error("[helm-install-wizard] Failed to update install options", error);
|
|
382
|
+
setApiError(error instanceof Error ? error.message : "Failed to update install options");
|
|
383
|
+
} finally {
|
|
384
|
+
setIsLoadingInstructions(false);
|
|
385
|
+
}
|
|
386
|
+
};
|
|
387
|
+
updateOptions();
|
|
388
|
+
}, [selectedRelease, installOptionsId, token, updateInstallOptionsAction, networkAvailability, registryAccess, privateRegistryHostname]);
|
|
389
|
+
const lastPrivateRegistryRef = useRef("");
|
|
390
|
+
useEffect(() => {
|
|
391
|
+
if (networkAvailability !== "airgap" || !installOptionsId || !getInstallOptionsAction) {
|
|
392
|
+
return;
|
|
393
|
+
}
|
|
394
|
+
const currentValue = privateRegistryHostname || "";
|
|
395
|
+
if (lastPrivateRegistryRef.current === currentValue) {
|
|
396
|
+
return;
|
|
397
|
+
}
|
|
398
|
+
lastPrivateRegistryRef.current = currentValue;
|
|
399
|
+
const refreshInstructions = async () => {
|
|
400
|
+
setIsLoadingInstructions(true);
|
|
401
|
+
try {
|
|
402
|
+
const result = await getInstallOptionsAction({
|
|
403
|
+
token,
|
|
404
|
+
installOptionsId,
|
|
405
|
+
includeInstructions: true,
|
|
406
|
+
privateRegistryHostname: currentValue || void 0
|
|
407
|
+
});
|
|
408
|
+
if (result.instructions) {
|
|
409
|
+
setInstructions(result.instructions);
|
|
410
|
+
}
|
|
411
|
+
} catch (error) {
|
|
412
|
+
console.error("[helm-install-wizard] Failed to refresh instructions", error);
|
|
413
|
+
} finally {
|
|
414
|
+
setIsLoadingInstructions(false);
|
|
415
|
+
}
|
|
416
|
+
};
|
|
417
|
+
refreshInstructions();
|
|
418
|
+
}, [privateRegistryHostname, networkAvailability, installOptionsId, token, getInstallOptionsAction]);
|
|
419
|
+
useEffect(() => {
|
|
420
|
+
if (hasResumedInstallation.current) {
|
|
421
|
+
return;
|
|
422
|
+
}
|
|
423
|
+
if (!initialInstallOptionsId || !getInstallOptionsAction || step !== 2) {
|
|
424
|
+
return;
|
|
425
|
+
}
|
|
426
|
+
hasResumedInstallation.current = true;
|
|
427
|
+
const resumeInstallation = async () => {
|
|
428
|
+
setIsLoadingInstructions(true);
|
|
429
|
+
try {
|
|
430
|
+
const result = await getInstallOptionsAction({
|
|
431
|
+
token,
|
|
432
|
+
installOptionsId: initialInstallOptionsId,
|
|
433
|
+
includeInstructions: true
|
|
434
|
+
});
|
|
435
|
+
if (result.instance_name) {
|
|
436
|
+
setInstanceName(result.instance_name);
|
|
437
|
+
}
|
|
438
|
+
if (result.service_account_id) {
|
|
439
|
+
setServiceAccountId(result.service_account_id);
|
|
440
|
+
}
|
|
441
|
+
if (result.instructions) {
|
|
442
|
+
setInstructions(result.instructions);
|
|
443
|
+
}
|
|
444
|
+
if (result.channel_id && result.channel_release_sequence) {
|
|
445
|
+
const matchingRelease = releases.find(
|
|
446
|
+
(r) => r.channelId === result.channel_id && r.channelSequence === result.channel_release_sequence
|
|
447
|
+
);
|
|
448
|
+
if (matchingRelease) {
|
|
449
|
+
setSelectedRelease(matchingRelease);
|
|
450
|
+
lastReleaseUpdateRef.current = {
|
|
451
|
+
channelId: result.channel_id,
|
|
452
|
+
sequence: result.channel_release_sequence
|
|
453
|
+
};
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
} catch (error) {
|
|
457
|
+
console.error("[helm-install-wizard] Failed to resume installation", error);
|
|
458
|
+
setApiError(error instanceof Error ? error.message : "Failed to resume installation");
|
|
459
|
+
} finally {
|
|
460
|
+
setIsLoadingInstructions(false);
|
|
461
|
+
}
|
|
462
|
+
};
|
|
463
|
+
resumeInstallation();
|
|
464
|
+
}, [initialInstallOptionsId, getInstallOptionsAction, step, token, releases]);
|
|
465
|
+
useEffect(() => {
|
|
466
|
+
if (process.env.NODE_ENV === "development") {
|
|
467
|
+
return;
|
|
468
|
+
}
|
|
469
|
+
if (step !== 2 || !installOptionsId || !getInstallOptionsAction) {
|
|
470
|
+
return;
|
|
471
|
+
}
|
|
472
|
+
if (completedSteps["export_credentials"] && completedSteps["install_chart"]) {
|
|
473
|
+
return;
|
|
474
|
+
}
|
|
475
|
+
const pollInterval = setInterval(async () => {
|
|
476
|
+
try {
|
|
477
|
+
const result = await getInstallOptionsAction({
|
|
478
|
+
token,
|
|
479
|
+
installOptionsId,
|
|
480
|
+
includeInstructions: false
|
|
481
|
+
// We don't need instructions for status polling
|
|
482
|
+
});
|
|
483
|
+
const newCompletedSteps = {};
|
|
484
|
+
if (result.registry_authenticated_at) {
|
|
485
|
+
newCompletedSteps["export_credentials"] = true;
|
|
486
|
+
}
|
|
487
|
+
if (result.images_pulled_at) {
|
|
488
|
+
newCompletedSteps["install_chart"] = true;
|
|
489
|
+
}
|
|
490
|
+
if (newCompletedSteps["export_credentials"] !== completedSteps["export_credentials"] || newCompletedSteps["install_chart"] !== completedSteps["install_chart"]) {
|
|
491
|
+
setCompletedSteps((prev) => ({ ...prev, ...newCompletedSteps }));
|
|
492
|
+
}
|
|
493
|
+
if (newCompletedSteps["export_credentials"] && newCompletedSteps["install_chart"]) {
|
|
494
|
+
clearInterval(pollInterval);
|
|
495
|
+
}
|
|
496
|
+
} catch {
|
|
497
|
+
}
|
|
498
|
+
}, 2e3);
|
|
499
|
+
return () => clearInterval(pollInterval);
|
|
500
|
+
}, [step, installOptionsId, getInstallOptionsAction, token, completedSteps]);
|
|
501
|
+
const handleContinue = async () => {
|
|
502
|
+
if (!instanceName.trim()) {
|
|
503
|
+
setShowErrors(true);
|
|
504
|
+
return;
|
|
505
|
+
}
|
|
506
|
+
if (!token) {
|
|
507
|
+
setApiError("Configuration error: authentication token is required");
|
|
508
|
+
console.error("[helm-install-wizard] token prop is required but was not provided");
|
|
509
|
+
return;
|
|
510
|
+
}
|
|
511
|
+
setShowErrors(false);
|
|
512
|
+
setApiError(null);
|
|
513
|
+
setIsCreatingServiceAccount(true);
|
|
514
|
+
try {
|
|
515
|
+
const trimmedInstanceName = instanceName.trim();
|
|
516
|
+
if (serviceAccountId && originalInstanceName === trimmedInstanceName && installOptionsId && updateInstallOptionsAction) {
|
|
517
|
+
const firstRelease = helmReleases[0];
|
|
518
|
+
if (networkAvailability !== "airgap") {
|
|
519
|
+
setInputRegistryHostname("");
|
|
520
|
+
setPrivateRegistryHostname("");
|
|
521
|
+
lastPrivateRegistryRef.current = "";
|
|
522
|
+
}
|
|
523
|
+
setInstructions(null);
|
|
524
|
+
await updateInstallOptionsAction({
|
|
525
|
+
token,
|
|
526
|
+
installOptionsId,
|
|
527
|
+
installType: "helm",
|
|
528
|
+
channelId: firstRelease?.channelId,
|
|
529
|
+
channelReleaseSequence: firstRelease?.channelSequence,
|
|
530
|
+
networkAvailability,
|
|
531
|
+
registryAvailability: registryAccess,
|
|
532
|
+
kubernetesDistribution,
|
|
533
|
+
isMultiNode: true,
|
|
534
|
+
serviceAccountId,
|
|
535
|
+
includeInstructions: false
|
|
536
|
+
// Don't need instructions from PATCH
|
|
537
|
+
});
|
|
538
|
+
if (getInstallOptionsAction) {
|
|
539
|
+
const freshData = await getInstallOptionsAction({
|
|
540
|
+
token,
|
|
541
|
+
installOptionsId,
|
|
542
|
+
includeInstructions: true
|
|
543
|
+
});
|
|
544
|
+
setInstructions(freshData.instructions ?? null);
|
|
545
|
+
}
|
|
546
|
+
if (firstRelease) {
|
|
547
|
+
setSelectedRelease(firstRelease);
|
|
548
|
+
lastReleaseUpdateRef.current = {
|
|
549
|
+
channelId: firstRelease.channelId,
|
|
550
|
+
sequence: firstRelease.channelSequence
|
|
551
|
+
};
|
|
552
|
+
}
|
|
553
|
+
console.debug("[helm-install-wizard] Transitioning to step 2 (reused service account)");
|
|
554
|
+
setStep(2);
|
|
555
|
+
onInstallOptionsIdChange?.(installOptionsId);
|
|
556
|
+
return;
|
|
557
|
+
}
|
|
558
|
+
if (typeof window !== "undefined" && window.sessionStorage) {
|
|
559
|
+
window.sessionStorage.removeItem(HELM_INSTALL_SERVICE_ACCOUNT_KEY);
|
|
560
|
+
window.sessionStorage.removeItem(HELM_INSTALL_OPTIONS_KEY);
|
|
561
|
+
}
|
|
562
|
+
const saData = await createServiceAccountAction(trimmedInstanceName, token);
|
|
563
|
+
if (typeof window !== "undefined" && window.sessionStorage) {
|
|
564
|
+
window.sessionStorage.setItem(HELM_INSTALL_SERVICE_ACCOUNT_KEY, JSON.stringify(saData));
|
|
565
|
+
}
|
|
566
|
+
setServiceAccountId(saData.service_account.id);
|
|
567
|
+
setOriginalInstanceName(trimmedInstanceName);
|
|
568
|
+
if (createInstallOptionsAction) {
|
|
569
|
+
console.debug("[helm-install-wizard] Creating install options...");
|
|
570
|
+
const firstRelease = helmReleases[0];
|
|
571
|
+
const installOptionsResult = await createInstallOptionsAction({
|
|
572
|
+
token,
|
|
573
|
+
installType: "helm",
|
|
574
|
+
instanceName: trimmedInstanceName,
|
|
575
|
+
serviceAccountId: saData.service_account.id,
|
|
576
|
+
networkAvailability,
|
|
577
|
+
registryAvailability: registryAccess,
|
|
578
|
+
kubernetesDistribution,
|
|
579
|
+
isMultiNode: true,
|
|
580
|
+
// Helm installations are always multi-node
|
|
581
|
+
channelId: firstRelease?.channelId,
|
|
582
|
+
channelReleaseSequence: firstRelease?.channelSequence
|
|
583
|
+
});
|
|
584
|
+
if (firstRelease) {
|
|
585
|
+
setSelectedRelease(firstRelease);
|
|
586
|
+
lastReleaseUpdateRef.current = {
|
|
587
|
+
channelId: firstRelease.channelId,
|
|
588
|
+
sequence: firstRelease.channelSequence
|
|
589
|
+
};
|
|
590
|
+
}
|
|
591
|
+
const optionsId = installOptionsResult.install_options?.id ?? installOptionsResult.id;
|
|
592
|
+
if (!optionsId) {
|
|
593
|
+
throw new Error("Install options response did not contain an ID");
|
|
594
|
+
}
|
|
595
|
+
setInstallOptionsId(optionsId);
|
|
596
|
+
if (typeof window !== "undefined" && window.sessionStorage) {
|
|
597
|
+
window.sessionStorage.setItem(HELM_INSTALL_OPTIONS_KEY, JSON.stringify(installOptionsResult));
|
|
598
|
+
}
|
|
599
|
+
if (installOptionsResult.instructions) {
|
|
600
|
+
setInstructions(installOptionsResult.instructions);
|
|
601
|
+
}
|
|
602
|
+
onInstallOptionsIdChange?.(optionsId);
|
|
603
|
+
}
|
|
604
|
+
console.debug("[helm-install-wizard] Transitioning to step 2");
|
|
605
|
+
setStep(2);
|
|
606
|
+
onStepChange?.(2);
|
|
607
|
+
} catch (error) {
|
|
608
|
+
console.error("[helm-install-wizard] Failed to continue", error);
|
|
609
|
+
const errorMessage = error instanceof Error ? error.message : "Failed to continue";
|
|
610
|
+
if (errorMessage.toLowerCase().includes("already exists")) {
|
|
611
|
+
setApiError("Instance name must be unique. Please choose a different name.");
|
|
612
|
+
} else {
|
|
613
|
+
setApiError(errorMessage);
|
|
614
|
+
}
|
|
615
|
+
} finally {
|
|
616
|
+
setIsCreatingServiceAccount(false);
|
|
617
|
+
}
|
|
618
|
+
};
|
|
619
|
+
const handleBack = () => {
|
|
620
|
+
setApiError(null);
|
|
621
|
+
setShowErrors(false);
|
|
622
|
+
setStep(1);
|
|
623
|
+
onStepChange?.(1);
|
|
624
|
+
};
|
|
625
|
+
const handleFinish = useCallback(async () => {
|
|
626
|
+
navigateTo("/update");
|
|
627
|
+
}, []);
|
|
628
|
+
const handleReleaseSelect = useCallback((release) => {
|
|
629
|
+
setSelectedRelease(release);
|
|
630
|
+
}, []);
|
|
631
|
+
const handlePrivateRegistryHostnameChange = useCallback((e) => {
|
|
632
|
+
const value = e.target.value;
|
|
633
|
+
setInputRegistryHostname(value);
|
|
634
|
+
if (registryDebounceRef.current) {
|
|
635
|
+
clearTimeout(registryDebounceRef.current);
|
|
636
|
+
}
|
|
637
|
+
registryDebounceRef.current = setTimeout(() => {
|
|
638
|
+
setPrivateRegistryHostname(value);
|
|
639
|
+
}, 1e3);
|
|
640
|
+
}, []);
|
|
641
|
+
useEffect(() => {
|
|
642
|
+
return () => {
|
|
643
|
+
if (registryDebounceRef.current) {
|
|
644
|
+
clearTimeout(registryDebounceRef.current);
|
|
645
|
+
}
|
|
646
|
+
};
|
|
647
|
+
}, []);
|
|
648
|
+
if (step === 2) {
|
|
649
|
+
return /* @__PURE__ */ jsxs("div", { className: "space-y-6", children: [
|
|
650
|
+
/* @__PURE__ */ jsx(StepIndicator, { step: 2 }),
|
|
651
|
+
/* @__PURE__ */ jsx("div", { className: "overflow-hidden rounded-2xl border border-gray-100 bg-gray-50 p-6", children: /* @__PURE__ */ jsxs("div", { className: "min-w-0 space-y-6", children: [
|
|
652
|
+
/* @__PURE__ */ jsxs("div", { className: "min-w-0", children: [
|
|
653
|
+
/* @__PURE__ */ jsx("h2", { className: "text-xl font-semibold text-gray-900", children: networkAvailability === "proxy" ? "Helm Proxy Install" : networkAvailability === "airgap" ? "Helm Air Gap Install" : "Helm Online Install" }),
|
|
654
|
+
/* @__PURE__ */ jsxs("div", { className: "mt-6 space-y-6", children: [
|
|
655
|
+
/* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
656
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 text-indigo-500", children: [
|
|
657
|
+
/* @__PURE__ */ jsx("span", { className: "flex h-6 w-6 items-center justify-center rounded-full bg-indigo-100 font-semibold", children: "1" }),
|
|
658
|
+
/* @__PURE__ */ jsx("span", { className: "font-medium text-gray-900", children: "Select a version" })
|
|
659
|
+
] }),
|
|
660
|
+
/* @__PURE__ */ jsx(
|
|
661
|
+
VersionDropdown,
|
|
662
|
+
{
|
|
663
|
+
releases: helmReleases,
|
|
664
|
+
selectedRelease,
|
|
665
|
+
onSelect: handleReleaseSelect,
|
|
666
|
+
isLoading: isLoadingReleases,
|
|
667
|
+
isLoadingInstructions,
|
|
668
|
+
error: releasesError
|
|
669
|
+
}
|
|
670
|
+
)
|
|
671
|
+
] }),
|
|
672
|
+
networkAvailability === "airgap" && selectedRelease && /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
673
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 text-indigo-500", children: [
|
|
674
|
+
/* @__PURE__ */ jsx("span", { className: "flex h-6 w-6 items-center justify-center rounded-full bg-indigo-100 font-semibold", children: "2" }),
|
|
675
|
+
/* @__PURE__ */ jsx("span", { className: "font-medium text-gray-900", children: "(Optional) Specify registry URI" })
|
|
676
|
+
] }),
|
|
677
|
+
/* @__PURE__ */ jsxs("div", { className: "ml-8", children: [
|
|
678
|
+
/* @__PURE__ */ jsxs("p", { className: "text-sm text-gray-500 mb-2", children: [
|
|
679
|
+
"Specify your registry URI to replace ",
|
|
680
|
+
/* @__PURE__ */ jsx("code", { className: "bg-gray-100 px-1 rounded text-gray-700", children: "$YOUR_PRIVATE_REGISTRY" }),
|
|
681
|
+
" in the commands below."
|
|
682
|
+
] }),
|
|
683
|
+
/* @__PURE__ */ jsx(
|
|
684
|
+
"input",
|
|
685
|
+
{
|
|
686
|
+
type: "text",
|
|
687
|
+
value: inputRegistryHostname,
|
|
688
|
+
onChange: handlePrivateRegistryHostnameChange,
|
|
689
|
+
placeholder: "your.registry.com",
|
|
690
|
+
className: "portal-input w-64"
|
|
691
|
+
}
|
|
692
|
+
)
|
|
693
|
+
] })
|
|
694
|
+
] }),
|
|
695
|
+
selectedRelease && /* @__PURE__ */ jsx(
|
|
696
|
+
InstallationInstructions,
|
|
697
|
+
{
|
|
698
|
+
instructions,
|
|
699
|
+
isLoading: isLoadingInstructions,
|
|
700
|
+
completedSteps,
|
|
701
|
+
registryAccess,
|
|
702
|
+
networkAvailability
|
|
703
|
+
}
|
|
704
|
+
)
|
|
705
|
+
] })
|
|
706
|
+
] }),
|
|
707
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between text-sm text-gray-500", children: [
|
|
708
|
+
/* @__PURE__ */ jsx(
|
|
709
|
+
"button",
|
|
710
|
+
{
|
|
711
|
+
type: "button",
|
|
712
|
+
onClick: handleBack,
|
|
713
|
+
className: "rounded-xl px-4 py-2 font-medium text-gray-500 transition hover:bg-gray-100",
|
|
714
|
+
children: "Back"
|
|
715
|
+
}
|
|
716
|
+
),
|
|
717
|
+
/* @__PURE__ */ jsx("span", { children: "Step 2 of 2" }),
|
|
718
|
+
/* @__PURE__ */ jsx(
|
|
719
|
+
"button",
|
|
720
|
+
{
|
|
721
|
+
type: "button",
|
|
722
|
+
onClick: handleFinish,
|
|
723
|
+
className: "rounded-xl bg-indigo-500 px-4 py-2 font-medium text-white transition hover:bg-indigo-600",
|
|
724
|
+
children: "Finish"
|
|
725
|
+
}
|
|
726
|
+
)
|
|
727
|
+
] }),
|
|
728
|
+
/* @__PURE__ */ jsxs("p", { className: "text-center text-xs text-gray-400", children: [
|
|
729
|
+
"Having trouble? ",
|
|
730
|
+
/* @__PURE__ */ jsx("a", { className: "text-indigo-500", href: "#", children: "Open an issue." })
|
|
731
|
+
] })
|
|
732
|
+
] }) })
|
|
733
|
+
] });
|
|
734
|
+
}
|
|
735
|
+
return /* @__PURE__ */ jsxs("div", { className: "space-y-6", children: [
|
|
736
|
+
/* @__PURE__ */ jsx(StepIndicator, { step }),
|
|
737
|
+
/* @__PURE__ */ jsxs("div", { className: "rounded-2xl border border-gray-100 bg-gray-50 p-6", children: [
|
|
738
|
+
/* @__PURE__ */ jsxs("div", { className: "space-y-6", children: [
|
|
739
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
740
|
+
/* @__PURE__ */ jsxs("label", { className: "flex items-center gap-2 text-sm font-medium text-gray-700", children: [
|
|
741
|
+
"Instance Name",
|
|
742
|
+
/* @__PURE__ */ jsx(
|
|
743
|
+
"span",
|
|
744
|
+
{
|
|
745
|
+
className: "flex h-4 w-4 items-center justify-center rounded-full border border-gray-300 text-xs text-gray-400 cursor-help",
|
|
746
|
+
title: "The instance name is both a nickname for the instance and the name of the service account that we will create for the installation.",
|
|
747
|
+
children: "i"
|
|
748
|
+
}
|
|
749
|
+
)
|
|
750
|
+
] }),
|
|
751
|
+
/* @__PURE__ */ jsx(
|
|
752
|
+
"input",
|
|
753
|
+
{
|
|
754
|
+
value: instanceName,
|
|
755
|
+
onChange: (event) => setInstanceName(event.target.value),
|
|
756
|
+
placeholder: "Instance nickname",
|
|
757
|
+
"aria-invalid": showErrors && !instanceName.trim(),
|
|
758
|
+
className: `portal-input mt-2 w-48 ${showErrors && !instanceName.trim() ? "border-rose-400 focus:border-rose-400 focus:ring-rose-200" : ""}`
|
|
759
|
+
}
|
|
760
|
+
),
|
|
761
|
+
showErrors && !instanceName.trim() ? /* @__PURE__ */ jsx("span", { className: "mt-1 block text-xs text-rose-500", children: "Instance name is required." }) : null
|
|
762
|
+
] }),
|
|
763
|
+
apiError ? /* @__PURE__ */ jsx("div", { className: "rounded-lg border border-rose-200 bg-rose-50 p-3 text-sm text-rose-800", children: apiError }) : null,
|
|
764
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
765
|
+
/* @__PURE__ */ jsx("label", { className: "block text-sm font-medium text-gray-700", children: "Kubernetes Distribution" }),
|
|
766
|
+
/* @__PURE__ */ jsx(
|
|
767
|
+
"select",
|
|
768
|
+
{
|
|
769
|
+
value: kubernetesDistribution,
|
|
770
|
+
onChange: (e) => setKubernetesDistribution(e.target.value),
|
|
771
|
+
className: "portal-select mt-2 w-64",
|
|
772
|
+
children: K8S_DISTRIBUTIONS.map(({ value, label }) => /* @__PURE__ */ jsx("option", { value, children: label }, value))
|
|
773
|
+
}
|
|
774
|
+
)
|
|
775
|
+
] }),
|
|
776
|
+
/* @__PURE__ */ jsxs("fieldset", { className: "space-y-2", children: [
|
|
777
|
+
/* @__PURE__ */ jsx("legend", { className: "text-sm font-medium text-gray-700", children: "Cluster Network Availability" }),
|
|
778
|
+
/* @__PURE__ */ jsxs("label", { className: "flex items-center gap-3 text-sm text-gray-600", children: [
|
|
779
|
+
/* @__PURE__ */ jsx(
|
|
780
|
+
"input",
|
|
781
|
+
{
|
|
782
|
+
type: "radio",
|
|
783
|
+
name: "network-availability",
|
|
784
|
+
checked: networkAvailability === "online",
|
|
785
|
+
onChange: () => setNetworkAvailability("online"),
|
|
786
|
+
className: "portal-radio"
|
|
787
|
+
}
|
|
788
|
+
),
|
|
789
|
+
"Outbound requests allowed"
|
|
790
|
+
] }),
|
|
791
|
+
/* @__PURE__ */ jsxs("label", { className: "flex items-center gap-3 text-sm text-gray-600", children: [
|
|
792
|
+
/* @__PURE__ */ jsx(
|
|
793
|
+
"input",
|
|
794
|
+
{
|
|
795
|
+
type: "radio",
|
|
796
|
+
name: "network-availability",
|
|
797
|
+
checked: networkAvailability === "proxy",
|
|
798
|
+
onChange: () => setNetworkAvailability("proxy"),
|
|
799
|
+
className: "portal-radio"
|
|
800
|
+
}
|
|
801
|
+
),
|
|
802
|
+
"Outbound requests require HTTPS Proxy"
|
|
803
|
+
] }),
|
|
804
|
+
/* @__PURE__ */ jsxs("label", { className: "flex items-center gap-3 text-sm text-gray-600", children: [
|
|
805
|
+
/* @__PURE__ */ jsx(
|
|
806
|
+
"input",
|
|
807
|
+
{
|
|
808
|
+
type: "radio",
|
|
809
|
+
name: "network-availability",
|
|
810
|
+
checked: networkAvailability === "airgap",
|
|
811
|
+
onChange: () => setNetworkAvailability("airgap"),
|
|
812
|
+
className: "portal-radio"
|
|
813
|
+
}
|
|
814
|
+
),
|
|
815
|
+
"No outbound requests allowed (air gap)"
|
|
816
|
+
] })
|
|
817
|
+
] }),
|
|
818
|
+
/* @__PURE__ */ jsxs("fieldset", { className: "space-y-2", children: [
|
|
819
|
+
/* @__PURE__ */ jsx("legend", { className: "text-sm font-medium text-gray-700", children: "Registry Access" }),
|
|
820
|
+
/* @__PURE__ */ jsxs("label", { className: "flex items-center gap-3 text-sm text-gray-600", children: [
|
|
821
|
+
/* @__PURE__ */ jsx(
|
|
822
|
+
"input",
|
|
823
|
+
{
|
|
824
|
+
type: "radio",
|
|
825
|
+
name: "registry-access",
|
|
826
|
+
checked: registryAccess === "online",
|
|
827
|
+
onChange: () => setRegistryAccess("online"),
|
|
828
|
+
className: "portal-radio"
|
|
829
|
+
}
|
|
830
|
+
),
|
|
831
|
+
"My workstation can access the internet, the registry AND the cluster"
|
|
832
|
+
] }),
|
|
833
|
+
/* @__PURE__ */ jsxs("label", { className: "flex items-center gap-3 text-sm text-gray-600", children: [
|
|
834
|
+
/* @__PURE__ */ jsx(
|
|
835
|
+
"input",
|
|
836
|
+
{
|
|
837
|
+
type: "radio",
|
|
838
|
+
name: "registry-access",
|
|
839
|
+
checked: registryAccess === "partial",
|
|
840
|
+
onChange: () => setRegistryAccess("partial"),
|
|
841
|
+
className: "portal-radio"
|
|
842
|
+
}
|
|
843
|
+
),
|
|
844
|
+
"My workstation can only access the internet AND the registry (NOT the cluster)"
|
|
845
|
+
] }),
|
|
846
|
+
/* @__PURE__ */ jsxs("label", { className: "flex items-center gap-3 text-sm text-gray-600", children: [
|
|
847
|
+
/* @__PURE__ */ jsx(
|
|
848
|
+
"input",
|
|
849
|
+
{
|
|
850
|
+
type: "radio",
|
|
851
|
+
name: "registry-access",
|
|
852
|
+
checked: registryAccess === "offline",
|
|
853
|
+
onChange: () => setRegistryAccess("offline"),
|
|
854
|
+
className: "portal-radio"
|
|
855
|
+
}
|
|
856
|
+
),
|
|
857
|
+
"I need to download artifacts and transfer them for offline installation"
|
|
858
|
+
] })
|
|
859
|
+
] })
|
|
860
|
+
] }),
|
|
861
|
+
/* @__PURE__ */ jsxs("div", { className: "mt-6 flex items-center justify-between text-sm text-gray-500", children: [
|
|
862
|
+
/* @__PURE__ */ jsx("span", { children: "Step 1 of 2" }),
|
|
863
|
+
/* @__PURE__ */ jsx(
|
|
864
|
+
"button",
|
|
865
|
+
{
|
|
866
|
+
type: "button",
|
|
867
|
+
onClick: handleContinue,
|
|
868
|
+
disabled: isCreatingServiceAccount,
|
|
869
|
+
className: "rounded-xl bg-indigo-500 px-4 py-2 font-medium text-white transition hover:bg-indigo-600 disabled:cursor-not-allowed disabled:opacity-50",
|
|
870
|
+
children: isCreatingServiceAccount ? "Creating..." : "Continue"
|
|
871
|
+
}
|
|
872
|
+
)
|
|
873
|
+
] })
|
|
874
|
+
] })
|
|
875
|
+
] });
|
|
876
|
+
};
|
|
877
|
+
HelmInstallWizard.displayName = "HelmInstallWizard";
|
|
878
|
+
|
|
879
|
+
// src/utils/api-client.ts
|
|
880
|
+
async function authenticatedFetch(url, options = {}) {
|
|
881
|
+
const { token, ...fetchOptions } = options;
|
|
882
|
+
const headers = new Headers(fetchOptions.headers);
|
|
883
|
+
if (token) {
|
|
884
|
+
headers.set("authorization", `Bearer ${token}`);
|
|
885
|
+
}
|
|
886
|
+
const response = await fetch(url, {
|
|
887
|
+
...fetchOptions,
|
|
888
|
+
headers
|
|
889
|
+
});
|
|
890
|
+
if (response.status === 401) {
|
|
891
|
+
await handle401();
|
|
892
|
+
}
|
|
893
|
+
if (response.status === 502 || response.status === 503 || response.status === 504) {
|
|
894
|
+
await handleServerError(response.status);
|
|
895
|
+
}
|
|
896
|
+
return response;
|
|
897
|
+
}
|
|
898
|
+
async function handle401() {
|
|
899
|
+
const { redirect } = await import('next/navigation');
|
|
900
|
+
return redirect("/?expired=1");
|
|
901
|
+
}
|
|
902
|
+
async function handleServerError(statusCode) {
|
|
903
|
+
const { redirect } = await import('next/navigation');
|
|
904
|
+
let sourceUrl;
|
|
905
|
+
try {
|
|
906
|
+
const { headers } = await import('next/headers');
|
|
907
|
+
const headersList = await headers();
|
|
908
|
+
const referer = headersList.get("referer");
|
|
909
|
+
const host = headersList.get("host");
|
|
910
|
+
const pathname = headersList.get("x-invoke-path") || headersList.get("x-forwarded-path");
|
|
911
|
+
if (referer) {
|
|
912
|
+
sourceUrl = referer;
|
|
913
|
+
} else if (host && pathname) {
|
|
914
|
+
const protocol = headersList.get("x-forwarded-proto") || "https";
|
|
915
|
+
sourceUrl = `${protocol}://${host}${pathname}`;
|
|
916
|
+
}
|
|
917
|
+
} catch (error) {
|
|
918
|
+
console.debug("[portal-components] Could not determine source URL", error);
|
|
919
|
+
}
|
|
920
|
+
const params = new URLSearchParams({ code: String(statusCode) });
|
|
921
|
+
if (sourceUrl) {
|
|
922
|
+
params.set("source", sourceUrl);
|
|
923
|
+
}
|
|
924
|
+
return redirect(`/error?${params.toString()}`);
|
|
925
|
+
}
|
|
926
|
+
|
|
927
|
+
// src/actions/index.ts
|
|
928
|
+
var getApiOrigin = () => {
|
|
929
|
+
return (process.env.REPLICATED_APP_ORIGIN || "https://replicated.app").replace(/\/+$/, "");
|
|
930
|
+
};
|
|
931
|
+
var defineServerAction = (definition) => definition;
|
|
932
|
+
var createServiceAccount = defineServerAction({
|
|
933
|
+
id: "service-account/create",
|
|
934
|
+
description: "Creates a service account for installing applications",
|
|
935
|
+
visibility: "customer",
|
|
936
|
+
tags: ["service-account", "install"],
|
|
937
|
+
async run({ token, name }) {
|
|
938
|
+
if (!token || typeof token !== "string") {
|
|
939
|
+
throw new Error("Service account creation requires a session token");
|
|
940
|
+
}
|
|
941
|
+
if (!name || typeof name !== "string" || !name.trim()) {
|
|
942
|
+
throw new Error("Service account name is required");
|
|
943
|
+
}
|
|
944
|
+
const endpoint = `${getApiOrigin()}/v3/service-account`;
|
|
945
|
+
if (process.env.NODE_ENV !== "production") {
|
|
946
|
+
console.debug(
|
|
947
|
+
"[portal-components] creating service account via %s",
|
|
948
|
+
endpoint
|
|
949
|
+
);
|
|
950
|
+
}
|
|
951
|
+
const response = await authenticatedFetch(endpoint, {
|
|
952
|
+
method: "POST",
|
|
953
|
+
token,
|
|
954
|
+
headers: {
|
|
955
|
+
"content-type": "application/json"
|
|
956
|
+
},
|
|
957
|
+
body: JSON.stringify({ account_name: name.trim() })
|
|
958
|
+
});
|
|
959
|
+
if (!response.ok) {
|
|
960
|
+
const errorText = await response.text();
|
|
961
|
+
throw new Error(
|
|
962
|
+
`Service account creation failed (${response.status} ${response.statusText}): ${errorText}`
|
|
963
|
+
);
|
|
964
|
+
}
|
|
965
|
+
const data = await response.json();
|
|
966
|
+
return data;
|
|
967
|
+
}
|
|
968
|
+
});
|
|
969
|
+
var fetchCustomBrandingImpl = async () => {
|
|
970
|
+
const appSlug = process.env.PORTAL_APP_SLUG;
|
|
971
|
+
if (!appSlug) {
|
|
972
|
+
throw new Error("PORTAL_APP_SLUG is not configured");
|
|
973
|
+
}
|
|
974
|
+
const url = `${getApiOrigin()}/v3/custom-branding?app_slug=${encodeURIComponent(
|
|
975
|
+
appSlug
|
|
976
|
+
)}`;
|
|
977
|
+
if (process.env.NODE_ENV !== "production") {
|
|
978
|
+
console.debug(
|
|
979
|
+
"[portal-components] fetching custom branding via %s",
|
|
980
|
+
url
|
|
981
|
+
);
|
|
982
|
+
}
|
|
983
|
+
const response = await fetch(url, {
|
|
984
|
+
headers: {
|
|
985
|
+
accept: "application/json"
|
|
986
|
+
}
|
|
987
|
+
});
|
|
988
|
+
if (!response.ok) {
|
|
989
|
+
throw new Error(
|
|
990
|
+
`Custom branding request failed (${response.status} ${response.statusText})`
|
|
991
|
+
);
|
|
992
|
+
}
|
|
993
|
+
const payload = await response.json();
|
|
994
|
+
const brandingData = payload?.branding_data;
|
|
995
|
+
if (typeof brandingData !== "string") {
|
|
996
|
+
throw new Error("Custom branding response missing branding_data string");
|
|
997
|
+
}
|
|
998
|
+
return {
|
|
999
|
+
brandingData,
|
|
1000
|
+
documentation: payload?.documentation ?? null
|
|
1001
|
+
};
|
|
1002
|
+
};
|
|
1003
|
+
cache(fetchCustomBrandingImpl);
|
|
1004
|
+
|
|
1005
|
+
export { HELM_INSTALL_SERVICE_ACCOUNT_KEY, HelmInstallWizard, createServiceAccount };
|
|
1006
|
+
//# sourceMappingURL=helm-install-wizard.js.map
|
|
1007
|
+
//# sourceMappingURL=helm-install-wizard.js.map
|