1# Copyright (c) 2010 Spotify AB
2# Copyright (c) 2010 Jeremy Thurgood <firxen+boto@gmail.com>
3# Copyright (c) 2010-2011 Yelp
4#
5# Permission is hereby granted, free of charge, to any person obtaining a
6# copy of this software and associated documentation files (the
7# "Software"), to deal in the Software without restriction, including
8# without limitation the rights to use, copy, modify, merge, publish, dis-
9# tribute, sublicense, and/or sell copies of the Software, and to permit
10# persons to whom the Software is furnished to do so, subject to the fol-
11# lowing conditions:
12#
13# The above copyright notice and this permission notice shall be included
14# in all copies or substantial portions of the Software.
15#
16# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-
18# ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
19# SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
20# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
22# IN THE SOFTWARE.
23
24"""
25This module contains EMR response objects
26"""
27
28from boto.resultset import ResultSet
29
30
31class EmrObject(object):
32    Fields = set()
33
34    def __init__(self, connection=None):
35        self.connection = connection
36
37    def startElement(self, name, attrs, connection):
38        pass
39
40    def endElement(self, name, value, connection):
41        if name in self.Fields:
42            setattr(self, name.lower(), value)
43
44
45class RunJobFlowResponse(EmrObject):
46    Fields = set(['JobFlowId'])
47
48class AddInstanceGroupsResponse(EmrObject):
49    Fields = set(['InstanceGroupIds', 'JobFlowId'])
50
51class ModifyInstanceGroupsResponse(EmrObject):
52    Fields = set(['RequestId'])
53
54
55class Arg(EmrObject):
56    def __init__(self, connection=None):
57        self.value = None
58
59    def endElement(self, name, value, connection):
60        self.value = value
61
62
63class StepId(Arg):
64    pass
65
66
67class SupportedProduct(Arg):
68    pass
69
70
71class JobFlowStepList(EmrObject):
72    def __ini__(self, connection=None):
73        self.connection = connection
74        self.stepids = None
75
76    def startElement(self, name, attrs, connection):
77        if name == 'StepIds':
78            self.stepids = ResultSet([('member', StepId)])
79            return self.stepids
80        else:
81            return None
82
83
84class BootstrapAction(EmrObject):
85    Fields = set([
86        'Args',
87        'Name',
88        'Path',
89        'ScriptPath',
90    ])
91
92    def startElement(self, name, attrs, connection):
93        if name == 'Args':
94            self.args = ResultSet([('member', Arg)])
95            return self.args
96
97
98class KeyValue(EmrObject):
99    Fields = set([
100        'Key',
101        'Value',
102    ])
103
104
105class Step(EmrObject):
106    Fields = set([
107        'ActionOnFailure',
108        'CreationDateTime',
109        'EndDateTime',
110        'Jar',
111        'LastStateChangeReason',
112        'MainClass',
113        'Name',
114        'StartDateTime',
115        'State',
116    ])
117
118    def __init__(self, connection=None):
119        self.connection = connection
120        self.args = None
121
122    def startElement(self, name, attrs, connection):
123        if name == 'Args':
124            self.args = ResultSet([('member', Arg)])
125            return self.args
126        if name == 'Properties':
127            self.properties = ResultSet([('member', KeyValue)])
128            return self.properties
129
130
131class InstanceGroup(EmrObject):
132    Fields = set([
133        'BidPrice',
134        'CreationDateTime',
135        'EndDateTime',
136        'InstanceGroupId',
137        'InstanceRequestCount',
138        'InstanceRole',
139        'InstanceRunningCount',
140        'InstanceType',
141        'LastStateChangeReason',
142        'LaunchGroup',
143        'Market',
144        'Name',
145        'ReadyDateTime',
146        'StartDateTime',
147        'State',
148    ])
149
150
151class JobFlow(EmrObject):
152    Fields = set([
153        'AmiVersion',
154        'AvailabilityZone',
155        'CreationDateTime',
156        'Ec2KeyName',
157        'EndDateTime',
158        'HadoopVersion',
159        'Id',
160        'InstanceCount',
161        'JobFlowId',
162        'KeepJobFlowAliveWhenNoSteps',
163        'LastStateChangeReason',
164        'LogUri',
165        'MasterInstanceId',
166        'MasterInstanceType',
167        'MasterPublicDnsName',
168        'Name',
169        'NormalizedInstanceHours',
170        'ReadyDateTime',
171        'RequestId',
172        'SlaveInstanceType',
173        'StartDateTime',
174        'State',
175        'TerminationProtected',
176        'Type',
177        'Value',
178        'VisibleToAllUsers',
179    ])
180
181    def __init__(self, connection=None):
182        self.connection = connection
183        self.steps = None
184        self.instancegroups = None
185        self.bootstrapactions = None
186
187    def startElement(self, name, attrs, connection):
188        if name == 'Steps':
189            self.steps = ResultSet([('member', Step)])
190            return self.steps
191        elif name == 'InstanceGroups':
192            self.instancegroups = ResultSet([('member', InstanceGroup)])
193            return self.instancegroups
194        elif name == 'BootstrapActions':
195            self.bootstrapactions = ResultSet([('member', BootstrapAction)])
196            return self.bootstrapactions
197        elif name == 'SupportedProducts':
198            self.supported_products = ResultSet([('member', SupportedProduct)])
199            return self.supported_products
200        else:
201            return None
202
203
204class ClusterTimeline(EmrObject):
205    Fields = set([
206        'CreationDateTime',
207        'ReadyDateTime',
208        'EndDateTime'
209    ])
210
211class ClusterStateChangeReason(EmrObject):
212    Fields = set([
213        'Code',
214        'Message'
215    ])
216
217class ClusterStatus(EmrObject):
218    Fields = set([
219        'State',
220        'StateChangeReason',
221        'Timeline'
222    ])
223
224    def __init__(self, connection=None):
225        self.connection = connection
226        self.timeline = None
227
228    def startElement(self, name, attrs, connection):
229        if name == 'Timeline':
230            self.timeline = ClusterTimeline()
231            return self.timeline
232        elif name == 'StateChangeReason':
233            self.statechangereason = ClusterStateChangeReason()
234            return self.statechangereason
235        else:
236            return None
237
238
239class Ec2InstanceAttributes(EmrObject):
240    Fields = set([
241        'Ec2KeyName',
242        'Ec2SubnetId',
243        'Ec2AvailabilityZone',
244        'IamInstanceProfile'
245    ])
246
247
248class Application(EmrObject):
249    Fields = set([
250        'Name',
251        'Version',
252        'Args',
253        'AdditionalInfo'
254    ])
255
256
257class Cluster(EmrObject):
258    Fields = set([
259        'Id',
260        'Name',
261        'LogUri',
262        'RequestedAmiVersion',
263        'RunningAmiVersion',
264        'AutoTerminate',
265        'TerminationProtected',
266        'VisibleToAllUsers',
267        'MasterPublicDnsName',
268        'NormalizedInstanceHours',
269        'ServiceRole'
270    ])
271
272    def __init__(self, connection=None):
273        self.connection = connection
274        self.status = None
275        self.ec2instanceattributes = None
276        self.applications = None
277        self.tags = None
278
279    def startElement(self, name, attrs, connection):
280        if name == 'Status':
281            self.status = ClusterStatus()
282            return self.status
283        elif name == 'Ec2InstanceAttributes':
284            self.ec2instanceattributes = Ec2InstanceAttributes()
285            return self.ec2instanceattributes
286        elif name == 'Applications':
287            self.applications = ResultSet([('member', Application)])
288            return self.applications
289        elif name == 'Tags':
290            self.tags = ResultSet([('member', KeyValue)])
291            return self.tags
292        else:
293            return None
294
295
296class ClusterSummary(EmrObject):
297    Fields = set([
298        'Id',
299        'Name',
300        'NormalizedInstanceHours'
301    ])
302
303    def __init__(self, connection):
304        self.connection = connection
305        self.status = None
306
307    def startElement(self, name, attrs, connection):
308        if name == 'Status':
309            self.status = ClusterStatus()
310            return self.status
311        else:
312            return None
313
314
315class ClusterSummaryList(EmrObject):
316    Fields = set([
317        'Marker'
318    ])
319
320    def __init__(self, connection):
321        self.connection = connection
322        self.clusters = None
323
324    def startElement(self, name, attrs, connection):
325        if name == 'Clusters':
326            self.clusters = ResultSet([('member', ClusterSummary)])
327            return self.clusters
328        else:
329            return None
330
331
332class StepConfig(EmrObject):
333    Fields = set([
334        'Jar',
335        'MainClass'
336    ])
337
338    def __init__(self, connection=None):
339        self.connection = connection
340        self.properties = None
341        self.args = None
342
343    def startElement(self, name, attrs, connection):
344        if name == 'Properties':
345            self.properties = ResultSet([('member', KeyValue)])
346            return self.properties
347        elif name == 'Args':
348            self.args = ResultSet([('member', Arg)])
349            return self.args
350        else:
351            return None
352
353
354class HadoopStep(EmrObject):
355    Fields = set([
356        'Id',
357        'Name',
358        'ActionOnFailure'
359    ])
360
361    def __init__(self, connection=None):
362        self.connection = connection
363        self.config = None
364        self.status = None
365
366    def startElement(self, name, attrs, connection):
367        if name == 'Config':
368            self.config = StepConfig()
369            return self.config
370        elif name == 'Status':
371            self.status = ClusterStatus()
372            return self.status
373        else:
374            return None
375
376
377
378class InstanceGroupInfo(EmrObject):
379    Fields = set([
380        'Id',
381        'Name',
382        'Market',
383        'InstanceGroupType',
384        'BidPrice',
385        'InstanceType',
386        'RequestedInstanceCount',
387        'RunningInstanceCount'
388    ])
389
390    def __init__(self, connection=None):
391        self.connection = connection
392        self.status = None
393
394    def startElement(self, name, attrs, connection):
395        if name == 'Status':
396            self.status = ClusterStatus()
397            return self.status
398        else:
399            return None
400
401
402class InstanceGroupList(EmrObject):
403    Fields = set([
404        'Marker'
405    ])
406
407    def __init__(self, connection=None):
408        self.connection = connection
409        self.instancegroups = None
410
411    def startElement(self, name, attrs, connection):
412        if name == 'InstanceGroups':
413            self.instancegroups = ResultSet([('member', InstanceGroupInfo)])
414            return self.instancegroups
415        else:
416            return None
417
418
419class InstanceInfo(EmrObject):
420    Fields = set([
421        'Id',
422        'Ec2InstanceId',
423        'PublicDnsName',
424        'PublicIpAddress',
425        'PrivateDnsName',
426        'PrivateIpAddress'
427    ])
428
429    def __init__(self, connection=None):
430        self.connection = connection
431        self.status = None
432
433    def startElement(self, name, attrs, connection):
434        if name == 'Status':
435            self.status = ClusterStatus()
436            return self.status
437        else:
438            return None
439
440
441class InstanceList(EmrObject):
442    Fields = set([
443        'Marker'
444    ])
445
446    def __init__(self, connection=None):
447        self.connection = connection
448        self.instances = None
449
450    def startElement(self, name, attrs, connection):
451        if name == 'Instances':
452            self.instances = ResultSet([('member', InstanceInfo)])
453            return self.instances
454        else:
455            return None
456
457
458class StepSummary(EmrObject):
459    Fields = set([
460        'Id',
461        'Name'
462    ])
463
464    def __init__(self, connection=None):
465        self.connection = connection
466        self.status = None
467        self.config = None
468
469    def startElement(self, name, attrs, connection):
470        if name == 'Status':
471            self.status = ClusterStatus()
472            return self.status
473        elif name == 'Config':
474            self.config = StepConfig()
475            return self.config
476        else:
477            return None
478
479
480class StepSummaryList(EmrObject):
481    Fields = set([
482        'Marker'
483    ])
484
485    def __init__(self, connection=None):
486        self.connection = connection
487        self.steps = None
488
489    def startElement(self, name, attrs, connection):
490        if name == 'Steps':
491            self.steps = ResultSet([('member', StepSummary)])
492            return self.steps
493        else:
494            return None
495
496
497class BootstrapActionList(EmrObject):
498    Fields = set([
499        'Marker'
500    ])
501
502    def __init__(self, connection=None):
503        self.connection = connection
504        self.actions = None
505
506    def startElement(self, name, attrs, connection):
507        if name == 'BootstrapActions':
508            self.actions = ResultSet([('member', BootstrapAction)])
509            return self.actions
510        else:
511            return None
512