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 2014/12/21 18:10:54 UTC

libcloud git commit: [google compute] Add License resource to GCE driver Closes #420

Repository: libcloud
Updated Branches:
  refs/heads/trunk d8740d0af -> 0486f77e7


[google compute] Add License resource to GCE driver
Closes #420

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/0486f77e
Tree: http://git-wip-us.apache.org/repos/asf/libcloud/tree/0486f77e
Diff: http://git-wip-us.apache.org/repos/asf/libcloud/diff/0486f77e

Branch: refs/heads/trunk
Commit: 0486f77e7b3c6a70ce11fff45401b8d3767876bc
Parents: d8740d0
Author: Eric Johnson <er...@google.com>
Authored: Fri Dec 19 20:46:38 2014 +0000
Committer: Eric Johnson <er...@google.com>
Committed: Sun Dec 21 17:09:58 2014 +0000

----------------------------------------------------------------------
 CHANGES.rst                                     |   4 +
 libcloud/compute/drivers/gce.py                 |  82 +++++++++-
 .../gce/projects_suse-cloud_global_images.json  | 160 +++++++++++++++++++
 ...ects_suse-cloud_global_licenses_sles_11.json |   6 +
 ...ects_suse-cloud_global_licenses_sles_12.json |   6 +
 libcloud/test/compute/test_gce.py               |  23 +++
 6 files changed, 279 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/libcloud/blob/0486f77e/CHANGES.rst
----------------------------------------------------------------------
diff --git a/CHANGES.rst b/CHANGES.rst
index 008d836..7ce653c 100644
--- a/CHANGES.rst
+++ b/CHANGES.rst
@@ -16,6 +16,10 @@ General
 Compute
 ~~~~~~~
 
+- GCE Licenses added to the GCE driver.
+  (GITHUB-420)
+  [Eric Johnson]
+
 - GCE Projects support common instance metadata and usage export buckets
   (GITHUB-409)
   [Eric Johnson]

http://git-wip-us.apache.org/repos/asf/libcloud/blob/0486f77e/libcloud/compute/drivers/gce.py
----------------------------------------------------------------------
diff --git a/libcloud/compute/drivers/gce.py b/libcloud/compute/drivers/gce.py
index f44945e..a63c996 100644
--- a/libcloud/compute/drivers/gce.py
+++ b/libcloud/compute/drivers/gce.py
@@ -77,6 +77,21 @@ class GCEConnection(GoogleBaseConnection):
                                                          project)
 
 
+class GCELicense(UuidMixin):
+    """A GCE License used to track software usage in GCE nodes."""
+    def __init__(self, id, name, driver, charges_use_fee, extra=None):
+        self.id = str(id)
+        self.name = name
+        self.driver = driver
+        self.charges_use_fee = charges_use_fee
+        self.extra = extra or {}
+        UuidMixin.__init__(self)
+
+    def __repr__(self):
+        return '<GCELicense id="%s" name="%s" charges_use_fee="%s">' % (
+            self.id, self.name, self.charges_use_fee)
+
+
 class GCEDiskType(UuidMixin):
     """A GCE DiskType resource."""
     def __init__(self, id, name, zone, driver, extra=None):
@@ -3059,6 +3074,29 @@ class GCENodeDriver(NodeDriver):
         self.connection.async_request(request, method='DELETE')
         return True
 
