Repository: libcloud Updated Branches: refs/heads/trunk 5072fc0de -> 5395ccf83
Add node stop/start support Closes #442 Signed-off-by: Eric Johnson <[email protected]> Project: http://git-wip-us.apache.org/repos/asf/libcloud/repo Commit: http://git-wip-us.apache.org/repos/asf/libcloud/commit/5395ccf8 Tree: http://git-wip-us.apache.org/repos/asf/libcloud/tree/5395ccf8 Diff: http://git-wip-us.apache.org/repos/asf/libcloud/diff/5395ccf8 Branch: refs/heads/trunk Commit: 5395ccf8333092a4180804ce38625a3ef7a39753 Parents: 5072fc0 Author: Eric Johnson <[email protected]> Authored: Fri Jan 30 22:29:54 2015 +0000 Committer: Eric Johnson <[email protected]> Committed: Mon Feb 2 18:10:06 2015 +0000 ---------------------------------------------------------------------- CHANGES.rst | 4 ++ libcloud/compute/drivers/gce.py | 30 ++++++++++++ ..._us_central1_a_instances_node_name_stop.json | 15 ++++++ ...es_us_central1_a_instances_stopped_node.json | 48 ++++++++++++++++++++ ...central1_a_instances_stopped_node_start.json | 15 ++++++ ..._central1_a_instances_stopped_node_stop.json | 15 ++++++ ...ntral1_a_operations_operation_startnode.json | 15 ++++++ ...entral1_a_operations_operation_stopnode.json | 15 ++++++ libcloud/test/compute/test_gce.py | 39 ++++++++++++++++ 9 files changed, 196 insertions(+) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/libcloud/blob/5395ccf8/CHANGES.rst ---------------------------------------------------------------------- diff --git a/CHANGES.rst b/CHANGES.rst index 991f790..5ac315d 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -16,6 +16,10 @@ General Compute ~~~~~~~ +- GCE driver updated to include ex_stop_node() and ex_start_node() methods + (GITHUB-442) + [Eric Johnson] + - GCE driver now raises ResourceNotFoundError when the specified image is not found in any image project. Previously, this would return None but now raises the not-found exception instead. This fixes a bug where returning http://git-wip-us.apache.org/repos/asf/libcloud/blob/5395ccf8/libcloud/compute/drivers/gce.py ---------------------------------------------------------------------- diff --git a/libcloud/compute/drivers/gce.py b/libcloud/compute/drivers/gce.py index 1778818..1f29601 100644 --- a/libcloud/compute/drivers/gce.py +++ b/libcloud/compute/drivers/gce.py @@ -3447,6 +3447,36 @@ n self.connection.async_request(request, method='DELETE') return True + def ex_start_node(self, node): + """ + Start a node that is stopped and in TERMINATED state. + + :param node: Node object to start + :type node: :class:`Node` + + :return: True if successful + :rtype: ``bool`` + """ + request = '/zones/%s/instances/%s/start' % (node.extra['zone'].name, + node.name) + self.connection.async_request(request, method='POST') + return True + + def ex_stop_node(self, node): + """ + Stop a running node. + + :param node: Node object to stop + :type node: :class:`Node` + + :return: True if successful + :rtype: ``bool`` + """ + request = '/zones/%s/instances/%s/stop' % (node.extra['zone'].name, + node.name) + self.connection.async_request(request, method='POST') + return True + def destroy_node(self, node, destroy_boot_disk=False): """ Destroy a node. http://git-wip-us.apache.org/repos/asf/libcloud/blob/5395ccf8/libcloud/test/compute/fixtures/gce/zones_us_central1_a_instances_node_name_stop.json ---------------------------------------------------------------------- diff --git a/libcloud/test/compute/fixtures/gce/zones_us_central1_a_instances_node_name_stop.json b/libcloud/test/compute/fixtures/gce/zones_us_central1_a_instances_node_name_stop.json new file mode 100644 index 0000000..e68e06a --- /dev/null +++ b/libcloud/test/compute/fixtures/gce/zones_us_central1_a_instances_node_name_stop.json @@ -0,0 +1,15 @@ +{ + "kind": "compute#operation", + "id": "18431811683007150988", + "name": "operation-stopnode", + "zone": "https://www.googleapis.com/compute/v1/projects/project_name/zones/us-central1-a", + "operationType": "stop", + "targetLink": "https://www.googleapis.com/compute/v1/projects/project_name/zones/us-central1-a/instances/node-name", + "targetId": "12335588484913203363", + "status": "PENDING", + "user": "[email protected]", + "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-stopnode" +} http://git-wip-us.apache.org/repos/asf/libcloud/blob/5395ccf8/libcloud/test/compute/fixtures/gce/zones_us_central1_a_instances_stopped_node.json ---------------------------------------------------------------------- diff --git a/libcloud/test/compute/fixtures/gce/zones_us_central1_a_instances_stopped_node.json b/libcloud/test/compute/fixtures/gce/zones_us_central1_a_instances_stopped_node.json new file mode 100644 index 0000000..a47c75f --- /dev/null +++ b/libcloud/test/compute/fixtures/gce/zones_us_central1_a_instances_stopped_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": "stopped-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/stopped-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/5395ccf8/libcloud/test/compute/fixtures/gce/zones_us_central1_a_instances_stopped_node_start.json ---------------------------------------------------------------------- diff --git a/libcloud/test/compute/fixtures/gce/zones_us_central1_a_instances_stopped_node_start.json b/libcloud/test/compute/fixtures/gce/zones_us_central1_a_instances_stopped_node_start.json new file mode 100644 index 0000000..d531709 --- /dev/null +++ b/libcloud/test/compute/fixtures/gce/zones_us_central1_a_instances_stopped_node_start.json @@ -0,0 +1,15 @@ +{ + "kind": "compute#operation", + "id": "18431811683007150988", + "name": "operation-startnode", + "zone": "https://www.googleapis.com/compute/v1/projects/project_name/zones/us-central1-a", + "operationType": "start", + "targetLink": "https://www.googleapis.com/compute/v1/projects/project_name/zones/us-central1-a/instances/stopped-node", + "targetId": "12335588484913203363", + "status": "PENDING", + "user": "[email protected]", + "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-startnode" +} http://git-wip-us.apache.org/repos/asf/libcloud/blob/5395ccf8/libcloud/test/compute/fixtures/gce/zones_us_central1_a_instances_stopped_node_stop.json ---------------------------------------------------------------------- diff --git a/libcloud/test/compute/fixtures/gce/zones_us_central1_a_instances_stopped_node_stop.json b/libcloud/test/compute/fixtures/gce/zones_us_central1_a_instances_stopped_node_stop.json new file mode 100644 index 0000000..5febcc6 --- /dev/null +++ b/libcloud/test/compute/fixtures/gce/zones_us_central1_a_instances_stopped_node_stop.json @@ -0,0 +1,15 @@ +{ + "kind": "compute#operation", + "id": "18431811683007150988", + "name": "operation-stopnode", + "zone": "https://www.googleapis.com/compute/v1/projects/project_name/zones/us-central1-a", + "operationType": "stop", + "targetLink": "https://www.googleapis.com/compute/v1/projects/project_name/zones/us-central1-a/instances/stopped-node", + "targetId": "12335588484913203363", + "status": "PENDING", + "user": "[email protected]", + "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-stopnode" +} http://git-wip-us.apache.org/repos/asf/libcloud/blob/5395ccf8/libcloud/test/compute/fixtures/gce/zones_us_central1_a_operations_operation_startnode.json ---------------------------------------------------------------------- diff --git a/libcloud/test/compute/fixtures/gce/zones_us_central1_a_operations_operation_startnode.json b/libcloud/test/compute/fixtures/gce/zones_us_central1_a_operations_operation_startnode.json new file mode 100644 index 0000000..68276b2 --- /dev/null +++ b/libcloud/test/compute/fixtures/gce/zones_us_central1_a_operations_operation_startnode.json @@ -0,0 +1,15 @@ +{ + "kind": "compute#operation", + "id": "18431811683007150988", + "name": "operation-startnode", + "zone": "https://www.googleapis.com/compute/v1/projects/project_name/zones/us-central1-a", + "operationType": "start", + "targetLink": "https://www.googleapis.com/compute/v1/projects/project_name/zones/us-central1-a/instances/stopped-node", + "targetId": "12335588484913203363", + "status": "DONE", + "user": "[email protected]", + "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-startnode" +} http://git-wip-us.apache.org/repos/asf/libcloud/blob/5395ccf8/libcloud/test/compute/fixtures/gce/zones_us_central1_a_operations_operation_stopnode.json ---------------------------------------------------------------------- diff --git a/libcloud/test/compute/fixtures/gce/zones_us_central1_a_operations_operation_stopnode.json b/libcloud/test/compute/fixtures/gce/zones_us_central1_a_operations_operation_stopnode.json new file mode 100644 index 0000000..30275b6 --- /dev/null +++ b/libcloud/test/compute/fixtures/gce/zones_us_central1_a_operations_operation_stopnode.json @@ -0,0 +1,15 @@ +{ + "kind": "compute#operation", + "id": "18431811683007150988", + "name": "operation-stopnode", + "zone": "https://www.googleapis.com/compute/v1/projects/project_name/zones/us-central1-a", + "operationType": "stop", + "targetLink": "https://www.googleapis.com/compute/v1/projects/project_name/zones/us-central1-a/instances/node-name", + "targetId": "12335588484913203363", + "status": "DONE", + "user": "[email protected]", + "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-stopnode" +} http://git-wip-us.apache.org/repos/asf/libcloud/blob/5395ccf8/libcloud/test/compute/test_gce.py ---------------------------------------------------------------------- diff --git a/libcloud/test/compute/test_gce.py b/libcloud/test/compute/test_gce.py index 35ec80f..3b2c34e 100644 --- a/libcloud/test/compute/test_gce.py +++ b/libcloud/test/compute/test_gce.py @@ -443,6 +443,21 @@ class GCENodeDriverTest(LibcloudTestCase, TestCaseMixin): self.assertEqual(network.name, network_name) self.assertEqual(network.cidr, cidr) + def test_ex_node_start(self): + zone = 'us-central1-a' + node = self.driver.ex_get_node('stopped-node', zone) + self.assertTrue(self.driver.ex_start_node(node)) + + def test_ex_node_stop(self): + zone = 'us-central1-a' + node = self.driver.ex_get_node('node-name', zone) + self.assertTrue(self.driver.ex_stop_node(node)) + + # try and stop a stopped node (should work) + zone = 'us-central1-a' + node = self.driver.ex_get_node('stopped-node', zone) + self.assertTrue(self.driver.ex_stop_node(node)) + def test_create_node_req(self): image = self.driver.ex_get_image('debian-7') size = self.driver.ex_get_size('n1-standard-1') @@ -1314,6 +1329,30 @@ 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_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]) + + def _zones_us_central1_a_instances_stopped_node_start(self, method, url, body, header): + body = self.fixtures.load('zones_us_central1_a_instances_stopped_node_start.json') + return (httplib.OK, body, self.json_hdr, httplib.responses[httplib.OK]) + + def _zones_us_central1_a_instances_stopped_node_stop(self, method, url, body, header): + body = self.fixtures.load('zones_us_central1_a_instances_stopped_node_stop.json') + return (httplib.OK, body, self.json_hdr, httplib.responses[httplib.OK]) + + def _zones_us_central1_a_instances_stopped_node(self, method, url, body, headers): + body = self.fixtures.load('zones_us_central1_a_instances_stopped_node.json') + return (httplib.OK, body, self.json_hdr, httplib.responses[httplib.OK]) + + def _zones_us_central1_a_operations_operation_stopnode(self, method, url, body, headers): + body = self.fixtures.load('zones_us_central1_a_operations_operation_stopnode.json') + return (httplib.OK, body, self.json_hdr, httplib.responses[httplib.OK]) + + def _zones_us_central1_a_instances_node_name_stop(self, method, url, body, headers): + body = self.fixtures.load('zones_us_central1_a_instances_node_name_stop.json') + return (httplib.OK, body, self.json_hdr, httplib.responses[httplib.OK]) + def _zones_us_central1_a_instances_node_name_setMetadata(self, method, url, body, headers): body = self.fixtures.load('zones_us_central1_a_instances_node_name_setMetadata_post.json') return (httplib.OK, body, self.json_hdr, httplib.responses[httplib.OK])
