commit efabd2d425511a1a9a2bc6c3fa241d4d6ebd86b8
Author: Dionysis Grigoropoulos <dgrig@grnet.gr>
Date:   Mon Sep 30 15:45:58 2013 +0300

    cyclades: Neutron API add update_subnet, add tests
    
    Create update_subnet, some minor bugs need fixing
    Add tests for update_subnet and create_subnet
    Fix some bugs in subnets_views

diff --git a/snf-cyclades-app/synnefo/neutron/subnet_views.py b/snf-cyclades-app/synnefo/neutron/subnet_views.py
index 4bcf582..977b978 100644
--- a/snf-cyclades-app/synnefo/neutron/subnet_views.py
+++ b/snf-cyclades-app/synnefo/neutron/subnet_views.py
@@ -107,24 +107,25 @@ def create_subnet(request):
     if ipversion not in [4, 6]:
         raise api.faults.BadRequest("Malformed IP version type")
 
-    dhcp = subnet.get('enable_dhcp', True)
-    if dhcp not in [True, False]:
-        raise api.faults.BadRequest("Malformed request, enable_dhcp must be "
-                                    "True or False")
-    name = subnet.get('name', None)
-    if len(str(name)) > Subnet.SUBNET_NAME_LENGTH:
-        raise api.faults.BadRequest("Subnet name too long")
+    dhcp = check_dhcp_value(subnet.get('enable_dhcp', True))
+    name = check_name_length(subnet.get('name', None))
 
     # Returns the first available IP in the subnet
     if ipversion == 6:
-        potential_gateway = IPv6Network(cidr).network + 1
+        potential_gateway = str(IPv6Network(cidr).network + 1)
         check_number_of_subnets(network, 6)
     else:
-        potential_gateway = IPv4Network(cidr).network + 1
+        potential_gateway = str(IPv4Network(cidr).network + 1)
         check_number_of_subnets(network, 4)
 
     gateway = subnet.get('gateway_ip', potential_gateway)
-    networks.validate_network_params(cidr, gateway)
+
+    if ipversion == 6:
+        networks.validate_network_params(None, None, cidr, gateway)
+    else:
+        networks.validate_network_params(cidr, gateway)
+
+    check_for_hosts_dns(subnet)
 
     # FIX ME
     try:
@@ -134,7 +135,9 @@ def create_subnet(request):
     except:
         return "Error"
 
-    return HttpResponse(sub, status=200)
+    subnet_dict = subnet_to_dict(sub)
+    data = json.dumps({'subnet': subnet_dict})
+    return HttpResponse(data, status=200)
 
 
 @api.api_method(http_method='GET', user_required=True, logger=log)
@@ -165,11 +168,59 @@ def delete_subnet(request, sub_id):
 @api.api_method(http_method='PUT', user_required=True, logger=log)
 def update_subnet(request, sub_id):
     '''Update info of a subnet'''
+    dictionary = utils.get_request_dict(request)
+    log.info('Update subnet %s', dictionary)
+    user_id = request.user_uniq
 
+    try:
+        subnet = dictionary['subnet']
+    except KeyError:
+        raise api.faults.BadRequest("Malformed request")
 
-# util functions
+    original_subnet = get_subnet_fromdb(sub_id, user_id)
+    original_dict = subnet_to_dict(original_subnet)
+
+    if subnet.get('ip_version', None):
+        raise api.faults.BadRequest("Malformed request, ip_version cannot be "
+                                    "updated")
+    if subnet.get('cidr', None):
+        raise api.faults.BadRequest("Malformed request, cidr cannot be "
+                                    "updated")
+    if subnet.get('allocation_pools', None):
+        raise api.faults.BadRequest("Malformed request, allocation pools "
+                                    "cannot be updated")
+
+    check_for_hosts_dns(subnet)
+    name = subnet.get('name', original_dict['name'])
+    if name:
+        check_name_length(name)
+
+    dhcp = subnet.get('enable_dhcp', original_dict['enable_dhcp'])
+    check_dhcp_value(dhcp)
+
+    gateway = subnet.get('gateway_ip', original_dict['gateway_ip'])
+    #FIX ME, check if IP is in use
+    if original_dict['ip_version'] == 6:
+        networks.validate_network_params(None, None, original_dict['cidr'],
+                                         gateway)
+    else:
+        networks.validate_network_params(original_dict['cidr'], gateway)
 
+    try:
+        original_subnet.gateway = gateway
+        original_subnet.name = name
+        original_subnet.dhcp = dhcp
+        original_subnet.save()
+    except:
+        #Fix me
+        return "Unknown Error"
+
+    subnet_dict = subnet_to_dict(original_subnet)
+    data = json.dumps({'subnet': subnet_dict})
+    return HttpResponse(data, status=200)
 
+
+#Utility functions
 def subnet_to_dict(subnet):
     '''Returns a dictionary containing the info of a subnet'''
     # FIX ME, allocation pools
@@ -183,22 +234,49 @@ def subnet_to_dict(subnet):
 
 
 def check_number_of_subnets(network, version):
-    '''Checks if a user can add a subnet in a network'''
+    '''Check if a user can add a subnet in a network'''
     if network.subnet_set.filter(ipversion=version):
         raise api.faults.BadRequest("Only one subnet of IPv4/IPv6 per "
                                     "network is allowed")
 
 
+def check_dhcp_value(dhcp):
+    '''Check if dhcp value is in acceptable values'''
+    if dhcp not in [True, False]:
+        raise api.faults.BadRequest("Malformed request, enable_dhcp must be "
+                                    "True or False")
+    return dhcp
+
+
+def check_name_length(name):
+    '''Check if the length of a name is within acceptable value'''
+    if len(str(name)) > Subnet.SUBNET_NAME_LENGTH:
+        raise api.faults.BadRequest("Subnet name too long")
+    return name
+
+
+def check_for_hosts_dns(subnet):
+    '''
+    Check if a request contains host_routes or dns_nameservers options
+    Expects the request in a dictionary format
+    '''
+    if subnet.get('host_routes', None):
+        raise api.faults.BadRequest("Setting host routes isn't supported")
+    if subnet.get('dns_nameservers', None):
+        raise api.faults.BadRequest("Setting dns nameservers isn't supported")
+
+
 def get_subnet_fromdb(subnet_id, user_id, for_update=False):
-    """
+    '''
     Return a Subnet instance or raise ItemNotFound.
     This is the same as util.get_network
-    """
+    '''
     try:
         subnet_id = int(subnet_id)
-        objects = Subnet.objects
         if for_update:
-            objects = objects.select_for_update()
-        return objects.get(id=subnet_id, network__userid=user_id)
+            return Subnet.objects.select_for_update().get(id=subnet_id,
+                                                          network__userid=
+                                                          user_id)
+        return Subnet.objects.get(id=subnet_id, network__userid=user_id)
     except (ValueError, Subnet.DoesNotExist):
         raise api.faults.ItemNotFound('Subnet not found.')