+    def ex_get_license(self, project, name):
+        """
+        Return a License object for specified project and name.
+
+        :param  name: The project to reference when looking up the license.
+        :type   name: ``str``
+
+        :param  name: The name of the License
+        :type   name: ``str``
+
+        :return:  A DiskType object for the name
+        :rtype:   :class:`GCEDiskType`
+        """
+        saved_request_path = self.connection.request_path
+        new_request_path = saved_request_path.replace(self.project, project)
+        self.connection.request_path = new_request_path
+
+        request = '/global/licenses/%s' % (name)
+        response = self.connection.request(request, method='GET').object
+        self.connection.request_path = saved_request_path
+
+        return self._to_license(response)
+
     def ex_get_disktype(self, name, zone=None):
         """
         Return a DiskType object based on a name and optional zone.
@@ -4158,7 +4196,8 @@ class GCENodeDriver(NodeDriver):
         if 'sourceDiskId' in image:
             extra['sourceDiskId'] = image.get('sourceDiskId', None)
         if 'licenses' in image:
-            extra['licenses'] = image.get('licenses', None)
+            lic_objs = self._licenses_from_urls(licenses=image['licenses'])
+            extra['licenses'] = lic_objs
 
         return GCENodeImage(id=image['id'], name=image['name'], driver=self,
                             extra=extra)
@@ -4336,7 +4375,8 @@ class GCENodeDriver(NodeDriver):
         if 'storageBytesStatus' in snapshot:
             extra['storageBytesStatus'] = snapshot['storageBytesStatus']
         if 'licenses' in snapshot:
-            extra['licenses'] = snapshot['licenses']
+            lic_objs = self._licenses_from_urls(licenses=snapshot['licenses'])
+            extra['licenses'] = lic_objs
 
         return GCESnapshot(id=snapshot['id'], name=snapshot['name'],
                            size=snapshot['diskSizeGb'],
@@ -4453,6 +4493,24 @@ class GCENodeDriver(NodeDriver):
                        maintenance_windows=zone.get('maintenanceWindows'),
                        deprecated=deprecated, driver=self, extra=extra)
 
+    def _to_license(self, license):
+        """
+        Return a License object from the json-response dictionary.
+
+        :param  license: The dictionary describing the license.
+        :type   license: ``dict``
+
+        :return: License object
+        :rtype: :class:`GCELicense`
+        """
+        extra = {}
+        extra['selfLink'] = license.get('selfLink')
+        extra['kind'] = license.get('kind')
+
+        return GCELicense(id=license['name'], name=license['name'],
+                          charges_use_fee=license['chargesUseFee'],
+                          driver=self, extra=extra)
+
     def _set_project_metadata(self, metadata=None, force=False,
                               current_keys=""):
         """
@@ -4497,3 +4555,23 @@ class GCENodeDriver(NodeDriver):
                 new_md = updated_md
                 new_md.append({'key': 'sshKeys', 'value': current_keys})
         return new_md
+
+    def _licenses_from_urls(self, licenses):
+        """
+        Convert a list of license selfLinks into a list of :class:`GCELicense`
+        objects.
+
+        :param  licenses: A list of GCE license selfLink URLs.
+        :type   licenses: ``list`` of ``str``
+
+        :return: List of :class:`GCELicense` objects.
+        :rtype:  ``list``
+        """
+        return_list = []
+        for license in licenses:
+            selfLink_parts = license.split('/')
+            lic_proj = selfLink_parts[6]
+            lic_name = selfLink_parts[-1]
+            return_list.append(self.ex_get_license(project=lic_proj,
+                                                   name=lic_name))
+        return return_list

