qontract-reconcile 0.10.1rc758__py3-none-any.whl → 0.10.1rc759__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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: qontract-reconcile
3
- Version: 0.10.1rc758
3
+ Version: 0.10.1rc759
4
4
  Summary: Collection of tools to reconcile services with their desired state as defined in the app-interface DB.
5
5
  Home-page: https://github.com/app-sre/qontract-reconcile
6
6
  Author: Red Hat App-SRE Team
@@ -437,7 +437,7 @@ reconcile/terraform_init/integration.py,sha256=xcFKTc_or3xB3kE_I3OECNkkgbwALIwwd
437
437
  reconcile/terraform_init/merge_request.py,sha256=3CYtgSd7Q9zjKg4wsDz437EPCRfGeZZ8fZ0Y-ChKXJY,1475
438
438
  reconcile/terraform_init/merge_request_manager.py,sha256=fMcT6hbdEF3nFATJpvr8BedvQHq_MzFkgVJSloBNwOQ,3101
439
439
  reconcile/test/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
440
- reconcile/test/conftest.py,sha256=rQousYrxUz-EwAIbsYO6bIwR1B4CrOz9y_zaUVo2lfI,4466
440
+ reconcile/test/conftest.py,sha256=0pO4UxFeBALKbL9gwemyap0VkbPR8n5TtZbf5c9pSv0,4303
441
441
  reconcile/test/fixtures.py,sha256=9SDWAUlSd1rCx7z3GhULHcpr-I6FyCsXxaFAZIqYQsQ,591
442
442
  reconcile/test/test_acs_notifiers.py,sha256=xf3WL6q6V7KQdTVSx6YI-pa4yzOX3mkvIJomgPUc3Mw,12746
443
443
  reconcile/test/test_acs_policies.py,sha256=8pwnXpAO-0OI-6oubjf_oPPlpZjVldeZfJJ9uhsNMWM,17579
@@ -455,7 +455,7 @@ reconcile/test/test_cli.py,sha256=qx_iBwh4Z-YkK3sbjK1wEziPTgn060EN-baf9DNvR3k,10
455
455
  reconcile/test/test_closedbox_endpoint_monitoring.py,sha256=isMHYwRWMFARU2nbJgbl69kD6H0eA86noCM4MPVI1fo,7151
456
456
  reconcile/test/test_dashdotdb_dora.py,sha256=MfHGAsX2eSQSvBVt9_1Sah3aQKNJBXA9Iu86X0NWD6c,7705
457
457
  reconcile/test/test_database_access_manager.py,sha256=-9fYo8wMNhbJUTK_bd7g_fS5zYsAlqQ0rBDDYBMZvZQ,19595
458
- reconcile/test/test_deadmanssnitch.py,sha256=qtn1zwWgIQYw5JULLPvDLaj0GWiecYnvky0HcuETjdo,9843
458
+ reconcile/test/test_deadmanssnitch.py,sha256=YAf8wlZoEC60Ul7UA6Y6XqwnZ1yqf07J15ABqeLpqW4,9835
459
459
  reconcile/test/test_gabi_authorized_users.py,sha256=6XnV5Q9inxP81ktGMVKyWucjBTUj8Imy2L0HG3YHyUE,2496
460
460
  reconcile/test/test_gcr_mirror.py,sha256=A0y8auKZzr62-mGoxSQ__JnN0-ijZUltzjwR5miBgso,490
461
461
  reconcile/test/test_github_org.py,sha256=j3KeB4OnSln1gm2hidce49xdMru-j75NS3cM-AEgzZc,4511
@@ -513,7 +513,7 @@ reconcile/test/test_terraform_users.py,sha256=XOAfGvITCJPI1LTlISmHbA4ONMQMkxYUMT
513
513
  reconcile/test/test_terraform_vpc_peerings.py,sha256=ubcsKh0TrUIwuI1-W3ETIgzsFvzAyeoFmEJFC-IK6JY,20538
514
514
  reconcile/test/test_terraform_vpc_peerings_build_desired_state.py,sha256=DAfpb12I0PlqnuVUHK2vh4LH4d1OylT3H2GE_3TGZZI,47852
