Statistics
| Branch: | Tag: | Revision:

root / kamaki / clients / image / __init__.py @ ca5528f1

History | View | Annotate | Download (7.8 kB)

1 e3f01d64 Stavros Sachtouris
# Copyright 2011-2013 GRNET S.A. All rights reserved.
2 a1c50326 Giorgos Verigakis
#
3 a1c50326 Giorgos Verigakis
# Redistribution and use in source and binary forms, with or
4 a1c50326 Giorgos Verigakis
# without modification, are permitted provided that the following
5 a1c50326 Giorgos Verigakis
# conditions are met:
6 a1c50326 Giorgos Verigakis
#
7 a1c50326 Giorgos Verigakis
#   1. Redistributions of source code must retain the above
8 a1c50326 Giorgos Verigakis
#      copyright notice, this list of conditions and the following
9 a1c50326 Giorgos Verigakis
#      disclaimer.
10 a1c50326 Giorgos Verigakis
#
11 a1c50326 Giorgos Verigakis
#   2. Redistributions in binary form must reproduce the above
12 a1c50326 Giorgos Verigakis
#      copyright notice, this list of conditions and the following
13 a1c50326 Giorgos Verigakis
#      disclaimer in the documentation and/or other materials
14 a1c50326 Giorgos Verigakis
#      provided with the distribution.
15 a1c50326 Giorgos Verigakis
#
16 a1c50326 Giorgos Verigakis
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17 a1c50326 Giorgos Verigakis
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 a1c50326 Giorgos Verigakis
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 a1c50326 Giorgos Verigakis
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20 a1c50326 Giorgos Verigakis
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 a1c50326 Giorgos Verigakis
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 a1c50326 Giorgos Verigakis
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23 a1c50326 Giorgos Verigakis
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24 a1c50326 Giorgos Verigakis
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 a1c50326 Giorgos Verigakis
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26 a1c50326 Giorgos Verigakis
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 a1c50326 Giorgos Verigakis
# POSSIBILITY OF SUCH DAMAGE.
28 a1c50326 Giorgos Verigakis
#
29 a1c50326 Giorgos Verigakis
# The views and conclusions contained in the software and
30 a1c50326 Giorgos Verigakis
# documentation are those of the authors and should not be
31 a1c50326 Giorgos Verigakis
# interpreted as representing official policies, either expressed
32 a1c50326 Giorgos Verigakis
# or implied, of GRNET S.A.
33 cb69a058 Stavros Sachtouris
34 cb69a058 Stavros Sachtouris
from kamaki.clients import Client, ClientError
35 fab9b17f Stavros Sachtouris
from kamaki.clients.utils import path4url
36 a1c50326 Giorgos Verigakis
37 3dabe5d2 Stavros Sachtouris
38 17b255c7 Stavros Sachtouris
def _format_image_headers(headers):
39 17b255c7 Stavros Sachtouris
    reply = dict(properties=dict())
40 17b255c7 Stavros Sachtouris
    meta_prefix = 'x-image-meta-'
41 17b255c7 Stavros Sachtouris
    property_prefix = 'x-image-meta-property-'
42 17b255c7 Stavros Sachtouris
43 17b255c7 Stavros Sachtouris
    for key, val in headers.items():
44 17b255c7 Stavros Sachtouris
        key = key.lower()
45 17b255c7 Stavros Sachtouris
        if key.startswith(property_prefix):
46 17b255c7 Stavros Sachtouris
            key = key[len(property_prefix):].upper().replace('-', '_')
47 17b255c7 Stavros Sachtouris
            reply['properties'][key] = val
48 17b255c7 Stavros Sachtouris
        elif key.startswith(meta_prefix):
49 17b255c7 Stavros Sachtouris
            key = key[len(meta_prefix):]
50 17b255c7 Stavros Sachtouris
            reply[key] = val
51 17b255c7 Stavros Sachtouris
    return reply
52 17b255c7 Stavros Sachtouris
53 17b255c7 Stavros Sachtouris
54 cd75ff39 Giorgos Verigakis
class ImageClient(Client):
55 76e7661e Stavros Sachtouris
    """Synnefo Plankton API client"""
56 44b8928d Giorgos Verigakis
57 2f749e6e Stavros Sachtouris
    def __init__(self, base_url, token):
