qontract-reconcile 0.10.2.dev166__py3-none-any.whl → 0.10.2.dev168__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.dev166
3
+ Version: 0.10.2.dev168
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
@@ -17,7 +17,7 @@ reconcile/dashdotdb_base.py,sha256=83ZWIf5JJk3P_D69y2TmXRcQr6ELJGlv10OM0h7fJVs,4
17
17
  reconcile/dashdotdb_cso.py,sha256=QRK0YfIqO4rehs8btD3l_GXIO2ZIycTQEKEthBdB0xA,3639
18
18
  reconcile/dashdotdb_dora.py,sha256=olQnGp4JYpoh1lQEf9kHc2y3bMaAIUXEB6eFohWH8Io,17859
19
19
  reconcile/dashdotdb_dvo.py,sha256=lCkZ0iby6HrNQb-3kYb6xrt8wCjVUZYxKzz9SiStfHU,8946
20
- reconcile/dashdotdb_slo.py,sha256=PU1GzT6Uy07IIO3Y62cFfRfaBJYUPrMkMp71Up80_bg,8334
20
+ reconcile/dashdotdb_slo.py,sha256=TvKdMOtUZcZP9QydcUJMKh0zURHgOMN_RTpQpCkD1Z8,3960
21
21
  reconcile/database_access_manager.py,sha256=Z3aAmw2LsmMIIor-bOGzziVZdVNC82Gmw8oHBUAFf-8,25577
22
22
  reconcile/deadmanssnitch.py,sha256=n-5W-djUgwzpmdDM4eQIZpkkDmHY0vndt-42LJXI4Y8,7491
23
23
  reconcile/email_sender.py,sha256=38Wvl6WHqCwlqLx4oxVJOIeDmoJsyitD3g1F4jTkAj8,4246
@@ -227,7 +227,7 @@ reconcile/glitchtip_project_alerts/integration.py,sha256=BgMx-NyV9mTuv7Sotb2OioC
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=wNGZv8V6ivviCcwPLw34nzTR5fgwKRyE68Z93HbmBBs,2296576
230
+ reconcile/gql_definitions/introspection.json,sha256=zD5QWpv9KYduZHr8a6dFoGz-oSHM1ItN1Trn02Lh7XQ,2297479
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=bN5i4mks10Z23KJSj7jqp966Osq2dps4d-sPH9gjxEA,7008
@@ -295,7 +295,7 @@ reconcile/gql_definitions/common/pipeline_providers.py,sha256=9rpsqPuvj82B4ki56x
295
295
  reconcile/gql_definitions/common/quay_instances.py,sha256=toBkdYYVTmEafezAHZKgaW-mQ29xEW6jeronzsAlNyI,1786
296
296
  reconcile/gql_definitions/common/quay_orgs.py,sha256=NhA8kqvVUDbrsryEvEL5mlIv5R3T4XNhSRXtfL_yptY,1788
297
297
  reconcile/gql_definitions/common/reserved_networks.py,sha256=yP9qSQCaSQcva-ZgTnZp09qH27ur5_qK080ToIs04MY,2560
298
- reconcile/gql_definitions/common/saas_files.py,sha256=DA6aJspbuoSkVHlFI4HQ-YjdE5iN3eVg1k2lNtW0840,16863
298
+ reconcile/gql_definitions/common/saas_files.py,sha256=d1L_S5LgCMa4QuAqZGQYTWb5L_nPCOxSEjU4O__OeBU,17728
299
299
  reconcile/gql_definitions/common/saas_target_namespaces.py,sha256=4VYP2VbwY8WVwtSFk2-jsUNhSmRD3X4FWKxetOKvmd0,2835
300
300
  reconcile/gql_definitions/common/saasherder_settings.py,sha256=nqQLcMwYxLseqq0BEcVvmrpIj2eQq0h8XDSpLN6GGCw,1793
301
301
  reconcile/gql_definitions/common/slack_workspaces.py,sha256=2o0kgi4QiaRuNmZJnc_By4F6NsKIdRaXkrufRQw7Nok,1753
