qontract-reconcile 0.10.2.dev207__py3-none-any.whl → 0.10.2.dev209__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.2.dev207.dist-info → qontract_reconcile-0.10.2.dev209.dist-info}/METADATA +1 -1
- {qontract_reconcile-0.10.2.dev207.dist-info → qontract_reconcile-0.10.2.dev209.dist-info}/RECORD +10 -10
- reconcile/automated_actions/config/integration.py +11 -0
- reconcile/gql_definitions/automated_actions/instance.py +55 -16
- reconcile/gql_definitions/introspection.json +219 -0
- reconcile/utils/saasherder/interfaces.py +4 -0
- reconcile/utils/saasherder/models.py +26 -0
- reconcile/utils/saasherder/saasherder.py +87 -6
- {qontract_reconcile-0.10.2.dev207.dist-info → qontract_reconcile-0.10.2.dev209.dist-info}/WHEEL +0 -0
- {qontract_reconcile-0.10.2.dev207.dist-info → qontract_reconcile-0.10.2.dev209.dist-info}/entry_points.txt +0 -0
{qontract_reconcile-0.10.2.dev207.dist-info → qontract_reconcile-0.10.2.dev209.dist-info}/METADATA
RENAMED
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: qontract-reconcile
|
3
|
-
Version: 0.10.2.
|
3
|
+
Version: 0.10.2.dev209
|
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
|
{qontract_reconcile-0.10.2.dev207.dist-info → qontract_reconcile-0.10.2.dev209.dist-info}/RECORD
RENAMED
@@ -141,7 +141,7 @@ reconcile/aus/version_gates/ocp_gate_handler.py,sha256=RW1ppDaCZXVegV9AzzqYXxDUu
|
|
141
141
|
reconcile/aus/version_gates/sts_version_gate_handler.py,sha256=swwwz0YyvrEBf_InqrRRBCt2QzHYNvvq8jz9aYwElh4,3663
|
142
142
|
reconcile/automated_actions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
143
143
|
reconcile/automated_actions/config/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
144
|
-
reconcile/automated_actions/config/integration.py,sha256=
|
144
|
+
reconcile/automated_actions/config/integration.py,sha256=y4Ce_sgCx50lZQNvfkcnuyrDP4VPC1Dvq5-eBU8uibM,12248
|
145
145
|
reconcile/aws_account_manager/README.md,sha256=_XFM3GZNHUzv--e_navqJuaUWpjC6QrHfulreHynFf0,262
|
146
146
|
reconcile/aws_account_manager/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
147
147
|
reconcile/aws_account_manager/integration.py,sha256=XTamC824imAezzVoQhhwdMOawNcPCOghR_y7i_8bpJI,15343
|
@@ -227,7 +227,7 @@ reconcile/glitchtip_project_alerts/integration.py,sha256=d3PMy-mQSbSZdIGAVaZCA2U
|
|
227
227
|
reconcile/glitchtip_project_dsn/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
228
228
|
reconcile/glitchtip_project_dsn/integration.py,sha256=2iugub-kHYkHNK33n0v9_TeWonuxCPah_VkoTPvaajE,8077
|
229
229
|
reconcile/gql_definitions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
230
|
-
reconcile/gql_definitions/introspection.json,sha256=
|
230
|
+
reconcile/gql_definitions/introspection.json,sha256=98cLVDNRRqTIu5ONbfa0WqIptS3J7g-s4M2Dhq3oSo4,2345500
|
231
231
|
reconcile/gql_definitions/acs/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
232
232
|
reconcile/gql_definitions/acs/acs_instances.py,sha256=L91WW9LbhJbBSrECqShQpFtjoBOsmNIYLRpMbx1io5o,2181
|
233
233
|
reconcile/gql_definitions/acs/acs_policies.py,sha256=Ygpfl2-VkYLSlJvHgp_dJBfb66K_Rwfdfpsa18w1v1s,4338
|
@@ -241,7 +241,7 @@ reconcile/gql_definitions/app_sre_tekton_access_revalidation/__init__.py,sha256=
|
|
241
241
|
reconcile/gql_definitions/app_sre_tekton_access_revalidation/roles.py,sha256=8Y4NsS5T7tumDWxY5MuoV50MK2i-DsLYSpCRjb7KaLE,2353
|
242
242
|
reconcile/gql_definitions/app_sre_tekton_access_revalidation/users.py,sha256=XdVxBxiyTR6Cy939EHNw__0k7iWrZWlhrgS5DakST0I,2504
|
243
243
|
reconcile/gql_definitions/automated_actions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
244
|
-
reconcile/gql_definitions/automated_actions/instance.py,sha256=
|
244
|
+
reconcile/gql_definitions/automated_actions/instance.py,sha256=A2cTd13049HVSU7-AOOFpbpIoDkawEjCaHUsE3CoQGs,7478
|
245
245
|
reconcile/gql_definitions/aws_account_manager/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
246
246
|
reconcile/gql_definitions/aws_account_manager/aws_accounts.py,sha256=vF51KrY2gwX0J9vESiaRMPQqdAMEtz9f_tBq52bInp0,5148
|
247
247
|
reconcile/gql_definitions/aws_ami_cleanup/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -767,9 +767,9 @@ reconcile/utils/runtime/meta.py,sha256=dWdKS9eHVuowFkTK4lgXJ723vS1y9giOMzePUKnHn
|
|
767
767
|
reconcile/utils/runtime/runner.py,sha256=I30KRrX1UQbHc_Ir1cIZX3OfNSdoHKdnDSPAEB69Ilk,7944
|
768
768
|
reconcile/utils/runtime/sharding.py,sha256=r0ieUtNed7NvknSw6qQrCkKpVXE1shuHGnfFcnpA_k4,16142
|
769
769
|
reconcile/utils/saasherder/__init__.py,sha256=3U8plqMAPRE1kjwZ5YnIsYsggTf4_gS7flRUEuXVBAs,343
|
770
|
-
reconcile/utils/saasherder/interfaces.py,sha256=
|
771
|
-
reconcile/utils/saasherder/models.py,sha256=
|
772
|
-
reconcile/utils/saasherder/saasherder.py,sha256=
|
770
|
+
reconcile/utils/saasherder/interfaces.py,sha256=nbGVLiIXJvOtd5ZfKsP3bfrFbMpdQ02D0cTTM9rrED0,9286
|
771
|
+
reconcile/utils/saasherder/models.py,sha256=MSKaC65_bXSxKvhCibRH5K1DNppLPbw5w7_6VrjCCFU,11018
|
772
|
+
reconcile/utils/saasherder/saasherder.py,sha256=W9nmQyULr4Jx9VAMwFyhULbKo5WRP9nSieOnpO5UxKQ,90224
|
773
773
|
reconcile/utils/terraform/__init__.py,sha256=zNbiyTWo35AT1sFTElL2j_AA0jJ_yWE_bfFn-nD2xik,250
|
774
774
|
reconcile/utils/terraform/config.py,sha256=5UVrd563TMcvi4ooa5JvWVDW1I3bIWg484u79evfV_8,164
|
775
775
|
reconcile/utils/terraform/config_client.py,sha256=gRL1rQ0AqvShei_rcGqC3HDYGskOFKE1nPrJyJE9yno,4676
|
@@ -815,7 +815,7 @@ tools/saas_promotion_state/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJ
|
|
815
815
|
tools/saas_promotion_state/saas_promotion_state.py,sha256=UfwwRLS5Ya4_Nh1w5n1dvoYtchQvYE9yj1VANt2IKqI,3925
|
816
816
|
tools/sre_checkpoints/__init__.py,sha256=CDaDaywJnmRCLyl_NCcvxi-Zc0hTi_3OdwKiFOyS39I,145
|
817
817
|
tools/sre_checkpoints/util.py,sha256=zEDbGr18ZeHNQwW8pUsr2JRjuXIPz--WAGJxZo9sv_Y,894
|
818
|
-
qontract_reconcile-0.10.2.
|
819
|
-
qontract_reconcile-0.10.2.
|
820
|
-
qontract_reconcile-0.10.2.
|
821
|
-
qontract_reconcile-0.10.2.
|
818
|
+
qontract_reconcile-0.10.2.dev209.dist-info/METADATA,sha256=QKUofEI-f485b9dZemKXq6v2vV1nQPGJDX3BaZL1_g4,24555
|
819
|
+
qontract_reconcile-0.10.2.dev209.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
820
|
+
qontract_reconcile-0.10.2.dev209.dist-info/entry_points.txt,sha256=5i9l54La3vQrDLAdwDKQWC0iG4sV9RRfOb1BpvzOWLc,698
|
821
|
+
qontract_reconcile-0.10.2.dev209.dist-info/RECORD,,
|
@@ -17,10 +17,12 @@ from pydantic import BaseModel
|
|
17
17
|
import reconcile.openshift_base as ob
|
18
18
|
from reconcile.gql_definitions.automated_actions.instance import (
|
19
19
|
AutomatedActionActionListV1,
|
20
|
+
AutomatedActionExternalResourceRdsRebootV1,
|
20
21
|
AutomatedActionOpenshiftWorkloadRestartArgumentV1,
|
21
22
|
AutomatedActionOpenshiftWorkloadRestartV1,
|
22
23
|
AutomatedActionsInstanceV1,
|
23
24
|
AutomatedActionV1,
|
25
|
+
AWSAccountV1,
|
24
26
|
)
|
25
27
|
from reconcile.gql_definitions.automated_actions.instance import query as instance_query
|
26
28
|
from reconcile.utils import expiration, gql
|
@@ -165,6 +167,15 @@ class AutomatedActionsConfigIntegration(
|
|
165
167
|
arg.dict(exclude_none=True, exclude_defaults=True)
|
166
168
|
for arg in action.action_list_arguments or []
|
167
169
|
)
|
170
|
+
case AutomatedActionExternalResourceRdsRebootV1():
|
171
|
+
for arg in action.external_resource_rds_reboot_arguments:
|
172
|
+
for er in arg.namespace.external_resources or []:
|
173
|
+
if not isinstance(er.provisioner, AWSAccountV1):
|
174
|
+
continue
|
175
|
+
parameters.append({
|
176
|
+
"account": f"^{er.provisioner.name}$",
|
177
|
+
"identifier": arg.identifier,
|
178
|
+
})
|
168
179
|
case AutomatedActionOpenshiftWorkloadRestartV1():
|
169
180
|
parameters.extend(
|
170
181
|
{
|
@@ -84,6 +84,26 @@ query AutomatedActionsInstances {
|
|
84
84
|
}
|
85
85
|
}
|
86
86
|
maxOps
|
87
|
+
... on AutomatedActionActionList_v1 {
|
88
|
+
action_list_arguments: arguments {
|
89
|
+
action_user
|
90
|
+
max_age_minutes
|
91
|
+
}
|
92
|
+
}
|
93
|
+
... on AutomatedActionExternalResourceRdsReboot_v1 {
|
94
|
+
external_resource_rds_reboot_arguments: arguments {
|
95
|
+
namespace {
|
96
|
+
externalResources {
|
97
|
+
provisioner {
|
98
|
+
... on AWSAccount_v1 {
|
99
|
+
name
|
100
|
+
}
|
101
|
+
}
|
102
|
+
}
|
103
|
+
}
|
104
|
+
identifier
|
105
|
+
}
|
106
|
+
}
|
87
107
|
... on AutomatedActionOpenshiftWorkloadRestart_v1 {
|
88
108
|
openshift_workload_restart_arguments: arguments {
|
89
109
|
namespace {
|
@@ -100,12 +120,6 @@ query AutomatedActionsInstances {
|
|
100
120
|
name
|
101
121
|
}
|
102
122
|
}
|
103
|
-
... on AutomatedActionActionList_v1 {
|
104
|
-
action_list_arguments: arguments {
|
105
|
-
action_user
|
106
|
-
max_age_minutes
|
107
|
-
}
|
108
|
-
}
|
109
123
|
}
|
110
124
|
}
|
111
125
|
}
|
@@ -150,6 +164,40 @@ class AutomatedActionV1(ConfiguredBaseModel):
|
|
150
164
|
max_ops: int = Field(..., alias="maxOps")
|
151
165
|
|
152
166
|
|
167
|
+
class AutomatedActionActionListArgumentV1(ConfiguredBaseModel):
|
168
|
+
action_user: Optional[str] = Field(..., alias="action_user")
|
169
|
+
max_age_minutes: Optional[int] = Field(..., alias="max_age_minutes")
|
170
|
+
|
171
|
+
|
172
|
+
class AutomatedActionActionListV1(AutomatedActionV1):
|
173
|
+
action_list_arguments: Optional[list[AutomatedActionActionListArgumentV1]] = Field(..., alias="action_list_arguments")
|
174
|
+
|
175
|
+
|
176
|
+
class ExternalResourcesProvisionerV1(ConfiguredBaseModel):
|
177
|
+
...
|
178
|
+
|
179
|
+
|
180
|
+
class AWSAccountV1(ExternalResourcesProvisionerV1):
|
181
|
+
name: str = Field(..., alias="name")
|
182
|
+
|
183
|
+
|
184
|
+
class NamespaceExternalResourceV1(ConfiguredBaseModel):
|
185
|
+
provisioner: Union[AWSAccountV1, ExternalResourcesProvisionerV1] = Field(..., alias="provisioner")
|
186
|
+
|
187
|
+
|
188
|
+
class AutomatedActionExternalResourceArgumentV1_NamespaceV1(ConfiguredBaseModel):
|
189
|
+
external_resources: Optional[list[NamespaceExternalResourceV1]] = Field(..., alias="externalResources")
|
190
|
+
|
191
|
+
|
192
|
+
class AutomatedActionExternalResourceArgumentV1(ConfiguredBaseModel):
|
193
|
+
namespace: AutomatedActionExternalResourceArgumentV1_NamespaceV1 = Field(..., alias="namespace")
|
194
|
+
identifier: str = Field(..., alias="identifier")
|
195
|
+
|
196
|
+
|
197
|
+
class AutomatedActionExternalResourceRdsRebootV1(AutomatedActionV1):
|
198
|
+
external_resource_rds_reboot_arguments: list[AutomatedActionExternalResourceArgumentV1] = Field(..., alias="external_resource_rds_reboot_arguments")
|
199
|
+
|
200
|
+
|
153
201
|
class DisableClusterAutomationsV1(ConfiguredBaseModel):
|
154
202
|
integrations: Optional[list[str]] = Field(..., alias="integrations")
|
155
203
|
|
@@ -175,19 +223,10 @@ class AutomatedActionOpenshiftWorkloadRestartV1(AutomatedActionV1):
|
|
175
223
|
openshift_workload_restart_arguments: list[AutomatedActionOpenshiftWorkloadRestartArgumentV1] = Field(..., alias="openshift_workload_restart_arguments")
|
176
224
|
|
177
225
|
|
178
|
-
class AutomatedActionActionListArgumentV1(ConfiguredBaseModel):
|
179
|
-
action_user: Optional[str] = Field(..., alias="action_user")
|
180
|
-
max_age_minutes: Optional[int] = Field(..., alias="max_age_minutes")
|
181
|
-
|
182
|
-
|
183
|
-
class AutomatedActionActionListV1(AutomatedActionV1):
|
184
|
-
action_list_arguments: Optional[list[AutomatedActionActionListArgumentV1]] = Field(..., alias="action_list_arguments")
|
185
|
-
|
186
|
-
|
187
226
|
class AutomatedActionsInstanceV1(ConfiguredBaseModel):
|
188
227
|
name: str = Field(..., alias="name")
|
189
228
|
deployment: NamespaceV1 = Field(..., alias="deployment")
|
190
|
-
actions: Optional[list[Union[
|
229
|
+
actions: Optional[list[Union[AutomatedActionActionListV1, AutomatedActionExternalResourceRdsRebootV1, AutomatedActionOpenshiftWorkloadRestartV1, AutomatedActionV1]]] = Field(..., alias="actions")
|
191
230
|
|
192
231
|
|
193
232
|
class AutomatedActionsInstancesQueryData(ConfiguredBaseModel):
|
@@ -5737,6 +5737,11 @@
|
|
5737
5737
|
"name": "AutomatedActionCreateToken_v1",
|
5738
5738
|
"ofType": null
|
5739
5739
|
},
|
5740
|
+
{
|
5741
|
+
"kind": "OBJECT",
|
5742
|
+
"name": "AutomatedActionExternalResourceRdsReboot_v1",
|
5743
|
+
"ofType": null
|
5744
|
+
},
|
5740
5745
|
{
|
5741
5746
|
"kind": "OBJECT",
|
5742
5747
|
"name": "AutomatedActionNoOp_v1",
|
@@ -27339,6 +27344,11 @@
|
|
27339
27344
|
"name": "AutomatedActionCreateToken_v1",
|
27340
27345
|
"ofType": null
|
27341
27346
|
},
|
27347
|
+
{
|
27348
|
+
"kind": "OBJECT",
|
27349
|
+
"name": "AutomatedActionExternalResourceRdsReboot_v1",
|
27350
|
+
"ofType": null
|
27351
|
+
},
|
27342
27352
|
{
|
27343
27353
|
"kind": "OBJECT",
|
27344
27354
|
"name": "AutomatedActionNoOp_v1",
|
@@ -53500,6 +53510,215 @@
|
|
53500
53510
|
"enumValues": null,
|
53501
53511
|
"possibleTypes": null
|
53502
53512
|
},
|
53513
|
+
{
|
53514
|
+
"kind": "OBJECT",
|
53515
|
+
"name": "AutomatedActionExternalResourceRdsReboot_v1",
|
53516
|
+
"description": null,
|
53517
|
+
"fields": [
|
53518
|
+
{
|
53519
|
+
"name": "schema",
|
53520
|
+
"description": null,
|
53521
|
+
"args": [],
|
53522
|
+
"type": {
|
53523
|
+
"kind": "NON_NULL",
|
53524
|
+
"name": null,
|
53525
|
+
"ofType": {
|
53526
|
+
"kind": "SCALAR",
|
53527
|
+
"name": "String",
|
53528
|
+
"ofType": null
|
53529
|
+
}
|
53530
|
+
},
|
53531
|
+
"isDeprecated": false,
|
53532
|
+
"deprecationReason": null
|
53533
|
+
},
|
53534
|
+
{
|
53535
|
+
"name": "path",
|
53536
|
+
"description": null,
|
53537
|
+
"args": [],
|
53538
|
+
"type": {
|
53539
|
+
"kind": "NON_NULL",
|
53540
|
+
"name": null,
|
53541
|
+
"ofType": {
|
53542
|
+
"kind": "SCALAR",
|
53543
|
+
"name": "String",
|
53544
|
+
"ofType": null
|
53545
|
+
}
|
53546
|
+
},
|
53547
|
+
"isDeprecated": false,
|
53548
|
+
"deprecationReason": null
|
53549
|
+
},
|
53550
|
+
{
|
53551
|
+
"name": "type",
|
53552
|
+
"description": null,
|
53553
|
+
"args": [],
|
53554
|
+
"type": {
|
53555
|
+
"kind": "NON_NULL",
|
53556
|
+
"name": null,
|
53557
|
+
"ofType": {
|
53558
|
+
"kind": "SCALAR",
|
53559
|
+
"name": "String",
|
53560
|
+
"ofType": null
|
53561
|
+
}
|
53562
|
+
},
|
53563
|
+
"isDeprecated": false,
|
53564
|
+
"deprecationReason": null
|
53565
|
+
},
|
53566
|
+
{
|
53567
|
+
"name": "description",
|
53568
|
+
"description": null,
|
53569
|
+
"args": [],
|
53570
|
+
"type": {
|
53571
|
+
"kind": "SCALAR",
|
53572
|
+
"name": "String",
|
53573
|
+
"ofType": null
|
53574
|
+
},
|
53575
|
+
"isDeprecated": false,
|
53576
|
+
"deprecationReason": null
|
53577
|
+
},
|
53578
|
+
{
|
53579
|
+
"name": "maxOps",
|
53580
|
+
"description": null,
|
53581
|
+
"args": [],
|
53582
|
+
"type": {
|
53583
|
+
"kind": "NON_NULL",
|
53584
|
+
"name": null,
|
53585
|
+
"ofType": {
|
53586
|
+
"kind": "SCALAR",
|
53587
|
+
"name": "Int",
|
53588
|
+
"ofType": null
|
53589
|
+
}
|
53590
|
+
},
|
53591
|
+
"isDeprecated": false,
|
53592
|
+
"deprecationReason": null
|
53593
|
+
},
|
53594
|
+
{
|
53595
|
+
"name": "instances",
|
53596
|
+
"description": null,
|
53597
|
+
"args": [],
|
53598
|
+
"type": {
|
53599
|
+
"kind": "NON_NULL",
|
53600
|
+
"name": null,
|
53601
|
+
"ofType": {
|
53602
|
+
"kind": "LIST",
|
53603
|
+
"name": null,
|
53604
|
+
"ofType": {
|
53605
|
+
"kind": "NON_NULL",
|
53606
|
+
"name": null,
|
53607
|
+
"ofType": {
|
53608
|
+
"kind": "OBJECT",
|
53609
|
+
"name": "AutomatedActionsInstance_v1",
|
53610
|
+
"ofType": null
|
53611
|
+
}
|
53612
|
+
}
|
53613
|
+
}
|
53614
|
+
},
|
53615
|
+
"isDeprecated": false,
|
53616
|
+
"deprecationReason": null
|
53617
|
+
},
|
53618
|
+
{
|
53619
|
+
"name": "permissions",
|
53620
|
+
"description": null,
|
53621
|
+
"args": [],
|
53622
|
+
"type": {
|
53623
|
+
"kind": "LIST",
|
53624
|
+
"name": null,
|
53625
|
+
"ofType": {
|
53626
|
+
"kind": "NON_NULL",
|
53627
|
+
"name": null,
|
53628
|
+
"ofType": {
|
53629
|
+
"kind": "OBJECT",
|
53630
|
+
"name": "PermissionAutomatedActions_v1",
|
53631
|
+
"ofType": null
|
53632
|
+
}
|
53633
|
+
}
|
53634
|
+
},
|
53635
|
+
"isDeprecated": false,
|
53636
|
+
"deprecationReason": null
|
53637
|
+
},
|
53638
|
+
{
|
53639
|
+
"name": "arguments",
|
53640
|
+
"description": null,
|
53641
|
+
"args": [],
|
53642
|
+
"type": {
|
53643
|
+
"kind": "NON_NULL",
|
53644
|
+
"name": null,
|
53645
|
+
"ofType": {
|
53646
|
+
"kind": "LIST",
|
53647
|
+
"name": null,
|
53648
|
+
"ofType": {
|
53649
|
+
"kind": "NON_NULL",
|
53650
|
+
"name": null,
|
53651
|
+
"ofType": {
|
53652
|
+
"kind": "OBJECT",
|
53653
|
+
"name": "AutomatedActionExternalResourceArgument_v1",
|
53654
|
+
"ofType": null
|
53655
|
+
}
|
53656
|
+
}
|
53657
|
+
}
|
53658
|
+
},
|
53659
|
+
"isDeprecated": false,
|
53660
|
+
"deprecationReason": null
|
53661
|
+
}
|
53662
|
+
],
|
53663
|
+
"inputFields": null,
|
53664
|
+
"interfaces": [
|
53665
|
+
{
|
53666
|
+
"kind": "INTERFACE",
|
53667
|
+
"name": "AutomatedAction_v1",
|
53668
|
+
"ofType": null
|
53669
|
+
},
|
53670
|
+
{
|
53671
|
+
"kind": "INTERFACE",
|
53672
|
+
"name": "DatafileObject_v1",
|
53673
|
+
"ofType": null
|
53674
|
+
}
|
53675
|
+
],
|
53676
|
+
"enumValues": null,
|
53677
|
+
"possibleTypes": null
|
53678
|
+
},
|
53679
|
+
{
|
53680
|
+
"kind": "OBJECT",
|
53681
|
+
"name": "AutomatedActionExternalResourceArgument_v1",
|
53682
|
+
"description": null,
|
53683
|
+
"fields": [
|
53684
|
+
{
|
53685
|
+
"name": "namespace",
|
53686
|
+
"description": null,
|
53687
|
+
"args": [],
|
53688
|
+
"type": {
|
53689
|
+
"kind": "NON_NULL",
|
53690
|
+
"name": null,
|
53691
|
+
"ofType": {
|
53692
|
+
"kind": "OBJECT",
|
53693
|
+
"name": "Namespace_v1",
|
53694
|
+
"ofType": null
|
53695
|
+
}
|
53696
|
+
},
|
53697
|
+
"isDeprecated": false,
|
53698
|
+
"deprecationReason": null
|
53699
|
+
},
|
53700
|
+
{
|
53701
|
+
"name": "identifier",
|
53702
|
+
"description": null,
|
53703
|
+
"args": [],
|
53704
|
+
"type": {
|
53705
|
+
"kind": "NON_NULL",
|
53706
|
+
"name": null,
|
53707
|
+
"ofType": {
|
53708
|
+
"kind": "SCALAR",
|
53709
|
+
"name": "String",
|
53710
|
+
"ofType": null
|
53711
|
+
}
|
53712
|
+
},
|
53713
|
+
"isDeprecated": false,
|
53714
|
+
"deprecationReason": null
|
53715
|
+
}
|
53716
|
+
],
|
53717
|
+
"inputFields": null,
|
53718
|
+
"interfaces": [],
|
53719
|
+
"enumValues": null,
|
53720
|
+
"possibleTypes": null
|
53721
|
+
},
|
53503
53722
|
{
|
53504
53723
|
"kind": "OBJECT",
|
53505
53724
|
"name": "AutomatedActionNoOp_v1",
|
@@ -7,6 +7,7 @@ from typing import (
|
|
7
7
|
runtime_checkable,
|
8
8
|
)
|
9
9
|
|
10
|
+
from reconcile.gql_definitions.fragments.saas_slo_document import SLODocument
|
10
11
|
from reconcile.utils import oc_connection_parameters
|
11
12
|
from reconcile.utils.secret_reader import HasSecret
|
12
13
|
|
@@ -326,6 +327,9 @@ class SaasResourceTemplateTarget(HasParameters, HasSecretParameters, Protocol):
|
|
326
327
|
@property
|
327
328
|
def images(self) -> Sequence[SaasResourceTemplateTargetImage] | None: ...
|
328
329
|
|
330
|
+
@property
|
331
|
+
def slos(self) -> list[SLODocument] | None: ...
|
332
|
+
|
329
333
|
def uid(
|
330
334
|
self, parent_saas_file_name: str, parent_resource_template_name: str
|
331
335
|
) -> str: ...
|
@@ -12,6 +12,9 @@ from pydantic import (
|
|
12
12
|
Field,
|
13
13
|
)
|
14
14
|
|
15
|
+
from reconcile.gql_definitions.fragments.saas_slo_document import (
|
16
|
+
SLODocument,
|
17
|
+
)
|
15
18
|
from reconcile.utils.oc_connection_parameters import Cluster
|
16
19
|
from reconcile.utils.saasherder.interfaces import (
|
17
20
|
HasParameters,
|
@@ -66,8 +69,18 @@ class TriggerSpecBase:
|
|
66
69
|
raise NotImplementedError("implement this function in inheriting classes")
|
67
70
|
|
68
71
|
|
72
|
+
@dataclass(frozen=True)
|
73
|
+
class SLOKey:
|
74
|
+
slo_document_name: str
|
75
|
+
namespace_name: str
|
76
|
+
cluster_name: str
|
77
|
+
|
78
|
+
|
69
79
|
@dataclass
|
70
80
|
class TriggerSpecConfig(TriggerSpecBase):
|
81
|
+
resource_template_url: str
|
82
|
+
target_ref: str
|
83
|
+
slos: list[SLODocument] | None = None
|
71
84
|
target_name: str | None = None
|
72
85
|
reason: str | None = None
|
73
86
|
|
@@ -81,6 +94,19 @@ class TriggerSpecConfig(TriggerSpecBase):
|
|
81
94
|
key += f"/{self.target_name}"
|
82
95
|
return key
|
83
96
|
|
97
|
+
def extract_slo_keys(self) -> list[SLOKey]:
|
98
|
+
return [
|
99
|
+
SLOKey(
|
100
|
+
slo_document_name=slo_document.name,
|
101
|
+
namespace_name=namespace.namespace.name,
|
102
|
+
cluster_name=namespace.namespace.cluster.name,
|
103
|
+
)
|
104
|
+
for slo_document in self.slos or []
|
105
|
+
for namespace in slo_document.namespaces
|
106
|
+
if namespace.namespace.name == self.namespace_name
|
107
|
+
and namespace.namespace.cluster.name == self.cluster_name
|
108
|
+
]
|
109
|
+
|
84
110
|
|
85
111
|
@dataclass
|
86
112
|
class TriggerSpecMovingCommit(TriggerSpecBase):
|
@@ -71,6 +71,7 @@ from reconcile.utils.saasherder.models import (
|
|
71
71
|
ImageAuth,
|
72
72
|
Namespace,
|
73
73
|
Promotion,
|
74
|
+
SLOKey,
|
74
75
|
TargetSpec,
|
75
76
|
TriggerSpecConfig,
|
76
77
|
TriggerSpecContainerImage,
|
@@ -81,6 +82,7 @@ from reconcile.utils.saasherder.models import (
|
|
81
82
|
UpstreamJob,
|
82
83
|
)
|
83
84
|
from reconcile.utils.secret_reader import SecretReaderBase
|
85
|
+
from reconcile.utils.slo_document_manager import SLODetails, SLODocumentManager
|
84
86
|
from reconcile.utils.state import State
|
85
87
|
from reconcile.utils.vcs import VCS
|
86
88
|
|
@@ -1040,19 +1042,19 @@ class SaasHerder: # pylint: disable=too-many-public-methods
|
|
1040
1042
|
return channel_map
|
1041
1043
|
|
1042
1044
|
def _collect_blocked_versions(self) -> dict[str, set[str]]:
|
1043
|
-
blocked_versions: dict[str, set[str]] =
|
1045
|
+
blocked_versions: dict[str, set[str]] = defaultdict(set[str])
|
1044
1046
|
for saas_file in self.saas_files:
|
1045
1047
|
for cc in saas_file.app.code_components or []:
|
1046
1048
|
for v in cc.blocked_versions or []:
|
1047
|
-
blocked_versions
|
1049
|
+
blocked_versions[cc.url].add(v)
|
1048
1050
|
return blocked_versions
|
1049
1051
|
|
1050
1052
|
def _collect_hotfix_versions(self) -> dict[str, set[str]]:
|
1051
|
-
hotfix_versions: dict[str, set[str]] =
|
1053
|
+
hotfix_versions: dict[str, set[str]] = defaultdict(set[str])
|
1052
1054
|
for saas_file in self.saas_files:
|
1053
1055
|
for cc in saas_file.app.code_components or []:
|
1054
1056
|
for v in cc.hotfix_versions or []:
|
1055
|
-
hotfix_versions
|
1057
|
+
hotfix_versions[cc.url].add(v)
|
1056
1058
|
return hotfix_versions
|
1057
1059
|
|
1058
1060
|
@staticmethod
|
@@ -1273,6 +1275,8 @@ class SaasHerder: # pylint: disable=too-many-public-methods
|
|
1273
1275
|
cluster_name=target.namespace.cluster.name,
|
1274
1276
|
namespace_name=target.namespace.name,
|
1275
1277
|
target_name=target.name,
|
1278
|
+
resource_template_url=rt.url,
|
1279
|
+
target_ref=target.ref,
|
1276
1280
|
state_content=None,
|
1277
1281
|
).state_key
|
1278
1282
|
digest = SaasHerder.get_target_config_hash(
|
@@ -1691,7 +1695,82 @@ class SaasHerder: # pylint: disable=too-many-public-methods
|
|
1691
1695
|
results = threaded.run(
|
1692
1696
|
self.get_configs_diff_saas_file, self.saas_files, self.thread_pool_size
|
1693
1697
|
)
|
1694
|
-
|
1698
|
+
trigger_config_spec_list = list(itertools.chain.from_iterable(results))
|
1699
|
+
return self.filter_slo_breached_triggers(trigger_config_spec_list)
|
1700
|
+
|
1701
|
+
def filter_slo_breached_triggers(
|
1702
|
+
self, trigger_config_spec_list: list[TriggerSpecConfig]
|
1703
|
+
) -> list[TriggerSpecConfig]:
|
1704
|
+
trigger_config_specs_to_validate: list[TriggerSpecConfig] = [
|
1705
|
+
trigger_config_spec
|
1706
|
+
for trigger_config_spec in trigger_config_spec_list
|
1707
|
+
if trigger_config_spec.slos
|
1708
|
+
and trigger_config_spec.target_ref
|
1709
|
+
not in self.hotfix_versions[trigger_config_spec.resource_template_url]
|
1710
|
+
]
|
1711
|
+
if not trigger_config_specs_to_validate:
|
1712
|
+
return trigger_config_spec_list
|
1713
|
+
|
1714
|
+
slo_documents = [
|
1715
|
+
slo
|
1716
|
+
for trigger_spec in trigger_config_specs_to_validate
|
1717
|
+
for slo in trigger_spec.slos or []
|
1718
|
+
]
|
1719
|
+
slo_document_manager = SLODocumentManager(
|
1720
|
+
slo_documents=slo_documents,
|
1721
|
+
thread_pool_size=self.thread_pool_size,
|
1722
|
+
secret_reader=self.secret_reader,
|
1723
|
+
)
|
1724
|
+
breached_slos = slo_document_manager.get_breached_slos()
|
1725
|
+
if not breached_slos:
|
1726
|
+
return trigger_config_spec_list
|
1727
|
+
|
1728
|
+
breached_slos_map = self.make_breached_slos_map(breached_slos)
|
1729
|
+
valid_trigger_config_specs = [
|
1730
|
+
trigger_config_spec
|
1731
|
+
for trigger_config_spec in trigger_config_spec_list
|
1732
|
+
if not self.has_breached_slos(trigger_config_spec, breached_slos_map)
|
1733
|
+
]
|
1734
|
+
return valid_trigger_config_specs
|
1735
|
+
|
1736
|
+
@staticmethod
|
1737
|
+
def make_breached_slos_map(
|
1738
|
+
breached_slos: list[SLODetails],
|
1739
|
+
) -> dict[SLOKey, list[SLODetails]]:
|
1740
|
+
breached_slos_map: dict[SLOKey, list[SLODetails]] = defaultdict(
|
1741
|
+
list[SLODetails]
|
1742
|
+
)
|
1743
|
+
for breached_slo in breached_slos:
|
1744
|
+
breached_slos_map[
|
1745
|
+
SLOKey(
|
1746
|
+
slo_document_name=breached_slo.slo_document_name,
|
1747
|
+
namespace_name=breached_slo.namespace_name,
|
1748
|
+
cluster_name=breached_slo.cluster_name,
|
1749
|
+
)
|
1750
|
+
].append(breached_slo)
|
1751
|
+
return breached_slos_map
|
1752
|
+
|
1753
|
+
@staticmethod
|
1754
|
+
def has_breached_slos(
|
1755
|
+
trigger_spec: TriggerSpecConfig,
|
1756
|
+
breached_slo_map: dict[SLOKey, list[SLODetails]],
|
1757
|
+
) -> bool:
|
1758
|
+
matching_slo_keys = [
|
1759
|
+
slo_key
|
1760
|
+
for slo_key in trigger_spec.extract_slo_keys()
|
1761
|
+
if slo_key in breached_slo_map
|
1762
|
+
]
|
1763
|
+
if not matching_slo_keys:
|
1764
|
+
return False
|
1765
|
+
logging.info(
|
1766
|
+
f"Skipping target from saas file {trigger_spec.saas_file_name} due to following breached SLOs."
|
1767
|
+
)
|
1768
|
+
for matching_key in matching_slo_keys:
|
1769
|
+
for breached_slo in breached_slo_map[matching_key]:
|
1770
|
+
logging.info(
|
1771
|
+
f"SLO: {breached_slo.slo.name} of document {breached_slo.slo_document_name} is breached. Current value: {breached_slo.current_slo_value} Expected: {breached_slo.slo.slo_target}"
|
1772
|
+
)
|
1773
|
+
return True
|
1695
1774
|
|
1696
1775
|
@staticmethod
|
1697
1776
|
def remove_none_values(d: dict[Any, Any] | None) -> dict[Any, Any]:
|
@@ -1725,7 +1804,6 @@ class SaasHerder: # pylint: disable=too-many-public-methods
|
|
1725
1804
|
dtc = SaasHerder.remove_none_values(trigger_spec.state_content)
|
1726
1805
|
if ctc == dtc:
|
1727
1806
|
continue
|
1728
|
-
|
1729
1807
|
if self.include_trigger_trace:
|
1730
1808
|
trigger_spec.reason = f"{self.repo_url}/commit/{RunningState().commit}"
|
1731
1809
|
# For now we count every saas config change as an auto-promotion
|
@@ -1820,6 +1898,9 @@ class SaasHerder: # pylint: disable=too-many-public-methods
|
|
1820
1898
|
namespace_name=target.namespace.name,
|
1821
1899
|
target_name=target.name,
|
1822
1900
|
state_content=serializable_target_config,
|
1901
|
+
resource_template_url=rt.url,
|
1902
|
+
target_ref=target.ref,
|
1903
|
+
slos=target.slos or None,
|
1823
1904
|
)
|
1824
1905
|
configs[trigger_spec.state_key] = trigger_spec
|
1825
1906
|
|
{qontract_reconcile-0.10.2.dev207.dist-info → qontract_reconcile-0.10.2.dev209.dist-info}/WHEEL
RENAMED
File without changes
|
File without changes
|