qontract-reconcile 0.9.1rc292__py3-none-any.whl → 0.9.1rc294__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.9.1rc292
3
+ Version: 0.9.1rc294
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
@@ -179,6 +179,7 @@ reconcile/gql_definitions/common/app_interface_state_settings.py,sha256=-u159W10
179
179
  reconcile/gql_definitions/common/app_interface_vault_settings.py,sha256=GEjbO_R9qSWy-tyLoSR8P1usQ3QPA8kxIofd507xJzs,1789
180
180
  reconcile/gql_definitions/common/clusters.py,sha256=qr8gnFH71pYUGijReg0NvaQ7LF8u3pRvp1wG_8a43ig,24303
181
181
  reconcile/gql_definitions/common/clusters_minimal.py,sha256=iYnAPQ7jDtEu06XgkDlltXa2_iJsp56rIfDqEYef-uM,5257
182
+ reconcile/gql_definitions/common/clusters_with_peering.py,sha256=HiAjIcKt9ojihIFXZmYX9ELZDqgpGIWPhmUpoiEEMZY,11985
182
183
  reconcile/gql_definitions/common/github_orgs.py,sha256=G73Oa0oMLpqhaxw23HA_fxoyO2VJOEJh4WSAAz3NF2Y,2043
183
184
  reconcile/gql_definitions/common/namespaces.py,sha256=HNu55aeBQUGr4JfjQFj8sGAE2SILh_TtTT6LmsHfwPo,9161
184
185
  reconcile/gql_definitions/common/namespaces_minimal.py,sha256=0n9f2ldd_aEN9tzcqKvtzZ53ceH-1v411vVkD8wPaeY,3539
@@ -267,12 +268,12 @@ reconcile/prometheus_rules_tester/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeR
267
268
  reconcile/prometheus_rules_tester/integration.py,sha256=Sn6mjzC2lJQVcETS1J2Z3tOwm8M3DDW-1GVT-5ccNuA,8860
268
269
  reconcile/saas_auto_promotions_manager/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
269
270
  reconcile/saas_auto_promotions_manager/integration.py,sha256=hmRWva3_ZEO845wMkttEt4X6Izl5p8ZKs09NXWp8mkY,5609
270
- reconcile/saas_auto_promotions_manager/publisher.py,sha256=gdzR7jNDKy130pO6J-UNwXI__EXgiREzdaXvNkE3Bhg,1845
271
- reconcile/saas_auto_promotions_manager/subscriber.py,sha256=XCXJh_Otr2H3dkIXt7AiTNwCi3mRsT4BsNz0xipCv_Y,6699
271
+ reconcile/saas_auto_promotions_manager/publisher.py,sha256=Oi7QMlxY56NXO2W4NnB7kSeL-7Ef3oY75mIccoLWBwg,1980
272
+ reconcile/saas_auto_promotions_manager/subscriber.py,sha256=8w9q1ceA2XnuTntThg8v6mE3K28aG2Y2DwQSuTudkns,6942
272
273
  reconcile/saas_auto_promotions_manager/merge_request_manager/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
273
- reconcile/saas_auto_promotions_manager/merge_request_manager/merge_request.py,sha256=diDb4BkErloZF6MfzQbMkqC1gx8tglYkw10Vuf_4_Ho,1147
274
- reconcile/saas_auto_promotions_manager/merge_request_manager/merge_request_manager.py,sha256=QVaaL0hQn0fy-NPmoKyJMp3NxNfE8umYjReaTztxCps,9763
275
- reconcile/saas_auto_promotions_manager/merge_request_manager/renderer.py,sha256=2_jZO2hhFZmX_YYOQTanTY7N4OrCQASIeM-ppGxkuvc,4637
274
+ reconcile/saas_auto_promotions_manager/merge_request_manager/merge_request.py,sha256=PNu7sE-tDUY61E03z5w0b93fdowZ8auCl0S4_vhYOKQ,1333
275
+ reconcile/saas_auto_promotions_manager/merge_request_manager/merge_request_manager.py,sha256=SNJ9WLlaFnf_tblwC0xDBfrXi4SVadeFgV3llhTqbGM,10959
276
+ reconcile/saas_auto_promotions_manager/merge_request_manager/renderer.py,sha256=Ye3lmfWTbuHjMoCEOpGnGRK3QU0LwB_LVfnPXFdNxf4,4702
276
277
  reconcile/saas_auto_promotions_manager/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