@@ -307,7 +307,7 @@ reconcile/gql_definitions/cost_report/app_names.py,sha256=fzqYXyiTSll359J1F1o7qa
307
307
  reconcile/gql_definitions/cost_report/cost_namespaces.py,sha256=URRozAgSa9OnkqOCZf3MGH21_wcnsqYl0n-olXdjQH0,2286
308
308
  reconcile/gql_definitions/cost_report/settings.py,sha256=0nhBDJ5MZ1m7XkNDGrRLmsnUbzqZ4WRh_DDEEzKhcxU,2153
309
309
  reconcile/gql_definitions/dashdotdb_slo/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
310
- reconcile/gql_definitions/dashdotdb_slo/slo_documents_query.py,sha256=MYYpVOc8Ze9w7k6-tlUkp5OaPG_5bqHPS5FhfWTw00U,4335
310
+ reconcile/gql_definitions/dashdotdb_slo/slo_documents_query.py,sha256=a1zLeL_NCbK25fOeT1gZOch8HNPFcHhzVXQty3jKT_s,2430
311
311
  reconcile/gql_definitions/dynatrace_token_provider/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
312
312
  reconcile/gql_definitions/dynatrace_token_provider/dynatrace_bootstrap_tokens.py,sha256=5gTuAnR2rnx2k6Rn7FMEAzw6GCZ6F5HZbqkmJ9-3NI4,2244
313
313
  reconcile/gql_definitions/dynatrace_token_provider/token_specs.py,sha256=XGsMuB8gowRpqJjkD_KRomx-1OswzyWbF4qjVdhionk,2555
@@ -350,6 +350,7 @@ reconcile/gql_definitions/fragments/prometheus_instance.py,sha256=12ltnV9kdEw6Ln
350
350
  reconcile/gql_definitions/fragments/resource_limits_requirements.py,sha256=ucskQ_a8RxvFl5-IWxz5kk3g4-5Pvh_W4N3nLmuKxi0,744
351
351
  reconcile/gql_definitions/fragments/resource_requests_requirements.py,sha256=TFKO4YALFPanSvZvIJFz0dCioBU7i73Q6hkDtGMvs9I,736
352
352
  reconcile/gql_definitions/fragments/resource_values.py,sha256=-N2lNRhWp8PgocmIeX3U9f3l90Q97N2lXoq1pXdb_LE,742
353
+ reconcile/gql_definitions/fragments/saas_slo_document.py,sha256=6Ko_Kqny9gixPLKwr8RHL6DNx32rkNV24myurCVko-Q,2635
353
354
  reconcile/gql_definitions/fragments/saas_target_namespace.py,sha256=6f6WaerElaRi9_Ro-0CyWUkMHsbXlm0h9YXklftBwag,3991
354
355
  reconcile/gql_definitions/fragments/serviceaccount_token.py,sha256=2pG4rxAjvT-YsFBnm4zl301i7DCYznp99HOEGA-216I,1117
355
356
  reconcile/gql_definitions/fragments/terraform_state.py,sha256=S5QuTR9YlvUObiU7hevS9ybxZEssWoRGqCR9YtGwePs,1024
@@ -658,6 +659,7 @@ reconcile/utils/secret_reader.py,sha256=MaP56KZaAE35EyYbgAitdm6fUSxdzWeGFSOym9qi
658
659
  reconcile/utils/semver_helper.py,sha256=-WfPOMSA2v1h7hT3PwVf-Htg7wOsoKlQC1JdmDX2Ars,1268
659
660
  reconcile/utils/sharding.py,sha256=DDBHfs5TT9UgjmzewiXUjbncnrPuceAZWeOA4veGa7s,843
660
661
  reconcile/utils/slack_api.py,sha256=iaOFzv3wiZRhcgYK2NB4lsG6ymNsGk2MEuj0PgZVp7w,17355
662
+ reconcile/utils/slo_document_manager.py,sha256=CPgM2oH4AVzBqenakWo59R5yfwB62tnxSnSOHgir7l8,9500
661
663
  reconcile/utils/smtp_client.py,sha256=0xefB4I9E5eBB-FlxFJYjvz3Kvuqi_K3Ma_Wk0NAQKM,2779
