Revision a60e3cb0 lib/rapi/client.py

b/lib/rapi/client.py
333 333
    self._port = port
334 334
    self._logger = logger
335 335

  
336
    self._version = None
337

  
338 336
    self._base_url = "https://%s:%s" % (host, port)
339 337

  
340 338
    handlers = [_HTTPSHandler(self._logger, config_ssl_verification)]
......
357 355
      "User-Agent": self.USER_AGENT,
358 356
      }
359 357

  
360
  def _MakeUrl(self, path, query=None, prepend_version=True):
358
  def _MakeUrl(self, path, query=None):
361 359
    """Constructs the URL to pass to the HTTP client.
362 360

  
363 361
    @type path: str
364 362
    @param path: HTTP URL path
365 363
    @type query: list of two-tuples
366 364
    @param query: query arguments to pass to urllib.urlencode
367
    @type prepend_version: bool
368
    @param prepend_version: whether to automatically fetch and prepend the
369
        Ganeti RAPI version to the URL path
370 365

  
371 366
    @rtype:  str
372 367
    @return: URL path
373 368

  
374 369
    """
375
    if prepend_version:
376
      path = "/%d%s" % (self.GetVersion(), path)
377

  
378 370
    return "https://%(host)s:%(port)d%(path)s?%(query)s" % {
379 371
        "host": self._host,
380 372
        "port": self._port,
381 373
        "path": path,
382 374
        "query": urllib.urlencode(query or [])}
383 375

  
384
  def _SendRequest(self, method, path, query=None, content=None,
385
                   prepend_version=True):
376
  def _SendRequest(self, method, path, query=None, content=None):
386 377
    """Sends an HTTP request.
387 378

  
388 379
    This constructs a full URL, encodes and decodes HTTP bodies, and
......
396 387
    @param query: query arguments to pass to urllib.urlencode
397 388
    @type content: str or None
398 389
    @param content: HTTP body content
399
    @type prepend_version: bool
400
    @param prepend_version: whether to automatically fetch and prepend the
401
        Ganeti RAPI version to the URL path
402 390

  
403 391
    @rtype: str
404 392
    @return: JSON-Decoded response
......
410 398
    if content:
411 399
      content = simplejson.JSONEncoder(sort_keys=True).encode(content)
412 400

  
413
    url = self._MakeUrl(path, query, prepend_version)
401
    url = self._MakeUrl(path, query)
414 402

  
415 403
    req = _RapiRequest(method, url, self._headers, content)
416 404

  
......
442 430
    @return: Ganeti Remote API version
443 431

  
444 432
    """
445
    if self._version is None:
446
      self._version = self._SendRequest(HTTP_GET, "/version",
447
                                        prepend_version=False)
448
    return self._version
433
    return self._SendRequest(HTTP_GET, "/version")
449 434

  
450 435
  def GetOperatingSystems(self):
451 436
    """Gets the Operating Systems running in the Ganeti cluster.
......
454 439
    @return: operating systems
455 440

  
456 441
    """
457
    return self._SendRequest(HTTP_GET, "/os")
442
    return self._SendRequest(HTTP_GET, "/2/os")
458 443

  
459 444
  def GetInfo(self):
460 445
    """Gets info about the cluster.
......
463 448
    @return: information about the cluster
464 449

  
465 450
    """
466
    return self._SendRequest(HTTP_GET, "/info")
451
    return self._SendRequest(HTTP_GET, "/2/info")
467 452

  
468 453
  def GetClusterTags(self):
469 454
    """Gets the cluster tags.
......
472 457
    @return: cluster tags
473 458

  
474 459
    """
475
    return self._SendRequest(HTTP_GET, "/tags")
460
    return self._SendRequest(HTTP_GET, "/2/tags")
476 461

  
477 462
  def AddClusterTags(self, tags, dry_run=False):
