예제 #1
0
def handle_buildspec_image(solution, force_non_interactive):
    if not fileoperations.build_spec_exists():
        return

    build_spec = fileoperations.get_build_configuration()
    if not force_non_interactive and build_spec 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(
            solution)

        if type(platform_image) is dict:
            io.echo(strings['codebuild.latestplatform'].replace(
                '{platform}', solution))
        else:
            io.echo(prompts['codebuild.getplatform'].replace(
                '{platform}', solution))
            selected = utils.prompt_for_index_in_list(
                [image['description'] for image in platform_image][0])
            platform_image = [
                image for image in platform_image
                if selected == image['description']
            ][0]
        fileoperations.write_buildspec_config_header('Image',
                                                     platform_image['name'])
예제 #2
0
    def test_prompt_for_index_in_list__explicit_none_default_no_selection_made(
        self,
        echo_mock,
        prompt_mock,
    ):
        call_tracker = mock.Mock()
        call_tracker.attach_mock(echo_mock, 'echo_mock')
        call_tracker.attach_mock(prompt_mock, 'prompt_mock')

        lst = ['a', 'b', 'c']
        prompt_mock.side_effect = [0, 1]

        result = utils.prompt_for_index_in_list(lst, None)

        call_tracker.assert_has_calls([
            mock.call.echo_mock('1)', 'a'),
            mock.call.echo_mock('2)', 'b'),
            mock.call.echo_mock('3)', 'c'),
            mock.call.prompt_mock('make a selection', default=0),
            mock.call.echo_mock(
                'Sorry, that is not a valid choice. Please choose a number between 1 and 3.'
            ),
            mock.call.prompt_mock('make a selection', default=0),
            mock.call.echo_mock(),
        ],
                                      any_order=False)
        self.assertEqual(0, result)
예제 #3
0
파일: localops.py 프로젝트: mschmutz1/jokic
def open_webpage(cnt_viewmodel):
    """
    Open the webpage at container ip and host port we exposed when we ran this container.
    Raise error if container not running and prompt user to choose host port if multiple
    host ports exposed under this container.
    :param cnt_viewmodel: ContainerViewModel: contains view info about container
    :return: None
    """

    if not cnt_viewmodel.is_running():
        raise RuntimeError(strings['local.open.nocontainer'])

    # Get container id, exposed host port pairs
    cid_hostports = cnt_viewmodel.get_cid_hostport_pairs()
    num_exposed_hostports = cnt_viewmodel.num_exposed_hostports()

    if num_exposed_hostports == 1:
        _, host_port = cid_hostports[0]

    elif num_exposed_hostports > 1:
        io.echo()
        io.echo('Select a container applcation to open')
        io.echo()

        disp = ['Container {}, host port {}'.format(cid, p) for cid, p in cid_hostports]
        ind = utils.prompt_for_index_in_list(disp)

        _, host_port = cid_hostports[ind]

    else:
        raise RuntimeError(strings['local.open.noexposedport'])


    url = '{}:{}'.format(cnt_viewmodel.ip, host_port)
    commonops.open_webpage_in_browser(url)
예제 #4
0
def get_shared_lb_from_customer(interactive, elb_type, platform, vpc=None):
    """
    Prompt customer to select if they would like to use shared load balancer.
    Selection defaults to 'N'
    Prompt customer to select load balancer from a list, if they selected 'y' for previous prompt
    return: ARN of selected load balancer
    """
    if not interactive or elb_type != elb_names.APPLICATION_VERSION:
        return

    alb_list = elasticbeanstalk.list_application_load_balancers(platform, vpc)
    if not alb_list:
        return

    should_continue = io.get_boolean_response(
        text=prompts['sharedlb.shared_load_balancer_request_prompt'],
        default=False)
    if not should_continue:
        return

    alb_list_display_labels = []
    for load_balancer_arn in alb_list:
        load_balancer_name = parse_load_balancer_name(load_balancer_arn)
        alb_list_display_labels.append(load_balancer_name + ' - ' +
                                       load_balancer_arn)

    io.echo(prompts['sharedlb.shared_load_balancer_prompt'])
    selected_index = utils.prompt_for_index_in_list(alb_list_display_labels,
                                                    default=1)
    return alb_list[selected_index]
예제 #5
0
def prompt_for_platform_branch(family):
    branches = platform_branch_ops.list_nonretired_platform_branches()
    branches = [branch for branch in branches if branch['PlatformName'] == family]
    branches = _sort_platform_branches_for_prompt(branches)

    if len(branches) == 1:
        return PlatformBranch.from_platform_branch_summary(branches[0])

    branch_display_names = [_generate_platform_branch_prompt_text(branch) for branch in branches]
    default = utils.index_of(
        branches,
        value=platform_branch_lifecycle_states.SUPPORTED,
        key=lambda b: b['LifecycleState'])

    if default == -1:
        default = None
    else:
        default += 1

    io.echo(prompts['platformbranch.prompt'])
    index = utils.prompt_for_index_in_list(branch_display_names, default=default)
    return PlatformBranch.from_platform_branch_summary(branches[index])
예제 #6
0
    def test_prompt_for_index_in_list__explicit_none_default(
        self,
        echo_mock,
        prompt_mock,
    ):
        call_tracker = mock.Mock()
        call_tracker.attach_mock(echo_mock, 'echo_mock')
        call_tracker.attach_mock(prompt_mock, 'prompt_mock')

        lst = ['a', 'b', 'c']
        prompt_mock.return_value = 1

        result = utils.prompt_for_index_in_list(lst, None)

        call_tracker.assert_has_calls([
            mock.call.echo_mock('1)', 'a'),
            mock.call.echo_mock('2)', 'b'),
            mock.call.echo_mock('3)', 'c'),
            mock.call.prompt_mock('make a selection', default=0),
            mock.call.echo_mock(),
        ],
                                      any_order=False)
        self.assertEqual(0, result)
예제 #7
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)
예제 #8
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)