def test_foreach_select_from_args_stack_default(  # noqa: D103
    tmp_working_dir_multiple_stacks,
    multiple_stacks,
    default_args,
):
    default_args.stack = "default"

    wrapper_config = deepcopy(vars(default_args))
    parents_count = tfwrapper.detect_config_dir(wrapper_config)
    tfwrapper.detect_stack(wrapper_config,
                           parents_count,
                           raise_on_missing=False)

    stacks = [*tfwrapper.foreach_select_stacks(wrapper_config)]

    expected_stacks = [
        ("account0", "global", None, "default"),
        ("account0", "preprod", "eu-west-1", "default"),
        ("account0", "preprod", "eu-west-2", "default"),
        ("account0", "prod", "eu-west-1", "default"),
        ("account0", "prod", "eu-west-4", "default"),
        ("account0", "test", "eu-west-1", "default"),
        ("account0", "test", "eu-west-2", "default"),
        ("account0", "test", "eu-west-3", "default"),
        ("account1", "global", None, "default"),
        ("account1", "preprod", "eu-west-1", "default"),
        ("account1", "preprod", "eu-west-2", "default"),
        ("account1", "prod", "eu-west-1", "default"),
        ("account1", "prod", "eu-west-4", "default"),
    ]
    for i in range(len(stacks)):
        assert str(stacks[i]) == tfwrapper.get_stack_dir(
            wrapper_config["rootdir"], *expected_stacks[i])
    assert len(stacks) == len(expected_stacks)
def test_load_wrapper_config_autodetect_global(tmp_working_dir_global,
                                               default_args):  # noqa: D103
    paths = tmp_working_dir_global

    paths["state_conf"].write_text(
        textwrap.dedent("""
            ---
            aws:
                general:
                    account: '12345678910' # the AWS account to use for state storage
                credentials:
                    profile: terraform-states-profile # the AWS profile to use for state storage
            """))

    os.chdir(paths["stack_dir"])

    wrapper_config = deepcopy(vars(default_args))
    parents_count = tfwrapper.detect_config_dir(wrapper_config)
    tfwrapper.detect_stack(wrapper_config, parents_count)
    tfwrapper.load_wrapper_config(wrapper_config)
    assert wrapper_config["account"] == "testaccount"
    assert wrapper_config["environment"] == "global"
    assert wrapper_config["region"] is None
    assert wrapper_config["stack"] == "teststack"
    assert wrapper_config["state"]["aws"]["state_account"] == "12345678910"
    assert wrapper_config["state"]["aws"][
        "state_profile"] == "terraform-states-profile"
def test_foreach_select_from_args_env_preprod(tmp_working_dir_multiple_stacks,
                                              multiple_stacks,
                                              default_args):  # noqa: D103
    default_args.environment = "preprod"

    wrapper_config = deepcopy(vars(default_args))
    parents_count = tfwrapper.detect_config_dir(wrapper_config)
    tfwrapper.detect_stack(wrapper_config,
                           parents_count,
                           raise_on_missing=False)

    stacks = [*tfwrapper.foreach_select_stacks(wrapper_config)]

    expected_stacks = [
        ("account0", "preprod", "eu-west-1", "default"),
        ("account0", "preprod", "eu-west-1", "infra"),
        ("account0", "preprod", "eu-west-2", "default"),
        ("account0", "preprod", "eu-west-2", "infra"),
        ("account1", "preprod", "eu-west-1", "default"),
        ("account1", "preprod", "eu-west-1", "infra"),
        ("account1", "preprod", "eu-west-2", "default"),
        ("account1", "preprod", "eu-west-2", "infra"),
    ]
    for i in range(len(stacks)):
        assert str(stacks[i]) == tfwrapper.get_stack_dir(
            wrapper_config["rootdir"], *expected_stacks[i])
    assert len(stacks) == len(expected_stacks)
def test_detect_stack_regional_no_error_if_missing(tmp_working_dir_regional,
                                                   default_args):  # noqa: D103
    paths = tmp_working_dir_regional

    wrapper_config = deepcopy(vars(default_args))
    parents_count = tfwrapper.detect_config_dir(wrapper_config)
    tfwrapper.detect_stack(wrapper_config,
                           parents_count,
                           raise_on_missing=False)
    assert wrapper_config["account"] is None
    assert wrapper_config["environment"] is None
    assert wrapper_config["region"] is None
    assert wrapper_config["stack"] is None

    os.chdir(paths["account_dir"])
    wrapper_config = deepcopy(vars(default_args))
    parents_count = tfwrapper.detect_config_dir(wrapper_config)
    tfwrapper.detect_stack(wrapper_config,
                           parents_count,
                           raise_on_missing=False)
    assert wrapper_config["account"] == "testaccount"
    assert wrapper_config["environment"] is None
    assert wrapper_config["region"] is None
    assert wrapper_config["stack"] is None

    os.chdir(paths["environment_dir"])
    wrapper_config = deepcopy(vars(default_args))
    parents_count = tfwrapper.detect_config_dir(wrapper_config)
    tfwrapper.detect_stack(wrapper_config,
                           parents_count,
                           raise_on_missing=False)
    assert wrapper_config["account"] == "testaccount"
    assert wrapper_config["environment"] == "testenvironment"
    assert wrapper_config["region"] is None
    assert wrapper_config["stack"] is None

    os.chdir(paths["region_dir"])
    wrapper_config = deepcopy(vars(default_args))
    parents_count = tfwrapper.detect_config_dir(wrapper_config)
    tfwrapper.detect_stack(wrapper_config,
                           parents_count,
                           raise_on_missing=False)
    assert wrapper_config["account"] == "testaccount"
    assert wrapper_config["environment"] == "testenvironment"
    assert wrapper_config["region"] == "testregion"
    assert wrapper_config["stack"] is None

    os.chdir(paths["stack_dir"])
    wrapper_config = deepcopy(vars(default_args))
    parents_count = tfwrapper.detect_config_dir(wrapper_config)
    tfwrapper.detect_stack(wrapper_config,
                           parents_count,
                           raise_on_missing=False)
    assert wrapper_config["account"] == "testaccount"
    assert wrapper_config["environment"] == "testenvironment"
    assert wrapper_config["region"] == "testregion"
    assert wrapper_config["stack"] == "teststack"
