validio-sdk 5.2.0__tar.gz → 5.3.0__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.
Files changed (58) hide show
  1. {validio_sdk-5.2.0 → validio_sdk-5.3.0}/PKG-INFO +1 -1
  2. {validio_sdk-5.2.0 → validio_sdk-5.3.0}/pyproject.toml +1 -1
  3. {validio_sdk-5.2.0 → validio_sdk-5.3.0}/validio_sdk/_api/api.py +55 -1
  4. {validio_sdk-5.2.0 → validio_sdk-5.3.0}/validio_sdk/resource/_diff.py +5 -115
  5. {validio_sdk-5.2.0 → validio_sdk-5.3.0}/validio_sdk/resource/_server_resources.py +61 -10
  6. {validio_sdk-5.2.0 → validio_sdk-5.3.0}/validio_sdk/resource/credentials.py +243 -2
  7. {validio_sdk-5.2.0 → validio_sdk-5.3.0}/validio_sdk/resource/filters.py +11 -49
  8. {validio_sdk-5.2.0 → validio_sdk-5.3.0}/validio_sdk/resource/sources.py +178 -6
  9. validio_sdk-5.3.0/validio_sdk/resource/tests/__init__.py +0 -0
  10. {validio_sdk-5.2.0 → validio_sdk-5.3.0}/validio_sdk/resource/tests/test__resource.py +7 -45
  11. {validio_sdk-5.2.0 → validio_sdk-5.3.0}/validio_sdk/resource/validators.py +12 -141
  12. validio_sdk-5.2.0/validio_sdk/resource/__init__.py +0 -6
  13. validio_sdk-5.2.0/validio_sdk/resource/_field_selector.py +0 -145
  14. validio_sdk-5.2.0/validio_sdk/resource/tests/test__field_selector.py +0 -71
  15. {validio_sdk-5.2.0 → validio_sdk-5.3.0}/LICENSE +0 -0
  16. {validio_sdk-5.2.0 → validio_sdk-5.3.0}/README_PUBLIC.md +0 -0
  17. {validio_sdk-5.2.0 → validio_sdk-5.3.0}/validio_sdk/__init__.py +0 -0
  18. {validio_sdk-5.2.0 → validio_sdk-5.3.0}/validio_sdk/_api/__init__.py +0 -0
  19. {validio_sdk-5.2.0 → validio_sdk-5.3.0}/validio_sdk/client/__init__.py +0 -0
  20. {validio_sdk-5.2.0 → validio_sdk-5.3.0}/validio_sdk/client/client.py +0 -0
  21. {validio_sdk-5.2.0 → validio_sdk-5.3.0}/validio_sdk/code/__init__.py +0 -0
  22. {validio_sdk-5.2.0 → validio_sdk-5.3.0}/validio_sdk/code/_import.py +0 -0
  23. {validio_sdk-5.2.0 → validio_sdk-5.3.0}/validio_sdk/code/_progress.py +0 -0
  24. {validio_sdk-5.2.0 → validio_sdk-5.3.0}/validio_sdk/code/apply.py +0 -0
  25. {validio_sdk-5.2.0 → validio_sdk-5.3.0}/validio_sdk/code/plan.py +0 -0
  26. {validio_sdk-5.2.0 → validio_sdk-5.3.0}/validio_sdk/code/scaffold.py +0 -0
  27. {validio_sdk-5.2.0 → validio_sdk-5.3.0}/validio_sdk/code/settings.py +0 -0
  28. {validio_sdk-5.2.0 → validio_sdk-5.3.0}/validio_sdk/config.py +0 -0
  29. {validio_sdk-5.2.0 → validio_sdk-5.3.0}/validio_sdk/dbt.py +0 -0
  30. {validio_sdk-5.2.0 → validio_sdk-5.3.0}/validio_sdk/exception.py +0 -0
  31. {validio_sdk-5.2.0 → validio_sdk-5.3.0}/validio_sdk/metadata.py +0 -0
  32. {validio_sdk-5.2.0 → validio_sdk-5.3.0}/validio_sdk/py.typed +0 -0
  33. {validio_sdk-5.2.0/validio_sdk/resource/tests → validio_sdk-5.3.0/validio_sdk/resource}/__init__.py +0 -0
  34. {validio_sdk-5.2.0 → validio_sdk-5.3.0}/validio_sdk/resource/_diff_util.py +0 -0
  35. {validio_sdk-5.2.0 → validio_sdk-5.3.0}/validio_sdk/resource/_diffable.py +0 -0
  36. {validio_sdk-5.2.0 → validio_sdk-5.3.0}/validio_sdk/resource/_errors.py +0 -0
  37. {validio_sdk-5.2.0 → validio_sdk-5.3.0}/validio_sdk/resource/_resource.py +0 -0
  38. {validio_sdk-5.2.0 → validio_sdk-5.3.0}/validio_sdk/resource/_resource_graph.py +0 -0
  39. {validio_sdk-5.2.0 → validio_sdk-5.3.0}/validio_sdk/resource/_serde.py +0 -0
  40. {validio_sdk-5.2.0 → validio_sdk-5.3.0}/validio_sdk/resource/_update_namespace.py +0 -0
  41. {validio_sdk-5.2.0 → validio_sdk-5.3.0}/validio_sdk/resource/_util.py +0 -0
  42. {validio_sdk-5.2.0 → validio_sdk-5.3.0}/validio_sdk/resource/channels.py +0 -0
  43. {validio_sdk-5.2.0 → validio_sdk-5.3.0}/validio_sdk/resource/notification_rules.py +0 -0
  44. {validio_sdk-5.2.0 → validio_sdk-5.3.0}/validio_sdk/resource/replacement.py +0 -0
  45. {validio_sdk-5.2.0 → validio_sdk-5.3.0}/validio_sdk/resource/segmentations.py +0 -0
  46. {validio_sdk-5.2.0 → validio_sdk-5.3.0}/validio_sdk/resource/tags.py +0 -0
  47. {validio_sdk-5.2.0 → validio_sdk-5.3.0}/validio_sdk/resource/tests/assets/example_manifest.json +0 -0
  48. {validio_sdk-5.2.0 → validio_sdk-5.3.0}/validio_sdk/resource/tests/assets/expected_trimmed_manifest.json +0 -0
  49. {validio_sdk-5.2.0 → validio_sdk-5.3.0}/validio_sdk/resource/tests/test__channel.py +0 -0
  50. {validio_sdk-5.2.0 → validio_sdk-5.3.0}/validio_sdk/resource/tests/test__dbt.py +0 -0
  51. {validio_sdk-5.2.0 → validio_sdk-5.3.0}/validio_sdk/resource/tests/test__diff.py +0 -0
  52. {validio_sdk-5.2.0 → validio_sdk-5.3.0}/validio_sdk/resource/tests/test__plan.py +0 -0
  53. {validio_sdk-5.2.0 → validio_sdk-5.3.0}/validio_sdk/resource/tests/test__sql_validation.py +0 -0
  54. {validio_sdk-5.2.0 → validio_sdk-5.3.0}/validio_sdk/resource/tests/test_import.py +0 -0
  55. {validio_sdk-5.2.0 → validio_sdk-5.3.0}/validio_sdk/resource/thresholds.py +0 -0
  56. {validio_sdk-5.2.0 → validio_sdk-5.3.0}/validio_sdk/resource/windows.py +0 -0
  57. {validio_sdk-5.2.0 → validio_sdk-5.3.0}/validio_sdk/scalars.py +0 -0
  58. {validio_sdk-5.2.0 → validio_sdk-5.3.0}/validio_sdk/util.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: validio-sdk