277
278
  reconcile/saas_auto_promotions_manager/utils/saas_files_inventory.py,sha256=LEK_635Vt7VPWnhVonn54JxkfUKCehX3_6bJfD8zKbI,8597
278
279
  reconcile/saas_auto_promotions_manager/utils/vcs.py,sha256=wIB3DUazVpmysKuKmHZZ_yG9d04givRBulXrUuZyOgw,5240
@@ -434,6 +435,7 @@ reconcile/typed_queries/app_interface_state_settings.py,sha256=ytNAf3feg8JwmdCC4
434
435
  reconcile/typed_queries/app_interface_vault_settings.py,sha256=uFS7qLjjGnrK8gm2fkUT8RFd7s_5kxTWWpxZRhr1Ndo,746
435
436
  reconcile/typed_queries/clusters.py,sha256=mjEudUxMl0pqT0CIbDhgRONLQqfhTvDPS4SVyl0zIpM,393
436
437
  reconcile/typed_queries/clusters_minimal.py,sha256=MwFj2F_rqBFDI3sPbR4QbiME6HIYEPhrOyy07i_-oA8,409
438
+ reconcile/typed_queries/clusters_with_peering.py,sha256=lIai7SJJD0bqIJbe7virgrbYRqjLouSL2OpJD0itpAY,330
437
439
  reconcile/typed_queries/github_orgs.py,sha256=UZhoPl8qvA_tcO7CZlN8GuMKckt3ywd47Suu61rgHsc,258
438
440
  reconcile/typed_queries/gitlab_instances.py,sha256=ZVQHy2W9xIp53f5qYkjKLHLHgOVtQpxTfcmM1C2046g,291
439
441
  reconcile/typed_queries/glitchtip_settings.py,sha256=Hwq8H73PTK-ZIysGEqWcPEqYyRjETS91h9odp-T5ce0,721
@@ -470,7 +472,7 @@ reconcile/utils/git_secrets.py,sha256=897nRs7tycA3m7YYeVEbzOhI8RFrI9IJT2E0di1eJh
470
472
  reconcile/utils/github_api.py,sha256=6gdlKK0W3vZpxbbtOcohRgvZ4YkiSki7Gxdb16goHPo,2316
471
473
  reconcile/utils/gitlab_api.py,sha256=Pl92DmudBEf6qRvfBs3T3x2psvrUxOPU5beupzW1ug8,24873
472
474
  reconcile/utils/gpg.py,sha256=EKG7_fdMv8BMlV5yUdPiqoTx-KrzmVSEAl2sLkaKwWI,1123
473
- reconcile/utils/gql.py,sha256=gs0prtFY_Jm_-o4Fobz4hmulW9NL6KYkcrCuyXIIn1s,11622
475
+ reconcile/utils/gql.py,sha256=HcD8vYyX1reV1-7kNzszq6bWPJs7CvbNhPvBYwSE0pE,11655
474
476
  reconcile/utils/helm.py,sha256=IWlB_LrBK6ydwNQuZP2aMJGrtQw0lW7qdFqSrd3r8lg,1321
475
477
  reconcile/utils/helpers.py,sha256=rC6QwVBH40hLz6JrlNBB_UZfApaCrwgdjwlOFE_fG2M,371
476
478
  reconcile/utils/imap_client.py,sha256=byFAJATbITJPsGECSbvXBOcCnoeTUpDFiEjzOAxLm_U,1975
@@ -575,8 +577,8 @@ tools/sre_checkpoints/util.py,sha256=zEDbGr18ZeHNQwW8pUsr2JRjuXIPz--WAGJxZo9sv_Y
575
577
  tools/test/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
