Skip to content

Commit f68a2c9

Browse files
committed
add nodered_allow_nodeselector
1 parent eebdceb commit f68a2c9

11 files changed

Lines changed: 90 additions & 75 deletions

OpenFlow/src/Config.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,12 +96,13 @@ export class Config {
9696
Config.downloadtoken_expires_in = Config.getEnv("downloadtoken_expires_in", "15m");
9797
Config.personalnoderedtoken_expires_in = Config.getEnv("personalnoderedtoken_expires_in", "365d");
9898

99-
Config.nodered_image = Config.getEnv("nodered_image", "openiap/openflownodered:edge");
99+
Config.nodered_image = Config.getEnv("nodered_image", "openiap/nodered:edge");
100100
Config.saml_federation_metadata = Config.getEnv("saml_federation_metadata", "");
101101
Config.api_ws_url = Config.getEnv("api_ws_url", "ws://localhost:3000");
102102
Config.namespace = Config.getEnv("namespace", ""); // also sent to website
103103
Config.nodered_domain_schema = Config.getEnv("nodered_domain_schema", ""); // also sent to website
104104
Config.nodered_initial_liveness_delay = parseInt(Config.getEnv("nodered_initial_liveness_delay", "60"));
105+
Config.nodered_allow_nodeselector = Config.parseBoolean(Config.getEnv("nodered_allow_nodeselector", "false"));
105106
}
106107
public static db: DatabaseConnection = null;
107108
public static license_key: string = Config.getEnv("license_key", "");
@@ -184,12 +185,13 @@ export class Config {
184185
public static downloadtoken_expires_in: string = Config.getEnv("downloadtoken_expires_in", "15m");
185186
public static personalnoderedtoken_expires_in: string = Config.getEnv("personalnoderedtoken_expires_in", "365d");
186187

187-
public static nodered_image: string = Config.getEnv("nodered_image", "openiap/openflownodered:edge");
188+
public static nodered_image: string = Config.getEnv("nodered_image", "openiap/nodered:edge");
188189
public static saml_federation_metadata: string = Config.getEnv("saml_federation_metadata", "");
189190
public static api_ws_url: string = Config.getEnv("api_ws_url", "ws://localhost:3000");
190191
public static namespace: string = Config.getEnv("namespace", ""); // also sent to website
191192
public static nodered_domain_schema: string = Config.getEnv("nodered_domain_schema", ""); // also sent to website
192193
public static nodered_initial_liveness_delay: number = parseInt(Config.getEnv("nodered_initial_liveness_delay", "60"));
194+
public static nodered_allow_nodeselector: boolean = Config.parseBoolean(Config.getEnv("nodered_allow_nodeselector", "false"));
193195

194196
public static baseurl(): string {
195197
let result: string = "";

OpenFlow/src/Messages/Message.ts

Lines changed: 54 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import { Readable, Stream } from "stream";
1111
import { GridFSBucket, ObjectID, Db, Cursor, MongoNetworkError } from "mongodb";
1212
import * as path from "path";
1313
import { DatabaseConnection } from "../DatabaseConnection";
14-
import { StripeMessage, EnsureStripeCustomerMessage, NoderedUtil, QueuedMessage, RegisterQueueMessage, QueueMessage, CloseQueueMessage, ListCollectionsMessage, DropCollectionMessage, QueryMessage, AggregateMessage, InsertOneMessage, UpdateOneMessage, Base, UpdateManyMessage, InsertOrUpdateOneMessage, DeleteOneMessage, MapReduceMessage, SigninMessage, TokenUser, User, Rights, EnsureNoderedInstanceMessage, DeleteNoderedInstanceMessage, DeleteNoderedPodMessage, RestartNoderedInstanceMessage, GetNoderedInstanceMessage, GetNoderedInstanceLogMessage, SaveFileMessage, WellknownIds, GetFileMessage, UpdateFileMessage, CreateWorkflowInstanceMessage, RegisterUserMessage, NoderedUser, WatchMessage, GetDocumentVersionMessage, DeleteManyMessage, InsertManyMessage } from "openflow-api";
14+
import { StripeMessage, EnsureStripeCustomerMessage, NoderedUtil, QueuedMessage, RegisterQueueMessage, QueueMessage, CloseQueueMessage, ListCollectionsMessage, DropCollectionMessage, QueryMessage, AggregateMessage, InsertOneMessage, UpdateOneMessage, Base, UpdateManyMessage, InsertOrUpdateOneMessage, DeleteOneMessage, MapReduceMessage, SigninMessage, TokenUser, User, Rights, EnsureNoderedInstanceMessage, DeleteNoderedInstanceMessage, DeleteNoderedPodMessage, RestartNoderedInstanceMessage, GetNoderedInstanceMessage, GetNoderedInstanceLogMessage, SaveFileMessage, WellknownIds, GetFileMessage, UpdateFileMessage, CreateWorkflowInstanceMessage, RegisterUserMessage, NoderedUser, WatchMessage, GetDocumentVersionMessage, DeleteManyMessage, InsertManyMessage, GetKubeNodeLabels } from "openflow-api";
1515
import { Billing, stripe_customer, stripe_base, stripe_list, StripeAddPlanMessage, StripeCancelPlanMessage, stripe_subscription, stripe_subscription_item, stripe_plan, stripe_coupon } from "openflow-api";
1616
import { V1ResourceRequirements, V1Deployment } from "@kubernetes/client-node";
1717
import { amqpwrapper } from "../amqpwrapper";
@@ -167,6 +167,9 @@ export class Message {
167167
case "restartnoderedinstance":
168168
this.RestartNoderedInstance(cli);
169169
break;
170+
case "getkubenodelabels":
171+
this.GetKubeNodeLabels(cli);
172+
break;
170173
case "getnoderedinstance":
171174
this.GetNoderedInstance(cli);
172175
break;
@@ -951,7 +954,7 @@ export class Message {
951954
let msg: EnsureNoderedInstanceMessage;
952955
try {
953956
msg = EnsureNoderedInstanceMessage.assign(this.data);
954-
await this._EnsureNoderedInstance(cli, msg._id, false);
957+
await this._EnsureNoderedInstance(cli, msg._id, false, msg.labels);
955958
} catch (error) {
956959
this.data = "";
957960
cli._logger.error(error);
@@ -966,7 +969,7 @@ export class Message {
966969
}
967970
this.Send(cli);
968971
}
969-
private async _EnsureNoderedInstance(cli: WebSocketServerClient, _id: string, skipcreate: boolean): Promise<void> {
972+
private async _EnsureNoderedInstance(cli: WebSocketServerClient, _id: string, skipcreate: boolean, labels: any): Promise<void> {
970973
let user: NoderedUser;
971974
cli._logger.debug("[" + cli.user.username + "] EnsureNoderedInstance");
972975
if (_id === null || _id === undefined || _id === "") _id = cli.user._id;
@@ -1105,6 +1108,17 @@ export class Message {
11051108
}
11061109
}
11071110
}
1111+
if (_deployment && labels && Config.nodered_allow_nodeselector) {
1112+
if (typeof labels === "string") {
1113+
var item = JSON.parse(labels);
1114+
var spec: any = _deployment.spec.template.spec;
1115+
const keys = Object.keys(item);
1116+
if (spec.nodeSelector == null) spec.nodeSelector = {};
1117+
keys.forEach(key => {
1118+
spec.nodeSelector[key] = item[key];
1119+
})
1120+
}
1121+
}
11081122
try {
11091123
await KubeUtil.instance().AppsV1Api.createNamespacedDeployment(namespace, (_deployment as any));
11101124
Audit.NoderedAction(TokenUser.From(cli.user), true, name, "createdeployment", Config.nodered_image, null);
@@ -1304,7 +1318,7 @@ export class Message {
13041318
}
13051319
}
13061320
} else {
1307-
cli._logger.warn("[" + cli.user.username + "] GetNoderedInstance: found NO Namespaced Pods ???");
1321+
cli._logger.warn("[" + cli.user.username + "] DeleteNoderedPod: found NO Namespaced Pods ???");
13081322
Audit.NoderedAction(TokenUser.From(cli.user), false, null, "deletepod", image, msg.name);
13091323
}
13101324
} catch (error) {
@@ -1360,6 +1374,38 @@ export class Message {
13601374
}
13611375
this.Send(cli);
13621376
}
1377+
private async GetKubeNodeLabels(cli: WebSocketServerClient): Promise<void> {
1378+
this.Reply();
1379+
let msg: GetKubeNodeLabels;
1380+
try {
1381+
cli._logger.debug("[" + cli.user.username + "] GetKubeNodeLabels");
1382+
msg = GetKubeNodeLabels.assign(this.data);
1383+
const list = await KubeUtil.instance().CoreV1Api.listNode();
1384+
const result: any = {};
1385+
if (list != null) {
1386+
list.body.items.forEach(node => {
1387+
if (node.metadata && node.metadata.labels) {
1388+
const keys = Object.keys(node.metadata.labels);
1389+
keys.forEach(key => {
1390+
result[key] = node.metadata.labels[key];
1391+
});
1392+
}
1393+
});
1394+
}
1395+
msg.result = result;
1396+
} catch (error) {
1397+
this.data = "";
1398+
cli._logger.error(error);
1399+
if (msg !== null && msg !== undefined) msg.error = error.message ? error.message : error
1400+
}
1401+
try {
1402+
this.data = JSON.stringify(msg);
1403+
} catch (error) {
1404+
this.data = "";
1405+
cli._logger.error(error);
1406+
}
1407+
this.Send(cli);
1408+
}
13631409
private async GetNoderedInstance(cli: WebSocketServerClient): Promise<void> {
13641410
this.Reply();
13651411
let msg: GetNoderedInstanceMessage;
@@ -1435,7 +1481,7 @@ export class Message {
14351481
this.Reply();
14361482
let msg: GetNoderedInstanceLogMessage;
14371483
try {
1438-
cli._logger.debug("[" + cli.user.username + "] GetNoderedInstance");
1484+
cli._logger.debug("[" + cli.user.username + "] GetNoderedInstanceLog");
14391485
msg = GetNoderedInstanceLogMessage.assign(this.data);
14401486
const name = await this.GetInstanceName(msg._id, cli.user._id, cli.user.username, cli.jwt);
14411487
const namespace = Config.namespace;
@@ -1452,12 +1498,12 @@ export class Message {
14521498

14531499
}
14541500
if (!NoderedUtil.IsNullEmpty(msg.name) && item.metadata.name == msg.name && cli.user.HasRoleName("admins")) {
1455-
cli._logger.debug("[" + cli.user.username + "] GetNoderedInstance:" + name + " found one as " + item.metadata.name);
1501+
cli._logger.debug("[" + cli.user.username + "] GetNoderedInstanceLog:" + name + " found one as " + item.metadata.name);
14561502
const obj = await await KubeUtil.instance().CoreV1Api.readNamespacedPodLog(item.metadata.name, namespace, "", false);
14571503
msg.result = obj.body;
14581504
Audit.NoderedAction(TokenUser.From(cli.user), true, name, "readpodlog", image, item.metadata.name);
14591505
} else if (item.metadata.labels.app === name) {
1460-
cli._logger.debug("[" + cli.user.username + "] GetNoderedInstance:" + name + " found one as " + item.metadata.name);
1506+
cli._logger.debug("[" + cli.user.username + "] GetNoderedInstanceLog:" + name + " found one as " + item.metadata.name);
14611507
const obj = await await KubeUtil.instance().CoreV1Api.readNamespacedPodLog(item.metadata.name, namespace, "", false);
14621508
msg.result = obj.body;
14631509
Audit.NoderedAction(TokenUser.From(cli.user), true, name, "readpodlog", image, item.metadata.name);
@@ -2090,7 +2136,7 @@ export class Message {
20902136
if (billing.memory != newmemory) {
20912137
billing.memory = newmemory;
20922138
billing = await Config.db._UpdateOne(null, billing, "users", 3, true, rootjwt);
2093-
this._EnsureNoderedInstance(cli, msg.userid, true);
2139+
this._EnsureNoderedInstance(cli, msg.userid, true, null);
20942140
}
20952141
if (customer != null && !NoderedUtil.IsNullEmpty(billing.coupon) && customer.discount != null) {
20962142
if (billing.coupon != customer.discount.coupon.name) {

OpenFlow/src/public/Controllers.ts

Lines changed: 9 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1360,58 +1360,6 @@ export class SocketCtrl {
13601360
});
13611361
});
13621362
}
1363-
1364-
async EnsureNoderedInstance(_id: string, name: string) {
1365-
try {
1366-
await NoderedUtil.EnsureNoderedInstance(_id, false, null);
1367-
this.messages += "EnsureNoderedInstance completed" + "\n";
1368-
} catch (error) {
1369-
this.messages += error + "\n";
1370-
console.error(error);
1371-
}
1372-
if (!this.$scope.$$phase) { this.$scope.$apply(); }
1373-
}
1374-
async DeleteNoderedInstance(_id: string, name: string) {
1375-
try {
1376-
await NoderedUtil.DeleteNoderedInstance(null, _id);
1377-
this.messages += "DeleteNoderedInstance completed" + "\n";
1378-
} catch (error) {
1379-
this.messages += error + "\n";
1380-
console.error(error);
1381-
}
1382-
if (!this.$scope.$$phase) { this.$scope.$apply(); }
1383-
}
1384-
async RestartNoderedInstance(_id: string, name: string) {
1385-
try {
1386-
await NoderedUtil.RestartNoderedInstance(null, _id);
1387-
this.messages += "RestartNoderedInstance completed" + "\n";
1388-
} catch (error) {
1389-
this.messages += error + "\n";
1390-
console.error(error);
1391-
}
1392-
if (!this.$scope.$$phase) { this.$scope.$apply(); }
1393-
}
1394-
async StartNoderedInstance(_id: string, name: string) {
1395-
try {
1396-
await NoderedUtil.StartNoderedInstance(null, _id);
1397-
this.messages += "StartNoderedInstance completed" + "\n";
1398-
} catch (error) {
1399-
this.messages += error + "\n";
1400-
console.error(error);
1401-
}
1402-
if (!this.$scope.$$phase) { this.$scope.$apply(); }
1403-
}
1404-
async StopNoderedInstance(_id: string, name: string) {
1405-
try {
1406-
await NoderedUtil.StopNoderedInstance(null, _id);
1407-
this.messages += "StopNoderedInstance completed" + "\n";
1408-
} catch (error) {
1409-
this.messages += error + "\n";
1410-
console.error(error);
1411-
}
1412-
if (!this.$scope.$$phase) { this.$scope.$apply(); }
1413-
}
1414-
14151363
}
14161364
export class FilesCtrl extends entitiesCtrl<Base> {
14171365
public file: string;
@@ -2698,6 +2646,9 @@ export class NoderedCtrl {
26982646
public user: NoderedUser = null;
26992647
public limitsmemory: string = "";
27002648
public loading: boolean = false;
2649+
public labels: any[] = [];
2650+
public keys: string[] = [];
2651+
public label: any = null;
27012652
constructor(
27022653
public $scope: ng.IScope,
27032654
public $location: ng.ILocationService,
@@ -2744,6 +2695,11 @@ export class NoderedCtrl {
27442695
console.log(this.noderedurl);
27452696
// // this.GetNoderedInstance();
27462697
this.GetNoderedInstance();
2698+
this.labels = await NoderedUtil.GetKubeNodeLabels(null);
2699+
this.keys = Object.keys(this.labels);
2700+
this.loading = false;
2701+
if (!this.$scope.$$phase) { this.$scope.$apply(); }
2702+
27472703
});
27482704
}
27492705
async save() {
@@ -2839,7 +2795,7 @@ export class NoderedCtrl {
28392795
async EnsureNoderedInstance() {
28402796
try {
28412797
this.errormessage = "";
2842-
await NoderedUtil.EnsureNoderedInstance(this.userid, false, null);
2798+
await NoderedUtil.EnsureNoderedInstance(this.userid, false, this.label, null);
28432799
this.messages = "EnsureNoderedInstance completed" + "\n" + this.messages;
28442800
this.GetNoderedInstance();
28452801
} catch (error) {

OpenFlow/src/public/Nodered.html

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,17 @@ <h1 translate lib="web">nodered</h1>
105105
</div>
106106
</div>
107107
</section>
108+
<section>
109+
<div class="form-group" ng-show="menuctrl.hasrole('admins') && ctrl.labels">
110+
<label class="col-sm-3 control-label"><span translate lib="web">label</span>: </label>
111+
<div class="col-sm-9">
112+
<select class="form-control" ng-model="ctrl.label">
113+
<option value="">No label</option>
114+
<option ng-repeat="key in ctrl.keys">{{ '{"' + key + '":"' + ctrl.labels[key] + '"}'}}</option>
115+
</select>
116+
</div>
117+
</div>
118+
</section>
108119
<section>
109120
<div class="form-group">
110121
<div class="col-sm-offset-3 col-sm-9">

OpenFlowNodeRED/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@openiap/nodered",
3-
"version": "1.1.110",
3+
"version": "1.1.111",
44
"description": "Simple wrapper around NodeRed, RabbitMQ and MongoDB to support a more scaleable NodeRed implementation.\r Also the \"backend\" for [OpenRPA](https://github.com/skadefro/OpenRPA)",
55
"main": "index.js",
66
"scripts": {

VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
1.1.110
1+
1.1.111

docker-compose-toolbox.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ services:
4545
- "traefik.http.routers.web.rule=Host(`toolbox.openrpa.dk`)"
4646
- "traefik.http.routers.web.entrypoints=web"
4747
- "traefik.frontend.passHostHeader=true"
48-
image: "openiap/openflow:1.1.110"
48+
image: "openiap/openflow:1.1.111"
4949
container_name: "web"
5050
environment:
5151
- update_acl_based_on_groups=true
@@ -82,7 +82,7 @@ services:
8282
- "traefik.http.routers.nodered.rule=Host(`nodered1.toolbox.openrpa.dk`)"
8383
- "traefik.http.routers.nodered.entrypoints=web"
8484
- "traefik.http.services.nodered.loadbalancer.server.port=1880"
85-
image: "openiap/openflownodered:1.1.110"
85+
image: "openiap/nodered:1.1.111"
8686
container_name: "nodered"
8787
environment:
8888
# - nodered_id=1

docker-compose-traefik-letsencrypt.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ services:
6969
- "traefik.http.routers.web.entrypoints=web,websecure"
7070
- "traefik.frontend.passHostHeader=true"
7171
- "traefik.http.routers.web.tls.certresolver=myresolver"
72-
image: "openiap/openflow:1.1.110"
72+
image: "openiap/openflow:1.1.111"
7373
container_name: "web"
7474
environment:
7575
- update_acl_based_on_groups=true
@@ -107,7 +107,7 @@ services:
107107
- "traefik.http.routers.nodered.entrypoints=web,websecure"
108108
- "traefik.http.services.nodered.loadbalancer.server.port=1880"
109109
- "traefik.http.routers.nodered.tls.certresolver=myresolver"
110-
image: "openiap/openflownodered:1.1.110"
110+
image: "openiap/nodered:1.1.111"
111111
container_name: "nodered"
112112
environment:
113113
# - nodered_id=1

docker-compose-traefik.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ services:
4545
- "traefik.http.routers.web.rule=Host(`localhost.openrpa.dk`)"
4646
- "traefik.http.routers.web.entrypoints=web"
4747
- "traefik.frontend.passHostHeader=true"
48-
image: "openiap/openflow:1.1.110"
48+
image: "openiap/openflow:1.1.111"
4949
container_name: "web"
5050
environment:
5151
- update_acl_based_on_groups=true
@@ -82,7 +82,7 @@ services:
8282
- "traefik.http.routers.nodered.rule=Host(`nodered1.localhost.openrpa.dk`)"
8383
- "traefik.http.routers.nodered.entrypoints=web"
8484
- "traefik.http.services.nodered.loadbalancer.server.port=1880"
85-
image: "openiap/openflownodered:1.1.110"
85+
image: "openiap/nodered:1.1.111"
8686
container_name: "nodered"
8787
environment:
8888
# - nodered_id=1

docker-compose.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ services:
1818
- "5672:5672"
1919
- "15672:15672"
2020
web:
21-
image: "openiap/openflow:1.1.110"
21+
image: "openiap/openflow:1.1.111"
2222
environment:
2323
- update_acl_based_on_groups=true
2424
- multi_tenant=false
@@ -52,7 +52,7 @@ services:
5252
- "80:80"
5353
- "5858:5858"
5454
nodered:
55-
image: "openiap/openflownodered:1.1.110"
55+
image: "openiap/nodered:1.1.111"
5656
environment:
5757
# - nodered_id=1
5858
- nodered_sa=nodered1

0 commit comments

Comments
 (0)