blob: 9c13cacf0733eef402263eb8617d6058cc1b5b89 [file] [log] [blame]
Swapnil Kulkarni7dba3e62014-08-14 09:05:07 +00001# All Rights Reserved.
2#
3# Licensed under the Apache License, Version 2.0 (the "License"); you may
4# not use this file except in compliance with the License. You may obtain
5# a copy of the License at
6#
7# http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12# License for the specific language governing permissions and limitations
13# under the License.
14
15import json
16import time
17
Swapnil Kulkarni7dba3e62014-08-14 09:05:07 +000018from tempest import exceptions
Ken'ichi Ohmichia39d0be2014-12-17 08:46:11 +000019from tempest.services.volume.json import base
Swapnil Kulkarni7dba3e62014-08-14 09:05:07 +000020
21
Ken'ichi Ohmichia39d0be2014-12-17 08:46:11 +000022class BaseQosSpecsClientJSON(base.VolumeClient):
Swapnil Kulkarni7dba3e62014-08-14 09:05:07 +000023 """Client class to send CRUD QoS API requests"""
24
Swapnil Kulkarni7dba3e62014-08-14 09:05:07 +000025 def is_resource_deleted(self, qos_id):
26 try:
27 self.get_qos(qos_id)
28 except exceptions.NotFound:
29 return True
30 return False
31
Matt Riedemannd2b96512014-10-13 10:18:16 -070032 @property
33 def resource_type(self):
34 """Returns the primary type of resource this client works with."""
35 return 'qos'
36
Swapnil Kulkarni7dba3e62014-08-14 09:05:07 +000037 def wait_for_qos_operations(self, qos_id, operation, args=None):
38 """Waits for a qos operations to be completed.
39
40 NOTE : operation value is required for wait_for_qos_operations()
41 operation = 'qos-key' / 'disassociate' / 'disassociate-all'
42 args = keys[] when operation = 'qos-key'
43 args = volume-type-id disassociated when operation = 'disassociate'
44 args = None when operation = 'disassociate-all'
45 """
46 start_time = int(time.time())
47 while True:
48 if operation == 'qos-key-unset':
49 resp, body = self.get_qos(qos_id)
50 self.expected_success(200, resp.status)
51 if not any(key in body['specs'] for key in args):
52 return
53 elif operation == 'disassociate':
54 resp, body = self.get_association_qos(qos_id)
55 self.expected_success(200, resp.status)
56 if not any(args in body[i]['id'] for i in range(0, len(body))):
57 return
58 elif operation == 'disassociate-all':
59 resp, body = self.get_association_qos(qos_id)
60 self.expected_success(200, resp.status)
61 if not body:
62 return
63 else:
64 msg = (" operation value is either not defined or incorrect.")
65 raise exceptions.UnprocessableEntity(msg)
66
67 if int(time.time()) - start_time >= self.build_timeout:
68 raise exceptions.TimeoutException
69 time.sleep(self.build_interval)
70
71 def create_qos(self, name, consumer, **kwargs):
72 """Create a QoS Specification.
73
74 name : name of the QoS specifications
75 consumer : conumer of Qos ( front-end / back-end / both )
76 """
77 post_body = {'name': name, 'consumer': consumer}
78 post_body.update(kwargs)
79 post_body = json.dumps({'qos_specs': post_body})
80 resp, body = self.post('qos-specs', post_body)
81 self.expected_success(200, resp.status)
82 body = json.loads(body)
83 return resp, body['qos_specs']
84
85 def delete_qos(self, qos_id, force=False):
86 """Delete the specified QoS specification."""
87 resp, body = self.delete(
88 "qos-specs/%s?force=%s" % (str(qos_id), force))
89 self.expected_success(202, resp.status)
90
91 def list_qos(self):
92 """List all the QoS specifications created."""
93 url = 'qos-specs'
94 resp, body = self.get(url)
95 body = json.loads(body)
96 self.expected_success(200, resp.status)
97 return resp, body['qos_specs']
98
99 def get_qos(self, qos_id):
100 """Get the specified QoS specification."""
101 url = "qos-specs/%s" % str(qos_id)
102 resp, body = self.get(url)
103 body = json.loads(body)
104 self.expected_success(200, resp.status)
105 return resp, body['qos_specs']
106
107 def set_qos_key(self, qos_id, **kwargs):
108 """Set the specified keys/values of QoS specification.
109
110 kwargs : it is the dictionary of the key=value pairs to set
111 """
112 put_body = json.dumps({"qos_specs": kwargs})
113 resp, body = self.put('qos-specs/%s' % qos_id, put_body)
114 body = json.loads(body)
115 self.expected_success(200, resp.status)
116 return resp, body['qos_specs']
117
118 def unset_qos_key(self, qos_id, keys):
119 """Unset the specified keys of QoS specification.
120
121 keys : it is the array of the keys to unset
122 """
123 put_body = json.dumps({'keys': keys})
124 resp, _ = self.put('qos-specs/%s/delete_keys' % qos_id, put_body)
125 self.expected_success(202, resp.status)
126
127 def associate_qos(self, qos_id, vol_type_id):
128 """Associate the specified QoS with specified volume-type."""
129 url = "qos-specs/%s/associate" % str(qos_id)
130 url += "?vol_type_id=%s" % vol_type_id
131 resp, _ = self.get(url)
132 self.expected_success(202, resp.status)
133
134 def get_association_qos(self, qos_id):
135 """Get the association of the specified QoS specification."""
136 url = "qos-specs/%s/associations" % str(qos_id)
137 resp, body = self.get(url)
138 body = json.loads(body)
139 self.expected_success(200, resp.status)
140 return resp, body['qos_associations']
141
142 def disassociate_qos(self, qos_id, vol_type_id):
143 """Disassociate the specified QoS with specified volume-type."""
144 url = "qos-specs/%s/disassociate" % str(qos_id)
145 url += "?vol_type_id=%s" % vol_type_id
146 resp, _ = self.get(url)
147 self.expected_success(202, resp.status)
148
149 def disassociate_all_qos(self, qos_id):
150 """Disassociate the specified QoS with all associations."""
151 url = "qos-specs/%s/disassociate_all" % str(qos_id)
152 resp, _ = self.get(url)
153 self.expected_success(202, resp.status)
154
155
156class QosSpecsClientJSON(BaseQosSpecsClientJSON):
157 """Volume V1 QoS client."""