515
515
  reconcile/test/test_three_way_diff_strategy.py,sha256=2fjEqE2w4pIzKq18PRcADTSe01aGwsZfMGloU8xfNaE,3346
516
- reconcile/test/test_unleash.py,sha256=c1s_FRAZrAzzd3FbZrzHYjJzHELhoxPHBZnEzqsfMQg,6416
516
+ reconcile/test/test_unleash.py,sha256=krPgOVmwTE6lb773040Ely9BPbNYOeOIY0_8BK72dgo,6690
517
517
  reconcile/test/test_utils_jinja2.py,sha256=TpzQlpFnLGzNEZp5WOh0o7AuBiGEktqO4MuwiiJW2YY,3895
518
518
  reconcile/test/test_vault_replication.py,sha256=wlc4jm9f8P641UvvxIFFFc5_unJysNkOVrKJscjhQr0,16867
519
519
  reconcile/test/test_vault_utils.py,sha256=vbJnc89XAuE07qbTuWxHM5o9F6R9SO5aHXA38fwxT7A,1122
@@ -597,7 +597,7 @@ reconcile/utils/binary.py,sha256=EsOGg82Y2QJh91SGJE0tYpBKqU0iaaagQVoYONBtQn8,235
597
597
  reconcile/utils/config.py,sha256=aId5zrPjM_84u_T4yTRE_Psu3zo5-5_JCR6_7Wgv5UQ,990
598
598
  reconcile/utils/constants.py,sha256=pOUd97bqZdsAu5RWJ8NUs9cwCY7K9y0eW9VVeJ4fZIU,138
599
599
  reconcile/utils/data_structures.py,sha256=VyKfnlNJTiRvZKNpfgIrjESQ2YgmEpWuPQXT14WA1vI,311
600
- reconcile/utils/deadmanssnitch_api.py,sha256=hkfbfbRAhzLpI39o6Du7FZKVtf4UVJ1OljOQNUkmODM,2478
600
+ reconcile/utils/deadmanssnitch_api.py,sha256=OWwkqZxjLRNNfFrfZt-zJ4H1hm4OHg5EZ6lP55APOZc,2493
601
601
  reconcile/utils/defer.py,sha256=SniUsbgOEs9Pa8JkecLu0F94O63yQPByKXaElDYe0FI,377
602
602
  reconcile/utils/differ.py,sha256=kJmUp9ZffFPSUEviaAw3s9c92ErwRJeHaRexGPai7wA,7643
603
603
  reconcile/utils/disabled_integrations.py,sha256=avdDsFyl_LdTsrPVzlcIhWzT_V4C4MXw1ZC__aOtluE,1126
@@ -651,12 +651,12 @@ reconcile/utils/promtool.py,sha256=kT2rFZSBaRqW7SSHAuYzGZzQxM5Dzk8KW1NnEUYZU_s,2
651
651
  reconcile/utils/quay_api.py,sha256=EuOegpb-7ntEjkKLFwM2Oo4Nw7SyFtmyl3sQ9aXMtrM,8152
652
652
  reconcile/utils/raw_github_api.py,sha256=ZHC-SZuAyRe1zaMoOU7Krt1-zecDxENd9c_NzQYqK9g,2968
653
653
  reconcile/utils/repo_owners.py,sha256=j-pUjc9PuDzq7KpjNLpnhqfU8tUG4nj2WMhFp4ick7g,6629
654
- reconcile/utils/rest_api_base.py,sha256=uXLdXocNmRCxJsYFWOdUNLaTEu-dcxMLJg_CwRefETE,3970
654
+ reconcile/utils/rest_api_base.py,sha256=X5o4idyRCDzwnF5xFwmjyoaHmM1tXSZnykTA54Z7D2Q,4006
655
655
  reconcile/utils/ruamel.py,sha256=FzL4_L0FnMOUZmgThrZSMJs5MTdXwiy-E9MZWfk8bh8,397
656
656
  reconcile/utils/secret_reader.py,sha256=2DeYAAQFjUULEKlLw3UDAUoND6gbqvCh9uKPtlc-0us,10403
