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)
Exemple #2
0
    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)
Exemple #6
0
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)
Exemple #8
0
    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)
Exemple #9
0
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'])
Exemple #10
0
    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)
Exemple #11
0
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
Exemple #12
0
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()))
Exemple #13
0
    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)
Exemple #16
0
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
Exemple #19
0
    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)
Exemple #20
0
    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)
Exemple #21
0
    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)