n8n-nodes-soar 0.1.21 → 0.1.23
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/dist/common/asset.js +47 -58
- package/dist/common/connectionType.js +3 -2
- package/dist/common/executor/abstract.executor.js +51 -0
- package/dist/common/executor/docker.executor.js +57 -31
- package/dist/common/executor/jsonrpc.executor.js +123 -0
- package/dist/common/executor/{k8s.executor.js → kubernetes.executor.js} +56 -33
- package/dist/common/interface.js +4 -0
- package/dist/common/memorizer/abstract.memorizer.js +49 -0
- package/dist/common/memorizer/asset.memorizer.js +16 -0
- package/dist/common/memorizer/general.memorizer.js +17 -0
- package/dist/common/memorizer/storage/redis.storage.js +71 -0
- package/dist/common/proxy/abstract.proxy.js +4 -0
- package/dist/common/proxy/executor.proxy.js +50 -0
- package/dist/common/proxy/memorizer.proxy.js +51 -0
- package/dist/common/proxy/runner.proxy.js +60 -0
- package/dist/common/runner/container.runner.js +93 -108
- package/dist/common/runner/decorator/assetRunner.js +26 -0
- package/dist/common/runner/decorator/index.js +20 -0
- package/dist/common/runner/decorator/onlySuccess.js +20 -0
- package/dist/common/runner/{priority.js → decorator/priority.js} +16 -8
- package/dist/common/runner/priority.runner.js +6 -7
- package/dist/common/runner/runner.js +10 -29
- package/dist/constants/image.js +11 -0
- package/dist/credentials/SoarRunner/SoarRunner.credentials.js +73 -0
- package/dist/credentials/SoarRunner/icon.svg +8 -0
- package/dist/credentials/VulboxApi/VulboxApi.credentials.js +157 -0
- package/dist/credentials/VulboxApi/vulbox.svg +18 -0
- package/dist/nodes/Collector/Collector.node.js +56 -47
- package/dist/nodes/EmptyCheck/EmptyCheck.node.js +69 -0
- package/dist/nodes/Executor/DockerExecutor/DockerExecutor.node.js +80 -3
- package/dist/nodes/Executor/JsonRpcExecutor/JsonRpcExecutor.node.js +69 -0
- package/dist/nodes/Executor/JsonRpcExecutor/icon.svg +8 -0
- package/dist/nodes/Executor/KubernetesExecutor/KubernetesExecutor.node.js +112 -4
- package/dist/nodes/Fofa/Fofa.node.js +23 -14
- package/dist/nodes/Memorizer/Redis/RedisMemorizer.node.js +127 -0
- package/dist/nodes/Memorizer/Redis/redis.svg +1 -0
- package/dist/nodes/Platform/Vulbox/Vulbox.node.js +166 -0
- package/dist/nodes/Platform/Vulbox/api.js +211 -0
- package/dist/nodes/Platform/Vulbox/methods.js +124 -0
- package/dist/nodes/Platform/Vulbox/properties.js +403 -0
- package/dist/nodes/Platform/Vulbox/vulbox.svg +18 -0
- package/dist/nodes/Runner/Cmd/Cmd.node.js +105 -0
- package/dist/nodes/Runner/Dns/Dns.node.js +38 -22
- package/dist/nodes/Runner/Httpx/Httpx.node.js +147 -18
- package/dist/nodes/Runner/IcpLookup/IcpLookup.node.js +166 -0
- package/dist/nodes/Runner/IcpLookup/icp.svg +3 -0
- package/dist/nodes/Runner/Katana/Katana.node.js +42 -29
- package/dist/nodes/Runner/Masscan/Masscan.node.js +51 -29
- package/dist/nodes/Runner/Naabu/Naabu.node.js +35 -17
- package/dist/nodes/Runner/Nuclei/Nuclei.node.js +32 -14
- package/dist/nodes/Runner/Priority/Priority.node.js +2 -1
- package/dist/nodes/Runner/Subfinder/Subfinder.node.js +38 -15
- package/dist/nodes/Runner/Unauthor/Unauthor.node.js +32 -14
- package/dist/utils/decorator.js +22 -0
- package/package.json +19 -5
- package/dist/common/executor/executor.js +0 -48
- package/dist/nodes/Asset/SplitAsset/SplitAsset.node.js +0 -110
- package/dist/nodes/Asset/SplitAsset/split.svg +0 -13
- package/dist/nodes/Cdncheck/Cdncheck.node.js +0 -229
- package/dist/nodes/Httpx/Httpx.node.js +0 -754
- package/dist/nodes/Katana/Katana.node.js +0 -456
- package/dist/nodes/Katana/Katana.node.json +0 -9
- package/dist/nodes/Nuclei/Nuclei.node.js +0 -1024
- package/dist/nodes/Nuclei/Nuclei.node.json +0 -9
- package/dist/nodes/Runner/Katana/a.json +0 -30
- package/dist/nodes/Runner/Nuclei/a.json +0 -48
- package/dist/nodes/Runner/PriorityAdd/PriorityAdd.node.js +0 -97
- package/dist/nodes/Runner/Router/SwitchRouter/SwitchRouter.node.js +0 -101
- package/dist/nodes/Tshark/Tshark.node.js +0 -104
- package/dist/nodes/Tshark/Tshark.node.json +0 -9
- package/dist/nodes/Tshark/tshark.svg +0 -64
- package/dist/nodes/Unauthor/Unauthor.node.js +0 -135
- package/dist/nodes/Unauthor/Unauthor.node.json +0 -9
- package/dist/nodes/Unauthor/unauthor.svg +0 -7
- package/dist/nodes/Uncover/Uncover.node.js +0 -280
- package/dist/nodes/Uncover/Uncover.node.json +0 -9
package/dist/common/asset.js
CHANGED
@@ -48,6 +48,9 @@ class MissingPropertyError extends Error {
|
|
48
48
|
}
|
49
49
|
}
|
50
50
|
class Asset {
|
51
|
+
static fromPlain(plain) {
|
52
|
+
return (0, _classtransformer.plainToInstance)(Asset, plain);
|
53
|
+
}
|
51
54
|
getDomain() {
|
52
55
|
if (!this.basic.domain) {
|
53
56
|
throw new MissingPropertyError("basic.domain", this);
|
@@ -60,6 +63,12 @@ class Asset {
|
|
60
63
|
}
|
61
64
|
return this.basic.domain || this.basic.ip || "";
|
62
65
|
}
|
66
|
+
getIP() {
|
67
|
+
if (!this.basic.ip) {
|
68
|
+
throw new MissingPropertyError("basic.ip", this);
|
69
|
+
}
|
70
|
+
return this.basic.ip;
|
71
|
+
}
|
63
72
|
getPort() {
|
64
73
|
if (!this.basic.port) {
|
65
74
|
throw new MissingPropertyError("basic.port", this);
|
@@ -70,75 +79,55 @@ class Asset {
|
|
70
79
|
return `${this.getHost()}:${this.getPort()}`;
|
71
80
|
}
|
72
81
|
clone(patch) {
|
73
|
-
return
|
74
|
-
}
|
75
|
-
splitBySubdomains() {
|
76
|
-
if (this.subdomains?.length) {
|
77
|
-
return [
|
78
|
-
this,
|
79
|
-
...this.subdomains.map((n)=>{
|
80
|
-
return (0, _classtransformer.plainToInstance)(Asset, {
|
81
|
-
basic: {
|
82
|
-
host: n
|
83
|
-
},
|
84
|
-
metadata: this.metadata,
|
85
|
-
success: true
|
86
|
-
});
|
87
|
-
})
|
88
|
-
];
|
89
|
-
} else {
|
90
|
-
return [
|
91
|
-
this
|
92
|
-
];
|
93
|
-
}
|
82
|
+
return Asset.fromPlain(Object.assign({}, this, patch));
|
94
83
|
}
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
].map((n)=>{
|
101
|
-
return (0, _classtransformer.plainToInstance)(Asset, {
|
84
|
+
splitBySubdomains(subdomains) {
|
85
|
+
return [
|
86
|
+
this,
|
87
|
+
...subdomains.map((n)=>{
|
88
|
+
return Asset.fromPlain({
|
102
89
|
basic: {
|
103
|
-
domain:
|
104
|
-
ip: n
|
90
|
+
domain: n
|
105
91
|
},
|
106
|
-
metadata: this.metadata
|
107
|
-
success: true
|
92
|
+
metadata: this.metadata
|
108
93
|
});
|
94
|
+
})
|
95
|
+
];
|
96
|
+
}
|
97
|
+
splitByDnsRecords(dnsRecord) {
|
98
|
+
return [
|
99
|
+
...dnsRecord?.A ?? [],
|
100
|
+
...dnsRecord?.AAAA ?? []
|
101
|
+
].map((n)=>{
|
102
|
+
return Asset.fromPlain({
|
103
|
+
basic: {
|
104
|
+
domain: this.basic.domain,
|
105
|
+
ip: n
|
106
|
+
},
|
107
|
+
metadata: this.metadata
|
109
108
|
});
|
110
|
-
}
|
111
|
-
return [
|
112
|
-
this
|
113
|
-
];
|
114
|
-
}
|
109
|
+
});
|
115
110
|
}
|
116
|
-
splitByPorts() {
|
117
|
-
|
118
|
-
return
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
success: true
|
127
|
-
});
|
111
|
+
splitByPorts(ports) {
|
112
|
+
return ports.map((n)=>{
|
113
|
+
return Asset.fromPlain({
|
114
|
+
basic: {
|
115
|
+
domain: this.basic.domain,
|
116
|
+
ip: this.basic.ip,
|
117
|
+
port: n.port,
|
118
|
+
protocol: n.protocol
|
119
|
+
},
|
120
|
+
metadata: this.metadata
|
128
121
|
});
|
129
|
-
}
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
}
|
122
|
+
});
|
123
|
+
}
|
124
|
+
toPlain() {
|
125
|
+
return (0, _classtransformer.instanceToPlain)(this);
|
134
126
|
}
|
135
127
|
constructor(){
|
136
128
|
_define_property(this, "basic", new Basic());
|
137
|
-
_define_property(this, "subdomains", void 0);
|
138
|
-
_define_property(this, "dnsRecord", void 0);
|
139
|
-
_define_property(this, "ports", void 0);
|
140
129
|
_define_property(this, "metadata", void 0);
|
141
130
|
_define_property(this, "response", void 0);
|
142
|
-
_define_property(this, "
|
131
|
+
_define_property(this, "screenshot", void 0);
|
143
132
|
}
|
144
133
|
}
|
@@ -10,6 +10,7 @@ Object.defineProperty(exports, "NodeConnectionType", {
|
|
10
10
|
});
|
11
11
|
var NodeConnectionType;
|
12
12
|
(function(NodeConnectionType) {
|
13
|
-
NodeConnectionType["Runner"] = "
|
14
|
-
NodeConnectionType["Executor"] = "
|
13
|
+
NodeConnectionType["Runner"] = "soar_runner";
|
14
|
+
NodeConnectionType["Executor"] = "soar_executor";
|
15
|
+
NodeConnectionType["Memorizer"] = "soar_memorizer";
|
15
16
|
})(NodeConnectionType || (NodeConnectionType = {}));
|
@@ -0,0 +1,51 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
3
|
+
value: true
|
4
|
+
});
|
5
|
+
Object.defineProperty(exports, "AbstractExecutor", {
|
6
|
+
enumerable: true,
|
7
|
+
get: function() {
|
8
|
+
return AbstractExecutor;
|
9
|
+
}
|
10
|
+
});
|
11
|
+
const _n8nworkflow = require("n8n-workflow");
|
12
|
+
function _define_property(obj, key, value) {
|
13
|
+
if (key in obj) {
|
14
|
+
Object.defineProperty(obj, key, {
|
15
|
+
value: value,
|
16
|
+
enumerable: true,
|
17
|
+
configurable: true,
|
18
|
+
writable: true
|
19
|
+
});
|
20
|
+
} else {
|
21
|
+
obj[key] = value;
|
22
|
+
}
|
23
|
+
return obj;
|
24
|
+
}
|
25
|
+
class AbstractExecutor {
|
26
|
+
async readFile(path) {
|
27
|
+
const { stdout, stderr } = await this.run([
|
28
|
+
"cat",
|
29
|
+
path
|
30
|
+
]);
|
31
|
+
if (stderr !== "") {
|
32
|
+
throw new _n8nworkflow.NodeOperationError(this.func.getNode(), new Error(stderr));
|
33
|
+
}
|
34
|
+
return stdout;
|
35
|
+
}
|
36
|
+
async writeFile(path, content) {
|
37
|
+
// using base64 to avoid escaping issues
|
38
|
+
const { stderr } = await this.run([
|
39
|
+
"bash",
|
40
|
+
"-c",
|
41
|
+
`echo ${Buffer.from(content).toString("base64")} | base64 -d > ${path}`
|
42
|
+
]);
|
43
|
+
if (stderr !== "") {
|
44
|
+
throw new _n8nworkflow.NodeOperationError(this.func.getNode(), new Error(stderr));
|
45
|
+
}
|
46
|
+
}
|
47
|
+
constructor(func){
|
48
|
+
_define_property(this, "func", void 0);
|
49
|
+
this.func = func;
|
50
|
+
}
|
51
|
+
}
|
@@ -11,7 +11,7 @@ Object.defineProperty(exports, "DockerExecutor", {
|
|
11
11
|
const _stream = require("stream");
|
12
12
|
const _dockerode = /*#__PURE__*/ _interop_require_default(require("dockerode"));
|
13
13
|
const _n8nworkflow = require("n8n-workflow");
|
14
|
-
const
|
14
|
+
const _abstractexecutor = require("./abstract.executor");
|
15
15
|
function _define_property(obj, key, value) {
|
16
16
|
if (key in obj) {
|
17
17
|
Object.defineProperty(obj, key, {
|
@@ -30,29 +30,36 @@ function _interop_require_default(obj) {
|
|
30
30
|
default: obj
|
31
31
|
};
|
32
32
|
}
|
33
|
-
class DockerExecutor extends
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
stderr += chunk.toString();
|
46
|
-
done();
|
47
|
-
}
|
48
|
-
});
|
49
|
-
await this.docker.pull(image);
|
50
|
-
let container;
|
51
|
-
const containers = (await this.docker.listContainers({
|
33
|
+
class DockerExecutor extends _abstractexecutor.AbstractExecutor {
|
34
|
+
setContainer(container) {
|
35
|
+
this.container = container;
|
36
|
+
}
|
37
|
+
acquireContainer() {
|
38
|
+
if (!this.container) {
|
39
|
+
throw new _n8nworkflow.NodeOperationError(this.func.getNode(), "Container is not ready");
|
40
|
+
}
|
41
|
+
return this.container;
|
42
|
+
}
|
43
|
+
async listContainers() {
|
44
|
+
return (await this.docker.listContainers({
|
52
45
|
filters: '{"label": ["managed-by=n8n-nodes-soar"]}'
|
53
|
-
})).filter((n)=>n.Image === image);
|
46
|
+
})).filter((n)=>n.Image === this.image);
|
47
|
+
}
|
48
|
+
async findContainerByID(id) {
|
49
|
+
const containers = await this.listContainers();
|
50
|
+
const r = containers.find((n)=>n.Id === id);
|
51
|
+
if (!r) {
|
52
|
+
throw new _n8nworkflow.NodeOperationError(this.func.getNode(), `Container ${id} not found`);
|
53
|
+
}
|
54
|
+
return this.docker.getContainer(r.Id);
|
55
|
+
}
|
56
|
+
async prepareContainer() {
|
57
|
+
const { image } = this;
|
58
|
+
let container;
|
59
|
+
const containers = await this.listContainers();
|
54
60
|
if (containers.length === 0) {
|
55
61
|
this.func.logger.info(`Boot new container for image ${image}`);
|
62
|
+
await this.docker.pull(image);
|
56
63
|
container = await this.docker.createContainer({
|
57
64
|
Image: image,
|
58
65
|
Cmd: [
|
@@ -67,11 +74,28 @@ class DockerExecutor extends _executor.Executor {
|
|
67
74
|
} else {
|
68
75
|
container = this.docker.getContainer(containers[0].Id);
|
69
76
|
}
|
70
|
-
|
77
|
+
return container;
|
78
|
+
}
|
79
|
+
async run(cmd, options) {
|
80
|
+
let stdout = "";
|
81
|
+
let stderr = "";
|
82
|
+
const outStream = new _stream.Writable({
|
83
|
+
write (chunk, encoding, done) {
|
84
|
+
stdout += chunk.toString();
|
85
|
+
done();
|
86
|
+
}
|
87
|
+
});
|
88
|
+
const errStream = new _stream.Writable({
|
89
|
+
write (chunk, encoding, done) {
|
90
|
+
stderr += chunk.toString();
|
91
|
+
done();
|
92
|
+
}
|
93
|
+
});
|
94
|
+
const container = await this.acquireContainer();
|
71
95
|
const exec = await container.exec({
|
72
|
-
AttachStderr:
|
73
|
-
AttachStdout:
|
74
|
-
Env:
|
96
|
+
AttachStderr: !options?.ignoreStderr,
|
97
|
+
AttachStdout: !options?.ignoreStdout,
|
98
|
+
Env: options?.env,
|
75
99
|
Tty: false,
|
76
100
|
Cmd: cmd
|
77
101
|
});
|
@@ -83,15 +107,17 @@ class DockerExecutor extends _executor.Executor {
|
|
83
107
|
if (stderr !== "") {
|
84
108
|
throw new _n8nworkflow.NodeOperationError(this.func.getNode(), new Error(stderr));
|
85
109
|
}
|
86
|
-
|
87
|
-
|
110
|
+
return {
|
111
|
+
stdout,
|
112
|
+
stderr
|
113
|
+
};
|
88
114
|
}
|
89
|
-
constructor(credentials, func){
|
115
|
+
constructor(image, credentials, func){
|
90
116
|
super(func);
|
117
|
+
_define_property(this, "image", void 0);
|
91
118
|
_define_property(this, "docker", void 0);
|
92
|
-
|
93
|
-
|
94
|
-
}
|
119
|
+
_define_property(this, "container", void 0);
|
120
|
+
this.image = image;
|
95
121
|
this.docker = new _dockerode.default(credentials);
|
96
122
|
}
|
97
123
|
}
|
@@ -0,0 +1,123 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
3
|
+
value: true
|
4
|
+
});
|
5
|
+
function _export(target, all) {
|
6
|
+
for(var name in all)Object.defineProperty(target, name, {
|
7
|
+
enumerable: true,
|
8
|
+
get: all[name]
|
9
|
+
});
|
10
|
+
}
|
11
|
+
_export(exports, {
|
12
|
+
JSONRPCError: function() {
|
13
|
+
return JSONRPCError;
|
14
|
+
},
|
15
|
+
JSONRPCExecutor: function() {
|
16
|
+
return JSONRPCExecutor;
|
17
|
+
}
|
18
|
+
});
|
19
|
+
const _n8nworkflow = require("n8n-workflow");
|
20
|
+
const _ws = require("ws");
|
21
|
+
const _abstractexecutor = require("./abstract.executor");
|
22
|
+
function _define_property(obj, key, value) {
|
23
|
+
if (key in obj) {
|
24
|
+
Object.defineProperty(obj, key, {
|
25
|
+
value: value,
|
26
|
+
enumerable: true,
|
27
|
+
configurable: true,
|
28
|
+
writable: true
|
29
|
+
});
|
30
|
+
} else {
|
31
|
+
obj[key] = value;
|
32
|
+
}
|
33
|
+
return obj;
|
34
|
+
}
|
35
|
+
class JSONRPCError extends Error {
|
36
|
+
constructor(code, message, data){
|
37
|
+
super(`${code}: ${message} ${data ? JSON.stringify(data) : ""}`);
|
38
|
+
this.name = "JSONRPCError";
|
39
|
+
}
|
40
|
+
}
|
41
|
+
class JSONRPCExecutor extends _abstractexecutor.AbstractExecutor {
|
42
|
+
wait() {
|
43
|
+
if (this.ws.readyState === _ws.WebSocket.OPEN) {
|
44
|
+
return Promise.resolve(undefined);
|
45
|
+
}
|
46
|
+
return new Promise((resolve)=>{
|
47
|
+
this.ws.on("open", ()=>{
|
48
|
+
resolve(undefined);
|
49
|
+
});
|
50
|
+
});
|
51
|
+
}
|
52
|
+
id() {
|
53
|
+
return Math.floor(Math.random() * 1000000000);
|
54
|
+
}
|
55
|
+
async invoke(method, params) {
|
56
|
+
await this.wait();
|
57
|
+
return new Promise((resolve, reject)=>{
|
58
|
+
const id = this.id();
|
59
|
+
this.callbackMap.set(id, (n, e)=>{
|
60
|
+
if (e) {
|
61
|
+
reject(e);
|
62
|
+
} else {
|
63
|
+
resolve(n);
|
64
|
+
}
|
65
|
+
});
|
66
|
+
this.ws.send(JSON.stringify({
|
67
|
+
id,
|
68
|
+
method,
|
69
|
+
params
|
70
|
+
}));
|
71
|
+
});
|
72
|
+
}
|
73
|
+
listMethods() {
|
74
|
+
return this.invoke("system.ListMethods", []);
|
75
|
+
}
|
76
|
+
getMethod(method) {
|
77
|
+
return this.invoke("system.GetMethod", [
|
78
|
+
method
|
79
|
+
]);
|
80
|
+
}
|
81
|
+
run(cmd, options) {
|
82
|
+
return this.invoke("Run", [
|
83
|
+
cmd,
|
84
|
+
options ?? {}
|
85
|
+
]);
|
86
|
+
}
|
87
|
+
readFile(path) {
|
88
|
+
return this.invoke("ReadFile", [
|
89
|
+
path
|
90
|
+
]);
|
91
|
+
}
|
92
|
+
writeFile(path, content) {
|
93
|
+
return this.invoke("WriteFile", [
|
94
|
+
path,
|
95
|
+
content
|
96
|
+
]);
|
97
|
+
}
|
98
|
+
constructor(credentials, func){
|
99
|
+
super(func);
|
100
|
+
_define_property(this, "callbackMap", new Map());
|
101
|
+
_define_property(this, "ws", void 0);
|
102
|
+
const ws = new _ws.WebSocket(credentials.url + "/jsonrpc", {
|
103
|
+
headers: {
|
104
|
+
Authorization: `Basic ${Buffer.from(`${credentials.username}:${credentials.password}`).toString("base64")}`
|
105
|
+
}
|
106
|
+
});
|
107
|
+
ws.on("error", (e)=>{
|
108
|
+
throw new _n8nworkflow.NodeOperationError(this.func.getNode(), e);
|
109
|
+
});
|
110
|
+
ws.on("message", (data)=>{
|
111
|
+
const res = JSON.parse(data.toString());
|
112
|
+
const callback = this.callbackMap.get(res.id);
|
113
|
+
if (callback) {
|
114
|
+
if (res.error) {
|
115
|
+
callback(res.result, new JSONRPCError(res.error.code, res.error.message, res.error.data));
|
116
|
+
} else {
|
117
|
+
callback(res.result);
|
118
|
+
}
|
119
|
+
}
|
120
|
+
});
|
121
|
+
this.ws = ws;
|
122
|
+
}
|
123
|
+
}
|
@@ -2,16 +2,16 @@
|
|
2
2
|
Object.defineProperty(exports, "__esModule", {
|
3
3
|
value: true
|
4
4
|
});
|
5
|
-
Object.defineProperty(exports, "
|
5
|
+
Object.defineProperty(exports, "KubernetesExecutor", {
|
6
6
|
enumerable: true,
|
7
7
|
get: function() {
|
8
|
-
return
|
8
|
+
return KubernetesExecutor;
|
9
9
|
}
|
10
10
|
});
|
11
11
|
const _stream = require("stream");
|
12
12
|
const _clientnode = /*#__PURE__*/ _interop_require_wildcard(require("@kubernetes/client-node"));
|
13
13
|
const _n8nworkflow = require("n8n-workflow");
|
14
|
-
const
|
14
|
+
const _abstractexecutor = require("./abstract.executor");
|
15
15
|
function _define_property(obj, key, value) {
|
16
16
|
if (key in obj) {
|
17
17
|
Object.defineProperty(obj, key, {
|
@@ -66,20 +66,37 @@ function _interop_require_wildcard(obj, nodeInterop) {
|
|
66
66
|
}
|
67
67
|
return newObj;
|
68
68
|
}
|
69
|
-
class
|
70
|
-
|
69
|
+
class KubernetesExecutor extends _abstractexecutor.AbstractExecutor {
|
70
|
+
setPodName(podName) {
|
71
|
+
this.podName = podName;
|
72
|
+
}
|
73
|
+
acquirePodName() {
|
74
|
+
if (!this.podName) {
|
75
|
+
throw new _n8nworkflow.NodeOperationError(this.func.getNode(), "Pod name is not ready");
|
76
|
+
}
|
77
|
+
return this.podName;
|
78
|
+
}
|
79
|
+
async listNamespaces() {
|
71
80
|
const kc = this.kubeConfig;
|
72
81
|
const k8sCoreApi = kc.makeApiClient(_clientnode.CoreV1Api);
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
82
|
+
return (await k8sCoreApi.listNamespace()).body.items.map((n)=>n.metadata?.name ?? "");
|
83
|
+
}
|
84
|
+
async listPods() {
|
85
|
+
const kc = this.kubeConfig;
|
86
|
+
const k8sCoreApi = kc.makeApiClient(_clientnode.CoreV1Api);
|
87
|
+
const pods = (await k8sCoreApi.listNamespacedPod(this.namespace, undefined, undefined, undefined, undefined, "managed-by=n8n-nodes-soar")).body.items;
|
88
|
+
return pods.filter((n)=>(n.status?.phase === "Running" || n.status?.phase === "Pending") && n.spec?.containers[0].image === this.image).map((n)=>n.metadata?.name ?? "");
|
89
|
+
}
|
90
|
+
async preparePod() {
|
91
|
+
const { image, namespace } = this;
|
92
|
+
const pods = await this.listPods();
|
93
|
+
if (pods.length === 0) {
|
79
94
|
const podName = `n8n-soar-pod-${Date.now()}`;
|
95
|
+
this.func.logger.info(`Boot new pod for image ${image}`);
|
80
96
|
const podSpec = {
|
81
97
|
metadata: {
|
82
98
|
name: podName,
|
99
|
+
namespace,
|
83
100
|
labels: {
|
84
101
|
"managed-by": "n8n-nodes-soar"
|
85
102
|
}
|
@@ -100,14 +117,20 @@ class K8sExecutor extends _executor.Executor {
|
|
100
117
|
]
|
101
118
|
}
|
102
119
|
};
|
103
|
-
|
104
|
-
const
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
throw new Error("Pod name not set!");
|
120
|
+
const kc = this.kubeConfig;
|
121
|
+
const k8sCoreApi = kc.makeApiClient(_clientnode.CoreV1Api);
|
122
|
+
await k8sCoreApi.createNamespacedPod(this.namespace, podSpec);
|
123
|
+
return podName;
|
124
|
+
} else {
|
125
|
+
return pods[0];
|
110
126
|
}
|
127
|
+
}
|
128
|
+
async run(cmd, options) {
|
129
|
+
const { namespace } = this;
|
130
|
+
const kc = this.kubeConfig;
|
131
|
+
const k8sCoreApi = kc.makeApiClient(_clientnode.CoreV1Api);
|
132
|
+
const name = this.acquirePodName();
|
133
|
+
const pod = (await k8sCoreApi.readNamespacedPod(name, namespace)).body;
|
111
134
|
// if is in initial
|
112
135
|
if (pod.status?.phase === "Pending") {
|
113
136
|
while(true){
|
@@ -132,19 +155,19 @@ class K8sExecutor extends _executor.Executor {
|
|
132
155
|
stderrString += chunk.toString();
|
133
156
|
next();
|
134
157
|
};
|
135
|
-
this.func.logger.debug(`Running ${cmd.join(" ")}`);
|
136
158
|
await new Promise(async (resolve, reject)=>{
|
137
159
|
exec.exec(namespace, name, "main-container", [
|
138
160
|
"env",
|
139
|
-
...
|
161
|
+
...options?.env?.flatMap((v)=>[
|
140
162
|
"-e",
|
141
|
-
|
142
|
-
]),
|
163
|
+
v
|
164
|
+
]) ?? [],
|
143
165
|
...cmd
|
144
166
|
], stdout, stderr, null, false, (s)=>{
|
145
167
|
switch(s.status){
|
146
168
|
case "Failure":
|
147
|
-
|
169
|
+
console.log(stderrString, stdoutString);
|
170
|
+
reject(new Error(s.message));
|
148
171
|
break;
|
149
172
|
case "Success":
|
150
173
|
resolve(undefined);
|
@@ -152,19 +175,19 @@ class K8sExecutor extends _executor.Executor {
|
|
152
175
|
}
|
153
176
|
}).catch(reject);
|
154
177
|
});
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
}
|
159
|
-
this.func.logger.debug(`Result ${stdoutString}`);
|
160
|
-
return JSON.parse(stdoutString);
|
178
|
+
return {
|
179
|
+
stdout: stdoutString,
|
180
|
+
stderr: stderrString
|
181
|
+
};
|
161
182
|
}
|
162
|
-
constructor(credentials, func){
|
183
|
+
constructor(namespace, image, credentials, func){
|
163
184
|
super(func);
|
185
|
+
_define_property(this, "namespace", void 0);
|
186
|
+
_define_property(this, "image", void 0);
|
187
|
+
_define_property(this, "podName", void 0);
|
164
188
|
_define_property(this, "kubeConfig", void 0);
|
165
|
-
|
166
|
-
|
167
|
-
}
|
189
|
+
this.namespace = namespace;
|
190
|
+
this.image = image;
|
168
191
|
const kubeConfig = new _clientnode.KubeConfig();
|
169
192
|
switch(credentials.loadFrom){
|
170
193
|
case "automatic":
|
@@ -0,0 +1,49 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
3
|
+
value: true
|
4
|
+
});
|
5
|
+
Object.defineProperty(exports, "AbstractMemorizer", {
|
6
|
+
enumerable: true,
|
7
|
+
get: function() {
|
8
|
+
return AbstractMemorizer;
|
9
|
+
}
|
10
|
+
});
|
11
|
+
const _n8nworkflow = require("n8n-workflow");
|
12
|
+
function _define_property(obj, key, value) {
|
13
|
+
if (key in obj) {
|
14
|
+
Object.defineProperty(obj, key, {
|
15
|
+
value: value,
|
16
|
+
enumerable: true,
|
17
|
+
configurable: true,
|
18
|
+
writable: true
|
19
|
+
});
|
20
|
+
} else {
|
21
|
+
obj[key] = value;
|
22
|
+
}
|
23
|
+
return obj;
|
24
|
+
}
|
25
|
+
class AbstractMemorizer {
|
26
|
+
save(input, output) {
|
27
|
+
return this.storage.set(this.hash(input), output);
|
28
|
+
}
|
29
|
+
async batchSave(inputs, outputs) {
|
30
|
+
if (inputs.length !== outputs.length) {
|
31
|
+
throw new _n8nworkflow.NodeOperationError(this.func.getNode(), "Inputs and outputs must be the same length");
|
32
|
+
}
|
33
|
+
await Promise.all(inputs.map((input, index)=>this.storage.set(this.hash(input), outputs[index])));
|
34
|
+
}
|
35
|
+
load(input) {
|
36
|
+
return this.storage.get(this.hash(input));
|
37
|
+
}
|
38
|
+
async batchLoad(inputs) {
|
39
|
+
return Promise.all(inputs.map((input)=>this.storage.get(this.hash(input))));
|
40
|
+
}
|
41
|
+
constructor(func, itemIndex, storage){
|
42
|
+
_define_property(this, "func", void 0);
|
43
|
+
_define_property(this, "itemIndex", void 0);
|
44
|
+
_define_property(this, "storage", void 0);
|
45
|
+
this.func = func;
|
46
|
+
this.itemIndex = itemIndex;
|
47
|
+
this.storage = storage;
|
48
|
+
}
|
49
|
+
}
|
@@ -0,0 +1,16 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
3
|
+
value: true
|
4
|
+
});
|
5
|
+
Object.defineProperty(exports, "AssetMemorizer", {
|
6
|
+
enumerable: true,
|
7
|
+
get: function() {
|
8
|
+
return AssetMemorizer;
|
9
|
+
}
|
10
|
+
});
|
11
|
+
const _generalmemorizer = require("./general.memorizer");
|
12
|
+
class AssetMemorizer extends _generalmemorizer.GeneralMemorizer {
|
13
|
+
hash(data) {
|
14
|
+
return "asset:" + super.hash(data.json.basic);
|
15
|
+
}
|
16
|
+
}
|
@@ -0,0 +1,17 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
3
|
+
value: true
|
4
|
+
});
|
5
|
+
Object.defineProperty(exports, "GeneralMemorizer", {
|
6
|
+
enumerable: true,
|
7
|
+
get: function() {
|
8
|
+
return GeneralMemorizer;
|
9
|
+
}
|
10
|
+
});
|
11
|
+
const _nodecrypto = require("node:crypto");
|
12
|
+
const _abstractmemorizer = require("./abstract.memorizer");
|
13
|
+
class GeneralMemorizer extends _abstractmemorizer.AbstractMemorizer {
|
14
|
+
hash(data) {
|
15
|
+
return (0, _nodecrypto.createHash)("md5").update(JSON.stringify(data)).digest("hex");
|
16
|
+
}
|
17
|
+
}
|