Exemplo n.º 1
0
    def test_stream_build_config_app_creation_no_build_arn_failed_to_create(
            self, mock_wait_attribute, mock_success_events):
        mock_wait_attribute.return_value = False
        self.mock_beanstalk.get_application_versions.return_value = self.app_version_raw_response
        mock_success_events.side_effect = ServiceError(
            'Failed to create application version')

        build_spec = MagicMock()
        build_spec.timeout = 60

        self.assertRaises(
            ServiceError,
            buildspecops.stream_build_configuration_app_version_creation,
            self.app_name, self.version_label, build_spec)

        mock_wait_attribute.assert_called_with(self.app_name,
                                               [self.version_label],
                                               timeout=1)
        self.mock_beanstalk.get_application_versions.assert_called_with(
            self.app_name, version_labels=[self.version_label])
        self.mock_codebuild.batch_get_builds.assert_not_called()

        timeout_error_message = ' '.join([
            'The CodeBuild build timed out after 60 minute(s).',
            "To increase the time limit, use the 'Timeout' option in the 'buildspec.yml' file."
        ])
        mock_success_events.assert_called_with(
            app_name='foo-app',
            can_abort=False,
            request_id=None,
            timeout_error_message=timeout_error_message,
            timeout_in_minutes=60,
            version_label=self.version_label)
        self.mock_beanstalk.delete_application_version.assert_called_with(
            self.app_name, self.version_label)
Exemplo n.º 2
0
def create_codecommit_app_version(app_name,
                                  process=False,
                                  label=None,
                                  message=None,
                                  build_config=None):
    fileoperations.ProjectRoot.traverse()

    source_control = SourceControl.get_source_control()
    if source_control.get_current_commit() is None:
        io.log_warning(
            'There are no commits for the current branch, attempting '
            'to create an empty commit and launching with the sample '
            'application')
        source_control.create_initial_commit()

    if source_control.untracked_changes_exist():
        io.log_warning(strings['sc.unstagedchanges'])

    if label:
        version_label = label
    else:
        version_label = source_control.get_version_label()

    if message:
        description = message
    else:
        description = source_control.get_message()

    if len(description) > 200:
        description = description[:195] + '...'

    try:
        source_control.push_codecommit_code()
    except CommandError as e:
        io.echo("Could not push code to the CodeCommit repository:")
        raise e

    from ebcli.operations import gitops
    repository = gitops.get_default_repository()
    commit_id = source_control.get_current_commit()

    if repository is None or commit_id is None:
        raise ServiceError(
            "Could not find repository or commit id to create an application version"
        )

    io.log_info('Creating AppVersion ' + version_label)
    return _create_application_version(app_name,
                                       version_label,
                                       description,
                                       None,
                                       None,
                                       process,
                                       repository=repository,
                                       commit_id=commit_id,
                                       build_config=build_config)
Exemplo n.º 3
0
def _handle_response_code(response_data, attempt, aggregated_error_message):
    max_attempts = 10

    LOG.debug('Response: ' + str(response_data))
    status = response_data['ResponseMetadata']['HTTPStatusCode']
    LOG.debug('API call finished, status = ' + str(status))
    try:
        message = str(response_data['Error']['Message'])
    except KeyError:
        message = ""
    if status == 400:
        error = _get_400_error(response_data, message)
        if isinstance(error, ThrottlingError):
            LOG.debug('Received throttling error')
            if attempt > max_attempts:
                raise MaxRetriesError('Max retries exceeded for '
                                      'throttling error')
        else:
            raise error
    elif status == 403:
        LOG.debug('Received a 403')
        if not message:
            message = 'Are your permissions correct?'
        if _region_name == 'cn-north-1':
            raise NotAuthorizedInRegionError(
                'Operation Denied. ' + message + '\n' +
                strings['region.china.credentials'])
        else:
            raise NotAuthorizedError('Operation Denied. ' + message)
    elif status == 404:
        LOG.debug('Received a 404')
        raise NotFoundError(message)
    elif status == 409:
        LOG.debug('Received a 409')
        raise AlreadyExistsError(message)
    elif status in (500, 503, 504):
        LOG.debug('Received 5XX error')
        retry_failure_message = \
            'Received 5XX error during attempt #{0}\n   {1}\n'.format(
                str(attempt),
                message
            )

        aggregated_error_message.insert(attempt, retry_failure_message)

        if attempt > max_attempts:
            _handle_500_error(('\n').join(aggregated_error_message))
    else:
        raise ServiceError('API Call unsuccessful. '
                           'Status code returned ' + str(status))
