def do_command(self): force = self.app.pargs.force delete_application_and_resources = self.app.pargs.all ignore_links = self.app.pargs.ignore_links timeout = self.app.pargs.timeout nohang = self.app.pargs.nohang if delete_application_and_resources: app_name = self.get_app_name() cleanup = not self.app.pargs.region terminateops.delete_app(app_name, force, nohang=nohang, cleanup=cleanup, timeout=timeout) else: env_name = self.get_env_name() if not force: io.echo(prompts['terminate.confirm'].format(env_name=env_name)) io.validate_action(prompts['terminate.validate'], env_name) terminateops.terminate(env_name, force_terminate=ignore_links, nohang=nohang, timeout=timeout)
def do_command(self): force = self.app.pargs.force delete_application_and_resources = self.app.pargs.all ignore_links = self.app.pargs.ignore_links timeout = self.app.pargs.timeout nohang = self.app.pargs.nohang if delete_application_and_resources: app_name = self.get_app_name() cleanup = not self.app.pargs.region terminateops.delete_app( app_name, force, nohang=nohang, cleanup=cleanup, timeout=timeout ) else: env_name = self.get_env_name() if not force: io.echo(prompts['terminate.confirm'].format(env_name=env_name)) io.validate_action(prompts['terminate.validate'], env_name) terminateops.terminate( env_name, force_terminate=ignore_links, nohang=nohang, timeout=timeout )
def test_validate_action( self, get_input_mock ): get_input_mock.return_value = 'expected_input' io.validate_action('customer prompt', 'expected_input')
def delete_app_version_label(app_name, version_label): if version_label: # check if version_label exists under app_name app_versions = elasticbeanstalk.get_application_versions(app_name)['ApplicationVersions'] # if the given version label does not exist at all! if not any(version_label == app_version['VersionLabel'] for app_version in app_versions): raise ValidationError(strings['appversion.delete.notfound'].format(app_name, version_label)) envs = elasticbeanstalk.get_app_environments(app_name) versions_in_use = [(e.version_label, e.name) for e in envs] # find all the environments that are using the app version used_envs = [version[1] for version in versions_in_use if version[0] == version_label] if used_envs: raise ValidationError(strings['appversion.delete.deployed'].format(version_label, ','.join(used_envs))) try: io.validate_action(prompts['appversion.delete.validate'].format(version_label), "y") elasticbeanstalk.delete_application_version(app_name, version_label) io.echo('Application Version deleted successfully.') delete_successful = True except ValidationError: io.echo('Application Version will not be deleted.') delete_successful = False return delete_successful else: raise NotFoundError(strings['appversion.delete.none'])
def delete_platform_version(platform_version, force=False): arn = _version_to_arn(platform_version) if not force: io.echo(prompts['platformdelete.confirm'].replace( '{platform-arn}', arn)) io.validate_action(prompts['platformdelete.validate'], arn) environments = [] try: environments = [ env for env in elasticbeanstalk.get_environments() if env.platform.version == arn ] except NotFoundError: pass if len(environments) > 0: _, platform_name, platform_version = PlatformVersion.arn_to_platform( arn) raise ValidationError(strings['platformdeletevalidation.error'].format( platform_name, platform_version, '\n '.join([env.name for env in environments]))) response = elasticbeanstalk.delete_platform(arn) request_id = response['ResponseMetadata']['RequestId'] timeout = 10 commonops.wait_for_success_events(request_id, timeout_in_minutes=timeout, platform_arn=arn)
def initialize_codecommit(): source_control = SourceControl.get_source_control() try: source_control_setup = source_control.is_setup() except CommandError: source_control_setup = False if not source_control_setup: io.log_error("Cannot setup CodeCommit because there is no Source Control setup") return if codecommit.region_supported(commonops.get_default_region()): # Show the current setup if there is one and ask if they want to continue codecommit_setup = print_current_codecommit_settings() if codecommit_setup: try: io.validate_action("Do you wish to continue (y/n)", "y") except ValidationError: return # Setup git config settings for code commit credentials source_control.setup_codecommit_cred_config() # Get user desired repository from ebcli.controllers import initialize repository = initialize.get_repository_interactive() branch = initialize.get_branch_interactive(repository) # set defaults for current environment set_repo_default_for_current_environment(repository) set_branch_default_for_current_environment(branch) else: io.log_error("The region {0} is not supported by CodeCommit".format(commonops.get_default_region()))
def delete_platform_version(platform_version, force=False): arn = _version_to_arn(platform_version) if not force: io.echo(prompts['platformdelete.confirm'].replace('{platform-arn}', arn)) io.validate_action(prompts['platformdelete.validate'], arn) environments = [] try: environments = [env for env in elasticbeanstalk.get_environments() if env.platform.version == arn] except NotFoundError: pass if len(environments) > 0: _, platform_name, platform_version = PlatformVersion.arn_to_platform(arn) raise ValidationError(strings['platformdeletevalidation.error'].format( platform_name, platform_version, '\n '.join([env.name for env in environments]) )) response = elasticbeanstalk.delete_platform(arn) request_id = response['ResponseMetadata']['RequestId'] timeout = 10 commonops.wait_for_success_events(request_id, timeout_in_minutes=timeout, platform_arn=arn)
def cleanup_platforms(self): force = self.app.pargs.force all_platforms = self.app.pargs.all_platforms if all_platforms: platform_name = None else: platform_name = fileoperations.get_platform_name() # We clean up all failed platform versions failed_versions = sorted( platformops.list_custom_platform_versions( platform_name=platform_name, status='Failed', ) ) if failed_versions: if not force: if not platform_name: io.echo(prompts['cleanupplatform.confirm'].replace('{platform-name}', 'All Platforms')) for failed_version in failed_versions: io.echo(failed_version) io.validate_action(prompts['cleanupplatform.validate-all'], 'all') else: io.echo(prompts['cleanupplatform.confirm'].replace('{platform-name}', platform_name)) io.validate_action(prompts['cleanupplatform.validate'], platform_name) for failed_version in failed_versions: platformops.delete_platform_version(failed_version, force=True)
def do_command(self): force = self.app.pargs.force delete_application_and_resources = self.app.pargs.all ignore_links = self.app.pargs.ignore_links timeout = self.app.pargs.timeout nohang = self.app.pargs.nohang app_name = self.get_app_name() if delete_application_and_resources: cleanup = not self.app.pargs.region terminateops.delete_app(app_name, force, nohang=nohang, cleanup=cleanup, timeout=timeout) else: env_name = self.get_env_name() if not force: io.echo(prompts['terminate.confirm'].format(env_name=env_name)) io.validate_action(prompts['terminate.validate'], env_name) if terminateops.is_shared_load_balancer(app_name, env_name): alert_message = alerts['sharedlb.terminate'].format( env_name=env_name) io.log_alert(alert_message + '\n') terminateops.terminate(env_name, force_terminate=ignore_links, nohang=nohang, timeout=timeout)
def prompt_for_ec2_keyname(env_name=None, message=None, keyname=None): if message is None: message = prompts['ssh.setup'] if env_name: io.validate_action(prompts['terminate.validate'], env_name) else: io.echo(message) ssh = io.get_boolean_response() if not ssh: return None keys = [k['KeyName'] for k in ec2.get_key_pairs()] default_option = len(keys) if keyname: for index, key in enumerate(keys): if key == keyname: default_option = index + 1 if len(keys) < 1: keyname = _generate_and_upload_keypair(keys) else: new_key_option = '[ Create new KeyPair ]' keys.append(new_key_option) io.echo() io.echo(prompts['keypair.prompt']) keyname = utils.prompt_for_item_in_list(keys, default=default_option) if keyname == new_key_option: keyname = _generate_and_upload_keypair(keys) return keyname
def initialize_codecommit(): source_control = SourceControl.get_source_control() try: source_control_setup = source_control.is_setup() except CommandError: source_control_setup = False if not source_control_setup: io.log_error("Cannot setup CodeCommit because there is no Source Control setup") return if codecommit.region_supported(commonops.get_default_region()): # Show the current setup if there is one and ask if they want to continue codecommit_setup = print_current_codecommit_settings() if codecommit_setup: try: io.validate_action("Do you wish to continue (y/n)", "y") except ValidationError: return # Setup git config settings for code commit credentials source_control.setup_codecommit_cred_config() # Get user desired repository from ..controllers import initialize repository = initialize.get_repository_interactive() branch = initialize.get_branch_interactive(repository) # set defaults for current environment set_repo_default_for_current_environment(repository) set_branch_default_for_current_environment(branch) else: io.log_error("The region {0} is not supported by CodeCommit".format(commonops.get_default_region()))
def test_validate_action__mismatch(self, get_input_mock): get_input_mock.return_value = 'unexpected_input' with self.assertRaises(io.ValidationError) as context_manager: io.validate_action('customer prompt', 'expected_input') self.assertEqual('Names do not match. Exiting.', str(context_manager.exception))
def restore_environment_num(self, environment_number): """Take in user input as a string, convert it to a decimal, get the environment that the user input matches, and attempt to restore that environment. """ environment_number = int( environment_number) # raises InvalidOperation Exception environments = self.poller.all_environments e_len = len(environments) if environment_number > e_len or environment_number < 1: raise IndexError environment = environments[e_len - environment_number] env_id = environment.get(u'EnvironmentId') should_exit_display = True if env_id: try: self.flusher(term.get_terminal()) io.validate_action( prompts['restore.selectedenv'].replace( '{env_id}', env_id).replace( '{app}', utils.encode_to_ascii( environment.get('ApplicationName'))).replace( '{desc}', utils.encode_to_ascii( environment.get('Description'))). replace('{cname}', utils.encode_to_ascii( environment.get('CNAME'))).replace( '{version}', utils.encode_to_ascii( environment.get('VersionLabel'))). replace( '{platform}', utils.encode_to_ascii( environment.get('SolutionStackName'))).replace( '{dat_term}', environment.get('DateUpdated')), 'y') from ebcli.operations import restoreops # restore specified environment self.request_id = restoreops.restore(env_id) return should_exit_display except ValidationError: io.echo(responses['restore.norestore']) time.sleep(1) should_exit_display = False return should_exit_display # Exception should never get thrown else: raise Exception
def ask_for_customer_confirmation_to_delete_all_application_resources( app_name): application = elasticbeanstalk.describe_application(app_name) application['Versions'] = application.get('Versions', []) environments = elasticbeanstalk.get_environment_names(app_name) confirm_message = prompts['delete.confirm'].format( app_name=app_name, env_num=len(environments), config_num=len(application['ConfigurationTemplates']), version_num=len(application['Versions'])) io.echo(confirm_message) io.validate_action(prompts['delete.validate'], app_name)
def configure_codecommit(source): source_location, repository, branch = utils.parse_source(source) source_control = SourceControl.get_source_control() try: if not source_location: io.validate_action(prompts['codecommit.usecc'], "y") # Setup git config settings for code commit credentials source_control.setup_codecommit_cred_config() repository, branch = establish_codecommit_repository_and_branch( repository, branch, source_control, source_location) except ValidationError: LOG.debug("Denied option to use CodeCommit, continuing initialization") return repository, branch
def upgrade_env(app_name, env_name, timeout, confirm, noroll): env = elasticbeanstalk.get_environment_settings(app_name, env_name) latest = solution_stack_ops.find_solution_stack_from_string( env.platform.name, find_newer=True) if latest.name == env.platform.name: io.echo(prompts['upgrade.alreadylatest']) return else: single = elasticbeanstalk.get_option_setting( env.option_settings, namespaces.ENVIRONMENT, 'EnvironmentType') == 'SingleInstance' rolling_enabled = elasticbeanstalk.get_option_setting( env.option_settings, namespaces.ROLLING_UPDATES, option_names.ROLLING_UPDATE_ENABLED) == 'true' webserver = env.tier.name.lower() == 'webserver' io.echo() io.echo(prompts['upgrade.infodialog'].format(env_name)) io.echo('Current platform:', env.platform) io.echo('Latest platform: ', latest.name) io.echo() warning = _get_warning_message(confirm, single, rolling_enabled, webserver, noroll) if warning: io.log_warning(warning) io.echo(prompts['upgrade.altmessage']) io.echo() if not confirm: io.validate_action(prompts['upgrade.validate'], env.name) add_rolling = _should_add_rolling(single, rolling_enabled, noroll) do_upgrade(env_name, add_rolling, timeout, latest.name, health_based=webserver, platform_arn=latest.name)
def restore_environment_num(self, environment_number): """Take in user input as a string, convert it to a decimal, get the environment that the user input matches, and attempt to restore that environment. """ environment_number = int(environment_number) # raises InvalidOperation Exception environments = self.poller.all_environments e_len = len(environments) if environment_number > e_len or environment_number < 1: raise IndexError environment = environments[e_len - environment_number] env_id = environment.get(u'EnvironmentId') should_exit_display = True if env_id: try: self.flusher(term.get_terminal()) io.validate_action(prompts['restore.selectedenv'].replace('{env_id}', env_id) .replace('{app}', utils.encode_to_ascii(environment.get('ApplicationName'))) .replace('{desc}', utils.encode_to_ascii(environment.get('Description'))) .replace('{cname}', utils.encode_to_ascii(environment.get('CNAME'))) .replace('{version}', utils.encode_to_ascii(environment.get('VersionLabel'))) .replace('{platform}', utils.encode_to_ascii(environment.get('SolutionStackName'))) .replace('{dat_term}', environment.get('DateUpdated')), 'y') from ebcli.operations import restoreops # restore specified environment self.request_id = restoreops.restore(env_id) return should_exit_display except ValidationError: io.echo(responses['restore.norestore']) time.sleep(1) should_exit_display = False return should_exit_display # Exception should never get thrown else: raise Exception
def do_command(self): # get arguments self.interactive = self.app.pargs.interactive self.region = self.app.pargs.region self.noverify = self.app.pargs.no_verify_ssl self.force_non_interactive = False # Determine if the customer is avoiding interactive mode by setting the platform flag if self.app.pargs.platform: self.force_non_interactive = True # Code Commit integration self.source = self.app.pargs.source source_location = None branch = None repository = None if self.source is not None: source_location, repository, branch = utils.parse_source(self.source) # The user specifies directories to initialize self.modules = self.app.pargs.modules if self.modules and len(self.modules) > 0: self.initialize_multiple_directories() return default_env = self.get_old_values() fileoperations.touch_config_folder() if self.interactive: self.region = get_region(self.region, self.interactive, self.force_non_interactive) else: self.region = get_region_from_inputs(self.region) aws.set_region(self.region) self.region = set_up_credentials(self.app.pargs.profile, self.region, self.interactive) self.solution = self.get_solution_stack() self.app_name = self.get_app_name() if self.noverify: fileoperations.write_config_setting('global', 'no-verify-ssl', True) if not default_env and not self.interactive: # try to get default env from config file if exists try: default_env = commonops.get_current_branch_environment() except NotInitializedError: default_env = None elif self.interactive: default_env = None if self.force_non_interactive: default_env = '/ni' # Create application sstack, key = commonops.pull_down_app_info(self.app_name, default_env=default_env) if elasticbeanstalk.application_exist(self.app_name) \ else commonops.create_app(self.app_name, default_env=default_env) if not self.solution: self.solution = sstack platform_set = False if not self.solution or \ (self.interactive and not self.app.pargs.platform): if fileoperations.env_yaml_exists(): env_yaml_platform = fileoperations.get_platform_from_env_yaml() if env_yaml_platform: platform = solutionstack.SolutionStack(env_yaml_platform).platform_shorthand self.solution = platform platform_set = True if not platform_set: self.solution = solution_stack_ops.get_solution_stack_from_customer().platform_shorthand # Select CodeBuild image if BuildSpec is present do not prompt or show if we are non-interactive if fileoperations.build_spec_exists() and not self.force_non_interactive: build_spec = fileoperations.get_build_configuration() if build_spec is not None and build_spec.image is None: LOG.debug("Buildspec file is present but image is does not exist. Attempting to fill best guess.") platform_image = initializeops.get_codebuild_image_from_platform(self.solution) # If the return is a dictionary then it must be a single image and we can use that automatically if type(platform_image) is dict: io.echo('codebuild.latestplatform'.replace('{platform}', self.solution)) else: # Otherwise we have an array for images which we must prompt the customer to pick from io.echo(prompts['codebuild.getplatform'].replace('{platform}', self.solution)) selected = utils.prompt_for_index_in_list(map(lambda image: image['description'], platform_image)) platform_image = platform_image[selected] platform_image['name'] = utils.decode_bytes(platform_image['name']) # Finally write the CodeBuild image back to the buildspec file fileoperations.write_config_setting(fileoperations.buildspec_config_header, 'Image', platform_image['name'], file=fileoperations.buildspec_name) # Setup code commit integration # Ensure that git is setup source_control = SourceControl.get_source_control() try: source_control_setup = source_control.is_setup() if source_control_setup is None: source_control_setup = False except CommandError: source_control_setup = False default_branch_exists = False if gitops.git_management_enabled() and not self.interactive: default_branch_exists = True # Warn the customer if they picked a region that CodeCommit is not supported codecommit_region_supported = codecommit.region_supported(self.region) if self.source is not None and not codecommit_region_supported: io.log_warning(strings['codecommit.badregion']) # Prompt customer to opt into CodeCommit unless one of the follows holds: if self.force_non_interactive: prompt_codecommit = False elif not codecommit.region_supported(self.region): prompt_codecommit = False elif self.source and source_location.lower() != 'codecommit': # Do not prompt if customer has already specified a code source to # associate the EB workspace with prompt_codecommit = False elif default_branch_exists: # Do not prompt if customer has already configured the EB application # in the present working directory with Git prompt_codecommit = False else: prompt_codecommit = True # Prompt for interactive CodeCommit if prompt_codecommit: if not source_control_setup: io.echo(strings['codecommit.nosc']) else: io.echo(strings['codecommit.ccwarning']) try: if not self.source: io.validate_action(prompts['codecommit.usecc'], "y") # Setup git config settings for code commit credentials source_control.setup_codecommit_cred_config() # Get user specified repository remote_url = None if repository is None: repository = get_repository_interactive() else: try: setup_codecommit_remote_repo(repository, source_control) except ServiceError as ex: if self.source: create_codecommit_repository(repository) setup_codecommit_remote_repo(repository, source_control) else: io.log_error(strings['codecommit.norepo']) raise ex # Get user specified branch if branch is None: branch = get_branch_interactive(repository) else: try: codecommit.get_branch(repository, branch) except ServiceError as ex: if self.source: create_codecommit_branch(source_control, branch) else: io.log_error(strings['codecommit.nobranch']) raise ex source_control.setup_existing_codecommit_branch(branch, remote_url) except ValidationError: LOG.debug("Denied option to use CodeCommit, continuing initialization") # Initialize the whole setup initializeops.setup(self.app_name, self.region, self.solution, dir_path=None, repository=repository, branch=branch) if 'IIS' not in self.solution: self.keyname = self.get_keyname(default=key) if self.keyname == -1: self.keyname = None fileoperations.write_config_setting('global', 'default_ec2_keyname', self.keyname) # Default to including git submodules when creating zip files through `eb create`/`eb deploy`. fileoperations.write_config_setting('global', 'include_git_submodules', True)
def do_command(self): # get arguments self.interactive = self.app.pargs.interactive self.region = self.app.pargs.region self.noverify = self.app.pargs.no_verify_ssl self.force_non_interactive = False # Determine if the customer is avoiding interactive mode by setting the platform flag if self.app.pargs.platform: self.force_non_interactive = True # The user specifies directories to initialize self.modules = self.app.pargs.modules if self.modules and len(self.modules) > 0: self.initialize_multiple_directories() return source_location, branch, repository = None, None, None if self.app.pargs.source: source_location, repository, branch = utils.parse_source( self.app.pargs.source) default_env = self.get_old_values() fileoperations.touch_config_folder() self.region = set_region_for_application(self.interactive, self.region, self.force_non_interactive) self.region = set_up_credentials(self.app.pargs.profile, self.region, self.interactive) self.solution = self.get_solution_stack() self.app_name = self.get_app_name() if self.noverify: fileoperations.write_config_setting('global', 'no-verify-ssl', True) default_env = set_default_env(default_env, self.interactive, self.force_non_interactive) sstack, key = create_app_or_use_existing_one(self.app_name, default_env) self.solution = self.solution or sstack if fileoperations.env_yaml_exists(): self.solution = self.solution or extract_solution_stack_from_env_yaml( ) self.solution = self.solution or solution_stack_ops.get_solution_stack_from_customer( ).platform_shorthand handle_buildspec_image(self.solution, self.force_non_interactive) # Setup code commit integration # Ensure that git is setup source_control = SourceControl.get_source_control() try: source_control_setup = source_control.is_setup() if source_control_setup is None: source_control_setup = False except CommandError: source_control_setup = False default_branch_exists = not not (gitops.git_management_enabled() and not self.interactive) if source_location and not codecommit.region_supported(self.region): io.log_warning(strings['codecommit.badregion']) # Prompt customer to opt into CodeCommit unless one of the follows holds: if self.force_non_interactive: prompt_codecommit = False elif not codecommit.region_supported(self.region): prompt_codecommit = False elif source_location and source_location.lower() != 'codecommit': # Do not prompt if customer has already specified a code source to # associate the EB workspace with prompt_codecommit = False elif default_branch_exists: # Do not prompt if customer has already configured the EB application # in the present working directory with Git prompt_codecommit = False elif not source_control_setup: if source_location: io.echo(strings['codecommit.nosc']) prompt_codecommit = False else: prompt_codecommit = True # Prompt for interactive CodeCommit if prompt_codecommit: try: if not source_location: io.validate_action(prompts['codecommit.usecc'], "y") # Setup git config settings for code commit credentials source_control.setup_codecommit_cred_config() # Get user specified repository remote_url = None if repository is None: repository = get_repository_interactive() else: try: setup_codecommit_remote_repo(repository, source_control) except ServiceError as ex: if source_location: create_codecommit_repository(repository) setup_codecommit_remote_repo( repository, source_control) else: io.log_error(strings['codecommit.norepo']) raise ex # Get user specified branch if branch is None: branch = get_branch_interactive(repository) else: try: codecommit.get_branch(repository, branch) except ServiceError as ex: if source_location: create_codecommit_branch(source_control, branch) else: io.log_error(strings['codecommit.nobranch']) raise ex source_control.setup_existing_codecommit_branch( branch, remote_url) except ValidationError: LOG.debug( "Denied option to use CodeCommit, continuing initialization" ) # Initialize the whole setup initializeops.setup(self.app_name, self.region, self.solution, dir_path=None, repository=repository, branch=branch) if 'IIS' not in self.solution: self.keyname = self.get_keyname(default=key) if self.keyname == -1: self.keyname = None fileoperations.write_config_setting('global', 'default_ec2_keyname', self.keyname) # Default to including git submodules when creating zip files through `eb create`/`eb deploy`. fileoperations.write_config_setting('global', 'include_git_submodules', True)
def do_command(self): # get arguments self.interactive = self.app.pargs.interactive self.region = self.app.pargs.region self.noverify = self.app.pargs.no_verify_ssl self.force_non_interactive = False # Determine if the customer is avoiding interactive mode by setting the platform flag if self.app.pargs.platform: self.force_non_interactive = True # Code Commit integration self.source = self.app.pargs.source source_location = None branch = None repository = None if self.source is not None: source_location, repository, branch = utils.parse_source( self.source) # The user specifies directories to initialize self.modules = self.app.pargs.modules if self.modules and len(self.modules) > 0: self.initialize_multiple_directories() return default_env = self.get_old_values() fileoperations.touch_config_folder() if self.interactive: self.region = get_region(self.region, self.interactive, self.force_non_interactive) else: self.region = get_region_from_inputs(self.app.pargs.region) aws.set_region(self.region) # Warn the customer if they picked a region that CodeCommit is not supported codecommit_region_supported = codecommit.region_supported(self.region) if self.source is not None and not codecommit_region_supported: io.log_warning(strings['codecommit.badregion']) self.region = set_up_credentials(self.app.pargs.profile, self.region, self.interactive) self.solution = self.get_solution_stack() self.app_name = self.get_app_name() if self.noverify: fileoperations.write_config_setting('global', 'no-verify-ssl', True) if not default_env and not self.interactive: # try to get default env from config file if exists try: default_env = commonops.get_current_branch_environment() except NotInitializedError: default_env = None elif self.interactive: default_env = None if self.force_non_interactive: default_env = '/ni' # Create application sstack, key = commonops.pull_down_app_info(self.app_name, default_env=default_env) if elasticbeanstalk.application_exist(self.app_name) \ else commonops.create_app(self.app_name, default_env=default_env) if not self.solution: self.solution = sstack platform_set = False if not self.solution or \ (self.interactive and not self.app.pargs.platform): if fileoperations.env_yaml_exists(): env_yaml_platform = fileoperations.get_platform_from_env_yaml() if env_yaml_platform: platform = solutionstack.SolutionStack( env_yaml_platform).version self.solution = platform platform_set = True if not platform_set: result = commonops.prompt_for_solution_stack() self.solution = result.version # Select CodeBuild image if BuildSpec is present do not prompt or show if we are non-interactive if fileoperations.build_spec_exists( ) and not self.force_non_interactive: build_spec = fileoperations.get_build_configuration() if build_spec is not None and build_spec.image is None: LOG.debug( "Buildspec file is present but image is does not exist. Attempting to fill best guess." ) platform_image = initializeops.get_codebuild_image_from_platform( self.solution) # If the return is a dictionary then it must be a single image and we can use that automatically if type(platform_image) is dict: io.echo('codebuild.latestplatform'.replace( '{platform}', self.solution)) else: # Otherwise we have an array for images which we must prompt the customer to pick from io.echo(prompts['codebuild.getplatform'].replace( '{platform}', self.solution)) selected = utils.prompt_for_index_in_list( map(lambda image: image['description'], platform_image)) platform_image = platform_image[selected] platform_image['name'] = utils.decode_bytes( platform_image['name']) # Finally write the CodeBuild image back to the buildspec file fileoperations.write_config_setting( fileoperations.buildspec_config_header, 'Image', platform_image['name'], file=fileoperations.buildspec_name) # Setup code commit integration # Ensure that git is setup source_control = SourceControl.get_source_control() try: source_control_setup = source_control.is_setup() if source_control_setup is None: source_control_setup = False except CommandError: source_control_setup = False default_branch_exists = False if gitops.git_management_enabled() and not self.interactive: default_branch_exists = True prompt_codecommit = True # Do not prompt if we are in non-interactive mode, the region is not supported for CodeCommit, # the specified source is from CodeCommit OR we already have default CodeCommit values set. if self.force_non_interactive \ or not codecommit.region_supported(self.region) \ or self.source is not None \ or default_branch_exists: prompt_codecommit = False # Prompt for interactive CodeCommit if prompt_codecommit: if not source_control_setup: io.echo(strings['codecommit.nosc']) else: io.echo(strings['codecommit.ccwarning']) try: io.validate_action(prompts['codecommit.usecc'], "y") # Setup git config settings for code commit credentials source_control.setup_codecommit_cred_config() # Get user specified repository if repository is None: repository = get_repository_interactive() else: try: result = codecommit.get_repository(repository) source_control.setup_codecommit_remote_repo( remote_url=result['repositoryMetadata'] ['cloneUrlHttp']) except ServiceError as ex: io.log_error(strings['codecommit.norepo']) raise ex # Get user specified branch if branch is None: branch = get_branch_interactive(repository) else: try: codecommit.get_branch(repository, branch) except ServiceError as ex: io.log_error(strings['codecommit.nobranch']) raise ex source_control.setup_existing_codecommit_branch(branch) except ValidationError: LOG.debug( "Denied option to use CodeCommit, continuing initialization" ) # Initialize the whole setup initializeops.setup(self.app_name, self.region, self.solution, dir_path=None, repository=repository, branch=branch) if 'IIS' not in self.solution: self.keyname = self.get_keyname(default=key) if self.keyname == -1: self.keyname = None fileoperations.write_config_setting('global', 'default_ec2_keyname', self.keyname) # Default to including git submodules when creating zip files through `eb create`/`eb deploy`. fileoperations.write_config_setting('global', 'include_git_submodules', True)