You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@libcloud.apache.org by er...@apache.org on 2016/03/07 19:27:42 UTC

libcloud git commit: [google compute] Added setMachineType method to allow for changing sizes of instances

Repository: libcloud
Updated Branches:
  refs/heads/trunk 3aebd5b8b -> 6f3279c74


[google compute] Added setMachineType method to allow for changing sizes of instances

Closes #721

Signed-off-by: Eric Johnson <er...@google.com>


Project: http://git-wip-us.apache.org/repos/asf/libcloud/repo
Commit: http://git-wip-us.apache.org/repos/asf/libcloud/commit/6f3279c7
Tree: http://git-wip-us.apache.org/repos/asf/libcloud/tree/6f3279c7
Diff: http://git-wip-us.apache.org/repos/asf/libcloud/diff/6f3279c7

Branch: refs/heads/trunk
Commit: 6f3279c74d08daaaed60958e629baab1fe330a68
Parents: 3aebd5b
Author: Eric Johnson <er...@google.com>
Authored: Mon Mar 7 17:56:16 2016 +0000
Committer: Eric Johnson <er...@google.com>
Committed: Mon Mar 7 18:26:55 2016 +0000

----------------------------------------------------------------------
 CHANGES.rst                                     |  4 ++
 demos/gce_demo.py                               | 10 ++++
 libcloud/compute/drivers/gce.py                 | 24 ++++++++
 ...nes_us_central1_a_instances_custom_node.json | 48 +++++++++++++++
 ...l1_a_instances_node_name_setMachineType.json | 15 +++++
 ...a_instances_stopped_node_setMachineType.json | 15 +++++
 ...1_a_operations_operation_setMachineType.json | 15 +++++
 ...ons_operation_setMachineType_notstopped.json | 26 ++++++++
 libcloud/test/compute/test_gce.py               | 63 +++++++++++++++++++-
 9 files changed, 219 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/libcloud/blob/6f3279c7/CHANGES.rst
----------------------------------------------------------------------
diff --git a/CHANGES.rst b/CHANGES.rst
index 866613d..9ba7997 100644
--- a/CHANGES.rst
+++ b/CHANGES.rst
@@ -32,6 +32,10 @@ General
 Compute
 ~~~~~~~
 
+- [google compute] Added setMachineType method to allow for changing sizes of instances
+  (GITHUB-721)
+  [Eric Johnson]
+
 - [google compute] allow bypassing image search in standard project list
   (GITHUB-713)
   [Max Illfelder]

http://git-wip-us.apache.org/repos/asf/libcloud/blob/6f3279c7/demos/gce_demo.py
----------------------------------------------------------------------
diff --git a/demos/gce_demo.py b/demos/gce_demo.py
index c755a18..aae7093 100755
--- a/demos/gce_demo.py
+++ b/demos/gce_demo.py
@@ -362,6 +362,16 @@ def main_compute():
                                  ex_disk_auto_delete=False)
         display('  Node %s created' % name)
 
+        # Stop the node and change to a custom machine type (e.g. size)
+        display('Stopping node, setting custom size, starting node:')
+        name = '%s-np-node' % DEMO_BASE_NAME
+        gce.ex_stop_node(node_1)
+        gce.ex_set_machine_type(node_1, 'custom-2-4096')   # 2 vCPU, 4GB RAM
+        gce.ex_start_node(node_1)
+        node_1 = gce.ex_get_node(name)
+        display('  %s: state=%s, size=%s' % (name, node_1.extra['status'],
+                                             node_1.size))
+
         # == Create, and attach a disk ==
         display('Creating a new disk:')
         disk_name = '%s-attach-disk' % DEMO_BASE_NAME

