gns3-server 3.0.0__py3-none-any.whl

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.

Potentially problematic release.


This version of gns3-server might be problematic. Click here for more details.

Files changed (1251) hide show
  1. gns3_server-3.0.0.dist-info/LICENSE +674 -0
  2. gns3_server-3.0.0.dist-info/METADATA +868 -0
  3. gns3_server-3.0.0.dist-info/RECORD +1251 -0
  4. gns3_server-3.0.0.dist-info/WHEEL +5 -0
  5. gns3_server-3.0.0.dist-info/entry_points.txt +3 -0
  6. gns3_server-3.0.0.dist-info/top_level.txt +1 -0
  7. gns3server/__init__.py +17 -0
  8. gns3server/__main__.py +20 -0
  9. gns3server/alembic.ini +103 -0
  10. gns3server/api/__init__.py +0 -0
  11. gns3server/api/routes/__init__.py +0 -0
  12. gns3server/api/routes/compute/__init__.py +267 -0
  13. gns3server/api/routes/compute/atm_switch_nodes.py +233 -0
  14. gns3server/api/routes/compute/capabilities.py +51 -0
  15. gns3server/api/routes/compute/cloud_nodes.py +249 -0
  16. gns3server/api/routes/compute/compute.py +143 -0
  17. gns3server/api/routes/compute/dependencies/__init__.py +0 -0
  18. gns3server/api/routes/compute/dependencies/authentication.py +83 -0
  19. gns3server/api/routes/compute/docker_nodes.py +393 -0
  20. gns3server/api/routes/compute/dynamips_nodes.py +367 -0
  21. gns3server/api/routes/compute/ethernet_hub_nodes.py +236 -0
  22. gns3server/api/routes/compute/ethernet_switch_nodes.py +246 -0
  23. gns3server/api/routes/compute/frame_relay_switch_nodes.py +240 -0
  24. gns3server/api/routes/compute/images.py +156 -0
  25. gns3server/api/routes/compute/iou_nodes.py +344 -0
  26. gns3server/api/routes/compute/nat_nodes.py +244 -0
  27. gns3server/api/routes/compute/notifications.py +88 -0
  28. gns3server/api/routes/compute/projects.py +243 -0
  29. gns3server/api/routes/compute/qemu_nodes.py +412 -0
  30. gns3server/api/routes/compute/virtualbox_nodes.py +377 -0
  31. gns3server/api/routes/compute/vmware_nodes.py +355 -0
  32. gns3server/api/routes/compute/vpcs_nodes.py +343 -0
  33. gns3server/api/routes/controller/__init__.py +147 -0
  34. gns3server/api/routes/controller/acl.py +268 -0
  35. gns3server/api/routes/controller/appliances.py +150 -0
  36. gns3server/api/routes/controller/computes.py +231 -0
  37. gns3server/api/routes/controller/controller.py +319 -0
  38. gns3server/api/routes/controller/dependencies/__init__.py +0 -0
  39. gns3server/api/routes/controller/dependencies/authentication.py +117 -0
  40. gns3server/api/routes/controller/dependencies/database.py +38 -0
  41. gns3server/api/routes/controller/dependencies/rbac.py +78 -0
  42. gns3server/api/routes/controller/drawings.py +131 -0
  43. gns3server/api/routes/controller/gns3vm.py +71 -0
  44. gns3server/api/routes/controller/groups.py +231 -0
  45. gns3server/api/routes/controller/images.py +255 -0
  46. gns3server/api/routes/controller/links.py +287 -0
  47. gns3server/api/routes/controller/nodes.py +619 -0
  48. gns3server/api/routes/controller/pools.py +239 -0
  49. gns3server/api/routes/controller/privileges.py +43 -0
  50. gns3server/api/routes/controller/projects.py +595 -0
  51. gns3server/api/routes/controller/roles.py +224 -0
  52. gns3server/api/routes/controller/snapshots.py +124 -0
  53. gns3server/api/routes/controller/symbols.py +133 -0
  54. gns3server/api/routes/controller/templates.py +192 -0
  55. gns3server/api/routes/controller/users.py +254 -0
  56. gns3server/api/routes/index.py +93 -0
  57. gns3server/api/server.py +224 -0
  58. gns3server/appliances/6wind-turbo-router.gns3a +47 -0
  59. gns3server/appliances/IPCop.gns3a +52 -0
  60. gns3server/appliances/a10-vthunder.gns3a +72 -0
  61. gns3server/appliances/aaa.gns3a +20 -0
  62. gns3server/appliances/alcatel-7750.gns3a +74 -0
  63. gns3server/appliances/almalinux.gns3a +84 -0
  64. gns3server/appliances/alpine-linux-virt.gns3a +59 -0
  65. gns3server/appliances/alpine-linux.gns3a +21 -0
  66. gns3server/appliances/arista-ceos.gns3a +20 -0
  67. gns3server/appliances/arista-veos.gns3a +577 -0
  68. gns3server/appliances/aruba-arubaoscx.gns3a +233 -0
  69. gns3server/appliances/aruba-vgw.gns3a +60 -0
  70. gns3server/appliances/aruba-vmc.gns3a +56 -0
  71. gns3server/appliances/asterfusion-vAsterNOS.gns3a +49 -0
  72. gns3server/appliances/asterisk.gns3a +114 -0
  73. gns3server/appliances/bigswitch-bigcloud-fabric.gns3a +42 -0
  74. gns3server/appliances/bird.gns3a +42 -0
  75. gns3server/appliances/bird2.gns3a +57 -0
  76. gns3server/appliances/brocade-vadx.gns3a +43 -0
  77. gns3server/appliances/brocade-vrouter.gns3a +138 -0
  78. gns3server/appliances/brocade-vtm.gns3a +136 -0
  79. gns3server/appliances/bsdrp.gns3a +117 -0
  80. gns3server/appliances/centos-cloud.gns3a +115 -0
  81. gns3server/appliances/centos7.gns3a +72 -0
  82. gns3server/appliances/checkpoint-gaia.gns3a +81 -0
  83. gns3server/appliances/chromium.gns3a +19 -0
  84. gns3server/appliances/cisco-1700.gns3a +39 -0
  85. gns3server/appliances/cisco-2600.gns3a +38 -0
  86. gns3server/appliances/cisco-2691.gns3a +38 -0
  87. gns3server/appliances/cisco-3620.gns3a +38 -0
  88. gns3server/appliances/cisco-3640.gns3a +38 -0
  89. gns3server/appliances/cisco-3660.gns3a +38 -0
  90. gns3server/appliances/cisco-3725.gns3a +38 -0
  91. gns3server/appliances/cisco-3745.gns3a +45 -0
  92. gns3server/appliances/cisco-7200.gns3a +92 -0
  93. gns3server/appliances/cisco-asa.gns3a +86 -0
  94. gns3server/appliances/cisco-asav.gns3a +227 -0
  95. gns3server/appliances/cisco-c8000v.gns3a +108 -0
  96. gns3server/appliances/cisco-cat9k.gns3a +58 -0
  97. gns3server/appliances/cisco-csr1000v.gns3a +316 -0
  98. gns3server/appliances/cisco-dcnm.gns3a +96 -0
  99. gns3server/appliances/cisco-fcnf.gns3a +71 -0
  100. gns3server/appliances/cisco-fmcv.gns3a +139 -0
  101. gns3server/appliances/cisco-fsve.gns3a +57 -0
  102. gns3server/appliances/cisco-ftdv.gns3a +99 -0
  103. gns3server/appliances/cisco-iosv.gns3a +178 -0
  104. gns3server/appliances/cisco-iosvl2.gns3a +95 -0
  105. gns3server/appliances/cisco-iosxrv.gns3a +57 -0
  106. gns3server/appliances/cisco-iosxrv9k.gns3a +188 -0
  107. gns3server/appliances/cisco-iou-l2.gns3a +84 -0
  108. gns3server/appliances/cisco-iou-l3.gns3a +84 -0
  109. gns3server/appliances/cisco-ise.gns3a +154 -0
  110. gns3server/appliances/cisco-ngipsv.gns3a +73 -0
  111. gns3server/appliances/cisco-nxosv.gns3a +56 -0
  112. gns3server/appliances/cisco-nxosv9k.gns3a +433 -0
  113. gns3server/appliances/cisco-pyats.gns3a +19 -0
  114. gns3server/appliances/cisco-smc.gns3a +71 -0
  115. gns3server/appliances/cisco-vWLC.gns3a +140 -0
  116. gns3server/appliances/cisco-wsav.gns3a +44 -0
  117. gns3server/appliances/citrix-netscaler-vpx.gns3a +72 -0
  118. gns3server/appliances/citrix-sd-wan.gns3a +46 -0
  119. gns3server/appliances/citrix-sdwan-center.gns3a +46 -0
  120. gns3server/appliances/clavister-netsheild.gns3a +59 -0
  121. gns3server/appliances/clavister-netwall.gns3a +71 -0
  122. gns3server/appliances/clearos.gns3a +107 -0
  123. gns3server/appliances/cloudrouter.gns3a +72 -0
  124. gns3server/appliances/coreos.gns3a +329 -0
  125. gns3server/appliances/cumulus-vx.gns3a +440 -0
  126. gns3server/appliances/danos.gns3a +57 -0
  127. gns3server/appliances/debian.gns3a +85 -0
  128. gns3server/appliances/deft-linux.gns3a +96 -0
  129. gns3server/appliances/dell-ftos.gns3a +71 -0
  130. gns3server/appliances/dns.gns3a +20 -0
  131. gns3server/appliances/empty-vm.gns3a +199 -0
  132. gns3server/appliances/endhost.gns3a +17 -0
  133. gns3server/appliances/exos.gns3a +51 -0
  134. gns3server/appliances/extreme-networks-voss.gns3a +152 -0
  135. gns3server/appliances/f5-bigip.gns3a +322 -0
  136. gns3server/appliances/f5-bigiq.gns3a +165 -0
  137. gns3server/appliances/fedora-cloud.gns3a +70 -0
  138. gns3server/appliances/firefox.gns3a +59 -0
  139. gns3server/appliances/fortiadc-manager.gns3a +54 -0
  140. gns3server/appliances/fortiadc.gns3a +502 -0
  141. gns3server/appliances/fortianalyzer.gns3a +519 -0
  142. gns3server/appliances/fortiauthenticator.gns3a +251 -0
  143. gns3server/appliances/forticache.gns3a +210 -0
  144. gns3server/appliances/fortigate.gns3a +742 -0
  145. gns3server/appliances/fortimail.gns3a +392 -0
  146. gns3server/appliances/fortimanager.gns3a +519 -0
  147. gns3server/appliances/fortiproxy.gns3a +83 -0
  148. gns3server/appliances/fortirecorder.gns3a +69 -0
  149. gns3server/appliances/fortisandbox.gns3a +210 -0
  150. gns3server/appliances/fortisiem-super_worker.gns3a +210 -0
  151. gns3server/appliances/fortiweb.gns3a +308 -0
  152. gns3server/appliances/freeRouter.gns3a +44 -0
  153. gns3server/appliances/freebsd.gns3a +75 -0
  154. gns3server/appliances/freenas.gns3a +183 -0
  155. gns3server/appliances/frr.gns3a +84 -0
  156. gns3server/appliances/haproxy.gns3a +18 -0
  157. gns3server/appliances/hbcd-pe.gns3a +62 -0
  158. gns3server/appliances/hp-vsr1001.gns3a +149 -0
  159. gns3server/appliances/huawei-ar1kv.gns3a +58 -0
  160. gns3server/appliances/huawei-ce12800.gns3a +43 -0
  161. gns3server/appliances/huawei-ne40e.gns3a +94 -0
  162. gns3server/appliances/huawei-usg6kv.gns3a +50 -0
  163. gns3server/appliances/innovaphone-app.gns3a +50 -0
  164. gns3server/appliances/innovaphone-ipva.gns3a +78 -0
  165. gns3server/appliances/ipfire.gns3a +181 -0
  166. gns3server/appliances/ipterm.gns3a +19 -0
  167. gns3server/appliances/ipxe.gns3a +47 -0
  168. gns3server/appliances/juniper-junos-space.gns3a +46 -0
  169. gns3server/appliances/juniper-vmx-legacy.gns3a +55 -0
  170. gns3server/appliances/juniper-vmx-vcp.gns3a +520 -0
  171. gns3server/appliances/juniper-vmx-vfp.gns3a +281 -0
  172. gns3server/appliances/juniper-vqfx-pfe.gns3a +71 -0
  173. gns3server/appliances/juniper-vqfx-re.gns3a +85 -0
  174. gns3server/appliances/juniper-vrr.gns3a +66 -0
  175. gns3server/appliances/juniper-vsrx.gns3a +332 -0
  176. gns3server/appliances/jupyter.gns3a +20 -0
  177. gns3server/appliances/jupyter27.gns3a +20 -0
  178. gns3server/appliances/kali-linux-cli.gns3a +18 -0
  179. gns3server/appliances/kali-linux.gns3a +248 -0
  180. gns3server/appliances/kemp-vlm.gns3a +111 -0
  181. gns3server/appliances/kerio-connect.gns3a +131 -0
  182. gns3server/appliances/kerio-control.gns3a +143 -0
  183. gns3server/appliances/kerio-operator.gns3a +130 -0
  184. gns3server/appliances/lancom-vrouter.gns3a +45 -0
  185. gns3server/appliances/loadbalancer_org-va.gns3a +56 -0
  186. gns3server/appliances/macos-install.gns3a +72 -0
  187. gns3server/appliances/mcjoin.gns3a +19 -0
  188. gns3server/appliances/microcore-linux.gns3a +72 -0
  189. gns3server/appliances/mikrotik-ccr1036-8g-2s+.gns3a +165 -0
  190. gns3server/appliances/mikrotik-ccr1072-1g-8s+.gns3a +161 -0
  191. gns3server/appliances/mikrotik-chr.gns3a +108 -0
  192. gns3server/appliances/mikrotik-crs328-24p-4s+.gns3a +173 -0
  193. gns3server/appliances/mikrotik-crs328-4c-20s-4s+.gns3a +189 -0
  194. gns3server/appliances/mikrotik-rb1100ahx4-dude-edition.gns3a +155 -0
  195. gns3server/appliances/mikrotik-rb2011uias.gns3a +161 -0
  196. gns3server/appliances/mikrotik-rb3011uias.gns3a +161 -0
  197. gns3server/appliances/mikrotik-rb4011igs+.gns3a +161 -0
  198. gns3server/appliances/mikrotik-rb450g.gns3a +155 -0
  199. gns3server/appliances/mikrotik-rb450gx4.gns3a +155 -0
  200. gns3server/appliances/mikrotik-winbox.gns3a +19 -0
  201. gns3server/appliances/mininet.gns3a +47 -0
  202. gns3server/appliances/net_toolbox.gns3a +20 -0
  203. gns3server/appliances/netapp-ontapsim.gns3a +185 -0
  204. gns3server/appliances/netem.gns3a +44 -0
  205. gns3server/appliances/network_automation.gns3a +19 -0
  206. gns3server/appliances/nixos.gns3a +52 -0
  207. gns3server/appliances/nokia-vsim.gns3a +47 -0
  208. gns3server/appliances/ntopng.gns3a +24 -0
  209. gns3server/appliances/onos.gns3a +19 -0
  210. gns3server/appliances/op5-monitor.gns3a +72 -0
  211. gns3server/appliances/open-media-vault.gns3a +120 -0
  212. gns3server/appliances/openbsd.gns3a +44 -0
  213. gns3server/appliances/opennac.gns3a +45 -0
  214. gns3server/appliances/opensuse.gns3a +47 -0
  215. gns3server/appliances/openvswitch-management.gns3a +21 -0
  216. gns3server/appliances/openvswitch.gns3a +21 -0
  217. gns3server/appliances/openwrt-realview.gns3a +56 -0
  218. gns3server/appliances/openwrt.gns3a +359 -0
  219. gns3server/appliances/opnsense.gns3a +122 -0
  220. gns3server/appliances/oracle-linux-cloud.gns3a +115 -0
  221. gns3server/appliances/ostinato-wireshark.gns3a +20 -0
  222. gns3server/appliances/ostinato.gns3a +75 -0
  223. gns3server/appliances/ovs-snmp.gns3a +18 -0
  224. gns3server/appliances/packetfence-zen.gns3a +151 -0
  225. gns3server/appliances/pan-vm-fw.gns3a +241 -0
  226. gns3server/appliances/parrot-os.gns3a +68 -0
  227. gns3server/appliances/pfsense.gns3a +122 -0
  228. gns3server/appliances/proxmox-mg.gns3a +69 -0
  229. gns3server/appliances/puppy-linux.gns3a +82 -0
  230. gns3server/appliances/python-go-perl-php.gns3a +17 -0
  231. gns3server/appliances/raspian.gns3a +79 -0
  232. gns3server/appliances/reactos.gns3a +67 -0
  233. gns3server/appliances/rhel.gns3a +207 -0
  234. gns3server/appliances/riverbed-steelhead-ng-vcx.gns3a +68 -0
  235. gns3server/appliances/rockylinux.gns3a +100 -0
  236. gns3server/appliances/security-onion.gns3a +108 -0
  237. gns3server/appliances/smoothwall.gns3a +54 -0
  238. gns3server/appliances/sophos-iview.gns3a +66 -0
  239. gns3server/appliances/sophos-utm.gns3a +263 -0
  240. gns3server/appliances/sophos-xg.gns3a +198 -0
  241. gns3server/appliances/stonework.gns3a +21 -0
  242. gns3server/appliances/tacacs-gui.gns3a +57 -0
  243. gns3server/appliances/tinycore-linux.gns3a +73 -0
  244. gns3server/appliances/trendmicro-imsva.gns3a +54 -0
  245. gns3server/appliances/trendmicro-iwsva.gns3a +53 -0
  246. gns3server/appliances/truenas.gns3a +104 -0
  247. gns3server/appliances/turnkey-wordpress.gns3a +20 -0
  248. gns3server/appliances/ubuntu-cloud.gns3a +116 -0
  249. gns3server/appliances/ubuntu-docker.gns3a +20 -0
  250. gns3server/appliances/ubuntu-gui.gns3a +98 -0
  251. gns3server/appliances/untangle.gns3a +208 -0
  252. gns3server/appliances/viptela-edge-genericx86-64.gns3a +84 -0
  253. gns3server/appliances/viptela-smart-genericx86-64.gns3a +82 -0
  254. gns3server/appliances/viptela-vmanage-genericx86-64.gns3a +95 -0
  255. gns3server/appliances/vpp.gns3a +45 -0
  256. gns3server/appliances/vrin.gns3a +118 -0
  257. gns3server/appliances/vyos.gns3a +179 -0
  258. gns3server/appliances/watchguard-fireboxv.gns3a +45 -0
  259. gns3server/appliances/watchguard-xtmv.gns3a +45 -0
  260. gns3server/appliances/webterm.gns3a +20 -0
  261. gns3server/appliances/windows-11-dev-env.gns3a +74 -0
  262. gns3server/appliances/windows-xp+ie.gns3a +52 -0
  263. gns3server/appliances/windows.gns3a +125 -0
  264. gns3server/appliances/windows_server.gns3a +83 -0
  265. gns3server/appliances/zentyal-server.gns3a +159 -0
  266. gns3server/appliances/zeroshell.gns3a +103 -0
  267. gns3server/compute/__init__.py +38 -0
  268. gns3server/compute/adapters/__init__.py +0 -0
  269. gns3server/compute/adapters/adapter.py +104 -0
  270. gns3server/compute/adapters/ethernet_adapter.py +33 -0
  271. gns3server/compute/adapters/serial_adapter.py +32 -0
  272. gns3server/compute/base_manager.py +547 -0
  273. gns3server/compute/base_node.py +979 -0
  274. gns3server/compute/builtin/__init__.py +46 -0
  275. gns3server/compute/builtin/builtin_node_factory.py +42 -0
  276. gns3server/compute/builtin/nodes/__init__.py +0 -0
  277. gns3server/compute/builtin/nodes/cloud.py +548 -0
  278. gns3server/compute/builtin/nodes/ethernet_hub.py +104 -0
  279. gns3server/compute/builtin/nodes/ethernet_switch.py +104 -0
  280. gns3server/compute/builtin/nodes/nat.py +97 -0
  281. gns3server/compute/compute_error.py +48 -0
  282. gns3server/compute/docker/__init__.py +320 -0
  283. gns3server/compute/docker/docker_error.py +33 -0
  284. gns3server/compute/docker/docker_vm.py +1378 -0
  285. gns3server/compute/docker/resources/bin/udhcpc +15 -0
  286. gns3server/compute/docker/resources/etc/udhcpc/default.script +138 -0
  287. gns3server/compute/docker/resources/init.sh +102 -0
  288. gns3server/compute/docker/resources/run-cmd.sh +6 -0
  289. gns3server/compute/dynamips/__init__.py +661 -0
  290. gns3server/compute/dynamips/adapters/__init__.py +0 -0
  291. gns3server/compute/dynamips/adapters/adapter.py +165 -0
  292. gns3server/compute/dynamips/adapters/c1700_mb_1fe.py +36 -0
  293. gns3server/compute/dynamips/adapters/c1700_mb_wic1.py +37 -0
  294. gns3server/compute/dynamips/adapters/c2600_mb_1e.py +36 -0
  295. gns3server/compute/dynamips/adapters/c2600_mb_1fe.py +37 -0
  296. gns3server/compute/dynamips/adapters/c2600_mb_2e.py +36 -0
  297. gns3server/compute/dynamips/adapters/c2600_mb_2fe.py +36 -0
  298. gns3server/compute/dynamips/adapters/c7200_io_2fe.py +36 -0
  299. gns3server/compute/dynamips/adapters/c7200_io_fe.py +36 -0
  300. gns3server/compute/dynamips/adapters/c7200_io_ge_e.py +36 -0
  301. gns3server/compute/dynamips/adapters/gt96100_fe.py +31 -0
  302. gns3server/compute/dynamips/adapters/leopard_2fe.py +37 -0
  303. gns3server/compute/dynamips/adapters/nm_16esw.py +32 -0
  304. gns3server/compute/dynamips/adapters/nm_1e.py +32 -0
  305. gns3server/compute/dynamips/adapters/nm_1fe_tx.py +32 -0
  306. gns3server/compute/dynamips/adapters/nm_4e.py +32 -0
  307. gns3server/compute/dynamips/adapters/nm_4t.py +32 -0
  308. gns3server/compute/dynamips/adapters/pa_2fe_tx.py +32 -0
  309. gns3server/compute/dynamips/adapters/pa_4e.py +32 -0
  310. gns3server/compute/dynamips/adapters/pa_4t.py +32 -0
  311. gns3server/compute/dynamips/adapters/pa_8e.py +32 -0
  312. gns3server/compute/dynamips/adapters/pa_8t.py +32 -0
  313. gns3server/compute/dynamips/adapters/pa_a1.py +32 -0
  314. gns3server/compute/dynamips/adapters/pa_fe_tx.py +32 -0
  315. gns3server/compute/dynamips/adapters/pa_ge.py +32 -0
  316. gns3server/compute/dynamips/adapters/pa_pos_oc3.py +32 -0
  317. gns3server/compute/dynamips/adapters/wic_1enet.py +40 -0
  318. gns3server/compute/dynamips/adapters/wic_1t.py +40 -0
  319. gns3server/compute/dynamips/adapters/wic_2t.py +40 -0
  320. gns3server/compute/dynamips/dynamips_error.py +26 -0
  321. gns3server/compute/dynamips/dynamips_factory.py +71 -0
  322. gns3server/compute/dynamips/dynamips_hypervisor.py +333 -0
  323. gns3server/compute/dynamips/hypervisor.py +210 -0
  324. gns3server/compute/dynamips/nios/__init__.py +0 -0
  325. gns3server/compute/dynamips/nios/nio.py +352 -0
  326. gns3server/compute/dynamips/nios/nio_generic_ethernet.py +73 -0
  327. gns3server/compute/dynamips/nios/nio_linux_ethernet.py +72 -0
  328. gns3server/compute/dynamips/nios/nio_null.py +51 -0
  329. gns3server/compute/dynamips/nios/nio_tap.py +66 -0
  330. gns3server/compute/dynamips/nios/nio_udp.py +136 -0
  331. gns3server/compute/dynamips/nios/nio_unix.py +88 -0
  332. gns3server/compute/dynamips/nios/nio_vde.py +88 -0
  333. gns3server/compute/dynamips/nodes/__init__.py +0 -0
  334. gns3server/compute/dynamips/nodes/atm_switch.py +514 -0
  335. gns3server/compute/dynamips/nodes/bridge.py +107 -0
  336. gns3server/compute/dynamips/nodes/c1700.py +160 -0
  337. gns3server/compute/dynamips/nodes/c2600.py +171 -0
  338. gns3server/compute/dynamips/nodes/c2691.py +112 -0
  339. gns3server/compute/dynamips/nodes/c3600.py +155 -0
  340. gns3server/compute/dynamips/nodes/c3725.py +112 -0
  341. gns3server/compute/dynamips/nodes/c3745.py +112 -0
  342. gns3server/compute/dynamips/nodes/c7200.py +268 -0
  343. gns3server/compute/dynamips/nodes/device.py +134 -0
  344. gns3server/compute/dynamips/nodes/ethernet_hub.py +241 -0
  345. gns3server/compute/dynamips/nodes/ethernet_switch.py +496 -0
  346. gns3server/compute/dynamips/nodes/frame_relay_switch.py +379 -0
  347. gns3server/compute/dynamips/nodes/router.py +1797 -0
  348. gns3server/compute/error.py +40 -0
  349. gns3server/compute/iou/__init__.py +64 -0
  350. gns3server/compute/iou/iou_error.py +25 -0
  351. gns3server/compute/iou/iou_vm.py +1482 -0
  352. gns3server/compute/iou/utils/__init__.py +0 -0
  353. gns3server/compute/iou/utils/iou_export.py +233 -0
  354. gns3server/compute/iou/utils/iou_import.py +232 -0
  355. gns3server/compute/nios/__init__.py +0 -0
  356. gns3server/compute/nios/nio.py +120 -0
  357. gns3server/compute/nios/nio_ethernet.py +56 -0
  358. gns3server/compute/nios/nio_tap.py +56 -0
  359. gns3server/compute/nios/nio_udp.py +82 -0
  360. gns3server/compute/notification_manager.py +73 -0
  361. gns3server/compute/port_manager.py +402 -0
  362. gns3server/compute/project.py +434 -0
  363. gns3server/compute/project_manager.py +122 -0
  364. gns3server/compute/qemu/__init__.py +304 -0
  365. gns3server/compute/qemu/qemu_error.py +26 -0
  366. gns3server/compute/qemu/qemu_vm.py +2697 -0
  367. gns3server/compute/qemu/resources/config.img.zip +0 -0
  368. gns3server/compute/qemu/utils/__init__.py +0 -0
  369. gns3server/compute/qemu/utils/guest_cid.py +38 -0
  370. gns3server/compute/qemu/utils/qcow2.py +138 -0
  371. gns3server/compute/qemu/utils/ziputils.py +55 -0
  372. gns3server/compute/ubridge/__init__.py +0 -0
  373. gns3server/compute/ubridge/hypervisor.py +256 -0
  374. gns3server/compute/ubridge/ubridge_error.py +32 -0
  375. gns3server/compute/ubridge/ubridge_hypervisor.py +285 -0
  376. gns3server/compute/virtualbox/__init__.py +212 -0
  377. gns3server/compute/virtualbox/virtualbox_error.py +26 -0
  378. gns3server/compute/virtualbox/virtualbox_vm.py +1255 -0
  379. gns3server/compute/vmware/__init__.py +725 -0
  380. gns3server/compute/vmware/vmware_error.py +26 -0
  381. gns3server/compute/vmware/vmware_vm.py +1007 -0
  382. gns3server/compute/vpcs/__init__.py +91 -0
  383. gns3server/compute/vpcs/vpcs_error.py +26 -0
  384. gns3server/compute/vpcs/vpcs_vm.py +595 -0
  385. gns3server/config.py +284 -0
  386. gns3server/config_samples/gns3_server.conf +160 -0
  387. gns3server/configs/ios_base_startup-config.txt +26 -0
  388. gns3server/configs/ios_etherswitch_startup-config.txt +181 -0
  389. gns3server/configs/iou_l2_base_startup-config.txt +133 -0
  390. gns3server/configs/iou_l3_base_startup-config.txt +109 -0
  391. gns3server/configs/vpcs_base_config.txt +9 -0
  392. gns3server/controller/__init__.py +691 -0
  393. gns3server/controller/appliance.py +86 -0
  394. gns3server/controller/appliance_manager.py +486 -0
  395. gns3server/controller/appliance_to_template.py +132 -0
  396. gns3server/controller/compute.py +677 -0
  397. gns3server/controller/controller_error.py +77 -0
  398. gns3server/controller/drawing.py +229 -0
  399. gns3server/controller/export_project.py +336 -0
  400. gns3server/controller/gns3vm/__init__.py +412 -0
  401. gns3server/controller/gns3vm/base_gns3_vm.py +303 -0
  402. gns3server/controller/gns3vm/gns3_vm_error.py +28 -0
  403. gns3server/controller/gns3vm/hyperv_gns3_vm.py +346 -0
  404. gns3server/controller/gns3vm/remote_gns3_vm.py +73 -0
  405. gns3server/controller/gns3vm/virtualbox_gns3_vm.py +480 -0
  406. gns3server/controller/gns3vm/vmware_gns3_vm.py +216 -0
  407. gns3server/controller/import_project.py +332 -0
  408. gns3server/controller/link.py +461 -0
  409. gns3server/controller/node.py +840 -0
  410. gns3server/controller/notification.py +149 -0
  411. gns3server/controller/ports/__init__.py +0 -0
  412. gns3server/controller/ports/atm_port.py +51 -0
  413. gns3server/controller/ports/ethernet_port.py +49 -0
  414. gns3server/controller/ports/fastethernet_port.py +43 -0
  415. gns3server/controller/ports/frame_relay_port.py +43 -0
  416. gns3server/controller/ports/gigabitethernet_port.py +43 -0
  417. gns3server/controller/ports/port.py +109 -0
  418. gns3server/controller/ports/port_factory.py +213 -0
  419. gns3server/controller/ports/pos_port.py +52 -0
  420. gns3server/controller/ports/serial_port.py +63 -0
  421. gns3server/controller/project.py +1399 -0
  422. gns3server/controller/snapshot.py +140 -0
  423. gns3server/controller/symbol_themes.py +153 -0
  424. gns3server/controller/symbols.py +168 -0
  425. gns3server/controller/topology.py +788 -0
  426. gns3server/controller/udp_link.py +245 -0
  427. gns3server/core/__init__.py +0 -0
  428. gns3server/core/tasks.py +99 -0
  429. gns3server/crash_report.py +167 -0
  430. gns3server/db/__init__.py +0 -0
  431. gns3server/db/models/__init__.py +38 -0
  432. gns3server/db/models/acl.py +46 -0
  433. gns3server/db/models/base.py +117 -0
  434. gns3server/db/models/computes.py +33 -0
  435. gns3server/db/models/images.py +43 -0
  436. gns3server/db/models/pools.py +52 -0
  437. gns3server/db/models/privileges.py +359 -0
  438. gns3server/db/models/roles.py +57 -0
  439. gns3server/db/models/templates.py +272 -0
  440. gns3server/db/models/users.py +94 -0
  441. gns3server/db/repositories/__init__.py +0 -0
  442. gns3server/db/repositories/base.py +24 -0
  443. gns3server/db/repositories/computes.py +93 -0
  444. gns3server/db/repositories/images.py +141 -0
  445. gns3server/db/repositories/pools.py +218 -0
  446. gns3server/db/repositories/rbac.py +430 -0
  447. gns3server/db/repositories/templates.py +172 -0
  448. gns3server/db/repositories/users.py +289 -0
  449. gns3server/db/tasks.py +230 -0
  450. gns3server/db_migrations/README +5 -0
  451. gns3server/db_migrations/env.py +101 -0
  452. gns3server/db_migrations/script.py.mako +24 -0
  453. gns3server/db_migrations/versions/7ceeddd9c9a8_init.py +28 -0
  454. gns3server/db_migrations/versions/9a5292aa4389_add_mac_address_field_in_docker_.py +27 -0
  455. gns3server/disks/OVMF.fd +0 -0
  456. gns3server/disks/OVMF_CODE.fd +0 -0
  457. gns3server/disks/OVMF_VARS.fd +0 -0
  458. gns3server/disks/empty100G.qcow2 +0 -0
  459. gns3server/disks/empty10G.qcow2 +0 -0
  460. gns3server/disks/empty150G.qcow2 +0 -0
  461. gns3server/disks/empty1T.qcow2 +0 -0
  462. gns3server/disks/empty200G.qcow2 +0 -0
  463. gns3server/disks/empty20G.qcow2 +0 -0
  464. gns3server/disks/empty250G.qcow2 +0 -0
  465. gns3server/disks/empty30G.qcow2 +0 -0
  466. gns3server/disks/empty40G.qcow2 +0 -0
  467. gns3server/disks/empty500G.qcow2 +0 -0
  468. gns3server/disks/empty50G.qcow2 +0 -0
  469. gns3server/disks/empty8G.qcow2 +0 -0
  470. gns3server/gns3_server.egg-info/PKG-INFO +307 -0
  471. gns3server/gns3_server.egg-info/SOURCES.txt +0 -0
  472. gns3server/gns3_server.egg-info/dependency_links.txt +1 -0
  473. gns3server/gns3_server.egg-info/entry_points.txt +4 -0
  474. gns3server/gns3_server.egg-info/not-zip-safe +1 -0
  475. gns3server/gns3_server.egg-info/requires.txt +31 -0
  476. gns3server/gns3_server.egg-info/top_level.txt +2 -0
  477. gns3server/logger.py +164 -0
  478. gns3server/main.py +81 -0
  479. gns3server/schemas/__init__.py +85 -0
  480. gns3server/schemas/common.py +71 -0
  481. gns3server/schemas/compute/__init__.py +0 -0
  482. gns3server/schemas/compute/atm_switch_nodes.py +55 -0
  483. gns3server/schemas/compute/cloud_nodes.py +137 -0
  484. gns3server/schemas/compute/docker_nodes.py +75 -0
  485. gns3server/schemas/compute/dynamips_nodes.py +197 -0
  486. gns3server/schemas/compute/ethernet_hub_nodes.py +63 -0
  487. gns3server/schemas/compute/ethernet_switch_nodes.py +100 -0
  488. gns3server/schemas/compute/frame_relay_switch_nodes.py +55 -0
  489. gns3server/schemas/compute/iou_nodes.py +76 -0
  490. gns3server/schemas/compute/nat_nodes.py +122 -0
  491. gns3server/schemas/compute/nios.py +66 -0
  492. gns3server/schemas/compute/qemu_nodes.py +245 -0
  493. gns3server/schemas/compute/virtualbox_nodes.py +97 -0
  494. gns3server/schemas/compute/vmware_nodes.py +102 -0
  495. gns3server/schemas/compute/vpcs_nodes.py +68 -0
  496. gns3server/schemas/config.py +197 -0
  497. gns3server/schemas/controller/__init__.py +0 -0
  498. gns3server/schemas/controller/appliances.py +466 -0
  499. gns3server/schemas/controller/base.py +25 -0
  500. gns3server/schemas/controller/capabilities.py +34 -0
  501. gns3server/schemas/controller/computes.py +168 -0
  502. gns3server/schemas/controller/drawings.py +34 -0
  503. gns3server/schemas/controller/gns3vm.py +56 -0
  504. gns3server/schemas/controller/images.py +44 -0
  505. gns3server/schemas/controller/iou_license.py +23 -0
  506. gns3server/schemas/controller/labels.py +30 -0
  507. gns3server/schemas/controller/links.py +94 -0
  508. gns3server/schemas/controller/nodes.py +177 -0
  509. gns3server/schemas/controller/pools.py +81 -0
  510. gns3server/schemas/controller/projects.py +116 -0
  511. gns3server/schemas/controller/rbac.py +113 -0
  512. gns3server/schemas/controller/snapshots.py +42 -0
  513. gns3server/schemas/controller/templates/__init__.py +83 -0
  514. gns3server/schemas/controller/templates/cloud_templates.py +44 -0
  515. gns3server/schemas/controller/templates/docker_templates.py +59 -0
  516. gns3server/schemas/controller/templates/dynamips_templates.py +199 -0
  517. gns3server/schemas/controller/templates/ethernet_hub_templates.py +46 -0
  518. gns3server/schemas/controller/templates/ethernet_switch_templates.py +57 -0
  519. gns3server/schemas/controller/templates/iou_templates.py +47 -0
  520. gns3server/schemas/controller/templates/qemu_templates.py +94 -0
  521. gns3server/schemas/controller/templates/virtualbox_templates.py +64 -0
  522. gns3server/schemas/controller/templates/vmware_templates.py +61 -0
  523. gns3server/schemas/controller/templates/vpcs_templates.py +39 -0
  524. gns3server/schemas/controller/tokens.py +29 -0
  525. gns3server/schemas/controller/topology.py +82 -0
  526. gns3server/schemas/controller/users.py +105 -0
  527. gns3server/schemas/link.py +0 -0
  528. gns3server/schemas/qemu_disk_image.py +103 -0
  529. gns3server/schemas/version.py +25 -0
  530. gns3server/server.py +348 -0
  531. gns3server/services/__init__.py +19 -0
  532. gns3server/services/authentication.py +83 -0
  533. gns3server/services/computes.py +82 -0
  534. gns3server/services/templates.py +329 -0
  535. gns3server/static/.gitkeep +0 -0
  536. gns3server/static/favicon.ico +0 -0
  537. gns3server/static/redoc.standalone.js +1782 -0
  538. gns3server/static/swagger-ui-bundle.js +2 -0
  539. gns3server/static/swagger-ui.css +3 -0
  540. gns3server/static/web-ui/3rdpartylicenses.txt +2604 -0
  541. gns3server/static/web-ui/465.92c7ab880f2504d3.js +1 -0
  542. gns3server/static/web-ui/MaterialIcons-Regular.196fa4a92dd6fa73.ttf +0 -0
  543. gns3server/static/web-ui/MaterialIcons-Regular.1e50f5c2ffa6aba4.eot +0 -0
  544. gns3server/static/web-ui/MaterialIcons-Regular.7ea2023eeca07427.woff2 +0 -0
  545. gns3server/static/web-ui/MaterialIcons-Regular.db852539204b1a34.woff +0 -0
  546. gns3server/static/web-ui/NotoSans-Bold.635e9291df1a5a00.woff2 +0 -0
  547. gns3server/static/web-ui/NotoSans-Bold.885427cced6d8c94.woff +0 -0
  548. gns3server/static/web-ui/NotoSans-Bold.93203a43bc93ad9c.svg +8453 -0
  549. gns3server/static/web-ui/NotoSans-Bold.a7ab189a45f553b4.eot +0 -0
  550. gns3server/static/web-ui/NotoSans-Bold.e989c11744b36f58.ttf +0 -0
  551. gns3server/static/web-ui/NotoSans-BoldItalic.2baf33b639fc86a4.woff +0 -0
  552. gns3server/static/web-ui/NotoSans-BoldItalic.2eea9ba02e25c1d3.ttf +0 -0
  553. gns3server/static/web-ui/NotoSans-BoldItalic.46a5eec91da0d900.svg +8453 -0
  554. gns3server/static/web-ui/NotoSans-BoldItalic.7fdef73b477daa73.eot +0 -0
  555. gns3server/static/web-ui/NotoSans-BoldItalic.c62f70f121f271aa.woff2 +0 -0
  556. gns3server/static/web-ui/NotoSans-Italic.219ee88e5bc4e168.ttf +0 -0
  557. gns3server/static/web-ui/NotoSans-Italic.3d6f7cf772169c8d.svg +8453 -0
  558. gns3server/static/web-ui/NotoSans-Italic.77cd3818b5a2cb97.woff +0 -0
  559. gns3server/static/web-ui/NotoSans-Italic.85194585ae9d8c36.eot +0 -0
  560. gns3server/static/web-ui/NotoSans-Italic.eee02500e81db981.woff2 +0 -0
  561. gns3server/static/web-ui/NotoSans-Regular.156b7584192d70ed.eot +0 -0
  562. gns3server/static/web-ui/NotoSans-Regular.374d132a6803e279.woff2 +0 -0
  563. gns3server/static/web-ui/NotoSans-Regular.595e3f5876719740.woff +0 -0
  564. gns3server/static/web-ui/NotoSans-Regular.bb384defbe36eaec.svg +8453 -0
  565. gns3server/static/web-ui/NotoSans-Regular.e6139cb1663a1c57.ttf +0 -0
  566. gns3server/static/web-ui/ReleaseNotes.txt +179 -0
  567. gns3server/static/web-ui/assets/favicon.ico +0 -0
  568. gns3server/static/web-ui/assets/gns3_icon.svg +88 -0
  569. gns3server/static/web-ui/assets/gns3_icon_black.svg +88 -0
  570. gns3server/static/web-ui/assets/icons/mac/icon.icns +0 -0
  571. gns3server/static/web-ui/assets/icons/png/1024x1024.png +0 -0
  572. gns3server/static/web-ui/assets/icons/png/128x128.png +0 -0
  573. gns3server/static/web-ui/assets/icons/png/16x16.png +0 -0
  574. gns3server/static/web-ui/assets/icons/png/24x24.png +0 -0
  575. gns3server/static/web-ui/assets/icons/png/256x256.png +0 -0
  576. gns3server/static/web-ui/assets/icons/png/32x32.png +0 -0
  577. gns3server/static/web-ui/assets/icons/png/48x48.png +0 -0
  578. gns3server/static/web-ui/assets/icons/png/512x512.png +0 -0
  579. gns3server/static/web-ui/assets/icons/png/64x64.png +0 -0
  580. gns3server/static/web-ui/assets/icons/win/icon.ico +0 -0
  581. gns3server/static/web-ui/assets/logo-header.png +0 -0
  582. gns3server/static/web-ui/assets/resources/images/filter-capture.svg +428 -0
  583. gns3server/static/web-ui/assets/resources/images/filter.svg +708 -0
  584. gns3server/static/web-ui/assets/resources/images/inspect.svg +312 -0
  585. gns3server/static/web-ui/assets/resources/images/pause.svg +752 -0
  586. gns3server/static/web-ui/favicon.ico +0 -0
  587. gns3server/static/web-ui/index.html +51 -0
  588. gns3server/static/web-ui/main.f802edd2b8c6db1d.js +1 -0
  589. gns3server/static/web-ui/polyfills.319c79dd175e50d0.js +1 -0
  590. gns3server/static/web-ui/roboto-latin-100.539f0a96b40596f7.woff2 +0 -0
  591. gns3server/static/web-ui/roboto-latin-100.5ba994dac3e79ea8.woff +0 -0
  592. gns3server/static/web-ui/roboto-latin-100italic.41ba64219cb743c9.woff2 +0 -0
  593. gns3server/static/web-ui/roboto-latin-100italic.d61e7e8b07c0638c.woff +0 -0
  594. gns3server/static/web-ui/roboto-latin-300.4d8f8086236bad80.woff2 +0 -0
  595. gns3server/static/web-ui/roboto-latin-300.6c1bc461047e61f5.woff +0 -0
  596. gns3server/static/web-ui/roboto-latin-300italic.3a529751a590d3c1.woff +0 -0
  597. gns3server/static/web-ui/roboto-latin-300italic.45164643b3bd5824.woff2 +0 -0
  598. gns3server/static/web-ui/roboto-latin-400.1e2d4d3a272629cd.woff2 +0 -0
  599. gns3server/static/web-ui/roboto-latin-400.7e4a045b9373d9c1.woff +0 -0
  600. gns3server/static/web-ui/roboto-latin-400italic.68431199e5b90ea8.woff +0 -0
  601. gns3server/static/web-ui/roboto-latin-400italic.bb3c6955c4334c8a.woff2 +0 -0
  602. gns3server/static/web-ui/roboto-latin-500.1dfbc3dbf815e3f3.woff2 +0 -0
  603. gns3server/static/web-ui/roboto-latin-500.e21fe97fd2329ff7.woff +0 -0
  604. gns3server/static/web-ui/roboto-latin-500italic.7543a42b12b1452f.woff2 +0 -0
  605. gns3server/static/web-ui/roboto-latin-500italic.aaff6867154023d3.woff +0 -0
  606. gns3server/static/web-ui/roboto-latin-700.02633003129d1e63.woff +0 -0
  607. gns3server/static/web-ui/roboto-latin-700.12893bfc0762b0f3.woff2 +0 -0
  608. gns3server/static/web-ui/roboto-latin-700italic.bc7179e004e40113.woff2 +0 -0
  609. gns3server/static/web-ui/roboto-latin-700italic.e53062e27c63fafb.woff +0 -0
  610. gns3server/static/web-ui/roboto-latin-900.282ba77fda1349f3.woff2 +0 -0
  611. gns3server/static/web-ui/roboto-latin-900.4962e810cbb4d3e5.woff +0 -0
  612. gns3server/static/web-ui/roboto-latin-900italic.2394134a78bbaef8.woff +0 -0
  613. gns3server/static/web-ui/roboto-latin-900italic.9c1f80840351fa12.woff2 +0 -0
  614. gns3server/static/web-ui/runtime.24fa95b7061d7056.js +1 -0
  615. gns3server/static/web-ui/styles.6e966072487df0b7.css +5 -0
  616. gns3server/symbols/.gitkeep +0 -0
  617. gns3server/symbols/affinity/circle/blue/atm.svg +5 -0
  618. gns3server/symbols/affinity/circle/blue/bug.svg +8 -0
  619. gns3server/symbols/affinity/circle/blue/camera.svg +5 -0
  620. gns3server/symbols/affinity/circle/blue/camera_dome.svg +8 -0
  621. gns3server/symbols/affinity/circle/blue/client.svg +5 -0
  622. gns3server/symbols/affinity/circle/blue/client_vm.svg +6 -0
  623. gns3server/symbols/affinity/circle/blue/cloud.svg +5 -0
  624. gns3server/symbols/affinity/circle/blue/coffee.svg +6 -0
  625. gns3server/symbols/affinity/circle/blue/cog.svg +5 -0
  626. gns3server/symbols/affinity/circle/blue/communications.svg +5 -0
  627. gns3server/symbols/affinity/circle/blue/conversation.svg +12 -0
  628. gns3server/symbols/affinity/circle/blue/dna.svg +7 -0
  629. gns3server/symbols/affinity/circle/blue/dna2.svg +7 -0
  630. gns3server/symbols/affinity/circle/blue/docker.svg +11 -0
  631. gns3server/symbols/affinity/circle/blue/dslam.svg +5 -0
  632. gns3server/symbols/affinity/circle/blue/factory.svg +6 -0
  633. gns3server/symbols/affinity/circle/blue/fingerprint.svg +5 -0
  634. gns3server/symbols/affinity/circle/blue/firewall.svg +5 -0
  635. gns3server/symbols/affinity/circle/blue/firewall3.svg +5 -0
  636. gns3server/symbols/affinity/circle/blue/globe.svg +5 -0
  637. gns3server/symbols/affinity/circle/blue/grid.svg +5 -0
  638. gns3server/symbols/affinity/circle/blue/grid2.svg +5 -0
  639. gns3server/symbols/affinity/circle/blue/health.svg +5 -0
  640. gns3server/symbols/affinity/circle/blue/house.svg +9 -0
  641. gns3server/symbols/affinity/circle/blue/hub.svg +5 -0
  642. gns3server/symbols/affinity/circle/blue/inspect.svg +7 -0
  643. gns3server/symbols/affinity/circle/blue/inspect2.svg +6 -0
  644. gns3server/symbols/affinity/circle/blue/interconnect.svg +5 -0
  645. gns3server/symbols/affinity/circle/blue/ip_phone.svg +21 -0
  646. gns3server/symbols/affinity/circle/blue/isdn.svg +5 -0
  647. gns3server/symbols/affinity/circle/blue/laptop.svg +6 -0
  648. gns3server/symbols/affinity/circle/blue/ldap.svg +5 -0
  649. gns3server/symbols/affinity/circle/blue/light_bulb.svg +11 -0
  650. gns3server/symbols/affinity/circle/blue/link.svg +5 -0
  651. gns3server/symbols/affinity/circle/blue/loadbalancer.svg +5 -0
  652. gns3server/symbols/affinity/circle/blue/nas.svg +5 -0
  653. gns3server/symbols/affinity/circle/blue/nat.svg +60 -0
  654. gns3server/symbols/affinity/circle/blue/nat2.svg +55 -0
  655. gns3server/symbols/affinity/circle/blue/office.svg +5 -0
  656. gns3server/symbols/affinity/circle/blue/optical.svg +8 -0
  657. gns3server/symbols/affinity/circle/blue/phone_cloud.svg +6 -0
  658. gns3server/symbols/affinity/circle/blue/phone_old.svg +5 -0
  659. gns3server/symbols/affinity/circle/blue/phone_wireless.svg +8 -0
  660. gns3server/symbols/affinity/circle/blue/pinpoint.svg +5 -0
  661. gns3server/symbols/affinity/circle/blue/printer.svg +7 -0
  662. gns3server/symbols/affinity/circle/blue/rj45.svg +5 -0
  663. gns3server/symbols/affinity/circle/blue/router.svg +5 -0
  664. gns3server/symbols/affinity/circle/blue/router2.svg +5 -0
  665. gns3server/symbols/affinity/circle/blue/router_cloud.svg +6 -0
  666. gns3server/symbols/affinity/circle/blue/satellite.svg +6 -0
  667. gns3server/symbols/affinity/circle/blue/satellite_dish.svg +7 -0
  668. gns3server/symbols/affinity/circle/blue/scull.svg +8 -0
  669. gns3server/symbols/affinity/circle/blue/server.svg +5 -0
  670. gns3server/symbols/affinity/circle/blue/server_cluster.svg +7 -0
  671. gns3server/symbols/affinity/circle/blue/shield.svg +7 -0
  672. gns3server/symbols/affinity/circle/blue/statistics.svg +7 -0
  673. gns3server/symbols/affinity/circle/blue/storage.svg +5 -0
  674. gns3server/symbols/affinity/circle/blue/switch.svg +8 -0
  675. gns3server/symbols/affinity/circle/blue/switch_multilayer.svg +5 -0
  676. gns3server/symbols/affinity/circle/blue/tablet.svg +11 -0
  677. gns3server/symbols/affinity/circle/blue/template.svg +4 -0
  678. gns3server/symbols/affinity/circle/blue/tree.svg +5 -0
  679. gns3server/symbols/affinity/circle/blue/user.svg +7 -0
  680. gns3server/symbols/affinity/circle/blue/virtualbox.svg +7 -0
  681. gns3server/symbols/affinity/circle/blue/vm.svg +7 -0
  682. gns3server/symbols/affinity/circle/blue/vmware.svg +7 -0
  683. gns3server/symbols/affinity/circle/blue/vrf.svg +8 -0
  684. gns3server/symbols/affinity/circle/blue/wifi.svg +5 -0
  685. gns3server/symbols/affinity/circle/blue/wlc.svg +5 -0
  686. gns3server/symbols/affinity/circle/blue/xml.svg +5 -0
  687. gns3server/symbols/affinity/circle/gray/atm.svg +5 -0
  688. gns3server/symbols/affinity/circle/gray/bug.svg +8 -0
  689. gns3server/symbols/affinity/circle/gray/camera.svg +5 -0
  690. gns3server/symbols/affinity/circle/gray/camera_dome.svg +8 -0
  691. gns3server/symbols/affinity/circle/gray/client.svg +5 -0
  692. gns3server/symbols/affinity/circle/gray/client_vm.svg +6 -0
  693. gns3server/symbols/affinity/circle/gray/cloud.svg +5 -0
  694. gns3server/symbols/affinity/circle/gray/coffee.svg +6 -0
  695. gns3server/symbols/affinity/circle/gray/cog.svg +5 -0
  696. gns3server/symbols/affinity/circle/gray/communications.svg +5 -0
  697. gns3server/symbols/affinity/circle/gray/conversation.svg +12 -0
  698. gns3server/symbols/affinity/circle/gray/dna.svg +7 -0
  699. gns3server/symbols/affinity/circle/gray/dna2.svg +7 -0
  700. gns3server/symbols/affinity/circle/gray/docker.svg +11 -0
  701. gns3server/symbols/affinity/circle/gray/dslam.svg +5 -0
  702. gns3server/symbols/affinity/circle/gray/factory.svg +7 -0
  703. gns3server/symbols/affinity/circle/gray/fingerprint.svg +5 -0
  704. gns3server/symbols/affinity/circle/gray/firewall.svg +5 -0
  705. gns3server/symbols/affinity/circle/gray/firewall3.svg +5 -0
  706. gns3server/symbols/affinity/circle/gray/globe.svg +5 -0
  707. gns3server/symbols/affinity/circle/gray/grid.svg +5 -0
  708. gns3server/symbols/affinity/circle/gray/grid2.svg +5 -0
  709. gns3server/symbols/affinity/circle/gray/health.svg +5 -0
  710. gns3server/symbols/affinity/circle/gray/house.svg +9 -0
  711. gns3server/symbols/affinity/circle/gray/hub.svg +5 -0
  712. gns3server/symbols/affinity/circle/gray/inspect.svg +7 -0
  713. gns3server/symbols/affinity/circle/gray/inspect2.svg +6 -0
  714. gns3server/symbols/affinity/circle/gray/interconnect.svg +5 -0
  715. gns3server/symbols/affinity/circle/gray/ip_phone.svg +21 -0
  716. gns3server/symbols/affinity/circle/gray/isdn.svg +5 -0
  717. gns3server/symbols/affinity/circle/gray/laptop.svg +6 -0
  718. gns3server/symbols/affinity/circle/gray/ldap.svg +5 -0
  719. gns3server/symbols/affinity/circle/gray/light_bulb.svg +11 -0
  720. gns3server/symbols/affinity/circle/gray/link.svg +5 -0
  721. gns3server/symbols/affinity/circle/gray/loadbalancer.svg +5 -0
  722. gns3server/symbols/affinity/circle/gray/nas.svg +5 -0
  723. gns3server/symbols/affinity/circle/gray/nat.svg +60 -0
  724. gns3server/symbols/affinity/circle/gray/nat2.svg +55 -0
  725. gns3server/symbols/affinity/circle/gray/office.svg +5 -0
  726. gns3server/symbols/affinity/circle/gray/optical.svg +8 -0
  727. gns3server/symbols/affinity/circle/gray/phone_cloud.svg +6 -0
  728. gns3server/symbols/affinity/circle/gray/phone_old.svg +5 -0
  729. gns3server/symbols/affinity/circle/gray/phone_wireless.svg +8 -0
  730. gns3server/symbols/affinity/circle/gray/pinpoint.svg +5 -0
  731. gns3server/symbols/affinity/circle/gray/printer.svg +25 -0
  732. gns3server/symbols/affinity/circle/gray/rj45.svg +5 -0
  733. gns3server/symbols/affinity/circle/gray/router.svg +5 -0
  734. gns3server/symbols/affinity/circle/gray/router2.svg +5 -0
  735. gns3server/symbols/affinity/circle/gray/router_cloud.svg +6 -0
  736. gns3server/symbols/affinity/circle/gray/satellite.svg +6 -0
  737. gns3server/symbols/affinity/circle/gray/satellite_dish.svg +7 -0
  738. gns3server/symbols/affinity/circle/gray/scull.svg +8 -0
  739. gns3server/symbols/affinity/circle/gray/server.svg +5 -0
  740. gns3server/symbols/affinity/circle/gray/server_cluster.svg +7 -0
  741. gns3server/symbols/affinity/circle/gray/shield.svg +7 -0
  742. gns3server/symbols/affinity/circle/gray/statistics.svg +7 -0
  743. gns3server/symbols/affinity/circle/gray/storage.svg +5 -0
  744. gns3server/symbols/affinity/circle/gray/switch.svg +8 -0
  745. gns3server/symbols/affinity/circle/gray/switch_multilayer.svg +5 -0
  746. gns3server/symbols/affinity/circle/gray/tablet.svg +11 -0
  747. gns3server/symbols/affinity/circle/gray/template.svg +4 -0
  748. gns3server/symbols/affinity/circle/gray/tree.svg +5 -0
  749. gns3server/symbols/affinity/circle/gray/user.svg +7 -0
  750. gns3server/symbols/affinity/circle/gray/virtualbox.svg +7 -0
  751. gns3server/symbols/affinity/circle/gray/vm.svg +7 -0
  752. gns3server/symbols/affinity/circle/gray/vmware.svg +7 -0
  753. gns3server/symbols/affinity/circle/gray/vrf.svg +8 -0
  754. gns3server/symbols/affinity/circle/gray/wifi.svg +5 -0
  755. gns3server/symbols/affinity/circle/gray/wlc.svg +5 -0
  756. gns3server/symbols/affinity/circle/gray/xml.svg +5 -0
  757. gns3server/symbols/affinity/circle/green/atm.svg +5 -0
  758. gns3server/symbols/affinity/circle/green/bug.svg +8 -0
  759. gns3server/symbols/affinity/circle/green/camera.svg +5 -0
  760. gns3server/symbols/affinity/circle/green/camera_dome.svg +8 -0
  761. gns3server/symbols/affinity/circle/green/client.svg +5 -0
  762. gns3server/symbols/affinity/circle/green/client_vm.svg +6 -0
  763. gns3server/symbols/affinity/circle/green/cloud.svg +5 -0
  764. gns3server/symbols/affinity/circle/green/coffee.svg +6 -0
  765. gns3server/symbols/affinity/circle/green/cog.svg +5 -0
  766. gns3server/symbols/affinity/circle/green/communications.svg +5 -0
  767. gns3server/symbols/affinity/circle/green/conversation.svg +12 -0
  768. gns3server/symbols/affinity/circle/green/dna.svg +7 -0
  769. gns3server/symbols/affinity/circle/green/dna2.svg +7 -0
  770. gns3server/symbols/affinity/circle/green/docker.svg +11 -0
  771. gns3server/symbols/affinity/circle/green/dslam.svg +5 -0
  772. gns3server/symbols/affinity/circle/green/factory.svg +6 -0
  773. gns3server/symbols/affinity/circle/green/fingerprint.svg +5 -0
  774. gns3server/symbols/affinity/circle/green/firewall.svg +5 -0
  775. gns3server/symbols/affinity/circle/green/firewall3.svg +5 -0
  776. gns3server/symbols/affinity/circle/green/globe.svg +5 -0
  777. gns3server/symbols/affinity/circle/green/grid.svg +5 -0
  778. gns3server/symbols/affinity/circle/green/grid2.svg +5 -0
  779. gns3server/symbols/affinity/circle/green/health.svg +5 -0
  780. gns3server/symbols/affinity/circle/green/house.svg +9 -0
  781. gns3server/symbols/affinity/circle/green/hub.svg +5 -0
  782. gns3server/symbols/affinity/circle/green/inspect.svg +7 -0
  783. gns3server/symbols/affinity/circle/green/inspect2.svg +6 -0
  784. gns3server/symbols/affinity/circle/green/interconnect.svg +5 -0
  785. gns3server/symbols/affinity/circle/green/ip_phone.svg +21 -0
  786. gns3server/symbols/affinity/circle/green/isdn.svg +5 -0
  787. gns3server/symbols/affinity/circle/green/laptop.svg +6 -0
  788. gns3server/symbols/affinity/circle/green/ldap.svg +5 -0
  789. gns3server/symbols/affinity/circle/green/light_bulb.svg +11 -0
  790. gns3server/symbols/affinity/circle/green/link.svg +5 -0
  791. gns3server/symbols/affinity/circle/green/loadbalancer.svg +5 -0
  792. gns3server/symbols/affinity/circle/green/nas.svg +5 -0
  793. gns3server/symbols/affinity/circle/green/nat.svg +60 -0
  794. gns3server/symbols/affinity/circle/green/nat2.svg +55 -0
  795. gns3server/symbols/affinity/circle/green/office.svg +5 -0
  796. gns3server/symbols/affinity/circle/green/optical.svg +8 -0
  797. gns3server/symbols/affinity/circle/green/phone_cloud.svg +6 -0
  798. gns3server/symbols/affinity/circle/green/phone_old.svg +5 -0
  799. gns3server/symbols/affinity/circle/green/phone_wireless.svg +8 -0
  800. gns3server/symbols/affinity/circle/green/pinpoint.svg +5 -0
  801. gns3server/symbols/affinity/circle/green/printer.svg +7 -0
  802. gns3server/symbols/affinity/circle/green/rj45.svg +5 -0
  803. gns3server/symbols/affinity/circle/green/router.svg +5 -0
  804. gns3server/symbols/affinity/circle/green/router2.svg +5 -0
  805. gns3server/symbols/affinity/circle/green/router_cloud.svg +6 -0
  806. gns3server/symbols/affinity/circle/green/satellite.svg +6 -0
  807. gns3server/symbols/affinity/circle/green/satellite_dish.svg +7 -0
  808. gns3server/symbols/affinity/circle/green/scull.svg +8 -0
  809. gns3server/symbols/affinity/circle/green/server.svg +5 -0
  810. gns3server/symbols/affinity/circle/green/server_cluster.svg +7 -0
  811. gns3server/symbols/affinity/circle/green/shield.svg +7 -0
  812. gns3server/symbols/affinity/circle/green/statistics.svg +7 -0
  813. gns3server/symbols/affinity/circle/green/storage.svg +5 -0
  814. gns3server/symbols/affinity/circle/green/switch.svg +8 -0
  815. gns3server/symbols/affinity/circle/green/switch_multilayer.svg +5 -0
  816. gns3server/symbols/affinity/circle/green/tablet.svg +11 -0
  817. gns3server/symbols/affinity/circle/green/template.svg +4 -0
  818. gns3server/symbols/affinity/circle/green/tree.svg +5 -0
  819. gns3server/symbols/affinity/circle/green/user.svg +7 -0
  820. gns3server/symbols/affinity/circle/green/virtualbox.svg +7 -0
  821. gns3server/symbols/affinity/circle/green/vm.svg +7 -0
  822. gns3server/symbols/affinity/circle/green/vmware.svg +7 -0
  823. gns3server/symbols/affinity/circle/green/vrf.svg +8 -0
  824. gns3server/symbols/affinity/circle/green/wifi.svg +5 -0
  825. gns3server/symbols/affinity/circle/green/wlc.svg +5 -0
  826. gns3server/symbols/affinity/circle/green/xml.svg +5 -0
  827. gns3server/symbols/affinity/circle/red/atm.svg +5 -0
  828. gns3server/symbols/affinity/circle/red/bug.svg +8 -0
  829. gns3server/symbols/affinity/circle/red/camera.svg +5 -0
  830. gns3server/symbols/affinity/circle/red/camera_dome.svg +8 -0
  831. gns3server/symbols/affinity/circle/red/client.svg +5 -0
  832. gns3server/symbols/affinity/circle/red/client_vm.svg +6 -0
  833. gns3server/symbols/affinity/circle/red/cloud.svg +5 -0
  834. gns3server/symbols/affinity/circle/red/coffee.svg +6 -0
  835. gns3server/symbols/affinity/circle/red/cog.svg +5 -0
  836. gns3server/symbols/affinity/circle/red/communications.svg +5 -0
  837. gns3server/symbols/affinity/circle/red/conversation.svg +12 -0
  838. gns3server/symbols/affinity/circle/red/dna.svg +7 -0
  839. gns3server/symbols/affinity/circle/red/dna2.svg +7 -0
  840. gns3server/symbols/affinity/circle/red/docker.svg +11 -0
  841. gns3server/symbols/affinity/circle/red/dslam.svg +5 -0
  842. gns3server/symbols/affinity/circle/red/factory.svg +6 -0
  843. gns3server/symbols/affinity/circle/red/fingerprint.svg +5 -0
  844. gns3server/symbols/affinity/circle/red/firewall.svg +5 -0
  845. gns3server/symbols/affinity/circle/red/firewall3.svg +5 -0
  846. gns3server/symbols/affinity/circle/red/globe.svg +5 -0
  847. gns3server/symbols/affinity/circle/red/grid.svg +5 -0
  848. gns3server/symbols/affinity/circle/red/grid2.svg +5 -0
  849. gns3server/symbols/affinity/circle/red/health.svg +5 -0
  850. gns3server/symbols/affinity/circle/red/house.svg +9 -0
  851. gns3server/symbols/affinity/circle/red/hub.svg +5 -0
  852. gns3server/symbols/affinity/circle/red/inspect.svg +7 -0
  853. gns3server/symbols/affinity/circle/red/inspect2.svg +6 -0
  854. gns3server/symbols/affinity/circle/red/interconnect.svg +5 -0
  855. gns3server/symbols/affinity/circle/red/ip_phone.svg +21 -0
  856. gns3server/symbols/affinity/circle/red/isdn.svg +5 -0
  857. gns3server/symbols/affinity/circle/red/laptop.svg +6 -0
  858. gns3server/symbols/affinity/circle/red/ldap.svg +5 -0
  859. gns3server/symbols/affinity/circle/red/light_bulb.svg +11 -0
  860. gns3server/symbols/affinity/circle/red/link.svg +5 -0
  861. gns3server/symbols/affinity/circle/red/loadbalancer.svg +5 -0
  862. gns3server/symbols/affinity/circle/red/nas.svg +5 -0
  863. gns3server/symbols/affinity/circle/red/nat.svg +60 -0
  864. gns3server/symbols/affinity/circle/red/nat2.svg +55 -0
  865. gns3server/symbols/affinity/circle/red/office.svg +5 -0
  866. gns3server/symbols/affinity/circle/red/optical.svg +8 -0
  867. gns3server/symbols/affinity/circle/red/phone_cloud.svg +6 -0
  868. gns3server/symbols/affinity/circle/red/phone_old.svg +5 -0
  869. gns3server/symbols/affinity/circle/red/phone_wireless.svg +8 -0
  870. gns3server/symbols/affinity/circle/red/pinpoint.svg +5 -0
  871. gns3server/symbols/affinity/circle/red/printer.svg +7 -0
  872. gns3server/symbols/affinity/circle/red/rj45.svg +5 -0
  873. gns3server/symbols/affinity/circle/red/router.svg +5 -0
  874. gns3server/symbols/affinity/circle/red/router2.svg +5 -0
  875. gns3server/symbols/affinity/circle/red/router_cloud.svg +6 -0
  876. gns3server/symbols/affinity/circle/red/satellite.svg +6 -0
  877. gns3server/symbols/affinity/circle/red/satellite_dish.svg +7 -0
  878. gns3server/symbols/affinity/circle/red/scull.svg +8 -0
  879. gns3server/symbols/affinity/circle/red/server.svg +5 -0
  880. gns3server/symbols/affinity/circle/red/server_cluster.svg +7 -0
  881. gns3server/symbols/affinity/circle/red/shield.svg +7 -0
  882. gns3server/symbols/affinity/circle/red/statistics.svg +7 -0
  883. gns3server/symbols/affinity/circle/red/storage.svg +5 -0
  884. gns3server/symbols/affinity/circle/red/switch.svg +8 -0
  885. gns3server/symbols/affinity/circle/red/switch_multilayer.svg +5 -0
  886. gns3server/symbols/affinity/circle/red/tablet.svg +11 -0
  887. gns3server/symbols/affinity/circle/red/template.svg +4 -0
  888. gns3server/symbols/affinity/circle/red/tree.svg +5 -0
  889. gns3server/symbols/affinity/circle/red/user.svg +7 -0
  890. gns3server/symbols/affinity/circle/red/virtualbox.svg +7 -0
  891. gns3server/symbols/affinity/circle/red/vm.svg +7 -0
  892. gns3server/symbols/affinity/circle/red/vmware.svg +7 -0
  893. gns3server/symbols/affinity/circle/red/vrf.svg +8 -0
  894. gns3server/symbols/affinity/circle/red/wifi.svg +5 -0
  895. gns3server/symbols/affinity/circle/red/wlc.svg +5 -0
  896. gns3server/symbols/affinity/circle/red/xml.svg +5 -0
  897. gns3server/symbols/affinity/square/blue/atm.svg +5 -0
  898. gns3server/symbols/affinity/square/blue/bug.svg +5 -0
  899. gns3server/symbols/affinity/square/blue/camera.svg +12 -0
  900. gns3server/symbols/affinity/square/blue/camera_dome.svg +8 -0
  901. gns3server/symbols/affinity/square/blue/client.svg +8 -0
  902. gns3server/symbols/affinity/square/blue/client_vm.svg +8 -0
  903. gns3server/symbols/affinity/square/blue/cloud.svg +12 -0
  904. gns3server/symbols/affinity/square/blue/coffee.svg +5 -0
  905. gns3server/symbols/affinity/square/blue/cog.svg +8 -0
  906. gns3server/symbols/affinity/square/blue/communications.svg +8 -0
  907. gns3server/symbols/affinity/square/blue/conversation.svg +12 -0
  908. gns3server/symbols/affinity/square/blue/dna.svg +7 -0
  909. gns3server/symbols/affinity/square/blue/dna2.svg +7 -0
  910. gns3server/symbols/affinity/square/blue/docker.svg +11 -0
  911. gns3server/symbols/affinity/square/blue/dslam.svg +8 -0
  912. gns3server/symbols/affinity/square/blue/factory.svg +5 -0
  913. gns3server/symbols/affinity/square/blue/fingerprint.svg +9 -0
  914. gns3server/symbols/affinity/square/blue/firewall.svg +7 -0
  915. gns3server/symbols/affinity/square/blue/firewall3.svg +6 -0
  916. gns3server/symbols/affinity/square/blue/globe.svg +5 -0
  917. gns3server/symbols/affinity/square/blue/grid.svg +7 -0
  918. gns3server/symbols/affinity/square/blue/grid2.svg +7 -0
  919. gns3server/symbols/affinity/square/blue/health.svg +5 -0
  920. gns3server/symbols/affinity/square/blue/house.svg +6 -0
  921. gns3server/symbols/affinity/square/blue/hub.svg +7 -0
  922. gns3server/symbols/affinity/square/blue/inspect.svg +5 -0
  923. gns3server/symbols/affinity/square/blue/inspect2.svg +9 -0
  924. gns3server/symbols/affinity/square/blue/interconnect.svg +8 -0
  925. gns3server/symbols/affinity/square/blue/ip_phone.svg +23 -0
  926. gns3server/symbols/affinity/square/blue/isdn.svg +7 -0
  927. gns3server/symbols/affinity/square/blue/laptop.svg +8 -0
  928. gns3server/symbols/affinity/square/blue/ldap.svg +5 -0
  929. gns3server/symbols/affinity/square/blue/light_bulb.svg +11 -0
  930. gns3server/symbols/affinity/square/blue/link.svg +5 -0
  931. gns3server/symbols/affinity/square/blue/loadbalancer.svg +5 -0
  932. gns3server/symbols/affinity/square/blue/nas.svg +7 -0
  933. gns3server/symbols/affinity/square/blue/nat.svg +58 -0
  934. gns3server/symbols/affinity/square/blue/nat2.svg +74 -0
  935. gns3server/symbols/affinity/square/blue/office.svg +5 -0
  936. gns3server/symbols/affinity/square/blue/optical.svg +8 -0
  937. gns3server/symbols/affinity/square/blue/phone_cloud.svg +8 -0
  938. gns3server/symbols/affinity/square/blue/phone_old.svg +7 -0
  939. gns3server/symbols/affinity/square/blue/phone_wireless.svg +10 -0
  940. gns3server/symbols/affinity/square/blue/pinpoint.svg +9 -0
  941. gns3server/symbols/affinity/square/blue/printer.svg +27 -0
  942. gns3server/symbols/affinity/square/blue/rj45.svg +14 -0
  943. gns3server/symbols/affinity/square/blue/router.svg +7 -0
  944. gns3server/symbols/affinity/square/blue/router2.svg +5 -0
  945. gns3server/symbols/affinity/square/blue/router_cloud.svg +7 -0
  946. gns3server/symbols/affinity/square/blue/satellite.svg +8 -0
  947. gns3server/symbols/affinity/square/blue/satellite_dish.svg +7 -0
  948. gns3server/symbols/affinity/square/blue/scull.svg +10 -0
  949. gns3server/symbols/affinity/square/blue/server.svg +5 -0
  950. gns3server/symbols/affinity/square/blue/server_cluster.svg +9 -0
  951. gns3server/symbols/affinity/square/blue/shield.svg +5 -0
  952. gns3server/symbols/affinity/square/blue/statistics.svg +7 -0
  953. gns3server/symbols/affinity/square/blue/storage.svg +7 -0
  954. gns3server/symbols/affinity/square/blue/switch.svg +10 -0
  955. gns3server/symbols/affinity/square/blue/switch_multilayer.svg +8 -0
  956. gns3server/symbols/affinity/square/blue/tablet.svg +9 -0
  957. gns3server/symbols/affinity/square/blue/template.svg +4 -0
  958. gns3server/symbols/affinity/square/blue/tree.svg +5 -0
  959. gns3server/symbols/affinity/square/blue/user.svg +7 -0
  960. gns3server/symbols/affinity/square/blue/virtualbox.svg +7 -0
  961. gns3server/symbols/affinity/square/blue/vm.svg +7 -0
  962. gns3server/symbols/affinity/square/blue/vmware.svg +7 -0
  963. gns3server/symbols/affinity/square/blue/vrf.svg +5 -0
  964. gns3server/symbols/affinity/square/blue/wifi.svg +13 -0
  965. gns3server/symbols/affinity/square/blue/wlc.svg +7 -0
  966. gns3server/symbols/affinity/square/blue/xml.svg +10 -0
  967. gns3server/symbols/affinity/square/gray/atm.svg +5 -0
  968. gns3server/symbols/affinity/square/gray/bug.svg +5 -0
  969. gns3server/symbols/affinity/square/gray/camera.svg +12 -0
  970. gns3server/symbols/affinity/square/gray/camera_dome.svg +8 -0
  971. gns3server/symbols/affinity/square/gray/client.svg +8 -0
  972. gns3server/symbols/affinity/square/gray/client_vm.svg +8 -0
  973. gns3server/symbols/affinity/square/gray/cloud.svg +12 -0
  974. gns3server/symbols/affinity/square/gray/coffee.svg +5 -0
  975. gns3server/symbols/affinity/square/gray/cog.svg +8 -0
  976. gns3server/symbols/affinity/square/gray/communications.svg +8 -0
  977. gns3server/symbols/affinity/square/gray/conversation.svg +12 -0
  978. gns3server/symbols/affinity/square/gray/dna.svg +7 -0
  979. gns3server/symbols/affinity/square/gray/dna2.svg +7 -0
  980. gns3server/symbols/affinity/square/gray/docker.svg +11 -0
  981. gns3server/symbols/affinity/square/gray/dslam.svg +8 -0
  982. gns3server/symbols/affinity/square/gray/factory.svg +5 -0
  983. gns3server/symbols/affinity/square/gray/fingerprint.svg +9 -0
  984. gns3server/symbols/affinity/square/gray/firewall.svg +7 -0
  985. gns3server/symbols/affinity/square/gray/firewall3.svg +6 -0
  986. gns3server/symbols/affinity/square/gray/globe.svg +5 -0
  987. gns3server/symbols/affinity/square/gray/grid.svg +7 -0
  988. gns3server/symbols/affinity/square/gray/grid2.svg +7 -0
  989. gns3server/symbols/affinity/square/gray/health.svg +5 -0
  990. gns3server/symbols/affinity/square/gray/house.svg +6 -0
  991. gns3server/symbols/affinity/square/gray/hub.svg +7 -0
  992. gns3server/symbols/affinity/square/gray/inspect.svg +5 -0
  993. gns3server/symbols/affinity/square/gray/inspect2.svg +9 -0
  994. gns3server/symbols/affinity/square/gray/interconnect.svg +8 -0
  995. gns3server/symbols/affinity/square/gray/ip_phone.svg +23 -0
  996. gns3server/symbols/affinity/square/gray/isdn.svg +7 -0
  997. gns3server/symbols/affinity/square/gray/laptop.svg +8 -0
  998. gns3server/symbols/affinity/square/gray/ldap.svg +5 -0
  999. gns3server/symbols/affinity/square/gray/light_bulb.svg +11 -0
  1000. gns3server/symbols/affinity/square/gray/link.svg +5 -0
  1001. gns3server/symbols/affinity/square/gray/loadbalancer.svg +5 -0
  1002. gns3server/symbols/affinity/square/gray/nas.svg +7 -0
  1003. gns3server/symbols/affinity/square/gray/nat.svg +58 -0
  1004. gns3server/symbols/affinity/square/gray/nat2.svg +74 -0
  1005. gns3server/symbols/affinity/square/gray/office.svg +5 -0
  1006. gns3server/symbols/affinity/square/gray/optical.svg +8 -0
  1007. gns3server/symbols/affinity/square/gray/phone_cloud.svg +8 -0
  1008. gns3server/symbols/affinity/square/gray/phone_old.svg +7 -0
  1009. gns3server/symbols/affinity/square/gray/phone_wireless.svg +10 -0
  1010. gns3server/symbols/affinity/square/gray/pinpoint.svg +9 -0
  1011. gns3server/symbols/affinity/square/gray/printer.svg +27 -0
  1012. gns3server/symbols/affinity/square/gray/rj45.svg +14 -0
  1013. gns3server/symbols/affinity/square/gray/router.svg +7 -0
  1014. gns3server/symbols/affinity/square/gray/router2.svg +5 -0
  1015. gns3server/symbols/affinity/square/gray/router_cloud.svg +7 -0
  1016. gns3server/symbols/affinity/square/gray/satellite.svg +8 -0
  1017. gns3server/symbols/affinity/square/gray/satellite_dish.svg +7 -0
  1018. gns3server/symbols/affinity/square/gray/scull.svg +10 -0
  1019. gns3server/symbols/affinity/square/gray/server.svg +5 -0
  1020. gns3server/symbols/affinity/square/gray/server_cluster.svg +9 -0
  1021. gns3server/symbols/affinity/square/gray/shield.svg +5 -0
  1022. gns3server/symbols/affinity/square/gray/statistics.svg +7 -0
  1023. gns3server/symbols/affinity/square/gray/storage.svg +5 -0
  1024. gns3server/symbols/affinity/square/gray/switch.svg +10 -0
  1025. gns3server/symbols/affinity/square/gray/switch_multilayer.svg +9 -0
  1026. gns3server/symbols/affinity/square/gray/tablet.svg +9 -0
  1027. gns3server/symbols/affinity/square/gray/template.svg +4 -0
  1028. gns3server/symbols/affinity/square/gray/tree.svg +5 -0
  1029. gns3server/symbols/affinity/square/gray/user.svg +7 -0
  1030. gns3server/symbols/affinity/square/gray/virtualbox.svg +7 -0
  1031. gns3server/symbols/affinity/square/gray/vm.svg +7 -0
  1032. gns3server/symbols/affinity/square/gray/vmware.svg +7 -0
  1033. gns3server/symbols/affinity/square/gray/vrf.svg +5 -0
  1034. gns3server/symbols/affinity/square/gray/wifi.svg +13 -0
  1035. gns3server/symbols/affinity/square/gray/wlc.svg +7 -0
  1036. gns3server/symbols/affinity/square/gray/xml.svg +10 -0
  1037. gns3server/symbols/affinity/square/green/atm.svg +5 -0
  1038. gns3server/symbols/affinity/square/green/bug.svg +5 -0
  1039. gns3server/symbols/affinity/square/green/camera.svg +5 -0
  1040. gns3server/symbols/affinity/square/green/camera_dome.svg +8 -0
  1041. gns3server/symbols/affinity/square/green/client.svg +5 -0
  1042. gns3server/symbols/affinity/square/green/client_vm.svg +6 -0
  1043. gns3server/symbols/affinity/square/green/cloud.svg +12 -0
  1044. gns3server/symbols/affinity/square/green/coffee.svg +5 -0
  1045. gns3server/symbols/affinity/square/green/cog.svg +5 -0
  1046. gns3server/symbols/affinity/square/green/communications.svg +5 -0
  1047. gns3server/symbols/affinity/square/green/conversation.svg +12 -0
  1048. gns3server/symbols/affinity/square/green/dna.svg +7 -0
  1049. gns3server/symbols/affinity/square/green/dna2.svg +7 -0
  1050. gns3server/symbols/affinity/square/green/docker.svg +11 -0
  1051. gns3server/symbols/affinity/square/green/dslam.svg +5 -0
  1052. gns3server/symbols/affinity/square/green/factory.svg +5 -0
  1053. gns3server/symbols/affinity/square/green/fingerprint.svg +5 -0
  1054. gns3server/symbols/affinity/square/green/firewall.svg +5 -0
  1055. gns3server/symbols/affinity/square/green/firewall3.svg +5 -0
  1056. gns3server/symbols/affinity/square/green/globe.svg +5 -0
  1057. gns3server/symbols/affinity/square/green/grid.svg +5 -0
  1058. gns3server/symbols/affinity/square/green/grid2.svg +5 -0
  1059. gns3server/symbols/affinity/square/green/health.svg +5 -0
  1060. gns3server/symbols/affinity/square/green/house.svg +6 -0
  1061. gns3server/symbols/affinity/square/green/hub.svg +5 -0
  1062. gns3server/symbols/affinity/square/green/inspect.svg +5 -0
  1063. gns3server/symbols/affinity/square/green/inspect2.svg +5 -0
  1064. gns3server/symbols/affinity/square/green/interconnect.svg +5 -0
  1065. gns3server/symbols/affinity/square/green/ip_phone.svg +7 -0
  1066. gns3server/symbols/affinity/square/green/isdn.svg +5 -0
  1067. gns3server/symbols/affinity/square/green/laptop.svg +8 -0
  1068. gns3server/symbols/affinity/square/green/ldap.svg +5 -0
  1069. gns3server/symbols/affinity/square/green/light_bulb.svg +5 -0
  1070. gns3server/symbols/affinity/square/green/link.svg +5 -0
  1071. gns3server/symbols/affinity/square/green/loadbalancer.svg +5 -0
  1072. gns3server/symbols/affinity/square/green/nas.svg +5 -0
  1073. gns3server/symbols/affinity/square/green/nat.svg +58 -0
  1074. gns3server/symbols/affinity/square/green/nat2.svg +74 -0
  1075. gns3server/symbols/affinity/square/green/office.svg +5 -0
  1076. gns3server/symbols/affinity/square/green/optical.svg +8 -0
  1077. gns3server/symbols/affinity/square/green/phone_cloud.svg +6 -0
  1078. gns3server/symbols/affinity/square/green/phone_old.svg +5 -0
  1079. gns3server/symbols/affinity/square/green/phone_wireless.svg +5 -0
  1080. gns3server/symbols/affinity/square/green/pinpoint.svg +5 -0
  1081. gns3server/symbols/affinity/square/green/printer.svg +27 -0
  1082. gns3server/symbols/affinity/square/green/rj45.svg +5 -0
  1083. gns3server/symbols/affinity/square/green/router.svg +5 -0
  1084. gns3server/symbols/affinity/square/green/router2.svg +5 -0
  1085. gns3server/symbols/affinity/square/green/router_cloud.svg +6 -0
  1086. gns3server/symbols/affinity/square/green/satellite.svg +5 -0
  1087. gns3server/symbols/affinity/square/green/satellite_dish.svg +5 -0
  1088. gns3server/symbols/affinity/square/green/scull.svg +8 -0
  1089. gns3server/symbols/affinity/square/green/server.svg +5 -0
  1090. gns3server/symbols/affinity/square/green/server_cluster.svg +7 -0
  1091. gns3server/symbols/affinity/square/green/shield.svg +5 -0
  1092. gns3server/symbols/affinity/square/green/statistics.svg +5 -0
  1093. gns3server/symbols/affinity/square/green/storage.svg +5 -0
  1094. gns3server/symbols/affinity/square/green/switch.svg +10 -0
  1095. gns3server/symbols/affinity/square/green/switch_multilayer.svg +5 -0
  1096. gns3server/symbols/affinity/square/green/tablet.svg +9 -0
  1097. gns3server/symbols/affinity/square/green/template.svg +4 -0
  1098. gns3server/symbols/affinity/square/green/tree.svg +5 -0
  1099. gns3server/symbols/affinity/square/green/user.svg +7 -0
  1100. gns3server/symbols/affinity/square/green/virtualbox.svg +7 -0
  1101. gns3server/symbols/affinity/square/green/vm.svg +7 -0
  1102. gns3server/symbols/affinity/square/green/vmware.svg +7 -0
  1103. gns3server/symbols/affinity/square/green/vrf.svg +5 -0
  1104. gns3server/symbols/affinity/square/green/wifi.svg +5 -0
  1105. gns3server/symbols/affinity/square/green/wlc.svg +5 -0
  1106. gns3server/symbols/affinity/square/green/xml.svg +5 -0
  1107. gns3server/symbols/affinity/square/red/atm.svg +5 -0
  1108. gns3server/symbols/affinity/square/red/bug.svg +5 -0
  1109. gns3server/symbols/affinity/square/red/camera.svg +12 -0
  1110. gns3server/symbols/affinity/square/red/camera_dome.svg +8 -0
  1111. gns3server/symbols/affinity/square/red/client.svg +8 -0
  1112. gns3server/symbols/affinity/square/red/client_vm.svg +8 -0
  1113. gns3server/symbols/affinity/square/red/cloud.svg +12 -0
  1114. gns3server/symbols/affinity/square/red/coffee.svg +5 -0
  1115. gns3server/symbols/affinity/square/red/cog.svg +8 -0
  1116. gns3server/symbols/affinity/square/red/communications.svg +8 -0
  1117. gns3server/symbols/affinity/square/red/conversation.svg +12 -0
  1118. gns3server/symbols/affinity/square/red/dna.svg +7 -0
  1119. gns3server/symbols/affinity/square/red/dna2.svg +7 -0
  1120. gns3server/symbols/affinity/square/red/docker.svg +11 -0
  1121. gns3server/symbols/affinity/square/red/dslam.svg +8 -0
  1122. gns3server/symbols/affinity/square/red/factory.svg +5 -0
  1123. gns3server/symbols/affinity/square/red/fingerprint.svg +9 -0
  1124. gns3server/symbols/affinity/square/red/firewall.svg +7 -0
  1125. gns3server/symbols/affinity/square/red/firewall3.svg +5 -0
  1126. gns3server/symbols/affinity/square/red/globe.svg +5 -0
  1127. gns3server/symbols/affinity/square/red/grid.svg +7 -0
  1128. gns3server/symbols/affinity/square/red/grid2.svg +7 -0
  1129. gns3server/symbols/affinity/square/red/health.svg +5 -0
  1130. gns3server/symbols/affinity/square/red/house.svg +6 -0
  1131. gns3server/symbols/affinity/square/red/hub.svg +7 -0
  1132. gns3server/symbols/affinity/square/red/inspect.svg +5 -0
  1133. gns3server/symbols/affinity/square/red/inspect2.svg +9 -0
  1134. gns3server/symbols/affinity/square/red/interconnect.svg +8 -0
  1135. gns3server/symbols/affinity/square/red/ip_phone.svg +7 -0
  1136. gns3server/symbols/affinity/square/red/isdn.svg +7 -0
  1137. gns3server/symbols/affinity/square/red/laptop.svg +8 -0
  1138. gns3server/symbols/affinity/square/red/ldap.svg +5 -0
  1139. gns3server/symbols/affinity/square/red/light_bulb.svg +5 -0
  1140. gns3server/symbols/affinity/square/red/link.svg +5 -0
  1141. gns3server/symbols/affinity/square/red/loadbalancer.svg +5 -0
  1142. gns3server/symbols/affinity/square/red/nas.svg +7 -0
  1143. gns3server/symbols/affinity/square/red/nat.svg +58 -0
  1144. gns3server/symbols/affinity/square/red/nat2.svg +74 -0
  1145. gns3server/symbols/affinity/square/red/office.svg +5 -0
  1146. gns3server/symbols/affinity/square/red/optical.svg +8 -0
  1147. gns3server/symbols/affinity/square/red/phone_cloud.svg +6 -0
  1148. gns3server/symbols/affinity/square/red/phone_old.svg +5 -0
  1149. gns3server/symbols/affinity/square/red/phone_wireless.svg +5 -0
  1150. gns3server/symbols/affinity/square/red/pinpoint.svg +9 -0
  1151. gns3server/symbols/affinity/square/red/printer.svg +27 -0
  1152. gns3server/symbols/affinity/square/red/rj45.svg +14 -0
  1153. gns3server/symbols/affinity/square/red/router.svg +7 -0
  1154. gns3server/symbols/affinity/square/red/router2.svg +5 -0
  1155. gns3server/symbols/affinity/square/red/router_cloud.svg +6 -0
  1156. gns3server/symbols/affinity/square/red/satellite.svg +8 -0
  1157. gns3server/symbols/affinity/square/red/satellite_dish.svg +5 -0
  1158. gns3server/symbols/affinity/square/red/scull.svg +10 -0
  1159. gns3server/symbols/affinity/square/red/server.svg +5 -0
  1160. gns3server/symbols/affinity/square/red/server_cluster.svg +9 -0
  1161. gns3server/symbols/affinity/square/red/shield.svg +5 -0
  1162. gns3server/symbols/affinity/square/red/statistics.svg +5 -0
  1163. gns3server/symbols/affinity/square/red/storage.svg +7 -0
  1164. gns3server/symbols/affinity/square/red/switch.svg +10 -0
  1165. gns3server/symbols/affinity/square/red/switch_multilayer.svg +9 -0
  1166. gns3server/symbols/affinity/square/red/tablet.svg +9 -0
  1167. gns3server/symbols/affinity/square/red/template.svg +4 -0
  1168. gns3server/symbols/affinity/square/red/tree.svg +5 -0
  1169. gns3server/symbols/affinity/square/red/user.svg +7 -0
  1170. gns3server/symbols/affinity/square/red/virtualbox.svg +7 -0
  1171. gns3server/symbols/affinity/square/red/vm.svg +7 -0
  1172. gns3server/symbols/affinity/square/red/vmware.svg +7 -0
  1173. gns3server/symbols/affinity/square/red/vrf.svg +5 -0
  1174. gns3server/symbols/affinity/square/red/wifi.svg +13 -0
  1175. gns3server/symbols/affinity/square/red/wlc.svg +7 -0
  1176. gns3server/symbols/affinity/square/red/xml.svg +10 -0
  1177. gns3server/symbols/classic/PBX.svg +304 -0
  1178. gns3server/symbols/classic/PIX_firewall.svg +187 -0
  1179. gns3server/symbols/classic/access_point.svg +516 -0
  1180. gns3server/symbols/classic/access_server.svg +270 -0
  1181. gns3server/symbols/classic/asa.svg +424 -0
  1182. gns3server/symbols/classic/atm_bridge.svg +219 -0
  1183. gns3server/symbols/classic/atm_switch.svg +243 -0
  1184. gns3server/symbols/classic/call_manager.svg +228 -0
  1185. gns3server/symbols/classic/cloud.svg +163 -0
  1186. gns3server/symbols/classic/computer.svg +560 -0
  1187. gns3server/symbols/classic/docker_guest.svg +657 -0
  1188. gns3server/symbols/classic/dslam.svg +155 -0
  1189. gns3server/symbols/classic/edge_label_switch_router.svg +216 -0
  1190. gns3server/symbols/classic/ethernet_switch.svg +228 -0
  1191. gns3server/symbols/classic/firewall.svg +187 -0
  1192. gns3server/symbols/classic/frame_relay_switch.svg +263 -0
  1193. gns3server/symbols/classic/gateway.svg +309 -0
  1194. gns3server/symbols/classic/hub.svg +204 -0
  1195. gns3server/symbols/classic/ids.svg +310 -0
  1196. gns3server/symbols/classic/iosv_l2_virl.svg +286 -0
  1197. gns3server/symbols/classic/iosv_virl.svg +394 -0
  1198. gns3server/symbols/classic/ip_phone.svg +171 -0
  1199. gns3server/symbols/classic/label_switch_router.svg +223 -0
  1200. gns3server/symbols/classic/lightweight_ap.svg +536 -0
  1201. gns3server/symbols/classic/multilayer_switch.svg +317 -0
  1202. gns3server/symbols/classic/nat.svg +207 -0
  1203. gns3server/symbols/classic/optical_router.svg +207 -0
  1204. gns3server/symbols/classic/printer.svg +178 -0
  1205. gns3server/symbols/classic/qemu_guest.svg +1387 -0
  1206. gns3server/symbols/classic/route_switch_processor.svg +395 -0
  1207. gns3server/symbols/classic/router.awp.svg +362 -0
  1208. gns3server/symbols/classic/router.svg +203 -0
  1209. gns3server/symbols/classic/router_firewall.svg +395 -0
  1210. gns3server/symbols/classic/router_netflow.svg +215 -0
  1211. gns3server/symbols/classic/server.svg +226 -0
  1212. gns3server/symbols/classic/sip_server.svg +305 -0
  1213. gns3server/symbols/classic/traceng.svg +610 -0
  1214. gns3server/symbols/classic/vbox_guest.svg +7691 -0
  1215. gns3server/symbols/classic/vmware_guest.svg +572 -0
  1216. gns3server/symbols/classic/voice_access_server.svg +289 -0
  1217. gns3server/symbols/classic/voice_router.svg +223 -0
  1218. gns3server/symbols/classic/vpcs_guest.svg +574 -0
  1219. gns3server/symbols/classic/wlan_controller.svg +528 -0
  1220. gns3server/templates/compute.html +62 -0
  1221. gns3server/templates/controller.html +55 -0
  1222. gns3server/templates/index.html +12 -0
  1223. gns3server/templates/layout.html +20 -0
  1224. gns3server/templates/project.html +91 -0
  1225. gns3server/templates/upload.html +6 -0
  1226. gns3server/utils/__init__.py +123 -0
  1227. gns3server/utils/application_id.py +49 -0
  1228. gns3server/utils/asyncio/__init__.py +148 -0
  1229. gns3server/utils/asyncio/aiozipstream.py +528 -0
  1230. gns3server/utils/asyncio/embed_shell.py +369 -0
  1231. gns3server/utils/asyncio/input_stream.py +408 -0
  1232. gns3server/utils/asyncio/pool.py +69 -0
  1233. gns3server/utils/asyncio/raw_command_server.py +140 -0
  1234. gns3server/utils/asyncio/serial.py +87 -0
  1235. gns3server/utils/asyncio/telnet_server.py +450 -0
  1236. gns3server/utils/cpu_percent.py +46 -0
  1237. gns3server/utils/file_watcher.py +103 -0
  1238. gns3server/utils/get_resource.py +48 -0
  1239. gns3server/utils/hostname.py +112 -0
  1240. gns3server/utils/http_client.py +71 -0
  1241. gns3server/utils/images.py +378 -0
  1242. gns3server/utils/interfaces.py +254 -0
  1243. gns3server/utils/notification_queue.py +79 -0
  1244. gns3server/utils/path.py +76 -0
  1245. gns3server/utils/picture.py +146 -0
  1246. gns3server/utils/qt.py +44 -0
  1247. gns3server/utils/vmnet.py +277 -0
  1248. gns3server/utils/zipfile_zstd/__init__.py +10 -0
  1249. gns3server/utils/zipfile_zstd/_patcher.py +20 -0
  1250. gns3server/utils/zipfile_zstd/_zipfile.py +64 -0
  1251. gns3server/version.py +36 -0