3
- Version: 5.2.0
3
+ Version: 5.3.0
4
4
  Summary: SDK to interact with the Validio platform
5
5
  Home-page: https://validio.io/
6
6
  License: Apache-2.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.2.0"
6
+ version = "5.3.0"
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(credential.get("config", {}), [("powerBiAuth", "auth")])
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
@@ -2523,6 +2576,7 @@ async def apply_source_action(
2523
2576
  result = {f"source{action.value}": {"errors": e.errors}}
2524
2577
  else:
2525
2578
  result = {f"source{action.value}": {"errors": [{"message": str(e)}]}}
2579
+
2526
2580
  return result[f"source{action.value}"]
2527
2581
 
2528
2582
 
@@ -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,7 +24,6 @@ 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
29
  from validio_sdk.resource.channels import Channel
@@ -179,51 +174,29 @@ async def diff_resource_graph(
179
174
  server_ctx: DiffContext,
180
175
  import_mode: bool = False,
181
176
  ) -> GraphDiff:
182
- partial_diff = _diff_resource_graph(
177
+ graph_diff = _diff_resource_graph(
183
178
  namespace=namespace,
184
179
  manifest_ctx=manifest_ctx,
185
180
  server_ctx=server_ctx,
186
- for_validators=False,
187
181
  import_mode=import_mode,
188
182
  )
189
183
 
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
184
  await enrich_resource_graph(
193
185
  manifest_ctx=manifest_ctx,
194
186
  server_ctx=server_ctx,
195
- graph=partial_diff,
187
+ graph=graph_diff,
196
188
  session=session,
197
189
  schema_reinference=schema_reinference,
198
190
  show_secrets=show_secrets,
199
191
  )
200
192
 
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
193
  _compute_replacements(
221
194
  manifest_ctx=manifest_ctx,
222
195
  server_ctx=server_ctx,
223
- graph_diff=final_diff,
196
+ graph_diff=graph_diff,
224
197
  )
225
198
 
226
- return final_diff
199
+ return graph_diff
227
200
 
228
201
 
229
202
  def _compute_replacements(
@@ -406,85 +379,10 @@ def _visit_resource_to_cascade_update(
406
379
  )
407
380
 
408
381
 
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
382
  def _diff_resource_graph(
484
383
  namespace: str,
485
384
  manifest_ctx: DiffContext,
486
385
  server_ctx: DiffContext,
487
- for_validators: bool | None = None,
488
386
  import_mode: bool = False,
489
387
  ) -> GraphDiff:
490
388
  # Backwards compatibility: Here we note the filters that
@@ -506,14 +404,6 @@ def _diff_resource_graph(
506
404
  for field in fields:
507
405
  if field in CREATE_ONLY_RESOURCES:
508
406
  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
407
  diff_by_resource[field] = diff_fn(
518
408
  namespace, getattr(manifest_ctx, field), getattr(server_ctx, field)
519
409
  )
@@ -974,7 +864,7 @@ async def check_for_source_schema_changes(
974
864
  manifest_source, server_source
975
865
  )
976
866
 
977
- # Ensure the source has a schema in case we need it in a field selector.
867
+ # Ensure the source has a schema in case we need it later on.
978
868
  if manifest_source.jtd_schema is None:
979
869
  manifest_source.jtd_schema = server_source.jtd_schema
980
870
 
@@ -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
- auth: SnowflakeCredentialAuth = SnowflakeCredentialUserPassword(
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
- auth = SnowflakeCredentialKeyPair(
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=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,
@@ -839,10 +894,6 @@ async def apply_updates_on_server(
839
894
  dry_run_sql=dry_run_sql,
840
895
  )
841
896
 
842
- # Now we should have all source schemas available. We can expand
843
- # field selectors.
844
- expand_validator_field_selectors(ctx)
845
-
846
897
  # Then apply updates.
847
898
  await apply_updates(
848
899
  namespace=namespace,
@@ -713,8 +713,6 @@ class SnowflakeCredential(Credential):
713
713
 
714
714
  :param name: Unique resource name assigned to the credential
715
715
  :param account: Snowflake account identifier.
716
- :param user: Deprecated, use auth instead.
717
- :param password: Deprecated, use auth instead.
718
716
  :param auth: Credentials to use for authentication.
719
717
  :param warehouse: Snowflake virtual warehouse to use to run queries.
720
718
  :param role: Snowflake role to assume when running queries.
@@ -1308,6 +1306,249 @@ class AzureSynapseSqlCredential(AzureSynapseCredential):
1308
1306
  return {"password"}
1309
1307
 
1310
1308
 
1309
+ class MsSqlServerCredentialUserPassword(ApiSecretChangeNestedResource):
1310
+ """MsSql-compatible credential via user-password auth."""
1311
+
1312
+ def __init__(
1313
+ self,
1314
+ user: str,
1315
+ password: str,
1316
+ ):
1317
+ """
1318
+ Constructor.
1319
+
1320
+ :param user: User name.
1321
+ :param password: Password.
1322
+ """
1323
+ self.user = user
1324
+ self.password = password
1325
+
1326
+ def _api_variant_name(self) -> str:
1327
+ return "userPassword"
1328
+
1329
+ def _immutable_fields(self) -> set[str]:
1330
+ return set({})
1331
+
1332
+ def _mutable_fields(self) -> set[str]:
1333
+ return {"user"}
1334
+
1335
+ def _secret_fields(self) -> set[str]:
1336
+ return {"password"}
1337
+
1338
+ def _nested_objects(
1339
+ self,
1340
+ ) -> dict[str, Optional["Diffable | list[Diffable]"] | None]:
1341
+ return {}
1342
+
1343
+
1344
+ class MsSqlServerCredentialEntraId(ApiSecretChangeNestedResource):
1345
+ """MsSql-compatible credential via entra-id auth."""
1346
+
1347
+ def __init__(
1348
+ self,
1349
+ client_id: str,
1350
+ client_secret: str,
1351
+ ):
1352
+ """
1353
+ Constructor.
1354
+
1355
+ :param client_id: The client ID of your Azure registered application.
1356
+ :param client_secret: The client secret of your Azure registered application.
1357
+ """
1358
+ self.client_id = client_id
1359
+ self.client_secret = client_secret
1360
+
1361
+ def _api_variant_name(self) -> str:
1362
+ return "entraId"
1363
+
1364
+ def _immutable_fields(self) -> set[str]:
1365
+ return set({})
1366
+
1367
+ def _mutable_fields(self) -> set[str]:
1368
+ return {"client_id"}
1369
+
1370
+ def _secret_fields(self) -> set[str]:
1371
+ return {"client_secret"}
1372
+
1373
+ def _nested_objects(
1374
+ self,
1375
+ ) -> dict[str, Optional["Diffable | list[Diffable]"] | None]:
1376
+ return {}
1377
+
1378
+
1379
+ MsSqlServerCredentialAuth = Union[
1380
+ MsSqlServerCredentialUserPassword, MsSqlServerCredentialEntraId
1381
+ ]
1382
+
1383
+
1384
+ class MsSqlServerCredential(Credential):
1385
+ """Credential to connect to a Microsoft Sql Server warehouse."""
1386
+
1387
+ def __init__(
1388
+ self,
1389
+ name: str,
1390
+ host: str,
1391
+ port: int,
1392
+ auth: MsSqlServerCredentialAuth,
1393
+ database: str | None = None,
1394
+ enable_catalog: bool = False,
1395
+ display_name: str | None = None,
1396
+ ignore_changes: bool = False,
1397
+ __internal__: ResourceGraph | None = None,
1398
+ ):
1399
+ """
1400
+ Constructor.
1401
+
1402
+ :param name: Unique resource name assigned to the credential
1403
+ :param host: Host address of the server.
1404
+ :param port: Port number of the server.
1405
+ :param auth: Credentials to use for authentication.
1406
+ :param database: Name of the database to connect to
1407
+ :param enable_catalog: If set to true, this credential will
1408
+ be used to fetch catalog information.
1409
+ :param display_name: Human-readable name for the credential. This name is
1410
+ visible in the UI and does not need to be unique.
1411
+ :param ignore_changes: If set to true, changes to the resource will be ignored.
1412
+ """
1413
+ super().__init__(
1414
+ name=name,
1415
+ display_name=display_name,
1416
+ ignore_changes=ignore_changes,
1417
+ __internal__=__internal__,
1418
+ )
1419
+
1420
+ self.host = host
1421
+ self.port = port
1422
+ self.auth = auth
1423
+ self.database = database
1424
+ self.enable_catalog = enable_catalog
1425
+
1426
+ def _immutable_fields(self) -> set[str]:
1427
+ return set({})
1428
+
1429
+ def _mutable_fields(self) -> set[str]:
1430
+ return {
1431
+ *super()._mutable_fields(),
1432
+ *{
1433
+ "host",
1434
+ "port",
1435
+ "database",
1436
+ "enable_catalog",
1437
+ },
1438
+ }
1439
+
1440
+ def _secret_fields(self) -> set[str]:
1441
+ return set()
1442
+
1443
+ def _nested_objects(
1444
+ self,
1445
+ ) -> dict[str, Optional["Diffable | list[Diffable]"] | None]:
1446
+ return {"auth": self.auth}
1447
+
1448
+
1449
+ class OracleCredentialUserPassword(ApiSecretChangeNestedResource):
1450
+ """Oracle credential via user-password auth."""
1451
+
1452
+ def __init__(
1453
+ self,
1454
+ user: str,
1455
+ password: str,
1456
+ ):
1457
+ """
1458
+ Constructor.
1459
+
1460
+ :param user: User name.
1461
+ :param password: Password.
1462
+ """
1463
+ self.user = user
1464
+ self.password = password
1465
+
1466
+ def _api_variant_name(self) -> str:
1467
+ return "userPassword"
1468
+
1469
+ def _immutable_fields(self) -> set[str]:
1470
+ return set({})
1471
+
1472
+ def _mutable_fields(self) -> set[str]:
1473
+ return {"user"}
1474
+
1475
+ def _secret_fields(self) -> set[str]:
1476
+ return {"password"}
1477
+
1478
+ def _nested_objects(
1479
+ self,
1480
+ ) -> dict[str, Optional["Diffable | list[Diffable]"] | None]:
1481
+ return {}
1482
+
1483
+
1484
+ OracleCredentialAuth = Union[OracleCredentialUserPassword]
1485
+
1486
+
1487
+ class OracleCredential(Credential):
1488
+ """Credential to connect to an Oracle database."""
1489
+
1490
+ def __init__(
1491
+ self,
1492
+ name: str,
1493
+ host: str,
1494
+ port: int,
1495
+ database: str,
1496
+ auth: OracleCredentialAuth,
1497
+ enable_catalog: bool = False,
1498
+ display_name: str | None = None,
1499
+ ignore_changes: bool = False,
1500
+ __internal__: ResourceGraph | None = None,
1501
+ ):
1502
+ """
1503
+ Constructor.
1504
+
1505
+ :param name: Unique resource name assigned to the credential
1506
+ :param host: Host address of the server.
1507
+ :param port: Port number of the server.
1508
+ :param auth: Credentials to use for authentication.
1509
+ :param database: Name of the database to connect to
1510
+ :param enable_catalog: If set to true, this credential will
1511
+ be used to fetch catalog information.
1512
+ :param display_name: Human-readable name for the credential. This name is
1513
+ visible in the UI and does not need to be unique.
1514
+ :param ignore_changes: If set to true, changes to the resource will be ignored.
1515
+ """
1516
+ super().__init__(
1517
+ name=name,
1518
+ display_name=display_name,
1519
+ ignore_changes=ignore_changes,
1520
+ __internal__=__internal__,
1521
+ )
1522
+
1523
+ self.host = host
1524
+ self.port = port
1525
+ self.database = database
1526
+ self.auth = auth
1527
+ self.enable_catalog = enable_catalog
1528
+
1529
+ def _immutable_fields(self) -> set[str]:
1530
+ return set({})
1531
+
1532
+ def _mutable_fields(self) -> set[str]:
1533
+ return {
1534
+ *super()._mutable_fields(),
1535
+ *{
1536
+ "host",
1537
+ "port",
1538
+ "database",
1539
+ "enable_catalog",
1540
+ },
1541
+ }
1542
+
1543
+ def _secret_fields(self) -> set[str]:
1544
+ return set()
1545
+
1546
+ def _nested_objects(
1547
+ self,
1548
+ ) -> dict[str, Optional["Diffable | list[Diffable]"] | None]:
1549
+ return {"auth": self.auth}
1550
+
1551
+
1311
1552
  class TableauConnectedAppCredential(Credential):
1312
1553
  """
1313
1554
  A credential resource that can be used to connect