qontract-reconcile 0.10.2.dev257__py3-none-any.whl → 0.10.2.dev258__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.4
2
2
  Name: qontract-reconcile
3
- Version: 0.10.2.dev257
3
+ Version: 0.10.2.dev258
4
4
  Summary: Collection of tools to reconcile services with their desired state as defined in the app-interface DB.
5
5
  Project-URL: homepage, https://github.com/app-sre/qontract-reconcile
6
6
  Project-URL: repository, https://github.com/app-sre/qontract-reconcile
@@ -8,7 +8,7 @@ reconcile/aws_iam_password_reset.py,sha256=FpAqAXngmLFqkOtOjrz_i90qteUyLHJL0GMjo
8
8
  reconcile/aws_support_cases_sos.py,sha256=PDhilxQ4TBxVnxUPIUdTbKEaNUI0wzPiEsB91oHT2fY,3384
9
9
  reconcile/blackbox_exporter_endpoint_monitoring.py,sha256=O1wFp52EyF538c6txaWBs8eMtUIy19gyHZ6VzJ6QXS8,3512
10
10
  reconcile/checkpoint.py,sha256=gjtS8g6KIyKFYlHMSZjAqDUOlVh83nh4go-9yNrhWZU,5016
11
- reconcile/cli.py,sha256=2ZdX3b04aVYqpBYdF81dvbSRUjOxm17n-5ABNiZ8pT4,112157
11
+ reconcile/cli.py,sha256=GJ15k4DljB0aMHvtsX7zxPI-tY1j4DTHpd9FUBPSkKk,112289
12
12
  reconcile/closedbox_endpoint_monitoring_base.py,sha256=_OKz7K7HHw0-gzxeEma8PcUCtd70pRBy7JMoaAm8IVU,4940
13
13
  reconcile/cluster_deployment_mapper.py,sha256=5gumAaRCcFXsabUJ1dnuUy9WrP_FEEM5JnOnE8ch9sE,2326
14
14
  reconcile/dashdotdb_base.py,sha256=83ZWIf5JJk3P_D69y2TmXRcQr6ELJGlv10OM0h7fJVs,4767
@@ -469,7 +469,8 @@ reconcile/rhidp/sso_client/base.py,sha256=EfQ2ewcOKh5idg46UKAkY6z0m_nGQfvnQKffa2
469
469
  reconcile/rhidp/sso_client/integration.py,sha256=kA8g7c38ZBSdrRtyfEqy_WgSreD1PbwY7ZIN-3tZRPc,2221
470
470
  reconcile/rhidp/sso_client/metrics.py,sha256=Tq7tSOsqL3XdcPUdozxqzSPIodUeOV87UCTqpuuqqhw,1013
471
471
  reconcile/saas_auto_promotions_manager/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
472
- reconcile/saas_auto_promotions_manager/integration.py,sha256=PhngUNVQMdZ_7KlIOCokdYqQ2k-XdsvvfCb8BAdSiAA,6889
472
+ reconcile/saas_auto_promotions_manager/dependencies.py,sha256=9OdUadp9NHtXUeFj1da8Rw8NH-3w6AxAZeNpjHdaIqw,3600
473
+ reconcile/saas_auto_promotions_manager/integration.py,sha256=LE5-S0RTayYFvZRWn2OnAFLFqXNgemA5WZkTnr7dtmQ,4415
473
474
  reconcile/saas_auto_promotions_manager/meta.py,sha256=76Jp50r6Y_KyJoXFfSjrt5YrCtXyg_A4FXXxHYiS3TE,161
474
475
  reconcile/saas_auto_promotions_manager/publisher.py,sha256=5gphMxr2NUvyB7WDK4eAbgZeyeF30cZ3a2ZGrbFQgZk,2976
475
476
  reconcile/saas_auto_promotions_manager/s3_exporter.py,sha256=Y-r5R6viiAzglUHbYKItYSjT_axmLlPEJVmu_H6N170,2682