http://git-wip-us.apache.org/repos/asf/libcloud/blob/0486f77e/libcloud/test/compute/fixtures/gce/projects_suse-cloud_global_images.json
----------------------------------------------------------------------
diff --git a/libcloud/test/compute/fixtures/gce/projects_suse-cloud_global_images.json b/libcloud/test/compute/fixtures/gce/projects_suse-cloud_global_images.json
new file mode 100644
index 0000000..820df9f
--- /dev/null
+++ b/libcloud/test/compute/fixtures/gce/projects_suse-cloud_global_images.json
@@ -0,0 +1,160 @@
+{
+ "kind": "compute#imageList",
+ "selfLink": "https://www.googleapis.com/compute/v1/projects/suse-cloud/global/images",
+ "id": "projects/suse-cloud/global/images",
+ "items": [
+  {
+   "kind": "compute#image",
+   "selfLink": "https://www.googleapis.com/compute/v1/projects/suse-cloud/global/images/sles-11-sp3-v20140306",
+   "id": "3727805086509383287",
+   "creationTimestamp": "2014-03-06T13:13:29.791-08:00",
+   "name": "sles-11-sp3-v20140306",
+   "description": "",
+   "sourceType": "RAW",
+   "rawDisk": {
+    "source": "",
+    "containerType": "TAR"
+   },
+   "deprecated": {
+    "state": "DEPRECATED",
+    "replacement": "https://content.googleapis.com/compute/v1/projects/suse-cloud/global/images/sles-11-sp3-v20140609",
+    "deprecated": "2014-06-09T00:00:00Z"
+   },
+   "status": "READY",
+   "archiveSizeBytes": "354497936",
+   "diskSizeGb": "8",
+   "licenses": [
+    "https://content.googleapis.com/compute/v1/projects/suse-cloud/global/licenses/sles-11"
+   ]
+  },
+  {
+   "kind": "compute#image",
+   "selfLink": "https://www.googleapis.com/compute/v1/projects/suse-cloud/global/images/sles-11-sp3-v20140609",
+   "id": "10656986931280984622",
+   "creationTimestamp": "2014-06-09T10:29:06.385-07:00",
+   "name": "sles-11-sp3-v20140609",
+   "description": "",
+   "sourceType": "RAW",
+   "rawDisk": {
+    "source": "",
+    "containerType": "TAR"
+   },
+   "deprecated": {
+    "state": "DEPRECATED",
+    "replacement": "https://content.googleapis.com/compute/v1/projects/suse-cloud/global/images/sles-11-sp3-v20140712",
+    "deprecated": "2014-07-12T00:00:00Z"
+   },
+   "status": "READY",
+   "archiveSizeBytes": "1191603546",
+   "diskSizeGb": "8",
+   "licenses": [
+    "https://content.googleapis.com/compute/v1/projects/suse-cloud/global/licenses/sles-11"
+   ]
+  },
+  {
+   "kind": "compute#image",
+   "selfLink": "https://www.googleapis.com/compute/v1/projects/suse-cloud/global/images/sles-11-sp3-v20140712",
+   "id": "3415847542100990147",
+   "creationTimestamp": "2014-07-12T03:39:17.695-07:00",
+   "name": "sles-11-sp3-v20140712",
+   "description": "SUSE Linux Enterprise 11 SP3 built on 2014-07-12",
+   "sourceType": "RAW",
+   "rawDisk": {
+    "source": "",
+    "containerType": "TAR"
+   },
+   "deprecated": {
+    "state": "DEPRECATED",
+    "replacement": "https://content.googleapis.com/compute/v1/projects/suse-cloud/global/images/sles-11-sp3-v20140826",
+    "deprecated": "2014-06-26T00:00:00Z"
+   },
+   "status": "READY",
+   "archiveSizeBytes": "1071997074",
+   "diskSizeGb": "8",
+   "licenses": [
+    "https://content.googleapis.com/compute/v1/projects/suse-cloud/global/licenses/sles-11"
+   ]
+  },
+  {
+   "kind": "compute#image",
+   "selfLink": "https://www.googleapis.com/compute/v1/projects/suse-cloud/global/images/sles-11-sp3-v20140826",
+   "id": "588070221570840387",
+   "creationTimestamp": "2014-08-26T14:46:38.449-07:00",
+   "name": "sles-11-sp3-v20140826",
+   "description": "SUSE Linux Enterprise 11 SP3 released on 2014-06-26, built on 2014-08-20",
+   "sourceType": "RAW",
+   "rawDisk": {
+    "source": "",
+    "containerType": "TAR"
+   },
+   "deprecated": {
+    "state": "DEPRECATED",
+    "replacement": "https://content.googleapis.com/compute/v1/projects/suse-cloud/global/images/sles-11-sp3-v20140930",
+    "deprecated": "2014-10-30T00:00:00Z"
+   },
+   "status": "READY",
+   "archiveSizeBytes": "1072617138",
+   "diskSizeGb": "8",
+   "licenses": [
+    "https://content.googleapis.com/compute/v1/projects/suse-cloud/global/licenses/sles-11"
+   ]
+  },
+  {
+   "kind": "compute#image",
+   "selfLink": "https://www.googleapis.com/compute/v1/projects/suse-cloud/global/images/sles-11-sp3-v20140930",
+   "id": "3132872945991231828",
+   "creationTimestamp": "2014-09-30T08:27:46.201-07:00",
+   "name": "sles-11-sp3-v20140930",
+   "description": "SUSE Linux Enterprise Server 11 SP3",
+   "sourceType": "RAW",
+   "rawDisk": {
+    "source": "",
+    "containerType": "TAR"
+   },
+   "status": "READY",
+   "archiveSizeBytes": "1102825953",
+   "diskSizeGb": "8",
+   "licenses": [
+    "https://content.googleapis.com/compute/v1/projects/suse-cloud/global/licenses/sles-11"
+   ]
+  },
+  {
+   "kind": "compute#image",
+   "selfLink": "https://www.googleapis.com/compute/v1/projects/suse-cloud/global/images/sles-11-sp3-v20141105",
+   "id": "14793554030256860036",
+   "creationTimestamp": "2014-11-05T16:11:49.996-08:00",
+   "name": "sles-11-sp3-v20141105",
+   "description": "SUSE Linux Enterprise Server 11 SP3 built on 2014-11-05",
+   "sourceType": "RAW",
+   "rawDisk": {
+    "source": "",
+    "containerType": "TAR"
+   },
+   "status": "READY",
+   "archiveSizeBytes": "1075782309",
+   "diskSizeGb": "8",
+   "licenses": [
+    "https://content.googleapis.com/compute/v1/projects/suse-cloud/global/licenses/sles-11"
+   ]
+  },
+  {
+   "kind": "compute#image",
+   "selfLink": "https://www.googleapis.com/compute/v1/projects/suse-cloud/global/images/sles-12-v20141023",
+   "id": "15301906009182317384",
+   "creationTimestamp": "2014-10-26T08:14:59.932-07:00",
+   "name": "sles-12-v20141023",
+   "description": "SUSE Linux Enterprise Server 12 built on 2014-10-23",
+   "sourceType": "RAW",
+   "rawDisk": {
+    "source": "",
+    "containerType": "TAR"
+   },
+   "status": "READY",
+   "archiveSizeBytes": "1525260684",
+   "diskSizeGb": "8",
+   "licenses": [
+    "https://content.googleapis.com/compute/v1/projects/suse-cloud/global/licenses/sles-12"
+   ]
+  }
+ ]
+}

