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