blob: 479402af12016d6f50b4baa65e0dcccf651930e9 [file] [log] [blame]
Roman Prykhodchenko62b1ed12013-10-16 21:51:47 +03001# Licensed under the Apache License, Version 2.0 (the "License"); you may
2# not use this file except in compliance with the License. You may obtain
3# a copy of the License at
4#
5# http://www.apache.org/licenses/LICENSE-2.0
6#
7# Unless required by applicable law or agreed to in writing, software
8# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
9# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
10# License for the specific language governing permissions and limitations
11# under the License.
12
13from tempest.services.baremetal import base
14
15
Ken'ichi Ohmichia6287072015-07-02 02:43:15 +000016class BaremetalClient(base.BaremetalClient):
Roman Prykhodchenko62b1ed12013-10-16 21:51:47 +030017 """
18 Base Tempest REST client for Ironic API v1.
Roman Prykhodchenko62b1ed12013-10-16 21:51:47 +030019 """
Ken'ichi Ohmichi1f88ece2015-01-23 03:33:11 +000020 version = '1'
21 uri_prefix = 'v1'
Roman Prykhodchenko62b1ed12013-10-16 21:51:47 +030022
23 @base.handle_errors
Adam Gandelman00682612014-09-02 17:10:36 -070024 def list_nodes(self, **kwargs):
Roman Prykhodchenko62b1ed12013-10-16 21:51:47 +030025 """List all existing nodes."""
Adam Gandelman00682612014-09-02 17:10:36 -070026 return self._list_request('nodes', **kwargs)
Roman Prykhodchenko62b1ed12013-10-16 21:51:47 +030027
28 @base.handle_errors
29 def list_chassis(self):
30 """List all existing chassis."""
31 return self._list_request('chassis')
32
33 @base.handle_errors
Adam Gandelman00682612014-09-02 17:10:36 -070034 def list_chassis_nodes(self, chassis_uuid):
35 """List all nodes associated with a chassis."""
36 return self._list_request('/chassis/%s/nodes' % chassis_uuid)
37
38 @base.handle_errors
Sergey Nikitin0d43eb52014-02-03 14:50:02 +040039 def list_ports(self, **kwargs):
Roman Prykhodchenko62b1ed12013-10-16 21:51:47 +030040 """List all existing ports."""
Sergey Nikitin0d43eb52014-02-03 14:50:02 +040041 return self._list_request('ports', **kwargs)
42
43 @base.handle_errors
Adam Gandelman00682612014-09-02 17:10:36 -070044 def list_node_ports(self, uuid):
45 """List all ports associated with the node."""
46 return self._list_request('/nodes/%s/ports' % uuid)
47
48 @base.handle_errors
Mh Raiesfbe54512014-04-08 12:25:15 +053049 def list_nodestates(self, uuid):
50 """List all existing states."""
51 return self._list_request('/nodes/%s/states' % uuid)
52
53 @base.handle_errors
Yuiko Takada3083fca2014-04-25 11:52:33 +000054 def list_ports_detail(self, **kwargs):
Sergey Nikitin0d43eb52014-02-03 14:50:02 +040055 """Details list all existing ports."""
Yuiko Takada3083fca2014-04-25 11:52:33 +000056 return self._list_request('/ports/detail', **kwargs)
Roman Prykhodchenko62b1ed12013-10-16 21:51:47 +030057
58 @base.handle_errors
Mh Raiesb71cb7f2014-03-28 10:51:31 +053059 def list_drivers(self):
60 """List all existing drivers."""
61 return self._list_request('drivers')
62
63 @base.handle_errors
Roman Prykhodchenko62b1ed12013-10-16 21:51:47 +030064 def show_node(self, uuid):
65 """
66 Gets a specific node.
67
68 :param uuid: Unique identifier of the node in UUID format.
69 :return: Serialized node as a dictionary.
70
71 """
72 return self._show_request('nodes', uuid)
73
74 @base.handle_errors
Adam Gandelman00682612014-09-02 17:10:36 -070075 def show_node_by_instance_uuid(self, instance_uuid):
76 """
77 Gets a node associated with given instance uuid.
78
79 :param uuid: Unique identifier of the node in UUID format.
80 :return: Serialized node as a dictionary.
81
82 """
83 uri = '/nodes/detail?instance_uuid=%s' % instance_uuid
84
85 return self._show_request('nodes',
86 uuid=None,
87 uri=uri)
88
89 @base.handle_errors
Roman Prykhodchenko62b1ed12013-10-16 21:51:47 +030090 def show_chassis(self, uuid):
91 """
92 Gets a specific chassis.
93
94 :param uuid: Unique identifier of the chassis in UUID format.
95 :return: Serialized chassis as a dictionary.
96
97 """
98 return self._show_request('chassis', uuid)
99
100 @base.handle_errors
101 def show_port(self, uuid):
102 """
103 Gets a specific port.
104
105 :param uuid: Unique identifier of the port in UUID format.
106 :return: Serialized port as a dictionary.
107
108 """
109 return self._show_request('ports', uuid)
110
Kan3fd5d892015-01-26 01:36:01 -0800111 @base.handle_errors
112 def show_port_by_address(self, address):
113 """
114 Gets a specific port by address.
115
116 :param address: MAC address of the port.
117 :return: Serialized port as a dictionary.
118
119 """
120 uri = '/ports/detail?address=%s' % address
121
122 return self._show_request('ports', uuid=None, uri=uri)
123
Yuiko Takada8e2dfca2014-04-24 18:10:52 +0000124 def show_driver(self, driver_name):
125 """
126 Gets a specific driver.
127
128 :param driver_name: Name of driver.
129 :return: Serialized driver as a dictionary.
130 """
131 return self._show_request('drivers', driver_name)
132
Roman Prykhodchenko62b1ed12013-10-16 21:51:47 +0300133 @base.handle_errors
Adam Gandelman118cd392015-03-09 14:41:36 -0700134 def create_node(self, chassis_id=None, **kwargs):
Roman Prykhodchenko62b1ed12013-10-16 21:51:47 +0300135 """
136 Create a baremetal node with the specified parameters.
137
138 :param cpu_arch: CPU architecture of the node. Default: x86_64.
Adam Gandelman3ea1eb82015-02-18 19:13:25 -0800139 :param cpus: Number of CPUs. Default: 8.
140 :param local_gb: Disk size. Default: 1024.
141 :param memory_mb: Available RAM. Default: 4096.
Roman Prykhodchenko62b1ed12013-10-16 21:51:47 +0300142 :param driver: Driver name. Default: "fake"
143 :return: A tuple with the server response and the created node.
144
145 """
146 node = {'chassis_uuid': chassis_id,
147 'properties': {'cpu_arch': kwargs.get('cpu_arch', 'x86_64'),
Adam Gandelman3ea1eb82015-02-18 19:13:25 -0800148 'cpus': kwargs.get('cpus', 8),
149 'local_gb': kwargs.get('local_gb', 1024),
150 'memory_mb': kwargs.get('memory_mb', 4096)},
Roman Prykhodchenko62b1ed12013-10-16 21:51:47 +0300151 'driver': kwargs.get('driver', 'fake')}
152
Ken'ichi Ohmichi19b6ff52015-01-23 02:45:50 +0000153 return self._create_request('nodes', node)
Roman Prykhodchenko62b1ed12013-10-16 21:51:47 +0300154
155 @base.handle_errors
156 def create_chassis(self, **kwargs):
157 """
158 Create a chassis with the specified parameters.
159
160 :param description: The description of the chassis.
161 Default: test-chassis
162 :return: A tuple with the server response and the created chassis.
163
164 """
165 chassis = {'description': kwargs.get('description', 'test-chassis')}
166
Ken'ichi Ohmichi19b6ff52015-01-23 02:45:50 +0000167 return self._create_request('chassis', chassis)
Roman Prykhodchenko62b1ed12013-10-16 21:51:47 +0300168
169 @base.handle_errors
170 def create_port(self, node_id, **kwargs):
171 """
172 Create a port with the specified parameters.
173
174 :param node_id: The ID of the node which owns the port.
Sergey Nikitin0d43eb52014-02-03 14:50:02 +0400175 :param address: MAC address of the port.
176 :param extra: Meta data of the port. Default: {'foo': 'bar'}.
177 :param uuid: UUID of the port.
Roman Prykhodchenko62b1ed12013-10-16 21:51:47 +0300178 :return: A tuple with the server response and the created port.
179
180 """
Sergey Nikitin0d43eb52014-02-03 14:50:02 +0400181 port = {'extra': kwargs.get('extra', {'foo': 'bar'}),
182 'uuid': kwargs['uuid']}
183
184 if node_id is not None:
185 port['node_uuid'] = node_id
186
187 if kwargs['address'] is not None:
188 port['address'] = kwargs['address']
Roman Prykhodchenko62b1ed12013-10-16 21:51:47 +0300189
Ken'ichi Ohmichi19b6ff52015-01-23 02:45:50 +0000190 return self._create_request('ports', port)
Roman Prykhodchenko62b1ed12013-10-16 21:51:47 +0300191
192 @base.handle_errors
193 def delete_node(self, uuid):
194 """
195 Deletes a node having the specified UUID.
196
197 :param uuid: The unique identifier of the node.
198 :return: A tuple with the server response and the response body.
199
200 """
201 return self._delete_request('nodes', uuid)
202
203 @base.handle_errors
204 def delete_chassis(self, uuid):
205 """
206 Deletes a chassis having the specified UUID.
207
208 :param uuid: The unique identifier of the chassis.
209 :return: A tuple with the server response and the response body.
210
211 """
212 return self._delete_request('chassis', uuid)
213
214 @base.handle_errors
215 def delete_port(self, uuid):
216 """
217 Deletes a port having the specified UUID.
218
219 :param uuid: The unique identifier of the port.
220 :return: A tuple with the server response and the response body.
221
222 """
223 return self._delete_request('ports', uuid)
224
225 @base.handle_errors
226 def update_node(self, uuid, **kwargs):
227 """
228 Update the specified node.
229
230 :param uuid: The unique identifier of the node.
231 :return: A tuple with the server response and the updated node.
232
233 """
234 node_attributes = ('properties/cpu_arch',
Adam Gandelman3ea1eb82015-02-18 19:13:25 -0800235 'properties/cpus',
236 'properties/local_gb',
237 'properties/memory_mb',
Adam Gandelman00682612014-09-02 17:10:36 -0700238 'driver',
239 'instance_uuid')
Roman Prykhodchenko62b1ed12013-10-16 21:51:47 +0300240
241 patch = self._make_patch(node_attributes, **kwargs)
242
243 return self._patch_request('nodes', uuid, patch)
244
245 @base.handle_errors
246 def update_chassis(self, uuid, **kwargs):
247 """
248 Update the specified chassis.
249
250 :param uuid: The unique identifier of the chassis.
251 :return: A tuple with the server response and the updated chassis.
252
253 """
254 chassis_attributes = ('description',)
255 patch = self._make_patch(chassis_attributes, **kwargs)
256
257 return self._patch_request('chassis', uuid, patch)
258
259 @base.handle_errors
Sergey Nikitin0d43eb52014-02-03 14:50:02 +0400260 def update_port(self, uuid, patch):
Roman Prykhodchenko62b1ed12013-10-16 21:51:47 +0300261 """
262 Update the specified port.
263
264 :param uuid: The unique identifier of the port.
Sergey Nikitin0d43eb52014-02-03 14:50:02 +0400265 :param patch: List of dicts representing json patches.
Roman Prykhodchenko62b1ed12013-10-16 21:51:47 +0300266 :return: A tuple with the server response and the updated port.
267
268 """
Roman Prykhodchenko62b1ed12013-10-16 21:51:47 +0300269
270 return self._patch_request('ports', uuid, patch)
Mh Raiesf8ecf232014-04-17 12:43:55 +0530271
272 @base.handle_errors
273 def set_node_power_state(self, node_uuid, state):
274 """
275 Set power state of the specified node.
276
277 :param node_uuid: The unique identifier of the node.
278 :state: desired state to set (on/off/reboot).
279
280 """
281 target = {'target': state}
282 return self._put_request('nodes/%s/states/power' % node_uuid,
283 target)
raiesmh08e5d84572014-06-23 09:49:03 +0530284
285 @base.handle_errors
286 def validate_driver_interface(self, node_uuid):
287 """
288 Get all driver interfaces of a specific node.
289
290 :param uuid: Unique identifier of the node in UUID format.
291
292 """
293
294 uri = '{pref}/{res}/{uuid}/{postf}'.format(pref=self.uri_prefix,
295 res='nodes',
296 uuid=node_uuid,
297 postf='validate')
298
299 return self._show_request('nodes', node_uuid, uri=uri)
Lucas Alvares Gomes5d236cf2014-08-11 15:23:12 +0100300
301 @base.handle_errors
302 def set_node_boot_device(self, node_uuid, boot_device, persistent=False):
303 """
304 Set the boot device of the specified node.
305
306 :param node_uuid: The unique identifier of the node.
307 :param boot_device: The boot device name.
308 :param persistent: Boolean value. True if the boot device will
309 persist to all future boots, False if not.
310 Default: False.
311
312 """
313 request = {'boot_device': boot_device, 'persistent': persistent}
314 resp, body = self._put_request('nodes/%s/management/boot_device' %
315 node_uuid, request)
316 self.expected_success(204, resp.status)
317 return body
318
319 @base.handle_errors
320 def get_node_boot_device(self, node_uuid):
321 """
322 Get the current boot device of the specified node.
323
324 :param node_uuid: The unique identifier of the node.
325
326 """
327 path = 'nodes/%s/management/boot_device' % node_uuid
328 resp, body = self._list_request(path)
329 self.expected_success(200, resp.status)
330 return body
331
332 @base.handle_errors
333 def get_node_supported_boot_devices(self, node_uuid):
334 """
335 Get the supported boot devices of the specified node.
336
337 :param node_uuid: The unique identifier of the node.
338
339 """
340 path = 'nodes/%s/management/boot_device/supported' % node_uuid
341 resp, body = self._list_request(path)
342 self.expected_success(200, resp.status)
343 return body
Yuiko Takadabbf5cff2014-08-29 17:09:06 +0900344
345 @base.handle_errors
346 def get_console(self, node_uuid):
347 """
348 Get connection information about the console.
349
350 :param node_uuid: Unique identifier of the node in UUID format.
351
352 """
353
354 resp, body = self._show_request('nodes/states/console', node_uuid)
355 self.expected_success(200, resp.status)
356 return resp, body
357
358 @base.handle_errors
359 def set_console_mode(self, node_uuid, enabled):
360 """
361 Start and stop the node console.
362
363 :param node_uuid: Unique identifier of the node in UUID format.
364 :param enabled: Boolean value; whether to enable or disable the
365 console.
366
367 """
368
369 enabled = {'enabled': enabled}
370 resp, body = self._put_request('nodes/%s/states/console' % node_uuid,
371 enabled)
372 self.expected_success(202, resp.status)
373 return resp, body