blob: 329c54d9fcb3e3267f5ab06d6f0a1cf463157955 [file] [log] [blame]
Yair Fried1fc32a12014-08-04 09:11:30 +03001# Copyright 2013 Hewlett-Packard Development Company, L.P.
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
16import abc
Ken'ichi Ohmichi3ed6a552016-03-21 12:55:40 -070017import time
Yair Fried1fc32a12014-08-04 09:11:30 +030018
19import six
20
Ken'ichi Ohmichi3ed6a552016-03-21 12:55:40 -070021from tempest import exceptions
22from tempest.lib.common.utils import misc
23
Yair Fried1fc32a12014-08-04 09:11:30 +030024
25class AttributeDict(dict):
Ken'ichi Ohmichib2790842015-11-17 11:46:13 +000026 """Provide attribute access (dict.key) to dictionary values."""
Yair Fried1fc32a12014-08-04 09:11:30 +030027
28 def __getattr__(self, name):
29 """Allow attribute access for all keys in the dict."""
30 if name in self:
31 return self[name]
32 return super(AttributeDict, self).__getattribute__(name)
33
34
35@six.add_metaclass(abc.ABCMeta)
36class DeletableResource(AttributeDict):
Ken'ichi Ohmichib2790842015-11-17 11:46:13 +000037 """Support deletion of neutron resources (networks, subnets)
Yair Fried1fc32a12014-08-04 09:11:30 +030038
Ken'ichi Ohmichib2790842015-11-17 11:46:13 +000039 via a delete() method, as is supported by keystone and nova resources.
Yair Fried1fc32a12014-08-04 09:11:30 +030040 """
41
42 def __init__(self, *args, **kwargs):
43 self.client = kwargs.pop('client', None)
John Warren94d8faf2015-09-15 12:22:24 -040044 self.networks_client = kwargs.pop('networks_client', None)
Ken'ichi Ohmichie35f4722015-12-22 04:57:11 +000045 self.routers_client = kwargs.pop('routers_client', None)
John Warren3961acd2015-10-02 14:38:53 -040046 self.subnets_client = kwargs.pop('subnets_client', None)
John Warren49c0fe52015-10-22 12:35:54 -040047 self.ports_client = kwargs.pop('ports_client', None)
Yair Fried1fc32a12014-08-04 09:11:30 +030048 super(DeletableResource, self).__init__(*args, **kwargs)
49
50 def __str__(self):
51 return '<%s id="%s" name="%s">' % (self.__class__.__name__,
52 self.id, self.name)
53
54 @abc.abstractmethod
55 def delete(self):
56 return
57
Miguel Lavalle02ba8cd2014-09-01 19:23:22 -050058 @abc.abstractmethod
Yair Fried45f92952014-06-26 05:19:19 +030059 def refresh(self):
Miguel Lavalle02ba8cd2014-09-01 19:23:22 -050060 return
61
Yair Fried1fc32a12014-08-04 09:11:30 +030062 def __hash__(self):
63 return hash(self.id)
64
Miguel Lavalle02ba8cd2014-09-01 19:23:22 -050065 def wait_for_status(self, status):
66 if not hasattr(self, 'status'):
67 return
68
Yair Fried45f92952014-06-26 05:19:19 +030069 def helper_get():
70 self.refresh()
71 return self
72
Ken'ichi Ohmichi3ed6a552016-03-21 12:55:40 -070073 return self.wait_for_resource_status(helper_get, status)
74
75 def wait_for_resource_status(self, fetch, status):
76 """Waits for a network resource to reach a status
77
78 @param fetch: the callable to be used to query the resource status
79 @type fecth: callable that takes no parameters and returns the resource
80 @param status: the status that the resource has to reach
81 @type status: String
82 """
83 interval = self.build_interval
84 timeout = self.build_timeout
85 start_time = time.time()
86
87 while time.time() - start_time <= timeout:
88 resource = fetch()
89 if resource['status'] == status:
90 return
91 time.sleep(interval)
92
93 # At this point, the wait has timed out
94 message = 'Resource %s' % (str(resource))
95 message += ' failed to reach status %s' % status
96 message += ' (current: %s)' % resource['status']
97 message += ' within the required time %s' % timeout
98 caller = misc.find_test_caller()
99 if caller:
100 message = '(%s) %s' % (caller, message)
101 raise exceptions.TimeoutException(message)
Miguel Lavalle02ba8cd2014-09-01 19:23:22 -0500102
Yair Fried1fc32a12014-08-04 09:11:30 +0300103
104class DeletableNetwork(DeletableResource):
105
106 def delete(self):
John Warren94d8faf2015-09-15 12:22:24 -0400107 self.networks_client.delete_network(self.id)
Yair Fried1fc32a12014-08-04 09:11:30 +0300108
109
110class DeletableSubnet(DeletableResource):
111
112 def __init__(self, *args, **kwargs):
113 super(DeletableSubnet, self).__init__(*args, **kwargs)
114 self._router_ids = set()
115
116 def update(self, *args, **kwargs):
John Warren3961acd2015-10-02 14:38:53 -0400117 result = self.subnets_client.update_subnet(self.id,
118 *args,
119 **kwargs)
Yair Fried413bf2d2014-11-19 17:07:11 +0200120 return super(DeletableSubnet, self).update(**result['subnet'])
Yair Fried1fc32a12014-08-04 09:11:30 +0300121
122 def add_to_router(self, router_id):
123 self._router_ids.add(router_id)
Ken'ichi Ohmichie35f4722015-12-22 04:57:11 +0000124 self.routers_client.add_router_interface(router_id,
piyush11078694aca952015-12-17 12:54:44 +0530125 subnet_id=self.id)
Yair Fried1fc32a12014-08-04 09:11:30 +0300126
127 def delete(self):
128 for router_id in self._router_ids.copy():
Ken'ichi Ohmichie35f4722015-12-22 04:57:11 +0000129 self.routers_client.remove_router_interface(router_id,
piyush11078694aca952015-12-17 12:54:44 +0530130 subnet_id=self.id)
Yair Fried1fc32a12014-08-04 09:11:30 +0300131 self._router_ids.remove(router_id)
John Warren3961acd2015-10-02 14:38:53 -0400132 self.subnets_client.delete_subnet(self.id)
Yair Fried1fc32a12014-08-04 09:11:30 +0300133
134
135class DeletableRouter(DeletableResource):
136
137 def set_gateway(self, network_id):
138 return self.update(external_gateway_info=dict(network_id=network_id))
139
140 def unset_gateway(self):
141 return self.update(external_gateway_info=dict())
142
143 def update(self, *args, **kwargs):
Ken'ichi Ohmichie35f4722015-12-22 04:57:11 +0000144 result = self.routers_client.update_router(self.id,
145 *args,
146 **kwargs)
Yair Fried1fc32a12014-08-04 09:11:30 +0300147 return super(DeletableRouter, self).update(**result['router'])
148
149 def delete(self):
150 self.unset_gateway()
Ken'ichi Ohmichie35f4722015-12-22 04:57:11 +0000151 self.routers_client.delete_router(self.id)
Yair Fried1fc32a12014-08-04 09:11:30 +0300152
153
154class DeletableFloatingIp(DeletableResource):
155
Yair Fried45f92952014-06-26 05:19:19 +0300156 def refresh(self, *args, **kwargs):
David Kranz34e88122014-12-11 15:24:05 -0500157 result = self.client.show_floatingip(self.id,
158 *args,
159 **kwargs)
Yair Fried45f92952014-06-26 05:19:19 +0300160 super(DeletableFloatingIp, self).update(**result['floatingip'])
161
Yair Fried1fc32a12014-08-04 09:11:30 +0300162 def update(self, *args, **kwargs):
David Kranz34e88122014-12-11 15:24:05 -0500163 result = self.client.update_floatingip(self.id,
164 *args,
165 **kwargs)
Yair Fried1fc32a12014-08-04 09:11:30 +0300166 super(DeletableFloatingIp, self).update(**result['floatingip'])
167
168 def __repr__(self):
169 return '<%s addr="%s">' % (self.__class__.__name__,
170 self.floating_ip_address)
171
172 def __str__(self):
173 return '<"FloatingIP" addr="%s" id="%s">' % (self.floating_ip_address,
174 self.id)
175
176 def delete(self):
177 self.client.delete_floatingip(self.id)
178
179
180class DeletablePort(DeletableResource):
181
182 def delete(self):
John Warren49c0fe52015-10-22 12:35:54 -0400183 self.ports_client.delete_port(self.id)
Yair Fried1fc32a12014-08-04 09:11:30 +0300184
185
186class DeletableSecurityGroup(DeletableResource):
187
188 def delete(self):
189 self.client.delete_security_group(self.id)
190
191
192class DeletableSecurityGroupRule(DeletableResource):
193
194 def __repr__(self):
195 return '<%s id="%s">' % (self.__class__.__name__, self.id)
196
197 def delete(self):
198 self.client.delete_security_group_rule(self.id)
199
200
201class DeletablePool(DeletableResource):
202
203 def delete(self):
204 self.client.delete_pool(self.id)
205
206
207class DeletableMember(DeletableResource):
208
209 def delete(self):
210 self.client.delete_member(self.id)
211
212
213class DeletableVip(DeletableResource):
214
215 def delete(self):
216 self.client.delete_vip(self.id)
Miguel Lavalle02ba8cd2014-09-01 19:23:22 -0500217
Yair Fried45f92952014-06-26 05:19:19 +0300218 def refresh(self):
David Kranz34e88122014-12-11 15:24:05 -0500219 result = self.client.show_vip(self.id)
220 super(DeletableVip, self).update(**result['vip'])