qontract-reconcile 0.10.1rc1202__py3-none-any.whl → 0.10.2.dev2__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.dev2.dist-info/METADATA +500 -0
- {qontract_reconcile-0.10.1rc1202.dist-info → qontract_reconcile-0.10.2.dev2.dist-info}/RECORD +12 -130
- {qontract_reconcile-0.10.1rc1202.dist-info → qontract_reconcile-0.10.2.dev2.dist-info}/WHEEL +1 -2
- {qontract_reconcile-0.10.1rc1202.dist-info → qontract_reconcile-0.10.2.dev2.dist-info}/entry_points.txt +1 -0
- reconcile/aws_account_manager/README.md +5 -0
- reconcile/change_owners/README.md +34 -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.1rc1202.dist-info/METADATA +0 -64
- qontract_reconcile-0.10.1rc1202.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,178 +0,0 @@
|
|
1
|
-
from http import HTTPStatus
|
2
|
-
|
3
|
-
import pytest
|
4
|
-
import requests
|
5
|
-
|
6
|
-
import reconcile.checkpoint as sut
|
7
|
-
|
8
|
-
|
9
|
-
@pytest.fixture
|
10
|
-
def valid_app():
|
11
|
-
"""How a valid application looks like."""
|
12
|
-
return {
|
13
|
-
"sopsUrl": "https://www.redhat.com/sops",
|
14
|
-
"architectureDocument": "https://www.redhat.com/arch",
|
15
|
-
"grafanaUrl": "https://www.redhat.com/graf",
|
16
|
-
"serviceOwners": [{"name": "A Name", "email": "aname@adomain.com"}],
|
17
|
-
}
|
18
|
-
|
19
|
-
|
20
|
-
@pytest.fixture
|
21
|
-
def valid_owner():
|
22
|
-
"""How a valid owner looks like."""
|
23
|
-
return {"name": "A Name", "email": "a.name@redhat.com"}
|
24
|
-
|
25
|
-
|
26
|
-
def invalid_owners():
|
27
|
-
"""List the ways in which an owner can be invalid."""
|
28
|
-
return [
|
29
|
-
{"name": "A Name", "email": None},
|
30
|
-
{"name": "A Name", "email": "domainless"},
|
31
|
-
{"name": "A Name", "email": "@name.less"},
|
32
|
-
{"name": None, "email": "a-name@redhat.com"},
|
33
|
-
]
|
34
|
-
|
35
|
-
|
36
|
-
def test_valid_owner(valid_owner) -> None:
|
37
|
-
"""Confirm that the valid owner is recognized as such."""
|
38
|
-
assert sut.valid_owners([valid_owner])
|
39
|
-
|
40
|
-
|
41
|
-
@pytest.mark.parametrize("invalid_owner", invalid_owners())
|
42
|
-
def test_invalid_owners(invalid_owner):
|
43
|
-
"""Confirm that the invalid owners are flagged."""
|
44
|
-
assert not sut.valid_owners([invalid_owner])
|
45
|
-
|
46
|
-
|
47
|
-
@pytest.mark.parametrize("invalid_owner", invalid_owners())
|
48
|
-
def test_invalid_owners_remain_invalid(valid_owner, invalid_owner):
|
49
|
-
"""Confirm rejection of invalid owners even mixed with good ones."""
|
50
|
-
assert not sut.valid_owners([valid_owner, invalid_owner])
|
51
|
-
|
52
|
-
|
53
|
-
def test_url_makes_sense_ok(mocker):
|
54
|
-
"""Good URLs are accepted."""
|
55
|
-
get = mocker.patch.object(requests, "get", autospec=True)
|
56
|
-
r = requests.Response()
|
57
|
-
r.status_code = HTTPStatus.OK
|
58
|
-
get.return_value = r
|
59
|
-
|
60
|
-
assert sut.url_makes_sense("https://www.redhat.com/existing")
|
61
|
-
|
62
|
-
|
63
|
-
def test_url_makes_sense_unknown(mocker):
|
64
|
-
"""Ensure rejection of URLs pointing to missing documents."""
|
65
|
-
get = mocker.patch.object(requests, "get", autospec=True)
|
66
|
-
r = requests.Response()
|
67
|
-
r.status_code = HTTPStatus.NOT_FOUND
|
68
|
-
get.return_value = r
|
69
|
-
assert not sut.url_makes_sense("https://www.redhat.com/nonexisting")
|
70
|
-
|
71
|
-
|
72
|
-
def test_url_makes_sense_error():
|
73
|
-
"""Ensure rejection of URLs returning ConnectionError."""
|
74
|
-
assert not sut.url_makes_sense("https://TODO")
|
75
|
-
|
76
|
-
|
77
|
-
def test_url_makes_sense_empty():
|
78
|
-
"""Ensure rejection of empty URLs."""
|
79
|
-
assert not sut.url_makes_sense("")
|
80
|
-
|
81
|
-
|
82
|
-
def test_render_template():
|
83
|
-
"""Confirm rendering of all placeholders in the ticket template."""
|
84
|
-
txt = sut.render_template(
|
85
|
-
sut.MISSING_DATA_TEMPLATE, "aname", "apath", "afield", "avalue"
|
86
|
-
)
|
87
|
-
assert "aname" in txt
|
88
|
-
assert "apath" in txt
|
89
|
-
assert "afield" in txt
|
90
|
-
assert "avalue" in txt
|
91
|
-
|
92
|
-
|
93
|
-
def app_metadata():
|
94
|
-
"""List some metadata for some fake apps.
|
95
|
-
|
96
|
-
Returns the app structure and whether we expect it to have a
|
97
|
-
ticket associated with it
|
98
|
-
"""
|
99
|
-
return [
|
100
|
-
(
|
101
|
-
{
|
102
|
-
"name": "appname",
|
103
|
-
"sopsUrl": "https://www.somewhe.re",
|
104
|
-
"architectureDocument": "https://www.hereand.now",
|
105
|
-
"grafanaUrls": [],
|
106
|
-
},
|
107
|
-
False,
|
108
|
-
),
|
109
|
-
# Missing field - should cut a ticket
|
110
|
-
(
|
111
|
-
{
|
112
|
-
"name": "appname",
|
113
|
-
"sopsUrl": "https://www.somewhe.re",
|
114
|
-
"grafanaUrls": [],
|
115
|
-
},
|
116
|
-
True,
|
117
|
-
),
|
118
|
-
# Bad field - should cut a ticket
|
119
|
-
(
|
120
|
-
{
|
121
|
-
"name": "appname",
|
122
|
-
"architectureDocument": "",
|
123
|
-
"grafanaUrls": [],
|
124
|
-
"sopsUrl": "http://www.herea.nd",
|
125
|
-
},
|
126
|
-
True,
|
127
|
-
),
|
128
|
-
]
|
129
|
-
|
130
|
-
|
131
|
-
@pytest.mark.parametrize("app,needs_ticket", app_metadata())
|
132
|
-
def test_report_invalid_metadata(mocker, app, needs_ticket):
|
133
|
-
"""Test that valid apps don't get tickets and that invalid apps do."""
|
134
|
-
# TODO: I'm pretty sure a fixture can help with this
|
135
|
-
jira = mocker.patch.object(sut, "JiraClient", autospec=True)
|
136
|
-
filer = mocker.patch.object(sut, "file_ticket", autospec=True)
|
137
|
-
|
138
|
-
valid = sut.VALIDATORS
|
139
|
-
|
140
|
-
sut.VALIDATORS = {
|
141
|
-
"sopsUrl": bool,
|
142
|
-
"architectureDocument": bool,
|
143
|
-
"grafanaUrls": lambda _: True,
|
144
|
-
}
|
145
|
-
|
146
|
-
sut.report_invalid_metadata(app, "/a/path", "jiraboard", {}, "TICKET-123")
|
147
|
-
if needs_ticket:
|
148
|
-
filer.assert_called_once_with(
|
149
|
-
jira=jira.return_value,
|
150
|
-
app_name=app["name"],
|
151
|
-
labels=sut.DEFAULT_CHECKPOINT_LABELS,
|
152
|
-
parent="TICKET-123",
|
153
|
-
field="architectureDocument",
|
154
|
-
bad_value=str(app.get("architectureDocument")),
|
155
|
-
app_path="/a/path",
|
156
|
-
)
|
157
|
-
else:
|
158
|
-
filer.assert_not_called()
|
159
|
-
|
160
|
-
sut.VALIDATORS = valid
|
161
|
-
|
162
|
-
|
163
|
-
@pytest.mark.parametrize("app,needs_ticket", app_metadata())
|
164
|
-
def test_report_invalid_metadata_dry_run(mocker, app, needs_ticket):
|
165
|
-
"""Test the dry-run mode."""
|
166
|
-
renderer = mocker.patch.object(sut, "render_template", autospec=True)
|
167
|
-
valid = sut.VALIDATORS
|
168
|
-
sut.VALIDATORS = {
|
169
|
-
"sopsUrl": bool,
|
170
|
-
"architectureDocument": bool,
|
171
|
-
"grafanaUrls": lambda _: True,
|
172
|
-
}
|
173
|
-
sut.report_invalid_metadata(app, "/a/path", "jiraboard", {}, "TICKET-123", True)
|
174
|
-
if needs_ticket:
|
175
|
-
renderer.assert_called_once()
|
176
|
-
else:
|
177
|
-
renderer.assert_not_called()
|
178
|
-
sut.VALIDATORS = valid
|
reconcile/test/test_cli.py
DELETED
@@ -1,41 +0,0 @@
|
|
1
|
-
import pytest
|
2
|
-
from click.testing import CliRunner
|
3
|
-
|
4
|
-
import reconcile.cli as reconcile_cli
|
5
|
-
|
6
|
-
|
7
|
-
def test_config_is_required():
|
8
|
-
runner = CliRunner()
|
9
|
-
result = runner.invoke(reconcile_cli.integration)
|
10
|
-
assert result.exit_code == 0
|
11
|
-
|
12
|
-
|
13
|
-
def test_parse_image_tag_from_ref_valid():
|
14
|
-
t = ("env=main",)
|
15
|
-
expected = {"env": "main"}
|
16
|
-
result = reconcile_cli.parse_image_tag_from_ref(None, None, t)
|
17
|
-
assert result == expected
|
18
|
-
|
19
|
-
|
20
|
-
def test_parse_image_tag_from_ref_invalid_1():
|
21
|
-
t = ("env=",)
|
22
|
-
with pytest.raises(SystemExit):
|
23
|
-
reconcile_cli.parse_image_tag_from_ref(None, None, t)
|
24
|
-
|
25
|
-
|
26
|
-
def test_parse_image_tag_from_ref_invalid_2():
|
27
|
-
t = ("=main",)
|
28
|
-
with pytest.raises(SystemExit):
|
29
|
-
reconcile_cli.parse_image_tag_from_ref(None, None, t)
|
30
|
-
|
31
|
-
|
32
|
-
def test_parse_image_tag_from_ref_invalid_3():
|
33
|
-
t = ("=",)
|
34
|
-
with pytest.raises(SystemExit):
|
35
|
-
reconcile_cli.parse_image_tag_from_ref(None, None, t)
|
36
|
-
|
37
|
-
|
38
|
-
def test_parse_image_tag_from_ref_invalid_4():
|
39
|
-
t = ("env=main=test",)
|
40
|
-
with pytest.raises(SystemExit):
|
41
|
-
reconcile_cli.parse_image_tag_from_ref(None, None, t)
|
@@ -1,207 +0,0 @@
|
|
1
|
-
from unittest.mock import ANY
|
2
|
-
|
3
|
-
import pytest
|
4
|
-
|
5
|
-
from reconcile.blackbox_exporter_endpoint_monitoring import (
|
6
|
-
PROVIDER as BLACKBOX_EXPORTER_PROVIDER,
|
7
|
-
)
|
8
|
-
from reconcile.blackbox_exporter_endpoint_monitoring import (
|
9
|
-
build_probe as blackbox_exporter_probe_builder,
|
10
|
-
)
|
11
|
-
from reconcile.closedbox_endpoint_monitoring_base import (
|
12
|
-
fill_desired_state,
|
13
|
-
get_endpoints,
|
14
|
-
parse_prober_url,
|
15
|
-
queries,
|
16
|
-
)
|
17
|
-
from reconcile.signalfx_endpoint_monitoring import PROVIDER as SIGNALFX_PROVIDER
|
18
|
-
from reconcile.signalfx_endpoint_monitoring import build_probe as signalfx_probe_builder
|
19
|
-
from reconcile.utils.openshift_resource import ResourceInventory
|
20
|
-
|
21
|
-
from .fixtures import Fixtures
|
22
|
-
|
23
|
-
fxt = Fixtures("closedbox_exporter_endpoint_monitoring")
|
24
|
-
|
25
|
-
|
26
|
-
def get_endpoint_fixtures(path: str) -> dict:
|
27
|
-
return fxt.get_anymarkup(path)["appInterface"]["apps"]
|
28
|
-
|
29
|
-
|
30
|
-
def test_invalid_endpoints(mocker):
|
31
|
-
query = mocker.patch.object(queries, "get_service_monitoring_endpoints")
|
32
|
-
query.return_value = get_endpoint_fixtures("test_invalid_endpoints.yaml")
|
33
|
-
|
34
|
-
endpoints = get_endpoints(BLACKBOX_EXPORTER_PROVIDER)
|
35
|
-
assert len(endpoints) == 0
|
36
|
-
|
37
|
-
|
38
|
-
def test_blackbox_exporter_endpoint_loading(mocker):
|
39
|
-
ep_query = mocker.patch.object(queries, "get_service_monitoring_endpoints")
|
40
|
-
ep_query.return_value = get_endpoint_fixtures("test_endpoint.yaml")
|
41
|
-
|
42
|
-
endpoints = get_endpoints(BLACKBOX_EXPORTER_PROVIDER)
|
43
|
-
assert endpoints is not None
|
44
|
-
assert len(endpoints) == 1
|
45
|
-
|
46
|
-
provider = next(iter(endpoints.keys()))
|
47
|
-
assert provider.provider == BLACKBOX_EXPORTER_PROVIDER
|
48
|
-
provider_endpoints = endpoints.get(provider)
|
49
|
-
assert provider_endpoints is not None
|
50
|
-
assert len(provider_endpoints) == 1
|
51
|
-
assert len(provider_endpoints[0].monitoring) == 1
|
52
|
-
|
53
|
-
|
54
|
-
def test_parse_prober_url():
|
55
|
-
assert parse_prober_url("http://host:1234/path") == {
|
56
|
-
"url": "host:1234",
|
57
|
-
"scheme": "http",
|
58
|
-
"path": "/path",
|
59
|
-
}
|
60
|
-
|
61
|
-
assert parse_prober_url("http://host") == {"url": "host", "scheme": "http"}
|
62
|
-
|
63
|
-
|
64
|
-
def test_invalid_prober_url():
|
65
|
-
# scheme missing
|
66
|
-
with pytest.raises(ValueError):
|
67
|
-
parse_prober_url("host:1234/path")
|
68
|
-
|
69
|
-
|
70
|
-
def test_blackbox_exporter_probe_building(mocker):
|
71
|
-
ep_query = mocker.patch.object(queries, "get_service_monitoring_endpoints")
|
72
|
-
ep_query.return_value = get_endpoint_fixtures("test_blackbox_probe_building.yaml")
|
73
|
-
|
74
|
-
endpoints = get_endpoints(BLACKBOX_EXPORTER_PROVIDER)
|
75
|
-
assert len(endpoints) == 1
|
76
|
-
|
77
|
-
provider = next(iter(endpoints.keys()))
|
78
|
-
provider_endpoints = endpoints.get(provider)
|
79
|
-
assert provider_endpoints is not None
|
80
|
-
probe_resource = blackbox_exporter_probe_builder(provider, provider_endpoints)
|
81
|
-
assert probe_resource is not None
|
82
|
-
|
83
|
-
# verify prober url decomposition
|
84
|
-
spec = probe_resource.body.get("spec")
|
85
|
-
assert spec.get("prober") == {
|
86
|
-
"url": "exporterhost:9115",
|
87
|
-
"scheme": "http",
|
88
|
-
"path": "/probe",
|
89
|
-
}
|
90
|
-
|
91
|
-
# verify labels
|
92
|
-
labels = spec["targets"]["staticConfig"]["labels"]
|
93
|
-
assert labels.get("environment") == "staging"
|
94
|
-
|
95
|
-
# verify timeout and interval
|
96
|
-
assert spec["scrapeTimeout"] == provider.timeout
|
97
|
-
assert spec["interval"] == provider.checkInterval
|
98
|
-
|
99
|
-
# verify targets
|
100
|
-
assert "https://test1.url" in spec["targets"]["staticConfig"]["static"]
|
101
|
-
assert "https://test2.url" in spec["targets"]["staticConfig"]["static"]
|
102
|
-
|
103
|
-
|
104
|
-
def test_signalfx_probe_building(mocker):
|
105
|
-
ep_query = mocker.patch.object(queries, "get_service_monitoring_endpoints")
|
106
|
-
ep_query.return_value = get_endpoint_fixtures("test_signalfx_probe_building.yaml")
|
107
|
-
|
108
|
-
endpoints = get_endpoints(SIGNALFX_PROVIDER)
|
109
|
-
assert len(endpoints) == 1
|
110
|
-
|
111
|
-
provider = next(iter(endpoints.keys()))
|
112
|
-
provider_endpoints = endpoints.get(provider)
|
113
|
-
assert provider_endpoints is not None
|
114
|
-
probe_resource = signalfx_probe_builder(provider, provider_endpoints)
|
115
|
-
assert probe_resource is not None
|
116
|
-
|
117
|
-
# verify prober url decomposition
|
118
|
-
spec = probe_resource.body.get("spec")
|
119
|
-
assert spec.get("prober") == {
|
120
|
-
"url": "signalfxexporter:9091",
|
121
|
-
"scheme": "http",
|
122
|
-
"path": "/metrics/probe",
|
123
|
-
}
|
124
|
-
|
125
|
-
# verify labels
|
126
|
-
labels = spec["targets"]["staticConfig"]["labels"]
|
127
|
-
assert labels.get("environment") == "staging"
|
128
|
-
|
129
|
-
# verify timeout and interval
|
130
|
-
assert spec["scrapeTimeout"] == provider.timeout
|
131
|
-
assert spec["interval"] == provider.checkInterval
|
132
|
-
|
133
|
-
# verify targets
|
134
|
-
assert "test_1" in spec["targets"]["staticConfig"]["static"]
|
135
|
-
assert "test_2" in spec["targets"]["staticConfig"]["static"]
|
136
|
-
|
137
|
-
# verify relabeling
|
138
|
-
assert {
|
139
|
-
"action": "replace",
|
140
|
-
"regex": "^test_1$",
|
141
|
-
"replacement": "https://test1.url",
|
142
|
-
"sourceLabels": ["instance"],
|
143
|
-
"targetLabel": "instance",
|
144
|
-
} in spec["targets"]["staticConfig"]["relabelingConfigs"]
|
145
|
-
assert {
|
146
|
-
"action": "replace",
|
147
|
-
"regex": "^test_2$",
|
148
|
-
"replacement": "https://test2.url",
|
149
|
-
"sourceLabels": ["instance"],
|
150
|
-
"targetLabel": "instance",
|
151
|
-
} in spec["targets"]["staticConfig"]["relabelingConfigs"]
|
152
|
-
|
153
|
-
|
154
|
-
def test_blackbox_exporter_filling_desired_state(mocker):
|
155
|
-
ep_query = mocker.patch.object(queries, "get_service_monitoring_endpoints")
|
156
|
-
ep_query.return_value = get_endpoint_fixtures("test_endpoint.yaml")
|
157
|
-
add_desired_mock = mocker.patch.object(ResourceInventory, "add_desired")
|
158
|
-
|
159
|
-
endpoints = get_endpoints(BLACKBOX_EXPORTER_PROVIDER)
|
160
|
-
provider = next(iter(endpoints.keys()))
|
161
|
-
probe = blackbox_exporter_probe_builder(provider, endpoints[provider])
|
162
|
-
assert probe is not None
|
163
|
-
fill_desired_state(provider, probe, ResourceInventory())
|
164
|
-
|
165
|
-
assert add_desired_mock.call_count == 1
|
166
|
-
add_desired_mock.assert_called_with(
|
167
|
-
cluster="app-sre-stage-01",
|
168
|
-
namespace="openshift-customer-monitoring",
|
169
|
-
resource_type="Probe",
|
170
|
-
name="blackbox-exporter-http-2xx",
|
171
|
-
value=ANY,
|
172
|
-
)
|
173
|
-
|
174
|
-
|
175
|
-
def test_signalfx_filling_desired_state(mocker):
|
176
|
-
ep_query = mocker.patch.object(queries, "get_service_monitoring_endpoints")
|
177
|
-
ep_query.return_value = get_endpoint_fixtures("test_endpoint.yaml")
|
178
|
-
add_desired_mock = mocker.patch.object(ResourceInventory, "add_desired")
|
179
|
-
|
180
|
-
endpoints = get_endpoints(SIGNALFX_PROVIDER)
|
181
|
-
provider = next(iter(endpoints.keys()))
|
182
|
-
probe = signalfx_probe_builder(provider, endpoints[provider])
|
183
|
-
assert probe is not None
|
184
|
-
fill_desired_state(provider, probe, ResourceInventory())
|
185
|
-
|
186
|
-
assert add_desired_mock.call_count == 1
|
187
|
-
add_desired_mock.assert_called_with(
|
188
|
-
cluster="app-sre-stage-01",
|
189
|
-
namespace="openshift-customer-monitoring",
|
190
|
-
resource_type="Probe",
|
191
|
-
name="signalfx-exporter-http-2xx",
|
192
|
-
value=ANY,
|
193
|
-
)
|
194
|
-
|
195
|
-
|
196
|
-
def test_loading_multiple_providers_per_endpoint(mocker):
|
197
|
-
ep_query = mocker.patch.object(queries, "get_service_monitoring_endpoints")
|
198
|
-
ep_query.return_value = get_endpoint_fixtures(
|
199
|
-
"test_multiple_providers_per_endpoint.yaml"
|
200
|
-
)
|
201
|
-
endpoints = get_endpoints(BLACKBOX_EXPORTER_PROVIDER)
|
202
|
-
|
203
|
-
assert len(endpoints) == 2
|
204
|
-
|
205
|
-
for provider, eps in endpoints.items():
|
206
|
-
assert provider.provider == BLACKBOX_EXPORTER_PROVIDER
|
207
|
-
assert len(eps) == 2
|
@@ -1,245 +0,0 @@
|
|
1
|
-
from datetime import datetime
|
2
|
-
from unittest.mock import MagicMock
|
3
|
-
|
4
|
-
import yaml
|
5
|
-
from pytest_mock import MockerFixture
|
6
|
-
|
7
|
-
from reconcile.dashdotdb_dora import (
|
8
|
-
AppEnv,
|
9
|
-
Commit,
|
10
|
-
DashdotdbDORA,
|
11
|
-
Deployment,
|
12
|
-
RepoChanges,
|
13
|
-
SaasTarget,
|
14
|
-
)
|
15
|
-
|
16
|
-
|
17
|
-
def test_get_repo_ref_for_sha(mocker: MockerFixture):
|
18
|
-
mocker.patch("reconcile.dashdotdb_dora.DashdotdbDORA.__init__").return_value = None
|
19
|
-
d = DashdotdbDORA(False, "1", 1)
|
20
|
-
|
21
|
-
# mock gl_app_interface_get_file
|
22
|
-
d.gl_app_interface_get_file = MagicMock(
|
23
|
-
return_value=yaml.safe_dump({
|
24
|
-
"resourceTemplates": [
|
25
|
-
{
|
26
|
-
"name": "rt0",
|
27
|
-
"url": "url0",
|
28
|
-
"ref": "ref0",
|
29
|
-
"targets": [
|
30
|
-
{"namespace": {"$ref": "ns0"}, "ref": "ref0"},
|
31
|
-
{"namespace": {"$ref": "ns3"}, "ref": "ref3"},
|
32
|
-
],
|
33
|
-
},
|
34
|
-
{
|
35
|
-
"name": "rt1",
|
36
|
-
"url": "url1",
|
37
|
-
"ref": "ref1",
|
38
|
-
"targets": [
|
39
|
-
{"namespace": {"$ref": "ns0"}, "ref": "ref0"},
|
40
|
-
{"namespace": {"$ref": "ns1"}, "ref": "ref1"},
|
41
|
-
],
|
42
|
-
},
|
43
|
-
]
|
44
|
-
}).encode("utf-8")
|
45
|
-
)
|
46
|
-
|
47
|
-
saastarget = SaasTarget("app1", "env1", "/path1", "rt1", "ns1", "pipeline1")
|
48
|
-
info = d.get_repo_ref_for_sha(saastarget, "sha")
|
49
|
-
|
50
|
-
assert info == ("url1", "ref1")
|
51
|
-
|
52
|
-
|
53
|
-
def test_get_repo_ref_for_sha_none(mocker: MockerFixture):
|
54
|
-
mocker.patch("reconcile.dashdotdb_dora.DashdotdbDORA.__init__").return_value = None
|
55
|
-
d = DashdotdbDORA(False, "1", 1)
|
56
|
-
|
57
|
-
# mock gl_app_interface_get_file
|
58
|
-
d.gl_app_interface_get_file = MagicMock(
|
59
|
-
return_value=yaml.safe_dump({
|
60
|
-
"resourceTemplates": [
|
61
|
-
{
|
62
|
-
"name": "rt10",
|
63
|
-
"url": "url0",
|
64
|
-
"ref": "ref0",
|
65
|
-
"targets": [
|
66
|
-
{"namespace": {"$ref": "ns0"}, "ref": "ref0"},
|
67
|
-
{"namespace": {"$ref": "ns3"}, "ref": "ref3"},
|
68
|
-
],
|
69
|
-
},
|
70
|
-
{
|
71
|
-
"name": "rt11",
|
72
|
-
"url": "url1",
|
73
|
-
"ref": "ref1",
|
74
|
-
"targets": [
|
75
|
-
{"namespace": {"$ref": "ns0"}, "ref": "ref0"},
|
76
|
-
{"namespace": {"$ref": "ns1"}, "ref": "ref1"},
|
77
|
-
],
|
78
|
-
},
|
79
|
-
]
|
80
|
-
}).encode("utf-8")
|
81
|
-
)
|
82
|
-
|
83
|
-
saastarget = SaasTarget("app1", "env1", "/path1", "rt1", "ns1", "pipeline1")
|
84
|
-
info = d.get_repo_ref_for_sha(saastarget, "sha")
|
85
|
-
|
86
|
-
assert info == (None, None)
|
87
|
-
|
88
|
-
|
89
|
-
def test_compare_gh(mocker: MockerFixture):
|
90
|
-
mocker.patch("reconcile.dashdotdb_dora.DashdotdbDORA.__init__").return_value = None
|
91
|
-
d = DashdotdbDORA(False, "1", 1)
|
92
|
-
ghapi_mock = MagicMock()
|
93
|
-
|
94
|
-
def gl_commit_mock(sha, date):
|
95
|
-
obj = MagicMock()
|
96
|
-
obj.sha = sha
|
97
|
-
obj.commit.committer.date = date
|
98
|
-
return obj
|
99
|
-
|
100
|
-
ghapi_mock.compare.return_value = [
|
101
|
-
gl_commit_mock(
|
102
|
-
"8cfb8408f614e1d0179d75af793f3fddf42d054a", datetime(2023, 9, 1, 0, 0, 0)
|
103
|
-
),
|
104
|
-
gl_commit_mock(
|
105
|
-
"81677e1bc71324c9fa5c747b494add5a5af5e653", datetime(2023, 9, 2, 0, 0, 0)
|
106
|
-
),
|
107
|
-
gl_commit_mock(
|
108
|
-
"566f37f8e9985d775e619cc959b806f5a254a380", datetime(2023, 9, 3, 0, 0, 0)
|
109
|
-
),
|
110
|
-
gl_commit_mock(
|
111
|
-
"adab91701311fec1b0f5405adddaf68f886bba2c", datetime(2023, 9, 4, 0, 0, 0)
|
112
|
-
),
|
113
|
-
]
|
114
|
-
|
115
|
-
d._gh_apis = {"my/repo": ghapi_mock}
|
116
|
-
|
117
|
-
repo = "https://github.com/my/repo"
|
118
|
-
|
119
|
-
repo_changes = RepoChanges(
|
120
|
-
repo,
|
121
|
-
"e000dafd2e7bf34be41e7b3a5cb529ce7fbde257",
|
122
|
-
"adab91701311fec1b0f5405adddaf68f886bba2c",
|
123
|
-
)
|
124
|
-
rc, commits = d.compare(repo_changes)
|
125
|
-
assert rc == repo_changes
|
126
|
-
assert commits == [
|
127
|
-
Commit(
|
128
|
-
repo,
|
129
|
-
"8cfb8408f614e1d0179d75af793f3fddf42d054a",
|
130
|
-
datetime(2023, 9, 1, 0, 0, 0),
|
131
|
-
),
|
132
|
-
Commit(
|
133
|
-
repo,
|
134
|
-
"81677e1bc71324c9fa5c747b494add5a5af5e653",
|
135
|
-
datetime(2023, 9, 2, 0, 0, 0),
|
136
|
-
),
|
137
|
-
Commit(
|
138
|
-
repo,
|
139
|
-
"566f37f8e9985d775e619cc959b806f5a254a380",
|
140
|
-
datetime(2023, 9, 3, 0, 0, 0),
|
141
|
-
),
|
142
|
-
Commit(
|
143
|
-
repo,
|
144
|
-
"adab91701311fec1b0f5405adddaf68f886bba2c",
|
145
|
-
datetime(2023, 9, 4, 0, 0, 0),
|
146
|
-
),
|
147
|
-
]
|
148
|
-
|
149
|
-
|
150
|
-
def test_compare_gl(mocker: MockerFixture):
|
151
|
-
mocker.patch("reconcile.dashdotdb_dora.DashdotdbDORA.__init__").return_value = None
|
152
|
-
d = DashdotdbDORA(False, "1", 1)
|
153
|
-
d.gl = MagicMock()
|
154
|
-
d.gl.server = "https://gitlab.com"
|
155
|
-
d.gl.repository_compare.return_value = [
|
156
|
-
{
|
157
|
-
"id": "8cfb8408f614e1d0179d75af793f3fddf42d054a",
|
158
|
-
"committed_date": "2023-09-01T00:00:00",
|
159
|
-
},
|
160
|
-
{
|
161
|
-
"id": "81677e1bc71324c9fa5c747b494add5a5af5e653",
|
162
|
-
"committed_date": "2023-09-02T00:00:00",
|
163
|
-
},
|
164
|
-
{
|
165
|
-
"id": "566f37f8e9985d775e619cc959b806f5a254a380",
|
166
|
-
"committed_date": "2023-09-03T00:00:00",
|
167
|
-
},
|
168
|
-
{
|
169
|
-
"id": "adab91701311fec1b0f5405adddaf68f886bba2c",
|
170
|
-
"committed_date": "2023-09-04T00:00:00",
|
171
|
-
},
|
172
|
-
]
|
173
|
-
repo = "https://gitlab.com/my/repo"
|
174
|
-
|
175
|
-
repo_changes = RepoChanges(
|
176
|
-
repo,
|
177
|
-
"e000dafd2e7bf34be41e7b3a5cb529ce7fbde257",
|
178
|
-
"adab91701311fec1b0f5405adddaf68f886bba2c",
|
179
|
-
)
|
180
|
-
rc, commits = d.compare(repo_changes)
|
181
|
-
assert rc == repo_changes
|
182
|
-
assert commits == [
|
183
|
-
Commit(
|
184
|
-
repo,
|
185
|
-
"8cfb8408f614e1d0179d75af793f3fddf42d054a",
|
186
|
-
datetime(2023, 9, 1, 0, 0, 0),
|
187
|
-
),
|
188
|
-
Commit(
|
189
|
-
repo,
|
190
|
-
"81677e1bc71324c9fa5c747b494add5a5af5e653",
|
191
|
-
datetime(2023, 9, 2, 0, 0, 0),
|
192
|
-
),
|
193
|
-
Commit(
|
194
|
-
repo,
|
195
|
-
"566f37f8e9985d775e619cc959b806f5a254a380",
|
196
|
-
datetime(2023, 9, 3, 0, 0, 0),
|
197
|
-
),
|
198
|
-
Commit(
|
199
|
-
repo,
|
200
|
-
"adab91701311fec1b0f5405adddaf68f886bba2c",
|
201
|
-
datetime(2023, 9, 4, 0, 0, 0),
|
202
|
-
),
|
203
|
-
]
|
204
|
-
|
205
|
-
|
206
|
-
def test_get_latest_with_default(mocker: MockerFixture):
|
207
|
-
mocker.patch("reconcile.dashdotdb_dora.DashdotdbDORA.__init__").return_value = None
|
208
|
-
d = DashdotdbDORA(False, "1", 1)
|
209
|
-
d.dashdotdb_url = "http://localhost"
|
210
|
-
|
211
|
-
date = datetime(2023, 9, 3, 0, 0, 0)
|
212
|
-
appenv = AppEnv("app1", "env1")
|
213
|
-
|
214
|
-
response = MagicMock()
|
215
|
-
response.status_code = 200
|
216
|
-
response.json.return_value = {"finish_timestamp": date.isoformat()}
|
217
|
-
|
218
|
-
d._do_get = MagicMock(return_value=response) # type: ignore[method-assign]
|
219
|
-
|
220
|
-
latest = d.get_latest_with_default(date, appenv)
|
221
|
-
assert latest == (
|
222
|
-
AppEnv(app_name="app1", env_name="env1"),
|
223
|
-
datetime(2023, 9, 3, 0, 0),
|
224
|
-
)
|
225
|
-
|
226
|
-
|
227
|
-
def test_get_repo_changes(mocker: MockerFixture):
|
228
|
-
mocker.patch("reconcile.dashdotdb_dora.DashdotdbDORA.__init__").return_value = None
|
229
|
-
d = DashdotdbDORA(False, "1", 1)
|
230
|
-
|
231
|
-
saastarget = SaasTarget("app1", "env1", "/path1", "rt1", "ns1", "pipeline1")
|
232
|
-
date = datetime(2023, 9, 3, 0, 0)
|
233
|
-
deployment = Deployment("trigger1", date)
|
234
|
-
saastarget_deployment = (saastarget, deployment)
|
235
|
-
|
236
|
-
d.get_repo_ref_for_sha = MagicMock( # type: ignore[method-assign]
|
237
|
-
side_effect=[("repo1", "commitA"), ("repo1", "commitB")]
|
238
|
-
)
|
239
|
-
|
240
|
-
exp_saas_target, exp_deployment, repo_changes = d.get_repo_changes(
|
241
|
-
saastarget_deployment
|
242
|
-
)
|
243
|
-
assert exp_saas_target == saastarget
|
244
|
-
assert exp_deployment == deployment
|
245
|
-
assert repo_changes == RepoChanges("repo1", "commitA", "commitB")
|