def do_command(self): fileoperations.touch_config_folder() self.interactive = self.app.pargs.interactive or not self.app.pargs.platform_name self.region = self.app.pargs.region if self.interactive or not self.app.pargs.platform_name: self.region = get_region(self.app.pargs.region, self.interactive) else: self.region = get_region_from_inputs(self.app.pargs.region) aws.set_region(self.region) self.region = set_up_credentials(self.app.pargs.profile, self.region, self.interactive) self.platform_name, version = get_platform_name_and_version( self.app.pargs.platform_name) self.keyname = self.app.pargs.keyname if not self.keyname and self.interactive: self.keyname = get_keyname() initializeops.setup('Custom Platform Builder', self.region, None, workspace_type=Constants.WorkSpaceTypes.PLATFORM, platform_name=self.platform_name, platform_version=version) fileoperations.write_keyname(self.keyname) if version is None: platformops.set_workspace_to_latest()
def setUp(self): super(BaseIntegrationTest, self).setUp() aws._flush() aws.set_region('us-east-1') self.reset_backend() self.patcher_input = mock.patch('ebcli.core.io.get_input') self.patcher_output = mock.patch('ebcli.core.io.echo') self.patcher_warning = mock.patch('ebcli.core.io.log_warning') self.mock_input = self.patcher_input.start() self.mock_output = self.patcher_output.start() self.mock_warning = self.patcher_warning.start() self.patcher_endpoint = mock.patch('botocore.endpoint.Endpoint') self.mock_endpoint = self.patcher_endpoint.start() instance = self.mock_endpoint.return_value instance.make_request = mockservice.handle_response instance.host = 'http://someurl.test/something' if not os.path.exists('testDir/'): os.makedirs('testDir/') os.chdir('testDir') if not os.path.exists(fileoperations.beanstalk_directory): os.makedirs(fileoperations.beanstalk_directory) fileoperations.default_section = 'ebcli_test_default' if not os.path.exists('home'): os.makedirs('home') fileoperations.aws_config_folder = 'home' + os.path.sep fileoperations.aws_config_location \ = fileoperations.aws_config_folder + 'config'
def setUp(self): self.root_dir = os.getcwd() if not os.path.exists('testDir'): os.mkdir('testDir') aws.set_region(None) os.chdir('testDir')
def test_user_agent(self): aws.set_region('us-east-1') client = aws._get_client('elasticbeanstalk') user_agent = client._client_config.user_agent self.assertTrue( user_agent.startswith('eb-cli/{current_ebcli_version}'.format( current_ebcli_version=current_ebcli_version)))
def set_region_for_application(interactive, region, force_non_interactive): if interactive or (not region and not force_non_interactive): region = get_region(region, interactive, force_non_interactive) else: region = get_region_from_inputs(region) aws.set_region(region) return region
def set_region_for_application(interactive, region, force_non_interactive, platform=None): region = get_region(region, interactive, force_non_interactive, platform) aws.set_region(region) return region
def check_credentials(profile, given_profile, given_region, interactive, force_non_interactive): try: # Note, region is None unless explicitly set or read from old eb initializeops.credentials_are_valid() return profile, given_region except NoRegionError: region = get_region(None, interactive, force_non_interactive) aws.set_region(region) return profile, region except InvalidProfileError as e: if given_profile: # Provided profile is invalid, raise exception raise e else: # eb-cli profile doesnt exist, revert to default # try again profile = None aws.set_profile(profile) return check_credentials(profile, given_profile, given_region, interactive, force_non_interactive)
def check_credentials(profile, given_profile, given_region, interactive, force_non_interactive): try: # Note, region is None unless explicitly set or read from old eb initializeops.credentials_are_valid() return profile, given_region except NoRegionError: region = get_region(None, interactive, force_non_interactive) aws.set_region(region) return profile, region except InvalidProfileError: if given_profile: # Provided profile is invalid, raise exception raise else: # eb-cli profile doesnt exist, revert to default # try again profile = None aws.set_profile(profile) return check_credentials(profile, given_profile, given_region, interactive, force_non_interactive)
def ssh(self): aws.set_region(self.region) aws.set_profile(self.profile) if self.environment_name is None: environment_names = get_all_environment_names() if environment_names: error = "Please chose one of the following environment names:\n\n" error += "\n".join(sorted(environment_names)) + "\n" io.log_error(error) else: io.log_error( "The current Elastic Beanstalk application has no environments" ) sys.exit() instances = get_instance_ids(self.environment_name) if len(instances) == 1: instance = instances[0] else: io.echo() io.echo('Select an instance to ssh into') instance = utils.prompt_for_item_in_list(instances) params = [ "aws", "ssm", "start-session", "--document-name", "AWS-StartInteractiveCommand", "--parameters", "command='bash -l'", "--profile", self.profile, "--region", self.region, "--target", instance, ] os.system(" ".join(params))
def check_credentials(self, profile): given_profile = self.app.pargs.profile try: # Note, region is None unless explicitly set ## or read from old eb initializeops.credentials_are_valid() return profile except NoRegionError: self.region = self.get_region() aws.set_region(self.region) return profile except InvalidProfileError: if given_profile: # Provided profile is invalid, raise exception raise else: # eb-cli profile doesnt exist, revert to default # try again profile = None aws.set_profile(profile) return self.check_credentials(profile)
def do_command(self): fileoperations.touch_config_folder() self.interactive = self.app.pargs.interactive self.region = self.app.pargs.region if self.interactive: self.region = get_region(self.app.pargs.region, self.app.pargs.interactive) else: self.region = get_region_from_inputs(self.app.pargs.region) aws.set_region(self.region) self.region = set_up_credentials(self.app.pargs.profile, self.region, self.interactive) self.platform_name, version = self.get_platform_name_and_version() # If interactive mode, or explicit interactive due to missing platform_name if self.interactive or not self.platform_name: self.keyname = self.get_keyname(self.app.pargs.keyname) else: self.keyname = None if self.keyname == -1: self.keyname = None initializeops.setup( 'Custom Platform Builder', self.region, None, workspace_type=Constants.WorkSpaceTypes.PLATFORM, platform_name=self.platform_name, platform_version=version) fileoperations.write_keyname(self.keyname) if version is None: platformops.set_workspace_to_latest()
def main(): """ Main function called from console_scripts """ logger = logging.getLogger('ebi') logger.propagate = True logger.setLevel(logging.INFO) logger.addHandler(logging.StreamHandler()) parser = argparse.ArgumentParser() subparsers = parser.add_subparsers() parser_bgdeploy = subparsers.add_parser('bgdeploy') parser_clonedeploy = subparsers.add_parser('clonedeploy') parser_create = subparsers.add_parser('create') parser_deploy = subparsers.add_parser('deploy') apply_args_bgdeploy(parser_bgdeploy) apply_args_clonedeploy(parser_clonedeploy) apply_args_create(parser_create) apply_args_deploy(parser_deploy) parsed = parser.parse_args() if not hasattr(parsed, 'func'): parser.print_help() return conf = {} if parsed.profile: conf['profile_name'] = parsed.profile if parsed.region: conf['region_name'] = parsed.region boto3.setup_default_session(**conf) session = boto3._get_default_session() ebaws.set_region(session._session.get_config_variable('region')) ebaws.set_profile(session.profile_name) parsed.func(parsed)
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 initialize_multiple_directories(self): application_created = False self.app_name = None cwd = os.getcwd() for module in self.modules: if os.path.exists(module) and os.path.isdir(module): os.chdir(module) fileoperations.touch_config_folder() # Region should be set once for all modules if not self.region: 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) self.region = set_up_credentials(self.app.pargs.profile, self.region, self.interactive) solution = self.get_solution_stack() # App name should be set once for all modules if not self.app_name: # Switching back to the root dir will suggest the root dir name # as the application name os.chdir(cwd) self.app_name = self.get_app_name() os.chdir(module) if self.noverify: fileoperations.write_config_setting('global', 'no-verify-ssl', True) default_env = None if self.force_non_interactive: default_env = '/ni' if not application_created: sstack, key = commonops.create_app(self.app_name, default_env=default_env) application_created = True else: sstack, key = commonops.pull_down_app_info(self.app_name, default_env=default_env) io.echo('\n--- Configuring module: {0} ---'.format(module)) if not solution: solution = sstack platform_set = False # TODO: Do not require a solution stack if one has already been set by this point if not 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 solution = platform io.echo(strings['init.usingenvyamlplatform'].replace('{platform}', platform)) platform_set = True if not platform_set: solution = solution_stack_ops.get_solution_stack_from_customer() initializeops.setup(self.app_name, self.region, solution) if 'IIS' not in solution: keyname = self.get_keyname(default=key) if keyname == -1: self.keyname = None fileoperations.write_config_setting('global', 'default_ec2_keyname', keyname) os.chdir(cwd)
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)
def initialize_multiple_directories(self): application_created = False self.app_name = None cwd = os.getcwd() for module in self.modules: if os.path.exists(module) and os.path.isdir(module): os.chdir(module) fileoperations.touch_config_folder() # Region should be set once for all modules if not self.region: 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) self.region = set_up_credentials(self.app.pargs.profile, self.region, self.interactive) solution = self.get_solution_stack() # App name should be set once for all modules if not self.app_name: # Switching back to the root dir will suggest the root dir name # as the application name os.chdir(cwd) self.app_name = self.get_app_name() os.chdir(module) if self.noverify: fileoperations.write_config_setting( 'global', 'no-verify-ssl', True) default_env = None if self.force_non_interactive: default_env = '/ni' if not application_created: sstack, key = commonops.create_app(self.app_name, default_env=default_env) application_created = True else: sstack, key = commonops.pull_down_app_info( self.app_name, default_env=default_env) io.echo('\n--- Configuring module: {0} ---'.format(module)) if not solution: solution = sstack platform_set = False if not 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 solution = platform io.echo( strings['init.usingenvyamlplatform'].replace( '{platform}', platform)) platform_set = True if not platform_set: result = commonops.prompt_for_solution_stack() solution = result.version initializeops.setup(self.app_name, self.region, solution) if 'IIS' not in solution: keyname = self.get_keyname(default=key) if keyname == -1: self.keyname = None fileoperations.write_config_setting( 'global', 'default_ec2_keyname', keyname) os.chdir(cwd)
def tearDown(self): os.chdir(self.root_dir) shutil.rmtree('testDir') aws.set_region(None)
def set_region(region_name): if not region_name: region_name = commonops.get_default_region() aws.set_region(region_name)
parser.add_argument('--appEnvironment', type=str, required=True, dest='app_environment') parser.add_argument('--appversion', type=str, required=True, dest='version') parser.add_argument('--region', type=str, required=True, dest='region') parser.add_argument('--tags', type=str, required=True, dest='tags') parser.add_argument('--template', type=str, required=True, dest='template') if __name__ == "__main__": ''' Check if environment already exists. Note. There is no version check. ''' args = parser.parse_args() aws.set_region(args.region) response = eb.describe_environments(ApplicationName=args.app, EnvironmentNames=[ args.app_environment, ], IncludeDeleted=False) if response['Environments']: print 'Found Environment. Updating' __update_environment(application=args.app, app_environment=args.app_environment, version=args.version, template=args.template) else: print 'Not Found Environment. Creating'