image labels 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/c717e07f Tree: http://git-wip-us.apache.org/repos/asf/libcloud/tree/c717e07f Diff: http://git-wip-us.apache.org/repos/asf/libcloud/diff/c717e07f Branch: refs/heads/trunk Commit: c717e07f01dbb9ddb2cdff28368116d6c7c1a66b Parents: a94f928 Author: Eric Johnson <[email protected]> Authored: Thu Oct 26 17:05:44 2017 +0000 Committer: Eric Johnson <[email protected]> Committed: Tue Oct 31 15:54:01 2017 +0000 ---------------------------------------------------------------------- libcloud/compute/drivers/gce.py | 33 ++++++++++++++++++- .../gce/global_custom_image_setLabels_post.json | 15 +++++++++ .../compute/fixtures/gce/global_images.json | 30 +++++++++++++++-- ...perations_operation_setImageLabels_post.json | 15 +++++++++ libcloud/test/compute/test_gce.py | 34 +++++++++++++++++--- 5 files changed, 119 insertions(+), 8 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/libcloud/blob/c717e07f/libcloud/compute/drivers/gce.py ---------------------------------------------------------------------- diff --git a/libcloud/compute/drivers/gce.py b/libcloud/compute/drivers/gce.py index 21183a0..48154e6 100644 --- a/libcloud/compute/drivers/gce.py +++ b/libcloud/compute/drivers/gce.py @@ -1942,6 +1942,28 @@ class GCENodeDriver(NodeDriver): self.connection.async_request(request, method='POST', data=body) return True + def ex_set_image_labels(self, image, labels): + """ + Set labels for the specified image. + + :keyword image: The existing target Image for the request. + :type image: ``NodeImage`` + + :keyword labels: Set (or clear with None) labels for this image. + :type labels: ``dict`` or ``None`` + + :return: True if successful + :rtype: ``bool`` + """ + if not isinstance(image, NodeImage): + raise ValueError("Must specify a valid libcloud image object.") + image_name = image.name + current_fp = image.extra['labelFingerprint'] + body = {'labels': labels, 'labelFingerprint': current_fp} + request = '/global/%s/setLabels' % (image_name) + self.connection.async_request(request, method='POST', data=body) + return True + def ex_get_serial_output(self, node): """ Fetch the console/serial port output from the node. @@ -3241,7 +3263,8 @@ class GCENodeDriver(NodeDriver): def ex_create_image(self, name, volume, description=None, family=None, guest_os_features=None, use_existing=True, - wait_for_completion=True, ex_licenses=None): + wait_for_completion=True, ex_licenses=None, + ex_labels=None): """ Create an image from the provided volume. @@ -3270,6 +3293,9 @@ class GCENodeDriver(NodeDriver): to be associated with the image. :type ex_licenses: ``list`` of ``str`` + :keyword ex_labels: Labels dictionary for image. + :type ex_labels: ``dict`` or ``None`` + :keyword use_existing: If True and an image with the given name already exists, return an object for that image instead of attempting to create @@ -3304,6 +3330,9 @@ class GCENodeDriver(NodeDriver): ex_licenses = [ex_licenses] image_data['licenses'] = ex_licenses + if ex_labels: + image_data['labels'] = ex_labels + if guest_os_features: image_data['guestOsFeatures'] = [] if isinstance(guest_os_features, str): @@ -8387,6 +8416,8 @@ class GCENodeDriver(NodeDriver): if 'licenses' in image: lic_objs = self._licenses_from_urls(licenses=image['licenses']) extra['licenses'] = lic_objs + extra['labels'] = image.get('labels', None) + extra['labelFingerprint'] = image.get('labelFingerprint', None) return GCENodeImage(id=image['id'], name=image['name'], driver=self, extra=extra) http://git-wip-us.apache.org/repos/asf/libcloud/blob/c717e07f/libcloud/test/compute/fixtures/gce/global_custom_image_setLabels_post.json ---------------------------------------------------------------------- diff --git a/libcloud/test/compute/fixtures/gce/global_custom_image_setLabels_post.json b/libcloud/test/compute/fixtures/gce/global_custom_image_setLabels_post.json new file mode 100644 index 0000000..14ee486 --- /dev/null +++ b/libcloud/test/compute/fixtures/gce/global_custom_image_setLabels_post.json @@ -0,0 +1,15 @@ +{ + "endTime": "2013-06-26T10:05:07.630-07:00", + "id": "3681664092089171723", + "insertTime": "2013-06-26T10:05:03.271-07:00", + "kind": "compute#operation", + "name": "operation-setImageLabelspost", + "operationType": "insert", + "progress": 0, + "selfLink": "https://www.googleapis.com/compute/v1/projects/project_name/global/operations/operation-setImageLabels_post", + "startTime": "2013-06-26T10:05:03.315-07:00", + "status": "PENDING", + "targetId": "16211908079305042870", + "targetLink": "https://www.googleapis.com/compute/v1/projects/project_name/global/images/custom-image/setLabels", + "user": "[email protected]" +} http://git-wip-us.apache.org/repos/asf/libcloud/blob/c717e07f/libcloud/test/compute/fixtures/gce/global_images.json ---------------------------------------------------------------------- diff --git a/libcloud/test/compute/fixtures/gce/global_images.json b/libcloud/test/compute/fixtures/gce/global_images.json index 82f1ee2..1d9a048 100644 --- a/libcloud/test/compute/fixtures/gce/global_images.json +++ b/libcloud/test/compute/fixtures/gce/global_images.json @@ -4,12 +4,36 @@ "id": "projects/project_name/global/images", "items": [ { - + "kind": "compute#image", + "id": "7094983038334682865", + "creationTimestamp": "2017-10-26T07:58:38.442-07:00", + "name": "custom-image", + "description": "a custom image", + "sourceType": "RAW", + "status": "READY", + "archiveSizeBytes": "1314375168", + "diskSizeGb": "10", + "sourceDisk": "projects/project_name/zones/us-central1-b/disks/custom-instance", + "sourceDiskId": "3436116182804197834", + "family": "custom", + "selfLink": "projects/project_name/global/images/custom-image", + "labelFingerprint": "42WmSpB8rSM=", + "labels": { + "foo": "bar", + "one": "1", + "two": "two" + }, + "getResourceId": {}, + "getDisplayName": {}, + "getResourceType": {}, + "getFullResourcePath": {} + }, + { "kind": "compute#image", - "selfLink": "https://www.googleapis.com/compute/v1/projects/project_name/global/images/aws-ubuntu", + "selfLink": "https://www.googleapis.com/compute/v1/projects/project_name/global/images/custom-image", "id": "15632509721401584263", "creationTimestamp": "2014-12-09T09:26:27.234-08:00", - "name": "aws-ubuntu", + "name": "custom-image", "sourceType": "RAW", "rawDisk": { "source": "", http://git-wip-us.apache.org/repos/asf/libcloud/blob/c717e07f/libcloud/test/compute/fixtures/gce/global_operations_operation_setImageLabels_post.json ---------------------------------------------------------------------- diff --git a/libcloud/test/compute/fixtures/gce/global_operations_operation_setImageLabels_post.json b/libcloud/test/compute/fixtures/gce/global_operations_operation_setImageLabels_post.json new file mode 100644 index 0000000..326e959 --- /dev/null +++ b/libcloud/test/compute/fixtures/gce/global_operations_operation_setImageLabels_post.json @@ -0,0 +1,15 @@ +{ + "endTime": "2013-06-26T10:05:07.630-07:00", + "id": "3681664092089171723", + "insertTime": "2013-06-26T10:05:03.271-07:00", + "kind": "compute#operation", + "name": "operation-setImageLabelspost", + "operationType": "insert", + "progress": 100, + "selfLink": "https://www.googleapis.com/compute/v1/projects/project_name/global/operations/operation-setImageLabels_post", + "startTime": "2013-06-26T10:05:03.315-07:00", + "status": "DONE", + "targetId": "16211908079305042870", + "targetLink": "https://www.googleapis.com/compute/v1/projects/project_name/global/images/custom-image/setLabels", + "user": "[email protected]" +} http://git-wip-us.apache.org/repos/asf/libcloud/blob/c717e07f/libcloud/test/compute/test_gce.py ---------------------------------------------------------------------- diff --git a/libcloud/test/compute/test_gce.py b/libcloud/test/compute/test_gce.py index 0e54a76..3c38b98 100644 --- a/libcloud/test/compute/test_gce.py +++ b/libcloud/test/compute/test_gce.py @@ -361,11 +361,11 @@ class GCENodeDriverTest(GoogleTestCase, TestCaseMixin): debian_images = self.driver.list_images(ex_project='debian-cloud') local_plus_deb = self.driver.list_images( ['debian-cloud', 'project_name']) - self.assertEqual(len(local_images), 23) - self.assertEqual(len(all_deprecated_images), 158) + self.assertEqual(len(local_images), 24) + self.assertEqual(len(all_deprecated_images), 159) self.assertEqual(len(debian_images), 2) - self.assertEqual(len(local_plus_deb), 3) - self.assertEqual(local_images[0].name, 'aws-ubuntu') + self.assertEqual(len(local_plus_deb), 4) + self.assertEqual(local_images[0].name, 'custom-image') self.assertEqual(debian_images[1].name, 'debian-7-wheezy-v20131120') def test_ex_destroy_instancegroup(self): @@ -1906,6 +1906,21 @@ class GCENodeDriverTest(GoogleTestCase, TestCaseMixin): multilabels = {'item1': 'val1', 'item2': 'val2'} self.driver.ex_set_node_labels(node, multilabels) + def test_ex_set_image_labels(self): + image = self.driver.ex_get_image('custom-image') + # Test basic values + simplelabel = {'foo': 'bar'} + self.driver.ex_set_image_labels(image, simplelabel) + image = self.driver.ex_get_image('custom-image') + self.assertTrue('foo' in image.extra['labels']) + # Test multiple values + multilabels = {'one': '1', 'two': 'two'} + self.driver.ex_set_image_labels(image, multilabels) + image = self.driver.ex_get_image('custom-image') + self.assertEqual(len(image.extra['labels']), 3) + self.assertTrue('two' in image.extra['labels']) + self.assertTrue('two' in image.extra['labels']) + def test_ex_get_region(self): region_name = 'us-central1' region = self.driver.ex_get_region(region_name) @@ -2129,6 +2144,11 @@ class GCEMockHttp(MockHttp): 'zones_us_central1_a_instances_node_name_setLabels_post.json') return (httplib.OK, body, self.json_hdr, httplib.responses[httplib.OK]) + def _global_custom_image_setLabels(self, method, url, body, headers): + body = self.fixtures.load( + 'global_custom_image_setLabels_post.json') + return (httplib.OK, body, self.json_hdr, httplib.responses[httplib.OK]) + def _setCommonInstanceMetadata(self, method, url, body, headers): if method == 'POST': body = self.fixtures.load('setCommonInstanceMetadata_post.json') @@ -2610,6 +2630,12 @@ class GCEMockHttp(MockHttp): 'operations_operation_zones_us_central1_a_node_name_setLabels_post.json') return (httplib.OK, body, self.json_hdr, httplib.responses[httplib.OK]) + def _global_operations_operation_setImageLabels_post(self, method, url, + body, headers): + body = self.fixtures.load( + 'global_operations_operation_setImageLabels_post.json') + return (httplib.OK, body, self.json_hdr, httplib.responses[httplib.OK]) + def _zones_us_central1_a_operations_operation_zones_us_central1_a_targetInstances_post( self, method, url, body, headers): body = self.fixtures.load(
