Exemplo n.º 1
0
def promote_db_instance(module, conn):
    main_logger.log(30, "promote_db_instance called")
    params = select_parameters_meta(module, conn, 'PromoteReadReplica')
    instance_id = module.params.get('db_instance_identifier')

    result = get_db_instance(conn, instance_id)
    if not result:
        module.fail_json(msg="DB Instance %s does not exist" % instance_id)

    if result.get('replication_source'):
        if module.check_mode:
            module.exit_json(changed=True, promote_read_replica_params=params)
        try:
            response = conn.promote_read_replica(**params)
            instance = response['DBInstance']
            changed = True
        except botocore.exceptions.ClientError as e:
            module.fail_json(msg="Failed to promote replica instance: %s " %
                             str(e),
                             exception=traceback.format_exc(),
                             **camel_dict_to_snake_dict(e.response))
    else:
        changed = False

    if module.params.get('wait'):
        instance = await_resource(conn, instance_id, 'available', module)
    else:
        instance = get_db_instance(conn, instance_id)

    return dict(changed=changed, instance=instance)
Exemplo n.º 2
0
def restore_db_instance(module, conn):
    main_logger.log(30, "resore_db_instance called")
    params = select_parameters_meta(module, conn,
                                    'RestoreDBInstanceFromDBSnapshot')
    instance_id = module.params.get('db_instance_identifier')
    changed = False
    instance = get_db_instance(conn, instance_id)
    if not instance:
        if module.check_mode:
            module.exit_json(
                changed=True,
                restore_db_instance_from_db_snapshot_params=params)
        try:
            response = conn.restore_db_instance_from_db_snapshot(**params)
            instance = response['DBInstance']
            changed = True
        except botocore.exceptions.ClientError as e:
            module.fail_json(msg="Failed to restore instance: %s " % str(e),
                             exception=traceback.format_exc(),
                             **camel_dict_to_snake_dict(e.response))

    if module.params.get('wait'):
        instance = await_resource(conn, instance_id, 'available', module)
    else:
        instance = get_db_instance(conn, instance_id)

    return dict(changed=changed, instance=instance)
Exemplo n.º 3
0
def create_db_instance(module, conn):
    main_logger.log(30, "create_db_instance called")

    params = select_parameters_meta(module, conn, 'CreateDBInstance')

    instance_id = module.params.get('db_instance_identifier')
    params['DBInstanceIdentifier'] = instance_id

    changed = False
    instance = get_db_instance(conn, instance_id)
    if instance is None:
        if module.check_mode:
            module.exit_json(changed=True, create_db_instance_params=params)
        try:
            response = conn.create_db_instance(**params)
            instance = get_db_instance(conn, instance_id)
            changed = True
        except Exception as e:
            module.fail_json_aws(e, msg="trying to create instance")

    if module.params.get('wait'):
        resource = await_resource(conn, instance_id, 'available', module)
    else:
        resource = get_db_instance(conn, instance_id)

    return dict(changed=changed, instance=resource, response=response)
Exemplo n.º 4
0
def await_resource(conn, instance_id, status, module, await_pending=None):
    wait_timeout = module.params.get('wait_timeout') + time.time()
    # Refresh the resource immediately in case we just changed it's state;
    # should we sleep first?
    assert instance_id is not None
    resource = get_db_instance(conn, instance_id)
    main_logger.log(50, "await_resource called for " + instance_id)
    main_logger.log(
        40, "wait is {0} {1} await_pending is {2} status is {3}".format(
            str(wait_timeout), str(time.time()), str(await_pending),
            str(resource['DBInstanceStatus'])))
    rdat = resource["PendingModifiedValues"]
    while ((await_pending and rdat) or resource['DBInstanceStatus'] != status
           ) and wait_timeout > time.time():
        main_logger.log(70, "waiting with resource{}  ".format(str(resource)))
        time.sleep(5)
        # Temporary until all the rds2 commands have their responses parsed
        current_id = resource.get('DBInstanceIdentifier')
        if current_id is None:
            module.fail_json(
                msg="There was a problem waiting for RDS instance %s" %
                resource.instance)
        resource = get_db_instance(conn, current_id)
        if resource is None:
            break
        rdat = resource["PendingModifiedValues"]
    # resource will be none if it has actually been removed - e.g. we were waiting for deleted
    # status; maybe that should be an error in other situations?
    if wait_timeout <= time.time(
    ) and resource is not None and resource['DBInstanceStatus'] != status:
        module.fail_json(
            msg="Timeout waiting for RDS resource %s status is %s should be %s"
            % (resource.get('DBInstanceIdentifier'),
               resource['DBInstanceStatus'], status))
    return resource
Exemplo n.º 5
0
def wait_for_new_instance_id(conn, after_instance_id):
    # Wait until the new instance name is valid
    after_instance = None
    while not after_instance:
        # FIXME: Timeout!!!
        after_instance = get_db_instance(conn, after_instance_id)
        time.sleep(5)
    return after_instance
