@jfvilas/plugin-kwirth-fileman 0.13.10 → 0.14.2
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/README.md +18 -21
- package/dist/components/EntityKwirthFilemanContent.esm.js +103 -82
- package/dist/components/EntityKwirthFilemanContent.esm.js.map +1 -1
- package/dist/components/custom-fm.module.css.esm.js +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/version.esm.js +1 -1
- package/dist/version.esm.js.map +1 -1
- package/package.json +10 -10
package/README.md
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
# Backstage frontend KwirthFileman plugin
|
|
2
|
-
This package is a Backstage frontend plugin for **managing Kubernetes containers' filesystems** in real-time via Kwirth.
|
|
2
|
+
This package is a Backstage frontend plugin for **managing Kubernetes containers' filesystems visually** in real-time via Kwirth.
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
KwirthFileman plugin allows you to use a file-explorer-like plugin for navigating through the filesystem, allowing users to examine the content, and also perform file operations like rename, delete, copy, move, copy/cut/paste...
|
|
5
5
|
|
|
6
6
|
In addtion users can also download files (or folders), upload files and even preview file content.
|
|
7
7
|
|
|
8
8
|
- You need to install the Kwirth [Backstage backend plugin](https://www.npmjs.com/package/@jfvilas/plugin-kwirth-backend).
|
|
9
9
|
- You need to install Kwirth on your Kubernetes cluster, that is, this plugin is just another frontend for [Kwirth](https://jfvilas.github.io/kwirth).
|
|
10
10
|
|
|
11
|
-
Kwirth is a really-easy-to-use data-exporting system for Kubernetes that runs in only one pod (*no database is needed*). Refer to Kwirth GitHub project for [info on installation](https://github.com/jfvilas/kwirth?tab=readme-ov-file#installation). Kwirth installation is *one command away* from you.
|
|
11
|
+
Kwirth is a really-easy-to-use data-exporting system for Kubernetes that runs in only one pod (*no database is needed*), in your Desktop with a GUI or in a Docker container. Refer to Kwirth GitHub project for [info on installation](https://github.com/jfvilas/kwirth?tab=readme-ov-file#installation). Kwirth installation is *one command away* from you.
|
|
12
12
|
|
|
13
13
|
You can access [Kwirth project here](https://github.com/jfvilas/kwirth).
|
|
14
14
|
|
|
@@ -18,22 +18,22 @@ Following table shows version compatibility between this Kwirth Backstage plugin
|
|
|
18
18
|
|
|
19
19
|
| Plugin Kwirth version | Kwirth version |
|
|
20
20
|
|-|-|
|
|
21
|
-
|0.
|
|
21
|
+
|0.14.1|0.5.21|
|
|
22
22
|
|
|
23
23
|
|
|
24
24
|
## What is this plugin for?
|
|
25
|
-
This Backstage plugin adds Backstage a feature for working with Kubernetes containers filesystems and manage container data as
|
|
25
|
+
This Backstage plugin adds Backstage a powerful feature for working with Kubernetes containers' filesystems and manage container data as users would do with a Gnome, the Windows file explorer or an Apple file manager.
|
|
26
26
|
|
|
27
27
|
When KwirthFileman is correctly installed and configured, it is possible to manage Kubernetes containers filesystems like this:
|
|
28
28
|
|
|
29
29
|

|
|
30
30
|
|
|
31
|
-
This frontend plugin includes
|
|
31
|
+
This frontend plugin includes the visualization of filesystems. All needed configuration, and specially **permission settings**, are done in the backend plugin and the app-config.yaml. You can restrict access to pods, namespaces, clusters, containers, etc... by configuring permissions to be applied on the backend plugin.
|
|
32
32
|
|
|
33
33
|
## How does it work?
|
|
34
34
|
Let's explain this by following a user working sequence:
|
|
35
35
|
|
|
36
|
-
1. A Backstage user searchs for an entity in the Backstage.
|
|
36
|
+
1. A Backstage user searchs for an entity in the Backstage instance.
|
|
37
37
|
2. In the entity page there will be a new tab named 'KWIRTHFILEMAN'.
|
|
38
38
|
3. When the user clicks on KWIRTHFILEMAN the frontend plugin sends a request to the backend Kwirth plugin asking for containers information on all Kubernetes clusters available.
|
|
39
39
|
4. Next step is to identify the Kubernetes objects that match requested entity. As well as it occurs with other Backstage Kwirth plugins, Kwirth implements two strategies for getting the list of kubernetes objects that match:
|
|
@@ -43,7 +43,7 @@ Let's explain this by following a user working sequence:
|
|
|
43
43
|
6. With the final pod list, the backend plugin sends requests to the Kwirth instances on the clusters asking for API Keys specific for accessing containers filesystems.
|
|
44
44
|
7. With all this information, the backend builds a unique response containing all the pods the user have access to, and all the API keys needed to access the filesystems.
|
|
45
45
|
|
|
46
|
-
If everyting is correctly configured and tagged, the user should see a list of clusters. When selecting a cluster, the user should see a control for starting and
|
|
46
|
+
If everyting is correctly configured and tagged, the user should see a list of clusters. When selecting a cluster, the user should see a control for starting and stopping the file system browser. When the user clicks PLAY (on the right upper side), the file browser appears.
|
|
47
47
|
|
|
48
48
|
|
|
49
49
|
## Installation
|
|
@@ -51,22 +51,19 @@ It's very simple and straightforward, it is in fact very similar to any other fr
|
|
|
51
51
|
|
|
52
52
|
1. Install corresponding Backstage backend plugin [more information here](https://www.npmjs.com/package/@jfvilas/plugin-kwirth-backend).
|
|
53
53
|
2. Install this Backstage frontend plugin:
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
```
|
|
59
|
-
|
|
54
|
+
```sh
|
|
55
|
+
# From your Backstage root directory
|
|
56
|
+
yarn --cwd packages/app add @jfvilas/plugin-kwirth-fileman @jfvilas/plugin-kwirth-frontend @jfvilas/plugin-kwirth-common @jfvilas/kwirth-common
|
|
57
|
+
```
|
|
60
58
|
3. Make sure the [Kwirth backend plugin](https://www.npmjs.com/package/@jfvilas/plugin-kwirth-backend#configure) is installed and configured.
|
|
61
|
-
|
|
62
59
|
4. Restart your Backstage instance.
|
|
63
60
|
|
|
64
61
|
|
|
65
62
|
## Configuration: Entity Pages
|
|
66
63
|
For Kwirth plugin to be usable on the frontend, you must tailor your Entity Page to include the Kwirth components.
|
|
67
64
|
|
|
68
|
-
#### 1. Add the plugin as a tab in your Entity pages:
|
|
69
65
|
|
|
66
|
+
#### 1. Add the plugin as a tab in your Entity pages:
|
|
70
67
|
Firstly, import the plugin module.
|
|
71
68
|
|
|
72
69
|
```typescript
|
|
@@ -109,11 +106,11 @@ Use one of these strategies:
|
|
|
109
106
|
|
|
110
107
|
- **Strategy 1: one-to-one**. Add `backstage.io/kubernetes-id` annotation to your `catalog-info.yaml` for the entities deployed to Kubernetes you want to work with on Backstage. This is the same annotation that the Kubernetes core plugin uses, so, maybe you already have added it to your components. Exmaple:
|
|
111
108
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
109
|
+
```yaml
|
|
110
|
+
metadata:
|
|
111
|
+
annotations:
|
|
112
|
+
backstage.io/kubernetes-id: entity001
|
|
113
|
+
```
|
|
117
114
|
|
|
118
115
|
- **Strategy 2: use selectors**. Add `backstage.io/kubernetes-label-selector` annotation to your `catalog-info.yaml` for the entities you want to work with. This is the same annotation that the Kubernetes core plugin uses, so, maybe you already have added it to your components. The label selector value follows Kubernetes [label selector semantics](https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/). Example:
|
|
119
116
|
|
|
@@ -6,7 +6,7 @@ import { useApi, alertApiRef } from '@backstage/core-plugin-api';
|
|
|
6
6
|
import { isKwirthAvailable, ANNOTATION_BACKSTAGE_KUBERNETES_LABELID, ANNOTATION_BACKSTAGE_KUBERNETES_LABELSELECTOR, getPodList, getContainerList } from '@jfvilas/plugin-kwirth-common';
|
|
7
7
|
import { useEntity, MissingAnnotationEmptyState } from '@backstage/plugin-catalog-react';
|
|
8
8
|
import { kwirthFilemanApiRef } from '../api/types.esm.js';
|
|
9
|
-
import {
|
|
9
|
+
import { ESignalMessageLevel, accessKeySerialize, EInstanceMessageType, EInstanceMessageAction, EInstanceMessageFlow, EInstanceConfigView, EInstanceConfigObject, ESignalMessageEvent } from '@jfvilas/kwirth-common';
|
|
10
10
|
import { ComponentNotFound, ErrorType, ClusterList, KwirthNews, StatusLog } from '@jfvilas/plugin-kwirth-frontend';
|
|
11
11
|
import { FileManager } from '@jfvilas/react-file-manager';
|
|
12
12
|
import { VERSION } from '../version.esm.js';
|
|
@@ -48,7 +48,7 @@ const EntityKwirthFilemanContent = (props) => {
|
|
|
48
48
|
const [statusMessages, setStatusMessages] = useState([]);
|
|
49
49
|
const [webSocket, setWebSocket] = useState();
|
|
50
50
|
const [showStatusDialog, setShowStatusDialog] = useState(false);
|
|
51
|
-
const [statusLevel, setStatusLevel] = useState(
|
|
51
|
+
const [statusLevel, setStatusLevel] = useState(ESignalMessageLevel.INFO);
|
|
52
52
|
const [backendVersion, setBackendVersion] = useState("");
|
|
53
53
|
const [backendInfo, setBackendInfo] = useState();
|
|
54
54
|
const instance = useRef();
|
|
@@ -64,6 +64,7 @@ const EntityKwirthFilemanContent = (props) => {
|
|
|
64
64
|
});
|
|
65
65
|
const filemanBoxRef = useRef(null);
|
|
66
66
|
const [filemanBoxTop, setFilemanBoxTop] = useState(0);
|
|
67
|
+
const [runningInstance, setRunningInstance] = useState();
|
|
67
68
|
let permissions = {
|
|
68
69
|
create: true,
|
|
69
70
|
delete: true,
|
|
@@ -85,7 +86,7 @@ const EntityKwirthFilemanContent = (props) => {
|
|
|
85
86
|
let accessKey = cluster.accessKeys.get("fileman$read");
|
|
86
87
|
if (accessKey) {
|
|
87
88
|
fileUploadConfig = {
|
|
88
|
-
url: `${cluster.url}/channel/fileman/upload?key=${instance.current}`,
|
|
89
|
+
url: `${cluster.url}/${runningInstance}/channel/fileman/upload?key=${instance.current}`,
|
|
89
90
|
method: "POST",
|
|
90
91
|
headers: {
|
|
91
92
|
"Authorization": "Bearer " + accessKeySerialize(accessKey)
|
|
@@ -165,27 +166,26 @@ const EntityKwirthFilemanContent = (props) => {
|
|
|
165
166
|
const processFilemanMessage = (wsEvent) => {
|
|
166
167
|
let msg = JSON.parse(wsEvent.data);
|
|
167
168
|
switch (msg.type) {
|
|
168
|
-
case
|
|
169
|
+
case EInstanceMessageType.DATA: {
|
|
169
170
|
let response = JSON.parse(wsEvent.data);
|
|
170
171
|
switch (response.action) {
|
|
171
|
-
case
|
|
172
|
+
case EInstanceMessageAction.COMMAND:
|
|
172
173
|
{
|
|
173
174
|
switch (response.command) {
|
|
174
175
|
case "home" /* HOME */:
|
|
175
176
|
let data = response.data;
|
|
176
177
|
let nss = Array.from(new Set(data.map((n) => n.split("/")[0])));
|
|
177
|
-
nss.
|
|
178
|
+
nss.forEach((ns) => {
|
|
178
179
|
if (!files.current.some((f) => f.path === "/" + ns)) {
|
|
179
180
|
files.current.push({ name: ns, isDirectory: true, path: "/" + ns, class: "namespace" });
|
|
180
181
|
}
|
|
181
182
|
let podNames = Array.from(new Set(data.filter((a) => a.split("/")[0] === ns).map((o) => o.split("/")[1])));
|
|
182
|
-
podNames.
|
|
183
|
+
podNames.forEach((p) => {
|
|
183
184
|
if (!files.current.some((f) => f.path === "/" + ns + "/" + p)) {
|
|
184
185
|
files.current.push({ name: p, isDirectory: true, path: "/" + ns + "/" + p, class: "pod" });
|
|
185
186
|
}
|
|
186
|
-
let
|
|
187
|
-
|
|
188
|
-
containers.map((c) => {
|
|
187
|
+
let conts = Array.from(new Set(data.filter((a) => a.split("/")[0] === ns && a.split("/")[1] === p).map((o) => o.split("/")[2])));
|
|
188
|
+
conts.forEach((c) => {
|
|
189
189
|
if (!files.current.some((f) => f.path === "/" + ns + "/" + p + "/" + c)) {
|
|
190
190
|
files.current.push({ name: c, isDirectory: true, path: "/" + ns + "/" + p + "/" + c, class: "container" });
|
|
191
191
|
}
|
|
@@ -197,31 +197,34 @@ const EntityKwirthFilemanContent = (props) => {
|
|
|
197
197
|
case "dir" /* DIR */:
|
|
198
198
|
let content = JSON.parse(response.data);
|
|
199
199
|
if (content.status === "Success") {
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
200
|
+
if (content.status !== "Success") {
|
|
201
|
+
addMessage(ESignalMessageLevel.ERROR, content.text || content.message);
|
|
202
|
+
} else {
|
|
203
|
+
for (let o of content.metadata.object) {
|
|
204
|
+
let name = o.name.split("/")[o.name.split("/").length - 1];
|
|
205
|
+
let e = {
|
|
206
|
+
name,
|
|
207
|
+
isDirectory: o.type === 1,
|
|
208
|
+
path: o.name,
|
|
209
|
+
data: {
|
|
210
|
+
updatedAt: (/* @__PURE__ */ new Date(+o.time)).toISOString(),
|
|
211
|
+
size: +o.size,
|
|
212
|
+
...o.type === 0 ? { class: "file" } : {}
|
|
213
|
+
}
|
|
214
|
+
};
|
|
215
|
+
files.current = files.current.filter((f) => f.path !== e.path);
|
|
214
216
|
files.current.push(e);
|
|
217
|
+
}
|
|
215
218
|
}
|
|
216
219
|
setStateFiles([...files.current]);
|
|
217
220
|
} else {
|
|
218
|
-
addMessage(
|
|
221
|
+
addMessage(ESignalMessageLevel.ERROR, content.text || content.message);
|
|
219
222
|
}
|
|
220
223
|
break;
|
|
221
224
|
case "rename" /* RENAME */:
|
|
222
225
|
{
|
|
223
226
|
let content2 = JSON.parse(response.data);
|
|
224
|
-
if (content2.status !== "Success") addMessage(
|
|
227
|
+
if (content2.status !== "Success") addMessage(ESignalMessageLevel.ERROR, content2.text || content2.message);
|
|
225
228
|
}
|
|
226
229
|
break;
|
|
227
230
|
case "delete" /* DELETE */: {
|
|
@@ -232,7 +235,7 @@ const EntityKwirthFilemanContent = (props) => {
|
|
|
232
235
|
files.current = files.current.filter((f) => !f.path.startsWith(fname + "/"));
|
|
233
236
|
setStateFiles([...files.current]);
|
|
234
237
|
} else {
|
|
235
|
-
addMessage(
|
|
238
|
+
addMessage(ESignalMessageLevel.ERROR, content2.text || content2.message);
|
|
236
239
|
}
|
|
237
240
|
break;
|
|
238
241
|
}
|
|
@@ -241,18 +244,20 @@ const EntityKwirthFilemanContent = (props) => {
|
|
|
241
244
|
case "create" /* CREATE */: {
|
|
242
245
|
let content2 = JSON.parse(response.data);
|
|
243
246
|
if (content2.status === "Success") {
|
|
244
|
-
let
|
|
247
|
+
let e = {
|
|
245
248
|
name: content2.metadata.object.split("/").slice(-1)[0],
|
|
246
249
|
isDirectory: content2.metadata.type === 1,
|
|
247
250
|
path: content2.metadata.object,
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
+
data: {
|
|
252
|
+
updatedAt: (/* @__PURE__ */ new Date(+content2.metadata.time)).toISOString(),
|
|
253
|
+
size: +content2.metadata.size,
|
|
254
|
+
...content2.metadata.type.type === 0 ? { class: "file" } : {}
|
|
255
|
+
}
|
|
251
256
|
};
|
|
252
|
-
files.current.push(
|
|
257
|
+
files.current.push(e);
|
|
253
258
|
setStateFiles([...files.current]);
|
|
254
259
|
} else {
|
|
255
|
-
addMessage(
|
|
260
|
+
addMessage(ESignalMessageLevel.ERROR, content2.text || content2.message);
|
|
256
261
|
}
|
|
257
262
|
break;
|
|
258
263
|
}
|
|
@@ -262,26 +267,43 @@ const EntityKwirthFilemanContent = (props) => {
|
|
|
262
267
|
}
|
|
263
268
|
break;
|
|
264
269
|
}
|
|
265
|
-
case
|
|
270
|
+
case EInstanceMessageType.SIGNAL:
|
|
266
271
|
let signalMessage = JSON.parse(wsEvent.data);
|
|
267
|
-
if (signalMessage.flow ===
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
272
|
+
if (signalMessage.flow === EInstanceMessageFlow.RESPONSE) {
|
|
273
|
+
switch (signalMessage.action) {
|
|
274
|
+
case EInstanceMessageAction.START:
|
|
275
|
+
if (signalMessage.text) addMessage(ESignalMessageLevel.INFO, signalMessage.text);
|
|
276
|
+
instance.current = signalMessage.instance;
|
|
277
|
+
break;
|
|
278
|
+
case EInstanceMessageAction.RI:
|
|
279
|
+
setRunningInstance(signalMessage.data);
|
|
280
|
+
break;
|
|
281
|
+
case EInstanceMessageAction.COMMAND:
|
|
282
|
+
if (signalMessage.text) addMessage(signalMessage.level, signalMessage.text);
|
|
283
|
+
break;
|
|
284
|
+
default:
|
|
285
|
+
addMessage(ESignalMessageLevel.ERROR, wsEvent.data);
|
|
286
|
+
break;
|
|
273
287
|
}
|
|
274
|
-
} else if (signalMessage.flow ===
|
|
288
|
+
} else if (signalMessage.flow === EInstanceMessageFlow.UNSOLICITED) {
|
|
275
289
|
let cluster2 = validClusters.find((cluster3) => cluster3.name === selectedClusterName);
|
|
276
290
|
if (cluster2) {
|
|
277
291
|
let accessKey = cluster2.accessKeys.get("fileman$read");
|
|
278
292
|
if (accessKey && instance?.current) {
|
|
279
|
-
if (signalMessage.event ===
|
|
293
|
+
if (signalMessage.event === ESignalMessageEvent.ADD) {
|
|
294
|
+
let instanceConfig = {
|
|
295
|
+
action: EInstanceMessageAction.RI,
|
|
296
|
+
channel: "fileman",
|
|
297
|
+
flow: EInstanceMessageFlow.REQUEST,
|
|
298
|
+
type: EInstanceMessageType.SIGNAL,
|
|
299
|
+
instance: instance.current
|
|
300
|
+
};
|
|
301
|
+
wsEvent.target.send(JSON.stringify(instanceConfig));
|
|
280
302
|
let filemanMessage = {
|
|
281
|
-
flow:
|
|
282
|
-
action:
|
|
303
|
+
flow: EInstanceMessageFlow.REQUEST,
|
|
304
|
+
action: EInstanceMessageAction.COMMAND,
|
|
283
305
|
channel: "fileman",
|
|
284
|
-
type:
|
|
306
|
+
type: EInstanceMessageType.DATA,
|
|
285
307
|
accessKey: accessKeySerialize(accessKey),
|
|
286
308
|
instance: instance.current,
|
|
287
309
|
id: v4(),
|
|
@@ -295,13 +317,13 @@ const EntityKwirthFilemanContent = (props) => {
|
|
|
295
317
|
};
|
|
296
318
|
let payload = JSON.stringify(filemanMessage);
|
|
297
319
|
wsEvent.target.send(payload);
|
|
298
|
-
if (signalMessage.text) addMessage(
|
|
320
|
+
if (signalMessage.text) addMessage(ESignalMessageLevel.INFO, signalMessage.text);
|
|
299
321
|
}
|
|
300
322
|
} else {
|
|
301
|
-
addMessage(
|
|
323
|
+
addMessage(ESignalMessageLevel.INFO, "Have no instance/accessKey");
|
|
302
324
|
}
|
|
303
325
|
} else {
|
|
304
|
-
addMessage(
|
|
326
|
+
addMessage(ESignalMessageLevel.INFO, "Have no cluster");
|
|
305
327
|
}
|
|
306
328
|
}
|
|
307
329
|
break;
|
|
@@ -312,17 +334,14 @@ const EntityKwirthFilemanContent = (props) => {
|
|
|
312
334
|
};
|
|
313
335
|
const addMessage = (level2, text) => {
|
|
314
336
|
alertApi.post({ message: text, severity: level2, display: "transient" });
|
|
315
|
-
setStatusMessages((prev) => [...prev, {
|
|
316
|
-
level: level2,
|
|
317
|
-
text,
|
|
318
|
-
type: InstanceMessageTypeEnum.SIGNAL
|
|
319
|
-
}]);
|
|
337
|
+
setStatusMessages((prev) => [...prev, { level: level2, text, type: EInstanceMessageType.SIGNAL }]);
|
|
320
338
|
};
|
|
321
339
|
const websocketOnMessage = (wsEvent) => {
|
|
322
340
|
let instanceMessage;
|
|
323
341
|
try {
|
|
324
342
|
instanceMessage = JSON.parse(wsEvent.data);
|
|
325
343
|
} catch (err) {
|
|
344
|
+
addMessage(ESignalMessageLevel.ERROR, err);
|
|
326
345
|
console.log(err);
|
|
327
346
|
console.log(wsEvent.data);
|
|
328
347
|
return;
|
|
@@ -332,8 +351,8 @@ const EntityKwirthFilemanContent = (props) => {
|
|
|
332
351
|
processFilemanMessage(wsEvent);
|
|
333
352
|
break;
|
|
334
353
|
default:
|
|
335
|
-
addMessage(
|
|
336
|
-
addMessage(
|
|
354
|
+
addMessage(ESignalMessageLevel.ERROR, "Invalid channel in message: " + instanceMessage.channel);
|
|
355
|
+
addMessage(ESignalMessageLevel.ERROR, "Invalid message: " + JSON.stringify(instanceMessage));
|
|
337
356
|
break;
|
|
338
357
|
}
|
|
339
358
|
};
|
|
@@ -341,15 +360,14 @@ const EntityKwirthFilemanContent = (props) => {
|
|
|
341
360
|
setWebSocket(ws);
|
|
342
361
|
let cluster2 = validClusters.find((cluster3) => cluster3.name === selectedClusterName);
|
|
343
362
|
if (!cluster2) {
|
|
344
|
-
addMessage(
|
|
363
|
+
addMessage(ESignalMessageLevel.ERROR, "No cluster selected");
|
|
345
364
|
return;
|
|
346
365
|
}
|
|
347
366
|
let pods = cluster2.pods.filter((p2) => selectedNamespaces.includes(p2.namespace));
|
|
348
367
|
if (!pods) {
|
|
349
|
-
addMessage(
|
|
368
|
+
addMessage(ESignalMessageLevel.ERROR, "No pods found");
|
|
350
369
|
return;
|
|
351
370
|
}
|
|
352
|
-
console.log(`WS connected`);
|
|
353
371
|
let accessKey = cluster2.accessKeys.get("fileman$read");
|
|
354
372
|
if (accessKey) {
|
|
355
373
|
let containers = [];
|
|
@@ -362,30 +380,30 @@ const EntityKwirthFilemanContent = (props) => {
|
|
|
362
380
|
}
|
|
363
381
|
let iConfig = {
|
|
364
382
|
channel: "fileman",
|
|
365
|
-
objects:
|
|
366
|
-
action:
|
|
367
|
-
flow:
|
|
383
|
+
objects: EInstanceConfigObject.PODS,
|
|
384
|
+
action: EInstanceMessageAction.START,
|
|
385
|
+
flow: EInstanceMessageFlow.REQUEST,
|
|
368
386
|
instance: "",
|
|
369
387
|
accessKey: accessKeySerialize(accessKey),
|
|
370
388
|
scope: "fileman$read",
|
|
371
|
-
view: selectedContainerNames.length > 0 ?
|
|
389
|
+
view: selectedContainerNames.length > 0 ? EInstanceConfigView.CONTAINER : EInstanceConfigView.POD,
|
|
372
390
|
namespace: selectedNamespaces.join(","),
|
|
373
391
|
group: "",
|
|
374
392
|
pod: selectedPodNames.map((p2) => p2).join(","),
|
|
375
393
|
container: containers.join(","),
|
|
376
394
|
data: {},
|
|
377
|
-
type:
|
|
395
|
+
type: EInstanceMessageType.SIGNAL
|
|
378
396
|
};
|
|
379
397
|
ws.send(JSON.stringify(iConfig));
|
|
380
398
|
} else {
|
|
381
|
-
addMessage(
|
|
399
|
+
addMessage(ESignalMessageLevel.ERROR, "No accessKey for starting fileman streaming");
|
|
382
400
|
return;
|
|
383
401
|
}
|
|
384
402
|
};
|
|
385
403
|
const startFilemanViewer = () => {
|
|
386
404
|
let cluster2 = validClusters.find((cluster3) => cluster3.name === selectedClusterName);
|
|
387
405
|
if (!cluster2) {
|
|
388
|
-
addMessage(
|
|
406
|
+
addMessage(ESignalMessageLevel.ERROR, "No cluster selected");
|
|
389
407
|
return;
|
|
390
408
|
}
|
|
391
409
|
try {
|
|
@@ -422,14 +440,14 @@ const EntityKwirthFilemanContent = (props) => {
|
|
|
422
440
|
const prepareText = (txt) => {
|
|
423
441
|
return txt ? txt.length > 25 ? txt.substring(0, 25) + "..." : txt : "N/A";
|
|
424
442
|
};
|
|
425
|
-
return /* @__PURE__ */ React.createElement(Grid, { container: true, direction: "row" }, /* @__PURE__ */ React.createElement(Grid, { item: true }, /* @__PURE__ */ React.createElement(Typography, { variant: "h5" }, prepareText(title))), /* @__PURE__ */ React.createElement(Grid, { item: true, style: { marginTop: "-8px" } }, /* @__PURE__ */ React.createElement(IconButton, { title: "info", disabled: !statusMessages.some((m) => m.type ===
|
|
443
|
+
return /* @__PURE__ */ React.createElement(Grid, { container: true, direction: "row" }, /* @__PURE__ */ React.createElement(Grid, { item: true }, /* @__PURE__ */ React.createElement(Typography, { variant: "h5" }, prepareText(title))), /* @__PURE__ */ React.createElement(Grid, { item: true, style: { marginTop: "-8px" } }, /* @__PURE__ */ React.createElement(IconButton, { title: "info", disabled: !statusMessages.some((m) => m.type === EInstanceMessageType.SIGNAL && m.level === ESignalMessageLevel.INFO), onClick: () => show(ESignalMessageLevel.INFO) }, /* @__PURE__ */ React.createElement(InfoIcon, { style: { color: statusMessages.some((m) => m.type === EInstanceMessageType.SIGNAL && m.level === ESignalMessageLevel.INFO) ? "#1D63ED" : "#BDBDBD" } })), /* @__PURE__ */ React.createElement(IconButton, { title: "warning", disabled: !statusMessages.some((m) => m.type === EInstanceMessageType.SIGNAL && m.level === ESignalMessageLevel.WARNING), onClick: () => show(ESignalMessageLevel.WARNING), style: { marginLeft: "-16px" } }, /* @__PURE__ */ React.createElement(WarningIcon, { style: { color: statusMessages.some((m) => m.type === EInstanceMessageType.SIGNAL && m.level === ESignalMessageLevel.WARNING) ? "orange" : "#BDBDBD" } })), /* @__PURE__ */ React.createElement(IconButton, { title: "error", disabled: !statusMessages.some((m) => m.type === EInstanceMessageType.SIGNAL && m.level === ESignalMessageLevel.ERROR), onClick: () => show(ESignalMessageLevel.ERROR), style: { marginLeft: "-16px" } }, /* @__PURE__ */ React.createElement(ErrorIcon, { style: { color: statusMessages.some((m) => m.type === EInstanceMessageType.SIGNAL && m.level === ESignalMessageLevel.ERROR) ? "red" : "#BDBDBD" } }))));
|
|
426
444
|
};
|
|
427
445
|
const statusClear = (level2) => {
|
|
428
446
|
setStatusMessages(statusMessages.filter((m) => m.level !== level2));
|
|
429
447
|
setShowStatusDialog(false);
|
|
430
448
|
};
|
|
431
449
|
const onError = (error2, _file) => {
|
|
432
|
-
addMessage(
|
|
450
|
+
addMessage(ESignalMessageLevel.ERROR, error2.message);
|
|
433
451
|
};
|
|
434
452
|
const onRename = (file, newName) => {
|
|
435
453
|
let [namespace, pod, container] = file.path.split("/").slice(1);
|
|
@@ -452,10 +470,10 @@ const EntityKwirthFilemanContent = (props) => {
|
|
|
452
470
|
if (accessKey && instance?.current && webSocket) {
|
|
453
471
|
let [namespace, pod, container] = folder.split("/").slice(1);
|
|
454
472
|
let filemanMessage = {
|
|
455
|
-
flow:
|
|
456
|
-
action:
|
|
473
|
+
flow: EInstanceMessageFlow.REQUEST,
|
|
474
|
+
action: EInstanceMessageAction.COMMAND,
|
|
457
475
|
channel: "fileman",
|
|
458
|
-
type:
|
|
476
|
+
type: EInstanceMessageType.DATA,
|
|
459
477
|
accessKey: accessKeySerialize(accessKey),
|
|
460
478
|
instance: instance.current,
|
|
461
479
|
id: v4(),
|
|
@@ -478,10 +496,10 @@ const EntityKwirthFilemanContent = (props) => {
|
|
|
478
496
|
let accessKey = cluster2.accessKeys.get("fileman$read");
|
|
479
497
|
if (accessKey && instance?.current && webSocket) {
|
|
480
498
|
let filemanMessage = {
|
|
481
|
-
flow:
|
|
482
|
-
action:
|
|
499
|
+
flow: EInstanceMessageFlow.REQUEST,
|
|
500
|
+
action: EInstanceMessageAction.COMMAND,
|
|
483
501
|
channel: "fileman",
|
|
484
|
-
type:
|
|
502
|
+
type: EInstanceMessageType.DATA,
|
|
485
503
|
accessKey: accessKeySerialize(accessKey),
|
|
486
504
|
instance: instance.current,
|
|
487
505
|
id: v4(),
|
|
@@ -496,10 +514,10 @@ const EntityKwirthFilemanContent = (props) => {
|
|
|
496
514
|
let payload = JSON.stringify(filemanMessage);
|
|
497
515
|
webSocket.send(payload);
|
|
498
516
|
} else {
|
|
499
|
-
addMessage(
|
|
517
|
+
addMessage(ESignalMessageLevel.ERROR, "Have no instance/accessKey");
|
|
500
518
|
}
|
|
501
519
|
} else {
|
|
502
|
-
addMessage(
|
|
520
|
+
addMessage(ESignalMessageLevel.ERROR, "Have no cluster");
|
|
503
521
|
}
|
|
504
522
|
};
|
|
505
523
|
const onDelete = async (filesToDelete) => {
|
|
@@ -518,7 +536,7 @@ const EntityKwirthFilemanContent = (props) => {
|
|
|
518
536
|
let accessKey = cluster2.accessKeys.get("fileman$read");
|
|
519
537
|
if (accessKey) {
|
|
520
538
|
for (let file of filesToDownload) {
|
|
521
|
-
const url = `${cluster2.url}/channel/fileman/download?key=${instance.current}&filename=${file.path}`;
|
|
539
|
+
const url = `${cluster2.url}/${runningInstance}/channel/fileman/download?key=${instance.current}&filename=${file.path}`;
|
|
522
540
|
try {
|
|
523
541
|
const response = await fetch(url, { headers: { "Authorization": "Bearer " + accessKeySerialize(accessKey) } });
|
|
524
542
|
if (response.ok) {
|
|
@@ -533,18 +551,18 @@ const EntityKwirthFilemanContent = (props) => {
|
|
|
533
551
|
URL.revokeObjectURL(link.href);
|
|
534
552
|
} else {
|
|
535
553
|
console.error(`Error downloading file: ${file.path}`);
|
|
536
|
-
addMessage(
|
|
554
|
+
addMessage(ESignalMessageLevel.ERROR, `Error downloading file ${file.path}: (${response.status}) ${await response.text()}`);
|
|
537
555
|
}
|
|
538
556
|
} catch (error2) {
|
|
539
557
|
console.error(`Error downloading file: ${file.path}`, error2);
|
|
540
|
-
addMessage(
|
|
558
|
+
addMessage(ESignalMessageLevel.ERROR, `Error downloading file ${file.path}: ${error2}`);
|
|
541
559
|
}
|
|
542
560
|
}
|
|
543
561
|
} else {
|
|
544
|
-
addMessage(
|
|
562
|
+
addMessage(ESignalMessageLevel.ERROR, "Have no instance/accessKey");
|
|
545
563
|
}
|
|
546
564
|
} else {
|
|
547
|
-
addMessage(
|
|
565
|
+
addMessage(ESignalMessageLevel.ERROR, "Have no cluster");
|
|
548
566
|
}
|
|
549
567
|
};
|
|
550
568
|
const onPaste = (filesToPaste, destFolder, operation) => {
|
|
@@ -570,7 +588,7 @@ const EntityKwirthFilemanContent = (props) => {
|
|
|
570
588
|
style: { marginTop: -4, marginBottom: 4, flexShrink: 0 },
|
|
571
589
|
action: actionButtons()
|
|
572
590
|
}
|
|
573
|
-
)), started && /* @__PURE__ */ React.createElement(Grid, { ref: filemanBoxRef, style: { height: `calc(100vh - ${filemanBoxTop}px - 35px)
|
|
591
|
+
)), started && /* @__PURE__ */ React.createElement(Grid, { ref: filemanBoxRef, style: { height: `calc(100vh - ${filemanBoxTop}px - 35px)`, borderRadius: "12px", overflow: "hidden" } }, /* @__PURE__ */ React.createElement(
|
|
574
592
|
FileManager,
|
|
575
593
|
{
|
|
576
594
|
className: styles.customFm,
|
|
@@ -593,7 +611,10 @@ const EntityKwirthFilemanContent = (props) => {
|
|
|
593
611
|
onDownload,
|
|
594
612
|
enableFilePreview: false,
|
|
595
613
|
initialPath: "",
|
|
596
|
-
permissions
|
|
614
|
+
permissions,
|
|
615
|
+
maxNavigationPaneLevel: 3,
|
|
616
|
+
minFileActionsLevel: 3,
|
|
617
|
+
showBreadcrumb: true
|
|
597
618
|
}
|
|
598
619
|
))))), showStatusDialog && /* @__PURE__ */ React.createElement(StatusLog, { level: statusLevel, onClose: () => setShowStatusDialog(false), statusMessages, onClear: statusClear }));
|
|
599
620
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EntityKwirthFilemanContent.esm.js","sources":["../../src/components/EntityKwirthFilemanContent.tsx"],"sourcesContent":["/*\r\nCopyright 2025 Julio Fernandez\r\n\r\nLicensed under the Apache License, Version 2.0 (the \"License\");\r\nyou may not use this file except in compliance with the License.\r\nYou may obtain a copy of the License at\r\n\r\n http://www.apache.org/licenses/LICENSE-2.0\r\n\r\nUnless required by applicable law or agreed to in writing, software\r\ndistributed under the License is distributed on an \"AS IS\" BASIS,\r\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\nSee the License for the specific language governing permissions and\r\nlimitations under the License.\r\n*/\r\nimport React, { useEffect, useRef, useState } from 'react'\r\nimport { v4 as uuid } from 'uuid'\r\nimport useAsync from 'react-use/esm/useAsync'\r\n\r\nimport { Progress, WarningPanel } from '@backstage/core-components'\r\nimport { alertApiRef, useApi } from '@backstage/core-plugin-api'\r\nimport { ANNOTATION_BACKSTAGE_KUBERNETES_LABELID, ANNOTATION_BACKSTAGE_KUBERNETES_LABELSELECTOR, isKwirthAvailable, ClusterValidPods, IStatusLine, getPodList, getContainerList, IBackendInfo } from '@jfvilas/plugin-kwirth-common'\r\nimport { MissingAnnotationEmptyState, useEntity } from '@backstage/plugin-catalog-react'\r\n\r\n// kwirth\r\nimport { kwirthFilemanApiRef } from '../api'\r\nimport { accessKeySerialize, InstanceMessageActionEnum, InstanceConfigViewEnum, IInstanceMessage, InstanceMessageTypeEnum, SignalMessageLevelEnum, InstanceConfigObjectEnum, IInstanceConfig, InstanceMessageFlowEnum, SignalMessageEventEnum, ISignalMessage } from '@jfvilas/kwirth-common'\r\n\r\n// kwirth fileman components\r\nimport { KwirthNews, ComponentNotFound, StatusLog, ClusterList, ErrorType } from '@jfvilas/plugin-kwirth-frontend'\r\nimport { FileManager, IError, IFileData } from '@jfvilas/react-file-manager'\r\nimport { VERSION } from '../version'\r\n\r\n// Material-UI\r\nimport { Grid, Card, CardHeader, Box, IconButton, Typography } from '@material-ui/core'\r\n\r\n// styles\r\nimport '@jfvilas/react-file-manager/dist/style.css'\r\nimport styles from './custom-fm.module.css'\r\n\r\n// Icons\r\nimport PlayIcon from '@material-ui/icons/PlayArrow'\r\nimport PauseIcon from '@material-ui/icons/Pause'\r\nimport StopIcon from '@material-ui/icons/Stop'\r\nimport InfoIcon from '@material-ui/icons/Info'\r\nimport WarningIcon from '@material-ui/icons/Warning'\r\nimport ErrorIcon from '@material-ui/icons/Error'\r\nimport LogoIcon from '../assets/kwirthfileman-logo.svg'\r\nimport SvgIconNamespace from'./icons/ns.svg'\r\nimport SvgIconPod from'./icons/pod.svg'\r\nimport SvgIconContainer from'./icons/docker-mark-blue.svg'\r\n\r\nexport interface IEntityKwirthFilemanProps {\r\n hideVersion?: boolean\r\n excludeContainers?: string[]\r\n}\r\n\r\n\r\nconst NamespaceIcon = (props: {height?:number}) => { return <img src={SvgIconNamespace} alt='ns' height={`${props.height||16}px`}/> }\r\nconst PodIcon = (props: {height?:number}) => { return <img src={SvgIconPod} alt='pod' height={`${props.height||16}px`}/> }\r\nconst ContainerIcon = (props: {height?:number}) => { return <img src={SvgIconContainer} height={`${props.height||16}px`}/> }\r\n\r\nexport const EntityKwirthFilemanContent: React.FC<IEntityKwirthFilemanProps> = (props:IEntityKwirthFilemanProps) => { \r\n const { entity } = useEntity()\r\n const kwirthFilemanApi = useApi(kwirthFilemanApiRef)\r\n const alertApi = useApi(alertApiRef)\r\n const [validClusters, setResources] = useState<ClusterValidPods[]>([])\r\n const [selectedClusterName, setSelectedClusterName] = useState('')\r\n const [selectedNamespaces, setSelectedNamespaces] = useState<string[]>([])\r\n const [selectedPodNames, setSelectedPodNames] = useState<string[]>([])\r\n const [selectedContainerNames, setSelectedContainerNames] = useState<string[]>([])\r\n const [started, setStarted] = useState(false)\r\n const [stopped, setStopped] = useState(true)\r\n const paused=useRef<boolean>(false)\r\n const [statusMessages, setStatusMessages] = useState<IStatusLine[]>([])\r\n const [webSocket, setWebSocket] = useState<WebSocket>()\r\n const [showStatusDialog, setShowStatusDialog] = useState(false)\r\n const [statusLevel, setStatusLevel] = useState<SignalMessageLevelEnum>(SignalMessageLevelEnum.INFO)\r\n const [ backendVersion, setBackendVersion ] = useState<string>('')\r\n const [ backendInfo, setBackendInfo ] = useState<IBackendInfo>()\r\n const instance = useRef<string>()\r\n const [ stateFiles, setStateFiles ] = useState<IFileData[]>([])\r\n const files = useRef<IFileData[]>([])\r\n const [ currentPath, setCurrentPath] = useState('')\r\n const { loading, error } = useAsync ( async () => {\r\n if (backendVersion==='') setBackendVersion(await kwirthFilemanApi.getVersion())\r\n if (!backendInfo) setBackendInfo(await kwirthFilemanApi.getInfo())\r\n let reqScopes = ['fileman$read']\r\n let data:ClusterValidPods[] = await kwirthFilemanApi.requestAccess(entity, 'fileman', reqScopes)\r\n setResources(data)\r\n })\r\n const filemanBoxRef = useRef<HTMLDivElement | null>(null)\r\n const [filemanBoxTop, setFilemanBoxTop] = useState(0)\r\n let permissions={\r\n create: true,\r\n delete: true,\r\n download: true,\r\n copy: true,\r\n move: true,\r\n rename: true,\r\n upload: true\r\n }\r\n\r\n let icons = new Map()\r\n icons.set('namespace', { open:<NamespaceIcon height={18}/>, closed:<NamespaceIcon height={18}/>, grid:<NamespaceIcon height={40}/>, list:<NamespaceIcon height={18}/>, default:<NamespaceIcon height={18}/> })\r\n icons.set('pod', { open:<PodIcon height={18}/>, closed:<PodIcon height={18}/>, grid:<PodIcon height={40}/>, list:<PodIcon height={18}/>, default:<PodIcon height={18}/> })\r\n icons.set('container', { open:<ContainerIcon/>, closed:<ContainerIcon/>, grid:<ContainerIcon height={34}/>, list:<ContainerIcon height={16}/>, default:<ContainerIcon height={16}/> })\r\n\r\n interface IFileUploadConfig { \r\n url: string\r\n method?: \"POST\" | \"PUT\"\r\n headers?: { [key: string]: string }\r\n }\r\n let fileUploadConfig:IFileUploadConfig= {\r\n url: ''\r\n }\r\n\r\n let cluster = validClusters.find(cluster => cluster.name===selectedClusterName)\r\n if (cluster) {\r\n let accessKey = cluster.accessKeys.get('fileman$read')\r\n if (accessKey) {\r\n fileUploadConfig = {\r\n url: `${cluster.url}/channel/fileman/upload?key=${instance.current}`,\r\n method:'POST',\r\n headers: {\r\n 'Authorization': 'Bearer '+ accessKeySerialize(accessKey)\r\n }\r\n }\r\n }\r\n }\r\n \r\n let level = currentPath.split('/').length - 1\r\n if (level<3) {\r\n permissions = {\r\n create: false,\r\n delete: false,\r\n download: false,\r\n copy: false,\r\n move: false,\r\n rename: false,\r\n upload: false\r\n }\r\n }\r\n\r\n useEffect(() => {\r\n if (filemanBoxRef.current) setFilemanBoxTop(filemanBoxRef.current.getBoundingClientRect().top)\r\n })\r\n\r\n const clickStart = () => {\r\n if (!paused.current) {\r\n setStarted(true)\r\n paused.current=false\r\n setStopped(false)\r\n startFilemanViewer()\r\n }\r\n else {\r\n paused.current=false\r\n setStarted(true)\r\n }\r\n }\r\n\r\n const onClickPause = () => {\r\n setStarted(false)\r\n paused.current=true\r\n }\r\n\r\n const onClickStop = () => {\r\n setStarted(false)\r\n setStopped(true)\r\n paused.current=false\r\n stopFilemanViewer()\r\n }\r\n\r\n const onSelectCluster = (clusterName:string|undefined) => {\r\n if (started) onClickStop()\r\n if (clusterName) {\r\n setSelectedClusterName(clusterName)\r\n setSelectedPodNames([])\r\n setSelectedContainerNames([])\r\n setStatusMessages([])\r\n let cluster = validClusters.find(cluster => cluster.name === clusterName)\r\n\r\n if (cluster && cluster.pods) {\r\n let validNamespaces = Array.from(new Set(cluster.pods.map(pod => pod.namespace)))\r\n if (validNamespaces.length === 1) {\r\n setSelectedNamespaces(validNamespaces)\r\n let podList = getPodList (cluster.pods, validNamespaces)\r\n setSelectedPodNames(podList.map(pod => pod.name))\r\n setSelectedContainerNames(getContainerList(cluster.pods, validNamespaces, podList.map(pod => pod.name), props.excludeContainers || []))\r\n }\r\n else {\r\n setSelectedNamespaces([])\r\n }\r\n }\r\n }\r\n }\r\n\r\n enum FilemanCommandEnum {\r\n HOME = 'home',\r\n DIR = 'dir',\r\n CREATE = 'create',\r\n RENAME = 'rename',\r\n DELETE = 'delete',\r\n MOVE = 'move',\r\n COPY = 'copy',\r\n UPLOAD = 'upload',\r\n DOWNLOAD = 'download'\r\n }\r\n\r\n interface IFilemanMessage extends IInstanceMessage {\r\n msgtype: 'filemanmessage'\r\n id: string\r\n accessKey: string\r\n instance: string\r\n namespace: string\r\n group: string\r\n pod: string\r\n container: string\r\n command: FilemanCommandEnum\r\n params?: string[]\r\n }\r\n\r\n interface IFilemanMessageResponse extends IInstanceMessage {\r\n msgtype: 'filemanmessageresponse'\r\n id: string\r\n command: FilemanCommandEnum\r\n namespace: string\r\n group: string\r\n pod: string\r\n container: string\r\n data?: any\r\n }\r\n\r\n const processFilemanMessage = (wsEvent:any) => {\r\n let msg:IFilemanMessage = JSON.parse(wsEvent.data)\r\n\r\n switch (msg.type) {\r\n case InstanceMessageTypeEnum.DATA: {\r\n let response = JSON.parse(wsEvent.data) as IFilemanMessageResponse\r\n switch(response.action) {\r\n case InstanceMessageActionEnum.COMMAND: {\r\n switch(response.command) {\r\n case FilemanCommandEnum.HOME:\r\n let data = response.data as string[]\r\n let nss = Array.from (new Set (data.map(n => n.split('/')[0])))\r\n nss.map(ns => {\r\n if (!files.current.some(f => f.path === '/'+ ns)) {\r\n files.current.push ({ name: ns, isDirectory: true, path: '/'+ ns, class:'namespace' }) \r\n }\r\n let podNames = Array.from (new Set (data.filter(a => a.split('/')[0]===ns).map(o => o.split('/')[1])))\r\n podNames.map(p => {\r\n if (!files.current.some(f => f.path === '/'+ns+'/'+p)) {\r\n files.current.push ({ name: p, isDirectory: true, path: '/'+ns+'/'+p, class:'pod' })\r\n }\r\n let containers = Array.from (new Set (data.filter(a => a.split('/')[0]===ns && a.split('/')[1]===p).map(o => o.split('/')[2])))\r\n containers = containers.filter(c => !props.excludeContainers?.includes(c))\r\n containers.map(c => {\r\n if (!files.current.some(f => f.path === '/'+ns+'/'+p+'/'+c)) {\r\n files.current.push ({ name: c, isDirectory: true, path: '/'+ns+'/'+p+'/'+c, class:'container' })\r\n }\r\n })\r\n })\r\n })\r\n setStateFiles([...files.current])\r\n break\r\n case FilemanCommandEnum.DIR:\r\n let content = JSON.parse(response.data)\r\n if (content.status==='Success') {\r\n for (let o of content.metadata.object) {\r\n let name = o.name.split('/')[o.name.split('/').length-1]\r\n let e = {\r\n name,\r\n isDirectory: (o.type===1),\r\n path: o.name,\r\n updatedAt: new Date(+o.time).toISOString(),\r\n size: +o.size,\r\n ...(o.type===0? {class:'file'}:{})\r\n }\r\n let i = files.current.findIndex(f => f.path === e.path)\r\n if (i>=0)\r\n files.current[i]=e\r\n else\r\n files.current.push(e)\r\n }\r\n setStateFiles([...files.current])\r\n }\r\n else {\r\n addMessage( SignalMessageLevelEnum.ERROR, content.text || content.message)\r\n }\r\n break\r\n case FilemanCommandEnum.RENAME: {\r\n let content = JSON.parse(response.data)\r\n if (content.status!=='Success') addMessage( SignalMessageLevelEnum.ERROR, content.text || content.message)\r\n }\r\n break\r\n case FilemanCommandEnum.DELETE: {\r\n let content = JSON.parse(response.data)\r\n if (content.status==='Success') {\r\n let fname = content.metadata.object\r\n files.current = files.current.filter(f => f.path !== fname)\r\n files.current = files.current.filter(f => !f.path.startsWith(fname+'/'))\r\n setStateFiles([...files.current])\r\n }\r\n else {\r\n addMessage( SignalMessageLevelEnum.ERROR, content.text || content.message)\r\n }\r\n break\r\n }\r\n case FilemanCommandEnum.MOVE:\r\n case FilemanCommandEnum.COPY:\r\n case FilemanCommandEnum.CREATE: {\r\n let content = JSON.parse(response.data)\r\n if (content.status==='Success') {\r\n //filemanData.files = filemanData.files.filter(f => f.path !== content.metadata.object)\r\n let f = { \r\n name: (content.metadata.object as string).split('/').slice(-1)[0],\r\n isDirectory: (content.metadata.type===1),\r\n path: content.metadata.object,\r\n updatedAt: new Date(+content.metadata.time).toISOString(), \r\n size: +content.metadata.size,\r\n ...(content.metadata.type.type===0? {class:'file'}:{})\r\n }\r\n files.current.push(f)\r\n setStateFiles([...files.current])\r\n }\r\n else {\r\n addMessage( SignalMessageLevelEnum.ERROR, content.text || content.message)\r\n }\r\n break\r\n }\r\n }\r\n }\r\n break\r\n }\r\n break\r\n }\r\n case InstanceMessageTypeEnum.SIGNAL:\r\n let signalMessage = JSON.parse(wsEvent.data) as ISignalMessage\r\n if (signalMessage.flow === InstanceMessageFlowEnum.RESPONSE) {\r\n if (signalMessage.action === InstanceMessageActionEnum.START) {\r\n if (signalMessage.text) addMessage(SignalMessageLevelEnum.INFO, signalMessage.text)\r\n instance.current = signalMessage.instance\r\n }\r\n else {\r\n addMessage( SignalMessageLevelEnum.ERROR, wsEvent.data)\r\n }\r\n }\r\n else if (signalMessage.flow === InstanceMessageFlowEnum.UNSOLICITED) {\r\n let cluster = validClusters.find(cluster => cluster.name===selectedClusterName)\r\n if (cluster) {\r\n let accessKey = cluster.accessKeys.get('fileman$read')\r\n if (accessKey && instance?.current) {\r\n if (signalMessage.event === SignalMessageEventEnum.ADD) {\r\n let filemanMessage:IFilemanMessage = {\r\n flow: InstanceMessageFlowEnum.REQUEST,\r\n action: InstanceMessageActionEnum.COMMAND,\r\n channel: 'fileman',\r\n type: InstanceMessageTypeEnum.DATA,\r\n accessKey: accessKeySerialize(accessKey),\r\n instance: instance.current,\r\n id: uuid(),\r\n command: FilemanCommandEnum.HOME,\r\n namespace: signalMessage.namespace!,\r\n group: '',\r\n pod: signalMessage.pod!,\r\n container: signalMessage.container!,\r\n params: [],\r\n msgtype: 'filemanmessage'\r\n }\r\n let payload = JSON.stringify( filemanMessage )\r\n wsEvent.target.send(payload)\r\n if (signalMessage.text) addMessage( SignalMessageLevelEnum.INFO, signalMessage.text)\r\n }\r\n }\r\n else {\r\n addMessage( SignalMessageLevelEnum.INFO, 'Have no instance/accessKey')\r\n }\r\n }\r\n else {\r\n addMessage( SignalMessageLevelEnum.INFO, 'Have no cluster')\r\n }\r\n }\r\n break\r\n\r\n default:\r\n console.log(`Invalid message type ${msg.type}`)\r\n break\r\n }\r\n }\r\n\r\n const addMessage = (level:SignalMessageLevelEnum, text:string) => {\r\n alertApi.post({ message: text, severity: level, display:'transient' }) \r\n setStatusMessages ((prev) => [...prev, {\r\n level,\r\n text,\r\n type: InstanceMessageTypeEnum.SIGNAL,\r\n }])\r\n }\r\n\r\n const websocketOnMessage = (wsEvent:any) => {\r\n let instanceMessage:IInstanceMessage\r\n try {\r\n instanceMessage = JSON.parse(wsEvent.data) as IInstanceMessage\r\n }\r\n catch (err) {\r\n console.log(err)\r\n console.log(wsEvent.data)\r\n return\r\n }\r\n\r\n switch(instanceMessage.channel) {\r\n case 'fileman':\r\n processFilemanMessage(wsEvent)\r\n break\r\n default:\r\n addMessage (SignalMessageLevelEnum.ERROR, 'Invalid channel in message: '+instanceMessage.channel)\r\n addMessage (SignalMessageLevelEnum.ERROR, 'Invalid message: '+JSON.stringify(instanceMessage))\r\n break\r\n }\r\n }\r\n\r\n const websocketOnOpen = (ws:WebSocket) => {\r\n setWebSocket(ws)\r\n let cluster=validClusters.find(cluster => cluster.name === selectedClusterName)\r\n if (!cluster) {\r\n addMessage(SignalMessageLevelEnum.ERROR,'No cluster selected')\r\n return\r\n }\r\n let pods = cluster.pods.filter(p => selectedNamespaces.includes(p.namespace))\r\n if (!pods) {\r\n addMessage(SignalMessageLevelEnum.ERROR,'No pods found')\r\n return\r\n }\r\n console.log(`WS connected`)\r\n let accessKey = cluster.accessKeys.get('fileman$read')\r\n if (accessKey) {\r\n let containers:string[] = []\r\n if (selectedContainerNames.length>0) {\r\n for(var p of selectedPodNames) {\r\n for (var c of selectedContainerNames) {\r\n containers.push(p+'+'+c)\r\n }\r\n }\r\n }\r\n let iConfig:IInstanceConfig = {\r\n channel: 'fileman',\r\n objects: InstanceConfigObjectEnum.PODS,\r\n action: InstanceMessageActionEnum.START,\r\n flow: InstanceMessageFlowEnum.REQUEST,\r\n instance: '',\r\n accessKey: accessKeySerialize(accessKey),\r\n scope: 'fileman$read',\r\n view: (selectedContainerNames.length > 0 ? InstanceConfigViewEnum.CONTAINER : InstanceConfigViewEnum.POD),\r\n namespace: selectedNamespaces.join(','),\r\n group: '',\r\n pod: selectedPodNames.map(p => p).join(','),\r\n container: containers.join(','),\r\n data: {},\r\n type: InstanceMessageTypeEnum.SIGNAL\r\n }\r\n ws.send(JSON.stringify(iConfig))\r\n }\r\n else {\r\n addMessage(SignalMessageLevelEnum.ERROR,'No accessKey for starting fileman streaming')\r\n return\r\n }\r\n }\r\n\r\n const startFilemanViewer = () => {\r\n let cluster=validClusters.find(cluster => cluster.name===selectedClusterName);\r\n if (!cluster) {\r\n addMessage(SignalMessageLevelEnum.ERROR,'No cluster selected')\r\n return\r\n }\r\n\r\n try {\r\n let ws = new WebSocket(cluster.url)\r\n ws.onopen = () => websocketOnOpen(ws)\r\n ws.onmessage = (event) => websocketOnMessage(event)\r\n ws.onclose = (event) => websocketOnClose(event)\r\n setWebSocket(ws)\r\n }\r\n catch (err) {\r\n }\r\n\r\n }\r\n\r\n const websocketOnClose = (_event:any) => {\r\n console.log(`WS disconnected`)\r\n setStarted(false)\r\n paused.current=false\r\n setStopped(true)\r\n }\r\n\r\n const stopFilemanViewer = () => {\r\n webSocket?.close()\r\n }\r\n\r\n const actionButtons = () => {\r\n let hasKey=false\r\n let cluster=validClusters.find(cluster => cluster.name===selectedClusterName)\r\n if (cluster) {\r\n hasKey = Boolean(cluster.accessKeys.get('fileman$read'))\r\n }\r\n\r\n return <>\r\n <IconButton onClick={() => clickStart()} title=\"Play\" disabled={started || !paused || selectedPodNames.length === 0 || !hasKey}>\r\n <PlayIcon />\r\n </IconButton>\r\n <IconButton onClick={onClickPause} title=\"Pause\" disabled={!((started && !paused.current) && selectedPodNames.length > 0)}>\r\n <PauseIcon />\r\n </IconButton>\r\n <IconButton onClick={onClickStop} title=\"Stop\" disabled={stopped || selectedPodNames.length === 0}>\r\n <StopIcon />\r\n </IconButton>\r\n </>\r\n }\r\n\r\n const statusButtons = (title:string) => {\r\n const show = (level:SignalMessageLevelEnum) => {\r\n setShowStatusDialog(true)\r\n setStatusLevel(level)\r\n }\r\n\r\n const prepareText = (txt:string|undefined) => {\r\n return txt? (txt.length>25? txt.substring(0,25)+\"...\":txt) : 'N/A'\r\n }\r\n\r\n return (\r\n <Grid container direction='row' >\r\n <Grid item>\r\n <Typography variant='h5'>{prepareText(title)}</Typography>\r\n </Grid>\r\n <Grid item style={{marginTop:'-8px'}}>\r\n <IconButton title=\"info\" disabled={!statusMessages.some(m=>m.type === InstanceMessageTypeEnum.SIGNAL && m.level=== SignalMessageLevelEnum.INFO)} onClick={() => show(SignalMessageLevelEnum.INFO)}>\r\n <InfoIcon style={{ color:statusMessages.some(m=>m.type === InstanceMessageTypeEnum.SIGNAL && m.level=== SignalMessageLevelEnum.INFO)?'blue':'#BDBDBD'}}/>\r\n </IconButton>\r\n <IconButton title=\"warning\" disabled={!statusMessages.some(m=>m.type === InstanceMessageTypeEnum.SIGNAL && m.level=== SignalMessageLevelEnum.WARNING)} onClick={() => show(SignalMessageLevelEnum.WARNING)} style={{marginLeft:'-16px'}}>\r\n <WarningIcon style={{ color:statusMessages.some(m=>m.type === InstanceMessageTypeEnum.SIGNAL && m.level=== SignalMessageLevelEnum.WARNING)?'orange':'#BDBDBD'}}/>\r\n </IconButton>\r\n <IconButton title=\"error\" disabled={!statusMessages.some(m=>m.type === InstanceMessageTypeEnum.SIGNAL && m.level=== SignalMessageLevelEnum.ERROR)} onClick={() => show(SignalMessageLevelEnum.ERROR)} style={{marginLeft:'-16px'}}>\r\n <ErrorIcon style={{ color:statusMessages.some(m=>m.type === InstanceMessageTypeEnum.SIGNAL && m.level=== SignalMessageLevelEnum.ERROR)?'red':'#BDBDBD'}}/>\r\n </IconButton>\r\n </Grid>\r\n </Grid>\r\n )\r\n }\r\n\r\n const statusClear = (level: SignalMessageLevelEnum) => {\r\n setStatusMessages(statusMessages.filter(m=> m.level!==level))\r\n setShowStatusDialog(false)\r\n }\r\n\r\n const onError = (error: IError, _file: IFileData) => {\r\n addMessage( SignalMessageLevelEnum.ERROR, error.message)\r\n }\r\n\r\n const onRename\t= (file: IFileData, newName: string) => {\r\n let [namespace,pod,container] = file.path.split('/').slice(1)\r\n //filemanData.files = filemanData.files.filter (f => f.path!==file.path)\r\n files.current = files.current.filter (f => f.path!==file.path)\r\n setStateFiles([...files.current])\r\n sendCommand(FilemanCommandEnum.RENAME, namespace, pod, container, [file.path, newName])\r\n }\r\n\r\n const onRefresh = () => {\r\n if (level >= 3) {\r\n files.current = files.current.filter ( f => !f.path.startsWith(currentPath+'/'))\r\n //files.current = files.current.filter ( f => f.path!==currentPath)\r\n getLocalDir(currentPath+'/')\r\n }\r\n else {\r\n sendCommand(FilemanCommandEnum.HOME, '', '', '', [])\r\n }\r\n\r\n }\r\n \r\n const getLocalDir = (folder:string) => {\r\n let cluster = validClusters.find(cluster => cluster.name===selectedClusterName)\r\n if (cluster) {\r\n let accessKey = cluster.accessKeys.get('fileman$read')\r\n if (accessKey && instance?.current && webSocket) {\r\n let [namespace,pod,container] = folder.split('/').slice(1)\r\n let filemanMessage:IFilemanMessage = {\r\n flow: InstanceMessageFlowEnum.REQUEST,\r\n action: InstanceMessageActionEnum.COMMAND,\r\n channel: 'fileman',\r\n type: InstanceMessageTypeEnum.DATA,\r\n accessKey: accessKeySerialize(accessKey),\r\n instance: instance.current,\r\n id: uuid(),\r\n command: FilemanCommandEnum.DIR,\r\n namespace: namespace,\r\n group: '',\r\n pod: pod,\r\n container: container,\r\n params: [folder],\r\n msgtype: 'filemanmessage'\r\n }\r\n let payload = JSON.stringify(filemanMessage)\r\n webSocket.send(payload)\r\n }\r\n }\r\n }\r\n\r\n const sendCommand = (command: FilemanCommandEnum, namespace:string, pod:string, container:string, params:string[]) => {\r\n let cluster = validClusters.find(cluster => cluster.name===selectedClusterName)\r\n if (cluster) {\r\n let accessKey = cluster.accessKeys.get('fileman$read')\r\n if (accessKey && instance?.current && webSocket) { \r\n let filemanMessage:IFilemanMessage = {\r\n flow: InstanceMessageFlowEnum.REQUEST,\r\n action: InstanceMessageActionEnum.COMMAND,\r\n channel: 'fileman',\r\n type: InstanceMessageTypeEnum.DATA,\r\n accessKey: accessKeySerialize(accessKey),\r\n instance: instance.current,\r\n id: uuid(),\r\n command: command,\r\n namespace: namespace,\r\n group: '',\r\n pod: pod,\r\n container: container,\r\n params: params,\r\n msgtype: 'filemanmessage'\r\n }\r\n let payload = JSON.stringify( filemanMessage )\r\n webSocket.send(payload)\r\n }\r\n else {\r\n addMessage( SignalMessageLevelEnum.ERROR, 'Have no instance/accessKey')\r\n }\r\n }\r\n else {\r\n addMessage( SignalMessageLevelEnum.ERROR, 'Have no cluster')\r\n }\r\n }\r\n\r\n const onDelete = async (filesToDelete: IFileData[]) => {\r\n for (let file of filesToDelete) {\r\n let [namespace,pod,container] = file.path.split('/').slice(1)\r\n sendCommand(FilemanCommandEnum.DELETE, namespace, pod, container, [file.path])\r\n }\r\n }\r\n\r\n const onCreateFolder = async (name: string, parentFolder: IFileData) => {\r\n let [namespace,pod,container] = parentFolder.path.split('/').slice(1)\r\n sendCommand(FilemanCommandEnum.CREATE, namespace, pod, container, [parentFolder.path + '/' + name])\r\n }\r\n\r\n const onDownload = async (filesToDownload: Array<IFileData>) => {\r\n let cluster = validClusters.find(cluster => cluster.name===selectedClusterName)\r\n if (cluster) {\r\n let accessKey = cluster.accessKeys.get('fileman$read')\r\n if (accessKey) {\r\n\r\n for (let file of filesToDownload) {\r\n const url = `${cluster.url}/channel/fileman/download?key=${instance.current}&filename=${file.path}`\r\n \r\n try {\r\n const response = await fetch(url, { headers: { 'Authorization': 'Bearer '+ accessKeySerialize(accessKey) } })\r\n\r\n if (response.ok) {\r\n const blob = await response.blob()\r\n\r\n const link = document.createElement('a')\r\n link.href = URL.createObjectURL(blob)\r\n link.download = file.path.split('/').slice(-1)[0]\r\n if (file.isDirectory) link.download += '.tar.gz'\r\n document.body.appendChild(link)\r\n link.click()\r\n document.body.removeChild(link)\r\n URL.revokeObjectURL(link.href)\r\n }\r\n else {\r\n console.error(`Error downloading file: ${file.path}`)\r\n addMessage( SignalMessageLevelEnum.ERROR, `Error downloading file ${file.path}: (${response.status}) ${await response.text()}`)\r\n }\r\n }\r\n catch (error) {\r\n console.error(`Error downloading file: ${file.path}`, error)\r\n addMessage( SignalMessageLevelEnum.ERROR, `Error downloading file ${file.path}: ${error}`)\r\n }\r\n }\r\n }\r\n else {\r\n addMessage( SignalMessageLevelEnum.ERROR, 'Have no instance/accessKey')\r\n }\r\n }\r\n else {\r\n addMessage( SignalMessageLevelEnum.ERROR, 'Have no cluster')\r\n }\r\n }\r\n\r\n const onPaste = (filesToPaste: Array<IFileData>, destFolder:IFileData, operation:string) => {\r\n let command = operation==='move'? FilemanCommandEnum.MOVE : FilemanCommandEnum.COPY\r\n for (let file of filesToPaste) {\r\n let [namespace,pod,container] = file.path.split('/').slice(1)\r\n sendCommand(command, namespace, pod, container, [file.path, destFolder.path])\r\n } \r\n }\r\n\r\n const onFolderChange = (folder:string) => {\r\n setCurrentPath(folder)\r\n folder +='/'\r\n let level = folder.split('/').length - 1\r\n if (level > 3) getLocalDir(folder)\r\n }\r\n\r\n const onFileUploading = (file: IFileData, _parentFolder: IFileData) => { \r\n return { filename: currentPath + '/' + file.name }\r\n }\r\n\r\n return (<>\r\n\r\n { loading && <Progress/> }\r\n\r\n {!isKwirthAvailable(entity) && !loading && error && (\r\n <WarningPanel title={'An error has ocurred while obtaining data from kuebernetes clusters.'} message={error?.message} />\r\n )}\r\n\r\n {!isKwirthAvailable(entity) && !loading && (\r\n <MissingAnnotationEmptyState readMoreUrl='https://github.com/jfvilas/plugin-kwirth-fileman' annotation={[ANNOTATION_BACKSTAGE_KUBERNETES_LABELID, ANNOTATION_BACKSTAGE_KUBERNETES_LABELSELECTOR]}/>\r\n )}\r\n\r\n { isKwirthAvailable(entity) && !loading && validClusters && validClusters.length===0 &&\r\n <ComponentNotFound error={ErrorType.NO_CLUSTERS} entity={entity}/>\r\n }\r\n\r\n { isKwirthAvailable(entity) && !loading && validClusters && validClusters.length>0 && validClusters.reduce((sum,cluster) => sum+cluster.pods.length, 0)===0 &&\r\n <ComponentNotFound error={ErrorType.NO_PODS} entity={entity}/>\r\n }\r\n\r\n { isKwirthAvailable(entity) && !loading && validClusters && validClusters.length>0 && validClusters.reduce((sum,cluster) => sum+cluster.pods.length, 0)>0 &&\r\n <Box sx={{ display: 'flex', height:'100%'}}>\r\n <Box sx={{ width: '200px', maxWidth:'200px'}}>\r\n <Grid container direction='column'>\r\n <Grid item> \r\n <Card>\r\n <ClusterList resources={validClusters} selectedClusterName={selectedClusterName} onSelect={onSelectCluster}/>\r\n </Card>\r\n </Grid>\r\n {!props.hideVersion &&\r\n <Grid item>\r\n <Card>\r\n <KwirthNews latestVersions={backendInfo} backendVersion={backendVersion} ownVersion={VERSION}/>\r\n </Card>\r\n </Grid>\r\n }\r\n </Grid>\r\n </Box>\r\n\r\n <Box sx={{ flexGrow: 1, flex:1, overflow:'hidden', p:1, marginLeft:'8px' }}>\r\n\r\n { !selectedClusterName && \r\n <img src={LogoIcon} style={{ left:'40%', marginTop:'10%', width:'20%', position:'relative' }} />\r\n }\r\n\r\n { selectedClusterName && <>\r\n <Card style={{ marginTop:-8, marginBottom:'8px' }}>\r\n <CardHeader\r\n title={statusButtons(selectedClusterName)}\r\n style={{marginTop:-4, marginBottom:4, flexShrink:0}}\r\n action={actionButtons()}\r\n />\r\n </Card>\r\n { started && <Grid ref={filemanBoxRef} style={{height: `calc(100vh - ${filemanBoxTop}px - 35px)`}}>\r\n <FileManager \r\n className={styles.customFm}\r\n files={stateFiles}\r\n filePreviewPath='http://avoid-console-error'\r\n primaryColor='#1976d2'\r\n fontFamily='\"Helvetica Neue\", Helvetica, Roboto, Arial, sans-serif'\r\n height='100%'\r\n actions={new Map()}\r\n icons={icons} \r\n fileUploadConfig={fileUploadConfig}\r\n onCreateFolder={onCreateFolder}\r\n onError={onError}\r\n onRename={onRename}\r\n onPaste={onPaste}\r\n onDelete={onDelete}\r\n onFolderChange={onFolderChange}\r\n onRefresh={onRefresh}\r\n onFileUploading={onFileUploading}\r\n onDownload={onDownload}\r\n enableFilePreview={false}\r\n initialPath={''}\r\n permissions={permissions}\r\n />\r\n </Grid>}\r\n </>}\r\n </Box>\r\n </Box>\r\n }\r\n { showStatusDialog && <StatusLog level={statusLevel} onClose={() => setShowStatusDialog(false)} statusMessages={statusMessages} onClear={statusClear}/>}\r\n </>)\r\n}\r\n"],"names":["cluster","FilemanCommandEnum","content","uuid","level","p","error"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"EntityKwirthFilemanContent.esm.js","sources":["../../src/components/EntityKwirthFilemanContent.tsx"],"sourcesContent":["/*\r\nCopyright 2025 Julio Fernandez\r\n\r\nLicensed under the Apache License, Version 2.0 (the \"License\");\r\nyou may not use this file except in compliance with the License.\r\nYou may obtain a copy of the License at\r\n\r\n http://www.apache.org/licenses/LICENSE-2.0\r\n\r\nUnless required by applicable law or agreed to in writing, software\r\ndistributed under the License is distributed on an \"AS IS\" BASIS,\r\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\nSee the License for the specific language governing permissions and\r\nlimitations under the License.\r\n*/\r\nimport React, { useEffect, useRef, useState } from 'react'\r\nimport { v4 as uuid } from 'uuid'\r\nimport useAsync from 'react-use/esm/useAsync'\r\n\r\nimport { Progress, WarningPanel } from '@backstage/core-components'\r\nimport { alertApiRef, useApi } from '@backstage/core-plugin-api'\r\nimport { ANNOTATION_BACKSTAGE_KUBERNETES_LABELID, ANNOTATION_BACKSTAGE_KUBERNETES_LABELSELECTOR, isKwirthAvailable, ClusterValidPods, IStatusLine, getPodList, getContainerList, IBackendInfo } from '@jfvilas/plugin-kwirth-common'\r\nimport { MissingAnnotationEmptyState, useEntity } from '@backstage/plugin-catalog-react'\r\n\r\n// kwirth\r\nimport { kwirthFilemanApiRef } from '../api'\r\nimport { accessKeySerialize, IInstanceMessage, IInstanceConfig, ISignalMessage, EInstanceMessageType, EInstanceMessageAction, EInstanceMessageFlow, ESignalMessageEvent, EInstanceConfigObject, EInstanceConfigView, ESignalMessageLevel } from '@jfvilas/kwirth-common'\r\n\r\n// kwirth fileman components\r\nimport { KwirthNews, ComponentNotFound, StatusLog, ClusterList, ErrorType } from '@jfvilas/plugin-kwirth-frontend'\r\nimport { FileManager, IError } from '@jfvilas/react-file-manager'\r\nimport { VERSION } from '../version'\r\n\r\n// Material-UI\r\nimport { Grid, Card, CardHeader, Box, IconButton, Typography } from '@material-ui/core'\r\n\r\n// styles\r\nimport '@jfvilas/react-file-manager/dist/style.css'\r\nimport styles from './custom-fm.module.css'\r\n\r\n// Icons\r\nimport PlayIcon from '@material-ui/icons/PlayArrow'\r\nimport PauseIcon from '@material-ui/icons/Pause'\r\nimport StopIcon from '@material-ui/icons/Stop'\r\nimport InfoIcon from '@material-ui/icons/Info'\r\nimport WarningIcon from '@material-ui/icons/Warning'\r\nimport ErrorIcon from '@material-ui/icons/Error'\r\nimport LogoIcon from '../assets/kwirthfileman-logo.svg'\r\nimport SvgIconNamespace from'./icons/ns.svg'\r\nimport SvgIconPod from'./icons/pod.svg'\r\nimport SvgIconContainer from'./icons/docker-mark-blue.svg'\r\n\r\nexport interface IEntityKwirthFilemanProps {\r\n hideVersion?: boolean\r\n excludeContainers?: string[]\r\n}\r\n\r\n\r\nconst NamespaceIcon = (props: {height?:number}) => { return <img src={SvgIconNamespace} alt='ns' height={`${props.height||16}px`}/> }\r\nconst PodIcon = (props: {height?:number}) => { return <img src={SvgIconPod} alt='pod' height={`${props.height||16}px`}/> }\r\nconst ContainerIcon = (props: {height?:number}) => { return <img src={SvgIconContainer} height={`${props.height||16}px`}/> }\r\n\r\nexport const EntityKwirthFilemanContent: React.FC<IEntityKwirthFilemanProps> = (props:IEntityKwirthFilemanProps) => { \r\n const { entity } = useEntity()\r\n const kwirthFilemanApi = useApi(kwirthFilemanApiRef)\r\n const alertApi = useApi(alertApiRef)\r\n const [validClusters, setResources] = useState<ClusterValidPods[]>([])\r\n const [selectedClusterName, setSelectedClusterName] = useState('')\r\n const [selectedNamespaces, setSelectedNamespaces] = useState<string[]>([])\r\n const [selectedPodNames, setSelectedPodNames] = useState<string[]>([])\r\n const [selectedContainerNames, setSelectedContainerNames] = useState<string[]>([])\r\n const [started, setStarted] = useState(false)\r\n const [stopped, setStopped] = useState(true)\r\n const paused=useRef<boolean>(false)\r\n const [statusMessages, setStatusMessages] = useState<IStatusLine[]>([])\r\n const [webSocket, setWebSocket] = useState<WebSocket>()\r\n const [showStatusDialog, setShowStatusDialog] = useState(false)\r\n const [statusLevel, setStatusLevel] = useState<ESignalMessageLevel>(ESignalMessageLevel.INFO)\r\n const [ backendVersion, setBackendVersion ] = useState<string>('')\r\n const [ backendInfo, setBackendInfo ] = useState<IBackendInfo>()\r\n const instance = useRef<string>()\r\n const [ stateFiles, setStateFiles ] = useState<IFileObject[]>([])\r\n const files = useRef<IFileObject[]>([])\r\n const [ currentPath, setCurrentPath] = useState('')\r\n const { loading, error } = useAsync ( async () => {\r\n if (backendVersion==='') setBackendVersion(await kwirthFilemanApi.getVersion())\r\n if (!backendInfo) setBackendInfo(await kwirthFilemanApi.getInfo())\r\n let reqScopes = ['fileman$read']\r\n let data:ClusterValidPods[] = await kwirthFilemanApi.requestAccess(entity, 'fileman', reqScopes)\r\n setResources(data)\r\n })\r\n const filemanBoxRef = useRef<HTMLDivElement | null>(null)\r\n const [filemanBoxTop, setFilemanBoxTop] = useState(0)\r\n const [ runningInstance, setRunningInstance] = useState<string|undefined>()\r\n let permissions={\r\n create: true,\r\n delete: true,\r\n download: true,\r\n copy: true,\r\n move: true,\r\n rename: true,\r\n upload: true\r\n }\r\n\r\n let icons = new Map()\r\n icons.set('namespace', { open:<NamespaceIcon height={18}/>, closed:<NamespaceIcon height={18}/>, grid:<NamespaceIcon height={40}/>, list:<NamespaceIcon height={18}/>, default:<NamespaceIcon height={18}/> })\r\n icons.set('pod', { open:<PodIcon height={18}/>, closed:<PodIcon height={18}/>, grid:<PodIcon height={40}/>, list:<PodIcon height={18}/>, default:<PodIcon height={18}/> })\r\n icons.set('container', { open:<ContainerIcon/>, closed:<ContainerIcon/>, grid:<ContainerIcon height={34}/>, list:<ContainerIcon height={16}/>, default:<ContainerIcon height={16}/> })\r\n\r\n interface IFileUploadConfig { \r\n url: string\r\n method?: \"POST\" | \"PUT\"\r\n headers?: { [key: string]: string }\r\n }\r\n let fileUploadConfig:IFileUploadConfig= {\r\n url: ''\r\n }\r\n\r\n let cluster = validClusters.find(cluster => cluster.name===selectedClusterName)\r\n if (cluster) {\r\n let accessKey = cluster.accessKeys.get('fileman$read')\r\n if (accessKey) {\r\n fileUploadConfig = {\r\n url: `${cluster.url}/${runningInstance}/channel/fileman/upload?key=${instance.current}`,\r\n method:'POST',\r\n headers: {\r\n 'Authorization': 'Bearer '+ accessKeySerialize(accessKey)\r\n }\r\n }\r\n }\r\n }\r\n \r\n let level = currentPath.split('/').length - 1\r\n if (level<3) {\r\n permissions = {\r\n create: false,\r\n delete: false,\r\n download: false,\r\n copy: false,\r\n move: false,\r\n rename: false,\r\n upload: false\r\n }\r\n }\r\n\r\n useEffect(() => {\r\n if (filemanBoxRef.current) setFilemanBoxTop(filemanBoxRef.current.getBoundingClientRect().top)\r\n })\r\n\r\n const clickStart = () => {\r\n if (!paused.current) {\r\n setStarted(true)\r\n paused.current=false\r\n setStopped(false)\r\n startFilemanViewer()\r\n }\r\n else {\r\n paused.current=false\r\n setStarted(true)\r\n }\r\n }\r\n\r\n const onClickPause = () => {\r\n setStarted(false)\r\n paused.current=true\r\n }\r\n\r\n const onClickStop = () => {\r\n setStarted(false)\r\n setStopped(true)\r\n paused.current=false\r\n stopFilemanViewer()\r\n }\r\n\r\n const onSelectCluster = (clusterName:string|undefined) => {\r\n if (started) onClickStop()\r\n if (clusterName) {\r\n setSelectedClusterName(clusterName)\r\n setSelectedPodNames([])\r\n setSelectedContainerNames([])\r\n setStatusMessages([])\r\n let cluster = validClusters.find(cluster => cluster.name === clusterName)\r\n\r\n if (cluster && cluster.pods) {\r\n let validNamespaces = Array.from(new Set(cluster.pods.map(pod => pod.namespace)))\r\n if (validNamespaces.length === 1) {\r\n setSelectedNamespaces(validNamespaces)\r\n let podList = getPodList (cluster.pods, validNamespaces)\r\n setSelectedPodNames(podList.map(pod => pod.name))\r\n setSelectedContainerNames(getContainerList(cluster.pods, validNamespaces, podList.map(pod => pod.name), props.excludeContainers || []))\r\n }\r\n else {\r\n setSelectedNamespaces([])\r\n }\r\n }\r\n }\r\n }\r\n\r\n interface IFileObject {\r\n name: string;\r\n displayName?: string;\r\n isDirectory: boolean;\r\n path: string;\r\n layout?: string;\r\n class?: string;\r\n children?: string|any;\r\n data?: any;\r\n categories?: string[];\r\n features?: string[];\r\n }\r\n\r\n enum FilemanCommandEnum {\r\n HOME = 'home',\r\n DIR = 'dir',\r\n CREATE = 'create',\r\n RENAME = 'rename',\r\n DELETE = 'delete',\r\n MOVE = 'move',\r\n COPY = 'copy',\r\n UPLOAD = 'upload',\r\n DOWNLOAD = 'download'\r\n }\r\n\r\n interface IFilemanMessage extends IInstanceMessage {\r\n msgtype: 'filemanmessage'\r\n id: string\r\n accessKey: string\r\n instance: string\r\n namespace: string\r\n group: string\r\n pod: string\r\n container: string\r\n command: FilemanCommandEnum\r\n params?: string[]\r\n }\r\n\r\n interface IFilemanMessageResponse extends IInstanceMessage {\r\n msgtype: 'filemanmessageresponse'\r\n id: string\r\n command: FilemanCommandEnum\r\n namespace: string\r\n group: string\r\n pod: string\r\n container: string\r\n data?: any\r\n }\r\n\r\n const processFilemanMessage = (wsEvent:any) => {\r\n let msg:IFilemanMessage = JSON.parse(wsEvent.data)\r\n\r\n switch (msg.type) {\r\n case EInstanceMessageType.DATA: {\r\n let response = JSON.parse(wsEvent.data) as IFilemanMessageResponse\r\n switch(response.action) {\r\n case EInstanceMessageAction.COMMAND: {\r\n switch(response.command) {\r\n case FilemanCommandEnum.HOME:\r\n let data = response.data as string[]\r\n let nss = Array.from (new Set (data.map(n => n.split('/')[0])))\r\n nss.forEach(ns => {\r\n if (!files.current.some(f => f.path === '/'+ ns)) {\r\n files.current.push ({ name: ns, isDirectory: true, path: '/'+ ns, class:'namespace' })\r\n }\r\n let podNames = Array.from (new Set (data.filter(a => a.split('/')[0]===ns).map(o => o.split('/')[1])))\r\n podNames.forEach(p => {\r\n if (!files.current.some(f => f.path === '/'+ns+'/'+p)) {\r\n files.current.push({ name: p, isDirectory: true, path: '/'+ns+'/'+p, class:'pod' })\r\n }\r\n let conts = Array.from (new Set (data.filter(a => a.split('/')[0]===ns && a.split('/')[1]===p).map(o => o.split('/')[2])))\r\n conts.forEach(c => {\r\n if (!files.current.some(f => f.path === '/'+ns+'/'+p+'/'+c)) {\r\n files.current.push ({ name: c, isDirectory: true, path: '/'+ns+'/'+p+'/'+c, class:'container' })\r\n }\r\n })\r\n })\r\n })\r\n // let data = response.data as string[]\r\n // let nss = Array.from (new Set (data.map(n => n.split('/')[0])))\r\n // nss.map(ns => {\r\n // if (!files.current.some(f => f.path === '/'+ ns)) {\r\n // files.current.push ({ name: ns, isDirectory: true, path: '/'+ ns, class:'namespace' }) \r\n // }\r\n // let podNames = Array.from (new Set (data.filter(a => a.split('/')[0]===ns).map(o => o.split('/')[1])))\r\n // podNames.map(p => {\r\n // if (!files.current.some(f => f.path === '/'+ns+'/'+p)) {\r\n // files.current.push ({ name: p, isDirectory: true, path: '/'+ns+'/'+p, class:'pod' })\r\n // }\r\n // let containers = Array.from (new Set (data.filter(a => a.split('/')[0]===ns && a.split('/')[1]===p).map(o => o.split('/')[2])))\r\n // containers = containers.filter(c => !props.excludeContainers?.includes(c))\r\n // containers.map(c => {\r\n // if (!files.current.some(f => f.path === '/'+ns+'/'+p+'/'+c)) {\r\n // files.current.push ({ name: c, isDirectory: true, path: '/'+ns+'/'+p+'/'+c, class:'container' })\r\n // }\r\n // })\r\n // })\r\n // })\r\n setStateFiles([...files.current])\r\n break\r\n case FilemanCommandEnum.DIR:\r\n let content = JSON.parse(response.data)\r\n if (content.status==='Success') {\r\n // for (let o of content.metadata.object) {\r\n // let name = o.name.split('/')[o.name.split('/').length-1]\r\n // let e = {\r\n // name,\r\n // isDirectory: (o.type===1),\r\n // path: o.name,\r\n // updatedAt: new Date(+o.time).toISOString(),\r\n // size: +o.size,\r\n // ...(o.type===0? {class:'file'}:{})\r\n // }\r\n // let i = files.current.findIndex(f => f.path === e.path)\r\n // if (i>=0)\r\n // files.current[i]=e\r\n // else\r\n // files.current.push(e)\r\n // }\r\n if (content.status!=='Success') {\r\n addMessage( ESignalMessageLevel.ERROR, content.text || content.message)\r\n }\r\n else {\r\n for (let o of content.metadata.object) {\r\n let name = o.name.split('/')[o.name.split('/').length-1]\r\n let e:IFileObject = { \r\n name,\r\n isDirectory: (o.type===1),\r\n path: o.name,\r\n data: {\r\n updatedAt: new Date(+o.time).toISOString(),\r\n size: +o.size,\r\n ...(o.type===0? {class:'file'}:{})\r\n }\r\n }\r\n files.current = files.current.filter(f => f.path !== e.path)\r\n files.current.push (e)\r\n }\r\n }\r\n setStateFiles([...files.current])\r\n }\r\n else {\r\n addMessage( ESignalMessageLevel.ERROR, content.text || content.message)\r\n }\r\n break\r\n case FilemanCommandEnum.RENAME: {\r\n let content = JSON.parse(response.data)\r\n if (content.status!=='Success') addMessage( ESignalMessageLevel.ERROR, content.text || content.message)\r\n }\r\n break\r\n case FilemanCommandEnum.DELETE: {\r\n let content = JSON.parse(response.data)\r\n if (content.status==='Success') {\r\n // let fname = content.metadata.object\r\n // files.current = files.current.filter(f => f.path !== fname)\r\n // files.current = files.current.filter(f => !f.path.startsWith(fname+'/'))\r\n let fname = content.metadata.object\r\n files.current = files.current.filter(f => f.path !== fname)\r\n files.current = files.current.filter(f => !f.path.startsWith(fname+'/'))\r\n setStateFiles([...files.current])\r\n }\r\n else {\r\n addMessage( ESignalMessageLevel.ERROR, content.text || content.message)\r\n }\r\n break\r\n }\r\n case FilemanCommandEnum.MOVE:\r\n case FilemanCommandEnum.COPY:\r\n case FilemanCommandEnum.CREATE: {\r\n let content = JSON.parse(response.data)\r\n if (content.status==='Success') {\r\n // let f = { \r\n // name: (content.metadata.object as string).split('/').slice(-1)[0],\r\n // isDirectory: (content.metadata.type===1),\r\n // path: content.metadata.object,\r\n // updatedAt: new Date(+content.metadata.time).toISOString(), \r\n // size: +content.metadata.size,\r\n // ...(content.metadata.type.type===0? {class:'file'}:{})\r\n // }\r\n // files.current.push(f)\r\n let e:IFileObject = { \r\n name: (content.metadata.object as string).split('/').slice(-1)[0],\r\n isDirectory: (content.metadata.type===1),\r\n path: content.metadata.object,\r\n data: {\r\n updatedAt: new Date(+content.metadata.time).toISOString(), \r\n size: +content.metadata.size,\r\n ...(content.metadata.type.type===0? {class:'file'}:{})\r\n }\r\n }\r\n files.current.push(e)\r\n setStateFiles([...files.current])\r\n }\r\n else {\r\n addMessage( ESignalMessageLevel.ERROR, content.text || content.message)\r\n }\r\n break\r\n }\r\n }\r\n }\r\n break\r\n }\r\n break\r\n }\r\n case EInstanceMessageType.SIGNAL:\r\n let signalMessage = JSON.parse(wsEvent.data) as ISignalMessage\r\n if (signalMessage.flow === EInstanceMessageFlow.RESPONSE) {\r\n switch(signalMessage.action) {\r\n case EInstanceMessageAction.START:\r\n if (signalMessage.text) addMessage(ESignalMessageLevel.INFO, signalMessage.text)\r\n instance.current = signalMessage.instance\r\n break\r\n case EInstanceMessageAction.RI:\r\n setRunningInstance(signalMessage.data)\r\n break\r\n case EInstanceMessageAction.COMMAND:\r\n if (signalMessage.text) addMessage(signalMessage.level, signalMessage.text)\r\n break\r\n default:\r\n addMessage( ESignalMessageLevel.ERROR, wsEvent.data)\r\n break\r\n }\r\n }\r\n else if (signalMessage.flow === EInstanceMessageFlow.UNSOLICITED) {\r\n let cluster = validClusters.find(cluster => cluster.name===selectedClusterName)\r\n if (cluster) {\r\n let accessKey = cluster.accessKeys.get('fileman$read')\r\n if (accessKey && instance?.current) {\r\n if (signalMessage.event === ESignalMessageEvent.ADD) {\r\n // request a RI id\r\n let instanceConfig:IInstanceMessage = {\r\n action: EInstanceMessageAction.RI,\r\n channel: 'fileman',\r\n flow: EInstanceMessageFlow.REQUEST,\r\n type: EInstanceMessageType.SIGNAL,\r\n instance: instance.current\r\n }\r\n wsEvent.target.send(JSON.stringify( instanceConfig ))\r\n\r\n // request HOME dir\r\n let filemanMessage:IFilemanMessage = {\r\n flow: EInstanceMessageFlow.REQUEST,\r\n action: EInstanceMessageAction.COMMAND,\r\n channel: 'fileman',\r\n type: EInstanceMessageType.DATA,\r\n accessKey: accessKeySerialize(accessKey),\r\n instance: instance.current,\r\n id: uuid(),\r\n command: FilemanCommandEnum.HOME,\r\n namespace: signalMessage.namespace!,\r\n group: '',\r\n pod: signalMessage.pod!,\r\n container: signalMessage.container!,\r\n params: [],\r\n msgtype: 'filemanmessage'\r\n }\r\n let payload = JSON.stringify( filemanMessage )\r\n wsEvent.target.send(payload)\r\n if (signalMessage.text) addMessage( ESignalMessageLevel.INFO, signalMessage.text)\r\n }\r\n }\r\n else {\r\n addMessage( ESignalMessageLevel.INFO, 'Have no instance/accessKey')\r\n }\r\n }\r\n else {\r\n addMessage( ESignalMessageLevel.INFO, 'Have no cluster')\r\n }\r\n }\r\n break\r\n\r\n default:\r\n console.log(`Invalid message type ${msg.type}`)\r\n break\r\n }\r\n }\r\n\r\n const addMessage = (level:ESignalMessageLevel, text:string) => {\r\n alertApi.post({ message: text, severity: level, display:'transient' }) \r\n setStatusMessages ((prev) => [...prev, {level, text, type: EInstanceMessageType.SIGNAL }])\r\n }\r\n\r\n const websocketOnMessage = (wsEvent:any) => {\r\n let instanceMessage:IInstanceMessage\r\n try {\r\n instanceMessage = JSON.parse(wsEvent.data) as IInstanceMessage\r\n }\r\n catch (err:any) {\r\n addMessage(ESignalMessageLevel.ERROR, err)\r\n console.log(err)\r\n console.log(wsEvent.data)\r\n return\r\n }\r\n\r\n switch(instanceMessage.channel) {\r\n case 'fileman':\r\n processFilemanMessage(wsEvent)\r\n break\r\n default:\r\n addMessage (ESignalMessageLevel.ERROR, 'Invalid channel in message: '+instanceMessage.channel)\r\n addMessage (ESignalMessageLevel.ERROR, 'Invalid message: '+JSON.stringify(instanceMessage))\r\n break\r\n }\r\n }\r\n\r\n const websocketOnOpen = (ws:WebSocket) => {\r\n setWebSocket(ws)\r\n let cluster=validClusters.find(cluster => cluster.name === selectedClusterName)\r\n if (!cluster) {\r\n addMessage(ESignalMessageLevel.ERROR,'No cluster selected')\r\n return\r\n }\r\n let pods = cluster.pods.filter(p => selectedNamespaces.includes(p.namespace))\r\n if (!pods) {\r\n addMessage(ESignalMessageLevel.ERROR,'No pods found')\r\n return\r\n }\r\n let accessKey = cluster.accessKeys.get('fileman$read')\r\n if (accessKey) {\r\n let containers:string[] = []\r\n if (selectedContainerNames.length>0) {\r\n for(var p of selectedPodNames) {\r\n for (var c of selectedContainerNames) {\r\n containers.push(p+'+'+c)\r\n }\r\n }\r\n }\r\n let iConfig:IInstanceConfig = {\r\n channel: 'fileman',\r\n objects: EInstanceConfigObject.PODS,\r\n action: EInstanceMessageAction.START,\r\n flow: EInstanceMessageFlow.REQUEST,\r\n instance: '',\r\n accessKey: accessKeySerialize(accessKey),\r\n scope: 'fileman$read',\r\n view: (selectedContainerNames.length > 0 ? EInstanceConfigView.CONTAINER : EInstanceConfigView.POD),\r\n namespace: selectedNamespaces.join(','),\r\n group: '',\r\n pod: selectedPodNames.map(p => p).join(','),\r\n container: containers.join(','),\r\n data: {},\r\n type: EInstanceMessageType.SIGNAL\r\n }\r\n ws.send(JSON.stringify(iConfig))\r\n }\r\n else {\r\n addMessage(ESignalMessageLevel.ERROR,'No accessKey for starting fileman streaming')\r\n return\r\n }\r\n }\r\n\r\n const startFilemanViewer = () => {\r\n let cluster=validClusters.find(cluster => cluster.name===selectedClusterName);\r\n if (!cluster) {\r\n addMessage(ESignalMessageLevel.ERROR,'No cluster selected')\r\n return\r\n }\r\n\r\n try {\r\n let ws = new WebSocket(cluster.url)\r\n ws.onopen = () => websocketOnOpen(ws)\r\n ws.onmessage = (event) => websocketOnMessage(event)\r\n ws.onclose = (event) => websocketOnClose(event)\r\n setWebSocket(ws)\r\n }\r\n catch (err) {\r\n }\r\n\r\n }\r\n\r\n const websocketOnClose = (_event:any) => {\r\n console.log(`WS disconnected`)\r\n setStarted(false)\r\n paused.current=false\r\n setStopped(true)\r\n }\r\n\r\n const stopFilemanViewer = () => {\r\n webSocket?.close()\r\n }\r\n\r\n const actionButtons = () => {\r\n let hasKey=false\r\n let cluster=validClusters.find(cluster => cluster.name===selectedClusterName)\r\n if (cluster) {\r\n hasKey = Boolean(cluster.accessKeys.get('fileman$read'))\r\n }\r\n\r\n return <>\r\n <IconButton onClick={() => clickStart()} title=\"Play\" disabled={started || !paused || selectedPodNames.length === 0 || !hasKey}>\r\n <PlayIcon />\r\n </IconButton>\r\n <IconButton onClick={onClickPause} title=\"Pause\" disabled={!((started && !paused.current) && selectedPodNames.length > 0)}>\r\n <PauseIcon />\r\n </IconButton>\r\n <IconButton onClick={onClickStop} title=\"Stop\" disabled={stopped || selectedPodNames.length === 0}>\r\n <StopIcon />\r\n </IconButton>\r\n </>\r\n }\r\n\r\n const statusButtons = (title:string) => {\r\n const show = (level:ESignalMessageLevel) => {\r\n setShowStatusDialog(true)\r\n setStatusLevel(level)\r\n }\r\n\r\n const prepareText = (txt:string|undefined) => {\r\n return txt? (txt.length>25? txt.substring(0,25)+\"...\":txt) : 'N/A'\r\n }\r\n\r\n return (\r\n <Grid container direction='row' >\r\n <Grid item>\r\n <Typography variant='h5'>{prepareText(title)}</Typography>\r\n </Grid>\r\n <Grid item style={{marginTop:'-8px'}}>\r\n <IconButton title=\"info\" disabled={!statusMessages.some(m=>m.type === EInstanceMessageType.SIGNAL && m.level=== ESignalMessageLevel.INFO)} onClick={() => show(ESignalMessageLevel.INFO)}>\r\n <InfoIcon style={{ color:statusMessages.some(m=>m.type === EInstanceMessageType.SIGNAL && m.level=== ESignalMessageLevel.INFO)?'#1D63ED':'#BDBDBD'}}/>\r\n </IconButton>\r\n <IconButton title=\"warning\" disabled={!statusMessages.some(m=>m.type === EInstanceMessageType.SIGNAL && m.level=== ESignalMessageLevel.WARNING)} onClick={() => show(ESignalMessageLevel.WARNING)} style={{marginLeft:'-16px'}}>\r\n <WarningIcon style={{ color:statusMessages.some(m=>m.type === EInstanceMessageType.SIGNAL && m.level=== ESignalMessageLevel.WARNING)?'orange':'#BDBDBD'}}/>\r\n </IconButton>\r\n <IconButton title=\"error\" disabled={!statusMessages.some(m=>m.type === EInstanceMessageType.SIGNAL && m.level=== ESignalMessageLevel.ERROR)} onClick={() => show(ESignalMessageLevel.ERROR)} style={{marginLeft:'-16px'}}>\r\n <ErrorIcon style={{ color:statusMessages.some(m=>m.type === EInstanceMessageType.SIGNAL && m.level=== ESignalMessageLevel.ERROR)?'red':'#BDBDBD'}}/>\r\n </IconButton>\r\n </Grid>\r\n </Grid>\r\n )\r\n }\r\n\r\n const statusClear = (level: ESignalMessageLevel) => {\r\n setStatusMessages(statusMessages.filter(m=> m.level!==level))\r\n setShowStatusDialog(false)\r\n }\r\n\r\n const onError = (error: IError, _file: IFileObject) => {\r\n addMessage( ESignalMessageLevel.ERROR, error.message)\r\n }\r\n\r\n const onRename\t= (file: IFileObject, newName: string) => {\r\n let [namespace,pod,container] = file.path.split('/').slice(1)\r\n //filemanData.files = filemanData.files.filter (f => f.path!==file.path)\r\n files.current = files.current.filter (f => f.path!==file.path)\r\n setStateFiles([...files.current])\r\n sendCommand(FilemanCommandEnum.RENAME, namespace, pod, container, [file.path, newName])\r\n }\r\n\r\n const onRefresh = () => {\r\n if (level >= 3) {\r\n files.current = files.current.filter ( f => !f.path.startsWith(currentPath+'/'))\r\n getLocalDir(currentPath+'/')\r\n }\r\n else {\r\n sendCommand(FilemanCommandEnum.HOME, '', '', '', [])\r\n }\r\n\r\n }\r\n \r\n const getLocalDir = (folder:string) => {\r\n let cluster = validClusters.find(cluster => cluster.name===selectedClusterName)\r\n if (cluster) {\r\n let accessKey = cluster.accessKeys.get('fileman$read')\r\n if (accessKey && instance?.current && webSocket) {\r\n let [namespace,pod,container] = folder.split('/').slice(1)\r\n let filemanMessage:IFilemanMessage = {\r\n flow: EInstanceMessageFlow.REQUEST,\r\n action: EInstanceMessageAction.COMMAND,\r\n channel: 'fileman',\r\n type: EInstanceMessageType.DATA,\r\n accessKey: accessKeySerialize(accessKey),\r\n instance: instance.current,\r\n id: uuid(),\r\n command: FilemanCommandEnum.DIR,\r\n namespace: namespace,\r\n group: '',\r\n pod: pod,\r\n container: container,\r\n params: [folder],\r\n msgtype: 'filemanmessage'\r\n }\r\n let payload = JSON.stringify(filemanMessage)\r\n webSocket.send(payload)\r\n }\r\n }\r\n }\r\n\r\n const sendCommand = (command: FilemanCommandEnum, namespace:string, pod:string, container:string, params:string[]) => {\r\n let cluster = validClusters.find(cluster => cluster.name===selectedClusterName)\r\n if (cluster) {\r\n let accessKey = cluster.accessKeys.get('fileman$read')\r\n if (accessKey && instance?.current && webSocket) { \r\n let filemanMessage:IFilemanMessage = {\r\n flow: EInstanceMessageFlow.REQUEST,\r\n action: EInstanceMessageAction.COMMAND,\r\n channel: 'fileman',\r\n type: EInstanceMessageType.DATA,\r\n accessKey: accessKeySerialize(accessKey),\r\n instance: instance.current,\r\n id: uuid(),\r\n command: command,\r\n namespace: namespace,\r\n group: '',\r\n pod: pod,\r\n container: container,\r\n params: params,\r\n msgtype: 'filemanmessage'\r\n }\r\n let payload = JSON.stringify( filemanMessage )\r\n webSocket.send(payload)\r\n }\r\n else {\r\n addMessage( ESignalMessageLevel.ERROR, 'Have no instance/accessKey')\r\n }\r\n }\r\n else {\r\n addMessage( ESignalMessageLevel.ERROR, 'Have no cluster')\r\n }\r\n }\r\n\r\n const onDelete = async (filesToDelete: IFileObject[]) => {\r\n for (let file of filesToDelete) {\r\n let [namespace,pod,container] = file.path.split('/').slice(1)\r\n sendCommand(FilemanCommandEnum.DELETE, namespace, pod, container, [file.path])\r\n }\r\n }\r\n\r\n const onCreateFolder = async (name: string, parentFolder: IFileObject) => {\r\n let [namespace,pod,container] = parentFolder.path.split('/').slice(1)\r\n sendCommand(FilemanCommandEnum.CREATE, namespace, pod, container, [parentFolder.path + '/' + name])\r\n }\r\n\r\n const onDownload = async (filesToDownload: Array<IFileObject>) => {\r\n let cluster = validClusters.find(cluster => cluster.name===selectedClusterName)\r\n if (cluster) {\r\n let accessKey = cluster.accessKeys.get('fileman$read')\r\n if (accessKey) {\r\n\r\n for (let file of filesToDownload) {\r\n const url = `${cluster.url}/${runningInstance}/channel/fileman/download?key=${instance.current}&filename=${file.path}`\r\n \r\n try {\r\n const response = await fetch(url, { headers: { 'Authorization': 'Bearer '+ accessKeySerialize(accessKey) } })\r\n\r\n if (response.ok) {\r\n const blob = await response.blob()\r\n\r\n const link = document.createElement('a')\r\n link.href = URL.createObjectURL(blob)\r\n link.download = file.path.split('/').slice(-1)[0]\r\n if (file.isDirectory) link.download += '.tar.gz'\r\n document.body.appendChild(link)\r\n link.click()\r\n document.body.removeChild(link)\r\n URL.revokeObjectURL(link.href)\r\n }\r\n else {\r\n console.error(`Error downloading file: ${file.path}`)\r\n addMessage( ESignalMessageLevel.ERROR, `Error downloading file ${file.path}: (${response.status}) ${await response.text()}`)\r\n }\r\n }\r\n catch (error) {\r\n console.error(`Error downloading file: ${file.path}`, error)\r\n addMessage( ESignalMessageLevel.ERROR, `Error downloading file ${file.path}: ${error}`)\r\n }\r\n }\r\n }\r\n else {\r\n addMessage( ESignalMessageLevel.ERROR, 'Have no instance/accessKey')\r\n }\r\n }\r\n else {\r\n addMessage( ESignalMessageLevel.ERROR, 'Have no cluster')\r\n }\r\n }\r\n\r\n const onPaste = (filesToPaste: Array<IFileObject>, destFolder:IFileObject, operation:string) => {\r\n let command = operation==='move'? FilemanCommandEnum.MOVE : FilemanCommandEnum.COPY\r\n for (let file of filesToPaste) {\r\n let [namespace,pod,container] = file.path.split('/').slice(1)\r\n sendCommand(command, namespace, pod, container, [file.path, destFolder.path])\r\n } \r\n }\r\n\r\n const onFolderChange = (folder:string) => {\r\n setCurrentPath(folder)\r\n folder +='/'\r\n let level = folder.split('/').length - 1\r\n if (level > 3) getLocalDir(folder)\r\n }\r\n\r\n const onFileUploading = (file: IFileObject, _parentFolder: IFileObject) => { \r\n return { filename: currentPath + '/' + file.name }\r\n }\r\n\r\n return (<>\r\n\r\n { loading && <Progress/> }\r\n\r\n {!isKwirthAvailable(entity) && !loading && error && (\r\n <WarningPanel title={'An error has ocurred while obtaining data from kuebernetes clusters.'} message={error?.message} />\r\n )}\r\n\r\n {!isKwirthAvailable(entity) && !loading && (\r\n <MissingAnnotationEmptyState readMoreUrl='https://github.com/jfvilas/plugin-kwirth-fileman' annotation={[ANNOTATION_BACKSTAGE_KUBERNETES_LABELID, ANNOTATION_BACKSTAGE_KUBERNETES_LABELSELECTOR]}/>\r\n )}\r\n\r\n { isKwirthAvailable(entity) && !loading && validClusters && validClusters.length===0 &&\r\n <ComponentNotFound error={ErrorType.NO_CLUSTERS} entity={entity}/>\r\n }\r\n\r\n { isKwirthAvailable(entity) && !loading && validClusters && validClusters.length>0 && validClusters.reduce((sum,cluster) => sum+cluster.pods.length, 0)===0 &&\r\n <ComponentNotFound error={ErrorType.NO_PODS} entity={entity}/>\r\n }\r\n\r\n { isKwirthAvailable(entity) && !loading && validClusters && validClusters.length>0 && validClusters.reduce((sum,cluster) => sum+cluster.pods.length, 0)>0 &&\r\n <Box sx={{ display: 'flex', height:'100%'}}>\r\n <Box sx={{ width: '200px', maxWidth:'200px'}}>\r\n <Grid container direction='column'>\r\n <Grid item> \r\n <Card>\r\n <ClusterList resources={validClusters} selectedClusterName={selectedClusterName} onSelect={onSelectCluster}/>\r\n </Card>\r\n </Grid>\r\n {!props.hideVersion &&\r\n <Grid item>\r\n <Card>\r\n <KwirthNews latestVersions={backendInfo} backendVersion={backendVersion} ownVersion={VERSION}/>\r\n </Card>\r\n </Grid>\r\n }\r\n </Grid>\r\n </Box>\r\n\r\n <Box sx={{ flexGrow: 1, flex:1, overflow:'hidden', p:1, marginLeft:'8px' }}>\r\n\r\n { !selectedClusterName && \r\n <img src={LogoIcon} style={{ left:'40%', marginTop:'10%', width:'20%', position:'relative' }} />\r\n }\r\n\r\n { selectedClusterName && <>\r\n <Card style={{ marginTop:-8, marginBottom:'8px' }}>\r\n <CardHeader\r\n title={statusButtons(selectedClusterName)}\r\n style={{marginTop:-4, marginBottom:4, flexShrink:0}}\r\n action={actionButtons()}\r\n />\r\n </Card>\r\n { started && <Grid ref={filemanBoxRef} style={{height: `calc(100vh - ${filemanBoxTop}px - 35px)`, borderRadius:'12px', overflow:'hidden'}}>\r\n \r\n <FileManager \r\n className={styles.customFm}\r\n files={stateFiles}\r\n filePreviewPath='http://avoid-console-error'\r\n primaryColor='#1976d2'\r\n fontFamily='\"Helvetica Neue\", Helvetica, Roboto, Arial, sans-serif'\r\n height='100%'\r\n actions={new Map()}\r\n icons={icons} \r\n fileUploadConfig={fileUploadConfig}\r\n onCreateFolder={onCreateFolder}\r\n onError={onError}\r\n onRename={onRename}\r\n onPaste={onPaste}\r\n onDelete={onDelete}\r\n onFolderChange={onFolderChange}\r\n onRefresh={onRefresh}\r\n onFileUploading={onFileUploading}\r\n onDownload={onDownload}\r\n enableFilePreview={false}\r\n initialPath={''}\r\n permissions={permissions}\r\n maxNavigationPaneLevel={3}\r\n minFileActionsLevel={3}\r\n showBreadcrumb={true}\r\n />\r\n </Grid>}\r\n </>}\r\n </Box>\r\n </Box>\r\n }\r\n { showStatusDialog && <StatusLog level={statusLevel} onClose={() => setShowStatusDialog(false)} statusMessages={statusMessages} onClear={statusClear}/>}\r\n </>)\r\n}\r\n"],"names":["cluster","FilemanCommandEnum","content","uuid","level","p","error"],"mappings":"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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import styleInject from '../node_modules_dist/style-inject/dist/style-inject.es.esm.js';
|
|
2
2
|
|
|
3
|
-
var css_248z = ".file-explorer {\r\n
|
|
3
|
+
var css_248z = ".file-explorer *::-webkit-scrollbar {\r\n width: 12px !important;\r\n height: 12px !important;\r\n display: block !important;\r\n}\r\n\r\n.file-explorer *::-webkit-scrollbar-thumb {\r\n border-radius: 10px !important;\r\n}\r\n\r\n\r\n/* --- ESTILOS MODO CLARO (POR DEFECTO) --- */\r\n.file-explorer {\r\n box-shadow: 0px 2px 4px rgba(0,0,0,0.1);\r\n background-color: #ffffff;\r\n border-radius: 4px;\r\n min-height: 150px;\r\n border: 1px solid #e0e0e0;\r\n color: #000000;\r\n}\r\n\r\n.file-explorer *::-webkit-scrollbar-track {\r\n background: #f0f0f0 !important;\r\n}\r\n\r\n.file-explorer *::-webkit-scrollbar-thumb {\r\n background: #cdcdcd !important;\r\n border: 2px solid #f0f0f0 !important;\r\n}\r\n\r\n.file-explorer *::-webkit-scrollbar-thumb:hover {\r\n background: #a6a6a6 !important;\r\n}\r\n\r\n.file-explorer .toolbar {\r\n border-top-right-radius: 4px;\r\n border-top-left-radius: 4px;\r\n min-height: 46px;\r\n background-color: #f5f5f5;\r\n border-bottom: 1px solid #e0e0e0;\r\n}\r\n\r\n.file-explorer .breadcrumb {\r\n padding-top: 10px;\r\n min-height: 36px;\r\n color: #666666;\r\n}\r\n\r\n.file-explorer .file-item,\r\n.file-explorer .sb-folder-name,\r\n.file-explorer .folder-name {\r\n font-size: 14px;\r\n color: #000000;\r\n padding: 2px;\r\n}\r\n\r\n.file-explorer .sb-folder-name,\r\n.file-explorer .folder-name {\r\n font-size: 14px;\r\n color: #000000;\r\n}\r\n\r\n.file-explorer .files .file-item-container:hover {\r\n background-color: rgba(0, 0, 0, 0.04);\r\n}\r\n\r\n/* --- ESTILOS MODO OSCURO (ACTIVADOS POR DATA-THEME-MODE) --- */\r\n\r\n[data-theme-mode='dark'] .file-explorer {\r\n background-color: #424242 !important;\r\n border-color: #333333 !important;\r\n border-radius: 4px;\r\n overflow: hidden;\r\n color: #e0e0e0 !important;\r\n}\r\n\r\n[data-theme-mode='dark'] .file-explorer .toolbar,\r\n[data-theme-mode='dark'] .file-explorer .grid,\r\n[data-theme-mode='dark'] .file-explorer .list,\r\n[data-theme-mode='dark'] .file-explorer .bread-crumb-container,\r\n[data-theme-mode='dark'] .file-explorer .search-input,\r\n[data-theme-mode='dark'] .file-explorer .statusbar,\r\n[data-theme-mode='dark'] .file-explorer .sidebar-resize,\r\n[data-theme-mode='dark'] .file-explorer .navigation-pane,\r\n[data-theme-mode='dark'] .file-explorer .fm-context-menu,\r\n[data-theme-mode='dark'] .file-explorer .fm-modal-header,\r\n[data-theme-mode='dark'] .file-explorer .fm-modal-heading,\r\n[data-theme-mode='dark'] .file-explorer .file-delete-confirm,\r\n[data-theme-mode='dark'] .file-explorer .file-rename-folder-action,\r\n[data-theme-mode='dark'] .file-explorer .fm-rename-folder-input,\r\n[data-theme-mode='dark'] .file-explorer .fm-rename-folder-container,\r\n[data-theme-mode='dark'] .file-explorer .file-delete-confirm-text,\r\n[data-theme-mode='dark'] .file-explorer .fm-modal,\r\n[data-theme-mode='dark'] .file-explorer .divider,\r\n[data-theme-mode='dark'] .file-explorer .files-header,\r\n[data-theme-mode='dark'] .file-explorer .toggle-view {\r\n background-color: #424242 !important;\r\n color: #e0e0e0 !important;\r\n border-color: rgba(255, 255, 255, 0.12) !important;\r\n}\r\n\r\n[data-theme-mode='dark'] .fm-context-menu .file-context-menu-list ul li,\r\n[data-theme-mode='dark'] .toggle-view ul li {\r\n color: #e0e0e0 !important;\r\n}\r\n\r\n[data-theme-mode='dark'] .fm-context-menu .file-context-menu-list ul li:hover,\r\n[data-theme-mode='dark'] .toggle-view ul li:hover {\r\n background-color: rgba(255, 255, 255, 0.1) !important;\r\n color: #ffffff !important;\r\n}\r\n\r\n[data-theme-mode='dark'] .file-explorer .file-item,\r\n[data-theme-mode='dark'] .file-explorer .sb-folder-name,\r\n[data-theme-mode='dark'] .file-explorer .folder-name,\r\n[data-theme-mode='dark'] .item-action {\r\n color: #ffffff !important;\r\n}\r\n\r\n[data-theme-mode='dark'] .file-explorer .column-header {\r\n width: calc(70% - 45px) !important;\r\n}\r\n\r\n[data-theme-mode='dark'] .file-explorer .files .file-item-container:hover {\r\n background-color: rgba(255, 255, 255, 0.08) !important;\r\n}\r\n\r\n[data-theme-mode='dark'] .file-explorer *::-webkit-scrollbar-track {\r\n background: #424242 !important; /* Fondo oscuro del explorador */\r\n}\r\n\r\n[data-theme-mode='dark'] .file-explorer *::-webkit-scrollbar-thumb {\r\n background: #555555 !important; /* Gris que resalte en oscuro */\r\n border: 2px solid #424242 !important;\r\n}\r\n\r\n[data-theme-mode='dark'] .file-explorer *::-webkit-scrollbar-thumb:hover {\r\n background: #777777 !important;\r\n}";
|
|
4
4
|
var styles = {};
|
|
5
5
|
styleInject(css_248z);
|
|
6
6
|
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import * as _backstage_core_plugin_api from '@backstage/core-plugin-api';
|
|
2
2
|
import { DiscoveryApi, FetchApi } from '@backstage/core-plugin-api';
|
|
3
|
+
import * as _backstage_frontend_plugin_api from '@backstage/frontend-plugin-api';
|
|
3
4
|
import { Entity } from '@backstage/catalog-model';
|
|
4
5
|
import { ClusterValidPods, IBackendInfo } from '@jfvilas/plugin-kwirth-common';
|
|
5
6
|
|
|
@@ -19,7 +20,7 @@ interface KwirthFilemanApi {
|
|
|
19
20
|
getVersion(): Promise<any>;
|
|
20
21
|
getInfo(): any;
|
|
21
22
|
}
|
|
22
|
-
declare const kwirthFilemanApiRef:
|
|
23
|
+
declare const kwirthFilemanApiRef: _backstage_frontend_plugin_api.ApiRef<KwirthFilemanApi>;
|
|
23
24
|
|
|
24
25
|
interface KwirthFilemanClientOptions {
|
|
25
26
|
discoveryApi: DiscoveryApi;
|
package/dist/version.esm.js
CHANGED
package/dist/version.esm.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"version.esm.js","sources":["../src/version.ts"],"sourcesContent":["export const VERSION:string=\"0.
|
|
1
|
+
{"version":3,"file":"version.esm.js","sources":["../src/version.ts"],"sourcesContent":["export const VERSION:string=\"0.14.2\"; \r\n"],"names":[],"mappings":"AAAO,MAAM,OAAA,GAAe;;;;"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jfvilas/plugin-kwirth-fileman",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.14.2",
|
|
4
4
|
"description": "Frontend plugin for doing visual file management on Kubernetes containers",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"Backstage",
|
|
@@ -64,21 +64,21 @@
|
|
|
64
64
|
"test": "backstage-cli package test"
|
|
65
65
|
},
|
|
66
66
|
"dependencies": {
|
|
67
|
-
"@backstage/catalog-model": "^1.7.
|
|
68
|
-
"@backstage/core-components": "^0.18.
|
|
69
|
-
"@backstage/core-plugin-api": "^1.12.
|
|
70
|
-
"@backstage/frontend-plugin-api": "^0.
|
|
71
|
-
"@backstage/integration-react": "^1.2.
|
|
72
|
-
"@backstage/plugin-auth-react": "^0.1.
|
|
73
|
-
"@backstage/plugin-catalog-react": "^1.
|
|
74
|
-
"@jfvilas/react-file-manager": "^1.
|
|
67
|
+
"@backstage/catalog-model": "^1.7.7",
|
|
68
|
+
"@backstage/core-components": "^0.18.8",
|
|
69
|
+
"@backstage/core-plugin-api": "^1.12.4",
|
|
70
|
+
"@backstage/frontend-plugin-api": "^0.15.1",
|
|
71
|
+
"@backstage/integration-react": "^1.2.16",
|
|
72
|
+
"@backstage/plugin-auth-react": "^0.1.25",
|
|
73
|
+
"@backstage/plugin-catalog-react": "^2.1.0",
|
|
74
|
+
"@jfvilas/react-file-manager": "^1.4.23",
|
|
75
75
|
"@material-ui/core": "^4.12.2",
|
|
76
76
|
"@material-ui/icons": "^4.9.1",
|
|
77
77
|
"@types/react": "^16.13.1 || ^17.0.0 || ^18.0.0",
|
|
78
78
|
"react-use": "^17.2.4"
|
|
79
79
|
},
|
|
80
80
|
"devDependencies": {
|
|
81
|
-
"@backstage/cli": "^0.
|
|
81
|
+
"@backstage/cli": "^0.36.0",
|
|
82
82
|
"@testing-library/dom": "^10.0.0",
|
|
83
83
|
"@testing-library/jest-dom": "^6.0.0",
|
|
84
84
|
"@testing-library/react": "^15.0.0",
|