zenml-nightly 0.83.1.dev20250625__py3-none-any.whl → 0.83.1.dev20250626__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.
- zenml/VERSION +1 -1
- zenml/cli/base.py +3 -2
- zenml/cli/service_connectors.py +5 -12
- zenml/cli/stack.py +1 -5
- zenml/cli/utils.py +8 -52
- zenml/client.py +32 -40
- zenml/integrations/aws/container_registries/aws_container_registry.py +3 -1
- zenml/integrations/databricks/orchestrators/databricks_orchestrator_entrypoint_config.py +8 -3
- zenml/integrations/integration.py +23 -58
- zenml/models/__init__.py +2 -0
- zenml/models/v2/core/service_connector.py +178 -108
- zenml/service_connectors/service_connector.py +11 -61
- zenml/service_connectors/service_connector_utils.py +4 -2
- zenml/utils/package_utils.py +111 -1
- zenml/zen_server/routers/service_connectors_endpoints.py +7 -22
- zenml/zen_stores/migrations/versions/5bb25e95849c_add_internal_secrets.py +62 -0
- zenml/zen_stores/rest_zen_store.py +57 -4
- zenml/zen_stores/schemas/secret_schemas.py +5 -0
- zenml/zen_stores/schemas/service_connector_schemas.py +16 -14
- zenml/zen_stores/secrets_stores/service_connector_secrets_store.py +4 -1
- zenml/zen_stores/sql_zen_store.py +214 -102
- zenml/zen_stores/zen_store_interface.py +9 -1
- {zenml_nightly-0.83.1.dev20250625.dist-info → zenml_nightly-0.83.1.dev20250626.dist-info}/METADATA +1 -1
- {zenml_nightly-0.83.1.dev20250625.dist-info → zenml_nightly-0.83.1.dev20250626.dist-info}/RECORD +27 -27
- zenml/utils/integration_utils.py +0 -34
- {zenml_nightly-0.83.1.dev20250625.dist-info → zenml_nightly-0.83.1.dev20250626.dist-info}/LICENSE +0 -0
- {zenml_nightly-0.83.1.dev20250625.dist-info → zenml_nightly-0.83.1.dev20250626.dist-info}/WHEEL +0 -0
- {zenml_nightly-0.83.1.dev20250625.dist-info → zenml_nightly-0.83.1.dev20250626.dist-info}/entry_points.txt +0 -0
@@ -54,7 +54,6 @@ from packaging import version
|
|
54
54
|
from pydantic import (
|
55
55
|
ConfigDict,
|
56
56
|
Field,
|
57
|
-
SecretStr,
|
58
57
|
SerializeAsAny,
|
59
58
|
field_validator,
|
60
59
|
model_validator,
|
@@ -264,6 +263,7 @@ from zenml.models import (
|
|
264
263
|
ServiceAccountRequest,
|
265
264
|
ServiceAccountResponse,
|
266
265
|
ServiceAccountUpdate,
|
266
|
+
ServiceConnectorConfiguration,
|
267
267
|
ServiceConnectorFilter,
|
268
268
|
ServiceConnectorRequest,
|
269
269
|
ServiceConnectorResourcesModel,
|
@@ -6743,6 +6743,40 @@ class SqlZenStore(BaseZenStore):
|
|
6743
6743
|
if self.backup_secrets_store:
|
6744
6744
|
self.backup_secrets_store.delete_secret_values(secret_id=secret_id)
|
6745
6745
|
|
6746
|
+
def _create_secret_schema(
|
6747
|
+
self, secret: SecretRequest, session: Session, internal: bool = False
|
6748
|
+
) -> SecretSchema:
|
6749
|
+
"""Creates a new secret schema.
|
6750
|
+
|
6751
|
+
Args:
|
6752
|
+
secret: The secret to create.
|
6753
|
+
session: The session to use.
|
6754
|
+
internal: Whether the secret is internal.
|
6755
|
+
|
6756
|
+
Returns:
|
6757
|
+
The newly created secret schema.
|
6758
|
+
"""
|
6759
|
+
new_secret = SecretSchema.from_request(
|
6760
|
+
secret,
|
6761
|
+
internal=internal,
|
6762
|
+
)
|
6763
|
+
session.add(new_secret)
|
6764
|
+
session.commit()
|
6765
|
+
|
6766
|
+
try:
|
6767
|
+
# Set the secret values in the configured secrets store
|
6768
|
+
self._set_secret_values(
|
6769
|
+
secret_id=new_secret.id, values=secret.secret_values
|
6770
|
+
)
|
6771
|
+
except:
|
6772
|
+
# If setting the secret values fails, delete the secret from the
|
6773
|
+
# database.
|
6774
|
+
session.delete(new_secret)
|
6775
|
+
session.commit()
|
6776
|
+
raise
|
6777
|
+
|
6778
|
+
return new_secret
|
6779
|
+
|
6746
6780
|
@track_decorator(AnalyticsEvent.CREATED_SECRET)
|
6747
6781
|
def create_secret(self, secret: SecretRequest) -> SecretResponse:
|
6748
6782
|
"""Creates a new secret.
|
@@ -6777,31 +6811,17 @@ class SqlZenStore(BaseZenStore):
|
|
6777
6811
|
if secret_exists:
|
6778
6812
|
raise EntityExistsError(msg)
|
6779
6813
|
|
6780
|
-
new_secret =
|
6781
|
-
secret,
|
6814
|
+
new_secret = self._create_secret_schema(
|
6815
|
+
secret=secret,
|
6816
|
+
session=session,
|
6782
6817
|
)
|
6783
|
-
session.add(new_secret)
|
6784
|
-
session.commit()
|
6785
6818
|
|
6786
6819
|
secret_model = new_secret.to_model(
|
6787
6820
|
include_metadata=True, include_resources=True
|
6788
6821
|
)
|
6789
6822
|
|
6790
|
-
|
6791
|
-
|
6792
|
-
self._set_secret_values(
|
6793
|
-
secret_id=new_secret.id, values=secret.secret_values
|
6794
|
-
)
|
6795
|
-
except:
|
6796
|
-
# If setting the secret values fails, delete the secret from the
|
6797
|
-
# database.
|
6798
|
-
with Session(self.engine) as session:
|
6799
|
-
session.delete(new_secret)
|
6800
|
-
session.commit()
|
6801
|
-
raise
|
6802
|
-
|
6803
|
-
secret_model.set_secrets(secret.secret_values)
|
6804
|
-
return secret_model
|
6823
|
+
secret_model.set_secrets(secret.secret_values)
|
6824
|
+
return secret_model
|
6805
6825
|
|
6806
6826
|
def get_secret(
|
6807
6827
|
self, secret_id: UUID, hydrate: bool = True
|
@@ -6821,7 +6841,11 @@ class SqlZenStore(BaseZenStore):
|
|
6821
6841
|
"""
|
6822
6842
|
with Session(self.engine) as session:
|
6823
6843
|
secret_in_db = session.exec(
|
6824
|
-
select(SecretSchema).where(
|
6844
|
+
select(SecretSchema).where(
|
6845
|
+
SecretSchema.id == secret_id,
|
6846
|
+
# Don't return internal secrets
|
6847
|
+
col(SecretSchema.internal).is_(False),
|
6848
|
+
)
|
6825
6849
|
).first()
|
6826
6850
|
if (
|
6827
6851
|
secret_in_db is None
|
@@ -6870,6 +6894,10 @@ class SqlZenStore(BaseZenStore):
|
|
6870
6894
|
self._get_active_user(session).id
|
6871
6895
|
)
|
6872
6896
|
query = select(SecretSchema)
|
6897
|
+
# Don't return internal secrets
|
6898
|
+
query = query.where(
|
6899
|
+
col(SecretSchema.internal).is_(False),
|
6900
|
+
)
|
6873
6901
|
return self.filter_and_paginate(
|
6874
6902
|
session=session,
|
6875
6903
|
query=query,
|
@@ -6910,7 +6938,11 @@ class SqlZenStore(BaseZenStore):
|
|
6910
6938
|
"""
|
6911
6939
|
with Session(self.engine) as session:
|
6912
6940
|
existing_secret = session.exec(
|
6913
|
-
select(SecretSchema).where(
|
6941
|
+
select(SecretSchema).where(
|
6942
|
+
SecretSchema.id == secret_id,
|
6943
|
+
# Don't update internal secrets
|
6944
|
+
col(SecretSchema.internal).is_(False),
|
6945
|
+
)
|
6914
6946
|
).first()
|
6915
6947
|
|
6916
6948
|
active_user = self._get_active_user(session)
|
@@ -6978,6 +7010,27 @@ class SqlZenStore(BaseZenStore):
|
|
6978
7010
|
|
6979
7011
|
return secret_model
|
6980
7012
|
|
7013
|
+
def _delete_secret_schema(self, secret_id: UUID, session: Session) -> None:
|
7014
|
+
"""Deletes a secret schema.
|
7015
|
+
|
7016
|
+
Args:
|
7017
|
+
secret_id: The ID of the secret to delete.
|
7018
|
+
session: The session to use.
|
7019
|
+
"""
|
7020
|
+
# Delete the secret values in the configured secrets store
|
7021
|
+
try:
|
7022
|
+
self._delete_secret_values(secret_id=secret_id)
|
7023
|
+
except KeyError:
|
7024
|
+
# If the secret values don't exist in the secrets store, we don't
|
7025
|
+
# need to raise an error.
|
7026
|
+
pass
|
7027
|
+
|
7028
|
+
secret_in_db = session.exec(
|
7029
|
+
select(SecretSchema).where(SecretSchema.id == secret_id)
|
7030
|
+
).one()
|
7031
|
+
session.delete(secret_in_db)
|
7032
|
+
session.commit()
|
7033
|
+
|
6981
7034
|
def delete_secret(self, secret_id: UUID) -> None:
|
6982
7035
|
"""Delete a secret.
|
6983
7036
|
|
@@ -6989,7 +7042,11 @@ class SqlZenStore(BaseZenStore):
|
|
6989
7042
|
"""
|
6990
7043
|
with Session(self.engine) as session:
|
6991
7044
|
existing_secret = session.exec(
|
6992
|
-
select(SecretSchema).where(
|
7045
|
+
select(SecretSchema).where(
|
7046
|
+
SecretSchema.id == secret_id,
|
7047
|
+
# Don't delete internal secrets
|
7048
|
+
col(SecretSchema.internal).is_(False),
|
7049
|
+
)
|
6993
7050
|
).first()
|
6994
7051
|
|
6995
7052
|
if not existing_secret or (
|
@@ -7003,19 +7060,7 @@ class SqlZenStore(BaseZenStore):
|
|
7003
7060
|
"not owned by the current user."
|
7004
7061
|
)
|
7005
7062
|
|
7006
|
-
|
7007
|
-
try:
|
7008
|
-
self._delete_secret_values(secret_id=secret_id)
|
7009
|
-
except KeyError:
|
7010
|
-
# If the secret values don't exist in the secrets store, we don't
|
7011
|
-
# need to raise an error.
|
7012
|
-
pass
|
7013
|
-
|
7014
|
-
secret_in_db = session.exec(
|
7015
|
-
select(SecretSchema).where(SecretSchema.id == secret_id)
|
7016
|
-
).one()
|
7017
|
-
session.delete(secret_in_db)
|
7018
|
-
session.commit()
|
7063
|
+
self._delete_secret_schema(secret_id=secret_id, session=session)
|
7019
7064
|
|
7020
7065
|
def backup_secrets(
|
7021
7066
|
self, ignore_errors: bool = True, delete_secrets: bool = False
|
@@ -7379,7 +7424,6 @@ class SqlZenStore(BaseZenStore):
|
|
7379
7424
|
resource_types=service_connector.resource_types,
|
7380
7425
|
resource_id=service_connector.resource_id,
|
7381
7426
|
configuration=service_connector.configuration,
|
7382
|
-
secrets=service_connector.secrets,
|
7383
7427
|
)
|
7384
7428
|
|
7385
7429
|
with Session(self.engine) as session:
|
@@ -7397,7 +7441,8 @@ class SqlZenStore(BaseZenStore):
|
|
7397
7441
|
# Create the secret
|
7398
7442
|
secret_id = self._create_connector_secret(
|
7399
7443
|
connector_name=service_connector.name,
|
7400
|
-
secrets=service_connector.secrets,
|
7444
|
+
secrets=service_connector.configuration.secrets,
|
7445
|
+
session=session,
|
7401
7446
|
)
|
7402
7447
|
try:
|
7403
7448
|
# Create the service connector
|
@@ -7425,12 +7470,20 @@ class SqlZenStore(BaseZenStore):
|
|
7425
7470
|
connector = new_service_connector.to_model(
|
7426
7471
|
include_metadata=True, include_resources=True
|
7427
7472
|
)
|
7473
|
+
if new_service_connector.secret_id:
|
7474
|
+
secrets = self._get_secret_values(
|
7475
|
+
secret_id=new_service_connector.secret_id
|
7476
|
+
)
|
7477
|
+
connector.add_secrets(secrets)
|
7428
7478
|
self._populate_connector_type(connector)
|
7429
7479
|
|
7430
7480
|
return connector
|
7431
7481
|
|
7432
7482
|
def get_service_connector(
|
7433
|
-
self,
|
7483
|
+
self,
|
7484
|
+
service_connector_id: UUID,
|
7485
|
+
hydrate: bool = True,
|
7486
|
+
expand_secrets: bool = False,
|
7434
7487
|
) -> ServiceConnectorResponse:
|
7435
7488
|
"""Gets a specific service connector.
|
7436
7489
|
|
@@ -7438,6 +7491,8 @@ class SqlZenStore(BaseZenStore):
|
|
7438
7491
|
service_connector_id: The ID of the service connector to get.
|
7439
7492
|
hydrate: Flag deciding whether to hydrate the output model(s)
|
7440
7493
|
by including metadata fields in the response.
|
7494
|
+
expand_secrets: Flag deciding whether to include the secrets in the
|
7495
|
+
output model.
|
7441
7496
|
|
7442
7497
|
Returns:
|
7443
7498
|
The requested service connector, if it was found.
|
@@ -7453,12 +7508,20 @@ class SqlZenStore(BaseZenStore):
|
|
7453
7508
|
include_metadata=hydrate, include_resources=True
|
7454
7509
|
)
|
7455
7510
|
self._populate_connector_type(connector)
|
7511
|
+
|
7512
|
+
if expand_secrets and service_connector.secret_id:
|
7513
|
+
secrets = self._get_secret_values(
|
7514
|
+
secret_id=service_connector.secret_id
|
7515
|
+
)
|
7516
|
+
connector.add_secrets(secrets)
|
7517
|
+
|
7456
7518
|
return connector
|
7457
7519
|
|
7458
7520
|
def list_service_connectors(
|
7459
7521
|
self,
|
7460
7522
|
filter_model: ServiceConnectorFilter,
|
7461
7523
|
hydrate: bool = False,
|
7524
|
+
expand_secrets: bool = False,
|
7462
7525
|
) -> Page[ServiceConnectorResponse]:
|
7463
7526
|
"""List all service connectors.
|
7464
7527
|
|
@@ -7467,6 +7530,8 @@ class SqlZenStore(BaseZenStore):
|
|
7467
7530
|
params.
|
7468
7531
|
hydrate: Flag deciding whether to hydrate the output model(s)
|
7469
7532
|
by including metadata fields in the response.
|
7533
|
+
expand_secrets: Flag deciding whether to include the secrets in the
|
7534
|
+
output models.
|
7470
7535
|
|
7471
7536
|
Returns:
|
7472
7537
|
A page of all service connectors.
|
@@ -7499,6 +7564,27 @@ class SqlZenStore(BaseZenStore):
|
|
7499
7564
|
|
7500
7565
|
return items
|
7501
7566
|
|
7567
|
+
def to_model_and_expand_secrets(
|
7568
|
+
schema: ServiceConnectorSchema,
|
7569
|
+
) -> ServiceConnectorResponse:
|
7570
|
+
"""Convert a service connector schema to a model and expand the secrets.
|
7571
|
+
|
7572
|
+
Args:
|
7573
|
+
schema: The service connector schema to convert.
|
7574
|
+
|
7575
|
+
Returns:
|
7576
|
+
The converted service connector model.
|
7577
|
+
"""
|
7578
|
+
model = schema.to_model(
|
7579
|
+
include_metadata=hydrate, include_resources=True
|
7580
|
+
)
|
7581
|
+
|
7582
|
+
if expand_secrets and schema.secret_id:
|
7583
|
+
secrets = self._get_secret_values(secret_id=schema.secret_id)
|
7584
|
+
model.add_secrets(secrets)
|
7585
|
+
|
7586
|
+
return model
|
7587
|
+
|
7502
7588
|
with Session(self.engine) as session:
|
7503
7589
|
query = select(ServiceConnectorSchema)
|
7504
7590
|
paged_connectors: Page[ServiceConnectorResponse] = (
|
@@ -7508,11 +7594,13 @@ class SqlZenStore(BaseZenStore):
|
|
7508
7594
|
table=ServiceConnectorSchema,
|
7509
7595
|
filter_model=filter_model,
|
7510
7596
|
custom_fetch=fetch_connectors,
|
7597
|
+
custom_schema_to_model_conversion=to_model_and_expand_secrets,
|
7511
7598
|
hydrate=hydrate,
|
7512
7599
|
)
|
7513
7600
|
)
|
7514
7601
|
|
7515
7602
|
self._populate_connector_type(*paged_connectors.items)
|
7603
|
+
|
7516
7604
|
return paged_connectors
|
7517
7605
|
|
7518
7606
|
def update_service_connector(
|
@@ -7524,16 +7612,13 @@ class SqlZenStore(BaseZenStore):
|
|
7524
7612
|
set to None in the model, the field is not updated, but there are
|
7525
7613
|
special rules concerning some fields:
|
7526
7614
|
|
7527
|
-
* the `configuration`
|
7528
|
-
|
7529
|
-
|
7530
|
-
will replace the existing configuration and secrets values.
|
7615
|
+
* the `configuration` field represents a full valid configuration
|
7616
|
+
update, not just a partial update. If it is set (i.e. not None) in the
|
7617
|
+
update, its values will replace the existing configuration values.
|
7531
7618
|
* the `resource_id` field value is also a full replacement value: if set
|
7532
7619
|
to `None`, the resource ID is removed from the service connector.
|
7533
7620
|
* the `expiration_seconds` field value is also a full replacement value:
|
7534
7621
|
if set to `None`, the expiration is removed from the service connector.
|
7535
|
-
* the `secret_id` field value in the update is ignored, given that
|
7536
|
-
secrets are managed internally by the ZenML store.
|
7537
7622
|
* the `labels` field is also a full labels update: if set (i.e. not
|
7538
7623
|
`None`), all existing labels are removed and replaced by the new labels
|
7539
7624
|
in the update.
|
@@ -7631,24 +7716,25 @@ class SqlZenStore(BaseZenStore):
|
|
7631
7716
|
update.auth_method = (
|
7632
7717
|
update.auth_method or existing_connector_model.auth_method
|
7633
7718
|
)
|
7634
|
-
# Validate the configuration update. If the configuration
|
7635
|
-
#
|
7636
|
-
#
|
7637
|
-
# type schema and replaces the existing configuration and
|
7638
|
-
# secrets values
|
7719
|
+
# Validate the configuration update. If the configuration is
|
7720
|
+
# set, it is validated against the connector type schema and
|
7721
|
+
# replaces the existing configuration values
|
7639
7722
|
update.validate_and_configure_resources(
|
7640
7723
|
connector_type=connector_type,
|
7641
7724
|
resource_types=update.resource_types,
|
7642
7725
|
resource_id=update.resource_id,
|
7643
7726
|
configuration=update.configuration,
|
7644
|
-
secrets=update.secrets,
|
7645
7727
|
)
|
7646
7728
|
|
7647
|
-
|
7648
|
-
|
7649
|
-
|
7650
|
-
|
7651
|
-
|
7729
|
+
secret_id = existing_connector.secret_id
|
7730
|
+
if update.configuration is not None:
|
7731
|
+
# Update secret
|
7732
|
+
secret_id = self._update_connector_secret(
|
7733
|
+
connector_name=existing_connector.name,
|
7734
|
+
existing_secret_id=existing_connector.secret_id,
|
7735
|
+
secrets=update.configuration.secrets,
|
7736
|
+
session=session,
|
7737
|
+
)
|
7652
7738
|
|
7653
7739
|
existing_connector.update(
|
7654
7740
|
connector_update=update, secret_id=secret_id
|
@@ -7659,6 +7745,10 @@ class SqlZenStore(BaseZenStore):
|
|
7659
7745
|
connector = existing_connector.to_model(
|
7660
7746
|
include_metadata=True, include_resources=True
|
7661
7747
|
)
|
7748
|
+
if secret_id:
|
7749
|
+
secrets = self._get_secret_values(secret_id=secret_id)
|
7750
|
+
connector.add_secrets(secrets)
|
7751
|
+
|
7662
7752
|
self._populate_connector_type(connector)
|
7663
7753
|
return connector
|
7664
7754
|
|
@@ -7693,7 +7783,10 @@ class SqlZenStore(BaseZenStore):
|
|
7693
7783
|
|
7694
7784
|
if service_connector.secret_id:
|
7695
7785
|
try:
|
7696
|
-
self.
|
7786
|
+
self._delete_secret_schema(
|
7787
|
+
secret_id=service_connector.secret_id,
|
7788
|
+
session=session,
|
7789
|
+
)
|
7697
7790
|
except KeyError:
|
7698
7791
|
# If the secret doesn't exist anymore, we can ignore
|
7699
7792
|
# this error
|
@@ -7704,7 +7797,8 @@ class SqlZenStore(BaseZenStore):
|
|
7704
7797
|
def _create_connector_secret(
|
7705
7798
|
self,
|
7706
7799
|
connector_name: str,
|
7707
|
-
secrets:
|
7800
|
+
secrets: Dict[str, PlainSerializedSecretStr],
|
7801
|
+
session: Session,
|
7708
7802
|
) -> Optional[UUID]:
|
7709
7803
|
"""Creates a new secret to store the service connector secret credentials.
|
7710
7804
|
|
@@ -7712,6 +7806,7 @@ class SqlZenStore(BaseZenStore):
|
|
7712
7806
|
connector_name: The name of the service connector for which to
|
7713
7807
|
create a secret.
|
7714
7808
|
secrets: The secret credentials to store.
|
7809
|
+
session: The session to use.
|
7715
7810
|
|
7716
7811
|
Returns:
|
7717
7812
|
The ID of the newly created secret or None, if the service connector
|
@@ -7729,19 +7824,23 @@ class SqlZenStore(BaseZenStore):
|
|
7729
7824
|
# that is not already in use
|
7730
7825
|
while True:
|
7731
7826
|
secret_name = f"connector-{connector_name}-{random_str(4)}".lower()
|
7732
|
-
existing_secrets =
|
7733
|
-
|
7734
|
-
name
|
7827
|
+
existing_secrets = session.exec(
|
7828
|
+
select(SecretSchema).where(
|
7829
|
+
SecretSchema.name == secret_name,
|
7735
7830
|
)
|
7736
|
-
)
|
7737
|
-
if not existing_secrets
|
7831
|
+
).all()
|
7832
|
+
if not existing_secrets:
|
7738
7833
|
try:
|
7739
|
-
return self.
|
7834
|
+
return self._create_secret_schema(
|
7740
7835
|
SecretRequest(
|
7836
|
+
user=self._get_active_user(session=session).id,
|
7741
7837
|
name=secret_name,
|
7742
7838
|
private=False,
|
7743
7839
|
values=secrets,
|
7744
|
-
)
|
7840
|
+
),
|
7841
|
+
session=session,
|
7842
|
+
# Hide service connector secrets from the user
|
7843
|
+
internal=True,
|
7745
7844
|
).id
|
7746
7845
|
except KeyError:
|
7747
7846
|
# The secret already exists, try again
|
@@ -7811,48 +7910,51 @@ class SqlZenStore(BaseZenStore):
|
|
7811
7910
|
|
7812
7911
|
def _update_connector_secret(
|
7813
7912
|
self,
|
7814
|
-
|
7815
|
-
|
7913
|
+
connector_name: str,
|
7914
|
+
existing_secret_id: Optional[UUID],
|
7915
|
+
secrets: Dict[str, PlainSerializedSecretStr],
|
7916
|
+
session: Session,
|
7816
7917
|
) -> Optional[UUID]:
|
7817
7918
|
"""Updates the secret for a service connector.
|
7818
7919
|
|
7819
|
-
If the secrets field in the service connector update is set (i.e. not
|
7820
|
-
None), the existing secret, if any, is replaced. If the secrets field is
|
7821
|
-
set to an empty dict, the existing secret is deleted.
|
7822
|
-
|
7823
7920
|
Args:
|
7824
|
-
|
7825
|
-
secret.
|
7826
|
-
|
7921
|
+
connector_name: The name of the service connector for which to
|
7922
|
+
update a secret.
|
7923
|
+
existing_secret_id: The ID of the existing secret to update, if one
|
7924
|
+
exists.
|
7925
|
+
secrets: The secrets to store.
|
7926
|
+
session: The session to use.
|
7827
7927
|
|
7828
7928
|
Returns:
|
7829
7929
|
The ID of the updated secret or None, if the new service connector
|
7830
7930
|
does not contain any secret credentials.
|
7831
7931
|
"""
|
7832
|
-
if updated_connector.secrets is None:
|
7833
|
-
# If the connector update does not contain a secrets update, keep
|
7834
|
-
# the existing secret (if any)
|
7835
|
-
return existing_connector.secret_id
|
7836
|
-
|
7837
|
-
# Delete the existing secret (if any), to be replaced by the new secret
|
7838
|
-
if existing_connector.secret_id:
|
7839
|
-
try:
|
7840
|
-
self.delete_secret(existing_connector.secret_id)
|
7841
|
-
except KeyError:
|
7842
|
-
# Ignore if the secret no longer exists
|
7843
|
-
pass
|
7844
|
-
|
7845
7932
|
# If the new service connector does not contain any secret credentials,
|
7846
7933
|
# return None
|
7847
|
-
if not
|
7934
|
+
if not secrets:
|
7935
|
+
if existing_secret_id:
|
7936
|
+
try:
|
7937
|
+
self.delete_secret(existing_secret_id)
|
7938
|
+
except KeyError:
|
7939
|
+
# Ignore if the secret no longer exists
|
7940
|
+
pass
|
7848
7941
|
return None
|
7849
7942
|
|
7850
|
-
|
7851
|
-
|
7852
|
-
|
7853
|
-
|
7854
|
-
|
7943
|
+
if not existing_secret_id:
|
7944
|
+
# A secret does not exist yet, create a new one
|
7945
|
+
return self._create_connector_secret(
|
7946
|
+
connector_name=connector_name,
|
7947
|
+
secrets=secrets,
|
7948
|
+
session=session,
|
7949
|
+
)
|
7950
|
+
|
7951
|
+
# Update the existing secret - we only need to update the values
|
7952
|
+
self._update_secret_values(
|
7953
|
+
secret_id=existing_secret_id,
|
7954
|
+
values={k: v.get_secret_value() for k, v in secrets.items()},
|
7955
|
+
overwrite=True,
|
7855
7956
|
)
|
7957
|
+
return existing_secret_id
|
7856
7958
|
|
7857
7959
|
def verify_service_connector_config(
|
7858
7960
|
self,
|
@@ -7896,7 +7998,9 @@ class SqlZenStore(BaseZenStore):
|
|
7896
7998
|
The list of resources that the service connector has access to,
|
7897
7999
|
scoped to the supplied resource type and ID, if provided.
|
7898
8000
|
"""
|
7899
|
-
connector = self.get_service_connector(
|
8001
|
+
connector = self.get_service_connector(
|
8002
|
+
service_connector_id, expand_secrets=True
|
8003
|
+
)
|
7900
8004
|
|
7901
8005
|
connector_instance = service_connector_registry.instantiate_connector(
|
7902
8006
|
model=connector
|
@@ -7925,7 +8029,9 @@ class SqlZenStore(BaseZenStore):
|
|
7925
8029
|
A service connector client that can be used to access the given
|
7926
8030
|
resource.
|
7927
8031
|
"""
|
7928
|
-
connector = self.get_service_connector(
|
8032
|
+
connector = self.get_service_connector(
|
8033
|
+
service_connector_id, expand_secrets=True
|
8034
|
+
)
|
7929
8035
|
|
7930
8036
|
connector_instance = service_connector_registry.instantiate_connector(
|
7931
8037
|
model=connector
|
@@ -8131,7 +8237,9 @@ class SqlZenStore(BaseZenStore):
|
|
8131
8237
|
# Fetch an existing service connector
|
8132
8238
|
if isinstance(connector_id_or_info, UUID):
|
8133
8239
|
existing_service_connector = (
|
8134
|
-
self.get_service_connector(
|
8240
|
+
self.get_service_connector(
|
8241
|
+
connector_id_or_info, expand_secrets=True
|
8242
|
+
)
|
8135
8243
|
)
|
8136
8244
|
if need_to_generate_permanent_tokens:
|
8137
8245
|
if (
|
@@ -8140,20 +8248,22 @@ class SqlZenStore(BaseZenStore):
|
|
8140
8248
|
)
|
8141
8249
|
is not False
|
8142
8250
|
):
|
8143
|
-
connector_config =
|
8144
|
-
existing_service_connector.configuration
|
8145
|
-
)
|
8251
|
+
connector_config = existing_service_connector.configuration.plain
|
8146
8252
|
connector_config[
|
8147
8253
|
"generate_temporary_tokens"
|
8148
8254
|
] = False
|
8149
8255
|
self.update_service_connector(
|
8150
8256
|
existing_service_connector.id,
|
8151
8257
|
ServiceConnectorUpdate(
|
8152
|
-
configuration=
|
8258
|
+
configuration=ServiceConnectorConfiguration(
|
8259
|
+
**connector_config
|
8260
|
+
)
|
8153
8261
|
),
|
8154
8262
|
)
|
8155
8263
|
service_connectors.append(
|
8156
|
-
self.get_service_connector(
|
8264
|
+
self.get_service_connector(
|
8265
|
+
connector_id_or_info, expand_secrets=True
|
8266
|
+
)
|
8157
8267
|
)
|
8158
8268
|
# Create a new service connector
|
8159
8269
|
else:
|
@@ -8169,7 +8279,9 @@ class SqlZenStore(BaseZenStore):
|
|
8169
8279
|
name=connector_name,
|
8170
8280
|
connector_type=connector_id_or_info.type,
|
8171
8281
|
auth_method=connector_id_or_info.auth_method,
|
8172
|
-
configuration=
|
8282
|
+
configuration=ServiceConnectorConfiguration(
|
8283
|
+
**connector_config
|
8284
|
+
),
|
8173
8285
|
labels={
|
8174
8286
|
k: str(v)
|
8175
8287
|
for k, v in stack.labels.items()
|
@@ -1980,7 +1980,10 @@ class ZenStoreInterface(ABC):
|
|
1980
1980
|
|
1981
1981
|
@abstractmethod
|
1982
1982
|
def get_service_connector(
|
1983
|
-
self,
|
1983
|
+
self,
|
1984
|
+
service_connector_id: UUID,
|
1985
|
+
hydrate: bool = True,
|
1986
|
+
expand_secrets: bool = False,
|
1984
1987
|
) -> ServiceConnectorResponse:
|
1985
1988
|
"""Gets a specific service connector.
|
1986
1989
|
|
@@ -1988,6 +1991,8 @@ class ZenStoreInterface(ABC):
|
|
1988
1991
|
service_connector_id: The ID of the service connector to get.
|
1989
1992
|
hydrate: Flag deciding whether to hydrate the output model(s)
|
1990
1993
|
by including metadata fields in the response.
|
1994
|
+
expand_secrets: Flag deciding whether to include the secrets
|
1995
|
+
associated with the service connector.
|
1991
1996
|
|
1992
1997
|
Returns:
|
1993
1998
|
The requested service connector, if it was found.
|
@@ -2001,6 +2006,7 @@ class ZenStoreInterface(ABC):
|
|
2001
2006
|
self,
|
2002
2007
|
filter_model: ServiceConnectorFilter,
|
2003
2008
|
hydrate: bool = False,
|
2009
|
+
expand_secrets: bool = False,
|
2004
2010
|
) -> Page[ServiceConnectorResponse]:
|
2005
2011
|
"""List all service connectors.
|
2006
2012
|
|
@@ -2009,6 +2015,8 @@ class ZenStoreInterface(ABC):
|
|
2009
2015
|
params.
|
2010
2016
|
hydrate: Flag deciding whether to hydrate the output model(s)
|
2011
2017
|
by including metadata fields in the response.
|
2018
|
+
expand_secrets: Flag deciding whether to include the secrets
|
2019
|
+
associated with the service connector.
|
2012
2020
|
|
2013
2021
|
Returns:
|
2014
2022
|
A page of all service connectors.
|