@@ -0,0 +1,1399 @@
1
+ #!/usr/bin/env python
2
+ #
3
+ # Copyright (C) 2016 GNS3 Technologies Inc.
4
+ #
5
+ # This program is free software: you can redistribute it and/or modify
6
+ # it under the terms of the GNU General Public License as published by
7
+ # the Free Software Foundation, either version 3 of the License, or
8
+ # (at your option) any later version.
9
+ #
10
+ # This program is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU General Public License for more details.
14
+ #
15
+ # You should have received a copy of the GNU General Public License
16
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
17
+
18
+ import sys
19
+ import re
20
+ import os
21
+ import json
22
+ import uuid
23
+ import copy
24
+ import shutil
25
+ import time
26
+ import asyncio
27
+ import aiofiles
28
+ import tempfile
29
+ import zipfile
30
+ import pathlib
31
+
32
+ from uuid import UUID, uuid4
33
+
34
+ from .node import Node
35
+ from .compute import ComputeError
36
+ from .snapshot import Snapshot
37
+ from .drawing import Drawing
38
+ from .topology import project_to_topology, load_topology
39
+ from .udp_link import UDPLink
40
+ from ..config import Config
41
+ from ..utils.path import check_path_allowed, get_default_project_directory
42
+ from ..utils.application_id import get_next_application_id
43
+ from ..utils.asyncio.pool import Pool
44
+ from ..utils.asyncio import locking
45
+ from ..utils.asyncio import aiozipstream
46
+ from ..utils.asyncio import wait_run_in_executor
47
+ from .export_project import export_project
48
+ from .import_project import import_project, _move_node_file
49
+ from .controller_error import ControllerError, ControllerForbiddenError, ControllerNotFoundError
50
+
51
+ import logging
52
+
53
+ log = logging.getLogger(__name__)
54
+
55
+
56
+ def open_required(func):
57
+ """
58
+ Use this decorator to raise an error if the project is not opened
59
+ """
60
+
61
+ def wrapper(self, *args, **kwargs):
62
+ if self._status == "closed":
63
+ raise ControllerForbiddenError("The project is not opened")
64
+ return func(self, *args, **kwargs)
65
+
66
+ return wrapper
67
+
68
+
69
+ class Project:
70
+ """
71
+ A project inside a controller
72
+
73
+ :param project_id: force project identifier (None by default auto generate an UUID)
74
+ :param path: path of the project. (None use the standard directory)
75
+ :param status: Status of the project (opened / closed)
76
+ """
77
+
78
+ def __init__(
79
+ self,
80
+ name=None,
81
+ project_id=None,
82
+ path=None,
83
+ controller=None,
84
+ status="opened",
85
+ filename=None,
86
+ auto_start=False,
87
+ auto_open=False,
88
+ auto_close=True,
89
+ scene_height=1000,
90
+ scene_width=2000,
91
+ zoom=100,
92
+ show_layers=False,
93
+ snap_to_grid=False,
94
+ show_grid=False,
95
+ grid_size=75,
96
+ drawing_grid_size=25,
97
+ show_interface_labels=False,
98
+ variables=None,
99
+ supplier=None,
100
+ ):
101
+
102
+ self._controller = controller
103
+ assert name is not None
104
+ self._name = name
105
+ self._auto_start = auto_start
106
+ self._auto_close = auto_close
107
+ self._auto_open = auto_open
108
+ self._status = status
109
+ self._scene_height = scene_height
110
+ self._scene_width = scene_width
111
+ self._zoom = zoom
112
+ self._show_layers = show_layers
113
+ self._snap_to_grid = snap_to_grid
114
+ self._show_grid = show_grid
115
+ self._grid_size = grid_size
116
+ self._drawing_grid_size = drawing_grid_size
117
+ self._show_interface_labels = show_interface_labels
118
+ self._variables = variables
119
+ self._supplier = supplier
120
+
121
+ self._loading = False
122
+ self._closing = False
123
+
124
+ # Disallow overwrite of existing project
125
+ if project_id is None and path is not None:
126
+ if os.path.exists(path):
127
+ raise ControllerForbiddenError(f"The path {path} already exists")
128
+ else:
129
+ raise ControllerForbiddenError("Providing a path to create a new project is deprecated.")
130
+
131
+ if project_id is None:
132
+ self._id = str(uuid4())
133
+ else:
134
+ try:
135
+ UUID(project_id, version=4)
136
+ except ValueError:
137
+ raise ControllerError(f"{project_id} is not a valid UUID")
138
+ self._id = project_id
139
+
140
+ if path is None:
141
+ path = os.path.join(get_default_project_directory(), self._id)
142
+ self.path = path
143
+
144
+ if filename is not None:
145
+ self._filename = filename
146
+ else:
147
+ self._filename = self.name + ".gns3"
148
+
149
+ self.reset()
150
+
151
+ # At project creation we write an empty .gns3 with the meta
152
+ if not os.path.exists(self._topology_file()):
153
+ assert self._status != "closed"
154
+ self.dump()
155
+
156
+ self._iou_id_lock = asyncio.Lock()
157
+ log.debug(f'Project "{self.name}" [{self._id}] loaded')
158
+ self.emit_controller_notification("project.created", self.asdict())
159
+
160
+ def emit_notification(self, action, event):
161
+ """
162
+ Emit a project notification to all clients using this project.
163
+
164
+ :param action: Action name
165
+ :param event: Event to send
166
+ """
167
+
168
+ self._controller.notification.project_emit(action, event, project_id=self.id)
169
+
170
+ def emit_controller_notification(self, action, event):
171
+ """
172
+ Emit a controller notification, all clients will see it.
173
+
174
+ :param action: Action name
175
+ :param event: Event to send
176
+ """
177
+
178
+ self._controller.notification.controller_emit(action, event)
179
+
180
+ async def update(self, **kwargs):
181
+ """
182
+ Update the project
183
+ :param kwargs: Project properties
184
+ """
185
+
186
+ old_json = self.asdict()
187
+
188
+ for prop in kwargs:
189
+ setattr(self, prop, kwargs[prop])
190
+
191
+ # We send notif only if object has changed
192
+ if old_json != self.asdict():
193
+ self.emit_controller_notification("project.updated", self.asdict())
194
+ self.dump()
195
+
196
+ # update on computes
197
+ for compute in list(self._project_created_on_compute):
198
+ await compute.put(f"/projects/{self._id}", {"variables": self.variables})
199
+
200
+ def reset(self):
201
+ """
202
+ Called when open/close a project. Cleanup internal stuff
203
+ """
204
+ self._allocated_node_names = set()
205
+ self._nodes = {}
206
+ self._links = {}
207
+ self._drawings = {}
208
+ self._snapshots = {}
209
+ self._computes = []
210
+
211
+ # List the available snapshots
212
+ snapshot_dir = os.path.join(self.path, "snapshots")
213
+ if os.path.exists(snapshot_dir):
214
+ for snap in os.listdir(snapshot_dir):
215
+ if snap.endswith(".gns3project"):
216
+ try:
217
+ snapshot = Snapshot(self, filename=snap)
218
+ except ValueError:
219
+ log.error("Invalid snapshot file: {}".format(snap))
220
+ continue
221
+ self._snapshots[snapshot.id] = snapshot
222
+
223
+ # Create the project on demand on the compute node
224
+ self._project_created_on_compute = set()
225
+
226
+ @property
227
+ def scene_height(self):
228
+ return self._scene_height
229
+
230
+ @scene_height.setter
231
+ def scene_height(self, val):
232
+ """
233
+ Height of the drawing area
234
+ """
235
+ self._scene_height = val
236
+
237
+ @property
238
+ def scene_width(self):
239
+ return self._scene_width
240
+
241
+ @scene_width.setter
242
+ def scene_width(self, val):
243
+ """
244
+ Width of the drawing area
245
+ """
246
+ self._scene_width = val
247
+
248
+ @property
249
+ def zoom(self):
250
+ """
251
+ Zoom level in percentage
252
+ :return: integer > 0
253
+ """
254
+ return self._zoom
255
+
256
+ @zoom.setter
257
+ def zoom(self, zoom):
258
+ """
259
+ Setter for zoom level in percentage
260
+ """
261
+ self._zoom = zoom
262
+
263
+ @property
264
+ def show_layers(self):
265
+ """
266
+ Show layers mode
267
+ :return: bool
268
+ """
269
+ return self._show_layers
270
+
271
+ @show_layers.setter
272
+ def show_layers(self, show_layers):
273
+ """
274
+ Setter for show layers mode
275
+ """
276
+ self._show_layers = show_layers
277
+
278
+ @property
279
+ def snap_to_grid(self):
280
+ """
281
+ Snap to grid mode
282
+ :return: bool
283
+ """
284
+ return self._snap_to_grid
285
+
286
+ @snap_to_grid.setter
287
+ def snap_to_grid(self, snap_to_grid):
288
+ """
289
+ Setter for snap to grid mode
290
+ """
291
+ self._snap_to_grid = snap_to_grid
292
+
293
+ @property
294
+ def show_grid(self):
295
+ """
296
+ Show grid mode
297
+ :return: bool
298
+ """
299
+ return self._show_grid
300
+
301
+ @show_grid.setter
302
+ def show_grid(self, show_grid):
303
+ """
304
+ Setter for showing the grid mode
305
+ """
306
+ self._show_grid = show_grid
307
+
308
+ @property
309
+ def grid_size(self):
310
+ """
311
+ Grid size
312
+ :return: integer
313
+ """
314
+ return self._grid_size
315
+
316
+ @grid_size.setter
317
+ def grid_size(self, grid_size):
318
+ """
319
+ Setter for grid size
320
+ """
321
+ self._grid_size = grid_size
322
+
323
+ @property
324
+ def drawing_grid_size(self):
325
+ """
326
+ Grid size
327
+ :return: integer
328
+ """
329
+ return self._drawing_grid_size
330
+
331
+ @drawing_grid_size.setter
332
+ def drawing_grid_size(self, grid_size):
333
+ """
334
+ Setter for grid size
335
+ """
336
+ self._drawing_grid_size = grid_size
337
+
338
+ @property
339
+ def show_interface_labels(self):
340
+ """
341
+ Show interface labels mode
342
+ :return: bool
343
+ """
344
+ return self._show_interface_labels
345
+
346
+ @show_interface_labels.setter
347
+ def show_interface_labels(self, show_interface_labels):
348
+ """
349
+ Setter for show interface labels
350
+ """
351
+ self._show_interface_labels = show_interface_labels
352
+
353
+ @property
354
+ def variables(self):
355
+ """
356
+ Variables applied to the project
357
+ :return: list
358
+ """
359
+ return self._variables
360
+
361
+ @variables.setter
362
+ def variables(self, variables):
363
+ """
364
+ Setter for variables applied to the project
365
+ """
366
+ self._variables = variables
367
+
368
+ @property
369
+ def supplier(self):
370
+ """
371
+ Supplier of the project
372
+ :return: dict
373
+ """
374
+ return self._supplier
375
+
376
+ @supplier.setter
377
+ def supplier(self, supplier):
378
+ """
379
+ Setter for supplier of the project
380
+ """
381
+ self._supplier = supplier
382
+
383
+ @property
384
+ def auto_start(self):
385
+ """
386
+ Should project auto start when opened
387
+ """
388
+ return self._auto_start
389
+
390
+ @auto_start.setter
391
+ def auto_start(self, val):
392
+ self._auto_start = val
393
+
394
+ @property
395
+ def auto_close(self):
396
+ """
397
+ Should project automatically closed when client
398
+ stop listening for notification
399
+ """
400
+ return self._auto_close
401
+
402
+ @auto_close.setter
403
+ def auto_close(self, val):
404
+ self._auto_close = val
405
+
406
+ @property
407
+ def auto_open(self):
408
+ return self._auto_open
409
+
410
+ @auto_open.setter
411
+ def auto_open(self, val):
412
+ self._auto_open = val
413
+
414
+ @property
415
+ def controller(self):
416
+ return self._controller
417
+
418
+ @property
419
+ def name(self):
420
+ return self._name
421
+
422
+ @name.setter
423
+ def name(self, val):
424
+ self._name = val
425
+
426
+ @property
427
+ def id(self):
428
+ return self._id
429
+
430
+ @property
431
+ def path(self):
432
+ return self._path
433
+
434
+ @property
435
+ def status(self):
436
+ return self._status
437
+
438
+ @path.setter
439
+ def path(self, path):
440
+ check_path_allowed(path)
441
+ try:
442
+ os.makedirs(path, exist_ok=True)
443
+ except OSError as e:
444
+ raise ControllerError(f"Could not create project directory: {e}")
445
+
446
+ if '"' in path:
447
+ raise ControllerForbiddenError(
448
+ 'You are not allowed to use " in the project directory path. Not supported by Dynamips.'
449
+ )
450
+
451
+ self._path = path
452
+
453
+ @property
454
+ def captures_directory(self):
455
+ """
456
+ Location of the captures files
457
+ """
458
+ path = os.path.join(self._path, "project-files", "captures")
459
+ os.makedirs(path, exist_ok=True)
460
+ return path
461
+
462
+ @property
463
+ def pictures_directory(self):
464
+ """
465
+ Location of the images files
466
+ """
467
+ path = os.path.join(self._path, "project-files", "images")
468
+ os.makedirs(path, exist_ok=True)
469
+ return path
470
+
471
+ @property
472
+ def computes(self):
473
+ """
474
+ :return: List of computes used by the project
475
+ """
476
+
477
+ if self._status == "closed":
478
+ return self._get_closed_data("computes", "compute_id").values()
479
+ return self._project_created_on_compute
480
+
481
+ def remove_allocated_node_name(self, name):
482
+ """
483
+ Removes an allocated node name
484
+
485
+ :param name: allocated node name
486
+ """
487
+
488
+ if name in self._allocated_node_names:
489
+ self._allocated_node_names.remove(name)
490
+
491
+ def update_allocated_node_name(self, base_name):
492
+ """
493
+ Updates a node name or generate a new if no node
494
+ name is available.
495
+
496
+ :param base_name: new node base name
497
+ """
498
+
499
+ if base_name is None:
500
+ return None
501
+ base_name = re.sub(r"[ ]", "", base_name) # remove spaces in node name
502
+ if base_name in self._allocated_node_names:
503
+ base_name = re.sub(r"[0-9]+$", "{0}", base_name)
504
+
505
+ if "{0}" in base_name or "{id}" in base_name:
506
+ # base name is a template, replace {0} or {id} by an unique identifier
507
+ for number in range(1, 1000000):
508
+ try:
509
+ name = base_name.format(number, id=number, name="Node")
510
+ except KeyError as e:
511
+ raise ControllerError("{" + e.args[0] + "} is not a valid replacement string in the node name")
512
+ except (ValueError, IndexError) as e:
513
+ raise ControllerError(f"{base_name} is not a valid replacement string in the node name")
514
+ if name not in self._allocated_node_names:
515
+ self._allocated_node_names.add(name)
516
+ return name
517
+ else:
518
+ if base_name not in self._allocated_node_names:
519
+ self._allocated_node_names.add(base_name)
520
+ return base_name
521
+ # base name is not unique, let's find a unique name by appending a number
522
+ for number in range(1, 1000000):
523
+ name = base_name + str(number)
524
+ if name not in self._allocated_node_names:
525
+ self._allocated_node_names.add(name)
526
+ return name
527
+ raise ControllerError("A node name could not be allocated (node limit reached?)")
528
+
529
+ def update_node_name(self, node, new_name):
530
+
531
+ if new_name and node.name != new_name:
532
+ self.remove_allocated_node_name(node.name)
533
+ return self.update_allocated_node_name(new_name)
534
+ return new_name
535
+
536
+ @open_required
537
+ async def add_node_from_template(self, template, x=0, y=0, name=None, compute_id=None):
538
+ """
539
+ Create a node from a template.
540
+ """
541
+
542
+ template["x"] = x
543
+ template["y"] = y
544
+ node_type = template.pop("template_type")
545
+
546
+ if compute_id:
547
+ # use a custom compute_id
548
+ compute = self.controller.get_compute(compute_id)
549
+ else:
550
+ compute = self.controller.get_compute(template.pop("compute_id"))
551
+ template_name = template.pop("name")
552
+ log.info(f'Creating node from template "{template_name}" on compute "{compute.name}" [{compute.id}]')
553
+ default_name_format = template.pop("default_name_format", "{name}-{0}")
554
+ if name is None:
555
+ name = default_name_format.replace("{name}", template_name)
556
+ node_id = str(uuid.uuid4())
557
+ node = await self.add_node(compute, name, node_id, node_type=node_type, **template)
558
+ return node
559
+
560
+ async def _create_node(self, compute, name, node_id, node_type=None, **kwargs):
561
+
562
+ node = Node(self, compute, name, node_id=node_id, node_type=node_type, **kwargs)
563
+ if compute not in self._project_created_on_compute:
564
+ # For a local server we send the project path
565
+ if compute.id == "local":
566
+ data = {"name": self._name, "project_id": self._id, "path": self._path}
567
+ else:
568
+ data = {"name": self._name, "project_id": self._id}
569
+
570
+ if self._variables:
571
+ data["variables"] = self._variables
572
+
573
+ await compute.post("/projects", data=data)
574
+ self._project_created_on_compute.add(compute)
575
+
576
+ await node.create()
577
+ self._nodes[node.id] = node
578
+
579
+ return node
580
+
581
+ @open_required
582
+ async def add_node(self, compute, name, node_id, dump=True, node_type=None, **kwargs):
583
+ """
584
+ Create a node or return an existing node
585
+
586
+ :param dump: Dump topology to disk
587
+ :param kwargs: See the documentation of node
588
+ """
589
+
590
+ if node_id in self._nodes:
591
+ return self._nodes[node_id]
592
+
593
+ if compute.id not in self._computes:
594
+ self._computes.append(compute.id)
595
+
596
+ if node_type == "iou":
597
+ async with self._iou_id_lock:
598
+ # wait for an IOU node to be completely created before adding a new one
599
+ # this is important otherwise we allocate the same application ID (used
600
+ # to generate MAC addresses) when creating multiple IOU node at the same time
601
+ if "properties" in kwargs.keys():
602
+ # allocate a new application id for nodes loaded from the project
603
+ kwargs.get("properties")["application_id"] = get_next_application_id(
604
+ self._controller.projects, self._computes
605
+ )
606
+ elif "application_id" not in kwargs.keys() and not kwargs.get("properties"):
607
+ # allocate a new application id for nodes added to the project
608
+ kwargs["application_id"] = get_next_application_id(self._controller.projects, self._computes)
609
+ node = await self._create_node(compute, name, node_id, node_type, **kwargs)
610
+ else:
611
+ node = await self._create_node(compute, name, node_id, node_type, **kwargs)
612
+ self.emit_notification("node.created", node.asdict())
613
+ if dump:
614
+ self.dump()
615
+ return node
616
+
617
+ @locking
618
+ async def __delete_node_links(self, node):
619
+ """
620
+ Delete all link connected to this node.
621
+
622
+ The operation use a lock to avoid cleaning links from
623
+ multiple nodes at the same time.
624
+ """
625
+ for link in list(self._links.values()):
626
+ if node in link.nodes:
627
+ await self.delete_link(link.id, force_delete=True)
628
+
629
+ @open_required
630
+ async def delete_node(self, node_id):
631
+ node = self.get_node(node_id)
632
+ if node.locked:
633
+ raise ControllerError(f"Node {node.name} cannot be deleted because it is locked")
634
+ await self.__delete_node_links(node)
635
+ self.remove_allocated_node_name(node.name)
636
+ del self._nodes[node.id]
637
+ await node.destroy()
638
+ # refresh the compute IDs list
639
+ self._computes = [n.compute.id for n in self.nodes.values()]
640
+ self.dump()
641
+ self.emit_notification("node.deleted", node.asdict())
642
+
643
+ @open_required
644
+ def get_node(self, node_id):
645
+ """
646
+ Return the node or raise a 404 if the node is unknown
647
+ """
648
+ try:
649
+ return self._nodes[node_id]
650
+ except KeyError:
651
+ raise ControllerNotFoundError(f"Node ID {node_id} doesn't exist")
652
+
653
+ def _get_closed_data(self, section, id_key):
654
+ """
655
+ Get the data for a project from the .gns3 when
656
+ the project is closed
657
+
658
+ :param section: The section name in the .gns3
659
+ :param id_key: The key for the element unique id
660
+ """
661
+
662
+ try:
663
+ path = self._topology_file()
664
+ with open(path) as f:
665
+ topology = json.load(f)
666
+ except OSError as e:
667
+ raise ControllerError(f"Could not load topology: {e}")
668
+
669
+ try:
670
+ data = {}
671
+ for elem in topology["topology"][section]:
672
+ data[elem[id_key]] = elem
673
+ return data
674
+ except KeyError:
675
+ raise ControllerNotFoundError(f"Section {section} not found in the topology")
676
+
677
+ @property
678
+ def nodes(self):
679
+ """
680
+ :returns: Dictionary of the nodes
681
+ """
682
+ if self._status == "closed":
683
+ return self._get_closed_data("nodes", "node_id")
684
+ return self._nodes
685
+
686
+ @property
687
+ def drawings(self):
688
+ """
689
+ :returns: Dictionary of the drawings
690
+ """
691
+ if self._status == "closed":
692
+ return self._get_closed_data("drawings", "drawing_id")
693
+ return self._drawings
694
+
695
+ @open_required
696
+ async def add_drawing(self, drawing_id=None, dump=True, **kwargs):
697
+ """
698
+ Create an drawing or return an existing drawing
699
+
700
+ :param dump: Dump the topology to disk
701
+ :param kwargs: See the documentation of drawing
702
+ """
703
+ if drawing_id not in self._drawings:
704
+ drawing = Drawing(self, drawing_id=drawing_id, **kwargs)
705
+ self._drawings[drawing.id] = drawing
706
+ self.emit_notification("drawing.created", drawing.asdict())
707
+ if dump:
708
+ self.dump()
709
+ return drawing
710
+ return self._drawings[drawing_id]
711
+
712
+ @open_required
713
+ def get_drawing(self, drawing_id):
714
+ """
715
+ Return the Drawing or raise a 404 if the drawing is unknown
716
+ """
717
+ try:
718
+ return self._drawings[drawing_id]
719
+ except KeyError:
720
+ raise ControllerNotFoundError(f"Drawing ID {drawing_id} doesn't exist")
721
+
722
+ @open_required
723
+ async def delete_drawing(self, drawing_id):
724
+ drawing = self.get_drawing(drawing_id)
725
+ if drawing.locked:
726
+ raise ControllerError(f"Drawing ID {drawing_id} cannot be deleted because it is locked")
727
+ del self._drawings[drawing.id]
728
+ self.dump()
729
+ self.emit_notification("drawing.deleted", drawing.asdict())
730
+
731
+ @open_required
732
+ async def add_link(self, link_id=None, dump=True):
733
+ """
734
+ Create a link. By default the link is empty
735
+
736
+ :param dump: Dump topology to disk
737
+ """
738
+ if link_id and link_id in self._links:
739
+ return self._links[link_id]
740
+ link = UDPLink(self, link_id=link_id)
741
+ self._links[link.id] = link
742
+ if dump:
743
+ self.dump()
744
+ return link
745
+
746
+ @open_required
747
+ async def delete_link(self, link_id, force_delete=False):
748
+ link = self.get_link(link_id)
749
+ del self._links[link.id]
750
+ try:
751
+ await link.delete()
752
+ except Exception:
753
+ if force_delete is False:
754
+ raise
755
+ self.dump()
756
+ self.emit_notification("link.deleted", link.asdict())
757
+
758
+ @open_required
759
+ def get_link(self, link_id):
760
+ """
761
+ Return the Link or raise a 404 if the link is unknown
762
+ """
763
+ try:
764
+ return self._links[link_id]
765
+ except KeyError:
766
+ raise ControllerNotFoundError(f"Link ID {link_id} doesn't exist")
767
+
768
+ @property
769
+ def links(self):
770
+ """
771
+ :returns: Dictionary of the Links
772
+ """
773
+ if self._status == "closed":
774
+ return self._get_closed_data("links", "link_id")
775
+ return self._links
776
+
777
+ @property
778
+ def snapshots(self):
779
+ """
780
+ :returns: Dictionary of snapshots
781
+ """
782
+ return self._snapshots
783
+
784
+ @open_required
785
+ def get_snapshot(self, snapshot_id):
786
+ """
787
+ Return the snapshot or raise a 404 if the snapshot is unknown
788
+ """
789
+ try:
790
+ return self._snapshots[snapshot_id]
791
+ except KeyError:
792
+ raise ControllerNotFoundError(f"Snapshot ID {snapshot_id} doesn't exist")
793
+
794
+ @open_required
795
+ async def snapshot(self, name):
796
+ """
797
+ Snapshot the project
798
+
799
+ :param name: Name of the snapshot
800
+ """
801
+
802
+ if name in [snap.name for snap in self._snapshots.values()]:
803
+ raise ControllerError(f"The snapshot name {name} already exists")
804
+ snapshot = Snapshot(self, name=name)
805
+ await snapshot.create()
806
+ self._snapshots[snapshot.id] = snapshot
807
+ return snapshot
808
+
809
+ @open_required
810
+ async def delete_snapshot(self, snapshot_id):
811
+ snapshot = self.get_snapshot(snapshot_id)
812
+ del self._snapshots[snapshot.id]
813
+ os.remove(snapshot.path)
814
+
815
+ @locking
816
+ async def close(self, ignore_notification=False):
817
+ if self._status == "closed" or self._closing:
818
+ return
819
+ if self._loading:
820
+ log.warning(f"Closing project '{self.name}' ignored because it is being loaded")
821
+ return
822
+ self._closing = True
823
+ await self.stop_all()
824
+ for compute in list(self._project_created_on_compute):
825
+ try:
826
+ await compute.post(f"/projects/{self._id}/close", dont_connect=True)
827
+ # We don't care if a compute is down at this step
828
+ except (ComputeError, ControllerError, TimeoutError):
829
+ pass
830
+ self._clean_pictures()
831
+ self._status = "closed"
832
+ if not ignore_notification:
833
+ self.emit_controller_notification("project.closed", self.asdict())
834
+
835
+ self.reset()
836
+ self._closing = False
837
+
838
+ def _clean_pictures(self):
839
+ """
840
+ Delete unused pictures.
841
+ """
842
+
843
+ # Project have been deleted or is loading or is not opened
844
+ if not os.path.exists(self.path) or self._loading or self._status != "opened":
845
+ return
846
+ try:
847
+ pictures = set(os.listdir(self.pictures_directory))
848
+ for drawing in self._drawings.values():
849
+ try:
850
+ resource_filename = drawing.resource_filename
851
+ if resource_filename:
852
+ pictures.remove(resource_filename)
853
+ except KeyError:
854
+ pass
855
+
856
+ # don't remove supplier's logo
857
+ if self.supplier:
858
+ try:
859
+ logo = self.supplier["logo"]
860
+ pictures.remove(logo)
861
+ except KeyError:
862
+ pass
863
+
864
+ for pic_filename in pictures:
865
+ path = os.path.join(self.pictures_directory, pic_filename)
866
+ log.info(f"Deleting unused picture '{path}'")
867
+ os.remove(path)
868
+ except OSError as e:
869
+ log.warning(f"Could not delete unused pictures: {e}")
870
+
871
+ async def delete(self):
872
+
873
+ if self._status != "opened":
874
+ try:
875
+ await self.open()
876
+ except ControllerError as e:
877
+ # ignore missing images or other conflicts when deleting a project
878
+ log.warning(f"Conflict while deleting project: {e}")
879
+ await self.delete_on_computes()
880
+ await self.close()
881
+ try:
882
+ project_directory = get_default_project_directory()
883
+ if not os.path.commonprefix([project_directory, self.path]) == project_directory:
884
+ raise ControllerError(
885
+ f"Project '{self._name}' cannot be deleted because it is not in the default project directory: '{project_directory}'"
886
+ )
887
+ shutil.rmtree(self.path)
888
+ except OSError as e:
889
+ raise ControllerError(f"Cannot delete project directory {self.path}: {str(e)}")
890
+ self.emit_controller_notification("project.deleted", self.asdict())
891
+
892
+ async def delete_on_computes(self):
893
+ """
894
+ Delete the project on computes but not on controller
895
+ """
896
+ for compute in list(self._project_created_on_compute):
897
+ if compute.id != "local":
898
+ await compute.delete(f"/projects/{self._id}")
899
+ self._project_created_on_compute.remove(compute)
900
+
901
+ @classmethod
902
+ def _get_default_project_directory(cls):
903
+ """
904
+ Return the default location for the project directory
905
+ depending of the operating system
906
+ """
907
+
908
+ server_config = Config.instance().settings.Server
909
+ path = os.path.expanduser(server_config.projects_path)
910
+ path = os.path.normpath(path)
911
+ try:
912
+ os.makedirs(path, exist_ok=True)
913
+ except OSError as e:
914
+ raise ControllerError(f"Could not create project directory: {e}")
915
+ return path
916
+
917
+ def _topology_file(self):
918
+ return os.path.join(self.path, self._filename)
919
+
920
+ @locking
921
+ async def open(self):
922
+ """
923
+ Load topology elements
924
+ """
925
+
926
+ if self._closing is True:
927
+ raise ControllerError("Project is closing, please try again in a few seconds...")
928
+
929
+ if self._status == "opened":
930
+ return
931
+
932
+ self.reset()
933
+ self._loading = True
934
+ self._status = "opened"
935
+
936
+ path = self._topology_file()
937
+ if not os.path.exists(path):
938
+ self._loading = False
939
+ return
940
+ try:
941
+ shutil.copy(path, path + ".backup")
942
+ except OSError:
943
+ pass
944
+ try:
945
+ project_data = load_topology(path)
946
+
947
+ # load meta of project
948
+ keys_to_load = [
949
+ "auto_start",
950
+ "auto_close",
951
+ "auto_open",
952
+ "scene_height",
953
+ "scene_width",
954
+ "zoom",
955
+ "show_layers",
956
+ "snap_to_grid",
957
+ "show_grid",
958
+ "grid_size",
959
+ "drawing_grid_size",
960
+ "show_interface_labels",
961
+ ]
962
+
963
+ for key in keys_to_load:
964
+ val = project_data.get(key, None)
965
+ if val is not None:
966
+ setattr(self, key, val)
967
+
968
+ topology = project_data["topology"]
969
+ for compute in topology.get("computes", []):
970
+ await self.controller.add_compute(**compute)
971
+
972
+ # Get all compute used in the project
973
+ # used to allocate application IDs for IOU nodes.
974
+ for node in topology.get("nodes", []):
975
+ compute_id = node.get("compute_id")
976
+ if compute_id not in self._computes:
977
+ self._computes.append(compute_id)
978
+
979
+ for node in topology.get("nodes", []):
980
+ compute = self.controller.get_compute(node.pop("compute_id"))
981
+ name = node.pop("name")
982
+ node_id = node.pop("node_id", str(uuid.uuid4()))
983
+ await self.add_node(compute, name, node_id, dump=False, **node)
984
+ for link_data in topology.get("links", []):
985
+ if "link_id" not in link_data.keys():
986
+ # skip the link
987
+ continue
988
+ link = await self.add_link(link_id=link_data["link_id"])
989
+ if "filters" in link_data:
990
+ await link.update_filters(link_data["filters"])
991
+ if "link_style" in link_data:
992
+ await link.update_link_style(link_data["link_style"])
993
+ for node_link in link_data.get("nodes", []):
994
+ node = self.get_node(node_link["node_id"])
995
+ port = node.get_port(node_link["adapter_number"], node_link["port_number"])
996
+ if port is None:
997
+ log.warning(
998
+ "Port {}/{} for {} not found".format(
999
+ node_link["adapter_number"], node_link["port_number"], node.name
1000
+ )
1001
+ )
1002
+ continue
1003
+ if port.link is not None:
1004
+ log.warning(
1005
+ "Port {}/{} is already connected to link ID {}".format(
1006
+ node_link["adapter_number"], node_link["port_number"], port.link.id
1007
+ )
1008
+ )
1009
+ continue
1010
+ await link.add_node(
1011
+ node,
1012
+ node_link["adapter_number"],
1013
+ node_link["port_number"],
1014
+ label=node_link.get("label"),
1015
+ dump=False,
1016
+ )
1017
+ if len(link.nodes) != 2:
1018
+ # a link should have 2 attached nodes, this can happen with corrupted projects
1019
+ await self.delete_link(link.id, force_delete=True)
1020
+ for drawing_data in topology.get("drawings", []):
1021
+ await self.add_drawing(dump=False, **drawing_data)
1022
+
1023
+ self.dump()
1024
+ # We catch all error to be able to roll back the .gns3 to the previous state
1025
+ except Exception as e:
1026
+ for compute in list(self._project_created_on_compute):
1027
+ try:
1028
+ await compute.post(f"/projects/{self._id}/close")
1029
+ # We don't care if a compute is down at this step
1030
+ except ComputeError:
1031
+ pass
1032
+ try:
1033
+ if os.path.exists(path + ".backup"):
1034
+ shutil.copy(path + ".backup", path)
1035
+ except OSError:
1036
+ pass
1037
+ self._status = "closed"
1038
+ self._loading = False
1039
+ if isinstance(e, ComputeError):
1040
+ raise ControllerError(str(e))
1041
+ else:
1042
+ raise e
1043
+ try:
1044
+ os.remove(path + ".backup")
1045
+ except OSError:
1046
+ pass
1047
+
1048
+ self._loading = False
1049
+ self.emit_controller_notification("project.opened", self.asdict())
1050
+ # Should we start the nodes when project is open
1051
+ if self._auto_start:
1052
+ # Start all in the background without waiting for completion
1053
+ # we ignore errors because we want to let the user open
1054
+ # their project and fix it
1055
+ asyncio.ensure_future(self.start_all())
1056
+
1057
+ async def wait_loaded(self):
1058
+ """
1059
+ Wait until the project finish loading
1060
+ """
1061
+ while self._loading:
1062
+ await asyncio.sleep(0.5)
1063
+
1064
+ async def duplicate(self, name=None, reset_mac_addresses=True):
1065
+ """
1066
+ Duplicate a project
1067
+
1068
+ Implemented on top of the export / import features. It will generate a gns3p and reimport it.
1069
+
1070
+ NEW: fast duplication is used if possible (when there are no remote computes).
1071
+ If not, the project is exported and reimported as explained above.
1072
+
1073
+ :param name: Name of the new project. A new one will be generated in case of conflicts
1074
+ :param reset_mac_addresses: Reset MAC addresses for the new project
1075
+ """
1076
+
1077
+ # If the project was not open we open it temporary
1078
+ previous_status = self._status
1079
+ if self._status == "closed":
1080
+ await self.open()
1081
+
1082
+ self.dump()
1083
+ assert self._status != "closed"
1084
+
1085
+ try:
1086
+ proj = await self._fast_duplication(name, reset_mac_addresses)
1087
+ if proj:
1088
+ if previous_status == "closed":
1089
+ await self.close()
1090
+ return proj
1091
+ else:
1092
+ log.info("Fast duplication failed, fallback to normal duplication")
1093
+ except Exception as e:
1094
+ raise ControllerError(f"Cannot duplicate project: {str(e)}")
1095
+
1096
+ try:
1097
+ begin = time.time()
1098
+
1099
+ # use the parent directory of the project we are duplicating as a
1100
+ # temporary directory to avoid no space left issues when '/tmp'
1101
+ # is located on another partition.
1102
+ working_dir = os.path.abspath(os.path.join(self.path, os.pardir))
1103
+
1104
+ with tempfile.TemporaryDirectory(dir=working_dir) as tmpdir:
1105
+ # Do not compress the exported project when duplicating
1106
+ with aiozipstream.ZipFile(compression=zipfile.ZIP_STORED) as zstream:
1107
+ await export_project(
1108
+ zstream,
1109
+ self,
1110
+ tmpdir,
1111
+ keep_compute_ids=True,
1112
+ allow_all_nodes=True,
1113
+ reset_mac_addresses=reset_mac_addresses,
1114
+ )
1115
+
1116
+ # export the project to a temporary location
1117
+ project_path = os.path.join(tmpdir, "project.gns3p")
1118
+ log.info(f"Exporting project to '{project_path}'")
1119
+ async with aiofiles.open(project_path, "wb") as f:
1120
+ async for chunk in zstream:
1121
+ await f.write(chunk)
1122
+
1123
+ # import the temporary project
1124
+ with open(project_path, "rb") as f:
1125
+ project = await import_project(
1126
+ self._controller,
1127
+ str(uuid.uuid4()),
1128
+ f,
1129
+ name=name,
1130
+ keep_compute_ids=True
1131
+ )
1132
+
1133
+ log.info(f"Project '{project.name}' duplicated in {time.time() - begin:.4f} seconds")
1134
+ except (ValueError, OSError, UnicodeEncodeError) as e:
1135
+ raise ControllerError(f"Cannot duplicate project: {str(e)}")
1136
+
1137
+ if previous_status == "closed":
1138
+ await self.close()
1139
+
1140
+ return project
1141
+
1142
+ def is_running(self):
1143
+ """
1144
+ If a node is started or paused return True
1145
+ """
1146
+ for node in self._nodes.values():
1147
+ # Some node type are always running we ignore them
1148
+ if node.status != "stopped" and not node.is_always_running():
1149
+ return True
1150
+ return False
1151
+
1152
+ @open_required
1153
+ def lock(self):
1154
+ """
1155
+ Lock all drawings and nodes
1156
+ """
1157
+
1158
+ for drawing in self._drawings.values():
1159
+ if not drawing.locked:
1160
+ drawing.locked = True
1161
+ self.emit_notification("drawing.updated", drawing.asdict())
1162
+ for node in self.nodes.values():
1163
+ if not node.locked:
1164
+ node.locked = True
1165
+ self.emit_notification("node.updated", node.asdict())
1166
+ self.dump()
1167
+
1168
+ @open_required
1169
+ def unlock(self):
1170
+ """
1171
+ Unlock all drawings and nodes
1172
+ """
1173
+
1174
+ for drawing in self._drawings.values():
1175
+ if drawing.locked:
1176
+ drawing.locked = False
1177
+ self.emit_notification("drawing.updated", drawing.asdict())
1178
+ for node in self.nodes.values():
1179
+ if node.locked:
1180
+ node.locked = False
1181
+ self.emit_notification("node.updated", node.asdict())
1182
+ self.dump()
1183
+
1184
+ @property
1185
+ @open_required
1186
+ def locked(self):
1187
+ """
1188
+ Check if all items in a project are locked and not
1189
+ """
1190
+
1191
+ for drawing in self._drawings.values():
1192
+ if not drawing.locked:
1193
+ return False
1194
+ for node in self.nodes.values():
1195
+ if not node.locked:
1196
+ return False
1197
+ return True
1198
+
1199
+ def dump(self):
1200
+ """
1201
+ Dump topology to disk
1202
+ """
1203
+ try:
1204
+ topo = project_to_topology(self)
1205
+ path = self._topology_file()
1206
+ log.debug(f"Write topology file '{path}'")
1207
+ with open(path + ".tmp", "w+", encoding="utf-8") as f:
1208
+ json.dump(topo, f, indent=4, sort_keys=True)
1209
+ shutil.move(path + ".tmp", path)
1210
+ except OSError as e:
1211
+ raise ControllerError(f"Could not write topology: {e}")
1212
+
1213
+ @open_required
1214
+ async def start_all(self):
1215
+ """
1216
+ Start all nodes
1217
+ """
1218
+ pool = Pool(concurrency=3)
1219
+ for node in self.nodes.values():
1220
+ pool.append(node.start)
1221
+ await pool.join()
1222
+
1223
+ @open_required
1224
+ async def stop_all(self):
1225
+ """
1226
+ Stop all nodes
1227
+ """
1228
+ pool = Pool(concurrency=3)
1229
+ for node in self.nodes.values():
1230
+ pool.append(node.stop)
1231
+ await pool.join()
1232
+
1233
+ @open_required
1234
+ async def suspend_all(self):
1235
+ """
1236
+ Suspend all nodes
1237
+ """
1238
+ pool = Pool(concurrency=3)
1239
+ for node in self.nodes.values():
1240
+ pool.append(node.suspend)
1241
+ await pool.join()
1242
+
1243
+ @open_required
1244
+ async def reset_console_all(self):
1245
+ """
1246
+ Reset console for all nodes
1247
+ """
1248
+
1249
+ pool = Pool(concurrency=3)
1250
+ for node in self.nodes.values():
1251
+ pool.append(node.reset_console)
1252
+ await pool.join()
1253
+
1254
+ @open_required
1255
+ async def duplicate_node(self, node, x, y, z):
1256
+ """
1257
+ Duplicate a node
1258
+
1259
+ :param node: Node instance
1260
+ :param x: X position
1261
+ :param y: Y position
1262
+ :param z: Z position
1263
+ :returns: New node
1264
+ """
1265
+
1266
+ if node.status != "stopped" and not node.is_always_running():
1267
+ raise ControllerError("Cannot duplicate node data while the node is running")
1268
+
1269
+ data = copy.deepcopy(node.asdict(topology_dump=True))
1270
+ # Some properties like internal ID should not be duplicated
1271
+ for unique_property in (
1272
+ "node_id",
1273
+ "name",
1274
+ "mac_addr",
1275
+ "mac_address",
1276
+ "compute_id",
1277
+ "application_id",
1278
+ "dynamips_id",
1279
+ ):
1280
+ data.pop(unique_property, None)
1281
+ if "properties" in data:
1282
+ data["properties"].pop(unique_property, None)
1283
+ node_type = data.pop("node_type")
1284
+ data["x"] = x
1285
+ data["y"] = y
1286
+ data["z"] = z
1287
+ data["locked"] = False # duplicated node must not be locked
1288
+ new_node_uuid = str(uuid.uuid4())
1289
+ new_node = await self.add_node(node.compute, node.name, new_node_uuid, node_type=node_type, **data)
1290
+ try:
1291
+ await node.post("/duplicate", timeout=None, data={"destination_node_id": new_node_uuid})
1292
+ except ControllerNotFoundError:
1293
+ await self.delete_node(new_node_uuid)
1294
+ raise ControllerError("This node type cannot be duplicated")
1295
+ except ControllerError as e:
1296
+ await self.delete_node(new_node_uuid)
1297
+ raise e
1298
+ return new_node
1299
+
1300
+ def stats(self):
1301
+
1302
+ return {
1303
+ "nodes": len(self._nodes),
1304
+ "links": len(self._links),
1305
+ "drawings": len(self._drawings),
1306
+ "snapshots": len(self._snapshots),
1307
+ }
1308
+
1309
+ def asdict(self):
1310
+ return {
1311
+ "name": self._name,
1312
+ "project_id": self._id,
1313
+ "path": self._path,
1314
+ "filename": self._filename,
1315
+ "status": self._status,
1316
+ "auto_start": self._auto_start,
1317
+ "auto_close": self._auto_close,
1318
+ "auto_open": self._auto_open,
1319
+ "scene_height": self._scene_height,
1320
+ "scene_width": self._scene_width,
1321
+ "zoom": self._zoom,
1322
+ "show_layers": self._show_layers,
1323
+ "snap_to_grid": self._snap_to_grid,
1324
+ "show_grid": self._show_grid,
1325
+ "grid_size": self._grid_size,
1326
+ "drawing_grid_size": self._drawing_grid_size,
1327
+ "show_interface_labels": self._show_interface_labels,
1328
+ "supplier": self._supplier,
1329
+ "variables": self._variables,
1330
+ }
1331
+
1332
+ def __repr__(self):
1333
+ return f"<gns3server.controller.Project {self._name} {self._id}>"
1334
+
1335
+ async def _fast_duplication(self, name=None, reset_mac_addresses=True):
1336
+ """
1337
+ Fast duplication of a project.
1338
+
1339
+ Copy the project files directly rather than in an import-export fashion.
1340
+
1341
+ :param name: Name of the new project. A new one will be generated in case of conflicts
1342
+ :param reset_mac_addresses: Reset MAC addresses for the new project
1343
+ """
1344
+
1345
+ # remote replication is not supported with remote computes
1346
+ for compute in self.computes:
1347
+ if compute.id != "local":
1348
+ log.warning("Fast duplication is not supported with remote compute: '{}'".format(compute.id))
1349
+ return None
1350
+ # work dir
1351
+ p_work = pathlib.Path(self.path).parent.absolute()
1352
+ t0 = time.time()
1353
+ new_project_id = str(uuid.uuid4())
1354
+ new_project_path = p_work.joinpath(new_project_id)
1355
+ # copy dir
1356
+ await wait_run_in_executor(shutil.copytree, self.path, new_project_path.as_posix(), symlinks=True, ignore_dangling_symlinks=True)
1357
+ log.info("Project content copied from '{}' to '{}' in {}s".format(self.path, new_project_path, time.time() - t0))
1358
+ topology = json.loads(new_project_path.joinpath('{}.gns3'.format(self.name)).read_bytes())
1359
+ project_name = name or topology["name"]
1360
+ # If the project name is already used we generate a new one
1361
+ project_name = self.controller.get_free_project_name(project_name)
1362
+ topology["name"] = project_name
1363
+ # To avoid unexpected behavior (project start without manual operations just after import)
1364
+ topology["auto_start"] = False
1365
+ topology["auto_open"] = False
1366
+ topology["auto_close"] = False
1367
+ # change node ID
1368
+ node_old_to_new = {}
1369
+ for node in topology["topology"]["nodes"]:
1370
+ new_node_id = str(uuid.uuid4())
1371
+ if "node_id" in node:
1372
+ node_old_to_new[node["node_id"]] = new_node_id
1373
+ _move_node_file(new_project_path, node["node_id"], new_node_id)
1374
+ node["node_id"] = new_node_id
1375
+ if reset_mac_addresses:
1376
+ if "properties" in node:
1377
+ for prop, value in node["properties"].items():
1378
+ # reset the MAC address
1379
+ if prop in ("mac_addr", "mac_address"):
1380
+ node["properties"][prop] = None
1381
+ # change link ID
1382
+ for link in topology["topology"]["links"]:
1383
+ link["link_id"] = str(uuid.uuid4())
1384
+ for node in link["nodes"]:
1385
+ node["node_id"] = node_old_to_new[node["node_id"]]
1386
+ # Generate new drawings id
1387
+ for drawing in topology["topology"]["drawings"]:
1388
+ drawing["drawing_id"] = str(uuid.uuid4())
1389
+
1390
+ # And we dump the updated.gns3
1391
+ dot_gns3_path = new_project_path.joinpath('{}.gns3'.format(project_name))
1392
+ topology["project_id"] = new_project_id
1393
+ with open(dot_gns3_path, "w+") as f:
1394
+ json.dump(topology, f, indent=4)
1395
+
1396
+ os.remove(new_project_path.joinpath('{}.gns3'.format(self.name)))
1397
+ project = await self.controller.load_project(dot_gns3_path, load=False)
1398
+ log.info("Project '{}' fast duplicated in {:.4f} seconds".format(project.name, time.time() - t0))
1399
+ return project