662
664
  reconcile/utils/sqs_gateway.py,sha256=XNIf3PY4UCPNufP2Ul0UJj3fKlt5larBba-VTT-41Fg,2265
663
665
  reconcile/utils/state.py,sha256=az4tBmZ0EdbFcAGiBVUxs3cr2-BVWsuDQiNTvjjQq8s,16378
@@ -777,12 +779,12 @@ tools/app_sre_tekton_access_reporter.py,sha256=o9prLUgQpwO3msRWc2as1xT1y9OB3znkp
777
779
  tools/app_sre_tekton_access_revalidation.py,sha256=66nHEaY-bIqxIhpcmwN8AvQZu6ZXenfkg4Fut0pVZRM,2726
778
780
  tools/glitchtip_access_reporter.py,sha256=o01A6b88t3Wie6tj_tJWWVo2J01LxQ_a9giGm4UzEaU,2901
779
781
  tools/glitchtip_access_revalidation.py,sha256=PXN5wxl6OX8sxddPaakDF3X79nFLvpm-lz0mWLVelw0,2806
780
- tools/qontract_cli.py,sha256=VmwXfvYEUewhvTYA3M2ucjRzhCb2G42AWrb9asMsdSQ,157451
782
+ tools/qontract_cli.py,sha256=rmR4aUIghazzRPoxTcKY2YCZWKmYqpvwhS-p-uoeL-4,157549
781
783
  tools/sd_app_sre_alert_report.py,sha256=jQpJdXVID68bSNtJNOGDh0-ei1CfEUS4Itr4MAaBNFA,5062
782
784
  tools/template_validation.py,sha256=qpKYaTgk0GOPGa2Ct5_5sKdwIHtCAKIBGzsMPuJU5fw,3371
783
785
  tools/cli_commands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
784
786
  tools/cli_commands/container_images_report.py,sha256=SXh6sZ1dXXzd-2R5eeBufCtW3J4-Y55--0MZLdo4lr8,5409
785
- tools/cli_commands/erv2.py,sha256=5EekfLBoA0spsdUHrPH47_x7bxxe_q7dTWW7nDw3UxM,23833
787
+ tools/cli_commands/erv2.py,sha256=WJgom7Fe2HuM31QKieYs_3evJuH7DEyd53sV-FKX7PU,26047
786
788
  tools/cli_commands/gpg_encrypt.py,sha256=JWwds_Qg7KhSJMIGUh8TfI5-Jf17iUtmaEi4kWJxfVE,4907
787
789
  tools/cli_commands/systems_and_tools.py,sha256=EMHOF1AtUDaoSk0bbjl6oUKYAz4rTZjIBaF-6E6GspM,16816
788
790
  tools/cli_commands/cost_report/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -804,7 +806,7 @@ tools/saas_promotion_state/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJ
804
806
  tools/saas_promotion_state/saas_promotion_state.py,sha256=UfwwRLS5Ya4_Nh1w5n1dvoYtchQvYE9yj1VANt2IKqI,3925
805
807
  tools/sre_checkpoints/__init__.py,sha256=CDaDaywJnmRCLyl_NCcvxi-Zc0hTi_3OdwKiFOyS39I,145
806
808
  tools/sre_checkpoints/util.py,sha256=zEDbGr18ZeHNQwW8pUsr2JRjuXIPz--WAGJxZo9sv_Y,894
807
- qontract_reconcile-0.10.2.dev166.dist-info/METADATA,sha256=_e0XMBWL2FCdnLmJk8AkWVvocjGh8CMxIfjXsHt45ds,24627
808
- qontract_reconcile-0.10.2.dev166.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
809
- qontract_reconcile-0.10.2.dev166.dist-info/entry_points.txt,sha256=5i9l54La3vQrDLAdwDKQWC0iG4sV9RRfOb1BpvzOWLc,698
810
- qontract_reconcile-0.10.2.dev166.dist-info/RECORD,,
809
+ qontract_reconcile-0.10.2.dev168.dist-info/METADATA,sha256=wzA6vkcwYuN-6Jx92482hVcUXLcXr8p0BqSuz1gW-34,24627
810
+ qontract_reconcile-0.10.2.dev168.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
811
+ qontract_reconcile-0.10.2.dev168.dist-info/entry_points.txt,sha256=5i9l54La3vQrDLAdwDKQWC0iG4sV9RRfOb1BpvzOWLc,698
812
+ qontract_reconcile-0.10.2.dev168.dist-info/RECORD,,
@@ -1,11 +1,6 @@
1
- from collections.abc import Iterable
2
- from dataclasses import dataclass
3
- from math import isnan
4
1
  from typing import Any
