Pull the vnctoken remctl into the controls module
[invirt/packages/invirt-web.git] / code / validation.py
index f6e4a59..fe6d7c8 100644 (file)
@@ -4,9 +4,10 @@ import cache_acls
 import getafsgroups
 import re
 import string
 import getafsgroups
 import re
 import string
+import dns.resolver
 from invirt.database import Machine, NIC, Type, Disk, CDROM, Autoinstall
 from invirt.config import structs as config
 from invirt.database import Machine, NIC, Type, Disk, CDROM, Autoinstall
 from invirt.config import structs as config
-from webcommon import InvalidInput
+from invirt.common import InvalidInput
 
 MAX_MEMORY_TOTAL = 512
 MAX_MEMORY_SINGLE = 256
 
 MAX_MEMORY_TOTAL = 512
 MAX_MEMORY_SINGLE = 256
@@ -63,11 +64,11 @@ class Validate:
         if vmtype is not None:
             self.vmtype = validVmType(vmtype)
         if cdrom is not None:
         if vmtype is not None:
             self.vmtype = validVmType(vmtype)
         if cdrom is not None:
-            if not CDROM.get(cdrom):
+            if not CDROM.query().get(cdrom):
                 raise CodeError("Invalid cdrom type '%s'" % cdrom)
             self.cdrom = cdrom
         if autoinstall is not None:
                 raise CodeError("Invalid cdrom type '%s'" % cdrom)
             self.cdrom = cdrom
         if autoinstall is not None:
-            self.autoinstall = Autoinstall.get(autoinstall)
+            self.autoinstall = Autoinstall.query().get(autoinstall)
 
 
 def getMachinesByOwner(owner, machine=None):
 
 
 def getMachinesByOwner(owner, machine=None):
@@ -78,7 +79,7 @@ def getMachinesByOwner(owner, machine=None):
     """
     if machine:
         owner = machine.owner
     """
     if machine:
         owner = machine.owner
-    return Machine.select_by(owner=owner)
+    return Machine.query().filter_by(owner=owner)
 
 def maxMemory(owner, g, machine=None, on=True):
     """Return the maximum memory for a machine or a user.
 
 def maxMemory(owner, g, machine=None, on=True):
     """Return the maximum memory for a machine or a user.
@@ -110,14 +111,15 @@ def maxDisk(owner, machine=None):
         machine_id = machine.machine_id
     else:
         machine_id = None
         machine_id = machine.machine_id
     else:
         machine_id = None
-    disk_usage = Disk.query().filter_by(Disk.c.machine_id != machine_id,
-                                        owner=owner).sum(Disk.c.size) or 0
+    disk_usage = Disk.query().filter(Disk.c.machine_id != machine_id).\
+                     join('machine').\
+                     filter_by(owner=owner).sum(Disk.c.size) or 0
     return min(MAX_DISK_SINGLE, MAX_DISK_TOTAL-disk_usage/1024.)
 
 def cantAddVm(owner, g):
     machines = getMachinesByOwner(owner)
     active_machines = [m for m in machines if m.name in g.xmlist_raw]
     return min(MAX_DISK_SINGLE, MAX_DISK_TOTAL-disk_usage/1024.)
 
 def cantAddVm(owner, g):
     machines = getMachinesByOwner(owner)
     active_machines = [m for m in machines if m.name in g.xmlist_raw]
-    if len(machines) >= MAX_VMS_TOTAL:
+    if machines.count() >= MAX_VMS_TOTAL:
         return 'You have too many VMs to create a new one.'
     if len(active_machines) >= MAX_VMS_ACTIVE:
         return ('You already have the maximum number of VMs turned on.  '
         return 'You have too many VMs to create a new one.'
     if len(active_machines) >= MAX_VMS_ACTIVE:
         return ('You already have the maximum number of VMs turned on.  '
@@ -182,7 +184,7 @@ def validDisk(owner, g, disk, machine=None):
 def validVmType(vm_type):
     if vm_type is None:
         return None
 def validVmType(vm_type):
     if vm_type is None:
         return None
-    t = Type.get(vm_type)
+    t = Type.query().get(vm_type)
     if t is None:
         raise CodeError("Invalid vm type '%s'"  % vm_type)
     return t
     if t is None:
         raise CodeError("Invalid vm type '%s'"  % vm_type)
     return t
@@ -199,7 +201,7 @@ def testMachineId(user, state, machine_id, exists=True):
         machine_id = int(machine_id)
     except ValueError:
         raise InvalidInput('machine_id', machine_id, "Must be an integer.")
         machine_id = int(machine_id)
     except ValueError:
         raise InvalidInput('machine_id', machine_id, "Must be an integer.")
-    machine = Machine.get(machine_id)
+    machine = Machine.query().get(machine_id)
     if exists and machine is None:
         raise InvalidInput('machine_id', machine_id, "Does not exist.")
     if machine is not None and not haveAccess(user, state, machine):
     if exists and machine is None:
         raise InvalidInput('machine_id', machine_id, "Does not exist.")
     if machine is not None and not haveAccess(user, state, machine):
@@ -269,11 +271,33 @@ def testName(user, name, machine=None):
     name = name.lower()
     if machine is not None and name == machine.name:
         return None
     name = name.lower()
     if machine is not None and name == machine.name:
         return None
-    if not Machine.select_by(name=name):
+    try:
+        hostname = '%s.%s.' % (name, config.dns.domains[0])
+        resolver = dns.resolver.Resolver()
+        resolver.nameservers = ['127.0.0.1']
+        try:
+            resolver.query(hostname, 'A')
+        except dns.resolver.NoAnswer, e:
+            # If we can get the TXT record, then we can verify it's
+            # reserved. If this lookup fails, let it bubble up and be
+            # dealt with
+            answer = resolver.query(hostname, 'TXT')
+            txt = answer[0].strings[0]
+            if txt.startswith('reserved'):
+                raise InvalidInput('name', name, 'The name you have requested has been %s. For more information, contact us at %s' % (txt, config.dns.contact))
+
+        # If the hostname didn't exist, it would have thrown an
+        # exception by now - error out
+        raise InvalidInput('name', name, 'Name is already taken.')
+    except dns.resolver.NXDOMAIN, e:
         if not validMachineName(name):
             raise InvalidInput('name', name, 'You must provide a machine name.  Max 63 chars, alnum plus \'-\', does not begin or end with \'-\'.')
         return name
         if not validMachineName(name):
             raise InvalidInput('name', name, 'You must provide a machine name.  Max 63 chars, alnum plus \'-\', does not begin or end with \'-\'.')
         return name
-    raise InvalidInput('name', name, "Name is already taken.")
+    except InvalidInput:
+        raise
+    except:
+        # Any other error is a validation failure
+        raise InvalidInput('name', name, 'We were unable to verify that this name is available. If you believe this is in error, please contact us at %s' % config.dns.contact)
 
 def testDescription(user, description, machine=None):
     if description is None or description.strip() == '':
 
 def testDescription(user, description, machine=None):
     if description is None or description.strip() == '':