478 463
    """Adds tags to the cluster.
......
490 475
    if dry_run:
491 476
      query.append(("dry-run", 1))
492 477

  
493
    return self._SendRequest(HTTP_PUT, "/tags", query)
478
    return self._SendRequest(HTTP_PUT, "/2/tags", query)
494 479

  
495 480
  def DeleteClusterTags(self, tags, dry_run=False):
496 481
    """Deletes tags from the cluster.
......
505 490
    if dry_run:
506 491
      query.append(("dry-run", 1))
507 492

  
508
    self._SendRequest(HTTP_DELETE, "/tags", query)
493
    self._SendRequest(HTTP_DELETE, "/2/tags", query)
509 494

  
510 495
  def GetInstances(self, bulk=False):
511 496
    """Gets information about instances on the cluster.
......
521 506
    if bulk:
522 507
      query.append(("bulk", 1))
523 508

  
524
    instances = self._SendRequest(HTTP_GET, "/instances", query)
509
    instances = self._SendRequest(HTTP_GET, "/2/instances", query)
525 510
    if bulk:
526 511
      return instances
527 512
    else:
......
538 523
    @return: info about the instance
539 524

  
540 525
    """
541
    return self._SendRequest(HTTP_GET, "/instances/%s" % instance)
526
    return self._SendRequest(HTTP_GET, "/2/instances/%s" % instance)
542 527

  
543 528
  def CreateInstance(self, dry_run=False):
544 529
    """Creates a new instance.
......
555 540
    if dry_run:
556 541
      query.append(("dry-run", 1))
557 542

  
558
    return self._SendRequest(HTTP_POST, "/instances", query)
543
    return self._SendRequest(HTTP_POST, "/2/instances", query)
559 544

  
560 545
  def DeleteInstance(self, instance, dry_run=False):
561 546
    """Deletes an instance.
......
571 556
    if dry_run:
572 557
      query.append(("dry-run", 1))
573 558

  
574
    return self._SendRequest(HTTP_DELETE, "/instances/%s" % instance, query)
559
    return self._SendRequest(HTTP_DELETE, "/2/instances/%s" % instance, query)
575 560

  
576 561
  def GetInstanceTags(self, instance):
577 562
    """Gets tags for an instance.
......
583 568
    @return: tags for the instance
584 569

  
585 570
    """
586
    return self._SendRequest(HTTP_GET, "/instances/%s/tags" % instance)
571
    return self._SendRequest(HTTP_GET, "/2/instances/%s/tags" % instance)
587 572

  
588 573
  def AddInstanceTags(self, instance, tags, dry_run=False):
589 574
    """Adds tags to an instance.
......
603 588
    if dry_run:
604 589
      query.append(("dry-run", 1))
605 590

  
606
    return self._SendRequest(HTTP_PUT, "/instances/%s/tags" % instance, query)
591
    return self._SendRequest(HTTP_PUT, "/2/instances/%s/tags" % instance, query)
607 592

  
608 593
  def DeleteInstanceTags(self, instance, tags, dry_run=False):
609 594
    """Deletes tags from an instance.
......
620 605
    if dry_run:
621 606
      query.append(("dry-run", 1))
622 607

  
623
    self._SendRequest(HTTP_DELETE, "/instances/%s/tags" % instance, query)
608
    self._SendRequest(HTTP_DELETE, "/2/instances/%s/tags" % instance, query)
624 609

  
625 610
  def RebootInstance(self, instance, reboot_type=None, ignore_secondaries=None,
626 611
                     dry_run=False):
......
645 630
    if dry_run:
646 631
      query.append(("dry-run", 1))
647 632

  
648
    self._SendRequest(HTTP_POST, "/instances/%s/reboot" % instance, query)
633
    self._SendRequest(HTTP_POST, "/2/instances/%s/reboot" % instance, query)
649 634

  
650 635
  def ShutdownInstance(self, instance, dry_run=False):
