conlink 2.0.0 → 2.0.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/Dockerfile +2 -1
- package/README.md +18 -14
- package/examples/net2dot.yaml +2 -2
- package/examples/test4-multiple/modes/all/deps +1 -0
- package/examples/test4-multiple/{base-compose.yaml → modes/base/compose.yaml} +3 -3
- package/examples/test4-multiple/{node1-compose.yaml → modes/node1/compose.yaml} +0 -3
- package/examples/test4-multiple/modes/node1/deps +1 -0
- package/examples/test4-multiple/{nodes2-compose.yaml → modes/nodes2/compose.yaml} +0 -5
- package/examples/test4-multiple/modes/nodes2/deps +1 -0
- package/examples/test4-multiple/modes/web/compose.yaml +5 -0
- package/examples/test4-multiple/modes/web/deps +1 -0
- package/examples/test6-cfn.yaml +1 -2
- package/mdc +108 -0
- package/net2dot +1 -1
- package/net2dot.cljs +113 -0
- package/package.json +6 -1
- package/scripts/copy.sh +48 -0
- package/scripts/wait.sh +73 -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/TODO +0 -34
- package/examples/test4-multiple/all-compose.yaml +0 -5
- package/examples/test4-multiple/web-network.yaml +0 -2
- package/host-build.yaml +0 -1
- package/inspect.json +0 -210
- package/notes.txt +0 -82
- package/old/Dockerfile.bak +0 -26
- package/old/add-link.sh +0 -82
- package/old/conlink +0 -12
- package/old/conlink.cljs +0 -131
- package/old/dot_gitignore +0 -1
- package/old/examples/test2-compose.yaml +0 -32
- package/old/examples/test2-network.yaml +0 -42
- package/old/move-link.sh +0 -108
- package/old/net2dot.py +0 -122
- package/old/notes-old.txt +0 -97
- package/old/package.json +0 -16
- package/old/schema.yaml +0 -138
- package/old/schema.yaml.bak +0 -76
- package/old/test2b-compose.yaml +0 -18
- package/old/veth-link.sh +0 -96
- package/schema-ish.yaml +0 -29
- package/src/conlink/net2dot.cljs +0 -158
- package/tests/invalid-schema-1.yaml +0 -6
- package/tests/invalid-schema-2.yaml +0 -6
- package/tests/invalid-schema-3.yaml +0 -17
- package/tests/invalid-schema-4.yaml +0 -14
- package/tests/invalid-schema-5.yaml +0 -12
- package/tests/invalid-schema-6.yaml +0 -12
- package/tmp/conlink/.env +0 -1
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
# "Physical" network interface definitions.
|
|
2
|
-
# This defines container to container links.
|
|
3
|
-
links:
|
|
4
|
-
- left: {container: node1_1, intf: eth0, ip: 10.0.1.1/16}
|
|
5
|
-
right: {container: network_1, intf: node1-eth0}
|
|
6
|
-
- left: {container: node2_1, intf: eth0, ip: 10.0.1.2/16}
|
|
7
|
-
right: {container: network_1, intf: node2-eth0}
|
|
8
|
-
|
|
9
|
-
# Commands to run in containers after they are connected
|
|
10
|
-
commands:
|
|
11
|
-
- container: node1_1
|
|
12
|
-
command: ip route add default via 10.0.0.1
|
|
13
|
-
- container: node2_1
|
|
14
|
-
command: ip route add default via 10.0.0.1
|
|
15
|
-
|
|
16
|
-
# Network container mininet configuration
|
|
17
|
-
# This configuration is used by config_mininet.py inside the network
|
|
18
|
-
# container to define complex network elements (routers, switches,
|
|
19
|
-
# etc).
|
|
20
|
-
mininet-cfg:
|
|
21
|
-
switches:
|
|
22
|
-
- name: s1 # the switch between node1, node2, and internet
|
|
23
|
-
hosts:
|
|
24
|
-
- name: internet
|
|
25
|
-
opts: {ip: 10.0.0.1/16}
|
|
26
|
-
interfaces:
|
|
27
|
-
- name: node1-eth0
|
|
28
|
-
node: s1
|
|
29
|
-
- name: node2-eth0
|
|
30
|
-
node: s1
|
|
31
|
-
links:
|
|
32
|
-
- left: internet
|
|
33
|
-
right: s1
|
|
34
|
-
|
|
35
|
-
commands:
|
|
36
|
-
# In "internet" listen to 8.8.8.* addresses.
|
|
37
|
-
- node: internet
|
|
38
|
-
sync: true
|
|
39
|
-
command:
|
|
40
|
-
- ip link add ${DNS_INTF:-gdns} type dummy
|
|
41
|
-
- ip link set ${DNS_INTF:-gdns} up
|
|
42
|
-
- ip addr add 8.8.8.8/24 dev ${DNS_INTF:-gdns}
|
package/old/move-link.sh
DELETED
|
@@ -1,108 +0,0 @@
|
|
|
1
|
-
#!/bin/bash
|
|
2
|
-
|
|
3
|
-
# Copyright (c) 2023, Viasat, Inc
|
|
4
|
-
# Licensed under MPL 2.0
|
|
5
|
-
|
|
6
|
-
set -e
|
|
7
|
-
|
|
8
|
-
usage () {
|
|
9
|
-
echo >&2 "${0} [OPTIONS] TYPE INTF0 INTF1 PID0 PID1"
|
|
10
|
-
echo >&2 ""
|
|
11
|
-
echo >&2 " TYPE: one of the following values: move, vlan, macvlan,"
|
|
12
|
-
echo >&2 " macvtap, ipvlan, or ipvtap. If TYPE is 'move'"
|
|
13
|
-
echo >&2 " then INTF0 will be moved directly. For any other"
|
|
14
|
-
echo >&2 " TYPE a sub-interface of TYPE will be created on"
|
|
15
|
-
echo >&2 " INTF0 and the sub-interface virtual link will be"
|
|
16
|
-
echo >&2 " moved instead."
|
|
17
|
-
echo >&2 " INTF0: the interface in PID0 to move to PID1"
|
|
18
|
-
echo >&2 " INTF1: the interface in PID1 after moving"
|
|
19
|
-
echo >&2 " PID0: the process ID of the first namespace"
|
|
20
|
-
echo >&2 " PID1: the process ID of the second namespace"
|
|
21
|
-
echo >&2 ""
|
|
22
|
-
echo >&2 "OPTIONS:"
|
|
23
|
-
echo >&2 " --verbose - Verbose output (set -x)"
|
|
24
|
-
echo >&2 " --mode MODE - Mode setting for *vlan, *vtap TYPEs"
|
|
25
|
-
echo >&2 " --vlanid VLANID - VLAN ID for vlan TYPE"
|
|
26
|
-
echo >&2 " --ip IP - Add IP (CIDR) to the moved interface"
|
|
27
|
-
echo >&2 " --route 'ROUTE' - route to add to the moved interface"
|
|
28
|
-
echo >&2 " --nat TARGET - Stateless NAT traffic to/from TARGET"
|
|
29
|
-
exit 2
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
IPTABLES() {
|
|
33
|
-
local ns=${1}; shift
|
|
34
|
-
ip netns exec ${ns} iptables -D "${@}" 2>/dev/null || true
|
|
35
|
-
ip netns exec ${ns} iptables -I "${@}"
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
VERBOSE=${VERBOSE:-}
|
|
39
|
-
MODE= VLANID= IP= ROUTE= TARGET=
|
|
40
|
-
|
|
41
|
-
info() { echo "move-link [${PID0}/${IF0} ->> ${PID1}/${IF1}] ${*}"; }
|
|
42
|
-
warn() { >&2 echo "move-link [${PID0}/${IF0} ->> ${PID1}/${IF1}] ${*}"; }
|
|
43
|
-
die() { warn "ERROR: ${*}"; exit 1; }
|
|
44
|
-
|
|
45
|
-
# Parse arguments
|
|
46
|
-
positional=
|
|
47
|
-
while [ "${*}" ]; do
|
|
48
|
-
param=$1; OPTARG=$2
|
|
49
|
-
case ${param} in
|
|
50
|
-
--verbose) VERBOSE=1 ;;
|
|
51
|
-
--mode) MODE="${OPTARG}"; shift ;;
|
|
52
|
-
--vlanid) VLANID="${OPTARG}"; shift ;;
|
|
53
|
-
--ip) IP="${OPTARG}"; shift ;;
|
|
54
|
-
--route) ROUTE="${OPTARG}"; shift ;;
|
|
55
|
-
--nat) TARGET="${OPTARG}"; shift ;;
|
|
56
|
-
-h|--help) usage ;;
|
|
57
|
-
*) positional="${positional} $1" ;;
|
|
58
|
-
esac
|
|
59
|
-
shift
|
|
60
|
-
done
|
|
61
|
-
set -- ${positional}
|
|
62
|
-
|
|
63
|
-
TYPE=$1 IF0=$2 IF1=$3 PID0=$4 PID1=$5 NS0=ns${PID0} NS1=ns${PID1}
|
|
64
|
-
|
|
65
|
-
[ "${VERBOSE}" ] && set -x || true
|
|
66
|
-
|
|
67
|
-
# Check arguments
|
|
68
|
-
[ "${$#}" -lt 5 ] && usage
|
|
69
|
-
[ "${TARGET}" -a -z "${IP}" ] && die "--nat requires --ip"
|
|
70
|
-
|
|
71
|
-
# Sanity checks
|
|
72
|
-
[ ! -d /proc/$PID0 ] && die "PID0 $PID0 is no longer running!"
|
|
73
|
-
[ ! -d /proc/$PID1 ] && die "PID1 $PID1 is no longer running!"
|
|
74
|
-
|
|
75
|
-
export PATH=$PATH:/usr/sbin
|
|
76
|
-
mkdir -p /var/run/netns
|
|
77
|
-
ln -sf /proc/${PID0}/ns/net /var/run/netns/${NS0}
|
|
78
|
-
ln -sf /proc/${PID1}/ns/net /var/run/netns/${NS1}
|
|
79
|
-
|
|
80
|
-
info "Moving ${TYPE} link (${IP})"
|
|
81
|
-
|
|
82
|
-
case "${TYPE}" in
|
|
83
|
-
macvlan|macvtap|ipvlan|ipvtap|vlan)
|
|
84
|
-
ip -netns ${NS0} link add link ${IF0} name tmp$$ type ${TYPE} \
|
|
85
|
-
${MODE:+mode ${MODE}} ${VLANID:+id ${VLANID}}
|
|
86
|
-
ip -netns ${NS0} link set tmp$$ netns ${NS1} name ${IF1}
|
|
87
|
-
;;
|
|
88
|
-
move)
|
|
89
|
-
ip -netns ${NS0} link set ${IF0} netns ${NS1} name ${IF1}
|
|
90
|
-
;;
|
|
91
|
-
esac
|
|
92
|
-
|
|
93
|
-
info "Setting IP, ROUTE, and up state"
|
|
94
|
-
ip -netns ${NS1} --force -b - <<EOF
|
|
95
|
-
${IP:+addr add ${IP} dev ${IF1}}
|
|
96
|
-
link set ${IF1} up
|
|
97
|
-
${ROUTE:+route add ${ROUTE} dev ${IF1}}
|
|
98
|
-
EOF
|
|
99
|
-
|
|
100
|
-
if [ "${TARGET}" ]; then
|
|
101
|
-
info "Adding NAT rule to ${TARGET}"
|
|
102
|
-
IPTABLES ${NS1} PREROUTING -t nat -i ${IF1} -j DNAT --to-destination ${TARGET}
|
|
103
|
-
IPTABLES ${NS1} POSTROUTING -t nat -o ${IF1} -j SNAT --to-source ${IP%/*}
|
|
104
|
-
fi
|
|
105
|
-
|
|
106
|
-
info "Moved ${TYPE} link (${IP})"
|
|
107
|
-
|
|
108
|
-
# /test/move-link.sh --verbose ipvlan enp6s0 host 1 2500144 --ip 192.168.88.32/24 --nat 10.0.1.2
|
package/old/net2dot.py
DELETED
|
@@ -1,122 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env -S python3 -u
|
|
2
|
-
|
|
3
|
-
# Copyright (c) 2021, Viasat, Inc
|
|
4
|
-
# Licensed under MPL 2.0
|
|
5
|
-
|
|
6
|
-
import re, sys, yaml
|
|
7
|
-
|
|
8
|
-
NODE_PROPS = 'shape=box style=filled penwidth=1'
|
|
9
|
-
CONTAINER_PROPS = 'fontsize = 12 style = filled fillcolor = "#e1d5e7" color = "#9673a6"'
|
|
10
|
-
NETWORK_PROPS = '%s penwidth = 2' % CONTAINER_PROPS
|
|
11
|
-
INTF_PROPS = 'width=0.1 height=0.1 fontsize=10 fillcolor="#ffbb9e" color="#d7db00"'
|
|
12
|
-
SWITCH_PROPS = 'fontsize=12 style="rounded,filled" fillcolor="#dae8fc" color="#6c8ebf"'
|
|
13
|
-
HOST_PROPS = 'fontsize=12 fillcolor="#f5f5f5" color="#666666"'
|
|
14
|
-
|
|
15
|
-
def id(n):
|
|
16
|
-
return re.sub(r"-", "_", n)
|
|
17
|
-
|
|
18
|
-
def intfText(cluster, intf):
|
|
19
|
-
name = intf.get('intf', intf.get('origName', intf.get('name')))
|
|
20
|
-
if name.startswith('DUMMY_'):
|
|
21
|
-
return '%s__%s [shape=point style=invis]' % (
|
|
22
|
-
id(cluster), id(name))
|
|
23
|
-
else:
|
|
24
|
-
ip = intf.get('ip', intf.get('opts', {}).get('ip', ''))
|
|
25
|
-
if ip: ip = "\\n%s" % ip
|
|
26
|
-
return '%s__%s [label="%s%s" %s]' % (
|
|
27
|
-
id(cluster), id(name), name, ip, INTF_PROPS)
|
|
28
|
-
|
|
29
|
-
if __name__ == '__main__':
|
|
30
|
-
|
|
31
|
-
networkFile = sys.argv[1]
|
|
32
|
-
networkName = sys.argv[2]
|
|
33
|
-
|
|
34
|
-
netCfg = yaml.full_load(open(networkFile))
|
|
35
|
-
if 'services' in netCfg:
|
|
36
|
-
netService = re.sub(r'_1$', '', networkName)
|
|
37
|
-
netCfg = netCfg['services'][netService]['x-network']
|
|
38
|
-
mnCfg = netCfg['mininet-cfg']
|
|
39
|
-
|
|
40
|
-
links = []
|
|
41
|
-
containers = {}
|
|
42
|
-
containers[networkName] = {'nodes': []}
|
|
43
|
-
namespaces = {}
|
|
44
|
-
|
|
45
|
-
for link in netCfg.get('links', []):
|
|
46
|
-
l, r = link['left'], link['right']
|
|
47
|
-
clname, crname = l['container'], r['container']
|
|
48
|
-
ilname, irname = l['intf'], r['intf']
|
|
49
|
-
links.append([(clname, ilname), (crname, irname)])
|
|
50
|
-
for cname, intf in [(clname, l), (crname, r)]:
|
|
51
|
-
if cname not in containers:
|
|
52
|
-
containers[cname] = {'nodes': []}
|
|
53
|
-
containers[cname]['nodes'].append(intf)
|
|
54
|
-
|
|
55
|
-
for lk in mnCfg.get('links', []):
|
|
56
|
-
l, r = lk['left'], lk['right']
|
|
57
|
-
links.append([(networkName, l), (networkName, r)])
|
|
58
|
-
|
|
59
|
-
for s in mnCfg.get('switches', []):
|
|
60
|
-
namespaces[s['name']] = {'interfaces': [], 'type': 'switch', **s}
|
|
61
|
-
for h in mnCfg.get('hosts', []):
|
|
62
|
-
namespaces[h['name']] = {'interfaces': [], 'type': 'host', **h}
|
|
63
|
-
|
|
64
|
-
for i in mnCfg.get('interfaces', []):
|
|
65
|
-
nm, nd = i.get('origName', i['name']), i['node']
|
|
66
|
-
if nd in namespaces:
|
|
67
|
-
namespaces[nd]['interfaces'].append(i)
|
|
68
|
-
else:
|
|
69
|
-
links.append([(networkName, nm), (networkName, nd)])
|
|
70
|
-
|
|
71
|
-
# Make sure all namespaces have at least one interface so that
|
|
72
|
-
# they can be connected by edges (lhead, ltail)
|
|
73
|
-
for nsname, nsdata in namespaces.items():
|
|
74
|
-
if not nsdata['interfaces']:
|
|
75
|
-
nsdata['interfaces'].append({'name': 'DUMMY_%s' % nsname})
|
|
76
|
-
|
|
77
|
-
###
|
|
78
|
-
|
|
79
|
-
print('digraph D {')
|
|
80
|
-
print(' splines = true;')
|
|
81
|
-
print(' compound = true;')
|
|
82
|
-
print(' node [%s];' % NODE_PROPS)
|
|
83
|
-
|
|
84
|
-
for cname, cdata in containers.items():
|
|
85
|
-
print(' subgraph cluster_%s {' % id(cname))
|
|
86
|
-
print(' label = "%s";' % cname)
|
|
87
|
-
if cname == networkName:
|
|
88
|
-
print(' %s;' % NETWORK_PROPS)
|
|
89
|
-
else:
|
|
90
|
-
print(' %s;' % CONTAINER_PROPS)
|
|
91
|
-
for node in cdata['nodes']:
|
|
92
|
-
print(' %s;' % intfText(node['container'], node))
|
|
93
|
-
# mininet/network interface is processed after container links
|
|
94
|
-
# so that the mininet/network definitions take precedence
|
|
95
|
-
if cname == networkName:
|
|
96
|
-
for nsname, nsdata in namespaces.items():
|
|
97
|
-
print(' subgraph cluster_%s__%s {' % (
|
|
98
|
-
id(cname), id(nsname)))
|
|
99
|
-
print(' label = "%s";' % nsname)
|
|
100
|
-
if nsdata['type'] == 'switch':
|
|
101
|
-
print(' %s;' % SWITCH_PROPS)
|
|
102
|
-
else:
|
|
103
|
-
print(' %s;' % HOST_PROPS)
|
|
104
|
-
for intf in nsdata['interfaces']:
|
|
105
|
-
print(' %s;' % intfText(cname, intf))
|
|
106
|
-
print(' }')
|
|
107
|
-
print(" }")
|
|
108
|
-
|
|
109
|
-
for ((lc, ln), (rc, rn)) in links:
|
|
110
|
-
extra=''
|
|
111
|
-
if lc == networkName and ln in namespaces:
|
|
112
|
-
iname = namespaces[ln]['interfaces'][0]['name']
|
|
113
|
-
extra += ' ltail=cluster_%s__%s' % (id(networkName), id(ln))
|
|
114
|
-
ln = id(iname)
|
|
115
|
-
if rc == networkName and rn in namespaces:
|
|
116
|
-
iname = namespaces[rn]['interfaces'][0]['name']
|
|
117
|
-
extra += ' lhead=cluster_%s__%s' % (id(networkName), id(rn))
|
|
118
|
-
rn = id(iname)
|
|
119
|
-
print(' %s__%s -> %s__%s [dir=none%s];' % (
|
|
120
|
-
id(lc), id(ln), id(rc), id(rn), extra))
|
|
121
|
-
|
|
122
|
-
print("}")
|
package/old/notes-old.txt
DELETED
|
@@ -1,97 +0,0 @@
|
|
|
1
|
-
- MVP for ViaBox:
|
|
2
|
-
- [x] compose/x-network file loading
|
|
3
|
-
- [x] multiple config sources and merging
|
|
4
|
-
- [x] link route config
|
|
5
|
-
- [x] filtering on project and workdir
|
|
6
|
-
- [x] interface and MAC iteration
|
|
7
|
-
- [x] variable templating
|
|
8
|
-
- [ ] *vlan type interfaces
|
|
9
|
-
|
|
10
|
-
- Near term:
|
|
11
|
-
- [ ] dummy interfaces
|
|
12
|
-
- [ ] schema validation
|
|
13
|
-
- [ ] tc/qdisc settings
|
|
14
|
-
- [ ] arbitrary container commands
|
|
15
|
-
|
|
16
|
-
- Further term:
|
|
17
|
-
- [ ] CNI networking support
|
|
18
|
-
- [ ] tunnel interfaces
|
|
19
|
-
- [ ] multiple routes
|
|
20
|
-
- [ ] ovs flow config
|
|
21
|
-
- [ ] Multiple bridge-modes
|
|
22
|
-
- bridge-mode as part of the domain definition so that the
|
|
23
|
-
same conlink instances can support multiple bridge modes
|
|
24
|
-
simultaneously (with a default for links that don't
|
|
25
|
-
specify).
|
|
26
|
-
- [ ] CNI model:
|
|
27
|
-
- conlink runs in container listening for events on a UDS
|
|
28
|
-
(intead of docker events)
|
|
29
|
-
- an outer conlink command is the CNI client that formats
|
|
30
|
-
events to send over the UDS to the inner conlink
|
|
31
|
-
|
|
32
|
-
- Also see schema-ish.yaml
|
|
33
|
-
links:
|
|
34
|
-
- type: TYPE # Default: domain.
|
|
35
|
-
# Others: dummy, tunnel, host, *vlan, etc
|
|
36
|
-
|
|
37
|
-
domain: DOMAIN # ovs switch name
|
|
38
|
-
|
|
39
|
-
container: FOO # full container name
|
|
40
|
-
# OR
|
|
41
|
-
service: FOO # compose service name
|
|
42
|
-
|
|
43
|
-
interface: INTF # internal container interface name
|
|
44
|
-
|
|
45
|
-
# --- optional general ---
|
|
46
|
-
|
|
47
|
-
ip(s): IP # starting address, can include net slash to limit max
|
|
48
|
-
mac: MAC
|
|
49
|
-
mtu: MTU
|
|
50
|
-
route(s): ROUTE # `ip route add ROUTE`, maybe add "dev INTF" automatically
|
|
51
|
-
tc(s): TC # tc/qdisc commands/settings
|
|
52
|
-
flow(s): FLOW # `ovs-ofctl add-flow DOMAIN FLOW`. With var templating.
|
|
53
|
-
command(s): CMD # arbitrary shell cmd. After all links setup for this container
|
|
54
|
-
|
|
55
|
-
# --- optional for 'type:' links ---
|
|
56
|
-
|
|
57
|
-
host-intf: INTF # host interface to *vlan or move in
|
|
58
|
-
mode: MODE # bridge, etc
|
|
59
|
-
vlanid: VLANID # VLAN #
|
|
60
|
-
nat: NAT # nat target
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
- type maps to 'ip link' type with default of 'veth'
|
|
64
|
-
-
|
|
65
|
-
- when type is 'veth', then base default is 'conlink'
|
|
66
|
-
- when type is 'veth' and base is 'conlink', then bridge is required.
|
|
67
|
-
|
|
68
|
-
- conlink veth link: {type: veth [DEFAULT], base: conlink [DEFAULT], bridge: BRIDGE, dev: DEV}
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
Dependencies in python version:
|
|
73
|
-
- argparse
|
|
74
|
-
- shlex (parsing commands)
|
|
75
|
-
- compose_interpolation import TemplateWithDefaults
|
|
76
|
-
- cerberus import Validator
|
|
77
|
-
- options: joi, ajv, json-schema, and z-schema.
|
|
78
|
-
- docker
|
|
79
|
-
- psutil (pid_exists)
|
|
80
|
-
- json
|
|
81
|
-
- yaml
|
|
82
|
-
- mininet
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
- [deprecated idea] conlink sub-commands:
|
|
86
|
-
conlink spit
|
|
87
|
-
- output override docker-compose file with conlink service
|
|
88
|
-
- figure out volume mounts to get to other compose file(s)
|
|
89
|
-
conlink dc up ...
|
|
90
|
-
- generate override docker-compose file with conlink service
|
|
91
|
-
- run the compose command with override file
|
|
92
|
-
conlink start
|
|
93
|
-
- start inside compose
|
|
94
|
-
conlink run
|
|
95
|
-
- start outside compose
|
|
96
|
-
|
|
97
|
-
|
package/old/package.json
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "conlink",
|
|
3
|
-
"dependencies": {
|
|
4
|
-
"@exodus/schemasafe": "^1.3.0",
|
|
5
|
-
"ajv": "^8.12.0",
|
|
6
|
-
"dockerode": "^3.3.4",
|
|
7
|
-
"joi": "^17.10.2",
|
|
8
|
-
"nbb": "^1.2.178",
|
|
9
|
-
"neodoc": "^2.0.2",
|
|
10
|
-
"yaml": "^2.2.1"
|
|
11
|
-
},
|
|
12
|
-
"devDependencies": {
|
|
13
|
-
"shadow-cljs": "^2.25.7",
|
|
14
|
-
"source-map-support": "^0.5.21"
|
|
15
|
-
}
|
|
16
|
-
}
|
package/old/schema.yaml
DELETED
|
@@ -1,138 +0,0 @@
|
|
|
1
|
-
links:
|
|
2
|
-
type: list
|
|
3
|
-
schema:
|
|
4
|
-
type: dict
|
|
5
|
-
schema:
|
|
6
|
-
left:
|
|
7
|
-
type: dict
|
|
8
|
-
required: true
|
|
9
|
-
schema:
|
|
10
|
-
container: {type: string, required: true}
|
|
11
|
-
intf: {type: string, required: true}
|
|
12
|
-
ip: {type: string, required: false,
|
|
13
|
-
regex: '([0-9]+\.){3}[0-9]+\/[0-9]+'}
|
|
14
|
-
mac: {type: string, required: false,
|
|
15
|
-
regex: '([0-9A-Fa-f][0-9A-Fa-f]:){5}[0-9A-Fa-f][0-9A-Fa-f]'}
|
|
16
|
-
right:
|
|
17
|
-
type: dict
|
|
18
|
-
required: true
|
|
19
|
-
schema:
|
|
20
|
-
container: {type: string, required: true}
|
|
21
|
-
intf: {type: string, required: true}
|
|
22
|
-
ip: {type: string, required: false,
|
|
23
|
-
regex: '([0-9]+\.){3}[0-9]+\/[0-9]+'}
|
|
24
|
-
mac: {type: string, required: false,
|
|
25
|
-
regex: '([0-9A-Fa-f][0-9A-Fa-f]:){5}[0-9A-Fa-f][0-9A-Fa-f]'}
|
|
26
|
-
|
|
27
|
-
tunnels:
|
|
28
|
-
type: list
|
|
29
|
-
schema:
|
|
30
|
-
type: dict
|
|
31
|
-
schema:
|
|
32
|
-
type: {type: string, required: true}
|
|
33
|
-
intf: {type: string, required: true}
|
|
34
|
-
vni: {type: number, required: true}
|
|
35
|
-
remote: {type: string, required: true,
|
|
36
|
-
regex: '([0-9]+\.){3}[0-9]+'}
|
|
37
|
-
ip: {type: string, required: false,
|
|
38
|
-
regex: '([0-9]+\.){3}[0-9]+\/[0-9]+'}
|
|
39
|
-
mac: {type: string, required: false,
|
|
40
|
-
regex: '([0-9A-Fa-f][0-9A-Fa-f]:){5}[0-9A-Fa-f][0-9A-Fa-f]'}
|
|
41
|
-
link_args: {type: string, required: false}
|
|
42
|
-
|
|
43
|
-
interfaces:
|
|
44
|
-
type: list
|
|
45
|
-
schema:
|
|
46
|
-
type: dict
|
|
47
|
-
required: true
|
|
48
|
-
schema:
|
|
49
|
-
type: {type: string, required: true,
|
|
50
|
-
allowed: [link, vlan, macvlan, macvtap, ipvlan, ipvtap]}
|
|
51
|
-
container: {type: string, required: true}
|
|
52
|
-
host-intf: {type: string, required: true}
|
|
53
|
-
intf: {type: string, required: true}
|
|
54
|
-
mode: {type: string, required: false,
|
|
55
|
-
dependencies: {type: [macvlan, macvtap, ipvlan, ipvtap]}}
|
|
56
|
-
vlanid: {type: number, required: false,
|
|
57
|
-
dependencies: {type: [vlan]}}
|
|
58
|
-
ip: {type: string, required: false,
|
|
59
|
-
regex: '([0-9]+\.){3}[0-9]+\/[0-9]+'}
|
|
60
|
-
nat: {type: string, required: false,
|
|
61
|
-
regex: '([0-9]+\.){3}[0-9]+',
|
|
62
|
-
dependencies: ip}
|
|
63
|
-
|
|
64
|
-
network-settings: {type: string}
|
|
65
|
-
|
|
66
|
-
commands:
|
|
67
|
-
type: list
|
|
68
|
-
schema:
|
|
69
|
-
type: dict
|
|
70
|
-
schema:
|
|
71
|
-
container: {type: string, required: true}
|
|
72
|
-
command:
|
|
73
|
-
required: true
|
|
74
|
-
oneof: [ {type: string}, {type: list, schema: {type: string}} ]
|
|
75
|
-
|
|
76
|
-
mininet-cfg:
|
|
77
|
-
type: dict
|
|
78
|
-
schema:
|
|
79
|
-
|
|
80
|
-
switches:
|
|
81
|
-
type: list
|
|
82
|
-
required: false
|
|
83
|
-
schema:
|
|
84
|
-
type: dict
|
|
85
|
-
schema:
|
|
86
|
-
name: {type: string, required: true}
|
|
87
|
-
opts: {type: dict, required: false}
|
|
88
|
-
|
|
89
|
-
hosts:
|
|
90
|
-
type: list
|
|
91
|
-
required: false
|
|
92
|
-
schema:
|
|
93
|
-
type: dict
|
|
94
|
-
schema:
|
|
95
|
-
name: {type: string, required: true}
|
|
96
|
-
opts: {type: dict, required: false}
|
|
97
|
-
|
|
98
|
-
containers:
|
|
99
|
-
type: list
|
|
100
|
-
required: false
|
|
101
|
-
schema:
|
|
102
|
-
type: dict
|
|
103
|
-
schema:
|
|
104
|
-
name: {type: string, required: true}
|
|
105
|
-
opts: {type: dict, required: false}
|
|
106
|
-
|
|
107
|
-
links:
|
|
108
|
-
type: list
|
|
109
|
-
required: false
|
|
110
|
-
schema:
|
|
111
|
-
type: dict
|
|
112
|
-
schema:
|
|
113
|
-
left: {type: string, required: true}
|
|
114
|
-
right: {type: string, required: true}
|
|
115
|
-
opts: {type: dict, required: false}
|
|
116
|
-
|
|
117
|
-
interfaces:
|
|
118
|
-
type: list
|
|
119
|
-
required: false
|
|
120
|
-
schema:
|
|
121
|
-
type: dict
|
|
122
|
-
schema:
|
|
123
|
-
node: {type: string, required: true}
|
|
124
|
-
name: {type: string, required: true}
|
|
125
|
-
origName: {type: string, required: false}
|
|
126
|
-
opts: {type: dict, required: false}
|
|
127
|
-
|
|
128
|
-
commands:
|
|
129
|
-
type: list
|
|
130
|
-
required: false
|
|
131
|
-
schema:
|
|
132
|
-
type: dict
|
|
133
|
-
schema:
|
|
134
|
-
node: {type: string, required: true}
|
|
135
|
-
sync: {type: boolean, required: false}
|
|
136
|
-
command:
|
|
137
|
-
required: true
|
|
138
|
-
oneof: [ {type: string}, {type: list, schema: {type: string}} ]
|
package/old/schema.yaml.bak
DELETED
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
$defs:
|
|
2
|
-
one_link:
|
|
3
|
-
|
|
4
|
-
type: object
|
|
5
|
-
additionalProperties: false
|
|
6
|
-
required: ["links"]
|
|
7
|
-
properties:
|
|
8
|
-
links:
|
|
9
|
-
type: array
|
|
10
|
-
items:
|
|
11
|
-
type: object
|
|
12
|
-
# oneOf: [{required: ["container"]},
|
|
13
|
-
# {required: ["service"]},
|
|
14
|
-
# #{required: ["bridge"], properties: {type: {const: {oneOf: ["geneve", "vxlan"]}}}}]
|
|
15
|
-
# #{properties: {type: {const: "geneve"}}, required: ["bridge"]},
|
|
16
|
-
# #{properties: {type: {const: "vxlan"}}, required: ["bridge"]}
|
|
17
|
-
# {allOf: [{properties: {type: {const: "geneve"}}},
|
|
18
|
-
# {properties: {type: {const: "vxlan"}}}]}
|
|
19
|
-
# ]
|
|
20
|
-
|
|
21
|
-
# if: {properties: {type: {const: "veth"}}}
|
|
22
|
-
# then:
|
|
23
|
-
# allOf:
|
|
24
|
-
# - {required: ["bridge"]}
|
|
25
|
-
# - {not: {required: ["vlanid", "vni", "remote"]}}
|
|
26
|
-
# else:
|
|
27
|
-
# not: {required: ["bridge"]}
|
|
28
|
-
# if: {properties: {type: {const: "vlan"}}}
|
|
29
|
-
# then: {required: ["vlanid"]}
|
|
30
|
-
# else: {not: {required: ["vlanid"]}}
|
|
31
|
-
|
|
32
|
-
allOf:
|
|
33
|
-
- if: {properties: {type: {const: "veth"}}}
|
|
34
|
-
then: {required: ["bridge"]}
|
|
35
|
-
else: {not: {required: ["BOGUS"]}}
|
|
36
|
-
- if: {properties: {type: {const: "geneve"}}}
|
|
37
|
-
then: {required: ["bridge", "remote", "vni"]}
|
|
38
|
-
#else: {not: {required: ["bridge", "remote", "vni"]}}
|
|
39
|
-
else: {not: {required: ["BOGUS"]}}
|
|
40
|
-
- if: {properties: {type: {const: "vxlan"}}}
|
|
41
|
-
then: {required: ["bridge", "remote", "vni"]}
|
|
42
|
-
#else: {not: {required: ["bridge", "remote", "vni"]}}
|
|
43
|
-
else: {not: {required: ["BOGUS"]}}
|
|
44
|
-
|
|
45
|
-
additionalProperties: false
|
|
46
|
-
properties:
|
|
47
|
-
type:
|
|
48
|
-
type: string
|
|
49
|
-
default: "veth"
|
|
50
|
-
enum: [veth, dummy, vlan, ipvlan, ipvtap, macvlan, macvtap, geneve, vxlan]
|
|
51
|
-
service: {type: string}
|
|
52
|
-
container: {type: string}
|
|
53
|
-
bridge: {type: string}
|
|
54
|
-
dev: {type: string, default: "eth0"}
|
|
55
|
-
ip: {type: string, pattern: "^([0-9]{1,3}[.]){3}[0-9]+/[0-9]*$"}
|
|
56
|
-
mac: {type: string, pattern: "^([0-9A-Fa-f]{2}:){5}[0-9A-Fa-f]{2}$"}
|
|
57
|
-
mtu: {type: number}
|
|
58
|
-
route: {type: string}
|
|
59
|
-
|
|
60
|
-
vlanid: {type: number}
|
|
61
|
-
nat: {type: string, pattern: "^([0-9]{1,3}[.]){3}[0-9]+/[0-9]*$"}
|
|
62
|
-
|
|
63
|
-
vni: {type: number}
|
|
64
|
-
remote: {type: string, pattern: "^([0-9]{1,3}[.]){3}[0-9]+$"}
|
|
65
|
-
|
|
66
|
-
commands:
|
|
67
|
-
type: array
|
|
68
|
-
items:
|
|
69
|
-
type: object
|
|
70
|
-
required: ["command"]
|
|
71
|
-
oneOf: [{required: ["container"]},
|
|
72
|
-
{required: ["service"]}]
|
|
73
|
-
properties:
|
|
74
|
-
service: {type: string}
|
|
75
|
-
container: {type: string}
|
|
76
|
-
command: {type: string}
|
package/old/test2b-compose.yaml
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
# A docker-compose file with an external network configuration file
|
|
2
|
-
# and docker containers that are connected via a switch. The
|
|
3
|
-
# "internet" container is setup that is also connected to the switch
|
|
4
|
-
# and is listening on 8.8.8.8 (to test routing from the nodes).
|
|
5
|
-
|
|
6
|
-
version: "2.4"
|
|
7
|
-
|
|
8
|
-
services:
|
|
9
|
-
node:
|
|
10
|
-
image: alpine
|
|
11
|
-
network_mode: none
|
|
12
|
-
scale: 2
|
|
13
|
-
command: sleep 864000
|
|
14
|
-
|
|
15
|
-
internet:
|
|
16
|
-
image: alpine
|
|
17
|
-
network_mode: none
|
|
18
|
-
command: sleep 864000
|