• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.
21
22from boto.rds.dbsecuritygroup import DBSecurityGroup
23from boto.rds.parametergroup import ParameterGroup
24from boto.rds.statusinfo import StatusInfo
25from boto.rds.dbsubnetgroup import DBSubnetGroup
26from boto.rds.vpcsecuritygroupmembership import VPCSecurityGroupMembership
27from boto.resultset import ResultSet
28
29
30class DBInstance(object):
31    """
32    Represents a RDS DBInstance
33
34    Properties reference available from the AWS documentation at
35    http://goo.gl/sC2Kn
36
37    :ivar connection: connection
38    :ivar id: The name and identifier of the DBInstance
39    :ivar create_time: The date and time of creation
40    :ivar engine: The database engine being used
41    :ivar status: The status of the database in a string. e.g. "available"
42    :ivar allocated_storage: The size of the disk in gigabytes (int).
43    :ivar auto_minor_version_upgrade: Indicates that minor version patches
44        are applied automatically.
45    :ivar endpoint: A tuple that describes the hostname and port of
46        the instance. This is only available when the database is
47        in status "available".
48    :ivar instance_class: Contains the name of the compute and memory
49        capacity class of the DB Instance.
50    :ivar master_username: The username that is set as master username
51        at creation time.
52    :ivar parameter_groups: Provides the list of DB Parameter Groups
53        applied to this DB Instance.
54    :ivar security_groups: Provides List of DB Security Group elements
55        containing only DBSecurityGroup.Name and DBSecurityGroup.Status
56        subelements.
57    :ivar availability_zone: Specifies the name of the Availability Zone
58        the DB Instance is located in.
59    :ivar backup_retention_period: Specifies the number of days for
60        which automatic DB Snapshots are retained.
61    :ivar preferred_backup_window: Specifies the daily time range during
62        which automated backups are created if automated backups are
63        enabled, as determined by the backup_retention_period.
64    :ivar preferred_maintenance_window: Specifies the weekly time
65        range (in UTC) during which system maintenance can occur. (string)
66    :ivar latest_restorable_time: Specifies the latest time to which
67        a database can be restored with point-in-time restore. (string)
68    :ivar multi_az: Boolean that specifies if the DB Instance is a
69        Multi-AZ deployment.
70    :ivar iops: The current number of provisioned IOPS for the DB Instance.
71        Can be None if this is a standard instance.
72    :ivar vpc_security_groups: List of VPC Security Group Membership elements
73        containing only VpcSecurityGroupMembership.VpcSecurityGroupId and
74        VpcSecurityGroupMembership.Status subelements.
75    :ivar pending_modified_values: Specifies that changes to the
76        DB Instance are pending. This element is only included when changes
77        are pending. Specific changes are identified by subelements.
78    :ivar read_replica_dbinstance_identifiers: List of read replicas
79        associated with this DB instance.
80    :ivar status_infos: The status of a Read Replica. If the instance is not a
81        for a read replica, this will be blank.
82    :ivar character_set_name: If present, specifies the name of the character
83        set that this instance is associated with.
84    :ivar subnet_group: Specifies information on the subnet group associated
85        with the DB instance, including the name, description, and subnets
86        in the subnet group.
87    :ivar engine_version: Indicates the database engine version.
88    :ivar license_model: License model information for this DB instance.
89    """
90
91    def __init__(self, connection=None, id=None):
92        self.connection = connection
93        self.id = id
94        self.create_time = None
95        self.engine = None
96        self.status = None
97        self.allocated_storage = None
98        self.auto_minor_version_upgrade = None
99        self.endpoint = None
100        self.instance_class = None
101        self.master_username = None
102        self.parameter_groups = []
103        self.security_groups = []
104        self.read_replica_dbinstance_identifiers = []
105        self.availability_zone = None
106        self.backup_retention_period = None
107        self.preferred_backup_window = None
108        self.preferred_maintenance_window = None
109        self.latest_restorable_time = None
110        self.multi_az = False
111        self.iops = None
112        self.vpc_security_groups = None
113        self.pending_modified_values = None
114        self._in_endpoint = False
115        self._port = None
116        self._address = None
117        self.status_infos = None
118        self.character_set_name = None
119        self.subnet_group = None
120        self.engine_version = None
121        self.license_model = None
122
123    def __repr__(self):
124        return 'DBInstance:%s' % self.id
125
126    def startElement(self, name, attrs, connection):
127        if name == 'Endpoint':
128            self._in_endpoint = True
129        elif name == 'DBParameterGroups':
130            self.parameter_groups = ResultSet([('DBParameterGroup',
131                                                ParameterGroup)])
132            return self.parameter_groups
133        elif name == 'DBSecurityGroups':
134            self.security_groups = ResultSet([('DBSecurityGroup',
135                                               DBSecurityGroup)])
136            return self.security_groups
137        elif name == 'VpcSecurityGroups':
138            self.vpc_security_groups = ResultSet([('VpcSecurityGroupMembership',
139                                               VPCSecurityGroupMembership)])
140            return self.vpc_security_groups
141        elif name == 'PendingModifiedValues':
142            self.pending_modified_values = PendingModifiedValues()
143            return self.pending_modified_values
144        elif name == 'ReadReplicaDBInstanceIdentifiers':
145            self.read_replica_dbinstance_identifiers = \
146                    ReadReplicaDBInstanceIdentifiers()
147            return self.read_replica_dbinstance_identifiers
148        elif name == 'StatusInfos':
149            self.status_infos = ResultSet([
150                ('DBInstanceStatusInfo', StatusInfo)
151            ])
152            return self.status_infos
153        elif name == 'DBSubnetGroup':
154            self.subnet_group = DBSubnetGroup()
155            return self.subnet_group
156        return None
157
158    def endElement(self, name, value, connection):
159        if name == 'DBInstanceIdentifier':
160            self.id = value
161        elif name == 'DBInstanceStatus':
162            self.status = value
163        elif name == 'InstanceCreateTime':
164            self.create_time = value
165        elif name == 'Engine':
166            self.engine = value
167        elif name == 'DBInstanceStatus':
168            self.status = value
169        elif name == 'AllocatedStorage':
170            self.allocated_storage = int(value)
171        elif name == 'AutoMinorVersionUpgrade':
172            self.auto_minor_version_upgrade = value.lower() == 'true'
173        elif name == 'DBInstanceClass':
174            self.instance_class = value
175        elif name == 'MasterUsername':
176            self.master_username = value
177        elif name == 'Port':
178            if self._in_endpoint:
179                self._port = int(value)
180        elif name == 'Address':
181            if self._in_endpoint:
182                self._address = value
183        elif name == 'Endpoint':
184            self.endpoint = (self._address, self._port)
185            self._in_endpoint = False
186        elif name == 'AvailabilityZone':
187            self.availability_zone = value
188        elif name == 'BackupRetentionPeriod':
189            self.backup_retention_period = int(value)
190        elif name == 'LatestRestorableTime':
191            self.latest_restorable_time = value
192        elif name == 'PreferredMaintenanceWindow':
193            self.preferred_maintenance_window = value
194        elif name == 'PreferredBackupWindow':
195            self.preferred_backup_window = value
196        elif name == 'MultiAZ':
197            if value.lower() == 'true':
198                self.multi_az = True
199        elif name == 'Iops':
200            self.iops = int(value)
201        elif name == 'CharacterSetName':
202            self.character_set_name = value
203        elif name == 'EngineVersion':
204            self.engine_version = value
205        elif name == 'LicenseModel':
206            self.license_model = value
207        else:
208            setattr(self, name, value)
209
210    @property
211    def security_group(self):
212        """
213        Provide backward compatibility for previous security_group
214        attribute.
215        """
216        if len(self.security_groups) > 0:
217            return self.security_groups[-1]
218        else:
219            return None
220
221    @property
222    def parameter_group(self):
223        """
224        Provide backward compatibility for previous parameter_group
225        attribute.
226        """
227        if len(self.parameter_groups) > 0:
228            return self.parameter_groups[-1]
229        else:
230            return None
231
232    def snapshot(self, snapshot_id):
233        """
234        Create a new DB snapshot of this DBInstance.
235
236        :type identifier: string
237        :param identifier: The identifier for the DBSnapshot
238
239        :rtype: :class:`boto.rds.dbsnapshot.DBSnapshot`
240        :return: The newly created DBSnapshot
241        """
242        return self.connection.create_dbsnapshot(snapshot_id, self.id)
243
244    def reboot(self):
245        """
246        Reboot this DBInstance
247
248        :rtype: :class:`boto.rds.dbsnapshot.DBSnapshot`
249        :return: The newly created DBSnapshot
250        """
251        return self.connection.reboot_dbinstance(self.id)
252
253    def update(self, validate=False):
254        """
255        Update the DB instance's status information by making a call to fetch
256        the current instance attributes from the service.
257
258        :type validate: bool
259        :param validate: By default, if EC2 returns no data about the
260            instance the update method returns quietly.  If the
261            validate param is True, however, it will raise a
262            ValueError exception if no data is returned from EC2.
263        """
264        rs = self.connection.get_all_dbinstances(self.id)
265        if len(rs) > 0:
266            for i in rs:
267                if i.id == self.id:
268                    self.__dict__.update(i.__dict__)
269        elif validate:
270            raise ValueError('%s is not a valid Instance ID' % self.id)
271        return self.status
272
273    def stop(self, skip_final_snapshot=False, final_snapshot_id=''):
274        """
275        Delete this DBInstance.
276
277        :type skip_final_snapshot: bool
278        :param skip_final_snapshot: This parameter determines whether
279            a final db snapshot is created before the instance is
280            deleted.  If True, no snapshot is created.  If False, a
281            snapshot is created before deleting the instance.
282
283        :type final_snapshot_id: str
284        :param final_snapshot_id: If a final snapshot is requested, this
285            is the identifier used for that snapshot.
286
287        :rtype: :class:`boto.rds.dbinstance.DBInstance`
288        :return: The deleted db instance.
289        """
290        return self.connection.delete_dbinstance(self.id,
291                                                 skip_final_snapshot,
292                                                 final_snapshot_id)
293
294    def modify(self, param_group=None, security_groups=None,
295               preferred_maintenance_window=None,
296               master_password=None, allocated_storage=None,
297               instance_class=None,
298               backup_retention_period=None,
299               preferred_backup_window=None,
300               multi_az=False,
301               iops=None,
302               vpc_security_groups=None,
303               apply_immediately=False,
304               new_instance_id=None):
305        """
306        Modify this DBInstance.
307
308        :type param_group: str
309        :param param_group: Name of DBParameterGroup to associate with
310                            this DBInstance.
311
312        :type security_groups: list of str or list of DBSecurityGroup objects
313        :param security_groups: List of names of DBSecurityGroup to
314            authorize on this DBInstance.
315
316        :type preferred_maintenance_window: str
317        :param preferred_maintenance_window: The weekly time range (in
318            UTC) during which maintenance can occur.  Default is
319            Sun:05:00-Sun:09:00
320
321        :type master_password: str
322        :param master_password: Password of master user for the DBInstance.
323            Must be 4-15 alphanumeric characters.
324
325        :type allocated_storage: int
326        :param allocated_storage: The new allocated storage size, in GBs.
327            Valid values are [5-1024]
328
329        :type instance_class: str
330        :param instance_class: The compute and memory capacity of the
331            DBInstance.  Changes will be applied at next maintenance
332            window unless apply_immediately is True.
333
334            Valid values are:
335
336            * db.m1.small
337            * db.m1.large
338            * db.m1.xlarge
339            * db.m2.xlarge
340            * db.m2.2xlarge
341            * db.m2.4xlarge
342
343        :type apply_immediately: bool
344        :param apply_immediately: If true, the modifications will be
345            applied as soon as possible rather than waiting for the
346            next preferred maintenance window.
347
348        :type new_instance_id: str
349        :param new_instance_id: The new DB instance identifier.
350
351        :type backup_retention_period: int
352        :param backup_retention_period: The number of days for which
353            automated backups are retained.  Setting this to zero
354            disables automated backups.
355
356        :type preferred_backup_window: str
357        :param preferred_backup_window: The daily time range during
358            which automated backups are created (if enabled).  Must be
359            in h24:mi-hh24:mi format (UTC).
360
361        :type multi_az: bool
362        :param multi_az: If True, specifies the DB Instance will be
363            deployed in multiple availability zones.
364
365        :type iops: int
366        :param iops: The amount of IOPS (input/output operations per
367            second) to Provisioned for the DB Instance. Can be
368            modified at a later date.
369
370            Must scale linearly. For every 1000 IOPS provision, you
371            must allocated 100 GB of storage space. This scales up to
372            1 TB / 10 000 IOPS for MySQL and Oracle. MSSQL is limited
373            to 700 GB / 7 000 IOPS.
374
375            If you specify a value, it must be at least 1000 IOPS and
376            you must allocate 100 GB of storage.
377
378        :type vpc_security_groups: list
379        :param vpc_security_groups: List of VPCSecurityGroupMembership
380            that this DBInstance is a memberof.
381
382        :rtype: :class:`boto.rds.dbinstance.DBInstance`
383        :return: The modified db instance.
384        """
385        return self.connection.modify_dbinstance(self.id,
386                                                 param_group,
387                                                 security_groups,
388                                                 preferred_maintenance_window,
389                                                 master_password,
390                                                 allocated_storage,
391                                                 instance_class,
392                                                 backup_retention_period,
393                                                 preferred_backup_window,
394                                                 multi_az,
395                                                 apply_immediately,
396                                                 iops,
397                                                 vpc_security_groups,
398                                                 new_instance_id)
399
400
401class PendingModifiedValues(dict):
402    def startElement(self, name, attrs, connection):
403        return None
404
405    def endElement(self, name, value, connection):
406        if name != 'PendingModifiedValues':
407            self[name] = value
408
409
410class ReadReplicaDBInstanceIdentifiers(list):
411    def startElement(self, name, attrs, connection):
412        return None
413
414    def endElement(self, name, value, connection):
415        if name == 'ReadReplicaDBInstanceIdentifier':
416            self.append(value)
417