58 33dc6317 Stavros Sachtouris
        super(ImageClient, self).__init__(base_url, token)
59 2f749e6e Stavros Sachtouris
60 f5eac743 Stavros Sachtouris
    def list_public(self, detail=False, filters={}, order=''):
61 f5eac743 Stavros Sachtouris
        """
62 f5eac743 Stavros Sachtouris
        :param detail: (bool)
63 44b8928d Giorgos Verigakis

64 f5eac743 Stavros Sachtouris
        :param filters: (dict) request filters
65 44b8928d Giorgos Verigakis

66 cb69a058 Stavros Sachtouris
        :param order: (str) order listing by field (default is ascending, - for
67 cb69a058 Stavros Sachtouris
            descending)
68 f5eac743 Stavros Sachtouris

69 f5eac743 Stavros Sachtouris
        :returns: (list) id,name + full image info if detail
70 f5eac743 Stavros Sachtouris
        """
71 dd7461ac Stavros Sachtouris
        path = path4url('images', 'detail') if detail else (
72 dd7461ac Stavros Sachtouris
            path4url('images') + '/')
73 44b8928d Giorgos Verigakis
74 fa984c2c Stavros Sachtouris
        async_params = {}
75 2f749e6e Stavros Sachtouris
        if isinstance(filters, dict):
76 fa984c2c Stavros Sachtouris
            for key, value in filters.items():
77 fa984c2c Stavros Sachtouris
                if value:
78 fa984c2c Stavros Sachtouris
                    async_params[key] = value
79 6325d148 Stavros Sachtouris
        if order and order.startswith('-'):
80 d86c3c7d Stavros Sachtouris
            async_params['sort_dir'] = 'desc'
81 a1c50326 Giorgos Verigakis
            order = order[1:]
82 a1c50326 Giorgos Verigakis
        else:
83 d86c3c7d Stavros Sachtouris
            async_params['sort_dir'] = 'asc'
84 d86c3c7d Stavros Sachtouris
        if order:
85 d86c3c7d Stavros Sachtouris
            async_params['sort_key'] = order
86 44b8928d Giorgos Verigakis
87 fa984c2c Stavros Sachtouris
        r = self.get(path, async_params=async_params, success=200)
88 cd75ff39 Giorgos Verigakis
        return r.json
89 44b8928d Giorgos Verigakis
90 a1c50326 Giorgos Verigakis
    def get_meta(self, image_id):
91 cb69a058 Stavros Sachtouris
        """
92 cb69a058 Stavros Sachtouris
        :param image_id: (string)
93 cb69a058 Stavros Sachtouris

94 cb69a058 Stavros Sachtouris
        :returns: (list) image metadata (key:val)
95 cb69a058 Stavros Sachtouris
        """
96 3dabe5d2 Stavros Sachtouris
        path = path4url('images', image_id)
97 cd75ff39 Giorgos Verigakis
        r = self.head(path, success=200)
98 44b8928d Giorgos Verigakis
99 17b255c7 Stavros Sachtouris
        return _format_image_headers(r.headers)
100 44b8928d Giorgos Verigakis
101 a1c50326 Giorgos Verigakis
    def register(self, name, location, params={}, properties={}):
102 f5f35422 Stavros Sachtouris
        """Register an image that is uploaded at location
103 cb69a058 Stavros Sachtouris

104 cb69a058 Stavros Sachtouris
        :param name: (str)
105 cb69a058 Stavros Sachtouris

106 e99f9efb Stavros Sachtouris
        :param location: (str or iterable) if iterable, then
107 e99f9efb Stavros Sachtouris
            (user_uuid, container, image_path) else if string
108 e99f9efb Stavros Sachtouris
            pithos://<user_uuid>/<container>/<image object>
109 cb69a058 Stavros Sachtouris

110 cb69a058 Stavros Sachtouris
        :param params: (dict) image metadata (X-Image-Meta) can be id, store,
111 cb69a058 Stavros Sachtouris
            disc_format, container_format, size, checksum, is_public, owner
112 cb69a058 Stavros Sachtouris

113 cb69a058 Stavros Sachtouris
        :param properties: (dict) image properties (X-Image-Meta-Property)
114 7b6e977c Stavros Sachtouris

115 17b255c7 Stavros Sachtouris
        :returns: (dict) metadata of the created image
116 cb69a058 Stavros Sachtouris
        """
