paasta-tools 1.21.3__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.
- k8s_itests/__init__.py +0 -0
- k8s_itests/test_autoscaling.py +23 -0
- k8s_itests/utils.py +38 -0
- paasta_tools/__init__.py +20 -0
- paasta_tools/adhoc_tools.py +142 -0
- paasta_tools/api/__init__.py +13 -0
- paasta_tools/api/api.py +330 -0
- paasta_tools/api/api_docs/swagger.json +2323 -0
- paasta_tools/api/client.py +106 -0
- paasta_tools/api/settings.py +33 -0
- paasta_tools/api/tweens/__init__.py +6 -0
- paasta_tools/api/tweens/auth.py +125 -0
- paasta_tools/api/tweens/profiling.py +108 -0
- paasta_tools/api/tweens/request_logger.py +124 -0
- paasta_tools/api/views/__init__.py +13 -0
- paasta_tools/api/views/autoscaler.py +100 -0
- paasta_tools/api/views/exception.py +45 -0
- paasta_tools/api/views/flink.py +73 -0
- paasta_tools/api/views/instance.py +395 -0
- paasta_tools/api/views/pause_autoscaler.py +71 -0
- paasta_tools/api/views/remote_run.py +113 -0
- paasta_tools/api/views/resources.py +76 -0
- paasta_tools/api/views/service.py +35 -0
- paasta_tools/api/views/version.py +25 -0
- paasta_tools/apply_external_resources.py +79 -0
- paasta_tools/async_utils.py +109 -0
- paasta_tools/autoscaling/__init__.py +0 -0
- paasta_tools/autoscaling/autoscaling_service_lib.py +57 -0
- paasta_tools/autoscaling/forecasting.py +106 -0
- paasta_tools/autoscaling/max_all_k8s_services.py +41 -0
- paasta_tools/autoscaling/pause_service_autoscaler.py +77 -0
- paasta_tools/autoscaling/utils.py +52 -0
- paasta_tools/bounce_lib.py +184 -0
- paasta_tools/broadcast_log_to_services.py +62 -0
- paasta_tools/cassandracluster_tools.py +210 -0
- paasta_tools/check_autoscaler_max_instances.py +212 -0
- paasta_tools/check_cassandracluster_services_replication.py +35 -0
- paasta_tools/check_flink_services_health.py +203 -0
- paasta_tools/check_kubernetes_api.py +57 -0
- paasta_tools/check_kubernetes_services_replication.py +141 -0
- paasta_tools/check_oom_events.py +244 -0
- paasta_tools/check_services_replication_tools.py +324 -0
- paasta_tools/check_spark_jobs.py +234 -0
- paasta_tools/cleanup_kubernetes_cr.py +138 -0
- paasta_tools/cleanup_kubernetes_crd.py +145 -0
- paasta_tools/cleanup_kubernetes_jobs.py +344 -0
- paasta_tools/cleanup_tron_namespaces.py +96 -0
- paasta_tools/cli/__init__.py +13 -0
- paasta_tools/cli/authentication.py +85 -0
- paasta_tools/cli/cli.py +260 -0
- paasta_tools/cli/cmds/__init__.py +13 -0
- paasta_tools/cli/cmds/autoscale.py +143 -0
- paasta_tools/cli/cmds/check.py +334 -0
- paasta_tools/cli/cmds/cook_image.py +147 -0
- paasta_tools/cli/cmds/get_docker_image.py +76 -0
- paasta_tools/cli/cmds/get_image_version.py +172 -0
- paasta_tools/cli/cmds/get_latest_deployment.py +93 -0
- paasta_tools/cli/cmds/info.py +155 -0
- paasta_tools/cli/cmds/itest.py +117 -0
- paasta_tools/cli/cmds/list.py +66 -0
- paasta_tools/cli/cmds/list_clusters.py +42 -0
- paasta_tools/cli/cmds/list_deploy_queue.py +171 -0
- paasta_tools/cli/cmds/list_namespaces.py +84 -0
- paasta_tools/cli/cmds/local_run.py +1396 -0
- paasta_tools/cli/cmds/logs.py +1601 -0
- paasta_tools/cli/cmds/mark_for_deployment.py +1988 -0
- paasta_tools/cli/cmds/mesh_status.py +174 -0
- paasta_tools/cli/cmds/pause_service_autoscaler.py +107 -0
- paasta_tools/cli/cmds/push_to_registry.py +275 -0
- paasta_tools/cli/cmds/remote_run.py +252 -0
- paasta_tools/cli/cmds/rollback.py +347 -0
- paasta_tools/cli/cmds/secret.py +549 -0
- paasta_tools/cli/cmds/security_check.py +59 -0
- paasta_tools/cli/cmds/spark_run.py +1400 -0
- paasta_tools/cli/cmds/start_stop_restart.py +401 -0
- paasta_tools/cli/cmds/status.py +2302 -0
- paasta_tools/cli/cmds/validate.py +1012 -0
- paasta_tools/cli/cmds/wait_for_deployment.py +275 -0
- paasta_tools/cli/fsm/__init__.py +13 -0
- paasta_tools/cli/fsm/autosuggest.py +82 -0
- paasta_tools/cli/fsm/template/README.md +8 -0
- paasta_tools/cli/fsm/template/cookiecutter.json +7 -0
- paasta_tools/cli/fsm/template/{{cookiecutter.service}}/kubernetes-PROD.yaml +91 -0
- paasta_tools/cli/fsm/template/{{cookiecutter.service}}/monitoring.yaml +20 -0
- paasta_tools/cli/fsm/template/{{cookiecutter.service}}/service.yaml +8 -0
- paasta_tools/cli/fsm/template/{{cookiecutter.service}}/smartstack.yaml +6 -0
- paasta_tools/cli/fsm_cmd.py +121 -0
- paasta_tools/cli/paasta_tabcomplete.sh +23 -0
- paasta_tools/cli/schemas/adhoc_schema.json +199 -0
- paasta_tools/cli/schemas/autoscaling_schema.json +91 -0
- paasta_tools/cli/schemas/autotuned_defaults/cassandracluster_schema.json +37 -0
- paasta_tools/cli/schemas/autotuned_defaults/kubernetes_schema.json +89 -0
- paasta_tools/cli/schemas/deploy_schema.json +173 -0
- paasta_tools/cli/schemas/eks_schema.json +970 -0
- paasta_tools/cli/schemas/kubernetes_schema.json +970 -0
- paasta_tools/cli/schemas/rollback_schema.json +160 -0
- paasta_tools/cli/schemas/service_schema.json +25 -0
- paasta_tools/cli/schemas/smartstack_schema.json +322 -0
- paasta_tools/cli/schemas/tron_schema.json +699 -0
- paasta_tools/cli/utils.py +1118 -0
- paasta_tools/clusterman.py +21 -0
- paasta_tools/config_utils.py +385 -0
- paasta_tools/contrib/__init__.py +0 -0
- paasta_tools/contrib/bounce_log_latency_parser.py +68 -0
- paasta_tools/contrib/check_manual_oapi_changes.sh +24 -0
- paasta_tools/contrib/check_orphans.py +306 -0
- paasta_tools/contrib/create_dynamodb_table.py +35 -0
- paasta_tools/contrib/create_paasta_playground.py +105 -0
- paasta_tools/contrib/emit_allocated_cpu_metrics.py +50 -0
- paasta_tools/contrib/get_running_task_allocation.py +346 -0
- paasta_tools/contrib/habitat_fixer.py +86 -0
- paasta_tools/contrib/ide_helper.py +316 -0
- paasta_tools/contrib/is_pod_healthy_in_proxy.py +139 -0
- paasta_tools/contrib/is_pod_healthy_in_smartstack.py +50 -0
- paasta_tools/contrib/kill_bad_containers.py +109 -0
- paasta_tools/contrib/mass-deploy-tag.sh +44 -0
- paasta_tools/contrib/mock_patch_checker.py +86 -0
- paasta_tools/contrib/paasta_update_soa_memcpu.py +520 -0
- paasta_tools/contrib/render_template.py +129 -0
- paasta_tools/contrib/rightsizer_soaconfigs_update.py +348 -0
- paasta_tools/contrib/service_shard_remove.py +157 -0
- paasta_tools/contrib/service_shard_update.py +373 -0
- paasta_tools/contrib/shared_ip_check.py +77 -0
- paasta_tools/contrib/timeouts_metrics_prom.py +64 -0
- paasta_tools/delete_kubernetes_deployments.py +89 -0
- paasta_tools/deployment_utils.py +44 -0
- paasta_tools/docker_wrapper.py +234 -0
- paasta_tools/docker_wrapper_imports.py +13 -0
- paasta_tools/drain_lib.py +351 -0
- paasta_tools/dump_locally_running_services.py +71 -0
- paasta_tools/eks_tools.py +119 -0
- paasta_tools/envoy_tools.py +373 -0
- paasta_tools/firewall.py +504 -0
- paasta_tools/firewall_logging.py +154 -0
- paasta_tools/firewall_update.py +172 -0
- paasta_tools/flink_tools.py +345 -0
- paasta_tools/flinkeks_tools.py +90 -0
- paasta_tools/frameworks/__init__.py +0 -0
- paasta_tools/frameworks/adhoc_scheduler.py +71 -0
- paasta_tools/frameworks/constraints.py +87 -0
- paasta_tools/frameworks/native_scheduler.py +652 -0
- paasta_tools/frameworks/native_service_config.py +301 -0
- paasta_tools/frameworks/task_store.py +245 -0
- paasta_tools/generate_all_deployments +9 -0
- paasta_tools/generate_authenticating_services.py +94 -0
- paasta_tools/generate_deployments_for_service.py +255 -0
- paasta_tools/generate_services_file.py +114 -0
- paasta_tools/generate_services_yaml.py +30 -0
- paasta_tools/hacheck.py +76 -0
- paasta_tools/instance/__init__.py +0 -0
- paasta_tools/instance/hpa_metrics_parser.py +122 -0
- paasta_tools/instance/kubernetes.py +1362 -0
- paasta_tools/iptables.py +240 -0
- paasta_tools/kafkacluster_tools.py +143 -0
- paasta_tools/kubernetes/__init__.py +0 -0
- paasta_tools/kubernetes/application/__init__.py +0 -0
- paasta_tools/kubernetes/application/controller_wrappers.py +476 -0
- paasta_tools/kubernetes/application/tools.py +90 -0
- paasta_tools/kubernetes/bin/__init__.py +0 -0
- paasta_tools/kubernetes/bin/kubernetes_remove_evicted_pods.py +164 -0
- paasta_tools/kubernetes/bin/paasta_cleanup_remote_run_resources.py +135 -0
- paasta_tools/kubernetes/bin/paasta_cleanup_stale_nodes.py +181 -0
- paasta_tools/kubernetes/bin/paasta_secrets_sync.py +758 -0
- paasta_tools/kubernetes/remote_run.py +558 -0
- paasta_tools/kubernetes_tools.py +4679 -0
- paasta_tools/list_kubernetes_service_instances.py +128 -0
- paasta_tools/list_tron_namespaces.py +60 -0
- paasta_tools/long_running_service_tools.py +678 -0
- paasta_tools/mac_address.py +44 -0
- paasta_tools/marathon_dashboard.py +0 -0
- paasta_tools/mesos/__init__.py +0 -0
- paasta_tools/mesos/cfg.py +46 -0
- paasta_tools/mesos/cluster.py +60 -0
- paasta_tools/mesos/exceptions.py +59 -0
- paasta_tools/mesos/framework.py +77 -0
- paasta_tools/mesos/log.py +48 -0
- paasta_tools/mesos/master.py +306 -0
- paasta_tools/mesos/mesos_file.py +169 -0
- paasta_tools/mesos/parallel.py +52 -0
- paasta_tools/mesos/slave.py +115 -0
- paasta_tools/mesos/task.py +94 -0
- paasta_tools/mesos/util.py +69 -0
- paasta_tools/mesos/zookeeper.py +37 -0
- paasta_tools/mesos_maintenance.py +848 -0
- paasta_tools/mesos_tools.py +1051 -0
- paasta_tools/metrics/__init__.py +0 -0
- paasta_tools/metrics/metastatus_lib.py +1110 -0
- paasta_tools/metrics/metrics_lib.py +217 -0
- paasta_tools/monitoring/__init__.py +13 -0
- paasta_tools/monitoring/check_k8s_api_performance.py +110 -0
- paasta_tools/monitoring_tools.py +652 -0
- paasta_tools/monkrelaycluster_tools.py +146 -0
- paasta_tools/nrtsearchservice_tools.py +143 -0
- paasta_tools/nrtsearchserviceeks_tools.py +68 -0
- paasta_tools/oom_logger.py +321 -0
- paasta_tools/paasta_deploy_tron_jobs +3 -0
- paasta_tools/paasta_execute_docker_command.py +123 -0
- paasta_tools/paasta_native_serviceinit.py +21 -0
- paasta_tools/paasta_service_config_loader.py +201 -0
- paasta_tools/paastaapi/__init__.py +29 -0
- paasta_tools/paastaapi/api/__init__.py +3 -0
- paasta_tools/paastaapi/api/autoscaler_api.py +302 -0
- paasta_tools/paastaapi/api/default_api.py +569 -0
- paasta_tools/paastaapi/api/remote_run_api.py +604 -0
- paasta_tools/paastaapi/api/resources_api.py +157 -0
- paasta_tools/paastaapi/api/service_api.py +1736 -0
- paasta_tools/paastaapi/api_client.py +818 -0
- paasta_tools/paastaapi/apis/__init__.py +22 -0
- paasta_tools/paastaapi/configuration.py +455 -0
- paasta_tools/paastaapi/exceptions.py +137 -0
- paasta_tools/paastaapi/model/__init__.py +5 -0
- paasta_tools/paastaapi/model/adhoc_launch_history.py +176 -0
- paasta_tools/paastaapi/model/autoscaler_count_msg.py +176 -0
- paasta_tools/paastaapi/model/deploy_queue.py +178 -0
- paasta_tools/paastaapi/model/deploy_queue_service_instance.py +194 -0
- paasta_tools/paastaapi/model/envoy_backend.py +185 -0
- paasta_tools/paastaapi/model/envoy_location.py +184 -0
- paasta_tools/paastaapi/model/envoy_status.py +181 -0
- paasta_tools/paastaapi/model/flink_cluster_overview.py +188 -0
- paasta_tools/paastaapi/model/flink_config.py +173 -0
- paasta_tools/paastaapi/model/flink_job.py +186 -0
- paasta_tools/paastaapi/model/flink_job_details.py +192 -0
- paasta_tools/paastaapi/model/flink_jobs.py +175 -0
- paasta_tools/paastaapi/model/float_and_error.py +173 -0
- paasta_tools/paastaapi/model/hpa_metric.py +176 -0
- paasta_tools/paastaapi/model/inline_object.py +170 -0
- paasta_tools/paastaapi/model/inline_response200.py +170 -0
- paasta_tools/paastaapi/model/inline_response2001.py +170 -0
- paasta_tools/paastaapi/model/instance_bounce_status.py +200 -0
- paasta_tools/paastaapi/model/instance_mesh_status.py +186 -0
- paasta_tools/paastaapi/model/instance_status.py +220 -0
- paasta_tools/paastaapi/model/instance_status_adhoc.py +187 -0
- paasta_tools/paastaapi/model/instance_status_cassandracluster.py +173 -0
- paasta_tools/paastaapi/model/instance_status_flink.py +173 -0
- paasta_tools/paastaapi/model/instance_status_kafkacluster.py +173 -0
- paasta_tools/paastaapi/model/instance_status_kubernetes.py +263 -0
- paasta_tools/paastaapi/model/instance_status_kubernetes_autoscaling_status.py +187 -0
- paasta_tools/paastaapi/model/instance_status_kubernetes_v2.py +197 -0
- paasta_tools/paastaapi/model/instance_status_tron.py +204 -0
- paasta_tools/paastaapi/model/instance_tasks.py +182 -0
- paasta_tools/paastaapi/model/integer_and_error.py +173 -0
- paasta_tools/paastaapi/model/kubernetes_container.py +178 -0
- paasta_tools/paastaapi/model/kubernetes_container_v2.py +219 -0
- paasta_tools/paastaapi/model/kubernetes_healthcheck.py +176 -0
- paasta_tools/paastaapi/model/kubernetes_pod.py +201 -0
- paasta_tools/paastaapi/model/kubernetes_pod_event.py +176 -0
- paasta_tools/paastaapi/model/kubernetes_pod_v2.py +213 -0
- paasta_tools/paastaapi/model/kubernetes_replica_set.py +185 -0
- paasta_tools/paastaapi/model/kubernetes_version.py +202 -0
- paasta_tools/paastaapi/model/remote_run_outcome.py +189 -0
- paasta_tools/paastaapi/model/remote_run_start.py +185 -0
- paasta_tools/paastaapi/model/remote_run_stop.py +176 -0
- paasta_tools/paastaapi/model/remote_run_token.py +173 -0
- paasta_tools/paastaapi/model/resource.py +187 -0
- paasta_tools/paastaapi/model/resource_item.py +187 -0
- paasta_tools/paastaapi/model/resource_value.py +176 -0
- paasta_tools/paastaapi/model/smartstack_backend.py +191 -0
- paasta_tools/paastaapi/model/smartstack_location.py +181 -0
- paasta_tools/paastaapi/model/smartstack_status.py +181 -0
- paasta_tools/paastaapi/model/task_tail_lines.py +176 -0
- paasta_tools/paastaapi/model_utils.py +1879 -0
- paasta_tools/paastaapi/models/__init__.py +62 -0
- paasta_tools/paastaapi/rest.py +287 -0
- paasta_tools/prune_completed_pods.py +220 -0
- paasta_tools/puppet_service_tools.py +59 -0
- paasta_tools/py.typed +1 -0
- paasta_tools/remote_git.py +127 -0
- paasta_tools/run-paasta-api-in-dev-mode.py +57 -0
- paasta_tools/run-paasta-api-playground.py +51 -0
- paasta_tools/secret_providers/__init__.py +66 -0
- paasta_tools/secret_providers/vault.py +214 -0
- paasta_tools/secret_tools.py +277 -0
- paasta_tools/setup_istio_mesh.py +353 -0
- paasta_tools/setup_kubernetes_cr.py +412 -0
- paasta_tools/setup_kubernetes_crd.py +138 -0
- paasta_tools/setup_kubernetes_internal_crd.py +154 -0
- paasta_tools/setup_kubernetes_job.py +353 -0
- paasta_tools/setup_prometheus_adapter_config.py +1028 -0
- paasta_tools/setup_tron_namespace.py +248 -0
- paasta_tools/slack.py +75 -0
- paasta_tools/smartstack_tools.py +676 -0
- paasta_tools/spark_tools.py +283 -0
- paasta_tools/synapse_srv_namespaces_fact.py +42 -0
- paasta_tools/tron/__init__.py +0 -0
- paasta_tools/tron/client.py +158 -0
- paasta_tools/tron/tron_command_context.py +194 -0
- paasta_tools/tron/tron_timeutils.py +101 -0
- paasta_tools/tron_tools.py +1448 -0
- paasta_tools/utils.py +4307 -0
- paasta_tools/yaml_tools.py +44 -0
- paasta_tools-1.21.3.data/scripts/apply_external_resources.py +79 -0
- paasta_tools-1.21.3.data/scripts/bounce_log_latency_parser.py +68 -0
- paasta_tools-1.21.3.data/scripts/check_autoscaler_max_instances.py +212 -0
- paasta_tools-1.21.3.data/scripts/check_cassandracluster_services_replication.py +35 -0
- paasta_tools-1.21.3.data/scripts/check_flink_services_health.py +203 -0
- paasta_tools-1.21.3.data/scripts/check_kubernetes_api.py +57 -0
- paasta_tools-1.21.3.data/scripts/check_kubernetes_services_replication.py +141 -0
- paasta_tools-1.21.3.data/scripts/check_manual_oapi_changes.sh +24 -0
- paasta_tools-1.21.3.data/scripts/check_oom_events.py +244 -0
- paasta_tools-1.21.3.data/scripts/check_orphans.py +306 -0
- paasta_tools-1.21.3.data/scripts/check_spark_jobs.py +234 -0
- paasta_tools-1.21.3.data/scripts/cleanup_kubernetes_cr.py +138 -0
- paasta_tools-1.21.3.data/scripts/cleanup_kubernetes_crd.py +145 -0
- paasta_tools-1.21.3.data/scripts/cleanup_kubernetes_jobs.py +344 -0
- paasta_tools-1.21.3.data/scripts/create_dynamodb_table.py +35 -0
- paasta_tools-1.21.3.data/scripts/create_paasta_playground.py +105 -0
- paasta_tools-1.21.3.data/scripts/delete_kubernetes_deployments.py +89 -0
- paasta_tools-1.21.3.data/scripts/emit_allocated_cpu_metrics.py +50 -0
- paasta_tools-1.21.3.data/scripts/generate_all_deployments +9 -0
- paasta_tools-1.21.3.data/scripts/generate_authenticating_services.py +94 -0
- paasta_tools-1.21.3.data/scripts/generate_deployments_for_service.py +255 -0
- paasta_tools-1.21.3.data/scripts/generate_services_file.py +114 -0
- paasta_tools-1.21.3.data/scripts/generate_services_yaml.py +30 -0
- paasta_tools-1.21.3.data/scripts/get_running_task_allocation.py +346 -0
- paasta_tools-1.21.3.data/scripts/habitat_fixer.py +86 -0
- paasta_tools-1.21.3.data/scripts/ide_helper.py +316 -0
- paasta_tools-1.21.3.data/scripts/is_pod_healthy_in_proxy.py +139 -0
- paasta_tools-1.21.3.data/scripts/is_pod_healthy_in_smartstack.py +50 -0
- paasta_tools-1.21.3.data/scripts/kill_bad_containers.py +109 -0
- paasta_tools-1.21.3.data/scripts/kubernetes_remove_evicted_pods.py +164 -0
- paasta_tools-1.21.3.data/scripts/mass-deploy-tag.sh +44 -0
- paasta_tools-1.21.3.data/scripts/mock_patch_checker.py +86 -0
- paasta_tools-1.21.3.data/scripts/paasta_cleanup_remote_run_resources.py +135 -0
- paasta_tools-1.21.3.data/scripts/paasta_cleanup_stale_nodes.py +181 -0
- paasta_tools-1.21.3.data/scripts/paasta_deploy_tron_jobs +3 -0
- paasta_tools-1.21.3.data/scripts/paasta_execute_docker_command.py +123 -0
- paasta_tools-1.21.3.data/scripts/paasta_secrets_sync.py +758 -0
- paasta_tools-1.21.3.data/scripts/paasta_tabcomplete.sh +23 -0
- paasta_tools-1.21.3.data/scripts/paasta_update_soa_memcpu.py +520 -0
- paasta_tools-1.21.3.data/scripts/render_template.py +129 -0
- paasta_tools-1.21.3.data/scripts/rightsizer_soaconfigs_update.py +348 -0
- paasta_tools-1.21.3.data/scripts/service_shard_remove.py +157 -0
- paasta_tools-1.21.3.data/scripts/service_shard_update.py +373 -0
- paasta_tools-1.21.3.data/scripts/setup_istio_mesh.py +353 -0
- paasta_tools-1.21.3.data/scripts/setup_kubernetes_cr.py +412 -0
- paasta_tools-1.21.3.data/scripts/setup_kubernetes_crd.py +138 -0
- paasta_tools-1.21.3.data/scripts/setup_kubernetes_internal_crd.py +154 -0
- paasta_tools-1.21.3.data/scripts/setup_kubernetes_job.py +353 -0
- paasta_tools-1.21.3.data/scripts/setup_prometheus_adapter_config.py +1028 -0
- paasta_tools-1.21.3.data/scripts/shared_ip_check.py +77 -0
- paasta_tools-1.21.3.data/scripts/synapse_srv_namespaces_fact.py +42 -0
- paasta_tools-1.21.3.data/scripts/timeouts_metrics_prom.py +64 -0
- paasta_tools-1.21.3.dist-info/LICENSE +201 -0
- paasta_tools-1.21.3.dist-info/METADATA +74 -0
- paasta_tools-1.21.3.dist-info/RECORD +348 -0
- paasta_tools-1.21.3.dist-info/WHEEL +5 -0
- paasta_tools-1.21.3.dist-info/entry_points.txt +20 -0
- paasta_tools-1.21.3.dist-info/top_level.txt +2 -0
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
# Copyright 2015-2016 Yelp Inc.
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
import re
|
|
15
|
+
|
|
16
|
+
import dulwich.client
|
|
17
|
+
import dulwich.errors
|
|
18
|
+
|
|
19
|
+
from paasta_tools.utils import _run
|
|
20
|
+
from paasta_tools.utils import timeout
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def _make_determine_wants_func(ref_mutator):
|
|
24
|
+
"""Returns a safer version of ref_mutator, suitable for passing as the
|
|
25
|
+
determine_wants argument to dulwich's send_pack method. The returned
|
|
26
|
+
function will not delete or modify any existing refs."""
|
|
27
|
+
|
|
28
|
+
def determine_wants(old_refs):
|
|
29
|
+
refs = {k.decode("UTF-8"): v.decode("UTF-8") for k, v in old_refs.items()}
|
|
30
|
+
new_refs = ref_mutator(refs)
|
|
31
|
+
new_refs = {k.encode("UTF-8"): v.encode("UTF-8") for k, v in new_refs.items()}
|
|
32
|
+
new_refs.update(old_refs) # Make sure we don't delete/modify anything.
|
|
33
|
+
return new_refs
|
|
34
|
+
|
|
35
|
+
return determine_wants
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def make_force_push_mutate_refs_func(targets, sha):
|
|
39
|
+
"""Create a 'force push' function that will inform send_pack that we want
|
|
40
|
+
to mark a certain list of target branches/tags to point to a particular
|
|
41
|
+
git_sha.
|
|
42
|
+
|
|
43
|
+
:param targets: List of branches/tags to point at the input sha
|
|
44
|
+
:param sha: The git sha to point the branches/tags at
|
|
45
|
+
:returns: A function to do the ref manipulation that a dulwich client can use"""
|
|
46
|
+
|
|
47
|
+
def mutate_refs(refs):
|
|
48
|
+
for target in targets:
|
|
49
|
+
refs[target.encode("UTF-8")] = sha.encode("UTF-8")
|
|
50
|
+
return refs
|
|
51
|
+
|
|
52
|
+
return mutate_refs
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def create_remote_refs(git_url, ref_mutator, force=False):
|
|
56
|
+
"""Creates refs (tags, branches) on a remote git repo.
|
|
57
|
+
|
|
58
|
+
:param git_url: the URL or path to the remote git repo.
|
|
59
|
+
:param ref_mutator: A function that determines the new refs to create on
|
|
60
|
+
the remote repo. This gets passed a dictionary of the
|
|
61
|
+
remote server's refs in the format {name : hash, ...},
|
|
62
|
+
and should return a dictionary of the same format.
|
|
63
|
+
:param force: Bool, defaults to false. If true we will overwrite
|
|
64
|
+
refs even if they are already set.
|
|
65
|
+
:returns: The map of refs, with our changes applied.
|
|
66
|
+
"""
|
|
67
|
+
client, path = dulwich.client.get_transport_and_path(git_url)
|
|
68
|
+
|
|
69
|
+
if force is False:
|
|
70
|
+
determine_wants = _make_determine_wants_func(ref_mutator)
|
|
71
|
+
else:
|
|
72
|
+
determine_wants = ref_mutator
|
|
73
|
+
# We know we don't need to push any objects.
|
|
74
|
+
|
|
75
|
+
def generate_pack_contents(have, want):
|
|
76
|
+
return []
|
|
77
|
+
|
|
78
|
+
return client.send_pack(path, determine_wants, generate_pack_contents)
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
class LSRemoteException(Exception):
|
|
82
|
+
pass
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
@timeout(
|
|
86
|
+
seconds=60,
|
|
87
|
+
error_message="Timed out connecting to git server, is it reachable from where you are?",
|
|
88
|
+
use_signals=False,
|
|
89
|
+
)
|
|
90
|
+
def list_remote_refs(git_url):
|
|
91
|
+
"""Get the refs from a remote git repo as a dictionary of name->hash."""
|
|
92
|
+
client, path = dulwich.client.get_transport_and_path(git_url)
|
|
93
|
+
try:
|
|
94
|
+
refs = client.fetch_pack(path, lambda refs: [], None, lambda data: None)
|
|
95
|
+
return {k.decode("UTF-8"): v.decode("UTF-8") for k, v in refs.items()}
|
|
96
|
+
except dulwich.errors.HangupException as e:
|
|
97
|
+
raise LSRemoteException(f"Unable to fetch remote refs from {git_url}: {e}")
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
def get_authors(git_url, from_sha, to_sha):
|
|
101
|
+
"""Gets the list of authors who contributed to a git changeset.
|
|
102
|
+
Currently only supports fetching this in a very "yelpy" way by
|
|
103
|
+
executing a gitolite command"""
|
|
104
|
+
matches = re.match("(?P<git_server>.*):(?P<git_repo>.*)", git_url)
|
|
105
|
+
if matches is None:
|
|
106
|
+
return (1, f"could not understand the git url {git_url} for authors detection")
|
|
107
|
+
git_server = matches.group("git_server")
|
|
108
|
+
git_repo = matches.group("git_repo")
|
|
109
|
+
if git_server is None:
|
|
110
|
+
return (
|
|
111
|
+
1,
|
|
112
|
+
f"could not understand the git server in {git_url} for authors detection",
|
|
113
|
+
)
|
|
114
|
+
if git_repo is None:
|
|
115
|
+
return (
|
|
116
|
+
1,
|
|
117
|
+
f"could not understand the git repo in {git_url} for authors detection",
|
|
118
|
+
)
|
|
119
|
+
|
|
120
|
+
if "git.yelpcorp.com" in git_server:
|
|
121
|
+
ssh_command = (
|
|
122
|
+
f"ssh {git_server} authors-of-changeset {git_repo} {from_sha} {to_sha}"
|
|
123
|
+
)
|
|
124
|
+
return _run(command=ssh_command, timeout=5.0)
|
|
125
|
+
else:
|
|
126
|
+
# TODO: PAASTA-16927: support getting authors for services on GHE
|
|
127
|
+
return 1, f"Fetching authors not supported for {git_server}"
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import json
|
|
2
|
+
import os
|
|
3
|
+
from distutils.dir_util import copy_tree
|
|
4
|
+
|
|
5
|
+
from paasta_tools.cli.utils import pick_random_port
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def main():
|
|
9
|
+
print("-------------------------------------------------------")
|
|
10
|
+
print(
|
|
11
|
+
"Please run export PAASTA_SYSTEM_CONFIG_DIR=etc_paasta_for_development to continue"
|
|
12
|
+
)
|
|
13
|
+
print(
|
|
14
|
+
"Please set environment variable PAASTA_TEST_CLUSTER to the cluster you want to use."
|
|
15
|
+
)
|
|
16
|
+
print("This is necessary for tron jobs")
|
|
17
|
+
print("-------------------------------------------------------")
|
|
18
|
+
cluster = os.environ.get("PAASTA_TEST_CLUSTER", "norcal-devc")
|
|
19
|
+
config_path = "etc_paasta_for_development"
|
|
20
|
+
|
|
21
|
+
copy_tree("/etc/paasta", os.path.join(os.getcwd(), config_path))
|
|
22
|
+
# Generate tron.json
|
|
23
|
+
tron_config = {"tron": {"url": f"http://tron-{cluster}:8089"}}
|
|
24
|
+
with open(config_path + "/tron.json", "w") as f:
|
|
25
|
+
json.dump(tron_config, f)
|
|
26
|
+
# find unused port
|
|
27
|
+
port = pick_random_port("paasta-dev-api")
|
|
28
|
+
# Generate api endpoints
|
|
29
|
+
api_endpoints = {"api_endpoints": {cluster: f"http://localhost:{port}"}}
|
|
30
|
+
api_endpoints_path = os.path.join(os.getcwd(), config_path, "api_endpoints.json")
|
|
31
|
+
os.chmod(api_endpoints_path, 0o777)
|
|
32
|
+
with open(api_endpoints_path, "w") as f:
|
|
33
|
+
json.dump(api_endpoints, f)
|
|
34
|
+
|
|
35
|
+
# export config path
|
|
36
|
+
os.environ["PAASTA_SYSTEM_CONFIG_DIR"] = config_path
|
|
37
|
+
|
|
38
|
+
api_single_process = os.environ.get("PAASTA_API_SINGLE_PROCESS")
|
|
39
|
+
if api_single_process is not None and api_single_process.lower() == "true":
|
|
40
|
+
from paasta_tools.api.api import redirect_argv
|
|
41
|
+
|
|
42
|
+
with redirect_argv(["-D", "-c", cluster, str(port)]):
|
|
43
|
+
from paasta_tools.api import api
|
|
44
|
+
|
|
45
|
+
api.main("dev-mode")
|
|
46
|
+
else:
|
|
47
|
+
os.execl(
|
|
48
|
+
".tox/py38-linux/bin/python",
|
|
49
|
+
".tox/py38-linux/bin/python",
|
|
50
|
+
"-m",
|
|
51
|
+
"paasta_tools.api.api",
|
|
52
|
+
*["-D", "-c", cluster, str(port)],
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
if __name__ == "__main__":
|
|
57
|
+
main()
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import json
|
|
2
|
+
import os
|
|
3
|
+
|
|
4
|
+
from paasta_tools.cli.utils import pick_random_port
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def main():
|
|
8
|
+
print("-------------------------------------------------------")
|
|
9
|
+
print(
|
|
10
|
+
"Please run export PAASTA_SYSTEM_CONFIG_DIR=etc_paasta_playground to continue"
|
|
11
|
+
)
|
|
12
|
+
print(
|
|
13
|
+
"Please set environment variable PAASTA_TEST_CLUSTER to the cluster you want to use."
|
|
14
|
+
)
|
|
15
|
+
print("-------------------------------------------------------")
|
|
16
|
+
user = os.environ["USER"]
|
|
17
|
+
cluster = os.environ.get("PAASTA_TEST_CLUSTER", f"kind-{user}-k8s-test")
|
|
18
|
+
config_path = "etc_paasta_playground"
|
|
19
|
+
|
|
20
|
+
# find unused ports
|
|
21
|
+
port = pick_random_port("paasta-dev-api")
|
|
22
|
+
|
|
23
|
+
# Generate api endpoints
|
|
24
|
+
api_endpoints = {"api_endpoints": {cluster: f"http://localhost:{port}"}}
|
|
25
|
+
api_endpoints_path = os.path.join(config_path, "api_endpoints.json")
|
|
26
|
+
with open(api_endpoints_path, "w") as f:
|
|
27
|
+
json.dump(api_endpoints, f)
|
|
28
|
+
|
|
29
|
+
# export config path
|
|
30
|
+
os.environ["PAASTA_SYSTEM_CONFIG_DIR"] = config_path
|
|
31
|
+
|
|
32
|
+
api_single_process = os.environ.get("PAASTA_API_SINGLE_PROCESS")
|
|
33
|
+
if api_single_process is not None and api_single_process.lower() == "true":
|
|
34
|
+
from paasta_tools.api.api import redirect_argv
|
|
35
|
+
|
|
36
|
+
with redirect_argv(["-D", "-c", cluster, str(port)]):
|
|
37
|
+
from paasta_tools.api import api
|
|
38
|
+
|
|
39
|
+
api.main("dev-mode")
|
|
40
|
+
else:
|
|
41
|
+
os.execl(
|
|
42
|
+
".tox/py38-linux/bin/python",
|
|
43
|
+
".tox/py38-linux/bin/python",
|
|
44
|
+
"-m",
|
|
45
|
+
"paasta_tools.api.api",
|
|
46
|
+
*["-D", "-c", cluster, str(port)],
|
|
47
|
+
)
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
if __name__ == "__main__":
|
|
51
|
+
main()
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import os
|
|
2
|
+
from typing import Any
|
|
3
|
+
from typing import Dict
|
|
4
|
+
from typing import List
|
|
5
|
+
from typing import Mapping
|
|
6
|
+
from typing import Optional
|
|
7
|
+
|
|
8
|
+
from mypy_extensions import TypedDict
|
|
9
|
+
from service_configuration_lib import read_service_configuration
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class BaseSecretProvider:
|
|
13
|
+
def __init__(
|
|
14
|
+
self,
|
|
15
|
+
soa_dir: Optional[str],
|
|
16
|
+
service_name: Optional[str],
|
|
17
|
+
cluster_names: List[str],
|
|
18
|
+
**kwargs: Any,
|
|
19
|
+
) -> None:
|
|
20
|
+
self.soa_dir = soa_dir
|
|
21
|
+
self.cluster_names = cluster_names
|
|
22
|
+
self.service_name = service_name
|
|
23
|
+
if service_name:
|
|
24
|
+
self.secret_dir = os.path.join(self.soa_dir, self.service_name, "secrets")
|
|
25
|
+
service_config = read_service_configuration(self.service_name, self.soa_dir)
|
|
26
|
+
self.encryption_key = service_config.get("encryption_key", "paasta")
|
|
27
|
+
|
|
28
|
+
def decrypt_environment(
|
|
29
|
+
self, environment: Dict[str, str], **kwargs: Any
|
|
30
|
+
) -> Dict[str, str]:
|
|
31
|
+
raise NotImplementedError
|
|
32
|
+
|
|
33
|
+
def write_secret(
|
|
34
|
+
self,
|
|
35
|
+
action: str,
|
|
36
|
+
secret_name: str,
|
|
37
|
+
plaintext: bytes,
|
|
38
|
+
cross_environment_motivation: Optional[str] = None,
|
|
39
|
+
) -> None:
|
|
40
|
+
raise NotImplementedError
|
|
41
|
+
|
|
42
|
+
def decrypt_secret(self, secret_name: str) -> str:
|
|
43
|
+
raise NotImplementedError
|
|
44
|
+
|
|
45
|
+
def decrypt_secret_raw(self, secret_name: str) -> bytes:
|
|
46
|
+
raise NotImplementedError
|
|
47
|
+
|
|
48
|
+
def get_secret_signature_from_data(self, data: Mapping[str, Any]) -> Optional[str]:
|
|
49
|
+
raise NotImplementedError
|
|
50
|
+
|
|
51
|
+
def get_data_from_vault_path(self, path: str) -> Optional[Dict[str, str]]:
|
|
52
|
+
raise NotImplementedError
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
class CryptoKey(TypedDict):
|
|
56
|
+
key_name: str
|
|
57
|
+
key_version: str
|
|
58
|
+
key: str
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
class SecretProvider(BaseSecretProvider):
|
|
62
|
+
def get_key_versions(self, key_name: str) -> List[CryptoKey]:
|
|
63
|
+
"""
|
|
64
|
+
Dummy attribute to satisfy `mypy` because the class is imported dynamically via __import__
|
|
65
|
+
"""
|
|
66
|
+
raise NotImplementedError
|
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
import getpass
|
|
2
|
+
import logging
|
|
3
|
+
import os
|
|
4
|
+
from typing import Any
|
|
5
|
+
from typing import Dict
|
|
6
|
+
from typing import List
|
|
7
|
+
from typing import Mapping
|
|
8
|
+
from typing import Optional
|
|
9
|
+
|
|
10
|
+
from paasta_tools.secret_providers import CryptoKey
|
|
11
|
+
|
|
12
|
+
try:
|
|
13
|
+
from vault_tools.client.jsonsecret import get_plaintext
|
|
14
|
+
from vault_tools.paasta_secret import get_vault_client
|
|
15
|
+
from vault_tools.gpg import TempGpgKeyring
|
|
16
|
+
from vault_tools.paasta_secret import encrypt_secret
|
|
17
|
+
import hvac
|
|
18
|
+
except ImportError:
|
|
19
|
+
|
|
20
|
+
def get_plaintext(*args: Any, **kwargs: Any) -> bytes:
|
|
21
|
+
return b"No plain text available without vault_tools"
|
|
22
|
+
|
|
23
|
+
def get_vault_client(*args: Any, **kwargs: Any) -> None:
|
|
24
|
+
return None
|
|
25
|
+
|
|
26
|
+
TempGpgKeyring = None
|
|
27
|
+
|
|
28
|
+
def encrypt_secret(*args: Any, **kwargs: Any) -> None:
|
|
29
|
+
return None
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
from paasta_tools.secret_providers import BaseSecretProvider
|
|
33
|
+
from paasta_tools.secret_tools import get_secret_name_from_ref
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
log = logging.getLogger(__name__)
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
class SecretProvider(BaseSecretProvider):
|
|
40
|
+
def __init__(
|
|
41
|
+
self,
|
|
42
|
+
soa_dir: Optional[str],
|
|
43
|
+
service_name: Optional[str],
|
|
44
|
+
cluster_names: List[str],
|
|
45
|
+
vault_cluster_config: Dict[str, str] = {},
|
|
46
|
+
vault_auth_method: str = "ldap",
|
|
47
|
+
vault_token_file: str = "/root/.vault-token",
|
|
48
|
+
vault_num_uses: int = 1,
|
|
49
|
+
**kwargs: Any,
|
|
50
|
+
) -> None:
|
|
51
|
+
super().__init__(soa_dir, service_name, cluster_names)
|
|
52
|
+
self.vault_cluster_config = vault_cluster_config
|
|
53
|
+
self.vault_auth_method = vault_auth_method
|
|
54
|
+
self.vault_token_file = vault_token_file
|
|
55
|
+
self.ecosystems = self.get_vault_ecosystems_for_clusters()
|
|
56
|
+
self.clients: Mapping[str, hvac.Client] = {}
|
|
57
|
+
if vault_auth_method == "ldap":
|
|
58
|
+
username = getpass.getuser()
|
|
59
|
+
password = getpass.getpass(
|
|
60
|
+
"Please enter your LDAP password to auth with Vault\n"
|
|
61
|
+
)
|
|
62
|
+
else:
|
|
63
|
+
username = None
|
|
64
|
+
password = None
|
|
65
|
+
for ecosystem in self.ecosystems:
|
|
66
|
+
self.clients[ecosystem] = get_vault_client(
|
|
67
|
+
ecosystem=ecosystem,
|
|
68
|
+
num_uses=vault_num_uses,
|
|
69
|
+
vault_auth_method=self.vault_auth_method,
|
|
70
|
+
vault_token_file=self.vault_token_file,
|
|
71
|
+
username=username,
|
|
72
|
+
password=password,
|
|
73
|
+
)
|
|
74
|
+
|
|
75
|
+
def decrypt_environment(
|
|
76
|
+
self, environment: Dict[str, str], **kwargs: Any
|
|
77
|
+
) -> Dict[str, str]:
|
|
78
|
+
client = self.clients[self.ecosystems[0]]
|
|
79
|
+
secret_environment = {}
|
|
80
|
+
for k, v in environment.items():
|
|
81
|
+
secret_name = get_secret_name_from_ref(v)
|
|
82
|
+
secret_path = os.path.join(self.secret_dir, f"{secret_name}.json")
|
|
83
|
+
secret = get_plaintext(
|
|
84
|
+
client=client,
|
|
85
|
+
env=self.ecosystems[0],
|
|
86
|
+
path=secret_path,
|
|
87
|
+
cache_enabled=False,
|
|
88
|
+
cache_dir=None,
|
|
89
|
+
cache_key=None,
|
|
90
|
+
context=self.service_name,
|
|
91
|
+
rescue_failures=False,
|
|
92
|
+
).decode("utf-8")
|
|
93
|
+
secret_environment[k] = secret
|
|
94
|
+
return secret_environment
|
|
95
|
+
|
|
96
|
+
def get_vault_ecosystems_for_clusters(self) -> List[str]:
|
|
97
|
+
try:
|
|
98
|
+
return list(
|
|
99
|
+
{
|
|
100
|
+
self.vault_cluster_config[cluster_name]
|
|
101
|
+
for cluster_name in self.cluster_names
|
|
102
|
+
}
|
|
103
|
+
)
|
|
104
|
+
except KeyError as e:
|
|
105
|
+
print(
|
|
106
|
+
"Cannot find a vault cluster for the %s paasta cluster. A mapping must exist "
|
|
107
|
+
"in /etc/paasta so we contact the correct vault cluster to get/set secrets"
|
|
108
|
+
% e
|
|
109
|
+
)
|
|
110
|
+
raise
|
|
111
|
+
|
|
112
|
+
def write_secret(
|
|
113
|
+
self,
|
|
114
|
+
action: str,
|
|
115
|
+
secret_name: str,
|
|
116
|
+
plaintext: bytes,
|
|
117
|
+
cross_environment_motivation: Optional[str] = None,
|
|
118
|
+
) -> None:
|
|
119
|
+
with TempGpgKeyring(overwrite=True):
|
|
120
|
+
for ecosystem in self.ecosystems:
|
|
121
|
+
client = self.clients[ecosystem]
|
|
122
|
+
encrypt_secret(
|
|
123
|
+
client=client,
|
|
124
|
+
action=action,
|
|
125
|
+
ecosystem=ecosystem,
|
|
126
|
+
secret_name=secret_name,
|
|
127
|
+
soa_dir=self.soa_dir,
|
|
128
|
+
plaintext=plaintext,
|
|
129
|
+
service_name=self.service_name,
|
|
130
|
+
transit_key=self.encryption_key,
|
|
131
|
+
cross_environment_motivation=cross_environment_motivation,
|
|
132
|
+
)
|
|
133
|
+
|
|
134
|
+
def decrypt_secret(self, secret_name: str) -> str:
|
|
135
|
+
return self.decrypt_secret_raw(secret_name).decode("utf-8")
|
|
136
|
+
|
|
137
|
+
def decrypt_secret_raw(self, secret_name: str) -> bytes:
|
|
138
|
+
client = self.clients[self.ecosystems[0]]
|
|
139
|
+
secret_path = os.path.join(self.secret_dir, f"{secret_name}.json")
|
|
140
|
+
return get_plaintext(
|
|
141
|
+
client=client,
|
|
142
|
+
path=secret_path,
|
|
143
|
+
env=self.ecosystems[0],
|
|
144
|
+
cache_enabled=False,
|
|
145
|
+
cache_key=None,
|
|
146
|
+
cache_dir=None,
|
|
147
|
+
context=self.service_name,
|
|
148
|
+
rescue_failures=False,
|
|
149
|
+
)
|
|
150
|
+
|
|
151
|
+
def get_secret_signature_from_data(self, data: Mapping[str, Any]) -> Optional[str]:
|
|
152
|
+
ecosystem = self.ecosystems[0]
|
|
153
|
+
if data["environments"].get(ecosystem):
|
|
154
|
+
return data["environments"][ecosystem]["signature"]
|
|
155
|
+
else:
|
|
156
|
+
return None
|
|
157
|
+
|
|
158
|
+
def get_data_from_vault_path(self, path: str) -> Optional[Dict[str, str]]:
|
|
159
|
+
# clients.read returns None if not set
|
|
160
|
+
# if it is set, it returns an object with { **metadata, data: {} }
|
|
161
|
+
# eg lease_id, request_id, etc. we only care about 'data' here
|
|
162
|
+
|
|
163
|
+
client = self.clients[self.ecosystems[0]]
|
|
164
|
+
|
|
165
|
+
# there is a chance client is None (ie if the connection is invalid)
|
|
166
|
+
if client is None:
|
|
167
|
+
raise Exception(
|
|
168
|
+
"possible Vault misconfiguration as client is not available"
|
|
169
|
+
)
|
|
170
|
+
|
|
171
|
+
entry = client.read(path)
|
|
172
|
+
|
|
173
|
+
# returns one of 3 things:
|
|
174
|
+
# entry -> could be None
|
|
175
|
+
# entry["data"] -> could be an object with content
|
|
176
|
+
# entry["data"] -> could be empty (ie no secrets)
|
|
177
|
+
# all are plausible and valid scenarios that give different information about the path
|
|
178
|
+
|
|
179
|
+
if entry is not None:
|
|
180
|
+
return entry.get("data", {})
|
|
181
|
+
return None
|
|
182
|
+
|
|
183
|
+
def get_key_versions(
|
|
184
|
+
self,
|
|
185
|
+
key_name: str,
|
|
186
|
+
) -> List[CryptoKey]:
|
|
187
|
+
"""
|
|
188
|
+
Retrieve all versions of Vault key based on its metadata
|
|
189
|
+
"""
|
|
190
|
+
client = self.clients[self.ecosystems[0]]
|
|
191
|
+
crypto_keys: List[CryptoKey] = []
|
|
192
|
+
try:
|
|
193
|
+
meta_response = client.secrets.kv.read_secret_metadata(
|
|
194
|
+
path=key_name, mount_point="keystore"
|
|
195
|
+
)
|
|
196
|
+
|
|
197
|
+
for key_version in meta_response["data"]["versions"].keys():
|
|
198
|
+
key_response = client.secrets.kv.read_secret_version(
|
|
199
|
+
path=key_name, version=key_version, mount_point="keystore"
|
|
200
|
+
)
|
|
201
|
+
crypto_keys.append(
|
|
202
|
+
{
|
|
203
|
+
"key_name": key_name,
|
|
204
|
+
"key_version": key_response["data"]["metadata"]["version"],
|
|
205
|
+
"key": key_response["data"]["data"]["key"],
|
|
206
|
+
}
|
|
207
|
+
)
|
|
208
|
+
except hvac.exceptions.VaultError:
|
|
209
|
+
log.warning(
|
|
210
|
+
f"Could not fetch key versions for {key_name} on {self.ecosystems[0]}"
|
|
211
|
+
)
|
|
212
|
+
pass
|
|
213
|
+
|
|
214
|
+
return crypto_keys
|