qontract-reconcile 0.10.1rc1201__py3-none-any.whl → 0.10.2.dev1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- qontract_reconcile-0.10.2.dev1.dist-info/METADATA +500 -0
- {qontract_reconcile-0.10.1rc1201.dist-info → qontract_reconcile-0.10.2.dev1.dist-info}/RECORD +14 -132
- {qontract_reconcile-0.10.1rc1201.dist-info → qontract_reconcile-0.10.2.dev1.dist-info}/WHEEL +1 -2
- {qontract_reconcile-0.10.1rc1201.dist-info → qontract_reconcile-0.10.2.dev1.dist-info}/entry_points.txt +1 -0
- reconcile/aws_account_manager/README.md +5 -0
- reconcile/change_owners/README.md +34 -0
- reconcile/external_resources/manager.py +12 -1
- reconcile/external_resources/model.py +11 -0
- reconcile/glitchtip/README.md +150 -0
- reconcile/gql_definitions/introspection.json +51176 -0
- reconcile/run_integration.py +293 -0
- reconcile/utils/binary.py +2 -2
- reconcile/utils/mr/README.md +198 -0
- reconcile/utils/oc_map.py +2 -2
- tools/qontract_cli.py +0 -0
- qontract_reconcile-0.10.1rc1201.dist-info/METADATA +0 -64
- qontract_reconcile-0.10.1rc1201.dist-info/top_level.txt +0 -3
- reconcile/test/__init__.py +0 -0
- reconcile/test/conftest.py +0 -157
- reconcile/test/fixtures.py +0 -24
- reconcile/test/saas_auto_promotions_manager/__init__.py +0 -0
- reconcile/test/saas_auto_promotions_manager/conftest.py +0 -170
- reconcile/test/saas_auto_promotions_manager/merge_request_manager/__init__.py +0 -0
- reconcile/test/saas_auto_promotions_manager/merge_request_manager/merge_request_manager/__init__.py +0 -0
- reconcile/test/saas_auto_promotions_manager/merge_request_manager/merge_request_manager/conftest.py +0 -115
- reconcile/test/saas_auto_promotions_manager/merge_request_manager/merge_request_manager/data_keys.py +0 -19
- reconcile/test/saas_auto_promotions_manager/merge_request_manager/merge_request_manager/test_desired_state.py +0 -66
- reconcile/test/saas_auto_promotions_manager/merge_request_manager/merge_request_manager/test_merge_request_manager.py +0 -86
- reconcile/test/saas_auto_promotions_manager/merge_request_manager/merge_request_manager/test_mr_parser.py +0 -352
- reconcile/test/saas_auto_promotions_manager/merge_request_manager/merge_request_manager/test_reconciler.py +0 -494
- reconcile/test/saas_auto_promotions_manager/merge_request_manager/renderer/__init__.py +0 -0
- reconcile/test/saas_auto_promotions_manager/merge_request_manager/renderer/conftest.py +0 -25
- reconcile/test/saas_auto_promotions_manager/merge_request_manager/renderer/test_content_multiple_namespaces.py +0 -37
- reconcile/test/saas_auto_promotions_manager/merge_request_manager/renderer/test_content_single_namespace.py +0 -81
- reconcile/test/saas_auto_promotions_manager/merge_request_manager/renderer/test_content_single_target.py +0 -61
- reconcile/test/saas_auto_promotions_manager/merge_request_manager/renderer/test_json_path_selector.py +0 -74
- reconcile/test/saas_auto_promotions_manager/test_integration_test.py +0 -52
- reconcile/test/saas_auto_promotions_manager/utils/__init__.py +0 -0
- reconcile/test/test_acs_notifiers.py +0 -393
- reconcile/test/test_acs_policies.py +0 -497
- reconcile/test/test_acs_rbac.py +0 -865
- reconcile/test/test_aggregated_list.py +0 -237
- reconcile/test/test_amtool.py +0 -37
- reconcile/test/test_aws_ami_cleanup.py +0 -230
- reconcile/test/test_aws_ami_share.py +0 -68
- reconcile/test/test_aws_cloudwatch_log_retention.py +0 -434
- reconcile/test/test_aws_iam_keys.py +0 -70
- reconcile/test/test_aws_iam_password_reset.py +0 -35
- reconcile/test/test_aws_support_cases_sos.py +0 -23
- reconcile/test/test_checkpoint.py +0 -178
- reconcile/test/test_cli.py +0 -41
- reconcile/test/test_closedbox_endpoint_monitoring.py +0 -207
- reconcile/test/test_dashdotdb_dora.py +0 -245
- reconcile/test/test_database_access_manager.py +0 -660
- reconcile/test/test_deadmanssnitch.py +0 -290
- reconcile/test/test_gabi_authorized_users.py +0 -72
- reconcile/test/test_gcr_mirror.py +0 -14
- reconcile/test/test_github_org.py +0 -156
- reconcile/test/test_github_repo_invites.py +0 -119
- reconcile/test/test_gitlab_housekeeping.py +0 -333
- reconcile/test/test_gitlab_labeler.py +0 -126
- reconcile/test/test_gitlab_members.py +0 -219
- reconcile/test/test_gitlab_permissions.py +0 -164
- reconcile/test/test_instrumented_wrappers.py +0 -18
- reconcile/test/test_integrations_manager.py +0 -1252
- reconcile/test/test_jenkins_worker_fleets.py +0 -57
- reconcile/test/test_jira_permissions_validator.py +0 -519
- reconcile/test/test_jump_host.py +0 -114
- reconcile/test/test_ldap_users.py +0 -125
- reconcile/test/test_make.py +0 -28
- reconcile/test/test_ocm_additional_routers.py +0 -133
- reconcile/test/test_ocm_clusters.py +0 -798
- reconcile/test/test_ocm_clusters_manifest_updates.py +0 -87
- reconcile/test/test_ocm_machine_pools.py +0 -1103
- reconcile/test/test_ocm_update_recommended_version.py +0 -145
- reconcile/test/test_ocm_upgrade_scheduler_org_updater.py +0 -125
- reconcile/test/test_openshift_base.py +0 -1269
- reconcile/test/test_openshift_cluster_bots.py +0 -240
- reconcile/test/test_openshift_namespace_labels.py +0 -344
- reconcile/test/test_openshift_namespaces.py +0 -256
- reconcile/test/test_openshift_resource.py +0 -443
- reconcile/test/test_openshift_resources_base.py +0 -478
- reconcile/test/test_openshift_saas_deploy.py +0 -188
- reconcile/test/test_openshift_saas_deploy_change_tester.py +0 -308
- reconcile/test/test_openshift_saas_deploy_trigger_cleaner.py +0 -65
- reconcile/test/test_openshift_serviceaccount_tokens.py +0 -282
- reconcile/test/test_openshift_tekton_resources.py +0 -265
- reconcile/test/test_openshift_upgrade_watcher.py +0 -223
- reconcile/test/test_prometheus_rules_tester.py +0 -151
- reconcile/test/test_quay_membership.py +0 -86
- reconcile/test/test_quay_mirror.py +0 -172
- reconcile/test/test_quay_mirror_org.py +0 -82
- reconcile/test/test_quay_repos.py +0 -59
- reconcile/test/test_queries.py +0 -53
- reconcile/test/test_repo_owners.py +0 -47
- reconcile/test/test_requests_sender.py +0 -139
- reconcile/test/test_saasherder.py +0 -1611
- reconcile/test/test_saasherder_allowed_secret_paths.py +0 -125
- reconcile/test/test_secret_reader.py +0 -153
- reconcile/test/test_slack_base.py +0 -183
- reconcile/test/test_slack_usergroups.py +0 -785
- reconcile/test/test_sql_query.py +0 -316
- reconcile/test/test_status_board.py +0 -258
- reconcile/test/test_terraform_aws_route53.py +0 -29
- reconcile/test/test_terraform_cloudflare_dns.py +0 -117
- reconcile/test/test_terraform_cloudflare_resources.py +0 -408
- reconcile/test/test_terraform_cloudflare_users.py +0 -747
- reconcile/test/test_terraform_repo.py +0 -440
- reconcile/test/test_terraform_resources.py +0 -519
- reconcile/test/test_terraform_tgw_attachments.py +0 -1295
- reconcile/test/test_terraform_users.py +0 -152
- reconcile/test/test_terraform_vpc_peerings.py +0 -576
- reconcile/test/test_terraform_vpc_peerings_build_desired_state.py +0 -1434
- reconcile/test/test_three_way_diff_strategy.py +0 -131
- reconcile/test/test_utils_jinja2.py +0 -130
- reconcile/test/test_vault_replication.py +0 -534
- reconcile/test/test_vault_utils.py +0 -47
- reconcile/test/test_version_bump.py +0 -18
- reconcile/test/test_vpc_peerings_validator.py +0 -194
- reconcile/test/test_wrong_region.py +0 -78
- release/__init__.py +0 -0
- release/test_version.py +0 -50
- release/version.py +0 -104
- tools/cli_commands/test/__init__.py +0 -0
- tools/cli_commands/test/conftest.py +0 -332
- tools/cli_commands/test/test_aws_cost_report.py +0 -258
- tools/cli_commands/test/test_cost_management_api.py +0 -326
- tools/cli_commands/test/test_gpg_encrypt.py +0 -235
- tools/cli_commands/test/test_openshift_cost_optimization_report.py +0 -255
- tools/cli_commands/test/test_openshift_cost_report.py +0 -295
- tools/cli_commands/test/test_util.py +0 -70
- tools/test/__init__.py +0 -0
- tools/test/conftest.py +0 -77
- tools/test/test_app_interface_metrics_exporter.py +0 -48
- tools/test/test_erv2.py +0 -80
- tools/test/test_get_container_images.py +0 -230
- tools/test/test_qontract_cli.py +0 -197
- tools/test/test_saas_promotion_state.py +0 -187
- tools/test/test_sd_app_sre_alert_report.py +0 -74
- tools/test/test_sre_checkpoints.py +0 -79
@@ -1,519 +0,0 @@
|
|
1
|
-
from collections.abc import (
|
2
|
-
Callable,
|
3
|
-
Iterable,
|
4
|
-
Mapping,
|
5
|
-
)
|
6
|
-
from typing import Any
|
7
|
-
from unittest.mock import MagicMock, create_autospec
|
8
|
-
|
9
|
-
import pytest
|
10
|
-
from pytest_mock import MockerFixture
|
11
|
-
|
12
|
-
import reconcile.terraform_resources as integ
|
13
|
-
from reconcile.gql_definitions.terraform_resources.terraform_resources_namespaces import (
|
14
|
-
NamespaceV1,
|
15
|
-
)
|
16
|
-
from reconcile.utils.secret_reader import SecretReaderBase
|
17
|
-
|
18
|
-
|
19
|
-
def test_cannot_use_exclude_accounts_if_not_dry_run():
|
20
|
-
with pytest.raises(integ.ExcludeAccountsAndDryRunException) as excinfo:
|
21
|
-
integ.run(False, exclude_accounts=("a", "b"))
|
22
|
-
|
23
|
-
assert "--exclude-accounts is only supported in dry-run mode" in str(excinfo.value)
|
24
|
-
|
25
|
-
|
26
|
-
def test_cannot_use_exclude_account_with_same_account_name():
|
27
|
-
with pytest.raises(integ.ExcludeAccountsAndAccountNameException) as excinfo:
|
28
|
-
integ.run(True, exclude_accounts=("a", "b"), account_name=("b", "c", "d"))
|
29
|
-
|
30
|
-
assert (
|
31
|
-
"Using --exclude-accounts and --account-name with the same account is not allowed"
|
32
|
-
in str(excinfo.value)
|
33
|
-
)
|
34
|
-
|
35
|
-
|
36
|
-
def test_cannot_exclude_invalid_aws_account(mocker):
|
37
|
-
mocker.patch(
|
38
|
-
"reconcile.queries.get_aws_accounts",
|
39
|
-
return_value=[{"name": "a"}],
|
40
|
-
autospec=True,
|
41
|
-
)
|
42
|
-
with pytest.raises(ValueError) as excinfo:
|
43
|
-
integ.run(True, exclude_accounts=("b"))
|
44
|
-
|
45
|
-
assert (
|
46
|
-
"Accounts {'b'} were provided as arguments, but not found in app-interface. Check your input for typos or for missing AWS account definitions."
|
47
|
-
in str(excinfo.value)
|
48
|
-
)
|
49
|
-
|
50
|
-
|
51
|
-
def test_cannot_exclude_all_accounts(mocker):
|
52
|
-
mocker.patch(
|
53
|
-
"reconcile.queries.get_aws_accounts",
|
54
|
-
return_value=[{"name": "a"}, {"name": "b"}],
|
55
|
-
autospec=True,
|
56
|
-
)
|
57
|
-
|
58
|
-
with pytest.raises(ValueError) as excinfo:
|
59
|
-
integ.run(True, exclude_accounts=("a", "b"))
|
60
|
-
|
61
|
-
assert "You have excluded all aws accounts, verify your input" in str(excinfo.value)
|
62
|
-
|
63
|
-
|
64
|
-
def test_cannot_pass_two_aws_account_if_not_dry_run():
|
65
|
-
with pytest.raises(integ.MultipleAccountNamesInDryRunException) as excinfo:
|
66
|
-
integ.run(False, account_name=("a", "b"))
|
67
|
-
|
68
|
-
assert "Running with multiple accounts is only supported in dry-run mode" in str(
|
69
|
-
excinfo.value
|
70
|
-
)
|
71
|
-
|
72
|
-
|
73
|
-
def test_filter_accounts_by_name():
|
74
|
-
accounts = [{"name": "a"}, {"name": "b"}, {"name": "c"}]
|
75
|
-
|
76
|
-
filtered = integ.filter_accounts_by_name(accounts, names=("a", "b"))
|
77
|
-
|
78
|
-
assert filtered == [{"name": "a"}, {"name": "b"}]
|
79
|
-
|
80
|
-
|
81
|
-
def test_exclude_accounts_by_name():
|
82
|
-
accounts = [{"name": "a"}, {"name": "b"}, {"name": "c"}]
|
83
|
-
|
84
|
-
filtered = integ.exclude_accounts_by_name(accounts, names=("a", "b"))
|
85
|
-
|
86
|
-
assert filtered == [{"name": "c"}]
|
87
|
-
|
88
|
-
|
89
|
-
def test_cannot_pass_invalid_aws_account(mocker):
|
90
|
-
mocker.patch(
|
91
|
-
"reconcile.queries.get_aws_accounts",
|
92
|
-
return_value=[{"name": "a"}],
|
93
|
-
autospec=True,
|
94
|
-
)
|
95
|
-
with pytest.raises(ValueError) as excinfo:
|
96
|
-
integ.run(True, account_name=("a", "b"))
|
97
|
-
|
98
|
-
assert (
|
99
|
-
"Accounts {'b'} were provided as arguments, but not found in app-interface. Check your input for typos or for missing AWS account definitions."
|
100
|
-
in str(excinfo.value)
|
101
|
-
)
|
102
|
-
|
103
|
-
|
104
|
-
def namespace_dict(
|
105
|
-
name: str,
|
106
|
-
external_resources: Iterable[Mapping[str, Any]],
|
107
|
-
managed: bool = True,
|
108
|
-
delete: bool = False,
|
109
|
-
) -> dict[str, Any]:
|
110
|
-
data = {
|
111
|
-
"name": name,
|
112
|
-
"managedExternalResources": managed,
|
113
|
-
"externalResources": external_resources,
|
114
|
-
"cluster": {"name": "c", "serverUrl": "test"},
|
115
|
-
"app": {"name": "test"},
|
116
|
-
"environment": {"name": "test"},
|
117
|
-
}
|
118
|
-
if delete:
|
119
|
-
data["delete"] = True
|
120
|
-
return data
|
121
|
-
|
122
|
-
|
123
|
-
def test_filter_namespaces_no_managed_tf_resources(gql_class_factory: Callable):
|
124
|
-
ra = {"identifier": "a", "provider": "p"}
|
125
|
-
ns1 = gql_class_factory(NamespaceV1, namespace_dict("ns1", [], managed=False))
|
126
|
-
ns2 = gql_class_factory(
|
127
|
-
NamespaceV1,
|
128
|
-
namespace_dict(
|
129
|
-
"ns2",
|
130
|
-
[{"provider": "aws", "provisioner": {"name": "a"}, "resources": [ra]}],
|
131
|
-
),
|
132
|
-
)
|
133
|
-
namespaces = [ns1, ns2]
|
134
|
-
filtered = integ.filter_tf_namespaces(namespaces, None)
|
135
|
-
assert filtered == [ns2]
|
136
|
-
|
137
|
-
|
138
|
-
def test_filter_namespaces_with_accounts_filter(gql_class_factory: Callable):
|
139
|
-
ra = {"identifier": "a", "provider": "p"}
|
140
|
-
rb = {"identifier": "b", "provider": "p"}
|
141
|
-
rc = {"identifier": "c", "provider": "p"}
|
142
|
-
ns1 = gql_class_factory(
|
143
|
-
NamespaceV1,
|
144
|
-
namespace_dict(
|
145
|
-
"ns1",
|
146
|
-
[{"provider": "aws", "provisioner": {"name": "a"}, "resources": [ra]}],
|
147
|
-
),
|
148
|
-
)
|
149
|
-
ns2 = gql_class_factory(
|
150
|
-
NamespaceV1,
|
151
|
-
namespace_dict(
|
152
|
-
"ns2",
|
153
|
-
[{"provider": "aws", "provisioner": {"name": "b"}, "resources": [rb]}],
|
154
|
-
),
|
155
|
-
)
|
156
|
-
ns3 = gql_class_factory(
|
157
|
-
NamespaceV1,
|
158
|
-
namespace_dict(
|
159
|
-
"ns3",
|
160
|
-
[{"provider": "aws", "provisioner": {"name": "c"}, "resources": [rc]}],
|
161
|
-
),
|
162
|
-
)
|
163
|
-
|
164
|
-
namespaces = [ns1, ns2, ns3]
|
165
|
-
filtered = integ.filter_tf_namespaces(namespaces, ("a", "b"))
|
166
|
-
assert filtered == [ns1, ns2]
|
167
|
-
|
168
|
-
|
169
|
-
def test_filter_namespaces_no_accounts_filter(gql_class_factory: Callable):
|
170
|
-
ra = {"identifier": "a", "provider": "p"}
|
171
|
-
rb = {"identifier": "b", "provider": "p"}
|
172
|
-
ns1 = gql_class_factory(
|
173
|
-
NamespaceV1,
|
174
|
-
namespace_dict(
|
175
|
-
"ns1",
|
176
|
-
[{"provider": "aws", "provisioner": {"name": "a"}, "resources": [ra]}],
|
177
|
-
),
|
178
|
-
)
|
179
|
-
ns2 = gql_class_factory(
|
180
|
-
NamespaceV1,
|
181
|
-
namespace_dict(
|
182
|
-
"ns2",
|
183
|
-
[{"provider": "aws", "provisioner": {"name": "b"}, "resources": [rb]}],
|
184
|
-
),
|
185
|
-
)
|
186
|
-
namespaces = [ns1, ns2]
|
187
|
-
filtered = integ.filter_tf_namespaces(namespaces, None)
|
188
|
-
assert filtered == namespaces
|
189
|
-
|
190
|
-
|
191
|
-
def test_filter_namespaces_no_tf_resources_no_accounts_filter(
|
192
|
-
gql_class_factory: Callable,
|
193
|
-
):
|
194
|
-
"""
|
195
|
-
this test makes sure that a namespace is returned even if it has no resources
|
196
|
-
attached. this way we can delete the last terraform resources that might have been
|
197
|
-
defined on the namespace previously
|
198
|
-
"""
|
199
|
-
ra = {"identifier": "a", "provider": "p"}
|
200
|
-
ns1 = gql_class_factory(NamespaceV1, namespace_dict("ns1", [], managed=True))
|
201
|
-
ns2 = gql_class_factory(
|
202
|
-
NamespaceV1,
|
203
|
-
namespace_dict(
|
204
|
-
"ns2",
|
205
|
-
[{"provider": "aws", "provisioner": {"name": "a"}, "resources": [ra]}],
|
206
|
-
),
|
207
|
-
)
|
208
|
-
|
209
|
-
namespaces = [ns1, ns2]
|
210
|
-
filtered = integ.filter_tf_namespaces(namespaces, None)
|
211
|
-
assert filtered == [ns1, ns2]
|
212
|
-
|
213
|
-
|
214
|
-
def test_filter_tf_namespaces_no_tf_resources_with_accounts_filter(
|
215
|
-
gql_class_factory: Callable,
|
216
|
-
):
|
217
|
-
"""
|
218
|
-
even if an account filter is defined, a namespace without resources is returned
|
219
|
-
to enable terraform resource deletion. in contrast to that, a namespace with a resource
|
220
|
-
that does not match the account will not be returned.
|
221
|
-
"""
|
222
|
-
ra = {"identifier": "a", "provider": "p"}
|
223
|
-
ns1 = gql_class_factory(NamespaceV1, namespace_dict("ns1", [], managed=True))
|
224
|
-
ns2 = gql_class_factory(
|
225
|
-
NamespaceV1,
|
226
|
-
namespace_dict(
|
227
|
-
"ns2",
|
228
|
-
[{"provider": "aws", "provisioner": {"name": "a"}, "resources": [ra]}],
|
229
|
-
),
|
230
|
-
)
|
231
|
-
namespaces = [ns1, ns2]
|
232
|
-
filtered = integ.filter_tf_namespaces(namespaces, ["b"])
|
233
|
-
assert filtered == [ns1]
|
234
|
-
|
235
|
-
|
236
|
-
def test_filter_tf_namespaces_namespace_deleted(gql_class_factory: Callable):
|
237
|
-
"""
|
238
|
-
test that a deleted namespace is not returned
|
239
|
-
"""
|
240
|
-
ra = {"identifier": "a", "provider": "p"}
|
241
|
-
rb = {"identifier": "b", "provider": "p"}
|
242
|
-
ns1 = gql_class_factory(
|
243
|
-
NamespaceV1,
|
244
|
-
namespace_dict(
|
245
|
-
"ns1",
|
246
|
-
[{"provider": "aws", "provisioner": {"name": "a"}, "resources": [ra]}],
|
247
|
-
delete=True,
|
248
|
-
),
|
249
|
-
)
|
250
|
-
ns2 = gql_class_factory(
|
251
|
-
NamespaceV1,
|
252
|
-
namespace_dict(
|
253
|
-
"ns1",
|
254
|
-
[{"provider": "aws", "provisioner": {"name": "b"}, "resources": [rb]}],
|
255
|
-
),
|
256
|
-
)
|
257
|
-
|
258
|
-
namespaces = [ns1, ns2]
|
259
|
-
filtered = integ.filter_tf_namespaces(namespaces, None)
|
260
|
-
assert filtered == [ns2]
|
261
|
-
|
262
|
-
|
263
|
-
def setup_mocks(
|
264
|
-
mocker: MockerFixture,
|
265
|
-
secret_reader: SecretReaderBase,
|
266
|
-
aws_accounts: list[dict[str, Any]],
|
267
|
-
tf_namespaces: list[NamespaceV1],
|
268
|
-
feature_toggle_state: bool = True,
|
269
|
-
) -> dict[str, Any]:
|
270
|
-
mocked_queries = mocker.patch("reconcile.terraform_resources.queries")
|
271
|
-
mocked_queries.get_aws_accounts.return_value = aws_accounts
|
272
|
-
mocked_queries.get_app_interface_settings.return_value = []
|
273
|
-
|
274
|
-
mocker.patch(
|
275
|
-
"reconcile.terraform_resources.get_namespaces"
|
276
|
-
).return_value = tf_namespaces
|
277
|
-
|
278
|
-
mocked_ts = mocker.patch(
|
279
|
-
"reconcile.terraform_resources.Terrascript", autospec=True
|
280
|
-
).return_value
|
281
|
-
mocked_ts.resource_spec_inventory = {}
|
282
|
-
|
283
|
-
mocked_tf = mocker.patch(
|
284
|
-
"reconcile.terraform_resources.Terraform", autospec=True
|
285
|
-
).return_value
|
286
|
-
mocked_tf.plan.return_value = (False, None)
|
287
|
-
mocked_tf.should_apply.return_value = False
|
288
|
-
|
289
|
-
mocker.patch("reconcile.terraform_resources.AWSApi", autospec=True)
|
290
|
-
|
291
|
-
mocked_logging = mocker.patch("reconcile.terraform_resources.logging")
|
292
|
-
|
293
|
-
mocker.patch("reconcile.terraform_resources.get_app_interface_vault_settings")
|
294
|
-
|
295
|
-
mocker.patch(
|
296
|
-
"reconcile.terraform_resources.create_secret_reader",
|
297
|
-
return_value=secret_reader,
|
298
|
-
)
|
299
|
-
|
300
|
-
mock_extended_early_exit_run = mocker.patch(
|
301
|
-
"reconcile.terraform_resources.extended_early_exit_run"
|
302
|
-
)
|
303
|
-
|
304
|
-
get_feature_toggle_state = mocker.patch(
|
305
|
-
"reconcile.terraform_resources.get_feature_toggle_state",
|
306
|
-
return_value=feature_toggle_state,
|
307
|
-
)
|
308
|
-
|
309
|
-
return {
|
310
|
-
"queries": mocked_queries,
|
311
|
-
"ts": mocked_ts,
|
312
|
-
"tf": mocked_tf,
|
313
|
-
"logging": mocked_logging,
|
314
|
-
"extended_early_exit_run": mock_extended_early_exit_run,
|
315
|
-
"get_feature_toggle_state": get_feature_toggle_state,
|
316
|
-
}
|
317
|
-
|
318
|
-
|
319
|
-
def test_empty_run(
|
320
|
-
mocker: MockerFixture,
|
321
|
-
secret_reader: SecretReaderBase,
|
322
|
-
) -> None:
|
323
|
-
mocks = setup_mocks(
|
324
|
-
mocker,
|
325
|
-
secret_reader,
|
326
|
-
aws_accounts=[{"name": "a"}],
|
327
|
-
tf_namespaces=[],
|
328
|
-
)
|
329
|
-
|
330
|
-
integ.run(True, account_name="a")
|
331
|
-
|
332
|
-
mocks["logging"].warning.assert_called_once_with(
|
333
|
-
"No terraform namespaces found, consider disabling this integration, account names: a"
|
334
|
-
)
|
335
|
-
|
336
|
-
|
337
|
-
def test_run_with_extended_early_exit_run_enabled(
|
338
|
-
mocker: MockerFixture,
|
339
|
-
secret_reader: SecretReaderBase,
|
340
|
-
) -> None:
|
341
|
-
mocks = setup_mocks(
|
342
|
-
mocker,
|
343
|
-
secret_reader,
|
344
|
-
aws_accounts=[{"name": "a"}],
|
345
|
-
tf_namespaces=[],
|
346
|
-
)
|
347
|
-
defer = MagicMock()
|
348
|
-
expected_runner_params = integ.RunnerParams(
|
349
|
-
accounts=[{"name": "a"}],
|
350
|
-
account_names={"a"},
|
351
|
-
tf_namespaces=[],
|
352
|
-
tf=mocks["tf"],
|
353
|
-
ts=mocks["ts"],
|
354
|
-
secret_reader=secret_reader,
|
355
|
-
dry_run=True,
|
356
|
-
enable_deletion=False,
|
357
|
-
thread_pool_size=10,
|
358
|
-
internal=None,
|
359
|
-
use_jump_host=True,
|
360
|
-
light=False,
|
361
|
-
vault_output_path="",
|
362
|
-
defer=defer,
|
363
|
-
)
|
364
|
-
|
365
|
-
integ.run.__wrapped__(
|
366
|
-
True,
|
367
|
-
account_name="a",
|
368
|
-
enable_extended_early_exit=True,
|
369
|
-
extended_early_exit_cache_ttl_seconds=60,
|
370
|
-
log_cached_log_output=True,
|
371
|
-
defer=defer,
|
372
|
-
)
|
373
|
-
expected_cache_source = {
|
374
|
-
"terraform_configurations": mocks["ts"].terraform_configurations.return_value,
|
375
|
-
"resource_spec_inventory": mocks["ts"].resource_spec_inventory,
|
376
|
-
}
|
377
|
-
|
378
|
-
mocks["extended_early_exit_run"].assert_called_once_with(
|
379
|
-
integration=integ.QONTRACT_INTEGRATION,
|
380
|
-
integration_version=integ.QONTRACT_INTEGRATION_VERSION,
|
381
|
-
dry_run=True,
|
382
|
-
cache_source=expected_cache_source,
|
383
|
-
shard="a",
|
384
|
-
ttl_seconds=60,
|
385
|
-
logger=mocks["logging"].getLogger.return_value,
|
386
|
-
runner=integ.runner,
|
387
|
-
runner_params=expected_runner_params,
|
388
|
-
secret_reader=secret_reader,
|
389
|
-
log_cached_log_output=True,
|
390
|
-
)
|
391
|
-
|
392
|
-
|
393
|
-
def test_run_with_extended_early_exit_run_disabled(
|
394
|
-
mocker: MockerFixture,
|
395
|
-
secret_reader: SecretReaderBase,
|
396
|
-
) -> None:
|
397
|
-
mocks = setup_mocks(
|
398
|
-
mocker,
|
399
|
-
secret_reader,
|
400
|
-
aws_accounts=[{"name": "a"}],
|
401
|
-
tf_namespaces=[],
|
402
|
-
)
|
403
|
-
|
404
|
-
integ.run(
|
405
|
-
True,
|
406
|
-
account_name="a",
|
407
|
-
enable_extended_early_exit=False,
|
408
|
-
)
|
409
|
-
|
410
|
-
mocks["extended_early_exit_run"].assert_not_called()
|
411
|
-
mocks["tf"].plan.assert_called_once_with(False)
|
412
|
-
|
413
|
-
|
414
|
-
def test_run_with_extended_early_exit_run_feature_disabled(
|
415
|
-
mocker: MockerFixture,
|
416
|
-
secret_reader: SecretReaderBase,
|
417
|
-
) -> None:
|
418
|
-
mocks = setup_mocks(
|
419
|
-
mocker,
|
420
|
-
secret_reader,
|
421
|
-
aws_accounts=[{"name": "a"}],
|
422
|
-
tf_namespaces=[],
|
423
|
-
feature_toggle_state=False,
|
424
|
-
)
|
425
|
-
|
426
|
-
integ.run(
|
427
|
-
True,
|
428
|
-
account_name="a",
|
429
|
-
enable_extended_early_exit=True,
|
430
|
-
)
|
431
|
-
|
432
|
-
mocks["extended_early_exit_run"].assert_not_called()
|
433
|
-
mocks["tf"].plan.assert_called_once_with(False)
|
434
|
-
mocks["get_feature_toggle_state"].assert_called_once_with(
|
435
|
-
"terraform-resources-extended-early-exit",
|
436
|
-
default=False,
|
437
|
-
)
|
438
|
-
|
439
|
-
|
440
|
-
def test_terraform_resources_runner_dry_run(
|
441
|
-
secret_reader: SecretReaderBase,
|
442
|
-
) -> None:
|
443
|
-
tf = create_autospec(integ.Terraform)
|
444
|
-
tf.plan.return_value = (False, None)
|
445
|
-
|
446
|
-
ts = create_autospec(integ.Terrascript)
|
447
|
-
terraform_configurations = {"a": "b"}
|
448
|
-
ts.terraform_configurations.return_value = terraform_configurations
|
449
|
-
|
450
|
-
defer = MagicMock()
|
451
|
-
|
452
|
-
runner_params = {
|
453
|
-
"accounts": [{"name": "a"}],
|
454
|
-
"account_names": {"a"},
|
455
|
-
"tf_namespaces": [],
|
456
|
-
"tf": tf,
|
457
|
-
"ts": ts,
|
458
|
-
"secret_reader": secret_reader,
|
459
|
-
"dry_run": True,
|
460
|
-
"enable_deletion": False,
|
461
|
-
"thread_pool_size": 10,
|
462
|
-
"internal": None,
|
463
|
-
"use_jump_host": True,
|
464
|
-
"light": False,
|
465
|
-
"vault_output_path": "",
|
466
|
-
"defer": defer,
|
467
|
-
}
|
468
|
-
|
469
|
-
result = integ.runner(**runner_params)
|
470
|
-
|
471
|
-
assert result == integ.ExtendedEarlyExitRunnerResult(
|
472
|
-
payload=terraform_configurations,
|
473
|
-
applied_count=0,
|
474
|
-
)
|
475
|
-
|
476
|
-
|
477
|
-
def test_terraform_resources_runner_no_dry_run(
|
478
|
-
mocker: MockerFixture,
|
479
|
-
secret_reader: SecretReaderBase,
|
480
|
-
) -> None:
|
481
|
-
tf = create_autospec(integ.Terraform)
|
482
|
-
tf.plan.return_value = (False, None)
|
483
|
-
tf.apply_count = 1
|
484
|
-
tf.should_apply.return_value = True
|
485
|
-
tf.apply.return_value = False
|
486
|
-
|
487
|
-
ts = create_autospec(integ.Terrascript)
|
488
|
-
terraform_configurations = {"a": "b"}
|
489
|
-
ts.terraform_configurations.return_value = terraform_configurations
|
490
|
-
ts.resource_spec_inventory = {}
|
491
|
-
|
492
|
-
defer = MagicMock()
|
493
|
-
|
494
|
-
mocked_ob = mocker.patch("reconcile.terraform_resources.ob")
|
495
|
-
mocked_ob.realize_data.return_value = [{"action": "applied"}]
|
496
|
-
|
497
|
-
runner_params = {
|
498
|
-
"accounts": [{"name": "a"}],
|
499
|
-
"account_names": {"a"},
|
500
|
-
"tf_namespaces": [],
|
501
|
-
"tf": tf,
|
502
|
-
"ts": ts,
|
503
|
-
"secret_reader": secret_reader,
|
504
|
-
"dry_run": False,
|
505
|
-
"enable_deletion": False,
|
506
|
-
"thread_pool_size": 10,
|
507
|
-
"internal": None,
|
508
|
-
"use_jump_host": True,
|
509
|
-
"light": False,
|
510
|
-
"vault_output_path": "",
|
511
|
-
"defer": defer,
|
512
|
-
}
|
513
|
-
|
514
|
-
result = integ.runner(**runner_params)
|
515
|
-
|
516
|
-
assert result == integ.ExtendedEarlyExitRunnerResult(
|
517
|
-
payload=terraform_configurations,
|
518
|
-
applied_count=2,
|
519
|
-
)
|