def test_interactive_flag_allows_input_and_dynamic_plan_file(
        self,
        fixtures,
    ):
        environment = fixtures['environment']
        release_path = fixtures['release_path']
        account_alias = fixtures['account_alias']
        utcnow = fixtures['utcnow']
        access_key = fixtures['access_key']
        secret_key = fixtures['secret_key']
        token = fixtures['token']
        aws_region = fixtures['aws_region']
        secrets = fixtures['secrets']

        account_scheme = MagicMock(spec=AccountScheme)
        account_scheme.default_region = aws_region
        account_scheme.account_for_environment.return_value = \
            create_mock_account(account_alias)

        boto_session = Mock()
        boto_session.region_name = aws_region
        credentials = BotoCredentials(access_key, secret_key, token)
        boto_session.get_credentials.return_value = credentials

        deploy = Deploy(
            environment,
            release_path,
            secrets,
            account_scheme,
            boto_session,
            interactive=True,
        )

        with ExitStack() as stack:
            path_exists = stack.enter_context(
                patch('cdflow_commands.deploy.path.exists'))
            check_call = stack.enter_context(
                patch('cdflow_commands.deploy.check_call'))
            popen_call = stack.enter_context(
                patch('cdflow_commands.deploy.Popen'))
            NamedTemporaryFile = stack.enter_context(
                patch('cdflow_commands.deploy.NamedTemporaryFile'))
            mock_os = stack.enter_context(patch('cdflow_commands.deploy.os'))
            time = stack.enter_context(patch('cdflow_commands.deploy.time'))

            time.return_value = utcnow

            process_mock = Mock()
            process_mock.poll.return_value = 0
            attrs = {
                'communicate.return_value':
                (''.encode('utf-8'), ''.encode('utf-8'))
            }
            process_mock.configure_mock(**attrs)
            popen_call.return_value = process_mock

            secret_file_path = NamedTemporaryFile.return_value.__enter__\
                .return_value.name

            mock_os.environ = {}

            def mock_path_exists(path):
                return False

            path_exists.side_effect = mock_path_exists

            deploy.run()

            popen_call.assert_any_call(
                [
                    'terraform',
                    'plan',
                    '-var',
                    'env={}'.format(environment),
                    '-var-file',
                    'release.json',
                    '-var-file',
                    'platform-config/{}/{}.json'.format(
                        account_alias, boto_session.region_name),
                    '-var-file',
                    secret_file_path,
                    '-out',
                    'plan-$(date +%s)',
                    'infra',
                ],
                cwd=release_path,
                env={
                    'AWS_ACCESS_KEY_ID': credentials.access_key,
                    'AWS_SECRET_ACCESS_KEY': credentials.secret_key,
                    'AWS_SESSION_TOKEN': credentials.token,
                    'AWS_DEFAULT_REGION': aws_region,
                },
                stdout=PIPE,
                stderr=PIPE)
            check_call.assert_called()
    def test_deploy_runs_terraform_apply_obfuscates_secrets(self, fixtures):
        environment = fixtures['environment']
        release_path = fixtures['release_path']
        account_alias = fixtures['account_alias']
        utcnow = fixtures['utcnow']
        access_key = fixtures['access_key']
        secret_key = fixtures['secret_key']
        token = fixtures['token']
        aws_region = fixtures['aws_region']
        secrets = {'secrets': fixtures['secrets']}
        plan_output = fixtures['plan_output']

        account_scheme = MagicMock(spec=AccountScheme)
        account_scheme.default_region = aws_region
        account_scheme.account_for_environment.return_value = \
            create_mock_account(account_alias)

        boto_session = Mock()
        boto_session.region_name = aws_region
        credentials = BotoCredentials(access_key, secret_key, token)
        boto_session.get_credentials.return_value = credentials

        deploy = Deploy(
            environment,
            release_path,
            secrets,
            account_scheme,
            boto_session,
        )

        with ExitStack() as stack:
            stack.enter_context(patch('cdflow_commands.deploy.path.exists'))
            stack.enter_context(
                patch('cdflow_commands.deploy.NamedTemporaryFile'))
            check_call = stack.enter_context(
                patch('cdflow_commands.deploy.check_call'))
            popen_call = stack.enter_context(
                patch('cdflow_commands.deploy.Popen'))
            mock_os = stack.enter_context(patch('cdflow_commands.deploy.os'))
            time = stack.enter_context(patch('cdflow_commands.deploy.time'))
            mock_stdout = stack.enter_context(
                patch('cdflow_commands.deploy.sys.stdout'))

            time.return_value = utcnow

            process_mock = Mock()
            process_mock.poll.return_value = 0
            attrs = {
                'communicate.return_value': ((plan_output + random.choice(
                    list(secrets['secrets'].values()))).encode('utf-8'),
                                             ''.encode('utf-8'))
            }
            process_mock.configure_mock(**attrs)
            popen_call.return_value = process_mock

            mock_os.environ = {}

            deploy.run()

            check_call.assert_any_call(
                [
                    'terraform', 'apply', '-input=false',
                    'plan-{}'.format(utcnow)
                ],
                cwd=release_path,
                env={
                    'AWS_ACCESS_KEY_ID': credentials.access_key,
                    'AWS_SECRET_ACCESS_KEY': credentials.secret_key,
                    'AWS_SESSION_TOKEN': credentials.token,
                    'AWS_DEFAULT_REGION': aws_region,
                })

            for value in secrets['secrets'].values():
                assert value not in mock_stdout.write.call_args[0][0]