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)
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)
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))
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
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)
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)
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)
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)