|
15 | 15 | # License for the specific language governing permissions and limitations |
16 | 16 | # under the License. |
17 | 17 |
|
18 | | -""" |
19 | | -Base utilities to build API operation managers and objects on top of. |
20 | | -""" |
21 | | - |
| 18 | +from novaclient import base |
22 | 19 | from novaclient import exceptions |
23 | 20 |
|
24 | | -# Python 2.4 compat |
25 | | -try: |
26 | | - all |
27 | | -except NameError: |
28 | | - def all(iterable): |
29 | | - return True not in (not x for x in iterable) |
30 | | - |
31 | | - |
32 | | -def getid(obj): |
33 | | - """ |
34 | | - Abstracts the common pattern of allowing both an object or an object's ID |
35 | | - (UUID) as a parameter when dealing with relationships. |
36 | | - """ |
37 | | - |
38 | | - # Try to return the object's UUID first, if we have a UUID. |
39 | | - try: |
40 | | - if obj.uuid: |
41 | | - return obj.uuid |
42 | | - except AttributeError: |
43 | | - pass |
44 | | - try: |
45 | | - return obj.id |
46 | | - except AttributeError: |
47 | | - return obj |
48 | | - |
49 | | - |
50 | | -class Manager(object): |
51 | | - """ |
52 | | - Managers interact with a particular type of API (servers, flavors, images, |
53 | | - etc.) and provide CRUD operations for them. |
54 | | - """ |
55 | | - resource_class = None |
56 | | - |
57 | | - def __init__(self, api): |
58 | | - self.api = api |
59 | | - |
60 | | - def _list(self, url, response_key, obj_class=None, body=None): |
61 | | - resp = None |
62 | | - if body: |
63 | | - resp, body = self.api.client.post(url, body=body) |
64 | | - else: |
65 | | - resp, body = self.api.client.get(url) |
66 | | - |
67 | | - if obj_class is None: |
68 | | - obj_class = self.resource_class |
69 | | - return [obj_class(self, res) |
70 | | - for res in body[response_key] if res] |
71 | | - |
72 | | - def _get(self, url, response_key): |
73 | | - resp, body = self.api.client.get(url) |
74 | | - return self.resource_class(self, body[response_key]) |
75 | | - |
76 | | - def _create(self, url, body, response_key, return_raw=False): |
77 | | - resp, body = self.api.client.post(url, body=body) |
78 | | - if return_raw: |
79 | | - return body[response_key] |
80 | | - return self.resource_class(self, body[response_key]) |
81 | | - |
82 | | - def _delete(self, url): |
83 | | - resp, body = self.api.client.delete(url) |
84 | | - |
85 | | - def _update(self, url, body): |
86 | | - resp, body = self.api.client.put(url, body=body) |
87 | | - |
88 | | - |
89 | | -class ManagerWithFind(Manager): |
90 | | - """ |
91 | | - Like a `Manager`, but with additional `find()`/`findall()` methods. |
92 | | - """ |
93 | | - def find(self, **kwargs): |
94 | | - """ |
95 | | - Find a single item with attributes matching ``**kwargs``. |
96 | | -
|
97 | | - This isn't very efficient: it loads the entire list then filters on |
98 | | - the Python side. |
99 | | - """ |
100 | | - rl = self.findall(**kwargs) |
101 | | - try: |
102 | | - return rl[0] |
103 | | - except IndexError: |
104 | | - raise exceptions.NotFound(404, "No %s matching %s." % |
105 | | - (self.resource_class.__name__, kwargs)) |
106 | | - |
107 | | - def findall(self, **kwargs): |
108 | | - """ |
109 | | - Find all items with attributes matching ``**kwargs``. |
110 | | -
|
111 | | - This isn't very efficient: it loads the entire list then filters on |
112 | | - the Python side. |
113 | | - """ |
114 | | - found = [] |
115 | | - searches = kwargs.items() |
116 | | - |
117 | | - for obj in self.list(): |
118 | | - try: |
119 | | - if all(getattr(obj, attr) == value |
120 | | - for (attr, value) in searches): |
121 | | - found.append(obj) |
122 | | - except AttributeError: |
123 | | - continue |
124 | | - |
125 | | - return found |
126 | 21 |
|
127 | | - |
128 | | -class BootingManagerWithFind(ManagerWithFind): |
| 22 | +class BootingManagerWithFind(base.ManagerWithFind): |
129 | 23 | """Like a `ManagerWithFind`, but has the ability to boot servers.""" |
130 | 24 | def _boot(self, resource_url, response_key, name, image, flavor, |
131 | 25 | meta=None, files=None, zone_blob=None, |
@@ -155,8 +49,8 @@ def _boot(self, resource_url, response_key, name, image, flavor, |
155 | 49 | """ |
156 | 50 | body = {"server": { |
157 | 51 | "name": name, |
158 | | - "imageRef": getid(image), |
159 | | - "flavorRef": getid(flavor), |
| 52 | + "imageRef": base.getid(image), |
| 53 | + "flavorRef": base.getid(flavor), |
160 | 54 | }} |
161 | 55 | if meta: |
162 | 56 | body["server"]["metadata"] = meta |
@@ -194,43 +88,3 @@ def _boot(self, resource_url, response_key, name, image, flavor, |
194 | 88 |
|
195 | 89 | return self._create(resource_url, body, response_key, |
196 | 90 | return_raw=return_raw) |
197 | | - |
198 | | - |
199 | | -class Resource(object): |
200 | | - """ |
201 | | - A resource represents a particular instance of an object (server, flavor, |
202 | | - etc). This is pretty much just a bag for attributes. |
203 | | - """ |
204 | | - def __init__(self, manager, info): |
205 | | - self.manager = manager |
206 | | - self._info = info |
207 | | - self._add_details(info) |
208 | | - |
209 | | - def _add_details(self, info): |
210 | | - for (k, v) in info.iteritems(): |
211 | | - setattr(self, k, v) |
212 | | - |
213 | | - def __getattr__(self, k): |
214 | | - self.get() |
215 | | - if k not in self.__dict__: |
216 | | - raise AttributeError(k) |
217 | | - else: |
218 | | - return self.__dict__[k] |
219 | | - |
220 | | - def __repr__(self): |
221 | | - reprkeys = sorted(k for k in self.__dict__.keys() if k[0] != '_' and |
222 | | - k != 'manager') |
223 | | - info = ", ".join("%s=%s" % (k, getattr(self, k)) for k in reprkeys) |
224 | | - return "<%s %s>" % (self.__class__.__name__, info) |
225 | | - |
226 | | - def get(self): |
227 | | - new = self.manager.get(self.id) |
228 | | - if new: |
229 | | - self._add_details(new._info) |
230 | | - |
231 | | - def __eq__(self, other): |
232 | | - if not isinstance(other, self.__class__): |
233 | | - return False |
234 | | - if hasattr(self, 'id') and hasattr(other, 'id'): |
235 | | - return self.id == other.id |
236 | | - return self._info == other._info |
0 commit comments