conlink 2.0.0 → 2.0.1
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/.env +3 -0
- package/Dockerfile +2 -1
- package/README.md +7 -8
- package/examples/data.dot +457 -0
- package/examples/net2dot-data.dot +123 -0
- package/examples/net2dot.dot +457 -0
- package/examples/net2dot.yaml +2 -2
- package/examples/test1-data.dot +82 -0
- package/examples/test1.dot +286 -0
- package/examples/test6-cfn.yaml +1 -2
- package/host-build.yaml +1 -1
- package/modes0/a/deps +1 -0
- package/modes0/b/deps +1 -0
- package/modes0/c/deps +1 -0
- package/modes0/e/deps +1 -0
- package/modes1/a/deps +1 -0
- package/modes1/b/deps +1 -0
- package/modes1/c/deps +1 -0
- package/modes1/d/deps +1 -0
- package/modes2/a/deps +1 -0
- package/modes2/b/deps +1 -0
- package/modes2/c/deps +1 -0
- package/modes2/d/de +1 -0
- package/modes2/d/deps +1 -0
- package/modes3/ab/deps +1 -0
- package/modes3/accel/deps +1 -0
- package/modes3/mach3/deps +1 -0
- package/modes4/a/deps +1 -0
- package/modes4/b/deps +1 -0
- package/net2dot +1 -1
- package/net2dot.cljs +113 -0
- package/net2dot.mjs +21 -0
- package/old/graphviz.cljs +14 -0
- package/old/net2dot.cljs +114 -0
- package/old/set-cover-old.cljs +205 -0
- package/old/set-cover-old2.cljs +150 -0
- package/package.json +5 -1
- package/read-stream.cljs +12 -0
- package/resolve-deps.cljs +183 -0
- package/shadow-cljs.edn +1 -1
- package/src/conlink/addrs.cljc +3 -0
- package/src/conlink/core.cljs +21 -7
- package/src/conlink/util.cljs +13 -2
- package/topo1.cljs +35 -0
- package/topo2.cljs +36 -0
- package/topo3.cljs +44 -0
- package/src/conlink/net2dot.cljs +0 -158
|
@@ -0,0 +1,286 @@
|
|
|
1
|
+
digraph {
|
|
2
|
+
splines = true;
|
|
3
|
+
compound = true;
|
|
4
|
+
subgraph "cluster_host" {
|
|
5
|
+
shape = "box";
|
|
6
|
+
fontsize = 14;
|
|
7
|
+
style = "filled";
|
|
8
|
+
penwidth = 1;
|
|
9
|
+
fillcolor = "#f5f5f5";
|
|
10
|
+
color = "#666666";
|
|
11
|
+
label = "host system";
|
|
12
|
+
subgraph "cluster_conlink" {
|
|
13
|
+
shape = "box";
|
|
14
|
+
fontsize = 14;
|
|
15
|
+
style = "rounded,filled";
|
|
16
|
+
penwidth = 3;
|
|
17
|
+
fillcolor = "#c5d1e7";
|
|
18
|
+
color = "#7396a0";
|
|
19
|
+
label = "conlink/network";
|
|
20
|
+
subgraph "cluster_bridge_s1" {
|
|
21
|
+
shape = "box";
|
|
22
|
+
fontsize = 14;
|
|
23
|
+
style = "filled";
|
|
24
|
+
penwidth = 1;
|
|
25
|
+
fillcolor = "#c8badc";
|
|
26
|
+
color = "#6e509f";
|
|
27
|
+
label = "s1";
|
|
28
|
+
}
|
|
29
|
+
subgraph "cluster_bridge_s2" {
|
|
30
|
+
shape = "box";
|
|
31
|
+
fontsize = 14;
|
|
32
|
+
style = "filled";
|
|
33
|
+
penwidth = 1;
|
|
34
|
+
fillcolor = "#c8badc";
|
|
35
|
+
color = "#6e509f";
|
|
36
|
+
label = "s2";
|
|
37
|
+
}
|
|
38
|
+
subgraph "cluster_bridge_s3" {
|
|
39
|
+
shape = "box";
|
|
40
|
+
fontsize = 14;
|
|
41
|
+
style = "filled";
|
|
42
|
+
penwidth = 1;
|
|
43
|
+
fillcolor = "#c8badc";
|
|
44
|
+
color = "#6e509f";
|
|
45
|
+
label = "s3";
|
|
46
|
+
}
|
|
47
|
+
subgraph "cluster_bridge_s1" {
|
|
48
|
+
shape = "box";
|
|
49
|
+
fontsize = 14;
|
|
50
|
+
style = "filled";
|
|
51
|
+
penwidth = 1;
|
|
52
|
+
fillcolor = "#c8badc";
|
|
53
|
+
color = "#6e509f";
|
|
54
|
+
label = "s1";
|
|
55
|
+
"out_DASH_r0_1_DASH_eth_DASH_s1" [
|
|
56
|
+
color = "#af6b4e";
|
|
57
|
+
fillcolor = "#e8e8c8";
|
|
58
|
+
width = 0.1;
|
|
59
|
+
penwidth = 1;
|
|
60
|
+
style = "filled";
|
|
61
|
+
label = "r0_1-eth-s1";
|
|
62
|
+
shape = "box";
|
|
63
|
+
fontsize = 10;
|
|
64
|
+
height = 0.1;
|
|
65
|
+
];
|
|
66
|
+
"out_DASH_h1_1_DASH_eth0" [
|
|
67
|
+
color = "#af6b4e";
|
|
68
|
+
fillcolor = "#e8e8c8";
|
|
69
|
+
width = 0.1;
|
|
70
|
+
penwidth = 1;
|
|
71
|
+
style = "filled";
|
|
72
|
+
label = "h1_1-eth0";
|
|
73
|
+
shape = "box";
|
|
74
|
+
fontsize = 10;
|
|
75
|
+
height = 0.1;
|
|
76
|
+
];
|
|
77
|
+
}
|
|
78
|
+
subgraph "cluster_bridge_s2" {
|
|
79
|
+
shape = "box";
|
|
80
|
+
fontsize = 14;
|
|
81
|
+
style = "filled";
|
|
82
|
+
penwidth = 1;
|
|
83
|
+
fillcolor = "#c8badc";
|
|
84
|
+
color = "#6e509f";
|
|
85
|
+
label = "s2";
|
|
86
|
+
"out_DASH_r0_1_DASH_eth_DASH_s2" [
|
|
87
|
+
color = "#af6b4e";
|
|
88
|
+
fillcolor = "#e8e8c8";
|
|
89
|
+
width = 0.1;
|
|
90
|
+
penwidth = 1;
|
|
91
|
+
style = "filled";
|
|
92
|
+
label = "r0_1-eth-s2";
|
|
93
|
+
shape = "box";
|
|
94
|
+
fontsize = 10;
|
|
95
|
+
height = 0.1;
|
|
96
|
+
];
|
|
97
|
+
"out_DASH_h2_1_DASH_eth0" [
|
|
98
|
+
color = "#af6b4e";
|
|
99
|
+
fillcolor = "#e8e8c8";
|
|
100
|
+
width = 0.1;
|
|
101
|
+
penwidth = 1;
|
|
102
|
+
style = "filled";
|
|
103
|
+
label = "h2_1-eth0";
|
|
104
|
+
shape = "box";
|
|
105
|
+
fontsize = 10;
|
|
106
|
+
height = 0.1;
|
|
107
|
+
];
|
|
108
|
+
}
|
|
109
|
+
subgraph "cluster_bridge_s3" {
|
|
110
|
+
shape = "box";
|
|
111
|
+
fontsize = 14;
|
|
112
|
+
style = "filled";
|
|
113
|
+
penwidth = 1;
|
|
114
|
+
fillcolor = "#c8badc";
|
|
115
|
+
color = "#6e509f";
|
|
116
|
+
label = "s3";
|
|
117
|
+
"out_DASH_r0_1_DASH_eth_DASH_s3" [
|
|
118
|
+
color = "#af6b4e";
|
|
119
|
+
fillcolor = "#e8e8c8";
|
|
120
|
+
width = 0.1;
|
|
121
|
+
penwidth = 1;
|
|
122
|
+
style = "filled";
|
|
123
|
+
label = "r0_1-eth-s3";
|
|
124
|
+
shape = "box";
|
|
125
|
+
fontsize = 10;
|
|
126
|
+
height = 0.1;
|
|
127
|
+
];
|
|
128
|
+
"out_DASH_h3_1_DASH_eth0" [
|
|
129
|
+
color = "#af6b4e";
|
|
130
|
+
fillcolor = "#e8e8c8";
|
|
131
|
+
width = 0.1;
|
|
132
|
+
penwidth = 1;
|
|
133
|
+
style = "filled";
|
|
134
|
+
label = "h3_1-eth0";
|
|
135
|
+
shape = "box";
|
|
136
|
+
fontsize = 10;
|
|
137
|
+
height = 0.1;
|
|
138
|
+
];
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
subgraph "cluster_service_r0" {
|
|
142
|
+
shape = "box";
|
|
143
|
+
fontsize = 14;
|
|
144
|
+
style = "rounded,filled";
|
|
145
|
+
penwidth = 2;
|
|
146
|
+
fillcolor = "#c1d0d7";
|
|
147
|
+
color = "#7396a6";
|
|
148
|
+
label = "service 'r0'";
|
|
149
|
+
"r0_COLON_eth_DASH_s1" [
|
|
150
|
+
color = "#af6b4e";
|
|
151
|
+
fillcolor = "#e8e8c8";
|
|
152
|
+
width = 0.1;
|
|
153
|
+
penwidth = 1;
|
|
154
|
+
style = "filled";
|
|
155
|
+
label = "eth-s1";
|
|
156
|
+
shape = "box";
|
|
157
|
+
fontsize = 10;
|
|
158
|
+
height = 0.1;
|
|
159
|
+
];
|
|
160
|
+
"r0_COLON_eth_DASH_s2" [
|
|
161
|
+
color = "#af6b4e";
|
|
162
|
+
fillcolor = "#e8e8c8";
|
|
163
|
+
width = 0.1;
|
|
164
|
+
penwidth = 1;
|
|
165
|
+
style = "filled";
|
|
166
|
+
label = "eth-s2";
|
|
167
|
+
shape = "box";
|
|
168
|
+
fontsize = 10;
|
|
169
|
+
height = 0.1;
|
|
170
|
+
];
|
|
171
|
+
"r0_COLON_eth_DASH_s3" [
|
|
172
|
+
color = "#af6b4e";
|
|
173
|
+
fillcolor = "#e8e8c8";
|
|
174
|
+
width = 0.1;
|
|
175
|
+
penwidth = 1;
|
|
176
|
+
style = "filled";
|
|
177
|
+
label = "eth-s3";
|
|
178
|
+
shape = "box";
|
|
179
|
+
fontsize = 10;
|
|
180
|
+
height = 0.1;
|
|
181
|
+
];
|
|
182
|
+
}
|
|
183
|
+
subgraph "cluster_service_h1" {
|
|
184
|
+
shape = "box";
|
|
185
|
+
fontsize = 14;
|
|
186
|
+
style = "rounded,filled";
|
|
187
|
+
penwidth = 2;
|
|
188
|
+
fillcolor = "#c1d0d7";
|
|
189
|
+
color = "#7396a6";
|
|
190
|
+
label = "service 'h1'";
|
|
191
|
+
"h1_COLON_eth0" [
|
|
192
|
+
color = "#af6b4e";
|
|
193
|
+
fillcolor = "#e8e8c8";
|
|
194
|
+
width = 0.1;
|
|
195
|
+
penwidth = 1;
|
|
196
|
+
style = "filled";
|
|
197
|
+
label = "eth0";
|
|
198
|
+
shape = "box";
|
|
199
|
+
fontsize = 10;
|
|
200
|
+
height = 0.1;
|
|
201
|
+
];
|
|
202
|
+
}
|
|
203
|
+
subgraph "cluster_service_h2" {
|
|
204
|
+
shape = "box";
|
|
205
|
+
fontsize = 14;
|
|
206
|
+
style = "rounded,filled";
|
|
207
|
+
penwidth = 2;
|
|
208
|
+
fillcolor = "#c1d0d7";
|
|
209
|
+
color = "#7396a6";
|
|
210
|
+
label = "service 'h2'";
|
|
211
|
+
"h2_COLON_eth0" [
|
|
212
|
+
color = "#af6b4e";
|
|
213
|
+
fillcolor = "#e8e8c8";
|
|
214
|
+
width = 0.1;
|
|
215
|
+
penwidth = 1;
|
|
216
|
+
style = "filled";
|
|
217
|
+
label = "eth0";
|
|
218
|
+
shape = "box";
|
|
219
|
+
fontsize = 10;
|
|
220
|
+
height = 0.1;
|
|
221
|
+
];
|
|
222
|
+
}
|
|
223
|
+
subgraph "cluster_service_h3" {
|
|
224
|
+
shape = "box";
|
|
225
|
+
fontsize = 14;
|
|
226
|
+
style = "rounded,filled";
|
|
227
|
+
penwidth = 2;
|
|
228
|
+
fillcolor = "#c1d0d7";
|
|
229
|
+
color = "#7396a6";
|
|
230
|
+
label = "service 'h3'";
|
|
231
|
+
"h3_COLON_eth0" [
|
|
232
|
+
color = "#af6b4e";
|
|
233
|
+
fillcolor = "#e8e8c8";
|
|
234
|
+
width = 0.1;
|
|
235
|
+
penwidth = 1;
|
|
236
|
+
style = "filled";
|
|
237
|
+
label = "eth0";
|
|
238
|
+
shape = "box";
|
|
239
|
+
fontsize = 10;
|
|
240
|
+
height = 0.1;
|
|
241
|
+
];
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
"r0_COLON_eth_DASH_s1" -> "out_DASH_r0_1_DASH_eth_DASH_s1" [
|
|
245
|
+
shape = "box";
|
|
246
|
+
fontsize = 14;
|
|
247
|
+
style = "filled";
|
|
248
|
+
penwidth = 1;
|
|
249
|
+
label = "";
|
|
250
|
+
];
|
|
251
|
+
"r0_COLON_eth_DASH_s2" -> "out_DASH_r0_1_DASH_eth_DASH_s2" [
|
|
252
|
+
shape = "box";
|
|
253
|
+
fontsize = 14;
|
|
254
|
+
style = "filled";
|
|
255
|
+
penwidth = 1;
|
|
256
|
+
label = "";
|
|
257
|
+
];
|
|
258
|
+
"r0_COLON_eth_DASH_s3" -> "out_DASH_r0_1_DASH_eth_DASH_s3" [
|
|
259
|
+
shape = "box";
|
|
260
|
+
fontsize = 14;
|
|
261
|
+
style = "filled";
|
|
262
|
+
penwidth = 1;
|
|
263
|
+
label = "";
|
|
264
|
+
];
|
|
265
|
+
"h1_COLON_eth0" -> "out_DASH_h1_1_DASH_eth0" [
|
|
266
|
+
shape = "box";
|
|
267
|
+
fontsize = 14;
|
|
268
|
+
style = "filled";
|
|
269
|
+
penwidth = 1;
|
|
270
|
+
label = "";
|
|
271
|
+
];
|
|
272
|
+
"h2_COLON_eth0" -> "out_DASH_h2_1_DASH_eth0" [
|
|
273
|
+
shape = "box";
|
|
274
|
+
fontsize = 14;
|
|
275
|
+
style = "filled";
|
|
276
|
+
penwidth = 1;
|
|
277
|
+
label = "";
|
|
278
|
+
];
|
|
279
|
+
"h3_COLON_eth0" -> "out_DASH_h3_1_DASH_eth0" [
|
|
280
|
+
shape = "box";
|
|
281
|
+
fontsize = 14;
|
|
282
|
+
style = "filled";
|
|
283
|
+
penwidth = 1;
|
|
284
|
+
label = "";
|
|
285
|
+
];
|
|
286
|
+
}
|
package/examples/test6-cfn.yaml
CHANGED
|
@@ -88,10 +88,9 @@ Resources:
|
|
|
88
88
|
# echo "podman ps" | sudo -i -u ubuntu bash
|
|
89
89
|
|
|
90
90
|
## Download conlink image and repo
|
|
91
|
-
docker pull lonocloud/conlink
|
|
91
|
+
docker pull lonocloud/conlink
|
|
92
92
|
git clone https://github.com/LonoCloud/conlink /root/conlink
|
|
93
93
|
cd /root/conlink
|
|
94
|
-
git checkout -b config-and-cljs-refactor origin/config-and-cljs-refactor
|
|
95
94
|
|
|
96
95
|
#cfn-signal -e 0 --stack ${AWS::StackName} --region ${AWS::Region} --resource WaitHandle
|
|
97
96
|
cat > /tmp/signal << EOF
|
package/host-build.yaml
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
services: {network: {volumes: ["
|
|
1
|
+
services: {network: {volumes: ["../:/app/"]}}
|
package/modes0/a/deps
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
b,c
|
package/modes0/b/deps
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
c,d
|
package/modes0/c/deps
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
e
|
package/modes0/e/deps
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
f
|
package/modes1/a/deps
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
b c|d
|
package/modes1/b/deps
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
e f
|
package/modes1/c/deps
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
g
|
package/modes1/d/deps
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
g h
|
package/modes2/a/deps
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
b c
|
package/modes2/b/deps
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
c|d
|
package/modes2/c/deps
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
e
|
package/modes2/d/de
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
e
|
package/modes2/d/deps
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
e
|
package/modes3/ab/deps
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
base
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
base mach3|ab
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
base
|
package/modes4/a/deps
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
b c
|
package/modes4/b/deps
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
d|c
|
package/net2dot
CHANGED
package/net2dot.cljs
ADDED
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
#!/usr/bin/env nbb
|
|
2
|
+
|
|
3
|
+
;; Copyright (c) 2023, Viasat, Inc
|
|
4
|
+
;; Licensed under MPL 2.0
|
|
5
|
+
|
|
6
|
+
(ns net2dot
|
|
7
|
+
(:require [clojure.string :as S]
|
|
8
|
+
[clojure.pprint :refer [pprint]]
|
|
9
|
+
[cljs-bean.core :refer [->clj ->js]]
|
|
10
|
+
["fs" :as fs]
|
|
11
|
+
["ts-graphviz" :refer [Digraph Subgraph toDot Node Edge]]))
|
|
12
|
+
|
|
13
|
+
;; Reads JSON network config from stdin and outputs to dot (GraphViz)
|
|
14
|
+
|
|
15
|
+
(def DEFAULT-PROPS {:shape "box" :fontsize 14 :style "filled" :penwidth 1})
|
|
16
|
+
(def CONLINK-PROPS {:fillcolor "#c5d1e7" :color "#7396a0" :style "rounded,filled" :penwidth 3})
|
|
17
|
+
(def CON-PROPS {:fillcolor "#dfe8f1" :color "#7396a6" :style "rounded,filled"})
|
|
18
|
+
(def SVC-PROPS {:fillcolor "#c1d0d7" :color "#7396a6" :style "rounded,filled" :penwidth 2})
|
|
19
|
+
(def BRIDGE-PROPS {:fillcolor "#c8badc" :color "#6e509f"})
|
|
20
|
+
(def HOST-PROPS {:fillcolor "#f5f5f5" :color "#666666"})
|
|
21
|
+
(def INTF-PROPS {:fillcolor "#e8e8c8" :color "#af6b4e" :fontsize 10 :width 0.1 :height 0.1})
|
|
22
|
+
(def NIC-PROPS {:fillcolor "#e8e8c8" :color "#af6b4e" :fontsize 14})
|
|
23
|
+
(def TUN-PROPS {:fillcolor "#a5f5a5" :color "#888888"})
|
|
24
|
+
|
|
25
|
+
(defn dot-id [n]
|
|
26
|
+
(-> (name n)
|
|
27
|
+
(S/replace #"[:]" "_COLON_")
|
|
28
|
+
(S/replace #"[-]" "_DASH_")
|
|
29
|
+
(S/replace #"[*]" "_STAR_")
|
|
30
|
+
(S/replace #"[$]" "_DOLLAR_")
|
|
31
|
+
(S/replace #"[{]" "_LCURLY_")
|
|
32
|
+
(S/replace #"[}]" "_LCURLY_")
|
|
33
|
+
(S/replace #"[ ]" "_SPACE_")))
|
|
34
|
+
|
|
35
|
+
(defn node-props [label props]
|
|
36
|
+
(merge DEFAULT-PROPS props {:label label}))
|
|
37
|
+
|
|
38
|
+
(defn digraph [props]
|
|
39
|
+
(Digraph. (->js {:splines true :compound true})))
|
|
40
|
+
|
|
41
|
+
(defn subgraph [parent id label props]
|
|
42
|
+
(let [n (Subgraph. id (->js (node-props label props)))]
|
|
43
|
+
^obj (.addSubgraph parent n)
|
|
44
|
+
n))
|
|
45
|
+
|
|
46
|
+
(defn node [parent id label props]
|
|
47
|
+
(let [n (Node. id (->js (node-props label props)))]
|
|
48
|
+
^obj (.addNode parent n)
|
|
49
|
+
n))
|
|
50
|
+
|
|
51
|
+
(defn edge [parent idA idB label props]
|
|
52
|
+
(let [n (Edge. #js [idA idB] (->js (node-props label props)))]
|
|
53
|
+
^obj (.addEdge parent n)
|
|
54
|
+
n))
|
|
55
|
+
|
|
56
|
+
(defn render [network-config]
|
|
57
|
+
(let [graph (digraph {:splines true :compound true})
|
|
58
|
+
host (subgraph graph "cluster_host" "host system" HOST-PROPS)
|
|
59
|
+
conlink (subgraph host "cluster_conlink" "conlink/network" CONLINK-PROPS)
|
|
60
|
+
bridges (reduce
|
|
61
|
+
#(->> (subgraph conlink (str "cluster_bridge_" %2)
|
|
62
|
+
%2 BRIDGE-PROPS)
|
|
63
|
+
(assoc %1 %2))
|
|
64
|
+
{} (keep :bridge (:links network-config)))
|
|
65
|
+
services (reduce
|
|
66
|
+
#(->> (subgraph host (str "cluster_service_" (dot-id %2))
|
|
67
|
+
(str "service '" (name %2) "'") SVC-PROPS)
|
|
68
|
+
(assoc %1 %2))
|
|
69
|
+
{} (keys (:services network-config)))
|
|
70
|
+
containers (reduce
|
|
71
|
+
#(->> (subgraph host (str "cluster_container_" (dot-id %2))
|
|
72
|
+
(str "container '" (name %2) "'") CON-PROPS)
|
|
73
|
+
(assoc %1 %2))
|
|
74
|
+
{} (keys (:containers network-config)))]
|
|
75
|
+
|
|
76
|
+
(doseq [link (:links network-config)]
|
|
77
|
+
(let [{:keys [service container dev outer-dev bridge base]} link
|
|
78
|
+
cname (or service container)
|
|
79
|
+
cnode (get (if service services containers) (keyword cname))
|
|
80
|
+
dev-id (str cname ":" (name dev))
|
|
81
|
+
in-intf (node cnode (dot-id dev-id) dev INTF-PROPS)]
|
|
82
|
+
(when (#{:conlink :host} (keyword base))
|
|
83
|
+
(let [outer-dev (or outer-dev
|
|
84
|
+
(str (if service (str service "_1") container)
|
|
85
|
+
"-" (name dev)))
|
|
86
|
+
out-id (str "out-" outer-dev)
|
|
87
|
+
out-parent (condp = (keyword base)
|
|
88
|
+
:conlink (get bridges bridge)
|
|
89
|
+
:host host)
|
|
90
|
+
{:keys [type vlanid]} link
|
|
91
|
+
[elabel iprops] (if (= "host" base)
|
|
92
|
+
[(str (name type) (when vlanid
|
|
93
|
+
(str " " vlanid)))
|
|
94
|
+
NIC-PROPS]
|
|
95
|
+
["" INTF-PROPS])
|
|
96
|
+
out-intf (node out-parent (dot-id out-id) outer-dev iprops)
|
|
97
|
+
edge (edge graph in-intf out-intf elabel {})]
|
|
98
|
+
true))))
|
|
99
|
+
|
|
100
|
+
(doseq [{:keys [type remote bridge vni]} (:tunnels network-config)]
|
|
101
|
+
(let [br (get bridges bridge)
|
|
102
|
+
rt (node graph (dot-id remote)
|
|
103
|
+
(str "remote host " remote) TUN-PROPS)
|
|
104
|
+
intf (node br (dot-id (str type "-" vni))
|
|
105
|
+
(str type "-" vni) INTF-PROPS)]
|
|
106
|
+
(edge graph intf rt "" {})))
|
|
107
|
+
|
|
108
|
+
(toDot graph)))
|
|
109
|
+
|
|
110
|
+
(let [stdin (fs/readFileSync "/dev/stdin" "utf8")
|
|
111
|
+
network-config (->clj (js/JSON.parse stdin))
|
|
112
|
+
dot-graph (render network-config)]
|
|
113
|
+
(println dot-graph))
|
package/net2dot.mjs
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { attribute as _, Digraph, Subgraph, Node, Edge, toDot } from 'ts-graphviz';
|
|
2
|
+
|
|
3
|
+
const G = new Digraph();
|
|
4
|
+
const A = new Subgraph('A');
|
|
5
|
+
const node1 = new Node('node1', {
|
|
6
|
+
color: 'red'
|
|
7
|
+
});
|
|
8
|
+
const node2 = new Node('node2', {
|
|
9
|
+
color: 'blue'
|
|
10
|
+
});
|
|
11
|
+
const edge = new Edge([node1, node2], {
|
|
12
|
+
label: 'Edge Label',
|
|
13
|
+
color: 'pink'
|
|
14
|
+
});
|
|
15
|
+
G.addSubgraph(A);
|
|
16
|
+
A.addNode(node1);
|
|
17
|
+
A.addNode(node2);
|
|
18
|
+
A.addEdge(edge);
|
|
19
|
+
const dot = toDot(G);
|
|
20
|
+
|
|
21
|
+
console.log(dot)
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
(ns conlink.net2dot
|
|
2
|
+
(:require ["ts-graphviz" :refer [Digraph, Subgraph, Node, Edge, toDot]]))
|
|
3
|
+
|
|
4
|
+
(let [node1 (Node. "node1" #js {:color "red"})
|
|
5
|
+
node2 (Node. "node2" #js {:color "blue"})
|
|
6
|
+
edge (Edge. #js [node1 node2] #js {:color "pink"
|
|
7
|
+
:label "Edge Label"})
|
|
8
|
+
A (doto (Subgraph. "A")
|
|
9
|
+
(.addNode node1)
|
|
10
|
+
(.addNode node2)
|
|
11
|
+
(.addEdge edge))
|
|
12
|
+
G (doto (Digraph.)
|
|
13
|
+
(.addSubgraph A))]
|
|
14
|
+
(println (toDot G)))
|
package/old/net2dot.cljs
ADDED
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
#!/usr/bin/env nbb
|
|
2
|
+
|
|
3
|
+
(ns net2dot
|
|
4
|
+
(:require [clojure.string :as S]
|
|
5
|
+
[clojure.pprint :refer [pprint]]
|
|
6
|
+
[cljs-bean.core :refer [->clj ->js]]
|
|
7
|
+
["fs" :as fs]
|
|
8
|
+
["ts-graphviz" :refer [Digraph Subgraph toDot Node Edge]]))
|
|
9
|
+
|
|
10
|
+
;; Reads JSON network config from stdin and outputs to dot (GraphViz)
|
|
11
|
+
|
|
12
|
+
(def DEFAULT-PROPS {:shape "box" :fontsize 14 :style "filled" :penwidth 1})
|
|
13
|
+
(def CONLINK-PROPS {:style "rounded,filled" :fillcolor "#c1b5c7" :color "#9673a6"})
|
|
14
|
+
(def BRIDGE-PROPS {:style "filled" :fillcolor "#dae8fc" :color "#6c8ebf"})
|
|
15
|
+
(def HOST-PROPS {:style "filled" :fillcolor "#f5f5f5" :color "#666666"})
|
|
16
|
+
(def TUN-PROPS {:fillcolor "#a5a5a5" :color "#888888"})
|
|
17
|
+
(def INTF-PROPS {:width 0.1 :height 0.1 :fontsize 10 :fillcolor "#ffbb9e" :color "#d7db00"})
|
|
18
|
+
(def NIC-PROPS {:fontsize 14 :fillcolor "#ffbb9e" :color "#d7db00"})
|
|
19
|
+
(def CONTAINER-PROPS {:style "rounded,filled" :fillcolor "#e1d5e7" :color "#9673a6"})
|
|
20
|
+
(def SERVICE-PROPS (merge CONTAINER-PROPS {:fillcolor "#d1c5e7" :penwidth 2}))
|
|
21
|
+
|
|
22
|
+
(defn dot-id [n]
|
|
23
|
+
(-> (name n)
|
|
24
|
+
(S/replace #"[:]" "_COLON_")
|
|
25
|
+
(S/replace #"[-]" "_DASH_")
|
|
26
|
+
(S/replace #"[*]" "_STAR_")
|
|
27
|
+
(S/replace #"[$]" "_DOLLAR_")
|
|
28
|
+
(S/replace #"[{]" "_LCURLY_")
|
|
29
|
+
(S/replace #"[}]" "_LCURLY_")
|
|
30
|
+
(S/replace #"[ ]" "_SPACE_")))
|
|
31
|
+
|
|
32
|
+
(defn node-props [label props]
|
|
33
|
+
(merge DEFAULT-PROPS props {:label label}))
|
|
34
|
+
|
|
35
|
+
(defn digraph [props]
|
|
36
|
+
(Digraph. (->js {:splines true :compound true})))
|
|
37
|
+
|
|
38
|
+
(defn subgraph [parent id label props]
|
|
39
|
+
(let [n (Subgraph. id (->js (node-props label props)))]
|
|
40
|
+
^obj (.addSubgraph parent n)
|
|
41
|
+
n))
|
|
42
|
+
|
|
43
|
+
(defn node [parent id label props]
|
|
44
|
+
(let [n (Node. id (->js (node-props label props)))]
|
|
45
|
+
^obj (.addNode parent n)
|
|
46
|
+
n))
|
|
47
|
+
|
|
48
|
+
(defn edge [parent idA idB label props]
|
|
49
|
+
(let [n (Edge. #js [idA idB] (->js (node-props label props)))]
|
|
50
|
+
^obj (.addEdge parent n)
|
|
51
|
+
n))
|
|
52
|
+
|
|
53
|
+
(defn render [network-config]
|
|
54
|
+
(let [graph (digraph {:splines true :compound true})
|
|
55
|
+
host (subgraph graph "cluster_host" "host system" HOST-PROPS)
|
|
56
|
+
conlink (subgraph host "cluster_conlink" "conlink/network" CONLINK-PROPS)
|
|
57
|
+
bridges (reduce
|
|
58
|
+
#(assoc %1 %2
|
|
59
|
+
(subgraph conlink (str "cluster_bridge_" %2)
|
|
60
|
+
%2 BRIDGE-PROPS))
|
|
61
|
+
{} (keep :bridge (:links network-config)))
|
|
62
|
+
services (reduce
|
|
63
|
+
#(assoc %1 %2
|
|
64
|
+
(subgraph host
|
|
65
|
+
(str "cluster_service_" (dot-id %2))
|
|
66
|
+
(str "service '" %2 "'") SERVICE-PROPS))
|
|
67
|
+
{} (keys (:services network-config)))
|
|
68
|
+
containers (reduce
|
|
69
|
+
#(assoc %1 %2
|
|
70
|
+
(subgraph host
|
|
71
|
+
(str "cluster_container_" (dot-id %2))
|
|
72
|
+
(str "container '" %2 "'") CONTAINER-PROPS))
|
|
73
|
+
{} (keys (:services network-config)))
|
|
74
|
+
]
|
|
75
|
+
|
|
76
|
+
(doseq [link links]
|
|
77
|
+
(let [{:keys [service container dev outer-dev bridge base]} link
|
|
78
|
+
cname (or service container)
|
|
79
|
+
cn (get (if service services containers) cname)
|
|
80
|
+
dev-id (str cname ":" (name dev))
|
|
81
|
+
in-intf (node cn (dot-id dev-id) dev INTF-PROPS)]
|
|
82
|
+
(when (#{:conlink :host} (keyword base))
|
|
83
|
+
(let [outer-dev (or outer-dev
|
|
84
|
+
(str (if service (str service "_1") container)
|
|
85
|
+
"-" (name dev)))
|
|
86
|
+
out-id (str "out-" outer-dev)
|
|
87
|
+
out-parent (condp = (keyword base)
|
|
88
|
+
:conlink (get bridges bridge)
|
|
89
|
+
:host host)
|
|
90
|
+
{:keys [type vlanid]} link
|
|
91
|
+
[elabel iprops] (if (= "host" base)
|
|
92
|
+
[(str (name type) (when vlanid
|
|
93
|
+
(str " " vlanid)))
|
|
94
|
+
NIC-PROPS]
|
|
95
|
+
["" INTF-PROPS])
|
|
96
|
+
out-intf (node out-parent (dot-id out-id) outer-dev iprops)
|
|
97
|
+
edge (edge graph in-intf out-intf elabel {})]
|
|
98
|
+
true))))
|
|
99
|
+
|
|
100
|
+
(doseq [{:keys [type remote bridge vni]} (:tunnels network-config)]
|
|
101
|
+
(let [br (get bridges bridge)
|
|
102
|
+
rt (node graph (dot-id remote)
|
|
103
|
+
(str "remote host " remote) TUN-PROPS)
|
|
104
|
+
intf (node br (dot-id (str type "-" vni))
|
|
105
|
+
(str type "-" vni) INTF-PROPS)]
|
|
106
|
+
(edge graph intf rt "" {})))
|
|
107
|
+
|
|
108
|
+
(toDot graph)))
|
|
109
|
+
|
|
110
|
+
(defn main []
|
|
111
|
+
(let [stdin (fs/readFileSync "/dev/stdin" "utf8")
|
|
112
|
+
network-config (->clj (js/JSON.parse stdin))
|
|
113
|
+
dot-graph (render network-config)]
|
|
114
|
+
(println dot-graph)))
|