Revision 09a43b39

b/lib/rapi/rlib2.py
687 687
      })
688 688

  
689 689

  
690
def _ParseInstanceCreateRequestVersion1(data, dry_run):
691
  """Parses an instance creation request version 1.
692

  
693
  @rtype: L{opcodes.OpInstanceCreate}
694
  @return: Instance creation opcode
690
class R_2_instances(baserlib.OpcodeResource):
691
  """/2/instances resource.
695 692

  
696 693
  """
697
  override = {
698
    "dry_run": dry_run,
699
    }
700

  
701
  rename = {
694
  POST_OPCODE = opcodes.OpInstanceCreate
695
  POST_RENAME = {
702 696
    "os": "os_type",
703 697
    "name": "instance_name",
704 698
    }
705 699

  
706
  return baserlib.FillOpcode(opcodes.OpInstanceCreate, data, override,
707
                             rename=rename)
708

  
709

  
710
class R_2_instances(baserlib.ResourceBase):
711
  """/2/instances resource.
712

  
713
  """
714 700
  def GET(self):
715 701
    """Returns a list of all available instances.
716 702

  
......
727 713
      return baserlib.BuildUriList(instanceslist, "/2/instances/%s",
728 714
                                   uri_fields=("id", "uri"))
729 715

  
730
  def POST(self):
716
  def GetPostOpInput(self):
731 717
    """Create an instance.
732 718

  
733 719
    @return: a job id
734 720

  
735 721
    """
736
    if not isinstance(self.request_body, dict):
737
      raise http.HttpBadRequest("Invalid body contents, not a dictionary")
722
    baserlib.CheckType(self.request_body, dict, "Body contents")
738 723

  
739 724
    # Default to request data version 0
740 725
    data_version = self.getBodyParameter(_REQ_DATA_VERSION, 0)
......
742 727
    if data_version == 0:
743 728
      raise http.HttpBadRequest("Instance creation request version 0 is no"
744 729
                                " longer supported")
745
    elif data_version == 1:
746
      data = self.request_body.copy()
747
      # Remove "__version__"
748
      data.pop(_REQ_DATA_VERSION, None)
749
      op = _ParseInstanceCreateRequestVersion1(data, self.dryRun())
750
    else:
730
    elif data_version != 1:
751 731
      raise http.HttpBadRequest("Unsupported request data version %s" %
752 732
                                data_version)
753 733

  
754
    return self.SubmitJob([op])
734
    data = self.request_body.copy()
735
    # Remove "__version__"
736
    data.pop(_REQ_DATA_VERSION, None)
737

  
738
    return (data, {
739
      "dry_run": self.dryRun(),
740
      })
755 741

  
756 742

  
757 743
class R_2_instances_name(baserlib.OpcodeResource):
b/test/ganeti.rapi.rlib2_unittest.py
741 741
        self.assertRaises(IndexError, cl.GetNextSubmittedJob)
742 742

  
743 743

  
744
class TestParseInstanceCreateRequestVersion1(testutils.GanetiTestCase):
745
  def setUp(self):
746
    testutils.GanetiTestCase.setUp(self)
744
class TestInstanceCreation(testutils.GanetiTestCase):
745
  def test(self):
746
    clfactory = _FakeClientFactory(_FakeClient)
747 747

  
748
    self.Parse = rlib2._ParseInstanceCreateRequestVersion1
748
    name = "inst863.example.com"
749 749

  
750
  def test(self):
