dbt-platform-helper 13.1.0__py3-none-any.whl → 15.16.0__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.
- dbt_platform_helper/COMMANDS.md +107 -27
- dbt_platform_helper/commands/application.py +5 -6
- dbt_platform_helper/commands/codebase.py +31 -10
- dbt_platform_helper/commands/conduit.py +3 -5
- dbt_platform_helper/commands/config.py +20 -311
- dbt_platform_helper/commands/copilot.py +18 -391
- dbt_platform_helper/commands/database.py +17 -9
- dbt_platform_helper/commands/environment.py +20 -14
- dbt_platform_helper/commands/generate.py +0 -3
- dbt_platform_helper/commands/internal.py +140 -0
- dbt_platform_helper/commands/notify.py +58 -78
- dbt_platform_helper/commands/pipeline.py +23 -19
- dbt_platform_helper/commands/secrets.py +39 -93
- dbt_platform_helper/commands/version.py +7 -12
- dbt_platform_helper/constants.py +52 -7
- dbt_platform_helper/domain/codebase.py +89 -39
- dbt_platform_helper/domain/conduit.py +335 -76
- dbt_platform_helper/domain/config.py +381 -0
- dbt_platform_helper/domain/copilot.py +398 -0
- dbt_platform_helper/domain/copilot_environment.py +8 -8
- dbt_platform_helper/domain/database_copy.py +2 -2
- dbt_platform_helper/domain/maintenance_page.py +254 -430
- dbt_platform_helper/domain/notify.py +64 -0
- dbt_platform_helper/domain/pipelines.py +43 -35
- dbt_platform_helper/domain/plans.py +41 -0
- dbt_platform_helper/domain/secrets.py +279 -0
- dbt_platform_helper/domain/service.py +570 -0
- dbt_platform_helper/domain/terraform_environment.py +14 -13
- dbt_platform_helper/domain/update_alb_rules.py +412 -0
- dbt_platform_helper/domain/versioning.py +249 -0
- dbt_platform_helper/{providers → entities}/platform_config_schema.py +75 -82
- dbt_platform_helper/entities/semantic_version.py +83 -0
- dbt_platform_helper/entities/service.py +339 -0
- dbt_platform_helper/platform_exception.py +4 -0
- dbt_platform_helper/providers/autoscaling.py +24 -0
- dbt_platform_helper/providers/aws/__init__.py +0 -0
- dbt_platform_helper/providers/aws/exceptions.py +70 -0
- dbt_platform_helper/providers/aws/interfaces.py +13 -0
- dbt_platform_helper/providers/aws/opensearch.py +23 -0
- dbt_platform_helper/providers/aws/redis.py +21 -0
- dbt_platform_helper/providers/aws/sso_auth.py +75 -0
- dbt_platform_helper/providers/cache.py +40 -4
- dbt_platform_helper/providers/cloudformation.py +1 -1
- dbt_platform_helper/providers/config.py +137 -19
- dbt_platform_helper/providers/config_validator.py +112 -51
- dbt_platform_helper/providers/copilot.py +24 -16
- dbt_platform_helper/providers/ecr.py +89 -7
- dbt_platform_helper/providers/ecs.py +228 -36
- dbt_platform_helper/providers/environment_variable.py +24 -0
- dbt_platform_helper/providers/files.py +1 -1
- dbt_platform_helper/providers/io.py +36 -4
- dbt_platform_helper/providers/kms.py +22 -0
- dbt_platform_helper/providers/load_balancers.py +402 -42
- dbt_platform_helper/providers/logs.py +72 -0
- dbt_platform_helper/providers/parameter_store.py +134 -0
- dbt_platform_helper/providers/s3.py +21 -0
- dbt_platform_helper/providers/schema_migrations/__init__.py +0 -0
- dbt_platform_helper/providers/schema_migrations/schema_v0_to_v1_migration.py +43 -0
- dbt_platform_helper/providers/schema_migrator.py +77 -0
- dbt_platform_helper/providers/secrets.py +5 -5
- dbt_platform_helper/providers/slack_channel_notifier.py +62 -0
- dbt_platform_helper/providers/terraform_manifest.py +121 -19
- dbt_platform_helper/providers/version.py +106 -23
- dbt_platform_helper/providers/version_status.py +27 -0
- dbt_platform_helper/providers/vpc.py +36 -5
- dbt_platform_helper/providers/yaml_file.py +58 -2
- dbt_platform_helper/templates/environment-pipelines/main.tf +4 -3
- dbt_platform_helper/templates/svc/overrides/cfn.patches.yml +5 -0
- dbt_platform_helper/utilities/decorators.py +103 -0
- dbt_platform_helper/utils/application.py +119 -22
- dbt_platform_helper/utils/aws.py +39 -150
- dbt_platform_helper/utils/deep_merge.py +10 -0
- dbt_platform_helper/utils/git.py +1 -14
- dbt_platform_helper/utils/validation.py +1 -1
- {dbt_platform_helper-13.1.0.dist-info → dbt_platform_helper-15.16.0.dist-info}/METADATA +11 -20
- dbt_platform_helper-15.16.0.dist-info/RECORD +118 -0
- {dbt_platform_helper-13.1.0.dist-info → dbt_platform_helper-15.16.0.dist-info}/WHEEL +1 -1
- platform_helper.py +3 -1
- terraform/elasticache-redis/plans.yml +85 -0
- terraform/opensearch/plans.yml +71 -0
- terraform/postgres/plans.yml +128 -0
- dbt_platform_helper/addon-plans.yml +0 -224
- dbt_platform_helper/providers/aws.py +0 -37
- dbt_platform_helper/providers/opensearch.py +0 -36
- dbt_platform_helper/providers/redis.py +0 -34
- dbt_platform_helper/providers/semantic_version.py +0 -126
- dbt_platform_helper/templates/svc/manifest-backend.yml +0 -69
- dbt_platform_helper/templates/svc/manifest-public.yml +0 -109
- dbt_platform_helper/utils/cloudfoundry.py +0 -14
- dbt_platform_helper/utils/files.py +0 -53
- dbt_platform_helper/utils/manifests.py +0 -18
- dbt_platform_helper/utils/versioning.py +0 -238
- dbt_platform_helper-13.1.0.dist-info/RECORD +0 -96
- {dbt_platform_helper-13.1.0.dist-info → dbt_platform_helper-15.16.0.dist-info}/entry_points.txt +0 -0
- {dbt_platform_helper-13.1.0.dist-info → dbt_platform_helper-15.16.0.dist-info/licenses}/LICENSE +0 -0
|
@@ -8,15 +8,22 @@ from schema import Regex
|
|
|
8
8
|
from schema import Schema
|
|
9
9
|
from schema import SchemaError
|
|
10
10
|
|
|
11
|
+
from dbt_platform_helper.constants import PLATFORM_CONFIG_SCHEMA_VERSION
|
|
12
|
+
from dbt_platform_helper.domain.plans import PlanLoader
|
|
13
|
+
|
|
14
|
+
plan_manager = PlanLoader()
|
|
15
|
+
plan_manager.load()
|
|
16
|
+
|
|
11
17
|
|
|
12
18
|
class PlatformConfigSchema:
|
|
13
19
|
@staticmethod
|
|
14
20
|
def schema() -> Schema:
|
|
15
21
|
return Schema(
|
|
16
22
|
{
|
|
23
|
+
"schema_version": PLATFORM_CONFIG_SCHEMA_VERSION,
|
|
17
24
|
"application": str,
|
|
18
25
|
Optional("deploy_repository"): str,
|
|
19
|
-
|
|
26
|
+
"default_versions": PlatformConfigSchema.__default_versions_schema(),
|
|
20
27
|
Optional("environments"): PlatformConfigSchema.__environments_schema(),
|
|
21
28
|
Optional("codebase_pipelines"): PlatformConfigSchema.__codebase_pipelines_schema(),
|
|
22
29
|
Optional(
|
|
@@ -28,6 +35,7 @@ class PlatformConfigSchema:
|
|
|
28
35
|
PlatformConfigSchema.__monitoring_schema(),
|
|
29
36
|
PlatformConfigSchema.__opensearch_schema(),
|
|
30
37
|
PlatformConfigSchema.__postgres_schema(),
|
|
38
|
+
PlatformConfigSchema.__datadog_schema(),
|
|
31
39
|
PlatformConfigSchema.__prometheus_policy_schema(),
|
|
32
40
|
PlatformConfigSchema.__redis_schema(),
|
|
33
41
|
PlatformConfigSchema.__s3_bucket_schema(),
|
|
@@ -48,12 +56,13 @@ class PlatformConfigSchema:
|
|
|
48
56
|
"postgres": Schema(PlatformConfigSchema.__postgres_schema()),
|
|
49
57
|
"prometheus-policy": Schema(PlatformConfigSchema.__prometheus_policy_schema()),
|
|
50
58
|
"redis": Schema(PlatformConfigSchema.__redis_schema()),
|
|
59
|
+
"datadog": Schema(PlatformConfigSchema.__datadog_schema()),
|
|
51
60
|
"s3": Schema(PlatformConfigSchema.__s3_bucket_schema()),
|
|
52
61
|
"s3-policy": Schema(PlatformConfigSchema.__s3_bucket_policy_schema()),
|
|
53
62
|
"subscription-filter": PlatformConfigSchema.__no_configuration_required_schema(
|
|
54
63
|
"subscription-filter"
|
|
55
64
|
),
|
|
56
|
-
#
|
|
65
|
+
# TODO: DBTP-1943: The next three are no longer relevant. Remove them.
|
|
57
66
|
"monitoring": Schema(PlatformConfigSchema.__monitoring_schema()),
|
|
58
67
|
"vpc": PlatformConfigSchema.__no_configuration_required_schema("vpc"),
|
|
59
68
|
"xray": PlatformConfigSchema.__no_configuration_required_schema("xray"),
|
|
@@ -105,7 +114,6 @@ class PlatformConfigSchema:
|
|
|
105
114
|
Optional("default_waf"): str,
|
|
106
115
|
Optional("domain_prefix"): str,
|
|
107
116
|
Optional("enable_logging"): bool,
|
|
108
|
-
Optional("env_root"): str,
|
|
109
117
|
Optional("forwarded_values_forward"): str,
|
|
110
118
|
Optional("forwarded_values_headers"): [str],
|
|
111
119
|
Optional("forwarded_values_query_string"): bool,
|
|
@@ -143,7 +151,7 @@ class PlatformConfigSchema:
|
|
|
143
151
|
{
|
|
144
152
|
"name": str,
|
|
145
153
|
Optional("requires_approval"): bool,
|
|
146
|
-
}
|
|
154
|
+
},
|
|
147
155
|
],
|
|
148
156
|
},
|
|
149
157
|
{
|
|
@@ -158,22 +166,24 @@ class PlatformConfigSchema:
|
|
|
158
166
|
},
|
|
159
167
|
),
|
|
160
168
|
],
|
|
169
|
+
Optional("cache_invalidation"): {
|
|
170
|
+
"domains": PlatformConfigSchema.__cache_invalidation_domains_schema(),
|
|
171
|
+
},
|
|
161
172
|
},
|
|
162
173
|
}
|
|
163
174
|
|
|
175
|
+
@staticmethod
|
|
176
|
+
def __cache_invalidation_domains_schema() -> dict:
|
|
177
|
+
return {str: {"paths": [str], "environment": str}}
|
|
178
|
+
|
|
164
179
|
@staticmethod
|
|
165
180
|
def __default_versions_schema() -> dict:
|
|
166
181
|
return {
|
|
167
|
-
|
|
168
|
-
Optional("platform-helper"): str,
|
|
182
|
+
"platform-helper": str,
|
|
169
183
|
}
|
|
170
184
|
|
|
171
185
|
@staticmethod
|
|
172
186
|
def __environments_schema() -> dict:
|
|
173
|
-
_valid_environment_specific_version_overrides = {
|
|
174
|
-
Optional("terraform-platform-modules"): str,
|
|
175
|
-
}
|
|
176
|
-
|
|
177
187
|
return {
|
|
178
188
|
str: Or(
|
|
179
189
|
None,
|
|
@@ -188,10 +198,15 @@ class PlatformConfigSchema:
|
|
|
188
198
|
"id": str,
|
|
189
199
|
},
|
|
190
200
|
},
|
|
191
|
-
#
|
|
201
|
+
# TODO: DBTP-1943: requires_approval is no longer relevant since we don't have AWS Copilot manage environment pipelines
|
|
192
202
|
Optional("requires_approval"): bool,
|
|
193
|
-
Optional("versions"): _valid_environment_specific_version_overrides,
|
|
194
203
|
Optional("vpc"): str,
|
|
204
|
+
Optional("service-deployment-mode"): Or(
|
|
205
|
+
"copilot",
|
|
206
|
+
"dual-deploy-copilot-traffic",
|
|
207
|
+
"dual-deploy-platform-traffic",
|
|
208
|
+
"platform",
|
|
209
|
+
),
|
|
195
210
|
},
|
|
196
211
|
)
|
|
197
212
|
}
|
|
@@ -248,18 +263,8 @@ class PlatformConfigSchema:
|
|
|
248
263
|
|
|
249
264
|
@staticmethod
|
|
250
265
|
def __opensearch_schema() -> dict:
|
|
251
|
-
#
|
|
252
|
-
_valid_opensearch_plans = Or(
|
|
253
|
-
"tiny",
|
|
254
|
-
"small",
|
|
255
|
-
"small-ha",
|
|
256
|
-
"medium",
|
|
257
|
-
"medium-ha",
|
|
258
|
-
"large",
|
|
259
|
-
"large-ha",
|
|
260
|
-
"x-large",
|
|
261
|
-
"x-large-ha",
|
|
262
|
-
)
|
|
266
|
+
# TODO: DBTP-1943: Move to OpenSearch provider?
|
|
267
|
+
_valid_opensearch_plans = Or(*plan_manager.get_plan_names("opensearch"))
|
|
263
268
|
|
|
264
269
|
return {
|
|
265
270
|
"type": "opensearch",
|
|
@@ -286,47 +291,27 @@ class PlatformConfigSchema:
|
|
|
286
291
|
|
|
287
292
|
@staticmethod
|
|
288
293
|
def __postgres_schema() -> dict:
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
"tiny",
|
|
292
|
-
"small",
|
|
293
|
-
"small-ha",
|
|
294
|
-
"small-high-io",
|
|
295
|
-
"medium",
|
|
296
|
-
"medium-ha",
|
|
297
|
-
"medium-high-io",
|
|
298
|
-
"large",
|
|
299
|
-
"large-ha",
|
|
300
|
-
"large-high-io",
|
|
301
|
-
"x-large",
|
|
302
|
-
"x-large-ha",
|
|
303
|
-
"x-large-high-io",
|
|
304
|
-
"2x-large",
|
|
305
|
-
"2x-large-ha",
|
|
306
|
-
"2x-large-high-io",
|
|
307
|
-
"4x-large",
|
|
308
|
-
"4x-large-ha",
|
|
309
|
-
"4x-large-high-io",
|
|
310
|
-
)
|
|
294
|
+
_valid_postgres_plans = Or(*plan_manager.get_plan_names("postgres"))
|
|
295
|
+
_valid_postgres_version = Or(int, float)
|
|
311
296
|
|
|
312
|
-
#
|
|
297
|
+
# TODO: DBTP-1943: Move to Postgres provider?
|
|
313
298
|
_valid_postgres_storage_types = Or("gp2", "gp3", "io1", "io2")
|
|
314
299
|
|
|
315
300
|
_valid_postgres_database_copy = {
|
|
316
301
|
"from": PlatformConfigSchema.__valid_environment_name(),
|
|
317
302
|
"to": PlatformConfigSchema.__valid_environment_name(),
|
|
318
|
-
Optional("from_account"): str,
|
|
319
|
-
Optional("to_account"): str,
|
|
320
303
|
Optional("pipeline"): {Optional("schedule"): str},
|
|
321
304
|
}
|
|
322
305
|
|
|
323
306
|
return {
|
|
324
307
|
"type": "postgres",
|
|
325
|
-
"version":
|
|
308
|
+
Optional("version"): _valid_postgres_version,
|
|
326
309
|
Optional("deletion_policy"): PlatformConfigSchema.__valid_postgres_deletion_policy(),
|
|
327
310
|
Optional("environments"): {
|
|
328
311
|
PlatformConfigSchema.__valid_environment_name(): {
|
|
312
|
+
Optional("apply_immediately"): bool,
|
|
329
313
|
Optional("plan"): _valid_postgres_plans,
|
|
314
|
+
Optional("version"): (Or(int, float)),
|
|
330
315
|
Optional("volume_size"): PlatformConfigSchema.is_integer_between(20, 10000),
|
|
331
316
|
Optional("iops"): PlatformConfigSchema.is_integer_between(1000, 9950),
|
|
332
317
|
Optional("snapshot_id"): str,
|
|
@@ -336,9 +321,6 @@ class PlatformConfigSchema:
|
|
|
336
321
|
Optional("deletion_protection"): bool,
|
|
337
322
|
Optional("multi_az"): bool,
|
|
338
323
|
Optional("storage_type"): _valid_postgres_storage_types,
|
|
339
|
-
Optional("backup_retention_days"): PlatformConfigSchema.is_integer_between(
|
|
340
|
-
1, 35
|
|
341
|
-
),
|
|
342
324
|
}
|
|
343
325
|
},
|
|
344
326
|
Optional("database_copy"): [_valid_postgres_database_copy],
|
|
@@ -364,21 +346,7 @@ class PlatformConfigSchema:
|
|
|
364
346
|
|
|
365
347
|
@staticmethod
|
|
366
348
|
def __redis_schema() -> dict:
|
|
367
|
-
|
|
368
|
-
_valid_redis_plans = Or(
|
|
369
|
-
"micro",
|
|
370
|
-
"micro-ha",
|
|
371
|
-
"tiny",
|
|
372
|
-
"tiny-ha",
|
|
373
|
-
"small",
|
|
374
|
-
"small-ha",
|
|
375
|
-
"medium",
|
|
376
|
-
"medium-ha",
|
|
377
|
-
"large",
|
|
378
|
-
"large-ha",
|
|
379
|
-
"x-large",
|
|
380
|
-
"x-large-ha",
|
|
381
|
-
)
|
|
349
|
+
_valid_redis_plans = Or(*plan_manager.get_plan_names("redis"))
|
|
382
350
|
|
|
383
351
|
return {
|
|
384
352
|
"type": "redis",
|
|
@@ -398,7 +366,7 @@ class PlatformConfigSchema:
|
|
|
398
366
|
|
|
399
367
|
@staticmethod
|
|
400
368
|
def valid_s3_bucket_name(name: str):
|
|
401
|
-
#
|
|
369
|
+
# TODO: DBTP-1943: This is a public method becasue that's what the test expect. Perhaps it belongs in an S3 provider?
|
|
402
370
|
errors = []
|
|
403
371
|
if not (2 < len(name) < 64):
|
|
404
372
|
errors.append("Length must be between 3 and 63 characters inclusive.")
|
|
@@ -427,13 +395,36 @@ class PlatformConfigSchema:
|
|
|
427
395
|
errors.append(f"Names cannot be suffixed '{suffix}'.")
|
|
428
396
|
|
|
429
397
|
if errors:
|
|
430
|
-
#
|
|
398
|
+
# TODO: DBTP-1943: Raise suitable PlatformException?
|
|
431
399
|
raise SchemaError(
|
|
432
|
-
"Bucket name '{}' is invalid:\n
|
|
400
|
+
f"Bucket name '{name}' is invalid:\n" + "\n".join(f" {e}" for e in errors)
|
|
433
401
|
)
|
|
434
402
|
|
|
435
403
|
return True
|
|
436
404
|
|
|
405
|
+
@staticmethod
|
|
406
|
+
def __datadog_schema() -> dict:
|
|
407
|
+
return {
|
|
408
|
+
"type": "datadog",
|
|
409
|
+
Optional("environments"): {
|
|
410
|
+
Optional(PlatformConfigSchema.__valid_environment_name()): {
|
|
411
|
+
"team_name": str,
|
|
412
|
+
Optional("contact_name"): str,
|
|
413
|
+
Optional("contact_email"): str,
|
|
414
|
+
Optional("contacts"): [
|
|
415
|
+
{
|
|
416
|
+
"name": str,
|
|
417
|
+
"type": str,
|
|
418
|
+
"contact": str,
|
|
419
|
+
}
|
|
420
|
+
],
|
|
421
|
+
Optional("documentation_url"): str,
|
|
422
|
+
"services_to_monitor": dict,
|
|
423
|
+
Optional("description"): str,
|
|
424
|
+
},
|
|
425
|
+
},
|
|
426
|
+
}
|
|
427
|
+
|
|
437
428
|
@staticmethod
|
|
438
429
|
def __s3_bucket_schema() -> dict:
|
|
439
430
|
def _valid_s3_bucket_arn(key):
|
|
@@ -506,7 +497,9 @@ class PlatformConfigSchema:
|
|
|
506
497
|
},
|
|
507
498
|
Optional("cross_environment_service_access"): {
|
|
508
499
|
PlatformConfigSchema.__valid_schema_key(): {
|
|
509
|
-
|
|
500
|
+
# Deprecated: We didn't implement cross application access, no service teams are asking for it.
|
|
501
|
+
# application should be removed once we can confirm that no-one is using it.
|
|
502
|
+
Optional("application"): str,
|
|
510
503
|
"environment": PlatformConfigSchema.__valid_environment_name(),
|
|
511
504
|
"account": str,
|
|
512
505
|
"service": str,
|
|
@@ -538,10 +531,10 @@ class PlatformConfigSchema:
|
|
|
538
531
|
|
|
539
532
|
@staticmethod
|
|
540
533
|
def string_matching_regex(regex_pattern: str) -> Callable:
|
|
541
|
-
#
|
|
534
|
+
# TODO: DBTP-1943: public for the unit tests, not sure about testing what could be a private method. Perhaps it's covered by other tests anyway?
|
|
542
535
|
def validate(string):
|
|
543
536
|
if not re.match(regex_pattern, string):
|
|
544
|
-
#
|
|
537
|
+
# TODO: DBTP-1943: Raise suitable PlatformException?
|
|
545
538
|
raise SchemaError(
|
|
546
539
|
f"String '{string}' does not match the required pattern '{regex_pattern}'."
|
|
547
540
|
)
|
|
@@ -551,11 +544,11 @@ class PlatformConfigSchema:
|
|
|
551
544
|
|
|
552
545
|
@staticmethod
|
|
553
546
|
def is_integer_between(lower_limit, upper_limit) -> Callable:
|
|
554
|
-
#
|
|
547
|
+
# TODO: DBTP-1943: public for the unit tests, not sure about testing what could be a private method. Perhaps it's covered by other tests anyway?
|
|
555
548
|
def validate(value):
|
|
556
549
|
if isinstance(value, int) and lower_limit <= value <= upper_limit:
|
|
557
550
|
return True
|
|
558
|
-
#
|
|
551
|
+
# TODO: DBTP-1943: Raise suitable PlatformException?
|
|
559
552
|
raise SchemaError(f"should be an integer between {lower_limit} and {upper_limit}")
|
|
560
553
|
|
|
561
554
|
return validate
|
|
@@ -569,7 +562,7 @@ class PlatformConfigSchema:
|
|
|
569
562
|
|
|
570
563
|
@staticmethod
|
|
571
564
|
def __valid_branch_name() -> Callable:
|
|
572
|
-
#
|
|
565
|
+
# TODO: DBTP-1943: Make this actually validate a git branch name properly; https://git-scm.com/docs/git-check-ref-format
|
|
573
566
|
return PlatformConfigSchema.string_matching_regex(r"^((?!\*).)*(\*)?$")
|
|
574
567
|
|
|
575
568
|
@staticmethod
|
|
@@ -615,10 +608,10 @@ class PlatformConfigSchema:
|
|
|
615
608
|
|
|
616
609
|
|
|
617
610
|
class ConditionalOpensSearchSchema(Schema):
|
|
618
|
-
#
|
|
611
|
+
# TODO: DBTP-1943: Move to OpenSearch provider?
|
|
619
612
|
_valid_opensearch_min_volume_size: int = 10
|
|
620
613
|
|
|
621
|
-
#
|
|
614
|
+
# TODO: DBTP-1943: Move to OpenSearch provider?
|
|
622
615
|
_valid_opensearch_max_volume_size: dict = {
|
|
623
616
|
"tiny": 100,
|
|
624
617
|
"small": 200,
|
|
@@ -652,11 +645,11 @@ class ConditionalOpensSearchSchema(Schema):
|
|
|
652
645
|
|
|
653
646
|
if volume_size:
|
|
654
647
|
if not plan:
|
|
655
|
-
#
|
|
648
|
+
# TODO: DBTP-1943: Raise suitable PlatformException?
|
|
656
649
|
raise SchemaError(f"Missing key: 'plan'")
|
|
657
650
|
|
|
658
651
|
if volume_size < self._valid_opensearch_min_volume_size:
|
|
659
|
-
#
|
|
652
|
+
# TODO: DBTP-1943: Raise suitable PlatformException?
|
|
660
653
|
raise SchemaError(
|
|
661
654
|
f"Key 'environments' error: Key '{env}' error: Key 'volume_size' error: should be an integer greater than {self._valid_opensearch_min_volume_size}"
|
|
662
655
|
)
|
|
@@ -666,7 +659,7 @@ class ConditionalOpensSearchSchema(Schema):
|
|
|
666
659
|
plan == key
|
|
667
660
|
and not volume_size <= self._valid_opensearch_max_volume_size[key]
|
|
668
661
|
):
|
|
669
|
-
#
|
|
662
|
+
# TODO: DBTP-1943: Raise suitable PlatformException?
|
|
670
663
|
raise SchemaError(
|
|
671
664
|
f"Key 'environments' error: Key '{env}' error: Key 'volume_size' error: should be an integer between {self._valid_opensearch_min_volume_size} and {self._valid_opensearch_max_volume_size[key]} for plan {plan}"
|
|
672
665
|
)
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import re
|
|
2
|
+
from typing import Union
|
|
3
|
+
|
|
4
|
+
from dbt_platform_helper.providers.validation import ValidationException
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class IncompatibleMajorVersionException(ValidationException):
|
|
8
|
+
def __init__(self, app_version: str, check_version: str):
|
|
9
|
+
super().__init__()
|
|
10
|
+
self.app_version = app_version
|
|
11
|
+
self.check_version = check_version
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class IncompatibleMinorVersionException(ValidationException):
|
|
15
|
+
def __init__(self, app_version: str, check_version: str):
|
|
16
|
+
super().__init__()
|
|
17
|
+
self.app_version = app_version
|
|
18
|
+
self.check_version = check_version
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class SemanticVersion:
|
|
22
|
+
def __init__(self, major: int, minor: int, patch: int):
|
|
23
|
+
self.major = major
|
|
24
|
+
self.minor = minor
|
|
25
|
+
self.patch = patch
|
|
26
|
+
|
|
27
|
+
def __str__(self) -> str:
|
|
28
|
+
if self.major is None:
|
|
29
|
+
return "unknown"
|
|
30
|
+
return ".".join([str(s) for s in [self.major, self.minor, self.patch]])
|
|
31
|
+
|
|
32
|
+
def __repr__(self) -> str:
|
|
33
|
+
return str(self)
|
|
34
|
+
|
|
35
|
+
def __lt__(self, other) -> bool:
|
|
36
|
+
return (self.major, self.minor, self.patch) < (other.major, other.minor, other.patch)
|
|
37
|
+
|
|
38
|
+
def __eq__(self, other) -> bool:
|
|
39
|
+
if other is None:
|
|
40
|
+
return False
|
|
41
|
+
return (self.major, self.minor, self.patch) == (other.major, other.minor, other.patch)
|
|
42
|
+
|
|
43
|
+
def validate_compatibility_with(self, other):
|
|
44
|
+
if other is None:
|
|
45
|
+
raise ValidationException("Cannot compare NoneType")
|
|
46
|
+
if (self.major == 0 and other.major == 0) and (
|
|
47
|
+
self.minor != other.minor or self.patch != other.patch
|
|
48
|
+
):
|
|
49
|
+
raise IncompatibleMajorVersionException(str(self), str(other))
|
|
50
|
+
|
|
51
|
+
if self.major != other.major:
|
|
52
|
+
raise IncompatibleMajorVersionException(str(self), str(other))
|
|
53
|
+
|
|
54
|
+
if self.minor != other.minor:
|
|
55
|
+
raise IncompatibleMinorVersionException(str(self), str(other))
|
|
56
|
+
|
|
57
|
+
@staticmethod
|
|
58
|
+
def _cast_to_int_with_fallback(input, fallback=-1):
|
|
59
|
+
try:
|
|
60
|
+
return int(input)
|
|
61
|
+
except ValueError:
|
|
62
|
+
return fallback
|
|
63
|
+
|
|
64
|
+
@classmethod
|
|
65
|
+
def from_string(self, version_string: Union[str, None]):
|
|
66
|
+
if version_string is None:
|
|
67
|
+
return None
|
|
68
|
+
|
|
69
|
+
version_segments = re.split(r"[.\-]", version_string.replace("v", ""))
|
|
70
|
+
|
|
71
|
+
if len(version_segments) != 3:
|
|
72
|
+
return None
|
|
73
|
+
|
|
74
|
+
major, minor, patch = [self._cast_to_int_with_fallback(s) for s in version_segments]
|
|
75
|
+
|
|
76
|
+
return SemanticVersion(major, minor, patch)
|
|
77
|
+
|
|
78
|
+
@staticmethod
|
|
79
|
+
def is_semantic_version(version_string):
|
|
80
|
+
if not version_string:
|
|
81
|
+
return False
|
|
82
|
+
valid_semantic_string_regex = r"(?i)^v?[0-9]+[.-][0-9]+[.-][0-9]+$"
|
|
83
|
+
return re.match(valid_semantic_string_regex, version_string)
|