Exemplo n.º 4
0
def _make_api_call(operation_name, **operation_options):
    try:
        result = aws.make_api_call('codebuild', operation_name, **operation_options)
    except ServiceError as ex:
        if ex.code == 'AccessDeniedException':
            io.echo(
                "EB CLI does not have the right permissions to access CodeBuild.\n"
                "To learn more, see Docs: https://docs-aws.amazon.com/codebuild/"
                "latest/userguide/auth-and-access-control-permissions-reference.html"
            )
        raise ex
    except EndpointConnectionError:
        LOG.debug(
            "Caught endpoint timeout for CodeBuild."
            " We are assuming this is because they are not supported in that region yet."
        )
        raise ServiceError("Elastic Beanstalk does not support AWS CodeBuild in this region.")
    return result
Exemplo n.º 5
0
def _get_400_error(response_data, message):
    code = response_data['Error']['Code']
    LOG.debug('Received a 400 Error')
    if code == 'InvalidParameterValue':
        return InvalidParameterValueError(message)
    elif code == 'InvalidQueryParameter':
        return InvalidQueryParameterError(message)
    elif code.startswith('Throttling'):
        return ThrottlingError(message)
    elif code.startswith('ResourceNotFound'):
        return NotFoundError(message)
    elif code.startswith('TooManyPlatformsException'):
        return TooManyPlatformsError(message)
    elif code.startswith('TooManyConfigurationTemplatesException'):
        message = [
            'Your request cannot be completed. You have reached the maximum',
            'number of saved configuration templates. Learn more about service',
            'limits: http://docs.aws.amazon.com/general/latest/gr/aws_service_limits.html'
        ]
        return TooManyConfigurationTemplatesException(' '.join(message))
    else:
        return ServiceError(message, code=code)
Exemplo n.º 6
0
def create_app_version_from_source(
        app_name,
        source,
        process=False,
        label=None,
        message=None,
        build_config=None
):
    cwd = os.getcwd()
    fileoperations.ProjectRoot.traverse()
    try:
        if heuristics.directory_is_empty():
            io.echo('NOTE: {}'.format(strings['appversion.none']))
            return None
    finally:
        os.chdir(cwd)

    source_control = SourceControl.get_source_control()
    if source_control.untracked_changes_exist():
        io.log_warning(strings['sc.unstagedchanges'])

    if label:
        version_label = label
    else:
        version_label = source_control.get_version_label()

    if message:
        description = message
    else:
        description = source_control.get_message()

    if len(description) > 200:
        description = description[:195] + '...'

    source_location, repository, branch = utils.parse_source(source)

    if not branch or not repository:
        raise InvalidOptionsError(strings['codecommit.bad_source'])

    if source_location == "codecommit":
        try:
            result = codecommit.get_branch(repository, branch)
        except ServiceError as ex:
            io.log_error(
                "Could not get branch '{0}' for the repository '{1}' "
                "because of this error: {2}".format(
                    branch,
                    repository,
                    ex.code
                )
            )
            raise ex

        commit_id = result['branch']['commitId']
        if repository is None or commit_id is None:
            raise ServiceError("Could not find repository or commit id to create an application version")
    else:
        LOG.debug("Source location '{0}' is not supported".format(source_location))
        raise InvalidOptionsError(
            "This command does not support the given source location: {0}".format(
                source_location
            )
        )

    io.log_info('Creating AppVersion ' + version_label)
    return _create_application_version(app_name, version_label, description,
                                       None, None, process, repository=repository, commit_id=commit_id,
                                       build_config=build_config)