751 750
    disk_variants = [
752 751
      # No disks
753 752
      [],
......
798 797
          for disks in disk_variants:
799 798
            for beparams in beparam_variants:
800 799
              for hvparams in hvparam_variants:
801
                data = {
802
                  "name": "inst1.example.com",
803
                  "hypervisor": constants.HT_FAKE,
804
                  "disks": disks,
805
                  "nics": nics,
806
                  "mode": mode,
807
                  "disk_template": disk_template,
808
                  "os": "debootstrap",
809
                  }
810

  
811
                if beparams is not None:
812
                  data["beparams"] = beparams
813

  
814
                if hvparams is not None:
815
                  data["hvparams"] = hvparams
816

  
817 800
                for dry_run in [False, True]:
818
                  op = self.Parse(data, dry_run)
819
                  self.assert_(isinstance(op, opcodes.OpInstanceCreate))
801
                  queryargs = {
802
                    "dry-run": str(int(dry_run)),
803
                    }
804

  
805
                  data = {
806
                    rlib2._REQ_DATA_VERSION: 1,
807
                    "name": name,
808
                    "hypervisor": constants.HT_FAKE,
809
                    "disks": disks,
810
                    "nics": nics,
811
                    "mode": mode,
812
                    "disk_template": disk_template,
813
                    "os": "debootstrap",
814
                    }
815

  
816
                  if beparams is not None:
817
                    data["beparams"] = beparams
818

  
819
                  if hvparams is not None:
820
                    data["hvparams"] = hvparams
821

  
822
                  handler = _CreateHandler(rlib2.R_2_instances, [],
823
                                           queryargs, data, clfactory)
824
                  job_id = handler.POST()
825

  
826
                  cl = clfactory.GetNextClient()
827
                  self.assertRaises(IndexError, clfactory.GetNextClient)
828

  
829
                  (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
830
                  self.assertEqual(job_id, exp_job_id)
831
                  self.assertRaises(IndexError, cl.GetNextSubmittedJob)
832

  
833
                  self.assertTrue(isinstance(op, opcodes.OpInstanceCreate))
834
                  self.assertEqual(op.instance_name, name)
820 835
                  self.assertEqual(op.mode, mode)
821 836
                  self.assertEqual(op.disk_template, disk_template)
822 837
                  self.assertEqual(op.dry_run, dry_run)
......
845 860
                    self.assertEqualValues(op.hvparams, hvparams)
846 861

  
847 862
  def testLegacyName(self):
863
    clfactory = _FakeClientFactory(_FakeClient)
864

  
848 865
    name = "inst29128.example.com"
849 866
    data = {
867
      rlib2._REQ_DATA_VERSION: 1,
850 868
      "name": name,
851 869
      "disks": [],
852 870
      "nics": [],
853 871
      "mode": constants.INSTANCE_CREATE,
854 872
      "disk_template": constants.DT_PLAIN,
855 873
      }
856
    op = self.Parse(data, False)
857
    self.assert_(isinstance(op, opcodes.OpInstanceCreate))
874

  
875
    handler = _CreateHandler(rlib2.R_2_instances, [], {}, data, clfactory)
876
    job_id = handler.POST()
877

  
878
    cl = clfactory.GetNextClient()
879
    self.assertRaises(IndexError, clfactory.GetNextClient)
880

  
881
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
882
    self.assertEqual(job_id, exp_job_id)
883
    self.assertTrue(isinstance(op, opcodes.OpInstanceCreate))
858 884
    self.assertEqual(op.instance_name, name)
859 885
    self.assertFalse(hasattr(op, "name"))
886
    self.assertFalse(op.dry_run)
887

  
888
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
860 889

  
861 890
    # Define both
862
    data = {
863
      "name": name,
864
      "instance_name": "other.example.com",
865
      "disks": [],
866
      "nics": [],
867
      "mode": constants.INSTANCE_CREATE,
868
      "disk_template": constants.DT_PLAIN,
869
      }
870
    self.assertRaises(http.HttpBadRequest, self.Parse, data, False)
891
    data["instance_name"] = "other.example.com"
892
    assert "name" in data and "instance_name" in data
893
    handler = _CreateHandler(rlib2.R_2_instances, [], {}, data, clfactory)
894
    self.assertRaises(http.HttpBadRequest, handler.POST)
895
    self.assertRaises(IndexError, clfactory.GetNextClient)
871 896

  
872 897
  def testLegacyOs(self):
898
    clfactory = _FakeClientFactory(_FakeClient)
899

  
873 900
    name = "inst4673.example.com"
874 901
    os = "linux29206"
875 902
    data = {
903
      rlib2._REQ_DATA_VERSION: 1,
876 904
      "name": name,
877 905
      "os_type": os,
878 906
      "disks": [],
......
880 908
      "mode": constants.INSTANCE_CREATE,
881 909
      "disk_template": constants.DT_PLAIN,
882 910
      }
883
    op = self.Parse(data, False)
884
    self.assert_(isinstance(op, opcodes.OpInstanceCreate))
911

  
912
    handler = _CreateHandler(rlib2.R_2_instances, [], {}, data, clfactory)
913
    job_id = handler.POST()
914

  
915
    cl = clfactory.GetNextClient()
916
    self.assertRaises(IndexError, clfactory.GetNextClient)
917

  
918
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
919
    self.assertEqual(job_id, exp_job_id)
920
    self.assertTrue(isinstance(op, opcodes.OpInstanceCreate))
885 921
    self.assertEqual(op.instance_name, name)
886 922
    self.assertEqual(op.os_type, os)
887 923
    self.assertFalse(hasattr(op, "os"))
924
    self.assertFalse(op.dry_run)
925

  
926
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
888 927

  
889 928
    # Define both
890
    data = {
891
      "instance_name": name,
892
      "os": os,
893
      "os_type": "linux9584",
894
      "disks": [],
895
      "nics": [],
896
      "mode": constants.INSTANCE_CREATE,
897
      "disk_template": constants.DT_PLAIN,
898
      }
899
    self.assertRaises(http.HttpBadRequest, self.Parse, data, False)
929
    data["os"] = "linux9584"
930
    assert "os" in data and "os_type" in data
931
    handler = _CreateHandler(rlib2.R_2_instances, [], {}, data, clfactory)
932
    self.assertRaises(http.HttpBadRequest, handler.POST)
900 933

  
901 934
  def testErrors(self):
935
    clfactory = _FakeClientFactory(_FakeClient)
936

  
902 937
    # Test all required fields
903 938
    reqfields = {
939
      rlib2._REQ_DATA_VERSION: 1,
904 940
      "name": "inst1.example.com",
905 941
      "disks": [],
906 942
      "nics": [],
......
909 945
      }
910 946

  
911 947
    for name in reqfields.keys():
912
      self.assertRaises(http.HttpBadRequest, self.Parse,
913
                        dict(i for i in reqfields.iteritems() if i[0] != name),
914
                        False)
948
      data = dict(i for i in reqfields.iteritems() if i[0] != name)
949

  
950
      handler = _CreateHandler(rlib2.R_2_instances, [], {}, data, clfactory)
951
      self.assertRaises(http.HttpBadRequest, handler.POST)
952
      self.assertRaises(IndexError, clfactory.GetNextClient)
915 953

  
916 954
    # Invalid disks and nics
917 955
    for field in ["disks", "nics"]:
......
921 959
      for invvalue in invalid_values:
922 960
        data = reqfields.copy()
923 961
        data[field] = invvalue
924
        self.assertRaises(http.HttpBadRequest, self.Parse, data, False)
962
        handler = _CreateHandler(rlib2.R_2_instances, [], {}, data, clfactory)
963
        self.assertRaises(http.HttpBadRequest, handler.POST)
964
        self.assertRaises(IndexError, clfactory.GetNextClient)
965

  
966
  def testVersion(self):
967
    clfactory = _FakeClientFactory(_FakeClient)
968

  
969
    # No version field
970
    data = {
971
      "name": "inst1.example.com",
972
      "disks": [],
973
      "nics": [],
974
      "mode": constants.INSTANCE_CREATE,
975
      "disk_template": constants.DT_PLAIN,
976
      }
977

  
978
    handler = _CreateHandler(rlib2.R_2_instances, [], {}, data, clfactory)
979
    self.assertRaises(http.HttpBadRequest, handler.POST)
980

  
981
    # Old and incorrect versions
982
    for version in [0, -1, 10483, "Hello World"]:
983
      data[rlib2._REQ_DATA_VERSION] = version
984

  
985
      handler = _CreateHandler(rlib2.R_2_instances, [], {}, data, clfactory)
986
      self.assertRaises(http.HttpBadRequest, handler.POST)
987

  
988
      self.assertRaises(IndexError, clfactory.GetNextClient)
989

  
990
    # Correct version
991
    data[rlib2._REQ_DATA_VERSION] = 1
992
    handler = _CreateHandler(rlib2.R_2_instances, [], {}, data, clfactory)
993
    job_id = handler.POST()
994

  
995
    cl = clfactory.GetNextClient()
996
    self.assertRaises(IndexError, clfactory.GetNextClient)
997

  
998
    (exp_job_id, (op, )) = cl.GetNextSubmittedJob()
999
    self.assertEqual(job_id, exp_job_id)
1000
    self.assertTrue(isinstance(op, opcodes.OpInstanceCreate))
1001
    self.assertRaises(IndexError, cl.GetNextSubmittedJob)
925 1002

  
926 1003

  
927 1004
class TestBackupExport(unittest.TestCase):

Also available in: Unified diff