Revision 48436b97 lib/rapi/client.py

b/lib/rapi/client.py
60 60
# Internal constants
61 61
_REQ_DATA_VERSION_FIELD = "__version__"
62 62
_INST_CREATE_REQV1 = "instance-create-reqv1"
63
_INST_NIC_PARAMS = frozenset(["mac", "ip", "mode", "link", "bridge"])
64
_INST_CREATE_V0_DISK_PARAMS = frozenset(["size"])
65
_INST_CREATE_V0_PARAMS = frozenset([
66
  "os", "pnode", "snode", "iallocator", "start", "ip_check", "name_check",
67
  "hypervisor", "file_storage_dir", "file_driver", "dry_run",
68
  ])
69
_INST_CREATE_V0_DPARAMS = frozenset(["beparams", "hvparams"])
63 70

  
64 71

  
65 72
class Error(Exception):
......
676 683
      body.update((key, value) for key, value in kwargs.iteritems()
677 684
                  if key != "dry_run")
678 685
    else:
679
      # TODO: Implement instance creation request data version 0
680
      # When implementing version 0, care should be taken to refuse unknown
681
      # parameters and invalid values. The interface of this function must stay
686
      # Old request format (version 0)
687

  
688
      # The following code must make sure that an exception is raised when an
689
      # unsupported setting is requested by the caller. Otherwise this can lead
690
      # to bugs difficult to find. The interface of this function must stay
682 691
      # exactly the same for version 0 and 1 (e.g. they aren't allowed to
683 692
      # require different data types).
684
      raise NotImplementedError("Support for instance creation request data"
685
                                " version 0 is not yet implemented")
693

  
694
      # Validate disks
695
      for idx, disk in enumerate(disks):
696
        unsupported = set(disk.keys()) - _INST_CREATE_V0_DISK_PARAMS
697
        if unsupported:
698
          raise GanetiApiError("Server supports request version 0 only, but"
699
                               " disk %s specifies the unsupported parameters"
700
                               " %s, allowed are %s" %
701
                               (idx, unsupported,
702
                                list(_INST_CREATE_V0_DISK_PARAMS)))
703

  
704
      assert (len(_INST_CREATE_V0_DISK_PARAMS) == 1 and
705
              "size" in _INST_CREATE_V0_DISK_PARAMS)
706
      disk_sizes = [disk["size"] for disk in disks]
707

  
708
      # Validate NICs
709
      if not nics:
710
        raise GanetiApiError("Server supports request version 0 only, but"
711
                             " no NIC specified")
712
      elif len(nics) > 1:
713
        raise GanetiApiError("Server supports request version 0 only, but"
714
                             " more than one NIC specified")
715

  
716
      assert len(nics) == 1
717

  
718
      unsupported = set(nics[0].keys()) - _INST_NIC_PARAMS
719
      if unsupported:
720
        raise GanetiApiError("Server supports request version 0 only, but"
721
                             " NIC 0 specifies the unsupported parameters %s,"
722
                             " allowed are %s" %
723
                             (unsupported, list(_INST_NIC_PARAMS)))
724

  
725
      # Validate other parameters
726
      unsupported = (set(kwargs.keys()) - _INST_CREATE_V0_PARAMS -
727
                     _INST_CREATE_V0_DPARAMS)
728
      if unsupported:
729
        allowed = _INST_CREATE_V0_PARAMS.union(_INST_CREATE_V0_DPARAMS)
730
        raise GanetiApiError("Server supports request version 0 only, but"
731
                             " the following unsupported parameters are"
732
                             " specified: %s, allowed are %s" %
733
                             (unsupported, list(allowed)))
734

  
735
      # All required fields for request data version 0
736
      body = {
737
        _REQ_DATA_VERSION_FIELD: 0,
738
        "name": name,
739
        "disk_template": disk_template,
740
        "disks": disk_sizes,
741
        }
742

  
743
      # NIC fields
744
      assert len(nics) == 1
745
      assert not (set(body.keys()) & set(nics[0].keys()))
746
      body.update(nics[0])
747

  
748
      # Copy supported fields
749
      assert not (set(body.keys()) & set(kwargs.keys()))
750
      body.update(dict((key, value) for key, value in kwargs.items()
751
                       if key in _INST_CREATE_V0_PARAMS))
752

  
753
      # Merge dictionaries
754
      for i in (value for key, value in kwargs.items()
755
                if key in _INST_CREATE_V0_DPARAMS):
756
        assert not (set(body.keys()) & set(i.keys()))
757
        body.update(i)
758

  
759
      assert not (set(kwargs.keys()) -
760
                  (_INST_CREATE_V0_PARAMS | _INST_CREATE_V0_DPARAMS))
761
      assert not (set(body.keys()) & _INST_CREATE_V0_DPARAMS)
686 762

  
687 763
    return self._SendRequest(HTTP_POST, "/%s/instances" % GANETI_RAPI_VERSION,
688 764
                             query, body)

Also available in: Unified diff