657
657
  reconcile/utils/semver_helper.py,sha256=-WfPOMSA2v1h7hT3PwVf-Htg7wOsoKlQC1JdmDX2Ars,1268
658
658
  reconcile/utils/sharding.py,sha256=gkYf0lD3IUKQPEmdRJZ70mdDT1c9qWjbdP7evRsUis4,839
659
- reconcile/utils/slack_api.py,sha256=OPmzU6L9rJx2XXDlZkMlxLjOWu17yC-fVCoUItzQrXw,16295
659
+ reconcile/utils/slack_api.py,sha256=C-VThgYRtrRWraq9ZE6hEf1bXrwzRDCDK0uRw3DP6ew,16425
660
660
  reconcile/utils/smtp_client.py,sha256=gJNbBQJpAt5PX4t_TaeNHsXM8vt50bFgndml6yK2b5o,2800
661
661
  reconcile/utils/sqs_gateway.py,sha256=gFl9DM4DmGnptuxTOe4lS3YTyE80eSAvK42ljS8h4dA,2287
662
662
  reconcile/utils/state.py,sha256=FK8NLT1xyumuXpYRm0Nk6pWpOE_U6-NovGn6zKCw8vw,16298
@@ -783,8 +783,8 @@ tools/test/test_app_interface_metrics_exporter.py,sha256=SX7qL3D1SIRKFo95FoQztvf
783
783
  tools/test/test_qontract_cli.py,sha256=w2l4BHB09k1d-BGJ1jBUNCqDv7zkqYrMHojQXg-21kQ,4155
784
784
  tools/test/test_sd_app_sre_alert_report.py,sha256=v363r9zM7__0kR5K6mvJoGFcM9BvE33fWAayrqkpojA,2116
785
785
  tools/test/test_sre_checkpoints.py,sha256=SKqPPTl9ua0RFdSSofnoQX-JZE6dFLO3LRhfQzqtfh8,2607
786
- qontract_reconcile-0.10.1rc758.dist-info/METADATA,sha256=AV5BARka8wT3N8-xnQvmBspzkrCa7ewkyMWLaQ2xb-s,2382
787
- qontract_reconcile-0.10.1rc758.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
788
- qontract_reconcile-0.10.1rc758.dist-info/entry_points.txt,sha256=rIxI5zWtHNlfpDeq1a7pZXAPoqf7HG32KMTN3MeWK_8,429
789
- qontract_reconcile-0.10.1rc758.dist-info/top_level.txt,sha256=l5ISPoXzt0SdR4jVdkfa7RPSKNc8zAHYWAnR-Dw8Ey8,24
790
- qontract_reconcile-0.10.1rc758.dist-info/RECORD,,
786
+ qontract_reconcile-0.10.1rc759.dist-info/METADATA,sha256=N17GmMBM1N_QQwB544Gd7bz5DTOnTnT4o284Cj2JVgI,2382
787
+ qontract_reconcile-0.10.1rc759.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
788
+ qontract_reconcile-0.10.1rc759.dist-info/entry_points.txt,sha256=rIxI5zWtHNlfpDeq1a7pZXAPoqf7HG32KMTN3MeWK_8,429
789
+ qontract_reconcile-0.10.1rc759.dist-info/top_level.txt,sha256=l5ISPoXzt0SdR4jVdkfa7RPSKNc8zAHYWAnR-Dw8Ey8,24
790
+ qontract_reconcile-0.10.1rc759.dist-info/RECORD,,
@@ -12,10 +12,10 @@ from typing import (
12
12
  )
13
13
  from unittest.mock import create_autospec
14
14
 
15
- import httpretty as _httpretty
16
15
  import pytest
17
16
  from pydantic import BaseModel
18
17
  from pydantic.error_wrappers import ValidationError
18
+ from pytest_httpserver import HTTPServer
19
19
 
20
20
  from reconcile.gql_definitions.fragments.vault_secret import VaultSecret
21
21
  from reconcile.test.fixtures import Fixtures
@@ -29,13 +29,6 @@ def patch_sleep(mocker):
29
29
  yield mocker.patch.object(time, "sleep")
