def update(instance_id): updateable_params = ('AllocatedStorage',) incompletes = bottle.request.query.getone('accepts_incomplete') bottle.response.content_type = 'application/json' if incompletes is None: return _abort_async_required() data = json.loads(bottle.request.body.read()) for param in data['parameters'].keys(): if param not in updateable_params: bottle.response.status = 400 msg = 'Updating of {0} is not supported'.format(param) return json.dumps({'description': msg}) dynamodb = utils.boto3_session(**CONFIG['aws']).resource('dynamodb') table = dynamodb.Table(name=CONFIG['dynamodb_table']) record = table.get_item(Key={'instance_id': instance_id}) if 'Item' not in record.keys(): bottle.response.status = 410 return json.dumps({}) else: record = record.pop('Item') rds = RDS(DBInstanceIdentifier=record['hostname'], **CONFIG['aws']) details = rds.db_instance_details() if data['parameters']['AllocatedStorage'] <= details['AllocatedStorage']: bottle.response.status = 400 return json.dumps({ 'description': 'Decreasing AllocatedStorage is not supported.' }) rds.update_instance( DBInstanceIdentifier=record['hostname'], **data['parameters'] ) for i in xrange(0,10): details = rds.db_instance_details() if details['DBInstanceStatus'] != 'available': break sleep(5) else: bottle.response.status = 408 return json.dumps({}) record['last_operation'] = 'update' record['parameters'] = data['parameters'] table.put_item(Item=record) bottle.response.status = 202 return json.dumps({})
def create_from_snapshot_polling(record): """Last operation polling logic for create_from_snaphost action. """ bottle.response.content_type = 'application/json' try: dynamodb = utils.boto3_session(**CONFIG['aws']).resource('dynamodb') table = dynamodb.Table(name=CONFIG['dynamodb_table']) rds = RDS(name=record['hostname'], **CONFIG['aws']) filters = {'DBInstanceIdentifier': record['hostname']} details = rds.rds_conn.describe_db_instances(**filters) details = details['DBInstances'][0] except botocore.exceptions.ClientError as e: # This exception will be raised if nothing matches the filter. if e.response['Error']['Code'] == 'DBInstanceNotFound': bottle.response.status = 410 return json.dumps({}) else: raise if record['step'] == 'deploy': if details['DBInstanceStatus'] == 'available': params = {'DBInstanceIdentifier': record['hostname']} params.update(record['params_to_update']) # Get the new password to pass along for modify. with utils.Crypt(iv=record['iv'], key=CONFIG['encryption_key']) as c: creds = json.loads(c.decrypt(record['credentials'])) params['MasterUserPassword'] = creds['password'] rds.update_instance(**params) record['step'] = 'modify' table.put_item(Item=record) msg = ('RDS Instance is currently in the {0} ' 'state.'.format(details['DBInstanceStatus'])) response = {'state': 'in progress', 'description': msg} bottle.response.status = 200 return json.dumps(response) elif record['step'] == 'modify': if details['DBInstanceStatus'] == 'available': with utils.Crypt(iv=record['iv'], key=CONFIG['encryption_key']) as c: creds = json.loads(c.decrypt(record['credentials'])) creds['hostname'] = details['Endpoint']['Address'] uri = '{0}://{1}:{2}@{3}:{4}/{5}'.format( details['Engine'].lower(), creds['username'], creds['password'], creds['hostname'], creds['port'], creds['db_name'] ) creds['uri'] = uri with utils.Crypt(iv=record['iv'], key=CONFIG['encryption_key']) as c: creds = c.encrypt(json.dumps(creds)) record['credentials'] = creds record['step'] = 'complete' table.put_item(Item=record) msg = ('RDS Instance is currently in the {0} ' 'state.'.format(details['DBInstanceStatus'])) response = {'state': 'in progress', 'description': msg} bottle.response.status = 200 return json.dumps(response) elif record['step'] == 'complete': response = {'state': 'succeeded', 'description': 'Service Created.'} bottle.response.status = 200 return json.dumps(response) else: msg = 'The instance failed to provision' response = {'state': 'failed', 'description': msg} bottle.response.status = 200 return json.dumps(response)