You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@libcloud.apache.org by qu...@apache.org on 2018/03/09 04:47:19 UTC

[1/3] libcloud git commit: Add changes for #1176

Repository: libcloud
Updated Branches:
  refs/heads/trunk ec53824d6 -> 2b298b7cd


Add changes for #1176

Closes #1176


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

Branch: refs/heads/trunk
Commit: 2b298b7cd8d17b4b1c0db20292fdb7867a512ac6
Parents: 243c067
Author: Quentin Pradet <qu...@apache.org>
Authored: Fri Mar 9 08:45:57 2018 +0400
Committer: Quentin Pradet <qu...@apache.org>
Committed: Fri Mar 9 08:46:40 2018 +0400

----------------------------------------------------------------------
 CHANGES.rst | 3 +++
 1 file changed, 3 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/libcloud/blob/2b298b7c/CHANGES.rst
----------------------------------------------------------------------
diff --git a/CHANGES.rst b/CHANGES.rst
index bd32522..5f8dd1e 100644
--- a/CHANGES.rst
+++ b/CHANGES.rst
@@ -25,6 +25,9 @@ Compute
 - [OpenStack v2] Allow listing image members (GITHUB-1172)
   [Rick van de Loo]
 
+- [OpenStack v2] Allow creating and accepting image members (GITHUB-1176)
+  [Rick van de Loo]
+
 Changes in Apache Libcloud 2.3.0
 --------------------------------
 


[2/3] libcloud git commit: implement ex_accept_image_member for OpenStack

Posted by qu...@apache.org.
implement ex_accept_image_member for OpenStack

For sharing images between tenants. The tenant that owns the image
(which must have visibility status shared) can share it with another
tenant by creating a new image member. The image member must then accept
the image before it can be used.

Signed-off-by: Quentin Pradet <qu...@apache.org>


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

Branch: refs/heads/trunk
Commit: 243c06738ac6208cac7161086837b6a6055332c8
Parents: deb37f3
Author: Rick van de Loo <ri...@gmail.com>
Authored: Sun Mar 4 13:27:41 2018 +0100
Committer: Quentin Pradet <qu...@apache.org>
Committed: Fri Mar 9 08:46:40 2018 +0400

----------------------------------------------------------------------
 libcloud/compute/drivers/openstack.py           | 28 ++++++++++++++++++--
 ...54e_a1b2_4df8_b747_4bec97abc799_members.json |  2 ++
 libcloud/test/compute/test_openstack.py         | 21 +++++++++++++++
 3 files changed, 49 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/libcloud/blob/243c0673/libcloud/compute/drivers/openstack.py
----------------------------------------------------------------------
diff --git a/libcloud/compute/drivers/openstack.py b/libcloud/compute/drivers/openstack.py
index 1e52ceb..91eb1a4 100644
--- a/libcloud/compute/drivers/openstack.py
+++ b/libcloud/compute/drivers/openstack.py
@@ -2631,9 +2631,11 @@ class OpenStack_2_NodeDriver(OpenStack_1_1_NodeDriver):
         Note that this is not an idempotent operation. If this action is
         attempted using a tenant that is already in the image members
         group the API will throw a Conflict (409).
-        See https://developer.openstack.org/api-ref/image/v2/index.html#create-image-member
+        See the 'create-image-member' section on
+        https://developer.openstack.org/api-ref/image/v2/index.html
 
-        :param str image_id: The ID of the image to share with the specified tenant
+        :param str image_id: The ID of the image to share with the specified
+        tenant
         :param str member_id: The ID of the project / tenant (the image member)
         Note that this is the Keystone project ID and not the project name,
         so something like e2151b1fe02d4a8a2d1f5fc331522c0a
@@ -2672,6 +2674,28 @@ class OpenStack_2_NodeDriver(OpenStack_1_1_NodeDriver):
         )
         return self._to_image_member(response.object)
 
