qontract-reconcile 0.10.2.dev44__py3-none-any.whl → 0.10.2.dev46__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.dev44.dist-info → qontract_reconcile-0.10.2.dev46.dist-info}/METADATA +1 -1
- {qontract_reconcile-0.10.2.dev44.dist-info → qontract_reconcile-0.10.2.dev46.dist-info}/RECORD +17 -15
- reconcile/external_resources/aws.py +101 -11
- reconcile/external_resources/factories.py +23 -6
- reconcile/external_resources/manager.py +12 -7
- reconcile/external_resources/model.py +44 -2
- reconcile/external_resources/reconciler.py +10 -0
- reconcile/external_resources/state.py +74 -1
- reconcile/gql_definitions/external_resources/external_resources_modules.py +17 -0
- reconcile/gql_definitions/external_resources/external_resources_namespaces.py +32 -64
- reconcile/gql_definitions/external_resources/external_resources_settings.py +17 -0
- reconcile/gql_definitions/external_resources/fragments/__init__.py +0 -0
- reconcile/gql_definitions/external_resources/fragments/external_resources_module_overrides.py +36 -0
- reconcile/gql_definitions/introspection.json +40 -0
- tools/cli_commands/erv2.py +2 -2
- {qontract_reconcile-0.10.2.dev44.dist-info → qontract_reconcile-0.10.2.dev46.dist-info}/WHEEL +0 -0
- {qontract_reconcile-0.10.2.dev44.dist-info → qontract_reconcile-0.10.2.dev46.dist-info}/entry_points.txt +0 -0
{qontract_reconcile-0.10.2.dev44.dist-info → qontract_reconcile-0.10.2.dev46.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.dev46
|
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.dev44.dist-info → qontract_reconcile-0.10.2.dev46.dist-info}/RECORD
RENAMED
@@ -195,17 +195,17 @@ reconcile/endpoints_discovery/integration.py,sha256=fzy5tv4c_6WoAZGGBNJ276NVNB1O
|
|
195
195
|
reconcile/endpoints_discovery/merge_request.py,sha256=_yLb4tnvoZMCko8rta2C_CvOInJa9pa3HzSmHNtjgGU,2978
|
196
196
|
reconcile/endpoints_discovery/merge_request_manager.py,sha256=wUMsumxv8RnWaRattax4HfoRlhtVzmgro3GiJJ1C4Vc,6392
|
197
197
|
reconcile/external_resources/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
198
|
-
reconcile/external_resources/aws.py,sha256=
|
199
|
-
reconcile/external_resources/factories.py,sha256=
|
198
|
+
reconcile/external_resources/aws.py,sha256=KAs656zj4oZYpVbgWsDLXnJWJlLOZdR1JnRhikbF4x0,10712
|
199
|
+
reconcile/external_resources/factories.py,sha256=C0QHT0soEv6z99-ELAAE19S5MaMHhV0t1fSiQn0Coc4,5970
|
200
200
|
reconcile/external_resources/integration.py,sha256=JF38M7R0Z4ADUTx57TZqSZH9k_xpPlbAxQAcGyIISuM,6925
|
201
201
|
reconcile/external_resources/integration_secrets_sync.py,sha256=dX09O3r6KURziUYYfiki10orNjOGVma-XojhVqd0ww4,1667
|
202
|
-
reconcile/external_resources/manager.py,sha256=
|
202
|
+
reconcile/external_resources/manager.py,sha256=ZagwLn6YQ1XmgmMN3qpuDzQsQxa4VOYl-IQPZBwCDqM,17103
|
203
203
|
reconcile/external_resources/meta.py,sha256=noaytFzmShpzLA_ebGh7wuP45mOfHIOnnoUxivjDa1I,672
|
204
204
|
reconcile/external_resources/metrics.py,sha256=KiBjMUaN_z0cSkF_7Ar_a8RiuiwVqjyMcVdISlxhzXE,3898
|
205
|
-
reconcile/external_resources/model.py,sha256=
|
206
|
-
reconcile/external_resources/reconciler.py,sha256=
|
205
|
+
reconcile/external_resources/model.py,sha256=dxwiyI3J9xyLeue8_W9NJoap-CkKLMAoY0S0ml5-NbU,13450
|
206
|
+
reconcile/external_resources/reconciler.py,sha256=PK00cyMfBZLHH0W7w2bNomgAy85SotIVXbCBkGPSJdM,9432
|
207
207
|
reconcile/external_resources/secrets_sync.py,sha256=50fK4fzgSz-K8uy5_DQQWA_ju_rTDYAC2HRymgfY7TA,16344
|
208
|
-
reconcile/external_resources/state.py,sha256=
|
208
|
+
reconcile/external_resources/state.py,sha256=gF3ACdl7YiUlbQ4uEGrD6i_Txxqr6mT9f8IFlTQ-8dY,13176
|
209
209
|
reconcile/glitchtip/README.md,sha256=rfXT6jNP9khJW65jL7I2PgoxvxgcGGuJF8NpbzufEQ4,4335
|
210
210
|
reconcile/glitchtip/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
211
211
|
reconcile/glitchtip/integration.py,sha256=vCyg8W4ZUGxjU8tB1Gkre_auSpzo83n05mmO8_-7al0,8263
|
@@ -215,7 +215,7 @@ reconcile/glitchtip_project_alerts/integration.py,sha256=BgMx-NyV9mTuv7Sotb2OioC
|
|
215
215
|
reconcile/glitchtip_project_dsn/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
216
216
|
reconcile/glitchtip_project_dsn/integration.py,sha256=2iugub-kHYkHNK33n0v9_TeWonuxCPah_VkoTPvaajE,8077
|
217
217
|
reconcile/gql_definitions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
218
|
-
reconcile/gql_definitions/introspection.json,sha256=
|
218
|
+
reconcile/gql_definitions/introspection.json,sha256=jAWK0rPdJY39eevr2NWgD8lqbJew_m5BIhyEMbb_3lo,2236885
|
219
219
|
reconcile/gql_definitions/acs/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
220
220
|
reconcile/gql_definitions/acs/acs_instances.py,sha256=L91WW9LbhJbBSrECqShQpFtjoBOsmNIYLRpMbx1io5o,2181
|
221
221
|
reconcile/gql_definitions/acs/acs_policies.py,sha256=bN5i4mks10Z23KJSj7jqp966Osq2dps4d-sPH9gjxEA,7008
|
@@ -299,9 +299,11 @@ reconcile/gql_definitions/endpoints_discovery/__init__.py,sha256=47DEQpj8HBSa-_T
|
|
299
299
|
reconcile/gql_definitions/endpoints_discovery/apps.py,sha256=aBWRAwDUJQ32ghJS4cPQcR9SNl20Fcwd3pxHDB3YJQY,3172
|
300
300
|
reconcile/gql_definitions/external_resources/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
301
301
|
reconcile/gql_definitions/external_resources/aws_accounts.py,sha256=XR69j9dpTQ0gv8y-AZN7AJ0dPvO-wbHscyCDgrax6Bk,2046
|
302
|
-
reconcile/gql_definitions/external_resources/external_resources_modules.py,sha256=
|
303
|
-
reconcile/gql_definitions/external_resources/external_resources_namespaces.py,sha256
|
304
|
-
reconcile/gql_definitions/external_resources/external_resources_settings.py,sha256=
|
302
|
+
reconcile/gql_definitions/external_resources/external_resources_modules.py,sha256=JViHtDWEBwjStBUo_bUdm_sxdpjCHcoATeFvwFRLQpU,3009
|
303
|
+
reconcile/gql_definitions/external_resources/external_resources_namespaces.py,sha256=-0Q48lfH-fxAvwqYfXbLQ1aP7bFFh1BRQIYPnF7W9ZI,43067
|
304
|
+
reconcile/gql_definitions/external_resources/external_resources_settings.py,sha256=WBkJqnoyYCe1Vimwbp_Pa0RdyTdmWNf6oEWyA749QzA,3589
|
305
|
+
reconcile/gql_definitions/external_resources/fragments/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
306
|
+
reconcile/gql_definitions/external_resources/fragments/external_resources_module_overrides.py,sha256=T_qWCRtzU8F9frebBXG9TkeQdrKGt3R9YinSngPoFqM,1262
|
305
307
|
reconcile/gql_definitions/fragments/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
306
308
|
reconcile/gql_definitions/fragments/aus_organization.py,sha256=uBKbTuBa3CZmTXR5HOcGhRcu2U9kM93KbYmoWTxcpB0,4767
|
307
309
|
reconcile/gql_definitions/fragments/aws_account_common.py,sha256=3-7ZAP6GSff7Z2Syz2VQCLY4IySqBOSVmceaRiVNQpw,2385
|
@@ -751,7 +753,7 @@ tools/sd_app_sre_alert_report.py,sha256=jQpJdXVID68bSNtJNOGDh0-ei1CfEUS4Itr4MAaB
|
|
751
753
|
tools/template_validation.py,sha256=qpKYaTgk0GOPGa2Ct5_5sKdwIHtCAKIBGzsMPuJU5fw,3371
|
752
754
|
tools/cli_commands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
753
755
|
tools/cli_commands/container_images_report.py,sha256=8fG9XU-eEhJ7hKCdQzBcdPpvIJR-8WGkHOgFEulpfYQ,5213
|
754
|
-
tools/cli_commands/erv2.py,sha256=
|
756
|
+
tools/cli_commands/erv2.py,sha256=VxUlNXllo947UwmtvS-42IeI9x_t_X3MHrrSI3K_GRo,23274
|
755
757
|
tools/cli_commands/gpg_encrypt.py,sha256=NhzwN49UN7P5_FJgTUN5A4BIwNbFokIE4lwDax2iP5k,4891
|
756
758
|
tools/cli_commands/systems_and_tools.py,sha256=EMHOF1AtUDaoSk0bbjl6oUKYAz4rTZjIBaF-6E6GspM,16816
|
757
759
|
tools/cli_commands/cost_report/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -773,7 +775,7 @@ tools/saas_promotion_state/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJ
|
|
773
775
|
tools/saas_promotion_state/saas_promotion_state.py,sha256=UfwwRLS5Ya4_Nh1w5n1dvoYtchQvYE9yj1VANt2IKqI,3925
|
774
776
|
tools/sre_checkpoints/__init__.py,sha256=CDaDaywJnmRCLyl_NCcvxi-Zc0hTi_3OdwKiFOyS39I,145
|
775
777
|
tools/sre_checkpoints/util.py,sha256=zEDbGr18ZeHNQwW8pUsr2JRjuXIPz--WAGJxZo9sv_Y,894
|
776
|
-
qontract_reconcile-0.10.2.
|
777
|
-
qontract_reconcile-0.10.2.
|
778
|
-
qontract_reconcile-0.10.2.
|
779
|
-
qontract_reconcile-0.10.2.
|
778
|
+
qontract_reconcile-0.10.2.dev46.dist-info/METADATA,sha256=C5aPbZDbkFrj5j4y25HOkeCX-7xvvhvxDFYG1ymRabE,24665
|
779
|
+
qontract_reconcile-0.10.2.dev46.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
780
|
+
qontract_reconcile-0.10.2.dev46.dist-info/entry_points.txt,sha256=5i9l54La3vQrDLAdwDKQWC0iG4sV9RRfOb1BpvzOWLc,698
|
781
|
+
qontract_reconcile-0.10.2.dev46.dist-info/RECORD,,
|
@@ -1,9 +1,11 @@
|
|
1
|
+
import re
|
1
2
|
from abc import ABC, abstractmethod
|
2
3
|
from typing import Any
|
3
4
|
|
4
5
|
from reconcile.external_resources.model import (
|
5
6
|
ExternalResource,
|
6
7
|
ExternalResourceKey,
|
8
|
+
ExternalResourceModuleConfiguration,
|
7
9
|
ExternalResourcesInventory,
|
8
10
|
)
|
9
11
|
from reconcile.utils.external_resource_spec import (
|
@@ -21,10 +23,18 @@ class AWSResourceFactory(ABC):
|
|
21
23
|
self.secret_reader = secret_reader
|
22
24
|
|
23
25
|
@abstractmethod
|
24
|
-
def resolve(
|
26
|
+
def resolve(
|
27
|
+
self,
|
28
|
+
spec: ExternalResourceSpec,
|
29
|
+
module_conf: ExternalResourceModuleConfiguration,
|
30
|
+
) -> dict[str, Any]: ...
|
25
31
|
|
26
32
|
@abstractmethod
|
27
|
-
def validate(
|
33
|
+
def validate(
|
34
|
+
self,
|
35
|
+
resource: ExternalResource,
|
36
|
+
module_conf: ExternalResourceModuleConfiguration,
|
37
|
+
) -> None: ...
|
28
38
|
|
29
39
|
def find_linked_resources(
|
30
40
|
self, spec: ExternalResourceSpec
|
@@ -35,10 +45,18 @@ class AWSResourceFactory(ABC):
|
|
35
45
|
|
36
46
|
|
37
47
|
class AWSDefaultResourceFactory(AWSResourceFactory):
|
38
|
-
def resolve(
|
48
|
+
def resolve(
|
49
|
+
self,
|
50
|
+
spec: ExternalResourceSpec,
|
51
|
+
module_conf: ExternalResourceModuleConfiguration,
|
52
|
+
) -> dict[str, Any]:
|
39
53
|
return ResourceValueResolver(spec=spec, identifier_as_value=True).resolve()
|
40
54
|
|
41
|
-
def validate(
|
55
|
+
def validate(
|
56
|
+
self,
|
57
|
+
resource: ExternalResource,
|
58
|
+
module_conf: ExternalResourceModuleConfiguration,
|
59
|
+
) -> None: ...
|
42
60
|
|
43
61
|
|
44
62
|
class AWSElasticacheFactory(AWSDefaultResourceFactory):
|
@@ -49,7 +67,11 @@ class AWSElasticacheFactory(AWSDefaultResourceFactory):
|
|
49
67
|
"aws", provisioner, "elasticache", identifier
|
50
68
|
)
|
51
69
|
|
52
|
-
def resolve(
|
70
|
+
def resolve(
|
71
|
+
self,
|
72
|
+
spec: ExternalResourceSpec,
|
73
|
+
module_conf: ExternalResourceModuleConfiguration,
|
74
|
+
) -> dict[str, Any]:
|
53
75
|
"""Resolve the elasticache resource specification and translate some attributes to AWS >= 5.60.0 provider format."""
|
54
76
|
rvr = ResourceValueResolver(spec=spec, identifier_as_value=True)
|
55
77
|
data = rvr.resolve()
|
@@ -70,7 +92,11 @@ class AWSElasticacheFactory(AWSDefaultResourceFactory):
|
|
70
92
|
|
71
93
|
return data
|
72
94
|
|
73
|
-
def validate(
|
95
|
+
def validate(
|
96
|
+
self,
|
97
|
+
resource: ExternalResource,
|
98
|
+
module_conf: ExternalResourceModuleConfiguration,
|
99
|
+
) -> None:
|
74
100
|
"""Validate the elasticache resource specification."""
|
75
101
|
data = resource.data
|
76
102
|
if data.get("parameter_group"):
|
@@ -96,6 +122,8 @@ class AWSElasticacheFactory(AWSDefaultResourceFactory):
|
|
96
122
|
|
97
123
|
|
98
124
|
class AWSRdsFactory(AWSDefaultResourceFactory):
|
125
|
+
TIMEOUT_RE = re.compile(r"^\d+m$")
|
126
|
+
|
99
127
|
def _get_source_db_spec(
|
100
128
|
self, provisioner: str, identifier: str
|
101
129
|
) -> ExternalResourceSpec:
|
@@ -110,7 +138,11 @@ class AWSRdsFactory(AWSDefaultResourceFactory):
|
|
110
138
|
"aws", provisioner, "kms", identifier
|
111
139
|
)
|
112
140
|
|
113
|
-
def resolve(
|
141
|
+
def resolve(
|
142
|
+
self,
|
143
|
+
spec: ExternalResourceSpec,
|
144
|
+
module_conf: ExternalResourceModuleConfiguration,
|
145
|
+
) -> dict[str, Any]:
|
114
146
|
rvr = ResourceValueResolver(spec=spec, identifier_as_value=True)
|
115
147
|
data = rvr.resolve()
|
116
148
|
|
@@ -126,7 +158,7 @@ class AWSRdsFactory(AWSDefaultResourceFactory):
|
|
126
158
|
sourcedb_spec = self._get_source_db_spec(
|
127
159
|
spec.provisioner_name, data["replica_source"]
|
128
160
|
)
|
129
|
-
sourcedb = self.resolve(sourcedb_spec)
|
161
|
+
sourcedb = self.resolve(sourcedb_spec, module_conf)
|
130
162
|
sourcedb_region = (
|
131
163
|
sourcedb.get("region", None)
|
132
164
|
or sourcedb_spec.provisioner["resources_default_region"]
|
@@ -142,9 +174,59 @@ class AWSRdsFactory(AWSDefaultResourceFactory):
|
|
142
174
|
spec.provisioner_name, kms_key_id
|
143
175
|
).identifier
|
144
176
|
|
177
|
+
# If not timeouts are set, set default timeouts according to the module reconcile timeout configuration
|
178
|
+
# 5 minutes are substracted to let terraform finish gracefully before the Job is killed.
|
179
|
+
if "timeouts" not in data:
|
180
|
+
data["timeouts"] = {
|
181
|
+
"create": f"{module_conf.reconcile_timeout_minutes - 5}m",
|
182
|
+
"update": f"{module_conf.reconcile_timeout_minutes - 5}m",
|
183
|
+
"delete": f"{module_conf.reconcile_timeout_minutes - 5}m",
|
184
|
+
}
|
145
185
|
return data
|
146
186
|
|
147
|
-
def
|
187
|
+
def _get_timeout_minutes(
|
188
|
+
self,
|
189
|
+
timeout: str,
|
190
|
+
) -> int:
|
191
|
+
if not re.match(AWSRdsFactory.TIMEOUT_RE, timeout):
|
192
|
+
raise ValueError(
|
193
|
+
f"Invalid RDS instance timeout format: {timeout}. Specify timeout in minutes(m)."
|
194
|
+
)
|
195
|
+
return int(timeout[:-1])
|
196
|
+
|
197
|
+
def _validate_timeouts(
|
198
|
+
self,
|
199
|
+
resource: ExternalResource,
|
200
|
+
module_conf: ExternalResourceModuleConfiguration,
|
201
|
+
) -> None:
|
202
|
+
timeouts = resource.data.get("timeouts")
|
203
|
+
if not timeouts:
|
204
|
+
return
|
205
|
+
|
206
|
+
if not isinstance(timeouts, dict):
|
207
|
+
raise ValueError(
|
208
|
+
"Timeouts must be a dictionary with 'create', 'update' and/or 'delete' keys."
|
209
|
+
)
|
210
|
+
|
211
|
+
allowed_keys = {"create", "update", "delete"}
|
212
|
+
if unknown_keys := timeouts.keys() - allowed_keys:
|
213
|
+
raise ValueError(
|
214
|
+
f"Timeouts must be a dictionary with 'create', 'update' and/or 'delete' keys. Offending keys: {unknown_keys}."
|
215
|
+
)
|
216
|
+
|
217
|
+
for option, timeout in timeouts.items():
|
218
|
+
timeout_minutes = self._get_timeout_minutes(timeout)
|
219
|
+
if timeout_minutes >= module_conf.reconcile_timeout_minutes:
|
220
|
+
raise ValueError(
|
221
|
+
f"RDS instance {option} timeout value {timeout_minutes} must be lower than the module reconcile_timeout_minutes value {module_conf.reconcile_timeout_minutes}."
|
222
|
+
)
|
223
|
+
|
224
|
+
def validate(
|
225
|
+
self,
|
226
|
+
resource: ExternalResource,
|
227
|
+
module_conf: ExternalResourceModuleConfiguration,
|
228
|
+
) -> None:
|
229
|
+
self._validate_timeouts(resource, module_conf)
|
148
230
|
|
149
231
|
def find_linked_resources(
|
150
232
|
self, spec: ExternalResourceSpec
|
@@ -166,7 +248,11 @@ class AWSMskFactory(AWSDefaultResourceFactory):
|
|
166
248
|
"aws", provisioner, "msk", identifier
|
167
249
|
)
|
168
250
|
|
169
|
-
def resolve(
|
251
|
+
def resolve(
|
252
|
+
self,
|
253
|
+
spec: ExternalResourceSpec,
|
254
|
+
module_conf: ExternalResourceModuleConfiguration,
|
255
|
+
) -> dict[str, Any]:
|
170
256
|
rvr = ResourceValueResolver(spec=spec, identifier_as_value=True)
|
171
257
|
data = rvr.resolve()
|
172
258
|
data["output_prefix"] = spec.output_prefix
|
@@ -188,7 +274,11 @@ class AWSMskFactory(AWSDefaultResourceFactory):
|
|
188
274
|
del data["users"]
|
189
275
|
return data
|
190
276
|
|
191
|
-
def validate(
|
277
|
+
def validate(
|
278
|
+
self,
|
279
|
+
resource: ExternalResource,
|
280
|
+
module_conf: ExternalResourceModuleConfiguration,
|
281
|
+
) -> None:
|
192
282
|
data = resource.data
|
193
283
|
if (
|
194
284
|
data["number_of_broker_nodes"]
|
@@ -15,6 +15,7 @@ from reconcile.external_resources.meta import QONTRACT_INTEGRATION
|
|
15
15
|
from reconcile.external_resources.model import (
|
16
16
|
ExternalResource,
|
17
17
|
ExternalResourceKey,
|
18
|
+
ExternalResourceModuleConfiguration,
|
18
19
|
ExternalResourceProvision,
|
19
20
|
ExternalResourcesInventory,
|
20
21
|
ModuleInventory,
|
@@ -55,11 +56,19 @@ class ObjectFactory(Generic[T]):
|
|
55
56
|
|
56
57
|
class ExternalResourceFactory(ABC):
|
57
58
|
@abstractmethod
|
58
|
-
def create_external_resource(
|
59
|
+
def create_external_resource(
|
60
|
+
self,
|
61
|
+
spec: ExternalResourceSpec,
|
62
|
+
module_conf: ExternalResourceModuleConfiguration,
|
63
|
+
) -> ExternalResource:
|
59
64
|
pass
|
60
65
|
|
61
66
|
@abstractmethod
|
62
|
-
def validate_external_resource(
|
67
|
+
def validate_external_resource(
|
68
|
+
self,
|
69
|
+
resource: ExternalResource,
|
70
|
+
module_conf: ExternalResourceModuleConfiguration,
|
71
|
+
) -> None:
|
63
72
|
pass
|
64
73
|
|
65
74
|
def find_linked_resources(
|
@@ -121,9 +130,13 @@ class AWSExternalResourceFactory(ExternalResourceFactory):
|
|
121
130
|
self.er_inventory = er_inventory
|
122
131
|
self.secret_reader = secret_reader
|
123
132
|
|
124
|
-
def create_external_resource(
|
133
|
+
def create_external_resource(
|
134
|
+
self,
|
135
|
+
spec: ExternalResourceSpec,
|
136
|
+
module_conf: ExternalResourceModuleConfiguration,
|
137
|
+
) -> ExternalResource:
|
125
138
|
f = self.resource_factories.get_factory(spec.provider)
|
126
|
-
data = f.resolve(spec)
|
139
|
+
data = f.resolve(spec, module_conf)
|
127
140
|
data["tags"] = spec.tags(integration=QONTRACT_INTEGRATION)
|
128
141
|
data["default_tags"] = AWS_DEFAULT_TAGS
|
129
142
|
|
@@ -152,9 +165,13 @@ class AWSExternalResourceFactory(ExternalResourceFactory):
|
|
152
165
|
|
153
166
|
return ExternalResource(data=data, provision=provision)
|
154
167
|
|
155
|
-
def validate_external_resource(
|
168
|
+
def validate_external_resource(
|
169
|
+
self,
|
170
|
+
resource: ExternalResource,
|
171
|
+
module_conf: ExternalResourceModuleConfiguration,
|
172
|
+
) -> None:
|
156
173
|
f = self.resource_factories.get_factory(resource.provision.provider)
|
157
|
-
f.validate(resource)
|
174
|
+
f.validate(resource, module_conf)
|
158
175
|
|
159
176
|
def find_linked_resources(
|
160
177
|
self, spec: ExternalResourceSpec
|
@@ -197,8 +197,11 @@ class ExternalResourcesManager:
|
|
197
197
|
if spec.marked_to_delete:
|
198
198
|
continue
|
199
199
|
module = self.module_inventory.get_from_spec(spec)
|
200
|
+
module_conf = ExternalResourceModuleConfiguration.resolve_configuration(
|
201
|
+
module, spec, self.settings
|
202
|
+
)
|
200
203
|
try:
|
201
|
-
resource = self._build_external_resource(spec)
|
204
|
+
resource = self._build_external_resource(spec, module_conf)
|
202
205
|
except ExternalResourceValidationError as e:
|
203
206
|
self.errors[key] = e
|
204
207
|
continue
|
@@ -208,9 +211,7 @@ class ExternalResourcesManager:
|
|
208
211
|
resource_hash=resource.hash(),
|
209
212
|
input=resource.json(),
|
210
213
|
action=Action.APPLY,
|
211
|
-
module_configuration=
|
212
|
-
module, spec, self.settings
|
213
|
-
),
|
214
|
+
module_configuration=module_conf,
|
214
215
|
linked_resources=self._find_linked_resources(spec),
|
215
216
|
)
|
216
217
|
r.add(reconciliation)
|
@@ -362,10 +363,14 @@ class ExternalResourcesManager:
|
|
362
363
|
)
|
363
364
|
self.state_mgr.update_resource_status(key, ResourceStatus.CREATED)
|
364
365
|
|
365
|
-
def _build_external_resource(
|
366
|
+
def _build_external_resource(
|
367
|
+
self,
|
368
|
+
spec: ExternalResourceSpec,
|
369
|
+
module_conf: ExternalResourceModuleConfiguration,
|
370
|
+
) -> ExternalResource:
|
366
371
|
f = self.factories.get_factory(spec.provision_provider)
|
367
|
-
resource = f.create_external_resource(spec)
|
368
|
-
f.validate_external_resource(resource)
|
372
|
+
resource = f.create_external_resource(spec, module_conf)
|
373
|
+
f.validate_external_resource(resource, module_conf)
|
369
374
|
return resource
|
370
375
|
|
371
376
|
def _find_linked_resources(
|
@@ -18,7 +18,6 @@ from reconcile.gql_definitions.external_resources.external_resources_modules imp
|
|
18
18
|
ExternalResourcesModuleV1,
|
19
19
|
)
|
20
20
|
from reconcile.gql_definitions.external_resources.external_resources_namespaces import (
|
21
|
-
ExternalResourcesModuleOverridesV1,
|
22
21
|
NamespaceTerraformProviderResourceAWSV1,
|
23
22
|
NamespaceTerraformResourceElastiCacheV1,
|
24
23
|
NamespaceTerraformResourceKMSV1,
|
@@ -29,6 +28,10 @@ from reconcile.gql_definitions.external_resources.external_resources_namespaces
|
|
29
28
|
from reconcile.gql_definitions.external_resources.external_resources_settings import (
|
30
29
|
ExternalResourcesSettingsV1,
|
31
30
|
)
|
31
|
+
from reconcile.gql_definitions.external_resources.fragments.external_resources_module_overrides import (
|
32
|
+
ExternalResourcesModuleOverrides,
|
33
|
+
)
|
34
|
+
from reconcile.gql_definitions.fragments.deplopy_resources import DeployResourcesFields
|
32
35
|
from reconcile.utils.exceptions import FetchResourceError
|
33
36
|
from reconcile.utils.external_resource_spec import (
|
34
37
|
ExternalResourceSpec,
|
@@ -220,6 +223,38 @@ def load_module_inventory(
|
|
220
223
|
})
|
221
224
|
|
222
225
|
|
226
|
+
class ResourcesSpec(BaseModel, frozen=True):
|
227
|
+
cpu: str | None = None
|
228
|
+
memory: str | None = None
|
229
|
+
|
230
|
+
|
231
|
+
class Resources(BaseModel, frozen=True):
|
232
|
+
"""Hashable class to store module resources in reconciliations.
|
233
|
+
Default values are used as a fallback for existent objects that were
|
234
|
+
created without container resources, hence they don't have mem/cpu resources
|
235
|
+
in the ERv2 State. Eventually, all resources will have resources assignments
|
236
|
+
from the module spec, module_overrides, or app-interface settings.
|
237
|
+
"""
|
238
|
+
|
239
|
+
requests: ResourcesSpec = ResourcesSpec()
|
240
|
+
limits: ResourcesSpec = ResourcesSpec()
|
241
|
+
|
242
|
+
@staticmethod
|
243
|
+
def from_deploy_resources_fields(fields: DeployResourcesFields) -> "Resources":
|
244
|
+
"""Create Resource obect from GQL DeployResourcesFields.
|
245
|
+
|
246
|
+
DeployResourceFields can not be used directly as it not hashable."""
|
247
|
+
return Resources(
|
248
|
+
requests=ResourcesSpec(
|
249
|
+
cpu=fields.requests.cpu, memory=fields.requests.memory
|
250
|
+
),
|
251
|
+
limits=ResourcesSpec(
|
252
|
+
cpu=fields.limits.cpu,
|
253
|
+
memory=fields.limits.memory,
|
254
|
+
),
|
255
|
+
)
|
256
|
+
|
257
|
+
|
223
258
|
class ExternalResourceModuleConfiguration(BaseModel, frozen=True):
|
224
259
|
image: str = ""
|
225
260
|
version: str = ""
|
@@ -227,6 +262,7 @@ class ExternalResourceModuleConfiguration(BaseModel, frozen=True):
|
|
227
262
|
reconcile_timeout_minutes: int = -1000
|
228
263
|
outputs_secret_image: str = ""
|
229
264
|
outputs_secret_version: str = ""
|
265
|
+
resources: Resources = Resources()
|
230
266
|
|
231
267
|
@property
|
232
268
|
def image_version(self) -> str:
|
@@ -244,13 +280,14 @@ class ExternalResourceModuleConfiguration(BaseModel, frozen=True):
|
|
244
280
|
) -> "ExternalResourceModuleConfiguration":
|
245
281
|
module_overrides = spec.metadata.get(
|
246
282
|
"module_overrides"
|
247
|
-
) or
|
283
|
+
) or ExternalResourcesModuleOverrides(
|
248
284
|
module_type=None,
|
249
285
|
image=None,
|
250
286
|
version=None,
|
251
287
|
reconcile_timeout_minutes=None,
|
252
288
|
outputs_secret_image=None,
|
253
289
|
outputs_secret_version=None,
|
290
|
+
resources=None,
|
254
291
|
)
|
255
292
|
|
256
293
|
return ExternalResourceModuleConfiguration(
|
@@ -265,6 +302,11 @@ class ExternalResourceModuleConfiguration(BaseModel, frozen=True):
|
|
265
302
|
outputs_secret_version=module_overrides.outputs_secret_version
|
266
303
|
or module.outputs_secret_version
|
267
304
|
or settings.outputs_secret_version,
|
305
|
+
resources=Resources.from_deploy_resources_fields(
|
306
|
+
module_overrides.resources
|
307
|
+
or module.resources
|
308
|
+
or settings.module_default_resources
|
309
|
+
),
|
268
310
|
)
|
269
311
|
|
270
312
|
|
@@ -14,6 +14,7 @@ from kubernetes.client import (
|
|
14
14
|
V1ObjectMeta,
|
15
15
|
V1PodSpec,
|
16
16
|
V1PodTemplateSpec,
|
17
|
+
V1ResourceRequirements,
|
17
18
|
V1SecretVolumeSource,
|
18
19
|
V1Volume,
|
19
20
|
V1VolumeMount,
|
@@ -89,10 +90,19 @@ class ReconciliationK8sJob(K8sJob, BaseModel, frozen=True):
|
|
89
90
|
}
|
90
91
|
|
91
92
|
def job_spec(self) -> V1JobSpec:
|
93
|
+
assert self.reconciliation.module_configuration.resources is not None
|
92
94
|
job_container = V1Container(
|
93
95
|
name="job",
|
94
96
|
image=self.reconciliation.module_configuration.image_version,
|
95
97
|
image_pull_policy="Always",
|
98
|
+
resources=V1ResourceRequirements(
|
99
|
+
requests=self.reconciliation.module_configuration.resources.requests.dict(
|
100
|
+
exclude_none=True
|
101
|
+
),
|
102
|
+
limits=self.reconciliation.module_configuration.resources.limits.dict(
|
103
|
+
exclude_none=True
|
104
|
+
),
|
105
|
+
),
|
96
106
|
env=[
|
97
107
|
V1EnvVar(
|
98
108
|
name="DRY_RUN",
|
@@ -11,6 +11,8 @@ from reconcile.external_resources.model import (
|
|
11
11
|
ExternalResourceModuleConfiguration,
|
12
12
|
Reconciliation,
|
13
13
|
ReconciliationStatus,
|
14
|
+
Resources,
|
15
|
+
ResourcesSpec,
|
14
16
|
ResourceStatus,
|
15
17
|
)
|
16
18
|
from reconcile.utils.aws_api_typed.api import AWSApi
|
@@ -73,10 +75,48 @@ class DynamoDBStateAdapter:
|
|
73
75
|
MODCONF_VERSION = "version"
|
74
76
|
MODCONF_DRIFT_MINS = "drift_detection_minutes"
|
75
77
|
MODCONF_TIMEOUT_MINS = "timeout_minutes"
|
78
|
+
MODCONF_RESOURCES = "resources"
|
79
|
+
MODCONF_RESOURCES_REQUESTS = "requests"
|
80
|
+
MODCONF_RESOURCES_REQUESTS_CPU = "cpu"
|
81
|
+
MODCONF_RESOURCES_REQUESTS_MEMORY = "memory"
|
82
|
+
MODCONF_RESOURCES_LIMITS = "limits"
|
83
|
+
MODCONF_RESOURCES_LIMITS_CPU = "cpu"
|
84
|
+
MODCONF_RESOURCES_LIMITS_MEMORY = "memory"
|
76
85
|
|
77
86
|
def _get_value(self, item: Mapping[str, Any], key: str, type: str = "S") -> Any:
|
87
|
+
if item[key][type] == "None":
|
88
|
+
return None
|
78
89
|
return item[key][type]
|
79
90
|
|
91
|
+
def _build_resources(self, modconf: Mapping[str, Any]) -> Resources | None:
|
92
|
+
if self.MODCONF_RESOURCES not in modconf:
|
93
|
+
return Resources()
|
94
|
+
mc_resources = self._get_value(modconf, self.MODCONF_RESOURCES, type="M")
|
95
|
+
mc_resources_requests = self._get_value(
|
96
|
+
mc_resources, self.MODCONF_RESOURCES_REQUESTS, type="M"
|
97
|
+
)
|
98
|
+
mc_resources_limits = self._get_value(
|
99
|
+
mc_resources, self.MODCONF_RESOURCES_LIMITS, type="M"
|
100
|
+
)
|
101
|
+
return Resources(
|
102
|
+
requests=ResourcesSpec(
|
103
|
+
cpu=self._get_value(
|
104
|
+
mc_resources_requests, self.MODCONF_RESOURCES_REQUESTS_CPU
|
105
|
+
),
|
106
|
+
memory=self._get_value(
|
107
|
+
mc_resources_requests, self.MODCONF_RESOURCES_REQUESTS_MEMORY
|
108
|
+
),
|
109
|
+
),
|
110
|
+
limits=ResourcesSpec(
|
111
|
+
cpu=self._get_value(
|
112
|
+
mc_resources_limits, self.MODCONF_RESOURCES_LIMITS_CPU
|
113
|
+
),
|
114
|
+
memory=self._get_value(
|
115
|
+
mc_resources_limits, self.MODCONF_RESOURCES_LIMITS_MEMORY
|
116
|
+
),
|
117
|
+
),
|
118
|
+
)
|
119
|
+
|
80
120
|
def deserialize(
|
81
121
|
self,
|
82
122
|
item: Mapping[str, Any],
|
@@ -116,6 +156,7 @@ class DynamoDBStateAdapter:
|
|
116
156
|
reconcile_timeout_minutes=self._get_value(
|
117
157
|
modconf, self.MODCONF_TIMEOUT_MINS, type="N"
|
118
158
|
),
|
159
|
+
resources=self._build_resources(modconf),
|
119
160
|
),
|
120
161
|
)
|
121
162
|
|
@@ -164,7 +205,39 @@ class DynamoDBStateAdapter:
|
|
164
205
|
state.reconciliation.module_configuration.reconcile_timeout_minutes
|
165
206
|
)
|
166
207
|
},
|
167
|
-
|
208
|
+
self.MODCONF_RESOURCES: {
|
209
|
+
"M": {
|
210
|
+
self.MODCONF_RESOURCES_REQUESTS: {
|
211
|
+
"M": {
|
212
|
+
self.MODCONF_RESOURCES_REQUESTS_CPU: {
|
213
|
+
"S": str(
|
214
|
+
state.reconciliation.module_configuration.resources.requests.cpu
|
215
|
+
)
|
216
|
+
},
|
217
|
+
self.MODCONF_RESOURCES_REQUESTS_MEMORY: {
|
218
|
+
"S": str(
|
219
|
+
state.reconciliation.module_configuration.resources.requests.memory
|
220
|
+
)
|
221
|
+
},
|
222
|
+
}
|
223
|
+
},
|
224
|
+
self.MODCONF_RESOURCES_LIMITS: {
|
225
|
+
"M": {
|
226
|
+
self.MODCONF_RESOURCES_LIMITS_CPU: {
|
227
|
+
"S": str(
|
228
|
+
state.reconciliation.module_configuration.resources.limits.cpu
|
229
|
+
)
|
230
|
+
},
|
231
|
+
self.MODCONF_RESOURCES_LIMITS_MEMORY: {
|
232
|
+
"S": str(
|
233
|
+
state.reconciliation.module_configuration.resources.limits.memory
|
234
|
+
)
|
235
|
+
},
|
236
|
+
}
|
237
|
+
},
|
238
|
+
}
|
239
|
+
},
|
240
|
+
},
|
168
241
|
},
|
169
242
|
}
|
170
243
|
},
|
@@ -17,8 +17,21 @@ from pydantic import ( # noqa: F401 # pylint: disable=W0611
|
|
17
17
|
Json,
|
18
18
|
)
|
19
19
|
|
20
|
+
from reconcile.gql_definitions.fragments.deplopy_resources import DeployResourcesFields
|
21
|
+
|
20
22
|
|
21
23
|
DEFINITION = """
|
24
|
+
fragment DeployResourcesFields on DeployResources_v1 {
|
25
|
+
requests {
|
26
|
+
cpu
|
27
|
+
memory
|
28
|
+
}
|
29
|
+
limits {
|
30
|
+
cpu
|
31
|
+
memory
|
32
|
+
}
|
33
|
+
}
|
34
|
+
|
22
35
|
query ExternalResourcesModules {
|
23
36
|
modules: external_resources_modules_v1 {
|
24
37
|
provision_provider
|
@@ -31,6 +44,9 @@ query ExternalResourcesModules {
|
|
31
44
|
outputs_secret_sync
|
32
45
|
outputs_secret_image
|
33
46
|
outputs_secret_version
|
47
|
+
resources {
|
48
|
+
... DeployResourcesFields
|
49
|
+
}
|
34
50
|
}
|
35
51
|
}
|
36
52
|
"""
|
@@ -53,6 +69,7 @@ class ExternalResourcesModuleV1(ConfiguredBaseModel):
|
|
53
69
|
outputs_secret_sync: bool = Field(..., alias="outputs_secret_sync")
|
54
70
|
outputs_secret_image: Optional[str] = Field(..., alias="outputs_secret_image")
|
55
71
|
outputs_secret_version: Optional[str] = Field(..., alias="outputs_secret_version")
|
72
|
+
resources: Optional[DeployResourcesFields] = Field(..., alias="resources")
|
56
73
|
|
57
74
|
|
58
75
|
class ExternalResourcesModulesQueryData(ConfiguredBaseModel):
|
@@ -19,6 +19,7 @@ from pydantic import ( # noqa: F401 # pylint: disable=W0611
|
|
19
19
|
|
20
20
|
from reconcile.gql_definitions.fragments.aws_vpc import AWSVPC
|
21
21
|
from reconcile.gql_definitions.fragments.jumphost_common_fields import CommonJumphostFields
|
22
|
+
from reconcile.gql_definitions.external_resources.fragments.external_resources_module_overrides import ExternalResourcesModuleOverrides
|
22
23
|
from reconcile.gql_definitions.fragments.vault_secret import VaultSecret
|
23
24
|
|
24
25
|
|
@@ -53,6 +54,29 @@ fragment CommonJumphostFields on ClusterJumpHost_v1 {
|
|
53
54
|
}
|
54
55
|
}
|
55
56
|
|
57
|
+
fragment DeployResourcesFields on DeployResources_v1 {
|
58
|
+
requests {
|
59
|
+
cpu
|
60
|
+
memory
|
61
|
+
}
|
62
|
+
limits {
|
63
|
+
cpu
|
64
|
+
memory
|
65
|
+
}
|
66
|
+
}
|
67
|
+
|
68
|
+
fragment ExternalResourcesModuleOverrides on ExternalResourcesModuleOverrides_v1 {
|
69
|
+
module_type
|
70
|
+
image
|
71
|
+
version
|
72
|
+
reconcile_timeout_minutes
|
73
|
+
outputs_secret_image
|
74
|
+
outputs_secret_version
|
75
|
+
resources {
|
76
|
+
... DeployResourcesFields
|
77
|
+
}
|
78
|
+
}
|
79
|
+
|
56
80
|
fragment VaultSecret on VaultSecret_v1 {
|
57
81
|
path
|
58
82
|
field
|
@@ -111,12 +135,7 @@ query ExternalResourcesNamespaces {
|
|
111
135
|
managed_by_erv2
|
112
136
|
delete
|
113
137
|
module_overrides {
|
114
|
-
|
115
|
-
image
|
116
|
-
version
|
117
|
-
reconcile_timeout_minutes
|
118
|
-
outputs_secret_image
|
119
|
-
outputs_secret_version
|
138
|
+
... ExternalResourcesModuleOverrides
|
120
139
|
}
|
121
140
|
}
|
122
141
|
... on NamespaceTerraformResourceS3_v1 {
|
@@ -149,12 +168,7 @@ query ExternalResourcesNamespaces {
|
|
149
168
|
managed_by_erv2
|
150
169
|
delete
|
151
170
|
module_overrides {
|
152
|
-
|
153
|
-
image
|
154
|
-
version
|
155
|
-
reconcile_timeout_minutes
|
156
|
-
outputs_secret_image
|
157
|
-
outputs_secret_version
|
171
|
+
... ExternalResourcesModuleOverrides
|
158
172
|
}
|
159
173
|
}
|
160
174
|
... on NamespaceTerraformResourceServiceAccount_v1 {
|
@@ -275,12 +289,7 @@ query ExternalResourcesNamespaces {
|
|
275
289
|
managed_by_erv2
|
276
290
|
delete
|
277
291
|
module_overrides {
|
278
|
-
|
279
|
-
image
|
280
|
-
version
|
281
|
-
reconcile_timeout_minutes
|
282
|
-
outputs_secret_image
|
283
|
-
outputs_secret_version
|
292
|
+
... ExternalResourcesModuleOverrides
|
284
293
|
}
|
285
294
|
}
|
286
295
|
... on NamespaceTerraformResourceElasticSearch_v1 {
|
@@ -492,12 +501,7 @@ query ExternalResourcesNamespaces {
|
|
492
501
|
managed_by_erv2
|
493
502
|
delete
|
494
503
|
module_overrides {
|
495
|
-
|
496
|
-
image
|
497
|
-
version
|
498
|
-
reconcile_timeout_minutes
|
499
|
-
outputs_secret_image
|
500
|
-
outputs_secret_version
|
504
|
+
... ExternalResourcesModuleOverrides
|
501
505
|
}
|
502
506
|
}
|
503
507
|
}
|
@@ -576,15 +580,6 @@ class AWSRDSDataClassificationV1(ConfiguredBaseModel):
|
|
576
580
|
loss_impact: Optional[str] = Field(..., alias="loss_impact")
|
577
581
|
|
578
582
|
|
579
|
-
class ExternalResourcesModuleOverridesV1(ConfiguredBaseModel):
|
580
|
-
module_type: Optional[str] = Field(..., alias="module_type")
|
581
|
-
image: Optional[str] = Field(..., alias="image")
|
582
|
-
version: Optional[str] = Field(..., alias="version")
|
583
|
-
reconcile_timeout_minutes: Optional[int] = Field(..., alias="reconcile_timeout_minutes")
|
584
|
-
outputs_secret_image: Optional[str] = Field(..., alias="outputs_secret_image")
|
585
|
-
outputs_secret_version: Optional[str] = Field(..., alias="outputs_secret_version")
|
586
|
-
|
587
|
-
|
588
583
|
class NamespaceTerraformResourceRDSV1(NamespaceTerraformResourceAWSV1):
|
589
584
|
region: Optional[str] = Field(..., alias="region")
|
590
585
|
identifier: str = Field(..., alias="identifier")
|
@@ -604,7 +599,7 @@ class NamespaceTerraformResourceRDSV1(NamespaceTerraformResourceAWSV1):
|
|
604
599
|
data_classification: Optional[AWSRDSDataClassificationV1] = Field(..., alias="data_classification")
|
605
600
|
managed_by_erv2: Optional[bool] = Field(..., alias="managed_by_erv2")
|
606
601
|
delete: Optional[bool] = Field(..., alias="delete")
|
607
|
-
module_overrides: Optional[
|
602
|
+
module_overrides: Optional[ExternalResourcesModuleOverrides] = Field(..., alias="module_overrides")
|
608
603
|
|
609
604
|
|
610
605
|
class AWSS3EventNotificationV1(ConfiguredBaseModel):
|
@@ -629,15 +624,6 @@ class NamespaceTerraformResourceS3V1(NamespaceTerraformResourceAWSV1):
|
|
629
624
|
annotations: Optional[str] = Field(..., alias="annotations")
|
630
625
|
|
631
626
|
|
632
|
-
class NamespaceTerraformResourceElastiCacheV1_ExternalResourcesModuleOverridesV1(ConfiguredBaseModel):
|
633
|
-
module_type: Optional[str] = Field(..., alias="module_type")
|
634
|
-
image: Optional[str] = Field(..., alias="image")
|
635
|
-
version: Optional[str] = Field(..., alias="version")
|
636
|
-
reconcile_timeout_minutes: Optional[int] = Field(..., alias="reconcile_timeout_minutes")
|
637
|
-
outputs_secret_image: Optional[str] = Field(..., alias="outputs_secret_image")
|
638
|
-
outputs_secret_version: Optional[str] = Field(..., alias="outputs_secret_version")
|
639
|
-
|
640
|
-
|
641
627
|
class NamespaceTerraformResourceElastiCacheV1(NamespaceTerraformResourceAWSV1):
|
642
628
|
identifier: str = Field(..., alias="identifier")
|
643
629
|
defaults: str = Field(..., alias="defaults")
|
@@ -648,7 +634,7 @@ class NamespaceTerraformResourceElastiCacheV1(NamespaceTerraformResourceAWSV1):
|
|
648
634
|
annotations: Optional[str] = Field(..., alias="annotations")
|
649
635
|
managed_by_erv2: Optional[bool] = Field(..., alias="managed_by_erv2")
|
650
636
|
delete: Optional[bool] = Field(..., alias="delete")
|
651
|
-
module_overrides: Optional[
|
637
|
+
module_overrides: Optional[ExternalResourcesModuleOverrides] = Field(..., alias="module_overrides")
|
652
638
|
|
653
639
|
|
654
640
|
class ClusterV1(ConfiguredBaseModel):
|
@@ -784,15 +770,6 @@ class NamespaceTerraformResourceCloudWatchV1(NamespaceTerraformResourceAWSV1):
|
|
784
770
|
annotations: Optional[str] = Field(..., alias="annotations")
|
785
771
|
|
786
772
|
|
787
|
-
class NamespaceTerraformResourceKMSV1_ExternalResourcesModuleOverridesV1(ConfiguredBaseModel):
|
788
|
-
module_type: Optional[str] = Field(..., alias="module_type")
|
789
|
-
image: Optional[str] = Field(..., alias="image")
|
790
|
-
version: Optional[str] = Field(..., alias="version")
|
791
|
-
reconcile_timeout_minutes: Optional[int] = Field(..., alias="reconcile_timeout_minutes")
|
792
|
-
outputs_secret_image: Optional[str] = Field(..., alias="outputs_secret_image")
|
793
|
-
outputs_secret_version: Optional[str] = Field(..., alias="outputs_secret_version")
|
794
|
-
|
795
|
-
|
796
773
|
class NamespaceTerraformResourceKMSV1(NamespaceTerraformResourceAWSV1):
|
797
774
|
region: Optional[str] = Field(..., alias="region")
|
798
775
|
identifier: str = Field(..., alias="identifier")
|
@@ -802,7 +779,7 @@ class NamespaceTerraformResourceKMSV1(NamespaceTerraformResourceAWSV1):
|
|
802
779
|
annotations: Optional[str] = Field(..., alias="annotations")
|
803
780
|
managed_by_erv2: Optional[bool] = Field(..., alias="managed_by_erv2")
|
804
781
|
delete: Optional[bool] = Field(..., alias="delete")
|
805
|
-
module_overrides: Optional[
|
782
|
+
module_overrides: Optional[ExternalResourcesModuleOverrides] = Field(..., alias="module_overrides")
|
806
783
|
|
807
784
|
|
808
785
|
class NamespaceTerraformResourceElasticSearchV1(NamespaceTerraformResourceAWSV1):
|
@@ -1044,15 +1021,6 @@ class MskSecretParametersV1(ConfiguredBaseModel):
|
|
1044
1021
|
secret: VaultSecret = Field(..., alias="secret")
|
1045
1022
|
|
1046
1023
|
|
1047
|
-
class NamespaceTerraformResourceMskV1_ExternalResourcesModuleOverridesV1(ConfiguredBaseModel):
|
1048
|
-
module_type: Optional[str] = Field(..., alias="module_type")
|
1049
|
-
image: Optional[str] = Field(..., alias="image")
|
1050
|
-
version: Optional[str] = Field(..., alias="version")
|
1051
|
-
reconcile_timeout_minutes: Optional[int] = Field(..., alias="reconcile_timeout_minutes")
|
1052
|
-
outputs_secret_image: Optional[str] = Field(..., alias="outputs_secret_image")
|
1053
|
-
outputs_secret_version: Optional[str] = Field(..., alias="outputs_secret_version")
|
1054
|
-
|
1055
|
-
|
1056
1024
|
class NamespaceTerraformResourceMskV1(NamespaceTerraformResourceAWSV1):
|
1057
1025
|
region: Optional[str] = Field(..., alias="region")
|
1058
1026
|
identifier: str = Field(..., alias="identifier")
|
@@ -1062,7 +1030,7 @@ class NamespaceTerraformResourceMskV1(NamespaceTerraformResourceAWSV1):
|
|
1062
1030
|
users: Optional[list[MskSecretParametersV1]] = Field(..., alias="users")
|
1063
1031
|
managed_by_erv2: Optional[bool] = Field(..., alias="managed_by_erv2")
|
1064
1032
|
delete: Optional[bool] = Field(..., alias="delete")
|
1065
|
-
module_overrides: Optional[
|
1033
|
+
module_overrides: Optional[ExternalResourcesModuleOverrides] = Field(..., alias="module_overrides")
|
1066
1034
|
|
1067
1035
|
|
1068
1036
|
class NamespaceTerraformProviderResourceAWSV1(NamespaceExternalResourceV1):
|
@@ -17,8 +17,21 @@ from pydantic import ( # noqa: F401 # pylint: disable=W0611
|
|
17
17
|
Json,
|
18
18
|
)
|
19
19
|
|
20
|
+
from reconcile.gql_definitions.fragments.deplopy_resources import DeployResourcesFields
|
21
|
+
|
20
22
|
|
21
23
|
DEFINITION = """
|
24
|
+
fragment DeployResourcesFields on DeployResources_v1 {
|
25
|
+
requests {
|
26
|
+
cpu
|
27
|
+
memory
|
28
|
+
}
|
29
|
+
limits {
|
30
|
+
cpu
|
31
|
+
memory
|
32
|
+
}
|
33
|
+
}
|
34
|
+
|
22
35
|
query ExternalResourcesSettings {
|
23
36
|
settings: external_resources_settings_v1 {
|
24
37
|
state_dynamodb_account {
|
@@ -38,6 +51,9 @@ query ExternalResourcesSettings {
|
|
38
51
|
vault_secrets_path
|
39
52
|
outputs_secret_image
|
40
53
|
outputs_secret_version
|
54
|
+
module_default_resources {
|
55
|
+
... DeployResourcesFields
|
56
|
+
}
|
41
57
|
}
|
42
58
|
}
|
43
59
|
"""
|
@@ -73,6 +89,7 @@ class ExternalResourcesSettingsV1(ConfiguredBaseModel):
|
|
73
89
|
vault_secrets_path: str = Field(..., alias="vault_secrets_path")
|
74
90
|
outputs_secret_image: str = Field(..., alias="outputs_secret_image")
|
75
91
|
outputs_secret_version: str = Field(..., alias="outputs_secret_version")
|
92
|
+
module_default_resources: DeployResourcesFields = Field(..., alias="module_default_resources")
|
76
93
|
|
77
94
|
|
78
95
|
class ExternalResourcesSettingsQueryData(ConfiguredBaseModel):
|
File without changes
|
@@ -0,0 +1,36 @@
|
|
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.deplopy_resources import DeployResourcesFields
|
21
|
+
|
22
|
+
|
23
|
+
class ConfiguredBaseModel(BaseModel):
|
24
|
+
class Config:
|
25
|
+
smart_union=True
|
26
|
+
extra=Extra.forbid
|
27
|
+
|
28
|
+
|
29
|
+
class ExternalResourcesModuleOverrides(ConfiguredBaseModel):
|
30
|
+
module_type: Optional[str] = Field(..., alias="module_type")
|
31
|
+
image: Optional[str] = Field(..., alias="image")
|
32
|
+
version: Optional[str] = Field(..., alias="version")
|
33
|
+
reconcile_timeout_minutes: Optional[int] = Field(..., alias="reconcile_timeout_minutes")
|
34
|
+
outputs_secret_image: Optional[str] = Field(..., alias="outputs_secret_image")
|
35
|
+
outputs_secret_version: Optional[str] = Field(..., alias="outputs_secret_version")
|
36
|
+
resources: Optional[DeployResourcesFields] = Field(..., alias="resources")
|
@@ -33879,6 +33879,22 @@
|
|
33879
33879
|
},
|
33880
33880
|
"isDeprecated": false,
|
33881
33881
|
"deprecationReason": null
|
33882
|
+
},
|
33883
|
+
{
|
33884
|
+
"name": "module_default_resources",
|
33885
|
+
"description": null,
|
33886
|
+
"args": [],
|
33887
|
+
"type": {
|
33888
|
+
"kind": "NON_NULL",
|
33889
|
+
"name": null,
|
33890
|
+
"ofType": {
|
33891
|
+
"kind": "OBJECT",
|
33892
|
+
"name": "DeployResources_v1",
|
33893
|
+
"ofType": null
|
33894
|
+
}
|
33895
|
+
},
|
33896
|
+
"isDeprecated": false,
|
33897
|
+
"deprecationReason": null
|
33882
33898
|
}
|
33883
33899
|
],
|
33884
33900
|
"inputFields": null,
|
@@ -34080,6 +34096,18 @@
|
|
34080
34096
|
},
|
34081
34097
|
"isDeprecated": false,
|
34082
34098
|
"deprecationReason": null
|
34099
|
+
},
|
34100
|
+
{
|
34101
|
+
"name": "resources",
|
34102
|
+
"description": null,
|
34103
|
+
"args": [],
|
34104
|
+
"type": {
|
34105
|
+
"kind": "OBJECT",
|
34106
|
+
"name": "DeployResources_v1",
|
34107
|
+
"ofType": null
|
34108
|
+
},
|
34109
|
+
"isDeprecated": false,
|
34110
|
+
"deprecationReason": null
|
34083
34111
|
}
|
34084
34112
|
],
|
34085
34113
|
"inputFields": null,
|
@@ -43321,6 +43349,18 @@
|
|
43321
43349
|
},
|
43322
43350
|
"isDeprecated": false,
|
43323
43351
|
"deprecationReason": null
|
43352
|
+
},
|
43353
|
+
{
|
43354
|
+
"name": "resources",
|
43355
|
+
"description": null,
|
43356
|
+
"args": [],
|
43357
|
+
"type": {
|
43358
|
+
"kind": "OBJECT",
|
43359
|
+
"name": "DeployResources_v1",
|
43360
|
+
"ofType": null
|
43361
|
+
},
|
43362
|
+
"isDeprecated": false,
|
43363
|
+
"deprecationReason": null
|
43324
43364
|
}
|
43325
43365
|
],
|
43326
43366
|
"inputFields": null,
|
tools/cli_commands/erv2.py
CHANGED
@@ -118,13 +118,13 @@ class Erv2Cli:
|
|
118
118
|
self._er_settings, m_inventory, er_inventory, self._secret_reader
|
119
119
|
)
|
120
120
|
f = factories.get_factory(spec.provision_provider)
|
121
|
-
self._resource = f.create_external_resource(spec)
|
122
|
-
f.validate_external_resource(self._resource)
|
123
121
|
self._module_configuration = (
|
124
122
|
ExternalResourceModuleConfiguration.resolve_configuration(
|
125
123
|
m_inventory.get_from_spec(spec), spec, self._er_settings
|
126
124
|
)
|
127
125
|
)
|
126
|
+
self._resource = f.create_external_resource(spec, self._module_configuration)
|
127
|
+
f.validate_external_resource(self._resource, self._module_configuration)
|
128
128
|
|
129
129
|
@property
|
130
130
|
def input_data(self) -> str:
|
{qontract_reconcile-0.10.2.dev44.dist-info → qontract_reconcile-0.10.2.dev46.dist-info}/WHEEL
RENAMED
File without changes
|
File without changes
|