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.
- {qontract_reconcile-0.9.1rc292.dist-info → qontract_reconcile-0.9.1rc294.dist-info}/METADATA +1 -1
- {qontract_reconcile-0.9.1rc292.dist-info → qontract_reconcile-0.9.1rc294.dist-info}/RECORD +13 -11
- reconcile/gql_definitions/common/clusters_with_peering.py +393 -0
- reconcile/saas_auto_promotions_manager/merge_request_manager/merge_request.py +7 -0
- reconcile/saas_auto_promotions_manager/merge_request_manager/merge_request_manager.py +30 -0
- reconcile/saas_auto_promotions_manager/merge_request_manager/renderer.py +2 -2
- reconcile/saas_auto_promotions_manager/publisher.py +5 -0
- reconcile/saas_auto_promotions_manager/subscriber.py +8 -2
- reconcile/typed_queries/clusters_with_peering.py +11 -0
- reconcile/utils/gql.py +5 -4
- {qontract_reconcile-0.9.1rc292.dist-info → qontract_reconcile-0.9.1rc294.dist-info}/WHEEL +0 -0
- {qontract_reconcile-0.9.1rc292.dist-info → qontract_reconcile-0.9.1rc294.dist-info}/entry_points.txt +0 -0
- {qontract_reconcile-0.9.1rc292.dist-info → qontract_reconcile-0.9.1rc294.dist-info}/top_level.txt +0 -0
{qontract_reconcile-0.9.1rc292.dist-info → qontract_reconcile-0.9.1rc294.dist-info}/METADATA
RENAMED
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: qontract-reconcile
|
3
|
-
Version: 0.9.
|
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=
|
271
|
-
reconcile/saas_auto_promotions_manager/subscriber.py,sha256=
|
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=
|
274
|
-
reconcile/saas_auto_promotions_manager/merge_request_manager/merge_request_manager.py,sha256=
|
275
|
-
reconcile/saas_auto_promotions_manager/merge_request_manager/renderer.py,sha256=
|
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=
|
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.
|
579
|
-
qontract_reconcile-0.9.
|
580
|
-
qontract_reconcile-0.9.
|
581
|
-
qontract_reconcile-0.9.
|
582
|
-
qontract_reconcile-0.9.
|
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
|
|
@@ -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
|
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
|
330
|
+
if _gqlapi is None:
|
330
331
|
raise GqlApiError("gql module has not been initialized.")
|
331
332
|
|
332
333
|
return _gqlapi
|
File without changes
|
{qontract_reconcile-0.9.1rc292.dist-info → qontract_reconcile-0.9.1rc294.dist-info}/entry_points.txt
RENAMED
File without changes
|
{qontract_reconcile-0.9.1rc292.dist-info → qontract_reconcile-0.9.1rc294.dist-info}/top_level.txt
RENAMED
File without changes
|