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
reconcile/test/test_sql_query.py
DELETED
@@ -1,316 +0,0 @@
|
|
1
|
-
from collections.abc import Callable
|
2
|
-
from unittest.mock import create_autospec
|
3
|
-
|
4
|
-
import pytest
|
5
|
-
from pytest_mock import MockFixture
|
6
|
-
|
7
|
-
import reconcile.sql_query as intg
|
8
|
-
from reconcile.gql_definitions.common.smtp_client_settings import SmtpSettingsV1
|
9
|
-
from reconcile.sql_query import split_long_query
|
10
|
-
from reconcile.utils.oc import OCCli
|
11
|
-
from reconcile.utils.openshift_resource import ResourceInventory
|
12
|
-
from reconcile.utils.state import State
|
13
|
-
|
14
|
-
|
15
|
-
@pytest.mark.parametrize(
|
16
|
-
"q, size, expected",
|
17
|
-
[
|
18
|
-
("test", 1, ["t", "e", "s", "t"]),
|
19
|
-
(
|
20
|
-
"this is a longer string",
|
21
|
-
3,
|
22
|
-
["thi", "s i", "s a", " lo", "nge", "r s", "tri", "ng"],
|
23
|
-
),
|
24
|
-
("testtest", 100, ["testtest"]),
|
25
|
-
],
|
26
|
-
)
|
27
|
-
def test_split_long_query(q, size, expected):
|
28
|
-
assert split_long_query(q, size) == expected
|
29
|
-
|
30
|
-
|
31
|
-
@pytest.fixture
|
32
|
-
def smtp_settings(
|
33
|
-
gql_class_factory: Callable[..., SmtpSettingsV1],
|
34
|
-
) -> SmtpSettingsV1:
|
35
|
-
return gql_class_factory(
|
36
|
-
SmtpSettingsV1,
|
37
|
-
{
|
38
|
-
"mailAddress": "some_address",
|
39
|
-
"timeout": 30,
|
40
|
-
"credentials": {
|
41
|
-
"path": "some-path",
|
42
|
-
},
|
43
|
-
},
|
44
|
-
)
|
45
|
-
|
46
|
-
|
47
|
-
@pytest.fixture
|
48
|
-
def smtp_server_connection_info() -> dict:
|
49
|
-
return {
|
50
|
-
"server": "some-host",
|
51
|
-
"port": 1234,
|
52
|
-
"username": "some-username",
|
53
|
-
"password": "some-password",
|
54
|
-
}
|
55
|
-
|
56
|
-
|
57
|
-
@pytest.fixture
|
58
|
-
def sql_query() -> dict:
|
59
|
-
return {
|
60
|
-
"name": "some-query",
|
61
|
-
"delete": None,
|
62
|
-
"identifier": "rds-id",
|
63
|
-
"query": None,
|
64
|
-
"queries": ["SELECT * FROM table;"],
|
65
|
-
"namespace": {
|
66
|
-
"name": "some-namespace",
|
67
|
-
"managedExternalResources": True,
|
68
|
-
"externalResources": [
|
69
|
-
{
|
70
|
-
"provider": "aws",
|
71
|
-
"provisioner": {
|
72
|
-
"name": "some-provisioner",
|
73
|
-
},
|
74
|
-
"resources": [
|
75
|
-
{
|
76
|
-
"provider": "rds",
|
77
|
-
"identifier": "rds-id",
|
78
|
-
}
|
79
|
-
],
|
80
|
-
}
|
81
|
-
],
|
82
|
-
"app": {
|
83
|
-
"name": "some-app",
|
84
|
-
},
|
85
|
-
"environment": {
|
86
|
-
"name": "some-env",
|
87
|
-
},
|
88
|
-
"cluster": {
|
89
|
-
"name": "some-cluster",
|
90
|
-
},
|
91
|
-
},
|
92
|
-
"overrides": None,
|
93
|
-
"output": "stdout",
|
94
|
-
}
|
95
|
-
|
96
|
-
|
97
|
-
def setup_mocks(
|
98
|
-
mocker: MockFixture,
|
99
|
-
smtp_settings: SmtpSettingsV1,
|
100
|
-
smtp_server_connection_info: dict,
|
101
|
-
sql_query: dict,
|
102
|
-
state: dict,
|
103
|
-
time: float = 0.0,
|
104
|
-
current_items: dict[str, list[str]] | None = None,
|
105
|
-
) -> dict:
|
106
|
-
mocked_queries = mocker.patch("reconcile.sql_query.queries")
|
107
|
-
mocked_queries.get_app_interface_settings.return_value = {}
|
108
|
-
mocked_queries.get_app_interface_sql_queries.return_value = [sql_query]
|
109
|
-
mocked_state = create_autospec(State)
|
110
|
-
mocked_state.ls.return_value = [f"/{k}" for k in state]
|
111
|
-
mocked_state.__getitem__.side_effect = lambda x: state[x]
|
112
|
-
mocked_secret_reader = mocker.patch("reconcile.sql_query.SecretReader")
|
113
|
-
mocked_secret_reader.return_value.read_all_secret.return_value = (
|
114
|
-
smtp_server_connection_info
|
115
|
-
)
|
116
|
-
mocker.patch("reconcile.sql_query.init_state", return_value=mocked_state)
|
117
|
-
mocker.patch(
|
118
|
-
"reconcile.sql_query.typed_queries.smtp.settings", return_value=smtp_settings
|
119
|
-
)
|
120
|
-
mocked_ts = mocker.patch("reconcile.sql_query.Terrascript")
|
121
|
-
mocked_ts.return_value.init_values.return_value = {}
|
122
|
-
mocked_ob = mocker.patch("reconcile.sql_query.openshift_base")
|
123
|
-
|
124
|
-
mocked_oc_map = mocker.patch("reconcile.sql_query.OC_Map", autospec=True)
|
125
|
-
mocked_oc_client = create_autospec(OCCli)
|
126
|
-
mocked_oc_client.get_items.side_effect = lambda kind, **_: [
|
127
|
-
{"kind": kind, "metadata": {"name": name}}
|
128
|
-
for name in (current_items or {}).get(kind, [])
|
129
|
-
]
|
130
|
-
mocked_oc_map.return_value.__enter__.return_value.get_cluster.return_value = (
|
131
|
-
mocked_oc_client
|
132
|
-
)
|
133
|
-
|
134
|
-
mocked_time = mocker.patch("reconcile.sql_query.time")
|
135
|
-
mocked_time.time.return_value = time
|
136
|
-
|
137
|
-
return {
|
138
|
-
"mocked_queries": mocked_queries,
|
139
|
-
"mocked_state": mocked_state,
|
140
|
-
"mocked_ob": mocked_ob,
|
141
|
-
}
|
142
|
-
|
143
|
-
|
144
|
-
def _verify_publish_metrics(
|
145
|
-
ri: ResourceInventory,
|
146
|
-
integration: str,
|
147
|
-
expected_metrics: dict[tuple[str, str, str, str], int],
|
148
|
-
) -> None:
|
149
|
-
assert integration == "sql-query"
|
150
|
-
metrics = {
|
151
|
-
(cluster, namespace, kind, state): len(data[state])
|
152
|
-
for cluster, namespace, kind, data in ri
|
153
|
-
for state in ("current", "desired")
|
154
|
-
}
|
155
|
-
assert expected_metrics == metrics
|
156
|
-
|
157
|
-
|
158
|
-
def test_run_with_new_sql_query(
|
159
|
-
mocker: MockFixture,
|
160
|
-
smtp_settings: SmtpSettingsV1,
|
161
|
-
smtp_server_connection_info: dict,
|
162
|
-
sql_query: dict,
|
163
|
-
) -> None:
|
164
|
-
mocks = setup_mocks(
|
165
|
-
mocker=mocker,
|
166
|
-
smtp_settings=smtp_settings,
|
167
|
-
smtp_server_connection_info=smtp_server_connection_info,
|
168
|
-
sql_query=sql_query,
|
169
|
-
state={},
|
170
|
-
)
|
171
|
-
|
172
|
-
intg.run(False)
|
173
|
-
|
174
|
-
mocks["mocked_ob"].apply.assert_called()
|
175
|
-
assert mocks["mocked_ob"].apply.call_count == 4
|
176
|
-
mocks["mocked_ob"].delete.assert_not_called()
|
177
|
-
|
178
|
-
mocks["mocked_ob"].publish_metrics.assert_called_once()
|
179
|
-
ri, integration = mocks["mocked_ob"].publish_metrics.call_args[0]
|
180
|
-
expected_metrics = {
|
181
|
-
("some-cluster", "some-namespace", "ConfigMap", "current"): 0,
|
182
|
-
("some-cluster", "some-namespace", "ConfigMap", "desired"): 2,
|
183
|
-
("some-cluster", "some-namespace", "ServiceAccount", "current"): 0,
|
184
|
-
("some-cluster", "some-namespace", "ServiceAccount", "desired"): 1,
|
185
|
-
("some-cluster", "some-namespace", "Job", "current"): 0,
|
186
|
-
("some-cluster", "some-namespace", "Job", "desired"): 1,
|
187
|
-
("some-cluster", "some-namespace", "CronJob", "current"): 0,
|
188
|
-
("some-cluster", "some-namespace", "CronJob", "desired"): 0,
|
189
|
-
("some-cluster", "some-namespace", "Secret", "current"): 0,
|
190
|
-
("some-cluster", "some-namespace", "Secret", "desired"): 0,
|
191
|
-
}
|
192
|
-
_verify_publish_metrics(ri, integration, expected_metrics)
|
193
|
-
|
194
|
-
|
195
|
-
def test_run_with_deleted_sql_query(
|
196
|
-
mocker: MockFixture,
|
197
|
-
smtp_settings: SmtpSettingsV1,
|
198
|
-
smtp_server_connection_info: dict,
|
199
|
-
sql_query: dict,
|
200
|
-
) -> None:
|
201
|
-
mocks = setup_mocks(
|
202
|
-
mocker=mocker,
|
203
|
-
smtp_settings=smtp_settings,
|
204
|
-
smtp_server_connection_info=smtp_server_connection_info,
|
205
|
-
sql_query=sql_query,
|
206
|
-
state={"some-query": "DONE"},
|
207
|
-
)
|
208
|
-
|
209
|
-
intg.run(False)
|
210
|
-
|
211
|
-
mocks["mocked_ob"].apply.assert_not_called()
|
212
|
-
mocks["mocked_ob"].delete.assert_not_called()
|
213
|
-
|
214
|
-
mocks["mocked_ob"].publish_metrics.assert_called_once()
|
215
|
-
ri, integration = mocks["mocked_ob"].publish_metrics.call_args[0]
|
216
|
-
expected_metrics = {
|
217
|
-
("some-cluster", "some-namespace", "ConfigMap", "current"): 0,
|
218
|
-
("some-cluster", "some-namespace", "ConfigMap", "desired"): 0,
|
219
|
-
("some-cluster", "some-namespace", "ServiceAccount", "current"): 0,
|
220
|
-
("some-cluster", "some-namespace", "ServiceAccount", "desired"): 0,
|
221
|
-
("some-cluster", "some-namespace", "Job", "current"): 0,
|
222
|
-
("some-cluster", "some-namespace", "Job", "desired"): 0,
|
223
|
-
("some-cluster", "some-namespace", "CronJob", "current"): 0,
|
224
|
-
("some-cluster", "some-namespace", "CronJob", "desired"): 0,
|
225
|
-
("some-cluster", "some-namespace", "Secret", "current"): 0,
|
226
|
-
("some-cluster", "some-namespace", "Secret", "desired"): 0,
|
227
|
-
}
|
228
|
-
_verify_publish_metrics(ri, integration, expected_metrics)
|
229
|
-
|
230
|
-
|
231
|
-
@pytest.fixture
|
232
|
-
def current_items() -> dict[str, list[str]]:
|
233
|
-
return {
|
234
|
-
"ConfigMap": ["some-query-gpg-key", "some-query-q00000c00000"],
|
235
|
-
"ServiceAccount": ["some-query"],
|
236
|
-
"Job": ["some-query"],
|
237
|
-
}
|
238
|
-
|
239
|
-
|
240
|
-
def test_run_with_pending_deletion_sql_query(
|
241
|
-
mocker: MockFixture,
|
242
|
-
smtp_settings: SmtpSettingsV1,
|
243
|
-
smtp_server_connection_info: dict,
|
244
|
-
sql_query: dict,
|
245
|
-
current_items: dict[str, list[str]],
|
246
|
-
) -> None:
|
247
|
-
mocks = setup_mocks(
|
248
|
-
mocker=mocker,
|
249
|
-
smtp_settings=smtp_settings,
|
250
|
-
smtp_server_connection_info=smtp_server_connection_info,
|
251
|
-
sql_query=sql_query,
|
252
|
-
state={"some-query": 0},
|
253
|
-
time=604800.0,
|
254
|
-
current_items=current_items,
|
255
|
-
)
|
256
|
-
|
257
|
-
intg.run(False, enable_deletion=True)
|
258
|
-
|
259
|
-
mocks["mocked_ob"].apply.assert_not_called()
|
260
|
-
mocks["mocked_ob"].delete.assert_called()
|
261
|
-
assert mocks["mocked_ob"].delete.call_count == 4
|
262
|
-
mocks["mocked_state"].__setitem__.assert_called_once_with("some-query", "DONE")
|
263
|
-
|
264
|
-
mocks["mocked_ob"].publish_metrics.assert_called_once()
|
265
|
-
ri, integration = mocks["mocked_ob"].publish_metrics.call_args[0]
|
266
|
-
expected_metrics = {
|
267
|
-
("some-cluster", "some-namespace", "ConfigMap", "current"): 2,
|
268
|
-
("some-cluster", "some-namespace", "ConfigMap", "desired"): 0,
|
269
|
-
("some-cluster", "some-namespace", "ServiceAccount", "current"): 1,
|
270
|
-
("some-cluster", "some-namespace", "ServiceAccount", "desired"): 0,
|
271
|
-
("some-cluster", "some-namespace", "Job", "current"): 1,
|
272
|
-
("some-cluster", "some-namespace", "Job", "desired"): 0,
|
273
|
-
("some-cluster", "some-namespace", "CronJob", "current"): 0,
|
274
|
-
("some-cluster", "some-namespace", "CronJob", "desired"): 0,
|
275
|
-
("some-cluster", "some-namespace", "Secret", "current"): 0,
|
276
|
-
("some-cluster", "some-namespace", "Secret", "desired"): 0,
|
277
|
-
}
|
278
|
-
_verify_publish_metrics(ri, integration, expected_metrics)
|
279
|
-
|
280
|
-
|
281
|
-
def test_run_with_active_sql_query(
|
282
|
-
mocker: MockFixture,
|
283
|
-
smtp_settings: SmtpSettingsV1,
|
284
|
-
smtp_server_connection_info: dict,
|
285
|
-
sql_query: dict,
|
286
|
-
current_items: dict[str, list[str]],
|
287
|
-
) -> None:
|
288
|
-
mocks = setup_mocks(
|
289
|
-
mocker=mocker,
|
290
|
-
smtp_settings=smtp_settings,
|
291
|
-
smtp_server_connection_info=smtp_server_connection_info,
|
292
|
-
sql_query=sql_query,
|
293
|
-
state={"some-query": 0},
|
294
|
-
time=604800.0 - 1,
|
295
|
-
)
|
296
|
-
|
297
|
-
intg.run(False, enable_deletion=True)
|
298
|
-
|
299
|
-
mocks["mocked_ob"].apply.assert_not_called()
|
300
|
-
mocks["mocked_ob"].delete.assert_not_called()
|
301
|
-
|
302
|
-
mocks["mocked_ob"].publish_metrics.assert_called_once()
|
303
|
-
ri, integration = mocks["mocked_ob"].publish_metrics.call_args[0]
|
304
|
-
expected_metrics = {
|
305
|
-
("some-cluster", "some-namespace", "ConfigMap", "current"): 2,
|
306
|
-
("some-cluster", "some-namespace", "ConfigMap", "desired"): 2,
|
307
|
-
("some-cluster", "some-namespace", "ServiceAccount", "current"): 1,
|
308
|
-
("some-cluster", "some-namespace", "ServiceAccount", "desired"): 1,
|
309
|
-
("some-cluster", "some-namespace", "Job", "current"): 1,
|
310
|
-
("some-cluster", "some-namespace", "Job", "desired"): 1,
|
311
|
-
("some-cluster", "some-namespace", "CronJob", "current"): 0,
|
312
|
-
("some-cluster", "some-namespace", "CronJob", "desired"): 0,
|
313
|
-
("some-cluster", "some-namespace", "Secret", "current"): 0,
|
314
|
-
("some-cluster", "some-namespace", "Secret", "desired"): 0,
|
315
|
-
}
|
316
|
-
_verify_publish_metrics(ri, integration, expected_metrics)
|
@@ -1,258 +0,0 @@
|
|
1
|
-
from collections.abc import Callable
|
2
|
-
from unittest.mock import call
|
3
|
-
|
4
|
-
import pytest
|
5
|
-
from pytest_mock import MockerFixture
|
6
|
-
|
7
|
-
from reconcile.gql_definitions.status_board.status_board import StatusBoardV1
|
8
|
-
from reconcile.status_board import (
|
9
|
-
AbstractStatusBoard,
|
10
|
-
Application,
|
11
|
-
Product,
|
12
|
-
StatusBoardExporterIntegration,
|
13
|
-
StatusBoardHandler,
|
14
|
-
)
|
15
|
-
from reconcile.utils.ocm_base_client import OCMBaseClient
|
16
|
-
|
17
|
-
|
18
|
-
class StatusBoardStub(AbstractStatusBoard):
|
19
|
-
created: bool | None = False
|
20
|
-
deleted: bool | None = False
|
21
|
-
summarized: bool | None = False
|
22
|
-
|
23
|
-
def create(self, ocm: OCMBaseClient) -> None:
|
24
|
-
self.created = True
|
25
|
-
|
26
|
-
def delete(self, ocm: OCMBaseClient) -> None:
|
27
|
-
self.deleted = True
|
28
|
-
|
29
|
-
def summarize(self) -> str:
|
30
|
-
self.summarized = True
|
31
|
-
return ""
|
32
|
-
|
33
|
-
@staticmethod
|
34
|
-
def get_priority() -> int:
|
35
|
-
return 0
|
36
|
-
|
37
|
-
|
38
|
-
@pytest.fixture
|
39
|
-
def status_board(gql_class_factory: Callable[..., StatusBoardV1]) -> StatusBoardV1:
|
40
|
-
return gql_class_factory(
|
41
|
-
StatusBoardV1,
|
42
|
-
{
|
43
|
-
"name": "foo",
|
44
|
-
"ocm": {
|
45
|
-
"url": "https://foo.com",
|
46
|
-
"accessTokenUrl": "foo",
|
47
|
-
"accessTokenClientId": "foo",
|
48
|
-
"accessTokenClientSecret": {
|
49
|
-
"path": "foo",
|
50
|
-
"field": "foo",
|
51
|
-
"version": "1",
|
52
|
-
"format": "foo",
|
53
|
-
},
|
54
|
-
},
|
55
|
-
"globalAppSelectors": {"exclude": ['apps[?@.name=="excluded"]']},
|
56
|
-
"products": [
|
57
|
-
{
|
58
|
-
"appSelectors": {
|
59
|
-
"exclude": ['apps[?@.onboardingStatus!="OnBoarded"]']
|
60
|
-
},
|
61
|
-
"productEnvironment": {
|
62
|
-
"name": "foo",
|
63
|
-
"labels": '{"foo": "foo"}',
|
64
|
-
"namespaces": [
|
65
|
-
{
|
66
|
-
"app": {
|
67
|
-
"name": "excluded",
|
68
|
-
"onboardingStatus": "OnBoarded",
|
69
|
-
}
|
70
|
-
},
|
71
|
-
{
|
72
|
-
"app": {
|
73
|
-
"name": "foo",
|
74
|
-
"onboardingStatus": "OnBoarded",
|
75
|
-
"childrenApps": [
|
76
|
-
{
|
77
|
-
"name": "bar",
|
78
|
-
"onboardingStatus": "OnBoarded",
|
79
|
-
},
|
80
|
-
],
|
81
|
-
}
|
82
|
-
},
|
83
|
-
{"app": {"name": "oof", "onboardingStatus": "BestEffort"}},
|
84
|
-
],
|
85
|
-
"product": {
|
86
|
-
"name": "foo",
|
87
|
-
},
|
88
|
-
},
|
89
|
-
}
|
90
|
-
],
|
91
|
-
},
|
92
|
-
)
|
93
|
-
|
94
|
-
|
95
|
-
def test_status_board_handler(mocker: MockerFixture) -> None:
|
96
|
-
ocm = mocker.patch("reconcile.status_board.OCMBaseClient")
|
97
|
-
h = StatusBoardHandler(
|
98
|
-
action="create",
|
99
|
-
status_board_object=StatusBoardStub(name="foo", fullname="foo"),
|
100
|
-
)
|
101
|
-
|
102
|
-
h.act(dry_run=False, ocm=ocm)
|
103
|
-
assert isinstance(h.status_board_object, StatusBoardStub)
|
104
|
-
assert h.status_board_object.created
|
105
|
-
assert h.status_board_object.summarized
|
106
|
-
|
107
|
-
h = StatusBoardHandler(
|
108
|
-
action="delete",
|
109
|
-
status_board_object=StatusBoardStub(name="foo", fullname="foo"),
|
110
|
-
)
|
111
|
-
|
112
|
-
h.act(dry_run=False, ocm=ocm)
|
113
|
-
assert isinstance(h.status_board_object, StatusBoardStub)
|
114
|
-
assert h.status_board_object.deleted
|
115
|
-
assert h.status_board_object.summarized
|
116
|
-
|
117
|
-
|
118
|
-
def test_get_product_apps(status_board: StatusBoardV1) -> None:
|
119
|
-
p = StatusBoardExporterIntegration.get_product_apps(status_board)
|
120
|
-
assert p == {"foo": {"foo", "foo-bar"}}
|
121
|
-
|
122
|
-
|
123
|
-
def test_get_diff_create_app() -> None:
|
124
|
-
Product.update_forward_refs()
|
125
|
-
|
126
|
-
h = StatusBoardExporterIntegration.get_diff(
|
127
|
-
{"foo": {"foo", "bar"}},
|
128
|
-
[Product(name="foo", fullname="foo", applications=[])],
|
129
|
-
)
|
130
|
-
|
131
|
-
assert len(h) == 2
|
132
|
-
assert h[0].action == h[1].action == "create"
|
133
|
-
assert isinstance(h[0].status_board_object, Application)
|
134
|
-
assert isinstance(h[1].status_board_object, Application)
|
135
|
-
assert sorted([x.status_board_object.name for x in h]) == ["bar", "foo"]
|
136
|
-
assert sorted([x.status_board_object.fullname for x in h]) == ["foo/bar", "foo/foo"]
|
137
|
-
|
138
|
-
|
139
|
-
def test_get_diff_create_one_app() -> None:
|
140
|
-
Product.update_forward_refs()
|
141
|
-
|
142
|
-
h = StatusBoardExporterIntegration.get_diff(
|
143
|
-
{"foo": {"foo", "bar"}},
|
144
|
-
[
|
145
|
-
Product(
|
146
|
-
name="foo",
|
147
|
-
fullname="foo",
|
148
|
-
applications=[Application(name="bar", fullname="foo/bar")],
|
149
|
-
)
|
150
|
-
],
|
151
|
-
)
|
152
|
-
|
153
|
-
assert len(h) == 1
|
154
|
-
assert h[0].action == "create"
|
155
|
-
assert isinstance(h[0].status_board_object, Application)
|
156
|
-
assert h[0].status_board_object.name == "foo"
|
157
|
-
assert h[0].status_board_object.fullname == "foo/foo"
|
158
|
-
|
159
|
-
|
160
|
-
def test_get_diff_create_product_and_apps() -> None:
|
161
|
-
Product.update_forward_refs()
|
162
|
-
|
163
|
-
h = StatusBoardExporterIntegration.get_diff(
|
164
|
-
{"foo": {"foo", "bar"}},
|
165
|
-
[],
|
166
|
-
)
|
167
|
-
|
168
|
-
assert len(h) == 3
|
169
|
-
assert h[0].action == "create"
|
170
|
-
assert isinstance(h[0].status_board_object, Product)
|
171
|
-
assert isinstance(h[1].status_board_object, Application)
|
172
|
-
assert isinstance(h[2].status_board_object, Application)
|
173
|
-
|
174
|
-
|
175
|
-
def test_get_diff_noop() -> None:
|
176
|
-
Product.update_forward_refs()
|
177
|
-
|
178
|
-
h = StatusBoardExporterIntegration.get_diff(
|
179
|
-
{"foo": {"bar"}},
|
180
|
-
[
|
181
|
-
Product(
|
182
|
-
name="foo",
|
183
|
-
fullname="foo",
|
184
|
-
applications=[Application(name="bar", fullname="foo/bar")],
|
185
|
-
)
|
186
|
-
],
|
187
|
-
)
|
188
|
-
|
189
|
-
assert len(h) == 0
|
190
|
-
|
191
|
-
|
192
|
-
def test_get_diff_delete_app() -> None:
|
193
|
-
Product.update_forward_refs()
|
194
|
-
|
195
|
-
h = StatusBoardExporterIntegration.get_diff(
|
196
|
-
{"foo": set()},
|
197
|
-
[
|
198
|
-
Product(
|
199
|
-
name="foo",
|
200
|
-
fullname="foo",
|
201
|
-
applications=[Application(name="bar", fullname="foo/bar")],
|
202
|
-
)
|
203
|
-
],
|
204
|
-
)
|
205
|
-
|
206
|
-
assert len(h) == 1
|
207
|
-
assert h[0].action == "delete"
|
208
|
-
assert isinstance(h[0].status_board_object, Application)
|
209
|
-
assert h[0].status_board_object.name == "bar"
|
210
|
-
|
211
|
-
|
212
|
-
def test_get_diff_delete_apps_and_product() -> None:
|
213
|
-
Product.update_forward_refs()
|
214
|
-
|
215
|
-
h = StatusBoardExporterIntegration.get_diff(
|
216
|
-
{},
|
217
|
-
[
|
218
|
-
Product(
|
219
|
-
name="foo",
|
220
|
-
fullname="foo",
|
221
|
-
applications=[Application(name="bar", fullname="foo/bar")],
|
222
|
-
)
|
223
|
-
],
|
224
|
-
)
|
225
|
-
|
226
|
-
assert len(h) == 2
|
227
|
-
assert h[0].action == h[1].action == "delete"
|
228
|
-
assert isinstance(h[0].status_board_object, Application)
|
229
|
-
assert isinstance(h[1].status_board_object, Product)
|
230
|
-
|
231
|
-
|
232
|
-
def test_apply_sorted(mocker: MockerFixture) -> None:
|
233
|
-
Product.update_forward_refs()
|
234
|
-
ocm = mocker.patch("reconcile.status_board.OCMBaseClient", autospec=True)
|
235
|
-
logging = mocker.patch("reconcile.status_board.logging", autospec=True)
|
236
|
-
|
237
|
-
product = Product(name="foo", fullname="foo", applications=[])
|
238
|
-
h = [
|
239
|
-
StatusBoardHandler(
|
240
|
-
action="create",
|
241
|
-
status_board_object=Application(
|
242
|
-
name="bar", fullname="foo/bar", product=product
|
243
|
-
),
|
244
|
-
),
|
245
|
-
StatusBoardHandler(
|
246
|
-
action="create",
|
247
|
-
status_board_object=product,
|
248
|
-
),
|
249
|
-
]
|
250
|
-
|
251
|
-
StatusBoardExporterIntegration.apply_diff(True, ocm, h)
|
252
|
-
logging.info.assert_has_calls(
|
253
|
-
calls=[
|
254
|
-
call('create - Product: "foo"'),
|
255
|
-
call('create - Application: "bar" "foo/bar"'),
|
256
|
-
],
|
257
|
-
any_order=False,
|
258
|
-
)
|
@@ -1,29 +0,0 @@
|
|
1
|
-
import pytest
|
2
|
-
from pytest_mock import MockerFixture
|
3
|
-
|
4
|
-
import reconcile.terraform_aws_route53 as integ
|
5
|
-
|
6
|
-
|
7
|
-
@pytest.fixture
|
8
|
-
def aws_accounts() -> list[dict]:
|
9
|
-
return [
|
10
|
-
{
|
11
|
-
"name": "test-account",
|
12
|
-
}
|
13
|
-
]
|
14
|
-
|
15
|
-
|
16
|
-
def test_empty_run(
|
17
|
-
mocker: MockerFixture,
|
18
|
-
aws_accounts: list[dict],
|
19
|
-
) -> None:
|
20
|
-
mocked_logging = mocker.patch("reconcile.terraform_aws_route53.logging")
|
21
|
-
mocked_queries = mocker.patch("reconcile.terraform_aws_route53.queries")
|
22
|
-
mocked_queries.get_dns_zones.return_value = []
|
23
|
-
mocked_queries.get_aws_accounts.return_value = aws_accounts
|
24
|
-
|
25
|
-
integ.run(False)
|
26
|
-
|
27
|
-
mocked_logging.warning.assert_called_once_with(
|
28
|
-
"No participating AWS accounts found, consider disabling this integration, account name: None"
|
29
|
-
)
|