Exemplo n.º 7
0
def _raise_if_error_event(message):
    if message == responses['event.redmessage']:
        raise ServiceError(message)
    if message == responses['event.failedlaunch']:
        raise ServiceError(message)
    if message == responses['event.faileddeploy']:
        raise ServiceError(message)
    if message == responses['event.failedupdate']:
        raise ServiceError(message)
    if message == responses['event.updatefailed']:
        raise ServiceError(message)
    if message.startswith(responses['event.launchbad']):
        raise ServiceError(message)
    if message.startswith(responses['event.updatebad']):
        raise ServiceError(message)
    if message.startswith(responses['event.platformdeletefailed']):
        raise ServiceError(message)
    if message.startswith(responses['event.platformcreatefailed']):
        raise ServiceError(message)
    if message.startswith(responses['event.completewitherrors']):
        raise ServiceError(message)
    if message.startswith(responses['event.platform_ami_region_service_region_mismatch']):
        raise ServiceError(message)
    if (
            message.startswith(responses['event.launched_environment'])
            and 'However, there were issues during launch.' in message
    ):
        raise ServiceError(message)
    if responses['tags.no_tags_to_update'] in message:
        raise ServiceError(message)
    if message.startswith(responses['logs.fail']):
        raise ServiceError(message)
    if message.startswith(responses['create.ecsdockerrun1']):
        raise NotSupportedError(prompts['create.dockerrunupgrade'])
    if message.startswith(responses['appversion.finished']) and message.endswith('FAILED.'):
        raise ServiceError(message)
Exemplo n.º 8
0
def make_api_call(service_name, operation_name, **operation_options):
    operation = _set_operation(service_name, operation_name)
    aggregated_error_message = []
    max_attempts = 10

    region = _region_name
    if not region:
        region = 'default'

    attempt = 0
    while True:
        attempt += 1
        if attempt > 1:
            LOG.debug('Retrying -- attempt #' + str(attempt))
        delay = _get_delay(attempt)
        time.sleep(delay)
        try:
            LOG.debug('Making api call: (' + service_name + ', ' +
                      operation_name + ') to region: ' + region +
                      ' with args:' + str(operation_options))
            response_data = operation(**operation_options)
            status = response_data['ResponseMetadata']['HTTPStatusCode']
            LOG.debug('API call finished, status = ' + str(status))
            if response_data:
                LOG.debug('Response: ' + str(response_data))

            return response_data

        except botocore.exceptions.ClientError as e:
            _handle_response_code(e.response, attempt,
                                  aggregated_error_message)
        except botocore.parsers.ResponseParserError as e:
            LOG.debug('Botocore could not parse response received')
            if attempt > max_attempts:
                raise MaxRetriesError(
                    'Max retries exceeded for ResponseParserErrors' +
                    os.linesep.join(aggregated_error_message))

            aggregated_error_message.insert(attempt, str(e))
        except botocore.exceptions.NoCredentialsError:
            LOG.debug('No credentials found')
            raise CredentialsError('Operation Denied. You appear to have no'
                                   ' credentials')
        except botocore.exceptions.PartialCredentialsError as e:
            LOG.debug('Credentials incomplete')
            raise CredentialsError(str(e))

        except (botocore.exceptions.ValidationError,
                botocore.exceptions.ParamValidationError) as e:
            raise ValidationError(str(e))

        except botocore.exceptions.BotoCoreError:
            LOG.error('Botocore Error')
            raise

        except IOError as error:
            if hasattr(error.args[0], 'reason') and str(error.args[0].reason) == \
                    '[Errno -2] Name or service not known':
                raise ConnectionError()

            LOG.error('Error while contacting Elastic Beanstalk Service')
            LOG.debug('error:' + str(error))
            raise ServiceError(error)