576
578
  tools/test/test_qontract_cli.py,sha256=awwTHEc2DWlykuqGIYM0WOBoSL0KRnOraCLk3C7izis,1401
577
579
  tools/test/test_sre_checkpoints.py,sha256=SKqPPTl9ua0RFdSSofnoQX-JZE6dFLO3LRhfQzqtfh8,2607
578
- qontract_reconcile-0.9.1rc292.dist-info/METADATA,sha256=nRRiks-az7sMFQ04oizynlbvYPsNzLvgWAuOyv0EUL0,2287
579
- qontract_reconcile-0.9.1rc292.dist-info/WHEEL,sha256=pkctZYzUS4AYVn6dJ-7367OJZivF2e8RA9b_ZBjif18,92
580
- qontract_reconcile-0.9.1rc292.dist-info/entry_points.txt,sha256=aIVvB7OTCxYu0QkONzBPfFEyg68Pr8KUVKEEm4ChDVc,333
581
- qontract_reconcile-0.9.1rc292.dist-info/top_level.txt,sha256=j0CHPIc8TsVRB50wOz_jhxjjaRyCJB3NOQeXhuHS67c,34
582
- qontract_reconcile-0.9.1rc292.dist-info/RECORD,,
580
+ qontract_reconcile-0.9.1rc294.dist-info/METADATA,sha256=em0hOB9rEHOy04LHmQ0cxqOb4VfdGQeLxCP_Ez88aQw,2287
581
+ qontract_reconcile-0.9.1rc294.dist-info/WHEEL,sha256=pkctZYzUS4AYVn6dJ-7367OJZivF2e8RA9b_ZBjif18,92
582
+ qontract_reconcile-0.9.1rc294.dist-info/entry_points.txt,sha256=aIVvB7OTCxYu0QkONzBPfFEyg68Pr8KUVKEEm4ChDVc,333
583
+ qontract_reconcile-0.9.1rc294.dist-info/top_level.txt,sha256=j0CHPIc8TsVRB50wOz_jhxjjaRyCJB3NOQeXhuHS67c,34
584
+ qontract_reconcile-0.9.1rc294.dist-info/RECORD,,
@@ -0,0 +1,393 @@
1
+ """
2
+ Generated by qenerate plugin=pydantic_v1. DO NOT MODIFY MANUALLY!
3
+ """
4
+ from collections.abc import Callable # noqa: F401 # pylint: disable=W0611
5
+ from datetime import datetime # noqa: F401 # pylint: disable=W0611
6
+ from enum import Enum # noqa: F401 # pylint: disable=W0611
7
+ from typing import ( # noqa: F401 # pylint: disable=W0611
8
+ Any,
9
+ Optional,
10
+ Union,
11
+ )
12
+
13
+ from pydantic import ( # noqa: F401 # pylint: disable=W0611
14
+ BaseModel,
15
+ Extra,
16
+ Field,
17
+ Json,
18
+ )
19
+
20
+ from reconcile.gql_definitions.fragments.aws_infra_management_account import (
21
+ AWSInfrastructureManagementAccount,
22
+ )
23
+ from reconcile.gql_definitions.fragments.ocm_environment import OCMEnvironment
24
+ from reconcile.gql_definitions.fragments.vault_secret import VaultSecret
25
+
26
+
27
+ DEFINITION = """
28
+ fragment AWSInfrastructureManagementAccount on AWSInfrastructureManagementAccount_v1 {
29
+ account {
30
+ name
31
+ uid
32
+ terraformUsername
33
+ resourcesDefaultRegion
34
+ automationToken {
35
+ ... VaultSecret
36
+ }
37
+ }
38
+ accessLevel
39
+ default
40
+ }
41
+
42
+ fragment OCMEnvironment on OpenShiftClusterManagerEnvironment_v1 {
43
+ name
44
+ url
45
+ accessTokenClientId
46
+ accessTokenUrl
47
+ accessTokenClientSecret {
48
+ ... VaultSecret
49
+ }
50
+ }
51
+
52
+ fragment VaultSecret on VaultSecret_v1 {
53
+ path
54
+ field
55
+ version
56
+ format
57
+ }
58
+
59
+ query ClustersWithPeering {
60
+ clusters: clusters_v1
61
+ {
62
+ path
63
+ name
64
+ ocm {
65
+ name
66
+ environment {
67
+ ... OCMEnvironment
68
+ }
69
+ orgId
70
+ accessTokenClientId
71
+ accessTokenUrl
72
+ accessTokenClientSecret {
73
+ ... VaultSecret
74
+ }
75
+ blockedVersions
76
+ }
77
+ awsInfrastructureManagementAccounts {
78
+ ... AWSInfrastructureManagementAccount
79
+ }
80
+
81
+ spec {
82
+ region
83
+ }
84
+ network {
85
+ vpc
86
+ }
87
+ peering {
88
+ connections {
89
+ name
90
+ provider
91
+ manageRoutes
92
+ delete
93
+ ... on ClusterPeeringConnectionAccount_v1 {
94
+ vpc {
95
+ account {
96
+ name
97
+ uid
98
+ terraformUsername
99
+ automationToken {
100
+ ... VaultSecret
101
+ }
102
+ }
103
+ vpc_id
104
+ cidr_block
105
+ region
106
+ }
107
+ assumeRole
108
+ manageAccountRoutes
109
+ }
110
+ ... on ClusterPeeringConnectionAccountVPCMesh_v1 {
111
+ account {
112
+ name
113
+ uid
114
+ terraformUsername
115
+ automationToken {
116
+ ... VaultSecret
117
+ }
118
+ }
119
+ tags
120
+ }
121
+ ... on ClusterPeeringConnectionAccountTGW_v1 {
122
+ account {
123
+ name
124
+ uid
125
+ terraformUsername
126
+ automationToken {
127
+ ... VaultSecret
128
+ }
129
+ }
130
+ tags
131
+ cidrBlock
132
+ manageSecurityGroups
133
+ manageRoute53Associations
134
+ assumeRole
135
+ }
136
+ ... on ClusterPeeringConnectionClusterRequester_v1 {
137
+ cluster {
138
+ name
139
+ network {
140
+ vpc
141
+ }
142
+ spec {
143
+ region
144
+ }
145
+ awsInfrastructureManagementAccounts {
146
+ ... AWSInfrastructureManagementAccount
147
+ }
148
+ peering {
149
+ connections {
150
+ name
151
+ provider
152
+ manageRoutes
153
+ ... on ClusterPeeringConnectionClusterAccepter_v1 {
154
+ name
155
+ cluster {
156
+ name
157
+ }
158
+ awsInfrastructureManagementAccount {
159
+ name
160
+ uid
161
+ terraformUsername
162
+ automationToken {
163
+ ... VaultSecret
164
+ }
165
+ }
166
+ }
167
+ }
168
+ }
169
+ }
170
+ }
171
+ }
172
+ }
173
+ disable {
174
+ integrations
175
+ }
176
+ }
177
+ }
178
+ """
179
+
180
+
181
+ class ConfiguredBaseModel(BaseModel):
182
+ class Config:
183
+ smart_union = True
184
+ extra = Extra.forbid
185
+
186
+
187
+ class OpenShiftClusterManagerV1(ConfiguredBaseModel):
188
+ name: str = Field(..., alias="name")
189
+ environment: OCMEnvironment = Field(..., alias="environment")
190
+ org_id: str = Field(..., alias="orgId")
191
+ access_token_client_id: Optional[str] = Field(..., alias="accessTokenClientId")
192
+ access_token_url: Optional[str] = Field(..., alias="accessTokenUrl")
193
+ access_token_client_secret: Optional[VaultSecret] = Field(
194
+ ..., alias="accessTokenClientSecret"
195
+ )
196
+ blocked_versions: Optional[list[str]] = Field(..., alias="blockedVersions")
197
+
198
+
199
+ class ClusterSpecV1(ConfiguredBaseModel):
200
+ region: str = Field(..., alias="region")
201
+
202
+
203
+ class ClusterNetworkV1(ConfiguredBaseModel):
204
+ vpc: str = Field(..., alias="vpc")
205
+
206
+
207
+ class ClusterPeeringConnectionV1(ConfiguredBaseModel):
208
+ name: str = Field(..., alias="name")
209
+ provider: str = Field(..., alias="provider")
210
+ manage_routes: Optional[bool] = Field(..., alias="manageRoutes")
211
+ delete: Optional[bool] = Field(..., alias="delete")
212
+
213
+
214
+ class AWSAccountV1(ConfiguredBaseModel):
215
+ name: str = Field(..., alias="name")
216
+ uid: str = Field(..., alias="uid")
217
+ terraform_username: Optional[str] = Field(..., alias="terraformUsername")
218
+ automation_token: VaultSecret = Field(..., alias="automationToken")
219
+
220
+
221
+ class AWSVPCV1(ConfiguredBaseModel):
222
+ account: AWSAccountV1 = Field(..., alias="account")
223
+ vpc_id: str = Field(..., alias="vpc_id")
224
+ cidr_block: str = Field(..., alias="cidr_block")
225
+ region: str = Field(..., alias="region")
226
+
227
+
228
+ class ClusterPeeringConnectionAccountV1(ClusterPeeringConnectionV1):
229
+ vpc: AWSVPCV1 = Field(..., alias="vpc")
230
+ assume_role: Optional[str] = Field(..., alias="assumeRole")
231
+ manage_account_routes: Optional[bool] = Field(..., alias="manageAccountRoutes")
232
+
233
+
234
+ class ClusterPeeringConnectionAccountVPCMeshV1_AWSAccountV1(ConfiguredBaseModel):
235
+ name: str = Field(..., alias="name")
236
+ uid: str = Field(..., alias="uid")
237
+ terraform_username: Optional[str] = Field(..., alias="terraformUsername")
238
+ automation_token: VaultSecret = Field(..., alias="automationToken")
239
+
240
+
241
+ class ClusterPeeringConnectionAccountVPCMeshV1(ClusterPeeringConnectionV1):
242
+ account: ClusterPeeringConnectionAccountVPCMeshV1_AWSAccountV1 = Field(
243
+ ..., alias="account"
244
+ )
245
+ tags: Optional[Json] = Field(..., alias="tags")
246
+
247
+
248
+ class ClusterPeeringConnectionAccountTGWV1_AWSAccountV1(ConfiguredBaseModel):
249
+ name: str = Field(..., alias="name")
250
+ uid: str = Field(..., alias="uid")
251
+ terraform_username: Optional[str] = Field(..., alias="terraformUsername")
252
+ automation_token: VaultSecret = Field(..., alias="automationToken")
253
+
254
+
255
+ class ClusterPeeringConnectionAccountTGWV1(ClusterPeeringConnectionV1):
256
+ account: ClusterPeeringConnectionAccountTGWV1_AWSAccountV1 = Field(
257
+ ..., alias="account"
258
+ )
259
+ tags: Optional[Json] = Field(..., alias="tags")
260
+ cidr_block: Optional[str] = Field(..., alias="cidrBlock")
261
+ manage_security_groups: Optional[bool] = Field(..., alias="manageSecurityGroups")
262
+ manage_route53_associations: Optional[bool] = Field(
263
+ ..., alias="manageRoute53Associations"
264
+ )
265
+ assume_role: Optional[str] = Field(..., alias="assumeRole")
266
+
267
+
268
+ class ClusterPeeringConnectionClusterRequesterV1_ClusterV1_ClusterNetworkV1(
269
+ ConfiguredBaseModel
270
+ ):
271
+ vpc: str = Field(..., alias="vpc")
272
+
273
+
274
+ class ClusterPeeringConnectionClusterRequesterV1_ClusterV1_ClusterSpecV1(
275
+ ConfiguredBaseModel
276
+ ):
277
+ region: str = Field(..., alias="region")
278
+
279
+
280
+ class ClusterPeeringConnectionClusterRequesterV1_ClusterV1_ClusterPeeringV1_ClusterPeeringConnectionV1(
281
+ ConfiguredBaseModel
282
+ ):
283
+ name: str = Field(..., alias="name")
284
+ provider: str = Field(..., alias="provider")
285
+ manage_routes: Optional[bool] = Field(..., alias="manageRoutes")
286
+
287
+
288
+ class ClusterPeeringConnectionClusterAccepterV1_ClusterV1(ConfiguredBaseModel):
289
+ name: str = Field(..., alias="name")
290
+
291
+
292
+ class ClusterPeeringConnectionClusterAccepterV1_AWSAccountV1(ConfiguredBaseModel):
293
+ name: str = Field(..., alias="name")
294
+ uid: str = Field(..., alias="uid")
295
+ terraform_username: Optional[str] = Field(..., alias="terraformUsername")
296
+ automation_token: VaultSecret = Field(..., alias="automationToken")
297
+
298
+
299
+ class ClusterPeeringConnectionClusterAccepterV1(
300
+ ClusterPeeringConnectionClusterRequesterV1_ClusterV1_ClusterPeeringV1_ClusterPeeringConnectionV1
301
+ ):
302
+ name: str = Field(..., alias="name")
303
+ cluster: ClusterPeeringConnectionClusterAccepterV1_ClusterV1 = Field(
304
+ ..., alias="cluster"
305
+ )
306
+ aws_infrastructure_management_account: Optional[
307
+ ClusterPeeringConnectionClusterAccepterV1_AWSAccountV1
308
+ ] = Field(..., alias="awsInfrastructureManagementAccount")
309
+
310
+
311
+ class ClusterPeeringConnectionClusterRequesterV1_ClusterV1_ClusterPeeringV1(
312
+ ConfiguredBaseModel
313
+ ):
314
+ connections: list[
315
+ Union[
316
+ ClusterPeeringConnectionClusterAccepterV1,
317
+ ClusterPeeringConnectionClusterRequesterV1_ClusterV1_ClusterPeeringV1_ClusterPeeringConnectionV1,
318
+ ]
319
+ ] = Field(..., alias="connections")
320
+
321
+
322
+ class ClusterPeeringConnectionClusterRequesterV1_ClusterV1(ConfiguredBaseModel):
323
+ name: str = Field(..., alias="name")
324
+ network: Optional[
325
+ ClusterPeeringConnectionClusterRequesterV1_ClusterV1_ClusterNetworkV1
326
+ ] = Field(..., alias="network")
327
+ spec: Optional[
328
+ ClusterPeeringConnectionClusterRequesterV1_ClusterV1_ClusterSpecV1
329
+ ] = Field(..., alias="spec")
330
+ aws_infrastructure_management_accounts: Optional[
331
+ list[AWSInfrastructureManagementAccount]
332
+ ] = Field(..., alias="awsInfrastructureManagementAccounts")
333
+ peering: Optional[
334
+ ClusterPeeringConnectionClusterRequesterV1_ClusterV1_ClusterPeeringV1
335
+ ] = Field(..., alias="peering")
336
+
337
+
338
+ class ClusterPeeringConnectionClusterRequesterV1(ClusterPeeringConnectionV1):
339
+ cluster: ClusterPeeringConnectionClusterRequesterV1_ClusterV1 = Field(
340
+ ..., alias="cluster"
341
+ )
342
+
343
+
344
+ class ClusterPeeringV1(ConfiguredBaseModel):
345
+ connections: list[
346
+ Union[
347
+ ClusterPeeringConnectionAccountTGWV1,
348
+ ClusterPeeringConnectionAccountV1,
349
+ ClusterPeeringConnectionAccountVPCMeshV1,
350
+ ClusterPeeringConnectionClusterRequesterV1,
351
+ ClusterPeeringConnectionV1,
352
+ ]
353
+ ] = Field(..., alias="connections")
354
+
355
+
356
+ class DisableClusterAutomationsV1(ConfiguredBaseModel):
357
+ integrations: Optional[list[str]] = Field(..., alias="integrations")
358
+
359
+
360
+ class ClusterV1(ConfiguredBaseModel):
361
+ path: str = Field(..., alias="path")
362
+ name: str = Field(..., alias="name")
363
+ ocm: Optional[OpenShiftClusterManagerV1] = Field(..., alias="ocm")
364
+ aws_infrastructure_management_accounts: Optional[
365
+ list[AWSInfrastructureManagementAccount]
366
+ ] = Field(..., alias="awsInfrastructureManagementAccounts")
367
+ spec: Optional[ClusterSpecV1] = Field(..., alias="spec")
368
+ network: Optional[ClusterNetworkV1] = Field(..., alias="network")
369
+ peering: Optional[ClusterPeeringV1] = Field(..., alias="peering")
370
+ disable: Optional[DisableClusterAutomationsV1] = Field(..., alias="disable")
371
+
372
+
373
+ class ClustersWithPeeringQueryData(ConfiguredBaseModel):
374
+ clusters: Optional[list[ClusterV1]] = Field(..., alias="clusters")
375
+
376
+
377
+ def query(query_func: Callable, **kwargs: Any) -> ClustersWithPeeringQueryData:
378
+ """
379
+ This is a convenience function which queries and parses the data into
380
+ concrete types. It should be compatible with most GQL clients.
381
+ You do not have to use it to consume the generated data classes.
382
+ Alternatively, you can also mime and alternate the behavior
383
+ of this function in the caller.
384
+
385
+ Parameters:
386
+ query_func (Callable): Function which queries your GQL Server
387
+ kwargs: optional arguments that will be passed to the query function
388
+
389
+ Returns:
390
+ ClustersWithPeeringQueryData: queried data parsed into generated classes
391
+ """
392
+ raw_data: dict[Any, Any] = query_func(DEFINITION, **kwargs)
393
+ return ClustersWithPeeringQueryData(**raw_data)
@@ -9,6 +9,13 @@ LOG = logging.getLogger(__name__)
9
9
 