http://git-wip-us.apache.org/repos/asf/libcloud/blob/0486f77e/libcloud/test/compute/fixtures/gce/projects_suse-cloud_global_licenses_sles_11.json
----------------------------------------------------------------------
diff --git a/libcloud/test/compute/fixtures/gce/projects_suse-cloud_global_licenses_sles_11.json b/libcloud/test/compute/fixtures/gce/projects_suse-cloud_global_licenses_sles_11.json
new file mode 100644
index 0000000..90fd2ad
--- /dev/null
+++ b/libcloud/test/compute/fixtures/gce/projects_suse-cloud_global_licenses_sles_11.json
@@ -0,0 +1,6 @@
+{
+ "kind": "compute#license",
+ "selfLink": "https://www.googleapis.com/compute/v1/projects/suse-cloud/global/licenses/sles-11",
+ "name": "sles-11",
+ "chargesUseFee": true
+}

http://git-wip-us.apache.org/repos/asf/libcloud/blob/0486f77e/libcloud/test/compute/fixtures/gce/projects_suse-cloud_global_licenses_sles_12.json
----------------------------------------------------------------------
diff --git a/libcloud/test/compute/fixtures/gce/projects_suse-cloud_global_licenses_sles_12.json b/libcloud/test/compute/fixtures/gce/projects_suse-cloud_global_licenses_sles_12.json
new file mode 100644
index 0000000..bf1e32c
--- /dev/null
+++ b/libcloud/test/compute/fixtures/gce/projects_suse-cloud_global_licenses_sles_12.json
@@ -0,0 +1,6 @@
+{
+ "kind": "compute#license",
+ "selfLink": "https://www.googleapis.com/compute/v1/projects/suse-cloud/global/licenses/sles-12",
+ "name": "sles-12",
+ "chargesUseFee": true
+}