@@ -796,7 +797,7 @@ tools/saas_promotion_state/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJ
796
797
  tools/saas_promotion_state/saas_promotion_state.py,sha256=oF7C4hpIgyMTwTRm3Aun3cDCHIjVar65JoLp6NcJHlU,3909
797
798
  tools/sre_checkpoints/__init__.py,sha256=CDaDaywJnmRCLyl_NCcvxi-Zc0hTi_3OdwKiFOyS39I,145
798
799
  tools/sre_checkpoints/util.py,sha256=zEDbGr18ZeHNQwW8pUsr2JRjuXIPz--WAGJxZo9sv_Y,894
799
- qontract_reconcile-0.10.2.dev257.dist-info/METADATA,sha256=hzKI6s9NpHkpbiHIReBsUFBmMZW6-ZhXvLnjjJJIW0s,23827
800
- qontract_reconcile-0.10.2.dev257.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
801
- qontract_reconcile-0.10.2.dev257.dist-info/entry_points.txt,sha256=5i9l54La3vQrDLAdwDKQWC0iG4sV9RRfOb1BpvzOWLc,698
802
- qontract_reconcile-0.10.2.dev257.dist-info/RECORD,,
800
+ qontract_reconcile-0.10.2.dev258.dist-info/METADATA,sha256=UC6zLDyB42JRp2BvSXJZxOKr6zcWg_3x9yW7Tfmfzxk,23827
801
+ qontract_reconcile-0.10.2.dev258.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
802
+ qontract_reconcile-0.10.2.dev258.dist-info/entry_points.txt,sha256=5i9l54La3vQrDLAdwDKQWC0iG4sV9RRfOb1BpvzOWLc,698
803
+ qontract_reconcile-0.10.2.dev258.dist-info/RECORD,,
reconcile/cli.py CHANGED
@@ -2375,14 +2375,18 @@ def saas_auto_promotions_manager(
2375
2375
  env_name: str | None,
2376
2376
  app_name: str | None,
2377
2377
  ) -> None:
2378
- import reconcile.saas_auto_promotions_manager.integration
2378
+ from reconcile.saas_auto_promotions_manager.integration import (
2379
+ SaasAutoPromotionsManager,
2380
+ )
2379
2381
 