def test_detect_stack_global(tmp_working_dir_global,
                             default_args):  # noqa: D103
    paths = tmp_working_dir_global

    wrapper_config = deepcopy(vars(default_args))
    parents_count = tfwrapper.detect_config_dir(wrapper_config)
    with pytest.raises(ValueError) as e:
        tfwrapper.detect_stack(wrapper_config, parents_count)
    assert "account cannot be autodetected" in str(e.value)

    os.chdir(paths["account_dir"])
    wrapper_config = deepcopy(vars(default_args))
    parents_count = tfwrapper.detect_config_dir(wrapper_config)
    with pytest.raises(ValueError) as e:
        tfwrapper.detect_stack(wrapper_config, parents_count)
    assert "environment cannot be autodetected" in str(e.value)

    os.chdir(paths["environment_dir"])
    wrapper_config = deepcopy(vars(default_args))
    parents_count = tfwrapper.detect_config_dir(wrapper_config)
    with pytest.raises(ValueError) as e:
        tfwrapper.detect_stack(wrapper_config, parents_count)
    assert "stack cannot be autodetected" in str(e.value)

    os.chdir(paths["stack_dir"])
    wrapper_config = deepcopy(vars(default_args))
    parents_count = tfwrapper.detect_config_dir(wrapper_config)
    tfwrapper.detect_stack(wrapper_config, parents_count)
    assert wrapper_config["account"] == "testaccount"
    assert wrapper_config["environment"] == "global"
    assert wrapper_config["region"] is None
    assert wrapper_config["stack"] == "teststack"
def test_foreach_select_from_dir_account0_prod_euw1(
        tmp_working_dir_multiple_stacks, multiple_stacks,
        default_args):  # noqa: D103
    paths = tmp_working_dir_multiple_stacks

    os.chdir((paths["working_dir"] / "account0/prod/eu-west-1"))

    wrapper_config = deepcopy(vars(default_args))
    parents_count = tfwrapper.detect_config_dir(wrapper_config)
    tfwrapper.detect_stack(wrapper_config,
                           parents_count,
                           raise_on_missing=False)

    stacks = [*tfwrapper.foreach_select_stacks(wrapper_config)]

    expected_stacks = [
        ("account0", "prod", "eu-west-1", "default"),
        ("account0", "prod", "eu-west-1", "infra"),
    ]
    for i in range(len(stacks)):
        assert str(stacks[i]) == tfwrapper.get_stack_dir(
            wrapper_config["rootdir"], *expected_stacks[i])
    assert len(stacks) == len(expected_stacks)
def test_foreach_select_all_stacks(tmp_working_dir_multiple_stacks,
                                   multiple_stacks, default_args,
                                   caplog):  # noqa: D103
    wrapper_config = deepcopy(vars(default_args))
    parents_count = tfwrapper.detect_config_dir(wrapper_config)
    tfwrapper.detect_stack(wrapper_config,
                           parents_count,
                           raise_on_missing=False)

    stacks_with_configs = tfwrapper.foreach_select_stacks(wrapper_config)
    for stack_path, stack_config in stacks_with_configs.items():
        wrapper_stack_config = deepcopy(wrapper_config)
        parents_count = tfwrapper.detect_config_dir(wrapper_stack_config,
                                                    dir=stack_path)
        tfwrapper.detect_stack(wrapper_stack_config,
                               parents_count,
                               raise_on_missing=False,
                               dir=stack_path)
        stack_env = tfwrapper.get_stack_envvars(stack_config,
                                                wrapper_stack_config)
        assert "PATH" in stack_env
        assert stack_env["TFWRAPPER_TF_myvar"] == "myvalue"
        assert stack_env["TFWRAPPER_account"] == wrapper_stack_config[
            "account"]
        assert stack_env["TFWRAPPER_environment"] == wrapper_stack_config[
            "environment"]
        assert stack_env["TFWRAPPER_stack"] == wrapper_stack_config["stack"]
        assert stack_env["TFWRAPPER_region"] == (wrapper_stack_config["region"]
                                                 or "")

    stacks = [*stacks_with_configs]
    for i in range(len(stacks)):
        assert str(stacks[i]) == tfwrapper.get_stack_dir(
            wrapper_config["rootdir"], *multiple_stacks[i])
    assert len(stacks) == len(multiple_stacks)
    assert "Stack config conf/account2_global_default.yml has no matching directory at" in caplog.text