http://git-wip-us.apache.org/repos/asf/libcloud/blob/0486f77e/libcloud/test/compute/test_gce.py
----------------------------------------------------------------------
diff --git a/libcloud/test/compute/test_gce.py b/libcloud/test/compute/test_gce.py
index 8efeaa1..567276e 100644
--- a/libcloud/test/compute/test_gce.py
+++ b/libcloud/test/compute/test_gce.py
@@ -224,6 +224,11 @@ class GCENodeDriverTest(LibcloudTestCase, TestCaseMixin):
         names = [s.name for s in sizes_all]
         self.assertEqual(names.count('n1-standard-1'), 5)
 
+    def test_ex_get_license(self):
+        license = self.driver.ex_get_license('suse-cloud', 'sles-12')
+        self.assertTrue(license.name, 'sles-12')
+        self.assertTrue(license.charges_use_fee)
+
     def test_list_disktypes(self):
         disktypes = self.driver.ex_list_disktypes()
         disktypes_all = self.driver.ex_list_disktypes('all')
@@ -733,6 +738,12 @@ class GCENodeDriverTest(LibcloudTestCase, TestCaseMixin):
         self.assertEqual(fwr.targetpool.name, 'lctargetpool')
         self.assertEqual(fwr.protocol, 'TCP')
 
+    def test_ex_get_image_license(self):
+        image = self.driver.ex_get_image('sles-12-v20141023')
+        self.assertTrue('licenses' in image.extra)
+        self.assertTrue(image.extra['licenses'][0].name, 'sles-12')
+        self.assertTrue(image.extra['licenses'][0].charges_use_fee)
+
     def test_ex_get_image(self):
         partial_name = 'debian-7'
         image = self.driver.ex_get_image(partial_name)
@@ -1402,6 +1413,18 @@ class GCEMockHttp(MockHttpTestCase):
         body = self.fixtures.load('project.json')
         return (httplib.OK, body, self.json_hdr, httplib.responses[httplib.OK])
 
+    def _projects_suse_cloud_global_licenses_sles_11(self, method, url, body, headers):
+        body = self.fixtures.load('projects_suse-cloud_global_licenses_sles_11.json')
+        return (httplib.OK, body, self.json_hdr, httplib.responses[httplib.OK])
+
+    def _projects_suse_cloud_global_licenses_sles_12(self, method, url, body, headers):
+        body = self.fixtures.load('projects_suse-cloud_global_licenses_sles_12.json')
+        return (httplib.OK, body, self.json_hdr, httplib.responses[httplib.OK])
+
+    def _projects_suse_cloud_global_images(self, method, url, body, headers):
+        body = self.fixtures.load('projects_suse-cloud_global_images.json')
+        return (httplib.OK, body, self.json_hdr, httplib.responses[httplib.OK])
+
     def _projects_debian_cloud_global_images(self, method, url, body, headers):
         body = self.fixtures.load('projects_debian-cloud_global_images.json')
         return (httplib.OK, body, self.json_hdr, httplib.responses[httplib.OK])