1# Copyright (c) 2006-2009 Mitch Garnaat http://garnaat.org/
2#
3# Permission is hereby granted, free of charge, to any person obtaining a
4# copy of this software and associated documentation files (the
5# "Software"), to deal in the Software without restriction, including
6# without limitation the rights to use, copy, modify, merge, publish, dis-
7# tribute, sublicense, and/or sell copies of the Software, and to permit
8# persons to whom the Software is furnished to do so, subject to the fol-
9# lowing conditions:
10#
11# The above copyright notice and this permission notice shall be included
12# in all copies or substantial portions of the Software.
13#
14# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-
16# ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
17# SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
18# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
20# IN THE SOFTWARE.
21from boto.resultset import ResultSet
22from boto.ec2.ec2object import EC2Object
23from boto.utils import parse_ts
24
25
26class ReservedInstancesOffering(EC2Object):
27
28    def __init__(self, connection=None, id=None, instance_type=None,
29                 availability_zone=None, duration=None, fixed_price=None,
30                 usage_price=None, description=None, instance_tenancy=None,
31                 currency_code=None, offering_type=None,
32                 recurring_charges=None, pricing_details=None):
33        super(ReservedInstancesOffering, self).__init__(connection)
34        self.id = id
35        self.instance_type = instance_type
36        self.availability_zone = availability_zone
37        self.duration = duration
38        self.fixed_price = fixed_price
39        self.usage_price = usage_price
40        self.description = description
41        self.instance_tenancy = instance_tenancy
42        self.currency_code = currency_code
43        self.offering_type = offering_type
44        self.recurring_charges = recurring_charges
45        self.pricing_details = pricing_details
46
47    def __repr__(self):
48        return 'ReservedInstanceOffering:%s' % self.id
49
50    def startElement(self, name, attrs, connection):
51        if name == 'recurringCharges':
52            self.recurring_charges = ResultSet([('item', RecurringCharge)])
53            return self.recurring_charges
54        elif name == 'pricingDetailsSet':
55            self.pricing_details = ResultSet([('item', PricingDetail)])
56            return self.pricing_details
57        return None
58
59    def endElement(self, name, value, connection):
60        if name == 'reservedInstancesOfferingId':
61            self.id = value
62        elif name == 'instanceType':
63            self.instance_type = value
64        elif name == 'availabilityZone':
65            self.availability_zone = value
66        elif name == 'duration':
67            self.duration = int(value)
68        elif name == 'fixedPrice':
69            self.fixed_price = value
70        elif name == 'usagePrice':
71            self.usage_price = value
72        elif name == 'productDescription':
73            self.description = value
74        elif name == 'instanceTenancy':
75            self.instance_tenancy = value
76        elif name == 'currencyCode':
77            self.currency_code = value
78        elif name == 'offeringType':
79            self.offering_type = value
80        elif name == 'marketplace':
81            self.marketplace = True if value == 'true' else False
82
83    def describe(self):
84        print('ID=%s' % self.id)
85        print('\tInstance Type=%s' % self.instance_type)
86        print('\tZone=%s' % self.availability_zone)
87        print('\tDuration=%s' % self.duration)
88        print('\tFixed Price=%s' % self.fixed_price)
89        print('\tUsage Price=%s' % self.usage_price)
90        print('\tDescription=%s' % self.description)
91
92    def purchase(self, instance_count=1, dry_run=False):
93        return self.connection.purchase_reserved_instance_offering(
94            self.id,
95            instance_count,
96            dry_run=dry_run
97        )
98
99
100class RecurringCharge(object):
101    def __init__(self, connection=None, frequency=None, amount=None):
102        self.frequency = frequency
103        self.amount = amount
104
105    def startElement(self, name, attrs, connection):
106        return None
107
108    def endElement(self, name, value, connection):
109        setattr(self, name, value)
110
111
112class PricingDetail(object):
113    def __init__(self, connection=None, price=None, count=None):
114        self.price = price
115        self.count = count
116
117    def startElement(self, name, attrs, connection):
118        return None
119
120    def endElement(self, name, value, connection):
121        setattr(self, name, value)
122
123
124class ReservedInstance(ReservedInstancesOffering):
125
126    def __init__(self, connection=None, id=None, instance_type=None,
127                 availability_zone=None, duration=None, fixed_price=None,
128                 usage_price=None, description=None,
129                 instance_count=None, state=None):
130        super(ReservedInstance, self).__init__(connection, id, instance_type,
131                                               availability_zone, duration,
132                                               fixed_price, usage_price,
133                                               description)
134        self.instance_count = instance_count
135        self.state = state
136        self.start = None
137        self.end = None
138
139    def __repr__(self):
140        return 'ReservedInstance:%s' % self.id
141
142    def endElement(self, name, value, connection):
143        if name == 'reservedInstancesId':
144            self.id = value
145        if name == 'instanceCount':
146            self.instance_count = int(value)
147        elif name == 'state':
148            self.state = value
149        elif name == 'start':
150            self.start = value
151        elif name == 'end':
152            self.end = value
153        else:
154            super(ReservedInstance, self).endElement(name, value, connection)
155
156
157class ReservedInstanceListing(EC2Object):
158    def __init__(self, connection=None, listing_id=None, id=None,
159                 create_date=None, update_date=None,
160                 status=None, status_message=None, client_token=None):
161        self.connection = connection
162        self.listing_id = listing_id
163        self.id = id
164        self.create_date = create_date
165        self.update_date = update_date
166        self.status = status
167        self.status_message = status_message
168        self.client_token = client_token
169
170    def startElement(self, name, attrs, connection):
171        if name == 'instanceCounts':
172            self.instance_counts = ResultSet([('item', InstanceCount)])
173            return self.instance_counts
174        elif name == 'priceSchedules':
175            self.price_schedules = ResultSet([('item', PriceSchedule)])
176            return self.price_schedules
177        return None
178
179    def endElement(self, name, value, connection):
180        if name == 'reservedInstancesListingId':
181            self.listing_id = value
182        elif name == 'reservedInstancesId':
183            self.id = value
184        elif name == 'createDate':
185            self.create_date = value
186        elif name == 'updateDate':
187            self.update_date = value
188        elif name == 'status':
189            self.status = value
190        elif name == 'statusMessage':
191            self.status_message = value
192        else:
193            setattr(self, name, value)
194
195
196class InstanceCount(object):
197    def __init__(self, connection=None, state=None, instance_count=None):
198        self.state = state
199        self.instance_count = instance_count
200
201    def startElement(self, name, attrs, connection):
202        return None
203
204    def endElement(self, name, value, connection):
205        if name == 'state':
206            self.state = value
207        elif name == 'instanceCount':
208            self.instance_count = int(value)
209        else:
210            setattr(self, name, value)
211
212
213class PriceSchedule(object):
214    def __init__(self, connection=None, term=None, price=None,
215                 currency_code=None, active=None):
216        self.connection = connection
217        self.term = term
218        self.price = price
219        self.currency_code = currency_code
220        self.active = active
221
222    def startElement(self, name, attrs, connection):
223        return None
224
225    def endElement(self, name, value, connection):
226        if name == 'term':
227            self.term = int(value)
228        elif name == 'price':
229            self.price = value
230        elif name == 'currencyCode':
231            self.currency_code = value
232        elif name == 'active':
233            self.active = True if value == 'true' else False
234        else:
235            setattr(self, name, value)
236
237
238class ReservedInstancesConfiguration(object):
239    def __init__(self, connection=None, availability_zone=None, platform=None,
240                 instance_count=None, instance_type=None):
241        self.connection = connection
242        self.availability_zone = availability_zone
243        self.platform = platform
244        self.instance_count = instance_count
245        self.instance_type = instance_type
246
247    def startElement(self, name, attrs, connection):
248        return None
249
250    def endElement(self, name, value, connection):
251        if name == 'availabilityZone':
252            self.availability_zone = value
253        elif name == 'platform':
254            self.platform = value
255        elif name == 'instanceCount':
256            self.instance_count = int(value)
257        elif name == 'instanceType':
258            self.instance_type = value
259        else:
260            setattr(self, name, value)
261
262
263class ModifyReservedInstancesResult(object):
264    def __init__(self, connection=None, modification_id=None):
265        self.connection = connection
266        self.modification_id = modification_id
267
268    def startElement(self, name, attrs, connection):
269        return None
270
271    def endElement(self, name, value, connection):
272        if name == 'reservedInstancesModificationId':
273            self.modification_id = value
274        else:
275            setattr(self, name, value)
276
277
278class ModificationResult(object):
279    def __init__(self, connection=None, modification_id=None,
280                 availability_zone=None, platform=None, instance_count=None,
281                 instance_type=None):
282        self.connection = connection
283        self.modification_id = modification_id
284        self.availability_zone = availability_zone
285        self.platform = platform
286        self.instance_count = instance_count
287        self.instance_type = instance_type
288
289    def startElement(self, name, attrs, connection):
290        return None
291
292    def endElement(self, name, value, connection):
293        if name == 'reservedInstancesModificationId':
294            self.modification_id = value
295        elif name == 'availabilityZone':
296            self.availability_zone = value
297        elif name == 'platform':
298            self.platform = value
299        elif name == 'instanceCount':
300            self.instance_count = int(value)
301        elif name == 'instanceType':
302            self.instance_type = value
303        else:
304            setattr(self, name, value)
305
306
307class ReservedInstancesModification(object):
308    def __init__(self, connection=None, modification_id=None,
309                 reserved_instances=None, modification_results=None,
310                 create_date=None, update_date=None, effective_date=None,
311                 status=None, status_message=None, client_token=None):
312        self.connection = connection
313        self.modification_id = modification_id
314        self.reserved_instances = reserved_instances
315        self.modification_results = modification_results
316        self.create_date = create_date
317        self.update_date = update_date
318        self.effective_date = effective_date
319        self.status = status
320        self.status_message = status_message
321        self.client_token = client_token
322
323    def startElement(self, name, attrs, connection):
324        if name == 'reservedInstancesSet':
325            self.reserved_instances = ResultSet([
326                ('item', ReservedInstance)
327            ])
328            return self.reserved_instances
329        elif name == 'modificationResultSet':
330            self.modification_results = ResultSet([
331                ('item', ModificationResult)
332            ])
333            return self.modification_results
334        return None
335
336    def endElement(self, name, value, connection):
337        if name == 'reservedInstancesModificationId':
338            self.modification_id = value
339        elif name == 'createDate':
340            self.create_date = parse_ts(value)
341        elif name == 'updateDate':
342            self.update_date = parse_ts(value)
343        elif name == 'effectiveDate':
344            self.effective_date = parse_ts(value)
345        elif name == 'status':
346            self.status = value
347        elif name == 'statusMessage':
348            self.status_message = value
349        elif name == 'clientToken':
350            self.client_token = value
351        else:
352            setattr(self, name, value)
353