blob: 6827c9306b38b81dea62293061023ef5d4cfdd48 [file] [log] [blame]
Giulio Fidente74b08ad2014-01-18 04:02:51 +01001# Copyright 2014 OpenStack Foundation
2# 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
Giulio Fidente74b08ad2014-01-18 04:02:51 +010016import time
17
Matthew Treinish21905512015-07-13 10:33:35 -040018from oslo_serialization import jsonutils as json
19
ravikumar-venkatesan18c1d0e2015-03-18 11:28:37 +000020from tempest_lib import exceptions as lib_exc
21
Joseph Lanoux6809bab2014-12-18 14:57:18 +000022from tempest.common import service_client
Giulio Fidente74b08ad2014-01-18 04:02:51 +010023from tempest import exceptions
Giulio Fidente74b08ad2014-01-18 04:02:51 +010024
25
Ken'ichi Ohmichia6287072015-07-02 02:43:15 +000026class BaseBackupsClient(service_client.ServiceClient):
Giulio Fidente74b08ad2014-01-18 04:02:51 +010027 """
28 Client class to send CRUD Volume backup API requests to a Cinder endpoint
29 """
30
Giulio Fidente74b08ad2014-01-18 04:02:51 +010031 def create_backup(self, volume_id, container=None, name=None,
32 description=None):
33 """Creates a backup of volume."""
34 post_body = {'volume_id': volume_id}
35 if container:
36 post_body['container'] = container
37 if name:
38 post_body['name'] = name
39 if description:
40 post_body['description'] = description
41 post_body = json.dumps({'backup': post_body})
42 resp, body = self.post('backups', post_body)
43 body = json.loads(body)
Swapnil Kulkarnid9df38c2014-08-16 18:06:52 +000044 self.expected_success(202, resp.status)
John Warren6cadeee2015-08-13 17:00:56 +000045 return service_client.ResponseBody(resp, body)
Giulio Fidente74b08ad2014-01-18 04:02:51 +010046
47 def restore_backup(self, backup_id, volume_id=None):
48 """Restore volume from backup."""
49 post_body = {'volume_id': volume_id}
50 post_body = json.dumps({'restore': post_body})
51 resp, body = self.post('backups/%s/restore' % (backup_id), post_body)
52 body = json.loads(body)
Swapnil Kulkarnid9df38c2014-08-16 18:06:52 +000053 self.expected_success(202, resp.status)
John Warren6cadeee2015-08-13 17:00:56 +000054 return service_client.ResponseBody(resp, body)
Giulio Fidente74b08ad2014-01-18 04:02:51 +010055
56 def delete_backup(self, backup_id):
57 """Delete a backup of volume."""
58 resp, body = self.delete('backups/%s' % (str(backup_id)))
Swapnil Kulkarnid9df38c2014-08-16 18:06:52 +000059 self.expected_success(202, resp.status)
Joseph Lanoux6809bab2014-12-18 14:57:18 +000060 return service_client.ResponseBody(resp, body)
Giulio Fidente74b08ad2014-01-18 04:02:51 +010061
Ken'ichi Ohmichi35798fb2015-04-06 01:22:41 +000062 def show_backup(self, backup_id):
Giulio Fidente74b08ad2014-01-18 04:02:51 +010063 """Returns the details of a single backup."""
64 url = "backups/%s" % str(backup_id)
65 resp, body = self.get(url)
66 body = json.loads(body)
Swapnil Kulkarnid9df38c2014-08-16 18:06:52 +000067 self.expected_success(200, resp.status)
John Warren6cadeee2015-08-13 17:00:56 +000068 return service_client.ResponseBody(resp, body)
Giulio Fidente74b08ad2014-01-18 04:02:51 +010069
Ken'ichi Ohmichi35798fb2015-04-06 01:22:41 +000070 def list_backups(self, detail=False):
raiesmh08f04da342014-02-28 17:14:43 +053071 """Information for all the tenant's backups."""
Ken'ichi Ohmichi35798fb2015-04-06 01:22:41 +000072 url = "backups"
73 if detail:
74 url += "/detail"
raiesmh08f04da342014-02-28 17:14:43 +053075 resp, body = self.get(url)
76 body = json.loads(body)
Swapnil Kulkarnid9df38c2014-08-16 18:06:52 +000077 self.expected_success(200, resp.status)
John Warren6cadeee2015-08-13 17:00:56 +000078 return service_client.ResponseBody(resp, body)
raiesmh08f04da342014-02-28 17:14:43 +053079
ravikumar-venkatesan18c1d0e2015-03-18 11:28:37 +000080 def export_backup(self, backup_id):
81 """Export backup metadata record."""
82 url = "backups/%s/export_record" % backup_id
83 resp, body = self.get(url)
84 body = json.loads(body)
85 self.expected_success(200, resp.status)
John Warren6cadeee2015-08-13 17:00:56 +000086 return service_client.ResponseBody(resp, body)
ravikumar-venkatesan18c1d0e2015-03-18 11:28:37 +000087
88 def import_backup(self, backup_service, backup_url):
89 """Import backup metadata record."""
90 post_body = {'backup_service': backup_service,
91 'backup_url': backup_url}
92 post_body = json.dumps({'backup-record': post_body})
93 resp, body = self.post("backups/import_record", post_body)
94 body = json.loads(body)
95 self.expected_success(201, resp.status)
John Warren6cadeee2015-08-13 17:00:56 +000096 return service_client.ResponseBody(resp, body)
ravikumar-venkatesan18c1d0e2015-03-18 11:28:37 +000097
Giulio Fidente74b08ad2014-01-18 04:02:51 +010098 def wait_for_backup_status(self, backup_id, status):
99 """Waits for a Backup to reach a given status."""
John Warren6cadeee2015-08-13 17:00:56 +0000100 body = self.show_backup(backup_id)['backup']
Giulio Fidente74b08ad2014-01-18 04:02:51 +0100101 backup_status = body['status']
102 start = int(time.time())
103
104 while backup_status != status:
105 time.sleep(self.build_interval)
John Warren6cadeee2015-08-13 17:00:56 +0000106 body = self.show_backup(backup_id)['backup']
Giulio Fidente74b08ad2014-01-18 04:02:51 +0100107 backup_status = body['status']
108 if backup_status == 'error':
109 raise exceptions.VolumeBackupException(backup_id=backup_id)
110
111 if int(time.time()) - start >= self.build_timeout:
Martin Pavlasek1102c3a2014-10-20 17:17:55 +0200112 message = ('Volume backup %s failed to reach %s status '
113 '(current %s) within the required time (%s s).' %
114 (backup_id, status, backup_status,
115 self.build_timeout))
Giulio Fidente74b08ad2014-01-18 04:02:51 +0100116 raise exceptions.TimeoutException(message)
jun xieebc3da32014-11-18 14:34:56 +0800117
ravikumar-venkatesan18c1d0e2015-03-18 11:28:37 +0000118 def wait_for_backup_deletion(self, backup_id):
119 """Waits for backup deletion"""
120 start_time = int(time.time())
121 while True:
122 try:
123 self.show_backup(backup_id)
124 except lib_exc.NotFound:
125 return
126 if int(time.time()) - start_time >= self.build_timeout:
127 raise exceptions.TimeoutException
128 time.sleep(self.build_interval)
129
jun xieebc3da32014-11-18 14:34:56 +0800130
Ken'ichi Ohmichia6287072015-07-02 02:43:15 +0000131class BackupsClient(BaseBackupsClient):
jun xieebc3da32014-11-18 14:34:56 +0800132 """Volume V1 Backups client"""