Commit 0263ea07 authored by Christos Stavrakakis's avatar Christos Stavrakakis
Browse files

cyclades: Refactor code relative to networks

Move code checks from network-create management command to
logic/networks.py.

Also create common decorator for management commands to convert api
faults to command errors.
parent 1267db9e
......@@ -34,14 +34,12 @@
from optparse import make_option
from django.core.management.base import BaseCommand, CommandError
from synnefo.management.common import validate_network_info, get_backend
from synnefo.webproject.management.utils import pprint_table, parse_bool
from synnefo.management.common import get_backend, convert_api_faults
from synnefo.webproject.management.utils import parse_bool
from synnefo import quotas
from synnefo.db.models import Network, Backend
from synnefo.db.utils import validate_mac, InvalidMacAddress
from synnefo.logic import networks
from synnefo.logic.backend import create_network
from synnefo.api.util import values_from_flavor
NETWORK_FLAVORS = Network.FLAVORS.keys()
......@@ -53,12 +51,6 @@ class Command(BaseCommand):
help = "Create a new network"
option_list = BaseCommand.option_list + (
make_option(
"-n",
"--dry-run",
dest="dry_run",
default=False,
action="store_true"),
make_option(
'--name',
dest='name',
......@@ -91,8 +83,9 @@ class Command(BaseCommand):
make_option(
'--dhcp',
dest='dhcp',
action='store_true',
default=False,
default="False",
choices=["True", "False"],
metavar="True|False",
help='Automatically assign IPs'),
make_option(
'--public',
......@@ -142,11 +135,11 @@ class Command(BaseCommand):
' public networks'),
)
@convert_api_faults
def handle(self, *args, **options):
if args:
raise CommandError("Command doesn't accept any arguments")
dry_run = options["dry_run"]
name = options['name']
subnet = options['subnet']
gateway = options['gateway']
......@@ -161,6 +154,7 @@ class Command(BaseCommand):
tags = options['tags']
userid = options["owner"]
floating_ip_pool = parse_bool(options["floating_ip_pool"])
dhcp = parse_bool(options["dhcp"])
if not name:
raise CommandError("name is required")
......@@ -179,54 +173,19 @@ class Command(BaseCommand):
if not userid and not public:
raise CommandError("'owner' is required for private networks")
if mac_prefix and flavor == "MAC_FILTERED":
raise CommandError("Can not override MAC_FILTERED mac-prefix")
if link and flavor == "PHYSICAL_VLAN":
raise CommandError("Can not override PHYSICAL_VLAN link")
if backend_id:
if backend_id is not None:
try:
backend_id = int(backend_id)
except ValueError:
raise CommandError("Invalid backend-id: %s", backend_id)
backend = get_backend(backend_id)
fmode, flink, fmac_prefix, ftags = values_from_flavor(flavor)
mode = mode or fmode
link = link or flink
mac_prefix = mac_prefix or fmac_prefix
tags = tags or ftags
try:
validate_mac(mac_prefix + "0:00:00:00")
except InvalidMacAddress:
raise CommandError("Invalid MAC prefix '%s'" % mac_prefix)
subnet, gateway, subnet6, gateway6 = validate_network_info(options)
if not link or not mode:
raise CommandError("Can not create network."
" No connectivity link or mode")
netinfo = {
"name": name,
"userid": options["owner"],
"subnet": subnet,
"gateway": gateway,
"gateway6": gateway6,
"subnet6": subnet6,
"dhcp": options["dhcp"],
"flavor": flavor,
"public": public,
"mode": mode,
"link": link,
"mac_prefix": mac_prefix,
"tags": tags,
"floating_ip_pool": floating_ip_pool,
"state": "ACTIVE"}
if dry_run:
self.stdout.write("Creating network:\n")
pprint_table(self.stdout, tuple(netinfo.items()))
return
network = Network.objects.create(**netinfo)
if userid:
quotas.issue_and_accept_commission(network)
network = networks.create(user_id=userid, name=name, flavor=flavor,
subnet=subnet, gateway=gateway,
subnet6=subnet6, gateway6=gateway6,
dhcp=dhcp, public=public, mode=mode,
link=link, mac_prefix=mac_prefix, tags=tags,
floating_ip_pool=floating_ip_pool)
# Create network in Backend if needed
if floating_ip_pool:
......
......@@ -70,6 +70,7 @@ class Command(BaseCommand):
help="Password for the new server")
)
@common.convert_api_faults
def handle(self, *args, **options):
if args:
raise CommandError("Command doesn't accept any arguments")
......
......@@ -62,23 +62,38 @@ def network_command(action):
@transaction.commit_on_success
def create(user_id, name, flavor, subnet, gateway=None, subnet6=None,
gateway6=None, public=False, dhcp=True):
def create(user_id, name, flavor, subnet=None, gateway=None, subnet6=None,
gateway6=None, public=False, dhcp=True, link=None, mac_prefix=None,
mode=None, floating_ip_pool=False, tags=None):
if flavor is None:
raise faults.BadRequest("Missing request parameter 'type'")
elif flavor not in Network.FLAVORS.keys():
raise faults.BadRequest("Invalid network type '%s'" % flavor)
if mac_prefix is not None and flavor == "MAC_FILTERED":
raise faults.BadRequest("Can not override MAC_FILTERED mac-prefix")
if link is not None and flavor == "PHYSICAL_VLAN":
raise faults.BadRequest("Can not override PHYSICAL_VLAN link")
if subnet is None and floating_ip_pool:
raise faults.BadRequest("IPv6 only networks can not be"
" pools.")
# Check that network parameters are valid
util.validate_network_params(subnet, gateway, subnet6, gateway6)
try:
mode, link, mac_prefix, tags = util.values_from_flavor(flavor)
fmode, flink, fmac_prefix, ftags = util.values_from_flavor(flavor)
except EmptyPool:
log.error("Failed to allocate resources for network of type: %s",
flavor)
msg = "Failed to allocate resources for network."
raise faults.ServiceUnavailable(msg)
mode = mode or fmode
link = link or flink
mac_prefix = mac_prefix or fmac_prefix
tags = tags or ftags
validate_mac(mac_prefix + "0:00:00:00")
network = Network.objects.create(
......@@ -94,6 +109,8 @@ def create(user_id, name, flavor, subnet, gateway=None, subnet6=None,
link=link,
mac_prefix=mac_prefix,
tags=tags,
public=public,
floating_ip_pool=floating_ip_pool,
action='CREATE',
state='ACTIVE')
......
......@@ -33,6 +33,7 @@
from django.core.management import CommandError
from synnefo.db.models import Backend, VirtualMachine, Network, Flavor
from functools import wraps
from snf_django.lib.api import faults
from synnefo.api import util
......@@ -167,5 +168,15 @@ def check_backend_credentials(clustername, port, username, password):
" Ganeti Cluster name: %s" % info_name)
def convert_api_faults(func):
@wraps(func)
def wrapper(*args, **kwargs):
try:
return func(*args, **kwargs)
except faults.Fault as e:
raise CommandError(e.message)
return wrapper
class Omit(object):
pass
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