5
2
 
6
- import jinja2
7
3
  import requests
8
- from requests import Response
9
4
  from sretoolbox.utils import threaded
10
5
 
11
6
  from reconcile.dashdotdb_base import (
@@ -13,9 +8,9 @@ from reconcile.dashdotdb_base import (
13
8
  DashdotdbBase,
14
9
  )
15
10
  from reconcile.gql_definitions.dashdotdb_slo.slo_documents_query import (
16
- SLODocumentV1,
17
11
  query,
18
12
  )
13
+ from reconcile.gql_definitions.fragments.saas_slo_document import SLODocument
19
14
  from reconcile.typed_queries.app_interface_vault_settings import (
20
15
  get_app_interface_vault_settings,
21
16
  )
@@ -24,40 +19,22 @@ from reconcile.utils.secret_reader import (
24
19
  SecretReaderBase,
25
20
  create_secret_reader,
26
21
  )
22
+ from reconcile.utils.slo_document_manager import (
23
+ SLODetails,
24
+ SLODocumentManager,
25
+ )
27
26
 
28
27
  QONTRACT_INTEGRATION = "dashdotdb-slo"
28
+ READ_TIMEOUT = 300
29
+ MAX_RETRIES = 2
29
30
 
30
31
 
31
- def get_slo_documents() -> list[SLODocumentV1]:
32
+ def get_slo_documents() -> list[SLODocument]:
32
33
  gqlapi = gql.get_api()
33
34
  data = query(gqlapi.query)
34
35
  return list(data.slo_documents or [])
35
36
 
36
37
 
37
- @dataclass
38
- class ServiceSLO:
39
- name: str
40
- sli_type: str
41
- slo_doc_name: str
42
- namespace_name: str
43
- cluster_name: str
44
- service_name: str
45
- value: float
46
- target: float
47
-
48
- def dashdot_payload(self) -> dict[str, Any]:
49
- return {
50
- "name": self.name,
51
- "SLIType": self.sli_type,
52
- "SLODoc": {"name": self.slo_doc_name},
53
- "namespace": {"name": self.namespace_name},
54
- "cluster": {"name": self.cluster_name},
55
- "service": {"name": self.service_name},
56
- "value": self.value,
57
- "target": self.target,
58
- }
59
-
60
-
61
38
  class DashdotdbSLO(DashdotdbBase):
62
39
  def __init__(
63
40
  self, dry_run: bool, thread_pool_size: int, secret_reader: SecretReaderBase
@@ -70,19 +47,28 @@ class DashdotdbSLO(DashdotdbBase):
70
47
  secret_reader=secret_reader,
71
48
  )
72
49
 
73
- def _post(self, service_slos: Iterable[ServiceSLO]) -> Response | None:
74
- for item in service_slos:
75
- LOG.debug(f"About to POST SLO JSON item to dashdotDB:\n{item}\n")
76
-
77
- response = None
78
-
79
- for item in service_slos:
80
- slo_name = item.name
81
- endpoint = f"{self.dashdotdb_url}/api/v1/serviceslometrics/{slo_name}"
82
- payload = item.dashdot_payload()
83
- if self.dry_run:
84
- continue
50
+ @staticmethod
51
+ def get_dash_dot_db_payload(slo: SLODetails) -> dict[str, Any]:
52
+ return {
53
+ "name": slo.slo.name,
54
+ "SLIType": slo.slo.sli_type,
55
+ "SLODoc": {"name": slo.slo_document_name},
56
+ "namespace": {"name": slo.namespace_name},
57
+ "cluster": {"name": slo.cluster_name},
58
+ "service": {"name": slo.service_name},
59
+ "value": slo.current_slo_value,
60
+ "target": slo.slo.slo_target,
61
+ }
85
62
 
63
+ def _post(self, service_slo: SLODetails) -> None:
64
+ LOG.debug(f"About to POST SLO JSON item to dashdotDB:\n{service_slo}\n")
65
+ slo_name = service_slo.slo.name
66
+ endpoint = f"{self.dashdotdb_url}/api/v1/serviceslometrics/{slo_name}"
67
+ if service_slo.slo.slo_target_unit == "percent_0_1":
68
+ service_slo.current_slo_value *= 100
69
+ service_slo.slo.slo_target *= 100
70
+ payload = self.get_dash_dot_db_payload(service_slo)
71
+ if not self.dry_run:
86
72
  LOG.info("%s syncing slo %s", self.logmarker, slo_name)
87
73
  try:
88
74
  response = self._do_post(endpoint, payload)
@@ -94,127 +80,30 @@ class DashdotdbSLO(DashdotdbBase):
94
80
  LOG.error("%s error posting %s - %s", self.logmarker, slo_name, details)
95
81
 
96
82
  LOG.info("%s slo %s synced", self.logmarker, slo_name)
97
- return response
98
-
99
- def _get_service_slo(self, slo_document: SLODocumentV1) -> list[ServiceSLO]:
100
- LOG.debug("SLO: processing %s", slo_document.name)
101
- result: list[ServiceSLO] = []
102
- for namespace_access in slo_document.namespaces:
103
- if (
104
- namespace_access.slo_namespace
105
- and namespace_access.prometheus_access is None
106
- ):
107
- continue
108
-
109
- ns = namespace_access.namespace
110
- promtoken: str | None = None
111
- username: str | None = None
112
- password: str | None = None
113
- if namespace_access.prometheus_access:
114
- promurl = namespace_access.prometheus_access.url
115
- if (
116
- namespace_access.prometheus_access.username
117
- and namespace_access.prometheus_access.password
118
- ):
119
- username = self.secret_reader.read_secret(
120
- namespace_access.prometheus_access.username
121
- )
122
- password = self.secret_reader.read_secret(
123
- namespace_access.prometheus_access.password
124
- )
125
- else:
126
- promurl = ns.cluster.prometheus_url
127
- if not ns.cluster.automation_token:
128
- LOG.error(
129
- "namespace does not have automation token set %s - skipping", ns
130
- )
131
- continue
132
- promtoken = self._get_automation_token(ns.cluster.automation_token)
133
- for slo in slo_document.slos or []:
134
- unit = slo.slo_target_unit
135
- expr = slo.expr
136
- template = jinja2.Template(expr)
137
- window = slo.slo_parameters.window
138
- promquery = template.render({"window": window})
139
-
140
- try:
141
- prom_response = self._promget(
142
- url=promurl,
143
- params={"query": (f"{promquery}")},
144
- token=promtoken,
145
- username=username,
146
- password=password,
147
- )
148
- except requests.exceptions.ConnectionError as error:
149
- # This can happen when prometheus is unreachable, or when running locally
150
- # and some prometheus URL are openshift service names. The trick is to run
151
- # with `oc port-forward` and update the local hosts file if we need to query those.
152
- LOG.error(
153
- f"{self.logmarker} Could not reach prometheus at {promurl}: {error}."
154
- f"Skipping SLOs from SLO doc {slo_document.name}"
155
- )
156
- # cannot connect to this prometheus, skip all
157
- raise
158
- except requests.exceptions.HTTPError as error:
159
- LOG.error(
160
- f"{self.logmarker} Error wile querying {promurl}: {error}."
161
- f"Skipping SLO '{slo.name} from SLO doc {slo_document.name}"
162
- )
163
- # it could be a query issue, keep processing other SLOs from this doc
164
- continue
165
-
166
- prom_result = prom_response["data"]["result"]
167
- if not prom_result:
168
- continue
169
-
170
- slo_value = prom_result[0]["value"]
171
- if not slo_value:
172
- continue
173
-
174
- slo_value = float(slo_value[1])
175
- if isnan(slo_value):
176
- LOG.warning(
177
- f"{self.logmarker} Skipping SLO '{slo.name}' in SLO doc '{slo_document.name}'"
178
- "as the obtained value is not a number (maybe a division by 0?)"
179
- )
180
- continue
181
- slo_target = float(slo.slo_target)
182
-
183
- # In Dash.DB we want to always store SLOs in percentages
184
- if unit == "percent_0_1":
185
- slo_value *= 100
186
- slo_target *= 100
187
-
188
- result.append(
189
- ServiceSLO(
190
- name=slo.name,
191
- sli_type=slo.sli_type,
192
- namespace_name=ns.name,
193
- cluster_name=ns.cluster.name,
194
- service_name=ns.app.name,
195
- value=slo_value,
196
- target=slo_target,
197
- slo_doc_name=slo_document.name,
198
- )
199
- )
200
- return result
201
83
 
202
84
  def run(self) -> None:
203
85
  slo_documents = get_slo_documents()
204
86
 
205
- service_slos: list[list[ServiceSLO]] = threaded.run(
206
- func=self._get_service_slo,
207
- iterable=slo_documents,
87
+ slo_document_manager = SLODocumentManager(
88
+ slo_documents=slo_documents,
89
+ secret_reader=self.secret_reader,
208
90
  thread_pool_size=self.thread_pool_size,
91
+ read_timeout=READ_TIMEOUT,
92
+ max_retries=MAX_RETRIES,
209
93
  )
210
94
 
95
+ slo_details_list = slo_document_manager.get_current_slo_list()
96
+ valid_slo_list = [slo for slo in slo_details_list if slo]
97
+
211
98
  self._get_token()
212
- threaded.run(
213
- func=self._post,
214
- iterable=service_slos,
215
- thread_pool_size=self.thread_pool_size,
216
- )
217
- self._close_token()
99
+ try:
100
+ threaded.run(
101
+ func=self._post,
102
+ iterable=valid_slo_list,
103
+ thread_pool_size=self.thread_pool_size,
104
+ )
105
+ finally:
106
+ self._close_token()
218
107
 
219
108
 
220
109
  def run(dry_run: bool = False, thread_pool_size: int = 10) -> None:
@@ -18,6 +18,7 @@ from pydantic import ( # noqa: F401 # pylint: disable=W0611
18
18
  )
19
19
 
20
20
  from reconcile.gql_definitions.fragments.oc_connection_cluster import OcConnectionCluster
21
+ from reconcile.gql_definitions.fragments.saas_slo_document import SLODocument
21
22
  from reconcile.gql_definitions.fragments.saas_target_namespace import SaasTargetNamespace
22
23
  from reconcile.gql_definitions.fragments.vault_secret import VaultSecret
23
24
 
@@ -53,6 +54,50 @@ fragment OcConnectionCluster on Cluster_v1 {
53
54
  }
54
55
  }
55
56
 
57
+ fragment SLODocument on SLODocument_v1 {
58
+ name
59
+ namespaces {
60
+ prometheusAccess {
61
+ url
62
+ username {
63
+ ... VaultSecret
64
+ }
65
+ password {
66
+ ... VaultSecret
67
+ }
68
+ }
69
+ namespace {
70
+ name
71
+ app {
72
+ name
73
+ }
74
+ cluster {
75
+ name
76
+ automationToken {
77
+ ... VaultSecret
78
+ }
79
+ prometheusUrl
80
+ spec {
81
+ private
82
+ }
83
+ }
84
+ }
85
+ SLONamespace {
86
+ name
87
+ }
88
+ }
89
+ slos {
90
+ name
91
+ expr
92
+ SLIType
93
+ SLOParameters {
94
+ window
95
+ }
96
+ SLOTarget
97
+ SLOTargetUnit
98
+ }
99
+ }
100
+
56
101
  fragment SaasTargetNamespace on Namespace_v1 {
57
102
  name
58
103
  labels
@@ -253,6 +298,9 @@ query SaasFiles {
253
298
  namespace {
254
299
  ...SaasTargetNamespace
255
300
  }
301
+ slos {
302
+ ...SLODocument
303
+ }
256
304
  namespaceSelector {
257
305
  jsonPathSelectors {
258
306
  include
@@ -512,6 +560,7 @@ class SaasResourceTemplateTargetV2(ConfiguredBaseModel):
512
560
  path: Optional[str] = Field(..., alias="path")
513
561
  name: Optional[str] = Field(..., alias="name")
514
562
  namespace: Optional[SaasTargetNamespace] = Field(..., alias="namespace")
563
+ slos: Optional[list[SLODocument]] = Field(..., alias="slos")
515
564
  namespace_selector: Optional[SaasResourceTemplateTargetNamespaceSelectorV1] = Field(..., alias="namespaceSelector")
516
565
  provider: Optional[str] = Field(..., alias="provider")
517
566
  ref: str = Field(..., alias="ref")
@@ -17,19 +17,11 @@ from pydantic import ( # noqa: F401 # pylint: disable=W0611
17
17
  Json,
18
18
  )
19
19
 
20
- from reconcile.gql_definitions.fragments.vault_secret import VaultSecret
20
+ from reconcile.gql_definitions.fragments.saas_slo_document import SLODocument
21
21
 
22
22
 
23
23
  DEFINITION = """
24
- fragment VaultSecret on VaultSecret_v1 {
25
- path
26
- field
27
- version
28
- format
29
- }
30
-
31
- query SLODocuments {
32
- slo_documents: slo_document_v1 {
24
+ fragment SLODocument on SLODocument_v1 {
33
25
  name
34
26
  namespaces {
35
27
  prometheusAccess {
@@ -71,6 +63,18 @@ query SLODocuments {
71
63
  SLOTarget
72
64
  SLOTargetUnit
73
65
  }
66
+ }
67
+
68
+ fragment VaultSecret on VaultSecret_v1 {
69
+ path
70
+ field
71
+ version
72
+ format
73
+ }
74
+
75
+ query SLODocuments {
76
+ slo_documents: slo_document_v1 {
77
+ ... SLODocument
74
78
  }
75
79
  }
76
80
  """
@@ -82,64 +86,8 @@ class ConfiguredBaseModel(BaseModel):
82
86
  extra=Extra.forbid
83
87
 
84
88
 
85
- class SLOExternalPrometheusAccessV1(ConfiguredBaseModel):
86
- url: str = Field(..., alias="url")
87
- username: Optional[VaultSecret] = Field(..., alias="username")
88
- password: Optional[VaultSecret] = Field(..., alias="password")
89
-
90
-
91
- class AppV1(ConfiguredBaseModel):
92
- name: str = Field(..., alias="name")
93
-
94
-
95
- class ClusterSpecV1(ConfiguredBaseModel):
96
- private: bool = Field(..., alias="private")
97
-
98
-
99
- class ClusterV1(ConfiguredBaseModel):
100
- name: str = Field(..., alias="name")
101
- automation_token: Optional[VaultSecret] = Field(..., alias="automationToken")
102
- prometheus_url: str = Field(..., alias="prometheusUrl")
103
- spec: Optional[ClusterSpecV1] = Field(..., alias="spec")
104
-
105
-
106
- class NamespaceV1(ConfiguredBaseModel):
107
- name: str = Field(..., alias="name")
108
- app: AppV1 = Field(..., alias="app")
109
- cluster: ClusterV1 = Field(..., alias="cluster")
110
-
111
-
112
- class SLONamespacesV1_NamespaceV1(ConfiguredBaseModel):
113
- name: str = Field(..., alias="name")
114
-
115
-
116
- class SLONamespacesV1(ConfiguredBaseModel):
117
- prometheus_access: Optional[SLOExternalPrometheusAccessV1] = Field(..., alias="prometheusAccess")
118
- namespace: NamespaceV1 = Field(..., alias="namespace")
119
- slo_namespace: Optional[SLONamespacesV1_NamespaceV1] = Field(..., alias="SLONamespace")
120
-
121
-
122
- class SLODocumentSLOSLOParametersV1(ConfiguredBaseModel):
123
- window: str = Field(..., alias="window")
124
-
125
-
126
- class SLODocumentSLOV1(ConfiguredBaseModel):
127
- name: str = Field(..., alias="name")
128
- expr: str = Field(..., alias="expr")
129
- sli_type: str = Field(..., alias="SLIType")
130
- slo_parameters: SLODocumentSLOSLOParametersV1 = Field(..., alias="SLOParameters")
131
- slo_target: float = Field(..., alias="SLOTarget")
132
- slo_target_unit: str = Field(..., alias="SLOTargetUnit")
133
-
134
-
135
- class SLODocumentV1(ConfiguredBaseModel):
136
- name: str = Field(..., alias="name")
137
- namespaces: list[SLONamespacesV1] = Field(..., alias="namespaces")
138
- slos: Optional[list[SLODocumentSLOV1]] = Field(..., alias="slos")
139
-
140
-
141
89
  class SLODocumentsQueryData(ConfiguredBaseModel):
142
- slo_documents: Optional[list[SLODocumentV1]] = Field(..., alias="slo_documents")
90
+ slo_documents: Optional[list[SLODocument]] = Field(..., alias="slo_documents")
143
91
 
144
92
 
145
93
  def query(query_func: Callable, **kwargs: Any) -> SLODocumentsQueryData:
@@ -0,0 +1,82 @@
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.vault_secret import VaultSecret
21
+
22
+
23
+ class ConfiguredBaseModel(BaseModel):
24
+ class Config:
25
+ smart_union=True
26
+ extra=Extra.forbid
27
+
28
+
29
+ class SLOExternalPrometheusAccessV1(ConfiguredBaseModel):
30
+ url: str = Field(..., alias="url")
31
+ username: Optional[VaultSecret] = Field(..., alias="username")
32
+ password: Optional[VaultSecret] = Field(..., alias="password")
33
+
34
+
35
+ class AppV1(ConfiguredBaseModel):
36
+ name: str = Field(..., alias="name")
37
+
38
+
39
+ class ClusterSpecV1(ConfiguredBaseModel):
40
+ private: bool = Field(..., alias="private")
41
+
42
+
43
+ class ClusterV1(ConfiguredBaseModel):
44
+ name: str = Field(..., alias="name")
45
+ automation_token: Optional[VaultSecret] = Field(..., alias="automationToken")
46
+ prometheus_url: str = Field(..., alias="prometheusUrl")
47
+ spec: Optional[ClusterSpecV1] = Field(..., alias="spec")
48
+
49
+
50
+ class NamespaceV1(ConfiguredBaseModel):
51
+ name: str = Field(..., alias="name")
52
+ app: AppV1 = Field(..., alias="app")
53
+ cluster: ClusterV1 = Field(..., alias="cluster")
54
+
55
+
56
+ class SLONamespacesV1_NamespaceV1(ConfiguredBaseModel):
57
+ name: str = Field(..., alias="name")
58
+
59
+
60
+ class SLONamespacesV1(ConfiguredBaseModel):
61
+ prometheus_access: Optional[SLOExternalPrometheusAccessV1] = Field(..., alias="prometheusAccess")
62
+ namespace: NamespaceV1 = Field(..., alias="namespace")
63
+ slo_namespace: Optional[SLONamespacesV1_NamespaceV1] = Field(..., alias="SLONamespace")
64
+
65
+
66
+ class SLODocumentSLOSLOParametersV1(ConfiguredBaseModel):
67
+ window: str = Field(..., alias="window")
68
+
69
+
70
+ class SLODocumentSLOV1(ConfiguredBaseModel):
71
+ name: str = Field(..., alias="name")
72
+ expr: str = Field(..., alias="expr")
73
+ sli_type: str = Field(..., alias="SLIType")
74
+ slo_parameters: SLODocumentSLOSLOParametersV1 = Field(..., alias="SLOParameters")
75
+ slo_target: float = Field(..., alias="SLOTarget")
76
+ slo_target_unit: str = Field(..., alias="SLOTargetUnit")
77
+
78
+
79
+ class SLODocument(ConfiguredBaseModel):
80
+ name: str = Field(..., alias="name")
81
+ namespaces: list[SLONamespacesV1] = Field(..., alias="namespaces")
82
+ slos: Optional[list[SLODocumentSLOV1]] = Field(..., alias="slos")