2380
- run_integration(
2381
- reconcile.saas_auto_promotions_manager.integration,
2382
- ctx,
2383
- thread_pool_size,
2384
- env_name=env_name,
2385
- app_name=app_name,
2382
+ run_class_integration(
2383
+ integration=SaasAutoPromotionsManager.create(
2384
+ env_name=env_name,
2385
+ app_name=app_name,
2386
+ thread_pool_size=thread_pool_size,
2387
+ dry_run=ctx.obj["dry_run"],
2388
+ ),
2389
+ ctx=ctx,
2386
2390
  )
2387
2391
 
2388
2392
 
@@ -0,0 +1,95 @@
1
+ from typing import Self
2
+
3
+ from reconcile.openshift_saas_deploy import (
4
+ QONTRACT_INTEGRATION as OPENSHIFT_SAAS_DEPLOY,
5
+ )
6
+ from reconcile.saas_auto_promotions_manager.meta import QONTRACT_INTEGRATION
7
+ from reconcile.saas_auto_promotions_manager.utils.saas_files_inventory import (
8
+ SaasFilesInventory,
9
+ )
10
+ from reconcile.typed_queries.app_interface_repo_url import get_app_interface_repo_url
11
+ from reconcile.typed_queries.app_interface_vault_settings import (
12
+ get_app_interface_vault_settings,
13
+ )
14
+ from reconcile.typed_queries.github_orgs import get_github_orgs
15
+ from reconcile.typed_queries.gitlab_instances import get_gitlab_instances
16
+ from reconcile.typed_queries.saas_files import get_saas_files
17
+ from reconcile.utils.promotion_state import PromotionState
18
+ from reconcile.utils.secret_reader import SecretReaderBase, create_secret_reader
19
+ from reconcile.utils.state import State, init_state
20
+ from reconcile.utils.unleash import get_feature_toggle_state
21
+ from reconcile.utils.vcs import VCS
22
+
23
+
24
+ class Dependencies:
25
+ """
26
+ Dependencies class to hold all the external dependencies (API clients, state, etc.) for SAPM.
27
+ Dependency inversion simplifies setting up tests and centralizes dependency management.
28
+ """
29
+
30
+ def __init__(
31
+ self,
32
+ secret_reader: SecretReaderBase,
33
+ deployment_state: PromotionState,
34
+ vcs: VCS,
35
+ saas_file_inventory: SaasFilesInventory,
36
+ saas_deploy_state: State,
37
+ sapm_state: State,
38
+ ):
39
+ self.secret_reader = secret_reader
40
+ self.deployment_state = deployment_state
41
+ self.vcs = vcs
42
+ self.saas_file_inventory = saas_file_inventory
43
+ self.saas_deploy_state = saas_deploy_state
44
+ self.sapm_state = sapm_state
45
+
46
+ @classmethod
47
+ def create(
48
+ cls,
49
+ dry_run: bool,
50
+ thread_pool_size: int,
51
+ env_name: str | None = None,
52
+ app_name: str | None = None,
53
+ ) -> Self:
54
+ vault_settings = get_app_interface_vault_settings()
55
+ allow_deleting_mrs = get_feature_toggle_state(
56
+ integration_name=f"{QONTRACT_INTEGRATION}-allow-deleting-mrs",
57
+ default=False,
58
+ )
59
+ allow_opening_mrs = get_feature_toggle_state(
60
+ integration_name=f"{QONTRACT_INTEGRATION}-allow-opening-mrs",
61
+ default=False,
62
+ )
63
+ secret_reader = create_secret_reader(use_vault=vault_settings.vault)
64
+ vcs = VCS(
65
+ secret_reader=secret_reader,
66
+ github_orgs=get_github_orgs(),
67
+ gitlab_instances=get_gitlab_instances(),
68
+ app_interface_repo_url=get_app_interface_repo_url(),
69
+ dry_run=dry_run,
70
+ allow_deleting_mrs=allow_deleting_mrs,
71
+ allow_opening_mrs=allow_opening_mrs,
72
+ )
73
+ saas_files = get_saas_files(env_name=env_name, app_name=app_name)
74
+ saas_inventory = SaasFilesInventory(
75
+ saas_files=saas_files,
76
+ secret_reader=secret_reader,
77
+ thread_pool_size=thread_pool_size,
78
+ )
79
+ saas_deploy_state = init_state(
80
+ integration=OPENSHIFT_SAAS_DEPLOY, secret_reader=secret_reader
81
+ )
82
+ deployment_state = PromotionState(
83
+ state=saas_deploy_state,
84
+ )
85
+ sapm_state = init_state(
86
+ integration=QONTRACT_INTEGRATION, secret_reader=secret_reader
87
+ )
88
+ return cls(
89
+ secret_reader=secret_reader,
90
+ deployment_state=deployment_state,
91
+ vcs=vcs,
92
+ saas_file_inventory=saas_inventory,
93
+ saas_deploy_state=saas_deploy_state,
94
+ sapm_state=sapm_state,
95
+ )
@@ -1,13 +1,11 @@
1
+ from __future__ import annotations
2
+
1
3
  from collections.abc import Callable
2
4
 
3
5
  from sretoolbox.utils import threaded
4
6
 
5
- from reconcile.openshift_saas_deploy import (
6
- QONTRACT_INTEGRATION as OPENSHIFT_SAAS_DEPLOY,
7
- )
8
- from reconcile.saas_auto_promotions_manager.merge_request_manager.batcher import (
9
- Batcher,
10
- )
7
+ from reconcile.saas_auto_promotions_manager.dependencies import Dependencies
8
+ from reconcile.saas_auto_promotions_manager.merge_request_manager.batcher import Batcher
11
9
  from reconcile.saas_auto_promotions_manager.merge_request_manager.merge_request_manager_v2 import (
12
10
  MergeRequestManagerV2,
13
11
  )
@@ -21,189 +19,111 @@ from reconcile.saas_auto_promotions_manager.meta import QONTRACT_INTEGRATION
21
19
  from reconcile.saas_auto_promotions_manager.publisher import Publisher
22
20
  from reconcile.saas_auto_promotions_manager.s3_exporter import S3Exporter
23
21
  from reconcile.saas_auto_promotions_manager.subscriber import Subscriber
24
- from reconcile.saas_auto_promotions_manager.utils.saas_files_inventory import (
25
- SaasFilesInventory,
26
- )
27
- from reconcile.typed_queries.app_interface_repo_url import get_app_interface_repo_url
28
- from reconcile.typed_queries.app_interface_vault_settings import (
29
- get_app_interface_vault_settings,
30
- )
31
- from reconcile.typed_queries.github_orgs import get_github_orgs
32
- from reconcile.typed_queries.gitlab_instances import get_gitlab_instances
33
- from reconcile.typed_queries.saas_files import get_saas_files
34
22
  from reconcile.utils.defer import defer
35
- from reconcile.utils.promotion_state import PromotionState
36
- from reconcile.utils.secret_reader import create_secret_reader
37
- from reconcile.utils.state import State, init_state
38
- from reconcile.utils.unleash import get_feature_toggle_state
39
- from reconcile.utils.vcs import VCS
23
+ from reconcile.utils.runtime.integration import (
24
+ PydanticRunParams,
25
+ QontractReconcileIntegration,
26
+ )
40
27
 
41
28
 
42
- class SaasAutoPromotionsManager:
43
- def __init__(
44
- self,
45
- deployment_state: PromotionState,
46
- vcs: VCS,
47
- saas_file_inventory: SaasFilesInventory,
48
- merge_request_manager_v2: MergeRequestManagerV2,
49
- s3_exporter: S3Exporter,
50
- thread_pool_size: int,
29
+ class SaasAutoPromotionsManagerParams(PydanticRunParams):
30
+ thread_pool_size: int
31
+ env_name: str | None
32
+ app_name: str | None
33
+
34
+
35
+ class SaasAutoPromotionsManager(
36
+ QontractReconcileIntegration[SaasAutoPromotionsManagerParams]
37
+ ):
38
+ @classmethod
39
+ def create(
40
+ cls,
51
41
  dry_run: bool,
42
+ thread_pool_size: int,
43
+ env_name: str | None = None,
44
+ app_name: str | None = None,
45
+ ) -> SaasAutoPromotionsManager:
46
+ dependencies = Dependencies.create(
47
+ dry_run=dry_run,
48
+ thread_pool_size=thread_pool_size,
49
+ env_name=env_name,
50
+ app_name=app_name,
51
+ )
52
+ params = SaasAutoPromotionsManagerParams(
53
+ thread_pool_size=thread_pool_size,
54
+ env_name=env_name,
55
+ app_name=app_name,
56
+ )
57
+ return cls(dependencies=dependencies, params=params)
58
+
59
+ def __init__(
60
+ self, dependencies: Dependencies, params: SaasAutoPromotionsManagerParams
52
61
  ):
53
- self._deployment_state = deployment_state
54
- self._vcs = vcs
55
- self._saas_file_inventory = saas_file_inventory
56
- self._merge_request_manager_v2 = merge_request_manager_v2
57
- self._s3_exporter = s3_exporter
58
- self._thread_pool_size = thread_pool_size
59
- self._dry_run = dry_run
62
+ super().__init__(params)
63
+ self._dependencies = dependencies
60
64
 
61
65
  def _fetch_publisher_state(
62
66
  self,
63
67
  publisher: Publisher,
64
68
  ) -> None:
65
69
  publisher.fetch_commit_shas_and_deployment_info(
66
- vcs=self._vcs,
67
- deployment_state=self._deployment_state,
70
+ vcs=self._dependencies.vcs,
71
+ deployment_state=self._dependencies.deployment_state,
68
72
  )
69
73
 
70
- def _fetch_publisher_real_world_states(self) -> None:
74
+ def _fetch_publisher_real_world_states(self, thread_pool_size: int) -> None:
71
75
  threaded.run(
72
76
  self._fetch_publisher_state,
73
- self._saas_file_inventory.publishers,
74
- thread_pool_size=self._thread_pool_size,
77
+ self._dependencies.saas_file_inventory.publishers,
78
+ thread_pool_size=thread_pool_size,
75
79
  )
76
80
 
77
81
  def _compute_desired_subscriber_states(self) -> None:
78
- for subscriber in self._saas_file_inventory.subscribers:
82
+ for subscriber in self._dependencies.saas_file_inventory.subscribers:
79
83
  subscriber.compute_desired_state()
80
84
 
81
85
  def _get_subscribers_with_diff(self) -> list[Subscriber]:
82
- return [s for s in self._saas_file_inventory.subscribers if s.has_diff()]
86
+ return [
87
+ s
88
+ for s in self._dependencies.saas_file_inventory.subscribers
89
+ if s.has_diff()
90
+ ]
83
91
 
84
- def reconcile(self) -> None:
85
- self._deployment_state.cache_commit_shas_from_s3()
86
- self._fetch_publisher_real_world_states()
92
+ def reconcile(self, thread_pool_size: int, dry_run: bool) -> None:
93
+ self._dependencies.deployment_state.cache_commit_shas_from_s3()
94
+ self._fetch_publisher_real_world_states(thread_pool_size)
87
95
  self._compute_desired_subscriber_states()
88
96
  subscribers_with_diff = self._get_subscribers_with_diff()
89
- self._merge_request_manager_v2.reconcile(subscribers=subscribers_with_diff)
90
- self._s3_exporter.export_publisher_data(
91
- publishers=self._saas_file_inventory.publishers
97
+
98
+ mr_parser = MRParser(vcs=self._dependencies.vcs)
99
+ merge_request_manager_v2 = MergeRequestManagerV2(
100
+ vcs=self._dependencies.vcs,
101
+ reconciler=Batcher(),
102
+ mr_parser=mr_parser,
103
+ renderer=Renderer(),
104
+ )
105
+ merge_request_manager_v2.reconcile(subscribers=subscribers_with_diff)
106
+
107
+ s3_exporter = S3Exporter(
108
+ state=self._dependencies.sapm_state,
109
+ dry_run=dry_run,
110
+ )
111
+ s3_exporter.export_publisher_data(
112
+ publishers=self._dependencies.saas_file_inventory.publishers
92
113
  )
93
114
 
115
+ @property
116
+ def name(self) -> str:
117
+ return QONTRACT_INTEGRATION
94
118
 
95
- def init_external_dependencies(
96
- dry_run: bool,
97
- thread_pool_size: int,
98
- env_name: str | None = None,
99
- app_name: str | None = None,
100
- ) -> tuple[
101
- PromotionState,
102
- VCS,
103
- SaasFilesInventory,
104
- MergeRequestManagerV2,
105
- S3Exporter,
106
- State,
107
- State,
108
- ]:
109
- """
110
- Lets initialize everything that involves calls to external dependencies:
111
- - VCS -> Gitlab / Github queries
112
- - SaaSFileInventory -> qontract-server GQL query
113
- - DeploymentState -> S3 queries
114
- - MergeRequestManager -> Managing SAPM MRs with app-interface
115
- """
116
- vault_settings = get_app_interface_vault_settings()
117
- allow_deleting_mrs = get_feature_toggle_state(
118
- integration_name=f"{QONTRACT_INTEGRATION}-allow-deleting-mrs",
119
- default=False,
120
- )
121
- allow_opening_mrs = get_feature_toggle_state(
122
- integration_name=f"{QONTRACT_INTEGRATION}-allow-opening-mrs",
123
- default=False,
124
- )
125
- secret_reader = create_secret_reader(use_vault=vault_settings.vault)
126
- vcs = VCS(
127
- secret_reader=secret_reader,
128
- github_orgs=get_github_orgs(),
129
- gitlab_instances=get_gitlab_instances(),
130
- app_interface_repo_url=get_app_interface_repo_url(),
131
- dry_run=dry_run,
132
- allow_deleting_mrs=allow_deleting_mrs,
133
- allow_opening_mrs=allow_opening_mrs,
134
- )
135
- mr_parser = MRParser(vcs=vcs)
136
- merge_request_manager_v2 = MergeRequestManagerV2(
137
- vcs=vcs,
138
- reconciler=Batcher(),
139
- mr_parser=mr_parser,
140
- renderer=Renderer(),
141
- )
142
- saas_files = get_saas_files(env_name=env_name, app_name=app_name)
143
- saas_inventory = SaasFilesInventory(
144
- saas_files=saas_files,
145
- secret_reader=secret_reader,
146
- thread_pool_size=thread_pool_size,
147
- )
148
- saas_deploy_state = init_state(
149
- integration=OPENSHIFT_SAAS_DEPLOY, secret_reader=secret_reader
150
- )
151
- deployment_state = PromotionState(
152
- state=saas_deploy_state,
153
- )
154
- sapm_state = init_state(
155
- integration=QONTRACT_INTEGRATION, secret_reader=secret_reader
156
- )
157
- s3_exporter = S3Exporter(
158
- state=sapm_state,
159
- dry_run=dry_run,
160
- )
161
- return (
162
- deployment_state,
163
- vcs,
164
- saas_inventory,
165
- merge_request_manager_v2,
166
- s3_exporter,
167
- saas_deploy_state,
168
- sapm_state,
169
- )
170
-
171
-
172
- @defer
173
- def run(
174
- dry_run: bool,
175
- thread_pool_size: int,
176
- env_name: str | None = None,
177
- app_name: str | None = None,
178
- defer: Callable | None = None,
179
- ) -> None:
180
- (
181
- deployment_state,
182
- vcs,
183
- saas_inventory,
184
- merge_request_manager_v2,
185
- s3_exporter,
186
- saas_deploy_state,
187
- sapm_state,
188
- ) = init_external_dependencies(
189
- dry_run=dry_run,
190
- env_name=env_name,
191
- app_name=app_name,
192
- thread_pool_size=thread_pool_size,
193
- )
194
- if defer:
195
- defer(vcs.cleanup)
196
- defer(saas_deploy_state.cleanup)
197
- defer(sapm_state.cleanup)
198
-
199
- integration = SaasAutoPromotionsManager(
200
- deployment_state=deployment_state,
201
- vcs=vcs,
202
- saas_file_inventory=saas_inventory,
203
- merge_request_manager_v2=merge_request_manager_v2,
204
- s3_exporter=s3_exporter,
205
- thread_pool_size=thread_pool_size,
206
- dry_run=dry_run,
207
- )
208
-
209
- integration.reconcile()
119
+ @defer
120
+ def run(
121
+ self,
122
+ dry_run: bool,
123
+ defer: Callable | None = None,
124
+ ) -> None:
125
+ if defer:
126
+ defer(self._dependencies.vcs.cleanup)
127
+ defer(self._dependencies.saas_deploy_state.cleanup)
128
+ defer(self._dependencies.sapm_state.cleanup)
129
+ self.reconcile(thread_pool_size=self.params.thread_pool_size, dry_run=dry_run)