1# Copyright (c) 2009-2010 Reza Lotun http://reza.lotun.name/
2# Copyright (c) 2011 Jann Kleen
3#
4# Permission is hereby granted, free of charge, to any person obtaining a
5# copy of this software and associated documentation files (the
6# "Software"), to deal in the Software without restriction, including
7# without limitation the rights to use, copy, modify, merge, publish, dis-
8# tribute, sublicense, and/or sell copies of the Software, and to permit
9# persons to whom the Software is furnished to do so, subject to the fol-
10# lowing conditions:
11#
12# The above copyright notice and this permission notice shall be included
13# in all copies or substantial portions of the Software.
14#
15# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
16# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-
17# ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
18# SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
19# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21# IN THE SOFTWARE.
22
23from boto.resultset import ResultSet
24from boto.ec2.elb.listelement import ListElement
25
26
27class Alarm(object):
28    def __init__(self, connection=None):
29        self.connection = connection
30        self.name = None
31        self.alarm_arn = None
32
33    def __repr__(self):
34        return 'Alarm:%s' % self.name
35
36    def startElement(self, name, attrs, connection):
37        return None
38
39    def endElement(self, name, value, connection):
40        if name == 'AlarmName':
41            self.name = value
42        elif name == 'AlarmARN':
43            self.alarm_arn = value
44        else:
45            setattr(self, name, value)
46
47
48class AdjustmentType(object):
49    def __init__(self, connection=None):
50        self.connection = connection
51        self.adjustment_type = None
52
53    def __repr__(self):
54        return 'AdjustmentType:%s' % self.adjustment_type
55
56    def startElement(self, name, attrs, connection):
57        return
58
59    def endElement(self, name, value, connection):
60        if name == 'AdjustmentType':
61            self.adjustment_type = value
62        return
63
64
65class MetricCollectionTypes(object):
66    class BaseType(object):
67        arg = ''
68
69        def __init__(self, connection):
70            self.connection = connection
71            self.val = None
72
73        def __repr__(self):
74            return '%s:%s' % (self.arg, self.val)
75
76        def startElement(self, name, attrs, connection):
77            return
78
79        def endElement(self, name, value, connection):
80            if name == self.arg:
81                self.val = value
82
83    class Metric(BaseType):
84        arg = 'Metric'
85
86    class Granularity(BaseType):
87        arg = 'Granularity'
88
89    def __init__(self, connection=None):
90        self.connection = connection
91        self.metrics = []
92        self.granularities = []
93
94    def __repr__(self):
95        return 'MetricCollectionTypes:<%s, %s>' % (self.metrics, self.granularities)
96
97    def startElement(self, name, attrs, connection):
98        if name == 'Granularities':
99            self.granularities = ResultSet([('member', self.Granularity)])
100            return self.granularities
101        elif name == 'Metrics':
102            self.metrics = ResultSet([('member', self.Metric)])
103            return self.metrics
104
105    def endElement(self, name, value, connection):
106        return
107
108
109class ScalingPolicy(object):
110    def __init__(self, connection=None, **kwargs):
111        """
112        Scaling Policy
113
114        :type name: str
115        :param name: Name of scaling policy.
116
117        :type adjustment_type: str
118        :param adjustment_type: Specifies the type of adjustment. Valid values are `ChangeInCapacity`, `ExactCapacity` and `PercentChangeInCapacity`.
119
120        :type as_name: str or int
121        :param as_name: Name or ARN of the Auto Scaling Group.
122
123        :type scaling_adjustment: int
124        :param scaling_adjustment: Value of adjustment (type specified in `adjustment_type`).
125
126        :type min_adjustment_step: int
127        :param min_adjustment_step: Value of min adjustment step required to
128            apply the scaling policy (only make sense when use `PercentChangeInCapacity` as adjustment_type.).
129
130        :type cooldown: int
131        :param cooldown: Time (in seconds) before Alarm related Scaling Activities can start after the previous Scaling Activity ends.
132
133        """
134        self.name = kwargs.get('name', None)
135        self.adjustment_type = kwargs.get('adjustment_type', None)
136        self.as_name = kwargs.get('as_name', None)
137        self.scaling_adjustment = kwargs.get('scaling_adjustment', None)
138        self.cooldown = kwargs.get('cooldown', None)
139        self.connection = connection
140        self.min_adjustment_step = kwargs.get('min_adjustment_step', None)
141
142    def __repr__(self):
143        return 'ScalingPolicy(%s group:%s adjustment:%s)' % (self.name,
144                                                             self.as_name,
145                                                             self.adjustment_type)
146
147    def startElement(self, name, attrs, connection):
148        if name == 'Alarms':
149            self.alarms = ResultSet([('member', Alarm)])
150            return self.alarms
151
152    def endElement(self, name, value, connection):
153        if name == 'PolicyName':
154            self.name = value
155        elif name == 'AutoScalingGroupName':
156            self.as_name = value
157        elif name == 'PolicyARN':
158            self.policy_arn = value
159        elif name == 'ScalingAdjustment':
160            self.scaling_adjustment = int(value)
161        elif name == 'Cooldown':
162            self.cooldown = int(value)
163        elif name == 'AdjustmentType':
164            self.adjustment_type = value
165        elif name == 'MinAdjustmentStep':
166            self.min_adjustment_step = int(value)
167
168    def delete(self):
169        return self.connection.delete_policy(self.name, self.as_name)
170
171
172class TerminationPolicies(list):
173    def __init__(self, connection=None, **kwargs):
174        pass
175
176    def startElement(self, name, attrs, connection):
177        pass
178
179    def endElement(self, name, value, connection):
180        if name == 'member':
181            self.append(value)
182