blob: 660d71decc49c216c22cea4a67d5f8856e20fd7f [file] [log] [blame]
Oleksiy Petrenko2652ac12018-04-16 17:40:13 +03001try:
2 from urllib.parse import urlencode
3except ImportError:
4 from urllib import urlencode
5import hashlib
6
7from glancev2.common import send, get_raw_client, get_by_name_or_uuid
8
9RESOURCE_LIST_KEY = 'images'
10
11
12@send('get')
13def image_list(**kwargs):
Oleh Hryhorov6de49c92018-05-21 12:53:59 +000014 url = '/images?{}'.format(urlencode(kwargs))
Oleksiy Petrenko2652ac12018-04-16 17:40:13 +030015 return url, {}
16
17
18@send('post')
19def image_create(**kwargs):
Oleh Hryhorov6de49c92018-05-21 12:53:59 +000020 url = '/images'
Oleksiy Petrenko2652ac12018-04-16 17:40:13 +030021 return url, {'json': kwargs}
22
23
24@get_by_name_or_uuid(image_list, RESOURCE_LIST_KEY)
25@send('get')
26def image_get_details(image_id, **kwargs):
Oleh Hryhorov6de49c92018-05-21 12:53:59 +000027 url = '/images/{}'.format(image_id)
Oleksiy Petrenko2652ac12018-04-16 17:40:13 +030028 return url, {}
29
30
31@get_by_name_or_uuid(image_list, RESOURCE_LIST_KEY)
32@send('patch')
33def image_update(image_id, properties, **kwargs):
Oleh Hryhorov6de49c92018-05-21 12:53:59 +000034 url = '/images/{}'.format(image_id)
Oleksiy Petrenko2652ac12018-04-16 17:40:13 +030035 headers = {
36 'Content-Type': 'application/openstack-images-v2.1-json-patch',
37 }
38 return url, {'json': properties, 'headers': headers}
39
40
41@get_by_name_or_uuid(image_list, RESOURCE_LIST_KEY)
42@send('delete')
43def image_delete(image_id, **kwargs):
Oleh Hryhorov6de49c92018-05-21 12:53:59 +000044 url = '/images/{}'.format(image_id)
Oleksiy Petrenko2652ac12018-04-16 17:40:13 +030045 return url, {}
46
47
48@get_by_name_or_uuid(image_list, RESOURCE_LIST_KEY)
49@send('post')
50def image_deactivate(image_id, **kwargs):
Oleh Hryhorov6de49c92018-05-21 12:53:59 +000051 url = '/images/{}/actions/deactivate'.format(image_id)
Oleksiy Petrenko2652ac12018-04-16 17:40:13 +030052 return url, {}
53
54
55@get_by_name_or_uuid(image_list, RESOURCE_LIST_KEY)
56@send('post')
57def image_reactivate(image_id, **kwargs):
Oleh Hryhorov6de49c92018-05-21 12:53:59 +000058 url = '/images/{}/actions/reactivate'.format(image_id)
Oleksiy Petrenko2652ac12018-04-16 17:40:13 +030059 return url, {}
60
61
62class StreamingDownloader(object):
63
64 def __init__(self, adapter, image_id, chunksize):
65 self.hasher = hashlib.new('md5')
66 self.chunksize = chunksize
67
Oleh Hryhorov6de49c92018-05-21 12:53:59 +000068 resp = adapter.get('/images/{}/file'.format(image_id),
Oleksiy Petrenko2652ac12018-04-16 17:40:13 +030069 stream=True)
70 if resp.status_code != 200:
71 raise Exception('Invalid response code: %s' % resp.status_code)
72
73 self._request = resp
74
75 def __iter__(self):
76 for chunk in self._request.iter_content(chunk_size=self.chunksize):
77 self.hasher.update(chunk)
78 yield chunk
79
80 def validate(self):
81 return self.hasher.hexdigest() == self._request.headers['Content-Md5']
82
83
84@get_by_name_or_uuid(image_list, RESOURCE_LIST_KEY)
85def image_data_download(image_id, file_name, **kwargs):
86 cloud_name = kwargs.pop('cloud_name')
87 adapter = get_raw_client(cloud_name)
88 downloader = StreamingDownloader(adapter, image_id, 1024 * 1024)
89 with open(file_name, 'wb') as f:
90 for chunk in downloader:
91 f.write(chunk)
92 return downloader.validate()
93
94
95@get_by_name_or_uuid(image_list, RESOURCE_LIST_KEY)
96@send('put')
97def image_data_upload(image_id, file_name, **kwargs):
Oleh Hryhorov6de49c92018-05-21 12:53:59 +000098 url = '/images/{}/file'.format(image_id)
Oleksiy Petrenko2652ac12018-04-16 17:40:13 +030099 headers = {'Content-Type': 'application/octet-stream '}
100 with open(file_name, 'rb') as f:
101 data = f.readlines()
102 return url, {'json': data, 'headers': headers}