10
10
 
11
11
  class SAPMMR(MergeRequestBase):
12
+ """
13
+ Very thin wrapper around MergeRequestBase.
14
+ This class is not tested, thus logic in here
15
+ is kept to a minimum. Any rendering should
16
+ happen in renderer.py
17
+ """
18
+
12
19
  name = "SAPM"
13
20
 
14
21
  def __init__(
@@ -31,6 +31,22 @@ class OpenMergeRequest:
31
31
 
32
32
 
33
33
  class MergeRequestManager:
34
+ """
35
+ Manager for SAPM merge requests. This class
36
+ is responsible for housekeeping (closing old/bad MRs) and
37
+ opening new MRs for subscribers with a state diff.
38
+
39
+ The idea is that for every channel combination there exists
40
+ maximum one open MR in app-interface. I.e., all changes for
41
+ a channel combination are batched in a single MR. A content hash in the
42
+ description is used to identify the content of that MR. If a
43
+ channel combination receives new content before an already open MR
44
+ is merged, then the manager will first close the old MR and then
45
+ open a new MR with the new content. We might need to change this
46
+ batching approach in the future to have even less promotion MRs,
47
+ but for now this is sufficient.
48
+ """
49
+
34
50
  def __init__(self, vcs: VCS, renderer: Renderer):
35
51
  self._vcs = vcs
36
52
  self._renderer = renderer
@@ -57,6 +73,15 @@ class MergeRequestManager:
57
73
  ]
