commit | author | age
|
f973b9
|
1 |
import ipaddress |
JK |
2 |
import random |
|
3 |
|
|
4 |
import flask |
|
5 |
import pyroute2 |
|
6 |
from docker_plugin_api.NetworkDriverEntities import * |
|
7 |
from docker_plugin_api.Plugin import Blueprint, InputValidationException |
|
8 |
|
|
9 |
from .NetworkDriverData import * |
|
10 |
|
|
11 |
app = Blueprint('NetworkDriver', __name__) |
|
12 |
|
|
13 |
|
|
14 |
def genid(size=8, chars='0123456789abcdef'): |
|
15 |
return ''.join([random.choice(chars) for _ in range(size)]) |
|
16 |
|
|
17 |
|
8c0fc5
|
18 |
def create_interface(endpoint, network) -> str: |
f973b9
|
19 |
ifname0 = 'veth{}'.format(genid()) |
JK |
20 |
ifname1 = 'veth{}'.format(genid()) |
8c0fc5
|
21 |
|
f973b9
|
22 |
with pyroute2.IPRoute() as ip: |
JK |
23 |
ip.link('add', ifname=ifname0, peer=ifname1, kind='veth') |
|
24 |
idx = ip.link_lookup(ifname=ifname0)[0] |
|
25 |
if endpoint.Interface.MacAddress: |
|
26 |
ip.link('set', index=idx, address=endpoint.Interface.MacAddress) |
|
27 |
ip.link('set', index=idx, state='up') |
|
28 |
if endpoint.Interface.Address: |
|
29 |
addr = ipaddress.ip_interface(endpoint.Interface.Address) |
|
30 |
ip.addr('add', index=idx, address=addr.ip.compressed, mask=addr.network.prefixlen) |
|
31 |
if endpoint.Interface.AddressIPv6: |
|
32 |
addr = ipaddress.ip_interface(endpoint.Interface.AddressIPv6) |
|
33 |
ip.addr('add', index=idx, address=addr.ip.compressed, mask=addr.network.prefixlen) |
|
34 |
endpoint.Interface.Name = ifname0 |
|
35 |
|
|
36 |
idx = ip.link_lookup(ifname=ifname1)[0] |
|
37 |
ip.link('set', index=idx, state='up') |
|
38 |
if 'parent' in network.Options: |
|
39 |
id_parent = ip.link_lookup(ifname=network.Options['parent'])[0] |
|
40 |
print(ip.link("set", index=idx, master=id_parent)) |
|
41 |
endpoint.Interface.Peer = ifname1 |
|
42 |
|
8c0fc5
|
43 |
return ifname0 |
JK |
44 |
|
|
45 |
|
|
46 |
@app.route('/NetworkDriver.GetCapabilities', methods=['POST']) |
|
47 |
def GetCapabilities(): |
|
48 |
return { |
|
49 |
'Scope': 'local', |
|
50 |
'ConnectivityScope': 'global', |
|
51 |
} |
|
52 |
|
|
53 |
|
|
54 |
@app.route('/NetworkDriver.CreateNetwork', methods=['POST']) |
|
55 |
def CreateNetwork(): |
|
56 |
network = NetworkCreateEntity(**flask.request.get_json(force=True)) |
|
57 |
try: |
|
58 |
for option, value in network.Options['com.docker.network.generic'].items(): |
|
59 |
if option not in network.Options: |
|
60 |
network.Options[option] = value |
|
61 |
except KeyError: |
|
62 |
pass |
|
63 |
networks[network.NetworkID] = network |
|
64 |
networks_sync() |
|
65 |
return {} |
|
66 |
|
|
67 |
|
|
68 |
@app.route('/NetworkDriver.DeleteNetwork', methods=['POST']) |
|
69 |
def DeleteNetwork(): |
|
70 |
network = NetworkDeleteEntity(**flask.request.get_json(force=True)) |
|
71 |
if network.NetworkID in networks: |
|
72 |
del networks[network.NetworkID] |
|
73 |
networks_sync() |
|
74 |
return {} |
|
75 |
|
|
76 |
|
|
77 |
@app.route('/NetworkDriver.CreateEndpoint', methods=['POST']) |
|
78 |
def CreateEndpoint(): |
|
79 |
endpoint = EndpointCreateEntity(**flask.request.get_json(force=True)) |
|
80 |
endpoints['{}-{}'.format(endpoint.NetworkID, endpoint.EndpointID)] = endpoint |
|
81 |
return { |
|
82 |
'Interface': { |
|
83 |
} |
|
84 |
} |
|
85 |
|
|
86 |
|
|
87 |
@app.route('/NetworkDriver.EndpointOperInfo', methods=['POST']) |
|
88 |
def EndpointOperInfo(): |
|
89 |
endpoint = EndpointOperInfoEntity(**flask.request.get_json(force=True)) |
|
90 |
return { |
|
91 |
'Value': { |
|
92 |
} |
|
93 |
} |
|
94 |
|
|
95 |
|
|
96 |
@app.route('/NetworkDriver.DeleteEndpoint', methods=['POST']) |
|
97 |
def DeleteEndpoint(): |
|
98 |
entity = EndpointDeleteEntity(**flask.request.get_json(force=True)) |
|
99 |
endpoint_id = '{}-{}'.format(entity.NetworkID, entity.EndpointID) |
|
100 |
if endpoint_id in endpoints: |
|
101 |
del endpoints['{}-{}'.format(entity.NetworkID, entity.EndpointID)] |
|
102 |
return {} |
|
103 |
|
|
104 |
|
|
105 |
@app.route('/NetworkDriver.Join', methods=['POST']) |
|
106 |
def Join(): |
|
107 |
join = JoinEntity(**flask.request.get_json(force=True)) |
|
108 |
network = networks[join.NetworkID] |
|
109 |
endpoint = endpoints['{}-{}'.format(join.NetworkID, join.EndpointID)] |
|
110 |
|
|
111 |
interface = create_interface(endpoint, network) |
|
112 |
|
f973b9
|
113 |
gw4 = None |
JK |
114 |
for net4 in network.IPv4: |
|
115 |
try: |
|
116 |
gw4 = ipaddress.ip_interface(net4.Gateway) |
|
117 |
break |
|
118 |
except: |
|
119 |
pass |
|
120 |
gw6 = None |
|
121 |
for net6 in network.IPv6: |
|
122 |
try: |
|
123 |
gw6 = ipaddress.ip_interface(net6.Gateway) |
|
124 |
break |
|
125 |
except: |
|
126 |
pass |
|
127 |
|
|
128 |
result = { |
|
129 |
'InterfaceName': { |
8c0fc5
|
130 |
'SrcName': interface, |
f973b9
|
131 |
'DstPrefix': 'eth', |
JK |
132 |
}, |
|
133 |
} |
|
134 |
if gw4 is not None: |
|
135 |
result['Gateway'] = gw4.ip.compressed |
|
136 |
if gw6 is not None: |
|
137 |
result['GatewayIPv6'] = gw6.ip.compressed |
|
138 |
return result |
|
139 |
|
|
140 |
|
|
141 |
@app.route('/NetworkDriver.Leave', methods=['POST']) |
|
142 |
def Leave(): |
|
143 |
leave = LeaveEntity(**flask.request.get_json(force=True)) |
|
144 |
return {} |
|
145 |
|
|
146 |
|
|
147 |
@app.route('/NetworkDriver.DiscoverNew', methods=['POST']) |
|
148 |
def DiscoverNew(): |
|
149 |
entity = DiscoverNewEntity(**flask.request.get_json(force=True)) |
|
150 |
return {} |
|
151 |
|
|
152 |
|
|
153 |
@app.route('/NetworkDriver.DiscoverDelete', methods=['POST']) |
|
154 |
def DiscoverDelete(): |
|
155 |
entity = DiscoverDeleteEntity(**flask.request.get_json(force=True)) |
|
156 |
return {} |
|
157 |
|
|
158 |
|
|
159 |
@app.route('/NetworkDriver.ProgramExternalConnectivity', methods=['POST']) |
|
160 |
def ProgramExternalConnectivity(): |
|
161 |
entity = ProgramExternalConnectivityEntity(**flask.request.get_json(force=True)) |
|
162 |
return {} |
|
163 |
|
|
164 |
|
|
165 |
@app.route('/NetworkDriver.RevokeExternalConnectivity', methods=['POST']) |
|
166 |
def RevokeExternalConnectivity(): |
|
167 |
entity = RevokeExternalConnectivityEntity(**flask.request.get_json(force=True)) |
|
168 |
return {} |