+    def ex_accept_image_member(self, image_id, member_id):
+        """
+        Accept a pending image as a member.
+
+        This call is idempotent unlike ex_create_image_member,
+        you can accept the same image many times.
+
+        :param      image_id: ID of the image to accept
+        :type       image_id: ``str``
+
+        :param      project: ID of the project to accept the image as
+        :type       image_id: ``str``
+
+        :rtype: ``bool``
+        """
+        data = {'status': 'accepted'}
+        response = self.image_connection.request(
+            '/v2/images/%s/members/%s' % (image_id, member_id),
+            method='PUT', data=json.dumps(data)
+        )
+        return self._to_image_member(response.object)
+
 
 class OpenStack_1_1_FloatingIpPool(object):
     """

http://git-wip-us.apache.org/repos/asf/libcloud/blob/243c0673/libcloud/test/compute/fixtures/openstack_v1.1/_images_8af1a54e_a1b2_4df8_b747_4bec97abc799_members.json
----------------------------------------------------------------------
diff --git a/libcloud/test/compute/fixtures/openstack_v1.1/_images_8af1a54e_a1b2_4df8_b747_4bec97abc799_members.json b/libcloud/test/compute/fixtures/openstack_v1.1/_images_8af1a54e_a1b2_4df8_b747_4bec97abc799_members.json
new file mode 100644
index 0000000..ce54718
--- /dev/null
+++ b/libcloud/test/compute/fixtures/openstack_v1.1/_images_8af1a54e_a1b2_4df8_b747_4bec97abc799_members.json
@@ -0,0 +1,2 @@
+{"status": "accepted", "created_at": "2018-03-02T14:19:38Z", "updated_at": "2018-03-02T14:20:37Z", "image_id": "8af1a54e-a1b2-4df8-b747-4bec97abc799", "member_id": "e2151b1fe02d4a8a2d1f5fc331522c0a", "schema": "/v2/schemas/member"}
+

http://git-wip-us.apache.org/repos/asf/libcloud/blob/243c0673/libcloud/test/compute/test_openstack.py
----------------------------------------------------------------------
diff --git a/libcloud/test/compute/test_openstack.py b/libcloud/test/compute/test_openstack.py
index ab59884..e9d9315 100644
--- a/libcloud/test/compute/test_openstack.py
+++ b/libcloud/test/compute/test_openstack.py
@@ -1678,6 +1678,20 @@ class OpenStack_2_Tests(OpenStack_1_1_Tests):
         self.assertEqual(image_member.extra['updated'], '2017-01-12T12:31:54Z')
         self.assertEqual(image_member.extra['schema'], '/v2/schemas/member')
 
+    def test_ex_accept_image_member(self):
+        image_id = '8af1a54e-a1b2-4df8-b747-4bec97abc799'
+        image_member_id = 'e2151b1fe02d4a8a2d1f5fc331522c0a'
+        image_member = self.driver.ex_accept_image_member(
+            image_id, image_member_id
+        )
+
+        self.assertEqual(image_member.id, image_member_id)
+        self.assertEqual(image_member.image_id, image_id)
+        self.assertEqual(image_member.state, NodeImageMemberState.ACCEPTED)
+        self.assertEqual(image_member.created, '2018-03-02T14:19:38Z')
+        self.assertEqual(image_member.extra['updated'], '2018-03-02T14:20:37Z')
+        self.assertEqual(image_member.extra['schema'], '/v2/schemas/member')
+
 
 class OpenStack_1_1_FactoryMethodTests(OpenStack_1_1_Tests):
     should_list_locations = False
@@ -1846,6 +1860,13 @@ class OpenStack_1_1_MockHttp(MockHttp, unittest.TestCase):
         else:
             raise NotImplementedError()
 
+    def _v2_1337_v2_images_8af1a54e_a1b2_4df8_b747_4bec97abc799_members_e2151b1fe02d4a8a2d1f5fc331522c0a(self, method, url, body, headers):
+        if method == "PUT":
+            body = self.fixtures.load('_images_8af1a54e_a1b2_4df8_b747_4bec97abc799_members.json')
+            return (httplib.OK, body, self.json_content_headers, httplib.responses[httplib.OK])
+        else:
+            raise NotImplementedError()
+
     def _v2_1337_v2_images_d9a9cd9a_278a_444c_90a6_d24b8c688a63_members_016926dff12345e8b10329f24c99745b(self, method, url, body, headers):
         if method == "GET":
             body = self.fixtures.load(


[3/3] libcloud git commit: implement ex_create_image_member for OpenStack

Posted by qu...@apache.org.
implement ex_create_image_member for OpenStack

give a project (previously known as tenant) access to an image. after the tenant has been given access, it still needs to accept the image (using the scoped token for that project).

Signed-off-by: Quentin Pradet <qu...@apache.org>


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

Branch: refs/heads/trunk
Commit: deb37f36c909d3f2ce9769305bb3b050b40e0f14
Parents: ec53824
Author: Rick van de Loo <ri...@gmail.com>
Authored: Sun Mar 4 13:00:20 2018 +0100
Committer: Quentin Pradet <qu...@apache.org>
Committed: Fri Mar 9 08:46:40 2018 +0400

----------------------------------------------------------------------
 libcloud/compute/drivers/openstack.py           | 32 ++++++++++++++++++++
 ...54e_a1b2_4df8_b747_4bec97abc799_members.json |  2 ++
 libcloud/test/compute/test_openstack.py         | 21 +++++++++++++
 3 files changed, 55 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/libcloud/blob/deb37f36/libcloud/compute/drivers/openstack.py
----------------------------------------------------------------------
diff --git a/libcloud/compute/drivers/openstack.py b/libcloud/compute/drivers/openstack.py
index 527dce9..1e52ceb 100644
--- a/libcloud/compute/drivers/openstack.py
+++ b/libcloud/compute/drivers/openstack.py
@@ -2622,6 +2622,38 @@ class OpenStack_2_NodeDriver(OpenStack_1_1_NodeDriver):
             image_members.append(self._to_image_member(image_member))
         return image_members
 
+    def ex_create_image_member(self, image_id, member_id):
+        """
+        Give a project access to an image.
+
+        The image should have visibility status 'shared'.
+
+        Note that this is not an idempotent operation. If this action is
+        attempted using a tenant that is already in the image members
+        group the API will throw a Conflict (409).
+        See https://developer.openstack.org/api-ref/image/v2/index.html#create-image-member
+
+        :param str image_id: The ID of the image to share with the specified tenant
+        :param str member_id: The ID of the project / tenant (the image member)
+        Note that this is the Keystone project ID and not the project name,
+        so something like e2151b1fe02d4a8a2d1f5fc331522c0a
+        :return None:
+
+        :param      image_id: ID of the image to share
+        :type       image_id: ``str``
+
+        :param      project: ID of the project to give access to the image
+        :type       image_id: ``str``
+
+        :rtype: ``list`` of :class:`NodeImageMember`
+        """
+        data = {'member': member_id}
+        response = self.image_connection.request(
+            '/v2/images/%s/members' % image_id,
+            method='POST', data=json.dumps(data)
+        )
+        return self._to_image_member(response.object)
+
     def ex_get_image_member(self, image_id, member_id):
         """
         Get a member of an image by id