Exemplo n.º 6
0
def get_instance_to_work_on(module, conn):
    instance_id = module.params.get('db_instance_identifier')
    old_instance_id = module.params.get('old_db_instance_identifier')
    before_instance = None

    if old_instance_id is not None:
        before_instance = get_db_instance(conn, old_instance_id)

    if before_instance is not None:
        if get_db_instance(conn, instance_id):
            module.fail_json(
                msg=
                "both old and new instance exist so can't act safely; please clean up one",
                exception=traceback.format_exc())
        instance = before_instance
    else:
        instance = get_db_instance(conn, instance_id)

    return instance
Exemplo n.º 7
0
 def test_diff_should_compare_important_rds_attributes(self):
     conn = FakeResource()
     db_inst = instance_to_facts(get_db_instance(conn, "fakeDBIDstring"))
     assert len(instance_facts_diff(db_inst, db_inst)
                ) == 0, "comparison of identical instances shows difference!"
     assert not (instance_facts_diff(db_inst, db_inst)
                 ), "comparsion of identical instances is not false!"
     bigger_inst = copy.deepcopy(db_inst)
     bigger_inst["allocated_storage"] = db_inst["allocated_storage"] + 5
     assert len(instance_facts_diff(db_inst, bigger_inst)
                ) > 0, "comparison of differing instances is empty!"
Exemplo n.º 8
0
def replicate_db_instance(module, conn):
    """if the database doesn't exist, create it as a replica of an existing instance
    """
    main_logger.log(30, "replicate_db_instance called")
    params = select_parameters_meta(module, conn,
                                    'CreateDBInstanceReadReplica')
    instance_id = module.params.get('db_instance_identifier')

    instance = get_db_instance(conn, instance_id)
    if instance:
        instance_source = instance.get('SourceDBInstanceIdentifier')
        if not instance_source:
            module.fail_json(
                msg="instance %s already exists; cannot overwrite with replica"
                % instance_id)
        if instance_source != params('SourceDBInstanceIdentifier'):
            module.fail_json(
                msg=
                "instance %s already exists with wrong source %s cannot overwrite"
                % (instance_id, params('SourceDBInstanceIdentifier')))

        changed = False
    else:
        if module.check_mode:
            module.exit_json(changed=True,
                             create_db_instance_read_replica_params=params)
        try:
            response = conn.create_db_instance_read_replica(**params)
            instance = get_db_instance(conn, instance_id)
            changed = True
        except Exception as e:
            module.fail_json_aws(
                e, msg="trying to create read replica of instance")

    if module.params.get('wait'):
        resource = await_resource(conn, instance_id, 'available', module)
    else:
        resource = get_db_instance(conn, instance_id)

    return dict(changed=changed, instance=resource, response=response)
Exemplo n.º 9
0
def delete_db_instance(module, conn):
    main_logger.log(30, "delete_db_instance called")
    try:
        del (module.params['storage_type'])
    except KeyError:
        pass

    params = select_parameters_meta(module, conn, 'DeleteDBInstance')
    instance_id = module.params.get('db_instance_identifier')
    snapshot = module.params.get('final_db_snapshot_identifier')

    result = get_db_instance(conn, instance_id)
    if not result:
        return dict(changed=False)
    if result['DBInstanceStatus'] == 'deleting':
        return dict(changed=False)
    if snapshot:
        params["SkipFinalSnapshot"] = False
        params["FinalDBSnapshotIdentifier"] = snapshot
        del (module.params['snapshot'])
    else:
        params["SkipFinalSnapshot"] = True
    if module.check_mode:
        module.exit_json(changed=True, delete_db_instance_params=params)

    # FIXME: it's possible to get "trying to delete instance: An error occurred
    # (InvalidDBInstanceState) when calling the DeleteDBInstance operation:
    # Cannot delete DB Instance with a read replica still creating",

    # our call should retry here.

    try:
        response = conn.delete_db_instance(**params)
        instance = result
    except Exception as e:
        module.fail_json_aws(e, msg="trying to delete instance")

    # If we're not waiting for a delete to complete then we're all done
    # so just return
    if not module.params.get('wait'):
        return dict(changed=True, response=response)
    try:
        instance = await_resource(conn, instance_id, 'deleted', module)
    except botocore.exceptions.ClientError as e:
        if e.code == 'DBInstanceNotFound':
            return dict(changed=True)
        else:
            module.fail_json_aws(e, msg="waiting for rds deletion to complete")
    except Exception as e:
        module.fail_json_aws(e, msg="waiting for rds deletion to complete")

    return dict(changed=True, response=response, instance=instance)
Exemplo n.º 10
0
 def test_instance_facts_gives_sensible_values(self):
     conn = FakeResource()
     db_facts = instance_to_facts(get_db_instance(conn, "fakeDBIDstring"))
     assert db_facts[db_id_key] == "fakeDBIDstring"
Exemplo n.º 11
0
 def test_get_db_instance_should_return_camel_dict(self):
     conn = FakeResource()
     db_inst = get_db_instance(conn, "fakeDBIDstring")
     assert db_id_key not in db_inst
     assert db_inst["DBInstanceIdentifier"] == "fakeDBIDstring"