117 dd7461ac Stavros Sachtouris
        path = path4url('images') + '/'
118 edbee9c8 Stavros Sachtouris
        self.set_header('X-Image-Meta-Name', name)
119 e99f9efb Stavros Sachtouris
        location = location if (
120 e99f9efb Stavros Sachtouris
            isinstance(location, str) or isinstance(location, unicode)) else (
121 e99f9efb Stavros Sachtouris
                'pithos://%s' % '/'.join(location))
122 edbee9c8 Stavros Sachtouris
        self.set_header('X-Image-Meta-Location', location)
123 44b8928d Giorgos Verigakis
124 fe5173b9 Stavros Sachtouris
        async_headers = {}
125 a1c50326 Giorgos Verigakis
        for key, val in params.items():
126 2dc39c27 Stavros Sachtouris
            if key in ('store', 'disk_format', 'container_format',
127 2dc39c27 Stavros Sachtouris
                       'size', 'checksum', 'is_public', 'owner') and val:
128 a1c50326 Giorgos Verigakis
                key = 'x-image-meta-' + key.replace('_', '-')
129 fe5173b9 Stavros Sachtouris
                async_headers[key] = val
130 44b8928d Giorgos Verigakis
131 a1c50326 Giorgos Verigakis
        for key, val in properties.items():
132 f875dd02 Stavros Sachtouris
            async_headers['x-image-meta-property-%s' % key] = val
133 44b8928d Giorgos Verigakis
134 7b6e977c Stavros Sachtouris
        r = self.post(path, success=200, async_headers=async_headers)
135 17b255c7 Stavros Sachtouris
136 17b255c7 Stavros Sachtouris
        return _format_image_headers(r.headers)
137 bcebdfef Stavros Sachtouris
138 fd6608bd Stavros Sachtouris
    def unregister(self, image_id):
139 fd6608bd Stavros Sachtouris
        """Unregister an image
140 fd6608bd Stavros Sachtouris

141 fd6608bd Stavros Sachtouris
        :param image_id: (str)
142 f5f35422 Stavros Sachtouris

143 f5f35422 Stavros Sachtouris
        :returns: (dict) response headers
144 fd6608bd Stavros Sachtouris
        """
145 fd6608bd Stavros Sachtouris
        path = path4url('images', image_id)
146 f5f35422 Stavros Sachtouris
        r = self.delete(path, success=204)
147 f5f35422 Stavros Sachtouris
        return r.headers
148 fd6608bd Stavros Sachtouris
149 a1c50326 Giorgos Verigakis
    def list_members(self, image_id):
150 cb69a058 Stavros Sachtouris
        """
151 cb69a058 Stavros Sachtouris
        :param image_id: (str)
152 cb69a058 Stavros Sachtouris

153 cb69a058 Stavros Sachtouris
        :returns: (list) users who can use current user's images
154 cb69a058 Stavros Sachtouris
        """
155 3dabe5d2 Stavros Sachtouris
        path = path4url('images', image_id, 'members')
156 cd75ff39 Giorgos Verigakis
        r = self.get(path, success=200)
157 cd75ff39 Giorgos Verigakis
        return r.json['members']
158 a1c50326 Giorgos Verigakis
159 a1c50326 Giorgos Verigakis
    def list_shared(self, member):
160 cb69a058 Stavros Sachtouris
        """
161 cb69a058 Stavros Sachtouris
        :param member: (str) sharers account
162 cb69a058 Stavros Sachtouris

163 cb69a058 Stavros Sachtouris
        :returns: (list) images shared by member
164 cb69a058 Stavros Sachtouris
        """
165 edbee9c8 Stavros Sachtouris
        path = path4url('shared-images', member)
166 1bb4d14d Stavros Sachtouris
        #self.set_param('format', 'json')
167 cd75ff39 Giorgos Verigakis
        r = self.get(path, success=200)
168 cd75ff39 Giorgos Verigakis
        return r.json['shared_images']
169 a1c50326 Giorgos Verigakis
170 a1c50326 Giorgos Verigakis
    def add_member(self, image_id, member):