http://git-wip-us.apache.org/repos/asf/libcloud/blob/deb37f36/libcloud/test/compute/fixtures/openstack_v1.1/_images_9af1a54e_a1b2_4df8_b747_4bec97abc799_members.json
----------------------------------------------------------------------
diff --git a/libcloud/test/compute/fixtures/openstack_v1.1/_images_9af1a54e_a1b2_4df8_b747_4bec97abc799_members.json b/libcloud/test/compute/fixtures/openstack_v1.1/_images_9af1a54e_a1b2_4df8_b747_4bec97abc799_members.json
new file mode 100644
index 0000000..3bc4174
--- /dev/null
+++ b/libcloud/test/compute/fixtures/openstack_v1.1/_images_9af1a54e_a1b2_4df8_b747_4bec97abc799_members.json
@@ -0,0 +1,2 @@
+{"status": "pending", "created_at": "2018-03-02T14:19:38Z", "updated_at": "2018-03-02T14:19:38Z", "image_id": "9af1a54e-a1b2-4df8-b747-4bec97abc799", "member_id": "e2151b1fe02d4a8a2d1f5fc331522c0a", "schema": "/v2/schemas/member"}
+

http://git-wip-us.apache.org/repos/asf/libcloud/blob/deb37f36/libcloud/test/compute/test_openstack.py
----------------------------------------------------------------------
diff --git a/libcloud/test/compute/test_openstack.py b/libcloud/test/compute/test_openstack.py
index 02ed3f3..ab59884 100644
--- a/libcloud/test/compute/test_openstack.py
+++ b/libcloud/test/compute/test_openstack.py
@@ -1650,6 +1650,20 @@ class OpenStack_2_Tests(OpenStack_1_1_Tests):
         self.assertEqual(image_member.extra['updated'], '2017-01-12T12:31:54Z')
         self.assertEqual(image_member.extra['schema'], '/v2/schemas/member')
 
+    def test_ex_create_image_member(self):
+        image_id = '9af1a54e-a1b2-4df8-b747-4bec97abc799'
+        image_member_id = 'e2151b1fe02d4a8a2d1f5fc331522c0a'
+        image_member = self.driver.ex_create_image_member(
+            image_id, image_member_id
+        )
+
+        self.assertEqual(image_member.id, image_member_id)
+        self.assertEqual(image_member.image_id, image_id)
+        self.assertEqual(image_member.state, NodeImageMemberState.PENDING)
+        self.assertEqual(image_member.created, '2018-03-02T14:19:38Z')
+        self.assertEqual(image_member.extra['updated'], '2018-03-02T14:19:38Z')
+        self.assertEqual(image_member.extra['schema'], '/v2/schemas/member')
+
     def test_ex_get_image_member(self):
         image_id = 'd9a9cd9a-278a-444c-90a6-d24b8c688a63'
         image_member_id = '016926dff12345e8b10329f24c99745b'
@@ -1825,6 +1839,13 @@ class OpenStack_1_1_MockHttp(MockHttp, unittest.TestCase):
         else:
             raise NotImplementedError()
 
+    def _v2_1337_v2_images_9af1a54e_a1b2_4df8_b747_4bec97abc799_members(self, method, url, body, headers):
+        if method == "POST":
+            body = self.fixtures.load('_images_9af1a54e_a1b2_4df8_b747_4bec97abc799_members.json')
+            return (httplib.OK, body, self.json_content_headers, httplib.responses[httplib.OK])
+        else:
+            raise NotImplementedError()
+
     def _v2_1337_v2_images_d9a9cd9a_278a_444c_90a6_d24b8c688a63_members_016926dff12345e8b10329f24c99745b(self, method, url, body, headers):
         if method == "GET":
             body = self.fixtures.load(