Statistics
| Branch: | Tag: | Revision:

root / kamaki / clients / image.py @ d2cea1e2

History | View | Annotate | Download (4.4 kB)

1
# Copyright 2011 GRNET S.A. All rights reserved.
2
#
3
# Redistribution and use in source and binary forms, with or
4
# without modification, are permitted provided that the following
5
# conditions are met:
6
#
7
#   1. Redistributions of source code must retain the above
8
#      copyright notice, this list of conditions and the following
9
#      disclaimer.
10
#
11
#   2. Redistributions in binary form must reproduce the above
12
#      copyright notice, this list of conditions and the following
13
#      disclaimer in the documentation and/or other materials
14
#      provided with the distribution.
15
#
16
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27
# POSSIBILITY OF SUCH DAMAGE.
28
#
29
# The views and conclusions contained in the software and
30
# documentation are those of the authors and should not be
31
# interpreted as representing official policies, either expressed
32
# or implied, of GRNET S.A.
33

    
34
"""
35
    OpenStack Image Service API 1.0 client
36
"""
37

    
38
from urllib import quote
39

    
40
from .http import HTTPClient
41

    
42

    
43
class ImageClient(HTTPClient):
44
    @property
45
    def url(self):
46
        url = self.config.get('image_url') or self.config.get('url')
47
        if not url:
48
            raise ClientError('No URL was given')
49
        return url
50
    
51
    @property
52
    def token(self):
53
        token = self.config.get('image_token') or self.config.get('token')
54
        if not token:
55
            raise ClientError('No token was given')
56
        return token
57
    
58
    def list_public(self, detail=False, filters={}, order=''):
59
        path = '/images/detail' if detail else '/images/'
60
        params = {}
61
        params.update(filters)
62
        
63
        if order.startswith('-'):
64
            params['sort_dir'] = 'desc'
65
            order = order[1:]
66
        else:
67
            params['sort_dir'] = 'asc'
68
        
69
        if order:
70
            params['sort_key'] = order
71
        
72
        if params:
73
            path += '?' + '&'.join('%s=%s' % item for item in params.items())
74
        return self.http_get(path)
75
    
76
    def get_meta(self, image_id):
77
        path = '/images/%s' % image_id
78
        resp, buf = self.raw_http_cmd('HEAD', path)
79
        reply = {}
80
        prefix = 'x-image-meta-'
81
        for key, val in resp.getheaders():
82
            key = key.lower()
83
            if not key.startswith(prefix):
84
                continue
85
            key = key[len(prefix):]
86
            reply[key] = val
87
        return reply
88
    
89
    def register(self, name, location, params={}, properties={}):
90
        path = '/images/'
91
        headers = {}
92
        headers['x-image-meta-name'] = quote(name)
93
        headers['x-image-meta-location'] = location
94
        for key, val in params.items():
95
            if key in ('id', 'store', 'disk_format', 'container_format',
96
                       'size', 'checksum', 'is_public', 'owner'):
97
                key = 'x-image-meta-' + key.replace('_', '-')
98
                headers[key] = val
99
        for key, val in properties.items():
100
            headers['x-image-meta-property-' + quote(key)] = quote(val)
101
        return self.http_post(path, headers=headers, success=200)
102
    
103
    def list_members(self, image_id):
104
        path = '/images/%s/members' % image_id
105
        reply = self.http_get(path)
106
        return reply['members']
107

    
108
    def list_shared(self, member):
109
        path = '/shared-images/%s' % member
110
        reply = self.http_get(path)
111
        return reply['shared_images']
112

    
113
    def add_member(self, image_id, member):
114
        path = '/images/%s/members/%s' % (image_id, member)
115
        self.http_put(path)
116
    
117
    def remove_member(self, image_id, member):
118
        path = '/images/%s/members/%s' % (image_id, member)
119
        self.http_delete(path)
120
    
121
    def set_members(self, image_id, members):
122
        path = '/images/%s/members' % image_id
123
        req = {'memberships': [{'member_id': member} for member in members]}
124
        body = json.dumps(req)
125
        self.http_put(path, body)