blob: a61f31d1032b889788d55b8558fe399908fba414 [file] [log] [blame]
Kurt Taylor6a6f5be2013-04-02 18:53:47 -04001# Copyright 2013 IBM Corp.
Matthew Treinisha62347f2013-03-01 16:37:30 -05002# All Rights Reserved.
3#
4# Licensed under the Apache License, Version 2.0 (the "License"); you may
5# not use this file except in compliance with the License. You may obtain
6# a copy of the License at
7#
8# http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13# License for the specific language governing permissions and limitations
14# under the License.
15
Matthew Treinish21905512015-07-13 10:33:35 -040016from oslo_serialization import jsonutils as json
Matthew Treinish89128142015-04-23 10:44:30 -040017from six.moves.urllib import parse as urllib
Matthew Treinisha62347f2013-03-01 16:37:30 -050018
19from tempest.common import glance_http
Ken'ichi Ohmichie76510d2016-03-02 10:33:48 -080020from tempest.lib.common import rest_client
Andrea Frittoli (andreaf)db9672e2016-02-23 14:07:24 -050021from tempest.lib import exceptions as lib_exc
Matthew Treinish684d8992014-01-30 16:27:40 +000022
Matthew Treinisha62347f2013-03-01 16:37:30 -050023
Yaroslav Lobankov2fea4052016-04-19 15:05:57 +030024class ImagesClient(rest_client.RestClient):
Matthew Treinisha62347f2013-03-01 16:37:30 -050025
Ken'ichi Ohmichie76510d2016-03-02 10:33:48 -080026 def __init__(self, auth_provider, catalog_type, region, **kwargs):
Yaroslav Lobankov2fea4052016-04-19 15:05:57 +030027 super(ImagesClient, self).__init__(
Ken'ichi Ohmichie76510d2016-03-02 10:33:48 -080028 auth_provider, catalog_type, region, **kwargs)
Andrea Frittoli8bbdb162014-01-06 11:06:13 +000029 self._http = None
Ken'ichi Ohmichie76510d2016-03-02 10:33:48 -080030 self.dscv = kwargs.get("disable_ssl_certificate_validation")
31 self.ca_certs = kwargs.get("ca_certs")
Matthew Treinisha62347f2013-03-01 16:37:30 -050032
33 def _get_http(self):
Andrea Frittoli8bbdb162014-01-06 11:06:13 +000034 return glance_http.HTTPClient(auth_provider=self.auth_provider,
35 filters=self.filters,
Masayuki Igawabc7e1892015-03-03 11:46:48 +090036 insecure=self.dscv,
37 ca_certs=self.ca_certs)
Matthew Treinisha62347f2013-03-01 16:37:30 -050038
Andrea Frittoli8bbdb162014-01-06 11:06:13 +000039 @property
40 def http(self):
41 if self._http is None:
Masayuki Igawabc7e1892015-03-03 11:46:48 +090042 self._http = self._get_http()
Andrea Frittoli8bbdb162014-01-06 11:06:13 +000043 return self._http
44
Sergey Nikitinc6b2ee82014-02-03 17:13:50 +040045 def update_image(self, image_id, patch):
Ken'ichi Ohmichi25b30162015-11-30 11:27:13 +000046 """Update an image.
47
48 Available params: see http://developer.openstack.org/
49 api-ref-image-v2.html#updateImage-v2
50 """
Sergey Nikitinc6b2ee82014-02-03 17:13:50 +040051 data = json.dumps(patch)
Sergey Nikitinc6b2ee82014-02-03 17:13:50 +040052 headers = {"Content-Type": "application/openstack-images-v2.0"
53 "-json-patch"}
54 resp, body = self.patch('v2/images/%s' % image_id, data, headers)
David Kranz9c3b3b62014-06-19 16:05:53 -040055 self.expected_success(200, resp.status)
ghanshyam08a73f92015-08-31 17:32:49 +090056 body = json.loads(body)
Ken'ichi Ohmichie76510d2016-03-02 10:33:48 -080057 return rest_client.ResponseBody(resp, body)
Sergey Nikitinc6b2ee82014-02-03 17:13:50 +040058
Ken'ichi Ohmichi25b30162015-11-30 11:27:13 +000059 def create_image(self, **kwargs):
60 """Create an image.
Matthew Treinishce3ef922013-03-11 14:02:46 -040061
Ken'ichi Ohmichi25b30162015-11-30 11:27:13 +000062 Available params: see http://developer.openstack.org/
63 api-ref-image-v2.html#createImage-v2
64 """
65 data = json.dumps(kwargs)
Valeriy Ponomaryov88686d82014-02-16 12:24:51 +020066 resp, body = self.post('v2/images', data)
David Kranz9c3b3b62014-06-19 16:05:53 -040067 self.expected_success(201, resp.status)
Matthew Treinisha62347f2013-03-01 16:37:30 -050068 body = json.loads(body)
Ken'ichi Ohmichie76510d2016-03-02 10:33:48 -080069 return rest_client.ResponseBody(resp, body)
Matthew Treinisha62347f2013-03-01 16:37:30 -050070
bkopilov81aaae72015-05-15 23:46:25 +030071 def deactivate_image(self, image_id):
72 url = 'v2/images/%s/actions/deactivate' % image_id
73 resp, body = self.post(url, None)
74 self.expected_success(204, resp.status)
Ken'ichi Ohmichie76510d2016-03-02 10:33:48 -080075 return rest_client.ResponseBody(resp, body)
bkopilov81aaae72015-05-15 23:46:25 +030076
77 def reactivate_image(self, image_id):
78 url = 'v2/images/%s/actions/reactivate' % image_id
79 resp, body = self.post(url, None)
80 self.expected_success(204, resp.status)
Ken'ichi Ohmichie76510d2016-03-02 10:33:48 -080081 return rest_client.ResponseBody(resp, body)
bkopilov81aaae72015-05-15 23:46:25 +030082
Matthew Treinisha62347f2013-03-01 16:37:30 -050083 def delete_image(self, image_id):
84 url = 'v2/images/%s' % image_id
David Kranz9c3b3b62014-06-19 16:05:53 -040085 resp, _ = self.delete(url)
86 self.expected_success(204, resp.status)
Ken'ichi Ohmichie76510d2016-03-02 10:33:48 -080087 return rest_client.ResponseBody(resp)
Matthew Treinisha62347f2013-03-01 16:37:30 -050088
Ken'ichi Ohmichie3acc122015-05-22 00:32:54 +000089 def list_images(self, params=None):
Matthew Treinisha62347f2013-03-01 16:37:30 -050090 url = 'v2/images'
91
92 if params:
93 url += '?%s' % urllib.urlencode(params)
94
95 resp, body = self.get(url)
David Kranz9c3b3b62014-06-19 16:05:53 -040096 self.expected_success(200, resp.status)
Matthew Treinisha62347f2013-03-01 16:37:30 -050097 body = json.loads(body)
Ken'ichi Ohmichie76510d2016-03-02 10:33:48 -080098 return rest_client.ResponseBody(resp, body)
Matthew Treinisha62347f2013-03-01 16:37:30 -050099
Ken'ichi Ohmichi5d410762015-05-22 01:10:03 +0000100 def show_image(self, image_id):
Matthew Treinisha62347f2013-03-01 16:37:30 -0500101 url = 'v2/images/%s' % image_id
102 resp, body = self.get(url)
David Kranz9c3b3b62014-06-19 16:05:53 -0400103 self.expected_success(200, resp.status)
Matthew Treinisha62347f2013-03-01 16:37:30 -0500104 body = json.loads(body)
Ken'ichi Ohmichie76510d2016-03-02 10:33:48 -0800105 return rest_client.ResponseBody(resp, body)
Matthew Treinisha62347f2013-03-01 16:37:30 -0500106
107 def is_resource_deleted(self, id):
108 try:
Ken'ichi Ohmichi5d410762015-05-22 01:10:03 +0000109 self.show_image(id)
Masayuki Igawabfa07602015-01-20 18:47:17 +0900110 except lib_exc.NotFound:
Matthew Treinisha62347f2013-03-01 16:37:30 -0500111 return True
112 return False
113
Matt Riedemannd2b96512014-10-13 10:18:16 -0700114 @property
115 def resource_type(self):
116 """Returns the primary type of resource this client works with."""
117 return 'image'
118
Ken'ichi Ohmichi66494e92015-06-08 04:28:10 +0000119 def store_image_file(self, image_id, data):
Matthew Treinisha62347f2013-03-01 16:37:30 -0500120 url = 'v2/images/%s/file' % image_id
121 headers = {'Content-Type': 'application/octet-stream'}
122 resp, body = self.http.raw_request('PUT', url, headers=headers,
123 body=data)
David Kranz9c3b3b62014-06-19 16:05:53 -0400124 self.expected_success(204, resp.status)
Ken'ichi Ohmichie76510d2016-03-02 10:33:48 -0800125 return rest_client.ResponseBody(resp, body)
Matthew Treinisha62347f2013-03-01 16:37:30 -0500126
Ken'ichi Ohmichi6bd6f202015-11-20 05:29:38 +0000127 def show_image_file(self, image_id):
Matthew Treinisha62347f2013-03-01 16:37:30 -0500128 url = 'v2/images/%s/file' % image_id
129 resp, body = self.get(url)
David Kranz9c3b3b62014-06-19 16:05:53 -0400130 self.expected_success(200, resp.status)
Ken'ichi Ohmichie76510d2016-03-02 10:33:48 -0800131 return rest_client.ResponseBodyData(resp, body)
Anju Tiwaric4952982013-10-20 07:10:02 +0530132
133 def add_image_tag(self, image_id, tag):
134 url = 'v2/images/%s/tags/%s' % (image_id, tag)
Valeriy Ponomaryov88686d82014-02-16 12:24:51 +0200135 resp, body = self.put(url, body=None)
David Kranz9c3b3b62014-06-19 16:05:53 -0400136 self.expected_success(204, resp.status)
Ken'ichi Ohmichie76510d2016-03-02 10:33:48 -0800137 return rest_client.ResponseBody(resp, body)
Anju Tiwaric4952982013-10-20 07:10:02 +0530138
139 def delete_image_tag(self, image_id, tag):
140 url = 'v2/images/%s/tags/%s' % (image_id, tag)
141 resp, _ = self.delete(url)
David Kranz9c3b3b62014-06-19 16:05:53 -0400142 self.expected_success(204, resp.status)
Ken'ichi Ohmichie76510d2016-03-02 10:33:48 -0800143 return rest_client.ResponseBody(resp)
Attila Fazekas689e2652013-10-07 18:06:57 +0200144
Ken'ichi Ohmichif0df53c2015-05-22 01:16:50 +0000145 def list_image_members(self, image_id):
Attila Fazekas689e2652013-10-07 18:06:57 +0200146 url = 'v2/images/%s/members' % image_id
147 resp, body = self.get(url)
David Kranz9c3b3b62014-06-19 16:05:53 -0400148 self.expected_success(200, resp.status)
Attila Fazekas689e2652013-10-07 18:06:57 +0200149 body = json.loads(body)
Ken'ichi Ohmichie76510d2016-03-02 10:33:48 -0800150 return rest_client.ResponseBody(resp, body)
Attila Fazekas689e2652013-10-07 18:06:57 +0200151
Ken'ichi Ohmichi9dacbe02015-11-30 12:01:39 +0000152 def create_image_member(self, image_id, **kwargs):
153 """Create an image member.
154
155 Available params: see http://developer.openstack.org/
156 api-ref-image-v2.html#createImageMember-v2
157 """
Attila Fazekas689e2652013-10-07 18:06:57 +0200158 url = 'v2/images/%s/members' % image_id
Ken'ichi Ohmichi2f8f6c22015-11-24 02:28:52 +0000159 data = json.dumps(kwargs)
Valeriy Ponomaryov88686d82014-02-16 12:24:51 +0200160 resp, body = self.post(url, data)
David Kranz9c3b3b62014-06-19 16:05:53 -0400161 self.expected_success(200, resp.status)
Attila Fazekas689e2652013-10-07 18:06:57 +0200162 body = json.loads(body)
Ken'ichi Ohmichie76510d2016-03-02 10:33:48 -0800163 return rest_client.ResponseBody(resp, body)
Attila Fazekas689e2652013-10-07 18:06:57 +0200164
Ken'ichi Ohmichi2f8f6c22015-11-24 02:28:52 +0000165 def update_image_member(self, image_id, member_id, **kwargs):
Ken'ichi Ohmichi5a1c9342015-11-30 12:12:19 +0000166 """Update an image member.
167
168 Available params: see http://developer.openstack.org/
169 api-ref-image-v2.html#updateImageMember-v2
170 """
Attila Fazekas689e2652013-10-07 18:06:57 +0200171 url = 'v2/images/%s/members/%s' % (image_id, member_id)
Ken'ichi Ohmichi2f8f6c22015-11-24 02:28:52 +0000172 data = json.dumps(kwargs)
Valeriy Ponomaryov88686d82014-02-16 12:24:51 +0200173 resp, body = self.put(url, data)
David Kranz9c3b3b62014-06-19 16:05:53 -0400174 self.expected_success(200, resp.status)
Attila Fazekas689e2652013-10-07 18:06:57 +0200175 body = json.loads(body)
Ken'ichi Ohmichie76510d2016-03-02 10:33:48 -0800176 return rest_client.ResponseBody(resp, body)
Sergey Nikitinc6b2ee82014-02-03 17:13:50 +0400177
Ken'ichi Ohmichic3728c62015-06-08 04:01:45 +0000178 def show_image_member(self, image_id, member_id):
Sergey Nikitinc6b2ee82014-02-03 17:13:50 +0400179 url = 'v2/images/%s/members/%s' % (image_id, member_id)
180 resp, body = self.get(url)
David Kranz9c3b3b62014-06-19 16:05:53 -0400181 self.expected_success(200, resp.status)
Ken'ichi Ohmichie76510d2016-03-02 10:33:48 -0800182 return rest_client.ResponseBody(resp, json.loads(body))
Sergey Nikitinc6b2ee82014-02-03 17:13:50 +0400183
Ken'ichi Ohmichib8461cb2015-11-20 08:10:51 +0000184 def delete_image_member(self, image_id, member_id):
Sergey Nikitinc6b2ee82014-02-03 17:13:50 +0400185 url = 'v2/images/%s/members/%s' % (image_id, member_id)
186 resp, _ = self.delete(url)
David Kranz9c3b3b62014-06-19 16:05:53 -0400187 self.expected_success(204, resp.status)
Ken'ichi Ohmichie76510d2016-03-02 10:33:48 -0800188 return rest_client.ResponseBody(resp)
raiesmh08a1ce3542014-03-04 11:58:29 +0530189
Ken'ichi Ohmichi66494e92015-06-08 04:28:10 +0000190 def show_schema(self, schema):
raiesmh08a1ce3542014-03-04 11:58:29 +0530191 url = 'v2/schemas/%s' % schema
192 resp, body = self.get(url)
David Kranz9c3b3b62014-06-19 16:05:53 -0400193 self.expected_success(200, resp.status)
raiesmh08a1ce3542014-03-04 11:58:29 +0530194 body = json.loads(body)
Ken'ichi Ohmichie76510d2016-03-02 10:33:48 -0800195 return rest_client.ResponseBody(resp, body)
piyush1107865f829d72015-09-11 11:46:35 +0530196
197 def list_resource_types(self):
198 url = '/v2/metadefs/resource_types'
199 resp, body = self.get(url)
200 self.expected_success(200, resp.status)
201 body = json.loads(body)
Ken'ichi Ohmichie76510d2016-03-02 10:33:48 -0800202 return rest_client.ResponseBody(resp, body)
piyush1107865f829d72015-09-11 11:46:35 +0530203
Ken'ichi Ohmichi2f8f6c22015-11-24 02:28:52 +0000204 def create_namespace(self, **kwargs):
205 """Create a namespace.
piyush1107865f829d72015-09-11 11:46:35 +0530206
Ken'ichi Ohmichi2f8f6c22015-11-24 02:28:52 +0000207 Available params: see http://developer.openstack.org/
208 api-ref-image-v2.html#createNamespace-v2
209 """
210 data = json.dumps(kwargs)
piyush1107865f829d72015-09-11 11:46:35 +0530211 resp, body = self.post('/v2/metadefs/namespaces', data)
212 self.expected_success(201, resp.status)
213 body = json.loads(body)
Ken'ichi Ohmichie76510d2016-03-02 10:33:48 -0800214 return rest_client.ResponseBody(resp, body)
piyush1107865f829d72015-09-11 11:46:35 +0530215
Ken'ichi Ohmichi19515632015-11-24 02:08:24 +0000216 def show_namespace(self, namespace):
piyush1107865f829d72015-09-11 11:46:35 +0530217 url = '/v2/metadefs/namespaces/%s' % namespace
218 resp, body = self.get(url)
219 self.expected_success(200, resp.status)
220 body = json.loads(body)
Ken'ichi Ohmichie76510d2016-03-02 10:33:48 -0800221 return rest_client.ResponseBody(resp, body)
piyush1107865f829d72015-09-11 11:46:35 +0530222
Ken'ichi Ohmichi2f8f6c22015-11-24 02:28:52 +0000223 def update_namespace(self, namespace, **kwargs):
224 """Update a namespace.
piyush1107865f829d72015-09-11 11:46:35 +0530225
Ken'ichi Ohmichi2f8f6c22015-11-24 02:28:52 +0000226 Available params: see http://developer.openstack.org/
227 api-ref-image-v2.html#updateNamespace-v2
228 """
229 # NOTE: On Glance API, we need to pass namespace on both URI
230 # and a request body.
231 params = {'namespace': namespace}
232 params.update(kwargs)
piyush1107865f829d72015-09-11 11:46:35 +0530233 data = json.dumps(params)
piyush1107865f829d72015-09-11 11:46:35 +0530234 url = '/v2/metadefs/namespaces/%s' % namespace
235 resp, body = self.put(url, body=data)
236 self.expected_success(200, resp.status)
237 body = json.loads(body)
Ken'ichi Ohmichie76510d2016-03-02 10:33:48 -0800238 return rest_client.ResponseBody(resp, body)
piyush1107865f829d72015-09-11 11:46:35 +0530239
Ken'ichi Ohmichi19515632015-11-24 02:08:24 +0000240 def delete_namespace(self, namespace):
piyush1107865f829d72015-09-11 11:46:35 +0530241 url = '/v2/metadefs/namespaces/%s' % namespace
242 resp, _ = self.delete(url)
243 self.expected_success(204, resp.status)
Ken'ichi Ohmichie76510d2016-03-02 10:33:48 -0800244 return rest_client.ResponseBody(resp)