58
74
 
59
75
  def housekeeping(self) -> None:
76
+ """
77
+ Close bad MRs:
78
+ - bad description format
79
+ - old SAPM version
80
+ - merge conflict
81
+
82
+ --> if we bump the SAPM version, we automatically close
83
+ old open MRs and replace them with new ones.
84
+ """
60
85
  seen: set[tuple[str, str, str]] = set()
61
86
  for mr in self._open_raw_mrs:
62
87
  attrs = mr.attributes
@@ -177,6 +202,11 @@ class MergeRequestManager:
177
202
  def create_promotion_merge_requests(
178
203
  self, subscribers: Iterable[Subscriber]
179
204
  ) -> None:
205
+ """
206
+ Open new MR for channel combinations with new content.
207
+ If there is new content, close any existing MR for that
208
+ channel combination.
209
+ """
180
210
  subscribers_per_channel_combo = self._aggregate_subscribers_per_channel_combo(
181
211
  subscribers=subscribers
182
212
  )
@@ -19,13 +19,13 @@ This MR promotes all subscribers with auto-promotions for these channel(s).
19
19
  Please **do not remove the {SAPM_LABEL} label** from this MR.
20
20
 
21
21
  Parts of this description are used by SAPM to manage auto-promotions.
22
-
23
- Please **do not modify or alter this description**.
24
22
  """
25
23
 
26
24
 
27
25
  class Renderer:
28
26
  """