30
30
 
31
31
 
32
- @pytest.fixture()
33
- def httpretty():
34
- with _httpretty.enabled(allow_net_connect=False):
35
- _httpretty.reset()
36
- yield _httpretty
37
-
38
-
39
32
  @pytest.fixture
40
33
  def secret_reader(mocker) -> None:
41
34
  mock_secretreader = mocker.patch(
@@ -153,19 +146,18 @@ def gql_api_builder() -> Callable[[Optional[Mapping]], GqlApi]:
153
146
 
154
147
 
155
148
  @pytest.fixture
156
- def set_httpretty_responses_based_on_fixture(httpretty: _httpretty) -> Callable:
157
- """Create httpretty responses based fixture files."""
149
+ def set_httpserver_responses_based_on_fixture(httpserver: HTTPServer) -> Callable:
150
+ """Create httpserver responses based fixture files."""
158
151
 
159
- def _(url: str, fx: Fixtures, paths: Iterable[str]) -> None:
152
+ def _(fx: Fixtures, paths: Iterable[str]) -> None:
160
153
  for path in paths:
161
154
  for method in ["get", "post", "put", "patch", "delete"]:
162
- method_file = Path(fx.path(path)) / f"{method}.json"
155
+ method_file = Path(fx.path(path.lstrip("/"))) / f"{method}.json"
163
156
  if method_file.exists():
164
- httpretty.register_uri(
165
- getattr(httpretty, method.upper()),
166
- f"{url}/{path}",
167
- body=method_file.read_text(),
168
- content_type="text/json",
157
+ httpserver.expect_oneshot_request(
158
+ path, method=method
159
+ ).respond_with_data(
160
+ method_file.read_text(), content_type="text/json"
169
161
  )
170
162
 
171
163
  return _
@@ -20,7 +20,7 @@ from reconcile.utils.deadmanssnitch_api import (
20
20
 
21
21
 
22
22
  @pytest.fixture
23
- def deadmanssnitch_api() -> MockerFixture:
23
+ def deadmanssnitch_api() -> MagicMock:
24
24
  return create_autospec(DeadMansSnitchApi)
25
25
 
26
26
 
@@ -55,7 +55,7 @@ def secret_reader(mocker: MockerFixture) -> MockerFixture:
55
55
 
56
56
  def test_get_current_state(
57
57
  secret_reader: MagicMock,
58
- deadmanssnitch_api: MockerFixture,
58
+ deadmanssnitch_api: MagicMock,
59
59
  mocker: MockerFixture,
60
60
  deadmanssnitch_settings: DeadMansSnitchSettingsV1,
61
61
  ) -> None:
@@ -1,8 +1,8 @@
1
- import json
2
1
  import os
2
+ from collections.abc import Callable
3
3
 
4
- import httpretty
5
4
  import pytest
5
+ from pytest_httpserver import HTTPServer
6
6
  from UnleashClient.features import Feature
7
7
 
8
8
  import reconcile.utils.unleash
@@ -22,6 +22,75 @@ def reset_client():
22
22
  reconcile.utils.unleash.client = None
23
23
 
24
24
 
25
+ def _setup_unleash_httpserver(features: dict, httpserver: HTTPServer) -> HTTPServer:
26
+ httpserver.expect_request("/client/features").respond_with_json(features)
27
+ httpserver.expect_request("/client/register", method="post").respond_with_data(
28
+ status=202
29
+ )
30
+ return httpserver
31
+
32
+
33
+ @pytest.fixture
34
+ def setup_unleash_disable_cluster_strategy(httpserver: HTTPServer):
35
+ def _(enabled: bool) -> HTTPServer:
36
+ features = {
37
+ "version": 2,
38
+ "features": [
39
+ {
40
+ "strategies": [
41
+ {
42
+ "name": "disableCluster",
43
+ "constraints": [],
44
+ "parameters": {"cluster_name": "foo"},
45
+ },
46
+ ],
47
+ "impressionData": False,
48
+ "enabled": enabled,
49
+ "name": "test-strategies",
50
+ "description": "",
51
+ "project": "default",
52
+ "stale": False,
53
+ "type": "release",
54
+ "variants": [],
55
+ }
56
+ ],
57
+ }
58
+ return _setup_unleash_httpserver(features, httpserver)
59
+
60
+ return _
61
+
62
+
63
+ @pytest.fixture
64
+ def setup_unleash_enable_cluster_strategy(httpserver: HTTPServer):
65
+ def _(enabled: bool) -> HTTPServer:
66
+ features = {
67
+ "version": 2,
68
+ "features": [
69
+ {
70
+ "strategies": [
71
+ {
72
+ "name": "enableCluster",
73
+ "constraints": [],
74
+ "parameters": {"cluster_name": "enabled-cluster"},
75
+ },
76
+ ],
77
+ "impressionData": False,
78
+ "enabled": enabled,
79
+ "name": "test-strategies",
80
+ "description": "",
81
+ "project": "default",
82
+ "stale": False,
83
+ "type": "release",
84
+ "variants": [],
85
+ }
86
+ ],
87
+ }
88
+
89
+ return _setup_unleash_httpserver(features, httpserver)
90
+
91
+ return _
92
+
93
+
25
94
  def test__get_unleash_api_client(mocker):
26
95
  mocked_unleash_client = mocker.patch(
27
96
  "reconcile.utils.unleash.UnleashClient",
@@ -108,42 +177,12 @@ def test_get_feature_toggles(mocker, monkeypatch):
108
177
  assert toggles["bar"] == "enabled"
109
178
 
110
179
 
111
- def setup_unleash_disable_cluster_strategy_httpretty(enabled: bool):
112
- features = {
113
- "version": 2,
114
- "features": [
115
- {
116
- "strategies": [
117
- {
118
- "name": "disableCluster",
119
- "constraints": [],
120
- "parameters": {"cluster_name": "foo"},
121
- },
122
- ],
123
- "impressionData": False,
124
- "enabled": enabled,
125
- "name": "test-strategies",
126
- "description": "",
127
- "project": "default",
128
- "stale": False,
129
- "type": "release",
130
- "variants": [],
131
- }
132
- ],
133
- }
134
-
135
- feature_param = (httpretty.GET, "http://unleash/api/client/features")
136
- httpretty.register_uri(*feature_param, body=json.dumps(features), status=200)
137
-
138
- register_param = (httpretty.POST, "http://unleash/api/client/register")
139
- httpretty.register_uri(*register_param, status=202)
140
-
141
-
142
- @httpretty.activate(allow_net_connect=False)
143
- def test_get_feature_toggle_state_with_strategy(reset_client):
144
- os.environ["UNLEASH_API_URL"] = "http://unleash/api"
180
+ def test_get_feature_toggle_state_with_strategy(
181
+ reset_client: None, setup_unleash_disable_cluster_strategy: Callable
182
+ ):
183
+ httpserver = setup_unleash_disable_cluster_strategy(True)
184
+ os.environ["UNLEASH_API_URL"] = httpserver.url_for("/")
145
185
  os.environ["UNLEASH_CLIENT_ACCESS_TOKEN"] = "bar"
146
- setup_unleash_disable_cluster_strategy_httpretty(True)
147
186
  assert not get_feature_toggle_state(
148
187
  "test-strategies", context={"cluster_name": "foo"}
149
188
  )
@@ -151,53 +190,24 @@ def test_get_feature_toggle_state_with_strategy(reset_client):
151
190
  _shutdown_client()
152
191
 
153
192
 
154
- @httpretty.activate(allow_net_connect=False)
155
- def test_get_feature_toggle_state_disabled_with_strategy(reset_client):
156
- os.environ["UNLEASH_API_URL"] = "http://unleash/api"
193
+ def test_get_feature_toggle_state_disabled_with_strategy(
194
+ reset_client: None, setup_unleash_disable_cluster_strategy: Callable
195
+ ):
196
+ httpserver = setup_unleash_disable_cluster_strategy(False)
197
+ os.environ["UNLEASH_API_URL"] = httpserver.url_for("/")
157
198
  os.environ["UNLEASH_CLIENT_ACCESS_TOKEN"] = "bar"
158
- setup_unleash_disable_cluster_strategy_httpretty(False)
159
199
  assert not get_feature_toggle_state(
160
200
  "test-strategies", context={"cluster_name": "bar"}
161
201
  )
162
202
  _shutdown_client()
163
203
 
164
204
 
165
- def setup_unleash_enable_cluster_strategy_httpretty(enabled: bool):
166
- features = {
167
- "version": 2,
168
- "features": [
169
- {
170
- "strategies": [
171
- {
172
- "name": "enableCluster",
173
- "constraints": [],
174
- "parameters": {"cluster_name": "enabled-cluster"},
175
- },
176
- ],
177
- "impressionData": False,
178
- "enabled": enabled,
179
- "name": "test-strategies",
180
- "description": "",
181
- "project": "default",
182
- "stale": False,
183
- "type": "release",
184
- "variants": [],
185
- }
186
- ],
187
- }
188
-
189
- feature_param = (httpretty.GET, "http://unleash/api/client/features")
190
- httpretty.register_uri(*feature_param, body=json.dumps(features), status=200)
191
-
192
- register_param = (httpretty.POST, "http://unleash/api/client/register")
193
- httpretty.register_uri(*register_param, status=202)
194
-
195
-
196
- @httpretty.activate(allow_net_connect=False)
197
- def test_get_feature_toggle_state_with_enable_cluster_strategy(reset_client):
198
- os.environ["UNLEASH_API_URL"] = "http://unleash/api"
205
+ def test_get_feature_toggle_state_with_enable_cluster_strategy(
206
+ reset_client: None, setup_unleash_enable_cluster_strategy: Callable
207
+ ):
208
+ httpserver = setup_unleash_enable_cluster_strategy(True)
209
+ os.environ["UNLEASH_API_URL"] = httpserver.url_for("/")
199
210
  os.environ["UNLEASH_CLIENT_ACCESS_TOKEN"] = "bar"
200
- setup_unleash_enable_cluster_strategy_httpretty(True)
201
211
  assert get_feature_toggle_state(
202
212
  "test-strategies", context={"cluster_name": "enabled-cluster"}
203
213
  )
@@ -49,10 +49,12 @@ class DeadMansSnitchApi:
49
49
  self.session.close()
50
50
 
51
51
  def get_snitches(self, tags: list[str]) -> list[Snitch]:
52
- full_url = f"{self.url}?tags={','.join(tags)}"
53
52
  logging.debug("Getting snitches for tags:%s", tags)
54
53
  response = self.session.get(
55
- url=full_url, auth=(self.token, ""), timeout=self.timeout
54
+ url=self.url,
55
+ params={"tags": ",".join(tags)},
56
+ auth=(self.token, ""),
57
+ timeout=self.timeout,
56
58
  )
57
59
  response.raise_for_status()
58
60
  snitches = [Snitch(**item) for item in response.json()]
@@ -75,6 +75,7 @@ class ApiBase:
75
75
 
76
76
  def _get(self, url: str) -> dict[str, Any]:
77
77
  response = self.session.get(urljoin(self.host, url), timeout=self.read_timeout)
78
+ response.raise_for_status()
78
79
  return response.json()
79
80
 
80
81
  def _list(
@@ -166,6 +166,7 @@ class SlackApi:
166
166
  api_config: Optional[SlackApiConfig] = None,
167
167
  init_usergroups: bool = True,
168
168
  channel: Optional[str] = None,
169
+ slack_url: Optional[str] = None,
169
170
  **chat_kwargs: Any,
170
171
  ) -> None:
171
172
  """
@@ -187,7 +188,11 @@ class SlackApi:
187
188
  else:
188
189
  self.config = SlackApiConfig()
189
190
 
190
- self._sc = WebClient(token=token, timeout=self.config.timeout)
191
+ self._sc = WebClient(
192
+ token=token,
193
+ timeout=self.config.timeout,
194
+ base_url=slack_url or WebClient.BASE_URL,
195
+ )
191
196
  self._configure_client_retry()
192
197
 
193
198
  self._results: dict[str, Any] = {}