171 cb69a058 Stavros Sachtouris
        """
172 cb69a058 Stavros Sachtouris
        :param image_id: (str)
173 cb69a058 Stavros Sachtouris

174 cb69a058 Stavros Sachtouris
        :param member: (str) user to allow access to current user's images
175 cb69a058 Stavros Sachtouris
        """
176 edbee9c8 Stavros Sachtouris
        path = path4url('images', image_id, 'members', member)
177 f5f35422 Stavros Sachtouris
        self.set_header('Content-Length', len(member))
178 f5f35422 Stavros Sachtouris
        r = self.put(path, success=204)
179 f5f35422 Stavros Sachtouris
        return r.headers
180 986b53f8 Giorgos Verigakis
181 a1c50326 Giorgos Verigakis
    def remove_member(self, image_id, member):
182 cb69a058 Stavros Sachtouris
        """
183 cb69a058 Stavros Sachtouris
        :param image_id: (str)
184 cb69a058 Stavros Sachtouris

185 cb69a058 Stavros Sachtouris
        :param member: (str) user to deprive from current user's images
186 cb69a058 Stavros Sachtouris
        """
187 edbee9c8 Stavros Sachtouris
        path = path4url('images', image_id, 'members', member)
188 f5f35422 Stavros Sachtouris
        r = self.delete(path, success=204)
189 f5f35422 Stavros Sachtouris
        return r.headers
190 44b8928d Giorgos Verigakis
191 a1c50326 Giorgos Verigakis
    def set_members(self, image_id, members):
192 cb69a058 Stavros Sachtouris
        """
193 cb69a058 Stavros Sachtouris
        :param image_id: (str)
194 cb69a058 Stavros Sachtouris

195 cb69a058 Stavros Sachtouris
        :param members: (list) user to deprive from current user's images
196 cb69a058 Stavros Sachtouris
        """
197 edbee9c8 Stavros Sachtouris
        path = path4url('images', image_id, 'members')
198 a1c50326 Giorgos Verigakis
        req = {'memberships': [{'member_id': member} for member in members]}
199 f5f35422 Stavros Sachtouris
        r = self.put(path, json=req, success=204)
200 f5f35422 Stavros Sachtouris
        return r.headers
201 dad1b874 Stavros Sachtouris
202 dad1b874 Stavros Sachtouris
    def update_image(
203 dad1b874 Stavros Sachtouris
            self, image_id,
204 dad1b874 Stavros Sachtouris
            name=None, disk_format=None, container_format=None,
205 dad1b874 Stavros Sachtouris
            status=None, public=None, owner_id=None, **properties):
206 dad1b874 Stavros Sachtouris
        path = path4url('images', image_id)
207 dad1b874 Stavros Sachtouris
        if name is not None:
208 dad1b874 Stavros Sachtouris
            self.set_header('X-Image-Meta-Name', name)
209 dad1b874 Stavros Sachtouris
        if disk_format is not None:
210 dad1b874 Stavros Sachtouris
            self.set_header('X-Image-Meta-Disk-Format', disk_format)
211 dad1b874 Stavros Sachtouris
        if container_format is not None:
212 dad1b874 Stavros Sachtouris
            self.set_header('X-Image-Meta-Container-Format', container_format)
213 dad1b874 Stavros Sachtouris
        if status is not None:
214 dad1b874 Stavros Sachtouris
            self.set_header('X-Image-Meta-Status', status)
215 dad1b874 Stavros Sachtouris
        if public is not None:
216 dad1b874 Stavros Sachtouris
            self.set_header('X-Image-Meta-Is-Public', bool(public))
217 dad1b874 Stavros Sachtouris
        if owner_id is not None:
218 dad1b874 Stavros Sachtouris
            self.set_header('X-Image-Meta-Owner', owner_id)
219 dad1b874 Stavros Sachtouris
        for k, v in properties.items():
220 dad1b874 Stavros Sachtouris
            self.set_header('X-Image-Meta-Property-%s' % k, v)
221 ca5528f1 Stavros Sachtouris
        self.set_header('Content-Length', 0)
222 dad1b874 Stavros Sachtouris
        r = self.put(path, success=200)
223 dad1b874 Stavros Sachtouris
        return r.headers