27
+ This class is only concerned with rendering text for MRs.
28
+ Most logic evolves around ruamel yaml modification.
29
29
  This class makes testing for MergeRequestManager easier.
30
30
  """
31
31
 
@@ -20,6 +20,11 @@ class DeploymentInfo:
20
20
 
21
21
 
22
22
  class Publisher:
23
+ """
24
+ Hold all information about a saas publisher target.
25
+ Contains logic to fetch the current state of a publisher.
26
+ """
27
+
23
28
  def __init__(
24
29
  self,
25
30
  ref: str,
@@ -26,6 +26,11 @@ class ConfigHash:
26
26
 
27
27
 
28
28
  class Subscriber:
29
+ """
30
+ Hold all information about a saas subscriber target.
31
+ Contains logic to determine desired state.
32
+ """
33
+
29
34
  def __init__(
30
35
  self,
31
36
  saas_name: str,
@@ -52,7 +57,8 @@ class Subscriber:
52
57
  el for s in self.config_hashes_by_channel_name.values() for el in s
53
58
  }
54
59
  # We explicitly only care about subset - we do not care about
55
- # dangling current hashses
60
+ # dangling current hashes - these are checked in saasherder
61
+ # MR validation function.
56
62
  desired_hashes_are_in_current_hashes = (
57
63
  set(self.desired_hashes) <= current_hashes
58
64
  )
@@ -156,7 +162,7 @@ class Subscriber:
156
162
  def combined_content_hash(subscribers: Iterable["Subscriber"]) -> str:
157
163
  """
