validio-sdk 5.2.0__tar.gz → 5.3.1__tar.gz
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.
- {validio_sdk-5.2.0 → validio_sdk-5.3.1}/PKG-INFO +1 -1
- {validio_sdk-5.2.0 → validio_sdk-5.3.1}/pyproject.toml +1 -1
- {validio_sdk-5.2.0 → validio_sdk-5.3.1}/validio_sdk/_api/api.py +55 -5
- {validio_sdk-5.2.0 → validio_sdk-5.3.1}/validio_sdk/code/_import.py +1 -1
- {validio_sdk-5.2.0 → validio_sdk-5.3.1}/validio_sdk/code/plan.py +1 -5
- {validio_sdk-5.2.0 → validio_sdk-5.3.1}/validio_sdk/resource/_diff.py +6 -151
- {validio_sdk-5.2.0 → validio_sdk-5.3.1}/validio_sdk/resource/_server_resources.py +66 -18
- {validio_sdk-5.2.0 → validio_sdk-5.3.1}/validio_sdk/resource/channels.py +17 -94
- {validio_sdk-5.2.0 → validio_sdk-5.3.1}/validio_sdk/resource/credentials.py +243 -2
- {validio_sdk-5.2.0 → validio_sdk-5.3.1}/validio_sdk/resource/filters.py +37 -152
- {validio_sdk-5.2.0 → validio_sdk-5.3.1}/validio_sdk/resource/sources.py +178 -6
- validio_sdk-5.3.1/validio_sdk/resource/tests/__init__.py +0 -0
- {validio_sdk-5.2.0 → validio_sdk-5.3.1}/validio_sdk/resource/tests/test__diff.py +3 -2
- {validio_sdk-5.2.0 → validio_sdk-5.3.1}/validio_sdk/resource/tests/test__plan.py +0 -54
- {validio_sdk-5.2.0 → validio_sdk-5.3.1}/validio_sdk/resource/tests/test__resource.py +7 -47
- {validio_sdk-5.2.0 → validio_sdk-5.3.1}/validio_sdk/resource/validators.py +40 -255
- validio_sdk-5.2.0/validio_sdk/resource/__init__.py +0 -6
- validio_sdk-5.2.0/validio_sdk/resource/_field_selector.py +0 -145
- validio_sdk-5.2.0/validio_sdk/resource/tests/test__channel.py +0 -137
- validio_sdk-5.2.0/validio_sdk/resource/tests/test__field_selector.py +0 -71
- {validio_sdk-5.2.0 → validio_sdk-5.3.1}/LICENSE +0 -0
- {validio_sdk-5.2.0 → validio_sdk-5.3.1}/README_PUBLIC.md +0 -0
- {validio_sdk-5.2.0 → validio_sdk-5.3.1}/validio_sdk/__init__.py +0 -0
- {validio_sdk-5.2.0 → validio_sdk-5.3.1}/validio_sdk/_api/__init__.py +0 -0
- {validio_sdk-5.2.0 → validio_sdk-5.3.1}/validio_sdk/client/__init__.py +0 -0
- {validio_sdk-5.2.0 → validio_sdk-5.3.1}/validio_sdk/client/client.py +0 -0
- {validio_sdk-5.2.0 → validio_sdk-5.3.1}/validio_sdk/code/__init__.py +0 -0
- {validio_sdk-5.2.0 → validio_sdk-5.3.1}/validio_sdk/code/_progress.py +0 -0
- {validio_sdk-5.2.0 → validio_sdk-5.3.1}/validio_sdk/code/apply.py +0 -0
- {validio_sdk-5.2.0 → validio_sdk-5.3.1}/validio_sdk/code/scaffold.py +0 -0
- {validio_sdk-5.2.0 → validio_sdk-5.3.1}/validio_sdk/code/settings.py +0 -0
- {validio_sdk-5.2.0 → validio_sdk-5.3.1}/validio_sdk/config.py +0 -0
- {validio_sdk-5.2.0 → validio_sdk-5.3.1}/validio_sdk/dbt.py +0 -0
- {validio_sdk-5.2.0 → validio_sdk-5.3.1}/validio_sdk/exception.py +0 -0
- {validio_sdk-5.2.0 → validio_sdk-5.3.1}/validio_sdk/metadata.py +0 -0
- {validio_sdk-5.2.0 → validio_sdk-5.3.1}/validio_sdk/py.typed +0 -0
- {validio_sdk-5.2.0/validio_sdk/resource/tests → validio_sdk-5.3.1/validio_sdk/resource}/__init__.py +0 -0
- {validio_sdk-5.2.0 → validio_sdk-5.3.1}/validio_sdk/resource/_diff_util.py +0 -0
- {validio_sdk-5.2.0 → validio_sdk-5.3.1}/validio_sdk/resource/_diffable.py +0 -0
- {validio_sdk-5.2.0 → validio_sdk-5.3.1}/validio_sdk/resource/_errors.py +0 -0
- {validio_sdk-5.2.0 → validio_sdk-5.3.1}/validio_sdk/resource/_resource.py +0 -0
- {validio_sdk-5.2.0 → validio_sdk-5.3.1}/validio_sdk/resource/_resource_graph.py +0 -0
- {validio_sdk-5.2.0 → validio_sdk-5.3.1}/validio_sdk/resource/_serde.py +0 -0
- {validio_sdk-5.2.0 → validio_sdk-5.3.1}/validio_sdk/resource/_update_namespace.py +0 -0
- {validio_sdk-5.2.0 → validio_sdk-5.3.1}/validio_sdk/resource/_util.py +0 -0
- {validio_sdk-5.2.0 → validio_sdk-5.3.1}/validio_sdk/resource/notification_rules.py +0 -0
- {validio_sdk-5.2.0 → validio_sdk-5.3.1}/validio_sdk/resource/replacement.py +0 -0
- {validio_sdk-5.2.0 → validio_sdk-5.3.1}/validio_sdk/resource/segmentations.py +0 -0
- {validio_sdk-5.2.0 → validio_sdk-5.3.1}/validio_sdk/resource/tags.py +0 -0
- {validio_sdk-5.2.0 → validio_sdk-5.3.1}/validio_sdk/resource/tests/assets/example_manifest.json +0 -0
- {validio_sdk-5.2.0 → validio_sdk-5.3.1}/validio_sdk/resource/tests/assets/expected_trimmed_manifest.json +0 -0
- {validio_sdk-5.2.0 → validio_sdk-5.3.1}/validio_sdk/resource/tests/test__dbt.py +0 -0
- {validio_sdk-5.2.0 → validio_sdk-5.3.1}/validio_sdk/resource/tests/test__sql_validation.py +0 -0
- {validio_sdk-5.2.0 → validio_sdk-5.3.1}/validio_sdk/resource/tests/test_import.py +0 -0
- {validio_sdk-5.2.0 → validio_sdk-5.3.1}/validio_sdk/resource/thresholds.py +0 -0
- {validio_sdk-5.2.0 → validio_sdk-5.3.1}/validio_sdk/resource/windows.py +0 -0
- {validio_sdk-5.2.0 → validio_sdk-5.3.1}/validio_sdk/scalars.py +0 -0
- {validio_sdk-5.2.0 → validio_sdk-5.3.1}/validio_sdk/util.py +0 -0
|
@@ -3,7 +3,7 @@ name = "validio-sdk"
|
|
|
3
3
|
# This version does not represent the released version or any tag. For each
|
|
4
4
|
# release we automatically bump this before building and publishing so this
|
|
5
5
|
# should be kept at 0.0.1dev1
|
|
6
|
-
version = "5.
|
|
6
|
+
version = "5.3.1"
|
|
7
7
|
description = "SDK to interact with the Validio platform"
|
|
8
8
|
authors = ["Validio <support@validio.io>"]
|
|
9
9
|
license = "Apache-2.0"
|
|
@@ -453,6 +453,22 @@ async def get_sources(
|
|
|
453
453
|
schedule
|
|
454
454
|
}
|
|
455
455
|
}
|
|
456
|
+
... on MsSqlServerSource {
|
|
457
|
+
config {
|
|
458
|
+
database
|
|
459
|
+
schema
|
|
460
|
+
table
|
|
461
|
+
schedule
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
... on OracleSource {
|
|
465
|
+
config {
|
|
466
|
+
database
|
|
467
|
+
schema
|
|
468
|
+
table
|
|
469
|
+
schedule
|
|
470
|
+
}
|
|
471
|
+
}
|
|
456
472
|
... on PostgreSqlSource {
|
|
457
473
|
config {
|
|
458
474
|
database
|
|
@@ -992,6 +1008,37 @@ async def get_credentials(
|
|
|
992
1008
|
}
|
|
993
1009
|
enableCatalog
|
|
994
1010
|
}
|
|
1011
|
+
... on MsSqlServerCredential {
|
|
1012
|
+
config {
|
|
1013
|
+
host
|
|
1014
|
+
port
|
|
1015
|
+
database
|
|
1016
|
+
auth {
|
|
1017
|
+
__typename
|
|
1018
|
+
... on MsSqlServerCredentialEntraId {
|
|
1019
|
+
clientId
|
|
1020
|
+
}
|
|
1021
|
+
... on MsSqlServerCredentialUserPassword {
|
|
1022
|
+
user
|
|
1023
|
+
}
|
|
1024
|
+
}
|
|
1025
|
+
}
|
|
1026
|
+
enableCatalog
|
|
1027
|
+
}
|
|
1028
|
+
... on OracleCredential {
|
|
1029
|
+
config {
|
|
1030
|
+
host
|
|
1031
|
+
port
|
|
1032
|
+
databaseRequired: database
|
|
1033
|
+
auth {
|
|
1034
|
+
__typename
|
|
1035
|
+
... on OracleCredentialUserPassword {
|
|
1036
|
+
user
|
|
1037
|
+
}
|
|
1038
|
+
}
|
|
1039
|
+
}
|
|
1040
|
+
enableCatalog
|
|
1041
|
+
}
|
|
995
1042
|
... on PostgreSqlCredential {
|
|
996
1043
|
config {
|
|
997
1044
|
host
|
|
@@ -1117,7 +1164,13 @@ async def get_credentials(
|
|
|
1117
1164
|
result = [result]
|
|
1118
1165
|
|
|
1119
1166
|
for i, credential in enumerate(result):
|
|
1120
|
-
_replace_aliases(
|
|
1167
|
+
_replace_aliases(
|
|
1168
|
+
credential.get("config", {}),
|
|
1169
|
+
[
|
|
1170
|
+
("powerBiAuth", "auth"),
|
|
1171
|
+
("databaseRequired", "database"),
|
|
1172
|
+
],
|
|
1173
|
+
)
|
|
1121
1174
|
result[i] = credential
|
|
1122
1175
|
|
|
1123
1176
|
return result[0] if return_first else result
|
|
@@ -1141,7 +1194,6 @@ async def get_channels(
|
|
|
1141
1194
|
}
|
|
1142
1195
|
... on SlackChannel {
|
|
1143
1196
|
config {
|
|
1144
|
-
slackWebhookUrl: webhookUrl
|
|
1145
1197
|
applicationLinkUrl
|
|
1146
1198
|
slackChannelId
|
|
1147
1199
|
interactiveMessageEnabled
|
|
@@ -1154,7 +1206,6 @@ async def get_channels(
|
|
|
1154
1206
|
}
|
|
1155
1207
|
... on MsTeamsChannel {
|
|
1156
1208
|
config {
|
|
1157
|
-
msTeamsWebhookUrl: webhookUrl
|
|
1158
1209
|
applicationLinkUrl
|
|
1159
1210
|
msTeamsChannelId
|
|
1160
1211
|
msTeamsInteractiveMessageEnabled: interactiveMessageEnabled
|
|
@@ -1223,8 +1274,6 @@ async def get_channels(
|
|
|
1223
1274
|
_replace_aliases(
|
|
1224
1275
|
ftr["config"],
|
|
1225
1276
|
[
|
|
1226
|
-
("slackWebhookUrl", "webhookUrl"),
|
|
1227
|
-
("msTeamsWebhookUrl", "webhookUrl"),
|
|
1228
1277
|
("msTeamsInteractiveMessageEnabled", "interactiveMessageEnabled"),
|
|
1229
1278
|
("emailInteractiveMessageEnabled", "interactiveMessageEnabled"),
|
|
1230
1279
|
],
|
|
@@ -2523,6 +2572,7 @@ async def apply_source_action(
|
|
|
2523
2572
|
result = {f"source{action.value}": {"errors": e.errors}}
|
|
2524
2573
|
else:
|
|
2525
2574
|
result = {f"source{action.value}": {"errors": [{"message": str(e)}]}}
|
|
2575
|
+
|
|
2526
2576
|
return result[f"source{action.value}"]
|
|
2527
2577
|
|
|
2528
2578
|
|
|
@@ -24,7 +24,7 @@ from validio_sdk.resource._resource import (
|
|
|
24
24
|
)
|
|
25
25
|
from validio_sdk.resource._server_resources import load_resources
|
|
26
26
|
from validio_sdk.resource._util import SourceSchemaReinference
|
|
27
|
-
from validio_sdk.resource.channels import
|
|
27
|
+
from validio_sdk.resource.channels import WebhookChannel
|
|
28
28
|
from validio_sdk.resource.tags import Tag
|
|
29
29
|
|
|
30
30
|
|
|
@@ -286,10 +286,6 @@ def _create_resource_diff_object(
|
|
|
286
286
|
if not show_secrets and hasattr(r, "_secret_fields"):
|
|
287
287
|
secret_fields = r._secret_fields()
|
|
288
288
|
|
|
289
|
-
# Workaround for Channel having a special secret field
|
|
290
|
-
if isinstance(r, Channel):
|
|
291
|
-
secret_fields.update(r._deprecated_secret_fields())
|
|
292
|
-
|
|
293
289
|
if secret_fields:
|
|
294
290
|
for field in secret_fields:
|
|
295
291
|
# We want to avoid overriding webhook_url if it is None already
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
import asyncio
|
|
2
|
-
import copy
|
|
3
2
|
import dataclasses
|
|
4
|
-
import re
|
|
5
3
|
import typing
|
|
6
4
|
from dataclasses import dataclass
|
|
7
5
|
from typing import (
|
|
@@ -9,7 +7,6 @@ from typing import (
|
|
|
9
7
|
Any,
|
|
10
8
|
Optional,
|
|
11
9
|
TypeVar,
|
|
12
|
-
cast,
|
|
13
10
|
)
|
|
14
11
|
|
|
15
12
|
from camel_converter import to_snake
|
|
@@ -18,7 +15,6 @@ from gql.transport.exceptions import TransportQueryError
|
|
|
18
15
|
from validio_sdk._api.api import secrets_changed_by_field, split_to_n_chunks
|
|
19
16
|
from validio_sdk.client import Session
|
|
20
17
|
from validio_sdk.exception import ValidioBugError, ValidioError
|
|
21
|
-
from validio_sdk.resource._diff_util import must_find_source
|
|
22
18
|
from validio_sdk.resource._diffable import (
|
|
23
19
|
ApiSecretChangeNestedResource,
|
|
24
20
|
Diffable,
|
|
@@ -28,10 +24,8 @@ from validio_sdk.resource._errors import (
|
|
|
28
24
|
max_resource_depth_exceeded,
|
|
29
25
|
updated_resource_type_mismatch_exception,
|
|
30
26
|
)
|
|
31
|
-
from validio_sdk.resource._field_selector import SelectorWithFieldName
|
|
32
27
|
from validio_sdk.resource._resource import CREATE_ONLY_RESOURCES, DiffContext, Resource
|
|
33
28
|
from validio_sdk.resource._util import SourceSchemaReinference, _sanitize_error
|
|
34
|
-
from validio_sdk.resource.channels import Channel
|
|
35
29
|
from validio_sdk.resource.replacement import (
|
|
36
30
|
CascadeReplacementReason,
|
|
37
31
|
ImmutableFieldReplacementReason,
|
|
@@ -41,7 +35,6 @@ from validio_sdk.resource.replacement import (
|
|
|
41
35
|
from validio_sdk.resource.segmentations import Segmentation
|
|
42
36
|
from validio_sdk.resource.sources import Source
|
|
43
37
|
from validio_sdk.resource.tags import Tag
|
|
44
|
-
from validio_sdk.resource.validators import Reference, Validator
|
|
45
38
|
from validio_sdk.resource.windows import TumblingWindow
|
|
46
39
|
|
|
47
40
|
if TYPE_CHECKING:
|
|
@@ -179,51 +172,29 @@ async def diff_resource_graph(
|
|
|
179
172
|
server_ctx: DiffContext,
|
|
180
173
|
import_mode: bool = False,
|
|
181
174
|
) -> GraphDiff:
|
|
182
|
-
|
|
175
|
+
graph_diff = _diff_resource_graph(
|
|
183
176
|
namespace=namespace,
|
|
184
177
|
manifest_ctx=manifest_ctx,
|
|
185
178
|
server_ctx=server_ctx,
|
|
186
|
-
for_validators=False,
|
|
187
179
|
import_mode=import_mode,
|
|
188
180
|
)
|
|
189
181
|
|
|
190
|
-
# Enrich resource_graph. We do this before expanding field selectors
|
|
191
|
-
# because the latter depends on the schema for all sources being present.
|
|
192
182
|
await enrich_resource_graph(
|
|
193
183
|
manifest_ctx=manifest_ctx,
|
|
194
184
|
server_ctx=server_ctx,
|
|
195
|
-
graph=
|
|
185
|
+
graph=graph_diff,
|
|
196
186
|
session=session,
|
|
197
187
|
schema_reinference=schema_reinference,
|
|
198
188
|
show_secrets=show_secrets,
|
|
199
189
|
)
|
|
200
190
|
|
|
201
|
-
# Expand field selector for validators.
|
|
202
|
-
expand_validator_field_selectors(manifest_ctx)
|
|
203
|
-
|
|
204
|
-
# Now after expanding field selectors, we can diff validators.
|
|
205
|
-
validators_diff = _diff_resource_graph(
|
|
206
|
-
namespace=namespace,
|
|
207
|
-
manifest_ctx=manifest_ctx,
|
|
208
|
-
server_ctx=server_ctx,
|
|
209
|
-
for_validators=True,
|
|
210
|
-
import_mode=import_mode,
|
|
211
|
-
)
|
|
212
|
-
|
|
213
|
-
final_diff = partial_diff
|
|
214
|
-
final_diff.to_create.validators = validators_diff.to_create.validators
|
|
215
|
-
final_diff.to_update.validators = validators_diff.to_update.validators
|
|
216
|
-
final_diff.to_delete.validators = validators_diff.to_delete.validators
|
|
217
|
-
for k, v in validators_diff.replacement_ctx.validators.items():
|
|
218
|
-
final_diff.replacement_ctx.validators[k] = v
|
|
219
|
-
|
|
220
191
|
_compute_replacements(
|
|
221
192
|
manifest_ctx=manifest_ctx,
|
|
222
193
|
server_ctx=server_ctx,
|
|
223
|
-
graph_diff=
|
|
194
|
+
graph_diff=graph_diff,
|
|
224
195
|
)
|
|
225
196
|
|
|
226
|
-
return
|
|
197
|
+
return graph_diff
|
|
227
198
|
|
|
228
199
|
|
|
229
200
|
def _compute_replacements(
|
|
@@ -281,8 +252,7 @@ def _visit_resource_to_replace(
|
|
|
281
252
|
to_delete: dict[str, Resource] = getattr(graph_diff.to_delete, resource_type)
|
|
282
253
|
|
|
283
254
|
# Remove the resource from the update list.
|
|
284
|
-
|
|
285
|
-
del to_update[resource_name]
|
|
255
|
+
to_update.pop(resource_name, None)
|
|
286
256
|
|
|
287
257
|
# Flag the resource to be created.
|
|
288
258
|
manifest_resources: dict[str, Resource] = getattr(manifest_ctx, resource_type)
|
|
@@ -406,85 +376,10 @@ def _visit_resource_to_cascade_update(
|
|
|
406
376
|
)
|
|
407
377
|
|
|
408
378
|
|
|
409
|
-
def expand_validator_field_selectors(manifest_ctx: DiffContext) -> None:
|
|
410
|
-
for name in list(manifest_ctx.validators.keys()):
|
|
411
|
-
template = manifest_ctx.validators[name]
|
|
412
|
-
|
|
413
|
-
source_field_selector: SelectorWithFieldName | None = getattr(
|
|
414
|
-
template, "_field_selector", None
|
|
415
|
-
)
|
|
416
|
-
reference_field_selector: dict[str, str] | None = getattr(
|
|
417
|
-
template, "_reference_field_selector", None
|
|
418
|
-
)
|
|
419
|
-
filter_field_selector: SelectorWithFieldName | None = (
|
|
420
|
-
getattr(template.filter, "_field_selector", None)
|
|
421
|
-
if template.filter
|
|
422
|
-
else None
|
|
423
|
-
)
|
|
424
|
-
|
|
425
|
-
if source_field_selector:
|
|
426
|
-
field_selector = source_field_selector
|
|
427
|
-
elif filter_field_selector:
|
|
428
|
-
field_selector = filter_field_selector
|
|
429
|
-
else:
|
|
430
|
-
continue
|
|
431
|
-
|
|
432
|
-
source = must_find_source(manifest_ctx, template.source_name)
|
|
433
|
-
if source.jtd_schema is None:
|
|
434
|
-
# If we have no schema then it means we're doing a diff where the
|
|
435
|
-
# source's credential has not yet been created - which means we can't
|
|
436
|
-
# do schema inference. As a result, we can't yet expand the selector.
|
|
437
|
-
continue
|
|
438
|
-
|
|
439
|
-
if source_field_selector:
|
|
440
|
-
delattr(template, "_field_selector")
|
|
441
|
-
if reference_field_selector:
|
|
442
|
-
delattr(template, "_reference_field_selector")
|
|
443
|
-
if filter_field_selector:
|
|
444
|
-
delattr(template.filter, "_field_selector")
|
|
445
|
-
|
|
446
|
-
# Remove the placeholder validator.
|
|
447
|
-
del manifest_ctx.validators[name]
|
|
448
|
-
|
|
449
|
-
fields = field_selector.field_selector._get_matching_fields(
|
|
450
|
-
cast(Any, source.jtd_schema)
|
|
451
|
-
)
|
|
452
|
-
|
|
453
|
-
# We don't want to deep copy the entire resource graph
|
|
454
|
-
resource_graph = template._resource_graph
|
|
455
|
-
template._resource_graph = None # type: ignore
|
|
456
|
-
for field in fields:
|
|
457
|
-
validator = copy.deepcopy(template)
|
|
458
|
-
validator._resource_graph = resource_graph
|
|
459
|
-
|
|
460
|
-
# We must obey to our own naming convention so we drop everything
|
|
461
|
-
# that's not valid.
|
|
462
|
-
resource_name = validator.name % {"field": field}
|
|
463
|
-
resource_name = resource_name.replace(" ", "_").lower()
|
|
464
|
-
resource_name = re.sub(r"[^a-z0-9_.-]", "_", resource_name)
|
|
465
|
-
validator.name = resource_name
|
|
466
|
-
|
|
467
|
-
if source_field_selector:
|
|
468
|
-
setattr(validator, field_selector.field_name, field)
|
|
469
|
-
|
|
470
|
-
if reference_field_selector:
|
|
471
|
-
setattr(validator, reference_field_selector["field_name"], field)
|
|
472
|
-
|
|
473
|
-
if filter_field_selector:
|
|
474
|
-
setattr(
|
|
475
|
-
validator.filter,
|
|
476
|
-
field_selector.field_name,
|
|
477
|
-
field,
|
|
478
|
-
)
|
|
479
|
-
|
|
480
|
-
manifest_ctx.validators[resource_name] = validator
|
|
481
|
-
|
|
482
|
-
|
|
483
379
|
def _diff_resource_graph(
|
|
484
380
|
namespace: str,
|
|
485
381
|
manifest_ctx: DiffContext,
|
|
486
382
|
server_ctx: DiffContext,
|
|
487
|
-
for_validators: bool | None = None,
|
|
488
383
|
import_mode: bool = False,
|
|
489
384
|
) -> GraphDiff:
|
|
490
385
|
# Backwards compatibility: Here we note the filters that
|
|
@@ -506,14 +401,6 @@ def _diff_resource_graph(
|
|
|
506
401
|
for field in fields:
|
|
507
402
|
if field in CREATE_ONLY_RESOURCES:
|
|
508
403
|
continue
|
|
509
|
-
|
|
510
|
-
include_diff = (
|
|
511
|
-
True
|
|
512
|
-
if for_validators is None
|
|
513
|
-
else (field == "validators") == for_validators
|
|
514
|
-
)
|
|
515
|
-
if not include_diff:
|
|
516
|
-
continue
|
|
517
404
|
diff_by_resource[field] = diff_fn(
|
|
518
405
|
namespace, getattr(manifest_ctx, field), getattr(server_ctx, field)
|
|
519
406
|
)
|
|
@@ -676,23 +563,6 @@ def diff(
|
|
|
676
563
|
if isinstance(manifest_object, Resource) and manifest_object.ignore_changes:
|
|
677
564
|
return None
|
|
678
565
|
|
|
679
|
-
# NOTE: Backwards compatibility while we transition to Filter resources.
|
|
680
|
-
# If we're about to diff a validator where the manifest validator still uses
|
|
681
|
-
# the JSONFilterExpression mode, then force the server object to work
|
|
682
|
-
# in the JSONFilterExpression mode so that we can compare the same fields.
|
|
683
|
-
# Same for validator reference.
|
|
684
|
-
if (
|
|
685
|
-
isinstance(manifest_object, (Reference, Validator))
|
|
686
|
-
and
|
|
687
|
-
# NOTE: the server resource is always the Validator. Even if
|
|
688
|
-
# the server object is potentially the nested 'Reference'.
|
|
689
|
-
# This is mostly for type-checking.
|
|
690
|
-
isinstance(server_resource, Validator)
|
|
691
|
-
and isinstance(manifest_resource, Validator)
|
|
692
|
-
) and not manifest_object._filter_resource_mode():
|
|
693
|
-
manifest_resource._force_filter_expression_mode()
|
|
694
|
-
server_resource._force_filter_expression_mode()
|
|
695
|
-
|
|
696
566
|
if isinstance(server_resource, Segmentation) and isinstance(
|
|
697
567
|
manifest_resource, Segmentation
|
|
698
568
|
):
|
|
@@ -752,20 +622,6 @@ def diff(
|
|
|
752
622
|
server = getattr(server_object, field)
|
|
753
623
|
|
|
754
624
|
if manifest != server:
|
|
755
|
-
# This is a temporary fix to support marking deprecated secret fields as
|
|
756
|
-
# changed on a `Channel`. If the field is both in `_mutable_fields`
|
|
757
|
-
# and also in `_deprecated_secret_fields` we will flag the field in
|
|
758
|
-
# `secret_fields_changed` if there has been an update. This ensures
|
|
759
|
-
# that the value is redacted by default when displaying the config.
|
|
760
|
-
secret_fields_changed = None
|
|
761
|
-
if (
|
|
762
|
-
isinstance(manifest_object, Channel)
|
|
763
|
-
and field in manifest_object._deprecated_secret_fields()
|
|
764
|
-
):
|
|
765
|
-
secret_fields_changed = {
|
|
766
|
-
field: True,
|
|
767
|
-
}
|
|
768
|
-
|
|
769
625
|
# Whenever we find there's a change to make, grab all fields on both
|
|
770
626
|
# resource versions so that we can present them as a diff.
|
|
771
627
|
# Regardless of at what depth we find a change, the diff we present
|
|
@@ -774,7 +630,6 @@ def diff(
|
|
|
774
630
|
return ResourceUpdate(
|
|
775
631
|
manifest_resource,
|
|
776
632
|
server_resource,
|
|
777
|
-
secret_fields_changed=secret_fields_changed,
|
|
778
633
|
)
|
|
779
634
|
|
|
780
635
|
# Some fields require the resource to be re-created if the type changes
|
|
@@ -974,7 +829,7 @@ async def check_for_source_schema_changes(
|
|
|
974
829
|
manifest_source, server_source
|
|
975
830
|
)
|
|
976
831
|
|
|
977
|
-
# Ensure the source has a schema in case we need it
|
|
832
|
+
# Ensure the source has a schema in case we need it later on.
|
|
978
833
|
if manifest_source.jtd_schema is None:
|
|
979
834
|
manifest_source.jtd_schema = server_source.jtd_schema
|
|
980
835
|
|
|
@@ -10,16 +10,13 @@ from gql.transport.exceptions import TransportQueryError
|
|
|
10
10
|
import validio_sdk
|
|
11
11
|
from validio_sdk._api import api
|
|
12
12
|
from validio_sdk.client import Session
|
|
13
|
-
from validio_sdk.client.client import Client
|
|
14
13
|
from validio_sdk.code._progress import ProgressBar
|
|
15
|
-
from validio_sdk.config import Config, ValidioConfig
|
|
16
14
|
from validio_sdk.exception import ValidioBugError, ValidioError
|
|
17
15
|
from validio_sdk.resource._diff import (
|
|
18
16
|
DiffContext,
|
|
19
17
|
GraphDiff,
|
|
20
18
|
ResourceUpdate,
|
|
21
19
|
ResourceUpdates,
|
|
22
|
-
expand_validator_field_selectors,
|
|
23
20
|
infer_schemas,
|
|
24
21
|
)
|
|
25
22
|
from validio_sdk.resource._diff_util import (
|
|
@@ -59,6 +56,13 @@ from validio_sdk.resource.credentials import (
|
|
|
59
56
|
LookerCredential,
|
|
60
57
|
MsPowerBiCredential,
|
|
61
58
|
MsPowerBiCredentialAuthEntraId,
|
|
59
|
+
MsSqlServerCredential,
|
|
60
|
+
MsSqlServerCredentialAuth,
|
|
61
|
+
MsSqlServerCredentialEntraId,
|
|
62
|
+
MsSqlServerCredentialUserPassword,
|
|
63
|
+
OracleCredential,
|
|
64
|
+
OracleCredentialAuth,
|
|
65
|
+
OracleCredentialUserPassword,
|
|
62
66
|
PostgreSqlCredential,
|
|
63
67
|
SigmaCredential,
|
|
64
68
|
SnowflakeCredential,
|
|
@@ -314,12 +318,12 @@ async def load_credentials(
|
|
|
314
318
|
auth_type = c["config"]["auth"]["__typename"]
|
|
315
319
|
|
|
316
320
|
if auth_type == "SnowflakeCredentialUserPassword":
|
|
317
|
-
|
|
321
|
+
sf_auth: SnowflakeCredentialAuth = SnowflakeCredentialUserPassword(
|
|
318
322
|
user=c["config"]["auth"]["user"],
|
|
319
323
|
password="UNSET",
|
|
320
324
|
)
|
|
321
325
|
elif auth_type == "SnowflakeCredentialKeyPair":
|
|
322
|
-
|
|
326
|
+
sf_auth = SnowflakeCredentialKeyPair(
|
|
323
327
|
user=c["config"]["auth"]["user"],
|
|
324
328
|
private_key="UNSET",
|
|
325
329
|
private_key_passphrase="UNSET",
|
|
@@ -330,13 +334,64 @@ async def load_credentials(
|
|
|
330
334
|
credential = SnowflakeCredential(
|
|
331
335
|
name=name,
|
|
332
336
|
account=c["config"]["account"],
|
|
333
|
-
auth=
|
|
337
|
+
auth=sf_auth,
|
|
334
338
|
warehouse=c["config"]["warehouse"],
|
|
335
339
|
role=c["config"]["role"],
|
|
336
340
|
display_name=display_name,
|
|
337
341
|
enable_catalog=c["enableCatalog"],
|
|
338
342
|
__internal__=g,
|
|
339
343
|
)
|
|
344
|
+
case "MsSqlServerCredential":
|
|
345
|
+
auth_type = c["config"]["auth"]["__typename"]
|
|
346
|
+
|
|
347
|
+
if auth_type == "MsSqlServerCredentialUserPassword":
|
|
348
|
+
ms_auth: MsSqlServerCredentialAuth = (
|
|
349
|
+
MsSqlServerCredentialUserPassword(
|
|
350
|
+
user=c["config"]["auth"]["user"],
|
|
351
|
+
password="UNSET",
|
|
352
|
+
)
|
|
353
|
+
)
|
|
354
|
+
elif auth_type == "MsSqlServerCredentialEntraId":
|
|
355
|
+
ms_auth = MsSqlServerCredentialEntraId(
|
|
356
|
+
client_id=c["config"]["auth"]["clientId"],
|
|
357
|
+
client_secret="UNSET",
|
|
358
|
+
)
|
|
359
|
+
else:
|
|
360
|
+
raise ValidioBugError(
|
|
361
|
+
f"Unknown MsSqlServer auth type: '{auth_type}'"
|
|
362
|
+
)
|
|
363
|
+
|
|
364
|
+
credential = MsSqlServerCredential(
|
|
365
|
+
name=name,
|
|
366
|
+
host=c["config"]["host"],
|
|
367
|
+
port=c["config"]["port"],
|
|
368
|
+
database=c["config"]["database"],
|
|
369
|
+
auth=ms_auth,
|
|
370
|
+
display_name=display_name,
|
|
371
|
+
enable_catalog=c["enableCatalog"],
|
|
372
|
+
__internal__=g,
|
|
373
|
+
)
|
|
374
|
+
case "OracleCredential":
|
|
375
|
+
auth_type = c["config"]["auth"]["__typename"]
|
|
376
|
+
|
|
377
|
+
if auth_type == "OracleCredentialUserPassword":
|
|
378
|
+
oracle_auth: OracleCredentialAuth = OracleCredentialUserPassword(
|
|
379
|
+
user=c["config"]["auth"]["user"],
|
|
380
|
+
password="UNSET",
|
|
381
|
+
)
|
|
382
|
+
else:
|
|
383
|
+
raise ValidioBugError(f"Unknown Oracle auth type: '{auth_type}'")
|
|
384
|
+
|
|
385
|
+
credential = OracleCredential(
|
|
386
|
+
name=name,
|
|
387
|
+
host=c["config"]["host"],
|
|
388
|
+
port=c["config"]["port"],
|
|
389
|
+
database=c["config"]["database"],
|
|
390
|
+
auth=oracle_auth,
|
|
391
|
+
display_name=display_name,
|
|
392
|
+
enable_catalog=c["enableCatalog"],
|
|
393
|
+
__internal__=g,
|
|
394
|
+
)
|
|
340
395
|
case "KafkaSslCredential":
|
|
341
396
|
credential = KafkaSslCredential(
|
|
342
397
|
name=name,
|
|
@@ -443,7 +498,6 @@ async def load_channels(
|
|
|
443
498
|
|
|
444
499
|
cfg = ch["config"]
|
|
445
500
|
application_link_url = cfg["applicationLinkUrl"]
|
|
446
|
-
unset_or_none = None if cfg.get("webhookUrl") else "UNSET"
|
|
447
501
|
interactive_message_enabled = cfg.get("interactiveMessageEnabled", None)
|
|
448
502
|
display_name = ch["name"]
|
|
449
503
|
# The 'secret' parts of a channel are left unset since they are not
|
|
@@ -454,10 +508,9 @@ async def load_channels(
|
|
|
454
508
|
name=name,
|
|
455
509
|
application_link_url=application_link_url,
|
|
456
510
|
ms_teams_channel_id=cfg["msTeamsChannelId"],
|
|
457
|
-
client_id=
|
|
458
|
-
client_secret=
|
|
511
|
+
client_id="UNSET",
|
|
512
|
+
client_secret="UNSET",
|
|
459
513
|
interactive_message_enabled=interactive_message_enabled,
|
|
460
|
-
webhook_url=cfg["webhookUrl"],
|
|
461
514
|
display_name=display_name,
|
|
462
515
|
__internal__=g,
|
|
463
516
|
)
|
|
@@ -466,11 +519,10 @@ async def load_channels(
|
|
|
466
519
|
name=name,
|
|
467
520
|
application_link_url=application_link_url,
|
|
468
521
|
slack_channel_id=cfg["slackChannelId"],
|
|
469
|
-
token=
|
|
470
|
-
signing_secret=
|
|
471
|
-
app_token=
|
|
522
|
+
token="UNSET",
|
|
523
|
+
signing_secret="UNSET",
|
|
524
|
+
app_token="UNSET",
|
|
472
525
|
interactive_message_enabled=interactive_message_enabled,
|
|
473
|
-
webhook_url=cfg["webhookUrl"],
|
|
474
526
|
display_name=display_name,
|
|
475
527
|
__internal__=g,
|
|
476
528
|
)
|
|
@@ -839,10 +891,6 @@ async def apply_updates_on_server(
|
|
|
839
891
|
dry_run_sql=dry_run_sql,
|
|
840
892
|
)
|
|
841
893
|
|
|
842
|
-
# Now we should have all source schemas available. We can expand
|
|
843
|
-
# field selectors.
|
|
844
|
-
expand_validator_field_selectors(ctx)
|
|
845
|
-
|
|
846
894
|
# Then apply updates.
|
|
847
895
|
await apply_updates(
|
|
848
896
|
namespace=namespace,
|