Query an instance upon creation from the EC2 API

def query_instance(vm_=None, call=None):
    '''
    Query an instance upon creation from the EC2 API
    '''
    if call == 'function':
        # Technically this function may be called other ways too, but it
        # definitely cannot be called with --function.
        raise SaltCloudSystemExit(
            'The query_instance action must be called with -a or --action.'
        )

    instance_id = vm_['instance_id']
    location = vm_.get('location', get_location(vm_))
    __utils__['cloud.fire_event'](
        'event',
        'querying instance',
        'salt/cloud/{0}/querying'.format(vm_['name']),
        args={'instance_id': instance_id},
        sock_dir=__opts__['sock_dir'],
        transport=__opts__['transport']
    )

    log.debug('The new VM instance_id is %s', instance_id)

    params = {'Action': 'DescribeInstances',
              'InstanceId.1': instance_id}

    provider = get_provider(vm_)

    attempts = 0
    while attempts < aws.AWS_MAX_RETRIES:
        data, requesturl = aws.query(params,                # pylint: disable=unbalanced-tuple-unpacking
                                     location=location,
                                     provider=provider,
                                     opts=__opts__,
                                     return_url=True,
                                     sigver='4')
        log.debug('The query returned: %s', data)

        if isinstance(data, dict) and 'error' in data:
            log.warning(
                'There was an error in the query. %s attempts '
                'remaining: %s', attempts, data['error']
            )
        elif isinstance(data, list) and not data:
            log.warning(
                'Query returned an empty list. %s attempts '
                'remaining.', attempts
            )
        else:
            break

        aws.sleep_exponential_backoff(attempts)
        attempts += 1
        continue
    else:
        raise SaltCloudSystemExit(
            'An error occurred while creating VM: {0}'.format(data['error'])
        )

    def __query_ip_address(params, url):  # pylint: disable=W0613
        data = aws.query(params,
                         location=location,
                         provider=provider,
                         opts=__opts__,
                         sigver='4')
        if not data:
            log.error(
                'There was an error while querying EC2. Empty response'
            )
            # Trigger a failure in the wait for IP function
            return False

        if isinstance(data, dict) and 'error' in data:
            log.warning('There was an error in the query. %s', data['error'])
            # Trigger a failure in the wait for IP function
            return False

        log.debug('Returned query data: %s', data)

        if ssh_interface(vm_) == 'public_ips':
            if 'ipAddress' in data[0]['instancesSet']['item']:
                return data
            else:
                log.error(
                    'Public IP not detected.'
                )

        if ssh_interface(vm_) == 'private_ips':
            if 'privateIpAddress' in data[0]['instancesSet']['item']:
                return data
            else:
                log.error(
                    'Private IP not detected.'
                )

    try:
        data = salt.utils.cloud.wait_for_ip(
            __query_ip_address,
            update_args=(params, requesturl),
            timeout=config.get_cloud_config_value(
                'wait_for_ip_timeout', vm_, __opts__, default=10 * 60),
            interval=config.get_cloud_config_value(
                'wait_for_ip_interval', vm_, __opts__, default=10),
            interval_multiplier=config.get_cloud_config_value(
                'wait_for_ip_interval_multiplier', vm_, __opts__, default=1),
        )
    except (SaltCloudExecutionTimeout, SaltCloudExecutionFailure) as exc:
        try:
            # It might be already up, let's destroy it!
            destroy(vm_['name'])
        except SaltCloudSystemExit:
            pass
        finally:
            raise SaltCloudSystemExit(six.text_type(exc))

    if 'reactor' in vm_ and vm_['reactor'] is True:
        __utils__['cloud.fire_event'](
            'event',
            'instance queried',
            'salt/cloud/{0}/query_reactor'.format(vm_['name']),
            args={'data': data},
            sock_dir=__opts__['sock_dir'],
            transport=__opts__['transport']
        )

    return data