zenml-nightly 0.55.0.dev20240124__py3-none-any.whl → 0.72.0.dev20250116__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/__init__.py +9 -12
- zenml/actions/__init__.py +14 -0
- zenml/actions/base_action.py +682 -0
- zenml/actions/pipeline_run/__init__.py +0 -0
- zenml/actions/pipeline_run/pipeline_run_action.py +223 -0
- zenml/analytics/context.py +70 -15
- zenml/analytics/enums.py +21 -17
- zenml/analytics/models.py +1 -0
- zenml/analytics/utils.py +19 -7
- zenml/annotators/base_annotator.py +4 -3
- zenml/artifact_stores/base_artifact_store.py +155 -72
- zenml/artifact_stores/local_artifact_store.py +3 -2
- zenml/artifacts/artifact_config.py +67 -58
- zenml/artifacts/external_artifact.py +24 -39
- zenml/artifacts/external_artifact_config.py +27 -37
- zenml/artifacts/preexisting_data_materializer.py +90 -0
- zenml/artifacts/unmaterialized_artifact.py +2 -12
- zenml/artifacts/utils.py +521 -220
- zenml/cli/__init__.py +1511 -456
- zenml/cli/annotator.py +48 -14
- zenml/cli/artifact.py +22 -4
- zenml/cli/authorized_device.py +1 -0
- zenml/cli/base.py +185 -22
- zenml/cli/code_repository.py +1 -0
- zenml/cli/formatter.py +1 -1
- zenml/cli/integration.py +119 -24
- zenml/cli/login.py +1053 -0
- zenml/cli/model.py +42 -15
- zenml/cli/model_registry.py +1 -2
- zenml/cli/pipeline.py +168 -82
- zenml/cli/secret.py +1 -2
- zenml/cli/served_model.py +56 -26
- zenml/cli/server.py +486 -619
- zenml/cli/service_accounts.py +55 -14
- zenml/cli/service_connectors.py +97 -6
- zenml/cli/stack.py +821 -531
- zenml/cli/stack_components.py +15 -598
- zenml/cli/tag.py +1 -0
- zenml/cli/text_utils.py +36 -2
- zenml/cli/user_management.py +204 -6
- zenml/cli/utils.py +411 -290
- zenml/client.py +1742 -298
- zenml/client_lazy_loader.py +224 -0
- zenml/code_repositories/base_code_repository.py +5 -4
- zenml/code_repositories/git/local_git_repository_context.py +1 -0
- zenml/code_repositories/local_repository_context.py +1 -0
- zenml/config/__init__.py +2 -0
- zenml/config/base_settings.py +6 -6
- zenml/config/build_configuration.py +43 -17
- zenml/config/compiler.py +82 -49
- zenml/config/docker_settings.py +139 -83
- zenml/config/global_config.py +260 -234
- zenml/config/pipeline_configurations.py +32 -11
- zenml/config/pipeline_run_configuration.py +15 -3
- zenml/config/pipeline_spec.py +6 -6
- zenml/config/resource_settings.py +8 -9
- zenml/config/retry_config.py +27 -0
- zenml/config/schedule.py +27 -18
- zenml/config/secret_reference_mixin.py +8 -4
- zenml/config/secrets_store_config.py +16 -24
- zenml/config/server_config.py +434 -51
- zenml/config/settings_resolver.py +2 -1
- zenml/config/source.py +97 -31
- zenml/config/step_configurations.py +83 -39
- zenml/config/step_run_info.py +3 -0
- zenml/config/store_config.py +20 -54
- zenml/config/strict_base_model.py +2 -6
- zenml/console.py +0 -1
- zenml/constants.py +232 -74
- zenml/container_registries/azure_container_registry.py +1 -0
- zenml/container_registries/base_container_registry.py +7 -3
- zenml/container_registries/default_container_registry.py +4 -3
- zenml/container_registries/dockerhub_container_registry.py +1 -0
- zenml/container_registries/gcp_container_registry.py +1 -0
- zenml/container_registries/github_container_registry.py +2 -10
- zenml/data_validators/base_data_validator.py +2 -2
- zenml/entrypoints/base_entrypoint_configuration.py +76 -17
- zenml/entrypoints/pipeline_entrypoint_configuration.py +1 -0
- zenml/entrypoints/step_entrypoint_configuration.py +21 -2
- zenml/enums.py +91 -9
- zenml/environment.py +52 -319
- zenml/{steps/base_parameters.py → event_hub/__init__.py} +5 -7
- zenml/event_hub/base_event_hub.py +196 -0
- zenml/event_hub/event_hub.py +181 -0
- zenml/event_sources/__init__.py +14 -0
- zenml/{lineage_graph/edge.py → event_sources/base_event.py} +5 -7
- zenml/event_sources/base_event_source.py +695 -0
- zenml/event_sources/webhooks/__init__.py +14 -0
- zenml/event_sources/webhooks/base_webhook_event_source.py +231 -0
- zenml/exceptions.py +40 -41
- zenml/feature_stores/base_feature_store.py +4 -6
- zenml/hooks/hook_validators.py +3 -11
- zenml/image_builders/base_image_builder.py +5 -2
- zenml/image_builders/build_context.py +24 -80
- zenml/image_builders/local_image_builder.py +14 -6
- zenml/integrations/__init__.py +16 -4
- zenml/integrations/airflow/__init__.py +3 -5
- zenml/integrations/airflow/flavors/airflow_orchestrator_flavor.py +15 -7
- zenml/integrations/airflow/orchestrators/airflow_orchestrator.py +15 -252
- zenml/integrations/airflow/orchestrators/dag_generator.py +5 -3
- zenml/integrations/argilla/__init__.py +46 -0
- zenml/integrations/argilla/annotators/__init__.py +20 -0
- zenml/integrations/argilla/annotators/argilla_annotator.py +443 -0
- zenml/{post_execution → integrations/argilla/flavors}/__init__.py +9 -13
- zenml/integrations/argilla/flavors/argilla_annotator_flavor.py +150 -0
- zenml/integrations/aws/__init__.py +7 -3
- zenml/integrations/aws/container_registries/aws_container_registry.py +44 -8
- zenml/integrations/aws/flavors/__init__.py +6 -0
- zenml/integrations/aws/flavors/aws_container_registry_flavor.py +3 -2
- zenml/integrations/aws/flavors/aws_image_builder_flavor.py +146 -0
- zenml/integrations/aws/flavors/sagemaker_orchestrator_flavor.py +104 -16
- zenml/integrations/aws/flavors/sagemaker_step_operator_flavor.py +6 -2
- zenml/integrations/aws/image_builders/__init__.py +20 -0
- zenml/integrations/aws/image_builders/aws_image_builder.py +307 -0
- zenml/integrations/aws/orchestrators/sagemaker_orchestrator.py +421 -133
- zenml/integrations/aws/service_connectors/aws_service_connector.py +175 -48
- zenml/integrations/aws/step_operators/sagemaker_step_operator.py +1 -1
- zenml/integrations/azure/__init__.py +14 -5
- zenml/integrations/azure/azureml_utils.py +201 -0
- zenml/integrations/azure/flavors/__init__.py +11 -0
- zenml/integrations/azure/flavors/azureml.py +139 -0
- zenml/integrations/azure/flavors/azureml_orchestrator_flavor.py +166 -0
- zenml/integrations/azure/flavors/azureml_step_operator_flavor.py +71 -18
- zenml/integrations/azure/orchestrators/__init__.py +19 -0
- zenml/integrations/azure/orchestrators/azureml_orchestrator.py +583 -0
- zenml/integrations/azure/orchestrators/azureml_orchestrator_entrypoint_config.py +82 -0
- zenml/integrations/azure/service_connectors/azure_service_connector.py +15 -6
- zenml/integrations/azure/step_operators/azureml_step_operator.py +78 -173
- zenml/integrations/bentoml/__init__.py +1 -1
- zenml/integrations/bentoml/constants.py +1 -1
- zenml/integrations/bentoml/materializers/bentoml_bento_materializer.py +19 -31
- zenml/integrations/bentoml/model_deployers/bentoml_model_deployer.py +128 -239
- zenml/integrations/bentoml/services/__init__.py +15 -4
- zenml/integrations/bentoml/services/bentoml_container_deployment.py +399 -0
- zenml/integrations/bentoml/services/{bentoml_deployment.py → bentoml_local_deployment.py} +85 -43
- zenml/integrations/bentoml/services/deployment_type.py +23 -0
- zenml/integrations/bentoml/steps/bento_builder.py +2 -0
- zenml/integrations/bentoml/steps/bentoml_deployer.py +97 -47
- zenml/integrations/bitbucket/__init__.py +42 -0
- zenml/integrations/bitbucket/plugins/__init__.py +20 -0
- zenml/integrations/bitbucket/plugins/bitbucket_webhook_event_source_flavor.py +43 -0
- zenml/integrations/bitbucket/plugins/event_sources/__init__.py +0 -0
- zenml/integrations/bitbucket/plugins/event_sources/bitbucket_webhook_event_source.py +486 -0
- zenml/integrations/comet/__init__.py +49 -0
- zenml/integrations/{kserve/services → comet/experiment_trackers}/__init__.py +5 -6
- zenml/integrations/comet/experiment_trackers/comet_experiment_tracker.py +175 -0
- zenml/integrations/comet/flavors/__init__.py +24 -0
- zenml/integrations/comet/flavors/comet_experiment_tracker_flavor.py +129 -0
- zenml/integrations/constants.py +14 -2
- zenml/integrations/databricks/__init__.py +70 -0
- zenml/{lineage_graph → integrations/databricks/flavors}/__init__.py +14 -18
- zenml/integrations/databricks/flavors/databricks_model_deployer_flavor.py +118 -0
- zenml/integrations/databricks/flavors/databricks_orchestrator_flavor.py +174 -0
- zenml/integrations/{kserve → databricks}/model_deployers/__init__.py +5 -5
- zenml/integrations/databricks/model_deployers/databricks_model_deployer.py +249 -0
- zenml/integrations/databricks/orchestrators/__init__.py +20 -0
- zenml/integrations/databricks/orchestrators/databricks_orchestrator.py +501 -0
- zenml/integrations/databricks/orchestrators/databricks_orchestrator_entrypoint_config.py +97 -0
- zenml/integrations/databricks/services/__init__.py +19 -0
- zenml/integrations/databricks/services/databricks_deployment.py +407 -0
- zenml/integrations/{gcp/orchestrators/vertex_scheduler → databricks/utils}/__init__.py +2 -2
- zenml/integrations/databricks/utils/databricks_utils.py +87 -0
- zenml/integrations/deepchecks/__init__.py +30 -10
- zenml/integrations/deepchecks/data_validators/deepchecks_data_validator.py +59 -18
- zenml/integrations/deepchecks/materializers/deepchecks_dataset_materializer.py +3 -1
- zenml/integrations/deepchecks/materializers/deepchecks_results_materializer.py +3 -3
- zenml/integrations/deepchecks/validation_checks.py +62 -35
- zenml/integrations/discord/__init__.py +1 -0
- zenml/integrations/discord/steps/discord_alerter_ask_step.py +1 -0
- zenml/integrations/discord/steps/discord_alerter_post_step.py +1 -0
- zenml/integrations/evidently/__init__.py +22 -4
- zenml/integrations/evidently/column_mapping.py +11 -3
- zenml/integrations/evidently/data_validators/evidently_data_validator.py +24 -6
- zenml/integrations/evidently/metrics.py +7 -8
- zenml/integrations/evidently/tests.py +7 -8
- zenml/integrations/facets/__init__.py +22 -5
- zenml/integrations/facets/models.py +2 -7
- zenml/integrations/feast/__init__.py +19 -3
- zenml/integrations/feast/feature_stores/feast_feature_store.py +13 -32
- zenml/integrations/gcp/__init__.py +6 -6
- zenml/integrations/gcp/artifact_stores/gcp_artifact_store.py +6 -0
- zenml/integrations/gcp/flavors/gcp_artifact_store_flavor.py +1 -0
- zenml/integrations/gcp/flavors/vertex_orchestrator_flavor.py +24 -2
- zenml/integrations/gcp/flavors/vertex_step_operator_flavor.py +14 -1
- zenml/integrations/gcp/google_credentials_mixin.py +1 -1
- zenml/integrations/gcp/orchestrators/vertex_orchestrator.py +519 -296
- zenml/integrations/gcp/service_connectors/gcp_service_connector.py +788 -113
- zenml/integrations/gcp/step_operators/vertex_step_operator.py +9 -1
- zenml/integrations/github/__init__.py +15 -0
- zenml/integrations/github/code_repositories/github_code_repository.py +3 -2
- zenml/integrations/github/plugins/__init__.py +19 -0
- zenml/integrations/github/plugins/event_sources/__init__.py +0 -0
- zenml/integrations/github/plugins/event_sources/github_webhook_event_source.py +510 -0
- zenml/integrations/github/plugins/github_webhook_event_source_flavor.py +43 -0
- zenml/integrations/gitlab/code_repositories/gitlab_code_repository.py +7 -1
- zenml/integrations/great_expectations/__init__.py +22 -10
- zenml/integrations/great_expectations/data_validators/ge_data_validator.py +61 -57
- zenml/integrations/great_expectations/flavors/great_expectations_data_validator_flavor.py +35 -2
- zenml/integrations/great_expectations/ge_store_backend.py +24 -11
- zenml/integrations/great_expectations/materializers/ge_materializer.py +9 -9
- zenml/integrations/great_expectations/utils.py +5 -5
- zenml/integrations/huggingface/__init__.py +52 -1
- zenml/integrations/huggingface/flavors/__init__.py +26 -0
- zenml/integrations/huggingface/flavors/huggingface_model_deployer_flavor.py +130 -0
- zenml/integrations/huggingface/materializers/__init__.py +3 -0
- zenml/integrations/huggingface/materializers/huggingface_datasets_materializer.py +102 -19
- zenml/integrations/huggingface/materializers/huggingface_pt_model_materializer.py +18 -19
- zenml/integrations/huggingface/materializers/huggingface_t5_materializer.py +104 -0
- zenml/integrations/huggingface/materializers/huggingface_tf_model_materializer.py +18 -19
- zenml/integrations/huggingface/materializers/huggingface_tokenizer_materializer.py +13 -15
- zenml/integrations/huggingface/model_deployers/__init__.py +20 -0
- zenml/integrations/huggingface/model_deployers/huggingface_model_deployer.py +247 -0
- zenml/integrations/huggingface/services/__init__.py +19 -0
- zenml/integrations/huggingface/services/huggingface_deployment.py +292 -0
- zenml/integrations/huggingface/steps/__init__.py +21 -0
- zenml/integrations/huggingface/steps/accelerate_runner.py +166 -0
- zenml/integrations/huggingface/steps/huggingface_deployer.py +110 -0
- zenml/integrations/hyperai/__init__.py +53 -0
- zenml/integrations/hyperai/flavors/__init__.py +20 -0
- zenml/integrations/hyperai/flavors/hyperai_orchestrator_flavor.py +170 -0
- zenml/integrations/hyperai/orchestrators/__init__.py +21 -0
- zenml/integrations/hyperai/orchestrators/hyperai_orchestrator.py +510 -0
- zenml/integrations/hyperai/service_connectors/__init__.py +20 -0
- zenml/integrations/hyperai/service_connectors/hyperai_service_connector.py +375 -0
- zenml/integrations/integration.py +101 -47
- zenml/integrations/kaniko/flavors/kaniko_image_builder_flavor.py +6 -44
- zenml/integrations/kaniko/image_builders/kaniko_image_builder.py +9 -6
- zenml/integrations/kubeflow/__init__.py +4 -1
- zenml/integrations/kubeflow/flavors/kubeflow_orchestrator_flavor.py +67 -82
- zenml/integrations/kubeflow/orchestrators/kubeflow_orchestrator.py +306 -248
- zenml/integrations/kubernetes/__init__.py +6 -3
- zenml/integrations/kubernetes/flavors/__init__.py +8 -0
- zenml/integrations/kubernetes/flavors/kubernetes_orchestrator_flavor.py +43 -2
- zenml/integrations/kubernetes/flavors/kubernetes_step_operator_flavor.py +166 -0
- zenml/integrations/kubernetes/orchestrators/kube_utils.py +67 -12
- zenml/integrations/kubernetes/orchestrators/kubernetes_orchestrator.py +89 -21
- zenml/integrations/kubernetes/orchestrators/kubernetes_orchestrator_entrypoint.py +39 -7
- zenml/integrations/kubernetes/orchestrators/manifest_utils.py +42 -19
- zenml/integrations/kubernetes/pod_settings.py +21 -31
- zenml/integrations/kubernetes/serialization_utils.py +3 -3
- zenml/integrations/kubernetes/service_connectors/kubernetes_service_connector.py +14 -11
- zenml/integrations/kubernetes/step_operators/__init__.py +22 -0
- zenml/integrations/kubernetes/step_operators/kubernetes_step_operator.py +236 -0
- zenml/integrations/label_studio/__init__.py +1 -3
- zenml/integrations/label_studio/annotators/label_studio_annotator.py +46 -14
- zenml/integrations/label_studio/flavors/__init__.py +2 -0
- zenml/integrations/label_studio/flavors/label_studio_annotator_flavor.py +20 -5
- zenml/integrations/langchain/__init__.py +7 -1
- zenml/integrations/langchain/materializers/document_materializer.py +44 -8
- zenml/integrations/langchain/materializers/openai_embedding_materializer.py +28 -2
- zenml/integrations/lightgbm/__init__.py +1 -0
- zenml/integrations/lightgbm/materializers/lightgbm_booster_materializer.py +8 -15
- zenml/integrations/lightgbm/materializers/lightgbm_dataset_materializer.py +11 -16
- zenml/integrations/lightning/__init__.py +48 -0
- zenml/integrations/lightning/flavors/__init__.py +23 -0
- zenml/integrations/lightning/flavors/lightning_orchestrator_flavor.py +168 -0
- zenml/integrations/lightning/orchestrators/__init__.py +23 -0
- zenml/integrations/lightning/orchestrators/lightning_orchestrator.py +617 -0
- zenml/integrations/lightning/orchestrators/lightning_orchestrator_entrypoint.py +303 -0
- zenml/integrations/lightning/orchestrators/lightning_orchestrator_entrypoint_configuration.py +77 -0
- zenml/integrations/lightning/orchestrators/utils.py +67 -0
- zenml/integrations/mlflow/__init__.py +55 -8
- zenml/integrations/mlflow/experiment_trackers/mlflow_experiment_tracker.py +31 -13
- zenml/integrations/mlflow/flavors/mlflow_experiment_tracker_flavor.py +32 -37
- zenml/integrations/mlflow/model_deployers/mlflow_model_deployer.py +42 -233
- zenml/integrations/mlflow/model_registries/mlflow_model_registry.py +42 -49
- zenml/integrations/mlflow/services/mlflow_deployment.py +30 -5
- zenml/integrations/mlflow/steps/mlflow_deployer.py +25 -27
- zenml/integrations/mlflow/steps/mlflow_registry.py +3 -1
- zenml/integrations/modal/__init__.py +46 -0
- zenml/integrations/modal/flavors/__init__.py +26 -0
- zenml/integrations/modal/flavors/modal_step_operator_flavor.py +125 -0
- zenml/integrations/modal/step_operators/__init__.py +22 -0
- zenml/integrations/modal/step_operators/modal_step_operator.py +242 -0
- zenml/integrations/neptune/experiment_trackers/neptune_experiment_tracker.py +7 -5
- zenml/integrations/neptune/experiment_trackers/run_state.py +71 -55
- zenml/integrations/neptune/flavors/neptune_experiment_tracker_flavor.py +1 -1
- zenml/integrations/neural_prophet/__init__.py +6 -1
- zenml/integrations/numpy/__init__.py +32 -0
- zenml/integrations/{kserve/constants.py → numpy/materializers/__init__.py} +5 -4
- zenml/integrations/numpy/materializers/numpy_materializer.py +246 -0
- zenml/integrations/openai/__init__.py +1 -1
- zenml/integrations/openai/hooks/open_ai_failure_hook.py +39 -14
- zenml/{steps/external_artifact.py → integrations/pandas/__init__.py} +17 -11
- zenml/integrations/{kserve/custom_deployer → pandas/materializers}/__init__.py +5 -5
- zenml/integrations/pandas/materializers/pandas_materializer.py +192 -0
- zenml/integrations/pigeon/__init__.py +44 -0
- zenml/integrations/pigeon/annotators/__init__.py +20 -0
- zenml/integrations/pigeon/annotators/pigeon_annotator.py +330 -0
- zenml/integrations/{kserve → pigeon}/flavors/__init__.py +7 -7
- zenml/integrations/pigeon/flavors/pigeon_annotator_flavor.py +104 -0
- zenml/integrations/pillow/materializers/pillow_image_materializer.py +17 -20
- zenml/integrations/polars/__init__.py +1 -0
- zenml/integrations/polars/materializers/dataframe_materializer.py +26 -39
- zenml/integrations/prodigy/__init__.py +48 -0
- zenml/integrations/prodigy/annotators/__init__.py +20 -0
- zenml/integrations/prodigy/annotators/prodigy_annotator.py +275 -0
- zenml/integrations/prodigy/flavors/__init__.py +24 -0
- zenml/integrations/prodigy/flavors/prodigy_annotator_flavor.py +101 -0
- zenml/integrations/pycaret/__init__.py +6 -0
- zenml/integrations/pycaret/materializers/model_materializer.py +7 -22
- zenml/integrations/pytorch/materializers/base_pytorch_materializer.py +8 -2
- zenml/integrations/pytorch/materializers/pytorch_module_materializer.py +4 -1
- zenml/integrations/registry.py +38 -1
- zenml/integrations/s3/__init__.py +2 -3
- zenml/integrations/s3/artifact_stores/s3_artifact_store.py +191 -9
- zenml/integrations/s3/flavors/s3_artifact_store_flavor.py +22 -45
- zenml/integrations/s3/utils.py +39 -0
- zenml/integrations/seldon/__init__.py +18 -2
- zenml/integrations/seldon/model_deployers/seldon_model_deployer.py +19 -141
- zenml/integrations/seldon/secret_schemas/secret_schemas.py +2 -2
- zenml/integrations/seldon/seldon_client.py +55 -70
- zenml/integrations/seldon/services/seldon_deployment.py +4 -5
- zenml/integrations/seldon/steps/seldon_deployer.py +21 -20
- zenml/integrations/sklearn/__init__.py +1 -1
- zenml/integrations/skypilot/flavors/skypilot_orchestrator_base_vm_config.py +29 -7
- zenml/integrations/skypilot/orchestrators/skypilot_base_vm_orchestrator.py +47 -28
- zenml/integrations/skypilot/orchestrators/skypilot_orchestrator_entrypoint.py +2 -2
- zenml/integrations/skypilot_aws/__init__.py +3 -2
- zenml/integrations/skypilot_aws/flavors/skypilot_orchestrator_aws_vm_flavor.py +1 -1
- zenml/integrations/skypilot_azure/__init__.py +2 -4
- zenml/integrations/skypilot_azure/flavors/skypilot_orchestrator_azure_vm_flavor.py +1 -1
- zenml/integrations/skypilot_gcp/__init__.py +3 -2
- zenml/integrations/skypilot_gcp/flavors/skypilot_orchestrator_gcp_vm_flavor.py +1 -1
- zenml/integrations/skypilot_kubernetes/__init__.py +52 -0
- zenml/integrations/skypilot_kubernetes/flavors/__init__.py +26 -0
- zenml/integrations/skypilot_kubernetes/flavors/skypilot_orchestrator_kubernetes_vm_flavor.py +125 -0
- zenml/integrations/skypilot_kubernetes/orchestrators/__init__.py +25 -0
- zenml/integrations/skypilot_kubernetes/orchestrators/skypilot_kubernetes_vm_orchestrator.py +74 -0
- zenml/integrations/skypilot_lambda/__init__.py +50 -0
- zenml/integrations/{kserve/secret_schemas → skypilot_lambda/flavors}/__init__.py +9 -12
- zenml/integrations/skypilot_lambda/flavors/skypilot_orchestrator_lambda_vm_flavor.py +130 -0
- zenml/{lineage_graph/node → integrations/skypilot_lambda/orchestrators}/__init__.py +8 -15
- zenml/integrations/skypilot_lambda/orchestrators/skypilot_lambda_vm_orchestrator.py +92 -0
- zenml/integrations/slack/__init__.py +1 -0
- zenml/integrations/slack/alerters/slack_alerter.py +22 -2
- zenml/integrations/slack/flavors/__init__.py +2 -0
- zenml/integrations/slack/flavors/slack_alerter_flavor.py +13 -4
- zenml/integrations/slack/steps/slack_alerter_ask_step.py +1 -0
- zenml/integrations/slack/steps/slack_alerter_post_step.py +1 -0
- zenml/integrations/spark/flavors/spark_step_operator_flavor.py +2 -39
- zenml/integrations/spark/step_operators/kubernetes_step_operator.py +1 -0
- zenml/integrations/spark/step_operators/spark_entrypoint_configuration.py +1 -0
- zenml/integrations/spark/step_operators/spark_step_operator.py +2 -0
- zenml/integrations/tekton/__init__.py +2 -1
- zenml/integrations/tekton/flavors/tekton_orchestrator_flavor.py +66 -23
- zenml/integrations/tekton/orchestrators/tekton_orchestrator.py +549 -235
- zenml/integrations/tensorboard/__init__.py +1 -13
- zenml/integrations/tensorboard/services/tensorboard_service.py +3 -4
- zenml/integrations/tensorboard/visualizers/tensorboard_visualizer.py +66 -59
- zenml/integrations/tensorflow/__init__.py +10 -15
- zenml/integrations/tensorflow/materializers/keras_materializer.py +24 -27
- zenml/integrations/tensorflow/materializers/tf_dataset_materializer.py +9 -16
- zenml/integrations/vllm/__init__.py +50 -0
- zenml/integrations/vllm/flavors/__init__.py +21 -0
- zenml/integrations/vllm/flavors/vllm_model_deployer_flavor.py +91 -0
- zenml/integrations/vllm/model_deployers/__init__.py +19 -0
- zenml/integrations/vllm/model_deployers/vllm_model_deployer.py +263 -0
- zenml/integrations/vllm/services/__init__.py +19 -0
- zenml/integrations/vllm/services/vllm_deployment.py +206 -0
- zenml/integrations/wandb/__init__.py +1 -0
- zenml/integrations/wandb/flavors/wandb_experiment_tracker_flavor.py +21 -18
- zenml/integrations/whylogs/__init__.py +18 -2
- zenml/integrations/whylogs/data_validators/whylogs_data_validator.py +3 -3
- zenml/integrations/whylogs/flavors/whylogs_data_validator_flavor.py +1 -1
- zenml/integrations/whylogs/materializers/whylogs_materializer.py +14 -21
- zenml/integrations/xgboost/materializers/xgboost_booster_materializer.py +11 -22
- zenml/integrations/xgboost/materializers/xgboost_dmatrix_materializer.py +10 -19
- zenml/io/fileio.py +1 -0
- zenml/io/filesystem.py +2 -2
- zenml/io/local_filesystem.py +3 -3
- zenml/logger.py +41 -17
- zenml/logging/__init__.py +5 -0
- zenml/logging/step_logging.py +280 -32
- zenml/{new/steps → login}/__init__.py +4 -1
- zenml/login/credentials.py +370 -0
- zenml/login/credentials_store.py +638 -0
- zenml/{new/pipelines → login/pro}/__init__.py +4 -1
- zenml/login/pro/client.py +492 -0
- zenml/login/pro/constants.py +28 -0
- zenml/{zen_stores/schemas/identity_schemas.py → login/pro/models.py} +9 -11
- zenml/login/pro/organization/__init__.py +14 -0
- zenml/login/pro/organization/client.py +79 -0
- zenml/{lineage_graph/node/base_node.py → login/pro/organization/models.py} +13 -12
- zenml/{_hub → login/pro/tenant}/__init__.py +2 -2
- zenml/login/pro/tenant/client.py +92 -0
- zenml/login/pro/tenant/models.py +176 -0
- zenml/login/pro/utils.py +107 -0
- zenml/login/server_info.py +52 -0
- zenml/{cli → login}/web_login.py +71 -21
- zenml/materializers/__init__.py +2 -4
- zenml/materializers/base_materializer.py +180 -51
- zenml/materializers/built_in_materializer.py +50 -23
- zenml/materializers/cloudpickle_materializer.py +4 -5
- zenml/materializers/numpy_materializer.py +23 -233
- zenml/materializers/pandas_materializer.py +22 -174
- zenml/materializers/pydantic_materializer.py +2 -2
- zenml/materializers/service_materializer.py +12 -10
- zenml/materializers/structured_string_materializer.py +12 -6
- zenml/materializers/uuid_materializer.py +79 -0
- zenml/metadata/lazy_load.py +33 -17
- zenml/metadata/metadata_types.py +112 -3
- zenml/model/lazy_load.py +85 -4
- zenml/model/model.py +236 -226
- zenml/model/utils.py +99 -141
- zenml/model_deployers/base_model_deployer.py +319 -47
- zenml/model_registries/base_model_registry.py +17 -15
- zenml/models/__init__.py +254 -175
- zenml/models/v2/base/base.py +254 -112
- zenml/models/v2/base/base_plugin_flavor.py +76 -0
- zenml/models/v2/base/filter.py +530 -199
- zenml/models/v2/base/page.py +2 -12
- zenml/models/v2/base/scoped.py +292 -22
- zenml/models/v2/core/action.py +276 -0
- zenml/models/v2/core/action_flavor.py +57 -0
- zenml/models/v2/core/api_key.py +35 -12
- zenml/models/v2/core/artifact.py +126 -6
- zenml/models/v2/core/artifact_version.py +289 -65
- zenml/models/v2/core/artifact_visualization.py +10 -4
- zenml/models/v2/core/code_reference.py +13 -4
- zenml/models/v2/core/code_repository.py +39 -16
- zenml/models/v2/core/component.py +113 -61
- zenml/models/v2/core/device.py +25 -5
- zenml/models/v2/core/event_source.py +244 -0
- zenml/models/v2/core/event_source_flavor.py +67 -0
- zenml/models/v2/core/flavor.py +90 -27
- zenml/models/v2/core/logs.py +81 -12
- zenml/models/v2/core/model.py +91 -42
- zenml/models/v2/core/model_version.py +100 -55
- zenml/models/v2/core/model_version_artifact.py +96 -89
- zenml/models/v2/core/model_version_pipeline_run.py +86 -53
- zenml/models/v2/core/pipeline.py +205 -80
- zenml/models/v2/core/pipeline_build.py +110 -21
- zenml/models/v2/core/pipeline_deployment.py +101 -36
- zenml/models/v2/core/pipeline_run.py +545 -33
- zenml/models/v2/core/run_metadata.py +23 -181
- zenml/models/v2/core/run_template.py +439 -0
- zenml/models/v2/core/schedule.py +66 -29
- zenml/models/v2/core/secret.py +33 -21
- zenml/models/v2/core/server_settings.py +224 -0
- zenml/models/v2/core/service.py +500 -0
- zenml/models/v2/core/service_account.py +40 -15
- zenml/models/v2/core/service_connector.py +247 -49
- zenml/models/v2/core/stack.py +163 -70
- zenml/models/v2/core/step_run.py +210 -48
- zenml/models/v2/core/tag.py +21 -8
- zenml/models/v2/core/tag_resource.py +13 -4
- zenml/models/v2/core/trigger.py +422 -0
- zenml/models/v2/core/trigger_execution.py +119 -0
- zenml/models/v2/core/user.py +136 -69
- zenml/models/v2/core/workspace.py +26 -7
- zenml/models/v2/misc/auth_models.py +11 -2
- zenml/models/v2/misc/build_item.py +3 -3
- zenml/models/v2/misc/external_user.py +3 -6
- zenml/models/v2/misc/info_models.py +78 -0
- zenml/models/v2/misc/loaded_visualization.py +2 -2
- zenml/models/v2/misc/run_metadata.py +38 -0
- zenml/models/v2/misc/server_models.py +100 -0
- zenml/models/v2/misc/service_connector_type.py +9 -17
- zenml/models/v2/misc/stack_deployment.py +96 -0
- zenml/models/v2/misc/user_auth.py +7 -9
- zenml/orchestrators/__init__.py +4 -0
- zenml/orchestrators/base_orchestrator.py +136 -25
- zenml/orchestrators/containerized_orchestrator.py +1 -0
- zenml/orchestrators/dag_runner.py +18 -3
- zenml/orchestrators/input_utils.py +109 -48
- zenml/orchestrators/local/local_orchestrator.py +10 -0
- zenml/orchestrators/local_docker/local_docker_orchestrator.py +14 -42
- zenml/orchestrators/output_utils.py +16 -6
- zenml/orchestrators/publish_utils.py +12 -5
- zenml/orchestrators/step_launcher.py +142 -194
- zenml/orchestrators/step_run_utils.py +386 -0
- zenml/orchestrators/step_runner.py +181 -270
- zenml/orchestrators/utils.py +219 -84
- zenml/orchestrators/wheeled_orchestrator.py +147 -0
- zenml/pipelines/__init__.py +3 -16
- zenml/{new/pipelines → pipelines}/build_utils.py +287 -47
- zenml/{new/pipelines → pipelines}/pipeline_context.py +6 -2
- zenml/pipelines/pipeline_decorator.py +40 -64
- zenml/{new/pipelines/pipeline.py → pipelines/pipeline_definition.py} +376 -440
- zenml/pipelines/run_utils.py +358 -0
- zenml/plugins/__init__.py +0 -0
- zenml/plugins/base_plugin_flavor.py +88 -0
- zenml/plugins/plugin_flavor_registry.py +342 -0
- zenml/secret/base_secret.py +7 -8
- zenml/secret/schemas/basic_auth_secret_schema.py +0 -1
- zenml/service_connectors/docker_service_connector.py +19 -4
- zenml/service_connectors/service_connector.py +12 -14
- zenml/service_connectors/service_connector_registry.py +71 -55
- zenml/service_connectors/service_connector_utils.py +418 -0
- zenml/services/__init__.py +0 -2
- zenml/services/container/container_service.py +9 -6
- zenml/services/container/container_service_endpoint.py +1 -1
- zenml/services/container/entrypoint.py +3 -2
- zenml/services/local/local_daemon_entrypoint.py +9 -6
- zenml/services/local/local_service.py +1 -1
- zenml/services/local/local_service_endpoint.py +1 -1
- zenml/services/service.py +222 -130
- zenml/services/service_status.py +2 -1
- zenml/services/service_type.py +6 -5
- zenml/stack/flavor.py +25 -18
- zenml/stack/flavor_registry.py +4 -4
- zenml/stack/stack.py +20 -131
- zenml/stack/stack_component.py +136 -110
- zenml/stack/utils.py +36 -15
- zenml/stack_deployments/__init__.py +14 -0
- zenml/stack_deployments/aws_stack_deployment.py +320 -0
- zenml/stack_deployments/azure_stack_deployment.py +315 -0
- zenml/stack_deployments/gcp_stack_deployment.py +315 -0
- zenml/stack_deployments/stack_deployment.py +232 -0
- zenml/stack_deployments/utils.py +48 -0
- zenml/step_operators/step_operator_entrypoint_configuration.py +2 -1
- zenml/steps/__init__.py +3 -9
- zenml/steps/base_step.py +172 -315
- zenml/{new/steps → steps}/decorated_step.py +1 -0
- zenml/steps/entrypoint_function_utils.py +33 -93
- zenml/{new/steps → steps}/step_context.py +70 -50
- zenml/steps/step_decorator.py +47 -93
- zenml/steps/step_invocation.py +22 -60
- zenml/steps/utils.py +161 -48
- zenml/types.py +14 -1
- zenml/utils/archivable.py +178 -0
- zenml/utils/callback_registry.py +71 -0
- zenml/utils/code_repository_utils.py +1 -0
- zenml/utils/code_utils.py +346 -0
- zenml/utils/cuda_utils.py +50 -0
- zenml/utils/dashboard_utils.py +67 -21
- zenml/utils/deprecation_utils.py +22 -24
- zenml/utils/dict_utils.py +22 -0
- zenml/utils/docker_utils.py +34 -5
- zenml/utils/downloaded_repository_context.py +1 -0
- zenml/utils/env_utils.py +55 -1
- zenml/utils/filesync_model.py +65 -28
- zenml/utils/function_utils.py +260 -0
- zenml/utils/integration_utils.py +1 -0
- zenml/utils/json_utils.py +131 -0
- zenml/utils/materializer_utils.py +1 -1
- zenml/utils/metadata_utils.py +368 -0
- zenml/utils/notebook_utils.py +136 -0
- zenml/utils/package_utils.py +89 -0
- zenml/utils/pagination_utils.py +9 -7
- zenml/utils/pipeline_docker_image_builder.py +152 -149
- zenml/utils/pydantic_utils.py +276 -66
- zenml/utils/requirements_utils.py +71 -0
- zenml/utils/secret_utils.py +66 -12
- zenml/utils/settings_utils.py +2 -1
- zenml/utils/singleton.py +15 -3
- zenml/utils/source_code_utils.py +1 -0
- zenml/utils/source_utils.py +236 -14
- zenml/utils/string_utils.py +140 -0
- zenml/utils/typed_model.py +5 -3
- zenml/utils/typing_utils.py +223 -0
- zenml/utils/visualization_utils.py +5 -3
- zenml/utils/yaml_utils.py +1 -1
- zenml/zen_server/auth.py +387 -55
- zenml/zen_server/cache.py +208 -0
- zenml/zen_server/cloud_utils.py +253 -0
- zenml/zen_server/csrf.py +91 -0
- zenml/zen_server/dashboard/assets/404-Dfq64Boz.js +1 -0
- zenml/zen_server/dashboard/assets/@radix-DeK6qiuw.js +85 -0
- zenml/zen_server/dashboard/assets/@react-router-B3Z5rLr2.js +29 -0
- zenml/zen_server/dashboard/assets/@reactflow-BUNIMFeC.js +17 -0
- zenml/zen_server/dashboard/assets/@reactflow-C26Olbza.css +1 -0
- zenml/zen_server/dashboard/assets/@tanstack-DT5WLu9C.js +22 -0
- zenml/zen_server/dashboard/assets/AlertDialogDropdownItem-B73Vs10T.js +1 -0
- zenml/zen_server/dashboard/assets/CodeSnippet-Bbx6fIb6.css +1 -0
- zenml/zen_server/dashboard/assets/CodeSnippet-DIJRT2NT.js +9 -0
- zenml/zen_server/dashboard/assets/CollapsibleCard-BzUHGZOU.js +1 -0
- zenml/zen_server/dashboard/assets/Commands-BEGyld4c.js +1 -0
- zenml/zen_server/dashboard/assets/ComponentBadge-xyKiek1s.js +1 -0
- zenml/zen_server/dashboard/assets/CopyButton-DhW-mapu.js +2 -0
- zenml/zen_server/dashboard/assets/CsvVizualization-D8oazBiE.js +15 -0
- zenml/zen_server/dashboard/assets/DeleteAlertDialog-WkSIIgfy.js +1 -0
- zenml/zen_server/dashboard/assets/DialogItem-Bgroeg29.js +1 -0
- zenml/zen_server/dashboard/assets/DisplayDate-CDMUcQHS.js +1 -0
- zenml/zen_server/dashboard/assets/EmptyState-BzdlCwp3.js +1 -0
- zenml/zen_server/dashboard/assets/Error-CY5tlu17.js +1 -0
- zenml/zen_server/dashboard/assets/ExecutionStatus-G8mjIaeA.js +1 -0
- zenml/zen_server/dashboard/assets/Helpbox-Bb1ed--O.js +1 -0
- zenml/zen_server/dashboard/assets/Infobox-Da6-76M2.js +1 -0
- zenml/zen_server/dashboard/assets/InlineAvatar-DqnZaBNq.js +1 -0
- zenml/zen_server/dashboard/assets/Lock-CYYy18Mm.js +1 -0
- zenml/zen_server/dashboard/assets/MarkdownVisualization-ylXaAxev.js +14 -0
- zenml/zen_server/dashboard/assets/NestedCollapsible-aK5ojKoF.js +1 -0
- zenml/zen_server/dashboard/assets/NumberBox-Dtp3J6g5.js +1 -0
- zenml/zen_server/dashboard/assets/Partials-CqZp5NMX.js +1 -0
- zenml/zen_server/dashboard/assets/PasswordChecker-B0nadgh6.js +1 -0
- zenml/zen_server/dashboard/assets/ProBadge-B4tRUYve.js +1 -0
- zenml/zen_server/dashboard/assets/ProCta-CZuP29Qz.js +1 -0
- zenml/zen_server/dashboard/assets/ProviderIcon-Bd7GUQ1_.js +1 -0
- zenml/zen_server/dashboard/assets/ProviderRadio-mstdqzsS.js +1 -0
- zenml/zen_server/dashboard/assets/RunSelector-CsruSB4i.js +1 -0
- zenml/zen_server/dashboard/assets/RunsBody-DxxtWVYz.js +1 -0
- zenml/zen_server/dashboard/assets/SearchField-D6tPxyqw.js +1 -0
- zenml/zen_server/dashboard/assets/SecretTooltip-CLzJIYW_.js +1 -0
- zenml/zen_server/dashboard/assets/SetPassword-Yn50ooBC.js +1 -0
- zenml/zen_server/dashboard/assets/StackList-U537qoYd.js +1 -0
- zenml/zen_server/dashboard/assets/Tabs-CNv-eTYM.js +1 -0
- zenml/zen_server/dashboard/assets/Tick-jEIevzVf.js +1 -0
- zenml/zen_server/dashboard/assets/UpdatePasswordSchemas-C16GW-kX.js +1 -0
- zenml/zen_server/dashboard/assets/UsageReason-Bf2tzhv1.js +1 -0
- zenml/zen_server/dashboard/assets/WizardFooter-D6i-AP1K.js +1 -0
- zenml/zen_server/dashboard/assets/acp-DOsXjFc7.webp +0 -0
- zenml/zen_server/dashboard/assets/adam-e-y0WnB_.webp +0 -0
- zenml/zen_server/dashboard/assets/alex-DcCuDHPg.webp +0 -0
- zenml/zen_server/dashboard/assets/all-pipeline-runs-query-DUti43aF.js +1 -0
- zenml/zen_server/dashboard/assets/baris-C0ZrZ10g.webp +0 -0
- zenml/zen_server/dashboard/assets/check-DloQpStc.js +1 -0
- zenml/zen_server/dashboard/assets/check-circle-jNbX5-sR.js +1 -0
- zenml/zen_server/dashboard/assets/chevron-down-6JyMkfjR.js +1 -0
- zenml/zen_server/dashboard/assets/chevron-right-double-D7ojK9Co.js +1 -0
- zenml/zen_server/dashboard/assets/cloud-squares-DeRLMopf.svg +43 -0
- zenml/zen_server/dashboard/assets/code-browser-CUFUIHfp.js +1 -0
- zenml/zen_server/dashboard/assets/code-snippets-CqONne41.js +13 -0
- zenml/zen_server/dashboard/assets/components-Br2ezRib.js +1 -0
- zenml/zen_server/dashboard/assets/connectors-video-C9qY4syJ.svg +21 -0
- zenml/zen_server/dashboard/assets/copy-C8XQA2Ug.js +1 -0
- zenml/zen_server/dashboard/assets/create-stack-Ch2WPs9U.js +1 -0
- zenml/zen_server/dashboard/assets/dates-3pMLCNrD.js +1 -0
- zenml/zen_server/dashboard/assets/delete-run-Byf9hTjA.js +1 -0
- zenml/zen_server/dashboard/assets/docker-BdA9vrnW.js +1 -0
- zenml/zen_server/dashboard/assets/dots-horizontal-otGBOSDJ.js +1 -0
- zenml/zen_server/dashboard/assets/flyte-Cj-xy_8I.svg +10 -0
- zenml/zen_server/dashboard/assets/form-schemas-BZqKBPBF.js +1 -0
- zenml/zen_server/dashboard/assets/gcp-CFtm4BA7.js +1 -0
- zenml/zen_server/dashboard/assets/hamza-NKKOZz1I.webp +0 -0
- zenml/zen_server/dashboard/assets/help-Cc9bBIJH.js +1 -0
- zenml/zen_server/dashboard/assets/index-CE0aQlv8.js +55 -0
- zenml/zen_server/dashboard/assets/index-CtdYkjUi.js +1 -0
- zenml/zen_server/dashboard/assets/index-CyBKZcpO.js +1 -0
- zenml/zen_server/dashboard/assets/index-DXvT1_Um.css +1 -0
- zenml/zen_server/dashboard/assets/index-Uu49AX48.js +1 -0
- zenml/zen_server/dashboard/assets/index-v6gQjDEo.js +1 -0
- zenml/zen_server/dashboard/assets/index.esm-Dy6Z9Ung.js +1 -0
- zenml/zen_server/dashboard/assets/inter-cyrillic-400-normal-BLGc9T1a.woff2 +0 -0
- zenml/zen_server/dashboard/assets/inter-cyrillic-400-normal-ZzOtrSSW.woff +0 -0
- zenml/zen_server/dashboard/assets/inter-cyrillic-500-normal-D4Vwzodn.woff2 +0 -0
- zenml/zen_server/dashboard/assets/inter-cyrillic-500-normal-DH2hs3aW.woff +0 -0
- zenml/zen_server/dashboard/assets/inter-cyrillic-600-normal-BGBWG807.woff2 +0 -0
- zenml/zen_server/dashboard/assets/inter-cyrillic-600-normal-BuzJQFbW.woff +0 -0
- zenml/zen_server/dashboard/assets/inter-cyrillic-ext-400-normal-BPnxn4xp.woff +0 -0
- zenml/zen_server/dashboard/assets/inter-cyrillic-ext-400-normal-Dc4VJyIJ.woff2 +0 -0
- zenml/zen_server/dashboard/assets/inter-cyrillic-ext-500-normal-BShVwWPj.woff2 +0 -0
- zenml/zen_server/dashboard/assets/inter-cyrillic-ext-500-normal-CUiC4oBV.woff +0 -0
- zenml/zen_server/dashboard/assets/inter-cyrillic-ext-600-normal-Bt9VVOA-.woff +0 -0
- zenml/zen_server/dashboard/assets/inter-cyrillic-ext-600-normal-CaqZN2hq.woff2 +0 -0
- zenml/zen_server/dashboard/assets/inter-greek-400-normal-BZzXV7-1.woff +0 -0
- zenml/zen_server/dashboard/assets/inter-greek-400-normal-DxZsaF_h.woff2 +0 -0
- zenml/zen_server/dashboard/assets/inter-greek-500-normal-CeQXL5ds.woff2 +0 -0
- zenml/zen_server/dashboard/assets/inter-greek-500-normal-d_eO-yCQ.woff +0 -0
- zenml/zen_server/dashboard/assets/inter-greek-600-normal-CwicyhtI.woff +0 -0
- zenml/zen_server/dashboard/assets/inter-greek-600-normal-Dhlb-90d.woff2 +0 -0
- zenml/zen_server/dashboard/assets/inter-greek-ext-400-normal-Bput3-QP.woff2 +0 -0
- zenml/zen_server/dashboard/assets/inter-greek-ext-400-normal-DCpCPQOf.woff +0 -0
- zenml/zen_server/dashboard/assets/inter-greek-ext-500-normal-B6guLgqG.woff2 +0 -0
- zenml/zen_server/dashboard/assets/inter-greek-ext-500-normal-M2hEX8vc.woff +0 -0
- zenml/zen_server/dashboard/assets/inter-greek-ext-600-normal-C9WLioJ8.woff +0 -0
- zenml/zen_server/dashboard/assets/inter-greek-ext-600-normal-Cnui8OiR.woff2 +0 -0
- zenml/zen_server/dashboard/assets/inter-latin-400-normal-BOOGhInR.woff2 +0 -0
- zenml/zen_server/dashboard/assets/inter-latin-400-normal-gitzw0hO.woff +0 -0
- zenml/zen_server/dashboard/assets/inter-latin-500-normal-D2bGa7uu.woff2 +0 -0
- zenml/zen_server/dashboard/assets/inter-latin-500-normal-deR1Tlfd.woff +0 -0
- zenml/zen_server/dashboard/assets/inter-latin-600-normal-B5cFAncS.woff +0 -0
- zenml/zen_server/dashboard/assets/inter-latin-600-normal-D273HNI0.woff2 +0 -0
- zenml/zen_server/dashboard/assets/inter-latin-ext-400-normal-C1t-h-pH.woff +0 -0
- zenml/zen_server/dashboard/assets/inter-latin-ext-400-normal-hnt3BR84.woff2 +0 -0
- zenml/zen_server/dashboard/assets/inter-latin-ext-500-normal-CIS2RHJS.woff2 +0 -0
- zenml/zen_server/dashboard/assets/inter-latin-ext-500-normal-UMdmhHu2.woff +0 -0
- zenml/zen_server/dashboard/assets/inter-latin-ext-600-normal-BnYJhD27.woff2 +0 -0
- zenml/zen_server/dashboard/assets/inter-latin-ext-600-normal-CAF0vJDd.woff +0 -0
- zenml/zen_server/dashboard/assets/inter-vietnamese-400-normal-BUNmGMP1.woff +0 -0
- zenml/zen_server/dashboard/assets/inter-vietnamese-400-normal-DMkecbls.woff2 +0 -0
- zenml/zen_server/dashboard/assets/inter-vietnamese-500-normal-DOriooB6.woff2 +0 -0
- zenml/zen_server/dashboard/assets/inter-vietnamese-500-normal-DQPw2Hwd.woff +0 -0
- zenml/zen_server/dashboard/assets/inter-vietnamese-600-normal-Cc8MFFhd.woff2 +0 -0
- zenml/zen_server/dashboard/assets/inter-vietnamese-600-normal-Cm6aH8_k.woff +0 -0
- zenml/zen_server/dashboard/assets/key-icon-aH-QIa5R.js +1 -0
- zenml/zen_server/dashboard/assets/kubernetes-B2wmAJ1d.js +1 -0
- zenml/zen_server/dashboard/assets/layout-BtHBmE4w.js +1 -0
- zenml/zen_server/dashboard/assets/link-external-b9AXw_sW.js +1 -0
- zenml/zen_server/dashboard/assets/login-command-CkqxPtV3.js +1 -0
- zenml/zen_server/dashboard/assets/login-mutation-DNDVp_2H.js +1 -0
- zenml/zen_server/dashboard/assets/logs-WMSM52RF.js +1 -0
- zenml/zen_server/dashboard/assets/mcp-Cb1aMeoq.webp +0 -0
- zenml/zen_server/dashboard/assets/metaflow-weOkWNyT.svg +10 -0
- zenml/zen_server/dashboard/assets/not-found-Bmup4ctE.js +1 -0
- zenml/zen_server/dashboard/assets/package-C6uypY4h.js +1 -0
- zenml/zen_server/dashboard/assets/page--XLMzHrn.js +1 -0
- zenml/zen_server/dashboard/assets/page-ANYGfEUL.js +1 -0
- zenml/zen_server/dashboard/assets/page-B5Sr8pib.js +1 -0
- zenml/zen_server/dashboard/assets/page-BC27C_OI.js +2 -0
- zenml/zen_server/dashboard/assets/page-BNxYrN0q.js +1 -0
- zenml/zen_server/dashboard/assets/page-BYJfqgLN.js +1 -0
- zenml/zen_server/dashboard/assets/page-B_0XkV48.js +1 -0
- zenml/zen_server/dashboard/assets/page-BrmJp1Wt.js +1 -0
- zenml/zen_server/dashboard/assets/page-C2nU3Gxn.js +1 -0
- zenml/zen_server/dashboard/assets/page-C70wZtV2.js +1 -0
- zenml/zen_server/dashboard/assets/page-CHRn1fQm.js +1 -0
- zenml/zen_server/dashboard/assets/page-CWr96ZKN.js +1 -0
- zenml/zen_server/dashboard/assets/page-CXAbSyp9.js +1 -0
- zenml/zen_server/dashboard/assets/page-CaeI9ptC.js +1 -0
- zenml/zen_server/dashboard/assets/page-Cc8ZEuj4.js +1 -0
- zenml/zen_server/dashboard/assets/page-CltCNL0T.js +1 -0
- zenml/zen_server/dashboard/assets/page-CmlYj7Nl.js +1 -0
- zenml/zen_server/dashboard/assets/page-D6Ev5P8V.js +1 -0
- zenml/zen_server/dashboard/assets/page-D9Oh05fl.js +1 -0
- zenml/zen_server/dashboard/assets/page-DGlm1RVc.js +1 -0
- zenml/zen_server/dashboard/assets/page-DN4BVIOL.js +1 -0
- zenml/zen_server/dashboard/assets/page-Dif8CWyZ.js +1 -0
- zenml/zen_server/dashboard/assets/page-DlIi5ThM.js +1 -0
- zenml/zen_server/dashboard/assets/page-DoW7YxTu.js +1 -0
- zenml/zen_server/dashboard/assets/page-Dth9X1Ih.js +1 -0
- zenml/zen_server/dashboard/assets/page-DweqqCkF.js +1 -0
- zenml/zen_server/dashboard/assets/page-DyOJ_pq3.js +1 -0
- zenml/zen_server/dashboard/assets/page-Hn8q9iJZ.js +1 -0
- zenml/zen_server/dashboard/assets/page-IhckKFnD.js +6 -0
- zenml/zen_server/dashboard/assets/page-LyZ_l8vR.js +1 -0
- zenml/zen_server/dashboard/assets/page-PamGpk0j.js +1 -0
- zenml/zen_server/dashboard/assets/page-PxOWfKgF.js +2 -0
- zenml/zen_server/dashboard/assets/persist-DeXRG61d.js +1 -0
- zenml/zen_server/dashboard/assets/persist-vP0-Xl4f.js +1 -0
- zenml/zen_server/dashboard/assets/plus-tf1V2hTJ.js +1 -0
- zenml/zen_server/dashboard/assets/refresh-BjOeWlEq.js +1 -0
- zenml/zen_server/dashboard/assets/repos-video-D8kpu60k.svg +9 -0
- zenml/zen_server/dashboard/assets/rocket-DjT2cDvG.js +1 -0
- zenml/zen_server/dashboard/assets/service-DH_oUqQj.js +2 -0
- zenml/zen_server/dashboard/assets/settings_preview-0JLrRgHP.webp +0 -0
- zenml/zen_server/dashboard/assets/sharedSchema-Bw1_Wa7l.js +14 -0
- zenml/zen_server/dashboard/assets/stack-detail-query-B_0R_fd6.js +1 -0
- zenml/zen_server/dashboard/assets/stefan-B08Ftbba.webp +0 -0
- zenml/zen_server/dashboard/assets/templates-1S_8WeSK.webp +0 -0
- zenml/zen_server/dashboard/assets/tick-circle-BEX_Tp4v.js +1 -0
- zenml/zen_server/dashboard/assets/tour-cover-BYfeen6M.webp +0 -0
- zenml/zen_server/dashboard/assets/trash-arLUMWMS.js +1 -0
- zenml/zen_server/dashboard/assets/update-server-settings-mutation-D9qYhfaN.js +1 -0
- zenml/zen_server/dashboard/assets/upgrade-form-CwRHBuXB.webp +0 -0
- zenml/zen_server/dashboard/assets/url-Dh93fvh0.js +1 -0
- zenml/zen_server/dashboard/assets/zod-BwEbpOxH.js +1 -0
- zenml/zen_server/dashboard/index.html +19 -1
- zenml/zen_server/deploy/__init__.py +7 -16
- zenml/zen_server/deploy/base_provider.py +49 -78
- zenml/zen_server/deploy/{local → daemon}/__init__.py +3 -3
- zenml/zen_server/deploy/{local/local_provider.py → daemon/daemon_provider.py} +48 -66
- zenml/zen_server/deploy/{local/local_zen_server.py → daemon/daemon_zen_server.py} +78 -62
- zenml/zen_server/deploy/deployer.py +94 -175
- zenml/zen_server/deploy/deployment.py +23 -17
- zenml/zen_server/deploy/docker/docker_provider.py +15 -31
- zenml/zen_server/deploy/docker/docker_zen_server.py +30 -35
- zenml/zen_server/deploy/helm/Chart.yaml +1 -1
- zenml/zen_server/deploy/helm/README.md +3 -13
- zenml/zen_server/deploy/helm/templates/NOTES.txt +23 -7
- zenml/zen_server/deploy/helm/templates/_environment.tpl +175 -23
- zenml/zen_server/deploy/helm/templates/server-db-job.yaml +45 -18
- zenml/zen_server/deploy/helm/templates/server-db-pvc.yaml +25 -0
- zenml/zen_server/deploy/helm/templates/server-deployment.yaml +22 -6
- zenml/zen_server/deploy/helm/templates/server-secret.yaml +11 -10
- zenml/zen_server/deploy/helm/values.yaml +210 -28
- zenml/zen_server/exceptions.py +20 -1
- zenml/zen_server/feature_gate/__init__.py +13 -0
- zenml/zen_server/feature_gate/endpoint_utils.py +61 -0
- zenml/zen_server/feature_gate/feature_gate_interface.py +49 -0
- zenml/zen_server/feature_gate/zenml_cloud_feature_gate.py +125 -0
- zenml/zen_server/jwt.py +64 -32
- zenml/zen_server/rate_limit.py +200 -0
- zenml/zen_server/rbac/endpoint_utils.py +92 -9
- zenml/zen_server/rbac/models.py +21 -17
- zenml/zen_server/rbac/rbac_sql_zen_store.py +175 -0
- zenml/zen_server/rbac/utils.py +71 -30
- zenml/zen_server/rbac/zenml_cloud_rbac.py +13 -188
- zenml/zen_server/routers/actions_endpoints.py +324 -0
- zenml/zen_server/routers/artifact_version_endpoints.py +28 -2
- zenml/zen_server/routers/auth_endpoints.py +249 -131
- zenml/zen_server/routers/code_repositories_endpoints.py +1 -0
- zenml/zen_server/routers/devices_endpoints.py +56 -49
- zenml/zen_server/routers/event_source_endpoints.py +327 -0
- zenml/zen_server/routers/logs_endpoints.py +66 -0
- zenml/zen_server/routers/model_versions_endpoints.py +59 -0
- zenml/zen_server/routers/models_endpoints.py +7 -1
- zenml/zen_server/routers/pipeline_builds_endpoints.py +6 -1
- zenml/zen_server/routers/pipeline_deployments_endpoints.py +35 -0
- zenml/zen_server/routers/pipelines_endpoints.py +19 -32
- zenml/zen_server/routers/plugin_endpoints.py +107 -0
- zenml/zen_server/routers/run_templates_endpoints.py +212 -0
- zenml/zen_server/routers/runs_endpoints.py +91 -32
- zenml/zen_server/routers/schedule_endpoints.py +1 -0
- zenml/zen_server/routers/secrets_endpoints.py +4 -2
- zenml/zen_server/routers/server_endpoints.py +186 -4
- zenml/zen_server/routers/service_connectors_endpoints.py +56 -0
- zenml/zen_server/routers/service_endpoints.py +180 -0
- zenml/zen_server/routers/stack_components_endpoints.py +2 -1
- zenml/zen_server/routers/stack_deployment_endpoints.py +164 -0
- zenml/zen_server/routers/steps_endpoints.py +21 -12
- zenml/zen_server/routers/triggers_endpoints.py +336 -0
- zenml/zen_server/routers/users_endpoints.py +280 -45
- zenml/zen_server/routers/webhook_endpoints.py +127 -0
- zenml/zen_server/routers/workspaces_endpoints.py +220 -185
- zenml/zen_server/secure_headers.py +120 -0
- zenml/{new → zen_server/template_execution}/__init__.py +1 -1
- zenml/zen_server/template_execution/runner_entrypoint_configuration.py +42 -0
- zenml/zen_server/template_execution/utils.py +474 -0
- zenml/zen_server/template_execution/workload_manager_interface.py +92 -0
- zenml/zen_server/utils.py +374 -74
- zenml/zen_server/zen_server_api.py +299 -52
- zenml/zen_stores/base_zen_store.py +90 -58
- zenml/zen_stores/migrations/alembic.py +22 -9
- zenml/zen_stores/migrations/env.py +2 -2
- zenml/zen_stores/migrations/utils.py +731 -0
- zenml/zen_stores/migrations/versions/0.21.0_release.py +0 -1
- zenml/zen_stores/migrations/versions/0.21.1_release.py +0 -1
- zenml/zen_stores/migrations/versions/0.22.0_release.py +0 -1
- zenml/zen_stores/migrations/versions/0.23.0_release.py +0 -1
- zenml/zen_stores/migrations/versions/0.30.0_release.py +0 -1
- zenml/zen_stores/migrations/versions/0.31.0_release.py +0 -1
- zenml/zen_stores/migrations/versions/0.31.1_release.py +0 -1
- zenml/zen_stores/migrations/versions/0.32.0_release.py +0 -1
- zenml/zen_stores/migrations/versions/0.32.1_release.py +0 -1
- zenml/zen_stores/migrations/versions/0.33.0_release.py +0 -1
- zenml/zen_stores/migrations/versions/0.34.0_release.py +0 -1
- zenml/zen_stores/migrations/versions/0.35.0_release.py +0 -1
- zenml/zen_stores/migrations/versions/0.35.1_release.py +0 -1
- zenml/zen_stores/migrations/versions/0.36.0_release.py +0 -1
- zenml/zen_stores/migrations/versions/0.36.1_release.py +0 -1
- zenml/zen_stores/migrations/versions/0.37.0_release.py +0 -1
- zenml/zen_stores/migrations/versions/0.38.0_release.py +0 -1
- zenml/zen_stores/migrations/versions/0.39.0_release.py +0 -1
- zenml/zen_stores/migrations/versions/0.39.1_release.py +0 -1
- zenml/zen_stores/migrations/versions/0.40.0_release.py +0 -1
- zenml/zen_stores/migrations/versions/0.40.1_release.py +0 -1
- zenml/zen_stores/migrations/versions/0.40.2_release.py +0 -1
- zenml/zen_stores/migrations/versions/0.40.3_release.py +0 -1
- zenml/zen_stores/migrations/versions/0.41.0_release.py +0 -1
- zenml/zen_stores/migrations/versions/0.42.0_release.py +0 -1
- zenml/zen_stores/migrations/versions/0.42.1_release.py +0 -1
- zenml/zen_stores/migrations/versions/0.43.0_release.py +0 -1
- zenml/zen_stores/migrations/versions/0.44.0_release.py +0 -1
- zenml/zen_stores/migrations/versions/0.44.1_release.py +0 -1
- zenml/zen_stores/migrations/versions/0.44.2_release.py +0 -1
- zenml/zen_stores/migrations/versions/0.44.3_release.py +0 -1
- zenml/zen_stores/migrations/versions/0.45.0_release.py +0 -1
- zenml/zen_stores/migrations/versions/0.45.1_release_0_45_1.py +0 -1
- zenml/zen_stores/migrations/versions/0.45.2_release.py +0 -1
- zenml/zen_stores/migrations/versions/0.45.3_release.py +0 -1
- zenml/zen_stores/migrations/versions/0.45.4_release.py +0 -1
- zenml/zen_stores/migrations/versions/0.45.5_release.py +0 -1
- zenml/zen_stores/migrations/versions/0.45.6_release.py +0 -1
- zenml/zen_stores/migrations/versions/0.46.0_release.py +0 -1
- zenml/zen_stores/migrations/versions/0.46.1_release.py +0 -1
- zenml/zen_stores/migrations/versions/0.47.0_release.py +0 -1
- zenml/zen_stores/migrations/versions/0.50.0_release.py +0 -1
- zenml/zen_stores/migrations/versions/0.51.0_release.py +0 -1
- zenml/zen_stores/migrations/versions/0.52.0_release.py +0 -1
- zenml/zen_stores/migrations/versions/0.53.0_release.py +0 -1
- zenml/zen_stores/migrations/versions/0.53.1_release.py +0 -1
- zenml/zen_stores/migrations/versions/0.54.0_release.py +0 -1
- zenml/zen_stores/migrations/versions/0.54.1_release.py +0 -1
- zenml/zen_stores/migrations/versions/0.55.0_release.py +0 -1
- zenml/zen_stores/migrations/versions/0.55.1_release.py +23 -0
- zenml/zen_stores/migrations/versions/0.55.2_release.py +23 -0
- zenml/zen_stores/migrations/versions/0.55.3_release.py +23 -0
- zenml/zen_stores/migrations/versions/0.55.4_release.py +23 -0
- zenml/zen_stores/migrations/versions/0.55.5_release.py +23 -0
- zenml/zen_stores/migrations/versions/0.56.0_release.py +23 -0
- zenml/zen_stores/migrations/versions/0.56.1_release.py +23 -0
- zenml/zen_stores/migrations/versions/0.56.2_release.py +23 -0
- zenml/zen_stores/migrations/versions/0.56.3_release.py +23 -0
- zenml/zen_stores/migrations/versions/0.56.4_release.py +23 -0
- zenml/zen_stores/migrations/versions/0.57.0.rc1_release.py +23 -0
- zenml/zen_stores/migrations/versions/0.57.0.rc2_release.py +23 -0
- zenml/zen_stores/migrations/versions/0.57.0_release.py +23 -0
- zenml/zen_stores/migrations/versions/0.57.1_release.py +23 -0
- zenml/zen_stores/migrations/versions/0.58.0_release.py +23 -0
- zenml/zen_stores/migrations/versions/0.58.1_release.py +23 -0
- zenml/zen_stores/migrations/versions/0.58.2_release.py +23 -0
- zenml/zen_stores/migrations/versions/0.60.0_release.py +23 -0
- zenml/zen_stores/migrations/versions/0.61.0_release.py +23 -0
- zenml/zen_stores/migrations/versions/0.62.0_release.py +23 -0
- zenml/zen_stores/migrations/versions/0.63.0_release.py +23 -0
- zenml/zen_stores/migrations/versions/0.64.0_release.py +23 -0
- zenml/zen_stores/migrations/versions/0.65.0_release.py +23 -0
- zenml/zen_stores/migrations/versions/0.66.0_release.py +23 -0
- zenml/zen_stores/migrations/versions/0.67.0_release.py +23 -0
- zenml/zen_stores/migrations/versions/0.68.0_release.py +23 -0
- zenml/zen_stores/migrations/versions/0.68.1_release.py +23 -0
- zenml/zen_stores/migrations/versions/0.70.0_release.py +23 -0
- zenml/zen_stores/migrations/versions/0.71.0_release.py +23 -0
- zenml/zen_stores/migrations/versions/0.72.0_release.py +23 -0
- zenml/zen_stores/migrations/versions/026d4577b6a0_add_code_path.py +39 -0
- zenml/zen_stores/migrations/versions/03742aa7fdd7_add_secrets.py +1 -0
- zenml/zen_stores/migrations/versions/0701da9951a0_added_service_table.py +94 -0
- zenml/zen_stores/migrations/versions/0b06faa59c93_add_service_connectors.py +1 -0
- zenml/zen_stores/migrations/versions/0d707865f404_adding_labels_to_stacks.py +30 -0
- zenml/zen_stores/migrations/versions/0e4735b23577_increase_pipeline_spec_field_length.py +1 -0
- zenml/zen_stores/migrations/versions/1041bc644e0d_remove_secrets_manager.py +6 -3
- zenml/zen_stores/migrations/versions/10a907dad202_delete_mlmd_tables.py +2 -1
- zenml/zen_stores/migrations/versions/14d687c8fa1c_rename_model_config_to_model_version.py +1 -0
- zenml/zen_stores/migrations/versions/19f27d5b234e_add_build_and_deployment_tables.py +1 -0
- zenml/zen_stores/migrations/versions/1a9a9d2a836d_admin_users.py +56 -0
- zenml/zen_stores/migrations/versions/1ac1b9c04da1_make_secrets_values_optional.py +1 -0
- zenml/zen_stores/migrations/versions/1cb6477f72d6_move_artifact_save_type.py +99 -0
- zenml/zen_stores/migrations/versions/1d74e596abb8_add_run_once_start_time_to_schedule.py +36 -0
- zenml/zen_stores/migrations/versions/1d8f30c54477_migrate_to_new_.py +124 -0
- zenml/zen_stores/migrations/versions/248dfd320b68_update_size_of_flavor_config_schema.py +1 -0
- zenml/zen_stores/migrations/versions/25155145c545_separate_actions_and_triggers.py +228 -0
- zenml/zen_stores/migrations/versions/26351d482b9e_add_step_run_unique_constraint.py +37 -0
- zenml/zen_stores/migrations/versions/26b776ad583e_redesign_artifacts.py +9 -10
- zenml/zen_stores/migrations/versions/2d201872e23c_remove_db_dependency_loop.py +29 -0
- zenml/zen_stores/migrations/versions/37835ce041d2_optimizing_database.py +4 -3
- zenml/zen_stores/migrations/versions/389046140cad_data_versioning.py +1 -0
- zenml/zen_stores/migrations/versions/3944116bbd56_rename_project_to_workspace.py +1 -0
- zenml/zen_stores/migrations/versions/3b68abe58f44_add_model_watchtower_entities.py +1 -0
- zenml/zen_stores/migrations/versions/3c5a367730c2_add_environment_info_to_runs.py +1 -0
- zenml/zen_stores/migrations/versions/3dcc5d20e82f_add_last_user_activity.py +51 -0
- zenml/zen_stores/migrations/versions/43a86093b60e_add_labels_for_stack_components.py +1 -0
- zenml/zen_stores/migrations/versions/46506f72f0ed_add_server_settings.py +123 -0
- zenml/zen_stores/migrations/versions/479103df60b6_add_triggers.py +162 -0
- zenml/zen_stores/migrations/versions/4a3087070f4e_add_step_source_code.py +1 -0
- zenml/zen_stores/migrations/versions/4c41c0ca42db_add_code_repository_table.py +1 -0
- zenml/zen_stores/migrations/versions/4d688d8f7aff_rename_model_version_to_model.py +1 -0
- zenml/zen_stores/migrations/versions/4e1972485075_endpoint_artifact_deployment_artifact.py +1 -0
- zenml/zen_stores/migrations/versions/4f66af55fbb9_rename_model_config_model_to_model_.py +1 -0
- zenml/zen_stores/migrations/versions/5330ba58bf20_rename_tables_and_foreign_keys.py +8 -9
- zenml/zen_stores/migrations/versions/5994f9ad0489_introduce_role_permissions.py +4 -2
- zenml/zen_stores/migrations/versions/5cc3f41cf048_add_save_models_to_registry.py +1 -0
- zenml/zen_stores/migrations/versions/6119cd9b93c2_tags_table.py +1 -0
- zenml/zen_stores/migrations/versions/623a234c11f5_add_sdk_docs_url_to_flavors.py +1 -0
- zenml/zen_stores/migrations/versions/6917bce75069_add_pipeline_run_unique_constraint.py +5 -4
- zenml/zen_stores/migrations/versions/6a28c4fd0ef2_add_caching_info.py +1 -0
- zenml/zen_stores/migrations/versions/6f707b385dc1_fix_model_artifacts.py +1 -0
- zenml/zen_stores/migrations/versions/722392c91006_make_is_service_account_mandatory.py +1 -0
- zenml/zen_stores/migrations/versions/72675226b2de_unique_users.py +31 -0
- zenml/zen_stores/migrations/versions/72722dee4686_track_server_version.py +1 -0
- zenml/zen_stores/migrations/versions/7280c14811d6_use_text_type.py +1 -0
- zenml/zen_stores/migrations/versions/728c6369cfaa_add_name_column_to_input_artifact_pk.py +4 -2
- zenml/zen_stores/migrations/versions/729263e47b55_fix_external_input_artifacts.py +1 -0
- zenml/zen_stores/migrations/versions/743ec82b1b3c_update_size_of_build_images.py +3 -2
- zenml/zen_stores/migrations/versions/7500f434b71c_remove_shared_columns.py +4 -2
- zenml/zen_stores/migrations/versions/76a7b9451ccd_add_build_template_deployment_id.py +52 -0
- zenml/zen_stores/migrations/versions/7834208cc3f6_artifact_project_scoping.py +9 -7
- zenml/zen_stores/migrations/versions/7b651bf6822e_track_secrets_in_db.py +7 -7
- zenml/zen_stores/migrations/versions/7d1919bb1ef0_add_run_templates.py +100 -0
- zenml/zen_stores/migrations/versions/7e4a481d17f7_add_identity_table.py +3 -2
- zenml/zen_stores/migrations/versions/7f603e583dd7_fixed_migration.py +2 -1
- zenml/zen_stores/migrations/versions/86fa52918b54_remove_teams_and_roles.py +1 -0
- zenml/zen_stores/migrations/versions/8a64fbfecda0_add_num_outputs_to_run_step.py +1 -0
- zenml/zen_stores/migrations/versions/8ed03137cacc_polymorthic_run_metadata.py +1 -0
- zenml/zen_stores/migrations/versions/904464ea4041_add_pipeline_model_run_unique_constraints.py +192 -0
- zenml/zen_stores/migrations/versions/909550c7c4da_remove_user_hub_token.py +36 -0
- zenml/zen_stores/migrations/versions/93cbda80a732_add_service_accounts.py +1 -0
- zenml/zen_stores/migrations/versions/979eff8fc4b1_add_code_repo_description_and_logo_url.py +1 -0
- zenml/zen_stores/migrations/versions/9971237fa937_artifact_visualizations.py +1 -0
- zenml/zen_stores/migrations/versions/9d8020441014_increase_step_configuration_length.py +1 -0
- zenml/zen_stores/migrations/versions/a1237ba94fd8_add_model_version_producer_run_unique_.py +68 -0
- zenml/zen_stores/migrations/versions/a39c4184c8ce_remove_secrets_manager_flavors.py +3 -2
- zenml/zen_stores/migrations/versions/a91762e6be36_artifact_version_table.py +5 -4
- zenml/zen_stores/migrations/versions/ade72effebaf_added_logs_table.py +1 -0
- zenml/zen_stores/migrations/versions/alembic_start.py +2 -1
- zenml/zen_stores/migrations/versions/b4eccf34dfa3_add_hub_token_to_user_model.py +1 -0
- zenml/zen_stores/migrations/versions/b4fca5241eea_migrate_onboarding_state.py +167 -0
- zenml/zen_stores/migrations/versions/b557b2871693_update_step_run_input_types.py +33 -0
- zenml/zen_stores/migrations/versions/b59aa68fdb1f_simplify_pipelines.py +139 -0
- zenml/zen_stores/migrations/versions/b73bc71f1106_remove_component_spec_path.py +36 -0
- zenml/zen_stores/migrations/versions/bf2120261b5a_add_configured_model_version_id.py +74 -0
- zenml/zen_stores/migrations/versions/c1b18cec3a48_increase_length_on_flavor_config_schema.py +1 -0
- zenml/zen_stores/migrations/versions/c22561cbb3a9_add_artifact_unique_constraints.py +86 -0
- zenml/zen_stores/migrations/versions/cc269488e5a9_separate_run_metadata.py +135 -0
- zenml/zen_stores/migrations/versions/cc9894cb58aa_add_user_metadata.py +41 -0
- zenml/zen_stores/migrations/versions/ccd68b7825ae_add_status_to_pipeline_and_step_run.py +1 -0
- zenml/zen_stores/migrations/versions/d02b3d3464cf_add_orchestrator_run_id_column.py +1 -0
- zenml/zen_stores/migrations/versions/d26471b6fe8f_update_build_filtering.py +1 -0
- zenml/zen_stores/migrations/versions/d7b3acf9aa46_create_schedule_table.py +1 -0
- zenml/zen_stores/migrations/versions/e1d66d91a099_add_stack_and_component_spec_paths_to_.py +1 -0
- zenml/zen_stores/migrations/versions/e5225281b4d3_add_connector_skew_tolerance.py +1 -0
- zenml/zen_stores/migrations/versions/e65aa6708ff7_pipeline_versioning.py +1 -0
- zenml/zen_stores/migrations/versions/ec0d785ca296_create_run_metadata_table.py +1 -0
- zenml/zen_stores/migrations/versions/ec6307720f92_simplify_model_version_links.py +119 -0
- zenml/zen_stores/migrations/versions/f3b3964e3a0f_add_oauth_devices.py +1 -0
- zenml/zen_stores/migrations/versions/f49904a80aa7_increase_length_of_artifact_table_sources.py +1 -0
- zenml/zen_stores/migrations/versions/fbd7f18ced1e_increase_step_run_field_lengths.py +5 -4
- zenml/zen_stores/rest_zen_store.py +1326 -305
- zenml/zen_stores/schemas/__init__.py +22 -3
- zenml/zen_stores/schemas/action_schemas.py +192 -0
- zenml/zen_stores/schemas/api_key_schemas.py +23 -10
- zenml/zen_stores/schemas/artifact_schemas.py +112 -49
- zenml/zen_stores/schemas/artifact_visualization_schemas.py +17 -8
- zenml/zen_stores/schemas/base_schemas.py +27 -0
- zenml/zen_stores/schemas/code_repository_schemas.py +25 -10
- zenml/zen_stores/schemas/component_schemas.py +74 -11
- zenml/zen_stores/schemas/constants.py +16 -0
- zenml/zen_stores/schemas/device_schemas.py +29 -15
- zenml/zen_stores/schemas/event_source_schemas.py +188 -0
- zenml/zen_stores/schemas/flavor_schemas.py +19 -9
- zenml/zen_stores/schemas/logs_schemas.py +12 -6
- zenml/zen_stores/schemas/model_schemas.py +192 -139
- zenml/zen_stores/schemas/pipeline_build_schemas.py +16 -16
- zenml/zen_stores/schemas/pipeline_deployment_schemas.py +58 -17
- zenml/zen_stores/schemas/pipeline_run_schemas.py +170 -35
- zenml/zen_stores/schemas/pipeline_schemas.py +51 -33
- zenml/zen_stores/schemas/run_metadata_schemas.py +28 -78
- zenml/zen_stores/schemas/run_template_schemas.py +267 -0
- zenml/zen_stores/schemas/schedule_schema.py +15 -5
- zenml/zen_stores/schemas/secret_schemas.py +18 -10
- zenml/zen_stores/schemas/server_settings_schemas.py +129 -0
- zenml/zen_stores/schemas/service_connector_schemas.py +13 -6
- zenml/zen_stores/schemas/service_schemas.py +258 -0
- zenml/zen_stores/schemas/stack_schemas.py +23 -6
- zenml/zen_stores/schemas/step_run_schemas.py +132 -41
- zenml/zen_stores/schemas/tag_schemas.py +31 -50
- zenml/zen_stores/schemas/trigger_schemas.py +316 -0
- zenml/zen_stores/schemas/user_schemas.py +66 -23
- zenml/zen_stores/schemas/utils.py +112 -0
- zenml/zen_stores/schemas/workspace_schemas.py +36 -19
- zenml/zen_stores/secrets_stores/aws_secrets_store.py +41 -32
- zenml/zen_stores/secrets_stores/azure_secrets_store.py +20 -23
- zenml/zen_stores/secrets_stores/base_secrets_store.py +80 -12
- zenml/zen_stores/secrets_stores/gcp_secrets_store.py +42 -33
- zenml/zen_stores/secrets_stores/hashicorp_secrets_store.py +7 -11
- zenml/zen_stores/secrets_stores/secrets_store_interface.py +1 -0
- zenml/zen_stores/secrets_stores/service_connector_secrets_store.py +15 -8
- zenml/zen_stores/secrets_stores/sql_secrets_store.py +8 -9
- zenml/zen_stores/sql_zen_store.py +4062 -799
- zenml/zen_stores/template_utils.py +263 -0
- zenml/zen_stores/zen_store_interface.py +614 -44
- zenml_nightly-0.72.0.dev20250116.dist-info/METADATA +486 -0
- zenml_nightly-0.72.0.dev20250116.dist-info/RECORD +1294 -0
- {zenml_nightly-0.55.0.dev20240124.dist-info → zenml_nightly-0.72.0.dev20250116.dist-info}/WHEEL +1 -1
- CLA.md +0 -110
- CODE-OF-CONDUCT.md +0 -132
- CONTRIBUTING.md +0 -260
- README.md +0 -304
- RELEASE_NOTES.md +0 -3919
- ROADMAP.md +0 -5
- SECURITY.md +0 -15
- zenml/_hub/client.py +0 -285
- zenml/_hub/constants.py +0 -21
- zenml/_hub/utils.py +0 -80
- zenml/api.py +0 -61
- zenml/cli/hub.py +0 -1115
- zenml/cli/stack_recipes.py +0 -469
- zenml/integrations/gcp/google_cloud_function.py +0 -187
- zenml/integrations/gcp/google_cloud_scheduler.py +0 -83
- zenml/integrations/gcp/orchestrators/vertex_scheduler/main.py +0 -91
- zenml/integrations/gcp/orchestrators/vertex_scheduler/requirements.txt +0 -2
- zenml/integrations/kserve/__init__.py +0 -57
- zenml/integrations/kserve/custom_deployer/zenml_custom_model.py +0 -175
- zenml/integrations/kserve/flavors/kserve_model_deployer_flavor.py +0 -137
- zenml/integrations/kserve/model_deployers/kserve_model_deployer.py +0 -1003
- zenml/integrations/kserve/secret_schemas/secret_schemas.py +0 -65
- zenml/integrations/kserve/services/kserve_deployment.py +0 -596
- zenml/integrations/kserve/steps/__init__.py +0 -22
- zenml/integrations/kserve/steps/kserve_deployer.py +0 -472
- zenml/integrations/kserve/steps/kserve_step_utils.py +0 -293
- zenml/integrations/kubeflow/utils.py +0 -96
- zenml/lineage_graph/lineage_graph.py +0 -244
- zenml/lineage_graph/node/artifact_node.py +0 -52
- zenml/lineage_graph/node/step_node.py +0 -41
- zenml/models/v2/base/internal.py +0 -37
- zenml/models/v2/base/update.py +0 -40
- zenml/models/v2/misc/hub_plugin_models.py +0 -79
- zenml/new/pipelines/deserialization_utils.py +0 -291
- zenml/new/pipelines/model_utils.py +0 -72
- zenml/new/pipelines/pipeline_decorator.py +0 -109
- zenml/new/steps/step_decorator.py +0 -160
- zenml/pipelines/base_pipeline.py +0 -274
- zenml/post_execution/pipeline.py +0 -58
- zenml/post_execution/pipeline_run.py +0 -55
- zenml/services/service_registry.py +0 -214
- zenml/services/terraform/__init__.py +0 -14
- zenml/services/terraform/terraform_service.py +0 -441
- zenml/steps/step_environment.py +0 -108
- zenml/steps/step_output.py +0 -36
- zenml/utils/mlstacks_utils.py +0 -635
- zenml/utils/terraform_utils.py +0 -42
- zenml/zen_server/dashboard/_redirects +0 -1
- zenml/zen_server/dashboard/asset-manifest.json +0 -131
- zenml/zen_server/dashboard/manifest.json +0 -25
- zenml/zen_server/dashboard/precache-manifest.c139638dcc4d9d3425353266447a2fad.js +0 -462
- zenml/zen_server/dashboard/robots.txt +0 -2
- zenml/zen_server/dashboard/service-worker.js +0 -39
- zenml/zen_server/dashboard/static/css/2.5b37d44a.chunk.css +0 -16
- zenml/zen_server/dashboard/static/css/2.5b37d44a.chunk.css.map +0 -1
- zenml/zen_server/dashboard/static/css/main.77e46c35.chunk.css +0 -2
- zenml/zen_server/dashboard/static/css/main.77e46c35.chunk.css.map +0 -1
- zenml/zen_server/dashboard/static/js/2.bb4cef22.chunk.js +0 -3
- zenml/zen_server/dashboard/static/js/2.bb4cef22.chunk.js.LICENSE.txt +0 -95
- zenml/zen_server/dashboard/static/js/2.bb4cef22.chunk.js.map +0 -1
- zenml/zen_server/dashboard/static/js/main.270838b4.chunk.js +0 -2
- zenml/zen_server/dashboard/static/js/main.270838b4.chunk.js.map +0 -1
- zenml/zen_server/dashboard/static/js/runtime-main.bfca2edd.js +0 -2
- zenml/zen_server/dashboard/static/js/runtime-main.bfca2edd.js.map +0 -1
- zenml/zen_server/dashboard/static/media/AlertTriangle.28aee535.svg +0 -5
- zenml/zen_server/dashboard/static/media/ArrowSquareOut.abfb9bc7.svg +0 -5
- zenml/zen_server/dashboard/static/media/Back.86c23a22.svg +0 -4
- zenml/zen_server/dashboard/static/media/BookOpen.5cb101ff.svg +0 -4
- zenml/zen_server/dashboard/static/media/BoundingBox.1eb98717.svg +0 -10
- zenml/zen_server/dashboard/static/media/Burger.9b1c67d7.svg +0 -3
- zenml/zen_server/dashboard/static/media/Cached.2381fb8d.svg +0 -1
- zenml/zen_server/dashboard/static/media/Calendar.356e11c7.svg +0 -3
- zenml/zen_server/dashboard/static/media/ChartBarHorizontal.0247447b.svg +0 -6
- zenml/zen_server/dashboard/static/media/ChartLine.0d79e18d.svg +0 -4
- zenml/zen_server/dashboard/static/media/ChatDots.2e1c9211.svg +0 -6
- zenml/zen_server/dashboard/static/media/Check.dad6beb2.svg +0 -3
- zenml/zen_server/dashboard/static/media/CheckCircleFilled.c19566d0.svg +0 -3
- zenml/zen_server/dashboard/static/media/Checkbox.af50e31e.svg +0 -3
- zenml/zen_server/dashboard/static/media/ChevronDown.f860ce32.svg +0 -3
- zenml/zen_server/dashboard/static/media/ChevronDownLight.6642d756.svg +0 -3
- zenml/zen_server/dashboard/static/media/ChevronLeft.f6edfcdb.svg +0 -3
- zenml/zen_server/dashboard/static/media/CircleCheck.f98fd6ca.svg +0 -1
- zenml/zen_server/dashboard/static/media/Clock.ffc9de95.svg +0 -3
- zenml/zen_server/dashboard/static/media/Close.74e9efbc.svg +0 -5
- zenml/zen_server/dashboard/static/media/CloseWithBorder.6960930a.svg +0 -3
- zenml/zen_server/dashboard/static/media/CloseWithoutBorder.cd6f71df.svg +0 -3
- zenml/zen_server/dashboard/static/media/CloudArrowUp.0aecb235.svg +0 -6
- zenml/zen_server/dashboard/static/media/Code.ef0f33b5.svg +0 -3
- zenml/zen_server/dashboard/static/media/Config.0be63f8a.svg +0 -1
- zenml/zen_server/dashboard/static/media/Connector.9fd46ef1.svg +0 -10
- zenml/zen_server/dashboard/static/media/Copy.36e2112a.svg +0 -1
- zenml/zen_server/dashboard/static/media/Dashboard.d05787e0.svg +0 -3
- zenml/zen_server/dashboard/static/media/Data.b1c3b5f8.svg +0 -3
- zenml/zen_server/dashboard/static/media/Delete.3c361b28.svg +0 -8
- zenml/zen_server/dashboard/static/media/Docs.7541d478.svg +0 -7
- zenml/zen_server/dashboard/static/media/Download.fba04d87.svg +0 -5
- zenml/zen_server/dashboard/static/media/Edit.490eb294.svg +0 -6
- zenml/zen_server/dashboard/static/media/EmptyRightArrow.23749d01.svg +0 -3
- zenml/zen_server/dashboard/static/media/Example.6396cd37.svg +0 -5
- zenml/zen_server/dashboard/static/media/Extension.1394cd4a.svg +0 -3
- zenml/zen_server/dashboard/static/media/Eye.d9e4ee62.svg +0 -4
- zenml/zen_server/dashboard/static/media/Failed.0213c1a0.svg +0 -1
- zenml/zen_server/dashboard/static/media/FileText.1f15bacd.svg +0 -7
- zenml/zen_server/dashboard/static/media/Filter.ab6b9c0d.svg +0 -3
- zenml/zen_server/dashboard/static/media/Folders.12b29887.svg +0 -5
- zenml/zen_server/dashboard/static/media/FunnelFill.6df4c143.svg +0 -3
- zenml/zen_server/dashboard/static/media/GitCommit.7dd9c2aa.svg +0 -5
- zenml/zen_server/dashboard/static/media/GitHub_Logo.cefc2023.png +0 -0
- zenml/zen_server/dashboard/static/media/Graph.2c63a892.svg +0 -11
- zenml/zen_server/dashboard/static/media/History.08329240.svg +0 -3
- zenml/zen_server/dashboard/static/media/Home.0843b0d5.svg +0 -3
- zenml/zen_server/dashboard/static/media/ImageBuilder.ea762d9c.svg +0 -6
- zenml/zen_server/dashboard/static/media/InProgress.304a0edc.svg +0 -1
- zenml/zen_server/dashboard/static/media/Info.9fe10c5c.svg +0 -3
- zenml/zen_server/dashboard/static/media/KeyboardReturn.491afbe3.svg +0 -3
- zenml/zen_server/dashboard/static/media/Link.72bbb55d.svg +0 -4
- zenml/zen_server/dashboard/static/media/Lock.30f5e1fe.svg +0 -5
- zenml/zen_server/dashboard/static/media/Lock2.a769ea52.svg +0 -3
- zenml/zen_server/dashboard/static/media/LockKey.92f21621.svg +0 -6
- zenml/zen_server/dashboard/static/media/Logs.8bf4d005.svg +0 -5
- zenml/zen_server/dashboard/static/media/MinusCircle.4188f418.svg +0 -4
- zenml/zen_server/dashboard/static/media/ModelRegistry.f0de050a.svg +0 -6
- zenml/zen_server/dashboard/static/media/MultiUser.a2ba7c67.svg +0 -10
- zenml/zen_server/dashboard/static/media/PaginationFirst.92628634.svg +0 -4
- zenml/zen_server/dashboard/static/media/PaginationLast.00d3c732.svg +0 -4
- zenml/zen_server/dashboard/static/media/PaginationNext.86158845.svg +0 -3
- zenml/zen_server/dashboard/static/media/PaginationPrev.60c18a88.svg +0 -3
- zenml/zen_server/dashboard/static/media/Pen.f2d831d4.svg +0 -6
- zenml/zen_server/dashboard/static/media/PhotoCamera.179d6d4c.svg +0 -3
- zenml/zen_server/dashboard/static/media/Pipeline.30d298b0.svg +0 -7
- zenml/zen_server/dashboard/static/media/Plus.5aa1c16b.svg +0 -3
- zenml/zen_server/dashboard/static/media/PlusCircle.92d860dd.svg +0 -5
- zenml/zen_server/dashboard/static/media/Repositories.71a36b8c.svg +0 -3
- zenml/zen_server/dashboard/static/media/RightArrow.f30d3871.svg +0 -29
- zenml/zen_server/dashboard/static/media/Rocket.63bf7b9d.svg +0 -3
- zenml/zen_server/dashboard/static/media/RocketLaunch.1bff2b59.svg +0 -6
- zenml/zen_server/dashboard/static/media/Rubik-Medium.c87313aa.ttf +0 -0
- zenml/zen_server/dashboard/static/media/Rubik-Regular.b3d0902b.ttf +0 -0
- zenml/zen_server/dashboard/static/media/Run.daec4fb2.svg +0 -6
- zenml/zen_server/dashboard/static/media/Search.d1afcce5.svg +0 -4
- zenml/zen_server/dashboard/static/media/Settings.59ca73ae.svg +0 -4
- zenml/zen_server/dashboard/static/media/Share2.46c3ff66.svg +0 -3
- zenml/zen_server/dashboard/static/media/SignOut.6aa718c5.svg +0 -3
- zenml/zen_server/dashboard/static/media/SimplePlus.5cf7ec20.svg +0 -3
- zenml/zen_server/dashboard/static/media/SingleUser.bef3a095.svg +0 -4
- zenml/zen_server/dashboard/static/media/SourceCodePro-Regular.b484b32f.ttf +0 -0
- zenml/zen_server/dashboard/static/media/Stack.19b604ac.svg +0 -5
- zenml/zen_server/dashboard/static/media/StackComponent.b1ba90b5.svg +0 -4
- zenml/zen_server/dashboard/static/media/Star.f0c25022.svg +0 -9
- zenml/zen_server/dashboard/static/media/StarOutline.94ca8cd9.svg +0 -3
- zenml/zen_server/dashboard/static/media/Storefront.4b4796fe.svg +0 -3
- zenml/zen_server/dashboard/static/media/Stream.543e3039.svg +0 -3
- zenml/zen_server/dashboard/static/media/SupportAgent.510ddf1f.svg +0 -8
- zenml/zen_server/dashboard/static/media/Table.77033750.svg +0 -6
- zenml/zen_server/dashboard/static/media/Tool.d5785486.svg +0 -3
- zenml/zen_server/dashboard/static/media/UserPlus.741a99d7.svg +0 -6
- zenml/zen_server/dashboard/static/media/Verified.0625b2a0.svg +0 -3
- zenml/zen_server/dashboard/static/media/addNew.4fb6c939.svg +0 -8
- zenml/zen_server/dashboard/static/media/arrowClose.cbd53f3f.svg +0 -3
- zenml/zen_server/dashboard/static/media/arrowOpen.6ceef0af.svg +0 -3
- zenml/zen_server/dashboard/static/media/check_small.30bc0138.svg +0 -3
- zenml/zen_server/dashboard/static/media/circleArrowSideClose.98d6013e.svg +0 -18
- zenml/zen_server/dashboard/static/media/circleArrowSideOpen.63653df6.svg +0 -18
- zenml/zen_server/dashboard/static/media/image.104fd14b.png +0 -0
- zenml/zen_server/dashboard/static/media/imageAddIcon.e83004a9.svg +0 -7
- zenml/zen_server/dashboard/static/media/logo.93333e5c.svg +0 -1
- zenml/zen_server/dashboard/static/media/logo_small.4204397d.svg +0 -3
- zenml/zen_server/dashboard/static/media/logo_white.d4b4414e.svg +0 -20
- zenml/zen_server/dashboard/static/media/notConnected.5e2c8ea7.svg +0 -8
- zenml/zen_server/dashboard/static/media/plugin-fallback.72c294e6.svg +0 -6
- zenml/zen_server/dashboard/static/media/share.bcd998b0.svg +0 -5
- zenml/zen_server/dashboard/static/media/stars.08a9b19a.svg +0 -8
- zenml/zen_server/deploy/terraform/__init__.py +0 -41
- zenml/zen_server/deploy/terraform/providers/__init__.py +0 -14
- zenml/zen_server/deploy/terraform/providers/aws_provider.py +0 -61
- zenml/zen_server/deploy/terraform/providers/azure_provider.py +0 -59
- zenml/zen_server/deploy/terraform/providers/gcp_provider.py +0 -59
- zenml/zen_server/deploy/terraform/providers/terraform_provider.py +0 -332
- zenml/zen_server/deploy/terraform/recipes/aws/.gitignore +0 -8
- zenml/zen_server/deploy/terraform/recipes/aws/helm.tf +0 -20
- zenml/zen_server/deploy/terraform/recipes/aws/ingress.tf +0 -30
- zenml/zen_server/deploy/terraform/recipes/aws/outputs.tf +0 -14
- zenml/zen_server/deploy/terraform/recipes/aws/printf.cmd +0 -2
- zenml/zen_server/deploy/terraform/recipes/aws/sql.tf +0 -62
- zenml/zen_server/deploy/terraform/recipes/aws/terraform.tf +0 -44
- zenml/zen_server/deploy/terraform/recipes/aws/variables.tf +0 -179
- zenml/zen_server/deploy/terraform/recipes/aws/vpc.tf +0 -47
- zenml/zen_server/deploy/terraform/recipes/aws/zen_server.tf +0 -111
- zenml/zen_server/deploy/terraform/recipes/azure/.gitignore +0 -8
- zenml/zen_server/deploy/terraform/recipes/azure/helm.tf +0 -20
- zenml/zen_server/deploy/terraform/recipes/azure/ingress.tf +0 -30
- zenml/zen_server/deploy/terraform/recipes/azure/key_vault.tf +0 -73
- zenml/zen_server/deploy/terraform/recipes/azure/outputs.tf +0 -14
- zenml/zen_server/deploy/terraform/recipes/azure/printf.cmd +0 -2
- zenml/zen_server/deploy/terraform/recipes/azure/rg.tf +0 -36
- zenml/zen_server/deploy/terraform/recipes/azure/sql.tf +0 -65
- zenml/zen_server/deploy/terraform/recipes/azure/terraform.tf +0 -52
- zenml/zen_server/deploy/terraform/recipes/azure/variables.tf +0 -188
- zenml/zen_server/deploy/terraform/recipes/azure/zen_server.tf +0 -111
- zenml/zen_server/deploy/terraform/recipes/gcp/.gitignore +0 -8
- zenml/zen_server/deploy/terraform/recipes/gcp/helm.tf +0 -20
- zenml/zen_server/deploy/terraform/recipes/gcp/ingress.tf +0 -30
- zenml/zen_server/deploy/terraform/recipes/gcp/outputs.tf +0 -14
- zenml/zen_server/deploy/terraform/recipes/gcp/printf.cmd +0 -2
- zenml/zen_server/deploy/terraform/recipes/gcp/sql.tf +0 -64
- zenml/zen_server/deploy/terraform/recipes/gcp/terraform.tf +0 -44
- zenml/zen_server/deploy/terraform/recipes/gcp/variables.tf +0 -183
- zenml/zen_server/deploy/terraform/recipes/gcp/zen_server.tf +0 -122
- zenml/zen_server/deploy/terraform/terraform_zen_server.py +0 -255
- zenml/zen_server/routers/run_metadata_endpoints.py +0 -97
- zenml_nightly-0.55.0.dev20240124.dist-info/METADATA +0 -438
- zenml_nightly-0.55.0.dev20240124.dist-info/RECORD +0 -1072
- {zenml_nightly-0.55.0.dev20240124.dist-info → zenml_nightly-0.72.0.dev20250116.dist-info}/LICENSE +0 -0
- {zenml_nightly-0.55.0.dev20240124.dist-info → zenml_nightly-0.72.0.dev20250116.dist-info}/entry_points.txt +0 -0
@@ -19,6 +19,8 @@ services:
|
|
19
19
|
- Explicit GCP service account key
|
20
20
|
|
21
21
|
"""
|
22
|
+
|
23
|
+
import base64
|
22
24
|
import datetime
|
23
25
|
import json
|
24
26
|
import os
|
@@ -32,14 +34,21 @@ import google.api_core.exceptions
|
|
32
34
|
import google.auth
|
33
35
|
import google.auth.exceptions
|
34
36
|
import requests
|
37
|
+
from google.auth import aws as gcp_aws
|
38
|
+
from google.auth import external_account as gcp_external_account
|
35
39
|
from google.auth import (
|
36
40
|
impersonated_credentials as gcp_impersonated_credentials,
|
37
41
|
)
|
42
|
+
from google.auth._default import (
|
43
|
+
_AWS_SUBJECT_TOKEN_TYPE,
|
44
|
+
_get_external_account_credentials,
|
45
|
+
)
|
38
46
|
from google.auth.transport.requests import Request
|
39
|
-
from google.cloud import container_v1, storage
|
47
|
+
from google.cloud import artifactregistry_v1, container_v1, storage
|
48
|
+
from google.cloud.location import locations_pb2
|
40
49
|
from google.oauth2 import credentials as gcp_credentials
|
41
50
|
from google.oauth2 import service_account as gcp_service_account
|
42
|
-
from pydantic import Field,
|
51
|
+
from pydantic import Field, field_validator, model_validator
|
43
52
|
|
44
53
|
from zenml.constants import (
|
45
54
|
DOCKER_REGISTRY_RESOURCE_TYPE,
|
@@ -67,18 +76,21 @@ from zenml.service_connectors.service_connector import (
|
|
67
76
|
ServiceConnector,
|
68
77
|
)
|
69
78
|
from zenml.utils.enum_utils import StrEnum
|
79
|
+
from zenml.utils.pydantic_utils import before_validator_handler
|
80
|
+
from zenml.utils.secret_utils import PlainSerializedSecretStr
|
70
81
|
|
71
82
|
logger = get_logger(__name__)
|
72
83
|
|
73
84
|
GKE_KUBE_API_TOKEN_EXPIRATION = 60
|
74
85
|
DEFAULT_IMPERSONATE_TOKEN_EXPIRATION = 3600 # 1 hour
|
86
|
+
GCP_SESSION_EXPIRATION_BUFFER = 15 # 15 minutes
|
75
87
|
|
76
88
|
|
77
89
|
class GCPUserAccountCredentials(AuthenticationConfig):
|
78
90
|
"""GCP user account credentials."""
|
79
91
|
|
80
|
-
user_account_json:
|
81
|
-
title="GCP User Account Credentials JSON",
|
92
|
+
user_account_json: PlainSerializedSecretStr = Field(
|
93
|
+
title="GCP User Account Credentials JSON optionally base64 encoded.",
|
82
94
|
)
|
83
95
|
|
84
96
|
generate_temporary_tokens: bool = Field(
|
@@ -89,30 +101,48 @@ class GCPUserAccountCredentials(AuthenticationConfig):
|
|
89
101
|
"distribute the user account credentials JSON to clients instead.",
|
90
102
|
)
|
91
103
|
|
92
|
-
@
|
104
|
+
@model_validator(mode="before")
|
105
|
+
@classmethod
|
106
|
+
@before_validator_handler
|
93
107
|
def validate_user_account_dict(
|
94
|
-
cls,
|
108
|
+
cls, data: Dict[str, Any]
|
95
109
|
) -> Dict[str, Any]:
|
96
110
|
"""Convert the user account credentials to JSON if given in dict format.
|
97
111
|
|
98
112
|
Args:
|
99
|
-
|
113
|
+
data: The configuration values.
|
100
114
|
|
101
115
|
Returns:
|
102
116
|
The validated configuration values.
|
117
|
+
|
118
|
+
Raises:
|
119
|
+
ValueError: If the user account credentials JSON is invalid.
|
103
120
|
"""
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
121
|
+
user_account_json = data.get("user_account_json")
|
122
|
+
if isinstance(user_account_json, dict):
|
123
|
+
data["user_account_json"] = json.dumps(data["user_account_json"])
|
124
|
+
elif isinstance(user_account_json, str):
|
125
|
+
# Check if the user account JSON is base64 encoded and decode it
|
126
|
+
if re.match(r"^[A-Za-z0-9+/=]+$", user_account_json):
|
127
|
+
try:
|
128
|
+
data["user_account_json"] = base64.b64decode(
|
129
|
+
user_account_json
|
130
|
+
).decode("utf-8")
|
131
|
+
except Exception as e:
|
132
|
+
raise ValueError(
|
133
|
+
f"Failed to decode base64 encoded user account JSON: {e}"
|
134
|
+
)
|
135
|
+
return data
|
109
136
|
|
110
|
-
@
|
111
|
-
|
137
|
+
@field_validator("user_account_json")
|
138
|
+
@classmethod
|
139
|
+
def validate_user_account_json(
|
140
|
+
cls, value: PlainSerializedSecretStr
|
141
|
+
) -> PlainSerializedSecretStr:
|
112
142
|
"""Validate the user account credentials JSON.
|
113
143
|
|
114
144
|
Args:
|
115
|
-
|
145
|
+
value: The user account credentials JSON.
|
116
146
|
|
117
147
|
Returns:
|
118
148
|
The validated user account credentials JSON.
|
@@ -121,7 +151,7 @@ class GCPUserAccountCredentials(AuthenticationConfig):
|
|
121
151
|
ValueError: If the user account credentials JSON is invalid.
|
122
152
|
"""
|
123
153
|
try:
|
124
|
-
user_account_info = json.loads(
|
154
|
+
user_account_info = json.loads(value.get_secret_value())
|
125
155
|
except json.JSONDecodeError as e:
|
126
156
|
raise ValueError(
|
127
157
|
f"GCP user account credentials is not a valid JSON: {e}"
|
@@ -139,7 +169,7 @@ class GCPUserAccountCredentials(AuthenticationConfig):
|
|
139
169
|
if missing_fields:
|
140
170
|
raise ValueError(
|
141
171
|
f"GCP user account credentials JSON is missing required "
|
142
|
-
f
|
172
|
+
f"fields: {', '.join(list(missing_fields))}"
|
143
173
|
)
|
144
174
|
|
145
175
|
if user_account_info["type"] != "authorized_user":
|
@@ -149,14 +179,14 @@ class GCPUserAccountCredentials(AuthenticationConfig):
|
|
149
179
|
"instead of 'authorized_user'."
|
150
180
|
)
|
151
181
|
|
152
|
-
return
|
182
|
+
return value
|
153
183
|
|
154
184
|
|
155
185
|
class GCPServiceAccountCredentials(AuthenticationConfig):
|
156
186
|
"""GCP service account credentials."""
|
157
187
|
|
158
|
-
service_account_json:
|
159
|
-
title="GCP Service Account Key JSON",
|
188
|
+
service_account_json: PlainSerializedSecretStr = Field(
|
189
|
+
title="GCP Service Account Key JSON optionally base64 encoded.",
|
160
190
|
)
|
161
191
|
|
162
192
|
generate_temporary_tokens: bool = Field(
|
@@ -167,30 +197,51 @@ class GCPServiceAccountCredentials(AuthenticationConfig):
|
|
167
197
|
"distribute the service account key JSON to clients instead.",
|
168
198
|
)
|
169
199
|
|
170
|
-
@
|
200
|
+
@model_validator(mode="before")
|
201
|
+
@classmethod
|
202
|
+
@before_validator_handler
|
171
203
|
def validate_service_account_dict(
|
172
|
-
cls,
|
204
|
+
cls, data: Dict[str, Any]
|
173
205
|
) -> Dict[str, Any]:
|
174
206
|
"""Convert the service account credentials to JSON if given in dict format.
|
175
207
|
|
176
208
|
Args:
|
177
|
-
|
209
|
+
data: The configuration values.
|
178
210
|
|
179
211
|
Returns:
|
180
212
|
The validated configuration values.
|
213
|
+
|
214
|
+
Raises:
|
215
|
+
ValueError: If the service account credentials JSON is invalid.
|
181
216
|
"""
|
182
|
-
|
183
|
-
|
184
|
-
|
217
|
+
service_account_json = data.get("service_account_json")
|
218
|
+
if isinstance(service_account_json, dict):
|
219
|
+
data["service_account_json"] = json.dumps(
|
220
|
+
data["service_account_json"]
|
185
221
|
)
|
186
|
-
|
222
|
+
elif isinstance(service_account_json, str):
|
223
|
+
# Check if the service account JSON is base64 encoded and decode it
|
224
|
+
if re.match(r"^[A-Za-z0-9+/=]+$", service_account_json):
|
225
|
+
try:
|
226
|
+
data["service_account_json"] = base64.b64decode(
|
227
|
+
service_account_json
|
228
|
+
).decode("utf-8")
|
229
|
+
except Exception as e:
|
230
|
+
raise ValueError(
|
231
|
+
f"Failed to decode base64 encoded service account JSON: {e}"
|
232
|
+
)
|
187
233
|
|
188
|
-
|
189
|
-
|
234
|
+
return data
|
235
|
+
|
236
|
+
@field_validator("service_account_json")
|
237
|
+
@classmethod
|
238
|
+
def validate_service_account_json(
|
239
|
+
cls, value: PlainSerializedSecretStr
|
240
|
+
) -> PlainSerializedSecretStr:
|
190
241
|
"""Validate the service account credentials JSON.
|
191
242
|
|
192
243
|
Args:
|
193
|
-
|
244
|
+
value: The service account credentials JSON.
|
194
245
|
|
195
246
|
Returns:
|
196
247
|
The validated service account credentials JSON.
|
@@ -199,7 +250,7 @@ class GCPServiceAccountCredentials(AuthenticationConfig):
|
|
199
250
|
ValueError: If the service account credentials JSON is invalid.
|
200
251
|
"""
|
201
252
|
try:
|
202
|
-
service_account_info = json.loads(
|
253
|
+
service_account_info = json.loads(value.get_secret_value())
|
203
254
|
except json.JSONDecodeError as e:
|
204
255
|
raise ValueError(
|
205
256
|
f"GCP service account credentials is not a valid JSON: {e}"
|
@@ -225,7 +276,7 @@ class GCPServiceAccountCredentials(AuthenticationConfig):
|
|
225
276
|
if missing_fields:
|
226
277
|
raise ValueError(
|
227
278
|
f"GCP service account credentials JSON is missing required "
|
228
|
-
f
|
279
|
+
f"fields: {', '.join(list(missing_fields))}"
|
229
280
|
)
|
230
281
|
|
231
282
|
if service_account_info["type"] != "service_account":
|
@@ -235,13 +286,113 @@ class GCPServiceAccountCredentials(AuthenticationConfig):
|
|
235
286
|
"instead of 'service_account'."
|
236
287
|
)
|
237
288
|
|
238
|
-
return
|
289
|
+
return value
|
290
|
+
|
291
|
+
|
292
|
+
class GCPExternalAccountCredentials(AuthenticationConfig):
|
293
|
+
"""GCP external account credentials."""
|
294
|
+
|
295
|
+
external_account_json: PlainSerializedSecretStr = Field(
|
296
|
+
title="GCP External Account JSON optionally base64 encoded.",
|
297
|
+
)
|
298
|
+
|
299
|
+
generate_temporary_tokens: bool = Field(
|
300
|
+
default=True,
|
301
|
+
title="Generate temporary OAuth 2.0 tokens",
|
302
|
+
description="Whether to generate temporary OAuth 2.0 tokens from the "
|
303
|
+
"external account key JSON. If set to False, the connector will "
|
304
|
+
"distribute the external account JSON to clients instead.",
|
305
|
+
)
|
306
|
+
|
307
|
+
@model_validator(mode="before")
|
308
|
+
@classmethod
|
309
|
+
@before_validator_handler
|
310
|
+
def validate_service_account_dict(
|
311
|
+
cls, data: Dict[str, Any]
|
312
|
+
) -> Dict[str, Any]:
|
313
|
+
"""Convert the external account credentials to JSON if given in dict format.
|
314
|
+
|
315
|
+
Args:
|
316
|
+
data: The configuration values.
|
317
|
+
|
318
|
+
Returns:
|
319
|
+
The validated configuration values.
|
320
|
+
|
321
|
+
Raises:
|
322
|
+
ValueError: If the external account credentials JSON is invalid.
|
323
|
+
"""
|
324
|
+
external_account_json = data.get("external_account_json")
|
325
|
+
if isinstance(external_account_json, dict):
|
326
|
+
data["external_account_json"] = json.dumps(
|
327
|
+
data["external_account_json"]
|
328
|
+
)
|
329
|
+
elif isinstance(external_account_json, str):
|
330
|
+
# Check if the external account JSON is base64 encoded and decode it
|
331
|
+
if re.match(r"^[A-Za-z0-9+/=]+$", external_account_json):
|
332
|
+
try:
|
333
|
+
data["external_account_json"] = base64.b64decode(
|
334
|
+
external_account_json
|
335
|
+
).decode("utf-8")
|
336
|
+
except Exception as e:
|
337
|
+
raise ValueError(
|
338
|
+
f"Failed to decode base64 encoded external account JSON: {e}"
|
339
|
+
)
|
340
|
+
|
341
|
+
return data
|
342
|
+
|
343
|
+
@field_validator("external_account_json")
|
344
|
+
@classmethod
|
345
|
+
def validate_external_account_json(
|
346
|
+
cls, value: PlainSerializedSecretStr
|
347
|
+
) -> PlainSerializedSecretStr:
|
348
|
+
"""Validate the external account credentials JSON.
|
349
|
+
|
350
|
+
Args:
|
351
|
+
value: The external account credentials JSON.
|
352
|
+
|
353
|
+
Returns:
|
354
|
+
The validated external account credentials JSON.
|
355
|
+
|
356
|
+
Raises:
|
357
|
+
ValueError: If the external account credentials JSON is invalid.
|
358
|
+
"""
|
359
|
+
try:
|
360
|
+
external_account_info = json.loads(value.get_secret_value())
|
361
|
+
except json.JSONDecodeError as e:
|
362
|
+
raise ValueError(
|
363
|
+
f"GCP external account credentials is not a valid JSON: {e}"
|
364
|
+
)
|
365
|
+
|
366
|
+
# Check that all fields are present
|
367
|
+
required_fields = [
|
368
|
+
"type",
|
369
|
+
"subject_token_type",
|
370
|
+
"token_url",
|
371
|
+
]
|
372
|
+
# Compute missing fields
|
373
|
+
missing_fields = set(required_fields) - set(
|
374
|
+
external_account_info.keys()
|
375
|
+
)
|
376
|
+
if missing_fields:
|
377
|
+
raise ValueError(
|
378
|
+
f"GCP external account credentials JSON is missing required "
|
379
|
+
f"fields: {', '.join(list(missing_fields))}"
|
380
|
+
)
|
381
|
+
|
382
|
+
if external_account_info["type"] != "external_account":
|
383
|
+
raise ValueError(
|
384
|
+
"The JSON does not contain GCP external account credentials. "
|
385
|
+
f'The "type" field is set to {external_account_info["type"]} '
|
386
|
+
"instead of 'external_account'."
|
387
|
+
)
|
388
|
+
|
389
|
+
return value
|
239
390
|
|
240
391
|
|
241
392
|
class GCPOAuth2Token(AuthenticationConfig):
|
242
393
|
"""GCP OAuth 2.0 token credentials."""
|
243
394
|
|
244
|
-
token:
|
395
|
+
token: PlainSerializedSecretStr = Field(
|
245
396
|
title="GCP OAuth 2.0 Token",
|
246
397
|
)
|
247
398
|
|
@@ -249,20 +400,72 @@ class GCPOAuth2Token(AuthenticationConfig):
|
|
249
400
|
class GCPBaseConfig(AuthenticationConfig):
|
250
401
|
"""GCP base configuration."""
|
251
402
|
|
403
|
+
@property
|
404
|
+
def gcp_project_id(self) -> str:
|
405
|
+
"""Get the GCP project ID.
|
406
|
+
|
407
|
+
This method must be implemented by subclasses to ensure that the GCP
|
408
|
+
project ID is always available.
|
409
|
+
|
410
|
+
Raises:
|
411
|
+
NotImplementedError: If the method is not implemented.
|
412
|
+
"""
|
413
|
+
raise NotImplementedError
|
414
|
+
|
415
|
+
|
416
|
+
class GCPBaseProjectIDConfig(GCPBaseConfig):
|
417
|
+
"""GCP base configuration with included project ID."""
|
418
|
+
|
252
419
|
project_id: str = Field(
|
253
420
|
title="GCP Project ID where the target resource is located.",
|
254
421
|
)
|
255
422
|
|
423
|
+
@property
|
424
|
+
def gcp_project_id(self) -> str:
|
425
|
+
"""Get the GCP project ID.
|
256
426
|
|
257
|
-
|
427
|
+
Returns:
|
428
|
+
The GCP project ID.
|
429
|
+
"""
|
430
|
+
return self.project_id
|
431
|
+
|
432
|
+
|
433
|
+
class GCPUserAccountConfig(GCPBaseProjectIDConfig, GCPUserAccountCredentials):
|
258
434
|
"""GCP user account configuration."""
|
259
435
|
|
260
436
|
|
261
437
|
class GCPServiceAccountConfig(GCPBaseConfig, GCPServiceAccountCredentials):
|
262
438
|
"""GCP service account configuration."""
|
263
439
|
|
440
|
+
_project_id: Optional[str] = None
|
264
441
|
|
265
|
-
|
442
|
+
@property
|
443
|
+
def gcp_project_id(self) -> str:
|
444
|
+
"""Get the GCP project ID.
|
445
|
+
|
446
|
+
When a service account JSON is provided, the project ID can be extracted
|
447
|
+
from it instead of being provided explicitly.
|
448
|
+
|
449
|
+
Returns:
|
450
|
+
The GCP project ID.
|
451
|
+
"""
|
452
|
+
if self._project_id is None:
|
453
|
+
self._project_id = json.loads(
|
454
|
+
self.service_account_json.get_secret_value()
|
455
|
+
)["project_id"]
|
456
|
+
# Guaranteed by the field validator
|
457
|
+
assert self._project_id is not None
|
458
|
+
|
459
|
+
return self._project_id
|
460
|
+
|
461
|
+
|
462
|
+
class GCPExternalAccountConfig(
|
463
|
+
GCPBaseProjectIDConfig, GCPExternalAccountCredentials
|
464
|
+
):
|
465
|
+
"""GCP external account configuration."""
|
466
|
+
|
467
|
+
|
468
|
+
class GCPOAuth2TokenConfig(GCPBaseProjectIDConfig, GCPOAuth2Token):
|
266
469
|
"""GCP OAuth 2.0 configuration."""
|
267
470
|
|
268
471
|
service_account_email: Optional[str] = Field(
|
@@ -288,10 +491,177 @@ class GCPAuthenticationMethods(StrEnum):
|
|
288
491
|
IMPLICIT = "implicit"
|
289
492
|
USER_ACCOUNT = "user-account"
|
290
493
|
SERVICE_ACCOUNT = "service-account"
|
494
|
+
EXTERNAL_ACCOUNT = "external-account"
|
291
495
|
OAUTH2_TOKEN = "oauth2-token"
|
292
496
|
IMPERSONATION = "impersonation"
|
293
497
|
|
294
498
|
|
499
|
+
try:
|
500
|
+
from google.auth.aws import _DefaultAwsSecurityCredentialsSupplier
|
501
|
+
|
502
|
+
class ZenMLAwsSecurityCredentialsSupplier(
|
503
|
+
_DefaultAwsSecurityCredentialsSupplier # type: ignore[misc]
|
504
|
+
):
|
505
|
+
"""An improved version of the GCP external account credential supplier for AWS.
|
506
|
+
|
507
|
+
The original GCP external account credential supplier only provides
|
508
|
+
rudimentary support for extracting AWS credentials from environment
|
509
|
+
variables or the AWS metadata service. This version improves on that by
|
510
|
+
using the boto3 library itself (if available), which uses the entire range
|
511
|
+
of implicit authentication features packed into it.
|
512
|
+
|
513
|
+
Without this improvement, `sts.AssumeRoleWithWebIdentity` authentication is
|
514
|
+
not supported for EKS pods and the EC2 attached role credentials are
|
515
|
+
used instead (see: https://medium.com/@derek10cloud/gcp-workload-identity-federation-doesnt-yet-support-eks-irsa-in-aws-a3c71877671a).
|
516
|
+
"""
|
517
|
+
|
518
|
+
def get_aws_security_credentials(
|
519
|
+
self, context: Any, request: Any
|
520
|
+
) -> gcp_aws.AwsSecurityCredentials:
|
521
|
+
"""Get the security credentials from the local environment.
|
522
|
+
|
523
|
+
This method is a copy of the original method from the
|
524
|
+
`google.auth.aws._DefaultAwsSecurityCredentialsSupplier` class. It has
|
525
|
+
been modified to use the boto3 library to extract the AWS credentials
|
526
|
+
from the local environment.
|
527
|
+
|
528
|
+
Args:
|
529
|
+
context: The context to use to get the security credentials.
|
530
|
+
request: The request to use to get the security credentials.
|
531
|
+
|
532
|
+
Returns:
|
533
|
+
The AWS temporary security credentials.
|
534
|
+
"""
|
535
|
+
try:
|
536
|
+
import boto3
|
537
|
+
|
538
|
+
session = boto3.Session()
|
539
|
+
credentials = session.get_credentials()
|
540
|
+
if credentials is not None:
|
541
|
+
creds = credentials.get_frozen_credentials()
|
542
|
+
return gcp_aws.AwsSecurityCredentials(
|
543
|
+
creds.access_key,
|
544
|
+
creds.secret_key,
|
545
|
+
creds.token,
|
546
|
+
)
|
547
|
+
except ImportError:
|
548
|
+
pass
|
549
|
+
|
550
|
+
logger.debug(
|
551
|
+
"Failed to extract AWS credentials from the local environment "
|
552
|
+
"using the boto3 library. Falling back to the original "
|
553
|
+
"implementation."
|
554
|
+
)
|
555
|
+
|
556
|
+
return super().get_aws_security_credentials(context, request)
|
557
|
+
|
558
|
+
def get_aws_region(self, context: Any, request: Any) -> str:
|
559
|
+
"""Get the AWS region from the local environment.
|
560
|
+
|
561
|
+
This method is a copy of the original method from the
|
562
|
+
`google.auth.aws._DefaultAwsSecurityCredentialsSupplier` class. It has
|
563
|
+
been modified to use the boto3 library to extract the AWS
|
564
|
+
region from the local environment.
|
565
|
+
|
566
|
+
Args:
|
567
|
+
context: The context to use to get the security credentials.
|
568
|
+
request: The request to use to get the security credentials.
|
569
|
+
|
570
|
+
Returns:
|
571
|
+
The AWS region.
|
572
|
+
"""
|
573
|
+
try:
|
574
|
+
import boto3
|
575
|
+
|
576
|
+
session = boto3.Session()
|
577
|
+
if session.region_name:
|
578
|
+
return session.region_name # type: ignore[no-any-return]
|
579
|
+
except ImportError:
|
580
|
+
pass
|
581
|
+
|
582
|
+
logger.debug(
|
583
|
+
"Failed to extract AWS region from the local environment "
|
584
|
+
"using the boto3 library. Falling back to the original "
|
585
|
+
"implementation."
|
586
|
+
)
|
587
|
+
|
588
|
+
return super().get_aws_region( # type: ignore[no-any-return]
|
589
|
+
context, request
|
590
|
+
)
|
591
|
+
|
592
|
+
except ImportError:
|
593
|
+
# The `google.auth.aws._DefaultAwsSecurityCredentialsSupplier`
|
594
|
+
# class has been introduced in the `google-auth` library version 2.29.0.
|
595
|
+
# Before that, the AWS logic was part of the `google.auth.awsCredentials`
|
596
|
+
# class itself.
|
597
|
+
ZenMLAwsSecurityCredentialsSupplier = None # type: ignore[assignment,misc]
|
598
|
+
pass
|
599
|
+
|
600
|
+
|
601
|
+
class ZenMLGCPAWSExternalAccountCredentials(gcp_aws.Credentials): # type: ignore[misc]
|
602
|
+
"""An improved version of the GCP external account credential for AWS.
|
603
|
+
|
604
|
+
The original GCP external account credential only provides rudimentary
|
605
|
+
support for extracting AWS credentials from environment variables or the
|
606
|
+
AWS metadata service. This version improves on that by using the boto3
|
607
|
+
library itself (if available), which uses the entire range of implicit
|
608
|
+
authentication features packed into it.
|
609
|
+
|
610
|
+
Without this improvement, `sts.AssumeRoleWithWebIdentity` authentication is
|
611
|
+
not supported for EKS pods and the EC2 attached role credentials are
|
612
|
+
used instead (see: https://medium.com/@derek10cloud/gcp-workload-identity-federation-doesnt-yet-support-eks-irsa-in-aws-a3c71877671a).
|
613
|
+
|
614
|
+
IMPORTANT: subclassing this class only works with the `google-auth` library
|
615
|
+
version lower than 2.29.0. Starting from version 2.29.0, the AWS logic
|
616
|
+
has been moved to a separate `google.auth.aws._DefaultAwsSecurityCredentialsSupplier`
|
617
|
+
class that can be subclassed instead and supplied as the
|
618
|
+
`aws_security_credentials_supplier` parameter to the
|
619
|
+
`google.auth.aws.Credentials` class.
|
620
|
+
"""
|
621
|
+
|
622
|
+
def _get_security_credentials(
|
623
|
+
self, request: Any, imdsv2_session_token: Any
|
624
|
+
) -> Dict[str, Any]:
|
625
|
+
"""Get the security credentials from the local environment.
|
626
|
+
|
627
|
+
This method is a copy of the original method from the
|
628
|
+
`google.auth._default` module. It has been modified to use the boto3
|
629
|
+
library to extract the AWS credentials from the local environment.
|
630
|
+
|
631
|
+
Args:
|
632
|
+
request: The request to use to get the security credentials.
|
633
|
+
imdsv2_session_token: The IMDSv2 session token to use to get the
|
634
|
+
security credentials.
|
635
|
+
|
636
|
+
Returns:
|
637
|
+
The AWS temporary security credentials.
|
638
|
+
"""
|
639
|
+
try:
|
640
|
+
import boto3
|
641
|
+
|
642
|
+
session = boto3.Session()
|
643
|
+
credentials = session.get_credentials()
|
644
|
+
if credentials is not None:
|
645
|
+
creds = credentials.get_frozen_credentials()
|
646
|
+
return {
|
647
|
+
"access_key_id": creds.access_key,
|
648
|
+
"secret_access_key": creds.secret_key,
|
649
|
+
"security_token": creds.token,
|
650
|
+
}
|
651
|
+
except ImportError:
|
652
|
+
pass
|
653
|
+
|
654
|
+
logger.debug(
|
655
|
+
"Failed to extract AWS credentials from the local environment "
|
656
|
+
"using the boto3 library. Falling back to the original "
|
657
|
+
"implementation."
|
658
|
+
)
|
659
|
+
|
660
|
+
return super()._get_security_credentials( # type: ignore[no-any-return]
|
661
|
+
request, imdsv2_session_token
|
662
|
+
)
|
663
|
+
|
664
|
+
|
295
665
|
GCP_SERVICE_CONNECTOR_TYPE_SPEC = ServiceConnectorTypeModel(
|
296
666
|
name="GCP Service Connector",
|
297
667
|
connector_type=GCP_CONNECTOR_TYPE,
|
@@ -378,7 +748,7 @@ resources in the specified project. When used remotely in a GCP workload, the
|
|
378
748
|
configured project has to be the same as the project of the attached service
|
379
749
|
account.
|
380
750
|
""",
|
381
|
-
config_class=
|
751
|
+
config_class=GCPBaseProjectIDConfig,
|
382
752
|
),
|
383
753
|
AuthenticationMethodModel(
|
384
754
|
name="GCP User Account",
|
@@ -435,6 +805,46 @@ picked up when auto-configuration is used.
|
|
435
805
|
""",
|
436
806
|
config_class=GCPServiceAccountConfig,
|
437
807
|
),
|
808
|
+
AuthenticationMethodModel(
|
809
|
+
name="GCP External Account",
|
810
|
+
auth_method=GCPAuthenticationMethods.EXTERNAL_ACCOUNT,
|
811
|
+
description="""
|
812
|
+
Use [GCP workload identity federation](https://cloud.google.com/iam/docs/workload-identity-federation)
|
813
|
+
to authenticate to GCP services using AWS IAM credentials, Azure Active
|
814
|
+
Directory credentials or generic OIDC tokens.
|
815
|
+
|
816
|
+
This authentication method only requires a GCP workload identity external
|
817
|
+
account JSON file that only contains the configuration for the external account
|
818
|
+
without any sensitive credentials. It allows implementing a two layer
|
819
|
+
authentication scheme that keeps the set of permissions associated with implicit
|
820
|
+
credentials down to the bare minimum and grants permissions to the
|
821
|
+
privilege-bearing GCP service account instead.
|
822
|
+
|
823
|
+
This authentication method can be used to authenticate to GCP services using
|
824
|
+
credentials from other cloud providers or identity providers. When used with
|
825
|
+
workloads running on AWS or Azure, it involves automatically picking up
|
826
|
+
credentials from the AWS IAM or Azure AD identity associated with the workload
|
827
|
+
and using them to authenticate to GCP services. This means that the result
|
828
|
+
depends on the environment where the ZenML server is deployed and is thus not
|
829
|
+
fully reproducible.
|
830
|
+
|
831
|
+
By default, the GCP connector generates temporary OAuth 2.0 tokens from the
|
832
|
+
external account credentials and distributes them to clients. The tokens have a
|
833
|
+
limited lifetime of 1 hour. This behavior can be disabled by setting the
|
834
|
+
`generate_temporary_tokens` configuration option to `False`, in which case, the
|
835
|
+
connector will distribute the external account credentials JSON to clients
|
836
|
+
instead (not recommended).
|
837
|
+
|
838
|
+
A GCP project is required and the connector may only be used to access GCP
|
839
|
+
resources in the specified project. This project must be the same as the one
|
840
|
+
for which the external account was configured.
|
841
|
+
|
842
|
+
If you already have the GOOGLE_APPLICATION_CREDENTIALS environment variable
|
843
|
+
configured to point to an external account key JSON file, it will be
|
844
|
+
automatically picked up when auto-configuration is used.
|
845
|
+
""",
|
846
|
+
config_class=GCPExternalAccountConfig,
|
847
|
+
),
|
438
848
|
AuthenticationMethodModel(
|
439
849
|
name="GCP Oauth 2.0 Token",
|
440
850
|
auth_method=GCPAuthenticationMethods.OAUTH2_TOKEN,
|
@@ -584,14 +994,53 @@ GKE clusters in the GCP project that it is configured to use.
|
|
584
994
|
emoji=":cyclone:",
|
585
995
|
),
|
586
996
|
ResourceTypeModel(
|
587
|
-
name="GCP
|
997
|
+
name="GCP GAR container registry",
|
588
998
|
resource_type=DOCKER_REGISTRY_RESOURCE_TYPE,
|
589
999
|
description="""
|
590
|
-
Allows Stack Components to access a
|
1000
|
+
Allows Stack Components to access a Google Artifact Registry as a standard
|
591
1001
|
Docker registry resource. When used by Stack Components, they are provided a
|
592
1002
|
pre-authenticated Python Docker client instance.
|
593
1003
|
|
594
|
-
The configured credentials must have at least the following [GCP permissions](https://cloud.google.com/iam/docs/
|
1004
|
+
The configured credentials must have at least the following [GCP permissions](https://cloud.google.com/iam/docs/understanding-roles#artifact-registry-roles):
|
1005
|
+
|
1006
|
+
- `artifactregistry.repositories.createOnPush`
|
1007
|
+
- `artifactregistry.repositories.downloadArtifacts`
|
1008
|
+
- `artifactregistry.repositories.get`
|
1009
|
+
- `artifactregistry.repositories.list`
|
1010
|
+
- `artifactregistry.repositories.readViaVirtualRepository`
|
1011
|
+
- `artifactregistry.repositories.uploadArtifacts`
|
1012
|
+
- `artifactregistry.locations.list`
|
1013
|
+
|
1014
|
+
The Artifact Registry Create-on-Push Writer role includes all of the above
|
1015
|
+
permissions.
|
1016
|
+
|
1017
|
+
This resource type also includes legacy GCR container registry support.
|
1018
|
+
|
1019
|
+
**Important Notice: Google Container Registry** [**is being replaced by Artifact Registry**](https://cloud.google.com/artifact-registry/docs/transition/transition-from-gcr).
|
1020
|
+
Please start using Artifact Registry for your containers. As per Google's
|
1021
|
+
documentation, *"after May 15, 2024, Artifact Registry will host images for the
|
1022
|
+
gcr.io domain in Google Cloud projects without previous Container Registry
|
1023
|
+
usage. After March 18, 2025, Container Registry will be shut down."*.
|
1024
|
+
|
1025
|
+
Support for legacy GCR registries is still included in the GCP service
|
1026
|
+
connector. Users that already have GCP service connectors configured to access
|
1027
|
+
GCR registries may continue to use them without taking any action. However, it
|
1028
|
+
is recommended to transition to Google Artifact Registries as soon as possible
|
1029
|
+
by following [the GCP guide on this subject](https://cloud.google.com/artifact-registry/docs/transition/transition-from-gcr)
|
1030
|
+
and making the following updates to ZenML GCP Service Connectors that are used
|
1031
|
+
to access GCR resources:
|
1032
|
+
|
1033
|
+
* add the IAM permissions documented here to the GCP Service Connector
|
1034
|
+
credentials to enable them to access the Artifact Registries.
|
1035
|
+
* users may keep the gcr.io GCR URLs already configured in the GCP Service
|
1036
|
+
Connectors as well as those used in linked Container Registry stack components
|
1037
|
+
given that these domains are redirected by Google to GAR as covered in the GCR
|
1038
|
+
transition guide. Alternatively, users may update the GCP Service Connector
|
1039
|
+
configuration and/or the Container Registry stack components to use the
|
1040
|
+
replacement Artifact Registry URLs.
|
1041
|
+
|
1042
|
+
When used with GCR registries, the configured credentials must have at least the
|
1043
|
+
following [GCP permissions](https://cloud.google.com/iam/docs/understanding-roles#cloud-storage-roles):
|
595
1044
|
|
596
1045
|
- `storage.buckets.get`
|
597
1046
|
- `storage.multipartUploads.abort`
|
@@ -605,17 +1054,21 @@ The configured credentials must have at least the following [GCP permissions](ht
|
|
605
1054
|
The Storage Legacy Bucket Writer role includes all of the above permissions
|
606
1055
|
while at the same time restricting access to only the GCR buckets.
|
607
1056
|
|
608
|
-
|
609
|
-
|
610
|
-
|
1057
|
+
If set, the resource name must identify a GAR or GCR registry using one of the
|
1058
|
+
following formats:
|
1059
|
+
|
1060
|
+
- Google Artifact Registry repository URI: `[https://]<region>-docker.pkg.dev/<project-id>/<registry-id>[/<repository-name>]`
|
1061
|
+
- Google Artifact Registry name: `projects/<project-id>/locations/<location>/repositories/<repository-id>`
|
1062
|
+
- (legacy) GCR repository URI: `[https://][us.|eu.|asia.]gcr.io/<project-id>[/<repository-name>]`
|
611
1063
|
|
612
|
-
|
1064
|
+
The connector can only be used to access GAR and GCR registries in the GCP
|
1065
|
+
project that it is configured to use.
|
613
1066
|
""",
|
614
1067
|
auth_methods=GCPAuthenticationMethods.values(),
|
615
|
-
#
|
616
|
-
#
|
617
|
-
#
|
618
|
-
supports_instances=
|
1068
|
+
# The connector provides access to the entire GCR container registry
|
1069
|
+
# for the configured GCP project as well as any number of artifact
|
1070
|
+
# registry repositories.
|
1071
|
+
supports_instances=True,
|
619
1072
|
logo_url="https://public-flavor-logos.s3.eu-central-1.amazonaws.com/container_registry/docker.png",
|
620
1073
|
emoji=":whale:",
|
621
1074
|
),
|
@@ -650,7 +1103,7 @@ class GCPServiceConnector(ServiceConnector):
|
|
650
1103
|
auth_method: str,
|
651
1104
|
resource_type: Optional[str] = None,
|
652
1105
|
resource_id: Optional[str] = None,
|
653
|
-
) -> Tuple[
|
1106
|
+
) -> Tuple[gcp_credentials.Credentials, Optional[datetime.datetime]]:
|
654
1107
|
"""Get a GCP session object with credentials for the specified resource.
|
655
1108
|
|
656
1109
|
Args:
|
@@ -673,7 +1126,10 @@ class GCPServiceConnector(ServiceConnector):
|
|
673
1126
|
# Refresh expired sessions
|
674
1127
|
now = datetime.datetime.now(datetime.timezone.utc)
|
675
1128
|
expires_at = expires_at.replace(tzinfo=datetime.timezone.utc)
|
676
|
-
if
|
1129
|
+
# check if the token expires in the near future
|
1130
|
+
if expires_at > now + datetime.timedelta(
|
1131
|
+
minutes=GCP_SESSION_EXPIRATION_BUFFER
|
1132
|
+
):
|
677
1133
|
return session, expires_at
|
678
1134
|
|
679
1135
|
logger.debug(
|
@@ -711,7 +1167,10 @@ class GCPServiceConnector(ServiceConnector):
|
|
711
1167
|
auth_method: str,
|
712
1168
|
resource_type: Optional[str] = None,
|
713
1169
|
resource_id: Optional[str] = None,
|
714
|
-
) -> Tuple[
|
1170
|
+
) -> Tuple[
|
1171
|
+
gcp_credentials.Credentials,
|
1172
|
+
Optional[datetime.datetime],
|
1173
|
+
]:
|
715
1174
|
"""Authenticate to GCP and return a session with credentials.
|
716
1175
|
|
717
1176
|
Args:
|
@@ -762,8 +1221,49 @@ class GCPServiceConnector(ServiceConnector):
|
|
762
1221
|
scopes=scopes,
|
763
1222
|
)
|
764
1223
|
)
|
1224
|
+
elif auth_method == GCPAuthenticationMethods.EXTERNAL_ACCOUNT:
|
1225
|
+
self._check_implicit_auth_method_allowed()
|
1226
|
+
|
1227
|
+
assert isinstance(cfg, GCPExternalAccountConfig)
|
1228
|
+
|
1229
|
+
# As a special case, for the AWS external account credential,
|
1230
|
+
# we use a custom credential class that supports extracting
|
1231
|
+
# the AWS credentials from the local environment, metadata
|
1232
|
+
# service or IRSA (if running on AWS EKS).
|
1233
|
+
account_info = json.loads(
|
1234
|
+
cfg.external_account_json.get_secret_value()
|
1235
|
+
)
|
1236
|
+
if (
|
1237
|
+
account_info.get("subject_token_type")
|
1238
|
+
== _AWS_SUBJECT_TOKEN_TYPE
|
1239
|
+
):
|
1240
|
+
if ZenMLAwsSecurityCredentialsSupplier is not None:
|
1241
|
+
account_info["aws_security_credentials_supplier"] = (
|
1242
|
+
ZenMLAwsSecurityCredentialsSupplier(
|
1243
|
+
account_info.pop("credential_source"),
|
1244
|
+
)
|
1245
|
+
)
|
1246
|
+
credentials = (
|
1247
|
+
ZenMLGCPAWSExternalAccountCredentials.from_info(
|
1248
|
+
account_info,
|
1249
|
+
scopes=scopes,
|
1250
|
+
)
|
1251
|
+
)
|
1252
|
+
else:
|
1253
|
+
credentials, _ = _get_external_account_credentials(
|
1254
|
+
json.loads(
|
1255
|
+
cfg.external_account_json.get_secret_value()
|
1256
|
+
),
|
1257
|
+
filename="", # Not used
|
1258
|
+
scopes=scopes,
|
1259
|
+
)
|
1260
|
+
|
765
1261
|
else:
|
1262
|
+
# Service account or impersonation (which is a special case of
|
1263
|
+
# service account authentication)
|
1264
|
+
|
766
1265
|
assert isinstance(cfg, GCPServiceAccountConfig)
|
1266
|
+
|
767
1267
|
credentials = (
|
768
1268
|
gcp_service_account.Credentials.from_service_account_info(
|
769
1269
|
json.loads(
|
@@ -773,22 +1273,24 @@ class GCPServiceConnector(ServiceConnector):
|
|
773
1273
|
)
|
774
1274
|
)
|
775
1275
|
|
776
|
-
|
777
|
-
|
778
|
-
|
779
|
-
try:
|
780
|
-
credentials = gcp_impersonated_credentials.Credentials(
|
781
|
-
source_credentials=credentials,
|
782
|
-
target_principal=cfg.target_principal,
|
783
|
-
target_scopes=scopes,
|
784
|
-
lifetime=self.expiration_seconds,
|
785
|
-
)
|
786
|
-
except google.auth.exceptions.GoogleAuthError as e:
|
787
|
-
raise AuthorizationException(
|
788
|
-
f"Failed to impersonate service account "
|
789
|
-
f"'{cfg.target_principal}': {e}"
|
1276
|
+
if auth_method == GCPAuthenticationMethods.IMPERSONATION:
|
1277
|
+
assert isinstance(
|
1278
|
+
cfg, GCPServiceAccountImpersonationConfig
|
790
1279
|
)
|
791
1280
|
|
1281
|
+
try:
|
1282
|
+
credentials = gcp_impersonated_credentials.Credentials(
|
1283
|
+
source_credentials=credentials,
|
1284
|
+
target_principal=cfg.target_principal,
|
1285
|
+
target_scopes=scopes,
|
1286
|
+
lifetime=self.expiration_seconds,
|
1287
|
+
)
|
1288
|
+
except google.auth.exceptions.GoogleAuthError as e:
|
1289
|
+
raise AuthorizationException(
|
1290
|
+
f"Failed to impersonate service account "
|
1291
|
+
f"'{cfg.target_principal}': {e}"
|
1292
|
+
)
|
1293
|
+
|
792
1294
|
if not credentials.valid:
|
793
1295
|
try:
|
794
1296
|
with requests.Session() as session:
|
@@ -849,60 +1351,101 @@ class GCPServiceConnector(ServiceConnector):
|
|
849
1351
|
|
850
1352
|
return bucket_name
|
851
1353
|
|
852
|
-
def
|
1354
|
+
def _parse_gar_resource_id(
|
853
1355
|
self,
|
854
1356
|
resource_id: str,
|
855
|
-
) -> str:
|
856
|
-
"""Validate and convert
|
1357
|
+
) -> Tuple[str, Optional[str]]:
|
1358
|
+
"""Validate and convert a GAR resource ID to a Google Artifact Registry ID and name.
|
857
1359
|
|
858
1360
|
Args:
|
859
1361
|
resource_id: The resource ID to convert.
|
860
1362
|
|
861
1363
|
Returns:
|
862
|
-
The
|
1364
|
+
The Google Artifact Registry ID and name. The name is omitted if the
|
1365
|
+
resource ID is a GCR repository URI.
|
863
1366
|
|
864
1367
|
Raises:
|
865
|
-
ValueError: If the provided resource ID is not a valid
|
866
|
-
repository URI.
|
1368
|
+
ValueError: If the provided resource ID is not a valid GAR
|
1369
|
+
or GCR repository URI.
|
867
1370
|
"""
|
868
1371
|
# The resource ID could mean different things:
|
869
1372
|
#
|
870
|
-
# -
|
1373
|
+
# - a GAR repository URI
|
1374
|
+
# - a GAR repository name
|
1375
|
+
# - a GCR repository URI (backwards-compatibility)
|
871
1376
|
#
|
872
1377
|
# We need to extract the project ID and registry ID from
|
873
1378
|
# the provided resource ID
|
874
|
-
config_project_id = self.config.
|
1379
|
+
config_project_id = self.config.gcp_project_id
|
875
1380
|
project_id: Optional[str] = None
|
876
|
-
|
877
|
-
|
878
|
-
|
879
|
-
|
880
|
-
|
1381
|
+
canonical_url: str
|
1382
|
+
registry_name: Optional[str] = None
|
1383
|
+
|
1384
|
+
# A Google Artifact Registry URI uses the <location>-docker-pkg.dev
|
1385
|
+
# domain format with the project ID as the first part of the URL path
|
1386
|
+
# and the registry name as the second part of the URL path
|
1387
|
+
if match := re.match(
|
1388
|
+
r"^(https://)?(([a-z0-9-]+)-docker\.pkg\.dev/([a-z0-9-]+)/([a-z0-9-.]+))(/.+)*$",
|
881
1389
|
resource_id,
|
882
1390
|
):
|
883
|
-
# The resource ID is a
|
884
|
-
|
885
|
-
|
886
|
-
|
887
|
-
|
1391
|
+
# The resource ID is a Google Artifact Registry URI
|
1392
|
+
project_id = match[4]
|
1393
|
+
location = match[3]
|
1394
|
+
repository = match[5]
|
1395
|
+
|
1396
|
+
# Return the GAR URL without the image name and without the protocol
|
1397
|
+
canonical_url = match[2]
|
1398
|
+
registry_name = f"projects/{project_id}/locations/{location}/repositories/{repository}"
|
1399
|
+
|
1400
|
+
# Alternatively, the Google Artifact Registry name uses the
|
1401
|
+
# projects/<project-id>/locations/<location>/repositories/<repository-id>
|
1402
|
+
# format
|
1403
|
+
elif match := re.match(
|
1404
|
+
r"^projects/([a-z0-9-]+)/locations/([a-z0-9-]+)/repositories/([a-z0-9-.]+)$",
|
1405
|
+
resource_id,
|
1406
|
+
):
|
1407
|
+
# The resource ID is a Google Artifact Registry name
|
1408
|
+
project_id = match[1]
|
1409
|
+
location = match[2]
|
1410
|
+
repository = match[3]
|
1411
|
+
|
1412
|
+
# Return the GAR URL
|
1413
|
+
canonical_url = (
|
1414
|
+
f"{location}-docker.pkg.dev/{project_id}/{repository}"
|
1415
|
+
)
|
1416
|
+
registry_name = resource_id
|
1417
|
+
|
1418
|
+
# A legacy GCR repository URI uses one of several hostnames (gcr.io,
|
1419
|
+
# us.gcr.io, eu.gcr.io, asia.gcr.io) and the project ID is the
|
1420
|
+
# first part of the URL path
|
1421
|
+
elif match := re.match(
|
1422
|
+
r"^(https://)?(((us|eu|asia)\.)?gcr\.io/[a-z0-9-]+)(/.+)*$",
|
1423
|
+
resource_id,
|
1424
|
+
):
|
1425
|
+
# The resource ID is a legacy GCR repository URI.
|
1426
|
+
# Return the GAR URL without the image name and without the protocol
|
1427
|
+
canonical_url = match[2]
|
1428
|
+
|
888
1429
|
else:
|
889
1430
|
raise ValueError(
|
890
|
-
f"Invalid resource ID for a
|
891
|
-
f"Supported formats are:\n"
|
1431
|
+
f"Invalid resource ID for a Google Artifact Registry: "
|
1432
|
+
f"{resource_id}. Supported formats are:\n"
|
1433
|
+
f"Google Artifact Registry URI: [https://]<region>-docker.pkg.dev/<project-id>/<registry-id>[/<repository-name>]\n"
|
1434
|
+
f"Google Artifact Registry name: projects/<project-id>/locations/<location>/repositories/<repository-id>\n"
|
892
1435
|
f"GCR repository URI: [https://][us.|eu.|asia.]gcr.io/<project-id>[/<repository-name>]"
|
893
1436
|
)
|
894
1437
|
|
895
1438
|
# If the connector is configured with a project and the resource ID
|
896
|
-
# is
|
1439
|
+
# is a GAR repository URI that specifies a different project,
|
897
1440
|
# we raise an error
|
898
1441
|
if project_id and project_id != config_project_id:
|
899
1442
|
raise ValueError(
|
900
|
-
f"The GCP project for the {resource_id}
|
901
|
-
f"'{project_id}' does not match the project
|
902
|
-
f"the connector: '{config_project_id}'."
|
1443
|
+
f"The GCP project for the {resource_id} Google Artifact "
|
1444
|
+
f"Registry '{project_id}' does not match the project "
|
1445
|
+
f"configured in the connector: '{config_project_id}'."
|
903
1446
|
)
|
904
1447
|
|
905
|
-
return
|
1448
|
+
return canonical_url, registry_name
|
906
1449
|
|
907
1450
|
def _parse_gke_resource_id(self, resource_id: str) -> str:
|
908
1451
|
"""Validate and convert an GKE resource ID to a GKE cluster name.
|
@@ -951,7 +1494,7 @@ class GCPServiceConnector(ServiceConnector):
|
|
951
1494
|
cluster_name = self._parse_gke_resource_id(resource_id)
|
952
1495
|
return cluster_name
|
953
1496
|
elif resource_type == DOCKER_REGISTRY_RESOURCE_TYPE:
|
954
|
-
registry_id = self.
|
1497
|
+
registry_id, _ = self._parse_gar_resource_id(
|
955
1498
|
resource_id,
|
956
1499
|
)
|
957
1500
|
return registry_id
|
@@ -975,9 +1518,7 @@ class GCPServiceConnector(ServiceConnector):
|
|
975
1518
|
authorized.
|
976
1519
|
"""
|
977
1520
|
if resource_type == GCP_RESOURCE_TYPE:
|
978
|
-
return self.config.
|
979
|
-
elif resource_type == DOCKER_REGISTRY_RESOURCE_TYPE:
|
980
|
-
return f"gcr.io/{self.config.project_id}"
|
1521
|
+
return self.config.gcp_project_id
|
981
1522
|
|
982
1523
|
raise RuntimeError(
|
983
1524
|
f"Default resource ID not supported for '{resource_type}' resource "
|
@@ -1034,7 +1575,7 @@ class GCPServiceConnector(ServiceConnector):
|
|
1034
1575
|
|
1035
1576
|
# Create an GCS client for the bucket
|
1036
1577
|
client = storage.Client(
|
1037
|
-
project=self.config.
|
1578
|
+
project=self.config.gcp_project_id, credentials=credentials
|
1038
1579
|
)
|
1039
1580
|
return client
|
1040
1581
|
|
@@ -1074,7 +1615,7 @@ class GCPServiceConnector(ServiceConnector):
|
|
1074
1615
|
|
1075
1616
|
# There is no way to configure the local gcloud CLI to use
|
1076
1617
|
# temporary OAuth 2.0 tokens. However, we can configure it to use
|
1077
|
-
# the service account credentials
|
1618
|
+
# the service account or external account credentials
|
1078
1619
|
if self.auth_method == GCPAuthenticationMethods.SERVICE_ACCOUNT:
|
1079
1620
|
assert isinstance(self.config, GCPServiceAccountConfig)
|
1080
1621
|
# Use the service account credentials JSON to configure the
|
@@ -1082,6 +1623,13 @@ class GCPServiceConnector(ServiceConnector):
|
|
1082
1623
|
gcloud_config_json = (
|
1083
1624
|
self.config.service_account_json.get_secret_value()
|
1084
1625
|
)
|
1626
|
+
elif self.auth_method == GCPAuthenticationMethods.EXTERNAL_ACCOUNT:
|
1627
|
+
assert isinstance(self.config, GCPExternalAccountConfig)
|
1628
|
+
# Use the external account credentials JSON to configure the
|
1629
|
+
# local gcloud CLI
|
1630
|
+
gcloud_config_json = (
|
1631
|
+
self.config.external_account_json.get_secret_value()
|
1632
|
+
)
|
1085
1633
|
|
1086
1634
|
if gcloud_config_json:
|
1087
1635
|
from google.auth import _cloud_sdk
|
@@ -1108,6 +1656,7 @@ class GCPServiceConnector(ServiceConnector):
|
|
1108
1656
|
"gcloud",
|
1109
1657
|
"auth",
|
1110
1658
|
"login",
|
1659
|
+
"--quiet",
|
1111
1660
|
"--cred-file",
|
1112
1661
|
adc_path,
|
1113
1662
|
],
|
@@ -1132,7 +1681,7 @@ class GCPServiceConnector(ServiceConnector):
|
|
1132
1681
|
"config",
|
1133
1682
|
"set",
|
1134
1683
|
"project",
|
1135
|
-
self.config.
|
1684
|
+
self.config.gcp_project_id,
|
1136
1685
|
],
|
1137
1686
|
check=True,
|
1138
1687
|
stderr=subprocess.STDOUT,
|
@@ -1163,9 +1712,10 @@ class GCPServiceConnector(ServiceConnector):
|
|
1163
1712
|
raise NotImplementedError(
|
1164
1713
|
f"Local gcloud client configuration for resource type "
|
1165
1714
|
f"{resource_type} is only supported if the "
|
1166
|
-
f"'{GCPAuthenticationMethods.SERVICE_ACCOUNT}'
|
1167
|
-
f"
|
1168
|
-
f"
|
1715
|
+
f"'{GCPAuthenticationMethods.SERVICE_ACCOUNT}' or "
|
1716
|
+
f"'{GCPAuthenticationMethods.EXTERNAL_ACCOUNT}' "
|
1717
|
+
f"authentication method is used and only if the generation of "
|
1718
|
+
f"temporary OAuth 2.0 tokens is disabled by setting the "
|
1169
1719
|
f"'generate_temporary_tokens' option to 'False' in the "
|
1170
1720
|
f"service connector configuration."
|
1171
1721
|
)
|
@@ -1235,9 +1785,7 @@ class GCPServiceConnector(ServiceConnector):
|
|
1235
1785
|
)
|
1236
1786
|
|
1237
1787
|
if auth_method == GCPAuthenticationMethods.IMPLICIT:
|
1238
|
-
|
1239
|
-
|
1240
|
-
auth_config = GCPBaseConfig(
|
1788
|
+
auth_config = GCPBaseProjectIDConfig(
|
1241
1789
|
project_id=project_id,
|
1242
1790
|
)
|
1243
1791
|
elif auth_method == GCPAuthenticationMethods.OAUTH2_TOKEN:
|
@@ -1339,6 +1887,51 @@ class GCPServiceConnector(ServiceConnector):
|
|
1339
1887
|
project_id=project_id,
|
1340
1888
|
service_account_json=service_account_json,
|
1341
1889
|
)
|
1890
|
+
# Check if external account credentials are available
|
1891
|
+
elif isinstance(credentials, gcp_external_account.Credentials):
|
1892
|
+
if auth_method not in [
|
1893
|
+
GCPAuthenticationMethods.EXTERNAL_ACCOUNT,
|
1894
|
+
None,
|
1895
|
+
]:
|
1896
|
+
raise NotImplementedError(
|
1897
|
+
f"Could not perform auto-configuration for "
|
1898
|
+
f"authentication method {auth_method}. Only "
|
1899
|
+
f"GCP external account credentials have been detected."
|
1900
|
+
)
|
1901
|
+
|
1902
|
+
auth_method = GCPAuthenticationMethods.EXTERNAL_ACCOUNT
|
1903
|
+
external_account_json_file = os.environ.get(
|
1904
|
+
"GOOGLE_APPLICATION_CREDENTIALS"
|
1905
|
+
)
|
1906
|
+
if external_account_json_file is None:
|
1907
|
+
# No explicit service account JSON file was specified in the
|
1908
|
+
# environment, meaning that the credentials were loaded from
|
1909
|
+
# the GCP application default credentials (ADC) file.
|
1910
|
+
from google.auth import _cloud_sdk
|
1911
|
+
|
1912
|
+
# Use the location of the gcloud application default
|
1913
|
+
# credentials file
|
1914
|
+
external_account_json_file = (
|
1915
|
+
_cloud_sdk.get_application_default_credentials_path()
|
1916
|
+
)
|
1917
|
+
|
1918
|
+
if not external_account_json_file or not os.path.isfile(
|
1919
|
+
external_account_json_file
|
1920
|
+
):
|
1921
|
+
raise AuthorizationException(
|
1922
|
+
"No GCP service account credentials were found in the "
|
1923
|
+
"environment or the application default credentials "
|
1924
|
+
"path. Please set the GOOGLE_APPLICATION_CREDENTIALS "
|
1925
|
+
"environment variable to the path of the external "
|
1926
|
+
"account JSON file or run 'gcloud auth application-"
|
1927
|
+
"default login' to generate a new ADC file."
|
1928
|
+
)
|
1929
|
+
with open(external_account_json_file, "r") as f:
|
1930
|
+
external_account_json = f.read()
|
1931
|
+
auth_config = GCPExternalAccountConfig(
|
1932
|
+
project_id=project_id,
|
1933
|
+
external_account_json=external_account_json,
|
1934
|
+
)
|
1342
1935
|
else:
|
1343
1936
|
raise AuthorizationException(
|
1344
1937
|
"No valid GCP credentials could be detected."
|
@@ -1401,7 +1994,7 @@ class GCPServiceConnector(ServiceConnector):
|
|
1401
1994
|
|
1402
1995
|
if resource_type == GCS_RESOURCE_TYPE:
|
1403
1996
|
gcs_client = storage.Client(
|
1404
|
-
project=self.config.
|
1997
|
+
project=self.config.gcp_project_id, credentials=credentials
|
1405
1998
|
)
|
1406
1999
|
if not resource_id:
|
1407
2000
|
# List all GCS buckets
|
@@ -1426,11 +2019,87 @@ class GCPServiceConnector(ServiceConnector):
|
|
1426
2019
|
raise AuthorizationException(msg) from e
|
1427
2020
|
|
1428
2021
|
if resource_type == DOCKER_REGISTRY_RESOURCE_TYPE:
|
1429
|
-
|
2022
|
+
# Get a GAR client
|
2023
|
+
gar_client = artifactregistry_v1.ArtifactRegistryClient(
|
2024
|
+
credentials=credentials
|
2025
|
+
)
|
1430
2026
|
|
1431
|
-
|
1432
|
-
|
1433
|
-
|
2027
|
+
if resource_id:
|
2028
|
+
registry_id, registry_name = self._parse_gar_resource_id(
|
2029
|
+
resource_id
|
2030
|
+
)
|
2031
|
+
|
2032
|
+
if registry_name is None:
|
2033
|
+
# This is a legacy GCR repository URI. We can't verify
|
2034
|
+
# the repository access without attempting to connect to it
|
2035
|
+
# via Docker/OCI, so just return the resource ID.
|
2036
|
+
return [registry_id]
|
2037
|
+
|
2038
|
+
# Check if the specified GAR registry exists
|
2039
|
+
try:
|
2040
|
+
repository = gar_client.get_repository(
|
2041
|
+
name=registry_name,
|
2042
|
+
)
|
2043
|
+
if repository.format_.name != "DOCKER":
|
2044
|
+
raise AuthorizationException(
|
2045
|
+
f"Google Artifact Registry '{resource_id}' is not a "
|
2046
|
+
"Docker registry."
|
2047
|
+
)
|
2048
|
+
return [registry_id]
|
2049
|
+
except google.api_core.exceptions.GoogleAPIError as e:
|
2050
|
+
msg = f"Failed to fetch Google Artifact Registry '{registry_id}': {e}"
|
2051
|
+
logger.error(msg)
|
2052
|
+
raise AuthorizationException(msg) from e
|
2053
|
+
|
2054
|
+
# For backwards compatibility, we initialize the list of resource
|
2055
|
+
# IDs with all GCR supported registries for the configured GCP
|
2056
|
+
# project
|
2057
|
+
resource_ids: List[str] = [
|
2058
|
+
f"{location}gcr.io/{self.config.gcp_project_id}"
|
2059
|
+
for location in ["", "us.", "eu.", "asia."]
|
2060
|
+
]
|
2061
|
+
|
2062
|
+
# List all Google Artifact Registries
|
2063
|
+
try:
|
2064
|
+
# First, we need to fetch all the Artifact Registry supported
|
2065
|
+
# locations
|
2066
|
+
locations = gar_client.list_locations(
|
2067
|
+
request=locations_pb2.ListLocationsRequest(
|
2068
|
+
name=f"projects/{self.config.gcp_project_id}"
|
2069
|
+
)
|
2070
|
+
)
|
2071
|
+
location_names = [
|
2072
|
+
locations.locations[i].location_id
|
2073
|
+
for i in range(len(locations.locations))
|
2074
|
+
]
|
2075
|
+
|
2076
|
+
# Then, we need to fetch all the repositories in each location
|
2077
|
+
repository_names: List[str] = []
|
2078
|
+
for location in location_names:
|
2079
|
+
repositories = gar_client.list_repositories(
|
2080
|
+
parent=f"projects/{self.config.gcp_project_id}/locations/{location}"
|
2081
|
+
)
|
2082
|
+
repository_names.extend(
|
2083
|
+
[
|
2084
|
+
repository.name
|
2085
|
+
for repository in repositories
|
2086
|
+
if repository.format_.name == "DOCKER"
|
2087
|
+
]
|
2088
|
+
)
|
2089
|
+
|
2090
|
+
for repository_name in repository_names:
|
2091
|
+
# Convert the repository name to a canonical GAR URL
|
2092
|
+
resource_ids.append(
|
2093
|
+
self._parse_gar_resource_id(repository_name)[0]
|
2094
|
+
)
|
2095
|
+
|
2096
|
+
except google.api_core.exceptions.GoogleAPIError as e:
|
2097
|
+
msg = f"Failed to list Google Artifact Registries: {e}"
|
2098
|
+
logger.error(msg)
|
2099
|
+
# TODO: enable when GCR is no longer supported:
|
2100
|
+
# raise AuthorizationException(msg) from e
|
2101
|
+
|
2102
|
+
return resource_ids
|
1434
2103
|
|
1435
2104
|
if resource_type == KUBERNETES_CLUSTER_RESOURCE_TYPE:
|
1436
2105
|
gke_client = container_v1.ClusterManagerClient(
|
@@ -1440,7 +2109,7 @@ class GCPServiceConnector(ServiceConnector):
|
|
1440
2109
|
# List all GKE clusters
|
1441
2110
|
try:
|
1442
2111
|
clusters = gke_client.list_clusters(
|
1443
|
-
parent=f"projects/{self.config.
|
2112
|
+
parent=f"projects/{self.config.gcp_project_id}/locations/-"
|
1444
2113
|
)
|
1445
2114
|
cluster_names = [cluster.name for cluster in clusters.clusters]
|
1446
2115
|
except google.api_core.exceptions.GoogleAPIError as e:
|
@@ -1514,7 +2183,7 @@ class GCPServiceConnector(ServiceConnector):
|
|
1514
2183
|
# object
|
1515
2184
|
auth_method: str = GCPAuthenticationMethods.OAUTH2_TOKEN
|
1516
2185
|
config: GCPBaseConfig = GCPOAuth2TokenConfig(
|
1517
|
-
project_id=self.config.
|
2186
|
+
project_id=self.config.gcp_project_id,
|
1518
2187
|
token=credentials.token,
|
1519
2188
|
service_account_email=credentials.signer_email
|
1520
2189
|
if hasattr(credentials, "signer_email")
|
@@ -1535,6 +2204,12 @@ class GCPServiceConnector(ServiceConnector):
|
|
1535
2204
|
config = self.config
|
1536
2205
|
auth_method = self.auth_method
|
1537
2206
|
expires_at = None
|
2207
|
+
elif self.auth_method == GCPAuthenticationMethods.EXTERNAL_ACCOUNT:
|
2208
|
+
assert isinstance(self.config, GCPExternalAccountConfig)
|
2209
|
+
if not self.config.generate_temporary_tokens:
|
2210
|
+
config = self.config
|
2211
|
+
auth_method = self.auth_method
|
2212
|
+
expires_at = None
|
1538
2213
|
|
1539
2214
|
# Create a client-side GCP connector instance that is fully formed
|
1540
2215
|
# and ready to use to connect to the specified resource (i.e. has
|
@@ -1553,7 +2228,7 @@ class GCPServiceConnector(ServiceConnector):
|
|
1553
2228
|
if resource_type == DOCKER_REGISTRY_RESOURCE_TYPE:
|
1554
2229
|
assert resource_id is not None
|
1555
2230
|
|
1556
|
-
registry_id = self.
|
2231
|
+
registry_id, _ = self._parse_gar_resource_id(resource_id)
|
1557
2232
|
|
1558
2233
|
# Create a client-side Docker connector instance with the temporary
|
1559
2234
|
# Docker credentials
|
@@ -1582,7 +2257,7 @@ class GCPServiceConnector(ServiceConnector):
|
|
1582
2257
|
# List all GKE clusters
|
1583
2258
|
try:
|
1584
2259
|
clusters = gke_client.list_clusters(
|
1585
|
-
parent=f"projects/{self.config.
|
2260
|
+
parent=f"projects/{self.config.gcp_project_id}/locations/-"
|
1586
2261
|
)
|
1587
2262
|
cluster_map = {
|
1588
2263
|
cluster.name: cluster for cluster in clusters.clusters
|
@@ -1626,7 +2301,7 @@ class GCPServiceConnector(ServiceConnector):
|
|
1626
2301
|
auth_method=KubernetesAuthenticationMethods.TOKEN,
|
1627
2302
|
resource_type=resource_type,
|
1628
2303
|
config=KubernetesTokenConfig(
|
1629
|
-
cluster_name=f"gke_{self.config.
|
2304
|
+
cluster_name=f"gke_{self.config.gcp_project_id}_{cluster_name}",
|
1630
2305
|
certificate_authority=cluster_ca_cert,
|
1631
2306
|
server=f"https://{cluster_server}",
|
1632
2307
|
token=bearer_token,
|