651 636
    """Shuts down an instance.
......
660 645
    if dry_run:
661 646
      query.append(("dry-run", 1))
662 647

  
663
    self._SendRequest(HTTP_PUT, "/instances/%s/shutdown" % instance, query)
648
    self._SendRequest(HTTP_PUT, "/2/instances/%s/shutdown" % instance, query)
664 649

  
665 650
  def StartupInstance(self, instance, dry_run=False):
666 651
    """Starts up an instance.
......
675 660
    if dry_run:
676 661
      query.append(("dry-run", 1))
677 662

  
678
    self._SendRequest(HTTP_PUT, "/instances/%s/startup" % instance, query)
663
    self._SendRequest(HTTP_PUT, "/2/instances/%s/startup" % instance, query)
679 664

  
680 665
  def ReinstallInstance(self, instance, os, no_startup=False):
681 666
    """Reinstalls an instance.
......
691 676
    query = [("os", os)]
692 677
    if no_startup:
693 678
      query.append(("nostartup", 1))
694
    self._SendRequest(HTTP_POST, "/instances/%s/reinstall" % instance, query)
679
    self._SendRequest(HTTP_POST, "/2/instances/%s/reinstall" % instance, query)
695 680

  
696 681
  def ReplaceInstanceDisks(self, instance, disks, mode="replace_auto",
697 682
                           remote_node=None, iallocator="hail", dry_run=False):
......
737 722
      query.append(("dry-run", 1))
738 723

  
739 724
    return self._SendRequest(HTTP_POST,
740
                             "/instances/%s/replace-disks" % instance, query)
725
                             "/2/instances/%s/replace-disks" % instance, query)
741 726

  
742 727
  def GetJobs(self):
743 728
    """Gets all jobs for the cluster.
......
746 731
    @return: job ids for the cluster
747 732

  
748 733
    """
749
    return [int(j["id"]) for j in self._SendRequest(HTTP_GET, "/jobs")]
734
    return [int(j["id"]) for j in self._SendRequest(HTTP_GET, "/2/jobs")]
750 735

  
751 736
  def GetJobStatus(self, job_id):
752 737
    """Gets the status of a job.
......
758 743
    @return: job status
759 744

  
760 745
    """
761
    return self._SendRequest(HTTP_GET, "/jobs/%d" % job_id)
746
    return self._SendRequest(HTTP_GET, "/2/jobs/%d" % job_id)
762 747

  
763 748
  def DeleteJob(self, job_id, dry_run=False):
764 749
    """Deletes a job.
......
773 758
    if dry_run:
774 759
      query.append(("dry-run", 1))
775 760

  
776
    self._SendRequest(HTTP_DELETE, "/jobs/%d" % job_id, query)
761
    self._SendRequest(HTTP_DELETE, "/2/jobs/%d" % job_id, query)
777 762

  
778 763
  def GetNodes(self, bulk=False):
779 764
    """Gets all nodes in the cluster.
......
790 775
    if bulk:
791 776
      query.append(("bulk", 1))
792 777

  
793
    nodes = self._SendRequest(HTTP_GET, "/nodes", query)
778
    nodes = self._SendRequest(HTTP_GET, "/2/nodes", query)
794 779
    if bulk:
795 780
      return nodes
796 781
    else:
......
806 791
    @return: info about the node
807 792

  
808 793
    """
809
    return self._SendRequest(HTTP_GET, "/nodes/%s" % node)
794
    return self._SendRequest(HTTP_GET, "/2/nodes/%s" % node)
810 795

  
811 796
  def EvacuateNode(self, node, iallocator=None, remote_node=None,
812 797
                   dry_run=False):
......
838 823
    if dry_run:
839 824
      query.append(("dry-run", 1))
840 825

  
841
    return self._SendRequest(HTTP_POST, "/nodes/%s/evacuate" % node, query)
826
    return self._SendRequest(HTTP_POST, "/2/nodes/%s/evacuate" % node, query)
842 827

  
843 828
  def MigrateNode(self, node, live=True, dry_run=False):
