mirror of
https://github.com/GNS3/gns3-server
synced 2024-12-29 02:08:10 +00:00
Tool to quickly add and remove VMware vmnet interfaces on Linux.
This commit is contained in:
parent
b118f9a078
commit
ebfe003885
4
setup.py
4
setup.py
@ -21,7 +21,7 @@ from setuptools.command.test import test as TestCommand
|
||||
|
||||
# we only support Python 3 version >= 3.4
|
||||
if sys.version_info < (3, 4):
|
||||
raise RuntimeError("Python 3.4 or higher is required")
|
||||
raise SystemExit("Python 3.4 or higher is required")
|
||||
|
||||
class PyTest(TestCommand):
|
||||
def finalize_options(self):
|
||||
@ -57,7 +57,7 @@ setup(
|
||||
entry_points={
|
||||
"console_scripts": [
|
||||
"gns3server = gns3server.main:main",
|
||||
"gns3dms = gns3dms.main:main",
|
||||
"gns3vmnet = utils.vmnet:main",
|
||||
]
|
||||
},
|
||||
packages=find_packages(".", exclude=["docs", "tests"]),
|
||||
|
1
utils/__init__.py
Normal file
1
utils/__init__.py
Normal file
@ -0,0 +1 @@
|
||||
__author__ = 'grossmj'
|
152
utils/vmnet.py
Normal file
152
utils/vmnet.py
Normal file
@ -0,0 +1,152 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Copyright (C) 2015 GNS3 Technologies Inc.
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import sys
|
||||
import os
|
||||
import ipaddress
|
||||
import argparse
|
||||
|
||||
from collections import OrderedDict
|
||||
|
||||
VMWARE_NETWORKING_FILE = "/etc/vmware/networking"
|
||||
DEFAULT_RANGE = [10, 100]
|
||||
|
||||
|
||||
def parse_networking_file():
|
||||
"""
|
||||
Parse the VMware networking file.
|
||||
"""
|
||||
|
||||
pairs = dict()
|
||||
allocated_subnets = []
|
||||
try:
|
||||
with open(VMWARE_NETWORKING_FILE, "r", encoding="utf-8") as f:
|
||||
version = f.readline()
|
||||
for line in f.read().splitlines():
|
||||
try:
|
||||
_, key, value = line.split(' ', 3)
|
||||
key = key.strip()
|
||||
value = value.strip()
|
||||
pairs[key] = value
|
||||
if key.endswith("HOSTONLY_SUBNET"):
|
||||
allocated_subnets.append(value)
|
||||
except ValueError:
|
||||
raise SystemExit("Error while parsing {}".format(VMWARE_NETWORKING_FILE))
|
||||
except OSError as e:
|
||||
raise SystemExit("Cannot open {}: {}".format(VMWARE_NETWORKING_FILE, e))
|
||||
return version, pairs, allocated_subnets
|
||||
|
||||
|
||||
def write_networking_file(version, pairs):
|
||||
"""
|
||||
Write the VMware networking file.
|
||||
"""
|
||||
|
||||
vmnets = OrderedDict(sorted(pairs.items(), key=lambda t: t[0]))
|
||||
try:
|
||||
with open(VMWARE_NETWORKING_FILE, "w", encoding="utf-8") as f:
|
||||
f.write(version)
|
||||
for key, value in vmnets.items():
|
||||
f.write("answer {} {}\n".format(key, value))
|
||||
except OSError as e:
|
||||
raise SystemExit("Cannot open {}: {}".format(VMWARE_NETWORKING_FILE, e))
|
||||
|
||||
# restart VMware networking service
|
||||
os.system("vmware-networks --stop")
|
||||
os.system("vmware-networks --start")
|
||||
|
||||
|
||||
def parse_vmnet_range(start, end):
|
||||
"""
|
||||
Parse the vmnet range on the command line.
|
||||
"""
|
||||
|
||||
class Range(argparse.Action):
|
||||
def __call__(self, parser, args, values, option_string=None):
|
||||
if len(values) != 2:
|
||||
raise argparse.ArgumentTypeError("vmnet range must consist of 2 numbers")
|
||||
if not start <= values[0] or not values[1] <= end:
|
||||
raise argparse.ArgumentTypeError("vmnet range must be between {} and {}".format(start, end))
|
||||
setattr(args, self.dest, values)
|
||||
return Range
|
||||
|
||||
|
||||
def main():
|
||||
"""
|
||||
Entry point for the VMNET tool.
|
||||
"""
|
||||
|
||||
if not sys.platform.startswith("linux"):
|
||||
raise SystemExit("This program can only be used on Linux")
|
||||
|
||||
parser = argparse.ArgumentParser(description='%(prog)s add/remove vmnet interfaces')
|
||||
parser.add_argument('-r', "--range", nargs='+', action=parse_vmnet_range(1, 255),
|
||||
type=int, help="vmnet range to add (default is {} {})".format(DEFAULT_RANGE[0], DEFAULT_RANGE[1]))
|
||||
parser.add_argument("-C", "--clean", action="store_true", help="remove all vmnets excepting vmnet1 and vmnet8")
|
||||
parser.add_argument("-l", "--list", action="store_true", help="list all existing vmnets")
|
||||
|
||||
try:
|
||||
args = parser.parse_args()
|
||||
except argparse.ArgumentTypeError as e:
|
||||
raise SystemExit(e)
|
||||
|
||||
vmnet_range = args.range if args.range is not None else DEFAULT_RANGE
|
||||
if not os.access(VMWARE_NETWORKING_FILE, os.W_OK):
|
||||
raise SystemExit("You must run this script as root")
|
||||
|
||||
version, pairs, allocated_subnets = parse_networking_file()
|
||||
|
||||
if args.list:
|
||||
for vmnet_number in range(1, 256):
|
||||
vmnet_name = "VNET_{}_VIRTUAL_ADAPTER".format(vmnet_number)
|
||||
if vmnet_name in pairs:
|
||||
print("vmnet{}".format(vmnet_number))
|
||||
return
|
||||
|
||||
if args.clean:
|
||||
# clean all vmnets but vmnet1 and vmnet8
|
||||
for key in pairs.copy().keys():
|
||||
if key.startswith("VNET_1_") or key.startswith("VNET_8_"):
|
||||
continue
|
||||
del pairs[key]
|
||||
else:
|
||||
for vmnet_number in range(vmnet_range[0], vmnet_range[1]):
|
||||
vmnet_name = "VNET_{}_VIRTUAL_ADAPTER".format(vmnet_number)
|
||||
if vmnet_name in pairs:
|
||||
continue
|
||||
allocated_subnet = None
|
||||
for subnet in ipaddress.ip_network("172.16.0.0/16").subnets(prefixlen_diff=8):
|
||||
subnet = str(subnet.network_address)
|
||||
if subnet not in allocated_subnets:
|
||||
allocated_subnet = subnet
|
||||
allocated_subnets.append(allocated_subnet)
|
||||
break
|
||||
|
||||
if allocated_subnet is None:
|
||||
print("Couldn't allocate a subnet for vmnet{}".format(vmnet_number))
|
||||
continue
|
||||
|
||||
print("Adding vmnet{}...".format(vmnet_number))
|
||||
pairs["VNET_{}_HOSTONLY_NETMASK".format(vmnet_number)] = "255.255.255.0"
|
||||
pairs["VNET_{}_HOSTONLY_SUBNET".format(vmnet_number)] = allocated_subnet
|
||||
pairs["VNET_{}_VIRTUAL_ADAPTER".format(vmnet_number)] = "yes"
|
||||
|
||||
write_networking_file(version, pairs)
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
Loading…
Reference in New Issue
Block a user