qontract-reconcile 0.10.1rc889__py3-none-any.whl → 0.10.1rc891__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.1rc889.dist-info → qontract_reconcile-0.10.1rc891.dist-info}/METADATA +1 -1
- {qontract_reconcile-0.10.1rc889.dist-info → qontract_reconcile-0.10.1rc891.dist-info}/RECORD +8 -8
- tools/qontract_cli.py +21 -0
- tools/saas_promotion_state/saas_promotion_state.py +33 -0
- tools/test/test_saas_promotion_state.py +102 -1
- {qontract_reconcile-0.10.1rc889.dist-info → qontract_reconcile-0.10.1rc891.dist-info}/WHEEL +0 -0
- {qontract_reconcile-0.10.1rc889.dist-info → qontract_reconcile-0.10.1rc891.dist-info}/entry_points.txt +0 -0
- {qontract_reconcile-0.10.1rc889.dist-info → qontract_reconcile-0.10.1rc891.dist-info}/top_level.txt +0 -0
{qontract_reconcile-0.10.1rc889.dist-info → qontract_reconcile-0.10.1rc891.dist-info}/METADATA
RENAMED
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: qontract-reconcile
|
3
|
-
Version: 0.10.
|
3
|
+
Version: 0.10.1rc891
|
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
|
{qontract_reconcile-0.10.1rc889.dist-info → qontract_reconcile-0.10.1rc891.dist-info}/RECORD
RENAMED
@@ -812,7 +812,7 @@ tools/app_interface_metrics_exporter.py,sha256=zkwkxdAUAxjdc-pzx2_oJXG25fo0Fnyd5
|
|
812
812
|
tools/app_interface_reporter.py,sha256=uy9eRHf6EdvD8ZY2WYdroGXm18DOdnqVZyxaWN3Bm_0,17724
|
813
813
|
tools/glitchtip_access_reporter.py,sha256=oPBnk_YoDuljU3v0FaChzOwwnk4vap1xEE67QEjzdqs,2948
|
814
814
|
tools/glitchtip_access_revalidation.py,sha256=8kbBJk04mkq28kWoRDDkfCGIF3GRg3pJrFAh1sW0dbk,2821
|
815
|
-
tools/qontract_cli.py,sha256=
|
815
|
+
tools/qontract_cli.py,sha256=lEK5alQqOXQryqdpWwrZPmWUWx3YYL60armyCu4Dguc,123885
|
816
816
|
tools/sd_app_sre_alert_report.py,sha256=e9vAdyenUz2f5c8-z-5WY0wv-SJ9aePKDH2r4IwB6pc,5063
|
817
817
|
tools/template_validation.py,sha256=qpKYaTgk0GOPGa2Ct5_5sKdwIHtCAKIBGzsMPuJU5fw,3371
|
818
818
|
tools/cli_commands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -833,18 +833,18 @@ tools/saas_metrics_exporter/commit_distance/channel.py,sha256=XEAh3eL8TmgMe7V2Bs
|
|
833
833
|
tools/saas_metrics_exporter/commit_distance/commit_distance.py,sha256=pUWaZfZf0TYOwAW0gDdU8cYgTR586J_8S_DWxqHMWNA,3116
|
834
834
|
tools/saas_metrics_exporter/commit_distance/metrics.py,sha256=5-y6n-sGACAS3eJ5ndY-2BFxcd0fxLfhvZmmBHu4JuA,426
|
835
835
|
tools/saas_promotion_state/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
836
|
-
tools/saas_promotion_state/saas_promotion_state.py,sha256=
|
836
|
+
tools/saas_promotion_state/saas_promotion_state.py,sha256=5LJ9rygZ304vxfsIuRfuxueoYRb72EZNKKITEcJ4Mtk,3908
|
837
837
|
tools/sre_checkpoints/__init__.py,sha256=CDaDaywJnmRCLyl_NCcvxi-Zc0hTi_3OdwKiFOyS39I,145
|
838
838
|
tools/sre_checkpoints/util.py,sha256=zEDbGr18ZeHNQwW8pUsr2JRjuXIPz--WAGJxZo9sv_Y,894
|
839
839
|
tools/test/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
840
840
|
tools/test/conftest.py,sha256=YLtiauk_StNFE-lirLnfG_BpJmlB2NGMZISE9A4zwvk,2421
|
841
841
|
tools/test/test_app_interface_metrics_exporter.py,sha256=SX7qL3D1SIRKFo95FoQztvftCWEEf-g1mfXOtgCog-g,1271
|
842
842
|
tools/test/test_qontract_cli.py,sha256=_D61RFGAN5x44CY1tYbouhlGXXABwYfxKSWSQx3Jrss,4941
|
843
|
-
tools/test/test_saas_promotion_state.py,sha256=
|
843
|
+
tools/test/test_saas_promotion_state.py,sha256=dy4kkSSAQ7bC0Xp2CociETGN-2aABEfL6FU5D9Jl00Y,6056
|
844
844
|
tools/test/test_sd_app_sre_alert_report.py,sha256=v363r9zM7__0kR5K6mvJoGFcM9BvE33fWAayrqkpojA,2116
|
845
845
|
tools/test/test_sre_checkpoints.py,sha256=SKqPPTl9ua0RFdSSofnoQX-JZE6dFLO3LRhfQzqtfh8,2607
|
846
|
-
qontract_reconcile-0.10.
|
847
|
-
qontract_reconcile-0.10.
|
848
|
-
qontract_reconcile-0.10.
|
849
|
-
qontract_reconcile-0.10.
|
850
|
-
qontract_reconcile-0.10.
|
846
|
+
qontract_reconcile-0.10.1rc891.dist-info/METADATA,sha256=VHFngce2-Z5G085gT1WzeoGZ2wj8M4njctG48i9QHHw,2273
|
847
|
+
qontract_reconcile-0.10.1rc891.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
|
848
|
+
qontract_reconcile-0.10.1rc891.dist-info/entry_points.txt,sha256=GKQqCl2j2X1BJQ69een6rHcR26PmnxnONLNOQB-nRjY,491
|
849
|
+
qontract_reconcile-0.10.1rc891.dist-info/top_level.txt,sha256=l5ISPoXzt0SdR4jVdkfa7RPSKNc8zAHYWAnR-Dw8Ey8,24
|
850
|
+
qontract_reconcile-0.10.1rc891.dist-info/RECORD,,
|
tools/qontract_cli.py
CHANGED
@@ -3690,6 +3690,27 @@ def get_promotion_state(channel: str, sha: str):
|
|
3690
3690
|
print(state)
|
3691
3691
|
|
3692
3692
|
|
3693
|
+
@root.command()
|
3694
|
+
@click.option("--channel", help="the channel that state is part of")
|
3695
|
+
@click.option("--sha", help="the commit sha we want state for")
|
3696
|
+
@click.option("--publisher-id", help="the publisher id we want state for")
|
3697
|
+
@environ(["APP_INTERFACE_STATE_BUCKET"])
|
3698
|
+
def mark_promotion_state_successful(channel: str, sha: str, publisher_id: str):
|
3699
|
+
from tools.saas_promotion_state.saas_promotion_state import (
|
3700
|
+
SaasPromotionState,
|
3701
|
+
)
|
3702
|
+
|
3703
|
+
promotion_state = SaasPromotionState.create(promotion_state=None, saas_files=None)
|
3704
|
+
print(f"Current states for {publisher_id=}")
|
3705
|
+
print(promotion_state.get(channel=channel, sha=sha).get(publisher_id, None))
|
3706
|
+
print()
|
3707
|
+
print("Pushing new state ...")
|
3708
|
+
promotion_state.set_successful(channel=channel, sha=sha, publisher_uid=publisher_id)
|
3709
|
+
print()
|
3710
|
+
print(f"New state for {publisher_id=}")
|
3711
|
+
print(promotion_state.get(channel=channel, sha=sha).get(publisher_id, None))
|
3712
|
+
|
3713
|
+
|
3693
3714
|
@root.command()
|
3694
3715
|
@click.option("--change-type-name")
|
3695
3716
|
@click.option("--role-name")
|
@@ -14,6 +14,14 @@ from reconcile.utils.secret_reader import create_secret_reader
|
|
14
14
|
from reconcile.utils.state import init_state
|
15
15
|
|
16
16
|
|
17
|
+
class SaasPromotionStateException(Exception):
|
18
|
+
pass
|
19
|
+
|
20
|
+
|
21
|
+
class SaasPromotionStateMissingException(Exception):
|
22
|
+
pass
|
23
|
+
|
24
|
+
|
17
25
|
class SaasPromotionState:
|
18
26
|
def __init__(
|
19
27
|
self, promotion_state: PromotionState, saas_files: Iterable[SaasFile]
|
@@ -54,6 +62,31 @@ class SaasPromotionState:
|
|
54
62
|
)
|
55
63
|
}
|
56
64
|
|
65
|
+
def set_successful(self, channel: str, sha: str, publisher_uid: str) -> None:
|
66
|
+
current_data = self._promotion_state.get_promotion_data(
|
67
|
+
sha=sha,
|
68
|
+
channel=channel,
|
69
|
+
target_uid=publisher_uid,
|
70
|
+
use_cache=False,
|
71
|
+
pre_check_sha_exists=False,
|
72
|
+
)
|
73
|
+
|
74
|
+
if not current_data:
|
75
|
+
raise SaasPromotionStateMissingException(
|
76
|
+
f"No promotion state in S3 for given {publisher_uid=} {sha=} {channel=}"
|
77
|
+
)
|
78
|
+
|
79
|
+
if current_data.success:
|
80
|
+
raise SaasPromotionStateException(
|
81
|
+
f"The current promotion state is already marked successful for given {publisher_uid=} {sha=} {channel=}",
|
82
|
+
current_data,
|
83
|
+
)
|
84
|
+
|
85
|
+
current_data.success = True
|
86
|
+
self._promotion_state.publish_promotion_data(
|
87
|
+
data=current_data, sha=sha, channel=channel, target_uid=publisher_uid
|
88
|
+
)
|
89
|
+
|
57
90
|
@staticmethod
|
58
91
|
def create(
|
59
92
|
promotion_state: PromotionState | None, saas_files: Iterable[SaasFile] | None
|
@@ -7,14 +7,18 @@ from unittest.mock import (
|
|
7
7
|
create_autospec,
|
8
8
|
)
|
9
9
|
|
10
|
+
from pytest import raises
|
11
|
+
|
10
12
|
from reconcile.typed_queries.saas_files import SaasFile
|
11
13
|
from reconcile.utils.promotion_state import PromotionData, PromotionState
|
12
14
|
from tools.saas_promotion_state.saas_promotion_state import (
|
13
15
|
SaasPromotionState,
|
16
|
+
SaasPromotionStateException,
|
17
|
+
SaasPromotionStateMissingException,
|
14
18
|
)
|
15
19
|
|
16
20
|
|
17
|
-
def
|
21
|
+
def test_get_saas_promotion_state(
|
18
22
|
saas_files_builder: Callable[[Iterable[Mapping]], list[SaasFile]],
|
19
23
|
) -> None:
|
20
24
|
saas_files = saas_files_builder([
|
@@ -84,3 +88,100 @@ def test_saas_promotion_state(
|
|
84
88
|
target_uid="616af45d7fad7f4eea8d52b8b5e8a058cef82ab0",
|
85
89
|
pre_check_sha_exists=False,
|
86
90
|
)
|
91
|
+
|
92
|
+
|
93
|
+
def test_set_saas_promotion_state_success(
|
94
|
+
saas_files_builder: Callable[[Iterable[Mapping]], list[SaasFile]],
|
95
|
+
) -> None:
|
96
|
+
saas_files = saas_files_builder([{"resourceTemplates": []}])
|
97
|
+
|
98
|
+
current_data = PromotionData(
|
99
|
+
check_in="test1",
|
100
|
+
saas_file="test2",
|
101
|
+
success=False,
|
102
|
+
target_config_hash="test3",
|
103
|
+
)
|
104
|
+
promotion_state = create_autospec(spec=PromotionState)
|
105
|
+
promotion_state.get_promotion_data.return_value = current_data
|
106
|
+
saas_promotion_state = SaasPromotionState.create(
|
107
|
+
promotion_state=promotion_state, saas_files=saas_files
|
108
|
+
)
|
109
|
+
saas_promotion_state.set_successful(
|
110
|
+
channel="test-channel", sha="test-sha", publisher_uid="test-uid"
|
111
|
+
)
|
112
|
+
|
113
|
+
promotion_state.get_promotion_data.assert_called_once_with(
|
114
|
+
sha="test-sha",
|
115
|
+
channel="test-channel",
|
116
|
+
use_cache=False,
|
117
|
+
target_uid="test-uid",
|
118
|
+
pre_check_sha_exists=False,
|
119
|
+
)
|
120
|
+
promotion_state.publish_promotion_data.assert_called_once_with(
|
121
|
+
data=PromotionData(
|
122
|
+
check_in="test1",
|
123
|
+
saas_file="test2",
|
124
|
+
success=True,
|
125
|
+
target_config_hash="test3",
|
126
|
+
),
|
127
|
+
channel="test-channel",
|
128
|
+
sha="test-sha",
|
129
|
+
target_uid="test-uid",
|
130
|
+
)
|
131
|
+
|
132
|
+
|
133
|
+
def test_set_saas_promotion_state_missing(
|
134
|
+
saas_files_builder: Callable[[Iterable[Mapping]], list[SaasFile]],
|
135
|
+
) -> None:
|
136
|
+
saas_files = saas_files_builder([{"resourceTemplates": []}])
|
137
|
+
promotion_state = create_autospec(spec=PromotionState)
|
138
|
+
promotion_state.get_promotion_data.return_value = None
|
139
|
+
saas_promotion_state = SaasPromotionState.create(
|
140
|
+
promotion_state=promotion_state, saas_files=saas_files
|
141
|
+
)
|
142
|
+
|
143
|
+
with raises(SaasPromotionStateMissingException):
|
144
|
+
saas_promotion_state.set_successful(
|
145
|
+
channel="test-channel", sha="test-sha", publisher_uid="test-uid"
|
146
|
+
)
|
147
|
+
|
148
|
+
promotion_state.get_promotion_data.assert_called_once_with(
|
149
|
+
sha="test-sha",
|
150
|
+
channel="test-channel",
|
151
|
+
use_cache=False,
|
152
|
+
target_uid="test-uid",
|
153
|
+
pre_check_sha_exists=False,
|
154
|
+
)
|
155
|
+
promotion_state.publish_promotion_data.assert_not_called()
|
156
|
+
|
157
|
+
|
158
|
+
def test_set_saas_promotion_state_already_successful(
|
159
|
+
saas_files_builder: Callable[[Iterable[Mapping]], list[SaasFile]],
|
160
|
+
) -> None:
|
161
|
+
saas_files = saas_files_builder([{"resourceTemplates": []}])
|
162
|
+
|
163
|
+
current_data = PromotionData(
|
164
|
+
check_in="test1",
|
165
|
+
saas_file="test2",
|
166
|
+
success=True,
|
167
|
+
target_config_hash="test3",
|
168
|
+
)
|
169
|
+
promotion_state = create_autospec(spec=PromotionState)
|
170
|
+
promotion_state.get_promotion_data.return_value = current_data
|
171
|
+
saas_promotion_state = SaasPromotionState.create(
|
172
|
+
promotion_state=promotion_state, saas_files=saas_files
|
173
|
+
)
|
174
|
+
|
175
|
+
with raises(SaasPromotionStateException):
|
176
|
+
saas_promotion_state.set_successful(
|
177
|
+
channel="test-channel", sha="test-sha", publisher_uid="test-uid"
|
178
|
+
)
|
179
|
+
|
180
|
+
promotion_state.get_promotion_data.assert_called_once_with(
|
181
|
+
sha="test-sha",
|
182
|
+
channel="test-channel",
|
183
|
+
use_cache=False,
|
184
|
+
target_uid="test-uid",
|
185
|
+
pre_check_sha_exists=False,
|
186
|
+
)
|
187
|
+
promotion_state.publish_promotion_data.assert_not_called()
|
File without changes
|
File without changes
|
{qontract_reconcile-0.10.1rc889.dist-info → qontract_reconcile-0.10.1rc891.dist-info}/top_level.txt
RENAMED
File without changes
|