844 829
    """Migrates all primary instances from a node.
......
860 845
    if dry_run:
861 846
      query.append(("dry-run", 1))
862 847

  
863
    return self._SendRequest(HTTP_POST, "/nodes/%s/migrate" % node, query)
848
    return self._SendRequest(HTTP_POST, "/2/nodes/%s/migrate" % node, query)
864 849

  
865 850
  def GetNodeRole(self, node):
866 851
    """Gets the current role for a node.
......
872 857
    @return: the current role for a node
873 858

  
874 859
    """
875
    return self._SendRequest(HTTP_GET, "/nodes/%s/role" % node)
860
    return self._SendRequest(HTTP_GET, "/2/nodes/%s/role" % node)
876 861

  
877 862
  def SetNodeRole(self, node, role, force=False):
878 863
    """Sets the role for a node.
......
894 879
      raise InvalidNodeRole("%s is not a valid node role.", role)
895 880

  
896 881
    query = [("force", force)]
897
    return self._SendRequest(HTTP_PUT, "/nodes/%s/role" % node, query,
882
    return self._SendRequest(HTTP_PUT, "/2/nodes/%s/role" % node, query,
898 883
                             content=role)
899 884

  
900 885
  def GetNodeStorageUnits(self, node, storage_type, output_fields):
......
918 903
      raise InvalidStorageType("%s is an invalid storage type.", storage_type)
919 904

  
920 905
    query = [("storage_type", storage_type), ("output_fields", output_fields)]
921
    return self._SendRequest(HTTP_GET, "/nodes/%s/storage" % node, query)
906
    return self._SendRequest(HTTP_GET, "/2/nodes/%s/storage" % node, query)
922 907

  
923 908
  def ModifyNodeStorageUnits(self, node, storage_type, name, allocatable=True):
924 909
    """Modifies parameters of storage units on the node.
......
945 930
        ("storage_type", storage_type), ("name", name),
946 931
        ("allocatable", allocatable)
947 932
        ]
948
    return self._SendRequest(HTTP_PUT, "/nodes/%s/storage/modify" % node, query)
933
    return self._SendRequest(HTTP_PUT, "/2/nodes/%s/storage/modify" % node,
934
                             query)
949 935

  
950 936
  def RepairNodeStorageUnits(self, node, storage_type, name):
951 937
    """Repairs a storage unit on the node.
......
967 953
      raise InvalidStorageType("%s is an invalid storage type.", storage_type)
968 954

  
969 955
    query = [("storage_type", storage_type), ("name", name)]
970
    return self._SendRequest(HTTP_PUT, "/nodes/%s/storage/repair" % node, query)
956
    return self._SendRequest(HTTP_PUT, "/2/nodes/%s/storage/repair" % node,
957
                             query)
971 958

  
972 959
  def GetNodeTags(self, node):
973 960
    """Gets the tags for a node.
......
979 966
    @return: tags for the node
980 967

  
981 968
    """
982
    return self._SendRequest(HTTP_GET, "/nodes/%s/tags" % node)
969
    return self._SendRequest(HTTP_GET, "/2/nodes/%s/tags" % node)
983 970

  
984 971
  def AddNodeTags(self, node, tags, dry_run=False):
985 972
    """Adds tags to a node.
......
999 986
    if dry_run:
1000 987
      query.append(("dry-run", 1))
1001 988

  
1002
    return self._SendRequest(HTTP_PUT, "/nodes/%s/tags" % node, query,
989
    return self._SendRequest(HTTP_PUT, "/2/nodes/%s/tags" % node, query,
1003 990
                             content=tags)
1004 991

  
1005 992
  def DeleteNodeTags(self, node, tags, dry_run=False):
......
1020 1007
    if dry_run:
1021 1008
      query.append(("dry-run", 1))
1022 1009

  
1023
    return self._SendRequest(HTTP_DELETE, "/nodes/%s/tags" % node, query)
1010
    return self._SendRequest(HTTP_DELETE, "/2/nodes/%s/tags" % node, query)

Also available in: Unified diff