158
164
  Get a deterministic content hash for the attributes of a collection
159
- of subscribers.
165
+ of subscribers. The order of subscribers must not matter for the hash.
160
166
  It is important that this is a deterministic operation, because
161
167
  SAPM uses this hash to compare the content of MRs.
162
168
  """
@@ -0,0 +1,11 @@
1
+ from reconcile.gql_definitions.common.clusters_with_peering import (
2
+ ClusterV1,
3
+ query,
4
+ )
5
+ from reconcile.utils.gql import GqlApi
6
+
7
+
8
+ def get_clusters_with_peering(gql_api: GqlApi) -> list[ClusterV1]:
9
+ data = query(gql_api.query)
10
+ clusters = data.clusters or []
11
+ return [c for c in clusters if c.peering is not None]
reconcile/utils/gql.py CHANGED
@@ -24,8 +24,6 @@ from sretoolbox.utils import retry
24
24
  from reconcile.status import RunningState
25
25
  from reconcile.utils.config import get_config
26
26
 
27
- _gqlapi = None
28
-
29
27
  INTEGRATIONS_QUERY = """
30
28
  {
31
29
  integrations: integrations_v1 {
@@ -221,6 +219,9 @@ class GqlApi:
221
219
  return None
222
220
 
223
221
 
222
+ _gqlapi: Optional[GqlApi] = None
223
+
224
+
224
225
  def init(
225
226
  url: str,
226
227
  token: Optional[str] = None,
@@ -323,10 +324,10 @@ def _get_gql_server_and_token(
323
324
  return server, token, None, None
324
325
 
325
326
 
326
- def get_api():
327
+ def get_api() -> GqlApi:
327
328
  global _gqlapi
328
329
 
329
- if not _gqlapi:
330
+ if _gqlapi is None:
330
331
  raise GqlApiError("gql module has not been initialized.")
331
332
 
332
333
  return _gqlapi