http://git-wip-us.apache.org/repos/asf/libcloud/blob/6f3279c7/libcloud/compute/drivers/gce.py
----------------------------------------------------------------------
diff --git a/libcloud/compute/drivers/gce.py b/libcloud/compute/drivers/gce.py
index 7b4960d..14e10ab 100644
--- a/libcloud/compute/drivers/gce.py
+++ b/libcloud/compute/drivers/gce.py
@@ -3685,6 +3685,30 @@ class GCENodeDriver(NodeDriver):
         self.connection.async_request(request, method='DELETE')
         return True
 
+    def ex_set_machine_type(self, node, machine_type='n1-standard-1'):
+        """
+        Set the machine type of the stopped instance. Can be the short-name,
+        a full, or partial URL.
+
+        :param  node: Target node object to change
+        :type   node: :class:`Node`
+
+        :param  machine_type: Desired machine type
+        :type   machine_type: ``str``
+
+        :return:  True if successful
+        :rtype:   ``bool``
+        """
+        request = mt_url = '/zones/%s' % node.extra['zone'].name
+
+        mt = machine_type.split('/')[-1]
+        mt_url = '%s/machineTypes/%s' % (mt_url, mt)
+
+        request = '%s/instances/%s/setMachineType' % (request, node.name)
+        body = {"machineType": mt_url}
+        self.connection.async_request(request, method='POST', data=body)
+        return True
+
     def ex_start_node(self, node):
         """
         Start a node that is stopped and in TERMINATED state.

http://git-wip-us.apache.org/repos/asf/libcloud/blob/6f3279c7/libcloud/test/compute/fixtures/gce/zones_us_central1_a_instances_custom_node.json
----------------------------------------------------------------------
diff --git a/libcloud/test/compute/fixtures/gce/zones_us_central1_a_instances_custom_node.json b/libcloud/test/compute/fixtures/gce/zones_us_central1_a_instances_custom_node.json
new file mode 100644
index 0000000..bb0153d
--- /dev/null
+++ b/libcloud/test/compute/fixtures/gce/zones_us_central1_a_instances_custom_node.json
@@ -0,0 +1,48 @@
+{
+  "canIpForward": false,
+  "creationTimestamp": "2013-12-13T10:45:23.351-08:00",
+  "disks": [
+    {
+      "boot": true,
+      "deviceName": "persistent-disk-0",
+      "index": 0,
+      "kind": "compute#attachedDisk",
+      "mode": "READ_WRITE",
+      "source": "https://www.googleapis.com/compute/v1/projects/project_name/zones/us-central1-a/disks/lcdisk",
+      "type": "PERSISTENT"
+    }
+  ],
+  "id": "4006034190819017667",
+  "kind": "compute#instance",
+  "machineType": "https://www.googleapis.com/compute/v1/projects/project_name/zones/us-central1-a/machineTypes/n1-standard-1",
+  "metadata": {
+    "fingerprint": "42WmSpB8rSM=",
+    "kind": "compute#metadata"
+  },
+  "name": "custom-node",
+  "networkInterfaces": [
+    {
+      "accessConfigs": [
+        {
+          "kind": "compute#accessConfig",
+          "name": "External NAT",
+          "natIP": "23.236.58.15",
+          "type": "ONE_TO_ONE_NAT"
+        }
+      ],
+      "name": "nic0",
+      "network": "https://www.googleapis.com/compute/v1/projects/project_name/global/networks/default",
+      "networkIP": "10.240.72.75"
+    }
+  ],
+  "scheduling": {
+    "automaticRestart": true,
+    "onHostMaintenance": "MIGRATE"
+  },
+  "selfLink": "https://www.googleapis.com/compute/v1/projects/project_name/zones/us-central1-a/instances/custom-node",
+  "status": "TERMINATED",
+  "tags": {
+    "fingerprint": "42WmSpB8rSM="
+  },
+  "zone": "https://www.googleapis.com/compute/v1/projects/project_name/zones/us-central1-a"
+}

http://git-wip-us.apache.org/repos/asf/libcloud/blob/6f3279c7/libcloud/test/compute/fixtures/gce/zones_us_central1_a_instances_node_name_setMachineType.json
----------------------------------------------------------------------
diff --git a/libcloud/test/compute/fixtures/gce/zones_us_central1_a_instances_node_name_setMachineType.json b/libcloud/test/compute/fixtures/gce/zones_us_central1_a_instances_node_name_setMachineType.json
new file mode 100644
index 0000000..2d1b397
--- /dev/null
+++ b/libcloud/test/compute/fixtures/gce/zones_us_central1_a_instances_node_name_setMachineType.json
@@ -0,0 +1,15 @@
+{
+ "kind": "compute#operation",
+ "id": "18431811683007150988",
+ "name": "operation-setMachineType-notstopped",
+ "zone": "https://www.googleapis.com/compute/v1/projects/project_name/zones/us-central1-a",
+ "operationType": "setMachineType",
+ "targetLink": "https://www.googleapis.com/compute/v1/projects/project_name/zones/us-central1-a/instances/node-name",
+ "targetId": "12335588484913203363",
+ "status": "PENDING",
+ "user": "erjohnso@google.com",
+ "progress": 0,
+ "insertTime": "2015-01-30T06:55:11.503-08:00",
+ "startTime": "2015-01-30T06:55:11.847-08:00",
+ "selfLink": "https://www.googleapis.com/compute/v1/projects/project_name/zones/us-central1-a/operations/operation-setMachineType-notstopped"
+}

http://git-wip-us.apache.org/repos/asf/libcloud/blob/6f3279c7/libcloud/test/compute/fixtures/gce/zones_us_central1_a_instances_stopped_node_setMachineType.json
----------------------------------------------------------------------
diff --git a/libcloud/test/compute/fixtures/gce/zones_us_central1_a_instances_stopped_node_setMachineType.json b/libcloud/test/compute/fixtures/gce/zones_us_central1_a_instances_stopped_node_setMachineType.json
new file mode 100644
index 0000000..c1e0622
--- /dev/null
+++ b/libcloud/test/compute/fixtures/gce/zones_us_central1_a_instances_stopped_node_setMachineType.json
@@ -0,0 +1,15 @@
+{
+ "kind": "compute#operation",
+ "id": "18431811683007150988",
+ "name": "operation-setMachineType",
+ "zone": "https://www.googleapis.com/compute/v1/projects/project_name/zones/us-central1-a",
+ "operationType": "setMachineType",
+ "targetLink": "https://www.googleapis.com/compute/v1/projects/project_name/zones/us-central1-a/instances/stopped-node",
+ "targetId": "12335588484913203363",
+ "status": "PENDING",
+ "user": "erjohnso@google.com",
+ "progress": 0,
+ "insertTime": "2015-01-30T06:55:11.503-08:00",
+ "startTime": "2015-01-30T06:55:11.847-08:00",
+ "selfLink": "https://www.googleapis.com/compute/v1/projects/project_name/zones/us-central1-a/operations/operation-setMachineType"
+}

http://git-wip-us.apache.org/repos/asf/libcloud/blob/6f3279c7/libcloud/test/compute/fixtures/gce/zones_us_central1_a_operations_operation_setMachineType.json
----------------------------------------------------------------------
diff --git a/libcloud/test/compute/fixtures/gce/zones_us_central1_a_operations_operation_setMachineType.json b/libcloud/test/compute/fixtures/gce/zones_us_central1_a_operations_operation_setMachineType.json
new file mode 100644
index 0000000..fcea412
--- /dev/null
+++ b/libcloud/test/compute/fixtures/gce/zones_us_central1_a_operations_operation_setMachineType.json
@@ -0,0 +1,15 @@
+{
+ "kind": "compute#operation",
+ "id": "18431811683007150988",
+ "name": "operation-setMachineType",
+ "zone": "https://www.googleapis.com/compute/v1/projects/project_name/zones/us-central1-a",
+ "operationType": "setMachineType",
+ "targetLink": "https://www.googleapis.com/compute/v1/projects/project_name/zones/us-central1-a/instances/stopped-node",
+ "targetId": "12335588484913203363",
+ "status": "DONE",
+ "user": "erjohnso@google.com",
+ "progress": 100,
+ "insertTime": "2015-01-30T06:55:11.503-08:00",
+ "startTime": "2015-01-30T06:55:11.847-08:00",
+ "selfLink": "https://www.googleapis.com/compute/v1/projects/project_name/zones/us-central1-a/operations/operation-setMachineType"
+}

http://git-wip-us.apache.org/repos/asf/libcloud/blob/6f3279c7/libcloud/test/compute/fixtures/gce/zones_us_central1_a_operations_operation_setMachineType_notstopped.json
----------------------------------------------------------------------
diff --git a/libcloud/test/compute/fixtures/gce/zones_us_central1_a_operations_operation_setMachineType_notstopped.json b/libcloud/test/compute/fixtures/gce/zones_us_central1_a_operations_operation_setMachineType_notstopped.json
new file mode 100644
index 0000000..234e272
--- /dev/null
+++ b/libcloud/test/compute/fixtures/gce/zones_us_central1_a_operations_operation_setMachineType_notstopped.json
@@ -0,0 +1,26 @@
+{
+ "kind": "compute#operation",
+ "id": "1122640775725896976",
+ "name": "operation-setMachineType-notstopped",
+ "zone": "https://content.googleapis.com/compute/v1/projects/project_name/zones/us-central1-a",
+ "operationType": "setMachineType",
+ "targetLink": "https://content.googleapis.com/compute/v1/projects/project_name/zones/us-central1-a/instances/node-name",
+ "targetId": "10940055899777330894",
+ "status": "DONE",
+ "user": "erjohnso@google.com",
+ "progress": 100,
+ "insertTime": "2016-03-07T08:09:34.445-08:00",
+ "startTime": "2016-03-07T08:09:34.679-08:00",
+ "endTime": "2016-03-07T08:09:35.161-08:00",
+ "error": {
+  "errors": [
+   {
+    "code": "RESOURCE_NOT_READY",
+    "message": "The resource 'projects/project_name/zones/us-central1-a/instances/node-name' is not ready"
+   }
+  ]
+ },
+ "httpErrorStatusCode": 400,
+ "httpErrorMessage": "BAD REQUEST",
+ "selfLink": "https://content.googleapis.com/compute/v1/projects/project_name/zones/us-central1-a/operations/operation-setMachineType-notstopped"
+}

http://git-wip-us.apache.org/repos/asf/libcloud/blob/6f3279c7/libcloud/test/compute/test_gce.py
----------------------------------------------------------------------
diff --git a/libcloud/test/compute/test_gce.py b/libcloud/test/compute/test_gce.py
index ef6a158..162a756 100644
--- a/libcloud/test/compute/test_gce.py
+++ b/libcloud/test/compute/test_gce.py
@@ -29,7 +29,8 @@ from libcloud.compute.drivers.gce import (GCENodeDriver, API_VERSION,
                                           GCETargetHttpProxy, GCEUrlMap,
                                           GCEZone)
 from libcloud.common.google import (GoogleBaseAuthConnection,
-                                    ResourceNotFoundError, ResourceExistsError)
+                                    ResourceNotFoundError, ResourceExistsError,
+                                    InvalidRequestError, GoogleBaseError)
 from libcloud.test.common.test_google import GoogleAuthMockHttp, GoogleTestCase
 from libcloud.compute.base import Node, StorageVolume
 
@@ -478,6 +479,28 @@ class GCENodeDriverTest(GoogleTestCase, TestCaseMixin):
         self.assertEqual(network.name, network_name)
         self.assertEqual(network.cidr, cidr)
 
+    def test_ex_set_machine_type_notstopped(self):
+        # get running node, change machine type
+        zone = 'us-central1-a'
+        node = self.driver.ex_get_node('node-name', zone)
+        self.assertRaises(GoogleBaseError, self.driver.ex_set_machine_type,
+                          node, 'custom-4-61440')
+
+    def test_ex_set_machine_type_invalid(self):
+        # get stopped node, change machine type
+        zone = 'us-central1-a'
+        node = self.driver.ex_get_node('custom-node', zone)
+        self.assertRaises(InvalidRequestError, self.driver.ex_set_machine_type,
+                          node, 'custom-1-61440')
+
+    def test_ex_set_machine_type(self):
+        # get stopped node, change machine type
+        zone = 'us-central1-a'
+        node = self.driver.ex_get_node('stopped-node', zone)
+        self.assertEqual(node.size, 'n1-standard-1')
+        self.assertEqual(node.extra['status'], 'TERMINATED')
+        self.assertTrue(self.driver.ex_set_machine_type(node, 'custom-4-11264'))
+
     def test_ex_node_start(self):
         zone = 'us-central1-a'
         node = self.driver.ex_get_node('stopped-node', zone)
@@ -1414,6 +1437,44 @@ class GCEMockHttp(MockHttpTestCase):
             body = self.fixtures.load('setUsageExportBucket_post.json')
         return (httplib.OK, body, self.json_hdr, httplib.responses[httplib.OK])
 
+    def _zones_us_central1_a_instances_custom_node(self, method, url, body, header):
+        body = self.fixtures.load('zones_us_central1_a_instances_custom_node.json')
+        return (httplib.OK, body, self.json_hdr, httplib.responses[httplib.OK])
+
+    def _zones_us_central1_a_instances_node_name_setMachineType(self, method, url, body, header):
+        body = self.fixtures.load('zones_us_central1_a_instances_node_name_setMachineType.json')
+        return (httplib.OK, body, self.json_hdr, httplib.responses[httplib.OK])
+
+    def _zones_us_central1_a_operations_operation_setMachineType_notstopped(self, method, url, body, header):
+        body = self.fixtures.load('zones_us_central1_a_operations_operation_setMachineType_notstopped.json')
+        return (httplib.OK, body, self.json_hdr, httplib.responses[httplib.OK])
+
+    def _zones_us_central1_a_instances_custom_node_setMachineType(self, method, url, body, header):
+        body = {
+            "error": {
+                "errors": [
+                    {
+                        "domain": "global",
+                        "reason": "invalid",
+                        "message": "Invalid value for field 'resource.machineTypes': "
+                                   "'projects/project_name/zones/us-central1-a/machineTypes/custom-1-61440'.  Resource was not found.",
+                    }
+                ],
+                "code": 400,
+                "message": "Invalid value for field 'resource.machineTypes': "
+                           "'projects/project_name/zones/us-central1-a/machineTypes/custom-1-61440'.  Resource was not found."
+            }
+        }
+        return (httplib.BAD_REQUEST, body, self.json_hdr, httplib.responses[httplib.BAD_REQUEST])
+
+    def _zones_us_central1_a_instances_stopped_node_setMachineType(self, method, url, body, header):
+        body = self.fixtures.load('zones_us_central1_a_instances_stopped_node_setMachineType.json')
+        return (httplib.OK, body, self.json_hdr, httplib.responses[httplib.OK])
+
+    def _zones_us_central1_a_operations_operation_setMachineType(self, method, url, body, header):
+        body = self.fixtures.load('zones_us_central1_a_operations_operation_setMachineType.json')
+        return (httplib.OK, body, self.json_hdr, httplib.responses[httplib.OK])
+
     def _zones_us_central1_a_operations_operation_startnode(self, method, url, body, header):
         body = self.fixtures.load('zones_us_central1_a_operations_operation_startnode.json')
         return (httplib.OK, body, self.json_hdr, httplib.responses[httplib.OK])