Commit 005cecbd authored by Christos Stavrakakis's avatar Christos Stavrakakis
Browse files

Import snf-manage network-modify command

Add extra support for changing link and mac_prefix. Also support
reserving and releasing IPs.
parent 1ccb6901
......@@ -31,9 +31,14 @@
# interpreted as representing official policies, either expressed
# or implied, of GRNET S.A.
import ipaddr
from datetime import datetime
from django.utils.timesince import timesince, timeuntil
from django.core.management import CommandError
from synnefo.api.util import validate_network_size
from synnefo.settings import MAX_CIDR_BLOCK
def format_bool(b):
......@@ -55,3 +60,36 @@ def format_vm_state(vm):
return "BUILD(" + str(vm.buildpercentage) + "%)"
else:
return vm.operstate
def validate_network_info(options):
subnet = options['subnet']
gateway = options['gateway']
subnet6 = options['subnet6']
gateway6 = options['gateway6']
try:
net = ipaddr.IPv4Network(subnet)
prefix = net.prefixlen
if not validate_network_size(prefix):
raise CommandError("Unsupport network mask %d."
" Must be in range (%s,29] "
% (prefix, MAX_CIDR_BLOCK))
except ValueError:
raise CommandError('Malformed subnet')
try:
gateway and ipaddr.IPv4Address(gateway) or None
except ValueError:
raise CommandError('Malformed gateway')
try:
subnet6 and ipaddr.IPv6Network(subnet6) or None
except ValueError:
raise CommandError('Malformed subnet6')
try:
gateway6 and ipaddr.IPv6Address(gateway6) or None
except ValueError:
raise CommandError('Malformed gateway6')
return subnet, gateway, subnet6, gateway6
......@@ -36,11 +36,8 @@ from optparse import make_option
from django.core.management.base import BaseCommand, CommandError
from synnefo.db.models import Network, Backend
from synnefo.api.util import net_resources, validate_network_size
from synnefo.logic.backend import create_network
from synnefo import settings
import ipaddr
from _common import validate_network_info
NETWORK_TYPES = ['PUBLIC_ROUTED', 'PRIVATE_MAC_FILTERED',
'PRIVATE_PHYSICAL_VLAN', 'CUSTOM_ROUTED',
......@@ -176,36 +173,3 @@ class Command(BaseCommand):
# Create BackendNetwork entries for all Backends
network.create_backend_network()
create_network(network)
def validate_network_info(options):
subnet = options['subnet']
gateway = options['gateway']
subnet6 = options['subnet6']
gateway6 = options['gateway6']
try:
net = ipaddr.IPv4Network(subnet)
prefix = net.prefixlen
if not validate_network_size(prefix):
raise CommandError("Unsupport network mask %d."
" Must be in range (%s,29] "
% (prefix, settings.MAX_CIDR_BLOCK))
except ValueError:
raise CommandError('Malformed subnet')
try:
gateway and ipaddr.IPv4Address(gateway) or None
except ValueError:
raise CommandError('Malformed gateway')
try:
subnet6 and ipaddr.IPv6Network(subnet6) or None
except ValueError:
raise CommandError('Malformed subnet6')
try:
gateway6 and ipaddr.IPv6Address(gateway6) or None
except ValueError:
raise CommandError('Malformed gateway6')
return subnet, gateway, subnet6, gateway6
......@@ -35,22 +35,35 @@ from optparse import make_option
from django.core.management.base import BaseCommand, CommandError
from synnefo.db.models import Network
from synnefo.db.models import Network, pooled_rapi_client
from _common import validate_network_info
HELP_MSG = \
"""Modify a network.
This management command will only modify the state of the network in Cyclades
DB. The state of the network in the Ganeti backends will remain unchanged. You
should manually modify the network in all the backends, to synchronize the
state of DB and Ganeti.
The only exception is add_reserved_ips and remove_reserved_ips options, which
modify the IP pool in the Ganeti backends.
"""
class Command(BaseCommand):
args = "<network id>"
help = "Modify a network"
help = HELP_MSG
output_transaction = True
option_list = BaseCommand.option_list + (
make_option('--name',
dest='name',
metavar='NAME',
help="Set network's name"),
make_option('--owner',
dest='owner',
metavar='USER_ID',
help="Set network's owner"),
make_option('--userid',
dest='userid',
help="Set the userid of the network owner"),
make_option('--subnet',
dest='subnet',
help="Set network's subnet"),
......@@ -69,7 +82,20 @@ class Command(BaseCommand):
make_option('--state',
dest='state',
metavar='STATE',
help="Set network's state")
help="Set network's state"),
make_option('--link',
dest='link',
help="Set the connectivity link"),
make_option('--mac-prefix',
dest="mac_prefix",
help="Set the MAC prefix"),
make_option('--add-reserved-ips',
dest="add_reserved_ips",
help="Comma seperated list of IPs to externally reserve."),
make_option('--remove-reserved-ips',
dest="remove_reserved_ips",
help="Comma seperated list of IPs to externally release."),
)
def handle(self, *args, **options):
......@@ -79,43 +105,42 @@ class Command(BaseCommand):
try:
network_id = int(args[0])
network = Network.objects.get(id=network_id)
except ValueError:
raise CommandError("Invalid network ID")
except (ValueError, Network.DoesNotExist):
raise CommandError("Invalid network id")
name = options.get('name')
if name is not None:
network.name = name
owner = options.get('owner')
if owner is not None:
network.userid = owner
raise CommandError("Network not found in DB")
subnet = options.get('subnet')
if subnet is not None:
network.subnet = subnet
gateway = options.get('gateway')
if gateway is not None:
network.gateway = gateway
subnet6 = options.get('subnet6')
if subnet6 is not None:
network.subnet6 = subnet6
gateway6 = options.get('gateway6')
if gateway6 is not None:
network.gateway6 = gateway6
dhcp = options.get('dhcp')
if dhcp is not None:
network.dhcp = dhcp
# Validate subnet
if options.get('subnet'):
validate_network_info(options)
# Validate state
state = options.get('state')
if state is not None:
if state:
allowed = [x[0] for x in Network.OPER_STATES]
if state not in allowed:
msg = "Invalid state, must be one of %s" % ', '.join(allowed)
raise CommandError(msg)
network.state = state
fields = ('name', 'userid', 'subnet', 'gateway', 'subnet6', 'gateway6',
'dhcp', 'state', 'link', 'mac_prefix')
for field in fields:
value = options.get(field, None)
if value:
network.__setattr__(field, value)
add_reserved_ips = options.get('add_reserved_ips')
remove_reserved_ips = options.get('remove_reserved_ips')
if add_reserved_ips or remove_reserved_ips:
if add_reserved_ips:
add_reserved_ips = add_reserved_ips.split(",")
if remove_reserved_ips:
remove_reserved_ips = remove_reserved_ips.split(",")
for bnetwork in network.backend_networks.all():
with pooled_rapi_client(bnetwork.backend) as c:
c.ModifyNetwork(network=network.backend_id,
add_reserved_ips=add_reserved_ips,
remove_reserved_ips=remove_reserved_ips)
network.save()
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment